summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiago Gomes <tiago.gomes@codethink.co.uk>2015-01-22 11:39:46 +0000
committerTiago Gomes <tiago.gomes@codethink.co.uk>2015-01-22 11:39:46 +0000
commit70efb9c3529a4c0cee5f4672704f0341d05fb359 (patch)
tree30739c93a70d922d6710a148427042f29f130f24
parent6a0eb04c3d2ac24d80d505b42a8f67799487d133 (diff)
parent902fcb22d611b7f9e99369ecab223c00c877b82c (diff)
downloadgawk-baserock/tiagogomes/armv8l64.tar.gz
Merge branch 'master' into baserock/tiagogomes/armv8l64baserock/tiagogomes/armv8l64
-rw-r--r--.gitignore4
-rw-r--r--CMakeLists.txt108
-rw-r--r--ChangeLog3560
-rw-r--r--Checklist18
-rw-r--r--FUTURES64
-rw-r--r--INSTALL212
-rw-r--r--LIMITATIONS22
-rw-r--r--Makefile.am86
-rw-r--r--Makefile.in653
-rw-r--r--NEWS208
-rw-r--r--PROBLEMS15
-rw-r--r--README29
-rw-r--r--README.cvs8
-rw-r--r--README.git139
-rw-r--r--README_d/ChangeLog69
-rw-r--r--README_d/README.VMS155
-rw-r--r--README_d/README.bootstrap32
-rw-r--r--README_d/README.cmake95
-rw-r--r--README_d/README.gcc-311
-rw-r--r--README_d/README.hacking9
-rw-r--r--README_d/README.mpfr25
-rw-r--r--README_d/README.pc28
-rw-r--r--README_d/README.solaris18
-rw-r--r--TODO205
-rw-r--r--aclocal.m4696
-rw-r--r--array.c440
-rw-r--r--awk.h859
-rw-r--r--awkgram.c5384
-rw-r--r--awkgram.y1588
-rw-r--r--awklib/ChangeLog40
-rw-r--r--awklib/Makefile.am21
-rw-r--r--awklib/Makefile.in308
-rw-r--r--awklib/eg/data/BBS-list11
-rw-r--r--awklib/eg/data/mail-list11
-rw-r--r--awklib/eg/lib/ctime.awk1
-rw-r--r--awklib/eg/lib/div.awk17
-rw-r--r--awklib/eg/lib/ftrans.awk4
-rw-r--r--awklib/eg/lib/getopt.awk7
-rw-r--r--awklib/eg/lib/gettime.awk4
-rw-r--r--awklib/eg/lib/grcat.c2
-rw-r--r--awklib/eg/lib/groupawk.in6
-rw-r--r--awklib/eg/lib/inplace.awk14
-rw-r--r--awklib/eg/lib/noassign.awk2
-rw-r--r--awklib/eg/lib/processarray.awk12
-rw-r--r--awklib/eg/lib/pwcat.c2
-rw-r--r--awklib/eg/lib/quicksort.awk5
-rw-r--r--awklib/eg/lib/readable.awk2
-rw-r--r--awklib/eg/lib/readfile.awk15
-rw-r--r--awklib/eg/lib/shellquote.awk22
-rw-r--r--awklib/eg/lib/strtonum.awk21
-rw-r--r--awklib/eg/misc/arraymax.awk10
-rw-r--r--awklib/eg/misc/findpat.awk13
-rw-r--r--awklib/eg/prog/alarm.awk9
-rw-r--r--awklib/eg/prog/cut.awk23
-rw-r--r--awklib/eg/prog/egrep.awk14
-rw-r--r--awklib/eg/prog/extract.awk19
-rw-r--r--awklib/eg/prog/id.awk38
-rw-r--r--awklib/eg/prog/igawk.sh2
-rw-r--r--awklib/eg/prog/indirectcall.awk2
-rw-r--r--awklib/eg/prog/labels.awk3
-rw-r--r--awklib/eg/prog/pi.awk18
-rw-r--r--awklib/eg/prog/split.awk12
-rw-r--r--awklib/eg/prog/tee.awk6
-rw-r--r--awklib/eg/prog/uniq.awk10
-rw-r--r--bisonfix.awk33
-rwxr-xr-xbootstrap.sh8
-rw-r--r--builtin.c1077
-rw-r--r--cint_array.c151
-rw-r--r--cmake/Toolchain_clang.cmake19
-rw-r--r--cmake/Toolchain_generic.cmake21
-rw-r--r--cmake/Toolchain_mingw32.cmake23
-rw-r--r--cmake/Toolchain_s390.cmake20
-rw-r--r--cmake/auk.icobin0 -> 5190 bytes
-rwxr-xr-xcmake/basictest553
-rwxr-xr-xcmake/configure58
-rw-r--r--cmake/configure.cmake300
-rwxr-xr-xcmake/docmaker100
-rw-r--r--cmake/package.cmake54
-rw-r--r--cmd.h26
-rw-r--r--command.c1794
-rw-r--r--command.y124
-rwxr-xr-xcompile347
-rwxr-xr-xconfig.guess624
-rwxr-xr-xconfig.rpath120
-rwxr-xr-xconfig.sub385
-rw-r--r--configh.in74
-rwxr-xr-xconfigure1912
-rw-r--r--configure.ac152
-rw-r--r--custom.h14
-rw-r--r--debug.c827
-rwxr-xr-xdepcomp612
-rw-r--r--dfa.c4360
-rw-r--r--dfa.h33
-rw-r--r--doc/CMakeLists.txt95
-rw-r--r--doc/ChangeLog1254
-rw-r--r--doc/Makefile.am46
-rw-r--r--doc/Makefile.in335
-rw-r--r--doc/api-figure1.eps536
-rw-r--r--doc/api-figure1.fig40
-rw-r--r--doc/api-figure1.pdfbin0 -> 10707 bytes
-rw-r--r--doc/api-figure1.pngbin0 -> 9183 bytes
-rw-r--r--doc/api-figure1.txt24
-rw-r--r--doc/api-figure2.eps517
-rw-r--r--doc/api-figure2.fig26
-rw-r--r--doc/api-figure2.pdfbin0 -> 12031 bytes
-rw-r--r--doc/api-figure2.pngbin0 -> 8983 bytes
-rw-r--r--doc/api-figure2.txt12
-rw-r--r--doc/api-figure3.eps526
-rw-r--r--doc/api-figure3.fig29
-rw-r--r--doc/api-figure3.pdfbin0 -> 12345 bytes
-rw-r--r--doc/api-figure3.pngbin0 -> 8860 bytes
-rw-r--r--doc/api-figure3.txt13
-rw-r--r--doc/array-elements.eps158
-rw-r--r--doc/array-elements.fig27
-rw-r--r--doc/array-elements.pdfbin0 -> 6796 bytes
-rw-r--r--doc/array-elements.pngbin0 -> 6091 bytes
-rw-r--r--doc/array-elements.txt4
-rw-r--r--doc/awkcard.in344
-rw-r--r--doc/awkforai.txt158
-rw-r--r--doc/gawk.1900
-rw-r--r--doc/gawk.info24533
-rw-r--r--doc/gawk.texi26206
-rw-r--r--doc/gawkinet.info6
-rw-r--r--doc/gawkinet.texi8
-rw-r--r--doc/gawktexi.in41021
-rw-r--r--doc/general-program.pdfbin5588 -> 5613 bytes
-rw-r--r--doc/general-program.pngbin0 -> 6078 bytes
-rw-r--r--doc/general-program.txt4
-rw-r--r--doc/macros4
-rw-r--r--doc/process-flow.pdfbin6558 -> 6583 bytes
-rw-r--r--doc/process-flow.pngbin0 -> 7856 bytes
-rw-r--r--doc/process-flow.txt11
-rw-r--r--doc/sidebar.awk67
-rw-r--r--doc/texinfo.tex1914
-rw-r--r--eval.c1602
-rw-r--r--ext.c296
-rw-r--r--extension/.gitignore3
-rw-r--r--extension/ABOUT-NLS1282
-rw-r--r--extension/AUTHORS13
-rw-r--r--extension/CMakeLists.txt84
-rw-r--r--extension/COPYING674
-rw-r--r--extension/ChangeLog964
-rw-r--r--extension/INSTALL370
-rw-r--r--extension/Makefile.am130
-rw-r--r--extension/Makefile.in1258
-rw-r--r--extension/NEWS7
-rw-r--r--extension/README10
-rw-r--r--extension/README.fts68
-rw-r--r--extension/aclocal.m41224
-rw-r--r--extension/arrayparm.c83
-rw-r--r--extension/build-aux/ChangeLog33
-rwxr-xr-xextension/build-aux/ar-lib270
-rwxr-xr-xextension/build-aux/compile347
-rwxr-xr-xextension/build-aux/config.guess1568
-rwxr-xr-xextension/build-aux/config.rpath690
-rwxr-xr-xextension/build-aux/config.sub1793
-rwxr-xr-xextension/build-aux/depcomp756
-rwxr-xr-xextension/build-aux/install-sh480
-rw-r--r--extension/build-aux/ltmain.sh11044
-rwxr-xr-xextension/build-aux/missing215
-rw-r--r--extension/configh.in214
-rwxr-xr-xextension/configure17003
-rw-r--r--extension/configure.ac86
-rw-r--r--extension/dl.c92
-rwxr-xr-xextension/doit1
-rw-r--r--extension/filefuncs.3am370
-rw-r--r--extension/filefuncs.c986
-rw-r--r--extension/fnmatch.3am125
-rw-r--r--extension/fnmatch.c207
-rw-r--r--extension/foo.awk9
-rw-r--r--extension/fork.3am98
-rw-r--r--extension/fork.c143
-rw-r--r--extension/fts.3773
-rw-r--r--extension/gawkdirfd.h57
-rw-r--r--extension/gawkfts.c1263
-rw-r--r--extension/gawkfts.h157
-rw-r--r--extension/inplace.3am92
-rw-r--r--extension/inplace.c278
-rw-r--r--extension/m4/ChangeLog30
-rw-r--r--extension/m4/dirfd.m484
-rw-r--r--extension/m4/gettext.m4383
-rw-r--r--extension/m4/iconv.m4214
-rw-r--r--extension/m4/intlmacosx.m451
-rw-r--r--extension/m4/lib-ld.m4110
-rw-r--r--extension/m4/lib-link.m4774
-rw-r--r--extension/m4/lib-prefix.m4224
-rw-r--r--extension/m4/libtool.m48027
-rw-r--r--extension/m4/ltoptions.m4382
-rw-r--r--extension/m4/ltsugar.m4124
-rw-r--r--extension/m4/ltversion.m423
-rw-r--r--extension/m4/lt~obsolete.m499
-rw-r--r--extension/m4/nls.m432
-rw-r--r--extension/m4/po.m4449
-rw-r--r--extension/m4/progtest.m492
-rw-r--r--extension/ordchr.3am78
-rw-r--r--extension/ordchr.c101
-rw-r--r--extension/readdir.3am105
-rw-r--r--extension/readdir.c334
-rw-r--r--extension/readfile.3am87
-rw-r--r--extension/readfile.c222
-rw-r--r--extension/revoutput.3am74
-rw-r--r--extension/revoutput.c139
-rw-r--r--extension/revtwoway.3am64
-rw-r--r--extension/revtwoway.c342
-rw-r--r--extension/rwarray.3am103
-rw-r--r--extension/rwarray.awk28
-rw-r--r--extension/rwarray.c535
-rw-r--r--extension/rwarray0.c475
-rw-r--r--extension/stack.c90
-rw-r--r--extension/stack.h31
-rwxr-xr-xextension/steps23
-rw-r--r--extension/testarg.awk7
-rw-r--r--extension/testarg.c55
-rw-r--r--extension/testarrayparm.awk10
-rw-r--r--extension/testext.c884
-rw-r--r--extension/testff.awk30
-rw-r--r--extension/testfork.awk20
-rw-r--r--extension/testordchr.awk6
-rw-r--r--extension/time.3am89
-rw-r--r--extension/time.c221
-rw-r--r--extension/xreadlink.c95
-rw-r--r--extension/xreadlink.h23
-rw-r--r--extras/ChangeLog3
-rw-r--r--extras/Makefile.am29
-rw-r--r--extras/Makefile.in516
-rw-r--r--extras/gawk.csh11
-rw-r--r--extras/gawk.sh31
-rw-r--r--field.c294
-rw-r--r--floatcomp.c24
-rw-r--r--gawkapi.c1155
-rw-r--r--gawkapi.h926
-rw-r--r--gawkmisc.c2
-rw-r--r--getopt.c161
-rw-r--r--getopt.h29
-rw-r--r--getopt1.c12
-rw-r--r--getopt_int.h8
-rw-r--r--gettext.h39
-rw-r--r--helpers/ChangeLog41
-rw-r--r--helpers/chlistref.awk31
-rwxr-xr-xhelpers/do.outline102
-rw-r--r--helpers/fixdump.awk69
-rwxr-xr-xhelpers/quoteconvert2.sh49
-rw-r--r--helpers/scanfmt.c22
-rw-r--r--helpers/testdfa.c1082
-rw-r--r--helpers/testnet.awk12
-rw-r--r--helpers/testnet.c396
-rw-r--r--helpers/tryfmt.c23
-rwxr-xr-xinstall-sh487
-rw-r--r--int_array.c115
-rw-r--r--interpret.h1427
-rw-r--r--io.c2152
-rw-r--r--m4/ChangeLog91
-rw-r--r--m4/codeset.m412
-rw-r--r--m4/gettext.m458
-rw-r--r--m4/glibc2.m418
-rw-r--r--m4/glibc21.m418
-rw-r--r--m4/iconv.m4110
-rw-r--r--m4/intdiv0.m450
-rw-r--r--m4/intl.m4121
-rw-r--r--m4/intldir.m46
-rw-r--r--m4/intlmacosx.m412
-rw-r--r--m4/intmax.m412
-rw-r--r--m4/inttypes-pri.m412
-rw-r--r--m4/inttypes_h.m429
-rw-r--r--m4/lcmessage.m411
-rw-r--r--m4/lib-ld.m477
-rw-r--r--m4/lib-link.m443
-rw-r--r--m4/lib-prefix.m42
-rw-r--r--m4/lock.m4308
-rw-r--r--m4/longlong.m4106
-rw-r--r--m4/mpfr.m462
-rw-r--r--m4/nls.m42
-rw-r--r--m4/noreturn.m438
-rw-r--r--m4/po.m438
-rw-r--r--m4/printf-posix.m415
-rw-r--r--m4/progtest.m421
-rw-r--r--m4/readline.m478
-rw-r--r--m4/size_max.m437
-rw-r--r--m4/stdint_h.m429
-rw-r--r--m4/uintmax_t.m414
-rw-r--r--m4/visibility.m434
-rw-r--r--m4/wchar_t.m410
-rw-r--r--m4/wint_t.m420
-rw-r--r--m4/xsize.m46
-rw-r--r--main.c1047
-rw-r--r--mbsupport.h59
-rwxr-xr-xmissing460
-rw-r--r--missing_d/ChangeLog36
-rw-r--r--missing_d/fnmatch.c489
-rw-r--r--missing_d/fnmatch.h85
-rw-r--r--missing_d/gawkbool.h (renamed from eval_d.c)25
-rw-r--r--missing_d/snprintf.c8
-rw-r--r--missing_d/strtoul.c12
-rw-r--r--missing_d/wcmisc.c100
-rwxr-xr-xmkinstalldirs9
-rw-r--r--mpfr.c1783
-rw-r--r--msg.c75
-rw-r--r--node.c168
-rw-r--r--nonposix.h (renamed from eval_p.c)12
-rw-r--r--old-extension/ChangeLog13
-rw-r--r--old-extension/bindarr.c347
-rw-r--r--old-extension/dbarray.awk222
-rw-r--r--old-extension/fileop.c394
-rw-r--r--old-extension/record.awk252
-rw-r--r--old-extension/sparr.c163
-rw-r--r--old-extension/spec_array.c416
-rw-r--r--old-extension/spec_array.h (renamed from profile_p.c)15
-rwxr-xr-xold-extension/steps10
-rw-r--r--old-extension/testdbarray.awk21
-rwxr-xr-xold-extension/testrecord.sh19
-rw-r--r--old-extension/testsparr.awk18
-rw-r--r--pc/ChangeLog405
-rw-r--r--pc/Makefile148
-rw-r--r--pc/Makefile.ext75
-rw-r--r--pc/Makefile.tst2491
-rw-r--r--pc/config.h149
-rw-r--r--pc/config.sed167
-rw-r--r--pc/dlfcn.h12
-rw-r--r--pc/gawkmisc.pc316
-rw-r--r--pc/in.h1
-rw-r--r--pc/install.awk10
-rw-r--r--pc/popen.c95
-rw-r--r--pc/popen.h5
-rw-r--r--pc/socket.h42
-rw-r--r--pc/testoutcmp.awk57
-rw-r--r--po/CMakeLists.txt133
-rw-r--r--po/ChangeLog29
-rw-r--r--po/LINGUAS3
-rw-r--r--po/Makefile.in.in53
-rw-r--r--po/Makevars39
-rw-r--r--po/Makevars.template37
-rw-r--r--po/POTFILES.in23
-rw-r--r--po/Rules-quot15
-rw-r--r--po/ast.gmobin37068 -> 0 bytes
-rw-r--r--po/ca.gmobin25787 -> 83005 bytes
-rw-r--r--po/ca.po3734
-rw-r--r--po/da.gmobin48739 -> 42160 bytes
-rw-r--r--po/da.po3119
-rw-r--r--po/de.gmobin52166 -> 45199 bytes
-rw-r--r--po/de.po2780
-rw-r--r--po/es.gmobin51471 -> 44600 bytes
-rw-r--r--po/es.po2800
-rw-r--r--po/fi.gmobin51684 -> 84555 bytes
-rw-r--r--po/fi.po2847
-rwxr-xr-xpo/fix-merge.awk6
-rw-r--r--po/fr.gmobin53311 -> 85628 bytes
-rw-r--r--po/fr.po2667
-rw-r--r--po/ga.gmobin33929 -> 0 bytes
-rw-r--r--po/gawk.pot2436
-rw-r--r--po/he.gmobin24651 -> 0 bytes
-rw-r--r--po/id.gmobin35809 -> 0 bytes
-rw-r--r--po/id.po3182
-rw-r--r--po/it.gmobin44316 -> 81018 bytes
-rw-r--r--po/it.po3076
-rw-r--r--po/ja.gmobin55596 -> 52559 bytes
-rw-r--r--po/ja.po2718
-rw-r--r--po/ms.gmobin0 -> 1184 bytes
-rw-r--r--po/ms.po3350
-rw-r--r--po/nl.gmobin49267 -> 80863 bytes
-rw-r--r--po/nl.po2746
-rw-r--r--po/pl.gmobin50946 -> 71101 bytes
-rw-r--r--po/pl.po2732
-rw-r--r--po/pt_BR.gmobin29120 -> 0 bytes
-rw-r--r--po/ro.gmobin25383 -> 0 bytes
-rw-r--r--po/rw.gmobin487 -> 0 bytes
-rw-r--r--po/sv.gmobin48752 -> 80917 bytes
-rw-r--r--po/sv.po3213
-rw-r--r--po/tr.gmobin33826 -> 0 bytes
-rw-r--r--po/vi.gmobin40445 -> 93025 bytes
-rw-r--r--po/vi.po3704
-rw-r--r--po/zh_CN.gmobin33717 -> 0 bytes
-rw-r--r--posix/ChangeLog56
-rw-r--r--posix/gawkmisc.c44
-rw-r--r--profile.c671
-rw-r--r--protos.h6
-rw-r--r--random.h11
-rw-r--r--re.c219
-rw-r--r--regcomp.c183
-rw-r--r--regex.c18
-rw-r--r--regex.h85
-rw-r--r--regex_internal.c64
-rw-r--r--regex_internal.h37
-rw-r--r--regexec.c62
-rw-r--r--replace.c11
-rw-r--r--str_array.c173
-rw-r--r--symbol.c452
-rw-r--r--test/CMakeLists.txt90
-rw-r--r--test/ChangeLog958
-rwxr-xr-xtest/Gentests28
-rw-r--r--test/Makefile.am1091
-rw-r--r--test/Makefile.in2843
-rw-r--r--test/Maketests1615
-rw-r--r--test/backbigs1.awk1
-rw-r--r--test/backbigs1.in1
-rw-r--r--test/backbigs1.ok0
-rw-r--r--test/backsmalls1.awk1
-rw-r--r--test/backsmalls1.in36
-rw-r--r--test/backsmalls1.ok14
-rw-r--r--test/backsmalls2.awk10
-rw-r--r--test/backsmalls2.ok0
-rw-r--r--test/badargs.ok9
-rw-r--r--test/badassign1.awk1
-rw-r--r--test/badassign1.ok3
-rw-r--r--test/badbuild.awk6
-rw-r--r--test/badbuild.in1
-rw-r--r--test/badbuild.ok3
-rw-r--r--test/beginfile2.ok10
-rwxr-xr-xtest/beginfile2.sh40
-rwxr-xr-xtest/charasbytes.awk1
-rw-r--r--test/charasbytes.in1
-rw-r--r--test/charasbytes.ok3
-rw-r--r--test/clos1way.awk2
-rw-r--r--test/colonwarn.awk4
-rw-r--r--test/colonwarn.in1
-rw-r--r--test/colonwarn.ok3
-rw-r--r--test/dbugeval.in2
-rw-r--r--test/dbugeval.ok1
-rw-r--r--test/dfamb1.awk4
-rw-r--r--test/dfamb1.in1
-rw-r--r--test/dfamb1.ok2
-rw-r--r--test/dumpvars.ok2
-rw-r--r--test/exit2.awk2
-rw-r--r--test/exit2.ok0
-rw-r--r--test/filefuncs.awk25
-rw-r--r--test/filefuncs.ok0
-rw-r--r--test/fmtspcl-mpfr.ok0
-rw-r--r--test/fnarydel-mpfr.ok27
-rw-r--r--test/fnmatch.awk13
-rw-r--r--test/fnmatch.ok8
-rw-r--r--test/fnparydl-mpfr.ok10
-rw-r--r--test/fork.awk33
-rw-r--r--test/fork.ok0
-rw-r--r--test/fork2.awk35
-rw-r--r--test/fork2.ok0
-rw-r--r--test/fts.awk146
-rw-r--r--test/functab1.awk3
-rw-r--r--test/functab1.ok2
-rw-r--r--test/functab2.awk8
-rw-r--r--test/functab2.ok2
-rw-r--r--test/functab3.awk10
-rw-r--r--test/functab3.ok2
-rw-r--r--test/functab4.awk30
-rw-r--r--test/functab4.ok4
-rw-r--r--test/genpot.awk1
-rw-r--r--test/genpot.ok5
-rw-r--r--test/gensub2.ok1
-rw-r--r--test/getline5.awk35
-rw-r--r--test/getline5.ok1
-rw-r--r--test/hello.awk3
-rw-r--r--test/id.awk11
-rw-r--r--test/id.ok74
-rw-r--r--test/incdupe.ok3
-rw-r--r--test/incdupe2.ok2
-rw-r--r--test/incdupe3.ok2
-rw-r--r--test/incdupe4.ok2
-rw-r--r--test/incdupe5.ok2
-rw-r--r--test/incdupe6.ok3
-rw-r--r--test/incdupe7.ok3
-rw-r--r--test/inchello.awk1
-rw-r--r--test/inclib.awk7
-rw-r--r--test/include.awk5
-rw-r--r--test/include.ok2
-rw-r--r--test/include2.ok2
-rw-r--r--test/indirectcall2.awk11
-rw-r--r--test/indirectcall2.ok4
-rw-r--r--test/inplace.1.in2
-rw-r--r--test/inplace.2.in2
-rw-r--r--test/inplace.in3
-rw-r--r--test/inplace1.1.ok2
-rw-r--r--test/inplace1.2.ok2
-rw-r--r--test/inplace1.ok6
-rw-r--r--test/inplace2.1.bak.ok2
-rw-r--r--test/inplace2.1.ok2
-rw-r--r--test/inplace2.2.bak.ok2
-rw-r--r--test/inplace2.2.ok2
-rw-r--r--test/inplace2.ok6
-rw-r--r--test/inplace3.1.bak.ok2
-rw-r--r--test/inplace3.1.ok2
-rw-r--r--test/inplace3.2.bak.ok2
-rw-r--r--test/inplace3.2.ok2
-rw-r--r--test/inplace3.ok12
-rw-r--r--test/jarebug.awk1
-rw-r--r--test/jarebug.in4
-rw-r--r--test/jarebug.ok4
-rwxr-xr-xtest/jarebug.sh21
-rw-r--r--test/lintwarn.ok7
-rw-r--r--test/mbprintf4.awk35
-rw-r--r--test/mbprintf4.in3
-rw-r--r--test/mbprintf4.ok81
-rw-r--r--test/messages.awk2
-rw-r--r--test/mpfrbigint.awk11
-rw-r--r--test/mpfrbigint.ok5
-rw-r--r--test/mpfrexprange.awk7
-rw-r--r--test/mpfrexprange.ok2
-rw-r--r--test/mpfrieee.awk13
-rw-r--r--test/mpfrieee.ok12
-rw-r--r--test/mpfrnegzero.awk15
-rw-r--r--test/mpfrnegzero.ok9
-rw-r--r--test/mpfrnr.awk10
-rw-r--r--test/mpfrnr.in3
-rw-r--r--test/mpfrnr.ok1
-rw-r--r--test/mpfrrem.awk6
-rw-r--r--test/mpfrrem.ok4
-rw-r--r--test/mpfrrnd.awk15
-rw-r--r--test/mpfrrnd.ok10
-rw-r--r--test/mpfrsort.awk8
-rw-r--r--test/mpfrsort.ok11
-rw-r--r--test/mpfrsqrt.awk82
-rw-r--r--test/mpfrsqrt.ok2
-rw-r--r--test/nfloop.awk8
-rw-r--r--test/nfloop.ok1
-rwxr-xr-xtest/ofs1.awk23
-rw-r--r--test/ofs1.in4
-rw-r--r--test/ofs1.ok7
-rw-r--r--test/ordchr.awk10
-rw-r--r--test/ordchr.ok5
-rw-r--r--test/ordchr2.ok1
-rw-r--r--test/paramuninitglobal.awk15
-rw-r--r--test/paramuninitglobal.ok4
-rw-r--r--test/parseme.ok2
-rw-r--r--test/printfbad3.awk22
-rw-r--r--test/printfbad3.ok1
-rw-r--r--test/printfbad4.awk5
-rw-r--r--test/printfbad4.ok2
-rw-r--r--test/printhuge.awk3
-rw-r--r--test/printhuge.ok1
-rw-r--r--test/profile2.ok6
-rw-r--r--test/profile3.ok2
-rw-r--r--test/profile4.awk8
-rw-r--r--test/profile4.ok9
-rw-r--r--test/profile5.awk5179
-rw-r--r--test/profile5.ok8354
-rw-r--r--test/profile6.awk7
-rw-r--r--test/profile6.ok10
-rw-r--r--test/profile7.awk12
-rw-r--r--test/profile7.ok15
-rw-r--r--test/profile8.awk9
-rw-r--r--test/profile8.ok14
-rw-r--r--test/rand-mpfr.ok1
-rw-r--r--test/rand-mpfr1.ok1
-rw-r--r--test/rand.ok2
-rw-r--r--test/randtest.ok0
-rwxr-xr-xtest/randtest.sh113
-rw-r--r--test/readdir.awk3
-rw-r--r--test/readdir0.awk44
-rw-r--r--test/readfile2.awk12
-rw-r--r--test/readfile2.ok21
-rw-r--r--test/regexpbrack.awk2
-rw-r--r--test/regexpbrack.in0
-rw-r--r--test/regexpbrack.ok0
-rw-r--r--test/regexprange.awk14
-rw-r--r--test/regexprange.ok52
-rw-r--r--test/reginttrad.awk6
-rw-r--r--test/reginttrad.ok1
-rw-r--r--test/regnul1.awk84
-rw-r--r--test/regnul1.ok8
-rw-r--r--test/regnul2.awk112
-rw-r--r--test/regnul2.ok27
-rw-r--r--test/regrange.ok2
-rw-r--r--test/revout.awk6
-rw-r--r--test/revout.ok1
-rw-r--r--test/revtwoway.awk11
-rw-r--r--test/revtwoway.ok2
-rw-r--r--test/rri1.awk1
-rw-r--r--test/rri1.in1
-rw-r--r--test/rri1.ok0
-rw-r--r--test/rsgetline.awk23
-rw-r--r--test/rsgetline.in1
-rw-r--r--test/rsgetline.ok3
-rw-r--r--test/rsglstdin.ok3
-rw-r--r--test/rtlenmb.ok3
-rw-r--r--test/rwarray.awk40
-rw-r--r--test/rwarray.in780
-rw-r--r--test/rwarray.ok3
-rwxr-xr-xtest/sortglos.awk51
-rwxr-xr-xtest/sortglos.in22
-rw-r--r--test/sortglos.ok15
-rw-r--r--test/split_after_fpat.awk11
-rw-r--r--test/split_after_fpat.in1
-rw-r--r--test/split_after_fpat.ok4
-rw-r--r--test/strftime.awk42
-rw-r--r--test/symtab1.awk21
-rw-r--r--test/symtab1.ok31
-rw-r--r--test/symtab2.awk6
-rw-r--r--test/symtab2.ok2
-rw-r--r--test/symtab3.awk1
-rw-r--r--test/symtab3.ok2
-rw-r--r--test/symtab4.awk1
-rw-r--r--test/symtab4.in2
-rw-r--r--test/symtab4.ok2
-rw-r--r--test/symtab5.awk1
-rw-r--r--test/symtab5.in2
-rw-r--r--test/symtab5.ok2
-rw-r--r--test/symtab6.awk1
-rw-r--r--test/symtab6.ok26
-rw-r--r--test/symtab7.awk7
-rw-r--r--test/symtab7.in3
-rw-r--r--test/symtab7.ok2
-rw-r--r--test/symtab8.awk5
-rw-r--r--test/symtab8.in1
-rw-r--r--test/symtab8.ok27
-rw-r--r--test/symtab9.awk19
-rw-r--r--test/symtab9.ok1
-rw-r--r--test/testext.ok79
-rw-r--r--test/time.awk22
-rw-r--r--test/time.ok3
-rw-r--r--version.c2
-rw-r--r--version.in3
-rw-r--r--vms/ChangeLog299
-rw-r--r--vms/backup_gawk_src.com113
-rw-r--r--vms/build_gawk_pcsi_desc.com428
-rw-r--r--vms/build_gawk_pcsi_text.com179
-rw-r--r--vms/build_gawk_release_notes.com67
-rw-r--r--vms/compare_gawk_source.com367
-rw-r--r--vms/config_h.com1661
-rw-r--r--vms/descrip.mms322
-rw-r--r--vms/fcntl.h10
-rw-r--r--vms/gawk.hlp34
-rw-r--r--vms/gawk_alias_setup.com139
-rw-r--r--vms/gawk_build_steps.txt220
-rw-r--r--vms/gawk_ident.com21
-rw-r--r--vms/gawk_plugin.opt5
-rw-r--r--vms/gawk_release_note_start.txt189
-rw-r--r--vms/gawk_verb.com26
-rw-r--r--vms/gawkmisc.vms488
-rw-r--r--vms/generate_config_vms_h_gawk.com298
-rw-r--r--vms/gnv_gawk_startup.com75
-rw-r--r--vms/make_pcsi_gawk_kit_name.com189
-rw-r--r--vms/pcsi_gawk_file_list.txt120
-rw-r--r--vms/pcsi_product_gawk.com187
-rw-r--r--vms/remove_old_gawk.com113
-rw-r--r--vms/stage_gawk_install.com300
-rw-r--r--vms/vax/ChangeLog11
-rw-r--r--vms/vax/gawk_plugin_xfer.mar_exact13
-rw-r--r--vms/vax/gawk_plugin_xfer.opt5
-rw-r--r--vms/vax/macro32_exactcase.com16
-rw-r--r--vms/vax/macro32_exactcase.patch11
-rw-r--r--vms/vms-conf.h661
-rw-r--r--vms/vms.h24
-rw-r--r--vms/vms_args.c24
-rw-r--r--vms/vms_cli.c32
-rw-r--r--vms/vms_crtl_init.c470
-rw-r--r--vms/vms_fwrite.c16
-rw-r--r--vms/vms_gawk.c27
-rw-r--r--vms/vms_misc.c35
-rw-r--r--vms/vms_popen.c17
-rw-r--r--vms/vmsbuild.com100
-rw-r--r--vms/vmstest.com810
-rw-r--r--xalloc.h34
-rwxr-xr-x[-rw-r--r--]ylwrap201
650 files changed, 240532 insertions, 50315 deletions
diff --git a/.gitignore b/.gitignore
index e2ae74d3..72445191 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,14 +5,14 @@
# Directories
autom4te.cache
.deps
+*.dSYM
# Single files.
Makefile
config.h
config.log
config.status
-dgawk
gawk
-pgawk
stamp-h1
+test/fmtspcl.ok
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 00000000..154d2afb
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,108 @@
+#
+# CMakeLists.txt --- CMake input file for gawk
+#
+# Copyright (C) 2013
+# 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 3 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 CMake to produce Makefile
+
+cmake_minimum_required (VERSION 2.6)
+project (gawk C)
+
+include(cmake/configure.cmake)
+
+set (EXTRA_LIBS "")
+
+if (${HAVE_MPFR})
+ set (EXTRA_LIBS ${EXTRA_LIBS} mpfr gmp)
+endif ()
+if (${HAVE_LIBREADLINE})
+ set (EXTRA_LIBS ${EXTRA_LIBS} readline)
+endif ()
+if (${DYNAMIC})
+ set (EXTRA_LIBS ${EXTRA_LIBS} ${CMAKE_DL_LIBS} )
+endif ()
+
+include_directories(${CMAKE_SOURCE_DIR})
+
+if(WIN32 OR "${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
+ # This is enough to build with MinGW in a native Windows environment
+ # and also with a cross-compiler on OpenSuSE 12.2.
+ # On Ubuntu 12.04 patches to gawk's source code are needed:
+ # - insert #include <windows.h> at the top of awk.h
+ # - remove function execvp from pc/gawkmisc.pc
+ DefineConfigHValue(HAVE_SETENV 1)
+ DefineConfigHValue(HAVE_USLEEP 1)
+ DefineConfigHValue(STDC_HEADERS 1)
+ DefineConfigHValue(HAVE_STRINGIZE 1)
+ include_directories(${CMAKE_SOURCE_DIR}/missing_d)
+ DefineConfigHValue(HAVE_MKSTEMP 1)
+ set (EXTRA_LIBS ${EXTRA_LIBS} ws2_32)
+ # TODO: Eli Zaretskii remined me that the generated
+ # settings in config.h should be the same as those in
+ # pc/config.h. With these settings and DYNAMIC=1
+ # it looks like functions in dynamic libs (extensions) can
+ # be invoked on Windows.
+ DefineConfigHValue(HAVE_GETSYSTEMTIMEASFILETIME 1)
+ set (GAWK_SOURCES ${GAWK_SOURCES} regex.c pc/getid.c pc/gawkmisc.pc pc/popen.c)
+ include_directories(${CMAKE_SOURCE_DIR}/pc)
+endif()
+
+set (GAWK_SOURCES ${GAWK_SOURCES}
+ array.c
+ builtin.c
+ cint_array.c
+ command.c
+ debug.c
+ dfa.c
+ eval.c
+ ext.c
+ field.c
+ floatcomp.c
+ gawkapi.c
+ gawkmisc.c
+ int_array.c
+ io.c
+ main.c
+ mpfr.c
+ msg.c
+ node.c
+ profile.c
+ random.c
+ re.c
+ replace.c
+ str_array.c
+ symbol.c
+ version.c
+)
+
+add_executable (gawk ${GAWK_SOURCES} ${BISON_awkgram_OUTPUTS})
+target_link_libraries (gawk m ${EXTRA_LIBS})
+install(PROGRAMS ${CMAKE_BINARY_DIR}/gawk${CMAKE_EXECUTABLE_SUFFIX} DESTINATION bin)
+
+# Beware: before building the extension, -DGAWK gets undefined.
+add_subdirectory(extension)
+enable_testing()
+add_subdirectory(test)
+add_subdirectory(doc)
+include(InstallRequiredSystemLibraries)
+set(CPACK_PACKAGING_INSTALL_PREFIX /usr)
+include(cmake/package.cmake)
diff --git a/ChangeLog b/ChangeLog
index dbead39b..75a049da 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,3550 @@
+2015-01-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.c (api_set_array_element): Remove useless call to
+ make_aname.
+ * symbol.c (load_symbols): Ditto.
+ Thanks to Andrew Schorr for pointing out the problem.
+
+2015-01-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.c: Update to bison 3.0.3.
+ * command.c: Ditto.
+ * NEWS: Note same.
+
+2015-01-16 Stephen Davies <sdavies@sdc.com.au>
+
+ * awkgram.y (rule): Set first_rule to false. Catches more cases
+ for gathering comments. Thanks to Hermann Peifer for the test case.
+
+2015-01-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.h, dfa.c: Sync with grep. Mainly copyright updates.
+ * getopt.c, getopt.h, getopt1.c getopt_int.h: Sync with GLIBC.
+ Mainly copyright updates, one minor code fix.
+
+2015-01-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ Remove deferred variables.
+
+ * awk.h (register_deferred_variable): Remove declaration.
+ * awkgram.y (is_deferred_variable, process_deferred,
+ symtab_used, extensions_used, deferred_variables,
+ process_deferred): Remove declarations, bodies, and uses.
+ * builtin.c (do_length): Update comment.
+ * main.c (init_vars): Just call load_procinfo() and `load_environ()'.
+
+2015-01-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Update debug flags if developing.
+ * awkgram.y (yylex): Regex parsing bug fix for bracket expressions.
+ Thanks to Mike Brennan for the report.
+ * builtin.c (format_tree): Catch non-use of count$ for dynamic
+ field width or precision.
+
+ Unrelated:
+
+ Load deferred variables if extensions are used; they might
+ want to access PROCINFO and/or ENVIRON. Thanks to Andrew Schorr
+ for pointing out the issue.
+
+ * awkgram.y (extensions_used): New variable. Set it on @load.
+ (do_add_scrfile): Set it on -l.
+ (process_deferred): Check it also.
+
+2014-12-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile.c (pprint): Be sure to set ip2 in all paths
+ through the code. Thanks to GCC 4.9 for the warning.
+
+2014-12-12 Stephen Davies <sdavies@sdc.com.au>
+
+ Improve comment handling in pretty printing.
+
+ * awk.h (comment_type): New field in the node.
+ (EOL_COMMENT, FULL_COMMENT): New defines.
+ * awkgram.y (block_comment): New variable.
+ (check_comment): New function.
+ (grammar): Add code to handle comments as needed.
+ (get_comment): Now takes a flag indicating kind of comment.
+ (yylex): Collect comments appropriately.
+ (append_rule): Ditto.
+ * profile.c (pprint): Smarten up comment handling.
+ Have printing \n take comments into account.
+ (end_line): New function.
+ (pp_func): Better handling of function comments.
+
+2014-12-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Sync with GNU grep.
+
+2014-11-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_sub): Improve wording of gensub warnings.
+
+2014-11-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_sub): For gensub, add more warnings for invalid
+ third argument.
+
+2014-11-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h: Move all inline functions to the bottom of the file.
+ Keeps modern GCC happier.
+
+2014-11-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (emalloc, realloc): Redefine in terms of ...
+ (emalloc_real, eralloc_real): New static inline functions.
+ (fatal): Move definition up.
+ * gawkmisc.c (xmalloc): If count is zero, make it one for older
+ mallocs that require size > 0 (such as z/OS).
+
+2014-11-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c: Remove a debugging // comment.
+ * NOTES: Removed.
+
+ Unrelated:
+
+ Revert changes of 2014-11-20 from Paul Eggert. Causes failures
+ on z/OS.
+
+ Unrelated: Avoid unnecessary copying of $0.
+
+ * interpret.h (UNFIELD): New macro.
+ (r_interpret): Use it where *lhs is assigned to.
+
+2014-11-20 Paul Eggert <eggert@cs.ucla.edu>
+
+ Port to systems where malloc (0) and/or realloc(P, 0) returns NULL.
+ * gawkmisc.c (xmalloc):
+ * xalloc.h (realloc):
+ Do not fail if malloc(0) or realloc(P, 0) returns NULL.
+ Fail only when the allocator returns null when attempting to
+ allocate a nonzero number of bytes.
+
+2014-11-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ Infrastructure upgrades:
+
+ * Automake 1.14.1, Gettext 0.19.3, Libtool 2.4.3.
+ * compile, extension/build-aux/compile: New files.
+
+2014-11-19 gettextize <bug-gnu-gettext@gnu.org>
+
+ * configure.ac (AM_GNU_GETTEXT_VERSION): Bump to 0.19.3.
+
+2014-11-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * interpret.h: Revert change of 2014-11-11 since it breaks
+ certain uses.
+
+ Unrelated:
+
+ * dfa.c: Sync with GNU grep.
+
+2014-11-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c, awk.h, awkgram.y, builtin.c, dfa.c, eval.c, field.c,
+ interpret.h, io.c, main.c, mpfr.c, node.c, re.c, regex_internal.h,
+ replace.c: Remove all uses of MBS_SUPPORT.
+ * regex_internal.h: Disable wide characters on DJGPP.
+ * mbsupport.h: Rework to be needed only for DJGPP.
+
+2014-11-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ Don't let memory used increase linearly in the size of
+ the input. Problem reported by dragan legic
+ <dragan.legic@yandex.ru>.
+
+ * field.c (set_record): NUL-terminate the buffer.
+ * interpret.h (r_interpret): Op_field_spec: if it's $0, increment
+ the valref. Op_store_var: if we got $0, handle it appropriately.
+
+2014-11-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ Reorder main.c activities so that we can set a locale on the
+ command line with the new, for now undocumented, -Z option.
+
+ * main.c (parse_args, set_locale_stuff): New functions.
+ (stopped_early): Made file level static.
+ (optlist, optab): Add new argument.
+ (main): Adjust ordering and move inline code into new functions.
+
+2014-11-09 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.c (node_to_awk_value): When the type wanted is AWK_UNDEFINED
+ and a it's a Node_val set to Nnull_string, return AWK_UNDEFINED instead
+ of AWK_NUMBER 0.
+
+2014-11-03 Norihiro Tanaka <noritnk@kcn.ne.jp>
+
+ * re.c (research): Use dfa superset to improve matching speed.
+
+2014-11-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile.c (div_on_left_mul_on_right): New function.
+ (parenthesize): Call it.
+
+2014-10-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure: Regenerated after fix to m4/readline.m4.
+
+ Unrelated; fixes to profiling. Thanks to Hermann Peifer and
+ Manuel Collado for pointing out problems:
+
+ * profile.c (pprint): For Op_unary_minus, parenthesize -(-x)
+ correctly.
+ (prec_level): Get the levels right (checked the grammar).
+ (is_unary_minus): New function.
+ (pp_concat): Add checks for unary minus; needs to be parenthesized.
+
+2014-10-30 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * NEWS: Mention installation of /etc/profile.d/gawk.{csh,sh}.
+
+2014-10-29 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * configure.ac (AC_CONFIG_FILES): Add extras/Makefile.
+ * Makefile.am (SUBDIRS): Add extras.
+ * extras: Add new subdirectory.
+
+2014-10-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Sync with GNU grep. Again, again.
+
+2014-10-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Sync with GNU grep. Again.
+
+2014-10-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Sync with GNU grep.
+
+2014-10-17 John E. Malmberg <wb8tyw@qsl.net>
+
+ * ext.c (close_extensions): Test for null pointer since
+ since this can be called by signal handler before the
+ pointers are initialized.
+
+2014-10-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ Make sane the handling of AWKPATH and AWKLIBPATH:
+
+ 1. Don't explicitly search "."; it must be in the path either
+ physically or as null element a la the shell's $PATH
+ 2. If environment's value was empty, use built-in default value.
+ 3. Set ENVIRON["AWK*PATH"] to the path used.
+
+ * io.c (path_info): Remove try_cwd member.
+ (get_cwd): Removed, not needed anymore.
+ (do_find_source): Don't do explicit check in current directory.
+ It must come from the AWKPATH or AWKLIBPATH variable.
+ * main.c (path_environ): If value from environment was empty,
+ set it to the default. This is how gawk has behaved since 2.10.
+
+2014-10-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regcomp.c (__re_error_msgid): Make error message for REG_EBRACK
+ more helpful - also used for unmatched [:, [., [=.
+ Thanks to Davide Brini for raising the issue.
+
+2014-10-12 KO Myung-Hun <komh78@gmail.com>
+
+ Fixes for OS/2:
+
+ * Makefile.am (install-exec-hook, uninstall-links): Use $(EXEEXT).
+ * getopt.h: Redefinitions if using KLIBC.
+ * io.c (_S_IFDIR, _S_IRWXU): Define if the more standard versions
+ are available.
+
+2014-10-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * README: Remove Pat Rankin from VMS duties, per his request.
+
+2014-10-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Sync with GNU grep.
+
+2014-10-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile.c (pprint): Fix typo in header. Sheesh.
+
+ Unrelated:
+
+ * awkgram.y (mk_program): Add a comment that we don't need to
+ clear the comment* variables.
+
+2014-10-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile.c (pp_string_fp): Fix breaklines case to actually
+ output the current letter. This broke at gawk 4.0.0. Sigh.
+ Thanks to Bert Bos (bert@w3.org) for the report.
+
+2014-10-03 Stephen Davies <sdavies@sdc.com.au>
+
+ * awkgram.y (program_comment): Renamed from comment0.
+ (function_comment): Renamed from commentf.
+
+2014-10-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y, profile.c: Minor white space cleanups.
+
+2014-10-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ Fix a few compile warnings:
+
+ * awkgram.y (split_comment): Make static.
+ General: Remove some unused variables, clean up some whitepace nits.
+
+ * profile.c (indent): Add some braces to turn off compiler warnings.
+
+2014-09-29 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * main.c (main): In optlist, it should say "h", not "h:", since there
+ is no argument for the help option. Thanks to Joep van Delft for
+ the bug report.
+
+2014-09-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.h: Minor edits to sync with documentation. Does not
+ influence the behavior of the API.
+
+2014-09-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * command.y (cmdtab): Add "where" as an alias for "backtrace".
+ Finally!
+
+ Unrelated:
+
+ * dfa.c: Sync with GNU grep.
+
+2014-09-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (check_for_bad): Bitwise-and the bad character with 0xFF
+ to avoid sign extension into a large integer.
+
+ Unrelated:
+
+ * configure.ac: Add an option to enable locale letters in identifiers.
+ Undocumented and subject to being rescinded at any time in the future.
+ * NEWS: Mention to look at configure --help.
+
+ Unrelated:
+
+ * profile.c (pprint): Use "rule(s)" instead of "block(s)" in the
+ header.
+
+2014-09-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (yylex): Don't check for junk characters inside
+ quoted strings. Caused issues on DJGPP and Solaris.
+
+ Unrelated:
+
+ * io.c (devopen): Straighten things out with respect to
+ compatibility with BWK awk.
+
+2014-09-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y: Further commentary as to the treacherousness
+ of isalnum and isalpha.
+
+2014-09-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ Finish removing use of isalpha and isalnum.
+
+ * awk.h (is_alpha, is_alnum, is_identchar): Add declarations.
+ * awkgram.y (yylex): Use is_alpha.
+ (is_alpha, is_alnum): New functions.
+ (is_identchar): Use is_alnum.
+ * builtin.c (r_format_tree): Use is_alpha, is_alnum.
+ * command.y (yylex): Use is_alpha, is_identchar.
+ * ext.c (is_letter): Use is_alpha.
+ (is_identifier_char): Removed; replaced uses with is_identchar.
+ * main.c (arg_assign): Use is_alpha, is_alnum.
+ * node.c (r_force_number): Use is_alpha.
+
+2014-09-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (is_identchar): Change from simple macro to function
+ since use of isalnum() let non-ASCII letters slip through into
+ identifiers.
+
+2014-09-13 Stephen Davies <sdavies@sdc.com.au>
+
+ When doing pretty-printing (but not profiling), include the original
+ comments in the output.
+
+ General rules:
+
+ Pretty printing:
+ - Do NOT indent by a tab
+ - Do NOT print the header comments ("# BEGIN rules", etc.)
+ - DO print the comments that are in the program
+
+ Profiling:
+ - DO indent by a tab
+ - DO print the header comments
+ - Do NOT print the program's original comments
+
+ * awkgram.y (comment0, commentf): New varibles that are pointers to
+ program and function comments.
+ (get_comment): New function that retrieves consecutive comment lines
+ and empty lines as a unit).
+ (split_comment): New function: iff first block in the program is a
+ function and it is predeeded by comments, take the last non-blank
+ line as function comment and any preceeding lines as program comment.)
+
+ Following token rules were changed to handle comments:
+
+ * awkgram.y (pattern, LEX_BEGIN, LEX_END, LEX_BEGINFILE, LEX_ENDFILE,
+ action, function_prologue, statements): Update to handle comments.
+
+ Following functions were changed to handle comments:
+
+ * awkgram.y (mk_program, mk_function, allow_newline and yylex): Update
+ to handle comments. (Also fixed typo in case '\\'.)
+
+ * profile.c (print_comment): New function to format comment printing.
+ (indent, pprint, dump_prog, pp_func): Changed to handle comments and
+ the revised indentation rules.
+
+2014-09-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h: Move libsigsegv stuff to ...
+ * main.c: here. Thanks to Yehezkel Bernat for motivating
+ the cleanup.
+ * symbol.c (make_symbol, install, install_symbol): Add const to
+ first parameter. Adjust decls and fix up uses.
+
+2014-09-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ Add builtin functions to FUNCTAB for consistency.
+
+ * awk.h (Node_builtin_func): New node type.
+ (install_builtins): Declare new function.
+ * awkgram.y [DEBUG_USE]: New flag value for debug functions; they
+ don't go into FUNCTAB.
+ (install_builtins): New function.
+ * eval.c (nodetypes): Add Node_builtin_func.
+ * interpret.h (r_interpret): Rework indirect calls of built-ins
+ since they're now in the symbol table.
+ * main.c (main): Call `install_builtins'.
+ * symbol.c (install): Adjust for Node_builtin_func.
+ (load_symbols): Ditto.
+
+2014-09-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile.c (pprint): Case Op_K_for: Improve printing of
+ empty for loop header.
+
+ Unrelated: Make indirect function calls work for built-in and
+ extension functions.
+
+ * awkgram.y (lookup_builtin): New function.
+ * awk.h (builtin_func_t): New typedef.
+ (lookup_builtin): Declare it.
+ * interpret.h (r_interpret): For indirect calls, add code to
+ find and call builtin functions, and call extension functions.
+
+2014-09-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_substr): Return "" instead of null string in case
+ result is passed to length() with --lint. Based on discussions in
+ comp.lang.awk.
+
+ Unrelated:
+
+ * interpret.h (r_interpret): For indirect function call, separate
+ error message if lookup returned NULL. Otherwise got a core dump.
+ Thanks to "Kenny McKormack" for the report in comp.lang.awk.
+
+2014-08-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Add test for strcasecmp.
+ * regcomp.c: Remove special case code around use of strcasecmp().
+ * replace.c: Include missing/strncasecmp.c if either strcasecmp()
+ or strncasecmp() aren't available.
+
+2014-08-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regcomp.c, regex_internal.c: Sync with GBLIC. Why not.
+
+ Unrelated:
+
+ Remove support for MirBSD. It uglified the code too much
+ for no discernable gain.
+
+ * configure.ac: Remove check for MirBSD and define of
+ LIBC_IS_BORKED.
+ * dfa.c: Remove code depending on LIBC_IS_BORKED.
+ * main.c: Ditto.
+ * regcomp.c: Ditto.
+ * NEWS: Updated.
+
+2014-08-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regex.h: Remove underscores in names of parameters in function
+ declarations. Tweak names as neeeded.
+
+2014-08-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * node.c (parse_escape): Max of 2 digits after \x.
+
+2014-08-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * symbol.c: General formatting cleanup.
+
+2014-08-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (usage): Adjust whitespace for -L and add "invalid"
+ as a possible value for it. Report from Robert P. J. Day
+ <rpjday@crashcourse.ca>.
+
+2014-08-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (SUBDIRS): Put awklib after doc so that examples
+ get extracted when the doc changes.
+
+2014-08-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_sub): Move initial allocation of the replacement
+ string down towards code to do the replacement, with a (we hope)
+ better guesstimate of how much to initially allocate. The idea
+ is to avoid unnecessary realloc() calls by making a better guess
+ at how much to allocate. This came up in an email discussion
+ with Tom Dickey about mawk's gsub().
+
+2014-08-12 Juergen Kahrs <jkahrs@users.sourceforge.net>
+
+ * cmake/configure.cmake:
+ * cmake/package.cmake: Copyright update.
+ * README.cmake:
+ * README_d/README.cmake: Moved file.
+
+2014-08-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ OFS being set should rebuild $0 using previous OFS if $0
+ needs to be rebuilt. Thanks to Mike Brennan for pointing this out.
+
+ * awk.h (rebuild_record): Declare.
+ * eval.c (set_OFS): If not being called from var_init(), check
+ if $0 needs rebuilding. If so, parse the record fully and rebuild it.
+ Make OFS point to a separate copy of the new OFS for next time, since
+ OFS_node->var_value->stptr was already updated at this point.
+ * field.c (rebuild_record): Is now extern instead of static.
+ Use OFS and OFSlen instead of the value of OFS_node.
+
+ Unrelated:
+
+ * Makefile.am (RM): Define for makes that don't have it,
+ such as on OpenBSD. Thanks to Jeremie Courreges-Anglas
+ <jca@wxcvbn.org> for the report.
+
+2014-08-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ Bug fix: For MPFR sqrt(), need to set precision of result to be
+ the same as that of the argument. Doesn't hurt other functions.
+ See test/mpfrsqrt.awk. Thank to Katie Wasserman <katie@wass.net>
+ for the bug report.
+
+ * mpfr.c (do_mpfr_func): New function. Runs code for MPFR functions
+ while still enabling debugging. Add call here to mpfr_set_prec().
+ Original code from SPEC_MATH macro.
+ (SPEC_MATH): Change macro to call do_mpfr_func().
+
+ Next MPFR bug fix: The % operator gave strange results for negative
+ numerator. Thanks again to Katie Wasserman for the bug report.
+
+ * mpfr.c (mpg_mod): Use mpz_tdiv_qr() instead of mpz_mod(). From
+ the GMP doc, mpz_mod() should have worked; it's not clear why
+ it doesn't.
+
+2014-08-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (format_tree): Don't need to check return value of
+ wctombr for -2. Thanks to Eli Zaretskii for pointing this out.
+
+ Unrelated:
+
+ * gawkapi.h: Fix doc for API get_record - errcode needs to
+ be greater than zero.
+ * interpret.h (r_interpret): Move setting of ERRNO to here, from ...
+ * io.c (inrec): ... here. Makes the code cleaner.
+
+2014-08-03 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * awkgram.y (getfname): Match on either ptr or ptr2 so --profile
+ will work in -M (MPFR bignum) mode.
+
+2014-07-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (format_tree): Make %c handling more sane on Windows.
+ Rework the lint messages.
+
+ Unrelated:
+
+ * dfa.c: Sync with GNU grep. Mainly white space differences.
+
+ Unrelated:
+
+ * mpfr.c (cleanup_mpfr): New function to deallocate _mpf_t1
+ and _mpf_t2; removes some valgrind warnings.
+ * awk.h (cleanup_mpfr): Add declaration.
+ * main.c (main): Add call to `cleanup_mpfr'.
+
+ Fix memory leak:
+
+ * mpfr.c (do_mpfr_div): Add unref to denominator and numerator
+ to not leak memory. Thanks to Katie Wasserman <katie@wass.net>
+ for isolating the problem to that routine.
+
+2014-07-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (main): Add a warning message if -M is used and gawk was
+ compiled without MPFR/GMP.
+
+2014-07-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (usage): Put text for `-n' *after* text for `-m'.
+ Report from Robert P. J. Day <rpjday@crashcourse.ca>.
+
+ Fix problems with I/O errors reported by Assaf Gordon
+ <assafgordon@gmail.com>:
+
+ * io.c (inrec): Change type to bool to make calling easier. Add
+ check in non-EOF case for error, and if so, return false.
+ Update ERRNO in case there is an ENDFILE block.
+ * awk.h (inrec): Change type in declaration.
+ * interpret.h (r_interpret): Change call of inrec() to boolean
+ notation.
+
+2014-07-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ New `div()' function to do integer division and remainder;
+ mainly useful for use with GMP integers. Thanks to
+ Katie Wasserman <katie@wass.net> for the suggestion.
+
+ * awk.h (do_div, do_mpfr_div): Declare new functions.
+ * builtin.c (do_div): New function.
+ * mpfr.c (do_mpfr_div): New function.
+ * awkgram.y (tokentab): New entry.
+ (snode): Add check for do_div/do_mpfr_div to make 3rd arg
+ be an array.
+ * NEWS: Updated.
+ * TODO: Updated.
+
+2014-07-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (check_for_bad): New routine to do the fatal message,
+ with smarter checking.
+ (nextc): Call it as appropriate.
+
+ * builtin.c (format_tree): Add check for bad returns from mbrlen
+ to avoid trying to malloc (size_t) -1 bytes. Thanks to
+ mail.green.fox@gmail.com for the bug report.
+
+2014-07-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (nextc): Add bool check_for_bad parameter to check
+ for bad characters in the source program.
+ (yylex): Adjust calls.
+
+2014-06-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (main): The --pretty-print option no longer runs the
+ program. This removes the need for the GAWK_NO_PP_RUN environment var.
+ * NEWS: Updated.
+ * TODO: Updated.
+
+2014-06-22 Paul Eggert <eggert@penguin.cs.ucla.edu>
+
+ Bring in from GNULIB:
+
+ regex: fix memory leak in compiler
+ Fix by Andreas Schwab in:
+ https://sourceware.org/ml/libc-alpha/2014-06/msg00462.html
+ * lib/regcomp.c (parse_expression): Deallocate partially
+ constructed tree before returning error.
+
+2014-06-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_sub): Add more info to leading comment.
+ Add some whitespace in the code.
+
+2014-06-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Sync with GNU grep.
+
+2014-06-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c (mbs_to_wchar): Define a macro if not MBS.
+
+2014-05-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Sync with GNU grep.
+
+2014-05-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (inetfile): Change return type to bool. Wrap code
+ with ifdef HAVE_SOCKETS so that it'll compile on DJGPP.
+
+2014-05-22 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ Allow any redirected getline inside BEGINFILE/ENDFILE.
+
+ * awkgram.y (LEX_GETLINE): Only require a redirection and not also
+ a variable if getline is in a BEGINFILE or ENDFILE rule.
+ * interpret.h (Op_K_getline_redir): Remove check and fatal error.
+
+2014-05-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c (dfaexec): Minor sync with GNU grep.
+
+2014-05-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * custom.h (_GL_PURE): Move definition to here. Sigh.
+ * dfa.h, dfa.c: Sync with GNU grep. Sigh.
+
+ Unrelated:
+
+ * custom.h: Remove stuff for Ultrix 4.3. No one has such
+ systems anymore; this just got missed earlier.
+
+2014-05-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * debug.c (do_eval): Repair fix of 2014-05-09 and use
+ assoc_remove to take @eval out of the function table.
+ * symbol.c: Fix a comment. This file needs some work.
+
+2014-05-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (get_a_record): Finish TERMNEAREND handling in case
+ we don't have a regular file but aren't going to get more data.
+ Added some additional comments.
+
+2014-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * debug.c (do_eval): Don't free `f' which points into the context
+ that was previously freed. Bug reported by Jan Chaloupka
+ <jchaloup@redhat.com>. Apparently introduced with move to
+ SYMTAB and FUNCTAB, but only showed up on Fedora 20 and Ubuntu 14.04,
+ which have a newer glibc.
+ (do_eval): Fix a memory leak seen by valgrind on Fedora 20 and
+ Ubuntu 14.04: the new SRCFILE that is added wasn't released.
+
+ Unrelated:
+
+ * io.c (get_a_record): Handle return of TERMNEAREND when the
+ entire file has been read into the buffer and we're using a
+ regex for RS. Bug report by Grail Dane <grail69@hotmail.com>.
+
+2014-05-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * debug.c (debug_prog): Change check for GAWK_RESTART so that it
+ actually works. Bug fix: run command in debugger would start
+ over again but not actually start running the program.
+
+2014-04-25 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * io.c (two_way_open): In forked child, reset SIGPIPE to SIG_DFL.
+ Fixes problems with "broken pipe" errors from child processes,
+ restoring 4.1.0 and earlier behavior. Thanks to Daryl F
+ <wyatt@prairieturtle.ca> for the report.
+ (gawk_popen): Ditto.
+
+2014-04-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.h, dfa.c: Merge with GNU grep; lots of forward motion.
+
+2014-04-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ Update xalloc.h for pending merge with dfa.
+
+ * xalloc.h (xstrdup): Implement this.
+ (x2nrealloc): Incorporate changed logic from GNULIB.
+
+2014-04-20 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * io.c (struct inet_socket_info): Define new structure
+ for use in parsing special socket filenames.
+ (inetfile): Parse all components of the special socket filename
+ into the struct inet_socket_info. Returns true only if it is a
+ valid socket fliename, unlike the previous version which checked
+ for the '/inet[46]?/' prefix only.
+ (redirect): Patch to use updated inetfile() function.
+ (devopen): Remove logic to parse socket filenames, since this has
+ been moved into the inetfile() function.
+ (two_way_open): Update args to inetfile().
+
+2014-04-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_rand): Make calls to random() in predictable
+ order to avoid order of evaluation differences amongst compilers.
+ Thanks to Anders Magnusson <ragge@ludd.ltu.se> (of the PCC team)
+ for the suggestion.
+
+2014-04-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Change adding of -export-dynamic for GCC to be
+ -Wl,-export-dynamic, which then works for PCC also.
+
+2014-04-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (closemabyesocket): Define if not defined, e.g. building
+ without socket code. Thanks to dave.gma@googlemail.com (Dave Sines)
+ for the report.
+
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.1: Release tar ball made.
+
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * README: Update.
+ * configure.ac: Bump version.
+
+2014-04-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regcomp.c (parse_bracket_exp): Move a call to `re_free' inside
+ an ifdef. Makes the code marginally cleaner.
+
+2014-03-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Sync with GNU grep.
+
+2014-03-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Remove duplicate AC_HEADER_TIME and rearrange
+ order of macros some. May help on older systems.
+
+2014-03-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Move include of dfa.h around for correct building
+ on Irix. Thanks to Nelson H.F. Beebe for the report.
+
+ Unrelated:
+
+ * .gitignore: Simplify .dSYM pattern for Mac OS X.
+
+2014-03-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c (using_simple_locale): Add ifdefs in case there is no
+ locale support at all. Thanks to Scott Deifik for the report.
+
+ Unrelated:
+
+ * main.c (UPDATE_YEAR): Set to 2014.
+
+2014-03-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ * .gitignore: Add .dSYM directories for Mac OS X.
+ Thanks to Hermann Peifer for the suggestion.
+
+2014-03-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.h, dfa.c: Sync with grep. Yet again.
+ * regex_internal.c (built_wcs_upper_buffer, build_upper_buffer):
+ Fixes from GNULIB for mixed case matching on Mac OS X.
+
+ Unrelated:
+
+ * builtin.c (format_tree): Smarten handling of %' flag. Always
+ pass it in for floating point formats. Then only add the
+ thousands_sep if there is one. Also, allow for thousands_sep
+ to be a string, not just one character. Thanks to Michal Jaegermann
+ for the report.
+
+2014-03-08 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.c (api_impl): Add memory allocation function pointers.
+ * gawkapi.h (GAWK_API_MINOR_VERSION): Bump.
+ (gawk_api_t): Add memory allocation function pointers api_malloc,
+ api_calloc, api_realloc, and api_free.
+ (gawk_malloc, gawk_calloc, gawk_realloc, gawk_free): New macros.
+ (emalloc): Replace malloc with gawk_malloc.
+ (erealloc): Replace erealloc with gawk_erealloc.
+
+2014-03-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ Straighten out enumerated types some more.
+
+ * awk.h (add_srcfile): Fix type of first parameter.
+ * awkgram.y (add_srcfile, do_add_srcfile): Ditto.
+ * cmd.h (A_NONE): New enum nametypeval.
+ * command.y (argtab): Use it in final value.
+ * ext.c (make_builtin): Use awk_false, awk_true.
+ * io.c (init_output_wrapper): Use awk_false.
+
+ Unrelated:
+
+ * debug.c (do_commands): Initialize num to silence warnings.
+ Thanks to Michal Jaegermann.
+
+ Unrelated:
+
+ * builtin.c (do_mktime): Change lint warning for minutes to
+ check against 59, not 60. Thanks to Hermann Peifer for the report.
+
+2014-03-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Sync with grep. Yet again.
+
+2014-02-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Sync with grep. Looks like good improvement with
+ respect to bracket expressions.
+
+2014-02-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ Fixes for enum/int mismatches as warned by some compilers.
+
+ * awk.h (ANONE): New enum for array sorting.
+ * array.c (assoc_list): Use it.
+ * builtin.c (format_tree): New MP_NONE value.
+ * gawkapi.c: Use awk_false and awk_true everywhere instead of
+ false and true.
+
+2014-02-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Set up do-nothing extension/Makefile on
+ MirBSD also.
+
+2014-02-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.h, dfa.c (parse_bracket_exp): Sync with grep.
+
+2014-02-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regex.h, regex.c, regex_internal.c, regex_internal.h: Sync
+ with GLIBC. Mainly copyright updates.
+ * getopt.c, getopt.h, getopt1.c, getopt_int.h: Ditto.
+ * dfa.c (parse_bracket_exp): Sync with grep, where they restored
+ the buggy code. Sigh.
+
+ Unrelated:
+
+ * NEWS: Typo fix.
+ * interpret.h (r_interpret): Init a variable for BEGINFILE to avoid
+ compiler warnings. Thanks to Michal Jaegermann.
+
+2014-02-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.c, command.c: Regenerated - Bison 3.0.2.
+
+2014-02-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c (to_uchar): Make use of this. Syncs with GNU grep.
+
+2014-02-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (negate_num): Bracket `tval' in #ifdef MPFR since it's
+ only used in that code.
+
+2014-01-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (dist-hook): Improve creation of pc/config.h. We
+ have to jump through a lot of hoops for 'make distcheck' to
+ actually work.
+
+2014-01-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (dist-hook): Improve creation of pc/config.h to copy
+ the new file into the distribution directory being created.
+ Also, put the temporary files into /tmp.
+
+2014-01-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (negate_num): If just a double, return. Fixes a bug
+ that showed up on 32-bit systems with MPFR. Thanks to Eli Zaretskii
+ and Corinna Vinschen for the report. Also, free the MPZ integer.
+ Thanks to valgrind for the report.
+
+ Unrelated:
+
+ * dfa.c: Sync with GNU grep - removed some special cased code
+ for grep.
+
+2014-01-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac, field.c: Update copyright year.
+
+2014-01-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (negate_num): Handle the case of -0 for MPFR; the sign
+ was getting lost. Thanks to Hermann Peifer for the report.
+
+2014-01-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c (parse_bracket_exp): Sync with GNU grep, which now uses
+ gawk's code for RRI in single-byte locales! Hurray.
+
+2014-01-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: For z/OS, restore creation of do-nothing
+ Makefile in extension directory.
+
+2014-01-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * field.c (do_split): Make sure split() gets FS value if no
+ third arg even after FPAT was set. Thanks to Janis Papanagnou
+ for the report.
+
+2014-01-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * README: Fix John Malmberg's email address.
+
+2014-01-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y: Update copyright year.
+ (func_use): Simplify code.
+ * command.y: Update copyright year.
+ * ext.c: Update copyright year.
+ (make_builtin): Small simplification.
+ (make_old_builtin): Make code consistent with make_builtin(), add
+ call to track_ext_func().
+ * bootstrap.sh: Update copyright year. Remove touch of version.c
+ since that file is no longer autogenerated.
+
+2014-01-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * command.y (next_word): Move into ifdef for HAVE_LIBREADLINE,
+ since it's only used by that code.
+ * ext.c (load_old_ext): Minor improvements.
+
+2014-01-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * config.guess, config.rpath, config.sub, depcomp,
+ install-sh: Updated.
+ * dfa.h, dfa.c: Sync with GNU grep; comment fix and copyright year.
+ * NEWS: Updated some, including copyright year.
+
+2013-12-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * README: Add John Malmberg for VMS.
+
+2013-12-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * getopt.h: Add `defined(__sun)' to list of system that do get to
+ include stdlib.h. Needed for Illumos. Thanks to
+ Richard Palo <richard.palo@free.fr> for the report.
+
+2013-12-21 Mike Frysinger <vapier@gentoo.org>
+
+ * configure.ac: Add --disable-extensions flag to control
+ compiling extensions. Better for cross-compiling.
+ (AC_CANONICAL_HOST): Added. Changed case statments appropriately.
+ * Makefile.am (check-for-shared-lib-support): Removed.
+ (check-recursive, all-recursive): Removed.
+
+2013-12-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * config.guess: Updated.
+ * configure, aclocal.m4: Updated based on automake 1.13.4.
+
+2013-12-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regexec.c (re_search_internal): Make sure `dfa' pointer is
+ not NULL before trying to dereference it.
+
+2013-12-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac (AC_FUNC_VPRINTF): Remove. Not needed on current
+ systems.
+ * awk.h (HAVE_VPRINTF): Remove check.
+
+2013-12-12 John E. Malmberg <wb8tyw@qsl.net>
+
+ * io.c (redirect): Add additional VMS error codes.
+ (nextfile): Retry open after closing some files.
+
+2013-12-10 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * io.c (closemaybesocket): Add definition for DJGPP.
+
+2013-12-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (Floor, Ceil): Remove declarations and VMS redefinitions.
+ * floatcomp.c (Floor, Ceil): Removed, not needed. Move bracketing
+ ifdef to the top of the file.
+ * builtin.c (double_to_int): Use floor() and ceil().
+
+2013-12-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regex_internal.h (__attribute__): Define to empty if not GCC.
+ * custom.h (__attribute__): Remove the definition from here; the
+ right place was regex_internal.h.
+
+2013-12-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ No need to generate version.c from version.in.
+ Thanks to John E. Malmberg <wb8tyw@qsl.net> for the suggestion.
+
+ * version.in: Removed.
+ * version.c: Use PACKAGE_STRING directly.
+ * Makefile.am (EXTRA_DIST): Remove version.in.
+ (distcleancheck_listfiles): Remove this rule.
+ (MAINTAINERCLEANFILES): Remove this definition.
+ (version.c): Remove the rule to create it.
+
+2013-12-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ Fixes for Z/OS.
+
+ * custom.h (__attribute__): Define to empty.
+ * dfa.c (parse_bracket_exp): Add a cast to quiet a warning.
+ * regex.c: Correctly bracket include of <sys/param.h>.
+
+ Unrelated:
+
+ * debug.c (find_rule): Add a FIXME comment.
+
+2013-12-03 John E. Malmberg <wb8tyw@qsl.net>
+
+ * io.c (redirect): Add additional VMS error code to check.
+ (do_find_source): Append "/" if not a VMS filename.
+
+2013-12-01 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * main.c (optab): Sort by long option name.
+
+2013-11-27 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * main.c (optab): Add entry for --include.
+
+2013-11-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Merge from grep; minor fixes in how bit twiddling
+ is done.
+
+2013-11-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c (lex): Reset laststart so that stuff like \s* works.
+ Fix from grep.
+
+2013-10-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (efwrite): If write error to stdout is EPIPE,
+ die silently. Thanks to Hermann Peifer for helping find this.
+
+2013-10-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ Revise error messages when writing to standard output or standard
+ error to ignore EPIPE. Add the ability based on an environment
+ variable to get the source file and line number.
+
+ * awk.h (r_warning): Renamed from warning.
+ (warning): New macro to set location and call warning.
+ * io.c (flush_io): Print errors only if not EPIPE.
+ (close_io): Ditto.
+ * main.c (lintfunc): Init to r_warning.
+ (main): Enhance explanatory comment.
+ (usage): Print errors only if not EPIPE.
+ (copyleft): Ditto.
+ * msg.c (err): Make printing srcfile and srcline depend upon
+ GAWK_MSG_SRC environment variable.
+ (r_warning): Renamed from warning.
+
+2013-10-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (main): Ignore SIGPIPE. See the comment in the code.
+ Thanks to Alan Broder for reporting the issue.
+
+ Unrelated:
+
+ * rand.c (do_rand): Fix computation and loop checking against
+ 1.0 to use do..while.
+
+2013-10-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ Make -O work again. Turns out that C99 bool variables
+ are clamped to zero or one.
+
+ * main.c (do_optimize): Init to false.
+ (main): Set do_optimize to true on -O.
+ * eval.c (setup_frame): Change all uses of do_optimize to be
+ a boolean check instead of a test > 1.
+ * awkgram.y: Ditto.
+ (optimize_assignment): Remove check against do_optimize since
+ it was inited to true anyway.
+
+ Unrelated:
+
+ * re.c (resetup): Add a comment about the joy of syntax bits.
+
+ Unrelated:
+
+ * builtin.c (do_rand): If result is exactly 1.0, keep trying.
+ Thanks to Nelson Beebe.
+
+2013-10-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c (lex): Sync with GNU grep. Handle multibyte \s and \S.
+
+ Unrelated:
+
+ * awk.h [ARRAY_MAXED]: Fix value of this and subsequent flags
+ after addition of NULL_FIELD.
+ * eval.c (flags2str): Add NULL_FIELD. Duh.
+
+2013-10-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (mk_assignment): Rework switch to handle Op_assign,
+ and to provide a better error message upon unknown opcode.
+
+2013-09-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Sync with GNU grep.
+
+2013-09-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_rand): Make the result more random by calling
+ random() twice. See the comment in the code. Thanks to
+ Bob Jewett <jewett@bill.scs.agilent.com> for the report and
+ the fix.
+
+2013-09-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * debug.c (find_rule): Handle case where lineno is zero. Can happen
+ if break is given without a line number on a current line. Thanks
+ to Ray Song <i@maskray.me> for the report.
+
+2013-09-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c (parse_bracket_exp): Use code from grep to keep things within
+ range (updates change of 2013-09-08). Fix whitespace in one of the
+ gawk-only additions.
+
+2013-09-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ Fix use of NF after it's extended, e.g. see test/nfloop.awk.
+
+ * awk.h (NULL_FIELD): New flag
+ * builtin.c (do_print_rec): Check f0->flags instead of if
+ equal to Nnull_string.
+ * eval.c (r_get_field): Check (*lhs)->flags instead of if
+ equal to Nnull_string or Null_field.
+ * field.c (init_fields): Init field zero and Null_field with
+ NULL_FIELD flag.
+ (set_NF): Set parse_high_water = NF in case NF extended past the
+ end. This is the actual bug fix.
+
+2013-09-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ Fixes based on reports from a static code checker. Thanks to
+ Anders Wallin for sending in the list.
+
+ * array.c (asort_actual): Free list if it's not NULL.
+ * builtin.c (do_sub): Set buf to NULL and assert on it before using
+ it.
+ * cint_array.c (cint_array_init): Clamp any value of NHAT from the
+ environment such that it won't overflow power_two_table when used as
+ an index.
+ * dfa.c (parse_bracket_exp): Check that len is in range before using it
+ to index buf.
+ * getopt.c (_getopt_internal_r): Change call to alloca to use malloc.
+ * io.c (socket_open): Init read_len to zero.
+ (two_way_open): Upon failure to fork, close the slave fd also.
+ * re.c (research): Init try_backref to false.
+ * regcomp.c (build_range_exp): Free any items that were allocated in
+ the case where not all items were.
+ (build_charclass_op): Same. Init br_token to zero with memset.
+ (create_tree): Init token t to zero with memset.
+ * regex_internal.c (re_dfa_add_node): Free any items that were
+ allocated in the case where not all items were.
+ * symbol.c (destroy_symbol): On default, break, to fall into releasing
+ of resources.
+
+2013-08-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * debug.c (HAVE_HISTORY_LIST): Move checks and defines to the top.
+ (do_save, serialize): Adjust #if checks to depend on having both
+ readline and the history functions. Needed for Mac OS X whose
+ native readline is a very old version. Sigh.
+ * configh.in, configure: Regenerated due to change in m4/readline.m4.
+ Issue reported by Hermann Peifer and Larry Baker.
+
+ Unrelated:
+
+ * getopt.c: Sync with GLIBC, changes are minor.
+
+ Unrelated:
+
+ * dfa.c: Sync with version in grep. Primarily whitespace / comment
+ wording changes.
+
+2013-08-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regcomp.c (parse_dup_op): Remove RE_TOKEN_INIT_BUG code (change of
+ Feb 19 2005) since it's no longer needed.
+
+ * regcomp.c (re_fastmap_iter): Undo addition of volatile from
+ Jan 18 2007; no longer needed and is one less change to have to
+ maintain aginst the upstream.
+
+ * regcomp.c, regex.h, regex_internal.h: Sync with GLIBC.
+
+2013-08-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ * str_array.c (env_store): If the new value being stored is NULL,
+ pass in "" instead. Avoids core dump on Mac OS X.
+ Thanks to Hermann Peifer for the bug report.
+
+2013-08-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * nonposix.h: New file. Contains FAKE_FD_VALUE.
+ * awk.h: Include it if MinGW or EMX.
+ * Makefile.am (base_sources): Add nonposix.h.
+
+2013-08-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ Reflect updates to ENVIRON into the real environment.
+
+ * awk.h (init_env_array): Add declaration.
+ * main.c (load_environ): Call init_env_array.
+ * str_array.c (env_remove, env_store, env_clear, init_env_array):
+ New functions.
+ (env_array_func): New array vtable.
+
+2013-08-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (force_array): Set symbol->xarray to NULL before
+ initing the array if it was Node_var_new.
+ (null_array): Restore assert, undoing change of 2013-05-27.
+
+2013-08-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * debug.c (print_memory): Fix whitespace / indentation.
+
+2013-08-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (append_rule): Add attempt to insert any comment
+ before a rule. Commented out at the moment.
+
+2013-07-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (enum opcodeval): Add Op_comment.
+ * awkgram.y (comment): New variable to hold comment text.
+ (statement): Add saved comments to lists being built.
+ (allow_newline): Save comment text if necessary. Append if have
+ existing text.
+ (yylex): Ditto.
+ * debug.c (print_instruction): Handle Op_comment.
+ * eval.c (optypes): Add entry for Op_comment.
+ * interpret.h (r_interpret): Ditto.
+ * profile.c (pprint): For Op_comment, print the comment text.
+
+2013-07-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (FAKE_FD_VALUE): Move definition from here ...
+ * awk.h (FAKE_FD_VALUE): ... to here. Fixes compilation on MinGW.
+
+2013-07-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (get_a_record): Change `min' to `MIN' for consistency with
+ other files and general practice.
+
+2013-07-04 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.h (awk_element_t): Add comment indicating that the array
+ element index will always be a string!
+ * gawkapi.c (api_flatten_array): When converting the index to an awk
+ value, request a string conversion, since we want the indices to
+ appear as strings to the extensions. This makes the call to
+ force_string redundant, since node_to_awk_value does that internally
+ when we request a string.
+
+2013-07-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (format_tree): Fixes for %c with multibyte characters
+ and field width > 1. Bugs reported by Nethox <nethox@gmail.com>.
+
+2013-07-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile.c (pp_string): Add a call to chksize and fix another.
+ Avoids valgrind errors on profile5 test. Thanks to Andrew
+ Schorr for the report.
+
+2013-06-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y: Minor whitespace cleanup, remove redundant ifdef.
+
+2013-06-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c (copytoks): Rewrite to call addtok_mb() directly. Avoids
+ problems with multibyte characters inside character sets.
+ Thanks to Steven Daniels <stevendaniels88@gmail.com> for reporting
+ the problem. Much thanks to Mike Haertel <mike@ducky.net> for the
+ analysis and fix.
+
+2013-06-24 Eli Zaretskii <eliz@gnu.org>
+
+ * io.c: Move #include "popen.h" out of the HAVE_SOCKETS condition,
+ as this is needed for non-sockets builds as well. See
+ http://lists.gnu.org/archive/html/bug-gawk/2013-06/msg00014.html
+ for the details of the problem this caused.
+
+2013-06-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c: Add ifdefs for VMS so that it will compile again.
+ Thanks to Anders Wallin.
+
+2013-06-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * debug.c (print_lines): Move setting of binary mode to after all
+ the messing with the fd. Simplifies code some.
+ * io.c (srcopen): Rearrange so that can add call to setbinmode
+ here too. This fixes the debugger and makes reading source
+ files a little faster. Thanks again to Corinna Vinschen.
+
+2013-06-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * debug.c (print_lines): Set binary mode so that calculation of the
+ byte offsets will be right. Thanks to Corinna Vinschen for the
+ direction.
+
+2013-06-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * re.c (check_bracket_exp): Remove warning about ranges being
+ locale dependent, since they aren't anymore.
+
+2013-06-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (iop_finish): Change fstat call to fcntl/F_GETFL per
+ Eli Z., for Windows.
+
+2013-06-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * eval.c (unwind_stack): If exiting, don't worry about strange stuff
+ on the stack.
+
+ Unrelated:
+
+ * awk.h (init_sockets): Declare.
+ * io.c (init_io): Remove ifdef around call.
+
+2013-06-01 Eli Zaretskii <eliz@gnu.org>
+
+ * io.c (SHUT_RD) [SD_RECEIVE]: Define to SD_RECEIVE.
+ (SHUT_WR) [SD_SEND]: Define to SD_SEND.
+ (SHUT_RDWR) [SD_BOTH]: Define to SD_BOTH.
+ (FD_TO_SOCKET, closemaybesocket) [!FD_TO_SOCKET]: New macros.
+ (SOCKET_TO_FD, SOCKET) [!SOCKET_TO_FD]: New macros.
+ (PIPES_SIMULATED): Define only for DJGPP.
+ (pipe) [__MINGW32__]: Define to call _pipe, unless PIPES_SIMULATED
+ is defined.
+ (init_io) [HAVE_SOCKETS]: Call init_sockets.
+ (iop_close, socketopen): Call closemaybesocket instead of close.
+ (redirect) [__MINGW32__]: Call wait_any with a non-zero argument.
+ (devopen) [__EMX__ || __MINGW32__]: Don't call stat on network
+ pseudo-filenames.
+ (two_way_open) [HAVE_SOCKETS]: Switch input and output to binary
+ mode if appropriate.
+ (two_way_open) [!PIPES_SIMULATED]: Use the __EMX__ code for MinGW
+ as well.
+ [__MINGW32__] Call spawnl to invoke $ComSpec and pass it a
+ suitably quoted command line.
+ (two_way_open) [__MINGW32__]: Wait only for a specified process
+ ID. If successful, update the exit status of the exited process.
+ Don't use signals that are undefined on MinGW.
+ (two_way_open) [!PIPES_SIMULATED]: Use the __EMX__ code for MinGW
+ as well.
+ (min): Define only if not already defined.
+ (read_with_timeout) [__MINGW32__]: Allow reading from sockets with
+ timeout.
+ (gawk_fclose) [__MINGW32__]: Close the underlying socket as well.
+
+ * getopt.c: Include stdlib.h for MinGW as well.
+
+2013-05-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ More profiling fixes:
+
+ * profile.c (pprint): For Op_in_array, parenthesize subscript if
+ the precedence is lower. E.g.: (c = tolower(foo)) in ARRAY.
+ (prec_level): Merge cases for precedence of 5.
+ (parenthesize): Simplify, as in 3.1.8. Avoids stuff like
+ `(x == 1 && (z ==2 && (q == 4 && w == 7)))'.
+
+ Unrelated:
+
+ * io.c (iop_finish): fstat the fd before closing it to avoid
+ errors on some operating systems. Thanks to Eli Zaretskii
+ for the report.
+
+2013-05-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile.c (pp_group3): Renamed from pp_concat. Change all calls.
+ (is_binary): Change return type to bool.
+ (is_scalar): New function.
+ (pp_concat): New function to handle concatenation operator better.
+ (pprint): Call it at case Op_concat. Fix Op_K_delete if multiple
+ indexes to separate with "][".
+ General: Add leading comments as needed.
+
+2013-05-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (main): Add minor hack to not run code if pretty printing
+ and undocumented env var GAWK_NO_PP_RUN exists.
+ * profile.c (pp_string): Explicitly print NUL chars as \000.
+
+2013-05-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac (AM_INIT_AUTOMAKE): Add dist-lzip to quiet
+ outside maintainer warnings.
+
+ Unrelated:
+
+ * configure.ac (AC_STRUCT_ST_BLKSIZE): Replaced with call to
+ AC_CHECK_MEMBERS.
+
+ Unrelated:
+
+ * array.c (null_array): Remove the assert and just clear
+ symbol->xarray.
+
+2013-05-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * getopt.c: For Mac OS X, also include <stdlib.h> to avoid
+ some compiler warnings.
+
+2013-05-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.h [FAKE_FD_VALUE]: Moved from here to ...
+ * io.c [FAKE_FD_VALAUE]: here.
+
+2013-05-14 Eli Zaretskii <eliz@gnu.org>
+
+ * io.c (devopen) [__EMX__ || __MINGW32__]: Produce EISDIR on MinGW
+ when an attempt to open() a directory fails.
+ (two_way_open) [__EMX__ || __MINGW32__]: When trying to open() a
+ directory fails with EISDIR, assign FAKE_FD_VALUE to the file
+ descriptor and attributes of a directory to its mode bits. This
+ is needed to support the readdir extension.
+
+ * gawkapi.h (FAKE_FD_VALUE): New macro, used in io.h and in
+ extension/gawkdirfd.h.
+
+2013-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.0: Release tar ball made.
+
+2013-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (snode): Make it a fatal error to use a regexp constant
+ as the second argument of index(). Thanks to Christopher Durant
+ <christopher.durant@marquesa.net> and Brian Kernighan for the report
+ and the advice.
+
+2013-04-28 Eli Zaretskii <eliz@gnu.org>
+
+ * io.c (redirect): Remove the HACK that called close_one when
+ errno was zero in the MinGW build. This prevents failure in
+ several tests in the test suite, e.g., closebad.
+
+2013-04-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * bootstrap.sh: Fix a comment.
+
+2013-04-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (do_getline_redir): Fix the leading comment.
+
+2013-04-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (load_procinfo): Add PROCINFO entries for API major
+ and minor versions.
+
+2013-04-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * missing: Update from Automake 1.13.1.
+
+2013-04-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Fix a typo.
+
+2013-04-17 Corinna Vinschen <vinschen@redhat.com>
+
+ * configure.ac: Remove special casing for cygwin for libiconv
+ and libintl.
+
+2013-04-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * bootstrap.sh: Touch gawk.texi too. Update copyright.
+
+2013-04-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.c: Regenerated from bison 2.7.1.
+ * command.c: Ditto.
+ * dfa.h, dfa.c: Minor edits to sync with GNU grep.
+ * gettext.h: Sync with gettext 0.18.2.1.
+ * random.h: Remove obsolete __P macro and use. Update copyright year.
+ * Makefile.am, array.c, builtin.c, cint_array.c, cmd.h, debug.c,
+ eval.c, ext.c, field.c, gawkapi.c, gawkapi.h, gettext.h, int_array.c,
+ interpret.h, msg.c, node.c, profile.c, re.c, replace.c, str_array.c,
+ symbol.c: Update copyright year.
+
+ Update to automake 1.13.1:
+
+ * configure.ac (AM_INIT_AUTOMAKE): Update version.
+ * configure, Makefile.in, aclocal.m4, awklib/Makefile.in,
+ doc/Makefile.in, test/Makefile.in: Regenerated.
+
+ * getopt.c, getopt.h, getopt1.c, getopt_int.h: Sync with GLIBC.
+
+2013-04-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (check_funcs): Fix logic of test for called but
+ not defined warning. Thanks to Scott Deifik for the bug report.
+
+2013-04-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile.c (print_lib_list): Send final newline to prof_fp
+ instead of stdout. Thanks to Hermann Peifer for the bug report.
+
+2013-03-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (SUBDIRS): Move extension back into the middle of
+ the list so that `make check' without a prior `make' works.
+
+ Unrelated:
+
+ * main.c (main): Move env_lc into ifdef for LIBC_IS_BORKED.
+
+2013-03-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ For systems where libc is borked (MirBSD, maybe others).
+
+ * dfa.c: Force use of gawk_mb_cur_max instead of MB_CUR_MAX and make
+ mbrtowc a macro that always fails.
+ (using_utf8): Force utf8 to be 0 if libc borked and gawk_mb_cur_max
+ is one.
+ * main.c (main): If libc is borked and LC_ALL or LANG exist in the
+ environment and are set to "C" or "c", force gawk_mb_cur_max to one.
+
+2013-03-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * re.c (check_bracket_exp): Make handling of embedded ] in
+ regexp smarter. Thanks to Ed Morton <mortoneccc@comcast.net>
+ for reporting the bug.
+
+2013-03-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ Don't build extensions if API isn't supported:
+
+ * Makefile.am (SUBDIRS): Move extension directory to last in case
+ building the extensions is not supported.
+ * configure.ac: Add check for MirBSD and don't even try to run the
+ checks for DYNAMIC if so.
+
+ Check for systems (MirBSD) where libc doesn't understand not
+ to use UTF-8 for LC_ALL=C.
+
+ * configure.ac (LIBC_IS_BORKED): AC_DEFINE if needed.
+ * regcomp.c (init_dfa): Change logic as needed if LIBC_IS_BORKED.
+
+2013-02-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ Cause profiling / pretty printing to include a list of
+ loaded extensions. Thanks to Hermann Peifer for the bug report.
+
+ * awk.h (srcfiles): Add declaration.
+ * profile.c (print_lib_list): New function.
+ (dump_prog): Call it.
+
+2013-02-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (expression_list): In case of error return the list
+ instead of NULL so that snode gets something it can count.
+
+2013-02-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * bisonfix.awk: Comment out code for fixing contined #if
+ statements. It is likely not needed anymore. Leave it there in
+ case I'm wrong.
+
+2013-02-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (printf_common): Move nargs > 0 check into assert.
+ (do_sprintf): Add nargs check and fatal message to here.
+
+2013-02-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (main): Remove undocumented -m option which was for
+ compatibility with BWK awk. His awk dropped it back in 2007.
+
+2013-02-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Add Automake test for cross compiling.
+
+2013-01-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regcomp.c, regex.c, regex_internal.c, regexec.c: Update
+ copyright years to sync with GLIBC.
+
+ From: http://www.sourceware.org/ml/libc-alpha/2013-01/msg00967.html,
+ by Andreas Schwab <schwab@suse.de>:
+
+ * regexec.c (extend_buffers): Add parameter min_len.
+ (check_matching): Pass minimum needed length.
+ (clean_state_log_if_needed): Likewise.
+ (get_subexp): Likewise.`
+
+2013-01-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Include "dfa.h" which includes regex.h after limits.h
+ so that RE_DUP_MAX gets the correct value. Especially needed on
+ OpenVMS. Thanks to Anders Wallin.
+
+ * main.c (version): Print out API version numbers if DYNAMIC.
+ Helpful also for knowing if to run the shlib tests.
+
+ * configure: Regenerated after change in m4/readline.m4.
+
+2013-01-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * PROBLEMS: Removed. It is no longer needed.
+ * Makefile.am (EXTRA_DIST): Remove PROBLEMS from list.
+
+2013-01-31 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * configure.ac: Remove TEST_MPFR conditional added in last patch.
+ We will instead test for MPFR capability by looking at the output
+ from gawk --version.
+
+2013-01-27 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * configure.ac: Add MPFR test for use in test/Makefile.am.
+
+2013-01-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (parms_shadow): Change int param to bool.
+ * cmd.h (output_is_tty): Sync type with rest of code (is bool).
+ * dfa.c (MALLOC): Undef first, for Irix.
+ * Makefile.am (LDADD): Use LIBREADLINE and LIBMPFR instead of
+ automake substitutions.
+ * configure.ac (AC_INIT): Version bump.
+ (GAWK_CHECK_READLINE): Renamed from GNUPG_CHECK_READLINE.
+
+2013-01-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (list_functions): Change parameter to bool.
+ * symbol.c (list_functions): Ditto.
+ (get_symbols): Change sort parameter to bool. Additional
+ code cleanup.
+
+2013-01-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ * symbol.c (get_symbols): Reset count after each loop to only
+ sort the actual items retrieved. Thanks to Hermann Peifer (by
+ way of Andrew Schorr) for reporting the bug. Also add some
+ commentary and fix function name in emalloc calls.
+
+2013-01-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * re.c (regexflags2str): New routine.
+ (resetup): If do_intervals, also turn on RE_NO_BK_BRACES.
+ Thanks to Yan Lei <yanl.fnst@cn.fujitsu.com> for the
+ bug report.
+
+2013-01-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ Fix a problem with include ordering to get ptrdiff_t definition,
+ showed up on Debian Lenny. Reported by Manuel Collado.
+ Fix brought over from grep.
+
+ * dfa.h: Include regex.h and stddef.h directly.
+ * dfa.c: Adjust includes.
+
+2013-01-11 John Haque <j.eh@mchsi.com>
+
+ * awk.h (do_mpfr_rshift): Renamed from do_mpfr_rhift.
+ * awkgram.y (do_mpfr_rshift): Renamed from do_mpfr_rhift.
+ * mpfr.c (_tz1, _tz2, _mpz1, _mpz2, mpz1, mpz2, get_bit_ops,
+ free_bit_ops): Removed.
+ (init_mpfr): Remove calls to mpz_init.
+ (get_intval, free_intval): New functions.
+ (do_mpfr_rshift, do_mpfr_lshift): Rework code.
+ (do_mpfr_and, do_mpfr_or, do_mpfr_xor): Accept two or more arguments
+ to match regular functions.
+
+2013-01-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * bisonfix.awk: Adjust ARGV / ARGC to force reading of standard
+ input; apparently needed for Mac OS X. Thanks to Akim Demaille
+ for the report.
+
+2013-01-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (redirect, two_way_open): Set the name field in the
+ awk_input_buf_t and awk_output_buf_t structures, as needed.
+ Thanks to Manuel Collado for the report.
+
+2013-01-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regex_internal.h (struct re_dfa_t): Restore ifdefs around
+ __libc_lock_define, they really were needed. Bleah.
+
+2013-01-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ Sync with GLIBC regex files.
+
+ * regex_internal.h (struct re_dfa_t): Remove ifdefs around
+ __libc_lock_define since it's already defined to empty in non-LIBC
+ case.
+ * regexec.c (check_node_accept_bytes): Restore decl with use from
+ GLIBC code since this is LIBC case.
+
+2012-12-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_print, do_printf): Use output_fp as default
+ output for print/printf only if running under the debugger.
+ Otherwise use stdout as Brian, Peter, and Al intended.
+
+2012-12-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ Remove sym-constant from API after discussions with John
+ Haque and Andrew Schorr.
+
+ * gawkapi.h (api_sym_constant): Removed field in API struct.
+ (sym_constant): Remove macro.
+ * gawkapi.c (set_constant, api_sym_update, api_sym_constant): Removed.
+ (sym_update_real): Renamed to api_sym_update(). is_const parameter
+ removed and code adjusted.
+
+2012-12-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.2: Release tar ball made.
+
+2012-12-23 John Haque <j.eh@mchsi.com>
+
+ * eval.c (r_get_lhs): Node_array_ref. If original is Node_var,
+ don't assign null-string as value.
+ * ext.c (get_argument): Node_array_ref. Check if already a scalar.
+
+2011-12-23 John Haque <j.eh@mchsi.com>
+
+ * awkgram.y (is_deferred_variable): New function.
+ (func_install): Call it.
+ * eval.c (r_interpret): Op_push_arg. Check for uninitialized scalar.
+
+2012-12-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (tokentab): Whitespace fix for "include".
+ * builtin.c (printf_common): Do a fatal error if no args to printf()
+ or sprintf().
+
+2012-12-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * bootstrap.sh: Touch extension/aclocal.m4 also.
+
+ Unrelated: Extend input parser API:
+
+ * awk.h (IOBUF): Remove read_func pointer.
+ * gawkapi.h (awk_input_buf_t): Move it to here.
+ * io.c (iop_alloc, get_a_record, get_read_timeout): Adjust code.
+
+ Unrelated: Make sure that variables like NF, NR, FNR are
+ accessable correctly both through SYMTAB and through API.
+
+ * gawkapi.c (api_sym_lookup): Call update_global_values().
+ (api_sym_lookup_scalar): Ditto.
+ * interpret.h (Op_subscript, Op_subscript_lhs): Ditto.
+ * main.c (update_global_values): Adjust comment.
+
+ Unrelated: Fix --disable-lint so that everything compiles.
+
+ * main.c (main): Move case lable inside ifdef.
+ * awkgram.y (isnoeffect): Add ifdefs around declaration, use,
+ and function body.
+
+ Unrelated: Restore building with tcc.
+
+ * awk.h (AFUNC): Move to array.c which is the only place its used.
+ (ainit_ind, atypeof_ind, etc.): New macros for use in array.c
+ * array.c (AFUNC): Change to use F##_ind. Works with tcc and other
+ compilers.
+ * configure.ac: Only add -export-dynamic flag if compiling with gcc.
+
+2012-12-18 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.c (sym_update_real): If setting a scalar variable that exists
+ already in an undefined state with type set to Node_var_new, we must
+ update the type to Node_var if the new value is not undefined.
+
+2012-12-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (tokentab): "extension" needs to be inside ifdef DYNAMIC.
+ Thanks to Anders Wallin for finding this.
+
+2012-12-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * debug.c (do_set_var): Fix last remaining `*assoc_lookup() = x'.
+
+2012-12-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ Infrastructure Updates:
+
+ * awkgram.c, command.c: Regenerated with bison 2.7.
+ * config.guess, config.sub, depcomp: Updated from automake 1.12.6.
+
+2012-12-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ Clean up BINMODE to use symbolic values.
+
+ * awk.h (enum binmode_values): New enum.
+ * eval.c (set_BINMODE): Use them.
+ * io.c (binmode, close_rp, gawk_popen): Ditto.
+ * main.c (main): Ditto.
+ * builtin.c (do_system): Ditto.
+
+ Unrelated:
+
+ * configure.ac: Look for posix_openpt
+ * io.c (two_way_open): Use posix_openpt if it's available.
+ Thanks to Christian Weisgerber <naddy@mips.inka.de> for
+ the changes.
+
+ Also unrelated:
+
+ * regex.c: Don't include <sys/param.h> on VMS. Thanks to
+ Anders Wallin.
+
+ Also unrelated:
+
+ * ext.c (is_letter, is_identifier_char): New functions. Don't use
+ <ctype.h> functions since those could rely on the locale.
+ (make_builtin): Adjust test for valid name to call the new
+ functions and return false instead of throwing a fatal error.
+ (make_old_builtin): Adjust test for valid name to call the new
+ function.
+ * awk.h (is_identchar): Move from here, ...
+ * awkgram.y (is_identchar): ... to here. This is safe, since
+ the locale is C during parsing the program.
+
+ Also unrelated: Make all checks for bitflags being set consistent
+ in case we should wish to switch them to macro calls:
+
+ * awkgram.y, builtin.c, cint_array.c, debug.c, eval.c, gawkapi.c,
+ int_array.c, io.c, mpfr.c, node.c, profile.c, str_array.c: Fix
+ as needed.
+
+2012-12-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (tokentab): `fflush()' is now in POSIX, remove the
+ RESX flag. This was the last use, so delete the flag.
+ (yylex): Don't check RESX.
+
+ Thanks to Nathan Weeks <weeks@iastate.edu> for helping make this
+ happen.
+
+2012-12-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ * interpret.h: For op_assign_concat, if both strings
+ have WSTRCUR, then do the realloc() and append for the
+ wide string too. Thanks to Janis Papanagnou
+ <janis_papanagnou@hotmail.com> for the discussion in
+ comp.lang.awk.
+
+2012-11-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regcomp.c, regex.c, regex_internal.h, regexec.c: Sync
+ with GLIBC. Why not.
+
+ * gawkapi.c (awk_bool_t): Change into an enum with awk_false and
+ awk_true values.
+
+2012-01-30 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ Further cleanups of macros in awk.h
+
+ * awk.h (_r, _t): Remove declarations.
+ (unref, m_force_string): Remove macros.
+ (r_unref): Move declaration.
+ (r_force_string): Remove declaration.
+ (DEREF, force_string, force_number, unref): Now inline functions.
+ (POP_STRING, TOP_STRING): Back to macros.
+ * eval.c (_t): Remove definition.
+ * main.c (_r): Remove definition.
+ * node.c (r_force_string): Remove.
+
+2012-11-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_fflush): Make fflush() and fflush("") both
+ flush everything. See the comment in the code.
+
+2012-11-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (Node_old_ext_func, Op_old_ext_func): New enum values.
+ * configure.ac: Use -export-dynamic if supported for old extension
+ mechanism.
+ * eval.c (nodeytpes): Add Node_old_ext_func.
+ (optypetab): Add Op_old_ext_func.
+ * ext.c (make_old_ext_builtin): "New" function.
+ * interpret.h: Special case Op_old_ext_builtin. Add checks for
+ Node_old_ext_func.
+ * msg.c: Adjust placement of a comment.
+
+2012-05-02 John Haque <j.eh@mchsi.com>
+
+ * str_array.c (str_copy): Initialize next pointer in the linked list
+ to avoid memory corruption.
+ * int_array.c (int_copy): Ditto.
+
+2012-04-21 John Haque <j.eh@mchsi.com>
+
+ Shutdown routine for a dynamic extension.
+
+ * awk.h (SRCFILE): New field fini_func.
+ * ext.c (load_ext): Takes an additional argument to look up and
+ save the clean up routine in SRCFILE struct.
+ (INIT_FUNC, FINI_FUNC): Defines for default init and fini routine
+ names.
+ (do_ext): Use default for the name of the init or fini routine if
+ one is not supplied. Adjust call to load_ext().
+ (close_extensions): Execute fini routines.
+ * interpret.h (Op_at_exit): Call close_extensions().
+ * msg.c (gawk_exit): Ditto.
+ * debug.c (close_all): Ditto.
+ * main.c (main): Adjust call to load_ext().
+ * awkgram.y (tokentab): Specify 2nd and 3rd optional arguments
+ for the extension() built-in.
+
+ Unrelated:
+
+ * interpret.h (Op_arrayfor_init): Use assoc_length for array size.
+
+2012-04-19 John Haque <j.eh@mchsi.com>
+
+ Enhanced array interface to support transparent implementation
+ using external storage and ...
+
+ * awk.h (astore): Optional post-assignment store routine for
+ array subscripts.
+ (Op_subscript_assign): New opcode to support the store routine.
+ (alength): New array interface routine for array length.
+ (assoc_length): New macro.
+ (assoc_empty): Renamed from array_empty.
+ * awkgram.y (snode): Append Op_subscript_assign opcode if
+ (g)sub variable is an array element.
+ (mk_getline): Same for getline variable.
+ (mk_assignment): Same if assigning to an array element.
+ * field.c (set_element): Call store routine if needed.
+ * builtin.c (do_match): Ditto.
+ (do_length): Use length routine for array size.
+ * symbol.c (print_vars): Ditto.
+ * array.c (null_length): Default function for array length interface.
+ (asort_actual): Call store routine if defined.
+ (asort_actual, assoc_list): Use length routine for array size.
+ (null_array_func): Add length and store routine entries.
+ * str_array.c (str_array_func): Same.
+ * cint_array.c (cint_array_func): Same.
+ * int_array.c (int_array_func): Same.
+ * eval.c (optypetab): Add Op_subscript_assign.
+ * profile.c (pprint): Add case Op_subscript_assign.
+ * interpret.h (set_array, set_idx): New variables to keep track
+ of an array element with store routine.
+ (Op_sub_array, Op_subscript_lhs, Op_store_sub, Op_subscript_assign):
+ Add code to handle array store routine.
+ * debug.c (print_symbol, print_array, cmp_val, watchpoint_triggered,
+ initialize_watch_item): Use length routine for array size.
+
+ * awk.h (assoc_kind_t): New typedef for enum assoc_list_flags.
+ (sort_context_t): Renamed from SORT_CONTEXT.
+ * array.c (asort_actual, assoc_sort): Adjust.
+ * cint_array.c (cint_list, tree_list, leaf_list): Adjust.
+ * int_array.c (int_list): Adjust.
+ * str_array.c (str_list): Adjust.
+
+2012-04-18 John Haque <j.eh@mchsi.com>
+
+ * awk.h (atypeof, AFUNC): New macros.
+ (afunc_t): Renamed typedef from array_ptr.
+ * array.c (register_array_func, null_lookup): Use AFUNC macro
+ instead of hard-coded index for array functions.
+ (asort_actual): Unref null array elements before overwriting.
+ (force_array): Renamed from get_array.
+ (null_array): Renamed from init_array. Also initialize flags to 0.
+ (array_types): Renamed from atypes.
+ (num_array_types): Renamed from num_atypes.
+ * interpret.h (r_interpret): In case Op_sub_array, unref null array element.
+ * str_array.c (str_array_init): Reworked for (re)initialization of array.
+ * int_array.c (int_array_init): Ditto.
+ * cint_array.c (cint_array_init): Ditto.
+
+2012-11-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ Directory cleanup.
+
+ * TODO.xgawk, FUTURES: Merged into TODO.
+ * TODO: More stuff added.
+ * Makefile.am (EXTRA_DIST): Updated.
+
+2012-11-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ Cleanup of awk.h.
+
+ * array.c (r_in_array): Removed.
+ * awk.h (MALLOC_ARG_T): Replaced with size_t everywhere.
+ (S_ISREG, setsid): Moved to io.c.
+ (__extension__): Removed.
+ (INT32_BIT): Moved to cint_array.c.
+ (_t): Always declare.
+ (DO_LINT_INVALID, et al): Moved into an enum.
+ (POP_ARRAY, POP_PARAM, POP_SCALAR, TOP_SCALAR, dupnode, in_array):
+ Moved into inline functions.
+ (force_number, force_string): Simplified.
+ (ZOS_USS): Remove undef of DYNAMIC, it's handled in configure.ac.
+ * io.c (S_ISREG, setsid): Moved to here.
+ * cint_array.c (INT32_BIT): Moved to here.
+ * eval.c (_t): Always define.
+ * protos.h: Use size_t directly instead of MALLOC_ARG_T.
+
+ Unrelated:
+
+ * gawkapi.h: Add `awk_' prefix to structure tags where they
+ were missing. Document the full list of include files needed.
+
+2012-11-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (do_find_source): On VMS, don't add the `/' separater.
+ Thanks to Anders Wallin.
+
+ MPFR minor cleanup:
+
+ * awk.h (mpfr_unset): Declare new function.
+ * mpfr.c (mpfr_unset): New function.
+ * node.c (r_unref): Call it instead of inline code.
+ * gawk_api.c (api_sym_update_scalar): Call it instead of inline code.
+
+2012-11-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * symbol.c (get_symbols): Check type, not vname. Keeps
+ valgrind happy. Thanks to Andrew Schorr for noticing the problem.
+
+2012-11-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Update to bison 2.6.5. Various files regenerated.
+ * io.c (find_source): Add a default value for SHLIBEXT.
+ (read_with_timeout): For VMS also, just use read().
+
+2012-11-10 John Haque <j.eh@mchsi.com>
+
+ * int_array.c (int_copy): Initialize next pointer of newchain to null.
+ * eval.c (eval_condition): Force string context for an integer used
+ as array index.
+
+2012-11-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.c (api_add_ext_func, api_awk_atexit, api_clear_array,
+ api_create_array, api_create_value, api_register_ext_version,
+ api_release_value, api_update_ERRNO_string, node_to_awk_value,
+ remove_element, run_ext_exit_handlers): Add null pointer checks.
+ Everywhere: Add / fixup leading comments.
+
+ * interpret.h (Op_store_sub): If assigning to an unitialized variable
+ through SYMTAB, change it to Node_var. Add explanatory comments.
+ * symbol.c (get_symbol): Rationalized. Skip non-variables in SYMTAB.
+
+2012-11-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.h: Minor documentation edit.
+
+2012-10-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (want_regexp): Use as a bool, not as an int.
+ * field.c: Fix a comment.
+ * gawkapi.h: Add comment to include <errno.h>.
+ * symbol.c (load_symbols): ``No automatic aggregate initialization.''
+ Here too. Sigh again.
+
+ * gawkapi.h: Minor documentation edits.
+
+2012-11-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_fflush): Make fflush() and fflush("") both
+ flush everything. See the comment in the code.
+
+2012-10-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Update to bison 2.6.4. Various files regenerated.
+
+2012-10-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.h: Continuing the minor formatting / doc cleanups.
+
+2012-10-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.h: Continuing the minor formatting / doc cleanups.
+
+2012-10-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.h: Still more minor formatting / doc cleanups.
+
+2012-10-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.h: More minor formatting / doc cleanups.
+
+2012-10-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ Fixes for z/OS from Dave Pitts.
+
+ * awk.h (assoc_list_flags): No trailing comma on last enum value.
+ * gawkapi.h (awk_valtype_t): Ditto.
+ * symbol.c (lookup): ``No automatic aggregate initialization.'' Sigh.
+
+ Unrelated:
+
+ * gawkapi.h: Minor formatting / doc cleanups.
+
+2012-10-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ If SYMTAB is used, make sure ENVIRON and PROCINFO get loaded too.
+
+ * awkgram.y (process_deferred): New function. Call it when program
+ is completely parsed.
+ (symtab_used): New variable.
+ (variable): Set it to true if SYMTAB is looked up.
+ * main.c (load_environ, load_procinfo): Make sure the routines are
+ only called once.
+
+ Unrelated fixes:
+
+ * awkgram.y (yylex): Check continue_allowed and break_allowed as
+ soon as they are seen in the scanner; the rules that check them
+ can not be reduced until after a token that allows them is seen,
+ leading to errors at execution time.
+ * interpret.h (Op_K_break, Op_K_continue, Op_jmp): Add asssertion
+ that pc->target_jmp is not NULL.
+
+ * symbol.c (lookup): Correct a comment.
+
+2012-10-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.h (IOBUF_PUBLIC): Renamed awk_input_buf_t.
+ (struct iobuf_public): Renamed struct awk_input.
+ * awk.h: Adjust.
+
+2012-10-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Update to Automake 1.12.4. Various files regenerated.
+
+2012-10-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (dup_ent): New member for Node_param_list.
+ * symbol.c (install): For parameters, if this is a duplicate, chain
+ it off the original using the dup_ent pointer.
+ (remove_params): If there's a duplicate, remove it from the list.
+
+ * awk.h: Fix flags to have unique numeric values. Oops.
+
+2012-10-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.h: Add considerably more documentation. Rearrange order
+ of functions in the struct to make more sense, grouping related
+ functions together in a more logical order.
+ * gawkapi.c: Adjust as needed.
+ * ext.c (make_builtin): Adjust for name change in struct member.
+
+2012-10-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ * mbsupport.h: Add a bunch of undefs for z/OS.
+
+2012-10-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * TODO.xgawk: Update.
+ * awk.h (make_str_node): Removed macro.
+ (make_string): Modified to call make_str_node.
+ (r_make_str_node): Renamed to make_str_node.
+ * gawkapi.c: Changed r_make_str_node to make_str_node everywhere.
+ * node.c (make_str_node): Renamed from make_str_node.
+
+ Update to automake 1.12.4.
+
+ * Makefile.in, aclocal.m4, awklib/Makefile.in, doc/Makefile.in,
+ extension/Makefile.in, extension/aclocal.m4, test/Makefile.in:
+ Regenerated.
+
+ * interpret.h (Op_Subscript): Added lint warnings for FUNCTAB
+ and SYMTAB.
+
+2012-10-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (func_table): Declare.
+ * awkgram.y: If do_posix or do_traditional, then check for
+ delete on SYMTAB. Add check for delete on FUNCTAB, also.
+ * interpret.h (Op_Subscript): For FUNCTAB, return the element name
+ as its value too. Avoids lots of weirdness and allows indirect calls
+ after assignment from FUNCTAB["foo"] to work.
+ (Op_store_sub): Disallow assignment to elements of FUNCTAB.
+ (Op_indirect_func_all): Turn assert into check and fatal error.
+ * symbol.c (func_table): No longer static.
+ (lookup): If do_posix or do_traditional, skip the global table.
+ (release_all_vars): Clear func_table too.
+
+2012-09-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ First cut at SYMTAB and FUNCTAB. This does the following:
+ - Change symbol table handling to use gawk arrays.
+ - Store symbols in SYMTAB array and allow indirect access
+ through SYMTAB to variables, both getting and setting.
+ - List function names in FUNCTAB indexes; Values cannot be
+ used at the moment.
+ - No documentation yet.
+
+ * awk.h (Node_hashnode, hnext, hname, hlength, hcode, hvalue):
+ Removed, not needed any more.
+ (init_symbol_table, symbol_table): Add declarations.
+ * awkgram.y: Disallow delete on SYMTAB, fix warning for tawk
+ extension if traditional.
+ * eval.c (nodetypes): Remove Node_hashnode element.
+ * interpret.h (Op_subscript, Op_store_sub): Handle SYMTAB and go
+ through to the actual value.
+ * main.c (main): Init Nnull_string earlier. Add call to
+ init_symbol_table().
+ * profile.c (pp_str, pp_len): Change definitions.
+ (pp_next): New macro.
+ (pp_push, pp_pop): Adjust uses.
+ * symbol.c (variables): Removed.
+ (global_table, param_table, func_table, symbol_table,
+ installing_specials): New variables.
+ (lookup, make_params, install_params, remove_params, remove_symbol,
+ make_symbol, install, get_symbols, release_all_vars, append_symbol,
+ release_symbols, load_symbols): Rework logic considerably.
+ (init_symbol_table): New function.
+
+2012-09-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ `delete array' and `nextfile' are now in POSIX.
+ Thanks to Nathan Weeks <weeks@iastate.edu> for the
+ initiative and letting us know about it.
+
+ * awkgram.y: Make the right code changes for `delete array'
+ and `nextfile'.
+ (tokentab): Set flags to zero for nextfile.
+
+2012-09-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * symbol.c (load_symbols): Zero out the new node. Prevents assertion
+ failure on PPC Mac OS X.
+
+2012-09-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ Allow read-only access to built-in variables from extensions.
+
+ * awk.h (NO_EXT_SET): New flag.
+ * gawkapi.c (api_sym_lookup, api_sym_update_real): Set flag if off
+ limits variable instead of failing. Adjust logic.
+ (api_sym_update_scalar, api_set_array_element, api_del_array_element,
+ api_release_flattened_array): Adjust logic.
+ * gawkapi.h: Adjust documentation.
+
+ Provide PROCINFO["identifiers"]. Undocumented for now.
+
+ * awk.h (load_symbols): Add declaration.
+ * awkgram.y (variable): Adjust comment formatting.
+ * main.c (main): Call load_symbols().
+ * symbol.c (load_symbols): New function.
+
+2012-09-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Determination of DYNAMIC adjusted. Hopefully is
+ smarter for z/OS.
+
+2012-09-13 Dave Pitts <dpitts@cozx.com>
+
+ * awk.h: Add defines for z/OS for newer types.
+
+2012-08-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.c: Wrap various bits in #ifdef DYNAMIC so that
+ gawk will compile on systems without dynamic loading.
+
+2012-08-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ Add version facility to API. Thanks to Manuel Collado
+ for the idea.
+
+ * awk.h (print_ext_versions): Declare.
+ Rearrange includes and decls to make more sense.
+ * gawkapi.h (register_ext_version): New API.
+ (dl_load_func): Add code for ext_version.
+ * gawkapi.c (api_register_ext_version, print_ext_versions):
+ New functions.
+ * main.c (do_version): New variable.
+ (optab): Set it for -v / --version.
+ (main): Set it in arg parsing switch. Call version() after the
+ extensions have been loaded.
+
+2012-08-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ Add output wrapper and two-way processor to extension API.
+
+ * awk.h (struct redirect): Replace output FILE * with awk_output_buf_t.
+ (register_output_wrapper, register_two_way_processor): Declare.
+ * builtin.c (efwrite): Adjust logic to use rp->output data and
+ functions if rp is not NULL. Remove redundant declaration of function.
+ (do_fflush, do_printf, do_print, do_print_rec): Same adjustment.
+ * ext.c (make_builtin): Adjust error messages.
+ * gawkapi.c (api_register_output_wrapper,
+ api_register_two_way_processor): New functions.
+ (sym_update_real): Adjust code formatting.
+ * gawkapi.h (awk_input_parser_t): Make next pointer awk_const.
+ (awk_output_buf_t, awk_two_way_processor_t): New structs.
+ (api_register_output_wrapper, api_register_two_way_processor): New APIs.
+ (dl_load_func): Allow for empty function table (NULL elements).
+ * io.c (find_output_wrapper, init_output_wrapper, find_two_processor,
+ gawk_fwrite, gawk_ferror, gawk_fflush, gawk_fclose): New functions.
+ (redirect): Call init_output_wrapper, find_output_wrapper as needed.
+ Adjust use of rp->fp to rp->output.fp and also function calls.
+ (close_rp, close_redir, flush_io): Same adjustment.
+ (two_way_open): Same adjustment. Call find_two_way_processor, and
+ find_output_wrapper, as needed.
+
+2012-08-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Update infrastructure: Automake 1.12.3 and bison 2.6.2.
+
+2012-08-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Sync w/GNU grep.
+
+2012-08-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.h: Make the versions enum constants instead of defines.
+
+2012-08-11 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * awkgram.y (add_srcfile): It is now a fatal error to load the
+ same file with -f and -i (or @include).
+ * TODO.xgawk: Update to reflect this change.
+
+2012-08-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * FUTURES, TODO.xgawk: Updates.
+
+2012-08-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Add -DNDEBUG to remove asserts if not developing.
+
+ * gawkapi.h: Document how to build up arrays.
+ * gawkapi.c (api_sym_update): For an array, pass the new cookie
+ back out to the extension.
+
+ * awk.h (IOBUF): Move struct stat into IOBUF_PUBLIC.
+ (os_isreadable): Change to take an IOBUF_PUBLIC.
+ * gawkapi.h (IOBUF_PUBLIC): Received struct stat.
+ (INVALID_HANDLE): Moves to here.
+ * io.c (iop_alloc): Stat the fd and fill in stat buf.
+ (iop_finish): Use passed in stat info.
+
+2012-08-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ * README.git: More stuff added.
+
+2012-08-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (iop_finish): New function.
+ (iop_alloc): Add errno_val parameter. Move code into iop_finish.
+ Add large explanatory leading comment.
+ (after_beginfile): Rework logic. Check for input parser first, then
+ check for invalid iop.
+ (nextfile): Organize code better. Call iop_alloc then iop_finish.
+ (redirect): Call iop_alloc, find_input_parser, iop_finish.
+ (two_way_open): Call iop_alloc, find_input_parser, iop_finish.
+ (gawk_popen): Call iop_alloc, find_input_parser, iop_finish.
+ (find_input_parser): Set iop->valid if input parser takes control.
+ (get_a_record): Rework setting RT to use macros.
+
+2012-07-29 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * awk.h (set_RT_to_null, set_RT): Removed.
+ * gawkapi.h (api_set_RT): Removed.
+ (get_record): Signature changed in input parser struct.
+ * gawkapi.c (api_set_RT): Removed.
+ * io.c (set_RT_to_null, set_RT): Removed.
+ (get_a_record): Adjustments for new API for input parser.
+
+2012-07-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (os_isreadable): Adjust declaration.
+ (struct iobuf): Add new member `valid'.
+ * io.c (iop_alloc): Remove do_input_parsers parameter, it's
+ always true. Adjust logic to set things to invalid if could not
+ find an input parser.
+ (after_beginfile): Use valid member to check if iobuf is valid.
+ Don't clear iop->errcode.
+ (nextfile): Adjust logic to clear errcode if valid is true and
+ also to update ERRNO.
+ (redirect): Check iop->valid and cleanup as necessary, including
+ setting ERRNO.
+ (two_way_open): Ditto.
+ (gawk_popen): Ditto.
+ (devopen): Remove check for directory.
+
+2012-07-27 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * io.c (find_input_parser): Issue a warning if take_control_of fails.
+
+2012-07-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (set_RT): Change to take a NODE * parameter.
+ * io.c (set_RT): Change to take a NODE * parameter.
+ * gawkapi.h: Change open hook to input parser in comment.
+ * gawkapi.c (api_set_RT): Adjust call to set_RT.
+
+2012-07-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (set_RT_to_null, set_RT): Declare functions.
+ (os_isreadable): Declare function.
+ * io.c (set_RT_to_null, set_RT): New functions.
+ (iop_close): Init ret to zero.
+ * gawkapi.c (api_register_input_parser): Check for null pointer.
+ (api_set_RT): New function.
+ * gawkapi.h (api_set_RT): New function.
+
+2012-07-26 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.h (IOBUF_PUBLIC): Document the get_record and close_func
+ API.
+ (awk_input_parser_t) Change can_take_file argument to const, and
+ document the API.
+ * io.c (get_a_record): Document that the caller initializes *errcode
+ to 0, and remote the test for non-NULL errcode.
+
+2012-07-26 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.c (api_sym_update_scalar): Fix some minor bugs. Was
+ not updating AWK_NUMBER when valref != 1. And strings were not
+ freeing MPFR values.
+
+2012-07-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ Start refactoring of IOBUF handling and turn "open hooks"
+ into "input parsers".
+
+ * awk.h (IOP_NOFREE_OBJ): Flag removed.
+ (register_input_parser): Renamed from register_open_hook.
+ * ext.c (load_ext): Make sure lib_name is not NULL.
+ * gawk_api.c (api_register_input_parser): Renamed from
+ api_register_open_hook.
+ * gawk_api.h (api_register_input_parser): Renamed from
+ api_register_open_hook. Rework structure to have "do you want it"
+ and "take control of it" functions.
+ * io.c (iop_alloc): Remove third argument which is IOBUF pointer.
+ Always malloc it. Remove use of IOP_NOFREE_OBJ everywhere.
+ (find_input_parser): Renamed from find_open_hook.
+ (nextfile): Don't use static IOBUF.
+ (iop_close): Call close_func first. Then close fd or remap it
+ if it's still not INVALID_HANDLE.
+ (register_input_parser): Renamed from register_open_hook.
+ Use a FIFO list and check if more than one parser will accept the
+ file. If so, fatal error.
+
+2012-07-25 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * configure.ac: Instead of using acl_shlibext for the shared library
+ extension, define our own variable GAWKLIBEXT with a hack to work
+ correctly on Mac OS X.
+ * Makefile.am (SHLIBEXT): Use the value of GAWKLIBEXT instead of
+ acl_shlibext.
+
+2012-07-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Add crude but small hack to make plug-ins work
+ on Mac OS X.
+
+2012-07-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.h: Rework table to not take up so much space.
+ * gawkapi.c (api_sym_update_scalar): Rework optimization code
+ to clean up the function.
+
+2012-07-17 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.h: Add comments explaining new api_create_value and
+ api_release_value functions.
+ * gawkapi.c (sym_update_real): Allow updates with AWK_SCALAR and
+ AWK_VALUE_COOKIE types. After creating a regular variable,
+ remove the call to unref(node->var_value), since this is not
+ done elsewhere in the code (see, for example, main.c:init_vars).
+ If the update is for an existing variable, allow any val_type
+ except AWK_ARRAY (was previously disallowing AWK_SCALAR and
+ AWK_VALUE_COOKIE for no apparent reason).
+ (api_sym_update_scalar): The switch should return false for an
+ invalid val_type value, so change the AWK_ARRAY case to default.
+ (valid_subscript_type): Any scalar value is good, so accept any valid
+ type except AWK_ARRAY.
+ (api_create_value): Accept only AWK_NUMBER and AWK_STRING values.
+ Anything else should fail.
+
+2012-07-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ Speedup:
+
+ * awk.h (r_free_wstr): Renamed from free_wstr.
+ (free_wstr): Macro to test the WSTRCUR flag first.
+ * node.c (r_free_wstr): Renamed from free_wstr.
+
+ Support value cookies:
+
+ * gawkapi.h (awk_val_type_t): Add AWK_VALUE_COOKIE.
+ (awk_value_cookie_t): New type.
+ (awk_value_t): Support AWK_VALUE_COOKIE.
+ (api_create_value, api_release_value): New function pointers.
+ * gawkapi.c (awk_value_to_node, api_sym_update_scalar,
+ valid_subscript_type): Handle AWK_VALUE_COOKIE.
+ (api_create_value, api_release_value): New functions.
+
+2012-07-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.c (awk_value_to_node): Support AWK_SCALAR.
+ (api_sym_update_scalar): Performance improvements.
+
+2012-07-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ Allow creation of constants. Thanks to John Haque for the
+ implementation concept.
+
+ * gawk_api.h (api_sym_constant): Create a constant.
+ * gawk_api.h (api_sym_update_real): Renamed from api_sym_update.
+ Add is_const paramater and do the right thing if true.
+ (api_sym_update, api_sym_constant): Call api_sym_update_real
+ in the correct way.
+ (set_constant): New function.
+
+2012-07-11 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.h: Fix typo in comment.
+ (awk_value_t): Type for scalar_cookie should be awk_scalar_t,
+ not awk_array_t.
+ (gawk_api): Add new api_sym_lookup_scalar function.
+ (sym_lookup_scalar): New wrapper macro for api_sym_lookup_scalar hook.
+ * gawkapi.c (api_sym_lookup_scalar): New function for faster scalar
+ lookup.
+ (api_impl): Add entry for api_sym_lookup_scalar.
+
+2012-07-11 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.c (awk_value_to_node): Change to a switch statement
+ so AWK_SCALAR or other invalid type is handled properly.
+ (valid_subscript_type): Test whether a value type is acceptable
+ for use as an array subscript (any scalar value will do).
+ (api_get_array_element, api_set_array_element, api_del_array_element):
+ Use new valid_subscript_type instead of restricting to string values.
+
+2012-07-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ Lots of API work.
+
+ * gawkapi.h: Function pointer members renamed api_XXXX and
+ macros adjusted. More documentation.
+ (awk_valtype_t): New AWK_SCALAR enum for scalar cookies.
+ (awk_scalar_t): New type.
+ (awk_value_t): New member scalar_cookie.
+ (api_sym_update_scalar): New API function.
+ (erealloc): New macro.
+ (make_const_string): New macro, renamed from dup_string.
+ (make_malloced_string): New macro, renamed from make_string.
+ (make_null_string): New inline function.
+ (dl_load_func): Add call to init routine through pointer if
+ not NULL.
+
+ * gawkapi.c (awk_value_to_node): Assume that string values came
+ from malloc.
+ (node_to_awk_value): Handle AWK_SCALAR.
+ (api_sym_update): Ditto.
+ (api_sym_update_scalar): New routine.
+ (api_get_array_element): Return false if the element doesn't exist.
+ Always unref the subscript.
+ (remove_element): New helper routine.
+ (api_del_array_element): Use it.
+ (api_release_flattened_array): Ditto.
+ (api_impl): Add the new routine.
+
+2012-07-11 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.c (api_sym_update): Allow val_type to be AWK_UNDEFINED
+ for setting a variable to "", i.e. dupnode(Nnull_string).
+
+2012-07-10 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * awkgram.y (add_srcfile): Lint warning message for a previously loaded
+ shared library should say "already loaded shared library" instead
+ of "already included source file".
+
+2012-07-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.h (set_array_element): Use index + value instead
+ of element structure. Matches get_array_element.
+ (set_array_element_by_elem): New macro to use an element.
+ * gawkapi.c (api_set_array_element): Make the necessary adjustments.
+
+2012-07-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (tokentab): Remove limit on number of arguments
+ for "and", "or", and "xor".
+ * builtin.c (do_and, do_or, do_xor): Modify code to perform the
+ respective operation on any number of arguments. There must be
+ at least two.
+
+2012-06-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.h: Improve the documentation of the return values
+ per Andrew Schorr.
+
+2012-06-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * TODO.xgawk: Updated.
+ * awk.h (track_ext_func): Declared.
+ * awkgram.y (enum defref): Add option for extension function.
+ (struct fdesc): Add member for extension function.
+ (func_use): Handle extension function, mark as extension and defined.
+ (track_ext_func): New function.
+ (check_funcs): Update logic for extension functions.
+ * ext.c (make_builtin): Call track_ext_func.
+
+2012-06-24 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * TODO.xgawk: Most of IOBUF has been hidden.
+ * gawkapi.h (IOBUF): Remove declaration (now back in awk.h).
+ (IOBUF_PUBLIC): Declare new structure defining subset of IOBUF fields
+ that should be exposed to extensions.
+ (gawk_api): Update register_open_hook argument from IOBUF to
+ IOBUF_PUBLIC.
+ * awk.h (IOBUF): Restore declaration with 5 fields moved to new
+ IOBUF_PUBLIC structure.
+ (register_open_hook): Update open_func argument from IOBUF to
+ IOBUF_PUBLIC.
+ * gawkapi.c (api_register_open_hook): Ditto.
+ * io.c (after_beginfile, nextfile, iop_close, gawk_pclose): Some fields
+ such as fd and name are now inside the IOBUF public structure.
+ (struct open_hook): Update open_func argument from IOBUF to
+ (register_open_hook): Ditto.
+ (find_open_hook): opaque now inside IOBUF_PUBLIC.
+ (iop_alloc): fd and name now in IOBUF_PUBLIC.
+ (get_a_record): If the get_record hook returns EOF, set the IOP_AT_EOF
+ flag. Access fd inside IOBUF_PUBLIC.
+ (get_read_timeout): File name now inside IOBUF_PUBLIC.
+ * interpret.h (r_interpret): File name now inside IOBUF_PUBLIC.
+ * ext.c (load_ext): No need to call return at the end of a void
+ function.
+
+2012-06-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * ext.c (load_ext): Don't retun a value from a void function.
+ * gawkapi.c (api_set_array_element): Set up vname and parent_array.
+
+2012-06-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ More API and cleanup:
+
+ * awk.h (stopme): Make signature match other built-ins.
+ * awkgram.y (stopme): Make signature match other built-ins.
+ (regexp): Minor edit.
+ * gawkapi.c (api_set_argument): Remove unused variable.
+ Set parent_array field of array value.
+ * TODO.xgawk: Update some.
+
+ Remove extension() builtin.
+
+ * awk.h (do_ext): Removed.
+ (load_ext): Signature changed.
+ * awkgram.y (tokentab): Remove do_ext.
+ Change calls to do_ext.
+ * ext.c (load_ext): Make init function a constant.
+ * main.c (main): Change calls to do_ext.
+
+2012-06-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ Restore lost debugging function:
+
+ * awkgram.y (stopme): Restore long lost debugging function.
+ * awk.h (stopme): Add declaration.
+
+ API work:
+
+ * ext.c (get_argument): Make extern.
+ * awk.h (get_argument): Declare it.
+ * gawkapi.c (api_set_argument): Call it. Finish off the logic.
+ (api_get_argument): Refine logic to use get_argument.
+ * gawkapi.h (set_argument): New API.
+
+2012-06-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ Remove code duplication in gawkapi.c from msg.c:
+
+ * awk.h (err): Add `isfatal' first parameter.
+ * awkgram.y (err): Adjust all calls.
+ * msg.c (err): Adjust all calls. Move fatal code to here ...
+ (r_fatal): From here.
+ * gawkapi.c: Remove code duplication and adjust calls to `err'.
+
+ Handle deleting elements of flattened array:
+
+ * awk.h (get_argument): Remove declaration.
+ * ext.c (get_argument): Make static.
+ * gawkapi.h (awk_flat_array_t): Make opaque fields const. Add
+ more descriptive comments.
+ * gawkapi.c (release_flattened_array): Delete elements flagged
+ for deletion. Free the flattened array also.
+
+ Add additional debugging when developing:
+
+ * configure.ac: Add additional debugging flags.
+ * configure: Regenerated.
+
+2012-06-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.h (get_array_element): Restore `wanted' paramater.
+ (awk_element_t): Use awk_value_t for index. Add awk_flat_array_t.
+ (flatten_array): Change signature to use awk_flat_array_t;
+ (release_flattened_array): Change signature to use awk_flat_array_t;
+ * gawkapi.c (api_sym_update): Handle case where variable exists already.
+ (api_get_array_element): Restore `wanted' paramater and pass it
+ on to node_to_awk_value.
+ (api_set_array_element): Revisse to match changed element type.
+ (api_flatten_array): Revise signature, implement.
+ (api_release_flattened_array): Revise signature, implement.
+
+2012-06-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ API Work:
+
+ * gawkapi.h (get_array_element): Remove `wanted' parameter.
+ (r_make_string): Comment the need for `api' and `ext_id' parameters.
+ * gawkapi.c (api_sym_update): Move checks to front.
+ Initial code for handling arrays. Still needs work.
+ (api_get_array_element): Implemented.
+ (api_set_array_element): Additional checking code.
+ (api_del_array_element): Implemented.
+ (api_create_array): Implemented.
+ (init_ext_api): Force do_xxx values to be 1 or 0.
+ (update_ext_api): Ditto.
+
+2012-06-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ API Work:
+
+ * gawkapi.h (awk_value_t): Restore union.
+ (get_curfunc_param): Renamed to get_argument. Return type changed
+ to awk_bool_t. Semantics better thought out and documented.
+ (awk_atexit, get_array_element): Return type now void.
+ (sym_lookup): Return type now void. Argument order rationalized.
+ * gawkapi.c (node_to_awk_value): Return type is now awk_bool_t.
+ Semantics now match table in gawkawpi.h.
+ (api_awk_atexit): Return type now void.
+ (api_sym_lookup): Return type is now awk_bool_t. Change parameter
+ order.
+ (api_get_array_element): Return type is now awk_bool_t.
+
+ Further API implementations and fixes for extension/testext.c:
+
+ * awk.h (final_exit): Add declaration.
+ * ext.c (load_ext): Change `func' to install_func.
+ * gawkapi.c: Add casts to void for id param in all functions.
+ (api_sym_update): Finish implementation.
+ (api_get_array_element): Start implementation.
+ (api_set_array_element): Add error checking.
+ (api_get_element_count): Add error checking, return the right value.
+ * main.c (main): Call final_exit instead of exit.
+ (arg_assign): Ditto.
+ * msg.c (final_exit): New routine to run the exit handlers and exit.
+ (gawk_exit): Call it.
+ * profile.c (dump_and_exit): Ditto.
+
+2012-06-10 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * TODO.xgawk: Addition of time extension moved to "done" section.
+
+2012-06-10 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.c (api_update_ERRNO_string): Treat boolean true as a request
+ for TRANSLATE, and false as DONT_TRANSLATE.
+
+2012-06-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * cint_array.c (tree_print, leaf_print): Add additional casts
+ for printf warnings.
+
+ * awk.h (update_ext_api): Add declaration.
+ * gawkapi.c (update_ext_api): New function.
+ * eval.c (set_LINT): Call update_ext_api() at the end.
+ * gawkapi.h: Document that do_XXX could change on the fly.
+
+ * awk.h (run_ext_exit_handlers): Add declaration.
+ * msg.c (gawk_exit): Call it.
+
+2012-06-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ * ext.c (load_ext): Remove use of RTLD_GLOBAL. Not needed in new
+ scheme. Clean up error messages.
+
+2012-06-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Remove use of -export-dynamic for GCC.
+ * configure: Regenerated.
+
+2012-05-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (is_off_limits_var): Minor coding style edit.
+ * gawkapi.c (awk_value_to_node): More cleanup.
+ (node_to_awk_value): Use `wanted' for decision making.
+ (api_sym_update): Start implementation. Needs more work.
+ General: More cleanup, comments.
+ * gawkapi.h (api_sym_update): Add additional comments.
+
+2012-05-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkapi.c (node_to_awk_value): Add third parameter indicating type
+ of value desired. Based on that, do force_string or force_number
+ to get the "other" type.
+ (awk_value_to_node): Clean up the code a bit.
+ (get_curfunc_param): Move forcing of values into node_to_awk_value.
+ (api_sym_lookup): Add third parameter indicating type of value wanted.
+ (api_get_array_element): Ditto.
+ * gawk_api.h: Additional comments and clarifications. Revise APIs
+ to take third 'wanted' argument as above.
+ (awk_value_t): No longer a union so that both values may be accessed.
+ All macros: Parenthesized the bodies.
+ * bootstrap.sh: Rationalize a bit.
+
+2012-05-26 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (include_HEADERS): Add so gawkapi.h will be installed.
+ (base_sources): Add gawkapi.h so that it is in dist tarball.
+ * TODO.xgawk: Update.
+ * main.c (is_off_limits_var): Stop returning true for everything
+ except PROCINFO.
+
+2012-05-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (is_off_limits_var): New function to check if a variable
+ is one that an extension function may not change.
+ * awk.h (is_off_limits_var): Declare it.
+ * gawkapi.c (api_sym_lookup): Use it.
+
+ * bootstrap.sh: Touch various files in the extension directory also.
+
+2012-05-24 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.h (awk_param_type_t): Remove (use awk_valtype_t instead).
+ (awk_ext_func_t): Pass a result argument, and return an awk_value_t *.
+ (gawk_api.get_curfunc_param): Add a result argument.
+ (gawk_api.set_return_value): Remove obsolete function.
+ (gawk_api.sym_lookup, gawk_api.get_array_element): Add a result
+ argument.
+ (gawk_api.api_make_string, gawk_api.api_make_number): Remove hooks,
+ since access to gawk internal state is not required to do this.
+ (set_return_value): Remove obsolete macro.
+ (get_curfunc_param, sym_lookup, get_array_element): Add result argument.
+ (r_make_string, make_number): New static inline functions.
+ (make_string, dup_string): Revise macro definitions.
+ (dl_load_func): Remove global_api_p and global_ext_id args,
+ and fix SEGV by setting api prior to checking its version members.
+ (GAWK): Expand ifdef to include more stuff.
+ * gawkapi.c (node_to_awk_value): Add result argument.
+ (api_get_curfunc_param): Add result argument, and use awk_valtype_t.
+ (api_set_return_value): Remove obsolete function.
+ (awk_value_to_node): New global function to convert back into internal
+ format.
+ (api_add_ext_func): Simply call make_builtin.
+ (node_to_awk_value): Add result argument, and handle Node_val case.
+ (api_sym_lookup, api_get_array_element): Add result argument.
+ (api_set_array_element): Implement.
+ (api_make_string, api_make_number): Remove functions that belong on
+ client side.
+ (api_impl): Remove 3 obsolete entries.
+ * TODO.xgawk: Update to reflect progress.
+ * Makefile.am (base_sources): Add gawkapi.c.
+ * awk.h: Include gawkapi.h earlier.
+ (api_impl, init_ext_api, awk_value_to_node): Add declarations
+ so we can hook in new API.
+ (INSTRUCTION): Add new union type efptr for external functions.
+ (extfunc): New define for d.efptr.
+ (load_ext): Remove 3rd obj argument that was never used for anything.
+ (make_builtin): Change signature for new API.
+ * awkgram.y (load_library): Change 2nd argument to load_ext
+ from dlload to dl_load, and remove pointless 3rd argument.
+ * main.c (main): Call init_ext_api() before loading shared libraries.
+ Change 2nd argument to load_ext from dlload to dl_load, and remove
+ pointless 3rd argument.
+ * ext.c (do_ext): Remove pointless 3rd argument to load_ext.
+ (load_ext): Remove 3rd argument. Port to new API (change initialization
+ function signature). If initialization function fails, issue a warning
+ and return -1, else return 0.
+ (make_builtin): Port to new API.
+ * interpret.h (r_interpret): For Op_ext_builtin, call external functions
+ with an awk_value_t result buffer, and convert the returned value
+ to a NODE *. For Node_ext_func, code now in extfunc instead of builtin.
+
+2012-05-21 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * configure.ac: Remove libtool, and call configure in the
+ extension subdirectory. Change pkgextensiondir to remove the
+ version number, since the new API has builtin version checks.
+ * TODO.xgawk: Update.
+ * ltmain.sh: Removed, since libtool no longer used here.
+
+2012-05-19 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * TODO.xgawk: Update to reflect progress and new issues.
+ * main.c (main): Add -i (--include) option.
+ (usage): Ditto.
+ * awkgram.y (add_srcfile): Eliminate duplicates only for SRC_INC
+ and SRC_EXTLIB sources (i.e. -f duplicates should not be removed).
+ * io.c (find_source): Set DEFAULT_FILETYPE to ".awk" if not defined
+ elsewhere.
+
+2012-05-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h: Include "gawkapi.h" to get IOBUF.
+ * gawkapi.h: Considerable updates.
+ * gawkapi.c: New file. Start at implementing the APIs.
+
+2012-05-13 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * TODO.xgawk: Update to reflect recent discussions and deletion of
+ extension/xreadlink.[ch].
+
+2012-05-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ Sweeping change: Use `bool', `true', and `false' everywhere.
+
+2012-04-09 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * eval.c (unset_ERRNO): Fix memory management bug -- need to use
+ dupnode with Nnull_string.
+
+2012-04-08 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (valgrind): Define VALGRIND instead of redefining AWK.
+ This allows test/Makefile.am to set up the command environment as
+ desired.
+ (valgrind-noleak): Ditto, plus set --leak-check=no instead of the
+ default summary setting.
+
+2012-04-07 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * TODO.xgawk: Update to reflect progress.
+
+2012-04-01 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * TODO.xgawk: Move valgrind-noleak item into "done" section.
+ * Makefile.am (valgrind-noleak): Add new valgrind rule that omits
+ the "--leak-check=full" option to help spot more serious problems.
+
+2012-04-01 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * TODO.xgawk: Move ERRNO item into "done" section.
+ * awk.h (update_ERRNO, update_ERRNO_saved): Remove declarations.
+ (update_ERRNO_int, enum errno_translate, update_ERRNO_string,
+ unset_ERRNO): Add new declarations.
+ * eval.c (update_ERRNO_saved): Renamed to update_ERRNO_int.
+ (update_ERRNO_string, unset_ERRNO): New functions.
+ * ext.c (do_ext): Use new update_ERRNO_string function.
+ * io.c (ERRNO_node): Remove redundant extern declaration (in awk.h).
+ (after_beginfile, nextfile): Replace update_ERRNO() with
+ update_ERRNO_int(errno).
+ (inrec): Replace update_ERRNO_saved with update_ERRNO_int.
+ (do_close): Use new function update_ERRNO_string.
+ (close_redir, do_getline_redir, do_getline): Replace update_ERRNO_saved
+ with update_ERRNO_int.
+
+2012-03-27 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * TODO.xgawk: Update to reflect debate about how to support Cygwin
+ and other platforms that cannot link shared libraries with unresolved
+ references.
+ * awkgram.y (add_srcfile): Minor bug fix: reverse sense of test
+ added by Arnold in last patch.
+ * configure.ac: AC_DISABLE_STATIC must come before AC_PROG_LIBTOOL.
+
+2012-03-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ Some cleanups.
+
+ * awkgram.y (add_srcfile): Use whole messages, better for
+ translations.
+ * io.c (init_awkpath): Small style tweak.
+ * main.c (path_environ): Straighten out initial comment, fix
+ compiler warning by making `val' const char *.
+
+2012-03-25 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * configure.ac (AC_DISABLE_STATIC): Add this to avoid building useless
+ static extension libraries.
+
+2012-03-25 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * TODO.xgawk: New file listing completed and pending xgawk enhancements.
+
+2012-03-24 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * io.c (path_info): Fix white space.
+ (pi_awkpath, pi_awklibpath): Avoid structure initializers.
+ (do_find_source): Eliminate pointless parentheses.
+ (find_source): Leave a space after "&".
+ * main.c (load_environ): Fix typo in comment.
+
+2012-03-21 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * awkgram.y (LEX_LOAD): New token to support @load.
+ (grammar): Add rules to support @load.
+ (tokentab): Add "load".
+ (add_srcfile): Improve error message to distinguish between source files
+ and shared libraries.
+ (load_library): New function to load libraries specified with @load.
+ (yylex): Add support for LEX_LOAD (treated the same way as LEX_INCLUDE).
+
+2012-03-20 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (EXTRA_DIST): Remove extension.
+ (SUBDIRS): Add extension so libraries will be built.
+ (DEFS): Define DEFLIBPATH and SHLIBEXT so we can find shared libraries.
+ * awk.h (deflibpath): New extern declaration.
+ * configure.ac: Add support for building shared libraries by adding
+ AC_PROG_LIBTOOL and AC_SUBST for acl_shlibext and pkgextensiondir.
+ (AC_CONFIG_FILES): Add extension/Makefile.
+ * io.c (pi_awkpath, pi_awklibpath): New static structures to contain
+ path information.
+ (awkpath, max_pathlen): Remove static variables now inside pi_awkpath.
+ (init_awkpath): Operate on path_info structure to support both
+ AWKPATH and AWKLIBPATH. No need for max_path to be static, since
+ this should be called only once for each environment variable.
+ (do_find_source): Add a path_info arg to specify which path to search.
+ Check the try_cwd parameter to decide whether to search the current
+ directory (not desirable for AWKLIBPATH).
+ (find_source): Choose appropriate path_info structure based on value
+ of the is_extlib argument. Set EXTLIB_SUFFIX using SHLIBEXT define
+ instead of hardcoding ".so".
+ * main.c (path_environ): New function to add AWKPATH or AWKLIBPATH
+ to the ENVIRON array.
+ (load_environ): Call path_environ for AWKPATH and AWKLIBPATH.
+
+2012-06-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (main): Do setlocale to "C" if --characters-as-bytes.
+ Thanks to "SP" for the bug report.
+
+2012-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Added AC_HEADER_STDBOOL
+ * awk.h, dfa.c, regex.c: Reworked to use results
+ of test and include missing_d/gawkbool.h.
+
+2012-05-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * array.c (prnode): Add casts to void* for %p format.
+ * debug.c (print_instruction): Ditto.
+ * builtin.c: Fix %lf format to be %f everywhere.
+
+ Unrelated:
+
+ * replace.c: Don't include "config.h", awk.h gets it for us.
+
+2012-05-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * getopt.c [DJGPP]: Change to __DJGPP__.
+ * mbsupport.h [DJGPP]: Change to __DJGPP__.
+
+ Unrelated:
+
+ * awk.h: Workarounds for _TANDEM_SOURCE.
+
+2012-05-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Sync with GNU grep. RRI code now there, needed additional
+ change for gawk.
+ * configure.ac: Add check for stdbool.h.
+ * regex.c: Add check for if not have stdbool.h, then define the
+ bool stuff.
+
+2012-04-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Sync with GNU grep.
+ * xalloc.h (xmemdup): Added, from grep, for dfa.c. Sigh.
+
+2012-04-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ Update to autoconf 2.69, automake 1.12.
+
+ * INSTALL, aclocal.m4, configh.in, depcomp, install-sh, missing,
+ mkinstalldirs, ylwrap: Updated.
+ * configure.ac (AC_TYPE_LONG_LONG_INT, AC_TYPE_UNSIGNED_LONG_LONG_INT,
+ AC_TYPE_INTMAX_T, AC_TYPE_UINTMAX_T): Renamed from gl_* versions.
+ * configure: Regenerated.
+
+2012-04-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * cmd.h (dPrompt, commands_Prompt, eval_Prompt, dgawk_Prompt): Changed
+ to dbg_prompt, commands_prompt, eval_prompt, dgawk_prompt.
+ * debug.c: Ditto.
+ * command.y: Ditto. Some minor whitespace and comments cleanup.
+
+2012-04-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ io.c cleanup and some speedup for RS as regexp parsing.
+
+ * awk.h (Regexp): New members has_meta and maybe_long.
+ (enum redirval): Add redirect_none as value 0.
+ (remaybelong): Remove function declaration.
+ * awkgram.y: Use redirect_none instead of 0 for no redirect cases.
+ * io.c (go_getline_redir): Second arg now of type enum redirval.
+ Changed intovar into into_variable.
+ (comments and whitespace): Lots of general cleanup.
+ (socket_open): readle changed to read_len.
+ (two_way_open): Add additional calls to os_close_on_exec.
+ (rsrescan): Simplify code a bit and use RS->maybe_long.
+ * re.c (make_regexp): Set up new members in Regexp struct.
+ (remaybelong): Remove function.
+ (reisstring): Simplified code.
+
+2012-04-16 Eli Zaretskii <eliz@gnu.org>
+
+ * io.c (read_with_timeout) [__MINGW32__]: Just call the blocking
+ 'read', as 'select' is only available for sockets.
+ * mpfr.c (set_ROUNDMODE) [!HAVE_MPFR]: Renamed from set_RNDMODE.
+ * main.c (load_procinfo): Declare name[] also when HAVE_MPFR is
+ defined even though HAVE_GETGROUPS etc. are not.
+
+2012-04-12 John Haque <j.eh@mchsi.com>
+
+ * array.c, awk.h, awkgram.y, builtin.c, command.y, debug.c,
+ field.c, mpfr.c, profile.c: Change RND_MODE to ROUND_MODE.
+
+2012-04-11 John Haque <j.eh@mchsi.com>
+
+ * main.c (varinit): Change RNDMODE to ROUNDMODE.
+
+2012-04-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c: Change --arbitrary-precision to --bignum.
+
+2012-04-02 John Haque <j.eh@mchsi.com>
+
+ Add support for arbitrary-precision arithmetic.
+
+ * mpfr.c: New file.
+ * awk.h (struct exp_node): Add union to handle different number types.
+ (MPFN, MPZN): New flag values.
+ (DO_MPFR, do_mpfr): New defines.
+ (PREC_node, RNDMODE_node): Add declarations.
+ (PRECISION, RND_MODE, MNR, MFNR, mpzval, do_ieee_fmt): Add declarations.
+ (make_number, str2number, format_val, cmp_numbers): Ditto.
+ (force_number): Change definition.
+ (Func_pre_exec, Func_post_exec): New typedefs.
+ (POP_NUMBER, TOP_NUMBER): Change definitions.
+ (get_number_ui, get_number_si, get_number_d, get_number_uj,
+ iszero, IEEE_FMT, mpg_float, mpg_integer, mpg_float,
+ mpg_integer): New defines.
+ * awkgram.y (tokentab): Add alternate function entries for MPFR/GMP.
+ (snode): Choose the appropriate function.
+ (negate_num): New function to negate a number.
+ (grammar): Use it.
+ (yylex): Adjust number handling code.
+ * array.c (value_info, asort_actual, sort_user_func): Adjust for
+ MPFR/GMP numbers.
+ (do_adump, indent): Minor changes.
+ (sort_up_index_number, sort_up_value_number, sort_up_value_type): Use
+ cmp_numbers() for numeric comparisons.
+ * builtin.c (mpz2mpfr): New function.
+ (format_tree): Adjust to handle MPFR and GMP numbers.
+ * eval.c (register_exec_hook): New function to manage interpreter hooks.
+ (num_exec_hook, pre_execute, post_execute): New and adjusted definitions.
+ (h_interpret): Renamed from debug_interpret.
+ (init_interpret): Changed to use the new name.
+ (flags2str): New entries for MPFN and MPZN.
+ (cmp_nodes): Reworked to use seperate routine for numeric comparisons.
+ (set_IGNORECASE, set_BINMODE, set_LINT, update_NR, update_FNR,
+ update_NF): Adjust code and some cleanup.
+ * field.c (rebuild_record): Field copying code reworked to handle
+ MPFR/GMP numbers.
+ (set_NF): Minor adjustment.
+ * io.c (INCREMENT_REC): New macro.
+ (inrec, do_getline): Use the new macro.
+ (nextfile, set_NR, set_FNR, get_read_timeout, pty_vs_pipe): Adjust code
+ to handle MPFR/GMP numbers.
+ * interpret.h (r_interpret): Adjust TOP_NUMBER/POP_NUMBER usage.
+ (EXEC_HOOK): New macro and definition.
+ (DEBUGGING): Removed.
+ * main.c (DEFAULT_PREC, DEFAULT_RNDMODE): New defines.
+ (opttab): New entry for option arbitrary-precision.
+ (main): Handle the new option.
+ (usage): Add to usage message.
+ (varinit): Add PREC and RNDMODE.
+ (load_procinfo): Install MPFR and GMP related items.
+ (version): Append MPFR and GMP versions to message.
+ * msg.c (err) : Adjust FNR handling with MPFR/GMP.
+ * node.c (r_format_val): Renamed from format_val.
+ (r_force_number): Return NODE * instead of AWKNUM.
+ (make_number, str2number, format_val, cmp_numpers: Defined and initialized.
+ (r_unref): Free MPFR/MPZ numbers.
+ (get_numbase): Renamed from isnondecimal and return the base.
+ (cmp_awknums): New function to compare two AWKNUMs.
+ * command.y (yylex): Adjust number handling code.
+ (grammar): Minor adjustments to handle negative numbers.
+ * debug.c (init_debug): New function.
+ (do_info, do_set_var, watchpoint_triggered, serialize,
+ initialize_watch_item, do_watch, print_watch_item): Minor adjustments.
+ (debug_pre_execute): Adjusted to handle MPFR and GMP numbers.
+
+2012-04-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * INSTALL, config.guess, config.sub, depcomp, install-sh,
+ missing, mkinstalldirs, ylwrap: Update to latest from automake 1.11.4.
+
+2012-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Update various files to automake 1.11.4.
+
+2012-03-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac (GAWK_AC_NORETURN): Do as macro instead of inline.
+
+2012-03-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.h, dfa.c: Sync with grep. Major cleanups and some changes
+ there.
+ * re.c (research): Pass size_t* to dfaexec to match type change.
+ * configure.ac (AH_VERBATIM[_Noreturn]): Added from Paul Eggert to
+ ease compiling.
+ (AC_INIT): Bump version.
+ * configure, configh.in, version.c: Regenerated.
+
+2012-03-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.1: Release tar ball made.
+
+2012-03-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * getopt.c: Add DJGPP to list of platforms where it's ok
+ to include <stdlib.h>.
+ * awkgram.y, builtin.c, ext.c, mbsupport.h, re.c: Update
+ copyright year.
+
+2012-03-21 Corinna Vinschen <vinschen@redhat.com>
+
+ * getopt.c: Add Cygwin to list of platforms where it's ok
+ to include <stdlib.h>.
+
+2012-03-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ Get new getopt to work on Linux and C90 compilers:
+
+ * getopt.c: Undef ELIDE_CODE for gawk.
+ (_getopt_internal_r): Init first.needs_free to 0. In test for -W
+ move executable code to after declarations for C90 compilers.
+ * getopt1.c: Undef ELIDE_CODE for gawk.
+
+ Minor bug fix with printf, thanks to John Haque:
+
+ * builtin.c (format_tree): Initialize base to zero at the top
+ of the while loop.
+
+ Getting next tar ball ready:
+
+ * configure.ac: Remove duplicate check for wcscoll. Thanks
+ to Stepan Kasal.
+
+2012-03-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * getopt.c, getopt.h, getopt1.c, getopt_int.h, regcomp.c,
+ regex.c, regex.h, regex_internal.c, regex_internal.h,
+ regexec.c: Sync with GLIBC, what the heck.
+
+2012-03-14 Eli Zaretskii <eliz@gnu.org>
+
+ * mbsupport.h (btowc): Change for non-DJGPP.
+ * re.c (dfaerror): Add call to exit for DJGPP.
+
+2012-03-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regex_internal.c (re_string_skip_chars): Fix calculation of
+ remain_len with m.b. chars. Thanks to Stanislav Brabec
+ <sbrabec@suse.cz>.
+
+2012-02-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (init_groupset): Make `getgroups' failing a non-fatal
+ error. After all, what's the big deal? Should help on Plan 9.
+
+2012-02-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c (parse_bracket_exp): Revert changes 2012-02-15 to stay
+ in sync with grep.
+ * dfa.h (dfarerror): Add __attribute__ from grep.
+
+2012-02-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ Fix warnings from GCC 4.6.2 -Wall option.
+
+ * awkgram.y (newline_eof): New function to replace body of
+ NEWLINE_EOF macro.
+ (yylex): Replace body of NEWLINE_EOF macro.
+ * dfa.c (parse_bracket_exp): Init variables to zero.
+ * ext.c (dummy, junk): Remove.
+ * regex_internal.c (re_string_reconstruct): Remove buf array. It was
+ set but not used.
+
+2012-02-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Sync with GNU grep.
+
+2012-02-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * main.c (main): Move init of `output_fp' to before parsing of
+ program so that error messages from msg.c don't dump core.
+ Thanks to Michael Haardt <michael@moria.de>.
+
+2012-01-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c [is_valid_unibtye_character]: Fix from GNU grep to
+ bug reported by me from Scott Deifik for DJGPP.
+
+2012-01-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Sync with GNU grep.
+
+2012-01-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (Read_can_timeout, Read_timeout, Read_default_timeout):
+ Renamed to use lower case.
+ Other minor stylistic edits.
+
+2012-01-01 John Haque <j.eh@mchsi.com>
+
+ * awk.h (struct iobuf): New entry read_func.
+ * io.c (Read_can_timeout, Read_timeout, Read_default_timeout):
+ New variables.
+ (init_io): New routine to initialize the variables.
+ (in_PROCINFO): New "clever" routine to parse elements with indices
+ seperated by a SUPSEP.
+ (get_read_timeout): New routine to read timeout value for an IOBUF.
+ (read_with_timeout): New routine to read from a fd with a timeout.
+ (pty_vs_pipe): Use in_PROCINFO().
+ (get_a_record): Set the timeout value and the read routine as necessary.
+ * main.c (main): Call init_io().
+
+2011-12-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile_p.c: Remove the file.
+ * msg.c (err): Remove check for name being dgawk.
+
+2011-12-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h [STREQ, STREQN]: Remove macros.
+ * awkgram.y, builtin.c, command.y, debug.c, eval.c,
+ io.c, msg.c: Change all uses to call strcmp, strncmp.
+
+2011-12-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * int_array.c, str_array.c: Fix some compiler warnings 32/64
+ bit system differences.
+
+2011-12-26 John Haque <j.eh@mchsi.com>
+
+ Merge gawk, pgawk and dgawk into a single executable gawk.
+
+ * awk.h (DO_PRETTY_PRINT, DO_PROFILE, DO_DEBUG,
+ do_pretty_print, do_debug): New defines.
+ (interpret): New variable, a pointer to an interpreter routine.
+ (enum exe_mode): Nuked.
+ * main.c (opttab): New options --pretty-print and --debug;
+ Remove option --command.
+ (usage): Update usage messages.
+ * interpret.h: New file.
+ * eval.c (r_interpret): Move to the new file.
+ (debug_interpret): New interpreter routine when debugging.
+ (init_interpret): New routine to initialize interpreter related
+ variables.
+ * eval_d.c, eval_p.c: Delete files.
+ * debug.c (interpret): Renamed to debug_prog.
+ (DEFAULT_PROMPT, DEFAULT_HISTFILE, DEFAULT_OPTFILE): Remove prefix 'd'.
+ * profile.c (init_profiling): Nuked.
+ * Makefile.am: Adjusted.
+
+ Add command line option --load for loading extensions.
+
+ * awk.h (srctype): Add new source type SRC_EXTLIB.
+ * ext.c(load_ext): New routine to load extension.
+ (do_ext): Adjust to use load_ext().
+ * main.c (opttab): Add new option --load.
+ (main): Call load_ext() to load extensions.
+ (usage): Add usage message for the new option.
+ * io.c (get_cwd): New routine.
+ (do_find_source): Use the new routine.
+ (find_source): Handle new type SRC_EXTLIB.
+ * awkgram.y (parse_program, next_sourcefile): Skip type SRC_EXTLIB.
+ (add_srcfile): Adjust call to find_source.
+ * debug.c (source_find): Same.
+
+ Unrelated:
+
+ * ext.c (get_argument): Fixed argument parsing.
+ * array.c (null_array_func): Reworked array routines for an empty array.
+ * str_array.c, int_array.c: Make GCC happy, use %u instead of %lu
+ printf formats.
+ * eval.c (node_Boolean): New array for TRUE and FALSE nodes.
+ (init_interpret): Create the new nodes.
+ (eval_condition): Add test for the new nodes.
+ (setup_frame): Disable tail-recursion optimization when profiling.
+ * interpret.h (r_interpret): Use the boolean nodes instead of making
+ new ones when needed.
+
+2011-12-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ Finish Rational Range Interpretation (!)
+
+ * dfa.c (match_mb_charset): Compare wide characters directly
+ instead of using wcscoll().
+ * regexec.c (check_node_accept_byte): Ditto.
+
+ Thanks to Paolo Bonzini for pointing these out.
+
+2011-12-06 John Haque <j.eh@mchsi.com>
+
+ * debug.c (source_find): Fix misplaced call to efree.
+ * profile.c (redir2str): Add a missing comma in the redirtab array.
+ * eval.c (r_interpret): Disallow call to exit if currule is undefined.
+ This avoids the possiblity of running END blocks more than once when
+ used in a user-defined sorted-in comparision function.
+ * array.c (sort_user_func): Adjust appropriately.
+
+2011-12-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h, mbsupport.h: Changes for MBS support on DJGPP
+ and z/OS.
+ * io.c: Disable pty support on z/OS.
+
+2011-11-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Sync with GNU grep.
+ * dfa.h: Add _GL_ATTRIBUTE_PURE macro. Bleah.
+
+2011-11-14 John Haque <j.eh@mchsi.com>
+
+ * debug.c (set_breakpoint_at): Fix problem with setting
+ breakpoints in a switch statement. Thanks to Giorgio Palandri
+ <giorgio.palandri@gmail.com> for the bug report.
+
+2011-11-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * mbsupport.h: Add check for HAVE_BTOWC, per Pat Rankin.
+
+2011-11-12 Eli Zaretskii <eliz@gnu.org>
+
+ * mbsupport.h: Additional glop for dfa.c in Windows environment.
+
+2011-11-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dfa.c: Move glop for ! MBS_SUPPORT to ...
+ * mbsupport.h: ... here.
+ * replace.c: Include missing_d/wcmisc.c if ! MBS_SUPPORT.
+ * regex_internal.h: Move include of mbsupport.h up and add
+ additional checks to avoid inclusion of wctype.h and wchar.h.
+
2011-10-27 Arnold D. Robbins <arnold@skeeve.com>
* builtin.c (do_strftime): Per Pat Rankin, instead of casting
@@ -378,6 +3925,19 @@
* pprint (profile.c): Add case for the new opcode.
* print_instruction (debug.c): Ditto.
+ Take out translation for errno strings; extensions will
+ need to use their own domain.
+
+ * awk.h (enum errno_translate): Removed.
+ (update_ERRNO_string): Remove second translate paramater.
+ * eval.c (update_ERRNO_string): Remove second translate paramater
+ and code that used it.
+ * gawkapi.h (api_update_ERRNO_string): Remove third translate
+ parameter.
+ * gawkapi.c (api_update_ERRNO_string): Remove third translate
+ paramater and change call to update_ERRNO_string.
+ * io.c (do_close): Fix call to update_ERRNO_string.
+
2011-07-15 Arnold D. Robbins <arnold@skeeve.com>
* awk.h: Typo fix: "loner" --> longer. Thanks to Nelson Beebe.
diff --git a/Checklist b/Checklist
index acfbff84..e0e1ffec 100644
--- a/Checklist
+++ b/Checklist
@@ -1,8 +1,9 @@
-Mon May 16 17:36:21 IDT 2011
+Fri Apr 4 11:43:29 IDT 2014
============================
A checklist for making releases
+The regtest test and other non-standard tests all pass
Copyright dates in all files updated
main.c - copyright message too!
ChangeLogs in place and updated
@@ -11,23 +12,25 @@ README_d/* edited
VMS/* version stuff up to date
vms/vmsbuild.com
vms/descrip.mms
- vms/vms-conf.h: update VERSION and PACKAGE_VERSION
NEWS is up to date
Any new options have been added to usage function
All paper work signed and sent in
All files checked in
Version information is correct in
- version.c
doc/gawk.1
doc/awkcard.in
- doc/gawk.texi
+ doc/gawktexi.in
doc/gawkinet.texi
+ extension/configure.ac
doc/texinfo.tex is up to date
-doc/gawk.texi is up to date
+doc/gawktexi.in is up to date
doc/gawkinet.texi is up to date
doc/gawk.1 is up to date
doc/awkcard.in is up to date
+Run prepinfo on the manual.
+Spell check the manual.
test/Makefile.am: order and prettify lists of tests
+API Version numbers have been modified correctly in gawkapi.h.
Testing on
make clean
@@ -35,6 +38,11 @@ Testing on
make maintainer-clean
make release
+ compile with tcc
+ compile with clang
+
+ compile 32 bit tests - clang and gcc
+
configure --disable-lint
configure --disable-nls
configure --with-whiny-user-strftime
diff --git a/FUTURES b/FUTURES
deleted file mode 100644
index 02574107..00000000
--- a/FUTURES
+++ /dev/null
@@ -1,64 +0,0 @@
- Copyright (C) 2005, 2006, 2010, 2011 Free Software Foundation, Inc.
-
- Copying and distribution of this file, with or without modification,
- are permitted in any medium without royalty provided the copyright
- notice and this notice are preserved.
-
-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.
-
-For 4.1
-=======
- Merge gawk/pgawk/dgawk into one executable
-
- Consider removing use of and/or need for the protos.h file.
-
- Consider moving var_value info into Node_var itself
- to reduce memory usage.
-
- Merge xmlgawk -l feature
-
- Merge xmlgawk XML extensions
-
- Integrate MPFR to provide high precision arithmetic.
-
- Continue code reviews / code cleanup
-
-For 4.2
-=======
- Implement designed API for loadable modules
-
- Redo the loadable modules interface from the awk level.
-
- Rework management of array index storage. (Partially DONE.)
-
- DBM storage of awk arrays. Try to allow multiple dbm packages.
-
- ? Move the loadable modules interface to libtool.
-
- ? Add an optional base to strtonum, allowing 2-36.
-
- ? Optional third argument for index indicating where to start the
- search.
-
- ?? 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.
-
- ??? Gnulib
-
-Probably never:
-===============
- Do an optimization pass over parse tree?
-
- Consider integrating Fred Fish's DBUG library into gawk.
-
- Make awk '/foo/' files... run at egrep speeds (how?)
-
- ? 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.
diff --git a/INSTALL b/INSTALL
index 5458714e..6e90e07d 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,19 +1,25 @@
Installation Instructions
*************************
-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
-2006 Free Software Foundation, Inc.
+Copyright (C) 1994-1996, 1999-2002, 2004-2012 Free Software Foundation,
+Inc.
-This file is free documentation; the Free Software Foundation gives
-unlimited permission to copy, distribute and modify it.
+ Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved. This file is offered as-is,
+without warranty of any kind.
Basic Installation
==================
-Briefly, the shell commands `./configure; make; make install' should
+ Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
-instructions specific to this package.
+instructions specific to this package. Some packages provide this
+`INSTALL' file but do not implement all of the features documented
+below. The lack of an optional feature in a given package is not
+necessarily a bug. More recommendations for GNU packages can be found
+in *note Makefile Conventions: (standards)Makefile Conventions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
@@ -42,7 +48,7 @@ may remove or edit it.
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
-The simplest way to compile this package is:
+ 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.
@@ -53,12 +59,22 @@ The simplest way to compile this package is:
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
- the package.
+ the package, generally using the just-built uninstalled binaries.
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
+ documentation. When installing into a prefix owned by root, it is
+ recommended that the package be configured and built as a regular
+ user, and only the `make install' phase executed with root
+ privileges.
+
+ 5. Optionally, type `make installcheck' to repeat any self-tests, but
+ this time using the binaries in their final installed location.
+ This target does not install anything. Running this target as a
+ regular user, particularly if the prior `make install' required
+ root privileges, verifies that the installation completed
+ correctly.
+
+ 6. 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
@@ -67,12 +83,22 @@ The simplest way to compile this package is:
all sorts of other programs in order to regenerate files that came
with the distribution.
+ 7. Often, you can also type `make uninstall' to remove the installed
+ files again. In practice, not all packages have tested that
+ uninstallation works correctly, even though it is required by the
+ GNU Coding Standards.
+
+ 8. Some packages, particularly those that use Automake, provide `make
+ distcheck', which can by used by developers to test that all other
+ targets like `make install' and `make uninstall' work correctly.
+ This target is generally not run by end users.
+
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.
+ 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
@@ -85,25 +111,41 @@ is an example:
Compiling For Multiple Architectures
====================================
-You can compile the package for more than one kind of computer at the
+ 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 can use 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 `..'.
+source code in the directory that `configure' is in and in `..'. This
+is known as a "VPATH" build.
With a non-GNU `make', it is safer 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.
+ On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor. Like
+this:
+
+ ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CPP="gcc -E" CXXCPP="g++ -E"
+
+ This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
+
Installation Names
==================
-By default, `make install' installs the package's commands under
+ By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
-`configure' the option `--prefix=PREFIX'.
+`configure' the option `--prefix=PREFIX', where PREFIX must be an
+absolute file name.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
@@ -114,16 +156,47 @@ Documentation and other data files 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.
+you can set and what kinds of files go in them. In general, the
+default for these options is expressed in terms of `${prefix}', so that
+specifying just `--prefix' will affect all of the other directory
+specifications that were not explicitly provided.
+
+ The most portable way to affect installation locations is to pass the
+correct locations to `configure'; however, many packages provide one or
+both of the following shortcuts of passing variable assignments to the
+`make install' command line to change installation locations without
+having to reconfigure or recompile.
+
+ The first method involves providing an override variable for each
+affected directory. For example, `make install
+prefix=/alternate/directory' will choose an alternate location for all
+directory configuration variables that were expressed in terms of
+`${prefix}'. Any directories that were specified during `configure',
+but not in terms of `${prefix}', must each be overridden at install
+time for the entire installation to be relocated. The approach of
+makefile variable overrides for each directory variable is required by
+the GNU Coding Standards, and ideally causes no recompilation.
+However, some platforms have known limitations with the semantics of
+shared libraries that end up requiring recompilation when using this
+method, particularly noticeable in packages that use GNU Libtool.
+
+ The second method involves providing the `DESTDIR' variable. For
+example, `make install DESTDIR=/alternate/directory' will prepend
+`/alternate/directory' before all installation names. The approach of
+`DESTDIR' overrides is not required by the GNU Coding Standards, and
+does not work on platforms that have drive letters. On the other hand,
+it does better at avoiding recompilation issues, and works well even
+when some directory options were not specified in terms of `${prefix}'
+at `configure' time.
+
+Optional Features
+=================
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
+ 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
@@ -135,14 +208,58 @@ 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.
+ Some packages offer the ability to configure how verbose the
+execution of `make' will be. For these packages, running `./configure
+--enable-silent-rules' sets the default to minimal output, which can be
+overridden with `make V=1'; while running `./configure
+--disable-silent-rules' sets the default to verbose, which can be
+overridden with `make V=0'.
+
+Particular systems
+==================
+
+ On HP-UX, the default C compiler is not ANSI C compatible. If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+ ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+ HP-UX `make' updates targets which have the same time stamps as
+their prerequisites, which makes it generally unusable when shipped
+generated files such as `configure' are involved. Use GNU `make'
+instead.
+
+ On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file. The option `-nodtk' can be used as
+a workaround. If GNU CC is not installed, it is therefore recommended
+to try
+
+ ./configure CC="cc"
+
+and if that doesn't work, try
+
+ ./configure CC="cc -nodtk"
+
+ On Solaris, don't put `/usr/ucb' early in your `PATH'. This
+directory contains several dysfunctional programs; working variants of
+these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
+in your `PATH', put it _after_ `/usr/bin'.
+
+ On Haiku, software installed for all users goes in `/boot/common',
+not `/usr/local'. It is recommended to use the following options:
+
+ ./configure --prefix=/boot/common
+
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
+ 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:
@@ -150,7 +267,8 @@ type, such as `sun4', or a canonical name which has the form:
where SYSTEM can have one of these forms:
- OS KERNEL-OS
+ 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
@@ -168,9 +286,9 @@ 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'.
+ 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.
@@ -179,7 +297,7 @@ 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
+ 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
@@ -191,18 +309,27 @@ causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf bug. Until the bug is fixed you can use this workaround:
+an Autoconf limitation. Until the limitation is lifted, you can use
+this workaround:
- CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+ CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
-`configure' recognizes the following options to control how it operates.
+ `configure' recognizes the following options to control how it
+operates.
`--help'
`-h'
- Print a summary of the options to `configure', and exit.
+ Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+ Print a summary of the options unique to this package's
+ `configure', and exit. The `short' variant lists options used
+ only in the top level, while the `recursive' variant lists options
+ also present in any nested packages.
`--version'
`-V'
@@ -229,6 +356,15 @@ an Autoconf bug. Until the bug is fixed you can use this workaround:
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
+`--prefix=DIR'
+ Use DIR as the installation prefix. *note Installation Names::
+ for more details, including other options available for fine-tuning
+ the installation locations.
+
+`--no-create'
+`-n'
+ Run the configure checks, but stop before creating any output
+ files.
+
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.
-
diff --git a/LIMITATIONS b/LIMITATIONS
deleted file mode 100644
index 719f018a..00000000
--- a/LIMITATIONS
+++ /dev/null
@@ -1,22 +0,0 @@
- Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-
- Copying and distribution of this file, with or without modification,
- are permitted in any medium without royalty provided the copyright
- notice and this notice are preserved.
-
-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
diff --git a/Makefile.am b/Makefile.am
index e9248506..9119ad91 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
#
# Makefile.am --- automake input file for gawk
#
-# Copyright (C) 2000-2011 the Free Software Foundation, Inc.
+# Copyright (C) 2000-2014 the Free Software Foundation, Inc.
#
# This file is part of GAWK, the GNU implementation of the
# AWK Programming Language.
@@ -35,20 +35,16 @@ AM_MAKEFLAGS = 'CFLAGS=$(CFLAGS)' 'LDFLAGS=$(LDFLAGS)'
EXTRA_DIST = \
ChangeLog.0 \
COPYING \
- FUTURES \
INSTALL \
- LIMITATIONS \
NEWS \
NEWS.0 \
POSIX.STD \
- PROBLEMS \
README_d \
bisonfix.awk \
config.guess \
config.rpath \
config.sub \
depcomp \
- extension \
m4 \
missing \
missing_d \
@@ -59,42 +55,47 @@ EXTRA_DIST = \
regex_internal.c \
regex_internal.h \
regexec.c \
- version.in \
vms \
ylwrap
-# It's OK for the generated file `version.c' not to be removed by
-# "make distclean".
-distcleancheck_listfiles = \
- find . -type f -print | grep -v '^\./version\.c$$'
-
# The order to do things in.
# Build explicitly in "." in order to build gawk first, so
# that `make check' without a prior `make' works.
+# Build in awklib after in doc, since we want to extract
+# sample files if doc/gawk.texi changed.
SUBDIRS = \
. \
- awklib \
doc \
+ awklib \
po \
+ extension \
+ extras \
test
# what to make and install
-bin_PROGRAMS = gawk pgawk dgawk
+bin_PROGRAMS = gawk
+include_HEADERS = gawkapi.h
-# sources for both gawk and pgawk
+# sources for both gawk and dgawk
base_sources = \
array.c \
awk.h \
awkgram.y \
builtin.c \
cint_array.c \
+ cmd.h \
+ command.y \
custom.h \
+ debug.c \
dfa.c \
dfa.h \
+ eval.c \
ext.c \
field.c \
floatcomp.c \
floatmagic.h \
+ gawkapi.c \
+ gawkapi.h \
gawkmisc.c \
getopt.c \
getopt.h \
@@ -102,11 +103,15 @@ base_sources = \
getopt_int.h \
gettext.h \
int_array.c \
+ interpret.h \
io.c \
mbsupport.h \
main.c \
+ mpfr.c \
msg.c \
node.c \
+ nonposix.h \
+ profile.c \
protos.h \
random.c \
random.h \
@@ -119,13 +124,10 @@ base_sources = \
version.c \
xalloc.h
-gawk_SOURCES = $(base_sources) eval.c profile.c
-pgawk_SOURCES = $(base_sources) eval_p.c profile_p.c
-dgawk_SOURCES = $(base_sources) eval_d.c profile.c cmd.h command.y debug.c
+gawk_SOURCES = $(base_sources)
# Get extra libs as needed, Automake will supply LIBINTL and SOCKET_LIBS.
-LDADD = $(LIBSIGSEGV) $(LIBINTL) $(SOCKET_LIBS)
-dgawk_LDADD = $(LDADD) @LIBREADLINE@
+LDADD = $(LIBSIGSEGV) $(LIBINTL) $(SOCKET_LIBS) $(LIBREADLINE) $(LIBMPFR)
# Directory for gawk's data files. Automake supplies datadir.
pkgdatadir = $(datadir)/awk
@@ -133,18 +135,22 @@ pkgdatadir = $(datadir)/awk
# stuff for compiling gawk/pgawk
DEFPATH='".$(PATH_SEPARATOR)$(pkgdatadir)"'
-DEFS= -DDEFPATH=$(DEFPATH) -DHAVE_CONFIG_H -DGAWK -DLOCALEDIR='"$(datadir)/locale"'
+# shared library support:
+SHLIBEXT = "\"$(GAWKLIBEXT)"\"
+DEFLIBPATH="\"$(pkgextensiondir)\""
+
+DEFS= -DDEFPATH=$(DEFPATH) -DDEFLIBPATH=$(DEFLIBPATH) -DSHLIBEXT=$(SHLIBEXT) -DHAVE_CONFIG_H -DGAWK -DLOCALEDIR='"$(datadir)/locale"'
# Get rid of core files when cleaning
CLEANFILES = core core.*
-MAINTAINERCLEANFILES = version.c
-
# We want hard links for install-exec-hook, below
LN= ln
+# For some make's, e.g. OpenBSD, that don't define this
+RM = rm -f
+
# 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
@@ -152,35 +158,39 @@ LN= ln
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 ]; \
- then $(LN_S) gawk$(EXEEXT) awk; \
+ 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 ] && cmp awk gawk$(EXEEXT) > /dev/null; then rm -f awk; fi ; \
- rm -f gawk-$(VERSION)$(EXEEXT) pgawk-$(VERSION)$(EXEEXT); exit 0)
+ if [ -f awk$(EXEEXT) ] && cmp awk$(EXEEXT) gawk$(EXEEXT) > /dev/null; then rm -f awk$(EXEEXT); fi ; \
+ rm -f gawk-$(VERSION)$(EXEEXT); exit 0)
uninstall-recursive: uninstall-links
# force there to be a gawk executable before running tests
-check-local: gawk$(EXEEXT) pgawk$(EXEEXT)
+check-local: gawk$(EXEEXT)
# A little extra clean up when making distributions.
# And additional set up for the pc directory.
dist-hook:
cd $(distdir)/extension ; rm -f *.o *.so
cd $(srcdir)/pc ; \
- sed -n -f configpk.sed < ../configure.ac > tmp.sed ; \
- sed -f config.sed < ../configh.in > config.tmp ; \
- sed -f tmp.sed < config.tmp > config.h ; \
- $(RM) tmp.sed config.tmp
+ chmod u+w config.h ; \
+ sed -n -f configpk.sed < ../configure.ac > /tmp/tmp.sed ; \
+ sed -f config.sed < ../configh.in > /tmp/config.tmp ; \
+ sed -f /tmp/tmp.sed < /tmp/config.tmp > config.h ; \
+ $(RM) /tmp/tmp.sed /tmp/config.tmp
+ pwd
+ chmod u+w $(distdir)/pc/config.h
+ cp $(srcdir)/pc/config.h $(distdir)/pc/config.h
# Special rules for individual files
# Use of awk instead of $(AWK) is deliberate, in case gawk doesn't build
# or work correctly.
+
awkgram.c: awkgram.y
$(YACC) $(AM_YFLAGS) $(YFLAGS) $<
sed 's/parse error/syntax error/g' < y.tab.c | awk -f $(srcdir)/bisonfix.awk awkgram > $*.c && rm y.tab.c
@@ -188,9 +198,6 @@ awkgram.c: awkgram.y
if cmp -s y.tab.h $*.h; then rm -f y.tab.h; else mv y.tab.h $*.h; fi; \
else :; fi
-version.c: config.status version.in
- $(SHELL) ./config.status --file=version.c:version.in
-
command.c: command.y
$(YACC) -p zz $<
sed 's/parse error/syntax error/g' < y.tab.c | awk -f $(srcdir)/bisonfix.awk command > $*.c && rm y.tab.c
@@ -204,5 +211,10 @@ diffout valgrind-scan:
valgrind:
cd test; rm -f log.[0-9]*; \
- make check AWK="valgrind --leak-check=full --log-file=log.%p ../gawk"; \
+ make check VALGRIND="valgrind --leak-check=full --log-file=log.%p"; \
+ make valgrind-scan
+
+valgrind-noleak:
+ cd test; rm -f log.[0-9]*; \
+ make check VALGRIND="valgrind --leak-check=no --log-file=log.%p"; \
make valgrind-scan
diff --git a/Makefile.in b/Makefile.in
index 26d6017b..e45c520f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
+# Copyright (C) 1994-2013 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.
@@ -18,7 +17,7 @@
#
# Makefile.am --- automake input file for gawk
#
-# Copyright (C) 2000-2011 the Free Software Foundation, Inc.
+# Copyright (C) 2000-2014 the Free Software Foundation, Inc.
#
# This file is part of GAWK, the GNU implementation of the
# AWK Programming Language.
@@ -38,7 +37,53 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
+
VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
@@ -56,26 +101,26 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-bin_PROGRAMS = gawk$(EXEEXT) pgawk$(EXEEXT) dgawk$(EXEEXT)
+bin_PROGRAMS = gawk$(EXEEXT)
subdir = .
-DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
- $(srcdir)/Makefile.in $(srcdir)/configh.in \
- $(top_srcdir)/configure ABOUT-NLS AUTHORS COPYING ChangeLog \
- INSTALL NEWS TODO awkgram.c command.c config.guess \
- config.rpath config.sub depcomp install-sh missing \
- mkinstalldirs ylwrap
+DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \
+ $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/configure $(am__configure_deps) \
+ $(srcdir)/configh.in mkinstalldirs ABOUT-NLS awkgram.c \
+ command.c depcomp ylwrap $(include_HEADERS) COPYING TODO \
+ compile config.guess config.rpath config.sub install-sh \
+ missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/arch.m4 \
$(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/gettext.m4 \
$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
- $(top_srcdir)/m4/intmax_t.m4 $(top_srcdir)/m4/inttypes_h.m4 \
$(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/lcmessage.m4 \
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libsigsegv.m4 \
- $(top_srcdir)/m4/longlong.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/longlong.m4 $(top_srcdir)/m4/mpfr.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/noreturn.m4 \
$(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
$(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/socket.m4 \
- $(top_srcdir)/m4/stdint_h.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)
@@ -85,68 +130,143 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
-am__installdirs = "$(DESTDIR)$(bindir)"
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)"
PROGRAMS = $(bin_PROGRAMS)
am__objects_1 = array.$(OBJEXT) awkgram.$(OBJEXT) builtin.$(OBJEXT) \
- cint_array.$(OBJEXT) dfa.$(OBJEXT) ext.$(OBJEXT) \
- field.$(OBJEXT) floatcomp.$(OBJEXT) gawkmisc.$(OBJEXT) \
+ cint_array.$(OBJEXT) command.$(OBJEXT) debug.$(OBJEXT) \
+ dfa.$(OBJEXT) eval.$(OBJEXT) ext.$(OBJEXT) field.$(OBJEXT) \
+ floatcomp.$(OBJEXT) gawkapi.$(OBJEXT) gawkmisc.$(OBJEXT) \
getopt.$(OBJEXT) getopt1.$(OBJEXT) int_array.$(OBJEXT) \
- io.$(OBJEXT) main.$(OBJEXT) msg.$(OBJEXT) node.$(OBJEXT) \
- random.$(OBJEXT) re.$(OBJEXT) regex.$(OBJEXT) \
- replace.$(OBJEXT) str_array.$(OBJEXT) symbol.$(OBJEXT) \
- version.$(OBJEXT)
-am_dgawk_OBJECTS = $(am__objects_1) eval_d.$(OBJEXT) profile.$(OBJEXT) \
- command.$(OBJEXT) debug.$(OBJEXT)
-dgawk_OBJECTS = $(am_dgawk_OBJECTS)
-am__DEPENDENCIES_1 =
-am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1)
-dgawk_DEPENDENCIES = $(am__DEPENDENCIES_2)
-am_gawk_OBJECTS = $(am__objects_1) eval.$(OBJEXT) profile.$(OBJEXT)
+ io.$(OBJEXT) main.$(OBJEXT) mpfr.$(OBJEXT) msg.$(OBJEXT) \
+ node.$(OBJEXT) profile.$(OBJEXT) random.$(OBJEXT) re.$(OBJEXT) \
+ regex.$(OBJEXT) replace.$(OBJEXT) str_array.$(OBJEXT) \
+ symbol.$(OBJEXT) version.$(OBJEXT)
+am_gawk_OBJECTS = $(am__objects_1)
gawk_OBJECTS = $(am_gawk_OBJECTS)
gawk_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
gawk_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
-am_pgawk_OBJECTS = $(am__objects_1) eval_p.$(OBJEXT) \
- profile_p.$(OBJEXT)
-pgawk_OBJECTS = $(am_pgawk_OBJECTS)
-pgawk_LDADD = $(LDADD)
-pgawk_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \
+ -e s/c++$$/h++/ -e s/c$$/h/
+YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS)
+AM_V_YACC = $(am__v_YACC_@AM_V@)
+am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@)
+am__v_YACC_0 = @echo " YACC " $@;
+am__v_YACC_1 =
YLWRAP = $(top_srcdir)/ylwrap
-SOURCES = $(dgawk_SOURCES) $(gawk_SOURCES) $(pgawk_SOURCES)
-DIST_SOURCES = $(dgawk_SOURCES) $(gawk_SOURCES) $(pgawk_SOURCES)
-RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
- html-recursive info-recursive install-data-recursive \
- install-dvi-recursive install-exec-recursive \
- install-html-recursive install-info-recursive \
- install-pdf-recursive install-ps-recursive install-recursive \
- installcheck-recursive installdirs-recursive pdf-recursive \
- ps-recursive uninstall-recursive
+SOURCES = $(gawk_SOURCES)
+DIST_SOURCES = $(gawk_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+HEADERS = $(include_HEADERS)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
-AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
- $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
- distdir dist dist-all distcheck
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ cscope distdir dist dist-all distcheck
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+ $(LISP)configh.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
+CSCOPE = cscope
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)"; }; }
+ if test -d "$(distdir)"; then \
+ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -rf "$(distdir)" \
+ || { sleep 5 && rm -rf "$(distdir)"; }; \
+ else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
@@ -172,14 +292,19 @@ am__relativize = \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
-DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.xz
+DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.lz $(distdir).tar.xz
GZIP_ENV = --best
+DIST_TARGETS = dist-lzip dist-xz dist-gzip
distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
# Directory for gawk's data files. Automake supplies datadir.
pkgdatadir = $(datadir)/awk
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
@@ -190,13 +315,14 @@ CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
-DEFS = -DDEFPATH=$(DEFPATH) -DHAVE_CONFIG_H -DGAWK -DLOCALEDIR='"$(datadir)/locale"'
+DEFS = -DDEFPATH=$(DEFPATH) -DDEFLIBPATH=$(DEFLIBPATH) -DSHLIBEXT=$(SHLIBEXT) -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@
+GAWKLIBEXT = @GAWKLIBEXT@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
@@ -212,6 +338,7 @@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
LDFLAGS = @LDFLAGS@
LIBICONV = @LIBICONV@
LIBINTL = @LIBINTL@
+LIBMPFR = @LIBMPFR@
LIBOBJS = @LIBOBJS@
LIBREADLINE = @LIBREADLINE@
LIBS = @LIBS@
@@ -237,6 +364,7 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
POSUB = @POSUB@
+SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SOCKET_LIBS = @SOCKET_LIBS@
@@ -253,6 +381,7 @@ abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
+acl_shlibext = @acl_shlibext@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -287,12 +416,14 @@ mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
+pkgextensiondir = @pkgextensiondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
@@ -311,20 +442,16 @@ AM_MAKEFLAGS = 'CFLAGS=$(CFLAGS)' 'LDFLAGS=$(LDFLAGS)'
EXTRA_DIST = \
ChangeLog.0 \
COPYING \
- FUTURES \
INSTALL \
- LIMITATIONS \
NEWS \
NEWS.0 \
POSIX.STD \
- PROBLEMS \
README_d \
bisonfix.awk \
config.guess \
config.rpath \
config.sub \
depcomp \
- extension \
m4 \
missing \
missing_d \
@@ -335,42 +462,46 @@ EXTRA_DIST = \
regex_internal.c \
regex_internal.h \
regexec.c \
- version.in \
vms \
ylwrap
-# It's OK for the generated file `version.c' not to be removed by
-# "make distclean".
-distcleancheck_listfiles = \
- find . -type f -print | grep -v '^\./version\.c$$'
-
-
# The order to do things in.
# Build explicitly in "." in order to build gawk first, so
# that `make check' without a prior `make' works.
+# Build in awklib after in doc, since we want to extract
+# sample files if doc/gawk.texi changed.
SUBDIRS = \
. \
- awklib \
doc \
+ awklib \
po \
+ extension \
+ extras \
test
+include_HEADERS = gawkapi.h
-# sources for both gawk and pgawk
+# sources for both gawk and dgawk
base_sources = \
array.c \
awk.h \
awkgram.y \
builtin.c \
cint_array.c \
+ cmd.h \
+ command.y \
custom.h \
+ debug.c \
dfa.c \
dfa.h \
+ eval.c \
ext.c \
field.c \
floatcomp.c \
floatmagic.h \
+ gawkapi.c \
+ gawkapi.h \
gawkmisc.c \
getopt.c \
getopt.h \
@@ -378,11 +509,15 @@ base_sources = \
getopt_int.h \
gettext.h \
int_array.c \
+ interpret.h \
io.c \
mbsupport.h \
main.c \
+ mpfr.c \
msg.c \
node.c \
+ nonposix.h \
+ profile.c \
protos.h \
random.c \
random.h \
@@ -395,29 +530,32 @@ base_sources = \
version.c \
xalloc.h
-gawk_SOURCES = $(base_sources) eval.c profile.c
-pgawk_SOURCES = $(base_sources) eval_p.c profile_p.c
-dgawk_SOURCES = $(base_sources) eval_d.c profile.c cmd.h command.y debug.c
+gawk_SOURCES = $(base_sources)
# Get extra libs as needed, Automake will supply LIBINTL and SOCKET_LIBS.
-LDADD = $(LIBSIGSEGV) $(LIBINTL) $(SOCKET_LIBS)
-dgawk_LDADD = $(LDADD) @LIBREADLINE@
+LDADD = $(LIBSIGSEGV) $(LIBINTL) $(SOCKET_LIBS) $(LIBREADLINE) $(LIBMPFR)
# stuff for compiling gawk/pgawk
DEFPATH = '".$(PATH_SEPARATOR)$(pkgdatadir)"'
+# shared library support:
+SHLIBEXT = "\"$(GAWKLIBEXT)"\"
+DEFLIBPATH = "\"$(pkgextensiondir)\""
+
# Get rid of core files when cleaning
CLEANFILES = core core.*
-MAINTAINERCLEANFILES = version.c
# We want hard links for install-exec-hook, below
LN = ln
+
+# For some make's, e.g. OpenBSD, that don't define this
+RM = rm -f
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
.SUFFIXES:
.SUFFIXES: .c .o .obj .y
-am--refresh:
+am--refresh: Makefile
@:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
@@ -453,10 +591,8 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
config.h: stamp-h1
- @if test ! -f $@; then \
- rm -f stamp-h1; \
- $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
- else :; fi
+ @test -f $@ || rm -f stamp-h1
+ @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
stamp-h1: $(srcdir)/configh.in $(top_builddir)/config.status
@rm -f stamp-h1
@@ -470,14 +606,18 @@ distclean-hdr:
-rm -f config.h stamp-h1
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
- test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+ fi; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
- while read p p1; do if test -f $$p; \
- then echo "$$p"; echo "$$p"; else :; fi; \
+ while read p p1; do if test -f $$p \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
done | \
- sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
@@ -498,22 +638,18 @@ uninstall-binPROGRAMS:
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
- -e 's/$$/$(EXEEXT)/' `; \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(bindir)" && rm -f $$files
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
-dgawk$(EXEEXT): $(dgawk_OBJECTS) $(dgawk_DEPENDENCIES)
- @rm -f dgawk$(EXEEXT)
- $(LINK) $(dgawk_OBJECTS) $(dgawk_LDADD) $(LIBS)
-gawk$(EXEEXT): $(gawk_OBJECTS) $(gawk_DEPENDENCIES)
+
+gawk$(EXEEXT): $(gawk_OBJECTS) $(gawk_DEPENDENCIES) $(EXTRA_gawk_DEPENDENCIES)
@rm -f gawk$(EXEEXT)
- $(LINK) $(gawk_OBJECTS) $(gawk_LDADD) $(LIBS)
-pgawk$(EXEEXT): $(pgawk_OBJECTS) $(pgawk_DEPENDENCIES)
- @rm -f pgawk$(EXEEXT)
- $(LINK) $(pgawk_OBJECTS) $(pgawk_LDADD) $(LIBS)
+ $(AM_V_CCLD)$(LINK) $(gawk_OBJECTS) $(gawk_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -529,21 +665,20 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dfa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eval.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eval_d.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eval_p.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/field.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/floatcomp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gawkapi.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gawkmisc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/int_array.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpfr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msg.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profile.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profile_p.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/re.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regex.Po@am__quote@
@@ -553,39 +688,63 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@
.c.o:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.y.c:
- $(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE)
+ $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE)
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
# 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):
- @fail= failcom='exit 1'; \
- for f in x $$MAKEFLAGS; do \
- case $$f in \
- *=* | --[!k]*);; \
- *k*) failcom='fail=yes';; \
- esac; \
- done; \
+# 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.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
- list='$(SUBDIRS)'; for subdir in $$list; do \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
@@ -600,57 +759,12 @@ $(RECURSIVE_TARGETS):
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
-$(RECURSIVE_CLEAN_TARGETS):
- @fail= 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; \
- ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
- || eval $$failcom; \
- done && test -z "$$fail"
-tags-recursive:
- list='$(SUBDIRS)'; for subdir in $$list; do \
- test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
- done
-ctags-recursive:
- list='$(SUBDIRS)'; for subdir in $$list; do \
- test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
- done
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
-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; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: tags-recursive $(HEADERS) $(SOURCES) configh.in $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
@@ -666,12 +780,7 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) configh.in $(TAGS_DEPENDENCIES) \
set "$$@" "$$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; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
+ $(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
@@ -683,15 +792,11 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) configh.in $(TAGS_DEPENDENCIES) \
$$unique; \
fi; \
fi
-ctags: CTAGS
-CTAGS: ctags-recursive $(HEADERS) $(SOURCES) configh.in $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- 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; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
@@ -700,9 +805,31 @@ GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+ test ! -s cscope.files \
+ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+ -rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+ -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
distdir: $(DISTFILES)
$(am__remove_distdir)
@@ -738,13 +865,10 @@ distdir: $(DISTFILES)
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
- test -d "$(distdir)/$$subdir" \
- || $(MKDIR_P) "$(distdir)/$$subdir" \
- || exit 1; \
- fi; \
- done
- @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
@@ -776,36 +900,40 @@ distdir: $(DISTFILES)
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
dist-bzip2: distdir
- tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
- $(am__remove_distdir)
-
-dist-lzma: distdir
- tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
- $(am__remove_distdir)
+ tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+ $(am__post_remove_distdir)
+dist-lzip: distdir
+ tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+ $(am__post_remove_distdir)
dist-xz: distdir
- tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
- $(am__remove_distdir)
+ tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+ $(am__post_remove_distdir)
dist-tarZ: distdir
+ @echo WARNING: "Support for shar distribution archives is" \
+ "deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
dist-shar: distdir
+ @echo WARNING: "Support for distribution archives compressed with" \
+ "legacy program 'compress' is deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
-dist dist-all: distdir
- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
- tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
- $(am__remove_distdir)
+dist dist-all:
+ $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+ $(am__post_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
@@ -816,8 +944,8 @@ distcheck: dist
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
- *.tar.lzma*) \
- lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
+ *.tar.lz*) \
+ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
*.tar.xz*) \
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
*.tar.Z*) \
@@ -827,17 +955,19 @@ distcheck: dist
*.zip*) \
unzip $(distdir).zip ;;\
esac
- chmod -R a-w $(distdir); chmod a+w $(distdir)
- mkdir $(distdir)/_build
- mkdir $(distdir)/_inst
+ chmod -R a-w $(distdir)
+ chmod u+w $(distdir)
+ mkdir $(distdir)/_build $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build \
- && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ && ../configure \
+ $(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
+ --srcdir=.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
@@ -860,13 +990,21 @@ distcheck: dist
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
&& cd "$$am__cwd" \
|| exit 1
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
distuninstallcheck:
- @$(am__cd) '$(distuninstallcheck_dir)' \
- && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+ @test -n '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: trying to run $@ with an empty' \
+ '$$(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ $(am__cd) '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
@@ -885,10 +1023,10 @@ distcleancheck: distclean
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-local
check: check-recursive
-all-am: Makefile $(PROGRAMS) config.h
+all-am: Makefile $(PROGRAMS) $(HEADERS) config.h
installdirs: installdirs-recursive
installdirs-am:
- for dir in "$(DESTDIR)$(bindir)"; do \
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-recursive
@@ -901,10 +1039,15 @@ install-am: all-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
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
mostlyclean-generic:
clean-generic:
@@ -919,7 +1062,6 @@ maintainer-clean-generic:
@echo "it deletes files that may require special tools to rebuild."
-rm -f awkgram.c
-rm -f command.c
- -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-recursive
clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
@@ -943,7 +1085,7 @@ info: info-recursive
info-am:
-install-data-am:
+install-data-am: install-includeHEADERS
install-dvi: install-dvi-recursive
@@ -991,33 +1133,32 @@ ps: ps-recursive
ps-am:
-uninstall-am: uninstall-binPROGRAMS
+uninstall-am: uninstall-binPROGRAMS uninstall-includeHEADERS
-.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check-am \
- ctags-recursive install-am install-exec-am install-strip \
- tags-recursive
+.MAKE: $(am__recursive_targets) all check-am install-am \
+ install-exec-am install-strip
-.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
- all all-am am--refresh check check-am check-local clean \
- clean-binPROGRAMS clean-generic ctags ctags-recursive dist \
- dist-all dist-bzip2 dist-gzip dist-hook dist-lzma dist-shar \
- dist-tarZ dist-xz dist-zip distcheck distclean \
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
+ am--refresh check check-am check-local clean clean-binPROGRAMS \
+ clean-cscope clean-generic cscope cscopelist-am ctags ctags-am \
+ dist dist-all dist-bzip2 dist-gzip dist-hook dist-lzip \
+ dist-shar dist-tarZ dist-xz dist-zip distcheck distclean \
distclean-compile distclean-generic distclean-hdr \
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-dvi \
install-dvi-am install-exec install-exec-am install-exec-hook \
- install-html install-html-am install-info install-info-am \
- install-man install-pdf install-pdf-am install-ps \
- install-ps-am install-strip installcheck installcheck-am \
- installdirs installdirs-am maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-compile \
- mostlyclean-generic pdf pdf-am ps ps-am tags tags-recursive \
- uninstall uninstall-am uninstall-binPROGRAMS
+ install-html install-html-am install-includeHEADERS \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs installdirs-am \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-includeHEADERS
# 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
@@ -1025,35 +1166,39 @@ uninstall-am: uninstall-binPROGRAMS
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 ]; \
- then $(LN_S) gawk$(EXEEXT) awk; \
+ 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 ] && cmp awk gawk$(EXEEXT) > /dev/null; then rm -f awk; fi ; \
- rm -f gawk-$(VERSION)$(EXEEXT) pgawk-$(VERSION)$(EXEEXT); exit 0)
+ if [ -f awk$(EXEEXT) ] && cmp awk$(EXEEXT) gawk$(EXEEXT) > /dev/null; then rm -f awk$(EXEEXT); fi ; \
+ rm -f gawk-$(VERSION)$(EXEEXT); exit 0)
uninstall-recursive: uninstall-links
# force there to be a gawk executable before running tests
-check-local: gawk$(EXEEXT) pgawk$(EXEEXT)
+check-local: gawk$(EXEEXT)
# A little extra clean up when making distributions.
# And additional set up for the pc directory.
dist-hook:
cd $(distdir)/extension ; rm -f *.o *.so
cd $(srcdir)/pc ; \
- sed -n -f configpk.sed < ../configure.ac > tmp.sed ; \
- sed -f config.sed < ../configh.in > config.tmp ; \
- sed -f tmp.sed < config.tmp > config.h ; \
- $(RM) tmp.sed config.tmp
+ chmod u+w config.h ; \
+ sed -n -f configpk.sed < ../configure.ac > /tmp/tmp.sed ; \
+ sed -f config.sed < ../configh.in > /tmp/config.tmp ; \
+ sed -f /tmp/tmp.sed < /tmp/config.tmp > config.h ; \
+ $(RM) /tmp/tmp.sed /tmp/config.tmp
+ pwd
+ chmod u+w $(distdir)/pc/config.h
+ cp $(srcdir)/pc/config.h $(distdir)/pc/config.h
# Special rules for individual files
# Use of awk instead of $(AWK) is deliberate, in case gawk doesn't build
# or work correctly.
+
awkgram.c: awkgram.y
$(YACC) $(AM_YFLAGS) $(YFLAGS) $<
sed 's/parse error/syntax error/g' < y.tab.c | awk -f $(srcdir)/bisonfix.awk awkgram > $*.c && rm y.tab.c
@@ -1061,9 +1206,6 @@ awkgram.c: awkgram.y
if cmp -s y.tab.h $*.h; then rm -f y.tab.h; else mv y.tab.h $*.h; fi; \
else :; fi
-version.c: config.status version.in
- $(SHELL) ./config.status --file=version.c:version.in
-
command.c: command.y
$(YACC) -p zz $<
sed 's/parse error/syntax error/g' < y.tab.c | awk -f $(srcdir)/bisonfix.awk command > $*.c && rm y.tab.c
@@ -1077,7 +1219,12 @@ diffout valgrind-scan:
valgrind:
cd test; rm -f log.[0-9]*; \
- make check AWK="valgrind --leak-check=full --log-file=log.%p ../gawk"; \
+ make check VALGRIND="valgrind --leak-check=full --log-file=log.%p"; \
+ make valgrind-scan
+
+valgrind-noleak:
+ cd test; rm -f log.[0-9]*; \
+ make check VALGRIND="valgrind --leak-check=no --log-file=log.%p"; \
make valgrind-scan
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/NEWS b/NEWS
index 0106f7ce..421d2c76 100644
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,215 @@
- Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.
+
+Changes from 4.1.x to 4.2.0
+---------------------------
+
+1. If not in POSIX mode, changes to ENVIRON are reflected into
+ gawk's environment, affecting any programs run by system()
+ or for piped redirections. This can also affect built-in routines, such
+ as mktime(), which is typically influenced by the TZ environment variable.
+
+2. The series of numbers returned by rand() should now be "more
+ random" than previously. Gawk's rand() remains repeatable; you will
+ get the same series of numbers each time you call rand() repeatedly,
+ but this will be a different series than previously.
+
+3. The --pretty-print option no longer runs the program too.
+
+4. The igawk script and igawk.1 man page are no longer installed by
+ `make install'. They have been obsolete since gawk 4.0.0.
+
+5. Gawk now has a `div()' function to perform integer division; this is
+ primarily useful for the -M option to avoid MPFR division when all
+ values involved are integers.
+
+6. Gawk can now be built with CMake. This is an alternative build
+ system for those who may want it; gawk is not going to switch off
+ use of the autotools anytime soon, if ever.
+
+7. Gawk now processes a maximum of two hexadecimal digits in \x
+ escape sequences inside strings.
+
+8. MirBSD is no longer supported.
+
+9. Pretty printing now preserves comments and places them into the
+ pretty-printed file.
+
+10. `make install' now installs shell startup files
+ $sysconfdir/profile.d/gawk.{csh,sh} containing shell functions to
+ manipulate the AWKPATH and AWKLIBPATH environment variables. On a Fedora
+ system, these files belong in /etc/profile.d, but the appropriate location
+ may be different on other platforms.
+
+Changes from 4.1.1 to 4.1.2
+---------------------------
+
+1. The manual has been considerably improved.
+ - Thoroughly reviewed and updated.
+ - Out-of-date examples replaced.
+ - Chapter 15 on MPFR reworked.
+ - Summary sections added to all chapters.
+ - Exercises added in several chapters.
+
+2. The debugger's "restart" command now works again.
+
+3. Redirected getline is now allowed inside BEGINFILE/ENDFILE.
+
+4. A number of bugs have been fixed in the MPFR code.
+
+5. Indirect function calls now work for both built-in and
+ extension functions.
+
+6. Built-in functions are now included in FUNCTAB.
+
+7. In non-English locales, it was accidentally possible to use "letters"
+ beside those of the English alphabet in identifiers. This has
+ been fixed. (isalpha and isalnum are NOT our friends.)
+
+ If you feel that you must have this misfeature, use `configure --help'
+ to see what option to use when configuring gawk to reenable it.
+
+8. The "where" command has been added to the debugger as an alias
+ for "backtrace". This will make life easier for long-time GDB users.
+
+9. Gawk no longer explicitly checks the current directory after doing
+ a path search of AWKPATH. The default value continues to have "." at
+ the front, so most people should not be affected. If you have your own
+ AWKPATH setting, be sure to put "." in it somewhere. The documentation
+ has been updated and clarified.
+
+10. Infrastructure upgrades: Automake 1.14.1, Gettext 0.19.3, Libtool 2.4.3,
+ Bison 3.0.3.
+
+XX. A number of bugs have been fixed. See the ChangeLog.
+
+Changes from 4.1.0 to 4.1.1
+---------------------------
+
+1. The "stat" extension now includes a "devbsize" element which indicates
+ the units for the "nblocks" element.
+
+2. The extension facility now works on MinGW. Many of the extensions can be
+ built and used directly.
+
+3. A number of bugs in the pretty-printing / profiling code have been fixed.
+
+4. Sockets and two-way pipes now work under MinGW.
+
+5. The debugger now lists source code correctly under Cygwin.
+
+6. Configuration and building with the Mac OS X libreadline should work now.
+
+7. The -O option now works again.
+
+8. The --include option, documented since 4.0, now actually works.
+
+9. Infrastructure updated to automake 1.13.4, bison 3.0.2, and
+ libtool 2.4.2.418.
+
+10. The configure script now accepts a --disable-extensions option,
+ which disables checking for and building the extensions.
+
+11. The VMS port has been considerably improved. In particular config.h
+ is now generated by a DCL script. Also, the extension facility works
+ and several of the extensions can be built and used. Currently, the
+ extension facility only works on Alpha and Itanium.
+
+12. The API now provides functions pointers for malloc(), calloc(),
+ realloc() and free(), to insure that the same memory allocation
+ functions are always used. This bumps the minor version by one.
+
+13. The printf quote flag now works correctly in locales with a different
+ decimal point character but without a thousands separator character.
+ If the thousands separator is a string, it will be correctly added
+ to decimal numbers.
+
+14. The readfile extension now has an input parser that will read whole
+ files as a single record.
+
+15. A number of bugs have been fixed. See the ChangeLog.
+
+Changes from 4.0.2 to 4.1.0
+---------------------------
+
+1. The three executables gawk, pgawk, and dgawk, have been merged into
+ one, named just gawk. As a result:
+ * The -R option is gone
+ * Use -D to run the debugger. An optional file argument is a
+ list of commands to run first.
+ * Use -o to do pretty-printing only.
+ * Use -p to do profiling.
+ This considerably reduces gawk's "footprint" and eases the documentation
+ burden as well.
+
+2. Gawk now supports high precision arithmetic with MPFR. The default is
+ still double precision, but setting PREC changes things, or using
+ the -M / --bignum options. This support is not compiled in if the MPFR
+ library is not available.
+
+3. The new -i option (from xgawk) is used for loading awk library files.
+ This differs from -f in that the first non-option argument is treated
+ as a script.
+
+4. The new -l option (from xgawk) is used for loading dynamic extensions.
+
+5. The dynamic extension interface has been completely redone! There is
+ now a defined API for C extensions to use. A C extension acts like
+ a function written in awk, except that it cannot do everything that awk
+ code can. However, this allows interfacing to any facility that is
+ available from C. This is a major development, see the doc, which has
+ a nice shiny new chapter describing everything.
+
+ This support is not compiled in if dynamic loading of shared libraries
+ is not supported.
+
+ The old extension mechanism is still supported for compatiblity, but
+ it will most definitely be removed at the next major release.
+
+6. The "inplace" extension, built using the new facility, can be used to
+ simulate the GNU "sed -i" feature.
+
+7. The and(), or() and xor() functions now take any number of arguments,
+ with a minimum of two.
+
+8. New arrays: SYMTAB, FUNCTAB, and PROCINFO["identifiers"]. SYMTAB allows
+ indirect access to any defined variable or array; it is possible to
+ "walk" the symbol table, if that should be necessary.
+
+9. Support for building gawk with a cross compiler has been improved.
+
+10. Infrastructure upgrades: bison 2.7.1, gettext 0.18.2.1, automake 1.13.1,
+ libtool 2.4.2 for the extensions.
+
+Changes from 4.0.1 to 4.0.2
+---------------------------
+
+1. Infrastructure upgrades: Autoconf 2.69, Automake 1.12.6, bison 2.7.
+
+2. `fflush()', `nextfile', and `delete array' are all now part of POSIX.
+
+3. fflush() behavior changed to match BWK awk and for POSIX - now both
+ fflush() and fflush("") flush all open output redirections.
+
+4. Various minor bug fixes and documentation updates.
+Changes from 4.0.0 to 4.0.1
+---------------------------
+
+1. The default handling of backslash in sub() and gsub() has been reverted to
+ the behavior of 3.1. It was silly to think I could break compatibility that
+ way, even for standards compliance.
+
+2. Completed the implementation of Rational Range Interpretation.
+
+3. Failure to get the group set is no longer a fatal error.
+
+4. Lots of minor bugs fixed and portability clean-ups along the way. See
+ the ChangeLog for details.
+
Changes from 3.1.8 to 4.0.0
---------------------------
diff --git a/PROBLEMS b/PROBLEMS
deleted file mode 100644
index 072d56e7..00000000
--- a/PROBLEMS
+++ /dev/null
@@ -1,15 +0,0 @@
- Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-
- Copying and distribution of this file, with or without modification,
- are permitted in any medium without royalty provided the copyright
- notice and this notice are preserved.
-
-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.
diff --git a/README b/README
index 3e009c5c..a7925ee5 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
- Copyright (C) 2005, 2006, 2007, 2009, 2010, 2011
+ Copyright (C) 2005, 2006, 2007, 2009, 2010, 2011, 2012, 2013, 2014
Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
@@ -7,19 +7,21 @@
README:
-This is GNU Awk 4.0.0. It is upwardly compatible with Brian Kernighan's
+This is GNU Awk 4.1.1. It is upwardly compatible with Brian Kernighan's
version of Unix awk. It is almost completely compliant with the
2008 POSIX 1003.1 standard for awk. (See the note below about POSIX.)
-This is a major new release. See NEWS and ChangeLog for details.
+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.
+Work to be done is described briefly in the TODO file, which is available
+only in the 'master' branch in the Git repo.
+
+Changes in this version are summarized in the NEWS file.
Read the file POSIX.STD for a discussion of issues where the standard
says one thing but gawk does something different.
-To format the documentation with TeX, use at least version 2010-12-23.17
+To format the documentation with TeX, use at least version 2014-03-18.17
of texinfo.tex. There is a usable copy of texinfo.tex in the doc directory.
INSTALLATION:
@@ -45,9 +47,12 @@ 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.
+possibly in the case of strftime. There may be differences based on
+installed (or not installed) locales and the quality of multibyte
+character support on your system.
+
+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
@@ -65,7 +70,7 @@ 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 is now a separate mailing
+Email should be sent to bug-gawk@gnu.org. This is a separate mailing
list at GNU Central. The advantage to using this address is that bug
reports are archived at GNU Central.
@@ -86,8 +91,8 @@ OS/2:
andreas.buening@nexgo.de
VMS:
- Pat Rankin
- r.pat.rankin@gmail.com
+ John Malmberg
+ wb8tyw@qsl.net
z/OS (OS/390):
Dave Pitts
diff --git a/README.cvs b/README.cvs
index fa397ba9..4b1f4812 100644
--- a/README.cvs
+++ b/README.cvs
@@ -1,4 +1,4 @@
-Fri Feb 4 10:26:09 IST 2011
+Tue Feb 12 20:02:25 IST 2013
============================
If you are reading this, you are looking in the wrong file. Gawk is
@@ -9,10 +9,8 @@ According to the Savannah website, you can use:
cvs -d:pserver:anonymous@pserver.git.sv.gnu.org:/gawk.git \
co -d gawk master
-to get the development version. This works.
-
-However, as far as I can see, there is no way to get to any of the other
-branches in the Git repository via CVS.
+to get the development version. However, while this used to work, it
+no longer does, so it is not recommended.
Please move directly to Git if you can.
diff --git a/README.git b/README.git
index 59079598..c947cc24 100644
--- a/README.git
+++ b/README.git
@@ -1,4 +1,4 @@
-Mon Oct 24 21:50:18 IST 2011
+Thu Apr 17 16:54:26 IDT 2014
============================
If you are reading this, you have retrieved the gawk code base via
@@ -20,10 +20,27 @@ Really.
You can find gawk's GIT repository at Savannah
https://savannah.gnu.org/git/?group=gawk
+
Detailed instructions on using and contributing to gawk can also be
-found there
-http://savannah.gnu.org/maintenance/UsingGit
+found at Savannah, see http://savannah.gnu.org/maintenance/UsingGit
+
+Thanks,
+
+Arnold Robbins
+Gawk Maintainer
+
+=====================================================================
+Here are some questions and answers related to using git compiled
+by several of the gawk maintainers.
+- I don't want to mess with git. Can I just get a tarball of a branch without
+ a lot of hassle?
+
+Yes. Use something like this:
+
+ wget http://git.savannah.gnu.org/cgit/gawk.git/snapshot/gawk-BRANCH-NAME.tar.gz
+
+Put the right thing in place of BRANCH-NAME.
- How can I check out the GIT repository ?
@@ -179,6 +196,13 @@ something to the repository.
git checkout my_stuff # change to branch my_stuff
git checkout -b my_stuff # create new branch my_stuff and change to it
+- How can I pull patches from a branch ?
+
+ git pull origin feature_branch
+
+The name of the branch can be omitted if your current branch is
+created to track the feature_branch ("git branch -t", see below).
+
- How can I create a branch ?
For each new feature to be considered for inclusion into future
@@ -187,7 +211,8 @@ branch shall be based on the master branch.
# make master branch the base
git checkout master
- git branch my_new_feature_branch
+ # create new feature branch and connect local to upstream branch
+ git branch -t my_new_feature_branch
touch my_new_file.c
git add my_new_file.c
git status
@@ -195,6 +220,18 @@ branch shall be based on the master branch.
git push -u origin my_new_feature_branch
git checkout my_new_feature_branch
+
+- How can I merge recent patches from the master branch ?
+
+My feature branch has been created as describe above (based on master).
+While I committed and pushed up my changes, the master branch has also changed.
+Now I want to catch up with recent changes in the master branch.
+
+ git diff origin/master # What is in master that I don't have ?
+ git merge origin/master # Merge all master patches into local rep
+ git push -u origin my_new_feature_branch # Push these local changes up
+
+
- How can I throw away an obsolete branch ?
git push origin :newfeature # remove remote branch
@@ -204,12 +241,16 @@ branch shall be based on the master branch.
- I have made stupid changes to a file and want the original back, how ?
- svn checkout file_name.ext
+ git checkout file_name.ext
This will only work if the file was not yet committed.
If you have already committed the change and want back the
last pushed version, use "git reset" instead.
+- I have committed stupid changes, how can I undo the "git commit" ?
+
+ http://stackoverflow.com/questions/927358/git-undo-last-commit
+
- Who changed a specific line in my file ?
@@ -235,8 +276,90 @@ You can inspect the log history file-wise but also directory-wise.
git gc
+- How can I change settings with an editor (without "git xxx" command) ?
-Thanks,
+This is useful for inspecting the settings of local and remote branches that track each other.
-Arnold Robbins
-Gawk Maintainer
+ vi .git/config
+
+- I'm a devoted user of Bazaar, and don't want to switch to git. Is
+ there any way for me to track Gawk development with bzr?
+
+Yes, there is. First, install the latest version of bzr (2.5.0 or
+later is required). If it doesn't come with the bzr-git plugin,
+download and install it from https://launchpad.net/bzr-git. You will
+also need dulwich, which is a Python implementation of the git
+protocol; get it from http://www.samba.org/~jelmer/dulwich/.
+
+(To know whether you have bzr-git, type "bzr plugins".)
+
+Next, clone the Gawk git repository with this command:
+
+ bzr git-import git://git.savannah.gnu.org/gawk.git gawk
+
+This will create a directory called 'gawk' with meta-data of the
+repository, but without any working trees. To checkout the files,
+chdir to that directory and type:
+
+ bzr checkout
+
+This will checkout the files for the default branch. To see the list
+of branches, type
+
+ bzr branches
+
+To switch to another branch, type
+
+ bzr switch --force BRANCH
+
+where BRANCH is the name of the branch, e.g. 'xgawk'. (The --force
+option is a workaround for an annoying misfeature in bzr 2.5.0, which
+will most probably be resolved in the near future.)
+
+To sync the current branch with upstream, type
+
+ bzr pull
+
+If you want to update several branches, "bzr switch" to each one in
+turn, followed by "bzr pull" to sync the branch.
+
+- How do I manage things if I want to undo a commit?
+
+It depends upon if you have pushed the commit or not. Lots of good
+info is at http://stackoverflow.com/questions/927358/git-undo-last-commit .
+
+- What is the difference between using `git rebase' and `git merge' ?
+
+Both of these can be used to bring one branch up to date with respect
+to another. For example, if you are working on a feature branch based
+off master, and master has since progressed, you can use
+
+ git checkout feature
+ git merge master
+
+or
+
+ git checkout feature
+ git rebase master
+
+In the end, you will have your changes on top of the current version of
+master in the feature branch.
+
+So which to use? The answer depends on whether your feature branch
+has been pushed up to the Savannah repo or not.
+
+If your branch is completely local to your machine, use `git rebase'.
+Otherwise, use `git merge'.
+
+- How do I remove branches in my local repo that are no longer in the
+ remote repo?
+
+ Either
+ git fetch --prune
+ or
+ git remote prune origin
+
+ These remove the remote branches (i.e., origin/something)
+ that no longer exist on the remote.
+
+ (Thanks to Stepan Kasal for this answer.)
diff --git a/README_d/ChangeLog b/README_d/ChangeLog
index 945ba215..8c19cfdb 100644
--- a/README_d/ChangeLog
+++ b/README_d/ChangeLog
@@ -1,3 +1,72 @@
+2014-08-12 Juergen Kahrs <jkahrs@users.sourceforge.net>
+
+ * README.cmake: Moved file from top-level to here.
+
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.1: Release tar ball made.
+
+2014-04-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * README.gcc-3: New file.
+
+2014-01-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ * README.solaris: Updated.
+
+2014-01-12 John E. Malmberg <wb8tyw@qsl.net>
+
+ * README.VMS: document that the gawk.cld needs a fix.
+
+2013-12-23 John E. Malmberg <wb8tyw@qsl.net>
+
+ * README.VMS: Add documentation about building dynamic
+ extensions.
+
+2013-12-23 John E. Malmberg <wb8tyw@qsl.net>
+
+ * README.VMS: Document decoding Gawk VMS exit codes.
+
+2013-12-16 John E. Malmberg <wb8tyw@qsl.net>
+
+ * README.VMS: Further updates.
+
+2013-12-05 John E. Malmberg <wb8tyw@qsl.net>
+
+ * README.VMS: updated with current build information.
+
+2013-07-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * README.pc: Update that |& also now works on MinGW.
+
+2013-05-14 Eli Zaretskii <eliz@gnu.org>
+
+ * README.pc: Update the pc build and test instructions.
+
+2013-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.0: Release tar ball made.
+
+2013-04-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * README.hacking, README.mpfr, README.pc: Updated.
+
+2012-12-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.2: Release tar ball made.
+
+2012-04-11 John Haque <j.eh@mchsi.com>
+
+ * README.hacking: New file.
+
+2012-04-01 John Haque <j.eh@mchsi.com>
+
+ * README.mpfr: New file.
+
+2012-03-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.1: Release tar ball made.
+
2011-07-29 Arnold D. Robbins <arnold@skeeve.com>
* README.pc: Add download location info for DJGPP version.
diff --git a/README_d/README.VMS b/README_d/README.VMS
index b47cb0f7..0faabbc2 100644
--- a/README_d/README.VMS
+++ b/README_d/README.VMS
@@ -6,21 +6,112 @@ 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
+ |$ MMS/DESCRIPTION=[.VMS]DESCRIP.MMS gawk
+or
+ |$ MMK/DESCRIPTION=[.VMS]DESCRIP.MMS gawk
+
+Note that on IA64 and Alpha the case of the target may be important.
+MMS has had problems on ODS-5 volumes. MMK does not have these issues.
+MMK is available free from https://github.com/endlesssoftware/mmk.
+The most recent builds of gawk on VMS used MMK.
+
+Support of the vmsbuild.com may get dropped in a future release.
DEC C -- use either vmsbuild.com or descrip.mms as is.
+ DEC C is also known as Compaq C and HP C.
+
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.
+ * IMPORTANT NOTE * VAX C should not be used on VAX/VMS 5.5-2 and
+ later. Use DEC C instead.
+
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.
+Most recent builds are using:
+ OpenVMS VAX 7.3 using DEC C 6.4
+ OpenVMS Alpha 8.3 using HP C V 7.3
+ OpenVMS Alpha 8.4 using HP C V 7.3
+ OpenVMS IA64 8.4 using HP C V 7.3
+
+GAWK was originally ported for VMS V4.6 and up. It has not been tested
+with a release that old for some time.
+
+Compiling dynamic extensions on VMS:
+
+GAWK comes with some dynamic extensions. The extensions that have been
+ported to VMS can be built using one of the following commands.
+
+ |$ MMS/DESCRIPTION=[.VMS]DESCRIP.MMS extensions
+or
+ |$ MMK/DESCRIPTION=[.VMS]DESCRIP.MMS extensions
+
+GAWK uses AWKLIBPATH as either an environment variable or a logical name
+to find the dynamic extensions.
+
+Dynamic extensions need to be compiled with the same compiler options for
+floating point, pointer size, and symbol name handling as gawk.
+Alpha and Itanium should use IEEE floating point. The pointer size is 32 bits,
+and the symbol name handling is to be exact case with CRC shortening for
+symbols longer than 32 bits.
+
+Currently dynamic extensions have only been tested to work on VMS 8.3 and later
+on both Alpha and Itanium. Dynamic extensions are not currently working on
+VAX/VMS 7.3.
+
+Compile time are macros needed to be defined before the first VMS supplied
+header file is included. Usually this will be done with a config.h file.
+
+#if (__CRTL_VER >= 70200000) && !defined (__VAX)
+#define _LARGEFILE 1
+#endif
+
+#ifndef __VAX
+#ifdef __CRTL_VER
+#if __CRTL_VER >= 80200000
+#define _USE_STD_STAT 1
+#endif
+#endif
+#endif
+
+Alpha and Itanium:
+
+/name=(as_is,short)
+/float=ieee/ieee_mode=denorm_results
+
+VAX:
+
+/name=(as_is,short)
+
+The linker option files are [.vms]gawk_plugin.opt for Alpha and Itanium.
+
+As the VAX dynamic plug-in feature is not yet working, the files potentially
+needed for a future VAX plugin are in [.vms.vax] directory of the source.
+
+
+Testing GAWK on VMS:
+
+After you build gawk, you can test it with the [.vms]vmstest.com procedure.
+The procedure takes a parameter that is either for a list of tests or
+a specific test. The parameter clean cleans up files left over from running
+the tests.
+
+ $ set def [.test]
+ $ @[-.vms]vmstest.com bigtest
+ $ @[-.vms]vmstest.com clean
+ $ set def [-]
+
+To test the dynamic extensions on VMS 8.3 and later, use:
+
+ $ set def [.test]
+ $ @[-.vms]vmstest.com extension
+ $ @[-.vms]vmstest.com clean
+ $ set def [-]
Installing GAWK on VMS:
@@ -33,6 +124,11 @@ 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.
+If your gawk was installed by a PCSI kit into the GNV$GNU: directory tree,
+the program will be known as GNV$GNU:[bin]gnv$gawk.exe and the help file
+will be GNV$GNU:[vms_help]gawk.hlp. The GNV$GNU:[vms_bin]gawk_verb.cld can be
+used to add GAWK and the alias AWK to a DCL command table.
+
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
@@ -79,9 +175,52 @@ 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.
-------------------------------
-Thu Jun 18 05:22:10 IDT 2009
-============================
+ The exit status from Gawk is encoded in the the VMS $status exit
+value so that the severity bits are set as expected and the original
+Gawk exit value can be extracted.
+
+To extract the actual gawk exit code from the VMS status use:
+ unix_status = (vms_status .and. &x7f8) / 8
+
+The exit value is encoded to comply with VMS coding standards and
+will have the C_FACILITY_NO of 0x350000 with the constant 0xA000
+added to the number shifted over by 3 bits to make room for the
+severity codes.
+
+The Gawk exit value of 1 will result in the VMS status having the
+ERROR severity status set. The Gawk exit value of 2 will result in
+the FATAL severity status set. All other Gawk exit values will have
+the Success severity status set.
+
+This change was needed to provide all Gawk exit values to VMS programs and
+for compatibilty with programs written in C and the GNV environment.
+
+Older versions of Gawk incorrectly mostly passed through the Gawk
+status values instead of encoding them. DCL scripts that were checking
+the severity values will probably not need changing. DCL scripts that
+were checking the exact exit status will need an update.
+
+VAX/VMS floating point uses unbiased rounding. This is generaly incompatible
+with the expected behavior. The ofmta test in the test directory will
+fail on VAX.
+
+Gawk needs the SYS$TIMEZONE_RULE or TZ logical name to be defined or it
+will output times in GMT.
+
+The vmstest.com script needs SYS$TIMEZONE_NAME to be defined to match
+the SYS$TIMEZONE_RULE. Older versions of VMS do not define these logical
+names.
+
+TO DO Items (not in order of priority)
+
+1. Implement dynamic plug-ins on VAX.
+
+2. With the system() function, the status for DCL commands are not being
+ returned.
+
+3. Need gawk to accept logical names GNV$AWKPATH, GNV$AWKLIB, and
+ GNV$AWK_LIBARARY in addtion to the unprefixed names. This will allow
+ system wide default values to be set by an installation kit.
-On OpenVMS V7.3 (Alpha) the "manyfiles" test is known to fail. The reason
-is not (yet) known.
+4. Need to fix the gawk.cld file to not require a parameter for the options
+ that do not use the parameter.
diff --git a/README_d/README.bootstrap b/README_d/README.bootstrap
new file mode 100644
index 00000000..152bbefa
--- /dev/null
+++ b/README_d/README.bootstrap
@@ -0,0 +1,32 @@
+Tue Dec 6 21:33:19 IST 2011
+============================
+
+As documented in the mail below, if you are using a system without any
+version of awk installed, you will have bootstrapping problems (i.e., running
+configure). The solution is to install mawk or Brian Kernighan's awk
+first.
+
+Arnold Robbins
+------------------------------------
+From: Simon Josefsson <simon@josefsson.org>
+To: bug-gawk@gnu.org
+Date: Sat, 19 Nov 2011 15:24:22 +0100
+Message-ID: <87r514faw9.fsf@latte.josefsson.org>
+Subject: [bug-gawk] building gawk requires an awk?
+
+Hello,
+
+I was not able to build gawk 4.0.0 on a GNU/Hurd machine that didn't
+have any awk, the ./configure script failed at the end:
+
+config.status: creating Makefile
+./config.status: line 1169: awk: command not found
+config.status: error: could not create Makefile
+
+Is this a known bootstrapping issue? Same happened for 3.1.8. I looked
+in README but didn't find anything obvious.
+
+Btw, building 'mawk' first and then gawk 4.0.0 works. Running self
+checks didn't work because there is no 'cmp' on the system either...
+
+/Simon
diff --git a/README_d/README.cmake b/README_d/README.cmake
new file mode 100644
index 00000000..b291d1be
--- /dev/null
+++ b/README_d/README.cmake
@@ -0,0 +1,95 @@
+CMake is a build automation system
+ http://en.wikipedia.org/wiki/Cmake
+
+We try to use it as a replacement for the established GNU build system.
+This attempt is currently only experimental. If you wonder why anyone
+should do this, read
+
+ Why the KDE project switched to CMake -- and how
+ http://lwn.net/Articles/188693/
+ Escape from GNU Autohell!
+ http://www.shlomifish.org/open-source/anti/autohell
+
+- How can I get GNU Awk compiled with CMake as fast as possible ?
+ git clone git://git.savannah.gnu.org/gawk.git
+ cd gawk
+ git checkout cmake
+ mkdir build
+ cd build
+ cmake ..
+ make
+ ./gawk --version
+ make test
+Notice that this git-checkout allows you to read the source code,
+track the cmake branch and get updates. You will not be able to
+commit anything.
+
+- How can I use git to contribute source code ?
+You need an account at Savannah. Read this to understand the first steps:
+ http://savannah.gnu.org/maintenance/UsingGit
+ README.git
+Use your account there to register your public ssh key at Savannah.
+Then you are ready to checkout. Remember that (when cloning) you are
+setting up your own local repository and make sure you configure it
+properly.
+ git clone ssh://my_account_name@git.sv.gnu.org/srv/git/gawk.git
+ git config --global user.name "first-name last-name"
+ git config --global user.email First.Last@email.com
+ git config --global color.ui auto
+
+- What is the current status of the cmake branch ?
+It has just begun, pre-alpha, unclear if it will ever be taken up
+by the maintainer. We want to study if using CMake with such a
+basic tool like gawk is feasible and if it easier to use than
+the GNU build system.
+
+- Where can I find a tutorial on CMake basics ?
+Use the "official tutorial":
+ http://www.cmake.org/cmake/help/cmake_tutorial.html
+
+- Where is the reference of all commands and variables ?
+Depending on the CMake version you use, select one of these:
+ http://www.cmake.org/cmake/help/v2.8.10/cmake.html
+
+- How can I cross-compile ?
+Proceed in the same way as explained above for native compilation,
+but use a different build directory. When using CMake, do this:
+ cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain_mingw32.cmake ..
+Write a new Toolchain file for your cross-compiler and use it.
+
+- How can I build an installable file ?
+Use "make package". The exact kind of installable file depends on your
+operating system and defaults to TGZ.
+
+- Can I build an executable that runs on any Win32 platform ?
+Yes, there are two ways of doing this.
+In both cases you need a MinGW compiler and the NSIS package builder
+installed on the host that shall do the build.
+ http://sourceforge.net/projects/mingw
+ http://sourceforge.net/projects/nsis
+When installed properly, the NSIS tool can even build an installer file
+(a single .exe file that unpacks, registers and installs the gawk executable
+and several other files).
+1. way: native build on a Win32 platform
+ http://www.cmake.org/cmake/help/runningcmake.html
+ After clicking "Configure" select the MinGW option with the default native compiler
+ In the build directory, the command "mingw32-make" will build the gawk.exe
+ The command "mingw32-make package" will build installer file
+2. way: build with cross-compiler on a Linux platform like Ubuntu 12.04 LTS
+ Proceed as describe above for cross-compilers.
+ The command "make ; make package" will build gawk.exe and the installer file
+
+- How can I run test cases ?
+You can run all the test cases that are defined in test/Makefile.am.
+These test case scripts were not changed, but the way they are invoked has
+been adapted to CMake habits.
+See http://cmake.org/Wiki/CMake/Testing_With_CTest#Simple_Testing
+ cmake ..
+ make
+ make test # run all test cases
+ ctest -N # list all test cases but don't run them
+ ctest -R BASIC # run all test cases belonging to group BASIC
+ ctest -R MPFR # run all test cases belonging to group MPFR
+ ctest -E SHLIB.filefunc # run all tests, except the SHLIB.filefunc test case
+Remember that running test cases is possible only after a native build.
+
diff --git a/README_d/README.gcc-3 b/README_d/README.gcc-3
new file mode 100644
index 00000000..c76a9af7
--- /dev/null
+++ b/README_d/README.gcc-3
@@ -0,0 +1,11 @@
+Wed Apr 2 21:29:17 IDT 2014
+============================
+
+I have had a report that on a GNU/Linux system using gcc 3.3.6 (32 bit)
+that the aasort test fails. Compiling without -O builds a gawk that
+does pass all tests.
+
+Caveat Emptor.
+
+Arnold Robbins
+arnold@skeeve.com
diff --git a/README_d/README.hacking b/README_d/README.hacking
new file mode 100644
index 00000000..d179488c
--- /dev/null
+++ b/README_d/README.hacking
@@ -0,0 +1,9 @@
+* Use one of the following macros to access the value of a numeric NODE:
+ Macro Returned C type
+ ---------------------------------------
+ get_number_ui(n) unsigned long
+ get_number_si(n) long
+ get_number_d(n) double
+ get_number_uj(n) uintmax_t
+
+* Use iszero(n) to test if a numeric NODE is zero.
diff --git a/README_d/README.mpfr b/README_d/README.mpfr
new file mode 100644
index 00000000..892a22a1
--- /dev/null
+++ b/README_d/README.mpfr
@@ -0,0 +1,25 @@
+Sat Mar 17 07:32:01 CDT 2012
+=============================
+
+The MPFR and GMP versions known to work for Mac OS X on PPC:
+GNU MPFR 3.1.0, GNU MP 4.3.1
+
+----
+Precompiled binaries for GMP and MPFR in Windows may be available
+from here:
+
+ http://sourceforge.net/projects/ezwinports/files/
+
+or here:
+
+ http://sourceforge.net/projects/mingw/files/MinGW/Base/mpfr/
+ http://sourceforge.net/projects/mingw/files/MinGW/Base/gmp/
+
+You should try to use libraries downloaded from the same site
+to avoid possible incompatibilities.
+
+----
+Gawk has been compiled and tested using the following combinations
+of MPFR and GMP versions on GNU/Linux:
+GNU MPFR 2.4.2, GNU MP 4.3.2
+GNU MPFR 3.1.0, GNU MP 5.0.2, 5.0.3
diff --git a/README_d/README.pc b/README_d/README.pc
index f8addb09..63ba473e 100644
--- a/README_d/README.pc
+++ b/README_d/README.pc
@@ -10,16 +10,17 @@ DOS, and Windows32 with rsxnt), and Jan-Jaap van der Heijden and Mumit Khan
to compile and run gawk under Windows. For Cygwin, building and
installation is the same as under Unix:
- tar -xvpzf gawk-4.0.x.tar.gz
- cd gawk-4.0.x
+ tar -xvpzf gawk-4.1.x.tar.gz
+ cd gawk-4.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! *
-***************************************************************************
+******************************** N O T E *******************************
+* The `|&' operator only works when gawk is compiled for Cygwin or for *
+* MinGW. Neither socket support nor two-way pipes work in any other *
+* Windows environment! *
+************************************************************************
Building gawk
-------------
@@ -28,7 +29,8 @@ 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.
+with your make utility. If you are building with MinGW, copy the
+file Makefile.ext to extension/Makefile.
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
@@ -40,6 +42,10 @@ 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".
+For the MinGW build, after you build in the top-level directory, chdir
+to the extension subdirectory and say "make" there to build the
+extensions.
+
Testing and installing gawk
---------------------------
@@ -54,9 +60,11 @@ 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.
+used to modify test/Makefile for your platform. For starters, just
+copy pc/Makefile.tst to test/Makefile, then walk through the variables
+defined at the beginning and change them as appropriate for your
+setup. 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
diff --git a/README_d/README.solaris b/README_d/README.solaris
index 639ca2c6..91e0c701 100644
--- a/README_d/README.solaris
+++ b/README_d/README.solaris
@@ -1,20 +1,14 @@
-Fri Jul 15 14:24:00 IDT 2011
+Wed Jan 22 21:51:59 IST 2014
============================
-It looks like you need to use
- -Xc -D_XPG4_2
+On Solaris 10 x86, Solaris 11 x86, Solaris 10 sparc and Solaris 11 sparc,
+with the Sun compiler (Solaris Studio 12.3) you need to use
-on Solaris 10 with the Sun C compiler when compiling gawk in order for
-libsigsegv to be found correctly, and
+ c99 -Xc -D_XPG6
- -Xc -D_XPG4_2 -Duint64_t=upad64_t
+to correctly compile gawk and the extensions.
-on Solaris 9.
-
-Tue Apr 20 11:33:20 IDT 2010
-============================
-The lc_num1 test fails on Solaris 10 systems. This is a bug with Solaris,
-not gawk.
+Various tests can fail if the necessary locales aren't installed.
Arnold Robbins
arnold@skeeve.com
diff --git a/TODO b/TODO
index ab38248c..3670f126 100644
--- a/TODO
+++ b/TODO
@@ -1,57 +1,176 @@
-Add debugger commands to reference card
-Review all FIXME and TODO comments
+Sun Sep 28 22:19:10 IDT 2014
+============================
-FIX regular field splitting to use FPAT algorithm.
+There were too many files tracking different thoughts and ideas for
+things to do, or consider doing. This file merges them into one. As
+tasks are completed, they should be removed.
-Look at function order within files.
+This file should exist only in the master branch or branches based off
+of it for development, but not in the stable branch. This may require some
+careful work with Git.
-regex.h - remove underscores in param names (for 4.1)
+TODO
+====
-Really make failure to open a socket a non-fatal error (for 4.1).
+Minor Cleanups and Code Improvements
+------------------------------------
-?? Scope IDs for IPv6 addresses ??
+ Review the bash source script for working with shared libraries in
+ order to nuke the use of libtool. [ Partially started in the
+ nolibtool branch. ]
-------
+ API:
+ ??? #if !defined(GAWK) && !defined(GAWK_OMIT_CONVENIENCE_MACROS)
-Code Review:
-awkgram.y
-awkprintf.h
-cmd.h
-command.y
-debug.c
-eval.c
-ext.c
-field.c
-floatcomp.c
-floatmagic.h
-gawkmisc.c
-io.c
-profile.c
-protos.h
+ ?? Add debugger commands to reference card
-DONE:
-awk.h
-array.c
-builtin.c
-node.c
-mbsupport.h
-xalloc.h
-version.c
-re.c
-replace.c
-msg.c
-hard-locale.h
-custom.h
-main.c
+ Look at function order within files.
-------
+ Consider removing use of and/or need for the protos.h file.
-Add in gawk/mp
+ Recheck if gnulib regex can be dropped in
-Design and implement I/O plugin API.
+ Fully synchronize whitespace tests (for \s, \S in Unicode
+ environment) with those of GNU grep.
-Implement C function call API per man pages
+Minor New Features
+------------------
-xgawk features (@load, -l, others)
+ Enable command line source text in the debugger.
-Add tests for patches in emails
+ Enhance extension/fork.c waitpid to allow the caller to specify
+ the options. And add an optional array argument to wait and
+ waitpid in which to return exit status information.
+
+ Consider relaxing the strictness of --posix.
+
+ Make it possible to put print/printf + redirections into
+ an expression.
+
+ ? Add an optional base to strtonum, allowing 2-36.
+
+ ? Optional third argument for index indicating where to start the
+ search.
+
+Major New Features
+------------------
+
+ Think about how to generalize indirect access. Manuel Collado
+ suggests things like
+
+ foo = 5
+ @"foo" += 4
+
+ Also needed:
+
+ Indirect through array elements, not just scalar variables
+
+ Some way to make regexp constants first class citizens:
+ - Assign to variables
+ - Pass to functions
+ Tawk has this and it would also make indirect calling of builtins
+ work more reasonably. Probably would use a special syntax like
+ @/.../ for such objects.
+
+ Consider a typeof() function that returns a string (scalar, array,
+ regexp).
+
+ Add ability to do decimal arithmetic.
+
+ Rework management of array index storage. (Partially DONE.)
+
+ Consider using an atom table for all string array indices.
+
+ DBM storage of awk arrays. Try to allow multiple dbm packages.
+
+ ?? A RECLEN variable for fixed-length record input. PROCINFO["RS"]
+ would be "RS" or "RECLEN" depending upon what's in use.
+ *** Could this be done as an extension?
+
+ ?? Use a new or improved dfa and/or regex library.
+
+ Rewrite in C++.
+
+Things To Think About That May Never Happen
+-------------------------------------------
+
+ Consider making shadowed variables a warning and not
+ a fatal warning when --lint=fatal.
+
+ Similar for extra parameters in a function call.
+
+ Look at code coverage tools, like S2E: https://s2e.epfl.ch/
+
+ Try running with diehard. See http://www.diehard-software.org,
+ https://github.com/emeryberger/DieHard
+
+ Implement namespaces. Arnold suggested the following in an email:
+ - Extend the definition of an 'identifier' to include "." as a valid
+ character although an identifier can't start with it.
+ - Extension libraries install functions and global variables with names
+ that have a "." in them: XML.parse(), XML.name, whatever.
+ - Awk code can read/write such variables and call such functions,
+ but they cannot define such functions
+ function XML.foo() { .. } # error
+ or create a variable with such a name if it doesn't exist. This would
+ be a run-time error, not a parse-time error.
+ - This last rule may be too restrictive.
+ I don't want to get into fancy rules a la perl and file-scope visibility
+ etc, I'd like to keep things simple. But how we design this is going
+ to be very important.
+
+ Include a sample rpm spec file in a new packaging subdirectory.
+ (Really needed?)
+
+ Patch lexer for @include and @load to make quotes optional.
+ (Really needed?)
+
+ Add a lint check if the return value of a function is used but
+ the function did not supply a value.
+
+ Consider making gawk output +nan for NaN values so that it
+ will accept its own output as input.
+ NOTE: Investigated this. GLIBC formats NaN as '-nan'
+ and -NaN as 'nan'. Dealing with this is not simple.
+
+ Enhance FIELDWIDTHS with some way to indicate "the rest of the record".
+ E.g., a length of 0 or -1 or something. Maybe "n"?
+
+
+Things That We Decided We Will Never Do
+=======================================
+
+ Consider moving var_value info into Node_var itself to reduce
+ memory usage. This would break all uses of get_lhs in the
+ code. It's too sweeping a change.
+
+ Add macros for working with flags instead of using & and |
+ directly.
+
+ FIX regular field splitting to use FPAT algorithm.
+ Note: Looked at this. Not sure it's with the trouble:
+ If it ain't broke...
+
+ Scope IDs for IPv6 addresses
+
+ Gnulib
+
+ Make FIELDWIDTHS be an array?
+
+ "Do an optimization pass over parse tree?"
+ This isn't relevant now that we are using a byte code engine.
+
+ "Consider integrating Fred Fish's DBUG library into gawk."
+ I did this once as an experiment. But I don't see a lot of value
+ to this at this stage of the development. Stepping through things
+ in a debugger is generally enough. Also, I would have to try to
+ track down the latest version of this.
+
+ "Make awk '/foo/' files... run at egrep speeds (how?)"
+ This has been on the list since the early days (gawk 1.x or early
+ 2.x). But I am not sure how to really do this, nor have I done
+ timings, nor does there seem to be any real demand for this.
+
+ Change from dlopen to using the libltdl library (i.e. lt_dlopen).
+ This may support more platforms. If we move off of libtool
+ then this is the wrong direction.
diff --git a/aclocal.m4 b/aclocal.m4
index 742da619..8907206b 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,7 +1,7 @@
-# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2007, 2008, 2009 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.
@@ -11,15 +11,16 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],,
-[m4_warning([this file was generated for autoconf 2.68.
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
-To do so, use the procedure documented by the package, typically `autoreconf'.])])
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
-# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -31,10 +32,10 @@ To do so, use the procedure documented by the package, typically `autoreconf'.])
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.11'
+[am__api_version='1.14'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.11.1], [],
+m4_if([$1], [1.14.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -50,22 +51,22 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11.1])dnl
+[AM_AUTOMAKE_VERSION([1.14.1])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 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/../..'.
+# $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
@@ -84,7 +85,7 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
#
# 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
+# 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,
@@ -110,22 +111,19 @@ am_aux_dir=`cd $ac_aux_dir && pwd`
# AM_CONDITIONAL -*- Autoconf -*-
-# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 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 9
-
# 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_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
AC_SUBST([$1_TRUE])dnl
AC_SUBST([$1_FALSE])dnl
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
@@ -144,16 +142,14 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
-# Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 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 10
-# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# 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
@@ -163,7 +159,7 @@ fi])])
# _AM_DEPENDENCIES(NAME)
# ----------------------
# See how the compiler implements dependency checking.
-# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
# 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
@@ -176,12 +172,13 @@ 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], UPC, [depcc="$UPC" am_compiler_list=],
- [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
- [depcc="$$1" am_compiler_list=])
+m4_if([$1], [CC], [depcc="$CC" am_compiler_list=],
+ [$1], [CXX], [depcc="$CXX" am_compiler_list=],
+ [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+ [$1], [UPC], [depcc="$UPC" am_compiler_list=],
+ [$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],
@@ -189,8 +186,9 @@ AC_CACHE_CHECK([dependency style of $depcc],
# 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'.
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
@@ -229,16 +227,16 @@ AC_CACHE_CHECK([dependency style of $depcc],
: > 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
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
done
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # 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. Also, some Intel
- # versions had trouble with output in subdirs
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
am__obj=sub/conftest.${OBJEXT-o}
am__minus_obj="-o $am__obj"
case $depmode in
@@ -247,16 +245,16 @@ AC_CACHE_CHECK([dependency style of $depcc],
test "$am__universal" = false || continue
;;
nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
+ # 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
;;
- msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
am__obj=conftest.${OBJEXT-o}
@@ -304,7 +302,7 @@ AM_CONDITIONAL([am__fastdep$1], [
# AM_SET_DEPDIR
# -------------
# Choose a directory name for dependency files.
-# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+# 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
@@ -314,34 +312,39 @@ 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])
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+ [--enable-dependency-tracking],
+ [do not reject slow dependency extractors])
+AS_HELP_STRING(
+ [--disable-dependency-tracking],
+ [speeds up one-time build])])
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
+ am__nodep='_no'
fi
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
AC_SUBST([AMDEPBACKSLASH])dnl
_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
])
# Generate code to set up dependency tracking. -*- Autoconf -*-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 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 5
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
[{
- # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # Older Autoconf quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting.
case $CONFIG_FILES in
@@ -354,7 +357,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
# 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
+ # 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.
@@ -366,21 +369,19 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
continue
fi
# Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running `make'.
+ # 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
+ 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
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`AS_DIRNAME(["$file"])`
@@ -398,7 +399,7 @@ AC_DEFUN([_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
+# 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],
@@ -408,18 +409,21 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# Do all the work for Automake. -*- Autoconf -*-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 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 16
-
# 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.
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
# -----------------------------------------------
@@ -432,7 +436,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# 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.62])dnl
+[AC_PREREQ([2.65])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
@@ -461,31 +465,40 @@ 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_DIAGNOSE([obsolete],
+ [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
AC_SUBST([PACKAGE], [$1])dnl
AC_SUBST([VERSION], [$2])],
[_AM_SET_OPTIONS([$1])dnl
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
-m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+m4_if(
+ m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+ [ok:ok],,
[m4_fatal([AC_INIT should be called with package and version arguments])])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
+[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_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])
AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
-AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
@@ -496,34 +509,78 @@ _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
[_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
+ [_AM_DEPENDENCIES([CC])],
+ [m4_define([AC_PROG_CC],
+ m4_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
+ [_AM_DEPENDENCIES([CXX])],
+ [m4_define([AC_PROG_CXX],
+ m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
AC_PROVIDE_IFELSE([AC_PROG_OBJC],
- [_AM_DEPENDENCIES(OBJC)],
- [define([AC_PROG_OBJC],
- defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+ [_AM_DEPENDENCIES([OBJC])],
+ [m4_define([AC_PROG_OBJC],
+ m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+ [_AM_DEPENDENCIES([OBJCXX])],
+ [m4_define([AC_PROG_OBJCXX],
+ m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
])
-_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
-dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
-dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
-dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
AC_CONFIG_COMMANDS_PRE(dnl
[m4_provide_if([_AM_COMPILER_EXEEXT],
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
-])
-dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+ fi
+fi])
+
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
dnl mangled by Autoconf and run in a shell conditional statement.
m4_define([_AC_COMPILER_EXEEXT],
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
-
# 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.
@@ -545,7 +602,7 @@ for _am_header in $config_headers :; do
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -564,16 +621,14 @@ if test x"${install_sh}" != xset; then
install_sh="\${SHELL} $am_aux_dir/install-sh"
esac
fi
-AC_SUBST(install_sh)])
+AC_SUBST([install_sh])])
-# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+# Copyright (C) 2003-2013 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],
@@ -589,14 +644,12 @@ AC_SUBST([am__leading_dot])])
# Check to see how 'make' treats includes. -*- Autoconf -*-
-# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 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_MAKE_INCLUDE()
# -----------------
# Check to see how make treats includes.
@@ -614,7 +667,7 @@ am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
+# Ignore all kinds of additional output from 'make'.
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=include
@@ -641,15 +694,12 @@ rm -f confinc confmf
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 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 6
-
# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
AC_DEFUN([AM_MISSING_PROG],
@@ -657,11 +707,10 @@ AC_DEFUN([AM_MISSING_PROG],
$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.
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
AC_REQUIRE_AUX_FILE([missing])dnl
@@ -674,63 +723,35 @@ if test x"${MISSING+set}" != xset; then
esac
fi
# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
else
am_missing_run=
- AC_MSG_WARN([`missing' script is too old or missing])
+ AC_MSG_WARN(['missing' script is too old or missing])
fi
])
-# Copyright (C) 2003, 2004, 2005, 2006 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 for `mkdir -p'.
-AC_DEFUN([AM_PROG_MKDIR_P],
-[AC_PREREQ([2.60])dnl
-AC_REQUIRE([AC_PROG_MKDIR_P])dnl
-dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
-dnl while keeping a definition of mkdir_p for backward compatibility.
-dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
-dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
-dnl Makefile.ins that do not define MKDIR_P, so we do our own
-dnl adjustment using top_builddir (which is defined more often than
-dnl MKDIR_P).
-AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
-case $mkdir_p in
- [[\\/$]]* | ?:[[\\/]]*) ;;
- */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-])
-
# Helper functions for option handling. -*- Autoconf -*-
-# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 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_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)])
+[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],
[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
@@ -741,24 +762,82 @@ AC_DEFUN([_AM_SET_OPTIONS],
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-# Check to make sure that the build environment is sane. -*- Autoconf -*-
+# Copyright (C) 1999-2013 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_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+ [whether $CC understands -c and -o together],
+ [am_cv_prog_cc_c_o],
+ [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
-# Free Software Foundation, Inc.
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 2001-2013 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 5
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+ ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ (exit $ac_status); }])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 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_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
[AC_MSG_CHECKING([whether build environment is sane])
-# Just in case
-sleep 1
-echo timestamp > conftest.file
# Reject unsafe characters in $srcdir or the absolute working directory
# name. Accept space and tab only in the latter.
am_lf='
@@ -769,32 +848,40 @@ case `pwd` in
esac
case $srcdir in
*[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
- AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+ AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
esac
-# Do `set' in a subshell so we don't clobber the current shell's
+# 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
-
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ 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
+ 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
+ if test "$[2]" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
test "$[2]" = conftest.file
)
then
@@ -804,9 +891,85 @@ else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
-AC_MSG_RESULT(yes)])
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+ [AC_MSG_CHECKING([that generated files are newer than configure])
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2013 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_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+ [--enable-silent-rules],
+ [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+ [--disable-silent-rules],
+ [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+ [am_cv_make_support_nested_variables],
+ [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+ dnl Using '$V' instead of '$(V)' breaks IRIX make.
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -814,34 +977,32 @@ AC_MSG_RESULT(yes)])
# AM_PROG_INSTALL_STRIP
# ---------------------
-# One issue with vendor `install' (even GNU) is that you can't
+# 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
+# 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
+# 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'.
+# 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="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
-# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2006-2013 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_SUBST_NOTMAKE(VARIABLE)
# ---------------------------
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
@@ -849,24 +1010,22 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])])
AC_DEFUN([_AM_SUBST_NOTMAKE])
# AM_SUBST_NOTMAKE(VARIABLE)
-# ---------------------------
+# --------------------------
# Public sister of _AM_SUBST_NOTMAKE.
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
-# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+# Copyright (C) 2004-2013 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'.
+# 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
@@ -876,75 +1035,114 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# 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.
+[# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll 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
+m4_if([$1], [v7],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+ [m4_case([$1],
+ [ustar],
+ [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+ # There is notably a 21 bits limit for the UID and the GID. In fact,
+ # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+ # and bug#13588).
+ am_max_uid=2097151 # 2^21 - 1
+ am_max_gid=$am_max_uid
+ # The $UID and $GID variables are not portable, so we need to resort
+ # to the POSIX-mandated id(1) utility. Errors in the 'id' calls
+ # below are definitely unexpected, so allow the users to see them
+ # (that is, avoid stderr redirection).
+ am_uid=`id -u || echo unknown`
+ am_gid=`id -g || echo unknown`
+ AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+ if test $am_uid -le $am_max_uid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi
+ AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+ if test $am_gid -le $am_max_gid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi],
+
+ [pax],
+ [],
+
+ [m4_fatal([Unknown tar format])])
+
+ AC_MSG_CHECKING([how to create a $1 tar archive])
+
+ # Go ahead even if we have the value already cached. We do so because we
+ # need to set the values for the 'am__tar' and 'am__untar' variables.
+ _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+ 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
- # 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])
+ # 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])
+ AM_RUN_LOG([cat conftest.dir/file])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+ done
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_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
@@ -954,8 +1152,6 @@ m4_include([m4/codeset.m4])
m4_include([m4/gettext.m4])
m4_include([m4/iconv.m4])
m4_include([m4/intlmacosx.m4])
-m4_include([m4/intmax_t.m4])
-m4_include([m4/inttypes_h.m4])
m4_include([m4/isc-posix.m4])
m4_include([m4/lcmessage.m4])
m4_include([m4/lib-ld.m4])
@@ -963,11 +1159,11 @@ m4_include([m4/lib-link.m4])
m4_include([m4/lib-prefix.m4])
m4_include([m4/libsigsegv.m4])
m4_include([m4/longlong.m4])
+m4_include([m4/mpfr.m4])
m4_include([m4/nls.m4])
+m4_include([m4/noreturn.m4])
m4_include([m4/po.m4])
m4_include([m4/progtest.m4])
m4_include([m4/readline.m4])
m4_include([m4/socket.m4])
-m4_include([m4/stdint_h.m4])
-m4_include([m4/uintmax_t.m4])
m4_include([m4/ulonglong.m4])
diff --git a/array.c b/array.c
index 2a89a606..f7993624 100644
--- a/array.c
+++ b/array.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-2011 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-2014 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -27,47 +27,49 @@
extern FILE *output_fp;
extern NODE **fmt_list; /* declared in eval.c */
-extern array_ptr str_array_func[];
-extern array_ptr cint_array_func[];
-extern array_ptr int_array_func[];
static size_t SUBSEPlen;
static char *SUBSEP;
static char indent_char[] = " ";
-static NODE **e_lookup(NODE *symbol, NODE *subs);
-static array_ptr empty_array_func[NUM_AFUNCS] = {
- (array_ptr) 0,
- (array_ptr) 0,
- e_lookup,
+static NODE **null_lookup(NODE *symbol, NODE *subs);
+static NODE **null_dump(NODE *symbol, NODE *subs);
+static afunc_t null_array_func[] = {
+ (afunc_t) 0,
+ (afunc_t) 0,
+ null_length,
+ null_lookup,
+ null_afunc,
+ null_afunc,
+ null_afunc,
+ null_afunc,
+ null_afunc,
+ null_dump,
+ (afunc_t) 0,
};
#define MAX_ATYPE 10
-static array_ptr *atypes[MAX_ATYPE];
-static int num_atypes = 0;
+static afunc_t *array_types[MAX_ATYPE];
+static int num_array_types = 0;
-/*
- * register_array_func --- add routines to handle arrays.
- *
- * index 0 : initialization.
- * index 1 : check if index is compatible.
- * index 8 : array dump, memory and other statistics (do_adump).
- */
-
+/* array func to index mapping */
+#define AFUNC(F) (F ## _ind)
+
+/* register_array_func --- add routines to handle arrays */
int
-register_array_func(array_ptr *afunc)
+register_array_func(afunc_t *afunc)
{
- if (afunc && num_atypes < MAX_ATYPE) {
- if (afunc != str_array_func && ! afunc[1])
- return FALSE;
- atypes[num_atypes++] = afunc;
- if (afunc[0]) /* execute init routine if any */
- (void) (*afunc[0])(NULL, NULL);
- return TRUE;
+ if (afunc && num_array_types < MAX_ATYPE) {
+ if (afunc != str_array_func && ! afunc[AFUNC(atypeof)])
+ return false;
+ array_types[num_array_types++] = afunc;
+ if (afunc[AFUNC(ainit)]) /* execute init routine if any */
+ (void) (*afunc[AFUNC(ainit)])(NULL, NULL);
+ return true;
}
- return FALSE;
+ return false;
}
@@ -77,8 +79,10 @@ void
array_init()
{
(void) register_array_func(str_array_func); /* the default */
- (void) register_array_func(int_array_func);
- (void) register_array_func(cint_array_func);
+ if (! do_mpfr) {
+ (void) register_array_func(int_array_func);
+ (void) register_array_func(cint_array_func);
+ }
}
@@ -91,92 +95,83 @@ make_array()
getnode(array);
memset(array, '\0', sizeof(NODE));
array->type = Node_var_array;
- array->array_funcs = empty_array_func;
+ array->array_funcs = null_array_func;
/* vname, flags, and parent_array not set here */
return array;
}
-/* init_array --- initialize an array node */
+/* null_array --- force symbol to be an empty typeless array */
void
-init_array(NODE *symbol)
+null_array(NODE *symbol)
{
symbol->type = Node_var_array;
- symbol->array_funcs = empty_array_func;
+ symbol->array_funcs = null_array_func;
symbol->buckets = NULL;
symbol->table_size = symbol->array_size = 0;
symbol->array_capacity = 0;
+ symbol->flags = 0;
assert(symbol->xarray == NULL);
- /* symbol->xarray = NULL; */
- /* flags, vname, parent_array not (re)initialized */
+ /* vname, parent_array not (re)initialized */
}
-/* e_lookup: assign type to an empty array. */
+/* null_lookup --- assign type to an empty array. */
static NODE **
-e_lookup(NODE *symbol, NODE *subs)
+null_lookup(NODE *symbol, NODE *subs)
{
int i;
- array_ptr *afunc = NULL;
+ afunc_t *afunc = NULL;
- assert(array_empty(symbol) == TRUE);
+ assert(symbol->table_size == 0);
- /* Check which array type wants to accept this sub; traverse
+ /*
+ * Check which array type wants to accept this sub; traverse
* array type list in reverse order.
*/
- for (i = num_atypes - 1; i >= 1; i--) {
- afunc = atypes[i];
- if (afunc[1](symbol, subs) != NULL)
+ for (i = num_array_types - 1; i >= 1; i--) {
+ afunc = array_types[i];
+ if (afunc[AFUNC(atypeof)](symbol, subs) != NULL)
break;
}
if (i == 0 || afunc == NULL)
- afunc = atypes[0]; /* default is str_array_func */
+ afunc = array_types[0]; /* default is str_array_func */
symbol->array_funcs = afunc;
/* We have the right type of array; install the subscript */
return symbol->alookup(symbol, subs);
}
+/* null_length --- default function for array length interface */
-/* assoc_clear --- flush all the values in symbol[] */
-
-void
-assoc_clear(NODE *symbol)
+NODE **
+null_length(NODE *symbol, NODE *subs ATTRIBUTE_UNUSED)
{
- if (! array_empty(symbol))
- (void) symbol->aclear(symbol, NULL);
+ static NODE *tmp;
+ tmp = symbol;
+ return & tmp;
}
+/* null_afunc --- default function for array interface */
-/* r_in_array --- test whether the array element symbol[subs] exists or not,
- * return pointer to value if it does.
- */
-
-NODE *
-r_in_array(NODE *symbol, NODE *subs)
+NODE **
+null_afunc(NODE *symbol ATTRIBUTE_UNUSED, NODE *subs ATTRIBUTE_UNUSED)
{
- NODE **ret;
-
- if (array_empty(symbol))
- return NULL;
- ret = symbol->aexists(symbol, subs);
- return (ret ? *ret : NULL);
+ return NULL;
}
+/* null_dump --- dump function for an empty array */
-/* assoc_remove --- remove an index from symbol[] */
-
-int
-assoc_remove(NODE *symbol, NODE *subs)
+static NODE **
+null_dump(NODE *symbol, NODE *subs ATTRIBUTE_UNUSED)
{
- if (array_empty(symbol))
- return FALSE;
- return (symbol->aremove(symbol, subs) != NULL);
+ fprintf(output_fp, "array `%s' is empty\n", array_vname(symbol));
+ return NULL;
}
@@ -188,11 +183,9 @@ assoc_copy(NODE *symbol, NODE *newsymb)
assert(newsymb->vname != NULL);
assoc_clear(newsymb);
- if (! array_empty(symbol)) {
- (void) symbol->acopy(symbol, newsymb);
- newsymb->array_funcs = symbol->array_funcs;
- newsymb->flags = symbol->flags;
- }
+ (void) symbol->acopy(symbol, newsymb);
+ newsymb->array_funcs = symbol->array_funcs;
+ newsymb->flags = symbol->flags;
return newsymb;
}
@@ -202,9 +195,7 @@ assoc_copy(NODE *symbol, NODE *newsymb)
void
assoc_dump(NODE *symbol, NODE *ndump)
{
- if (array_empty(symbol))
- fprintf(output_fp, "array `%s' is empty\n", array_vname(symbol));
- else if (symbol->adump)
+ if (symbol->adump)
(void) symbol->adump(symbol, ndump);
}
@@ -330,28 +321,29 @@ array_vname(const NODE *symbol)
/*
- * get_array --- proceed to the actual Node_var_array,
+ * force_array --- 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_array(NODE *symbol, int canfatal)
+force_array(NODE *symbol, bool canfatal)
{
NODE *save_symbol = symbol;
- int isparam = FALSE;
+ bool isparam = false;
if (symbol->type == Node_param_list) {
save_symbol = symbol = GET_PARAM(symbol->param_cnt);
- isparam = TRUE;
+ isparam = true;
if (symbol->type == Node_array_ref)
symbol = symbol->orig_array;
}
switch (symbol->type) {
case Node_var_new:
- init_array(symbol);
+ symbol->xarray = NULL; /* make sure union is as it should be */
+ null_array(symbol);
symbol->parent_array = NULL; /* main array has no parent */
/* fall through */
case Node_var_array:
@@ -391,9 +383,9 @@ set_SUBSEP()
/* concat_exp --- concatenate expression list into a single string */
NODE *
-concat_exp(int nargs, int do_subsep)
+concat_exp(int nargs, bool do_subsep)
{
- /* do_subsep is FALSE for Op_concat */
+ /* do_subsep is false for Op_concat */
NODE *r;
char *str;
char *s;
@@ -445,7 +437,8 @@ concat_exp(int nargs, int do_subsep)
}
-/* adjust_fcall_stack: remove subarray(s) of symbol[] from
+/*
+ * adjust_fcall_stack: remove subarray(s) of symbol[] from
* function call stack.
*/
@@ -493,7 +486,8 @@ adjust_fcall_stack(NODE *symbol, int nsubs)
&& symbol->parent_array != NULL
&& nsubs > 0
) {
- /* 'symbol' is a subarray, and 'r' is the same subarray:
+ /*
+ * 'symbol' is a subarray, and 'r' is the same subarray:
*
* function f(c, d) { delete c[0]; .. }
* BEGIN { a[0][0] = 1; f(a, a[0]); .. }
@@ -504,9 +498,8 @@ adjust_fcall_stack(NODE *symbol, int nsubs)
* BEGIN { a[0][0] = 1; f(a[0], a[0]); ...}
*/
- init_array(r);
+ null_array(r);
r->parent_array = NULL;
- r->flags = 0;
continue;
}
@@ -514,7 +507,8 @@ adjust_fcall_stack(NODE *symbol, int nsubs)
for (n = n->parent_array; n != NULL; n = n->parent_array) {
assert(n->type == Node_var_array);
if (n == symbol) {
- /* 'r' is a subarray of 'symbol':
+ /*
+ * 'r' is a subarray of 'symbol':
*
* function f(c, d) { delete c; .. use d as array .. }
* BEGIN { a[0][0] = 1; f(a, a[0]); .. }
@@ -522,9 +516,8 @@ adjust_fcall_stack(NODE *symbol, int nsubs)
* BEGIN { a[0][0][0][0] = 1; f(a[0], a[0][0][0]); .. }
*
*/
- init_array(r);
+ null_array(r);
r->parent_array = NULL;
- r->flags = 0;
break;
}
}
@@ -639,14 +632,13 @@ void
do_delete_loop(NODE *symbol, NODE **lhs)
{
NODE **list;
- NODE fl;
+ NODE akind;
- if (array_empty(symbol))
- return;
+ akind.flags = AINDEX|ADELETE; /* need a single index */
+ list = symbol->alist(symbol, & akind);
- fl.flags = AINDEX|ADELETE; /* need a single index */
- list = symbol->alist(symbol, & fl);
- assert(list != NULL);
+ if (assoc_empty(symbol))
+ return;
unref(*lhs);
*lhs = list[0];
@@ -660,7 +652,6 @@ do_delete_loop(NODE *symbol, NODE **lhs)
/* value_info --- print scalar node info */
-
static void
value_info(NODE *n)
{
@@ -676,11 +667,29 @@ value_info(NODE *n)
if ((n->flags & (STRING|STRCUR)) != 0) {
fprintf(output_fp, "<");
fprintf(output_fp, "\"%.*s\"", PREC_STR, n->stptr);
- if ((n->flags & (NUMBER|NUMCUR)) != 0)
+ if ((n->flags & (NUMBER|NUMCUR)) != 0) {
+#ifdef HAVE_MPFR
+ if (is_mpg_float(n))
+ fprintf(output_fp, ":%s",
+ mpg_fmt("%.*R*g", PREC_NUM, ROUND_MODE, n->mpg_numbr));
+ else if (is_mpg_integer(n))
+ fprintf(output_fp, ":%s", mpg_fmt("%Zd", n->mpg_i));
+ else
+#endif
fprintf(output_fp, ":%.*g", PREC_NUM, n->numbr);
+ }
fprintf(output_fp, ">");
- } else
+ } else {
+#ifdef HAVE_MPFR
+ if (is_mpg_float(n))
+ fprintf(output_fp, "<%s>",
+ mpg_fmt("%.*R*g", PREC_NUM, ROUND_MODE, n->mpg_numbr));
+ else if (is_mpg_integer(n))
+ fprintf(output_fp, "<%s>", mpg_fmt("%Zd", n->mpg_i));
+ else
+#endif
fprintf(output_fp, "<%.*g>", PREC_NUM, n->numbr);
+ }
fprintf(output_fp, ":%s", flags2str(n->flags));
@@ -701,32 +710,6 @@ value_info(NODE *n)
}
-#ifdef ARRAYDEBUG
-
-NODE *
-do_aoption(int nargs)
-{
- int ret = -1;
- NODE *opt, *val;
- int i;
- array_ptr *afunc;
-
- val = POP_SCALAR();
- opt = POP_SCALAR();
- for (i = 0; i < num_atypes; i++) {
- afunc = atypes[i];
- if (afunc[NUM_AFUNCS] && (*afunc[NUM_AFUNCS])(opt, val) != NULL) {
- ret = 0;
- break;
- }
- }
- DEREF(opt);
- DEREF(val);
- return make_number((AWKNUM) ret);
-}
-
-#endif
-
void
indent(int indent_level)
{
@@ -745,7 +728,7 @@ assoc_info(NODE *subs, NODE *val, NODE *ndump, const char *aname)
indent_level++;
indent(indent_level);
fprintf(output_fp, "I: [%s:", aname);
- if ((subs->flags & INTIND) != 0)
+ if ((subs->flags & (MPFN|MPZN|INTIND)) == INTIND)
fprintf(output_fp, "<%ld>", (long) subs->numbr);
else
value_info(subs);
@@ -777,14 +760,15 @@ do_adump(int nargs)
static NODE ndump;
long depth = 0;
- /* depth < 0, no index and value info.
+ /*
+ * depth < 0, no index and value info.
* = 0, main array index and value info; does not descend into sub-arrays.
* > 0, descends into 'depth' sub-arrays, and prints index and value info.
*/
if (nargs == 2) {
- tmp = POP_SCALAR();
- depth = (long) force_number(tmp);
+ tmp = POP_NUMBER();
+ depth = get_number_si(tmp);
DEREF(tmp);
}
symbol = POP_PARAM();
@@ -802,11 +786,11 @@ do_adump(int nargs)
/* asort_actual --- do the actual work to sort the input array */
static NODE *
-asort_actual(int nargs, SORT_CTXT ctxt)
+asort_actual(int nargs, sort_context_t ctxt)
{
NODE *array, *dest = NULL, *result;
NODE *r, *subs, *s;
- NODE **list, **ptr;
+ NODE **list = NULL, **ptr, **lhs;
unsigned long num_elems, i;
const char *sort_str;
@@ -855,18 +839,20 @@ asort_actual(int nargs, SORT_CTXT ctxt)
}
}
- if (array_empty(array)) {
- /* source array is empty */
- if (dest != NULL && dest != array)
- assoc_clear(dest);
- return make_number((AWKNUM) 0);
- }
- num_elems = array->table_size;
-
/* sorting happens inside assoc_list */
list = assoc_list(array, sort_str, ctxt);
DEREF(s);
+ num_elems = assoc_length(array);
+ if (num_elems == 0 || list == NULL) {
+ /* source array is empty */
+ if (dest != NULL && dest != array)
+ assoc_clear(dest);
+ if (list != NULL)
+ efree(list);
+ return make_number((AWKNUM) 0);
+ }
+
/*
* Must not assoc_clear() the source array before constructing
* the output array. assoc_list() does not duplicate array values
@@ -883,21 +869,23 @@ asort_actual(int nargs, SORT_CTXT ctxt)
result->parent_array = array->parent_array;
}
- subs = make_number((AWKNUM) 0.0);
-
if (ctxt == ASORTI) {
/* We want the indices of the source array. */
for (i = 1, ptr = list; i <= num_elems; i++, ptr += 2) {
- subs->numbr = (AWKNUM) i;
- r = *ptr;
- *assoc_lookup(result, subs) = r;
+ subs = make_number(i);
+ lhs = assoc_lookup(result, subs);
+ unref(*lhs);
+ *lhs = *ptr;
+ if (result->astore != NULL)
+ (*result->astore)(result, subs);
+ unref(subs);
}
} else {
/* We want the values of the source array. */
for (i = 1, ptr = list; i <= num_elems; i++) {
- subs->numbr = (AWKNUM) i;
+ subs = make_number(i);
/* free index node */
r = *ptr++;
@@ -906,11 +894,11 @@ asort_actual(int nargs, SORT_CTXT ctxt)
/* value node */
r = *ptr++;
- /* FIXME: asort(a) optimization */
-
- if (r->type == Node_val)
- *assoc_lookup(result, subs) = dupnode(r);
- else {
+ if (r->type == Node_val) {
+ lhs = assoc_lookup(result, subs);
+ unref(*lhs);
+ *lhs = dupnode(r);
+ } else {
NODE *arr;
arr = make_array();
subs = force_string(subs);
@@ -918,12 +906,16 @@ asort_actual(int nargs, SORT_CTXT ctxt)
subs->stptr = NULL;
subs->flags &= ~STRCUR;
arr->parent_array = array; /* actual parent, not the temporary one. */
- *assoc_lookup(result, subs) = assoc_copy(r, arr);
+ lhs = assoc_lookup(result, subs);
+ unref(*lhs);
+ *lhs = assoc_copy(r, arr);
}
+ if (result->astore != NULL)
+ (*result->astore)(result, subs);
+ unref(subs);
}
}
- unref(subs);
efree(list);
if (result != dest) {
@@ -956,13 +948,13 @@ do_asorti(int nargs)
/*
- * cmp_string --- compare two strings; logic similar to cmp_nodes() in eval.c
+ * cmp_strings --- compare two strings; logic similar to cmp_nodes() in eval.c
* except the extra case-sensitive comparison when the case-insensitive
* result is a match.
*/
static int
-cmp_string(const NODE *n1, const NODE *n2)
+cmp_strings(const NODE *n1, const NODE *n2)
{
char *s1, *s2;
size_t len1, len2;
@@ -986,14 +978,13 @@ cmp_string(const NODE *n1, const NODE *n2)
const unsigned char *cp1 = (const unsigned char *) s1;
const unsigned char *cp2 = (const unsigned char *) s2;
-#if MBS_SUPPORT
if (gawk_mb_cur_max > 1) {
ret = strncasecmpmbs((const unsigned char *) cp1,
(const unsigned char *) cp2, lmin);
- } else
-#endif
- for (ret = 0; lmin-- > 0 && ret == 0; cp1++, cp2++)
- ret = casetable[*cp1] - casetable[*cp2];
+ } else {
+ for (ret = 0; lmin-- > 0 && ret == 0; cp1++, cp2++)
+ ret = casetable[*cp1] - casetable[*cp2];
+ }
if (ret != 0)
return ret;
/*
@@ -1008,7 +999,6 @@ cmp_string(const NODE *n1, const NODE *n2)
return (len1 < len2) ? -1 : 1;
}
-
/* sort_up_index_string --- qsort comparison function; ascending index strings. */
static int
@@ -1019,7 +1009,7 @@ sort_up_index_string(const void *p1, const void *p2)
/* Array indices are strings */
t1 = *((const NODE *const *) p1);
t2 = *((const NODE *const *) p2);
- return cmp_string(t1, t2);
+ return cmp_strings(t1, t2);
}
@@ -1052,15 +1042,14 @@ sort_up_index_number(const void *p1, const void *p2)
t1 = *((const NODE *const *) p1);
t2 = *((const NODE *const *) p2);
- if (t1->numbr < t2->numbr)
- ret = -1;
- else
- ret = (t1->numbr > t2->numbr);
+ ret = cmp_numbers(t1, t2);
+ if (ret != 0)
+ return ret;
/* break a tie with the index string itself */
- if (ret == 0)
- return cmp_string(t1, t2);
- return ret;
+ t1 = force_string((NODE *) t1);
+ t2 = force_string((NODE *) t2);
+ return cmp_strings(t1, t2);
}
/* sort_down_index_number --- qsort comparison function; descending index numbers */
@@ -1090,7 +1079,7 @@ sort_up_value_string(const void *p1, const void *p2)
return -1; /* t1 (scalar) < t2 (sub-array) */
/* t1 and t2 both have string values */
- return cmp_string(t1, t2);
+ return cmp_strings(t1, t2);
}
@@ -1121,23 +1110,17 @@ sort_up_value_number(const void *p1, const void *p2)
if (t2->type == Node_var_array)
return -1; /* t1 (scalar) < t2 (sub-array) */
- /* t1 and t2 both Node_val, and force_number'ed */
- if (t1->numbr < t2->numbr)
- ret = -1;
- else
- ret = (t1->numbr > t2->numbr);
-
- if (ret == 0) {
- /*
- * Use string value to guarantee same sort order on all
- * versions of qsort().
- */
- t1 = force_string(t1);
- t2 = force_string(t2);
- ret = cmp_string(t1, t2);
- }
+ ret = cmp_numbers(t1, t2);
+ if (ret != 0)
+ return ret;
- return ret;
+ /*
+ * Use string value to guarantee same sort order on all
+ * versions of qsort().
+ */
+ t1 = force_string(t1);
+ t2 = force_string(t2);
+ return cmp_strings(t1, t2);
}
@@ -1184,12 +1167,7 @@ sort_up_value_type(const void *p1, const void *p2)
(void) force_string(n2);
if ((n1->flags & NUMBER) != 0 && (n2->flags & NUMBER) != 0) {
- if (n1->numbr < n2->numbr)
- return -1;
- else if (n1->numbr > n2->numbr)
- return 1;
- else
- return 0;
+ return cmp_numbers(n1, n2);
}
/* 3. All numbers are less than all strings. This is aribitrary. */
@@ -1200,7 +1178,7 @@ sort_up_value_type(const void *p1, const void *p2)
}
/* 4. Two strings */
- return cmp_string(n1, n2);
+ return cmp_strings(n1, n2);
}
/* sort_down_value_type --- qsort comparison function; descending value type */
@@ -1216,10 +1194,9 @@ sort_down_value_type(const void *p1, const void *p2)
static int
sort_user_func(const void *p1, const void *p2)
{
- NODE *idx1, *idx2, *val1, *val2;
- AWKNUM ret;
+ NODE *idx1, *idx2, *val1, *val2, *r;
+ int ret;
INSTRUCTION *code;
- extern int exiting;
idx1 = *((NODE *const *) p1);
idx2 = *((NODE *const *) p2);
@@ -1242,29 +1219,38 @@ sort_user_func(const void *p1, const void *p2)
PUSH(val2);
/* execute the comparison function */
- (void) interpret(code);
-
- if (exiting) /* do not assume anything about the user-defined function! */
- gawk_exit(exit_val);
+ (void) (*interpret)(code);
/* return value of the comparison function */
- POP_NUMBER(ret);
-
- return (ret < 0.0) ? -1 : (ret > 0.0);
+ r = POP_NUMBER();
+#ifdef HAVE_MPFR
+ /*
+ * mpfr_sgn(mpz_sgn): Returns a positive value if op > 0,
+ * zero if op = 0, and a negative value if op < 0.
+ */
+ if (is_mpg_float(r))
+ ret = mpfr_sgn(r->mpg_numbr);
+ else if (is_mpg_integer(r))
+ ret = mpz_sgn(r->mpg_i);
+ else
+#endif
+ ret = (r->numbr < 0.0) ? -1 : (r->numbr > 0.0);
+ DEREF(r);
+ return ret;
}
/* assoc_list -- construct, and optionally sort, a list of array elements */
NODE **
-assoc_list(NODE *symbol, const char *sort_str, SORT_CTXT sort_ctxt)
+assoc_list(NODE *symbol, const char *sort_str, sort_context_t sort_ctxt)
{
typedef int (*qsort_compfunc)(const void *, const void *);
static const struct qsort_funcs {
const char *name;
qsort_compfunc comp_func;
- enum assoc_list_flags flags;
+ assoc_kind_t kind;
} sort_funcs[] = {
{ "@ind_str_asc", sort_up_index_string, AINDEX|AISTR|AASC },
{ "@ind_num_asc", sort_up_index_number, AINDEX|AINUM|AASC },
@@ -1279,24 +1265,22 @@ assoc_list(NODE *symbol, const char *sort_str, SORT_CTXT sort_ctxt)
{ "@unsorted", 0, AINDEX },
};
- /* N.B.: AASC and ADESC are hints to the specific array types.
+ /*
+ * N.B.: AASC and ADESC are hints to the specific array types.
* See cint_list() in cint_array.c.
*/
NODE **list;
- NODE fl;
+ NODE akind;
unsigned long num_elems, j;
int elem_size, qi;
qsort_compfunc cmp_func = 0;
INSTRUCTION *code = NULL;
extern int currule;
int save_rule = 0;
+ assoc_kind_t assoc_kind = ANONE;
- num_elems = symbol->table_size;
- assert(num_elems > 0);
-
elem_size = 1;
- fl.flags = 0;
for (qi = 0, j = sizeof(sort_funcs)/sizeof(sort_funcs[0]); qi < j; qi++) {
if (strcmp(sort_funcs[qi].name, sort_str) == 0)
@@ -1305,15 +1289,15 @@ assoc_list(NODE *symbol, const char *sort_str, SORT_CTXT sort_ctxt)
if (qi < j) {
cmp_func = sort_funcs[qi].comp_func;
- fl.flags = sort_funcs[qi].flags;
+ assoc_kind = sort_funcs[qi].kind;
if (symbol->array_funcs != cint_array_func)
- fl.flags &= ~(AASC|ADESC);
+ assoc_kind &= ~(AASC|ADESC);
- if (sort_ctxt != SORTED_IN || (fl.flags & AVALUE) != 0) {
+ if (sort_ctxt != SORTED_IN || (assoc_kind & AVALUE) != 0) {
/* need index and value pair in the list */
- fl.flags |= (AINDEX|AVALUE);
+ assoc_kind |= (AINDEX|AVALUE);
elem_size = 2;
}
@@ -1321,8 +1305,7 @@ assoc_list(NODE *symbol, const char *sort_str, SORT_CTXT sort_ctxt)
NODE *f;
const char *sp;
- for (sp = sort_str; *sp != '\0'
- && ! isspace((unsigned char) *sp); sp++)
+ for (sp = sort_str; *sp != '\0' && ! isspace((unsigned char) *sp); sp++)
continue;
/* empty string or string with space(s) not valid as function name */
@@ -1336,7 +1319,7 @@ assoc_list(NODE *symbol, const char *sort_str, SORT_CTXT sort_ctxt)
cmp_func = sort_user_func;
/* need index and value pair in the list */
- fl.flags |= (AVALUE|AINDEX);
+ assoc_kind |= (AVALUE|AINDEX);
elem_size = 2;
/* make function call instructions */
@@ -1346,9 +1329,10 @@ assoc_list(NODE *symbol, const char *sort_str, SORT_CTXT sort_ctxt)
(code + 1)->expr_count = 4; /* function takes 4 arguments */
code->nexti = bcalloc(Op_stop, 1, 0);
- /* make non-local jumps `next' and `nextfile' fatal in
+ /*
+ * make non-redirected getline, exit, `next' and `nextfile' fatal in
* callback function by setting currule in interpret()
- * to undefined (0). `exit' is handled in sort_user_func.
+ * to undefined (0).
*/
save_rule = currule; /* save current rule */
@@ -1357,10 +1341,14 @@ assoc_list(NODE *symbol, const char *sort_str, SORT_CTXT sort_ctxt)
PUSH_CODE(code);
}
- list = symbol->alist(symbol, & fl);
+ akind.flags = (unsigned int) assoc_kind; /* kludge */
+ list = symbol->alist(symbol, & akind);
+ assoc_kind = (assoc_kind_t) akind.flags; /* symbol->alist can modify it */
- if (! cmp_func || (fl.flags & (AASC|ADESC)) != 0)
- return list; /* unsorted or list already sorted */
+ if (list == NULL || ! cmp_func || (assoc_kind & (AASC|ADESC)) != 0)
+ return list; /* empty list or unsorted, or list already sorted */
+
+ num_elems = assoc_length(symbol);
qsort(list, num_elems, elem_size * sizeof(NODE *), cmp_func); /* shazzam! */
@@ -1371,9 +1359,7 @@ assoc_list(NODE *symbol, const char *sort_str, SORT_CTXT sort_ctxt)
bcfree(code); /* Op_func_call */
}
- if (sort_ctxt == SORTED_IN
- && (fl.flags & (AINDEX|AVALUE)) == (AINDEX|AVALUE)
- ) {
+ if (sort_ctxt == SORTED_IN && (assoc_kind & (AINDEX|AVALUE)) == (AINDEX|AVALUE)) {
/* relocate all index nodes to the first half of the list. */
for (j = 1; j < num_elems; j++)
list[j] = list[2 * j];
diff --git a/awk.h b/awk.h
index 2bb325b6..74cc3c21 100644
--- a/awk.h
+++ b/awk.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-2011 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-2014 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -30,6 +30,15 @@
* any system headers. Otherwise, extreme death, destruction
* and loss of life results.
*/
+#if defined(_TANDEM_SOURCE)
+/*
+ * config.h forces this even on non-tandem systems but it
+ * causes problems elsewhere if used in the check below.
+ * so workaround it. bleah.
+ */
+#define tandem_for_real 1
+#endif
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -38,7 +47,7 @@
#define _GNU_SOURCE 1 /* enable GNU extensions */
#endif /* _GNU_SOURCE */
-#if defined(_TANDEM_SOURCE) && ! defined(_SCO_DS)
+#if defined(tandem_for_real) && ! defined(_SCO_DS)
#define _XOPEN_SOURCE_EXTENDED 1
#endif
@@ -76,13 +85,21 @@
extern int errno;
#endif
-#include "mbsupport.h" /* defines MBS_SUPPORT */
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#endif /* not STDC_HEADERS */
+
+#ifdef HAVE_STDBOOL_H
+#include <stdbool.h>
+#else
+#include "missing_d/gawkbool.h"
+#endif
-#if MBS_SUPPORT
/* We can handle multibyte strings. */
#include <wchar.h>
#include <wctype.h>
-#endif
+
+#include "mbsupport.h" /* defines stuff for DJGPP to fake MBS */
#ifdef STDC_HEADERS
#include <float.h>
@@ -98,14 +115,22 @@ extern int errno;
#if HAVE_STDINT_H
# include <stdint.h>
#endif
+#else /* ZOS_USS */
+#include <limits.h>
+#include <sys/time.h>
+#define INT32_MAX INT_MAX
+#define INT32_MIN INT_MIN
+#ifndef __uint32_t
+#define __uint32_t 1
+typedef unsigned long uint32_t;
+#endif
+typedef long int32_t;
#endif /* !ZOS_USS */
/* ----------------- System dependencies (with more includes) -----------*/
/* This section is the messiest one in the file, not a lot that can be done */
-#define MALLOC_ARG_T size_t
-
#ifndef VMS
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
@@ -127,14 +152,6 @@ typedef int off_t;
# endif
#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>
-#endif /* not STDC_HEADERS */
-
#include "protos.h"
#ifdef HAVE_STRING_H
@@ -161,18 +178,10 @@ typedef int off_t;
#define O_BINARY 0
#endif
-#ifndef HAVE_VPRINTF
-#error "you lose: you need a system with vfprintf"
-#endif /* HAVE_VPRINTF */
-
#ifndef HAVE_SETLOCALE
#define setlocale(locale, val) /* nothing */
#endif /* HAVE_SETLOCALE */
-#ifndef HAVE_SETSID
-#define setsid() /* nothing */
-#endif /* HAVE_SETSID */
-
#if HAVE_MEMCPY_ULONG
extern char *memcpy_ulong(char *dest, const char *src, unsigned long l);
#define memcpy memcpy_ulong
@@ -182,18 +191,27 @@ extern void *memset_ulong(void *dest, int val, unsigned long l);
#define memset memset_ulong
#endif
-#ifdef HAVE_LIBSIGSEGV
-#include <sigsegv.h>
-#else
-typedef void *stackoverflow_context_t;
-#define sigsegv_install_handler(catchsegv) signal(SIGSEGV, catchsig)
-/* define as 0 rather than empty so that (void) cast on it works */
-#define stackoverflow_install_handler(catchstackoverflow, extra_stack, STACK_SIZE) 0
-#endif
+#if defined(__EMX__) || defined(__MINGW32__)
+#include "nonposix.h"
+#endif /* defined(__EMX__) || defined(__MINGW32__) */
/* use this as lintwarn("...")
this is a hack but it gives us the right semantics */
#define lintwarn (*(set_loc(__FILE__, __LINE__),lintfunc))
+/* same thing for warning */
+#define warning (*(set_loc(__FILE__, __LINE__),r_warning))
+
+#ifdef HAVE_MPFR
+#include <gmp.h>
+#include <mpfr.h>
+#ifndef MPFR_RNDN
+/* for compatibility with MPFR 2.X */
+#define MPFR_RNDN GMP_RNDN
+#define MPFR_RNDZ GMP_RNDZ
+#define MPFR_RNDU GMP_RNDU
+#define MPFR_RNDD GMP_RNDD
+#endif
+#endif
#include "regex.h"
#include "dfa.h"
@@ -204,6 +222,8 @@ typedef struct Regexp {
short dfa;
short has_anchor; /* speed up of avoid_dfa kludge, temporary */
short non_empty; /* for use in fpat_parse_field */
+ short has_meta; /* re has meta chars so (probably) isn't simple string */
+ short maybe_long; /* re has meta chars that can match long text */
} Regexp;
#define RESTART(rp,s) (rp)->regs.start[0]
#define REEND(rp,s) (rp)->regs.end[0]
@@ -215,6 +235,8 @@ typedef struct Regexp {
#define RE_NEED_START 1 /* need to know start/end of match */
#define RE_NO_BOL 2 /* not allowed to match ^ in regexp */
+#include "gawkapi.h"
+
/* Stuff for losing systems. */
#if !defined(HAVE_STRTOD)
extern double gawk_strtod();
@@ -239,25 +261,10 @@ extern double gawk_strtod();
#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3)
#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
-
/* ------------------ Constants, Structures, Typedefs ------------------ */
#define AWKNUM double
-#ifndef TRUE
-/* a bit hackneyed, but what the heck */
-#define TRUE 1
-#define FALSE 0
-#endif
-
-#define INT32_BIT 32
-
enum defrule { BEGIN = 1, Rule, END, BEGINFILE, ENDFILE,
MAXRULE /* sentinel, not legal */ };
extern const char *const ruletab[];
@@ -278,8 +285,9 @@ typedef enum nodevals {
Node_param_list, /* lnode is a variable, rnode is more list */
Node_func, /* lnode is param. list, rnode is body */
Node_ext_func, /* extension function, code_ptr is builtin code */
+ Node_old_ext_func, /* extension function, code_ptr is builtin code */
+ Node_builtin_func, /* built-in function, main use is for FUNCTAB */
- Node_hashnode, /* an identifier in the symbol table */
Node_array_ref, /* array passed by ref as parameter */
Node_array_tree, /* Hashed array tree (HAT) */
Node_array_leaf, /* Linear 1-D array */
@@ -329,7 +337,7 @@ typedef union bucket_item {
struct exp_instruction;
typedef int (*Func_print)(FILE *, const char *, ...);
-typedef struct exp_node **(*array_ptr)(struct exp_node *, struct exp_node *);
+typedef struct exp_node **(*afunc_t)(struct exp_node *, struct exp_node *);
/*
* NOTE - this struct is a rather kludgey -- it is packed to minimize
@@ -342,13 +350,14 @@ typedef struct exp_node {
struct exp_node *lptr;
struct exp_instruction *li;
long ll;
- array_ptr *lp;
+ afunc_t *lp;
} l;
union {
struct exp_node *rptr;
Regexp *preg;
struct exp_node **av;
BUCKET **bv;
+ void *aq;
void (*uptr)(void);
struct exp_instruction *iptr;
} r;
@@ -369,17 +378,23 @@ typedef struct exp_node {
} nodep;
struct {
+#ifdef HAVE_MPFR
+ union {
+ AWKNUM fltnum;
+ mpfr_t mpnum;
+ mpz_t mpi;
+ } nm;
+#else
AWKNUM fltnum; /* this is here for optimal packing of
* the structure on many machines
*/
+#endif
char *sp;
size_t slen;
long sref;
int idx;
-#if MBS_SUPPORT
wchar_t *wsp;
size_t wslen;
-#endif
} val;
} sub;
NODETYPE type;
@@ -402,12 +417,16 @@ typedef struct exp_node {
* lazy conversion to string.
*/
# define WSTRCUR 0x0400 /* wide str value is current */
+# define MPFN 0x0800 /* arbitrary-precision floating-point number */
+# define MPZN 0x1000 /* arbitrary-precision integer */
+# define NO_EXT_SET 0x2000 /* extension cannot set a value for this variable */
+# define NULL_FIELD 0x4000 /* this is the null field */
/* type = Node_var_array */
-# define ARRAYMAXED 0x0800 /* array is at max size */
-# define HALFHAT 0x1000 /* half-capacity Hashed Array Tree;
+# define ARRAYMAXED 0x8000 /* array is at max size */
+# define HALFHAT 0x10000 /* half-capacity Hashed Array Tree;
* See cint_array.c */
-# define XARRAY 0x2000 /* FIXME: Nuke */
+# define XARRAY 0x20000
} NODE;
#define vname sub.nodep.name
@@ -416,17 +435,12 @@ typedef struct exp_node {
#define nextp sub.nodep.l.lptr
#define rnode sub.nodep.r.rptr
-/* Node_hashnode, Node_param_list */
-#define hnext sub.nodep.r.rptr
-#define hname vname
-#define hlength sub.nodep.reserved
-#define hcode sub.nodep.cnt
-#define hvalue sub.nodep.x.extra
+/* Node_param_list */
+#define param vname
+#define dup_ent sub.nodep.r.rptr
/* Node_param_list, Node_func */
#define param_cnt sub.nodep.l.ll
-/* Node_param_list */
-#define param vname
/* Node_func */
#define fparms sub.nodep.rn
@@ -446,7 +460,13 @@ typedef struct exp_node {
#define stfmt sub.val.idx
#define wstptr sub.val.wsp
#define wstlen sub.val.wslen
-#define numbr sub.val.fltnum
+#ifdef HAVE_MPFR
+#define mpg_numbr sub.val.nm.mpnum
+#define mpg_i sub.val.nm.mpi
+#define numbr sub.val.nm.fltnum
+#else
+#define numbr sub.val.fltnum
+#endif
/* Node_arrayfor */
#define for_list sub.nodep.r.av
@@ -469,6 +489,7 @@ typedef struct exp_node {
/* Node_var_array: */
#define buckets sub.nodep.r.bv
#define nodes sub.nodep.r.av
+#define a_opaque sub.nodep.r.aq
#define array_funcs sub.nodep.l.lp
#define array_base sub.nodep.l.ll
#define table_size sub.nodep.reflags
@@ -477,17 +498,29 @@ typedef struct exp_node {
#define xarray sub.nodep.rn
#define parent_array sub.nodep.x.extra
-/* array_funcs[0] is the array initialization function and
- * array_funcs[1] is the index type checking function
- */
-#define alookup array_funcs[2]
-#define aexists array_funcs[3]
-#define aclear array_funcs[4]
-#define aremove array_funcs[5]
-#define alist array_funcs[6]
-#define acopy array_funcs[7]
-#define adump array_funcs[8]
-#define NUM_AFUNCS 9 /* # of entries in array_funcs */
+#define ainit array_funcs[0]
+#define ainit_ind 0
+#define atypeof array_funcs[1]
+#define atypeof_ind 1
+#define alength array_funcs[2]
+#define alength_ind 2
+#define alookup array_funcs[3]
+#define alookup_ind 3
+#define aexists array_funcs[4]
+#define aexists_ind 4
+#define aclear array_funcs[5]
+#define aclear_ind 5
+#define aremove array_funcs[6]
+#define aremove_ind 6
+#define alist array_funcs[7]
+#define alist_ind 7
+#define acopy array_funcs[8]
+#define acopy_ind 8
+#define adump array_funcs[9]
+#define adump_ind 9
+#define astore array_funcs[10]
+#define astore_ind 10
+#define NUM_AFUNCS 11 /* # of entries in array_funcs */
/* Node_array_ref: */
#define orig_array lnode
@@ -497,6 +530,11 @@ typedef struct exp_node {
#define adepth sub.nodep.l.ll
#define alevel sub.nodep.x.xl
+/* Op_comment */
+#define comment_type sub.val.idx
+#define EOL_COMMENT 1
+#define FULL_COMMENT 2
+
/* --------------------------------lint warning types----------------------------*/
typedef enum lintvals {
LINT_illegal,
@@ -595,6 +633,7 @@ typedef enum opcodeval {
Op_builtin,
Op_sub_builtin, /* sub, gsub and gensub */
Op_ext_builtin,
+ Op_old_ext_builtin, /* temporary */
Op_in_array, /* boolean test of membership in array */
/* function call instruction */
@@ -602,7 +641,7 @@ typedef enum opcodeval {
Op_indirect_func_call,
Op_push, /* scalar variable */
- Op_push_arg, /* variable type (scalar or array) argument to built-in */
+ Op_push_arg, /* variable type (scalar or array) argument to built-in */
Op_push_i, /* number, string */
Op_push_re, /* regex */
Op_push_array,
@@ -624,11 +663,13 @@ typedef enum opcodeval {
Op_var_update, /* update value of NR, NF or FNR */
Op_var_assign,
Op_field_assign,
+ Op_subscript_assign,
Op_after_beginfile,
Op_after_endfile,
Op_func,
+ Op_comment, /* for pretty printing */
Op_exec_count,
Op_breakpoint,
Op_lint,
@@ -655,7 +696,8 @@ typedef enum opcodeval {
enum redirval {
/* I/O redirections */
- redirect_output = 1,
+ redirect_none = 0,
+ redirect_output,
redirect_append,
redirect_pipe,
redirect_pipein,
@@ -671,6 +713,7 @@ typedef struct exp_instruction {
NODE *dn;
struct exp_instruction *di;
NODE *(*fptr)(int);
+ awk_value_t *(*efptr)(int, awk_value_t *);
long dl;
char *name;
} d;
@@ -691,6 +734,7 @@ typedef struct exp_instruction {
#define memory d.dn
#define builtin d.fptr
+#define extfunc d.efptr
#define builtin_idx d.dl
#define expr_count x.xl
@@ -835,11 +879,8 @@ typedef struct exp_instruction {
/* Op_store_var */
#define initval x.xn
-
typedef struct iobuf {
- const char *name; /* filename */
- int fd; /* file descriptor */
- struct stat sbuf; /* stat buf */
+ awk_input_buf_t public; /* exposed to extensions */
char *buf; /* start data buffer */
char *off; /* start of current record in buffer */
char *dataend; /* first byte in buffer to hold new data,
@@ -850,19 +891,14 @@ typedef struct iobuf {
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)(char **out, struct iobuf *, int *errcode);
- void (*close_func)(struct iobuf *); /* open and close hooks */
-
+ bool valid;
int errcode;
int flag;
# define IOP_IS_TTY 1
-# define IOP_NOFREE_OBJ 2
-# define IOP_AT_EOF 4
-# define IOP_CLOSED 8
-# define IOP_AT_START 16
+# define IOP_AT_EOF 2
+# define IOP_CLOSED 4
+# define IOP_AT_START 8
} IOBUF;
typedef void (*Func_ptr)(void);
@@ -883,7 +919,6 @@ struct redirect {
# define RED_SOCKET 1024
# define RED_TCP 2048
char *value;
- FILE *fp;
FILE *ifp; /* input fp, needed for PIPES_SIMULATED */
IOBUF *iop;
int pid;
@@ -891,6 +926,16 @@ struct redirect {
struct redirect *prev;
struct redirect *next;
const char *mode;
+ awk_output_buf_t output;
+};
+
+/* values for BINMODE, used as bit flags */
+
+enum binmode_values {
+ TEXT_TRANSLATE = 0, /* usual \r\n ---> \n translation */
+ BINMODE_INPUT = 1, /* no translation for input files */
+ BINMODE_OUTPUT = 2, /* no translation for output files */
+ BINMODE_BOTH = 3 /* no translation for either */
};
/*
@@ -901,8 +946,14 @@ typedef struct srcfile {
struct srcfile *next;
struct srcfile *prev;
- enum srctype { SRC_CMDLINE = 1, SRC_STDIN, SRC_FILE, SRC_INC } stype;
- char *src; /* name on command line or inclde statement */
+ enum srctype {
+ SRC_CMDLINE = 1,
+ SRC_STDIN,
+ SRC_FILE,
+ SRC_INC,
+ SRC_EXTLIB
+ } stype;
+ char *src; /* name on command line or include statement */
char *fullpath; /* full path after AWKPATH search */
time_t mtime;
struct stat sbuf;
@@ -913,6 +964,8 @@ typedef struct srcfile {
int fd;
int maxlen; /* size of the longest line */
+ void (*fini_func)(); /* dynamic extension of type SRC_EXTLIB */
+
char *lexptr;
char *lexend;
char *lexeme;
@@ -951,6 +1004,8 @@ enum block_id {
BLOCK_MAX /* count */
};
+typedef int (*Func_pre_exec)(INSTRUCTION **);
+typedef void (*Func_post_exec)(INSTRUCTION *);
#ifndef LONG_MAX
#define LONG_MAX ((long)(~(1L << (sizeof (long) * 8 - 1))))
@@ -970,7 +1025,7 @@ extern long NR;
extern long FNR;
extern int BINMODE;
extern int IGNORECASE;
-extern int RS_is_null;
+extern bool RS_is_null;
extern char *OFS;
extern int OFSlen;
extern char *ORS;
@@ -985,60 +1040,62 @@ 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, *FPAT_node;
+extern NODE *PREC_node, *ROUNDMODE_node;
extern NODE *Nnull_string;
extern NODE *Null_field;
extern NODE **fields_arr;
extern int sourceline;
extern char *source;
+extern int (*interpret)(INSTRUCTION *); /* interpreter routine */
+extern NODE *(*make_number)(double); /* double instead of AWKNUM on purpose */
+extern NODE *(*str2number)(NODE *);
+extern NODE *(*format_val)(const char *, int, NODE *);
+extern int (*cmp_numbers)(const NODE *, const NODE *);
-#if __GNUC__ < 2
-extern NODE *_t; /* used as temporary in macros */
-#endif
-extern NODE *_r; /* used as temporary in macros */
+/* built-in array types */
+extern afunc_t str_array_func[];
+extern afunc_t cint_array_func[];
+extern afunc_t int_array_func[];
extern BLOCK nextfree[];
-extern int field0_valid;
+extern bool field0_valid;
extern int do_flags;
-/* only warn about invalid */
-#define DO_LINT_INVALID 0x0001
-/* warn about all things */
-#define DO_LINT_ALL 0x0002
-/* warn about stuff not in V7 awk */
-#define DO_LINT_OLD 0x0004
-/* no gnu extensions, add traditional weirdnesses */
-#define DO_TRADITIONAL 0x0008
-/* turn off gnu and unix extensions */
-#define DO_POSIX 0x0010
-/* dump locale-izable strings to stdout */
-#define DO_INTL 0x0020
-/* allow octal/hex C style DATA. Use with caution! */
-#define DO_NON_DEC_DATA 0x0040
-/* allow {...,...} in regexps, see resetup() */
-#define DO_INTERVALS 0x0080
-/* profile and pretty print the program */
-#define DO_PROFILING 0x0100
-/* dump all global variables at end */
-#define DO_DUMP_VARS 0x0200
-/* release vars when done */
-#define DO_TIDY_MEM 0x0400
-/* sandbox mode - disable 'system' function & redirections */
-#define DO_SANDBOX 0x0800
-
+extern SRCFILE *srcfiles; /* source files */
+
+enum do_flag_values {
+ DO_LINT_INVALID = 0x0001, /* only warn about invalid */
+ DO_LINT_ALL = 0x0002, /* warn about all things */
+ DO_LINT_OLD = 0x0004, /* warn about stuff not in V7 awk */
+ DO_TRADITIONAL = 0x0008, /* no gnu extensions, add traditional weirdnesses */
+ DO_POSIX = 0x0010, /* turn off gnu and unix extensions */
+ DO_INTL = 0x0020, /* dump locale-izable strings to stdout */
+ DO_NON_DEC_DATA = 0x0040, /* allow octal/hex C style DATA. Use with caution! */
+ DO_INTERVALS = 0x0080, /* allow {...,...} in regexps, see resetup() */
+ DO_PRETTY_PRINT = 0x0100, /* pretty print the program */
+ DO_DUMP_VARS = 0x0200, /* dump all global variables at end */
+ DO_TIDY_MEM = 0x0400, /* release vars when done */
+ DO_SANDBOX = 0x0800, /* sandbox mode - disable 'system' function & redirections */
+ DO_PROFILE = 0x1000, /* profile the program */
+ DO_DEBUG = 0x2000, /* debug the program */
+ DO_MPFR = 0x4000 /* arbitrary-precision floating-point math */
+};
#define do_traditional (do_flags & DO_TRADITIONAL)
-#define do_posix (do_flags & DO_POSIX)
-#define do_intl (do_flags & DO_INTL)
+#define do_posix (do_flags & DO_POSIX)
+#define do_intl (do_flags & DO_INTL)
#define do_non_decimal_data (do_flags & DO_NON_DEC_DATA)
#define do_intervals (do_flags & DO_INTERVALS)
-#define do_profiling (do_flags & DO_PROFILING)
+#define do_pretty_print (do_flags & DO_PRETTY_PRINT)
+#define do_profile (do_flags & DO_PROFILE)
#define do_dump_vars (do_flags & DO_DUMP_VARS)
#define do_tidy_mem (do_flags & DO_TIDY_MEM)
#define do_sandbox (do_flags & DO_SANDBOX)
+#define do_debug (do_flags & DO_DEBUG)
+#define do_mpfr (do_flags & DO_MPFR)
-
-extern int do_optimize;
+extern bool do_optimize;
extern int use_lc_numeric;
extern int exit_val;
@@ -1049,11 +1106,7 @@ extern int exit_val;
#define do_lint (do_flags & (DO_LINT_INVALID|DO_LINT_ALL))
#define do_lint_old (do_flags & DO_LINT_OLD)
#endif
-#if MBS_SUPPORT
extern int gawk_mb_cur_max;
-#else
-#define gawk_mb_cur_max (1)
-#endif
#if defined (HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
extern GETGROUPS_T *groupset;
@@ -1064,26 +1117,30 @@ extern int ngroups;
extern struct lconv loc;
#endif /* HAVE_LOCALE_H */
+#ifdef HAVE_MPFR
+extern mpfr_prec_t PRECISION;
+extern mpfr_rnd_t ROUND_MODE;
+extern mpz_t MNR;
+extern mpz_t MFNR;
+extern mpz_t mpzval;
+extern bool do_ieee_fmt; /* emulate IEEE 754 floating-point format */
+#endif
+
+
extern const char *myname;
extern const char def_strftime_format[];
extern char quote;
extern char *defpath;
+extern char *deflibpath;
extern char envsep;
extern char casetable[]; /* for case-independent regexp matching */
-/*
- * Provide a way for code to know which program is executing:
- * gawk vs dgawk vs pgawk.
- */
-enum exe_mode { exe_normal = 1, exe_debugging, exe_profiling };
-extern enum exe_mode which_gawk; /* (defined in eval.c) */
-
/* ------------------------- Runtime stack -------------------------------- */
typedef union stack_item {
- NODE *rptr; /* variable etc. */
+ NODE *rptr; /* variable etc. */
NODE **lptr; /* address of a variable etc. */
} STACK_ITEM;
@@ -1097,11 +1154,11 @@ extern STACK_ITEM *stack_top;
#define stack_adj(n) (stack_ptr += (n))
#define stack_empty() (stack_ptr < stack_bottom)
-#define POP() decr_sp()->rptr
-#define POP_ADDRESS() decr_sp()->lptr
-#define PEEK(n) (stack_ptr - (n))->rptr
-#define TOP() stack_ptr->rptr /* same as PEEK(0) */
-#define TOP_ADDRESS() stack_ptr->lptr
+#define POP() (decr_sp()->rptr)
+#define POP_ADDRESS() (decr_sp()->lptr)
+#define PEEK(n) ((stack_ptr - (n))->rptr)
+#define TOP() (stack_ptr->rptr) /* same as PEEK(0) */
+#define TOP_ADDRESS() (stack_ptr->lptr)
#define PUSH(r) (void) (incr_sp()->rptr = (r))
#define PUSH_ADDRESS(l) (void) (incr_sp()->lptr = (l))
#define REPLACE(r) (void) (stack_ptr->rptr = (r))
@@ -1118,50 +1175,56 @@ extern STACK_ITEM *stack_top;
#define UPREF(r) (void) ((r)->valref++)
-#define DEREF(r) ( _r = (r), (--_r->valref == 0) ? r_unref(_r) : (void)0 )
-
-#if __GNUC__ >= 2
-
-#define POP_ARRAY() ({ NODE *_t = POP(); \
- _t->type == Node_var_array ? _t : get_array(_t, TRUE); })
-
-#define POP_PARAM() ({ NODE *_t = POP(); \
- _t->type == Node_var_array ? _t : get_array(_t, FALSE); })
-
-#define POP_NUMBER(x) ({ NODE *_t = POP_SCALAR(); x = force_number(_t); DEREF(_t); })
-#define TOP_NUMBER(x) ({ NODE *_t = TOP_SCALAR(); x = force_number(_t); DEREF(_t); })
-
-#define POP_SCALAR() ({ NODE *_t = POP(); _t->type != Node_var_array ? _t \
- : (fatal(_("attempt to use array `%s' in a scalar context"), array_vname(_t)), _t);})
-#define TOP_SCALAR() ({ NODE *_t = TOP(); _t->type != Node_var_array ? _t \
- : (fatal(_("attempt to use array `%s' in a scalar context"), array_vname(_t)), _t);})
-
-#define POP_STRING() force_string(POP_SCALAR())
-#define TOP_STRING() force_string(TOP_SCALAR())
-
-#else /* not __GNUC__ */
-
-#define POP_ARRAY() (_t = POP(), \
- _t->type == Node_var_array ? _t : get_array(_t, TRUE))
-
-#define POP_PARAM() (_t = POP(), \
- _t->type == Node_var_array ? _t : get_array(_t, FALSE))
-
-#define POP_NUMBER(x) (_t = POP_SCALAR(), x = force_number(_t), DEREF(_t))
-#define TOP_NUMBER(x) (_t = TOP_SCALAR(), x = force_number(_t), DEREF(_t))
-
-#define POP_SCALAR() (_t = POP(), _t->type != Node_var_array ? _t \
- : (fatal(_("attempt to use array `%s' in a scalar context"), array_vname(_t)), _t))
-#define TOP_SCALAR() (_t = TOP(), _t->type != Node_var_array ? _t \
- : (fatal(_("attempt to use array `%s' in a scalar context"), array_vname(_t)), _t))
+extern void r_unref(NODE *tmp);
-#define POP_STRING() (_r = POP_SCALAR(), m_force_string(_r))
-#define TOP_STRING() (_r = TOP_SCALAR(), m_force_string(_r))
+static inline void
+DEREF(NODE *r)
+{
+ if (--r->valref == 0)
+ r_unref(r);
+}
-#endif /* __GNUC__ */
+#define POP_NUMBER() force_number(POP_SCALAR())
+#define TOP_NUMBER() force_number(TOP_SCALAR())
/* ------------------------- Pseudo-functions ------------------------- */
-#define is_identchar(c) (isalnum(c) || (c) == '_')
+#ifdef HAVE_MPFR
+/* conversion to C types */
+#define get_number_ui(n) (((n)->flags & MPFN) ? mpfr_get_ui((n)->mpg_numbr, ROUND_MODE) \
+ : ((n)->flags & MPZN) ? mpz_get_ui((n)->mpg_i) \
+ : (unsigned long) (n)->numbr)
+#define get_number_si(n) (((n)->flags & MPFN) ? mpfr_get_si((n)->mpg_numbr, ROUND_MODE) \
+ : ((n)->flags & MPZN) ? mpz_get_si((n)->mpg_i) \
+ : (long) (n)->numbr)
+#define get_number_d(n) (((n)->flags & MPFN) ? mpfr_get_d((n)->mpg_numbr, ROUND_MODE) \
+ : ((n)->flags & MPZN) ? mpz_get_d((n)->mpg_i) \
+ : (double) (n)->numbr)
+#define get_number_uj(n) (((n)->flags & MPFN) ? mpfr_get_uj((n)->mpg_numbr, ROUND_MODE) \
+ : ((n)->flags & MPZN) ? (uintmax_t) mpz_get_d((n)->mpg_i) \
+ : (uintmax_t) (n)->numbr)
+
+#define iszero(n) (((n)->flags & MPFN) ? mpfr_zero_p((n)->mpg_numbr) \
+ : ((n)->flags & MPZN) ? (mpz_sgn((n)->mpg_i) == 0) \
+ : ((n)->numbr == 0.0))
+
+#define IEEE_FMT(r, t) (void) (do_ieee_fmt && format_ieee(r, t))
+
+#define mpg_float() mpg_node(MPFN)
+#define mpg_integer() mpg_node(MPZN)
+#define is_mpg_float(n) (((n)->flags & MPFN) != 0)
+#define is_mpg_integer(n) (((n)->flags & MPZN) != 0)
+#define is_mpg_number(n) (((n)->flags & (MPZN|MPFN)) != 0)
+#else
+#define get_number_ui(n) (unsigned long) (n)->numbr
+#define get_number_si(n) (long) (n)->numbr
+#define get_number_d(n) (double) (n)->numbr
+#define get_number_uj(n) (uintmax_t) (n)->numbr
+
+#define is_mpg_number(n) 0
+#define is_mpg_float(n) 0
+#define is_mpg_integer(n) 0
+#define iszero(n) ((n)->numbr == 0.0)
+#endif
#define var_uninitialized(n) ((n)->var_value == Nnull_string)
@@ -1180,8 +1243,7 @@ extern STACK_ITEM *stack_top;
#define getbucket(b) getblock(b, BLOCK_BUCKET, BUCKET *)
#define freebucket(b) freeblock(b, BLOCK_BUCKET)
-#define make_string(s, l) r_make_str_node((s), (l), 0)
-#define make_str_node(s, l, f) r_make_str_node((s), (l), (f))
+#define make_string(s, l) make_str_node((s), (l), 0)
#define SCAN 1
#define ALREADY_MALLOCED 2
@@ -1189,107 +1251,63 @@ extern STACK_ITEM *stack_top;
#define cant_happen() r_fatal("internal error line %d, file: %s", \
__LINE__, __FILE__)
-#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 = (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))
+#define emalloc(var,ty,x,str) (void) (var = (ty) emalloc_real((size_t)(x), str, #var, __FILE__, __LINE__))
+#define erealloc(var,ty,x,str) (void) (var = (ty) erealloc_real((void *) var, (size_t)(x), str, #var, __FILE__, __LINE__))
#define efree(p) free(p)
-#ifdef GAWKDEBUG
-#define force_number r_force_number
-#define dupnode r_dupnode
-#define unref r_unref
-#define m_force_string r_force_string
-extern NODE *r_force_string(NODE *s);
-#else /* not GAWKDEBUG */
-
-#define unref(r) ( _r = (r), (_r == NULL || --_r->valref > 0) ? \
- (void)0 : r_unref(_r) )
-
-#define m_force_string(_ts) (((_ts->flags & STRCUR) && \
- (_ts->stfmt == -1 || _ts->stfmt == CONVFMTidx)) ? \
- _ts : format_val(CONVFMT, CONVFMTidx, _ts))
-
-#if __GNUC__ >= 2
-#define dupnode(n) __extension__ ({ NODE *_tn = (n); \
- (_tn->flags & MALLOC) ? (_tn->valref++, _tn) : r_dupnode(_tn); })
-
-#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); m_force_string(_ts); })
-
-#else /* not __GNUC__ */
-#define dupnode(n) (_t = (n), \
- (_t->flags & MALLOC) ? (_t->valref++, _t) : r_dupnode(_t))
-
-#define force_number r_force_number
-#define force_string(s) (_t = (s), m_force_string(_t))
-#endif /* __GNUC__ */
-#endif /* 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
-
extern jmp_buf fatal_tag;
-extern int fatal_tag_valid;
+extern bool fatal_tag_valid;
#define PUSH_BINDING(stack, tag, val) \
if (val++) \
memcpy((char *) (stack), (const char *) tag, sizeof(jmp_buf))
#define POP_BINDING(stack, tag, val) \
-if (--val) \
+if (--val) \
memcpy((char *) tag, (const char *) (stack), sizeof(jmp_buf))
-#define array_empty(a) ((a)->table_size == 0)
-#define assoc_lookup(a, s) (a)->alookup(a, s)
+#define assoc_length(a) ((*((a)->alength(a, NULL)))->table_size)
+#define assoc_empty(a) (assoc_length(a) == 0)
+#define assoc_lookup(a, s) ((a)->alookup(a, s))
-#if __GNUC__ >= 2
-#define in_array(a, s) ({ NODE **_l; array_empty(a) ? NULL \
- : (_l = (a)->aexists(a, s), _l ? *_l : NULL); })
-#else /* not __GNUC__ */
-#define in_array(a, s) r_in_array(a, s)
-#endif /* __GNUC__ */
+/* assoc_clear --- flush all the values in symbol[] */
+#define assoc_clear(a) (void) ((a)->aclear(a, NULL))
+/* assoc_remove --- remove an index from symbol[] */
+#define assoc_remove(a, s) ((a)->aremove(a, s) != NULL)
/* ------------- Function prototypes or defs (as appropriate) ------------- */
/* array.c */
-typedef enum sort_context { SORTED_IN = 1, ASORT, ASORTI } SORT_CTXT;
-enum assoc_list_flags {
-AINDEX = 0x01, /* list of indices */
-AVALUE = 0x02, /* list of values */
-AINUM = 0x04, /* numeric index */
-AISTR = 0x08, /* string index */
-AVNUM = 0x10, /* numeric scalar value */
-AVSTR = 0x20, /* string scalar value */
-AASC = 0x40, /* ascending order */
-ADESC = 0x80, /* descending order */
-ADELETE = 0x100, /* need a single index; for use in do_delete_loop */
-};
+typedef enum { SORTED_IN = 1, ASORT, ASORTI } sort_context_t;
+typedef enum {
+ ANONE = 0x00, /* "unused" value */
+ AINDEX = 0x001, /* list of indices */
+ AVALUE = 0x002, /* list of values */
+ AINUM = 0x004, /* numeric index */
+ AISTR = 0x008, /* string index */
+ AVNUM = 0x010, /* numeric scalar value */
+ AVSTR = 0x020, /* string scalar value */
+ AASC = 0x040, /* ascending order */
+ ADESC = 0x080, /* descending order */
+ ADELETE = 0x100 /* need a single index; for use in do_delete_loop */
+} assoc_kind_t;
extern NODE *make_array(void);
-extern void init_array(NODE *symbol);
-extern NODE *get_array(NODE *symbol, int canfatal);
+extern void null_array(NODE *symbol);
+extern NODE *force_array(NODE *symbol, bool canfatal);
extern const char *make_aname(const NODE *symbol);
extern const char *array_vname(const NODE *symbol);
extern void array_init(void);
-extern int register_array_func(array_ptr *afunc);
+extern int register_array_func(afunc_t *afunc);
+extern NODE **null_length(NODE *symbol, NODE *subs);
+extern NODE **null_afunc(NODE *symbol, NODE *subs);
extern void set_SUBSEP(void);
-extern NODE *concat_exp(int nargs, int do_subsep);
-extern void assoc_clear(NODE *symbol);
-extern NODE *r_in_array(NODE *symbol, NODE *subs);
-extern int assoc_remove(NODE *symbol, NODE *subs);
+extern NODE *concat_exp(int nargs, bool do_subsep);
extern NODE *assoc_copy(NODE *symbol, NODE *newsymb);
extern void assoc_dump(NODE *symbol, NODE *p);
-extern NODE **assoc_list(NODE *symbol, const char *sort_str, SORT_CTXT sort_ctxt);
+extern NODE **assoc_list(NODE *symbol, const char *sort_str, sort_context_t sort_ctxt);
extern void assoc_info(NODE *subs, NODE *val, NODE *p, const char *aname);
extern void do_delete(NODE *symbol, int nsubs);
extern void do_delete_loop(NODE *symbol, NODE **lhs);
@@ -1298,18 +1316,28 @@ extern NODE *do_aoption(int nargs);
extern NODE *do_asort(int nargs);
extern NODE *do_asorti(int nargs);
extern unsigned long (*hash)(const char *s, size_t len, unsigned long hsize, size_t *code);
+extern void init_env_array(NODE *env_node);
/* awkgram.c */
extern NODE *variable(int location, char *name, NODETYPE type);
extern int parse_program(INSTRUCTION **pcode);
+extern void track_ext_func(const char *name);
extern void dump_funcs(void);
extern void dump_vars(const char *fname);
extern const char *getfname(NODE *(*)(int));
+extern NODE *stopme(int nargs);
extern void shadow_funcs(void);
extern int check_special(const char *name);
-extern SRCFILE *add_srcfile(int stype, char *src, SRCFILE *curr, int *already_included, int *errcode);
-extern void register_deferred_variable(const char *name, NODE *(*load_func)(void));
+extern SRCFILE *add_srcfile(enum srctype stype, char *src, SRCFILE *curr, bool *already_included, int *errcode);
+extern void free_srcfile(SRCFILE *thisfile);
extern int files_are_same(char *path, SRCFILE *src);
extern void valinfo(NODE *n, Func_print print_func, FILE *fp);
+extern void negate_num(NODE *n);
+typedef NODE *(*builtin_func_t)(int); /* function that implements a built-in */
+extern builtin_func_t lookup_builtin(const char *name);
+extern void install_builtins(void);
+extern bool is_alpha(int c);
+extern bool is_alnum(int c);
+extern bool is_identchar(int c);
/* builtin.c */
extern double double_to_int(double d);
extern NODE *do_exp(int nargs);
@@ -1351,15 +1379,15 @@ extern AWKNUM nondec2awknum(char *str, size_t len);
extern NODE *do_dcgettext(int nargs);
extern NODE *do_dcngettext(int nargs);
extern NODE *do_bindtextdomain(int nargs);
-#if MBS_SUPPORT
+extern NODE *do_div(int nargs);
extern int strncasecmpmbs(const unsigned char *,
const unsigned char *, size_t);
-#endif
/* eval.c */
extern void PUSH_CODE(INSTRUCTION *cp);
extern INSTRUCTION *POP_CODE(void);
-extern int interpret(INSTRUCTION *);
-extern int cmp_nodes(NODE *p1, NODE *p2);
+extern void init_interpret(void);
+extern int cmp_nodes(NODE *t1, NODE *t2);
+extern int cmp_awknums(const NODE *t1, const NODE *t2);
extern void set_IGNORECASE(void);
extern void set_OFS(void);
extern void set_ORS(void);
@@ -1368,8 +1396,9 @@ extern void set_CONVFMT(void);
extern void set_BINMODE(void);
extern void set_LINT(void);
extern void set_TEXTDOMAIN(void);
-extern void update_ERRNO(void);
-extern void update_ERRNO_saved(int);
+extern void update_ERRNO_int(int);
+extern void update_ERRNO_string(const char *string);
+extern void unset_ERRNO(void);
extern void update_NR(void);
extern void update_NF(void);
extern void update_FNR(void);
@@ -1378,28 +1407,31 @@ extern const char *flags2str(int);
extern const char *genflags2str(int flagval, const struct flagtab *tab);
extern const char *nodetype2str(NODETYPE type);
extern void load_casetable(void);
-
extern AWKNUM calc_exp(AWKNUM x1, AWKNUM x2);
extern const char *opcode2str(OPCODE type);
extern const char *op2str(OPCODE type);
-extern NODE **r_get_lhs(NODE *n, int reference);
+extern NODE **r_get_lhs(NODE *n, bool reference);
extern STACK_ITEM *grow_stack(void);
-#ifdef PROFILING
extern void dump_fcall_stack(FILE *fp);
-#endif
+extern int register_exec_hook(Func_pre_exec preh, Func_post_exec posth);
/* ext.c */
-NODE *do_ext(int nargs);
+extern NODE *do_ext(int nargs);
+void load_ext(const char *lib_name); /* temporary */
+extern NODE *load_old_ext(SRCFILE *s, const char *init_func, const char *fini_func, NODE *obj);
+extern void close_extensions(void);
#ifdef DYNAMIC
-void make_builtin(const char *, NODE *(*)(int), int);
-NODE *get_argument(int);
-NODE *get_actual_argument(int, int, int);
-#define get_scalar_argument(i, opt) get_actual_argument((i), (opt), FALSE)
-#define get_array_argument(i, opt) get_actual_argument((i), (opt), TRUE)
+extern void make_old_builtin(const char *, NODE *(*)(int), int);
+extern awk_bool_t make_builtin(const awk_ext_func_t *);
+extern NODE *get_argument(int);
+extern NODE *get_actual_argument(int, bool, bool);
+#define get_scalar_argument(i, opt) get_actual_argument((i), (opt), false)
+#define get_array_argument(i, opt) get_actual_argument((i), (opt), true)
#endif
/* field.c */
extern void init_fields(void);
extern void set_record(const char *buf, int cnt);
extern void reset_record(void);
+extern void rebuild_record(void);
extern void set_NF(void);
extern NODE **get_field(long num, Func_ptr *assign);
extern NODE *do_split(int nargs);
@@ -1418,6 +1450,14 @@ typedef enum {
} field_sep_type;
extern field_sep_type current_field_sep(void);
+/* gawkapi.c: */
+extern gawk_api_t api_impl;
+extern void init_ext_api(void);
+extern void update_ext_api(void);
+extern NODE *awk_value_to_node(const awk_value_t *);
+extern void run_ext_exit_handlers(int exitval);
+extern void print_ext_versions(void);
+
/* gawkmisc.c */
extern char *gawk_name(const char *filespec);
extern void os_arg_fixup(int *argcp, char ***argvp);
@@ -1425,6 +1465,7 @@ extern int os_devopen(const char *name, int flag);
extern void os_close_on_exec(int fd, const char *name, const char *what, const char *dir);
extern int os_isatty(int fd);
extern int os_isdir(int fd);
+extern int os_isreadable(const awk_input_buf_t *iobuf, bool *isdir);
extern int os_is_setuid(void);
extern int os_setbinmode(int fd, int mode);
extern void os_restore_mode(int fd);
@@ -1433,62 +1474,97 @@ extern int ispath(const char *file);
extern int isdirpunct(int c);
/* io.c */
-extern void register_open_hook(void *(*open_func)(IOBUF *));
+extern void init_sockets(void);
+extern void init_io(void);
+extern void register_input_parser(awk_input_parser_t *input_parser);
+extern void register_output_wrapper(awk_output_wrapper_t *wrapper);
+extern void register_two_way_processor(awk_two_way_processor_t *processor);
extern void set_FNR(void);
extern void set_NR(void);
extern struct redirect *redirect(NODE *redir_exp, int redirtype, int *errflg);
extern NODE *do_close(int nargs);
extern int flush_io(void);
-extern int close_io(int *stdio_problem);
+extern int close_io(bool *stdio_problem);
extern int devopen(const char *name, const char *mode);
extern int srcopen(SRCFILE *s);
-extern char *find_source(const char *src, struct stat *stb, int *errcode);
-extern NODE *do_getline_redir(int intovar, int redirtype);
+extern char *find_source(const char *src, struct stat *stb, int *errcode, int is_extlib);
+extern NODE *do_getline_redir(int intovar, enum redirval redirtype);
extern NODE *do_getline(int intovar, IOBUF *iop);
extern struct redirect *getredirect(const char *str, int len);
-extern int inrec(IOBUF *iop, int *errcode);
-extern int nextfile(IOBUF **curfile, int skipping);
+extern bool inrec(IOBUF *iop, int *errcode);
+extern int nextfile(IOBUF **curfile, bool skipping);
/* main.c */
-extern int arg_assign(char *arg, int initing);
+extern int arg_assign(char *arg, bool initing);
extern int is_std_var(const char *var);
+extern int is_off_limits_var(const char *var);
extern char *estrdup(const char *str, size_t len);
extern void update_global_values();
extern long getenv_long(const char *name);
+
+/* mpfr.c */
+extern void set_PREC(void);
+extern void set_ROUNDMODE(void);
+extern void mpfr_unset(NODE *n);
+#ifdef HAVE_MPFR
+extern int mpg_cmp(const NODE *, const NODE *);
+extern int format_ieee(mpfr_ptr, int);
+extern NODE *mpg_update_var(NODE *);
+extern long mpg_set_var(NODE *);
+extern NODE *do_mpfr_and(int);
+extern NODE *do_mpfr_atan2(int);
+extern NODE *do_mpfr_compl(int);
+extern NODE *do_mpfr_cos(int);
+extern NODE *do_mpfr_div(int);
+extern NODE *do_mpfr_exp(int);
+extern NODE *do_mpfr_int(int);
+extern NODE *do_mpfr_log(int);
+extern NODE *do_mpfr_lshift(int);
+extern NODE *do_mpfr_or(int);
+extern NODE *do_mpfr_rand(int);
+extern NODE *do_mpfr_rshift(int);
+extern NODE *do_mpfr_sin(int);
+extern NODE *do_mpfr_sqrt(int);
+extern NODE *do_mpfr_srand(int);
+extern NODE *do_mpfr_strtonum(int);
+extern NODE *do_mpfr_xor(int);
+extern void init_mpfr(mpfr_prec_t, const char *);
+extern void cleanup_mpfr(void);
+extern NODE *mpg_node(unsigned int);
+extern const char *mpg_fmt(const char *, ...);
+extern int mpg_strtoui(mpz_ptr, char *, size_t, char **, int);
+#endif
/* msg.c */
extern void gawk_exit(int status);
-extern void err(const char *s, const char *emsg, va_list argp) ATTRIBUTE_PRINTF(2, 0);
+extern void final_exit(int status) ATTRIBUTE_NORETURN;
+extern void err(bool isfatal, const char *s, const char *emsg, va_list argp) ATTRIBUTE_PRINTF(3, 0);
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 r_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;
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)
-extern void (*lintfunc) (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
+extern void (*lintfunc)(const char *mesg, ...) ATTRIBUTE_PRINTF_1;
#else
-extern void (*lintfunc) (const char *mesg, ...);
+extern void (*lintfunc)(const char *mesg, ...);
#endif
/* profile.c */
-extern void init_profiling(int *flag, const char *def_file);
extern void init_profiling_signals(void);
extern void set_prof_file(const char *filename);
extern void dump_prog(INSTRUCTION *code);
-extern char *pp_number(AWKNUM d);
+extern char *pp_number(NODE *n);
extern char *pp_string(const char *in_str, size_t len, int delim);
extern char *pp_node(NODE *n);
extern int pp_func(INSTRUCTION *pc, void *);
extern void pp_string_fp(Func_print print_func, FILE *fp, const char *str,
- size_t namelen, int delim, int breaklines);
+ size_t namelen, int delim, bool breaklines);
/* node.c */
-extern AWKNUM r_force_number(NODE *n);
-extern NODE *format_val(const char *format, int index, NODE *s);
+extern NODE *r_force_number(NODE *n);
+extern NODE *r_format_val(const char *format, int index, NODE *s);
extern NODE *r_dupnode(NODE *n);
-extern NODE *make_number(AWKNUM x);
-extern NODE *r_make_str_node(const char *s, size_t len, int flags);
+extern NODE *make_str_node(const char *s, size_t len, int flags);
extern void *more_blocks(int id);
-extern void r_unref(NODE *tmp);
extern int parse_escape(const char **string_ptr);
-#if MBS_SUPPORT
extern NODE *str2wstr(NODE *n, size_t **ptr);
extern NODE *wstr2str(NODE *n);
#define force_wstring(n) str2wstr(n, NULL)
@@ -1496,16 +1572,14 @@ extern const wchar_t *wstrstr(const wchar_t *haystack, size_t hs_len,
const wchar_t *needle, size_t needle_len);
extern const wchar_t *wcasestrstr(const wchar_t *haystack, size_t hs_len,
const wchar_t *needle, size_t needle_len);
-extern void free_wstr(NODE *n);
+extern void r_free_wstr(NODE *n);
+#define free_wstr(n) do { if ((n)->flags & WSTRCUR) r_free_wstr(n); } while(0)
extern wint_t btowc_cache[];
#define btowc_cache(x) btowc_cache[(x)&0xFF]
extern void init_btowc_cache();
#define is_valid_character(b) (btowc_cache[(b)&0xFF] != WEOF)
-#else
-#define free_wstr(NODE) /* empty */
-#endif
/* re.c */
-extern Regexp *make_regexp(const char *s, size_t len, int ignorecase, int dfa, int canfatal);
+extern Regexp *make_regexp(const char *s, size_t len, bool ignorecase, bool dfa, bool canfatal);
extern int research(Regexp *rp, char *str, int start, size_t len, int flags);
extern void refree(Regexp *rp);
extern void reg_error(const char *s);
@@ -1514,11 +1588,14 @@ extern void resyntax(int syntax);
extern void resetup(void);
extern int avoid_dfa(NODE *re, char *str, size_t len);
extern int reisstring(const char *text, size_t len, Regexp *re, const char *buf);
-extern int remaybelong(const char *text, size_t len);
-extern int isnondecimal(const char *str, int use_locale);
+extern int get_numbase(const char *str, bool use_locale);
/* symbol.c */
-extern NODE *install_symbol(char *name, NODETYPE type);
+extern void load_symbols();
+extern void init_symbol_table();
+extern NODE *symbol_table;
+extern NODE *func_table;
+extern NODE *install_symbol(const char *name, NODETYPE type);
extern NODE *remove_symbol(NODE *r);
extern void destroy_symbol(NODE *r);
extern void release_symbols(NODE *symlist, int keep_globals);
@@ -1535,27 +1612,18 @@ extern AWK_CONTEXT *new_context(void);
extern void push_context(AWK_CONTEXT *ctxt);
extern void pop_context();
extern int in_main_context();
-extern void free_context(AWK_CONTEXT *ctxt, int );
+extern void free_context(AWK_CONTEXT *ctxt, bool keep_globals);
extern NODE **variable_list();
-extern NODE **function_list(int sort);
+extern NODE **function_list(bool sort);
extern void print_vars(NODE **table, Func_print print_func, FILE *fp);
/* floatcomp.c */
-#ifdef VMS /* VMS linker weirdness? */
-#define Ceil gawk_ceil
-#define Floor gawk_floor
-#endif
-
-extern AWKNUM Floor(AWKNUM n);
-extern AWKNUM Ceil(AWKNUM n);
#ifdef HAVE_UINTMAX_T
extern uintmax_t adjust_uint(uintmax_t n);
#else
#define adjust_uint(n) (n)
#endif
-#define INVALID_HANDLE (-1)
-
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
@@ -1581,7 +1649,6 @@ extern uintmax_t adjust_uint(uintmax_t n);
/* For z/OS, from Dave Pitts. EXIT_FAILURE is normally 8, make it 1. */
#ifdef ZOS_USS
-#undef DYNAMIC
#ifdef EXIT_FAILURE
#undef EXIT_FAILURE
@@ -1589,3 +1656,155 @@ extern uintmax_t adjust_uint(uintmax_t n);
#define EXIT_FAILURE 1
#endif
+
+/* ------------------ Inline Functions ------------------ */
+
+/*
+ * These must come last to get all the function declarations and
+ * macro definitions before their bodies.
+ *
+ * This is wasteful if the compiler doesn't support inline. We won't
+ * worry about it until someone complains.
+ */
+
+/* POP_ARRAY --- get the array at the top of the stack */
+
+static inline NODE *
+POP_ARRAY()
+{
+ NODE *t = POP();
+
+ return (t->type == Node_var_array) ? t : force_array(t, true);
+}
+
+/* POP_PARAM --- get the top parameter, array or scalar */
+
+static inline NODE *
+POP_PARAM()
+{
+ NODE *t = POP();
+
+ return (t->type == Node_var_array) ? t : force_array(t, false);
+}
+
+/* POP_SCALAR --- pop the scalar at the top of the stack */
+
+static inline NODE *
+POP_SCALAR()
+{
+ NODE *t = POP();
+
+ if (t->type == Node_var_array)
+ fatal(_("attempt to use array `%s' in a scalar context"), array_vname(t));
+
+ return t;
+}
+
+/* TOP_SCALAR --- get the scalar at the top of the stack */
+
+static inline NODE *
+TOP_SCALAR()
+{
+ NODE *t = TOP();
+
+ if (t->type == Node_var_array)
+ fatal(_("attempt to use array `%s' in a scalar context"), array_vname(t));
+
+ return t;
+}
+
+/* POP_STRING --- pop the string at the top of the stack */
+#define POP_STRING() force_string(POP_SCALAR())
+
+/* TOP_STRING --- get the string at the top of the stack */
+#define TOP_STRING() force_string(TOP_SCALAR())
+
+/* in_array --- return pointer to element in array if there */
+
+static inline NODE *
+in_array(NODE *a, NODE *s)
+{
+ NODE **ret;
+
+ ret = a->aexists(a, s);
+
+ return ret ? *ret : NULL;
+}
+
+#ifdef GAWKDEBUG
+#define dupnode r_dupnode
+#else
+/* dupnode --- up the reference on a node */
+
+static inline NODE *
+dupnode(NODE *n)
+{
+ if ((n->flags & MALLOC) != 0) {
+ n->valref++;
+ return n;
+ }
+ return r_dupnode(n);
+}
+#endif
+
+static inline NODE *
+force_string(NODE *s)
+{
+ if ((s->flags & STRCUR) != 0
+ && (s->stfmt == -1 || s->stfmt == CONVFMTidx)
+ )
+ return s;
+ return format_val(CONVFMT, CONVFMTidx, s);
+}
+
+#ifdef GAWKDEBUG
+#define unref r_unref
+#define force_number str2number
+#else /* not GAWKDEBUG */
+
+static inline void
+unref(NODE *r)
+{
+ if (r != NULL && --r->valref <= 0)
+ r_unref(r);
+}
+
+static inline NODE *
+force_number(NODE *n)
+{
+ return (n->flags & NUMCUR) ? n : str2number(n);
+}
+
+#endif /* GAWKDEBUG */
+
+static inline void *
+emalloc_real(size_t count, const char *where, const char *var, const char *file, int line)
+{
+ void *ret;
+
+ if (count == 0)
+ fatal("%s:%d: emalloc called with zero bytes", file, line);
+
+ ret = (void *) malloc(count);
+ if (ret == NULL)
+ fatal(_("%s:%d:%s: %s: can't allocate %ld bytes of memory (%s)"),
+ file, line, where, var, (long) count, strerror(errno));
+
+ return ret;
+}
+
+static inline void *
+erealloc_real(void *ptr, size_t count, const char *where, const char *var, const char *file, int line)
+{
+ void *ret;
+
+ if (count == 0)
+ fatal("%s:%d: erealloc called with zero bytes", file, line);
+
+ ret = (void *) realloc(ptr, count);
+ if (ret == NULL)
+ fatal(_("%s:%d:%s: %s: can't reallocate %ld bytes of memory (%s)"),
+ file, line, where, var, (long) count, strerror(errno));
+
+ return ret;
+}
diff --git a/awkgram.c b/awkgram.c
index 298e3a0b..6cc78686 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -1,19 +1,19 @@
-/* A Bison parser, made by GNU Bison 2.5. */
+/* A Bison parser, made by GNU Bison 3.0.3. */
/* Bison implementation for Yacc-like parsers in C
-
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
-
+
+ Copyright (C) 1984, 1989-1990, 2000-2015 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 3 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, see <http://www.gnu.org/licenses/>. */
@@ -26,7 +26,7 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
-
+
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
@@ -44,7 +44,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.5"
+#define YYBISON_VERSION "3.0.3"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -58,15 +58,11 @@
/* Pull parsers. */
#define YYPULL 1
-/* Using locations. */
-#define YYLSP_NEEDED 0
/* Copy the first part of user declarations. */
-
-/* Line 268 of yacc.c */
-#line 26 "awkgram.y"
+#line 26 "awkgram.y" /* yacc.c:339 */
#ifdef GAWKDEBUG
#define YYDEBUG 12
@@ -90,12 +86,15 @@ static char **check_params(char *fname, int pcount, INSTRUCTION *list);
static int install_function(char *fname, INSTRUCTION *fi, INSTRUCTION *plist);
static NODE *mk_rexp(INSTRUCTION *exp);
static void param_sanity(INSTRUCTION *arglist);
-static int parms_shadow(INSTRUCTION *pc, int *shadow);
+static int parms_shadow(INSTRUCTION *pc, bool *shadow);
+#ifndef NO_LINT
static int isnoeffect(OPCODE type);
+#endif
static INSTRUCTION *make_assignable(INSTRUCTION *ip);
static void dumpintlstr(const char *str, size_t len);
static void dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2);
static int include_source(INSTRUCTION *file);
+static int load_library(INSTRUCTION *file);
static void next_sourcefile(void);
static char *tokexpand(void);
@@ -115,19 +114,21 @@ static INSTRUCTION *mk_boolean(INSTRUCTION *left, INSTRUCTION *right, INSTRUCTIO
static INSTRUCTION *mk_assignment(INSTRUCTION *lhs, INSTRUCTION *rhs, INSTRUCTION *op);
static INSTRUCTION *mk_getline(INSTRUCTION *op, INSTRUCTION *opt_var, INSTRUCTION *redir, int redirtype);
static NODE *make_regnode(int type, NODE *exp);
-static int count_expressions(INSTRUCTION **list, int isarg);
+static int count_expressions(INSTRUCTION **list, bool isarg);
static INSTRUCTION *optimize_assignment(INSTRUCTION *exp);
static void add_lint(INSTRUCTION *list, LINTTYPE linttype);
-enum defref { FUNC_DEFINE, FUNC_USE };
+enum defref { FUNC_DEFINE, FUNC_USE, FUNC_EXT };
static void func_use(const char *name, enum defref how);
static void check_funcs(void);
static ssize_t read_one_line(int fd, void *buffer, size_t count);
static int one_line_close(int fd);
+static void split_comment(void);
+static void check_comment(void);
-static int want_source = FALSE;
-static int want_regexp; /* lexical scanning kludge */
+static bool want_source = false;
+static bool want_regexp = false; /* lexical scanning kludge */
static char *in_function; /* parsing kludge */
static int rule = 0;
@@ -140,25 +141,24 @@ const char *const ruletab[] = {
"ENDFILE",
};
-static int in_print = FALSE; /* lexical scanning kludge for print */
+static bool in_print = false; /* lexical scanning kludge for print */
static int in_parens = 0; /* lexical scanning kludge for print */
static int sub_counter = 0; /* array dimension counter for use in delete */
static char *lexptr = NULL; /* 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 int lexeof; /* seen EOF for current source? */
+static bool lexeof; /* seen EOF for current source? */
static char *thisline = NULL;
static int in_braces = 0; /* count braces for firstline, lastline in an 'action' */
static int lastline = 0;
static int firstline = 0;
static SRCFILE *sourcefile = NULL; /* current program source */
static int lasttok = 0;
-static int eof_warned = FALSE; /* GLOBAL: want warning for each file */
+static bool eof_warned = false; /* GLOBAL: want warning for each file */
static int break_allowed; /* kludge for break */
static int continue_allowed; /* kludge for continue */
-
#define END_FILE -1000
#define END_SRC -2000
@@ -173,6 +173,7 @@ extern int sourceline;
extern SRCFILE *srcfiles;
extern INSTRUCTION *rule_list;
extern int max_args;
+extern NODE **args_array;
static INSTRUCTION *rule_block[sizeof(ruletab)];
@@ -183,6 +184,14 @@ static INSTRUCTION *ip_end;
static INSTRUCTION *ip_endfile;
static INSTRUCTION *ip_beginfile;
+static INSTRUCTION *comment = NULL;
+static INSTRUCTION *program_comment = NULL;
+static INSTRUCTION *function_comment = NULL;
+static INSTRUCTION *block_comment = NULL;
+
+static bool func_first = true;
+static bool first_rule = true;
+
static inline INSTRUCTION *list_create(INSTRUCTION *x);
static inline INSTRUCTION *list_append(INSTRUCTION *l, INSTRUCTION *x);
static inline INSTRUCTION *list_prepend(INSTRUCTION *l, INSTRUCTION *x);
@@ -192,14 +201,15 @@ extern double fmod(double x, double y);
#define YYSTYPE INSTRUCTION *
+#line 205 "awkgram.c" /* yacc.c:339 */
-/* Line 268 of yacc.c */
-#line 198 "awkgram.c"
-
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
+# ifndef YY_NULLPTR
+# if defined __cplusplus && 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# endif
/* Enabling verbose error messages. */
#ifdef YYERROR_VERBOSE
@@ -209,69 +219,72 @@ extern double fmod(double x, double y);
# define YYERROR_VERBOSE 0
#endif
-/* Enabling the token table. */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
-/* Tokens. */
+/* Token type. */
#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,
- FILENAME = 261,
- YNUMBER = 262,
- YSTRING = 263,
- RELOP = 264,
- IO_OUT = 265,
- IO_IN = 266,
- ASSIGNOP = 267,
- ASSIGN = 268,
- MATCHOP = 269,
- CONCAT_OP = 270,
- SUBSCRIPT = 271,
- LEX_BEGIN = 272,
- LEX_END = 273,
- LEX_IF = 274,
- LEX_ELSE = 275,
- LEX_RETURN = 276,
- LEX_DELETE = 277,
- LEX_SWITCH = 278,
- LEX_CASE = 279,
- LEX_DEFAULT = 280,
- LEX_WHILE = 281,
- LEX_DO = 282,
- LEX_FOR = 283,
- LEX_BREAK = 284,
- LEX_CONTINUE = 285,
- LEX_PRINT = 286,
- LEX_PRINTF = 287,
- LEX_NEXT = 288,
- LEX_EXIT = 289,
- LEX_FUNCTION = 290,
- LEX_BEGINFILE = 291,
- LEX_ENDFILE = 292,
- LEX_GETLINE = 293,
- LEX_NEXTFILE = 294,
- LEX_IN = 295,
- LEX_AND = 296,
- LEX_OR = 297,
- INCREMENT = 298,
- DECREMENT = 299,
- LEX_BUILTIN = 300,
- LEX_LENGTH = 301,
- LEX_EOF = 302,
- LEX_INCLUDE = 303,
- LEX_EVAL = 304,
- NEWLINE = 305,
- SLASH_BEFORE_EQUAL = 306,
- UNARY = 307
- };
+ enum yytokentype
+ {
+ FUNC_CALL = 258,
+ NAME = 259,
+ REGEXP = 260,
+ FILENAME = 261,
+ YNUMBER = 262,
+ YSTRING = 263,
+ RELOP = 264,
+ IO_OUT = 265,
+ IO_IN = 266,
+ ASSIGNOP = 267,
+ ASSIGN = 268,
+ MATCHOP = 269,
+ CONCAT_OP = 270,
+ SUBSCRIPT = 271,
+ LEX_BEGIN = 272,
+ LEX_END = 273,
+ LEX_IF = 274,
+ LEX_ELSE = 275,
+ LEX_RETURN = 276,
+ LEX_DELETE = 277,
+ LEX_SWITCH = 278,
+ LEX_CASE = 279,
+ LEX_DEFAULT = 280,
+ LEX_WHILE = 281,
+ LEX_DO = 282,
+ LEX_FOR = 283,
+ LEX_BREAK = 284,
+ LEX_CONTINUE = 285,
+ LEX_PRINT = 286,
+ LEX_PRINTF = 287,
+ LEX_NEXT = 288,
+ LEX_EXIT = 289,
+ LEX_FUNCTION = 290,
+ LEX_BEGINFILE = 291,
+ LEX_ENDFILE = 292,
+ LEX_GETLINE = 293,
+ LEX_NEXTFILE = 294,
+ LEX_IN = 295,
+ LEX_AND = 296,
+ LEX_OR = 297,
+ INCREMENT = 298,
+ DECREMENT = 299,
+ LEX_BUILTIN = 300,
+ LEX_LENGTH = 301,
+ LEX_EOF = 302,
+ LEX_INCLUDE = 303,
+ LEX_EVAL = 304,
+ LEX_LOAD = 305,
+ NEWLINE = 306,
+ SLASH_BEFORE_EQUAL = 307,
+ UNARY = 308
+ };
#endif
/* Tokens. */
#define FUNC_CALL 258
@@ -321,26 +334,28 @@ extern double fmod(double x, double y);
#define LEX_EOF 302
#define LEX_INCLUDE 303
#define LEX_EVAL 304
-#define NEWLINE 305
-#define SLASH_BEFORE_EQUAL 306
-#define UNARY 307
-
-
-
+#define LEX_LOAD 305
+#define NEWLINE 306
+#define SLASH_BEFORE_EQUAL 307
+#define UNARY 308
+/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
-/* Copy the second part of user declarations. */
+extern YYSTYPE yylval;
+
+int yyparse (void);
-/* Line 343 of yacc.c */
-#line 344 "awkgram.c"
+
+/* Copy the second part of user declarations. */
+
+#line 359 "awkgram.c" /* yacc.c:358 */
#ifdef short
# undef short
@@ -354,11 +369,8 @@ typedef unsigned char yytype_uint8;
#ifdef YYTYPE_INT8
typedef YYTYPE_INT8 yytype_int8;
-#elif (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-typedef signed char yytype_int8;
#else
-typedef short int yytype_int8;
+typedef signed char yytype_int8;
#endif
#ifdef YYTYPE_UINT16
@@ -378,8 +390,7 @@ typedef short int yytype_int16;
# define YYSIZE_T __SIZE_TYPE__
# elif defined size_t
# define YYSIZE_T size_t
-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
+# elif ! defined YYSIZE_T
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# else
@@ -393,37 +404,67 @@ typedef short int yytype_int16;
# if defined YYENABLE_NLS && YYENABLE_NLS
# if ENABLE_NLS
# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
# endif
# endif
# ifndef YY_
-# define YY_(msgid) msgid
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__ \
+ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
+ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+# define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+# define _Noreturn __declspec (noreturn)
+# else
+# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
# endif
#endif
/* Suppress unused-variable warnings by "using" E. */
#if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
+# define YYUSE(E) ((void) (E))
#else
-# define YYUSE(e) /* empty */
+# define YYUSE(E) /* empty */
#endif
-/* Identity function, used to suppress warnings about constant conditions. */
-#ifndef lint
-# define YYID(n) (n)
-#else
-#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
-static int
-YYID (int yyi)
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+ _Pragma ("GCC diagnostic pop")
#else
-static int
-YYID (yyi)
- int yyi;
+# define YY_INITIAL_VALUE(Value) Value
#endif
-{
- return yyi;
-}
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
#if ! defined yyoverflow || YYERROR_VERBOSE
@@ -442,9 +483,9 @@ YYID (yyi)
# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
-# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# endif
@@ -454,8 +495,8 @@ YYID (yyi)
# endif
# ifdef YYSTACK_ALLOC
- /* Pacify GCC's `empty if-body' warning. */
-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+ /* Pacify GCC's 'empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
# ifndef YYSTACK_ALLOC_MAXIMUM
/* The OS might guarantee only one guard page at the bottom of the stack,
and a page size can be as small as 4096 bytes. So we cannot safely
@@ -471,7 +512,7 @@ YYID (yyi)
# endif
# if (defined __cplusplus && ! defined EXIT_SUCCESS \
&& ! ((defined YYMALLOC || defined malloc) \
- && (defined YYFREE || defined free)))
+ && (defined YYFREE || defined free)))
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
@@ -479,15 +520,13 @@ YYID (yyi)
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
-# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
+# if ! defined malloc && ! defined EXIT_SUCCESS
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# ifndef YYFREE
# define YYFREE free
-# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
+# if ! defined free && ! defined EXIT_SUCCESS
void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
@@ -495,7 +534,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-#if (! defined yyoverflow && (! defined __cplusplus || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
/* A type that is properly aligned for any stack member. */
union yyalloc
@@ -520,35 +561,35 @@ union yyalloc
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_alloc, Stack) \
- do \
- { \
- YYSIZE_T yynewbytes; \
- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
- Stack = &yyptr->Stack_alloc; \
- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
- yyptr += yynewbytes / sizeof (*yyptr); \
- } \
- while (YYID (0))
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
#endif
#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
-/* Copy COUNT objects from FROM to TO. The source and destination do
+/* Copy COUNT objects from SRC to DST. 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)))
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
# else
-# define YYCOPY(To, From, Count) \
- do \
- { \
- YYSIZE_T yyi; \
- for (yyi = 0; yyi < (Count); yyi++) \
- (To)[yyi] = (From)[yyi]; \
- } \
- while (YYID (0))
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } \
+ while (0)
# endif
# endif
#endif /* !YYCOPY_NEEDED */
@@ -556,40 +597,42 @@ union yyalloc
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 2
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 1150
+#define YYLAST 1155
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 74
+#define YYNTOKENS 75
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 64
+#define YYNNTS 65
/* YYNRULES -- Number of rules. */
-#define YYNRULES 184
-/* YYNRULES -- Number of states. */
-#define YYNSTATES 329
+#define YYNRULES 188
+/* YYNSTATES -- Number of states. */
+#define YYNSTATES 335
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
+ by yylex, with out-of-bounds checking. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 307
+#define YYMAXUTOK 308
-#define YYTRANSLATE(YYX) \
+#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, without out-of-bounds checking. */
static const yytype_uint8 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, 62, 2, 2, 65, 61, 2, 2,
- 66, 67, 59, 57, 54, 58, 2, 60, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 53, 73,
- 55, 2, 56, 52, 68, 2, 2, 2, 2, 2,
+ 2, 2, 2, 63, 2, 2, 66, 62, 2, 2,
+ 67, 68, 60, 58, 55, 59, 2, 61, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 54, 74,
+ 56, 2, 57, 53, 69, 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, 69, 2, 70, 64, 2, 2, 2, 2, 2,
+ 2, 70, 2, 71, 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, 71, 2, 72, 2, 2, 2, 2,
+ 2, 2, 2, 72, 2, 73, 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,
@@ -607,124 +650,36 @@ static const yytype_uint8 yytranslate[] =
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, 46, 47, 48, 49, 50, 51, 63
+ 45, 46, 47, 48, 49, 50, 51, 52, 64
};
#if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
- YYRHS. */
-static const yytype_uint16 yyprhs[] =
-{
- 0, 0, 3, 4, 7, 10, 13, 16, 19, 22,
- 25, 30, 32, 35, 37, 38, 40, 45, 47, 49,
- 51, 53, 59, 61, 63, 65, 68, 70, 72, 79,
- 80, 84, 86, 88, 89, 92, 95, 97, 100, 103,
- 107, 109, 119, 126, 135, 144, 157, 169, 171, 174,
- 177, 180, 183, 187, 188, 193, 196, 197, 202, 203,
- 208, 213, 215, 216, 218, 219, 222, 225, 231, 236,
- 238, 241, 244, 246, 248, 250, 252, 254, 258, 259,
- 260, 264, 271, 281, 283, 286, 287, 289, 290, 293,
- 294, 296, 298, 302, 304, 307, 311, 312, 314, 315,
- 317, 319, 323, 325, 328, 332, 336, 340, 344, 348,
- 352, 356, 360, 366, 368, 370, 372, 375, 377, 379,
- 381, 383, 385, 387, 390, 392, 396, 400, 404, 408,
- 412, 416, 420, 423, 426, 432, 437, 441, 445, 449,
- 453, 457, 461, 463, 466, 470, 475, 480, 482, 484,
- 486, 489, 492, 494, 496, 499, 502, 504, 507, 512,
- 513, 515, 516, 519, 521, 524, 526, 530, 532, 535,
- 538, 540, 543, 545, 549, 551, 553, 554, 557, 560,
- 562, 563, 565, 567, 569
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const yytype_int16 yyrhs[] =
-{
- 75, 0, -1, -1, 75, 76, -1, 75, 103, -1,
- 75, 47, -1, 75, 1, -1, 78, 79, -1, 78,
- 87, -1, 82, 79, -1, 68, 48, 77, 87, -1,
- 6, -1, 6, 1, -1, 1, -1, -1, 111, -1,
- 111, 54, 104, 111, -1, 17, -1, 18, -1, 36,
- -1, 37, -1, 131, 86, 132, 134, 104, -1, 4,
- -1, 3, -1, 81, -1, 68, 49, -1, 45, -1,
- 46, -1, 35, 80, 66, 106, 133, 104, -1, -1,
- 85, 84, 5, -1, 60, -1, 51, -1, -1, 86,
- 88, -1, 86, 1, -1, 103, -1, 135, 104, -1,
- 135, 104, -1, 131, 86, 132, -1, 102, -1, 23,
- 66, 111, 133, 104, 131, 95, 104, 132, -1, 26,
- 66, 111, 133, 104, 88, -1, 27, 104, 88, 26,
- 66, 111, 133, 104, -1, 28, 66, 4, 40, 128,
- 133, 104, 88, -1, 28, 66, 94, 135, 104, 111,
- 135, 104, 94, 133, 104, 88, -1, 28, 66, 94,
- 135, 104, 135, 104, 94, 133, 104, 88, -1, 89,
- -1, 29, 87, -1, 30, 87, -1, 33, 87, -1,
- 39, 87, -1, 34, 108, 87, -1, -1, 21, 90,
- 108, 87, -1, 91, 87, -1, -1, 98, 92, 99,
- 100, -1, -1, 22, 4, 93, 122, -1, 22, 66,
- 4, 67, -1, 111, -1, -1, 91, -1, -1, 95,
- 96, -1, 95, 1, -1, 24, 97, 136, 104, 86,
- -1, 25, 136, 104, 86, -1, 7, -1, 58, 7,
- -1, 57, 7, -1, 8, -1, 83, -1, 31, -1,
- 32, -1, 109, -1, 66, 110, 133, -1, -1, -1,
- 10, 101, 115, -1, 19, 66, 111, 133, 104, 88,
- -1, 19, 66, 111, 133, 104, 88, 20, 104, 88,
- -1, 50, -1, 103, 50, -1, -1, 103, -1, -1,
- 55, 116, -1, -1, 107, -1, 4, -1, 107, 137,
- 4, -1, 1, -1, 107, 1, -1, 107, 137, 1,
- -1, -1, 111, -1, -1, 110, -1, 111, -1, 110,
- 137, 111, -1, 1, -1, 110, 1, -1, 110, 1,
- 111, -1, 110, 137, 1, -1, 129, 112, 111, -1,
- 111, 41, 111, -1, 111, 42, 111, -1, 111, 14,
- 111, -1, 111, 40, 128, -1, 111, 114, 111, -1,
- 111, 52, 111, 53, 111, -1, 115, -1, 13, -1,
- 12, -1, 51, 13, -1, 9, -1, 55, -1, 113,
- -1, 56, -1, 116, -1, 117, -1, 115, 116, -1,
- 118, -1, 116, 64, 116, -1, 116, 59, 116, -1,
- 116, 60, 116, -1, 116, 61, 116, -1, 116, 57,
- 116, -1, 116, 58, 116, -1, 38, 121, 105, -1,
- 129, 43, -1, 129, 44, -1, 66, 110, 133, 40,
- 128, -1, 115, 11, 38, 121, -1, 117, 64, 116,
- -1, 117, 59, 116, -1, 117, 60, 116, -1, 117,
- 61, 116, -1, 117, 57, 116, -1, 117, 58, 116,
- -1, 83, -1, 62, 116, -1, 66, 111, 133, -1,
- 45, 66, 109, 133, -1, 46, 66, 109, 133, -1,
- 46, -1, 119, -1, 129, -1, 43, 129, -1, 44,
- 129, -1, 7, -1, 8, -1, 58, 116, -1, 57,
- 116, -1, 120, -1, 68, 120, -1, 3, 66, 109,
- 133, -1, -1, 129, -1, -1, 123, 16, -1, 124,
- -1, 123, 124, -1, 125, -1, 69, 110, 70, -1,
- 125, -1, 126, 125, -1, 126, 16, -1, 4, -1,
- 4, 127, -1, 128, -1, 65, 118, 130, -1, 43,
- -1, 44, -1, -1, 71, 104, -1, 72, 104, -1,
- 67, -1, -1, 135, -1, 73, -1, 53, -1, 54,
- 104, -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 191, 191, 193, 198, 199, 203, 215, 219, 230,
- 236, 244, 252, 254, 260, 261, 263, 289, 300, 311,
- 317, 326, 336, 338, 340, 346, 351, 352, 356, 375,
- 374, 408, 410, 415, 416, 429, 434, 435, 439, 441,
- 443, 450, 540, 582, 624, 737, 744, 751, 761, 770,
- 779, 788, 803, 819, 818, 842, 854, 854, 948, 948,
- 973, 996, 1002, 1003, 1009, 1010, 1017, 1022, 1034, 1048,
- 1050, 1056, 1061, 1063, 1071, 1073, 1082, 1083, 1091, 1096,
- 1096, 1107, 1111, 1119, 1120, 1123, 1125, 1130, 1131, 1140,
- 1141, 1146, 1151, 1157, 1159, 1161, 1168, 1169, 1175, 1176,
- 1181, 1183, 1188, 1190, 1192, 1194, 1200, 1207, 1209, 1211,
- 1227, 1237, 1244, 1246, 1251, 1253, 1255, 1263, 1265, 1270,
- 1272, 1277, 1279, 1281, 1331, 1333, 1335, 1337, 1339, 1341,
- 1343, 1345, 1368, 1373, 1378, 1403, 1409, 1411, 1413, 1415,
- 1417, 1419, 1424, 1428, 1459, 1461, 1467, 1473, 1486, 1487,
- 1488, 1493, 1498, 1502, 1506, 1519, 1532, 1537, 1573, 1591,
- 1592, 1598, 1599, 1604, 1606, 1613, 1630, 1647, 1649, 1656,
- 1661, 1669, 1679, 1691, 1700, 1704, 1708, 1712, 1716, 1720,
- 1723, 1725, 1729, 1733, 1737
+ 0, 204, 204, 206, 211, 212, 216, 228, 233, 244,
+ 250, 255, 263, 271, 273, 278, 286, 288, 294, 302,
+ 312, 342, 356, 370, 378, 389, 401, 403, 405, 411,
+ 416, 417, 421, 456, 455, 489, 491, 496, 502, 530,
+ 535, 536, 540, 542, 544, 551, 641, 683, 725, 838,
+ 845, 852, 862, 871, 880, 889, 900, 916, 915, 939,
+ 951, 951, 1049, 1049, 1082, 1112, 1118, 1119, 1125, 1126,
+ 1133, 1138, 1150, 1164, 1166, 1174, 1179, 1181, 1189, 1191,
+ 1200, 1201, 1209, 1214, 1214, 1225, 1229, 1237, 1238, 1241,
+ 1243, 1248, 1249, 1258, 1259, 1264, 1269, 1275, 1277, 1279,
+ 1286, 1287, 1293, 1294, 1299, 1301, 1306, 1308, 1316, 1321,
+ 1330, 1337, 1339, 1341, 1357, 1367, 1374, 1376, 1381, 1383,
+ 1385, 1393, 1395, 1400, 1402, 1407, 1409, 1411, 1461, 1463,
+ 1465, 1467, 1469, 1471, 1473, 1475, 1489, 1494, 1499, 1524,
+ 1530, 1532, 1534, 1536, 1538, 1540, 1545, 1549, 1581, 1583,
+ 1589, 1595, 1608, 1609, 1610, 1615, 1620, 1624, 1628, 1643,
+ 1656, 1661, 1697, 1715, 1716, 1722, 1723, 1728, 1730, 1737,
+ 1754, 1771, 1773, 1780, 1785, 1793, 1803, 1815, 1824, 1828,
+ 1832, 1836, 1840, 1844, 1847, 1849, 1853, 1857, 1861
};
#endif
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+#if YYDEBUG || YYERROR_VERBOSE || 0
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
@@ -738,28 +693,28 @@ static const char *const yytname[] =
"LEX_FUNCTION", "LEX_BEGINFILE", "LEX_ENDFILE", "LEX_GETLINE",
"LEX_NEXTFILE", "LEX_IN", "LEX_AND", "LEX_OR", "INCREMENT", "DECREMENT",
"LEX_BUILTIN", "LEX_LENGTH", "LEX_EOF", "LEX_INCLUDE", "LEX_EVAL",
- "NEWLINE", "SLASH_BEFORE_EQUAL", "'?'", "':'", "','", "'<'", "'>'",
- "'+'", "'-'", "'*'", "'/'", "'%'", "'!'", "UNARY", "'^'", "'$'", "'('",
- "')'", "'@'", "'['", "']'", "'{'", "'}'", "';'", "$accept", "program",
- "rule", "source", "pattern", "action", "func_name", "lex_builtin",
- "function_prologue", "regexp", "$@1", "a_slash", "statements",
- "statement_term", "statement", "non_compound_stmt", "$@2", "simple_stmt",
- "$@3", "$@4", "opt_simple_stmt", "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",
- "simp_exp_nc", "non_post_simp_exp", "func_call", "direct_func_call",
- "opt_variable", "delete_subscript_list", "delete_subscript",
- "delete_exp_list", "bracketed_exp_list", "subscript", "subscript_list",
- "simple_variable", "variable", "opt_incdec", "l_brace", "r_brace",
- "r_paren", "opt_semi", "semi", "colon", "comma", 0
+ "LEX_LOAD", "NEWLINE", "SLASH_BEFORE_EQUAL", "'?'", "':'", "','", "'<'",
+ "'>'", "'+'", "'-'", "'*'", "'/'", "'%'", "'!'", "UNARY", "'^'", "'$'",
+ "'('", "')'", "'@'", "'['", "']'", "'{'", "'}'", "';'", "$accept",
+ "program", "rule", "source", "library", "pattern", "action", "func_name",
+ "lex_builtin", "function_prologue", "regexp", "$@1", "a_slash",
+ "statements", "statement_term", "statement", "non_compound_stmt", "$@2",
+ "simple_stmt", "$@3", "$@4", "opt_simple_stmt", "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", "simp_exp_nc", "non_post_simp_exp",
+ "func_call", "direct_func_call", "opt_variable", "delete_subscript_list",
+ "delete_subscript", "delete_exp_list", "bracketed_exp_list", "subscript",
+ "subscript_list", "simple_variable", "variable", "opt_incdec", "l_brace",
+ "r_brace", "r_paren", "opt_semi", "semi", "colon", "comma", YY_NULLPTR
};
#endif
# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
- token YYLEX-NUM. */
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+ (internal) symbol number NUM (which must be that of a token). */
static const yytype_uint16 yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
@@ -767,541 +722,493 @@ static const yytype_uint16 yytoknum[] =
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, 301, 302, 303, 304,
- 305, 306, 63, 58, 44, 60, 62, 43, 45, 42,
- 47, 37, 33, 307, 94, 36, 40, 41, 64, 91,
- 93, 123, 125, 59
+ 305, 306, 307, 63, 58, 44, 60, 62, 43, 45,
+ 42, 47, 37, 33, 308, 94, 36, 40, 41, 64,
+ 91, 93, 123, 125, 59
};
# endif
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const yytype_uint8 yyr1[] =
-{
- 0, 74, 75, 75, 75, 75, 75, 76, 76, 76,
- 76, 77, 77, 77, 78, 78, 78, 78, 78, 78,
- 78, 79, 80, 80, 80, 80, 81, 81, 82, 84,
- 83, 85, 85, 86, 86, 86, 87, 87, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88, 89, 89,
- 89, 89, 89, 90, 89, 89, 92, 91, 93, 91,
- 91, 91, 94, 94, 95, 95, 95, 96, 96, 97,
- 97, 97, 97, 97, 98, 98, 99, 99, 100, 101,
- 100, 102, 102, 103, 103, 104, 104, 105, 105, 106,
- 106, 107, 107, 107, 107, 107, 108, 108, 109, 109,
- 110, 110, 110, 110, 110, 110, 111, 111, 111, 111,
- 111, 111, 111, 111, 112, 112, 112, 113, 113, 114,
- 114, 115, 115, 115, 116, 116, 116, 116, 116, 116,
- 116, 116, 116, 116, 116, 117, 117, 117, 117, 117,
- 117, 117, 118, 118, 118, 118, 118, 118, 118, 118,
- 118, 118, 118, 118, 118, 118, 119, 119, 120, 121,
- 121, 122, 122, 123, 123, 124, 125, 126, 126, 127,
- 128, 128, 129, 129, 130, 130, 130, 131, 132, 133,
- 134, 134, 135, 136, 137
-};
+#define YYPACT_NINF -273
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-static const yytype_uint8 yyr2[] =
-{
- 0, 2, 0, 2, 2, 2, 2, 2, 2, 2,
- 4, 1, 2, 1, 0, 1, 4, 1, 1, 1,
- 1, 5, 1, 1, 1, 2, 1, 1, 6, 0,
- 3, 1, 1, 0, 2, 2, 1, 2, 2, 3,
- 1, 9, 6, 8, 8, 12, 11, 1, 2, 2,
- 2, 2, 3, 0, 4, 2, 0, 4, 0, 4,
- 4, 1, 0, 1, 0, 2, 2, 5, 4, 1,
- 2, 2, 1, 1, 1, 1, 1, 3, 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, 1, 2, 1, 3, 3, 3, 3, 3,
- 3, 3, 2, 2, 5, 4, 3, 3, 3, 3,
- 3, 3, 1, 2, 3, 4, 4, 1, 1, 1,
- 2, 2, 1, 1, 2, 2, 1, 2, 4, 0,
- 1, 0, 2, 1, 2, 1, 3, 1, 2, 2,
- 1, 2, 1, 3, 1, 1, 0, 2, 2, 1,
- 0, 1, 1, 1, 2
-};
+#define yypact_value_is_default(Yystate) \
+ (!!((Yystate) == (-273)))
-/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
- Performed when YYTABLE doesn't specify something else to do. Zero
- means the default is an error. */
-static const yytype_uint8 yydefact[] =
+#define YYTABLE_NINF -104
+
+#define yytable_value_is_error(Yytable_value) \
+ (!!((Yytable_value) == (-104)))
+
+ /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+static const yytype_int16 yypact[] =
{
- 2, 0, 1, 6, 0, 170, 152, 153, 17, 18,
- 0, 19, 20, 159, 0, 0, 0, 147, 5, 83,
- 32, 0, 0, 31, 0, 0, 0, 0, 3, 0,
- 0, 142, 29, 4, 15, 113, 121, 122, 124, 148,
- 156, 172, 149, 0, 0, 167, 0, 171, 23, 22,
- 26, 27, 0, 0, 24, 87, 160, 150, 151, 0,
- 0, 0, 155, 149, 154, 143, 0, 176, 149, 102,
- 0, 100, 0, 157, 85, 182, 7, 8, 36, 33,
- 85, 9, 0, 84, 117, 0, 0, 0, 0, 0,
- 85, 118, 120, 119, 0, 0, 123, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 115,
- 114, 132, 133, 0, 0, 0, 0, 100, 0, 169,
- 168, 25, 0, 0, 131, 0, 0, 0, 174, 175,
- 173, 103, 85, 179, 0, 0, 144, 13, 0, 0,
- 86, 177, 0, 37, 30, 109, 110, 107, 108, 0,
- 0, 111, 159, 129, 130, 126, 127, 128, 125, 140,
- 141, 137, 138, 139, 136, 116, 106, 158, 166, 93,
- 91, 0, 0, 88, 145, 146, 104, 184, 0, 105,
- 101, 12, 10, 35, 0, 53, 0, 0, 0, 85,
- 0, 0, 0, 74, 75, 0, 96, 0, 85, 34,
- 47, 0, 56, 40, 61, 33, 180, 85, 0, 16,
- 135, 85, 94, 0, 134, 0, 96, 58, 0, 0,
- 0, 0, 62, 48, 49, 50, 0, 97, 51, 178,
- 55, 0, 0, 85, 181, 38, 112, 28, 95, 92,
- 0, 0, 161, 0, 0, 0, 0, 170, 63, 0,
- 52, 0, 78, 76, 39, 21, 85, 54, 59, 0,
- 163, 165, 60, 85, 85, 0, 0, 85, 0, 79,
- 57, 0, 162, 164, 0, 0, 0, 0, 0, 77,
- 0, 81, 64, 42, 0, 85, 0, 85, 80, 85,
- 0, 85, 0, 85, 62, 0, 66, 0, 0, 65,
- 0, 43, 44, 62, 0, 82, 69, 72, 0, 0,
- 73, 0, 183, 85, 41, 0, 85, 71, 70, 85,
- 33, 85, 0, 33, 0, 0, 46, 0, 45
+ -273, 376, -273, -273, -27, -21, -273, -273, -273, -273,
+ 157, -273, -273, 11, 11, 11, -5, -3, -273, -273,
+ -273, 1019, 1019, -273, 1019, 1065, 821, 116, -273, -20,
+ 1, -273, -273, 35, 758, 992, 252, 296, -273, -273,
+ -273, -273, 233, 789, 821, -273, 2, -273, -273, -273,
+ -273, -273, 63, 54, -273, 69, -273, -273, -273, 789,
+ 789, 127, 87, 115, 87, 87, 1019, 131, -273, -273,
+ 55, 295, 40, 47, -273, 83, -273, -273, -273, 35,
+ -273, 83, -273, 151, -273, -273, 1019, 132, 1019, 1019,
+ 1019, 83, -273, -273, -273, 1019, 124, 252, 1019, 1019,
+ 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019,
+ -273, -273, -273, -273, 152, 1019, 100, 16, 1034, 37,
+ -273, -273, -273, 43, 1019, -273, 100, 100, 295, -273,
+ -273, -273, 1019, 83, -273, 137, 867, -273, -273, 75,
+ -19, -273, 77, -19, 35, -273, 596, -273, -273, 123,
+ -273, 141, 175, 1098, 1019, 161, 11, -26, -26, 87,
+ 87, 87, 87, -26, -26, 87, 87, 87, 87, -273,
+ 1034, -273, -273, -273, -273, 100, 65, 252, -273, -273,
+ 1034, -273, 132, -273, 1034, -273, -273, -273, -273, -273,
+ 104, -273, 26, 118, 119, 83, 121, -19, -19, -273,
+ -273, -19, 1019, -19, 83, -273, -273, -19, -273, -273,
+ 1034, -273, 117, 83, 1019, 1034, -273, 83, -273, 112,
+ -273, 1019, 1019, -273, 188, 1019, 1019, 710, 900, -273,
+ -273, -273, -19, 1034, -273, -273, -273, 642, 596, 83,
+ -273, -273, 1034, -273, -273, -273, 295, -19, -21, 126,
+ 295, 295, 169, -13, -273, 117, -273, 821, 186, -273,
+ -273, -273, 83, -273, -273, 13, -273, -273, -273, 83,
+ 83, 139, 132, 83, 55, -273, -273, 710, -273, -273,
+ 1, 710, 1019, 100, 743, 137, 1019, 192, -273, -273,
+ 295, 83, 286, 83, 992, 83, 44, 83, 710, 83,
+ 946, 710, -273, 247, 154, -273, 156, -273, -273, 946,
+ 100, -273, -273, -273, 226, 228, -273, 154, -273, 83,
+ -273, 100, 83, -273, -273, 83, -273, 83, 710, -273,
+ 448, 710, -273, 522, -273
};
-/* YYDEFGOTO[NTERM-NUM]. */
-static const yytype_int16 yydefgoto[] =
+ /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint8 yydefact[] =
{
- -1, 1, 28, 139, 29, 76, 53, 54, 30, 31,
- 82, 32, 142, 77, 199, 200, 216, 201, 231, 242,
- 249, 290, 299, 311, 202, 252, 270, 280, 203, 140,
- 141, 124, 171, 172, 226, 115, 116, 204, 114, 93,
- 94, 35, 36, 37, 38, 39, 40, 55, 258, 259,
- 260, 45, 46, 47, 41, 42, 130, 205, 206, 136,
- 233, 207, 313, 135
+ 2, 0, 1, 6, 0, 174, 156, 157, 21, 22,
+ 0, 23, 24, 163, 0, 0, 0, 151, 5, 87,
+ 36, 0, 0, 35, 0, 0, 0, 0, 3, 0,
+ 0, 146, 33, 4, 19, 117, 125, 126, 128, 152,
+ 160, 176, 153, 0, 0, 171, 0, 175, 27, 26,
+ 30, 31, 0, 0, 28, 91, 164, 154, 155, 0,
+ 0, 0, 159, 153, 158, 147, 0, 180, 153, 106,
+ 0, 104, 0, 0, 161, 89, 186, 7, 8, 40,
+ 37, 89, 9, 0, 88, 121, 0, 0, 0, 0,
+ 0, 89, 122, 124, 123, 0, 0, 127, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 119, 118, 136, 137, 0, 0, 0, 0, 104, 0,
+ 173, 172, 29, 0, 0, 135, 0, 0, 0, 178,
+ 179, 177, 107, 89, 183, 0, 0, 148, 14, 0,
+ 0, 17, 0, 0, 90, 181, 0, 41, 34, 113,
+ 114, 111, 112, 0, 0, 115, 163, 133, 134, 130,
+ 131, 132, 129, 144, 145, 141, 142, 143, 140, 120,
+ 110, 162, 170, 97, 95, 0, 0, 92, 149, 150,
+ 108, 188, 0, 109, 105, 13, 10, 16, 11, 39,
+ 0, 57, 0, 0, 0, 89, 0, 0, 0, 78,
+ 79, 0, 100, 0, 89, 38, 51, 0, 60, 44,
+ 65, 37, 184, 89, 0, 20, 139, 89, 98, 0,
+ 138, 0, 100, 62, 0, 0, 0, 0, 66, 52,
+ 53, 54, 0, 101, 55, 182, 59, 0, 0, 89,
+ 185, 42, 116, 32, 99, 96, 0, 0, 165, 0,
+ 0, 0, 0, 174, 67, 0, 56, 0, 82, 80,
+ 43, 25, 89, 58, 63, 0, 167, 169, 64, 89,
+ 89, 0, 0, 89, 0, 83, 61, 0, 166, 168,
+ 0, 0, 0, 0, 0, 81, 0, 85, 68, 46,
+ 0, 89, 0, 89, 84, 89, 0, 89, 0, 89,
+ 66, 0, 70, 0, 0, 69, 0, 47, 48, 66,
+ 0, 86, 73, 76, 0, 0, 77, 0, 187, 89,
+ 45, 0, 89, 75, 74, 89, 37, 89, 0, 37,
+ 0, 0, 50, 0, 49
};
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
- STATE-NUM. */
-#define YYPACT_NINF -264
-static const yytype_int16 yypact[] =
+ /* YYPGOTO[NTERM-NUM]. */
+static const yytype_int16 yypgoto[] =
{
- -264, 367, -264, -264, -31, -42, -264, -264, -264, -264,
- 165, -264, -264, 46, 46, 46, -29, -27, -264, -264,
- -264, 1010, 1010, -264, 1010, 1055, 836, 27, -264, -35,
- -7, -264, -264, 17, 1088, 984, 288, 362, -264, -264,
- -264, -264, 146, 768, 836, -264, 1, -264, -264, -264,
- -264, -264, 60, -18, -264, 11, -264, -264, -264, 768,
- 768, 74, 52, 9, 52, 52, 1010, 13, -264, -264,
- 53, 341, 28, -264, 79, -264, -264, -264, 17, -264,
- 79, -264, 119, -264, -264, 1010, 148, 1010, 1010, 1010,
- 79, -264, -264, -264, 1010, 122, 288, 1010, 1010, 1010,
- 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, -264,
- -264, -264, -264, 151, 1010, 94, 81, 1094, 40, -264,
- -264, -264, 45, 1010, -264, 94, 94, 341, -264, -264,
- -264, 1010, 79, -264, 125, 862, -264, -264, 82, -22,
- 17, -264, 584, -264, -264, 62, -264, 212, 267, 301,
- 1010, 118, 46, 127, 127, 52, 52, 52, 52, 127,
- 127, 52, 52, 52, 52, -264, 1094, -264, -264, -264,
- -264, 94, 61, 288, -264, -264, 1094, -264, 148, -264,
- 1094, -264, -264, -264, 105, -264, 10, 109, 112, 79,
- 113, -22, -22, -264, -264, -22, 1010, -22, 79, -264,
- -264, -22, -264, -264, 1094, -264, 107, 79, 1010, 1094,
- -264, 79, -264, 43, -264, 1010, 1010, -264, 180, 1010,
- 1010, 697, 907, -264, -264, -264, -22, 1094, -264, -264,
- -264, 630, 584, 79, -264, -264, 1094, -264, -264, -264,
- 341, -22, -42, 126, 341, 341, 166, -14, -264, 107,
- -264, 836, 190, -264, -264, -264, 79, -264, -264, 16,
- -264, -264, -264, 79, 79, 136, 148, 79, 53, -264,
- -264, 697, -264, -264, -7, 697, 1010, 94, 742, 125,
- 1010, 186, -264, -264, 341, 79, 278, 79, 984, 79,
- 132, 79, 697, 79, 939, 697, -264, 240, 155, -264,
- 137, -264, -264, 939, 94, -264, -264, -264, 205, 206,
- -264, 155, -264, 79, -264, 94, 79, -264, -264, 79,
- -264, 79, 697, -264, 438, 697, -264, 511, -264
+ -273, -273, -273, -273, -273, -273, 208, -273, -273, -273,
+ -64, -273, -273, -202, 71, -58, -273, -273, -218, -273,
+ -273, -272, -273, -273, -273, -273, -273, -273, -273, -273,
+ 50, 76, -273, -273, -273, 19, -54, -23, -1, -273,
+ -273, -273, -44, 39, -273, 224, -273, -11, 94, -273,
+ -273, -7, -38, -273, -273, -73, -2, -273, -28, -231,
+ -46, -273, -25, -57, 85
};
-/* YYPGOTO[NTERM-NUM]. */
-static const yytype_int16 yypgoto[] =
+ /* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
{
- -264, -264, -264, -264, -264, 187, -264, -264, -264, -74,
- -264, -264, -197, 98, -203, -264, -264, -213, -264, -264,
- -263, -264, -264, -264, -264, -264, -264, -264, -264, 44,
- 73, -264, -264, -264, 18, -54, -23, -1, -264, -264,
- -264, -55, 39, -264, 202, -264, 124, 77, -264, -264,
- -19, -39, -264, -264, -70, -2, -264, -28, -222, -46,
- -264, -25, -79, 70
+ -1, 1, 28, 140, 143, 29, 77, 53, 54, 30,
+ 31, 83, 32, 146, 78, 205, 206, 222, 207, 237,
+ 248, 255, 296, 305, 317, 208, 258, 276, 286, 209,
+ 144, 145, 125, 175, 176, 232, 116, 117, 210, 115,
+ 94, 95, 35, 36, 37, 38, 39, 40, 55, 264,
+ 265, 266, 45, 46, 47, 41, 42, 131, 211, 212,
+ 137, 239, 213, 319, 136
};
-/* 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 YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -100
+ /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_int16 yytable[] =
{
- 34, 79, 79, 70, 80, 125, 126, 120, 232, 248,
- 254, 56, 57, 58, 217, 19, 146, 119, 246, 63,
- 63, 118, 63, 68, 134, 71, 266, 44, 19, 137,
- 4, 304, 272, 63, 138, 43, 74, 59, 75, 60,
- 315, 131, 117, 117, 238, 33, 169, 239, 122, 170,
- 5, 75, 111, 112, 131, 44, 128, 129, 117, 117,
- 62, 64, 212, 65, 74, 127, 123, 83, 281, 167,
- 44, 84, 283, 78, 96, 72, 218, 4, 314, 174,
- 175, 248, 131, 181, 145, 44, 147, 148, 149, 302,
- 248, -99, 305, 151, 132, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 132, 214, 121,
- 168, 25, -89, 166, 80, 132, 102, 91, 92, 326,
- 133, 63, 328, 324, 144, 211, 327, -100, -90, 19,
- 176, -99, -11, 296, 180, 132, 153, 154, 155, 156,
- 157, 158, 159, 160, 161, 162, 163, 164, -99, 209,
- 56, 73, 5, 143, -99, -11, 297, 298, 109, 110,
- 152, 133, 173, 150, 165, 178, 80, 80, 48, 49,
- 80, 215, 80, -100, -100, 219, 80, 253, 220, 222,
- 75, 234, 19, 78, 243, 73, 99, 100, 101, 111,
- 112, 102, 265, 262, 256, 227, 277, 113, 263, 264,
- 269, 80, 276, 261, -85, 177, 289, 236, 312, 198,
- 50, 51, 317, 318, 240, 227, 80, 81, 244, 245,
- 261, 84, 279, 310, 267, 288, 85, 67, 268, 210,
- 117, 285, 319, 52, 241, 78, 78, 182, 291, 78,
- 273, 78, 213, 0, 0, 78, 282, 306, 307, 0,
- 71, 0, 86, 287, 0, 0, 0, 0, 316, 0,
- 0, 293, 221, 0, 0, 0, 0, 91, 92, 321,
- 78, 229, 0, 0, 0, 284, 84, 286, 63, 0,
- 235, 85, 0, 0, 237, 78, 63, 84, 0, 223,
- 224, 20, 85, 225, 0, 228, 0, 308, 309, 230,
- 23, 0, 0, 0, 0, 0, 255, 86, 87, 0,
- 84, 0, 0, 0, 0, 85, 0, 0, 86, 87,
- 88, 0, 91, 92, 250, 0, 0, 96, 0, 271,
- 89, 0, 0, 91, 92, 0, 274, 275, 0, 257,
- 278, 86, 87, 88, 0, 97, 98, 99, 100, 101,
- 84, 75, 102, 89, 208, 85, 91, 92, 292, 0,
- 294, 0, 295, 300, 301, 0, 303, 2, 3, 0,
- 4, 5, 0, 0, 6, 7, 0, 0, 0, 0,
- 0, 86, 87, 88, 8, 9, 320, 0, 0, 322,
- 0, 0, 323, 89, 325, 0, 91, 92, 0, 0,
- 0, 0, 10, 11, 12, 13, 0, 0, 133, 0,
- 14, 15, 16, 17, 18, 0, 0, 19, 20, 103,
- 104, 105, 106, 107, 21, 22, 108, 23, 0, 24,
- 0, 0, 25, 26, 0, 27, 0, 0, -14, 183,
- -14, 4, 5, 0, 0, 6, 7, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 184, 0, 185,
- 186, 187, -68, -68, 188, 189, 190, 191, 192, 193,
- 194, 195, 196, 0, 0, 0, 13, 197, 0, 0,
- 0, 14, 15, 16, 17, 0, 0, 0, -68, 20,
- 0, 0, 0, 0, 0, 21, 22, 0, 23, 0,
- 24, 0, 0, 25, 26, 0, 61, 0, 0, 74,
- -68, 75, 183, 0, 4, 5, 0, 0, 6, 7,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 184, 0, 185, 186, 187, -67, -67, 188, 189, 190,
- 191, 192, 193, 194, 195, 196, 0, 0, 0, 13,
- 197, 0, 0, 0, 14, 15, 16, 17, 0, 0,
- 0, -67, 20, 0, 0, 0, 0, 0, 21, 22,
- 0, 23, 0, 24, 0, 0, 25, 26, 0, 61,
- 0, 0, 74, -67, 75, 183, 0, 4, 5, 0,
- 0, 6, 7, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 184, 0, 185, 186, 187, 0, 0,
- 188, 189, 190, 191, 192, 193, 194, 195, 196, 0,
- 0, 0, 13, 197, 0, 0, 0, 14, 15, 16,
- 17, 69, 0, 4, 5, 20, 0, 6, 7, 0,
- -98, 21, 22, 0, 23, 0, 24, 0, 0, 25,
- 26, 0, 61, 0, 0, 74, 198, 75, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 13, 0,
- 0, 0, 0, 14, 15, 16, 17, 0, 0, 0,
- -98, 20, 0, 0, 0, 0, 0, 21, 22, 0,
- 23, 0, 24, 0, 0, 25, 251, -98, 61, 0,
- 4, 5, 0, -98, 6, 7, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 184, 0, 185, 186,
- 187, 0, 0, 188, 189, 190, 191, 192, 193, 194,
- 195, 196, 0, 0, 0, 13, 197, 0, 0, 0,
- 14, 15, 16, 17, 0, 4, 5, 0, 20, 6,
- 7, 0, 0, 0, 21, 22, 0, 23, 0, 24,
- 0, 0, 25, 26, 0, 61, 0, 0, 74, 69,
- 75, 4, 5, 0, 0, 6, 7, 0, 0, 0,
- 13, 0, 0, 0, 0, 14, 15, 16, 17, 0,
- 0, 0, 0, 20, 0, 0, 0, 0, 0, 21,
- 22, 0, 23, 0, 24, 0, 13, 25, 26, 0,
- 61, 14, 15, 16, 17, 75, 0, 0, 0, 20,
- 0, 0, 0, 0, 0, 21, 22, 0, 23, 0,
- 24, 0, 0, 25, 26, -98, 61, 69, 0, 4,
+ 34, 80, 80, 70, 81, 126, 127, 260, 121, 238,
+ 254, 56, 57, 58, 150, 5, 74, 132, 120, 63,
+ 63, 119, 63, 68, 135, 71, -103, 272, 310, 278,
+ 223, 19, 19, 63, 100, 101, 102, 321, 132, 103,
+ 43, 138, 118, 118, 173, 302, 139, 174, 141, 44,
+ 74, 33, 75, 142, 76, 76, 132, 44, 118, 118,
+ 62, 64, 59, 65, 60, 128, 218, -103, 303, 304,
+ 171, 133, 44, 75, 97, 320, 185, 25, 187, 79,
+ 178, 179, 254, 44, -103, 149, 84, 151, 152, 153,
+ -103, 254, 133, 224, 155, 19, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, 172, 220,
+ 133, -93, 122, 244, 170, 81, 245, -89, 81, 4,
+ 133, 123, 63, 134, 330, 124, -12, 333, -15, 217,
+ 4, 180, 85, -94, 19, 184, 5, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167, 168, -12,
+ 85, -15, 103, 215, 56, 86, 148, 147, 112, 113,
+ 48, 49, 156, 177, 72, 169, 73, 154, 134, 252,
+ -104, 221, 81, 81, 129, 130, 81, 182, 81, 92,
+ 93, 87, 81, 259, 85, 225, 226, 240, 228, 86,
+ 79, 76, 249, 79, 268, 271, 275, 92, 93, 283,
+ 262, 233, 50, 51, 269, 270, 282, 81, 318, 181,
+ 267, 186, 295, 242, 188, 87, 88, -104, -104, 287,
+ 246, 233, 81, 289, 250, 251, 52, 267, 285, 204,
+ 273, 92, 93, 323, 274, 324, 118, 291, 82, 316,
+ 308, 247, 294, 311, 297, 110, 111, 79, 79, 67,
+ 216, 79, 288, 79, 312, 313, 71, 79, 279, 293,
+ 325, 219, 0, 0, 322, 0, 0, 299, 229, 230,
+ 332, 227, 231, 334, 234, 327, 112, 113, 236, 0,
+ 235, 290, 79, 292, 63, 114, 0, 0, 0, 241,
+ 0, 0, 63, 243, 0, 85, 0, 79, 0, 20,
+ 86, 0, 0, 256, 85, 314, 315, 0, 23, 86,
+ 98, 99, 100, 101, 102, 261, 0, 103, 263, 0,
+ 0, 0, 0, 0, 0, 0, 87, 88, 89, 0,
+ 0, 0, 0, 97, 0, 87, 88, 89, 277, 90,
+ 0, 0, 92, 93, 0, 280, 281, 0, 90, 284,
+ 0, 92, 93, 0, 104, 105, 106, 107, 108, 0,
+ 76, 109, 0, 134, 0, 0, 0, 298, 0, 300,
+ 0, 301, 306, 307, 0, 309, 2, 3, 0, 4,
5, 0, 0, 6, 7, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 179, 0, 4, 5, 0, 0, 6,
- 7, 0, 0, 0, 13, 0, 0, 0, 0, 14,
- 15, 16, 17, 0, 0, 0, 0, 20, 0, 0,
- 0, 0, 0, 21, 22, 0, 23, 0, 24, 0,
- 13, 25, 26, 0, 61, 14, 15, 16, 17, 0,
- 4, 247, 0, 20, 6, 7, 0, 0, 0, 21,
- 22, 0, 23, 0, 24, 0, 0, 25, 26, 186,
- 61, 0, 0, 0, 0, 0, 0, 0, 193, 194,
- 0, 0, 4, 5, 0, 13, 6, 7, 0, 0,
- 14, 15, 16, 17, 0, 0, 0, 0, 20, 0,
- 0, 186, 0, 0, 21, 22, 0, 23, 0, 24,
- 193, 194, 25, 26, 0, 61, 0, 13, 0, 0,
- 0, 0, 14, 15, 16, 17, 0, 4, 5, 0,
- 20, 6, 7, 0, 0, 95, 21, 22, 0, 23,
+ 0, 0, 0, 8, 9, 326, 0, 0, 328, 0,
+ 0, 329, 0, 331, 0, 0, 0, 0, 0, 0,
+ 0, 10, 11, 12, 13, 0, 0, 0, 0, 14,
+ 15, 16, 17, 18, 0, 0, 0, 19, 20, 0,
+ 0, 0, 0, 0, 21, 22, 0, 23, 0, 24,
+ 0, 0, 25, 26, 0, 27, 0, 0, -18, 189,
+ -18, 4, 5, 0, 0, 6, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 190, 0, 191,
+ 192, 193, -72, -72, 194, 195, 196, 197, 198, 199,
+ 200, 201, 202, 0, 0, 0, 13, 203, 0, 0,
+ 0, 14, 15, 16, 17, 0, 0, 0, 0, -72,
+ 20, 0, 0, 0, 0, 0, 21, 22, 0, 23,
0, 24, 0, 0, 25, 26, 0, 61, 0, 0,
- 0, 0, 0, 4, 5, 0, 0, 6, 7, 0,
- 0, 0, 13, 0, 0, 0, 0, 14, 15, 16,
- 17, 0, 0, 0, 0, 20, 0, 0, 0, 0,
- 0, 21, 22, 0, 23, 0, 24, 0, 13, 25,
- 26, 0, 61, 14, 15, 16, 17, 0, 4, 5,
- 0, 20, 6, 7, 0, 0, 0, 21, 22, 0,
- 23, 0, 24, 0, 0, 25, 26, 0, 61, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 84, 14, 15,
- 16, 17, 85, 84, 0, 0, 20, 0, 85, 0,
- 0, 0, 21, 22, 0, 23, 0, 24, 0, 0,
- 25, 66, 0, 61, 0, 0, 0, 0, 86, 87,
- 88, 0, 0, 0, 86, 87, 88, 0, 0, 0,
- 89, 0, 90, 91, 92, 0, 89, 0, 0, 91,
- 92
+ 75, -72, 76, 189, 0, 4, 5, 0, 0, 6,
+ 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 190, 0, 191, 192, 193, -71, -71, 194, 195,
+ 196, 197, 198, 199, 200, 201, 202, 0, 0, 0,
+ 13, 203, 0, 0, 0, 14, 15, 16, 17, 0,
+ 0, 0, 0, -71, 20, 0, 0, 0, 0, 0,
+ 21, 22, 0, 23, 0, 24, 0, 0, 25, 26,
+ 0, 61, 0, 0, 75, -71, 76, 189, 0, 4,
+ 5, 0, 0, 6, 7, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 190, 0, 191, 192, 193,
+ 0, 0, 194, 195, 196, 197, 198, 199, 200, 201,
+ 202, 0, 0, 0, 13, 203, 0, 0, 0, 14,
+ 15, 16, 17, 69, 0, 4, 5, 0, 20, 6,
+ 7, 0, -102, 0, 21, 22, 0, 23, 0, 24,
+ 0, 0, 25, 26, 0, 61, 0, 0, 75, 204,
+ 76, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 0, 0, 0, 0, 14, 15, 16, 17, 0,
+ 0, 0, 0, -102, 20, 0, 0, 0, 0, 0,
+ 21, 22, 0, 23, 0, 24, 0, 0, 25, 257,
+ -102, 61, 0, 4, 5, 0, -102, 6, 7, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 190,
+ 0, 191, 192, 193, 0, 0, 194, 195, 196, 197,
+ 198, 199, 200, 201, 202, 0, 4, 5, 13, 203,
+ 6, 7, 0, 14, 15, 16, 17, 0, 0, 0,
+ 0, 0, 20, 0, 0, 0, 0, 85, 21, 22,
+ 0, 23, 86, 24, 0, 0, 25, 26, 0, 61,
+ 0, 13, 75, 0, 76, 0, 14, 15, 16, 17,
+ 69, 0, 4, 5, 0, 20, 6, 7, 87, 88,
+ 89, 21, 22, 0, 23, 0, 24, 0, 0, 25,
+ 26, 90, 61, 91, 92, 93, 0, 76, 0, 0,
+ 0, 0, 69, 0, 4, 5, 0, 13, 6, 7,
+ 0, 0, 14, 15, 16, 17, 0, 0, 0, 0,
+ 0, 20, 0, 0, 0, 0, 0, 21, 22, 0,
+ 23, 0, 24, 0, 0, 25, 26, -102, 61, 13,
+ 0, 0, 0, 0, 14, 15, 16, 17, 183, 0,
+ 4, 5, 0, 20, 6, 7, 0, 0, 0, 21,
+ 22, 0, 23, 0, 24, 0, 0, 25, 26, 0,
+ 61, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 4, 253, 13, 0, 6, 7, 0,
+ 14, 15, 16, 17, 0, 0, 0, 0, 0, 20,
+ 0, 0, 192, 0, 0, 21, 22, 0, 23, 0,
+ 24, 199, 200, 25, 26, 0, 61, 0, 13, 0,
+ 0, 0, 0, 14, 15, 16, 17, 0, 0, 4,
+ 5, 0, 20, 6, 7, 0, 0, 0, 21, 22,
+ 0, 23, 0, 24, 0, 0, 25, 26, 192, 61,
+ 0, 0, 0, 0, 0, 0, 0, 199, 200, 0,
+ 0, 0, 0, 0, 13, 0, 0, 0, 0, 14,
+ 15, 16, 17, 0, 0, 4, 5, 0, 20, 6,
+ 7, 0, 0, 96, 21, 22, 0, 23, 0, 24,
+ 0, 0, 25, 26, 0, 61, 0, 0, 0, 0,
+ 0, 0, 4, 5, 0, 0, 6, 7, 0, 0,
+ 13, 0, 0, 0, 0, 14, 15, 16, 17, 0,
+ 0, 0, 0, 85, 20, 0, 0, 0, 86, 0,
+ 21, 22, 0, 23, 0, 24, 0, 13, 25, 26,
+ 0, 61, 14, 15, 16, 17, 0, 0, 4, 5,
+ 0, 20, 6, 7, 87, 88, 89, 21, 22, 0,
+ 23, 0, 24, 0, 0, 25, 26, 90, 61, 0,
+ 92, 93, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 85, 14, 15,
+ 16, 17, 86, 0, 0, 0, 0, 20, 0, 0,
+ 0, 0, 0, 21, 22, 0, 23, 0, 24, 0,
+ 0, 25, 66, 0, 61, 0, 0, 0, 87, 88,
+ 89, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 90, 214, 0, 92, 93
};
-#define yypact_value_is_default(yystate) \
- ((yystate) == (-264))
-
-#define yytable_value_is_error(yytable_value) \
- ((yytable_value) == (-100))
-
static const yytype_int16 yycheck[] =
{
- 1, 29, 30, 26, 29, 59, 60, 46, 205, 222,
- 232, 13, 14, 15, 4, 50, 86, 16, 221, 21,
- 22, 44, 24, 25, 70, 26, 40, 69, 50, 1,
- 3, 294, 16, 35, 6, 66, 71, 66, 73, 66,
- 303, 1, 43, 44, 1, 1, 1, 4, 66, 4,
- 4, 73, 43, 44, 1, 69, 43, 44, 59, 60,
- 21, 22, 1, 24, 71, 66, 55, 50, 271, 115,
- 69, 9, 275, 29, 35, 48, 66, 3, 300, 125,
- 126, 294, 1, 1, 85, 69, 87, 88, 89, 292,
- 303, 10, 295, 94, 54, 97, 98, 99, 100, 101,
- 102, 103, 104, 105, 106, 107, 108, 54, 178, 49,
- 70, 65, 67, 114, 139, 54, 64, 55, 56, 322,
- 67, 123, 325, 320, 5, 171, 323, 9, 67, 50,
- 131, 50, 50, 1, 135, 54, 97, 98, 99, 100,
- 101, 102, 103, 104, 105, 106, 107, 108, 67, 150,
- 152, 27, 4, 80, 73, 73, 24, 25, 12, 13,
- 38, 67, 123, 90, 13, 40, 191, 192, 3, 4,
- 195, 66, 197, 55, 56, 66, 201, 231, 66, 66,
- 73, 206, 50, 139, 4, 61, 59, 60, 61, 43,
- 44, 64, 26, 67, 240, 196, 266, 51, 244, 245,
- 10, 226, 66, 242, 72, 132, 20, 208, 53, 72,
- 45, 46, 7, 7, 215, 216, 241, 30, 219, 220,
- 259, 9, 268, 297, 249, 280, 14, 25, 251, 152,
- 231, 277, 311, 68, 216, 191, 192, 139, 284, 195,
- 259, 197, 172, -1, -1, 201, 274, 7, 8, -1,
- 251, -1, 40, 278, -1, -1, -1, -1, 304, -1,
- -1, 286, 189, -1, -1, -1, -1, 55, 56, 315,
- 226, 198, -1, -1, -1, 276, 9, 278, 280, -1,
- 207, 14, -1, -1, 211, 241, 288, 9, -1, 191,
- 192, 51, 14, 195, -1, 197, -1, 57, 58, 201,
- 60, -1, -1, -1, -1, -1, 233, 40, 41, -1,
- 9, -1, -1, -1, -1, 14, -1, -1, 40, 41,
- 42, -1, 55, 56, 226, -1, -1, 288, -1, 256,
- 52, -1, -1, 55, 56, -1, 263, 264, -1, 241,
- 267, 40, 41, 42, -1, 57, 58, 59, 60, 61,
- 9, 73, 64, 52, 53, 14, 55, 56, 285, -1,
- 287, -1, 289, 290, 291, -1, 293, 0, 1, -1,
- 3, 4, -1, -1, 7, 8, -1, -1, -1, -1,
- -1, 40, 41, 42, 17, 18, 313, -1, -1, 316,
- -1, -1, 319, 52, 321, -1, 55, 56, -1, -1,
- -1, -1, 35, 36, 37, 38, -1, -1, 67, -1,
- 43, 44, 45, 46, 47, -1, -1, 50, 51, 57,
- 58, 59, 60, 61, 57, 58, 64, 60, -1, 62,
- -1, -1, 65, 66, -1, 68, -1, -1, 71, 1,
- 73, 3, 4, -1, -1, 7, 8, -1, -1, -1,
+ 1, 29, 30, 26, 29, 59, 60, 238, 46, 211,
+ 228, 13, 14, 15, 87, 4, 27, 1, 16, 21,
+ 22, 44, 24, 25, 70, 26, 10, 40, 300, 16,
+ 4, 51, 51, 35, 60, 61, 62, 309, 1, 65,
+ 67, 1, 43, 44, 1, 1, 6, 4, 1, 70,
+ 61, 1, 72, 6, 74, 74, 1, 70, 59, 60,
+ 21, 22, 67, 24, 67, 66, 1, 51, 24, 25,
+ 116, 55, 70, 72, 35, 306, 1, 66, 1, 29,
+ 126, 127, 300, 70, 68, 86, 51, 88, 89, 90,
+ 74, 309, 55, 67, 95, 51, 98, 99, 100, 101,
+ 102, 103, 104, 105, 106, 107, 108, 109, 71, 182,
+ 55, 68, 49, 1, 115, 140, 4, 73, 143, 3,
+ 55, 67, 124, 68, 326, 56, 51, 329, 51, 175,
+ 3, 132, 9, 68, 51, 136, 4, 98, 99, 100,
+ 101, 102, 103, 104, 105, 106, 107, 108, 109, 74,
+ 9, 74, 65, 154, 156, 14, 5, 81, 43, 44,
+ 3, 4, 38, 124, 48, 13, 50, 91, 68, 227,
+ 9, 67, 197, 198, 43, 44, 201, 40, 203, 56,
+ 57, 40, 207, 237, 9, 67, 67, 212, 67, 14,
+ 140, 74, 4, 143, 68, 26, 10, 56, 57, 272,
+ 246, 202, 45, 46, 250, 251, 67, 232, 54, 133,
+ 248, 140, 20, 214, 143, 40, 41, 56, 57, 277,
+ 221, 222, 247, 281, 225, 226, 69, 265, 274, 73,
+ 255, 56, 57, 7, 257, 7, 237, 283, 30, 303,
+ 298, 222, 286, 301, 290, 12, 13, 197, 198, 25,
+ 156, 201, 280, 203, 7, 8, 257, 207, 265, 284,
+ 317, 176, -1, -1, 310, -1, -1, 292, 197, 198,
+ 328, 195, 201, 331, 203, 321, 43, 44, 207, -1,
+ 204, 282, 232, 284, 286, 52, -1, -1, -1, 213,
+ -1, -1, 294, 217, -1, 9, -1, 247, -1, 52,
+ 14, -1, -1, 232, 9, 58, 59, -1, 61, 14,
+ 58, 59, 60, 61, 62, 239, -1, 65, 247, -1,
+ -1, -1, -1, -1, -1, -1, 40, 41, 42, -1,
+ -1, -1, -1, 294, -1, 40, 41, 42, 262, 53,
+ -1, -1, 56, 57, -1, 269, 270, -1, 53, 273,
+ -1, 56, 57, -1, 58, 59, 60, 61, 62, -1,
+ 74, 65, -1, 68, -1, -1, -1, 291, -1, 293,
+ -1, 295, 296, 297, -1, 299, 0, 1, -1, 3,
+ 4, -1, -1, 7, 8, -1, -1, -1, -1, -1,
+ -1, -1, -1, 17, 18, 319, -1, -1, 322, -1,
+ -1, 325, -1, 327, -1, -1, -1, -1, -1, -1,
+ -1, 35, 36, 37, 38, -1, -1, -1, -1, 43,
+ 44, 45, 46, 47, -1, -1, -1, 51, 52, -1,
+ -1, -1, -1, -1, 58, 59, -1, 61, -1, 63,
+ -1, -1, 66, 67, -1, 69, -1, -1, 72, 1,
+ 74, 3, 4, -1, -1, 7, 8, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, 19, -1, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, -1, -1, -1, 38, 39, -1, -1,
- -1, 43, 44, 45, 46, -1, -1, -1, 50, 51,
- -1, -1, -1, -1, -1, 57, 58, -1, 60, -1,
- 62, -1, -1, 65, 66, -1, 68, -1, -1, 71,
- 72, 73, 1, -1, 3, 4, -1, -1, 7, 8,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 19, -1, 21, 22, 23, 24, 25, 26, 27, 28,
- 29, 30, 31, 32, 33, 34, -1, -1, -1, 38,
- 39, -1, -1, -1, 43, 44, 45, 46, -1, -1,
- -1, 50, 51, -1, -1, -1, -1, -1, 57, 58,
- -1, 60, -1, 62, -1, -1, 65, 66, -1, 68,
- -1, -1, 71, 72, 73, 1, -1, 3, 4, -1,
- -1, 7, 8, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 19, -1, 21, 22, 23, -1, -1,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, -1,
- -1, -1, 38, 39, -1, -1, -1, 43, 44, 45,
- 46, 1, -1, 3, 4, 51, -1, 7, 8, -1,
- 10, 57, 58, -1, 60, -1, 62, -1, -1, 65,
- 66, -1, 68, -1, -1, 71, 72, 73, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 38, -1,
- -1, -1, -1, 43, 44, 45, 46, -1, -1, -1,
- 50, 51, -1, -1, -1, -1, -1, 57, 58, -1,
- 60, -1, 62, -1, -1, 65, 66, 67, 68, -1,
- 3, 4, -1, 73, 7, 8, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 19, -1, 21, 22,
- 23, -1, -1, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, -1, -1, -1, 38, 39, -1, -1, -1,
- 43, 44, 45, 46, -1, 3, 4, -1, 51, 7,
- 8, -1, -1, -1, 57, 58, -1, 60, -1, 62,
- -1, -1, 65, 66, -1, 68, -1, -1, 71, 1,
- 73, 3, 4, -1, -1, 7, 8, -1, -1, -1,
- 38, -1, -1, -1, -1, 43, 44, 45, 46, -1,
- -1, -1, -1, 51, -1, -1, -1, -1, -1, 57,
- 58, -1, 60, -1, 62, -1, 38, 65, 66, -1,
- 68, 43, 44, 45, 46, 73, -1, -1, -1, 51,
- -1, -1, -1, -1, -1, 57, 58, -1, 60, -1,
- 62, -1, -1, 65, 66, 67, 68, 1, -1, 3,
+ -1, 43, 44, 45, 46, -1, -1, -1, -1, 51,
+ 52, -1, -1, -1, -1, -1, 58, 59, -1, 61,
+ -1, 63, -1, -1, 66, 67, -1, 69, -1, -1,
+ 72, 73, 74, 1, -1, 3, 4, -1, -1, 7,
+ 8, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 19, -1, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, -1, -1, -1,
+ 38, 39, -1, -1, -1, 43, 44, 45, 46, -1,
+ -1, -1, -1, 51, 52, -1, -1, -1, -1, -1,
+ 58, 59, -1, 61, -1, 63, -1, -1, 66, 67,
+ -1, 69, -1, -1, 72, 73, 74, 1, -1, 3,
4, -1, -1, 7, 8, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 1, -1, 3, 4, -1, -1, 7,
- 8, -1, -1, -1, 38, -1, -1, -1, -1, 43,
- 44, 45, 46, -1, -1, -1, -1, 51, -1, -1,
- -1, -1, -1, 57, 58, -1, 60, -1, 62, -1,
- 38, 65, 66, -1, 68, 43, 44, 45, 46, -1,
- 3, 4, -1, 51, 7, 8, -1, -1, -1, 57,
- 58, -1, 60, -1, 62, -1, -1, 65, 66, 22,
- 68, -1, -1, -1, -1, -1, -1, -1, 31, 32,
- -1, -1, 3, 4, -1, 38, 7, 8, -1, -1,
- 43, 44, 45, 46, -1, -1, -1, -1, 51, -1,
- -1, 22, -1, -1, 57, 58, -1, 60, -1, 62,
- 31, 32, 65, 66, -1, 68, -1, 38, -1, -1,
- -1, -1, 43, 44, 45, 46, -1, 3, 4, -1,
- 51, 7, 8, -1, -1, 11, 57, 58, -1, 60,
- -1, 62, -1, -1, 65, 66, -1, 68, -1, -1,
- -1, -1, -1, 3, 4, -1, -1, 7, 8, -1,
- -1, -1, 38, -1, -1, -1, -1, 43, 44, 45,
- 46, -1, -1, -1, -1, 51, -1, -1, -1, -1,
- -1, 57, 58, -1, 60, -1, 62, -1, 38, 65,
- 66, -1, 68, 43, 44, 45, 46, -1, 3, 4,
- -1, 51, 7, 8, -1, -1, -1, 57, 58, -1,
- 60, -1, 62, -1, -1, 65, 66, -1, 68, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 19, -1, 21, 22, 23,
+ -1, -1, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, -1, -1, -1, 38, 39, -1, -1, -1, 43,
+ 44, 45, 46, 1, -1, 3, 4, -1, 52, 7,
+ 8, -1, 10, -1, 58, 59, -1, 61, -1, 63,
+ -1, -1, 66, 67, -1, 69, -1, -1, 72, 73,
+ 74, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 38, -1, -1, -1, -1, 43, 44, 45, 46, -1,
+ -1, -1, -1, 51, 52, -1, -1, -1, -1, -1,
+ 58, 59, -1, 61, -1, 63, -1, -1, 66, 67,
+ 68, 69, -1, 3, 4, -1, 74, 7, 8, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 19,
+ -1, 21, 22, 23, -1, -1, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, -1, 3, 4, 38, 39,
+ 7, 8, -1, 43, 44, 45, 46, -1, -1, -1,
+ -1, -1, 52, -1, -1, -1, -1, 9, 58, 59,
+ -1, 61, 14, 63, -1, -1, 66, 67, -1, 69,
+ -1, 38, 72, -1, 74, -1, 43, 44, 45, 46,
+ 1, -1, 3, 4, -1, 52, 7, 8, 40, 41,
+ 42, 58, 59, -1, 61, -1, 63, -1, -1, 66,
+ 67, 53, 69, 55, 56, 57, -1, 74, -1, -1,
+ -1, -1, 1, -1, 3, 4, -1, 38, 7, 8,
+ -1, -1, 43, 44, 45, 46, -1, -1, -1, -1,
+ -1, 52, -1, -1, -1, -1, -1, 58, 59, -1,
+ 61, -1, 63, -1, -1, 66, 67, 68, 69, 38,
+ -1, -1, -1, -1, 43, 44, 45, 46, 1, -1,
+ 3, 4, -1, 52, 7, 8, -1, -1, -1, 58,
+ 59, -1, 61, -1, 63, -1, -1, 66, 67, -1,
+ 69, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 3, 4, 38, -1, 7, 8, -1,
+ 43, 44, 45, 46, -1, -1, -1, -1, -1, 52,
+ -1, -1, 22, -1, -1, 58, 59, -1, 61, -1,
+ 63, 31, 32, 66, 67, -1, 69, -1, 38, -1,
+ -1, -1, -1, 43, 44, 45, 46, -1, -1, 3,
+ 4, -1, 52, 7, 8, -1, -1, -1, 58, 59,
+ -1, 61, -1, 63, -1, -1, 66, 67, 22, 69,
+ -1, -1, -1, -1, -1, -1, -1, 31, 32, -1,
+ -1, -1, -1, -1, 38, -1, -1, -1, -1, 43,
+ 44, 45, 46, -1, -1, 3, 4, -1, 52, 7,
+ 8, -1, -1, 11, 58, 59, -1, 61, -1, 63,
+ -1, -1, 66, 67, -1, 69, -1, -1, -1, -1,
+ -1, -1, 3, 4, -1, -1, 7, 8, -1, -1,
+ 38, -1, -1, -1, -1, 43, 44, 45, 46, -1,
+ -1, -1, -1, 9, 52, -1, -1, -1, 14, -1,
+ 58, 59, -1, 61, -1, 63, -1, 38, 66, 67,
+ -1, 69, 43, 44, 45, 46, -1, -1, 3, 4,
+ -1, 52, 7, 8, 40, 41, 42, 58, 59, -1,
+ 61, -1, 63, -1, -1, 66, 67, 53, 69, -1,
+ 56, 57, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, 9, 43, 44,
- 45, 46, 14, 9, -1, -1, 51, -1, 14, -1,
- -1, -1, 57, 58, -1, 60, -1, 62, -1, -1,
- 65, 66, -1, 68, -1, -1, -1, -1, 40, 41,
- 42, -1, -1, -1, 40, 41, 42, -1, -1, -1,
- 52, -1, 54, 55, 56, -1, 52, -1, -1, 55,
- 56
+ 45, 46, 14, -1, -1, -1, -1, 52, -1, -1,
+ -1, -1, -1, 58, 59, -1, 61, -1, 63, -1,
+ -1, 66, 67, -1, 69, -1, -1, -1, 40, 41,
+ 42, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 53, 54, -1, 56, 57
};
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
- symbol of state STATE-NUM. */
+ /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
- 0, 75, 0, 1, 3, 4, 7, 8, 17, 18,
- 35, 36, 37, 38, 43, 44, 45, 46, 47, 50,
- 51, 57, 58, 60, 62, 65, 66, 68, 76, 78,
- 82, 83, 85, 103, 111, 115, 116, 117, 118, 119,
- 120, 128, 129, 66, 69, 125, 126, 127, 3, 4,
- 45, 46, 68, 80, 81, 121, 129, 129, 129, 66,
- 66, 68, 116, 129, 116, 116, 66, 118, 129, 1,
- 110, 111, 48, 120, 71, 73, 79, 87, 103, 131,
- 135, 79, 84, 50, 9, 14, 40, 41, 42, 52,
- 54, 55, 56, 113, 114, 11, 116, 57, 58, 59,
- 60, 61, 64, 57, 58, 59, 60, 61, 64, 12,
- 13, 43, 44, 51, 112, 109, 110, 111, 110, 16,
- 125, 49, 66, 55, 105, 109, 109, 111, 43, 44,
- 130, 1, 54, 67, 133, 137, 133, 1, 6, 77,
- 103, 104, 86, 104, 5, 111, 128, 111, 111, 111,
- 104, 111, 38, 116, 116, 116, 116, 116, 116, 116,
- 116, 116, 116, 116, 116, 13, 111, 133, 70, 1,
- 4, 106, 107, 116, 133, 133, 111, 104, 40, 1,
- 111, 1, 87, 1, 19, 21, 22, 23, 26, 27,
- 28, 29, 30, 31, 32, 33, 34, 39, 72, 88,
- 89, 91, 98, 102, 111, 131, 132, 135, 53, 111,
- 121, 133, 1, 137, 128, 66, 90, 4, 66, 66,
- 66, 104, 66, 87, 87, 87, 108, 111, 87, 104,
- 87, 92, 86, 134, 135, 104, 111, 104, 1, 4,
- 111, 108, 93, 4, 111, 111, 88, 4, 91, 94,
- 87, 66, 99, 109, 132, 104, 133, 87, 122, 123,
- 124, 125, 67, 133, 133, 26, 40, 135, 110, 10,
- 100, 104, 16, 124, 104, 104, 66, 128, 104, 133,
- 101, 88, 131, 88, 111, 133, 111, 135, 115, 20,
- 95, 133, 104, 135, 104, 104, 1, 24, 25, 96,
- 104, 104, 88, 104, 94, 88, 7, 8, 57, 58,
- 83, 97, 53, 136, 132, 94, 133, 7, 7, 136,
- 104, 133, 104, 104, 86, 104, 88, 86, 88
+ 0, 76, 0, 1, 3, 4, 7, 8, 17, 18,
+ 35, 36, 37, 38, 43, 44, 45, 46, 47, 51,
+ 52, 58, 59, 61, 63, 66, 67, 69, 77, 80,
+ 84, 85, 87, 105, 113, 117, 118, 119, 120, 121,
+ 122, 130, 131, 67, 70, 127, 128, 129, 3, 4,
+ 45, 46, 69, 82, 83, 123, 131, 131, 131, 67,
+ 67, 69, 118, 131, 118, 118, 67, 120, 131, 1,
+ 112, 113, 48, 50, 122, 72, 74, 81, 89, 105,
+ 133, 137, 81, 86, 51, 9, 14, 40, 41, 42,
+ 53, 55, 56, 57, 115, 116, 11, 118, 58, 59,
+ 60, 61, 62, 65, 58, 59, 60, 61, 62, 65,
+ 12, 13, 43, 44, 52, 114, 111, 112, 113, 112,
+ 16, 127, 49, 67, 56, 107, 111, 111, 113, 43,
+ 44, 132, 1, 55, 68, 135, 139, 135, 1, 6,
+ 78, 1, 6, 79, 105, 106, 88, 106, 5, 113,
+ 130, 113, 113, 113, 106, 113, 38, 118, 118, 118,
+ 118, 118, 118, 118, 118, 118, 118, 118, 118, 13,
+ 113, 135, 71, 1, 4, 108, 109, 118, 135, 135,
+ 113, 106, 40, 1, 113, 1, 89, 1, 89, 1,
+ 19, 21, 22, 23, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 39, 73, 90, 91, 93, 100, 104,
+ 113, 133, 134, 137, 54, 113, 123, 135, 1, 139,
+ 130, 67, 92, 4, 67, 67, 67, 106, 67, 89,
+ 89, 89, 110, 113, 89, 106, 89, 94, 88, 136,
+ 137, 106, 113, 106, 1, 4, 113, 110, 95, 4,
+ 113, 113, 90, 4, 93, 96, 89, 67, 101, 111,
+ 134, 106, 135, 89, 124, 125, 126, 127, 68, 135,
+ 135, 26, 40, 137, 112, 10, 102, 106, 16, 126,
+ 106, 106, 67, 130, 106, 135, 103, 90, 133, 90,
+ 113, 135, 113, 137, 117, 20, 97, 135, 106, 137,
+ 106, 106, 1, 24, 25, 98, 106, 106, 90, 106,
+ 96, 90, 7, 8, 58, 59, 85, 99, 54, 138,
+ 134, 96, 135, 7, 7, 138, 106, 135, 106, 106,
+ 88, 106, 90, 88, 90
};
-#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. However,
- YYFAIL appears to be in use. Nevertheless, it is formally deprecated
- in Bison 2.4.2's NEWS entry, where a plan to phase it out is
- discussed. */
-
-#define YYFAIL goto yyerrlab
-#if defined YYFAIL
- /* This is here to suppress warnings from the GCC cpp's
- -Wunused-macros. Normally we don't worry about that warning, but
- some users do, and we want to make it easy for users to remove
- YYFAIL uses, which will produce warnings from Bison 2.5. */
-#endif
+ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 75, 76, 76, 76, 76, 76, 77, 77, 77,
+ 77, 77, 78, 78, 78, 79, 79, 79, 80, 80,
+ 80, 80, 80, 80, 80, 81, 82, 82, 82, 82,
+ 83, 83, 84, 86, 85, 87, 87, 88, 88, 88,
+ 89, 89, 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 91, 91, 91, 91, 91, 92, 91, 91,
+ 94, 93, 95, 93, 93, 93, 96, 96, 97, 97,
+ 97, 98, 98, 99, 99, 99, 99, 99, 100, 100,
+ 101, 101, 102, 103, 102, 104, 104, 105, 105, 106,
+ 106, 107, 107, 108, 108, 109, 109, 109, 109, 109,
+ 110, 110, 111, 111, 112, 112, 112, 112, 112, 112,
+ 113, 113, 113, 113, 113, 113, 113, 113, 114, 114,
+ 114, 115, 115, 116, 116, 117, 117, 117, 118, 118,
+ 118, 118, 118, 118, 118, 118, 118, 118, 118, 119,
+ 119, 119, 119, 119, 119, 119, 120, 120, 120, 120,
+ 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+ 121, 121, 122, 123, 123, 124, 124, 125, 125, 126,
+ 127, 128, 128, 129, 130, 130, 131, 131, 132, 132,
+ 132, 133, 134, 135, 136, 136, 137, 138, 139
+};
-#define YYRECOVERING() (!!yyerrstatus)
+ /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 0, 2, 2, 2, 2, 2, 2, 2,
+ 4, 4, 1, 2, 1, 1, 2, 1, 0, 1,
+ 4, 1, 1, 1, 1, 5, 1, 1, 1, 2,
+ 1, 1, 6, 0, 3, 1, 1, 0, 2, 2,
+ 1, 2, 2, 3, 1, 9, 6, 8, 8, 12,
+ 11, 1, 2, 2, 2, 2, 3, 0, 4, 2,
+ 0, 4, 0, 4, 4, 1, 0, 1, 0, 2,
+ 2, 5, 4, 1, 2, 2, 1, 1, 1, 1,
+ 1, 3, 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, 1, 2, 1, 3,
+ 3, 3, 3, 3, 3, 3, 2, 2, 5, 4,
+ 3, 3, 3, 3, 3, 3, 1, 2, 3, 4,
+ 4, 1, 1, 1, 2, 2, 1, 1, 2, 2,
+ 1, 2, 4, 0, 1, 0, 2, 1, 2, 1,
+ 3, 1, 2, 2, 1, 2, 1, 3, 1, 1,
+ 0, 2, 2, 1, 0, 1, 1, 1, 2
+};
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY && yylen == 1) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- YYPOPSTACK (1); \
- goto yybackup; \
- } \
- else \
- { \
- yyerror (YY_("syntax error: cannot back up")); \
- YYERROR; \
- } \
-while (YYID (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 (YYID (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 (YYID (0))
-#endif
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
-/* This macro is provided for backward compatibility. */
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
-#ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-#endif
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (0)
+
+/* Error token number */
+#define YYTERROR 1
+#define YYERRCODE 256
-/* 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
@@ -1311,53 +1218,46 @@ while (YYID (0))
# define YYFPRINTF fprintf
# endif
-# define YYDPRINTF(Args) \
-do { \
- if (yydebug) \
- YYFPRINTF Args; \
-} while (YYID (0))
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+/* This macro is provided for backward compatibility. */
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
+
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
-do { \
- if (yydebug) \
- { \
- YYFPRINTF (stderr, "%s ", Title); \
- yy_symbol_print (stderr, \
- Type, Value); \
- YYFPRINTF (stderr, "\n"); \
- } \
-} while (YYID (0))
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
+/*----------------------------------------.
+| Print this symbol's value on YYOUTPUT. |
+`----------------------------------------*/
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
static void
yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
-#else
-static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep)
- FILE *yyoutput;
- int yytype;
- YYSTYPE const * const yyvaluep;
-#endif
{
+ FILE *yyo = yyoutput;
+ YYUSE (yyo);
if (!yyvaluep)
return;
# ifdef YYPRINT
if (yytype < YYNTOKENS)
YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# else
- YYUSE (yyoutput);
# endif
- switch (yytype)
- {
- default:
- break;
- }
+ YYUSE (yytype);
}
@@ -1365,21 +1265,11 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep)
| Print this symbol on YYOUTPUT. |
`--------------------------------*/
-#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
static void
yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
-#else
-static void
-yy_symbol_print (yyoutput, yytype, yyvaluep)
- FILE *yyoutput;
- int yytype;
- YYSTYPE const * const yyvaluep;
-#endif
{
- if (yytype < YYNTOKENS)
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
- else
- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+ YYFPRINTF (yyoutput, "%s %s (",
+ yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
yy_symbol_value_print (yyoutput, yytype, yyvaluep);
YYFPRINTF (yyoutput, ")");
@@ -1390,15 +1280,8 @@ yy_symbol_print (yyoutput, yytype, yyvaluep)
| TOP (included). |
`------------------------------------------------------------------*/
-#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
static void
yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
-#else
-static void
-yy_stack_print (yybottom, yytop)
- yytype_int16 *yybottom;
- yytype_int16 *yytop;
-#endif
{
YYFPRINTF (stderr, "Stack now");
for (; yybottom <= yytop; yybottom++)
@@ -1409,48 +1292,42 @@ yy_stack_print (yybottom, yytop)
YYFPRINTF (stderr, "\n");
}
-# define YY_STACK_PRINT(Bottom, Top) \
-do { \
- if (yydebug) \
- yy_stack_print ((Bottom), (Top)); \
-} while (YYID (0))
+# 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 __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
-static void
-yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
-#else
static void
-yy_reduce_print (yyvsp, yyrule)
- YYSTYPE *yyvsp;
- int yyrule;
-#endif
+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
{
+ unsigned long int yylno = yyrline[yyrule];
int yynrhs = yyr2[yyrule];
int yyi;
- unsigned long int yylno = yyrline[yyrule];
YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
- yyrule - 1, yylno);
+ yyrule - 1, yylno);
/* The symbols being reduced. */
for (yyi = 0; yyi < yynrhs; yyi++)
{
YYFPRINTF (stderr, " $%d = ", yyi + 1);
- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
- &(yyvsp[(yyi + 1) - (yynrhs)])
- );
+ yy_symbol_print (stderr,
+ yystos[yyssp[yyi + 1 - yynrhs]],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ );
YYFPRINTF (stderr, "\n");
}
}
-# define YY_REDUCE_PRINT(Rule) \
-do { \
- if (yydebug) \
- yy_reduce_print (yyvsp, Rule); \
-} while (YYID (0))
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyssp, yyvsp, Rule); \
+} while (0)
/* Nonzero means print parse trace. It is left uninitialized so that
multiple parsers can coexist. */
@@ -1464,7 +1341,7 @@ int yydebug;
/* YYINITDEPTH -- initial size of the parser's stacks. */
-#ifndef YYINITDEPTH
+#ifndef YYINITDEPTH
# define YYINITDEPTH 200
#endif
@@ -1487,14 +1364,8 @@ int yydebug;
# define yystrlen strlen
# else
/* Return the length of YYSTR. */
-#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
static YYSIZE_T
yystrlen (const char *yystr)
-#else
-static YYSIZE_T
-yystrlen (yystr)
- const char *yystr;
-#endif
{
YYSIZE_T yylen;
for (yylen = 0; yystr[yylen]; yylen++)
@@ -1510,15 +1381,8 @@ yystrlen (yystr)
# else
/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
YYDEST. */
-#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
static char *
yystpcpy (char *yydest, const char *yysrc)
-#else
-static char *
-yystpcpy (yydest, yysrc)
- char *yydest;
- const char *yysrc;
-#endif
{
char *yyd = yydest;
const char *yys = yysrc;
@@ -1548,27 +1412,27 @@ yytnamerr (char *yyres, const char *yystr)
char const *yyp = yystr;
for (;;)
- switch (*++yyp)
- {
- case '\'':
- case ',':
- goto do_not_strip_quotes;
-
- case '\\':
- if (*++yyp != '\\')
- goto do_not_strip_quotes;
- /* Fall through. */
- default:
- if (yyres)
- yyres[yyn] = *yyp;
- yyn++;
- break;
-
- case '"':
- if (yyres)
- yyres[yyn] = '\0';
- return yyn;
- }
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
do_not_strip_quotes: ;
}
@@ -1591,12 +1455,11 @@ static int
yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
yytype_int16 *yyssp, int yytoken)
{
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
+ YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */
- const char *yyformat = 0;
+ const char *yyformat = YY_NULLPTR;
/* Arguments of yyformat. */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
/* Number of reported tokens (one for the "unexpected", one per
@@ -1604,10 +1467,6 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
int yycount = 0;
/* There are many possibilities here to consider:
- - Assume YYFAIL is not used. It's too flawed to consider. See
- <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
- for details. YYERROR is fine as it does not invoke this
- function.
- If this state is a consistent state with a default action, then
the only way this function was invoked is if the default action
is an error action. In that case, don't check for expected
@@ -1656,11 +1515,13 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
break;
}
yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- if (! (yysize <= yysize1
- && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
+ {
+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+ if (! (yysize <= yysize1
+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
}
}
}
@@ -1680,10 +1541,12 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
# undef YYCASE_
}
- yysize1 = yysize + yystrlen (yyformat);
- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
+ {
+ YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
if (*yymsg_alloc < yysize)
{
@@ -1720,47 +1583,20 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
| Release the memory associated to this symbol. |
`-----------------------------------------------*/
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
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
{
YYUSE (yyvaluep);
-
if (!yymsg)
yymsg = "Deleting";
YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
- switch (yytype)
- {
-
- default:
- break;
- }
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
}
-/* 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 lookahead symbol. */
@@ -1768,7 +1604,6 @@ int yychar;
/* The semantic value of the lookahead symbol. */
YYSTYPE yylval;
-
/* Number of syntax errors so far. */
int yynerrs;
@@ -1777,35 +1612,18 @@ int yynerrs;
| yyparse. |
`----------*/
-#ifdef YYPARSE_PARAM
-#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void *YYPARSE_PARAM)
-#else
-int
-yyparse (YYPARSE_PARAM)
- void *YYPARSE_PARAM;
-#endif
-#else /* ! YYPARSE_PARAM */
-#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
int
yyparse (void)
-#else
-int
-yyparse ()
-
-#endif
-#endif
{
int yystate;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
/* The stacks and their tools:
- `yyss': related to states.
- `yyvs': related to semantic values.
+ 'yyss': related to states.
+ 'yyvs': related to semantic values.
- Refer to the stacks thru separate pointers, to allow yyoverflow
+ Refer to the stacks through separate pointers, to allow yyoverflow
to reallocate them elsewhere. */
/* The state stack. */
@@ -1823,7 +1641,7 @@ yyparse ()
int yyn;
int yyresult;
/* Lookahead token as an internal (translated) token number. */
- int yytoken;
+ int yytoken = 0;
/* The variables used to return semantic value and location from the
action routines. */
YYSTYPE yyval;
@@ -1841,9 +1659,8 @@ yyparse ()
Keep to zero when no symbol should be popped. */
int yylen = 0;
- yytoken = 0;
- yyss = yyssa;
- yyvs = yyvsa;
+ yyssp = yyss = yyssa;
+ yyvsp = yyvs = yyvsa;
yystacksize = YYINITDEPTH;
YYDPRINTF ((stderr, "Starting parse\n"));
@@ -1852,14 +1669,6 @@ yyparse ()
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;
-
goto yysetstate;
/*------------------------------------------------------------.
@@ -1880,23 +1689,23 @@ yyparse ()
#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;
- yytype_int16 *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 (YY_("memory exhausted"),
- &yyss1, yysize * sizeof (*yyssp),
- &yyvs1, yysize * sizeof (*yyvsp),
- &yystacksize);
-
- yyss = yyss1;
- yyvs = yyvs1;
+ /* 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;
+ yytype_int16 *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 (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
}
#else /* no yyoverflow */
# ifndef YYSTACK_RELOCATE
@@ -1904,22 +1713,22 @@ yyparse ()
# else
/* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize)
- goto yyexhaustedlab;
+ goto yyexhaustedlab;
yystacksize *= 2;
if (YYMAXDEPTH < yystacksize)
- yystacksize = YYMAXDEPTH;
+ yystacksize = YYMAXDEPTH;
{
- yytype_int16 *yyss1 = yyss;
- union yyalloc *yyptr =
- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
- if (! yyptr)
- goto yyexhaustedlab;
- YYSTACK_RELOCATE (yyss_alloc, yyss);
- YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
# undef YYSTACK_RELOCATE
- if (yyss1 != yyssa)
- YYSTACK_FREE (yyss1);
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
}
# endif
#endif /* no yyoverflow */
@@ -1928,10 +1737,10 @@ yyparse ()
yyvsp = yyvs + yysize - 1;
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
- (unsigned long int) yystacksize));
+ (unsigned long int) yystacksize));
if (yyss + yystacksize - 1 <= yyssp)
- YYABORT;
+ YYABORT;
}
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
@@ -1960,7 +1769,7 @@ yybackup:
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
- yychar = YYLEX;
+ yychar = yylex ();
}
if (yychar <= YYEOF)
@@ -2000,7 +1809,9 @@ yybackup:
yychar = YYEMPTY;
yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
goto yynewstate;
@@ -2023,7 +1834,7 @@ yyreduce:
yylen = yyr2[yyn];
/* If YYLEN is nonzero, implement the default value of the action:
- `$$ = $1'.
+ '$$ = $1'.
Otherwise, the following line sets YYVAL to garbage.
This behavior is undocumented and Bison
@@ -2037,28 +1848,24 @@ yyreduce:
switch (yyn)
{
case 3:
-
-/* Line 1821 of yacc.c */
-#line 194 "awkgram.y"
+#line 207 "awkgram.y" /* yacc.c:1646 */
{
rule = 0;
yyerrok;
}
+#line 1857 "awkgram.c" /* yacc.c:1646 */
break;
case 5:
-
-/* Line 1821 of yacc.c */
-#line 200 "awkgram.y"
+#line 213 "awkgram.y" /* yacc.c:1646 */
{
next_sourcefile();
}
+#line 1865 "awkgram.c" /* yacc.c:1646 */
break;
case 6:
-
-/* Line 1821 of yacc.c */
-#line 204 "awkgram.y"
+#line 217 "awkgram.y" /* yacc.c:1646 */
{
rule = 0;
/*
@@ -2067,266 +1874,324 @@ yyreduce:
*/
/* yyerrok; */
}
+#line 1878 "awkgram.c" /* yacc.c:1646 */
break;
case 7:
-
-/* Line 1821 of yacc.c */
-#line 216 "awkgram.y"
+#line 229 "awkgram.y" /* yacc.c:1646 */
{
- (void) append_rule((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
+ (void) append_rule((yyvsp[-1]), (yyvsp[0]));
+ first_rule = false;
}
+#line 1887 "awkgram.c" /* yacc.c:1646 */
break;
case 8:
-
-/* Line 1821 of yacc.c */
-#line 220 "awkgram.y"
+#line 234 "awkgram.y" /* yacc.c:1646 */
{
if (rule != Rule) {
msg(_("%s blocks must have an action part"), ruletab[rule]);
errcount++;
- } else if ((yyvsp[(1) - (2)]) == NULL) {
+ } else if ((yyvsp[-1]) == NULL) {
msg(_("each rule must have a pattern or an action part"));
errcount++;
} else /* pattern rule with non-empty pattern */
- (void) append_rule((yyvsp[(1) - (2)]), NULL);
+ (void) append_rule((yyvsp[-1]), NULL);
}
+#line 1902 "awkgram.c" /* yacc.c:1646 */
break;
case 9:
-
-/* Line 1821 of yacc.c */
-#line 231 "awkgram.y"
+#line 245 "awkgram.y" /* yacc.c:1646 */
{
in_function = NULL;
- (void) mk_function((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
+ (void) mk_function((yyvsp[-1]), (yyvsp[0]));
yyerrok;
}
+#line 1912 "awkgram.c" /* yacc.c:1646 */
break;
case 10:
-
-/* Line 1821 of yacc.c */
-#line 237 "awkgram.y"
+#line 251 "awkgram.y" /* yacc.c:1646 */
{
- want_source = FALSE;
+ want_source = false;
yyerrok;
}
+#line 1921 "awkgram.c" /* yacc.c:1646 */
break;
case 11:
+#line 256 "awkgram.y" /* yacc.c:1646 */
+ {
+ want_source = false;
+ yyerrok;
+ }
+#line 1930 "awkgram.c" /* yacc.c:1646 */
+ break;
-/* Line 1821 of yacc.c */
-#line 245 "awkgram.y"
+ case 12:
+#line 264 "awkgram.y" /* yacc.c:1646 */
{
- if (include_source((yyvsp[(1) - (1)])) < 0)
+ if (include_source((yyvsp[0])) < 0)
YYABORT;
- efree((yyvsp[(1) - (1)])->lextok);
- bcfree((yyvsp[(1) - (1)]));
+ efree((yyvsp[0])->lextok);
+ bcfree((yyvsp[0]));
(yyval) = NULL;
}
+#line 1942 "awkgram.c" /* yacc.c:1646 */
break;
- case 12:
-
-/* Line 1821 of yacc.c */
-#line 253 "awkgram.y"
+ case 13:
+#line 272 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 1948 "awkgram.c" /* yacc.c:1646 */
break;
- case 13:
-
-/* Line 1821 of yacc.c */
-#line 255 "awkgram.y"
+ case 14:
+#line 274 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 1954 "awkgram.c" /* yacc.c:1646 */
break;
- case 14:
+ case 15:
+#line 279 "awkgram.y" /* yacc.c:1646 */
+ {
+ if (load_library((yyvsp[0])) < 0)
+ YYABORT;
+ efree((yyvsp[0])->lextok);
+ bcfree((yyvsp[0]));
+ (yyval) = NULL;
+ }
+#line 1966 "awkgram.c" /* yacc.c:1646 */
+ break;
-/* Line 1821 of yacc.c */
-#line 260 "awkgram.y"
- { (yyval) = NULL; rule = Rule; }
+ case 16:
+#line 287 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = NULL; }
+#line 1972 "awkgram.c" /* yacc.c:1646 */
break;
- case 15:
+ case 17:
+#line 289 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = NULL; }
+#line 1978 "awkgram.c" /* yacc.c:1646 */
+ break;
-/* Line 1821 of yacc.c */
-#line 262 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); rule = Rule; }
+ case 18:
+#line 294 "awkgram.y" /* yacc.c:1646 */
+ {
+ rule = Rule;
+ if (comment != NULL) {
+ (yyval) = list_create(comment);
+ comment = NULL;
+ } else
+ (yyval) = NULL;
+ }
+#line 1991 "awkgram.c" /* yacc.c:1646 */
break;
- case 16:
+ case 19:
+#line 303 "awkgram.y" /* yacc.c:1646 */
+ {
+ rule = Rule;
+ if (comment != NULL) {
+ (yyval) = list_prepend((yyvsp[0]), comment);
+ comment = NULL;
+ } else
+ (yyval) = (yyvsp[0]);
+ }
+#line 2004 "awkgram.c" /* yacc.c:1646 */
+ break;
-/* Line 1821 of yacc.c */
-#line 264 "awkgram.y"
+ case 20:
+#line 313 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *tp;
- add_lint((yyvsp[(1) - (4)]), LINT_assign_in_cond);
- add_lint((yyvsp[(4) - (4)]), LINT_assign_in_cond);
+ add_lint((yyvsp[-3]), LINT_assign_in_cond);
+ add_lint((yyvsp[0]), LINT_assign_in_cond);
tp = instruction(Op_no_op);
- list_prepend((yyvsp[(1) - (4)]), bcalloc(Op_line_range, !!do_profiling + 1, 0));
- (yyvsp[(1) - (4)])->nexti->triggered = FALSE;
- (yyvsp[(1) - (4)])->nexti->target_jmp = (yyvsp[(4) - (4)])->nexti;
-
- list_append((yyvsp[(1) - (4)]), instruction(Op_cond_pair));
- (yyvsp[(1) - (4)])->lasti->line_range = (yyvsp[(1) - (4)])->nexti;
- (yyvsp[(1) - (4)])->lasti->target_jmp = tp;
-
- list_append((yyvsp[(4) - (4)]), instruction(Op_cond_pair));
- (yyvsp[(4) - (4)])->lasti->line_range = (yyvsp[(1) - (4)])->nexti;
- (yyvsp[(4) - (4)])->lasti->target_jmp = tp;
- if (do_profiling) {
- ((yyvsp[(1) - (4)])->nexti + 1)->condpair_left = (yyvsp[(1) - (4)])->lasti;
- ((yyvsp[(1) - (4)])->nexti + 1)->condpair_right = (yyvsp[(4) - (4)])->lasti;
+ list_prepend((yyvsp[-3]), bcalloc(Op_line_range, !!do_pretty_print + 1, 0));
+ (yyvsp[-3])->nexti->triggered = false;
+ (yyvsp[-3])->nexti->target_jmp = (yyvsp[0])->nexti;
+
+ list_append((yyvsp[-3]), instruction(Op_cond_pair));
+ (yyvsp[-3])->lasti->line_range = (yyvsp[-3])->nexti;
+ (yyvsp[-3])->lasti->target_jmp = tp;
+
+ list_append((yyvsp[0]), instruction(Op_cond_pair));
+ (yyvsp[0])->lasti->line_range = (yyvsp[-3])->nexti;
+ (yyvsp[0])->lasti->target_jmp = tp;
+ if (do_pretty_print) {
+ ((yyvsp[-3])->nexti + 1)->condpair_left = (yyvsp[-3])->lasti;
+ ((yyvsp[-3])->nexti + 1)->condpair_right = (yyvsp[0])->lasti;
}
- (yyval) = list_append(list_merge((yyvsp[(1) - (4)]), (yyvsp[(4) - (4)])), tp);
+ if (comment != NULL) {
+ (yyval) = list_append(list_merge(list_prepend((yyvsp[-3]), comment), (yyvsp[0])), tp);
+ comment = NULL;
+ } else
+ (yyval) = list_append(list_merge((yyvsp[-3]), (yyvsp[0])), tp);
rule = Rule;
}
+#line 2038 "awkgram.c" /* yacc.c:1646 */
break;
- case 17:
-
-/* Line 1821 of yacc.c */
-#line 290 "awkgram.y"
+ case 21:
+#line 343 "awkgram.y" /* yacc.c:1646 */
{
static int begin_seen = 0;
+
+ func_first = false;
if (do_lint_old && ++begin_seen == 2)
- warning_ln((yyvsp[(1) - (1)])->source_line,
+ warning_ln((yyvsp[0])->source_line,
_("old awk does not support multiple `BEGIN' or `END' rules"));
- (yyvsp[(1) - (1)])->in_rule = rule = BEGIN;
- (yyvsp[(1) - (1)])->source_file = source;
- (yyval) = (yyvsp[(1) - (1)]);
+ (yyvsp[0])->in_rule = rule = BEGIN;
+ (yyvsp[0])->source_file = source;
+ check_comment();
+ (yyval) = (yyvsp[0]);
}
+#line 2056 "awkgram.c" /* yacc.c:1646 */
break;
- case 18:
-
-/* Line 1821 of yacc.c */
-#line 301 "awkgram.y"
+ case 22:
+#line 357 "awkgram.y" /* yacc.c:1646 */
{
static int end_seen = 0;
+
+ func_first = false;
if (do_lint_old && ++end_seen == 2)
- warning_ln((yyvsp[(1) - (1)])->source_line,
+ warning_ln((yyvsp[0])->source_line,
_("old awk does not support multiple `BEGIN' or `END' rules"));
- (yyvsp[(1) - (1)])->in_rule = rule = END;
- (yyvsp[(1) - (1)])->source_file = source;
- (yyval) = (yyvsp[(1) - (1)]);
+ (yyvsp[0])->in_rule = rule = END;
+ (yyvsp[0])->source_file = source;
+ check_comment();
+ (yyval) = (yyvsp[0]);
}
+#line 2074 "awkgram.c" /* yacc.c:1646 */
break;
- case 19:
-
-/* Line 1821 of yacc.c */
-#line 312 "awkgram.y"
+ case 23:
+#line 371 "awkgram.y" /* yacc.c:1646 */
{
- (yyvsp[(1) - (1)])->in_rule = rule = BEGINFILE;
- (yyvsp[(1) - (1)])->source_file = source;
- (yyval) = (yyvsp[(1) - (1)]);
+ func_first = false;
+ (yyvsp[0])->in_rule = rule = BEGINFILE;
+ (yyvsp[0])->source_file = source;
+ check_comment();
+ (yyval) = (yyvsp[0]);
}
+#line 2086 "awkgram.c" /* yacc.c:1646 */
break;
- case 20:
-
-/* Line 1821 of yacc.c */
-#line 318 "awkgram.y"
+ case 24:
+#line 379 "awkgram.y" /* yacc.c:1646 */
{
- (yyvsp[(1) - (1)])->in_rule = rule = ENDFILE;
- (yyvsp[(1) - (1)])->source_file = source;
- (yyval) = (yyvsp[(1) - (1)]);
+ func_first = false;
+ (yyvsp[0])->in_rule = rule = ENDFILE;
+ (yyvsp[0])->source_file = source;
+ check_comment();
+ (yyval) = (yyvsp[0]);
}
+#line 2098 "awkgram.c" /* yacc.c:1646 */
break;
- case 21:
-
-/* Line 1821 of yacc.c */
-#line 327 "awkgram.y"
+ case 25:
+#line 390 "awkgram.y" /* yacc.c:1646 */
{
- if ((yyvsp[(2) - (5)]) == NULL)
- (yyval) = list_create(instruction(Op_no_op));
+ INSTRUCTION *ip;
+ if ((yyvsp[-3]) == NULL)
+ ip = list_create(instruction(Op_no_op));
else
- (yyval) = (yyvsp[(2) - (5)]);
+ ip = (yyvsp[-3]);
+ (yyval) = ip;
}
+#line 2111 "awkgram.c" /* yacc.c:1646 */
break;
- case 22:
-
-/* Line 1821 of yacc.c */
-#line 337 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+ case 26:
+#line 402 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 2117 "awkgram.c" /* yacc.c:1646 */
break;
- case 23:
-
-/* Line 1821 of yacc.c */
-#line 339 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+ case 27:
+#line 404 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 2123 "awkgram.c" /* yacc.c:1646 */
break;
- case 24:
-
-/* Line 1821 of yacc.c */
-#line 341 "awkgram.y"
+ case 28:
+#line 406 "awkgram.y" /* yacc.c:1646 */
{
yyerror(_("`%s' is a built-in function, it cannot be redefined"),
tokstart);
YYABORT;
}
+#line 2133 "awkgram.c" /* yacc.c:1646 */
break;
- case 25:
-
-/* Line 1821 of yacc.c */
-#line 347 "awkgram.y"
- { (yyval) = (yyvsp[(2) - (2)]); }
+ case 29:
+#line 412 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 2139 "awkgram.c" /* yacc.c:1646 */
break;
- case 28:
-
-/* Line 1821 of yacc.c */
-#line 357 "awkgram.y"
+ case 32:
+#line 422 "awkgram.y" /* yacc.c:1646 */
{
- (yyvsp[(1) - (6)])->source_file = source;
- if (install_function((yyvsp[(2) - (6)])->lextok, (yyvsp[(1) - (6)]), (yyvsp[(4) - (6)])) < 0)
+ /*
+ * treat any comments between BOF and the first function
+ * definition (with no intervening BEGIN etc block) as
+ * program comments. Special kludge: iff there are more
+ * than one such comments, treat the last as a function
+ * comment.
+ */
+ if (comment != NULL && func_first
+ && strstr(comment->memory->stptr, "\n\n") != NULL)
+ split_comment();
+ /* save any other pre-function comment as function comment */
+ if (comment != NULL) {
+ function_comment = comment;
+ comment = NULL;
+ }
+ func_first = false;
+ (yyvsp[-5])->source_file = source;
+ if (install_function((yyvsp[-4])->lextok, (yyvsp[-5]), (yyvsp[-2])) < 0)
YYABORT;
- in_function = (yyvsp[(2) - (6)])->lextok;
- (yyvsp[(2) - (6)])->lextok = NULL;
- bcfree((yyvsp[(2) - (6)]));
+ in_function = (yyvsp[-4])->lextok;
+ (yyvsp[-4])->lextok = NULL;
+ bcfree((yyvsp[-4]));
/* $4 already free'd in install_function */
- (yyval) = (yyvsp[(1) - (6)]);
+ (yyval) = (yyvsp[-5]);
}
+#line 2170 "awkgram.c" /* yacc.c:1646 */
break;
- case 29:
-
-/* Line 1821 of yacc.c */
-#line 375 "awkgram.y"
- { ++want_regexp; }
+ case 33:
+#line 456 "awkgram.y" /* yacc.c:1646 */
+ { want_regexp = true; }
+#line 2176 "awkgram.c" /* yacc.c:1646 */
break;
- case 30:
-
-/* Line 1821 of yacc.c */
-#line 377 "awkgram.y"
+ case 34:
+#line 458 "awkgram.y" /* yacc.c:1646 */
{
NODE *n, *exp;
char *re;
size_t len;
- re = (yyvsp[(3) - (3)])->lextok;
- (yyvsp[(3) - (3)])->lextok = NULL;
+ re = (yyvsp[0])->lextok;
+ (yyvsp[0])->lextok = NULL;
len = strlen(re);
if (do_lint) {
if (len == 0)
- lintwarn_ln((yyvsp[(3) - (3)])->source_line,
+ lintwarn_ln((yyvsp[0])->source_line,
_("regexp constant `//' looks like a C++ comment, but is not"));
- else if ((re)[0] == '*' && (re)[len-1] == '*')
+ else if (re[0] == '*' && re[len-1] == '*')
/* possible C comment */
- lintwarn_ln((yyvsp[(3) - (3)])->source_line,
+ lintwarn_ln((yyvsp[0])->source_line,
_("regexp constant `/%s/' looks like a C comment, but is not"), re);
}
@@ -2336,81 +2201,93 @@ yyreduce:
unref(exp);
YYABORT;
}
- (yyval) = (yyvsp[(3) - (3)]);
+ (yyval) = (yyvsp[0]);
(yyval)->opcode = Op_match_rec;
(yyval)->memory = n;
}
+#line 2209 "awkgram.c" /* yacc.c:1646 */
break;
- case 31:
-
-/* Line 1821 of yacc.c */
-#line 409 "awkgram.y"
- { bcfree((yyvsp[(1) - (1)])); }
+ case 35:
+#line 490 "awkgram.y" /* yacc.c:1646 */
+ { bcfree((yyvsp[0])); }
+#line 2215 "awkgram.c" /* yacc.c:1646 */
break;
- case 33:
-
-/* Line 1821 of yacc.c */
-#line 415 "awkgram.y"
- { (yyval) = NULL; }
+ case 37:
+#line 496 "awkgram.y" /* yacc.c:1646 */
+ {
+ if (comment != NULL) {
+ (yyval) = list_create(comment);
+ comment = NULL;
+ } else (yyval) = NULL;
+ }
+#line 2226 "awkgram.c" /* yacc.c:1646 */
break;
- case 34:
-
-/* Line 1821 of yacc.c */
-#line 417 "awkgram.y"
+ case 38:
+#line 503 "awkgram.y" /* yacc.c:1646 */
{
- if ((yyvsp[(2) - (2)]) == NULL)
- (yyval) = (yyvsp[(1) - (2)]);
- else {
- add_lint((yyvsp[(2) - (2)]), LINT_no_effect);
- if ((yyvsp[(1) - (2)]) == NULL)
- (yyval) = (yyvsp[(2) - (2)]);
- else
- (yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
+ if ((yyvsp[0]) == NULL) {
+ if (comment == NULL)
+ (yyval) = (yyvsp[-1]);
+ else {
+ (yyval) = list_append((yyvsp[-1]), comment);
+ comment = NULL;
+ }
+ } else {
+ add_lint((yyvsp[0]), LINT_no_effect);
+ if ((yyvsp[-1]) == NULL) {
+ if (comment == NULL)
+ (yyval) = (yyvsp[0]);
+ else {
+ (yyval) = list_append((yyvsp[0]), comment);
+ comment = NULL;
+ }
+ } else {
+ if (comment != NULL) {
+ list_append((yyvsp[0]), comment);
+ comment = NULL;
+ }
+ (yyval) = list_merge((yyvsp[-1]), (yyvsp[0]));
+ }
}
- yyerrok;
+ yyerrok;
}
+#line 2258 "awkgram.c" /* yacc.c:1646 */
break;
- case 35:
-
-/* Line 1821 of yacc.c */
-#line 430 "awkgram.y"
+ case 39:
+#line 531 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 2264 "awkgram.c" /* yacc.c:1646 */
break;
- case 38:
-
-/* Line 1821 of yacc.c */
-#line 440 "awkgram.y"
+ case 42:
+#line 541 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 2270 "awkgram.c" /* yacc.c:1646 */
break;
- case 39:
-
-/* Line 1821 of yacc.c */
-#line 442 "awkgram.y"
- { (yyval) = (yyvsp[(2) - (3)]); }
+ case 43:
+#line 543 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[-1]); }
+#line 2276 "awkgram.c" /* yacc.c:1646 */
break;
- case 40:
-
-/* Line 1821 of yacc.c */
-#line 444 "awkgram.y"
+ case 44:
+#line 545 "awkgram.y" /* yacc.c:1646 */
{
- if (do_profiling)
- (yyval) = list_prepend((yyvsp[(1) - (1)]), instruction(Op_exec_count));
+ if (do_pretty_print)
+ (yyval) = list_prepend((yyvsp[0]), instruction(Op_exec_count));
else
- (yyval) = (yyvsp[(1) - (1)]);
+ (yyval) = (yyvsp[0]);
}
+#line 2287 "awkgram.c" /* yacc.c:1646 */
break;
- case 41:
-
-/* Line 1821 of yacc.c */
-#line 451 "awkgram.y"
+ case 45:
+#line 552 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *dflt, *curr = NULL, *cexp, *cstmt;
INSTRUCTION *ip, *nextc, *tbreak;
@@ -2425,13 +2302,13 @@ yyreduce:
dflt = instruction(Op_jmp);
dflt->target_jmp = tbreak; /* if no case match and no explicit default */
- if ((yyvsp[(7) - (9)]) != NULL) {
- curr = (yyvsp[(7) - (9)])->nexti;
- bcfree((yyvsp[(7) - (9)])); /* Op_list */
+ if ((yyvsp[-2]) != NULL) {
+ curr = (yyvsp[-2])->nexti;
+ bcfree((yyvsp[-2])); /* Op_list */
} /* else
curr = NULL; */
- for(; curr != NULL; curr = nextc) {
+ for (; curr != NULL; curr = nextc) {
INSTRUCTION *caseexp = curr->case_exp;
INSTRUCTION *casestmt = curr->case_stmt;
@@ -2456,7 +2333,7 @@ yyreduce:
case_values[case_count++] = caseval;
} else {
/* match a constant regex against switch expression. */
- (curr + 1)->match_exp = TRUE;
+ (curr + 1)->match_exp = true;
}
curr->stmt_start = casestmt->nexti;
curr->stmt_end = casestmt->lasti;
@@ -2469,7 +2346,7 @@ yyreduce:
else
dflt->target_jmp = casestmt->nexti;
- if (do_profiling) {
+ if (do_pretty_print) {
curr->stmt_start = casestmt->nexti;
curr->stmt_end = casestmt->lasti;
(void) list_prepend(cexp, curr);
@@ -2483,13 +2360,13 @@ yyreduce:
if (case_values != NULL)
efree(case_values);
- ip = (yyvsp[(3) - (9)]);
- if (do_profiling) {
- (void) list_prepend(ip, (yyvsp[(1) - (9)]));
+ ip = (yyvsp[-6]);
+ if (do_pretty_print) {
+ (void) list_prepend(ip, (yyvsp[-8]));
(void) list_prepend(ip, instruction(Op_exec_count));
- (yyvsp[(1) - (9)])->target_break = tbreak;
- ((yyvsp[(1) - (9)]) + 1)->switch_start = cexp->nexti;
- ((yyvsp[(1) - (9)]) + 1)->switch_end = cexp->lasti;
+ (yyvsp[-8])->target_break = tbreak;
+ ((yyvsp[-8]) + 1)->switch_start = cexp->nexti;
+ ((yyvsp[-8]) + 1)->switch_end = cexp->lasti;
}/* else
$1 is NULL */
@@ -2500,12 +2377,11 @@ yyreduce:
break_allowed--;
fix_break_continue(ip, tbreak, NULL);
}
+#line 2381 "awkgram.c" /* yacc.c:1646 */
break;
- case 42:
-
-/* Line 1821 of yacc.c */
-#line 541 "awkgram.y"
+ case 46:
+#line 642 "awkgram.y" /* yacc.c:1646 */
{
/*
* -----------------
@@ -2523,22 +2399,22 @@ yyreduce:
INSTRUCTION *ip, *tbreak, *tcont;
tbreak = instruction(Op_no_op);
- add_lint((yyvsp[(3) - (6)]), LINT_assign_in_cond);
- tcont = (yyvsp[(3) - (6)])->nexti;
- ip = list_append((yyvsp[(3) - (6)]), instruction(Op_jmp_false));
+ add_lint((yyvsp[-3]), LINT_assign_in_cond);
+ tcont = (yyvsp[-3])->nexti;
+ ip = list_append((yyvsp[-3]), instruction(Op_jmp_false));
ip->lasti->target_jmp = tbreak;
- if (do_profiling) {
+ if (do_pretty_print) {
(void) list_append(ip, instruction(Op_exec_count));
- (yyvsp[(1) - (6)])->target_break = tbreak;
- (yyvsp[(1) - (6)])->target_continue = tcont;
- ((yyvsp[(1) - (6)]) + 1)->while_body = ip->lasti;
- (void) list_prepend(ip, (yyvsp[(1) - (6)]));
+ (yyvsp[-5])->target_break = tbreak;
+ (yyvsp[-5])->target_continue = tcont;
+ ((yyvsp[-5]) + 1)->while_body = ip->lasti;
+ (void) list_prepend(ip, (yyvsp[-5]));
}/* else
$1 is NULL */
- if ((yyvsp[(6) - (6)]) != NULL)
- (void) list_merge(ip, (yyvsp[(6) - (6)]));
+ if ((yyvsp[0]) != NULL)
+ (void) list_merge(ip, (yyvsp[0]));
(void) list_append(ip, instruction(Op_jmp));
ip->lasti->target_jmp = tcont;
(yyval) = list_append(ip, tbreak);
@@ -2547,12 +2423,11 @@ yyreduce:
continue_allowed--;
fix_break_continue(ip, tbreak, tcont);
}
+#line 2427 "awkgram.c" /* yacc.c:1646 */
break;
- case 43:
-
-/* Line 1821 of yacc.c */
-#line 583 "awkgram.y"
+ case 47:
+#line 684 "awkgram.y" /* yacc.c:1646 */
{
/*
* -----------------
@@ -2569,13 +2444,13 @@ yyreduce:
INSTRUCTION *ip, *tbreak, *tcont;
tbreak = instruction(Op_no_op);
- tcont = (yyvsp[(6) - (8)])->nexti;
- add_lint((yyvsp[(6) - (8)]), LINT_assign_in_cond);
- if ((yyvsp[(3) - (8)]) != NULL)
- ip = list_merge((yyvsp[(3) - (8)]), (yyvsp[(6) - (8)]));
+ tcont = (yyvsp[-2])->nexti;
+ add_lint((yyvsp[-2]), LINT_assign_in_cond);
+ if ((yyvsp[-5]) != NULL)
+ ip = list_merge((yyvsp[-5]), (yyvsp[-2]));
else
- ip = list_prepend((yyvsp[(6) - (8)]), instruction(Op_no_op));
- if (do_profiling)
+ ip = list_prepend((yyvsp[-2]), instruction(Op_no_op));
+ if (do_pretty_print)
(void) list_prepend(ip, instruction(Op_exec_count));
(void) list_append(ip, instruction(Op_jmp_true));
ip->lasti->target_jmp = ip->nexti;
@@ -2585,31 +2460,30 @@ yyreduce:
continue_allowed--;
fix_break_continue(ip, tbreak, tcont);
- if (do_profiling) {
- (yyvsp[(1) - (8)])->target_break = tbreak;
- (yyvsp[(1) - (8)])->target_continue = tcont;
- ((yyvsp[(1) - (8)]) + 1)->doloop_cond = tcont;
- (yyval) = list_prepend(ip, (yyvsp[(1) - (8)]));
- bcfree((yyvsp[(4) - (8)]));
+ if (do_pretty_print) {
+ (yyvsp[-7])->target_break = tbreak;
+ (yyvsp[-7])->target_continue = tcont;
+ ((yyvsp[-7]) + 1)->doloop_cond = tcont;
+ (yyval) = list_prepend(ip, (yyvsp[-7]));
+ bcfree((yyvsp[-4]));
} /* else
- $1 and $4 are NULLs */
+ $1 and $4 are NULLs */
}
+#line 2473 "awkgram.c" /* yacc.c:1646 */
break;
- case 44:
-
-/* Line 1821 of yacc.c */
-#line 625 "awkgram.y"
+ case 48:
+#line 726 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *ip;
- char *var_name = (yyvsp[(3) - (8)])->lextok;
-
- if ((yyvsp[(8) - (8)]) != NULL
- && (yyvsp[(8) - (8)])->lasti->opcode == Op_K_delete
- && (yyvsp[(8) - (8)])->lasti->expr_count == 1
- && (yyvsp[(8) - (8)])->nexti->opcode == Op_push
- && ((yyvsp[(8) - (8)])->nexti->memory->type != Node_var || !((yyvsp[(8) - (8)])->nexti->memory->var_update))
- && strcmp((yyvsp[(8) - (8)])->nexti->memory->vname, var_name) == 0
+ char *var_name = (yyvsp[-5])->lextok;
+
+ if ((yyvsp[0]) != NULL
+ && (yyvsp[0])->lasti->opcode == Op_K_delete
+ && (yyvsp[0])->lasti->expr_count == 1
+ && (yyvsp[0])->nexti->opcode == Op_push
+ && ((yyvsp[0])->nexti->memory->type != Node_var || !((yyvsp[0])->nexti->memory->var_update))
+ && strcmp((yyvsp[0])->nexti->memory->vname, var_name) == 0
) {
/* Efficiency hack. Recognize the special case of
@@ -2626,85 +2500,85 @@ yyreduce:
*/
NODE *arr = NULL;
- ip = (yyvsp[(8) - (8)])->nexti->nexti;
- if ((yyvsp[(5) - (8)])->nexti->opcode == Op_push && (yyvsp[(5) - (8)])->lasti == (yyvsp[(5) - (8)])->nexti)
- arr = (yyvsp[(5) - (8)])->nexti->memory;
+ ip = (yyvsp[0])->nexti->nexti;
+ if ((yyvsp[-3])->nexti->opcode == Op_push && (yyvsp[-3])->lasti == (yyvsp[-3])->nexti)
+ arr = (yyvsp[-3])->nexti->memory;
if (arr != NULL
&& ip->opcode == Op_no_op
&& ip->nexti->opcode == Op_push_array
&& strcmp(ip->nexti->memory->vname, arr->vname) == 0
- && ip->nexti->nexti == (yyvsp[(8) - (8)])->lasti
+ && ip->nexti->nexti == (yyvsp[0])->lasti
) {
- (void) make_assignable((yyvsp[(8) - (8)])->nexti);
- (yyvsp[(8) - (8)])->lasti->opcode = Op_K_delete_loop;
- (yyvsp[(8) - (8)])->lasti->expr_count = 0;
- if ((yyvsp[(1) - (8)]) != NULL)
- bcfree((yyvsp[(1) - (8)]));
+ (void) make_assignable((yyvsp[0])->nexti);
+ (yyvsp[0])->lasti->opcode = Op_K_delete_loop;
+ (yyvsp[0])->lasti->expr_count = 0;
+ if ((yyvsp[-7]) != NULL)
+ bcfree((yyvsp[-7]));
efree(var_name);
- bcfree((yyvsp[(3) - (8)]));
- bcfree((yyvsp[(4) - (8)]));
- bcfree((yyvsp[(5) - (8)]));
- (yyval) = (yyvsp[(8) - (8)]);
+ bcfree((yyvsp[-5]));
+ bcfree((yyvsp[-4]));
+ bcfree((yyvsp[-3]));
+ (yyval) = (yyvsp[0]);
} else
goto regular_loop;
} else {
INSTRUCTION *tbreak, *tcont;
- /* [ Op_push_array a ]
- * [ Op_arrayfor_init | ib ]
- * ic:[ Op_arrayfor_incr | ib ]
- * [ Op_var_assign if any ]
- *
- * body
- *
- * [Op_jmp | ic ]
- * ib:[Op_arrayfor_final ]
- */
+ /* [ Op_push_array a ]
+ * [ Op_arrayfor_init | ib ]
+ * ic:[ Op_arrayfor_incr | ib ]
+ * [ Op_var_assign if any ]
+ *
+ * body
+ *
+ * [Op_jmp | ic ]
+ * ib:[Op_arrayfor_final ]
+ */
regular_loop:
- ip = (yyvsp[(5) - (8)]);
+ ip = (yyvsp[-3]);
ip->nexti->opcode = Op_push_array;
tbreak = instruction(Op_arrayfor_final);
- (yyvsp[(4) - (8)])->opcode = Op_arrayfor_incr;
- (yyvsp[(4) - (8)])->array_var = variable((yyvsp[(3) - (8)])->source_line, var_name, Node_var);
- (yyvsp[(4) - (8)])->target_jmp = tbreak;
- tcont = (yyvsp[(4) - (8)]);
- (yyvsp[(3) - (8)])->opcode = Op_arrayfor_init;
- (yyvsp[(3) - (8)])->target_jmp = tbreak;
- (void) list_append(ip, (yyvsp[(3) - (8)]));
-
- if (do_profiling) {
- (yyvsp[(1) - (8)])->opcode = Op_K_arrayfor;
- (yyvsp[(1) - (8)])->target_continue = tcont;
- (yyvsp[(1) - (8)])->target_break = tbreak;
- (void) list_append(ip, (yyvsp[(1) - (8)]));
+ (yyvsp[-4])->opcode = Op_arrayfor_incr;
+ (yyvsp[-4])->array_var = variable((yyvsp[-5])->source_line, var_name, Node_var);
+ (yyvsp[-4])->target_jmp = tbreak;
+ tcont = (yyvsp[-4]);
+ (yyvsp[-5])->opcode = Op_arrayfor_init;
+ (yyvsp[-5])->target_jmp = tbreak;
+ (void) list_append(ip, (yyvsp[-5]));
+
+ if (do_pretty_print) {
+ (yyvsp[-7])->opcode = Op_K_arrayfor;
+ (yyvsp[-7])->target_continue = tcont;
+ (yyvsp[-7])->target_break = tbreak;
+ (void) list_append(ip, (yyvsp[-7]));
} /* else
$1 is NULL */
/* add update_FOO instruction if necessary */
- if ((yyvsp[(4) - (8)])->array_var->type == Node_var && (yyvsp[(4) - (8)])->array_var->var_update) {
+ if ((yyvsp[-4])->array_var->type == Node_var && (yyvsp[-4])->array_var->var_update) {
(void) list_append(ip, instruction(Op_var_update));
- ip->lasti->update_var = (yyvsp[(4) - (8)])->array_var->var_update;
+ ip->lasti->update_var = (yyvsp[-4])->array_var->var_update;
}
- (void) list_append(ip, (yyvsp[(4) - (8)]));
+ (void) list_append(ip, (yyvsp[-4]));
/* add set_FOO instruction if necessary */
- if ((yyvsp[(4) - (8)])->array_var->type == Node_var && (yyvsp[(4) - (8)])->array_var->var_assign) {
+ if ((yyvsp[-4])->array_var->type == Node_var && (yyvsp[-4])->array_var->var_assign) {
(void) list_append(ip, instruction(Op_var_assign));
- ip->lasti->assign_var = (yyvsp[(4) - (8)])->array_var->var_assign;
+ ip->lasti->assign_var = (yyvsp[-4])->array_var->var_assign;
}
- if (do_profiling) {
+ if (do_pretty_print) {
(void) list_append(ip, instruction(Op_exec_count));
- ((yyvsp[(1) - (8)]) + 1)->forloop_cond = (yyvsp[(4) - (8)]);
- ((yyvsp[(1) - (8)]) + 1)->forloop_body = ip->lasti;
+ ((yyvsp[-7]) + 1)->forloop_cond = (yyvsp[-4]);
+ ((yyvsp[-7]) + 1)->forloop_body = ip->lasti;
}
- if ((yyvsp[(8) - (8)]) != NULL)
- (void) list_merge(ip, (yyvsp[(8) - (8)]));
+ if ((yyvsp[0]) != NULL)
+ (void) list_merge(ip, (yyvsp[0]));
(void) list_append(ip, instruction(Op_jmp));
- ip->lasti->target_jmp = (yyvsp[(4) - (8)]);
+ ip->lasti->target_jmp = (yyvsp[-4]);
(yyval) = list_append(ip, tbreak);
fix_break_continue(ip, tbreak, tcont);
}
@@ -2712,173 +2586,157 @@ regular_loop:
break_allowed--;
continue_allowed--;
}
+#line 2590 "awkgram.c" /* yacc.c:1646 */
break;
- case 45:
-
-/* Line 1821 of yacc.c */
-#line 738 "awkgram.y"
+ case 49:
+#line 839 "awkgram.y" /* yacc.c:1646 */
{
- (yyval) = mk_for_loop((yyvsp[(1) - (12)]), (yyvsp[(3) - (12)]), (yyvsp[(6) - (12)]), (yyvsp[(9) - (12)]), (yyvsp[(12) - (12)]));
+ (yyval) = mk_for_loop((yyvsp[-11]), (yyvsp[-9]), (yyvsp[-6]), (yyvsp[-3]), (yyvsp[0]));
break_allowed--;
continue_allowed--;
}
+#line 2601 "awkgram.c" /* yacc.c:1646 */
break;
- case 46:
-
-/* Line 1821 of yacc.c */
-#line 745 "awkgram.y"
+ case 50:
+#line 846 "awkgram.y" /* yacc.c:1646 */
{
- (yyval) = mk_for_loop((yyvsp[(1) - (11)]), (yyvsp[(3) - (11)]), (INSTRUCTION *) NULL, (yyvsp[(8) - (11)]), (yyvsp[(11) - (11)]));
+ (yyval) = mk_for_loop((yyvsp[-10]), (yyvsp[-8]), (INSTRUCTION *) NULL, (yyvsp[-3]), (yyvsp[0]));
break_allowed--;
continue_allowed--;
}
+#line 2612 "awkgram.c" /* yacc.c:1646 */
break;
- case 47:
-
-/* Line 1821 of yacc.c */
-#line 752 "awkgram.y"
+ case 51:
+#line 853 "awkgram.y" /* yacc.c:1646 */
{
- if (do_profiling)
- (yyval) = list_prepend((yyvsp[(1) - (1)]), instruction(Op_exec_count));
+ if (do_pretty_print)
+ (yyval) = list_prepend((yyvsp[0]), instruction(Op_exec_count));
else
- (yyval) = (yyvsp[(1) - (1)]);
+ (yyval) = (yyvsp[0]);
}
+#line 2623 "awkgram.c" /* yacc.c:1646 */
break;
- case 48:
-
-/* Line 1821 of yacc.c */
-#line 762 "awkgram.y"
+ case 52:
+#line 863 "awkgram.y" /* yacc.c:1646 */
{
if (! break_allowed)
- error_ln((yyvsp[(1) - (2)])->source_line,
+ error_ln((yyvsp[-1])->source_line,
_("`break' is not allowed outside a loop or switch"));
- (yyvsp[(1) - (2)])->target_jmp = NULL;
- (yyval) = list_create((yyvsp[(1) - (2)]));
+ (yyvsp[-1])->target_jmp = NULL;
+ (yyval) = list_create((yyvsp[-1]));
}
+#line 2636 "awkgram.c" /* yacc.c:1646 */
break;
- case 49:
-
-/* Line 1821 of yacc.c */
-#line 771 "awkgram.y"
+ case 53:
+#line 872 "awkgram.y" /* yacc.c:1646 */
{
if (! continue_allowed)
- error_ln((yyvsp[(1) - (2)])->source_line,
+ error_ln((yyvsp[-1])->source_line,
_("`continue' is not allowed outside a loop"));
- (yyvsp[(1) - (2)])->target_jmp = NULL;
- (yyval) = list_create((yyvsp[(1) - (2)]));
+ (yyvsp[-1])->target_jmp = NULL;
+ (yyval) = list_create((yyvsp[-1]));
}
+#line 2649 "awkgram.c" /* yacc.c:1646 */
break;
- case 50:
-
-/* Line 1821 of yacc.c */
-#line 780 "awkgram.y"
+ case 54:
+#line 881 "awkgram.y" /* yacc.c:1646 */
{
/* if inside function (rule = 0), resolve context at run-time */
if (rule && rule != Rule)
- error_ln((yyvsp[(1) - (2)])->source_line,
+ error_ln((yyvsp[-1])->source_line,
_("`next' used in %s action"), ruletab[rule]);
- (yyvsp[(1) - (2)])->target_jmp = ip_rec;
- (yyval) = list_create((yyvsp[(1) - (2)]));
+ (yyvsp[-1])->target_jmp = ip_rec;
+ (yyval) = list_create((yyvsp[-1]));
}
+#line 2662 "awkgram.c" /* yacc.c:1646 */
break;
- case 51:
-
-/* Line 1821 of yacc.c */
-#line 789 "awkgram.y"
+ case 55:
+#line 890 "awkgram.y" /* yacc.c:1646 */
{
- if (do_traditional)
- error_ln((yyvsp[(1) - (2)])->source_line,
- _("`nextfile' is a gawk extension"));
-
/* if inside function (rule = 0), resolve context at run-time */
if (rule == BEGIN || rule == END || rule == ENDFILE)
- error_ln((yyvsp[(1) - (2)])->source_line,
+ error_ln((yyvsp[-1])->source_line,
_("`nextfile' used in %s action"), ruletab[rule]);
- (yyvsp[(1) - (2)])->target_newfile = ip_newfile;
- (yyvsp[(1) - (2)])->target_endfile = ip_endfile;
- (yyval) = list_create((yyvsp[(1) - (2)]));
+ (yyvsp[-1])->target_newfile = ip_newfile;
+ (yyvsp[-1])->target_endfile = ip_endfile;
+ (yyval) = list_create((yyvsp[-1]));
}
+#line 2677 "awkgram.c" /* yacc.c:1646 */
break;
- case 52:
-
-/* Line 1821 of yacc.c */
-#line 804 "awkgram.y"
+ case 56:
+#line 901 "awkgram.y" /* yacc.c:1646 */
{
/* Initialize the two possible jump targets, the actual target
* is resolved at run-time.
*/
- (yyvsp[(1) - (3)])->target_end = ip_end; /* first instruction in end_block */
- (yyvsp[(1) - (3)])->target_atexit = ip_atexit; /* cleanup and go home */
+ (yyvsp[-2])->target_end = ip_end; /* first instruction in end_block */
+ (yyvsp[-2])->target_atexit = ip_atexit; /* cleanup and go home */
- if ((yyvsp[(2) - (3)]) == NULL) {
- (yyval) = list_create((yyvsp[(1) - (3)]));
+ if ((yyvsp[-1]) == NULL) {
+ (yyval) = list_create((yyvsp[-2]));
(void) list_prepend((yyval), instruction(Op_push_i));
(yyval)->nexti->memory = dupnode(Nnull_string);
} else
- (yyval) = list_append((yyvsp[(2) - (3)]), (yyvsp[(1) - (3)]));
+ (yyval) = list_append((yyvsp[-1]), (yyvsp[-2]));
}
+#line 2696 "awkgram.c" /* yacc.c:1646 */
break;
- case 53:
-
-/* Line 1821 of yacc.c */
-#line 819 "awkgram.y"
+ case 57:
+#line 916 "awkgram.y" /* yacc.c:1646 */
{
if (! in_function)
yyerror(_("`return' used outside function context"));
}
+#line 2705 "awkgram.c" /* yacc.c:1646 */
break;
- case 54:
-
-/* Line 1821 of yacc.c */
-#line 822 "awkgram.y"
+ case 58:
+#line 919 "awkgram.y" /* yacc.c:1646 */
{
- if ((yyvsp[(3) - (4)]) == NULL) {
- (yyval) = list_create((yyvsp[(1) - (4)]));
+ if ((yyvsp[-1]) == NULL) {
+ (yyval) = list_create((yyvsp[-3]));
(void) list_prepend((yyval), instruction(Op_push_i));
(yyval)->nexti->memory = dupnode(Nnull_string);
} else {
- if (do_optimize > 1
- && (yyvsp[(3) - (4)])->lasti->opcode == Op_func_call
- && STREQ((yyvsp[(3) - (4)])->lasti->func_name, in_function)
+ if (do_optimize
+ && (yyvsp[-1])->lasti->opcode == Op_func_call
+ && strcmp((yyvsp[-1])->lasti->func_name, in_function) == 0
) {
/* Do tail recursion optimization. Tail
* call without a return value is recognized
* in mk_function().
*/
- ((yyvsp[(3) - (4)])->lasti + 1)->tail_call = TRUE;
+ ((yyvsp[-1])->lasti + 1)->tail_call = true;
}
- (yyval) = list_append((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)]));
+ (yyval) = list_append((yyvsp[-1]), (yyvsp[-3]));
}
}
+#line 2730 "awkgram.c" /* yacc.c:1646 */
break;
- case 56:
-
-/* Line 1821 of yacc.c */
-#line 854 "awkgram.y"
- { in_print = TRUE; in_parens = 0; }
+ case 60:
+#line 951 "awkgram.y" /* yacc.c:1646 */
+ { in_print = true; in_parens = 0; }
+#line 2736 "awkgram.c" /* yacc.c:1646 */
break;
- case 57:
-
-/* Line 1821 of yacc.c */
-#line 855 "awkgram.y"
+ case 61:
+#line 952 "awkgram.y" /* yacc.c:1646 */
{
/*
* Optimization: plain `print' has no expression list, so $3 is null.
@@ -2886,16 +2744,15 @@ regular_loop:
* which is faster for these two cases.
*/
- if ((yyvsp[(1) - (4)])->opcode == Op_K_print &&
- ((yyvsp[(3) - (4)]) == NULL
- || ((yyvsp[(3) - (4)])->lasti->opcode == Op_field_spec
- && (yyvsp[(3) - (4)])->nexti->nexti->nexti == (yyvsp[(3) - (4)])->lasti
- && (yyvsp[(3) - (4)])->nexti->nexti->opcode == Op_push_i
- && (yyvsp[(3) - (4)])->nexti->nexti->memory->type == Node_val
- && (yyvsp[(3) - (4)])->nexti->nexti->memory->numbr == 0.0)
+ if ((yyvsp[-3])->opcode == Op_K_print &&
+ ((yyvsp[-1]) == NULL
+ || ((yyvsp[-1])->lasti->opcode == Op_field_spec
+ && (yyvsp[-1])->nexti->nexti->nexti == (yyvsp[-1])->lasti
+ && (yyvsp[-1])->nexti->nexti->opcode == Op_push_i
+ && (yyvsp[-1])->nexti->nexti->memory->type == Node_val)
)
) {
- static short warned = FALSE;
+ static bool warned = false;
/* -----------------
* output_redir
* [ redirect exp ]
@@ -2905,32 +2762,37 @@ regular_loop:
* [Op_K_print_rec | NULL | redir_type | expr_count]
*/
- if ((yyvsp[(3) - (4)]) != NULL) {
- bcfree((yyvsp[(3) - (4)])->lasti); /* Op_field_spec */
- unref((yyvsp[(3) - (4)])->nexti->nexti->memory); /* Node_val */
- bcfree((yyvsp[(3) - (4)])->nexti->nexti); /* Op_push_i */
- bcfree((yyvsp[(3) - (4)])->nexti); /* Op_list */
- bcfree((yyvsp[(3) - (4)])); /* Op_list */
+ if ((yyvsp[-1]) != NULL) {
+ NODE *n = (yyvsp[-1])->nexti->nexti->memory;
+
+ if (! iszero(n))
+ goto regular_print;
+
+ bcfree((yyvsp[-1])->lasti); /* Op_field_spec */
+ unref(n); /* Node_val */
+ bcfree((yyvsp[-1])->nexti->nexti); /* Op_push_i */
+ bcfree((yyvsp[-1])->nexti); /* Op_list */
+ bcfree((yyvsp[-1])); /* Op_list */
} else {
if (do_lint && (rule == BEGIN || rule == END) && ! warned) {
- warned = TRUE;
- lintwarn_ln((yyvsp[(1) - (4)])->source_line,
+ warned = true;
+ lintwarn_ln((yyvsp[-3])->source_line,
_("plain `print' in BEGIN or END rule should probably be `print \"\"'"));
}
}
- (yyvsp[(1) - (4)])->expr_count = 0;
- (yyvsp[(1) - (4)])->opcode = Op_K_print_rec;
- if ((yyvsp[(4) - (4)]) == NULL) { /* no redircetion */
- (yyvsp[(1) - (4)])->redir_type = 0;
- (yyval) = list_create((yyvsp[(1) - (4)]));
+ (yyvsp[-3])->expr_count = 0;
+ (yyvsp[-3])->opcode = Op_K_print_rec;
+ if ((yyvsp[0]) == NULL) { /* no redircetion */
+ (yyvsp[-3])->redir_type = redirect_none;
+ (yyval) = list_create((yyvsp[-3]));
} else {
INSTRUCTION *ip;
- ip = (yyvsp[(4) - (4)])->nexti;
- (yyvsp[(1) - (4)])->redir_type = ip->redir_type;
- (yyvsp[(4) - (4)])->nexti = ip->nexti;
+ ip = (yyvsp[0])->nexti;
+ (yyvsp[-3])->redir_type = ip->redir_type;
+ (yyvsp[0])->nexti = ip->nexti;
bcfree(ip);
- (yyval) = list_append((yyvsp[(4) - (4)]), (yyvsp[(1) - (4)]));
+ (yyval) = list_append((yyvsp[0]), (yyvsp[-3]));
}
} else {
/* -----------------
@@ -2942,622 +2804,590 @@ regular_loop:
* [$1 | NULL | redir_type | expr_count]
*
*/
-
- if ((yyvsp[(4) - (4)]) == NULL) { /* no redirection */
- if ((yyvsp[(3) - (4)]) == NULL) { /* printf without arg */
- (yyvsp[(1) - (4)])->expr_count = 0;
- (yyvsp[(1) - (4)])->redir_type = 0;
- (yyval) = list_create((yyvsp[(1) - (4)]));
+regular_print:
+ if ((yyvsp[0]) == NULL) { /* no redirection */
+ if ((yyvsp[-1]) == NULL) { /* printf without arg */
+ (yyvsp[-3])->expr_count = 0;
+ (yyvsp[-3])->redir_type = redirect_none;
+ (yyval) = list_create((yyvsp[-3]));
} else {
- INSTRUCTION *t = (yyvsp[(3) - (4)]);
- (yyvsp[(1) - (4)])->expr_count = count_expressions(&t, FALSE);
- (yyvsp[(1) - (4)])->redir_type = 0;
- (yyval) = list_append(t, (yyvsp[(1) - (4)]));
+ INSTRUCTION *t = (yyvsp[-1]);
+ (yyvsp[-3])->expr_count = count_expressions(&t, false);
+ (yyvsp[-3])->redir_type = redirect_none;
+ (yyval) = list_append(t, (yyvsp[-3]));
}
} else {
INSTRUCTION *ip;
- ip = (yyvsp[(4) - (4)])->nexti;
- (yyvsp[(1) - (4)])->redir_type = ip->redir_type;
- (yyvsp[(4) - (4)])->nexti = ip->nexti;
+ ip = (yyvsp[0])->nexti;
+ (yyvsp[-3])->redir_type = ip->redir_type;
+ (yyvsp[0])->nexti = ip->nexti;
bcfree(ip);
- if ((yyvsp[(3) - (4)]) == NULL) {
- (yyvsp[(1) - (4)])->expr_count = 0;
- (yyval) = list_append((yyvsp[(4) - (4)]), (yyvsp[(1) - (4)]));
+ if ((yyvsp[-1]) == NULL) {
+ (yyvsp[-3])->expr_count = 0;
+ (yyval) = list_append((yyvsp[0]), (yyvsp[-3]));
} else {
- INSTRUCTION *t = (yyvsp[(3) - (4)]);
- (yyvsp[(1) - (4)])->expr_count = count_expressions(&t, FALSE);
- (yyval) = list_append(list_merge((yyvsp[(4) - (4)]), t), (yyvsp[(1) - (4)]));
+ INSTRUCTION *t = (yyvsp[-1]);
+ (yyvsp[-3])->expr_count = count_expressions(&t, false);
+ (yyval) = list_append(list_merge((yyvsp[0]), t), (yyvsp[-3]));
}
}
}
}
+#line 2837 "awkgram.c" /* yacc.c:1646 */
break;
- case 58:
-
-/* Line 1821 of yacc.c */
-#line 948 "awkgram.y"
+ case 62:
+#line 1049 "awkgram.y" /* yacc.c:1646 */
{ sub_counter = 0; }
+#line 2843 "awkgram.c" /* yacc.c:1646 */
break;
- case 59:
-
-/* Line 1821 of yacc.c */
-#line 949 "awkgram.y"
+ case 63:
+#line 1050 "awkgram.y" /* yacc.c:1646 */
{
- char *arr = (yyvsp[(2) - (4)])->lextok;
+ char *arr = (yyvsp[-2])->lextok;
- (yyvsp[(2) - (4)])->opcode = Op_push_array;
- (yyvsp[(2) - (4)])->memory = variable((yyvsp[(2) - (4)])->source_line, arr, Node_var_new);
+ (yyvsp[-2])->opcode = Op_push_array;
+ (yyvsp[-2])->memory = variable((yyvsp[-2])->source_line, arr, Node_var_new);
- if ((yyvsp[(4) - (4)]) == NULL) {
- static short warned = FALSE;
+ if (! do_posix && ! do_traditional) {
+ if ((yyvsp[-2])->memory == symbol_table)
+ fatal(_("`delete' is not allowed with SYMTAB"));
+ else if ((yyvsp[-2])->memory == func_table)
+ fatal(_("`delete' is not allowed with FUNCTAB"));
+ }
- if (do_lint && ! warned) {
- warned = TRUE;
- lintwarn_ln((yyvsp[(1) - (4)])->source_line,
- _("`delete array' is a gawk extension"));
- }
- if (do_traditional)
- error_ln((yyvsp[(1) - (4)])->source_line,
- _("`delete array' is a gawk extension"));
- (yyvsp[(1) - (4)])->expr_count = 0;
- (yyval) = list_append(list_create((yyvsp[(2) - (4)])), (yyvsp[(1) - (4)]));
+ if ((yyvsp[0]) == NULL) {
+ /*
+ * As of September 2012, POSIX has added support
+ * for `delete array'. See:
+ * http://austingroupbugs.net/view.php?id=544
+ *
+ * Thanks to Nathan Weeks for the initiative.
+ *
+ * Thus we no longer warn or check do_posix.
+ * Also, since BWK awk supports it, we don't have to
+ * check do_traditional either.
+ */
+ (yyvsp[-3])->expr_count = 0;
+ (yyval) = list_append(list_create((yyvsp[-2])), (yyvsp[-3]));
} else {
- (yyvsp[(1) - (4)])->expr_count = sub_counter;
- (yyval) = list_append(list_append((yyvsp[(4) - (4)]), (yyvsp[(2) - (4)])), (yyvsp[(1) - (4)]));
+ (yyvsp[-3])->expr_count = sub_counter;
+ (yyval) = list_append(list_append((yyvsp[0]), (yyvsp[-2])), (yyvsp[-3]));
}
}
+#line 2880 "awkgram.c" /* yacc.c:1646 */
break;
- case 60:
-
-/* Line 1821 of yacc.c */
-#line 978 "awkgram.y"
+ case 64:
+#line 1087 "awkgram.y" /* yacc.c:1646 */
{
- static short warned = FALSE;
- char *arr = (yyvsp[(3) - (4)])->lextok;
+ static bool warned = false;
+ char *arr = (yyvsp[-1])->lextok;
if (do_lint && ! warned) {
- warned = TRUE;
- lintwarn_ln((yyvsp[(1) - (4)])->source_line,
+ warned = true;
+ lintwarn_ln((yyvsp[-3])->source_line,
_("`delete(array)' is a non-portable tawk extension"));
}
if (do_traditional) {
- error_ln((yyvsp[(1) - (4)])->source_line,
- _("`delete array' is a gawk extension"));
+ error_ln((yyvsp[-3])->source_line,
+ _("`delete(array)' is a non-portable tawk extension"));
+ }
+ (yyvsp[-1])->memory = variable((yyvsp[-1])->source_line, arr, Node_var_new);
+ (yyvsp[-1])->opcode = Op_push_array;
+ (yyvsp[-3])->expr_count = 0;
+ (yyval) = list_append(list_create((yyvsp[-1])), (yyvsp[-3]));
+
+ if (! do_posix && ! do_traditional) {
+ if ((yyvsp[-1])->memory == symbol_table)
+ fatal(_("`delete' is not allowed with SYMTAB"));
+ else if ((yyvsp[-1])->memory == func_table)
+ fatal(_("`delete' is not allowed with FUNCTAB"));
}
- (yyvsp[(3) - (4)])->memory = variable((yyvsp[(3) - (4)])->source_line, arr, Node_var_new);
- (yyvsp[(3) - (4)])->opcode = Op_push_array;
- (yyvsp[(1) - (4)])->expr_count = 0;
- (yyval) = list_append(list_create((yyvsp[(3) - (4)])), (yyvsp[(1) - (4)]));
}
+#line 2910 "awkgram.c" /* yacc.c:1646 */
break;
- case 61:
-
-/* Line 1821 of yacc.c */
-#line 997 "awkgram.y"
- { (yyval) = optimize_assignment((yyvsp[(1) - (1)])); }
+ case 65:
+#line 1113 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = optimize_assignment((yyvsp[0])); }
+#line 2916 "awkgram.c" /* yacc.c:1646 */
break;
- case 62:
-
-/* Line 1821 of yacc.c */
-#line 1002 "awkgram.y"
+ case 66:
+#line 1118 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 2922 "awkgram.c" /* yacc.c:1646 */
break;
- case 63:
-
-/* Line 1821 of yacc.c */
-#line 1004 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+ case 67:
+#line 1120 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 2928 "awkgram.c" /* yacc.c:1646 */
break;
- case 64:
-
-/* Line 1821 of yacc.c */
-#line 1009 "awkgram.y"
+ case 68:
+#line 1125 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 2934 "awkgram.c" /* yacc.c:1646 */
break;
- case 65:
-
-/* Line 1821 of yacc.c */
-#line 1011 "awkgram.y"
+ case 69:
+#line 1127 "awkgram.y" /* yacc.c:1646 */
{
- if ((yyvsp[(1) - (2)]) == NULL)
- (yyval) = list_create((yyvsp[(2) - (2)]));
+ if ((yyvsp[-1]) == NULL)
+ (yyval) = list_create((yyvsp[0]));
else
- (yyval) = list_prepend((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
+ (yyval) = list_prepend((yyvsp[-1]), (yyvsp[0]));
}
+#line 2945 "awkgram.c" /* yacc.c:1646 */
break;
- case 66:
-
-/* Line 1821 of yacc.c */
-#line 1018 "awkgram.y"
+ case 70:
+#line 1134 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 2951 "awkgram.c" /* yacc.c:1646 */
break;
- case 67:
-
-/* Line 1821 of yacc.c */
-#line 1023 "awkgram.y"
+ case 71:
+#line 1139 "awkgram.y" /* yacc.c:1646 */
{
- INSTRUCTION *casestmt = (yyvsp[(5) - (5)]);
- if ((yyvsp[(5) - (5)]) == NULL)
+ INSTRUCTION *casestmt = (yyvsp[0]);
+ if ((yyvsp[0]) == NULL)
casestmt = list_create(instruction(Op_no_op));
- if (do_profiling)
+ if (do_pretty_print)
(void) list_prepend(casestmt, instruction(Op_exec_count));
- (yyvsp[(1) - (5)])->case_exp = (yyvsp[(2) - (5)]);
- (yyvsp[(1) - (5)])->case_stmt = casestmt;
- bcfree((yyvsp[(3) - (5)]));
- (yyval) = (yyvsp[(1) - (5)]);
+ (yyvsp[-4])->case_exp = (yyvsp[-3]);
+ (yyvsp[-4])->case_stmt = casestmt;
+ bcfree((yyvsp[-2]));
+ (yyval) = (yyvsp[-4]);
}
+#line 2967 "awkgram.c" /* yacc.c:1646 */
break;
- case 68:
-
-/* Line 1821 of yacc.c */
-#line 1035 "awkgram.y"
+ case 72:
+#line 1151 "awkgram.y" /* yacc.c:1646 */
{
- INSTRUCTION *casestmt = (yyvsp[(4) - (4)]);
- if ((yyvsp[(4) - (4)]) == NULL)
+ INSTRUCTION *casestmt = (yyvsp[0]);
+ if ((yyvsp[0]) == NULL)
casestmt = list_create(instruction(Op_no_op));
- if (do_profiling)
+ if (do_pretty_print)
(void) list_prepend(casestmt, instruction(Op_exec_count));
- bcfree((yyvsp[(2) - (4)]));
- (yyvsp[(1) - (4)])->case_stmt = casestmt;
- (yyval) = (yyvsp[(1) - (4)]);
+ bcfree((yyvsp[-2]));
+ (yyvsp[-3])->case_stmt = casestmt;
+ (yyval) = (yyvsp[-3]);
}
+#line 2982 "awkgram.c" /* yacc.c:1646 */
break;
- case 69:
-
-/* Line 1821 of yacc.c */
-#line 1049 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+ case 73:
+#line 1165 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 2988 "awkgram.c" /* yacc.c:1646 */
break;
- case 70:
-
-/* Line 1821 of yacc.c */
-#line 1051 "awkgram.y"
+ case 74:
+#line 1167 "awkgram.y" /* yacc.c:1646 */
{
- (yyvsp[(2) - (2)])->memory->numbr = -(force_number((yyvsp[(2) - (2)])->memory));
- bcfree((yyvsp[(1) - (2)]));
- (yyval) = (yyvsp[(2) - (2)]);
+ NODE *n = (yyvsp[0])->memory;
+ (void) force_number(n);
+ negate_num(n);
+ bcfree((yyvsp[-1]));
+ (yyval) = (yyvsp[0]);
}
+#line 3000 "awkgram.c" /* yacc.c:1646 */
break;
- case 71:
-
-/* Line 1821 of yacc.c */
-#line 1057 "awkgram.y"
+ case 75:
+#line 1175 "awkgram.y" /* yacc.c:1646 */
{
- bcfree((yyvsp[(1) - (2)]));
- (yyval) = (yyvsp[(2) - (2)]);
+ bcfree((yyvsp[-1]));
+ (yyval) = (yyvsp[0]);
}
+#line 3009 "awkgram.c" /* yacc.c:1646 */
break;
- case 72:
-
-/* Line 1821 of yacc.c */
-#line 1062 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+ case 76:
+#line 1180 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 3015 "awkgram.c" /* yacc.c:1646 */
break;
- case 73:
-
-/* Line 1821 of yacc.c */
-#line 1064 "awkgram.y"
+ case 77:
+#line 1182 "awkgram.y" /* yacc.c:1646 */
{
- (yyvsp[(1) - (1)])->opcode = Op_push_re;
- (yyval) = (yyvsp[(1) - (1)]);
+ (yyvsp[0])->opcode = Op_push_re;
+ (yyval) = (yyvsp[0]);
}
+#line 3024 "awkgram.c" /* yacc.c:1646 */
break;
- case 74:
-
-/* Line 1821 of yacc.c */
-#line 1072 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+ case 78:
+#line 1190 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 3030 "awkgram.c" /* yacc.c:1646 */
break;
- case 75:
-
-/* Line 1821 of yacc.c */
-#line 1074 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+ case 79:
+#line 1192 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 3036 "awkgram.c" /* yacc.c:1646 */
break;
- case 77:
-
-/* Line 1821 of yacc.c */
-#line 1084 "awkgram.y"
+ case 81:
+#line 1202 "awkgram.y" /* yacc.c:1646 */
{
- (yyval) = (yyvsp[(2) - (3)]);
+ (yyval) = (yyvsp[-1]);
}
+#line 3044 "awkgram.c" /* yacc.c:1646 */
break;
- case 78:
-
-/* Line 1821 of yacc.c */
-#line 1091 "awkgram.y"
+ case 82:
+#line 1209 "awkgram.y" /* yacc.c:1646 */
{
- in_print = FALSE;
+ in_print = false;
in_parens = 0;
(yyval) = NULL;
}
+#line 3054 "awkgram.c" /* yacc.c:1646 */
break;
- case 79:
-
-/* Line 1821 of yacc.c */
-#line 1096 "awkgram.y"
- { in_print = FALSE; in_parens = 0; }
+ case 83:
+#line 1214 "awkgram.y" /* yacc.c:1646 */
+ { in_print = false; in_parens = 0; }
+#line 3060 "awkgram.c" /* yacc.c:1646 */
break;
- case 80:
-
-/* Line 1821 of yacc.c */
-#line 1097 "awkgram.y"
+ case 84:
+#line 1215 "awkgram.y" /* yacc.c:1646 */
{
- if ((yyvsp[(1) - (3)])->redir_type == redirect_twoway
- && (yyvsp[(3) - (3)])->lasti->opcode == Op_K_getline_redir
- && (yyvsp[(3) - (3)])->lasti->redir_type == redirect_twoway)
+ if ((yyvsp[-2])->redir_type == redirect_twoway
+ && (yyvsp[0])->lasti->opcode == Op_K_getline_redir
+ && (yyvsp[0])->lasti->redir_type == redirect_twoway)
yyerror(_("multistage two-way pipelines don't work"));
- (yyval) = list_prepend((yyvsp[(3) - (3)]), (yyvsp[(1) - (3)]));
- }
- break;
-
- case 81:
-
-/* Line 1821 of yacc.c */
-#line 1108 "awkgram.y"
- {
- (yyval) = mk_condition((yyvsp[(3) - (6)]), (yyvsp[(1) - (6)]), (yyvsp[(6) - (6)]), NULL, NULL);
+ (yyval) = list_prepend((yyvsp[0]), (yyvsp[-2]));
}
+#line 3072 "awkgram.c" /* yacc.c:1646 */
break;
- case 82:
-
-/* Line 1821 of yacc.c */
-#line 1113 "awkgram.y"
+ case 85:
+#line 1226 "awkgram.y" /* yacc.c:1646 */
{
- (yyval) = mk_condition((yyvsp[(3) - (9)]), (yyvsp[(1) - (9)]), (yyvsp[(6) - (9)]), (yyvsp[(7) - (9)]), (yyvsp[(9) - (9)]));
+ (yyval) = mk_condition((yyvsp[-3]), (yyvsp[-5]), (yyvsp[0]), NULL, NULL);
}
+#line 3080 "awkgram.c" /* yacc.c:1646 */
break;
- case 87:
-
-/* Line 1821 of yacc.c */
-#line 1130 "awkgram.y"
- { (yyval) = NULL; }
- break;
-
- case 88:
-
-/* Line 1821 of yacc.c */
-#line 1132 "awkgram.y"
+ case 86:
+#line 1231 "awkgram.y" /* yacc.c:1646 */
{
- bcfree((yyvsp[(1) - (2)]));
- (yyval) = (yyvsp[(2) - (2)]);
+ (yyval) = mk_condition((yyvsp[-6]), (yyvsp[-8]), (yyvsp[-3]), (yyvsp[-2]), (yyvsp[0]));
}
- break;
-
- case 89:
-
-/* Line 1821 of yacc.c */
-#line 1140 "awkgram.y"
- { (yyval) = NULL; }
- break;
-
- case 90:
-
-/* Line 1821 of yacc.c */
-#line 1142 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]) ; }
+#line 3088 "awkgram.c" /* yacc.c:1646 */
break;
case 91:
-
-/* Line 1821 of yacc.c */
-#line 1147 "awkgram.y"
- {
- (yyvsp[(1) - (1)])->param_count = 0;
- (yyval) = list_create((yyvsp[(1) - (1)]));
- }
+#line 1248 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = NULL; }
+#line 3094 "awkgram.c" /* yacc.c:1646 */
break;
case 92:
-
-/* Line 1821 of yacc.c */
-#line 1152 "awkgram.y"
+#line 1250 "awkgram.y" /* yacc.c:1646 */
{
- (yyvsp[(3) - (3)])->param_count = (yyvsp[(1) - (3)])->lasti->param_count + 1;
- (yyval) = list_append((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]));
- yyerrok;
+ bcfree((yyvsp[-1]));
+ (yyval) = (yyvsp[0]);
}
+#line 3103 "awkgram.c" /* yacc.c:1646 */
break;
case 93:
-
-/* Line 1821 of yacc.c */
-#line 1158 "awkgram.y"
+#line 1258 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 3109 "awkgram.c" /* yacc.c:1646 */
break;
case 94:
-
-/* Line 1821 of yacc.c */
-#line 1160 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (2)]); }
+#line 1260 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 3115 "awkgram.c" /* yacc.c:1646 */
break;
case 95:
-
-/* Line 1821 of yacc.c */
-#line 1162 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (3)]); }
+#line 1265 "awkgram.y" /* yacc.c:1646 */
+ {
+ (yyvsp[0])->param_count = 0;
+ (yyval) = list_create((yyvsp[0]));
+ }
+#line 3124 "awkgram.c" /* yacc.c:1646 */
break;
case 96:
-
-/* Line 1821 of yacc.c */
-#line 1168 "awkgram.y"
- { (yyval) = NULL; }
+#line 1270 "awkgram.y" /* yacc.c:1646 */
+ {
+ (yyvsp[0])->param_count = (yyvsp[-2])->lasti->param_count + 1;
+ (yyval) = list_append((yyvsp[-2]), (yyvsp[0]));
+ yyerrok;
+ }
+#line 3134 "awkgram.c" /* yacc.c:1646 */
break;
case 97:
-
-/* Line 1821 of yacc.c */
-#line 1170 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+#line 1276 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = NULL; }
+#line 3140 "awkgram.c" /* yacc.c:1646 */
break;
case 98:
-
-/* Line 1821 of yacc.c */
-#line 1175 "awkgram.y"
- { (yyval) = NULL; }
+#line 1278 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[-1]); }
+#line 3146 "awkgram.c" /* yacc.c:1646 */
break;
case 99:
-
-/* Line 1821 of yacc.c */
-#line 1177 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+#line 1280 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[-2]); }
+#line 3152 "awkgram.c" /* yacc.c:1646 */
break;
case 100:
-
-/* Line 1821 of yacc.c */
-#line 1182 "awkgram.y"
- { (yyval) = mk_expression_list(NULL, (yyvsp[(1) - (1)])); }
+#line 1286 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = NULL; }
+#line 3158 "awkgram.c" /* yacc.c:1646 */
break;
case 101:
-
-/* Line 1821 of yacc.c */
-#line 1184 "awkgram.y"
- {
- (yyval) = mk_expression_list((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]));
- yyerrok;
- }
+#line 1288 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 3164 "awkgram.c" /* yacc.c:1646 */
break;
case 102:
-
-/* Line 1821 of yacc.c */
-#line 1189 "awkgram.y"
+#line 1293 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 3170 "awkgram.c" /* yacc.c:1646 */
break;
case 103:
-
-/* Line 1821 of yacc.c */
-#line 1191 "awkgram.y"
- { (yyval) = NULL; }
+#line 1295 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 3176 "awkgram.c" /* yacc.c:1646 */
break;
case 104:
-
-/* Line 1821 of yacc.c */
-#line 1193 "awkgram.y"
- { (yyval) = NULL; }
+#line 1300 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = mk_expression_list(NULL, (yyvsp[0])); }
+#line 3182 "awkgram.c" /* yacc.c:1646 */
break;
case 105:
-
-/* Line 1821 of yacc.c */
-#line 1195 "awkgram.y"
- { (yyval) = NULL; }
+#line 1302 "awkgram.y" /* yacc.c:1646 */
+ {
+ (yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0]));
+ yyerrok;
+ }
+#line 3191 "awkgram.c" /* yacc.c:1646 */
break;
case 106:
-
-/* Line 1821 of yacc.c */
-#line 1201 "awkgram.y"
- {
- if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode == Op_match_rec)
- lintwarn_ln((yyvsp[(2) - (3)])->source_line,
- _("regular expression on right of assignment"));
- (yyval) = mk_assignment((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)]));
- }
+#line 1307 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = NULL; }
+#line 3197 "awkgram.c" /* yacc.c:1646 */
break;
case 107:
-
-/* Line 1821 of yacc.c */
-#line 1208 "awkgram.y"
- { (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
+#line 1309 "awkgram.y" /* yacc.c:1646 */
+ {
+ /*
+ * Returning the expression list instead of NULL lets
+ * snode get a list of arguments that it can count.
+ */
+ (yyval) = (yyvsp[-1]);
+ }
+#line 3209 "awkgram.c" /* yacc.c:1646 */
break;
case 108:
-
-/* Line 1821 of yacc.c */
-#line 1210 "awkgram.y"
- { (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
+#line 1317 "awkgram.y" /* yacc.c:1646 */
+ {
+ /* Ditto */
+ (yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0]));
+ }
+#line 3218 "awkgram.c" /* yacc.c:1646 */
break;
case 109:
-
-/* Line 1821 of yacc.c */
-#line 1212 "awkgram.y"
+#line 1322 "awkgram.y" /* yacc.c:1646 */
{
- if ((yyvsp[(1) - (3)])->lasti->opcode == Op_match_rec)
- warning_ln((yyvsp[(2) - (3)])->source_line,
- _("regular expression on left of `~' or `!~' operator"));
-
- if ((yyvsp[(3) - (3)])->lasti == (yyvsp[(3) - (3)])->nexti && (yyvsp[(3) - (3)])->nexti->opcode == Op_match_rec) {
- (yyvsp[(2) - (3)])->memory = (yyvsp[(3) - (3)])->nexti->memory;
- bcfree((yyvsp[(3) - (3)])->nexti); /* Op_match_rec */
- bcfree((yyvsp[(3) - (3)])); /* Op_list */
- (yyval) = list_append((yyvsp[(1) - (3)]), (yyvsp[(2) - (3)]));
- } else {
- (yyvsp[(2) - (3)])->memory = make_regnode(Node_dynregex, NULL);
- (yyval) = list_append(list_merge((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])), (yyvsp[(2) - (3)]));
- }
+ /* Ditto */
+ (yyval) = (yyvsp[-2]);
}
+#line 3227 "awkgram.c" /* yacc.c:1646 */
break;
case 110:
-
-/* Line 1821 of yacc.c */
-#line 1228 "awkgram.y"
+#line 1331 "awkgram.y" /* yacc.c:1646 */
{
- if (do_lint_old)
- warning_ln((yyvsp[(2) - (3)])->source_line,
- _("old awk does not support the keyword `in' except after `for'"));
- (yyvsp[(3) - (3)])->nexti->opcode = Op_push_array;
- (yyvsp[(2) - (3)])->opcode = Op_in_array;
- (yyvsp[(2) - (3)])->expr_count = 1;
- (yyval) = list_append(list_merge((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])), (yyvsp[(2) - (3)]));
+ if (do_lint && (yyvsp[0])->lasti->opcode == Op_match_rec)
+ lintwarn_ln((yyvsp[-1])->source_line,
+ _("regular expression on right of assignment"));
+ (yyval) = mk_assignment((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1]));
}
+#line 3238 "awkgram.c" /* yacc.c:1646 */
break;
case 111:
-
-/* Line 1821 of yacc.c */
-#line 1238 "awkgram.y"
- {
- if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode == Op_match_rec)
- lintwarn_ln((yyvsp[(2) - (3)])->source_line,
- _("regular expression on right of comparison"));
- (yyval) = list_append(list_merge((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])), (yyvsp[(2) - (3)]));
- }
+#line 1338 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = mk_boolean((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
+#line 3244 "awkgram.c" /* yacc.c:1646 */
break;
case 112:
-
-/* Line 1821 of yacc.c */
-#line 1245 "awkgram.y"
- { (yyval) = mk_condition((yyvsp[(1) - (5)]), (yyvsp[(2) - (5)]), (yyvsp[(3) - (5)]), (yyvsp[(4) - (5)]), (yyvsp[(5) - (5)])); }
+#line 1340 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = mk_boolean((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
+#line 3250 "awkgram.c" /* yacc.c:1646 */
break;
case 113:
+#line 1342 "awkgram.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[-2])->lasti->opcode == Op_match_rec)
+ warning_ln((yyvsp[-1])->source_line,
+ _("regular expression on left of `~' or `!~' operator"));
-/* Line 1821 of yacc.c */
-#line 1247 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+ if ((yyvsp[0])->lasti == (yyvsp[0])->nexti && (yyvsp[0])->nexti->opcode == Op_match_rec) {
+ (yyvsp[-1])->memory = (yyvsp[0])->nexti->memory;
+ bcfree((yyvsp[0])->nexti); /* Op_match_rec */
+ bcfree((yyvsp[0])); /* Op_list */
+ (yyval) = list_append((yyvsp[-2]), (yyvsp[-1]));
+ } else {
+ (yyvsp[-1])->memory = make_regnode(Node_dynregex, NULL);
+ (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), (yyvsp[-1]));
+ }
+ }
+#line 3270 "awkgram.c" /* yacc.c:1646 */
break;
case 114:
-
-/* Line 1821 of yacc.c */
-#line 1252 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+#line 1358 "awkgram.y" /* yacc.c:1646 */
+ {
+ if (do_lint_old)
+ warning_ln((yyvsp[-1])->source_line,
+ _("old awk does not support the keyword `in' except after `for'"));
+ (yyvsp[0])->nexti->opcode = Op_push_array;
+ (yyvsp[-1])->opcode = Op_in_array;
+ (yyvsp[-1])->expr_count = 1;
+ (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), (yyvsp[-1]));
+ }
+#line 3284 "awkgram.c" /* yacc.c:1646 */
break;
case 115:
-
-/* Line 1821 of yacc.c */
-#line 1254 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+#line 1368 "awkgram.y" /* yacc.c:1646 */
+ {
+ if (do_lint && (yyvsp[0])->lasti->opcode == Op_match_rec)
+ lintwarn_ln((yyvsp[-1])->source_line,
+ _("regular expression on right of comparison"));
+ (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), (yyvsp[-1]));
+ }
+#line 3295 "awkgram.c" /* yacc.c:1646 */
break;
case 116:
-
-/* Line 1821 of yacc.c */
-#line 1256 "awkgram.y"
- {
- (yyvsp[(2) - (2)])->opcode = Op_assign_quotient;
- (yyval) = (yyvsp[(2) - (2)]);
- }
+#line 1375 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = mk_condition((yyvsp[-4]), (yyvsp[-3]), (yyvsp[-2]), (yyvsp[-1]), (yyvsp[0])); }
+#line 3301 "awkgram.c" /* yacc.c:1646 */
break;
case 117:
-
-/* Line 1821 of yacc.c */
-#line 1264 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+#line 1377 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 3307 "awkgram.c" /* yacc.c:1646 */
break;
case 118:
-
-/* Line 1821 of yacc.c */
-#line 1266 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+#line 1382 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 3313 "awkgram.c" /* yacc.c:1646 */
break;
case 119:
-
-/* Line 1821 of yacc.c */
-#line 1271 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+#line 1384 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 3319 "awkgram.c" /* yacc.c:1646 */
break;
case 120:
-
-/* Line 1821 of yacc.c */
-#line 1273 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+#line 1386 "awkgram.y" /* yacc.c:1646 */
+ {
+ (yyvsp[0])->opcode = Op_assign_quotient;
+ (yyval) = (yyvsp[0]);
+ }
+#line 3328 "awkgram.c" /* yacc.c:1646 */
break;
case 121:
-
-/* Line 1821 of yacc.c */
-#line 1278 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+#line 1394 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 3334 "awkgram.c" /* yacc.c:1646 */
break;
case 122:
-
-/* Line 1821 of yacc.c */
-#line 1280 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+#line 1396 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 3340 "awkgram.c" /* yacc.c:1646 */
break;
case 123:
+#line 1401 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 3346 "awkgram.c" /* yacc.c:1646 */
+ break;
+
+ case 124:
+#line 1403 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 3352 "awkgram.c" /* yacc.c:1646 */
+ break;
+
+ case 125:
+#line 1408 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 3358 "awkgram.c" /* yacc.c:1646 */
+ break;
+
+ case 126:
+#line 1410 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 3364 "awkgram.c" /* yacc.c:1646 */
+ break;
-/* Line 1821 of yacc.c */
-#line 1282 "awkgram.y"
+ case 127:
+#line 1412 "awkgram.y" /* yacc.c:1646 */
{
int count = 2;
- int is_simple_var = FALSE;
+ bool is_simple_var = false;
- if ((yyvsp[(1) - (2)])->lasti->opcode == Op_concat) {
+ if ((yyvsp[-1])->lasti->opcode == Op_concat) {
/* multiple (> 2) adjacent strings optimization */
- is_simple_var = ((yyvsp[(1) - (2)])->lasti->concat_flag & CSVAR);
- count = (yyvsp[(1) - (2)])->lasti->expr_count + 1;
- (yyvsp[(1) - (2)])->lasti->opcode = Op_no_op;
+ is_simple_var = ((yyvsp[-1])->lasti->concat_flag & CSVAR);
+ count = (yyvsp[-1])->lasti->expr_count + 1;
+ (yyvsp[-1])->lasti->opcode = Op_no_op;
} else {
- is_simple_var = ((yyvsp[(1) - (2)])->nexti->opcode == Op_push
- && (yyvsp[(1) - (2)])->lasti == (yyvsp[(1) - (2)])->nexti); /* first exp. is a simple
+ is_simple_var = ((yyvsp[-1])->nexti->opcode == Op_push
+ && (yyvsp[-1])->lasti == (yyvsp[-1])->nexti); /* first exp. is a simple
* variable?; kludge for use
* in Op_assign_concat.
*/
}
- if (do_optimize > 1
- && (yyvsp[(1) - (2)])->nexti == (yyvsp[(1) - (2)])->lasti && (yyvsp[(1) - (2)])->nexti->opcode == Op_push_i
- && (yyvsp[(2) - (2)])->nexti == (yyvsp[(2) - (2)])->lasti && (yyvsp[(2) - (2)])->nexti->opcode == Op_push_i
+ if (do_optimize
+ && (yyvsp[-1])->nexti == (yyvsp[-1])->lasti && (yyvsp[-1])->nexti->opcode == Op_push_i
+ && (yyvsp[0])->nexti == (yyvsp[0])->lasti && (yyvsp[0])->nexti->opcode == Op_push_i
) {
- NODE *n1 = (yyvsp[(1) - (2)])->nexti->memory;
- NODE *n2 = (yyvsp[(2) - (2)])->nexti->memory;
+ NODE *n1 = (yyvsp[-1])->nexti->memory;
+ NODE *n2 = (yyvsp[0])->nexti->memory;
size_t nlen;
n1 = force_string(n1);
@@ -3570,211 +3400,184 @@ regular_loop:
n1->flags &= ~(NUMCUR|NUMBER|NUMINT);
n1->flags |= (STRING|STRCUR);
unref(n2);
- bcfree((yyvsp[(2) - (2)])->nexti);
- bcfree((yyvsp[(2) - (2)]));
- (yyval) = (yyvsp[(1) - (2)]);
+ bcfree((yyvsp[0])->nexti);
+ bcfree((yyvsp[0]));
+ (yyval) = (yyvsp[-1]);
} else {
- (yyval) = list_append(list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)])), instruction(Op_concat));
+ (yyval) = list_append(list_merge((yyvsp[-1]), (yyvsp[0])), instruction(Op_concat));
(yyval)->lasti->concat_flag = (is_simple_var ? CSVAR : 0);
(yyval)->lasti->expr_count = count;
if (count > max_args)
max_args = count;
}
}
+#line 3415 "awkgram.c" /* yacc.c:1646 */
break;
- case 125:
-
-/* Line 1821 of yacc.c */
-#line 1334 "awkgram.y"
- { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
+ case 129:
+#line 1464 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
+#line 3421 "awkgram.c" /* yacc.c:1646 */
break;
- case 126:
-
-/* Line 1821 of yacc.c */
-#line 1336 "awkgram.y"
- { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
+ case 130:
+#line 1466 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
+#line 3427 "awkgram.c" /* yacc.c:1646 */
break;
- case 127:
-
-/* Line 1821 of yacc.c */
-#line 1338 "awkgram.y"
- { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
+ case 131:
+#line 1468 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
+#line 3433 "awkgram.c" /* yacc.c:1646 */
break;
- case 128:
-
-/* Line 1821 of yacc.c */
-#line 1340 "awkgram.y"
- { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
+ case 132:
+#line 1470 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
+#line 3439 "awkgram.c" /* yacc.c:1646 */
break;
- case 129:
-
-/* Line 1821 of yacc.c */
-#line 1342 "awkgram.y"
- { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
+ case 133:
+#line 1472 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
+#line 3445 "awkgram.c" /* yacc.c:1646 */
break;
- case 130:
-
-/* Line 1821 of yacc.c */
-#line 1344 "awkgram.y"
- { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
+ case 134:
+#line 1474 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
+#line 3451 "awkgram.c" /* yacc.c:1646 */
break;
- case 131:
-
-/* Line 1821 of yacc.c */
-#line 1346 "awkgram.y"
+ case 135:
+#line 1476 "awkgram.y" /* yacc.c:1646 */
{
/*
- * In BEGINFILE/ENDFILE, allow `getline var < file'
+ * In BEGINFILE/ENDFILE, allow `getline [var] < file'
*/
- if (rule == BEGINFILE || rule == ENDFILE) {
- if ((yyvsp[(2) - (3)]) != NULL && (yyvsp[(3) - (3)]) != NULL)
- ; /* all ok */
- else {
- if ((yyvsp[(2) - (3)]) != NULL)
- error_ln((yyvsp[(1) - (3)])->source_line,
- _("`getline var' invalid inside `%s' rule"), ruletab[rule]);
- else
- error_ln((yyvsp[(1) - (3)])->source_line,
- _("`getline' invalid inside `%s' rule"), ruletab[rule]);
- }
- }
- if (do_lint && rule == END && (yyvsp[(3) - (3)]) == NULL)
- lintwarn_ln((yyvsp[(1) - (3)])->source_line,
+ if ((rule == BEGINFILE || rule == ENDFILE) && (yyvsp[0]) == NULL)
+ error_ln((yyvsp[-2])->source_line,
+ _("non-redirected `getline' invalid inside `%s' rule"), ruletab[rule]);
+ if (do_lint && rule == END && (yyvsp[0]) == NULL)
+ lintwarn_ln((yyvsp[-2])->source_line,
_("non-redirected `getline' undefined inside END action"));
- (yyval) = mk_getline((yyvsp[(1) - (3)]), (yyvsp[(2) - (3)]), (yyvsp[(3) - (3)]), redirect_input);
+ (yyval) = mk_getline((yyvsp[-2]), (yyvsp[-1]), (yyvsp[0]), redirect_input);
}
+#line 3469 "awkgram.c" /* yacc.c:1646 */
break;
- case 132:
-
-/* Line 1821 of yacc.c */
-#line 1369 "awkgram.y"
+ case 136:
+#line 1490 "awkgram.y" /* yacc.c:1646 */
{
- (yyvsp[(2) - (2)])->opcode = Op_postincrement;
- (yyval) = mk_assignment((yyvsp[(1) - (2)]), NULL, (yyvsp[(2) - (2)]));
+ (yyvsp[0])->opcode = Op_postincrement;
+ (yyval) = mk_assignment((yyvsp[-1]), NULL, (yyvsp[0]));
}
+#line 3478 "awkgram.c" /* yacc.c:1646 */
break;
- case 133:
-
-/* Line 1821 of yacc.c */
-#line 1374 "awkgram.y"
+ case 137:
+#line 1495 "awkgram.y" /* yacc.c:1646 */
{
- (yyvsp[(2) - (2)])->opcode = Op_postdecrement;
- (yyval) = mk_assignment((yyvsp[(1) - (2)]), NULL, (yyvsp[(2) - (2)]));
+ (yyvsp[0])->opcode = Op_postdecrement;
+ (yyval) = mk_assignment((yyvsp[-1]), NULL, (yyvsp[0]));
}
+#line 3487 "awkgram.c" /* yacc.c:1646 */
break;
- case 134:
-
-/* Line 1821 of yacc.c */
-#line 1379 "awkgram.y"
+ case 138:
+#line 1500 "awkgram.y" /* yacc.c:1646 */
{
if (do_lint_old) {
- warning_ln((yyvsp[(4) - (5)])->source_line,
+ warning_ln((yyvsp[-1])->source_line,
_("old awk does not support the keyword `in' except after `for'"));
- warning_ln((yyvsp[(4) - (5)])->source_line,
+ warning_ln((yyvsp[-1])->source_line,
_("old awk does not support multidimensional arrays"));
}
- (yyvsp[(5) - (5)])->nexti->opcode = Op_push_array;
- (yyvsp[(4) - (5)])->opcode = Op_in_array;
- if ((yyvsp[(2) - (5)]) == NULL) { /* error */
+ (yyvsp[0])->nexti->opcode = Op_push_array;
+ (yyvsp[-1])->opcode = Op_in_array;
+ if ((yyvsp[-3]) == NULL) { /* error */
errcount++;
- (yyvsp[(4) - (5)])->expr_count = 0;
- (yyval) = list_merge((yyvsp[(5) - (5)]), (yyvsp[(4) - (5)]));
+ (yyvsp[-1])->expr_count = 0;
+ (yyval) = list_merge((yyvsp[0]), (yyvsp[-1]));
} else {
- INSTRUCTION *t = (yyvsp[(2) - (5)]);
- (yyvsp[(4) - (5)])->expr_count = count_expressions(&t, FALSE);
- (yyval) = list_append(list_merge(t, (yyvsp[(5) - (5)])), (yyvsp[(4) - (5)]));
+ INSTRUCTION *t = (yyvsp[-3]);
+ (yyvsp[-1])->expr_count = count_expressions(&t, false);
+ (yyval) = list_append(list_merge(t, (yyvsp[0])), (yyvsp[-1]));
}
}
+#line 3511 "awkgram.c" /* yacc.c:1646 */
break;
- case 135:
-
-/* Line 1821 of yacc.c */
-#line 1404 "awkgram.y"
+ case 139:
+#line 1525 "awkgram.y" /* yacc.c:1646 */
{
- (yyval) = mk_getline((yyvsp[(3) - (4)]), (yyvsp[(4) - (4)]), (yyvsp[(1) - (4)]), (yyvsp[(2) - (4)])->redir_type);
- bcfree((yyvsp[(2) - (4)]));
+ (yyval) = mk_getline((yyvsp[-1]), (yyvsp[0]), (yyvsp[-3]), (yyvsp[-2])->redir_type);
+ bcfree((yyvsp[-2]));
}
+#line 3520 "awkgram.c" /* yacc.c:1646 */
break;
- case 136:
-
-/* Line 1821 of yacc.c */
-#line 1410 "awkgram.y"
- { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
+ case 140:
+#line 1531 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
+#line 3526 "awkgram.c" /* yacc.c:1646 */
break;
- case 137:
-
-/* Line 1821 of yacc.c */
-#line 1412 "awkgram.y"
- { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
+ case 141:
+#line 1533 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
+#line 3532 "awkgram.c" /* yacc.c:1646 */
break;
- case 138:
-
-/* Line 1821 of yacc.c */
-#line 1414 "awkgram.y"
- { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
+ case 142:
+#line 1535 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
+#line 3538 "awkgram.c" /* yacc.c:1646 */
break;
- case 139:
-
-/* Line 1821 of yacc.c */
-#line 1416 "awkgram.y"
- { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
+ case 143:
+#line 1537 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
+#line 3544 "awkgram.c" /* yacc.c:1646 */
break;
- case 140:
-
-/* Line 1821 of yacc.c */
-#line 1418 "awkgram.y"
- { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
+ case 144:
+#line 1539 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
+#line 3550 "awkgram.c" /* yacc.c:1646 */
break;
- case 141:
-
-/* Line 1821 of yacc.c */
-#line 1420 "awkgram.y"
- { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
+ case 145:
+#line 1541 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
+#line 3556 "awkgram.c" /* yacc.c:1646 */
break;
- case 142:
-
-/* Line 1821 of yacc.c */
-#line 1425 "awkgram.y"
+ case 146:
+#line 1546 "awkgram.y" /* yacc.c:1646 */
{
- (yyval) = list_create((yyvsp[(1) - (1)]));
+ (yyval) = list_create((yyvsp[0]));
}
+#line 3564 "awkgram.c" /* yacc.c:1646 */
break;
- case 143:
-
-/* Line 1821 of yacc.c */
-#line 1429 "awkgram.y"
+ case 147:
+#line 1550 "awkgram.y" /* yacc.c:1646 */
{
- if ((yyvsp[(2) - (2)])->opcode == Op_match_rec) {
- (yyvsp[(2) - (2)])->opcode = Op_nomatch;
- (yyvsp[(1) - (2)])->opcode = Op_push_i;
- (yyvsp[(1) - (2)])->memory = make_number(0.0);
- (yyval) = list_append(list_append(list_create((yyvsp[(1) - (2)])),
- instruction(Op_field_spec)), (yyvsp[(2) - (2)]));
+ if ((yyvsp[0])->opcode == Op_match_rec) {
+ (yyvsp[0])->opcode = Op_nomatch;
+ (yyvsp[-1])->opcode = Op_push_i;
+ (yyvsp[-1])->memory = make_number(0.0);
+ (yyval) = list_append(list_append(list_create((yyvsp[-1])),
+ instruction(Op_field_spec)), (yyvsp[0]));
} else {
- if (do_optimize > 1 && (yyvsp[(2) - (2)])->nexti == (yyvsp[(2) - (2)])->lasti
- && (yyvsp[(2) - (2)])->nexti->opcode == Op_push_i
+ if (do_optimize && (yyvsp[0])->nexti == (yyvsp[0])->lasti
+ && (yyvsp[0])->nexti->opcode == Op_push_i
+ && ((yyvsp[0])->nexti->memory->flags & (MPFN|MPZN)) == 0
) {
- NODE *n = (yyvsp[(2) - (2)])->nexti->memory;
+ NODE *n = (yyvsp[0])->nexti->memory;
if ((n->flags & (STRCUR|STRING)) != 0) {
n->numbr = (AWKNUM) (n->stlen == 0);
n->flags &= ~(STRCUR|STRING);
@@ -3784,165 +3587,155 @@ regular_loop:
n->stlen = 0;
} else
n->numbr = (AWKNUM) (n->numbr == 0.0);
- bcfree((yyvsp[(1) - (2)]));
- (yyval) = (yyvsp[(2) - (2)]);
+ bcfree((yyvsp[-1]));
+ (yyval) = (yyvsp[0]);
} else {
- (yyvsp[(1) - (2)])->opcode = Op_not;
- add_lint((yyvsp[(2) - (2)]), LINT_assign_in_cond);
- (yyval) = list_append((yyvsp[(2) - (2)]), (yyvsp[(1) - (2)]));
+ (yyvsp[-1])->opcode = Op_not;
+ add_lint((yyvsp[0]), LINT_assign_in_cond);
+ (yyval) = list_append((yyvsp[0]), (yyvsp[-1]));
}
}
}
+#line 3600 "awkgram.c" /* yacc.c:1646 */
break;
- case 144:
-
-/* Line 1821 of yacc.c */
-#line 1460 "awkgram.y"
- { (yyval) = (yyvsp[(2) - (3)]); }
+ case 148:
+#line 1582 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[-1]); }
+#line 3606 "awkgram.c" /* yacc.c:1646 */
break;
- case 145:
-
-/* Line 1821 of yacc.c */
-#line 1462 "awkgram.y"
+ case 149:
+#line 1584 "awkgram.y" /* yacc.c:1646 */
{
- (yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)]));
+ (yyval) = snode((yyvsp[-1]), (yyvsp[-3]));
if ((yyval) == NULL)
YYABORT;
}
+#line 3616 "awkgram.c" /* yacc.c:1646 */
break;
- case 146:
-
-/* Line 1821 of yacc.c */
-#line 1468 "awkgram.y"
+ case 150:
+#line 1590 "awkgram.y" /* yacc.c:1646 */
{
- (yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)]));
+ (yyval) = snode((yyvsp[-1]), (yyvsp[-3]));
if ((yyval) == NULL)
YYABORT;
}
+#line 3626 "awkgram.c" /* yacc.c:1646 */
break;
- case 147:
-
-/* Line 1821 of yacc.c */
-#line 1474 "awkgram.y"
+ case 151:
+#line 1596 "awkgram.y" /* yacc.c:1646 */
{
- static short warned1 = FALSE;
+ static bool warned = false;
- if (do_lint && ! warned1) {
- warned1 = TRUE;
- lintwarn_ln((yyvsp[(1) - (1)])->source_line,
+ if (do_lint && ! warned) {
+ warned = true;
+ lintwarn_ln((yyvsp[0])->source_line,
_("call of `length' without parentheses is not portable"));
}
- (yyval) = snode(NULL, (yyvsp[(1) - (1)]));
+ (yyval) = snode(NULL, (yyvsp[0]));
if ((yyval) == NULL)
YYABORT;
}
+#line 3643 "awkgram.c" /* yacc.c:1646 */
break;
- case 150:
-
-/* Line 1821 of yacc.c */
-#line 1489 "awkgram.y"
+ case 154:
+#line 1611 "awkgram.y" /* yacc.c:1646 */
{
- (yyvsp[(1) - (2)])->opcode = Op_preincrement;
- (yyval) = mk_assignment((yyvsp[(2) - (2)]), NULL, (yyvsp[(1) - (2)]));
+ (yyvsp[-1])->opcode = Op_preincrement;
+ (yyval) = mk_assignment((yyvsp[0]), NULL, (yyvsp[-1]));
}
+#line 3652 "awkgram.c" /* yacc.c:1646 */
break;
- case 151:
-
-/* Line 1821 of yacc.c */
-#line 1494 "awkgram.y"
+ case 155:
+#line 1616 "awkgram.y" /* yacc.c:1646 */
{
- (yyvsp[(1) - (2)])->opcode = Op_predecrement;
- (yyval) = mk_assignment((yyvsp[(2) - (2)]), NULL, (yyvsp[(1) - (2)]));
+ (yyvsp[-1])->opcode = Op_predecrement;
+ (yyval) = mk_assignment((yyvsp[0]), NULL, (yyvsp[-1]));
}
+#line 3661 "awkgram.c" /* yacc.c:1646 */
break;
- case 152:
-
-/* Line 1821 of yacc.c */
-#line 1499 "awkgram.y"
+ case 156:
+#line 1621 "awkgram.y" /* yacc.c:1646 */
{
- (yyval) = list_create((yyvsp[(1) - (1)]));
+ (yyval) = list_create((yyvsp[0]));
}
+#line 3669 "awkgram.c" /* yacc.c:1646 */
break;
- case 153:
-
-/* Line 1821 of yacc.c */
-#line 1503 "awkgram.y"
+ case 157:
+#line 1625 "awkgram.y" /* yacc.c:1646 */
{
- (yyval) = list_create((yyvsp[(1) - (1)]));
+ (yyval) = list_create((yyvsp[0]));
}
+#line 3677 "awkgram.c" /* yacc.c:1646 */
break;
- case 154:
-
-/* Line 1821 of yacc.c */
-#line 1507 "awkgram.y"
+ case 158:
+#line 1629 "awkgram.y" /* yacc.c:1646 */
{
- if ((yyvsp[(2) - (2)])->lasti->opcode == Op_push_i
- && ((yyvsp[(2) - (2)])->lasti->memory->flags & (STRCUR|STRING)) == 0
+ if ((yyvsp[0])->lasti->opcode == Op_push_i
+ && ((yyvsp[0])->lasti->memory->flags & (STRCUR|STRING)) == 0
) {
- (yyvsp[(2) - (2)])->lasti->memory->numbr = -(force_number((yyvsp[(2) - (2)])->lasti->memory));
- (yyval) = (yyvsp[(2) - (2)]);
- bcfree((yyvsp[(1) - (2)]));
+ NODE *n = (yyvsp[0])->lasti->memory;
+ (void) force_number(n);
+ negate_num(n);
+ (yyval) = (yyvsp[0]);
+ bcfree((yyvsp[-1]));
} else {
- (yyvsp[(1) - (2)])->opcode = Op_unary_minus;
- (yyval) = list_append((yyvsp[(2) - (2)]), (yyvsp[(1) - (2)]));
+ (yyvsp[-1])->opcode = Op_unary_minus;
+ (yyval) = list_append((yyvsp[0]), (yyvsp[-1]));
}
}
+#line 3696 "awkgram.c" /* yacc.c:1646 */
break;
- case 155:
-
-/* Line 1821 of yacc.c */
-#line 1520 "awkgram.y"
+ case 159:
+#line 1644 "awkgram.y" /* yacc.c:1646 */
{
/*
* was: $$ = $2
* POSIX semantics: force a conversion to numeric type
*/
- (yyvsp[(1) - (2)])->opcode = Op_plus_i;
- (yyvsp[(1) - (2)])->memory = make_number(0.0);
- (yyval) = list_append((yyvsp[(2) - (2)]), (yyvsp[(1) - (2)]));
+ (yyvsp[-1])->opcode = Op_plus_i;
+ (yyvsp[-1])->memory = make_number(0.0);
+ (yyval) = list_append((yyvsp[0]), (yyvsp[-1]));
}
+#line 3710 "awkgram.c" /* yacc.c:1646 */
break;
- case 156:
-
-/* Line 1821 of yacc.c */
-#line 1533 "awkgram.y"
+ case 160:
+#line 1657 "awkgram.y" /* yacc.c:1646 */
{
- func_use((yyvsp[(1) - (1)])->lasti->func_name, FUNC_USE);
- (yyval) = (yyvsp[(1) - (1)]);
+ func_use((yyvsp[0])->lasti->func_name, FUNC_USE);
+ (yyval) = (yyvsp[0]);
}
+#line 3719 "awkgram.c" /* yacc.c:1646 */
break;
- case 157:
-
-/* Line 1821 of yacc.c */
-#line 1538 "awkgram.y"
+ case 161:
+#line 1662 "awkgram.y" /* yacc.c:1646 */
{
/* indirect function call */
INSTRUCTION *f, *t;
char *name;
NODE *indirect_var;
- static short warned = FALSE;
+ static bool warned = false;
const char *msg = _("indirect function calls are a gawk extension");
if (do_traditional || do_posix)
yyerror("%s", msg);
else if (do_lint && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn("%s", msg);
}
- f = (yyvsp[(2) - (2)])->lasti;
+ f = (yyvsp[0])->lasti;
f->opcode = Op_indirect_func_call;
name = estrdup(f->func_name, strlen(f->func_name));
if (is_std_var(name))
@@ -3957,79 +3750,71 @@ regular_loop:
* @f(f="real_fun")
*/
- (yyval) = list_prepend((yyvsp[(2) - (2)]), t);
+ (yyval) = list_prepend((yyvsp[0]), t);
}
+#line 3756 "awkgram.c" /* yacc.c:1646 */
break;
- case 158:
-
-/* Line 1821 of yacc.c */
-#line 1574 "awkgram.y"
+ case 162:
+#line 1698 "awkgram.y" /* yacc.c:1646 */
{
- param_sanity((yyvsp[(3) - (4)]));
- (yyvsp[(1) - (4)])->opcode = Op_func_call;
- (yyvsp[(1) - (4)])->func_body = NULL;
- if ((yyvsp[(3) - (4)]) == NULL) { /* no argument or error */
- ((yyvsp[(1) - (4)]) + 1)->expr_count = 0;
- (yyval) = list_create((yyvsp[(1) - (4)]));
+ param_sanity((yyvsp[-1]));
+ (yyvsp[-3])->opcode = Op_func_call;
+ (yyvsp[-3])->func_body = NULL;
+ if ((yyvsp[-1]) == NULL) { /* no argument or error */
+ ((yyvsp[-3]) + 1)->expr_count = 0;
+ (yyval) = list_create((yyvsp[-3]));
} else {
- INSTRUCTION *t = (yyvsp[(3) - (4)]);
- ((yyvsp[(1) - (4)]) + 1)->expr_count = count_expressions(&t, TRUE);
- (yyval) = list_append(t, (yyvsp[(1) - (4)]));
+ INSTRUCTION *t = (yyvsp[-1]);
+ ((yyvsp[-3]) + 1)->expr_count = count_expressions(&t, true);
+ (yyval) = list_append(t, (yyvsp[-3]));
}
}
+#line 3774 "awkgram.c" /* yacc.c:1646 */
break;
- case 159:
-
-/* Line 1821 of yacc.c */
-#line 1591 "awkgram.y"
+ case 163:
+#line 1715 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 3780 "awkgram.c" /* yacc.c:1646 */
break;
- case 160:
-
-/* Line 1821 of yacc.c */
-#line 1593 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+ case 164:
+#line 1717 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 3786 "awkgram.c" /* yacc.c:1646 */
break;
- case 161:
-
-/* Line 1821 of yacc.c */
-#line 1598 "awkgram.y"
+ case 165:
+#line 1722 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 3792 "awkgram.c" /* yacc.c:1646 */
break;
- case 162:
-
-/* Line 1821 of yacc.c */
-#line 1600 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (2)]); }
+ case 166:
+#line 1724 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[-1]); }
+#line 3798 "awkgram.c" /* yacc.c:1646 */
break;
- case 163:
-
-/* Line 1821 of yacc.c */
-#line 1605 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+ case 167:
+#line 1729 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 3804 "awkgram.c" /* yacc.c:1646 */
break;
- case 164:
-
-/* Line 1821 of yacc.c */
-#line 1607 "awkgram.y"
+ case 168:
+#line 1731 "awkgram.y" /* yacc.c:1646 */
{
- (yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
+ (yyval) = list_merge((yyvsp[-1]), (yyvsp[0]));
}
+#line 3812 "awkgram.c" /* yacc.c:1646 */
break;
- case 165:
-
-/* Line 1821 of yacc.c */
-#line 1614 "awkgram.y"
+ case 169:
+#line 1738 "awkgram.y" /* yacc.c:1646 */
{
- INSTRUCTION *ip = (yyvsp[(1) - (1)])->lasti;
+ INSTRUCTION *ip = (yyvsp[0])->lasti;
int count = ip->sub_count; /* # of SUBSEP-seperated expressions */
if (count > 1) {
/* change Op_subscript or Op_sub_array to Op_concat */
@@ -4039,169 +3824,152 @@ regular_loop:
} else
ip->opcode = Op_no_op;
sub_counter++; /* count # of dimensions */
- (yyval) = (yyvsp[(1) - (1)]);
+ (yyval) = (yyvsp[0]);
}
+#line 3830 "awkgram.c" /* yacc.c:1646 */
break;
- case 166:
-
-/* Line 1821 of yacc.c */
-#line 1631 "awkgram.y"
+ case 170:
+#line 1755 "awkgram.y" /* yacc.c:1646 */
{
- INSTRUCTION *t = (yyvsp[(2) - (3)]);
- if ((yyvsp[(2) - (3)]) == NULL) {
- error_ln((yyvsp[(3) - (3)])->source_line,
+ INSTRUCTION *t = (yyvsp[-1]);
+ if ((yyvsp[-1]) == NULL) {
+ error_ln((yyvsp[0])->source_line,
_("invalid subscript expression"));
/* install Null string as subscript. */
t = list_create(instruction(Op_push_i));
t->nexti->memory = dupnode(Nnull_string);
- (yyvsp[(3) - (3)])->sub_count = 1;
+ (yyvsp[0])->sub_count = 1;
} else
- (yyvsp[(3) - (3)])->sub_count = count_expressions(&t, FALSE);
- (yyval) = list_append(t, (yyvsp[(3) - (3)]));
+ (yyvsp[0])->sub_count = count_expressions(&t, false);
+ (yyval) = list_append(t, (yyvsp[0]));
}
+#line 3848 "awkgram.c" /* yacc.c:1646 */
break;
- case 167:
-
-/* Line 1821 of yacc.c */
-#line 1648 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+ case 171:
+#line 1772 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 3854 "awkgram.c" /* yacc.c:1646 */
break;
- case 168:
-
-/* Line 1821 of yacc.c */
-#line 1650 "awkgram.y"
+ case 172:
+#line 1774 "awkgram.y" /* yacc.c:1646 */
{
- (yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
+ (yyval) = list_merge((yyvsp[-1]), (yyvsp[0]));
}
+#line 3862 "awkgram.c" /* yacc.c:1646 */
break;
- case 169:
-
-/* Line 1821 of yacc.c */
-#line 1657 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (2)]); }
+ case 173:
+#line 1781 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[-1]); }
+#line 3868 "awkgram.c" /* yacc.c:1646 */
break;
- case 170:
-
-/* Line 1821 of yacc.c */
-#line 1662 "awkgram.y"
+ case 174:
+#line 1786 "awkgram.y" /* yacc.c:1646 */
{
- char *var_name = (yyvsp[(1) - (1)])->lextok;
+ char *var_name = (yyvsp[0])->lextok;
- (yyvsp[(1) - (1)])->opcode = Op_push;
- (yyvsp[(1) - (1)])->memory = variable((yyvsp[(1) - (1)])->source_line, var_name, Node_var_new);
- (yyval) = list_create((yyvsp[(1) - (1)]));
+ (yyvsp[0])->opcode = Op_push;
+ (yyvsp[0])->memory = variable((yyvsp[0])->source_line, var_name, Node_var_new);
+ (yyval) = list_create((yyvsp[0]));
}
+#line 3880 "awkgram.c" /* yacc.c:1646 */
break;
- case 171:
-
-/* Line 1821 of yacc.c */
-#line 1670 "awkgram.y"
+ case 175:
+#line 1794 "awkgram.y" /* yacc.c:1646 */
{
- char *arr = (yyvsp[(1) - (2)])->lextok;
- (yyvsp[(1) - (2)])->memory = variable((yyvsp[(1) - (2)])->source_line, arr, Node_var_new);
- (yyvsp[(1) - (2)])->opcode = Op_push_array;
- (yyval) = list_prepend((yyvsp[(2) - (2)]), (yyvsp[(1) - (2)]));
+ char *arr = (yyvsp[-1])->lextok;
+ (yyvsp[-1])->memory = variable((yyvsp[-1])->source_line, arr, Node_var_new);
+ (yyvsp[-1])->opcode = Op_push_array;
+ (yyval) = list_prepend((yyvsp[0]), (yyvsp[-1]));
}
+#line 3891 "awkgram.c" /* yacc.c:1646 */
break;
- case 172:
-
-/* Line 1821 of yacc.c */
-#line 1680 "awkgram.y"
+ case 176:
+#line 1804 "awkgram.y" /* yacc.c:1646 */
{
- INSTRUCTION *ip = (yyvsp[(1) - (1)])->nexti;
+ INSTRUCTION *ip = (yyvsp[0])->nexti;
if (ip->opcode == Op_push
&& ip->memory->type == Node_var
&& ip->memory->var_update
) {
- (yyval) = list_prepend((yyvsp[(1) - (1)]), instruction(Op_var_update));
+ (yyval) = list_prepend((yyvsp[0]), instruction(Op_var_update));
(yyval)->nexti->update_var = ip->memory->var_update;
} else
- (yyval) = (yyvsp[(1) - (1)]);
+ (yyval) = (yyvsp[0]);
}
+#line 3907 "awkgram.c" /* yacc.c:1646 */
break;
- case 173:
-
-/* Line 1821 of yacc.c */
-#line 1692 "awkgram.y"
+ case 177:
+#line 1816 "awkgram.y" /* yacc.c:1646 */
{
- (yyval) = list_append((yyvsp[(2) - (3)]), (yyvsp[(1) - (3)]));
- if ((yyvsp[(3) - (3)]) != NULL)
- mk_assignment((yyvsp[(2) - (3)]), NULL, (yyvsp[(3) - (3)]));
+ (yyval) = list_append((yyvsp[-1]), (yyvsp[-2]));
+ if ((yyvsp[0]) != NULL)
+ mk_assignment((yyvsp[-1]), NULL, (yyvsp[0]));
}
+#line 3917 "awkgram.c" /* yacc.c:1646 */
break;
- case 174:
-
-/* Line 1821 of yacc.c */
-#line 1701 "awkgram.y"
+ case 178:
+#line 1825 "awkgram.y" /* yacc.c:1646 */
{
- (yyvsp[(1) - (1)])->opcode = Op_postincrement;
+ (yyvsp[0])->opcode = Op_postincrement;
}
+#line 3925 "awkgram.c" /* yacc.c:1646 */
break;
- case 175:
-
-/* Line 1821 of yacc.c */
-#line 1705 "awkgram.y"
+ case 179:
+#line 1829 "awkgram.y" /* yacc.c:1646 */
{
- (yyvsp[(1) - (1)])->opcode = Op_postdecrement;
+ (yyvsp[0])->opcode = Op_postdecrement;
}
+#line 3933 "awkgram.c" /* yacc.c:1646 */
break;
- case 176:
-
-/* Line 1821 of yacc.c */
-#line 1708 "awkgram.y"
+ case 180:
+#line 1832 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 3939 "awkgram.c" /* yacc.c:1646 */
break;
- case 178:
-
-/* Line 1821 of yacc.c */
-#line 1716 "awkgram.y"
+ case 182:
+#line 1840 "awkgram.y" /* yacc.c:1646 */
{ yyerrok; }
+#line 3945 "awkgram.c" /* yacc.c:1646 */
break;
- case 179:
-
-/* Line 1821 of yacc.c */
-#line 1720 "awkgram.y"
+ case 183:
+#line 1844 "awkgram.y" /* yacc.c:1646 */
{ yyerrok; }
+#line 3951 "awkgram.c" /* yacc.c:1646 */
break;
- case 182:
-
-/* Line 1821 of yacc.c */
-#line 1729 "awkgram.y"
+ case 186:
+#line 1853 "awkgram.y" /* yacc.c:1646 */
{ yyerrok; }
+#line 3957 "awkgram.c" /* yacc.c:1646 */
break;
- case 183:
-
-/* Line 1821 of yacc.c */
-#line 1733 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); yyerrok; }
+ case 187:
+#line 1857 "awkgram.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); yyerrok; }
+#line 3963 "awkgram.c" /* yacc.c:1646 */
break;
- case 184:
-
-/* Line 1821 of yacc.c */
-#line 1737 "awkgram.y"
+ case 188:
+#line 1861 "awkgram.y" /* yacc.c:1646 */
{ yyerrok; }
+#line 3969 "awkgram.c" /* yacc.c:1646 */
break;
-
-/* Line 1821 of yacc.c */
-#line 4217 "awkgram.c"
+#line 3973 "awkgram.c" /* yacc.c:1646 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -4223,7 +3991,7 @@ regular_loop:
*++yyvsp = yyval;
- /* Now `shift' the result of the reduction. Determine what state
+ /* 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. */
@@ -4238,9 +4006,9 @@ regular_loop:
goto yynewstate;
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
+/*--------------------------------------.
+| yyerrlab -- here on detecting error. |
+`--------------------------------------*/
yyerrlab:
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
@@ -4291,20 +4059,20 @@ yyerrlab:
if (yyerrstatus == 3)
{
/* If just tried and failed to reuse lookahead token after an
- error, discard it. */
+ error, discard it. */
if (yychar <= YYEOF)
- {
- /* Return failure if at end of input. */
- if (yychar == YYEOF)
- YYABORT;
- }
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
else
- {
- yydestruct ("Error: discarding",
- yytoken, &yylval);
- yychar = YYEMPTY;
- }
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
}
/* Else will try to reuse lookahead token after shifting the error
@@ -4323,7 +4091,7 @@ yyerrorlab:
if (/*CONSTCOND*/ 0)
goto yyerrorlab;
- /* Do not reclaim the symbols of the rule which action triggered
+ /* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */
YYPOPSTACK (yylen);
yylen = 0;
@@ -4336,35 +4104,37 @@ yyerrorlab:
| yyerrlab1 -- common code for both syntax error and YYERROR. |
`-------------------------------------------------------------*/
yyerrlab1:
- yyerrstatus = 3; /* Each real token shifted decrements this. */
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
for (;;)
{
yyn = yypact[yystate];
if (!yypact_value_is_default (yyn))
- {
- yyn += YYTERROR;
- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
- {
- yyn = yytable[yyn];
- if (0 < yyn)
- break;
- }
- }
+ {
+ 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;
+ YYABORT;
yydestruct ("Error: popping",
- yystos[yystate], yyvsp);
+ yystos[yystate], yyvsp);
YYPOPSTACK (1);
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
}
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
/* Shift the error token. */
@@ -4388,7 +4158,7 @@ yyabortlab:
yyresult = 1;
goto yyreturn;
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#if !defined yyoverflow || YYERROR_VERBOSE
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
@@ -4407,14 +4177,14 @@ yyreturn:
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval);
}
- /* Do not reclaim the symbols of the rule which action triggered
+ /* Do not reclaim the symbols of the rule whose action triggered
this YYABORT or YYACCEPT. */
YYPOPSTACK (yylen);
YY_STACK_PRINT (yyss, yyssp);
while (yyssp != yyss)
{
yydestruct ("Cleanup: popping",
- yystos[*yyssp], yyvsp);
+ yystos[*yyssp], yyvsp);
YYPOPSTACK (1);
}
#ifndef yyoverflow
@@ -4425,14 +4195,9 @@ yyreturn:
if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);
#endif
- /* Make sure YYID is used. */
- return YYID (yyresult);
+ return yyresult;
}
-
-
-
-/* Line 2067 of yacc.c */
-#line 1739 "awkgram.y"
+#line 1863 "awkgram.y" /* yacc.c:1906 */
struct token {
@@ -4446,11 +4211,12 @@ struct token {
# 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 */
-# define BREAK 0x1000 /* break allowed inside */
-# define CONTINUE 0x2000 /* continue allowed inside */
+# define BREAK 0x0800 /* break allowed inside */
+# define CONTINUE 0x1000 /* continue allowed inside */
+# define DEBUG_USE 0x2000 /* for use by developers */
NODE *(*ptr)(int); /* function that implements this keyword */
+ NODE *(*ptr2)(int); /* alternate arbitrary-precision function */
};
#if 'a' == 0x81 /* it's EBCDIC */
@@ -4474,84 +4240,93 @@ tokcompare(const void *l, const void *r)
* Function pointers come from declarations in awk.h.
*/
+#ifdef HAVE_MPFR
+#define MPF(F) do_mpfr_##F
+#else
+#define MPF(F) 0
+#endif
+
static const struct token tokentab[] = {
-{"BEGIN", Op_rule, LEX_BEGIN, 0, 0},
-{"BEGINFILE", Op_rule, LEX_BEGINFILE, GAWKX, 0},
-{"END", Op_rule, LEX_END, 0, 0},
-{"ENDFILE", Op_rule, LEX_ENDFILE, GAWKX, 0},
+{"BEGIN", Op_rule, LEX_BEGIN, 0, 0, 0},
+{"BEGINFILE", Op_rule, LEX_BEGINFILE, GAWKX, 0, 0},
+{"END", Op_rule, LEX_END, 0, 0, 0},
+{"ENDFILE", Op_rule, LEX_ENDFILE, GAWKX, 0, 0},
#ifdef ARRAYDEBUG
-{"adump", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_adump},
+{"adump", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|DEBUG_USE, do_adump, 0},
#endif
-{"and", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_and},
-#ifdef ARRAYDEBUG
-{"aoption", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_aoption},
+{"and", Op_builtin, LEX_BUILTIN, GAWKX, do_and, MPF(and)},
+{"asort", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_asort, 0},
+{"asorti", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_asorti, 0},
+{"atan2", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_atan2, MPF(atan2)},
+{"bindtextdomain", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_bindtextdomain, 0},
+{"break", Op_K_break, LEX_BREAK, 0, 0, 0},
+{"case", Op_K_case, LEX_CASE, GAWKX, 0, 0},
+{"close", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1)|A(2), do_close, 0},
+{"compl", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_compl, MPF(compl)},
+{"continue", Op_K_continue, LEX_CONTINUE, 0, 0, 0},
+{"cos", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_cos, MPF(cos)},
+{"dcgettext", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_dcgettext, 0},
+{"dcngettext", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3)|A(4)|A(5), do_dcngettext, 0},
+{"default", Op_K_default, LEX_DEFAULT, GAWKX, 0, 0},
+{"delete", Op_K_delete, LEX_DELETE, NOT_OLD, 0, 0},
+{"div", Op_builtin, LEX_BUILTIN, GAWKX|A(3), do_div, MPF(div)},
+{"do", Op_K_do, LEX_DO, NOT_OLD|BREAK|CONTINUE, 0, 0},
+{"else", Op_K_else, LEX_ELSE, 0, 0, 0},
+{"eval", Op_symbol, LEX_EVAL, 0, 0, 0},
+{"exit", Op_K_exit, LEX_EXIT, 0, 0, 0},
+{"exp", Op_builtin, LEX_BUILTIN, A(1), do_exp, MPF(exp)},
+#ifdef DYNAMIC
+{"extension", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_ext, 0},
#endif
-{"asort", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_asort},
-{"asorti", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_asorti},
-{"atan2", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_atan2},
-{"bindtextdomain", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_bindtextdomain},
-{"break", Op_K_break, LEX_BREAK, 0, 0},
-{"case", Op_K_case, LEX_CASE, GAWKX, 0},
-{"close", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1)|A(2), do_close},
-{"compl", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_compl},
-{"continue", Op_K_continue, LEX_CONTINUE, 0, 0},
-{"cos", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_cos},
-{"dcgettext", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_dcgettext},
-{"dcngettext", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3)|A(4)|A(5), do_dcngettext},
-{"default", Op_K_default, LEX_DEFAULT, GAWKX, 0},
-{"delete", Op_K_delete, LEX_DELETE, NOT_OLD, 0},
-{"do", Op_K_do, LEX_DO, NOT_OLD|BREAK|CONTINUE, 0},
-{"else", Op_K_else, LEX_ELSE, 0, 0},
-{"eval", Op_symbol, LEX_EVAL, 0, 0},
-{"exit", Op_K_exit, LEX_EXIT, 0, 0},
-{"exp", Op_builtin, LEX_BUILTIN, A(1), do_exp},
-{"extension", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_ext},
-{"fflush", Op_builtin, LEX_BUILTIN, RESX|A(0)|A(1), do_fflush},
-{"for", Op_K_for, LEX_FOR, BREAK|CONTINUE, 0},
-{"func", Op_func, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0},
-{"function",Op_func, LEX_FUNCTION, NOT_OLD, 0},
-{"gensub", Op_sub_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), 0},
-{"getline", Op_K_getline_redir, LEX_GETLINE, NOT_OLD, 0},
-{"gsub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0},
-{"if", Op_K_if, LEX_IF, 0, 0},
-{"in", Op_symbol, LEX_IN, 0, 0},
-{"include", Op_symbol, LEX_INCLUDE, GAWKX, 0},
-{"index", Op_builtin, LEX_BUILTIN, A(2), do_index},
-{"int", Op_builtin, LEX_BUILTIN, A(1), do_int},
-{"isarray", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_isarray},
-{"length", Op_builtin, LEX_LENGTH, A(0)|A(1), do_length},
-{"log", Op_builtin, LEX_BUILTIN, A(1), do_log},
-{"lshift", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_lshift},
-{"match", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_match},
-{"mktime", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_mktime},
-{"next", Op_K_next, LEX_NEXT, 0, 0},
-{"nextfile", Op_K_nextfile, LEX_NEXTFILE, GAWKX, 0},
-{"or", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_or},
-{"patsplit", Op_builtin, LEX_BUILTIN, GAWKX|A(2)|A(3)|A(4), do_patsplit},
-{"print", Op_K_print, LEX_PRINT, 0, 0},
-{"printf", Op_K_printf, LEX_PRINTF, 0, 0},
-{"rand", Op_builtin, LEX_BUILTIN, NOT_OLD|A(0), do_rand},
-{"return", Op_K_return, LEX_RETURN, NOT_OLD, 0},
-{"rshift", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_rshift},
-{"sin", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_sin},
-{"split", Op_builtin, LEX_BUILTIN, A(2)|A(3)|A(4), do_split},
-{"sprintf", Op_builtin, LEX_BUILTIN, 0, do_sprintf},
-{"sqrt", Op_builtin, LEX_BUILTIN, A(1), do_sqrt},
-{"srand", Op_builtin, LEX_BUILTIN, NOT_OLD|A(0)|A(1), do_srand},
-{"strftime", Op_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2)|A(3), do_strftime},
-{"strtonum", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum},
-{"sub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0},
-{"substr", Op_builtin, LEX_BUILTIN, A(2)|A(3), do_substr},
-{"switch", Op_K_switch, LEX_SWITCH, GAWKX|BREAK, 0},
-{"system", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_system},
-{"systime", Op_builtin, LEX_BUILTIN, GAWKX|A(0), do_systime},
-{"tolower", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_tolower},
-{"toupper", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_toupper},
-{"while", Op_K_while, LEX_WHILE, BREAK|CONTINUE, 0},
-{"xor", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_xor},
+{"fflush", Op_builtin, LEX_BUILTIN, A(0)|A(1), do_fflush, 0},
+{"for", Op_K_for, LEX_FOR, BREAK|CONTINUE, 0, 0},
+{"func", Op_func, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0, 0},
+{"function",Op_func, LEX_FUNCTION, NOT_OLD, 0, 0},
+{"gensub", Op_sub_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), 0, 0},
+{"getline", Op_K_getline_redir, LEX_GETLINE, NOT_OLD, 0, 0},
+{"gsub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0, 0},
+{"if", Op_K_if, LEX_IF, 0, 0, 0},
+{"in", Op_symbol, LEX_IN, 0, 0, 0},
+{"include", Op_symbol, LEX_INCLUDE, GAWKX, 0, 0},
+{"index", Op_builtin, LEX_BUILTIN, A(2), do_index, 0},
+{"int", Op_builtin, LEX_BUILTIN, A(1), do_int, MPF(int)},
+{"isarray", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_isarray, 0},
+{"length", Op_builtin, LEX_LENGTH, A(0)|A(1), do_length, 0},
+{"load", Op_symbol, LEX_LOAD, GAWKX, 0, 0},
+{"log", Op_builtin, LEX_BUILTIN, A(1), do_log, MPF(log)},
+{"lshift", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_lshift, MPF(lshift)},
+{"match", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_match, 0},
+{"mktime", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_mktime, 0},
+{"next", Op_K_next, LEX_NEXT, 0, 0, 0},
+{"nextfile", Op_K_nextfile, LEX_NEXTFILE, 0, 0, 0},
+{"or", Op_builtin, LEX_BUILTIN, GAWKX, do_or, MPF(or)},
+{"patsplit", Op_builtin, LEX_BUILTIN, GAWKX|A(2)|A(3)|A(4), do_patsplit, 0},
+{"print", Op_K_print, LEX_PRINT, 0, 0, 0},
+{"printf", Op_K_printf, LEX_PRINTF, 0, 0, 0},
+{"rand", Op_builtin, LEX_BUILTIN, NOT_OLD|A(0), do_rand, MPF(rand)},
+{"return", Op_K_return, LEX_RETURN, NOT_OLD, 0, 0},
+{"rshift", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_rshift, MPF(rshift)},
+{"sin", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_sin, MPF(sin)},
+{"split", Op_builtin, LEX_BUILTIN, A(2)|A(3)|A(4), do_split, 0},
+{"sprintf", Op_builtin, LEX_BUILTIN, 0, do_sprintf, 0},
+{"sqrt", Op_builtin, LEX_BUILTIN, A(1), do_sqrt, MPF(sqrt)},
+{"srand", Op_builtin, LEX_BUILTIN, NOT_OLD|A(0)|A(1), do_srand, MPF(srand)},
+#if defined(GAWKDEBUG) || defined(ARRAYDEBUG) /* || ... */
+{"stopme", Op_builtin, LEX_BUILTIN, GAWKX|A(0)|DEBUG_USE, stopme, 0},
+#endif
+{"strftime", Op_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2)|A(3), do_strftime, 0},
+{"strtonum", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum, MPF(strtonum)},
+{"sub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0, 0},
+{"substr", Op_builtin, LEX_BUILTIN, A(2)|A(3), do_substr, 0},
+{"switch", Op_K_switch, LEX_SWITCH, GAWKX|BREAK, 0, 0},
+{"system", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_system, 0},
+{"systime", Op_builtin, LEX_BUILTIN, GAWKX|A(0), do_systime, 0},
+{"tolower", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_tolower, 0},
+{"toupper", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_toupper, 0},
+{"while", Op_K_while, LEX_WHILE, BREAK|CONTINUE, 0, 0},
+{"xor", Op_builtin, LEX_BUILTIN, GAWKX, do_xor, MPF(xor)},
};
-#if MBS_SUPPORT
/* Variable containing the current shift state. */
static mbstate_t cur_mbstate;
/* Ring buffer containing current characters. */
@@ -4563,10 +4338,6 @@ 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) */
@@ -4578,12 +4349,53 @@ getfname(NODE *(*fptr)(int))
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)
+ if (tokentab[i].ptr == fptr || tokentab[i].ptr2 == fptr)
return tokentab[i].operator;
return NULL;
}
+/* negate_num --- negate a number in NODE */
+
+void
+negate_num(NODE *n)
+{
+#ifdef HAVE_MPFR
+ int tval = 0;
+#endif
+
+ if (! is_mpg_number(n)) {
+ n->numbr = -n->numbr;
+ return;
+ }
+
+#ifdef HAVE_MPFR
+ if (is_mpg_integer(n)) {
+ if (! iszero(n)) {
+ mpz_neg(n->mpg_i, n->mpg_i);
+ return;
+ }
+
+ /*
+ * 0 --> -0 conversion. Requires turning the MPG integer
+ * into an MPFR float.
+ */
+
+ mpz_clear(n->mpg_i); /* release the integer storage */
+
+ /* Convert and fall through. */
+ tval = mpfr_set_d(n->mpg_numbr, 0.0, ROUND_MODE);
+ IEEE_FMT(n->mpg_numbr, tval);
+ n->flags &= ~MPZN;
+ n->flags |= MPFN;
+ }
+
+ /* mpfr float case */
+ tval = mpfr_neg(n->mpg_numbr, n->mpg_numbr, ROUND_MODE);
+ IEEE_FMT(n->mpg_numbr, tval);
+#endif
+}
+
/* print_included_from --- print `Included from ..' file names and locations */
static void
@@ -4607,7 +4419,7 @@ print_included_from()
line--;
msg("%s %s:%d%c",
s->prev == sourcefile ? "In file included from"
- : " from",
+ : " from",
(s->stype == SRC_INC ||
s->stype == SRC_FILE) ? s->src : "cmd. line",
line,
@@ -4629,7 +4441,7 @@ warning_ln(int line, const char *mesg, ...)
sourceline = line;
print_included_from();
va_start(args, mesg);
- err(_("warning: "), mesg, args);
+ err(false, _("warning: "), mesg, args);
va_end(args);
sourceline = saveline;
}
@@ -4647,9 +4459,9 @@ lintwarn_ln(int line, const char *mesg, ...)
print_included_from();
va_start(args, mesg);
if (lintfunc == r_fatal)
- err(_("fatal: "), mesg, args);
+ err(true, _("fatal: "), mesg, args);
else
- err(_("warning: "), mesg, args);
+ err(false, _("warning: "), mesg, args);
va_end(args);
sourceline = saveline;
if (lintfunc == r_fatal)
@@ -4669,7 +4481,7 @@ error_ln(int line, const char *m, ...)
print_included_from();
errcount++;
va_start(args, m);
- err("error: ", m, args);
+ err(false, "error: ", m, args);
va_end(args);
sourceline = saveline;
}
@@ -4747,7 +4559,7 @@ yyerror(const char *m, ...)
*bp++ = ' ';
}
strcpy(bp, mesg);
- err("", buf, args);
+ err(false, "", buf, args);
va_end(args);
efree(buf);
}
@@ -4788,7 +4600,7 @@ mk_program()
if (endfile_block == NULL)
endfile_block = list_create(ip_endfile);
else {
- ip_rec->has_endfile = TRUE;
+ ip_rec->has_endfile = true;
(void) list_prepend(endfile_block, ip_endfile);
}
@@ -4814,6 +4626,11 @@ mk_program()
cp = end_block;
else
cp = list_merge(begin_block, end_block);
+ if (program_comment != NULL) {
+ (void) list_prepend(cp, program_comment);
+ }
+ if (comment != NULL)
+ (void) list_append(cp, comment);
(void) list_append(cp, ip_atexit);
(void) list_append(cp, instruction(Op_stop));
@@ -4846,6 +4663,12 @@ mk_program()
if (begin_block != NULL)
cp = list_merge(begin_block, cp);
+ if (program_comment != NULL) {
+ (void) list_prepend(cp, program_comment);
+ }
+ if (comment != NULL) {
+ (void) list_append(cp, comment);
+ }
(void) list_append(cp, ip_atexit);
(void) list_append(cp, instruction(Op_stop));
@@ -4853,6 +4676,10 @@ out:
/* delete the Op_list, not needed */
tmp = cp->nexti;
bcfree(cp);
+ /* these variables are not used again but zap them anyway. */
+ comment = NULL;
+ function_comment = NULL;
+ program_comment = NULL;
return tmp;
#undef begin_block
@@ -4889,8 +4716,11 @@ parse_program(INSTRUCTION **pcode)
ip_atexit = instruction(Op_atexit); /* target for `exit' in END block */
}
- sourcefile = srcfiles->next;
- lexeof = FALSE;
+ for (sourcefile = srcfiles->next; sourcefile->stype == SRC_EXTLIB;
+ sourcefile = sourcefile->next)
+ ;
+
+ lexeof = false;
lexptr = NULL;
lasttok = 0;
memset(rule_block, 0, sizeof(ruletab) * sizeof(INSTRUCTION *));
@@ -4906,13 +4736,27 @@ parse_program(INSTRUCTION **pcode)
if (ret == 0) /* avoid spurious warning if parser aborted with YYABORT */
check_funcs();
+ if (args_array == NULL)
+ emalloc(args_array, NODE **, (max_args + 2) * sizeof(NODE *), "parse_program");
+ else
+ erealloc(args_array, NODE **, (max_args + 2) * sizeof(NODE *), "parse_program");
+
return (ret || errcount);
}
+/* free_srcfile --- free a SRCFILE struct */
+
+void
+free_srcfile(SRCFILE *thisfile)
+{
+ efree(thisfile->src);
+ efree(thisfile);
+}
+
/* do_add_srcfile --- add one item to srcfiles */
static SRCFILE *
-do_add_srcfile(int stype, char *src, char *path, SRCFILE *thisfile)
+do_add_srcfile(enum srctype stype, char *src, char *path, SRCFILE *thisfile)
{
SRCFILE *s;
@@ -4934,7 +4778,7 @@ do_add_srcfile(int stype, char *src, char *path, SRCFILE *thisfile)
*/
SRCFILE *
-add_srcfile(int stype, char *src, SRCFILE *thisfile, int *already_included, int *errcode)
+add_srcfile(enum srctype stype, char *src, SRCFILE *thisfile, bool *already_included, int *errcode)
{
SRCFILE *s;
struct stat sbuf;
@@ -4942,41 +4786,61 @@ add_srcfile(int stype, char *src, SRCFILE *thisfile, int *already_included, int
int errno_val = 0;
if (already_included)
- *already_included = FALSE;
+ *already_included = false;
if (errcode)
*errcode = 0;
if (stype == SRC_CMDLINE || stype == SRC_STDIN)
return do_add_srcfile(stype, src, NULL, thisfile);
- path = find_source(src, &sbuf, &errno_val);
+ path = find_source(src, & sbuf, &errno_val, stype == SRC_EXTLIB);
if (path == NULL) {
if (errcode) {
*errcode = errno_val;
return NULL;
}
- fatal(_("can't open source file `%s' for reading (%s)"),
- src, errno_val ? strerror(errno_val) : _("reason unknown"));
+ /* use full messages to ease translation */
+ fatal(stype != SRC_EXTLIB
+ ? _("can't open source file `%s' for reading (%s)")
+ : _("can't open shared library `%s' for reading (%s)"),
+ src,
+ errno_val ? strerror(errno_val) : _("reason unknown"));
}
+ /* N.B. We do not eliminate duplicate SRC_FILE (-f) programs. */
for (s = srcfiles->next; s != srcfiles; s = s->next) {
- if ((s->stype == SRC_FILE || s->stype == SRC_INC)
- && files_are_same(path, s)
- ) {
- if (do_lint) {
- int line = sourceline;
- /* Kludge: the line number may be off for `@include file'.
- * Since, this function is also used for '-f file' in main.c,
- * sourceline > 1 check ensures that the call is at
- * parse time.
- */
- if (sourceline > 1 && lasttok == NEWLINE)
- line--;
- lintwarn_ln(line, _("already included source file `%s'"), src);
+ if ((s->stype == SRC_FILE || s->stype == SRC_INC || s->stype == SRC_EXTLIB) && files_are_same(path, s)) {
+ if (stype == SRC_INC || stype == SRC_EXTLIB) {
+ /* eliminate duplicates */
+ if ((stype == SRC_INC) && (s->stype == SRC_FILE))
+ fatal(_("can't include `%s' and use it as a program file"), src);
+
+ if (do_lint) {
+ int line = sourceline;
+ /* Kludge: the line number may be off for `@include file'.
+ * Since, this function is also used for '-f file' in main.c,
+ * sourceline > 1 check ensures that the call is at
+ * parse time.
+ */
+ if (sourceline > 1 && lasttok == NEWLINE)
+ line--;
+ lintwarn_ln(line,
+ stype != SRC_EXTLIB
+ ? _("already included source file `%s'")
+ : _("already loaded shared library `%s'"),
+ src);
+ }
+ efree(path);
+ if (already_included)
+ *already_included = true;
+ return NULL;
+ } else {
+ /* duplicates are allowed for -f */
+ if (s->stype == SRC_INC)
+ fatal(_("can't include `%s' and use it as a program file"), src);
+ /* no need to scan for further matches, since
+ * they must be of homogeneous type */
+ break;
}
- efree(path);
- if (already_included)
- *already_included = TRUE;
- return NULL;
}
}
@@ -4994,7 +4858,7 @@ include_source(INSTRUCTION *file)
SRCFILE *s;
char *src = file->lextok;
int errcode;
- int already_included;
+ bool already_included;
if (do_traditional || do_posix) {
error_ln(file->source_line, _("@include is a gawk extension"));
@@ -5031,8 +4895,43 @@ include_source(INSTRUCTION *file)
sourceline = 0;
source = NULL;
lasttok = 0;
- lexeof = FALSE;
- eof_warned = FALSE;
+ lexeof = false;
+ eof_warned = false;
+ return 0;
+}
+
+/* load_library --- load a shared library */
+
+static int
+load_library(INSTRUCTION *file)
+{
+ SRCFILE *s;
+ char *src = file->lextok;
+ int errcode;
+ bool already_included;
+
+ if (do_traditional || do_posix) {
+ error_ln(file->source_line, _("@load is a gawk extension"));
+ return -1;
+ }
+
+ if (strlen(src) == 0) {
+ if (do_lint)
+ lintwarn_ln(file->source_line, _("empty filename after @load"));
+ return 0;
+ }
+
+ s = add_srcfile(SRC_EXTLIB, src, sourcefile, &already_included, &errcode);
+ if (s == NULL) {
+ if (already_included)
+ return 0;
+ error_ln(file->source_line,
+ _("can't open shared library `%s' for reading (%s)"),
+ src, errcode ? strerror(errcode) : _("reason unknown"));
+ return -1;
+ }
+
+ load_ext(s->fullpath);
return 0;
}
@@ -5059,11 +4958,11 @@ next_sourcefile()
* Previous versions of gawk did not core dump in such a
* case.
*
- * assert(lexeof == TRUE);
+ * assert(lexeof == true);
*/
- lexeof = FALSE;
- eof_warned = FALSE;
+ lexeof = false;
+ eof_warned = false;
sourcefile->srclines = sourceline; /* total no of lines in current file */
if (sourcefile->fd > INVALID_HANDLE) {
if (sourcefile->fd != fileno(stdin)) /* safety */
@@ -5076,9 +4975,12 @@ next_sourcefile()
sourcefile->lexptr_begin = NULL;
}
- sourcefile = sourcefile->next;
- if (sourcefile == srcfiles)
- return;
+ while ((sourcefile = sourcefile->next) != NULL) {
+ if (sourcefile == srcfiles)
+ return;
+ if (sourcefile->stype != SRC_EXTLIB)
+ break;
+ }
if (sourcefile->lexptr_begin != NULL) {
/* resume reading from already opened file (postponed to process '@include') */
@@ -5104,7 +5006,7 @@ get_src_buf()
{
int n;
char *scan;
- int newfile;
+ bool newfile;
int savelen;
struct stat sbuf;
@@ -5129,7 +5031,7 @@ get_src_buf()
readfunc = read_one_line;
}
- newfile = FALSE;
+ newfile = false;
if (sourcefile == srcfiles)
return NULL;
@@ -5145,13 +5047,13 @@ get_src_buf()
* gawk '' /path/name
* Sigh.
*/
- static short warned = FALSE;
+ static bool warned = false;
if (do_lint && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn(_("empty program text on command line"));
}
- lexeof = TRUE;
+ lexeof = true;
}
} else if (sourcefile->buf == NULL && *(lexptr-1) != '\n') {
/*
@@ -5179,7 +5081,7 @@ get_src_buf()
lexend = lexptr + 1;
sourcefile->buf = buf;
} else
- lexeof = TRUE;
+ lexeof = true;
return lexptr;
}
@@ -5200,7 +5102,7 @@ get_src_buf()
error(_("can't open source file `%s' for reading (%s)"),
in, strerror(errno));
errcount++;
- lexeof = TRUE;
+ lexeof = true;
return sourcefile->src;
}
@@ -5216,7 +5118,7 @@ get_src_buf()
l = A_DECENT_BUFFER_SIZE;
#undef A_DECENT_BUFFER_SIZE
sourcefile->bufsize = l;
- newfile = TRUE;
+ newfile = true;
emalloc(sourcefile->buf, char *, sourcefile->bufsize, "get_src_buf");
lexptr = lexptr_begin = lexeme = sourcefile->buf;
savelen = 0;
@@ -5267,17 +5169,17 @@ get_src_buf()
error(_("can't read sourcefile `%s' (%s)"),
source, strerror(errno));
errcount++;
- lexeof = TRUE;
+ lexeof = true;
} else {
lexend = lexptr + n;
if (n == 0) {
- static short warned = FALSE;
- if (do_lint && newfile && ! warned){
- warned = TRUE;
+ static bool warned = false;
+ if (do_lint && newfile && ! warned) {
+ warned = true;
sourceline = 0;
lintwarn(_("source file `%s' is empty"), source);
}
- lexeof = TRUE;
+ lexeof = true;
}
}
return sourcefile->buf;
@@ -5309,12 +5211,38 @@ tokexpand()
return tok;
}
-/* nextc --- get the next input character */
+/* check_bad_char --- fatal if c isn't allowed in gawk source code */
+
+/*
+ * The error message was inspired by someone who decided to put
+ * a physical \0 byte into the source code to see what would
+ * happen and then filed a bug report about it. Sigh.
+ */
+
+static void
+check_bad_char(int c)
+{
+ /* allow escapes. needed for autoconf. bleah. */
+ switch (c) {
+ case '\a':
+ case '\b':
+ case '\f':
+ case '\n':
+ case '\r':
+ case '\t':
+ return;
+ default:
+ break;
+ }
+
+ if (iscntrl(c) && ! isspace(c))
+ fatal(_("PEBKAC error: invalid character '\\%03o' in source code"), c & 0xFF);
+}
-#if MBS_SUPPORT
+/* nextc --- get the next input character */
static int
-nextc(void)
+nextc(bool check_for_bad)
{
if (gawk_mb_cur_max > 1) {
again:
@@ -5337,7 +5265,7 @@ again:
mbstate_t tmp_state;
size_t mbclen;
- for (idx = 0 ; lexptr + idx < lexend ; idx++) {
+ for (idx = 0; lexptr + idx < lexend; idx++) {
tmp_state = cur_mbstate;
mbclen = mbrlen(lexptr, idx + 1, &tmp_state);
@@ -5365,48 +5293,134 @@ again:
0 : work_ring_idx + 1;
cur_char_ring[work_ring_idx] = 0;
}
+ if (check_for_bad)
+ check_bad_char(*lexptr);
return (int) (unsigned char) *lexptr++;
} else {
do {
if (lexeof)
return END_FILE;
- if (lexptr && lexptr < lexend)
- return ((int) (unsigned char) *lexptr++);
+ if (lexptr && lexptr < lexend) {
+ if (check_for_bad)
+ check_bad_char(*lexptr);
+ return ((int) (unsigned char) *lexptr++);
+ }
} while (get_src_buf());
return END_SRC;
}
}
-#else /* MBS_SUPPORT */
-
-int
-nextc()
-{
- do {
- if (lexeof)
- return END_FILE;
- if (lexptr && lexptr < lexend)
- return ((int) (unsigned char) *lexptr++);
- } while (get_src_buf());
- return END_SRC;
-}
-
-#endif /* MBS_SUPPORT */
-
/* pushback --- push a character back on the input */
static inline void
pushback(void)
{
-#if MBS_SUPPORT
if (gawk_mb_cur_max > 1)
cur_ring_idx = (cur_ring_idx == 0)? RING_BUFFER_SIZE - 1 :
cur_ring_idx - 1;
-#endif
(! lexeof && lexptr && lexptr > lexptr_begin ? lexptr-- : lexptr);
}
+/* check_comment --- check for block comment */
+
+void
+check_comment(void)
+{
+ if (comment != NULL) {
+ if (first_rule) {
+ program_comment = comment;
+ } else
+ block_comment = comment;
+ comment = NULL;
+ }
+ first_rule = false;
+}
+
+/*
+ * get_comment --- collect comment text.
+ * Flag = EOL_COMMENT for end-of-line comments.
+ * Flag = FULL_COMMENT for self-contained comments.
+ */
+
+int
+get_comment(int flag)
+{
+ int c;
+ int sl;
+ tok = tokstart;
+ tokadd('#');
+ sl = sourceline;
+
+ while (true) {
+ while ((c = nextc(false)) != '\n' && c != END_FILE) {
+ tokadd(c);
+ }
+ if (flag == EOL_COMMENT) {
+ /* comment at end of line. */
+ if (c == '\n')
+ tokadd(c);
+ break;
+ }
+ if (c == '\n') {
+ tokadd(c);
+ sourceline++;
+ do {
+ c = nextc(false);
+ if (c == '\n') {
+ sourceline++;
+ tokadd(c);
+ }
+ } while (isspace(c) && c != END_FILE);
+ if (c == END_FILE)
+ break;
+ else if (c != '#') {
+ pushback();
+ sourceline--;
+ break;
+ } else
+ tokadd(c);
+ } else
+ break;
+ }
+ comment = bcalloc(Op_comment, 1, sl);
+ comment->source_file = source;
+ comment->memory = make_str_node(tokstart, tok - tokstart, 0);
+ comment->memory->comment_type = flag;
+
+ return c;
+}
+
+/* split_comment --- split initial comment text into program and function parts */
+
+static void
+split_comment(void)
+{
+ char *p;
+ int l;
+ NODE *n;
+
+ p = comment->memory->stptr;
+ l = comment->memory->stlen - 3;
+ /* have at least two comments so split at last blank line (\n\n) */
+ while (l >= 0) {
+ if (p[l] == '\n' && p[l+1] == '\n') {
+ function_comment = comment;
+ n = function_comment->memory;
+ function_comment->memory = make_str_node(p + l + 2, n->stlen - l - 2, 0);
+ /* create program comment */
+ program_comment = bcalloc(Op_comment, 1, sourceline);
+ program_comment->source_file = comment->source_file;
+ p[l + 2] = 0;
+ program_comment->memory = make_str_node(p, l + 2, 0);
+ comment = NULL;
+ freenode(n);
+ break;
+ }
+ else
+ l--;
+ }
+}
/* allow_newline --- allow newline after &&, ||, ? and : */
@@ -5416,14 +5430,19 @@ allow_newline(void)
int c;
for (;;) {
- c = nextc();
+ c = nextc(true);
if (c == END_FILE) {
pushback();
break;
}
if (c == '#') {
- while ((c = nextc()) != '\n' && c != END_FILE)
- continue;
+ if (do_pretty_print && ! do_profile) {
+ /* collect comment byte code iff doing pretty print but not profiling. */
+ c = get_comment(EOL_COMMENT);
+ } else {
+ while ((c = nextc(false)) != '\n' && c != END_FILE)
+ continue;
+ }
if (c == END_FILE) {
pushback();
break;
@@ -5438,33 +5457,53 @@ allow_newline(void)
}
}
+/* newline_eof --- return newline or EOF as needed and adjust variables */
+
+/*
+ * This routine used to be a macro, however GCC 4.6.2 warned about
+ * the result of a computation not being used. Converting to a function
+ * removes the warnings.
+ */
+
+static int
+newline_eof()
+{
+ /* NB: a newline at end does not start a source line. */
+ if (lasttok != NEWLINE) {
+ pushback();
+ if (do_lint && ! eof_warned) {
+ lintwarn(_("source file does not end in newline"));
+ eof_warned = true;
+ }
+ sourceline++;
+ return NEWLINE;
+ }
+
+ sourceline--;
+ eof_warned = false;
+ return LEX_EOF;
+}
+
/* yylex --- Read the input and turn it into tokens. */
static int
yylex(void)
{
int c;
- int seen_e = FALSE; /* These are for numbers */
- int seen_point = FALSE;
- int esc_seen; /* for literal strings */
+ bool seen_e = false; /* These are for numbers */
+ bool seen_point = false;
+ bool esc_seen; /* for literal strings */
int mid;
- static int did_newline = FALSE;
+ int base;
+ static bool did_newline = false;
char *tokkey;
- int inhex = FALSE;
- int intlstr = FALSE;
+ bool inhex = false;
+ bool intlstr = false;
AWKNUM d;
#define GET_INSTRUCTION(op) bcalloc(op, 1, sourceline)
- /* NB: a newline at end does not start a source line. */
-
-#define NEWLINE_EOF \
- (lasttok != NEWLINE ? \
- (pushback(), do_lint && ! eof_warned && \
- (lintwarn(_("source file does not end in newline")), \
- eof_warned = TRUE), sourceline++, NEWLINE) : \
- (sourceline--, eof_warned = FALSE, LEX_EOF))
-
+#define NEWLINE_EOF newline_eof()
yylval = (INSTRUCTION *) NULL;
if (lasttok == SUBSCRIPT) {
@@ -5475,7 +5514,7 @@ yylex(void)
if (lasttok == LEX_EOF) /* error earlier in current source, must give up !! */
return 0;
- c = nextc();
+ c = nextc(true);
if (c == END_SRC)
return 0;
if (c == END_FILE)
@@ -5514,29 +5553,27 @@ yylex(void)
* The code for \ handles \[ and \].
*/
- want_regexp = FALSE;
+ want_regexp = false;
tok = tokstart;
for (;;) {
- c = nextc();
+ c = nextc(true);
if (gawk_mb_cur_max == 1 || nextc_is_1stbyte) switch (c) {
case '[':
/* one day check for `.' and `=' too */
- if (nextc() == ':' || in_brack == 0)
+ if (nextc(true) == ':' || in_brack == 0)
in_brack++;
pushback();
break;
case ']':
- if (tokstart[0] == '['
- && (tok == tokstart + 1
- || (tok == tokstart + 2
- && tokstart[1] == '^')))
+ if (tok[-1] == '['
+ || (tok[-2] == '[' && tok[-1] == '^'))
/* do nothing */;
else
in_brack--;
break;
case '\\':
- if ((c = nextc()) == END_FILE) {
+ if ((c = nextc(true)) == END_FILE) {
pushback();
yyerror(_("unterminated regexp ends with `\\' at end of file"));
goto end_regexp; /* kludge */
@@ -5556,7 +5593,7 @@ end_regexp:
yylval = GET_INSTRUCTION(Op_token);
yylval->lextok = estrdup(tokstart, tok - tokstart);
if (do_lint) {
- int peek = nextc();
+ int peek = nextc(true);
pushback();
if (peek == 'i' || peek == 's') {
@@ -5586,16 +5623,14 @@ end_regexp:
retry:
/* skipping \r is a hack, but windows is just too pervasive. sigh. */
- while ((c = nextc()) == ' ' || c == '\t' || c == '\r')
+ while ((c = nextc(true)) == ' ' || c == '\t' || c == '\r')
continue;
lexeme = lexptr ? lexptr - 1 : lexptr;
thisline = NULL;
tok = tokstart;
-#if MBS_SUPPORT
if (gawk_mb_cur_max == 1 || nextc_is_1stbyte)
-#endif
switch (c) {
case END_SRC:
return 0;
@@ -5608,9 +5643,23 @@ retry:
return lasttok = NEWLINE;
case '#': /* it's a comment */
- while ((c = nextc()) != '\n') {
+ if (do_pretty_print && ! do_profile) {
+ /*
+ * Collect comment byte code iff doing pretty print
+ * but not profiling.
+ */
+ if (lasttok == NEWLINE || lasttok == 0)
+ c = get_comment(FULL_COMMENT);
+ else
+ c = get_comment(EOL_COMMENT);
+
if (c == END_FILE)
return lasttok = NEWLINE_EOF;
+ } else {
+ while ((c = nextc(false)) != '\n') {
+ if (c == END_FILE)
+ return lasttok = NEWLINE_EOF;
+ }
}
sourceline++;
return lasttok = NEWLINE;
@@ -5621,33 +5670,37 @@ retry:
case '\\':
#ifdef RELAXED_CONTINUATION
/*
- * This code puports to allow comments and/or whitespace
+ * This code purports 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')
+ while ((c = nextc(true)) == ' ' || c == '\t' || c == '\r')
continue;
if (c == '#') {
- static short warned = FALSE;
+ static bool warned = false;
if (do_lint && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn(
_("use of `\\ #...' line continuation is not portable"));
}
- while ((c = nextc()) != '\n')
- if (c == END_FILE)
- break;
+ if (do_pretty_print && ! do_profile)
+ c = get_comment(EOL_COMMENT);
+ else {
+ while ((c = nextc(false)) != '\n')
+ if (c == END_FILE)
+ break;
+ }
}
pushback();
}
#endif /* RELAXED_CONTINUATION */
- c = nextc();
+ c = nextc(true);
if (c == '\r') /* allow MS-DOS files. bleah */
- c = nextc();
+ c = nextc(true);
if (c == '\n') {
sourceline++;
goto retry;
@@ -5686,7 +5739,7 @@ retry:
case '[':
return lasttok = c;
case ']':
- c = nextc();
+ c = nextc(true);
pushback();
if (c == '[') {
yylval = GET_INSTRUCTION(Op_sub_array);
@@ -5698,7 +5751,7 @@ retry:
return ']';
case '*':
- if ((c = nextc()) == '=') {
+ if ((c = nextc(true)) == '=') {
yylval = GET_INSTRUCTION(Op_assign_times);
return lasttok = ASSIGNOP;
} else if (do_posix) {
@@ -5707,11 +5760,11 @@ retry:
return lasttok = '*';
} else if (c == '*') {
/* make ** and **= aliases for ^ and ^= */
- static int did_warn_op = FALSE, did_warn_assgn = FALSE;
+ static bool did_warn_op = false, did_warn_assgn = false;
- if (nextc() == '=') {
+ if (nextc(true) == '=') {
if (! did_warn_assgn) {
- did_warn_assgn = TRUE;
+ did_warn_assgn = true;
if (do_lint)
lintwarn(_("POSIX does not allow operator `**='"));
if (do_lint_old)
@@ -5722,7 +5775,7 @@ retry:
} else {
pushback();
if (! did_warn_op) {
- did_warn_op = TRUE;
+ did_warn_op = true;
if (do_lint)
lintwarn(_("POSIX does not allow operator `**'"));
if (do_lint_old)
@@ -5737,7 +5790,7 @@ retry:
return lasttok = '*';
case '/':
- if (nextc() == '=') {
+ if (nextc(true) == '=') {
pushback();
return lasttok = SLASH_BEFORE_EQUAL;
}
@@ -5746,7 +5799,7 @@ retry:
return lasttok = '/';
case '%':
- if (nextc() == '=') {
+ if (nextc(true) == '=') {
yylval = GET_INSTRUCTION(Op_assign_mod);
return lasttok = ASSIGNOP;
}
@@ -5756,11 +5809,11 @@ retry:
case '^':
{
- static int did_warn_op = FALSE, did_warn_assgn = FALSE;
+ static bool did_warn_op = false, did_warn_assgn = false;
- if (nextc() == '=') {
+ if (nextc(true) == '=') {
if (do_lint_old && ! did_warn_assgn) {
- did_warn_assgn = TRUE;
+ did_warn_assgn = true;
warning(_("operator `^=' is not supported in old awk"));
}
yylval = GET_INSTRUCTION(Op_assign_exp);
@@ -5768,7 +5821,7 @@ retry:
}
pushback();
if (do_lint_old && ! did_warn_op) {
- did_warn_op = TRUE;
+ did_warn_op = true;
warning(_("operator `^' is not supported in old awk"));
}
yylval = GET_INSTRUCTION(Op_exp);
@@ -5776,7 +5829,7 @@ retry:
}
case '+':
- if ((c = nextc()) == '=') {
+ if ((c = nextc(true)) == '=') {
yylval = GET_INSTRUCTION(Op_assign_plus);
return lasttok = ASSIGNOP;
}
@@ -5789,7 +5842,7 @@ retry:
return lasttok = '+';
case '!':
- if ((c = nextc()) == '=') {
+ if ((c = nextc(true)) == '=') {
yylval = GET_INSTRUCTION(Op_notequal);
return lasttok = RELOP;
}
@@ -5802,7 +5855,7 @@ retry:
return lasttok = '!';
case '<':
- if (nextc() == '=') {
+ if (nextc(true) == '=') {
yylval = GET_INSTRUCTION(Op_leq);
return lasttok = RELOP;
}
@@ -5811,7 +5864,7 @@ retry:
return lasttok = '<';
case '=':
- if (nextc() == '=') {
+ if (nextc(true) == '=') {
yylval = GET_INSTRUCTION(Op_equal);
return lasttok = RELOP;
}
@@ -5820,7 +5873,7 @@ retry:
return lasttok = ASSIGN;
case '>':
- if ((c = nextc()) == '=') {
+ if ((c = nextc(true)) == '=') {
yylval = GET_INSTRUCTION(Op_geq);
return lasttok = RELOP;
} else if (c == '>') {
@@ -5847,19 +5900,23 @@ retry:
* hacking the grammar.
*/
if (did_newline) {
- did_newline = FALSE;
+ did_newline = false;
if (--in_braces == 0)
lastline = sourceline;
return lasttok = c;
}
- did_newline++;
+ did_newline = true;
--lexptr; /* pick up } next time */
return lasttok = NEWLINE;
case '"':
string:
- esc_seen = FALSE;
- while ((c = nextc()) != '"') {
+ esc_seen = false;
+ /*
+ * Allow any kind of junk in quoted string,
+ * so pass false to nextc().
+ */
+ while ((c = nextc(false)) != '"') {
if (c == '\n') {
pushback();
yyerror(_("unterminated string"));
@@ -5867,12 +5924,12 @@ retry:
}
if ((gawk_mb_cur_max == 1 || nextc_is_1stbyte) &&
c == '\\') {
- c = nextc();
+ c = nextc(true);
if (c == '\n') {
sourceline++;
continue;
}
- esc_seen = TRUE;
+ esc_seen = true;
if (! want_source || c != '"')
tokadd('\\');
}
@@ -5894,14 +5951,14 @@ retry:
tok - tokstart, esc_seen ? SCAN : 0);
if (intlstr) {
yylval->memory->flags |= INTLSTR;
- intlstr = FALSE;
+ intlstr = false;
if (do_intl)
dumpintlstr(yylval->memory->stptr, yylval->memory->stlen);
}
return lasttok = YSTRING;
case '-':
- if ((c = nextc()) == '=') {
+ if ((c = nextc(true)) == '=') {
yylval = GET_INSTRUCTION(Op_assign_minus);
return lasttok = ASSIGNOP;
}
@@ -5914,7 +5971,7 @@ retry:
return lasttok = '-';
case '.':
- c = nextc();
+ c = nextc(true);
pushback();
if (! isdigit(c))
return lasttok = '.';
@@ -5933,7 +5990,7 @@ retry:
case '9':
/* It's a number */
for (;;) {
- int gotnumber = FALSE;
+ bool gotnumber = false;
tokadd(c);
switch (c) {
@@ -5942,10 +5999,10 @@ retry:
if (do_traditional)
goto done;
if (tok == tokstart + 2) {
- int peek = nextc();
+ int peek = nextc(true);
if (isxdigit(peek)) {
- inhex = TRUE;
+ inhex = true;
pushback(); /* following digit */
} else {
pushback(); /* x or X */
@@ -5956,22 +6013,22 @@ retry:
case '.':
/* period ends exponent part of floating point number */
if (seen_point || seen_e) {
- gotnumber = TRUE;
+ gotnumber = true;
break;
}
- seen_point = TRUE;
+ seen_point = true;
break;
case 'e':
case 'E':
if (inhex)
break;
if (seen_e) {
- gotnumber = TRUE;
+ gotnumber = true;
break;
}
- seen_e = TRUE;
- if ((c = nextc()) == '-' || c == '+') {
- int c2 = nextc();
+ seen_e = true;
+ if ((c = nextc(true)) == '-' || c == '+') {
+ int c2 = nextc(true);
if (isdigit(c2)) {
tokadd(c);
@@ -6014,27 +6071,52 @@ retry:
break;
default:
done:
- gotnumber = TRUE;
+ gotnumber = true;
}
if (gotnumber)
break;
- c = nextc();
+ c = nextc(true);
}
pushback();
tokadd('\0');
yylval = GET_INSTRUCTION(Op_push_i);
- if (! do_traditional && isnondecimal(tokstart, FALSE)) {
+
+ base = 10;
+ if (! do_traditional) {
+ base = get_numbase(tokstart, false);
if (do_lint) {
- if (isdigit((unsigned char) tokstart[1])) /* not an 'x' or 'X' */
+ if (base == 8)
lintwarn("numeric constant `%.*s' treated as octal",
(int) strlen(tokstart)-1, tokstart);
- else if (tokstart[1] == 'x' || tokstart[1] == 'X')
+ else if (base == 16)
lintwarn("numeric constant `%.*s' treated as hexadecimal",
(int) strlen(tokstart)-1, tokstart);
}
+ }
+
+#ifdef HAVE_MPFR
+ if (do_mpfr) {
+ NODE *r;
+
+ if (! seen_point && ! seen_e) {
+ r = mpg_integer();
+ mpg_strtoui(r->mpg_i, tokstart, strlen(tokstart), NULL, base);
+ errno = 0;
+ } else {
+ int tval;
+ r = mpg_float();
+ tval = mpfr_strtofr(r->mpg_numbr, tokstart, NULL, base, ROUND_MODE);
+ errno = 0;
+ IEEE_FMT(r->mpg_numbr, tval);
+ }
+ yylval->memory = r;
+ return lasttok = YNUMBER;
+ }
+#endif
+ if (base != 10)
d = nondec2awknum(tokstart, strlen(tokstart));
- } else
+ else
d = atof(tokstart);
yylval->memory = make_number(d);
if (d <= INT32_MAX && d >= INT32_MIN && d == (int32_t) d)
@@ -6042,7 +6124,7 @@ retry:
return lasttok = YNUMBER;
case '&':
- if ((c = nextc()) == '&') {
+ if ((c = nextc(true)) == '&') {
yylval = GET_INSTRUCTION(Op_and);
allow_newline();
return lasttok = LEX_AND;
@@ -6052,7 +6134,7 @@ retry:
return lasttok = '&';
case '|':
- if ((c = nextc()) == '|') {
+ if ((c = nextc(true)) == '|') {
yylval = GET_INSTRUCTION(Op_or);
allow_newline();
return lasttok = LEX_OR;
@@ -6073,7 +6155,7 @@ retry:
}
}
- if (c != '_' && ! isalpha(c)) {
+ if (c != '_' && ! is_alpha(c)) {
yyerror(_("invalid char '%c' in expression"), c);
return lasttok = LEX_EOF;
}
@@ -6093,8 +6175,8 @@ retry:
* occasions where the interactions are funny.
*/
if (! do_traditional && c == '_' && lasttok != '$') {
- if ((c = nextc()) == '"') {
- intlstr = TRUE;
+ if ((c = nextc(true)) == '"') {
+ intlstr = true;
goto string;
}
pushback();
@@ -6105,7 +6187,7 @@ retry:
tok = tokstart;
while (c != END_FILE && is_identchar(c)) {
tokadd(c);
- c = nextc();
+ c = nextc(true);
}
tokadd('\0');
pushback();
@@ -6115,43 +6197,39 @@ retry:
static int warntab[sizeof(tokentab) / sizeof(tokentab[0])];
int class = tokentab[mid].class;
- if ((class == LEX_INCLUDE || class == LEX_EVAL)
+ if ((class == LEX_INCLUDE || class == LEX_LOAD || class == LEX_EVAL)
&& lasttok != '@')
goto out;
if (do_lint) {
- if ((tokentab[mid].flags & GAWKX) && ! (warntab[mid] & GAWKX)) {
+ if ((tokentab[mid].flags & GAWKX) != 0 && (warntab[mid] & GAWKX) == 0) {
lintwarn(_("`%s' is a gawk extension"),
tokentab[mid].operator);
warntab[mid] |= GAWKX;
}
- if ((tokentab[mid].flags & RESX) && ! (warntab[mid] & RESX)) {
- lintwarn(_("`%s' is a Bell Labs extension"),
- tokentab[mid].operator);
- warntab[mid] |= RESX;
- }
- if ((tokentab[mid].flags & NOT_POSIX) && ! (warntab[mid] & NOT_POSIX)) {
+ if ((tokentab[mid].flags & NOT_POSIX) != 0 && (warntab[mid] & NOT_POSIX) == 0) {
lintwarn(_("POSIX does not allow `%s'"),
tokentab[mid].operator);
warntab[mid] |= NOT_POSIX;
}
}
- if (do_lint_old && (tokentab[mid].flags & NOT_OLD)
- && ! (warntab[mid] & NOT_OLD)
+ if (do_lint_old && (tokentab[mid].flags & NOT_OLD) != 0
+ && (warntab[mid] & NOT_OLD) == 0
) {
warning(_("`%s' is not supported in old awk"),
tokentab[mid].operator);
warntab[mid] |= NOT_OLD;
}
- if (tokentab[mid].flags & BREAK)
+ if ((tokentab[mid].flags & BREAK) != 0)
break_allowed++;
- if (tokentab[mid].flags & CONTINUE)
+ if ((tokentab[mid].flags & CONTINUE) != 0)
continue_allowed++;
switch (class) {
case LEX_INCLUDE:
- want_source = TRUE;
+ case LEX_LOAD:
+ want_source = true;
break;
case LEX_EVAL:
if (in_main_context())
@@ -6175,14 +6253,36 @@ retry:
case LEX_WHILE:
case LEX_DO:
case LEX_SWITCH:
- if (! do_profiling)
+ if (! do_pretty_print)
return lasttok = class;
/* fall through */
case LEX_CASE:
yylval = bcalloc(tokentab[mid].value, 2, sourceline);
break;
+ /*
+ * These must be checked here, due to the LALR nature of the parser,
+ * the rules for continue and break may not be reduced until after
+ * a token that increments the xxx_allowed varibles is seen. Bleah.
+ */
+ case LEX_CONTINUE:
+ if (! continue_allowed) {
+ error_ln(sourceline,
+ _("`continue' is not allowed outside a loop"));
+ errcount++;
+ }
+ goto make_instruction;
+
+ case LEX_BREAK:
+ if (! break_allowed) {
+ error_ln(sourceline,
+ _("`break' is not allowed outside a loop or switch"));
+ errcount++;
+ }
+ goto make_instruction;
+
default:
+make_instruction:
yylval = GET_INSTRUCTION(tokentab[mid].value);
if (class == LEX_BUILTIN || class == LEX_LENGTH)
yylval->builtin_idx = mid;
@@ -6197,7 +6297,7 @@ out:
yylval->lextok = tokkey;
return lasttok = FUNC_CALL;
} else {
- static short goto_warned = FALSE;
+ static bool goto_warned = false;
yylval = GET_INSTRUCTION(Op_token);
yylval->lextok = tokkey;
@@ -6205,7 +6305,7 @@ out:
#define SMART_ALECK 1
if (SMART_ALECK && do_lint
&& ! goto_warned && strcasecmp(tokkey, "goto") == 0) {
- goto_warned = TRUE;
+ goto_warned = true;
lintwarn(_("`goto' considered harmful!\n"));
}
return lasttok = NAME;
@@ -6283,10 +6383,10 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
yyerror(_("%s third parameter is not a changeable object"),
operator);
else
- ip->do_reference = TRUE;
+ ip->do_reference = true;
}
- r->expr_count = count_expressions(&subn, FALSE);
+ r->expr_count = count_expressions(&subn, false);
ip = subn->lasti;
(void) list_append(subn, r);
@@ -6301,7 +6401,11 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
subn->lasti->assign_ctxt = Op_sub_builtin;
subn->lasti->field_assign = (Func_ptr) 0;
ip->target_assign = subn->lasti;
+ } else if (ip->opcode == Op_subscript_lhs) {
+ (void) list_append(subn, instruction(Op_subscript_assign));
+ subn->lasti->assign_ctxt = Op_sub_builtin;
}
+
return subn;
} else {
@@ -6315,12 +6419,18 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
list_append(list_create(ip), instruction(Op_field_spec)));
}
- r->expr_count = count_expressions(&subn, FALSE);
+ r->expr_count = count_expressions(&subn, false);
return list_append(subn, r);
}
}
- r->builtin = tokentab[idx].ptr;
+#ifdef HAVE_MPFR
+ /* N.B.: If necessary, add special processing for alternate builtin, below */
+ if (do_mpfr && tokentab[idx].ptr2)
+ r->builtin = tokentab[idx].ptr2;
+ else
+#endif
+ r->builtin = tokentab[idx].ptr;
/* special case processing for a few builtins */
@@ -6344,15 +6454,24 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
arg = subn->nexti;
if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push)
arg->nexti->opcode = Op_push_arg; /* argument may be array */
+ } else if (r->builtin == do_div
+#ifdef HAVE_MPFR
+ || r->builtin == MPF(div)
+#endif
+ ) {
+ arg = subn->nexti->lasti->nexti->lasti->nexti; /* 3rd arg list */
+ ip = arg->lasti;
+ if (ip->opcode == Op_push)
+ ip->opcode = Op_push_array;
} else if (r->builtin == do_match) {
- static short warned = FALSE;
+ static bool warned = false;
arg = subn->nexti->lasti->nexti; /* 2nd arg list */
(void) mk_rexp(arg);
if (nexp == 3) { /* 3rd argument there */
if (do_lint && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn(_("match: third argument is a gawk extension"));
}
if (do_traditional) {
@@ -6406,10 +6525,10 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
ip->opcode = Op_push_array;
}
} else if (r->builtin == do_close) {
- static short warned = FALSE;
+ static bool warned = false;
if (nexp == 2) {
if (do_lint && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn(_("close: second argument is a gawk extension"));
}
if (do_traditional) {
@@ -6455,6 +6574,12 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
ip->opcode = Op_push_array;
}
}
+ else if (r->builtin == do_index) {
+ arg = subn->nexti->lasti->nexti; /* 2nd arg list */
+ ip = arg->lasti;
+ if (ip->opcode == Op_match_rec)
+ fatal(_("index: regexp constant as second argument is not allowed"));
+ }
#ifdef ARRAYDEBUG
else if (r->builtin == do_adump) {
ip = subn->nexti->lasti;
@@ -6464,7 +6589,7 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
#endif
if (subn != NULL) {
- r->expr_count = count_expressions(&subn, FALSE);
+ r->expr_count = count_expressions(&subn, false);
return list_append(subn, r);
}
@@ -6476,10 +6601,10 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
/* parms_shadow --- check if parameters shadow globals */
static int
-parms_shadow(INSTRUCTION *pc, int *shadow)
+parms_shadow(INSTRUCTION *pc, bool *shadow)
{
int pcount, i;
- int ret = FALSE;
+ bool ret = false;
NODE *func, *fp;
char *fname;
@@ -6489,7 +6614,7 @@ parms_shadow(INSTRUCTION *pc, int *shadow)
#if 0 /* can't happen, already exited if error ? */
if (fname == NULL || func == NULL) /* error earlier */
- return FALSE;
+ return false;
#endif
pcount = func->param_cnt;
@@ -6508,7 +6633,7 @@ parms_shadow(INSTRUCTION *pc, int *shadow)
warning(
_("function `%s': parameter `%s' shadows global variable"),
fname, fp[i].param);
- ret = TRUE;
+ ret = true;
}
}
@@ -6516,7 +6641,6 @@ parms_shadow(INSTRUCTION *pc, int *shadow)
return 0;
}
-
/* valinfo --- dump var info */
void
@@ -6525,16 +6649,30 @@ valinfo(NODE *n, Func_print print_func, FILE *fp)
if (n == Nnull_string)
print_func(fp, "uninitialized scalar\n");
else if (n->flags & STRING) {
- pp_string_fp(print_func, fp, n->stptr, n->stlen, '"', FALSE);
+ pp_string_fp(print_func, fp, n->stptr, n->stlen, '"', false);
print_func(fp, "\n");
- } else if (n->flags & NUMBER)
+ } else if (n->flags & NUMBER) {
+#ifdef HAVE_MPFR
+ if (is_mpg_float(n))
+ print_func(fp, "%s\n", mpg_fmt("%.17R*g", ROUND_MODE, n->mpg_numbr));
+ else if (is_mpg_integer(n))
+ print_func(fp, "%s\n", mpg_fmt("%Zd", n->mpg_i));
+ else
+#endif
print_func(fp, "%.17g\n", n->numbr);
- else if (n->flags & STRCUR) {
- pp_string_fp(print_func, fp, n->stptr, n->stlen, '"', FALSE);
+ } else if (n->flags & STRCUR) {
+ pp_string_fp(print_func, fp, n->stptr, n->stlen, '"', false);
print_func(fp, "\n");
- } else if (n->flags & NUMCUR)
+ } else if (n->flags & NUMCUR) {
+#ifdef HAVE_MPFR
+ if (is_mpg_float(n))
+ print_func(fp, "%s\n", mpg_fmt("%.17R*g", ROUND_MODE, n->mpg_numbr));
+ else if (is_mpg_integer(n))
+ print_func(fp, "%s\n", mpg_fmt("%Zd", n->mpg_i));
+ else
+#endif
print_func(fp, "%.17g\n", n->numbr);
- else
+ } else
print_func(fp, "?? flags %s\n", flags2str(n->flags));
}
@@ -6568,7 +6706,7 @@ void
dump_funcs()
{
NODE **funcs;
- funcs = function_list(TRUE);
+ funcs = function_list(true);
(void) foreach_func(funcs, (int (*)(INSTRUCTION *, void *)) pp_func, (void *) 0);
efree(funcs);
}
@@ -6580,13 +6718,13 @@ void
shadow_funcs()
{
static int calls = 0;
- int shadow = FALSE;
+ bool shadow = false;
NODE **funcs;
if (calls++ != 0)
fatal(_("shadow_funcs() called twice!"));
- funcs = function_list(TRUE);
+ funcs = function_list(true);
(void) foreach_func(funcs, (int (*)(INSTRUCTION *, void *)) parms_shadow, & shadow);
efree(funcs);
@@ -6608,7 +6746,7 @@ mk_function(INSTRUCTION *fi, INSTRUCTION *def)
thisfunc = fi->func_body;
assert(thisfunc != NULL);
- if (do_optimize > 1 && def->lasti->opcode == Op_pop) {
+ if (do_optimize && def->lasti->opcode == Op_pop) {
/* tail call which does not return any value. */
INSTRUCTION *t;
@@ -6616,9 +6754,16 @@ mk_function(INSTRUCTION *fi, INSTRUCTION *def)
for (t = def->nexti; t->nexti != def->lasti; t = t->nexti)
;
if (t->opcode == Op_func_call
- && STREQ(t->func_name, thisfunc->vname)
- )
- (t + 1)->tail_call = TRUE;
+ && strcmp(t->func_name, thisfunc->vname) == 0)
+ (t + 1)->tail_call = true;
+ }
+
+ /* add any pre-function comment to start of action for profile.c */
+
+ if (function_comment != NULL) {
+ function_comment->source_line = 0;
+ (void) list_prepend(def, function_comment);
+ function_comment = NULL;
}
/* add an implicit return at end;
@@ -6629,7 +6774,7 @@ mk_function(INSTRUCTION *fi, INSTRUCTION *def)
def->lasti->memory = dupnode(Nnull_string);
(void) list_append(def, instruction(Op_K_return));
- if (do_profiling)
+ if (do_pretty_print)
(void) list_prepend(def, instruction(Op_exec_count));
/* fi->opcode = Op_func */
@@ -6744,6 +6889,7 @@ static struct fdesc {
char *name;
short used;
short defined;
+ short extension;
struct fdesc *next;
} *ftable[HASHSIZE];
@@ -6759,15 +6905,9 @@ func_use(const char *name, enum defref how)
len = strlen(name);
ind = hash(name, len, HASHSIZE, NULL);
- 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;
- }
- }
+ for (fp = ftable[ind]; fp != NULL; fp = fp->next)
+ if (strcmp(fp->name, name) == 0)
+ goto update_value;
/* not in the table, fall through to allocate a new one */
@@ -6775,12 +6915,25 @@ func_use(const char *name, enum defref how)
memset(fp, '\0', sizeof(struct fdesc));
emalloc(fp->name, char *, len + 1, "func_use");
strcpy(fp->name, name);
+ fp->next = ftable[ind];
+ ftable[ind] = fp;
+
+update_value:
if (how == FUNC_DEFINE)
fp->defined++;
- else
+ else if (how == FUNC_EXT) {
+ fp->defined++;
+ fp->extension++;
+ } else
fp->used++;
- fp->next = ftable[ind];
- ftable[ind] = fp;
+}
+
+/* track_ext_func --- add an extension function to the table */
+
+void
+track_ext_func(const char *name)
+{
+ func_use(name, FUNC_EXT);
}
/* check_funcs --- verify functions that are called but not defined */
@@ -6798,17 +6951,18 @@ check_funcs()
for (fp = ftable[i]; fp != NULL; fp = fp->next) {
#ifdef REALLYMEAN
/* making this the default breaks old code. sigh. */
- if (fp->defined == 0) {
+ if (fp->defined == 0 && ! fp->extension) {
error(
_("function `%s' called but never defined"), fp->name);
errcount++;
}
#else
- if (do_lint && fp->defined == 0)
+ if (do_lint && fp->defined == 0 && ! fp->extension)
lintwarn(
_("function `%s' called but never defined"), fp->name);
#endif
- if (do_lint && fp->used == 0) {
+
+ if (do_lint && fp->used == 0 && ! fp->extension) {
lintwarn(_("function `%s' defined but never called directly"),
fp->name);
}
@@ -6847,37 +7001,6 @@ param_sanity(INSTRUCTION *arglist)
}
}
-/* deferred variables --- 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 *
@@ -6891,20 +7014,7 @@ variable(int location, char *name, NODETYPE type)
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.
- */
- return install_symbol(name, type);
- }
- if (STREQ(name, dv->name)) {
- r = (*dv->load_func)();
- break;
- }
- }
+ return install_symbol(name, type);
}
efree(name);
return r;
@@ -6923,7 +7033,7 @@ make_regnode(int type, NODE *exp)
n->re_cnt = 1;
if (type == Node_regex) {
- n->re_reg = make_regexp(exp->stptr, exp->stlen, FALSE, TRUE, FALSE);
+ n->re_reg = make_regexp(exp->stptr, exp->stlen, false, true, false);
if (n->re_reg == NULL) {
freenode(n);
return NULL;
@@ -6955,6 +7065,7 @@ mk_rexp(INSTRUCTION *list)
return ip->memory;
}
+#ifndef NO_LINT
/* isnoeffect --- when used as a statement, has no side effects */
static int
@@ -6990,13 +7101,15 @@ isnoeffect(OPCODE type)
case Op_match_rec:
case Op_not:
case Op_in_array:
- return TRUE;
+ return true;
default:
break; /* keeps gcc -Wall happy */
}
- return FALSE;
+ return false;
}
+#endif /* NO_LINT */
+
/* make_assignable --- make this operand an assignable one if posiible */
@@ -7019,6 +7132,14 @@ make_assignable(INSTRUCTION *ip)
return NULL;
}
+/* stopme --- for debugging */
+
+NODE *
+stopme(int nargs ATTRIBUTE_UNUSED)
+{
+ return make_number(0.0);
+}
+
/* dumpintlstr --- write out an initial .po file entry for the string */
static void
@@ -7036,7 +7157,7 @@ dumpintlstr(const char *str, size_t len)
}
printf("msgid ");
- pp_string_fp(fprintf, stdout, str, len, '"', TRUE);
+ pp_string_fp(fprintf, stdout, str, len, '"', true);
putchar('\n');
printf("msgstr \"\"\n\n");
fflush(stdout);
@@ -7059,10 +7180,10 @@ dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2)
}
printf("msgid ");
- pp_string_fp(fprintf, stdout, str1, len1, '"', TRUE);
+ pp_string_fp(fprintf, stdout, str1, len1, '"', true);
putchar('\n');
printf("msgid_plural ");
- pp_string_fp(fprintf, stdout, str2, len2, '"', TRUE);
+ pp_string_fp(fprintf, stdout, str2, len2, '"', true);
putchar('\n');
printf("msgstr[0] \"\"\nmsgstr[1] \"\"\n\n");
fflush(stdout);
@@ -7080,13 +7201,13 @@ mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION *op)
if (s2->lasti == ip2 && ip2->opcode == Op_push_i) {
/* do any numeric constant folding */
ip1 = s1->nexti;
- if (do_optimize > 1
+ if (do_optimize
&& ip1 == s1->lasti && ip1->opcode == Op_push_i
- && (ip1->memory->flags & (STRCUR|STRING)) == 0
- && (ip2->memory->flags & (STRCUR|STRING)) == 0
+ && (ip1->memory->flags & (MPFN|MPZN|STRCUR|STRING)) == 0
+ && (ip2->memory->flags & (MPFN|MPZN|STRCUR|STRING)) == 0
) {
NODE *n1 = ip1->memory, *n2 = ip2->memory;
- res = force_number(n1);
+ res = force_number(n1)->numbr;
(void) force_number(n2);
switch (op->opcode) {
case Op_times:
@@ -7254,7 +7375,7 @@ mk_condition(INSTRUCTION *cond, INSTRUCTION *ifp, INSTRUCTION *true_branch,
if (false_branch == NULL) {
false_branch = list_create(instruction(Op_no_op));
if (elsep != NULL) { /* else { } */
- if (do_profiling)
+ if (do_pretty_print)
(void) list_prepend(false_branch, elsep);
else
bcfree(elsep);
@@ -7265,7 +7386,7 @@ mk_condition(INSTRUCTION *cond, INSTRUCTION *ifp, INSTRUCTION *true_branch,
/* avoid a series of no_op's: if .. else if .. else if .. */
if (false_branch->lasti->opcode != Op_no_op)
(void) list_append(false_branch, instruction(Op_no_op));
- if (do_profiling) {
+ if (do_pretty_print) {
(void) list_prepend(false_branch, elsep);
false_branch->nexti->branch_end = false_branch->lasti;
(void) list_prepend(false_branch, instruction(Op_exec_count));
@@ -7280,7 +7401,7 @@ mk_condition(INSTRUCTION *cond, INSTRUCTION *ifp, INSTRUCTION *true_branch,
ip = list_append(cond, instruction(Op_jmp_false));
ip->lasti->target_jmp = false_branch->nexti->nexti;
- if (do_profiling) {
+ if (do_pretty_print) {
(void) list_prepend(ip, ifp);
(void) list_append(ip, instruction(Op_exec_count));
ip->nexti->branch_if = ip->lasti;
@@ -7342,13 +7463,17 @@ append_rule(INSTRUCTION *pattern, INSTRUCTION *action)
if (rule != Rule) {
rp = pattern;
- if (do_profiling)
+ if (do_pretty_print)
(void) list_append(action, instruction(Op_no_op));
(rp + 1)->firsti = action->nexti;
(rp + 1)->lasti = action->lasti;
(rp + 2)->first_line = pattern->source_line;
(rp + 2)->last_line = lastline;
- ip = list_prepend(action, rp);
+ if (block_comment != NULL) {
+ ip = list_prepend(list_prepend(action, block_comment), rp);
+ block_comment = NULL;
+ } else
+ ip = list_prepend(action, rp);
} else {
rp = bcalloc(Op_rule, 3, 0);
@@ -7358,7 +7483,7 @@ append_rule(INSTRUCTION *pattern, INSTRUCTION *action)
if (pattern == NULL) {
/* assert(action != NULL); */
- if (do_profiling)
+ if (do_pretty_print)
(void) list_prepend(action, instruction(Op_exec_count));
(rp + 1)->firsti = action->nexti;
(rp + 1)->lasti = tp;
@@ -7374,12 +7499,12 @@ append_rule(INSTRUCTION *pattern, INSTRUCTION *action)
if (action == NULL) {
(rp + 2)->last_line = find_line(pattern, LAST_LINE);
action = list_create(instruction(Op_K_print_rec));
- if (do_profiling)
+ if (do_pretty_print)
(void) list_prepend(action, instruction(Op_exec_count));
} else
(rp + 2)->last_line = lastline;
- if (do_profiling) {
+ if (do_pretty_print) {
(void) list_prepend(pattern, instruction(Op_exec_count));
(void) list_prepend(action, instruction(Op_exec_count));
}
@@ -7390,7 +7515,6 @@ append_rule(INSTRUCTION *pattern, INSTRUCTION *action)
action),
tp);
}
-
}
list_append(rule_list, rp + 1);
@@ -7423,8 +7547,13 @@ mk_assignment(INSTRUCTION *lhs, INSTRUCTION *rhs, INSTRUCTION *op)
case Op_push_array:
tp->opcode = Op_push_lhs;
break;
+ case Op_field_assign:
+ yyerror(_("cannot assign a value to the result of a field post-increment expression"));
+ break;
default:
- cant_happen();
+ yyerror(_("invalid target of assignment (opcode %s)"),
+ opcode2str(tp->opcode));
+ break;
}
tp->do_reference = (op->opcode != Op_assign); /* check for uninitialized reference */
@@ -7440,7 +7569,7 @@ mk_assignment(INSTRUCTION *lhs, INSTRUCTION *rhs, INSTRUCTION *op)
&& tp->memory->type == Node_var
&& tp->memory->var_assign
) {
- tp->do_reference = FALSE; /* no uninitialized reference checking
+ tp->do_reference = false; /* no uninitialized reference checking
* for a special variable.
*/
(void) list_append(ip, instruction(Op_var_assign));
@@ -7449,6 +7578,8 @@ mk_assignment(INSTRUCTION *lhs, INSTRUCTION *rhs, INSTRUCTION *op)
(void) list_append(ip, instruction(Op_field_assign));
ip->lasti->field_assign = (Func_ptr) 0;
tp->target_assign = ip->lasti;
+ } else if (tp->opcode == Op_subscript_lhs) {
+ (void) list_append(ip, instruction(Op_subscript_assign));
}
return ip;
@@ -7492,10 +7623,8 @@ optimize_assignment(INSTRUCTION *exp)
i2 = NULL;
i1 = exp->lasti;
- if ( ! do_optimize
- || ( i1->opcode != Op_assign
- && i1->opcode != Op_field_assign)
- )
+ if ( i1->opcode != Op_assign
+ && i1->opcode != Op_field_assign)
return list_append(exp, instruction(Op_pop));
for (i2 = exp->nexti; i2 != i1; i2 = i2->nexti) {
@@ -7658,7 +7787,11 @@ mk_getline(INSTRUCTION *op, INSTRUCTION *var, INSTRUCTION *redir, int redirtype)
asgn->assign_ctxt = op->opcode;
asgn->field_assign = (Func_ptr) 0; /* determined at run time */
tp->target_assign = asgn;
+ } else if (tp->opcode == Op_subscript_lhs) {
+ asgn = instruction(Op_subscript_assign);
+ asgn->assign_ctxt = op->opcode;
}
+
if (redir != NULL) {
ip = list_merge(redir, var);
(void) list_append(ip, op);
@@ -7669,7 +7802,7 @@ mk_getline(INSTRUCTION *op, INSTRUCTION *var, INSTRUCTION *redir, int redirtype)
else
ip = list_create(op);
op->into_var = (var != NULL);
- op->redir_type = (redir != NULL) ? redirtype : 0;
+ op->redir_type = (redir != NULL) ? redirtype : redirect_none;
return (asgn == NULL ? ip : list_append(ip, asgn));
}
@@ -7720,7 +7853,7 @@ mk_for_loop(INSTRUCTION *forp, INSTRUCTION *init, INSTRUCTION *cond,
if (init != NULL)
ip = list_merge(init, ip);
- if (do_profiling) {
+ if (do_pretty_print) {
(void) list_append(ip, instruction(Op_exec_count));
(forp + 1)->forloop_cond = pp_cond;
(forp + 1)->forloop_body = ip->lasti;
@@ -7742,7 +7875,7 @@ mk_for_loop(INSTRUCTION *forp, INSTRUCTION *init, INSTRUCTION *cond,
ret = list_append(ip, tbreak);
fix_break_continue(ret, tbreak, tcont);
- if (do_profiling) {
+ if (do_pretty_print) {
forp->target_break = tbreak;
forp->target_continue = tcont;
ret = list_prepend(ret, forp);
@@ -7843,7 +7976,7 @@ mk_expression_list(INSTRUCTION *list, INSTRUCTION *s1)
*/
static int
-count_expressions(INSTRUCTION **list, int isarg)
+count_expressions(INSTRUCTION **list, bool isarg)
{
INSTRUCTION *expr;
INSTRUCTION *r = NULL;
@@ -7959,13 +8092,13 @@ check_special(const char *name)
int low, high, mid;
int i;
#if 'a' == 0x81 /* it's EBCDIC */
- static int did_sort = FALSE;
+ static bool did_sort = false;
if (! did_sort) {
qsort((void *) tokentab,
sizeof(tokentab) / sizeof(tokentab[0]),
sizeof(tokentab[0]), tokcompare);
- did_sort = TRUE;
+ did_sort = true;
}
#endif
@@ -8038,3 +8171,94 @@ one_line_close(int fd)
}
+/* lookup_builtin --- find a builtin function or return NULL */
+
+builtin_func_t
+lookup_builtin(const char *name)
+{
+ int mid = check_special(name);
+
+ if (mid == -1 || tokentab[mid].class != LEX_BUILTIN)
+ return NULL;
+#ifdef HAVE_MPFR
+ if (do_mpfr)
+ return tokentab[mid].ptr2;
+#endif
+
+ return tokentab[mid].ptr;
+}
+
+/* install_builtins --- add built-in functions to FUNCTAB */
+
+void
+install_builtins(void)
+{
+ int i, j;
+
+ j = sizeof(tokentab) / sizeof(tokentab[0]);
+ for (i = 0; i < j; i++) {
+ if ( tokentab[i].class == LEX_BUILTIN
+ && (tokentab[i].flags & DEBUG_USE) == 0) {
+ (void) install_symbol(tokentab[i].operator, Node_builtin_func);
+ }
+ }
+}
+
+/*
+ * 9/2014: Gawk cannot use <ctype.h> isalpha or isalnum when
+ * parsing the program since that can let through non-English
+ * letters. So, we supply our own. !@#$%^&*()-ing locales!
+ */
+
+/* is_alpha --- return true if c is an English letter */
+
+/*
+ * The scene of the murder was grisly to look upon. When the inspector
+ * arrived, the sergeant turned to him and said, "Another programmer stabbed
+ * in the back. He never knew what happened."
+ *
+ * The inspector replied, "Looks like the MO of isalpha, and his even meaner
+ * big brother, isalnum. The Locale brothers." The sergeant merely
+ * shuddered in horror.
+ */
+
+bool
+is_alpha(int c)
+{
+#ifdef I_DONT_KNOW_WHAT_IM_DOING
+ return isalpha(c);
+#else /* ! I_DONT_KNOW_WHAT_IM_DOING */
+ switch (c) {
+ 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':
+ 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':
+ return true;
+ }
+ return false;
+#endif /* ! I_DONT_KNOW_WHAT_IM_DOING */
+}
+
+/* is_alnum --- return true for alphanumeric, English only letters */
+
+bool
+is_alnum(int c)
+{
+ /* digit test is good for EBCDIC too. so there. */
+ return (is_alpha(c) || ('0' <= c && c <= '9'));
+}
+
+
+/* is_identchar --- return true if c can be in an identifier */
+
+bool
+is_identchar(int c)
+{
+ return (is_alnum(c) || c == '_');
+}
diff --git a/awkgram.y b/awkgram.y
index 08eb9904..5e3bade9 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-2011 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-2015 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -46,12 +46,15 @@ static char **check_params(char *fname, int pcount, INSTRUCTION *list);
static int install_function(char *fname, INSTRUCTION *fi, INSTRUCTION *plist);
static NODE *mk_rexp(INSTRUCTION *exp);
static void param_sanity(INSTRUCTION *arglist);
-static int parms_shadow(INSTRUCTION *pc, int *shadow);
+static int parms_shadow(INSTRUCTION *pc, bool *shadow);
+#ifndef NO_LINT
static int isnoeffect(OPCODE type);
+#endif
static INSTRUCTION *make_assignable(INSTRUCTION *ip);
static void dumpintlstr(const char *str, size_t len);
static void dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2);
static int include_source(INSTRUCTION *file);
+static int load_library(INSTRUCTION *file);
static void next_sourcefile(void);
static char *tokexpand(void);
@@ -71,19 +74,21 @@ static INSTRUCTION *mk_boolean(INSTRUCTION *left, INSTRUCTION *right, INSTRUCTIO
static INSTRUCTION *mk_assignment(INSTRUCTION *lhs, INSTRUCTION *rhs, INSTRUCTION *op);
static INSTRUCTION *mk_getline(INSTRUCTION *op, INSTRUCTION *opt_var, INSTRUCTION *redir, int redirtype);
static NODE *make_regnode(int type, NODE *exp);
-static int count_expressions(INSTRUCTION **list, int isarg);
+static int count_expressions(INSTRUCTION **list, bool isarg);
static INSTRUCTION *optimize_assignment(INSTRUCTION *exp);
static void add_lint(INSTRUCTION *list, LINTTYPE linttype);
-enum defref { FUNC_DEFINE, FUNC_USE };
+enum defref { FUNC_DEFINE, FUNC_USE, FUNC_EXT };
static void func_use(const char *name, enum defref how);
static void check_funcs(void);
static ssize_t read_one_line(int fd, void *buffer, size_t count);
static int one_line_close(int fd);
+static void split_comment(void);
+static void check_comment(void);
-static int want_source = FALSE;
-static int want_regexp; /* lexical scanning kludge */
+static bool want_source = false;
+static bool want_regexp = false; /* lexical scanning kludge */
static char *in_function; /* parsing kludge */
static int rule = 0;
@@ -96,25 +101,24 @@ const char *const ruletab[] = {
"ENDFILE",
};
-static int in_print = FALSE; /* lexical scanning kludge for print */
+static bool in_print = false; /* lexical scanning kludge for print */
static int in_parens = 0; /* lexical scanning kludge for print */
static int sub_counter = 0; /* array dimension counter for use in delete */
static char *lexptr = NULL; /* 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 int lexeof; /* seen EOF for current source? */
+static bool lexeof; /* seen EOF for current source? */
static char *thisline = NULL;
static int in_braces = 0; /* count braces for firstline, lastline in an 'action' */
static int lastline = 0;
static int firstline = 0;
static SRCFILE *sourcefile = NULL; /* current program source */
static int lasttok = 0;
-static int eof_warned = FALSE; /* GLOBAL: want warning for each file */
+static bool eof_warned = false; /* GLOBAL: want warning for each file */
static int break_allowed; /* kludge for break */
static int continue_allowed; /* kludge for continue */
-
#define END_FILE -1000
#define END_SRC -2000
@@ -129,6 +133,7 @@ extern int sourceline;
extern SRCFILE *srcfiles;
extern INSTRUCTION *rule_list;
extern int max_args;
+extern NODE **args_array;
static INSTRUCTION *rule_block[sizeof(ruletab)];
@@ -139,6 +144,14 @@ static INSTRUCTION *ip_end;
static INSTRUCTION *ip_endfile;
static INSTRUCTION *ip_beginfile;
+static INSTRUCTION *comment = NULL;
+static INSTRUCTION *program_comment = NULL;
+static INSTRUCTION *function_comment = NULL;
+static INSTRUCTION *block_comment = NULL;
+
+static bool func_first = true;
+static bool first_rule = true;
+
static inline INSTRUCTION *list_create(INSTRUCTION *x);
static inline INSTRUCTION *list_append(INSTRUCTION *l, INSTRUCTION *x);
static inline INSTRUCTION *list_prepend(INSTRUCTION *l, INSTRUCTION *x);
@@ -163,7 +176,7 @@ extern double fmod(double x, double y);
%token LEX_AND LEX_OR INCREMENT DECREMENT
%token LEX_BUILTIN LEX_LENGTH
%token LEX_EOF
-%token LEX_INCLUDE LEX_EVAL
+%token LEX_INCLUDE LEX_EVAL LEX_LOAD
%token NEWLINE
/* Lowest to highest */
@@ -215,6 +228,7 @@ rule
: pattern action
{
(void) append_rule($1, $2);
+ first_rule = false;
}
| pattern statement_term
{
@@ -235,7 +249,12 @@ rule
}
| '@' LEX_INCLUDE source statement_term
{
- want_source = FALSE;
+ want_source = false;
+ yyerrok;
+ }
+ | '@' LEX_LOAD library statement_term
+ {
+ want_source = false;
yyerrok;
}
;
@@ -255,11 +274,41 @@ source
{ $$ = NULL; }
;
+library
+ : FILENAME
+ {
+ if (load_library($1) < 0)
+ YYABORT;
+ efree($1->lextok);
+ bcfree($1);
+ $$ = NULL;
+ }
+ | FILENAME error
+ { $$ = NULL; }
+ | error
+ { $$ = NULL; }
+ ;
+
pattern
: /* empty */
- { $$ = NULL; rule = Rule; }
+ {
+ rule = Rule;
+ if (comment != NULL) {
+ $$ = list_create(comment);
+ comment = NULL;
+ } else
+ $$ = NULL;
+ }
| exp
- { $$ = $1; rule = Rule; }
+ {
+ rule = Rule;
+ if (comment != NULL) {
+ $$ = list_prepend($1, comment);
+ comment = NULL;
+ } else
+ $$ = $1;
+ }
+
| exp ',' opt_nls exp
{
INSTRUCTION *tp;
@@ -268,8 +317,8 @@ pattern
add_lint($4, LINT_assign_in_cond);
tp = instruction(Op_no_op);
- list_prepend($1, bcalloc(Op_line_range, !!do_profiling + 1, 0));
- $1->nexti->triggered = FALSE;
+ list_prepend($1, bcalloc(Op_line_range, !!do_pretty_print + 1, 0));
+ $1->nexti->triggered = false;
$1->nexti->target_jmp = $4->nexti;
list_append($1, instruction(Op_cond_pair));
@@ -279,45 +328,59 @@ pattern
list_append($4, instruction(Op_cond_pair));
$4->lasti->line_range = $1->nexti;
$4->lasti->target_jmp = tp;
- if (do_profiling) {
+ if (do_pretty_print) {
($1->nexti + 1)->condpair_left = $1->lasti;
($1->nexti + 1)->condpair_right = $4->lasti;
}
- $$ = list_append(list_merge($1, $4), tp);
+ if (comment != NULL) {
+ $$ = list_append(list_merge(list_prepend($1, comment), $4), tp);
+ comment = NULL;
+ } else
+ $$ = list_append(list_merge($1, $4), tp);
rule = Rule;
}
| LEX_BEGIN
{
static int begin_seen = 0;
+
+ func_first = false;
if (do_lint_old && ++begin_seen == 2)
warning_ln($1->source_line,
_("old awk does not support multiple `BEGIN' or `END' rules"));
$1->in_rule = rule = BEGIN;
$1->source_file = source;
+ check_comment();
$$ = $1;
}
| LEX_END
{
static int end_seen = 0;
+
+ func_first = false;
if (do_lint_old && ++end_seen == 2)
warning_ln($1->source_line,
_("old awk does not support multiple `BEGIN' or `END' rules"));
$1->in_rule = rule = END;
$1->source_file = source;
+ check_comment();
$$ = $1;
}
| LEX_BEGINFILE
{
+ func_first = false;
$1->in_rule = rule = BEGINFILE;
$1->source_file = source;
+ check_comment();
$$ = $1;
}
| LEX_ENDFILE
{
+ func_first = false;
$1->in_rule = rule = ENDFILE;
$1->source_file = source;
+ check_comment();
$$ = $1;
}
;
@@ -325,10 +388,12 @@ pattern
action
: l_brace statements r_brace opt_semi opt_nls
{
+ INSTRUCTION *ip;
if ($2 == NULL)
- $$ = list_create(instruction(Op_no_op));
+ ip = list_create(instruction(Op_no_op));
else
- $$ = $2;
+ ip = $2;
+ $$ = ip;
}
;
@@ -355,6 +420,22 @@ lex_builtin
function_prologue
: LEX_FUNCTION func_name '(' opt_param_list r_paren opt_nls
{
+ /*
+ * treat any comments between BOF and the first function
+ * definition (with no intervening BEGIN etc block) as
+ * program comments. Special kludge: iff there are more
+ * than one such comments, treat the last as a function
+ * comment.
+ */
+ if (comment != NULL && func_first
+ && strstr(comment->memory->stptr, "\n\n") != NULL)
+ split_comment();
+ /* save any other pre-function comment as function comment */
+ if (comment != NULL) {
+ function_comment = comment;
+ comment = NULL;
+ }
+ func_first = false;
$1->source_file = source;
if (install_function($2->lextok, $1, $4) < 0)
YYABORT;
@@ -372,7 +453,7 @@ regexp
* is a regexp so it should read up to the closing slash.
*/
: a_slash
- { ++want_regexp; }
+ { want_regexp = true; }
REGEXP /* The terminating '/' is consumed by yylex(). */
{
NODE *n, *exp;
@@ -386,7 +467,7 @@ regexp
if (len == 0)
lintwarn_ln($3->source_line,
_("regexp constant `//' looks like a C++ comment, but is not"));
- else if ((re)[0] == '*' && (re)[len-1] == '*')
+ else if (re[0] == '*' && re[len-1] == '*')
/* possible C comment */
lintwarn_ln($3->source_line,
_("regexp constant `/%s/' looks like a C comment, but is not"), re);
@@ -412,19 +493,39 @@ a_slash
statements
: /* empty */
- { $$ = NULL; }
+ {
+ if (comment != NULL) {
+ $$ = list_create(comment);
+ comment = NULL;
+ } else $$ = NULL;
+ }
| statements statement
{
- if ($2 == NULL)
- $$ = $1;
- else {
+ if ($2 == NULL) {
+ if (comment == NULL)
+ $$ = $1;
+ else {
+ $$ = list_append($1, comment);
+ comment = NULL;
+ }
+ } else {
add_lint($2, LINT_no_effect);
- if ($1 == NULL)
- $$ = $2;
- else
+ if ($1 == NULL) {
+ if (comment == NULL)
+ $$ = $2;
+ else {
+ $$ = list_append($2, comment);
+ comment = NULL;
+ }
+ } else {
+ if (comment != NULL) {
+ list_append($2, comment);
+ comment = NULL;
+ }
$$ = list_merge($1, $2);
+ }
}
- yyerrok;
+ yyerrok;
}
| statements error
{ $$ = NULL; }
@@ -442,7 +543,7 @@ statement
{ $$ = $2; }
| if_statement
{
- if (do_profiling)
+ if (do_pretty_print)
$$ = list_prepend($1, instruction(Op_exec_count));
else
$$ = $1;
@@ -468,7 +569,7 @@ statement
} /* else
curr = NULL; */
- for(; curr != NULL; curr = nextc) {
+ for (; curr != NULL; curr = nextc) {
INSTRUCTION *caseexp = curr->case_exp;
INSTRUCTION *casestmt = curr->case_stmt;
@@ -493,7 +594,7 @@ statement
case_values[case_count++] = caseval;
} else {
/* match a constant regex against switch expression. */
- (curr + 1)->match_exp = TRUE;
+ (curr + 1)->match_exp = true;
}
curr->stmt_start = casestmt->nexti;
curr->stmt_end = casestmt->lasti;
@@ -506,7 +607,7 @@ statement
else
dflt->target_jmp = casestmt->nexti;
- if (do_profiling) {
+ if (do_pretty_print) {
curr->stmt_start = casestmt->nexti;
curr->stmt_end = casestmt->lasti;
(void) list_prepend(cexp, curr);
@@ -521,7 +622,7 @@ statement
efree(case_values);
ip = $3;
- if (do_profiling) {
+ if (do_pretty_print) {
(void) list_prepend(ip, $1);
(void) list_prepend(ip, instruction(Op_exec_count));
$1->target_break = tbreak;
@@ -560,7 +661,7 @@ statement
ip = list_append($3, instruction(Op_jmp_false));
ip->lasti->target_jmp = tbreak;
- if (do_profiling) {
+ if (do_pretty_print) {
(void) list_append(ip, instruction(Op_exec_count));
$1->target_break = tbreak;
$1->target_continue = tcont;
@@ -602,7 +703,7 @@ statement
ip = list_merge($3, $6);
else
ip = list_prepend($6, instruction(Op_no_op));
- if (do_profiling)
+ if (do_pretty_print)
(void) list_prepend(ip, instruction(Op_exec_count));
(void) list_append(ip, instruction(Op_jmp_true));
ip->lasti->target_jmp = ip->nexti;
@@ -612,14 +713,14 @@ statement
continue_allowed--;
fix_break_continue(ip, tbreak, tcont);
- if (do_profiling) {
+ if (do_pretty_print) {
$1->target_break = tbreak;
$1->target_continue = tcont;
($1 + 1)->doloop_cond = tcont;
$$ = list_prepend(ip, $1);
bcfree($4);
} /* else
- $1 and $4 are NULLs */
+ $1 and $4 are NULLs */
}
| LEX_FOR '(' NAME LEX_IN simple_variable r_paren opt_nls statement
{
@@ -672,16 +773,16 @@ statement
} else {
INSTRUCTION *tbreak, *tcont;
- /* [ Op_push_array a ]
- * [ Op_arrayfor_init | ib ]
- * ic:[ Op_arrayfor_incr | ib ]
- * [ Op_var_assign if any ]
- *
- * body
- *
- * [Op_jmp | ic ]
- * ib:[Op_arrayfor_final ]
- */
+ /* [ Op_push_array a ]
+ * [ Op_arrayfor_init | ib ]
+ * ic:[ Op_arrayfor_incr | ib ]
+ * [ Op_var_assign if any ]
+ *
+ * body
+ *
+ * [Op_jmp | ic ]
+ * ib:[Op_arrayfor_final ]
+ */
regular_loop:
ip = $5;
ip->nexti->opcode = Op_push_array;
@@ -695,7 +796,7 @@ regular_loop:
$3->target_jmp = tbreak;
(void) list_append(ip, $3);
- if (do_profiling) {
+ if (do_pretty_print) {
$1->opcode = Op_K_arrayfor;
$1->target_continue = tcont;
$1->target_break = tbreak;
@@ -716,7 +817,7 @@ regular_loop:
ip->lasti->assign_var = $4->array_var->var_assign;
}
- if (do_profiling) {
+ if (do_pretty_print) {
(void) list_append(ip, instruction(Op_exec_count));
($1 + 1)->forloop_cond = $4;
($1 + 1)->forloop_body = ip->lasti;
@@ -750,7 +851,7 @@ regular_loop:
}
| non_compound_stmt
{
- if (do_profiling)
+ if (do_pretty_print)
$$ = list_prepend($1, instruction(Op_exec_count));
else
$$ = $1;
@@ -787,10 +888,6 @@ non_compound_stmt
}
| LEX_NEXTFILE statement_term
{
- if (do_traditional)
- error_ln($1->source_line,
- _("`nextfile' is a gawk extension"));
-
/* if inside function (rule = 0), resolve context at run-time */
if (rule == BEGIN || rule == END || rule == ENDFILE)
error_ln($1->source_line,
@@ -825,15 +922,15 @@ non_compound_stmt
(void) list_prepend($$, instruction(Op_push_i));
$$->nexti->memory = dupnode(Nnull_string);
} else {
- if (do_optimize > 1
+ if (do_optimize
&& $3->lasti->opcode == Op_func_call
- && STREQ($3->lasti->func_name, in_function)
+ && strcmp($3->lasti->func_name, in_function) == 0
) {
/* Do tail recursion optimization. Tail
* call without a return value is recognized
* in mk_function().
*/
- ($3->lasti + 1)->tail_call = TRUE;
+ ($3->lasti + 1)->tail_call = true;
}
$$ = list_append($3, $1);
@@ -851,7 +948,7 @@ non_compound_stmt
* We don't bother to document it though. So there.
*/
simple_stmt
- : print { in_print = TRUE; in_parens = 0; } print_expression_list output_redir
+ : print { in_print = true; in_parens = 0; } print_expression_list output_redir
{
/*
* Optimization: plain `print' has no expression list, so $3 is null.
@@ -864,11 +961,10 @@ simple_stmt
|| ($3->lasti->opcode == Op_field_spec
&& $3->nexti->nexti->nexti == $3->lasti
&& $3->nexti->nexti->opcode == Op_push_i
- && $3->nexti->nexti->memory->type == Node_val
- && $3->nexti->nexti->memory->numbr == 0.0)
+ && $3->nexti->nexti->memory->type == Node_val)
)
) {
- static short warned = FALSE;
+ static bool warned = false;
/* -----------------
* output_redir
* [ redirect exp ]
@@ -879,14 +975,19 @@ simple_stmt
*/
if ($3 != NULL) {
- bcfree($3->lasti); /* Op_field_spec */
- unref($3->nexti->nexti->memory); /* Node_val */
+ NODE *n = $3->nexti->nexti->memory;
+
+ if (! iszero(n))
+ goto regular_print;
+
+ bcfree($3->lasti); /* Op_field_spec */
+ unref(n); /* Node_val */
bcfree($3->nexti->nexti); /* Op_push_i */
- bcfree($3->nexti); /* Op_list */
- bcfree($3); /* Op_list */
+ bcfree($3->nexti); /* Op_list */
+ bcfree($3); /* Op_list */
} else {
if (do_lint && (rule == BEGIN || rule == END) && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn_ln($1->source_line,
_("plain `print' in BEGIN or END rule should probably be `print \"\"'"));
}
@@ -895,7 +996,7 @@ simple_stmt
$1->expr_count = 0;
$1->opcode = Op_K_print_rec;
if ($4 == NULL) { /* no redircetion */
- $1->redir_type = 0;
+ $1->redir_type = redirect_none;
$$ = list_create($1);
} else {
INSTRUCTION *ip;
@@ -915,16 +1016,16 @@ simple_stmt
* [$1 | NULL | redir_type | expr_count]
*
*/
-
+regular_print:
if ($4 == NULL) { /* no redirection */
if ($3 == NULL) { /* printf without arg */
$1->expr_count = 0;
- $1->redir_type = 0;
+ $1->redir_type = redirect_none;
$$ = list_create($1);
} else {
INSTRUCTION *t = $3;
- $1->expr_count = count_expressions(&t, FALSE);
- $1->redir_type = 0;
+ $1->expr_count = count_expressions(&t, false);
+ $1->redir_type = redirect_none;
$$ = list_append(t, $1);
}
} else {
@@ -938,7 +1039,7 @@ simple_stmt
$$ = list_append($4, $1);
} else {
INSTRUCTION *t = $3;
- $1->expr_count = count_expressions(&t, FALSE);
+ $1->expr_count = count_expressions(&t, false);
$$ = list_append(list_merge($4, t), $1);
}
}
@@ -952,17 +1053,25 @@ simple_stmt
$2->opcode = Op_push_array;
$2->memory = variable($2->source_line, arr, Node_var_new);
- if ($4 == NULL) {
- static short warned = FALSE;
+ if (! do_posix && ! do_traditional) {
+ if ($2->memory == symbol_table)
+ fatal(_("`delete' is not allowed with SYMTAB"));
+ else if ($2->memory == func_table)
+ fatal(_("`delete' is not allowed with FUNCTAB"));
+ }
- if (do_lint && ! warned) {
- warned = TRUE;
- lintwarn_ln($1->source_line,
- _("`delete array' is a gawk extension"));
- }
- if (do_traditional)
- error_ln($1->source_line,
- _("`delete array' is a gawk extension"));
+ if ($4 == NULL) {
+ /*
+ * As of September 2012, POSIX has added support
+ * for `delete array'. See:
+ * http://austingroupbugs.net/view.php?id=544
+ *
+ * Thanks to Nathan Weeks for the initiative.
+ *
+ * Thus we no longer warn or check do_posix.
+ * Also, since BWK awk supports it, we don't have to
+ * check do_traditional either.
+ */
$1->expr_count = 0;
$$ = list_append(list_create($2), $1);
} else {
@@ -976,22 +1085,29 @@ simple_stmt
* should always be done.
*/
{
- static short warned = FALSE;
+ static bool warned = false;
char *arr = $3->lextok;
if (do_lint && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn_ln($1->source_line,
_("`delete(array)' is a non-portable tawk extension"));
}
if (do_traditional) {
error_ln($1->source_line,
- _("`delete array' is a gawk extension"));
+ _("`delete(array)' is a non-portable tawk extension"));
}
$3->memory = variable($3->source_line, arr, Node_var_new);
$3->opcode = Op_push_array;
$1->expr_count = 0;
$$ = list_append(list_create($3), $1);
+
+ if (! do_posix && ! do_traditional) {
+ if ($3->memory == symbol_table)
+ fatal(_("`delete' is not allowed with SYMTAB"));
+ else if ($3->memory == func_table)
+ fatal(_("`delete' is not allowed with FUNCTAB"));
+ }
}
| exp
{ $$ = optimize_assignment($1); }
@@ -1024,7 +1140,7 @@ case_statement
INSTRUCTION *casestmt = $5;
if ($5 == NULL)
casestmt = list_create(instruction(Op_no_op));
- if (do_profiling)
+ if (do_pretty_print)
(void) list_prepend(casestmt, instruction(Op_exec_count));
$1->case_exp = $2;
$1->case_stmt = casestmt;
@@ -1036,7 +1152,7 @@ case_statement
INSTRUCTION *casestmt = $4;
if ($4 == NULL)
casestmt = list_create(instruction(Op_no_op));
- if (do_profiling)
+ if (do_pretty_print)
(void) list_prepend(casestmt, instruction(Op_exec_count));
bcfree($2);
$1->case_stmt = casestmt;
@@ -1049,7 +1165,9 @@ case_value
{ $$ = $1; }
| '-' YNUMBER %prec UNARY
{
- $2->memory->numbr = -(force_number($2->memory));
+ NODE *n = $2->memory;
+ (void) force_number(n);
+ negate_num(n);
bcfree($1);
$$ = $2;
}
@@ -1089,11 +1207,11 @@ print_expression_list
output_redir
: /* empty */
{
- in_print = FALSE;
+ in_print = false;
in_parens = 0;
$$ = NULL;
}
- | IO_OUT { in_print = FALSE; in_parens = 0; } common_exp
+ | IO_OUT { in_print = false; in_parens = 0; } common_exp
{
if ($1->redir_type == redirect_twoway
&& $3->lasti->opcode == Op_K_getline_redir
@@ -1139,7 +1257,7 @@ opt_param_list
: /* empty */
{ $$ = NULL; }
| param_list
- { $$ = $1 ; }
+ { $$ = $1; }
;
param_list
@@ -1188,11 +1306,23 @@ expression_list
| error
{ $$ = NULL; }
| expression_list error
- { $$ = NULL; }
+ {
+ /*
+ * Returning the expression list instead of NULL lets
+ * snode get a list of arguments that it can count.
+ */
+ $$ = $1;
+ }
| expression_list error exp
- { $$ = NULL; }
+ {
+ /* Ditto */
+ $$ = mk_expression_list($1, $3);
+ }
| expression_list comma error
- { $$ = NULL; }
+ {
+ /* Ditto */
+ $$ = $1;
+ }
;
/* Expressions, not including the comma operator. */
@@ -1281,7 +1411,7 @@ common_exp
| common_exp simp_exp %prec CONCAT_OP
{
int count = 2;
- int is_simple_var = FALSE;
+ bool is_simple_var = false;
if ($1->lasti->opcode == Op_concat) {
/* multiple (> 2) adjacent strings optimization */
@@ -1296,7 +1426,7 @@ common_exp
*/
}
- if (do_optimize > 1
+ if (do_optimize
&& $1->nexti == $1->lasti && $1->nexti->opcode == Op_push_i
&& $2->nexti == $2->lasti && $2->nexti->opcode == Op_push_i
) {
@@ -1345,21 +1475,12 @@ simp_exp
| LEX_GETLINE opt_variable input_redir
{
/*
- * In BEGINFILE/ENDFILE, allow `getline var < file'
+ * In BEGINFILE/ENDFILE, allow `getline [var] < file'
*/
- if (rule == BEGINFILE || rule == ENDFILE) {
- if ($2 != NULL && $3 != NULL)
- ; /* all ok */
- else {
- if ($2 != NULL)
- error_ln($1->source_line,
- _("`getline var' invalid inside `%s' rule"), ruletab[rule]);
- else
- error_ln($1->source_line,
- _("`getline' invalid inside `%s' rule"), ruletab[rule]);
- }
- }
+ if ((rule == BEGINFILE || rule == ENDFILE) && $3 == NULL)
+ error_ln($1->source_line,
+ _("non-redirected `getline' invalid inside `%s' rule"), ruletab[rule]);
if (do_lint && rule == END && $3 == NULL)
lintwarn_ln($1->source_line,
_("non-redirected `getline' undefined inside END action"));
@@ -1391,7 +1512,7 @@ simp_exp
$$ = list_merge($5, $4);
} else {
INSTRUCTION *t = $2;
- $4->expr_count = count_expressions(&t, FALSE);
+ $4->expr_count = count_expressions(&t, false);
$$ = list_append(list_merge(t, $5), $4);
}
}
@@ -1434,8 +1555,9 @@ non_post_simp_exp
$$ = list_append(list_append(list_create($1),
instruction(Op_field_spec)), $2);
} else {
- if (do_optimize > 1 && $2->nexti == $2->lasti
+ if (do_optimize && $2->nexti == $2->lasti
&& $2->nexti->opcode == Op_push_i
+ && ($2->nexti->memory->flags & (MPFN|MPZN)) == 0
) {
NODE *n = $2->nexti->memory;
if ((n->flags & (STRCUR|STRING)) != 0) {
@@ -1472,10 +1594,10 @@ non_post_simp_exp
}
| LEX_LENGTH
{
- static short warned1 = FALSE;
+ static bool warned = false;
- if (do_lint && ! warned1) {
- warned1 = TRUE;
+ if (do_lint && ! warned) {
+ warned = true;
lintwarn_ln($1->source_line,
_("call of `length' without parentheses is not portable"));
}
@@ -1508,7 +1630,9 @@ non_post_simp_exp
if ($2->lasti->opcode == Op_push_i
&& ($2->lasti->memory->flags & (STRCUR|STRING)) == 0
) {
- $2->lasti->memory->numbr = -(force_number($2->lasti->memory));
+ NODE *n = $2->lasti->memory;
+ (void) force_number(n);
+ negate_num(n);
$$ = $2;
bcfree($1);
} else {
@@ -1540,13 +1664,13 @@ func_call
INSTRUCTION *f, *t;
char *name;
NODE *indirect_var;
- static short warned = FALSE;
+ static bool warned = false;
const char *msg = _("indirect function calls are a gawk extension");
if (do_traditional || do_posix)
yyerror("%s", msg);
else if (do_lint && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn("%s", msg);
}
@@ -1580,7 +1704,7 @@ direct_func_call
$$ = list_create($1);
} else {
INSTRUCTION *t = $3;
- ($1 + 1)->expr_count = count_expressions(&t, TRUE);
+ ($1 + 1)->expr_count = count_expressions(&t, true);
$$ = list_append(t, $1);
}
}
@@ -1638,7 +1762,7 @@ bracketed_exp_list
t->nexti->memory = dupnode(Nnull_string);
$3->sub_count = 1;
} else
- $3->sub_count = count_expressions(&t, FALSE);
+ $3->sub_count = count_expressions(&t, false);
$$ = list_append(t, $3);
}
;
@@ -1749,11 +1873,12 @@ struct token {
# 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 */
-# define BREAK 0x1000 /* break allowed inside */
-# define CONTINUE 0x2000 /* continue allowed inside */
+# define BREAK 0x0800 /* break allowed inside */
+# define CONTINUE 0x1000 /* continue allowed inside */
+# define DEBUG_USE 0x2000 /* for use by developers */
NODE *(*ptr)(int); /* function that implements this keyword */
+ NODE *(*ptr2)(int); /* alternate arbitrary-precision function */
};
#if 'a' == 0x81 /* it's EBCDIC */
@@ -1777,84 +1902,93 @@ tokcompare(const void *l, const void *r)
* Function pointers come from declarations in awk.h.
*/
+#ifdef HAVE_MPFR
+#define MPF(F) do_mpfr_##F
+#else
+#define MPF(F) 0
+#endif
+
static const struct token tokentab[] = {
-{"BEGIN", Op_rule, LEX_BEGIN, 0, 0},
-{"BEGINFILE", Op_rule, LEX_BEGINFILE, GAWKX, 0},
-{"END", Op_rule, LEX_END, 0, 0},
-{"ENDFILE", Op_rule, LEX_ENDFILE, GAWKX, 0},
+{"BEGIN", Op_rule, LEX_BEGIN, 0, 0, 0},
+{"BEGINFILE", Op_rule, LEX_BEGINFILE, GAWKX, 0, 0},
+{"END", Op_rule, LEX_END, 0, 0, 0},
+{"ENDFILE", Op_rule, LEX_ENDFILE, GAWKX, 0, 0},
#ifdef ARRAYDEBUG
-{"adump", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_adump},
+{"adump", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|DEBUG_USE, do_adump, 0},
#endif
-{"and", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_and},
-#ifdef ARRAYDEBUG
-{"aoption", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_aoption},
+{"and", Op_builtin, LEX_BUILTIN, GAWKX, do_and, MPF(and)},
+{"asort", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_asort, 0},
+{"asorti", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_asorti, 0},
+{"atan2", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_atan2, MPF(atan2)},
+{"bindtextdomain", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_bindtextdomain, 0},
+{"break", Op_K_break, LEX_BREAK, 0, 0, 0},
+{"case", Op_K_case, LEX_CASE, GAWKX, 0, 0},
+{"close", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1)|A(2), do_close, 0},
+{"compl", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_compl, MPF(compl)},
+{"continue", Op_K_continue, LEX_CONTINUE, 0, 0, 0},
+{"cos", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_cos, MPF(cos)},
+{"dcgettext", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_dcgettext, 0},
+{"dcngettext", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3)|A(4)|A(5), do_dcngettext, 0},
+{"default", Op_K_default, LEX_DEFAULT, GAWKX, 0, 0},
+{"delete", Op_K_delete, LEX_DELETE, NOT_OLD, 0, 0},
+{"div", Op_builtin, LEX_BUILTIN, GAWKX|A(3), do_div, MPF(div)},
+{"do", Op_K_do, LEX_DO, NOT_OLD|BREAK|CONTINUE, 0, 0},
+{"else", Op_K_else, LEX_ELSE, 0, 0, 0},
+{"eval", Op_symbol, LEX_EVAL, 0, 0, 0},
+{"exit", Op_K_exit, LEX_EXIT, 0, 0, 0},
+{"exp", Op_builtin, LEX_BUILTIN, A(1), do_exp, MPF(exp)},
+#ifdef DYNAMIC
+{"extension", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_ext, 0},
+#endif
+{"fflush", Op_builtin, LEX_BUILTIN, A(0)|A(1), do_fflush, 0},
+{"for", Op_K_for, LEX_FOR, BREAK|CONTINUE, 0, 0},
+{"func", Op_func, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0, 0},
+{"function",Op_func, LEX_FUNCTION, NOT_OLD, 0, 0},
+{"gensub", Op_sub_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), 0, 0},
+{"getline", Op_K_getline_redir, LEX_GETLINE, NOT_OLD, 0, 0},
+{"gsub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0, 0},
+{"if", Op_K_if, LEX_IF, 0, 0, 0},
+{"in", Op_symbol, LEX_IN, 0, 0, 0},
+{"include", Op_symbol, LEX_INCLUDE, GAWKX, 0, 0},
+{"index", Op_builtin, LEX_BUILTIN, A(2), do_index, 0},
+{"int", Op_builtin, LEX_BUILTIN, A(1), do_int, MPF(int)},
+{"isarray", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_isarray, 0},
+{"length", Op_builtin, LEX_LENGTH, A(0)|A(1), do_length, 0},
+{"load", Op_symbol, LEX_LOAD, GAWKX, 0, 0},
+{"log", Op_builtin, LEX_BUILTIN, A(1), do_log, MPF(log)},
+{"lshift", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_lshift, MPF(lshift)},
+{"match", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_match, 0},
+{"mktime", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_mktime, 0},
+{"next", Op_K_next, LEX_NEXT, 0, 0, 0},
+{"nextfile", Op_K_nextfile, LEX_NEXTFILE, 0, 0, 0},
+{"or", Op_builtin, LEX_BUILTIN, GAWKX, do_or, MPF(or)},
+{"patsplit", Op_builtin, LEX_BUILTIN, GAWKX|A(2)|A(3)|A(4), do_patsplit, 0},
+{"print", Op_K_print, LEX_PRINT, 0, 0, 0},
+{"printf", Op_K_printf, LEX_PRINTF, 0, 0, 0},
+{"rand", Op_builtin, LEX_BUILTIN, NOT_OLD|A(0), do_rand, MPF(rand)},
+{"return", Op_K_return, LEX_RETURN, NOT_OLD, 0, 0},
+{"rshift", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_rshift, MPF(rshift)},
+{"sin", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_sin, MPF(sin)},
+{"split", Op_builtin, LEX_BUILTIN, A(2)|A(3)|A(4), do_split, 0},
+{"sprintf", Op_builtin, LEX_BUILTIN, 0, do_sprintf, 0},
+{"sqrt", Op_builtin, LEX_BUILTIN, A(1), do_sqrt, MPF(sqrt)},
+{"srand", Op_builtin, LEX_BUILTIN, NOT_OLD|A(0)|A(1), do_srand, MPF(srand)},
+#if defined(GAWKDEBUG) || defined(ARRAYDEBUG) /* || ... */
+{"stopme", Op_builtin, LEX_BUILTIN, GAWKX|A(0)|DEBUG_USE, stopme, 0},
#endif
-{"asort", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_asort},
-{"asorti", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_asorti},
-{"atan2", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_atan2},
-{"bindtextdomain", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_bindtextdomain},
-{"break", Op_K_break, LEX_BREAK, 0, 0},
-{"case", Op_K_case, LEX_CASE, GAWKX, 0},
-{"close", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1)|A(2), do_close},
-{"compl", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_compl},
-{"continue", Op_K_continue, LEX_CONTINUE, 0, 0},
-{"cos", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_cos},
-{"dcgettext", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_dcgettext},
-{"dcngettext", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3)|A(4)|A(5), do_dcngettext},
-{"default", Op_K_default, LEX_DEFAULT, GAWKX, 0},
-{"delete", Op_K_delete, LEX_DELETE, NOT_OLD, 0},
-{"do", Op_K_do, LEX_DO, NOT_OLD|BREAK|CONTINUE, 0},
-{"else", Op_K_else, LEX_ELSE, 0, 0},
-{"eval", Op_symbol, LEX_EVAL, 0, 0},
-{"exit", Op_K_exit, LEX_EXIT, 0, 0},
-{"exp", Op_builtin, LEX_BUILTIN, A(1), do_exp},
-{"extension", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_ext},
-{"fflush", Op_builtin, LEX_BUILTIN, RESX|A(0)|A(1), do_fflush},
-{"for", Op_K_for, LEX_FOR, BREAK|CONTINUE, 0},
-{"func", Op_func, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0},
-{"function",Op_func, LEX_FUNCTION, NOT_OLD, 0},
-{"gensub", Op_sub_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), 0},
-{"getline", Op_K_getline_redir, LEX_GETLINE, NOT_OLD, 0},
-{"gsub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0},
-{"if", Op_K_if, LEX_IF, 0, 0},
-{"in", Op_symbol, LEX_IN, 0, 0},
-{"include", Op_symbol, LEX_INCLUDE, GAWKX, 0},
-{"index", Op_builtin, LEX_BUILTIN, A(2), do_index},
-{"int", Op_builtin, LEX_BUILTIN, A(1), do_int},
-{"isarray", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_isarray},
-{"length", Op_builtin, LEX_LENGTH, A(0)|A(1), do_length},
-{"log", Op_builtin, LEX_BUILTIN, A(1), do_log},
-{"lshift", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_lshift},
-{"match", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_match},
-{"mktime", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_mktime},
-{"next", Op_K_next, LEX_NEXT, 0, 0},
-{"nextfile", Op_K_nextfile, LEX_NEXTFILE, GAWKX, 0},
-{"or", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_or},
-{"patsplit", Op_builtin, LEX_BUILTIN, GAWKX|A(2)|A(3)|A(4), do_patsplit},
-{"print", Op_K_print, LEX_PRINT, 0, 0},
-{"printf", Op_K_printf, LEX_PRINTF, 0, 0},
-{"rand", Op_builtin, LEX_BUILTIN, NOT_OLD|A(0), do_rand},
-{"return", Op_K_return, LEX_RETURN, NOT_OLD, 0},
-{"rshift", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_rshift},
-{"sin", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_sin},
-{"split", Op_builtin, LEX_BUILTIN, A(2)|A(3)|A(4), do_split},
-{"sprintf", Op_builtin, LEX_BUILTIN, 0, do_sprintf},
-{"sqrt", Op_builtin, LEX_BUILTIN, A(1), do_sqrt},
-{"srand", Op_builtin, LEX_BUILTIN, NOT_OLD|A(0)|A(1), do_srand},
-{"strftime", Op_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2)|A(3), do_strftime},
-{"strtonum", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum},
-{"sub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0},
-{"substr", Op_builtin, LEX_BUILTIN, A(2)|A(3), do_substr},
-{"switch", Op_K_switch, LEX_SWITCH, GAWKX|BREAK, 0},
-{"system", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_system},
-{"systime", Op_builtin, LEX_BUILTIN, GAWKX|A(0), do_systime},
-{"tolower", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_tolower},
-{"toupper", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_toupper},
-{"while", Op_K_while, LEX_WHILE, BREAK|CONTINUE, 0},
-{"xor", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_xor},
+{"strftime", Op_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2)|A(3), do_strftime, 0},
+{"strtonum", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum, MPF(strtonum)},
+{"sub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0, 0},
+{"substr", Op_builtin, LEX_BUILTIN, A(2)|A(3), do_substr, 0},
+{"switch", Op_K_switch, LEX_SWITCH, GAWKX|BREAK, 0, 0},
+{"system", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_system, 0},
+{"systime", Op_builtin, LEX_BUILTIN, GAWKX|A(0), do_systime, 0},
+{"tolower", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_tolower, 0},
+{"toupper", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_toupper, 0},
+{"while", Op_K_while, LEX_WHILE, BREAK|CONTINUE, 0, 0},
+{"xor", Op_builtin, LEX_BUILTIN, GAWKX, do_xor, MPF(xor)},
};
-#if MBS_SUPPORT
/* Variable containing the current shift state. */
static mbstate_t cur_mbstate;
/* Ring buffer containing current characters. */
@@ -1866,10 +2000,6 @@ 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) */
@@ -1881,12 +2011,53 @@ getfname(NODE *(*fptr)(int))
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)
+ if (tokentab[i].ptr == fptr || tokentab[i].ptr2 == fptr)
return tokentab[i].operator;
return NULL;
}
+/* negate_num --- negate a number in NODE */
+
+void
+negate_num(NODE *n)
+{
+#ifdef HAVE_MPFR
+ int tval = 0;
+#endif
+
+ if (! is_mpg_number(n)) {
+ n->numbr = -n->numbr;
+ return;
+ }
+
+#ifdef HAVE_MPFR
+ if (is_mpg_integer(n)) {
+ if (! iszero(n)) {
+ mpz_neg(n->mpg_i, n->mpg_i);
+ return;
+ }
+
+ /*
+ * 0 --> -0 conversion. Requires turning the MPG integer
+ * into an MPFR float.
+ */
+
+ mpz_clear(n->mpg_i); /* release the integer storage */
+
+ /* Convert and fall through. */
+ tval = mpfr_set_d(n->mpg_numbr, 0.0, ROUND_MODE);
+ IEEE_FMT(n->mpg_numbr, tval);
+ n->flags &= ~MPZN;
+ n->flags |= MPFN;
+ }
+
+ /* mpfr float case */
+ tval = mpfr_neg(n->mpg_numbr, n->mpg_numbr, ROUND_MODE);
+ IEEE_FMT(n->mpg_numbr, tval);
+#endif
+}
+
/* print_included_from --- print `Included from ..' file names and locations */
static void
@@ -1910,7 +2081,7 @@ print_included_from()
line--;
msg("%s %s:%d%c",
s->prev == sourcefile ? "In file included from"
- : " from",
+ : " from",
(s->stype == SRC_INC ||
s->stype == SRC_FILE) ? s->src : "cmd. line",
line,
@@ -1932,7 +2103,7 @@ warning_ln(int line, const char *mesg, ...)
sourceline = line;
print_included_from();
va_start(args, mesg);
- err(_("warning: "), mesg, args);
+ err(false, _("warning: "), mesg, args);
va_end(args);
sourceline = saveline;
}
@@ -1950,9 +2121,9 @@ lintwarn_ln(int line, const char *mesg, ...)
print_included_from();
va_start(args, mesg);
if (lintfunc == r_fatal)
- err(_("fatal: "), mesg, args);
+ err(true, _("fatal: "), mesg, args);
else
- err(_("warning: "), mesg, args);
+ err(false, _("warning: "), mesg, args);
va_end(args);
sourceline = saveline;
if (lintfunc == r_fatal)
@@ -1972,7 +2143,7 @@ error_ln(int line, const char *m, ...)
print_included_from();
errcount++;
va_start(args, m);
- err("error: ", m, args);
+ err(false, "error: ", m, args);
va_end(args);
sourceline = saveline;
}
@@ -2050,7 +2221,7 @@ yyerror(const char *m, ...)
*bp++ = ' ';
}
strcpy(bp, mesg);
- err("", buf, args);
+ err(false, "", buf, args);
va_end(args);
efree(buf);
}
@@ -2091,7 +2262,7 @@ mk_program()
if (endfile_block == NULL)
endfile_block = list_create(ip_endfile);
else {
- ip_rec->has_endfile = TRUE;
+ ip_rec->has_endfile = true;
(void) list_prepend(endfile_block, ip_endfile);
}
@@ -2117,6 +2288,11 @@ mk_program()
cp = end_block;
else
cp = list_merge(begin_block, end_block);
+ if (program_comment != NULL) {
+ (void) list_prepend(cp, program_comment);
+ }
+ if (comment != NULL)
+ (void) list_append(cp, comment);
(void) list_append(cp, ip_atexit);
(void) list_append(cp, instruction(Op_stop));
@@ -2149,6 +2325,12 @@ mk_program()
if (begin_block != NULL)
cp = list_merge(begin_block, cp);
+ if (program_comment != NULL) {
+ (void) list_prepend(cp, program_comment);
+ }
+ if (comment != NULL) {
+ (void) list_append(cp, comment);
+ }
(void) list_append(cp, ip_atexit);
(void) list_append(cp, instruction(Op_stop));
@@ -2156,6 +2338,10 @@ out:
/* delete the Op_list, not needed */
tmp = cp->nexti;
bcfree(cp);
+ /* these variables are not used again but zap them anyway. */
+ comment = NULL;
+ function_comment = NULL;
+ program_comment = NULL;
return tmp;
#undef begin_block
@@ -2192,8 +2378,11 @@ parse_program(INSTRUCTION **pcode)
ip_atexit = instruction(Op_atexit); /* target for `exit' in END block */
}
- sourcefile = srcfiles->next;
- lexeof = FALSE;
+ for (sourcefile = srcfiles->next; sourcefile->stype == SRC_EXTLIB;
+ sourcefile = sourcefile->next)
+ ;
+
+ lexeof = false;
lexptr = NULL;
lasttok = 0;
memset(rule_block, 0, sizeof(ruletab) * sizeof(INSTRUCTION *));
@@ -2209,13 +2398,27 @@ parse_program(INSTRUCTION **pcode)
if (ret == 0) /* avoid spurious warning if parser aborted with YYABORT */
check_funcs();
+ if (args_array == NULL)
+ emalloc(args_array, NODE **, (max_args + 2) * sizeof(NODE *), "parse_program");
+ else
+ erealloc(args_array, NODE **, (max_args + 2) * sizeof(NODE *), "parse_program");
+
return (ret || errcount);
}
+/* free_srcfile --- free a SRCFILE struct */
+
+void
+free_srcfile(SRCFILE *thisfile)
+{
+ efree(thisfile->src);
+ efree(thisfile);
+}
+
/* do_add_srcfile --- add one item to srcfiles */
static SRCFILE *
-do_add_srcfile(int stype, char *src, char *path, SRCFILE *thisfile)
+do_add_srcfile(enum srctype stype, char *src, char *path, SRCFILE *thisfile)
{
SRCFILE *s;
@@ -2237,7 +2440,7 @@ do_add_srcfile(int stype, char *src, char *path, SRCFILE *thisfile)
*/
SRCFILE *
-add_srcfile(int stype, char *src, SRCFILE *thisfile, int *already_included, int *errcode)
+add_srcfile(enum srctype stype, char *src, SRCFILE *thisfile, bool *already_included, int *errcode)
{
SRCFILE *s;
struct stat sbuf;
@@ -2245,41 +2448,61 @@ add_srcfile(int stype, char *src, SRCFILE *thisfile, int *already_included, int
int errno_val = 0;
if (already_included)
- *already_included = FALSE;
+ *already_included = false;
if (errcode)
*errcode = 0;
if (stype == SRC_CMDLINE || stype == SRC_STDIN)
return do_add_srcfile(stype, src, NULL, thisfile);
- path = find_source(src, &sbuf, &errno_val);
+ path = find_source(src, & sbuf, &errno_val, stype == SRC_EXTLIB);
if (path == NULL) {
if (errcode) {
*errcode = errno_val;
return NULL;
}
- fatal(_("can't open source file `%s' for reading (%s)"),
- src, errno_val ? strerror(errno_val) : _("reason unknown"));
+ /* use full messages to ease translation */
+ fatal(stype != SRC_EXTLIB
+ ? _("can't open source file `%s' for reading (%s)")
+ : _("can't open shared library `%s' for reading (%s)"),
+ src,
+ errno_val ? strerror(errno_val) : _("reason unknown"));
}
+ /* N.B. We do not eliminate duplicate SRC_FILE (-f) programs. */
for (s = srcfiles->next; s != srcfiles; s = s->next) {
- if ((s->stype == SRC_FILE || s->stype == SRC_INC)
- && files_are_same(path, s)
- ) {
- if (do_lint) {
- int line = sourceline;
- /* Kludge: the line number may be off for `@include file'.
- * Since, this function is also used for '-f file' in main.c,
- * sourceline > 1 check ensures that the call is at
- * parse time.
- */
- if (sourceline > 1 && lasttok == NEWLINE)
- line--;
- lintwarn_ln(line, _("already included source file `%s'"), src);
+ if ((s->stype == SRC_FILE || s->stype == SRC_INC || s->stype == SRC_EXTLIB) && files_are_same(path, s)) {
+ if (stype == SRC_INC || stype == SRC_EXTLIB) {
+ /* eliminate duplicates */
+ if ((stype == SRC_INC) && (s->stype == SRC_FILE))
+ fatal(_("can't include `%s' and use it as a program file"), src);
+
+ if (do_lint) {
+ int line = sourceline;
+ /* Kludge: the line number may be off for `@include file'.
+ * Since, this function is also used for '-f file' in main.c,
+ * sourceline > 1 check ensures that the call is at
+ * parse time.
+ */
+ if (sourceline > 1 && lasttok == NEWLINE)
+ line--;
+ lintwarn_ln(line,
+ stype != SRC_EXTLIB
+ ? _("already included source file `%s'")
+ : _("already loaded shared library `%s'"),
+ src);
+ }
+ efree(path);
+ if (already_included)
+ *already_included = true;
+ return NULL;
+ } else {
+ /* duplicates are allowed for -f */
+ if (s->stype == SRC_INC)
+ fatal(_("can't include `%s' and use it as a program file"), src);
+ /* no need to scan for further matches, since
+ * they must be of homogeneous type */
+ break;
}
- efree(path);
- if (already_included)
- *already_included = TRUE;
- return NULL;
}
}
@@ -2297,7 +2520,7 @@ include_source(INSTRUCTION *file)
SRCFILE *s;
char *src = file->lextok;
int errcode;
- int already_included;
+ bool already_included;
if (do_traditional || do_posix) {
error_ln(file->source_line, _("@include is a gawk extension"));
@@ -2334,8 +2557,43 @@ include_source(INSTRUCTION *file)
sourceline = 0;
source = NULL;
lasttok = 0;
- lexeof = FALSE;
- eof_warned = FALSE;
+ lexeof = false;
+ eof_warned = false;
+ return 0;
+}
+
+/* load_library --- load a shared library */
+
+static int
+load_library(INSTRUCTION *file)
+{
+ SRCFILE *s;
+ char *src = file->lextok;
+ int errcode;
+ bool already_included;
+
+ if (do_traditional || do_posix) {
+ error_ln(file->source_line, _("@load is a gawk extension"));
+ return -1;
+ }
+
+ if (strlen(src) == 0) {
+ if (do_lint)
+ lintwarn_ln(file->source_line, _("empty filename after @load"));
+ return 0;
+ }
+
+ s = add_srcfile(SRC_EXTLIB, src, sourcefile, &already_included, &errcode);
+ if (s == NULL) {
+ if (already_included)
+ return 0;
+ error_ln(file->source_line,
+ _("can't open shared library `%s' for reading (%s)"),
+ src, errcode ? strerror(errcode) : _("reason unknown"));
+ return -1;
+ }
+
+ load_ext(s->fullpath);
return 0;
}
@@ -2362,11 +2620,11 @@ next_sourcefile()
* Previous versions of gawk did not core dump in such a
* case.
*
- * assert(lexeof == TRUE);
+ * assert(lexeof == true);
*/
- lexeof = FALSE;
- eof_warned = FALSE;
+ lexeof = false;
+ eof_warned = false;
sourcefile->srclines = sourceline; /* total no of lines in current file */
if (sourcefile->fd > INVALID_HANDLE) {
if (sourcefile->fd != fileno(stdin)) /* safety */
@@ -2379,9 +2637,12 @@ next_sourcefile()
sourcefile->lexptr_begin = NULL;
}
- sourcefile = sourcefile->next;
- if (sourcefile == srcfiles)
- return;
+ while ((sourcefile = sourcefile->next) != NULL) {
+ if (sourcefile == srcfiles)
+ return;
+ if (sourcefile->stype != SRC_EXTLIB)
+ break;
+ }
if (sourcefile->lexptr_begin != NULL) {
/* resume reading from already opened file (postponed to process '@include') */
@@ -2407,7 +2668,7 @@ get_src_buf()
{
int n;
char *scan;
- int newfile;
+ bool newfile;
int savelen;
struct stat sbuf;
@@ -2432,7 +2693,7 @@ get_src_buf()
readfunc = read_one_line;
}
- newfile = FALSE;
+ newfile = false;
if (sourcefile == srcfiles)
return NULL;
@@ -2448,13 +2709,13 @@ get_src_buf()
* gawk '' /path/name
* Sigh.
*/
- static short warned = FALSE;
+ static bool warned = false;
if (do_lint && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn(_("empty program text on command line"));
}
- lexeof = TRUE;
+ lexeof = true;
}
} else if (sourcefile->buf == NULL && *(lexptr-1) != '\n') {
/*
@@ -2482,7 +2743,7 @@ get_src_buf()
lexend = lexptr + 1;
sourcefile->buf = buf;
} else
- lexeof = TRUE;
+ lexeof = true;
return lexptr;
}
@@ -2503,7 +2764,7 @@ get_src_buf()
error(_("can't open source file `%s' for reading (%s)"),
in, strerror(errno));
errcount++;
- lexeof = TRUE;
+ lexeof = true;
return sourcefile->src;
}
@@ -2519,7 +2780,7 @@ get_src_buf()
l = A_DECENT_BUFFER_SIZE;
#undef A_DECENT_BUFFER_SIZE
sourcefile->bufsize = l;
- newfile = TRUE;
+ newfile = true;
emalloc(sourcefile->buf, char *, sourcefile->bufsize, "get_src_buf");
lexptr = lexptr_begin = lexeme = sourcefile->buf;
savelen = 0;
@@ -2570,17 +2831,17 @@ get_src_buf()
error(_("can't read sourcefile `%s' (%s)"),
source, strerror(errno));
errcount++;
- lexeof = TRUE;
+ lexeof = true;
} else {
lexend = lexptr + n;
if (n == 0) {
- static short warned = FALSE;
- if (do_lint && newfile && ! warned){
- warned = TRUE;
+ static bool warned = false;
+ if (do_lint && newfile && ! warned) {
+ warned = true;
sourceline = 0;
lintwarn(_("source file `%s' is empty"), source);
}
- lexeof = TRUE;
+ lexeof = true;
}
}
return sourcefile->buf;
@@ -2612,12 +2873,38 @@ tokexpand()
return tok;
}
-/* nextc --- get the next input character */
+/* check_bad_char --- fatal if c isn't allowed in gawk source code */
+
+/*
+ * The error message was inspired by someone who decided to put
+ * a physical \0 byte into the source code to see what would
+ * happen and then filed a bug report about it. Sigh.
+ */
+
+static void
+check_bad_char(int c)
+{
+ /* allow escapes. needed for autoconf. bleah. */
+ switch (c) {
+ case '\a':
+ case '\b':
+ case '\f':
+ case '\n':
+ case '\r':
+ case '\t':
+ return;
+ default:
+ break;
+ }
-#if MBS_SUPPORT
+ if (iscntrl(c) && ! isspace(c))
+ fatal(_("PEBKAC error: invalid character '\\%03o' in source code"), c & 0xFF);
+}
+
+/* nextc --- get the next input character */
static int
-nextc(void)
+nextc(bool check_for_bad)
{
if (gawk_mb_cur_max > 1) {
again:
@@ -2640,7 +2927,7 @@ again:
mbstate_t tmp_state;
size_t mbclen;
- for (idx = 0 ; lexptr + idx < lexend ; idx++) {
+ for (idx = 0; lexptr + idx < lexend; idx++) {
tmp_state = cur_mbstate;
mbclen = mbrlen(lexptr, idx + 1, &tmp_state);
@@ -2668,48 +2955,134 @@ again:
0 : work_ring_idx + 1;
cur_char_ring[work_ring_idx] = 0;
}
+ if (check_for_bad)
+ check_bad_char(*lexptr);
return (int) (unsigned char) *lexptr++;
} else {
do {
if (lexeof)
return END_FILE;
- if (lexptr && lexptr < lexend)
- return ((int) (unsigned char) *lexptr++);
+ if (lexptr && lexptr < lexend) {
+ if (check_for_bad)
+ check_bad_char(*lexptr);
+ return ((int) (unsigned char) *lexptr++);
+ }
} while (get_src_buf());
return END_SRC;
}
}
-#else /* MBS_SUPPORT */
-
-int
-nextc()
-{
- do {
- if (lexeof)
- return END_FILE;
- if (lexptr && lexptr < lexend)
- return ((int) (unsigned char) *lexptr++);
- } while (get_src_buf());
- return END_SRC;
-}
-
-#endif /* MBS_SUPPORT */
-
/* pushback --- push a character back on the input */
static inline void
pushback(void)
{
-#if MBS_SUPPORT
if (gawk_mb_cur_max > 1)
cur_ring_idx = (cur_ring_idx == 0)? RING_BUFFER_SIZE - 1 :
cur_ring_idx - 1;
-#endif
(! lexeof && lexptr && lexptr > lexptr_begin ? lexptr-- : lexptr);
}
+/* check_comment --- check for block comment */
+
+void
+check_comment(void)
+{
+ if (comment != NULL) {
+ if (first_rule) {
+ program_comment = comment;
+ } else
+ block_comment = comment;
+ comment = NULL;
+ }
+ first_rule = false;
+}
+
+/*
+ * get_comment --- collect comment text.
+ * Flag = EOL_COMMENT for end-of-line comments.
+ * Flag = FULL_COMMENT for self-contained comments.
+ */
+
+int
+get_comment(int flag)
+{
+ int c;
+ int sl;
+ tok = tokstart;
+ tokadd('#');
+ sl = sourceline;
+
+ while (true) {
+ while ((c = nextc(false)) != '\n' && c != END_FILE) {
+ tokadd(c);
+ }
+ if (flag == EOL_COMMENT) {
+ /* comment at end of line. */
+ if (c == '\n')
+ tokadd(c);
+ break;
+ }
+ if (c == '\n') {
+ tokadd(c);
+ sourceline++;
+ do {
+ c = nextc(false);
+ if (c == '\n') {
+ sourceline++;
+ tokadd(c);
+ }
+ } while (isspace(c) && c != END_FILE);
+ if (c == END_FILE)
+ break;
+ else if (c != '#') {
+ pushback();
+ sourceline--;
+ break;
+ } else
+ tokadd(c);
+ } else
+ break;
+ }
+ comment = bcalloc(Op_comment, 1, sl);
+ comment->source_file = source;
+ comment->memory = make_str_node(tokstart, tok - tokstart, 0);
+ comment->memory->comment_type = flag;
+
+ return c;
+}
+
+/* split_comment --- split initial comment text into program and function parts */
+
+static void
+split_comment(void)
+{
+ char *p;
+ int l;
+ NODE *n;
+
+ p = comment->memory->stptr;
+ l = comment->memory->stlen - 3;
+ /* have at least two comments so split at last blank line (\n\n) */
+ while (l >= 0) {
+ if (p[l] == '\n' && p[l+1] == '\n') {
+ function_comment = comment;
+ n = function_comment->memory;
+ function_comment->memory = make_str_node(p + l + 2, n->stlen - l - 2, 0);
+ /* create program comment */
+ program_comment = bcalloc(Op_comment, 1, sourceline);
+ program_comment->source_file = comment->source_file;
+ p[l + 2] = 0;
+ program_comment->memory = make_str_node(p, l + 2, 0);
+ comment = NULL;
+ freenode(n);
+ break;
+ }
+ else
+ l--;
+ }
+}
/* allow_newline --- allow newline after &&, ||, ? and : */
@@ -2719,14 +3092,19 @@ allow_newline(void)
int c;
for (;;) {
- c = nextc();
+ c = nextc(true);
if (c == END_FILE) {
pushback();
break;
}
if (c == '#') {
- while ((c = nextc()) != '\n' && c != END_FILE)
- continue;
+ if (do_pretty_print && ! do_profile) {
+ /* collect comment byte code iff doing pretty print but not profiling. */
+ c = get_comment(EOL_COMMENT);
+ } else {
+ while ((c = nextc(false)) != '\n' && c != END_FILE)
+ continue;
+ }
if (c == END_FILE) {
pushback();
break;
@@ -2741,33 +3119,53 @@ allow_newline(void)
}
}
+/* newline_eof --- return newline or EOF as needed and adjust variables */
+
+/*
+ * This routine used to be a macro, however GCC 4.6.2 warned about
+ * the result of a computation not being used. Converting to a function
+ * removes the warnings.
+ */
+
+static int
+newline_eof()
+{
+ /* NB: a newline at end does not start a source line. */
+ if (lasttok != NEWLINE) {
+ pushback();
+ if (do_lint && ! eof_warned) {
+ lintwarn(_("source file does not end in newline"));
+ eof_warned = true;
+ }
+ sourceline++;
+ return NEWLINE;
+ }
+
+ sourceline--;
+ eof_warned = false;
+ return LEX_EOF;
+}
+
/* yylex --- Read the input and turn it into tokens. */
static int
yylex(void)
{
int c;
- int seen_e = FALSE; /* These are for numbers */
- int seen_point = FALSE;
- int esc_seen; /* for literal strings */
+ bool seen_e = false; /* These are for numbers */
+ bool seen_point = false;
+ bool esc_seen; /* for literal strings */
int mid;
- static int did_newline = FALSE;
+ int base;
+ static bool did_newline = false;
char *tokkey;
- int inhex = FALSE;
- int intlstr = FALSE;
+ bool inhex = false;
+ bool intlstr = false;
AWKNUM d;
#define GET_INSTRUCTION(op) bcalloc(op, 1, sourceline)
- /* NB: a newline at end does not start a source line. */
-
-#define NEWLINE_EOF \
- (lasttok != NEWLINE ? \
- (pushback(), do_lint && ! eof_warned && \
- (lintwarn(_("source file does not end in newline")), \
- eof_warned = TRUE), sourceline++, NEWLINE) : \
- (sourceline--, eof_warned = FALSE, LEX_EOF))
-
+#define NEWLINE_EOF newline_eof()
yylval = (INSTRUCTION *) NULL;
if (lasttok == SUBSCRIPT) {
@@ -2778,7 +3176,7 @@ yylex(void)
if (lasttok == LEX_EOF) /* error earlier in current source, must give up !! */
return 0;
- c = nextc();
+ c = nextc(true);
if (c == END_SRC)
return 0;
if (c == END_FILE)
@@ -2817,29 +3215,27 @@ yylex(void)
* The code for \ handles \[ and \].
*/
- want_regexp = FALSE;
+ want_regexp = false;
tok = tokstart;
for (;;) {
- c = nextc();
+ c = nextc(true);
if (gawk_mb_cur_max == 1 || nextc_is_1stbyte) switch (c) {
case '[':
/* one day check for `.' and `=' too */
- if (nextc() == ':' || in_brack == 0)
+ if (nextc(true) == ':' || in_brack == 0)
in_brack++;
pushback();
break;
case ']':
- if (tokstart[0] == '['
- && (tok == tokstart + 1
- || (tok == tokstart + 2
- && tokstart[1] == '^')))
+ if (tok[-1] == '['
+ || (tok[-2] == '[' && tok[-1] == '^'))
/* do nothing */;
else
in_brack--;
break;
case '\\':
- if ((c = nextc()) == END_FILE) {
+ if ((c = nextc(true)) == END_FILE) {
pushback();
yyerror(_("unterminated regexp ends with `\\' at end of file"));
goto end_regexp; /* kludge */
@@ -2859,7 +3255,7 @@ end_regexp:
yylval = GET_INSTRUCTION(Op_token);
yylval->lextok = estrdup(tokstart, tok - tokstart);
if (do_lint) {
- int peek = nextc();
+ int peek = nextc(true);
pushback();
if (peek == 'i' || peek == 's') {
@@ -2889,16 +3285,14 @@ end_regexp:
retry:
/* skipping \r is a hack, but windows is just too pervasive. sigh. */
- while ((c = nextc()) == ' ' || c == '\t' || c == '\r')
+ while ((c = nextc(true)) == ' ' || c == '\t' || c == '\r')
continue;
lexeme = lexptr ? lexptr - 1 : lexptr;
thisline = NULL;
tok = tokstart;
-#if MBS_SUPPORT
if (gawk_mb_cur_max == 1 || nextc_is_1stbyte)
-#endif
switch (c) {
case END_SRC:
return 0;
@@ -2911,9 +3305,23 @@ retry:
return lasttok = NEWLINE;
case '#': /* it's a comment */
- while ((c = nextc()) != '\n') {
+ if (do_pretty_print && ! do_profile) {
+ /*
+ * Collect comment byte code iff doing pretty print
+ * but not profiling.
+ */
+ if (lasttok == NEWLINE || lasttok == 0)
+ c = get_comment(FULL_COMMENT);
+ else
+ c = get_comment(EOL_COMMENT);
+
if (c == END_FILE)
return lasttok = NEWLINE_EOF;
+ } else {
+ while ((c = nextc(false)) != '\n') {
+ if (c == END_FILE)
+ return lasttok = NEWLINE_EOF;
+ }
}
sourceline++;
return lasttok = NEWLINE;
@@ -2924,33 +3332,37 @@ retry:
case '\\':
#ifdef RELAXED_CONTINUATION
/*
- * This code puports to allow comments and/or whitespace
+ * This code purports 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')
+ while ((c = nextc(true)) == ' ' || c == '\t' || c == '\r')
continue;
if (c == '#') {
- static short warned = FALSE;
+ static bool warned = false;
if (do_lint && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn(
_("use of `\\ #...' line continuation is not portable"));
}
- while ((c = nextc()) != '\n')
- if (c == END_FILE)
- break;
+ if (do_pretty_print && ! do_profile)
+ c = get_comment(EOL_COMMENT);
+ else {
+ while ((c = nextc(false)) != '\n')
+ if (c == END_FILE)
+ break;
+ }
}
pushback();
}
#endif /* RELAXED_CONTINUATION */
- c = nextc();
+ c = nextc(true);
if (c == '\r') /* allow MS-DOS files. bleah */
- c = nextc();
+ c = nextc(true);
if (c == '\n') {
sourceline++;
goto retry;
@@ -2989,7 +3401,7 @@ retry:
case '[':
return lasttok = c;
case ']':
- c = nextc();
+ c = nextc(true);
pushback();
if (c == '[') {
yylval = GET_INSTRUCTION(Op_sub_array);
@@ -3001,7 +3413,7 @@ retry:
return ']';
case '*':
- if ((c = nextc()) == '=') {
+ if ((c = nextc(true)) == '=') {
yylval = GET_INSTRUCTION(Op_assign_times);
return lasttok = ASSIGNOP;
} else if (do_posix) {
@@ -3010,11 +3422,11 @@ retry:
return lasttok = '*';
} else if (c == '*') {
/* make ** and **= aliases for ^ and ^= */
- static int did_warn_op = FALSE, did_warn_assgn = FALSE;
+ static bool did_warn_op = false, did_warn_assgn = false;
- if (nextc() == '=') {
+ if (nextc(true) == '=') {
if (! did_warn_assgn) {
- did_warn_assgn = TRUE;
+ did_warn_assgn = true;
if (do_lint)
lintwarn(_("POSIX does not allow operator `**='"));
if (do_lint_old)
@@ -3025,7 +3437,7 @@ retry:
} else {
pushback();
if (! did_warn_op) {
- did_warn_op = TRUE;
+ did_warn_op = true;
if (do_lint)
lintwarn(_("POSIX does not allow operator `**'"));
if (do_lint_old)
@@ -3040,7 +3452,7 @@ retry:
return lasttok = '*';
case '/':
- if (nextc() == '=') {
+ if (nextc(true) == '=') {
pushback();
return lasttok = SLASH_BEFORE_EQUAL;
}
@@ -3049,7 +3461,7 @@ retry:
return lasttok = '/';
case '%':
- if (nextc() == '=') {
+ if (nextc(true) == '=') {
yylval = GET_INSTRUCTION(Op_assign_mod);
return lasttok = ASSIGNOP;
}
@@ -3059,11 +3471,11 @@ retry:
case '^':
{
- static int did_warn_op = FALSE, did_warn_assgn = FALSE;
+ static bool did_warn_op = false, did_warn_assgn = false;
- if (nextc() == '=') {
+ if (nextc(true) == '=') {
if (do_lint_old && ! did_warn_assgn) {
- did_warn_assgn = TRUE;
+ did_warn_assgn = true;
warning(_("operator `^=' is not supported in old awk"));
}
yylval = GET_INSTRUCTION(Op_assign_exp);
@@ -3071,7 +3483,7 @@ retry:
}
pushback();
if (do_lint_old && ! did_warn_op) {
- did_warn_op = TRUE;
+ did_warn_op = true;
warning(_("operator `^' is not supported in old awk"));
}
yylval = GET_INSTRUCTION(Op_exp);
@@ -3079,7 +3491,7 @@ retry:
}
case '+':
- if ((c = nextc()) == '=') {
+ if ((c = nextc(true)) == '=') {
yylval = GET_INSTRUCTION(Op_assign_plus);
return lasttok = ASSIGNOP;
}
@@ -3092,7 +3504,7 @@ retry:
return lasttok = '+';
case '!':
- if ((c = nextc()) == '=') {
+ if ((c = nextc(true)) == '=') {
yylval = GET_INSTRUCTION(Op_notequal);
return lasttok = RELOP;
}
@@ -3105,7 +3517,7 @@ retry:
return lasttok = '!';
case '<':
- if (nextc() == '=') {
+ if (nextc(true) == '=') {
yylval = GET_INSTRUCTION(Op_leq);
return lasttok = RELOP;
}
@@ -3114,7 +3526,7 @@ retry:
return lasttok = '<';
case '=':
- if (nextc() == '=') {
+ if (nextc(true) == '=') {
yylval = GET_INSTRUCTION(Op_equal);
return lasttok = RELOP;
}
@@ -3123,7 +3535,7 @@ retry:
return lasttok = ASSIGN;
case '>':
- if ((c = nextc()) == '=') {
+ if ((c = nextc(true)) == '=') {
yylval = GET_INSTRUCTION(Op_geq);
return lasttok = RELOP;
} else if (c == '>') {
@@ -3150,19 +3562,23 @@ retry:
* hacking the grammar.
*/
if (did_newline) {
- did_newline = FALSE;
+ did_newline = false;
if (--in_braces == 0)
lastline = sourceline;
return lasttok = c;
}
- did_newline++;
+ did_newline = true;
--lexptr; /* pick up } next time */
return lasttok = NEWLINE;
case '"':
string:
- esc_seen = FALSE;
- while ((c = nextc()) != '"') {
+ esc_seen = false;
+ /*
+ * Allow any kind of junk in quoted string,
+ * so pass false to nextc().
+ */
+ while ((c = nextc(false)) != '"') {
if (c == '\n') {
pushback();
yyerror(_("unterminated string"));
@@ -3170,12 +3586,12 @@ retry:
}
if ((gawk_mb_cur_max == 1 || nextc_is_1stbyte) &&
c == '\\') {
- c = nextc();
+ c = nextc(true);
if (c == '\n') {
sourceline++;
continue;
}
- esc_seen = TRUE;
+ esc_seen = true;
if (! want_source || c != '"')
tokadd('\\');
}
@@ -3197,14 +3613,14 @@ retry:
tok - tokstart, esc_seen ? SCAN : 0);
if (intlstr) {
yylval->memory->flags |= INTLSTR;
- intlstr = FALSE;
+ intlstr = false;
if (do_intl)
dumpintlstr(yylval->memory->stptr, yylval->memory->stlen);
}
return lasttok = YSTRING;
case '-':
- if ((c = nextc()) == '=') {
+ if ((c = nextc(true)) == '=') {
yylval = GET_INSTRUCTION(Op_assign_minus);
return lasttok = ASSIGNOP;
}
@@ -3217,7 +3633,7 @@ retry:
return lasttok = '-';
case '.':
- c = nextc();
+ c = nextc(true);
pushback();
if (! isdigit(c))
return lasttok = '.';
@@ -3236,7 +3652,7 @@ retry:
case '9':
/* It's a number */
for (;;) {
- int gotnumber = FALSE;
+ bool gotnumber = false;
tokadd(c);
switch (c) {
@@ -3245,10 +3661,10 @@ retry:
if (do_traditional)
goto done;
if (tok == tokstart + 2) {
- int peek = nextc();
+ int peek = nextc(true);
if (isxdigit(peek)) {
- inhex = TRUE;
+ inhex = true;
pushback(); /* following digit */
} else {
pushback(); /* x or X */
@@ -3259,22 +3675,22 @@ retry:
case '.':
/* period ends exponent part of floating point number */
if (seen_point || seen_e) {
- gotnumber = TRUE;
+ gotnumber = true;
break;
}
- seen_point = TRUE;
+ seen_point = true;
break;
case 'e':
case 'E':
if (inhex)
break;
if (seen_e) {
- gotnumber = TRUE;
+ gotnumber = true;
break;
}
- seen_e = TRUE;
- if ((c = nextc()) == '-' || c == '+') {
- int c2 = nextc();
+ seen_e = true;
+ if ((c = nextc(true)) == '-' || c == '+') {
+ int c2 = nextc(true);
if (isdigit(c2)) {
tokadd(c);
@@ -3317,27 +3733,52 @@ retry:
break;
default:
done:
- gotnumber = TRUE;
+ gotnumber = true;
}
if (gotnumber)
break;
- c = nextc();
+ c = nextc(true);
}
pushback();
tokadd('\0');
yylval = GET_INSTRUCTION(Op_push_i);
- if (! do_traditional && isnondecimal(tokstart, FALSE)) {
+
+ base = 10;
+ if (! do_traditional) {
+ base = get_numbase(tokstart, false);
if (do_lint) {
- if (isdigit((unsigned char) tokstart[1])) /* not an 'x' or 'X' */
+ if (base == 8)
lintwarn("numeric constant `%.*s' treated as octal",
(int) strlen(tokstart)-1, tokstart);
- else if (tokstart[1] == 'x' || tokstart[1] == 'X')
+ else if (base == 16)
lintwarn("numeric constant `%.*s' treated as hexadecimal",
(int) strlen(tokstart)-1, tokstart);
}
+ }
+
+#ifdef HAVE_MPFR
+ if (do_mpfr) {
+ NODE *r;
+
+ if (! seen_point && ! seen_e) {
+ r = mpg_integer();
+ mpg_strtoui(r->mpg_i, tokstart, strlen(tokstart), NULL, base);
+ errno = 0;
+ } else {
+ int tval;
+ r = mpg_float();
+ tval = mpfr_strtofr(r->mpg_numbr, tokstart, NULL, base, ROUND_MODE);
+ errno = 0;
+ IEEE_FMT(r->mpg_numbr, tval);
+ }
+ yylval->memory = r;
+ return lasttok = YNUMBER;
+ }
+#endif
+ if (base != 10)
d = nondec2awknum(tokstart, strlen(tokstart));
- } else
+ else
d = atof(tokstart);
yylval->memory = make_number(d);
if (d <= INT32_MAX && d >= INT32_MIN && d == (int32_t) d)
@@ -3345,7 +3786,7 @@ retry:
return lasttok = YNUMBER;
case '&':
- if ((c = nextc()) == '&') {
+ if ((c = nextc(true)) == '&') {
yylval = GET_INSTRUCTION(Op_and);
allow_newline();
return lasttok = LEX_AND;
@@ -3355,7 +3796,7 @@ retry:
return lasttok = '&';
case '|':
- if ((c = nextc()) == '|') {
+ if ((c = nextc(true)) == '|') {
yylval = GET_INSTRUCTION(Op_or);
allow_newline();
return lasttok = LEX_OR;
@@ -3376,7 +3817,7 @@ retry:
}
}
- if (c != '_' && ! isalpha(c)) {
+ if (c != '_' && ! is_alpha(c)) {
yyerror(_("invalid char '%c' in expression"), c);
return lasttok = LEX_EOF;
}
@@ -3396,8 +3837,8 @@ retry:
* occasions where the interactions are funny.
*/
if (! do_traditional && c == '_' && lasttok != '$') {
- if ((c = nextc()) == '"') {
- intlstr = TRUE;
+ if ((c = nextc(true)) == '"') {
+ intlstr = true;
goto string;
}
pushback();
@@ -3408,7 +3849,7 @@ retry:
tok = tokstart;
while (c != END_FILE && is_identchar(c)) {
tokadd(c);
- c = nextc();
+ c = nextc(true);
}
tokadd('\0');
pushback();
@@ -3418,43 +3859,39 @@ retry:
static int warntab[sizeof(tokentab) / sizeof(tokentab[0])];
int class = tokentab[mid].class;
- if ((class == LEX_INCLUDE || class == LEX_EVAL)
+ if ((class == LEX_INCLUDE || class == LEX_LOAD || class == LEX_EVAL)
&& lasttok != '@')
goto out;
if (do_lint) {
- if ((tokentab[mid].flags & GAWKX) && ! (warntab[mid] & GAWKX)) {
+ if ((tokentab[mid].flags & GAWKX) != 0 && (warntab[mid] & GAWKX) == 0) {
lintwarn(_("`%s' is a gawk extension"),
tokentab[mid].operator);
warntab[mid] |= GAWKX;
}
- if ((tokentab[mid].flags & RESX) && ! (warntab[mid] & RESX)) {
- lintwarn(_("`%s' is a Bell Labs extension"),
- tokentab[mid].operator);
- warntab[mid] |= RESX;
- }
- if ((tokentab[mid].flags & NOT_POSIX) && ! (warntab[mid] & NOT_POSIX)) {
+ if ((tokentab[mid].flags & NOT_POSIX) != 0 && (warntab[mid] & NOT_POSIX) == 0) {
lintwarn(_("POSIX does not allow `%s'"),
tokentab[mid].operator);
warntab[mid] |= NOT_POSIX;
}
}
- if (do_lint_old && (tokentab[mid].flags & NOT_OLD)
- && ! (warntab[mid] & NOT_OLD)
+ if (do_lint_old && (tokentab[mid].flags & NOT_OLD) != 0
+ && (warntab[mid] & NOT_OLD) == 0
) {
warning(_("`%s' is not supported in old awk"),
tokentab[mid].operator);
warntab[mid] |= NOT_OLD;
}
- if (tokentab[mid].flags & BREAK)
+ if ((tokentab[mid].flags & BREAK) != 0)
break_allowed++;
- if (tokentab[mid].flags & CONTINUE)
+ if ((tokentab[mid].flags & CONTINUE) != 0)
continue_allowed++;
switch (class) {
case LEX_INCLUDE:
- want_source = TRUE;
+ case LEX_LOAD:
+ want_source = true;
break;
case LEX_EVAL:
if (in_main_context())
@@ -3478,14 +3915,36 @@ retry:
case LEX_WHILE:
case LEX_DO:
case LEX_SWITCH:
- if (! do_profiling)
+ if (! do_pretty_print)
return lasttok = class;
/* fall through */
case LEX_CASE:
yylval = bcalloc(tokentab[mid].value, 2, sourceline);
break;
+ /*
+ * These must be checked here, due to the LALR nature of the parser,
+ * the rules for continue and break may not be reduced until after
+ * a token that increments the xxx_allowed varibles is seen. Bleah.
+ */
+ case LEX_CONTINUE:
+ if (! continue_allowed) {
+ error_ln(sourceline,
+ _("`continue' is not allowed outside a loop"));
+ errcount++;
+ }
+ goto make_instruction;
+
+ case LEX_BREAK:
+ if (! break_allowed) {
+ error_ln(sourceline,
+ _("`break' is not allowed outside a loop or switch"));
+ errcount++;
+ }
+ goto make_instruction;
+
default:
+make_instruction:
yylval = GET_INSTRUCTION(tokentab[mid].value);
if (class == LEX_BUILTIN || class == LEX_LENGTH)
yylval->builtin_idx = mid;
@@ -3500,7 +3959,7 @@ out:
yylval->lextok = tokkey;
return lasttok = FUNC_CALL;
} else {
- static short goto_warned = FALSE;
+ static bool goto_warned = false;
yylval = GET_INSTRUCTION(Op_token);
yylval->lextok = tokkey;
@@ -3508,7 +3967,7 @@ out:
#define SMART_ALECK 1
if (SMART_ALECK && do_lint
&& ! goto_warned && strcasecmp(tokkey, "goto") == 0) {
- goto_warned = TRUE;
+ goto_warned = true;
lintwarn(_("`goto' considered harmful!\n"));
}
return lasttok = NAME;
@@ -3586,10 +4045,10 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
yyerror(_("%s third parameter is not a changeable object"),
operator);
else
- ip->do_reference = TRUE;
+ ip->do_reference = true;
}
- r->expr_count = count_expressions(&subn, FALSE);
+ r->expr_count = count_expressions(&subn, false);
ip = subn->lasti;
(void) list_append(subn, r);
@@ -3604,7 +4063,11 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
subn->lasti->assign_ctxt = Op_sub_builtin;
subn->lasti->field_assign = (Func_ptr) 0;
ip->target_assign = subn->lasti;
+ } else if (ip->opcode == Op_subscript_lhs) {
+ (void) list_append(subn, instruction(Op_subscript_assign));
+ subn->lasti->assign_ctxt = Op_sub_builtin;
}
+
return subn;
} else {
@@ -3618,12 +4081,18 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
list_append(list_create(ip), instruction(Op_field_spec)));
}
- r->expr_count = count_expressions(&subn, FALSE);
+ r->expr_count = count_expressions(&subn, false);
return list_append(subn, r);
}
}
- r->builtin = tokentab[idx].ptr;
+#ifdef HAVE_MPFR
+ /* N.B.: If necessary, add special processing for alternate builtin, below */
+ if (do_mpfr && tokentab[idx].ptr2)
+ r->builtin = tokentab[idx].ptr2;
+ else
+#endif
+ r->builtin = tokentab[idx].ptr;
/* special case processing for a few builtins */
@@ -3647,15 +4116,24 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
arg = subn->nexti;
if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push)
arg->nexti->opcode = Op_push_arg; /* argument may be array */
+ } else if (r->builtin == do_div
+#ifdef HAVE_MPFR
+ || r->builtin == MPF(div)
+#endif
+ ) {
+ arg = subn->nexti->lasti->nexti->lasti->nexti; /* 3rd arg list */
+ ip = arg->lasti;
+ if (ip->opcode == Op_push)
+ ip->opcode = Op_push_array;
} else if (r->builtin == do_match) {
- static short warned = FALSE;
+ static bool warned = false;
arg = subn->nexti->lasti->nexti; /* 2nd arg list */
(void) mk_rexp(arg);
if (nexp == 3) { /* 3rd argument there */
if (do_lint && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn(_("match: third argument is a gawk extension"));
}
if (do_traditional) {
@@ -3709,10 +4187,10 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
ip->opcode = Op_push_array;
}
} else if (r->builtin == do_close) {
- static short warned = FALSE;
+ static bool warned = false;
if (nexp == 2) {
if (do_lint && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn(_("close: second argument is a gawk extension"));
}
if (do_traditional) {
@@ -3758,6 +4236,12 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
ip->opcode = Op_push_array;
}
}
+ else if (r->builtin == do_index) {
+ arg = subn->nexti->lasti->nexti; /* 2nd arg list */
+ ip = arg->lasti;
+ if (ip->opcode == Op_match_rec)
+ fatal(_("index: regexp constant as second argument is not allowed"));
+ }
#ifdef ARRAYDEBUG
else if (r->builtin == do_adump) {
ip = subn->nexti->lasti;
@@ -3767,7 +4251,7 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
#endif
if (subn != NULL) {
- r->expr_count = count_expressions(&subn, FALSE);
+ r->expr_count = count_expressions(&subn, false);
return list_append(subn, r);
}
@@ -3779,10 +4263,10 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
/* parms_shadow --- check if parameters shadow globals */
static int
-parms_shadow(INSTRUCTION *pc, int *shadow)
+parms_shadow(INSTRUCTION *pc, bool *shadow)
{
int pcount, i;
- int ret = FALSE;
+ bool ret = false;
NODE *func, *fp;
char *fname;
@@ -3792,7 +4276,7 @@ parms_shadow(INSTRUCTION *pc, int *shadow)
#if 0 /* can't happen, already exited if error ? */
if (fname == NULL || func == NULL) /* error earlier */
- return FALSE;
+ return false;
#endif
pcount = func->param_cnt;
@@ -3811,7 +4295,7 @@ parms_shadow(INSTRUCTION *pc, int *shadow)
warning(
_("function `%s': parameter `%s' shadows global variable"),
fname, fp[i].param);
- ret = TRUE;
+ ret = true;
}
}
@@ -3819,7 +4303,6 @@ parms_shadow(INSTRUCTION *pc, int *shadow)
return 0;
}
-
/* valinfo --- dump var info */
void
@@ -3828,16 +4311,30 @@ valinfo(NODE *n, Func_print print_func, FILE *fp)
if (n == Nnull_string)
print_func(fp, "uninitialized scalar\n");
else if (n->flags & STRING) {
- pp_string_fp(print_func, fp, n->stptr, n->stlen, '"', FALSE);
+ pp_string_fp(print_func, fp, n->stptr, n->stlen, '"', false);
print_func(fp, "\n");
- } else if (n->flags & NUMBER)
+ } else if (n->flags & NUMBER) {
+#ifdef HAVE_MPFR
+ if (is_mpg_float(n))
+ print_func(fp, "%s\n", mpg_fmt("%.17R*g", ROUND_MODE, n->mpg_numbr));
+ else if (is_mpg_integer(n))
+ print_func(fp, "%s\n", mpg_fmt("%Zd", n->mpg_i));
+ else
+#endif
print_func(fp, "%.17g\n", n->numbr);
- else if (n->flags & STRCUR) {
- pp_string_fp(print_func, fp, n->stptr, n->stlen, '"', FALSE);
+ } else if (n->flags & STRCUR) {
+ pp_string_fp(print_func, fp, n->stptr, n->stlen, '"', false);
print_func(fp, "\n");
- } else if (n->flags & NUMCUR)
+ } else if (n->flags & NUMCUR) {
+#ifdef HAVE_MPFR
+ if (is_mpg_float(n))
+ print_func(fp, "%s\n", mpg_fmt("%.17R*g", ROUND_MODE, n->mpg_numbr));
+ else if (is_mpg_integer(n))
+ print_func(fp, "%s\n", mpg_fmt("%Zd", n->mpg_i));
+ else
+#endif
print_func(fp, "%.17g\n", n->numbr);
- else
+ } else
print_func(fp, "?? flags %s\n", flags2str(n->flags));
}
@@ -3871,7 +4368,7 @@ void
dump_funcs()
{
NODE **funcs;
- funcs = function_list(TRUE);
+ funcs = function_list(true);
(void) foreach_func(funcs, (int (*)(INSTRUCTION *, void *)) pp_func, (void *) 0);
efree(funcs);
}
@@ -3883,13 +4380,13 @@ void
shadow_funcs()
{
static int calls = 0;
- int shadow = FALSE;
+ bool shadow = false;
NODE **funcs;
if (calls++ != 0)
fatal(_("shadow_funcs() called twice!"));
- funcs = function_list(TRUE);
+ funcs = function_list(true);
(void) foreach_func(funcs, (int (*)(INSTRUCTION *, void *)) parms_shadow, & shadow);
efree(funcs);
@@ -3911,7 +4408,7 @@ mk_function(INSTRUCTION *fi, INSTRUCTION *def)
thisfunc = fi->func_body;
assert(thisfunc != NULL);
- if (do_optimize > 1 && def->lasti->opcode == Op_pop) {
+ if (do_optimize && def->lasti->opcode == Op_pop) {
/* tail call which does not return any value. */
INSTRUCTION *t;
@@ -3919,9 +4416,16 @@ mk_function(INSTRUCTION *fi, INSTRUCTION *def)
for (t = def->nexti; t->nexti != def->lasti; t = t->nexti)
;
if (t->opcode == Op_func_call
- && STREQ(t->func_name, thisfunc->vname)
- )
- (t + 1)->tail_call = TRUE;
+ && strcmp(t->func_name, thisfunc->vname) == 0)
+ (t + 1)->tail_call = true;
+ }
+
+ /* add any pre-function comment to start of action for profile.c */
+
+ if (function_comment != NULL) {
+ function_comment->source_line = 0;
+ (void) list_prepend(def, function_comment);
+ function_comment = NULL;
}
/* add an implicit return at end;
@@ -3932,7 +4436,7 @@ mk_function(INSTRUCTION *fi, INSTRUCTION *def)
def->lasti->memory = dupnode(Nnull_string);
(void) list_append(def, instruction(Op_K_return));
- if (do_profiling)
+ if (do_pretty_print)
(void) list_prepend(def, instruction(Op_exec_count));
/* fi->opcode = Op_func */
@@ -4047,6 +4551,7 @@ static struct fdesc {
char *name;
short used;
short defined;
+ short extension;
struct fdesc *next;
} *ftable[HASHSIZE];
@@ -4062,15 +4567,9 @@ func_use(const char *name, enum defref how)
len = strlen(name);
ind = hash(name, len, HASHSIZE, NULL);
- 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;
- }
- }
+ for (fp = ftable[ind]; fp != NULL; fp = fp->next)
+ if (strcmp(fp->name, name) == 0)
+ goto update_value;
/* not in the table, fall through to allocate a new one */
@@ -4078,12 +4577,25 @@ func_use(const char *name, enum defref how)
memset(fp, '\0', sizeof(struct fdesc));
emalloc(fp->name, char *, len + 1, "func_use");
strcpy(fp->name, name);
+ fp->next = ftable[ind];
+ ftable[ind] = fp;
+
+update_value:
if (how == FUNC_DEFINE)
fp->defined++;
- else
+ else if (how == FUNC_EXT) {
+ fp->defined++;
+ fp->extension++;
+ } else
fp->used++;
- fp->next = ftable[ind];
- ftable[ind] = fp;
+}
+
+/* track_ext_func --- add an extension function to the table */
+
+void
+track_ext_func(const char *name)
+{
+ func_use(name, FUNC_EXT);
}
/* check_funcs --- verify functions that are called but not defined */
@@ -4101,17 +4613,18 @@ check_funcs()
for (fp = ftable[i]; fp != NULL; fp = fp->next) {
#ifdef REALLYMEAN
/* making this the default breaks old code. sigh. */
- if (fp->defined == 0) {
+ if (fp->defined == 0 && ! fp->extension) {
error(
_("function `%s' called but never defined"), fp->name);
errcount++;
}
#else
- if (do_lint && fp->defined == 0)
+ if (do_lint && fp->defined == 0 && ! fp->extension)
lintwarn(
_("function `%s' called but never defined"), fp->name);
#endif
- if (do_lint && fp->used == 0) {
+
+ if (do_lint && fp->used == 0 && ! fp->extension) {
lintwarn(_("function `%s' defined but never called directly"),
fp->name);
}
@@ -4150,37 +4663,6 @@ param_sanity(INSTRUCTION *arglist)
}
}
-/* deferred variables --- 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 *
@@ -4194,20 +4676,7 @@ variable(int location, char *name, NODETYPE type)
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.
- */
- return install_symbol(name, type);
- }
- if (STREQ(name, dv->name)) {
- r = (*dv->load_func)();
- break;
- }
- }
+ return install_symbol(name, type);
}
efree(name);
return r;
@@ -4226,7 +4695,7 @@ make_regnode(int type, NODE *exp)
n->re_cnt = 1;
if (type == Node_regex) {
- n->re_reg = make_regexp(exp->stptr, exp->stlen, FALSE, TRUE, FALSE);
+ n->re_reg = make_regexp(exp->stptr, exp->stlen, false, true, false);
if (n->re_reg == NULL) {
freenode(n);
return NULL;
@@ -4258,6 +4727,7 @@ mk_rexp(INSTRUCTION *list)
return ip->memory;
}
+#ifndef NO_LINT
/* isnoeffect --- when used as a statement, has no side effects */
static int
@@ -4293,13 +4763,15 @@ isnoeffect(OPCODE type)
case Op_match_rec:
case Op_not:
case Op_in_array:
- return TRUE;
+ return true;
default:
break; /* keeps gcc -Wall happy */
}
- return FALSE;
+ return false;
}
+#endif /* NO_LINT */
+
/* make_assignable --- make this operand an assignable one if posiible */
@@ -4322,6 +4794,14 @@ make_assignable(INSTRUCTION *ip)
return NULL;
}
+/* stopme --- for debugging */
+
+NODE *
+stopme(int nargs ATTRIBUTE_UNUSED)
+{
+ return make_number(0.0);
+}
+
/* dumpintlstr --- write out an initial .po file entry for the string */
static void
@@ -4339,7 +4819,7 @@ dumpintlstr(const char *str, size_t len)
}
printf("msgid ");
- pp_string_fp(fprintf, stdout, str, len, '"', TRUE);
+ pp_string_fp(fprintf, stdout, str, len, '"', true);
putchar('\n');
printf("msgstr \"\"\n\n");
fflush(stdout);
@@ -4362,10 +4842,10 @@ dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2)
}
printf("msgid ");
- pp_string_fp(fprintf, stdout, str1, len1, '"', TRUE);
+ pp_string_fp(fprintf, stdout, str1, len1, '"', true);
putchar('\n');
printf("msgid_plural ");
- pp_string_fp(fprintf, stdout, str2, len2, '"', TRUE);
+ pp_string_fp(fprintf, stdout, str2, len2, '"', true);
putchar('\n');
printf("msgstr[0] \"\"\nmsgstr[1] \"\"\n\n");
fflush(stdout);
@@ -4383,13 +4863,13 @@ mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION *op)
if (s2->lasti == ip2 && ip2->opcode == Op_push_i) {
/* do any numeric constant folding */
ip1 = s1->nexti;
- if (do_optimize > 1
+ if (do_optimize
&& ip1 == s1->lasti && ip1->opcode == Op_push_i
- && (ip1->memory->flags & (STRCUR|STRING)) == 0
- && (ip2->memory->flags & (STRCUR|STRING)) == 0
+ && (ip1->memory->flags & (MPFN|MPZN|STRCUR|STRING)) == 0
+ && (ip2->memory->flags & (MPFN|MPZN|STRCUR|STRING)) == 0
) {
NODE *n1 = ip1->memory, *n2 = ip2->memory;
- res = force_number(n1);
+ res = force_number(n1)->numbr;
(void) force_number(n2);
switch (op->opcode) {
case Op_times:
@@ -4557,7 +5037,7 @@ mk_condition(INSTRUCTION *cond, INSTRUCTION *ifp, INSTRUCTION *true_branch,
if (false_branch == NULL) {
false_branch = list_create(instruction(Op_no_op));
if (elsep != NULL) { /* else { } */
- if (do_profiling)
+ if (do_pretty_print)
(void) list_prepend(false_branch, elsep);
else
bcfree(elsep);
@@ -4568,7 +5048,7 @@ mk_condition(INSTRUCTION *cond, INSTRUCTION *ifp, INSTRUCTION *true_branch,
/* avoid a series of no_op's: if .. else if .. else if .. */
if (false_branch->lasti->opcode != Op_no_op)
(void) list_append(false_branch, instruction(Op_no_op));
- if (do_profiling) {
+ if (do_pretty_print) {
(void) list_prepend(false_branch, elsep);
false_branch->nexti->branch_end = false_branch->lasti;
(void) list_prepend(false_branch, instruction(Op_exec_count));
@@ -4583,7 +5063,7 @@ mk_condition(INSTRUCTION *cond, INSTRUCTION *ifp, INSTRUCTION *true_branch,
ip = list_append(cond, instruction(Op_jmp_false));
ip->lasti->target_jmp = false_branch->nexti->nexti;
- if (do_profiling) {
+ if (do_pretty_print) {
(void) list_prepend(ip, ifp);
(void) list_append(ip, instruction(Op_exec_count));
ip->nexti->branch_if = ip->lasti;
@@ -4645,13 +5125,17 @@ append_rule(INSTRUCTION *pattern, INSTRUCTION *action)
if (rule != Rule) {
rp = pattern;
- if (do_profiling)
+ if (do_pretty_print)
(void) list_append(action, instruction(Op_no_op));
(rp + 1)->firsti = action->nexti;
(rp + 1)->lasti = action->lasti;
(rp + 2)->first_line = pattern->source_line;
(rp + 2)->last_line = lastline;
- ip = list_prepend(action, rp);
+ if (block_comment != NULL) {
+ ip = list_prepend(list_prepend(action, block_comment), rp);
+ block_comment = NULL;
+ } else
+ ip = list_prepend(action, rp);
} else {
rp = bcalloc(Op_rule, 3, 0);
@@ -4661,7 +5145,7 @@ append_rule(INSTRUCTION *pattern, INSTRUCTION *action)
if (pattern == NULL) {
/* assert(action != NULL); */
- if (do_profiling)
+ if (do_pretty_print)
(void) list_prepend(action, instruction(Op_exec_count));
(rp + 1)->firsti = action->nexti;
(rp + 1)->lasti = tp;
@@ -4677,12 +5161,12 @@ append_rule(INSTRUCTION *pattern, INSTRUCTION *action)
if (action == NULL) {
(rp + 2)->last_line = find_line(pattern, LAST_LINE);
action = list_create(instruction(Op_K_print_rec));
- if (do_profiling)
+ if (do_pretty_print)
(void) list_prepend(action, instruction(Op_exec_count));
} else
(rp + 2)->last_line = lastline;
- if (do_profiling) {
+ if (do_pretty_print) {
(void) list_prepend(pattern, instruction(Op_exec_count));
(void) list_prepend(action, instruction(Op_exec_count));
}
@@ -4693,7 +5177,6 @@ append_rule(INSTRUCTION *pattern, INSTRUCTION *action)
action),
tp);
}
-
}
list_append(rule_list, rp + 1);
@@ -4726,8 +5209,13 @@ mk_assignment(INSTRUCTION *lhs, INSTRUCTION *rhs, INSTRUCTION *op)
case Op_push_array:
tp->opcode = Op_push_lhs;
break;
+ case Op_field_assign:
+ yyerror(_("cannot assign a value to the result of a field post-increment expression"));
+ break;
default:
- cant_happen();
+ yyerror(_("invalid target of assignment (opcode %s)"),
+ opcode2str(tp->opcode));
+ break;
}
tp->do_reference = (op->opcode != Op_assign); /* check for uninitialized reference */
@@ -4743,7 +5231,7 @@ mk_assignment(INSTRUCTION *lhs, INSTRUCTION *rhs, INSTRUCTION *op)
&& tp->memory->type == Node_var
&& tp->memory->var_assign
) {
- tp->do_reference = FALSE; /* no uninitialized reference checking
+ tp->do_reference = false; /* no uninitialized reference checking
* for a special variable.
*/
(void) list_append(ip, instruction(Op_var_assign));
@@ -4752,6 +5240,8 @@ mk_assignment(INSTRUCTION *lhs, INSTRUCTION *rhs, INSTRUCTION *op)
(void) list_append(ip, instruction(Op_field_assign));
ip->lasti->field_assign = (Func_ptr) 0;
tp->target_assign = ip->lasti;
+ } else if (tp->opcode == Op_subscript_lhs) {
+ (void) list_append(ip, instruction(Op_subscript_assign));
}
return ip;
@@ -4795,10 +5285,8 @@ optimize_assignment(INSTRUCTION *exp)
i2 = NULL;
i1 = exp->lasti;
- if ( ! do_optimize
- || ( i1->opcode != Op_assign
- && i1->opcode != Op_field_assign)
- )
+ if ( i1->opcode != Op_assign
+ && i1->opcode != Op_field_assign)
return list_append(exp, instruction(Op_pop));
for (i2 = exp->nexti; i2 != i1; i2 = i2->nexti) {
@@ -4961,7 +5449,11 @@ mk_getline(INSTRUCTION *op, INSTRUCTION *var, INSTRUCTION *redir, int redirtype)
asgn->assign_ctxt = op->opcode;
asgn->field_assign = (Func_ptr) 0; /* determined at run time */
tp->target_assign = asgn;
+ } else if (tp->opcode == Op_subscript_lhs) {
+ asgn = instruction(Op_subscript_assign);
+ asgn->assign_ctxt = op->opcode;
}
+
if (redir != NULL) {
ip = list_merge(redir, var);
(void) list_append(ip, op);
@@ -4972,7 +5464,7 @@ mk_getline(INSTRUCTION *op, INSTRUCTION *var, INSTRUCTION *redir, int redirtype)
else
ip = list_create(op);
op->into_var = (var != NULL);
- op->redir_type = (redir != NULL) ? redirtype : 0;
+ op->redir_type = (redir != NULL) ? redirtype : redirect_none;
return (asgn == NULL ? ip : list_append(ip, asgn));
}
@@ -5023,7 +5515,7 @@ mk_for_loop(INSTRUCTION *forp, INSTRUCTION *init, INSTRUCTION *cond,
if (init != NULL)
ip = list_merge(init, ip);
- if (do_profiling) {
+ if (do_pretty_print) {
(void) list_append(ip, instruction(Op_exec_count));
(forp + 1)->forloop_cond = pp_cond;
(forp + 1)->forloop_body = ip->lasti;
@@ -5045,7 +5537,7 @@ mk_for_loop(INSTRUCTION *forp, INSTRUCTION *init, INSTRUCTION *cond,
ret = list_append(ip, tbreak);
fix_break_continue(ret, tbreak, tcont);
- if (do_profiling) {
+ if (do_pretty_print) {
forp->target_break = tbreak;
forp->target_continue = tcont;
ret = list_prepend(ret, forp);
@@ -5146,7 +5638,7 @@ mk_expression_list(INSTRUCTION *list, INSTRUCTION *s1)
*/
static int
-count_expressions(INSTRUCTION **list, int isarg)
+count_expressions(INSTRUCTION **list, bool isarg)
{
INSTRUCTION *expr;
INSTRUCTION *r = NULL;
@@ -5262,13 +5754,13 @@ check_special(const char *name)
int low, high, mid;
int i;
#if 'a' == 0x81 /* it's EBCDIC */
- static int did_sort = FALSE;
+ static bool did_sort = false;
if (! did_sort) {
qsort((void *) tokentab,
sizeof(tokentab) / sizeof(tokentab[0]),
sizeof(tokentab[0]), tokcompare);
- did_sort = TRUE;
+ did_sort = true;
}
#endif
@@ -5340,3 +5832,95 @@ one_line_close(int fd)
return ret;
}
+
+/* lookup_builtin --- find a builtin function or return NULL */
+
+builtin_func_t
+lookup_builtin(const char *name)
+{
+ int mid = check_special(name);
+
+ if (mid == -1 || tokentab[mid].class != LEX_BUILTIN)
+ return NULL;
+#ifdef HAVE_MPFR
+ if (do_mpfr)
+ return tokentab[mid].ptr2;
+#endif
+
+ return tokentab[mid].ptr;
+}
+
+/* install_builtins --- add built-in functions to FUNCTAB */
+
+void
+install_builtins(void)
+{
+ int i, j;
+
+ j = sizeof(tokentab) / sizeof(tokentab[0]);
+ for (i = 0; i < j; i++) {
+ if ( tokentab[i].class == LEX_BUILTIN
+ && (tokentab[i].flags & DEBUG_USE) == 0) {
+ (void) install_symbol(tokentab[i].operator, Node_builtin_func);
+ }
+ }
+}
+
+/*
+ * 9/2014: Gawk cannot use <ctype.h> isalpha or isalnum when
+ * parsing the program since that can let through non-English
+ * letters. So, we supply our own. !@#$%^&*()-ing locales!
+ */
+
+/* is_alpha --- return true if c is an English letter */
+
+/*
+ * The scene of the murder was grisly to look upon. When the inspector
+ * arrived, the sergeant turned to him and said, "Another programmer stabbed
+ * in the back. He never knew what happened."
+ *
+ * The inspector replied, "Looks like the MO of isalpha, and his even meaner
+ * big brother, isalnum. The Locale brothers." The sergeant merely
+ * shuddered in horror.
+ */
+
+bool
+is_alpha(int c)
+{
+#ifdef I_DONT_KNOW_WHAT_IM_DOING
+ return isalpha(c);
+#else /* ! I_DONT_KNOW_WHAT_IM_DOING */
+ switch (c) {
+ 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':
+ 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':
+ return true;
+ }
+ return false;
+#endif /* ! I_DONT_KNOW_WHAT_IM_DOING */
+}
+
+/* is_alnum --- return true for alphanumeric, English only letters */
+
+bool
+is_alnum(int c)
+{
+ /* digit test is good for EBCDIC too. so there. */
+ return (is_alpha(c) || ('0' <= c && c <= '9'));
+}
+
+
+/* is_identchar --- return true if c can be in an identifier */
+
+bool
+is_identchar(int c)
+{
+ return (is_alnum(c) || c == '_');
+}
diff --git a/awklib/ChangeLog b/awklib/ChangeLog
index 2ae225be..bede4234 100644
--- a/awklib/ChangeLog
+++ b/awklib/ChangeLog
@@ -1,3 +1,43 @@
+2014-11-05 Juergen Kahrs <juergen.kahrs@googlemail.com>
+
+ * Makefile.am (AWKPROG): Add quotes around the name in case the
+ build dir has spaces in it.
+
+2014-10-17 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (stamp-eg): Use explicit ./extract.awk to avoid
+ assumptions about AWKPATH in the environment.
+
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.1: Release tar ball made.
+
+2014-03-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (clean-local): Clean up .dSYM directories for Mac OS X.
+ Thanks to Hermann Piefer for the suggestion.
+
+2013-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.0: Release tar ball made.
+
+2013-02-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (AWKPROG): Add definition and conditional for
+ cross compiling. Thanks to Juergen Kahrs.
+
+2013-01-08 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * eg/lib/inplace.awk: Add new file generated from doc/gawk.texi.
+
+2012-12-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.2: Release tar ball made.
+
+2012-03-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.1: Release tar ball made.
+
2011-06-24 Arnold D. Robbins <arnold@skeeve.com>
* Makefile.am (EXTRA_DIST): Add ChangeLog.0.
diff --git a/awklib/Makefile.am b/awklib/Makefile.am
index 4ff14036..27bb269f 100644
--- a/awklib/Makefile.am
+++ b/awklib/Makefile.am
@@ -26,7 +26,12 @@
EXTRA_DIST = ChangeLog ChangeLog.0 extract.awk eg $(srcdir)/stamp-eg
# With some locales, the script extract.awk fails.
# So we fix the locale to some sensible value.
-AWKPROG = LC_ALL=C LANG=C $(abs_top_builddir)/gawk$(EXEEXT)
+
+if TEST_CROSS_COMPILE
+AWKPROG = LC_ALL=C LANG=C awk$(EXEEXT)
+else
+AWKPROG = LC_ALL=C LANG=C "$(abs_top_builddir)/gawk$(EXEEXT)"
+endif
# Get config.h from the build directory and custom.h from the source directory.
AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)
@@ -34,13 +39,12 @@ 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: $(srcdir)/stamp-eg $(AUXPROGS) igawk $(AUXAWK)
+all: $(srcdir)/stamp-eg $(AUXPROGS) $(AUXAWK)
install-exec-hook: $(AUXAWK)
$(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
@@ -52,21 +56,21 @@ install-exec-hook: $(AUXAWK)
# 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
+ rm -f $(AUXAWK) *.exe
rm -fr eg.old
+ rm -fr grcat.dSYM pwcat.dSYM
$(srcdir)/stamp-eg: $(srcdir)/../doc/gawk.texi $(srcdir)/../doc/gawkinet.texi
cd $(srcdir) && \
rm -fr eg && \
rm -fr stamp-eg && \
- $(AWKPROG) -f extract.awk ../doc/gawk.texi ../doc/gawkinet.texi
+ $(AWKPROG) -f ./extract.awk ../doc/gawk.texi ../doc/gawkinet.texi
@echo 'some makes are stupid and will not check a directory' > $(srcdir)/stamp-eg
@echo 'against a file, so this file is a place holder. gack.' >> $(srcdir)/stamp-eg
-$(srcdir)/eg/lib/pwcat.c $(srcdir)/eg/lib/grcat.c $(srcdir)/eg/prog/igawk.sh \
+$(srcdir)/eg/lib/pwcat.c $(srcdir)/eg/lib/grcat.c \
$(srcdir)/eg/lib/passwdawk.in $(srcdir)/eg/lib/groupawk.in: stamp-eg; @:
pwcat$(EXEEXT): $(srcdir)/eg/lib/pwcat.c
@@ -75,9 +79,6 @@ pwcat$(EXEEXT): $(srcdir)/eg/lib/pwcat.c
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
diff --git a/awklib/Makefile.in b/awklib/Makefile.in
index 01511c36..b4b887a1 100644
--- a/awklib/Makefile.in
+++ b/awklib/Makefile.in
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
+# Copyright (C) 1994-2013 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.
@@ -38,8 +37,52 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
-
VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
@@ -58,19 +101,19 @@ build_triplet = @build@
host_triplet = @host@
pkglibexec_PROGRAMS = pwcat$(EXEEXT) grcat$(EXEEXT)
subdir = awklib
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp ChangeLog
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/arch.m4 \
$(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/gettext.m4 \
$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
- $(top_srcdir)/m4/intmax_t.m4 $(top_srcdir)/m4/inttypes_h.m4 \
$(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/lcmessage.m4 \
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libsigsegv.m4 \
- $(top_srcdir)/m4/longlong.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/longlong.m4 $(top_srcdir)/m4/mpfr.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/noreturn.m4 \
$(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
$(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/socket.m4 \
- $(top_srcdir)/m4/stdint_h.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)
@@ -78,7 +121,7 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
-am__installdirs = "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(bindir)"
+am__installdirs = "$(DESTDIR)$(pkglibexecdir)"
PROGRAMS = $(pkglibexec_PROGRAMS)
nodist_grcat_OBJECTS = grcat.$(OBJEXT)
grcat_OBJECTS = $(nodist_grcat_OBJECTS)
@@ -86,38 +129,58 @@ grcat_LDADD = $(LDADD)
nodist_pwcat_OBJECTS = pwcat.$(OBJEXT)
pwcat_OBJECTS = $(nodist_pwcat_OBJECTS)
pwcat_LDADD = $(LDADD)
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
- *) f=$$p;; \
- esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
- srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
- for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
- for p in $$list; do echo "$$p $$p"; done | \
- sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
- $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
- if (++n[$$2] == $(am__install_max)) \
- { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
- END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
- sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
- sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-SCRIPTS = $(bin_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
SOURCES = $(nodist_grcat_SOURCES) $(nodist_pwcat_SOURCES)
DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -125,6 +188,7 @@ pkgdatadir = $(datadir)/awk
pkglibexecdir = $(libexecdir)/awk
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
@@ -142,6 +206,7 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
+GAWKLIBEXT = @GAWKLIBEXT@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
@@ -157,6 +222,7 @@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
LDFLAGS = @LDFLAGS@
LIBICONV = @LIBICONV@
LIBINTL = @LIBINTL@
+LIBMPFR = @LIBMPFR@
LIBOBJS = @LIBOBJS@
LIBREADLINE = @LIBREADLINE@
LIBS = @LIBS@
@@ -182,6 +248,7 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
POSUB = @POSUB@
+SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SOCKET_LIBS = @SOCKET_LIBS@
@@ -198,6 +265,7 @@ abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
+acl_shlibext = @acl_shlibext@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -232,25 +300,27 @@ mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
+pkgextensiondir = @pkgextensiondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
EXTRA_DIST = ChangeLog ChangeLog.0 extract.awk eg $(srcdir)/stamp-eg
+@TEST_CROSS_COMPILE_FALSE@AWKPROG = LC_ALL=C LANG=C "$(abs_top_builddir)/gawk$(EXEEXT)"
# With some locales, the script extract.awk fails.
# So we fix the locale to some sensible value.
-AWKPROG = LC_ALL=C LANG=C $(abs_top_builddir)/gawk$(EXEEXT)
+@TEST_CROSS_COMPILE_TRUE@AWKPROG = LC_ALL=C LANG=C awk$(EXEEXT)
# Get config.h from the build directory and custom.h from the source directory.
AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)
-bin_SCRIPTS = igawk
AUXAWK = passwd.awk group.awk
nodist_grcat_SOURCES = grcat.c
nodist_pwcat_SOURCES = pwcat.c
@@ -290,14 +360,18 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
install-pkglibexecPROGRAMS: $(pkglibexec_PROGRAMS)
@$(NORMAL_INSTALL)
- test -z "$(pkglibexecdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibexecdir)"
@list='$(pkglibexec_PROGRAMS)'; test -n "$(pkglibexecdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibexecdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkglibexecdir)" || exit 1; \
+ fi; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
- while read p p1; do if test -f $$p; \
- then echo "$$p"; echo "$$p"; else :; fi; \
+ while read p p1; do if test -f $$p \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
done | \
- sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
@@ -318,47 +392,14 @@ uninstall-pkglibexecPROGRAMS:
@list='$(pkglibexec_PROGRAMS)'; test -n "$(pkglibexecdir)" || list=; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
- -e 's/$$/$(EXEEXT)/' `; \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(pkglibexecdir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(pkglibexecdir)" && rm -f $$files
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)'; test -n "$(bindir)" || list=; \
- for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
- done | \
- sed -e 'p;s,.*/,,;n' \
- -e 'h;s|.*|.|' \
- -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
- $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
- { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
- if ($$2 == $$4) { files[d] = files[d] " " $$1; \
- if (++n[d] == $(am__install_max)) { \
- print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
- else { print "f", d "/" $$4, $$1 } } \
- END { for (d in files) print "f", d, files[d] }' | \
- while read type dir files; do \
- if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
- test -z "$$files" || { \
- echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
- $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
- } \
- ; done
-
-uninstall-binSCRIPTS:
- @$(NORMAL_UNINSTALL)
- @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
- files=`for p in $$list; do echo "$$p"; done | \
- sed -e 's,.*/,,;$(transform)'`; \
- test -n "$$list" || exit 0; \
- echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
- cd "$(DESTDIR)$(bindir)" && rm -f $$files
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -370,39 +411,28 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwcat.Po@am__quote@
.c.o:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
-
-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; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
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; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
+ $(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
@@ -414,15 +444,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$$unique; \
fi; \
fi
-ctags: CTAGS
-CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- 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; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
@@ -431,6 +457,21 @@ GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
@@ -467,9 +508,9 @@ distdir: $(DISTFILES)
done
check-am: all-am
check: check-am
-all-am: Makefile $(PROGRAMS) $(SCRIPTS)
+all-am: Makefile $(PROGRAMS)
installdirs:
- for dir in "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(bindir)"; do \
+ for dir in "$(DESTDIR)$(pkglibexecdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
@@ -482,10 +523,15 @@ install-am: all-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
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
mostlyclean-generic:
clean-generic:
@@ -526,7 +572,7 @@ install-dvi: install-dvi-am
install-dvi-am:
-install-exec-am: install-binSCRIPTS install-pkglibexecPROGRAMS
+install-exec-am: install-pkglibexecPROGRAMS
@$(NORMAL_INSTALL)
$(MAKE) $(AM_MAKEFLAGS) install-exec-hook
install-html: install-html-am
@@ -566,16 +612,15 @@ ps: ps-am
ps-am:
-uninstall-am: uninstall-binSCRIPTS uninstall-local \
- uninstall-pkglibexecPROGRAMS
+uninstall-am: uninstall-local uninstall-pkglibexecPROGRAMS
.MAKE: install-am install-exec-am install-strip
-.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-dvi \
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-local clean-pkglibexecPROGRAMS cscopelist-am ctags \
+ ctags-am distclean distclean-compile distclean-generic \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-exec-hook \
install-html install-html-am install-info install-info-am \
install-man install-pdf install-pdf-am \
@@ -583,11 +628,11 @@ uninstall-am: uninstall-binSCRIPTS uninstall-local \
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-local uninstall-pkglibexecPROGRAMS
+ tags tags-am uninstall uninstall-am uninstall-local \
+ uninstall-pkglibexecPROGRAMS
-all: $(srcdir)/stamp-eg $(AUXPROGS) igawk $(AUXAWK)
+all: $(srcdir)/stamp-eg $(AUXPROGS) $(AUXAWK)
install-exec-hook: $(AUXAWK)
$(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
@@ -599,21 +644,21 @@ install-exec-hook: $(AUXAWK)
# 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
+ rm -f $(AUXAWK) *.exe
rm -fr eg.old
+ rm -fr grcat.dSYM pwcat.dSYM
$(srcdir)/stamp-eg: $(srcdir)/../doc/gawk.texi $(srcdir)/../doc/gawkinet.texi
cd $(srcdir) && \
rm -fr eg && \
rm -fr stamp-eg && \
- $(AWKPROG) -f extract.awk ../doc/gawk.texi ../doc/gawkinet.texi
+ $(AWKPROG) -f ./extract.awk ../doc/gawk.texi ../doc/gawkinet.texi
@echo 'some makes are stupid and will not check a directory' > $(srcdir)/stamp-eg
@echo 'against a file, so this file is a place holder. gack.' >> $(srcdir)/stamp-eg
-$(srcdir)/eg/lib/pwcat.c $(srcdir)/eg/lib/grcat.c $(srcdir)/eg/prog/igawk.sh \
+$(srcdir)/eg/lib/pwcat.c $(srcdir)/eg/lib/grcat.c \
$(srcdir)/eg/lib/passwdawk.in $(srcdir)/eg/lib/groupawk.in: stamp-eg; @:
pwcat$(EXEEXT): $(srcdir)/eg/lib/pwcat.c
@@ -622,9 +667,6 @@ pwcat$(EXEEXT): $(srcdir)/eg/lib/pwcat.c
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
diff --git a/awklib/eg/data/BBS-list b/awklib/eg/data/BBS-list
deleted file mode 100644
index 1007417f..00000000
--- a/awklib/eg/data/BBS-list
+++ /dev/null
@@ -1,11 +0,0 @@
-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
diff --git a/awklib/eg/data/mail-list b/awklib/eg/data/mail-list
new file mode 100644
index 00000000..37ff350a
--- /dev/null
+++ b/awklib/eg/data/mail-list
@@ -0,0 +1,11 @@
+Amelia 555-5553 amelia.zodiacusque@gmail.com F
+Anthony 555-3412 anthony.asserturo@hotmail.com A
+Becky 555-7685 becky.algebrarum@gmail.com A
+Bill 555-1675 bill.drowning@hotmail.com A
+Broderick 555-0542 broderick.aliquotiens@yahoo.com R
+Camilla 555-2912 camilla.infusarum@skynet.be R
+Fabius 555-1234 fabius.undevicesimus@ucb.edu F
+Julie 555-6699 julie.perscrutabor@skeeve.com F
+Martin 555-6480 martin.codicibus@hotmail.com A
+Samuel 555-3430 samuel.lanceolis@shu.edu A
+Jean-Paul 555-2127 jeanpaul.campanorum@nyu.edu R
diff --git a/awklib/eg/lib/ctime.awk b/awklib/eg/lib/ctime.awk
index f37856c6..cea25b7a 100644
--- a/awklib/eg/lib/ctime.awk
+++ b/awklib/eg/lib/ctime.awk
@@ -5,6 +5,7 @@
function ctime(ts, format)
{
format = "%a %b %e %H:%M:%S %Z %Y"
+
if (ts == 0)
ts = systime() # use current time as default
return strftime(format, ts)
diff --git a/awklib/eg/lib/div.awk b/awklib/eg/lib/div.awk
new file mode 100644
index 00000000..5939024d
--- /dev/null
+++ b/awklib/eg/lib/div.awk
@@ -0,0 +1,17 @@
+# div --- do integer division
+
+#
+# Arnold Robbins, arnold@skeeve.com, Public Domain
+# July, 2014
+
+function div(numerator, denominator, result)
+{
+ split("", result)
+
+ numerator = int(numerator)
+ denominator = int(denominator)
+ result["quotient"] = int(numerator / denominator)
+ result["remainder"] = int(numerator % denominator)
+
+ return 0.0
+}
diff --git a/awklib/eg/lib/ftrans.awk b/awklib/eg/lib/ftrans.awk
index 1709ac82..6461efff 100644
--- a/awklib/eg/lib/ftrans.awk
+++ b/awklib/eg/lib/ftrans.awk
@@ -1,4 +1,4 @@
-# ftrans.awk --- handle data file transitions
+# ftrans.awk --- handle datafile transitions
#
# user supplies beginfile() and endfile() functions
#
@@ -12,4 +12,4 @@ FNR == 1 {
beginfile(FILENAME)
}
-END { endfile(_filename_) }
+END { endfile(_filename_) }
diff --git a/awklib/eg/lib/getopt.awk b/awklib/eg/lib/getopt.awk
index 0b81aa09..6b1f4c50 100644
--- a/awklib/eg/lib/getopt.awk
+++ b/awklib/eg/lib/getopt.awk
@@ -17,7 +17,7 @@
# <c> a character representing the current option
# Private Data:
-# _opti -- index in multi-flag option, e.g., -abc
+# _opti -- index in multiflag option, e.g., -abc
function getopt(argc, argv, options, thisopt, i)
{
if (length(options) == 0) # no options given
@@ -38,8 +38,7 @@ function getopt(argc, argv, options, thisopt, i)
i = index(options, thisopt)
if (i == 0) {
if (Opterr)
- printf("%c -- invalid option\n",
- thisopt) > "/dev/stderr"
+ printf("%c -- invalid option\n", thisopt) > "/dev/stderr"
if (_opti >= length(argv[Optind])) {
Optind++
_opti = 0
@@ -70,7 +69,7 @@ BEGIN {
# test program
if (_getopt_test) {
while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
- printf("c = <%c>, optarg = <%s>\n",
+ printf("c = <%c>, Optarg = <%s>\n",
_go_c, Optarg)
printf("non-option arguments:\n")
for (; Optind < ARGC; Optind++)
diff --git a/awklib/eg/lib/gettime.awk b/awklib/eg/lib/gettime.awk
index 95f9c329..4cb56330 100644
--- a/awklib/eg/lib/gettime.awk
+++ b/awklib/eg/lib/gettime.awk
@@ -1,4 +1,4 @@
-# gettimeofday.awk --- get the time of day in a usable format
+# getlocaltime.awk --- get the time of day in a usable format
#
# Arnold Robbins, arnold@skeeve.com, Public Domain, May 1993
#
@@ -25,7 +25,7 @@
# time["weeknum"] -- week number, Sunday first day
# time["altweeknum"] -- week number, Monday first day
-function gettimeofday(time, ret, now, i)
+function getlocaltime(time, ret, now, i)
{
# get time once, avoids unnecessary system calls
now = systime()
diff --git a/awklib/eg/lib/grcat.c b/awklib/eg/lib/grcat.c
index ff2913a1..7d6b6a74 100644
--- a/awklib/eg/lib/grcat.c
+++ b/awklib/eg/lib/grcat.c
@@ -1,7 +1,7 @@
/*
* grcat.c
*
- * Generate a printable version of the group database
+ * Generate a printable version of the group database.
*/
/*
* Arnold Robbins, arnold@skeeve.com, May 1993
diff --git a/awklib/eg/lib/groupawk.in b/awklib/eg/lib/groupawk.in
index 0917b923..54a27f3d 100644
--- a/awklib/eg/lib/groupawk.in
+++ b/awklib/eg/lib/groupawk.in
@@ -5,8 +5,7 @@
# Revised October 2000
# Revised December 2010
-BEGIN \
-{
+BEGIN {
# Change to suit your system
_gr_awklib = "/usr/local/libexec/awk/"
}
@@ -39,8 +38,7 @@ function _gr_init( oldfs, oldrs, olddol0, grcat,
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
+ _gr_groupsbyuser[a[i]] = gr_groupsbyuser[a[i]] " " $1
else
_gr_groupsbyuser[a[i]] = $1
diff --git a/awklib/eg/lib/inplace.awk b/awklib/eg/lib/inplace.awk
new file mode 100644
index 00000000..6403a228
--- /dev/null
+++ b/awklib/eg/lib/inplace.awk
@@ -0,0 +1,14 @@
+# inplace --- load and invoke the inplace extension.
+
+@load "inplace"
+
+# Please set INPLACE_SUFFIX to make a backup copy. For example, you may
+# want to set INPLACE_SUFFIX to .bak on the command line or in a BEGIN rule.
+
+BEGINFILE {
+ inplace_begin(FILENAME, INPLACE_SUFFIX)
+}
+
+ENDFILE {
+ inplace_end(FILENAME, INPLACE_SUFFIX)
+}
diff --git a/awklib/eg/lib/noassign.awk b/awklib/eg/lib/noassign.awk
index 1f750edf..99227b37 100644
--- a/awklib/eg/lib/noassign.awk
+++ b/awklib/eg/lib/noassign.awk
@@ -7,7 +7,7 @@
function disable_assigns(argc, argv, i)
{
for (i = 1; i < argc; i++)
- if (argv[i] ~ /^[[:alpha:]_][[:alnum:]_]*=.*/)
+ if (argv[i] ~ /^[a-zA-Z_][a-zA-Z0-9_]*=.*/)
argv[i] = ("./" argv[i])
}
diff --git a/awklib/eg/lib/processarray.awk b/awklib/eg/lib/processarray.awk
new file mode 100644
index 00000000..79a86d1f
--- /dev/null
+++ b/awklib/eg/lib/processarray.awk
@@ -0,0 +1,12 @@
+function process_array(arr, name, process, do_arrays, i, new_name)
+{
+ for (i in arr) {
+ new_name = (name "[" i "]")
+ if (isarray(arr[i])) {
+ if (do_arrays)
+ @process(new_name, arr[i])
+ process_array(arr[i], new_name, process, do_arrays)
+ } else
+ @process(new_name, arr[i])
+ }
+}
diff --git a/awklib/eg/lib/pwcat.c b/awklib/eg/lib/pwcat.c
index 910e0329..934ef34e 100644
--- a/awklib/eg/lib/pwcat.c
+++ b/awklib/eg/lib/pwcat.c
@@ -1,7 +1,7 @@
/*
* pwcat.c
*
- * Generate a printable version of the password database
+ * Generate a printable version of the password database.
*/
/*
* Arnold Robbins, arnold@skeeve.com, May 1993
diff --git a/awklib/eg/lib/quicksort.awk b/awklib/eg/lib/quicksort.awk
index 7a635d6f..3ba2d6e3 100644
--- a/awklib/eg/lib/quicksort.awk
+++ b/awklib/eg/lib/quicksort.awk
@@ -1,8 +1,9 @@
# quicksort.awk --- Quicksort algorithm, with user-supplied
# comparison function
#
-# Arnold Robbins, arnoldskeeve.com, Public Domain
+# Arnold Robbins, arnold@skeeve.com, Public Domain
# January 2009
+
# quicksort --- C.A.R. Hoare's quick sort algorithm. See Wikipedia
# or almost any algorithms or computer science text
#
@@ -25,7 +26,7 @@ function quicksort(data, left, right, less_than, i, last)
# quicksort_swap --- helper function for quicksort, should really be inline
-function quicksort_swap(data, i, j, temp)
+function quicksort_swap(data, i, j, temp)
{
temp = data[i]
data[i] = data[j]
diff --git a/awklib/eg/lib/readable.awk b/awklib/eg/lib/readable.awk
index 6942dcca..37970a82 100644
--- a/awklib/eg/lib/readable.awk
+++ b/awklib/eg/lib/readable.awk
@@ -6,7 +6,7 @@
BEGIN {
for (i = 1; i < ARGC; i++) {
- if (ARGV[i] ~ /^[[:alpha:]_][[:alnum:]_]*=.*/ \
+ if (ARGV[i] ~ /^[a-zA-Z_][a-zA-Z0-9_]*=.*/ \
|| ARGV[i] == "-" || ARGV[i] == "/dev/stdin")
continue # assignment or standard input
else if ((getline junk < ARGV[i]) < 0) # unreadable
diff --git a/awklib/eg/lib/readfile.awk b/awklib/eg/lib/readfile.awk
new file mode 100644
index 00000000..9137b26d
--- /dev/null
+++ b/awklib/eg/lib/readfile.awk
@@ -0,0 +1,15 @@
+# readfile.awk --- read an entire file at once
+#
+# Original idea by Denis Shirokov, cosmogen@gmail.com, April 2013
+#
+
+function readfile(file, tmp, save_rs)
+{
+ save_rs = RS
+ RS = "^$"
+ getline tmp < file
+ close(file)
+ RS = save_rs
+
+ return tmp
+}
diff --git a/awklib/eg/lib/shellquote.awk b/awklib/eg/lib/shellquote.awk
new file mode 100644
index 00000000..cd943dc7
--- /dev/null
+++ b/awklib/eg/lib/shellquote.awk
@@ -0,0 +1,22 @@
+# shell_quote --- quote an argument for passing to the shell
+#
+# Michael Brennan
+# brennan@madronabluff.com
+# September 2014
+
+function shell_quote(s, # parameter
+ SINGLE, QSINGLE, i, X, n, ret) # locals
+{
+ if (s == "")
+ return "\"\""
+
+ SINGLE = "\x27" # single quote
+ QSINGLE = "\"\x27\""
+ n = split(s, X, SINGLE)
+
+ ret = SINGLE X[1] SINGLE
+ for (i = 2; i <= n; i++)
+ ret = ret QSINGLE SINGLE X[i] SINGLE
+
+ return ret
+}
diff --git a/awklib/eg/lib/strtonum.awk b/awklib/eg/lib/strtonum.awk
index a56ab50c..783496e4 100644
--- a/awklib/eg/lib/strtonum.awk
+++ b/awklib/eg/lib/strtonum.awk
@@ -3,8 +3,9 @@
#
# Arnold Robbins, arnold@skeeve.com, Public Domain
# February, 2004
+# Revised June, 2014
-function mystrtonum(str, ret, chars, n, i, k, c)
+function mystrtonum(str, ret, n, i, k, c)
{
if (str ~ /^0[0-7]*$/) {
# octal
@@ -12,12 +13,13 @@ function mystrtonum(str, ret, chars, n, i, k, c)
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
+ # index() returns 0 if c not in string,
+ # includes c == "0"
+ k = index("1234567", c)
ret = ret * 8 + k
}
- } else if (str ~ /^0[xX][[:xdigit:]]+/) {
+ } else if (str ~ /^0[xX][[:xdigit:]]+$/) {
# hexadecimal
str = substr(str, 3) # lop off leading 0x
n = length(str)
@@ -25,10 +27,9 @@ function mystrtonum(str, ret, chars, n, i, k, c)
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
+ # index() returns 0 if c not in string,
+ # includes c == "0"
+ k = index("123456789abcdef", c)
ret = ret * 16 + k
}
@@ -50,8 +51,8 @@ function mystrtonum(str, ret, chars, n, i, k, c)
# a[5] = "123.45"
# a[6] = "1.e3"
# a[7] = "1.32"
-# a[7] = "1.32E2"
-#
+# a[8] = "1.32E2"
+#
# for (i = 1; i in a; i++)
# print a[i], strtonum(a[i]), mystrtonum(a[i])
# }
diff --git a/awklib/eg/misc/arraymax.awk b/awklib/eg/misc/arraymax.awk
index 20dd1768..64197f56 100644
--- a/awklib/eg/misc/arraymax.awk
+++ b/awklib/eg/misc/arraymax.awk
@@ -1,10 +1,10 @@
{
- if ($1 > max)
- max = $1
- arr[$1] = $0
+ if ($1 > max)
+ max = $1
+ arr[$1] = $0
}
END {
- for (x = 1; x <= max; x++)
- print arr[x]
+ for (x = 1; x <= max; x++)
+ print arr[x]
}
diff --git a/awklib/eg/misc/findpat.awk b/awklib/eg/misc/findpat.awk
index e9bef9ea..9d799434 100644
--- a/awklib/eg/misc/findpat.awk
+++ b/awklib/eg/misc/findpat.awk
@@ -1,10 +1,9 @@
{
- if ($1 == "FIND")
- regex = $2
- else {
- where = match($0, regex)
- if (where != 0)
- print "Match of", regex, "found at",
- where, "in", $0
+ if ($1 == "FIND")
+ regex = $2
+ else {
+ where = match($0, regex)
+ if (where != 0)
+ print "Match of", regex, "found at", where, "in", $0
}
}
diff --git a/awklib/eg/prog/alarm.awk b/awklib/eg/prog/alarm.awk
index 53563d15..59630ea8 100644
--- a/awklib/eg/prog/alarm.awk
+++ b/awklib/eg/prog/alarm.awk
@@ -1,6 +1,6 @@
# alarm.awk --- set an alarm
#
-# Requires gettimeofday() library function
+# Requires getlocaltime() library function
#
# Arnold Robbins, arnold@skeeve.com, Public Domain
# May 1993
@@ -8,8 +8,7 @@
# usage: alarm time [ "message" [ count [ delay ] ] ]
-BEGIN \
-{
+BEGIN {
# Initial argument sanity checking
usage1 = "usage: alarm time ['message' [count [delay]]]"
usage2 = sprintf("\t(%s) time ::= hh:mm", ARGV[1])
@@ -53,7 +52,7 @@ BEGIN \
minute = atime[2] + 0 # force numeric
# get current broken down time
- gettimeofday(now)
+ getlocaltime(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.,
@@ -71,7 +70,7 @@ BEGIN \
# how long to sleep for
naptime = target - current
if (naptime <= 0) {
- print "time is in the past!" > "/dev/stderr"
+ print "alarm: time is in the past!" > "/dev/stderr"
exit 1
}
# zzzzzz..... go away if interrupted
diff --git a/awklib/eg/prog/cut.awk b/awklib/eg/prog/cut.awk
index fb4717c1..080279bc 100644
--- a/awklib/eg/prog/cut.awk
+++ b/awklib/eg/prog/cut.awk
@@ -12,16 +12,13 @@
#
# Requires getopt() and join() library functions
-function usage( e1, e2)
+function usage()
{
- e1 = "usage: cut [-f list] [-d c] [-s] [files...]"
- e2 = "usage: cut [-c list] [files...]"
- print e1 > "/dev/stderr"
- print e2 > "/dev/stderr"
+ print("usage: cut [-f list] [-d c] [-s] [files...]") > "/dev/stderr"
+ print("usage: cut [-c list] [files...]") > "/dev/stderr"
exit 1
}
-BEGIN \
-{
+BEGIN {
FS = "\t" # default
OFS = FS
while ((c = getopt(ARGC, ARGV, "sf:c:d:")) != -1) {
@@ -34,7 +31,7 @@ BEGIN \
OFS = ""
} else if (c == "d") {
if (length(Optarg) > 1) {
- printf("Using first character of %s" \
+ printf("cut: using first character of %s" \
" for delimiter\n", Optarg) > "/dev/stderr"
Optarg = substr(Optarg, 1, 1)
}
@@ -43,7 +40,7 @@ BEGIN \
if (FS == " ") # defeat awk semantics
FS = "[ ]"
} else if (c == "s")
- suppress++
+ suppress = 1
else
usage()
}
@@ -75,7 +72,7 @@ function set_fieldlist( n, m, i, j, k, f, g)
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",
+ printf("cut: bad field list: %s\n",
f[i]) > "/dev/stderr"
exit 1
}
@@ -86,7 +83,7 @@ function set_fieldlist( n, m, i, j, k, f, g)
}
nfields = j - 1
}
-function set_charlist( field, i, j, f, g, t,
+function set_charlist( field, i, j, f, g, n, m, t,
filler, last, len)
{
field = 1 # count total fields
@@ -96,7 +93,7 @@ function set_charlist( field, i, j, f, g, t,
if (index(f[i], "-") != 0) { # range
m = split(f[i], g, "-")
if (m != 2 || g[1] >= g[2]) {
- printf("bad character list: %s\n",
+ printf("cut: bad character list: %s\n",
f[i]) > "/dev/stderr"
exit 1
}
@@ -126,7 +123,7 @@ function set_charlist( field, i, j, f, g, t,
nfields = j - 1
}
{
- if (by_fields && suppress && index($0, FS) != 0)
+ if (by_fields && suppress && index($0, FS) == 0)
next
for (i = 1; i <= nfields; i++) {
diff --git a/awklib/eg/prog/egrep.awk b/awklib/eg/prog/egrep.awk
index 56d199c8..a4165a90 100644
--- a/awklib/eg/prog/egrep.awk
+++ b/awklib/eg/prog/egrep.awk
@@ -88,16 +88,12 @@ function endfile(file)
print
}
}
-END \
-{
- if (total == 0)
- exit 1
- exit 0
+END {
+ exit (total == 0)
}
-function usage( e)
+function usage()
{
- e = "Usage: egrep [-csvil] [-e pat] [files ...]"
- e = e "\n\tegrep [-csvil] pat [files ...]"
- print e > "/dev/stderr"
+ print("Usage: egrep [-csvil] [-e pat] [files ...]") > "/dev/stderr"
+ print("\n\tegrep [-csvil] pat [files ...]") > "/dev/stderr"
exit 1
}
diff --git a/awklib/eg/prog/extract.awk b/awklib/eg/prog/extract.awk
index dc105728..24f40ce5 100644
--- a/awklib/eg/prog/extract.awk
+++ b/awklib/eg/prog/extract.awk
@@ -1,5 +1,4 @@
-# extract.awk --- extract files and run programs
-# from texinfo files
+# extract.awk --- extract files and run programs from texinfo files
#
# Arnold Robbins, arnold@skeeve.com, Public Domain
# May 1993
@@ -7,10 +6,9 @@
BEGIN { IGNORECASE = 1 }
-/^@c(omment)?[ \t]+system/ \
-{
+/^@c(omment)?[ \t]+system/ {
if (NF < 3) {
- e = (FILENAME ":" FNR)
+ e = ("extract: " FILENAME ":" FNR)
e = (e ": badly formed `system' line")
print e > "/dev/stderr"
next
@@ -19,15 +17,14 @@ BEGIN { IGNORECASE = 1 }
$2 = ""
stat = system($0)
if (stat != 0) {
- e = (FILENAME ":" FNR)
+ e = ("extract: " FILENAME ":" FNR)
e = (e ": warning: system returned " stat)
print e > "/dev/stderr"
}
}
-/^@c(omment)?[ \t]+file/ \
-{
+/^@c(omment)?[ \t]+file/ {
if (NF != 3) {
- e = (FILENAME ":" FNR ": badly formed `file' line")
+ e = ("extract: " FILENAME ":" FNR ": badly formed `file' line")
print e > "/dev/stderr"
next
}
@@ -65,8 +62,8 @@ BEGIN { IGNORECASE = 1 }
}
function unexpected_eof()
{
- printf("%s:%d: unexpected EOF or error\n",
- FILENAME, FNR) > "/dev/stderr"
+ printf("extract: %s:%d: unexpected EOF or error\n",
+ FILENAME, FNR) > "/dev/stderr"
exit 1
}
diff --git a/awklib/eg/prog/id.awk b/awklib/eg/prog/id.awk
index 8b60a245..b6061f9b 100644
--- a/awklib/eg/prog/id.awk
+++ b/awklib/eg/prog/id.awk
@@ -5,13 +5,14 @@
# Arnold Robbins, arnold@skeeve.com, Public Domain
# May 1993
# Revised February 1996
+# Revised May 2014
+# Revised September 2014
# output is:
# uid=12(foo) euid=34(bar) gid=3(baz) \
# egid=5(blat) groups=9(nine),2(two),1(one)
-BEGIN \
-{
+BEGIN {
uid = PROCINFO["uid"]
euid = PROCINFO["euid"]
gid = PROCINFO["gid"]
@@ -19,34 +20,22 @@ BEGIN \
printf("uid=%d", uid)
pw = getpwuid(uid)
- if (pw != "") {
- split(pw, a, ":")
- printf("(%s)", a[1])
- }
+ pr_first_field(pw)
if (euid != uid) {
printf(" euid=%d", euid)
pw = getpwuid(euid)
- if (pw != "") {
- split(pw, a, ":")
- printf("(%s)", a[1])
- }
+ pr_first_field(pw)
}
printf(" gid=%d", gid)
pw = getgrgid(gid)
- if (pw != "") {
- split(pw, a, ":")
- printf("(%s)", a[1])
- }
+ pr_first_field(pw)
if (egid != gid) {
printf(" egid=%d", egid)
pw = getgrgid(egid)
- if (pw != "") {
- split(pw, a, ":")
- printf("(%s)", a[1])
- }
+ pr_first_field(pw)
}
for (i = 1; ("group" i) in PROCINFO; i++) {
@@ -55,13 +44,18 @@ BEGIN \
group = PROCINFO["group" i]
printf("%d", group)
pw = getgrgid(group)
- if (pw != "") {
- split(pw, a, ":")
- printf("(%s)", a[1])
- }
+ pr_first_field(pw)
if (("group" (i+1)) in PROCINFO)
printf(",")
}
print ""
}
+
+function pr_first_field(str, a)
+{
+ if (str != "") {
+ split(str, a, ":")
+ printf("(%s)", a[1])
+ }
+}
diff --git a/awklib/eg/prog/igawk.sh b/awklib/eg/prog/igawk.sh
index 03d1c996..70edf606 100644
--- a/awklib/eg/prog/igawk.sh
+++ b/awklib/eg/prog/igawk.sh
@@ -115,7 +115,7 @@ BEGIN {
}
fpath = pathto($2)
if (fpath == "") {
- printf("igawk:%s:%d: cannot find %s\n",
+ printf("igawk: %s:%d: cannot find %s\n",
input[stackptr], FNR, $2) > "/dev/stderr"
continue
}
diff --git a/awklib/eg/prog/indirectcall.awk b/awklib/eg/prog/indirectcall.awk
index 3ecb2887..165b022a 100644
--- a/awklib/eg/prog/indirectcall.awk
+++ b/awklib/eg/prog/indirectcall.awk
@@ -27,7 +27,7 @@ function do_sort(first, last, compare, data, i, retval)
retval = data[1]
for (i = 2; i in data; i++)
retval = retval " " data[i]
-
+
return retval
}
# sort --- sort the data in ascending order and return it as a string
diff --git a/awklib/eg/prog/labels.awk b/awklib/eg/prog/labels.awk
index abf53c3b..3195809b 100644
--- a/awklib/eg/prog/labels.awk
+++ b/awklib/eg/prog/labels.awk
@@ -48,7 +48,6 @@ function printpage( i, j)
Count++
}
-END \
-{
+END {
printpage()
}
diff --git a/awklib/eg/prog/pi.awk b/awklib/eg/prog/pi.awk
new file mode 100644
index 00000000..3297beff
--- /dev/null
+++ b/awklib/eg/prog/pi.awk
@@ -0,0 +1,18 @@
+# pi.awk --- compute the digits of pi
+#
+# Katie Wasserman, katie@wass.net
+# August 2014
+
+BEGIN {
+ digits = 100000
+ two = 2 * 10 ^ digits
+ pi = two
+ for (m = digits * 4; m > 0; --m) {
+ d = m * 2 + 1
+ x = pi * m
+ div(x, d, result)
+ pi = result["quotient"]
+ pi = pi + two
+ }
+ print pi
+}
diff --git a/awklib/eg/prog/split.awk b/awklib/eg/prog/split.awk
index c907530b..b878fa50 100644
--- a/awklib/eg/prog/split.awk
+++ b/awklib/eg/prog/split.awk
@@ -4,8 +4,9 @@
#
# Arnold Robbins, arnold@skeeve.com, Public Domain
# May 1993
+# Revised slightly, May 2014
-# usage: split [-num] [file] [outname]
+# usage: split [-count] [file] [outname]
BEGIN {
outfile = "x" # default
@@ -14,14 +15,14 @@ BEGIN {
usage()
i = 1
- if (ARGV[i] ~ /^-[[:digit:]]+$/) {
+ if (i in ARGV && ARGV[i] ~ /^-[[:digit:]]+$/) {
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
+ i++ # skip datafile name
if (i in ARGV) {
outfile = ARGV[i]
ARGV[i] = ""
@@ -49,9 +50,8 @@ BEGIN {
}
print > out
}
-function usage( e)
+function usage()
{
- e = "usage: split [-num] [file] [outname]"
- print e > "/dev/stderr"
+ print("usage: split [-num] [file] [outname]") > "/dev/stderr"
exit 1
}
diff --git a/awklib/eg/prog/tee.awk b/awklib/eg/prog/tee.awk
index 639b9f80..fd9985f1 100644
--- a/awklib/eg/prog/tee.awk
+++ b/awklib/eg/prog/tee.awk
@@ -7,8 +7,7 @@
# May 1993
# Revised December 1995
-BEGIN \
-{
+BEGIN {
for (i = 1; i < ARGC; i++)
copy[i] = ARGV[i]
@@ -35,8 +34,7 @@ BEGIN \
print > copy[i]
print
}
-END \
-{
+END {
for (i in copy)
close(copy[i])
}
diff --git a/awklib/eg/prog/uniq.awk b/awklib/eg/prog/uniq.awk
index 990387ac..7dd16099 100644
--- a/awklib/eg/prog/uniq.awk
+++ b/awklib/eg/prog/uniq.awk
@@ -5,10 +5,9 @@
# Arnold Robbins, arnold@skeeve.com, Public Domain
# May 1993
-function usage( e)
+function usage()
{
- e = "Usage: uniq [-udc [-n]] [+n] [ in [ out ]]"
- print e > "/dev/stderr"
+ print("Usage: uniq [-udc [-n]] [+n] [ in [ out ]]") > "/dev/stderr"
exit 1
}
@@ -18,8 +17,7 @@ function usage( e)
# -n skip n fields
# +n skip n characters, skip fields first
-BEGIN \
-{
+BEGIN {
count = 1
outputfile = "/dev/stdout"
opts = "udc0:1:2:3:4:5:6:7:8:9:"
@@ -31,7 +29,7 @@ BEGIN \
else if (c == "c")
do_count++
else if (index("0123456789", c) != 0) {
- # getopt requires args to options
+ # getopt() requires args to options
# this messes us up for things like -5
if (Optarg ~ /^[[:digit:]]+$/)
fcount = (c Optarg) + 0
diff --git a/bisonfix.awk b/bisonfix.awk
index a759d25b..87fe9ee9 100644
--- a/bisonfix.awk
+++ b/bisonfix.awk
@@ -1,6 +1,6 @@
# bisonfix.awk --- tweak awkgram.c for stupid compilers.
-# Copyright (C) 2005, 2009 the Free Software Foundation, Inc.
+# Copyright (C) 2005, 2009, 2013 the Free Software Foundation, Inc.
#
# This file is part of GAWK, the GNU implementation of the
# AWK Programming Language.
@@ -19,22 +19,23 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-BEGIN { sfile = ARGV[1] ; delete ARGV[1] }
+BEGIN { sfile = ARGV[1] ; ARGV[1] = "-" ; ARGC = 2 }
-/^#if.*\\$/ {
- line = $0
- sub(/\\$/, "", line)
- getline line2
- while (line2 ~ /\\$/) {
- line = line line2
- sub(/\\$/, "", line)
- getline line2
- }
- line = line line2
- sub(/\\$/, "", line)
- print line
- next
-}
+# 2/2013: Comment this out to see if any system still needs it.
+# /^#if.*\\$/ {
+# line = $0
+# sub(/\\$/, "", line)
+# getline line2
+# while (line2 ~ /\\$/) {
+# line = line line2
+# sub(/\\$/, "", line)
+# getline line2
+# }
+# line = line line2
+# sub(/\\$/, "", line)
+# print line
+# next
+# }
/^#line.*y\.tab\.c/ { sub(/y.tab/, sfile) }
diff --git a/bootstrap.sh b/bootstrap.sh
index 54a97108..85cdd196 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -3,7 +3,7 @@
# bootstrap.sh --- touch relevant files to avoid out-of-date issues in
# Git sandboxes
-# Copyright (C) 2007, 2009, 2010, 2011 the Free Software Foundation, Inc.
+# Copyright (C) 2007, 2009-2014 the Free Software Foundation, Inc.
#
# This file is part of GAWK, the GNU implementation of the
# AWK Programming Language.
@@ -23,17 +23,21 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
touch aclocal.m4
+touch extension/aclocal.m4
find awklib -type f -print | xargs touch
sleep 1
touch configure
+touch extension/configure
sleep 2
touch configh.in
+touch extension/configh.in
sleep 1
touch test/Maketests
find . -name Makefile.in -print | xargs touch
+touch doc/gawk.texi # make later than gawktexi.in
+sleep 1
touch doc/*.info
touch po/*.gmo
touch po/stamp-po
touch awkgram.c
touch command.c
-touch version.c
diff --git a/builtin.c b/builtin.c
index 5bc1c023..38a974fc 100644
--- a/builtin.c
+++ b/builtin.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-2011 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-2015 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -73,7 +73,7 @@ extern void srandom(unsigned long seed);
extern NODE **args_array;
extern int max_args;
extern NODE **fields_arr;
-extern int output_is_tty;
+extern bool output_is_tty;
extern FILE *output_fp;
@@ -83,7 +83,7 @@ s1 = POP(); \
do { if (s1->type == Node_var_array) { \
DEREF(s2); \
fatal(_("attempt to use array `%s' in a scalar context"), array_vname(s1)); \
-}} while (FALSE)
+}} while (false)
/*
@@ -92,9 +92,6 @@ fatal(_("attempt to use array `%s' in a scalar context"), array_vname(s1)); \
*/
#define GAWK_RANDOM_MAX 0x7fffffffL
-static void efwrite(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
@@ -104,21 +101,35 @@ efwrite(const void *ptr,
FILE *fp,
const char *from,
struct redirect *rp,
- int flush)
+ bool flush)
{
errno = 0;
- if (fwrite(ptr, size, count, fp) != count)
+ if (rp != NULL) {
+ if (rp->output.gawk_fwrite(ptr, size, count, fp, rp->output.opaque) != count)
+ goto wrerror;
+ } else 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;
+ || (rp != NULL && (rp->flag & RED_NOBUF) != 0))) {
+ if (rp != NULL) {
+ rp->output.gawk_fflush(fp, rp->output.opaque);
+ if (rp->output.gawk_ferror(fp, rp->output.opaque))
+ goto wrerror;
+ } else {
+ fflush(fp);
+ if (ferror(fp))
+ goto wrerror;
+ }
}
return;
wrerror:
+ /* die silently on EPIPE to stdout */
+ if (fp == stdout && errno == EPIPE)
+ gawk_exit(EXIT_FATAL);
+
+ /* otherwise die verbosely */
fatal(_("%s to \"%s\" failed (%s)"), from,
rp ? rp->value : _("standard output"),
errno ? strerror(errno) : _("reason unknown"));
@@ -135,7 +146,7 @@ do_exp(int nargs)
tmp = POP_SCALAR();
if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
lintwarn(_("exp: received non-numeric argument"));
- d = force_number(tmp);
+ d = force_number(tmp)->numbr;
DEREF(tmp);
errno = 0;
res = exp(d);
@@ -156,9 +167,9 @@ static FILE *
stdfile(const char *name, size_t len)
{
if (len == 11) {
- if (STREQN(name, "/dev/stderr", 11))
+ if (strncmp(name, "/dev/stderr", 11) == 0)
return stderr;
- else if (STREQN(name, "/dev/stdout", 11))
+ else if (strncmp(name, "/dev/stdout", 11) == 0)
return stdout;
}
@@ -176,29 +187,45 @@ do_fflush(int nargs)
int status = 0;
const char *file;
- /* fflush() --- flush stdout */
+ /*
+ * November, 2012.
+ * It turns out that circa 2002, when BWK
+ * added fflush() and fflush("") to his awk, he made both of
+ * them flush everything.
+ *
+ * Now, with our inside agent getting ready to try to get fflush()
+ * standardized in POSIX, we are going to make our awk consistent
+ * with his. This should not really affect anyone, as flushing
+ * everything also flushes stdout.
+ *
+ * So. Once upon a time:
+ * fflush() --- flush stdout
+ * fflush("") --- flush everything
+ * Now, both calls flush everything.
+ */
+
+ /* fflush() */
if (nargs == 0) {
- if (output_fp != stdout)
- (void) fflush(output_fp);
- status = fflush(stdout);
+ status = flush_io();
return make_number((AWKNUM) status);
}
tmp = POP_STRING();
file = tmp->stptr;
- /* fflush("") --- flush all */
+ /* fflush("") */
if (tmp->stlen == 0) {
status = flush_io();
DEREF(tmp);
return make_number((AWKNUM) status);
}
+ /* fflush("/some/path") */
rp = getredirect(tmp->stptr, tmp->stlen);
status = -1;
if (rp != NULL) {
if ((rp->flag & (RED_WRITE|RED_APPEND)) == 0) {
- if (rp->flag & RED_PIPE)
+ if ((rp->flag & RED_PIPE) != 0)
warning(_("fflush: cannot flush: pipe `%s' opened for reading, not writing"),
file);
else
@@ -207,9 +234,9 @@ do_fflush(int nargs)
DEREF(tmp);
return make_number((AWKNUM) status);
}
- fp = rp->fp;
+ fp = rp->output.fp;
if (fp != NULL)
- status = fflush(fp);
+ status = rp->output.gawk_fflush(fp, rp->output.opaque);
} else if ((fp = stdfile(tmp->stptr, tmp->stlen)) != NULL) {
status = fflush(fp);
} else {
@@ -220,7 +247,6 @@ do_fflush(int nargs)
return make_number((AWKNUM) status);
}
-#if MBS_SUPPORT
/* strncasecmpmbs --- like strncasecmp (multibyte string version) */
int
@@ -300,14 +326,6 @@ index_multibyte_buffer(char* src, char* dest, int len)
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 */
@@ -318,15 +336,13 @@ do_index(int nargs)
const char *p1, *p2;
size_t l1, l2;
long ret;
-#if MBS_SUPPORT
- int do_single_byte = FALSE;
+ bool do_single_byte = false;
mbstate_t mbs1, mbs2;
if (gawk_mb_cur_max > 1) {
memset(& mbs1, 0, sizeof(mbstate_t));
memset(& mbs2, 0, sizeof(mbstate_t));
}
-#endif
POP_TWO_SCALARS(s1, s2);
@@ -356,7 +372,6 @@ do_index(int nargs)
goto out;
}
-#if MBS_SUPPORT
if (gawk_mb_cur_max > 1) {
s1 = force_wstring(s1);
s2 = force_wstring(s2);
@@ -367,14 +382,12 @@ do_index(int nargs)
do_single_byte = ((s1->wstlen == 0 && s1->stlen > 0)
|| (s2->wstlen == 0 && s2->stlen > 0));
}
-#endif
/* IGNORECASE will already be false if posix */
if (IGNORECASE) {
while (l1 > 0) {
if (l2 > l1)
break;
-#if MBS_SUPPORT
if (! do_single_byte && gawk_mb_cur_max > 1) {
const wchar_t *pos;
@@ -385,21 +398,18 @@ do_index(int nargs)
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++;
-#if MBS_SUPPORT
+ /*
+ * 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++;
}
-#endif
}
} else {
while (l1 > 0) {
@@ -410,7 +420,6 @@ do_index(int nargs)
ret = 1 + s1->stlen - l1;
break;
}
-#if MBS_SUPPORT
if (! do_single_byte && gawk_mb_cur_max > 1) {
const wchar_t *pos;
@@ -424,10 +433,6 @@ do_index(int nargs)
l1--;
p1++;
}
-#else
- l1--;
- p1++;
-#endif
}
}
out:
@@ -442,9 +447,9 @@ double
double_to_int(double d)
{
if (d >= 0)
- d = Floor(d);
+ d = floor(d);
else
- d = Ceil(d);
+ d = ceil(d);
return d;
}
@@ -459,7 +464,7 @@ do_int(int nargs)
tmp = POP_SCALAR();
if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
lintwarn(_("int: received non-numeric argument"));
- d = force_number(tmp);
+ d = force_number(tmp)->numbr;
d = double_to_int(d);
DEREF(tmp);
return make_number((AWKNUM) d);
@@ -491,15 +496,27 @@ do_length(int nargs)
tmp = POP();
if (tmp->type == Node_var_array) {
- static short warned = FALSE;
+ static bool warned = false;
+ unsigned long size;
if (do_posix)
fatal(_("length: received array argument"));
if (do_lint && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn(_("`length(array)' is a gawk extension"));
}
- return make_number((AWKNUM) tmp->table_size);
+
+ /*
+ * Support for deferred loading of array elements requires that
+ * we use the array length interface even though it isn't
+ * necessary for the built-in array types.
+ *
+ * 1/2015: The deferred arrays are gone, but this is probably
+ * still a good idea.
+ */
+
+ size = assoc_length(tmp);
+ return make_number(size);
}
assert(tmp->type == Node_val);
@@ -508,7 +525,6 @@ do_length(int nargs)
lintwarn(_("length: received non-string argument"));
tmp = force_string(tmp);
-#if MBS_SUPPORT
if (gawk_mb_cur_max > 1) {
tmp = force_wstring(tmp);
len = tmp->wstlen;
@@ -519,7 +535,6 @@ do_length(int nargs)
if (len == 0 && tmp->stlen > 0)
len = tmp->stlen;
} else
-#endif
len = tmp->stlen;
DEREF(tmp);
@@ -537,7 +552,7 @@ do_log(int nargs)
tmp = POP_SCALAR();
if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
lintwarn(_("log: received non-numeric argument"));
- arg = (double) force_number(tmp);
+ arg = force_number(tmp)->numbr;
if (arg < 0.0)
warning(_("log: received negative argument %g"), arg);
d = log(arg);
@@ -546,6 +561,42 @@ do_log(int nargs)
}
+#ifdef HAVE_MPFR
+
+/*
+ * mpz2mpfr --- convert an arbitrary-precision integer to a float
+ * without any loss of precision. The returned value is only
+ * good for temporary use.
+ */
+
+
+static mpfr_ptr
+mpz2mpfr(mpz_ptr zi)
+{
+ size_t prec;
+ static mpfr_t mpfrval;
+ static bool inited = false;
+ int tval;
+
+ /* estimate minimum precision for exact conversion */
+ prec = mpz_sizeinbase(zi, 2); /* most significant 1 bit position starting at 1 */
+ prec -= (size_t) mpz_scan1(zi, 0); /* least significant 1 bit index starting at 0 */
+ if (prec < MPFR_PREC_MIN)
+ prec = MPFR_PREC_MIN;
+ else if (prec > MPFR_PREC_MAX)
+ prec = MPFR_PREC_MAX;
+
+ if (! inited) {
+ mpfr_init2(mpfrval, prec);
+ inited = true;
+ } else
+ mpfr_set_prec(mpfrval, prec);
+ tval = mpfr_set_z(mpfrval, zi, ROUND_MODE);
+ IEEE_FMT(mpfrval, tval);
+ return mpfrval;
+}
+#endif
+
/*
* format_tree() formats arguments of sprintf,
* and accordingly to a fmt_string providing a format like in
@@ -603,8 +654,8 @@ format_tree(
size_t cur_arg = 0;
NODE *r = NULL;
- int i;
- int toofew = FALSE;
+ int i, nc;
+ bool toofew = false;
char *obuf, *obufout;
size_t osiz, ofre;
const char *chbuf;
@@ -612,12 +663,12 @@ format_tree(
int cs1;
NODE *arg;
long fw, prec, argnum;
- int used_dollar;
- int lj, alt, big_flag, bigbig_flag, small_flag, have_prec, need_format;
+ bool used_dollar;
+ bool lj, alt, big_flag, bigbig_flag, small_flag, have_prec, need_format;
long *cur = NULL;
uintmax_t uval;
- int sgn;
- int base = 0;
+ bool sgn;
+ int base;
/*
* Although this is an array, the elements serve two different
* purposes. The first element is the general buffer meant
@@ -635,14 +686,20 @@ format_tree(
char *cend = &cpbufs[0].stackbuf[sizeof(cpbufs[0].stackbuf)];
char *cp;
const char *fill;
- AWKNUM tmpval;
- char signchar = FALSE;
+ AWKNUM tmpval = 0.0;
+ char signchar = '\0';
size_t len;
- int zero_flag = FALSE;
- int quote_flag = FALSE;
+ bool zero_flag = false;
+ bool quote_flag = false;
int ii, jj;
char *chp;
size_t copy_count, char_count;
+#ifdef HAVE_MPFR
+ mpz_ptr zi;
+ mpfr_ptr mf;
+#endif
+ enum { MP_NONE = 0, MP_INT_WITH_PREC = 1, MP_INT_WITHOUT_PREC, MP_FLOAT } fmt_type;
+
static const char sp[] = " ";
static const char zero_string[] = "0";
static const char lchbuf[] = "0123456789abcdef";
@@ -705,7 +762,7 @@ format_tree(
goto out; \
} else if (cur_arg >= num_args) { \
arg = 0; /* shutup the compiler */ \
- toofew = TRUE; \
+ toofew = true; \
break; \
} else { \
arg = the_args[cur_arg]; \
@@ -713,8 +770,8 @@ format_tree(
} \
}
- need_format = FALSE;
- used_dollar = FALSE;
+ need_format = false;
+ used_dollar = false;
s0 = s1 = fmt_string;
while (n0-- > 0) {
@@ -722,18 +779,26 @@ format_tree(
s1++;
continue;
}
- need_format = TRUE;
+ need_format = true;
bchunk(s0, s1 - s0);
s0 = s1;
cur = &fw;
fw = 0;
prec = 0;
+ base = 0;
argnum = 0;
- have_prec = FALSE;
- signchar = FALSE;
- zero_flag = FALSE;
- quote_flag = FALSE;
- lj = alt = big_flag = bigbig_flag = small_flag = FALSE;
+ base = 0;
+ have_prec = false;
+ signchar = '\0';
+ zero_flag = false;
+ quote_flag = false;
+#ifdef HAVE_MPFR
+ mf = NULL;
+ zi = NULL;
+#endif
+ fmt_type = MP_NONE;
+
+ lj = alt = big_flag = bigbig_flag = small_flag = false;
fill = sp;
cp = cend;
chbuf = lchbuf;
@@ -750,7 +815,7 @@ check_pos:
break; /* reject as a valid format */
goto retry;
case '%':
- need_format = FALSE;
+ need_format = false;
/*
* 29 Oct. 2002:
* The C99 standard pages 274 and 279 seem to imply that
@@ -782,7 +847,7 @@ check_pos:
* screws up floating point formatting.
*/
if (cur == & fw)
- zero_flag = TRUE;
+ zero_flag = true;
if (lj)
goto retry;
/* FALL through */
@@ -809,7 +874,7 @@ check_pos:
*cur = *cur * 10 + *s1++ - '0';
}
if (prec < 0) /* negative precision is discarded */
- have_prec = FALSE;
+ have_prec = false;
if (cur == &prec)
cur = NULL;
if (n0 == 0) /* badly formatted control string */
@@ -824,7 +889,7 @@ check_pos:
if (cur == &fw) {
argnum = fw;
fw = 0;
- used_dollar = TRUE;
+ used_dollar = true;
if (argnum <= 0) {
msg(_("fatal: arg count with `$' must be > 0"));
goto out;
@@ -842,7 +907,10 @@ check_pos:
case '*':
if (cur == NULL)
break;
- if (! do_traditional && isdigit((unsigned char) *s1)) {
+ if (! do_traditional && used_dollar && ! isdigit((unsigned char) *s1)) {
+ fatal(_("fatal: must use `count$' on all formats or none"));
+ break; /* silence warnings */
+ } else if (! do_traditional && isdigit((unsigned char) *s1)) {
int val = 0;
for (; n0 > 0 && *s1 && isdigit((unsigned char) *s1); s1++, n0--) {
@@ -857,30 +925,31 @@ check_pos:
n0--;
}
if (val >= num_args) {
- toofew = TRUE;
+ toofew = true;
break;
}
arg = the_args[val];
} else {
parse_next_arg();
}
- *cur = force_number(arg);
+ (void) force_number(arg);
+ *cur = get_number_si(arg);
if (*cur < 0 && cur == &fw) {
*cur = -*cur;
lj++;
}
if (cur == &prec) {
if (*cur >= 0)
- have_prec = TRUE;
+ have_prec = true;
else
- have_prec = FALSE;
+ have_prec = false;
cur = NULL;
}
goto retry;
case ' ': /* print ' ' or '-' */
/* 'space' flag is ignored */
/* if '+' already present */
- if (signchar != FALSE)
+ if (signchar != false)
goto check_pos;
/* FALL THROUGH */
case '+': /* print '+' or '-' */
@@ -900,16 +969,14 @@ check_pos:
if (cur != &fw)
break;
cur = &prec;
- have_prec = TRUE;
+ have_prec = true;
goto retry;
case '#':
- alt = TRUE;
+ alt = true;
goto check_pos;
case '\'':
#if defined(HAVE_LOCALE_H)
- /* allow quote_flag if there is a thousands separator. */
- if (loc.thousands_sep[0] != '\0')
- quote_flag = TRUE;
+ quote_flag = true;
goto check_pos;
#else
goto retry;
@@ -918,62 +985,61 @@ check_pos:
if (big_flag)
break;
else {
- static short warned = FALSE;
+ static bool warned = false;
if (do_lint && ! warned) {
lintwarn(_("`l' is meaningless in awk formats; ignored"));
- warned = TRUE;
+ warned = true;
}
if (do_posix) {
msg(_("fatal: `l' is not permitted in POSIX awk formats"));
goto out;
}
}
- big_flag = TRUE;
+ big_flag = true;
goto retry;
case 'L':
if (bigbig_flag)
break;
else {
- static short warned = FALSE;
+ static bool warned = false;
if (do_lint && ! warned) {
lintwarn(_("`L' is meaningless in awk formats; ignored"));
- warned = TRUE;
+ warned = true;
}
if (do_posix) {
msg(_("fatal: `L' is not permitted in POSIX awk formats"));
goto out;
}
}
- bigbig_flag = TRUE;
+ bigbig_flag = true;
goto retry;
case 'h':
if (small_flag)
break;
else {
- static short warned = FALSE;
+ static bool warned = false;
if (do_lint && ! warned) {
lintwarn(_("`h' is meaningless in awk formats; ignored"));
- warned = TRUE;
+ warned = true;
}
if (do_posix) {
msg(_("fatal: `h' is not permitted in POSIX awk formats"));
goto out;
}
}
- small_flag = TRUE;
+ small_flag = true;
goto retry;
case 'c':
- need_format = FALSE;
+ need_format = false;
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) {
- uval = (uintmax_t) arg->numbr;
-#if MBS_SUPPORT
+ if ((arg->flags & NUMBER) != 0) {
+ uval = get_number_uj(arg);
if (gawk_mb_cur_max > 1) {
char buf[100];
wchar_t wc;
@@ -981,13 +1047,29 @@ check_pos:
size_t count;
memset(& mbs, 0, sizeof(mbs));
+
+ /* handle systems with too small wchar_t */
+ if (sizeof(wchar_t) < 4 && uval > 0xffff) {
+ if (do_lint)
+ lintwarn(
+ _("[s]printf: value %g is too big for %%c format"),
+ arg->numbr);
+
+ goto out0;
+ }
+
wc = uval;
count = wcrtomb(buf, wc, & mbs);
if (count == 0
- || count == (size_t)-1
- || count == (size_t)-2)
+ || count == (size_t) -1) {
+ if (do_lint)
+ lintwarn(
+ _("[s]printf: value %g is not a valid wide character"),
+ arg->numbr);
+
goto out0;
+ }
memcpy(cpbuf, buf, count);
prec = count;
@@ -998,11 +1080,7 @@ out0:
;
/* else,
fall through */
-#endif
- if (do_lint && uval > 255) {
- lintwarn("[s]printf: value %g is too big for %%c format",
- arg->numbr);
- }
+
cpbuf[0] = uval;
prec = 1;
cp = cpbuf;
@@ -1015,7 +1093,7 @@ out0:
* used to work? 6/2003.)
*/
cp = arg->stptr;
-#if MBS_SUPPORT
+ prec = 1;
/*
* First character can be multiple bytes if
* it's a multibyte character. Grr.
@@ -1026,20 +1104,16 @@ out0:
memset(& state, 0, sizeof(state));
count = mbrlen(cp, arg->stlen, & state);
- if (count == 0
- || count == (size_t)-1
- || count == (size_t)-2)
- goto out2;
- prec = count;
- goto pr_tail;
+ if (count != (size_t) -1 && count != (size_t) -2 && count > 0) {
+ prec = count;
+ /* may need to increase fw so that padding happens, see pr_tail code */
+ if (fw > 0)
+ fw += count - 1;
+ }
}
-out2:
- ;
-#endif
- prec = 1;
goto pr_tail;
case 's':
- need_format = FALSE;
+ need_format = false;
parse_next_arg();
arg = force_string(arg);
if (fw == 0 && ! have_prec)
@@ -1053,9 +1127,18 @@ out2:
goto pr_tail;
case 'd':
case 'i':
- need_format = FALSE;
+ need_format = false;
parse_next_arg();
- tmpval = force_number(arg);
+ (void) force_number(arg);
+#ifdef HAVE_MPFR
+ if (is_mpg_float(arg))
+ goto mpf0;
+ else if (is_mpg_integer(arg))
+ goto mpz0;
+ else
+#endif
+ tmpval = arg->numbr;
+
/*
* Check for Nan or Inf.
*/
@@ -1073,12 +1156,12 @@ out2:
if (tmpval < 0) {
tmpval = -tmpval;
- sgn = TRUE;
+ sgn = true;
} else {
if (tmpval == -0.0)
/* avoid printing -0 */
tmpval = 0.0;
- sgn = FALSE;
+ sgn = false;
}
/*
* Use snprintf return value to tell if there
@@ -1102,6 +1185,9 @@ out2:
}
if (i < 1)
goto out_of_range;
+#if defined(HAVE_LOCALE_H)
+ quote_flag = (quote_flag && loc.thousands_sep[0] != 0);
+#endif
chp = &cpbufs[1].buf[i-1];
ii = jj = 0;
do {
@@ -1109,12 +1195,18 @@ out2:
chp--; i--;
#if defined(HAVE_LOCALE_H)
if (quote_flag && loc.grouping[ii] && ++jj == loc.grouping[ii]) {
- if (i) /* only add if more digits coming */
- PREPEND(loc.thousands_sep[0]); /* XXX - assumption it's one char */
+ if (i) { /* only add if more digits coming */
+ int k;
+ const char *ts = loc.thousands_sep;
+
+ for (k = strlen(ts) - 1; k >= 0; k--) {
+ PREPEND(ts[k]);
+ }
+ }
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;
+ quote_flag = false;
else {
ii++;
jj = 0;
@@ -1164,9 +1256,80 @@ out2:
base += 2; /* FALL THROUGH */
case 'o':
base += 8;
- need_format = FALSE;
+ need_format = false;
parse_next_arg();
- tmpval = force_number(arg);
+ (void) force_number(arg);
+#ifdef HAVE_MPFR
+ if (is_mpg_integer(arg)) {
+mpz0:
+ zi = arg->mpg_i;
+
+ if (cs1 != 'd' && cs1 != 'i') {
+ if (mpz_sgn(zi) <= 0) {
+ /*
+ * Negative value or 0 requires special handling.
+ * Unlike MPFR, GMP does not allow conversion
+ * to (u)intmax_t. So we first convert GMP type to
+ * a MPFR type.
+ */
+ mf = mpz2mpfr(zi);
+ goto mpf1;
+ }
+ signchar = '\0'; /* Don't print '+' */
+ }
+
+ /* See comments above about when to fill with zeros */
+ zero_flag = (! lj
+ && ((zero_flag && ! have_prec)
+ || (fw == 0 && have_prec)));
+
+ fmt_type = have_prec ? MP_INT_WITH_PREC : MP_INT_WITHOUT_PREC;
+ goto fmt0;
+
+ } else if (is_mpg_float(arg)) {
+mpf0:
+ mf = arg->mpg_numbr;
+ if (! mpfr_number_p(mf)) {
+ /* inf or NaN */
+ cs1 = 'g';
+ fmt_type = MP_FLOAT;
+ goto fmt1;
+ }
+
+ if (cs1 != 'd' && cs1 != 'i') {
+mpf1:
+ /*
+ * The output of printf("%#.0x", 0) is 0 instead of 0x, hence <= in
+ * the comparison below.
+ */
+ if (mpfr_sgn(mf) <= 0) {
+ if (! mpfr_fits_intmax_p(mf, ROUND_MODE)) {
+ /* -ve number is too large */
+ cs1 = 'g';
+ fmt_type = MP_FLOAT;
+ goto fmt1;
+ }
+
+ tmpval = uval = (uintmax_t) mpfr_get_sj(mf, ROUND_MODE);
+ if (! alt && have_prec && prec == 0 && tmpval == 0)
+ goto pr_tail; /* printf("%.0x", 0) is no characters */
+ goto int0;
+ }
+ signchar = '\0'; /* Don't print '+' */
+ }
+
+ /* See comments above about when to fill with zeros */
+ zero_flag = (! lj
+ && ((zero_flag && ! have_prec)
+ || (fw == 0 && have_prec)));
+
+ (void) mpfr_get_z(mpzval, mf, MPFR_RNDZ); /* convert to GMP integer */
+ fmt_type = have_prec ? MP_INT_WITH_PREC : MP_INT_WITHOUT_PREC;
+ zi = mpzval;
+ goto fmt0;
+ } else
+#endif
+ tmpval = arg->numbr;
/*
* ``The result of converting a zero value with a
@@ -1185,14 +1348,19 @@ out2:
if (tmpval < 0) {
uval = (uintmax_t) (intmax_t) tmpval;
- if ((AWKNUM)(intmax_t)uval !=
- double_to_int(tmpval))
+ if ((AWKNUM)(intmax_t)uval != double_to_int(tmpval))
goto out_of_range;
} else {
uval = (uintmax_t) tmpval;
if ((AWKNUM)uval != double_to_int(tmpval))
goto out_of_range;
}
+#ifdef HAVE_MPFR
+ int0:
+#endif
+#if defined(HAVE_LOCALE_H)
+ quote_flag = (quote_flag && loc.thousands_sep[0] != 0);
+#endif
/*
* When to fill with zeroes is of course not simple.
* First: No zero fill if left-justifying.
@@ -1211,12 +1379,18 @@ out2:
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 */
- PREPEND(loc.thousands_sep[0]); /* XXX --- assumption it's one char */
+ if (uval) { /* only add if more digits coming */
+ int k;
+ const char *ts = loc.thousands_sep;
+
+ for (k = strlen(ts) - 1; k >= 0; k--) {
+ PREPEND(ts[k]);
+ }
+ }
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;
+ quote_flag = false;
else {
ii++;
jj = 0;
@@ -1257,9 +1431,14 @@ out2:
copy_count = prec;
if (fw == 0 && ! have_prec)
;
- else if (gawk_mb_cur_max > 1 && (cs1 == 's' || cs1 == 'c')) {
- assert(cp == arg->stptr || cp == cpbuf);
- copy_count = mbc_byte_count(arg->stptr, prec);
+ else if (gawk_mb_cur_max > 1) {
+ if (cs1 == 's') {
+ assert(cp == arg->stptr || cp == cpbuf);
+ copy_count = mbc_byte_count(arg->stptr, prec);
+ }
+ /* prec was set by code for %c */
+ /* else
+ copy_count = prec; */
}
bchunk(cp, copy_count);
while (fw > prec) {
@@ -1275,7 +1454,7 @@ out2:
lintwarn(_("[s]printf: value %g is out of range for `%%%c' format"),
(double) tmpval, cs1);
cs1 = 'g';
- goto format_float;
+ goto fmt1;
case 'F':
#if ! defined(PRINTF_HAS_F_FORMAT) || PRINTF_HAS_F_FORMAT != 1
@@ -1287,13 +1466,30 @@ out2:
case 'e':
case 'f':
case 'E':
- need_format = FALSE;
+ need_format = false;
parse_next_arg();
- tmpval = force_number(arg);
- format_float:
+ (void) force_number(arg);
+
+ if (! is_mpg_number(arg))
+ tmpval = arg->numbr;
+#ifdef HAVE_MPFR
+ else if (is_mpg_float(arg)) {
+ mf = arg->mpg_numbr;
+ fmt_type = MP_FLOAT;
+ } else {
+ /* arbitrary-precision integer, convert to MPFR float */
+ assert(mf == NULL);
+ mf = mpz2mpfr(arg->mpg_i);
+ fmt_type = MP_FLOAT;
+ }
+#endif
+ fmt1:
if (! have_prec)
prec = DEFAULT_G_PRECISION;
- chksize(fw + prec + 9); /* 9 == slop */
+#ifdef HAVE_MPFR
+ fmt0:
+#endif
+ chksize(fw + prec + 11); /* 11 == slop */
cp = cpbuf;
*cp++ = '%';
if (lj)
@@ -1306,32 +1502,53 @@ out2:
*cp++ = '0';
if (quote_flag)
*cp++ = '\'';
- strcpy(cp, "*.*");
- cp += 3;
- *cp++ = cs1;
- *cp = '\0';
+
#if defined(LC_NUMERIC)
if (quote_flag && ! use_lc_numeric)
setlocale(LC_NUMERIC, "");
#endif
- {
- int n;
- while ((n = snprintf(obufout, ofre, cpbuf,
- (int) fw, (int) prec,
- (double) tmpval)) >= ofre)
- chksize(n)
+
+ switch (fmt_type) {
+#ifdef HAVE_MPFR
+ case MP_INT_WITH_PREC:
+ sprintf(cp, "*.*Z%c", cs1);
+ while ((nc = mpfr_snprintf(obufout, ofre, cpbuf,
+ (int) fw, (int) prec, zi)) >= ofre)
+ chksize(nc)
+ break;
+ case MP_INT_WITHOUT_PREC:
+ sprintf(cp, "*Z%c", cs1);
+ while ((nc = mpfr_snprintf(obufout, ofre, cpbuf,
+ (int) fw, zi)) >= ofre)
+ chksize(nc)
+ break;
+ case MP_FLOAT:
+ sprintf(cp, "*.*R*%c", cs1);
+ while ((nc = mpfr_snprintf(obufout, ofre, cpbuf,
+ (int) fw, (int) prec, ROUND_MODE, mf)) >= ofre)
+ chksize(nc)
+ break;
+#endif
+ default:
+ sprintf(cp, "*.*%c", cs1);
+ while ((nc = snprintf(obufout, ofre, cpbuf,
+ (int) fw, (int) prec,
+ (double) tmpval)) >= ofre)
+ chksize(nc)
}
+
#if defined(LC_NUMERIC)
if (quote_flag && ! use_lc_numeric)
setlocale(LC_NUMERIC, "C");
#endif
+
len = strlen(obufout);
ofre -= len;
obufout += len;
s0 = s1;
break;
default:
- if (do_lint && isalpha(cs1))
+ if (do_lint && is_alpha(cs1))
lintwarn(_("ignoring unknown format specifier character `%c': no argument converted"), cs1);
break;
}
@@ -1365,6 +1582,7 @@ out:
if (obuf != NULL)
efree(obuf);
}
+
if (r == NULL)
gawk_exit(EXIT_FATAL);
return r;
@@ -1379,7 +1597,7 @@ printf_common(int nargs)
int i;
NODE *r, *tmp;
- assert(nargs <= max_args);
+ assert(nargs > 0 && nargs <= max_args);
for (i = 1; i <= nargs; i++) {
tmp = args_array[nargs - i] = POP();
if (tmp->type == Node_var_array) {
@@ -1402,6 +1620,10 @@ NODE *
do_sprintf(int nargs)
{
NODE *r;
+
+ if (nargs == 0)
+ fatal(_("sprintf: no arguments"));
+
r = printf_common(nargs);
if (r == NULL)
gawk_exit(EXIT_FATAL);
@@ -1443,9 +1665,11 @@ do_printf(int nargs, int redirtype)
fatal(_("attempt to use array `%s' in a scalar context"), array_vname(redir_exp));
rp = redirect(redir_exp, redirtype, & errflg);
if (rp != NULL)
- fp = rp->fp;
- } else
+ fp = rp->output.fp;
+ } else if (do_debug) /* only the debugger can change the default output */
fp = output_fp;
+ else
+ fp = stdout;
tmp = printf_common(nargs);
if (redir_exp != NULL) {
@@ -1457,9 +1681,9 @@ do_printf(int nargs, int redirtype)
DEREF(tmp);
return;
}
- efwrite(tmp->stptr, sizeof(char), tmp->stlen, fp, "printf", rp, TRUE);
+ efwrite(tmp->stptr, sizeof(char), tmp->stlen, fp, "printf", rp, true);
if (rp != NULL && (rp->flag & RED_TWOWAY) != 0)
- fflush(rp->fp);
+ rp->output.gawk_fflush(rp->output.fp, rp->output.opaque);
DEREF(tmp);
} else
gawk_exit(EXIT_FATAL);
@@ -1476,7 +1700,7 @@ do_sqrt(int nargs)
tmp = POP_SCALAR();
if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
lintwarn(_("sqrt: received non-numeric argument"));
- arg = (double) force_number(tmp);
+ arg = (double) force_number(tmp)->numbr;
DEREF(tmp);
if (arg < 0.0)
warning(_("sqrt: called with negative argument %g"), arg);
@@ -1495,9 +1719,16 @@ do_substr(int nargs)
double d_index = 0, d_length = 0;
size_t src_len;
- if (nargs == 3)
- POP_NUMBER(d_length);
- POP_NUMBER(d_index);
+ if (nargs == 3) {
+ t1 = POP_NUMBER();
+ d_length = get_number_d(t1);
+ DEREF(t1);
+ }
+
+ t1 = POP_NUMBER();
+ d_index = get_number_d(t1);
+ DEREF(t1);
+
t1 = POP_STRING();
if (nargs == 3) {
@@ -1507,7 +1738,14 @@ do_substr(int nargs)
else if (do_lint == DO_LINT_INVALID && ! (d_length >= 0))
lintwarn(_("substr: length %g is not >= 0"), d_length);
DEREF(t1);
- return dupnode(Nnull_string);
+ /*
+ * Return explicit null string instead of doing
+ * dupnode(Nnull_string) so that if the result
+ * is checked with the combination of length()
+ * and lint, no error is reported about using
+ * an uninitialized value. Same thing later, too.
+ */
+ return make_string("", 0);
}
if (do_lint) {
if (double_to_int(d_length) != d_length)
@@ -1546,13 +1784,11 @@ do_substr(int nargs)
if (nargs == 2) { /* third arg. missing */
/* use remainder of string */
length = t1->stlen - indx; /* default to bytes */
-#if MBS_SUPPORT
if (gawk_mb_cur_max > 1) {
t1 = force_wstring(t1);
if (t1->wstlen > 0) /* use length of wide char string if we have one */
length = t1->wstlen - indx;
}
-#endif
d_length = length; /* set here in case used in diagnostics, below */
}
@@ -1561,16 +1797,14 @@ do_substr(int nargs)
if (do_lint && (do_lint == DO_LINT_ALL || ((indx | length) != 0)))
lintwarn(_("substr: source string is zero length"));
DEREF(t1);
- return dupnode(Nnull_string);
+ return make_string("", 0);
}
/* get total len of input string, for following checks */
-#if 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) {
@@ -1578,7 +1812,7 @@ do_substr(int nargs)
lintwarn(_("substr: start index %g is past end of string"),
d_index);
DEREF(t1);
- return dupnode(Nnull_string);
+ return make_string("", 0);
}
if (length > src_len - indx) {
if (do_lint)
@@ -1588,7 +1822,6 @@ do_substr(int nargs)
length = src_len - indx;
}
-#if MBS_SUPPORT
/* force_wstring() already called */
if (gawk_mb_cur_max == 1 || t1->wstlen == t1->stlen)
/* single byte case */
@@ -1618,9 +1851,6 @@ do_substr(int nargs)
*cp = '\0';
r = make_str_node(substr, cp - substr, ALREADY_MALLOCED);
}
-#else
- r = make_string(t1->stptr + indx, length);
-#endif
DEREF(t1);
return r;
@@ -1648,7 +1878,7 @@ do_strftime(int nargs)
format = def_strftime_format; /* traditional date format */
formatlen = strlen(format);
(void) time(& fclock); /* current time of day */
- do_gmt = FALSE;
+ do_gmt = false;
if (PROCINFO_node != NULL) {
sub = make_string("strftime", 8);
@@ -1681,7 +1911,8 @@ do_strftime(int nargs)
t2 = POP_SCALAR();
if (do_lint && (t2->flags & (NUMCUR|NUMBER)) == 0)
lintwarn(_("strftime: received non-numeric second argument"));
- clock_val = (long) force_number(t2);
+ (void) force_number(t2);
+ clock_val = get_number_si(t2);
if (clock_val < 0)
fatal(_("strftime: second argument less than 0 or too big for time_t"));
fclock = (time_t) clock_val;
@@ -1774,10 +2005,10 @@ do_mktime(int nargs)
& hour, & minute, & second,
& dst);
- if (do_lint /* Ready? Set! Go: */
- && ( (second < 0 || second > 60)
- || (minute < 0 || minute > 60)
- || (hour < 0 || hour > 23)
+ if ( do_lint /* Ready? Set! Go: */
+ && ( (second < 0 || second > 60)
+ || (minute < 0 || minute > 59)
+ || (hour < 0 || hour > 23) /* FIXME ISO 8601 allows 24 ? */
|| (day < 1 || day > 31)
|| (month < 1 || month > 12) ))
lintwarn(_("mktime: at least one of the values is out of the default range"));
@@ -1832,7 +2063,7 @@ do_system(int nargs)
ret = system(cmd);
if (ret != -1)
ret = WEXITSTATUS(ret);
- if ((BINMODE & 1) != 0)
+ if ((BINMODE & BINMODE_INPUT) != 0)
os_setbinmode(fileno(stdin), O_BINARY);
cmd[tmp->stlen] = save;
@@ -1861,9 +2092,11 @@ do_print(int nargs, int redirtype)
fatal(_("attempt to use array `%s' in a scalar context"), array_vname(redir_exp));
rp = redirect(redir_exp, redirtype, & errflg);
if (rp != NULL)
- fp = rp->fp;
- } else
+ fp = rp->output.fp;
+ } else if (do_debug) /* only the debugger can change the default output */
fp = output_fp;
+ else
+ fp = stdout;
for (i = 1; i <= nargs; i++) {
tmp = args_array[i] = POP();
@@ -1893,18 +2126,18 @@ do_print(int nargs, int redirtype)
}
for (i = nargs; i > 0; i--) {
- efwrite(args_array[i]->stptr, sizeof(char), args_array[i]->stlen, fp, "print", rp, FALSE);
+ efwrite(args_array[i]->stptr, sizeof(char), args_array[i]->stlen, fp, "print", rp, false);
DEREF(args_array[i]);
if (i != 1 && OFSlen > 0)
efwrite(OFS, sizeof(char), (size_t) OFSlen,
- fp, "print", rp, FALSE);
+ fp, "print", rp, false);
}
if (ORSlen > 0)
- efwrite(ORS, sizeof(char), (size_t) ORSlen, fp, "print", rp, TRUE);
+ efwrite(ORS, sizeof(char), (size_t) ORSlen, fp, "print", rp, true);
if (rp != NULL && (rp->flag & RED_TWOWAY) != 0)
- fflush(rp->fp);
+ rp->output.gawk_fflush(rp->output.fp, rp->output.opaque);
}
/* do_print_rec --- special case printing of $0, for speed */
@@ -1923,7 +2156,7 @@ do_print_rec(int nargs, int redirtype)
redir_exp = TOP();
rp = redirect(redir_exp, redirtype, & errflg);
if (rp != NULL)
- fp = rp->fp;
+ fp = rp->output.fp;
DEREF(redir_exp);
decr_sp();
} else
@@ -1937,19 +2170,18 @@ do_print_rec(int nargs, int redirtype)
f0 = fields_arr[0];
- if (do_lint && f0 == Nnull_string)
+ if (do_lint && (f0->flags & NULL_FIELD) != 0)
lintwarn(_("reference to uninitialized field `$%d'"), 0);
- efwrite(f0->stptr, sizeof(char), f0->stlen, fp, "print", rp, FALSE);
+ 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);
+ efwrite(ORS, sizeof(char), (size_t) ORSlen, fp, "print", rp, true);
if (rp != NULL && (rp->flag & RED_TWOWAY) != 0)
- fflush(rp->fp);
+ rp->output.gawk_fflush(rp->output.fp, rp->output.opaque);
}
-#if MBS_SUPPORT
/* is_wupper --- function version of iswupper for passing function pointers */
@@ -2014,7 +2246,6 @@ wide_tolower(wchar_t *wstr, size_t wlen)
{
wide_change_case(wstr, wlen, is_wupper, to_wlower);
}
-#endif
/* do_tolower --- lower case a string */
@@ -2037,14 +2268,11 @@ do_tolower(int nargs)
cp < cp2; cp++)
if (isupper(*cp))
*cp = tolower(*cp);
- }
-#if MBS_SUPPORT
- else {
+ } else {
force_wstring(t2);
wide_tolower(t2->wstptr, t2->wstlen);
wstr2str(t2);
}
-#endif
DEREF(t1);
return t2;
@@ -2071,14 +2299,11 @@ do_toupper(int nargs)
cp < cp2; cp++)
if (islower(*cp))
*cp = toupper(*cp);
- }
-#if MBS_SUPPORT
- else {
+ } else {
force_wstring(t2);
wide_toupper(t2->wstptr, t2->wstlen);
wstr2str(t2);
}
-#endif
DEREF(t1);
return t2;
@@ -2099,8 +2324,8 @@ do_atan2(int nargs)
if ((t2->flags & (NUMCUR|NUMBER)) == 0)
lintwarn(_("atan2: received non-numeric second argument"));
}
- d1 = force_number(t1);
- d2 = force_number(t2);
+ d1 = force_number(t1)->numbr;
+ d2 = force_number(t2)->numbr;
DEREF(t1);
DEREF(t2);
return make_number((AWKNUM) atan2(d1, d2));
@@ -2117,7 +2342,7 @@ do_sin(int nargs)
tmp = POP_SCALAR();
if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
lintwarn(_("sin: received non-numeric argument"));
- d = sin((double) force_number(tmp));
+ d = sin((double) force_number(tmp)->numbr);
DEREF(tmp);
return make_number((AWKNUM) d);
}
@@ -2133,14 +2358,14 @@ do_cos(int nargs)
tmp = POP_SCALAR();
if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
lintwarn(_("cos: received non-numeric argument"));
- d = cos((double) force_number(tmp));
+ d = cos((double) force_number(tmp)->numbr);
DEREF(tmp);
return make_number((AWKNUM) d);
}
/* do_rand --- do the rand function */
-static int firstrand = TRUE;
+static bool firstrand = true;
/* Some systems require this array to be integer aligned. Sigh. */
#define SIZEOF_STATE 256
static uint32_t istate[SIZEOF_STATE/sizeof(uint32_t)];
@@ -2150,10 +2375,12 @@ static char *const state = (char *const) istate;
NODE *
do_rand(int nargs ATTRIBUTE_UNUSED)
{
+ double tmprand;
+#define RAND_DIVISOR ((double)GAWK_RANDOM_MAX+1.0)
if (firstrand) {
(void) initstate((unsigned) 1, state, SIZEOF_STATE);
/* don't need to srandom(1), initstate() does it for us. */
- firstrand = FALSE;
+ firstrand = false;
setstate(state);
}
/*
@@ -2161,7 +2388,66 @@ do_rand(int nargs ATTRIBUTE_UNUSED)
*
* 0 <= n < 1
*/
- return make_number((AWKNUM) (random() % GAWK_RANDOM_MAX) / GAWK_RANDOM_MAX);
+ /*
+ * Date: Wed, 28 Aug 2013 17:52:46 -0700
+ * From: Bob Jewett <jewett@bill.scs.agilent.com>
+ *
+ * Call random() twice to fill in more bits in the value
+ * of the double. Also, there is a bug in random() such
+ * that when the values of successive values are combined
+ * like (rand1*rand2)^2, (rand3*rand4)^2, ... the
+ * resulting time series is not white noise. The
+ * following also seems to fix that bug.
+ *
+ * The add/subtract 0.5 keeps small bits from filling
+ * below 2^-53 in the double, not that anyone should be
+ * looking down there.
+ *
+ * Date: Wed, 25 Sep 2013 10:45:38 -0600 (MDT)
+ * From: "Nelson H. F. Beebe" <beebe@math.utah.edu>
+ * (4) The code is typical of many published fragments for converting
+ * from integer to floating-point, and I discuss the serious pitfalls
+ * in my book, because it leads to platform-dependent behavior at the
+ * end points of the interval [0,1]
+ *
+ * (5) the documentation in the gawk info node says
+ *
+ * `rand()'
+ * Return a random number. The values of `rand()' are uniformly
+ * distributed between zero and one. The value could be zero but is
+ * never one.(1)
+ *
+ * The division by RAND_DIVISOR may not guarantee that 1.0 is never
+ * returned: the programmer forgot the platform-dependent issue of
+ * rounding.
+ *
+ * For points 4 and 5, the safe way is a loop:
+ *
+ * double
+ * rand(void) // return value in [0.0, 1.0)
+ * {
+ * value = internal_rand();
+ *
+ * while (value == 1.0)
+ * value = internal_rand();
+ *
+ * return (value);
+ * }
+ */
+
+ do {
+ long d1, d2;
+ /*
+ * Do the calls in predictable order to avoid
+ * compiler differences in order of evaluation.
+ */
+ d1 = random();
+ d2 = random();
+ tmprand = 0.5 + ( (d1/RAND_DIVISOR + d2) / RAND_DIVISOR );
+ tmprand -= 0.5;
+ } while (tmprand == 1.0);
+
+ return make_number((AWKNUM) tmprand);
}
/* do_srand --- seed the random number generator */
@@ -2176,7 +2462,7 @@ do_srand(int nargs)
if (firstrand) {
(void) initstate((unsigned) 1, state, SIZEOF_STATE);
/* don't need to srandom(1), we're changing the seed below */
- firstrand = FALSE;
+ firstrand = false;
(void) setstate(state);
}
@@ -2186,7 +2472,7 @@ do_srand(int nargs)
tmp = POP_SCALAR();
if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
lintwarn(_("srand: received non-numeric argument"));
- srandom((unsigned int) (save_seed = (long) force_number(tmp)));
+ srandom((unsigned int) (save_seed = (long) force_number(tmp)->numbr));
DEREF(tmp);
}
return make_number((AWKNUM) ret);
@@ -2228,13 +2514,12 @@ do_match(int nargs)
size_t *wc_indices = NULL;
rlength = REEND(rp, t1->stptr) - RESTART(rp, t1->stptr); /* byte length */
-#if MBS_SUPPORT
if (rlength > 0 && 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 */
@@ -2256,12 +2541,10 @@ do_match(int nargs)
start = t1->stptr + s;
subpat_start = s;
subpat_len = len = SUBPATEND(rp, t1->stptr, ii) - s;
-#if MBS_SUPPORT
if (len > 0 && 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);
it->flags |= MAYBE_NUM; /* user input */
@@ -2270,6 +2553,9 @@ do_match(int nargs)
lhs = assoc_lookup(dest, sub);
unref(*lhs);
*lhs = it;
+ /* execute post-assignment routine if any */
+ if (dest->astore != NULL)
+ (*dest->astore)(dest, sub);
unref(sub);
sprintf(buff, "%d", ii);
@@ -2293,6 +2579,8 @@ do_match(int nargs)
lhs = assoc_lookup(dest, sub);
unref(*lhs);
*lhs = it;
+ if (dest->astore != NULL)
+ (*dest->astore)(dest, sub);
unref(sub);
memcpy(buf, buff, ilen);
@@ -2306,6 +2594,8 @@ do_match(int nargs)
lhs = assoc_lookup(dest, sub);
unref(*lhs);
*lhs = it;
+ if (dest->astore != NULL)
+ (*dest->astore)(dest, sub);
unref(sub);
}
}
@@ -2337,7 +2627,7 @@ do_match(int nargs)
* #! /usr/local/bin/mawk -f
*
* BEGIN {
- * TRUE = 1; FALSE = 0
+ * true = 1; false = 0
* print "--->", mygsub("abc", "b+", "FOO")
* print "--->", mygsub("abc", "x*", "X")
* print "--->", mygsub("abc", "b*", "X")
@@ -2349,10 +2639,10 @@ do_match(int nargs)
* function mygsub(str, regex, replace, origstr, newstr, eosflag, nonzeroflag)
* {
* origstr = str;
- * eosflag = nonzeroflag = FALSE
+ * eosflag = nonzeroflag = false
* while (match(str, regex)) {
* if (RLENGTH > 0) { # easy case
- * nonzeroflag = TRUE
+ * nonzeroflag = true
* if (RSTART == 1) { # match at front of string
* newstr = newstr replace
* } else {
@@ -2365,7 +2655,7 @@ do_match(int nargs)
* # which we don't really want, so skip over it
* newstr = newstr substr(str, 1, 1)
* str = substr(str, 2)
- * nonzeroflag = FALSE
+ * nonzeroflag = false
* } else {
* # 0-length match
* if (RSTART == 1) {
@@ -2379,7 +2669,7 @@ do_match(int nargs)
* if (eosflag)
* break
* else
- * eosflag = TRUE
+ * eosflag = true
* }
* if (length(str) > 0)
* newstr = newstr str # rest of string
@@ -2397,23 +2687,28 @@ do_match(int nargs)
* 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.
+ * 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.
*
- * 11/2010: The text in the 2008 standard is the same as just quoted. However, POSIX behavior
- * is now the default. This can change the behavior of awk programs. The old behavior
- * is not available.
+ * 11/2010: The text in the 2008 standard is the same as just quoted.
+ * However, POSIX behavior is now the default. This can change the behavior
+ * of awk programs. The old behavior is not available.
+ *
+ * 7/2011: Reverted backslash handling to what it used to be. It was in
+ * gawk for too long. Should have known better.
*/
/*
@@ -2446,7 +2741,7 @@ do_sub(int nargs, unsigned int flags)
long how_many = 1; /* one substitution for sub, also gensub default */
int global;
long current;
- int lastmatchnonzero;
+ bool lastmatchnonzero;
char *mb_indices = NULL;
if ((flags & GENSUB) != 0) {
@@ -2463,15 +2758,18 @@ do_sub(int nargs, unsigned int flags)
if (t1->stlen > 0 && (t1->stptr[0] == 'g' || t1->stptr[0] == 'G'))
how_many = -1;
else {
- d = force_number(t1);
-
+ (void) force_number(t1);
+ d = get_number_d(t1);
if ((t1->flags & NUMCUR) != 0)
goto set_how_many;
+ warning(_("gensub: third argument `%.*s' treated as 1"),
+ (int) t1->stlen, t1->stptr);
how_many = 1;
}
} else {
- d = force_number(t1);
+ (void) force_number(t1);
+ d = get_number_d(t1);
set_how_many:
if (d < 1)
how_many = 1;
@@ -2479,8 +2777,8 @@ set_how_many:
how_many = d;
else
how_many = LONG_MAX;
- if (d == 0)
- warning(_("gensub: third argument of 0 treated as 1"));
+ if (d <= 0)
+ warning(_("gensub: third argument %g treated as 1"), d);
}
DEREF(t1);
@@ -2518,14 +2816,11 @@ set_how_many:
text = t->stptr;
textlen = t->stlen;
- buflen = textlen + 2;
repl = s->stptr;
replend = repl + s->stlen;
repllen = replend - repl;
- emalloc(buf, char *, buflen + 2, "do_sub");
- buf[buflen] = '\0';
- buf[buflen + 1] = '\0';
+
ampersands = 0;
/*
@@ -2547,7 +2842,7 @@ set_how_many:
repllen--;
ampersands++;
} else if (*scan == '\\') {
- if (flags & GENSUB) { /* gensub, behave sanely */
+ if ((flags & GENSUB) != 0) { /* gensub, behave sanely */
if (isdigit((unsigned char) scan[1])) {
ampersands++;
scan++;
@@ -2583,7 +2878,14 @@ set_how_many:
}
}
- lastmatchnonzero = FALSE;
+ lastmatchnonzero = false;
+
+ /* guesstimate how much room to allocate; +2 forces > 0 */
+ buflen = textlen + (ampersands + 1) * repllen + 2;
+ emalloc(buf, char *, buflen + 2, "do_sub");
+ buf[buflen] = '\0';
+ buf[buflen + 1] = '\0';
+
bp = buf;
for (current = 1;; current++) {
matches++;
@@ -2615,7 +2917,7 @@ set_how_many:
if (matchstart == matchend
&& lastmatchnonzero
&& matchstart == text) {
- lastmatchnonzero = FALSE;
+ lastmatchnonzero = false;
matches--;
goto empty;
}
@@ -2684,7 +2986,7 @@ set_how_many:
} else
*bp++ = *scan;
if (matchstart != matchend)
- lastmatchnonzero = TRUE;
+ lastmatchnonzero = true;
} else {
/*
* don't want this match, skip over it by copying
@@ -2725,13 +3027,16 @@ set_how_many:
done:
DEREF(s);
- if ((matches == 0 || (flags & LITERAL) != 0) && buf != NULL)
+ if ((matches == 0 || (flags & LITERAL) != 0) && buf != NULL) {
efree(buf);
+ buf = NULL;
+ }
if (flags & GENSUB) {
if (matches > 0) {
/* return the result string */
DEREF(t);
+ assert(buf != NULL);
return make_str_node(buf, textlen, ALREADY_MALLOCED);
}
@@ -2740,7 +3045,7 @@ done:
}
/* For a string literal, must not change the original string. */
- if (flags & LITERAL)
+ if ((flags & LITERAL) != 0)
DEREF(t);
else if (matches > 0) {
unref(*lhs);
@@ -2777,15 +3082,15 @@ do_lshift(int nargs)
if ((s2->flags & (NUMCUR|NUMBER)) == 0)
lintwarn(_("lshift: received non-numeric second argument"));
}
- val = force_number(s1);
- shift = force_number(s2);
+ val = force_number(s1)->numbr;
+ shift = force_number(s2)->numbr;
if (do_lint) {
if (val < 0 || shift < 0)
- lintwarn(_("lshift(%lf, %lf): negative values will give strange results"), val, shift);
+ lintwarn(_("lshift(%f, %f): 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);
+ lintwarn(_("lshift(%f, %f): 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);
+ lintwarn(_("lshift(%f, %f): too large shift value will give strange results"), val, shift);
}
DEREF(s1);
@@ -2814,15 +3119,15 @@ do_rshift(int nargs)
if ((s2->flags & (NUMCUR|NUMBER)) == 0)
lintwarn(_("rshift: received non-numeric second argument"));
}
- val = force_number(s1);
- shift = force_number(s2);
+ val = force_number(s1)->numbr;
+ shift = force_number(s2)->numbr;
if (do_lint) {
if (val < 0 || shift < 0)
- lintwarn(_("rshift(%lf, %lf): negative values will give strange results"), val, shift);
+ lintwarn(_("rshift(%f, %f): 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);
+ lintwarn(_("rshift(%f, %f): 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);
+ lintwarn(_("rshift(%f, %f): too large shift value will give strange results"), val, shift);
}
DEREF(s1);
@@ -2840,33 +3145,30 @@ do_rshift(int nargs)
NODE *
do_and(int nargs)
{
- NODE *s1, *s2;
- uintmax_t uleft, uright, res;
- AWKNUM left, right;
+ NODE *s1;
+ uintmax_t res, uval;
+ AWKNUM val;
+ int i;
- POP_TWO_SCALARS(s1, s2);
- 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);
- }
+ res = ~0; /* start off with all ones */
+ if (nargs < 2)
+ fatal(_("and: called with less than two arguments"));
- DEREF(s1);
- DEREF(s2);
+ for (i = 1; nargs > 0; nargs--, i++) {
+ s1 = POP_SCALAR();
+ if (do_lint && (s1->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("and: argument %d is non-numeric"), i);
+
+ val = force_number(s1)->numbr;
+ if (do_lint && val < 0)
+ lintwarn(_("and: argument %d negative value %g will give strange results"), i, val);
+
+ uval = (uintmax_t) val;
+ res &= uval;
- uleft = (uintmax_t) left;
- uright = (uintmax_t) right;
+ DEREF(s1);
+ }
- res = uleft & uright;
return make_integer(res);
}
@@ -2875,33 +3177,30 @@ do_and(int nargs)
NODE *
do_or(int nargs)
{
- NODE *s1, *s2;
- uintmax_t uleft, uright, res;
- AWKNUM left, right;
+ NODE *s1;
+ uintmax_t res, uval;
+ AWKNUM val;
+ int i;
- POP_TWO_SCALARS(s1, s2);
- 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);
- }
+ res = 0;
+ if (nargs < 2)
+ fatal(_("or: called with less than two arguments"));
- DEREF(s1);
- DEREF(s2);
+ for (i = 1; nargs > 0; nargs--, i++) {
+ s1 = POP_SCALAR();
+ if (do_lint && (s1->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("or: argument %d is non-numeric"), i);
+
+ val = force_number(s1)->numbr;
+ if (do_lint && val < 0)
+ lintwarn(_("or: argument %d negative value %g will give strange results"), i, val);
- uleft = (uintmax_t) left;
- uright = (uintmax_t) right;
+ uval = (uintmax_t) val;
+ res |= uval;
+
+ DEREF(s1);
+ }
- res = uleft | uright;
return make_integer(res);
}
@@ -2910,36 +3209,33 @@ do_or(int nargs)
NODE *
do_xor(int nargs)
{
- NODE *s1, *s2;
- uintmax_t uleft, uright, res;
- AWKNUM left, right;
+ NODE *s1;
+ uintmax_t res, uval;
+ AWKNUM val;
+ int i;
- POP_TWO_SCALARS(s1, s2);
- left = force_number(s1);
- right = force_number(s2);
+ if (nargs < 2)
+ fatal(_("xor: called with less than two arguments"));
- 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);
- }
+ res = 0; /* silence compiler warning */
+ for (i = 1; nargs > 0; nargs--, i++) {
+ s1 = POP_SCALAR();
+ if (do_lint && (s1->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("xor: argument %d is non-numeric"), i);
- DEREF(s1);
- DEREF(s2);
+ val = force_number(s1)->numbr;
+ if (do_lint && val < 0)
+ lintwarn(_("xor: argument %d negative value %g will give strange results"), i, val);
+
+ uval = (uintmax_t) val;
+ if (i == 1)
+ res = uval;
+ else
+ res ^= uval;
- uleft = (uintmax_t) left;
- uright = (uintmax_t) right;
+ DEREF(s1);
+ }
- res = uleft ^ uright;
return make_integer(res);
}
@@ -2955,16 +3251,14 @@ do_compl(int nargs)
tmp = POP_SCALAR();
if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
lintwarn(_("compl: received non-numeric argument"));
- d = force_number(tmp);
+ d = force_number(tmp)->numbr;
DEREF(tmp);
if (do_lint) {
- if ((tmp->flags & (NUMCUR|NUMBER)) == 0)
- lintwarn(_("compl: received non-numeric argument"));
if (d < 0)
- lintwarn(_("compl(%lf): negative value will give strange results"), d);
+ lintwarn(_("compl(%f): negative value will give strange results"), d);
if (double_to_int(d) != d)
- lintwarn(_("compl(%lf): fractional value will be truncated"), d);
+ lintwarn(_("compl(%f): fractional value will be truncated"), d);
}
uval = (uintmax_t) d;
@@ -2982,11 +3276,11 @@ do_strtonum(int nargs)
tmp = POP_SCALAR();
if ((tmp->flags & (NUMBER|NUMCUR)) != 0)
- d = (AWKNUM) force_number(tmp);
- else if (isnondecimal(tmp->stptr, use_lc_numeric))
+ d = (AWKNUM) force_number(tmp)->numbr;
+ else if (get_numbase(tmp->stptr, use_lc_numeric) != 10)
d = nondec2awknum(tmp->stptr, tmp->stlen);
else
- d = (AWKNUM) force_number(tmp);
+ d = (AWKNUM) force_number(tmp)->numbr;
DEREF(tmp);
return make_number((AWKNUM) d);
@@ -3236,7 +3530,10 @@ do_dcngettext(int nargs)
}
#endif
- POP_NUMBER(d); /* third argument */
+ t2 = POP_NUMBER(); /* third argument */
+ d = get_number_d(t2);
+ DEREF(t2);
+
number = (unsigned long) double_to_int(d);
t2 = POP_STRING(); /* second argument */
string2 = t2->stptr;
@@ -3298,13 +3595,78 @@ do_bindtextdomain(int nargs)
return make_string(the_result, strlen(the_result));
}
+/* do_div --- do integer division, return quotient and remainder in dest array */
+
+/*
+ * We define the semantics as:
+ * numerator = int(numerator)
+ * denominator = int(denonmator)
+ * quotient = int(numerator / denomator)
+ * remainder = int(numerator % denomator)
+ */
+
+NODE *
+do_div(int nargs)
+{
+ NODE *numerator, *denominator, *result;
+ double num, denom, quotient, remainder;
+ NODE *sub, **lhs;
+
+ result = POP_PARAM();
+ if (result->type != Node_var_array)
+ fatal(_("div: third argument is not an array"));
+ assoc_clear(result);
+
+ denominator = POP_SCALAR();
+ numerator = POP_SCALAR();
+
+ if (do_lint) {
+ if ((numerator->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("div: received non-numeric first argument"));
+ if ((denominator->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("div: received non-numeric second argument"));
+ }
+
+ (void) force_number(numerator);
+ (void) force_number(denominator);
+ num = double_to_int(get_number_d(numerator));
+ denom = double_to_int(get_number_d(denominator));
+
+ if (denom == 0.0)
+ fatal(_("div: division by zero attempted"));
+
+ quotient = double_to_int(num / denom);
+ /*
+ * FIXME: This code is duplicated, factor it out to a
+ * separate function.
+ */
+#ifdef HAVE_FMOD
+ remainder = fmod(num, denom);
+#else /* ! HAVE_FMOD */
+ (void) modf(num / denom, & remainder);
+ remainder = num - remainder * denom;
+#endif /* ! HAVE_FMOD */
+ remainder = double_to_int(remainder);
+
+ sub = make_string("quotient", 8);
+ lhs = assoc_lookup(result, sub);
+ unref(*lhs);
+ *lhs = make_number((AWKNUM) quotient);
+
+ sub = make_string("remainder", 9);
+ lhs = assoc_lookup(result, sub);
+ unref(*lhs);
+ *lhs = make_number((AWKNUM) remainder);
+
+ return make_number((AWKNUM) 0.0);
+}
+
/* mbc_byte_count --- return number of bytes for corresponding numchars multibyte characters */
static size_t
mbc_byte_count(const char *ptr, size_t numchars)
{
-#if MBS_SUPPORT
mbstate_t cur_state;
size_t sum = 0;
int mb_len;
@@ -3325,9 +3687,6 @@ mbc_byte_count(const char *ptr, size_t numchars)
}
return sum;
-#else
- return numchars;
-#endif
}
/* mbc_char_count --- return number of m.b. chars in string, up to numbytes bytes */
@@ -3335,7 +3694,6 @@ mbc_byte_count(const char *ptr, size_t numchars)
static size_t
mbc_char_count(const char *ptr, size_t numbytes)
{
-#if MBS_SUPPORT
mbstate_t cur_state;
size_t sum = 0;
int mb_len;
@@ -3358,7 +3716,4 @@ mbc_char_count(const char *ptr, size_t numbytes)
}
return sum;
-#else
- return numbytes;
-#endif
}
diff --git a/cint_array.c b/cint_array.c
index 3d812cbb..3945e6e7 100644
--- a/cint_array.c
+++ b/cint_array.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-2011 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-2013 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -25,6 +25,8 @@
#include "awk.h"
+#define INT32_BIT 32
+
extern FILE *output_fp;
extern void indent(int indent_level);
extern NODE **is_integer(NODE *symbol, NODE *subs);
@@ -37,7 +39,8 @@ extern NODE **is_integer(NODE *symbol, NODE *subs);
static int NHAT = 10;
static long THRESHOLD;
-/* What is the optimium NHAT ? timing results suggest that 10 is a good choice,
+/*
+ * What is the optimium NHAT ? timing results suggest that 10 is a good choice,
* although differences aren't that significant for > 10.
*/
@@ -52,13 +55,13 @@ static NODE **cint_list(NODE *symbol, NODE *t);
static NODE **cint_copy(NODE *symbol, NODE *newsymb);
static NODE **cint_dump(NODE *symbol, NODE *ndump);
#ifdef ARRAYDEBUG
-static NODE **cint_option(NODE *opt, NODE *val);
static void cint_print(NODE *symbol);
#endif
-array_ptr cint_array_func[] = {
+afunc_t cint_array_func[] = {
cint_array_init,
is_uinteger,
+ null_length,
cint_lookup,
cint_exists,
cint_clear,
@@ -66,9 +69,7 @@ array_ptr cint_array_func[] = {
cint_list,
cint_copy,
cint_dump,
-#ifdef ARRAYDEBUG
- cint_option,
-#endif
+ (afunc_t) 0,
};
static inline int cint_hash(long k);
@@ -81,7 +82,7 @@ static NODE **tree_exists(NODE *tree, long k);
static void tree_clear(NODE *tree);
static int tree_remove(NODE *symbol, NODE *tree, long k);
static void tree_copy(NODE *newsymb, NODE *tree, NODE *newtree);
-static long tree_list(NODE *tree, NODE **list, unsigned int flags);
+static long tree_list(NODE *tree, NODE **list, assoc_kind_t assoc_kind);
static inline NODE **tree_find(NODE *tree, long k, int i);
static void tree_info(NODE *tree, NODE *ndump, const char *aname);
static size_t tree_kilobytes(NODE *tree);
@@ -94,7 +95,7 @@ static inline NODE **leaf_exists(NODE *array, long k);
static void leaf_clear(NODE *array);
static int leaf_remove(NODE *symbol, NODE *array, long k);
static void leaf_copy(NODE *newsymb, NODE *array, NODE *newarray);
-static long leaf_list(NODE *array, NODE **list, unsigned int flags);
+static long leaf_list(NODE *array, NODE **list, assoc_kind_t assoc_kind);
static void leaf_info(NODE *array, NODE *ndump, const char *aname);
#ifdef ARRAYDEBUG
static void leaf_print(NODE *array, size_t bi, int indent_level);
@@ -142,16 +143,25 @@ static const long power_two_table[] = {
*
*/
-/* cint_array_init --- check relevant environment variables */
+/* cint_array_init --- array initialization routine */
static NODE **
cint_array_init(NODE *symbol ATTRIBUTE_UNUSED, NODE *subs ATTRIBUTE_UNUSED)
{
- long newval;
+ if (symbol == NULL) {
+ long newval;
+ size_t nelems = (sizeof(power_two_table) / sizeof(power_two_table[0]));
+
+ /* check relevant environment variables */
+ if ((newval = getenv_long("NHAT")) > 1 && newval < INT32_BIT)
+ NHAT = newval;
+ /* don't allow overflow off the end of the table */
+ if (NHAT >= nelems)
+ NHAT = nelems - 2;
+ THRESHOLD = power_two_table[NHAT + 1];
+ } else
+ null_array(symbol);
- if ((newval = getenv_long("NHAT")) > 1 && newval < INT32_BIT)
- NHAT = newval;
- THRESHOLD = power_two_table[NHAT + 1];
return (NODE **) ! NULL;
}
@@ -237,13 +247,11 @@ xinstall:
symbol->table_size++;
if (xn == NULL) {
- extern array_ptr int_array_func[];
- extern array_ptr str_array_func[];
-
xn = symbol->xarray = make_array();
xn->vname = symbol->vname; /* shallow copy */
- /* Avoid using assoc_lookup(xn, subs) which may lead
+ /*
+ * Avoid using assoc_lookup(xn, subs) which may lead
* to infinite recursion.
*/
@@ -302,7 +310,7 @@ cint_clear(NODE *symbol, NODE *subs ATTRIBUTE_UNUSED)
}
efree(symbol->nodes);
- init_array(symbol); /* re-initialize symbol */
+ symbol->ainit(symbol, NULL); /* re-initialize symbol */
return NULL;
}
@@ -316,10 +324,14 @@ cint_remove(NODE *symbol, NODE *subs)
int h1;
NODE *tn, *xn = symbol->xarray;
- assert(symbol->nodes != NULL);
+ if (symbol->table_size == 0)
+ return NULL;
+
if (! ISUINT(symbol, subs))
goto xremove;
+ assert(symbol->nodes != NULL);
+
k = subs->numbr;
h1 = cint_hash(k);
tn = symbol->nodes[h1];
@@ -335,9 +347,10 @@ cint_remove(NODE *symbol, NODE *subs)
if (xn == NULL && symbol->table_size == 0) {
efree(symbol->nodes);
- init_array(symbol); /* re-initialize array 'symbol' */
+ symbol->ainit(symbol, NULL); /* re-initialize array 'symbol' */
} else if(xn != NULL && symbol->table_size == xn->table_size) {
/* promote xn to symbol */
+
xn->flags &= ~XARRAY;
xn->parent_array = symbol->parent_array;
efree(symbol->nodes);
@@ -413,15 +426,16 @@ cint_list(NODE *symbol, NODE *t)
unsigned long k = 0, num_elems, list_size;
size_t j, ja, jd;
int elem_size = 1;
+ assoc_kind_t assoc_kind;
num_elems = symbol->table_size;
if (num_elems == 0)
return NULL;
-
- if ((t->flags & (AINDEX|AVALUE|ADELETE)) == (AINDEX|ADELETE))
+ assoc_kind = (assoc_kind_t) t->flags;
+ if ((assoc_kind & (AINDEX|AVALUE|ADELETE)) == (AINDEX|ADELETE))
num_elems = 1;
- if ((t->flags & (AINDEX|AVALUE)) == (AINDEX|AVALUE))
+ if ((assoc_kind & (AINDEX|AVALUE)) == (AINDEX|AVALUE))
elem_size = 2;
list_size = num_elems * elem_size;
@@ -429,7 +443,8 @@ cint_list(NODE *symbol, NODE *t)
xn = symbol->xarray;
list = xn->alist(xn, t);
assert(list != NULL);
- t->flags &= ~(AASC|ADESC);
+ assoc_kind &= ~(AASC|ADESC);
+ t->flags = (unsigned int) assoc_kind;
if (num_elems == 1 || num_elems == xn->table_size)
return list;
erealloc(list, NODE **, list_size * sizeof(NODE *), "cint_list");
@@ -437,18 +452,20 @@ cint_list(NODE *symbol, NODE *t)
} else
emalloc(list, NODE **, list_size * sizeof(NODE *), "cint_list");
-
- if ((t->flags & AINUM) == 0) /* not sorting by "index num" */
- t->flags &= ~(AASC|ADESC);
+ if ((assoc_kind & AINUM) == 0) {
+ /* not sorting by "index num" */
+ assoc_kind &= ~(AASC|ADESC);
+ t->flags = (unsigned int) assoc_kind;
+ }
/* populate it with index in ascending or descending order */
for (ja = NHAT, jd = INT32_BIT - 1; ja < INT32_BIT && jd >= NHAT; ) {
- j = (t->flags & ADESC) ? jd-- : ja++;
+ j = (assoc_kind & ADESC) != 0 ? jd-- : ja++;
tn = symbol->nodes[j];
if (tn == NULL)
continue;
- k += tree_list(tn, list + k, t->flags);
+ k += tree_list(tn, list + k, assoc_kind);
if (k >= list_size)
return list;
}
@@ -468,7 +485,6 @@ cint_dump(NODE *symbol, NODE *ndump)
AWKNUM kb = 0;
extern AWKNUM int_kilobytes(NODE *symbol);
extern AWKNUM str_kilobytes(NODE *symbol);
- extern array_ptr int_array_func[];
indent_level = ndump->alevel;
@@ -562,7 +578,8 @@ cint_hash(long k)
/* Find the Floor(log base 2 of 32-bit integer) */
- /* Warren Jr., Henry S. (2002). Hacker's Delight.
+ /*
+ * Warren Jr., Henry S. (2002). Hacker's Delight.
* Addison Wesley. pp. pp. 215. ISBN 978-0201914658.
*
* r = 0;
@@ -574,7 +591,8 @@ cint_hash(long k)
*/
- /* Slightly different code copied from:
+ /*
+ * Slightly different code copied from:
*
* http://www-graphics.stanford.edu/~seander/bithacks.html
* Bit Twiddling Hacks
@@ -619,22 +637,6 @@ cint_find(NODE *symbol, long k, int h1)
#ifdef ARRAYDEBUG
-static NODE **
-cint_option(NODE *opt, NODE *val)
-{
- NODE *tmp;
- NODE **ret = (NODE **) ! NULL;
-
- tmp = force_string(opt);
- (void) force_number(val);
- if (STREQ(tmp->stptr, "NHAT"))
- NHAT = (int) val->numbr;
- else
- ret = NULL;
- return ret;
-}
-
-
/* cint_print --- print structural info */
static void
@@ -840,14 +842,14 @@ tree_remove(NODE *symbol, NODE *tree, long k)
assert(i >= 0);
tn = tree->nodes[i];
if (tn == NULL)
- return FALSE;
+ return false;
if (tn->type == Node_array_tree
&& ! tree_remove(symbol, tn, k))
- return FALSE;
+ return false;
else if (tn->type == Node_array_leaf
&& ! leaf_remove(symbol, tn, k))
- return FALSE;
+ return false;
if (tn->table_size == 0) {
freenode(tn);
@@ -860,7 +862,7 @@ tree_remove(NODE *symbol, NODE *tree, long k)
memset(tree, '\0', sizeof(NODE));
tree->type = Node_array_tree;
}
- return TRUE;
+ return true;
}
@@ -885,7 +887,7 @@ tree_find(NODE *tree, long k, int i)
/* tree_list --- return a list of items in the HAT */
static long
-tree_list(NODE *tree, NODE **list, unsigned int flags)
+tree_list(NODE *tree, NODE **list, assoc_kind_t assoc_kind)
{
NODE *tn;
size_t j, cj, hsize;
@@ -898,15 +900,15 @@ tree_list(NODE *tree, NODE **list, unsigned int flags)
hsize /= 2;
for (j = 0; j < hsize; j++) {
- cj = (flags & ADESC) ? (hsize - 1 - j) : j;
+ cj = (assoc_kind & ADESC) != 0 ? (hsize - 1 - j) : j;
tn = tree->nodes[cj];
if (tn == NULL)
continue;
if (tn->type == Node_array_tree)
- k += tree_list(tn, list + k, flags);
+ k += tree_list(tn, list + k, assoc_kind);
else
- k += leaf_list(tn, list + k, flags);
- if ((flags & ADELETE) != 0 && k >= 1)
+ k += leaf_list(tn, list + k, assoc_kind);
+ if ((assoc_kind & ADELETE) != 0 && k >= 1)
return k;
}
return k;
@@ -1011,8 +1013,9 @@ tree_print(NODE *tree, size_t bi, int indent_level)
hsize = tree->array_size;
if ((tree->flags & HALFHAT) != 0)
hsize /= 2;
- fprintf(output_fp, "%4lu:%s[%4lu:%-4lu]\n", bi,
- (tree->flags & HALFHAT) ? "HH" : "H",
+ fprintf(output_fp, "%4lu:%s[%4lu:%-4lu]\n",
+ (unsigned long) bi,
+ (tree->flags & HALFHAT) != 0 ? "HH" : "H",
(unsigned long) hsize, (unsigned long) tree->table_size);
for (j = 0; j < hsize; j++) {
@@ -1029,9 +1032,10 @@ tree_print(NODE *tree, size_t bi, int indent_level)
/*--------------------- leaf (linear 1-D) array --------------------*/
-/* leaf_lookup --- find an integer subscript in the array; Install it if
- it isn't there.
-*/
+/*
+ * leaf_lookup --- find an integer subscript in the array; Install it if
+ * it isn't there.
+ */
static inline NODE **
leaf_lookup(NODE *symbol, NODE *array, long k, long size, long base)
@@ -1101,7 +1105,7 @@ leaf_remove(NODE *symbol, NODE *array, long k)
lhs = array->nodes + (k - array->array_base);
if (*lhs == NULL)
- return FALSE;
+ return false;
*lhs = NULL;
if (--array->table_size == 0) {
efree(array->nodes);
@@ -1109,7 +1113,7 @@ leaf_remove(NODE *symbol, NODE *array, long k)
symbol->array_capacity -= array->array_size;
array->array_size = 0; /* sanity */
}
- return TRUE;
+ return true;
}
@@ -1150,7 +1154,7 @@ leaf_copy(NODE *newsymb, NODE *array, NODE *newarray)
/* leaf_list --- return a list of items */
static long
-leaf_list(NODE *array, NODE **list, unsigned int flags)
+leaf_list(NODE *array, NODE **list, assoc_kind_t assoc_kind)
{
NODE *r, *subs;
long num, i, ci, k = 0;
@@ -1158,14 +1162,14 @@ leaf_list(NODE *array, NODE **list, unsigned int flags)
static char buf[100];
for (i = 0; i < size; i++) {
- ci = (flags & ADESC) ? (size - 1 - i) : i;
+ ci = (assoc_kind & ADESC) != 0 ? (size - 1 - i) : i;
r = array->nodes[ci];
if (r == NULL)
continue;
/* index */
num = array->array_base + ci;
- if (flags & AISTR) {
+ if ((assoc_kind & AISTR) != 0) {
sprintf(buf, "%ld", num);
subs = make_string(buf, strlen(buf));
subs->numbr = num;
@@ -1177,16 +1181,16 @@ leaf_list(NODE *array, NODE **list, unsigned int flags)
list[k++] = subs;
/* value */
- if (flags & AVALUE) {
+ if ((assoc_kind & AVALUE) != 0) {
if (r->type == Node_val) {
- if ((flags & AVNUM) != 0)
+ if ((assoc_kind & AVNUM) != 0)
(void) force_number(r);
- else if ((flags & AVSTR) != 0)
+ else if ((assoc_kind & AVSTR) != 0)
r = force_string(r);
}
list[k++] = r;
}
- if ((flags & ADELETE) != 0 && k >= 1)
+ if ((assoc_kind & ADELETE) != 0 && k >= 1)
return k;
}
@@ -1225,7 +1229,8 @@ static void
leaf_print(NODE *array, size_t bi, int indent_level)
{
indent(indent_level);
- fprintf(output_fp, "%4lu:L[%4lu:%-4lu]\n", bi,
+ fprintf(output_fp, "%4lu:L[%4lu:%-4lu]\n",
+ (unsigned long) bi,
(unsigned long) array->array_size,
(unsigned long) array->table_size);
}
diff --git a/cmake/Toolchain_clang.cmake b/cmake/Toolchain_clang.cmake
new file mode 100644
index 00000000..89353570
--- /dev/null
+++ b/cmake/Toolchain_clang.cmake
@@ -0,0 +1,19 @@
+# http://www.cmake.org/Wiki/CmakeMingw
+# http://www.cmake.org/Wiki/CMake_Cross_Compiling#The_toolchain_file
+
+# the name of the target operating system
+SET(CMAKE_SYSTEM_NAME Generic)
+
+# which compilers to use for C and C++
+SET(CMAKE_C_COMPILER /usr/bin/clang)
+
+# here is the target environment located
+SET(CMAKE_FIND_ROOT_PATH /usr/lib64/clang/3.1)
+
+# adjust the default behaviour of the FIND_XXX() commands:
+# search headers and libraries in the target environment, search
+# programs in the host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
diff --git a/cmake/Toolchain_generic.cmake b/cmake/Toolchain_generic.cmake
new file mode 100644
index 00000000..91ddc6e7
--- /dev/null
+++ b/cmake/Toolchain_generic.cmake
@@ -0,0 +1,21 @@
+# http://www.cmake.org/Wiki/CmakeMingw
+# http://www.cmake.org/Wiki/CMake_Cross_Compiling#The_toolchain_file
+
+# the name of the target operating system
+SET(CMAKE_SYSTEM_NAME Generic)
+
+# which compilers to use for C and C++
+# Settings for Ubuntu 12.04.1 LTS
+SET(CMAKE_C_COMPILER /usr/bin/gcc)
+
+# here is the target environment located
+# Settings for Ubuntu 12.04.1 LTS
+SET(CMAKE_FIND_ROOT_PATH /usr/)
+
+# adjust the default behaviour of the FIND_XXX() commands:
+# search headers and libraries in the target environment, search
+# programs in the host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
diff --git a/cmake/Toolchain_mingw32.cmake b/cmake/Toolchain_mingw32.cmake
new file mode 100644
index 00000000..bb885f2f
--- /dev/null
+++ b/cmake/Toolchain_mingw32.cmake
@@ -0,0 +1,23 @@
+# http://www.cmake.org/Wiki/CmakeMingw
+# http://www.cmake.org/Wiki/CMake_Cross_Compiling#The_toolchain_file
+
+# the name of the target operating system
+SET(CMAKE_SYSTEM_NAME Windows)
+
+# which compilers to use for C and C++
+# Settings for Ubuntu 12.04.1 LTS
+SET(CMAKE_C_COMPILER /usr/bin/i686-w64-mingw32-gcc)
+SET(CMAKE_CXX_COMPILER /usr/bin/i686-w64-mingw32-g++)
+SET(CMAKE_RC_COMPILER /usr/bin/i686-w64-mingw32-windres)
+
+# here is the target environment located
+# Settings for Ubuntu 12.04.1 LTS
+SET(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32)
+
+# adjust the default behaviour of the FIND_XXX() commands:
+# search headers and libraries in the target environment, search
+# programs in the host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
diff --git a/cmake/Toolchain_s390.cmake b/cmake/Toolchain_s390.cmake
new file mode 100644
index 00000000..e1cdcfff
--- /dev/null
+++ b/cmake/Toolchain_s390.cmake
@@ -0,0 +1,20 @@
+# http://www.cmake.org/Wiki/CmakeMingw
+# http://www.cmake.org/Wiki/CMake_Cross_Compiling#The_toolchain_file
+# http://wiki.debian.org/EmdebianToolchain#Get_the_binaries
+
+# the name of the target operating system
+SET(CMAKE_SYSTEM_NAME Generic)
+
+# which compilers to use for C and C++
+SET(CMAKE_C_COMPILER /usr/bin/s390-linux-gnu-gcc-4.4)
+
+# here is the target environment located
+SET(CMAKE_FIND_ROOT_PATH /usr/s390-linux-gnu/)
+
+# adjust the default behaviour of the FIND_XXX() commands:
+# search headers and libraries in the target environment, search
+# programs in the host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
diff --git a/cmake/auk.ico b/cmake/auk.ico
new file mode 100644
index 00000000..795ef1d9
--- /dev/null
+++ b/cmake/auk.ico
Binary files differ
diff --git a/cmake/basictest b/cmake/basictest
new file mode 100755
index 00000000..210ed224
--- /dev/null
+++ b/cmake/basictest
@@ -0,0 +1,553 @@
+#!/bin/sh
+
+# Use this for debugging the test cases.
+# The resulting textual output will not destroy the test cases.
+set -x
+# After test case execution, the output can be found in
+# build/Testing/Temporary/LastTest.log
+
+export PATH=$PATH:/c/MinGW/msys/1.0/bin
+export GAWKEXE=$1
+export TESTCASE=$2
+TOPSRCDIR=$(dirname ${0})/..
+SRCDIR=${TOPSRCDIR}/test
+export AWKPATH=${SRCDIR}
+export AWKLIBPATH=$(dirname ${GAWKEXE})/extension/
+export LANG=C
+# Is this shell running in a native MinGW shell (MSYS) ?
+if test -n "$COMSPEC"; then
+ # Ignore all differences in white space.
+ COMPARE="diff -w"
+ PATH_SEPARATOR="\\"
+else
+ # This is a shell running in Unix environment.
+ COMPARE="cmp"
+ PATH_SEPARATOR="/"
+fi
+
+# This is the central function for executing a standard test case.
+# Many of the more specialized test cases rely on this function.
+function simple_test_case() {
+ local options=$1 # options passed to the gawk executable
+ local parameters=$2 # parameters passed to the test case script
+ cd ${SRCDIR}
+ if test -r ${TESTCASE}.in
+ # Any existing .in file will be redirected to standard input.
+ # The output redirection must be bound to the test script, otherwise
+ # the "set -x" logging would mix with the test case output.
+ then
+ ${pregawk} $GAWKEXE ${options} -f ${TESTCASE}.awk ${parameters} < ${TESTCASE}.in ${postgawk} > _${TESTCASE} 2>&1
+ else
+ ${pregawk} $GAWKEXE ${options} -f ${TESTCASE}.awk ${parameters} ${postgawk} > _${TESTCASE} 2>&1
+ fi || echo EXIT CODE: $? >> _${TESTCASE}
+ # Compare the expected (correct) output with the actual output.
+ ${COMPARE} ${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+ # If the comparison succeeds then remove the actual output.
+ # Else leave the actual output file untouched for later analysis.
+}
+
+# Each test case that cannot be handle in the "standard way" shall
+# be implemented as a function here.
+
+function lintold() { simple_test_case "--lint-old" "" ; }
+function defref() { simple_test_case "--lint" "" ; }
+function fmtspcl() { simple_test_case "--lint" "" ; }
+function lintwarn() { simple_test_case "--lint" "" ; }
+function noeffect() { simple_test_case "--lint" "" ; }
+function nofmtch() { simple_test_case "--lint" "" ; }
+function shadow() { simple_test_case "--lint" "" ; }
+function uninit2() { simple_test_case "--lint" "" ; }
+function uninit3() { simple_test_case "--lint" "" ; }
+function uninit4() { simple_test_case "--lint" "" ; }
+function uninit5() { simple_test_case "--lint" "" ; }
+function uninitialized() { simple_test_case "--lint" "" ; }
+
+function 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=$GAWKEXE ${SRCDIR}/regtest.sh
+}
+
+function compare() { simple_test_case "" "0 1" ; }
+
+function inftest() {
+ echo This test is very machine specific...
+ $GAWKEXE -f ${SRCDIR}/inftest.awk | sed "s/inf/Inf/g" >_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function getline2() { simple_test_case "" "getline2.awk getline2.awk" ; }
+
+function awkpath() {
+ AWKPATH="${SRCDIR}$(PATH_SEPARATOR)/lib" $GAWKEXE -f awkpath.awk >_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function argtest() { simple_test_case "" "-x -y abc" ; }
+
+function badargs() {
+ $GAWKEXE -f 2>&1 | grep -v patchlevel >_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function nonl() { simple_test_case "--lint" "/dev/null" ; }
+
+function poundbang() {
+# The original poundbang test case looks a bit non-deterministic.
+# This is a shortened version.
+ sed "s;/tmp/gawk;$GAWKEXE;" < ${SRCDIR}/poundbang.awk > ./_pbd.awk
+ chmod +x ./_pbd.awk
+ ./_pbd.awk ${SRCDIR}/poundbang.awk > _`basename ${TESTCASE}` ;
+ ${COMPARE} ${SRCDIR}/poundbang.awk _`basename ${TESTCASE}` && rm -f _`basename ${TESTCASE}` _pbd.awk
+}
+
+function messages() {
+ $GAWKEXE -f ${SRCDIR}/messages.awk >_out2 2>_out3
+ ${COMPARE} ${SRCDIR}/out1.ok _out1 && ${COMPARE} ${SRCDIR}/out2.ok _out2 && ${COMPARE} ${SRCDIR}/out3.ok _out3 && rm -f _out1 _out2 _out3
+}
+
+function argarray() {
+ case ${SRCDIR} in
+ .) : ;;
+ *) cp ${SRCDIR}/argarray.in . ;;
+ esac
+ TEST=test echo just a test | $GAWKEXE -f ${SRCDIR}/argarray.awk ./argarray.in - >_${TESTCASE}
+ case ${SRCDIR} in
+ .) : ;;
+ *) rm -f ./argarray.in ;;
+ esac
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+
+function localenl() {
+ ${SRCDIR}/${TESTCASE}.sh >_${TESTCASE} 2>/dev/null
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function mbprintf1() {
+ GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE
+ LANG=en_US.UTF-8
+ $GAWKEXE -f ${SRCDIR}/${TESTCASE}.awk ${SRCDIR}/${TESTCASE}.in >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >> _${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function mbfw1() {
+ GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE
+ LANG=en_US.UTF-8
+ $GAWKEXE -f ${SRCDIR}/${TESTCASE}.awk ${SRCDIR}/${TESTCASE}.in >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >> _${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function printfbad2() {
+ $GAWKEXE --lint -f ${SRCDIR}/${TESTCASE}.awk ${SRCDIR}/${TESTCASE}.in 2>&1 | sed "s;$SRCDIR/;;g" >_${TESTCASE} || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function beginfile1() {
+ AWKPATH=${SRCDIR} $GAWKEXE -f ${TESTCASE}.awk ${SRCDIR}/${TESTCASE}.awk . ./no/such/file Makefile >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function beginfile2() {
+ # This differs from the original, the pwd part is new.
+ # The re-direction is now bound to the .sh file.
+ # This way the output of "set -x" is not written to the script's output file.
+ ( cd ${SRCDIR} && LC_ALL=C AWK="$GAWKEXE" ${SRCDIR}/${TESTCASE}.sh ${SRCDIR}/${TESTCASE}.in > `pwd`/_${TESTCASE} 2>&1 )
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok ${SRCDIR}/_${TESTCASE} && rm -f ${SRCDIR}/_${TESTCASE}
+}
+
+function dumpvars() {
+ AWKPATH=${SRCDIR} $GAWKEXE --dump-variables 1 < ${SRCDIR}/${TESTCASE}.in >/dev/null 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ mv awkvars.out _${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function manyfiles() {
+ rm -rf junk
+ mkdir junk
+ $GAWKEXE 'BEGIN { for (i = 1; i <= 1030; i++) print i, i}' >_${TESTCASE}
+ $GAWKEXE -f ${SRCDIR}/manyfiles.awk _${TESTCASE} _${TESTCASE}
+ wc -l junk/* | $GAWKEXE '$1 != 2' | wc -l | sed "s/ *//g" > _${TESTCASE}
+ rm -rf junk
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function exitval1() {
+ $GAWKEXE -f ${SRCDIR}/exitval1.awk >_${TESTCASE} 2>&1; echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function fsspcoln() {
+ $GAWKEXE -f ${SRCDIR}/${TESTCASE}.awk 'FS=[ :]+' ${SRCDIR}/${TESTCASE}.in >_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function rsstart2() {
+ $GAWKEXE -f ${SRCDIR}/${TESTCASE}.awk ${SRCDIR}/rsstart1.in >_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function rsstart3() {
+ head ${SRCDIR}/rsstart1.in | $GAWKEXE -f ${SRCDIR}/rsstart2.awk >_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function strftime() {
+ echo This test could fail on slow machines or on a minute boundary,
+ echo so if it does, double check the actual results:
+ GAWKLOCALE=C; export GAWKLOCALE
+ TZ=GMT0; export TZ
+ (LC_ALL=C date) | $GAWKEXE -v OUTPUT=_${TESTCASE} -f ${SRCDIR}/strftime.awk
+ ${COMPARE} strftime.ok _${TESTCASE} && rm -f _${TESTCASE} strftime.ok || exit 0
+}
+
+function inplace1() {
+ cp ${SRCDIR}/inplace.1.in _${TESTCASE}.1
+ cp ${SRCDIR}/inplace.2.in _${TESTCASE}.2
+ AWKPATH=${SRCDIR}/../awklib/eg/lib $GAWKEXE -i inplace 'BEGIN {print "before"} {gsub(/foo/, "bar"); print} END {print "after"}' _${TESTCASE}.1 - _${TESTCASE}.2 < ${SRCDIR}/inplace.in >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.1.ok _${TESTCASE}.1 && rm -f _${TESTCASE}.1
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.2.ok _${TESTCASE}.2 && rm -f _${TESTCASE}.2
+}
+
+function inplace2() {
+ cp ${SRCDIR}/inplace.1.in _${TESTCASE}.1
+ cp ${SRCDIR}/inplace.2.in _${TESTCASE}.2
+ AWKPATH=${SRCDIR}/../awklib/eg/lib $GAWKEXE -i inplace -v INPLACE_SUFFIX=.bak 'BEGIN {print "before"} {gsub(/foo/, "bar"); print} END {print "after"}' _${TESTCASE}.1 - _${TESTCASE}.2 < ${SRCDIR}/inplace.in >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.1.ok _${TESTCASE}.1 && rm -f _${TESTCASE}.1
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.1.bak.ok _${TESTCASE}.1.bak && rm -f _${TESTCASE}.1.bak
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.2.ok _${TESTCASE}.2 && rm -f _${TESTCASE}.2
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.2.bak.ok _${TESTCASE}.2.bak && rm -f _${TESTCASE}.2.bak
+}
+
+function inplace3() {
+ cp ${SRCDIR}/inplace.1.in _${TESTCASE}.1
+ cp ${SRCDIR}/inplace.2.in _${TESTCASE}.2
+ AWKPATH=${SRCDIR}/../awklib/eg/lib $GAWKEXE -i inplace -v INPLACE_SUFFIX=.bak 'BEGIN {print "before"} {gsub(/foo/, "bar"); print} END {print "after"}' _${TESTCASE}.1 - _${TESTCASE}.2 < ${SRCDIR}/inplace.in >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ AWKPATH=${SRCDIR}/../awklib/eg/lib $GAWKEXE -i inplace -v INPLACE_SUFFIX=.bak 'BEGIN {print "Before"} {gsub(/bar/, "foo"); print} END {print "After"}' _${TESTCASE}.1 - _${TESTCASE}.2 < ${SRCDIR}/inplace.in >>_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.1.ok _${TESTCASE}.1 && rm -f _${TESTCASE}.1
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.1.bak.ok _${TESTCASE}.1.bak && rm -f _${TESTCASE}.1.bak
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.2.ok _${TESTCASE}.2 && rm -f _${TESTCASE}.2
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.2.bak.ok _${TESTCASE}.2.bak && rm -f _${TESTCASE}.2.bak
+}
+
+function testext() {
+ $GAWKEXE ' /^(@load|BEGIN)/,/^}/' ${SRCDIR}/../extension/testext.c > testext.awk
+ $GAWKEXE -f ${TESTCASE}.awk > ${SRCDIR}/_${TESTCASE} 2>&1 || echo EXIT CODE: $? >> ${SRCDIR}/_${TESTCASE}
+ rm -f testext.awk
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok ${SRCDIR}/_${TESTCASE} && rm -f ${SRCDIR}/_${TESTCASE}
+}
+
+function readdir() {
+ if [ "`uname`" = Linux ] && [ "`stat -f . 2>/dev/null | awk 'NR == 2 { print $NF }'`" = nfs ]; then
+ echo This test may fail on GNU/Linux systems when run on an NFS filesystem.;
+ echo If it does, try rerunning on an ext'[234]' filesystem. ;
+ fi
+ $GAWKEXE -f ${TESTCASE}.awk ${SRCDIR}/.. > ${SRCDIR}/_${TESTCASE} 2>&1
+ ls -afli ${TOPSRCDIR} | sed 1d | $GAWKEXE -f ${SRCDIR}/readdir0.awk -v extout=${SRCDIR}/_${TESTCASE} > ${SRCDIR}/${TESTCASE}.ok
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok ${SRCDIR}/_${TESTCASE} && rm -f ${SRCDIR}/_${TESTCASE} ${SRCDIR}/${TESTCASE}.ok
+}
+
+function ordchr2() {
+ $GAWKEXE -l ordchr 'BEGIN {print chr(ord("z"))}' >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function include2() {
+ AWKPATH=${SRCDIR} $GAWKEXE -i inclib 'BEGIN {print sandwich("a", "b", "c")}' >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function incdupe() {
+ AWKPATH=${SRCDIR} $GAWKEXE --lint -i inclib -i inclib.awk 'BEGIN {print sandwich("a", "b", "c")}' >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function incdupe2() {
+ AWKPATH=${SRCDIR} $GAWKEXE --lint -f inclib -f inclib.awk >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function incdupe3() {
+ AWKPATH=${SRCDIR} $GAWKEXE --lint -f hello -f hello.awk >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function incdupe4() {
+ AWKPATH=${SRCDIR} $GAWKEXE --lint -f hello -i hello.awk >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function incdupe5() {
+ AWKPATH=${SRCDIR} $GAWKEXE --lint -i hello -f hello.awk >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function incdupe6() {
+ AWKPATH=${SRCDIR} $GAWKEXE --lint -i inchello -f hello.awk >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function incdupe7() {
+ AWKPATH=${SRCDIR} $GAWKEXE --lint -f hello -i inchello >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+# TODO: The compare operation passes even when there are diffs.
+function readfile() {
+ $GAWKEXE -l readfile 'BEGIN {printf "%s", readfile("Makefile")}' >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} Makefile _${TESTCASE} && rm -f _${TESTCASE} || cp -p Makefile ${TESTCASE}.ok
+}
+
+function fts() {
+ if [ "`uname`" = IRIX ]; then \
+ echo This test may fail on IRIX systems when run on an NFS filesystem.; \
+ echo If it does, try rerunning on an xfs filesystem. ; \
+ fi
+ simple_test_case "" ""
+}
+
+function charasbytes() {
+ [ -z "$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH=${SRCDIR} $GAWKEXE -b -v BINMODE=2 -f ${TESTCASE}.awk ${SRCDIR}/${TESTCASE}.in | \
+ od -c -t x1 | sed -e 's/ */ /g' -e 's/ *$//' >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function symtab6() {
+ $GAWKEXE -d__${TESTCASE} -f ${SRCDIR}/${TESTCASE}.awk
+ grep -v '^ENVIRON' __${TESTCASE} | grep -v '^PROCINFO' > _${TESTCASE} ; rm __${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function symtab8() {
+ $GAWKEXE -d__${TESTCASE} -f ${SRCDIR}/${TESTCASE}.awk ${SRCDIR}/${TESTCASE}.in >_${TESTCASE}
+ grep -v '^ENVIRON' __${TESTCASE} | grep -v '^PROCINFO' | grep -v '^FILENAME' >> _${TESTCASE} ; rm __${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function colonwarn() {
+ for i in 1 2 3 ; \
+ do $GAWKEXE -f ${SRCDIR}/${TESTCASE}.awk $i < ${SRCDIR}/${TESTCASE}.in ; \
+ done > _${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function litoct() {
+ echo ab | $GAWKEXE --traditional -f ${SRCDIR}/litoct.awk >_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function devfd() {
+ $GAWKEXE 1 /dev/fd/4 /dev/fd/5 4<${SRCDIR}/devfd.in4 5<${SRCDIR}/devfd.in5 >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >> _${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function fflush() {
+ ${SRCDIR}/fflush.sh >_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function mmap8k() {
+ $GAWKEXE '{ print }' ${SRCDIR}/mmap8k.in >_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/mmap8k.in _${TESTCASE} && rm -f _${TESTCASE} || cp ${SRCDIR}/${TESTCASE}.in ${TESTCASE}.ok
+}
+
+function pid() {
+ AWKPATH=${SRCDIR} AWK=$GAWKEXE ${SHELL} ${SRCDIR}/pid.sh $$ > _${TESTCASE} ; :
+ ${COMPARE} ${SRCDIR}/pid.ok _`basename ${TESTCASE}` && rm -f _${TESTCASE}
+}
+
+function strftlng() {
+ TZ=UTC; export TZ; $GAWKEXE -f ${SRCDIR}/strftlng.awk >_${TESTCASE}
+ if ${COMPARE} ${SRCDIR}/strftlng.ok _${TESTCASE} >/dev/null 2>&1 ; then : ; else \
+ TZ=UTC0; export TZ; $GAWKEXE -f ${SRCDIR}/strftlng.awk >_${TESTCASE} ; \
+ fi
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function nors() {
+ echo A B C D E | tr -d '\12\15' | $GAWKEXE '{ print $NF }' - ${SRCDIR}/nors.in > _${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function fmtspcl() {
+ $GAWKEXE -v "sd=${SRCDIR}" 'BEGIN {pnan = sprintf("%g",sqrt(-1)); nnan = sprintf("%g",-sqrt(-1)); pinf = sprintf("%g",-log(0)); ninf = sprintf("%g",log(0))} {sub(/positive_nan/,pnan); sub(/negative_nan/,nnan); sub(/positive_infinity/,pinf); sub(/negative_infinity/,ninf); sub(/fmtspcl/,(sd"/fmtspcl")); print}' < ${SRCDIR}/fmtspcl.tok > ${TESTCASE}.ok 2>/dev/null
+ $GAWKEXE $AWKFLAGS -f ${SRCDIR}/fmtspcl.awk --lint >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ if test -z "$AWKFLAGS" ; then
+ ${COMPARE} ${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+ else
+ ${COMPARE} ${SRCDIR}/${TESTCASE}-mpfr.ok _${TESTCASE} && rm -f _${TESTCASE}
+ fi
+}
+
+function pipeio2() { simple_test_case "-v SRCDIR=${SRCDIR}" "" ; }
+
+function arynocls() {
+ AWKPATH=${SRCDIR} $GAWKEXE -v INPUT=${SRCDIR}/arynocls.in -f arynocls.awk >_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function inetechu() {
+ echo This test is for establishing UDP connections
+ $GAWKEXE 'BEGIN {print "" |& "/inet/udp/0/127.0.0.1/9"}'
+}
+
+function inetecht() {
+ echo This test is for establishing TCP connections
+ $GAWKEXE 'BEGIN {print "" |& "/inet/tcp/0/127.0.0.1/9"}'
+}
+
+function inetdayu() {
+ echo This test is for bidirectional UDP transmission
+ $GAWKEXE 'BEGIN { print "" |& "/inet/udp/0/127.0.0.1/13"; \
+ "/inet/udp/0/127.0.0.1/13" |& getline; print $0}'
+}
+
+function inetdayt() {
+ echo This test is for bidirectional TCP transmission
+ $GAWKEXE 'BEGIN { print "" |& "/inet/tcp/0/127.0.0.1/13"; \
+ "/inet/tcp/0/127.0.0.1/13" |& getline; print $0}'
+}
+
+function redfilnm() { simple_test_case "" "srcdir=${SRCDIR}" ; }
+
+function leaddig() { simple_test_case "-v x=2E" "" ; }
+function longwrds() { simple_test_case "-vSORT=sort" "" ; }
+
+function gsubtst3() {
+ $GAWKEXE --re-interval -f ${SRCDIR}/${TESTCASE}.awk ${SRCDIR}/${TESTCASE}.in >_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function space() {
+ $GAWKEXE -f ' ' ${SRCDIR}/space.awk >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function rsnulbig() {
+ # Suppose that block size for pipe is at most 128kB:
+ $GAWKEXE 'BEGIN { for (i = 1; i <= 128*64+1; i++) print "abcdefgh123456\n" }' 2>&1 | \
+ $GAWKEXE 'BEGIN { RS = ""; ORS = "\n\n" }; { print }' 2>&1 | \
+ $GAWKEXE '/^[^a]/; END{ print NR }' >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function rsnulbig2() {
+ $GAWKEXE '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 | \
+ $GAWKEXE 'BEGIN { RS = ""; ORS = "\n\n" };{ print }' 2>&1 | \
+ $GAWKEXE '/^[^a]/; END { print NR }' >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function printf0() { simple_test_case "--posix" "" ; }
+
+function profile1() {
+ $GAWKEXE --pretty-print=ap-${TESTCASE}.out -f ${SRCDIR}/xref.awk ${SRCDIR}/dtdgport.awk > _${TESTCASE}.out1
+ $GAWKEXE -f ap-${TESTCASE}.out ${SRCDIR}/dtdgport.awk > _${TESTCASE}.out2 ; rm ap-${TESTCASE}.out
+ ${COMPARE} _${TESTCASE}.out1 _${TESTCASE}.out2 && rm _${TESTCASE}.out[12] || { echo EXIT CODE: $$? >>_${TESTCASE} ; \
+ cp $(srcdir)/dtdgport.awk > ${TESTCASE}.ok ; }
+}
+
+function profile2() {
+ $GAWKEXE --profile=ap-${TESTCASE}.out -v sortcmd=sort -f ${SRCDIR}/xref.awk ${SRCDIR}/dtdgport.awk > /dev/null
+ sed 1,2d < ap-${TESTCASE}.out > _${TESTCASE}; rm ap-${TESTCASE}.out
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function profile3() {
+ $GAWKEXE --profile=ap-${TESTCASE}.out -f ${SRCDIR}/${TESTCASE}.awk > /dev/null
+ sed 1,2d < ap-${TESTCASE}.out > _${TESTCASE}; rm ap-${TESTCASE}.out
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function profile4() {
+ GAWK_NO_PP_RUN=1 $GAWKEXE --profile=ap-${TESTCASE}.out -f ${SRCDIR}/${TESTCASE}.awk > /dev/null
+ sed 1,2d < ap-${TESTCASE}.out > _${TESTCASE}; rm ap-${TESTCASE}.out
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function profile5() {
+ GAWK_NO_PP_RUN=1 $GAWKEXE --profile=ap-${TESTCASE}.out -f ${SRCDIR}/${TESTCASE}.awk > /dev/null
+ sed 1,2d < ap-${TESTCASE}.out > _${TESTCASE}; rm ap-${TESTCASE}.out
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function posix2008sub() {
+ $GAWKEXE --posix -f ${SRCDIR}/${TESTCASE}.awk > _${TESTCASE} 2>&1
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function next() {
+ LC_ALL=${GAWKLOCALE:-C} LANG=${GAWKLOCALE:-C} AWK="$GAWKEXE" ${SRCDIR}/${TESTCASE}.sh > _${TESTCASE} 2>&1
+ LC_ALL=C ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function exit() {
+ AWK="$GAWKEXE" ${SRCDIR}/${TESTCASE}.sh > _${TESTCASE} 2>&1
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function mpfrexprange() { simple_test_case "-M -vPREC=53 " "" ; }
+function mpfrrnd() { simple_test_case "-M -vPREC=53 " "" ; }
+function mpfrnr() { simple_test_case "-M -vPREC=113" "" ; }
+function mpfrbigint() { simple_test_case "-M " "" ; }
+
+function jarebug() {
+ ${SRCDIR}/${TESTCASE}.sh "$GAWKEXE" "${SRCDIR}/${TESTCASE}.awk" "${SRCDIR}/${TESTCASE}.in" "_${TESTCASE}"
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function rtlen() {
+ ${SRCDIR}/${TESTCASE}.sh >_${TESTCASE} || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function rtlen01() {
+ ${SRCDIR}/${TESTCASE}.sh >_${TESTCASE} || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function rtlenmb() {
+ GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE
+ ${SRCDIR}/rtlen.sh >_${TESTCASE} || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function nondec2() { simple_test_case "--non-decimal-data -v a=0x1" "" ; }
+
+function nofile() {
+ $GAWKEXE '{}' no/such/file >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function binmode1() {
+ $GAWKEXE -v BINMODE=3 'BEGIN { print BINMODE }' >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function devfd1() {
+ $GAWKEXE -f ${SRCDIR}/${TESTCASE}.awk 4< ${SRCDIR}/devfd.in1 5< ${SRCDIR}/devfd.in2 >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+function devfd2() {
+ # The program text is the '1' which will print each record. How compact can you get?
+ $GAWKEXE 1 /dev/fd/4 /dev/fd/5 4< ${SRCDIR}/devfd.in1 5< ${SRCDIR}/devfd.in2 >_${TESTCASE} 2>&1 || echo EXIT CODE: $? >>_${TESTCASE}
+ ${COMPARE} ${SRCDIR}/${TESTCASE}.ok _${TESTCASE} && rm -f _${TESTCASE}
+}
+
+# Is this test case implemented as a function ?
+if [ "$( type -t $TESTCASE )" = "function" ]
+then
+ $TESTCASE
+else
+ # If no function exists, then treat the test case in standard way.
+ simple_test_case "" ""
+fi
+
diff --git a/cmake/configure b/cmake/configure
new file mode 100755
index 00000000..d375a81c
--- /dev/null
+++ b/cmake/configure
@@ -0,0 +1,58 @@
+#!/bin/sh
+# On 2013-05-14 Arnold wrote in an e-mail:
+
+# <QUOTE)
+# I think that using CMake would be more palatable if there is also a simple
+# configure wrapper that can be used by people who build distributions. This would
+# mean things like
+#
+# configure CC=XXXX # XXXX in { gcc, clang, tcc } or native platform cc
+# configure --prefix=/path/to/install
+#
+# And the few other current configure options like --with-whiny-user-strftime,
+# --disable-nls, etc. I don't know if we need all the standard configure options,
+# but I do want the ones I've added in configure.ac.
+# </QUOTE)
+
+
+# Anyone using this script still needs an out-of-source build directory.
+if [ -f CMakeLists.txt ] ; then
+ echo "Your current working directory contains a file CMakeLists.txt, indicating"
+ echo "that this is a source directory. Create a new directory elsewhere, change into"
+ echo "this empty directory and try again."
+ echo " mkdir build"
+ echo " cd build"
+ echo " ../$0"
+ exit 1
+fi
+
+# TODO: Evaluate all the options and translate the options into CMake variables.
+CC=$( which cc )
+PREFIX=""
+SRCDIR=".."
+WHINY=""
+
+for p in $@
+do
+ if [ ${p:0:3} = "CC=" ]; then CC=${p:3}; fi
+ if [ ${p:0:9} = "--prefix=" ]; then PREFIX=-DCMAKE_INSTALL_PREFIX=${p:9}; fi
+ if [ ${p:0:9} = "--srcdir=" ]; then SRCDIR=${p:9}; fi
+ if [ ${p:0:26} = "--with-whiny-user-strftime" ]; then WHINY=-DUSE_INCLUDED_STRFTIME=1; fi
+done
+CC=$( which $CC )
+
+rm -f Toolchain.cmake
+(
+ echo "set(CMAKE_C_COMPILER $CC)"
+ echo "set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)"
+ echo "set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)"
+ echo "set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)"
+) > Toolchain.cmake
+
+if ! [ -f ${SRCDIR}/CMakeLists.txt ] ; then
+ echo "The source directory (${SRCDIR}) does not contain a file CMakeLists.txt."
+ exit 1
+fi
+
+cmake ${PREFIX} ${WHINY} -DCMAKE_TOOLCHAIN_FILE=Toolchain.cmake ${SRCDIR}
+
diff --git a/cmake/configure.cmake b/cmake/configure.cmake
new file mode 100644
index 00000000..7dbe841c
--- /dev/null
+++ b/cmake/configure.cmake
@@ -0,0 +1,300 @@
+#
+# cmake/configure --- CMake input file for gawk
+#
+# Copyright (C) 2013-2014
+# 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 3 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 CMake to produce Makefile
+
+option (USE_CONFIG_H "Generate a file config.h for inclusion into C source code" ON)
+if (USE_CONFIG_H)
+ file( WRITE config.h "/* all settings defined by CMake. */\n\n" )
+ ADD_DEFINITIONS (-D HAVE_CONFIG_H)
+ # Configure a header file to pass some of the CMake settings
+ # to the source code
+ # http://www.cmake.org/cmake/help/v2.8.8/cmake.html#command:configure_file
+ # CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.cmake.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h IMMEDIATE )
+else()
+ file( WRITE config.h "/* empty file, all settings defined by CMake. */" )
+endif()
+
+include(CheckIncludeFiles)
+include(CheckIncludeFile)
+include(CheckSymbolExists)
+include(CheckFunctionExists)
+include(CheckLibraryExists)
+include(CheckTypeSize)
+include(CheckStructHasMember)
+INCLUDE(CheckCSourceCompiles)
+include(CheckPrototypeDefinition)
+
+MACRO(DefineConfigH feature)
+# message(STATUS feature=${feature}=${${feature}})
+ if (${feature})
+ if (${USE_CONFIG_H} STREQUAL ON)
+ FILE( APPEND config.h "#define ${feature} ${${feature}}\n")
+ else()
+ #ADD_DEFINITIONS (-D ${feature})
+ ADD_DEFINITIONS (-D${feature}=${${feature}})
+ endif ()
+ endif ()
+ENDMACRO(DefineConfigH)
+
+MACRO(DefineConfigHValue feature value)
+ set(${feature} ${value})
+ DefineConfigH(${feature})
+ENDMACRO(DefineConfigHValue)
+
+MACRO(DefineFunctionIfAvailable func feature)
+ check_function_exists("${func}" "${feature}")
+ DefineConfigH(${feature})
+ENDMACRO(DefineFunctionIfAvailable)
+
+MACRO(DefineHFileIfAvailable hfile feature)
+ check_include_file("${hfile}" "${feature}")
+ DefineConfigH(${feature})
+ENDMACRO(DefineHFileIfAvailable)
+
+MACRO(DefineTypeIfAvailable type feature)
+ check_type_size("${type}" "${feature}")
+ DefineConfigH(${feature})
+ENDMACRO(DefineTypeIfAvailable)
+
+MACRO(DefineSymbolIfAvailable symbol hfile feature)
+ check_symbol_exists("${symbol}" "${hfile}" "${feature}")
+ DefineConfigH(${feature})
+ENDMACRO(DefineSymbolIfAvailable)
+
+MACRO(DefineStructHasMemberIfAvailable struct member hfile feature)
+ check_struct_has_member("${struct}" "${member}" "${hfile}" "${feature}")
+ DefineConfigH(${feature})
+ENDMACRO(DefineStructHasMemberIfAvailable)
+
+MACRO(DefineLibraryIfAvailable lib func location feature)
+ check_library_exists("${lib}" "${func}" "${location}" "${feature}")
+ DefineConfigH(${feature})
+ENDMACRO(DefineLibraryIfAvailable)
+
+MACRO(DefineIfSourceCompiles source feature)
+ check_c_source_compiles( "${source}" "${feature}")
+ DefineConfigH(${feature})
+ENDMACRO(DefineIfSourceCompiles)
+
+FILE( READ configure.ac CONFIG_AUTOMAKE )
+STRING( REGEX MATCH "AC_INIT\\(\\[GNU Awk\\], ([0-9]+\\.[0-9]+\\.[0-9]+)" GAWK_AUTOMAKE_LINE_VERSION "${CONFIG_AUTOMAKE}")
+STRING( REGEX REPLACE ".*([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" GAWK_MAJOR_VERSION "${GAWK_AUTOMAKE_LINE_VERSION}")
+STRING( REGEX REPLACE ".*[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" GAWK_MINOR_VERSION "${GAWK_AUTOMAKE_LINE_VERSION}")
+STRING( REGEX REPLACE ".*[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" GAWK_BUGFIX_VERSION "${GAWK_AUTOMAKE_LINE_VERSION}")
+
+# The definition of the symbol GAWK cannot be passed in config.h
+# because the extensions will fail to build.
+add_definitions(-DGAWK)
+DefineConfigHValue(_GL_ATTRIBUTE_PURE "__attribute__ ((__pure__))")
+DefineConfigHValue(GAWK_VERSION "${GAWK_MAJOR_VERSION}.${GAWK_MINOR_VERSION}.${GAWK_BUGFIX_VERSION}")
+DefineConfigHValue(VERSION \\"${GAWK_VERSION}\\")
+DefineConfigHValue(PACKAGE \\"gawk\\")
+DefineConfigHValue(PACKAGE_STRING \\"GNU Awk ${GAWK_VERSION}\\")
+DefineConfigHValue(PACKAGE_TARNAME \\"gawk\\")
+DefineConfigHValue(PACKAGE_URL \\"http://www.gnu.org/software/gawk/\\")
+DefineConfigHValue(PACKAGE_VERSION \\"${GAWK_VERSION}\\")
+DefineConfigHValue(DEFPATH \\"${CMAKE_BINARY_DIR}/awk\\")
+DefineConfigHValue(DEFLIBPATH \\"${CMAKE_BINARY_DIR}/lib\\")
+if (CMAKE_DL_LIBS)
+ message(STATUS "Found CMAKE_DL_LIBS:${CMAKE_DL_LIBS}")
+else()
+ message(STATUS "Found no CMAKE_DL_LIBS")
+endif()
+if (CMAKE_SHARED_LIBRARY_SUFFIX)
+ DefineConfigHValue(DYNAMIC 1)
+ STRING( REGEX REPLACE "^(\\.)([a-zA-Z0-9])" "\\2" SHLIBEXT "${CMAKE_SHARED_LIBRARY_SUFFIX}")
+ DefineConfigHValue(SHLIBEXT \\"${SHLIBEXT}\\")
+ message(STATUS "Found SHLIBEXT: ${SHLIBEXT}")
+else()
+ message(STATUS "Found no SHLIBEXT")
+endif()
+DefineTypeIfAvailable("unsigned int" SIZEOF_UNSIGNED_INT)
+DefineTypeIfAvailable("unsigned long" SIZEOF_UNSIGNED_LONG)
+#/* Define to 1 if *printf supports %F format */
+add_definitions(-D PRINTF_HAS_F_FORMAT)
+#/* Define as the return type of signal handlers (`int' or `void'). */
+add_definitions(-D RETSIGTYPE=void)
+#add_definitions(-D PIPES_SIMULATED)
+check_prototype_definition(getpgrp "pid_t getpgrp(void)" "NULL" "unistd.h" GETPGRP_VOID)
+DefineConfigH(GETPGRP_VOID)
+#add_definitions(-D YYPARSE_PARAM)
+
+DefineFunctionIfAvailable(snprintf HAVE_SNPRINTF)
+DefineFunctionIfAvailable(vprintf HAVE_VPRINTF)
+DefineHFileIfAvailable(sys/types.h HAVE_SYS_TYPES_H)
+DefineHFileIfAvailable(sys/stat.h HAVE_SYS_STAT_H)
+DefineHFileIfAvailable(string.h HAVE_STRING_H)
+DefineHFileIfAvailable(memory.h HAVE_MEMORY_H)
+DefineHFileIfAvailable(strings.h HAVE_STRINGS_H)
+DefineHFileIfAvailable(stdint.h HAVE_STDINT_H)
+DefineHFileIfAvailable(inttypes.h HAVE_INTTYPES_H)
+DefineHFileIfAvailable(stdlib.h HAVE_STDLIB_H)
+DefineHFileIfAvailable(unistd.h HAVE_UNISTD_H)
+FIND_PATH(INTL_INCLUDE_DIR libintl.h PATHS /usr/include /usr/local/include)
+FIND_LIBRARY(INTL_LIBRARIES intl c PATHS /usr/lib/ /usr/local/lib)
+DefineSymbolIfAvailable("CODESET" "langinfo.h" HAVE_LANGINFO_CODESET)
+DefineSymbolIfAvailable("LC_MESSAGES" "locale.h" HAVE_LC_MESSAGES)
+DefineTypeIfAvailable("_Bool" HAVE__BOOL)
+if (${HAVE_GETTEXT} AND ${HAVE_DCGETTEXT} AND ${HAVE_LANGINFO_CODESET} AND ${HAVE_LC_MESSAGES})
+ add_definitions(-D LOCALEDIR=\\"/usr/share/locale\\")
+ add_definitions(-D ENABLE_NLS)
+ ADD_SUBDIRECTORY( po )
+endif()
+DefineHFileIfAvailable(stdbool.h HAVE_STDBOOL_H)
+DefineHFileIfAvailable(sys/wait.h HAVE_SYS_WAIT_H)
+DefineHFileIfAvailable(arpa/inet.h HAVE_ARPA_INET_H)
+DefineHFileIfAvailable(fcntl.h HAVE_FCNTL_H)
+DefineHFileIfAvailable(limits.h HAVE_LIMITS_H)
+DefineHFileIfAvailable(locale.h HAVE_LOCALE_H)
+DefineHFileIfAvailable(libintl.h HAVE_LIBINTL_H)
+DefineHFileIfAvailable(mcheck.h HAVE_MCHECK_H)
+DefineHFileIfAvailable(netdb.h HAVE_NETDB_H)
+DefineHFileIfAvailable(netinet/in.h HAVE_NETINET_IN_H)
+DefineHFileIfAvailable(stdarg.h HAVE_STDARG_H)
+DefineHFileIfAvailable(stddef.h HAVE_STDDEF_H)
+DefineHFileIfAvailable(sys/ioctl.h HAVE_SYS_IOCTL_H)
+DefineHFileIfAvailable(sys/param.h HAVE_SYS_PARAM_H)
+DefineHFileIfAvailable(sys/socket.h HAVE_SYS_SOCKET_H)
+DefineHFileIfAvailable(sys/termios.h HAVE_TERMIOS_H)
+DefineHFileIfAvailable(stropts.h HAVE_STROPTS_H)
+DefineHFileIfAvailable(wchar.h HAVE_WCHAR_H)
+DefineHFileIfAvailable(wctype.h HAVE_WCTYPE_H)
+DefineTypeIfAvailable("long long int" HAVE_LONG_LONG_INT)
+DefineTypeIfAvailable("unsigned long long int" HAVE_UNSIGNED_LONG_LONG_INT)
+DefineTypeIfAvailable(intmax_t INTMAX_T)
+DefineTypeIfAvailable(uintmax_t UINTMAX_T)
+DefineTypeIfAvailable("time_t" TIME_T_IN_SYS_TYPES_H)
+SET(CMAKE_EXTRA_INCLUDE_FILES wctype.h)
+DefineTypeIfAvailable("wctype_t" HAVE_WCTYPE_T)
+DefineTypeIfAvailable("wint_t" HAVE_WINT_T)
+SET(CMAKE_EXTRA_INCLUDE_FILES)
+
+DefineStructHasMemberIfAvailable("struct sockaddr_storage" ss_family sys/socket.h HAVE_SOCKADDR_STORAGE)
+DefineStructHasMemberIfAvailable("struct stat" st_blksize sys/stat.h HAVE_STRUCT_STAT_ST_BLKSIZE)
+DefineStructHasMemberIfAvailable("struct stat" st_blksize sys/stat.h HAVE_ST_BLKSIZE)
+DefineStructHasMemberIfAvailable("struct tm" tm_zone time.h HAVE_TM_ZONE)
+DefineStructHasMemberIfAvailable("struct tm" tm_zone time.h HAVE_STRUCT_TM_TM_ZONE)
+
+DefineHFileIfAvailable(sys/time.h HAVE_SYS_TIME_H)
+DefineFunctionIfAvailable(alarm HAVE_ALARM)
+DefineFunctionIfAvailable(tzname HAVE_DECL_TZNAME)
+DefineFunctionIfAvailable(mktime HAVE_MKTIME)
+DefineFunctionIfAvailable(getaddrinfo HAVE_GETADDRINFO)
+DefineFunctionIfAvailable(atexit HAVE_ATEXIT)
+DefineFunctionIfAvailable(btowc HAVE_BTOWC)
+DefineFunctionIfAvailable(fmod HAVE_FMOD)
+DefineFunctionIfAvailable(isinf HAVE_ISINF)
+DefineFunctionIfAvailable(ismod HAVE_ISMOD)
+DefineFunctionIfAvailable(getgrent HAVE_GETGRENT)
+DefineSymbolIfAvailable("getgroups" "unistd.h" HAVE_GETGROUPS)
+if (${HAVE_GETGROUPS})
+ check_prototype_definition(getgroups "int getgroups(int size, gid_t list[])" "NULL" "unistd.h" GETGROUPS_T)
+ if (${GETGROUPS_T})
+ DefineConfigHValue(GETGROUPS_T gid_t)
+ else()
+ DefineConfigHValue(GETGROUPS_T int)
+ endif()
+endif()
+
+DefineTypeIfAvailable("pid_t" PID_T)
+DefineTypeIfAvailable("intmax_t" HAVE_INTMAX_T)
+DefineFunctionIfAvailable(grantpt HAVE_GRANTPT)
+DefineFunctionIfAvailable(isascii HAVE_ISASCII)
+DefineFunctionIfAvailable(iswctype HAVE_ISWCTYPE)
+DefineFunctionIfAvailable(iswlower HAVE_ISWLOWER)
+DefineFunctionIfAvailable(iswupper HAVE_ISWUPPER)
+DefineFunctionIfAvailable(mbrlen HAVE_MBRLEN)
+DefineFunctionIfAvailable(memcmp HAVE_MEMCMP)
+DefineFunctionIfAvailable(memcpy HAVE_MEMCPY)
+DefineFunctionIfAvailable(memmove HAVE_MEMMOVE)
+DefineFunctionIfAvailable(memset HAVE_MEMSET)
+DefineFunctionIfAvailable(mkstemp HAVE_MKSTEMP)
+DefineFunctionIfAvailable(posix_openpt HAVE_POSIX_OPENPT)
+DefineFunctionIfAvailable(setenv HAVE_SETENV)
+DefineFunctionIfAvailable(setlocale HAVE_SETLOCALE)
+DefineFunctionIfAvailable(setsid HAVE_SETSID)
+DefineFunctionIfAvailable(strchr HAVE_STRCHR)
+DefineFunctionIfAvailable(strerror HAVE_STRERROR)
+DefineFunctionIfAvailable(strftime HAVE_STRFTIME)
+DefineFunctionIfAvailable(strncasecmp HAVE_STRNCASECMP)
+DefineFunctionIfAvailable(strcoll HAVE_STRCOLL)
+DefineFunctionIfAvailable(strtod HAVE_STRTOD)
+DefineFunctionIfAvailable(strtoul HAVE_STRTOUL)
+DefineFunctionIfAvailable(system HAVE_SYSTEM)
+DefineFunctionIfAvailable(tmpfile HAVE_TMPFILE)
+DefineFunctionIfAvailable(towlower HAVE_TOWLOWER)
+DefineFunctionIfAvailable(towupper HAVE_TOWUPPER)
+DefineFunctionIfAvailable(tzset HAVE_TZSET)
+DefineFunctionIfAvailable(usleep HAVE_USLEEP)
+DefineFunctionIfAvailable(wcrtomb HAVE_WCRTOMB)
+DefineFunctionIfAvailable(wcscoll HAVE_WCSCOLL)
+DefineFunctionIfAvailable(wctype HAVE_WCTYPE)
+DefineFunctionIfAvailable(mbrtowc HAVE_MBRTOWC)
+
+add_definitions(-D HAVE_STRINGIZE)
+add_definitions(-D _Noreturn=)
+
+find_package(BISON QUIET)
+# If there is a bison installed on this platform,
+if (${BISON_FOUND} STREQUAL "TRUE")
+ # then let bison generate awkgram.c.
+ BISON_TARGET(awkgram awkgram.y ${CMAKE_SOURCE_DIR}/awkgram.c)
+else()
+ # otherwise use the existing awkgram.c.
+ set(BISON_awkgram_OUTPUTS ${CMAKE_SOURCE_DIR}/awkgram.c)
+endif()
+
+find_package(Gettext REQUIRED)
+if (GETTEXT_FOUND STREQUAL "TRUE")
+ include_directories(${GETTEXT_INCLUDE_DIR})
+ DefineFunctionIfAvailable(gettext HAVE_GETTEXT)
+ DefineFunctionIfAvailable(dcgettext HAVE_DCGETTEXT)
+else ()
+ message( FATAL_ERROR "Gettext not found" )
+endif()
+
+find_package(LATEX)
+include(GNUInstallDirs)
+include(GetPrerequisites)
+
+# For some unknown reason the defines for the extensions
+# are written into config.h only if they are implemented
+# here and not in extension/CMakeLists.txt.
+DefineLibraryIfAvailable(m sin "" HAVE_LIBM)
+DefineLibraryIfAvailable(mpfr mpfr_add_si "" HAVE_MPFR)
+DefineLibraryIfAvailable(c socket "" HAVE_SOCKETS)
+DefineLibraryIfAvailable(readline readline "" HAVE_LIBREADLINE)
+DefineFunctionIfAvailable(fnmatch HAVE_FNMATCH)
+DefineHFileIfAvailable(fnmatch.h HAVE_FNMATCH_H)
+DefineHFileIfAvailable(dirent.h HAVE_DIRENT_H)
+DefineFunctionIfAvailable(dirfd HAVE_DIRFD)
+DefineFunctionIfAvailable(getdtablesize HAVE_GETDTABLESIZE)
+DefineFunctionIfAvailable(select HAVE_SELECT)
+DefineFunctionIfAvailable(gettimeofday HAVE_GETTIMEOFDAY)
+DefineHFileIfAvailable(sys/select.h HAVE_SYS_SELECT_H)
+DefineFunctionIfAvailable(nanosleep HAVE_NANOSLEEP)
+DefineHFileIfAvailable(time.h HAVE_TIME_H)
+DefineFunctionIfAvailable(GetSystemTimeAsFileTime HAVE_GETSYSTEMTIMEASFILETIME)
+
diff --git a/cmake/docmaker b/cmake/docmaker
new file mode 100755
index 00000000..4af7cee1
--- /dev/null
+++ b/cmake/docmaker
@@ -0,0 +1,100 @@
+#!/bin/sh
+
+# The first parameter is the target, the file to be built.
+# All remaining parameters are dependencies (file names).
+if [ $# -lt 1 ] ; then
+ echo " $0: Incorrect number ($#) of parameters passed: $*"
+ exit 1
+fi
+OUTFILE=$1
+shift 1
+INFILES="$@"
+
+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/\""
+SEDME2="sed '/%%Page: 10 10/,/0 Cg EP/d'"
+
+function BuildTarget()
+{
+ local OUTFILE=$1
+ local INFILE=""
+ local COMMAND=""
+
+ FILEBASE=${OUTFILE%.*}
+ case $OUTFILE in
+ *\.in | *\.1 | macros | cardfonts | colors | ad.block | setter.outline | \
+ gawkinet.texi | rflashlight.eps | api-figure1.fig | api-figure2.fig | api-figure3.fig | \
+ general-program.fig | process-flow.fig | statist.eps)
+ INFILE=$OUTFILE
+ ;;
+ *\.texi)
+ if [ $FILEBASE = gawk ] ; then
+ INFILE=gawktexi.in
+ else
+ INFILE=$OUTFILE.in
+ fi
+ COMMAND="awk -f sidebar.awk < $INFILE > $OUTFILE"
+ ;;
+ *\.dvi)
+ INFILE=$FILEBASE.texi
+ COMMAND="texi2dvi -q --clean $INFILE"
+ ;;
+ *\.info)
+ INFILE=$FILEBASE.texi
+ COMMAND="${MAKEINFO} $INFILE"
+ ;;
+ *\.ps)
+ if [ $FILEBASE = awkcard ] ; then
+ INFILE=awkcard.in
+ COMMAND="${TROFF} $* | ${SEDME} | cat setter.outline - | ${SEDME2} > awkcard.ps"
+ elif [ $FILEBASE = gawk.1 -o $FILEBASE = igawk.1 ] ; then
+ INFILE=$FILEBASE
+ COMMAND="groff -z -man $INFILE > $OUTFILE"
+ else
+ INFILE=$FILEBASE.dvi
+ COMMAND="dvips -q -o $OUTFILE $INFILE"
+ fi
+ ;;
+ *\.pdf)
+ INFILE=$FILEBASE.ps
+ COMMAND="ps2pdf -q $INFILE $OUTFILE"
+ ;;
+ *\.tr)
+ INFILE=$FILEBASE.in
+ COMMAND="sed 's:SRCDIR:.:' < $INFILE > $OUTFILE"
+ ;;
+ *\.nc)
+ INFILE=$FILEBASE.in
+ COMMAND="sed 's:SRCDIR:.:' < $INFILE > $OUTFILE"
+ COMMAND="${TROFF} $* | ${SEDME} | cat setter.outline - | ${SEDME2} > $FILEBASE.ps && touch $OUTFILE"
+ ;;
+ *)
+ echo " unknwon target $OUTFILE"
+ exit 1
+ esac
+
+ if [ ! -r "$INFILE" ] ; then
+ echo " $0: Cannot read input file $INFILE"
+ exit 1
+ fi
+
+ if [ -f "$OUTFILE" ] ; then
+ if [ "$INFILE" -ot "$OUTFILE" ] ; then
+ #printf " Target %15s is up-to-date\n" $OUTFILE
+ COMMAND=""
+ fi
+ fi
+ #echo " Generating $OUTFILE from $INFILE"
+ echo $COMMAND | sh -x
+ #echo "COMMAND=$COMMAND"
+}
+
+# Build all dependencies first, then build the target.
+for dep in $INFILES
+do
+ #echo $OUTFILE depends on $dep
+ BuildTarget $dep
+done
+BuildTarget $OUTFILE
+
diff --git a/cmake/package.cmake b/cmake/package.cmake
new file mode 100644
index 00000000..203a8c3b
--- /dev/null
+++ b/cmake/package.cmake
@@ -0,0 +1,54 @@
+#
+# cmake/package --- CMake input file for gawk
+#
+# Copyright (C) 2013-2014
+# 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 3 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 CMake to produce Makefile
+
+SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "This is GNU Awk ${GAWK_VERSION}")
+set(CPACK_PACKAGE_VENDOR "GNU Project - Free Software Foundation (FSF)")
+SET(CPACK_PACKAGE_NAME "gawk")
+SET(CPACK_PACKAGE_VERSION "${GAWK_VERSION}")
+SET(CPACK_PACKAGE_VERSION_MAJOR "${GAWK_MAJOR_VERSION}")
+SET(CPACK_PACKAGE_VERSION_MINOR "${GAWK_MINOR_VERSION}")
+SET(CPACK_PACKAGE_VERSION_PATCH "${GAWK_BUGFIX_VERSION}")
+SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
+SET(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README")
+set(CPACK_PACKAGE_CONTACT "bug-gawk@gnu.org")
+
+IF (WIN32)
+ SET(CPACK_GENERATOR "NSIS")
+ set(CPACK_NSIS_INSTALL_ROOT "C:")
+ set(CPACK_NSIS_MENU_LINKS "http://www.gnu.org/software/gawk" "GNU Awk")
+ set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/cmake/auk.ico")
+ set(CPACK_NSIS_MUI_UNIICON "${CMAKE_SOURCE_DIR}/cmake/auk.ico")
+ set(CPACK_NSIS_CONTACT "bug-gawk@gnu.org")
+ set(CPACK_NSIS_DISPLAY_NAME "GNU Awk")
+ELSE()
+ SET(CPACK_PACKAGING_INSTALL_PREFIX /usr)
+ IF(NOT CPACK_GENERATOR)
+ SET(CPACK_GENERATOR "TGZ")
+ ENDIF()
+ message(STATUS "CPACK_GENERATOR set to ${CPACK_GENERATOR}")
+ENDIF()
+
+INCLUDE(CPack)
diff --git a/cmd.h b/cmd.h
index 8f8026ae..6fca6d0a 100644
--- a/cmd.h
+++ b/cmd.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2004, 2010, 2011 the Free Software Foundation, Inc.
+ * Copyright (C) 2004, 2010, 2011, 2013, 2014 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -36,16 +36,16 @@ extern NODE *get_function(void);
extern int gprintf(FILE *fp, const char *format, ...);
extern jmp_buf pager_quit_tag;
-extern int pager_quit_tag_valid;
+extern bool pager_quit_tag_valid;
-extern int output_is_tty;
+extern bool output_is_tty;
extern int input_fd;
-extern int input_from_tty;
+extern bool input_from_tty;
extern FILE *out_fp;
-extern char *dPrompt;
-extern char *commands_Prompt;
-extern char *eval_Prompt;
-extern char *dgawk_Prompt;
+extern char *dbg_prompt;
+extern char *commands_prompt;
+extern char *eval_prompt;
+extern char *dgawk_prompt;
enum argtype {
D_illegal,
@@ -109,7 +109,8 @@ enum argtype {
/* non-number arguments to commands */
enum nametypeval {
- A_ARGS = 1,
+ A_NONE = 0,
+ A_ARGS,
A_BREAK,
A_DEL,
A_DISPLAY,
@@ -139,7 +140,7 @@ typedef struct cmd_argument {
#define a_string value.sval /* type = D_string, D_array, D_subscript or D_variable */
#define a_node value.nodeval /* type = D_node, D_field or D_func */
- int a_count; /* subscript count for D_subscript and D_array */
+ int a_count; /* subscript count for D_subscript and D_array */
} CMDARG;
typedef int (*Func_cmd)(CMDARG *, int);
@@ -168,9 +169,10 @@ extern char *(*read_a_line)(const char *prompt);
extern char *read_commands_string(const char *prompt);
extern int in_cmd_src(const char *);
extern int get_eof_status(void);
-extern void push_cmd_src(int fd, int istty, char * (*readfunc)(const char *), int (*closefunc)(int), int cmd, int eofstatus);
+extern void push_cmd_src(int fd, bool istty, char * (*readfunc)(const char *),
+ int (*closefunc)(int), int cmd, int eofstatus);
extern int pop_cmd_src(void);
-extern int has_break_or_watch_point(int *pnum, int any);
+extern int has_break_or_watch_point(int *pnum, bool any);
extern int do_list(CMDARG *arg, int cmd);
extern int do_info(CMDARG *arg, int cmd);
extern int do_print_var(CMDARG *arg, int cmd);
diff --git a/command.c b/command.c
index c3fea2b8..389814a5 100644
--- a/command.c
+++ b/command.c
@@ -1,19 +1,19 @@
-/* A Bison parser, made by GNU Bison 2.5. */
+/* A Bison parser, made by GNU Bison 3.0.3. */
/* Bison implementation for Yacc-like parsers in C
-
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
-
+
+ Copyright (C) 1984, 1989-1990, 2000-2015 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 3 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, see <http://www.gnu.org/licenses/>. */
@@ -26,7 +26,7 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
-
+
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
@@ -44,7 +44,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.5"
+#define YYBISON_VERSION "3.0.3"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -58,23 +58,19 @@
/* Pull parsers. */
#define YYPULL 1
-/* Using locations. */
-#define YYLSP_NEEDED 0
/* Substitute the variable and function names. */
#define yyparse zzparse
#define yylex zzlex
#define yyerror zzerror
-#define yylval zzlval
-#define yychar zzchar
#define yydebug zzdebug
#define yynerrs zznerrs
+#define yylval zzlval
+#define yychar zzchar
/* Copy the first part of user declarations. */
-
-/* Line 268 of yacc.c */
-#line 26 "command.y"
+#line 26 "command.y" /* yacc.c:339 */
#include "awk.h"
#include "cmd.h"
@@ -89,24 +85,24 @@ static void yyerror(const char *mesg, ...);
static int find_command(const char *token, size_t toklen);
-static int want_nodeval = FALSE;
+static bool want_nodeval = false;
-static int cmd_idx = -1; /* index of current command in cmd table */
-static int repeat_idx = -1; /* index of last repeatable command in command table */
+static int cmd_idx = -1; /* index of current command in cmd table */
+static int repeat_idx = -1; /* index of last repeatable command in command table */
static CMDARG *arg_list = NULL; /* list of arguments */
static long errcount = 0;
static char *lexptr_begin = NULL;
-static int in_commands = FALSE;
+static bool in_commands = false;
static int num_dim;
-static int in_eval = FALSE;
+static bool in_eval = false;
static const char start_EVAL[] = "function @eval(){";
static const char end_EVAL[] = "}";
static CMDARG *append_statement(CMDARG *stmt_list, char *stmt);
-static char *next_word(char *p, int len, char **endp);
static NODE *concat_args(CMDARG *a, int count);
#ifdef HAVE_LIBREADLINE
+static char *next_word(char *p, int len, char **endp);
static void history_expand_line(char **line);
static char *command_generator(const char *text, int state);
static char *srcfile_generator(const char *text, int state);
@@ -141,14 +137,15 @@ static void append_cmdarg(CMDARG *arg);
static int find_argument(CMDARG *arg);
#define YYSTYPE CMDARG *
+#line 141 "command.c" /* yacc.c:339 */
-/* Line 268 of yacc.c */
-#line 147 "command.c"
-
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
+# ifndef YY_NULLPTR
+# if defined __cplusplus && 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# endif
/* Enabling verbose error messages. */
#ifdef YYERROR_VERBOSE
@@ -158,65 +155,67 @@ static int find_argument(CMDARG *arg);
# define YYERROR_VERBOSE 0
#endif
-/* Enabling the token table. */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int zzdebug;
+#endif
-/* Tokens. */
+/* Token type. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- D_BACKTRACE = 258,
- D_BREAK = 259,
- D_CLEAR = 260,
- D_CONTINUE = 261,
- D_DELETE = 262,
- D_DISABLE = 263,
- D_DOWN = 264,
- D_ENABLE = 265,
- D_FINISH = 266,
- D_FRAME = 267,
- D_HELP = 268,
- D_IGNORE = 269,
- D_INFO = 270,
- D_LIST = 271,
- D_NEXT = 272,
- D_NEXTI = 273,
- D_PRINT = 274,
- D_PRINTF = 275,
- D_QUIT = 276,
- D_RETURN = 277,
- D_RUN = 278,
- D_SET = 279,
- D_STEP = 280,
- D_STEPI = 281,
- D_TBREAK = 282,
- D_UP = 283,
- D_UNTIL = 284,
- D_DISPLAY = 285,
- D_UNDISPLAY = 286,
- D_WATCH = 287,
- D_UNWATCH = 288,
- D_DUMP = 289,
- D_TRACE = 290,
- D_INT = 291,
- D_STRING = 292,
- D_NODE = 293,
- D_VARIABLE = 294,
- D_OPTION = 295,
- D_COMMANDS = 296,
- D_END = 297,
- D_SILENT = 298,
- D_SOURCE = 299,
- D_SAVE = 300,
- D_EVAL = 301,
- D_CONDITION = 302,
- D_STATEMENT = 303
- };
+ enum yytokentype
+ {
+ D_BACKTRACE = 258,
+ D_BREAK = 259,
+ D_CLEAR = 260,
+ D_CONTINUE = 261,
+ D_DELETE = 262,
+ D_DISABLE = 263,
+ D_DOWN = 264,
+ D_ENABLE = 265,
+ D_FINISH = 266,
+ D_FRAME = 267,
+ D_HELP = 268,
+ D_IGNORE = 269,
+ D_INFO = 270,
+ D_LIST = 271,
+ D_NEXT = 272,
+ D_NEXTI = 273,
+ D_PRINT = 274,
+ D_PRINTF = 275,
+ D_QUIT = 276,
+ D_RETURN = 277,
+ D_RUN = 278,
+ D_SET = 279,
+ D_STEP = 280,
+ D_STEPI = 281,
+ D_TBREAK = 282,
+ D_UP = 283,
+ D_UNTIL = 284,
+ D_DISPLAY = 285,
+ D_UNDISPLAY = 286,
+ D_WATCH = 287,
+ D_UNWATCH = 288,
+ D_DUMP = 289,
+ D_TRACE = 290,
+ D_INT = 291,
+ D_STRING = 292,
+ D_NODE = 293,
+ D_VARIABLE = 294,
+ D_OPTION = 295,
+ D_COMMANDS = 296,
+ D_END = 297,
+ D_SILENT = 298,
+ D_SOURCE = 299,
+ D_SAVE = 300,
+ D_EVAL = 301,
+ D_CONDITION = 302,
+ D_STATEMENT = 303
+ };
#endif
/* Tokens. */
#define D_BACKTRACE 258
@@ -266,22 +265,23 @@ static int find_argument(CMDARG *arg);
#define D_CONDITION 302
#define D_STATEMENT 303
-
-
-
+/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
-/* Copy the second part of user declarations. */
+extern YYSTYPE zzlval;
+
+int zzparse (void);
-/* Line 343 of yacc.c */
-#line 285 "command.c"
+
+/* Copy the second part of user declarations. */
+
+#line 285 "command.c" /* yacc.c:358 */
#ifdef short
# undef short
@@ -295,11 +295,8 @@ typedef unsigned char yytype_uint8;
#ifdef YYTYPE_INT8
typedef YYTYPE_INT8 yytype_int8;
-#elif (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-typedef signed char yytype_int8;
#else
-typedef short int yytype_int8;
+typedef signed char yytype_int8;
#endif
#ifdef YYTYPE_UINT16
@@ -319,8 +316,7 @@ typedef short int yytype_int16;
# define YYSIZE_T __SIZE_TYPE__
# elif defined size_t
# define YYSIZE_T size_t
-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
+# elif ! defined YYSIZE_T
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# else
@@ -334,37 +330,67 @@ typedef short int yytype_int16;
# if defined YYENABLE_NLS && YYENABLE_NLS
# if ENABLE_NLS
# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
# endif
# endif
# ifndef YY_
-# define YY_(msgid) msgid
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__ \
+ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
+ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+# define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+# define _Noreturn __declspec (noreturn)
+# else
+# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
# endif
#endif
/* Suppress unused-variable warnings by "using" E. */
#if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
+# define YYUSE(E) ((void) (E))
#else
-# define YYUSE(e) /* empty */
+# define YYUSE(E) /* empty */
#endif
-/* Identity function, used to suppress warnings about constant conditions. */
-#ifndef lint
-# define YYID(n) (n)
-#else
-#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
-static int
-YYID (int yyi)
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+ _Pragma ("GCC diagnostic pop")
#else
-static int
-YYID (yyi)
- int yyi;
+# define YY_INITIAL_VALUE(Value) Value
#endif
-{
- return yyi;
-}
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
#if ! defined yyoverflow || YYERROR_VERBOSE
@@ -383,9 +409,9 @@ YYID (yyi)
# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
-# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# endif
@@ -395,8 +421,8 @@ YYID (yyi)
# endif
# ifdef YYSTACK_ALLOC
- /* Pacify GCC's `empty if-body' warning. */
-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+ /* Pacify GCC's 'empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
# ifndef YYSTACK_ALLOC_MAXIMUM
/* The OS might guarantee only one guard page at the bottom of the stack,
and a page size can be as small as 4096 bytes. So we cannot safely
@@ -412,7 +438,7 @@ YYID (yyi)
# endif
# if (defined __cplusplus && ! defined EXIT_SUCCESS \
&& ! ((defined YYMALLOC || defined malloc) \
- && (defined YYFREE || defined free)))
+ && (defined YYFREE || defined free)))
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
@@ -420,15 +446,13 @@ YYID (yyi)
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
-# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
+# if ! defined malloc && ! defined EXIT_SUCCESS
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# ifndef YYFREE
# define YYFREE free
-# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
+# if ! defined free && ! defined EXIT_SUCCESS
void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
@@ -436,7 +460,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-#if (! defined yyoverflow && (! defined __cplusplus || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
/* A type that is properly aligned for any stack member. */
union yyalloc
@@ -461,35 +487,35 @@ union yyalloc
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_alloc, Stack) \
- do \
- { \
- YYSIZE_T yynewbytes; \
- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
- Stack = &yyptr->Stack_alloc; \
- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
- yyptr += yynewbytes / sizeof (*yyptr); \
- } \
- while (YYID (0))
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
#endif
#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
-/* Copy COUNT objects from FROM to TO. The source and destination do
+/* Copy COUNT objects from SRC to DST. 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)))
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
# else
-# define YYCOPY(To, From, Count) \
- do \
- { \
- YYSIZE_T yyi; \
- for (yyi = 0; yyi < (Count); yyi++) \
- (To)[yyi] = (From)[yyi]; \
- } \
- while (YYID (0))
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } \
+ while (0)
# endif
# endif
#endif /* !YYCOPY_NEEDED */
@@ -505,17 +531,19 @@ union yyalloc
#define YYNNTS 55
/* YYNRULES -- Number of rules. */
#define YYNRULES 156
-/* YYNRULES -- Number of states. */
+/* YYNSTATES -- Number of states. */
#define YYNSTATES 203
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
+ by yylex, with out-of-bounds checking. */
#define YYUNDEFTOK 2
#define YYMAXUTOK 303
-#define YYTRANSLATE(YYX) \
+#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, without out-of-bounds checking. */
static const yytype_uint8 yytranslate[] =
{
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -552,95 +580,29 @@ static const yytype_uint8 yytranslate[] =
};
#if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
- YYRHS. */
-static const yytype_uint16 yyprhs[] =
-{
- 0, 0, 3, 4, 7, 9, 12, 15, 17, 19,
- 21, 23, 25, 27, 29, 31, 33, 35, 37, 39,
- 41, 43, 45, 46, 51, 52, 53, 58, 62, 66,
- 69, 71, 73, 75, 78, 81, 84, 88, 91, 92,
- 96, 97, 101, 104, 107, 110, 113, 114, 120, 123,
- 124, 128, 129, 133, 134, 139, 142, 145, 148, 151,
- 154, 156, 158, 161, 162, 167, 169, 171, 173, 175,
- 176, 178, 180, 183, 187, 189, 190, 192, 194, 196,
- 197, 199, 203, 205, 206, 208, 210, 214, 218, 219,
- 220, 224, 226, 227, 233, 237, 238, 240, 241, 243,
- 244, 246, 247, 249, 251, 254, 256, 259, 263, 265,
- 268, 272, 274, 276, 278, 280, 284, 286, 287, 289,
- 291, 293, 295, 297, 301, 305, 309, 313, 314, 316,
- 318, 320, 322, 325, 328, 330, 334, 336, 340, 344,
- 346, 349, 351, 354, 357, 359, 362, 365, 366, 368,
- 369, 371, 373, 376, 378, 381, 384
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const yytype_int8 yyrhs[] =
-{
- 60, 0, -1, -1, 60, 61, -1, 113, -1, 71,
- 113, -1, 1, 113, -1, 6, -1, 17, -1, 18,
- -1, 25, -1, 26, -1, 31, -1, 33, -1, 8,
- -1, 7, -1, 28, -1, 9, -1, 3, -1, 12,
- -1, 4, -1, 27, -1, -1, 46, 66, 81, 113,
- -1, -1, -1, 68, 48, 69, 113, -1, 67, 68,
- 42, -1, 46, 66, 84, -1, 13, 94, -1, 21,
- -1, 23, -1, 11, -1, 62, 109, -1, 64, 110,
- -1, 15, 37, -1, 14, 111, 36, -1, 10, 95,
- -1, -1, 19, 72, 97, -1, -1, 20, 73, 99,
- -1, 16, 100, -1, 29, 87, -1, 5, 87, -1,
- 65, 88, -1, -1, 24, 74, 107, 49, 108, -1,
- 40, 85, -1, -1, 22, 75, 93, -1, -1, 30,
- 76, 91, -1, -1, 32, 77, 107, 79, -1, 63,
- 102, -1, 34, 92, -1, 44, 37, -1, 45, 37,
- -1, 41, 80, -1, 42, -1, 43, -1, 35, 37,
- -1, -1, 47, 111, 78, 79, -1, 70, -1, 83,
- -1, 109, -1, 1, -1, -1, 82, -1, 39, -1,
- 82, 39, -1, 82, 50, 39, -1, 1, -1, -1,
- 84, -1, 1, -1, 38, -1, -1, 37, -1, 37,
- 49, 37, -1, 37, -1, -1, 111, -1, 86, -1,
- 37, 51, 111, -1, 37, 51, 86, -1, -1, -1,
- 111, 89, 79, -1, 86, -1, -1, 37, 51, 111,
- 90, 79, -1, 37, 51, 86, -1, -1, 107, -1,
- -1, 37, -1, -1, 108, -1, -1, 37, -1, 102,
- -1, 37, 102, -1, 107, -1, 52, 39, -1, 52,
- 39, 106, -1, 96, -1, 97, 96, -1, 97, 50,
- 96, -1, 1, -1, 38, -1, 107, -1, 98, -1,
- 99, 50, 98, -1, 1, -1, -1, 53, -1, 54,
- -1, 111, -1, 86, -1, 101, -1, 37, 51, 111,
- -1, 37, 51, 86, -1, 37, 51, 101, -1, 111,
- 54, 111, -1, -1, 103, -1, 1, -1, 111, -1,
- 101, -1, 103, 111, -1, 103, 101, -1, 108, -1,
- 104, 50, 108, -1, 1, -1, 55, 104, 56, -1,
- 55, 104, 1, -1, 105, -1, 106, 105, -1, 39,
- -1, 57, 38, -1, 39, 106, -1, 38, -1, 53,
- 38, -1, 54, 38, -1, -1, 111, -1, -1, 112,
- -1, 36, -1, 53, 36, -1, 36, -1, 53, 36,
- -1, 54, 36, -1, 58, -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
0, 106, 106, 108, 126, 127, 177, 184, 185, 186,
187, 188, 192, 193, 194, 195, 199, 200, 201, 202,
- 206, 207, 212, 216, 235, 242, 242, 249, 265, 279,
- 280, 281, 282, 283, 284, 290, 302, 303, 304, 304,
- 305, 305, 306, 307, 308, 309, 310, 310, 311, 312,
- 312, 313, 313, 314, 314, 315, 316, 317, 322, 327,
- 353, 363, 368, 380, 380, 388, 402, 415, 416, 422,
- 423, 427, 428, 429, 430, 436, 437, 438, 443, 454,
- 455, 460, 468, 485, 486, 487, 488, 489, 494, 495,
- 495, 496, 497, 497, 498, 503, 504, 509, 510, 515,
- 516, 519, 521, 525, 526, 541, 542, 547, 555, 556,
- 557, 558, 562, 563, 567, 568, 569, 574, 575, 577,
- 584, 585, 586, 587, 588, 589, 593, 606, 607, 608,
- 612, 613, 614, 615, 619, 621, 623, 627, 642, 646,
- 648, 653, 654, 663, 673, 675, 682, 695, 696, 702,
- 703, 708, 714, 723, 725, 727, 735
+ 206, 207, 212, 216, 236, 243, 243, 250, 266, 280,
+ 281, 282, 283, 284, 285, 291, 303, 304, 305, 305,
+ 306, 306, 307, 308, 309, 310, 311, 311, 312, 313,
+ 313, 314, 314, 315, 315, 316, 317, 318, 323, 328,
+ 354, 364, 369, 381, 381, 389, 403, 416, 417, 423,
+ 424, 428, 429, 430, 431, 437, 438, 439, 444, 455,
+ 456, 461, 469, 486, 487, 488, 489, 490, 495, 496,
+ 496, 497, 498, 498, 499, 504, 505, 510, 511, 516,
+ 517, 520, 522, 526, 527, 542, 543, 548, 556, 557,
+ 558, 559, 563, 564, 568, 569, 570, 575, 576, 578,
+ 585, 586, 587, 588, 589, 590, 594, 607, 608, 609,
+ 613, 614, 615, 616, 620, 622, 624, 628, 643, 647,
+ 649, 654, 655, 664, 674, 676, 683, 696, 697, 703,
+ 704, 709, 715, 724, 726, 728, 736
};
#endif
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+#if YYDEBUG || YYERROR_VERBOSE || 0
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
@@ -664,13 +626,13 @@ static const char *const yytname[] =
"printf_args", "list_args", "integer_range", "opt_integer_list",
"integer_list", "exp_list", "subscript", "subscript_list", "variable",
"node", "opt_plus_integer", "opt_integer", "plus_integer", "integer",
- "nls", 0
+ "nls", YY_NULLPTR
};
#endif
# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
- token YYLEX-NUM. */
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+ (internal) symbol number NUM (which must be that of a token). */
static const yytype_uint16 yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
@@ -682,90 +644,18 @@ static const yytype_uint16 yytoknum[] =
};
# endif
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const yytype_uint8 yyr1[] =
-{
- 0, 59, 60, 60, 61, 61, 61, 62, 62, 62,
- 62, 62, 63, 63, 63, 63, 64, 64, 64, 64,
- 65, 65, 66, 67, 68, 69, 68, 70, 70, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 72, 71,
- 73, 71, 71, 71, 71, 71, 74, 71, 71, 75,
- 71, 76, 71, 77, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 78, 71, 71, 79, 80, 80, 81,
- 81, 82, 82, 82, 82, 83, 83, 83, 84, 85,
- 85, 85, 86, 87, 87, 87, 87, 87, 88, 89,
- 88, 88, 90, 88, 88, 91, 91, 92, 92, 93,
- 93, 94, 94, 95, 95, 96, 96, 96, 97, 97,
- 97, 97, 98, 98, 99, 99, 99, 100, 100, 100,
- 100, 100, 100, 100, 100, 100, 101, 102, 102, 102,
- 103, 103, 103, 103, 104, 104, 104, 105, 105, 106,
- 106, 107, 107, 107, 108, 108, 108, 109, 109, 110,
- 110, 111, 111, 112, 112, 112, 113
-};
+#define YYPACT_NINF -151
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-static const yytype_uint8 yyr2[] =
-{
- 0, 2, 0, 2, 1, 2, 2, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 0, 4, 0, 0, 4, 3, 3, 2,
- 1, 1, 1, 2, 2, 2, 3, 2, 0, 3,
- 0, 3, 2, 2, 2, 2, 0, 5, 2, 0,
- 3, 0, 3, 0, 4, 2, 2, 2, 2, 2,
- 1, 1, 2, 0, 4, 1, 1, 1, 1, 0,
- 1, 1, 2, 3, 1, 0, 1, 1, 1, 0,
- 1, 3, 1, 0, 1, 1, 3, 3, 0, 0,
- 3, 1, 0, 5, 3, 0, 1, 0, 1, 0,
- 1, 0, 1, 1, 2, 1, 2, 3, 1, 2,
- 3, 1, 1, 1, 1, 3, 1, 0, 1, 1,
- 1, 1, 1, 3, 3, 3, 3, 0, 1, 1,
- 1, 1, 2, 2, 1, 3, 1, 3, 3, 1,
- 2, 1, 2, 2, 1, 2, 2, 0, 1, 0,
- 1, 1, 2, 1, 2, 2, 1
-};
+#define yypact_value_is_default(Yystate) \
+ (!!((Yystate) == (-151)))
-/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
- Performed when YYTABLE doesn't specify something else to do. Zero
- means the default is an error. */
-static const yytype_uint8 yydefact[] =
-{
- 2, 0, 1, 0, 18, 20, 83, 7, 15, 14,
- 17, 0, 32, 19, 101, 0, 0, 117, 8, 9,
- 38, 40, 30, 49, 31, 46, 10, 11, 21, 16,
- 83, 51, 12, 53, 13, 97, 0, 79, 0, 60,
- 61, 0, 0, 22, 0, 156, 3, 147, 0, 149,
- 88, 24, 65, 0, 4, 6, 151, 82, 0, 85,
- 44, 84, 129, 0, 37, 131, 103, 128, 130, 102,
- 29, 0, 35, 82, 118, 119, 121, 42, 122, 120,
- 0, 0, 99, 0, 43, 95, 0, 98, 56, 62,
- 80, 48, 68, 59, 67, 148, 57, 58, 0, 63,
- 33, 55, 153, 0, 0, 34, 150, 82, 91, 45,
- 89, 0, 5, 0, 152, 104, 133, 132, 0, 36,
- 0, 111, 141, 0, 0, 108, 39, 105, 116, 112,
- 114, 41, 113, 144, 0, 0, 50, 100, 0, 52,
- 96, 0, 0, 74, 78, 71, 0, 70, 28, 0,
- 154, 155, 0, 0, 27, 25, 82, 87, 86, 126,
- 124, 125, 123, 0, 139, 143, 106, 142, 0, 109,
- 0, 145, 146, 0, 77, 54, 66, 76, 81, 23,
- 72, 0, 64, 94, 92, 90, 0, 136, 0, 134,
- 140, 107, 110, 115, 47, 73, 0, 26, 138, 0,
- 137, 93, 135
-};
+#define YYTABLE_NINF -148
-/* YYDEFGOTO[NTERM-NUM]. */
-static const yytype_int16 yydefgoto[] =
-{
- -1, 1, 46, 47, 48, 49, 50, 98, 51, 111,
- 186, 52, 53, 80, 81, 83, 82, 85, 86, 149,
- 175, 93, 146, 147, 176, 177, 91, 59, 60, 109,
- 153, 196, 139, 88, 136, 70, 64, 125, 126, 130,
- 131, 77, 65, 66, 67, 188, 164, 165, 127, 137,
- 94, 105, 68, 106, 54
-};
+#define yytable_value_is_error(Yytable_value) \
+ 0
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
- STATE-NUM. */
-#define YYPACT_NINF -151
+ /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
static const yytype_int16 yypact[] =
{
-151, 145, -151, -34, -151, -151, 50, -151, -151, -151,
@@ -791,7 +681,35 @@ static const yytype_int16 yypact[] =
-151, -151, -151
};
-/* YYPGOTO[NTERM-NUM]. */
+ /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint8 yydefact[] =
+{
+ 2, 0, 1, 0, 18, 20, 83, 7, 15, 14,
+ 17, 0, 32, 19, 101, 0, 0, 117, 8, 9,
+ 38, 40, 30, 49, 31, 46, 10, 11, 21, 16,
+ 83, 51, 12, 53, 13, 97, 0, 79, 0, 60,
+ 61, 0, 0, 22, 0, 156, 3, 147, 0, 149,
+ 88, 24, 65, 0, 4, 6, 151, 82, 0, 85,
+ 44, 84, 129, 0, 37, 131, 103, 128, 130, 102,
+ 29, 0, 35, 82, 118, 119, 121, 42, 122, 120,
+ 0, 0, 99, 0, 43, 95, 0, 98, 56, 62,
+ 80, 48, 68, 59, 67, 148, 57, 58, 0, 63,
+ 33, 55, 153, 0, 0, 34, 150, 82, 91, 45,
+ 89, 0, 5, 0, 152, 104, 133, 132, 0, 36,
+ 0, 111, 141, 0, 0, 108, 39, 105, 116, 112,
+ 114, 41, 113, 144, 0, 0, 50, 100, 0, 52,
+ 96, 0, 0, 74, 78, 71, 0, 70, 28, 0,
+ 154, 155, 0, 0, 27, 25, 82, 87, 86, 126,
+ 124, 125, 123, 0, 139, 143, 106, 142, 0, 109,
+ 0, 145, 146, 0, 77, 54, 66, 76, 81, 23,
+ 72, 0, 64, 94, 92, 90, 0, 136, 0, 134,
+ 140, 107, 110, 115, 47, 73, 0, 26, 138, 0,
+ 137, 93, 135
+};
+
+ /* YYPGOTO[NTERM-NUM]. */
static const yytype_int16 yypgoto[] =
{
-151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
@@ -802,10 +720,20 @@ static const yytype_int16 yypgoto[] =
97, -151, -5, -151, -3
};
-/* 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 YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -148
+ /* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
+{
+ -1, 1, 46, 47, 48, 49, 50, 98, 51, 111,
+ 186, 52, 53, 80, 81, 83, 82, 85, 86, 149,
+ 175, 93, 146, 147, 176, 177, 91, 59, 60, 109,
+ 153, 196, 139, 88, 136, 70, 64, 125, 126, 130,
+ 131, 77, 65, 66, 67, 188, 164, 165, 127, 137,
+ 94, 105, 68, 106, 54
+};
+
+ /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_int16 yytable[] =
{
55, 61, 76, 78, 132, 121, 138, 174, 140, 141,
@@ -831,12 +759,6 @@ static const yytype_int16 yytable[] =
0, 0, 0, 45
};
-#define yypact_value_is_default(yystate) \
- ((yystate) == (-151))
-
-#define yytable_value_is_error(yytable_value) \
- YYID (0)
-
static const yytype_int16 yycheck[] =
{
3, 6, 17, 17, 81, 1, 83, 1, 85, 86,
@@ -862,8 +784,8 @@ static const yytype_int16 yycheck[] =
-1, -1, -1, 58
};
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
- symbol of state STATE-NUM. */
+ /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
0, 60, 0, 1, 3, 4, 5, 6, 7, 8,
@@ -889,94 +811,83 @@ static const yytype_uint8 yystos[] =
56, 79, 108
};
-#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. However,
- YYFAIL appears to be in use. Nevertheless, it is formally deprecated
- in Bison 2.4.2's NEWS entry, where a plan to phase it out is
- discussed. */
-
-#define YYFAIL goto yyerrlab
-#if defined YYFAIL
- /* This is here to suppress warnings from the GCC cpp's
- -Wunused-macros. Normally we don't worry about that warning, but
- some users do, and we want to make it easy for users to remove
- YYFAIL uses, which will produce warnings from Bison 2.5. */
-#endif
+ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 59, 60, 60, 61, 61, 61, 62, 62, 62,
+ 62, 62, 63, 63, 63, 63, 64, 64, 64, 64,
+ 65, 65, 66, 67, 68, 69, 68, 70, 70, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71, 72, 71,
+ 73, 71, 71, 71, 71, 71, 74, 71, 71, 75,
+ 71, 76, 71, 77, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 78, 71, 71, 79, 80, 80, 81,
+ 81, 82, 82, 82, 82, 83, 83, 83, 84, 85,
+ 85, 85, 86, 87, 87, 87, 87, 87, 88, 89,
+ 88, 88, 90, 88, 88, 91, 91, 92, 92, 93,
+ 93, 94, 94, 95, 95, 96, 96, 96, 97, 97,
+ 97, 97, 98, 98, 99, 99, 99, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 101, 102, 102, 102,
+ 103, 103, 103, 103, 104, 104, 104, 105, 105, 106,
+ 106, 107, 107, 107, 108, 108, 108, 109, 109, 110,
+ 110, 111, 111, 112, 112, 112, 113
+};
-#define YYRECOVERING() (!!yyerrstatus)
+ /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 0, 2, 1, 2, 2, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 0, 4, 0, 0, 4, 3, 3, 2,
+ 1, 1, 1, 2, 2, 2, 3, 2, 0, 3,
+ 0, 3, 2, 2, 2, 2, 0, 5, 2, 0,
+ 3, 0, 3, 0, 4, 2, 2, 2, 2, 2,
+ 1, 1, 2, 0, 4, 1, 1, 1, 1, 0,
+ 1, 1, 2, 3, 1, 0, 1, 1, 1, 0,
+ 1, 3, 1, 0, 1, 1, 3, 3, 0, 0,
+ 3, 1, 0, 5, 3, 0, 1, 0, 1, 0,
+ 1, 0, 1, 1, 2, 1, 2, 3, 1, 2,
+ 3, 1, 1, 1, 1, 3, 1, 0, 1, 1,
+ 1, 1, 1, 3, 3, 3, 3, 0, 1, 1,
+ 1, 1, 2, 2, 1, 3, 1, 3, 3, 1,
+ 2, 1, 2, 2, 1, 2, 2, 0, 1, 0,
+ 1, 1, 2, 1, 2, 2, 1
+};
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY && yylen == 1) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- YYPOPSTACK (1); \
- goto yybackup; \
- } \
- else \
- { \
- yyerror (YY_("syntax error: cannot back up")); \
- YYERROR; \
- } \
-while (YYID (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 (YYID (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 (YYID (0))
-#endif
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
-/* This macro is provided for backward compatibility. */
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
-#ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-#endif
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (0)
+
+/* Error token number */
+#define YYTERROR 1
+#define YYERRCODE 256
-/* 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
@@ -986,53 +897,46 @@ while (YYID (0))
# define YYFPRINTF fprintf
# endif
-# define YYDPRINTF(Args) \
-do { \
- if (yydebug) \
- YYFPRINTF Args; \
-} while (YYID (0))
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+/* This macro is provided for backward compatibility. */
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
-do { \
- if (yydebug) \
- { \
- YYFPRINTF (stderr, "%s ", Title); \
- yy_symbol_print (stderr, \
- Type, Value); \
- YYFPRINTF (stderr, "\n"); \
- } \
-} while (YYID (0))
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
+/*----------------------------------------.
+| Print this symbol's value on YYOUTPUT. |
+`----------------------------------------*/
+
static void
yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
-#else
-static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep)
- FILE *yyoutput;
- int yytype;
- YYSTYPE const * const yyvaluep;
-#endif
{
+ FILE *yyo = yyoutput;
+ YYUSE (yyo);
if (!yyvaluep)
return;
# ifdef YYPRINT
if (yytype < YYNTOKENS)
YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# else
- YYUSE (yyoutput);
# endif
- switch (yytype)
- {
- default:
- break;
- }
+ YYUSE (yytype);
}
@@ -1040,21 +944,11 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep)
| Print this symbol on YYOUTPUT. |
`--------------------------------*/
-#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
static void
yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
-#else
-static void
-yy_symbol_print (yyoutput, yytype, yyvaluep)
- FILE *yyoutput;
- int yytype;
- YYSTYPE const * const yyvaluep;
-#endif
{
- if (yytype < YYNTOKENS)
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
- else
- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+ YYFPRINTF (yyoutput, "%s %s (",
+ yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
yy_symbol_value_print (yyoutput, yytype, yyvaluep);
YYFPRINTF (yyoutput, ")");
@@ -1065,15 +959,8 @@ yy_symbol_print (yyoutput, yytype, yyvaluep)
| TOP (included). |
`------------------------------------------------------------------*/
-#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
static void
yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
-#else
-static void
-yy_stack_print (yybottom, yytop)
- yytype_int16 *yybottom;
- yytype_int16 *yytop;
-#endif
{
YYFPRINTF (stderr, "Stack now");
for (; yybottom <= yytop; yybottom++)
@@ -1084,48 +971,42 @@ yy_stack_print (yybottom, yytop)
YYFPRINTF (stderr, "\n");
}
-# define YY_STACK_PRINT(Bottom, Top) \
-do { \
- if (yydebug) \
- yy_stack_print ((Bottom), (Top)); \
-} while (YYID (0))
+# 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 __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
-static void
-yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
-#else
static void
-yy_reduce_print (yyvsp, yyrule)
- YYSTYPE *yyvsp;
- int yyrule;
-#endif
+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
{
+ unsigned long int yylno = yyrline[yyrule];
int yynrhs = yyr2[yyrule];
int yyi;
- unsigned long int yylno = yyrline[yyrule];
YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
- yyrule - 1, yylno);
+ yyrule - 1, yylno);
/* The symbols being reduced. */
for (yyi = 0; yyi < yynrhs; yyi++)
{
YYFPRINTF (stderr, " $%d = ", yyi + 1);
- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
- &(yyvsp[(yyi + 1) - (yynrhs)])
- );
+ yy_symbol_print (stderr,
+ yystos[yyssp[yyi + 1 - yynrhs]],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ );
YYFPRINTF (stderr, "\n");
}
}
-# define YY_REDUCE_PRINT(Rule) \
-do { \
- if (yydebug) \
- yy_reduce_print (yyvsp, Rule); \
-} while (YYID (0))
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyssp, yyvsp, Rule); \
+} while (0)
/* Nonzero means print parse trace. It is left uninitialized so that
multiple parsers can coexist. */
@@ -1139,7 +1020,7 @@ int yydebug;
/* YYINITDEPTH -- initial size of the parser's stacks. */
-#ifndef YYINITDEPTH
+#ifndef YYINITDEPTH
# define YYINITDEPTH 200
#endif
@@ -1162,14 +1043,8 @@ int yydebug;
# define yystrlen strlen
# else
/* Return the length of YYSTR. */
-#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
static YYSIZE_T
yystrlen (const char *yystr)
-#else
-static YYSIZE_T
-yystrlen (yystr)
- const char *yystr;
-#endif
{
YYSIZE_T yylen;
for (yylen = 0; yystr[yylen]; yylen++)
@@ -1185,15 +1060,8 @@ yystrlen (yystr)
# else
/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
YYDEST. */
-#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
static char *
yystpcpy (char *yydest, const char *yysrc)
-#else
-static char *
-yystpcpy (yydest, yysrc)
- char *yydest;
- const char *yysrc;
-#endif
{
char *yyd = yydest;
const char *yys = yysrc;
@@ -1223,27 +1091,27 @@ yytnamerr (char *yyres, const char *yystr)
char const *yyp = yystr;
for (;;)
- switch (*++yyp)
- {
- case '\'':
- case ',':
- goto do_not_strip_quotes;
-
- case '\\':
- if (*++yyp != '\\')
- goto do_not_strip_quotes;
- /* Fall through. */
- default:
- if (yyres)
- yyres[yyn] = *yyp;
- yyn++;
- break;
-
- case '"':
- if (yyres)
- yyres[yyn] = '\0';
- return yyn;
- }
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
do_not_strip_quotes: ;
}
@@ -1266,12 +1134,11 @@ static int
yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
yytype_int16 *yyssp, int yytoken)
{
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
+ YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */
- const char *yyformat = 0;
+ const char *yyformat = YY_NULLPTR;
/* Arguments of yyformat. */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
/* Number of reported tokens (one for the "unexpected", one per
@@ -1279,10 +1146,6 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
int yycount = 0;
/* There are many possibilities here to consider:
- - Assume YYFAIL is not used. It's too flawed to consider. See
- <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
- for details. YYERROR is fine as it does not invoke this
- function.
- If this state is a consistent state with a default action, then
the only way this function was invoked is if the default action
is an error action. In that case, don't check for expected
@@ -1331,11 +1194,13 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
break;
}
yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- if (! (yysize <= yysize1
- && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
+ {
+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+ if (! (yysize <= yysize1
+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
}
}
}
@@ -1355,10 +1220,12 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
# undef YYCASE_
}
- yysize1 = yysize + yystrlen (yyformat);
- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
+ {
+ YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
if (*yymsg_alloc < yysize)
{
@@ -1395,47 +1262,20 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
| Release the memory associated to this symbol. |
`-----------------------------------------------*/
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
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
{
YYUSE (yyvaluep);
-
if (!yymsg)
yymsg = "Deleting";
YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
- switch (yytype)
- {
-
- default:
- break;
- }
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
}
-/* 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 lookahead symbol. */
@@ -1443,7 +1283,6 @@ int yychar;
/* The semantic value of the lookahead symbol. */
YYSTYPE yylval;
-
/* Number of syntax errors so far. */
int yynerrs;
@@ -1452,35 +1291,18 @@ int yynerrs;
| yyparse. |
`----------*/
-#ifdef YYPARSE_PARAM
-#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void *YYPARSE_PARAM)
-#else
-int
-yyparse (YYPARSE_PARAM)
- void *YYPARSE_PARAM;
-#endif
-#else /* ! YYPARSE_PARAM */
-#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
int
yyparse (void)
-#else
-int
-yyparse ()
-
-#endif
-#endif
{
int yystate;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
/* The stacks and their tools:
- `yyss': related to states.
- `yyvs': related to semantic values.
+ 'yyss': related to states.
+ 'yyvs': related to semantic values.
- Refer to the stacks thru separate pointers, to allow yyoverflow
+ Refer to the stacks through separate pointers, to allow yyoverflow
to reallocate them elsewhere. */
/* The state stack. */
@@ -1498,7 +1320,7 @@ yyparse ()
int yyn;
int yyresult;
/* Lookahead token as an internal (translated) token number. */
- int yytoken;
+ int yytoken = 0;
/* The variables used to return semantic value and location from the
action routines. */
YYSTYPE yyval;
@@ -1516,9 +1338,8 @@ yyparse ()
Keep to zero when no symbol should be popped. */
int yylen = 0;
- yytoken = 0;
- yyss = yyssa;
- yyvs = yyvsa;
+ yyssp = yyss = yyssa;
+ yyvsp = yyvs = yyvsa;
yystacksize = YYINITDEPTH;
YYDPRINTF ((stderr, "Starting parse\n"));
@@ -1527,14 +1348,6 @@ yyparse ()
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;
-
goto yysetstate;
/*------------------------------------------------------------.
@@ -1555,23 +1368,23 @@ yyparse ()
#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;
- yytype_int16 *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 (YY_("memory exhausted"),
- &yyss1, yysize * sizeof (*yyssp),
- &yyvs1, yysize * sizeof (*yyvsp),
- &yystacksize);
-
- yyss = yyss1;
- yyvs = yyvs1;
+ /* 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;
+ yytype_int16 *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 (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
}
#else /* no yyoverflow */
# ifndef YYSTACK_RELOCATE
@@ -1579,22 +1392,22 @@ yyparse ()
# else
/* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize)
- goto yyexhaustedlab;
+ goto yyexhaustedlab;
yystacksize *= 2;
if (YYMAXDEPTH < yystacksize)
- yystacksize = YYMAXDEPTH;
+ yystacksize = YYMAXDEPTH;
{
- yytype_int16 *yyss1 = yyss;
- union yyalloc *yyptr =
- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
- if (! yyptr)
- goto yyexhaustedlab;
- YYSTACK_RELOCATE (yyss_alloc, yyss);
- YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
# undef YYSTACK_RELOCATE
- if (yyss1 != yyssa)
- YYSTACK_FREE (yyss1);
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
}
# endif
#endif /* no yyoverflow */
@@ -1603,10 +1416,10 @@ yyparse ()
yyvsp = yyvs + yysize - 1;
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
- (unsigned long int) yystacksize));
+ (unsigned long int) yystacksize));
if (yyss + yystacksize - 1 <= yyssp)
- YYABORT;
+ YYABORT;
}
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
@@ -1635,7 +1448,7 @@ yybackup:
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
- yychar = YYLEX;
+ yychar = yylex ();
}
if (yychar <= YYEOF)
@@ -1675,7 +1488,9 @@ yybackup:
yychar = YYEMPTY;
yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
goto yynewstate;
@@ -1698,7 +1513,7 @@ yyreduce:
yylen = yyr2[yyn];
/* If YYLEN is nonzero, implement the default value of the action:
- `$$ = $1'.
+ '$$ = $1'.
Otherwise, the following line sets YYVAL to garbage.
This behavior is undocumented and Bison
@@ -1712,12 +1527,10 @@ yyreduce:
switch (yyn)
{
case 3:
-
-/* Line 1821 of yacc.c */
-#line 109 "command.y"
+#line 109 "command.y" /* yacc.c:1646 */
{
cmd_idx = -1;
- want_nodeval = FALSE;
+ want_nodeval = false;
if (lexptr_begin != NULL) {
if (input_from_tty && lexptr_begin[0] != '\0')
add_history(lexptr_begin);
@@ -1729,16 +1542,15 @@ yyreduce:
arg_list = NULL;
}
}
+#line 1546 "command.c" /* yacc.c:1646 */
break;
case 5:
-
-/* Line 1821 of yacc.c */
-#line 128 "command.y"
+#line 128 "command.y" /* yacc.c:1646 */
{
if (errcount == 0 && cmd_idx >= 0) {
Func_cmd cmdfunc;
- int terminate = FALSE;
+ bool terminate = false;
CMDARG *args;
int ctype = 0;
@@ -1772,7 +1584,7 @@ yyreduce:
if (in_commands)
cmdfunc = do_commands;
cmd_idx = -1;
- want_nodeval = FALSE;
+ want_nodeval = false;
args = arg_list;
arg_list = NULL;
@@ -1784,48 +1596,45 @@ yyreduce:
YYACCEPT;
}
}
+#line 1600 "command.c" /* yacc.c:1646 */
break;
case 6:
-
-/* Line 1821 of yacc.c */
-#line 178 "command.y"
+#line 178 "command.y" /* yacc.c:1646 */
{
yyerrok;
}
+#line 1608 "command.c" /* yacc.c:1646 */
break;
case 22:
-
-/* Line 1821 of yacc.c */
-#line 212 "command.y"
- { want_nodeval = TRUE; }
+#line 212 "command.y" /* yacc.c:1646 */
+ { want_nodeval = true; }
+#line 1614 "command.c" /* yacc.c:1646 */
break;
case 23:
-
-/* Line 1821 of yacc.c */
-#line 217 "command.y"
+#line 217 "command.y" /* yacc.c:1646 */
{
if (errcount == 0) {
/* don't free arg_list; passed on to statement_list
* non-terminal (empty rule action). See below.
*/
if (input_from_tty) {
- dPrompt = eval_Prompt;
- fprintf(out_fp, _("Type (g)awk statement(s). End with the command \"end\"\n"));
+ dbg_prompt = eval_prompt;
+ fprintf(out_fp,
+ _("Type (g)awk statement(s). End with the command \"end\"\n"));
rl_inhibit_completion = 1;
}
cmd_idx = -1;
- in_eval = TRUE;
+ in_eval = true;
}
}
+#line 1634 "command.c" /* yacc.c:1646 */
break;
case 24:
-
-/* Line 1821 of yacc.c */
-#line 235 "command.y"
+#line 236 "command.y" /* yacc.c:1646 */
{
(yyval) = append_statement(arg_list, (char *) start_EVAL);
if (read_a_line == read_commands_string) /* unserializing 'eval' in 'commands' */
@@ -1833,30 +1642,27 @@ yyreduce:
free_cmdarg(arg_list);
arg_list = NULL;
}
+#line 1646 "command.c" /* yacc.c:1646 */
break;
case 25:
-
-/* Line 1821 of yacc.c */
-#line 242 "command.y"
- { (yyval) = append_statement((yyvsp[(1) - (2)]), lexptr_begin); }
+#line 243 "command.y" /* yacc.c:1646 */
+ { (yyval) = append_statement((yyvsp[-1]), lexptr_begin); }
+#line 1652 "command.c" /* yacc.c:1646 */
break;
case 26:
-
-/* Line 1821 of yacc.c */
-#line 243 "command.y"
+#line 244 "command.y" /* yacc.c:1646 */
{
- (yyval) = (yyvsp[(3) - (4)]);
+ (yyval) = (yyvsp[-1]);
}
+#line 1660 "command.c" /* yacc.c:1646 */
break;
case 27:
-
-/* Line 1821 of yacc.c */
-#line 250 "command.y"
+#line 251 "command.y" /* yacc.c:1646 */
{
- arg_list = append_statement((yyvsp[(2) - (3)]), (char *) end_EVAL);
+ arg_list = append_statement((yyvsp[-1]), (char *) end_EVAL);
if (read_a_line == read_commands_string) { /* unserializing 'eval' in 'commands' */
char *str = arg_list->a_string;
size_t len = strlen(str);
@@ -1864,217 +1670,199 @@ yyreduce:
str[len - 2] = '\0';
}
if (input_from_tty) {
- dPrompt = in_commands ? commands_Prompt : dgawk_Prompt;
+ dbg_prompt = in_commands ? commands_prompt : dgawk_prompt;
rl_inhibit_completion = 0;
}
cmd_idx = find_command("eval", 4);
- in_eval = FALSE;
+ in_eval = false;
}
+#line 1680 "command.c" /* yacc.c:1646 */
break;
case 28:
-
-/* Line 1821 of yacc.c */
-#line 266 "command.y"
+#line 267 "command.y" /* yacc.c:1646 */
{
NODE *n;
CMDARG *arg;
- n = (yyvsp[(3) - (3)])->a_node;
+ n = (yyvsp[0])->a_node;
arg = append_statement(NULL, (char *) start_EVAL);
(void) append_statement(arg, n->stptr);
(void) append_statement(arg, (char *) end_EVAL);
free_cmdarg(arg_list);
arg_list = arg;
}
+#line 1695 "command.c" /* yacc.c:1646 */
break;
case 34:
-
-/* Line 1821 of yacc.c */
-#line 285 "command.y"
+#line 286 "command.y" /* yacc.c:1646 */
{
if (cmdtab[cmd_idx].class == D_FRAME
- && (yyvsp[(2) - (2)]) != NULL && (yyvsp[(2) - (2)])->a_int < 0)
- yyerror(_("invalid frame number: %d"), (yyvsp[(2) - (2)])->a_int);
+ && (yyvsp[0]) != NULL && (yyvsp[0])->a_int < 0)
+ yyerror(_("invalid frame number: %d"), (yyvsp[0])->a_int);
}
+#line 1705 "command.c" /* yacc.c:1646 */
break;
case 35:
-
-/* Line 1821 of yacc.c */
-#line 291 "command.y"
+#line 292 "command.y" /* yacc.c:1646 */
{
- int idx = find_argument((yyvsp[(2) - (2)]));
+ int idx = find_argument((yyvsp[0]));
if (idx < 0)
- yyerror(_("info: invalid option - \"%s\""), (yyvsp[(2) - (2)])->a_string);
+ yyerror(_("info: invalid option - \"%s\""), (yyvsp[0])->a_string);
else {
- efree((yyvsp[(2) - (2)])->a_string);
- (yyvsp[(2) - (2)])->a_string = NULL;
- (yyvsp[(2) - (2)])->type = D_argument;
- (yyvsp[(2) - (2)])->a_argument = argtab[idx].value;
+ efree((yyvsp[0])->a_string);
+ (yyvsp[0])->a_string = NULL;
+ (yyvsp[0])->type = D_argument;
+ (yyvsp[0])->a_argument = argtab[idx].value;
}
}
+#line 1721 "command.c" /* yacc.c:1646 */
break;
case 38:
-
-/* Line 1821 of yacc.c */
-#line 304 "command.y"
- { want_nodeval = TRUE; }
+#line 305 "command.y" /* yacc.c:1646 */
+ { want_nodeval = true; }
+#line 1727 "command.c" /* yacc.c:1646 */
break;
case 40:
-
-/* Line 1821 of yacc.c */
-#line 305 "command.y"
- { want_nodeval = TRUE; }
+#line 306 "command.y" /* yacc.c:1646 */
+ { want_nodeval = true; }
+#line 1733 "command.c" /* yacc.c:1646 */
break;
case 46:
-
-/* Line 1821 of yacc.c */
-#line 310 "command.y"
- { want_nodeval = TRUE; }
+#line 311 "command.y" /* yacc.c:1646 */
+ { want_nodeval = true; }
+#line 1739 "command.c" /* yacc.c:1646 */
break;
case 49:
-
-/* Line 1821 of yacc.c */
-#line 312 "command.y"
- { want_nodeval = TRUE; }
+#line 313 "command.y" /* yacc.c:1646 */
+ { want_nodeval = true; }
+#line 1745 "command.c" /* yacc.c:1646 */
break;
case 51:
-
-/* Line 1821 of yacc.c */
-#line 313 "command.y"
- { want_nodeval = TRUE; }
+#line 314 "command.y" /* yacc.c:1646 */
+ { want_nodeval = true; }
+#line 1751 "command.c" /* yacc.c:1646 */
break;
case 53:
-
-/* Line 1821 of yacc.c */
-#line 314 "command.y"
- { want_nodeval = TRUE; }
+#line 315 "command.y" /* yacc.c:1646 */
+ { want_nodeval = true; }
+#line 1757 "command.c" /* yacc.c:1646 */
break;
case 57:
-
-/* Line 1821 of yacc.c */
-#line 318 "command.y"
+#line 319 "command.y" /* yacc.c:1646 */
{
- if (in_cmd_src((yyvsp[(2) - (2)])->a_string))
- yyerror(_("source \"%s\": already sourced."), (yyvsp[(2) - (2)])->a_string);
+ if (in_cmd_src((yyvsp[0])->a_string))
+ yyerror(_("source \"%s\": already sourced."), (yyvsp[0])->a_string);
}
+#line 1766 "command.c" /* yacc.c:1646 */
break;
case 58:
-
-/* Line 1821 of yacc.c */
-#line 323 "command.y"
+#line 324 "command.y" /* yacc.c:1646 */
{
if (! input_from_tty)
- yyerror(_("save \"%s\": command not permitted."), (yyvsp[(2) - (2)])->a_string);
+ yyerror(_("save \"%s\": command not permitted."), (yyvsp[0])->a_string);
}
+#line 1775 "command.c" /* yacc.c:1646 */
break;
case 59:
-
-/* Line 1821 of yacc.c */
-#line 328 "command.y"
+#line 329 "command.y" /* yacc.c:1646 */
{
int type = 0;
int num;
- if ((yyvsp[(2) - (2)]) != NULL)
- num = (yyvsp[(2) - (2)])->a_int;
+ if ((yyvsp[0]) != NULL)
+ num = (yyvsp[0])->a_int;
if (errcount != 0)
;
else if (in_commands)
yyerror(_("Can't use command `commands' for breakpoint/watchpoint commands"));
- else if ((yyvsp[(2) - (2)]) == NULL && ! (type = has_break_or_watch_point(&num, TRUE)))
+ else if ((yyvsp[0]) == NULL && ! (type = has_break_or_watch_point(&num, true)))
yyerror(_("no breakpoint/watchpoint has been set yet"));
- else if ((yyvsp[(2) - (2)]) != NULL && ! (type = has_break_or_watch_point(&num, FALSE)))
+ else if ((yyvsp[0]) != NULL && ! (type = has_break_or_watch_point(&num, false)))
yyerror(_("invalid breakpoint/watchpoint number"));
if (type) {
- in_commands = TRUE;
+ in_commands = true;
if (input_from_tty) {
- dPrompt = commands_Prompt;
+ dbg_prompt = commands_prompt;
fprintf(out_fp, _("Type commands for when %s %d is hit, one per line.\n"),
(type == D_break) ? "breakpoint" : "watchpoint", num);
fprintf(out_fp, _("End with the command \"end\"\n"));
}
}
}
+#line 1805 "command.c" /* yacc.c:1646 */
break;
case 60:
-
-/* Line 1821 of yacc.c */
-#line 354 "command.y"
+#line 355 "command.y" /* yacc.c:1646 */
{
if (! in_commands)
yyerror(_("`end' valid only in command `commands' or `eval'"));
else {
if (input_from_tty)
- dPrompt = dgawk_Prompt;
- in_commands = FALSE;
+ dbg_prompt = dgawk_prompt;
+ in_commands = false;
}
}
+#line 1819 "command.c" /* yacc.c:1646 */
break;
case 61:
-
-/* Line 1821 of yacc.c */
-#line 364 "command.y"
+#line 365 "command.y" /* yacc.c:1646 */
{
if (! in_commands)
yyerror(_("`silent' valid only in command `commands'"));
}
+#line 1828 "command.c" /* yacc.c:1646 */
break;
case 62:
-
-/* Line 1821 of yacc.c */
-#line 369 "command.y"
+#line 370 "command.y" /* yacc.c:1646 */
{
- int idx = find_argument((yyvsp[(2) - (2)]));
+ int idx = find_argument((yyvsp[0]));
if (idx < 0)
- yyerror(_("trace: invalid option - \"%s\""), (yyvsp[(2) - (2)])->a_string);
+ yyerror(_("trace: invalid option - \"%s\""), (yyvsp[0])->a_string);
else {
- efree((yyvsp[(2) - (2)])->a_string);
- (yyvsp[(2) - (2)])->a_string = NULL;
- (yyvsp[(2) - (2)])->type = D_argument;
- (yyvsp[(2) - (2)])->a_argument = argtab[idx].value;
+ efree((yyvsp[0])->a_string);
+ (yyvsp[0])->a_string = NULL;
+ (yyvsp[0])->type = D_argument;
+ (yyvsp[0])->a_argument = argtab[idx].value;
}
}
+#line 1844 "command.c" /* yacc.c:1646 */
break;
case 63:
-
-/* Line 1821 of yacc.c */
-#line 380 "command.y"
- { want_nodeval = TRUE; }
+#line 381 "command.y" /* yacc.c:1646 */
+ { want_nodeval = true; }
+#line 1850 "command.c" /* yacc.c:1646 */
break;
case 64:
-
-/* Line 1821 of yacc.c */
-#line 381 "command.y"
+#line 382 "command.y" /* yacc.c:1646 */
{
int type;
- int num = (yyvsp[(2) - (4)])->a_int;
- type = has_break_or_watch_point(&num, FALSE);
+ int num = (yyvsp[-2])->a_int;
+ type = has_break_or_watch_point(&num, false);
if (! type)
yyerror(_("condition: invalid breakpoint/watchpoint number"));
}
+#line 1862 "command.c" /* yacc.c:1646 */
break;
case 65:
-
-/* Line 1821 of yacc.c */
-#line 389 "command.y"
+#line 390 "command.y" /* yacc.c:1646 */
{
if (in_commands) {
/* Prepend command 'eval' to argument list */
@@ -2085,433 +1873,387 @@ yyreduce:
arg_list = arg;
}
}
+#line 1877 "command.c" /* yacc.c:1646 */
break;
case 66:
-
-/* Line 1821 of yacc.c */
-#line 403 "command.y"
+#line 404 "command.y" /* yacc.c:1646 */
{
- if ((yyvsp[(1) - (1)]) != NULL) {
- NODE *n = (yyvsp[(1) - (1)])->a_node;
- (yyvsp[(1) - (1)])->type = D_string;
- (yyvsp[(1) - (1)])->a_string = n->stptr;
+ if ((yyvsp[0]) != NULL) {
+ NODE *n = (yyvsp[0])->a_node;
+ (yyvsp[0])->type = D_string;
+ (yyvsp[0])->a_string = n->stptr;
freenode(n);
}
- (yyval) = (yyvsp[(1) - (1)]);
+ (yyval) = (yyvsp[0]);
}
+#line 1891 "command.c" /* yacc.c:1646 */
break;
case 68:
-
-/* Line 1821 of yacc.c */
-#line 417 "command.y"
+#line 418 "command.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 1897 "command.c" /* yacc.c:1646 */
break;
case 69:
-
-/* Line 1821 of yacc.c */
-#line 422 "command.y"
+#line 423 "command.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 1903 "command.c" /* yacc.c:1646 */
break;
case 74:
-
-/* Line 1821 of yacc.c */
-#line 431 "command.y"
+#line 432 "command.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 1909 "command.c" /* yacc.c:1646 */
break;
case 75:
-
-/* Line 1821 of yacc.c */
-#line 436 "command.y"
+#line 437 "command.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 1915 "command.c" /* yacc.c:1646 */
break;
case 77:
-
-/* Line 1821 of yacc.c */
-#line 439 "command.y"
+#line 440 "command.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 1921 "command.c" /* yacc.c:1646 */
break;
case 78:
-
-/* Line 1821 of yacc.c */
-#line 444 "command.y"
+#line 445 "command.y" /* yacc.c:1646 */
{
NODE *n;
- n = (yyvsp[(1) - (1)])->a_node;
+ n = (yyvsp[0])->a_node;
if ((n->flags & STRING) == 0)
yyerror(_("argument not a string"));
}
+#line 1932 "command.c" /* yacc.c:1646 */
break;
case 79:
-
-/* Line 1821 of yacc.c */
-#line 454 "command.y"
+#line 455 "command.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 1938 "command.c" /* yacc.c:1646 */
break;
case 80:
-
-/* Line 1821 of yacc.c */
-#line 456 "command.y"
+#line 457 "command.y" /* yacc.c:1646 */
{
- if (find_option((yyvsp[(1) - (1)])->a_string) < 0)
- yyerror(_("option: invalid parameter - \"%s\""), (yyvsp[(1) - (1)])->a_string);
+ if (find_option((yyvsp[0])->a_string) < 0)
+ yyerror(_("option: invalid parameter - \"%s\""), (yyvsp[0])->a_string);
}
+#line 1947 "command.c" /* yacc.c:1646 */
break;
case 81:
-
-/* Line 1821 of yacc.c */
-#line 461 "command.y"
+#line 462 "command.y" /* yacc.c:1646 */
{
- if (find_option((yyvsp[(1) - (3)])->a_string) < 0)
- yyerror(_("option: invalid parameter - \"%s\""), (yyvsp[(1) - (3)])->a_string);
+ if (find_option((yyvsp[-2])->a_string) < 0)
+ yyerror(_("option: invalid parameter - \"%s\""), (yyvsp[-2])->a_string);
}
+#line 1956 "command.c" /* yacc.c:1646 */
break;
case 82:
-
-/* Line 1821 of yacc.c */
-#line 469 "command.y"
+#line 470 "command.y" /* yacc.c:1646 */
{
NODE *n;
- n = lookup((yyvsp[(1) - (1)])->a_string);
+ n = lookup((yyvsp[0])->a_string);
if (n == NULL || n->type != Node_func)
- yyerror(_("no such function - \"%s\""), (yyvsp[(1) - (1)])->a_string);
+ yyerror(_("no such function - \"%s\""), (yyvsp[0])->a_string);
else {
- (yyvsp[(1) - (1)])->type = D_func;
- efree((yyvsp[(1) - (1)])->a_string);
- (yyvsp[(1) - (1)])->a_string = NULL;
- (yyvsp[(1) - (1)])->a_node = n;
+ (yyvsp[0])->type = D_func;
+ efree((yyvsp[0])->a_string);
+ (yyvsp[0])->a_string = NULL;
+ (yyvsp[0])->a_node = n;
}
}
+#line 1973 "command.c" /* yacc.c:1646 */
break;
case 83:
-
-/* Line 1821 of yacc.c */
-#line 485 "command.y"
+#line 486 "command.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 1979 "command.c" /* yacc.c:1646 */
break;
case 88:
-
-/* Line 1821 of yacc.c */
-#line 494 "command.y"
+#line 495 "command.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 1985 "command.c" /* yacc.c:1646 */
break;
case 89:
-
-/* Line 1821 of yacc.c */
-#line 495 "command.y"
- { want_nodeval = TRUE; }
+#line 496 "command.y" /* yacc.c:1646 */
+ { want_nodeval = true; }
+#line 1991 "command.c" /* yacc.c:1646 */
break;
case 92:
-
-/* Line 1821 of yacc.c */
-#line 497 "command.y"
- { want_nodeval = TRUE; }
+#line 498 "command.y" /* yacc.c:1646 */
+ { want_nodeval = true; }
+#line 1997 "command.c" /* yacc.c:1646 */
break;
case 95:
-
-/* Line 1821 of yacc.c */
-#line 503 "command.y"
+#line 504 "command.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 2003 "command.c" /* yacc.c:1646 */
break;
case 97:
-
-/* Line 1821 of yacc.c */
-#line 509 "command.y"
+#line 510 "command.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 2009 "command.c" /* yacc.c:1646 */
break;
case 99:
-
-/* Line 1821 of yacc.c */
-#line 515 "command.y"
+#line 516 "command.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 2015 "command.c" /* yacc.c:1646 */
break;
case 104:
-
-/* Line 1821 of yacc.c */
-#line 527 "command.y"
+#line 528 "command.y" /* yacc.c:1646 */
{
- int idx = find_argument((yyvsp[(1) - (2)]));
+ int idx = find_argument((yyvsp[-1]));
if (idx < 0)
- yyerror(_("enable: invalid option - \"%s\""), (yyvsp[(1) - (2)])->a_string);
+ yyerror(_("enable: invalid option - \"%s\""), (yyvsp[-1])->a_string);
else {
- efree((yyvsp[(1) - (2)])->a_string);
- (yyvsp[(1) - (2)])->a_string = NULL;
- (yyvsp[(1) - (2)])->type = D_argument;
- (yyvsp[(1) - (2)])->a_argument = argtab[idx].value;
+ efree((yyvsp[-1])->a_string);
+ (yyvsp[-1])->a_string = NULL;
+ (yyvsp[-1])->type = D_argument;
+ (yyvsp[-1])->a_argument = argtab[idx].value;
}
}
+#line 2031 "command.c" /* yacc.c:1646 */
break;
case 106:
-
-/* Line 1821 of yacc.c */
-#line 543 "command.y"
+#line 544 "command.y" /* yacc.c:1646 */
{
- (yyvsp[(2) - (2)])->type = D_array; /* dump all items */
- (yyvsp[(2) - (2)])->a_count = 0;
+ (yyvsp[0])->type = D_array; /* dump all items */
+ (yyvsp[0])->a_count = 0;
}
+#line 2040 "command.c" /* yacc.c:1646 */
break;
case 107:
-
-/* Line 1821 of yacc.c */
-#line 548 "command.y"
+#line 549 "command.y" /* yacc.c:1646 */
{
- (yyvsp[(2) - (3)])->type = D_array;
- (yyvsp[(2) - (3)])->a_count = num_dim;
+ (yyvsp[-1])->type = D_array;
+ (yyvsp[-1])->a_count = num_dim;
}
+#line 2049 "command.c" /* yacc.c:1646 */
break;
case 117:
-
-/* Line 1821 of yacc.c */
-#line 574 "command.y"
+#line 575 "command.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 2055 "command.c" /* yacc.c:1646 */
break;
case 118:
-
-/* Line 1821 of yacc.c */
-#line 576 "command.y"
+#line 577 "command.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 2061 "command.c" /* yacc.c:1646 */
break;
case 119:
-
-/* Line 1821 of yacc.c */
-#line 578 "command.y"
+#line 579 "command.y" /* yacc.c:1646 */
{
CMDARG *a;
a = mk_cmdarg(D_int);
a->a_int = -1;
append_cmdarg(a);
}
+#line 2072 "command.c" /* yacc.c:1646 */
break;
case 126:
-
-/* Line 1821 of yacc.c */
-#line 594 "command.y"
+#line 595 "command.y" /* yacc.c:1646 */
{
- if ((yyvsp[(1) - (3)])->a_int > (yyvsp[(3) - (3)])->a_int)
+ if ((yyvsp[-2])->a_int > (yyvsp[0])->a_int)
yyerror(_("invalid range specification: %d - %d"),
- (yyvsp[(1) - (3)])->a_int, (yyvsp[(3) - (3)])->a_int);
+ (yyvsp[-2])->a_int, (yyvsp[0])->a_int);
else
- (yyvsp[(1) - (3)])->type = D_range;
- (yyval) = (yyvsp[(1) - (3)]);
+ (yyvsp[-2])->type = D_range;
+ (yyval) = (yyvsp[-2]);
}
+#line 2085 "command.c" /* yacc.c:1646 */
break;
case 127:
-
-/* Line 1821 of yacc.c */
-#line 606 "command.y"
+#line 607 "command.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 2091 "command.c" /* yacc.c:1646 */
break;
case 134:
-
-/* Line 1821 of yacc.c */
-#line 620 "command.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+#line 621 "command.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 2097 "command.c" /* yacc.c:1646 */
break;
case 135:
-
-/* Line 1821 of yacc.c */
-#line 622 "command.y"
- { (yyval) = (yyvsp[(1) - (3)]); }
+#line 623 "command.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[-2]); }
+#line 2103 "command.c" /* yacc.c:1646 */
break;
case 137:
-
-/* Line 1821 of yacc.c */
-#line 628 "command.y"
+#line 629 "command.y" /* yacc.c:1646 */
{
CMDARG *a;
NODE *subs;
int count = 0;
- for (a = (yyvsp[(2) - (3)]); a != NULL; a = a->next)
+ for (a = (yyvsp[-1]); a != NULL; a = a->next)
count++;
- subs = concat_args((yyvsp[(2) - (3)]), count);
- free_cmdarg((yyvsp[(2) - (3)])->next);
- (yyvsp[(2) - (3)])->next = NULL;
- (yyvsp[(2) - (3)])->type = D_node;
- (yyvsp[(2) - (3)])->a_node = subs;
- (yyval) = (yyvsp[(2) - (3)]);
+ subs = concat_args((yyvsp[-1]), count);
+ free_cmdarg((yyvsp[-1])->next);
+ (yyvsp[-1])->next = NULL;
+ (yyvsp[-1])->type = D_node;
+ (yyvsp[-1])->a_node = subs;
+ (yyval) = (yyvsp[-1]);
}
+#line 2122 "command.c" /* yacc.c:1646 */
break;
case 139:
-
-/* Line 1821 of yacc.c */
-#line 647 "command.y"
- { (yyval) = (yyvsp[(1) - (1)]); num_dim = 1; }
+#line 648 "command.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); num_dim = 1; }
+#line 2128 "command.c" /* yacc.c:1646 */
break;
case 140:
-
-/* Line 1821 of yacc.c */
-#line 649 "command.y"
- { (yyval) = (yyvsp[(1) - (2)]); num_dim++; }
+#line 650 "command.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[-1]); num_dim++; }
+#line 2134 "command.c" /* yacc.c:1646 */
break;
case 142:
-
-/* Line 1821 of yacc.c */
-#line 655 "command.y"
+#line 656 "command.y" /* yacc.c:1646 */
{
- NODE *n = (yyvsp[(2) - (2)])->a_node;
+ NODE *n = (yyvsp[0])->a_node;
if ((n->flags & NUMBER) == 0)
yyerror(_("non-numeric value for field number"));
else
- (yyvsp[(2) - (2)])->type = D_field;
- (yyval) = (yyvsp[(2) - (2)]);
+ (yyvsp[0])->type = D_field;
+ (yyval) = (yyvsp[0]);
}
+#line 2147 "command.c" /* yacc.c:1646 */
break;
case 143:
-
-/* Line 1821 of yacc.c */
-#line 664 "command.y"
+#line 665 "command.y" /* yacc.c:1646 */
{
/* a_string is array name, a_count is dimension count */
- (yyvsp[(1) - (2)])->type = D_subscript;
- (yyvsp[(1) - (2)])->a_count = num_dim;
- (yyval) = (yyvsp[(1) - (2)]);
+ (yyvsp[-1])->type = D_subscript;
+ (yyvsp[-1])->a_count = num_dim;
+ (yyval) = (yyvsp[-1]);
}
+#line 2158 "command.c" /* yacc.c:1646 */
break;
case 144:
-
-/* Line 1821 of yacc.c */
-#line 674 "command.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+#line 675 "command.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 2164 "command.c" /* yacc.c:1646 */
break;
case 145:
-
-/* Line 1821 of yacc.c */
-#line 676 "command.y"
+#line 677 "command.y" /* yacc.c:1646 */
{
- NODE *n = (yyvsp[(2) - (2)])->a_node;
+ NODE *n = (yyvsp[0])->a_node;
if ((n->flags & NUMBER) == 0)
yyerror(_("non-numeric value found, numeric expected"));
- (yyval) = (yyvsp[(2) - (2)]);
+ (yyval) = (yyvsp[0]);
}
+#line 2175 "command.c" /* yacc.c:1646 */
break;
case 146:
-
-/* Line 1821 of yacc.c */
-#line 683 "command.y"
+#line 684 "command.y" /* yacc.c:1646 */
{
- NODE *n = (yyvsp[(2) - (2)])->a_node;
+ NODE *n = (yyvsp[0])->a_node;
if ((n->flags & NUMBER) == 0)
yyerror(_("non-numeric value found, numeric expected"));
else
- (yyvsp[(2) - (2)])->a_node->numbr = - n->numbr;
- (yyval) = (yyvsp[(2) - (2)]);
+ negate_num(n);
+ (yyval) = (yyvsp[0]);
}
+#line 2188 "command.c" /* yacc.c:1646 */
break;
case 147:
-
-/* Line 1821 of yacc.c */
-#line 695 "command.y"
+#line 696 "command.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 2194 "command.c" /* yacc.c:1646 */
break;
case 148:
-
-/* Line 1821 of yacc.c */
-#line 697 "command.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+#line 698 "command.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 2200 "command.c" /* yacc.c:1646 */
break;
case 149:
-
-/* Line 1821 of yacc.c */
-#line 702 "command.y"
+#line 703 "command.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
+#line 2206 "command.c" /* yacc.c:1646 */
break;
case 150:
-
-/* Line 1821 of yacc.c */
-#line 704 "command.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+#line 705 "command.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 2212 "command.c" /* yacc.c:1646 */
break;
case 151:
-
-/* Line 1821 of yacc.c */
-#line 709 "command.y"
+#line 710 "command.y" /* yacc.c:1646 */
{
- if ((yyvsp[(1) - (1)])->a_int == 0)
+ if ((yyvsp[0])->a_int == 0)
yyerror(_("non-zero integer value"));
- (yyval) = (yyvsp[(1) - (1)]);
+ (yyval) = (yyvsp[0]);
}
+#line 2222 "command.c" /* yacc.c:1646 */
break;
case 152:
-
-/* Line 1821 of yacc.c */
-#line 715 "command.y"
+#line 716 "command.y" /* yacc.c:1646 */
{
- if ((yyvsp[(2) - (2)])->a_int == 0)
+ if ((yyvsp[0])->a_int == 0)
yyerror(_("non-zero integer value"));
- (yyval) = (yyvsp[(2) - (2)]);
+ (yyval) = (yyvsp[0]);
}
+#line 2232 "command.c" /* yacc.c:1646 */
break;
case 153:
-
-/* Line 1821 of yacc.c */
-#line 724 "command.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
+#line 725 "command.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 2238 "command.c" /* yacc.c:1646 */
break;
case 154:
-
-/* Line 1821 of yacc.c */
-#line 726 "command.y"
- { (yyval) = (yyvsp[(2) - (2)]); }
+#line 727 "command.y" /* yacc.c:1646 */
+ { (yyval) = (yyvsp[0]); }
+#line 2244 "command.c" /* yacc.c:1646 */
break;
case 155:
-
-/* Line 1821 of yacc.c */
-#line 728 "command.y"
+#line 729 "command.y" /* yacc.c:1646 */
{
- (yyvsp[(2) - (2)])->a_int = - (yyvsp[(2) - (2)])->a_int;
- (yyval) = (yyvsp[(2) - (2)]);
+ (yyvsp[0])->a_int = - (yyvsp[0])->a_int;
+ (yyval) = (yyvsp[0]);
}
+#line 2253 "command.c" /* yacc.c:1646 */
break;
case 156:
-
-/* Line 1821 of yacc.c */
-#line 736 "command.y"
+#line 737 "command.y" /* yacc.c:1646 */
{
if (lexptr_begin != NULL) {
if (input_from_tty && lexptr_begin[0] != '\0')
@@ -2520,12 +2262,11 @@ yyreduce:
lexptr_begin = NULL;
}
}
+#line 2266 "command.c" /* yacc.c:1646 */
break;
-
-/* Line 1821 of yacc.c */
-#line 2541 "command.c"
+#line 2270 "command.c" /* yacc.c:1646 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -2547,7 +2288,7 @@ yyreduce:
*++yyvsp = yyval;
- /* Now `shift' the result of the reduction. Determine what state
+ /* 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. */
@@ -2562,9 +2303,9 @@ yyreduce:
goto yynewstate;
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
+/*--------------------------------------.
+| yyerrlab -- here on detecting error. |
+`--------------------------------------*/
yyerrlab:
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
@@ -2615,20 +2356,20 @@ yyerrlab:
if (yyerrstatus == 3)
{
/* If just tried and failed to reuse lookahead token after an
- error, discard it. */
+ error, discard it. */
if (yychar <= YYEOF)
- {
- /* Return failure if at end of input. */
- if (yychar == YYEOF)
- YYABORT;
- }
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
else
- {
- yydestruct ("Error: discarding",
- yytoken, &yylval);
- yychar = YYEMPTY;
- }
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
}
/* Else will try to reuse lookahead token after shifting the error
@@ -2647,7 +2388,7 @@ yyerrorlab:
if (/*CONSTCOND*/ 0)
goto yyerrorlab;
- /* Do not reclaim the symbols of the rule which action triggered
+ /* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */
YYPOPSTACK (yylen);
yylen = 0;
@@ -2660,35 +2401,37 @@ yyerrorlab:
| yyerrlab1 -- common code for both syntax error and YYERROR. |
`-------------------------------------------------------------*/
yyerrlab1:
- yyerrstatus = 3; /* Each real token shifted decrements this. */
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
for (;;)
{
yyn = yypact[yystate];
if (!yypact_value_is_default (yyn))
- {
- yyn += YYTERROR;
- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
- {
- yyn = yytable[yyn];
- if (0 < yyn)
- break;
- }
- }
+ {
+ 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;
+ YYABORT;
yydestruct ("Error: popping",
- yystos[yystate], yyvsp);
+ yystos[yystate], yyvsp);
YYPOPSTACK (1);
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
}
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
/* Shift the error token. */
@@ -2712,7 +2455,7 @@ yyabortlab:
yyresult = 1;
goto yyreturn;
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#if !defined yyoverflow || YYERROR_VERBOSE
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
@@ -2731,14 +2474,14 @@ yyreturn:
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval);
}
- /* Do not reclaim the symbols of the rule which action triggered
+ /* Do not reclaim the symbols of the rule whose action triggered
this YYABORT or YYACCEPT. */
YYPOPSTACK (yylen);
YY_STACK_PRINT (yyss, yyssp);
while (yyssp != yyss)
{
yydestruct ("Cleanup: popping",
- yystos[*yyssp], yyvsp);
+ yystos[*yyssp], yyvsp);
YYPOPSTACK (1);
}
#ifndef yyoverflow
@@ -2749,14 +2492,9 @@ yyreturn:
if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);
#endif
- /* Make sure YYID is used. */
- return YYID (yyresult);
+ return yyresult;
}
-
-
-
-/* Line 2067 of yacc.c */
-#line 746 "command.y"
+#line 747 "command.y" /* yacc.c:1906 */
@@ -2910,6 +2648,8 @@ struct cmdtoken cmdtab[] = {
gettext_noop("up [N] - move N frames up the stack.") },
{ "watch", "w", D_watch, D_WATCH, do_watch,
gettext_noop("watch var - set a watchpoint for a variable.") },
+{ "where", "", D_backtrace, D_BACKTRACE, do_backtrace,
+ gettext_noop("where [N] - (same as backtrace) print trace of all or N innermost (outermost if N < 0) frames.") },
{ NULL, NULL, D_illegal, 0, (Func_cmd) 0,
NULL },
};
@@ -2929,7 +2669,7 @@ struct argtoken argtab[] = {
{ "sources", D_info, A_SOURCES },
{ "variables", D_info, A_VARIABLES },
{ "watch", D_info, A_WATCH },
- { NULL, D_illegal, 0 },
+ { NULL, D_illegal, A_NONE },
};
@@ -3051,7 +2791,7 @@ yylex(void)
if (lexptr_begin == NULL) {
again:
- lexptr_begin = read_a_line(dPrompt);
+ lexptr_begin = read_a_line(dbg_prompt);
if (lexptr_begin == NULL) { /* EOF or error */
if (get_eof_status() == EXIT_FATAL)
exit(EXIT_FATAL);
@@ -3125,7 +2865,7 @@ again:
}
while (c != '\0' && c != ' ' && c != '\t') {
- if (! isalpha(c) && ! in_eval) {
+ if (! is_alpha(c) && ! in_eval) {
yyerror(_("invalid character in command"));
return '\n';
}
@@ -3178,7 +2918,7 @@ again:
if (c == '"') {
char *str, *p;
int flags = ALREADY_MALLOCED;
- int esc_seen = FALSE;
+ bool esc_seen = false;
toklen = lexend - lexptr;
emalloc(str, char *, toklen + 2, "yylex");
@@ -3193,7 +2933,7 @@ err:
}
if (c == '\\') {
c = *++lexptr;
- esc_seen = TRUE;
+ esc_seen = true;
if (want_nodeval || c != '"')
*p++ = '\\';
}
@@ -3252,22 +2992,37 @@ err:
return D_STRING;
}
- /* assert(want_nodval == TRUE); */
-
/* look for awk number */
if (isdigit((unsigned char) tokstart[0])) {
- double d;
+ NODE *r = NULL;
errno = 0;
- d = strtod(tokstart, &lexptr);
+#ifdef HAVE_MPFR
+ if (do_mpfr) {
+ int tval;
+ r = mpg_float();
+ tval = mpfr_strtofr(r->mpg_numbr, tokstart, & lexptr, 0, ROUND_MODE);
+ IEEE_FMT(r->mpg_numbr, tval);
+ if (mpfr_integer_p(r->mpg_numbr)) {
+ /* integral value, convert to a GMP type. */
+ NODE *tmp = r;
+ r = mpg_integer();
+ mpfr_get_z(r->mpg_i, tmp->mpg_numbr, MPFR_RNDZ);
+ unref(tmp);
+ }
+ } else
+#endif
+ r = make_number(strtod(tokstart, & lexptr));
+
if (errno != 0) {
yyerror(strerror(errno));
+ unref(r);
errno = 0;
return '\n';
}
yylval = mk_cmdarg(D_node);
- yylval->a_node = make_number(d);
+ yylval->a_node = r;
append_cmdarg(yylval);
return D_NODE;
}
@@ -3278,12 +3033,12 @@ err:
|| c == ',' || c == '=')
return *lexptr++;
- if (c != '_' && ! isalpha(c)) {
+ if (c != '_' && ! is_alpha(c)) {
yyerror(_("invalid character"));
return '\n';
}
- while (isalnum(c) || c == '_')
+ while (is_identchar(c))
c = *++lexptr;
toklen = lexptr - tokstart;
@@ -3375,7 +3130,7 @@ find_command(const char *token, size_t toklen)
{
char *name, *abrv;
int i, k;
- int try_exact = TRUE;
+ bool try_exact = true;
int abrv_match = -1;
int partial_match = -1;
@@ -3399,7 +3154,7 @@ find_command(const char *token, size_t toklen)
return i;
if (*name > *token || i == (k - 1))
- try_exact = FALSE;
+ try_exact = false;
if (abrv_match < 0) {
abrv = cmdtab[i].abbrvn;
@@ -3447,16 +3202,18 @@ do_help(CMDARG *arg, int cmd)
i = find_command(name, strlen(name));
if (i >= 0) {
fprintf(out_fp, "%s\n", cmdtab[i].help_txt);
- if (STREQ(cmdtab[i].name, "option"))
+ if (strcmp(cmdtab[i].name, "option") == 0)
option_help();
} else
fprintf(out_fp, _("undefined command: %s\n"), name);
}
- return FALSE;
+ return false;
}
+#ifdef HAVE_LIBREADLINE
+
/* next_word --- find the next word in a line to complete
* (word seperation characters are space and tab).
*/
@@ -3483,8 +3240,6 @@ next_word(char *p, int len, char **endp)
return p;
}
-#ifdef HAVE_LIBREADLINE
-
/* command_completion --- attempt to complete based on the word number in line;
* try to complete on command names if this is the first word; for the next
* word(s), the type of completion depends on the command name (first word).
@@ -3502,7 +3257,7 @@ command_completion(const char *text, int start, int end)
int idx;
int len;
- rl_attempted_completion_over = TRUE; /* no default filename completion please */
+ rl_attempted_completion_over = true; /* no default filename completion please */
this_cmd = D_illegal;
len = start;
@@ -3688,4 +3443,3 @@ history_expand_line(char **line)
}
#endif
-
diff --git a/command.y b/command.y
index 18ef0613..08893743 100644
--- a/command.y
+++ b/command.y
@@ -1,9 +1,9 @@
/*
- * command.y - yacc/bison parser for debugger command
+ * command.y - yacc/bison parser for debugger commands.
*/
/*
- * Copyright (C) 2004, 2010, 2011 the Free Software Foundation, Inc.
+ * Copyright (C) 2004, 2010, 2011, 2014 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -37,24 +37,24 @@ static void yyerror(const char *mesg, ...);
static int find_command(const char *token, size_t toklen);
-static int want_nodeval = FALSE;
+static bool want_nodeval = false;
-static int cmd_idx = -1; /* index of current command in cmd table */
-static int repeat_idx = -1; /* index of last repeatable command in command table */
+static int cmd_idx = -1; /* index of current command in cmd table */
+static int repeat_idx = -1; /* index of last repeatable command in command table */
static CMDARG *arg_list = NULL; /* list of arguments */
static long errcount = 0;
static char *lexptr_begin = NULL;
-static int in_commands = FALSE;
+static bool in_commands = false;
static int num_dim;
-static int in_eval = FALSE;
+static bool in_eval = false;
static const char start_EVAL[] = "function @eval(){";
static const char end_EVAL[] = "}";
static CMDARG *append_statement(CMDARG *stmt_list, char *stmt);
-static char *next_word(char *p, int len, char **endp);
static NODE *concat_args(CMDARG *a, int count);
#ifdef HAVE_LIBREADLINE
+static char *next_word(char *p, int len, char **endp);
static void history_expand_line(char **line);
static char *command_generator(const char *text, int state);
static char *srcfile_generator(const char *text, int state);
@@ -108,7 +108,7 @@ input
| input line
{
cmd_idx = -1;
- want_nodeval = FALSE;
+ want_nodeval = false;
if (lexptr_begin != NULL) {
if (input_from_tty && lexptr_begin[0] != '\0')
add_history(lexptr_begin);
@@ -128,7 +128,7 @@ line
{
if (errcount == 0 && cmd_idx >= 0) {
Func_cmd cmdfunc;
- int terminate = FALSE;
+ bool terminate = false;
CMDARG *args;
int ctype = 0;
@@ -162,7 +162,7 @@ line
if (in_commands)
cmdfunc = do_commands;
cmd_idx = -1;
- want_nodeval = FALSE;
+ want_nodeval = false;
args = arg_list;
arg_list = NULL;
@@ -209,7 +209,7 @@ break_cmd
/* mid-rule action buried in non-terminal to avoid conflict */
set_want_nodeval
- : { want_nodeval = TRUE; }
+ : { want_nodeval = true; }
;
eval_prologue
@@ -220,12 +220,13 @@ eval_prologue
* non-terminal (empty rule action). See below.
*/
if (input_from_tty) {
- dPrompt = eval_Prompt;
- fprintf(out_fp, _("Type (g)awk statement(s). End with the command \"end\"\n"));
+ dbg_prompt = eval_prompt;
+ fprintf(out_fp,
+ _("Type (g)awk statement(s). End with the command \"end\"\n"));
rl_inhibit_completion = 1;
}
cmd_idx = -1;
- in_eval = TRUE;
+ in_eval = true;
}
}
;
@@ -256,11 +257,11 @@ eval_cmd
str[len - 2] = '\0';
}
if (input_from_tty) {
- dPrompt = in_commands ? commands_Prompt : dgawk_Prompt;
+ dbg_prompt = in_commands ? commands_prompt : dgawk_prompt;
rl_inhibit_completion = 0;
}
cmd_idx = find_command("eval", 4);
- in_eval = FALSE;
+ in_eval = false;
}
| D_EVAL set_want_nodeval string_node
{
@@ -301,17 +302,17 @@ command
}
| D_IGNORE plus_integer D_INT
| D_ENABLE enable_args
- | D_PRINT { want_nodeval = TRUE; } print_args
- | D_PRINTF { want_nodeval = TRUE; } printf_args
+ | D_PRINT { want_nodeval = true; } print_args
+ | D_PRINTF { want_nodeval = true; } printf_args
| D_LIST list_args
| D_UNTIL location
| D_CLEAR location
| break_cmd break_args
- | D_SET { want_nodeval = TRUE; } variable '=' node
+ | D_SET { want_nodeval = true; } variable '=' node
| D_OPTION option_args
- | D_RETURN { want_nodeval = TRUE; } opt_node
- | D_DISPLAY { want_nodeval = TRUE; } opt_variable
- | D_WATCH { want_nodeval = TRUE; } variable condition_exp
+ | D_RETURN { want_nodeval = true; } opt_node
+ | D_DISPLAY { want_nodeval = true; } opt_variable
+ | D_WATCH { want_nodeval = true; } variable condition_exp
| d_cmd opt_integer_list
| D_DUMP opt_string
| D_SOURCE D_STRING
@@ -336,14 +337,14 @@ command
;
else if (in_commands)
yyerror(_("Can't use command `commands' for breakpoint/watchpoint commands"));
- else if ($2 == NULL && ! (type = has_break_or_watch_point(&num, TRUE)))
+ else if ($2 == NULL && ! (type = has_break_or_watch_point(&num, true)))
yyerror(_("no breakpoint/watchpoint has been set yet"));
- else if ($2 != NULL && ! (type = has_break_or_watch_point(&num, FALSE)))
+ else if ($2 != NULL && ! (type = has_break_or_watch_point(&num, false)))
yyerror(_("invalid breakpoint/watchpoint number"));
if (type) {
- in_commands = TRUE;
+ in_commands = true;
if (input_from_tty) {
- dPrompt = commands_Prompt;
+ dbg_prompt = commands_prompt;
fprintf(out_fp, _("Type commands for when %s %d is hit, one per line.\n"),
(type == D_break) ? "breakpoint" : "watchpoint", num);
fprintf(out_fp, _("End with the command \"end\"\n"));
@@ -356,8 +357,8 @@ command
yyerror(_("`end' valid only in command `commands' or `eval'"));
else {
if (input_from_tty)
- dPrompt = dgawk_Prompt;
- in_commands = FALSE;
+ dbg_prompt = dgawk_prompt;
+ in_commands = false;
}
}
| D_SILENT
@@ -377,11 +378,11 @@ command
$2->a_argument = argtab[idx].value;
}
}
- | D_CONDITION plus_integer { want_nodeval = TRUE; } condition_exp
+ | D_CONDITION plus_integer { want_nodeval = true; } condition_exp
{
int type;
int num = $2->a_int;
- type = has_break_or_watch_point(&num, FALSE);
+ type = has_break_or_watch_point(&num, false);
if (! type)
yyerror(_("condition: invalid breakpoint/watchpoint number"));
}
@@ -492,9 +493,9 @@ location
break_args
: /* empty */
{ $$ = NULL; }
- | plus_integer { want_nodeval = TRUE; } condition_exp
+ | plus_integer { want_nodeval = true; } condition_exp
| func_name
- | D_STRING ':' plus_integer { want_nodeval = TRUE; } condition_exp
+ | D_STRING ':' plus_integer { want_nodeval = true; } condition_exp
| D_STRING ':' func_name
;
@@ -685,7 +686,7 @@ node
if ((n->flags & NUMBER) == 0)
yyerror(_("non-numeric value found, numeric expected"));
else
- $2->a_node->numbr = - n->numbr;
+ negate_num(n);
$$ = $2;
}
;
@@ -896,6 +897,8 @@ struct cmdtoken cmdtab[] = {
gettext_noop("up [N] - move N frames up the stack.") },
{ "watch", "w", D_watch, D_WATCH, do_watch,
gettext_noop("watch var - set a watchpoint for a variable.") },
+{ "where", "", D_backtrace, D_BACKTRACE, do_backtrace,
+ gettext_noop("where [N] - (same as backtrace) print trace of all or N innermost (outermost if N < 0) frames.") },
{ NULL, NULL, D_illegal, 0, (Func_cmd) 0,
NULL },
};
@@ -915,7 +918,7 @@ struct argtoken argtab[] = {
{ "sources", D_info, A_SOURCES },
{ "variables", D_info, A_VARIABLES },
{ "watch", D_info, A_WATCH },
- { NULL, D_illegal, 0 },
+ { NULL, D_illegal, A_NONE },
};
@@ -1037,7 +1040,7 @@ yylex(void)
if (lexptr_begin == NULL) {
again:
- lexptr_begin = read_a_line(dPrompt);
+ lexptr_begin = read_a_line(dbg_prompt);
if (lexptr_begin == NULL) { /* EOF or error */
if (get_eof_status() == EXIT_FATAL)
exit(EXIT_FATAL);
@@ -1111,7 +1114,7 @@ again:
}
while (c != '\0' && c != ' ' && c != '\t') {
- if (! isalpha(c) && ! in_eval) {
+ if (! is_alpha(c) && ! in_eval) {
yyerror(_("invalid character in command"));
return '\n';
}
@@ -1164,7 +1167,7 @@ again:
if (c == '"') {
char *str, *p;
int flags = ALREADY_MALLOCED;
- int esc_seen = FALSE;
+ bool esc_seen = false;
toklen = lexend - lexptr;
emalloc(str, char *, toklen + 2, "yylex");
@@ -1179,7 +1182,7 @@ err:
}
if (c == '\\') {
c = *++lexptr;
- esc_seen = TRUE;
+ esc_seen = true;
if (want_nodeval || c != '"')
*p++ = '\\';
}
@@ -1238,22 +1241,37 @@ err:
return D_STRING;
}
- /* assert(want_nodval == TRUE); */
-
/* look for awk number */
if (isdigit((unsigned char) tokstart[0])) {
- double d;
+ NODE *r = NULL;
errno = 0;
- d = strtod(tokstart, &lexptr);
+#ifdef HAVE_MPFR
+ if (do_mpfr) {
+ int tval;
+ r = mpg_float();
+ tval = mpfr_strtofr(r->mpg_numbr, tokstart, & lexptr, 0, ROUND_MODE);
+ IEEE_FMT(r->mpg_numbr, tval);
+ if (mpfr_integer_p(r->mpg_numbr)) {
+ /* integral value, convert to a GMP type. */
+ NODE *tmp = r;
+ r = mpg_integer();
+ mpfr_get_z(r->mpg_i, tmp->mpg_numbr, MPFR_RNDZ);
+ unref(tmp);
+ }
+ } else
+#endif
+ r = make_number(strtod(tokstart, & lexptr));
+
if (errno != 0) {
yyerror(strerror(errno));
+ unref(r);
errno = 0;
return '\n';
}
yylval = mk_cmdarg(D_node);
- yylval->a_node = make_number(d);
+ yylval->a_node = r;
append_cmdarg(yylval);
return D_NODE;
}
@@ -1264,12 +1282,12 @@ err:
|| c == ',' || c == '=')
return *lexptr++;
- if (c != '_' && ! isalpha(c)) {
+ if (c != '_' && ! is_alpha(c)) {
yyerror(_("invalid character"));
return '\n';
}
- while (isalnum(c) || c == '_')
+ while (is_identchar(c))
c = *++lexptr;
toklen = lexptr - tokstart;
@@ -1361,7 +1379,7 @@ find_command(const char *token, size_t toklen)
{
char *name, *abrv;
int i, k;
- int try_exact = TRUE;
+ bool try_exact = true;
int abrv_match = -1;
int partial_match = -1;
@@ -1385,7 +1403,7 @@ find_command(const char *token, size_t toklen)
return i;
if (*name > *token || i == (k - 1))
- try_exact = FALSE;
+ try_exact = false;
if (abrv_match < 0) {
abrv = cmdtab[i].abbrvn;
@@ -1433,16 +1451,18 @@ do_help(CMDARG *arg, int cmd)
i = find_command(name, strlen(name));
if (i >= 0) {
fprintf(out_fp, "%s\n", cmdtab[i].help_txt);
- if (STREQ(cmdtab[i].name, "option"))
+ if (strcmp(cmdtab[i].name, "option") == 0)
option_help();
} else
fprintf(out_fp, _("undefined command: %s\n"), name);
}
- return FALSE;
+ return false;
}
+#ifdef HAVE_LIBREADLINE
+
/* next_word --- find the next word in a line to complete
* (word seperation characters are space and tab).
*/
@@ -1469,8 +1489,6 @@ next_word(char *p, int len, char **endp)
return p;
}
-#ifdef HAVE_LIBREADLINE
-
/* command_completion --- attempt to complete based on the word number in line;
* try to complete on command names if this is the first word; for the next
* word(s), the type of completion depends on the command name (first word).
@@ -1488,7 +1506,7 @@ command_completion(const char *text, int start, int end)
int idx;
int len;
- rl_attempted_completion_over = TRUE; /* no default filename completion please */
+ rl_attempted_completion_over = true; /* no default filename completion please */
this_cmd = D_illegal;
len = start;
diff --git a/compile b/compile
new file mode 100755
index 00000000..531136b0
--- /dev/null
+++ b/compile
@@ -0,0 +1,347 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2013 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, see <http://www.gnu.org/licenses/>.
+
+# 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>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" "" $nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+ file=$1
+ case $file in
+ / | /[!/]*) # absolute file, and not a UNC file
+ if test -z "$file_conv"; then
+ # lazily determine how to convert abs files
+ case `uname -s` in
+ MINGW*)
+ file_conv=mingw
+ ;;
+ CYGWIN*)
+ file_conv=cygwin
+ ;;
+ *)
+ file_conv=wine
+ ;;
+ esac
+ fi
+ case $file_conv/,$2, in
+ *,$file_conv,*)
+ ;;
+ mingw/*)
+ file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+ ;;
+ cygwin/*)
+ file=`cygpath -m "$file" || echo "$file"`
+ ;;
+ wine/*)
+ file=`winepath -w "$file" || echo "$file"`
+ ;;
+ esac
+ ;;
+ esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+ func_file_conv "$1"
+ if test -z "$lib_path"; then
+ lib_path=$file
+ else
+ lib_path="$lib_path;$file"
+ fi
+ linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+ lib=$1
+ found=no
+ save_IFS=$IFS
+ IFS=';'
+ for dir in $lib_path $LIB
+ do
+ IFS=$save_IFS
+ if $shared && test -f "$dir/$lib.dll.lib"; then
+ found=yes
+ lib=$dir/$lib.dll.lib
+ break
+ fi
+ if test -f "$dir/$lib.lib"; then
+ found=yes
+ lib=$dir/$lib.lib
+ break
+ fi
+ if test -f "$dir/lib$lib.a"; then
+ found=yes
+ lib=$dir/lib$lib.a
+ break
+ fi
+ done
+ IFS=$save_IFS
+
+ if test "$found" != yes; then
+ lib=$lib.lib
+ fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+ # Assume a capable shell
+ lib_path=
+ shared=:
+ linker_opts=
+ for arg
+ do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ eat=1
+ case $2 in
+ *.o | *.[oO][bB][jJ])
+ func_file_conv "$2"
+ set x "$@" -Fo"$file"
+ shift
+ ;;
+ *)
+ func_file_conv "$2"
+ set x "$@" -Fe"$file"
+ shift
+ ;;
+ esac
+ ;;
+ -I)
+ eat=1
+ func_file_conv "$2" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -I*)
+ func_file_conv "${1#-I}" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -l)
+ eat=1
+ func_cl_dashl "$2"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -l*)
+ func_cl_dashl "${1#-l}"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -L)
+ eat=1
+ func_cl_dashL "$2"
+ ;;
+ -L*)
+ func_cl_dashL "${1#-L}"
+ ;;
+ -static)
+ shared=false
+ ;;
+ -Wl,*)
+ arg=${1#-Wl,}
+ save_ifs="$IFS"; IFS=','
+ for flag in $arg; do
+ IFS="$save_ifs"
+ linker_opts="$linker_opts $flag"
+ done
+ IFS="$save_ifs"
+ ;;
+ -Xlinker)
+ eat=1
+ linker_opts="$linker_opts $2"
+ ;;
+ -*)
+ set x "$@" "$1"
+ shift
+ ;;
+ *.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+ func_file_conv "$1"
+ set x "$@" -Tp"$file"
+ shift
+ ;;
+ *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+ func_file_conv "$1" mingw
+ set x "$@" "$file"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+ done
+ if test -n "$linker_opts"; then
+ linker_opts="-link$linker_opts"
+ fi
+ exec "$@" $linker_opts
+ exit 1
+}
+
+eat=
+
+case $1 in
+ '')
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "compile $scriptversion"
+ exit $?
+ ;;
+ cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+ func_cl_wrapper "$@" # Doesn't return...
+ ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ # So we strip '-o arg' only if arg is an object.
+ eat=1
+ case $2 in
+ *.o | *.obj)
+ ofile=$2
+ ;;
+ *)
+ set x "$@" -o "$2"
+ shift
+ ;;
+ esac
+ ;;
+ *.c)
+ cfile=$1
+ set x "$@" "$1"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+ # If no '-o' option was seen then we might have been invoked from a
+ # pattern rule where we don't need one. That is ok -- this is a
+ # normal compilation that the losing compiler can handle. If no
+ # '.c' file was seen then we are probably linking. That is also
+ # ok.
+ exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file. Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+ if mkdir "$lockdir" >/dev/null 2>&1; then
+ break
+ fi
+ sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+ test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+ test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+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-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/config.guess b/config.guess
index 850a1a48..4438cd70 100755
--- a/config.guess
+++ b/config.guess
@@ -1,10 +1,8 @@
#! /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, 2006 Free Software Foundation,
-# Inc.
+# Copyright 1992-2014 Free Software Foundation, Inc.
-timestamp='2006-07-02'
+timestamp='2014-01-01'
# 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
@@ -17,26 +15,22 @@ timestamp='2006-07-02'
# 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.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# 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.
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner.
#
-# 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.
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit build system type.
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+
me=`echo "$0" | sed -e 's,.*/,,'`
@@ -56,8 +50,7 @@ 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.
+Copyright 1992-2014 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."
@@ -139,12 +132,33 @@ 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
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+ ;;
+esac
+
# 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*,
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
@@ -161,6 +175,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
@@ -169,7 +184,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 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
+ | grep -q __ELF__
then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX?
@@ -179,7 +194,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
fi
;;
*)
- os=netbsd
+ os=netbsd
;;
esac
# The OS release
@@ -200,6 +215,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
@@ -222,7 +241,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
@@ -268,7 +287,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# 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 ;;
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
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
@@ -294,12 +316,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo s390-ibm-zvmoe
exit ;;
*:OS400:*:*)
- echo powerpc-ibm-os400
+ echo powerpc-ibm-os400
exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit ;;
- arm:riscos:*:*|arm:RISCOS:*:*)
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
echo arm-unknown-riscos
exit ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
@@ -323,14 +345,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
- i86pc:SunOS:5.*:*)
- echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
@@ -374,23 +415,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# 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}
+ echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
+ exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit ;;
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit ;;
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit ;;
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
m68k:machten:*:*)
echo m68k-apple-machten${UNAME_RELEASE}
exit ;;
@@ -460,8 +501,8 @@ EOF
echo m88k-motorola-sysv3
exit ;;
AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
+ # 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 ] || \
@@ -474,7 +515,7 @@ EOF
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
- exit ;;
+ exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit ;;
@@ -531,7 +572,7 @@ EOF
echo rs6000-ibm-aix3.2
fi
exit ;;
- *:AIX:*:[45])
+ *:AIX:*:[4567])
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
@@ -574,52 +615,52 @@ EOF
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" ;;
+ 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
+ esac ;;
+ esac
fi
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ sed 's/^ //' << EOF >$dummy.c
- #define _HPUX_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
+ #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);
+ 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);
- }
+ 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
@@ -639,7 +680,7 @@ EOF
# => hppa64-hp-hpux11.23
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
- grep __LP64__ >/dev/null
+ grep -q __LP64__
then
HP_ARCH="hppa2.0w"
else
@@ -710,22 +751,22 @@ EOF
exit ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
- exit ;;
+ exit ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
- exit ;;
+ exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
- exit ;;
+ exit ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
- exit ;;
+ exit ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
- exit ;;
+ exit ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
@@ -749,14 +790,14 @@ EOF
exit ;;
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 ;;
+ 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 ;;
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}"
+ 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 ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
@@ -768,37 +809,51 @@ EOF
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
- case ${UNAME_MACHINE} in
- pc98)
- echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
amd64)
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
*)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
esac
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
- i*:MINGW*:*)
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
+ *:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
+ i*:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
exit ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
- x86:Interix*:[3456]*)
- echo i586-pc-interix${UNAME_RELEASE}
- exit ;;
- EM64T:Interix*:[3456]*)
- echo x86_64-unknown-interix${UNAME_RELEASE}
- exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
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
@@ -819,200 +874,157 @@ EOF
exit ;;
*:GNU:*:*)
# the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit ;;
*: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
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ 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 -q ld.so.1
+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
arm*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ fi
+ fi
exit ;;
avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
cris:Linux:*:*)
- echo cris-axis-linux-gnu
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
crisv32:Linux:*:*)
- echo crisv32-axis-linux-gnu
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
frv:Linux:*:*)
- echo frv-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
exit ;;
ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
- 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 | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- mips64:Linux:*:*)
+ mips:Linux:*:* | mips64:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
- #undef mips64
- #undef mips64el
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mips64el
+ CPU=${UNAME_MACHINE}el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips64
+ CPU=${UNAME_MACHINE}
#else
CPU=
#endif
#endif
EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
;;
- or32:Linux:*:*)
- echo or32-unknown-linux-gnu
+ or1k:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
- ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
+ or32:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
- ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-${LIBC}
exit ;;
- 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}
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-${LIBC}
exit ;;
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 ;;
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
esac
exit ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
exit ;;
sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-gnu
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
exit ;;
x86_64:Linux:*:*)
- echo x86_64-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
- 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 ;;
- coff-i386)
- echo "${UNAME_MACHINE}-pc-linux-gnucoff"
- exit ;;
- "")
- # 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 ;;
- 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
- #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
- LIBC=gnu
- #else
- LIBC=gnuaout
- #endif
- #endif
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^LIBC/{
- s: ::g
- p
- }'`"
- test x"${LIBC}" != x && {
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
- exit
- }
- test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
- ;;
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
@@ -1020,11 +1032,11 @@ EOF
echo i386-sequent-sysv4
exit ;;
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,
+ # 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.
+ # Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit ;;
i*86:OS/2:*:*)
@@ -1041,7 +1053,7 @@ EOF
i*86:syllable:*:*)
echo ${UNAME_MACHINE}-pc-syllable
exit ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit ;;
i*86:*DOS:*:*)
@@ -1056,7 +1068,7 @@ EOF
fi
exit ;;
i*86:*:5:[678]*)
- # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
@@ -1084,10 +1096,13 @@ EOF
exit ;;
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 ;;
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit ;;
@@ -1122,8 +1137,18 @@ EOF
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4; exit; } ;;
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ 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; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit ;;
@@ -1136,7 +1161,7 @@ EOF
rs6000:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
echo powerpc-unknown-lynxos${UNAME_RELEASE}
exit ;;
SM[BE]S:UNIX_SV:*:*)
@@ -1156,10 +1181,10 @@ EOF
echo ns32k-sni-sysv
fi
exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- # says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
@@ -1185,11 +1210,11 @@ EOF
exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
+ echo mips-nec-sysv${UNAME_RELEASE}
else
- echo mips-unknown-sysv${UNAME_RELEASE}
+ echo mips-unknown-sysv${UNAME_RELEASE}
fi
- exit ;;
+ exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit ;;
@@ -1199,6 +1224,12 @@ EOF
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
@@ -1208,6 +1239,15 @@ EOF
SX-6:SUPER-UX:*:*)
echo sx6-nec-superux${UNAME_RELEASE}
exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit ;;
@@ -1216,9 +1256,31 @@ EOF
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- case $UNAME_PROCESSOR in
- unknown) UNAME_PROCESSOR=powerpc ;;
- esac
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
+ elif test "$UNAME_PROCESSOR" = i386 ; then
+ # Avoid executing cc on OS X 10.9, as it ships with a stub
+ # that puts up a graphical alert prompting to install
+ # developer tools. Any system running Mac OS X 10.7 or
+ # later (Darwin 11 and later) is required to have a 64-bit
+ # processor. This is not true of the ARM version of Darwin
+ # that Apple uses in portable devices.
+ UNAME_PROCESSOR=x86_64
+ fi
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
@@ -1232,7 +1294,10 @@ EOF
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
- NSE-?:NONSTOP_KERNEL:*:*)
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-*:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
NSR-?:NONSTOP_KERNEL:*:*)
@@ -1277,13 +1342,13 @@ EOF
echo pdp10-unknown-its
exit ;;
SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
+ echo mips-sei-seiux${UNAME_RELEASE}
exit ;;
*:DragonFly:*:*)
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
*:*VMS:*:*)
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
case "${UNAME_MACHINE}" in
A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;;
@@ -1298,11 +1363,14 @@ EOF
i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos
exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
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_
@@ -1320,11 +1388,11 @@ main ()
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
- "4"
+ "4"
#else
- ""
+ ""
#endif
- ); exit (0);
+ ); exit (0);
#endif
#endif
@@ -1458,9 +1526,9 @@ 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
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
and
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
If the version you run ($0) is already up to date, please
send the following data and any information you think might be
diff --git a/config.rpath b/config.rpath
index 17298f23..b625621f 100755
--- a/config.rpath
+++ b/config.rpath
@@ -2,7 +2,7 @@
# Output a system dependent set of variables, describing how to set the
# run time search path of shared libraries in an executable.
#
-# Copyright 1996-2010 Free Software Foundation, Inc.
+# Copyright 1996-2014 Free Software Foundation, Inc.
# Taken from GNU libtool, 2001
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
#
@@ -25,7 +25,7 @@
# 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 MSVC,
+# All known linkers require a '.a' archive for static linking (except MSVC,
# which needs '.lib').
libext=a
shrext=.so
@@ -57,13 +57,6 @@ else
aix*)
wl='-Wl,'
;;
- darwin*)
- case $cc_basename in
- xlc*)
- wl='-Wl,'
- ;;
- esac
- ;;
mingw* | cygwin* | pw32* | os2* | cegcc*)
;;
hpux9* | hpux10* | hpux11*)
@@ -72,9 +65,7 @@ else
irix5* | irix6* | nonstopux*)
wl='-Wl,'
;;
- newsos6)
- ;;
- linux* | k*bsd*-gnu)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
case $cc_basename in
ecc*)
wl='-Wl,'
@@ -85,17 +76,26 @@ else
lf95*)
wl='-Wl,'
;;
- pgcc | pgf77 | pgf90)
+ nagfor*)
+ wl='-Wl,-Wl,,'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
wl='-Wl,'
;;
ccc*)
wl='-Wl,'
;;
+ xl* | bgxl* | bgf* | mpixl*)
+ wl='-Wl,'
+ ;;
como)
wl='-lopt='
;;
*)
case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ F* | *Sun*Fortran*)
+ wl=
+ ;;
*Sun\ C*)
wl='-Wl,'
;;
@@ -103,13 +103,24 @@ else
;;
esac
;;
+ newsos6)
+ ;;
+ *nto* | *qnx*)
+ ;;
osf3* | osf4* | osf5*)
wl='-Wl,'
;;
rdos*)
;;
solaris*)
- wl='-Wl,'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ wl='-Qoption ld '
+ ;;
+ *)
+ wl='-Wl,'
+ ;;
+ esac
;;
sunos4*)
wl='-Qoption ld '
@@ -171,15 +182,14 @@ if test "$with_gnu_ld" = yes; then
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
+ case "$host_cpu" in
+ powerpc)
+ ;;
+ m68k)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
;;
beos*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
@@ -198,11 +208,13 @@ if test "$with_gnu_ld" = yes; then
ld_shlibs=no
fi
;;
+ haiku*)
+ ;;
interix[3-9]*)
hardcode_direct=no
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
- gnu* | linux* | k*bsd*-gnu)
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
@@ -325,10 +337,14 @@ else
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
+ case "$host_cpu" in
+ powerpc)
+ ;;
+ m68k)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
;;
bsdi[45]*)
;;
@@ -342,29 +358,16 @@ else
;;
darwin* | rhapsody*)
hardcode_direct=no
- if test "$GCC" = yes ; then
+ if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then
:
else
- case $cc_basename in
- xlc*)
- ;;
- *)
- ld_shlibs=no
- ;;
- esac
+ ld_shlibs=no
fi
;;
dgux*)
hardcode_libdir_flag_spec='-L$libdir'
;;
- freebsd1*)
- ld_shlibs=no
- ;;
- freebsd2.2*)
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- ;;
- freebsd2*)
+ freebsd2.[01]*)
hardcode_direct=yes
hardcode_minus_L=yes
;;
@@ -420,6 +423,8 @@ else
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
+ *nto* | *qnx*)
+ ;;
openbsd*)
if test -f /usr/libexec/ld.so; then
hardcode_direct=yes
@@ -515,7 +520,12 @@ case "$host_os" in
library_names_spec='$libname$shrext'
;;
amigaos*)
- library_names_spec='$libname.a'
+ case "$host_cpu" in
+ powerpc*)
+ library_names_spec='$libname$shrext' ;;
+ m68k)
+ library_names_spec='$libname.a' ;;
+ esac
;;
beos*)
library_names_spec='$libname$shrext'
@@ -534,19 +544,18 @@ case "$host_os" in
dgux*)
library_names_spec='$libname$shrext'
;;
- freebsd1*)
+ freebsd[23].*)
+ library_names_spec='$libname$shrext$versuffix'
;;
freebsd* | dragonfly*)
- case "$host_os" in
- freebsd[123]*)
- library_names_spec='$libname$shrext$versuffix' ;;
- *)
- library_names_spec='$libname$shrext' ;;
- esac
+ library_names_spec='$libname$shrext'
;;
gnu*)
library_names_spec='$libname$shrext'
;;
+ haiku*)
+ library_names_spec='$libname$shrext'
+ ;;
hpux9* | hpux10* | hpux11*)
case $host_cpu in
ia64*)
@@ -582,7 +591,7 @@ case "$host_os" in
;;
linux*oldld* | linux*aout* | linux*coff*)
;;
- linux* | k*bsd*-gnu)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
library_names_spec='$libname$shrext'
;;
knetbsd*-gnu)
@@ -594,7 +603,7 @@ case "$host_os" in
newsos6)
library_names_spec='$libname$shrext'
;;
- nto-qnx*)
+ *nto* | *qnx*)
library_names_spec='$libname$shrext'
;;
openbsd*)
@@ -625,6 +634,9 @@ case "$host_os" in
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
library_names_spec='$libname$shrext'
;;
+ tpf*)
+ library_names_spec='$libname$shrext'
+ ;;
uts4*)
library_names_spec='$libname$shrext'
;;
diff --git a/config.sub b/config.sub
index 38e508a5..092cff00 100755
--- a/config.sub
+++ b/config.sub
@@ -1,44 +1,40 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-# Inc.
+# Copyright 1992-2014 Free Software Foundation, Inc.
-timestamp='2006-09-20'
+timestamp='2014-01-01'
-# 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
+# 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 3 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.
+# 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.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# 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.
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
#
# 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.
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
# 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.
@@ -72,8 +68,7 @@ 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.
+Copyright 1992-2014 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."
@@ -120,12 +115,18 @@ esac
# 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-newlib* | linux-uclibc* | \
- uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
@@ -148,10 +149,13 @@ case $os in
-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)
+ -apple | -axis | -knuth | -cray | -microblaze*)
os=
basic_machine=$1
;;
+ -bluegene*)
+ os=-cnk
+ ;;
-sim | -cisco | -oki | -wec | -winbond)
os=
basic_machine=$1
@@ -166,10 +170,10 @@ case $os in
os=-chorusos
basic_machine=$1
;;
- -chorusrdb)
- os=-chorusrdb
+ -chorusrdb)
+ os=-chorusrdb
basic_machine=$1
- ;;
+ ;;
-hiux*)
os=-hiuxwe2
;;
@@ -214,6 +218,12 @@ case $os in
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
-lynx*)
os=-lynxos
;;
@@ -238,24 +248,35 @@ case $basic_machine in
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
+ | aarch64 | aarch64_be \
| 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 | avr32 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | be32 | be64 \
| bfin \
- | c4x | clipper \
+ | c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
- | fr30 | frv \
+ | epiphany \
+ | fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
+ | k1om \
+ | le32 | le64 \
+ | lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
- | maxq | mb | microblaze | mcore \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
- | mips64vr | mips64vrel \
+ | mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
@@ -266,31 +287,45 @@ case $basic_machine in
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
+ | moxie \
| mt \
| msp430 \
- | nios | nios2 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
- | or32 \
+ | open8 \
+ | or1k | or32 \
| pdp10 | pdp11 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
+ | rl78 | rx \
| score \
- | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | spu | strongarm \
- | tahoe | thumb | tic4x | tic80 | tron \
- | v850 | v850e \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| we32k \
- | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
- | z8k)
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
basic_machine=$basic_machine-unknown
;;
- m6811 | m68hc11 | m6812 | m68hc12)
- # Motorola 68HC11/12.
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
basic_machine=$basic_machine-unknown
os=-none
;;
@@ -300,6 +335,21 @@ case $basic_machine in
basic_machine=mt-unknown
;;
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
@@ -314,29 +364,38 @@ case $basic_machine in
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
+ | aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
+ | be32-* | be64-* \
| bfin-* | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
- | clipper-* | craynv-* | cydra-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
- | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
+ | k1om-* \
+ | le32-* | le64-* \
+ | lm32-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
- | mips64vr-* | mips64vrel-* \
+ | mips64octeon-* | mips64octeonel-* \
| mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
@@ -347,31 +406,41 @@ case $basic_machine in
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
- | nios-* | nios2-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| pyramid-* \
- | romp-* | rs6000-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
- | tahoe-* | thumb-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
| tron-* \
- | v850-* | v850e-* | vax-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
| we32k-* \
- | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
- | xstormy16-* | xtensa-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
| ymp-* \
- | z8k-*)
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -389,7 +458,7 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
- abacus)
+ abacus)
basic_machine=abacus-unknown
;;
adobe68k)
@@ -435,6 +504,10 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-bsd
;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
aux)
basic_machine=m68k-apple
os=-aux
@@ -443,10 +516,35 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
c90)
basic_machine=c90-cray
os=-unicos
;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -475,8 +573,8 @@ case $basic_machine in
basic_machine=craynv-cray
os=-unicosmp
;;
- cr16c)
- basic_machine=cr16c-unknown
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
os=-elf
;;
crds | unos)
@@ -514,6 +612,10 @@ case $basic_machine in
basic_machine=m88k-motorola
os=-sysv3
;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
@@ -629,7 +731,6 @@ case $basic_machine in
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
@@ -668,6 +769,14 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
m88k-omron*)
basic_machine=m88k-omron
;;
@@ -679,10 +788,21 @@ case $basic_machine in
basic_machine=ns32k-utek
os=-sysv
;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
mingw32)
- basic_machine=i386-pc
+ basic_machine=i686-pc
os=-mingw32
;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
miniframe)
basic_machine=m68000-convergent
;;
@@ -711,10 +831,18 @@ case $basic_machine in
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
+ msys)
+ basic_machine=i686-pc
+ os=-msys
+ ;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
@@ -779,6 +907,12 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
nsr-tandem)
basic_machine=nsr-tandem
;;
@@ -809,6 +943,14 @@ case $basic_machine in
basic_machine=i860-intel
os=-osf
;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
pbd)
basic_machine=sparc-tti
;;
@@ -853,9 +995,10 @@ case $basic_machine in
;;
power) basic_machine=power-ibm
;;
- ppc) basic_machine=powerpc-unknown
+ ppc | ppcbe) basic_machine=powerpc-unknown
;;
- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
@@ -880,7 +1023,11 @@ case $basic_machine in
basic_machine=i586-unknown
os=-pw32
;;
- rdos)
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
basic_machine=i386-pc
os=-rdos
;;
@@ -925,6 +1072,9 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
sh64)
basic_machine=sh64-unknown
;;
@@ -946,6 +1096,9 @@ case $basic_machine in
basic_machine=i860-stratus
os=-sysv4
;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
sun2)
basic_machine=m68000-sun
;;
@@ -1002,17 +1155,9 @@ case $basic_machine in
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
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
;;
tx39)
basic_machine=mipstx39-unknown
@@ -1081,6 +1226,9 @@ case $basic_machine in
xps | xps100)
basic_machine=xps100-honeywell
;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
ymp)
basic_machine=ymp-cray
os=-unicos
@@ -1089,6 +1237,10 @@ case $basic_machine in
basic_machine=z8k-unknown
os=-sim
;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
none)
basic_machine=none-none
os=-none
@@ -1127,7 +1279,7 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
- sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
@@ -1174,9 +1326,12 @@ esac
if [ x"$os" != x"" ]
then
case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
+ # First match some system type aliases
+ # that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
@@ -1197,21 +1352,23 @@ case $os in
# 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* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* \
+ | -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -openbsd* | -solidbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
| -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-newlib* | -linux-uclibc* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
@@ -1219,7 +1376,7 @@ case $os in
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers*)
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1258,7 +1415,7 @@ case $os in
-opened*)
os=-openedition
;;
- -os400*)
+ -os400*)
os=-os400
;;
-wince*)
@@ -1307,7 +1464,7 @@ case $os in
-sinix*)
os=-sysv4
;;
- -tpf*)
+ -tpf*)
os=-tpf
;;
-triton*)
@@ -1343,12 +1500,14 @@ case $os in
-aros*)
os=-aros
;;
- -kaos*)
- os=-kaos
- ;;
-zvmoe)
os=-zvmoe
;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
-none)
;;
*)
@@ -1371,10 +1530,10 @@ else
# system, and we'll never get to this point.
case $basic_machine in
- score-*)
+ score-*)
os=-elf
;;
- spu-*)
+ spu-*)
os=-elf
;;
*-acorn)
@@ -1386,8 +1545,23 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
- c4x-* | tic4x-*)
- os=-coff
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ c8051-*)
+ os=-elf
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
@@ -1407,19 +1581,22 @@ case $basic_machine in
;;
m68000-sun)
os=-sunos3
- # This also exists in the configure program, but was not the
- # default.
- # os=-sunos4
;;
m68*-cisco)
os=-aout
;;
+ mep-*)
+ os=-elf
+ ;;
mips*-cisco)
os=-elf
;;
mips*-*)
os=-elf
;;
+ or1k-*)
+ os=-elf
+ ;;
or32-*)
os=-coff
;;
@@ -1438,7 +1615,7 @@ case $basic_machine in
*-ibm)
os=-aix
;;
- *-knuth)
+ *-knuth)
os=-mmixware
;;
*-wec)
@@ -1543,7 +1720,7 @@ case $basic_machine in
-sunos*)
vendor=sun
;;
- -aix*)
+ -cnk*|-aix*)
vendor=ibm
;;
-beos*)
diff --git a/configh.in b/configh.in
index 5ab18321..301fa21a 100644
--- a/configh.in
+++ b/configh.in
@@ -42,9 +42,6 @@
*/
#undef HAVE_DECL_TZNAME
-/* 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
@@ -66,19 +63,18 @@
/* Define to 1 if you have the `grantpt' function. */
#undef HAVE_GRANTPT
+/* Do we have history_list? */
+#undef HAVE_HISTORY_LIST
+
/* Define if you have the iconv() function and it works. */
#undef HAVE_ICONV
-/* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */
+/* Define to 1 if the system has the type `intmax_t'. */
#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
@@ -115,9 +111,6 @@
/* 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 the system has the type `long long int'. */
#undef HAVE_LONG_LONG_INT
@@ -157,12 +150,18 @@
/* we have the mktime function */
#undef HAVE_MKTIME
+/* Define to 1 if you have fully functional mpfr and gmp libraries. */
+#undef HAVE_MPFR
+
/* 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 `posix_openpt' function. */
+#undef HAVE_POSIX_OPENPT
+
/* Define to 1 if you have the `setenv' function. */
#undef HAVE_SETENV
@@ -184,19 +183,21 @@
/* Define to 1 if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H
+/* Define to 1 if stdbool.h conforms to C99. */
+#undef HAVE_STDBOOL_H
+
/* Define to 1 if you have the <stddef.h> header file. */
#undef HAVE_STDDEF_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 `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
/* Define to 1 if you have the `strchr' function. */
#undef HAVE_STRCHR
@@ -236,10 +237,6 @@
/* Define to 1 if `tm_zone' is a 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
@@ -287,24 +284,18 @@
/* 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>. */
+/* Define to 1 if the system has the type `uintmax_t'. */
#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 the system has the type `unsigned long long int'. */
#undef HAVE_UNSIGNED_LONG_LONG_INT
/* Define to 1 if you have the `usleep' function. */
#undef HAVE_USLEEP
-/* 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
@@ -326,6 +317,12 @@
/* systems should define this type here */
#undef HAVE_WINT_T
+/* Define to 1 if the system has the type `_Bool'. */
+#undef HAVE__BOOL
+
+/* enable severe portability problems */
+#undef I_DONT_KNOW_WHAT_IM_DOING
+
/* disable lint checks */
#undef NO_LINT
@@ -402,6 +399,11 @@
/* Version number of package */
#undef VERSION
+/* Enable large inode numbers on Mac OS X 10.5. */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
@@ -411,6 +413,19 @@
/* Define to 1 if on MINIX. */
#undef _MINIX
+/* The _Noreturn keyword of C11. */
+#ifndef _Noreturn
+# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \
+ || 0x5110 <= __SUNPRO_C)
+# define _Noreturn __attribute__ ((__noreturn__))
+# elif defined _MSC_VER && 1200 <= _MSC_VER
+# define _Noreturn __declspec (noreturn)
+# else
+# define _Noreturn
+# endif
+#endif
+
+
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
#undef _POSIX_1_SOURCE
@@ -435,7 +450,8 @@
#undef inline
#endif
-/* Define to long or long long if <inttypes.h> and <stdint.h> don't define. */
+/* Define to the widest signed integer type if <stdint.h> and <inttypes.h> do
+ not define. */
#undef intmax_t
/* Define to `int' if <sys/types.h> does not define. */
@@ -467,8 +483,8 @@
/* 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 to the widest unsigned integer type if <stdint.h> and <inttypes.h>
+ do not define. */
#undef uintmax_t
#include "custom.h"
diff --git a/configure b/configure
index 9f916cf0..93862b34 100755
--- a/configure
+++ b/configure
@@ -1,13 +1,11 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for GNU Awk 4.0.70.
+# Generated by GNU Autoconf 2.69 for GNU Awk 4.1.60.
#
# Report bugs to <bug-gawk@gnu.org>.
#
#
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
@@ -136,6 +134,31 @@ export LANGUAGE
# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then
as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
@@ -169,7 +192,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
else
exitcode=1; echo positional parameters were not saved.
fi
-test x\$exitcode = x0 || exit 1"
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
@@ -214,21 +238,25 @@ IFS=$as_save_IFS
if test "x$CONFIG_SHELL" != x; then :
- # We cannot yet assume a decent shell, so we have to provide a
- # neutralization value for shells without unset; and this also
- # works around shells that cannot unset nonexistent variables.
- # Preserve -v and -x to the replacement shell.
- BASH_ENV=/dev/null
- ENV=/dev/null
- (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
- export CONFIG_SHELL
- case $- in # ((((
- *v*x* | *x*v* ) as_opts=-vx ;;
- *v* ) as_opts=-v ;;
- *x* ) as_opts=-x ;;
- * ) as_opts= ;;
- esac
- exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
fi
if test x$as_have_required = xno; then :
@@ -331,6 +359,14 @@ $as_echo X"$as_dir" |
} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
@@ -452,6 +488,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
chmod +x "$as_me.lineno" ||
{ $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
# 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 sensitive to this).
@@ -486,16 +526,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -507,28 +547,8 @@ else
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# 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'"
@@ -560,8 +580,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='GNU Awk'
PACKAGE_TARNAME='gawk'
-PACKAGE_VERSION='4.0.70'
-PACKAGE_STRING='GNU Awk 4.0.70'
+PACKAGE_VERSION='4.1.60'
+PACKAGE_STRING='GNU Awk 4.1.60'
PACKAGE_BUGREPORT='bug-gawk@gnu.org'
PACKAGE_URL='http://www.gnu.org/software/gawk/'
@@ -604,9 +624,13 @@ ac_includes_default="\
gt_needs=
ac_header_list=
ac_func_list=
+enable_option_checking=no
ac_subst_vars='am__EXEEXT_FALSE
am__EXEEXT_TRUE
LTLIBOBJS
+subdirs
+GAWKLIBEXT
+LIBMPFR
LIBREADLINE
SOCKET_LIBS
LIBSIGSEGV_PREFIX
@@ -614,6 +638,8 @@ LTLIBSIGSEGV
LIBSIGSEGV
HAVE_LIBSIGSEGV
LIBOBJS
+TEST_CROSS_COMPILE_FALSE
+TEST_CROSS_COMPILE_TRUE
POSUB
LTLIBINTL
LIBINTL
@@ -621,14 +647,6 @@ INTLLIBS
LTLIBICONV
LIBICONV
INTL_MACOSX_LIBS
-host_os
-host_vendor
-host_cpu
-host
-build_os
-build_vendor
-build_cpu
-build
XGETTEXT_EXTRA_OPTIONS
MSGMERGE
XGETTEXT_015
@@ -639,6 +657,9 @@ GMSGFMT
MSGFMT
GETTEXT_MACRO_VERSION
USE_NLS
+SED
+pkgextensiondir
+acl_shlibext
LN_S
YFLAGS
YACC
@@ -648,6 +669,7 @@ CPP
am__fastdepCC_FALSE
am__fastdepCC_TRUE
CCDEPMODE
+am__nodep
AMDEPBACKSLASH
AMDEP_FALSE
AMDEP_TRUE
@@ -661,6 +683,18 @@ CPPFLAGS
LDFLAGS
CFLAGS
CC
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
am__untar
am__tar
AMTAR
@@ -725,8 +759,10 @@ SHELL'
ac_subst_files=''
ac_user_opts='
enable_option_checking
+enable_silent_rules
with_whiny_user_strftime
enable_lint
+enable_severe_portability_problems
enable_dependency_tracking
enable_largefile
enable_nls
@@ -735,7 +771,9 @@ enable_rpath
with_libiconv_prefix
with_libintl_prefix
with_libsigsegv_prefix
+enable_extensions
with_readline
+with_mpfr
'
ac_precious_vars='build_alias
host_alias
@@ -748,7 +786,7 @@ CPPFLAGS
CPP
YACC
YFLAGS'
-
+ac_subdirs_all='extension'
# Initialize some variables set by options.
ac_init_help=
@@ -1203,8 +1241,6 @@ target=$target_alias
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
cross_compiling=maybe
- $as_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
@@ -1290,7 +1326,7 @@ 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 4.0.70 to adapt to many kinds of systems.
+\`configure' configures GNU Awk 4.1.60 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1360,7 +1396,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of GNU Awk 4.0.70:";;
+ short | recursive ) echo "Configuration of GNU Awk 4.1.60:";;
esac
cat <<\_ACEOF
@@ -1368,18 +1404,24 @@ Optional Features:
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-silent-rules less verbose build output (undo: "make V=1")
+ --disable-silent-rules verbose build output (undo: "make V=0")
--disable-lint Disable gawk lint checking
- --disable-dependency-tracking speeds up one-time build
- --enable-dependency-tracking do not reject slow dependency extractors
+ --enable-severe-portability-problems Enable really nasty portability problems
+ --enable-dependency-tracking
+ do not reject slow dependency extractors
+ --disable-dependency-tracking
+ speeds up one-time build
--disable-largefile omit support for large files
--disable-nls do not use Native Language Support
--disable-rpath do not hardcode runtime library paths
+ --disable-extensions disable dynamic extensions (default is detect)
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-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
@@ -1387,6 +1429,7 @@ Optional Packages:
--with-libsigsegv-prefix[=DIR] search for libsigsegv in DIR/include and DIR/lib
--without-libsigsegv-prefix don't search for libsigsegv in includedir and libdir
--with-readline=DIR look for the readline library in DIR
+ --with-mpfr=DIR look for the mpfr and gmp libraries in DIR
Some influential environment variables:
CC C compiler command
@@ -1472,10 +1515,10 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-GNU Awk configure 4.0.70
-generated by GNU Autoconf 2.68
+GNU Awk configure 4.1.60
+generated by GNU Autoconf 2.69
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
@@ -1752,7 +1795,7 @@ $as_echo "$ac_try_echo"; } >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
+ test -x conftest$ac_exeext
}; then :
ac_retval=0
else
@@ -1842,7 +1885,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) >= 0)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -1858,7 +1902,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -1884,7 +1929,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) < 0)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -1900,7 +1946,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) >= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -1934,7 +1981,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -2176,8 +2224,8 @@ cat >config.log <<_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 4.0.70, which was
-generated by GNU Autoconf 2.68. Invocation command line was
+It was created by GNU Awk $as_me 4.1.60, which was
+generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2544,7 +2592,7 @@ then
fi
-am__api_version='1.11'
+am__api_version='1.14'
ac_aux_dir=
for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
@@ -2612,7 +2660,7 @@ case $as_dir/ in #((
# by default.
for ac_prog in ginstall scoinst install; do
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if as_fn_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.
@@ -2670,9 +2718,6 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
$as_echo_n "checking whether build environment is sane... " >&6; }
-# Just in case
-sleep 1
-echo timestamp > conftest.file
# Reject unsafe characters in $srcdir or the absolute working directory
# name. Accept space and tab only in the latter.
am_lf='
@@ -2683,32 +2728,40 @@ case `pwd` in
esac
case $srcdir in
*[\\\"\#\$\&\'\`$am_lf\ \ ]*)
- as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+ as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
esac
-# Do `set' in a subshell so we don't clobber the current shell's
+# 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".
- as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
-alias in your environment" "$LINENO" 5
- fi
-
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ 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
+ 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".
+ as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
+ alias in your environment" "$LINENO" 5
+ fi
+ if test "$2" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
test "$2" = conftest.file
)
then
@@ -2720,6 +2773,16 @@ Check your system clock" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
test "$program_prefix" != NONE &&
program_transform_name="s&^&$program_prefix&;$program_transform_name"
# Use a double $ so make ignores it.
@@ -2742,12 +2805,12 @@ if test x"${MISSING+set}" != xset; then
esac
fi
# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
else
am_missing_run=
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
-$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
fi
if test x"${install_sh}" != xset; then
@@ -2759,10 +2822,10 @@ if test x"${install_sh}" != xset; then
esac
fi
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'. However `strip' might not be the right
+# 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.
+# 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.
@@ -2781,7 +2844,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_STRIP="${ac_tool_prefix}strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -2821,7 +2884,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_STRIP="strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -2872,7 +2935,7 @@ do
test -z "$as_dir" && as_dir=.
for ac_prog in mkdir gmkdir; do
for ac_exec_ext in '' $ac_executable_extensions; do
- { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
'mkdir (GNU coreutils) '* | \
'mkdir (coreutils) '* | \
@@ -2901,12 +2964,6 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
$as_echo "$MKDIR_P" >&6; }
-mkdir_p="$MKDIR_P"
-case $mkdir_p in
- [\\/$]* | ?:[\\/]*) ;;
- */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-
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.
@@ -2925,7 +2982,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AWK="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -2989,6 +3046,45 @@ else
fi
rmdir .tst 2>/dev/null
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
if test "`cd $srcdir && pwd`" != "`pwd`"; then
# Use -I$(srcdir) only when $(srcdir) != ., so that make's output
# is not polluted with repeated "-I."
@@ -3011,7 +3107,7 @@ fi
# Define the identity of the package.
PACKAGE='gawk'
- VERSION='4.0.70'
+ VERSION='4.1.60'
cat >>confdefs.h <<_ACEOF
@@ -3039,19 +3135,71 @@ AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
-# Always define AMTAR for backward compatibility.
+# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
-AMTAR=${AMTAR-"${am_missing_run}tar"}
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar pax cpio none'
-am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+ fi
+fi
+
@@ -3077,6 +3225,88 @@ $as_echo "#define NO_LINT 1" >>confdefs.h
fi
+# Check whether --enable-severe-portability-problems was given.
+if test "${enable_severe_portability_problems+set}" = set; then :
+ enableval=$enable_severe_portability_problems; if test "$enableval" = yes
+ then
+
+$as_echo "#define I_DONT_KNOW_WHAT_IM_DOING 1" >>confdefs.h
+
+ fi
+
+fi
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
DEPDIR="${am__leading_dot}deps"
@@ -3097,7 +3327,7 @@ am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
+# Ignore all kinds of additional output from 'make'.
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=include
@@ -3130,6 +3360,7 @@ fi
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
+ am__nodep='_no'
fi
if test "x$enable_dependency_tracking" != xno; then
AMDEP_TRUE=
@@ -3162,7 +3393,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3202,7 +3433,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3255,7 +3486,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}cc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3296,7 +3527,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_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
@@ -3354,7 +3585,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3398,7 +3629,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3844,8 +4075,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdarg.h>
#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+struct stat;
/* 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);
@@ -3930,6 +4160,65 @@ 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
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+ ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+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
+
+
depcc="$CC" am_compiler_list=
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
@@ -3941,8 +4230,9 @@ else
# 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'.
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
@@ -3976,16 +4266,16 @@ else
: > 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
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
done
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # 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. Also, some Intel
- # versions had trouble with output in subdirs
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
am__obj=sub/conftest.${OBJEXT-o}
am__minus_obj="-o $am__obj"
case $depmode in
@@ -3994,16 +4284,16 @@ else
test "$am__universal" = false || continue
;;
nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
+ # 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
;;
- msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
am__obj=conftest.${OBJEXT-o}
@@ -4212,7 +4502,7 @@ do
for ac_prog in grep ggrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+ as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found.
# Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in
@@ -4278,7 +4568,7 @@ do
for ac_prog in egrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+ as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found.
# Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in
@@ -4485,8 +4775,8 @@ else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-# define __EXTENSIONS__ 1
- $ac_includes_default
+# define __EXTENSIONS__ 1
+ $ac_includes_default
int
main ()
{
@@ -4536,7 +4826,7 @@ do
for ac_prog in egrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+ as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found.
# Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in
@@ -4602,7 +4892,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_YACC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4660,7 +4950,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4700,7 +4990,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4753,7 +5043,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}cc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4794,7 +5084,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_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
@@ -4852,7 +5142,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4896,7 +5186,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5092,8 +5382,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdarg.h>
#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+struct stat;
/* 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);
@@ -5178,6 +5467,65 @@ 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
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+ ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+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
+
+
depcc="$CC" am_compiler_list=
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
@@ -5189,8 +5537,9 @@ else
# 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'.
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
@@ -5224,16 +5573,16 @@ else
: > 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
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
done
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # 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. Also, some Intel
- # versions had trouble with output in subdirs
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
am__obj=sub/conftest.${OBJEXT-o}
am__minus_obj="-o $am__obj"
case $depmode in
@@ -5242,16 +5591,16 @@ else
test "$am__universal" = false || continue
;;
nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
+ # 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
;;
- msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
am__obj=conftest.${OBJEXT-o}
@@ -5486,7 +5835,7 @@ $as_echo_n "checking for special development options... " >&6; }
if test -f $srcdir/.developing
then
# add other debug flags as appropriate, save GAWKDEBUG for emergencies
- CFLAGS="$CFLAGS -DARRAYDEBUG"
+ CFLAGS="$CFLAGS -DARRAYDEBUG -DYYDEBUG -DLOCALEDEBUG"
if grep dbug $srcdir/.developing
then
CFLAGS="$CFLAGS -DDBUG"
@@ -5496,17 +5845,24 @@ then
# enable debugging using macros also
if test "$GCC" = yes
then
- CFLAGS="$CFLAGS -Wall"
+ CFLAGS="$CFLAGS -Wall -fno-builtin -g3"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
+ CFLAGS="$CFLAGS -DNDEBUG" # turn off assertions
fi
+# shared library suffix for dynamic loading:
+
+# default shared library location
+pkgextensiondir='${pkglibdir}'
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for z/OS USS compilation" >&5
$as_echo_n "checking for z/OS USS compilation... " >&6; }
@@ -5761,6 +6117,8 @@ _ACEOF
esac
rm -rf conftest*
fi
+
+
fi
@@ -5821,15 +6179,75 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu
-case `(uname) 2> /dev/null` in
-*CYGWIN*)
- with_libiconv_prefix=no
- with_libintl_prefix=no
- ;;
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ 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_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
*)
- ;;
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
esac
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5
$as_echo_n "checking whether NLS is requested... " >&6; }
@@ -5846,7 +6264,7 @@ $as_echo "$USE_NLS" >&6; }
- GETTEXT_MACRO_VERSION=0.18
+ GETTEXT_MACRO_VERSION=0.19
@@ -5854,15 +6272,14 @@ $as_echo "$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
+ # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which
+ # contains only /bin. Note that ksh looks also at the FPATH variable,
+ # so we have to set that as well for the test.
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
+ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
+ || PATH_SEPARATOR=';'
+ }
fi
# Find out how to test for executable files. Don't use a zero-byte file,
@@ -5938,7 +6355,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5977,15 +6394,14 @@ 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
+ # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which
+ # contains only /bin. Note that ksh looks also at the FPATH variable,
+ # so we have to set that as well for the test.
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
+ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
+ || PATH_SEPARATOR=';'
+ }
fi
# Find out how to test for executable files. Don't use a zero-byte file,
@@ -6055,15 +6471,14 @@ 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
+ # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which
+ # contains only /bin. Note that ksh looks also at the FPATH variable,
+ # so we have to set that as well for the test.
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
+ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
+ || PATH_SEPARATOR=';'
+ }
fi
# Find out how to test for executable files. Don't use a zero-byte file,
@@ -6146,76 +6561,6 @@ fi
eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
prefix="$acl_save_prefix"
-# Make sure we can run config.sub.
-$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
- as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
-$as_echo_n "checking build system type... " >&6; }
-if ${ac_cv_build+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_build_alias=$build_alias
-test "x$ac_build_alias" = x &&
- ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
-test "x$ac_build_alias" = x &&
- as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
-ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
- as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
-$as_echo "$ac_cv_build" >&6; }
-case $ac_cv_build in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
-esac
-build=$ac_cv_build
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_build
-shift
-build_cpu=$1
-build_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-build_os=$*
-IFS=$ac_save_IFS
-case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
-$as_echo_n "checking host system type... " >&6; }
-if ${ac_cv_host+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test "x$host_alias" = x; then
- ac_cv_host=$ac_cv_build
-else
- ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
- as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
-$as_echo "$ac_cv_host" >&6; }
-case $ac_cv_host in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
-esac
-host=$ac_cv_host
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_host
-shift
-host_cpu=$1
-host_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-host_os=$*
-IFS=$ac_save_IFS
-case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
-
# Check whether --with-gnu-ld was given.
@@ -6228,21 +6573,21 @@ 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
+ # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which
+ # contains only /bin. Note that ksh looks also at the FPATH variable,
+ # so we have to set that as well for the test.
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
+ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
+ || PATH_SEPARATOR=';'
+ }
fi
+
ac_prog=ld
if test "$GCC" = yes; then
# Check if gcc -print-prog-name=ld gives a path.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by GCC" >&5
-$as_echo_n "checking for ld used by GCC... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
case $host in
*-*-mingw*)
# gcc leaves a trailing carriage return which upsets mingw
@@ -6252,11 +6597,11 @@ $as_echo_n "checking for ld used by GCC... " >&6; }
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
+ # Canonicalize the pathname 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"
@@ -6281,23 +6626,26 @@ if ${acl_cv_path_LD+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -z "$LD"; then
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
for ac_dir in $PATH; do
+ IFS="$acl_save_ifs"
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.
+ # but apparently some variants of GNU ld 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
+ case `"$acl_cv_path_LD" -v 2>&1 </dev/null` in
*GNU* | *'with BFD'*)
- test "$with_gnu_ld" != no && break ;;
+ test "$with_gnu_ld" != no && break
+ ;;
*)
- test "$with_gnu_ld" != yes && break ;;
+ test "$with_gnu_ld" != yes && break
+ ;;
esac
fi
done
- IFS="$ac_save_ifs"
+ IFS="$acl_save_ifs"
else
acl_cv_path_LD="$LD" # Let the user override the test with a path.
fi
@@ -6317,12 +6665,14 @@ $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
if ${acl_cv_prog_gnu_ld+:} false; then :
$as_echo_n "(cached) " >&6
else
- # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+ # I'd rather use --version here, but apparently some GNU lds 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=yes
+ ;;
*)
- acl_cv_prog_gnu_ld=no ;;
+ acl_cv_prog_gnu_ld=no
+ ;;
esac
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_prog_gnu_ld" >&5
@@ -6505,7 +6855,7 @@ fi
done
if test -z "$already_handled"; then
names_already_handled="$names_already_handled $name"
- uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
+ uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'`
eval value=\"\$HAVE_LIB$uppername\"
if test -n "$value"; then
if test "$value" = yes; then
@@ -7034,15 +7384,19 @@ if eval \${$gt_func_gnugettext_libc+:} false; then :
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
+
#include <libintl.h>
$gt_revision_test_code
extern int _nl_msg_cat_cntr;
extern int *_nl_domain_bindings;
+
int
main ()
{
+
bindtextdomain ("", "");
return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings
+
;
return 0;
}
@@ -7100,14 +7454,16 @@ else
am_cv_lib_iconv=no
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* 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);
+ iconv(cd,NULL,NULL,NULL,NULL);
+ iconv_close(cd);
;
return 0;
}
@@ -7122,14 +7478,16 @@ rm -f core conftest.err conftest.$ac_objext \
LIBS="$LIBS $LIBICONV"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* 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);
+ iconv(cd,NULL,NULL,NULL,NULL);
+ iconv_close(cd);
;
return 0;
}
@@ -7153,15 +7511,17 @@ if ${am_cv_func_iconv_works+:} false; then :
$as_echo_n "(cached) " >&6
else
- am_save_LIBS="$LIBS"
+ am_save_LIBS="$LIBS"
if test $am_cv_lib_iconv = yes; then
LIBS="$LIBS $LIBICONV"
fi
if test "$cross_compiling" = yes; then :
- case "$host_os" in
+
+ case "$host_os" in
aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
*) am_cv_func_iconv_works="guessing yes" ;;
esac
+
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -7170,6 +7530,7 @@ else
#include <string.h>
int main ()
{
+ int result = 0;
/* Test against AIX 5.1 bug: Failures are not distinguishable from successful
returns. */
{
@@ -7186,7 +7547,8 @@ int main ()
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res == 0)
- return 1;
+ result |= 1;
+ iconv_close (cd_utf8_to_88591);
}
}
/* Test against Solaris 10 bug: Failures are not distinguishable from
@@ -7205,7 +7567,27 @@ int main ()
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res == 0)
- return 1;
+ result |= 2;
+ iconv_close (cd_ascii_to_88591);
+ }
+ }
+ /* Test against AIX 6.1..7.1 bug: Buffer overrun. */
+ {
+ iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
+ if (cd_88591_to_utf8 != (iconv_t)(-1))
+ {
+ static const char input[] = "\304";
+ static char buf[2] = { (char)0xDE, (char)0xAD };
+ const char *inptr = input;
+ size_t inbytesleft = 1;
+ char *outptr = buf;
+ size_t outbytesleft = 1;
+ size_t res = iconv (cd_88591_to_utf8,
+ (char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD)
+ result |= 4;
+ iconv_close (cd_88591_to_utf8);
}
}
#if 0 /* This bug could be worked around by the caller. */
@@ -7224,7 +7606,8 @@ int main ()
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
if ((int)res > 0)
- return 1;
+ result |= 8;
+ iconv_close (cd_88591_to_utf8);
}
}
#endif
@@ -7238,8 +7621,8 @@ int main ()
&& iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
/* Try HP-UX names. */
&& iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
- return 1;
- return 0;
+ result |= 16;
+ return result;
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
@@ -7356,7 +7739,7 @@ fi
done
if test -z "$already_handled"; then
names_already_handled="$names_already_handled $name"
- uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
+ uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'`
eval value=\"\$HAVE_LIB$uppername\"
if test -n "$value"; then
if test "$value" = yes; then
@@ -7754,6 +8137,7 @@ else
LIBS="$LIBS $LIBINTL"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
+
#include <libintl.h>
$gt_revision_test_code
extern int _nl_msg_cat_cntr;
@@ -7762,11 +8146,14 @@ extern
"C"
#endif
const char *_nl_expand_alias (const char *);
+
int
main ()
{
+
bindtextdomain ("", "");
return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")
+
;
return 0;
}
@@ -7782,6 +8169,7 @@ rm -f core conftest.err conftest.$ac_objext \
LIBS="$LIBS $LIBICONV"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
+
#include <libintl.h>
$gt_revision_test_code
extern int _nl_msg_cat_cntr;
@@ -7790,19 +8178,22 @@ extern
"C"
#endif
const char *_nl_expand_alias (const char *);
+
int
main ()
{
+
bindtextdomain ("", "");
return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")
+
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
LIBINTL="$LIBINTL $LIBICONV"
- LTLIBINTL="$LTLIBINTL $LTLIBICONV"
- eval "$gt_func_gnugettext_libintl=yes"
+ LTLIBINTL="$LTLIBINTL $LTLIBICONV"
+ eval "$gt_func_gnugettext_libintl=yes"
fi
rm -f core conftest.err conftest.$ac_objext \
@@ -7989,6 +8380,22 @@ $as_echo "#define HAVE_LC_MESSAGES 1" >>confdefs.h
fi
+for ac_header in arpa/inet.h fcntl.h limits.h locale.h libintl.h mcheck.h \
+ netdb.h netinet/in.h stdarg.h stddef.h string.h \
+ sys/ioctl.h sys/param.h sys/socket.h sys/time.h unistd.h \
+ termios.h stropts.h wchar.h wctype.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
$as_echo_n "checking for ANSI C header files... " >&6; }
if ${ac_cv_header_stdc+:} false; then :
@@ -8101,6 +8508,99 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
+$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
+if ${ac_cv_header_stdbool_h+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <stdbool.h>
+ #ifndef bool
+ "error: bool is not defined"
+ #endif
+ #ifndef false
+ "error: false is not defined"
+ #endif
+ #if false
+ "error: false is not 0"
+ #endif
+ #ifndef true
+ "error: true is not defined"
+ #endif
+ #if true != 1
+ "error: true is not 1"
+ #endif
+ #ifndef __bool_true_false_are_defined
+ "error: __bool_true_false_are_defined is not defined"
+ #endif
+
+ struct s { _Bool s: 1; _Bool t; } s;
+
+ char a[true == 1 ? 1 : -1];
+ char b[false == 0 ? 1 : -1];
+ char c[__bool_true_false_are_defined == 1 ? 1 : -1];
+ char d[(bool) 0.5 == true ? 1 : -1];
+ /* See body of main program for 'e'. */
+ char f[(_Bool) 0.0 == false ? 1 : -1];
+ char g[true];
+ char h[sizeof (_Bool)];
+ char i[sizeof s.t];
+ enum { j = false, k = true, l = false * true, m = true * 256 };
+ /* The following fails for
+ HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
+ _Bool n[m];
+ char o[sizeof n == m * sizeof n[0] ? 1 : -1];
+ char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
+ /* Catch a bug in an HP-UX C compiler. See
+ http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
+ http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
+ */
+ _Bool q = true;
+ _Bool *pq = &q;
+
+int
+main ()
+{
+
+ bool e = &s;
+ *pq |= q;
+ *pq |= ! q;
+ /* Refer to every declared value, to avoid compiler optimizations. */
+ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
+ + !m + !n + !o + !p + !q + !pq);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdbool_h=yes
+else
+ ac_cv_header_stdbool_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5
+$as_echo "$ac_cv_header_stdbool_h" >&6; }
+ ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default"
+if test "x$ac_cv_type__Bool" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE__BOOL 1
+_ACEOF
+
+
+fi
+
+
+if test $ac_cv_header_stdbool_h = yes; then
+
+$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
+
+fi
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5
$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; }
if ${ac_cv_header_sys_wait_h+:} false; then :
@@ -8177,22 +8677,6 @@ $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
fi
-for ac_header in arpa/inet.h fcntl.h limits.h locale.h libintl.h mcheck.h \
- netdb.h netinet/in.h stdarg.h stddef.h string.h \
- sys/ioctl.h sys/param.h sys/socket.h sys/time.h unistd.h \
- termios.h stropts.h wchar.h wctype.h
-do :
- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
if test "$ac_cv_header_string_h" = yes
then
@@ -8223,6 +8707,15 @@ done
fi
+ if test "x$build_alias" != "x$host_alias"; then
+ TEST_CROSS_COMPILE_TRUE=
+ TEST_CROSS_COMPILE_FALSE='#'
+else
+ TEST_CROSS_COMPILE_TRUE='#'
+ TEST_CROSS_COMPILE_FALSE=
+fi
+
+
ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
if test "x$ac_cv_type_pid_t" = xyes; then :
@@ -8383,25 +8876,76 @@ if ${ac_cv_type_long_long_int+:} false; then :
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-long long int ll = 9223372036854775807ll;
- long long int nll = -9223372036854775807LL;
- typedef int a[((-9223372036854775807LL < 0
- && 0 < 9223372036854775807ll)
- ? 1 : -1)];
- int i = 63;
+
+ /* For now, do not test the preprocessor; as of 2007 there are too many
+ implementations with broken preprocessors. Perhaps this can
+ be revisited in 2012. In the meantime, code should not expect
+ #if to work with literals wider than 32 bits. */
+ /* Test literals. */
+ long long int ll = 9223372036854775807ll;
+ long long int nll = -9223372036854775807LL;
+ unsigned long long int ull = 18446744073709551615ULL;
+ /* Test constant expressions. */
+ typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
+ ? 1 : -1)];
+ typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
+ ? 1 : -1)];
+ int i = 63;
int
main ()
{
-long long int llmax = 9223372036854775807ll;
- return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
- | (llmax / ll) | (llmax % ll));
+/* Test availability of runtime routines for shift and division. */
+ long long int llmax = 9223372036854775807ll;
+ unsigned long long int ullmax = 18446744073709551615ull;
+ return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
+ | (llmax / ll) | (llmax % ll)
+ | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
+ | (ullmax / ull) | (ullmax % ull));
;
return 0;
}
+
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
+ if test "$cross_compiling" = yes; then :
ac_cv_type_long_long_int=yes
else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+ #ifndef LLONG_MAX
+ # define HALF \
+ (1LL << (sizeof (long long int) * CHAR_BIT - 2))
+ # define LLONG_MAX (HALF - 1 + HALF)
+ #endif
+int
+main ()
+{
+long long int n = 1;
+ int i;
+ for (i = 0; ; i++)
+ {
+ long long int m = n << i;
+ if (m >> i != n)
+ return 1;
+ if (LLONG_MAX / 2 < m)
+ break;
+ }
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_type_long_long_int=yes
+else
+ ac_cv_type_long_long_int=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+else
ac_cv_type_long_long_int=no
fi
rm -f core conftest.err conftest.$ac_objext \
@@ -8416,15 +8960,6 @@ $as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h
fi
-
- ac_cv_type_long_long=$ac_cv_type_long_long_int
- if test $ac_cv_type_long_long = yes; then
-
-$as_echo "#define HAVE_LONG_LONG 1" >>confdefs.h
-
- fi
-
-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5
$as_echo_n "checking for unsigned long long int... " >&6; }
if ${ac_cv_type_unsigned_long_long_int+:} false; then :
@@ -8464,130 +8999,41 @@ $as_echo "#define HAVE_UNSIGNED_LONG_LONG_INT 1" >>confdefs.h
- ac_cv_type_unsigned_long_long=$ac_cv_type_unsigned_long_long_int
- if test $ac_cv_type_unsigned_long_long = yes; then
-
-$as_echo "#define HAVE_UNSIGNED_LONG_LONG 1" >>confdefs.h
-
- fi
-
-
- if test "OS/390" = "`uname`"
- then
- gl_cv_header_inttypes_h=no
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inttypes.h" >&5
-$as_echo_n "checking for inttypes.h... " >&6; }
-if ${gl_cv_header_inttypes_h+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <inttypes.h>
-int
-main ()
-{
-uintmax_t i = (uintmax_t) -1; return !i;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- gl_cv_header_inttypes_h=yes
-else
- gl_cv_header_inttypes_h=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_inttypes_h" >&5
-$as_echo "$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
- fi
+ ac_fn_c_check_type "$LINENO" "intmax_t" "ac_cv_type_intmax_t" "$ac_includes_default"
+if test "x$ac_cv_type_intmax_t" = xyes; then :
+$as_echo "#define HAVE_INTMAX_T 1" >>confdefs.h
- if test "OS/390" = "`uname`"
- then
- gl_cv_header_stdint_h=no
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint.h" >&5
-$as_echo_n "checking for stdint.h... " >&6; }
-if ${gl_cv_header_stdint_h+:} false; then :
- $as_echo_n "(cached) " >&6
else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <stdint.h>
-int
-main ()
-{
-uintmax_t i = (uintmax_t) -1; return !i;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- gl_cv_header_stdint_h=yes
-else
- gl_cv_header_stdint_h=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_stdint_h" >&5
-$as_echo "$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
- 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'
+ test $ac_cv_type_long_long_int = yes \
+ && ac_type='long long int' \
+ || ac_type='long int'
cat >>confdefs.h <<_ACEOF
#define intmax_t $ac_type
_ACEOF
- else
-
-$as_echo "#define HAVE_INTMAX_T 1" >>confdefs.h
+fi
- fi
+ ac_fn_c_check_type "$LINENO" "uintmax_t" "ac_cv_type_uintmax_t" "$ac_includes_default"
+if test "x$ac_cv_type_uintmax_t" = xyes; then :
- if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then
+$as_echo "#define HAVE_UINTMAX_T 1" >>confdefs.h
- test $ac_cv_type_unsigned_long_long = yes \
- && ac_type='unsigned long long' \
- || ac_type='unsigned long'
+else
+ test $ac_cv_type_unsigned_long_long_int = yes \
+ && ac_type='unsigned long long int' \
+ || ac_type='unsigned long int'
cat >>confdefs.h <<_ACEOF
#define uintmax_t $ac_type
_ACEOF
- else
-
-$as_echo "#define HAVE_UINTMAX_T 1" >>confdefs.h
+fi
- fi
ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default"
if test "x$ac_cv_type_ssize_t" = xyes; then :
@@ -8816,23 +9262,7 @@ fi
-for ac_func in vprintf
-do :
- ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf"
-if test "x$ac_cv_func_vprintf" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_VPRINTF 1
-_ACEOF
-
-ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt"
-if test "x$ac_cv_func__doprnt" = xyes; then :
-$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h
-
-fi
-
-fi
-done
@@ -9291,8 +9721,8 @@ _ACEOF
fi
-case `uname` in
-OSF1) : ;;
+case $host_os in
+osf1) : ;;
*)
@@ -9375,7 +9805,7 @@ fi
done
if test -z "$already_handled"; then
names_already_handled="$names_already_handled $name"
- uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
+ uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'`
eval value=\"\$HAVE_LIB$uppername\"
if test -n "$value"; then
if test "$value" = yes; then
@@ -9854,10 +10284,10 @@ esac
for ac_func in atexit btowc fmod getgrent getgroups grantpt \
isascii iswctype iswlower iswupper mbrlen \
memcmp memcpy memcpy_ulong memmove memset \
- memset_ulong mkstemp setenv setlocale setsid snprintf strchr \
- strerror strftime strncasecmp strcoll strtod strtoul \
+ memset_ulong mkstemp posix_openpt setenv setlocale setsid snprintf strchr \
+ strerror strftime strcasecmp strncasecmp strcoll strtod strtoul \
system tmpfile towlower towupper tzset usleep wcrtomb \
- wcscoll wcscoll wctype
+ wcscoll wctype
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -9907,27 +10337,29 @@ $as_echo "#define HAVE_MBRTOWC 1" >>confdefs.h
fi
-ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default"
-if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+# Check whether --enable-extensions was given.
+if test "${enable_extensions+set}" = set; then :
+ enableval=$enable_extensions;
+fi
-$as_echo "#define DYNAMIC 1" >>confdefs.h
+if test "x$enable_extensions" != "xno"; then
+ extensions_supported=no
- if test "$GCC" = yes
- then
- # Add others here as appropriate,
- # one day use GNU libtool.
- # 3/2010: Used to have cygwin here but removed since
- # we get complaints that -export-dynamic doesn't work.
- if uname | $EGREP -i 'linux|freebsd' > /dev/null
- then
- LDFLAGS="$LDFLAGS -export-dynamic"
- fi
- fi
+ case $host_os in
+ mirbsd* | openedition*) # OS/390 z/OS POSIX layer
+ cat << \EOF > extension/Makefile
+all dist check clean distclean install uninstall distcheck:
+ @exit 0
+EOF
+ ;;
+ *)
+ ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
- # Check this separately. Some systems have dlopen
- # in libc. Notably freebsd and cygwin.
- # HP-NSK has it in zrldsrl
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
+ # Check this separately. Some systems have dlopen
+ # in libc. Notably freebsd and cygwin.
+ # HP-NSK has it in zrldsrl
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
$as_echo_n "checking for library containing dlopen... " >&6; }
if ${ac_cv_search_dlopen+:} false; then :
$as_echo_n "(cached) " >&6
@@ -9980,16 +10412,43 @@ $as_echo "$ac_cv_search_dlopen" >&6; }
ac_res=$ac_cv_search_dlopen
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
+ gawk_have_dlopen=yes
+else
+ gawk_have_dlopen=no
fi
+ # Only do DYNAMIC if we have the lib. z/OS (some versions) have
+ # the header but not the lib, apparently
+ if test "$gawk_have_dlopen" = yes
+ then
+ extensions_supported=yes
+
+$as_echo "#define DYNAMIC 1" >>confdefs.h
+
+ # Add -export-dynamic for old extensions. Only works for GCC
+ if test "$GCC" = yes; then
+ case $host_os in
+ linux*|freebsd*)
+ LDFLAGS="$LDFLAGS -Wl,-export-dynamic"
+ ;;
+ esac
+ fi
+ fi
fi
+ ;;
+ esac
+
+ if test "x$enable_extensions$extensions_supported" = "xyesno"; then
+ as_fn_error $? "extension support requested, but unavailable" "$LINENO" 5
+ fi
+ enable_extensions=$extensions_supported
+fi
-case `(uname) 2> /dev/null` in
-*VMS*|*BeOS*|*OS/2*|*MS-DOS*)
+case $host_os in
+vms*|beos*|os2*|msdos)
$as_echo "#define GETPGRP_VOID 1" >>confdefs.h
@@ -10244,48 +10703,133 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether readline via \"$_combo\" is present and sane" >&5
$as_echo_n "checking whether readline via \"$_combo\" is present and sane... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ if test "$cross_compiling" = yes; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-
-
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
-
int
main ()
{
-rl_completion_func_t *completer;
-add_history("foobar");
-rl_catch_signals=0;
-rl_inhibit_completion=0;
-rl_attempted_completion_function=NULL;
-rl_completion_matches(NULL,NULL);
+ int fd;
+ char *line;
+
+ close(0);
+ close(1);
+ fd = open("/dev/null", 2); /* should get fd 0 */
+ dup(fd);
+ line = readline("giveittome> ");
+
+ /* some printfs don't handle NULL for %s */
+ printf("got <%s>\n", line ? line : "(NULL)");
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
- _found_readline=yes
+ _found_readline=yes
else
- _found_readline=no
+ _found_readline=no
+
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+#include <readline/readline.h>
+#include <readline/history.h>
+
+int main(int argc, char **argv)
+{
+ int fd;
+ char *line;
+
+ close(0);
+ close(1);
+ fd = open("/dev/null", 2); /* should get fd 0 */
+ dup(fd);
+ line = readline("giveittome> ");
+
+ /* some printfs don't handle NULL for %s */
+ printf("got <%s>\n", line ? line : "(NULL)");
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ _found_readline=yes
+else
+ _found_readline=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_found_readline" >&5
$as_echo "$_found_readline" >&6; }
LIBS=$_readline_save_libs
if test $_found_readline = yes ; then
+ case $host_os in
+ *bsd* ) _combo="$_combo -ltermcap"
+ ;;
+ esac
$as_echo "#define HAVE_LIBREADLINE 1" >>confdefs.h
LIBREADLINE=$_combo
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for history_list in -lreadline" >&5
+$as_echo_n "checking for history_list in -lreadline... " >&6; }
+if ${ac_cv_lib_readline_history_list+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline $_combo $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char history_list ();
+int
+main ()
+{
+return history_list ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_readline_history_list=yes
+else
+ ac_cv_lib_readline_history_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_history_list" >&5
+$as_echo "$ac_cv_lib_readline_history_list" >&6; }
+if test "x$ac_cv_lib_readline_history_list" = xyes; then :
+
+$as_echo "#define HAVE_HISTORY_LIST 1" >>confdefs.h
+
+fi
+
+
break
fi
done
@@ -10297,51 +10841,88 @@ $as_echo "#define HAVE_LIBREADLINE 1" >>confdefs.h
fi
-ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default"
-if test "x$ac_cv_member_struct_stat_st_blksize" = xyes; then :
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
-_ACEOF
+# Check whether --with-mpfr was given.
+if test "${with_mpfr+set}" = set; then :
+ withval=$with_mpfr; _do_mpfr=$withval
+else
+ _do_mpfr=yes
+fi
-$as_echo "#define HAVE_ST_BLKSIZE 1" >>confdefs.h
-fi
+ if test "$_do_mpfr" != "no" ; then
+ if test -d "$withval" ; then
+ CPPFLAGS="${CPPFLAGS} -I$withval/include"
+ LDFLAGS="${LDFLAGS} -L$withval/lib"
+ fi
+ _mpfr_save_libs=$LIBS
+ _combo="-lmpfr -lgmp"
+ LIBS="$LIBS $_combo"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
-$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
-if ${ac_cv_header_time+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mpfr via \"$_combo\" is present and usable" >&5
+$as_echo_n "checking whether mpfr via \"$_combo\" is present and usable... " >&6; }
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include <sys/types.h>
-#include <sys/time.h>
-#include <time.h>
+
+
+#include <stdio.h>
+#include <mpfr.h>
+#include <gmp.h>
int
main ()
{
-if ((struct tm *) 0)
-return 0;
+
+mpfr_t p;
+mpz_t z;
+mpfr_init(p);
+mpz_init(z);
+mpfr_printf("%Rf%Zd", p, z);
+mpfr_clear(p);
+mpz_clear(z);
+
;
return 0;
}
_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_header_time=yes
+if ac_fn_c_try_link "$LINENO"; then :
+ _found_mpfr=yes
else
- ac_cv_header_time=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ _found_mpfr=no
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
-$as_echo "$ac_cv_header_time" >&6; }
-if test $ac_cv_header_time = yes; then
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_found_mpfr" >&5
+$as_echo "$_found_mpfr" >&6; }
+
+ LIBS=$_mpfr_save_libs
+
+ if test $_found_mpfr = yes ; then
+
+$as_echo "#define HAVE_MPFR 1" >>confdefs.h
+
+ LIBMPFR=$_combo
+
+ break
+ fi
+
+ unset _mpfr_save_libs
+ unset _combo
+ unset _found_mpfr
+ fi
+
+
+ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default"
+if test "x$ac_cv_member_struct_stat_st_blksize" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
+_ACEOF
-$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
fi
@@ -10460,7 +11041,8 @@ int
main ()
{
static int test_array [1 - 2 * !(((char) -1) < 0)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -10491,11 +11073,11 @@ else
int
main ()
{
-/* FIXME: Include the comments suggested by Paul. */
+
#ifndef __cplusplus
- /* Ultrix mips cc rejects this. */
+ /* Ultrix mips cc rejects this sort of thing. */
typedef int charset[2];
- const charset cs;
+ const charset cs = { 0, 0 };
/* SunOS 4.1.1 cc rejects this. */
char const *const *pcpcc;
char **ppc;
@@ -10512,8 +11094,9 @@ main ()
++pcpcc;
ppc = (char**) pcpcc;
pcpcc = (char const *const *) ppc;
- { /* SCO 3.2v4 cc rejects this. */
- char *t;
+ { /* SCO 3.2v4 cc rejects this sort of thing. */
+ char tx;
+ char *t = &tx;
char const *s = 0 ? (char *) 0 : (char const *) 0;
*t++ = 0;
@@ -10529,10 +11112,10 @@ main ()
iptr p = 0;
++p;
}
- { /* AIX XL C 1.02.0.0 rejects this saying
+ { /* AIX XL C 1.02.0.0 rejects this sort of thing, 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;
+ struct s { int j; const int *ap[3]; } bx;
+ struct s *b = &bx; b->j = 5;
}
{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
const int foo = 10;
@@ -10681,8 +11264,20 @@ 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"
+case $acl_shlibext in
+dylib) GAWKLIBEXT=so ;; # MacOS uses .dylib for shared libraries, but libtool uses .so for modules
+*) GAWKLIBEXT=$acl_shlibext ;;
+esac
+
+ac_config_files="$ac_config_files Makefile awklib/Makefile doc/Makefile extras/Makefile po/Makefile.in test/Makefile"
+
+if test "x$enable_extensions" = "xyes"; then
+
+
+subdirs="$subdirs extension"
+
+fi
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
@@ -10792,6 +11387,14 @@ LIBOBJS=$ac_libobjs
LTLIBOBJS=$ac_ltlibobjs
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
if test -n "$EXEEXT"; then
am__EXEEXT_TRUE=
am__EXEEXT_FALSE='#'
@@ -10812,6 +11415,10 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${TEST_CROSS_COMPILE_TRUE}" && test -z "${TEST_CROSS_COMPILE_FALSE}"; then
+ as_fn_error $? "conditional \"TEST_CROSS_COMPILE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
: "${CONFIG_STATUS=./config.status}"
ac_write_fail=0
@@ -11110,16 +11717,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -11179,28 +11786,16 @@ else
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# 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'"
@@ -11221,8 +11816,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by GNU Awk $as_me 4.0.70, which was
-generated by GNU Autoconf 2.68. Invocation command line was
+This file was extended by GNU Awk $as_me 4.1.60, which was
+generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -11289,11 +11884,11 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-GNU Awk config.status 4.0.70
-configured by $0, generated by GNU Autoconf 2.68,
+GNU Awk config.status 4.1.60
+configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
@@ -11384,7 +11979,7 @@ fi
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
- set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
shift
\$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
CONFIG_SHELL='$SHELL'
@@ -11431,6 +12026,7 @@ do
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"awklib/Makefile") CONFIG_FILES="$CONFIG_FILES awklib/Makefile" ;;
"doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+ "extras/Makefile") CONFIG_FILES="$CONFIG_FILES extras/Makefile" ;;
"po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;;
"test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
@@ -12029,7 +12625,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
case $ac_file$ac_mode in
"depfiles":C) test x"$AMDEP_TRUE" != x"" || {
- # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # Older Autoconf quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting.
case $CONFIG_FILES in
@@ -12042,7 +12638,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
# 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
+ # 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.
@@ -12076,21 +12672,19 @@ $as_echo X"$mf" |
continue
fi
# Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running `make'.
+ # 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
+ 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
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`$as_dirname -- "$file" ||
@@ -12133,7 +12727,7 @@ $as_echo X"$file" |
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_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.
@@ -12149,7 +12743,8 @@ $as_echo X"$file" |
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"
+ gt_tab=`printf '\t'`
+ cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/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
@@ -12160,12 +12755,12 @@ $as_echo X"$file" |
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 < 1.5.
+ # Hide the ALL_LINGUAS assignment from automake < 1.5.
eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
else
# The set of available languages was given in configure.in.
- # Hide the ALL_LINGUAS assigment from automake < 1.5.
+ # Hide the ALL_LINGUAS assignment from automake < 1.5.
eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
fi
# Compute POFILES
@@ -12269,6 +12864,151 @@ if test "$no_create" != yes; then
# would make configure fail if this is the last instruction.
$ac_cs_success || as_fn_exit 1
fi
+
+#
+# CONFIG_SUBDIRS section.
+#
+if test "$no_recursion" != yes; then
+
+ # Remove --cache-file, --srcdir, and --disable-option-checking arguments
+ # so they do not pile up.
+ ac_sub_configure_args=
+ ac_prev=
+ eval "set x $ac_configure_args"
+ shift
+ for ac_arg
+ do
+ if test -n "$ac_prev"; then
+ ac_prev=
+ continue
+ fi
+ case $ac_arg in
+ -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=*)
+ ;;
+ --config-cache | -C)
+ ;;
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ ;;
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ ;;
+ --disable-option-checking)
+ ;;
+ *)
+ case $ac_arg in
+ *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append ac_sub_configure_args " '$ac_arg'" ;;
+ esac
+ done
+
+ # Always prepend --prefix to ensure using the same prefix
+ # in subdir configurations.
+ ac_arg="--prefix=$prefix"
+ case $ac_arg in
+ *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args"
+
+ # Pass --silent
+ if test "$silent" = yes; then
+ ac_sub_configure_args="--silent $ac_sub_configure_args"
+ fi
+
+ # Always prepend --disable-option-checking to silence warnings, since
+ # different subdirs can have different --enable and --with options.
+ ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args"
+
+ ac_popdir=`pwd`
+ for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue
+
+ # Do not complain, so a configure script can configure whichever
+ # parts of a large source tree are present.
+ test -d "$srcdir/$ac_dir" || continue
+
+ ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)"
+ $as_echo "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5
+ $as_echo "$ac_msg" >&6
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ cd "$ac_dir"
+
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ ac_sub_configure=$ac_srcdir/configure.gnu
+ elif test -f "$ac_srcdir/configure"; then
+ ac_sub_configure=$ac_srcdir/configure
+ elif test -f "$ac_srcdir/configure.in"; then
+ # This should be Cygnus configure.
+ ac_sub_configure=$ac_aux_dir/configure
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5
+$as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;}
+ ac_sub_configure=
+ fi
+
+ # The recursion is here.
+ if test -n "$ac_sub_configure"; then
+ # Make the cache file name correct relative to the subdirectory.
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;;
+ *) # Relative name.
+ ac_sub_cache_file=$ac_top_build_prefix$cache_file ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5
+$as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;}
+ # The eval makes quoting arguments work.
+ eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \
+ --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" ||
+ as_fn_error $? "$ac_sub_configure failed for $ac_dir" "$LINENO" 5
+ fi
+
+ cd "$ac_popdir"
+ done
+fi
if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
diff --git a/configure.ac b/configure.ac
index 3b0ba330..fc0f93ba 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
dnl
dnl configure.ac --- autoconf input file for gawk
dnl
-dnl Copyright (C) 1995-2011 the Free Software Foundation, Inc.
+dnl Copyright (C) 1995-2015 the Free Software Foundation, Inc.
dnl
dnl This file is part of GAWK, the GNU implementation of the
dnl AWK Programming Language.
@@ -23,7 +23,7 @@ dnl
dnl Process this file with autoconf to produce a configure script.
-AC_INIT([GNU Awk], 4.0.70, bug-gawk@gnu.org, gawk)
+AC_INIT([GNU Awk], 4.1.60, 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.
@@ -39,8 +39,8 @@ then
export INSTALL
fi
-AC_PREREQ(2.68)
-AM_INIT_AUTOMAKE([1.11 dist-xz])
+AC_PREREQ(2.69)
+AM_INIT_AUTOMAKE([1.14 dist-xz dist-lzip])
AC_CONFIG_MACRO_DIR([m4])
@@ -58,7 +58,14 @@ AC_ARG_ENABLE([lint], [ --disable-lint Disable gawk lint checking],
AC_DEFINE(NO_LINT, 1, [disable lint checks])
fi
)
+AC_ARG_ENABLE([severe-portability-problems], [ --enable-severe-portability-problems Enable really nasty portability problems],
+ if test "$enableval" = yes
+ then
+ AC_DEFINE(I_DONT_KNOW_WHAT_IM_DOING, 1, [enable severe portability problems])
+ fi
+)
+AC_CANONICAL_HOST
AC_USE_SYSTEM_EXTENSIONS
dnl checks for programs
@@ -80,7 +87,7 @@ 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"
+ CFLAGS="$CFLAGS -DARRAYDEBUG -DYYDEBUG -DLOCALEDEBUG"
if grep dbug $srcdir/.developing
then
CFLAGS="$CFLAGS -DDBUG"
@@ -90,15 +97,21 @@ then
# enable debugging using macros also
if test "$GCC" = yes
then
- CFLAGS="$CFLAGS -Wall"
+ CFLAGS="$CFLAGS -Wall -fno-builtin -g3"
fi
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
+ CFLAGS="$CFLAGS -DNDEBUG" # turn off assertions
fi
AC_SUBST(CFLAGS)
+# shared library suffix for dynamic loading:
+AC_SUBST(acl_shlibext)
+# default shared library location
+AC_SUBST([pkgextensiondir], ['${pkglibdir}'])
+
dnl checks for systems
AC_ZOS_USS
AC_ISC_POSIX
@@ -116,31 +129,21 @@ dnl Set the programming language for checks. Fortunately,
dnl this only needs to be set once, since everything is in C.
AC_LANG([C])
-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.18.1])
+AM_GNU_GETTEXT_VERSION([0.19.3])
AM_LANGINFO_CODESET
gt_LC_MESSAGES
dnl checks for header files
-AC_HEADER_STDC
-AC_HEADER_SYS_WAIT
-AC_HEADER_TIME
AC_CHECK_HEADERS(arpa/inet.h fcntl.h limits.h locale.h libintl.h mcheck.h \
netdb.h netinet/in.h stdarg.h stddef.h string.h \
sys/ioctl.h sys/param.h sys/socket.h sys/time.h unistd.h \
termios.h stropts.h wchar.h wctype.h)
+AC_HEADER_STDC
+AC_HEADER_STDBOOL
+AC_HEADER_SYS_WAIT
+AC_HEADER_TIME
if test "$ac_cv_header_string_h" = yes
then
@@ -149,15 +152,18 @@ else
AC_CHECK_HEADERS(strings.h)
fi
+dnl Check cross compiling
+AM_CONDITIONAL([TEST_CROSS_COMPILE], [test "x$build_alias" != "x$host_alias"])
+
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_TYPE_LONG_LONG_INT
+AC_TYPE_UNSIGNED_LONG_LONG_INT
+AC_TYPE_INTMAX_T
+AC_TYPE_UINTMAX_T
AC_CHECK_TYPE(ssize_t, int)
AC_CHECK_SIZEOF(unsigned int)
AC_CHECK_SIZEOF(unsigned long)
@@ -237,8 +243,10 @@ dnl AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
])
TYPE_SOCKLEN_T
+dnl Check for C11 _Noreturn
+GAWK_AC_NORETURN
+
dnl checks for functions
-AC_FUNC_VPRINTF
AC_FUNC_MKTIME
case "$ac_cv_func_working_mktime" in
yes) AC_DEFINE(HAVE_MKTIME, 1, [we have the mktime function])
@@ -254,8 +262,8 @@ AC_CHECK_LIB(m, fmod)
AC_CHECK_LIB(m, isinf)
AC_CHECK_LIB(m, ismod)
dnl Don't look for libsigsegv on OSF/1, gives us severe headaches
-case `uname` in
-OSF1) : ;;
+case $host_os in
+osf1) : ;;
*)
gl_LIBSIGSEGV
;;
@@ -265,40 +273,65 @@ esac
AC_CHECK_FUNCS(atexit btowc fmod getgrent getgroups grantpt \
isascii iswctype iswlower iswupper mbrlen \
memcmp memcpy memcpy_ulong memmove memset \
- memset_ulong mkstemp setenv setlocale setsid snprintf strchr \
- strerror strftime strncasecmp strcoll strtod strtoul \
+ memset_ulong mkstemp posix_openpt setenv setlocale setsid snprintf strchr \
+ strerror strftime strcasecmp strncasecmp strcoll strtod strtoul \
system tmpfile towlower towupper tzset usleep wcrtomb \
- wcscoll wcscoll wctype)
+ 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.
- # 3/2010: Used to have cygwin here but removed since
- # we get complaints that -export-dynamic doesn't work.
- if uname | $EGREP -i 'linux|freebsd' > /dev/null
+AC_ARG_ENABLE([extensions],
+ [AS_HELP_STRING([--disable-extensions], [disable dynamic extensions (default is detect)])])
+if test "x$enable_extensions" != "xno"; then
+ extensions_supported=no
+
+ dnl On MirBSD (and probably other systems), don't even try.
+ case $host_os in
+ mirbsd* | openedition*) # OS/390 z/OS POSIX layer
+ cat << \EOF > extension/Makefile
+all dist check clean distclean install uninstall distcheck:
+ @exit 0
+EOF
+ ;;
+ *)
+ AC_CHECK_HEADER(dlfcn.h,
+ [
+ # Check this separately. Some systems have dlopen
+ # in libc. Notably freebsd and cygwin.
+ # HP-NSK has it in zrldsrl
+ AC_SEARCH_LIBS(dlopen, dl zrldsrl, gawk_have_dlopen=yes, gawk_have_dlopen=no)
+ # Only do DYNAMIC if we have the lib. z/OS (some versions) have
+ # the header but not the lib, apparently
+ if test "$gawk_have_dlopen" = yes
then
- LDFLAGS="$LDFLAGS -export-dynamic"
+ extensions_supported=yes
+ AC_DEFINE([DYNAMIC], 1, [dynamic loading is possible])
+ # Add -export-dynamic for old extensions. Only works for GCC
+ if test "$GCC" = yes; then
+ case $host_os in
+ linux*|freebsd*)
+ LDFLAGS="$LDFLAGS -Wl,-export-dynamic"
+ ;;
+ esac
+ fi
fi
- fi
+ ])
+ ;;
+ esac
- # Check this separately. Some systems have dlopen
- # in libc. Notably freebsd and cygwin.
- # HP-NSK has it in zrldsrl
- AC_SEARCH_LIBS(dlopen, dl zrldsrl)
-])
+ if test "x$enable_extensions$extensions_supported" = "xyesno"; then
+ AC_MSG_ERROR([extension support requested, but unavailable])
+ fi
+ enable_extensions=$extensions_supported
+fi
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*)
+case $host_os in
+vms*|beos*|os2*|msdos)
AC_DEFINE(GETPGRP_VOID, 1,
[Define to 1 if the getpgrp function requires zero arguments.])
;;
@@ -337,11 +370,13 @@ dnl check for sockets
GAWK_AC_LIB_SOCKETS
dnl check for readline support
-GNUPG_CHECK_READLINE
+GAWK_CHECK_READLINE
+
+dnl check for mpfr support
+GNUPG_CHECK_MPFR
dnl checks for structure members
-AC_STRUCT_ST_BLKSIZE
-AC_HEADER_TIME
+AC_CHECK_MEMBERS([struct stat.st_blksize])
AC_STRUCT_TM
AC_STRUCT_TIMEZONE
@@ -355,9 +390,22 @@ AC_C_STRINGIZE
AC_CONFIG_HEADERS([config.h:configh.in])
AH_BOTTOM([#include "custom.h"])
+dnl Crude but small hack to make plug-ins work on Mac OS X
+dnl We should really use the libtool value for shrext_cmds, but that
+dnl is not available here, since we do not use libtool at the top level.
+case $acl_shlibext in
+dylib) GAWKLIBEXT=so ;; # MacOS uses .dylib for shared libraries, but libtool uses .so for modules
+*) GAWKLIBEXT=$acl_shlibext ;;
+esac
+AC_SUBST(GAWKLIBEXT)
+
AC_CONFIG_FILES(Makefile
awklib/Makefile
doc/Makefile
+ extras/Makefile
po/Makefile.in
test/Makefile)
+if test "x$enable_extensions" = "xyes"; then
+ AC_CONFIG_SUBDIRS(extension)
+fi
AC_OUTPUT
diff --git a/custom.h b/custom.h
index 36b4aa0b..efaa0f27 100644
--- a/custom.h
+++ b/custom.h
@@ -47,12 +47,6 @@
#define HAVE_MKTIME 1
#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
@@ -76,3 +70,11 @@
extern int setenv(const char *name, const char *value, int rewrite);
extern int unsetenv(const char *name);
#endif
+
+/* Junk for dfa.[ch] */
+/* The __pure__ attribute was added in gcc 2.96. */
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
+# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
+#else
+# define _GL_ATTRIBUTE_PURE /* empty */
+#endif
diff --git a/debug.c b/debug.c
index 5870a40f..58012b72 100644
--- a/debug.c
+++ b/debug.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2004, 2010, 2011 the Free Software Foundation, Inc.
+ * Copyright (C) 2004, 2010-2013 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -30,7 +30,7 @@
#include <fcntl.h> /* open() */
#endif
-extern int exiting;
+extern bool exiting;
extern SRCFILE *srcfiles;
extern INSTRUCTION *rule_list;
extern INSTRUCTION *code_block;
@@ -40,7 +40,6 @@ extern FILE *output_fp;
extern IOBUF *curfile;
extern const char *command_file;
extern const char *get_spec_varname(Func_ptr fptr);
-extern int r_interpret(INSTRUCTION *);
extern int zzparse(void);
#define read_command() (void) zzparse()
@@ -50,11 +49,11 @@ static char *linebuf = NULL; /* used to print a single line of source */
static size_t linebuf_len;
FILE *out_fp;
-char *dPrompt;
-char *commands_Prompt = "> "; /* breakpoint or watchpoint commands list */
-char *eval_Prompt = "@> "; /* awk statement(s) */
+char *dbg_prompt;
+char *commands_prompt = "> "; /* breakpoint or watchpoint commands list */
+char *eval_prompt = "@> "; /* awk statement(s) */
-int input_from_tty = FALSE;
+bool input_from_tty = false;
int input_fd;
static SRCFILE *cur_srcfile;
@@ -62,7 +61,7 @@ static long cur_frame = 0;
static INSTRUCTION *cur_pc;
int cur_rule = 0;
-static int prog_running = FALSE;
+static bool prog_running = false;
struct condition {
INSTRUCTION *code;
@@ -90,7 +89,7 @@ typedef struct break_point {
INSTRUCTION *bpi; /* Op_breakpoint */
struct commands_item commands; /* list of commands to run */
- int silent;
+ bool silent;
struct condition cndn;
@@ -109,6 +108,12 @@ static BREAKPOINT breakpoints = { &breakpoints, &breakpoints, 0 };
static int sess_history_base = 0;
#endif
+#ifndef HAVE_HISTORY_LIST
+#define HIST_ENTRY void
+#define history_list() NULL
+#endif
+
+
/* 'list' command */
static int last_printed_line = 0;
static int last_print_count; /* # of lines printed */
@@ -169,12 +174,12 @@ static struct {
INSTRUCTION *pc; /* 'until' and 'return' commands */
int repeat_count; /* 'step', 'next', 'stepi', 'nexti' commands */
- int print_frame; /* print frame info, 'finish' and 'until' */
- int print_ret; /* print returned value, 'finish' */
+ bool print_frame; /* print frame info, 'finish' and 'until' */
+ bool print_ret; /* print returned value, 'finish' */
int break_point; /* non-zero (breakpoint number) if stopped at break point */
int watch_point; /* non-zero (watchpoint number) if stopped at watch point */
- int (*check_func)(INSTRUCTION **); /* function to decide when to suspend
+ int (*check_func)(INSTRUCTION **); /* function to decide when to suspend
* awk interpreter and return control
* to debugger command interpreter.
*/
@@ -185,7 +190,7 @@ static struct {
/* restart related stuff */
extern char **d_argv; /* copy of argv array */
-static int need_restart = FALSE;
+static bool need_restart = false;
enum { BREAK=1, WATCH, DISPLAY, HISTORY, OPTION };
static const char *const env_variable[] = {
"",
@@ -214,9 +219,9 @@ struct dbg_option {
const char *help_txt;
};
-#define DEFAULT_HISTFILE "./.dgawk_history"
-#define DEFAULT_OPTFILE "./.dgawkrc"
-#define DEFAULT_PROMPT "dgawk> "
+#define DEFAULT_HISTFILE "./.gawk_history"
+#define DEFAULT_OPTFILE "./.gawkrc"
+#define DEFAULT_PROMPT "gawk> "
#define DEFAULT_LISTSIZE 15
#define DEFAULT_HISTSIZE 100
@@ -232,14 +237,14 @@ static const char *options_file = DEFAULT_OPTFILE;
static const char *history_file = DEFAULT_HISTFILE;
#endif
-/* keep all option variables in one place */
+/* debugger option related variables */
static char *output_file = "/dev/stdout"; /* gawk output redirection */
-char *dgawk_Prompt = NULL; /* initialized in interpret */
+char *dgawk_prompt = NULL; /* initialized in interpret */
static int list_size = DEFAULT_LISTSIZE; /* # of lines that 'list' prints */
-static int do_trace = FALSE;
-static int do_save_history = TRUE;
-static int do_save_options = TRUE;
+static int do_trace = false;
+static int do_save_history = true;
+static int do_save_options = true;
static int history_size = DEFAULT_HISTSIZE; /* max # of lines in history file */
static const struct dbg_option option_list[] = {
@@ -249,7 +254,7 @@ static const struct dbg_option option_list[] = {
gettext_noop("set or show the list command window size.") },
{"outfile", NULL, &output_file, &set_gawk_output,
gettext_noop("set or show gawk output file.") },
-{"prompt", NULL, &dgawk_Prompt, &set_prompt,
+{"prompt", NULL, &dgawk_prompt, &set_prompt,
gettext_noop("set or show debugger prompt."), },
{"save_history", &do_save_history, NULL, &set_save_history,
gettext_noop("(un)set or show saving of command history (value=on|off).") },
@@ -265,18 +270,18 @@ static void save_options(const char *file);
/* pager */
jmp_buf pager_quit_tag;
-int pager_quit_tag_valid = FALSE;
+bool pager_quit_tag_valid = false;
static int screen_width = INT_MAX; /* no of columns */
static int screen_height = INT_MAX; /* no of rows */
static int pager_lines_printed = 0; /* no of lines printed so far */
-static void restart(int run) ATTRIBUTE_NORETURN;
+static void restart(bool run) ATTRIBUTE_NORETURN;
static void close_all(void);
static int open_readfd(const char *file);
static int find_lines(SRCFILE *s);
static SRCFILE *source_find(char *src);
static int print_lines(char *src, int start_line, int nlines);
-static void print_symbol(NODE *r, int isparam);
+static void print_symbol(NODE *r, bool isparam);
static NODE *find_frame(long num);
static NODE *find_param(const char *name, long num, char **pname);
static NODE *find_symbol(const char *name, char **pname);
@@ -293,10 +298,9 @@ static void delete_commands_item(struct commands_item *c);
static NODE *execute_code(volatile INSTRUCTION *code);
static int pre_execute_code(INSTRUCTION **pi);
static int parse_condition(int type, int num, char *expr);
-static BREAKPOINT *add_breakpoint(INSTRUCTION *, INSTRUCTION *, char *, int);
+static BREAKPOINT *add_breakpoint(INSTRUCTION *prevp, INSTRUCTION *ip, char *src, bool silent);
static BREAKPOINT *set_breakpoint_next(INSTRUCTION *rp, INSTRUCTION *ip);
-static BREAKPOINT *set_breakpoint_at(INSTRUCTION *, int, int);
-static int set_breakpoint(CMDARG *arg, int temporary);
+static BREAKPOINT *set_breakpoint_at(INSTRUCTION *rp, int lineno, bool silent);
static void delete_breakpoint(BREAKPOINT *b);
static BREAKPOINT *find_breakpoint(long num);
static void display(struct list_item *d);
@@ -308,12 +312,13 @@ static int watchpoint_triggered(struct list_item *w);
static void print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump);
static int print_code(INSTRUCTION *pc, void *x);
static void next_command();
+static void debug_post_execute(INSTRUCTION *pc);
+static int debug_pre_execute(INSTRUCTION **pi);
static char *g_readline(const char *prompt);
static int prompt_yes_no(const char *, char , int , FILE *);
-
static struct pf_data {
Func_print print_func;
- int defn;
+ bool defn;
FILE *fp;
} pf_data;
@@ -326,8 +331,8 @@ struct command_source
char * (*read_func)(const char *);
int (*close_func)(int);
int eof_status; /* see push_cmd_src */
- int cmd; /* D_source or 0 */
- char *str; /* sourced file */
+ int cmd; /* D_source or 0 */
+ char *str; /* sourced file */
struct command_source *next;
};
@@ -338,9 +343,9 @@ static struct command_source *cmd_src = NULL;
do { \
if (! prog_running) { \
d_error(_("program not running.")); \
- return FALSE; \
+ return false; \
} \
- } while (FALSE)
+ } while (false)
/* g_readline -- read a line of text; the interface is like 'readline' but
@@ -485,16 +490,16 @@ source_find(char *src)
return s;
}
- path = find_source(src, &sbuf, &errno_val);
+ path = find_source(src, & sbuf, & errno_val, false);
if (path != NULL) {
for (s = srcfiles->next; s != srcfiles; s = s->next) {
if ((s->stype == SRC_FILE || s->stype == SRC_INC)
- && files_are_same(path, s)) {
+ && files_are_same(path, s)) {
efree(path);
return s;
}
- efree(path);
}
+ efree(path);
}
d_error(_("cannot find source file named `%s' (%s)"), src, strerror(errno_val));
@@ -537,6 +542,9 @@ print_lines(char *src, int start_line, int nlines)
}
}
+ /* set binary mode so that byte offset calculations will be right */
+ os_setbinmode(s->fd, O_BINARY);
+
if (s->line_offset == NULL && find_lines(s) != 0)
return -1;
if (start_line < 1 || start_line > s->srclines) {
@@ -574,10 +582,10 @@ print_lines(char *src, int start_line, int nlines)
*/
if (nlines > 1) {
BREAKPOINT *b;
- int has_bpt = FALSE;
+ bool has_bpt = false;
for (b = breakpoints.prev; b != &breakpoints; b = b->prev) {
if (src == b->src && i == b->bpi->source_line) {
- has_bpt = TRUE;
+ has_bpt = true;
break;
}
}
@@ -652,7 +660,7 @@ do_list(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
if (last_printed_line != last_print_count)
line_first = 1;
else
- return FALSE;
+ return false;
}
} else {
line:
@@ -706,7 +714,7 @@ list:
last_printed_line = line_last;
last_print_count = line_last - line_first + 1;
}
- return FALSE;
+ return false;
}
/* do_info --- info command */
@@ -717,7 +725,7 @@ do_info(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
NODE **table;
if (arg == NULL || arg->type != D_argument)
- return FALSE;
+ return false;
switch (arg->a_argument) {
case A_SOURCE:
@@ -746,16 +754,16 @@ do_info(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
gprintf(out_fp, _("Number Disp Enabled Location\n\n"));
for (b = breakpoints.prev; b != &breakpoints; b = b->prev) {
char *disp = "keep";
- if (b->flags & BP_ENABLE_ONCE)
+ if ((b->flags & BP_ENABLE_ONCE) != 0)
disp = "dis";
- else if(b->flags & BP_TEMP)
+ else if ((b->flags & BP_TEMP) != 0)
disp = "del";
gprintf(out_fp, "%-6d %-4.4s %-7.7s file %s, line #%d\n",
- b->number, disp, (b->flags & BP_ENABLE) ? "yes" : "no",
+ b->number, disp, (b->flags & BP_ENABLE) != 0 ? "yes" : "no",
b->src, b->bpi->source_line);
if (b->hit_count > 0)
gprintf(out_fp, _("\tno of hits = %ld\n"), b->hit_count);
- if (b->flags & BP_IGNORE)
+ if ((b->flags & BP_IGNORE) != 0)
gprintf(out_fp, _("\tignore next %ld hit(s)\n"), b->ignore_count);
if (b->cndn.code != NULL)
gprintf(out_fp, _("\tstop condition: %s\n"), b->cndn.expr);
@@ -808,7 +816,7 @@ do_info(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
if (func == NULL) {
/* print ARGV ? */
fprintf(out_fp, _("None in main().\n"));
- return FALSE;
+ return false;
}
pcount = func->param_cnt; /* # of defined params */
@@ -832,7 +840,7 @@ do_info(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
if (r->type == Node_array_ref)
r = r->orig_array;
fprintf(out_fp, "%s = ", func->fparms[i].param);
- print_symbol(r, TRUE);
+ print_symbol(r, true);
}
if (to < from)
fprintf(out_fp, "%s",
@@ -853,13 +861,13 @@ do_info(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
break;
case A_FUNCTIONS:
- table = function_list(TRUE);
+ table = function_list(true);
initialize_pager(out_fp);
if (setjmp(pager_quit_tag) == 0) {
gprintf(out_fp, _("All defined functions:\n\n"));
pf_data.print_func = gprintf;
pf_data.fp = out_fp;
- pf_data.defn = TRUE;
+ pf_data.defn = true;
(void) foreach_func(table,
(int (*)(INSTRUCTION *, void *)) print_function,
&pf_data);
@@ -894,7 +902,7 @@ do_info(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
}
gprintf(out_fp, "\n");
} else if (IS_FIELD(d))
- gprintf(out_fp, "%d:\t$%ld\n", d->number, (long) symbol->numbr);
+ gprintf(out_fp, "%d:\t$%ld\n", d->number, get_number_si(symbol));
else
gprintf(out_fp, "%d:\t%s\n", d->number, d->sname);
if (d->cndn.code != NULL)
@@ -925,13 +933,13 @@ do_info(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
break;
}
- return FALSE;
+ return false;
}
/* print_symbol --- print a symbol table entry */
static void
-print_symbol(NODE *r, int isparam)
+print_symbol(NODE *r, bool isparam)
{
switch (r->type) {
case Node_var_new:
@@ -943,7 +951,7 @@ print_symbol(NODE *r, int isparam)
valinfo(r->var_value, fprintf, out_fp);
break;
case Node_var_array:
- fprintf(out_fp, "array, %ld elements\n", r->table_size);
+ fprintf(out_fp, "array, %ld elements\n", assoc_length(r));
break;
case Node_func:
fprintf(out_fp, "`function'\n");
@@ -962,7 +970,7 @@ find_frame(long num)
if (num == 0)
return frame_ptr;
- assert(prog_running == TRUE);
+ assert(prog_running == true);
assert(num <= fcall_count);
assert(fcall_list[num] != NULL);
return fcall_list[num];
@@ -991,7 +999,7 @@ find_param(const char *name, long num, char **pname)
pcount = func->param_cnt;
for (i = 0; i < pcount; i++) {
fparam = func->fparms[i].param;
- if (STREQ(name, fparam)) {
+ if (strcmp(name, fparam) == 0) {
r = f->stack[i];
if (r->type == Node_array_ref)
r = r->orig_array;
@@ -1064,12 +1072,12 @@ print_array(volatile NODE *arr, char *arr_name)
volatile int ret = 0;
volatile jmp_buf pager_quit_tag_stack;
- if (array_empty(arr)) {
+ if (assoc_empty((NODE *) arr)) {
gprintf(out_fp, _("array `%s' is empty\n"), arr_name);
return 0;
}
- num_elems = arr->table_size;
+ num_elems = assoc_length((NODE *) arr);
/* sort indices, sub_arrays are also sorted! */
list = assoc_list((NODE *) arr, "@ind_str_asc", SORTED_IN);
@@ -1115,7 +1123,7 @@ print_subscript(NODE *arr, char *arr_name, CMDARG *a, int count)
else {
/* print # of elements in array */
fprintf(out_fp, "%s = ", r->vname);
- print_symbol(r, FALSE);
+ print_symbol(r, false);
}
} else {
fprintf(out_fp, "%s[\"%s\"] = ", arr_name, subs->stptr);
@@ -1180,7 +1188,7 @@ do_print_var(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
break;
case D_field:
- print_field(a->a_node->numbr);
+ print_field(get_number_si(a->a_node));
break;
default:
@@ -1188,7 +1196,7 @@ do_print_var(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
break;
}
}
- return FALSE;
+ return false;
}
/* do_set_var --- set command */
@@ -1264,7 +1272,9 @@ do_set_var(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
array = make_array();
array->vname = estrdup(subs->stptr, subs->stlen);
array->parent_array = r;
- *assoc_lookup(r, subs) = array;
+ lhs = assoc_lookup(r, subs);
+ unref(*lhs);
+ *lhs = array;
r = array;
} else if (value->type != Node_var_array) {
d_error(_("attempt to use scalar `%s[\"%s\"]' as array"),
@@ -1284,7 +1294,7 @@ do_set_var(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
long field_num;
Func_ptr assign = NULL;
- field_num = (long) arg->a_node->numbr;
+ field_num = get_number_si(arg->a_node);
assert(field_num >= 0);
arg = arg->next;
val = arg->a_node;
@@ -1300,7 +1310,7 @@ do_set_var(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
default:
break;
}
- return FALSE;
+ return false;
}
/* find_item --- find an item in the watch/display list */
@@ -1345,7 +1355,7 @@ delete_item(struct list_item *d)
delete_commands_item(c->next);
}
- free_context(d->cndn.ctxt, FALSE);
+ free_context(d->cndn.ctxt, false);
if (d->cndn.expr != NULL)
efree(d->cndn.expr);
@@ -1534,7 +1544,7 @@ display(struct list_item *d)
} else if (IS_FIELD(d)) {
NODE *r = d->symbol;
fprintf(out_fp, "%d: ", d->number);
- print_field(r->numbr);
+ print_field(get_number_si(r));
} else {
print_sym:
fprintf(out_fp, "%d: %s = ", d->number, d->sname);
@@ -1554,13 +1564,13 @@ do_display(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
/* display all items */
for (d = display_list.prev; d != &display_list; d = d->prev)
display(d);
- return FALSE;
+ return false;
}
if ((d = do_add_item(&display_list, arg)) != NULL)
display(d);
- return FALSE;
+ return false;
}
/* do_undisplay --- undisplay command */
@@ -1569,7 +1579,7 @@ int
do_undisplay(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
{
do_delete_item(&display_list, arg);
- return FALSE;
+ return false;
}
/* condition_triggered --- test if a condition expression is true */
@@ -1582,16 +1592,16 @@ condition_triggered(struct condition *cndn)
assert(cndn != NULL);
if (cndn->code == NULL)
- return TRUE;
+ return true;
push_context(cndn->ctxt);
r = execute_code((volatile INSTRUCTION *) cndn->code);
pop_context(); /* switch to prev context */
if (r == NULL) /* fatal error */
- return FALSE; /* not triggered */
+ return false; /* not triggered */
force_number(r);
- di = (r->numbr != 0.0);
+ di = ! iszero(r);
DEREF(r);
return di;
}
@@ -1620,7 +1630,7 @@ find_subscript(struct list_item *item, NODE **ptr)
return 0;
}
-/* cmp_val --- compare values of watched item, returns TRUE if different; */
+/* cmp_val --- compare values of watched item, returns true if different; */
static int
cmp_val(struct list_item *w, NODE *old, NODE *new)
@@ -1628,38 +1638,38 @@ cmp_val(struct list_item *w, NODE *old, NODE *new)
/*
* case old new result
* ------------------------------
- * 1: NULL ARRAY TRUE
- * 2: NULL SCALAR TRUE
- * 3: NULL NULL FALSE
+ * 1: NULL ARRAY true
+ * 2: NULL SCALAR true
+ * 3: NULL NULL false
* 4: SCALAR SCALAR cmp_node
- * 5: SCALAR ARRAY TRUE
- * 6: SCALAR NULL TRUE
- * 7: ARRAY SCALAR TRUE
+ * 5: SCALAR ARRAY true
+ * 6: SCALAR NULL true
+ * 7: ARRAY SCALAR true
* 8: ARRAY ARRAY compare size
- * 9: ARRAY NULL TRUE
+ * 9: ARRAY NULL true
*/
if (WATCHING_ARRAY(w)) {
long size = 0;
if (! new) /* 9 */
- return TRUE;
+ return true;
if (new->type == Node_val) /* 7 */
- return TRUE;
+ return true;
/* new->type == Node_var_array */ /* 8 */
- size = new->table_size;
+ size = assoc_length(new);
if (w->cur_size == size)
- return FALSE;
- return TRUE;
+ return false;
+ return true;
}
if (! old && ! new) /* 3 */
- return FALSE;
+ return false;
if ((! old && new) /* 1, 2 */
|| (old && ! new)) /* 6 */
- return TRUE;
+ return true;
if (new->type == Node_var_array) /* 5 */
- return TRUE;
+ return true;
return cmp_nodes(old, new); /* 4 */
}
@@ -1685,7 +1695,7 @@ watchpoint_triggered(struct list_item *w)
(void) find_subscript(w, &t2);
else if (IS_FIELD(w)) {
long field_num;
- field_num = (long) w->symbol->numbr;
+ field_num = get_number_si(w->symbol);
t2 = *get_field(field_num, NULL);
} else {
switch (symbol->type) {
@@ -1720,7 +1730,7 @@ watchpoint_triggered(struct list_item *w)
w->flags &= ~CUR_IS_ARRAY;
w->cur_value = dupnode(t2);
} else
- w->cur_size = (t2->type == Node_var_array) ? t2->table_size : 0;
+ w->cur_size = (t2->type == Node_var_array) ? assoc_length(t2) : 0;
} else if (! t1) { /* 1, 2 */
w->old_value = 0;
/* new != NULL */
@@ -1728,7 +1738,7 @@ watchpoint_triggered(struct list_item *w)
w->cur_value = dupnode(t2);
else {
w->flags |= CUR_IS_ARRAY;
- w->cur_size = (t2->type == Node_var_array) ? t2->table_size : 0;
+ w->cur_size = (t2->type == Node_var_array) ? assoc_length(t2) : 0;
}
} else /* if (t1->type == Node_val) */ { /* 4, 5, 6 */
w->old_value = w->cur_value;
@@ -1736,7 +1746,7 @@ watchpoint_triggered(struct list_item *w)
w->cur_value = 0;
else if (t2->type == Node_var_array) {
w->flags |= CUR_IS_ARRAY;
- w->cur_size = t2->table_size;
+ w->cur_size = assoc_length(t2);
} else
w->cur_value = dupnode(t2);
}
@@ -1762,13 +1772,13 @@ initialize_watch_item(struct list_item *w)
w->cur_value = (NODE *) 0;
else if (r->type == Node_var_array) { /* it's a sub-array */
w->flags |= CUR_IS_ARRAY;
- w->cur_size = r->table_size;
+ w->cur_size = assoc_length(r);
} else
w->cur_value = dupnode(r);
} else if (IS_FIELD(w)) {
long field_num;
t = w->symbol;
- field_num = (long) t->numbr;
+ field_num = get_number_si(t);
r = *get_field(field_num, NULL);
w->cur_value = dupnode(r);
} else {
@@ -1779,7 +1789,7 @@ initialize_watch_item(struct list_item *w)
w->cur_value = dupnode(r);
} else if (symbol->type == Node_var_array) {
w->flags |= CUR_IS_ARRAY;
- w->cur_size = symbol->table_size;
+ w->cur_size = assoc_length(symbol);
} /* else
can't happen */
}
@@ -1797,17 +1807,17 @@ do_watch(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
w = do_add_item(&watch_list, arg);
if (w == NULL)
- return FALSE;
+ return false;
if (initialize_watch_item(w) == -1) {
delete_item(w);
- return FALSE;
+ return false;
}
fprintf(out_fp, "Watchpoint %d: ", w->number);
symbol = w->symbol;
-/* FIXME: common code also in print_watch_item */
+ /* FIXME: common code also in print_watch_item */
if (IS_SUBSCRIPT(w)) {
fprintf(out_fp, "%s", w->sname);
for (i = 0; i < w->num_subs; i++) {
@@ -1816,11 +1826,11 @@ do_watch(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
}
fprintf(out_fp, "\n");
} else if (IS_FIELD(w))
- fprintf(out_fp, "$%ld\n", (long) symbol->numbr);
+ fprintf(out_fp, "$%ld\n", get_number_si(symbol));
else
fprintf(out_fp, "%s\n", w->sname);
- return FALSE;
+ return false;
}
/* do_unwatch --- unwatch command */
@@ -1829,7 +1839,7 @@ int
do_unwatch(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
{
do_delete_item(&watch_list, arg);
- return FALSE;
+ return false;
}
/* callback from pop_frame in eval.c */
@@ -1905,7 +1915,7 @@ print_frame(NODE *func, char *src, int srcline)
else {
pf_data.print_func = fprintf;
pf_data.fp = out_fp;
- pf_data.defn = FALSE;
+ pf_data.defn = false;
(void) print_function(func->code_ptr, &pf_data);
}
fprintf(out_fp, _(" at `%s':%d"), src, srcline);
@@ -1918,7 +1928,7 @@ print_numbered_frame(long num)
{
NODE *f;
- assert(prog_running == TRUE);
+ assert(prog_running == true);
f = find_frame(num);
if (num == 0) {
fprintf(out_fp, "#%ld\t ", num);
@@ -1962,7 +1972,7 @@ do_backtrace(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
}
if (cur <= fcall_count)
fprintf(out_fp, _("More stack frames follow ...\n"));
- return FALSE;
+ return false;
}
/* print_cur_frame_and_sourceline --- print current frame, and
@@ -1976,7 +1986,7 @@ print_cur_frame_and_sourceline()
int srcline;
char *src;
- assert(prog_running == TRUE);
+ assert(prog_running == true);
f = find_frame(cur_frame);
if (cur_frame == 0) {
src = source;
@@ -2005,12 +2015,12 @@ do_frame(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
if (arg && arg->type == D_int) {
if (arg->a_int < 0 || arg->a_int > fcall_count) {
d_error(_("invalid frame number"));
- return FALSE;
+ return false;
}
cur_frame = arg->a_int;
}
print_cur_frame_and_sourceline();
- return FALSE;
+ return false;
}
/* do_up --- up command */
@@ -2028,7 +2038,7 @@ do_up(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
else if (cur_frame > fcall_count)
cur_frame = fcall_count;
print_cur_frame_and_sourceline();
- return FALSE;
+ return false;
}
/* do_down --- down command */
@@ -2046,7 +2056,7 @@ do_down(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
else if (cur_frame > fcall_count)
cur_frame = fcall_count;
print_cur_frame_and_sourceline();
- return FALSE;
+ return false;
}
/* find_rule --- find a rule or function in file 'src' containing
@@ -2058,12 +2068,23 @@ find_rule(char *src, long lineno)
{
INSTRUCTION *rp;
- assert(lineno > 0);
- for (rp = rule_list->nexti; rp != NULL; rp = rp->nexti) {
- if ((rp - 1)->source_file == src
- && lineno >= (rp + 1)->first_line
- && lineno <= (rp + 1)->last_line)
- return (rp - 1);
+ /*
+ * FIXME: The check for zero and code that goes with it
+ * are probably fragile. A break with no arguments can
+ * cause this in certain cases. Try to review how this works.
+ */
+ if (lineno == 0) {
+ for (rp = rule_list->nexti; rp != NULL; rp = rp->nexti) {
+ if ((rp - 1)->source_file == src && (rp - 1)->source_line > 0)
+ return (rp - 1);
+ }
+ } else {
+ for (rp = rule_list->nexti; rp != NULL; rp = rp->nexti) {
+ if ((rp - 1)->source_file == src
+ && lineno >= (rp + 1)->first_line
+ && lineno <= (rp + 1)->last_line)
+ return (rp - 1);
+ }
}
return NULL;
}
@@ -2082,7 +2103,7 @@ mk_breakpoint(char *src, int srcline)
emalloc(b, BREAKPOINT *, sizeof(BREAKPOINT), "mk_breakpoint");
memset(&b->cndn, 0, sizeof(struct condition));
b->commands.next = b->commands.prev = &b->commands;
- b->silent = FALSE;
+ b->silent = false;
b->number = ++watch_list.number; /* breakpoints and watchpoints use same counter */
@@ -2126,7 +2147,7 @@ delete_breakpoint(BREAKPOINT *b)
delete_commands_item(c->next);
}
- free_context(b->cndn.ctxt, FALSE);
+ free_context(b->cndn.ctxt, false);
if (b->cndn.expr != NULL)
efree(b->cndn.expr);
@@ -2156,7 +2177,7 @@ find_breakpoint(long num)
/* add_breakpoint --- add a breakpoint instruction between PREVP and IP */
static BREAKPOINT *
-add_breakpoint(INSTRUCTION *prevp, INSTRUCTION *ip, char *src, int silent)
+add_breakpoint(INSTRUCTION *prevp, INSTRUCTION *ip, char *src, bool silent)
{
BREAKPOINT *b;
INSTRUCTION *bp;
@@ -2173,8 +2194,8 @@ add_breakpoint(INSTRUCTION *prevp, INSTRUCTION *ip, char *src, int silent)
* This is more verbose that it might otherwise be,
* in order to provide easily translatable strings.
*/
- if (b->flags & BP_ENABLE) {
- if (b->flags & BP_IGNORE)
+ if ((b->flags & BP_ENABLE) != 0) {
+ if ((b->flags & BP_IGNORE) != 0)
fprintf(out_fp,
_("Note: breakpoint %d (enabled, ignore next %ld hits), also set at %s:%d"),
b->number,
@@ -2188,7 +2209,7 @@ add_breakpoint(INSTRUCTION *prevp, INSTRUCTION *ip, char *src, int silent)
b->src,
lineno);
} else {
- if (b->flags & BP_IGNORE)
+ if ((b->flags & BP_IGNORE) != 0)
fprintf(out_fp,
_("Note: breakpoint %d (disabled, ignore next %ld hits), also set at %s:%d"),
b->number,
@@ -2222,11 +2243,28 @@ add_breakpoint(INSTRUCTION *prevp, INSTRUCTION *ip, char *src, int silent)
/* set_breakpoint_at --- set a breakpoint at given line number*/
static BREAKPOINT *
-set_breakpoint_at(INSTRUCTION *rp, int lineno, int silent)
+set_breakpoint_at(INSTRUCTION *rp, int lineno, bool silent)
{
INSTRUCTION *ip, *prevp;
for (prevp = rp, ip = rp->nexti; ip; prevp = ip, ip = ip->nexti) {
+ if (ip->opcode == Op_K_case) {
+ INSTRUCTION *i1, *i2;
+
+ /* Special case: the code line numbers for a switch do not form
+ * a monotonically increasing sequence. Check if the line # is between
+ * the first and last statements of the case block before continuing
+ * the search.
+ */
+ for (i2 = ip->stmt_start, i1 = i2->nexti; i2 != ip->stmt_end;
+ i2 = i1, i1 = i1->nexti) {
+ if (i1->source_line >= lineno)
+ return add_breakpoint(i2, i1, rp->source_file, silent);
+ if (i1 == ip->stmt_end)
+ break;
+ }
+ }
+
if (ip->source_line >= lineno)
return add_breakpoint(prevp, ip, rp->source_file, silent);
if (ip == (rp + 1)->lasti)
@@ -2249,7 +2287,7 @@ set_breakpoint_next(INSTRUCTION *rp, INSTRUCTION *ip)
ip = ip->nexti;
for (; ip; prevp = ip, ip = ip->nexti) {
if (ip->source_line > 0)
- return add_breakpoint(prevp, ip, rp->source_file, FALSE);
+ return add_breakpoint(prevp, ip, rp->source_file, false);
if (ip == (rp + 1)->lasti)
break;
}
@@ -2259,7 +2297,7 @@ set_breakpoint_next(INSTRUCTION *rp, INSTRUCTION *ip)
/* set_breakpoint --- set a breakpoint */
static int
-set_breakpoint(CMDARG *arg, int temporary)
+set_breakpoint(CMDARG *arg, bool temporary)
{
int lineno;
BREAKPOINT *b = NULL;
@@ -2308,7 +2346,7 @@ set_breakpoint(CMDARG *arg, int temporary)
if (temporary)
b->flags |= BP_TEMP;
}
- return FALSE;
+ return false;
}
/* arg != NULL */
@@ -2319,7 +2357,7 @@ set_breakpoint(CMDARG *arg, int temporary)
arg = arg->next;
if (s == NULL || arg == NULL
|| (arg->type != D_int && arg->type != D_func))
- return FALSE;
+ return false;
src = s->src;
if (arg->type == D_func) /* break filename:function */
goto func;
@@ -2333,7 +2371,7 @@ set_breakpoint(CMDARG *arg, int temporary)
rp = find_rule(src, lineno);
if (rp == NULL)
fprintf(out_fp, _("Can't find rule!!!\n"));
- if (rp == NULL || (b = set_breakpoint_at(rp, lineno, FALSE)) == NULL)
+ if (rp == NULL || (b = set_breakpoint_at(rp, lineno, false)) == NULL)
fprintf(out_fp, _("Can't set breakpoint at `%s':%d\n"),
src, lineno);
if (b != NULL && temporary)
@@ -2345,7 +2383,7 @@ set_breakpoint(CMDARG *arg, int temporary)
func:
func = arg->a_node;
rp = func->code_ptr;
- if ((b = set_breakpoint_at(rp, rp->source_line, FALSE)) == NULL)
+ if ((b = set_breakpoint_at(rp, rp->source_line, false)) == NULL)
fprintf(out_fp, _("Can't set breakpoint in function `%s'\n"),
func->vname);
else if (temporary)
@@ -2354,7 +2392,7 @@ func:
break;
default:
- return FALSE;
+ return false;
}
/* condition if any */
arg = arg->next;
@@ -2365,7 +2403,7 @@ func:
fprintf(out_fp, _("breakpoint %d set at file `%s', line %d is unconditional\n"),
b->number, src, lineno);
}
- return FALSE;
+ return false;
}
@@ -2386,7 +2424,7 @@ breakpoint_triggered(BREAKPOINT *b)
return 0;
b->hit_count++;
- if (b->flags & BP_ENABLE_ONCE) {
+ if ((b->flags & BP_ENABLE_ONCE) != 0) {
b->flags &= ~BP_ENABLE_ONCE;
b->flags &= ~BP_ENABLE;
}
@@ -2398,7 +2436,7 @@ breakpoint_triggered(BREAKPOINT *b)
int
do_breakpoint(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
{
- return set_breakpoint(arg, FALSE);
+ return set_breakpoint(arg, false);
}
/* do_tmp_breakpoint --- tbreak command */
@@ -2406,7 +2444,7 @@ do_breakpoint(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
int
do_tmp_breakpoint(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
{
- return set_breakpoint(arg, TRUE);
+ return set_breakpoint(arg, true);
}
/* do_clear --- clear command */
@@ -2420,7 +2458,7 @@ do_clear(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
NODE *func;
SRCFILE *s = cur_srcfile;
char *src = cur_srcfile->src;
- int bp_found = FALSE;
+ bool bp_found = false;
if (arg == NULL) { /* clear */
CHECK_PROG_RUNNING();
@@ -2442,7 +2480,7 @@ do_clear(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
arg = arg->next;
if (s == NULL || arg == NULL ||
(arg->type != D_int && arg->type != D_func))
- return FALSE;
+ return false;
src = s->src;
if (arg->type == D_func)
goto func;
@@ -2452,7 +2490,7 @@ do_clear(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
lineno = (int) arg->a_int;
if (lineno <= 0 || lineno > s->srclines) {
d_error(_("line number %d in file `%s' out of range"), lineno, src);
- return FALSE;
+ return false;
}
break;
@@ -2479,7 +2517,7 @@ func:
fprintf(out_fp, "\n");
/* fall through */
default:
- return FALSE;
+ return false;
}
delete_bp:
@@ -2504,7 +2542,7 @@ delete_bp:
src, (int) lineno);
else
fprintf(out_fp, "\n");
- return FALSE;
+ return false;
}
/* enable_breakpoint --- enable a breakpoint and set its disposition */
@@ -2560,7 +2598,7 @@ do_enable_breakpoint(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
enable_breakpoint(b, disp);
}
}
- return FALSE;
+ return false;
}
/* do_delete_breakpoint --- delete command */
@@ -2569,10 +2607,10 @@ int
do_delete_breakpoint(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
{
if (arg == NULL) {
- int delete_all = TRUE;
+ bool delete_all = true;
delete_all = prompt_yes_no(
_("Delete all breakpoints? (y or n) "),
- _("y")[0], TRUE, out_fp);
+ _("y")[0], true, out_fp);
if (delete_all) {
while (breakpoints.next != &breakpoints)
@@ -2601,7 +2639,7 @@ do_delete_breakpoint(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
delete_breakpoint(b);
}
}
- return FALSE;
+ return false;
}
/* do_ignore_breakpoint --- ignore command */
@@ -2613,7 +2651,7 @@ do_ignore_breakpoint(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
if (arg == NULL || arg->type != D_int
|| arg->next == NULL || arg->next->type != D_int)
- return FALSE;
+ return false;
if ((b = find_breakpoint(arg->a_int)) == NULL)
d_error(_("invalid breakpoint number"));
@@ -2629,7 +2667,7 @@ do_ignore_breakpoint(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
b->number);
}
}
- return FALSE;
+ return false;
}
/* do_disable_breakpoint --- disable command */
@@ -2664,7 +2702,7 @@ do_disable_breakpoint(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
b->flags &= ~BP_ENABLE;
}
}
- return FALSE;
+ return false;
}
#ifdef HAVE_LIBREADLINE
@@ -2705,17 +2743,26 @@ initialize_readline()
#endif
-/* interpret --- debugger entry point */
+/* init_debug --- register debugger exec hooks */
+
+void
+init_debug()
+{
+ register_exec_hook(debug_pre_execute, debug_post_execute);
+}
+
+
+/* debug_prog --- debugger entry point */
int
-interpret(INSTRUCTION *pc)
+debug_prog(INSTRUCTION *pc)
{
char *run;
input_fd = fileno(stdin);
out_fp = stdout;
if (os_isatty(input_fd))
- input_from_tty = TRUE;
+ input_from_tty = true;
if (input_fd == 0 && input_from_tty)
initialize_readline();
@@ -2737,8 +2784,8 @@ interpret(INSTRUCTION *pc)
exit(EXIT_FAILURE);
}
- dgawk_Prompt = estrdup(DEFAULT_PROMPT, strlen(DEFAULT_PROMPT));
- dPrompt = dgawk_Prompt;
+ dgawk_prompt = estrdup(DEFAULT_PROMPT, strlen(DEFAULT_PROMPT));
+ dbg_prompt = dgawk_prompt;
memset(&stop, 0, sizeof(stop));
stop.command = D_illegal;
@@ -2754,11 +2801,11 @@ interpret(INSTRUCTION *pc)
unserialize(OPTION);
unsetenv("DGAWK_RESTART");
fprintf(out_fp, "Restarting ...\n");
- if (run[0] == 'T')
+ if (strcasecmp(run, "true") == 0)
(void) do_run(NULL, 0);
} else if (command_file != NULL) {
- /* run commands from a file (--command=file or -R file) */
+ /* run commands from a file (--debug=file or -D file) */
int fd;
fd = open_readfd(command_file);
if (fd == INVALID_HANDLE) {
@@ -2766,7 +2813,7 @@ interpret(INSTRUCTION *pc)
command_file, strerror(errno));
exit(EXIT_FAILURE);
}
- push_cmd_src(fd, FALSE, g_readline, close, 0, EXIT_FAILURE);
+ push_cmd_src(fd, false, g_readline, close, 0, EXIT_FAILURE);
cmd_src->str = estrdup(command_file, strlen(command_file));
} else {
@@ -2780,7 +2827,7 @@ interpret(INSTRUCTION *pc)
/* read saved options */
fd = open_readfd(options_file);
if (fd > INVALID_HANDLE)
- push_cmd_src(fd, FALSE, g_readline, close, 0, EXIT_SUCCESS);
+ push_cmd_src(fd, false, g_readline, close, 0, EXIT_SUCCESS);
}
/* start the command interpreter */
@@ -2799,16 +2846,16 @@ check_watchpoint()
struct list_item *w;
if (stop.command == D_return)
- return FALSE;
+ return false;
for (w = watch_list.prev; w != &watch_list; w = w->prev) {
int wnum = watchpoint_triggered(w);
if (wnum > 0) {
stop.watch_point = wnum;
- stop.print_frame = TRUE;
- return TRUE;
+ stop.print_frame = true;
+ return true;
}
}
- return FALSE;
+ return false;
}
/* check_breakpoint --- check if breakpoint triggered */
@@ -2820,7 +2867,7 @@ check_breakpoint(INSTRUCTION **pi)
pc = *pi;
if (stop.command == D_return)
- return FALSE;
+ return false;
if (pc->opcode == Op_breakpoint) {
int bnum;
*pi = pc->nexti; /* skip past the breakpoint instruction;
@@ -2829,17 +2876,17 @@ check_breakpoint(INSTRUCTION **pi)
bnum = breakpoint_triggered(pc->break_pt);
if (bnum > 0) {
stop.break_point = bnum;
- stop.print_frame = TRUE;
- return TRUE;
+ stop.print_frame = true;
+ return true;
}
}
- return FALSE;
+ return false;
}
/* restart --- restart the debugger */
static void
-restart(int run)
+restart(bool run)
{
/* save state in the environment after serialization */
serialize(BREAK);
@@ -2849,7 +2896,7 @@ restart(int run)
serialize(OPTION);
/* tell the new process to restore state from the environment */
- setenv("DGAWK_RESTART", (run ? "TRUE" : "FALSE"), 1);
+ setenv("DGAWK_RESTART", (run ? "true" : "false"), 1);
/* close all open files */
close_all();
@@ -2869,15 +2916,15 @@ do_run(CMDARG *arg ATTRIBUTE_UNUSED, int cmd ATTRIBUTE_UNUSED)
{
if (prog_running) {
if (! input_from_tty)
- need_restart = TRUE; /* handled later */
+ need_restart = true; /* handled later */
else {
need_restart = prompt_yes_no(
_("Program already running. Restart from beginning (y/n)? "),
- _("y")[0], FALSE, out_fp);
+ _("y")[0], false, out_fp);
if (! need_restart) {
fprintf(out_fp, _("Program not restarted\n"));
- return FALSE;
+ return false;
}
}
}
@@ -2885,36 +2932,36 @@ do_run(CMDARG *arg ATTRIBUTE_UNUSED, int cmd ATTRIBUTE_UNUSED)
if (need_restart) {
/* avoid endless cycles of restarting */
if (command_file != NULL) {
- /* input_from_tty = FALSE */
+ /* input_from_tty = false */
fprintf(stderr, _("error: cannot restart, operation not allowed\n"));
exit(EXIT_FAILURE);
}
if (cmd_src->cmd == D_source) {
- /* input_from_tty = FALSE */
+ /* input_from_tty = false */
fprintf(out_fp, _("error (%s): cannot restart, ignoring rest of the commands\n"), cmd_src->str);
pop_cmd_src();
- return FALSE;
+ return false;
}
- restart(TRUE); /* does not return */
+ restart(true); /* does not return */
}
fprintf(out_fp, _("Starting program: \n"));
- prog_running = TRUE;
- fatal_tag_valid = TRUE;
+ prog_running = true;
+ fatal_tag_valid = true;
if (setjmp(fatal_tag) == 0)
- (void) r_interpret(code_block);
+ (void) interpret(code_block);
- fatal_tag_valid = FALSE;
- prog_running = FALSE;
+ fatal_tag_valid = false;
+ prog_running = false;
fprintf(out_fp, _("Program exited %s with exit value: %d\n"),
(! exiting && exit_val != EXIT_SUCCESS) ? "abnormally"
: "normally",
exit_val);
- need_restart = TRUE;
- return FALSE;
+ need_restart = true;
+ return false;
}
/* do_quit --- quit command */
@@ -2922,14 +2969,14 @@ do_run(CMDARG *arg ATTRIBUTE_UNUSED, int cmd ATTRIBUTE_UNUSED)
int
do_quit(CMDARG *arg ATTRIBUTE_UNUSED, int cmd ATTRIBUTE_UNUSED)
{
- int terminate = TRUE;
+ bool terminate = true;
if (prog_running)
terminate = prompt_yes_no(
_("The program is running. Exit anyway (y/n)? "),
- _("y")[0], TRUE, out_fp);
+ _("y")[0], true, out_fp);
if (terminate) {
close_all();
- do_trace = FALSE; /* don't save 'trace on' */
+ do_trace = false; /* don't save 'trace on' */
#ifdef HAVE_LIBREADLINE
if (do_save_history && input_from_tty) {
@@ -2944,7 +2991,7 @@ do_quit(CMDARG *arg ATTRIBUTE_UNUSED, int cmd ATTRIBUTE_UNUSED)
exit(exit_val);
}
- return FALSE;
+ return false;
}
/* do_continue --- continue command */
@@ -2956,23 +3003,23 @@ do_continue(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
CHECK_PROG_RUNNING();
if (! arg || arg->type != D_int)
- return TRUE;
+ return true;
/* arg is breakpoint ignore count if stopped at a breakpoint */
if (! stop.break_point) {
fprintf(out_fp, _("Not stopped at any breakpoint; argument ignored.\n"));
- return TRUE;
+ return true;
}
b = find_breakpoint(stop.break_point);
if (b == NULL) {
d_error(_("invalid breakpoint number %d."), stop.break_point);
- return FALSE;
+ return false;
}
b->flags |= BP_IGNORE;
b->ignore_count = arg->a_int;
fprintf(out_fp, _("Will ignore next %ld crossings of breakpoint %d.\n"),
b->ignore_count, stop.break_point);
- return TRUE;
+ return true;
}
/* next_step --- common code for next and step commands */
@@ -2986,10 +3033,10 @@ next_step(CMDARG *arg, int cmd)
else
stop.repeat_count = 1;
stop.command = cmd;
- return TRUE;
+ return true;
}
-/* check_step --- process step command, return TRUE if stopping */
+/* check_step --- process step command, return true if stopping */
static int
check_step(INSTRUCTION **pi)
@@ -2998,7 +3045,7 @@ check_step(INSTRUCTION **pi)
stop.fcall_count = fcall_count;
stop.sourceline = sourceline;
stop.source = source;
- stop.print_frame = TRUE;
+ stop.print_frame = true;
return (--stop.repeat_count == 0);
}
@@ -3012,10 +3059,10 @@ check_step(INSTRUCTION **pi)
stop.sourceline = sourceline;
return (--stop.repeat_count == 0);
}
- return FALSE;
+ return false;
}
-/* do_step -- process step command, return TRUE if stopping */
+/* do_step -- process step command, return true if stopping */
int
do_step(CMDARG *arg, int cmd)
@@ -3031,7 +3078,7 @@ do_step(CMDARG *arg, int cmd)
return ret;
}
-/* do_stepi -- process stepi command, return TRUE if stopping */
+/* do_stepi -- process stepi command, return true if stopping */
static int
check_stepi(INSTRUCTION **pi)
@@ -3052,7 +3099,7 @@ do_stepi(CMDARG *arg, int cmd)
}
-/* check_next -- process next command returning TRUE if stopping */
+/* check_next -- process next command returning true if stopping */
static int
check_next(INSTRUCTION **pi)
@@ -3063,7 +3110,7 @@ check_next(INSTRUCTION **pi)
stop.fcall_count = fcall_count;
stop.sourceline = sourceline;
stop.source = source;
- stop.print_frame = TRUE;
+ stop.print_frame = true;
return (--stop.repeat_count == 0);
}
@@ -3087,7 +3134,7 @@ check_next(INSTRUCTION **pi)
}
#endif
- return FALSE;
+ return false;
}
/* do_next -- next command */
@@ -3107,7 +3154,7 @@ do_next(CMDARG *arg, int cmd)
return ret;
}
-/* check_nexti --- process nexti command, returns TRUE if stopping */
+/* check_nexti --- process nexti command, returns true if stopping */
static int
check_nexti(INSTRUCTION **pi)
@@ -3115,7 +3162,7 @@ check_nexti(INSTRUCTION **pi)
/* make sure not to step inside function calls */
if (fcall_count < stop.fcall_count) {
- stop.print_frame = TRUE;
+ stop.print_frame = true;
stop.fcall_count = fcall_count;
}
return (fcall_count == stop.fcall_count
@@ -3137,16 +3184,16 @@ do_nexti(CMDARG *arg, int cmd)
return ret;
}
-/* check_finish --- process finish command, returns TRUE if stopping */
+/* check_finish --- process finish command, returns true if stopping */
static int
check_finish(INSTRUCTION **pi)
{
if (fcall_count == stop.fcall_count) {
- stop.print_frame = TRUE;
- return TRUE;
+ stop.print_frame = true;
+ return true;
}
- return FALSE;
+ return false;
}
/* do_finish --- finish command */
@@ -3158,7 +3205,7 @@ do_finish(CMDARG *arg ATTRIBUTE_UNUSED, int cmd)
if (cur_frame == fcall_count) {
fprintf(out_fp,
_("'finish' not meaningful in the outermost frame main()\n"));
- return FALSE;
+ return false;
}
stop.fcall_count = fcall_count - cur_frame - 1;
assert(stop.fcall_count >= 0);
@@ -3166,11 +3213,11 @@ do_finish(CMDARG *arg ATTRIBUTE_UNUSED, int cmd)
print_numbered_frame(cur_frame);
stop.check_func = check_finish;
stop.command = cmd;
- stop.print_ret = TRUE;
- return TRUE;
+ stop.print_ret = true;
+ return true;
}
-/* check_return --- process return, returns TRUE if stopping */
+/* check_return --- process return, returns true if stopping */
static int
check_return(INSTRUCTION **pi)
@@ -3178,8 +3225,8 @@ check_return(INSTRUCTION **pi)
assert(fcall_count >= stop.fcall_count);
if (fcall_count == stop.fcall_count) {
- stop.print_frame = TRUE;
- return TRUE;
+ stop.print_frame = true;
+ return true;
}
if (fcall_count > stop.fcall_count) { /* innermost frame just returned */
@@ -3192,7 +3239,7 @@ check_return(INSTRUCTION **pi)
/* assert((*pi)->opcode == Op_K_return); */
}
- return FALSE;
+ return false;
}
/* do_return --- return command */
@@ -3206,7 +3253,7 @@ do_return(CMDARG *arg, int cmd)
func = find_frame(cur_frame)->func_node;
if (func == NULL) {
fprintf(out_fp, _("'return' not meaningful in the outermost frame main()\n"));
- return FALSE;
+ return false;
}
stop.fcall_count = fcall_count - cur_frame - 1;
@@ -3223,26 +3270,26 @@ do_return(CMDARG *arg, int cmd)
n = dupnode(Nnull_string);
PUSH(n);
- return TRUE;
+ return true;
}
-/* check_until --- process until, returns TRUE if stopping */
+/* check_until --- process until, returns true if stopping */
int
check_until(INSTRUCTION **pi)
{
if (fcall_count < stop.fcall_count) { /* current stack frame returned */
- stop.print_frame = TRUE;
- return TRUE;
+ stop.print_frame = true;
+ return true;
} else if (fcall_count == stop.fcall_count) {
if (stop.pc && *pi == stop.pc) /* until location */
- return TRUE;
+ return true;
if (stop.sourceline > 0 /* until */
&& source == stop.source
&& sourceline > stop.sourceline)
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
/* do_until --- until command */
@@ -3277,7 +3324,7 @@ do_until(CMDARG *arg, int cmd)
stop.fcall_count = fcall_count - cur_frame;
stop.check_func = check_until;
stop.command = cmd;
- return TRUE;
+ return true;
}
/* GDB: until location - continue running program until
@@ -3291,7 +3338,7 @@ do_until(CMDARG *arg, int cmd)
arg = arg->next;
if (s == NULL || arg == NULL
|| (arg->type != D_int && arg->type != D_func))
- return FALSE;
+ return false;
src = s->src;
if (arg->type == D_func)
goto func;
@@ -3302,7 +3349,7 @@ do_until(CMDARG *arg, int cmd)
if (lineno <= 0 || lineno > s->srclines) {
d_error(_("line number %d in file `%s' out of range"),
lineno, src);
- return FALSE;
+ return false;
}
break;
@@ -3316,19 +3363,19 @@ func:
stop.fcall_count = fcall_count - cur_frame;
stop.check_func = check_until;
stop.command = cmd;
- return TRUE;
+ return true;
}
}
fprintf(out_fp, _("Can't find specified location in function `%s'\n"),
func->vname);
/* fall through */
default:
- return FALSE;
+ return false;
}
if ((rp = find_rule(src, lineno)) == NULL) {
d_error(_("invalid source line %d in file `%s'"), lineno, src);
- return FALSE;
+ return false;
}
for (ip = rp->nexti; ip; ip = ip->nexti) {
@@ -3337,14 +3384,14 @@ func:
stop.fcall_count = fcall_count - cur_frame;
stop.check_func = check_until;
stop.command = cmd;
- return TRUE;
+ return true;
}
if (ip == (rp + 1)->lasti)
break;
}
fprintf(out_fp, _("Can't find specified location %d in file `%s'\n"),
lineno, src);
- return FALSE;
+ return false;
}
/* print_watch_item --- print watched item name, old and current values */
@@ -3364,7 +3411,7 @@ print_watch_item(struct list_item *w)
}
fprintf(out_fp, "\n");
} else if (IS_FIELD(w))
- fprintf(out_fp, "$%ld\n", (long) symbol->numbr);
+ fprintf(out_fp, "$%ld\n", get_number_si(symbol));
else
fprintf(out_fp, "%s\n", w->sname);
@@ -3379,9 +3426,9 @@ else \
valinfo(w->V, fprintf, out_fp);
fprintf(out_fp, " Old value: ");
- print_value((w->flags & OLD_IS_ARRAY), old_size, old_value);
+ print_value((w->flags & OLD_IS_ARRAY) != 0, old_size, old_value);
fprintf(out_fp, " New value: ");
- print_value((w->flags & CUR_IS_ARRAY), cur_size, cur_value);
+ print_value((w->flags & CUR_IS_ARRAY) != 0, cur_size, cur_value);
#undef print_value
}
@@ -3431,7 +3478,7 @@ next_command()
if (stop.print_frame) {
print_frame(frame_ptr->func_node, source, sourceline);
fprintf(out_fp, "\n");
- stop.print_frame = FALSE;
+ stop.print_frame = false;
}
(void) print_lines(source, sourceline, 1);
@@ -3475,10 +3522,10 @@ no_output:
read_command(); /* zzparse */
}
-/* post_execute --- post_hook in the interpreter */
+/* debug_post_execute --- post_hook in the interpreter */
-void
-post_execute(INSTRUCTION *pc)
+static void
+debug_post_execute(INSTRUCTION *pc)
{
if (! in_main_context())
return;
@@ -3489,15 +3536,15 @@ post_execute(INSTRUCTION *pc)
case Op_K_exit:
if (stop.command == D_finish) {
/* cancel finish command */
- stop.print_ret = FALSE;
- stop.print_frame = FALSE;
+ stop.print_ret = false;
+ stop.print_frame = false;
stop.command = D_illegal;
stop.check_func = NULL;
fprintf(out_fp, _("'finish' not meaningful with non-local jump '%s'\n"),
op2str(pc->opcode));
} else if (stop.command == D_until) {
/* cancel until command */
- stop.print_frame = FALSE;
+ stop.print_frame = false;
stop.command = D_illegal;
stop.check_func = NULL;
fprintf(out_fp, _("'until' not meaningful with non-local jump '%s'\n"),
@@ -3515,7 +3562,7 @@ post_execute(INSTRUCTION *pc)
r = TOP();
fprintf(out_fp, "Returned value = ");
valinfo(r, fprintf, out_fp);
- stop.print_ret = FALSE;
+ stop.print_ret = false;
}
break;
@@ -3528,15 +3575,15 @@ post_execute(INSTRUCTION *pc)
}
}
-/* pre_execute --- pre_hook, called by the interpreter before execution;
+/* debug_pre_execute --- pre_hook, called by the interpreter before execution;
* checks if execution needs to be suspended and control
* transferred to the debugger.
*/
-int
-pre_execute(INSTRUCTION **pi)
+static int
+debug_pre_execute(INSTRUCTION **pi)
{
- static int cant_stop = FALSE;
+ static bool cant_stop = false;
NODE *m;
if (! in_main_context())
@@ -3551,7 +3598,7 @@ pre_execute(INSTRUCTION **pi)
&& cur_pc->opcode != Op_breakpoint
&& stop.command != D_return
)
- print_instruction(cur_pc, fprintf, out_fp, FALSE);
+ print_instruction(cur_pc, fprintf, out_fp, false);
/* N.B.: For Op_field_spec_lhs must execute instructions upto Op_field_assign
* as a group before stopping. Otherwise, watch/print of field variables
@@ -3561,48 +3608,48 @@ pre_execute(INSTRUCTION **pi)
switch (cur_pc->opcode) {
case Op_field_spec_lhs:
- cant_stop = TRUE;
+ cant_stop = true;
break;
case Op_field_assign:
- cant_stop = FALSE;
- return TRUE; /* may stop at next instruction */
+ cant_stop = false;
+ return true; /* may stop at next instruction */
case Op_push_lhs:
m = cur_pc->memory;
if (m->type == Node_var && m->var_assign)
- cant_stop = TRUE;
+ cant_stop = true;
break;
case Op_arrayfor_incr: /* can have special var as array variable !!! */
m = cur_pc->array_var;
if (m->type == Node_var && m->var_assign)
- cant_stop = TRUE;
+ cant_stop = true;
break;
case Op_var_assign:
- cant_stop = FALSE;
- return TRUE; /* may stop at next instruction */
+ cant_stop = false;
+ return true; /* may stop at next instruction */
case Op_rule:
cur_rule = cur_pc->in_rule;
- return TRUE;
+ return true;
case Op_func:
case Op_var_update:
- return TRUE;
+ return true;
case Op_breakpoint:
break; /* processed later in check_breakpoint() */
default:
if (cur_pc->source_line <= 0)
- return TRUE;
+ return true;
break;
}
if (cant_stop)
- return TRUE;
+ return true;
assert(sourceline > 0);
@@ -3626,42 +3673,56 @@ static void
print_memory(NODE *m, NODE *func, Func_print print_func, FILE *fp)
{
switch (m->type) {
- case Node_val:
- if (m == Nnull_string)
- print_func(fp, "Nnull_string");
- else if ((m->flags & NUMBER) != 0)
- print_func(fp, "%g", m->numbr);
- else if ((m->flags & STRING) != 0)
- pp_string_fp(print_func, fp, m->stptr, m->stlen, '"', FALSE);
- else if ((m->flags & NUMCUR) != 0)
+ case Node_val:
+ if (m == Nnull_string)
+ print_func(fp, "Nnull_string");
+ else if ((m->flags & NUMBER) != 0) {
+#ifdef HAVE_MPFR
+ if ((m->flags & MPFN) != 0)
+ print_func(fp, "%s", mpg_fmt("%R*g", ROUND_MODE, m->mpg_numbr));
+ else if ((m->flags & MPZN) != 0)
+ print_func(fp, "%s", mpg_fmt("%Zd", m->mpg_i));
+ else
+#endif
print_func(fp, "%g", m->numbr);
- else if ((m->flags & STRCUR) != 0)
- pp_string_fp(print_func, fp, m->stptr, m->stlen, '"', FALSE);
+ } else if ((m->flags & STRING) != 0)
+ pp_string_fp(print_func, fp, m->stptr, m->stlen, '"', false);
+ else if ((m->flags & NUMCUR) != 0) {
+#ifdef HAVE_MPFR
+ if ((m->flags & MPFN) != 0)
+ print_func(fp, "%s", mpg_fmt("%R*g", ROUND_MODE, m->mpg_numbr));
+ else if ((m->flags & MPZN) != 0)
+ print_func(fp, "%s", mpg_fmt("%Zd", m->mpg_i));
else
- print_func(fp, "-?-");
- print_func(fp, " [%s]", flags2str(m->flags));
- break;
+#endif
+ print_func(fp, "%g", m->numbr);
+ } else if ((m->flags & STRCUR) != 0)
+ pp_string_fp(print_func, fp, m->stptr, m->stlen, '"', false);
+ else
+ print_func(fp, "-?-");
+ print_func(fp, " [%s]", flags2str(m->flags));
+ break;
- case Node_regex:
- pp_string_fp(print_func, fp, m->re_exp->stptr, m->re_exp->stlen, '/', FALSE);
- break;
+ case Node_regex:
+ pp_string_fp(print_func, fp, m->re_exp->stptr, m->re_exp->stlen, '/', false);
+ break;
- case Node_dynregex:
- break;
-
- case Node_param_list:
- assert(func != NULL);
- print_func(fp, "%s", func->fparms[m->param_cnt].param);
- break;
+ case Node_dynregex:
+ break;
+
+ case Node_param_list:
+ assert(func != NULL);
+ print_func(fp, "%s", func->fparms[m->param_cnt].param);
+ break;
- case Node_var:
- case Node_var_new:
- case Node_var_array:
- print_func(fp, "%s", m->vname);
- break;
+ case Node_var:
+ case Node_var_new:
+ case Node_var_array:
+ print_func(fp, "%s", m->vname);
+ break;
- default:
- print_func(fp, "?"); /* can't happen */
+ default:
+ print_func(fp, "?"); /* can't happen */
}
}
@@ -3677,7 +3738,8 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump)
if (noffset == 0) {
static char buf[50];
/* offset for 2nd to last lines in a multi-line output */
- noffset = sprintf(buf, "[ :%p] %-20.20s: ", pc, opcode2str(pc->opcode));
+ noffset = sprintf(buf, "[ :%p] %-20.20s: ", (void *) pc,
+ opcode2str(pc->opcode));
}
if (pc->opcode == Op_func) {
@@ -3732,7 +3794,7 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump)
case Op_field_spec_lhs:
print_func(fp, "[target_assign = %p] [do_reference = %s]\n",
- pc->target_assign, pc->do_reference ? "TRUE" : "FALSE");
+ pc->target_assign, pc->do_reference ? "true" : "false");
break;
case Op_func:
@@ -3742,12 +3804,12 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump)
case Op_K_getline_redir:
print_func(fp, "[into_var = %s] [redir_type = \"%s\"]\n",
- pc->into_var ? "TRUE" : "FALSE",
+ pc->into_var ? "true" : "false",
redir2str(pc->redir_type));
break;
case Op_K_getline:
- print_func(fp, "[into_var = %s]\n", pc->into_var ? "TRUE" : "FALSE");
+ print_func(fp, "[into_var = %s]\n", pc->into_var ? "true" : "false");
print_func(fp, "%*s[target_beginfile = %p] [target_endfile = %p]\n",
noffset, "",
(pc + 1)->target_beginfile, (pc + 1)->target_endfile);
@@ -3803,7 +3865,7 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump)
case Op_K_case:
print_func(fp, "[target_jmp = %p] [match_exp = %s]\n",
- pc->target_jmp, (pc + 1)->match_exp ? "TRUE" : "FALSE");
+ pc->target_jmp, (pc + 1)->match_exp ? "true" : "false");
break;
case Op_arrayfor_incr:
@@ -3833,9 +3895,9 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump)
{ 0, NULL }
};
- if (pc->sub_flags & GSUB)
+ if ((pc->sub_flags & GSUB) != 0)
fname = "gsub";
- else if (pc->sub_flags & GENSUB)
+ else if ((pc->sub_flags & GENSUB) != 0)
fname = "gensub";
print_func(fp, "%s [arg_count = %ld] [sub_flags = %s]\n",
fname, pc->expr_count,
@@ -3866,7 +3928,7 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump)
case Op_subscript_lhs:
print_func(fp, "[sub_count = %ld] [do_reference = %s]\n",
pc->sub_count,
- pc->do_reference ? "TRUE" : "FALSE");
+ pc->do_reference ? "true" : "false");
break;
case Op_K_delete:
@@ -3878,7 +3940,7 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump)
/* NB: concat_flag CSVAR only used in grammar, don't display it */
print_func(fp, "[expr_count = %ld] [concat_flag = %s]\n",
pc->expr_count,
- (pc->concat_flag & CSUBSEP) ? "CSUBSEP" : "0");
+ (pc->concat_flag & CSUBSEP) != 0 ? "CSUBSEP" : "0");
break;
case Op_rule:
@@ -3914,7 +3976,7 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump)
case Op_push_lhs:
print_memory(pc->memory, func, print_func, fp);
print_func(fp, " [do_reference = %s]\n",
- pc->do_reference ? "TRUE" : "FALSE");
+ pc->do_reference ? "true" : "false");
break;
case Op_push_i:
@@ -3933,6 +3995,7 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump)
case Op_quotient_i:
case Op_mod_i:
case Op_assign_concat:
+ case Op_comment:
print_memory(pc->memory, func, print_func, fp);
/* fall through */
default:
@@ -3948,10 +4011,10 @@ do_trace_instruction(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
{
if (arg != NULL && arg->type == D_argument
&& arg->a_argument == A_TRACE_ON)
- do_trace = TRUE;
+ do_trace = true;
else
- do_trace = FALSE;
- return FALSE;
+ do_trace = false;
+ return false;
}
/* print_code --- print a list of instructions */
@@ -3978,34 +4041,34 @@ do_dump_instructions(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
if ((fp = fopen(arg->a_string, "w")) == NULL) {
d_error(_("could not open `%s' for writing (%s)"),
arg->a_string, strerror(errno));
- return FALSE;
+ return false;
}
pf_data.print_func = fprintf;
pf_data.fp = fp;
- pf_data.defn = TRUE; /* in_dump = TRUE */
+ pf_data.defn = true; /* in_dump = true */
(void) print_code(code_block, &pf_data);
- funcs = function_list(TRUE);
+ funcs = function_list(true);
(void) foreach_func(funcs,
(int (*)(INSTRUCTION *, void *)) print_code,
&pf_data);
efree(funcs);
fclose(fp);
- return FALSE;
+ return false;
}
- funcs = function_list(TRUE);
+ funcs = function_list(true);
initialize_pager(out_fp);
if (setjmp(pager_quit_tag) == 0) {
pf_data.print_func = gprintf;
pf_data.fp = out_fp;
- pf_data.defn = TRUE; /* in_dump = TRUE */
+ pf_data.defn = true; /* in_dump = true */
(void) print_code(code_block, &pf_data);
(void) foreach_func(funcs,
(int (*)(INSTRUCTION *, void *)) print_code,
&pf_data);
}
efree(funcs);
- return FALSE;
+ return false;
}
/* do_save --- save command */
@@ -4013,7 +4076,7 @@ do_dump_instructions(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
int
do_save(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
{
-#ifdef HAVE_LIBREADLINE
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_HISTORY_LIST)
FILE *fp;
HIST_ENTRY **hist_list;
int i;
@@ -4021,7 +4084,7 @@ do_save(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
if ((fp = fopen(arg->a_string, "w")) == NULL) {
d_error(_("could not open `%s' for writing (%s)"),
arg->a_string, strerror(errno));
- return FALSE;
+ return false;
}
hist_list = history_list();
@@ -4036,7 +4099,7 @@ do_save(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
*/
if (strlen(line) > 1
- && STREQN(line, "sa", 2))
+ && strncmp(line, "sa", 2) == 0)
continue;
fprintf(fp, "%s\n", line);
@@ -4044,7 +4107,7 @@ do_save(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
}
fclose(fp);
#endif
- return FALSE;
+ return false;
}
/* do_option --- option command */
@@ -4062,7 +4125,7 @@ do_option(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
else
fprintf(out_fp, "%s = %d\n", opt->name, *(opt->num_val));
}
- return FALSE;
+ return false;
}
name = arg->a_string;
@@ -4070,11 +4133,11 @@ do_option(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
value = arg ? arg->a_string : NULL;
for (opt = option_list; opt->name; opt++) { /* linear search */
- if (STREQ(name, opt->name))
+ if (strcmp(name, opt->name) == 0)
break;
}
if (! opt->name)
- return FALSE;
+ return false;
if (value == NULL) { /* display current setting */
if (opt->str_val != NULL)
@@ -4083,7 +4146,7 @@ do_option(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
fprintf(out_fp, "%s = %d\n", opt->name, *(opt->num_val));
} else
(*(opt->assign))(value);
- return FALSE;
+ return false;
}
@@ -4116,12 +4179,12 @@ initialize_pager(FILE *fp)
static void
prompt_continue(FILE *fp)
{
- int quit_pager = FALSE;
+ bool quit_pager = false;
if (os_isatty(fileno(fp)) && input_fd == 0)
quit_pager = prompt_yes_no(
_("\t------[Enter] to continue or q [Enter] to quit------"),
- _("q")[0], FALSE, fp);
+ _("q")[0], false, fp);
if (quit_pager)
longjmp(pager_quit_tag, 1);
pager_lines_printed = 0;
@@ -4149,7 +4212,7 @@ gprintf(FILE *fp, const char *format, ...)
}
#undef GPRINTF_BUFSIZ
- while (TRUE) {
+ while (true) {
va_start(args, format);
nchar = vsnprintf(buf + bl, buflen - bl, format, args);
va_end(args);
@@ -4237,11 +4300,6 @@ serialize_subscript(char *buf, int buflen, struct list_item *item)
static void
serialize(int type)
{
-#ifndef HAVE_LIBREADLINE
-#define HIST_ENTRY void
-#define history_list() NULL
-#endif
-
static char *buf = NULL;
static int buflen = 0;
int bl;
@@ -4346,7 +4404,7 @@ enlarge_buffer:
nchar = serialize_subscript(buf + bl, buflen - bl, wd);
else if (IS_FIELD(wd))
nchar = snprintf(buf + bl, buflen - bl, "%d%c%d%c%d%c",
- wd->number, FSEP, D_field, FSEP, (int) wd->symbol->numbr, FSEP);
+ wd->number, FSEP, D_field, FSEP, (int) get_number_si(wd->symbol), FSEP);
else
nchar = snprintf(buf + bl, buflen - bl, "%d%c%d%c%s%c",
wd->number, FSEP, D_variable, FSEP, wd->sname, FSEP);
@@ -4355,7 +4413,7 @@ enlarge_buffer:
cndn = &wd->cndn;
break;
case HISTORY:
-#ifdef HAVE_LIBREADLINE
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_HISTORY_LIST)
h = (HIST_ENTRY *) ptr;
nchar = strlen(h->line);
if (nchar >= buflen - bl)
@@ -4485,7 +4543,7 @@ unserialize_commands(char *str, int str_len)
return;
commands_string = str;
commands_string_len = str_len;
- push_cmd_src(INVALID_HANDLE, FALSE, read_commands_string, 0, 0, EXIT_FATAL);
+ push_cmd_src(INVALID_HANDLE, false, read_commands_string, 0, 0, EXIT_FATAL);
line_sep = CSEP;
read_command(); /* forced to return in do_commands */
pop_cmd_src();
@@ -4587,7 +4645,7 @@ unserialize_breakpoint(char **pstr, int *pstr_len, int field_cnt)
return NULL;
rp = find_rule(src, lineno);
if (rp == NULL
- || (b = set_breakpoint_at(rp, lineno, TRUE)) == NULL
+ || (b = set_breakpoint_at(rp, lineno, true)) == NULL
)
return NULL;
@@ -4619,8 +4677,9 @@ unserialize_option(char **pstr, int *pstr_len, int field_cnt ATTRIBUTE_UNUSED)
const struct dbg_option *opt;
for (opt = option_list; opt->name; opt++) {
- if (STREQN(pstr[0], opt->name, pstr_len[0])) {
+ if (strncmp(pstr[0], opt->name, pstr_len[0]) == 0) {
char *value;
+
value = estrdup(pstr[1], pstr_len[1]);
(*(opt->assign))(value);
efree(value);
@@ -4718,14 +4777,14 @@ prompt_yes_no(const char *mesg, char res_true, int res_default, FILE *fp)
}
/* has_break_or_watch_point --- check if given breakpoint or watchpoint
- * number exists. When flag any is TRUE,
+ * number exists. When flag any is true,
* check if any breakpoint/watchpoint
* has been set (ignores num). Returns
* type (breakpoint or watchpoint) or 0.
*/
int
-has_break_or_watch_point(int *pnum, int any)
+has_break_or_watch_point(int *pnum, bool any)
{
BREAKPOINT *b = NULL;
struct list_item *w = NULL;
@@ -4793,12 +4852,12 @@ do_commands(CMDARG *arg, int cmd)
struct commands_item *c;
if (cmd == D_commands) {
- int num, type;
+ int num = -1, type;
if (arg == NULL)
- type = has_break_or_watch_point(&num, TRUE);
+ type = has_break_or_watch_point(&num, true);
else {
num = arg->a_int;
- type = has_break_or_watch_point(&num, FALSE);
+ type = has_break_or_watch_point(&num, false);
}
b = NULL;
w = NULL;
@@ -4814,19 +4873,19 @@ do_commands(CMDARG *arg, int cmd)
c = c->prev;
delete_commands_item(c->next);
}
- return FALSE;
+ return false;
} else if (cmd == D_end) {
commands = NULL;
if (read_a_line == read_commands_string) /* unserializig commands */
- return TRUE; /* done unserializing, terminate zzparse() */
- return FALSE;
+ return true; /* done unserializing, terminate zzparse() */
+ return false;
} else if (cmd == D_silent) {
if (b != NULL)
- b->silent = TRUE;
+ b->silent = true;
else if (w != NULL)
- w->silent = TRUE;
+ w->silent = true;
/* we also append silent command to the list for use
* in `info break(watch)', and to simplify
* serialization/unserialization of commands.
@@ -4849,7 +4908,7 @@ do_commands(CMDARG *arg, int cmd)
c->next = commands;
commands->prev = c;
c->prev->next = c;
- return FALSE;
+ return false;
}
/* execute_commands --- execute breakpoint/watchpoint commands, the first
@@ -4862,7 +4921,7 @@ execute_commands(struct commands_item *commands)
{
struct commands_item *c;
Func_cmd cmd_ptr;
- int ret = FALSE;
+ bool ret = false;
for (c = commands->next; c != commands; c = c->next) {
if (c->cmd == D_silent)
@@ -4912,7 +4971,7 @@ do_print_f(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
{
long field_num;
r = a->a_node;
- field_num = (long) r->numbr;
+ field_num = get_number_si(r);
tmp[i] = *get_field(field_num, NULL);
}
break;
@@ -4981,7 +5040,7 @@ do_print_f(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
}
done:
efree(tmp);
- return FALSE;
+ return false;
}
/* do_source --- source command */
@@ -4996,12 +5055,12 @@ do_source(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
if (fd <= INVALID_HANDLE) {
d_error(_("can't open source file `%s' for reading (%s)"),
file, strerror(errno));
- return FALSE;
+ return false;
}
- push_cmd_src(fd, FALSE, g_readline, close, D_source, EXIT_SUCCESS);
+ push_cmd_src(fd, false, g_readline, close, D_source, EXIT_SUCCESS);
cmd_src->str = estrdup(file, strlen(file));
- return FALSE;
+ return false;
}
/* open_readfd --- open a file for reading */
@@ -5031,7 +5090,7 @@ find_option(char *name)
int idx;
for (idx = 0; (p = option_list[idx].name); idx++) {
- if (STREQ(p, name))
+ if (strcmp(p, name) == 0)
return idx;
}
return -1;
@@ -5100,19 +5159,19 @@ set_gawk_output(const char *file)
if (fp == NULL)
close(fd);
- } else if (STREQN(file, "/dev/", 5)) {
+ } else if (strncmp(file, "/dev/", 5) == 0) {
char *cp = (char *) file + 5;
- if (STREQ(cp, "stdout"))
+ if (strcmp(cp, "stdout") == 0)
return;
- if (STREQ(cp, "stderr")) {
+ if (strcmp(cp, "stderr") == 0) {
output_fp = stderr;
output_file = "/dev/stderr";
output_is_tty = os_isatty(fileno(stderr));
return;
}
- if (STREQN(cp, "fd/", 3)) {
+ if (strncmp(cp, "fd/", 3) == 0) {
cp += 3;
fd = (int) strtoul(cp, NULL, 10);
if (errno == 0 && fd > INVALID_HANDLE) {
@@ -5155,9 +5214,9 @@ set_gawk_output(const char *file)
static void
set_prompt(const char *value)
{
- efree(dgawk_Prompt);
- dgawk_Prompt = estrdup(value, strlen(value));
- dPrompt = dgawk_Prompt;
+ efree(dgawk_prompt);
+ dgawk_prompt = estrdup(value, strlen(value));
+ dbg_prompt = dgawk_prompt;
}
/* set_option_flag --- convert option string to flag value */
@@ -5166,10 +5225,10 @@ static int
set_option_flag(const char *value)
{
long n;
- if (STREQ(value, "on"))
- return TRUE;
- if (STREQ(value, "off"))
- return FALSE;
+ if (strcmp(value, "on") == 0)
+ return true;
+ if (strcmp(value, "off") == 0)
+ return false;
errno = 0;
n = strtol(value, NULL, 0);
return (errno == 0 && n != 0);
@@ -5287,11 +5346,11 @@ save_options(const char *file)
static void
close_all()
{
- int stdio_problem;
+ bool stdio_problem;
struct command_source *cs;
- (void) nextfile(&curfile, TRUE); /* close input data file */
- (void) close_io(&stdio_problem);
+ (void) nextfile(& curfile, true); /* close input data file */
+ (void) close_io(& stdio_problem);
if (cur_srcfile->fd != INVALID_HANDLE) {
close(cur_srcfile->fd);
cur_srcfile->fd = INVALID_HANDLE;
@@ -5303,6 +5362,8 @@ close_all()
}
}
+ close_extensions();
+
set_gawk_output(NULL); /* closes output_fp if not stdout */
}
@@ -5356,11 +5417,11 @@ execute_code(volatile INSTRUCTION *code)
*/
save_stack_size = (stack_ptr - stack_bottom) + 1;
- do_flags = FALSE;
+ do_flags = false;
PUSH_BINDING(fatal_tag_stack, fatal_tag, fatal_tag_valid);
if (setjmp(fatal_tag) == 0) {
- (void) r_interpret((INSTRUCTION *) code);
+ (void) interpret((INSTRUCTION *) code);
r = POP_SCALAR();
} else /* fatal error */
(void) unwind_stack(save_stack_size);
@@ -5388,6 +5449,7 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
int ecount = 0, pcount = 0;
int ret;
int save_flags = do_flags;
+ SRCFILE *the_source;
if (prog_running) {
this_frame = find_frame(0);
@@ -5398,15 +5460,15 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
ctxt = new_context();
ctxt->install_func = append_symbol; /* keep track of newly installed globals */
push_context(ctxt);
- (void) add_srcfile(SRC_CMDLINE, arg->a_string, srcfiles, NULL, NULL);
- do_flags = FALSE;
+ the_source = add_srcfile(SRC_CMDLINE, arg->a_string, srcfiles, NULL, NULL);
+ do_flags = false;
ret = parse_program(&code);
do_flags = save_flags;
remove_params(this_func);
if (ret != 0) {
pop_context(); /* switch to prev context */
- free_context(ctxt, FALSE /* keep_globals */);
- return FALSE;
+ free_context(ctxt, false /* keep_globals */);
+ return false;
}
f = lookup("@eval");
@@ -5463,7 +5525,7 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
#if 0
pf_data.print_func = fprintf;
pf_data.fp = out_fp;
- pf_data.defn = FALSE; /* in_dump = FALSE */
+ pf_data.defn = false; /* in_dump = false */
(void) print_code(f->code_ptr, &pf_data);
#endif
@@ -5499,15 +5561,28 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
this_func->param_cnt -= ecount;
}
- /* always destroy symbol "@eval", however destroy all newly installed
- * globals only if fatal error in r_interpret (r == NULL).
+ /*
+ * Always destroy symbol "@eval", however destroy all newly installed
+ * globals only if fatal error (execute_code() returing NULL).
*/
pop_context(); /* switch to prev context */
free_context(ctxt, (ret_val != NULL)); /* free all instructions and optionally symbols */
- if (ret_val != NULL)
- destroy_symbol(f); /* destroy "@eval" */
- return FALSE;
+
+ if (ret_val != NULL) {
+ /*
+ * Remove @eval from FUNCTAB, so that above code
+ * will work the next time around.
+ */
+ NODE *s = make_string("@eval", 5);
+
+ (void) assoc_remove(func_table, s);
+ unref(s);
+ }
+
+ free_srcfile(the_source);
+
+ return false;
}
/*
@@ -5569,14 +5644,14 @@ parse_condition(int type, int num, char *expr)
ctxt->install_func = check_symbol;
push_context(ctxt);
(void) add_srcfile(SRC_CMDLINE, expr, srcfiles, NULL, NULL);
- do_flags = FALSE;
+ do_flags = false;
ret = parse_program(&code);
do_flags = save_flags;
remove_params(this_func);
pop_context();
if (ret != 0 || invalid_symbol) {
- free_context(ctxt, FALSE /* keep_globals */);
+ free_context(ctxt, false /* keep_globals */);
return -1;
}
@@ -5606,7 +5681,7 @@ parse_condition(int type, int num, char *expr)
out:
if (cndn->expr != NULL)
efree(cndn->expr);
- free_context(cndn->ctxt, FALSE);
+ free_context(cndn->ctxt, false);
cndn->code = code;
cndn->expr = expr;
cndn->ctxt = ctxt;
@@ -5623,15 +5698,15 @@ do_condition(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
char *expr = NULL;
num = arg->a_int;
- type = has_break_or_watch_point(&num, FALSE);
+ type = has_break_or_watch_point(&num, false);
if (! type)
- return FALSE;
+ return false;
arg = arg->next; /* condition expression */
if (arg != NULL)
expr = arg->a_string;
if (parse_condition(type, num, expr) == 0 && arg != NULL)
arg->a_string = NULL; /* don't let free_cmdarg free it */
- return FALSE;
+ return false;
}
/* in_cmd_src --- check if filename already in cmd_src */
@@ -5641,10 +5716,10 @@ in_cmd_src(const char *filename)
{
struct command_source *cs;
for (cs = cmd_src; cs != NULL; cs = cs->next) {
- if (cs->str != NULL && STREQ(cs->str, filename))
- return TRUE;
+ if (cs->str != NULL && strcmp(cs->str, filename) == 0)
+ return true;
}
- return FALSE;
+ return false;
}
int
@@ -5658,7 +5733,7 @@ get_eof_status()
void
push_cmd_src(
int fd,
- int istty,
+ bool istty,
char * (*readfunc)(const char *),
int (*closefunc)(int),
int ctype,
diff --git a/depcomp b/depcomp
index ca5ea4e1..31788017 100755
--- a/depcomp
+++ b/depcomp
@@ -1,10 +1,9 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
-scriptversion=2006-10-15.18
+scriptversion=2013-05-30.07; # UTC
-# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software
-# Foundation, Inc.
+# Copyright (C) 1999-2013 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
@@ -17,9 +16,7 @@ scriptversion=2006-10-15.18
# 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.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -30,9 +27,9 @@ scriptversion=2006-10-15.18
case $1 in
'')
- echo "$0: No command. Try \`$0 --help' for more information." 1>&2
- exit 1;
- ;;
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
@@ -42,11 +39,11 @@ as side-effects.
Environment variables:
depmode Dependency tracking mode.
- source Source file read by `PROGRAMS ARGS'.
- object Object file output by `PROGRAMS ARGS'.
+ 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.
+ tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
@@ -59,6 +56,66 @@ EOF
;;
esac
+# Get the directory component of the given path, and save it in the
+# global variables '$dir'. Note that this directory component will
+# be either empty or ending with a '/' character. This is deliberate.
+set_dir_from ()
+{
+ case $1 in
+ */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
+ *) dir=;;
+ esac
+}
+
+# Get the suffix-stripped basename of the given path, and save it the
+# global variable '$base'.
+set_base_from ()
+{
+ base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
+}
+
+# If no dependency file was actually created by the compiler invocation,
+# we still have to create a dummy depfile, to avoid errors with the
+# Makefile "include basename.Plo" scheme.
+make_dummy_depfile ()
+{
+ echo "#dummy" > "$depfile"
+}
+
+# Factor out some common post-processing of the generated depfile.
+# Requires the auxiliary global variable '$tmpdepfile' to be set.
+aix_post_process_depfile ()
+{
+ # If the compiler actually managed to produce a dependency file,
+ # post-process it.
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form 'foo.o: dependency.h'.
+ # Do two passes, one to just change these to
+ # $object: dependency.h
+ # and one to simply output
+ # dependency.h:
+ # which is needed to avoid the deleted-header problem.
+ { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
+ sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
+ } > "$depfile"
+ rm -f "$tmpdepfile"
+ else
+ make_dummy_depfile
+ fi
+}
+
+# A tabulation character.
+tab=' '
+# A newline character.
+nl='
+'
+# Character ranges might be problematic outside the C locale.
+# These definitions help.
+upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
+lower=abcdefghijklmnopqrstuvwxyz
+digits=0123456789
+alpha=${upper}${lower}
+
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
@@ -71,6 +128,9 @@ tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
+# Avoid interferences from the environment.
+gccflag= dashmflag=
+
# 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
@@ -82,9 +142,32 @@ if test "$depmode" = hp; then
fi
if test "$depmode" = dashXmstdout; then
- # This is just like dashmstdout with a different argument.
- dashmflag=-xM
- depmode=dashmstdout
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+ # This is just like msvisualcpp but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+ # This is just like msvc7 but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+ # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
+ gccflag=-qmakedep=gcc,-MF
+ depmode=gcc
fi
case "$depmode" in
@@ -107,8 +190,7 @@ gcc3)
done
"$@"
stat=$?
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
@@ -116,13 +198,17 @@ gcc3)
;;
gcc)
+## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
+## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
+## (see the conditional assignment to $gccflag above).
## 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).
+## -MM, not -M (despite what the docs say). Also, it might not be
+## supported by the other compilers which use the 'gcc' depmode.
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
@@ -130,31 +216,31 @@ gcc)
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
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.
+ # 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.
+## 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
+## 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.
+## well. hp depmode also adds that space, but also prefixes the VPATH
+## to the object. Take care to not repeat it in the output.
## 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"
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
@@ -165,115 +251,136 @@ hp)
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"
+xlc)
+ # 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
;;
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
+ # 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"
+ set_dir_from "$object"
+ set_base_from "$object"
if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$base.u
+ tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$dir$base.u
+ tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
-
- if test -f "$tmpdepfile"; then :
- else
- stripped=`echo "$stripped" | sed 's,^.*/,,'`
- tmpdepfile="$stripped.u"
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
fi
- if test $stat -eq 0; then :
- else
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ aix_post_process_depfile
+ ;;
+
+tcc)
+ # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
+ # FIXME: That version still under development at the moment of writing.
+ # Make that this statement remains true also for stable, released
+ # versions.
+ # It will wrap lines (doesn't matter whether long or short) with a
+ # trailing '\', as in:
+ #
+ # foo.o : \
+ # foo.c \
+ # foo.h \
+ #
+ # It will put a trailing '\' even on the last line, and will use leading
+ # spaces rather than leading tabs (at least since its commit 0394caf7
+ # "Emit spaces for -MD").
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -ne 0; then
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 "$depfile"
+ # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
+ # We have to change lines of the first kind to '$object: \'.
+ sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
+ # And for each line of the second kind, we have to emit a 'dep.h:'
+ # dummy dependency, to avoid the deleted-header problem.
+ sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
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
+## The order of this option in the case statement is important, since the
+## shell code in configure will try each of these formats in the order
+## listed in this file. A plain '-MD' option would be understood by many
+## compilers, so we must ensure this comes after the gcc and icc options.
+pgcc)
+ # Portland's C compiler understands '-MD'.
+ # Will always output deps to 'file.d' where file is the root name of the
+ # source file under compilation, even if file resides in a subdirectory.
+ # The object file name does not affect the name of the '.d' file.
+ # pgcc 10.2 will output
# foo.o: sub/foo.c sub/foo.h
- # and will wrap long lines using \ :
+ # and will wrap long lines using '\' :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
+ set_dir_from "$object"
+ # Use the source, not the object, to determine the base name, since
+ # that's sadly what pgcc will do too.
+ set_base_from "$source"
+ tmpdepfile=$base.d
+
+ # For projects that build the same source file twice into different object
+ # files, the pgcc approach of using the *source* file root name can cause
+ # problems in parallel builds. Use a locking strategy to avoid stomping on
+ # the same $tmpdepfile.
+ lockdir=$base.d-lock
+ trap "
+ echo '$0: caught signal, cleaning up...' >&2
+ rmdir '$lockdir'
+ exit 1
+ " 1 2 13 15
+ numtries=100
+ i=$numtries
+ while test $i -gt 0; do
+ # mkdir is a portable test-and-set.
+ if mkdir "$lockdir" 2>/dev/null; then
+ # This process acquired the lock.
+ "$@" -MD
+ stat=$?
+ # Release the lock.
+ rmdir "$lockdir"
+ break
+ else
+ # If the lock is being held by a different process, wait
+ # until the winning process is done or we timeout.
+ while test -d "$lockdir" && test $i -gt 0; do
+ sleep 1
+ i=`expr $i - 1`
+ done
+ fi
+ i=`expr $i - 1`
+ done
+ trap - 1 2 13 15
+ if test $i -le 0; then
+ echo "$0: failed to acquire lock after $numtries attempts" >&2
+ echo "$0: check lockdir '$lockdir'" >&2
+ exit 1
+ fi
- "$@" -MD -MF "$tmpdepfile"
- stat=$?
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
@@ -285,8 +392,8 @@ icc)
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"
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
+ | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
@@ -297,9 +404,8 @@ hp2)
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
- dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
- test "x$dir" = "x$object" && dir=
- base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ set_dir_from "$object"
+ set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
@@ -310,8 +416,7 @@ hp2)
"$@" +Maked
fi
stat=$?
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
@@ -321,72 +426,107 @@ hp2)
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
- sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
- # Add `dependent.h:' lines.
- sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile"
+ sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
+ # Add 'dependent.h:' lines.
+ sed -ne '2,${
+ s/^ *//
+ s/ \\*$//
+ s/$/:/
+ p
+ }' "$tmpdepfile" >> "$depfile"
else
- echo "#dummy" > "$depfile"
+ make_dummy_depfile
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
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 mechanism 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 $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"
- ;;
+ # 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.
+ set_dir_from "$object"
+ set_base_from "$object"
+
+ if test "$libtool" = yes; then
+ # Libtool generates 2 separate objects for the 2 libraries. These
+ # two compilations output dependencies 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$base.o.d # libtool 1.5
+ tmpdepfile2=$dir.libs/$base.o.d # Likewise.
+ tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ # Same post-processing that is required for AIX mode.
+ aix_post_process_depfile
+ ;;
+
+msvc7)
+ if test "$libtool" = yes; then
+ showIncludes=-Wc,-showIncludes
+ else
+ showIncludes=-showIncludes
+ fi
+ "$@" $showIncludes > "$tmpdepfile"
+ stat=$?
+ grep -v '^Note: including file: ' "$tmpdepfile"
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The first sed program below extracts the file names and escapes
+ # backslashes for cygpath. The second sed program outputs the file
+ # name when reading, but also accumulates all include files in the
+ # hold buffer in order to output them again at the end. This only
+ # works with sed implementations that can handle large buffers.
+ sed < "$tmpdepfile" -n '
+/^Note: including file: *\(.*\)/ {
+ s//\1/
+ s/\\/\\\\/g
+ p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+ s/.*/'"$tab"'/
+ G
+ p
+}' >> "$depfile"
+ echo >> "$depfile" # make sure the fragment doesn't end with a backslash
+ rm -f "$tmpdepfile"
+ ;;
+
+msvc7msys)
+ # 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
+ ;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
@@ -399,13 +539,13 @@ dashmstdout)
# Remove the call to Libtool.
if test "$libtool" = yes; then
- while test $1 != '--mode=compile'; do
+ while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
- # Remove `-o $object'.
+ # Remove '-o $object'.
IFS=" "
for arg
do
@@ -425,18 +565,18 @@ dashmstdout)
done
test -z "$dashmflag" && dashmflag=-M
- # Require at least two characters before searching for `:'
+ # 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.
+ # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
- sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$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"
+ # Some versions of the HPUX 10.20 sed can't process this sed invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
@@ -450,41 +590,51 @@ makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
- while test $1 != '--mode=compile'; do
+ while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
- cleared=no
- for arg in "$@"; do
+ cleared=no eat=no
+ for arg
+ do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
+ if test $eat = yes; then
+ eat=no
+ continue
+ fi
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.
+ -arch)
+ eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
- obj_suffix="`echo $object | sed 's/^.*\././'`"
+ 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"
+ # makedepend may prepend the VPATH from the source file name to the object.
+ # No need to regex-escape $object, excess matching of '.' is harmless.
+ sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process the last invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed '1,2d' "$tmpdepfile" \
+ | tr ' ' "$nl" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
@@ -495,13 +645,13 @@ cpp)
# Remove the call to Libtool.
if test "$libtool" = yes; then
- while test $1 != '--mode=compile'; do
+ while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
- # Remove `-o $object'.
+ # Remove '-o $object'.
IFS=" "
for arg
do
@@ -520,10 +670,10 @@ cpp)
esac
done
- "$@" -E |
- sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
- -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
- sed '$ s: \\$::' > "$tmpdepfile"
+ "$@" -E \
+ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ | sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
@@ -533,35 +683,56 @@ cpp)
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.
+ # always write the preprocessed file to stdout.
"$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
IFS=" "
for arg
do
case "$arg" in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
- set fnord "$@"
- shift
- shift
- ;;
+ set fnord "$@"
+ shift
+ shift
+ ;;
*)
- set fnord "$@" "$arg"
- 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"
+ "$@" -E 2>/dev/null |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$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"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+ echo "$tab" >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
+msvcmsys)
+ # 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
+ ;;
+
none)
exec "$@"
;;
@@ -580,5 +751,6 @@ exit 0
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
# End:
diff --git a/dfa.c b/dfa.c
index 789c6b91..2cfd30b6 100644
--- a/dfa.c
+++ b/dfa.c
@@ -1,5 +1,5 @@
/* dfa.c - deterministic extended regexp routines for GNU
- Copyright (C) 1988, 1998, 2000, 2002, 2004-2005, 2007-2011 Free Software
+ Copyright (C) 1988, 1998, 2000, 2002, 2004-2005, 2007-2015 Free Software
Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -21,6 +21,7 @@
Modified July, 1988 by Arthur David Olson to assist BMG speedups */
#include <config.h>
+
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
@@ -37,6 +38,11 @@
#include <locale.h>
#endif
+/* Gawk doesn't use Gnulib, so don't assume that setlocale is present. */
+#ifndef LC_ALL
+# define setlocale(category, locale) NULL
+#endif
+
#define STREQ(a, b) (strcmp (a, b) == 0)
/* ISASCIIDIGIT differs from isdigit, as follows:
@@ -45,46 +51,23 @@
- 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
+ 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)
-#include "mbsupport.h" /* defines MBS_SUPPORT to 1 or 0, as appropriate */
-#if MBS_SUPPORT
-/* We can handle multibyte strings. */
#include <wchar.h>
#include <wctype.h>
-#if HAVE_LANGINFO_CODESET
-# include <langinfo.h>
-#endif
-#endif
+#include "xalloc.h"
-#ifdef GAWK
-#define bool int
-#define true (1)
-#define false (0)
-#if ! MBS_SUPPORT
-#define wctype_t int
-#define wint_t int
-#define mbstate_t int
-#define WEOF EOF
-#define towupper toupper
-#define towlower tolower
-#define btowc(x) (x)
-#define iswalnum isalnum
-#define iswalpha isalpha
-#define iswupper isupper
-#endif /* ! MBS_SUPPORT */
-#endif /* GAWK */
+#if defined(__DJGPP__)
+#include "mbsupport.h"
+#endif
-#include "regex.h"
#include "dfa.h"
-#include "xalloc.h"
#ifdef GAWK
static int
@@ -92,77 +75,9 @@ is_blank (int c)
{
return (c == ' ' || c == '\t');
}
-
-#if ! MBS_SUPPORT
-static const char *classes[] = {
- "<dummy>",
- "alnum",
- "alpha",
- "blank",
- "cntrl",
- "digit",
- "graph",
- "lower",
- "print",
- "punct",
- "space",
- "upper",
- "xdigit",
- NULL
-};
-
-static wctype_t wctype(const char *name)
-{
- int i;
-
- for (i = 1; classes[i] != NULL; i++)
- if (strcmp(name, classes[i]) == 0)
- return i;
-
- return 0;
-}
-
-static int iswctype(wint_t wc, wctype_t desc)
-{
- int j = sizeof(classes) / sizeof(classes[0]);
-
- if (desc >= j || desc == 0)
- return 0;
-
- switch (desc) {
- case 1: return isalnum(wc);
- case 2: return isalpha(wc);
- case 3: return is_blank(wc);
- case 4: return iscntrl(wc);
- case 5: return isdigit(wc);
- case 6: return isgraph(wc);
- case 7: return islower(wc);
- case 8: return isprint(wc);
- case 9: return ispunct(wc);
- case 10: return isspace(wc);
- case 11: return isupper(wc);
- case 12: return isxdigit(wc);
- default: return 0;
- }
-}
-
-static int wcscoll(const wchar_t *ws1, const wchar_t *ws2)
-{
- size_t i;
-
- for (i = 0; ws1[i] != 0 && ws2[i] != 0; i++) {
- if (ws1[i] < ws2[i])
- return -1;
- else if (ws1[i] > ws2[i])
- return 1;
- }
-
- return (ws1[i] - ws2[i]);
-}
-#endif /* ! MBS_SUPPORT */
#endif /* GAWK */
-/* HPUX, define those as macros in sys/param.h */
+/* HPUX defines these as macros in sys/param.h. */
#ifdef setbit
# undef setbit
#endif
@@ -170,29 +85,55 @@ static int wcscoll(const wchar_t *ws1, const wchar_t *ws2)
# undef clrbit
#endif
-/* Number of bits in an unsigned char. */
-#ifndef CHARBITS
-# define CHARBITS 8
-#endif
+/* First integer value that is greater than any character code. */
+enum { NOTCHAR = 1 << CHAR_BIT };
-/* First integer value that is greater than any character code. */
-#define NOTCHAR (1 << CHARBITS)
+/* This represents part of a character class. It must be unsigned and
+ at least CHARCLASS_WORD_BITS wide. Any excess bits are zero. */
+typedef unsigned int charclass_word;
-/* INTBITS need not be exact, just a lower bound. */
-#ifndef INTBITS
-# define INTBITS (CHARBITS * sizeof (int))
-#endif
+/* The number of bits used in a charclass word. utf8_classes assumes
+ this is exactly 32. */
+enum { CHARCLASS_WORD_BITS = 32 };
-/* Number of ints required to hold a bit for every character. */
-#define CHARCLASS_INTS ((NOTCHAR + INTBITS - 1) / INTBITS)
+/* The maximum useful value of a charclass_word; all used bits are 1. */
+#define CHARCLASS_WORD_MASK \
+ (((charclass_word) 1 << (CHARCLASS_WORD_BITS - 1) << 1) - 1)
+
+/* Number of words required to hold a bit for every character. */
+enum
+{
+ CHARCLASS_WORDS = (NOTCHAR + CHARCLASS_WORD_BITS - 1) / CHARCLASS_WORD_BITS
+};
-/* Sets of unsigned characters are stored as bit vectors in arrays of ints. */
-typedef int charclass[CHARCLASS_INTS];
+/* Sets of unsigned characters are stored as bit vectors in arrays of ints. */
+typedef charclass_word charclass[CHARCLASS_WORDS];
/* Convert a possibly-signed character to an unsigned character. This is
a bit safer than casting to unsigned char, since it catches some type
errors that the cast doesn't. */
-static inline unsigned char to_uchar (char ch) { return ch; }
+static unsigned char
+to_uchar (char ch)
+{
+ return ch;
+}
+
+/* Contexts tell us whether a character is a newline or a word constituent.
+ Word-constituent characters are those that satisfy iswalnum, plus '_'.
+ Each character has a single CTX_* value; bitmasks of CTX_* values denote
+ a particular character class.
+
+ A state also stores a context value, which is a bitmask of CTX_* values.
+ A state's context represents a set of characters that the state's
+ predecessors must match. For example, a state whose context does not
+ include CTX_LETTER will never have transitions where the previous
+ character is a word constituent. A state whose context is CTX_ANY
+ might have transitions from any character. */
+
+#define CTX_NONE 1
+#define CTX_LETTER 2
+#define CTX_NEWLINE 4
+#define CTX_ANY 7
/* Sometimes characters can only be matched depending on the surrounding
context. Such context decisions depend on what the previous character
@@ -201,340 +142,392 @@ static inline unsigned char to_uchar (char ch) { return ch; }
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().
+ bit 8-11 - valid contexts when next character is CTX_NEWLINE
+ bit 4-7 - valid contexts when next character is CTX_LETTER
+ bit 0-3 - valid contexts when next character is CTX_NONE
The macro SUCCEEDS_IN_CONTEXT determines whether 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. */
+ succeeds in a particular context. Prev is a bitmask of possible
+ context values for the previous character, curr is the (single-bit)
+ context value for the lookahead character. */
+#define NEWLINE_CONSTRAINT(constraint) (((constraint) >> 8) & 0xf)
+#define LETTER_CONSTRAINT(constraint) (((constraint) >> 4) & 0xf)
+#define OTHER_CONSTRAINT(constraint) ((constraint) & 0xf)
+
+#define SUCCEEDS_IN_CONTEXT(constraint, prev, curr) \
+ ((((curr) & CTX_NONE ? OTHER_CONSTRAINT (constraint) : 0) \
+ | ((curr) & CTX_LETTER ? LETTER_CONSTRAINT (constraint) : 0) \
+ | ((curr) & CTX_NEWLINE ? NEWLINE_CONSTRAINT (constraint) : 0)) & (prev))
+
+/* The following macros describe what a constraint depends on. */
+#define PREV_NEWLINE_CONSTRAINT(constraint) (((constraint) >> 2) & 0x111)
+#define PREV_LETTER_CONSTRAINT(constraint) (((constraint) >> 1) & 0x111)
+#define PREV_OTHER_CONSTRAINT(constraint) ((constraint) & 0x111)
+
#define PREV_NEWLINE_DEPENDENT(constraint) \
- (((constraint) & 0xc0) >> 2 != ((constraint) & 0x30))
+ (PREV_NEWLINE_CONSTRAINT (constraint) != PREV_OTHER_CONSTRAINT (constraint))
#define PREV_LETTER_DEPENDENT(constraint) \
- (((constraint) & 0x0c) >> 2 != ((constraint) & 0x03))
+ (PREV_LETTER_CONSTRAINT (constraint) != PREV_OTHER_CONSTRAINT (constraint))
/* 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
+ the constraints corresponding to the special tokens previously defined. */
+#define NO_CONSTRAINT 0x777
+#define BEGLINE_CONSTRAINT 0x444
+#define ENDLINE_CONSTRAINT 0x700
+#define BEGWORD_CONSTRAINT 0x050
+#define ENDWORD_CONSTRAINT 0x202
+#define LIMWORD_CONSTRAINT 0x252
+#define NOTLIMWORD_CONSTRAINT 0x525
/* 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
+ codes are returned by the lexical analyzer. */
+
+typedef ptrdiff_t token;
+
+/* Predefined token values. */
+enum
{
- END = -1, /* END is a terminal symbol that matches the
+ 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. */
+ a transition on END. */
- /* Ordinary character values are terminal symbols that match themselves. */
+ /* Ordinary character values are terminal symbols that match themselves. */
- EMPTY = NOTCHAR, /* EMPTY is a terminal symbol that matches
- the empty string. */
+ EMPTY = NOTCHAR, /* EMPTY is a terminal symbol that matches
+ the empty string. */
- BACKREF, /* BACKREF is generated by \<digit>; it
+ BACKREF, /* BACKREF is generated by \<digit>
+ or by any other construct that
is 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. */
+ a backtracking matcher. */
- BEGLINE, /* BEGLINE is a terminal symbol that matches
- the empty string if it is at the beginning
- of a line. */
+ BEGLINE, /* BEGLINE is a terminal symbol that matches
+ the empty string 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. */
+ ENDLINE, /* ENDLINE is a terminal symbol that matches
+ the empty string 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. */
+ BEGWORD, /* BEGWORD is a terminal symbol that matches
+ the empty string 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. */
+ ENDWORD, /* ENDWORD is a terminal symbol that matches
+ the empty string 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. */
+ LIMWORD, /* LIMWORD is a terminal symbol that matches
+ the empty string 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. */
+ NOTLIMWORD, /* NOTLIMWORD is a terminal symbol that
+ matches the empty string 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. */
+ QMARK, /* QMARK is an operator of one argument that
+ matches zero or one occurrences of its
+ argument. */
- STAR, /* STAR is an operator of one argument that
+ STAR, /* STAR is an operator of one argument that
matches the Kleene closure (zero or more
- occurrences) of its argument. */
+ occurrences) of its argument. */
- PLUS, /* PLUS is an operator of one argument that
+ PLUS, /* PLUS is an operator of one argument that
matches the positive closure (one or more
- occurrences) of its argument. */
+ occurrences) of its argument. */
- REPMN, /* REPMN is a lexical token corresponding
+ REPMN, /* REPMN is a lexical token corresponding
to the {m,n} construct. REPMN never
- appears in the compiled token vector. */
+ appears in the compiled token vector. */
- CAT, /* CAT is an operator of two arguments that
+ CAT, /* CAT is an operator of two arguments that
matches the concatenation of its
arguments. CAT is never returned by the
- lexical analyzer. */
+ lexical analyzer. */
- OR, /* OR is an operator of two arguments that
- matches either of its arguments. */
+ OR, /* OR is an operator of two arguments that
+ matches either of its arguments. */
- LPAREN, /* LPAREN never appears in the parse tree,
- it is only a lexeme. */
+ LPAREN, /* LPAREN never appears in the parse tree,
+ it is only a lexeme. */
- RPAREN, /* RPAREN never appears in the parse tree. */
+ RPAREN, /* RPAREN never appears in the parse tree. */
- ANYCHAR, /* ANYCHAR is a terminal symbol that matches
- any multibyte (or single byte) characters.
- It is used only if MB_CUR_MAX > 1. */
+ ANYCHAR, /* ANYCHAR is a terminal symbol that matches
+ a valid multibyte (or single byte) character.
+ It is used only if MB_CUR_MAX > 1. */
- MBCSET, /* MBCSET is similar to CSET, but for
+ MBCSET, /* MBCSET is similar to CSET, but for
multibyte characters. */
- WCHAR, /* Only returned by lex. wctok contains
+ WCHAR, /* Only returned by lex. wctok contains
the wide character representation. */
- CSET /* CSET and (and any value greater) is a
+ CSET /* CSET and (and any value greater) is a
terminal symbol that matches any of a
- class of characters. */
-} token;
+ class of characters. */
+};
/* 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. */
+ a constraint. */
typedef struct
{
- unsigned int index; /* Index into the parse array. */
- unsigned int constraint; /* Constraint for matching this position. */
+ size_t index; /* Index into the parse array. */
+ unsigned int constraint; /* Constraint for matching this position. */
} position;
-/* Sets of positions are stored as arrays. */
+/* 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 *elems; /* Elements of this position set. */
+ size_t nelem; /* Number of elements in this set. */
+ size_t alloc; /* Number of elements allocated in ELEMS. */
} position_set;
+/* Sets of leaves are also stored as arrays. */
+typedef struct
+{
+ size_t *elems; /* Elements of this position set. */
+ size_t nelem; /* Number of elements in this set. */
+} leaf_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. */
+ 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. */
- position_set mbps; /* Positions which can match multibyte
- characters. e.g. period.
- These staff are used only if
- MB_CUR_MAX > 1. */
+ size_t hash; /* Hash of the positions of this state. */
+ position_set elems; /* Positions this state could match. */
+ unsigned char context; /* Context from previous state. */
+ bool has_backref; /* This state matches a \<digit>. */
+ bool has_mbcset; /* This state matches a MBCSET. */
+ unsigned short constraint; /* Constraint for this state to accept. */
+ token first_end; /* Token value of the first END in elems. */
+ position_set mbps; /* Positions which can match multibyte
+ characters, e.g., period.
+ Used only if MB_CUR_MAX > 1. */
} dfa_state;
+/* States are indexed by state_num values. These are normally
+ nonnegative but -1 is used as a special value. */
+typedef ptrdiff_t state_num;
+
/* A bracket operator.
- e.g. [a-c], [[:alpha:]], etc. */
+ e.g., [a-c], [[:alpha:]], etc. */
struct mb_char_classes
{
- int cset;
- 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;
+ ptrdiff_t cset;
+ bool invert;
+ wchar_t *chars; /* Normal characters. */
+ size_t nchars;
+ wctype_t *ch_classes; /* Character classes. */
+ size_t nch_classes;
+ struct /* Range characters. */
+ {
+ wchar_t beg; /* Range start. */
+ wchar_t end; /* Range end. */
+ } *ranges;
+ size_t nranges;
+ char **equivs; /* Equivalence classes. */
+ size_t nequivs;
char **coll_elems;
- int ncoll_elems; /* Collating elements. */
+ size_t ncoll_elems; /* Collating elements. */
};
-/* A compiled regular expression. */
+/* A compiled regular expression. */
struct dfa
{
- /* Fields filled 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. */
-
- /* Fields filled 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
+ /* Fields filled by the scanner. */
+ charclass *charclasses; /* Array of character sets for CSET tokens. */
+ size_t cindex; /* Index for adding new charclasses. */
+ size_t calloc; /* Number of charclasses allocated. */
+
+ /* Fields filled by the parser. */
+ token *tokens; /* Postfix parse array. */
+ size_t tindex; /* Index for adding new tokens. */
+ size_t talloc; /* Number of tokens currently allocated. */
+ size_t 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(). */
- unsigned int mb_cur_max; /* Cached value of MB_CUR_MAX. */
- int utf8_anychar_classes[5]; /* To lower ANYCHAR in UTF-8 locales. */
+ parse tree. */
+ size_t nleaves; /* Number of leaves on the parse tree. */
+ size_t nregexps; /* Count of parallel regexps being built
+ with dfaparse. */
+ bool fast; /* The DFA is fast. */
+ bool multibyte; /* MB_CUR_MAX > 1. */
+ token utf8_anychar_classes[5]; /* To lower ANYCHAR in UTF-8 locales. */
+ mbstate_t mbs; /* Multibyte conversion state. */
- /* The following are used only if MB_CUR_MAX > 1. */
+ /* dfaexec implementation. */
+ char *(*dfaexec) (struct dfa *, char const *, char *, int, size_t *, int *);
+
+ /* The following are valid only if MB_CUR_MAX > 1. */
/* The value of multibyte_prop[i] is defined by following rule.
- if tokens[i] < NOTCHAR
- bit 0 : tokens[i] is the first byte of a character, including
- single-byte characters.
- bit 1 : tokens[i] is the last byte of a character, including
- single-byte characters.
+ if tokens[i] < NOTCHAR
+ bit 0 : tokens[i] is the first byte of a character, including
+ single-byte characters.
+ bit 1 : tokens[i] is the last byte of a character, including
+ single-byte characters.
- if tokens[i] = MBCSET
- ("the index of mbcsets correspnd to this operator" << 2) + 3
+ if tokens[i] = MBCSET
+ ("the index of mbcsets corresponding 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'
+ = '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
- */
- int nmultibyte_prop;
+ = 3 , 1 , 0 , 2 , 3
+ */
int *multibyte_prop;
+ /* A table indexed by byte values that contains the corresponding wide
+ character (if any) for that byte. WEOF means the byte is not a
+ valid single-byte character. */
+ wint_t mbrtowc_cache[NOTCHAR];
+
/* Array of the bracket expression in the DFA. */
struct mb_char_classes *mbcsets;
- int nmbcsets;
- int mbcsets_alloc;
+ size_t nmbcsets;
+ size_t mbcsets_alloc;
- /* Fields filled 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. */
+ /* Fields filled by the superset. */
+ struct dfa *superset; /* Hint of the dfa. */
- /* Fields filled by the parse tree->NFA conversion. */
- position_set *follows; /* Array of follow sets, indexed by position
+ /* Fields filled by the state builder. */
+ dfa_state *states; /* States of the dfa. */
+ state_num sindex; /* Index for adding new states. */
+ size_t salloc; /* Number of states currently allocated. */
+
+ /* Fields filled by the parse tree->NFA conversion. */
+ 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
+ maximum possible position index. */
+ bool searchflag; /* 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. */
-
- /* Fields filled by dfaexec. */
- 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
+ beginning of the buffer. */
+
+ /* Fields filled by dfaexec. */
+ state_num tralloc; /* Number of transition tables that have
+ slots so far, not counting trans[-1]. */
+ int trcount; /* Number of transition tables that have
+ actually been built. */
+ int min_trcount; /* Minimum of number of transition tables.
+ Always keep the number, even after freeing
+ the transition tables. It is also the
+ number of initial states. */
+ state_num **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
+ this table is NULL. This points to one
+ past the start of the allocated array,
+ and trans[-1] is always NULL. */
+ state_num **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. */
+ state_num *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
+ as a sentinel at the end of the buffer. */
+ state_num initstate_letter; /* Initial state for letter context. */
+ state_num initstate_others; /* Initial state for other contexts. */
+ struct dfamust *musts; /* List of strings, at least one of which
is known to appear in any r.e. matching
- the dfa. */
+ the dfa. */
+ position_set mb_follows; /* Follow set added by ANYCHAR and/or MBCSET
+ on demand. */
+ int *mb_match_lens; /* Array of length reduced by ANYCHAR and/or
+ MBCSET. Null if mb_follows.elems has not
+ been allocated. */
};
-/* Some macros for user access to dfa internals. */
+/* Some macros for user access to dfa internals. */
-/* ACCEPTING returns true if s could possibly be an accepting state of r. */
+/* 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)
+/* STATE accepts in the specified context. */
+#define ACCEPTS_IN_CONTEXT(prev, curr, state, dfa) \
+ SUCCEEDS_IN_CONTEXT ((dfa).states[state].constraint, prev, curr)
static void dfamust (struct dfa *dfa);
static void regexp (void);
-/* These two macros are identical to the ones in gnulib's xalloc.h,
- except that they not to case the result to "(t *)", and thus may
- be used via type-free CALLOC and MALLOC macros. */
-#undef XNMALLOC
-#undef XCALLOC
-
-/* Allocate memory for N elements of type T, with error checking. */
-/* extern t *XNMALLOC (size_t n, typename t); */
-# define XNMALLOC(n, t) \
- (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t)))
-
-/* Allocate memory for N elements of type T, with error checking,
- and zero it. */
-/* extern t *XCALLOC (size_t n, typename t); */
-# define XCALLOC(n, t) \
- (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t)))
-
-#define CALLOC(p, n) do { (p) = XCALLOC (n, *(p)); } while (0)
-#define MALLOC(p, n) do { (p) = XNMALLOC (n, *(p)); } while (0)
-#define REALLOC(p, n) do {(p) = xnrealloc (p, n, sizeof (*(p))); } while (0)
-
-/* Reallocate an array of type *P if N_ALLOC is <= N_REQUIRED. */
-#define REALLOC_IF_NECESSARY(p, n_alloc, n_required) \
- do \
- { \
- assert (0 <= (n_required)); \
- if ((n_alloc) <= (n_required)) \
- { \
- size_t new_n_alloc = (n_required) + !(p); \
- (p) = x2nrealloc (p, &new_n_alloc, sizeof (*(p))); \
- (n_alloc) = new_n_alloc; \
- } \
- } \
- while (false)
+static void
+dfambcache (struct dfa *d)
+{
+ int i;
+ for (i = CHAR_MIN; i <= CHAR_MAX; ++i)
+ {
+ char c = i;
+ unsigned char uc = i;
+ mbstate_t s = { 0 };
+ wchar_t wc;
+ d->mbrtowc_cache[uc] = mbrtowc (&wc, &c, 1, &s) <= 1 ? wc : WEOF;
+ }
+}
+
+/* Store into *PWC the result of converting the leading bytes of the
+ multibyte buffer S of length N bytes, using the mbrtowc_cache in *D
+ and updating the conversion state in *D. On conversion error,
+ convert just a single byte, to WEOF. Return the number of bytes
+ converted.
+
+ This differs from mbrtowc (PWC, S, N, &D->mbs) as follows:
+
+ * PWC points to wint_t, not to wchar_t.
+ * The last arg is a dfa *D instead of merely a multibyte conversion
+ state D->mbs. D also contains an mbrtowc_cache for speed.
+ * N must be at least 1.
+ * S[N - 1] must be a sentinel byte.
+ * Shift encodings are not supported.
+ * The return value is always in the range 1..N.
+ * D->mbs is always valid afterwards.
+ * *PWC is always set to something. */
+static size_t
+mbs_to_wchar (wint_t *pwc, char const *s, size_t n, struct dfa *d)
+{
+ unsigned char uc = s[0];
+ wint_t wc = d->mbrtowc_cache[uc];
+
+ if (wc == WEOF)
+ {
+ wchar_t wch;
+ size_t nbytes = mbrtowc (&wch, s, n, &d->mbs);
+ if (0 < nbytes && nbytes < (size_t) -2)
+ {
+ *pwc = wch;
+ return nbytes;
+ }
+ memset (&d->mbs, 0, sizeof d->mbs);
+ }
+ *pwc = wc;
+ return 1;
+}
#ifdef DEBUG
@@ -544,55 +537,95 @@ prtok (token t)
char const *s;
if (t < 0)
- fprintf(stderr, "END");
+ fprintf (stderr, "END");
else if (t < NOTCHAR)
- fprintf(stderr, "%c", t);
+ {
+ int ch = t;
+ fprintf (stderr, "%c", ch);
+ }
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 LPAREN: s = "LPAREN"; break;
- case RPAREN: s = "RPAREN"; break;
- case ANYCHAR: s = "ANYCHAR"; break;
- case MBCSET: s = "MBCSET"; break;
- default: s = "CSET"; break;
+ 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 LPAREN:
+ s = "LPAREN";
+ break;
+ case RPAREN:
+ s = "RPAREN";
+ break;
+ case ANYCHAR:
+ s = "ANYCHAR";
+ break;
+ case MBCSET:
+ s = "MBCSET";
+ break;
+ default:
+ s = "CSET";
+ break;
}
- fprintf(stderr, "%s", s);
+ fprintf (stderr, "%s", s);
}
}
#endif /* DEBUG */
-/* Stuff pertaining to charclasses. */
+/* Stuff pertaining to charclasses. */
-static int
+static bool
tstbit (unsigned int b, charclass const c)
{
- return c[b / INTBITS] & 1 << b % INTBITS;
+ return c[b / CHARCLASS_WORD_BITS] >> b % CHARCLASS_WORD_BITS & 1;
}
static void
setbit (unsigned int b, charclass c)
{
- c[b / INTBITS] |= 1 << b % INTBITS;
+ c[b / CHARCLASS_WORD_BITS] |= (charclass_word) 1 << b % CHARCLASS_WORD_BITS;
}
static void
clrbit (unsigned int b, charclass c)
{
- c[b / INTBITS] &= ~(1 << b % INTBITS);
+ c[b / CHARCLASS_WORD_BITS] &= ~((charclass_word) 1
+ << b % CHARCLASS_WORD_BITS);
}
static void
@@ -612,51 +645,134 @@ notset (charclass s)
{
int i;
- for (i = 0; i < CHARCLASS_INTS; ++i)
- s[i] = ~s[i];
+ for (i = 0; i < CHARCLASS_WORDS; ++i)
+ s[i] = CHARCLASS_WORD_MASK & ~s[i];
}
-static int
+static bool
equal (charclass const s1, charclass const s2)
{
return memcmp (s1, s2, sizeof (charclass)) == 0;
}
-/* A pointer to the current dfa is kept here during parsing. */
-static struct dfa *dfa;
+/* Ensure that the array addressed by PTR holds at least NITEMS +
+ (PTR || !NITEMS) items. Either return PTR, or reallocate the array
+ and return its new address. Although PTR may be null, the returned
+ value is never null.
-/* Find the index of charclass s in dfa->charclasses, or allocate a new charclass. */
-static int
-charclass_index (charclass const s)
+ The array holds *NALLOC items; *NALLOC is updated on reallocation.
+ ITEMSIZE is the size of one item. Avoid O(N**2) behavior on arrays
+ growing linearly. */
+static void *
+maybe_realloc (void *ptr, size_t nitems, size_t *nalloc, size_t itemsize)
{
- int i;
+ if (nitems < *nalloc)
+ return ptr;
+ *nalloc = nitems;
+ return x2nrealloc (ptr, nalloc, itemsize);
+}
- for (i = 0; i < dfa->cindex; ++i)
- if (equal(s, dfa->charclasses[i]))
+/* In DFA D, find the index of charclass S, or allocate a new one. */
+static size_t
+dfa_charclass_index (struct dfa *d, charclass const s)
+{
+ size_t i;
+
+ for (i = 0; i < d->cindex; ++i)
+ if (equal (s, d->charclasses[i]))
return i;
- REALLOC_IF_NECESSARY(dfa->charclasses, dfa->calloc, dfa->cindex + 1);
- ++dfa->cindex;
- copyset(s, dfa->charclasses[i]);
+ d->charclasses = maybe_realloc (d->charclasses, d->cindex, &d->calloc,
+ sizeof *d->charclasses);
+ ++d->cindex;
+ copyset (s, d->charclasses[i]);
return i;
}
-/* Syntax bits controlling the behavior of the lexical analyzer. */
+/* A pointer to the current dfa is kept here during parsing. */
+static struct dfa *dfa;
+
+/* Find the index of charclass S in the current DFA, or allocate a new one. */
+static size_t
+charclass_index (charclass const s)
+{
+ return dfa_charclass_index (dfa, s);
+}
+
+/* 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;
+/* Flag for case-folding letters into sets. */
+static bool case_fold;
/* End-of-line byte in data. */
static unsigned char eolbyte;
-/* Entry point to set syntax options. */
+/* Cache of char-context values. */
+static int sbit[NOTCHAR];
+
+/* Set of characters considered letters. */
+static charclass letters;
+
+/* Set of characters that are newline. */
+static charclass newline;
+
+/* Add this to the test for whether a byte is word-constituent, since on
+ BSD-based systems, many values in the 128..255 range are classified as
+ alphabetic, while on glibc-based systems, they are not. */
+#ifdef __GLIBC__
+# define is_valid_unibyte_character(c) 1
+#else
+# define is_valid_unibyte_character(c) (btowc (c) != WEOF)
+#endif
+
+/* C is a "word-constituent" byte. */
+#define IS_WORD_CONSTITUENT(C) \
+ (is_valid_unibyte_character (C) && (isalnum (C) || (C) == '_'))
+
+static int
+char_context (unsigned char c)
+{
+ if (c == eolbyte)
+ return CTX_NEWLINE;
+ if (IS_WORD_CONSTITUENT (c))
+ return CTX_LETTER;
+ return CTX_NONE;
+}
+
+static int
+wchar_context (wint_t wc)
+{
+ if (wc == (wchar_t) eolbyte || wc == 0)
+ return CTX_NEWLINE;
+ if (wc == L'_' || iswalnum (wc))
+ return CTX_LETTER;
+ return CTX_NONE;
+}
+
+/* Entry point to set syntax options. */
void
dfasyntax (reg_syntax_t bits, int fold, unsigned char eol)
{
+ unsigned int i;
+
syntax_bits_set = 1;
syntax_bits = bits;
- case_fold = fold;
+ case_fold = fold != 0;
eolbyte = eol;
+
+ for (i = 0; i < NOTCHAR; ++i)
+ {
+ sbit[i] = char_context (i);
+ switch (sbit[i])
+ {
+ case CTX_LETTER:
+ setbit (i, letters);
+ break;
+ case CTX_NEWLINE:
+ setbit (i, newline);
+ break;
+ }
+ }
}
/* Set a bit in the charclass for the given wchar_t. Do nothing if WC
@@ -664,7 +780,6 @@ dfasyntax (reg_syntax_t bits, int fold, unsigned char eol)
this may happen when folding case in weird Turkish locales where
dotless i/dotted I are not included in the chosen character set.
Return whether a bit was set in the charclass. */
-#if MBS_SUPPORT
static bool
setbit_wc (wint_t wc, charclass c)
{
@@ -676,111 +791,104 @@ setbit_wc (wint_t wc, charclass c)
return true;
}
-/* Set a bit in the charclass for the given single byte character,
- if it is valid in the current character set. */
-static void
-setbit_c (int b, charclass c)
-{
- /* Do nothing if b is invalid in this character set. */
- if (MB_CUR_MAX > 1 && btowc (b) == WEOF)
- return;
- setbit (b, c);
-}
-#else
-# define setbit_c setbit
-static inline bool setbit_wc (wint_t wc, charclass c)
-{
- abort ();
- /*NOTREACHED*/
- return false;
-}
-#endif
-
-/* Like setbit_c, but if case is folded, set both cases of a letter. For
- MB_CUR_MAX > 1, the resulting charset is only used as an optimization,
- and the caller takes care of setting the appropriate field of struct
- mb_char_classes. */
+/* Set a bit for B and its case variants in the charclass C.
+ MB_CUR_MAX must be 1. */
static void
setbit_case_fold_c (int b, charclass c)
{
- if (MB_CUR_MAX > 1)
- {
- wint_t wc = btowc (b);
- if (wc == WEOF)
- return;
- setbit (b, c);
- if (case_fold && iswalpha (wc))
- setbit_wc (iswupper (wc) ? towlower (wc) : towupper (wc), c);
- }
- else
- {
- setbit (b, c);
- if (case_fold && isalpha (b))
- setbit_c (isupper (b) ? tolower (b) : toupper (b), c);
- }
+ int ub = toupper (b);
+ int i;
+ for (i = 0; i < NOTCHAR; i++)
+ if (toupper (i) == ub)
+ setbit (i, c);
}
/* UTF-8 encoding allows some optimizations that we can't otherwise
- assume in a multibyte encoding. */
-static inline int
+ assume in a multibyte encoding. */
+int
using_utf8 (void)
{
static int utf8 = -1;
- if (utf8 == -1)
+ if (utf8 < 0)
{
-#if defined HAVE_LANGINFO_CODESET && MBS_SUPPORT
- utf8 = (STREQ (nl_langinfo (CODESET), "UTF-8"));
-#else
- utf8 = 0;
-#endif
+ wchar_t wc;
+ mbstate_t mbs = { 0 };
+ utf8 = mbrtowc (&wc, "\xc4\x80", 2, &mbs) == 2 && wc == 0x100;
}
-
return utf8;
}
+/* The current locale is known to be a unibyte locale
+ without multicharacter collating sequences and where range
+ comparisons simply use the native encoding. These locales can be
+ processed more efficiently. */
+
+static bool
+using_simple_locale (void)
+{
+ /* The native character set is known to be compatible with
+ the C locale. The following test isn't perfect, but it's good
+ enough in practice, as only ASCII and EBCDIC are in common use
+ and this test correctly accepts ASCII and rejects EBCDIC. */
+ enum { native_c_charset =
+ ('\b' == 8 && '\t' == 9 && '\n' == 10 && '\v' == 11 && '\f' == 12
+ && '\r' == 13 && ' ' == 32 && '!' == 33 && '"' == 34 && '#' == 35
+ && '%' == 37 && '&' == 38 && '\'' == 39 && '(' == 40 && ')' == 41
+ && '*' == 42 && '+' == 43 && ',' == 44 && '-' == 45 && '.' == 46
+ && '/' == 47 && '0' == 48 && '9' == 57 && ':' == 58 && ';' == 59
+ && '<' == 60 && '=' == 61 && '>' == 62 && '?' == 63 && 'A' == 65
+ && 'Z' == 90 && '[' == 91 && '\\' == 92 && ']' == 93 && '^' == 94
+ && '_' == 95 && 'a' == 97 && 'z' == 122 && '{' == 123 && '|' == 124
+ && '}' == 125 && '~' == 126)
+ };
+
+ if (! native_c_charset || dfa->multibyte)
+ return false;
+ else
+ {
+ static int unibyte_c = -1;
+ if (unibyte_c < 0)
+ {
+ char const *locale = setlocale (LC_ALL, NULL);
+ unibyte_c = (!locale
+ || STREQ (locale, "C")
+ || STREQ (locale, "POSIX"));
+ }
+ return unibyte_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. */
+ 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 char const *lexptr; /* Pointer to next input character. */
+static size_t lexleft; /* Number of characters remaining. */
+static token lasttok; /* Previous token returned; initially END. */
+static bool laststart; /* We're separated from beginning or (,
+ | only by zero-width characters. */
+static size_t parens; /* Count of outstanding left parens. */
+static int minrep, maxrep; /* Repeat counts for {m,n}. */
-static int cur_mb_len = 1; /* Length of the multibyte representation of
+static int cur_mb_len = 1; /* Length of the multibyte representation of
wctok. */
-/* These variables are used only if (MB_CUR_MAX > 1). */
-static mbstate_t mbs; /* Mbstate for mbrlen(). */
-static wchar_t wctok; /* Wide character representation of the current
- multibyte character. */
-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(). */
-
-
-#if MBS_SUPPORT
-/* Note that characters become unsigned here. */
+
+static wint_t wctok; /* Wide character representation of the current
+ multibyte character, or WEOF if there was
+ an encoding error. Used only if
+ MB_CUR_MAX > 1. */
+
+
+/* Fetch the next lexical input character. Set C (of type int) to the
+ next input byte, except set C to EOF if the input is a multibyte
+ character of length greater than 1. Set WC (of type wint_t) to the
+ value of the input if it is a valid multibyte character (possibly
+ of length 1); otherwise set WC to WEOF. If there is no more input,
+ report EOFERR if EOFERR is not null, and return lasttok = END
+ otherwise. */
# define FETCH_WC(c, wc, eoferr) \
do { \
if (! lexleft) \
@@ -792,77 +900,97 @@ static unsigned char const *buf_end; /* reference to end in dfaexec(). */
} \
else \
{ \
- wchar_t _wc; \
- cur_mb_len = mbrtowc(&_wc, lexptr, lexleft, &mbs); \
- if (cur_mb_len <= 0) \
- { \
- cur_mb_len = 1; \
- --lexleft; \
- (wc) = (c) = to_uchar (*lexptr++); \
- } \
- else \
- { \
- lexptr += cur_mb_len; \
- lexleft -= cur_mb_len; \
- (wc) = _wc; \
- (c) = wctob(wc); \
- } \
+ wint_t _wc; \
+ size_t nbytes = mbs_to_wchar (&_wc, lexptr, lexleft, dfa); \
+ cur_mb_len = nbytes; \
+ (wc) = _wc; \
+ (c) = nbytes == 1 ? to_uchar (*lexptr) : EOF; \
+ lexptr += nbytes; \
+ lexleft -= nbytes; \
} \
- } while(0)
+ } while (0)
-# define FETCH(c, eoferr) \
- do { \
- wint_t wc; \
- FETCH_WC(c, wc, eoferr); \
- } while(0)
+#ifndef MIN
+# define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
-#else
-/* Note that characters become unsigned here. */
-# define FETCH(c, eoferr) \
- do { \
- if (! lexleft) \
- { \
- if ((eoferr) != 0) \
- dfaerror (eoferr); \
- else \
- return lasttok = END; \
- } \
- (c) = to_uchar (*lexptr++); \
- --lexleft; \
- } while(0)
-
-# define FETCH_WC(c, unused, eoferr) FETCH (c, eoferr)
-
-#endif /* MBS_SUPPORT */
+/* The set of wchar_t values C such that there's a useful locale
+ somewhere where C != towupper (C) && C != towlower (towupper (C)).
+ For example, 0x00B5 (U+00B5 MICRO SIGN) is in this table, because
+ towupper (0x00B5) == 0x039C (U+039C GREEK CAPITAL LETTER MU), and
+ towlower (0x039C) == 0x03BC (U+03BC GREEK SMALL LETTER MU). */
+static short const lonesome_lower[] =
+ {
+ 0x00B5, 0x0131, 0x017F, 0x01C5, 0x01C8, 0x01CB, 0x01F2, 0x0345,
+ 0x03C2, 0x03D0, 0x03D1, 0x03D5, 0x03D6, 0x03F0, 0x03F1,
+
+ /* U+03F2 GREEK LUNATE SIGMA SYMBOL lacks a specific uppercase
+ counterpart in locales predating Unicode 4.0.0 (April 2003). */
+ 0x03F2,
+
+ 0x03F5, 0x1E9B, 0x1FBE,
+ };
+
+/* Maximum number of characters that can be the case-folded
+ counterparts of a single character, not counting the character
+ itself. This is 1 for towupper, 1 for towlower, and 1 for each
+ entry in LONESOME_LOWER. */
+enum
+{ CASE_FOLDED_BUFSIZE = 2 + sizeof lonesome_lower / sizeof *lonesome_lower };
+
+/* Find the characters equal to C after case-folding, other than C
+ itself, and store them into FOLDED. Return the number of characters
+ stored. */
+static int
+case_folded_counterparts (wchar_t c, wchar_t folded[CASE_FOLDED_BUFSIZE])
+{
+ int i;
+ int n = 0;
+ wint_t uc = towupper (c);
+ wint_t lc = towlower (uc);
+ if (uc != c)
+ folded[n++] = uc;
+ if (lc != uc && lc != c && towupper (lc) == uc)
+ folded[n++] = lc;
+ for (i = 0; i < sizeof lonesome_lower / sizeof *lonesome_lower; i++)
+ {
+ wint_t li = lonesome_lower[i];
+ if (li != lc && li != uc && li != c && towupper (li) == uc)
+ folded[n++] = li;
+ }
+ return n;
+}
typedef int predicate (int);
/* 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. */
-struct dfa_ctype {
+ the class. The leading [ has already been eaten by the lexical
+ analyzer. */
+struct dfa_ctype
+{
const char *name;
predicate *func;
bool single_byte_only;
};
static const struct dfa_ctype prednames[] = {
- { "alpha", isalpha, false },
- { "upper", isupper, false },
- { "lower", islower, false },
- { "digit", isdigit, true },
- { "xdigit", isxdigit, true },
- { "space", isspace, false },
- { "punct", ispunct, false },
- { "alnum", isalnum, false },
- { "print", isprint, false },
- { "graph", isgraph, false },
- { "cntrl", iscntrl, false },
- { "blank", is_blank, false },
- { NULL, NULL, false }
+ {"alpha", isalpha, false},
+ {"upper", isupper, false},
+ {"lower", islower, false},
+ {"digit", isdigit, true},
+ {"xdigit", isxdigit, false},
+ {"space", isspace, false},
+ {"punct", ispunct, false},
+ {"alnum", isalnum, false},
+ {"print", isprint, false},
+ {"graph", isgraph, false},
+ {"cntrl", iscntrl, false},
+ {"blank", is_blank, false},
+ {NULL, NULL, false}
};
-static const struct dfa_ctype *
+static const struct dfa_ctype *_GL_ATTRIBUTE_PURE
find_pred (const char *str)
{
unsigned int i;
@@ -874,15 +1002,17 @@ find_pred (const char *str)
}
/* Multibyte character handling sub-routine for lex.
- This function parse a bracket expression and build a struct
- mb_char_classes. */
+ Parse a bracket expression and build a struct mb_char_classes. */
static token
parse_bracket_exp (void)
{
- int invert;
+ bool invert;
int c, c1, c2;
charclass ccl;
- wint_t wc1 = 0;
+
+ /* This is a bracket expression that dfaexec is known to
+ process correctly. */
+ bool known_bracket_exp = true;
/* Used to warn about [:space:].
Bit 0 = first character is a colon.
@@ -893,21 +1023,21 @@ parse_bracket_exp (void)
wint_t wc;
wint_t wc2;
+ wint_t wc1 = 0;
/* 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;
+ size_t chars_al, ranges_al, ch_classes_al, equivs_al, coll_elems_al;
- chars_al = 1;
- range_sts_al = range_ends_al = 0;
- ch_classes_al = equivs_al = coll_elems_al = 0;
- if (MB_CUR_MAX > 1)
+ chars_al = ranges_al = ch_classes_al = equivs_al = coll_elems_al = 0;
+ if (dfa->multibyte)
{
- REALLOC_IF_NECESSARY(dfa->mbcsets, dfa->mbcsets_alloc, dfa->nmbcsets + 1);
+ dfa->mbcsets = maybe_realloc (dfa->mbcsets, dfa->nmbcsets,
+ &dfa->mbcsets_alloc,
+ sizeof *dfa->mbcsets);
/* dfa->multibyte_prop[] hold the index of dfa->mbcsets.
- We will update dfa->multibyte_prop[] in addtok(), because we can't
+ We will update dfa->multibyte_prop[] in addtok, because we can't
decide the index in dfa->tokens[]. */
/* Initialize work area. */
@@ -922,40 +1052,38 @@ parse_bracket_exp (void)
if (c == '^')
{
FETCH_WC (c, wc, _("unbalanced ["));
- invert = 1;
+ invert = true;
+ known_bracket_exp = using_simple_locale ();
}
else
- invert = 0;
+ invert = false;
colon_warning_state = (c == ':');
do
{
- c1 = EOF; /* mark c1 is not initialized". */
+ c1 = NOTCHAR; /* Mark c1 as not initialized. */
colon_warning_state &= ~2;
/* 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))
+ dfa is ever called. */
+ if (c == '[')
{
-#define BRACKET_BUFFER_SIZE 128
- char str[BRACKET_BUFFER_SIZE];
FETCH_WC (c1, wc1, _("unbalanced ["));
- /* If pattern contains `[[:', `[[.', or `[[='. */
- if (c1 == ':'
- /* TODO: handle `[[.' and `[[=' also for MB_CUR_MAX == 1. */
- || (MB_CUR_MAX > 1 && (c1 == '.' || c1 == '='))
- )
+ if ((c1 == ':' && (syntax_bits & RE_CHAR_CLASSES))
+ || c1 == '.' || c1 == '=')
{
+ enum { MAX_BRACKET_STRING_LEN = 32 };
+ char str[MAX_BRACKET_STRING_LEN + 1];
size_t len = 0;
for (;;)
{
FETCH_WC (c, wc, _("unbalanced ["));
if ((c == c1 && *lexptr == ']') || lexleft == 0)
break;
- if (len < BRACKET_BUFFER_SIZE)
+ if (len < MAX_BRACKET_STRING_LEN)
str[len++] = c;
else
/* This is in any case an invalid class name. */
@@ -966,63 +1094,37 @@ parse_bracket_exp (void)
/* Fetch bracket. */
FETCH_WC (c, wc, _("unbalanced ["));
if (c1 == ':')
- /* build character class. */
+ /* Build character class. POSIX allows character
+ classes to match multicharacter collating elements,
+ but the regex code does not support that, so do not
+ worry about that possibility. */
{
char const *class
- = (case_fold && (STREQ (str, "upper")
- || STREQ (str, "lower"))
- ? "alpha"
- : str);
+ = (case_fold && (STREQ (str, "upper")
+ || STREQ (str, "lower")) ? "alpha" : str);
const struct dfa_ctype *pred = find_pred (class);
if (!pred)
- dfaerror(_("invalid character class"));
+ dfaerror (_("invalid character class"));
- if (MB_CUR_MAX > 1 && !pred->single_byte_only)
+ if (dfa->multibyte && !pred->single_byte_only)
{
/* Store the character class as wctype_t. */
- wctype_t wt = wctype (class);
+ wctype_t wt = (wctype_t) wctype (class);
- if (ch_classes_al == 0)
- MALLOC(work_mbc->ch_classes, ++ch_classes_al);
- REALLOC_IF_NECESSARY(work_mbc->ch_classes,
- ch_classes_al,
- work_mbc->nch_classes + 1);
+ work_mbc->ch_classes
+ = maybe_realloc (work_mbc->ch_classes,
+ work_mbc->nch_classes, &ch_classes_al,
+ sizeof *work_mbc->ch_classes);
work_mbc->ch_classes[work_mbc->nch_classes++] = wt;
}
for (c2 = 0; c2 < NOTCHAR; ++c2)
- if (pred->func(c2))
- setbit_case_fold_c (c2, ccl);
+ if (pred->func (c2))
+ setbit (c2, ccl);
}
+ else
+ known_bracket_exp = false;
- else if (MBS_SUPPORT && (c1 == '=' || c1 == '.'))
- {
- char *elem;
- MALLOC(elem, len + 1);
- strncpy(elem, str, len + 1);
-
- if (c1 == '=')
- /* build equivalent class. */
- {
- if (equivs_al == 0)
- MALLOC(work_mbc->equivs, ++equivs_al);
- REALLOC_IF_NECESSARY(work_mbc->equivs,
- equivs_al,
- work_mbc->nequivs + 1);
- work_mbc->equivs[work_mbc->nequivs++] = elem;
- }
-
- if (c1 == '.')
- /* build collating element. */
- {
- if (coll_elems_al == 0)
- MALLOC(work_mbc->coll_elems, ++coll_elems_al);
- REALLOC_IF_NECESSARY(work_mbc->coll_elems,
- coll_elems_al,
- work_mbc->ncoll_elems + 1);
- work_mbc->coll_elems[work_mbc->ncoll_elems++] = elem;
- }
- }
colon_warning_state |= 8;
/* Fetch new lookahead character. */
@@ -1035,105 +1137,114 @@ parse_bracket_exp (void)
}
if (c == '\\' && (syntax_bits & RE_BACKSLASH_ESCAPE_IN_LISTS))
- FETCH_WC(c, wc, _("unbalanced ["));
+ FETCH_WC (c, wc, _("unbalanced ["));
- if (c1 == EOF)
- FETCH_WC(c1, wc1, _("unbalanced ["));
+ if (c1 == NOTCHAR)
+ FETCH_WC (c1, wc1, _("unbalanced ["));
if (c1 == '-')
/* build range characters. */
{
- FETCH_WC(c2, wc2, _("unbalanced ["));
- if (c2 == ']')
+ FETCH_WC (c2, wc2, _("unbalanced ["));
+
+ /* A bracket expression like [a-[.aa.]] matches an unknown set.
+ Treat it like [-a[.aa.]] while parsing it, and
+ remember that the set is unknown. */
+ if (c2 == '[' && *lexptr == '.')
{
- /* 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;
+ known_bracket_exp = false;
+ c2 = ']';
}
- }
-
- if (c1 == '-' && c2 != ']')
- {
- if (c2 == '\\'
- && (syntax_bits & RE_BACKSLASH_ESCAPE_IN_LISTS))
- FETCH_WC(c2, wc2, _("unbalanced ["));
- if (MB_CUR_MAX > 1)
+ if (c2 != ']')
{
- /* When case folding map a range, say [m-z] (or even [M-z])
- to the pair of ranges, [m-z] [M-Z]. */
- if (range_sts_al == 0)
- {
- MALLOC(work_mbc->range_sts, ++range_sts_al);
- MALLOC(work_mbc->range_ends, ++range_ends_al);
- }
- REALLOC_IF_NECESSARY(work_mbc->range_sts,
- range_sts_al, work_mbc->nranges + 1);
- REALLOC_IF_NECESSARY(work_mbc->range_ends,
- range_ends_al, work_mbc->nranges + 1);
- work_mbc->range_sts[work_mbc->nranges] =
- case_fold ? towlower(wc) : (wchar_t)wc;
- work_mbc->range_ends[work_mbc->nranges++] =
- case_fold ? towlower(wc2) : (wchar_t)wc2;
-
-#ifndef GREP
- if (case_fold && (iswalpha(wc) || iswalpha(wc2)))
+ if (c2 == '\\' && (syntax_bits & RE_BACKSLASH_ESCAPE_IN_LISTS))
+ FETCH_WC (c2, wc2, _("unbalanced ["));
+
+ if (dfa->multibyte)
{
- REALLOC_IF_NECESSARY(work_mbc->range_sts,
- range_sts_al, work_mbc->nranges + 1);
- work_mbc->range_sts[work_mbc->nranges] = towupper(wc);
- REALLOC_IF_NECESSARY(work_mbc->range_ends,
- range_ends_al, work_mbc->nranges + 1);
- work_mbc->range_ends[work_mbc->nranges++] = towupper(wc2);
+ /* When case folding map a range, say [m-z] (or even [M-z])
+ to the pair of ranges, [m-z] [M-Z]. Although this code
+ is wrong in multiple ways, it's never used in practice.
+ FIXME: Remove this (and related) unused code. */
+ if (wc != WEOF && wc2 != WEOF)
+ {
+ work_mbc->ranges
+ = maybe_realloc (work_mbc->ranges,
+ work_mbc->nranges + 2,
+ &ranges_al, sizeof *work_mbc->ranges);
+ work_mbc->ranges[work_mbc->nranges].beg
+ = case_fold ? towlower (wc) : wc;
+ work_mbc->ranges[work_mbc->nranges++].end
+ = case_fold ? towlower (wc2) : wc2;
+
+ if (case_fold && (iswalpha (wc) || iswalpha (wc2)))
+ {
+ work_mbc->ranges[work_mbc->nranges].beg
+ = towupper (wc);
+ work_mbc->ranges[work_mbc->nranges++].end
+ = towupper (wc2);
+ }
+ }
}
-#endif
- }
- else
- {
- c1 = c;
- if (case_fold)
+ else if (using_simple_locale ())
{
- c1 = tolower (c1);
- c2 = tolower (c2);
+ for (c1 = c; c1 <= c2; c1++)
+ setbit (c1, ccl);
+ if (case_fold)
+ {
+ int uc = toupper (c);
+ int uc2 = toupper (c2);
+ for (c1 = 0; c1 < NOTCHAR; c1++)
+ {
+ int uc1 = toupper (c1);
+ if (uc <= uc1 && uc1 <= uc2)
+ setbit (c1, ccl);
+ }
+ }
}
- for (c = c1; c <= c2; c++)
- setbit_case_fold_c (c, ccl);
+ else
+ known_bracket_exp = false;
+
+ colon_warning_state |= 8;
+ FETCH_WC (c1, wc1, _("unbalanced ["));
+ continue;
}
- colon_warning_state |= 8;
- FETCH_WC(c1, wc1, _("unbalanced ["));
- continue;
+ /* 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;
}
colon_warning_state |= (c == ':') ? 2 : 4;
- if (MB_CUR_MAX == 1)
+ if (!dfa->multibyte)
{
- setbit_case_fold_c (c, ccl);
+ if (case_fold)
+ setbit_case_fold_c (c, ccl);
+ else
+ setbit (c, ccl);
continue;
}
- if (case_fold && iswalpha(wc))
- {
- wc = towlower(wc);
- if (!setbit_wc (wc, ccl))
- {
- REALLOC_IF_NECESSARY(work_mbc->chars, chars_al,
- work_mbc->nchars + 1);
- work_mbc->chars[work_mbc->nchars++] = wc;
- }
-#ifdef GREP
- continue;
-#else
- wc = towupper(wc);
-#endif
- }
- if (!setbit_wc (wc, ccl))
+ if (wc == WEOF)
+ known_bracket_exp = false;
+ else
{
- REALLOC_IF_NECESSARY(work_mbc->chars, chars_al,
- work_mbc->nchars + 1);
- work_mbc->chars[work_mbc->nchars++] = wc;
+ wchar_t folded[CASE_FOLDED_BUFSIZE + 1];
+ int i;
+ int n = (case_fold ? case_folded_counterparts (wc, folded + 1) + 1
+ : 1);
+ folded[0] = wc;
+ for (i = 0; i < n; i++)
+ if (!setbit_wc (folded[i], ccl))
+ {
+ work_mbc->chars
+ = maybe_realloc (work_mbc->chars, work_mbc->nchars,
+ &chars_al, sizeof *work_mbc->chars);
+ work_mbc->chars[work_mbc->nchars++] = folded[i];
+ }
}
}
while ((wc = wc1, (c = c1) != ']'));
@@ -1141,33 +1252,47 @@ parse_bracket_exp (void)
if (colon_warning_state == 7)
dfawarn (_("character class syntax is [[:space:]], not [:space:]"));
- if (MB_CUR_MAX > 1)
+ if (! known_bracket_exp)
+ return BACKREF;
+
+ if (dfa->multibyte)
{
static charclass zeroclass;
work_mbc->invert = invert;
- work_mbc->cset = equal(ccl, zeroclass) ? -1 : charclass_index(ccl);
+ work_mbc->cset = equal (ccl, zeroclass) ? -1 : charclass_index (ccl);
return MBCSET;
}
if (invert)
{
- assert(MB_CUR_MAX == 1);
- notset(ccl);
+ assert (!dfa->multibyte);
+ notset (ccl);
if (syntax_bits & RE_HAT_LISTS_NOT_NEWLINE)
- clrbit(eolbyte, ccl);
+ clrbit (eolbyte, ccl);
}
- return CSET + charclass_index(ccl);
+ return CSET + charclass_index (ccl);
}
-/* Return non-zero if C is a `word-constituent' byte; zero otherwise. */
-#define IS_WORD_CONSTITUENT(C) (isalnum(C) || (C) == '_')
+#define PUSH_LEX_STATE(s) \
+ do \
+ { \
+ char const *lexptr_saved = lexptr; \
+ size_t lexleft_saved = lexleft; \
+ lexptr = (s); \
+ lexleft = strlen (lexptr)
+
+#define POP_LEX_STATE() \
+ lexptr = lexptr_saved; \
+ lexleft = lexleft_saved; \
+ } \
+ while (0)
static token
lex (void)
{
- unsigned int c, c2;
- int backslash = 0;
+ int c, c2;
+ bool backslash = false;
charclass ccl;
int i;
@@ -1179,14 +1304,7 @@ lex (void)
"if (backslash) ...". */
for (i = 0; i < 2; ++i)
{
- if (MB_CUR_MAX > 1)
- {
- FETCH_WC (c, wctok, NULL);
- if ((int)c == EOF)
- goto normal_char;
- }
- else
- FETCH(c, NULL);
+ FETCH_WC (c, wctok, NULL);
switch (c)
{
@@ -1194,17 +1312,15 @@ lex (void)
if (backslash)
goto normal_char;
if (lexleft == 0)
- dfaerror(_("unfinished \\ escape"));
- backslash = 1;
+ dfaerror (_("unfinished \\ escape"));
+ backslash = true;
break;
case '^':
if (backslash)
goto normal_char;
if (syntax_bits & RE_CONTEXT_INDEP_ANCHORS
- || lasttok == END
- || lasttok == LPAREN
- || lasttok == OR)
+ || lasttok == END || lasttok == LPAREN || lasttok == OR)
return lasttok = BEGLINE;
goto normal_char;
@@ -1235,19 +1351,19 @@ lex (void)
case '9':
if (backslash && !(syntax_bits & RE_NO_BK_REFS))
{
- laststart = 0;
+ laststart = false;
return lasttok = BACKREF;
}
goto normal_char;
case '`':
if (backslash && !(syntax_bits & RE_NO_GNU_OPS))
- return lasttok = BEGLINE; /* FIXME: should be beginning of string */
+ 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 */
+ return lasttok = ENDLINE; /* FIXME: should be end of string */
goto normal_char;
case '<':
@@ -1303,74 +1419,54 @@ lex (void)
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
+ {,N} - 0 through N
+ {,} - 0 to infinity (same as '*')
{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;
+ {
+ char const *p = lexptr;
+ char const *lim = p + lexleft;
+ minrep = maxrep = -1;
+ for (; p != lim && ISASCIIDIGIT (*p); p++)
+ {
+ if (minrep < 0)
+ minrep = *p - '0';
+ else
+ minrep = MIN (RE_DUP_MAX + 1, minrep * 10 + *p - '0');
+ }
+ if (p != lim)
+ {
+ if (*p != ',')
+ maxrep = minrep;
+ else
+ {
+ if (minrep < 0)
+ minrep = 0;
+ while (++p != lim && ISASCIIDIGIT (*p))
+ {
+ if (maxrep < 0)
+ maxrep = *p - '0';
+ else
+ maxrep = MIN (RE_DUP_MAX + 1, maxrep * 10 + *p - '0');
+ }
+ }
+ }
+ if (! ((! backslash || (p != lim && *p++ == '\\'))
+ && p != lim && *p++ == '}'
+ && 0 <= minrep && (maxrep < 0 || minrep <= maxrep)))
+ {
+ if (syntax_bits & RE_INVALID_INTERVAL_ORD)
+ goto normal_char;
+ dfaerror (_("invalid content of \\{\\}"));
+ }
+ if (RE_DUP_MAX < maxrep)
+ dfaerror (_("regular expression too big"));
+ lexptr = p;
+ lexleft = lim - p;
+ }
+ laststart = false;
return lasttok = REPMN;
case '|':
@@ -1378,22 +1474,21 @@ lex (void)
goto normal_char;
if (backslash != ((syntax_bits & RE_NO_BK_VBAR) == 0))
goto normal_char;
- laststart = 1;
+ laststart = true;
return lasttok = OR;
case '\n':
if (syntax_bits & RE_LIMITED_OPS
- || backslash
- || !(syntax_bits & RE_NEWLINE_ALT))
+ || backslash || !(syntax_bits & RE_NEWLINE_ALT))
goto normal_char;
- laststart = 1;
+ laststart = true;
return lasttok = OR;
case '(':
if (backslash != ((syntax_bits & RE_NO_BK_PARENS) == 0))
goto normal_char;
++parens;
- laststart = 1;
+ laststart = true;
return lasttok = LPAREN;
case ')':
@@ -1402,73 +1497,110 @@ lex (void)
if (parens == 0 && syntax_bits & RE_UNMATCHED_RIGHT_PAREN_ORD)
goto normal_char;
--parens;
- laststart = 0;
+ laststart = false;
return lasttok = RPAREN;
case '.':
if (backslash)
goto normal_char;
- if (MB_CUR_MAX > 1)
+ if (dfa->multibyte)
{
/* In multibyte environment period must match with a single
character not a byte. So we use ANYCHAR. */
- laststart = 0;
+ laststart = false;
return lasttok = ANYCHAR;
}
- zeroset(ccl);
- notset(ccl);
+ zeroset (ccl);
+ notset (ccl);
if (!(syntax_bits & RE_DOT_NEWLINE))
- clrbit(eolbyte, ccl);
+ clrbit (eolbyte, ccl);
if (syntax_bits & RE_DOT_NOT_NULL)
- clrbit('\0', ccl);
- laststart = 0;
- return lasttok = CSET + charclass_index(ccl);
+ clrbit ('\0', ccl);
+ laststart = false;
+ return lasttok = CSET + charclass_index (ccl);
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);
+ if (!dfa->multibyte)
+ {
+ zeroset (ccl);
+ for (c2 = 0; c2 < NOTCHAR; ++c2)
+ if (isspace (c2))
+ setbit (c2, ccl);
+ if (c == 'S')
+ notset (ccl);
+ laststart = false;
+ return lasttok = CSET + charclass_index (ccl);
+ }
+
+ /* FIXME: see if optimizing this, as is done with ANYCHAR and
+ add_utf8_anychar, makes sense. */
+
+ /* \s and \S are documented to be equivalent to [[:space:]] and
+ [^[:space:]] respectively, so tell the lexer to process those
+ strings, each minus its "already processed" '['. */
+ PUSH_LEX_STATE (c == 's' ? "[:space:]]" : "^[:space:]]");
+
+ lasttok = parse_bracket_exp ();
+
+ POP_LEX_STATE ();
+
+ laststart = false;
+ return lasttok;
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);
+
+ if (!dfa->multibyte)
+ {
+ zeroset (ccl);
+ for (c2 = 0; c2 < NOTCHAR; ++c2)
+ if (IS_WORD_CONSTITUENT (c2))
+ setbit (c2, ccl);
+ if (c == 'W')
+ notset (ccl);
+ laststart = false;
+ return lasttok = CSET + charclass_index (ccl);
+ }
+
+ /* FIXME: see if optimizing this, as is done with ANYCHAR and
+ add_utf8_anychar, makes sense. */
+
+ /* \w and \W are documented to be equivalent to [_[:alnum:]] and
+ [^_[:alnum:]] respectively, so tell the lexer to process those
+ strings, each minus its "already processed" '['. */
+ PUSH_LEX_STATE (c == 'w' ? "_[:alnum:]]" : "^_[:alnum:]]");
+
+ lasttok = parse_bracket_exp ();
+
+ POP_LEX_STATE ();
+
+ laststart = false;
+ return lasttok;
case '[':
if (backslash)
goto normal_char;
- laststart = 0;
- return lasttok = parse_bracket_exp();
+ laststart = false;
+ return lasttok = parse_bracket_exp ();
default:
normal_char:
- laststart = 0;
+ laststart = false;
/* For multibyte character sets, folding is done in atom. Always
return WCHAR. */
- if (MB_CUR_MAX > 1)
+ if (dfa->multibyte)
return lasttok = WCHAR;
- if (case_fold && isalpha(c))
+ if (case_fold && isalpha (c))
{
- zeroset(ccl);
+ zeroset (ccl);
setbit_case_fold_c (c, ccl);
- return lasttok = CSET + charclass_index(ccl);
+ return lasttok = CSET + charclass_index (ccl);
}
return lasttok = c;
@@ -1476,31 +1608,33 @@ lex (void)
}
/* The above loop should consume at most a backslash
- and some other character. */
- abort();
- return END; /* keeps pedantic compilers happy. */
+ and some other character. */
+ abort ();
+ return END; /* keeps pedantic compilers happy. */
}
-/* Recursive descent parser for regular expressions. */
+/* Recursive descent parser for regular expressions. */
-static token tok; /* Lookahead token. */
-static int depth; /* Current depth of a hypothetical stack
+static token tok; /* Lookahead token. */
+static size_t 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(). */
+ dfaanalyze. */
static void
addtok_mb (token t, int mbprop)
{
- if (MB_CUR_MAX > 1)
+ if (dfa->talloc == dfa->tindex)
{
- REALLOC_IF_NECESSARY(dfa->multibyte_prop, dfa->nmultibyte_prop,
- dfa->tindex + 1);
- dfa->multibyte_prop[dfa->tindex] = mbprop;
+ dfa->tokens = x2nrealloc (dfa->tokens, &dfa->talloc,
+ sizeof *dfa->tokens);
+ if (dfa->multibyte)
+ dfa->multibyte_prop = xnrealloc (dfa->multibyte_prop, dfa->talloc,
+ sizeof *dfa->multibyte_prop);
}
-
- REALLOC_IF_NECESSARY(dfa->tokens, dfa->talloc, dfa->tindex + 1);
+ if (dfa->multibyte)
+ dfa->multibyte_prop[dfa->tindex] = mbprop;
dfa->tokens[dfa->tindex++] = t;
switch (t)
@@ -1515,8 +1649,12 @@ addtok_mb (token t, int mbprop)
--depth;
break;
+ case BACKREF:
+ dfa->fast = false;
+ /* fallthrough */
default:
++dfa->nleaves;
+ /* fallthrough */
case EMPTY:
++depth;
break;
@@ -1528,11 +1666,11 @@ addtok_mb (token t, int mbprop)
static void addtok_wc (wint_t wc);
/* Add the given token to the parse tree, maintaining the depth count and
- updating the maximum depth if necessary. */
+ updating the maximum depth if necessary. */
static void
addtok (token t)
{
- if (MB_CUR_MAX > 1 && t == MBCSET)
+ if (dfa->multibyte && t == MBCSET)
{
bool need_or = false;
struct mb_char_classes *work_mbc = &dfa->mbcsets[dfa->nmbcsets - 1];
@@ -1541,7 +1679,7 @@ addtok (token t)
This does not require UTF-8. */
if (!work_mbc->invert)
{
- int i;
+ size_t i;
for (i = 0; i < work_mbc->nchars; i++)
{
addtok_wc (work_mbc->chars[i]);
@@ -1552,14 +1690,14 @@ addtok (token t)
work_mbc->nchars = 0;
}
- /* UTF-8 allows treating a simple, non-inverted MBCSET like a CSET. */
+ /* If the MBCSET is non-inverted and doesn't include neither
+ character classes including multibyte characters, range
+ expressions, equivalence classes nor collating elements,
+ it can be replaced to a simple CSET. */
if (work_mbc->invert
- || (!using_utf8() && work_mbc->cset != -1)
- || work_mbc->nchars != 0
|| work_mbc->nch_classes != 0
|| work_mbc->nranges != 0
- || work_mbc->nequivs != 0
- || work_mbc->ncoll_elems != 0)
+ || work_mbc->nequivs != 0 || work_mbc->ncoll_elems != 0)
{
addtok_mb (MBCSET, ((dfa->nmbcsets - 1) << 2) + 3);
if (need_or)
@@ -1571,7 +1709,6 @@ addtok (token t)
that the mbcset is empty now. Do nothing in that case. */
if (work_mbc->cset != -1)
{
- assert (using_utf8 ());
addtok (CSET + work_mbc->cset);
if (need_or)
addtok (OR);
@@ -1584,49 +1721,57 @@ addtok (token t)
}
}
-#if 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>".
+ e.g., we construct the 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> */
static void
addtok_wc (wint_t wc)
{
unsigned char buf[MB_LEN_MAX];
- mbstate_t s;
+ mbstate_t s = { 0 };
int i;
- memset (&s, 0, sizeof s);
- cur_mb_len = wcrtomb ((char *) buf, wc, &s);
+ size_t stored_bytes = wcrtomb ((char *) buf, wc, &s);
- /* This is merely stop-gap. When cur_mb_len is 0 or negative,
- buf[0] is undefined, yet skipping the addtok_mb call altogether
- can result in heap corruption. */
- if (cur_mb_len <= 0)
- buf[0] = 0;
+ if (stored_bytes != (size_t) -1)
+ cur_mb_len = stored_bytes;
+ else
+ {
+ /* This is merely stop-gap. buf[0] is undefined, yet skipping
+ the addtok_mb call altogether can corrupt the heap. */
+ cur_mb_len = 1;
+ buf[0] = 0;
+ }
- addtok_mb(buf[0], cur_mb_len == 1 ? 3 : 1);
+ addtok_mb (buf[0], cur_mb_len == 1 ? 3 : 1);
for (i = 1; i < cur_mb_len; i++)
{
- addtok_mb(buf[i], i == cur_mb_len - 1 ? 2 : 0);
- addtok(CAT);
+ addtok_mb (buf[i], i == cur_mb_len - 1 ? 2 : 0);
+ addtok (CAT);
}
}
-#else
-static void addtok_wc (wint_t wc) {}
-#endif
static void
add_utf8_anychar (void)
{
-#if MBS_SUPPORT
static const charclass utf8_classes[5] = {
- { 0, 0, 0, 0, ~0, ~0, 0, 0 }, /* 80-bf: non-lead bytes */
- { ~0, ~0, ~0, ~0, 0, 0, 0, 0 }, /* 00-7f: 1-byte sequence */
- { 0, 0, 0, 0, 0, 0, 0xfffffffcU, 0 }, /* c2-df: 2-byte sequence */
- { 0, 0, 0, 0, 0, 0, 0, 0xffff }, /* e0-ef: 3-byte sequence */
- { 0, 0, 0, 0, 0, 0, 0, 0xff0000 } /* f0-f7: 4-byte sequence */
+ /* 80-bf: non-leading bytes. */
+ {0, 0, 0, 0, CHARCLASS_WORD_MASK, CHARCLASS_WORD_MASK, 0, 0},
+
+ /* 00-7f: 1-byte sequence. */
+ {CHARCLASS_WORD_MASK, CHARCLASS_WORD_MASK, CHARCLASS_WORD_MASK,
+ CHARCLASS_WORD_MASK, 0, 0, 0, 0},
+
+ /* c2-df: 2-byte sequence. */
+ {0, 0, 0, 0, 0, 0, ~3 & CHARCLASS_WORD_MASK, 0},
+
+ /* e0-ef: 3-byte sequence. */
+ {0, 0, 0, 0, 0, 0, 0, 0xffff},
+
+ /* f0-f7: 4-byte sequence. */
+ {0, 0, 0, 0, 0, 0, 0, 0xff0000}
};
const unsigned int n = sizeof (utf8_classes) / sizeof (utf8_classes[0]);
unsigned int i;
@@ -1644,15 +1789,15 @@ add_utf8_anychar (void)
if (syntax_bits & RE_DOT_NOT_NULL)
clrbit ('\0', c);
}
- dfa->utf8_anychar_classes[i] = CSET + charclass_index(c);
+ dfa->utf8_anychar_classes[i] = CSET + charclass_index (c);
}
/* A valid UTF-8 character is
- ([0x00-0x7f]
- |[0xc2-0xdf][0x80-0xbf]
- |[0xe0-0xef[0x80-0xbf][0x80-0xbf]
- |[0xf0-f7][0x80-0xbf][0x80-0xbf][0x80-0xbf])
+ ([0x00-0x7f]
+ |[0xc2-0xdf][0x80-0xbf]
+ |[0xe0-0xef[0x80-0xbf][0x80-0xbf]
+ |[0xf0-f7][0x80-0xbf][0x80-0xbf][0x80-0xbf])
which I'll write more concisely "B|CA|DAA|EAAA". Factor the [0x00-0x7f]
and you get "B|(C|(D|EA)A)A". And since the token buffer is in reverse
@@ -1665,7 +1810,6 @@ add_utf8_anychar (void)
addtok (CAT);
addtok (OR);
}
-#endif
}
/* The grammar understood by the parser is as follows.
@@ -1701,67 +1845,70 @@ add_utf8_anychar (void)
LPAREN regexp RPAREN
<empty>
- The parser builds a parse tree in postfix form in an array of tokens. */
+ The parser builds a parse tree in postfix form in an array of tokens. */
static void
atom (void)
{
- if (0)
+ if (tok == WCHAR)
{
- /* empty */
- }
- else if (MBS_SUPPORT && tok == WCHAR)
- {
- addtok_wc (case_fold ? towlower(wctok) : wctok);
-#ifndef GREP
- if (case_fold && iswalpha(wctok))
+ if (wctok == WEOF)
+ addtok (BACKREF);
+ else
{
- addtok_wc (towupper(wctok));
- addtok (OR);
+ addtok_wc (wctok);
+
+ if (case_fold)
+ {
+ wchar_t folded[CASE_FOLDED_BUFSIZE];
+ int i, n = case_folded_counterparts (wctok, folded);
+ for (i = 0; i < n; i++)
+ {
+ addtok_wc (folded[i]);
+ addtok (OR);
+ }
+ }
}
-#endif
- tok = lex();
+ tok = lex ();
}
- else if (MBS_SUPPORT && tok == ANYCHAR && using_utf8())
+ else if (tok == ANYCHAR && using_utf8 ())
{
/* For UTF-8 expand the period to a series of CSETs that define a valid
UTF-8 character. This avoids using the slow multibyte path. I'm
pretty sure it would be both profitable and correct to do it for
any encoding; however, the optimization must be done manually as
- it is done above in add_utf8_anychar. So, let's start with
+ it is done above in add_utf8_anychar. So, let's start with
UTF-8: it is the most used, and the structure of the encoding
makes the correctness more obvious. */
- add_utf8_anychar();
- tok = lex();
+ add_utf8_anychar ();
+ tok = lex ();
}
else if ((tok >= 0 && tok < NOTCHAR) || tok >= CSET || tok == BACKREF
|| tok == BEGLINE || tok == ENDLINE || tok == BEGWORD
-#if MBS_SUPPORT
|| tok == ANYCHAR || tok == MBCSET
-#endif /* MBS_SUPPORT */
|| tok == ENDWORD || tok == LIMWORD || tok == NOTLIMWORD)
{
- addtok(tok);
- tok = lex();
+ addtok (tok);
+ tok = lex ();
}
else if (tok == LPAREN)
{
- tok = lex();
- regexp();
+ tok = lex ();
+ regexp ();
if (tok != RPAREN)
- dfaerror(_("unbalanced ("));
- tok = lex();
+ dfaerror (_("unbalanced ("));
+ tok = lex ();
}
else
- addtok(EMPTY);
+ addtok (EMPTY);
}
-/* Return the number of tokens in the given subexpression. */
-static int
-nsubtoks (int tindex)
+/* Return the number of tokens in the given subexpression. */
+static size_t _GL_ATTRIBUTE_PURE
+nsubtoks (size_t tindex)
{
- int ntoks1;
+ size_t ntoks1;
switch (dfa->tokens[tindex - 1])
{
@@ -1770,96 +1917,96 @@ nsubtoks (int tindex)
case QMARK:
case STAR:
case PLUS:
- return 1 + nsubtoks(tindex - 1);
+ return 1 + nsubtoks (tindex - 1);
case CAT:
case OR:
- ntoks1 = nsubtoks(tindex - 1);
- return 1 + ntoks1 + nsubtoks(tindex - 1 - ntoks1);
+ ntoks1 = nsubtoks (tindex - 1);
+ return 1 + ntoks1 + nsubtoks (tindex - 1 - ntoks1);
}
}
-/* Copy the given subexpression to the top of the tree. */
+/* Copy the given subexpression to the top of the tree. */
static void
-copytoks (int tindex, int ntokens)
+copytoks (size_t tindex, size_t ntokens)
{
- int i;
+ size_t i;
- for (i = 0; i < ntokens; ++i)
- {
- addtok(dfa->tokens[tindex + i]);
- /* Update index into multibyte csets. */
- if (MB_CUR_MAX > 1 && dfa->tokens[tindex + i] == MBCSET)
- dfa->multibyte_prop[dfa->tindex - 1] = dfa->multibyte_prop[tindex + i];
- }
+ if (dfa->multibyte)
+ for (i = 0; i < ntokens; ++i)
+ addtok_mb (dfa->tokens[tindex + i], dfa->multibyte_prop[tindex + i]);
+ else
+ for (i = 0; i < ntokens; ++i)
+ addtok_mb (dfa->tokens[tindex + i], 3);
}
static void
closure (void)
{
- int tindex, ntokens, i;
+ int i;
+ size_t tindex, ntokens;
- atom();
+ atom ();
while (tok == QMARK || tok == STAR || tok == PLUS || tok == REPMN)
if (tok == REPMN && (minrep || maxrep))
{
- ntokens = nsubtoks(dfa->tindex);
+ ntokens = nsubtoks (dfa->tindex);
tindex = dfa->tindex - ntokens;
if (maxrep < 0)
- addtok(PLUS);
+ addtok (PLUS);
if (minrep == 0)
- addtok(QMARK);
+ addtok (QMARK);
for (i = 1; i < minrep; ++i)
{
- copytoks(tindex, ntokens);
- addtok(CAT);
+ copytoks (tindex, ntokens);
+ addtok (CAT);
}
for (; i < maxrep; ++i)
{
- copytoks(tindex, ntokens);
- addtok(QMARK);
- addtok(CAT);
+ copytoks (tindex, ntokens);
+ addtok (QMARK);
+ addtok (CAT);
}
- tok = lex();
+ tok = lex ();
}
else if (tok == REPMN)
{
- dfa->tindex -= nsubtoks(dfa->tindex);
- tok = lex();
- closure();
+ dfa->tindex -= nsubtoks (dfa->tindex);
+ tok = lex ();
+ closure ();
}
else
{
- addtok(tok);
- tok = lex();
+ addtok (tok);
+ tok = lex ();
}
}
static void
branch (void)
{
- closure();
+ closure ();
while (tok != RPAREN && tok != OR && tok >= 0)
{
- closure();
- addtok(CAT);
+ closure ();
+ addtok (CAT);
}
}
static void
regexp (void)
{
- branch();
+ branch ();
while (tok == OR)
{
- tok = lex();
- branch();
- addtok(OR);
+ tok = lex ();
+ branch ();
+ 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. */
+ the struct dfa to parse into. */
void
dfaparse (char const *s, size_t len, struct dfa *d)
{
@@ -1867,56 +2014,71 @@ dfaparse (char const *s, size_t len, struct dfa *d)
lexptr = s;
lexleft = len;
lasttok = END;
- laststart = 1;
+ laststart = true;
parens = 0;
- if (MB_CUR_MAX > 1)
+ if (dfa->multibyte)
{
cur_mb_len = 0;
- memset(&mbs, 0, sizeof mbs);
+ memset (&d->mbs, 0, sizeof d->mbs);
}
- if (! syntax_bits_set)
- dfaerror(_("no syntax specified"));
+ if (!syntax_bits_set)
+ dfaerror (_("no syntax specified"));
- tok = lex();
+ tok = lex ();
depth = d->depth;
- regexp();
+ regexp ();
if (tok != END)
- dfaerror(_("unbalanced )"));
+ dfaerror (_("unbalanced )"));
- addtok(END - d->nregexps);
- addtok(CAT);
+ addtok (END - d->nregexps);
+ addtok (CAT);
if (d->nregexps)
- addtok(OR);
+ addtok (OR);
++d->nregexps;
}
-/* Some primitives for operating on sets of positions. */
+/* Some primitives for operating on sets of positions. */
-/* Copy one set to another; the destination must be large enough. */
+/* Copy one set to another. */
static void
-copy (position_set const *src, position_set *dst)
+copy (position_set const *src, position_set * dst)
{
- memcpy(dst->elems, src->elems, sizeof(dst->elems[0]) * src->nelem);
+ if (dst->alloc < src->nelem)
+ {
+ free (dst->elems);
+ dst->alloc = src->nelem;
+ dst->elems = x2nrealloc (NULL, &dst->alloc, sizeof *dst->elems);
+ }
+ memcpy (dst->elems, src->elems, src->nelem * sizeof *dst->elems);
dst->nelem = src->nelem;
}
+static void
+alloc_position_set (position_set * s, size_t size)
+{
+ s->elems = xnmalloc (size, sizeof *s->elems);
+ s->alloc = size;
+ s->nelem = 0;
+}
+
/* Insert position P in set S. S is maintained in sorted order on
decreasing index. If there is already an entry in S with P.index
then merge (logically-OR) P's constraints into the one in S.
- S->elems must point to an array large enough to hold the resulting set. */
+ S->elems must point to an array large enough to hold the resulting set. */
static void
-insert (position p, position_set *s)
+insert (position p, position_set * s)
{
- int count = s->nelem;
- int lo = 0, hi = count;
+ size_t count = s->nelem;
+ size_t lo = 0, hi = count;
+ size_t i;
while (lo < hi)
{
- int mid = ((unsigned) lo + (unsigned) hi) >> 1;
+ size_t mid = (lo + hi) >> 1;
if (s->elems[mid].index > p.index)
lo = mid + 1;
else
@@ -1924,24 +2086,31 @@ insert (position p, position_set *s)
}
if (lo < count && p.index == s->elems[lo].index)
- s->elems[lo].constraint |= p.constraint;
- else
{
- int i;
- for (i = count; i > lo; i--)
- s->elems[i] = s->elems[i - 1];
- s->elems[lo] = p;
- ++s->nelem;
+ s->elems[lo].constraint |= p.constraint;
+ return;
}
+
+ s->elems = maybe_realloc (s->elems, count, &s->alloc, sizeof *s->elems);
+ for (i = count; i > lo; i--)
+ s->elems[i] = s->elems[i - 1];
+ s->elems[lo] = p;
+ ++s->nelem;
}
/* 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. */
+ 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)
+merge (position_set const *s1, position_set const *s2, position_set * m)
{
- int i = 0, j = 0;
+ size_t i = 0, j = 0;
+ if (m->alloc < s1->nelem + s2->nelem)
+ {
+ free (m->elems);
+ m->elems = maybe_realloc (NULL, s1->nelem + s2->nelem, &m->alloc,
+ sizeof *m->elems);
+ }
m->nelem = 0;
while (i < s1->nelem && j < s2->nelem)
if (s1->elems[i].index > s2->elems[j].index)
@@ -1959,11 +2128,11 @@ merge (position_set const *s1, position_set const *s2, position_set *m)
m->elems[m->nelem++] = s2->elems[j++];
}
-/* Delete a position from a set. */
+/* Delete a position from a set. */
static void
-delete (position p, position_set *s)
+delete (position p, position_set * s)
{
- int i;
+ size_t i;
for (i = 0; i < s->nelem; ++i)
if (p.index == s->elems[i].index)
@@ -1975,26 +2144,22 @@ delete (position p, position_set *s)
/* 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)
+ state. Context tells whether we got here on a newline or letter. */
+static state_num
+state_index (struct dfa *d, position_set const *s, int context)
{
- int hash = 0;
+ size_t hash = 0;
int constraint;
- int i, j;
-
- newline = newline ? 1 : 0;
- letter = letter ? 1 : 0;
+ state_num i, j;
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. */
+ /* 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)
+ || context != d->states[i].context)
continue;
for (j = 0; j < s->nelem; ++j)
if (s->elems[j].constraint
@@ -2005,37 +2170,33 @@ state_index (struct dfa *d, position_set const *s, int newline, int letter)
return i;
}
- /* We'll have to create a new state. */
- REALLOC_IF_NECESSARY(d->states, d->salloc, d->sindex + 1);
+ /* We'll have to create a new state. */
+ d->states = maybe_realloc (d->states, d->sindex, &d->salloc,
+ sizeof *d->states);
d->states[i].hash = hash;
- MALLOC(d->states[i].elems.elems, s->nelem);
- copy(s, &d->states[i].elems);
- d->states[i].newline = newline;
- d->states[i].letter = letter;
- d->states[i].backref = 0;
+ alloc_position_set (&d->states[i].elems, s->nelem);
+ copy (s, &d->states[i].elems);
+ d->states[i].context = context;
+ d->states[i].has_backref = false;
+ d->states[i].has_mbcset = false;
d->states[i].constraint = 0;
d->states[i].first_end = 0;
- if (MBS_SUPPORT)
- {
- d->states[i].mbps.nelem = 0;
- d->states[i].mbps.elems = NULL;
- }
+ d->states[i].mbps.nelem = 0;
+ d->states[i].mbps.elems = NULL;
+
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))
+ if (SUCCEEDS_IN_CONTEXT (constraint, context, CTX_ANY))
d->states[i].constraint |= constraint;
- if (! d->states[i].first_end)
+ 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->states[i].has_backref = true;
}
++d->sindex;
@@ -2047,28 +2208,29 @@ state_index (struct dfa *d, position_set const *s, int newline, int letter)
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. */
+ S->elems must be large enough to hold the result. */
static void
-epsclosure (position_set *s, struct dfa const *d)
+epsclosure (position_set *s, struct dfa const *d, char *visited)
{
- int i, j;
- char *visited; /* array of booleans, enough to use char, not int */
+ size_t i, j;
position p, old;
-
- CALLOC(visited, d->tindex);
+ bool initialized = false;
for (i = 0; i < s->nelem; ++i)
if (d->tokens[s->elems[i].index] >= NOTCHAR
&& d->tokens[s->elems[i].index] != BACKREF
-#if MBS_SUPPORT
&& d->tokens[s->elems[i].index] != ANYCHAR
&& d->tokens[s->elems[i].index] != MBCSET
-#endif
&& d->tokens[s->elems[i].index] < CSET)
{
+ if (!initialized)
+ {
+ memset (visited, 0, d->tindex * sizeof (*visited));
+ initialized = true;
+ }
old = s->elems[i];
p.constraint = old.constraint;
- delete(s->elems[i], s);
+ delete (s->elems[i], s);
if (visited[old.index])
{
--i;
@@ -2101,15 +2263,60 @@ epsclosure (position_set *s, struct dfa const *d)
for (j = 0; j < d->follows[old.index].nelem; ++j)
{
p.index = d->follows[old.index].elems[j].index;
- insert(p, s);
+ insert (p, s);
}
- /* Force rescan to start at the beginning. */
+ /* Force rescan to start at the beginning. */
i = -1;
}
+}
+
+/* Returns the set of contexts for which there is at least one
+ character included in C. */
+
+static int
+charclass_context (charclass c)
+{
+ int context = 0;
+ unsigned int j;
+
+ if (tstbit (eolbyte, c))
+ context |= CTX_NEWLINE;
+
+ for (j = 0; j < CHARCLASS_WORDS; ++j)
+ {
+ if (c[j] & letters[j])
+ context |= CTX_LETTER;
+ if (c[j] & ~(letters[j] | newline[j]))
+ context |= CTX_NONE;
+ }
+
+ return context;
+}
+
+/* Returns the contexts on which the position set S depends. Each context
+ in the set of returned contexts (let's call it SC) may have a different
+ follow set than other contexts in SC, and also different from the
+ follow set of the complement set (sc ^ CTX_ANY). However, all contexts
+ in the complement set will have the same follow set. */
+
+static int _GL_ATTRIBUTE_PURE
+state_separate_contexts (position_set const *s)
+{
+ int separate_contexts = 0;
+ size_t j;
+
+ for (j = 0; j < s->nelem; ++j)
+ {
+ if (PREV_NEWLINE_DEPENDENT (s->elems[j].constraint))
+ separate_contexts |= CTX_NEWLINE;
+ if (PREV_LETTER_DEPENDENT (s->elems[j].constraint))
+ separate_contexts |= CTX_LETTER;
+ }
- free(visited);
+ return separate_contexts;
}
+
/* 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.
@@ -2161,239 +2368,223 @@ epsclosure (position_set *s, struct dfa const *d)
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. */
+ 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;
+ /* Array allocated to hold position sets. */
+ position *posalloc = xnmalloc (d->nleaves, 2 * sizeof *posalloc);
+ /* Firstpos and lastpos elements. */
+ position *firstpos = posalloc + d->nleaves;
+ position *lastpos = firstpos + d->nleaves;
+
+ /* Stack for element counts and nullable flags. */
+ struct
+ {
+ /* Whether the entry is nullable. */
+ bool nullable;
+
+ /* Counts of firstpos and lastpos sets. */
+ size_t nfirstpos;
+ size_t nlastpos;
+ } *stkalloc = xnmalloc (d->depth, sizeof *stkalloc), *stk = stkalloc;
+
+ position_set tmp; /* Temporary set for merging sets. */
+ position_set merged; /* Result of merging sets. */
+ int separate_contexts; /* Context wanted by some position. */
+ size_t i, j;
position *pos;
+ char *visited = xnmalloc (d->tindex, sizeof *visited);
#ifdef DEBUG
- fprintf(stderr, "dfaanalyze:\n");
+ fprintf (stderr, "dfaanalyze:\n");
for (i = 0; i < d->tindex; ++i)
{
- fprintf(stderr, " %d:", i);
- prtok(d->tokens[i]);
+ fprintf (stderr, " %zd:", i);
+ prtok (d->tokens[i]);
}
- putc('\n', stderr);
+ putc ('\n', stderr);
#endif
- d->searchflag = searchflag;
+ d->searchflag = searchflag != 0;
+ alloc_position_set (&merged, d->nleaves);
+ d->follows = xcalloc (d->tindex, sizeof *d->follows);
- MALLOC(nullable, d->depth);
- o_nullable = nullable;
- MALLOC(nfirstpos, d->depth);
- o_nfirst = nfirstpos;
- MALLOC(firstpos, d->nleaves);
- o_firstpos = firstpos, firstpos += d->nleaves;
- MALLOC(nlastpos, d->depth);
- o_nlast = nlastpos;
- MALLOC(lastpos, d->nleaves);
- o_lastpos = lastpos, lastpos += d->nleaves;
- CALLOC(nalloc, d->tindex);
- MALLOC(merged.elems, d->nleaves);
+ for (i = 0; i < d->tindex; ++i)
+ {
+ switch (d->tokens[i])
+ {
+ case EMPTY:
+ /* The empty set is nullable. */
+ stk->nullable = true;
- CALLOC(d->follows, d->tindex);
+ /* The firstpos and lastpos of the empty leaf are both empty. */
+ stk->nfirstpos = stk->nlastpos = 0;
+ stk++;
+ break;
- 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,
- nalloc[pos[j].index], merged.nelem);
- copy(&merged, &d->follows[pos[j].index]);
- }
+ case STAR:
+ case PLUS:
+ /* Every element in the firstpos of the argument is in the follow
+ of every element in the lastpos. */
+ tmp.nelem = stk[-1].nfirstpos;
+ tmp.elems = firstpos;
+ pos = lastpos;
+ for (j = 0; j < stk[-1].nlastpos; ++j)
+ {
+ merge (&tmp, &d->follows[pos[j].index], &merged);
+ copy (&merged, &d->follows[pos[j].index]);
+ }
+ /* fallthrough */
- 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,
- nalloc[pos[j].index], merged.nelem);
- copy(&merged, &d->follows[pos[j].index]);
- }
+ case QMARK:
+ /* A QMARK or STAR node is automatically nullable. */
+ if (d->tokens[i] != PLUS)
+ stk[-1].nullable = true;
+ break;
- /* 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:
- /* 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, nalloc[i]);
- 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 = stk[-1].nfirstpos;
+ tmp.elems = firstpos;
+ pos = lastpos + stk[-1].nlastpos;
+ for (j = 0; j < stk[-2].nlastpos; ++j)
+ {
+ merge (&tmp, &d->follows[pos[j].index], &merged);
+ 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 (stk[-2].nullable)
+ stk[-2].nfirstpos += stk[-1].nfirstpos;
+ else
+ firstpos += stk[-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 (stk[-1].nullable)
+ stk[-2].nlastpos += stk[-1].nlastpos;
+ else
+ {
+ pos = lastpos + stk[-2].nlastpos;
+ for (j = stk[-1].nlastpos; j-- > 0;)
+ pos[j] = lastpos[j];
+ lastpos += stk[-2].nlastpos;
+ stk[-2].nlastpos = stk[-1].nlastpos;
+ }
+
+ /* A CAT node is nullable if both arguments are nullable. */
+ stk[-2].nullable &= stk[-1].nullable;
+ stk--;
+ break;
+
+ case OR:
+ /* The firstpos is the union of the firstpos of each argument. */
+ stk[-2].nfirstpos += stk[-1].nfirstpos;
+
+ /* The lastpos is the union of the lastpos of each argument. */
+ stk[-2].nlastpos += stk[-1].nlastpos;
+
+ /* An OR node is nullable if either argument is nullable. */
+ stk[-2].nullable |= stk[-1].nullable;
+ stk--;
+ 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. */
+ stk->nullable = d->tokens[i] == BACKREF;
+
+ /* This position is in its own firstpos and lastpos. */
+ stk->nfirstpos = stk->nlastpos = 1;
+ stk++;
+
+ --firstpos, --lastpos;
+ firstpos->index = lastpos->index = i;
+ firstpos->constraint = lastpos->constraint = NO_CONSTRAINT;
+
+ /* Allocate the follow set for this position. */
+ alloc_position_set (&d->follows[i], 1);
+ 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)
+ /* ... balance the above nonsyntactic #ifdef goo... */
+ fprintf (stderr, "node %zd:", i);
+ prtok (d->tokens[i]);
+ putc ('\n', stderr);
+ fprintf (stderr,
+ stk[-1].nullable ? " nullable: yes\n" : " nullable: no\n");
+ fprintf (stderr, " firstpos:");
+ for (j = stk[-1].nfirstpos; j-- > 0;)
{
- fprintf(stderr, " %d:", firstpos[j].index);
- prtok(d->tokens[firstpos[j].index]);
+ fprintf (stderr, " %zd:", firstpos[j].index);
+ prtok (d->tokens[firstpos[j].index]);
}
- fprintf(stderr, "\n lastpos:");
- for (j = nlastpos[-1] - 1; j >= 0; --j)
+ fprintf (stderr, "\n lastpos:");
+ for (j = stk[-1].nlastpos; j-- > 0;)
{
- fprintf(stderr, " %d:", lastpos[j].index);
- prtok(d->tokens[lastpos[j].index]);
+ fprintf (stderr, " %zd:", lastpos[j].index);
+ prtok (d->tokens[lastpos[j].index]);
}
- putc('\n', stderr);
- }
+ putc ('\n', stderr);
#endif
+ }
/* For each follow set that is the follow set of a real position, replace
- it with its epsilon closure. */
+ it with its epsilon closure. */
for (i = 0; i < d->tindex; ++i)
if (d->tokens[i] < NOTCHAR || d->tokens[i] == BACKREF
-#if MBS_SUPPORT
- || d->tokens[i] == ANYCHAR
- || d->tokens[i] == MBCSET
-#endif
+ || d->tokens[i] == ANYCHAR || d->tokens[i] == MBCSET
|| 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, "follows(%zd:", i);
+ prtok (d->tokens[i]);
+ fprintf (stderr, "):");
+ for (j = d->follows[i].nelem; j-- > 0;)
{
- fprintf(stderr, " %d:", d->follows[i].elems[j].index);
- prtok(d->tokens[d->follows[i].elems[j].index]);
+ fprintf (stderr, " %zd:", d->follows[i].elems[j].index);
+ prtok (d->tokens[d->follows[i].elems[j].index]);
}
- putc('\n', stderr);
+ putc ('\n', stderr);
#endif
- copy(&d->follows[i], &merged);
- epsclosure(&merged, d);
- if (d->follows[i].nelem < merged.nelem)
- REALLOC(d->follows[i].elems, merged.nelem);
- copy(&merged, &d->follows[i]);
+ copy (&d->follows[i], &merged);
+ epsclosure (&merged, d, visited);
+ 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. */
+ 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, 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);
+ for (i = 0; i < stk[-1].nfirstpos; ++i)
+ insert (firstpos[i], &merged);
+ epsclosure (&merged, d, visited);
+
+ /* Build the initial state. */
+ separate_contexts = state_separate_contexts (&merged);
+ if (separate_contexts & CTX_NEWLINE)
+ state_index (d, &merged, CTX_NEWLINE);
+ d->initstate_others = d->min_trcount
+ = state_index (d, &merged, separate_contexts ^ CTX_ANY);
+ if (separate_contexts & CTX_LETTER)
+ d->initstate_letter = d->min_trcount
+ = state_index (d, &merged, CTX_LETTER);
+ else
+ d->initstate_letter = d->initstate_others;
+ d->min_trcount++;
+
+ free (posalloc);
+ free (stkalloc);
+ free (merged.elems);
+ free (visited);
}
+
/* Find, for each character, the transition out of state s of d, and store
it in the appropriate slot of trans.
@@ -2423,97 +2614,78 @@ dfaanalyze (struct dfa *d, int searchflag)
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. */
+ position in that group. */
void
-dfastate (int s, struct dfa *d, int trans[])
+dfastate (state_num s, struct dfa *d, state_num trans[])
{
- position_set *grps; /* As many as will ever be needed. */
- charclass *labels; /* 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. */
- int next_isnt_1st_byte = 0; /* Flag if we can't add state0. */
- int i, j, k;
-
- grps = xnmalloc (NOTCHAR, sizeof *grps);
- labels = xnmalloc (NOTCHAR, sizeof *labels);
-
- /* 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);
+ leaf_set grps[NOTCHAR]; /* As many as will ever be needed. */
+ charclass labels[NOTCHAR]; /* Labels corresponding to the groups. */
+ size_t ngrps = 0; /* Number of groups actually used. */
+ position pos; /* Current position being considered. */
+ charclass matches; /* Set of matching characters. */
+ charclass_word matchesf; /* Nonzero if matches is nonempty. */
+ charclass intersect; /* Intersection with some label set. */
+ charclass_word intersectf; /* Nonzero if intersect is nonempty. */
+ charclass leftovers; /* Stuff in the label that didn't match. */
+ charclass_word leftoversf; /* Nonzero if leftovers is nonempty. */
+ position_set follows; /* Union of the follows of some group. */
+ position_set tmp; /* Temporary space for merging sets. */
+ int possible_contexts; /* Contexts that this group can match. */
+ int separate_contexts; /* Context that new state wants to know. */
+ state_num state; /* New state. */
+ state_num state_newline; /* New state on a newline transition. */
+ state_num state_letter; /* New state on a letter transition. */
+ bool next_isnt_1st_byte = false; /* We can't add state0. */
+ size_t i, j, k;
+
+ 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);
+ setbit (d->tokens[pos.index], matches);
else if (d->tokens[pos.index] >= CSET)
- copyset(d->charclasses[d->tokens[pos.index] - CSET], matches);
- else if (MBS_SUPPORT
- && (d->tokens[pos.index] == ANYCHAR
- || d->tokens[pos.index] == MBCSET))
- /* MB_CUR_MAX > 1 */
+ copyset (d->charclasses[d->tokens[pos.index] - CSET], matches);
+ else
{
- /* 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)
+ if (d->tokens[pos.index] == MBCSET
+ || d->tokens[pos.index] == ANYCHAR)
{
- MALLOC(d->states[s].mbps.elems, d->states[s].elems.nelem);
+ /* MB_CUR_MAX > 1 */
+ if (d->tokens[pos.index] == MBCSET)
+ d->states[s].has_mbcset = true;
+ /* 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)
+ alloc_position_set (&d->states[s].mbps, 1);
+ insert (pos, &(d->states[s].mbps));
}
- insert(pos, &(d->states[s].mbps));
continue;
}
- else
- continue;
/* Some characters may need to be eliminated from matches because
- they fail in the current context. */
- if (pos.constraint != 0xFF)
+ they fail in the current context. */
+ if (pos.constraint != NO_CONSTRAINT)
{
- 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)
+ if (!SUCCEEDS_IN_CONTEXT (pos.constraint,
+ d->states[s].context, CTX_NEWLINE))
+ for (j = 0; j < CHARCLASS_WORDS; ++j)
+ matches[j] &= ~newline[j];
+ if (!SUCCEEDS_IN_CONTEXT (pos.constraint,
+ d->states[s].context, CTX_LETTER))
+ for (j = 0; j < CHARCLASS_WORDS; ++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 (!SUCCEEDS_IN_CONTEXT (pos.constraint,
+ d->states[s].context, CTX_NONE))
+ for (j = 0; j < CHARCLASS_WORDS; ++j)
+ matches[j] &= letters[j] | newline[j];
- /* If there are no characters left, there's no point in going on. */
- for (j = 0; j < CHARCLASS_INTS && !matches[j]; ++j)
+ /* If there are no characters left, there's no point in going on. */
+ for (j = 0; j < CHARCLASS_WORDS && !matches[j]; ++j)
continue;
- if (j == CHARCLASS_INTS)
+ if (j == CHARCLASS_WORDS)
continue;
}
@@ -2521,92 +2693,89 @@ dfastate (int s, struct dfa *d, int trans[])
{
/* If matches contains a single character only, and the current
group's label doesn't contain that character, go on to the
- next group. */
+ next group. */
if (d->tokens[pos.index] >= 0 && d->tokens[pos.index] < NOTCHAR
- && !tstbit(d->tokens[pos.index], labels[j]))
+ && !tstbit (d->tokens[pos.index], labels[j]))
continue;
/* Check if this group's label has a nonempty intersection with
- matches. */
+ matches. */
intersectf = 0;
- for (k = 0; k < CHARCLASS_INTS; ++k)
- (intersect[k] = matches[k] & labels[j][k]) ? (intersectf = 1) : 0;
- if (! intersectf)
+ for (k = 0; k < CHARCLASS_WORDS; ++k)
+ intersectf |= intersect[k] = matches[k] & labels[j][k];
+ if (!intersectf)
continue;
- /* It does; now find the set differences both ways. */
+ /* It does; now find the set differences both ways. */
leftoversf = matchesf = 0;
- for (k = 0; k < CHARCLASS_INTS; ++k)
+ for (k = 0; k < CHARCLASS_WORDS; ++k)
{
- /* Even an optimizing compiler can't know this for sure. */
- int match = matches[k], label = labels[j][k];
+ /* Even an optimizing compiler can't know this for sure. */
+ charclass_word match = matches[k], label = labels[j][k];
- (leftovers[k] = ~match & label) ? (leftoversf = 1) : 0;
- (matches[k] = match & ~label) ? (matchesf = 1) : 0;
+ leftoversf |= leftovers[k] = ~match & label;
+ matchesf |= matches[k] = match & ~label;
}
- /* If there were leftovers, create a new group labeled with them. */
+ /* 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, d->nleaves);
- copy(&grps[j], &grps[ngrps]);
+ copyset (leftovers, labels[ngrps]);
+ copyset (intersect, labels[j]);
+ grps[ngrps].elems = xnmalloc (d->nleaves,
+ sizeof *grps[ngrps].elems);
+ memcpy (grps[ngrps].elems, grps[j].elems,
+ sizeof (grps[j].elems[0]) * grps[j].nelem);
+ grps[ngrps].nelem = grps[j].nelem;
++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;
+ /* Put the position in the current group. The constraint is
+ irrelevant here. */
+ grps[j].elems[grps[j].nelem++] = pos.index;
/* If every character matching the current position has been
- accounted for, we're done. */
- if (! matchesf)
+ 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. */
+ unaccounted for, then we'll have to create a new group. */
if (j == ngrps)
{
- copyset(matches, labels[ngrps]);
- zeroset(matches);
- MALLOC(grps[ngrps].elems, d->nleaves);
+ copyset (matches, labels[ngrps]);
+ zeroset (matches);
+ grps[ngrps].elems = xnmalloc (d->nleaves, sizeof *grps[ngrps].elems);
grps[ngrps].nelem = 1;
- grps[ngrps].elems[0] = pos;
+ grps[ngrps].elems[0] = pos.index;
++ngrps;
}
}
- MALLOC(follows.elems, d->nleaves);
- MALLOC(tmp.elems, d->nleaves);
+ alloc_position_set (&follows, d->nleaves);
+ alloc_position_set (&tmp, 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. */
+ 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);
+ /* Find the state(s) corresponding to the positions of state 0. */
+ copy (&d->states[0].elems, &follows);
+ separate_contexts = state_separate_contexts (&follows);
+ state = state_index (d, &follows, separate_contexts ^ CTX_ANY);
+ if (separate_contexts & CTX_NEWLINE)
+ state_newline = state_index (d, &follows, CTX_NEWLINE);
else
state_newline = state;
- if (wants_letter)
- state_letter = state_index(d, &follows, 0, 1);
+ if (separate_contexts & CTX_LETTER)
+ state_letter = state_index (d, &follows, CTX_LETTER);
else
state_letter = state;
+
for (i = 0; i < NOTCHAR; ++i)
- trans[i] = (IS_WORD_CONSTITUENT(i)) ? state_letter : state;
+ trans[i] = (IS_WORD_CONSTITUENT (i)) ? state_letter : state;
trans[eolbyte] = state_newline;
}
else
@@ -2618,12 +2787,12 @@ dfastate (int s, struct dfa *d, int trans[])
follows.nelem = 0;
/* Find the union of the follows of the positions of the group.
- This is a hideously inefficient loop. Fix it someday. */
+ 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);
+ for (k = 0; k < d->follows[grps[i].elems[j]].nelem; ++k)
+ insert (d->follows[grps[i].elems[j]].elems[k], &follows);
- if (d->mb_cur_max > 1)
+ if (d->multibyte)
{
/* If a token in follows.elems is not 1st byte of a multibyte
character, or the states of follows must accept the bytes
@@ -2643,62 +2812,53 @@ dfastate (int s, struct dfa *d, int trans[])
codepoint of <sb a>, it must not be <sb a> but 2nd byte of
<mb A>, so we cannot add state[0]. */
- next_isnt_1st_byte = 0;
+ next_isnt_1st_byte = false;
for (j = 0; j < follows.nelem; ++j)
{
if (!(d->multibyte_prop[follows.elems[j].index] & 1))
{
- next_isnt_1st_byte = 1;
+ next_isnt_1st_byte = true;
break;
}
}
}
/* If we are building a searching matcher, throw in the positions
- of state 0 as well. */
- if (d->searchflag
- && (! MBS_SUPPORT
- || (d->mb_cur_max == 1 || !next_isnt_1st_byte)))
- 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);
+ of state 0 as well. */
+ if (d->searchflag && (!d->multibyte || !next_isnt_1st_byte))
+ {
+ merge (&d->states[0].elems, &follows, &tmp);
+ copy (&tmp, &follows);
+ }
+
+ /* Find out if the new state will want any context information. */
+ possible_contexts = charclass_context (labels[i]);
+ separate_contexts = state_separate_contexts (&follows);
+
+ /* Find the state(s) corresponding to the union of the follows. */
+ if ((separate_contexts & possible_contexts) != possible_contexts)
+ state = state_index (d, &follows, separate_contexts ^ CTX_ANY);
+ else
+ state = -1;
+ if (separate_contexts & possible_contexts & CTX_NEWLINE)
+ state_newline = state_index (d, &follows, CTX_NEWLINE);
else
state_newline = state;
- if (wants_letter)
- state_letter = state_index(d, &follows, 0, 1);
+ if (separate_contexts & possible_contexts & CTX_LETTER)
+ state_letter = state_index (d, &follows, CTX_LETTER);
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)
+ /* Set the transitions for each character in the current label. */
+ for (j = 0; j < CHARCLASS_WORDS; ++j)
+ for (k = 0; k < CHARCLASS_WORD_BITS; ++k)
+ if (labels[i][j] >> k & 1)
{
- int c = j * INTBITS + k;
+ int c = j * CHARCLASS_WORD_BITS + k;
if (c == eolbyte)
trans[c] = state_newline;
- else if (IS_WORD_CONSTITUENT(c))
+ else if (IS_WORD_CONSTITUENT (c))
trans[c] = state_letter;
else if (c < NOTCHAR)
trans[c] = state;
@@ -2706,11 +2866,34 @@ dfastate (int s, struct dfa *d, int trans[])
}
for (i = 0; i < ngrps; ++i)
- free(grps[i].elems);
- free(follows.elems);
- free(tmp.elems);
- free(grps);
- free(labels);
+ free (grps[i].elems);
+ free (follows.elems);
+ free (tmp.elems);
+}
+
+/* Make sure D's state arrays are large enough to hold NEW_STATE. */
+static void
+realloc_trans_if_necessary (struct dfa *d, state_num new_state)
+{
+ state_num oldalloc = d->tralloc;
+ if (oldalloc <= new_state)
+ {
+ state_num **realtrans = d->trans ? d->trans - 1 : NULL;
+ size_t newalloc, newalloc1;
+ newalloc1 = new_state + 1;
+ realtrans = x2nrealloc (realtrans, &newalloc1, sizeof *realtrans);
+ realtrans[0] = NULL;
+ d->trans = realtrans + 1;
+ d->tralloc = newalloc = newalloc1 - 1;
+ d->fails = xnrealloc (d->fails, newalloc, sizeof *d->fails);
+ d->success = xnrealloc (d->success, newalloc, sizeof *d->success);
+ d->newlines = xnrealloc (d->newlines, newalloc, sizeof *d->newlines);
+ for (; oldalloc < newalloc; oldalloc++)
+ {
+ d->trans[oldalloc] = NULL;
+ d->fails[oldalloc] = NULL;
+ }
+ }
}
/* Some routines for manipulating a compiled dfa's transition tables.
@@ -2718,160 +2901,85 @@ dfastate (int s, struct dfa *d, int trans[])
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. */
+ TODO: Improve this comment, get rid of the unnecessary redundancy. */
static void
-build_state (int s, struct dfa *d)
+build_state (state_num s, struct dfa *d)
{
- int *trans; /* The new transition table. */
- int i;
+ state_num *trans; /* The new transition table. */
+ state_num i, maxstate;
/* 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. */
+ were only needed once or twice will be cleared away. However, do not
+ clear the initial D->min_trcount states, since they are always used. */
if (d->trcount >= 1024)
{
- for (i = 0; i < d->tralloc; ++i)
+ for (i = d->min_trcount; i < d->tralloc; ++i)
{
- free(d->trans[i]);
- free(d->fails[i]);
+ free (d->trans[i]);
+ free (d->fails[i]);
d->trans[i] = d->fails[i] = NULL;
}
- d->trcount = 0;
+ d->trcount = d->min_trcount;
}
++d->trcount;
- /* Set up the success bits for this state. */
+ /* 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, NOTCHAR);
- dfastate(s, d, trans);
+ if (ACCEPTS_IN_CONTEXT (d->states[s].context, CTX_NEWLINE, s, *d))
+ d->success[s] |= CTX_NEWLINE;
+ if (ACCEPTS_IN_CONTEXT (d->states[s].context, CTX_LETTER, s, *d))
+ d->success[s] |= CTX_LETTER;
+ if (ACCEPTS_IN_CONTEXT (d->states[s].context, CTX_NONE, s, *d))
+ d->success[s] |= CTX_NONE;
+
+ trans = xmalloc (NOTCHAR * sizeof *trans);
+ 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. */
+ largest state mentioned in the table. */
+ maxstate = -1;
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, d->tralloc + 1);
- d->trans = d->realtrans + 1;
- REALLOC(d->fails, d->tralloc);
- REALLOC(d->success, d->tralloc);
- REALLOC(d->newlines, d->tralloc);
- while (oldalloc < d->tralloc)
- {
- d->trans[oldalloc] = NULL;
- d->fails[oldalloc++] = NULL;
- }
- }
+ if (maxstate < trans[i])
+ maxstate = trans[i];
+ realloc_trans_if_necessary (d, maxstate);
/* Keep the newline transition in a special place so we can use it as
- a sentinel. */
+ a sentinel. */
d->newlines[s] = trans[eolbyte];
trans[eolbyte] = -1;
- if (ACCEPTING(s, *d))
+ 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, d->tralloc + 1);
- d->trans = d->realtrans + 1;
- CALLOC(d->fails, d->tralloc);
- MALLOC(d->success, d->tralloc);
- MALLOC(d->newlines, d->tralloc);
- build_state(0, d);
-}
-
/* 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); \
- *end = saved_end; \
- 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, d->tralloc + 1);
- d->trans = d->realtrans + 1;
- REALLOC(d->fails, d->tralloc);
- REALLOC(d->success, d->tralloc);
- REALLOC(d->newlines, d->tralloc);
- while (oldalloc < d->tralloc)
- {
- d->trans[oldalloc] = NULL;
- d->fails[oldalloc++] = NULL;
- }
- }
-}
-
-/* Return values of transit_state_singlebyte(), and
+/* 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. */
+ 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().
+ 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)
+transit_state_singlebyte (struct dfa *d, state_num s, unsigned char const *p,
+ state_num * next_state)
{
- int *t;
- int works = s;
+ state_num *t;
+ state_num works = s;
status_transit_state rval = TRANSIT_STATE_IN_PROGRESS;
@@ -2885,14 +2993,7 @@ transit_state_singlebyte (struct dfa *d, int s, unsigned char const *p,
works = 0;
}
else if (works < 0)
- {
- if (p == buf_end)
- {
- /* At the moment, it must not happen. */
- abort ();
- }
- works = 0;
- }
+ works = 0;
else if (d->fails[works])
{
works = d->fails[works][*p];
@@ -2900,121 +3001,93 @@ transit_state_singlebyte (struct dfa *d, int s, unsigned char const *p,
}
else
{
- build_state(works, d);
+ build_state (works, d);
}
}
*next_state = works;
return rval;
}
-/* Match a "." against the current context. buf_begin[IDX] is the
- current position. Return the length of the match, in bytes.
- POS is the position of the ".". */
+/* Match a "." against the current context. Return the length of the
+ match, in bytes. POS is the position of the ".". */
static int
-match_anychar (struct dfa *d, int s, position pos, int idx)
+match_anychar (struct dfa *d, state_num s, position pos,
+ wint_t wc, size_t mbclen)
{
- int newline = 0;
- int letter = 0;
- wchar_t wc;
- int mbclen;
+ int context;
- wc = inputwcs[idx];
- mbclen = (mblen_buf[idx] == 0)? 1 : mblen_buf[idx];
-
- /* Check context. */
- if (wc == (wchar_t)eolbyte)
+ /* Check syntax bits. */
+ if (wc == (wchar_t) eolbyte)
{
if (!(syntax_bits & RE_DOT_NEWLINE))
return 0;
- newline = 1;
}
- else if (wc == (wchar_t)'\0')
+ else if (wc == (wchar_t) '\0')
{
if (syntax_bits & RE_DOT_NOT_NULL)
return 0;
- newline = 1;
}
+ else if (wc == WEOF)
+ return 0;
- if (iswalnum(wc) || wc == L'_')
- letter = 1;
-
- if (!SUCCEEDS_IN_CONTEXT(pos.constraint, d->states[s].newline,
- newline, d->states[s].letter, letter))
+ context = wchar_context (wc);
+ if (!SUCCEEDS_IN_CONTEXT (pos.constraint, d->states[s].context, context))
return 0;
return mbclen;
}
/* Match a bracket expression against the current context.
- buf_begin[IDX] is the current position.
Return the length of the match, in bytes.
POS is the position of the bracket expression. */
static int
-match_mb_charset (struct dfa *d, int s, position pos, int idx)
+match_mb_charset (struct dfa *d, state_num s, position pos,
+ char const *p, wint_t wc, size_t match_len)
{
- 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. */
+ size_t i;
+ bool match; /* Matching succeeded. */
+ int op_len; /* Length of the operator. */
char buffer[128];
- wchar_t wcbuf[6];
- /* Pointer to the structure to which we are currently refering. */
+ /* Pointer to the structure to which we are currently referring. */
struct mb_char_classes *work_mbc;
- int newline = 0;
- int letter = 0;
- wchar_t wc; /* Current refering character. */
+ int context;
- wc = inputwcs[idx];
+ /* Check syntax bits. */
+ if (wc == WEOF)
+ return 0;
- /* 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))
+ context = wchar_context (wc);
+ if (!SUCCEEDS_IN_CONTEXT (pos.constraint, d->states[s].context, context))
return 0;
- /* Assign the current refering operator to work_mbc. */
+ /* Assign the current referring operator to work_mbc. */
work_mbc = &(d->mbcsets[(d->multibyte_prop[pos.index]) >> 2]);
match = !work_mbc->invert;
- match_len = (mblen_buf[idx] == 0)? 1 : mblen_buf[idx];
/* Match in range 0-255? */
if (wc < NOTCHAR && work_mbc->cset != -1
- && tstbit((unsigned char)wc, d->charclasses[work_mbc->cset]))
+ && tstbit (to_uchar (wc), d->charclasses[work_mbc->cset]))
goto charset_matched;
/* match with a character class? */
- for (i = 0; i<work_mbc->nch_classes; i++)
+ for (i = 0; i < work_mbc->nch_classes; i++)
{
- if (iswctype((wint_t)wc, work_mbc->ch_classes[i]))
+ if (iswctype ((wint_t) wc, work_mbc->ch_classes[i]))
goto charset_matched;
}
- strncpy(buffer, (char const *) buf_begin + idx, match_len);
+ strncpy (buffer, p, match_len);
buffer[match_len] = '\0';
- /* match with an equivalent class? */
- for (i = 0; i<work_mbc->nequivs; i++)
+ /* match with an equivalence class? */
+ for (i = 0; i < work_mbc->nequivs; i++)
{
- op_len = strlen(work_mbc->equivs[i]);
- strncpy(buffer, (char const *) buf_begin + idx, op_len);
+ op_len = strlen (work_mbc->equivs[i]);
+ strncpy (buffer, p, op_len);
buffer[op_len] = '\0';
- if (strcoll(work_mbc->equivs[i], buffer) == 0)
+ if (strcoll (work_mbc->equivs[i], buffer) == 0)
{
match_len = op_len;
goto charset_matched;
@@ -3022,35 +3095,28 @@ match_mb_charset (struct dfa *d, int s, position pos, int idx)
}
/* match with a collating element? */
- for (i = 0; i<work_mbc->ncoll_elems; i++)
+ for (i = 0; i < work_mbc->ncoll_elems; i++)
{
- op_len = strlen(work_mbc->coll_elems[i]);
- strncpy(buffer, (char const *) buf_begin + idx, op_len);
+ op_len = strlen (work_mbc->coll_elems[i]);
+ strncpy (buffer, p, op_len);
buffer[op_len] = '\0';
- if (strcoll(work_mbc->coll_elems[i], buffer) == 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++)
+ 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)
+ if (work_mbc->ranges[i].beg <= wc && wc <= work_mbc->ranges[i].end)
goto charset_matched;
}
/* match with a character? */
- for (i = 0; i<work_mbc->nchars; i++)
+ for (i = 0; i < work_mbc->nchars; i++)
{
if (wc == work_mbc->chars[i])
goto charset_matched;
@@ -3058,117 +3124,113 @@ match_mb_charset (struct dfa *d, int s, position pos, int idx)
match = !match;
- charset_matched:
+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.
- `idx' 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 idx)
+/* Check whether each of 'd->states[s].mbps.elem' can match. Then return the
+ array which corresponds to 'd->states[s].mbps.elem'; each element of the
+ array contains the number of bytes with which the element can match.
+
+ The caller MUST free the array which this function return. */
+static int *
+check_matching_with_multibyte_ops (struct dfa *d, state_num s,
+ char const *p, wint_t wc, size_t mbclen)
{
- int i;
- int* rarray;
+ size_t i;
+ int *rarray;
- MALLOC(rarray, d->states[s].mbps.nelem);
+ rarray = d->mb_match_lens;
for (i = 0; i < d->states[s].mbps.nelem; ++i)
{
position pos = d->states[s].mbps.elems[i];
- switch(d->tokens[pos.index])
+ switch (d->tokens[pos.index])
{
case ANYCHAR:
- rarray[i] = match_anychar(d, s, pos, idx);
+ rarray[i] = match_anychar (d, s, pos, wc, mbclen);
break;
case MBCSET:
- rarray[i] = match_mb_charset(d, s, pos, idx);
+ rarray[i] = match_mb_charset (d, s, pos, p, wc, mbclen);
break;
default:
- break; /* cannot happen. */
+ break; /* cannot 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. */
+ be the 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 enumerates. */
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)
+transit_state_consume_1char (struct dfa *d, state_num s,
+ unsigned char const **pp,
+ wint_t wc, size_t mbclen,
+ int *match_lens)
{
- int i, j;
- int s1, s2;
- int* work_mbls;
+ size_t i, j;
+ int k;
+ state_num s1, s2;
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];
+ if (! match_lens && d->states[s].mbps.nelem != 0)
+ match_lens = check_matching_with_multibyte_ops (d, s, (char const *) *pp,
+ wc, mbclen);
- /* Calculate the state which can be reached from the state `s' by
- consuming `*mbclen' single bytes from the buffer. */
+ /* 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++)
+ for (k = 0; k < mbclen; k++)
{
s2 = s1;
- rs = transit_state_singlebyte(d, s2, (*pp)++, &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;
+ copy (&d->states[s1].elems, &d->mb_follows);
- /* Add all of the positions which can be reached from `s' by consuming
+ /* 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 (i = 0; i < d->states[s].mbps.nelem; i++)
+ {
+ if (match_lens[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);
+ insert (d->follows[d->states[s].mbps.elems[i].index].elems[j],
+ &d->mb_follows);
}
- if (match_lens == NULL && work_mbls != NULL)
- free(work_mbls);
+ /* FIXME: this return value is always ignored. */
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)
+static state_num
+transit_state (struct dfa *d, state_num s, unsigned char const **pp,
+ unsigned char const *end)
{
- int s1;
- int mbclen; /* The length of current input multibyte character. */
+ state_num s1;
+ int mbclen; /* The length of current input multibyte character. */
int maxlen = 0;
- int i, j;
+ size_t i, j;
int *match_lens = NULL;
- int nelem = d->states[s].mbps.nelem; /* Just a alias. */
- position_set follows;
+ size_t nelem = d->states[s].mbps.nelem; /* Just a alias. */
unsigned char const *p1 = *pp;
- wchar_t wc;
+ wint_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);
+ mbclen = mbs_to_wchar (&wc, (char const *) *pp, end - *pp, d);
+ match_lens = check_matching_with_multibyte_ops (d, s, (char const *) *pp,
+ wc, mbclen);
for (i = 0; i < nelem; i++)
/* Search the operator which match the longest string,
@@ -3184,101 +3246,70 @@ transit_state (struct dfa *d, int s, unsigned char const **pp)
We need to check only one single byte character. */
{
status_transit_state rs;
- rs = transit_state_singlebyte(d, s, *pp, &s1);
+ rs = transit_state_singlebyte (d, s, *pp, &s1);
/* We must update the pointer if state transition succeeded. */
if (rs == TRANSIT_STATE_DONE)
++*pp;
- free(match_lens);
return s1;
}
/* This state has some operators which can match a multibyte character. */
- follows.nelem = 0;
- MALLOC(follows.elems, d->nleaves);
+ d->mb_follows.nelem = 0;
- /* `maxlen' may be longer than the length of a character, because it may
+ /* '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. */
- transit_state_consume_1char(d, s, pp, match_lens, &mbclen, &follows);
+ We enumerate all of the positions which 's' can reach by consuming
+ 'maxlen' bytes. */
+ transit_state_consume_1char (d, s, pp, wc, mbclen, match_lens);
- wc = inputwcs[*pp - mbclen - buf_begin];
- s1 = state_index(d, &follows, wc == L'\n', iswalnum(wc));
- realloc_trans_if_necessary(d, s1);
+ s1 = state_index (d, &d->mb_follows, wchar_context (wc));
+ realloc_trans_if_necessary (d, s1);
while (*pp - p1 < maxlen)
{
- follows.nelem = 0;
- transit_state_consume_1char(d, s1, pp, NULL, &mbclen, &follows);
+ mbclen = mbs_to_wchar (&wc, (char const *) *pp, end - *pp, d);
+ transit_state_consume_1char (d, s1, pp, wc, mbclen, NULL);
- for (i = 0; i < nelem ; i++)
+ 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);
+ insert (d->follows[d->states[s1].mbps.elems[i].index].elems[j],
+ &d->mb_follows);
}
- wc = inputwcs[*pp - mbclen - buf_begin];
- s1 = state_index(d, &follows, wc == L'\n', iswalnum(wc));
- realloc_trans_if_necessary(d, s1);
+ s1 = state_index (d, &d->mb_follows, wchar_context (wc));
+ realloc_trans_if_necessary (d, s1);
}
- free(match_lens);
- free(follows.elems);
return s1;
}
-
-/* Initialize mblen_buf and inputwcs with data from the next line. */
-
-static void
-prepare_wc_buf (const char *begin, const char *end)
+/* The initial state may encounter a byte which is not a single byte character
+ nor the first byte of a multibyte character. But it is incorrect for the
+ initial state to accept such a byte. For example, in Shift JIS the regular
+ expression "\\" accepts the codepoint 0x5c, but should not accept the second
+ byte of the codepoint 0x815c. Then the initial state must skip the bytes
+ that are not a single byte character nor the first byte of a multibyte
+ character.
+
+ Given DFA state d, use mbs_to_wchar to advance MBP until it reaches or
+ exceeds P. If WCP is non-NULL, set *WCP to the final wide character
+ processed, or if no wide character is processed, set it to WEOF.
+ Both P and MBP must be no larger than END. */
+static unsigned char const *
+skip_remains_mb (struct dfa *d, unsigned char const *p,
+ unsigned char const *mbp, char const *end, wint_t *wcp)
{
-#if MBS_SUPPORT
- unsigned char eol = eolbyte;
- size_t remain_bytes, i;
-
- buf_begin = (unsigned char *) begin;
-
- 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 == (size_t) -1
- || remain_bytes == (size_t) -2
- || (remain_bytes == 1 && inputwcs[i] == (wchar_t)begin[i]))
- {
- remain_bytes = 0;
- inputwcs[i] = (wchar_t)begin[i];
- mblen_buf[i] = 0;
- if (begin[i] == eol)
- break;
- }
- else
- {
- mblen_buf[i] = remain_bytes;
- remain_bytes--;
- }
- }
- else
- {
- mblen_buf[i] = remain_bytes;
- inputwcs[i] = 0;
- remain_bytes--;
- }
- }
-
- buf_end = (unsigned char *) (begin + i);
- mblen_buf[i] = 0;
- inputwcs[i] = 0; /* sentinel */
-#endif /* MBS_SUPPORT */
+ wint_t wc = WEOF;
+ while (mbp < p)
+ mbp += mbs_to_wchar (&wc, (char const *) mbp,
+ end - (char const *) mbp, d);
+ if (wcp != NULL)
+ *wcp = wc;
+ return mbp;
}
/* Search through a buffer looking for a match to the given struct dfa.
@@ -3288,236 +3319,316 @@ prepare_wc_buf (const char *begin, const char *end)
points to the beginning of the buffer, and END points to the first byte
after its end. Note however that we store a sentinel byte (usually
newline) in *END, so the actual buffer must be one byte longer.
- When NEWLINE is nonzero, newlines may appear in the matching string.
+ When ALLOW_NL is nonzero, newlines may appear in the matching string.
If COUNT is non-NULL, increment *COUNT once for each newline processed.
Finally, if BACKREF is non-NULL set *BACKREF to indicate whether we
encountered a back-reference (1) or not (0). The caller may use this
- to decide whether to fall back on a backtracking matcher. */
-char *
-dfaexec (struct dfa *d, char const *begin, char *end,
- int newline, int *count, int *backref)
+ to decide whether to fall back on a backtracking matcher.
+
+ If MULTIBYTE, the input consists of multibyte characters and/or
+ encoding-error bytes. Otherwise, the input consists of single-byte
+ characters. */
+static inline char *
+dfaexec_main (struct dfa *d, char const *begin, char *end,
+ int allow_nl, size_t *count, int *backref, bool multibyte)
{
- int s, s1; /* Current state. */
- unsigned char const *p; /* Current input character. */
- int **trans, *t; /* Copy of d->trans so it can be optimized
- into a register. */
- unsigned char eol = eolbyte; /* Likewise for eolbyte. */
+ state_num s, s1; /* Current state. */
+ unsigned char const *p, *mbp; /* Current input character. */
+ state_num **trans, *t; /* Copy of d->trans so it can be optimized
+ into a register. */
+ unsigned char eol = eolbyte; /* Likewise for eolbyte. */
unsigned char saved_end;
- static int sbit[NOTCHAR]; /* Table for anding with d->success. */
- static int sbit_init;
+ size_t nlcount = 0;
- if (! sbit_init)
+ if (!d->tralloc)
{
- unsigned int i;
-
- sbit_init = 1;
- for (i = 0; i < NOTCHAR; ++i)
- sbit[i] = (IS_WORD_CONSTITUENT(i)) ? 2 : 1;
- sbit[eol] = 4;
+ realloc_trans_if_necessary (d, 1);
+ build_state (0, d);
}
- if (! d->tralloc)
- build_state_zero(d);
-
s = s1 = 0;
- p = (unsigned char const *) begin;
+ p = mbp = (unsigned char const *) begin;
trans = d->trans;
saved_end = *(unsigned char *) end;
*end = eol;
- if (d->mb_cur_max > 1)
+ if (multibyte)
{
- MALLOC(mblen_buf, end - begin + 2);
- MALLOC(inputwcs, end - begin + 2);
- memset(&mbs, 0, sizeof(mbstate_t));
- prepare_wc_buf ((const char *) p, end);
+ memset (&d->mbs, 0, sizeof d->mbs);
+ if (! d->mb_match_lens)
+ {
+ d->mb_match_lens = xnmalloc (d->nleaves, sizeof *d->mb_match_lens);
+ alloc_position_set (&d->mb_follows, d->nleaves);
+ }
}
for (;;)
{
- if (d->mb_cur_max > 1)
- while ((t = trans[s]))
- {
- if (p > buf_end)
- break;
- s1 = s;
- SKIP_REMAINS_MB_IF_INITIAL_STATE(s, p);
+ if (multibyte)
+ {
+ while ((t = trans[s]) != NULL)
+ {
+ s1 = s;
- if (d->states[s].mbps.nelem == 0)
- {
- s = t[*p++];
- continue;
- }
+ if (s < d->min_trcount)
+ {
+ if (d->min_trcount == 1)
+ {
+ if (d->states[s].mbps.nelem == 0)
+ {
+ do
+ {
+ while (t[*p] == 0)
+ p++;
+ p = mbp = skip_remains_mb (d, p, mbp, end, NULL);
+ }
+ while (t[*p] == 0);
+ }
+ else
+ p = mbp = skip_remains_mb (d, p, mbp, end, NULL);
+ }
+ else
+ {
+ wint_t wc;
+ mbp = skip_remains_mb (d, p, mbp, end, &wc);
+
+ /* If d->min_trcount is greater than 1, maybe
+ transit to another initial state after skip. */
+ if (p < mbp)
+ {
+ int context = wchar_context (wc);
+ if (context == CTX_LETTER)
+ s = d->initstate_letter;
+ else
+ /* It's CTX_NONE. CTX_NEWLINE cannot happen,
+ as we assume that a newline is always a
+ single byte character. */
+ s = d->initstate_others;
+ p = mbp;
+ s1 = s;
+ }
+ }
+ }
- /* Falling back to the glibc matcher in this case gives
- better performance (up to 25% better on [a-z], for
- example) and enables support for collating symbols and
- equivalence classes. */
- if (backref)
- {
- *backref = 1;
- free(mblen_buf);
- free(inputwcs);
- *end = saved_end;
- return (char *) p;
- }
+ if (d->states[s].mbps.nelem == 0)
+ {
+ s = t[*p++];
+ continue;
+ }
- /* Can match with a multibyte character (and multi character
- collating element). Transition table might be updated. */
- s = transit_state(d, s, &p);
- trans = d->trans;
- }
+ /* The following code is used twice.
+ Use a macro to avoid the risk that they diverge. */
+#define State_transition() \
+ do { \
+ /* Falling back to the glibc matcher in this case gives \
+ better performance (up to 25% better on [a-z], for \
+ example) and enables support for collating symbols and \
+ equivalence classes. */ \
+ if (d->states[s].has_mbcset && backref) \
+ { \
+ *backref = 1; \
+ goto done; \
+ } \
+ \
+ /* Can match with a multibyte character (and multi-character \
+ collating element). Transition table might be updated. */ \
+ s = transit_state (d, s, &p, (unsigned char *) end); \
+ \
+ /* If previous character is newline after a transition \
+ for ANYCHAR or MBCSET in non-UTF8 multibyte locales, \
+ check whether current position is beyond the end of \
+ the input buffer. Also, transit to initial state if \
+ !ALLOW_NL, even if RE_DOT_NEWLINE is set. */ \
+ if (p[-1] == eol) \
+ { \
+ if ((char *) p > end) \
+ { \
+ p = NULL; \
+ goto done; \
+ } \
+ \
+ nlcount++; \
+ \
+ if (!allow_nl) \
+ s = 0; \
+ } \
+ \
+ mbp = p; \
+ trans = d->trans; \
+ } while (0)
+
+ State_transition();
+ }
+ }
else
{
- while ((t = trans[s]) != 0)
+ if (s == 0 && (t = trans[s]) != NULL)
+ {
+ while (t[*p] == 0)
+ p++;
+ s1 = 0;
+ s = t[*p++];
+ }
+
+ while ((t = trans[s]) != NULL)
{
s1 = t[*p++];
- if ((t = trans[s1]) == 0)
+ if ((t = trans[s1]) == NULL)
{
- int tmp = s; s = s1; s1 = tmp; /* swap */
+ state_num tmp = s;
+ s = s1;
+ s1 = tmp; /* swap */
break;
}
s = t[*p++];
}
}
- if (s >= 0 && (char *) p <= end && d->fails[s])
+ if (s < 0)
{
- if (d->success[s] & sbit[*p])
- {
- if (backref)
- *backref = (d->states[s].backref != 0);
- if (d->mb_cur_max > 1)
- {
- free(mblen_buf);
- free(inputwcs);
- }
- *end = saved_end;
- return (char *) p;
- }
-
- s1 = s;
- if (d->mb_cur_max > 1)
+ if ((char *) p > end || p[-1] != eol || d->newlines[s1] < 0)
{
- /* Can match with a multibyte character (and multicharacter
- collating element). Transition table might be updated. */
- s = transit_state(d, s, &p);
- trans = d->trans;
+ p = NULL;
+ goto done;
}
- else
- s = d->fails[s][*p++];
- continue;
- }
- /* If the previous character was a newline, count it. */
- if ((char *) p <= end && p[-1] == eol)
- {
- if (count)
- ++*count;
+ /* The previous character was a newline, count it, and skip
+ checking of multibyte character boundary until here. */
+ nlcount++;
+ mbp = p;
- if (d->mb_cur_max > 1)
- prepare_wc_buf ((const char *) p, end);
+ s = allow_nl ? d->newlines[s1] : 0;
}
- /* Check if we've run off the end of the buffer. */
- if ((char *) p > end)
+ if (d->fails[s])
{
- if (d->mb_cur_max > 1)
+ if (d->success[s] & sbit[*p])
{
- free(mblen_buf);
- free(inputwcs);
+ if (backref)
+ *backref = d->states[s].has_backref;
+ goto done;
}
- *end = saved_end;
- return NULL;
- }
- if (s >= 0)
+ s1 = s;
+ if (multibyte)
+ State_transition();
+ else
+ s = d->fails[s][*p++];
+ }
+ else
{
- build_state(s, d);
+ if (!d->trans[s])
+ build_state (s, d);
trans = d->trans;
- continue;
}
+ }
- if (p[-1] == eol && newline)
- {
- s = d->newlines[s1];
- continue;
- }
+ done:
+ if (count)
+ *count += nlcount;
+ *end = saved_end;
+ return (char *) p;
+}
- s = 0;
- }
+/* Specialized versions of dfaexec_main for multibyte and single-byte
+ cases. This is for performance. */
+
+static char *
+dfaexec_mb (struct dfa *d, char const *begin, char *end,
+ int allow_nl, size_t *count, int *backref)
+{
+ return dfaexec_main (d, begin, end, allow_nl, count, backref, true);
+}
+
+static char *
+dfaexec_sb (struct dfa *d, char const *begin, char *end,
+ int allow_nl, size_t *count, int *backref)
+{
+ return dfaexec_main (d, begin, end, allow_nl, count, backref, false);
+}
+
+/* Like dfaexec_main (D, BEGIN, END, ALLOW_NL, COUNT, BACKREF, D->multibyte),
+ but faster. */
+
+char *
+dfaexec (struct dfa *d, char const *begin, char *end,
+ int allow_nl, size_t *count, int *backref)
+{
+ return d->dfaexec (d, begin, end, allow_nl, count, backref);
+}
+
+struct dfa *
+dfasuperset (struct dfa const *d)
+{
+ return d->superset;
+}
+
+bool
+dfaisfast (struct dfa const *d)
+{
+ return d->fast;
}
static void
free_mbdata (struct dfa *d)
{
- unsigned int i;
+ size_t i;
- free(d->multibyte_prop);
- d->multibyte_prop = NULL;
+ free (d->multibyte_prop);
for (i = 0; i < d->nmbcsets; ++i)
{
- unsigned int j;
+ size_t j;
struct mb_char_classes *p = &(d->mbcsets[i]);
- free(p->chars);
- free(p->ch_classes);
- free(p->range_sts);
- free(p->range_ends);
+ free (p->chars);
+ free (p->ch_classes);
+ free (p->ranges);
for (j = 0; j < p->nequivs; ++j)
- free(p->equivs[j]);
- free(p->equivs);
+ free (p->equivs[j]);
+ free (p->equivs);
for (j = 0; j < p->ncoll_elems; ++j)
- free(p->coll_elems[j]);
- free(p->coll_elems);
+ free (p->coll_elems[j]);
+ free (p->coll_elems);
}
- free(d->mbcsets);
- d->mbcsets = NULL;
- d->nmbcsets = 0;
+ free (d->mbcsets);
+ free (d->mb_follows.elems);
+ free (d->mb_match_lens);
+ d->mb_match_lens = NULL;
}
/* Initialize the components of a dfa that the other routines don't
- initialize for themselves. */
+ initialize for themselves. */
void
dfainit (struct dfa *d)
{
memset (d, 0, sizeof *d);
-
- d->calloc = 1;
- MALLOC(d->charclasses, d->calloc);
-
- d->talloc = 1;
- MALLOC(d->tokens, d->talloc);
-
- d->mb_cur_max = MB_CUR_MAX;
-
- if (d->mb_cur_max > 1)
- {
- d->nmultibyte_prop = 1;
- MALLOC(d->multibyte_prop, d->nmultibyte_prop);
- d->mbcsets_alloc = 1;
- MALLOC(d->mbcsets, d->mbcsets_alloc);
- }
+ d->multibyte = MB_CUR_MAX > 1;
+ d->dfaexec = d->multibyte ? dfaexec_mb : dfaexec_sb;
+ d->fast = !d->multibyte;
}
static void
dfaoptimize (struct dfa *d)
{
- unsigned int i;
+ size_t i;
+ bool have_backref = false;
- if (!MBS_SUPPORT || !using_utf8())
+ if (!using_utf8 ())
return;
for (i = 0; i < d->tindex; ++i)
{
- switch(d->tokens[i])
+ switch (d->tokens[i])
{
case ANYCHAR:
/* Lowered. */
abort ();
+ case BACKREF:
+ have_backref = true;
+ break;
case MBCSET:
/* Requires multi-byte algorithm. */
return;
@@ -3526,58 +3637,170 @@ dfaoptimize (struct dfa *d)
}
}
+ if (!have_backref && d->superset)
+ {
+ /* The superset DFA is not likely to be much faster, so remove it. */
+ dfafree (d->superset);
+ free (d->superset);
+ d->superset = NULL;
+ }
+
free_mbdata (d);
- d->mb_cur_max = 1;
+ d->multibyte = false;
+ d->dfaexec = dfaexec_sb;
}
-/* Parse and analyze a single string of the given length. */
+static void
+dfassbuild (struct dfa *d)
+{
+ size_t i, j;
+ charclass ccl;
+ bool have_achar = false;
+ bool have_nchar = false;
+ struct dfa *sup = dfaalloc ();
+
+ *sup = *d;
+ sup->multibyte = false;
+ sup->dfaexec = dfaexec_sb;
+ sup->multibyte_prop = NULL;
+ sup->mbcsets = NULL;
+ sup->superset = NULL;
+ sup->states = NULL;
+ sup->sindex = 0;
+ sup->follows = NULL;
+ sup->tralloc = 0;
+ sup->trans = NULL;
+ sup->fails = NULL;
+ sup->success = NULL;
+ sup->newlines = NULL;
+ sup->musts = NULL;
+
+ sup->charclasses = xnmalloc (sup->calloc, sizeof *sup->charclasses);
+ if (d->cindex)
+ {
+ memcpy (sup->charclasses, d->charclasses,
+ d->cindex * sizeof *sup->charclasses);
+ }
+
+ sup->tokens = xnmalloc (d->tindex, 2 * sizeof *sup->tokens);
+ sup->talloc = d->tindex * 2;
+
+ for (i = j = 0; i < d->tindex; i++)
+ {
+ switch (d->tokens[i])
+ {
+ case ANYCHAR:
+ case MBCSET:
+ case BACKREF:
+ zeroset (ccl);
+ notset (ccl);
+ sup->tokens[j++] = CSET + dfa_charclass_index (sup, ccl);
+ sup->tokens[j++] = STAR;
+ if (d->tokens[i + 1] == QMARK || d->tokens[i + 1] == STAR
+ || d->tokens[i + 1] == PLUS)
+ i++;
+ have_achar = true;
+ break;
+ case BEGWORD:
+ case ENDWORD:
+ case LIMWORD:
+ case NOTLIMWORD:
+ if (d->multibyte)
+ {
+ /* These constraints aren't supported in a multibyte locale.
+ Ignore them in the superset DFA, and treat them as
+ backreferences in the main DFA. */
+ sup->tokens[j++] = EMPTY;
+ d->tokens[i] = BACKREF;
+ break;
+ }
+ default:
+ sup->tokens[j++] = d->tokens[i];
+ if ((0 <= d->tokens[i] && d->tokens[i] < NOTCHAR)
+ || d->tokens[i] >= CSET)
+ have_nchar = true;
+ break;
+ }
+ }
+ sup->tindex = j;
+
+ if (have_nchar && (have_achar || d->multibyte))
+ d->superset = sup;
+ else
+ {
+ dfafree (sup);
+ free (sup);
+ }
+}
+
+/* Parse and analyze a single string of the given length. */
void
dfacomp (char const *s, size_t len, struct dfa *d, int searchflag)
{
- dfainit(d);
- dfaparse(s, len, d);
- dfamust(d);
- dfaoptimize(d);
- dfaanalyze(d, searchflag);
+ dfainit (d);
+ dfambcache (d);
+ dfaparse (s, len, d);
+ dfamust (d);
+ dfassbuild (d);
+ dfaoptimize (d);
+ dfaanalyze (d, searchflag);
+ if (d->superset)
+ {
+ d->fast = true;
+ dfaanalyze (d->superset, searchflag);
+ }
}
-/* Free the storage held by the components of a dfa. */
+/* Free the storage held by the components of a dfa. */
void
dfafree (struct dfa *d)
{
- int i;
+ size_t i;
struct dfamust *dm, *ndm;
- free(d->charclasses);
- free(d->tokens);
+ free (d->charclasses);
+ free (d->tokens);
- if (d->mb_cur_max > 1)
- free_mbdata(d);
+ if (d->multibyte)
+ free_mbdata (d);
- for (i = 0; i < d->sindex; ++i) {
- free(d->states[i].elems.elems);
- if (MBS_SUPPORT)
- free(d->states[i].mbps.elems);
- }
- free(d->states);
- for (i = 0; i < d->tindex; ++i)
- free(d->follows[i].elems);
- free(d->follows);
- for (i = 0; i < d->tralloc; ++i)
+ for (i = 0; i < d->sindex; ++i)
+ {
+ free (d->states[i].elems.elems);
+ free (d->states[i].mbps.elems);
+ }
+ free (d->states);
+
+ if (d->follows)
{
- free(d->trans[i]);
- free(d->fails[i]);
+ for (i = 0; i < d->tindex; ++i)
+ free (d->follows[i].elems);
+ free (d->follows);
}
- free(d->realtrans);
- free(d->fails);
- free(d->newlines);
- free(d->success);
+
+ if (d->trans)
+ {
+ for (i = 0; i < d->tralloc; ++i)
+ {
+ free (d->trans[i]);
+ free (d->fails[i]);
+ }
+
+ free (d->trans - 1);
+ free (d->fails);
+ free (d->newlines);
+ free (d->success);
+ }
+
for (dm = d->musts; dm; dm = ndm)
{
ndm = dm->next;
- free(dm->must);
- free(dm);
+ free (dm->must);
+ free (dm);
}
+
+ if (d->superset)
+ dfafree (d->superset);
}
/* Having found the postfix representation of the regular expression,
@@ -3625,23 +3848,23 @@ dfafree (struct dfa *d)
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
+ 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) ?
+ OR longest common longest common (do p->is and substrings common
+ leading trailing to q->is have same p->in and
+ (sub)sequence (sub)sequence q->in length and content) ?
+ of p->left of p->right
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.
+ 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
+ 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
@@ -3662,135 +3885,85 @@ dfafree (struct dfa *d)
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)? */
+ 'psi|epsilon' is likelier)? */
static char *
icatalloc (char *old, char const *new)
{
char *result;
- size_t oldsize = old == NULL ? 0 : strlen (old);
- size_t newsize = new == NULL ? 0 : strlen (new);
+ size_t oldsize;
+ size_t newsize = strlen (new);
if (newsize == 0)
return old;
+ oldsize = strlen (old);
result = xrealloc (old, oldsize + newsize + 1);
- strcpy (result + oldsize, new);
+ memcpy (result + oldsize, new, newsize + 1);
return result;
}
-static char *
-icpyalloc (char const *string)
-{
- return icatalloc (NULL, string);
-}
-
-static char *
-istrstr (char const *lookin, char const *lookfor)
-{
- char const *cp;
- size_t len;
-
- len = strlen(lookfor);
- for (cp = lookin; *cp != '\0'; ++cp)
- if (strncmp(cp, lookfor, len) == 0)
- return (char *) cp;
- return NULL;
-}
-
static void
freelist (char **cpp)
{
- int i;
-
- if (cpp == NULL)
- return;
- for (i = 0; cpp[i] != NULL; ++i)
- {
- free(cpp[i]);
- cpp[i] = NULL;
- }
+ while (*cpp)
+ free (*cpp++);
}
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;
- }
+ size_t i, j;
+ new = memcpy (xmalloc (len + 1), new, len);
new[len] = '\0';
- /* Is there already something in the list that's new (or longer)? */
+ /* 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)
+ if (strstr (cpp[i], new) != NULL)
{
- free(new);
+ free (new);
return cpp;
}
- /* Eliminate any obsoleted strings. */
+ /* Eliminate any obsoleted strings. */
j = 0;
while (cpp[j] != NULL)
- if (istrstr(new, cpp[j]) == NULL)
+ if (strstr (new, cpp[j]) == NULL)
++j;
else
{
- free(cpp[j]);
+ free (cpp[j]);
if (--i == j)
break;
cpp[j] = cpp[i];
cpp[i] = NULL;
}
- /* Add the new string. */
- cpp = xnrealloc(cpp, i + 2, sizeof *cpp);
+ /* Add the new string. */
+ cpp = xnrealloc (cpp, i + 2, sizeof *cpp);
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. */
+ list of their distinct common substrings. */
static char **
comsubs (char *left, char const *right)
{
- char **cpp;
+ char **cpp = xzalloc (sizeof *cpp);
char *lcp;
- char *rcp;
- size_t i, len;
-
- if (left == NULL || right == NULL)
- return NULL;
- cpp = malloc(sizeof *cpp);
- if (cpp == NULL)
- return NULL;
- cpp[0] = NULL;
+
for (lcp = left; *lcp != '\0'; ++lcp)
{
- len = 0;
- rcp = strchr (right, *lcp);
+ size_t len = 0;
+ char *rcp = strchr (right, *lcp);
while (rcp != NULL)
{
+ size_t i;
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;
- {
- char **p = enlist (cpp, lcp, len);
- if (p == NULL)
- {
- freelist (cpp);
- cpp = NULL;
- break;
- }
- cpp = p;
- }
+ if (len != 0)
+ cpp = enlist (cpp, lcp, len);
}
return cpp;
}
@@ -3798,151 +3971,152 @@ comsubs (char *left, char const *right)
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;
- }
+ for (; *new; new++)
+ old = enlist (old, *new, strlen (*new));
return old;
}
/* Given two lists of substrings, return a new list giving substrings
- common to both. */
+ 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 = malloc(sizeof *both);
- if (both == NULL)
- return NULL;
- both[0] = NULL;
+ char **both = xzalloc (sizeof *both);
+ size_t lnum, rnum;
+
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;
+ char **temp = comsubs (left[lnum], right[rnum]);
+ both = addlists (both, temp);
+ freelist (temp);
+ free (temp);
}
}
return both;
}
-typedef struct
+typedef struct must must;
+
+struct must
{
char **in;
char *left;
char *right;
char *is;
-} must;
+ bool begline;
+ bool endline;
+ must *prev;
+};
+
+static must *
+allocmust (must *mp)
+{
+ must *new_mp = xmalloc (sizeof *new_mp);
+ new_mp->in = xzalloc (sizeof *new_mp->in);
+ new_mp->left = xzalloc (2);
+ new_mp->right = xzalloc (2);
+ new_mp->is = xzalloc (2);
+ new_mp->begline = false;
+ new_mp->endline = false;
+ new_mp->prev = mp;
+ return new_mp;
+}
static void
resetmust (must *mp)
{
+ freelist (mp->in);
+ mp->in[0] = NULL;
mp->left[0] = mp->right[0] = mp->is[0] = '\0';
- freelist(mp->in);
+ mp->begline = false;
+ mp->endline = false;
+}
+
+static void
+freemust (must *mp)
+{
+ freelist (mp->in);
+ free (mp->in);
+ free (mp->left);
+ free (mp->right);
+ free (mp->is);
+ free (mp);
}
static void
dfamust (struct dfa *d)
{
- must *musts;
- must *mp;
- char *result;
- int ri;
- int i;
- int exact;
- token t;
- static must must0;
+ must *mp = NULL;
+ char const *result = "";
+ size_t ri;
+ size_t i;
+ bool exact = false;
+ bool begline = false;
+ bool endline = false;
struct dfamust *dm;
- static char empty_string[] = "";
-
- result = empty_string;
- exact = 0;
- musts = xnmalloc(d->tindex + 1, sizeof *musts);
- mp = musts;
- for (i = 0; i <= d->tindex; ++i)
- mp[i] = must0;
- for (i = 0; i <= d->tindex; ++i)
- {
- mp[i].in = xmalloc(sizeof *mp[i].in);
- mp[i].left = xmalloc(2);
- mp[i].right = xmalloc(2);
- mp[i].is = xmalloc(2);
- 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 < d->tindex; ++i)
- {
- fprintf(stderr, " %d:", i);
- prtok(d->tokens[i]);
- }
- putc('\n', stderr);
-#endif
+
for (ri = 0; ri < d->tindex; ++ri)
{
- switch (t = d->tokens[ri])
+ token t = d->tokens[ri];
+ switch (t)
{
+ case BEGLINE:
+ mp = allocmust (mp);
+ mp->begline = true;
+ break;
+ case ENDLINE:
+ mp = allocmust (mp);
+ mp->endline = true;
+ break;
case LPAREN:
case RPAREN:
assert (!"neither LPAREN nor RPAREN may appear here");
+
case EMPTY:
- case BEGLINE:
- case ENDLINE:
case BEGWORD:
case ENDWORD:
case LIMWORD:
case NOTLIMWORD:
case BACKREF:
- resetmust(mp);
+ case ANYCHAR:
+ case MBCSET:
+ mp = allocmust (mp);
break;
+
case STAR:
case QMARK:
- assert (musts < mp);
- --mp;
- resetmust(mp);
+ resetmust (mp);
break;
+
case OR:
- assert (&musts[2] <= mp);
{
char **new;
- must *lmp;
- must *rmp;
- int j, ln, rn, n;
-
- rmp = --mp;
- lmp = --mp;
- /* Guaranteed to be. Unlikely, but. . . */
- if (!STREQ (lmp->is, rmp->is))
- lmp->is[0] = '\0';
+ must *rmp = mp;
+ must *lmp = mp = mp->prev;
+ size_t j, ln, rn, n;
+
+ /* Guaranteed to be. Unlikely, but ... */
+ if (STREQ (lmp->is, rmp->is))
+ {
+ lmp->begline &= rmp->begline;
+ lmp->endline &= rmp->endline;
+ }
+ else
+ {
+ lmp->is[0] = '\0';
+ lmp->begline = false;
+ lmp->endline = false;
+ }
/* 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);
+ ln = strlen (lmp->right);
+ rn = strlen (rmp->right);
n = ln;
if (n > rn)
n = rn;
@@ -3952,141 +4126,127 @@ dfamust (struct dfa *d)
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(lmp->in);
+ new = inboth (lmp->in, rmp->in);
+ freelist (lmp->in);
+ free (lmp->in);
lmp->in = new;
+ freemust (rmp);
}
break;
+
case PLUS:
- assert (musts < mp);
- --mp;
mp->is[0] = '\0';
break;
+
case END:
- assert (mp == &musts[1]);
- for (i = 0; musts[0].in[i] != NULL; ++i)
- if (strlen(musts[0].in[i]) > strlen(result))
- result = musts[0].in[i];
- if (STREQ (result, musts[0].is))
- exact = 1;
+ assert (!mp->prev);
+ for (i = 0; mp->in[i] != NULL; ++i)
+ if (strlen (mp->in[i]) > strlen (result))
+ result = mp->in[i];
+ if (STREQ (result, mp->is))
+ {
+ exact = true;
+ begline = mp->begline;
+ endline = mp->endline;
+ }
goto done;
+
case CAT:
- assert (&musts[2] <= mp);
{
- must *lmp;
- must *rmp;
+ must *rmp = mp;
+ must *lmp = mp = mp->prev;
- 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')
+ right, plus concatenation of
+ left's right and right's left. */
+ lmp->in = addlists (lmp->in, rmp->in);
+ if (lmp->right[0] != '\0' && rmp->left[0] != '\0')
{
- char *tp;
-
- tp = icpyalloc(lmp->right);
- tp = icatalloc(tp, rmp->left);
- lmp->in = enlist(lmp->in, tp, strlen(tp));
- free(tp);
- if (lmp->in == NULL)
- goto done;
+ size_t lrlen = strlen (lmp->right);
+ size_t rllen = strlen (rmp->left);
+ char *tp = xmalloc (lrlen + rllen);
+ memcpy (tp, lmp->right, lrlen);
+ memcpy (tp + lrlen, rmp->left, rllen);
+ lmp->in = enlist (lmp->in, tp, lrlen + rllen);
+ free (tp);
}
/* Left-hand */
if (lmp->is[0] != '\0')
- {
- lmp->left = icatalloc(lmp->left,
- rmp->left);
- if (lmp->left == NULL)
- goto done;
- }
+ lmp->left = icatalloc (lmp->left, rmp->left);
/* Right-hand */
if (rmp->is[0] == '\0')
lmp->right[0] = '\0';
- lmp->right = icatalloc(lmp->right, rmp->right);
- if (lmp->right == NULL)
- goto done;
+ lmp->right = icatalloc (lmp->right, rmp->right);
/* Guaranteed to be */
- if (lmp->is[0] != '\0' && rmp->is[0] != '\0')
+ if ((lmp->is[0] != '\0' || lmp->begline)
+ && (rmp->is[0] != '\0' || rmp->endline))
{
- lmp->is = icatalloc(lmp->is, rmp->is);
- if (lmp->is == NULL)
- goto done;
+ lmp->is = icatalloc (lmp->is, rmp->is);
+ lmp->endline = rmp->endline;
}
else
- lmp->is[0] = '\0';
+ {
+ lmp->is[0] = '\0';
+ lmp->begline = false;
+ lmp->endline = false;
+ }
+ freemust (rmp);
}
break;
+
+ case '\0':
+ /* Not on *my* shift. */
+ goto done;
+
default:
- if (t < END)
- {
- assert (!"oops! t >= END");
- }
- else if (t == '\0')
- {
- /* not on *my* shift */
- goto done;
- }
- else if (t >= CSET
- || !MBS_SUPPORT
- || t == ANYCHAR
- || t == MBCSET
- )
+ mp = allocmust (mp);
+ if (CSET <= t)
{
- /* 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;
+ /* If T is a singleton, or if case-folding in a unibyte
+ locale and T's members all case-fold to the same char,
+ convert T to one of its members. Otherwise, do
+ nothing further with T. */
+ charclass *ccl = &d->charclasses[t - CSET];
+ int j;
+ for (j = 0; j < NOTCHAR; j++)
+ if (tstbit (j, *ccl))
+ break;
+ if (! (j < NOTCHAR))
+ break;
+ t = j;
+ while (++j < NOTCHAR)
+ if (tstbit (j, *ccl)
+ && ! (case_fold && !d->multibyte
+ && toupper (j) == toupper (t)))
+ break;
+ if (j < NOTCHAR)
+ break;
}
+ mp->is[0] = mp->left[0] = mp->right[0]
+ = case_fold && !d->multibyte ? toupper (t) : t;
+ mp->is[1] = mp->left[1] = mp->right[1] = '\0';
+ mp->in = enlist (mp->in, mp->is, 1);
break;
}
-#ifdef DEBUG
- fprintf(stderr, " node: %d:", ri);
- prtok(d->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))
+done:
+ if (*result)
{
- MALLOC(dm, 1);
+ dm = xmalloc (sizeof *dm);
dm->exact = exact;
- MALLOC(dm->must, strlen(result) + 1);
- strcpy(dm->must, result);
+ dm->begline = begline;
+ dm->endline = endline;
+ dm->must = xstrdup (result);
dm->next = d->musts;
d->musts = dm;
}
- mp = musts;
- for (i = 0; i <= d->tindex; ++i)
+
+ while (mp)
{
- freelist(mp[i].in);
- free(mp[i].in);
- free(mp[i].left);
- free(mp[i].right);
- free(mp[i].is);
+ must *prev = mp->prev;
+ freemust (mp);
+ mp = prev;
}
- free(mp);
}
struct dfa *
@@ -4095,7 +4255,7 @@ dfaalloc (void)
return xmalloc (sizeof (struct dfa));
}
-struct dfamust *
+struct dfamust *_GL_ATTRIBUTE_PURE
dfamusts (struct dfa const *d)
{
return d->musts;
diff --git a/dfa.h b/dfa.h
index 4d65ee34..79027810 100644
--- a/dfa.h
+++ b/dfa.h
@@ -1,5 +1,5 @@
/* dfa.h - declarations for GNU deterministic regexp compiler
- Copyright (C) 1988, 1998, 2007, 2009-2011 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1998, 2007, 2009-2015 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
@@ -18,15 +18,21 @@
/* Written June, 1988 by Mike Haertel */
-#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) || __STRICT_ANSI__
-# define __attribute__(x)
-#endif
+#include <regex.h>
+#ifdef HAVE_STDBOOL_H
+#include <stdbool.h>
+#else
+#include "missing_d/gawkbool.h"
+#endif /* HAVE_STDBOOL_H */
+#include <stddef.h>
/* 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;
+ bool exact;
+ bool begline;
+ bool endline;
char *must;
struct dfamust *next;
};
@@ -67,7 +73,16 @@ extern void dfacomp (char const *, size_t, struct dfa *, int);
encountered a back-reference (1) or not (0). The caller may use this
to decide whether to fall back on a backtracking matcher. */
extern char *dfaexec (struct dfa *d, char const *begin, char *end,
- int newline, int *count, int *backref);
+ int newline, size_t *count, int *backref);
+
+/* Return a superset for D. The superset matches everything that D
+ matches, along with some other strings (though the latter should be
+ rare, for efficiency reasons). Return a null pointer if no useful
+ superset is available. */
+extern struct dfa *dfasuperset (struct dfa const *d) _GL_ATTRIBUTE_PURE;
+
+/* The DFA is likely to be fast. */
+extern bool dfaisfast (struct dfa const *) _GL_ATTRIBUTE_PURE;
/* Free the storage held by the components of a struct dfa. */
extern void dfafree (struct dfa *);
@@ -86,7 +101,7 @@ extern void dfaanalyze (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 (int, struct dfa *, int []);
+extern void dfastate (ptrdiff_t, struct dfa *, ptrdiff_t []);
/* Error handling. */
@@ -99,4 +114,6 @@ extern void dfawarn (const char *);
/* 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 (const char *);
+extern _Noreturn void dfaerror (const char *);
+
+extern int using_utf8 (void);
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
new file mode 100644
index 00000000..e12f5de0
--- /dev/null
+++ b/doc/CMakeLists.txt
@@ -0,0 +1,95 @@
+#
+# doc/CMakeLists.txt --- CMake input file for gawk
+#
+# Copyright (C) 2013
+# 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 3 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 CMake to produce Makefile
+
+MACRO(DocDependency outfile)
+ add_dependencies(doc ${outfile})
+ add_custom_target(
+ ${outfile}
+ DEPENDS ${ARGN}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMAND ${CMAKE_SOURCE_DIR}/cmake/docmaker ${outfile} ${ARGN}
+ )
+ENDMACRO(DocDependency)
+
+find_program(TEXI2DVI_CONVERTER texi2dvi)
+if (TEXI2DVI_CONVERTER)
+ add_custom_target(doc)
+ DocDependency(gawk.texi gawktexi.in rflashlight.eps api-figure1.fig api-figure2.fig api-figure3.fig general-program.fig process-flow.fig)
+ DocDependency(rflashlight.eps)
+ DocDependency(api-figure1.fig)
+ DocDependency(api-figure2.fig)
+ DocDependency(api-figure3.fig)
+ DocDependency(general-program.fig)
+ DocDependency(process-flow.fig)
+ DocDependency(gawk.dvi gawk.texi)
+ DocDependency(gawk.info gawk.texi)
+ DocDependency(gawkinet.dvi gawkinet.texi)
+ DocDependency(gawkinet.info gawkinet.texi)
+ DocDependency(gawkinet.texi statist.eps)
+ DocDependency(gawk.1.ps gawk.1)
+ DocDependency(igawk.1.ps igawk.1)
+ find_program(DVIPS_CONVERTER dvips)
+ if (DVIPS_CONVERTER)
+ DocDependency(gawk.ps gawk.dvi)
+ DocDependency(gawkinet.ps gawkinet.dvi)
+ find_program(PS2PDF_CONVERTER ps2pdf)
+ if (PS2PDF_CONVERTER)
+ DocDependency(gawk.1.pdf gawk.1.ps)
+ DocDependency(igawk.1.pdf igawk.1.ps)
+ DocDependency(gawk.pdf gawk.ps)
+ DocDependency(gawkinet.pdf gawkinet.ps)
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/gawk.1.pdf DESTINATION doc)
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/igawk.1.pdf DESTINATION doc)
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/gawk.info DESTINATION doc)
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/gawk.pdf DESTINATION doc)
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/gawkinet.info DESTINATION doc)
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/gawkinet.pdf DESTINATION doc)
+
+ set(CARDSRC macros cardfonts colors awkcard.tr)
+ set(CARDSRC_N macros cardfonts no.colors awkcard.tr)
+ set(CARDFILES ${CARDSRC} ad.block awkcard.in setter.outline)
+ DocDependency(awkcard.tr awkcard.in)
+ DocDependency(awkcard.nc ${CARDFILES})
+ DocDependency(awkcard.ps ${CARDFILES})
+ DocDependency(awkcard.pdf awkcard.ps)
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/awkcard.pdf DESTINATION doc)
+
+ else()
+ message(WARNING "Found no ps2pdf tool; no doc will be generated")
+ install(CODE "MESSAGE(\"doc generated only in .ps files\")")
+ endif()
+ else()
+ message(WARNING "Found no dvips tool; no doc will be generated")
+ install(CODE "MESSAGE(\"doc generated only in .dvi files and man pages in .ps files\")")
+ endif()
+else()
+ message(WARNING "Found no texi2dvi tool; no doc will be generated")
+ add_custom_command(
+ TARGET doc
+ COMMAND echo no doc generated because of missing texi2dvi
+ )
+endif()
+
diff --git a/doc/ChangeLog b/doc/ChangeLog
index aa365d70..d6e825f2 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,1257 @@
+2015-01-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: O'Reilly fixes.
+ Remove obsolete start/end of range indexing comments.
+
+2015-01-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: O'Reilly fixes.
+
+2015-01-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkinet.texi: Fix capitalization in document title.
+ * gawktexi.in: Here we again: Starting on more O'Reilly fixes.
+
+2014-12-26 Antonio Giovanni Colombo <azc100@gmail.com>
+
+ * gawktexi.in (Glossary): Really sort the items.
+
+2014-12-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Add one more paragraph to new foreword.
+ * gawktexi.in: Fix exponentiation in TeX mode. Thanks to
+ Marco Curreli by way of Antonio Giovanni Columbo.
+
+ * texinfo.tex: Updated.
+
+2014-12-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Minor fix.
+ Thanks to Teri Price <tjp212@lehigh.edu>.
+
+2014-12-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: More minor fixes.
+
+2014-12-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: More minor fixes.
+
+2014-12-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Minor fixes.
+
+2014-12-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: A minor fix.
+
+2014-12-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Various minor fixes and updates.
+
+2014-11-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Update that TZ env. var can influnce mktime
+ in running program. Thanks to Hermann Peifer.
+
+2014-11-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Update that RFC 4180 documents CSV data.
+
+2014-11-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Copyedits applied.
+
+2014-11-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Comment out that I need an owner for awk.info.
+ I may have found one or two people.
+
+2014-10-29 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawktexi.in: Document new extras directory containing shell startup
+ files to manipulate AWKPATH and AWKLIBPATH environment variables.
+
+2014-10-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.1: Clarification that debugger reads stdin.
+ * gawktexi.in: Ditto, and correctly place the "Braces" entry in
+ the Glossary. Thanks to Antonio Colombo for that.
+
+ Unrelated:
+
+ * gawktexi.in: Restore use of @sc. Karl fixed makeinfo. :-)
+
+2014-10-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Minor typo fixes.
+ Fix discussion of \x, per note from Antonio Colombo.
+
+2014-10-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Fix date in docbook attribution for new Foreword;
+ thanks to Antonio Columbo for the catch. Update latest version
+ of gettext.
+
+2014-10-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.1: Fix default value for AWKLIBPATH.
+ * gawktexi.in: Revised text for AWKPATH and AWKLIBPATH.
+
+2014-10-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Add new Foreword from Mike Brennan.
+
+2014-10-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Fix example outputs in chapter 2.
+ Improve description of SYMTAB.
+
+2014-10-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Revise doc for {INT,STR}_CHAIN_MAX. Remove Pat
+ Rankin from VMS duties (per his request). Add a small TeX fix
+ for the table in ch 16 for requesting values.
+
+2014-10-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Finished changes!
+
+2014-10-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (EMRED): Renamed from EMISTERED to match original.
+ Thanks to Warren Toomey at TUHS for access to archives recording
+ the text.
+
+2014-10-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Pretty much done!
+
+ Unrelated:
+
+ * gawktexi.in: Fix braino in awk version of div function.
+ Thanks to Katie Wasserman for the catch.
+
+2014-10-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: More fixes after reading through the MS.
+
+ Unrelated:
+
+ * gawktexi.in: Add Katie Wasserman's program to compute
+ the digits of PI.
+
+ Unrelated:
+
+ * gawktexi.in: Document the differences between profiling
+ and pretty printing.
+
+2014-09-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: More fixes after reading through the MS.
+
+2014-09-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: More fixes after reading through the MS.
+ And still more fixes.
+
+2014-09-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: More fixes after reading through the MS.
+ Document the debugger's "where" command.
+
+2014-09-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Lots more fixes after reading through the MS.
+
+2014-09-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Rework the documentation of special files in
+ Chapter 5; some reordering as well as rewriting.
+
+2014-09-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktex.in: Continue fixes after reading through the MS.
+
+2014-09-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktex.in: Start on fixes after reading through the MS.
+
+2014-09-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Fix italics in quotations. Some docbook special
+ cases.
+
+2014-09-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Document that identifiers must use the English
+ letters.
+
+2014-09-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: More edits during review, minor addition.
+
+2014-09-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Remove text that won't get used.
+
+2014-09-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Minor cleanups.
+
+2014-09-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Document builtin functions in FUNCTAB and in
+ PROCINFO["identifiers"].
+ * gawk.1: Ditto.
+
+ Unrelated:
+
+ * gawktexi.in: More stuff from reviewer comments.
+
+2014-09-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Document that indirect calls now work on built-in
+ and extension functions.
+ * gawk.1: Same.
+
+2014-09-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Further fixes from reviews and bug reports.
+
+2014-09-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Corrections to walkthrough in debugger chapter.
+ Thanks to David Ward <dlward134@gmail.com> for the problem report.
+
+2014-09-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Add index entry for @ - @load, @include,
+ and indirect function calls. Thanks to "Kenny McKormack" in
+ comp.lang.awk.
+
+2014-08-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Continuing on reviewer comments, and other
+ bug fixes, miscellanious improvements.
+
+2014-08-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Use a different mechanism to exclude
+ exercises. Remove use of LC_ALL in an example; doesn't seem
+ to be needed anymore.
+
+ Unrelated:
+
+ * gawktexi.in: Document that MirBSD is no longer supported.
+
+2014-08-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Exercises are excluded from print edition.
+
+2014-08-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Continuing on reviewer comments.
+
+2014-08-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Continuing on reviewer comments.
+
+2014-08-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Continuing on reviewer comments.
+
+2014-08-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Continuing on reviewer comments.
+
+2014-08-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Continuing on reviewer comments.
+
+2014-08-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Continuing on reviewer comments.
+
+2014-08-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Starting on reviewer comments.
+ Update acknowledgements.
+
+2014-08-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Cause div.awk to get into the example files.
+
+2014-08-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Misc minor additions.
+
+2014-08-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: For sprintf %c document that if value is a valid
+ wide character, gawk uses the low 8 bits of the value.
+
+ Unrelated:
+
+ * gawktexi.in: Fix doc for API get_record - errcode needs to
+ be greater than zero.
+
+2014-07-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Numeric Functions): For `div()', clarify
+ truncation is towards zero. Thanks to Michal Jaegermann
+ for pointing out the need to clarify this.
+
+2014-07-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Numeric Functions): Document new `div()' function.
+ (Arbitrary Precision Integers): Document raison d'etre for div().
+ * gawk.1, awkcard.in: Document `div()'.
+
+2014-07-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Bracket Expressions): Add a note about how to
+ match ASCII characters. Thanks to Hermann Peifer.
+
+2014-06-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Update permissions on copyright page per
+ latest maintain.texi. Add GPL to print version of book.
+
+2014-06-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Document that --pretty-print no longer runs the
+ program. Remove mention of GAWK_NO_PP_RUN env var.
+
+2014-06-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Typo fixes and minor corrections.
+
+2014-06-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Add thanks to Patrice Dumas and to Karl Berry.
+ Per request from Hermann Peifer, try to clarify how local variables
+ in functions are initialized.
+
+2014-06-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Split 6.1.4 into subsections. Other minor fixes.
+
+2014-06-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Finish adding exerices.
+ Rework chapter 15 on floating point and MPFR.
+ Spell check. Fix menues.
+
+2014-06-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Start adding exercises.
+
+2014-06-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Finish up summaries. Improvements in mystrtonum().
+
+2014-06-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Fix typos from changes of 3 June when macros were
+ added for filename, data file, etc. Ooops.
+
+2014-06-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: More "Summary" sections. Through chapter 14.
+
+2014-06-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: More "Summary" sections. Through chapter 10.
+
+2014-06-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Update docbook figure markup.
+
+2014-06-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: More "Summary" sections.
+ Judiciously arrange for full xrefs in docbook in a few spots.
+
+2014-06-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Start adding "Summary" sections.
+
+2014-06-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Restore macros for file name vs. filename etc.
+ Go through @if... and @ifnot... and fix them up too. Other misc.
+ cleanup.
+
+2014-05-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Remove some obsolete bits, fix up some other
+ minor stuff.
+
+2014-05-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Edits through the end!
+
+2014-05-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Edits through Appendix A.
+ * gawktexi.in: Tweak nested lists for docbook.
+
+2014-05-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Staying current): New section.
+
+2014-05-22 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawktexi.in (BEGINFILE/ENDFILE): Update doc for getline - any
+ redirected form is allowed inside BEGINFILE/ENDFILE.
+
+2014-05-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Add comments for where we need full xrefs in
+ docbook.
+
+2014-05-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Misc improvements for docbook, consistency
+ in table and figure captions.
+
+2014-05-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Edits through Chapter 16.
+
+2014-05-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Edits through Chapter 14.
+
+2014-05-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Fix displays for docbook, edits through Chapter 11.
+
+2014-05-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Fix real preface for docbook.
+
+2014-05-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Complete formatting for FOR_PRINT and not FOR_PRINT.
+
+2014-05-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Docbook edits for preface and parts.
+ Document AWKBUFSIZE.
+
+2014-05-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Editing progress. Through Chapter 9.
+
+2014-05-05 Michal Jaegermann <michal@harddata.com>
+
+ * array-elements.fig: Fix subscripts to be aligned
+ horizontally. Regenerate the other files.
+
+2014-05-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Editing progress. Through Chapter 8.
+ * array-elements.eps, array-elements.fig, array-elements.pdf,
+ array-elements.png array-elements.txt: New files.
+ * Makefile.am (EXTRA_DIST): Add them.
+
+2014-04-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Editing progress. Through Chapter 5.
+ * gawktexi.in: Editing progress. Through Chapter 6 and into
+ Chapter 7.
+
+2014-04-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Editing progress. Through Chapter 3.
+
+2014-04-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Start on revisions.
+
+2014-04-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.1: Remove the bit about single character programs overflowing
+ the parse stack. It doesn't seem to be true anymore.
+
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.1: Release tar ball made.
+
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Update to latest.
+ * awkcard.in: Update copyright, patchlevel in download.
+ * gawktexi.in: Update patchlevel, update month, spell check.
+
+2014-03-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Cleanups to docbook, finish math stuff.
+
+2014-03-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Minor cleanups to the indexing.
+
+ Unrelated:
+
+ * gawktexi.in: Merge in changes needed for creating valid
+ DocBook XML. Works with post-5.2 Texinfo and dblatex!
+
+2014-03-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Finish the massive indexing improvements such that
+ functions are indexed the way I want in TeX and the way Eli
+ wants in Info.
+
+ Unrelated:
+
+ * gawktexi.in: Add a note in extension chapter that lookup of
+ PROCINFO can fail.
+
+2014-03-27 Eli Zaretskii <eliz@gnu.org>
+
+ * gawktexi.in: First round of massive indexing improvements.
+
+2014-03-27 Antonio Giovanni Colombo <azc100@gmail.com>
+
+ * gawktexi.in: Redo all the examples using BBS-list to a different
+ file that doesn't use out-of-date concepts.
+
+2014-03-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Finish indexing improvements. (For now, anyway.)
+
+ Unrelated:
+
+ * gawk.1: Document the quote flag! (Better late than never.)
+ * awkcard.in: Update documentation of quote flag.
+
+2014-03-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Minor edits to the discussion of the memory allocation
+ functions.
+
+2014-03-08 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawktexi.in: Document new extension API functions api_malloc,
+ api_calloc, api_realloc, and api_free.
+
+2014-03-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Indexing improvements.
+
+2014-03-02 John E. Malmberg <wb8tyw@qsl.net>
+
+ * gawktexi.in: Remove paragraph about obsolete VMS
+ compilers. Update reference about building PCSI kit.
+
+2014-02-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Lots of small fixes throughout, update of
+ profiling output. Finished fixes needed before a release.
+
+2014-02-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Add a quote to the alarm clock program.
+
+2014-02-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Update to latest.
+
+2014-02-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Lots of small edits.
+
+2014-02-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: More minor fixes, update UPDATE_MONTH.
+
+2014-02-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: More minor fixes, in indexing.
+
+2014-02-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in, gawkinet.texi: Minor fixes, mostly in indexing.
+ * texinfo.tex: Update to latest.
+
+2014-01-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Add `()' to names of extension functions in indexing
+ commands and in one place in the text. Consistency, don'tcha know.
+
+2014-01-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Add a few missing STARTOFRANGE comments.
+ * gawk.1: Note that `(i, j) in array' doesn't work in for loops.
+ Update the copyright year.
+
+2014-01-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Update info for Anders Wallin.
+
+2014-01-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Updated to current version.
+ * gawktexi.in: Add magic stuff so that PDFs have "dark red"
+ links like before.
+
+2014-01-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Feature History): New node.
+ (Common Extensions): Update features now in mawk, too.
+
+2014-12-14 John E. Malmberg <wb8tyw@qsl.net>
+
+ * gawktexi.in: Add information on building VMS PCSI kit.
+
+2014-01-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Full Line Fields): New node.
+ Update copyright year.
+
+2013-12-29 John E. Malmberg <wb8tyw@qsl.net>
+
+ * gawktexi.in: VMS dynamic extensions.
+
+2013-12-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: More minor additions / fixes.
+ (Bugs): Add John Malmberg for VMS. Other minor edits.
+
+2013-12-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Minor additions / fixes.
+
+2013-12-23 John E. Malmberg <wb8tyw@qsl.net>
+
+ * gawktexi.in: Document the VMS exit status encoding.
+
+2013-12-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Additional Configuration Options): Document
+ the --disable-extensions option.
+
+2013-12-16 John E. Malmberg <wb8tyw@qsl.net>
+
+ * gawktexi.in: Updates to VMS sections.
+
+2013-12-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Fix the presentation of asort() and asorti().
+ Thanks to Andy Schorr for pointing out the problems.
+
+2013-11-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Update quotations to use @author, fix a few
+ placements of footnotes.
+
+2013-11-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Update the list of files included in the gawk
+ distribution and fix a few typos.
+
+2013-11-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Fix the section and subsection headings in
+ the Preface. Also change the short title page to just
+ "GNU Awk".
+
+2013-10-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Add @shorttitlepage command.
+
+2013-10-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Contributors): Update with more info.
+ (Distributtion contents): Ditto.
+ General: Remove all hyphens when used with "multi" prefix.
+
+2013-10-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Other Environment Variables): Document GAWK_MSG_SRC
+ variable and fix documentation of *_CHAIN_MAX variables.
+
+2013-10-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Conversion, Printf Ordering): Better wording for
+ descriptions of CONVFMT. Thanks to Hermann Peifer.
+
+2013-09-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Other Versions): Updated info on MKS awk and
+ some other links.
+
+2013-09-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Readfile function): New node.
+
+2013-09-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (FN, FFN, DF,DDF, PVERSION, CTL): Remove macros.
+ They have no alternate versions and are just in the way.
+
+2013-08-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.1: Document that ENVIRON updates affect the environment.
+ * gawktexi.in: Ditto.
+
+2013-06-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Update from Karl, fixes a formating problem.
+ * gawktexi.in (Conversions): Undo @w{} around @option{--posix}.
+
+2013-06-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Type Functions): Add more explanation to isarray(),
+ including that it makes no sense to call it at the global level.
+
+2013-06-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Make it crystal clear not to use delete with FUNCTAB,
+ or attempt to assign to it.
+
+2013-05-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Internal File Description): Add "devbsize" element
+ to stat data array.
+
+2013-05-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawtexi.in: Sample filefuncs.c extension code: Change test from
+ ifdef HAVE_ST_BLKSIZE to HAVE_STRUCT_STAT_ST_BLKSIZE.
+
+2013-05-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Quick Installation): Add a paragraph advising to
+ run `make install'. Thanks to Hermann Peifer.
+
+2013-05-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (gawkextlib): Add a note to use make install on
+ gawkextlib itself. Thanks to Hermann Peifer.
+ (Cut program): Fix test for skipping lines if -s was supplied.
+ Thanks to David Ward <bamberward@gmail.com> for the bug report.
+
+2013-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.0: Release tar ball made.
+
+2013-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in, gawk.1: Document that a regexp constant as the second
+ argument to index() produces a fatal error.
+ * gawktexi.in: More cleanups. Particularly, cleanup the index.
+
+2013-04-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Renamed from gawkman.texi.
+ Add a reference to Overton's IEEE Math book in MPFR chapter.
+ Thanks to Nelson Beebe for the recommendation.
+ * Makefile.am, sidebar.awk: Adjusted.
+
+2013-04-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkman.texi: Cleanup in MPFR and API chapters.
+ Also minor cleanup in design decisions. Add vim modeline.
+ * api-figure2.fig: Minor fix.
+ * api-figure2.eps, api-figure2.pdf, api-figure2.png: Regenerated.
+
+2013-04-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.1: Finish cleanup pass.
+ * awkcard.in: Document that getline sets RT.
+ * gawkman.texi: Ditto.
+
+2013-04-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.1: Start cleanup pass.
+ * awkcard.in: Minor addition.
+ * gawkman.texi: Minor fixes.
+
+ * gawk.1, gawkman.texi: Document PROCINFO entries for API
+ major and minor versions.
+
+2013-04-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkman.texi: Update all the menus. Fix spelling errors. Remove
+ some unneeded fakenodes.
+
+2013-04-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkcard.in: Clean up and bring up to date.
+
+2013-04-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (gawk.ps, gawkinet.ps): Set TEXINPUTS to point
+ at $(srcdir) to be able to include various figures if doing a
+ build not in the source directory.
+
+2013-04-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkman.texi: New file. This is now the real source for the
+ manual and gawk.texi is generated from it.
+ * sidebar.awk: New file to DTRT for sidebars in the manual.
+ * Makefile.am (EXTRA_DIST): Update.
+ (gawk.texi): Add new rule to create / update it if necessary.
+
+2013-04-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Pretty much finish cleanup. Move i18n chapter to
+ after advanced features chapter.
+ * texinfo.tex: Updated to current in texinfo SVN.
+
+2013-04-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Continue cleanup.
+
+2013-04-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Add link to 'pawk' - awk for python.
+ Further cleanups.
+
+2013-04-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Continue cleanup.
+
+2013-04-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Continue cleanup.
+
+2013-04-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Continue cleanup.
+
+2013-04-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Continue cleanup.
+
+2013-04-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Start a simple cleanup pass before the release.
+
+2013-03-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Update URL for texinfo, fix a typo.
+
+2013-03-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi (Getline/Pipe): Add a nice quote from BWK.
+
+2013-02-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Restore centering of text images.
+
+2013-02-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi (Other Versions): Remove the description of xmlgawk.
+
+2013-02-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: For Info output, don't use @center on text images
+ since the new makeinfo doesn't yet center the file as a block.
+ Thanks to Karl Berry for the diagnostic.
+ * gawk.1: Remove commented out doc for -m option which was for
+ compatibility with BWK awk. His awk dropped it back in 2007.
+
+2013-01-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * api-figure2.txt, api-figure3.txt: Convert tabs to spaces.
+ * gawk.texi (Gory Details): Fix a command that new makeinfo doesn't
+ recognize.
+ (Conversion): Update example to be in POSIX mode. Thanks to
+ Hermann Peifer.
+
+2013-01-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi (Dynamic Typing): Clarify that gawk dies after the
+ first fatal error on the test program. Thanks to Hermann Peifer.
+
+2013-01-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi (Setting Precision): Fix a typo. 3.322 instead
+ of 3.332. Thanks to Hermann Peifer.
+
+2013-01-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Minor edits to documentation for new inplace extension.
+
+2013-01-08 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawk.texi: Add documentation for new inplace extension.
+
+2013-01-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi, awkcard.in: Sync what mawk has. Main point of
+ interest is that mawk supports the three time functions.
+
+2013-01-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi, awkcard.in: Add Git Hub info for BWK awk.
+ Update copyrights.
+ * gawk.texi: Add Software Tools quote in chapter on library functions.
+
+2012-12-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Remove doc sym_constant() API function.
+
+2012-12-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.2: Release tar ball made.
+
+2012-12-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Remove an incorrect comment.
+ * awkcard.in: Bump patch level.
+
+2012-12-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi (Input Parsers): Add info on read_func.
+
+2012-12-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Move design decisions on new API to appendix C.
+ Move section on old extensions to last in the same appendix.
+
+2012-12-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * macros: Update to GPL Version 3 and add copyright year.
+ * texinfo.tex: Updated, from automake 1.12.6.
+ * gawk.texi (Derived Files): A few minor fixes.
+
+2012-12-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkforai.txt: Changed content to be pointers to the article
+ to avoid copyright issues.
+ * gawk.texi: Updated description of awkforai.txt.
+
+2012-12-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi (I/O Functions): Document that fflush() is now part
+ of POSIX. Fix in a few other places as well.
+ * awkcard.in: Update for fflush().
+
+2012-12-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Fix all @tex ... @end tex tables to use a different
+ control character than @ so that the new makeinfo won't
+ complain about them. Thanks to Karl Berry for the guidance.
+ (Old Extension Mechansim): New node.
+
+2012-12-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: API chapter. Sync with gawkapi.h
+
+2012-11-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: API chapter. Change command for making shared libs
+ to use gcc, not ld. Thanks to Nelson Beebe.
+ (I/O Functions): Document new behavior for fflush().
+ * gawk.1: Update for fflush().
+ * awkcard.in: Ditto. And some general cleanup.
+
+2012-11-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi (Future Extensions): Point to TODO file in the
+ gawk dist.
+ (Implementation Limitations): New node, from old LIMITATIONS file.
+
+2012-11-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: In API chapter, document the full list of include
+ files that need to be included.
+
+2012-11-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: In API chapter, update behavior of stat function
+ in the filefuncs extension. Update the code example and prose
+ to match the current code.
+
+2012-11-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: In API chapter, update behavior of readdir extension.
+
+2012-11-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Minor edits in API chapter.
+ Thanks to Nelson Beebe.
+
+2012-11-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Minor edits in API chapter.
+ Thanks to Andrew Schorr.
+
+2012-11-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Rearrange chapter order and separate into parts
+ using @part for TeX. Fix capitalization in @caption text.
+ (Variable Scope): Document that arrays can be local also.
+ Thanks to Denis Shirokov <cosmogen@gmail.com>, for pointing out
+ the lack.
+
+2012-11-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Semi-rationalize invocations of @image.
+
+2012-11-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: New chapter on extension API.
+ * api-figure1.pdf, api-figure2.pdf, api-figure3.pdf,
+ general-program.pdf, process-flow.pdf: New files. Again.
+ * Makefile.am (EXTRA_DIST): Update. Again.
+
+2012-11-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * api-figure1.pdf, api-figure2.pdf, api-figure3.pdf: Removed.
+ * api-figure1.txt, api-figure2.txt, api-figure3.txt,
+ api-figure1.png, api-figure2.png, api-figure3.png: New files.
+ * Makefile.am (EXTRA_DIST): Update.
+
+ * gawk.texi: Fix up images.
+ * general-program.pdf, process-flow.pdf: Removed.
+ * general-program.png, process-flow.png,
+ general-program.txt, process-flow.txt: New files.
+ * Makefile.am (EXTRA_DIST): Update.
+
+2012-10-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * api-figure1.eps, api-figure1.fig, api-figure1.pdf,
+ api-figure2.eps, api-figure2.fig, api-figure2.pdf,
+ api-figure3.eps, api-figure3.fig, api-figure3.pdf: New files.
+ * Makefile.am (EXTRA_DIST): Add the above.
+
+2012-10-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi (Glossary): Document cookie, some cleanup of
+ notes at the end.
+
+2012-10-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: More doc on SYMTAB.
+
+2012-10-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (LN, install-data-hook, uninstall-hook): Removed. No
+ longer needed since dgawk and pgawk are gone.
+
+2012-10-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am: Add dgawk.1 to man page links created / removed
+ on install / uninstall. (On stable branch.)
+
+2012-10-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi (Glossary). Correct the full name for `ISO' per
+ bug report from William Bresler <wbresler@acm.org>. Add a link
+ to the ISO website.
+
+ * gawk.texi, gawk.1, awkcard.in: Document FUNCTAB, SYMTAB, and
+ PROCINFO["identifiers"]. Including that delete does not work
+ on FUNCTAB and SYMTAB.
+
+2012-09-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi (Nextfile Statement): Document that it's now part of POSIX
+ and update the title.
+ (Delete): Document that `delete array' is now part of POSIX.
+ * awkcard.in: Adjust coloring for nextfile and delete array.
+
+2012-09-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Updated to version 2012-09-05.06.
+
+2012-08-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Minor edits, fix some spelling mistakes.
+
+2012-08-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: More edits to chapter on arithmetic.
+ Primarily English changes.
+
+2012-08-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Emphasize more that floating point behavior is
+ not a language issue. Add a pointer to POSIX bc.
+ Move arithmetic chapter to later in the book, before chapter
+ on dynamic extensions.
+
+2012-08-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Update infrastructure to Automake 1.12.3.
+
+2012-08-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Fixed a math bug in the chapter on multiple
+ precision floating point. Thanks to John Haque.
+
+2012-08-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Merged discussion of numbers from Appendix C into
+ the chapter on arbitrary precision arithmetic. Did some surgery
+ on that chapter to organize it a little better.
+
+2012-08-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkcard.in, gawk.1, gawk.texi: Updated. Mostly for new API stuff
+ but also some other things.
+ * gawk.texi (Derived Files): New node.
+
+2012-08-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (install-data-hook): Install a dgawk.1 link to the
+ man page also. Remove it on uninstall.
+
+2012-07-29 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawk.texi: Document that RT is set by getline.
+
+2012-07-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi, gawk.1, awkcard.in: Document that and(), or(), and
+ xor() can all take any number of arguments, with a minimum of two.
+
+2012-06-10 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawk.texi: Rename gettimeofday function to getlocaltime, since
+ the new time extension will provide gettimeofday.
+
+2012-05-24 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawk.texi, gawk.1: Replace references to dlload with dl_load.
+ But much more work needs to be done on the docs.
+
+2012-05-19 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawk.texi, gawk.1: Document new -i option, and describe new default
+ .awk suffix behavior.
+
+2012-04-01 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawk.texi: Replace documentation of removed functions update_ERRNO and
+ update_ERRNO_saved with descriptions new functions update_ERRNO_int,
+ update_ERRNO_string and unset_ERRNO. And fix a couple of examples
+ to use update_ERRNO_int instead of update_ERRNO.
+
+2012-03-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Minor style edits.
+
+2012-03-21 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawk.texi, gawk.1: Document new @load keyword.
+
+2012-03-20 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawk.texi, gawk.1: Add AWKLIBPATH.
+
+2012-08-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi (Ranges and Locales): Clarified ranges and
+ locales. Again.
+
+2012-08-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi (PC Binary Installation): Document Eli Zaretskii's
+ site.
+ (Records): Update case of RS = "a". It only prints 1 if in
+ POSIX mode. Thanks to Jeroen Schot who first reported it.
+
+2012-07-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi (Ranges and Locales): Clarified ranges and
+ locales.
+
+2012-07-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi (Getline Notes): Discuss side effects in
+ argument expression.
+
+2012-06-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi, awkcard.in: Latest mawk understands /dev/stdin.
+
+2012-04-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Add that -b affects output.
+
+2012-04-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Update to latest from automake 1.12.
+
+2012-04-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * texinfo.tex: Update to latest from automake 1.11.4.
+
+2012-04-11 John Haque <j.eh@mchsi.com>
+
+ * gawk.texi: Change RNDMODE to ROUNDMODE.
+ * gawk.1, awkcard.in: Ditto.
+
+2012-04-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Change --arbitrary-precision to --bignum.
+ * gawk.1: Ditto.
+ * awkcard.in: Add --bignum, RNDMODE, PREC.
+
+2012-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Editing on new chapter on arbitrary precision numbers.
+
+2012-03-31 John Haque <j.eh@mchsi.com>
+
+ * gawk.texi, gawk.1: Add text on support for arbitrary precision
+ numbers.
+
+2012-02-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi, gawk.1: And some minor edits thereunto.
+
+2012-02-03 John Haque <j.eh@mchsi.com>
+
+ * gawk.texi, gawk.1: Add text on read timeout.
+
+2011-12-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkcard.in, gawk.1: Minor edits after merge of executables.
+
+2011-12-21 John Haque <j.eh@mchsi.com>
+
+ * gawk.texi: Updated sections on profiling and debugging
+ after merging the exes. Document new options --debug and
+ --load, and add a sub-section on loading extension library.
+ * gawk.1: Same.
+ * awkcard.in: Same.
+
+2012-03-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.1: Release tar ball made.
+
+2012-02-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi, awkcard.in: Bump patch level.
+ * texinfo.tex: Updated from Texinfo CVS.
+
+2011-12-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Various typo fixes from mailing list.
+
+2011-11-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.1: Fix some .BR to be .B.
+
+2011-11-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Further improvement in the discussion of sorted array
+ traversal. Some sections reordered and text edited to suit.
+
+2011-11-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawk.texi: Try to improve discussion of sorted array
+ traversal.
+
2011-09-24 Arnold D. Robbins <arnold@skeeve.com>
* gawk.1: Fix some spelling errors. Thanks to
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 744b70a9..8a0442a7 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -26,12 +26,23 @@
info_TEXINFOS = gawk.texi gawkinet.texi
-man_MANS = gawk.1 igawk.1
+man_MANS = gawk.1
EXTRA_DIST = ChangeLog ChangeLog.0 README.card ad.block setter.outline \
awkcard.in awkforai.txt texinfo.tex cardfonts \
+ api-figure1.eps api-figure1.fig api-figure1.pdf \
+ api-figure1.png api-figure1.txt \
+ api-figure2.eps api-figure2.fig api-figure2.pdf \
+ api-figure2.png api-figure2.txt \
+ api-figure3.eps api-figure3.fig api-figure3.pdf \
+ api-figure3.png api-figure3.txt \
+ array-elements.eps array-elements.fig array-elements.pdf \
+ array-elements.png array-elements.txt \
+ gawktexi.in sidebar.awk \
general-program.eps general-program.fig general-program.pdf \
+ general-program.png general-program.txt \
process-flow.eps process-flow.fig process-flow.pdf \
+ process-flow.png process-flow.txt \
macros colors no.colors $(man_MANS) \
lflashlight-small.xpic lflashlight.eps lflashlight.pdf \
rflashlight-small.xpic rflashlight.eps rflashlight.pdf \
@@ -39,7 +50,7 @@ EXTRA_DIST = ChangeLog ChangeLog.0 README.card ad.block setter.outline \
bc_notes
# Get rid of generated files when cleaning
-CLEANFILES = *.ps *.html *.dvi *~ awkcard.nc awkcard.tr gawk.pdf gawkinet.pdf awkcard.pdf gawk.1.pdf igawk.1.pdf
+CLEANFILES = *.ps *.html *.dvi *~ awkcard.nc awkcard.tr gawk.pdf gawkinet.pdf awkcard.pdf gawk.1.pdf
MAKEINFO = @MAKEINFO@ --no-split --force
@@ -61,31 +72,18 @@ AWKCARD = awkcard.ps
# 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.
+gawk.texi: $(srcdir)/gawktexi.in $(srcdir)/sidebar.awk
+ awk -f $(srcdir)/sidebar.awk < $(srcdir)/gawktexi.in > gawk.texi
-# We want hard links for install-data-hook, below
-LN= ln -f
+postscript: gawk.ps gawkinet.ps gawk.1.ps $(AWKCARD)
-# 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)
-
-pdf: postscript gawk.pdf gawkinet.pdf awkcard.pdf gawk.1.pdf igawk.1.pdf
+pdf: postscript gawk.pdf gawkinet.pdf awkcard.pdf gawk.1.pdf
gawk.ps: gawk.dvi
- dvips -o gawk.ps gawk.dvi
+ TEXINPUTS=$(srcdir): dvips -o gawk.ps gawk.dvi
gawkinet.ps: gawkinet.dvi
- dvips -o gawkinet.ps gawkinet.dvi
+ TEXINPUTS=$(srcdir): dvips -o gawkinet.ps gawkinet.dvi
gawk.1.ps: gawk.1
-groff -man $(srcdir)/gawk.1 > gawk.1.ps
@@ -93,12 +91,6 @@ gawk.1.ps: gawk.1
gawk.1.pdf: gawk.1.ps
ps2pdf gawk.1.ps gawk.1.pdf
-igawk.1.ps: igawk.1
- -groff -man $(srcdir)/igawk.1 > igawk.1.ps
-
-igawk.1.pdf: igawk.1.ps
- ps2pdf igawk.1.ps igawk.1.pdf
-
awkcard.tr: awkcard.in
sed 's:SRCDIR:$(srcdir):' < $(srcdir)/awkcard.in > awkcard.tr
diff --git a/doc/Makefile.in b/doc/Makefile.in
index 2d3dbae2..a17000bc 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
+# Copyright (C) 1994-2013 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.
@@ -39,6 +38,51 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -58,20 +102,19 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = doc
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog \
- texinfo.tex
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/mkinstalldirs texinfo.tex ChangeLog
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/arch.m4 \
$(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/gettext.m4 \
$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
- $(top_srcdir)/m4/intmax_t.m4 $(top_srcdir)/m4/inttypes_h.m4 \
$(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/lcmessage.m4 \
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libsigsegv.m4 \
- $(top_srcdir)/m4/longlong.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/longlong.m4 $(top_srcdir)/m4/mpfr.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/noreturn.m4 \
$(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
$(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/socket.m4 \
- $(top_srcdir)/m4/stdint_h.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)
@@ -79,8 +122,48 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
SOURCES =
DIST_SOURCES =
+AM_V_DVIPS = $(am__v_DVIPS_@AM_V@)
+am__v_DVIPS_ = $(am__v_DVIPS_@AM_DEFAULT_V@)
+am__v_DVIPS_0 = @echo " DVIPS " $@;
+am__v_DVIPS_1 =
+AM_V_MAKEINFO = $(am__v_MAKEINFO_@AM_V@)
+am__v_MAKEINFO_ = $(am__v_MAKEINFO_@AM_DEFAULT_V@)
+am__v_MAKEINFO_0 = @echo " MAKEINFO" $@;
+am__v_MAKEINFO_1 =
+AM_V_INFOHTML = $(am__v_INFOHTML_@AM_V@)
+am__v_INFOHTML_ = $(am__v_INFOHTML_@AM_DEFAULT_V@)
+am__v_INFOHTML_0 = @echo " INFOHTML" $@;
+am__v_INFOHTML_1 =
+AM_V_TEXI2DVI = $(am__v_TEXI2DVI_@AM_V@)
+am__v_TEXI2DVI_ = $(am__v_TEXI2DVI_@AM_DEFAULT_V@)
+am__v_TEXI2DVI_0 = @echo " TEXI2DVI" $@;
+am__v_TEXI2DVI_1 =
+AM_V_TEXI2PDF = $(am__v_TEXI2PDF_@AM_V@)
+am__v_TEXI2PDF_ = $(am__v_TEXI2PDF_@AM_DEFAULT_V@)
+am__v_TEXI2PDF_0 = @echo " TEXI2PDF" $@;
+am__v_TEXI2PDF_1 =
+AM_V_texinfo = $(am__v_texinfo_@AM_V@)
+am__v_texinfo_ = $(am__v_texinfo_@AM_DEFAULT_V@)
+am__v_texinfo_0 = -q
+am__v_texinfo_1 =
+AM_V_texidevnull = $(am__v_texidevnull_@AM_V@)
+am__v_texidevnull_ = $(am__v_texidevnull_@AM_DEFAULT_V@)
+am__v_texidevnull_0 = > /dev/null
+am__v_texidevnull_1 =
INFO_DEPS = $(srcdir)/gawk.info $(srcdir)/gawkinet.info
am__TEXINFO_TEX_DIR = $(srcdir)
DVIS = gawk.dvi gawkinet.dvi
@@ -93,6 +176,11 @@ TEXI2PDF = $(TEXI2DVI) --pdf --batch
MAKEINFOHTML = $(MAKEINFO) --html
AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
DVIPS = dvips
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
am__installdirs = "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)"
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
@@ -115,12 +203,20 @@ am__nobase_list = $(am__nobase_strip_setup); \
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
man1dir = $(mandir)/man1
NROFF = nroff
MANS = $(man_MANS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
@@ -138,6 +234,7 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
+GAWKLIBEXT = @GAWKLIBEXT@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
@@ -153,6 +250,7 @@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
LDFLAGS = @LDFLAGS@
LIBICONV = @LIBICONV@
LIBINTL = @LIBINTL@
+LIBMPFR = @LIBMPFR@
LIBOBJS = @LIBOBJS@
LIBREADLINE = @LIBREADLINE@
LIBS = @LIBS@
@@ -178,6 +276,7 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
POSUB = @POSUB@
+SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SOCKET_LIBS = @SOCKET_LIBS@
@@ -194,6 +293,7 @@ abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
+acl_shlibext = @acl_shlibext@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -228,23 +328,36 @@ mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
+pkgextensiondir = @pkgextensiondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
info_TEXINFOS = gawk.texi gawkinet.texi
-man_MANS = gawk.1 igawk.1
+man_MANS = gawk.1
EXTRA_DIST = ChangeLog ChangeLog.0 README.card ad.block setter.outline \
awkcard.in awkforai.txt texinfo.tex cardfonts \
+ api-figure1.eps api-figure1.fig api-figure1.pdf \
+ api-figure1.png api-figure1.txt \
+ api-figure2.eps api-figure2.fig api-figure2.pdf \
+ api-figure2.png api-figure2.txt \
+ api-figure3.eps api-figure3.fig api-figure3.pdf \
+ api-figure3.png api-figure3.txt \
+ array-elements.eps array-elements.fig array-elements.pdf \
+ array-elements.png array-elements.txt \
+ gawktexi.in sidebar.awk \
general-program.eps general-program.fig general-program.pdf \
+ general-program.png general-program.txt \
process-flow.eps process-flow.fig process-flow.pdf \
+ process-flow.png process-flow.txt \
macros colors no.colors $(man_MANS) \
lflashlight-small.xpic lflashlight.eps lflashlight.pdf \
rflashlight-small.xpic rflashlight.eps rflashlight.pdf \
@@ -253,7 +366,7 @@ EXTRA_DIST = ChangeLog ChangeLog.0 README.card ad.block setter.outline \
# Get rid of generated files when cleaning
-CLEANFILES = *.ps *.html *.dvi *~ awkcard.nc awkcard.tr gawk.pdf gawkinet.pdf awkcard.pdf gawk.1.pdf igawk.1.pdf
+CLEANFILES = *.ps *.html *.dvi *~ awkcard.nc awkcard.tr gawk.pdf gawkinet.pdf awkcard.pdf gawk.1.pdf
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/"
@@ -265,18 +378,6 @@ 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 -f
all: all-am
.SUFFIXES:
@@ -313,7 +414,7 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
.texi.info:
- restore=: && backupdir="$(am__leading_dot)am$$$$" && \
+ $(AM_V_MAKEINFO)restore=: && backupdir="$(am__leading_dot)am$$$$" && \
am__cwd=`pwd` && $(am__cd) $(srcdir) && \
rm -rf $$backupdir && mkdir $$backupdir && \
if ($(MAKEINFO) --version) >/dev/null 2>&1; then \
@@ -335,27 +436,25 @@ $(am__aclocal_m4_deps):
rm -rf $$backupdir; exit $$rc
.texi.dvi:
- TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ $(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
- $(TEXI2DVI) $<
+ $(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \
+ $<
.texi.pdf:
- TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ $(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
- $(TEXI2PDF) $<
+ $(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \
+ $<
.texi.html:
- rm -rf $(@:.html=.htp)
- if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ $(AM_V_MAKEINFO)rm -rf $(@:.html=.htp)
+ $(AM_V_at)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; \
+ rm -rf $@ && mv $(@:.html=.htp) $@; \
else \
- if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
- rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
- exit 1; \
+ rm -rf $(@:.html=.htp); exit 1; \
fi
$(srcdir)/gawk.info: gawk.texi
gawk.dvi: gawk.texi
@@ -366,8 +465,8 @@ gawkinet.dvi: gawkinet.texi
gawkinet.pdf: gawkinet.texi
gawkinet.html: gawkinet.texi
.dvi.ps:
- TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
- $(DVIPS) -o $@ $<
+ $(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ $(DVIPS) $(AM_V_texinfo) -o $@ $<
uninstall-dvi-am:
@$(NORMAL_UNINSTALL)
@@ -389,9 +488,7 @@ uninstall-html-am:
uninstall-info-am:
@$(PRE_UNINSTALL)
- @if test -d '$(DESTDIR)$(infodir)' && \
- (install-info --version && \
- install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+ @if test -d '$(DESTDIR)$(infodir)' && $(am__can_run_installinfo); then \
list='$(INFO_DEPS)'; \
for file in $$list; do \
relfile=`echo "$$file" | sed 's|^.*/||'`; \
@@ -448,12 +545,7 @@ dist-info: $(INFO_DEPS)
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 \
- 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
+ -rm -rf gawk.t2d gawk.t2p gawkinet.t2d gawkinet.t2p
clean-aminfo:
-test -z "gawk.dvi gawk.pdf gawk.ps gawk.html gawkinet.dvi gawkinet.pdf \
@@ -469,11 +561,18 @@ maintainer-clean-aminfo:
done
install-man1: $(man_MANS)
@$(NORMAL_INSTALL)
- test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)"
- @list=''; test -n "$(man1dir)" || exit 0; \
- { for i in $$list; do echo "$$i"; done; \
- l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
- sed -n '/\.1[a-z]*$$/p'; \
+ @list1=''; \
+ list2='$(man_MANS)'; \
+ test -n "$(man1dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.1[a-z]*$$/p'; \
+ fi; \
} | while read p; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; echo "$$p"; \
@@ -502,30 +601,15 @@ uninstall-man1:
sed -n '/\.1[a-z]*$$/p'; \
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
- test -z "$$files" || { \
- echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \
- cd "$(DESTDIR)$(man1dir)" && rm -f $$files; }
-tags: TAGS
-TAGS:
+ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
-ctags: CTAGS
-CTAGS:
+ctags CTAGS:
+
+cscope cscopelist:
distdir: $(DISTFILES)
- @list='$(MANS)'; if test -n "$$list"; then \
- list=`for p in $$list; do \
- if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
- if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
- if test -n "$$list" && \
- grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
- echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
- grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \
- echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \
- echo " typically \`make maintainer-clean' will remove them" >&2; \
- exit 1; \
- else :; fi; \
- else :; fi
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
@@ -575,10 +659,15 @@ install-am: all-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
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
mostlyclean-generic:
clean-generic:
@@ -612,14 +701,16 @@ info: info-am
info-am: $(INFO_DEPS)
install-data-am: install-info-am install-man
- @$(NORMAL_INSTALL)
- $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+
install-dvi: install-dvi-am
install-dvi-am: $(DVIS)
@$(NORMAL_INSTALL)
- test -z "$(dvidir)" || $(MKDIR_P) "$(DESTDIR)$(dvidir)"
@list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(dvidir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(dvidir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
@@ -634,18 +725,22 @@ install-html: install-html-am
install-html-am: $(HTMLS)
@$(NORMAL_INSTALL)
- test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)"
@list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \
$(am__strip_dir) \
- if test -d "$$d$$p"; then \
+ d2=$$d$$p; \
+ if test -d "$$d2"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \
$(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \
- echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \
- $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \
+ echo " $(INSTALL_DATA) '$$d2'/* '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(INSTALL_DATA) "$$d2"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \
else \
- list2="$$list2 $$d$$p"; \
+ list2="$$list2 $$d2"; \
fi; \
done; \
test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \
@@ -657,9 +752,12 @@ 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)'; test -n "$(infodir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(infodir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(infodir)" || exit 1; \
+ fi; \
for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
@@ -677,8 +775,7 @@ install-info-am: $(INFO_DEPS)
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done
@$(POST_INSTALL)
- @if (install-info --version && \
- install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+ @if $(am__can_run_installinfo); then \
list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
for file in $$list; do \
relfile=`echo "$$file" | sed 's|^.*/||'`; \
@@ -692,8 +789,11 @@ install-pdf: install-pdf-am
install-pdf-am: $(PDFS)
@$(NORMAL_INSTALL)
- test -z "$(pdfdir)" || $(MKDIR_P) "$(DESTDIR)$(pdfdir)"
@list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pdfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pdfdir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
@@ -705,8 +805,11 @@ install-ps: install-ps-am
install-ps-am: $(PSS)
@$(NORMAL_INSTALL)
- test -z "$(psdir)" || $(MKDIR_P) "$(DESTDIR)$(psdir)"
@list='$(PSS)'; test -n "$(psdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(psdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(psdir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
@@ -733,47 +836,45 @@ ps-am: $(PSS)
uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \
uninstall-man uninstall-pdf-am uninstall-ps-am
- @$(NORMAL_INSTALL)
- $(MAKE) $(AM_MAKEFLAGS) uninstall-hook
+
uninstall-man: uninstall-man1
-.MAKE: install-am install-data-am install-strip uninstall-am
+.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-aminfo 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-dvi install-dvi-am \
- install-exec install-exec-am install-html install-html-am \
- install-info install-info-am install-man install-man1 \
- install-pdf install-pdf-am install-ps install-ps-am \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-aminfo \
+ cscopelist-am ctags-am dist-info distclean distclean-generic \
+ distdir dvi dvi-am html html-am info info-am install \
+ install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-man1 install-pdf install-pdf-am install-ps \
+ install-ps-am 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-dvi-am uninstall-hook uninstall-html-am \
+ mostlyclean-generic pdf pdf-am ps ps-am tags-am uninstall \
+ uninstall-am uninstall-dvi-am uninstall-html-am \
uninstall-info-am uninstall-man uninstall-man1 \
uninstall-pdf-am uninstall-ps-am
-# Link gawk.1 to pgawk.1
-install-data-hook:
- (cd $(DESTDIR)$(man1dir); \
- $(LN) gawk.1 pgawk.1 2>/dev/null ; \
- exit 0)
+# 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
-# Undo the above when uninstalling
-uninstall-hook:
- cd $(DESTDIR)$(man1dir); rm -f pgawk.1 ; exit 0
+gawk.texi: $(srcdir)/gawktexi.in $(srcdir)/sidebar.awk
+ awk -f $(srcdir)/sidebar.awk < $(srcdir)/gawktexi.in > gawk.texi
-postscript: gawk.ps gawkinet.ps gawk.1.ps igawk.1.ps $(AWKCARD)
+postscript: gawk.ps gawkinet.ps gawk.1.ps $(AWKCARD)
-pdf: postscript gawk.pdf gawkinet.pdf awkcard.pdf gawk.1.pdf igawk.1.pdf
+pdf: postscript gawk.pdf gawkinet.pdf awkcard.pdf gawk.1.pdf
gawk.ps: gawk.dvi
- dvips -o gawk.ps gawk.dvi
+ TEXINPUTS=$(srcdir): dvips -o gawk.ps gawk.dvi
gawkinet.ps: gawkinet.dvi
- dvips -o gawkinet.ps gawkinet.dvi
+ TEXINPUTS=$(srcdir): dvips -o gawkinet.ps gawkinet.dvi
gawk.1.ps: gawk.1
-groff -man $(srcdir)/gawk.1 > gawk.1.ps
@@ -781,12 +882,6 @@ gawk.1.ps: gawk.1
gawk.1.pdf: gawk.1.ps
ps2pdf gawk.1.ps gawk.1.pdf
-igawk.1.ps: igawk.1
- -groff -man $(srcdir)/igawk.1 > igawk.1.ps
-
-igawk.1.pdf: igawk.1.ps
- ps2pdf igawk.1.ps igawk.1.pdf
-
awkcard.tr: awkcard.in
sed 's:SRCDIR:$(srcdir):' < $(srcdir)/awkcard.in > awkcard.tr
diff --git a/doc/api-figure1.eps b/doc/api-figure1.eps
new file mode 100644
index 00000000..7af094c9
--- /dev/null
+++ b/doc/api-figure1.eps
@@ -0,0 +1,536 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Title: api-figure1.fig
+%%Creator: fig2dev Version 3.2 Patchlevel 5d
+%%CreationDate: Wed Oct 31 20:16:08 2012
+%%BoundingBox: 0 0 399 227
+%Magnification: 1.0000
+%%EndComments
+%%BeginProlog
+/MyAppDict 100 dict dup begin def
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+
+% This junk string is used by the show operators
+/PATsstr 1 string def
+/PATawidthshow { % cx cy cchar rx ry string
+ % Loop over each character in the string
+ { % cx cy cchar rx ry char
+ % Show the character
+ dup % cx cy cchar rx ry char char
+ PATsstr dup 0 4 -1 roll put % cx cy cchar rx ry char (char)
+ false charpath % cx cy cchar rx ry char
+ /clip load PATdraw
+ % Move past the character (charpath modified the
+ % current point)
+ currentpoint % cx cy cchar rx ry char x y
+ newpath
+ moveto % cx cy cchar rx ry char
+ % Reposition by cx,cy if the character in the string is cchar
+ 3 index eq { % cx cy cchar rx ry
+ 4 index 4 index rmoveto
+ } if
+ % Reposition all characters by rx ry
+ 2 copy rmoveto % cx cy cchar rx ry
+ } forall
+ pop pop pop pop pop % -
+ currentpoint
+ newpath
+ moveto
+} bind def
+/PATcg {
+ 7 dict dup begin
+ /lw currentlinewidth def
+ /lc currentlinecap def
+ /lj currentlinejoin def
+ /ml currentmiterlimit def
+ /ds [ currentdash ] def
+ /cc [ currentrgbcolor ] def
+ /cm matrix currentmatrix def
+ end
+} bind def
+% PATdraw - calculates the boundaries of the object and
+% fills it with the current pattern
+/PATdraw { % proc
+ save exch
+ PATpcalc % proc nw nh px py
+ 5 -1 roll exec % nw nh px py
+ newpath
+ PATfill % -
+ restore
+} bind def
+% PATfill - performs the tiling for the shape
+/PATfill { % nw nh px py PATfill -
+ PATDict /CurrentPattern get dup begin
+ setfont
+ % Set the coordinate system to Pattern Space
+ PatternGState PATsg
+ % Set the color for uncolored pattezns
+ PaintType 2 eq { PATDict /PColor get PATsc } if
+ % Create the string for showing
+ 3 index string % nw nh px py str
+ % Loop for each of the pattern sources
+ 0 1 Multi 1 sub { % nw nh px py str source
+ % Move to the starting location
+ 3 index 3 index % nw nh px py str source px py
+ moveto % nw nh px py str source
+ % For multiple sources, set the appropriate color
+ Multi 1 ne { dup PC exch get PATsc } if
+ % Set the appropriate string for the source
+ 0 1 7 index 1 sub { 2 index exch 2 index put } for pop
+ % Loop over the number of vertical cells
+ 3 index % nw nh px py str nh
+ { % nw nh px py str
+ currentpoint % nw nh px py str cx cy
+ 2 index oldshow % nw nh px py str cx cy
+ YStep add moveto % nw nh px py str
+ } repeat % nw nh px py str
+ } for
+ 5 { pop } repeat
+ end
+} bind def
+
+% PATkshow - kshow with the current pattezn
+/PATkshow { % proc string
+ exch bind % string proc
+ 1 index 0 get % string proc char
+ % Loop over all but the last character in the string
+ 0 1 4 index length 2 sub {
+ % string proc char idx
+ % Find the n+1th character in the string
+ 3 index exch 1 add get % string proc char char+1
+ exch 2 copy % strinq proc char+1 char char+1 char
+ % Now show the nth character
+ PATsstr dup 0 4 -1 roll put % string proc chr+1 chr chr+1 (chr)
+ false charpath % string proc char+1 char char+1
+ /clip load PATdraw
+ % Move past the character (charpath modified the current point)
+ currentpoint newpath moveto
+ % Execute the user proc (should consume char and char+1)
+ mark 3 1 roll % string proc char+1 mark char char+1
+ 4 index exec % string proc char+1 mark...
+ cleartomark % string proc char+1
+ } for
+ % Now display the last character
+ PATsstr dup 0 4 -1 roll put % string proc (char+1)
+ false charpath % string proc
+ /clip load PATdraw
+ neewath
+ pop pop % -
+} bind def
+% PATmp - the makepattern equivalent
+/PATmp { % patdict patmtx PATmp patinstance
+ exch dup length 7 add % We will add 6 new entries plus 1 FID
+ dict copy % Create a new dictionary
+ begin
+ % Matrix to install when painting the pattern
+ TilingType PATtcalc
+ /PatternGState PATcg def
+ PatternGState /cm 3 -1 roll put
+ % Check for multi pattern sources (Level 1 fast color patterns)
+ currentdict /Multi known not { /Multi 1 def } if
+ % Font dictionary definitions
+ /FontType 3 def
+ % Create a dummy encoding vector
+ /Encoding 256 array def
+ 3 string 0 1 255 {
+ Encoding exch dup 3 index cvs cvn put } for pop
+ /FontMatrix matrix def
+ /FontBBox BBox def
+ /BuildChar {
+ mark 3 1 roll % mark dict char
+ exch begin
+ Multi 1 ne {PaintData exch get}{pop} ifelse % mark [paintdata]
+ PaintType 2 eq Multi 1 ne or
+ { XStep 0 FontBBox aload pop setcachedevice }
+ { XStep 0 setcharwidth } ifelse
+ currentdict % mark [paintdata] dict
+ /PaintProc load % mark [paintdata] dict paintproc
+ end
+ gsave
+ false PATredef exec true PATredef
+ grestore
+ cleartomark % -
+ } bind def
+ currentdict
+ end % newdict
+ /foo exch % /foo newlict
+ definefont % newfont
+} bind def
+% PATpcalc - calculates the starting point and width/height
+% of the tile fill for the shape
+/PATpcalc { % - PATpcalc nw nh px py
+ PATDict /CurrentPattern get begin
+ gsave
+ % Set up the coordinate system to Pattern Space
+ % and lock down pattern
+ PatternGState /cm get setmatrix
+ BBox aload pop pop pop translate
+ % Determine the bounding box of the shape
+ pathbbox % llx lly urx ury
+ grestore
+ % Determine (nw, nh) the # of cells to paint width and height
+ PatHeight div ceiling % llx lly urx qh
+ 4 1 roll % qh llx lly urx
+ PatWidth div ceiling % qh llx lly qw
+ 4 1 roll % qw qh llx lly
+ PatHeight div floor % qw qh llx ph
+ 4 1 roll % ph qw qh llx
+ PatWidth div floor % ph qw qh pw
+ 4 1 roll % pw ph qw qh
+ 2 index sub cvi abs % pw ph qs qh-ph
+ exch 3 index sub cvi abs exch % pw ph nw=qw-pw nh=qh-ph
+ % Determine the starting point of the pattern fill
+ %(px, py)
+ 4 2 roll % nw nh pw ph
+ PatHeight mul % nw nh pw py
+ exch % nw nh py pw
+ PatWidth mul exch % nw nh px py
+ end
+} bind def
+
+% Save the original routines so that we can use them later on
+/oldfill /fill load def
+/oldeofill /eofill load def
+/oldstroke /stroke load def
+/oldshow /show load def
+/oldashow /ashow load def
+/oldwidthshow /widthshow load def
+/oldawidthshow /awidthshow load def
+/oldkshow /kshow load def
+
+% These defs are necessary so that subsequent procs don't bind in
+% the originals
+/fill { oldfill } bind def
+/eofill { oldeofill } bind def
+/stroke { oldstroke } bind def
+/show { oldshow } bind def
+/ashow { oldashow } bind def
+/widthshow { oldwidthshow } bind def
+/awidthshow { oldawidthshow } bind def
+/kshow { oldkshow } bind def
+/PATredef {
+ MyAppDict begin
+ {
+ /fill { /clip load PATdraw newpath } bind def
+ /eofill { /eoclip load PATdraw newpath } bind def
+ /stroke { PATstroke } bind def
+ /show { 0 0 null 0 0 6 -1 roll PATawidthshow } bind def
+ /ashow { 0 0 null 6 3 roll PATawidthshow }
+ bind def
+ /widthshow { 0 0 3 -1 roll PATawidthshow }
+ bind def
+ /awidthshow { PATawidthshow } bind def
+ /kshow { PATkshow } bind def
+ } {
+ /fill { oldfill } bind def
+ /eofill { oldeofill } bind def
+ /stroke { oldstroke } bind def
+ /show { oldshow } bind def
+ /ashow { oldashow } bind def
+ /widthshow { oldwidthshow } bind def
+ /awidthshow { oldawidthshow } bind def
+ /kshow { oldkshow } bind def
+ } ifelse
+ end
+} bind def
+false PATredef
+% Conditionally define setcmykcolor if not available
+/setcmykcolor where { pop } {
+ /setcmykcolor {
+ 1 sub 4 1 roll
+ 3 {
+ 3 index add neg dup 0 lt { pop 0 } if 3 1 roll
+ } repeat
+ setrgbcolor - pop
+ } bind def
+} ifelse
+/PATsc { % colorarray
+ aload length % c1 ... cn length
+ dup 1 eq { pop setgray } { 3 eq { setrgbcolor } { setcmykcolor
+ } ifelse } ifelse
+} bind def
+/PATsg { % dict
+ begin
+ lw setlinewidth
+ lc setlinecap
+ lj setlinejoin
+ ml setmiterlimit
+ ds aload pop setdash
+ cc aload pop setrgbcolor
+ cm setmatrix
+ end
+} bind def
+
+/PATDict 3 dict def
+/PATsp {
+ true PATredef
+ PATDict begin
+ /CurrentPattern exch def
+ % If it's an uncolored pattern, save the color
+ CurrentPattern /PaintType get 2 eq {
+ /PColor exch def
+ } if
+ /CColor [ currentrgbcolor ] def
+ end
+} bind def
+% PATstroke - stroke with the current pattern
+/PATstroke {
+ countdictstack
+ save
+ mark
+ {
+ currentpoint strokepath moveto
+ PATpcalc % proc nw nh px py
+ clip newpath PATfill
+ } stopped {
+ (*** PATstroke Warning: Path is too complex, stroking
+ with gray) =
+ cleartomark
+ restore
+ countdictstack exch sub dup 0 gt
+ { { end } repeat } { pop } ifelse
+ gsave 0.5 setgray oldstroke grestore
+ } { pop restore pop } ifelse
+ newpath
+} bind def
+/PATtcalc { % modmtx tilingtype PATtcalc tilematrix
+ % Note: tiling types 2 and 3 are not supported
+ gsave
+ exch concat % tilingtype
+ matrix currentmatrix exch % cmtx tilingtype
+ % Tiling type 1 and 3: constant spacing
+ 2 ne {
+ % Distort the pattern so that it occupies
+ % an integral number of device pixels
+ dup 4 get exch dup 5 get exch % tx ty cmtx
+ XStep 0 dtransform
+ round exch round exch % tx ty cmtx dx.x dx.y
+ XStep div exch XStep div exch % tx ty cmtx a b
+ 0 YStep dtransform
+ round exch round exch % tx ty cmtx a b dy.x dy.y
+ YStep div exch YStep div exch % tx ty cmtx a b c d
+ 7 -3 roll astore % { a b c d tx ty }
+ } if
+ grestore
+} bind def
+/PATusp {
+ false PATredef
+ PATDict begin
+ CColor PATsc
+ end
+} bind def
+
+% right30
+11 dict begin
+/PaintType 1 def
+/PatternType 1 def
+/TilingType 1 def
+/BBox [0 0 1 1] def
+/XStep 1 def
+/YStep 1 def
+/PatWidth 1 def
+/PatHeight 1 def
+/Multi 2 def
+/PaintData [
+ { clippath } bind
+ { 32 16 true [ 32 0 0 -16 0 16 ]
+ {<00030003000c000c0030003000c000c0030003000c000c00
+ 30003000c000c00000030003000c000c0030003000c000c0
+ 030003000c000c0030003000c000c000>}
+ imagemask } bind
+] def
+/PaintProc {
+ pop
+ exec fill
+} def
+currentdict
+end
+/P2 exch def
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+/pageheader {
+save
+newpath 0 227 moveto 0 0 lineto 399 0 lineto 399 227 lineto closepath clip newpath
+-194.8 350.2 translate
+1 -1 scale
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+} bind def
+/pagefooter {
+$F2psEnd
+restore
+} bind def
+%%EndProlog
+pageheader
+%
+% Fig objects follow
+%
+%
+% here starts figure with depth 50
+% Arc
+7.500 slw
+0 slc
+gs clippath
+3599 4000 m 3567 4148 l 3626 4161 l 3658 4013 l 3658 4013 l 3603 4124 l 3599 4000 l cp
+eoclip
+n 5449.3 4471.5 1878.7 -70.5453 -169.8379 arcn
+gs col0 s gr
+ gr
+
+% arrowhead
+0 slj
+n 3599 4000 m 3603 4124 l 3658 4013 l 3599 4000 l cp gs 0.00 setgray ef gr col0 s
+% Arc
+gs clippath
+4422 4004 m 4425 4155 l 4485 4154 l 4482 4003 l 4482 4003 l 4455 4124 l 4422 4004 l cp
+eoclip
+n 5539.0 4051.3 1087.6 -60.4713 175.3232 arcn
+gs col0 s gr
+ gr
+
+% arrowhead
+n 4422 4004 m 4455 4124 l 4482 4003 l 4422 4004 l cp gs 0.00 setgray ef gr col0 s
+% Arc
+gs clippath
+4986 4010 m 5012 4159 l 5072 4149 l 5046 4000 l 5046 4000 l 5037 4124 l 4986 4010 l cp
+eoclip
+n 5628.8 3967.5 613.5 -36.7999 163.6698 arcn
+gs col0 s gr
+ gr
+
+% arrowhead
+n 4986 4010 m 5037 4124 l 5046 4000 l 4986 4010 l cp gs 0.00 setgray ef gr col0 s
+% Arc
+135.000 slw
+gs clippath
+7736 3835 m 7756 3984 l 7907 3964 l 7887 3814 l 7841 3821 l 7828 3944 l 7782 3829 l cp
+eoclip
+n 6609.1 4056.9 1224.8 -93.9364 -4.5364 arc
+gs col0 s gr
+ gr
+
+% arrowhead
+7.500 slw
+n 7782 3829 m 7828 3944 l 7841 3821 l col0 s
+% Polyline
+n 3105 4140 m 6660 4140 l 6660 5085 l 3105 5085 l
+ cp gs col0 s gr
+% Polyline
+n 6660 4140 m 8730 4140 l 8730 5085 l 6660 5085 l
+ cp gs col7 0.50 shd ef gr gs col0 s gr
+% Polyline
+n 5805 2610 m 6345 2610 l 6345 3690 l 5805 3690 l
+ cp gs col0 s gr
+% Polyline
+n 5805 2835 m 6345 2835 l 6345 3015 l 5805 3015 l
+ cp gs col0 s gr
+% Polyline
+n 5805 3195 m 6345 3195 l 6345 3375 l 5805 3375 l
+ cp gs col0 s gr
+% Polyline
+n 5805 3510 m 6345 3510 l 6345 3690 l 5805 3690 l
+ cp gs col0 s gr
+% Polyline
+n 3510 4140 m 3780 4140 l 3780 5085 l 3510 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 234.00 276.00] PATmp PATsp ef gr PATusp gs col0 s gr
+% Polyline
+n 4365 4140 m 4635 4140 l 4635 5085 l 4365 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 291.00 276.00] PATmp PATsp ef gr PATusp gs col0 s gr
+% Polyline
+n 4905 4140 m 5265 4140 l 5265 5085 l 4905 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 327.00 276.00] PATmp PATsp ef gr PATusp gs col0 s gr
+/Times-Roman ff 180.00 scf sf
+3510 5490 m
+gs 1 -1 sc (gawk Main Program Address Space) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+7290 5490 m
+gs 1 -1 sc (Extension) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+5985 2115 m
+gs 1 -1 sc (API) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+5895 2340 m
+gs 1 -1 sc (Struct) col0 sh gr
+/Courier-Bold ff 180.00 scf sf
+7065 2655 m
+gs 1 -1 sc (dl_load\(api_p, id\);) col0 sh gr
+% here ends figure;
+pagefooter
+showpage
+%%Trailer
+end
+%EOF
diff --git a/doc/api-figure1.fig b/doc/api-figure1.fig
new file mode 100644
index 00000000..7bc47846
--- /dev/null
+++ b/doc/api-figure1.fig
@@ -0,0 +1,40 @@
+#FIG 3.2 Produced by xfig version 3.2.5b
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+5 1 0 1 0 7 50 -1 -1 0.000 0 1 1 0 5449.265 4471.471 6075 2700 4320 2970 3600 4140
+ 1 1 1.00 60.00 120.00
+5 1 0 1 0 7 50 -1 -1 0.000 0 1 1 0 5538.971 4051.323 6075 3105 4725 3330 4455 4140
+ 1 1 1.00 60.00 120.00
+5 1 0 1 0 7 50 -1 -1 0.000 0 1 1 0 5628.750 3967.500 6120 3600 5220 3510 5040 4140
+ 1 1 1.00 60.00 120.00
+5 1 0 10 0 7 50 -1 -1 0.000 0 0 1 0 6609.079 4056.868 6525 2835 7560 3285 7830 3960
+ 0 0 1.00 60.00 120.00
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 3105 4140 6660 4140 6660 5085 3105 5085 3105 4140
+2 2 0 1 0 7 50 -1 10 0.000 0 0 -1 0 0 5
+ 6660 4140 8730 4140 8730 5085 6660 5085 6660 4140
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 5805 2610 6345 2610 6345 3690 5805 3690 5805 2610
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 5805 2835 6345 2835 6345 3015 5805 3015 5805 2835
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 5805 3195 6345 3195 6345 3375 5805 3375 5805 3195
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 5805 3510 6345 3510 6345 3690 5805 3690 5805 3510
+2 2 0 1 0 7 50 -1 42 0.000 0 0 -1 0 0 5
+ 3510 4140 3780 4140 3780 5085 3510 5085 3510 4140
+2 2 0 1 0 7 50 -1 42 0.000 0 0 -1 0 0 5
+ 4365 4140 4635 4140 4635 5085 4365 5085 4365 4140
+2 2 0 1 0 7 50 -1 42 0.000 0 0 -1 0 0 5
+ 4905 4140 5265 4140 5265 5085 4905 5085 4905 4140
+4 0 0 50 -1 0 12 0.0000 4 180 2850 3510 5490 gawk Main Program Address Space\001
+4 0 0 50 -1 0 12 0.0000 4 135 825 7290 5490 Extension\001
+4 0 0 50 -1 0 12 0.0000 4 135 300 5985 2115 API\001
+4 0 0 50 -1 0 12 0.0000 4 135 480 5895 2340 Struct\001
+4 0 0 50 -1 14 12 0.0000 4 165 2280 7065 2655 dl_load(api_p, id);\001
diff --git a/doc/api-figure1.pdf b/doc/api-figure1.pdf
new file mode 100644
index 00000000..0c24b67d
--- /dev/null
+++ b/doc/api-figure1.pdf
Binary files differ
diff --git a/doc/api-figure1.png b/doc/api-figure1.png
new file mode 100644
index 00000000..72d552cd
--- /dev/null
+++ b/doc/api-figure1.png
Binary files differ
diff --git a/doc/api-figure1.txt b/doc/api-figure1.txt
new file mode 100644
index 00000000..686b853b
--- /dev/null
+++ b/doc/api-figure1.txt
@@ -0,0 +1,24 @@
+ API
+ Struct
+ +---+
+ | |
+ +---+
+ +---------------| |
+ | +---+ dl_load(api_p, id);
+ | | | ___________________
+ | +---+ |
+ | +---------| | __________________ |
+ | | +---+ ||
+ | | | | ||
+ | | +---+ ||
+ | | +---| | ||
+ | | | +---+ \ || /
+ | | | \ /
+ v v v \/
++-------+-+---+-+---+-+------------------+--------------------+
+| |x| |x| |x| |OOOOOOOOOOOOOOOOOOOO|
+| |x| |x| |x| |OOOOOOOOOOOOOOOOOOOO|
+| |x| |x| |x| |OOOOOOOOOOOOOOOOOOOO|
++-------+-+---+-+---+-+------------------+--------------------+
+
+ gawk Main Program Address Space Extension
diff --git a/doc/api-figure2.eps b/doc/api-figure2.eps
new file mode 100644
index 00000000..caf5c34c
--- /dev/null
+++ b/doc/api-figure2.eps
@@ -0,0 +1,517 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Title: api-figure2.fig
+%%Creator: fig2dev Version 3.2 Patchlevel 5d
+%%CreationDate: Thu Apr 25 22:22:07 2013
+%%BoundingBox: 0 0 363 179
+%Magnification: 1.0000
+%%EndComments
+%%BeginProlog
+/MyAppDict 100 dict dup begin def
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+
+% This junk string is used by the show operators
+/PATsstr 1 string def
+/PATawidthshow { % cx cy cchar rx ry string
+ % Loop over each character in the string
+ { % cx cy cchar rx ry char
+ % Show the character
+ dup % cx cy cchar rx ry char char
+ PATsstr dup 0 4 -1 roll put % cx cy cchar rx ry char (char)
+ false charpath % cx cy cchar rx ry char
+ /clip load PATdraw
+ % Move past the character (charpath modified the
+ % current point)
+ currentpoint % cx cy cchar rx ry char x y
+ newpath
+ moveto % cx cy cchar rx ry char
+ % Reposition by cx,cy if the character in the string is cchar
+ 3 index eq { % cx cy cchar rx ry
+ 4 index 4 index rmoveto
+ } if
+ % Reposition all characters by rx ry
+ 2 copy rmoveto % cx cy cchar rx ry
+ } forall
+ pop pop pop pop pop % -
+ currentpoint
+ newpath
+ moveto
+} bind def
+/PATcg {
+ 7 dict dup begin
+ /lw currentlinewidth def
+ /lc currentlinecap def
+ /lj currentlinejoin def
+ /ml currentmiterlimit def
+ /ds [ currentdash ] def
+ /cc [ currentrgbcolor ] def
+ /cm matrix currentmatrix def
+ end
+} bind def
+% PATdraw - calculates the boundaries of the object and
+% fills it with the current pattern
+/PATdraw { % proc
+ save exch
+ PATpcalc % proc nw nh px py
+ 5 -1 roll exec % nw nh px py
+ newpath
+ PATfill % -
+ restore
+} bind def
+% PATfill - performs the tiling for the shape
+/PATfill { % nw nh px py PATfill -
+ PATDict /CurrentPattern get dup begin
+ setfont
+ % Set the coordinate system to Pattern Space
+ PatternGState PATsg
+ % Set the color for uncolored pattezns
+ PaintType 2 eq { PATDict /PColor get PATsc } if
+ % Create the string for showing
+ 3 index string % nw nh px py str
+ % Loop for each of the pattern sources
+ 0 1 Multi 1 sub { % nw nh px py str source
+ % Move to the starting location
+ 3 index 3 index % nw nh px py str source px py
+ moveto % nw nh px py str source
+ % For multiple sources, set the appropriate color
+ Multi 1 ne { dup PC exch get PATsc } if
+ % Set the appropriate string for the source
+ 0 1 7 index 1 sub { 2 index exch 2 index put } for pop
+ % Loop over the number of vertical cells
+ 3 index % nw nh px py str nh
+ { % nw nh px py str
+ currentpoint % nw nh px py str cx cy
+ 2 index oldshow % nw nh px py str cx cy
+ YStep add moveto % nw nh px py str
+ } repeat % nw nh px py str
+ } for
+ 5 { pop } repeat
+ end
+} bind def
+
+% PATkshow - kshow with the current pattezn
+/PATkshow { % proc string
+ exch bind % string proc
+ 1 index 0 get % string proc char
+ % Loop over all but the last character in the string
+ 0 1 4 index length 2 sub {
+ % string proc char idx
+ % Find the n+1th character in the string
+ 3 index exch 1 add get % string proc char char+1
+ exch 2 copy % strinq proc char+1 char char+1 char
+ % Now show the nth character
+ PATsstr dup 0 4 -1 roll put % string proc chr+1 chr chr+1 (chr)
+ false charpath % string proc char+1 char char+1
+ /clip load PATdraw
+ % Move past the character (charpath modified the current point)
+ currentpoint newpath moveto
+ % Execute the user proc (should consume char and char+1)
+ mark 3 1 roll % string proc char+1 mark char char+1
+ 4 index exec % string proc char+1 mark...
+ cleartomark % string proc char+1
+ } for
+ % Now display the last character
+ PATsstr dup 0 4 -1 roll put % string proc (char+1)
+ false charpath % string proc
+ /clip load PATdraw
+ neewath
+ pop pop % -
+} bind def
+% PATmp - the makepattern equivalent
+/PATmp { % patdict patmtx PATmp patinstance
+ exch dup length 7 add % We will add 6 new entries plus 1 FID
+ dict copy % Create a new dictionary
+ begin
+ % Matrix to install when painting the pattern
+ TilingType PATtcalc
+ /PatternGState PATcg def
+ PatternGState /cm 3 -1 roll put
+ % Check for multi pattern sources (Level 1 fast color patterns)
+ currentdict /Multi known not { /Multi 1 def } if
+ % Font dictionary definitions
+ /FontType 3 def
+ % Create a dummy encoding vector
+ /Encoding 256 array def
+ 3 string 0 1 255 {
+ Encoding exch dup 3 index cvs cvn put } for pop
+ /FontMatrix matrix def
+ /FontBBox BBox def
+ /BuildChar {
+ mark 3 1 roll % mark dict char
+ exch begin
+ Multi 1 ne {PaintData exch get}{pop} ifelse % mark [paintdata]
+ PaintType 2 eq Multi 1 ne or
+ { XStep 0 FontBBox aload pop setcachedevice }
+ { XStep 0 setcharwidth } ifelse
+ currentdict % mark [paintdata] dict
+ /PaintProc load % mark [paintdata] dict paintproc
+ end
+ gsave
+ false PATredef exec true PATredef
+ grestore
+ cleartomark % -
+ } bind def
+ currentdict
+ end % newdict
+ /foo exch % /foo newlict
+ definefont % newfont
+} bind def
+% PATpcalc - calculates the starting point and width/height
+% of the tile fill for the shape
+/PATpcalc { % - PATpcalc nw nh px py
+ PATDict /CurrentPattern get begin
+ gsave
+ % Set up the coordinate system to Pattern Space
+ % and lock down pattern
+ PatternGState /cm get setmatrix
+ BBox aload pop pop pop translate
+ % Determine the bounding box of the shape
+ pathbbox % llx lly urx ury
+ grestore
+ % Determine (nw, nh) the # of cells to paint width and height
+ PatHeight div ceiling % llx lly urx qh
+ 4 1 roll % qh llx lly urx
+ PatWidth div ceiling % qh llx lly qw
+ 4 1 roll % qw qh llx lly
+ PatHeight div floor % qw qh llx ph
+ 4 1 roll % ph qw qh llx
+ PatWidth div floor % ph qw qh pw
+ 4 1 roll % pw ph qw qh
+ 2 index sub cvi abs % pw ph qs qh-ph
+ exch 3 index sub cvi abs exch % pw ph nw=qw-pw nh=qh-ph
+ % Determine the starting point of the pattern fill
+ %(px, py)
+ 4 2 roll % nw nh pw ph
+ PatHeight mul % nw nh pw py
+ exch % nw nh py pw
+ PatWidth mul exch % nw nh px py
+ end
+} bind def
+
+% Save the original routines so that we can use them later on
+/oldfill /fill load def
+/oldeofill /eofill load def
+/oldstroke /stroke load def
+/oldshow /show load def
+/oldashow /ashow load def
+/oldwidthshow /widthshow load def
+/oldawidthshow /awidthshow load def
+/oldkshow /kshow load def
+
+% These defs are necessary so that subsequent procs don't bind in
+% the originals
+/fill { oldfill } bind def
+/eofill { oldeofill } bind def
+/stroke { oldstroke } bind def
+/show { oldshow } bind def
+/ashow { oldashow } bind def
+/widthshow { oldwidthshow } bind def
+/awidthshow { oldawidthshow } bind def
+/kshow { oldkshow } bind def
+/PATredef {
+ MyAppDict begin
+ {
+ /fill { /clip load PATdraw newpath } bind def
+ /eofill { /eoclip load PATdraw newpath } bind def
+ /stroke { PATstroke } bind def
+ /show { 0 0 null 0 0 6 -1 roll PATawidthshow } bind def
+ /ashow { 0 0 null 6 3 roll PATawidthshow }
+ bind def
+ /widthshow { 0 0 3 -1 roll PATawidthshow }
+ bind def
+ /awidthshow { PATawidthshow } bind def
+ /kshow { PATkshow } bind def
+ } {
+ /fill { oldfill } bind def
+ /eofill { oldeofill } bind def
+ /stroke { oldstroke } bind def
+ /show { oldshow } bind def
+ /ashow { oldashow } bind def
+ /widthshow { oldwidthshow } bind def
+ /awidthshow { oldawidthshow } bind def
+ /kshow { oldkshow } bind def
+ } ifelse
+ end
+} bind def
+false PATredef
+% Conditionally define setcmykcolor if not available
+/setcmykcolor where { pop } {
+ /setcmykcolor {
+ 1 sub 4 1 roll
+ 3 {
+ 3 index add neg dup 0 lt { pop 0 } if 3 1 roll
+ } repeat
+ setrgbcolor - pop
+ } bind def
+} ifelse
+/PATsc { % colorarray
+ aload length % c1 ... cn length
+ dup 1 eq { pop setgray } { 3 eq { setrgbcolor } { setcmykcolor
+ } ifelse } ifelse
+} bind def
+/PATsg { % dict
+ begin
+ lw setlinewidth
+ lc setlinecap
+ lj setlinejoin
+ ml setmiterlimit
+ ds aload pop setdash
+ cc aload pop setrgbcolor
+ cm setmatrix
+ end
+} bind def
+
+/PATDict 3 dict def
+/PATsp {
+ true PATredef
+ PATDict begin
+ /CurrentPattern exch def
+ % If it's an uncolored pattern, save the color
+ CurrentPattern /PaintType get 2 eq {
+ /PColor exch def
+ } if
+ /CColor [ currentrgbcolor ] def
+ end
+} bind def
+% PATstroke - stroke with the current pattern
+/PATstroke {
+ countdictstack
+ save
+ mark
+ {
+ currentpoint strokepath moveto
+ PATpcalc % proc nw nh px py
+ clip newpath PATfill
+ } stopped {
+ (*** PATstroke Warning: Path is too complex, stroking
+ with gray) =
+ cleartomark
+ restore
+ countdictstack exch sub dup 0 gt
+ { { end } repeat } { pop } ifelse
+ gsave 0.5 setgray oldstroke grestore
+ } { pop restore pop } ifelse
+ newpath
+} bind def
+/PATtcalc { % modmtx tilingtype PATtcalc tilematrix
+ % Note: tiling types 2 and 3 are not supported
+ gsave
+ exch concat % tilingtype
+ matrix currentmatrix exch % cmtx tilingtype
+ % Tiling type 1 and 3: constant spacing
+ 2 ne {
+ % Distort the pattern so that it occupies
+ % an integral number of device pixels
+ dup 4 get exch dup 5 get exch % tx ty cmtx
+ XStep 0 dtransform
+ round exch round exch % tx ty cmtx dx.x dx.y
+ XStep div exch XStep div exch % tx ty cmtx a b
+ 0 YStep dtransform
+ round exch round exch % tx ty cmtx a b dy.x dy.y
+ YStep div exch YStep div exch % tx ty cmtx a b c d
+ 7 -3 roll astore % { a b c d tx ty }
+ } if
+ grestore
+} bind def
+/PATusp {
+ false PATredef
+ PATDict begin
+ CColor PATsc
+ end
+} bind def
+
+% right30
+11 dict begin
+/PaintType 1 def
+/PatternType 1 def
+/TilingType 1 def
+/BBox [0 0 1 1] def
+/XStep 1 def
+/YStep 1 def
+/PatWidth 1 def
+/PatHeight 1 def
+/Multi 2 def
+/PaintData [
+ { clippath } bind
+ { 32 16 true [ 32 0 0 -16 0 16 ]
+ {<00030003000c000c0030003000c000c0030003000c000c00
+ 30003000c000c00000030003000c000c0030003000c000c0
+ 030003000c000c0030003000c000c000>}
+ imagemask } bind
+] def
+/PaintProc {
+ pop
+ exec fill
+} def
+currentdict
+end
+/P2 exch def
+
+% crosshatch45
+11 dict begin
+/PaintType 1 def
+/PatternType 1 def
+/TilingType 1 def
+/BBox [0 0 1 1] def
+/XStep 1 def
+/YStep 1 def
+/PatWidth 1 def
+/PatHeight 1 def
+/Multi 2 def
+/PaintData [
+ { clippath } bind
+ { 20 20 true [ 20 0 0 -20 0 20 ]
+ {<8020004050102088201104400a02800401000a02
+ 8011044020882040501080200040501020882011
+ 04400a02800401000a0280110440208820405010>}
+ imagemask } bind
+] def
+/PaintProc {
+ pop
+ exec fill
+} def
+currentdict
+end
+/P6 exch def
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+/pageheader {
+save
+newpath 0 179 moveto 0 0 lineto 363 0 lineto 363 179 lineto closepath clip newpath
+-194.8 350.2 translate
+1 -1 scale
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+} bind def
+/pagefooter {
+$F2psEnd
+restore
+} bind def
+%%EndProlog
+pageheader
+%
+% Fig objects follow
+%
+%
+% here starts figure with depth 50
+% Arc
+7.500 slw
+0 slc
+gs clippath
+3662 4014 m 3567 4132 l 3613 4170 l 3708 4052 l 3708 4052 l 3610 4127 l 3662 4014 l cp
+eoclip
+n 5895.0 5917.5 2902.8 -37.7581 -142.2419 arcn
+gs col0 s gr
+ gr
+
+% arrowhead
+0 slj
+n 3662 4014 m 3610 4127 l 3708 4052 l 3662 4014 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+n 3105 4140 m 6660 4140 l 6660 5085 l 3105 5085 l
+ cp gs col0 s gr
+% Polyline
+n 6660 4140 m 8730 4140 l 8730 5085 l 6660 5085 l
+ cp gs col7 0.50 shd ef gr gs col0 s gr
+% Polyline
+n 3510 4140 m 3780 4140 l 3780 5085 l 3510 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 234.00 276.00] PATmp PATsp ef gr PATusp gs col0 s gr
+% Polyline
+n 4365 4140 m 4635 4140 l 4635 5085 l 4365 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 291.00 276.00] PATmp PATsp ef gr PATusp gs col0 s gr
+% Polyline
+n 4905 4140 m 5265 4140 l 5265 5085 l 4905 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 327.00 276.00] PATmp PATsp ef gr PATusp gs col0 s gr
+% Polyline
+n 7965 4140 m 8370 4140 l 8370 5085 l 7965 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P6 [16 0 0 -16 531.00 276.00] PATmp PATsp ef gr PATusp gs col0 s gr
+/Times-Roman ff 180.00 scf sf
+3510 5490 m
+gs 1 -1 sc (gawk Main Program Address Space) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+7290 5490 m
+gs 1 -1 sc (Extension) col0 sh gr
+/Courier-Bold ff 180.00 scf sf
+3420 2880 m
+gs 1 -1 sc (register_ext_func\({ "chdir", do_chdir, 1 }\);) col0 sh gr
+% here ends figure;
+pagefooter
+showpage
+%%Trailer
+end
+%EOF
diff --git a/doc/api-figure2.fig b/doc/api-figure2.fig
new file mode 100644
index 00000000..2ae60854
--- /dev/null
+++ b/doc/api-figure2.fig
@@ -0,0 +1,26 @@
+#FIG 3.2 Produced by xfig version 3.2.5b
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+5 1 0 1 0 7 50 -1 -1 0.000 0 1 1 0 5895.000 5917.500 8190 4140 5940 3015 3600 4140
+ 1 1 1.00 60.00 120.00
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 3105 4140 6660 4140 6660 5085 3105 5085 3105 4140
+2 2 0 1 0 7 50 -1 10 0.000 0 0 -1 0 0 5
+ 6660 4140 8730 4140 8730 5085 6660 5085 6660 4140
+2 2 0 1 0 7 50 -1 42 0.000 0 0 -1 0 0 5
+ 3510 4140 3780 4140 3780 5085 3510 5085 3510 4140
+2 2 0 1 0 7 50 -1 42 0.000 0 0 -1 0 0 5
+ 4365 4140 4635 4140 4635 5085 4365 5085 4365 4140
+2 2 0 1 0 7 50 -1 42 0.000 0 0 -1 0 0 5
+ 4905 4140 5265 4140 5265 5085 4905 5085 4905 4140
+2 2 0 1 0 7 50 -1 46 0.000 0 0 -1 0 0 5
+ 7965 4140 8370 4140 8370 5085 7965 5085 7965 4140
+4 0 0 50 -1 0 12 0.0000 4 180 2850 3510 5490 gawk Main Program Address Space\001
+4 0 0 50 -1 0 12 0.0000 4 135 825 7290 5490 Extension\001
+4 0 0 50 -1 14 12 0.0000 4 165 5280 3420 2880 register_ext_func({ "chdir", do_chdir, 1 });\001
diff --git a/doc/api-figure2.pdf b/doc/api-figure2.pdf
new file mode 100644
index 00000000..20462856
--- /dev/null
+++ b/doc/api-figure2.pdf
Binary files differ
diff --git a/doc/api-figure2.png b/doc/api-figure2.png
new file mode 100644
index 00000000..a6e28c98
--- /dev/null
+++ b/doc/api-figure2.png
Binary files differ
diff --git a/doc/api-figure2.txt b/doc/api-figure2.txt
new file mode 100644
index 00000000..5ed8e2a8
--- /dev/null
+++ b/doc/api-figure2.txt
@@ -0,0 +1,12 @@
+ register_ext_func({ "chdir", do_chdir, 1 });
+
+ +--------------------------------------------+
+ | |
+ V |
++-------+-+---+-+---+-+------------------+--------------+-+---+
+| |x| |x| |x| |OOOOOOOOOOOOOO|X|OOO|
+| |x| |x| |x| |OOOOOOOOOOOOOO|X|OOO|
+| |x| |x| |x| |OOOOOOOOOOOOOO|X|OOO|
++-------+-+---+-+---+-+------------------+--------------+-+---+
+
+ gawk Main Program Address Space Extension
diff --git a/doc/api-figure3.eps b/doc/api-figure3.eps
new file mode 100644
index 00000000..d713575f
--- /dev/null
+++ b/doc/api-figure3.eps
@@ -0,0 +1,526 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Title: api-figure3.fig
+%%Creator: fig2dev Version 3.2 Patchlevel 5d
+%%CreationDate: Wed Oct 31 20:16:08 2012
+%%BoundingBox: 0 0 356 175
+%Magnification: 1.0000
+%%EndComments
+%%BeginProlog
+/MyAppDict 100 dict dup begin def
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+
+% This junk string is used by the show operators
+/PATsstr 1 string def
+/PATawidthshow { % cx cy cchar rx ry string
+ % Loop over each character in the string
+ { % cx cy cchar rx ry char
+ % Show the character
+ dup % cx cy cchar rx ry char char
+ PATsstr dup 0 4 -1 roll put % cx cy cchar rx ry char (char)
+ false charpath % cx cy cchar rx ry char
+ /clip load PATdraw
+ % Move past the character (charpath modified the
+ % current point)
+ currentpoint % cx cy cchar rx ry char x y
+ newpath
+ moveto % cx cy cchar rx ry char
+ % Reposition by cx,cy if the character in the string is cchar
+ 3 index eq { % cx cy cchar rx ry
+ 4 index 4 index rmoveto
+ } if
+ % Reposition all characters by rx ry
+ 2 copy rmoveto % cx cy cchar rx ry
+ } forall
+ pop pop pop pop pop % -
+ currentpoint
+ newpath
+ moveto
+} bind def
+/PATcg {
+ 7 dict dup begin
+ /lw currentlinewidth def
+ /lc currentlinecap def
+ /lj currentlinejoin def
+ /ml currentmiterlimit def
+ /ds [ currentdash ] def
+ /cc [ currentrgbcolor ] def
+ /cm matrix currentmatrix def
+ end
+} bind def
+% PATdraw - calculates the boundaries of the object and
+% fills it with the current pattern
+/PATdraw { % proc
+ save exch
+ PATpcalc % proc nw nh px py
+ 5 -1 roll exec % nw nh px py
+ newpath
+ PATfill % -
+ restore
+} bind def
+% PATfill - performs the tiling for the shape
+/PATfill { % nw nh px py PATfill -
+ PATDict /CurrentPattern get dup begin
+ setfont
+ % Set the coordinate system to Pattern Space
+ PatternGState PATsg
+ % Set the color for uncolored pattezns
+ PaintType 2 eq { PATDict /PColor get PATsc } if
+ % Create the string for showing
+ 3 index string % nw nh px py str
+ % Loop for each of the pattern sources
+ 0 1 Multi 1 sub { % nw nh px py str source
+ % Move to the starting location
+ 3 index 3 index % nw nh px py str source px py
+ moveto % nw nh px py str source
+ % For multiple sources, set the appropriate color
+ Multi 1 ne { dup PC exch get PATsc } if
+ % Set the appropriate string for the source
+ 0 1 7 index 1 sub { 2 index exch 2 index put } for pop
+ % Loop over the number of vertical cells
+ 3 index % nw nh px py str nh
+ { % nw nh px py str
+ currentpoint % nw nh px py str cx cy
+ 2 index oldshow % nw nh px py str cx cy
+ YStep add moveto % nw nh px py str
+ } repeat % nw nh px py str
+ } for
+ 5 { pop } repeat
+ end
+} bind def
+
+% PATkshow - kshow with the current pattezn
+/PATkshow { % proc string
+ exch bind % string proc
+ 1 index 0 get % string proc char
+ % Loop over all but the last character in the string
+ 0 1 4 index length 2 sub {
+ % string proc char idx
+ % Find the n+1th character in the string
+ 3 index exch 1 add get % string proc char char+1
+ exch 2 copy % strinq proc char+1 char char+1 char
+ % Now show the nth character
+ PATsstr dup 0 4 -1 roll put % string proc chr+1 chr chr+1 (chr)
+ false charpath % string proc char+1 char char+1
+ /clip load PATdraw
+ % Move past the character (charpath modified the current point)
+ currentpoint newpath moveto
+ % Execute the user proc (should consume char and char+1)
+ mark 3 1 roll % string proc char+1 mark char char+1
+ 4 index exec % string proc char+1 mark...
+ cleartomark % string proc char+1
+ } for
+ % Now display the last character
+ PATsstr dup 0 4 -1 roll put % string proc (char+1)
+ false charpath % string proc
+ /clip load PATdraw
+ neewath
+ pop pop % -
+} bind def
+% PATmp - the makepattern equivalent
+/PATmp { % patdict patmtx PATmp patinstance
+ exch dup length 7 add % We will add 6 new entries plus 1 FID
+ dict copy % Create a new dictionary
+ begin
+ % Matrix to install when painting the pattern
+ TilingType PATtcalc
+ /PatternGState PATcg def
+ PatternGState /cm 3 -1 roll put
+ % Check for multi pattern sources (Level 1 fast color patterns)
+ currentdict /Multi known not { /Multi 1 def } if
+ % Font dictionary definitions
+ /FontType 3 def
+ % Create a dummy encoding vector
+ /Encoding 256 array def
+ 3 string 0 1 255 {
+ Encoding exch dup 3 index cvs cvn put } for pop
+ /FontMatrix matrix def
+ /FontBBox BBox def
+ /BuildChar {
+ mark 3 1 roll % mark dict char
+ exch begin
+ Multi 1 ne {PaintData exch get}{pop} ifelse % mark [paintdata]
+ PaintType 2 eq Multi 1 ne or
+ { XStep 0 FontBBox aload pop setcachedevice }
+ { XStep 0 setcharwidth } ifelse
+ currentdict % mark [paintdata] dict
+ /PaintProc load % mark [paintdata] dict paintproc
+ end
+ gsave
+ false PATredef exec true PATredef
+ grestore
+ cleartomark % -
+ } bind def
+ currentdict
+ end % newdict
+ /foo exch % /foo newlict
+ definefont % newfont
+} bind def
+% PATpcalc - calculates the starting point and width/height
+% of the tile fill for the shape
+/PATpcalc { % - PATpcalc nw nh px py
+ PATDict /CurrentPattern get begin
+ gsave
+ % Set up the coordinate system to Pattern Space
+ % and lock down pattern
+ PatternGState /cm get setmatrix
+ BBox aload pop pop pop translate
+ % Determine the bounding box of the shape
+ pathbbox % llx lly urx ury
+ grestore
+ % Determine (nw, nh) the # of cells to paint width and height
+ PatHeight div ceiling % llx lly urx qh
+ 4 1 roll % qh llx lly urx
+ PatWidth div ceiling % qh llx lly qw
+ 4 1 roll % qw qh llx lly
+ PatHeight div floor % qw qh llx ph
+ 4 1 roll % ph qw qh llx
+ PatWidth div floor % ph qw qh pw
+ 4 1 roll % pw ph qw qh
+ 2 index sub cvi abs % pw ph qs qh-ph
+ exch 3 index sub cvi abs exch % pw ph nw=qw-pw nh=qh-ph
+ % Determine the starting point of the pattern fill
+ %(px, py)
+ 4 2 roll % nw nh pw ph
+ PatHeight mul % nw nh pw py
+ exch % nw nh py pw
+ PatWidth mul exch % nw nh px py
+ end
+} bind def
+
+% Save the original routines so that we can use them later on
+/oldfill /fill load def
+/oldeofill /eofill load def
+/oldstroke /stroke load def
+/oldshow /show load def
+/oldashow /ashow load def
+/oldwidthshow /widthshow load def
+/oldawidthshow /awidthshow load def
+/oldkshow /kshow load def
+
+% These defs are necessary so that subsequent procs don't bind in
+% the originals
+/fill { oldfill } bind def
+/eofill { oldeofill } bind def
+/stroke { oldstroke } bind def
+/show { oldshow } bind def
+/ashow { oldashow } bind def
+/widthshow { oldwidthshow } bind def
+/awidthshow { oldawidthshow } bind def
+/kshow { oldkshow } bind def
+/PATredef {
+ MyAppDict begin
+ {
+ /fill { /clip load PATdraw newpath } bind def
+ /eofill { /eoclip load PATdraw newpath } bind def
+ /stroke { PATstroke } bind def
+ /show { 0 0 null 0 0 6 -1 roll PATawidthshow } bind def
+ /ashow { 0 0 null 6 3 roll PATawidthshow }
+ bind def
+ /widthshow { 0 0 3 -1 roll PATawidthshow }
+ bind def
+ /awidthshow { PATawidthshow } bind def
+ /kshow { PATkshow } bind def
+ } {
+ /fill { oldfill } bind def
+ /eofill { oldeofill } bind def
+ /stroke { oldstroke } bind def
+ /show { oldshow } bind def
+ /ashow { oldashow } bind def
+ /widthshow { oldwidthshow } bind def
+ /awidthshow { oldawidthshow } bind def
+ /kshow { oldkshow } bind def
+ } ifelse
+ end
+} bind def
+false PATredef
+% Conditionally define setcmykcolor if not available
+/setcmykcolor where { pop } {
+ /setcmykcolor {
+ 1 sub 4 1 roll
+ 3 {
+ 3 index add neg dup 0 lt { pop 0 } if 3 1 roll
+ } repeat
+ setrgbcolor - pop
+ } bind def
+} ifelse
+/PATsc { % colorarray
+ aload length % c1 ... cn length
+ dup 1 eq { pop setgray } { 3 eq { setrgbcolor } { setcmykcolor
+ } ifelse } ifelse
+} bind def
+/PATsg { % dict
+ begin
+ lw setlinewidth
+ lc setlinecap
+ lj setlinejoin
+ ml setmiterlimit
+ ds aload pop setdash
+ cc aload pop setrgbcolor
+ cm setmatrix
+ end
+} bind def
+
+/PATDict 3 dict def
+/PATsp {
+ true PATredef
+ PATDict begin
+ /CurrentPattern exch def
+ % If it's an uncolored pattern, save the color
+ CurrentPattern /PaintType get 2 eq {
+ /PColor exch def
+ } if
+ /CColor [ currentrgbcolor ] def
+ end
+} bind def
+% PATstroke - stroke with the current pattern
+/PATstroke {
+ countdictstack
+ save
+ mark
+ {
+ currentpoint strokepath moveto
+ PATpcalc % proc nw nh px py
+ clip newpath PATfill
+ } stopped {
+ (*** PATstroke Warning: Path is too complex, stroking
+ with gray) =
+ cleartomark
+ restore
+ countdictstack exch sub dup 0 gt
+ { { end } repeat } { pop } ifelse
+ gsave 0.5 setgray oldstroke grestore
+ } { pop restore pop } ifelse
+ newpath
+} bind def
+/PATtcalc { % modmtx tilingtype PATtcalc tilematrix
+ % Note: tiling types 2 and 3 are not supported
+ gsave
+ exch concat % tilingtype
+ matrix currentmatrix exch % cmtx tilingtype
+ % Tiling type 1 and 3: constant spacing
+ 2 ne {
+ % Distort the pattern so that it occupies
+ % an integral number of device pixels
+ dup 4 get exch dup 5 get exch % tx ty cmtx
+ XStep 0 dtransform
+ round exch round exch % tx ty cmtx dx.x dx.y
+ XStep div exch XStep div exch % tx ty cmtx a b
+ 0 YStep dtransform
+ round exch round exch % tx ty cmtx a b dy.x dy.y
+ YStep div exch YStep div exch % tx ty cmtx a b c d
+ 7 -3 roll astore % { a b c d tx ty }
+ } if
+ grestore
+} bind def
+/PATusp {
+ false PATredef
+ PATDict begin
+ CColor PATsc
+ end
+} bind def
+
+% right30
+11 dict begin
+/PaintType 1 def
+/PatternType 1 def
+/TilingType 1 def
+/BBox [0 0 1 1] def
+/XStep 1 def
+/YStep 1 def
+/PatWidth 1 def
+/PatHeight 1 def
+/Multi 2 def
+/PaintData [
+ { clippath } bind
+ { 32 16 true [ 32 0 0 -16 0 16 ]
+ {<00030003000c000c0030003000c000c0030003000c000c00
+ 30003000c000c00000030003000c000c0030003000c000c0
+ 030003000c000c0030003000c000c000>}
+ imagemask } bind
+] def
+/PaintProc {
+ pop
+ exec fill
+} def
+currentdict
+end
+/P2 exch def
+
+% crosshatch45
+11 dict begin
+/PaintType 1 def
+/PatternType 1 def
+/TilingType 1 def
+/BBox [0 0 1 1] def
+/XStep 1 def
+/YStep 1 def
+/PatWidth 1 def
+/PatHeight 1 def
+/Multi 2 def
+/PaintData [
+ { clippath } bind
+ { 20 20 true [ 20 0 0 -20 0 20 ]
+ {<8020004050102088201104400a02800401000a02
+ 8011044020882040501080200040501020882011
+ 04400a02800401000a0280110440208820405010>}
+ imagemask } bind
+] def
+/PaintProc {
+ pop
+ exec fill
+} def
+currentdict
+end
+/P6 exch def
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+/pageheader {
+save
+newpath 0 175 moveto 0 0 lineto 356 0 lineto 356 175 lineto closepath clip newpath
+-194.8 350.2 translate
+1 -1 scale
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+} bind def
+/pagefooter {
+$F2psEnd
+restore
+} bind def
+%%EndProlog
+pageheader
+%
+% Fig objects follow
+%
+%
+% here starts figure with depth 50
+% Arc
+7.500 slw
+0 slc
+gs clippath
+8019 4079 m 8138 4172 l 8175 4125 l 8056 4032 l 8056 4032 l 8132 4130 l 8019 4079 l cp
+eoclip
+n 6120.0 6627.7 3207.7 -129.1463 -50.8537 arc
+gs col0 s gr
+ gr
+
+% arrowhead
+0 slj
+n 8019 4079 m 8132 4130 l 8056 4032 l 8019 4079 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+n 3105 4140 m 6660 4140 l 6660 5085 l 3105 5085 l
+ cp gs col0 s gr
+% Polyline
+n 6660 4140 m 8730 4140 l 8730 5085 l 6660 5085 l
+ cp gs col7 0.50 shd ef gr gs col0 s gr
+% Polyline
+n 3510 4140 m 3780 4140 l 3780 5085 l 3510 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 234.00 276.00] PATmp PATsp ef gr PATusp gs col0 s gr
+% Polyline
+n 4365 4140 m 4635 4140 l 4635 5085 l 4365 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 291.00 276.00] PATmp PATsp ef gr PATusp gs col0 s gr
+% Polyline
+n 4905 4140 m 5265 4140 l 5265 5085 l 4905 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 327.00 276.00] PATmp PATsp ef gr PATusp gs col0 s gr
+% Polyline
+n 7965 4140 m 8370 4140 l 8370 5085 l 7965 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P6 [16 0 0 -16 531.00 276.00] PATmp PATsp ef gr PATusp gs col0 s gr
+/Times-Roman ff 180.00 scf sf
+3510 5490 m
+gs 1 -1 sc (gawk Main Program Address Space) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+7290 5490 m
+gs 1 -1 sc (Extension) col0 sh gr
+/Courier-Bold ff 180.00 scf sf
+3240 3150 m
+gs 1 -1 sc ( chdir\("/path"\)) col0 sh gr
+/Courier-Bold ff 180.00 scf sf
+3330 3375 m
+gs 1 -1 sc (}) col0 sh gr
+/Courier-Bold ff 180.00 scf sf
+3375 2925 m
+gs 1 -1 sc (BEGIN {) col0 sh gr
+/Courier-Bold ff 180.00 scf sf
+6660 3150 m
+gs 1 -1 sc (\(*fnptr\)\(1\);) col0 sh gr
+% here ends figure;
+pagefooter
+showpage
+%%Trailer
+end
+%EOF
diff --git a/doc/api-figure3.fig b/doc/api-figure3.fig
new file mode 100644
index 00000000..5c7fdd97
--- /dev/null
+++ b/doc/api-figure3.fig
@@ -0,0 +1,29 @@
+#FIG 3.2 Produced by xfig version 3.2.5b
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+5 1 0 1 0 7 50 -1 -1 0.000 0 0 1 0 6120.000 6627.656 4095 4140 6120 3420 8145 4140
+ 1 1 1.00 60.00 120.00
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 3105 4140 6660 4140 6660 5085 3105 5085 3105 4140
+2 2 0 1 0 7 50 -1 10 0.000 0 0 -1 0 0 5
+ 6660 4140 8730 4140 8730 5085 6660 5085 6660 4140
+2 2 0 1 0 7 50 -1 42 0.000 0 0 -1 0 0 5
+ 3510 4140 3780 4140 3780 5085 3510 5085 3510 4140
+2 2 0 1 0 7 50 -1 42 0.000 0 0 -1 0 0 5
+ 4365 4140 4635 4140 4635 5085 4365 5085 4365 4140
+2 2 0 1 0 7 50 -1 42 0.000 0 0 -1 0 0 5
+ 4905 4140 5265 4140 5265 5085 4905 5085 4905 4140
+2 2 0 1 0 7 50 -1 46 0.000 0 0 -1 0 0 5
+ 7965 4140 8370 4140 8370 5085 7965 5085 7965 4140
+4 0 0 50 -1 0 12 0.0000 4 180 2850 3510 5490 gawk Main Program Address Space\001
+4 0 0 50 -1 0 12 0.0000 4 135 825 7290 5490 Extension\001
+4 0 0 50 -1 14 12 0.0000 4 180 2160 3240 3150 chdir("/path")\001
+4 0 0 50 -1 14 12 0.0000 4 150 120 3330 3375 }\001
+4 0 0 50 -1 14 12 0.0000 4 150 840 3375 2925 BEGIN {\001
+4 0 0 50 -1 14 12 0.0000 4 165 1440 6660 3150 (*fnptr)(1);\001
diff --git a/doc/api-figure3.pdf b/doc/api-figure3.pdf
new file mode 100644
index 00000000..517b2ecc
--- /dev/null
+++ b/doc/api-figure3.pdf
Binary files differ
diff --git a/doc/api-figure3.png b/doc/api-figure3.png
new file mode 100644
index 00000000..f7db0794
--- /dev/null
+++ b/doc/api-figure3.png
Binary files differ
diff --git a/doc/api-figure3.txt b/doc/api-figure3.txt
new file mode 100644
index 00000000..a601ce94
--- /dev/null
+++ b/doc/api-figure3.txt
@@ -0,0 +1,13 @@
+ BEGIN {
+ chdir("/path") (*fnptr)(1);
+ }
+ +--------------------------------------------+
+ | |
+ | V
++-------+-+---+-+---+-+------------------+--------------+-+---+
+| |x| |x| |x| |OOOOOOOOOOOOOO|X|OOO|
+| |x| |x| |x| |OOOOOOOOOOOOOO|X|OOO|
+| |x| |x| |x| |OOOOOOOOOOOOOO|X|OOO|
++-------+-+---+-+---+-+------------------+--------------+-+---+
+
+ gawk Main Program Address Space Extension
diff --git a/doc/array-elements.eps b/doc/array-elements.eps
new file mode 100644
index 00000000..041c0b39
--- /dev/null
+++ b/doc/array-elements.eps
@@ -0,0 +1,158 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Title: array-elements.fig
+%%Creator: fig2dev Version 3.2 Patchlevel 5d
+%%CreationDate: Sun May 4 22:46:26 2014
+%%BoundingBox: 0 0 379 76
+%Magnification: 1.0000
+%%EndComments
+%%BeginProlog
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+/pageheader {
+save
+newpath 0 76 moveto 0 0 lineto 379 0 lineto 379 76 lineto closepath clip newpath
+-203.3 199.4 translate
+1 -1 scale
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+} bind def
+/pagefooter {
+$F2psEnd
+restore
+} bind def
+%%EndProlog
+pageheader
+%
+% Fig objects follow
+%
+%
+% here starts figure with depth 50
+% Polyline
+0 slj
+0 slc
+7.500 slw
+n 4455 1980 m 4455 2700 l 4455 2655 l
+ 4455 2700 l gs col0 s gr
+% Polyline
+n 6075 1980 m
+ 6075 2700 l gs col0 s gr
+% Polyline
+n 7425 1980 m
+ 7425 2700 l gs col0 s gr
+/Courier-Bold ff 180.00 scf sf
+3735 2340 m
+gs 1 -1 sc (8) col0 sh gr
+/Courier-Bold ff 180.00 scf sf
+5175 2340 m
+gs 1 -1 sc ("foo") col0 sh gr
+/Courier-Bold ff 180.00 scf sf
+6795 2340 m
+gs 1 -1 sc ("") col0 sh gr
+/Courier-Bold ff 180.00 scf sf
+7875 2340 m
+gs 1 -1 sc (30) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+3735 3150 m
+gs 1 -1 sc (0) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+5175 3150 m
+gs 1 -1 sc (1) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+6795 3150 m
+gs 1 -1 sc (2) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+7875 3150 m
+gs 1 -1 sc (3) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+8730 2340 m
+gs 1 -1 sc (Value) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+8730 3150 m
+gs 1 -1 sc (Index) col0 sh gr
+% here ends figure;
+%
+% here starts figure with depth 40
+% Polyline
+0 slj
+0 slc
+7.500 slw
+n 3240 1980 m 8415 1980 l 8415 2700 l 3240 2700 l
+ cp gs col0 s gr
+% here ends figure;
+pagefooter
+showpage
+%%Trailer
+%EOF
diff --git a/doc/array-elements.fig b/doc/array-elements.fig
new file mode 100644
index 00000000..63b5ffbf
--- /dev/null
+++ b/doc/array-elements.fig
@@ -0,0 +1,27 @@
+#FIG 3.2 Produced by xfig version 3.2.5b
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5
+ 3240 1980 8415 1980 8415 2700 3240 2700 3240 1980
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4
+ 4455 1980 4455 2700 4455 2655 4455 2700
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+ 6075 1980 6075 2700
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+ 7425 1980 7425 2700
+4 0 0 50 -1 14 12 0.0000 4 120 120 3735 2340 8\001
+4 0 0 50 -1 14 12 0.0000 4 120 600 5175 2340 "foo"\001
+4 0 0 50 -1 14 12 0.0000 4 60 240 6795 2340 ""\001
+4 0 0 50 -1 14 12 0.0000 4 120 240 7875 2340 30\001
+4 0 0 50 -1 0 12 0.0000 4 135 105 3735 3150 0\001
+4 0 0 50 -1 0 12 0.0000 4 135 105 5175 3150 1\001
+4 0 0 50 -1 0 12 0.0000 4 135 105 6795 3150 2\001
+4 0 0 50 -1 0 12 0.0000 4 135 105 7875 3150 3\001
+4 0 0 50 -1 0 12 0.0000 4 135 480 8730 2340 Value\001
+4 0 0 50 -1 0 12 0.0000 4 135 465 8730 3150 Index\001
diff --git a/doc/array-elements.pdf b/doc/array-elements.pdf
new file mode 100644
index 00000000..328cbd1a
--- /dev/null
+++ b/doc/array-elements.pdf
Binary files differ
diff --git a/doc/array-elements.png b/doc/array-elements.png
new file mode 100644
index 00000000..b57d66b7
--- /dev/null
+++ b/doc/array-elements.png
Binary files differ
diff --git a/doc/array-elements.txt b/doc/array-elements.txt
new file mode 100644
index 00000000..8906318a
--- /dev/null
+++ b/doc/array-elements.txt
@@ -0,0 +1,4 @@
++---------+---------+--------+---------+
+| 8 | "foo" | "" | 30 | @r{Value}
++---------+---------+--------+---------+
+ 0 1 2 3 @r{Index}
diff --git a/doc/awkcard.in b/doc/awkcard.in
index 1c4d1910..556bdc1e 100644
--- a/doc/awkcard.in
+++ b/doc/awkcard.in
@@ -1,7 +1,8 @@
.\" AWK Reference Card --- Arnold Robbins, arnold@skeeve.com
.\"
.\" Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-.\" 2003, 2004, 2005, 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+.\" 2003, 2004, 2005, 2007, 2009, 2010, 2011, 2012, 2013, 2014
+.\" Free Software Foundation, Inc.
.\"
.\" Permission is granted to make and distribute verbatim copies of
.\" this reference card provided the copyright notice and this permission
@@ -25,8 +26,7 @@
.\" Strings to save typing
.ds AK \*(FCawk\*(FR
.ds GK \*(FCgawk\*(FR
-.ds PK \*(FCpgawk\*(FR
-.ds NK Bell Labs \*(FCawk\*(FR
+.ds NK Brian Kernighan's \*(FCawk\*(FR
.ds MK \*(FCmawk\*(FR
.\"
.\"
@@ -64,7 +64,7 @@ Environment Variables (\*(GK) 11
Escape Sequences 9
Expressions 7
Fields 10
-FTP/HTTP Information 18
+FTP/HTTP/GIT Information 18
Historical Features (\*(GK) 10
Input Control 13
Internationalization (\*(GK) 18
@@ -76,10 +76,10 @@ Pattern Elements 8
Printf Formats 14
Records 10
Regular Expressions 11
-Signals (\*(PK) 4
+Signals (\*(GK \*(FC\-\^\-profile\*(FR) 4
Special Filenames 12
String Functions 16
-Time Functions (\*(GK) 17
+Time Functions 17
Type Functions (\*(GK) 18
User-defined Functions 15
Variables 5\*(CX
@@ -100,8 +100,8 @@ Brian Kernighan and Michael Brennan who reviewed it.
\*(CD
.SL
.nf
-\*(FRCopyright \(co 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-2005, 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+\*(FRCopyright \(co 1996\(en2005, 2007, 2009\(en2014
+Free Software Foundation, Inc.
.nf
.BT
@@ -113,7 +113,7 @@ Brian Kernighan and Michael Brennan who reviewed it.
.ES
\*(CDThis card describes POSIX AWK, as well as three
freely available \*(AK implementations
-(see \fHFTP/HTTP Information\fP below).
+(see \fHFTP/HTTP/GIT Information\fP).
\*(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.
@@ -146,7 +146,7 @@ or
.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.)
+(See \fHEscape Sequences\fP.)
.sp .5
\*(FIstring\fP \- a group of characters enclosed in double quotes.
Strings may contain \*(FIescape sequences\*(FR.
@@ -249,25 +249,29 @@ copyright information on \*(FCstdout\*(FR.
.TI "\*(FC\-d\*(FR[\*(FIfile\*(FR], \*(FC\-\^\-dump-variables\*(FR[\*(FC=\*(FIfile\*(FR]
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.
+\*(FIfile\*(FR (default: \*(FCawkvars.out\*(FR).
+.TI "\*(FC\-D\*(FR[\*(FC\*(FIfile\*(FR], \*(FC\-\^\-debug\*(FR[\*(FC=\*(FIfile\*(FR]
+Enable debugging of program. Optionally read stored commands
+from \*(FIfile\*(FR.
.TI "\*(FC-e '\*(FItext\*(FC'\*(FR, \*(FC\-\^\-source '\*(FItext\*(FC'\*(FR
Use \*(FItext\*(FR as AWK program source code.
.TI "\*(FC\-E \*(FIfile\*(FR, \*(FC\-\^\-exec \*(FIfile\*(FR
Read program text from \*(FIfile\fP. No other
options are processed.
-Also disables command-line variable assignments.
+Also disable command-line variable assignments.
Useful with \*(FC#!\fP.
.TI "\*(FC\-g\*(FR, \*(FC\-\^\-gen\-pot\*(FR
Process the program and print a GNU \*(FCgettext\*(FR
-format \*(FC\&.pot\*(FR file on standard output,
+format \*(FC\&.pot\*(FR file on \*(FCstdout\*(FR,
containing the text of all strings that were marked
for localization.
.TI "\*(FC\-h\*(FR, \*(FC\-\^\-help\*(FR
Print a short summary of the available
options on \*(FCstdout\*(FR, then exit zero.
+.TI "\*(FC\-i \*(FIfile\*(FR, \*(FC\-\^\-include \*(FIfile\*(FR
+Include library AWK code in \*(FIfile\*(FR.
+.TI "\*(FC\-l \*(FIlib\*(FR, \*(FC\-\^\-load \*(FIlib\*(FR
+Load dynamic extension \*(FIlib\fP.
.TI "\*(FC\-L \*(FR[\*(FC\*(FIvalue\*(FR], \*(FC\-\^\-lint\*(FR[\*(FC=\*(FIvalue\*(FR]
Warn about dubious or non-portable constructs.
If \*(FIvalue\*(FR is
@@ -277,36 +281,25 @@ If \*(FIvalue\*(FR is
\*(FCinvalid\*(FR,
only issue warnings about things that are
actually invalid (not fully implemented yet).
+.TI "\*(FC\-M\*(FR, \*(FC\-\^\-bignum\*(FR
+Enable arbitrary-precision arithmetic.
.TI "\*(FC\-n\*(FR, \*(FC\-\^\-non\-decimal\-data\*(FR
Recognize octal and hexadecimal values in input data.
\*(FIUse this option with great caution!\*(FR
.TI "\*(FC\-N\*(FR, \*(FC\-\^\-use\-lc\-numeric\*(FR
Force use of the locale's decimal point character when parsing input data.
+.TI "\*(FC\-o\*(FR[\*(FC\*(FIfile\*(FR], \*(FC\-\^\-pretty-print\*(FR[\*(FC=\*(FIfile\*(FR]
+Output a pretty printed version of the program to \*(FIfile\*(FR
+(default: \*(FCawkprof.out\*(FR).
.TI "\*(FC\-O\*(FR, \*(FC\-\^\-optimize\*(FR
Enable some internal optimizations.
.TI "\*(FC\-p\*(FR[\*(FC\*(FIfile\*(FR], \*(FC\-\^\-profile\*(FR[\*(FC=\*(FIfile\*(FR]
Send profiling data to \*(FIfile\*(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
+The profile contains execution counts in the left margin
of each statement in the program.
.TI "\*(FC\-P\*(FR, \*(FC\-\^\-posix\*(FR
-Disable common and GNU extensions.
-.TI "\*(FC\-R \*(FIfile\*(FR, \*(FC\-\^\-command \*(FIfile\*(FR"
-\*(FCdgawk\*(FR only.
-Read stored debugger commands from \*(FIfile\*(FR.
-.TI "\*(FC\-r\*(FR, \*(FC\-\^\-re\-interval\*(FR
-Enable \*(FIinterval expressions\*(FR in regular
-expression matching (see \fHRegular
-Expressions\fP below). Useful if
-\*(FC\-\^\-traditional\*(FR is specified.
-.TI "\*(FC\-S\*(FR, \*(FC\-\^\-sandbox\*(FR
-Disable the \*(FCsystem()\*(FR function,
-input redirection with \*(FCgetline\*(FR,
-output redirection with \*(FCprint\*(FR and \*(FCprintf\*(FR,
-and dynamic extensions loading.\*(CB
+Disable common and GNU extensions.\*(CB
.in -4n
.EB "\s+2\f(HBCOMMAND LINE ARGUMENTS (\*(GK\f(HB)\*(FR\s0"
@@ -318,6 +311,14 @@ and dynamic extensions loading.\*(CB
.ES
.fi
.in +4n
+.TI "\*(FC\-r\*(FR, \*(FC\-\^\-re\-interval\*(FR
+Enable \*(FIinterval expressions\*(FR.
+(Needed with \*(FC\-c\*(FR.)
+.TI "\*(FC\-S\*(FR, \*(FC\-\^\-sandbox\*(FR
+Disable the \*(FCsystem()\*(FR function,
+input redirection with \*(FCgetline\*(FR,
+output redirection with \*(FCprint\*(FR and \*(FCprintf\*(FR,
+and loading dynamic extensions.
.TI "\*(FC-t\*(FR, \*(FC\-\^\-lint\-old\*(FR
Warn about constructs that are not
portable to the original version of
@@ -330,14 +331,14 @@ and exit zero.
.in -4n
.sp .5
.fi
-In compatibility mode,
-any other options are flagged as invalid, but are otherwise ignored.
Normally, if there is program text, unknown
options are passed on to the AWK program in
\*(FCARGV\*(FR
-for processing.\*(CB
+for processing.
+In compatibility mode,
+unknown options are flagged as invalid, but are otherwise ignored.\*(CB
.EB "\s+2\f(HBCOMMAND LINE ARGUMENTS (\*(GK\f(HB)\*(FR\s0"
-
+.sp .4
.\"
.\"
.\" --- Command Line Arguments (mawk)
@@ -370,7 +371,7 @@ Adjust the size of \*(MK's internal
T}
\*(FC\-W version\*(FR T{
Print version and copyright on
-\*(FCstdout\fP and limit information on \*(FCstderr\fP
+\*(FCstdout\fP, limit information on \*(FCstderr\fP,
and exit zero.
T}
.TE
@@ -382,14 +383,14 @@ The options may be abbreviated using just the first letter, e.g.,
and so on.\*(CB
.EB "\s+2\f(HBCOMMAND LINE ARGUMENTS (\*(MK\f(HB)\*(FR\s0"
.sp .7
-.\" --- Signals (pgawk)
+.\" --- Signals (gawk --profile)
.ES
.fi
-\*(CD\*(PK accepts two signals.
+\*(CD\*(GK accepts two signals while profiling.
\*(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"
+.EB "\s+2\f(HBSIGNALS (\*(GK \f(HB\-\^\-profile)\*(FR\s0"
.\" --- Lines And Statements
.ES
@@ -407,14 +408,14 @@ 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
+Normally, statements end with a newline, but lines ending in
a ``,'',
\*(FC{\*(FR,
\*(CB\*(FC?\*(FR,
\*(FC:\*(FR,\*(CD
-\*(FC&&\*(FR
+\*(FC&&\*(FR,
or
-\*(FC||\*(FR
+\*(FC||\*(FR,
are automatically continued.
Lines ending in \*(FCdo\fP or \*(FCelse\fP
also have their statements automatically continued on the following line.
@@ -435,7 +436,9 @@ and to the pattern-action statements themselves.\*(CX
\*(CDAWK programs are a sequence of pattern-action statements
and optional function definitions.
.sp .5
- \*(CB\*(FC@include "\*(FIfilename\*(FC"\*(CD
+ \*(CB\*(FC@include "\*(FIfilename\*(FC"
+.br
+ \*(FC@load "\*(FIfilename\*(FC"\*(CD
.br
\*(FIpattern\*(FC { \*(FIaction statements\*(FC }\*(FR
.br
@@ -449,8 +452,10 @@ The program text is read as if all the \*(FIprog-file\*(FR(s)
\*(CBand command line
source texts\*(CD had been concatenated.
.sp
-\*(GK includes files named on \*(FC@include\*(FR lines.
-Nested includes are allowed.\*(CD
+\*(CB\*(GK includes files named on \*(FC@include\*(FR lines.
+Nested includes are allowed.
+\*(GK loads extensions named on \*(FC@load\*(FR lines;
+see \fHDynamic Extensions\*(FR.\*(CD
.sp .5
AWK programs execute in the following order.
First, all variable assignments specified via the \*(FC\-v\fP
@@ -458,15 +463,13 @@ 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
+A command line argument of the form
\*(FIvar\*(FC=\*(FIval\*(FR,
-it is treated as a variable assignment. The variable
-\*(FIvar\fP will be assigned the value \*(FIval\*(FR.
+is treated as a variable assignment. The variable
+\*(FIvar\fP is 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
@@ -502,7 +505,7 @@ If a program only has an \*(FCEND\fP rule, the input is read.
.fi
.TS
expand;
-l lw(2i).
+l lw(2.3i).
\*(CD\*(FCARGC\fP T{
Number of command line arguments.
T}
@@ -539,12 +542,12 @@ is \*(FC"%.6g"\*(FR.
T}
\*(FCENVIRON\fP T{
Array containing the current environment.
-it is indexed by the environment
-variables, each element being the value of
+It is indexed by the environment
+variable names, each element being the value of
that variable.
T}
\*(CB\*(FCERRNO\fP T{
-String describing the error if a
+String error value if a
\*(FCgetline\*(FR
redirection or read
fails, or if
@@ -571,7 +574,11 @@ instead of the field separator.\*(CD
T}
\*(FCFS\fP T{
Input field separator, a space by default
-(see \fHFields\fP above).
+(see \fHFields\fP).
+T}
+\*(CB\*(FCFUNCTAB\fP T{
+An array indexed by the names of all user-defined
+and extension functions.\*(CD
T}
\*(CB\*(FCIGNORECASE\fP T{
If non-zero, all regular expression and string
@@ -587,13 +594,8 @@ 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.
-Any other true value just prints warnings.\*(CD
T}
-\*(FCNF\fP T{
+\*(CD\*(FCNF\fP T{
Number of fields in the current input record.
T}
\*(FCNR\fP T{
@@ -608,7 +610,11 @@ T}
\*(FCORS\fP T{
Output record separator, a newline by default.
T}
-\*(CB\*(FCPROCINFO\fP T{
+\*(CB\*(FCPREC\fP T{
+The working precision of arbitrary precision floating-point
+numbers, 53 by default.
+T}
+\*(FCPROCINFO\fP T{
Elements of this array provide access to information
about the running AWK program. See
\*(AM for details.\*(CD
@@ -617,9 +623,13 @@ T}
Length of the string matched by \*(FCmatch()\*(FR;
\-1 if no match.
T}
+\*(CB\*(FCROUNDMODE\fP T{
+The rounding mode to use for arbitrary precision arithmetic,
+by default \*(FC"N"\fP.\*(CD
+T}
\*(FCRS\fP T{
Input record separator, a newline by default
-(see \fHRecords\fP above).
+(see \fHRecords\fP).
T}
\*(FCRSTART\fP T{
Index of the first character matched by
@@ -633,7 +643,12 @@ T}
\*(FCSUBSEP\fP T{
Character(s) used to separate multiple subscripts
in array elements, by default \*(FC"\e034"\*(FR. (See
-\fHArrays\fP below).
+\fHArrays\fP).
+T}
+\*(CB\*(FCSYMTAB\fP T{
+An array indexed by the names of all global
+variables and arrays. May be used to indirectly
+set variable and array values.\*(CD
T}
\*(CB\*(FCTEXTDOMAIN\fP T{
The internationalization text domain,
@@ -654,7 +669,7 @@ 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.
+separated by the value of \*(FCSUBSEP\fP.
This simulates multi-dimensional
arrays. For example:
.nf
@@ -685,9 +700,11 @@ 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
+Specifying just the array name without a subscript in
the \*(FCdelete\fP
statement deletes the entire contents of an array.
+\*(CBYou cannot use \*(FCdelete\fP with \*(FCFUNCTAB\fP
+or \*(FCSYMTAB\fP.\*(CD
.sp .5
\*(CB\*(GK provides true multidimensional arrays.
Such arrays need not be ``rectangular'' as in C or C++. For example:
@@ -766,6 +783,10 @@ it will be treated as a string.
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
+Uninitialized variables have the numeric value 0 and the string value
+\*(FC"\^"\fP
+(the null, or empty, 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
@@ -790,11 +811,7 @@ elements and the elements of an array created by \*(FCsplit()\fP
\*(CBor \*(FCpatsplit()\fP\*(CD that are numeric strings.
The basic idea is that \*(FIuser input\*(FR,
and only user input, that looks numeric,
-should be treated that way.\*(CD
-.sp .5
-Uninitialized variables have the numeric value 0 and the string value
-\*(FC"\^"\fP
-(the null, or empty, string).\*(CX
+should be treated that way.\*(CX
.EB "\s+2\f(HBCONVERSIONS AND COMPARISONS\*(FR\s0"
.\" --- Pattern Elements
@@ -820,7 +837,7 @@ in a program, including different source files.
\*(CB\*(FCBEGINFILE\*(FR and \*(FCENDFILE\*(FR are special patterns that
execute before the first record of each file and after the last record
of each file, respectively. In the \*(FCBEGINFILE\*(FR rule, the \*(FCERRNO\*(FR
-variable is non-null if there is a problem with the file; the code should use
+variable is non-null if there is a problem with the file; the rule should use
\*(FCnextfile\*(FR to skip the file if desired. Otherwise \*(GK exits with
its usual fatal error. The actions for multiple
\*(FCBEGINFILE\*(FR and \*(FCENDFILE\*(FR patterns are merged.\*(CD
@@ -860,9 +877,9 @@ or go to the \*(FIincr\*(FR part of a \*(FCfor\*(FR loop.
.br
Delete element \*(FIindex\*(FR from array \*(FIarray\*(FR.
.ti -.2i
-\*(CL\*(FCdelete \*(FIarray\^\*(FR
+\*(FCdelete \*(FIarray\^\*(FR
.br
-Delete all elements from array \*(FIarray\*(FR.\*(CD
+Delete all elements from array \*(FIarray\*(FR.
.ti -.2i
\*(FCdo \*(FIstatement \*(FCwhile (\*(FIcondition\*(FC)\*(FR
.br
@@ -899,7 +916,7 @@ matches the closest \*(FCif\*(FR.
.ti -.2i
\*(FCnext\*(FR See \fHInput Control.\fP
.ti -.2i
-\*(CL\*(FCnextfile\*(FR See \fHInput Control.\fP\*(CD
+\*(FCnextfile\*(FR See \fHInput Control.\fP
.in -.2i
.\" --- Start switch statement
\*(CB\*(FCswitch (\*(FIexpression\*(FC) {
@@ -1016,7 +1033,7 @@ or
overrides the use of
\*(FCFPAT\fP.\*(CD
.sp .5
-Each field in the input record may be referenced by its position,
+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.
@@ -1025,7 +1042,7 @@ 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
+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
@@ -1033,7 +1050,7 @@ 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
+\*(CR(not \*(NK)\*(CD.\*(CX
.EB "\s+2\f(HBFIELDS\*(FR\s0"
.\" --- Historical Features
@@ -1068,7 +1085,7 @@ Summary of Regular Expressions
In Decreasing Precedence
_
\*(FC(\^\*(FIr\*(FC)\*(FR~regular expression (for grouping)
-\*(FIc\*(FR~if non-special char, matches itself
+\*(FIc\*(FR~if non-special character, 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)
@@ -1093,9 +1110,10 @@ _
.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.\*(CX
+The \*(FIr\*(FC{\*(FIn\*(FC,\*(FIm\*(FC}\*(FR notation is called an
+\*(FIinterval expression\fP.
+\*(CRNot supported by
+\*(MK or \*(NK.\*(CX
.sp .5
\*(CDIn regular expressions, within character ranges
(\*(FC[\*(FR...\*(FC]\*(FR),
@@ -1128,16 +1146,23 @@ The default path is
If a file name given to the \*(FC\-f\fP option contains a ``/'' character,
no path search is performed.
.sp .5
-.PP
+The variable \*(FCAWKLIBPATH\fP
+specifies the search path for dynamic extensions to use
+with \*(FC@load\fP and the \*(FC\-l\fP option.
+.sp .5
For socket communication,
\*(FCGAWK_SOCK_RETRIES\fP
-controls the number of retries, and
+controls the number of connection retries, and
\*(FCGAWK_MSEC_SLEEP\fP controls
the interval between retries.
The interval is in milliseconds. On systems that do not support
\*(FIusleep\fP(3),
the value is rounded up to an integral number of seconds.
.sp .5
+The value of \*(FCGAWK_READ_TIMEOUT\fP specifies the time, in milliseconds,
+for \*(GK to
+wait for input before returning with an error.
+.sp .5
If \*(FCPOSIXLY_CORRECT\fP exists
.\" in the environment,
then \*(GK
@@ -1158,7 +1183,7 @@ your program.
.ti +5n
\*(FCBEGIN { TEXTDOMAIN = "myprog" }\*(FR
.sp .3
-This allows \*(GK to find the \*(FC\&.mo\*(FR
+This allows \*(GK to find the \*(FC\&.gmo\*(FR
file associated with your program.
Without this step, \*(GK uses the \*(FCmessages\*(FR text domain,
which probably won't work.
@@ -1181,7 +1206,7 @@ to generate a \*(FC\&.pot\*(FR
file for your program.
.sp .5
5. Provide appropriate translations, and build and install a corresponding
-\*(FC\&.mo\*(FR file.
+\*(FC\&.gmo\*(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"
@@ -1204,7 +1229,7 @@ The filenames are:
expand;
l lw(2i).
\*(FC"\-"\fP standard input
-\*(FC/dev/stdin\fP standard input \*(CR(not \*(MK)\*(CD
+\*(FC/dev/stdin\fP standard input
\*(FC/dev/stdout\fP standard output
\*(FC/dev/stderr\fP standard error output
.TE
@@ -1266,11 +1291,16 @@ 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.
+.\" \*(CB\*(FIcmd \*(FC|& getline\*(FR Co-process pipe into \*(FCgetline\*(FR; set \*(FC$0\*(FR, \*(FCNF\*(FR.
.TE
.fi
.in +.2i
.ti -.2i
+\*(CB\*(FIcmd \*(FC|& getline\*(FR
+.br
+Co-process pipe into \*(FCgetline\*(FR; set \*(FC$0\*(FR, \*(FCNF\*(FR.
+.br
+.ti -.2i
\*(FIcmd \*(FC|& getline \*(FIv\*(FR
.br
Co-process pipe into \*(FCgetline\*(FR; set \*(FIv\*(FR.
@@ -1284,35 +1314,35 @@ program. Upon end of the input data,
execute any \*(FCEND\fP rule(s).
.br
.ti -.2i
-\*(CL\*(FCnextfile\fP
+\*(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).\*(CD
+next input file. Update \*(FCFILENAME\fP \*(CBand
+\*(FCARGIND\fP\*(CD, reset \*(FCFNR\fP to 1,
+and start over with the first
+pattern. Upon end
+of input data, execute any \*(FCEND\fP rule(s).
.in -.2i
.sp .5
.fi
\*(FCgetline\*(FR returns 1 on success, 0 on end of file, and \-1 on an error.
-\*(CBUpon an error, \*(FCERRNO\*(FR contains a string describing
+\*(CBAll versions set \*(FCRT\fP.
+Upon an error, \*(FCERRNO\*(FR contains a string describing
the problem.\*(CX
.EB "\s+2\f(HBINPUT CONTROL\*(FR\s0"
-
+.sp .6
.\" --- Output Control
.ES
.fi
.in +.2i
.ti -.2i
-\*(CL\*(FCfflush(\*(FR[\*(FIfile\^\*(FR]\*(FC)\*(FR
+\*(CD\*(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
-(\*(GK and \*(NK)\*(CD.
+with the open output file or pipe \*(FIfile\*(FR.
+If no \*(FIfile\fP, or if
+\*(FIfile\fP is null, then flush all open output files and pipes.
.ti -.2i
\*(FCprint\fP
.br
@@ -1327,7 +1357,7 @@ with \*(FCORS\fP.
.ti -.2i
\*(FCprintf \*(FIfmt\*(FC, \*(FIexpr-list\*(FR
.br
-Format and print (see \fHPrintf Formats\fP below).
+Format and print (see \fHPrintf Formats\fP).
.ti -.2i
\*(FCsystem(\*(FIcmd\*(FC)\*(FR
.br
@@ -1358,7 +1388,7 @@ Print data down a pipeline to \*(FIcmd\*(FR.
Print data down a pipeline to co-process \*(FIcmd\*(FR.\*(CX
.in -.2i
.EB "\s+2\f(HBOUTPUT CONTROL\*(FR\s0"
-
+.sp .6
.\" --- Closing Redirections
.ES
.fi
@@ -1463,7 +1493,8 @@ Only has an effect when the field width is wider
than the value to be printed.
T}
\*(CB\*(FC'\*(FR T{
-Use the locale's thousands separator for \*(FC%d\fP, \*(FC%i\fP, and \*(FC%u\fP.\*(CD
+Use the locale's thousands separator and decimal
+point characters.\*(CD
T}
\*(FIwidth\fP T{
Pad the field to this width. The field is normally
@@ -1474,8 +1505,8 @@ 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{
+ \*(FC%d\*(FR,\|\*(FC%o\*(FR,\|\*(FC%i\fP, \0
+ \*(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{
@@ -1578,17 +1609,20 @@ 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.
+\*(CB\*(FCdiv(\*(FIn\*(FR\*(FC,\*(FI d\*(FR\*(FC,\*(FI res\*(FR\*(FC)\*(FR T{
+Return the result of integer division in \*(FIres\*(FR.\*(CD
+T}
\*(FCexp(\*(FIexpr\*(FC)\*(FR The exponential function (\*(FIe \*(FC^ \*(FIx\*(FR).
\*(FCint(\*(FIexpr\*(FC)\*(FR Truncate 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).
+\*(FCrand()\fP A random number \*(FIN\fP such that 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.
+\*(FCsqrt(\*(FIexpr\*(FC)\*(FR The square root of \*(FIexpr\fP.
\&\*(FCsrand(\*(FR[\*(FIexpr\^\*(FR]\*(FC)\*(FR T{
Use \*(FIexpr\fP as the new seed for the random number
-generator. If no \*(FIexpr\fP, the time of day is used.
-Return the random number
-generator's previous seed.\*(CX
+generator. If no \*(FIexpr\fP, use the time of day.
+Return the \" random number generator's
+previous seed.\*(CX
T}
.TE
.EB "\s+2\f(HBNUMERIC FUNCTIONS\*(FR\s0"
@@ -1640,7 +1674,7 @@ 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
+and \*(FCgsub().\*(FR
.ti -.2i
\*(FCindex(\*(FIs\*(FC, \*(FIt\*(FC)\*(FR
.br
@@ -1669,7 +1703,7 @@ Subscripts
\*(FCa[\*(FIn\^\*(FC, "start"]\*(FR,
and
\*(FCa[\*(FIn\^\*(FC, "length"]\*(FR
-provide the starting index in the string and length
+provide the starting index in the string and length,
respectively, of each matching substring.\*(CD
.ti -.2i
\*(CB\*(FCpatsplit(\*(FIs\*(FC, \*(FIa \*(FR[\*(FC, \*(FIr \*(CB\*(FR[\*(FC, \*(FIseps \*(FR] \*(FR] \*(FC)\*(FR
@@ -1695,7 +1729,7 @@ and return the number of fields. If \*(FIr\fP is omitted, use \*(FCFS\fP
instead.
Clear the \*(FIa\fP \*(CBand \*(FIseps\fP\*(CD first.
Splitting behaves identically to field splitting.
-(See \fHFields\fP, above.)
+(See \fHFields\fP.)
.ti -.2i
\*(FCsprintf(\*(FIfmt\*(FC, \*(FIexpr-list\*(FC)\*(FR
.br
@@ -1715,12 +1749,11 @@ according to \*(FIfmt\*(FR, and return the result.\*(CX
.br
Examine \*(FIs\*(FR, and return its numeric value.
If \*(FIs\*(FR begins with a leading \*(FC0\*(FR,
-\*(FCstrtonum()\*(FR assumes that \*(FIs\*(FR
-is an octal number.
+treat it as 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. Otherwise, the
-number is treated as decimal.\*(CD
+or \*(FC0X\*(FR, treat
+\*(FIs\*(FR as a hexadecimal number. Otherwise,
+treat the number as decimal.\*(CD
.ti -.2i
\*(FCsub(\*(FIr\*(FC, \*(FIs \*(FR[\*(FC, \*(FIt\*(FR]\*(FC)\*(FR
.br
@@ -1752,8 +1785,8 @@ left unchanged.\*(CX
.\" --- Built-in Time Functions
.ES
.fi
-\*(CD\*(GK
-provides the following functions for obtaining time stamps and
+\*(CD\*(GK and \*(MK
+provide the following functions for obtaining time stamps and
formatting them.
.sp .5
.fi
@@ -1775,33 +1808,32 @@ according to the specification in \*(FIformat\*(FR. The
\*(FCsystime()\*(FR.
If \*(FIutc-flag\*(FR
is present and is non-zero or non-null, the result
-is in UTC, otherwise the result is in local time.
-If \*(FItimestamp\fP is missing, the current time of day is used. If
+is in UTC, otherwise it is in local time.
+If \*(FItimestamp\fP is missing, use the current time of day. If
\*(FIformat\fP is missing, use \*(FCPROCINFO["strftime"]\fP.
The default value is
equivalent to the output
-of \*(FIdate\*(FR(1).
+of \*(FIdate\*(FR\^(1).
.ti -.2i
\*(FCsystime()\fP
.br
Return the current time of day as the number of
-seconds since the Epoch.\*(CB
+seconds since the Epoch.\*(CL
.in -.2i
-.EB "\s+2\f(HBTIME FUNCTIONS (\*(GK\f(HB)\*(FR\s0"
+.EB "\s+2\f(HBTIME FUNCTIONS\*(FR\s0"
.sp .6
.\" --- Built-in Bit Manipulation Functions
.ES
.fi
\*(CD\*(GK
-provides the following functions for doing bitwise operations.
+provides the following bit manipulation functions.
.sp .5
.fi
.in +.2i
.ti -.2i
-\*(FCand(\*(FIv1\*(FC, \*(FIv2\*(FC)\*(FR
+\*(FCand(\*(FIv1\*(FC, \*(FIv2\*(FR [\*(FC,\*(FR ... ]\*(FC)\*(FR
.br
-Return the bitwise AND of the values provided by
-\*(FIv1\*(FR and \*(FIv2\*(FR.
+Return the bitwise AND of the arguments.
.ti -.2i
\*(FCcompl(\*(FIval\*(FC)\*(FR
.br
@@ -1813,20 +1845,18 @@ Return the bitwise complement of
Return the value of \*(FIval\*(FR,
shifted left by \*(FIcount\*(FR bits.
.ti -.2i
-\*(FCor(\*(FIv1\*(FC, \*(FIv2\*(FC)\*(FR
+\*(FCor(\*(FIv1\*(FC, \*(FIv2\*(FR [\*(FC,\*(FR ... ]\*(FC)\*(FR
.br
-Return the bitwise OR of the values provided by
-\*(FIv1\*(FR and \*(FIv2\*(FR.
+Return the bitwise OR of the arguments.
.ti -.2i
\*(FCrshift(\*(FIval\*(FC, \*(FIcount\*(FC)\*(FR
.br
Return the value of \*(FIval\*(FR,
shifted right by \*(FIcount\*(FR bits.
.ti -.2i
-\*(FCxor(\*(FIv1\*(FC, \*(FIv2\*(FC)\*(FR
+\*(FCxor(\*(FIv1\*(FC, \*(FIv2\*(FR [\*(FC,\*(FR ... ]\*(FC)\*(FR
.br
-Return the bitwise XOR of the values provided by
-\*(FIv1\*(FR and \*(FIv2\*(FR.\*(CB
+Return the bitwise XOR of the arguments.\*(CB
.in -.2i
.EB "\s+2\f(HBBIT MANIPULATION FUNCTIONS (\*(GK\f(HB)\*(FR\s0"
.sp .6
@@ -1835,16 +1865,15 @@ Return the bitwise XOR of the values provided by
.fi
.in +.2i
.ti -.2i
-\*(CD\*(FCextension(\*(FIlib\*(FC, \*(FIfunc\*(FC)\*(FR
+\*(CD\*(FC@load "\*(FIextension\*(FC"\*(FR
.br
-Dynamically load the shared library
-\*(FIlib\*(FR
-and call
-\*(FIfunc\*(FR
-in it to initialize the library.
+Dynamically load the named \*(FIextension\*(FR.
This adds new built-in functions to \*(GK.
-It returns the value returned by
-\*(FIfunc\*(FR.\*(CB
+.\" The extension should use the API defined by the
+.\" \*(FCgawkapi.h\*(FR header file, as documented in
+.\" the full manual.
+The extension is loaded during the parsing of the program.
+See the manual for details.\*(CB
.in -.2i
.EB "\s+2\f(HBDYNAMIC EXTENSIONS (\*(GK\f(HB)\*(FR\s0"
.BT
@@ -1870,7 +1899,7 @@ provides the following functions for runtime message translation.
.ti -.2i
\*(FCbindtextdomain(\*(FIdirectory \*(FR[\*(FC, \*(FIdomain\*(FR]\*(FC)\*(FR
.br
-Specify the directory where \*(GK looks for the \*(FC\&.mo\*(FR
+Specify the directory where \*(GK looks for the \*(FC\&.gmo\*(FR
files, in case they
will not or cannot be placed in the ``standard'' locations
(e.g., during testing).
@@ -1909,19 +1938,21 @@ to use the current domain.\*(CB
.in -.2i
.EB "\s+2\f(HBINTERNATIONALIZATION (\*(GK\f(HB)\*(FR\s0"
.sp .5
-.\" --- FTP/HTTP Information
+.\" --- FTP/HTTP/GIT Information
.ES
.nf
\*(CDHost: \*(FCftp.gnu.org\*(FR
-File: \*(FC/gnu/gawk/gawk-4.0.0.tar.gz\fP
+File: \*(FC/gnu/gawk/gawk-4.1.1.tar.gz\fP
.in +.2i
.fi
GNU \*(AK (\*(GK). There may be a later version.
.in -.2i
.nf
.sp .4
-\*(FChttp://www.cs.princeton.edu/~bwk/btl.mirror/
-awk.tar.gz\fP
+.\" http://www.cs.princeton.edu/~bwk/btl.mirror/
+.\" awk.tar.gz
+.\" .br
+\*(FCgit clone git://github.com/onetrueawk/awk\fP
.in +.2i
.fi
\*(NK. This version requires an ANSI C compiler;
@@ -1929,9 +1960,6 @@ GCC (the GNU Compiler Collection) works well.
.in -.2i
.nf
.sp .4
-... Host: \*(FCftp.whidbey.net\*(FR
-... File: \*(FC/pub/brennan/mawk1.3.3.tar.gz\fP
-... \*(FChttp://www.skeeve.com/gawk/mawk1.3.3.tar.gz\fP
Host: \*(FCinvisible-island.net\*(FR
File: \*(FC/mawk/mawk.tar.gz\fP
.in +.2i
@@ -1939,13 +1967,13 @@ File: \*(FC/mawk/mawk.tar.gz\fP
Michael Brennan's \*(MK. Thomas Dickey now
maintains it.\*(CX
.in -.2i
-.EB "\s+2\f(HBFTP/HTTP INFORMATION\*(FR\s0"
+.EB "\s+2\f(HBFTP/HTTP/GIT INFORMATION\*(FR\s0"
.sp .5
.\" --- Copying Permissions
.ES
.fi
-\*(CDCopyright \(co 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+\*(CDCopyright \(co 1996\(en2005,
+2007, 2009\(en2014 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
diff --git a/doc/awkforai.txt b/doc/awkforai.txt
index 3fca3204..2908da56 100644
--- a/doc/awkforai.txt
+++ b/doc/awkforai.txt
@@ -1,150 +1,18 @@
-Draft for ACM SIGPLAN Patterns (Language Trends)
+Sun Dec 9 11:58:23 IST 2012
+============================
-1996
+The original of this file was a draft of an article written in 1996 by
+Ronald P. Lui for an ACM Sigplan publication, explaining why he used
+gawk for teaching introductory Artificial Intelligence courses.
-Why GAWK for AI?
+Since it was not clear as to copying permissions and so on, it has been
+removed from the gawk distribution.
-Ronald P. Loui
+A quick web search shows that this same draft is available at
+http://www.cs.wustl.edu/~loui/sigplan and the final article is available
+from the ACM: http://dl.acm.org/citation.cfm?id=242908
-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).
+The article itself is recommended reading.
-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).
+Arnold Robbins
+arnold@skeeve.com
diff --git a/doc/gawk.1 b/doc/gawk.1
index 205eb389..3d5d1812 100644
--- a/doc/gawk.1
+++ b/doc/gawk.1
@@ -1,6 +1,5 @@
.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
@@ -14,7 +13,7 @@
. if \w'\(rq' .ds rq "\(rq
. \}
.\}
-.TH GAWK 1 "May 29 2011" "Free Software Foundation" "Utility Commands"
+.TH GAWK 1 "Aug 03 2014" "Free Software Foundation" "Utility Commands"
.SH NAME
gawk \- pattern scanning and processing language
.SH SYNOPSIS
@@ -33,30 +32,6 @@ gawk \- pattern scanning and processing language
]
.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 .\|.\|.
-.sp
-.B dgawk
-[ \*(PX or \*(GN style options ]
-.B \-f
-.I program-file
-[
-.B \-\^\-
-] file .\|.\|.
.SH DESCRIPTION
.I Gawk
is the \*(GN Project's implementation of the \*(AK programming language.
@@ -67,7 +42,7 @@ This version in turn is based on the description in
by Aho, Kernighan, and Weinberger.
.I Gawk
provides the additional features found in the current version
-of \*(UX
+of Brian Kernighan's
.I awk
and a number of \*(GN-specific extensions.
.PP
@@ -84,27 +59,31 @@ and
.B ARGV
pre-defined \*(AK variables.
.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
+When
+.I gawk
+is invoked with the
+.B \-\^\-profile
+option, it starts gathering profiling statistics
+from the execution of the program.
+.I Gawk
+runs more slowly in this mode, and automatically produces an execution
+profile in the file
.B awkprof.out
when done.
See the
.B \-\^\-profile
option, below.
.PP
-.I Dgawk
-is an
-.I awk
-debugger. Instead of running the program directly, it loads the
+.I Gawk
+also has an integrated debugger. An interactive debugging session can
+be started by supplying the
+.B \-\^\-debug
+option to the command line. In this mode of execution,
+.I gawk
+loads the
AWK source code and then prompts for debugging commands.
-Unlike
-.IR gawk " and " pgawk ", " dgawk
-only processes AWK program source provided with the
+.I Gawk
+can only debug AWK program source provided with the
.B \-f
option.
The debugger is documented in \*(EP.
@@ -117,8 +96,8 @@ while long options start with \*(lq\-\^\-\*(rq.
Long options are provided for both \*(GN-specific features and
for \*(PX-mandated features.
.PP
-.IR Gawk -
-specific options are typically used in long-option form.
+.IR Gawk -specific
+options are typically used in long-option form.
Arguments to long options are either joined with the option
by an
.B =
@@ -127,7 +106,7 @@ next command line argument.
Long options may be abbreviated, as long as the abbreviation
remains unique.
.PP
-Additionally, each long option has a corresponding short
+Additionally, every long option has a corresponding short
option, so that the option's functionality may be used from
within
.B #!
@@ -178,34 +157,7 @@ to the variable
before execution of the program begins.
Such variable values are available to the
.B BEGIN
-block of an \*(AK program.
-.ig
-.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 an earlier version of the Bell Laboratories
-research version of \*(UX
-.IR awk .
-They are ignored by
-.IR gawk ,
-since
-.I gawk
-has no pre-defined limits.
-(Current versions of the Bell Laboratories
-.I awk
-no longer accept them.)
-..
+rule of an \*(AK program.
.TP
.PD 0
.B \-b
@@ -218,6 +170,7 @@ process strings as multibyte characters.
The
.B "\-\^\-posix"
option overrides this one.
+.bp
.TP
.PD 0
.B \-c
@@ -228,7 +181,7 @@ Run in
.I compatibility
mode. In compatibility mode,
.I gawk
-behaves identically to \*(UX
+behaves identically to Brian Kernighan's
.IR awk ;
none of the \*(GN-specific extensions are recognized.
.\" The use of
@@ -273,6 +226,19 @@ names like
and so on.)
.TP
.PD 0
+\fB\-D\fR[\fIfile\fR]
+.TP
+.PD
+\fB\-\^\-debug\fR[\fB=\fIfile\fR]
+Enable debugging of \*(AK programs.
+By default, the debugger reads commands interactively from the keyboard
+(standard input).
+The optional
+.IR file
+argument specifies a file with a list
+of commands for the debugger to execute non-interactively.
+.TP
+.PD 0
.BI "\-e " program-text
.TP
.PD
@@ -331,6 +297,35 @@ the standard output.
these options cause an immediate, successful exit.)
.TP
.PD 0
+.BI "\-i " include-file
+.TP
+.PD
+.BI \-\^\-include " include-file"
+Load an awk source library.
+This searches for the library using the
+.B AWKPATH
+environment variable. If the initial search fails, another attempt will
+be made after appending the
+.B \&.awk
+suffix. The file will be loaded only
+once (i.e., duplicates are eliminated), and the code does not constitute
+the main program source.
+.TP
+.PD 0
+.BI "\-l " lib
+.TP
+.PD
+.BI \-\^\-load " lib"
+Load a shared library
+.IR lib .
+This searches for the library using the
+.B AWKLIBPATH
+environment variable. If the initial search fails, another attempt will
+be made after appending the default shared library suffix for the platform.
+The library initialization routine is expected to be named
+.BR dl_load() .
+.TP
+.PD 0
.BR "\-L " [ \fIvalue\fR ]
.TP
.PD
@@ -348,6 +343,16 @@ only warnings about things that are
actually invalid are issued. (This is not fully implemented yet.)
.TP
.PD 0
+.B \-M
+.TP
+.PD
+.B \-\^\-bignum
+Force arbitrary precision arithmetic on numbers. This option has
+no effect if
+.I gawk
+is not compiled to use the GNU MPFR and MP libraries.
+.TP
+.PD 0
.B \-n
.TP
.PD
@@ -387,30 +392,41 @@ users.
..
.TP
.PD 0
+\fB\-o\fR[\fIfile\fR]
+.TP
+.PD
+\fB\-\^\-pretty-print\fR[\fB=\fIfile\fR]
+Output a pretty printed version of the program to
+.IR file .
+If no
+.I file
+is provided,
+.I gawk
+uses a file named
+.B awkprof.out
+in the current directory.
+.TP
+.PD 0
.B \-O
.TP
.PD
.B \-\^\-optimize
Enable optimizations upon the internal representation of the program.
-Currently, this includes just simple constant-folding. The
+Currently, this includes simple constant-folding, and tail call
+elimination for recursive functions. The
.I gawk
maintainer hopes to add additional optimizations over time.
.TP
.PD 0
-\fB\-p\fR[\fIprof_file\fR]
+\fB\-p\fR[\fIprof-file\fR]
.TP
.PD
-\fB\-\^\-profile\fR[\fB=\fIprof_file\fR]
-Send profiling data to
-.IR prof_file .
+\fB\-\^\-profile\fR[\fB=\fIprof-file\fR]
+Start a profiling session, and send the 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
+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
@@ -454,11 +470,6 @@ cannot be used in place of
.B ^
and
.BR ^= .
-.TP
-\(bu
-The
-.B fflush()
-function is not available.
.RE
.TP
.PD 0
@@ -479,16 +490,7 @@ and
.I egrep
consistent with each other.
They are enabled by default, but this option remains for use with
-.BR \-\^-traditional .
-.TP
-.PD 0
-.B \-R
-.TP
-.PD
-.BI \-\^\-command " file"
-.I Dgawk
-only. Read stored debugger commands from
-.IR file .
+.BR \-\^\-traditional .
.TP
.PD 0
.BI \-S
@@ -501,7 +503,7 @@ in sandbox mode, disabling the
.B system()
function, input redirection with
.BR getline ,
-output redirection with
+output redirection with
.BR print " and " printf ,
and loading dynamic extensions.
Command execution (through pipelines) is also disabled.
@@ -514,7 +516,7 @@ This effectively blocks a script from accessing local resources
.PD
.B \-\^\-lint\-old
Provide warnings about constructs that are
-not portable to the original version of Unix
+not portable to the original version of \*(UX
.IR awk .
.TP
.PD 0
@@ -548,6 +550,10 @@ 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.
+.PP
+For \*(PX compatibility, the
+.B \-W
+option may be used, followed by the name of a long option.
.SH AWK PROGRAM EXECUTION
.PP
An \*(AK program consists of a sequence of pattern-action statements
@@ -555,6 +561,9 @@ and optional function definitions.
.RS
.PP
\fB@include "\fIfilename\fB"
+.br
+\fB@load "\fIfilename\fB"
+.br
\fIpattern\fB { \fIaction statements\fB }\fR
.br
\fBfunction \fIname\fB(\fIparameter list\fB) { \fIstatements\fB }\fR
@@ -584,14 +593,26 @@ functions with command line programs.
In addition, lines beginning with
.B @include
may be used to include other source files into your program,
-making library use even easier.
+making library use even easier. This is equivalent
+to using the
+.B \-i
+option.
+.PP
+Lines beginning with
+.B @load
+may be used to load shared libraries into your program. This is equivalent
+to using the
+.B \-l
+option.
.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
+and
+.B \-i
+options. 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
@@ -600,6 +621,17 @@ If a file name given to the
.B \-f
option contains a \*(lq/\*(rq character, no path search is performed.
.PP
+The environment variable
+.B AWKLIBPATH
+specifies a search path to use when finding source files named with
+the
+.B \-l
+option. If this variable does not exist, the default path is
+\fB"/usr/local/lib/gawk"\fR.
+(The actual directory may vary, depending upon how
+.I gawk
+was built and installed.)
+.PP
.I Gawk
executes \*(AK programs in the following order.
First,
@@ -613,7 +645,7 @@ Then,
.I gawk
executes the code in the
.B BEGIN
-block(s) (if any),
+rule(s) (if any),
and then proceeds to read
each file named in the
.B ARGV
@@ -631,7 +663,7 @@ will be assigned the value
.IR val .
(This happens after any
.B BEGIN
-block(s) have been run.)
+rule(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.
@@ -662,16 +694,17 @@ For each record in the input,
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.
+For each pattern that the record matches,
+.I gawk
+executes the associated
+.IR action .
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).
+rule(s) (if any).
.SS Command Line Directories
.PP
According to POSIX, files named on the
@@ -699,6 +732,10 @@ 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.
+.I Gawk
+provides true arrays of arrays; see
+.BR Arrays ,
+below.
Several pre-defined variables are set as a program
runs; these are described as needed and summarized below.
.SS Records
@@ -782,13 +819,13 @@ each field is made up of text that matches that regular expression. In
this case, the regular expression describes the fields themselves,
instead of the text that separates the fields.
Assigning a new value to
-.BR FS
+.B FS
or
.B FIELDWIDTHS
overrides the use of
.BR FPAT .
.PP
-Each field in the input record may be referenced by its position,
+Each field in the input record may be referenced by its position:
.BR $1 ,
.BR $2 ,
and so on.
@@ -810,14 +847,14 @@ 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
+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
+creates any intervening fields with the null string as their values, and
causes the value of
.B $0
to be recomputed, with the fields being separated by the value of
@@ -880,12 +917,18 @@ The conversion format for numbers, \fB"%.6g"\fR, by default.
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
+\fB"/home/arnold"\fR).
+.sp
+In POSIX mode,
+changing this array does not affect the environment seen by programs which
.I gawk
spawns via redirection or the
.B system()
function.
+Otherwise,
+.I gawk
+updates its real environment so that programs it spawns see
+the changes.
.TP
.B ERRNO
If a system error occurs either doing a redirection for
@@ -920,7 +963,7 @@ However,
.B FILENAME
is undefined inside the
.B BEGIN
-block
+rule
(unless set by
.BR getline ).
.TP
@@ -946,6 +989,17 @@ The input field separator, a space by default. See
.BR Fields ,
above.
.TP
+.B FUNCTAB
+An array whose indices and corresponding values
+are the names of all the user-defined
+or extension functions in the program.
+.BR NOTE :
+You may not use the
+.B delete
+statement with the
+.B FUNCTAB
+array.
+.TP
.B IGNORECASE
Controls the case-sensitivity of all regular expression
and string operations. If
@@ -1022,6 +1076,10 @@ The output field separator, a space by default.
.B ORS
The output record separator, by default a newline.
.TP
+.B PREC
+The working precision of arbitrary precision floating-point
+numbers, 53 by default.
+.TP
.B PROCINFO
The elements of this array provide access to information about the
running \*(AK program.
@@ -1037,7 +1095,7 @@ The following elements are guaranteed to be available:
.RS
.TP \w'\fBPROCINFO["version"]\fR'u+1n
\fBPROCINFO["egid"]\fP
-the value of the
+The value of the
.IR getegid (2)
system call.
.TP
@@ -1046,7 +1104,7 @@ The default time format string for
.BR strftime() .
.TP
\fBPROCINFO["euid"]\fP
-the value of the
+The value of the
.IR geteuid (2)
system call.
.TP
@@ -1061,22 +1119,57 @@ or \fB"FIELDWIDTHS"\fP if field splitting with
.B FIELDWIDTHS
is in effect.
.TP
+\fBPROCINFO["identifiers"]\fP
+A subarray, indexed by the names of all identifiers used in the
+text of the AWK program.
+The values indicate what
+.I gawk
+knows about the identifiers after it has finished parsing the program; they are
+.I not
+updated while the program runs.
+For each identifier, the value of the element is one of the following:
+.RS
+.TP
+\fB"array"\fR
+The identifier is an array.
+.TP
+\fB"builtin"\fR
+The identifier is a built-in function.
+.TP
+\fB"extension"\fR
+The identifier is an extension function loaded via
+.B @load
+or
+.BR \-l .
+.TP
+\fB"scalar"\fR
+The identifier is a scalar.
+.TP
+\fB"untyped"\fR
+The identifier is untyped (could be used as a scalar or array,
+.I gawk
+doesn't know yet).
+.TP
+\fB"user"\fR
+The identifier is a user-defined function.
+.RE
+.TP
\fBPROCINFO["gid"]\fP
-the value of the
+The value of the
.IR getgid (2)
system call.
.TP
\fBPROCINFO["pgrpid"]\fP
-the process group ID of the current process.
+The process group ID of the current process.
.TP
\fBPROCINFO["pid"]\fP
-the process ID of the current process.
+The process ID of the current process.
.TP
\fBPROCINFO["ppid"]\fP
-the parent process ID of the current process.
+The parent process ID of the current process.
.TP
\fBPROCINFO["uid"]\fP
-the value of the
+The value of the
.IR getuid (2)
system call.
.TP
@@ -1102,11 +1195,11 @@ and
\fB"@unsorted"\fR.
The value can also be the name of any comparison function defined
as follows:
-.PP
-.RS
+.sp
+.in +5m
\fBfunction cmp_func(i1, v1, i2, v2)\fR
-.RE
-.PP
+.in -5m
+.sp
where
.I i1
and
@@ -1120,11 +1213,64 @@ corresponding values of the two elements being compared.
It should return a number less than, equal to, or greater than 0,
depending on how the elements of the array are to be ordered.
.TP
+\fBPROCINFO["input", "READ_TIMEOUT"]\fP
+The timeout in milliseconds for reading data from
+.IR input ,
+where
+.I input
+is a redirection string or a filename. A value of zero or
+less than zero means no timeout.
+.TP
+\fBPROCINFO["mpfr_version"]\fP
+The version of the GNU MPFR library used for arbitrary precision
+number support in
+.IR gawk .
+This entry is not present if MPFR support is not compiled into
+.IR gawk .
+.TP
+\fBPROCINFO["gmp_version"]\fP
+The version of the GNU MP library used for arbitrary precision
+number support in
+.IR gawk .
+This entry is not present if MPFR support is not compiled into
+.IR gawk .
+.TP
+\fBPROCINFO["prec_max"]\fP
+The maximum precision supported by the GNU MPFR library for
+arbitrary precision floating-point numbers.
+This entry is not present if MPFR support is not compiled into
+.IR gawk .
+.TP
+\fBPROCINFO["prec_min"]\fP
+The minimum precision allowed by the GNU MPFR library for
+arbitrary precision floating-point numbers.
+This entry is not present if MPFR support is not compiled into
+.IR gawk .
+.TP
+\fBPROCINFO["api_major"]\fP
+The major version of the extension API.
+This entry is not present if loading dynamic extensions is not available.
+.TP
+\fBPROCINFO["api_minor"]\fP
+The minor version of the extension API.
+This entry is not present if loading dynamic extensions is not available.
+.TP
\fBPROCINFO["version"]\fP
the version of
.IR gawk .
.RE
.TP
+.B ROUNDMODE
+The rounding mode to use for arbitrary precision arithmetic on
+numbers, by default \fB"N"\fR (IEEE-754 roundTiesToEven mode).
+The accepted values are
+\fB"N"\fR or \fB"n"\fR for roundTiesToEven,
+\fB"U"\fR or \fB"u"\fR for roundTowardPositive,
+\fB"D"\fR or \fB"d"\fR for roundTowardNegative,
+\fB"Z"\fR or \fB"z"\fR for roundTowardZero,
+and if your version of GNU MPFR library supports it,
+\fB"A"\fR or \fB"a"\fR for roundTiesToAway.
+.TP
.B RS
The input record separator, by default a newline.
.TP
@@ -1152,6 +1298,32 @@ The length of the string matched by
The character used to separate multiple subscripts in array
elements, by default \fB"\e034"\fR.
.TP
+.B SYMTAB
+An array whose indices are the names of all currently defined
+global variables and arrays in the program. The array may be used
+for indirect access to read or write the value of a variable:
+.sp
+.ft B
+.nf
+.in +5m
+foo = 5
+SYMTAB["foo"] = 4
+print foo # prints 4
+.fi
+.ft R
+.in -5m
+.sp
+The
+.B isarray()
+function may be used to test if an element in
+.B SYMTAB
+is an array.
+You may not use the
+.B delete
+statement with the
+.B SYMTAB
+array.
+.TP
.B TEXTDOMAIN
The text domain of the \*(AK program; used to find the localized
translations for the program's strings.
@@ -1180,7 +1352,7 @@ x[i, j, k] = "hello, world\en"
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.
+are associative, i.e., indexed by string values.
.PP
The special operator
.B in
@@ -1204,6 +1376,11 @@ The
construct may also be used in a
.B for
loop to iterate over all the elements of an array.
+However, the
+.B "(i, j) in array"
+construct only works in tests, not in
+.B for
+loops.
.PP
An element may be deleted from an array using the
.B delete
@@ -1217,6 +1394,7 @@ just by specifying the array name without a subscript.
supports true multidimensional arrays. It does not require that
such arrays be ``rectangular'' as in C or C++.
For example:
+.sp
.RS
.ft B
.nf
@@ -1226,6 +1404,18 @@ a[2][2] = 7
.fi
.ft
.RE
+.PP
+.BR NOTE :
+You may need to tell
+.I gawk
+that an array element is really a subarray in order to use it where
+.I gawk
+expects an array (such as in the second argument to
+.BR split() ).
+You can do this by creating an element in the subarray and then
+deleting it with the
+.B delete
+statement.
.SS Variable Typing And Conversion
.PP
Variables and fields
@@ -1237,6 +1427,9 @@ it will be treated as a string.
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
+Uninitialized variables have the numeric value 0 and the string value ""
+(the null, or empty, string).
+.PP
When a string must be converted to a number, the conversion is accomplished
using
.IR strtod (3).
@@ -1267,7 +1460,7 @@ has a string value of \fB"12"\fR and not \fB"12.00"\fR.
.BR NOTE :
When operating in POSIX mode (such as with the
.B \-\^\-posix
-command line option),
+option),
beware that locale settings may interfere with the way
decimal numbers are treated: the decimal separator of the numbers you
are feeding to
@@ -1304,9 +1497,6 @@ 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
You may use C-style octal and hexadecimal constants in your AWK
program source code.
@@ -1332,28 +1522,28 @@ A literal backslash.
The \*(lqalert\*(rq character; usually the \s-1ASCII\s+1 \s-1BEL\s+1 character.
.TP
.B \eb
-backspace.
+Backspace.
.TP
.B \ef
-form-feed.
+Form-feed.
.TP
.B \en
-newline.
+Newline.
.TP
.B \er
-carriage return.
+Carriage return.
.TP
.B \et
-horizontal tab.
+Horizontal tab.
.TP
.B \ev
-vertical tab.
+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
+As in ISO 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.
@@ -1452,10 +1642,10 @@ The action parts of all
patterns are merged as if all the statements had
been written in a single
.B BEGIN
-block. They are executed before any
+rule. They are executed before any
of the input is read. Similarly, all the
.B END
-blocks are merged,
+rules are merged,
and executed when all the input is exhausted (or when an
.B exit
statement is executed).
@@ -1478,7 +1668,7 @@ Inside the
.B BEGINFILE
rule, the value of
.B ERRNO
-will be the empty string if the file could be opened successfully.
+will be the empty string if the file was opened successfully.
Otherwise, there is some problem with the file and the code should
use
.B nextfile
@@ -1530,58 +1720,59 @@ Regular expressions are the extended kind found in
They are composed of characters as follows:
.TP "\w'\fB[^\fIabc.\|.\|.\fB]\fR'u+2n"
.I c
-matches the non-metacharacter
+Matches the non-metacharacter
.IR c .
.TP
.I \ec
-matches the literal character
+Matches the literal character
.IR c .
.TP
.B .
-matches any character
+Matches any character
.I including
newline.
.TP
.B ^
-matches the beginning of a string.
+Matches the beginning of a string.
.TP
.B $
-matches the end of a string.
+Matches the end of a string.
.TP
.BI [ abc.\|.\|. ]
-character list, matches any of the characters
+A character list: matches any of the characters
.IR abc.\|.\|. .
+You may include a range of characters by separating them with a dash.
.TP
\fB[^\fIabc.\|.\|.\fB]\fR
-negated character list, matches any character except
+A negated character list: matches any character except
.IR abc.\|.\|. .
.TP
.IB r1 | r2
-alternation: matches either
+Alternation: matches either
.I r1
or
.IR r2 .
.TP
.I r1r2
-concatenation: matches
+Concatenation: matches
.IR r1 ,
and then
.IR r2 .
.TP
.IB r\^ +
-matches one or more
+Matches one or more
.IR r\^ "'s."
.TP
.IB r *
-matches zero or more
+Matches zero or more
.IR r\^ "'s."
.TP
.IB r\^ ?
-matches zero or one
+Matches zero or one
.IR r\^ "'s."
.TP
.BI ( r )
-grouping: matches
+Grouping: matches
.IR r .
.TP
.PD 0
@@ -1612,37 +1803,38 @@ is repeated at least
times.
.TP
.B \ey
-matches the empty string at either the beginning or the
+Matches the empty string at either the beginning or the
end of a word.
.TP
.B \eB
-matches the empty string within a word.
+Matches the empty string within a word.
.TP
.B \e<
-matches the empty string at the beginning of a word.
+Matches the empty string at the beginning of a word.
.TP
.B \e>
-matches the empty string at the end of a word.
+Matches the empty string at the end of a word.
.TP
.B \es
-matches any whitespace character.
+Matches any whitespace character.
.TP
.B \eS
-matches any nonwhitespace character.
+Matches any nonwhitespace character.
.TP
.B \ew
-matches any word-constituent character (letter, digit, or underscore).
+Matches any word-constituent character (letter, digit, or underscore).
.TP
.B \eW
-matches any character that is not word-constituent.
+Matches any character that is not word-constituent.
.TP
.B \e`
-matches the empty string at the beginning of a buffer (string).
+Matches the empty string at the beginning of a buffer (string).
.TP
.B \e'
-matches the empty string at the end of a buffer.
+Matches the empty string at the end of a buffer.
.PP
-The escape sequences that are valid in string constants (see below)
+The escape sequences that are valid in string constants (see
+.BR "String Constants" )
are also valid in regular expressions.
.PP
.I "Character classes"
@@ -1791,7 +1983,7 @@ interprets characters in regular expressions.
No options
In the default case,
.I gawk
-provide all the facilities of
+provides all the facilities of
\*(PX regular expressions and the \*(GN regular expression operators described above.
.TP
.B \-\^\-posix
@@ -1802,7 +1994,7 @@ matches a literal
.BR w ).
.TP
.B \-\^\-traditional
-Traditional Unix
+Traditional \*(UX
.I awk
regular expressions are matched. The \*(GN operators
are not special, and interval expressions are not available.
@@ -1824,7 +2016,7 @@ and input/output statements
available are patterned after those in C.
.SS Operators
.PP
-The operators in \*(AK, in order of decreasing precedence, are
+The operators in \*(AK, in order of decreasing precedence, are:
.PP
.TP "\w'\fB*= /= %= ^=\fR'u+1n"
.BR ( \&.\|.\|. )
@@ -1876,7 +2068,7 @@ Only use one on the right-hand side. The expression
has the same meaning as \fB(($0 ~ /foo/) ~ \fIexp\fB)\fR.
This is usually
.I not
-what was intended.
+what you want.
.TP
.B in
Array membership.
@@ -1952,7 +2144,8 @@ Set
from next input record; set
.BR NF ,
.BR NR ,
-.BR FNR .
+.BR FNR ,
+.BR RT .
.TP
.BI "getline <" file
Set
@@ -1960,20 +2153,23 @@ Set
from next record of
.IR file ;
set
-.BR NF .
+.BR NF ,
+.BR RT .
.TP
.BI getline " var"
Set
.I var
from next input record; set
.BR NR ,
-.BR FNR .
+.BR FNR ,
+.BR RT .
.TP
.BI getline " var" " <" file
Set
.I var
from next record of
-.IR file .
+.IR file ,
+.BR RT .
.TP
\fIcommand\fB | getline \fR[\fIvar\fR]
Run
@@ -1982,7 +2178,8 @@ piping the output either into
.B $0
or
.IR var ,
-as above.
+as above, and
+.BR RT .
.TP
\fIcommand\fB |& getline \fR[\fIvar\fR]
Run
@@ -1992,7 +2189,8 @@ piping the output either into
.B $0
or
.IR var ,
-as above.
+as above, and
+.BR RT .
Co-processes are a
.I gawk
extension.
@@ -2004,9 +2202,12 @@ below.)
.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
+\*(AK program.
+Upon reaching the end of the input data,
+.I gawk
+executes any
.B END
-block(s), if any, are executed.
+rule(s).
.TP
.B "nextfile"
Stop processing the current input file. The next input record read
@@ -2017,33 +2218,32 @@ and
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
+\*(AK program.
+Upon reaching the end of the input data,
+.I gawk
+executes any
.B END
-block(s), if any, are executed.
+rule(s).
.TP
.B print
Print the current record.
-The output record is terminated with the value of the
-.B ORS
-variable.
+The output record is terminated with the value of
+.BR ORS .
.TP
.BI print " expr-list"
Print 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.
+Each expression is separated by the value of
+.BR OFS .
+The output record is terminated with the value of
+.BR ORS .
.TP
.BI print " expr-list" " >" file
Print 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.
+Each expression is separated by the value of
+.BR OFS .
+The output record is terminated with the value of
+.BR ORS .
.TP
.BI printf " fmt, expr-list"
Format and print.
@@ -2064,9 +2264,7 @@ Flush any buffers associated with the open output file or pipe
.IR file .
If
.I file
-is missing, then flush standard output.
-If
-.I file
+is missing or if it
is the null string,
then flush all open output files and pipes.
.PP
@@ -2089,14 +2287,14 @@ Sends data to a co-process or socket.
below.)
.PP
The
-.BR getline
+.B getline
command returns 1 on success, 0 on end of file, and \-1 on an error.
Upon an error,
.B ERRNO
-contains a string describing the problem.
+is set to a string describing the problem.
.PP
.BR NOTE :
-Failure in opening a two-way socket will result in a non-fatal error being
+Failure in opening a two-way socket results in a non-fatal error being
returned to the calling function. If using a pipe, co-process, or socket to
.BR getline ,
or from
@@ -2133,7 +2331,7 @@ A decimal number (the integer part).
.TP
.BR %e , " %E"
A floating point number of the form
-.BR [\-]d.dddddde[+\^\-]dd .
+[\fB\-\fP]\fId\fB.\fIdddddd\^\fBe\fR[\fB+\-\fR]\fIdd\fR.
The
.B %E
format uses
@@ -2143,7 +2341,7 @@ instead of
.TP
.BR %f , " %F"
A floating point number of the form
-.BR [\-]ddd.dddddd .
+[\fB\-\fP]\fIddd\fB.\fIdddddd\fR.
If the system library supports it,
.B %F
is available as well. This is like
@@ -2234,9 +2432,9 @@ For
and
.BR %X ,
supply a leading
-.BR 0x
+.B 0x
or
-.BR 0X
+.B 0X
for
a nonzero result.
For
@@ -2262,11 +2460,20 @@ This applies only to the numeric output formats.
This flag only has an effect when the field width is wider than the
value to be printed.
.TP
+.B '
+A single quote character instructs
+.I gawk
+to insert the locale's thousands-separator character
+into decimal numbers, and to also use the locale's
+decimal point character with floating point formats.
+This requires correct locale support in the C library
+and in the definition of the current locale.
+.TP
.I width
The field should be padded to this width. The field is normally padded
-with spaces. If the
+with spaces. With the
.B 0
-flag has been used, it is padded with zeroes.
+flag, it is padded with zeroes.
.TP
.BI \&. prec
A number that specifies the precision to use when printing.
@@ -2301,15 +2508,15 @@ The dynamic
.I width
and
.I prec
-capabilities of the \*(AN C
+capabilities of the ISO C
.B printf()
routines are supported.
A
.B *
in place of either the
-.B width
+.I width
or
-.B prec
+.I prec
specifications causes their values to be taken from
the argument list to
.B printf
@@ -2340,6 +2547,9 @@ 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 \-
+The standard input.
+.TP
.B /dev/stdin
The standard input.
.TP
@@ -2425,6 +2635,23 @@ Return the cosine of
.IR expr ,
which is in radians.
.TP
+.BI div( num ", " denom ", " result )
+Truncate
+.I num
+and
+.I denom
+to integers. Return the quotient of
+.I num
+divided by
+.I denom
+in \fIresult\fB["quotient"]\fR
+and the remainder in
+in \fIresult\fB["remainder"]\fR.
+This is a
+.I gawk
+extension, primarily of value when working with
+arbitrarily large integers.
+.TP
.BI exp( expr )
The exponential function.
.TP
@@ -2446,7 +2673,8 @@ Return the sine of
which is in radians.
.TP
.BI sqrt( expr )
-The square root function.
+Return the square root of
+.IR expr .
.TP
\&\fBsrand(\fR[\fIexpr\^\fR]\fB)\fR
Use
@@ -2454,7 +2682,7 @@ Use
as the new seed for the random number generator. If no
.I expr
is provided, use the time of day.
-The return value is the previous seed for the random
+Return the previous seed for the random
number generator.
.SS String Functions
.PP
@@ -2479,7 +2707,7 @@ with sequential
integers starting with 1. If the optional
destination array
.I d
-is specified, then
+is specified,
first duplicate
.I s
into
@@ -2517,7 +2745,7 @@ a second array if you wish to preserve the original.
The purpose of the optional string
.I how
is the same as described in
-.BR asort()
+.B asort()
above.
.TP
\fBgensub(\fIr\fB, \fIs\fB, \fIh \fR[\fB, \fIt\fR]\fB)\fR
@@ -2589,7 +2817,7 @@ to get a literal
(This must be typed as \fB"\e\e&"\fP;
see \*(EP
for a fuller discussion of the rules for
-.BR &'s
+.BR & 's
and backslashes in the replacement text of
.BR sub() ,
.BR gsub() ,
@@ -2605,6 +2833,8 @@ or 0 if
.I t
is not present.
(This implies that character indices start at one.)
+It is a fatal error to use a regexp constant for
+.IR t .
.TP
\fBlength(\fR[\fIs\fR]\fB)
Return the length of the string
@@ -2675,11 +2905,11 @@ Element values are the portions of
that matched
.IR r .
The value of
-.I seps[i]
+.BI seps[ i ]
is the separator that appeared in
front of
-.IR a[i+1] .
-If
+.BI a[ i +1]\fR.
+\&\fRIf
.I r
is omitted,
.B FPAT
@@ -2712,33 +2942,33 @@ The arrays
and
.I seps
are cleared first.
-.I seps[i]
+.BI seps[ i ]
is the field separator matched by
.I r
between
-.I a[i]
+.BI a[ i ]
and
-.IR a[i+1] .
-If
+.BI a[ i +1]\fR.
+\&\fRIf
.I r
is a single space, then leading whitespace in
.I s
goes into the extra array element
-.I seps[0]
+.B seps[0]
and trailing whitespace goes into the extra array element
-.IR seps[n] ,
+.BI seps[ n ]\fR,
where
.I n
-is the return value of
-.IR "split(s, a, r, seps)" .
+is the return value of
+.BI split( s ", " a ", " r ", " seps )\fR.
Splitting behaves identically to field splitting, described above.
.TP
.BI sprintf( fmt , " expr-list" )
-Prints
+Print
.I expr-list
according to
.IR fmt ,
-and returns the resulting string.
+and return the resulting string.
.TP
.BI strtonum( str )
Examine
@@ -2749,10 +2979,8 @@ If
begins
with a leading
.BR 0 ,
-.B strtonum()
-assumes that
-.I str
-is an octal number.
+treat it
+as an octal number.
If
.I str
begins
@@ -2760,11 +2988,9 @@ with a leading
.B 0x
or
.BR 0X ,
-.B strtonum()
-assumes that
-.I str
-is a hexadecimal number.
-Otherwise, decimal is assumed.
+treat it
+as a hexadecimal number.
+Otherwise, assume it is a decimal number.
.TP
\fBsub(\fIr\fB, \fIs \fR[\fB, \fIt\fR]\fB)\fR
Just like
@@ -2877,7 +3103,7 @@ The default format is available in
.BR PROCINFO["strftime"] .
See the specification for the
.B strftime()
-function in \*(AN C for the format conversions that are
+function in ISO C for the format conversions that are
guaranteed to be available.
.TP
.B systime()
@@ -2893,11 +3119,9 @@ 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 .
+\fBand(\fIv1\fB, \fIv2 \fR[, ...]\fB)\fR
+Return the bitwise AND of the values provided in the argument list.
+There must be at least two.
.TP
\fBcompl(\fIval\fB)\fR
Return the bitwise complement of
@@ -2910,11 +3134,9 @@ 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 .
+\fBor(\fIv1\fB, \fIv2 \fR[, ...]\fB)\fR
+Return the bitwise OR of the values provided in the argument list.
+There must be at least two.
.TP
\fBrshift(\fIval\fB, \fIcount\fB)\fR
Return the value of
@@ -2923,11 +3145,9 @@ 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 .
+\fBxor(\fIv1\fB, \fIv2 \fR[, ...]\fB)\fR
+Return the bitwise XOR of the values provided in the argument list.
+There must be at least two.
.PP
.SS Type Function
The following function is for use with multidimensional arrays.
@@ -2945,7 +3165,7 @@ For full details, see \*(EP.
Specify the directory where
.I gawk
looks for the
-.B \&.mo
+.B \&.gmo
files, in case they
will not or cannot be placed in the ``standard'' locations
(e.g., during testing).
@@ -2989,7 +3209,7 @@ 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
+\fBdcngettext(\fIstring1\fB, \fIstring2\fB, \fInumber \fR[\fB, \fIdomain \fR[\fB, \fIcategory\fR]]\fB)\fR
Return the plural form used for
.I number
of the translation of
@@ -3073,7 +3293,7 @@ sign, like so:
.RS
.ft B
.nf
-function myfunc()
+function myfunc()
{
print "myfunc called"
\&.\|.\|.
@@ -3087,6 +3307,8 @@ function myfunc()
.fi
.ft R
.RE
+As of version 4.1.2, this works with user-defined functions,
+built-in functions, and extension functions.
.PP
If
.B \-\^\-lint
@@ -3099,31 +3321,20 @@ Calling an undefined function at run time is a fatal error.
The word
.B func
may be used in place of
-.BR function .
+.BR function ,
+although this is deprecated.
.SH DYNAMICALLY LOADING NEW FUNCTIONS
You can dynamically add new built-in functions to the running
.I gawk
-interpreter.
+interpreter with the
+.B @load
+statement.
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.
-Return the value returned by
-.IR function .
-.PP
-Using this feature at the C level is not pretty, but
-it is unlikely to go away. Additional mechanisms may
-be added at some point.
+see \*(EP.
.SH SIGNALS
-.I pgawk
-accepts two signals.
+The
+.I gawk
+profiler accepts two signals.
.B SIGUSR1
causes it to dump a profile and function call stack to the
profile file, which is either
@@ -3133,7 +3344,7 @@ or whatever file was named with the
option. It then continues to run.
.B SIGHUP
causes
-.I pgawk
+.I gawk
to dump the profile and function call stack and then exit.
.SH INTERNATIONALIZATION
.PP
@@ -3173,16 +3384,16 @@ action to assign a value to the
.B TEXTDOMAIN
variable to set the text domain to a name associated with your program:
.sp
-.RS
+.in +5m
.ft B
BEGIN { TEXTDOMAIN = "myprog" }
.ft R
-.RE
+.in -5m
.sp
This allows
.I gawk
to find the
-.B \&.mo
+.B \&.gmo
file associated with your program.
Without this step,
.I gawk
@@ -3205,12 +3416,12 @@ functions in your program, as appropriate.
Run
.B "gawk \-\^\-gen\-pot \-f myprog.awk > myprog.pot"
to generate a
-.B \&.po
+.B \&.pot
file for your program.
.TP
5.
Provide appropriate translations, and build and install the corresponding
-.B \&.mo
+.B \&.gmo
files.
.PP
The internationalization features are described in full detail in \*(EP.
@@ -3218,13 +3429,13 @@ The internationalization features are described in full detail in \*(EP.
A primary goal for
.I gawk
is compatibility with the \*(PX standard, as well as with the
-latest version of \*(UX
+latest version of Brian Kernighan's
.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
+but are part of the Brian Kernighan's version of
.IR awk ,
and are in the \*(PX standard.
.PP
@@ -3232,19 +3443,20 @@ 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
+rule 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
+rule 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.)
+(This feature was agreed upon by both the Bell Laboratories
+and the \*(GN developers.)
.PP
When processing arguments,
.I gawk
@@ -3275,14 +3487,14 @@ the
array; the
.BR \ea ,
and
-.BR \ev
+.B \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
+built-in functions (from the Bell Laboratories version); and the ISO C conversion specifications in
.B printf
(done first in the Bell Laboratories version).
.SH HISTORICAL FEATURES
@@ -3317,7 +3529,7 @@ issues a warning about its use if
is specified on the command line.
.SH GNU EXTENSIONS
.I Gawk
-has a number of extensions to \*(PX
+has a too-large number of extensions to \*(PX
.IR awk .
They are described in this section. All the extensions described here
can be disabled by
@@ -3345,22 +3557,22 @@ environment variable is not special.
.\" POSIX and language recognition issues
.TP
\(bu
-There is no facility for doing file inclusion
+There is no facility for doing file inclusion
.RI ( gawk 's
.B @include
mechanism).
.TP
\(bu
-The
-.B \ex
-escape sequence.
-(Disabled with
-.BR \-\^\-posix .)
+There is no facility for dynamically adding new functions
+written in C
+.RI ( gawk 's
+.B @load
+mechanism).
.TP
\(bu
The
-.B fflush()
-function.
+.B \ex
+escape sequence.
(Disabled with
.BR \-\^\-posix .)
.TP
@@ -3461,16 +3673,17 @@ and
The ability to pass an array to
.BR length() .
.\" 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.
+.\" (As of 2012, these are in POSIX)
+.\" .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
@@ -3498,12 +3711,6 @@ functions.
.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()
@@ -3572,15 +3779,37 @@ The
environment variable can be used to provide a list of directories that
.I gawk
searches when looking for files named via the
-.B \-f
+.BR \-f ,
+.RB \-\^\-file ,
+.B \-i
and
-.B \-\^\-file
+.B \-\^\-include
+options. If the initial search fails, the path is searched again after
+appending
+.B \&.awk
+to the filename.
+.PP
+The
+.B AWKLIBPATH
+environment variable can be used to provide a list of directories that
+.I gawk
+searches when looking for files named via the
+.B \-l
+and
+.B \-\^\-load
options.
.PP
-For socket communication, two special environment variables can be used to control the number of retries
-.RB ( GAWK_SOCK_RETRIES ),
-and the interval between retries
-.RB ( GAWK_MSEC_SLEEP ).
+The
+.B GAWK_READ_TIMEOUT
+environment variable can be used to specify a timeout
+in milliseconds for reading input from a terminal, pipe
+or two-way communication including sockets.
+.PP
+For connection to a remote host via socket,
+.B GAWK_SOCK_RETRIES
+controls the number of retries, and
+.B GAWK_MSEC_SLEEP
+and the interval between retries.
The interval is in milliseconds. On systems that do not support
.IR usleep (3),
the value is rounded up to an integral number of seconds.
@@ -3627,7 +3856,7 @@ status is 2. On non-POSIX systems, this value may be mapped to
.SH VERSION INFORMATION
This man page documents
.IR gawk ,
-version 4.0.
+version 4.1.
.SH AUTHORS
The original version of \*(UX
.I awk
@@ -3649,22 +3878,12 @@ 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 maintains the port to MS-DOS using DJGPP.
-Eli Zaretskii maintains the port to MS-Windows using MinGW.
-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.
-Andreas Buening now maintains the OS/2 port.
-The late Fred Fish supplied support for the Amiga,
-and Martin Brown provided the BeOS port.
-Stephen Davies provided the original Tandem port, and
-Matthew Woehlke provided changes for Tandem's POSIX-compliant systems.
-Dave Pitts provided the port to z/OS.
+See \*(EP for a full list of the contributors to
+.I gawk
+and its documentation.
.PP
See the
-.I README
+.B README
file in the
.I gawk
distribution for up-to-date information about maintainers
@@ -3705,6 +3924,7 @@ While the
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.
+Really.
.PP
If you're using a GNU/Linux or BSD-based system,
you may wish to submit a bug report to the vendor of your distribution.
@@ -3717,13 +3937,9 @@ 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 SEE ALSO
.IR egrep (1),
+.IR sed (1),
.IR getpid (2),
.IR getppid (2),
.IR getpgrp (2),
@@ -3739,7 +3955,7 @@ Alfred V. Aho, Brian W. Kernighan, Peter J. Weinberger,
Addison-Wesley, 1988. ISBN 0-201-07981-X.
.PP
\*(EP,
-Edition 4.0, shipped with the
+Edition 4.1, shipped with the
.I gawk
source.
The current version of this document is available online at
@@ -3780,13 +3996,13 @@ Run an external command for particular lines of data:
.ft R
.fi
.SH ACKNOWLEDGEMENTS
-Brian Kernighan of Bell Laboratories
+Brian Kernighan
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, 2007, 2009,
-2010, 2011
+2010, 2011, 2012, 2013, 2014
Free Software Foundation, Inc.
.PP
Permission is granted to make and distribute verbatim copies of
diff --git a/doc/gawk.info b/doc/gawk.info
index b92d1b87..cf827935 100644
--- a/doc/gawk.info
+++ b/doc/gawk.info
@@ -1,4 +1,4 @@
-This is gawk.info, produced by makeinfo version 4.8 from gawk.texi.
+This is gawk.info, produced by makeinfo version 4.13 from gawk.texi.
INFO-DIR-SECTION Text creation and manipulation
START-INFO-DIR-ENTRY
@@ -9,31 +9,27 @@ 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, 2007, 2009, 2010, 2011 Free Software
-Foundation, Inc.
+ Copyright (C) 1989, 1991, 1992, 1993, 1996-2005, 2007, 2009-2015
+Free Software Foundation, Inc.
- This is Edition 4 of `GAWK: Effective AWK Programming: A User's
-Guide for GNU Awk', for the 4.0.0 (or later) version of the GNU
+ This is Edition 4.1 of `GAWK: Effective AWK Programming: A User's
+Guide for GNU Awk', for the 4.1.2 (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.3 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".
+Invariant Sections being "GNU General Public License", with the
+Front-Cover Texts being "A GNU Manual", and with the Back-Cover Texts
+as in (a) below. A copy of the license is included in the section
+entitled "GNU Free Documentation License".
- a. "A GNU Manual"
-
- b. "You have the freedom to copy and modify this GNU manual. Buying
- copies from the FSF supports it in developing GNU and promoting
- software freedom."
+ a. The FSF's Back-Cover Text is: "You have the freedom to copy and
+ modify this GNU manual."

-File: gawk.info, Node: Top, Next: Foreword, Up: (dir)
+File: gawk.info, Node: Top, Next: Foreword3, Up: (dir)
General Introduction
********************
@@ -41,33 +37,30 @@ 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, 2007, 2009, 2010, 2011 Free Software
-Foundation, Inc.
+ Copyright (C) 1989, 1991, 1992, 1993, 1996-2005, 2007, 2009-2015
+Free Software Foundation, Inc.
- This is Edition 4 of `GAWK: Effective AWK Programming: A User's
-Guide for GNU Awk', for the 4.0.0 (or later) version of the GNU
+ This is Edition 4.1 of `GAWK: Effective AWK Programming: A User's
+Guide for GNU Awk', for the 4.1.2 (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.3 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"
+Invariant Sections being "GNU General Public License", with the
+Front-Cover Texts being "A GNU Manual", and with the Back-Cover Texts
+as in (a) below. A copy of the license is included in the section
+entitled "GNU Free Documentation License".
- b. "You have the freedom to copy and modify this GNU manual. Buying
- copies from the FSF supports it in developing GNU and promoting
- software freedom."
+ a. The FSF's Back-Cover Text is: "You have the freedom to copy and
+ modify this GNU manual."
* Menu:
-* Foreword:: Some nice words about this
+* Foreword3:: Some nice words about this
Info file.
+* Foreword4:: More nice words.
* Preface:: What this Info file is about; brief
history and acknowledgments.
* Getting Started:: A basic introduction to using
@@ -87,20 +80,24 @@ texts being (a) (see below), and with the Back-Cover Texts being (b)
* 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'.
* Library Functions:: A Library of `awk' Functions.
* Sample Programs:: Many `awk' programs with complete
explanations.
-* Debugger:: The `dgawk' debugger.
+* Advanced Features:: Stuff for advanced users, specific to
+ `gawk'.
+* Internationalization:: Getting `gawk' to speak your
+ language.
+* Debugger:: The `gawk' debugger.
+* Arbitrary Precision Arithmetic:: Arbitrary precision arithmetic with
+ `gawk'.
+* Dynamic Extensions:: Adding new built-in functions to
+ `gawk'.
* Language History:: The evolution of the `awk'
language.
* Installation:: Installing `gawk' under various
operating systems.
-* Notes:: Notes about `gawk' extensions and
- possible future work.
+* Notes:: Notes about adding things to `gawk'
+ and possible future work.
* Basic Concepts:: A very quick introduction to programming
concepts.
* Glossary:: An explanation of some unfamiliar terms.
@@ -109,478 +106,609 @@ texts being (a) (see below), and with the Back-Cover Texts being (b)
* 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.
-* DOS Quoting:: Quoting in Windows Batch Files.
-* 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.
-* Command Line:: How to run `awk'.
-* Options:: Command-line options and their
- meanings.
-* Other Arguments:: Input file names and variable
- assignments.
-* Naming Standard Input:: How to specify standard input with
- other files.
-* Environment Variables:: The environment variables
- `gawk' uses.
-* AWKPATH Variable:: Searching directories for `awk'
- programs.
-* Other Environment Variables:: The environment variables.
-* Exit Status:: `gawk''s exit status.
-* Include Files:: Including other files into your
- program.
-* Obsolete:: Obsolete Options and/or features.
-* Undocumented:: Undocumented Options and Features.
-* Regexp Usage:: How to Use Regular Expressions.
-* Escape Sequences:: How to write nonprinting characters.
-* Regexp Operators:: Regular Expression Operators.
-* Bracket Expressions:: 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.
-* 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.
-* Default Field Splitting:: How fields are normally separated.
-* 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.
-* Splitting By Content:: Defining Fields By Content
-* 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.
-* Command line directories:: What happens if you put a directory on
- the command line.
-* 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 Network:: Special files for network
- communications.
-* Special Caveats:: Things to watch out for.
-* Close Files And Pipes:: Closing Input and Output Files and
- Pipes.
-* Values:: Constants, Variables, and Regular
- Expressions.
-* 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.
-* All Operators:: `gawk''s operators.
-* 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 and Conditions:: Testing for true and false.
-* 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.
-* Variable Typing:: String type versus numeric type.
-* Comparison Operators:: The comparison operators.
-* POSIX String Comparison:: String comparison with POSIX rules.
-* 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.
-* Locales:: How the locale affects things.
-* 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.
-* BEGINFILE/ENDFILE:: Two special patterns for advanced
- control.
-* 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 Basics:: The basics of arrays.
-* 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.
-* Arrays of Arrays:: True multidimensional arrays.
-* 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.
-* Type Functions:: Functions for type information.
-* 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.
-* Calling A Function:: Don't use spaces.
-* Variable Scope:: Controlling variable scope.
-* Pass By Value/Reference:: Passing parameters.
-* Return Statement:: Specifying the value a function
- returns.
-* Dynamic Typing:: How variable types can change at
- runtime.
-* Indirect Calls:: Choosing the function to call 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.
-* Array Sorting:: Facilities for controlling array
- traversal and sorting arrays.
-* Controlling Array Traversal:: How to use PROCINFO["sorted_in"].
-* Controlling Scanning With A Function:: Using a function to control scanning.
-* Controlling Scanning:: Controlling the order in which arrays
- are scanned.
-* Array Sorting Functions:: How to use `asort()' and
- `asorti()'.
-* Two-way I/O:: Two-way communications with another
- process.
-* TCP/IP Networking:: Using `gawk' for network
- programming.
-* Profiling:: Profiling your `awk' programs.
-* Library Names:: How to best name private global
- variables in library functions.
-* General Functions:: Functions that are of general use.
-* 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.
-* 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.
-* Walking Arrays:: A function to walk arrays of arrays.
-* 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.
-* Anagram Program:: Finding anagrams from a dictionary.
-* Signature Program:: People do amazing things with too much
- time on their hands.
-* Debugging:: Introduction to `dgawk'.
-* Debugging Concepts:: Debugging In General.
-* Debugging Terms:: Additional Debugging Concepts.
-* Awk Debugging:: Awk Debugging.
-* Sample dgawk session:: Sample `dgawk' session.
-* dgawk invocation:: `dgawk' Invocation.
-* Finding The Bug:: Finding The Bug.
-* List of Debugger Commands:: Main `dgawk' Commands.
-* Breakpoint Control:: Control of breakpoints.
-* Dgawk Execution Control:: Control of execution.
-* Viewing And Changing Data:: Viewing and changing data.
-* Dgawk Stack:: Dealing with the stack.
-* Dgawk Info:: Obtaining information about the program
- and the debugger state.
-* Miscellaneous Dgawk Commands:: Miscellaneous Commands.
-* Readline Support:: Readline Support.
-* Dgawk Limitations:: Limitations and future plans.
-* 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 Brian Kernighan's
- version of `awk'.
-* POSIX/GNU:: The extensions in `gawk' not in
- POSIX `awk'.
-* Common Extensions:: Common Extensions Summary.
-* Ranges and Locales:: How locales used to affect regexp
- ranges.
-* 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.
-* 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 Testing:: Testing `gawk' on PC systems.
-* PC Using:: Running `gawk' on MS-DOS,
- Windows32 and OS/2.
-* Cygwin:: Building and running `gawk' for
- Cygwin.
-* MSYS:: Using `gawk' In The MSYS
- Environment.
-* 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 Old Gawk:: An old version comes with some VMS
- systems.
-* 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'.
-* Accessing The Source:: Accessing the Git repository.
-* 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.
-* Plugin License:: A note about licensing.
-* 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.
-* String Conversion Precision:: The String Value Can Lie.
-* Unexpected Results:: Floating Point Numbers Are Not Abstract
- Numbers.
-* POSIX Floating Point Problems:: Standards Versus Existing Practice.
-
- 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.
-
-File: gawk.info, Node: Foreword, Next: Preface, Prev: Top, Up: Top
-
-Foreword
-********
+* 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 the
+ keyboard 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.
+* DOS Quoting:: Quoting in Windows Batch Files.
+* 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.
+* Intro Summary:: Summary of the introduction.
+* Command Line:: How to run `awk'.
+* Options:: Command-line options and their
+ meanings.
+* Other Arguments:: Input file names and variable
+ assignments.
+* Naming Standard Input:: How to specify standard input with
+ other files.
+* Environment Variables:: The environment variables
+ `gawk' uses.
+* AWKPATH Variable:: Searching directories for
+ `awk' programs.
+* AWKLIBPATH Variable:: Searching directories for
+ `awk' shared libraries.
+* Other Environment Variables:: The environment variables.
+* Exit Status:: `gawk''s exit status.
+* Include Files:: Including other files into your
+ program.
+* Loading Shared Libraries:: Loading shared libraries into your
+ program.
+* Obsolete:: Obsolete Options and/or features.
+* Undocumented:: Undocumented Options and Features.
+* Invoking Summary:: Invocation summary.
+* Regexp Usage:: How to Use Regular Expressions.
+* Escape Sequences:: How to write nonprinting characters.
+* Regexp Operators:: Regular Expression Operators.
+* Bracket Expressions:: What can go between `[...]'.
+* Leftmost Longest:: How much text matches.
+* Computed Regexps:: Using Dynamic Regexps.
+* GNU Regexp Operators:: Operators specific to GNU software.
+* Case-sensitivity:: How to do case-insensitive matching.
+* Regexp Summary:: Regular expressions summary.
+* Records:: Controlling how data is split into
+ records.
+* awk split records:: How standard `awk' splits
+ records.
+* gawk split records:: How `gawk' splits 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.
+* Default Field Splitting:: How fields are normally separated.
+* 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.
+* Full Line Fields:: Making the full line be a single
+ field.
+* Field Splitting Summary:: Some final points and a summary table.
+* Constant Size:: Reading constant width data.
+* Splitting By Content:: Defining Fields By Content
+* Multiple Line:: Reading multiline 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.
+* Read Timeout:: Reading input with a timeout.
+* Command-line directories:: What happens if you put a directory on
+ the command line.
+* Input Summary:: Input summary.
+* Input Exercises:: Exercises.
+* 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 FD:: Special files for I/O.
+* Special Files:: File name interpretation in
+ `gawk'. `gawk' allows
+ access to inherited file descriptors.
+* Other Inherited Files:: Accessing other open files with
+ `gawk'.
+* 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.
+* Output Summary:: Output summary.
+* Output Exercises:: Exercises.
+* Values:: Constants, Variables, and Regular
+ Expressions.
+* 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.
+* Strings And Numbers:: How `awk' Converts Between
+ Strings And Numbers.
+* Locale influences conversions:: How the locale may affect conversions.
+* All Operators:: `gawk''s operators.
+* 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 and Conditions:: Testing for true and false.
+* 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.
+* Variable Typing:: String type versus numeric type.
+* Comparison Operators:: The comparison operators.
+* POSIX String Comparison:: String comparison with POSIX rules.
+* 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.
+* Locales:: How the locale affects things.
+* Expressions Summary:: Expressions summary.
+* 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.
+* BEGINFILE/ENDFILE:: Two special patterns for advanced
+ control.
+* 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 predefined 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'.
+* Pattern Action Summary:: Patterns and Actions summary.
+* Array Basics:: The basics of arrays.
+* 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.
+* Controlling Scanning:: Controlling the order in which arrays
+ are scanned.
+* Numeric Array Subscripts:: How to use numbers as subscripts in
+ `awk'.
+* Uninitialized Subscripts:: Using Uninitialized variables as
+ subscripts.
+* Delete:: The `delete' statement removes an
+ element from an array.
+* Multidimensional:: Emulating multidimensional arrays in
+ `awk'.
+* Multiscanning:: Scanning multidimensional arrays.
+* Arrays of Arrays:: True multidimensional arrays.
+* Arrays Summary:: Summary of arrays.
+* 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.
+* Type Functions:: Functions for type information.
+* 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.
+* Calling A Function:: Don't use spaces.
+* Variable Scope:: Controlling variable scope.
+* Pass By Value/Reference:: Passing parameters.
+* Return Statement:: Specifying the value a function
+ returns.
+* Dynamic Typing:: How variable types can change at
+ runtime.
+* Indirect Calls:: Choosing the function to call at
+ runtime.
+* Functions Summary:: Summary of functions.
+* Library Names:: How to best name private global
+ variables in library functions.
+* General Functions:: Functions that are of general use.
+* 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.
+* Getlocaltime Function:: A function to get formatted times.
+* Readfile Function:: A function to read an entire file at
+ once.
+* Shell Quoting:: A function to quote strings for the
+ shell.
+* 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.
+* Walking Arrays:: A function to walk arrays of arrays.
+* Library Functions Summary:: Summary of library functions.
+* Library Exercises:: Exercises.
+* 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.
+* Anagram Program:: Finding anagrams from a dictionary.
+* Signature Program:: People do amazing things with too much
+ time on their hands.
+* Programs Summary:: Summary of programs.
+* Programs Exercises:: Exercises.
+* Nondecimal Data:: Allowing nondecimal input data.
+* Array Sorting:: Facilities for controlling array
+ traversal and sorting arrays.
+* Controlling Array Traversal:: How to use PROCINFO["sorted_in"].
+* Array Sorting Functions:: How to use `asort()' and
+ `asorti()'.
+* Two-way I/O:: Two-way communications with another
+ process.
+* TCP/IP Networking:: Using `gawk' for network
+ programming.
+* Profiling:: Profiling your `awk' programs.
+* Advanced Features Summary:: Summary of advanced features.
+* 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.
+* I18N Summary:: Summary of I18N stuff.
+* Debugging:: Introduction to `gawk'
+ debugger.
+* Debugging Concepts:: Debugging in General.
+* Debugging Terms:: Additional Debugging Concepts.
+* Awk Debugging:: Awk Debugging.
+* Sample Debugging Session:: Sample debugging session.
+* Debugger Invocation:: How to Start the Debugger.
+* Finding The Bug:: Finding the Bug.
+* List of Debugger Commands:: Main debugger commands.
+* Breakpoint Control:: Control of Breakpoints.
+* Debugger Execution Control:: Control of Execution.
+* Viewing And Changing Data:: Viewing and Changing Data.
+* Execution Stack:: Dealing with the Stack.
+* Debugger Info:: Obtaining Information about the
+ Program and the Debugger State.
+* Miscellaneous Debugger Commands:: Miscellaneous Commands.
+* Readline Support:: Readline support.
+* Limitations:: Limitations and future plans.
+* Debugging Summary:: Debugging summary.
+* Computer Arithmetic:: A quick intro to computer math.
+* Math Definitions:: Defining terms used.
+* MPFR features:: The MPFR features in `gawk'.
+* FP Math Caution:: Things to know.
+* Inexactness of computations:: Floating point math is not exact.
+* Inexact representation:: Numbers are not exactly represented.
+* Comparing FP Values:: How to compare floating point values.
+* Errors accumulate:: Errors get bigger as they go.
+* Getting Accuracy:: Getting more accuracy takes some work.
+* Try To Round:: Add digits and round.
+* Setting precision:: How to set the precision.
+* Setting the rounding mode:: How to set the rounding mode.
+* Arbitrary Precision Integers:: Arbitrary Precision Integer Arithmetic
+ with `gawk'.
+* POSIX Floating Point Problems:: Standards Versus Existing Practice.
+* Floating point summary:: Summary of floating point discussion.
+* Extension Intro:: What is an extension.
+* Plugin License:: A note about licensing.
+* Extension Mechanism Outline:: An outline of how it works.
+* Extension API Description:: A full description of the API.
+* Extension API Functions Introduction:: Introduction to the API functions.
+* General Data Types:: The data types.
+* Memory Allocation Functions:: Functions for allocating memory.
+* Constructor Functions:: Functions for creating values.
+* Registration Functions:: Functions to register things with
+ `gawk'.
+* Extension Functions:: Registering extension functions.
+* Exit Callback Functions:: Registering an exit callback.
+* Extension Version String:: Registering a version string.
+* Input Parsers:: Registering an input parser.
+* Output Wrappers:: Registering an output wrapper.
+* Two-way processors:: Registering a two-way processor.
+* Printing Messages:: Functions for printing messages.
+* Updating `ERRNO':: Functions for updating `ERRNO'.
+* Requesting Values:: How to get a value.
+* Accessing Parameters:: Functions for accessing parameters.
+* Symbol Table Access:: Functions for accessing global
+ variables.
+* Symbol table by name:: Accessing variables by name.
+* Symbol table by cookie:: Accessing variables by ``cookie''.
+* Cached values:: Creating and using cached values.
+* Array Manipulation:: Functions for working with arrays.
+* Array Data Types:: Data types for working with arrays.
+* Array Functions:: Functions for working with arrays.
+* Flattening Arrays:: How to flatten arrays.
+* Creating Arrays:: How to create and populate arrays.
+* Extension API Variables:: Variables provided by the API.
+* Extension Versioning:: API Version information.
+* Extension API Informational Variables:: Variables providing information about
+ `gawk''s invocation.
+* Extension API Boilerplate:: Boilerplate code for using the API.
+* Finding Extensions:: How `gawk' finds compiled
+ extensions.
+* Extension Example:: Example C code for an extension.
+* 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.
+* Extension Samples:: The sample extensions that ship with
+ `gawk'.
+* Extension Sample File Functions:: The file functions sample.
+* Extension Sample Fnmatch:: An interface to `fnmatch()'.
+* Extension Sample Fork:: An interface to `fork()' and
+ other process functions.
+* Extension Sample Inplace:: Enabling in-place file editing.
+* Extension Sample Ord:: Character to value to character
+ conversions.
+* Extension Sample Readdir:: An interface to `readdir()'.
+* Extension Sample Revout:: Reversing output sample output
+ wrapper.
+* Extension Sample Rev2way:: Reversing data sample two-way
+ processor.
+* Extension Sample Read write array:: Serializing an array to a file.
+* Extension Sample Readfile:: Reading an entire file into a string.
+* Extension Sample Time:: An interface to `gettimeofday()'
+ and `sleep()'.
+* Extension Sample API Tests:: Tests for the API.
+* gawkextlib:: The `gawkextlib' project.
+* Extension summary:: Extension summary.
+* Extension Exercises:: Exercises.
+* 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 Brian Kernighan's
+ version of `awk'.
+* POSIX/GNU:: The extensions in `gawk' not
+ in POSIX `awk'.
+* Feature History:: The history of the features in
+ `gawk'.
+* Common Extensions:: Common Extensions Summary.
+* Ranges and Locales:: How locales used to affect regexp
+ ranges.
+* Contributors:: The major contributors to
+ `gawk'.
+* History summary:: History summary.
+* 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.
+* Shell Startup Files:: Shell convenience functions.
+* Additional Configuration Options:: Other compile-time options.
+* Configuration Philosophy:: How it's all supposed to work.
+* Non-Unix Installation:: Installation on Other Operating
+ Systems.
+* 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 Testing:: Testing `gawk' on PC systems.
+* PC Using:: Running `gawk' on MS-DOS,
+ Windows32 and OS/2.
+* Cygwin:: Building and running `gawk'
+ for Cygwin.
+* MSYS:: Using `gawk' In The MSYS
+ Environment.
+* VMS Installation:: Installing `gawk' on VMS.
+* VMS Compilation:: How to compile `gawk' under
+ VMS.
+* VMS Dynamic Extensions:: Compiling `gawk' dynamic
+ extensions on VMS.
+* VMS Installation Details:: How to install `gawk' under
+ VMS.
+* VMS Running:: How to run `gawk' under VMS.
+* VMS GNV:: The VMS GNV Project.
+* VMS Old Gawk:: An old version comes with some VMS
+ systems.
+* Bugs:: Reporting Problems and Bugs.
+* Other Versions:: Other freely available `awk'
+ implementations.
+* Installation summary:: Summary of installation.
+* Compatibility Mode:: How to disable certain `gawk'
+ extensions.
+* Additions:: Making Additions To `gawk'.
+* Accessing The Source:: Accessing the Git repository.
+* Adding Code:: Adding code to the main body of
+ `gawk'.
+* New Ports:: Porting `gawk' to a new
+ operating system.
+* Derived Files:: Why derived files are kept in the Git
+ repository.
+* Future Extensions:: New features that may be implemented
+ one day.
+* Implementation Limitations:: Some limitations of the
+ implementation.
+* Extension Design:: Design notes about the extension API.
+* Old Extension Problems:: Problems with the old mechanism.
+* Extension New Mechanism Goals:: Goals for the new mechanism.
+* Extension Other Design Decisions:: Some other design decisions.
+* Extension Future Growth:: Some room for future growth.
+* Old Extension Mechanism:: Some compatibility for old extensions.
+* Notes summary:: Summary of implementation notes.
+* Basic High Level:: The high level view.
+* Basic Data Typing:: A very quick intro to data types.
+
+ To my parents, for their love, and for the wonderful example they
+set for me.
+
+ To my wife Miriam, for making me complete. Thank you for building
+your life together with me.
+
+ To our children Chana, Rivka, Nachum and Malka, for enrichening our
+lives in innumerable ways.
+
+
+File: gawk.info, Node: Foreword3, Next: Foreword4, Prev: Top, Up: Top
+
+Foreword to the Third Edition
+*****************************
Arnold Robbins and I are good friends. We were introduced in 1990 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.
+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.
+on Unix, I found the gray AWK book, a.k.a. Alfred V. Aho, Brian W.
+Kernighan, and Peter J. Weinberger's `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 a 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
+language described in the gray book. I discovered that my computer had
+"old `awk'" and the 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.
@@ -591,14 +719,15 @@ 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
+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.
+support language extensions added after publication of `The AWK
+Programming Language'.
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
@@ -612,17 +741,17 @@ a definitive reference to the AWK language as defined by the 1987 Bell
Laboratories 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
+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.
+in C. Consequently, there is often a payoff to prototyping 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
@@ -637,32 +766,67 @@ want to learn how, then read this book.
Michael Brennan
Author of `mawk'
- March, 2001
+ March 2001
+
+
+File: gawk.info, Node: Foreword4, Next: Preface, Prev: Foreword3, Up: Top
+
+Foreword to the Fourth Edition
+******************************
+
+Some things don't change. Thirteen years ago I wrote: "If you use AWK
+or want to learn how, then read this book." True then, and still true
+today.
+
+ Learning to use a programming language is about more than mastering
+the syntax. One needs to acquire an understanding of how to use the
+features of the language to solve practical programming problems. A
+focus of this book is many examples that show how to use AWK.
+
+ Some things do change. Our computers are much faster and have more
+memory. Consequently, speed and storage inefficiencies of a high-level
+language matter less. Prototyping in AWK and then rewriting in C for
+performance reasons happens less, because more often the prototype is
+fast enough.
+
+ Of course, there are computing operations that are best done in C or
+C++. With `gawk' 4.1 and later, you do not have to choose between
+writing your program in AWK or in C/C++. You can write most of your
+program in AWK and the aspects that require C/C++ capabilities can be
+written in C/C++, and then the pieces glued together when the `gawk'
+module loads the C/C++ module as a dynamic plug-in. *note Dynamic
+Extensions::, has all the details, and, as expected, many examples to
+help you learn the ins and outs.
+
+ I enjoy programming in AWK and had fun (re)reading this book. I
+think you will too.
+
+ Michael Brennan
+ Author of `mawk'
+ October 2014

-File: gawk.info, Node: Preface, Next: Getting Started, Prev: Foreword, Up: Top
+File: gawk.info, Node: Preface, Next: Getting Started, Prev: Foreword4, 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 Java 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.
+may need to make changes wherever certain patterns appear, but leave the
+rest of the file alone. Such jobs are often easy 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'; if you invoke it
-with the proper options or environment variables (*note Options::), it
-is fully compatible with the POSIX(1) specification of the `awk'
-language and with the Unix version of `awk' maintained by Brian
-Kernighan. This means that all properly written `awk' programs should
-work with `gawk'. Thus, we usually don't distinguish between `gawk'
-and other `awk' implementations.
+with the proper options or environment variables, it is fully
+compatible with the POSIX(1) specification of the `awk' language and
+with the Unix version of `awk' maintained by Brian Kernighan. This
+means that all properly written `awk' programs should work with `gawk'.
+So most of the time, we don't distinguish between `gawk' and other
+`awk' implementations.
- Using `awk' allows you to:
+ Using `awk' you can:
* Manage small, personal databases
@@ -670,7 +834,7 @@ and other `awk' implementations.
* Validate data
- * Produce indexes and perform other document preparation tasks
+ * Produce indexes and perform other document-preparation tasks
* Experiment with algorithms that you can adapt later to other
computer languages
@@ -683,6 +847,10 @@ and other `awk' implementations.
* Perform simple network communications
+ * Profile and debug `awk' programs
+
+ * Extend the language with functions written in C or C++
+
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',(2) as well as basic shell facilities,
@@ -691,13 +859,11 @@ 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 Intel(R)-architecture
-PC-based computers up through large-scale systems, such as Crays.
-`gawk' has also been ported to Mac OS X, Microsoft Windows (all
-versions) and OS/2 PCs, and VMS. (Some other, obsolete systems to
-which `gawk' was once ported are no longer supported and the code for
-those systems has been removed.)
+of `awk' called `gawk' (which stands for "GNU `awk'"). `gawk' runs on
+a broad range of Unix systems, ranging from Intel-architecture PC-based
+computers up through large-scale systems. `gawk' has also been ported
+to Mac OS X, Microsoft Windows (all versions) and OS/2 PCs, and
+OpenVMS.(3)
* Menu:
@@ -714,33 +880,36 @@ those systems has been removed.)
---------- Footnotes ----------
- (1) The 2008 POSIX standard can be found online at
+ (1) The 2008 POSIX standard is accessible online at
`http://www.opengroup.org/onlinepubs/9699919799/'.
- (2) These commands are available on POSIX-compliant systems, as well
-as on traditional Unix-based systems. If you are using some other
+ (2) These utilities 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.
+ (3) Some other, obsolete systems to which `gawk' was once ported are
+no longer supported and the code for those systems has been removed.
+

File: gawk.info, Node: History, Next: Names, Up: Preface
History of `awk' and `gawk'
===========================
- Recipe For A Programming Language
+ 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.
+ 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.
+ 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
+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
@@ -749,18 +918,18 @@ V Release 3.1 (1987). The version in System V Release 4 (1989) 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 1994, 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
+Both the `gawk' designers and the original `awk' designers at Bell
+Laboratories provided feedback for the POSIX specification.
+
+ Paul Rubin wrote `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 1994, I became the primary maintainer. Current development
+focuses on bug fixes, performance improvements, standards compliance,
+and, occasionally, new features.
+
+ In May 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
@@ -769,9 +938,9 @@ the `gawk' distribution). His code finally became part of the main
John Haque rewrote the `gawk' internals, in the process providing an
`awk'-level debugger. This version became available as `gawk' version
-4.0, in 2011.
+4.0 in 2011.
- *Note Contributors::, for a complete list of those who made
+ *Note Contributors::, for a full list of those who have made
important contributions to `gawk'.

@@ -781,23 +950,20 @@ 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, there are systems with 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 we
-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'!)
+provided in *note Language History::. The language described in this
+Info file is often referred to as "new `awk'." By analogy, the
+original version of `awk' is referred to as "old `awk'."
+
+ Today, on most systems, when you run the `awk' utility you get some
+version of new `awk'.(1) If your system's standard `awk' is the old
+one, you will see something like this if you try the test program:
+
+ $ awk 1 /dev/null
+ error--> awk: syntax error near line 1
+ error--> awk: bailing out near line 1
+
+In this case, you should find a version of new `awk', or just install
+`gawk'!
Throughout this Info file, whenever we refer to a language feature
that should be available in any complete implementation of POSIX `awk',
@@ -806,7 +972,9 @@ specific to the GNU implementation, we use the term `gawk'.
---------- Footnotes ----------
- (1) Often, these systems use `gawk' for their `awk' implementation!
+ (1) Only Solaris systems still use an old `awk' for the default
+`awk' utility. A more modern `awk' lives in `/usr/xpg6/bin' on these
+systems.

File: gawk.info, Node: This Manual, Next: Conventions, Prev: Names, Up: Preface
@@ -826,96 +994,132 @@ programming language.
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.
+it notes any `gawk' features that are not in the POSIX standard for
+`awk'.
- There are subsections labeled 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."
+ There are sidebars 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 "sidebar."
Most of the time, the examples use complete `awk' programs. Some of
the more advanced sections show only the part of the `awk' program that
-illustrates the concept currently being described.
+illustrates the concept being described.
+
+ Although 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.
+
+ This Info file is split into several parts, as follows:
+
+ * Part I describes the `awk' language and the `gawk' program in
+ detail. It starts with the basics, and continues through all of
+ the features of `awk'. It contains the following chapters:
+
+ - *note Getting Started::, provides the essentials you need to
+ know to begin using `awk'.
+
+ - *note Invoking Gawk::, describes how to run `gawk', the
+ meaning of its command-line options, and how it finds `awk'
+ program source files.
+
+ - *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. Network I/O is also briefly introduced here.
+
+ - *note Printing::, describes how `awk' programs can produce
+ output with `print' and `printf'.
- 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 Expressions::, describes expressions, which are the
+ basic building blocks for getting most things done in a
+ program.
- *Note Getting Started::, provides the essentials you need to know to
-begin using `awk'.
+ - *note Patterns and Actions::, describes how to write patterns
+ for matching records, actions for doing something when a
+ record is matched, and the predefined variables `awk' and
+ `gawk' use.
- *Note Invoking Gawk::, describes how to run `gawk', the meaning of
-its command-line options, and how it finds `awk' program source files.
+ - *note Arrays::, covers `awk''s one-and-only data structure:
+ the associative array. Deleting array elements and whole
+ arrays is described, as well as sorting arrays in `gawk'.
+ The major node also describes how `gawk' provides arrays of
+ arrays.
- *Note Regexp::, introduces regular expressions in general, and in
-particular the flavors supported by POSIX `awk' and `gawk'.
+ - *note Functions::, describes the built-in functions `awk' and
+ `gawk' provide, as well as how to define your own functions.
+ It also discusses how `gawk' lets you call functions
+ indirectly.
- *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. Network I/O is also
-briefly introduced here.
+ * Part II shows how to use `awk' and `gawk' for problem solving.
+ There is lots of code here for you to read and learn from. This
+ part contains the following chapters:
- *Note Printing::, describes how `awk' programs can produce output
-with `print' and `printf'.
+ - *note Library Functions::, provides a number of functions
+ meant to be used from main `awk' programs.
- *Note Expressions::, describes expressions, which are the basic
-building blocks for getting most things done in a program.
+ - *note Sample Programs::, provides many sample `awk' programs.
- *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.
+ Reading these two chapters allows you to see `awk' solving real
+ problems.
- *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'. It also describes how
-`gawk' provides arrays of arrays.
+ * Part III focuses on features specific to `gawk'. It contains the
+ following chapters:
- *Note Functions::, describes the built-in functions `awk' and `gawk'
-provide, as well as how to define your own functions.
+ - *note Advanced Features::, describes a number of advanced
+ features. Of particular note are the abilities to control
+ the order of array traversal, have two-way communications
+ with another process, perform TCP/IP networking, and profile
+ your `awk' programs.
- *Note Internationalization::, describes special features in `gawk'
-for translating program messages into different languages at runtime.
+ - *note Internationalization::, describes special features 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 Debugger::, describes the `gawk' debugger.
- *Note Library Functions::, and *Note Sample Programs::, provide many
-sample `awk' programs. Reading them allows you to see `awk' solving
-real problems.
+ - *note Arbitrary Precision Arithmetic::, describes advanced
+ arithmetic facilities.
- *Note Debugger::, describes the `awk' debugger, `dgawk'.
+ - *note Dynamic Extensions::, describes how to add new
+ variables and functions to `gawk' by writing extensions in C
+ or C++.
- *Note Language History::, describes how the `awk' language has
-evolved since its first release to present. It also describes how
-`gawk' has acquired features over time.
+ * Part IV provides the appendices, the Glossary, and two licenses
+ that cover the `gawk' source code and this Info file, respectively.
+ It contains the following appendices:
- *Note Installation::, describes how to get `gawk', how to compile it
-on POSIX-compatible systems, and how to compile and use it on different
-non-POSIX systems. It also describes how to report bugs in `gawk' and
-where to get other freely available `awk' implementations.
+ - *note Language History::, describes how the `awk' language
+ has evolved since its first release to the present. It also
+ describes how `gawk' has acquired features over time.
- *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 Installation::, describes how to get `gawk', how to
+ compile it on POSIX-compatible systems, and how to compile
+ and use it on different non-POSIX systems. It also describes
+ how to report bugs in `gawk' and where to get other freely
+ available `awk' implementations.
- *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.
+ - *note Notes::, describes how to disable `gawk''s extensions,
+ as well as how to contribute new code to `gawk', and some
+ possible future directions for `gawk' development.
- 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 Basic Concepts::, provides some very cursory background
+ material for those who are completely unfamiliar with
+ computer programming.
- *Note Copying::, and *Note GNU Free Documentation License::, present
-the licenses that cover the `gawk' source code and this Info file,
-respectively.
+ The *note Glossary::, defines most, if not all, of the
+ significant terms used throughout the Info file. 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 ----------
@@ -928,18 +1132,18 @@ File: gawk.info, Node: Conventions, Next: Manual History, Prev: This Manual,
Typographical Conventions
=========================
-This Info file is written in Texinfo (http://texinfo.org), 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.
+This Info file is written in Texinfo
+(http://www.gnu.org/software/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
+ Examples you would type at the command line are preceded by the
common shell primary and secondary prompts, `$' and `>'. Input that
you type is shown `like this'. 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:
+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
@@ -951,23 +1155,27 @@ 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.
+key, and finally releasing both keys.
+
+ For the sake of brevity, throughout this Info file, we refer to
+Brian Kernighan's version of `awk' as "BWK `awk'." (*Note Other
+Versions::, for information on his and other versions.)
Dark Corners
-............
+------------
- Dark corners are basically fractal -- no matter how much you
- illuminate, there's always a smaller but darker one.
- Brian Kernighan
+ 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 `GAWK: Effective AWK Programming'),
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
+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, incomplete.
+ But, as noted by the opening quote, any coverage of dark corners is
+by definition incomplete.
Extensions to the standard `awk' language that are supported by more
than one `awk' implementation are marked "(c.e.)," and listed in the
@@ -986,13 +1194,13 @@ 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
+POSIX-compliant computing environment. The FSF uses the GNU General
+Public License (GPL) to ensure that its 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
+This Info file may also be read from GNU's website
(http://www.gnu.org/software/gawk/manual/).
A shell, an editor (Emacs), highly portable optimizing C, C++, and
@@ -1003,45 +1211,40 @@ released but remains 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(R), Power Architecture, Sun SPARC, IBM S/390, and other
+system for Intel, Power Architecture, Sun SPARC, IBM S/390, and other
systems.(2) Many GNU/Linux distributions are available for download
from the Internet.
- (There are numerous other freely available, Unix-like operating
-systems based on the Berkeley Software Distribution, and some of them
-use recent versions of `gawk' for their versions of `awk'. NetBSD
-(http://www.netbsd.org), FreeBSD (http://www.freebsd.org), and OpenBSD
-(http://www.openbsd.org) are three of the most popular ones, but there
-are others.)
-
- The Info file itself has gone through a number of previous editions.
+ The Info file itself has gone through multiple 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'.
+around 40 pages long. Diane Close and Richard Stallman improved it,
+yielding a version that was around 90 pages 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
+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 the previous editions.
-For Edition 4.0, the content has been thoroughly reviewed and updated.
-All references to versions prior to 4.0 have been removed. Of
-significant note for this edition is *Note Debugger::.
+For FSF edition 4.0, the content was thoroughly reviewed and updated.
+All references to `gawk' versions prior to 4.0 were removed. Of
+significant note for that edition was the addition of *note Debugger::.
- `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.
+ For FSF edition 4.1, the content has been reorganized into parts,
+and the major new additions are *note Arbitrary Precision Arithmetic::,
+and *note Dynamic Extensions::.
+
+ This Info file will undoubtedly continue to evolve. If you find an
+error in the Info file, please report it! *Note Bugs::, for
+information on submitting problem reports electronically.
---------- Footnotes ----------
- (1) GNU stands for "GNU's not Unix."
+ (1) GNU stands for "GNU's Not Unix."
- (2) The terminology "GNU/Linux" is explained in the *Note Glossary::.
+ (2) The terminology "GNU/Linux" is explained in the *note Glossary::.

File: gawk.info, Node: How To Contribute, Next: Acknowledgments, Prev: Manual History, Up: Preface
@@ -1062,13 +1265,13 @@ something more broad, I acquired the `awk.info' domain.
contributed code: the archive did not grow and the domain went unused
for several years.
- Fortunately, late in 2008, a volunteer took on the task of setting up
-an `awk'-related web site--`http://awk.info'--and did a very nice job.
+ Late in 2008, a volunteer took on the task of setting up an
+`awk'-related website--`http://awk.info'--and did a very nice job.
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 see `http://awk.info/?contribute' for how to contribute
-it to the web site.
+it to the website.

File: gawk.info, Node: Acknowledgments, Prev: How To Contribute, Up: Preface
@@ -1083,7 +1286,7 @@ acknowledgments:
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
+ 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.
@@ -1096,7 +1299,7 @@ GNU Project.
acknowledgements:
The following people (in alphabetical order) provided helpful
- comments on various versions of this book, Rick Adams, Dr. Nelson
+ comments on various versions of this book: Rick Adams, Dr. Nelson
H.F. Beebe, Karl Berry, Dr. Michael Brennan, Rich Burridge, Claire
Cloutier, Diane Close, Scott Deifik, Christopher ("Topher") Eliot,
Jeffrey Friedl, Dr. Darrel Hankerson, Michal Jaegermann, Dr.
@@ -1105,7 +1308,7 @@ acknowledgements:
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
+ 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
@@ -1126,30 +1329,43 @@ acknowledgements:
Ulrich Drepper, provided invaluable help and feedback for the
design of the internationalization features.
- Chuck Toporek, Mary Sheehan, and Claire Coutier of O'Reilly &
+ Chuck Toporek, Mary Sheehan, and Claire Cloutier of O'Reilly &
Associates contributed significant editorial help for this Info
file for the 3.1 release of `gawk'.
- Dr. Nelson Beebe, Andreas Buening, Antonio Colombo, Stephen Davies,
-Scott Deifik, John H. DuBois III, Darrel Hankerson, Michal Jaegermann,
-Ju"rgen Kahrs, Dave Pitts, Stepan Kasal, Pat Rankin, Andrew Schorr,
-Corinna Vinschen, Anders Wallin, and Eli Zaretskii (in alphabetical
-order) make up the current `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.
-
- John Haque contributed the modifications to convert `gawk' into a
-byte-code interpreter, including the debugger. Stephen Davies
-contributed to the effort to bring the byte-code changes into the
-mainstream code base. Efraim Yawitz contributed the initial text of
-*Note Debugger::.
-
- I would like to thank Brian Kernighan for invaluable assistance
-during the testing and debugging of `gawk', and for ongoing help and
-advice 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.
+ Dr. Nelson Beebe, Andreas Buening, Dr. Manuel Collado, Antonio
+Colombo, Stephen Davies, Scott Deifik, Akim Demaille, Darrel Hankerson,
+Michal Jaegermann, Ju"rgen Kahrs, Stepan Kasal, John Malmberg, Dave
+Pitts, Chet Ramey, Pat Rankin, Andrew Schorr, Corinna Vinschen, and Eli
+Zaretskii (in alphabetical order) make up the current `gawk' "crack
+portability team." Without their hard work and help, `gawk' would not
+be nearly the robust, portable program it is today. It has been and
+continues to be a pleasure working with this team of fine people.
+
+ Notable code and documentation contributions were made by a number
+of people. *Note Contributors::, for the full list.
+
+ Thanks to Michael Brennan for the Forewords.
+
+ Thanks to Patrice Dumas for the new `makeinfo' program. Thanks to
+Karl Berry, who continues to work to keep the Texinfo markup language
+sane.
+
+ Robert P.J. Day, Michael Brennan, and Brian Kernighan kindly acted as
+reviewers for the 2015 edition of this Info file. Their feedback helped
+improve the final work.
+
+ I would also like to thank Brian Kernighan for his invaluable
+assistance during the testing and debugging of `gawk', and for his
+ongoing help and advice 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.
+
+ Brian is in a class by himself as a programmer and technical author.
+I have to thank him (yet again) for his ongoing friendship and for
+being a role model to me for close to 30 years! Having him as a
+reviewer is an exciting privilege. It has also been extremely
+humbling...
I must thank my wonderful wife, Miriam, for her patience through the
many versions of this project, for her proofreading, and for sharing me
@@ -1159,12 +1375,6 @@ 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, 2011
-

File: gawk.info, Node: Getting Started, Next: Invoking Gawk, Prev: Preface, Up: Top
@@ -1174,28 +1384,28 @@ File: gawk.info, Node: Getting Started, Next: Invoking Gawk, Prev: Preface,
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.
+continues to process 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
+languages, because `awk' programs are "data driven" (i.e., 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 should 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
+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
+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:
+ Syntactically, a rule consists of a "pattern" followed by an
+"action". The action is enclosed in braces to separate it from the
+pattern. Newlines usually separate rules. Therefore, an `awk' program
+looks like this:
PATTERN { ACTION }
PATTERN { ACTION }
@@ -1216,6 +1426,7 @@ like this:
* Other Features:: Other Features of `awk'.
* When:: When to use `gawk' and when to use
other things.
+* Intro Summary:: Summary of the introduction.

File: gawk.info, Node: Running gawk, Next: Sample Data Files, Up: Getting Started
@@ -1241,7 +1452,7 @@ variations of each.
* One-shot:: Running a short throwaway `awk'
program.
-* Read Terminal:: Using no input files (input from terminal
+* Read Terminal:: Using no input files (input from the keyboard
instead).
* Long:: Putting permanent `awk' programs in
files.
@@ -1262,7 +1473,7 @@ 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
+where PROGRAM consists of a series of patterns and actions, as
described earlier.
This command format instructs the "shell", or command interpreter,
@@ -1277,7 +1488,8 @@ 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.
+ Later in this chapter, in *note Very Simple::, we'll see examples of
+several short, self-contained programs.

File: gawk.info, Node: Read Terminal, Next: Long, Prev: One-shot, Up: Running gawk
@@ -1291,27 +1503,35 @@ 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
+whatever you type on the keyboard. This continues until you indicate
+end-of-file by typing `Ctrl-d'. (On non-POSIX operating systems, the
end-of-file character may be different. For example, on OS/2, 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(1) (`BEGIN' is a feature we haven't discussed yet):
+programming:
- $ awk "BEGIN { print \"Don't Panic!\" }"
+ $ awk 'BEGIN { print "Don\47t 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.(2)
+ `awk' executes statements associated with `BEGIN' before reading any
+input. If there are no other statements in your program, as is the
+case here, `awk' just stops, instead of trying to read input it doesn't
+know how to process. The `\47' is a magic way (explained later) of
+getting a single quote into the program, without having to engage in
+ugly shell quoting tricks.
+
+ NOTE: If you use Bash as your shell, you should execute the
+ command `set +H' before running this program interactively, to
+ disable the C shell-style command history, which treats `!' as a
+ special character. We recommend putting this command into your
+ personal startup file.
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).
+works is explained shortly):
$ awk '{ print }'
Now is the time for all good men
@@ -1324,32 +1544,21 @@ works is explained shortly).
-| What, me worry?
Ctrl-d
- ---------- Footnotes ----------
-
- (1) If you use Bash as your shell, you should execute the command
-`set +H' before running this program interactively, to disable the C
-shell-style command history, which treats `!' as a special character.
-We recommend putting this command into your personal startup file.
-
- (2) 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.
-

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:
+Sometimes `awk' programs are very long. In these cases, 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:
+the file SOURCE-FILE (*note Options::). Any file name can be used for
+SOURCE-FILE. For example, you could put the program:
BEGIN { print "Don't Panic!" }
@@ -1359,19 +1568,20 @@ into the file `advice'. Then this command:
does the same thing as this one:
- awk "BEGIN { print \"Don't Panic!\" }"
+ awk 'BEGIN { print "Don\47t 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.
+that are provided on the `awk' command line. (Also, placing the
+program in a file allows us to use a literal single quote in the program
+text, instead of the magic `\47'.)
- If you want to clearly identify your `awk' program files 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.
+ If you want to clearly identify an `awk' program file 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.

File: gawk.info, Node: Executable Scripts, Next: Comments, Prev: Long, Up: Running gawk
@@ -1389,8 +1599,8 @@ like this:
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':
+type `advice' at the shell and the system arranges to run `awk' as if
+you had typed `awk -f advice':
$ chmod +x advice
$ advice
@@ -1404,11 +1614,27 @@ at the shell.)
program that users can invoke without their having to know that the
program is written in `awk'.
-Advanced Notes: Portability Issues with `#!'
---------------------------------------------
+ Understanding `#!'
+
+ `awk' is an "interpreted" language. This means that the `awk'
+utility reads your program and then processes your data according to
+the instructions in your program. (This is different from a "compiled"
+language such as C, where your program is first compiled into machine
+code that is executed directly by your system's processor.) The `awk'
+utility is thus termed an "interpreter". Many modern languages are
+interpreted.
+
+ The line beginning with `#!' lists the full file name of an
+interpreter to run and a single 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. (Note that on many systems
+`awk' may be found in `/usr/bin' instead of in `/bin'.)
-Some systems limit the length of the interpreter name to 32 characters.
-Often, this can be dealt with by using a symbolic link.
+ 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
@@ -1424,16 +1650,8 @@ the name of your script (`advice'). (d.c.) Don't rely on the value of
---------- Footnotes ----------
- (1) The `#!' mechanism works on GNU/Linux systems, BSD-based systems
-and 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.
+ (1) The `#!' mechanism works on GNU/Linux systems, BSD-based
+systems, and commercial Unix systems.

File: gawk.info, Node: Comments, Next: Quoting, Prev: Executable Scripts, Up: Running gawk
@@ -1447,13 +1665,13 @@ 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
+ In the `awk' language, a comment starts with the number 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
+the rest of a line following a number sign. For example, we could have
put the following into `advice':
- # This program prints a nice friendly message. It helps
+ # This program prints a nice, friendly message. It helps
# keep novice users from being afraid of the computer.
BEGIN { print "Don't Panic!" }
@@ -1462,17 +1680,17 @@ 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'
+ CAUTION: As mentioned in *note One-shot::, you can enclose short
+ to medium-sized 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 'BEGIN { print "hello" } # let's be cute'
>
The shell sees that the first two quotes match, and that a new
@@ -1486,20 +1704,20 @@ at a later time.
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.
+ help, because backslashes are not special inside single quotes.
+ The next node describes the shell's quoting rules.

File: gawk.info, Node: Quoting, Prev: Comments, Up: Running gawk
-1.1.6 Shell-Quoting Issues
+1.1.6 Shell Quoting Issues
--------------------------
* Menu:
* DOS Quoting:: Quoting in Windows Batch Files.
- For short to medium length `awk' programs, it is most convenient to
+ 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
@@ -1512,6 +1730,23 @@ 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 the C shell, you're on your own.
+ Before diving into the rules, we introduce a concept that appears
+throughout this Info file, which is that of the "null", or empty,
+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: `""'.
+In the shell, it can be written using single or double quotes: `""' or
+`'''. Although the null string has no characters in it, it does exist.
+For example, consider this command:
+
+ $ echo ""
+
+Here, the `echo' utility receives a single argument, even though that
+argument has no characters in it. In the rest of this Info file, we use
+the terms "null string" and "empty string" interchangeably. Now, on to
+the quoting rules:
+
* 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.
@@ -1524,20 +1759,23 @@ Shell). If you use the C shell, you're on your own.
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.
+ *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
+ Because 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:
+ stripped first.) Thus, the example seen in *note Read Terminal:::
+
+ awk 'BEGIN { print "Don\47t Panic!" }'
+
+ could instead be written this way:
$ awk "BEGIN { print \"Don't Panic!\" }"
-| Don't Panic!
@@ -1545,9 +1783,9 @@ Shell). If you use the C shell, you're on your own.
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:
+ command-line argument, while explicit 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
@@ -1555,10 +1793,10 @@ Shell). If you use the C shell, you're on your own.
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.
+ In the second case, `awk' attempts 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:
@@ -1567,7 +1805,7 @@ shell quoting tricks, like this:
-| 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.
+and the third are single-quoted, and the second is double-quoted.
This can be "simplified" to:
@@ -1594,8 +1832,7 @@ like so:
$ 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.
+This works nicely, but you should comment clearly what the escapes mean.
A fourth option is to use command-line variable assignment, like
this:
@@ -1603,9 +1840,12 @@ this:
$ awk -v sq="'" 'BEGIN { print "Here is a single quote <" sq ">" }'
-| Here is a single quote <'>
+ (Here, the two string constants and the value of `sq' are
+concatenated into a single string that is printed by `print'.)
+
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.
+shell won't be part of the picture and you can say what you mean.

File: gawk.info, Node: DOS Quoting, Up: Quoting
@@ -1632,37 +1872,38 @@ File: gawk.info, Node: Sample Data Files, Next: Very Simple, Prev: Running ga
===============================
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.
+data files. The first, `mail-list', represents a list of peoples' names
+together with their email addresses and information about those people.
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
+ In `mail-list', each record contains the name of a person, his/her
+phone number, his/her email address, and a code for his/her relationship
+with the author of the list. The columns are aligned using spaces. An
+`A' in the last column means that the person is an acquaintance. An
+`F' in the last column means that the person is a friend. An `R' means
+that the person is a relative:
+
+ Amelia 555-5553 amelia.zodiacusque@gmail.com F
+ Anthony 555-3412 anthony.asserturo@hotmail.com A
+ Becky 555-7685 becky.algebrarum@gmail.com A
+ Bill 555-1675 bill.drowning@hotmail.com A
+ Broderick 555-0542 broderick.aliquotiens@yahoo.com R
+ Camilla 555-2912 camilla.infusarum@skynet.be R
+ Fabius 555-1234 fabius.undevicesimus@ucb.edu F
+ Julie 555-6699 julie.perscrutabor@skeeve.com F
+ Martin 555-6480 martin.codicibus@hotmail.com A
+ Samuel 555-3430 samuel.lanceolis@shu.edu A
+ Jean-Paul 555-2127 jeanpaul.campanorum@nyu.edu R
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.
+and the first four months of the current year. An empty line separates
+the data for the two years:
Jan 13 25 15 115
Feb 15 32 24 226
@@ -1682,18 +1923,8 @@ and the first four months of the current year.
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.
+ The sample files are included in the `gawk' distribution, in the
+directory `awklib/eg/data'.

File: gawk.info, Node: Very Simple, Next: Two Rules, Prev: Sample Data Files, Up: Getting Started
@@ -1702,32 +1933,32 @@ File: gawk.info, Node: Very Simple, Next: Two Rules, Prev: Sample Data Files,
========================
The following command runs a simple `awk' program that searches the
-input file `BBS-list' for the character string `foo' (a grouping of
+input file `mail-list' for the character string `li' (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
+similar usage in English, such as "a string of pearls" or "a string of
cars in a train"):
- awk '/foo/ { print $0 }' BBS-list
+ awk '/li/ { print $0 }' mail-list
-When lines containing `foo' are found, they are printed because
+When lines containing `li' 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.
+ You will notice that slashes (`/') surround the string `li' in the
+`awk' program. The slashes indicate that `li' 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
+ $ awk '/li/ { print $0 }' mail-list
+ -| Amelia 555-5553 amelia.zodiacusque@gmail.com F
+ -| Broderick 555-0542 broderick.aliquotiens@yahoo.com R
+ -| Julie 555-6699 julie.perscrutabor@skeeve.com F
+ -| Samuel 555-3430 samuel.lanceolis@shu.edu A
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
@@ -1735,43 +1966,48 @@ 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:
-`awk' prints all lines matching the pattern `foo'. 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:
+braces) in the previous example and the result would be the same: `awk'
+prints all lines matching the pattern `li'. By comparison, omitting
+the `print' statement but retaining the braces makes an empty action
+that does nothing (i.e., no lines are printed).
+
+ Many practical `awk' programs are just a line or two long.
+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 you'll need to 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 every line that is longer than 80 characters:
+
+ awk 'length($0) > 80' data
+
+ The sole rule has a relational expression as its pattern and has no
+ action--so it uses the default action, printing the record.
* 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.
+ The code associated with `END' executes after all input has been
+ read; it's the other side of the coin to `BEGIN'.
* Print the length of the longest line in `data':
- expand data | awk '{ if (x < length()) x = length() }
- END { print "maximum line length is " x }'
+ expand data | awk '{ if (x < length($0)) x = length($0) }
+ 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.
+ This example differs slightly from the previous one: the input is
+ processed by the `expand' utility to change TABs into spaces, so
+ the widths compared are actually the right-margin columns, as
+ opposed to the number of input characters on each line.
* Print every line that has at least one field:
@@ -1789,7 +2025,7 @@ different ways to do the same things shown here:
* Print the total number of bytes used by FILES:
ls -l FILES | awk '{ x += $5 }
- END { print "total bytes: " x }'
+ END { print "total bytes: " x }'
* Print the total number of kilobytes used by FILES:
@@ -1808,8 +2044,8 @@ different ways to do the same things shown here:
awk 'NR % 2 == 0' data
- If you use the expression `NR % 2 == 1' instead, the program would
- print the odd-numbered lines.
+ If you used the expression `NR % 2 == 1' instead, the program
+ would print the odd-numbered lines.

File: gawk.info, Node: Two Rules, Next: More Complex, Prev: Very Simple, Up: Getting Started
@@ -1818,14 +2054,13 @@ File: gawk.info, Node: Two Rules, Next: More Complex, Prev: Very Simple, Up:
=============================
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.
+line, `awk' tries the patterns of each rule. If several patterns
+match, then several actions execute in the order in which they appear
+in the `awk' program. If no patterns match, then no actions 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
+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:
@@ -1842,25 +2077,19 @@ 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':
+files, `mail-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
+ > /21/ { print $0 }' mail-list inventory-shipped
+ -| Anthony 555-3412 anthony.asserturo@hotmail.com A
+ -| Camilla 555-2912 camilla.infusarum@skynet.be R
+ -| Fabius 555-1234 fabius.undevicesimus@ucb.edu F
+ -| Jean-Paul 555-2127 jeanpaul.campanorum@nyu.edu R
+ -| Jean-Paul 555-2127 jeanpaul.campanorum@nyu.edu R
-| Jan 21 36 64 620
-| Apr 21 70 74 514
-Note how the line beginning with `sabafoo' in `BBS-list' was printed
+Note how the line beginning with `Jean-Paul' in `mail-list' was printed
twice, once for each rule.

@@ -1875,8 +2104,8 @@ 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:
- LC_ALL=C ls -l | awk '$6 == "Nov" { sum += $5 }
- END { print sum }'
+ 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).
@@ -1895,20 +2124,20 @@ date the file was last modified. Its output looks like this:
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,
+identifies the file's owner. The fourth field identifies the file's
+group. The fifth field contains the file's size 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 file name.(1)
+contains the file name.
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.)
+`Nov'. Each time a line has the string `Nov' for its sixth field,
+`awk' performs the action `sum += $5'. 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,
@@ -1921,11 +2150,6 @@ displays your output. By manipulating fields and using `print'
statements, you can produce some very useful and impressive-looking
reports.
- ---------- Footnotes ----------
-
- (1) The `LC_ALL=C' is needed to produce this traditional-style
-output from `ls'.
-

File: gawk.info, Node: Statements/Lines, Next: Other Features, Prev: More Complex, Up: Getting Started
@@ -1936,7 +2160,7 @@ 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
+ /21/ { print $0 }' mail-list inventory-shipped
However, `gawk' ignores newlines after any of the following symbols
and keywords:
@@ -1960,24 +2184,24 @@ We have generally not used backslash continuation in our sample
programs. `gawk' places 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.
+most statements short in the 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:
+ 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 \\
@@ -2010,7 +2234,7 @@ comment, it ignores _everything_ on the rest of the line. For example:
> BEGIN rule
> }'
error--> gawk: cmd. line:2: BEGIN rule
- error--> gawk: cmd. line:2: ^ parse error
+ error--> gawk: cmd. line:2: ^ syntax error
In this case, it looks like the backslash would continue the comment
onto the next line. However, the backslash-newline combination is never
@@ -2033,7 +2257,7 @@ minor node could also be written this way:
---------- Footnotes ----------
(1) The `?' and `:' referred to here is the three-operand
-conditional expression described in *Note Conditional Exp::. Splitting
+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.
@@ -2054,12 +2278,13 @@ built-in functions for working with timestamps, performing bit
manipulation, for runtime string translation (internationalization),
determining the type of a variable, and array sorting.
- As we develop our presentation of the `awk' language, we introduce
-most of the variables and many of the functions. They are described
-systematically in *Note Built-in Variables::, and *Note Built-in::.
+ As we develop our presentation of the `awk' language, we will
+introduce most of the variables and many of the functions. They are
+described systematically in *note Built-in Variables::, and in *note
+Built-in::.

-File: gawk.info, Node: When, Prev: Other Features, Up: Getting Started
+File: gawk.info, Node: When, Next: Intro Summary, Prev: Other Features, Up: Getting Started
1.8 When to Use `awk'
=====================
@@ -2082,21 +2307,46 @@ 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. While the original `awk''s capabilities were strained
-by tasks of such complexity, modern versions are more capable. Even
-Brian Kernighan's version of `awk' has fewer predefined limits, and
-those that it has are much larger than they used to be.
+Prolog computer. The original `awk''s capabilities were strained by
+tasks of such complexity, but modern versions are more capable.
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.
+language. The shell is good at string and pattern matching; in
+addition, it allows powerful use of the system utilities. Python
+offers a nice balance between high-level ease of programming and access
+to system facilities.(1)
+
+ ---------- Footnotes ----------
+
+ (1) Other popular scripting languages include Ruby and Perl.
+
+
+File: gawk.info, Node: Intro Summary, Prev: When, Up: Getting Started
+
+1.9 Summary
+===========
+
+ * Programs in `awk' consist of PATTERN-ACTION pairs.
+
+ * An ACTION without a PATTERN always runs. The default ACTION for a
+ pattern without one is `{ print $0 }'.
+
+ * Use either `awk 'PROGRAM' FILES' or `awk -f PROGRAM-FILE FILES' to
+ run `awk'.
+
+ * You may use the special `#!' header line to create `awk' programs
+ that are directly executable.
+
+ * Comments in `awk' programs start with `#' and continue to the end
+ of the same line.
+
+ * Be aware of quoting issues when writing `awk' programs as part of
+ a larger shell script (or MS-Windows batch file).
+
+ * You may use backslash continuation to continue a source line.
+ Lines are automatically continued after a comma, open brace,
+ question mark, colon, `||', `&&', `do', and `else'.

File: gawk.info, Node: Invoking Gawk, Next: Regexp, Prev: Getting Started, Up: Top
@@ -2104,12 +2354,12 @@ File: gawk.info, Node: Invoking Gawk, Next: Regexp, Prev: Getting Started, U
2 Running `awk' and `gawk'
**************************
-This major node covers how to run awk, both POSIX-standard and
+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, reading standard input along with other files,
-`gawk''s environment variables, `gawk''s exit status, using include
-files, and obsolete and undocumented options and/or features.
+nonoption arguments. It then proceeds to cover how `gawk' searches for
+source files, reading standard input along with other files, `gawk''s
+environment variables, `gawk''s exit status, using include files, and
+obsolete and undocumented options and/or features.
Many of the options and features described here are discussed in
more detail later in the Info file; feel free to skip over things in
@@ -2125,8 +2375,10 @@ this major node that don't interest you right now.
* Environment Variables:: The environment variables `gawk' uses.
* Exit Status:: `gawk''s exit status.
* Include Files:: Including other files into your program.
+* Loading Shared Libraries:: Loading shared libraries into your program.
* Obsolete:: Obsolete Options and/or features.
* Undocumented:: Undocumented Options and Features.
+* Invoking Summary:: Invocation summary.

File: gawk.info, Node: Command Line, Next: Options, Up: Invoking Gawk
@@ -2138,11 +2390,11 @@ 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 ...
+ `awk' [OPTIONS] `-f' PROGFILE [`--'] FILE ...
+ `awk' [OPTIONS] [`--'] `'PROGRAM'' FILE ...
- Besides traditional one-letter POSIX-style options, `gawk' also
-supports GNU long options.
+ In addition to traditional one-letter POSIX-style options, `gawk'
+also supports GNU long options.
It is possible to invoke `awk' with an empty program:
@@ -2161,8 +2413,8 @@ File: gawk.info, Node: Options, Next: Other Arguments, Prev: Command Line, U
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
+uniquely identified. If the option takes an argument, either the
+keyword is 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.
@@ -2177,10 +2429,10 @@ The following list describes options mandated by the POSIX standard:
`-f SOURCE-FILE'
`--file SOURCE-FILE'
- Read `awk' program source from SOURCE-FILE instead of in the first
- non-option argument. This option may be given multiple times; the
- `awk' program consists of the concatenation the contents of each
- specified SOURCE-FILE.
+ Read the `awk' program source from SOURCE-FILE instead of in the
+ first nonoption argument. This option may be given multiple
+ times; the `awk' program consists of the concatenation of the
+ contents of each specified SOURCE-FILE.
`-v VAR=VAL'
`--assign VAR=VAL'
@@ -2195,7 +2447,7 @@ The following list describes options mandated by the POSIX standard:
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.
+ ignoring any initial value you may have given.
`-W GAWK-OPT'
Provide an implementation-specific option. This is the POSIX
@@ -2214,38 +2466,41 @@ The following list describes options mandated by the POSIX standard:
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 `-'. It is also useful for passing
- options on to the `awk' program; see *Note Getopt Function::.
+ options on to the `awk' program; see *note Getopt Function::.
The following list describes `gawk'-specific options:
`-b'
`--characters-as-bytes'
Cause `gawk' to treat all input data as single-byte characters.
+ In addition, all output written with `print' or `printf' is
+ treated as single-byte characters.
+
Normally, `gawk' follows the POSIX standard and attempts to process
- its input data according to the current locale. This can often
- involve converting multibyte characters into wide characters
- (internally), and can lead to problems or confusion if the input
- data does not contain valid multibyte characters. This option is
- an easy way to tell `gawk': "hands off my data!".
+ its input data according to the current locale (*note Locales::).
+ This can often involve converting multibyte characters into wide
+ characters (internally), and can lead to problems or confusion if
+ the input data does not contain valid multibyte characters. This
+ option is an easy way to tell `gawk', "Hands off my data!"
`-c'
`--traditional'
Specify "compatibility mode", in which the GNU extensions to the
- `awk' language are disabled, so that `gawk' behaves just like
- Brian Kernighan's version `awk'. *Note POSIX/GNU::, which
- summarizes the extensions. Also see *Note Compatibility Mode::.
+ `awk' language are disabled, so that `gawk' behaves just like BWK
+ `awk'. *Note POSIX/GNU::, which summarizes the extensions. Also
+ see *note Compatibility Mode::.
`-C'
`--copyright'
Print the short version of the General Public License and then
exit.
-`-d[FILE]'
-`--dump-variables[=FILE]'
+`-d'[FILE]
+`--dump-variables'[`='FILE]
Print a sorted list of global variables, their types, and final
- values to FILE. If no FILE is provided, print this list to the
- file named `awkvars.out' in the current directory. No space is
- allowed between the `-d' and FILE, if FILE is supplied.
+ values to FILE. If no FILE is provided, print this list to a file
+ named `awkvars.out' in the current directory. No space is allowed
+ between the `-d' and FILE, if FILE is supplied.
Having a list of all global variables is a good way to look for
typographical errors in your programs. You would also use this
@@ -2255,16 +2510,25 @@ The following list describes options mandated by the POSIX standard:
particularly easy mistake to make with simple variable names like
`i', `j', etc.)
-`-e PROGRAM-TEXT'
-`--source PROGRAM-TEXT'
+`-D'[FILE]
+`--debug'[`='FILE]
+ Enable debugging of `awk' programs (*note Debugging::). By
+ default, the debugger reads commands interactively from the
+ keyboard (standard input). The optional FILE argument allows you
+ to specify a file with a list of commands for the debugger to
+ execute noninteractively. No space is allowed between the `-D'
+ and FILE, if FILE is supplied.
+
+`-e' PROGRAM-TEXT
+`--source' PROGRAM-TEXT
Provide program source code in the PROGRAM-TEXT. This option
allows you to mix source code in files with source code that you
enter on the command line. This is particularly useful when you
have library functions that you want to use from your command-line
programs (*note AWKPATH Variable::).
-`-E FILE'
-`--exec FILE'
+`-E' FILE
+`--exec' FILE
Similar to `-f', read `awk' program text from FILE. There are two
differences from `-f':
@@ -2277,8 +2541,8 @@ The following list describes options mandated by the POSIX standard:
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
+ options, assignments, or `awk' source code (via `-e') to the CGI
+ application.(1) This option should be used with `#!' scripts
(*note Executable Scripts::), like so:
#! /usr/local/bin/gawk -E
@@ -2287,24 +2551,51 @@ The following list describes options mandated by the POSIX standard:
`-g'
`--gen-pot'
- Analyze the source program and generate a GNU `gettext' Portable
- Object Template file on standard output for all string constants
+ Analyze the source program and generate a GNU `gettext' portable
+ object template file on standard output for all string constants
that have been marked for translation. *Note
Internationalization::, for information about this option.
`-h'
`--help'
- Print a "usage" message summarizing the short and long style
+ Print a "usage" message summarizing the short- and long-style
options that `gawk' accepts and then exit.
-`-L [value]'
-`--lint[=value]'
+`-i' SOURCE-FILE
+`--include' SOURCE-FILE
+ Read an `awk' source library from SOURCE-FILE. This option is
+ completely equivalent to using the `@include' directive inside
+ your program. It is very similar to the `-f' option, but there
+ are two important differences. First, when `-i' is used, the
+ program source is not loaded if it has been previously loaded,
+ whereas with `-f', `gawk' always loads the file. Second, because
+ this option is intended to be used with code libraries, `gawk'
+ does not recognize such files as constituting main program input.
+ Thus, after processing an `-i' argument, `gawk' still expects to
+ find the main source code via the `-f' option or on the command
+ line.
+
+`-l' EXT
+`--load' EXT
+ Load a dynamic extension named EXT. Extensions are stored as
+ system shared libraries. This option searches for the library
+ using the `AWKLIBPATH' environment variable. The correct library
+ suffix for your platform will be supplied by default, so it need
+ not be specified in the extension name. The extension
+ initialization routine should be named `dl_load()'. An
+ alternative is to use the `@load' keyword inside the program to
+ load a shared library. This advanced feature is described in
+ detail in *note Dynamic Extensions::.
+
+`-L'[VALUE]
+`--lint'[`='VALUE]
Warn 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.
+ `awk' implementations. No space is allowed between the `-L' and
+ VALUE, if VALUE is supplied. 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.)
@@ -2316,38 +2607,54 @@ The following list describes options mandated by the POSIX standard:
inappropriate construct. As `awk' programs are usually short,
doing so is not burdensome.
+`-M'
+`--bignum'
+ Force arbitrary-precision arithmetic on numbers. This option has
+ no effect if `gawk' is not compiled to use the GNU MPFR and MP
+ libraries (*note Arbitrary Precision Arithmetic::).
+
`-n'
`--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.
+ with care. Also note that this option may disappear in a
+ future version of `gawk'.
`-N'
`--use-lc-numeric'
Force the use of the locale's decimal point character when parsing
numeric input data (*note Locales::).
+`-o'[FILE]
+`--pretty-print'[`='FILE]
+ Enable pretty-printing of `awk' programs. By default, the output
+ program is created in a file named `awkprof.out' (*note
+ Profiling::). The optional FILE argument allows you to specify a
+ different file name for the output. No space is allowed between
+ the `-o' and FILE, if FILE is supplied.
+
+ NOTE: In the past, this option would also execute your
+ program. This is no longer the case.
+
`-O'
`--optimize'
Enable some optimizations on the internal representation of the
- program. At the moment this includes just simple constant
- folding. The `gawk' maintainer hopes to add more optimizations
- over time.
+ program. At the moment, this includes just simple constant
+ folding.
-`-p[FILE]'
-`--profile[=FILE]'
+`-p'[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. No space is allowed between the `-p' and
FILE, if FILE is supplied.
- 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.
+ The profile contains execution counts for each statement in the
+ program in the left margin, and function call counts for each
+ function.
`-P'
`--posix'
@@ -2363,7 +2670,7 @@ The following list describes options mandated by the POSIX standard:
* Newlines are not allowed after `?' or `:' (*note Conditional
Exp::).
- * Specifying `-Ft' on the command-line does not set the value
+ * Specifying `-Ft' on the command line does not set the value
of `FS' to be a single TAB character (*note Field
Separators::).
@@ -2371,20 +2678,15 @@ The following list describes options mandated by the POSIX standard:
data (*note Locales::).
If you supply both `--traditional' and `--posix' on the command
- line, `--posix' takes precedence. `gawk' also issues a warning if
- both options are supplied.
+ line, `--posix' takes precedence. `gawk' issues a warning if both
+ options are supplied.
`-r'
`--re-interval'
Allow interval expressions (*note Regexp Operators::) in regexps.
This is now `gawk''s default behavior. Nevertheless, this option
- remains both for backward compatibility, and for use in
- combination with the `--traditional' option.
-
-`-R FILE'
-`--command=FILE'
- `dgawk' only. Read `dgawk' debugger options and commands from
- FILE. *Note Dgawk Info::, for more information.
+ remains (both for backward compatibility and for use in
+ combination with `--traditional').
`-S'
`--sandbox'
@@ -2420,44 +2722,43 @@ 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.)
+having to be included in each individual program. The `-i' option is
+similar in this regard. (As mentioned in *note Definition Syntax::,
+function names must be unique.)
With standard `awk', library functions can still be used, even if
-the program is entered at the terminal, by specifying `-f /dev/tty'.
+the program is entered at the keyboard, 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
+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::). The `--source'
-option may also be used multiple times on the command line.
-
- 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.
+source file and command-line `awk' programs, `gawk' provides the `-e'
+option. This does not require you to preempt the standard input for
+your source code; it allows you to easily mix command-line and library
+source code (*note AWKPATH Variable::). As with `-f', the `-e' and `-i'
+options may also be used multiple times on the command line.
+
+ If no `-f' or `-e' option is specified, then `gawk' uses the first
+nonoption 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 suppress extensions that conflict with POSIX,
-but `gawk' behaves differently: it suppresses all extensions, even
-those that do not conflict with POSIX, and behaves in 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:
+behaves in strict POSIX mode, exactly as if you had supplied `--posix'.
+Many GNU programs look for this environment variable to suppress
+extensions that conflict with POSIX, but `gawk' behaves differently: it
+suppresses all extensions, even those that do not conflict with POSIX,
+and behaves in 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 C shell-compatible shell,(1) you would add this line to the
+ For a C shell-compatible shell,(2) you would add this line to the
`.login' file in your home directory:
setenv POSIXLY_CORRECT true
@@ -2468,7 +2769,12 @@ environments.
---------- Footnotes ----------
- (1) Not recommended.
+ (1) For more detail, please see Section 4.4 of RFC 3875
+(http://www.ietf.org/rfc/rfc3875). Also see the explanatory note sent
+to the `gawk' bug mailing list
+(http://lists.gnu.org/archive/html/bug-gawk/2014-11/msg00022.html).
+
+ (2) Not recommended.

File: gawk.info, Node: Other Arguments, Next: Naming Standard Input, Prev: Options, Up: Invoking Gawk
@@ -2479,15 +2785,22 @@ File: gawk.info, Node: Other Arguments, Next: Naming Standard Input, Prev: Op
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. (See *Note Assignment
-Options::.)
+variable VAR--it does not specify a file at all. (See *note Assignment
+Options::.) In the following example, COUNT=1 is a variable assignment,
+not a file name:
- 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.
+ awk -f program.awk file1 count=1 file2
+
+ All the command-line 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 `ARGIND' to the index
+in `ARGV' of the current element.
+
+ Changing `ARGC' and `ARGV' in your `awk' program lets you control
+how `awk' processes the input files; this is described in more detail
+in *note ARGC and ARGV::.
The distinction between file name arguments and variable-assignment
arguments is made when `awk' is about to open the next input file. At
@@ -2504,18 +2817,18 @@ 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.
+ In some very early 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
+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:
@@ -2550,7 +2863,7 @@ with `getline' (*note Getline/File::).
In addition, `gawk' allows you to specify the special file name
`/dev/stdin', both on the command line and with `getline'. Some other
versions of `awk' also support this, but it is not standard. (Some
-operating systems provide a `/dev/stdin' file in the file system,
+operating systems provide a `/dev/stdin' file in the filesystem;
however, `gawk' always processes this file name itself.)

@@ -2565,102 +2878,157 @@ A number of environment variables influence how `gawk' behaves.
* AWKPATH Variable:: Searching directories for `awk'
programs.
+* AWKLIBPATH Variable:: Searching directories for `awk' shared
+ libraries.
* Other Environment Variables:: The environment variables.

-File: gawk.info, Node: AWKPATH Variable, Next: Other Environment Variables, Up: Environment Variables
+File: gawk.info, Node: AWKPATH Variable, Next: AWKLIBPATH Variable, Up: Environment Variables
2.5.1 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.
+on the command line with the `-f' option. In most `awk'
+implementations, you must supply a precise pathname for each program
+file, unless the file is in the current directory. But with `gawk', if
+the file name supplied to the `-f' or `-i' options does not contain a
+directory separator `/', 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)
-
- 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::.
+colons.(1) `gawk' gets its search path from the `AWKPATH' environment
+variable. If that variable does not exist, or if it has an empty value,
+`gawk' uses a default path (described shortly).
+
+ The search path feature is particularly helpful 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, you would have to type
+the full file name for each file.
+
+ By using the `-i' or `-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::.
+
+ If the source code file is not found after the initial search, the
+path is searched again after adding the suffix `.awk' to the file name.
+
+ `gawk''s path search mechanism is similar to the shell's. (See `The
+Bourne-Again SHell manual' (http://www.gnu.org/software/bash/manual/).)
+It treats a null entry in the path as indicating the current directory.
+(A null entry is indicated by starting or ending the path with a colon
+or by placing two colons next to each other [`::'].)
NOTE: To include the current directory in the path, either place
- `.' explicitly in the path or write 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 (`::').) This
- path search mechanism is similar to the shell's.
-
- However, `gawk' always looks in the current directory _before_
- searching `AWKPATH', so there is no real reason to include the
- current directory in the search path.
-
- 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.
+ `.' as an entry in the path or write a null entry in the path.
- 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'.
+ Different past versions of `gawk' would also look explicitly in
+ the current directory, either before or after the path search. As
+ of version 4.1.2, this no longer happens; if you wish to look in
+ the current directory, you must include `.' either as a separate
+ entry or as a null entry in the search path.
+
+ The default value for `AWKPATH' is `.:/usr/local/share/awk'.(2)
+Since `.' is included at the beginning, `gawk' searches first in the
+current directory and then in `/usr/local/share/awk'. In practice,
+this means that you will rarely need to change the value of `AWKPATH'.
+
+ *Note Shell Startup Files::, for information on functions that help
+to manipulate the `AWKPATH' variable.
+
+ `gawk' places the value of the search path that it used into
+`ENVIRON["AWKPATH"]'. This provides access to the actual search path
+value from within an `awk' program.
+
+ Although 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
+ (1) Semicolons on MS-Windows and MS-DOS.
+
+ (2) 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.

-File: gawk.info, Node: Other Environment Variables, Prev: AWKPATH Variable, Up: Environment Variables
+File: gawk.info, Node: AWKLIBPATH Variable, Next: Other Environment Variables, Prev: AWKPATH Variable, Up: Environment Variables
-2.5.2 Other Environment Variables
+2.5.2 The `AWKLIBPATH' Environment Variable
+-------------------------------------------
+
+The `AWKLIBPATH' environment variable is similar to the `AWKPATH'
+variable, but it is used to search for loadable extensions (stored as
+system shared libraries) specified with the `-l' option rather than for
+source files. If the extension is not found, the path is searched
+again after adding the appropriate shared library suffix for the
+platform. For example, on GNU/Linux systems, the suffix `.so' is used.
+The search path specified is also used for extensions loaded via the
+`@load' keyword (*note Loading Shared Libraries::).
+
+ If `AWKLIBPATH' does not exist in the environment, or if it has an
+empty value, `gawk' uses a default path; this is typically
+`/usr/local/lib/gawk', although it can vary depending upon how `gawk'
+was built.
+
+ *Note Shell Startup Files::, for information on functions that help
+to manipulate the `AWKLIBPATH' variable.
+
+ `gawk' places the value of the search path that it used into
+`ENVIRON["AWKLIBPATH"]'. This provides access to the actual search path
+value from within an `awk' program.
+
+
+File: gawk.info, Node: Other Environment Variables, Prev: AWKLIBPATH Variable, Up: Environment Variables
+
+2.5.3 Other Environment Variables
---------------------------------
A number of other environment variables affect `gawk''s behavior, but
they are more specialized. Those in the following list are meant to be
-used by regular users.
+used by regular users:
-`POSIXLY_CORRECT'
- Causes `gawk' to switch POSIX compatibility mode, disabling all
- traditional and GNU extensions. *Note Options::.
+`GAWK_MSEC_SLEEP'
+ Specifies the interval between connection retries, in
+ milliseconds. On systems that do not support the `usleep()' system
+ call, the value is rounded up to an integral number of seconds.
+
+`GAWK_READ_TIMEOUT'
+ Specifies the time, in milliseconds, for `gawk' to wait for input
+ before returning with an error. *Note Read Timeout::.
`GAWK_SOCK_RETRIES'
- Controls the number of time `gawk' will attempt to retry a two-way
+ Controls the number of times `gawk' attempts to retry a two-way
TCP/IP (socket) connection before giving up. *Note TCP/IP
Networking::.
-`GAWK_MSEC_SLEEP'
- Specifies the interval between connection retries, in
- milliseconds. On systems that do not support the `usleep()' system
- call, the value is rounded up to an integral number of seconds.
+`POSIXLY_CORRECT'
+ Causes `gawk' to switch to POSIX-compatibility mode, disabling all
+ traditional and GNU extensions. *Note Options::.
The environment variables in the following list are meant for use by
the `gawk' developers for testing and tuning. They are subject to
change. The variables are:
-`AVG_CHAIN_MAX'
- The average number of items `gawk' will maintain on a hash chain
- for managing arrays.
+`AWKBUFSIZE'
+ This variable only affects `gawk' on POSIX-compliant systems.
+ With a value of `exact', `gawk' uses the size of each input file
+ as the size of the memory buffer to allocate for I/O. Otherwise,
+ the value should be a number, and `gawk' uses that number as the
+ size of the buffer to allocate. (When this variable is not set,
+ `gawk' uses the smaller of the file's size and the "default"
+ blocksize, which is usually the filesystem's I/O blocksize.)
`AWK_HASH'
- If this variable exists with a value of `gst', `gawk' will switch
- to using the hash function from GNU Smalltalk for managing arrays.
+ If this variable exists with a value of `gst', `gawk' switches to
+ using the hash function from GNU Smalltalk for managing arrays.
This function may be marginally faster than the standard function.
`AWKREADFUNC'
@@ -2669,6 +3037,13 @@ change. The variables are:
debugging problems on filesystems on non-POSIX operating systems
where I/O is performed in records, not in blocks.
+`GAWK_MSG_SRC'
+ If this variable exists, `gawk' includes the file name and line
+ number within the `gawk' source code from which warning and/or
+ fatal messages are generated. Its purpose is to help isolate the
+ source of a message, as there are multiple places that produce the
+ same warning or error message.
+
`GAWK_NO_DFA'
If this variable exists, `gawk' does not use the DFA regexp matcher
for "does it match" kinds of tests. This can cause `gawk' to be
@@ -2681,9 +3056,17 @@ change. The variables are:
This specifies the amount by which `gawk' should grow its internal
evaluation stack, when needed.
+`INT_CHAIN_MAX'
+ This specifies intended maximum number of items `gawk' will
+ maintain on a hash chain for managing arrays indexed by integers.
+
+`STR_CHAIN_MAX'
+ This specifies intended maximum number of items `gawk' will
+ maintain on a hash chain for managing arrays indexed by strings.
+
`TIDYMEM'
If this variable exists, `gawk' uses the `mtrace()' library calls
- from GNU LIBC to help track down possible memory leaks.
+ from the GNU C library to help track down possible memory leaks.

File: gawk.info, Node: Exit Status, Next: Include Files, Prev: Environment Variables, Up: Invoking Gawk
@@ -2700,13 +3083,13 @@ with the value of the C constant `EXIT_SUCCESS'. This is usually zero.
If an error occurs, `gawk' exits with the value of the C constant
`EXIT_FAILURE'. This is usually one.
- If `gawk' exits because of a fatal error, the exit status is 2. On
-non-POSIX systems, this value may be mapped to `EXIT_FAILURE'.
+ If `gawk' exits because of a fatal error, the exit status is two.
+On non-POSIX systems, this value may be mapped to `EXIT_FAILURE'.

-File: gawk.info, Node: Include Files, Next: Obsolete, Prev: Exit Status, Up: Invoking Gawk
+File: gawk.info, Node: Include Files, Next: Loading Shared Libraries, Prev: Exit Status, Up: Invoking Gawk
-2.7 Including Other Files Into Your Program
+2.7 Including Other Files into Your Program
===========================================
This minor node describes a feature that is specific to `gawk'.
@@ -2715,10 +3098,11 @@ This minor node describes a feature that is specific to `gawk'.
files. This gives you the ability to split large `awk' source files
into smaller, more manageable pieces, and also lets you reuse common
`awk' code from various `awk' scripts. In other words, you can group
-together `awk' functions, used to carry out specific tasks, into
-external files. These files can be used just like function libraries,
-using the `@include' keyword in conjunction with the `AWKPATH'
-environment variable.
+together `awk' functions used to carry out specific tasks into external
+files. These files can be used just like function libraries, using the
+`@include' keyword in conjunction with the `AWKPATH' environment
+variable. Note that source files may also be included using the `-i'
+option.
Let's see an example. We'll start with two (trivial) `awk' scripts,
namely `test1' and `test2'. Here is the `test1' script:
@@ -2737,17 +3121,17 @@ and here is `test2':
Running `gawk' with `test2' produces the following result:
$ gawk -f test2
- -| This is file test1.
- -| This is file test2.
+ -| This is script test1.
+ -| This is script test2.
- `gawk' runs the `test2' script which includes `test1' using the
-`@include' keyword. So, to include external `awk' source files you just
-use `@include' followed by the name of the file to be included,
+ `gawk' runs the `test2' script, which includes `test1' using the
+`@include' keyword. So, to include external `awk' source files, you
+just use `@include' followed by the name of the file to be included,
enclosed in double quotes.
NOTE: Keep in mind that this is a language construct and the file
name cannot be a string variable, but rather just a literal string
- in double quotes.
+ constant in double quotes.
The files to be included may be nested; e.g., given a third script,
namely `test3':
@@ -2760,31 +3144,31 @@ namely `test3':
Running `gawk' with the `test3' script produces the following results:
$ gawk -f test3
- -| This is file test1.
- -| This is file test2.
- -| This is file test3.
+ -| This is script test1.
+ -| This is script test2.
+ -| This is script test3.
The file name can, of course, be a pathname. For example:
@include "../io_funcs"
-or:
+and:
@include "/usr/awklib/network"
-are valid. The `AWKPATH' environment variable can be of great value
-when using `@include'. The same rules for the use of the `AWKPATH'
-variable in command-line file searches (*note AWKPATH Variable::) apply
-to `@include' also.
+are both valid. The `AWKPATH' environment variable can be of great
+value when using `@include'. The same rules for the use of the
+`AWKPATH' variable in command-line file searches (*note AWKPATH
+Variable::) apply to `@include' also.
This is very helpful in constructing `gawk' function libraries. If
-you have a large script with useful, general purpose `awk' functions,
+you have a large script with useful, general-purpose `awk' functions,
you can break it down into library files and put those files in a
-special directory. You can then include those "libraries," using
-either the full pathnames of the files, or by setting the `AWKPATH'
+special directory. You can then include those "libraries," either by
+using the full pathnames of the files, or by setting the `AWKPATH'
environment variable accordingly and then using `@include' with just
-the file part of the full pathname. Of course you can have more than
-one directory to keep library files; the more complex the working
+the file part of the full pathname. Of course, you can keep library
+files in more than one directory; the more complex the working
environment is, the more directories you may need to organize the files
to be included.
@@ -2795,38 +3179,116 @@ reducing the need for writing complex and tedious command lines. In
particular, `@include' is very useful for writing CGI scripts to be run
from web pages.
- As mentioned in *Note AWKPATH Variable::, the current directory is
-always searched first for source files, before searching in `AWKPATH',
-and this also applies to files named with `@include'.
+ As mentioned in *note AWKPATH Variable::, the current directory is
+always searched first for source files, before searching in `AWKPATH';
+this also applies to files named with `@include'.
+
+
+File: gawk.info, Node: Loading Shared Libraries, Next: Obsolete, Prev: Include Files, Up: Invoking Gawk
+
+2.8 Loading Dynamic Extensions into Your Program
+================================================
+
+This minor node describes a feature that is specific to `gawk'.
+
+ The `@load' keyword can be used to read external `awk' extensions
+(stored as system shared libraries). This allows you to link in
+compiled code that may offer superior performance and/or give you
+access to extended capabilities not supported by the `awk' language.
+The `AWKLIBPATH' variable is used to search for the extension. Using
+`@load' is completely equivalent to using the `-l' command-line option.
+
+ If the extension is not initially found in `AWKLIBPATH', another
+search is conducted after appending the platform's default shared
+library suffix to the file name. For example, on GNU/Linux systems,
+the suffix `.so' is used:
+
+ $ gawk '@load "ordchr"; BEGIN {print chr(65)}'
+ -| A
+
+This is equivalent to the following example:
+
+ $ gawk -lordchr 'BEGIN {print chr(65)}'
+ -| A
+
+For command-line usage, the `-l' option is more convenient, but `@load'
+is useful for embedding inside an `awk' source file that requires
+access to an extension.
+
+ *note Dynamic Extensions::, describes how to write extensions (in C
+or C++) that can be loaded with either `@load' or the `-l' option. It
+also describes the `ordchr' extension.

-File: gawk.info, Node: Obsolete, Next: Undocumented, Prev: Include Files, Up: Invoking Gawk
+File: gawk.info, Node: Obsolete, Next: Undocumented, Prev: Loading Shared Libraries, Up: Invoking Gawk
-2.8 Obsolete Options and/or Features
+2.9 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
+previous releases of `gawk' that either are not available in the
+current version or are still supported but deprecated (meaning that
they will _not_ be in the next release).
The process-related special files `/dev/pid', `/dev/ppid',
`/dev/pgrpid', and `/dev/user' were deprecated in `gawk' 3.1, but still
worked. As of version 4.0, they are no longer interpreted specially by
-`gawk'. (Use `PROCINFO' instead; see *Note Auto-set::.)
+`gawk'. (Use `PROCINFO' instead; see *note Auto-set::.)

-File: gawk.info, Node: Undocumented, Prev: Obsolete, Up: Invoking Gawk
+File: gawk.info, Node: Undocumented, Next: Invoking Summary, Prev: Obsolete, Up: Invoking Gawk
-2.9 Undocumented Options and Features
-=====================================
+2.10 Undocumented Options and Features
+======================================
- Use the Source, Luke!
- Obi-Wan
+ Use the Source, Luke! -- Obi-Wan
This minor node intentionally left blank.

+File: gawk.info, Node: Invoking Summary, Prev: Undocumented, Up: Invoking Gawk
+
+2.11 Summary
+============
+
+ * Use either `awk 'PROGRAM' FILES' or `awk -f PROGRAM-FILE FILES' to
+ run `awk'.
+
+ * The three standard options for all versions of `awk' are `-f',
+ `-F', and `-v'. `gawk' supplies these and many others, as well as
+ corresponding GNU-style long options.
+
+ * Nonoption command-line arguments are usually treated as file names,
+ unless they have the form `VAR=VALUE', in which case they are
+ taken as variable assignments to be performed at that point in
+ processing the input.
+
+ * All nonoption command-line arguments, excluding the program text,
+ are placed in the `ARGV' array. Adjusting `ARGC' and `ARGV'
+ affects how `awk' processes input.
+
+ * You can use a single minus sign (`-') to refer to standard input
+ on the command line. `gawk' also lets you use the special file
+ name `/dev/stdin'.
+
+ * `gawk' pays attention to a number of environment variables.
+ `AWKPATH', `AWKLIBPATH', and `POSIXLY_CORRECT' are the most
+ important ones.
+
+ * `gawk''s exit status conveys information to the program that
+ invoked it. Use the `exit' statement from within an `awk' program
+ to set the exit status.
+
+ * `gawk' allows you to include other `awk' source files into your
+ program using the `@include' statement and/or the `-i' and `-f'
+ command-line options.
+
+ * `gawk' allows you to load additional functions written in C or C++
+ using the `@load' statement and/or the `-l' option. (This
+ advanced feature is described later, in *note Dynamic
+ Extensions::.)
+
+
File: gawk.info, Node: Regexp, Next: Reading Files, Prev: Invoking Gawk, Up: Top
3 Regular Expressions
@@ -2840,8 +3302,8 @@ strings. Because regular expressions are such a fundamental part of
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
+the regexp `foo' matches any string containing `foo'. Thus, the
+pattern `/foo/' matches any input record containing the three adjacent
characters `foo' _anywhere_ in the record. Other kinds of regexps let
you specify more complicated classes of strings.
@@ -2851,10 +3313,11 @@ you specify more complicated classes of strings.
* Escape Sequences:: How to write nonprinting characters.
* Regexp Operators:: Regular Expression Operators.
* Bracket Expressions:: 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.
+* GNU Regexp Operators:: Operators specific to GNU software.
+* Case-sensitivity:: How to do case-insensitive matching.
+* Regexp Summary:: Regular expressions summary.

File: gawk.info, Node: Regexp Usage, Next: Escape Sequences, Up: Regexp
@@ -2866,27 +3329,27 @@ 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:
+second field of each record where the string `li' appears anywhere in
+the record:
- $ awk '/foo/ { print $2 }' BBS-list
- -| 555-1234
+ $ awk '/li/ { print $2 }' mail-list
+ -| 555-5553
+ -| 555-0542
-| 555-6699
- -| 555-6480
- -| 555-2127
+ -| 555-3430
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:
+statements. (*Note Statements::.) For example, the following is true
+if the expression EXP (taken as a string) matches REGEXP:
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:
+This 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
@@ -2940,20 +3403,20 @@ string or regexp. Thus, the string whose contents are the two
characters `"' and `\' must be written `"\"\\"'.
Other escape sequences represent unprintable characters such as TAB
-or newline. While there is nothing to stop you from entering most
+or newline. There is nothing to stop you from entering most
unprintable characters directly in a string constant or regexp constant,
-they may look ugly.
+but 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:
+ The following list presents 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.)
+ The "alert" character, `Ctrl-g', ASCII code 7 (BEL). (This often
+ makes some sort of audible noise.)
`\b'
Backspace, `Ctrl-h', ASCII code 8 (BS).
@@ -2971,7 +3434,7 @@ apply to both string constants and regexp constants:
Horizontal TAB, `Ctrl-i', ASCII code 9 (HT).
`\v'
- Vertical tab, `Ctrl-k', ASCII code 11 (VT).
+ Vertical TAB, `Ctrl-k', ASCII code 11 (VT).
`\NNN'
The octal value NNN, where NNN stands for 1 to 3 digits between
@@ -2980,77 +3443,84 @@ apply to both string constants and regexp constants:
`\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. (c.e.) However, using
- more than two hexadecimal digits produces undefined results. (The
- `\x' escape sequence is not allowed in POSIX `awk'.)
+ hexadecimal digits (`0'-`9', and either `A'-`F' or `a'-`f'). A
+ maximum of two digts are allowed after the `\x'. Any further
+ hexadecimal digits are treated as simple letters or numbers.
+ (c.e.) (The `\x' escape sequence is not allowed in POSIX awk.)
+
+ CAUTION: In ISO C, the escape sequence continues until the
+ first nonhexadecimal digit is seen. For many years, `gawk'
+ would continue incorporating hexadecimal digits into the
+ value until a non-hexadecimal digit or the end of the string
+ was encountered. However, using more than two hexadecimal
+ digits produced undefined results. As of version *FIXME:*
+ 4.3.0, only two digits are processed.
`\/'
A literal slash (necessary for regexp constants only). This
sequence 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
+ contains a slash (such as `/.*:\/home\/[[:alnum:]]+:.*/'; the
+ `[[:alnum:]]' notation is discussed in *note Bracket
+ Expressions::). Because the regexp is delimited by slashes, you
+ need to escape any 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 sequence 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.
+ that contains a double quote (such as `"He said \"hi!\" to her."').
+ Because the string is delimited by double quotes, you need to
+ escape any 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
+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.
+character not shown in the previous list or that is not an operator.
- 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::.
+ Backslash Before Regular Characters
- * 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
+ 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 Brian Kernighan's `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]+"'.)
+ This is what BWK `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
----------------------------------------------------
+ To summarize:
+
+ * The escape sequences in the preceding list 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.
+
+ 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
+ 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.)
@@ -3070,40 +3540,41 @@ 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
+ 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:
+sequences and that are not listed here stand for themselves:
`\'
- This is used to suppress the special meaning of a character when
- matching. For example, `\$' matches the character `$'.
+ This suppresses 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.
+ This matches the beginning of a string. `^@chapter' matches
+ `@chapter' at the beginning of a string, for example, 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:
+ a line (the point right after a `\n' newline character) 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:
+ is an anchor and does not match the end of a line (the point right
+ before a `\n' newline character) embedded in a string. The
+ condition in the following example is not true:
if ("line1\nLINE 2" ~ /1$/) ...
-`. (period)'
+`.' (period)
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
@@ -3115,15 +3586,15 @@ sequences and that are not listed in the table stand for themselves:
Otherwise, NUL is just another character. Other versions of `awk'
may not be able to match the NUL character.
-`[...]'
+`['...`]'
This is called a "bracket expression".(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 bracket expression is given in *Note Bracket
+ square brackets of a bracket expression is given in *note Bracket
Expressions::.
-`[^ ...]'
+`[^'...`]'
This is a "complemented bracket expression". The first character
after the `[' _must_ be a `^'. It matches any characters _except_
those in the square brackets. For example, `[^awk]' matches any
@@ -3132,14 +3603,15 @@ sequences and that are not listed in the table stand for themselves:
`|'
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.
+ expression operators. For example, `^P|[aeiouy]' matches any
+ string that matches either `^P' or `[aeiouy]'. This means it
+ matches any string that starts with `P' or contains (anywhere
+ within it) a lowercase English vowel.
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,
@@ -3154,31 +3626,29 @@ sequences and that are not listed in the table stand for themselves:
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.
+ There are two subtle points to understand about how `*' works.
+ First, the `*' applies only to the single preceding regular
+ expression component (e.g., in `ph*', it applies just to the `h').
+ To cause `*' to apply to a larger subexpression, use parentheses:
+ `(ph)*' matches `ph', `phph', `phphph', and so on.
+
+ Second, `*' finds as many repetitions as possible. If the text to
+ be matched is `phhhhhhhhhhhhhhooey', `ph*' matches all of the `h's.
`+'
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
+ match all three.
`?'
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}'
+`{'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,
@@ -3190,10 +3660,10 @@ sequences and that are not listed in the table stand for themselves:
Matches `whhhy', but not `why' or `whhhhy'.
`wh{3,5}y'
- Matches `whhhy', `whhhhy', or `whhhhhy', only.
+ Matches `whhhy', `whhhhy', or `whhhhhy' only.
`wh{2,}y'
- Matches `whhy' or `whhhy', and so on.
+ Matches `whhy', `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
@@ -3212,6 +3682,10 @@ sequences and that are not listed in the table stand for themselves:
constants are valid and work the way you want them to, using any
version of `awk'.(2)
+ Finally, when `{' and `}' appear in regexp constants in a way that
+ cannot be interpreted as an interval expression (such as
+ `/q{a}/'), then they stand for themselves.
+
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
@@ -3235,19 +3709,19 @@ list".
regexp operator or function.

-File: gawk.info, Node: Bracket Expressions, Next: GNU Regexp Operators, Prev: Regexp Operators, Up: Regexp
+File: gawk.info, Node: Bracket Expressions, Next: Leftmost Longest, Prev: Regexp Operators, Up: Regexp
3.4 Using Bracket Expressions
=============================
-As mentioned earlier, a bracket expression matches any character amongst
+As mentioned earlier, a bracket expression matches any character among
those listed between the opening and closing square brackets.
Within a bracket expression, a "range expression" consists of two
characters separated by a hyphen. It matches any single character that
sorts between the two characters, based upon the system's native
character set. For example, `[0-9]' is equivalent to `[0123456789]'.
-(See *Note Ranges and Locales::, for an explanation of how the POSIX
+(See *note Ranges and Locales::, for an explanation of how the POSIX
standard and `gawk' have changed over time. This is mainly of
historical interest.)
@@ -3256,10 +3730,12 @@ expression, put a `\' in front of it. For example:
[d\]]
-matches either `d' or `]'.
+matches either `d' or `]'. Additionally, if you place `]' right after
+the opening `[', the closing bracket is treated as one of the
+characters to be matched.
- This treatment of `\' in bracket expressions is compatible with
-other `awk' implementations and is also mandated by POSIX. The regular
+ The treatment of `\' in bracket expressions 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.
@@ -3273,29 +3749,29 @@ differs between the United States and France.
A character class is only valid in a regexp _inside_ the brackets of
a bracket expression. Character classes consist of `[:', a keyword
-denoting the class, and `:]'. *Note table-char-classes:: lists the
+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.
+`[: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).
+ characters)
`[:punct:]' Punctuation characters (characters that are not letters,
- digits, control characters, or space characters).
+ 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.
+ a few)
+`[:upper:]' Uppercase alphabetic characters
+`[:xdigit:]'Characters that are hexadecimal digits
-Table 3.1: POSIX Character Classes
+Table 3.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
@@ -3303,6 +3779,14 @@ set had other alphabetic characters in it, this would not match them.
With the POSIX character classes, you can write `/[[:alnum:]]/' to
match the alphabetic and numeric characters in your character set.
+ Some utilities that match regular expressions provide a nonstandard
+`[:ascii:]' character class; `awk' does not. However, you can simulate
+such a construct using `[\x00-\x7F]'. This matches all values
+numerically between zero and 127, which is the defined range of the
+ASCII character set. Use a complemented character list
+(`[^\x00-\x7F]') to match any single-byte characters that are not in
+the ASCII range.
+
Two additional special sequences can appear in bracket expressions.
These apply to non-ASCII character sets, which can have single symbols
(called "collating elements") that are represented with more than one
@@ -3330,9 +3814,119 @@ Equivalence classes
classes.

-File: gawk.info, Node: GNU Regexp Operators, Next: Case-sensitivity, Prev: Bracket Expressions, Up: Regexp
+File: gawk.info, Node: Leftmost Longest, Next: Computed Regexps, Prev: Bracket Expressions, Up: Regexp
+
+3.5 How Much Text Matches?
+==========================
+
+Consider the following:
+
+ echo aaaabcd | awk '{ sub(/a+/, "<A>"); print }'
+
+ This example uses the `sub()' function to make a change to the input
+record. (`sub()' replaces the first instance of any text matched by
+the first argument with the string provided as the second argument;
+*note String Functions::). 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::).
+
+
+File: gawk.info, Node: Computed Regexps, Next: GNU Regexp Operators, Prev: Leftmost Longest, Up: Regexp
+
+3.6 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 then used as the regexp. A
+regexp computed in this way is called a "dynamic regexp" or a "computed
+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.
+
+ NOTE: 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.
+
+ Using `\n' in Bracket Expressions of Dynamic Regexps
+
+ Some older versions of `awk' do not allow the newline character to
+be used inside a bracket expression for a dynamic regexp:
+
+ $ awk '$0 ~ "[ \t\n]"'
+ error--> awk: newline in character class [
+ error--> ]...
+ error--> source line number 1
+ error--> context is
+ error--> $0 ~ "[ >>> \t\n]" <<<
+
+ 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.
+
+
+File: gawk.info, Node: GNU Regexp Operators, Next: Case-sensitivity, Prev: Computed Regexps, Up: Regexp
-3.5 `gawk'-Specific Regexp Operators
+3.7 `gawk'-Specific Regexp Operators
====================================
GNU software that deals with regular expressions provides a number of
@@ -3378,9 +3972,9 @@ letters, digits, or underscores (`_'):
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:
+"buffer" is, naturally, an Emacs buffer. Other GNU programs, including
+`gawk', consider the entire string to match as the buffer. The
+operators are:
`\`'
Matches the empty string at the beginning of a buffer (string).
@@ -3404,21 +3998,20 @@ GNU `\b' appears to be the lesser of two evils.
No options
In the default case, `gawk' provides all the facilities of POSIX
- regexps and the GNU regexp operators described in *Note Regexp
+ regexps and the GNU regexp operators described in *note Regexp
Operators::.
`--posix'
- Only POSIX regexps are supported; the GNU operators are not special
- (e.g., `\w' matches a literal `w'). Interval expressions are
- allowed.
+ Match only POSIX regexps; 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, and interval expressions are not available. The
- POSIX character classes (`[[:alnum:]]', etc.) are supported, as
- Brian Kernighan's `awk' does support them. Characters described
- by octal and hexadecimal escape sequences are treated literally,
- even if they represent regexp metacharacters.
+ Match traditional Unix `awk' regexps. The GNU operators are not
+ special, and interval expressions are not available. Because BWK
+ `awk' supports them, the POSIX character classes (`[[:alnum:]]',
+ etc.) are available. Characters described by octal and
+ hexadecimal escape sequences are treated literally, even if they
+ represent regexp metacharacters.
`--re-interval'
Allow interval expressions in regexps, if `--traditional' has been
@@ -3426,9 +4019,9 @@ No options
default.

-File: gawk.info, Node: Case-sensitivity, Next: Leftmost Longest, Prev: GNU Regexp Operators, Up: Regexp
+File: gawk.info, Node: Case-sensitivity, Next: Regexp Summary, Prev: GNU Regexp Operators, Up: Regexp
-3.6 Case Sensitivity in Matching
+3.8 Case Sensitivity in Matching
================================
Case is normally significant in regular expressions, both when matching
@@ -3454,10 +4047,11 @@ 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:
+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
@@ -3465,20 +4059,17 @@ zero:
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
+ In general, you cannot use `IGNORECASE' to make certain rules case
+insensitive and other rules case sensitive, as there is no
straightforward way to set `IGNORECASE' just for the pattern of a
particular rule.(1) To do this, use either bracket expressions 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.
+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.
-
- Both regexp and string comparison operations are affected by
-`IGNORECASE'.
+`IGNORECASE' from the command line is a way to make a program case
+insensitive without having to edit it.
In multibyte locales, the equivalences between upper- and lowercase
characters are tested based on the wide-character values of the
@@ -3502,113 +4093,42 @@ obscure and we don't recommend it.
means that `gawk' does the right thing.

-File: gawk.info, Node: Leftmost Longest, Next: Computed Regexps, Prev: Case-sensitivity, Up: Regexp
-
-3.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::).
-
-
-File: gawk.info, Node: Computed Regexps, Prev: Leftmost Longest, Up: Regexp
-
-3.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 then used as the regexp. A
-regexp 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.
-
- NOTE: 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.
+File: gawk.info, Node: Regexp Summary, Prev: Case-sensitivity, Up: Regexp
- 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 `*'.
+3.9 Summary
+===========
- 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:
+ * Regular expressions describe sets of strings to be matched. In
+ `awk', regular expression constants are written enclosed between
+ slashes: `/'...`/'.
- * 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.
+ * Regexp constants may be used standalone in patterns and in
+ conditional expressions, or as part of matching expressions using
+ the `~' and `!~' operators.
- * 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.
+ * Escape sequences let you represent nonprintable characters and
+ also let you represent regexp metacharacters as literal characters
+ to be matched.
- * Using regexp constants is better form; it shows clearly that you
- intend a regexp match.
-
-Advanced Notes: Using `\n' in Bracket Expressions of Dynamic Regexps
---------------------------------------------------------------------
+ * Regexp operators provide grouping, alternation, and repetition.
-Some commercial versions of `awk' do not allow the newline character to
-be used inside a bracket expression for a dynamic regexp:
+ * Bracket expressions give you a shorthand for specifying sets of
+ characters that can match at a particular point in a regexp.
+ Within bracket expressions, POSIX character classes let you specify
+ certain groups of characters in a locale-independent fashion.
- $ awk '$0 ~ "[ \t\n]"'
- error--> awk: newline in character class [
- error--> ]...
- error--> source line number 1
- error--> context is
- error--> >>> <<<
+ * Regular expressions match the leftmost longest text in the string
+ being matched. This matters for cases where you need to know the
+ extent of the match, such as for text substitution and when the
+ record separator is a regexp.
- But a newline in a regexp constant works with no problem:
+ * Matching expressions may use dynamic regexps (i.e., string values
+ treated as regular expressions).
- $ awk '$0 ~ /[ \t\n]/'
- here is a sample line
- -| here is a sample line
- Ctrl-d
+ * `gawk''s `IGNORECASE' variable lets you control the case
+ sensitivity of regexp matching. In other `awk' versions, use
+ `tolower()' or `toupper()'.
- `gawk' does not have this problem, and it isn't likely to occur
-often in practice, but it's worth noting for future reference.

File: gawk.info, Node: Reading Files, Next: Printing, Prev: Regexp, Up: Top
@@ -3621,8 +4141,8 @@ 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 name of the current input file can be found in the predefined
+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
@@ -3644,11 +4164,14 @@ have to be named on the `awk' command line (*note Getline::).
* Field Separators:: The field separator and how to change it.
* Constant Size:: Reading constant width data.
* Splitting By Content:: Defining Fields By Content
-* Multiple Line:: Reading multi-line records.
+* Multiple Line:: Reading multiline records.
* Getline:: Reading files under explicit program control
using the `getline' function.
-* Command line directories:: What happens if you put a directory on the
+* Read Timeout:: Reading input with a timeout.
+* Command-line directories:: What happens if you put a directory on the
command line.
+* Input Summary:: Input summary.
+* Input Exercises:: Exercises.

File: gawk.info, Node: Records, Next: Fields, Up: Reading Files
@@ -3656,97 +4179,129 @@ File: gawk.info, Node: Records, Next: Fields, Up: Reading Files
4.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', records the total number of
-input records read so far from all data files. It starts at zero, but
-is never automatically reset to zero.
+`awk' divides the input for your program into records and fields. It
+keeps track of the number of records that have been read so far from
+the current input file. This value is stored in a predefined variable
+called `FNR', which is reset to zero every time a new file is started.
+Another predefined variable, `NR', records the total number of input
+records read so far from all data files. It starts at zero, but is
+never automatically reset to zero.
+
+* Menu:
+
+* awk split records:: How standard `awk' splits records.
+* gawk split records:: How `gawk' splits records.
+
+
+File: gawk.info, Node: awk split records, Next: gawk split records, Up: Records
+
+4.1.1 Record Splitting with Standard `awk'
+------------------------------------------
- Records are separated by a character called the "record separator".
-By default, the record separator is the newline character. This is why
+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'.
+predefined 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
+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
+ awk 'BEGIN { RS = "u" }
+ { print $0 }' mail-list
+
+changes the value of `RS' to `u', before reading any input. This is a
+string whose first character is the letter "u"; as a result, records
+are separated by the letter "u." 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 `u'
+changed to a newline. Here are the results of running the program on
+`mail-list':
+
+ $ awk 'BEGIN { RS = "u" }
+ > { print $0 }' mail-list
+ -| Amelia 555-5553 amelia.zodiac
+ -| sq
+ -| e@gmail.com F
+ -| Anthony 555-3412 anthony.assert
+ -| ro@hotmail.com A
+ -| Becky 555-7685 becky.algebrar
+ -| m@gmail.com A
+ -| Bill 555-1675 bill.drowning@hotmail.com A
+ -| Broderick 555-0542 broderick.aliq
+ -| otiens@yahoo.com R
+ -| Camilla 555-2912 camilla.inf
+ -| sar
+ -| m@skynet.be R
+ -| Fabi
+ -| s 555-1234 fabi
+ -| s.
+ -| ndevicesim
+ -| s@
+ -| cb.ed
+ -| F
+ -| J
+ -| lie 555-6699 j
+ -| lie.perscr
+ -| tabor@skeeve.com F
+ -| Martin 555-6480 martin.codicib
+ -| s@hotmail.com A
+ -| Sam
+ -| el 555-3430 sam
+ -| el.lanceolis@sh
+ -| .ed
+ -| A
+ -| Jean-Pa
+ -| l 555-2127 jeanpa
+ -| l.campanor
+ -| m@ny
+ -| .ed
+ -| R
-|
-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:
+Note that the entry for the name `Bill' is not split. In the original
+data file (*note Sample Data Files::), the line looks like this:
- camelot 555-0542 300 C
+ Bill 555-1675 bill.drowning@hotmail.com A
-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
+It contains no `u' so there is no reason to split the record, unlike
+the others which have one or more occurrences of the `u'. In fact,
+this record is treated as part of the previous record; 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
+ awk '{ print $0 }' RS="u" mail-list
-This sets `RS' to `/' before processing `BBS-list'.
+This sets `RS' to `u' before processing `mail-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':
+ Using an alphabetic character such as `u' for the record separator
+is highly likely to produce strange results. Using an unusual
+character such as `/' is more likely to produce correct behavior in the
+majority of cases, but there are no guarantees. The moral is: Know Your
+Data.
- $ echo | awk 'BEGIN { RS = "a" } ; { print NF }'
+ When using regular characters as the record separator, there is one
+unusual case that occurs when `gawk' is being fully POSIX-compliant
+(*note Options::). Then, the following (extreme) pipeline prints a
+surprising `1':
+
+ $ echo | gawk --posix '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.
+(In the normal case, `gawk' treats the newline as whitespace, printing
+`0' as the result. Most other versions of `awk' also act this way.)
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
@@ -3765,16 +4320,22 @@ 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::). (c.e.) 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.
+
+File: gawk.info, Node: gawk split records, Prev: awk split records, Up: Records
+
+4.1.2 Record Splitting with `gawk'
+----------------------------------
+
+When using `gawk', the value of `RS' is not limited to a one-character
+string. It can be any regular expression (*note Regexp::). (c.e.) 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
@@ -3790,19 +4351,19 @@ 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 =
- -|
+ > { 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'.
+The square brackets delineate the contents of `RT', letting you see the
+leading and trailing whitespace. The final value of `RT' is a 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
+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'
@@ -3814,18 +4375,17 @@ that this will never happen.
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'.
+ that happens to contain newline characters. It is thus best to
+ avoid anchor metacharacters 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.
+value of `RS' determines the end of the record.
-Advanced Notes: `RS = "\0"' Is Not Portable
--------------------------------------------
+ `RS = "\0"' Is Not Portable
-There are times when you might want to treat an entire data file as a
+ 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
@@ -3838,17 +4398,24 @@ 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.
+record separator. This works for certain special files, such as
+`/proc/environ' on GNU/Linux systems, where the NUL character is in
+fact the record separator. However, this usage is _not_ portable to
+most other `awk' implementations.
- All other `awk' implementations(1) store strings internally as
-C-style strings. C strings use the NUL character as the string
+ Almost 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.
+ It happens that recent versions of `mawk' can use the NUL character
+as a record separator. However, this is a special case: `mawk' does not
+allow embedded NUL characters in strings. (This may change in a future
+version of `mawk'.)
+
+ *Note Readfile Function::, for an interesting way to read whole
+files. If you are using `gawk', see *note Extension Sample Readfile::,
+for another option.
---------- Footnotes ----------
@@ -3864,8 +4431,8 @@ When `awk' reads an input record, the record is automatically "parsed"
or separated by the `awk' utility 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
+newlines;(1) other characters that are considered whitespace by other
+languages (such as formfeed, vertical tab, etc.) are _not_ considered
whitespace by `awk'.
The purpose of fields is to make it more convenient for you to refer
@@ -3873,12 +4440,12 @@ 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,
+ You use a dollar-sign (`$') 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:
+the field numbers are not limited to single digits. `$127' is the
+127th field in the record.) For example, suppose the following is a
+line of input:
This seems like a pretty nice example.
@@ -3887,7 +4454,7 @@ Here the first field, or `$1', is `This', the second field, or `$2', is
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
+ `NF' is a predefined 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
@@ -3896,29 +4463,26 @@ 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
+field, is a special case: it represents the whole input record. Use it
+when you are not interested in specific fields. Here are some more
+examples:
+
+ $ awk '$1 ~ /li/ { print $0 }' mail-list
+ -| Amelia 555-5553 amelia.zodiacusque@gmail.com F
+ -| Julie 555-6699 julie.perscrutabor@skeeve.com F
+
+This example prints each record in the file `mail-list' whose first
+field contains the string `li'.
+
+ By contrast, the following example looks for `li' in _the entire
+record_ and prints the first and last fields for each matching input
+record:
+
+ $ awk '/li/ { print $1, $NF }' mail-list
+ -| Amelia F
+ -| Broderick R
+ -| Julie F
+ -| Samuel A
---------- Footnotes ----------
@@ -3931,31 +4495,31 @@ File: gawk.info, Node: Nonconstant Fields, Next: Changing Fields, Prev: Field
4.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:
+A field number need not 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:
+record, two in the second, and so on. 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 '{ print $(2*2) }' mail-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
+necessary whenever there is a binary operator(1) in the field-number
+expression. This example, then, prints the type of relationship (the
+fourth field) for every line of the file `mail-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.
@@ -3965,11 +4529,17 @@ not allowed; trying to reference one usually terminates the program.
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
+ 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.
+Variables::). Thus, the expression `$NF' is not a special feature--it
+is the direct consequence of evaluating `NF' and using its value as a
+field number.
+
+ ---------- Footnotes ----------
+
+ (1) A "binary operator", such as `*' for multiplication, is one that
+takes two operands. The distinction is required, because `awk' also has
+unary (one-operand) and ternary (three-operand) operators.

File: gawk.info, Node: Changing Fields, Next: Field Separators, Prev: Nonconstant Fields, Up: Reading Files
@@ -3996,11 +4566,11 @@ 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::.
+ For this to work, the text in `$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
@@ -4014,8 +4584,8 @@ subtracted from the second field of each line:
-| Mar 5 24 34 228
...
- It is also possible to also assign contents to fields that are out
-of range. For example:
+ It is also possible to assign contents to fields that are out of
+range. For example:
$ awk '{ $6 = ($5 + $4 + $3 + $2)
> print $6 }' inventory-shipped
@@ -4065,7 +4635,7 @@ even when you assign the empty string to a field. For example:
-| a::c:d
-| 4
-The field is still there; it just has an empty value, denoted by the
+The field is still there; it just has an empty value, delimited by the
two colons between `a' and `c'. This example shows what happens if you
create a new field:
@@ -4082,12 +4652,12 @@ value six.
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 = 3; print $0 }'
-| NF = 6
-| a b c
CAUTION: Some versions of `awk' don't rebuild `$0' when `NF' is
- decremented. Caveat emptor.
+ decremented.
Finally, there are times when it is convenient to force `awk' to
rebuild the entire record, using the current value of the fields and
@@ -4096,8 +4666,8 @@ rebuild the entire record, using the current value of the fields and
$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.
+This forces `awk' to 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
@@ -4105,19 +4675,18 @@ 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::).
-Advanced Notes: Understanding `$0'
-----------------------------------
+ Understanding `$0'
-It is important to remember that `$0' is the _full_ record, exactly as
-it was read from the input. This includes any leading or trailing
+ It is important to remember that `$0' is the _full_ record, exactly
+as it was read from the input. This includes any leading or trailing
whitespace, and the exact whitespace (or other characters) that
separate the fields.
- It is a not-uncommon error to try to change the field separators in
-a record simply by setting `FS' and `OFS', and then expecting a plain
+ It is a common error to try to change the field separators in a
+record simply by setting `FS' and `OFS', and then expecting a plain
`print' or `print $0' to print the modified record.
- But this does not work, since nothing was done to change the record
+ But this does not work, because nothing was done to change the record
itself. Instead, you must force the record to be rebuilt, typically
with a statement such as `$1 = $1', as described earlier.
@@ -4132,7 +4701,8 @@ File: gawk.info, Node: Field Separators, Next: Constant Size, Prev: Changing
* Default Field Splitting:: How fields are normally separated.
* 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.
+* Command Line Field Separator:: Setting `FS' from the command line.
+* Full Line Fields:: Making the full line be a single field.
* Field Splitting Summary:: Some final points and a summary table.
The "field separator", which is either a single character or a
@@ -4150,13 +4720,13 @@ the following line:
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'.
+ The field separator is represented by the predefined 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
+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
@@ -4251,7 +4821,7 @@ letter):
> { print $2 }'
-| a
-In this case, the first field is "null" or empty.
+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:
@@ -4263,25 +4833,24 @@ play whenever `$0' is recomputed. For instance, study this pipeline:
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'.
+`OFS' (which is a space by default). 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'.
There is an additional subtlety to be aware of when using regular
-expressions for field splitting. It is not well-specified in the POSIX
+expressions for field splitting. It is not well specified in the POSIX
standard, or anywhere else, what `^' means when splitting fields. Does
the `^' match only at the beginning of the entire record? Or is each
field separator a new string? It turns out that different `awk'
versions answer this question differently, and you should not rely on
any specific behavior in your programs. (d.c.)
- As a point of information, Brian Kernighan's `awk' allows `^' to
-match only at the beginning of the record. `gawk' also works this way.
-For example:
+ As a point of information, BWK `awk' allows `^' to match only at the
+beginning of the record. `gawk' also works this way. For example:
$ echo 'xxAA xxBxx C' |
> gawk -F '(^x+)|( +)' '{ for (i = 1; i <= NF; i++)
- > printf "-->%s<--\n", $i }'
+ > printf "-->%s<--\n", $i }'
-| --><--
-| -->AA<--
-| -->xxBxx<--
@@ -4314,7 +4883,7 @@ Options::), if `FS' is the null string, then `gawk' also behaves this
way.

-File: gawk.info, Node: Command Line Field Separator, Next: Field Splitting Summary, Prev: Single Character Fields, Up: Field Separators
+File: gawk.info, Node: Command Line Field Separator, Next: Full Line Fields, Prev: Single Character Fields, Up: Field Separators
4.5.4 Setting `FS' from the Command Line
----------------------------------------
@@ -4326,13 +4895,10 @@ For example:
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.
+specifies a file containing an `awk' program.
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
+same way as assignments to the predefined 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:
@@ -4350,60 +4916,101 @@ 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.
+you really do want to separate your fields with `t's. Use `-F '\t''
+when not in compatibility mode to specify that TABs separate fields.
- As an example, let's use an `awk' program file called `baud.awk'
-that contains the pattern `/300/' and the action `print $1':
+ As an example, let's use an `awk' program file called `edu.awk' that
+contains the pattern `/edu/' and the action `print $1':
- /300/ { print $1 }
+ /edu/ { 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
+the file `mail-list'. The following command prints a list of the names
+of the people that work at or attend a university, 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
+ $ awk -F- -f edu.awk mail-list
+ -| Fabius 555
+ -| Samuel 555
+ -| Jean
+
+Note the third line of output. The third line in the original file
looked like this:
- alpo-net 555-3412 2400/1200/300 A
+ Jean-Paul 555-2127 jeanpaul.campanorum@nyu.edu R
- The `-' as part of the system's name was used as the field
+ The `-' as part of the person'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 login name and the second is
-the user's (encrypted or shadow) password. A password file entry might
-look like this:
+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 login name and the
+second is the user's encrypted or shadow password. (A shadow password
+is indicated by the presence of a single `x' in the second field.) A
+password file entry might look like this:
- arnold:xyzzy:2076:10:Arnold Robbins:/home/arnold:/bin/bash
+ arnold:x: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:
+the entries for users whose full name is not indicated:
+
+ awk -F: '$5 == ""' /etc/passwd
+
+
+File: gawk.info, Node: Full Line Fields, Next: Field Splitting Summary, Prev: Command Line Field Separator, Up: Field Separators
+
+4.5.5 Making the Full Line Be a Single Field
+--------------------------------------------
+
+Occasionally, it's useful to treat the whole input line as a single
+field. This can be done easily and portably simply by setting `FS' to
+`"\n"' (a newline):(1)
+
+ awk -F'\n' 'PROGRAM' FILES ...
+
+When you do this, `$1' is the same as `$0'.
- awk -F: '$2 == ""' /etc/passwd
+ 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 older 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'(2) 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 the full
+first line of the file, something like:
+
+ root:x:0:0:Root:/:
+
+ ---------- Footnotes ----------
+
+ (1) Thanks to Andrew Schorr for this tip.
+
+ (2) The `sed' utility is a "stream editor." Its behavior is also
+defined by the POSIX standard.

-File: gawk.info, Node: Field Splitting Summary, Prev: Command Line Field Separator, Up: Field Separators
+File: gawk.info, Node: Field Splitting Summary, Prev: Full Line Fields, Up: Field Separators
-4.5.5 Field-Splitting Summary
+4.5.6 Field-Splitting Summary
-----------------------------
It is important to remember that when you assign a string constant as
@@ -4415,7 +5022,7 @@ 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
+ The following list summarizes how fields are split, based on the
value of `FS' (`==' means "is equal to"):
`FS == " "'
@@ -4435,40 +5042,12 @@ value of `FS' (`==' means "is equal to"):
`FS == ""'
Each individual character in the record becomes a separate field.
- (This is a `gawk' extension; it is not specified by the POSIX
+ (This is a common 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.
+ `FS' and `IGNORECASE'
- However, many older 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
+ 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:
@@ -4480,28 +5059,23 @@ Thus, in the following code:
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
+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.
-

File: gawk.info, Node: Constant Size, Next: Splitting By Content, Prev: Field Separators, Up: Reading Files
4.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.)
+This minor node discusses an advanced feature of `gawk'. If you are a
+novice `awk' user, you might want to skip it on the first reading.
-`gawk' provides 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.
+ `gawk' provides 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
@@ -4531,17 +5105,14 @@ use of `FIELDWIDTHS':
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
+ The following program takes this 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
+ sub(/^ +/, "", idle) # strip leading spaces
if (idle == "")
idle = 0
if (idle ~ /:/) {
@@ -4554,6 +5125,9 @@ calculated idle time:
print $1, $2, idle
}
+ NOTE: The preceding program uses a number of `awk' features that
+ haven't been introduced yet.
+
Running the program on the data produces the following results:
hzuo ttyV0 0
@@ -4597,26 +5171,25 @@ of such a function).

File: gawk.info, Node: Splitting By Content, Next: Multiple Line, Prev: Constant Size, Up: Reading Files
-4.7 Defining Fields By Content
+4.7 Defining Fields by Content
==============================
-(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.)
+This minor node discusses an advanced feature of `gawk'. If you are a
+novice `awk' user, you might want to skip it on the first reading.
-Normally, when using `FS', `gawk' defines the fields as the parts of
+ Normally, when using `FS', `gawk' defines the fields as the parts of
the record that occur in between each field separator. In other words,
`FS' defines what a field _is not_, instead of what a field _is_.
However, there are times when you really want to define the fields by
what they are, and not by what they are not.
- The most notorious such case is so-called "comma separated value"
+ The most notorious such case is so-called "comma-separated values"
(CSV) data. Many spreadsheet programs, for example, can export their
data into text files, where each record is terminated with a newline,
and fields are separated by commas. If only commas separated the data,
there wouldn't be an issue. The problem comes when one of the fields
-contains an _embedded_ comma. While there is no formal standard
-specification for CSV data(1), in such cases, most programs embed the
-field in double quotes. So we might have data like this:
+contains an _embedded_ comma. In such cases, most programs embed the
+field in double quotes.(1) So we might have data like this:
Robbins,Arnold,"1234 A Pretty Street, NE",MyTown,MyState,12345-6789,USA
@@ -4624,7 +5197,7 @@ field in double quotes. So we might have data like this:
value of `FPAT' should be a string that provides a regular expression.
This regular expression describes the contents of each field.
- In the case of CSV data as presented above, each field is either
+ In the case of CSV data as presented here, each field is either
"anything that is not a comma," or "a double quote, anything that is
not a double quote, and a closing double quote." If written as a
regular expression constant (*note Regexp::), we would have
@@ -4671,15 +5244,17 @@ would be to remove the quotes when they occur, with something like this:
As with `FS', the `IGNORECASE' variable (*note User-modified::)
affects field splitting with `FPAT'.
- Similar to `FIELDWIDTHS', the value of `PROCINFO["FS"]' will be
-`"FPAT"' if content-based field splitting is being used.
+ Assigning a value to `FPAT' overrides field splitting with `FS' and
+with `FIELDWIDTHS'. Similar to `FIELDWIDTHS', the value of
+`PROCINFO["FS"]' will be `"FPAT"' if content-based field splitting is
+being used.
NOTE: Some programs export CSV data that contains embedded
newlines between the double quotes. `gawk' provides no way to
- deal with this. Since there is no formal specification for CSV
- data, there isn't much more to be done; the `FPAT' mechanism
+ deal with this. Even though a formal specification for CSV data
+ exists, there isn't much more to be done; the `FPAT' mechanism
provides an elegant solution for the majority of cases, and the
- `gawk' maintainer is satisfied with that.
+ `gawk' developers are satisfied with that.
As written, the regexp used for `FPAT' requires that each field have
a least one character. A straightforward modification (changing
@@ -4690,9 +5265,16 @@ changed the first `+' to `*') allows fields to be empty:
Finally, the `patsplit()' function makes the same functionality
available for splitting regular strings (*note String Functions::).
+ To recap, `gawk' provides three independent methods to split input
+records into fields. `gawk' uses whichever mechanism was last chosen
+based on which of the three variables--`FS', `FIELDWIDTHS', and
+`FPAT'--was last assigned to.
+
---------- Footnotes ----------
- (1) At least, we don't know of one.
+ (1) The CSV format lacked a formal standard definition for many
+years. RFC 4180 (http://www.ietf.org/rfc/rfc4180.txt) standardizes the
+most common practices.

File: gawk.info, Node: Multiple Line, Next: Getline, Prev: Splitting By Content, Up: Reading Files
@@ -4729,8 +5311,8 @@ 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
+ However, 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.)
@@ -4798,8 +5380,8 @@ A simple program to process this file is as follows:
-|
...
- *Note Labels Program::, for a more realistic program that deals with
-address lists. The following table summarizes how records are split,
+ *Note Labels Program::, for a more realistic program dealing with
+address lists. The following list summarizes how records are split,
based on the value of `RS'. (`==' means "is equal to.")
`RS == "\n"'
@@ -4823,9 +5405,10 @@ based on the value of `RS'. (`==' means "is equal to.")
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'. But if the input file ended without any text
-that matches `RS', then `gawk' sets `RT' to the null string.
+ If not in compatibility mode (*note Options::), `gawk' sets `RT' to
+the input text that matched the value specified by `RS'. But if the
+input file ended without any text that matches `RS', then `gawk' sets
+`RT' to the null string.
---------- Footnotes ----------
@@ -4834,13 +5417,13 @@ feature of `RS' does not apply. It does apply to the default field
separator of a single space: `FS = " "'.

-File: gawk.info, Node: Getline, Next: Command line directories, Prev: Multiple Line, Up: Reading Files
+File: gawk.info, Node: Getline, Next: Read Timeout, Prev: Multiple Line, Up: Reading Files
4.9 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
+stream--either the standard input (usually your keyboard, 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.
@@ -4852,8 +5435,8 @@ 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
+ The `getline' command returns 1 if it finds a record and 0 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.
@@ -4862,7 +5445,7 @@ describing the error that occurred.
represents a shell command.
NOTE: When `--sandbox' is specified (*note Options::), reading
- lines from files, pipes and coprocesses is disabled.
+ lines from files, pipes, and coprocesses is disabled.
* Menu:
@@ -4892,38 +5475,48 @@ 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:
+ # Remove text between /* and */, inclusive
{
- 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), "*/")
- offset = t + 2
- while (u == 0) {
- if (getline <= 0) {
- m = "unexpected EOF or error"
- m = (m ": " ERRNO)
- print m > "/dev/stderr"
+ if ((i = index($0, "/*")) != 0) {
+ out = substr($0, 1, i - 1) # leading part of the string
+ rest = substr($0, i + 2) # ... */ ...
+ j = index(rest, "*/") # is */ in trailing part?
+ if (j > 0) {
+ rest = substr(rest, j + 2) # remove comment
+ } else {
+ while (j == 0) {
+ # get more text
+ if (getline <= 0) {
+ print("unexpected EOF or error:", ERRNO) > "/dev/stderr"
exit
- }
- u = index($0, "*/")
- offset = 0
- }
- # substr() expression will be "" if */
- # occurred at end of line
- $0 = tmp substr($0, offset + u + 2)
- }
- print $0
+ }
+ # build up the line using string concatenation
+ rest = rest $0
+ j = index(rest, "*/") # is */ in trailing part?
+ if (j != 0) {
+ rest = substr(rest, j + 2)
+ break
+ }
+ }
+ }
+ # build up the output line using string concatenation
+ $0 = out rest
+ }
+ print $0
}
This `awk' program deletes 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'.
+input. It uses a number of features we haven't covered yet, including
+string concatenation (*note Concatenation::) and the `index()' and
+`substr()' built-in functions (*note String Functions::). 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', `RT', 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
@@ -4968,10 +5561,10 @@ and produces these results:
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.
+ The `getline' command used in this way sets only the variables `NR',
+`FNR', and `RT' (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.

File: gawk.info, Node: Getline/File, Next: Getline/Variable/File, Prev: Getline/Variable, Up: Getline
@@ -4997,14 +5590,14 @@ with a value equal to 10 in the current input file:
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'.
+are changed, resulting in a new value of `NF'. `RT' is also set.
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
-all `awk' implementations.
+concatenation operator (not discussed yet; *note Concatenation::) is
+not parenthesized. You should write it as `getline < (dir "/" file)' if
+you want your program to be portable to all `awk' implementations.

File: gawk.info, Node: Getline/Variable/File, Next: Getline/Pipe, Prev: Getline/File, Up: Getline
@@ -5013,10 +5606,10 @@ File: gawk.info, Node: Getline/Variable/File, Next: Getline/Pipe, Prev: Getli
-------------------------------------------------
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 the variable VAR. As earlier, 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
+ In this version of `getline', none of the predefined variables are
changed and the record is not split into fields. The only variable
changed is VAR.(1) For example, the following program copies all the
input files to the output, except for records that say
@@ -5056,7 +5649,10 @@ File: gawk.info, Node: Getline/Pipe, Next: Getline/Variable/Pipe, Prev: Getli
4.9.5 Using `getline' from a Pipe
---------------------------------
-The output of a command can also be piped into `getline', using
+ Omniscience has much to recommend it. Failing that, attention to
+ details would be useful. -- Brian Kernighan
+
+ 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
@@ -5094,13 +5690,13 @@ the program might produce:
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.)
+Notice that this program ran the command `who' and printed the 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.
+and `FNR' are not changed. `RT' is set.
According to POSIX, `EXPRESSION | getline' is ambiguous if
EXPRESSION contains unparenthesized operators other than `$'--for
@@ -5112,10 +5708,10 @@ all `awk' implementations.
NOTE: Unfortunately, `gawk' has not been consistent in its
treatment of a construct like `"echo " "date" | getline'. Most
versions, including the current version, treat it at as `("echo "
- "date") | getline'. (This how Brian Kernighan's `awk' behaves.)
- Some versions changed and treated it as `"echo " ("date" |
- getline)'. (This is how `mawk' behaves.) In short, _always_ use
- explicit parentheses, and then you won't have to worry.
+ "date") | getline'. (This is also how BWK `awk' behaves.) Some
+ versions changed and treated it as `"echo " ("date" | getline)'.
+ (This is how `mawk' behaves.) In short, _always_ use explicit
+ parentheses, and then you won't have to worry.

File: gawk.info, Node: Getline/Variable/Pipe, Next: Getline/Coprocess, Prev: Getline/Pipe, Up: Getline
@@ -5134,8 +5730,8 @@ following program reads the current date and time into the variable
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.
+ In this version of `getline', none of the predefined variables are
+changed and the record is not split into fields. However, `RT' is set.
According to POSIX, `EXPRESSION | getline VAR' is ambiguous if
EXPRESSION contains unparenthesized operators other than `$'; for
@@ -5168,7 +5764,7 @@ 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'.
+and of `NF' and `RT'.
Coprocesses are an advanced feature. They are discussed here only
because this is the minor node on `getline'. *Note Two-way I/O::,
@@ -5184,9 +5780,9 @@ 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
+ In this version of `getline', none of the predefined variables are
changed and the record is not split into fields. The only variable
-changed is VAR.
+changed is VAR. However, `RT' is set.
Coprocesses are an advanced feature. They are discussed here only
because this is the minor node on `getline'. *Note Two-way I/O::,
@@ -5206,10 +5802,10 @@ in mind:
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.
+ * Some very old `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
@@ -5217,62 +5813,276 @@ in mind:
`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::.)
+ files. (d.c.) (See *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
+ `$0' and `NF' 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.
- * *Note Getline Summary::, presents a table summarizing the
+ * *note Getline Summary::, presents a table summarizing the
`getline' variants and which variables they can affect. It is
worth noting that those variants which do not use redirection can
cause `FILENAME' to be updated if they cause `awk' to start
reading a new input file.
+ * If the variable being assigned is an expression with side effects,
+ different versions of `awk' behave differently upon encountering
+ end-of-file. Some versions don't evaluate the expression; many
+ versions (including `gawk') do. Here is an example, due to Duncan
+ Moore:
+
+ BEGIN {
+ system("echo 1 > f")
+ while ((getline a[++c] < "f") > 0) { }
+ print c
+ }
+
+ Here, the side effect is the `++c'. Is `c' incremented if end of
+ file is encountered, before the element in `a' is assigned?
+
+ `gawk' treats `getline' like a function call, and evaluates the
+ expression `a[++c]' before attempting to read from `f'. However,
+ some versions of `awk' only evaluate the expression once they know
+ that there is a string value to be assigned.
+

File: gawk.info, Node: Getline Summary, Prev: Getline Notes, Up: Getline
4.9.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, and
-whether the variant is standard or a `gawk' extension.
+*note table-getline-variants:: summarizes the eight variants of
+`getline', listing which predefined variables are set by each one, and
+whether the variant is standard or a `gawk' extension. Note: for each
+variant, `gawk' sets the `RT' predefined variable.
-Variant Effect Standard /
- Extension
+Variant Effect `awk' / `gawk'
-------------------------------------------------------------------------
-`getline' Sets `$0', `NF', `FNR', Standard
- and `NR'
-`getline' VAR Sets VAR, `FNR', and `NR' Standard
-`getline <' FILE Sets `$0' and `NF' Standard
-`getline VAR < FILE' Sets VAR Standard
-COMMAND `| getline' Sets `$0' and `NF' Standard
-COMMAND `| getline' VAR Sets VAR Standard
-COMMAND `|& getline' Sets `$0' and `NF' Extension
-COMMAND `|& getline' Sets VAR Extension
+`getline' Sets `$0', `NF', `FNR', `awk'
+ `NR', and `RT'
+`getline' VAR Sets VAR, `FNR', `NR', and `awk'
+ `RT'
+`getline <' FILE Sets `$0', `NF', and `RT' `awk'
+`getline VAR < FILE' Sets VAR and `RT' `awk'
+COMMAND `| getline' Sets `$0', `NF', and `RT' `awk'
+COMMAND `| getline' VAR Sets VAR and `RT' `awk'
+COMMAND `|& getline' Sets `$0', `NF', and `RT' `gawk'
+COMMAND `|& getline' Sets VAR and `RT' `gawk'
VAR
-Table 4.1: getline Variants and What They Set
+Table 4.1: `getline' variants and what they set

-File: gawk.info, Node: Command line directories, Prev: Getline, Up: Reading Files
+File: gawk.info, Node: Read Timeout, Next: Command-line directories, Prev: Getline, Up: Reading Files
+
+4.10 Reading Input with a Timeout
+=================================
-4.10 Directories On The Command Line
+This minor node describes a feature that is specific to `gawk'.
+
+ You may specify a timeout in milliseconds for reading input from the
+keyboard, a pipe, or two-way communication, including TCP/IP sockets.
+This can be done on a per input, command, or connection basis, by
+setting a special element in the `PROCINFO' array (*note Auto-set::):
+
+ PROCINFO["input_name", "READ_TIMEOUT"] = TIMEOUT IN MILLISECONDS
+
+ When set, this causes `gawk' to time out and return failure if no
+data is available to read within the specified timeout period. For
+example, a TCP client can decide to give up on receiving any response
+from the server after a certain amount of time:
+
+ Service = "/inet/tcp/0/localhost/daytime"
+ PROCINFO[Service, "READ_TIMEOUT"] = 100
+ if ((Service |& getline) > 0)
+ print $0
+ else if (ERRNO != "")
+ print ERRNO
+
+ Here is how to read interactively from the user(1) without waiting
+for more than five seconds:
+
+ PROCINFO["/dev/stdin", "READ_TIMEOUT"] = 5000
+ while ((getline < "/dev/stdin") > 0)
+ print $0
+
+ `gawk' terminates the read operation if input does not arrive after
+waiting for the timeout period, returns failure and sets `ERRNO' to an
+appropriate string value. A negative or zero value for the timeout is
+the same as specifying no timeout at all.
+
+ A timeout can also be set for reading from the keyboard in the
+implicit loop that reads input records and matches them against
+patterns, like so:
+
+ $ gawk 'BEGIN { PROCINFO["-", "READ_TIMEOUT"] = 5000 }
+ > { print "You entered: " $0 }'
+ gawk
+ -| You entered: gawk
+
+ In this case, failure to respond within five seconds results in the
+following error message:
+
+ error--> gawk: cmd. line:2: (FILENAME=- FNR=1) fatal: error reading input file `-': Connection timed out
+
+ The timeout can be set or changed at any time, and will take effect
+on the next attempt to read from the input device. In the following
+example, we start with a timeout value of one second, and progressively
+reduce it by one-tenth of a second until we wait indefinitely for the
+input to arrive:
+
+ PROCINFO[Service, "READ_TIMEOUT"] = 1000
+ while ((Service |& getline) > 0) {
+ print $0
+ PROCINFO[Service, "READ_TIMEOUT"] -= 100
+ }
+
+ NOTE: You should not assume that the read operation will block
+ exactly after the tenth record has been printed. It is possible
+ that `gawk' will read and buffer more than one record's worth of
+ data the first time. Because of this, changing the value of
+ timeout like in the preceding example is not very useful.
+
+ If the `PROCINFO' element is not present and the `GAWK_READ_TIMEOUT'
+environment variable exists, `gawk' uses its value to initialize the
+timeout value. The exclusive use of the environment variable to
+specify timeout has the disadvantage of not being able to control it on
+a per command or connection basis.
+
+ `gawk' considers a timeout event to be an error even though the
+attempt to read from the underlying device may succeed in a later
+attempt. This is a limitation, and it also means that you cannot use
+this to multiplex input from two or more sources.
+
+ Assigning a timeout value prevents read operations from blocking
+indefinitely. But bear in mind that there are other ways `gawk' can
+stall waiting for an input device to be ready. A network client can
+sometimes take a long time to establish a connection before it can
+start reading any data, or the attempt to open a FIFO special file for
+reading can block indefinitely until some other process opens it for
+writing.
+
+ ---------- Footnotes ----------
+
+ (1) This assumes that standard input is the keyboard.
+
+
+File: gawk.info, Node: Command-line directories, Next: Input Summary, Prev: Read Timeout, Up: Reading Files
+
+4.11 Directories on the Command Line
====================================
According to the POSIX standard, files named on the `awk' command line
-must be text files. It is a fatal error if they are not. Most
-versions of `awk' treat a directory on the command line as a fatal
-error.
+must be text files; it is a fatal error if they are not. Most versions
+of `awk' treat a directory on the command line as a fatal error.
By default, `gawk' produces a warning for a directory on the command
-line, but otherwise ignores it. If either of the `--posix' or
-`--traditional' options is given, then `gawk' reverts to treating a
-directory on the command line as a fatal error.
+line, but otherwise ignores it. This makes it easier to use shell
+wildcards with your `awk' program:
+
+ $ gawk -f whizprog.awk * Directories could kill this program
+
+ If either of the `--posix' or `--traditional' options is given, then
+`gawk' reverts to treating a directory on the command line as a fatal
+error.
+
+ *Note Extension Sample Readdir::, for a way to treat directories as
+usable data from an `awk' program.
+
+
+File: gawk.info, Node: Input Summary, Next: Input Exercises, Prev: Command-line directories, Up: Reading Files
+
+4.12 Summary
+============
+
+ * Input is split into records based on the value of `RS'. The
+ possibilities are as follows:
+
+ Value of `RS' Records are split on `awk' / `gawk'
+ ...
+ ----------------------------------------------------------------------
+ Any single That character `awk'
+ character
+ The empty string Runs of two or more `awk'
+ (`""') newlines
+ A regexp Text that matches the `gawk'
+ regexp
+
+ * `FNR' indicates how many records have been read from the current
+ input file; `NR' indicates how many records have been read in
+ total.
+
+ * `gawk' sets `RT' to the text matched by `RS'.
+
+ * After splitting the input into records, `awk' further splits the
+ record into individual fields, named `$1', `$2', and so on. `$0'
+ is the whole record, and `NF' indicates how many fields there are.
+ The default way to split fields is between whitespace characters.
+
+ * Fields may be referenced using a variable, as in `$NF'. Fields
+ may also be assigned values, which causes the value of `$0' to be
+ recomputed when it is later referenced. Assigning to a field with
+ a number greater than `NF' creates the field and rebuilds the
+ record, using `OFS' to separate the fields. Incrementing `NF'
+ does the same thing. Decrementing `NF' throws away fields and
+ rebuilds the record.
+
+ * Field splitting is more complicated than record splitting:
+
+ Field separator value Fields are split ... `awk' /
+ `gawk'
+ ----------------------------------------------------------------------
+ `FS == " "' On runs of whitespace `awk'
+ `FS == ANY SINGLE On that character `awk'
+ CHARACTER'
+ `FS == REGEXP' On text matching the regexp `awk'
+ `FS == ""' Each individual character is `gawk'
+ a separate field
+ `FIELDWIDTHS == LIST OF Based on character position `gawk'
+ COLUMNS'
+ `FPAT == REGEXP' On the text surrounding text `gawk'
+ matching the regexp
+
+ * Using `FS = "\n"' causes the entire record to be a single field
+ (assuming that newlines separate records).
+
+ * `FS' may be set from the command line using the `-F' option. This
+ can also be done using command-line variable assignment.
+
+ * Use `PROCINFO["FS"]' to see how fields are being split.
+
+ * Use `getline' in its various forms to read additional records,
+ from the default input stream, from a file, or from a pipe or
+ coprocess.
+
+ * Use `PROCINFO[FILE, "READ_TIMEOUT"]' to cause reads to timeout for
+ FILE.
+
+ * Directories on the command line are fatal for standard `awk';
+ `gawk' ignores them if not in POSIX mode.
+
+
+
+File: gawk.info, Node: Input Exercises, Prev: Input Summary, Up: Reading Files
+
+4.13 Exercises
+==============
+
+ 1. Using the `FIELDWIDTHS' variable (*note Constant Size::), write a
+ program to read election data, where each record represents one
+ voter's votes. Come up with a way to define which columns are
+ associated with each ballot item, and print the total votes,
+ including abstentions, for each item.
+
+ 2. *note Plain Getline::, presented a program to remove C-style
+ comments (`/* ... */') from the input. That program does not work
+ if one comment ends on one line and another one starts later on
+ the same line. That can be fixed by making one simple change.
+ What is it?
+

File: gawk.info, Node: Printing, Next: Expressions, Prev: Reading Files, Up: Top
@@ -5286,7 +6096,7 @@ 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
+so on. (For the exceptions, *note Output Separators::, and *note
OFMT::.) For printing with specifications, you need the `printf'
statement (*note Printf::).
@@ -5304,10 +6114,13 @@ function.
* Printf:: The `printf' statement.
* Redirection:: How to redirect output to multiple files and
pipes.
+* Special FD:: Special files for I/O.
* 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.
+* Output Summary:: Output summary.
+* Output Exercises:: Exercises.

File: gawk.info, Node: Print, Next: Print Examples, Up: Printing
@@ -5315,10 +6128,10 @@ File: gawk.info, Node: Print, Next: Print Examples, Up: Printing
5.1 The `print' Statement
=========================
-The `print' statement is used for producing 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:
+Use the `print' statement to produce output with simple, standardized
+formatting. You 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, ...
@@ -5333,11 +6146,15 @@ 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.
+`print ""'. 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.
+
+ Note that the `print' statement is a statement and not an
+expression--you can't use it in the pattern part of a PATTERN-ACTION
+statement, for example.

File: gawk.info, Node: Print Examples, Next: Output Separators, Prev: Print, Up: Printing
@@ -5385,8 +6202,8 @@ Here is the same program, without the comma:
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:
+(`$1') and green crates shipped (`$2'). We do this using a `BEGIN'
+rule (*note BEGIN/END::) so that the headings are only printed once:
awk 'BEGIN { print "Month Crates"
print "----- ------" }
@@ -5429,15 +6246,16 @@ 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 simply 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 field separator" by setting the predefined variable `OFS'.
+The initial value of this variable is the string `" "' (i.e., 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.
+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
@@ -5449,13 +6267,29 @@ 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
+ > { print $1, $2 }' mail-list
+ -| Amelia;555-5553
-|
- -| alpo-net;555-3412
+ -| Anthony;555-3412
+ -|
+ -| Becky;555-7685
+ -|
+ -| Bill;555-1675
+ -|
+ -| Broderick;555-0542
+ -|
+ -| Camilla;555-2912
+ -|
+ -| Fabius;555-1234
+ -|
+ -| Julie;555-6699
+ -|
+ -| Martin;555-6480
+ -|
+ -| Samuel;555-3430
+ -|
+ -| Jean-Paul;555-2127
-|
- -| barfly;555-7685
- ...
If the value of `ORS' does not contain a newline, the program's
output runs together on a single line.
@@ -5473,14 +6307,14 @@ that string. `awk' uses the `sprintf()' function to do this conversion
`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::.
+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:
+ The predefined variable `OFMT' contains the 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 a different
+format specification for the value of `OFMT', as shown in the following
+example:
$ awk 'BEGIN {
> OFMT = "%.0f" # print numbers as integers (rounds)
@@ -5502,8 +6336,6 @@ by `print', use `printf'. With `printf' you can 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).
-You do this by supplying a string, called the "format string", that
-controls how and where to print the other arguments.
* Menu:
@@ -5522,10 +6354,10 @@ 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 an output
-redirection (*note Redirection::).
+As for `print', the entire list of arguments may optionally be enclosed
+in parentheses. Here too, the parentheses are necessary if any of the
+item expressions use the `>' relational operator; otherwise, it can be
+confused with an output 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
@@ -5546,12 +6378,12 @@ statements. For example:
$ awk 'BEGIN {
> ORS = "\nOUCH!\n"; OFS = "+"
- > msg = "Dont Panic!"
+ > msg = "Don\47t Panic!"
> printf "%s\n", msg
> }'
- -| Dont Panic!
+ -| Don't Panic!
-Here, neither the `+' nor the `OUCH' appear in the output message.
+Here, neither the `+' nor the `OUCH!' appear in the output message.

File: gawk.info, Node: Control Letters, Next: Format Modifiers, Prev: Basic Printf, Up: Printf
@@ -5567,9 +6399,9 @@ print. The rest of the format specifier is made up of optional
width. Here is a list of the format-control letters:
`%c'
- Print 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.
+ Print a number as a character; thus, `printf "%c", 65' outputs the
+ letter `A'. The output for a string value is the first character
+ of the string.
NOTE: The POSIX standard says the first character of a string
is printed. In locales with multibyte characters, `gawk'
@@ -5577,17 +6409,19 @@ width. Here is a list of the format-control letters:
valid wide character and then to print the multibyte encoding
of that character. Similarly, when printing a numeric value,
`gawk' allows the value to be within the numeric range of
- values that can be held in a wide character.
+ values that can be held in a wide character. If the
+ conversion to multibyte encoding fails, `gawk' uses the low
+ eight bits of the value as the character to print.
Other `awk' versions generally restrict themselves to printing
the first byte of a string or to numeric values within the
range of a single byte (0-255).
-`%d, %i'
+`%d', `%i'
Print a decimal integer. The two control letters are equivalent.
(The `%i' specification is for compatibility with ISO C.)
-`%e, %E'
+`%e', `%E'
Print a number in scientific (exponential) notation; for example:
printf "%4.3e\n", 1950
@@ -5606,10 +6440,11 @@ width. Here is a list of the format-control letters:
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
+ 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'.
+ `-infinity', and positive infinity as `inf' or `infinity'. The
+ special "not a number" value formats as `-nan' or `nan' (*note
+ Math Definitions::).
`%F'
Like `%f' but the infinity and "not a number" values are spelled
@@ -5618,7 +6453,7 @@ width. Here is a list of the format-control letters:
The `%F' format is a POSIX extension to ISO C; not all systems
support it. On those that don't, `gawk' uses `%f' instead.
-`%g, %G'
+`%g', `%G'
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'.
@@ -5631,10 +6466,10 @@ width. Here is a list of the format-control letters:
`%u'
Print an unsigned decimal integer. (This format is of marginal
- use, because all numbers in `awk' are floating-point; it is
+ use, because all numbers in `awk' are floating point; it is
provided primarily for compatibility with C.)
-`%x, %X'
+`%x', `%X'
Print an unsigned hexadecimal integer; `%X' uses the letters `A'
through `F' instead of `a' through `f' (*note
Nondecimal-numbers::).
@@ -5659,7 +6494,7 @@ File: gawk.info, Node: Format Modifiers, Next: Printf Examples, Prev: Control
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
+We 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:
@@ -5679,10 +6514,9 @@ which they may appear:
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.
+ and why to use positional specifiers. For now, we ignore them.
-`-'
+`- (Minus)'
The minus sign, used before the width modifier (see later on in
this list), says to left-justify the argument within its specified
width. Normally, the argument is printed right-justified in the
@@ -5703,21 +6537,21 @@ which they may appear:
space modifier.
`#'
- Use an "alternate form" for certain control letters. For `%o',
+ Use an "alternative 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', `%f', 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 only
- to the numeric output formats. This flag only has an effect when
- the field width is wider than the value to print.
+ A leading `0' (zero) acts as a flag indicating that output should
+ be padded with zeros instead of spaces. This applies only to the
+ numeric output formats. This flag only has an effect when the
+ field width is wider than the value to print.
`''
A single quote or apostrophe character is a POSIX extension to ISO
- C. It indicates that the integer part of a floating point value,
+ 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:
@@ -5730,12 +6564,12 @@ which they may appear:
-| 1,234,567 Results in US English UTF locale
For more information about locales and internationalization issues,
- see *Note Locales::.
+ see *note Locales::.
NOTE: The `'' flag is a nice feature, but its use complicates
things: it becomes difficult to use it in command-line
programs. For information on appropriate quoting tricks, see
- *Note Quoting::.
+ *note Quoting::.
`WIDTH'
This is a number specifying the desired minimum width of a field.
@@ -5782,10 +6616,10 @@ which they may appear:
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:
+ The C library `printf''s dynamic WIDTH and PREC capability (e.g.,
+`"%*.*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
@@ -5809,11 +6643,12 @@ string, like so:
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 them. 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.
+ C programmers may be used to supplying additional modifiers (`h',
+`j', `l', `L', `t', and `z') in `printf' format strings. These are not
+valid in `awk'. Most `awk' implementations silently ignore them. 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.

File: gawk.info, Node: Printf Examples, Prev: Format Modifiers, Up: Printf
@@ -5824,25 +6659,25 @@ File: gawk.info, Node: Printf Examples, Prev: Format Modifiers, Up: Printf
The following simple example shows how to use `printf' to make an
aligned table:
- awk '{ printf "%-10s %s\n", $1, $2 }' BBS-list
+ awk '{ printf "%-10s %s\n", $1, $2 }' mail-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
+This command prints the names of the people (`$1') in the file
+`mail-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
+ $ awk '{ printf "%-10s %s\n", $1, $2 }' mail-list
+ -| Amelia 555-5553
+ -| Anthony 555-3412
+ -| Becky 555-7685
+ -| Bill 555-1675
+ -| Broderick 555-0542
+ -| Camilla 555-2912
+ -| Fabius 555-1234
+ -| Julie 555-6699
+ -| Martin 555-6480
+ -| Samuel 555-3430
+ -| Jean-Paul 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
@@ -5854,20 +6689,21 @@ 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
+tops of the columns. This is done using a `BEGIN' rule (*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
+ { printf "%-10s %s\n", $1, $2 }' mail-list
- The above example mixes `print' and `printf' statements in the same
-program. Using just `printf' statements can produce the same results:
+ The preceding example mixes `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
+ { printf "%-10s %s\n", $1, $2 }' mail-list
Printing each column heading with the same format specification used
for the column elements ensures that the headings are aligned just like
@@ -5879,15 +6715,10 @@ 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::).
+ { printf format, $1, $2 }' mail-list

-File: gawk.info, Node: Redirection, Next: Special Files, Prev: Printf, Up: Printing
+File: gawk.info, Node: Redirection, Next: Special FD, Prev: Printf, Up: Printing
5.6 Redirecting Output of `print' and `printf'
==============================================
@@ -5897,7 +6728,7 @@ output, usually the screen. Both `print' and `printf' can also send
their output to other places. This is called "redirection".
NOTE: When `--sandbox' is specified (*note Options::), redirecting
- output to files and pipes is disabled.
+ output to files, pipes and coprocesses is disabled.
A redirection appears after the `print' or `printf' statement.
Redirections in `awk' are written just like redirections in shell
@@ -5905,7 +6736,7 @@ 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
+to a coprocess. We show them all for the `print' statement, but they
work identically for `printf':
`print ITEMS > OUTPUT-FILE'
@@ -5919,19 +6750,19 @@ work identically for `printf':
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
+ is how an `awk' program can write a list of peoples' 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
+ > print $1 > "name-list" }' mail-list
$ cat phone-list
-| 555-5553
-| 555-3412
...
$ cat name-list
- -| aardvark
- -| alpo-net
+ -| Amelia
+ -| Anthony
...
Each output file contains one name or number per line.
@@ -5952,12 +6783,12 @@ work identically for `printf':
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
+ one unsorted list of peoples' names, and one list sorted in reverse
alphabetical order:
awk '{ print $1 > "names.unsorted"
command = "sort -r > names.sorted"
- print $1 | command }' BBS-list
+ print $1 | command }' mail-list
The unsorted list is written with an ordinary redirection, while
the sorted list is written by piping through the `sort' utility.
@@ -5968,16 +6799,10 @@ work identically for `printf':
maintenance:
report = "mail bug-system"
- print "Awk script failed:", $0 | report
- m = ("at record number " FNR " of " FILENAME)
- print m | report
+ print("Awk script failed:", $0) | report
+ print("at record number", FNR, "of", FILENAME) | 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.
@@ -5986,7 +6811,7 @@ work identically for `printf':
FILE or COMMAND--it is not necessary to always use a string
constant. Using a variable is generally a good idea, because (if
you mean to refer to that same file or command) `awk' requires
- that the string value be spelled identically every time.
+ that the string value be written identically every time.
`print ITEMS |& COMMAND'
This redirection prints the items to the input of COMMAND. The
@@ -6015,7 +6840,7 @@ a file, and then to use `>>' for subsequent output:
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
+`>' for all the `print' statements, because the output file is only
opened once. (It happens that if you mix `>' and `>>' that output is
produced in the expected order. However, mixing the operators for the
same file is definitely poor style, and is confusing to readers of your
@@ -6026,14 +6851,13 @@ 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'
---------------------------------
+ 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:
+ 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" }
@@ -6044,67 +6868,56 @@ 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.
-
-File: gawk.info, Node: Special Files, Next: Close Files And Pipes, Prev: Redirection, Up: Printing
-
-5.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 and TCP/IP networking.
-
-* Menu:
-
-* Special FD:: Special files for I/O.
-* Special Network:: Special files for network communications.
-* Special Caveats:: Things to watch out for.
+ *Note Shell Quoting::, for a function that can help in generating
+command lines to be fed to the shell.

-File: gawk.info, Node: Special FD, Next: Special Network, Up: Special Files
+File: gawk.info, Node: Special FD, Next: Special Files, Prev: Redirection, Up: Printing
-5.7.1 Special Files for Standard Descriptors
---------------------------------------------
+5.7 Special Files for Standard Pre-Opened Data Streams
+======================================================
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 keyboard and screen,
-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,
+These open streams (and any other open file or pipe) are often referred
+to by the technical term "file descriptors".
+
+ These streams are, by default, connected to your keyboard and
+screen, 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:
+ In traditional 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 screen, like this:
+far from elegant, and it also requires a separate process. So people
+writing `awk' programs often don't do this. Instead, they send the
+error messages to the screen, like this:
print "Serious error detected!" > "/dev/tty"
(`/dev/tty' is a special file supplied by the operating system that is
connected to your keyboard and screen. It represents the "terminal,"(1)
which on modern systems is a keyboard and screen, not a serial console.)
-This usually has the same effect but not always: although the standard
-error stream is usually the screen, it can be redirected; when that
-happens, writing to the screen is not correct. In fact, if `awk' is
-run from a background job, it may not have a terminal at all. Then
+This generally has the same effect but not always: although the
+standard error stream is usually the screen, it can be redirected; when
+that happens, writing to the screen 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. (c.e.). It also provides syntax for accessing 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:
+ `gawk', BWK `awk', and `mawk' provide special file names for
+accessing the three standard streams. If the file name matches one of
+these special names when `gawk' (or one of the others) redirects input
+or output, then it directly uses the descriptor 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).
@@ -6115,16 +6928,8 @@ those that are POSIX-compliant:
`/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:
+ With these facilities, the proper way to write an error message then
+becomes:
print "Serious error detected!" > "/dev/stderr"
@@ -6132,21 +6937,60 @@ error message in a `gawk' program is to use `/dev/stderr', like this:
redirection, the value must be a string. It is a common error to omit
the quotes, which leads to confusing results.
- Finally, using the `close()' function on a file name of the form
-`"/dev/fd/N"', for file descriptor numbers above two, will actually
-close the given file descriptor.
-
- The `/dev/stdin', `/dev/stdout', and `/dev/stderr' special files are
-also recognized internally by several other versions of `awk'.
+ `gawk' does not treat these file names as special when in
+POSIX-compatibility mode. However, because BWK `awk' supports them,
+`gawk' does support them even when invoked with the `--traditional'
+option (*note Options::).
---------- Footnotes ----------
(1) The "tty" in `/dev/tty' stands for "Teletype," a serial terminal.

-File: gawk.info, Node: Special Network, Next: Special Caveats, Prev: Special FD, Up: Special Files
+File: gawk.info, Node: Special Files, Next: Close Files And Pipes, Prev: Special FD, Up: Printing
+
+5.8 Special File Names in `gawk'
+================================
+
+Besides access to standard input, standard output, and standard error,
+`gawk' provides access to any open file descriptor. Additionally,
+there are special file names reserved for TCP/IP networking.
+
+* Menu:
-5.7.2 Special Files for Network Communications
+* Other Inherited Files:: Accessing other open files with
+ `gawk'.
+* Special Network:: Special files for network communications.
+* Special Caveats:: Things to watch out for.
+
+
+File: gawk.info, Node: Other Inherited Files, Next: Special Network, Up: Special Files
+
+5.8.1 Accessing Other Open Files With `gawk'
+--------------------------------------------
+
+Besides the `/dev/stdin', `/dev/stdout', and `/dev/stderr' special file
+names mentioned earlier, `gawk' provides syntax for accessing any other
+inherited open file:
+
+`/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
+essentially aliases for `/dev/fd/0', `/dev/fd/1', and `/dev/fd/2',
+respectively. However, those names are more self-explanatory.
+
+ Note that using `close()' on a file name of the form `"/dev/fd/N"',
+for file descriptor numbers above two, does actually close the given
+file descriptor.
+
+
+File: gawk.info, Node: Special Network, Next: Special Caveats, Prev: Other Inherited Files, Up: Special Files
+
+5.8.2 Special Files for Network Communications
----------------------------------------------
`gawk' programs can open a two-way TCP/IP connection, acting as either
@@ -6155,25 +6999,29 @@ form:
`/NET-TYPE/PROTOCOL/LOCAL-PORT/REMOTE-HOST/REMOTE-PORT'
- The NET-TYPE is one of `inet', `inet4' or `inet6'. The PROTOCOL is
+ The NET-TYPE is one of `inet', `inet4', or `inet6'. The PROTOCOL is
one of `tcp' or `udp', 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::.
+*note TCP/IP Networking::.

File: gawk.info, Node: Special Caveats, Prev: Special Network, Up: Special Files
-5.7.3 Special File Name Caveats
+5.8.3 Special File Name Caveats
-------------------------------
-Here is a list of things to bear in mind when using the special file
-names that `gawk' provides:
+Here are some 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::).
+ * Recognition of the file names for the three standard pre-opened
+ files is disabled only in POSIX mode.
+
+ * Recognition of the other special file names is disabled if `gawk'
+ is in compatibility mode (either `--traditional' or `--posix';
+ *note Options::).
* `gawk' _always_ interprets these special file names. For example,
using `/dev/fd/4' for output actually writes on file descriptor 4,
@@ -6184,9 +7032,9 @@ names that `gawk' provides:
behavior.

-File: gawk.info, Node: Close Files And Pipes, Prev: Special Files, Up: Printing
+File: gawk.info, Node: Close Files And Pipes, Next: Output Summary, Prev: Special Files, Up: Printing
-5.8 Closing Input and Output Redirections
+5.9 Closing Input and Output Redirections
=========================================
If the same file name or the same shell command is used with `getline'
@@ -6292,14 +7140,17 @@ 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.
+ `close()' silently does nothing if given an argument that does not
+represent a file, pipe, or coprocess that was opened with a
+redirection. In such a case, it returns a negative value, indicating
+an error. In addition, `gawk' sets `ERRNO' to a string indicating the
+error.
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.
+It is, more likely, a close of a file that was never opened with a
+redirection, so `awk' silently does nothing, except return a negative
+value.
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
@@ -6308,15 +7159,14 @@ 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.
+feature, discussion is delayed until *note Two-way I/O::, which
+describes it in more detail and gives an example.
-Advanced Notes: Using `close()''s Return Value
-----------------------------------------------
+ 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.)
+ In many older versions of Unix `awk', the `close()' function is
+actually a statement. (d.c.) It is a syntax error to try and use the
+return value from `close()':
command = "..."
command | getline info
@@ -6325,8 +7175,8 @@ statement. It is a syntax error to try and use the return value from
`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.
+cases, `gawk' sets the predefined 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
@@ -6351,6 +7201,56 @@ call. See the system manual pages for information on how to decode this
value.

+File: gawk.info, Node: Output Summary, Next: Output Exercises, Prev: Close Files And Pipes, Up: Printing
+
+5.10 Summary
+============
+
+ * The `print' statement prints comma-separated expressions. Each
+ expression is separated by the value of `OFS' and terminated by
+ the value of `ORS'. `OFMT' provides the conversion format for
+ numeric values for the `print' statement.
+
+ * The `printf' statement provides finer-grained control over output,
+ with format control letters for different data types and various
+ flags that modify the behavior of the format control letters.
+
+ * Output from both `print' and `printf' may be redirected to files,
+ pipes, and coprocesses.
+
+ * `gawk' provides special file names for access to standard input,
+ output, and error, and for network communications.
+
+ * Use `close()' to close open file, pipe, and coprocess redirections.
+ For coprocesses, it is possible to close only one direction of the
+ communications.
+
+
+
+File: gawk.info, Node: Output Exercises, Prev: Output Summary, Up: Printing
+
+5.11 Exercises
+==============
+
+ 1. Rewrite the program:
+
+ awk 'BEGIN { print "Month Crates"
+ print "----- ------" }
+ { print $1, " ", $2 }' inventory-shipped
+
+ from *note Output Separators::, by using a new value of `OFS'.
+
+ 2. Use the `printf' statement to line up the headings and table data
+ for the `inventory-shipped' example that was covered in *note
+ Print::.
+
+ 3. What happens if you forget the double quotes when redirecting
+ output, as follows:
+
+ BEGIN { print "Serious error detected!" > /dev/stderr }
+
+
+
File: gawk.info, Node: Expressions, Next: Patterns and Actions, Prev: Printing, Up: Top
6 Expressions
@@ -6376,12 +7276,13 @@ operators.
* Function Calls:: A function call is an expression.
* Precedence:: How various operators nest.
* Locales:: How the locale affects things.
+* Expressions Summary:: Expressions summary.

File: gawk.info, Node: Values, Next: All Operators, Up: Expressions
-6.1 Constants, Variables and Conversions
-========================================
+6.1 Constants, Variables, and Conversions
+=========================================
Expressions are built up from values and the operations performed upon
them. This minor node describes the elementary objects which provide
@@ -6407,7 +7308,7 @@ 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.
+forms, but are internally stored in an identical manner.
* Menu:
@@ -6431,7 +7332,7 @@ the same value:
1050e-1
A string constant consists of a sequence of characters enclosed in
-double-quotation marks. For example:
+double quotation marks. For example:
"parrot"
@@ -6444,8 +7345,9 @@ 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.
+uses double-precision floating-point numbers. On most modern systems,
+these are in IEEE 754 standard format. *Note Arbitrary Precision
+Arithmetic::, for much more information.

File: gawk.info, Node: Nondecimal-numbers, Next: Regexp Constants, Prev: Scalar Constants, Up: Constants
@@ -6453,17 +7355,17 @@ File: gawk.info, Node: Nondecimal-numbers, Next: Regexp Constants, Prev: Scal
6.1.1.2 Octal and Hexadecimal Numbers
.....................................
-In `awk', all numbers are in decimal; i.e., base 10. Many other
+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.
+1, 2, 3, 4, 5, 6, 7, 10, 11, 12, and so on. 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. Because 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
@@ -6497,11 +7399,11 @@ 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
+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:
+octal constants. For example, `gawk' treats `018' as decimal 18:
$ gawk 'BEGIN { print "021 is", 021 ; print 018 }'
-| 021 is 17
@@ -6511,10 +7413,9 @@ octal constants; e.g., `gawk' treats `018' as decimal 18:
If `gawk' is in compatibility mode (*note Options::), they are not
available.
-Advanced Notes: A Constant's Base Does Not Affect Its Value
------------------------------------------------------------
+ A Constant's Base Does Not Affect Its Value
-Once a numeric constant has been converted internally into a number,
+ 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:
@@ -6531,8 +7432,9 @@ File: gawk.info, Node: Regexp Constants, Prev: Nondecimal-numbers, Up: Consta
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).
+match computed or dynamic regexps (which are typically just ordinary
+strings or variables that contain a regexp, but could be a more complex
+expression).

File: gawk.info, Node: Using Constant Regexps, Next: Variables, Prev: Constants, Up: Values
@@ -6544,8 +7446,8 @@ 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:
+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"
@@ -6557,7 +7459,7 @@ and:
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:
+its author probably intended:
# Note that /foo/ is on the left of the ~
if (/foo/ ~ $1) print "found foo"
@@ -6579,13 +7481,14 @@ the contents of the current input record.
Constant regular expressions are also used as the first argument for
the `gensub()', `sub()', and `gsub()' functions, as the second argument
-of the `match()' function, and as the third argument of the
-`patsplit()' function (*note String Functions::). Modern
+of the `match()' function, and as the third argument of the `split()'
+and `patsplit()' functions (*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:
+not. (d.c.) Because some built-in functions accept regexp constants
+as arguments, it can be confusing when attempting to use regexp
+constants as arguments to user-defined functions (*note
+User-defined::). For example:
function mysub(pat, repl, str, global)
{
@@ -6604,12 +7507,12 @@ For example:
}
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.
+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, because
+passing a truth value in this way is probably not what was intended.

File: gawk.info, Node: Variables, Next: Conversion, Prev: Using Constant Regexps, Up: Values
@@ -6625,7 +7528,7 @@ on the `awk' command line.
* Menu:
* Using Variables:: Using variables in your programs.
-* Assignment Options:: Setting variables on the command-line and a
+* Assignment Options:: Setting variables on the command line and a
summary of command-line syntax. This is an
advanced method of input.
@@ -6638,31 +7541,34 @@ File: gawk.info, Node: Using Variables, Next: Assignment Options, Up: Variabl
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.
+it may not begin with a digit. Here, a "letter" is any one of the 52
+upper- and lowercase English letters. Other characters that may be
+defined as letters in non-English locales are not valid in variable
+names. 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::. In addition, the `sub()' and
`gsub()' functions can change a variable's value, and the `match()',
-`patsplit()' and `split()' functions can change the contents of their
+`split()', and `patsplit()' functions can change the contents of their
array parameters. *Note String Functions::.
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
+record). *Note Built-in Variables::, for a list of the predefined
+variables. These predefined variables can be used and assigned just
+like all other variables, but their values are also used or changed
+automatically by `awk'. All predefined 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 explicitly
-"initialize" a variable in `awk', which is what you would do in C and
-in most other traditional languages.
+initialize a variable in `awk', which is what you would do in C and in
+most other traditional languages.

File: gawk.info, Node: Assignment Options, Prev: Using Variables, Up: Variables
@@ -6690,16 +7596,16 @@ 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
+ awk '{ print $n }' n=4 inventory-shipped n=2 mail-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
`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':
+printed in lines from `mail-list':
- $ awk '{ print $n }' n=4 inventory-shipped n=2 BBS-list
+ $ awk '{ print $n }' n=4 inventory-shipped n=2 mail-list
-| 15
-| 24
...
@@ -6718,6 +7624,22 @@ File: gawk.info, Node: Conversion, Prev: Variables, Up: Values
6.1.4 Conversion of Strings and Numbers
---------------------------------------
+Number-to-string and string-to-number conversion are generally
+straightforward. There can be subtleties to be aware of; this minor
+node discusses this important facet of `awk'.
+
+* Menu:
+
+* Strings And Numbers:: How `awk' Converts Between Strings And
+ Numbers.
+* Locale influences conversions:: How the locale may affect conversions.
+
+
+File: gawk.info, Node: Strings And Numbers, Next: Locale influences conversions, Up: Conversion
+
+6.1.4.1 How `awk' Converts Between 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
@@ -6738,15 +7660,15 @@ string, concatenate that number with the empty string, `""'. 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
+1,000, 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
+controlled by the `awk' predefined 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
+ `CONVFMT''s default value is `"%.6g"', which creates a value with at
most six significant digits. For some applications, you might want to
change it to specify more precision. On most modern machines, 17
digits is usually enough to capture a floating-point number's value
@@ -6767,61 +7689,74 @@ value of `CONVFMT' may be. Given the following code fragment:
`b' has the value `"12"', not `"12.00"'. (d.c.)
+ Pre-POSIX `awk' Used `OFMT' for String Conversion
+
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.
-
- And, 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.
+change their behavior. *Note Print::, for more information on the
+`print' statement.
+
+ ---------- Footnotes ----------
+
+ (1) Pathological cases can require up to 752 digits (!), but we
+doubt that you need to worry about this.
+
+
+File: gawk.info, Node: Locale influences conversions, Prev: Strings And Numbers, Up: Conversion
+
+6.1.4.2 Locales Can Influence Conversion
+........................................
+
+Where you are can matter when it comes to converting between numbers and
+strings. The local character set and language--the "locale"--can
+affect numeric formats. In particular, for `awk' programs, it affects
+the decimal point character and the thousands-separator character. The
+`"C"' locale, and most English-language locales, use the period
+character (`.') as the decimal point and don't have a thousands
+separator. However, many (if not most) European and non-English
+locales use the comma (`,') as the decimal point character. European
+locales often use either a space or a period as the thousands
+separator, if they have one.
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.
-Here are some examples indicating the difference in behavior, on a
-GNU/Linux system:
+number-to-string conversion, the local decimal point character is used.
+(d.c.) In all cases, numbers in source code and in input data cannot
+have a thousands separator. Here are some examples indicating the
+difference in behavior, on a GNU/Linux system:
+ $ export POSIXLY_CORRECT=1 Force POSIX behavior
$ gawk 'BEGIN { printf "%g\n", 3.1415927 }'
-| 3.14159
- $ LC_ALL=en_DK gawk 'BEGIN { printf "%g\n", 3.1415927 }'
+ $ LC_ALL=en_DK.utf-8 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 }'
+ $ echo 4,321 | LC_ALL=en_DK.utf-8 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.
+The `en_DK.utf-8' 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 including the fractional part, 4.321.
Some earlier versions of `gawk' fully complied with this aspect of
the standard. However, many users in non-English locales complained
-about this behavior, since their data used a period as the decimal
+about this behavior, because their data used a period as the decimal
point, so the default behavior was restored to use a period as the
decimal point character. You can use the `--use-lc-numeric' option
(*note Options::) to force `gawk' to use the locale's decimal point
character. (`gawk' also uses the locale's decimal point character when
in POSIX mode, either via `--posix', or the `POSIXLY_CORRECT'
-environment variable.)
+environment variable, as shown previously.)
- *Note table-locale-affects:: describes the cases in which the
+ *note table-locale-affects:: describes the cases in which the
locale's decimal point character is used and when a period is used.
Some of these features have not been described yet.
@@ -6832,22 +7767,17 @@ Feature Default `--posix' or `--use-lc-numeric'
Input Use period Use locale
`strtonum()'Use period Use locale
-Table 6.1: Locale Decimal Point versus A Period
+Table 6.1: Locale decimal point versus a period
- Finally, modern day formal standards and IEEE standard floating point
+ Finally, modern day formal standards and IEEE standard floating-point
representation can have an unusual but important effect on the way
`gawk' converts some special string values to numbers. The details are
-presented in *Note POSIX Floating Point Problems::.
-
- ---------- Footnotes ----------
-
- (1) Pathological cases can require up to 752 digits (!), but we
-doubt that you need to worry about this.
+presented in *note POSIX Floating Point Problems::.

File: gawk.info, Node: All Operators, Next: Truth Values and Conditions, Prev: Values, Up: Expressions
-6.2 Operators: Doing Something With Values
+6.2 Operators: Doing Something with Values
==========================================
This minor node introduces the "operators" which make use of the values
@@ -6891,17 +7821,17 @@ scores:
The following list provides the arithmetic operators in `awk', in
order from the highest precedence to the lowest:
+`X ^ Y'
+`X ** Y'
+ Exponentiation; X raised to the Y power. `2 ^ 3' has the value
+ eight; the character sequence `**' is equivalent to `^'. (c.e.)
+
`- 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 `^'. (c.e.)
-
`X * Y'
Multiplication.
@@ -6909,9 +7839,9 @@ order from the highest precedence to the lowest:
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.)
+ 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
@@ -6952,29 +7882,28 @@ File: gawk.info, Node: Concatenation, Next: Assignment Ops, Prev: Arithmetic
6.2.2 String Concatenation
--------------------------
- It seemed like a good idea at the time.
- Brian Kernighan
+ 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
+ $ awk '{ print "Field number one: " $1 }' mail-list
+ -| Field number one: Amelia
+ -| Field number one: Anthony
...
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
+ $ awk '{ print "Field number one:" $1 }' mail-list
+ -| Field number one:Amelia
+ -| Field number one:Anthony
...
Because string concatenation does not have an explicit operator, it
-is often necessary to insure that it happens at the right time by using
+is often necessary to ensure that it happens at the right time by using
parentheses to enclose the items to concatenate. For example, you
might expect that the following code fragment concatenates `file' and
`name':
@@ -7000,9 +7929,9 @@ example:
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'.
+It is not defined whether the second 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:
@@ -7026,13 +7955,14 @@ Otherwise, it's parsed as follows:
=> -12 (-24)
=> -12-24
- As mentioned earlier, when doing concatenation, _parenthesize_.
-Otherwise, you're never quite sure what you'll get.
+ As mentioned earlier, when mixing concatenation with other
+operators, _parenthesize_. Otherwise, you're never quite sure what
+you'll get.
---------- Footnotes ----------
- (1) It happens that Brian Kernighan's `awk', `gawk' and `mawk' all
-"get it right," but you should not rely on this.
+ (1) It happens that BWK `awk', `gawk' and `mawk' all "get it right,"
+but you should not rely on this.

File: gawk.info, Node: Assignment Ops, Next: Increment Ops, Prev: Concatenation, Up: All Operators
@@ -7075,9 +8005,9 @@ 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:
+A variable's type is simply the type of whatever value was last assigned
+to it. In the following program fragment, the variable `foo' has a
+numeric value at first, and a string value later on:
foo = 1
print foo
@@ -7148,43 +8078,43 @@ righthand expression. For example:
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
+*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:
+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.
+ *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.
+LVALUE `+=' INCREMENT Add INCREMENT to the value of LVALUE
+LVALUE `-=' DECREMENT Subtract DECREMENT from the value of LVALUE
+LVALUE `*=' Multiply 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 `/=' DIVISOR Divide the value of LVALUE by DIVISOR
+LVALUE `%=' MODULUS Set LVALUE to its remainder by MODULUS
LVALUE `^=' POWER
-LVALUE `**=' POWER Raises LVALUE to the power POWER. (c.e.)
+LVALUE `**=' POWER Raise LVALUE to the power POWER (c.e.)
-Table 6.2: Arithmetic Assignment Operators
+Table 6.2: 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
---------------------------------------------------------------------------
+ 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:
+ There is a syntactic ambiguity between the `/=' assignment operator
+and regexp constants whose first character is an `='. (d.c.) This is
+most notable in some commercial `awk' versions. For example:
$ awk /==/ /dev/null
error--> awk: syntax error at source line 1
@@ -7196,8 +8126,7 @@ A workaround is:
awk '/[=]=/' /dev/null
- `gawk' does not have this problem, nor do the other freely available
-versions described in *Note Other Versions::.
+ `gawk' does not have this problem; BWK `awk' and `mawk' also do not.

File: gawk.info, Node: Increment Ops, Prev: Assignment Ops, Up: All Operators
@@ -7212,20 +8141,20 @@ 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
+"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
+`++' 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
+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).
@@ -7257,12 +8186,10 @@ is a summary of increment and decrement expressions:
of the expression. (This expression is like `LVALUE++', but
instead of adding, it subtracts.)
-Advanced Notes: Operator Evaluation Order
------------------------------------------
+ Operator Evaluation Order
Doctor, doctor! It hurts when I do this!
- So don't do that!
- Groucho Marx
+ So don't do that! -- Groucho Marx
What happens for something like the following?
@@ -7291,8 +8218,8 @@ File: gawk.info, Node: Truth Values and Conditions, Next: Function Calls, Pre
6.3 Truth Values and Conditions
===============================
-In certain contexts, expression values also serve as "truth values;"
-i.e., they determine what should happen next as the program runs. This
+In certain contexts, expression values also serve as "truth values";
+(i.e., they determine what should happen next as the program runs). This
minor node describes how `awk' defines "true" and "false" and how
values are compared.
@@ -7343,8 +8270,8 @@ File: gawk.info, Node: Typing and Comparison, Next: Boolean Ops, Prev: Truth
6.3.2 Variable Typing and Comparison Expressions
------------------------------------------------
- The Guide is definitive. Reality is frequently inaccurate.
- The Hitchhiker's Guide to the Galaxy
+ The Guide is definitive. Reality is frequently inaccurate. --
+ Douglas Adams, `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
@@ -7360,17 +8287,14 @@ are typed, and how `awk' compares variables.

File: gawk.info, Node: Variable Typing, Next: Comparison Operators, Up: Typing and Comparison
-6.3.2.1 String Type Versus Numeric Type
+6.3.2.1 String Type versus Numeric Type
.......................................
-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. The various versions of the POSIX
-standard did not get the rules quite right for several editions.
-Fortunately, as of at least the 2008 standard (and possibly earlier),
-the standard has been fixed, and variable typing follows these rules:(1)
+The 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. Variable typing follows these rules:
* A numeric constant or the result of a numeric operation has the
NUMERIC attribute.
@@ -7379,9 +8303,9 @@ the standard has been fixed, and variable typing follows these rules:(1)
STRING attribute.
* Fields, `getline' input, `FILENAME', `ARGV' elements, `ENVIRON'
- elements, and the elements of an array created by `patsplit()',
- `split()' and `match()' that are numeric strings have the STRNUM
- attribute. Otherwise, they have the STRING attribute.
+ elements, and the elements of an array created by `match()',
+ `split()', and `patsplit()' 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
@@ -7416,7 +8340,7 @@ operands, according to the following symmetric matrix:
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"', when it appears in program source code,
-is a string--even though it looks numeric--and is _never_ treated as
+is a string--even though it looks numeric--and is _never_ treated as a
number for comparison purposes.
In short, when one operand is a "pure" string, such as a string
@@ -7427,33 +8351,27 @@ comparison is performed.
characters, and so is first and foremost of STRING type; input strings
that look numeric are additionally given the STRNUM attribute. Thus,
the six-character input string ` +3.14' receives the STRNUM attribute.
-In contrast, the eight-character literal `" +3.14"' appearing in
-program text is a string constant. The following examples print `1'
-when the comparison between the two different constants is true, `0'
-otherwise:
+In contrast, the eight characters `" +3.14"' appearing in program text
+comprise a string constant. The following examples print `1' when the
+comparison between the two different constants is true, `0' otherwise:
- $ echo ' +3.14' | gawk '{ print $0 == " +3.14" }' True
+ $ echo ' +3.14' | awk '{ print($0 == " +3.14") }' True
-| 1
- $ echo ' +3.14' | gawk '{ print $0 == "+3.14" }' False
+ $ echo ' +3.14' | awk '{ print($0 == "+3.14") }' False
-| 0
- $ echo ' +3.14' | gawk '{ print $0 == "3.14" }' False
+ $ echo ' +3.14' | awk '{ print($0 == "3.14") }' False
-| 0
- $ echo ' +3.14' | gawk '{ print $0 == 3.14 }' True
+ $ echo ' +3.14' | awk '{ print($0 == 3.14) }' True
-| 1
- $ echo ' +3.14' | gawk '{ print $1 == " +3.14" }' False
+ $ echo ' +3.14' | awk '{ print($1 == " +3.14") }' False
-| 0
- $ echo ' +3.14' | gawk '{ print $1 == "+3.14" }' True
+ $ echo ' +3.14' | awk '{ print($1 == "+3.14") }' True
-| 1
- $ echo ' +3.14' | gawk '{ print $1 == "3.14" }' False
+ $ echo ' +3.14' | awk '{ print($1 == "3.14") }' False
-| 0
- $ echo ' +3.14' | gawk '{ print $1 == 3.14 }' True
+ $ echo ' +3.14' | awk '{ print($1 == 3.14) }' True
-| 1
- ---------- Footnotes ----------
-
- (1) `gawk' has followed these rules for many years, and it is
-gratifying that the POSIX standard is also now correct.
-

File: gawk.info, Node: Comparison Operators, Next: POSIX String Comparison, Prev: Variable Typing, Up: Typing and Comparison
@@ -7462,24 +8380,24 @@ File: gawk.info, Node: Comparison Operators, Next: POSIX String Comparison, P
"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
+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 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.
+ denoted by Y
SUBSCRIPT `in' True if the array ARRAY has an element with the
-ARRAY subscript SUBSCRIPT.
+ARRAY subscript SUBSCRIPT
-Table 6.3: Relational Operators
+Table 6.3: Relational operators
Comparison expressions have the value one if true and zero if false.
When comparing operands of mixed types, numeric operands are converted
@@ -7504,29 +8422,29 @@ 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:
+ The following list of expressions illustrates the kinds of
+comparisons `awk' performs, as well as what the result of each
+comparison is:
`1.5 <= 2.0'
- numeric comparison (true)
+ Numeric comparison (true)
`"abc" >= "xyz"'
- string comparison (false)
+ String comparison (false)
`1.5 != " +2"'
- string comparison (true)
+ String comparison (true)
`"1e2" < "3"'
- string comparison (true)
+ String comparison (true)
`a = 2; b = "2"'
`a == b'
- string comparison (true)
+ String comparison (true)
`a = 2; b = " +2"'
-
`a == b'
- string comparison (false)
+ String comparison (false)
In this example:
@@ -7553,13 +8471,13 @@ 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
+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:
+ A constant regular expression in slashes by itself is also an
+expression. `/REGEXP/' is an abbreviation for the following comparison
+expression:
$0 ~ /REGEXP/
@@ -7570,13 +8488,14 @@ Constant Regexps::, where this is discussed in more detail.

File: gawk.info, Node: POSIX String Comparison, Prev: Comparison Operators, Up: Typing and Comparison
-6.3.2.3 String Comparison With POSIX Rules
+6.3.2.3 String Comparison with POSIX Rules
..........................................
The POSIX standard says that string comparison is performed based on
-the locale's collating order. This is usually very different from the
-results obtained when doing straight character-by-character
-comparison.(1)
+the locale's "collating order". This is the order in which characters
+sort, as defined by the locale (for more discussion, *note Locales::).
+This order is usually very different from the results obtained when
+doing straight character-by-character comparison.(1)
Because this behavior differs considerably from existing practice,
`gawk' only implements it when in POSIX mode (*note Options::). Here
@@ -7620,9 +8539,9 @@ 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':
+ both `edu' and `li':
- if ($0 ~ /2400/ && $0 ~ /foo/) print
+ if ($0 ~ /edu/ && $0 ~ /li/) print
The subexpression BOOLEAN2 is evaluated only if BOOLEAN1 is true.
This can make a difference when BOOLEAN2 contains expressions that
@@ -7633,13 +8552,15 @@ Boolean operators are:
`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:
+ that contain _either_ `edu' or `li':
- if ($0 ~ /2400/ || $0 ~ /foo/) print
+ if ($0 ~ /edu/ || $0 ~ /li/) print
The subexpression BOOLEAN2 is evaluated only if BOOLEAN1 is false.
- This can make a difference when BOOLEAN2 contains expressions
- that have side effects.
+ This can make a difference when BOOLEAN2 contains expressions that
+ have side effects. (Thus, this test never really distinguishes
+ records that contain both `edu' and `li'--as soon as `edu' is
+ matched, the full test succeeds.)
`! BOOLEAN'
True if BOOLEAN is false. For example, the following program
@@ -7647,18 +8568,18 @@ Boolean operators are:
variable is not defined:
BEGIN { if (! ("HOME" in ENVIRON))
- print "no home!" }
+ print "no home!" }
- (The `in' operator is described in *Note Reference to Elements::.)
+ (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 that end with `&&' 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
@@ -7669,7 +8590,7 @@ following program is one way to print lines in between special
bracketing lines:
$1 == "START" { interested = ! interested; next }
- interested == 1 { print }
+ interested { print }
$1 == "END" { interested = ! interested; next }
The variable `interested', as with all `awk' variables, starts out
@@ -7679,7 +8600,15 @@ 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.(1)
- NOTE: The `next' statement is discussed in *Note Next Statement::.
+ Most commonly, the `!' operator is used in the conditions of `if'
+and `while' statements, where it often makes more sense to phrase the
+logic in the negative:
+
+ if (! SOME CONDITION || SOME OTHER CONDITION) {
+ ... DO WHATEVER PROCESSING ...
+ }
+
+ 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
@@ -7728,7 +8657,7 @@ not. *Note Arrays::, for more information about arrays.
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.
+is specified (*note Options::), this extension is disabled.

File: gawk.info, Node: Function Calls, Next: Precedence, Prev: Truth Values and Conditions, Up: Expressions
@@ -7745,6 +8674,8 @@ 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.
+Finally, `gawk' lets you write functions in C or C++ that may be called
+from your program (*note Dynamic Extensions::).
The way to use a function is with a "function call" expression,
which consists of the function name followed immediately by a list of
@@ -7759,7 +8690,7 @@ examples show function calls with and without 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
+ opening 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
@@ -7776,19 +8707,21 @@ the number of which to take the square root:
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::).
+treated as local variables. Such local variables act like the empty
+string if referenced where a string value is required, and like zero if
+referenced where a numeric value is required (*note User-defined::).
As an advanced feature, `gawk' provides indirect function calls,
which is a way to choose the function to call at runtime, instead of
when you write the source code to your program. We defer discussion of
-this feature until later; see *Note Indirect Calls::.
+this feature until later; see *note Indirect 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 `sqrt(ARGUMENT)' is the square root of ARGUMENT.
-The following program reads numbers, one number per line, and prints the
-square root of each one:
+ Like every other expression, the function call has a value, often
+called the "return value", which is computed by the function based on
+the arguments you give it. In this example, the return value of
+`sqrt(ARGUMENT)' is the square root of ARGUMENT. 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
@@ -7858,10 +8791,10 @@ violates the precedence rules; for example, `$$0++--' is not a valid
expression because the first `$' has higher precedence than the `++';
to avoid the problem the expression can be rewritten as `$($0++)--'.
- This table presents `awk''s operators, in order of highest to lowest
+ This list presents `awk''s operators, in order of highest to lowest
precedence:
-`(...)'
+`('...`)'
Grouping.
`$'
@@ -7882,7 +8815,7 @@ precedence:
`+ -'
Addition, subtraction.
-`String Concatenation'
+String concatenation
There is no special symbol for concatenation. The operands are
simply written side by side (*note Concatenation::).
@@ -7897,9 +8830,9 @@ precedence:
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)'.
+ precedence without parentheses. Such combinations (e.g., `print
+ foo > a ? b : c'), result in syntax errors. The correct way to
+ write this statement is `print foo > (a ? b : c)'.
`~ !~'
Matching, nonmatching.
@@ -7923,16 +8856,18 @@ precedence:
POSIX. For maximum portability, do not use them.

-File: gawk.info, Node: Locales, Prev: Precedence, Up: Expressions
+File: gawk.info, Node: Locales, Next: Expressions Summary, Prev: Precedence, Up: Expressions
-6.6 Where You Are Makes A Difference
+6.6 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.
+system about the local character set and language. The ISO C standard
+defines a default `"C"' locale, which is an environment that is typical
+of what many C programmers are used to.
- Once upon a time, the locale setting used to affect regexp matching
-(*note Ranges and Locales::), but this is no longer true.
+ Once upon a time, the locale setting used to affect regexp matching,
+but this is no longer true (*note Ranges and Locales::).
Locales can affect record splitting. For the normal case of `RS =
"\n"', the locale is largely irrelevant. For other single-character
@@ -7941,13 +8876,77 @@ much better performance when reading records. Otherwise, `gawk' has to
make several function calls, _per input character_, to find the record
terminator.
+ Locales can affect how dates and times are formatted (*note Time
+Functions::). For example, a common way to abbreviate the date
+September 4, 2015, in the United States is "9/4/15." In many countries
+in Europe, however, it is abbreviated "4.9.15." Thus, the `%x'
+specification in a `"US"' locale might produce `9/4/15', while in a
+`"EUROPE"' locale, it might produce `4.9.15'.
+
According to POSIX, string comparison is also affected by locales
-(similar to regular expressions). The details are presented in *Note
+(similar to regular expressions). The details are presented in *note
POSIX String Comparison::.
Finally, the locale affects the value of the decimal point character
used when `gawk' parses input data. This is discussed in detail in
-*Note Conversion::.
+*note Conversion::.
+
+
+File: gawk.info, Node: Expressions Summary, Prev: Locales, Up: Expressions
+
+6.7 Summary
+===========
+
+ * Expressions are the basic elements of computation in programs.
+ They are built from constants, variables, function calls, and
+ combinations of the various kinds of values with operators.
+
+ * `awk' supplies three kinds of constants: numeric, string, and
+ regexp. `gawk' lets you specify numeric constants in octal and
+ hexadecimal (bases 8 and 16) as well as decimal (base 10). In
+ certain contexts, a standalone regexp constant such as `/foo/' has
+ the same meaning as `$0 ~ /foo/'.
+
+ * Variables hold values between uses in computations. A number of
+ built-in variables provide information to your `awk' program, and
+ a number of others let you control how `awk' behaves.
+
+ * Numbers are automatically converted to strings, and strings to
+ numbers, as needed by `awk'. Numeric values are converted as if
+ they were formatted with `sprintf()' using the format in `CONVFMT'.
+ Locales can influence the conversions.
+
+ * `awk' provides the usual arithmetic operators (addition,
+ subtraction, multiplication, division, modulus), and unary plus
+ and minus. It also provides comparison operators, boolean
+ operators, array membership testing, and regexp matching
+ operators. String concatenation is accomplished by placing two
+ expressions next to each other; there is no explicit operator.
+ The three-operand `?:' operator provides an "if-else" test within
+ expressions.
+
+ * Assignment operators provide convenient shorthands for common
+ arithmetic operations.
+
+ * In `awk', a value is considered to be true if it is non-zero _or_
+ non-null. Otherwise, the value is false.
+
+ * A variable's type is set upon each assignment and may change over
+ its lifetime. The type determines how it behaves in comparisons
+ (string or numeric).
+
+ * Function calls return a value which may be used as part of a larger
+ expression. Expressions used to pass parameter values are fully
+ evaluated before the function is called. `awk' provides built-in
+ and user-defined functions; this is described in *note Functions::.
+
+ * Operator precedence specifies the order in which operations are
+ performed, unless explicitly overridden by parentheses. `awk''s
+ operator precedence is compatible with that of C.
+
+ * Locales can affect the format of data as output by an `awk'
+ program, and occasionally the format for data read as input.
+

File: gawk.info, Node: Patterns and Actions, Next: Arrays, Prev: Expressions, Up: Top
@@ -7958,7 +8957,7 @@ File: gawk.info, Node: Patterns and Actions, Next: Arrays, Prev: Expressions,
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.
+and `awk''s predefined variables.
The pattern-action rules and the statements available for use within
actions form the core of `awk' programming. In a sense, everything
@@ -7972,7 +8971,8 @@ top of. Now it's time to start building something useful.
* Action Overview:: What goes into an action.
* Statements:: Describes the various control statements in
detail.
-* Built-in Variables:: Summarizes the built-in variables.
+* Built-in Variables:: Summarizes the predefined variables.
+* Pattern Action Summary:: Patterns and Actions summary.

File: gawk.info, Node: Pattern Overview, Next: Using Shell Variables, Up: Patterns and Actions
@@ -8001,10 +9001,10 @@ summary of the types of `awk' patterns:
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
+`BEGPAT, ENDPAT'
+ 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::.)
+ BEGPAT and the final record that matches ENDPAT. (*Note Ranges::.)
`BEGIN'
`END'
@@ -8013,8 +9013,8 @@ summary of the types of `awk' patterns:
`BEGINFILE'
`ENDFILE'
- Special patterns for you to supply startup or cleanup actions to
- done on a per file basis. (*Note BEGINFILE/ENDFILE::.)
+ Special patterns for you to supply startup or cleanup actions to be
+ done on a per-file basis. (*Note BEGINFILE/ENDFILE::.)
`EMPTY'
The empty pattern matches every input record. (*Note Empty::.)
@@ -8048,73 +9048,69 @@ 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.
+*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':
+precisely `li':
- $ awk '$1 == "foo" { print $2 }' BBS-list
+ $ awk '$1 == "li" { print $2 }' mail-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':
+(There is no output, because there is no person with the exact name
+`li'.) Contrast this with the following regular expression match, which
+accepts any record with a first field that contains `li':
- $ awk '$1 ~ /foo/ { print $2 }' BBS-list
- -| 555-1234
+ $ awk '$1 ~ /li/ { print $2 }' mail-list
+ -| 555-5553
-| 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'.
+ pattern. The expression `/li/' has the value one if `li' appears in
+the current input record. Thus, as a pattern, `/li/' matches any record
+containing `li'.
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
+`mail-list' that contain both `edu' and `li':
+
+ $ awk '/edu/ && /li/' mail-list
+ -| Samuel 555-3430 samuel.lanceolis@shu.edu A
+
+ The following command prints all records in `mail-list' that contain
+_either_ `edu' or `li' (or both, of course):
+
+ $ awk '/edu/ || /li/' mail-list
+ -| Amelia 555-5553 amelia.zodiacusque@gmail.com F
+ -| Broderick 555-0542 broderick.aliquotiens@yahoo.com R
+ -| Fabius 555-1234 fabius.undevicesimus@ucb.edu F
+ -| Julie 555-6699 julie.perscrutabor@skeeve.com F
+ -| Samuel 555-3430 samuel.lanceolis@shu.edu A
+ -| Jean-Paul 555-2127 jeanpaul.campanorum@nyu.edu R
+
+ The following command prints all records in `mail-list' that do
+_not_ contain the string `li':
+
+ $ awk '! /li/' mail-list
+ -| Anthony 555-3412 anthony.asserturo@hotmail.com A
+ -| Becky 555-7685 becky.algebrarum@gmail.com A
+ -| Bill 555-1675 bill.drowning@hotmail.com A
+ -| Camilla 555-2912 camilla.infusarum@skynet.be R
+ -| Fabius 555-1234 fabius.undevicesimus@ucb.edu F
+ -| Martin 555-6480 martin.codicibus@hotmail.com A
+ -| Jean-Paul 555-2127 jeanpaul.campanorum@nyu.edu R
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', `END',
-`BEGINFILE' and `ENDFILE', which never match any input record, are not
+`BEGINFILE', and `ENDFILE', which never match any input record, are not
expressions and cannot appear inside Boolean patterns.
The precedence of the different operators which can appear in
-patterns is described in *Note Precedence::.
+patterns is described in *note Precedence::.

File: gawk.info, Node: Ranges, Next: BEGIN/END, Prev: Expression Patterns, Up: Pattern Overview
@@ -8137,7 +9133,7 @@ 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
+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.
@@ -8181,6 +9177,10 @@ worked around; range patterns do not combine with other patterns:
error--> gawk: cmd. line:1: (/1/,/2/) || /Yes/
error--> gawk: cmd. line:1: ^ syntax error
+ As a minor point of interest, although it is poor style, POSIX
+allows you to put a newline after the comma in a range pattern.
+(d.c.)
+

File: gawk.info, Node: BEGIN/END, Next: BEGINFILE/ENDFILE, Prev: Ranges, Up: Pattern Overview
@@ -8192,8 +9192,7 @@ All the patterns described so far are for matching input records. The
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.
+referred to as "`BEGIN' and `END' blocks" by longtime `awk' programmers.
* Menu:
@@ -8211,19 +9210,19 @@ 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.
+ > BEGIN { print "Analysis of \"li\"" }
+ > /li/ { ++n }
+ > END { print "\"li\" appears in", n, "records." }' mail-list
+ -| Analysis of "li"
+ -| "li" appears in 4 records.
+
+ This program finds the number of records in the input file
+`mail-list' that contain the string `li'. 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, as `awk' does this automatically
+(*note Variables::). The second rule increments the variable `n' every
+time a record containing the pattern `li' 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).
@@ -8265,10 +9264,10 @@ File: gawk.info, Node: I/O And BEGIN/END, Prev: Using BEGIN/END, Up: BEGIN/EN
7.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
+There are several (sometimes subtle) points to be aware of 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
@@ -8281,27 +9280,27 @@ 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 Brian Kernighan's `awk', and possibly other
-implementations, do not.
+although logically one would think that it should be. In fact, all of
+BWK `awk', `mawk', and `gawk' preserve the value of `$0' for use in
+`END' rules. Be aware, however, that some other implementations and
+many older versions of Unix `awk' 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 record. 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.
+`$0' is the null string, then this prints an empty record. Many
+longtime `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,
+because 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::.)
+Similarly, those statements are not valid in an `END' rule, because all
+the input has been read. (*Note Next Statement::, and *note Nextfile
+Statement::,.)

File: gawk.info, Node: BEGINFILE/ENDFILE, Next: Empty, Prev: BEGIN/END, Up: Pattern Overview
@@ -8321,8 +9320,8 @@ program are merged, in the order they are read by `gawk', and all
reads the first record from a file. `FILENAME' is set to the name of
the current file, and `FNR' is set to zero.
- The `BEGINFILE' rule provides you the opportunity for two tasks that
-would otherwise be difficult or impossible to perform:
+ The `BEGINFILE' rule provides you the opportunity to accomplish two
+tasks that would otherwise be difficult or impossible to perform:
* You can test if the file is readable. Normally, it is a fatal
error if a file named on the command line cannot be opened for
@@ -8336,10 +9335,10 @@ would otherwise be difficult or impossible to perform:
entirely. Otherwise, `gawk' exits with the usual fatal error.
* If you have written extensions that modify the record handling (by
- inserting an "open hook"), you can invoke them at this point,
- before `gawk' has started processing the file. (This is a _very_
- advanced feature, currently used only by the XMLgawk project
- (http://xmlgawk.sourceforge.net).)
+ inserting an "input parser," *note Input Parsers::), you can invoke
+ them at this point, before `gawk' has started processing the file.
+ (This is a _very_ advanced feature, currently used only by the
+ `gawkextlib' project (http://gawkextlib.sourceforge.net).)
The `ENDFILE' rule is called when `gawk' has finished processing the
last record in an input file. For the last input file, it will be
@@ -8353,12 +9352,12 @@ makes it possible to catch and process I/O errors at the level of the
`awk' program.
The `next' statement (*note Next Statement::) is not allowed inside
-either a `BEGINFILE' or and `ENDFILE' rule. The `nextfile' statement
-(*note Nextfile Statement::) is allowed only inside a `BEGINFILE' rule,
-but not inside an `ENDFILE' rule.
+either a `BEGINFILE' or an `ENDFILE' rule. The `nextfile' statement is
+allowed only inside a `BEGINFILE' rule, but not inside an `ENDFILE'
+rule.
The `getline' statement (*note Getline::) is restricted inside both
-`BEGINFILE' and `ENDFILE'. Only the `getline VARIABLE < FILE' form is
+`BEGINFILE' and `ENDFILE': only redirected forms of `getline' are
allowed.
`BEGINFILE' and `ENDFILE' are `gawk' extensions. In most other
@@ -8374,7 +9373,7 @@ File: gawk.info, Node: Empty, Prev: BEGINFILE/ENDFILE, Up: Pattern Overview
An empty (i.e., nonexistent) pattern is considered to match _every_
input record. For example, the program:
- awk '{ print $1 }' BBS-list
+ awk '{ print $1 }' mail-list
prints the first field of every record.
@@ -8390,19 +9389,19 @@ 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:
+ A common method is to use shell quoting to substitute the variable's
+value into the program inside the script. For example, consider the
+following program:
printf "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' shell
-variable inside the quotes. The second part is single-quoted.
+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' shell 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
@@ -8411,7 +9410,7 @@ 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
+variable. Then use dynamic regexps to match the pattern (*note
Computed Regexps::). The following shows how to redo the previous
example using this technique:
@@ -8424,10 +9423,10 @@ 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.
+Using a variable also provides more flexibility, as 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.

File: gawk.info, Node: Action Overview, Next: Statements, Prev: Using Shell Variables, Up: Patterns and Actions
@@ -8442,19 +9441,19 @@ 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 }]
+ [PATTERN] `{ ACTION }'
+ PATTERN [`{ ACTION }']
...
- function NAME(ARGS) { ... }
+ `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 }':
+braces (`{...}'). Each statement specifies one thing to do. The
+statements are separated by newlines or semicolons. The 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 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
@@ -8473,13 +9472,13 @@ Control statements
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.
+ Enclose one or more statements in 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
+ `awk' are the `next' statement (*note Next Statement::) and the
`nextfile' statement (*note Nextfile Statement::).
Output statements
@@ -8504,7 +9503,7 @@ 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.
+with braces, separating them with newlines or semicolons.
* Menu:
@@ -8533,7 +9532,7 @@ File: gawk.info, Node: If Statement, Next: While Statement, Up: Statements
The `if'-`else' statement is `awk''s decision-making statement. It
looks like this:
- if (CONDITION) THEN-BODY [else ELSE-BODY]
+ `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;
@@ -8547,13 +9546,13 @@ following:
else
print "x is odd"
- In this example, if the expression `x % 2 == 0' is true (that is, if
+ In this example, if the expression `x % 2 == 0' is true (i.e., 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:
+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"
@@ -8583,18 +9582,18 @@ 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++
- }
+executes again. This process repeats until the CONDITION is no longer
+true. If the CONDITION is initially false, the body of the loop never
+executes 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,
@@ -8606,7 +9605,7 @@ 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
+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.
@@ -8625,27 +9624,27 @@ the CONDITION is true. It looks like this:
BODY
while (CONDITION)
- Even if the CONDITION is false at the start, the BODY is executed at
+ Even if the CONDITION is false at the start, the BODY executes at
least once (and only once, unless executing BODY makes CONDITION true).
Contrast this with the corresponding `while' statement:
while (CONDITION)
- BODY
+ 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)
+ 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
+very realistic example, because 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.

@@ -8669,9 +9668,10 @@ 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
+ awk '
+ {
+ for (i = 1; i <= 3; i++)
+ print $i
}' inventory-shipped
This prints the first three fields of each input record, with one field
@@ -8695,7 +9695,7 @@ 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
+ 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,
@@ -8723,7 +9723,7 @@ 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
+ There is an alternative version of the `for' loop, for iterating over
all the indices of an array:
for (i in array)
@@ -8738,9 +9738,12 @@ File: gawk.info, Node: Switch Statement, Next: Break Statement, Prev: For Sta
7.4.5 The `switch' Statement
----------------------------
-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
+This minor node describes a `gawk'-specific feature. If `gawk' is in
+compatibility mode (*note Options::), it is not available.
+
+ 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
@@ -8763,32 +9766,36 @@ match to a given case is made, the case statement bodies execute 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
+ while ((c = getopt(ARGC, ARGV, "aksx")) != -1) {
+ switch (c) {
+ case "a":
+ # report size of all files
+ all_files = TRUE;
+ break
+ case "k":
+ BLOCK_SIZE = 1024 # 1K block size
+ break
+ case "s":
+ # do sums only
+ sum_only = TRUE
+ break
+ case "x":
+ # don't cross filesystems
+ fts_flags = or(fts_flags, FTS_XDEV)
+ break
+ case "?":
+ default:
+ usage()
+ break
+ }
}
- 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.
-
- This `switch' statement is a `gawk' extension. If `gawk' is in
-compatibility mode (*note Options::), it is not available.
+ Note that if none of the statements specified here halt execution of
+a matched `case' statement, execution falls through to the next `case'
+until execution halts. In this example, the `case' for `"?"' falls
+through to the `default' case, which is to call a function named
+`usage()'. (The `getopt()' function being called here is described in
+*note Getopt Function::.)

File: gawk.info, Node: Break Statement, Next: Continue Statement, Prev: Switch Statement, Up: Statements
@@ -8802,15 +9809,15 @@ 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
+ 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'
@@ -8825,28 +9832,28 @@ Statement::.)
# 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
+ 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 is also used to break out of the `switch'
-statement. This is discussed in *Note Switch Statement::.
+statement. This is discussed in *note Switch Statement::.
The `break' statement has no meaning when used outside the body of a
loop or `switch'. 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::). (d.c.) Recent versions of Brian Kernighan's `awk' no
-longer allow this usage, nor does `gawk'.
+Statement::). (d.c.) Recent versions of BWK `awk' no longer allow
+this usage, nor does `gawk'.

File: gawk.info, Node: Continue Statement, Next: Next Statement, Prev: Break Statement, Up: Statements
@@ -8889,14 +9896,15 @@ the previous example with the following `while' loop:
print ""
}
-This program loops forever once `x' reaches 5.
+This program loops forever once `x' reaches 5, because the increment
+(`x++') is never reached.
The `continue' statement has no special meaning with respect to the
-`switch' statement, nor does it any 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::).
-(d.c.) Recent versions of Brian Kernighan's `awk' no longer work this
+`switch' statement, nor does it have any 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::). (d.c.) Recent versions of BWK `awk' no longer work this
way, nor does `gawk'.

@@ -8928,15 +9936,14 @@ 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
+ printf("%s:%d: skipped: NF != 4\n", FILENAME, FNR) > "/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::.
+error output stream, as error messages should be. For more detail, see
+*note Special Files::.
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::.
@@ -8946,62 +9953,65 @@ rules. *Note BEGINFILE/ENDFILE::.
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.
+as a syntax error. Although POSIX does not disallow it, most 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.

File: gawk.info, Node: Nextfile Statement, Next: Exit Statement, Prev: Next Statement, Up: Statements
-7.4.9 Using `gawk''s `nextfile' Statement
------------------------------------------
+7.4.9 The `nextfile' Statement
+------------------------------
-`gawk' provides the `nextfile' statement, which is similar to the
-`next' statement. (c.e.) 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, any `ENDFILE' rules are
-executed except in the case as mentioned below, `FILENAME' is updated
-to the name of the next data file listed on the command line, `FNR' is
-reset to one, `ARGIND' is incremented, any `BEGINFILE' rules are
-executed, 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. An exception to this is
-when the `nextfile' is invoked during execution of any statement in an
-`END' rule; In this case, it causes the program to stop immediately.
+The `nextfile' statement is similar to the `next' statement. However,
+instead of abandoning processing of the current record, the `nextfile'
+statement instructs `awk' to stop processing the current data file.
+
+ 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, and processing starts over with the first rule in the
+program. If the `nextfile' statement causes the end of the input to be
+reached, then the code in any `END' rules is executed. An exception to
+this is when `nextfile' is invoked during execution of any statement in
+an `END' rule; in this case, it causes the program to stop immediately.
*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.
+Without `nextfile', in order to move on to the next data file, a program
+would have to continue scanning the unwanted records. The `nextfile'
+statement accomplishes this much more efficiently.
+
+ In `gawk', execution of `nextfile' causes additional things to
+happen: any `ENDFILE' rules are executed if `gawk' is not currently in
+an `END' or `BEGINFILE' rule, `ARGIND' is incremented, and any
+`BEGINFILE' rules are executed. (`ARGIND' hasn't been introduced yet.
+*Note Built-in Variables::.)
- In addition, `nextfile' is useful inside a `BEGINFILE' rule to skip
+ With `gawk', `nextfile' is useful inside a `BEGINFILE' rule to skip
over a file that would otherwise cause `gawk' to exit with a fatal
error. In this case, `ENDFILE' rules are not executed. *Note
BEGINFILE/ENDFILE::.
- While one might think that `close(FILENAME)' would accomplish the
+ Although it might seem 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'.
- The current version of the Brian Kernighan's `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.
+ NOTE: For many years, `nextfile' was a common extension. In
+ September 2012, it was accepted for inclusion into the POSIX
+ standard. See the Austin Group website
+ (http://austingroupbugs.net/view.php?id=607).
+
+ The current version of BWK `awk', and `mawk' also support
+`nextfile'. However, they don'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.

File: gawk.info, Node: Exit Statement, Prev: Nextfile Statement, Up: Statements
@@ -9013,7 +10023,7 @@ 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]
+ `exit' [RETURN CODE]
When an `exit' statement is executed from a `BEGIN' rule, the
program stops processing everything immediately. No input records are
@@ -9025,8 +10035,8 @@ 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. Any `ENDFILE' rules are also skipped; they
-are not executed.
+`END' rule if there is one. `gawk' also skips any `ENDFILE' rules;
+they do not execute.
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
@@ -9047,12 +10057,12 @@ 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")
+ if (("date" | getline date_now) <= 0) {
+ print "Can't get system date" > "/dev/stderr"
+ exit 1
+ }
+ print "current date is", date_now
+ close("date")
}
NOTE: For full portability, exit values should be between zero and
@@ -9061,10 +10071,10 @@ statement with a nonzero argument, as shown in the following example:
systems.

-File: gawk.info, Node: Built-in Variables, Prev: Statements, Up: Patterns and Actions
+File: gawk.info, Node: Built-in Variables, Next: Pattern Action Summary, Prev: Statements, Up: Patterns and Actions
-7.5 Built-in Variables
-======================
+7.5 Predefined 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
@@ -9074,9 +10084,9 @@ 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.
+ This minor node documents all of `gawk''s predefined variables, most
+of which are also documented in the major nodes describing their areas
+of activity.
* Menu:
@@ -9089,12 +10099,17 @@ activity.

File: gawk.info, Node: User-modified, Next: Auto-set, Up: Built-in Variables
-7.5.1 Built-in Variables That Control `awk'
+7.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 (`#').
+to control how `awk' does certain things.
+
+ The variables that are specific to `gawk' are marked with a pound
+sign (`#'). These variables are `gawk' extensions. In other `awk'
+implementations or if `gawk' is in compatibility mode (*note
+Options::), they are not special. (Any exceptions are noted in the
+description of each variable.)
`BINMODE #'
On non-POSIX systems, this variable specifies use of binary mode
@@ -9107,14 +10122,11 @@ specific to `gawk' are marked with a pound sign (`#').
string value of `"rw"' or `"wr"' indicates that all files should
use binary I/O. Any other string value is treated the same as
`"rw"', but causes `gawk' to generate a warning message.
- `BINMODE' is described in more detail in *Note PC Using::.
+ `BINMODE' is described in more detail in *note PC Using::. `mawk'
+ (*note Other Versions::), also supports this variable, but only
+ using numeric values.
- 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'
+``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::).
@@ -9122,29 +10134,21 @@ specific to `gawk' are marked with a pound sign (`#').
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
+ 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' and `FPAT' 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'.
-
`FPAT #'
- This is a regular expression (as a string) that tells `gawk' to
- create the fields based on text that matches the regular
- expression. Assigning a value to `FPAT' overrides the use of `FS'
- and `FIELDWIDTHS' for field splitting. *Note Splitting By
- Content::, for more information.
-
- If `gawk' is in compatibility mode (*note Options::), then `FPAT'
- has no special meaning, and field-splitting operations occur based
- exclusively on the value of `FS'.
+ A regular expression (as a string) that tells `gawk' to create the
+ fields based on text that matches the regular expression.
+ Assigning a value to `FPAT' overrides the use of `FS' and
+ `FIELDWIDTHS' for field splitting. *Note Splitting By Content::,
+ for more information.
`FS'
- This is the input field separator (*note Field Separators::). The
- value is a single-character string or a multi-character regular
+ The input field separator (*note Field Separators::). The value
+ is a single-character string or a multicharacter 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
@@ -9180,13 +10184,9 @@ specific to `gawk' are marked with a pound sign (`#').
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
+ 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
@@ -9202,13 +10202,12 @@ specific to `gawk' are marked with a pound sign (`#').
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'.
+ 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' 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::).
@@ -9216,40 +10215,45 @@ specific to `gawk' are marked with a pound sign (`#').
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
+ 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::.)
+`PREC #'
+ The working precision of arbitrary-precision floating-point
+ numbers, 53 bits by default (*note Setting precision::).
+
+`ROUNDMODE #'
+ The rounding mode to use for arbitrary-precision arithmetic on
+ numbers, by default `"N"' (`roundTiesToEven' in the IEEE 754
+ standard; *note Setting the rounding mode::).
+
+``RS''
+ The 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::).
+``SUBSEP''
+ 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 Multidimensional::).
`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.
+ 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"'.
---------- Footnotes ----------
@@ -9258,15 +10262,19 @@ specific to `gawk' are marked with a pound sign (`#').

File: gawk.info, Node: Auto-set, Next: ARGC and ARGV, Prev: User-modified, Up: Built-in Variables
-7.5.2 Built-in Variables That Convey Information
+7.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 (`#').
+your program.
+
+ The variables that are specific to `gawk' are marked with a pound
+sign (`#'). These variables are `gawk' extensions. In other `awk'
+implementations or if `gawk' is in compatibility mode (*note
+Options::), they are not special:
-`ARGC, ARGV'
+`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'
@@ -9276,13 +10284,13 @@ with a pound sign (`#').
$ awk 'BEGIN {
> for (i = 0; i < ARGC; i++)
> print ARGV[i]
- > }' inventory-shipped BBS-list
+ > }' inventory-shipped mail-list
-| awk
-| inventory-shipped
- -| BBS-list
+ -| mail-list
`ARGV[0]' contains `awk', `ARGV[1]' contains `inventory-shipped',
- and `ARGV[2]' contains `BBS-list'. The value of `ARGC' is three,
+ and `ARGV[2]' contains `mail-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.
@@ -9308,28 +10316,40 @@ with a pound sign (`#').
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.
+ program, `gawk' automatically sets it to a new value when it opens
+ the next file.
`ENVIRON'
An associative array containing 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.
+ example, `ENVIRON["HOME"]' might be `/home/arnold'.
+
+ For POSIX `awk', changing this array does not affect the
+ environment passed on to any programs that `awk' may spawn via
+ redirection or the `system()' function.
+
+ However, beginning with version 4.2, if not in POSIX compatibility
+ mode, `gawk' does update its own environment when `ENVIRON' is
+ changed, thus changing the environment seen by programs that it
+ creates. You should therefore be especially careful if you modify
+ `ENVIRON["PATH"]"', which is the search path for finding
+ executable programs.
+
+ This can also affect the running `gawk' program, since some of the
+ built-in functions may pay attention to certain environment
+ variables. The most notable instance of this is `mktime()' (*note
+ Time Functions::), which pays attention the value of the `TZ'
+ environment variable on many systems.
Some operating systems may not have environment variables. On
such systems, the `ENVIRON' array is empty (except for
- `ENVIRON["AWKPATH"]', *note AWKPATH Variable::).
+ `ENVIRON["AWKPATH"]' and `ENVIRON["AWKLIBPATH"]'; *note AWKPATH
+ Variable::, and *note AWKLIBPATH Variable::).
`ERRNO #'
- If a system error occurs during a redirection for `getline',
- during a read for `getline', or during a `close()' operation, then
+ 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.
In addition, `gawk' clears `ERRNO' before opening each
@@ -9343,24 +10363,20 @@ with a pound sign (`#').
`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.
+ The name of the current input file. When no data files are listed
+ on the command line, `awk' reads from the standard input and
+ `FILENAME' is set to `"-"'. `FILENAME' changes each time a new
+ file is read (*note Reading Files::). Inside a `BEGIN' rule, the
+ value of `FILENAME' is `""', because 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 Records::). It
- is reinitialized to zero each time a new input file is started.
+ The current record number in the current file. `awk' increments
+ `FNR' each time it reads a new record (*note Records::). `awk'
+ resets `FNR' to zero each time it starts a new input file.
`NF'
The number of fields in the current input record. `NF' is set
@@ -9373,10 +10389,19 @@ with a pound sign (`#').
create or remove fields from the current record. *Note Changing
Fields::.
+`FUNCTAB #'
+ An array whose indices and corresponding values are the names of
+ all the built-in, user-defined, and extension functions in the
+ program.
+
+ NOTE: Attempting to use the `delete' statement with the
+ `FUNCTAB' array causes a fatal error. Any attempt to assign
+ to an element of `FUNCTAB' also causes a fatal error.
+
`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.
+ beginning of the program's execution (*note Records::). `awk'
+ increments `NR' each time it reads a new record.
`PROCINFO #'
The elements of this array provide access to information about the
@@ -9395,6 +10420,38 @@ with a pound sign (`#').
effect, or `"FPAT"' if field matching with `FPAT' is in
effect.
+ `PROCINFO["identifiers"]'
+ A subarray, indexed by the names of all identifiers used in
+ the text of the AWK program. An "identifier" is simply the
+ name of a variable (be it scalar or array), built-in
+ function, user-defined function, or extension function. For
+ each identifier, the value of the element is one of the
+ following:
+
+ `"array"'
+ The identifier is an array.
+
+ `"builtin"'
+ The identifier is a built-in function.
+
+ `"extension"'
+ The identifier is an extension function loaded via
+ `@load' or `-l'.
+
+ `"scalar"'
+ The identifier is a scalar.
+
+ `"untyped"'
+ The identifier is untyped (could be used as a scalar or
+ array, `gawk' doesn't know yet).
+
+ `"user"'
+ The identifier is a user-defined function.
+
+ The values indicate what `gawk' knows about the identifiers
+ after it has finished parsing the program; they are _not_
+ updated while the program runs.
+
`PROCINFO["gid"]'
The value of the `getgid()' system call.
@@ -9409,9 +10466,9 @@ with a pound sign (`#').
`PROCINFO["sorted_in"]'
If this element exists in `PROCINFO', its value controls the
- order in which array indices will be processed by `for (index
- in array) ...' loops. Since this is an advanced feature, we
- defer the full description until later; see *Note Scanning an
+ order in which array indices will be processed by `for (INDX
+ in ARRAY)' loops. This is an advanced feature, so we defer
+ the full description until later; see *note Scanning an
Array::.
`PROCINFO["strftime"]'
@@ -9425,18 +10482,48 @@ with a pound sign (`#').
`PROCINFO["version"]'
The version of `gawk'.
+ The following additional elements in the array are available to
+ provide information about the MPFR and GMP libraries if your
+ version of `gawk' supports arbitrary-precision arithmetic (*note
+ Arbitrary Precision Arithmetic::):
+
+ `PROCINFO["mpfr_version"]'
+ The version of the GNU MPFR library.
+
+ `PROCINFO["gmp_version"]'
+ The version of the GNU MP library.
+
+ `PROCINFO["prec_max"]'
+ The maximum precision supported by MPFR.
+
+ `PROCINFO["prec_min"]'
+ The minimum precision required by MPFR.
+
+ The following additional elements in the array are available to
+ provide information about the version of the extension API, if
+ your version of `gawk' supports dynamic loading of extension
+ functions (*note Dynamic Extensions::):
+
+ `PROCINFO["api_major"]'
+ The major version of the extension API.
+
+ `PROCINFO["api_minor"]'
+ The minor version of the extension API.
+
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::).
- The `PROCINFO' array is also used to cause coprocesses to
- communicate over pseudo-ttys instead of through two-way pipes;
- this is discussed further in *Note Two-way I/O::.
+ The `PROCINFO' array has the following additional uses:
+
+ * It may be used to provide a timeout when reading from any
+ open input file, pipe, or coprocess. *Note Read Timeout::,
+ for more information.
- This array is a `gawk' extension. In other `awk' implementations,
- or if `gawk' is in compatibility mode (*note Options::), it is not
- special.
+ * It may be used to cause coprocesses to communicate over
+ pseudo-ttys instead of through two-way pipes; this is
+ discussed further in *note Two-way I/O::.
`RLENGTH'
The length of the substring matched by the `match()' function
@@ -9452,21 +10539,59 @@ with a pound sign (`#').
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.
+ The input text that matched the text denoted by `RS', the record
+ separator. It is set every time a record is read.
- This variable is a `gawk' extension. In other `awk'
- implementations, or if `gawk' is in compatibility mode (*note
- Options::), it is not special.
+`SYMTAB #'
+ An array whose indices are the names of all defined global
+ variables and arrays in the program. `SYMTAB' makes `gawk''s
+ symbol table visible to the `awk' programmer. It is built as
+ `gawk' parses the program and is complete before the program
+ starts to run.
-Advanced Notes: Changing `NR' and `FNR'
----------------------------------------
+ The array may be used for indirect access to read or write the
+ value of a variable:
-`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.) The following example shows
-this:
+ foo = 5
+ SYMTAB["foo"] = 4
+ print foo # prints 4
+
+ The `isarray()' function (*note Type Functions::) may be used to
+ test if an element in `SYMTAB' is an array. Also, you may not use
+ the `delete' statement with the `SYMTAB' array.
+
+ You may use an index for `SYMTAB' that is not a predefined
+ identifier:
+
+ SYMTAB["xxx"] = 5
+ print SYMTAB["xxx"]
+
+ This works as expected: in this case `SYMTAB' acts just like a
+ regular array. The only difference is that you can't then delete
+ `SYMTAB["xxx"]'.
+
+ The `SYMTAB' array is more interesting than it looks. Andrew Schorr
+ points out that it effectively gives `awk' data pointers. Consider
+ his example:
+
+ # Indirect multiply of any variable by amount, return result
+
+ function multiply(variable, amount)
+ {
+ return SYMTAB[variable] *= amount
+ }
+
+ NOTE: In order to avoid severe time-travel paradoxes,(2)
+ neither `FUNCTAB' nor `SYMTAB' are available as elements
+ within the `SYMTAB' array.
+
+ 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.) The following example
+shows this:
$ echo '1
> 2
@@ -9488,25 +10613,27 @@ file by resetting `NR' to zero when `FILENAME' changed.
to `"-"', even if there were data files to be processed. This behavior
was incorrect and should not be relied upon in your programs.
+ (2) Not to mention difficult implementation issues.
+

File: gawk.info, Node: ARGC and ARGV, Prev: Auto-set, Up: Built-in Variables
7.5.3 Using `ARGC' and `ARGV'
-----------------------------
-*Note Auto-set::, presented the following program describing the
+*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
+ > }' inventory-shipped mail-list
-| awk
-| inventory-shipped
- -| BBS-list
+ -| mail-list
In this example, `ARGV[0]' contains `awk', `ARGV[1]' contains
-`inventory-shipped', and `ARGV[2]' contains `BBS-list'. Notice that
+`inventory-shipped', and `ARGV[2]' contains `mail-list'. Notice that
the `awk' program is not entered in `ARGV'. The other command-line
options, with their arguments, are also not entered. This includes
variable assignments done with the `-v' option (*note Options::).
@@ -9549,10 +10676,18 @@ 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:
+actual processing of the input begins. *Note Split Program::, and
+*note Tee Program::, for examples of each way of removing elements from
+`ARGV'.
+
+ To actually get options into an `awk' program, end the `awk' options
+with `--' and then supply the `awk' program's options, in the following
+manner:
+
+ awk -f myprog.awk -- -v -q file1 file2 ...
+
+ The following fragment processes `ARGV' in order to examine, and
+then remove, the previously mentioned command-line options:
BEGIN {
for (i = 1; i < ARGC; i++) {
@@ -9570,24 +10705,79 @@ and then remove, command-line options:
}
}
- 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:
+ Ending the `awk' options with `--' isn't 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 command line with `gawk' would
+be:
- awk -f myprog -- -v -q 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 -q -v file1 file2 ...
+ gawk -f myprog.awk -q -v file1 file2 ...
Because `-q' is not a valid `gawk' option, it and the following `-v'
are passed on to the `awk' program. (*Note Getopt Function::, for an
`awk' library function that parses command-line options.)
+ When designing your program, you should choose options that don't
+conflict with `gawk''s, because it will process any options that it
+accepts before passing the rest of the command line on to your program.
+Using `#!' with the `-E' option may help (*Note Executable Scripts::,
+and *note Options::,).
+
+
+File: gawk.info, Node: Pattern Action Summary, Prev: Built-in Variables, Up: Patterns and Actions
+
+7.6 Summary
+===========
+
+ * Pattern-action pairs make up the basic elements of an `awk'
+ program. Patterns are either normal expressions, range
+ expressions, regexp constants, one of the special keywords
+ `BEGIN', `END', `BEGINFILE', `ENDFILE', or empty. The action
+ executes if the current record matches the pattern. Empty
+ (missing) patterns match all records.
+
+ * I/O from `BEGIN' and `END' rules have certain constraints. This
+ is also true, only more so, for `BEGINFILE' and `ENDFILE' rules.
+ The latter two give you "hooks" into `gawk''s file processing,
+ allowing you to recover from a file that otherwise would cause a
+ fatal error (such as a file that cannot be opened).
+
+ * Shell variables can be used in `awk' programs by careful use of
+ shell quoting. It is easier to pass a shell variable into `awk'
+ by using the `-v' option and an `awk' variable.
+
+ * Actions consist of statements enclosed in curly braces. Statements
+ are built up from expressions, control statements, compound
+ statements, input and output statements, and deletion statements.
+
+ * The control statements in `awk' are `if'-`else', `while', `for',
+ and `do'-`while'. `gawk' adds the `switch' statement. There are
+ two flavors of `for' statement: one for performing general
+ looping, and the other for iterating through an array.
+
+ * `break' and `continue' let you exit early or start the next
+ iteration of a loop (or get out of a `switch').
+
+ * `next' and `nextfile' let you read the next record and start over
+ at the top of your program, or skip to the next input file and
+ start over, respectively.
+
+ * The `exit' statement terminates your program. When executed from
+ an action (or function body) it transfers control to the `END'
+ statements. From an `END' statement body, it exits immediately.
+ You may pass an optional numeric value to be used as `awk''s exit
+ status.
+
+ * Some predefined variables provide control over `awk', mainly for
+ I/O. Other variables convey information from `awk' to your
+ program.
+
+ * `ARGC' and `ARGV' make the command-line arguments available to
+ your program. Manipulating them from a `BEGIN' rule lets you
+ control how `awk' will process the provided data files.
+
+

File: gawk.info, Node: Arrays, Next: Functions, Prev: Patterns and Actions, Up: Top
@@ -9604,27 +10794,23 @@ 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 moves on to discuss `gawk''s facility
for sorting arrays, and ends with a brief description of `gawk''s
-ability to support true multidimensional arrays.
-
- `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.
+ability to support true arrays of arrays.
* Menu:
* Array Basics:: The basics of arrays.
-* 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
+* Delete:: The `delete' statement removes an element
+ from an array.
+* Multidimensional:: Emulating multidimensional arrays in
`awk'.
* Arrays of Arrays:: True multidimensional arrays.
+* Arrays Summary:: Summary of arrays.

-File: gawk.info, Node: Array Basics, Next: Delete, Up: Arrays
+File: gawk.info, Node: Array Basics, Next: Numeric Array Subscripts, Up: Arrays
8.1 The Basics of Arrays
========================
@@ -9641,6 +10827,8 @@ one at a time, and traversing all of the elements in an array.
* Scanning an Array:: A variation of the `for' statement. It
loops through the indices of an array's
existing elements.
+* Controlling Scanning:: Controlling the order in which arrays are
+ scanned.

File: gawk.info, Node: Array Intro, Next: Reference to Elements, Up: Array Basics
@@ -9649,8 +10837,7 @@ File: gawk.info, Node: Array Intro, Next: Reference to Elements, Up: Array Ba
----------------------------
Doing linear scans over an associative array is like trying to
- club someone to death with a loaded Uzi.
- Larry Wall
+ club someone to death with a loaded Uzi. -- Larry Wall
The `awk' language provides one-dimensional arrays for storing
groups of related strings or numbers. Every `awk' array must have a
@@ -9662,8 +10849,8 @@ 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.
+Additionally, any number or string, 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
@@ -9681,19 +10868,20 @@ declared.)
A contiguous array of four elements might look like the following
example, conceptually, if the element values are 8, `"foo"', `""', and
-30:
+30 as shown in *note figure-array-elements:::
- +---------+---------+--------+---------+
- | 8 | "foo" | "" | 30 | Value
- +---------+---------+--------+---------+
- 0 1 2 3 Index
++---------+---------+--------+---------+
+| 8 | "foo" | "" | 30 | @r{Value}
++---------+---------+--------+---------+
+ 0 1 2 3 @r{Index}
+Figure 8.1: A contiguous array
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
+that each array is a collection of pairs--an index and its corresponding
array element value:
Index 3 Value 30
@@ -9701,7 +10889,8 @@ array element value:
Index 0 Value 8
Index 2 Value ""
-The pairs are shown in jumbled order because their order is irrelevant.
+The pairs are shown in jumbled order because their order is
+irrelevant.(1)
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
@@ -9729,10 +10918,11 @@ from English to French:
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.
+numbers and strings as indices. (In fact, array subscripts are always
+strings. There are some subtleties to how numbers work when used as
+array subscripts; this is discussed in more detail in *note Numeric
+Array Subscripts::.) Here, the number `1' isn't double quoted, because
+`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
@@ -9743,6 +10933,11 @@ 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.
+ ---------- Footnotes ----------
+
+ (1) The ordering will vary among `awk' implementations, which
+typically use hash tables to store array elements and values.
+

File: gawk.info, Node: Reference to Elements, Next: Assigning Elements, Prev: Array Intro, Up: Array Basics
@@ -9777,18 +10972,20 @@ been assigned any value as well as elements that have been deleted
# Check if "foo" exists in a: Incorrect!
if (a["foo"] != "") ...
- This is incorrect, since this will _create_ `a["foo"]' if it
- didn't exist before!
+ This is incorrect for two reasons. First, it _creates_ `a["foo"]'
+ if it didn't exist before! Second, it is valid (if a bit unusual)
+ to set an array element equal to the empty string.
To determine whether an element exists in an array at a certain
index, use the following expression:
- IND in ARRAY
+ INDX in ARRAY
-This expression tests whether the particular index IND exists, without
+This expression tests whether the particular index INDX exists, without
the side effect of creating that element if it is not present. The
-expression has the value one (true) if `ARRAY[IND]' exists and zero
-(false) if it does not exist. For example, this statement tests
+expression has the value one (true) if `ARRAY[INDX]' exists and zero
+(false) if it does not exist. (We use INDX here, because `index' is
+the name of a built-in function.) For example, this statement tests
whether the array `frequencies' contains the index `2':
if (2 in frequencies)
@@ -9832,14 +11029,14 @@ encountering repeated numbers, gaps, or lines that don't begin with a
number:
{
- if ($1 > max)
- max = $1
- arr[$1] = $0
+ if ($1 > max)
+ max = $1
+ arr[$1] = $0
}
END {
- for (x = 1; x <= max; x++)
- print arr[x]
+ for (x = 1; x <= max; x++)
+ print arr[x]
}
The first rule keeps track of the largest line number seen so far;
@@ -9867,13 +11064,13 @@ 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]
+ for (x = 1; x <= max; x++)
+ if (x in arr)
+ print arr[x]
}

-File: gawk.info, Node: Scanning an Array, Prev: Array Example, Up: Array Basics
+File: gawk.info, Node: Scanning an Array, Next: Controlling Scanning, Prev: Array Example, Up: Array Basics
8.1.5 Scanning All Elements of an Array
---------------------------------------
@@ -9887,7 +11084,7 @@ lowest index up to the highest. This technique won't do the job in
has a special kind of `for' statement for scanning an array:
for (VAR in ARRAY)
- BODY
+ 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.
@@ -9922,105 +11119,202 @@ built-in function `length()'.
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 normally 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'
+elements within `awk' and in standard `awk' 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.
- As an extension, `gawk' makes it possible for you to loop over the
-elements of an array in order, based on the value of
-`PROCINFO["sorted_in"]' (*note Auto-set::). This is an advanced
-feature, so discussion of it is delayed until *Note Controlling Array
-Traversal::.
+ As a point of information, `gawk' sets up the list of elements to be
+iterated over before the loop starts, and does not change it. But not
+all `awk' versions do so. Consider this program, named `loopcheck.awk':
- In addition, `gawk' provides built-in functions for sorting arrays;
-see *Note Array Sorting Functions::.
+ BEGIN {
+ a["here"] = "here"
+ a["is"] = "is"
+ a["a"] = "a"
+ a["loop"] = "loop"
+ for (i in a) {
+ j++
+ a[j] = j
+ print i
+ }
+ }
+
+ Here is what happens when run with `gawk' (and `mawk'):
+
+ $ gawk -f loopcheck.awk
+ -| here
+ -| loop
+ -| a
+ -| is
+
+ Contrast this to BWK `awk':
+
+ $ nawk -f loopcheck.awk
+ -| loop
+ -| here
+ -| is
+ -| a
+ -| 1

-File: gawk.info, Node: Delete, Next: Numeric Array Subscripts, Prev: Array Basics, Up: Arrays
+File: gawk.info, Node: Controlling Scanning, Prev: Scanning an Array, Up: Array Basics
-8.2 The `delete' Statement
-==========================
+8.1.6 Using Predefined Array Scanning Orders with `gawk'
+--------------------------------------------------------
-To remove an individual element of an array, use the `delete' statement:
+This node describes a feature that is specific to `gawk'.
- delete ARRAY[INDEX-EXPRESSION]
+ By default, when a `for' loop traverses an array, the order is
+undefined, meaning that the `awk' implementation determines the order
+in which the array is traversed. This order is usually based on the
+internal implementation of arrays and will vary from one version of
+`awk' to the next.
- 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 been given a value. The following is an example of
-deleting elements in an array:
+ Often, though, you may wish to do something simple, such as
+"traverse the array by comparing the indices in ascending order," or
+"traverse the array by comparing the values in descending order."
+`gawk' provides two mechanisms which give you this control.
- for (i in frequencies)
- delete frequencies[i]
+ * Set `PROCINFO["sorted_in"]' to one of a set of predefined values.
+ We describe this now.
-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):
+ * Set `PROCINFO["sorted_in"]' to the name of a user-defined function
+ to use for comparison of array elements. This advanced feature is
+ described later in *note Array Sorting::.
- delete foo[4]
- if (4 in foo)
- print "This will never be printed"
+ The following special values for `PROCINFO["sorted_in"]' are
+available:
- It is important to note that deleting an element is _not_ the same
-as assigning it a null value (the empty string, `""'). For example:
+`"@unsorted"'
+ Array elements are processed in arbitrary order, which is the
+ default `awk' behavior.
- foo[4] = ""
- if (4 in foo)
- print "This is printed, even though foo[4] is empty"
+`"@ind_str_asc"'
+ Order by indices in ascending order compared as strings; this is
+ the most basic sort. (Internally, array indices are always
+ strings, so with `a[2*5] = 1' the index is `"10"' rather than
+ numeric 10.)
- It is not an error to delete an element that does not exist.
-However, 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.
+`"@ind_num_asc"'
+ Order by indices in ascending order but force them to be treated
+ as numbers in the process. Any index with a non-numeric value
+ will end up positioned as if it were zero.
- All the elements of an array may be deleted with a single statement
-(c.e.) by leaving off the subscript in the `delete' statement, as
-follows:
+`"@val_type_asc"'
+ Order by element values in ascending order (rather than by
+ indices). Ordering is by the type assigned to the element (*note
+ Typing and Comparison::). All numeric values come before all
+ string values, which in turn come before all subarrays.
+ (Subarrays have not been described yet; *note Arrays of Arrays::.)
- delete ARRAY
+`"@val_str_asc"'
+ Order by element values in ascending order (rather than by
+ indices). Scalar values are compared as strings. Subarrays, if
+ present, come out last.
- This ability is a `gawk' extension; it is not available in
-compatibility mode (*note Options::).
+`"@val_num_asc"'
+ Order by element values in ascending order (rather than by
+ indices). Scalar values are compared as numbers. Subarrays, if
+ present, come out last. When numeric values are equal, the string
+ values are used to provide an ordering: this guarantees consistent
+ results across different versions of the C `qsort()' function,(1)
+ which `gawk' uses internally to perform the sorting.
- 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.
+`"@ind_str_desc"'
+ String indices ordered from high to low.
- The following statement provides a portable but nonobvious way to
-clear out an array:(1)
+`"@ind_num_desc"'
+ Numeric indices ordered from high to low.
- split("", array)
+`"@val_type_desc"'
+ Element values, based on type, ordered from high to low.
+ Subarrays, if present, come out first.
- 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.
+`"@val_str_desc"'
+ Element values, treated as strings, ordered from high to low.
+ Subarrays, if present, come out first.
+
+`"@val_num_desc"'
+ Element values, treated as numbers, ordered from high to low.
+ Subarrays, if present, come out first.
- 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:
+ The array traversal order is determined before the `for' loop starts
+to run. Changing `PROCINFO["sorted_in"]' in the loop body does not
+affect the loop. For example:
- a[1] = 3
- delete a
- a = 3
+ $ gawk '
+ > BEGIN {
+ > a[4] = 4
+ > a[3] = 3
+ > for (i in a)
+ > print i, a[i]
+ > }'
+ -| 4 4
+ -| 3 3
+ $ gawk '
+ > BEGIN {
+ > PROCINFO["sorted_in"] = "@ind_str_asc"
+ > a[4] = 4
+ > a[3] = 3
+ > for (i in a)
+ > print i, a[i]
+ > }'
+ -| 3 3
+ -| 4 4
+
+ When sorting an array by element values, if a value happens to be a
+subarray then it is considered to be greater than any string or numeric
+value, regardless of what the subarray itself contains, and all
+subarrays are treated as being equal to each other. Their order
+relative to each other is determined by their index strings.
+
+ Here are some additional things to bear in mind about sorted array
+traversal:
+
+ * The value of `PROCINFO["sorted_in"]' is global. That is, it affects
+ all array traversal `for' loops. If you need to change it within
+ your own code, you should see if it's defined and save and restore
+ the value:
+
+ ...
+ if ("sorted_in" in PROCINFO) {
+ save_sorted = PROCINFO["sorted_in"]
+ PROCINFO["sorted_in"] = "@val_str_desc" # or whatever
+ }
+ ...
+ if (save_sorted)
+ PROCINFO["sorted_in"] = save_sorted
+
+ * As already mentioned, the default array traversal order is
+ represented by `"@unsorted"'. You can also get the default
+ behavior by assigning the null string to `PROCINFO["sorted_in"]'
+ or by just deleting the `"sorted_in"' element from the `PROCINFO'
+ array with the `delete' statement. (The `delete' statement hasn't
+ been described yet; *note Delete::.)
+
+ In addition, `gawk' provides built-in functions for sorting arrays;
+see *note Array Sorting Functions::.
---------- Footnotes ----------
- (1) Thanks to Michael Brennan for pointing this out.
+ (1) When two elements compare as equal, the C `qsort()' function
+does not guarantee that they will maintain their original relative
+order after sorting. Using the string value to provide a unique
+ordering when the numeric values are equal ensures that `gawk' behaves
+consistently across different environments.

-File: gawk.info, Node: Numeric Array Subscripts, Next: Uninitialized Subscripts, Prev: Delete, Up: Arrays
+File: gawk.info, Node: Numeric Array Subscripts, Next: Uninitialized Subscripts, Prev: Array Basics, Up: Arrays
-8.3 Using Numbers to Subscript Arrays
+8.2 Using Numbers to Subscript Arrays
=====================================
An important aspect to remember about arrays 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
+(*note Conversion::). This means that the value of the predefined
variable `CONVFMT' can affect how your program accesses elements of an
array. For example:
@@ -10039,13 +11333,13 @@ string value `"12.153"' (using the default conversion value of
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 different
-from `"12.153"'.
+two significant digits. This test fails, because `"12.15"' is
+different 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:
+values always convert 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]
@@ -10058,14 +11352,14 @@ 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 since they can sometimes have a subtle
+as you would expect them to. But it is useful to have a precise
+knowledge of the actual rules, as they can sometimes have a subtle
effect on your programs.

-File: gawk.info, Node: Uninitialized Subscripts, Next: Multi-dimensional, Prev: Numeric Array Subscripts, Up: Arrays
+File: gawk.info, Node: Uninitialized Subscripts, Next: Delete, Prev: Numeric Array Subscripts, Up: Arrays
-8.4 Using Uninitialized Variables as Subscripts
+8.3 Using Uninitialized Variables as Subscripts
===============================================
Suppose it's necessary to write a program to print the input data in
@@ -10076,13 +11370,13 @@ might look like this:
> line 2
> line 3' | awk '{ l[lines] = $0; ++lines }
> END {
- > for (i = lines-1; i >= 0; --i)
+ > 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
+ Unfortunately, the very first line of input data did not appear in
the output!
Upon first glance, we would think that this program should have
@@ -10097,7 +11391,7 @@ following version of the program works correctly:
{ l[lines++] = $0 }
END {
- for (i = lines - 1; i >= 0; --i)
+ for (i = lines - 1; i >= 0; i--)
print l[i]
}
@@ -10111,19 +11405,98 @@ string as a subscript if `--lint' is provided on the command line
(*note Options::).

-File: gawk.info, Node: Multi-dimensional, Next: Arrays of Arrays, Prev: Uninitialized Subscripts, Up: Arrays
+File: gawk.info, Node: Delete, Next: Multidimensional, Prev: Uninitialized Subscripts, Up: Arrays
+
+8.4 The `delete' Statement
+==========================
+
+To remove an individual element of an array, use the `delete' statement:
+
+ delete ARRAY[INDEX-EXPRESSION]
+
+ 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 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.
+However, 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
+
+ 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.
+
+ This form of the `delete' statement is also supported by BWK `awk'
+and `mawk', as well as by a number of other implementations.
+
+ NOTE: For many years, using `delete' without a subscript was a
+ common extension. In September 2012, it was accepted for
+ inclusion into the POSIX standard. See the Austin Group website
+ (http://austingroupbugs.net/view.php?id=544).
+
+ 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 all the elements from an array does not change
+ its type; you cannot clear 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.
+
+
+File: gawk.info, Node: Multidimensional, Next: Arrays of Arrays, Prev: Delete, Up: Arrays
8.5 Multidimensional Arrays
===========================
* Menu:
-* Multi-scanning:: Scanning multidimensional arrays.
+* Multiscanning:: Scanning multidimensional arrays.
- A multidimensional array is an array in which an element is
+ 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
+(in many 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
@@ -10155,13 +11528,14 @@ 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
+single-dimensional arrays. Write the whole sequence of indices in
parentheses, separated by commas, as the left operand:
- (SUBSCRIPT1, SUBSCRIPT2, ...) in ARRAY
+ if ((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
+ Here is an example that 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:
{
@@ -10197,13 +11571,13 @@ the program produces the following output:
3 2 1 6

-File: gawk.info, Node: Multi-scanning, Up: Multi-dimensional
+File: gawk.info, Node: Multiscanning, Up: Multidimensional
8.5.1 Scanning Multidimensional Arrays
--------------------------------------
There is no special `for' statement for scanning a "multidimensional"
-array. There cannot be one, because, in truth, there are no
+array. There cannot be one, because, in truth, `awk' does not have
multidimensional arrays or elements--there is only a multidimensional
_way of accessing_ an array.
@@ -10223,7 +11597,7 @@ 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
+ 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
@@ -10237,13 +11611,14 @@ The result is to set `separate[1]' to `"1"' and `separate[2]' to
recovered.

-File: gawk.info, Node: Arrays of Arrays, Prev: Multi-dimensional, Up: Arrays
+File: gawk.info, Node: Arrays of Arrays, Next: Arrays Summary, Prev: Multidimensional, Up: Arrays
8.6 Arrays of Arrays
====================
-`gawk' supports arrays of arrays. Elements of a subarray are referred
-to by their own indices enclosed in square brackets, just like the
+`gawk' goes beyond standard `awk''s multidimensional array access and
+provides true arrays of arrays. Elements of a subarray are referred to
+by their own indices enclosed in square brackets, just like the
elements of the main array. For example, the following creates a
two-element subarray at index `1' of the main array `a':
@@ -10254,20 +11629,21 @@ two-element subarray at index `1' of the main array `a':
can contain another subarray as a value, which in turn can hold other
arrays as well. In this way, you can create arrays of three or more
dimensions. The indices can be any `awk' expression, including scalars
-separated by commas (that is, a regular `awk' simulated
-multidimensional subscript). So the following is valid in `gawk':
+separated by commas (i.e., a regular `awk' simulated multidimensional
+subscript). So the following is valid in `gawk':
a[1][3][1, "name"] = "barney"
Each subarray and the main array can be of different length. In
fact, the elements of an array or its subarray do not all have to have
the same type. This means that the main array and any of its subarrays
-can be non-rectangular, or jagged in structure. One can assign a scalar
-value to the index `4' of the main array `a':
+can be non-rectangular, or jagged in structure. You can assign a scalar
+value to the index `4' of the main array `a', even though `a[1]' is
+itself an array and not a scalar:
a[4] = "An element in a jagged array"
- The terms "dimension", "row" and "column" are meaningless when
+ The terms "dimension", "row", and "column" are meaningless when
applied to such an array, but we will use "dimension" henceforth to
imply the maximum number of indices needed to refer to an existing
element. The type of any element that has already been assigned cannot
@@ -10324,6 +11700,8 @@ an array element is itself an array:
print array[i][j]
}
}
+ else
+ print array[i]
}
If the structure of a jagged array of arrays is known in advance,
@@ -10340,8 +11718,8 @@ the following code prints the elements of our main array `a':
}
}
-*Note Walking Arrays::, for a user-defined function that will "walk" an
-arbitrarily-dimensioned array of arrays.
+*Note Walking Arrays::, for a user-defined function that "walks" an
+arbitrarily dimensioned array of arrays.
Recall that a reference to an uninitialized array element yields a
value of `""', the null string. This has one important implication when
@@ -10358,7 +11736,55 @@ by creating an arbitrary index:
-| a

-File: gawk.info, Node: Functions, Next: Internationalization, Prev: Arrays, Up: Top
+File: gawk.info, Node: Arrays Summary, Prev: Arrays of Arrays, Up: Arrays
+
+8.7 Summary
+===========
+
+ * Standard `awk' provides one-dimensional associative arrays (arrays
+ indexed by string values). All arrays are associative; numeric
+ indices are converted automatically to strings.
+
+ * Array elements are referenced as `ARRAY[INDX]'. Referencing an
+ element creates it if it did not exist previously.
+
+ * The proper way to see if an array has an element with a given index
+ is to use the `in' operator: `INDX in ARRAY'.
+
+ * Use `for (INDX in ARRAY) ...' to scan through all the individual
+ elements of an array. In the body of the loop, INDX takes on the
+ value of each element's index in turn.
+
+ * The order in which a `for (INDX in ARRAY)' loop traverses an array
+ is undefined in POSIX `awk' and varies among implementations.
+ `gawk' lets you control the order by assigning special predefined
+ values to `PROCINFO["sorted_in"]'.
+
+ * Use `delete ARRAY[INDX]' to delete an individual element. To
+ delete all of the elements in an array, use `delete ARRAY'. This
+ latter feature has been a common extension for many years and is
+ now standard, but may not be supported by all commercial versions
+ of `awk'.
+
+ * Standard `awk' simulates multidimensional arrays by separating
+ subscript values with a comma. The values are concatenated into a
+ single string, separated by the value of `SUBSEP'. The fact that
+ such a subscript was created in this way is not retained; thus
+ changing `SUBSEP' may have unexpected consequences. You can use
+ `(SUB1, SUB2, ...) in ARRAY' to see if such a multidimensional
+ subscript exists in ARRAY.
+
+ * `gawk' provides true arrays of arrays. You use a separate set of
+ square brackets for each dimension in such an array:
+ `data[row][col]', for example. Array elements may thus be either
+ scalar values (number or string) or another array.
+
+ * Use the `isarray()' built-in function to determine if an array
+ element is itself a subarray.
+
+
+
+File: gawk.info, Node: Functions, Next: Library Functions, Prev: Arrays, Up: Top
9 Functions
***********
@@ -10366,7 +11792,8 @@ File: gawk.info, Node: Functions, Next: Internationalization, Prev: Arrays,
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, sort arrays, and internationalize and localize programs.
+manipulation, sort arrays, provide type information, 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
@@ -10377,11 +11804,12 @@ major node describes these "user-defined" functions.
* Built-in:: Summarizes the built-in functions.
* User-defined:: Describes User-defined functions in detail.
* Indirect Calls:: Choosing the function to call at runtime.
+* Functions Summary:: Summary of functions.

File: gawk.info, Node: Built-in, Next: User-defined, Up: Functions
-9.1 Built-in Functions
+9.1 Built-In Functions
======================
"Built-in" functions are always available for your `awk' program to
@@ -10406,7 +11834,7 @@ for your convenience.

File: gawk.info, Node: Calling Built-in, Next: Numeric Functions, Up: Built-in
-9.1.1 Calling Built-in Functions
+9.1.1 Calling Built-In Functions
--------------------------------
To call one of `awk''s built-in functions, write the name of the
@@ -10414,7 +11842,7 @@ 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, but nonetheless it is good practice to avoid using
+opening parenthesis, but nonetheless 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.
@@ -10440,7 +11868,7 @@ 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)
+ 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
@@ -10458,11 +11886,27 @@ with numbers. Optional parameters are enclosed in square
brackets ([ ]):
`atan2(Y, X)'
- Return the arctangent of `Y / X' in radians.
+ Return the arctangent of `Y / X' in radians. You can use `pi =
+ atan2(0, -1)' to retrieve the value of pi.
`cos(X)'
Return the cosine of X, with X in radians.
+`div(NUMERATOR, DENOMINATOR, RESULT)'
+ Perform integer division, similar to the standard C function of the
+ same name. First, truncate `numerator' and `denominator' towards
+ zero, creating integer values. Clear the `result' array, and then
+ set `result["quotient"]' to the result of `numerator /
+ denominator', truncated towards zero to an integer, and set
+ `result["remainder"]' to the result of `numerator % denominator',
+ truncated towards zero to an integer. This function is primarily
+ intended for use with arbitrary length integers; it avoids
+ creating MPFR arbitrary precision floating-point values (*note
+ Arbitrary Precision Integers::).
+
+ This function is a `gawk' extension. It is not available in
+ compatibility mode (*note Options::).
+
`exp(X)'
Return the exponential of X (`e ^ X') or report an error if X is
out of range. The range of values X can have depends on your
@@ -10470,14 +11914,13 @@ brackets ([ ]):
`int(X)'
Return 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.
+ 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.
`log(X)'
Return the natural logarithm of X, if X is positive; otherwise,
- report an error.
+ return `NaN' ("not a number") on IEEE 754 systems. Additionally,
+ `gawk' prints a warning message when `x' is negative.
`rand()'
Return a random number. The values of `rand()' are uniformly
@@ -10488,8 +11931,9 @@ brackets ([ ]):
user-defined function that can be used to obtain a random
non-negative integer less than N:
- function randint(n) {
- return int(n * rand())
+ function randint(n)
+ {
+ return int(n * rand())
}
The multiplication produces a random number greater than zero and
@@ -10506,8 +11950,7 @@ brackets ([ ]):
# Roll 3 six-sided dice and
# print total number of points.
{
- printf("%d points\n",
- roll(6)+roll(6)+roll(6))
+ printf("%d points\n", roll(6) + roll(6) + roll(6))
}
CAUTION: In most `awk' implementations, including `gawk',
@@ -10527,7 +11970,7 @@ brackets ([ ]):
Return the positive square root of X. `gawk' prints a warning
message if X is negative. Thus, `sqrt(4)' is 2.
-`srand([X])'
+`srand('[X]`)'
Set the starting point, or seed, for generating random numbers to
the value X.
@@ -10548,6 +11991,9 @@ brackets ([ ]):
easy to keep track of the seeds in case you need to consistently
reproduce sequences of random numbers.
+ POSIX does not specify the initial seed; it differs among `awk'
+ implementations.
+
---------- Footnotes ----------
(1) The C version of `rand()' on many Unix systems is known to
@@ -10560,7 +12006,7 @@ numbers.
(2) `mawk' uses a different seed each time.
(3) Computer-generated random numbers really are not truly random.
-They are technically known as "pseudorandom." This means that while
+They are technically known as "pseudorandom." This means that although
the numbers in a sequence appear to be random, you can in fact generate
the same sequence of random numbers over and over again.
@@ -10571,20 +12017,32 @@ File: gawk.info, Node: String Functions, Next: I/O Functions, Prev: Numeric F
-----------------------------------
The functions in this minor node look at or change the text of one or
-more strings. `gawk' understands locales (*note Locales::), and does
-all string processing in terms of _characters_, not _bytes_. This
-distinction is particularly important to understand for locales where
-one character may be represented by multiple bytes. Thus, for example,
-`length()' returns the number of characters in a string, and not the
-number of bytes used to represent those characters, Similarly,
-`index()' works with character indices, and not byte indices.
+more strings.
+
+ `gawk' understands locales (*note Locales::), and does all string
+processing in terms of _characters_, not _bytes_. This distinction is
+particularly important to understand for locales where one character
+may be represented by multiple bytes. Thus, for example, `length()'
+returns the number of characters in a string, and not the number of
+bytes used to represent those characters. Similarly, `index()' works
+with character indices, and not byte indices.
+
+ CAUTION: A number of functions deal with indices into strings.
+ For these functions, the first character of a string is at
+ position (index) one. This is different from C and the languages
+ descended from it, where the first character is at position zero.
+ You need to remember this when doing index calculations,
+ particularly if you are used to C.
In the following list, optional parameters are enclosed in square
brackets ([ ]). Several functions perform string substitution; the
full discussion is provided in the description of the `sub()' function,
-which comes towards the end since the list is presented in alphabetic
-order. Those functions that are specific to `gawk' are marked with a
-pound sign (`#'):
+which comes toward the end, because the list is presented
+alphabetically.
+
+ Those functions that are specific to `gawk' are marked with a pound
+sign (`#'). They are not available in compatibility mode (*note
+Options::):
* Menu:
@@ -10592,27 +12050,29 @@ pound sign (`#'):
`&' with `sub()', `gsub()', and
`gensub()'.
-`asort(SOURCE [, DEST [, HOW ] ]) #'
- Return the number of elements in the array SOURCE. `gawk' sorts
- the contents of SOURCE and replaces the indices of the sorted
- values of SOURCE 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. The optional third argument HOW is a string which
- controls the rule for comparing values, and the sort direction. A
- single space is required between the comparison mode, `string' or
- `number', and the direction specification, `ascending' or
- `descending'. You can omit direction and/or mode in which case it
- will default to `ascending' and `string', respectively. An empty
- string "" is the same as the default `"ascending string"' for the
- value of HOW. If the `source' array contains subarrays as values,
- they will come out last(first) in the `dest' array for
- `ascending'(`descending') order specification. The value of
- `IGNORECASE' affects the sorting. The third argument can also be
- a user-defined function name in which case the value returned by
- the function is used to order the array elements before
- constructing the result array. *Note Array Sorting Functions::,
- for more information.
+`asort('SOURCE [`,' DEST [`,' HOW ] ]`) #'
+`asorti('SOURCE [`,' DEST [`,' HOW ] ]`) #'
+ These two functions are similar in behavior, so they are described
+ together.
+
+ NOTE: The following description ignores the third argument,
+ HOW, as it requires understanding features that we have not
+ discussed yet. Thus, the discussion here is a deliberate
+ simplification. (We do provide all the details later on; see
+ *note Array Sorting Functions::, for the full story.)
+
+ Both functions return the number of elements in the array SOURCE.
+ For `asort()', `gawk' sorts the values of SOURCE and replaces the
+ indices of the sorted values of SOURCE 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.
+
+ When comparing strings, `IGNORECASE' affects the sorting (*note
+ Array Sorting Functions::). If the SOURCE array contains
+ subarrays as values (*note Arrays of Arrays::), they will come
+ last, after all scalar values. Subarrays are _not_ recursively
+ sorted.
For example, if the contents of `a' are as follows:
@@ -10630,26 +12090,16 @@ pound sign (`#'):
a[2] = "de"
a[3] = "sac"
- In order to reverse the direction of the sorted results in the
- above example, `asort()' can be called with three arguments as
- follows:
-
- asort(a, a, "descending")
-
- The `asort()' function is described in more detail in *Note Array
- Sorting Functions::. `asort()' is a `gawk' extension; it is not
- available in compatibility mode (*note Options::).
+ The `asorti()' function works similarly to `asort()', however, the
+ _indices_ are sorted, instead of the values. Thus, in the previous
+ example, starting with the same initial set of indices and values
+ in `a', calling `asorti(a)' would yield:
-`asorti(SOURCE [, DEST [, HOW ] ]) #'
- Return the number of elements in the array SOURCE. It works
- similarly to `asort()', however, the _indices_ are sorted, instead
- of the values. (Here too, `IGNORECASE' affects the sorting.)
+ a[1] = "first"
+ a[2] = "last"
+ a[3] = "middle"
- The `asorti()' function is described in more detail in *Note Array
- Sorting Functions::. `asorti()' is a `gawk' extension; it is not
- available in compatibility mode (*note Options::).
-
-`gensub(REGEXP, REPLACEMENT, HOW [, TARGET]) #'
+`gensub(REGEXP, REPLACEMENT, HOW' [`, TARGET']`) #'
Search the target string TARGET for matches of the regular
expression REGEXP. If HOW is a string beginning with `g' or `G'
(short for "global"), then replace all matches of REGEXP with
@@ -10658,7 +12108,7 @@ pound sign (`#'):
`$0'. It returns the modified string as the result of the
function and the original target string is _not_ changed.
- `gensub()' is a general substitution function. It's purpose is to
+ `gensub()' is a general substitution function. Its purpose is to
provide more features than the standard `sub()' and `gsub()'
functions.
@@ -10699,10 +12149,7 @@ pound sign (`#'):
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::).
-
-`gsub(REGEXP, REPLACEMENT [, TARGET])'
+`gsub(REGEXP, REPLACEMENT' [`, TARGET']`)'
Search TARGET for _all_ of the longest, leftmost, _nonoverlapping_
matching substrings it can find and replace them with REPLACEMENT.
The `g' in `gsub()' stands for "global," which means replace
@@ -10726,10 +12173,14 @@ pound sign (`#'):
$ awk 'BEGIN { print index("peanut", "an") }'
-| 3
- If FIND is not found, `index()' returns zero. (Remember that
- string indices in `awk' start at one.)
+ If FIND is not found, `index()' returns zero.
-`length([STRING])'
+ With BWK `awk' and `gawk', it is a fatal error to use a regexp
+ constant for FIND. Other implementations allow it, simply
+ treating the regexp constant as an expression meaning `$0 ~
+ /regexp/'. (d.c.).
+
+`length('[STRING]`)'
Return 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 five. By contrast,
@@ -10769,14 +12220,14 @@ pound sign (`#'):
array argument is not portable. If `--posix' is supplied, using
an array argument is a fatal error (*note Arrays::).
-`match(STRING, REGEXP [, ARRAY])'
+`match(STRING, REGEXP' [`, ARRAY']`)'
Search STRING for the longest, leftmost substring matched by the
- regular expression, REGEXP and return the character position, or
- "index", at which that substring begins (one, if it starts at the
+ regular expression, REGEXP and return the character position
+ (index) at which that substring begins (one, if it starts at the
beginning of STRING). If no match is found, return zero.
- The REGEXP argument may be either a regexp constant (`/.../') or a
- string constant (`"..."'). In the latter case, the string is
+ 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.
@@ -10787,21 +12238,20 @@ pound sign (`#'):
`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.
+ The `match()' function sets the predefined variable `RSTART' to
+ the index. It also sets the predefined 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
+ if ($1 == "FIND")
+ regex = $2
+ else {
+ where = match($0, regex)
+ if (where != 0)
+ print "Match of", regex, "found at", where, "in", $0
}
}
@@ -10848,7 +12298,7 @@ pound sign (`#'):
-| 9 7
There may not be subscripts for the start and index for every
- parenthesized subexpression, since they may not all have matched
+ parenthesized subexpression, because they may not all have matched
text; thus they should be tested for with the `in' operator (*note
Reference to Elements::).
@@ -10856,7 +12306,7 @@ pound sign (`#'):
compatibility mode (*note Options::), using a third argument is a
fatal error.
-`patsplit(STRING, ARRAY [, FIELDPAT [, SEPS ] ]) #'
+`patsplit(STRING, ARRAY' [`, FIELDPAT' [`, SEPS' ] ]`) #'
Divide STRING into pieces defined by FIELDPAT and store the pieces
in ARRAY and the separator strings in the SEPS array. The first
piece is stored in `ARRAY[1]', the second piece in `ARRAY[2]', and
@@ -10870,29 +12320,25 @@ pound sign (`#'):
The `patsplit()' function splits strings into pieces in a manner
similar to the way input lines are split into fields using `FPAT'
- (*note Splitting By Content::.
+ (*note Splitting By Content::).
Before splitting the string, `patsplit()' deletes any previously
existing elements in the arrays ARRAY and SEPS.
- The `patsplit()' function is a `gawk' extension. In compatibility
- mode (*note Options::), it is not available.
-
-`split(STRING, ARRAY [, FIELDSEP [, SEPS ] ])'
+`split(STRING, ARRAY' [`, FIELDSEP' [`, SEPS' ] ]`)'
Divide STRING into pieces separated by FIELDSEP and store the
pieces in ARRAY and the separator strings in the SEPS 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;
- *note Regexp Field Splitting::). If FIELDSEP is omitted, the
- value of `FS' is used. `split()' returns the number of elements
- created. SEPS is a `gawk' extension with `SEPS[I]' being the
- separator string between `ARRAY[I]' and `ARRAY[I+1]'. If FIELDSEP
- is a single space then any leading whitespace goes into `SEPS[0]'
- and any trailing whitespace goes into `SEPS[N]' where N is the
- return value of `split()' (that is, the number of elements in
- ARRAY).
+ `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. SEPS is a `gawk' extension with
+ `SEPS[I]' being the separator string between `ARRAY[I]' and
+ `ARRAY[I+1]'. If FIELDSEP is a single space then any leading
+ whitespace goes into `SEPS[0]' and any trailing whitespace goes
+ into `SEPS[N]' where N is the return value of `split()' (i.e., the
+ number of elements in ARRAY).
The `split()' function splits strings into pieces in a manner
similar to the way input lines are split into fields. For example:
@@ -10916,7 +12362,7 @@ pound sign (`#'):
As with input field-splitting, when the value of FIELDSEP is
`" "', leading and trailing whitespace is ignored in values
assigned to the elements of ARRAY but not in SEPS, and the elements
- are separated by runs of whitespace. Also as with input
+ 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.
(c.e.)
@@ -10943,6 +12389,9 @@ pound sign (`#'):
has one element only. The value of that element is the original
STRING.
+ In POSIX mode (*note Options::), the fourth argument is not
+ allowed.
+
`sprintf(FORMAT, EXPRESSION1, ...)'
Return (without printing) the string that `printf' would have
printed out with the same arguments (*note Printf::). For example:
@@ -10968,18 +12417,15 @@ pound sign (`#'):
Note also that `strtonum()' uses the current locale's decimal point
for recognizing numbers (*note Locales::).
- `strtonum()' is a `gawk' extension; it is not available in
- compatibility mode (*note Options::).
-
-`sub(REGEXP, REPLACEMENT [, TARGET])'
+`sub(REGEXP, REPLACEMENT' [`, TARGET']`)'
Search TARGET, which is treated as a string, for the leftmost,
longest substring matched by the regular expression REGEXP.
Modify the entire string by replacing the matched text with
REPLACEMENT. The modified string becomes the new value of TARGET.
Return the number of substitutions made (zero or one).
- The REGEXP argument may be either a regexp constant (`/.../') or a
- string constant (`"..."'). In the latter case, the string is
+ 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.
@@ -11044,7 +12490,7 @@ pound sign (`#'):
into a string, and then the value of that string is treated as the
regexp to match.
-`substr(STRING, START [, LENGTH])'
+`substr(STRING, START' [`, LENGTH' ]`)'
Return 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)'
@@ -11057,11 +12503,11 @@ pound sign (`#'):
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: Brian Kernighan's
- `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.
+ (POSIX doesn't specify what to do in this case: BWK `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
@@ -11098,6 +12544,17 @@ pound sign (`#'):
Nonalphabetic characters are left unchanged. For example,
`toupper("MiXeD cAsE 123")' returns `"MIXED CASE 123"'.
+ 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) Unless you use the `--non-decimal-data' option, which isn't
@@ -11114,26 +12571,30 @@ is number zero.

File: gawk.info, Node: Gory Details, Up: String Functions
-9.1.3.1 More About `\' and `&' with `sub()', `gsub()', and `gensub()'
+9.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.
+ CAUTION: This subsubsection has been reported to cause headaches.
+ You might want to skip it upon first reading.
+
+ 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.
+program and builds an internal copy of it to execute. 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
+sequences listed in *note Escape Sequences::. Thus, for every `\' that
`awk' processes at the runtime level, you must type two backslashes at
the lexical level. When a character that is not valid for an escape
-sequence follows the `\', Brian Kernighan's `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"'.
+sequence follows the `\', BWK `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.
@@ -11141,19 +12602,20 @@ 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::.
+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'
+ `\&' `&' The matched text
+ `\\&' `\&' A literal `&'
+ `\\\&' `\&' A literal `&'
+ `\\\\&' `\\&' A literal `\&'
+ `\\\\\&' `\\&' A literal `\&'
+ `\\\\\\&' `\\\&' A literal `\\&'
+ `\\q' `\q' A literal `\q'
-Table 9.1: Historical Escape Sequence Processing for `sub()' and `gsub()'
+Table 9.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
@@ -11164,49 +12626,25 @@ 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::.
+ Several editions of the POSIX standard attempted to fix this problem
+but weren't successful. The details are irrelevant at this point in
+time.
- You type `sub()' sees `sub()' generates
- ------- --------- --------------
- `&' `&' the matched text
- `\\&' `\&' a literal `&'
- `\\\\&' `\\&' a literal `\', then the matched text
- `\\\\\\&' `\\\&' a literal `\&'
-
-Table 9.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::.
+ At one point, 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'
+ `\\\\\\&' `\\\&' A literal `\&'
+ `\\\\&' `\\&' A literal `\', followed by the matched text
+ `\\&' `\&' A literal `&'
+ `\\q' `\q' A literal `\q'
`\\\\' `\\' `\\'
-Table 9.3: Proposed rules for sub and backslash
+Table 9.2: GNU `awk' rules for `sub()' and backslash
In a nutshell, at the runtime level, there are now three special
sequences of characters (`\\\&', `\\&' and `\&') whereas historically
@@ -11214,39 +12652,38 @@ 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.
+ `gawk' 3.0 and 3.1 follow these rules for `sub()' and `gsub()'. The
+POSIX standard took much longer to be revised than was expected. In
+addition, the `gawk' maintainer's proposal was lost during the
+standardization process. The final rules are somewhat simpler. The
+results are similar except for one case.
The 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-sub::.
+rules are presented in *note table-posix-sub::.
You type `sub()' sees `sub()' generates
------- --------- --------------
- `\\\\\\&' `\\\&' a literal `\&'
- `\\\\&' `\\&' a literal `\', followed by the matched text
- `\\&' `\&' a literal `&'
- `\\q' `\q' a literal `\q'
+ `\\\\\\&' `\\\&' A literal `\&'
+ `\\\\&' `\\&' A literal `\', followed by the matched text
+ `\\&' `\&' A literal `&'
+ `\\q' `\q' A literal `\q'
`\\\\' `\\' `\'
-Table 9.4: POSIX rules for `sub()' and `gsub()'
+Table 9.3: POSIX rules for `sub()' and `gsub()'
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' followed the POSIX rules when
`--posix' is specified (*note Options::). Otherwise, it continued to
-follow the 1996 proposed rules, since that had been its behavior for
-many years.
+follow the proposed rules, as that had been its behavior for many years.
- When version 4.0.0, was released, the `gawk' maintainer made the
+ When version 4.0.0 was released, the `gawk' maintainer made the
POSIX rules the default, breaking well over a decade's worth of
-backwards compatibility.(2) Needless to say, this was a bad idea, and
-as of version 4.0.1, `gawk' resumed its historical behavior, and only
+backward compatibility.(1) Needless to say, this was a bad idea, and as
+of version 4.0.1, `gawk' resumed its historical behavior, and only
follows the POSIX rules when `--posix' is given.
The rules for `gensub()' are considerably simpler. At the runtime
@@ -11254,40 +12691,26 @@ 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::.
+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'
+ `&' `&' The matched text
+ `\\&' `\&' A literal `&'
+ `\\\\' `\\' A literal `\'
+ `\\\\&' `\\&' A literal `\', then the matched text
+ `\\\\\\&' `\\\&' A literal `\&'
+ `\\q' `\q' A literal `q'
-Table 9.5: Escape Sequence Processing for `gensub()'
+Table 9.4: 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.
-
- (2) This was rather naive of him, despite there being a note in this
+ (1) This was rather naive of him, despite there being a note in this
section indicating that the next major version would move to the POSIX
rules.
@@ -11300,7 +12723,7 @@ File: gawk.info, Node: I/O Functions, Next: Time Functions, Prev: String Func
The following functions relate to input/output (I/O). Optional
parameters are enclosed in square brackets ([ ]):
-`close(FILENAME [, HOW])'
+`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
@@ -11315,44 +12738,87 @@ parameters are enclosed in square brackets ([ ]):
not matter. *Note Two-way I/O::, which discusses this feature in
more detail and gives an example.
-`fflush([FILENAME])'
+ Note that the second argument to `close()' is a `gawk' extension;
+ it is not available in compatibility mode (*note Options::).
+
+`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. (c.e.).
+ redirecting output to a pipe or coprocess.
- Many utility programs "buffer" their output; i.e., they save
+ Many utility programs "buffer" their output (i.e., they save
information to write to a disk file or the screen 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
+ 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()'
+ buffers (i.e., 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 Brian Kernighan's 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::).
+ Brian Kernighan added `fflush()' to his `awk' in April 1992. For
+ two decades, it was a common extension. In December 2012, it was
+ accepted for inclusion into the POSIX standard. See the Austin
+ Group website (http://austingroupbugs.net/view.php?id=634).
+
+ POSIX standardizes `fflush()' as follows: if there is no argument,
+ or if the argument is the null string (`""'), then `awk' flushes
+ the buffers for _all_ open output files and pipes.
+
+ NOTE: Prior to version 4.0.2, `gawk' would flush only the
+ standard output if there was no argument, and flush all
+ output files and pipes if the argument was the null string.
+ This was changed in order to be compatible with Brian
+ Kernighan's `awk', in the hope that standardizing this
+ feature in POSIX would then be easier (which indeed helped).
- `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. Brian Kernighan's `awk' also
- supports these extensions.
+ With `gawk', you can use `fflush("/dev/stdout")' if you wish
+ to flush only the standard output.
`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.
+ otherwise, it returns non-zero. (`gawk' 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.
+ 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.
+
`system(COMMAND)'
Execute the operating-system command COMMAND and then return to
the `awk' program. Return COMMAND's exit status.
@@ -11386,53 +12852,21 @@ parameters are enclosed in square brackets ([ ]):
is disabled (*note Options::).
-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.
+ Controlling Output Buffering with `system()'
-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:
+ The `fflush()' function provides explicit control over output
+buffering for individual files and pipes. However, its use is not
+portable to many older `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
+useful, it is also efficient. Although 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.)
@@ -11487,8 +12921,9 @@ 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 ([ ]):
+the POSIX standard.(2) However, recent versions of `mawk' (*note Other
+Versions::) also support these functions. Optional parameters are
+enclosed in square brackets ([ ]):
`mktime(DATESPEC)'
Turn DATESPEC into a timestamp in the same form as is returned by
@@ -11513,7 +12948,7 @@ Optional parameters are enclosed in square brackets ([ ]):
If DATESPEC does not contain enough elements or if the resulting
time is out of range, `mktime()' returns -1.
-`strftime([FORMAT [, TIMESTAMP [, UTC-FLAG]]])'
+`strftime('[FORMAT [`,' TIMESTAMP [`,' UTC-FLAG] ] ]`)'
Format the time specified by TIMESTAMP based on the contents of
the FORMAT string and return the result. It is similar to the
function of the same name in ISO C. If UTC-FLAG is present and is
@@ -11522,13 +12957,14 @@ Optional parameters are enclosed in square brackets ([ ]):
Otherwise, the value is formatted for the local time zone. 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 the value of
+ `gawk' uses the current time of day as the timestamp. Without a
+ FORMAT argument, `strftime()' uses the value of
`PROCINFO["strftime"]' as the format string (*note Built-in
Variables::). The default string value is
`"%a %b %e %H:%M:%S %Z %Y"'. This format string produces output
that is equivalent to that of the `date' utility. You can assign
- a new value to `PROCINFO["strftime"]' to change the default format.
+ a new value to `PROCINFO["strftime"]' to change the default
+ format; see the following list for the various format directives.
`systime()'
Return the current time as the number of seconds since the system
@@ -11592,11 +13028,11 @@ the following date format specifications:
`%g'
The year modulo 100 of the ISO 8601 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 8601 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.
+ number (00-99). For example, January 1, 2012, is in week 53 of
+ 2011. Thus, the year of its ISO 8601 week number is 2011, even
+ though its year is 2012. Similarly, December 31, 2012, is in week
+ 1 of 2013. Thus, the year of its ISO week number is 2013, even
+ though its year is 2012.
`%G'
The full year of the ISO week number, as a decimal number.
@@ -11676,7 +13112,7 @@ the following date format specifications:
The year modulo 100 as a decimal number (00-99).
`%Y'
- The full year as a decimal number (e.g., 2011).
+ The full year as a decimal number (e.g., 2015).
`%z'
The timezone offset in a +HHMM format (e.g., the format necessary
@@ -11688,24 +13124,15 @@ the following date format specifications:
`%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
+ "Alternative 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, 2012 in the United States is "9/4/12." In many countries
-in Europe, however, it is abbreviated "4.9.12." Thus, the `%x'
-specification in a `"US"' locale might produce `9/4/12', while in a
-`"EUROPE"' locale, it might produce `4.9.12'. The ISO C standard
-defines a default `"C"' locale, which is an environment that is typical
-of what many C programmers are used to.
+ If a conversion specifier is not one of those just listed, the
+behavior is undefined.(6)
For systems that are not yet fully standards-compliant, `gawk'
supplies a copy of `strftime()' from the GNU C Library. It supports
@@ -11725,8 +13152,8 @@ format specifications are available:
The time as a decimal timestamp in seconds since the epoch.
- Additionally, the alternate representations are recognized but their
-normal representations are used.
+ Additionally, the alternative representations are recognized but
+their normal representations are used.
The following example is an `awk' implementation of the POSIX `date'
utility. Normally, the `date' utility prints the current date and time
@@ -11736,7 +13163,7 @@ 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 Wednesday, March 30, 2011.
+ -| Today is Monday, September 22, 2014.
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
@@ -11753,7 +13180,7 @@ if the time zone is set to UTC:
esac
gawk 'BEGIN {
- format = "%a %b %e %H:%M:%S %Z %Y"
+ format = PROCINFO["strftime"]
exitval = 0
if (ARGC > 2)
@@ -11783,7 +13210,7 @@ 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
+Other internationalization features are described in *note
Internationalization::.
(6) This is because ISO C leaves the behavior of the C version of
@@ -11797,13 +13224,13 @@ File: gawk.info, Node: Bitwise Functions, Next: Type Functions, Prev: Time Fu
9.1.6 Bit-Manipulation Functions
--------------------------------
- I can explain it for you, but I can't understand it for you.
+ 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
+are bitwise AND, OR, and XOR. The operations are described in *note
table-bitwise-ops::.
Bit Operator
@@ -11814,7 +13241,7 @@ table-bitwise-ops::.
0 | 0 0 | 0 1 | 0 1
1 | 0 1 | 1 1 | 1 0
-Table 9.6: Bitwise Operations
+Table 9.5: 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.
@@ -11825,30 +13252,33 @@ 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:
+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'. The following list describes `gawk''s built-in
+functions that implement the bitwise operations. Optional parameters
+are enclosed in square brackets ([ ]):
-`and(V1, V2)'
- Return the bitwise AND of the values provided by V1 and V2.
+``and('V1`,' V2 [`,' ...]`)''
+ Return the bitwise AND of the arguments. There must be at least
+ two.
-`compl(VAL)'
+``compl(VAL)''
Return the bitwise complement of VAL.
-`lshift(VAL, COUNT)'
+``lshift(VAL, COUNT)''
Return the value of VAL, shifted left by COUNT bits.
-`or(V1, V2)'
- Return the bitwise OR of the values provided by V1 and V2.
+``or('V1`,' V2 [`,' ...]`)''
+ Return the bitwise OR of the arguments. There must be at least two.
-`rshift(VAL, COUNT)'
+``rshift(VAL, COUNT)''
Return the value of VAL, shifted right by COUNT bits.
-`xor(V1, V2)'
- Return the bitwise XOR of the values provided by V1 and V2.
+``xor('V1`,' V2 [`,' ...]`)''
+ Return the bitwise XOR of the arguments. There must be at least
+ two.
- For all of these functions, first the double precision
+ 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
@@ -11906,7 +13336,7 @@ 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,
+ 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.
@@ -11919,7 +13349,7 @@ Nondecimal-numbers::), and then demonstrates the results of the
(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.
+have the left side fill with 1's.

File: gawk.info, Node: Type Functions, Next: I18N Functions, Prev: Bitwise Functions, Up: Built-in
@@ -11929,12 +13359,25 @@ File: gawk.info, Node: Type Functions, Next: I18N Functions, Prev: Bitwise Fu
`gawk' provides a single function that lets you distinguish an array
from a scalar variable. This is necessary for writing code that
-traverses every element of a true multidimensional array (*note Arrays
-of Arrays::).
+traverses every element of an array of arrays (*note Arrays of
+Arrays::).
`isarray(X)'
Return a true value if X is an array. Otherwise return false.
+ `isarray()' is meant for use in two circumstances. The first is when
+traversing a multidimensional array: you can test if an element is
+itself an array or not. The second is inside the body of a
+user-defined function (not discussed yet; *note User-defined::), to
+test if a parameter is an array or not.
+
+ NOTE: Using `isarray()' at the global level to test variables
+ makes no sense. Because you are the one writing the program, you
+ are supposed to know if your variables are arrays or not. And in
+ fact, due to the way `gawk' works, if you pass the name of a
+ variable that has not been previously used to `isarray()', `gawk'
+ ends up turning it into a scalar.
+

File: gawk.info, Node: I18N Functions, Prev: Type Functions, Up: Built-in
@@ -11947,7 +13390,7 @@ descriptions here are purposely brief. *Note Internationalization::,
for the full story. Optional parameters are enclosed in square
brackets ([ ]):
-`bindtextdomain(DIRECTORY [, DOMAIN])'
+`bindtextdomain(DIRECTORY' [`,' DOMAIN]`)'
Set 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
@@ -11957,13 +13400,13 @@ brackets ([ ]):
the null string (`""'), then `bindtextdomain()' returns the
current binding for the given DOMAIN.
-`dcgettext(STRING [, DOMAIN [, CATEGORY]])'
+`dcgettext(STRING' [`,' DOMAIN [`,' CATEGORY] ]`)'
Return 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]])'
+`dcngettext(STRING1, STRING2, NUMBER' [`,' DOMAIN [`,' CATEGORY] ]`)'
Return 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,
@@ -11979,8 +13422,8 @@ File: gawk.info, Node: User-defined, Next: Indirect Calls, Prev: Built-in, U
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.
+ones (*note Function Calls::), but it is up to you to define them
+(i.e., to tell `awk' what they should do).
* Menu:
@@ -11997,7 +13440,10 @@ File: gawk.info, Node: Definition Syntax, Next: Function Example, Up: User-de
9.2.1 Function Definition Syntax
--------------------------------
-Definitions of functions can appear anywhere between the rules of an
+ It's entirely fair to say that the `awk' syntax for local variable
+ definitions is appallingly awful. -- Brian Kernighan
+
+ 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
@@ -12006,29 +13452,36 @@ starting to execute any of it.
The definition of a function named NAME looks like this:
- function NAME([PARAMETER-LIST])
- {
+ `function' NAME`('[PARAMETER-LIST]`)'
+ `{'
BODY-OF-FUNCTION
- }
+ `}'
Here, 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.
+underscores that doesn't start with a digit. Here too, only the 52
+upper- and lowercase English letters may be used in a function name.
+Within a single `awk' program, any particular name can only be used as
+a variable, array, or function.
PARAMETER-LIST is an optional 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.
+call.
- In addition, according to the POSIX standard, function parameters
-cannot have the same name as one of the special built-in variables
-(*note Built-in Variables::. Not all versions of `awk' enforce this
+ A function cannot have two parameters with the same name, nor may it
+have a parameter with the same name as the function itself. In
+addition, according to the POSIX standard, function parameters cannot
+have the same name as one of the special predefined variables (*note
+Built-in Variables::). Not all versions of `awk' enforce this
restriction.
+ Local variables act like the empty string if referenced where a
+string value is required, and like zero if referenced where a numeric
+value is required. This is the same as regular variables that have
+never been assigned a value. (There is more to understand about local
+variables; *note Dynamic Typing::.)
+
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
@@ -12070,8 +13523,8 @@ function. When this happens, we say the function is "recursive". The
act of a function calling itself is called "recursion".
All the built-in functions return a value to their caller.
-User-defined functions can do also, using the `return' statement, which
-is described in detail in *Note Return Statement::. Many of the
+User-defined functions can do so also, using the `return' statement,
+which is described in detail in *note Return Statement::. Many of the
subsequent examples in this minor node use the `return' statement.
In many `awk' implementations, including `gawk', the keyword
@@ -12083,7 +13536,7 @@ function:
func foo() { a = sqrt($1) ; print a }
-Instead it defines a rule that, for each record, concatenates the value
+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
@@ -12095,7 +13548,7 @@ keyword `function' when defining a function.
---------- Footnotes ----------
- (1) This program won't actually run, since `foo()' is undefined.
+ (1) This program won't actually run, because `foo()' is undefined.

File: gawk.info, Node: Function Example, Next: Function Caveats, Prev: Definition Syntax, Up: User-defined
@@ -12128,12 +13581,13 @@ this program, using our function to format the results, prints:
5.6
21.2
- This function deletes all the elements in an array:
+ This function deletes all the elements in an array (recall that the
+extra whitespace signifies the start of the local variable list):
function delarray(a, i)
{
for (i in a)
- delete a[i]
+ delete a[i]
}
When working with arrays, it is often necessary to delete all the
@@ -12141,30 +13595,31 @@ 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.)
+contents of an entire array is a relatively recent(1) addition to the
+POSIX standard.)
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.
+In this case, the recursion terminates when the input string is already
+empty:
- function rev(str, start)
+ function rev(str)
{
- if (start == 0)
+ if (str == "")
return ""
- return (substr(str, start, 1) rev(str, start - 1))
+ return (rev(substr(str, 2)) substr(str, 1, 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
+ > gawk -e '{ print rev($0) }' -f rev.awk
-| !cinaP t'noD
- The C `ctime()' function takes a timestamp and returns it in a
+ The C `ctime()' function takes a timestamp and returns it as 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()':
@@ -12176,18 +13631,30 @@ an `awk' version of `ctime()':
function ctime(ts, format)
{
format = "%a %b %e %H:%M:%S %Z %Y"
+
if (ts == 0)
ts = systime() # use current time as default
return strftime(format, ts)
}
+ You might think that `ctime()' could use `PROCINFO["strftime"]' for
+its format string. That would be a mistake, because `ctime()' is
+supposed to return the time formatted in a standard fashion, and
+user-level code could have changed `PROCINFO["strftime"]'.
+
+ ---------- Footnotes ----------
+
+ (1) Late in 2012.
+

File: gawk.info, Node: Function Caveats, Next: Return Statement, Prev: Function Example, Up: User-defined
9.2.3 Calling User-Defined Functions
------------------------------------
-This section describes how to call a user-defined function.
+"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.
* Menu:
@@ -12198,27 +13665,23 @@ This section describes how to call a user-defined function.

File: gawk.info, Node: Calling A Function, Next: Variable Scope, Up: Function Caveats
-9.2.3.1 Writing A Function Call
+9.2.3.1 Writing a Function Call
...............................
-"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 become the actual arguments.
-For example, here is a call to `foo()' with three arguments (the first
-being a string concatenation):
+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 become 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
+ between the function name and the opening 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.

@@ -12227,9 +13690,10 @@ File: gawk.info, Node: Variable Scope, Next: Pass By Value/Reference, Prev: C
9.2.3.2 Controlling Variable Scope
..................................
-There is no way to make a variable local to a `{ ... }' block in `awk',
-but you can make a variable local to a function. It is good practice to
-do so whenever a variable is needed only in that function.
+Unlike many languages, there is no way to make a variable local to a
+`{' ... `}' block in `awk', but you can make a variable local to a
+function. It is good practice to do so whenever a variable is needed
+only in that function.
To make a variable local to a function, simply declare the variable
as an argument after the actual function arguments (*note Definition
@@ -12270,7 +13734,7 @@ variable instance:
top's i=3
If you want `i' to be local to both `foo()' and `bar()' do as
-follows (the extra-space before `i' is a coding convention to indicate
+follows (the extra space before `i' is a coding convention to indicate
that `i' is a local variable, not an argument):
function bar( i)
@@ -12304,23 +13768,56 @@ that `i' is a local variable, not an argument):
foo's i=1
top's i=10
+ Besides scalar values (strings and numbers), you may also have local
+arrays. By using a parameter name as an array, `awk' treats it as an
+array, and it is local to the function. In addition, recursive calls
+create new arrays. Consider this example:
+
+ function some_func(p1, a)
+ {
+ if (p1++ > 3)
+ return
+
+ a[p1] = p1
+
+ some_func(p1)
+
+ printf("At level %d, index %d %s found in a\n",
+ p1, (p1 - 1), (p1 - 1) in a ? "is" : "is not")
+ printf("At level %d, index %d %s found in a\n",
+ p1, p1, p1 in a ? "is" : "is not")
+ print ""
+ }
+
+ BEGIN {
+ some_func(1)
+ }
+
+ When run, this program produces the following output:
+
+ At level 4, index 3 is not found in a
+ At level 4, index 4 is found in a
+
+ At level 3, index 2 is not found in a
+ At level 3, index 3 is found in a
+
+ At level 2, index 1 is not found in a
+ At level 2, index 2 is found in a
+

File: gawk.info, Node: Pass By Value/Reference, Prev: Variable Scope, Up: Function Caveats
-9.2.3.3 Passing Function Arguments By Value Or By Reference
+9.2.3.3 Passing Function Arguments by Value Or by Reference
...........................................................
In `awk', when you declare a function, there is no way to declare
explicitly whether the arguments are passed "by value" or "by
reference".
- Instead the passing convention is determined at runtime when the
-function is called according to the following rule:
-
- * If the argument is an array variable, then it is passed by
- reference,
-
- * Otherwise the argument is passed by value.
+ Instead, the passing convention is determined at runtime when the
+function is called according to the following rule: if the argument is
+an array variable, then it is passed by reference. Otherwise, the
+argument is passed by value.
Passing an argument by value means that when a function is called, it
is given a _copy_ of the value of this argument. The caller may use a
@@ -12372,8 +13869,8 @@ function _are_ visible outside that function.
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'.
+ 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
@@ -12395,8 +13892,9 @@ 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
+ Some `awk' implementations generate a runtime error if you use
+either the `next' statement or the `nextfile' statement (*note Next
+Statement::, and *note Nextfile Statement::) inside a user-defined
function. `gawk' does not have this limitation.

@@ -12411,11 +13909,11 @@ 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]
+ `return' [EXPRESSION]
The EXPRESSION part is optional. Due most likely to an oversight,
POSIX does not define what the return value is if you omit the
-EXPRESSION. Technically speaking, this make the returned value
+EXPRESSION. Technically speaking, this makes the returned value
undefined, and therefore, unpredictable. In practice, though, all
versions of `awk' simply return the null string, which acts like zero
if used in a numeric context.
@@ -12445,11 +13943,12 @@ a value for the largest number among the elements of an array:
}
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 local
-variables. You should follow this convention when defining functions.
+local variables `i' and `ret' are not intended to be arguments; there
+is nothing to stop you from passing more than one argument to
+`maxelt()' but the results would be strange. The extra space before
+`i' in the function parameter list indicates that `i' and `ret' are
+local variables. 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
@@ -12508,16 +14007,20 @@ Here is an annotated sample program:
x = 1 # now not allowed, runtime error
}
+ In this example, the first call to `foo()' generates a fatal error,
+so `awk' will not report the second error. If you comment out that
+call, though, then `awk' does report the second error.
+
Usually, such things aren't a big issue, but it's worth being aware
of them.

-File: gawk.info, Node: Indirect Calls, Prev: User-defined, Up: Functions
+File: gawk.info, Node: Indirect Calls, Next: Functions Summary, Prev: User-defined, Up: Functions
9.3 Indirect Function Calls
===========================
-This section describes a `gawk'-specific extension.
+This section describes an advanced, `gawk'-specific extension.
Often, you may wish to defer the choice of function to call until
runtime. For example, you may have different kinds of records, each of
@@ -12556,18 +14059,18 @@ your test scores:
This style of programming works, but can be awkward. With "indirect"
function calls, you tell `gawk' to use the _value_ of a variable as the
-name of the function to call.
+_name_ of the function to call.
The syntax is similar to that of a regular function call: an
-identifier immediately followed by a left parenthesis, any arguments,
-and then a closing right parenthesis, with the addition of a leading `@'
-character:
+identifier immediately followed by an opening parenthesis, any
+arguments, and then a closing parenthesis, with the addition of a
+leading `@' character:
the_func = "sum"
- result = @the_func() # calls the `sum' function
+ result = @the_func() # calls the sum() function
Here is a full program that processes the previously shown data,
-using indirect function calls.
+using indirect function calls:
# indirectcall.awk --- Demonstrate indirect function calls
@@ -12595,10 +14098,9 @@ using indirect function calls.
These two functions expect to work on fields; thus the parameters
`first' and `last' indicate where in the fields to start and end.
-Otherwise they perform the expected computations and are not unusual.
+Otherwise they perform the expected computations and are not unusual:
# For each record, print the class name and the requested statistics
-
{
class_name = $1
gsub(/_/, " ", class_name) # Replace _ with spaces
@@ -12679,7 +14181,7 @@ mechanism allows you to sort arbitrary data in an arbitrary fashion.
# quicksort_swap --- helper function for quicksort, should really be inline
- function quicksort_swap(data, i, j, temp)
+ function quicksort_swap(data, i, j, temp)
{
temp = data[i]
data[i] = data[j]
@@ -12715,8 +14217,8 @@ order.
Next comes a sorting function. It is parameterized with the
starting and ending field numbers and the comparison function. It
-builds an array with the data and calls `quicksort' appropriately, and
-then formats the results as a single string:
+builds an array with the data and calls `quicksort()' appropriately,
+and then formats the results as a single string:
# do_sort --- sort the data according to `compare'
# and return it as a string
@@ -12782,1602 +14284,189 @@ names of the two comparison functions:
-| sort: <87.1 93.4 95.6 100.0>
-| rsort: <100.0 95.6 93.4 87.1>
- Remember that you must supply a leading `@' in front of an indirect
-function call.
-
- Unfortunately, indirect function calls cannot be used with the
-built-in functions. However, you can generally write "wrapper"
-functions which call the built-in ones, and those can be called
-indirectly. (Other than, perhaps, the mathematical functions, there is
-not a lot of reason to try to call the built-in functions indirectly.)
-
- `gawk' does its best to make indirect function calls efficient. For
-example, in the following case:
-
- for (i = 1; i <= n; i++)
- @the_func()
-
-`gawk' will look up the actual function to call only once.
-
-
-File: gawk.info, Node: Internationalization, Next: Advanced Features, Prev: Functions, Up: Top
-
-10 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.
-
- For many years, 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 forced to write in C or 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.
-
-
-File: gawk.info, Node: I18N and L10N, Next: Explaining gettext, Up: Internationalization
-
-10.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.
-
-
-File: gawk.info, Node: Explaining gettext, Next: Programmer i18n, Prev: I18N and L10N, Up: Internationalization
-
-10.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 template file (`guide.pot'),
- 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.pot' is copied to a
- portable object file (`.po') and translations are created and
- shipped with the application. For example, there might be a
- `fr.po' for a French translation.
-
- 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("%s", 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("%s", _("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 the 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'. Therefore, 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.
-
-
-File: gawk.info, Node: Programmer i18n, Next: Translator i18n, Prev: Explaining gettext, Up: Internationalization
-
-10.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]])'
- Return 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]])'
- Return 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 about argument order as for the `dcgettext()'
- function apply.
-
-`bindtextdomain(DIRECTORY [, DOMAIN])'
- Change 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). Return 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'.
-
-
-File: gawk.info, Node: Translator i18n, Next: I18N Example, Prev: Programmer i18n, Up: Internationalization
-
-10.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-pot' 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.
-
-
-File: gawk.info, Node: String Extraction, Next: Printf Ordering, Up: Translator i18n
-
-10.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-pot' command-line
-option to create the initial `.pot' file:
-
- $ gawk --gen-pot -f guide.awk > guide.pot
-
- When run with `--gen-pot', `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) The `xgettext' utility that comes with GNU `gettext' can handle
-`.awk' files.
-
-
-File: gawk.info, Node: Printf Ordering, Next: I18N Portability, Prev: String Extraction, Up: Translator i18n
-
-10.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 specifiers 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 counterintuitive.
-
- `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.
-
-
-File: gawk.info, Node: I18N Portability, Prev: Printf Ordering, Up: Translator i18n
-
-10.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.
-
-
-File: gawk.info, Node: I18N Example, Next: Gawk I18N, Prev: Translator i18n, Up: Internationalization
-
-10.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-pot' to create the `.pot' file:
-
- $ gawk --gen-pot -f guide.awk > guide.pot
-
-This produces:
-
- #: guide.awk:4
- msgid "Don't Panic"
- msgstr ""
-
- #: guide.awk:5
- msgid "The Answer Is"
- msgstr ""
-
- This original portable object template 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.pot' file.
-
- Next, the messages must be translated. Here is a translation to a
-hypothetical dialect of English, called "Mellow":(1)
-
- $ cp guide.pot 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.
-
-
-File: gawk.info, Node: Gawk I18N, Prev: I18N Example, Up: Internationalization
-
-10.6 `gawk' Can Speak Your Language
-===================================
-
-`gawk' itself has been internationalized using the GNU `gettext'
-package. (GNU `gettext' is described in complete detail in *note (GNU
-`gettext' utilities)Top:: gettext, GNU gettext tools.) As of this
-writing, the latest version of GNU `gettext' is version 0.18.1
-(ftp://ftp.gnu.org/gnu/gettext/gettext-0.18.1.tar.gz).
-
- If a translation of `gawk''s messages exists, then `gawk' produces
-usage messages, warnings, and fatal errors in the local language.
-
-
-File: gawk.info, Node: Advanced Features, Next: Library Functions, Prev: Internationalization, Up: Top
-
-11 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. Then, `gawk''s
-special features for sorting arrays are presented. 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. 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.
-* Array Sorting:: Facilities for controlling array traversal and
- sorting arrays.
-* Two-way I/O:: Two-way communications with another process.
-* TCP/IP Networking:: Using `gawk' for network programming.
-* Profiling:: Profiling your `awk' programs.
-
-
-File: gawk.info, Node: Nondecimal Data, Next: Array Sorting, Up: Advanced Features
-
-11.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 this facility could lead to surprising results, the
-default is to leave it 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.
-
-
-File: gawk.info, Node: Array Sorting, Next: Two-way I/O, Prev: Nondecimal Data, Up: Advanced Features
-
-11.2 Controlling Array Traversal and Array Sorting
-==================================================
-
-`gawk' lets you control the order in which `for (i in array)' loops
-will traverse an array.
-
- In addition, two built-in functions, `asort()' and `asorti()', let
-you sort arrays based on the array values and indices, respectively.
-These two functions also provide control over the sorting criteria used
-to order the elements during sorting.
-
-* Menu:
-
-* Controlling Array Traversal:: How to use PROCINFO["sorted_in"].
-* Array Sorting Functions:: How to use `asort()' and `asorti()'.
-
-
-File: gawk.info, Node: Controlling Array Traversal, Next: Array Sorting Functions, Up: Array Sorting
-
-11.2.1 Controlling Array Traversal
-----------------------------------
-
-By default, the order in which a `for (i in array)' loop scans an array
-is not defined; it is generally based upon the internal implementation
-of arrays inside `awk'.
-
- Often, though, it is desirable to be able to loop over the elements
-in a particular order that you, the programmer, choose. `gawk' lets
-you do this; this node describes how.
-
-* Menu:
-
-* Controlling Scanning With A Function:: Using a function to control scanning.
-* Controlling Scanning:: Controlling the order in which arrays
- are scanned.
-
-
-File: gawk.info, Node: Controlling Scanning With A Function, Next: Controlling Scanning, Up: Controlling Array Traversal
-
-11.2.1.1 Array Scanning Using A User-defined Function
-.....................................................
-
-The value of `PROCINFO["sorted_in"]' can be a function name. This lets
-you traverse an array based on any custom criterion. The array
-elements are ordered according to the return value of this function.
-The comparison function should be defined with at least four arguments:
-
- function comp_func(i1, v1, i2, v2)
- {
- COMPARE ELEMENTS 1 AND 2 IN SOME FASHION
- RETURN < 0; 0; OR > 0
- }
-
- Here, I1 and I2 are the indices, and V1 and V2 are the corresponding
-values of the two elements being compared. Either V1 or V2, or both,
-can be arrays if the array being traversed contains subarrays as
-values. The three possible return values are interpreted this way:
-
-`comp_func(i1, v1, i2, v2) < 0'
- Index I1 comes before index I2 during loop traversal.
-
-`comp_func(i1, v1, i2, v2) == 0'
- Indices I1 and I2 come together but the relative order with
- respect to each other is undefined.
-
-`comp_func(i1, v1, i2, v2) > 0'
- Index I1 comes after index I2 during loop traversal.
-
- Our first comparison function can be used to scan an array in
-numerical order of the indices:
-
- function cmp_num_idx(i1, v1, i2, v2)
- {
- # numerical index comparison, ascending order
- return (i1 - i2)
- }
-
- Our second function traverses an array based on the string order of
-the element values rather than by indices:
-
- function cmp_str_val(i1, v1, i2, v2)
- {
- # string value comparison, ascending order
- v1 = v1 ""
- v2 = v2 ""
- if (v1 < v2)
- return -1
- return (v1 != v2)
- }
-
- The third comparison function makes all numbers, and numeric strings
-without any leading or trailing spaces, come out first during loop
-traversal:
+ Another example where indirect functions calls are useful can be
+found in processing arrays. *note Walking Arrays::, presented a simple
+function for "walking" an array of arrays. That function simply
+printed the name and value of each scalar array element. However, it is
+easy to generalize that function, by passing in the name of a function
+to call when walking an array. The modified function looks like this:
- function cmp_num_str_val(i1, v1, i2, v2, n1, n2)
+ function process_array(arr, name, process, do_arrays, i, new_name)
{
- # numbers before string value comparison, ascending order
- n1 = v1 + 0
- n2 = v2 + 0
- if (n1 == v1)
- return (n2 == v2) ? (n1 - n2) : -1
- else if (n2 == v2)
- return 1
- return (v1 < v2) ? -1 : (v1 != v2)
- }
-
- Here is a main program to demonstrate how `gawk' behaves using each
-of the previous functions:
-
- BEGIN {
- data["one"] = 10
- data["two"] = 20
- data[10] = "one"
- data[100] = 100
- data[20] = "two"
-
- f[1] = "cmp_num_idx"
- f[2] = "cmp_str_val"
- f[3] = "cmp_num_str_val"
- for (i = 1; i <= 3; i++) {
- printf("Sort function: %s\n", f[i])
- PROCINFO["sorted_in"] = f[i]
- for (j in data)
- printf("\tdata[%s] = %s\n", j, data[j])
- print ""
+ for (i in arr) {
+ new_name = (name "[" i "]")
+ if (isarray(arr[i])) {
+ if (do_arrays)
+ @process(new_name, arr[i])
+ process_array(arr[i], new_name, process, do_arrays)
+ } else
+ @process(new_name, arr[i])
}
}
- Here are the results when the program is run:
-
- $ gawk -f compdemo.awk
- -| Sort function: cmp_num_idx Sort by numeric index
- -| data[two] = 20
- -| data[one] = 10 Both strings are numerically zero
- -| data[10] = one
- -| data[20] = two
- -| data[100] = 100
- -|
- -| Sort function: cmp_str_val Sort by element values as strings
- -| data[one] = 10
- -| data[100] = 100 String 100 is less than string 20
- -| data[two] = 20
- -| data[10] = one
- -| data[20] = two
- -|
- -| Sort function: cmp_num_str_val Sort all numbers before all strings
- -| data[one] = 10
- -| data[two] = 20
- -| data[100] = 100
- -| data[10] = one
- -| data[20] = two
+ The arguments are as follows:
- Consider sorting the entries of a GNU/Linux system password file
-according to login names. The following program sorts records by a
-specific field position and can be used for this purpose:
+`arr'
+ The array.
- # sort.awk --- simple program to sort by field position
- # field position is specified by the global variable POS
+`name'
+ The name of the array (a string).
- function cmp_field(i1, v1, i2, v2)
- {
- # comparison by value, as string, and ascending order
- return v1[POS] < v2[POS] ? -1 : (v1[POS] != v2[POS])
- }
-
- {
- for (i = 1; i <= NF; i++)
- a[NR][i] = $i
- }
-
- END {
- PROCINFO["sorted_in"] = "cmp_field"
- if (POS < 1 || POS > NF)
- POS = 1
- for (i in a) {
- for (j = 1; j <= NF; j++)
- printf("%s%c", a[i][j], j < NF ? ":" : "")
- print ""
- }
- }
-
- The first field in each entry of the password file is the user's
-login name, and the fields are seperated by colons. Each record
-defines a subarray (*note Arrays of Arrays::), with each field as an
-element in the subarray. Running the program produces the following
-output:
+`process'
+ The name of the function to call.
- $ gawk -vPOS=1 -F: -f sort.awk /etc/passwd
- -| adm:x:3:4:adm:/var/adm:/sbin/nologin
- -| apache:x:48:48:Apache:/var/www:/sbin/nologin
- -| avahi:x:70:70:Avahi daemon:/:/sbin/nologin
- ...
+`do_arrays'
+ If this is true, the function can handle elements that are
+ subarrays.
- The comparison should normally always return the same value when
-given a specific pair of array elements as its arguments. If
-inconsistent results are returned then the order is undefined. This
-behavior can be exploited to introduce random order into otherwise
-seemingly ordered data:
+ If subarrays are to be processed, that is done before walking them
+further.
- function cmp_randomize(i1, v1, i2, v2)
- {
- # random order
- return (2 - 4 * rand())
- }
+ When run with the following scaffolding, the function produces the
+same results as does the earlier `walk_array()' function:
- As mentioned above, the order of the indices is arbitrary if two
-elements compare equal. This is usually not a problem, but letting the
-tied elements come out in arbitrary order can be an issue, especially
-when comparing item values. The partial ordering of the equal elements
-may change during the next loop traversal, if other elements are added
-or removed from the array. One way to resolve ties when comparing
-elements with otherwise equal values is to include the indices in the
-comparison rules. Note that doing this may make the loop traversal
-less efficient, so consider it only if necessary. The following
-comparison functions force a deterministic order, and are based on the
-fact that the indices of two elements are never equal:
+ BEGIN {
+ a[1] = 1
+ a[2][1] = 21
+ a[2][2] = 22
+ a[3] = 3
+ a[4][1][1] = 411
+ a[4][2] = 42
- function cmp_numeric(i1, v1, i2, v2)
- {
- # numerical value (and index) comparison, descending order
- return (v1 != v2) ? (v2 - v1) : (i2 - i1)
+ process_array(a, "a", "do_print", 0)
}
- function cmp_string(i1, v1, i2, v2)
+ function do_print(name, element)
{
- # string value (and index) comparison, descending order
- v1 = v1 i1
- v2 = v2 i2
- return (v1 > v2) ? -1 : (v1 != v2)
+ printf "%s = %s\n", name, element
}
- A custom comparison function can often simplify ordered loop
-traversal, and the sky is really the limit when it comes to designing
-such a function.
-
- When string comparisons are made during a sort, either for element
-values where one or both aren't numbers, or for element indices handled
-as strings, the value of `IGNORECASE' (*note Built-in Variables::)
-controls whether the comparisons treat corresponding uppercase and
-lowercase letters as equivalent or distinct.
-
- Another point to keep in mind is that in the case of subarrays the
-element values can themselves be arrays; a production comparison
-function should use the `isarray()' function (*note Type Functions::),
-to check for this, and choose a defined sorting order for subarrays.
-
- All sorting based on `PROCINFO["sorted_in"]' is disabled in POSIX
-mode, since the `PROCINFO' array is not special in that case.
-
- As a side note, sorting the array indices before traversing the
-array has been reported to add 15% to 20% overhead to the execution
-time of `awk' programs. For this reason, sorted array traversal is not
-the default.
-
-
-File: gawk.info, Node: Controlling Scanning, Prev: Controlling Scanning With A Function, Up: Controlling Array Traversal
-
-11.2.1.2 Controlling Array Scanning Order
-.........................................
-
-As described in *Note Controlling Scanning With A Function::, you can
-provide the name of a function as the value of `PROCINFO["sorted_in"]'
-to specify custom sorting criteria.
-
- Often, though, you may wish to do something simple, such as "sort
-based on comparing the indices in ascending order," or "sort based on
-comparing the values in descending order." Having to write a simple
-comparison function for this purpose for use in all of your programs
-becomes tedious. For the common simple cases, `gawk' provides the
-option of supplying special names that do the requested sorting for you.
-You can think of them as "predefined" sorting functions, if you like,
-although the names purposely include characters that are not valid in
-real `awk' function names.
-
- The following special values are available:
-
-`"@ind_str_asc"'
- Order by indices compared as strings; this is the most basic sort.
- (Internally, array indices are always strings, so with `a[2*5] = 1'
- the index is `"10"' rather than numeric 10.)
-
-`"@ind_num_asc"'
- Order by indices but force them to be treated as numbers in the
- process. Any index with a non-numeric value will end up
- positioned as if it were zero.
-
-`"@val_type_asc"'
- Order by element values rather than indices. Ordering is by the
- type assigned to the element (*note Typing and Comparison::). All
- numeric values come before all string values, which in turn come
- before all subarrays.
-
-`"@val_str_asc"'
- Order by element values rather than by indices. Scalar values are
- compared as strings. Subarrays, if present, come out last.
-
-`"@val_num_asc"'
- Order by element values rather than by indices. Scalar values are
- compared as numbers. Subarrays, if present, come out last. When
- numeric values are equal, the string values are used to provide an
- ordering: this guarantees consistent results across different
- versions of the C `qsort()' function.(1)
-
-`"@ind_str_desc"'
- Reverse order from the most basic sort.
-
-`"@ind_num_desc"'
- Numeric indices ordered from high to low.
-
-`"@val_type_desc"'
- Element values, based on type, in descending order.
-
-`"@val_str_desc"'
- Element values, treated as strings, ordered from high to low.
- Subarrays, if present, come out first.
-
-`"@val_num_desc"'
- Element values, treated as numbers, ordered from high to low.
- Subarrays, if present, come out first.
-
-`"@unsorted"'
- Array elements are processed in arbitrary order, which is the
- normal `awk' behavior. You can also get the normal behavior by just
- deleting the `"sorted_in"' element from the `PROCINFO' array, if
- it previously had a value assigned to it.
-
- The array traversal order is determined before the `for' loop starts
-to run. Changing `PROCINFO["sorted_in"]' in the loop body will not
-affect the loop.
-
- For example:
-
- $ gawk 'BEGIN {
- > a[4] = 4
- > a[3] = 3
- > for (i in a)
- > print i, a[i]
- > }'
- -| 4 4
- -| 3 3
- $ gawk 'BEGIN {
- > PROCINFO["sorted_in"] = "@ind_str_asc"
- > a[4] = 4
- > a[3] = 3
- > for (i in a)
- > print i, a[i]
- > }'
- -| 3 3
- -| 4 4
-
- When sorting an array by element values, if a value happens to be a
-subarray then it is considered to be greater than any string or numeric
-value, regardless of what the subarray itself contains, and all
-subarrays are treated as being equal to each other. Their order
-relative to each other is determined by their index strings.
-
- ---------- Footnotes ----------
-
- (1) When two elements compare as equal, the C `qsort()' function
-does not guarantee that they will maintain their original relative
-order after sorting. Using the string value to provide a unique
-ordering when the numeric values are equal ensures that `gawk' behaves
-consistently across different environments.
-
-
-File: gawk.info, Node: Array Sorting Functions, Prev: Controlling Array Traversal, Up: Array Sorting
-
-11.2.2 Sorting Array Values and Indices with `gawk'
----------------------------------------------------
-
-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]
+ Remember that you must supply a leading `@' in front of an indirect
+function call.
- 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 array elements are compared as strings.
+ Starting with version 4.1.2 of `gawk', indirect function calls may
+also be used with built-in functions and with extension functions
+(*note Dynamic Extensions::). The only thing you cannot do is pass a
+regular expression constant to a built-in function through an indirect
+function call.(1)
- 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:
+ `gawk' does its best to make indirect function calls efficient. For
+example, in the following case:
- 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.
-
- `asort()' accepts a third string argument to control comparison of
-array elements. As with `PROCINFO["sorted_in"]', this argument may be
-the name of a user-defined function, or one of the predefined names
-that `gawk' provides (*note Controlling Scanning With A Function::).
-
- NOTE: In all cases, the sorted element values consist of the
- original array's element values. The ability to control
- comparison merely affects the way in which they are sorted.
-
- Often, what's needed is to sort on the values of the _indices_
-instead of the values of the elements. To do that, 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++) {
- Work with sorted indices directly:
- DO SOMETHING WITH dest[i]
- ...
- Access original array via sorted indices:
- DO SOMETHING WITH source[dest[i]]
- }
- }
-
- Similar to `asort()', in all cases, the sorted element values
-consist of the original array's indices. The ability to control
-comparison merely affects the way in which they are sorted.
-
- 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.(1)
-
- 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.
-
- Because `IGNORECASE' affects string comparisons, the value of
-`IGNORECASE' also affects sorting for both `asort()' and `asorti()'.
-Note also that the locale's sorting order does _not_ come into play;
-comparisons are based on character values only.(2) Caveat Emptor.
-
- ---------- Footnotes ----------
-
- (1) You may also use one of the predefined sorting names that sorts
-in decreasing order.
-
- (2) This is true because locale-based comparison occurs only when in
-POSIX compatibility mode, and since `asort()' and `asorti()' are `gawk'
-extensions, they are not available in that case.
-
-
-File: gawk.info, Node: Two-way I/O, Next: TCP/IP Networking, Prev: Array Sorting, Up: Advanced Features
-
-11.3 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.
-
- However, with `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 `|&' 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 coprocess. 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
-coprocess 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'.
-
- You may also 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, save in convenience variable
- PROCINFO[command, "pty"] = 1 # update PROCINFO
- print ... |& command # start two-way pipe
- ...
+ @the_func()
-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.
+`gawk' looks up the actual function to call only once.
---------- Footnotes ----------
- (1) This is very different from the same operator in the C shell.
-
-
-File: gawk.info, Node: TCP/IP Networking, Next: Profiling, Prev: Two-way I/O, Up: Advanced Features
-
-11.4 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
-network 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 one of
-`/inet/', `/inet4/' or `/inet6'.
-
- The full syntax of the special file name is
-`/NET-TYPE/PROTOCOL/LOCAL-PORT/REMOTE-HOST/REMOTE-PORT'. The
-components are:
-
-NET-TYPE
- Specifies the kind of Internet connection to make. Use `/inet4/'
- to force IPv4, and `/inet6/' to force IPv6. Plain `/inet/' (which
- used to be the only option) uses the system default, most likely
- IPv4.
-
-PROTOCOL
- The protocol to use over IP. This must be either `tcp', or `udp',
- for a TCP or UDP IP connection, respectively. The use of TCP is
- recommended for most applications.
-
-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
- `getaddrinfo()' 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.
-
- NOTE: Failure in opening a two-way socket will result in a
- non-fatal error being returned to the calling code. The value of
- `ERRNO' indicates the error (*note Auto-set::).
-
- 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. See *note (General
-Introduction)Top:: gawkinet, TCP/IP Internetworking with `gawk', for a
-much more complete introduction and discussion, as well as extensive
-examples.
+ (1) This may change in a future version; recheck the documentation
+that comes with your version of `gawk' to see if it has.

-File: gawk.info, Node: Profiling, Prev: TCP/IP Networking, Up: Advanced Features
-
-11.5 Profiling Your `awk' Programs
-==================================
-
-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'.
-
- 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 features of profiling
-output. They are as follows:
-
- * The program is printed in the order `BEGIN' rule, `BEGINFILE' rule,
- pattern/action rules, `ENDFILE' rule, `END' rule and functions,
- listed alphabetically. Multiple `BEGIN' and `END' rules are
- merged together, as are multiple `BEGINFILE' and `ENDFILE' rules.
-
- * 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)'.
+File: gawk.info, Node: Functions Summary, Prev: Indirect Calls, Up: Functions
- * 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',
-`END', `BEGINFILE', and `ENDFILE' 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:
+9.4 Summary
+===========
- $ pgawk -f myprog &
- [1] 13992
+ * `awk' provides built-in functions and lets you define your own
+ functions.
-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':
+ * POSIX `awk' provides three kinds of built-in functions: numeric,
+ string, and I/O. `gawk' provides functions that sort arrays, work
+ with values representing time, do bit manipulation, determine
+ variable type (array versus scalar), and internationalize and
+ localize programs. `gawk' also provides several extensions to
+ some of standard functions, typically in the form of additional
+ arguments.
- $ kill -USR1 13992
+ * Functions accept zero or more arguments and return a value. The
+ expressions that provide the argument values are completely
+ evaluated before the function is called. Order of evaluation is
+ not defined. The return value can be ignored.
-As usual, the profiled version of the program is written to
-`awkprof.out', or to a different file if you use the `--profile' option.
+ * The handling of backslash in `sub()' and `gsub()' is not simple.
+ It is more straightforward in `gawk''s `gensub()' function, but
+ that function still requires care in its use.
- Along with the regular profile, as shown earlier, the profile
-includes a trace of any active functions:
+ * User-defined functions provide important capabilities but come with
+ some syntactic inelegancies. In a function call, there cannot be
+ any space between the function name and the opening left
+ parenthesis of the argument list. Also, there is no provision for
+ local variables, so the convention is to add extra parameters, and
+ to separate them visually from the real parameters by extra
+ whitespace.
- # Function Call Stack:
+ * User-defined functions may call other user-defined (and built-in)
+ functions and may call themselves recursively. Function parameters
+ "hide" any global variables of the same names. You cannot use the
+ name of a reserved variable (such as `ARGC') as the name of a
+ parameter in user-defined functions.
- # 3. baz
- # 2. bar
- # 1. foo
- # -- main --
+ * Scalar values are passed to user-defined functions by value. Array
+ parameters are passed by reference; any changes made by the
+ function to array parameters are thus visible after the function
+ has returned.
- 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.
+ * Use the `return' statement to return from a user-defined function.
+ An optional expression becomes the function's return value. Only
+ scalar values may be returned by a function.
- If you use the `HUP' signal instead of the `USR1' signal, `pgawk'
-produces the profile and the function call trace and then exits.
+ * If a variable that has never been used is passed to a user-defined
+ function, how that function treats the variable can set its nature:
+ either scalar or array.
- When `pgawk' runs on MS-Windows systems, 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.
+ * `gawk' provides indirect function calls using a special syntax.
+ By setting a variable to the name of a function, you can determine
+ at runtime what function will be called at that point in the
+ program. This is equivalent to function pointers in C and C++.
- Finally, regular `gawk' also accepts the `--profile' option. When
-called this way, `gawk' "pretty prints" the program into `awkprof.out',
-without any execution counts.

-File: gawk.info, Node: Library Functions, Next: Sample Programs, Prev: Advanced Features, Up: Top
+File: gawk.info, Node: Library Functions, Next: Sample Programs, Prev: Functions, Up: Top
-12 A Library of `awk' Functions
+10 A Library of `awk' Functions
*******************************
-*Note User-defined::, describes how to write your own `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.
+ In their seminal 1976 book, `Software Tools',(1) Brian Kernighan and
+P.J. Plauger wrote:
+
+ Good Programming is not learned from generalities, but by seeing
+ how significant programs can be made clean, easy to read, easy to
+ maintain and modify, human-engineered, efficient and reliable, by
+ the application of common sense and good programming practices.
+ Careful study and imitation of good programs leads to better
+ writing.
+
+ In fact, they felt this idea was so important that they placed this
+statement on the cover of their book. Because we believe strongly that
+their statement is correct, this major node and *note Sample
+Programs::, provide a good-sized body of code for you to read and, we
+hope, 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
+ *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 `awk' user
-community, see *Note How To Contribute::, for more information.
+community, 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.
+ The programs in this major node and in *note Sample Programs::,
+freely use `gawk'-specific features. 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
@@ -14388,7 +14477,7 @@ for different implementations of `awk' is pretty straightforward.
* 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
+ `IGNORECASE'. You can achieve almost the same effect(2) by adding
the following rule to the beginning of the program:
# ignore case
@@ -14409,17 +14498,22 @@ for different implementations of `awk' is pretty straightforward.
* Passwd Functions:: Functions for getting user information.
* Group Functions:: Functions for getting group information.
* Walking Arrays:: A function to walk arrays of arrays.
+* Library Functions Summary:: Summary of library functions.
+* Library Exercises:: Exercises.
---------- Footnotes ----------
- (1) The effects are not identical. Output of the transformed record
+ (1) Sadly, over 35 years later, many of the lessons taught by this
+book have yet to be learned by a vast number of practicing programmers.
+
+ (2) 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.

File: gawk.info, Node: Library Names, Next: General Functions, Up: Library Functions
-12.1 Naming Library Function Global Variables
+10.1 Naming Library Function Global Variables
=============================================
Due to the way the `awk' language evolved, variables are either
@@ -14430,8 +14524,8 @@ specific function). There is no intermediate state analogous to
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.
+variables are called "private", as 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
@@ -14447,8 +14541,8 @@ 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
+example, `_pw_byname()' in the user database routines (*note Passwd
+Functions::). This convention is recommended, as 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.(1)
@@ -14459,7 +14553,7 @@ 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'.
+variable is not one of `awk''s predefined 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
@@ -14469,15 +14563,16 @@ 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
+ # some_var should be local but by oversight is not
+ USE VARIABLE some_var
+ ...
}
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
+*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'.
@@ -14488,9 +14583,9 @@ 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 our own `awk'
-programming style has evolved and to provide some basis for this
+ (1) Although all the library routines could have been rewritten to
+use this convention, this was not done, in order to show how our 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
@@ -14499,7 +14594,7 @@ verifying this.

File: gawk.info, Node: General Functions, Next: Data File Management, Prev: Library Names, Up: Library Functions
-12.2 General Programming
+10.2 General Programming
========================
This minor node presents a number of functions that are of general
@@ -14517,12 +14612,14 @@ programming use.
* 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.
+* Getlocaltime Function:: A function to get formatted times.
+* Readfile Function:: A function to read an entire file at once.
+* Shell Quoting:: A function to quote strings for the shell.

File: gawk.info, Node: Strtonum Function, Next: Assert Function, Up: General Functions
-12.2.1 Converting Strings To Numbers
+10.2.1 Converting Strings to Numbers
------------------------------------
The `strtonum()' function (*note String Functions::) is a `gawk'
@@ -14531,7 +14628,7 @@ versions of `awk':
# mystrtonum --- convert string to number
- function mystrtonum(str, ret, chars, n, i, k, c)
+ function mystrtonum(str, ret, n, i, k, c)
{
if (str ~ /^0[0-7]*$/) {
# octal
@@ -14539,12 +14636,13 @@ versions of `awk':
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
+ # index() returns 0 if c not in string,
+ # includes c == "0"
+ k = index("1234567", c)
ret = ret * 8 + k
}
- } else if (str ~ /^0[xX][[:xdigit:]]+/) {
+ } else if (str ~ /^0[xX][[:xdigit:]]+$/) {
# hexadecimal
str = substr(str, 3) # lop off leading 0x
n = length(str)
@@ -14552,10 +14650,9 @@ versions of `awk':
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
+ # index() returns 0 if c not in string,
+ # includes c == "0"
+ k = index("123456789abcdef", c)
ret = ret * 16 + k
}
@@ -14577,7 +14674,7 @@ versions of `awk':
# a[5] = "123.45"
# a[6] = "1.e3"
# a[7] = "1.32"
- # a[7] = "1.32E2"
+ # a[8] = "1.32E2"
#
# for (i = 1; i in a; i++)
# print a[i], strtonum(a[i]), mystrtonum(a[i])
@@ -14586,9 +14683,11 @@ versions of `awk':
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.
+sets `k' to the index in `"1234567"' of the current octal digit. The
+return value will either be the same number as the digit, or zero if
+the character is not there, which will be true for a `0'. This is
+safe, because the regexp test in the `if' ensures that only octal
+values are converted.
Similar logic applies to the code that checks for and converts a
hexadecimal value, which starts with `0x' or `0X'. The use of
@@ -14606,7 +14705,7 @@ be tested with `gawk' and the results compared to the built-in

File: gawk.info, Node: Assert Function, Next: Round Function, Prev: Strtonum Function, Up: General Functions
-12.2.2 Assertions
+10.2.2 Assertions
-----------------
When writing large programs, it is often useful to know that a
@@ -14614,7 +14713,7 @@ 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
+`assert()' macro that a 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:
@@ -14692,14 +14791,14 @@ rule always ends with an `exit' statement.

File: gawk.info, Node: Round Function, Next: Cliff Random Function, Prev: Assert Function, Up: General Functions
-12.2.3 Rounding Numbers
+10.2.3 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
+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
@@ -14733,12 +14832,12 @@ might be useful if your `awk''s `printf' does unbiased rounding:
}
# test harness
- { print $0, round($0) }
+ # { print $0, round($0) }

File: gawk.info, Node: Cliff Random Function, Next: Ordinal Functions, Prev: Round Function, Up: General Functions
-12.2.4 The Cliff Random Number Generator
+10.2.4 The Cliff Random Number Generator
----------------------------------------
The Cliff random number generator
@@ -14767,7 +14866,7 @@ might try using this function instead.

File: gawk.info, Node: Ordinal Functions, Next: Join Function, Prev: Cliff Random Function, Up: General Functions
-12.2.5 Translating Between Characters and Numbers
+10.2.5 Translating Between Characters and Numbers
-------------------------------------------------
One commercial implementation of `awk' supplies a built-in function,
@@ -14809,16 +14908,16 @@ corresponding character. Both functions are written very nicely in
}
}
- Some explanation of the numbers used by `chr' is worthwhile. The
-most prominent character set in use today is ASCII.(1) Although an
+ Some explanation of the numbers used by `_ord_init()' is worthwhile.
+The most prominent character set in use today is ASCII.(1) 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.(2) 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
+character set, which uses all 256 values. There are other character
+sets in use on some older systems, but they are not really worth
worrying about:
function ord(str, c)
@@ -14835,8 +14934,7 @@ worrying about:
}
#### test code ####
- # BEGIN \
- # {
+ # BEGIN {
# for (;;) {
# printf("enter a character: ")
# if (getline var <= 0)
@@ -14860,12 +14958,12 @@ tests such as used here prohibitively expensive.
(2) 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 loop from 0 to 255.
+extensions, you can simplify `_ord_init()' to loop from 0 to 255.

-File: gawk.info, Node: Join Function, Next: Gettimeofday Function, Prev: Ordinal Functions, Up: General Functions
+File: gawk.info, Node: Join Function, Next: Getlocaltime Function, Prev: Ordinal Functions, Up: General Functions
-12.2.6 Merging an Array into a String
+10.2.6 Merging an Array into a String
-------------------------------------
When doing string processing, it is often useful to be able to join all
@@ -14877,7 +14975,7 @@ application programs (*note Sample Programs::).
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
+indices are numeric--a reasonable assumption, as the array was likely
created with `split()' (*note String Functions::):
# join.awk --- join an array into a string
@@ -14910,22 +15008,22 @@ concatenation. The lack of an explicit operator for concatenation
makes string operations more difficult than they really need to be.

-File: gawk.info, Node: Gettimeofday Function, Prev: Join Function, Up: General Functions
+File: gawk.info, Node: Getlocaltime Function, Next: Readfile Function, Prev: Join Function, Up: General Functions
-12.2.7 Managing the Time of Day
+10.2.7 Managing the Time of Day
-------------------------------
-The `systime()' and `strftime()' functions described in *Note Time
+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
+with the time of day in human-readable form. Although `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
+ The following function, `getlocaltime()', 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
+ # getlocaltime.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:
@@ -14949,7 +15047,7 @@ current time formatted in the same way as the `date' utility:
# time["weeknum"] -- week number, Sunday first day
# time["altweeknum"] -- week number, Monday first day
- function gettimeofday(time, ret, now, i)
+ function getlocaltime(time, ret, now, i)
{
# get time once, avoids unnecessary system calls
now = systime()
@@ -14987,14 +15085,129 @@ current time formatted in the same way as the `date' utility:
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
+*note Alarm Program::, uses this function. A more general design for
+the `getlocaltime()' function would have allowed the user to supply an
optional timestamp value to use instead of the current time.

+File: gawk.info, Node: Readfile Function, Next: Shell Quoting, Prev: Getlocaltime Function, Up: General Functions
+
+10.2.8 Reading a Whole File At Once
+-----------------------------------
+
+Often, it is convenient to have the entire contents of a file available
+in memory as a single string. A straightforward but naive way to do
+that might be as follows:
+
+ function readfile(file, tmp, contents)
+ {
+ if ((getline tmp < file) < 0)
+ return
+
+ contents = tmp
+ while (getline tmp < file) > 0)
+ contents = contents RT tmp
+
+ close(file)
+ return contents
+ }
+
+ This function reads from `file' one record at a time, building up
+the full contents of the file in the local variable `contents'. It
+works, but is not necessarily efficient.
+
+ The following function, based on a suggestion by Denis Shirokov,
+reads the entire contents of the named file in one shot:
+
+ # readfile.awk --- read an entire file at once
+
+ function readfile(file, tmp, save_rs)
+ {
+ save_rs = RS
+ RS = "^$"
+ getline tmp < file
+ close(file)
+ RS = save_rs
+
+ return tmp
+ }
+
+ It works by setting `RS' to `^$', a regular expression that will
+never match if the file has contents. `gawk' reads data from the file
+into `tmp' attempting to match `RS'. The match fails after each read,
+but fails quickly, such that `gawk' fills `tmp' with the entire
+contents of the file. (*Note Records::, for information on `RT' and
+`RS'.)
+
+ In the case that `file' is empty, the return value is the null
+string. Thus calling code may use something like:
+
+ contents = readfile("/some/path")
+ if (length(contents) == 0)
+ # file was empty ...
+
+ This tests the result to see if it is empty or not. An equivalent
+test would be `contents == ""'.
+
+ *Note Extension Sample Readfile::, for an extension function that
+also reads an entire file into memory.
+
+
+File: gawk.info, Node: Shell Quoting, Prev: Readfile Function, Up: General Functions
+
+10.2.9 Quoting Strings to Pass to the Shell
+-------------------------------------------
+
+Michael Brennan offers the following programming pattern, which he uses
+frequently:
+
+ #! /bin/sh
+
+ awkp='
+ ...
+ '
+
+ INPUT_PROGRAM | awk "$awkp" | /bin/sh
+
+ For example, a program of his named `flac-edit' has this form:
+
+ $ flac-edit -song="Whoope! That's Great" file.flac
+
+ It generates the following output, which is to be piped to the shell
+(`/bin/sh'):
+
+ chmod +w file.flac
+ metaflac --remove-tag=TITLE file.flac
+ LANG=en_US.88591 metaflac --set-tag=TITLE='Whoope! That'"'"'s Great' file.flac
+ chmod -w file.flac
+
+ Note the need for shell quoting. The function `shell_quote()' does
+it. `SINGLE' is the one-character string `"'"' and `QSINGLE' is the
+three-character string `"\"'\""':
+
+ # shell_quote --- quote an argument for passing to the shell
+
+ function shell_quote(s, # parameter
+ SINGLE, QSINGLE, i, X, n, ret) # locals
+ {
+ if (s == "")
+ return "\"\""
+
+ SINGLE = "\x27" # single quote
+ QSINGLE = "\"\x27\""
+ n = split(s, X, SINGLE)
+
+ ret = SINGLE X[1] SINGLE
+ for (i = 2; i <= n; i++)
+ ret = ret QSINGLE SINGLE X[i] SINGLE
+
+ return ret
+ }
+
+
File: gawk.info, Node: Data File Management, Next: Getopt Function, Prev: General Functions, Up: Library Functions
-12.3 Data File Management
+10.3 Data File Management
=========================
This minor node presents functions that are useful for managing
@@ -15011,10 +15224,10 @@ command-line data files.

File: gawk.info, Node: Filetrans Function, Next: Rewind Function, Up: Data File Management
-12.3.1 Noting Data File Boundaries
+10.3.1 Noting Data File Boundaries
----------------------------------
-The `BEGIN' and `END' rules are each executed exactly once at the
+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
@@ -15040,15 +15253,14 @@ does so _portably_; this works with any implementation of `awk':
# that each take the name of the file being started or
# finished, respectively.
- FILENAME != _oldfilename \
- {
+ FILENAME != _oldfilename {
if (_oldfilename != "")
endfile(_oldfilename)
_oldfilename = FILENAME
beginfile(FILENAME)
}
- END { endfile(FILENAME) }
+ END { endfile(FILENAME) }
This file must be loaded before the user's "main" program, so that
the rule it supplies is executed first.
@@ -15075,7 +15287,7 @@ again the value of multiple `BEGIN' and `END' rules should be clear.
pass and at the beginning of the second pass. The following version
solves the problem:
- # ftrans.awk --- handle data file transitions
+ # ftrans.awk --- handle datafile transitions
#
# user supplies beginfile() and endfile() functions
@@ -15086,21 +15298,20 @@ solves the problem:
beginfile(FILENAME)
}
- END { endfile(_filename_) }
+ END { endfile(_filename_) }
- *Note Wc Program::, shows how this library function can be used and
+ *note Wc Program::, shows how this library function can be used and
how it simplifies writing the main program.
-Advanced Notes: So Why Does `gawk' have `BEGINFILE' and `ENDFILE'?
-------------------------------------------------------------------
+ So Why Does `gawk' Have `BEGINFILE' and `ENDFILE'?
-You are probably wondering, if `beginfile()' and `endfile()' functions
-can do the job, why does `gawk' have `BEGINFILE' and `ENDFILE' patterns
-(*note BEGINFILE/ENDFILE::)?
+ You are probably wondering, if `beginfile()' and `endfile()'
+functions can do the job, why does `gawk' have `BEGINFILE' and
+`ENDFILE' patterns (*note BEGINFILE/ENDFILE::)?
Good question. Normally, if `awk' cannot open a file, this causes
an immediate fatal error. In this case, there is no way for a
-user-defined function to deal with the problem, since the mechanism for
+user-defined function to deal with the problem, as the mechanism for
calling it relies on the file being open and at the first record. Thus,
the main reason for `BEGINFILE' is to give you a "hook" to catch files
that cannot be processed. `ENDFILE' exists for symmetry, and because
@@ -15109,7 +15320,7 @@ it provides an easy way to do per-file cleanup processing.

File: gawk.info, Node: Rewind Function, Next: File Checking, Prev: Filetrans Function, Up: Data File Management
-12.3.2 Rereading the Current File
+10.3.2 Rereading the Current File
---------------------------------
Another request for a new built-in function was for a `rewind()'
@@ -15140,30 +15351,29 @@ over with it from the top. For lack of a better name, we'll call 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::).
+ The `rewind()' function relies on the `ARGIND' variable (*note
+Auto-set::), which is specific to `gawk'. It also relies on the
+`nextfile' keyword (*note Nextfile Statement::). Because of this, you
+should not call it from an `ENDFILE' rule. (This isn't necessary
+anyway, because `gawk' goes to the next file as soon as an `ENDFILE'
+rule finishes!)

File: gawk.info, Node: File Checking, Next: Empty Files, Prev: Rewind Function, Up: Data File Management
-12.3.3 Checking for Readable Data Files
+10.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:
+such files and keep going.(1) 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] ~ /^[[:alpha:]_][[:alnum:]_]*=.*/ \
+ if (ARGV[i] ~ /^[a-zA-Z_][a-zA-Z0-9_]*=.*/ \
|| ARGV[i] == "-" || ARGV[i] == "/dev/stdin")
continue # assignment or standard input
else if ((getline junk < ARGV[i]) < 0) # unreadable
@@ -15174,13 +15384,23 @@ program to your `awk' program:
}
This works, because the `getline' won't be fatal. Removing the
-element from `ARGV' with `delete' skips the file (since it's no longer
-in the list). See also *Note ARGC and ARGV::.
+element from `ARGV' with `delete' skips the file (because it's no
+longer in the list). See also *note ARGC and ARGV::.
+
+ Because `awk' variable names only allow the English letters, the
+regular expression check purposely does not use character classes such
+as `[:alpha:]' and `[:alnum:]' (*note Bracket Expressions::)
+
+ ---------- Footnotes ----------
+
+ (1) The `BEGINFILE' special pattern (*note BEGINFILE/ENDFILE::)
+provides an alternative mechanism for dealing with files that can't be
+opened. However, the code here provides a portable solution.

File: gawk.info, Node: Empty Files, Next: Ignoring Assigns, Prev: File Checking, Up: Data File Management
-12.3.4 Checking For Zero-length Files
+10.3.4 Checking for Zero-length Files
-------------------------------------
All known `awk' implementations silently skip over zero-length files.
@@ -15193,7 +15413,7 @@ 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
+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:
@@ -15228,21 +15448,15 @@ normal case.
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.
-

File: gawk.info, Node: Ignoring Assigns, Prev: Empty Files, Up: Data File Management
-12.3.5 Treating Assignments as File Names
+10.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 a
-file name that contain an `=' character, `awk' treats the file name as
+file name that contains 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
@@ -15255,7 +15469,7 @@ programming with a library file does the trick:
function disable_assigns(argc, argv, i)
{
for (i = 1; i < argc; i++)
- if (argv[i] ~ /^[[:alpha:]_][[:alnum:]_]*=.*/)
+ if (argv[i] ~ /^[a-zA-Z_][a-zA-Z0-9_]*=.*/)
argv[i] = ("./" argv[i])
}
@@ -15280,14 +15494,14 @@ arguments are left alone.

File: gawk.info, Node: Getopt Function, Next: Passwd Functions, Prev: Data File Management, Up: Library Functions
-12.4 Processing Command-Line Options
+10.4 Processing Command-Line Options
====================================
-Most utilities on POSIX compatible systems take options on the command
+Most utilities on POSIX-compatible systems take options 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
+"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.
@@ -15399,7 +15613,7 @@ characters (*note String Functions::).(1)
# <c> a character representing the current option
# Private Data:
- # _opti -- index in multi-flag option, e.g., -abc
+ # _opti -- index in multiflag option, e.g., -abc
The function starts out with comments presenting a list of the
global variables it uses, what the return values are, what they mean,
@@ -15443,8 +15657,7 @@ not an option, and it ends option processing. Continuing on:
i = index(options, thisopt)
if (i == 0) {
if (Opterr)
- printf("%c -- invalid option\n",
- thisopt) > "/dev/stderr"
+ printf("%c -- invalid option\n", thisopt) > "/dev/stderr"
if (_opti >= length(argv[Optind])) {
Optind++
_opti = 0
@@ -15513,10 +15726,10 @@ next element in `argv'. If neither condition is true, then only
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]':
+`Opterr' is set to one, because the default behavior is for `getopt()'
+to print a diagnostic message upon seeing an invalid option. `Optind'
+is set to one, because there's no reason to look at the program name,
+which is in `ARGV[0]':
BEGIN {
Opterr = 1 # default is to diagnose
@@ -15525,7 +15738,7 @@ is in `ARGV[0]':
# test program
if (_getopt_test) {
while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
- printf("c = <%c>, optarg = <%s>\n",
+ printf("c = <%c>, Optarg = <%s>\n",
_go_c, Optarg)
printf("non-option arguments:\n")
for (; Optind < ARGC; Optind++)
@@ -15538,17 +15751,17 @@ is in `ARGV[0]':
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>
+ -| 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 = <>
+ -| c = <a>, Optarg = <>
error--> x -- invalid option
- -| c = <?>, optarg = <>
+ -| c = <?>, Optarg = <>
-| non-option arguments:
-| ARGV[4] = <xyz>
-| ARGV[5] = <abc>
@@ -15556,24 +15769,28 @@ result of two sample runs of the test program:
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.
- NOTE: After `getopt()' is through, it is the responsibility of the
- user level code 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.
+ NOTE: After `getopt()' is through, user-level code must 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.
+
+ Using `#!' with the `-E' option may help avoid conflicts between
+your program's options and `gawk''s options, as `-E' causes `gawk' to
+abandon processing of further options (*note Executable Scripts::, and
+*note Options::).
- Several of the sample programs presented in *Note Sample Programs::,
+ 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.
+have left it alone, as using `substr()' is more portable.

File: gawk.info, Node: Passwd Functions, Next: Group Functions, Prev: Getopt Function, Up: Library Functions
-12.5 Reading the User Database
+10.5 Reading the User Database
==============================
The `PROCINFO' array (*note Built-in Variables::) provides access to
@@ -15593,7 +15810,7 @@ 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,
+ Although 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
@@ -15607,7 +15824,7 @@ that "cats" the password database:
/*
* pwcat.c
*
- * Generate a printable version of the password database
+ * Generate a printable version of the password database.
*/
#include <stdio.h>
#include <pwd.h>
@@ -15638,13 +15855,13 @@ Encrypted password
systems.
User-ID
- The user's numeric user ID number. (On some systems it's a C
+ The user's numeric user ID number. (On some systems, it's a C
`long', and not an `int'. Thus we cast it to `long' for all
cases.)
Group-ID
The user's numeric group ID number. (Similar comments about
- `long' vs. `int' apply here.)
+ `long' versus `int' apply here.)
Full name
The user's full name, and perhaps other information associated
@@ -15661,7 +15878,7 @@ Login shell
A few lines representative of `pwcat''s output are as follows:
$ pwcat
- -| root:3Ov02d5VaUPB6:0:1:Operator:/:/bin/sh
+ -| root:x:0:1:Operator:/:/bin/sh
-| nobody:*:65534:65534::/:
-| daemon:*:1:1::/:
-| sys:*:2:2::/:/bin/csh
@@ -15718,27 +15935,24 @@ corresponding to the C functions of the same names:
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
+ The function `_pw_init()' fills three copies of the user information
+into 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, since `_pw_init()' needs to be called only once.
+efficiency, as `_pw_init()' needs to be called only 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 `FPAT', or on some other `awk' implementation.
+is in effect or not. Doing so is necessary, as 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. 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 `FPAT',
+or on some other `awk' implementation.
The code that checks for using `FPAT', using `using_fpat' and
-`PROCINFO["FS"]' is similar.
+`PROCINFO["FS"]', is similar.
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
@@ -15758,9 +15972,9 @@ create the element with the null string as its value:
return _pw_byname[name]
}
- 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:
+ 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)
{
@@ -15803,10 +16017,10 @@ simplifies the code but runs an extra process that may never be needed.)
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
-such a change would clutter up the code.
+this is not necessary, as most `awk' programs are I/O-bound, and such a
+change would clutter up the code.
- The `id' program in *Note Id Program::, uses these functions.
+ The `id' program in *note Id Program::, uses these functions.
---------- Footnotes ----------
@@ -15816,10 +16030,10 @@ network database.

File: gawk.info, Node: Group Functions, Next: Walking Arrays, Prev: Passwd Functions, Up: Library Functions
-12.6 Reading the Group Database
+10.6 Reading the Group Database
===============================
-Much of the discussion presented in *Note Passwd Functions::, applies
+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
@@ -15832,7 +16046,7 @@ group database, is as follows:
/*
* grcat.c
*
- * Generate a printable version of the group database
+ * Generate a printable version of the group database.
*/
#include <stdio.h>
#include <grp.h>
@@ -15868,12 +16082,13 @@ Group Password
used; it is usually empty or set to `*'.
Group ID Number
- The group's numeric group ID number; this number must be unique
- within the file. (On some systems it's a C `long', and not an
- `int'. Thus we cast it to `long' for all cases.)
+ The group's numeric group ID number; the association of name to
+ number must be unique within the file. (On some systems it's a C
+ `long', and not an `int'. Thus we cast it to `long' for all
+ cases.)
Group Member List
- A comma-separated list of user names. These users are members of
+ 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
@@ -15897,8 +16112,7 @@ the same names:
# group.awk --- functions for dealing with the group file
- BEGIN \
- {
+ BEGIN {
# Change to suit your system
_gr_awklib = "/usr/local/libexec/awk/"
}
@@ -15931,8 +16145,7 @@ the same names:
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
+ _gr_groupsbyuser[a[i]] = gr_groupsbyuser[a[i]] " " $1
else
_gr_groupsbyuser[a[i]] = $1
@@ -15966,7 +16179,7 @@ used, and to restore the appropriate field splitting mechanism.
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 user name (`_gr_groupsbyuser'), which
+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
@@ -15974,15 +16187,12 @@ 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:johny,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 user names 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'.)
+ID number is already seen. If it is, the usernames are simply
+concatenated onto the previous list of users.(1)
Finally, `_gr_init()' closes the pipeline to `grcat', restores `FS'
(and `FIELDWIDTHS' or `FPAT' if necessary), `RS', and `$0', initializes
@@ -16009,7 +16219,7 @@ looks up the information associated with that group ID:
}
The `getgruser()' function does not have a C counterpart. It takes a
-user name and returns the list of groups that have the user as a member:
+username and returns the list of groups that have the user as a member:
function getgruser(user)
{
@@ -16045,15 +16255,21 @@ body of `_gr_init()' into a `BEGIN' rule).
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.
+ The `id' program in *note Id Program::, uses these functions.
+
+ ---------- Footnotes ----------
+
+ (1) 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'.

-File: gawk.info, Node: Walking Arrays, Prev: Group Functions, Up: Library Functions
+File: gawk.info, Node: Walking Arrays, Next: Library Functions Summary, Prev: Group Functions, Up: Library Functions
-12.7 Traversing Arrays of Arrays
+10.7 Traversing Arrays of Arrays
================================
-*Note Arrays of Arrays::, described how `gawk' provides arrays of
+*note Arrays of Arrays::, described how `gawk' provides arrays of
arrays. In particular, any element of an array may be either a scalar,
or another array. The `isarray()' function (*note Type Functions::)
lets you distinguish an array from a scalar. The following function,
@@ -16091,25 +16307,93 @@ value. Here is a main program to demonstrate:
When run, the program produces the following output:
$ gawk -f walk_array.awk
- -| a[4][1][1] = 411
- -| a[4][2] = 42
-| a[1] = 1
-| a[2][1] = 21
-| a[2][2] = 22
-| a[3] = 3
+ -| a[4][1][1] = 411
+ -| a[4][2] = 42
+
+
+File: gawk.info, Node: Library Functions Summary, Next: Library Exercises, Prev: Walking Arrays, Up: Library Functions
+
+10.8 Summary
+============
+
+ * Reading programs is an excellent way to learn Good Programming.
+ The functions and programs provided in this major node and the next
+ are intended to serve that purpose.
+
+ * When writing general-purpose library functions, put some thought
+ into how to name any global variables so that they won't conflict
+ with variables from a user's program.
+
+ * The functions presented here fit into the following categories:
+
+ General problems
+ Number-to-string conversion, assertions, rounding, random
+ number generation, converting characters to numbers, joining
+ strings, getting easily usable time-of-day information, and
+ reading a whole file in one shot.
+
+ Managing data files
+ Noting data file boundaries, rereading the current file,
+ checking for readable files, checking for zero-length files,
+ and treating assignments as file names.
+
+ Processing command-line options
+ An `awk' version of the standard C `getopt()' function.
+
+ Reading the user and group databases
+ Two sets of routines that parallel the C library versions.
+
+ Traversing arrays of arrays
+ A simple function to traverse an array of arrays to any depth.
+
+
+
+File: gawk.info, Node: Library Exercises, Prev: Library Functions Summary, Up: Library Functions
+
+10.9 Exercises
+==============
+
+ 1. In *note Empty Files::, we presented the `zerofile.awk' program,
+ which made use of `gawk''s `ARGIND' variable. Can this problem be
+ solved without relying on `ARGIND'? If so, how?
+
+ 2. As a related challenge, revise that code to handle the case where
+ an intervening value in `ARGV' is a variable assignment.
+
+ 3. *note Walking Arrays::, presented a function that walked a
+ multidimensional array to print it out. However, walking an array
+ and processing each element is a general-purpose operation.
+ Generalize the `walk_array()' function by adding an additional
+ parameter named `process'.
+
+ Then, inside the loop, instead of printing the array element's
+ index and value, use the indirect function call syntax (*note
+ Indirect Calls::) on `process', passing it the index and the value.
+
+ When calling `walk_array()', you would pass the name of a
+ user-defined function that expects to receive an index and a value,
+ and then processes the element.
+
+ Test your new version by printing the array; you should end up with
+ output identical to that of the original version.
+

-File: gawk.info, Node: Sample Programs, Next: Debugger, Prev: Library Functions, Up: Top
+File: gawk.info, Node: Sample Programs, Next: Advanced Features, Prev: Library Functions, Up: Top
-13 Practical `awk' Programs
+11 Practical `awk' Programs
***************************
-*Note Library Functions::, presents the idea that reading programs in a
+*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 library functions presented in *Note
+ Many of these programs use library functions presented in *note
Library Functions::.
* Menu:
@@ -16117,11 +16401,13 @@ Library Functions::.
* Running Examples:: How to run these examples.
* Clones:: Clones of common utilities.
* Miscellaneous Programs:: Some interesting `awk' programs.
+* Programs Summary:: Summary of programs.
+* Programs Exercises:: Exercises.

File: gawk.info, Node: Running Examples, Next: Clones, Up: Sample Programs
-13.1 Running the Example Programs
+11.1 Running the Example Programs
=================================
To run a given program, you would typically do something like this:
@@ -16144,7 +16430,7 @@ OPTIONS are any command-line options for the program that start with a

File: gawk.info, Node: Clones, Next: Miscellaneous Programs, Prev: Running Examples, Up: Sample Programs
-13.2 Reinventing Wheels for Fun and Profit
+11.2 Reinventing Wheels for Fun and Profit
==========================================
This minor node presents a number of POSIX utilities implemented in
@@ -16174,7 +16460,7 @@ programming for "real world" tasks.

File: gawk.info, Node: Cut Program, Next: Egrep Program, Up: Clones
-13.2.1 Cutting out Fields and Columns
+11.2.1 Cutting Out Fields and Columns
-------------------------------------
The `cut' utility selects, or "cuts," characters or fields from its
@@ -16227,18 +16513,13 @@ supplied:
#
# Requires getopt() and join() library functions
- function usage( e1, e2)
+ function usage()
{
- e1 = "usage: cut [-f list] [-d c] [-s] [files...]"
- e2 = "usage: cut [-c list] [files...]"
- print e1 > "/dev/stderr"
- print e2 > "/dev/stderr"
+ print("usage: cut [-f list] [-d c] [-s] [files...]") > "/dev/stderr"
+ print("usage: cut [-c list] [files...]") > "/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 rule then sets the output field separator to be the
@@ -16248,8 +16529,7 @@ through the command-line options. Exactly one of the variables
should be done by fields or by characters, respectively. When cutting
by characters, the output field separator is set to the null string:
- BEGIN \
- {
+ BEGIN {
FS = "\t" # default
OFS = FS
while ((c = getopt(ARGC, ARGV, "sf:c:d:")) != -1) {
@@ -16262,7 +16542,7 @@ by characters, the output field separator is set to the null string:
OFS = ""
} else if (c == "d") {
if (length(Optarg) > 1) {
- printf("Using first character of %s" \
+ printf("cut: using first character of %s" \
" for delimiter\n", Optarg) > "/dev/stderr"
Optarg = substr(Optarg, 1, 1)
}
@@ -16271,7 +16551,7 @@ by characters, the output field separator is set to the null string:
if (FS == " ") # defeat awk semantics
FS = "[ ]"
} else if (c == "s")
- suppress++
+ suppress = 1
else
usage()
}
@@ -16284,7 +16564,7 @@ by characters, the output field separator is set to the null string:
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 remember
-that after `getopt()' is through (as described in *Note Getopt
+that after `getopt()' is through (as described in *note Getopt
Function::), 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.
@@ -16329,7 +16609,7 @@ splitting:
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",
+ printf("cut: bad field list: %s\n",
f[i]) > "/dev/stderr"
exit 1
}
@@ -16357,7 +16637,7 @@ fields to print are `$1', `$3', and `$5'. The intermediate fields are
the fields to print, and `t' tracks the complete field list, including
filler fields:
- function set_charlist( field, i, j, f, g, t,
+ function set_charlist( field, i, j, f, g, n, m, t,
filler, last, len)
{
field = 1 # count total fields
@@ -16367,7 +16647,7 @@ filler fields:
if (index(f[i], "-") != 0) { # range
m = split(f[i], g, "-")
if (m != 2 || g[1] >= g[2]) {
- printf("bad character list: %s\n",
+ printf("cut: bad character list: %s\n",
f[i]) > "/dev/stderr"
exit 1
}
@@ -16397,10 +16677,10 @@ filler fields:
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
+ Next is the rule that 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,
@@ -16411,7 +16691,7 @@ the next field also has data, then the separator character is written
out between the fields:
{
- if (by_fields && suppress && index($0, FS) != 0)
+ if (by_fields && suppress && index($0, FS) == 0)
next
for (i = 1; i <= nfields; i++) {
@@ -16425,22 +16705,22 @@ out between the fields:
}
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
+do the character-based cutting. It is possible in other `awk'
+implementations to use `substr()' (*note String Functions::), but it is
also extremely painful. The `FIELDWIDTHS' variable supplies an elegant
solution to the problem of picking the input line apart by characters.

File: gawk.info, Node: Egrep Program, Next: Id Program, Prev: Cut Program, Up: Clones
-13.2.2 Searching for Regular Expressions in Files
+11.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::). You invoke it as follows:
- egrep [ OPTIONS ] 'PATTERN' FILES ...
+ `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
@@ -16482,7 +16762,7 @@ 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::):
+`IGNORECASE' predefined variable (*note Built-in Variables::):
# egrep.awk --- simulate egrep in awk
#
@@ -16537,14 +16817,14 @@ the matched lines in the output:
# pattern = tolower(pattern)
}
- The last two lines are commented out, since they are not needed in
+ The last two lines are commented out, as 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':
+as it is not necessary with `gawk':
#{
# if (IGNORECASE)
@@ -16584,6 +16864,11 @@ know the total number of lines that matched the pattern:
total += fcount
}
+ The `BEGINFILE' and `ENDFILE' special patterns (*note
+BEGINFILE/ENDFILE::) could be used, but then the program would be
+`gawk'-specific. Additionally, this example was written before `gawk'
+acquired `BEGINFILE' and `ENDFILE'.
+
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
@@ -16629,34 +16914,20 @@ line is printed, with a leading file name and colon if necessary:
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
+ END {
+ exit (total == 0)
}
The `usage()' function prints a usage message in case of invalid
options, and then exits:
- function usage( e)
+ function usage()
{
- e = "Usage: egrep [-csvil] [-e pat] [files ...]"
- e = e "\n\tegrep [-csvil] pat [files ...]"
- print e > "/dev/stderr"
+ print("Usage: egrep [-csvil] [-e pat] [files ...]") > "/dev/stderr"
+ print("\n\tegrep [-csvil] pat [files ...]") > "/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
@@ -16665,7 +16936,7 @@ the translated line, not the original.

File: gawk.info, Node: Id Program, Next: Split Program, Prev: Egrep Program, Up: Clones
-13.2.3 Printing out User Information
+11.2.3 Printing Out User Information
------------------------------------
The `id' utility lists a user's real and effective user ID numbers,
@@ -16675,7 +16946,7 @@ different from the real ones. If possible, `id' also supplies the
corresponding user and group names. The output might look like this:
$ id
- -| uid=500(arnold) gid=500(arnold) groups=6(disk),7(lp),19(floppy)
+ -| uid=1000(arnold) gid=1000(arnold) groups=1000(arnold),4(adm),7(lp),27(sudo)
This information is part of what is provided by `gawk''s `PROCINFO'
array (*note Built-in Variables::). However, the `id' utility provides
@@ -16699,8 +16970,7 @@ and the group numbers:
# uid=12(foo) euid=34(bar) gid=3(baz) \
# egid=5(blat) groups=9(nine),2(two),1(one)
- BEGIN \
- {
+ BEGIN {
uid = PROCINFO["uid"]
euid = PROCINFO["euid"]
gid = PROCINFO["gid"]
@@ -16708,34 +16978,22 @@ and the group numbers:
printf("uid=%d", uid)
pw = getpwuid(uid)
- if (pw != "") {
- split(pw, a, ":")
- printf("(%s)", a[1])
- }
+ pr_first_field(pw)
if (euid != uid) {
printf(" euid=%d", euid)
pw = getpwuid(euid)
- if (pw != "") {
- split(pw, a, ":")
- printf("(%s)", a[1])
- }
+ pr_first_field(pw)
}
printf(" gid=%d", gid)
pw = getgrgid(gid)
- if (pw != "") {
- split(pw, a, ":")
- printf("(%s)", a[1])
- }
+ pr_first_field(pw)
if (egid != gid) {
printf(" egid=%d", egid)
pw = getgrgid(egid)
- if (pw != "") {
- split(pw, a, ":")
- printf("(%s)", a[1])
- }
+ pr_first_field(pw)
}
for (i = 1; ("group" i) in PROCINFO; i++) {
@@ -16744,10 +17002,7 @@ and the group numbers:
group = PROCINFO["group" i]
printf("%d", group)
pw = getgrgid(group)
- if (pw != "") {
- split(pw, a, ":")
- printf("(%s)", a[1])
- }
+ pr_first_field(pw)
if (("group" (i+1)) in PROCINFO)
printf(",")
}
@@ -16755,41 +17010,54 @@ and the group numbers:
print ""
}
+ function pr_first_field(str, a)
+ {
+ if (str != "") {
+ split(str, a, ":")
+ printf("(%s)", a[1])
+ }
+ }
+
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.
+`"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.
+`"group"', and then using `in' to see if that value is in the array
+(*note Reference to Elements::). 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.
+ The `pr_first_field()' function simply isolates out some code that
+is used repeatedly, making the whole program shorter and cleaner. In
+particular, moving the check for the empty string into this function
+saves several lines of code.
+

File: gawk.info, Node: Split Program, Next: Tee Program, Prev: Id Program, Up: Clones
-13.2.4 Splitting a Large File into Pieces
+11.2.4 Splitting a Large File into Pieces
-----------------------------------------
The `split' program splits large text files into smaller pieces. Usage
is as follows:(1)
- split [-COUNT] file [ PREFIX ]
+ `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.
+file has 1,000 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
+command line preceded with a minus (e.g., `-500' for files with 500
+lines in them instead of 1,000). 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::.
+`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
@@ -16802,7 +17070,7 @@ output file names:
# split.awk --- do split in awk
#
# Requires ord() and chr() library functions
- # usage: split [-num] [file] [outname]
+ # usage: split [-count] [file] [outname]
BEGIN {
outfile = "x" # default
@@ -16811,14 +17079,14 @@ output file names:
usage()
i = 1
- if (ARGV[i] ~ /^-[[:digit:]]+$/) {
+ if (i in ARGV && ARGV[i] ~ /^-[[:digit:]]+$/) {
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
+ i++ # skip datafile name
if (i in ARGV) {
outfile = ARGV[i]
ARGV[i] = ""
@@ -16858,15 +17126,12 @@ moves to the next letter in the alphabet and `s2' starts over again at
The `usage()' function simply prints an error message and exits:
- function usage( e)
+ function usage()
{
- e = "usage: split [-num] [file] [outname]"
- print e > "/dev/stderr"
+ print("usage: split [-num] [file] [outname]") > "/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
@@ -16880,21 +17145,21 @@ not relevant for what the program aims to demonstrate.

File: gawk.info, Node: Tee Program, Next: Uniq Program, Prev: Split Program, Up: Clones
-13.2.5 Duplicating Output into Multiple Files
+11.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 ...
+ `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
+into an array named `copy'. `ARGV[0]' is not needed, so it is not
+copied. `tee' cannot use `ARGV' directly, because `awk' attempts to
process each file name in `ARGV' as input data.
If the first argument is `-a', then the flag variable `append' is
@@ -16908,8 +17173,7 @@ input by setting `ARGV[1]' to `"-"' and `ARGC' to two:
# Copy standard input to all named output files.
# Append content if -a option is supplied.
#
- BEGIN \
- {
+ BEGIN {
for (i = 1; i < ARGC; i++)
copy[i] = ARGV[i]
@@ -16927,7 +17191,7 @@ input by setting `ARGV[1]' to `"-"' and `ARGC' to two:
ARGC = 2
}
- The following single rule does all the work. Since there is no
+ The following single rule does all the work. Because 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:
@@ -16951,16 +17215,16 @@ It is also possible to write the loop this way:
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.
+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 \
- {
+ END {
for (i in copy)
close(copy[i])
}
@@ -16968,7 +17232,7 @@ N input records and M output files, the first method only executes N

File: gawk.info, Node: Uniq Program, Next: Wc Program, Prev: Tee Program, Up: Clones
-13.2.6 Printing Nonduplicated Lines of Text
+11.2.6 Printing Nonduplicated Lines of Text
-------------------------------------------
The `uniq' utility reads sorted lines of data on its standard input,
@@ -16976,15 +17240,15 @@ 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 ]]
+ `uniq' [`-udc' [`-N']] [`+N'] [INPUTFILE [OUTPUTFILE]]
The options for `uniq' are:
`-d'
- Print only repeated lines.
+ Print only repeated (duplicated) lines.
`-u'
- Print only nonrepeated lines.
+ Print only nonrepeated (unique) lines.
`-c'
Count lines. This option overrides `-d' and `-u'. Both repeated
@@ -16999,11 +17263,11 @@ usage is as follows:
Skip N characters before comparing lines. Any fields specified
with `-N' are skipped first.
-`INPUT FILE'
+`INPUTFILE'
Data is read from the input file named on the command line,
instead of from the standard input.
-`OUTPUT FILE'
+`OUTPUTFILE'
The generated output is sent to the named output file, instead of
to the standard output.
@@ -17034,10 +17298,9 @@ standard output, `/dev/stdout':
#
# Requires getopt() and join() library functions
- function usage( e)
+ function usage()
{
- e = "Usage: uniq [-udc [-n]] [+n] [ in [ out ]]"
- print e > "/dev/stderr"
+ print("Usage: uniq [-udc [-n]] [+n] [ in [ out ]]") > "/dev/stderr"
exit 1
}
@@ -17047,8 +17310,7 @@ standard output, `/dev/stdout':
# -n skip n fields
# +n skip n characters, skip fields first
- BEGIN \
- {
+ BEGIN {
count = 1
outputfile = "/dev/stdout"
opts = "udc0:1:2:3:4:5:6:7:8:9:"
@@ -17060,7 +17322,7 @@ standard output, `/dev/stdout':
else if (c == "c")
do_count++
else if (index("0123456789", c) != 0) {
- # getopt requires args to options
+ # getopt() requires args to options
# this messes us up for things like -5
if (Optarg ~ /^[[:digit:]]+$/)
fcount = (c Optarg) + 0
@@ -17092,16 +17354,18 @@ standard output, `/dev/stdout':
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:
+`are_equal()' 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)
{
@@ -17134,13 +17398,13 @@ to.
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.
+because 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.
+incremented. Nothing is printed, as 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:
@@ -17187,18 +17451,18 @@ line of input data:

File: gawk.info, Node: Wc Program, Prev: Uniq Program, Up: Clones
-13.2.7 Counting Things
+11.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 ... ]
+ `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:
+counts for all the files. The options and their meanings are as
+follows:
`-l'
Count only lines.
@@ -17212,10 +17476,10 @@ the following list:
`-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.
+ Implementing `wc' in `awk' is particularly elegant, because `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 program uses the `getopt()' library function (*note Getopt
Function::) and the file-transition functions (*note Filetrans
@@ -17273,7 +17537,7 @@ lines, words, and characters to zero, and saves the current file name in
}
The `endfile()' function adds the current file's numbers to the
-running totals of lines, words, and characters.(1) It then prints out
+running totals of lines, words, and characters. 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:
@@ -17292,7 +17556,7 @@ those numbers for the file that was just read. It relies on
}
There is one rule that is executed for each line. It adds the length
-of the record, plus one, to `chars'.(2) Adding one plus the record
+of the record, plus one, to `chars'.(1) 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
@@ -17322,17 +17586,13 @@ in its length. Next, `lines' is incremented for each line read, and
---------- 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.
-
- (2) Since `gawk' understands multibyte locales, this code counts
+ (1) Because `gawk' understands multibyte locales, this code counts
characters, not bytes.

-File: gawk.info, Node: Miscellaneous Programs, Prev: Clones, Up: Sample Programs
+File: gawk.info, Node: Miscellaneous Programs, Next: Programs Summary, Prev: Clones, Up: Sample Programs
-13.3 A Grab Bag of `awk' Programs
+11.3 A Grab Bag of `awk' Programs
=================================
This minor node is a large "grab bag" of miscellaneous programs. We
@@ -17359,7 +17619,7 @@ hope you find them both interesting and enjoyable.

File: gawk.info, Node: Dupword Program, Next: Alarm Program, Up: Miscellaneous Programs
-13.3.1 Finding Duplicated Words in a Document
+11.3.1 Finding Duplicated Words in a Document
---------------------------------------------
A common error when writing large amounts of prose is to accidentally
@@ -17407,11 +17667,13 @@ word, comparing it to the previous one:

File: gawk.info, Node: Alarm Program, Next: Translate Program, Prev: Dupword Program, Up: Miscellaneous Programs
-13.3.2 An Alarm Clock Program
+11.3.2 An Alarm Clock Program
-----------------------------
- Nothing cures insomnia like a ringing alarm clock.
- Arnold Robbins
+ Nothing cures insomnia like a ringing alarm clock. -- Arnold
+ Robbins
+
+ Sleep is for web developers. -- Erik Quanstrom
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
@@ -17419,8 +17681,8 @@ 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::.
+ This program uses the `getlocaltime()' function from *note
+Getlocaltime 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
@@ -17435,11 +17697,10 @@ Statement::), but the processing could be done with a series of
# alarm.awk --- set an alarm
#
- # Requires gettimeofday() library function
+ # Requires getlocaltime() library function
# usage: alarm time [ "message" [ count [ delay ] ] ]
- BEGIN \
- {
+ BEGIN {
# Initial argument sanity checking
usage1 = "usage: alarm time ['message' [count [delay]]]"
usage2 = sprintf("\t(%s) time ::= hh:mm", ARGV[1])
@@ -17491,7 +17752,7 @@ alarm:
minute = atime[2] + 0 # force numeric
# get current broken down time
- gettimeofday(now)
+ getlocaltime(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.,
@@ -17509,7 +17770,7 @@ alarm:
# how long to sleep for
naptime = target - current
if (naptime <= 0) {
- print "time is in the past!" > "/dev/stderr"
+ print "alarm: time is in the past!" > "/dev/stderr"
exit 1
}
@@ -17540,7 +17801,7 @@ necessary:

File: gawk.info, Node: Translate Program, Next: Labels Program, Prev: Alarm Program, Up: Miscellaneous Programs
-13.3.3 Transliterating Characters
+11.3.3 Transliterating Characters
---------------------------------
The system `tr' utility transliterates characters. For example, it is
@@ -17557,17 +17818,17 @@ 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.
+ Once upon a time, a user proposed adding a transliteration function
+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:
+ The `translate' program was written long before `gawk' acquired the
+ability to split each character in a string into separate array
+elements. Thus, it makes repeated use of the `substr()', `index()',
+and `gsub()' built-in functions (*note String Functions::). There are
+two functions. The first, `stranslate()', takes three arguments:
`from'
A list of characters from which to translate.
@@ -17584,10 +17845,10 @@ simple loop goes through `from', one character at a time. For each
character in `from', if the character appears in `target', it is
replaced with 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.
+ The `translate()' function 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:
@@ -17639,34 +17900,36 @@ record:
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.
+ It is possible to do character transliteration in a user-level
+function, but it is not necessarily efficient, and we (the `gawk'
+developers) started to consider adding a built-in function. However,
+shortly after writing this program, we learned that Brian Kernighan had
+added the `toupper()' and `tolower()' functions to his `awk' (*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 ----------
+ Another obvious improvement is to enable the use of ranges, such as
+`a-z', as allowed by the `tr' utility. Look at the code for `cut.awk'
+(*note Cut Program::) for inspiration.
- (1) On some older 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.
+ ---------- Footnotes ----------
- (2) This program was written before `gawk' acquired the ability to
-split each character in a string into separate array elements.
+ (1) On some older systems, including Solaris, the system version of
+`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.

File: gawk.info, Node: Labels Program, Next: Word Sorting, Prev: Translate Program, Up: Miscellaneous Programs
-13.3.4 Printing Mailing Labels
+11.3.4 Printing Mailing Labels
------------------------------
Here is a "real world"(1) program. This script reads lists of names and
@@ -17682,18 +17945,18 @@ 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, because 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[7]', and so on. Two loops 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
@@ -17760,8 +18023,7 @@ not have been an even multiple of 20 labels in the data:
Count++
}
- END \
- {
+ END {
printpage()
}
@@ -17773,19 +18035,19 @@ something done."

File: gawk.info, Node: Word Sorting, Next: History Sorting, Prev: Labels Program, Up: Miscellaneous Programs
-13.3.5 Generating Word-Usage Counts
+11.3.5 Generating Word-Usage Counts
-----------------------------------
When working with large amounts of text, it can be interesting to know
how often different words appear. For example, an author may overuse
-certain words, in which case she might wish to find synonyms to
+certain words, in which case he or she might wish to find synonyms to
substitute for words that appear too often. This node develops a
program for counting words and presenting the frequency information in
a useful format.
At first glance, a program like this would seem to do the job:
- # Print list of word frequencies
+ # wordfreq-first-try.awk --- print list of word frequencies
{
for (i = 1; i <= NF; i++)
@@ -17807,9 +18069,9 @@ on real text files:
* 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.
+ as the same word. This is undesirable, because words are
+ capitalized if they begin sentences in normal text, and a
+ frequency analyzer should not be sensitive to capitalization.
* Words are detected using the `awk' convention that fields are
separated just by whitespace. Other characters in the input
@@ -17841,6 +18103,10 @@ script. Here is the new version of the program:
printf "%s\t%d\n", word, freq[word]
}
+ The regexp `/[^[:alnum:]_[:blank:]]/' might have been written
+`/[[:punct:]]/', but then underscores would also be removed, and we
+want to keep them.
+
Assuming we have saved this program in a file named `wordfreq.awk',
and that the data is in `file1', the following pipeline:
@@ -17877,7 +18143,7 @@ operating system documentation for more information on how to use the

File: gawk.info, Node: History Sorting, Next: Extract Program, Prev: Word Sorting, Up: Miscellaneous Programs
-13.3.6 Removing Duplicates from Unsorted Text
+11.3.6 Removing Duplicates from Unsorted Text
---------------------------------------------
The `uniq' program (*note Uniq Program::), removes duplicate lines from
@@ -17918,26 +18184,26 @@ information. For example, using the following `print' statement in the
print data[lines[i]], lines[i]
- This works because `data[$0]' is incremented each time a line is
-seen.
+This works because `data[$0]' is incremented each time a line is seen.

File: gawk.info, Node: Extract Program, Next: Simple Sed, Prev: History Sorting, Up: Miscellaneous Programs
-13.3.7 Extracting Programs from Texinfo Source Files
+11.3.7 Extracting Programs from Texinfo Source Files
----------------------------------------------------
-The nodes *Note Library Functions::, and *Note Sample Programs::, are
+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.
+to experiment with these programs, it is tedious 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 (http://texinfo.org), 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 (Texinfo)Top::
-texinfo,Texinfo--The GNU Documentation Format.
+This Info file is written in Texinfo
+(http://www.gnu.org/software/texinfo/), the GNU project's document
+formatting language. A single Texinfo source file can be used to
+produce both printed documentation, with TeX, and online documentation.
+(The Texinfo language is described fully, starting with *note
+(Texinfo)Top:: texinfo,Texinfo--The GNU Documentation Format.)
For our purposes, it is enough to know three things about Texinfo
input files:
@@ -17967,11 +18233,11 @@ 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:
+Effective AWK Programming' (`gawktexi.in') 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,
@@ -17987,7 +18253,7 @@ looks something like this:
@example
@c file examples/messages.awk
- END @{ print "Always avoid bored archeologists!" @}
+ END @{ print "Always avoid bored archaeologists!" @}
@c end file
@end example
...
@@ -17999,15 +18265,13 @@ upper- and lowercase letters in the directives won't matter.
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
+ # extract.awk --- extract files and run programs from texinfo files
BEGIN { IGNORECASE = 1 }
- /^@c(omment)?[ \t]+system/ \
- {
+ /^@c(omment)?[ \t]+system/ {
if (NF < 3) {
- e = (FILENAME ":" FNR)
+ e = ("extract: " FILENAME ":" FNR)
e = (e ": badly formed `system' line")
print e > "/dev/stderr"
next
@@ -18016,7 +18280,7 @@ with a zero exit status, signifying OK:
$2 = ""
stat = system($0)
if (stat != 0) {
- e = (FILENAME ":" FNR)
+ e = ("extract: " FILENAME ":" FNR)
e = (e ": warning: system returned " stat)
print e > "/dev/stderr"
}
@@ -18046,16 +18310,16 @@ 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.(1)
+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:
+with the value of `SUBSEP' (*note Multidimensional::), to rejoin the
+pieces back into a single line. That line is then printed to the
+output file:
- /^@c(omment)?[ \t]+file/ \
- {
+ /^@c(omment)?[ \t]+file/ {
if (NF != 3) {
- e = (FILENAME ":" FNR ": badly formed `file' line")
+ e = ("extract: " FILENAME ":" FNR ": badly formed `file' line")
print e > "/dev/stderr"
next
}
@@ -18106,8 +18370,8 @@ closing the open file:
function unexpected_eof()
{
- printf("%s:%d: unexpected EOF or error\n",
- FILENAME, FNR) > "/dev/stderr"
+ printf("extract: %s:%d: unexpected EOF or error\n",
+ FILENAME, FNR) > "/dev/stderr"
exit 1
}
@@ -18116,29 +18380,24 @@ closing the open file:
close(curfile)
}
- ---------- Footnotes ----------
-
- (1) This program was written before `gawk' had the `gensub()'
-function. Consider how you might use it to simplify the code.
-

File: gawk.info, Node: Simple Sed, Next: Igawk Program, Prev: Extract Program, Up: Miscellaneous Programs
-13.3.8 A Simple Stream Editor
+11.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:
+pipeline of commands. Although `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
+ 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
+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
@@ -18199,16 +18458,16 @@ arguments and calling `usage()' if there is a problem. Then it sets
(*note ARGC and ARGV::).
The `usage()' function prints an error message and exits. Finally,
-the single rule handles the printing scheme outlined above, using
+the single rule handles the printing scheme outlined earlier, using
`print' or `printf' as appropriate, depending upon the value of `RT'.

File: gawk.info, Node: Igawk Program, Next: Anagram Program, Prev: Simple Sed, Up: Miscellaneous Programs
-13.3.9 An Easy Way to Use Library Functions
+11.3.9 An Easy Way to Use Library Functions
-------------------------------------------
-In *Note Include Files::, we saw how `gawk' provides a built-in
+In *note Include Files::, we saw how `gawk' provides a built-in
file-inclusion capability. However, this is a `gawk' extension. This
minor node provides the motivation for making file inclusion available
for standard `awk', and shows how to do it using a combination of shell
@@ -18237,10 +18496,10 @@ to be able to write programs in the following manner:
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.
+"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
@@ -18256,13 +18515,13 @@ language.(1) It works as follows:
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.
+ a. Literal text, provided with `-e' 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
+ contents. Because the file-inclusion program works the way
+ `gawk' does, this gets the text of the file included in the
program at the correct point.
3. Run an `awk' program (naturally) over the shell variable's
@@ -18297,10 +18556,10 @@ are several cases of interest:
programming trick. Don't worry about it if you are not familiar
with `sh'.)
-`-v, -F'
+`-v', `-F'
These are saved and passed on to `gawk'.
-`-f, --file, --file=, -Wfile='
+`-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
@@ -18309,10 +18568,10 @@ are several cases of interest:
sequences in their arguments, possibly mangling the program text.
Using `expr' avoids this problem.)
-`--source, --source=, -Wsource='
+`--source', `--source=', `-Wsource='
The source text is appended to `program'.
-`--version, -Wversion'
+`--version', `-Wversion'
`igawk' prints its version number, runs `gawk --version' to get
the `gawk' version information, and then exits.
@@ -18321,8 +18580,8 @@ 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.
+processed, the shell variable `program' contains the complete text of
+the original `awk' program.
The program is as follows:
@@ -18458,12 +18717,12 @@ which represents the current directory:
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 the program
-prints an error message and continues.
+ 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 the program prints an error message and continues.
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
@@ -18486,7 +18745,7 @@ zero, the program is done:
}
fpath = pathto($2)
if (fpath == "") {
- printf("igawk:%s:%d: cannot find %s\n",
+ printf("igawk: %s:%d: cannot find %s\n",
input[stackptr], FNR, $2) > "/dev/stderr"
continue
}
@@ -18522,13 +18781,13 @@ is saved as a single string, even if the results contain whitespace.
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.
+ the `expand_prog' shell variable) reading 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.
+ shell variable `program'. Feed its contents to `gawk' via a here
+ document.
- 3. The results of this processing are saved in the shell variable
+ 3. Save the results of this processing in the shell variable
`processed_program' by using command substitution.
The last step is to call `gawk' with the expanded program, along
@@ -18540,7 +18799,7 @@ supplied.
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 fifth version of this program.
+ This version of `igawk' represents the fifth version of this program.
There are four key simplifications that make the program work better:
* Using `@include' even for the files named with `-f' makes building
@@ -18568,27 +18827,7 @@ 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.
-
- 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.
+features to a program; they can often be layered on top.(3)
---------- Footnotes ----------
@@ -18597,29 +18836,31 @@ 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.
+can loop forever if the file exists but is empty.
+
+ (3) `gawk' does `@include' processing itself in order to support the
+use of `awk' programs as Web CGI scripts.

File: gawk.info, Node: Anagram Program, Next: Signature Program, Prev: Igawk Program, Up: Miscellaneous Programs
-13.3.10 Finding Anagrams From A Dictionary
+11.3.10 Finding Anagrams from a Dictionary
------------------------------------------
An interesting programming challenge is to search for "anagrams" in a
word list (such as `/usr/share/dict/words' on many GNU/Linux systems).
One word is an anagram of another if both words contain the same letters
-(for example, "babbling" and "blabbing").
+(e.g., "babbling" and "blabbing").
- An elegant algorithm is presented in Column 2, Problem C of Jon
-Bentley's `Programming Pearls', second edition. The idea is to give
-words that are anagrams a common signature, sort all the words together
-by their signature, and then print them. Dr. Bentley observes that
-taking the letters in each word and sorting them produces that common
-signature.
+ Column 2, Problem C, of Jon Bentley's `Programming Pearls', Second
+Edition, presents an elegant algorithm. The idea is to give words that
+are anagrams a common signature, sort all the words together by their
+signature, and then print them. Dr. Bentley observes that taking the
+letters in each word and sorting them produces that common signature.
The following program uses arrays of arrays to bring together words
with the same signature and array sorting to print the words in sorted
-order.
+order:
# anagram.awk --- An implementation of the anagram finding algorithm
# from Jon Bentley's "Programming Pearls", 2nd edition.
@@ -18656,8 +18897,8 @@ back together:
}
Finally, the `END' rule traverses the array and prints out the
-anagram lists. It sends the output to the system `sort' command, since
-otherwise the anagrams would appear in arbitrary order:
+anagram lists. It sends the output to the system `sort' command
+because otherwise the anagrams would appear in arbitrary order:
END {
sort = "sort"
@@ -18692,7 +18933,7 @@ otherwise the anagrams would appear in arbitrary order:

File: gawk.info, Node: Signature Program, Prev: Anagram Program, Up: Miscellaneous Programs
-13.3.11 And Now For Something Completely Different
+11.3.11 And Now for Something Completely Different
--------------------------------------------------
The following program was written by Davide Brini and is published on
@@ -18714,59 +18955,1753 @@ supplies the following copyright terms:
X*(X-x)-o*o,(x+X)*o*o+o,x*(X-x)-O-O,x-O+(O+o+X+x)*(o+O),X*X-X*(x-O)-x+O,
O+X*(o*(o+O)+O),+x+O+X*o,x*(x-o),(o+X+x)*o*o-(x-O-O),O+(X-x)*(X+O),x-O}'
- We leave it to you to determine what the program does.
+ We leave it to you to determine what the program does. (If you are
+truly desperate to understand it, see Chris Johansen's explanation,
+which is embedded in the Texinfo source file for this Info file.)
+
+
+File: gawk.info, Node: Programs Summary, Next: Programs Exercises, Prev: Miscellaneous Programs, Up: Sample Programs
+
+11.4 Summary
+============
+
+ * The programs provided in this major node continue on the theme
+ that reading programs is an excellent way to learn Good
+ Programming.
+
+ * Using `#!' to make `awk' programs directly runnable makes them
+ easier to use. Otherwise, invoke the program using `awk -f ...'.
+
+ * Reimplementing standard POSIX programs in `awk' is a pleasant
+ exercise; `awk''s expressive power lets you write such programs in
+ relatively few lines of code, yet they are functionally complete
+ and usable.
+
+ * One of standard `awk''s weaknesses is working with individual
+ characters. The ability to use `split()' with the empty string as
+ the separator can considerably simplify such tasks.
+
+ * The library functions from *note Library Functions::, proved their
+ usefulness for a number of real (if small) programs.
+
+ * Besides reinventing POSIX wheels, other programs solved a
+ selection of interesting problems, such as finding duplicates
+ words in text, printing mailing labels, and finding anagrams.
+
+
+
+File: gawk.info, Node: Programs Exercises, Prev: Programs Summary, Up: Sample Programs
+
+11.5 Exercises
+==============
+
+ 1. Rewrite `cut.awk' (*note Cut Program::) using `split()' with `""'
+ as the separator.
+
+ 2. In *note Egrep Program::, we mentioned that `egrep -i' could be
+ simulated in versions of `awk' without `IGNORECASE' by using
+ `tolower()' on the line and the pattern. In a footnote there, we
+ also mentioned that this solution has a bug: the translated line is
+ output, and not the original one. Fix this problem.
+
+ 3. The POSIX version of `id' takes options that control which
+ information is printed. Modify the `awk' version (*note Id
+ Program::) to accept the same arguments and perform in the same
+ way.
+
+ 4. The `split.awk' program (*note Split Program::) assumes that
+ letters are contiguous in the character set, which isn't true for
+ EBCDIC systems. Fix this problem. (Hint: Consider a different
+ way to work through the alphabet, without relying on `ord()' and
+ `chr()'.)
+
+ 5. In `uniq.awk' (*note Uniq Program::, the logic for choosing which
+ lines to print represents a "state machine", which is "a device
+ that can be in one of a set number of stable conditions depending
+ on its previous condition and on the present values of its
+ inputs."(1) Brian Kernighan suggests that "an alternative approach
+ to state machines is to just read the input into an array, then
+ use indexing. It's almost always easier code, and for most inputs
+ where you would use this, just as fast." Rewrite the logic to
+ follow this suggestion.
+
+ 6. Why can't the `wc.awk' program (*note Wc Program::) just use the
+ value of `FNR' in `endfile()'? Hint: Examine the code in *note
+ Filetrans Function::.
+
+ 7. Manipulation of individual characters in the `translate' program
+ (*note Translate Program::) is painful using standard `awk'
+ functions. Given that `gawk' can split strings into individual
+ characters using `""' as the separator, how might you use this
+ feature to simplify the program?
+
+ 8. The `extract.awk' program (*note Extract Program::) was written
+ before `gawk' had the `gensub()' function. Use it to simplify the
+ code.
+
+ 9. Compare the performance of the `awksed.awk' program (*note Simple
+ Sed::) with the more straightforward:
+
+ BEGIN {
+ pat = ARGV[1]
+ repl = ARGV[2]
+ ARGV[1] = ARGV[2] = ""
+ }
+
+ { gsub(pat, repl); print }
+
+ 10. What are the advantages and disadvantages of `awksed.awk' versus
+ the real `sed' utility?
+
+ 11. In *note Igawk Program::, we mentioned that 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. What problem does this engender
+ though?
+
+ 12. As an additional example of the idea that it is not always
+ necessary to add new features to a program, 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. Make
+ this change.
+
+ 13. Modify `anagram.awk' (*note Anagram Program::), to avoid the use
+ of the external `sort' utility.
+
+
+ ---------- Footnotes ----------
+
+ (1) This is the definition returned from entering `define: state
+machine' into Google.

-File: gawk.info, Node: Debugger, Next: Language History, Prev: Sample Programs, Up: Top
+File: gawk.info, Node: Advanced Features, Next: Internationalization, Prev: Sample Programs, Up: Top
-14 `dgawk': The `awk' Debugger
+12 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. Then, `gawk''s
+special features for sorting arrays are presented. 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. Finally,
+`gawk' can "profile" an `awk' program, making it possible to tune it
+for performance.
+
+ A number of advanced features require separate major nodes of their
+own:
+
+ * *note Internationalization::, discusses how to internationalize
+ your `awk' programs, so that they can speak multiple national
+ languages.
+
+ * *note Debugger::, describes `gawk''s built-in command-line
+ debugger for debugging `awk' programs.
+
+ * *note Arbitrary Precision Arithmetic::, describes how you can use
+ `gawk' to perform arbitrary-precision arithmetic.
+
+ * *note Dynamic Extensions::, discusses the ability to dynamically
+ add new built-in functions to `gawk'.
+
+* Menu:
+
+* Nondecimal Data:: Allowing nondecimal input data.
+* Array Sorting:: Facilities for controlling array traversal and
+ sorting arrays.
+* Two-way I/O:: Two-way communications with another process.
+* TCP/IP Networking:: Using `gawk' for network programming.
+* Profiling:: Profiling your `awk' programs.
+* Advanced Features Summary:: Summary of advanced features.
+
+
+File: gawk.info, Node: Nondecimal Data, Next: Array Sorting, Up: Advanced Features
+
+12.1 Allowing Nondecimal Input Data
+===================================
+
+If you run `gawk' with the `--non-decimal-data' option, you can have
+nondecimal values 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 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 this facility could lead to surprising results, the
+default is to leave it 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 String Functions::). This makes your
+ programs easier to write and easier to read, and leads to less
+ surprising results.
+
+ This option may disappear in a future version of `gawk'.
+
+
+File: gawk.info, Node: Array Sorting, Next: Two-way I/O, Prev: Nondecimal Data, Up: Advanced Features
+
+12.2 Controlling Array Traversal and Array Sorting
+==================================================
+
+`gawk' lets you control the order in which a `for (i in array)' loop
+traverses an array.
+
+ In addition, two built-in functions, `asort()' and `asorti()', let
+you sort arrays based on the array values and indices, respectively.
+These two functions also provide control over the sorting criteria used
+to order the elements during sorting.
+
+* Menu:
+
+* Controlling Array Traversal:: How to use PROCINFO["sorted_in"].
+* Array Sorting Functions:: How to use `asort()' and `asorti()'.
+
+
+File: gawk.info, Node: Controlling Array Traversal, Next: Array Sorting Functions, Up: Array Sorting
+
+12.2.1 Controlling Array Traversal
+----------------------------------
+
+By default, the order in which a `for (i in array)' loop scans an array
+is not defined; it is generally based upon the internal implementation
+of arrays inside `awk'.
+
+ Often, though, it is desirable to be able to loop over the elements
+in a particular order that you, the programmer, choose. `gawk' lets
+you do this.
+
+ *note Controlling Scanning::, describes how you can assign special,
+predefined values to `PROCINFO["sorted_in"]' in order to control the
+order in which `gawk' traverses an array during a `for' loop.
+
+ In addition, the value of `PROCINFO["sorted_in"]' can be a function
+name.(1) This lets you traverse an array based on any custom criterion.
+The array elements are ordered according to the return value of this
+function. The comparison function should be defined with at least four
+arguments:
+
+ function comp_func(i1, v1, i2, v2)
+ {
+ COMPARE ELEMENTS 1 AND 2 IN SOME FASHION
+ RETURN < 0; 0; OR > 0
+ }
+
+ Here, I1 and I2 are the indices, and V1 and V2 are the corresponding
+values of the two elements being compared. Either V1 or V2, or both,
+can be arrays if the array being traversed contains subarrays as values.
+(*Note Arrays of Arrays::, for more information about subarrays.) The
+three possible return values are interpreted as follows:
+
+`comp_func(i1, v1, i2, v2) < 0'
+ Index I1 comes before index I2 during loop traversal.
+
+`comp_func(i1, v1, i2, v2) == 0'
+ Indices I1 and I2 come together but the relative order with
+ respect to each other is undefined.
+
+`comp_func(i1, v1, i2, v2) > 0'
+ Index I1 comes after index I2 during loop traversal.
+
+ Our first comparison function can be used to scan an array in
+numerical order of the indices:
+
+ function cmp_num_idx(i1, v1, i2, v2)
+ {
+ # numerical index comparison, ascending order
+ return (i1 - i2)
+ }
+
+ Our second function traverses an array based on the string order of
+the element values rather than by indices:
+
+ function cmp_str_val(i1, v1, i2, v2)
+ {
+ # string value comparison, ascending order
+ v1 = v1 ""
+ v2 = v2 ""
+ if (v1 < v2)
+ return -1
+ return (v1 != v2)
+ }
+
+ The third comparison function makes all numbers, and numeric strings
+without any leading or trailing spaces, come out first during loop
+traversal:
+
+ function cmp_num_str_val(i1, v1, i2, v2, n1, n2)
+ {
+ # numbers before string value comparison, ascending order
+ n1 = v1 + 0
+ n2 = v2 + 0
+ if (n1 == v1)
+ return (n2 == v2) ? (n1 - n2) : -1
+ else if (n2 == v2)
+ return 1
+ return (v1 < v2) ? -1 : (v1 != v2)
+ }
+
+ Here is a main program to demonstrate how `gawk' behaves using each
+of the previous functions:
+
+ BEGIN {
+ data["one"] = 10
+ data["two"] = 20
+ data[10] = "one"
+ data[100] = 100
+ data[20] = "two"
+
+ f[1] = "cmp_num_idx"
+ f[2] = "cmp_str_val"
+ f[3] = "cmp_num_str_val"
+ for (i = 1; i <= 3; i++) {
+ printf("Sort function: %s\n", f[i])
+ PROCINFO["sorted_in"] = f[i]
+ for (j in data)
+ printf("\tdata[%s] = %s\n", j, data[j])
+ print ""
+ }
+ }
+
+ Here are the results when the program is run:
+
+ $ gawk -f compdemo.awk
+ -| Sort function: cmp_num_idx Sort by numeric index
+ -| data[two] = 20
+ -| data[one] = 10 Both strings are numerically zero
+ -| data[10] = one
+ -| data[20] = two
+ -| data[100] = 100
+ -|
+ -| Sort function: cmp_str_val Sort by element values as strings
+ -| data[one] = 10
+ -| data[100] = 100 String 100 is less than string 20
+ -| data[two] = 20
+ -| data[10] = one
+ -| data[20] = two
+ -|
+ -| Sort function: cmp_num_str_val Sort all numeric values before all strings
+ -| data[one] = 10
+ -| data[two] = 20
+ -| data[100] = 100
+ -| data[10] = one
+ -| data[20] = two
+
+ Consider sorting the entries of a GNU/Linux system password file
+according to login name. The following program sorts records by a
+specific field position and can be used for this purpose:
+
+ # passwd-sort.awk --- simple program to sort by field position
+ # field position is specified by the global variable POS
+
+ function cmp_field(i1, v1, i2, v2)
+ {
+ # comparison by value, as string, and ascending order
+ return v1[POS] < v2[POS] ? -1 : (v1[POS] != v2[POS])
+ }
+
+ {
+ for (i = 1; i <= NF; i++)
+ a[NR][i] = $i
+ }
+
+ END {
+ PROCINFO["sorted_in"] = "cmp_field"
+ if (POS < 1 || POS > NF)
+ POS = 1
+ for (i in a) {
+ for (j = 1; j <= NF; j++)
+ printf("%s%c", a[i][j], j < NF ? ":" : "")
+ print ""
+ }
+ }
+
+ The first field in each entry of the password file is the user's
+login name, and the fields are separated by colons. Each record
+defines a subarray, with each field as an element in the subarray.
+Running the program produces the following output:
+
+ $ gawk -v POS=1 -F: -f sort.awk /etc/passwd
+ -| adm:x:3:4:adm:/var/adm:/sbin/nologin
+ -| apache:x:48:48:Apache:/var/www:/sbin/nologin
+ -| avahi:x:70:70:Avahi daemon:/:/sbin/nologin
+ ...
+
+ The comparison should normally always return the same value when
+given a specific pair of array elements as its arguments. If
+inconsistent results are returned, then the order is undefined. This
+behavior can be exploited to introduce random order into otherwise
+seemingly ordered data:
+
+ function cmp_randomize(i1, v1, i2, v2)
+ {
+ # random order (caution: this may never terminate!)
+ return (2 - 4 * rand())
+ }
+
+ As already mentioned, the order of the indices is arbitrary if two
+elements compare equal. This is usually not a problem, but letting the
+tied elements come out in arbitrary order can be an issue, especially
+when comparing item values. The partial ordering of the equal elements
+may change the next time the array is traversed, if other elements are
+added or removed from the array. One way to resolve ties when
+comparing elements with otherwise equal values is to include the
+indices in the comparison rules. Note that doing this may make the
+loop traversal less efficient, so consider it only if necessary. The
+following comparison functions force a deterministic order, and are
+based on the fact that the (string) indices of two elements are never
+equal:
+
+ function cmp_numeric(i1, v1, i2, v2)
+ {
+ # numerical value (and index) comparison, descending order
+ return (v1 != v2) ? (v2 - v1) : (i2 - i1)
+ }
+
+ function cmp_string(i1, v1, i2, v2)
+ {
+ # string value (and index) comparison, descending order
+ v1 = v1 i1
+ v2 = v2 i2
+ return (v1 > v2) ? -1 : (v1 != v2)
+ }
+
+ A custom comparison function can often simplify ordered loop
+traversal, and the sky is really the limit when it comes to designing
+such a function.
+
+ When string comparisons are made during a sort, either for element
+values where one or both aren't numbers, or for element indices handled
+as strings, the value of `IGNORECASE' (*note Built-in Variables::)
+controls whether the comparisons treat corresponding upper- and
+lowercase letters as equivalent or distinct.
+
+ Another point to keep in mind is that in the case of subarrays, the
+element values can themselves be arrays; a production comparison
+function should use the `isarray()' function (*note Type Functions::),
+to check for this, and choose a defined sorting order for subarrays.
+
+ All sorting based on `PROCINFO["sorted_in"]' is disabled in POSIX
+mode, because the `PROCINFO' array is not special in that case.
+
+ As a side note, sorting the array indices before traversing the
+array has been reported to add 15% to 20% overhead to the execution
+time of `awk' programs. For this reason, sorted array traversal is not
+the default.
+
+ ---------- Footnotes ----------
+
+ (1) This is why the predefined sorting orders start with an `@'
+character, which cannot be part of an identifier.
+
+
+File: gawk.info, Node: Array Sorting Functions, Prev: Controlling Array Traversal, Up: Array Sorting
+
+12.2.2 Sorting Array Values and Indices with `gawk'
+---------------------------------------------------
+
+In most `awk' implementations, sorting an array requires writing a
+`sort()' function. This can be educational for exploring different
+sorting algorithms, but 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 default comparison is based on the type of the elements (*note
+Typing and Comparison::). All numeric values come before all string
+values, which in turn come before all subarrays.
+
+ 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, use the `asorti()'
+function. The interface and behavior are 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++) {
+ Work with sorted indices directly:
+ DO SOMETHING WITH dest[i]
+ ...
+ Access original array via sorted indices:
+ DO SOMETHING WITH source[dest[i]]
+ }
+ }
+
+ So far, so good. Now it starts to get interesting. Both `asort()'
+and `asorti()' accept a third string argument to control comparison of
+array elements. When we introduced `asort()' and `asorti()' in *note
+String Functions::, we ignored this third argument; however, now is the
+time to describe how this argument affects these two functions.
+
+ Basically, the third argument specifies how the array is to be
+sorted. There are two possibilities. As with `PROCINFO["sorted_in"]',
+this argument may be one of the predefined names that `gawk' provides
+(*note Controlling Scanning::), or it may be the name of a user-defined
+function (*note Controlling Array Traversal::).
+
+ In the latter case, _the function can compare elements in any way it
+chooses_, taking into account just the indices, just the values, or
+both. This is extremely powerful.
+
+ Once the array is sorted, `asort()' takes the _values_ in their
+final order, and uses them to fill in the result array, whereas
+`asorti()' takes the _indices_ in their final order, and uses them to
+fill in the result array.
+
+ NOTE: 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.
+
+ Because `IGNORECASE' affects string comparisons, the value of
+`IGNORECASE' also affects sorting for both `asort()' and `asorti()'.
+Note also that the locale's sorting order does _not_ come into play;
+comparisons are based on character values only.(1)
+
+ ---------- Footnotes ----------
+
+ (1) This is true because locale-based comparison occurs only when in
+POSIX-compatibility mode, and because `asort()' and `asorti()' are
+`gawk' extensions, they are not available in that case.
+
+
+File: gawk.info, Node: Two-way I/O, Next: TCP/IP Networking, Prev: Array Sorting, Up: Advanced Features
+
+12.3 Two-Way Communications with Another Process
+================================================
+
+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.(1) However, with `gawk', it
+is possible to open a _two-way_ pipe to another process. The second
+process is termed a "coprocess", as it runs in parallel with `gawk'.
+The two-way connection is created using the `|&' operator (borrowed
+from the Korn shell, `ksh'):(2)
+
+ 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 coprocess. 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
+coprocess 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'. This is not
+strictly necessary here, but it's good to know how to do this.
+
+ You may also 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, save in convenience variable
+ PROCINFO[command, "pty"] = 1 # update PROCINFO
+ print ... |& command # start two-way pipe
+ ...
+
+Using ptys usually 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) Michael Brennan suggests the use of `rand()' to generate unique
+file names. This is a valid point; nevertheless, temporary files remain
+more difficult to use than two-way pipes.
+
+ (2) This is very different from the same operator in the C shell and
+in Bash.
+
+
+File: gawk.info, Node: TCP/IP Networking, Next: Profiling, Prev: Two-way I/O, Up: Advanced Features
+
+12.4 Using `gawk' for Network Programming
+=========================================
+
+ `EMRED':
+ A host is a host from coast to coast,
+ and nobody talks to a host that's close,
+ unless the host that isn't close
+ is busy, hung, or dead. -- Mike O'Brien (aka Mr. Protocol)
+
+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 network
+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 one of
+`/inet/', `/inet4/', or `/inet6/'.
+
+ The full syntax of the special file name is
+`/NET-TYPE/PROTOCOL/LOCAL-PORT/REMOTE-HOST/REMOTE-PORT'. The
+components are:
+
+NET-TYPE
+ Specifies the kind of Internet connection to make. Use `/inet4/'
+ to force IPv4, and `/inet6/' to force IPv6. Plain `/inet/' (which
+ used to be the only option) uses the system default, most likely
+ IPv4.
+
+PROTOCOL
+ The protocol to use over IP. This must be either `tcp', or `udp',
+ for a TCP or UDP IP connection, respectively. TCP should be used
+ for most applications.
+
+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
+ `getaddrinfo()' 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.
+
+ NOTE: Failure in opening a two-way socket will result in a
+ non-fatal error being returned to the calling code. The value of
+ `ERRNO' indicates the error (*note Auto-set::).
+
+ 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. See *note (General
+Introduction)Top:: gawkinet, TCP/IP Internetworking with `gawk', for a
+much more complete introduction and discussion, as well as extensive
+examples.
+
+
+File: gawk.info, Node: Profiling, Next: Advanced Features Summary, Prev: TCP/IP Networking, Up: Advanced Features
+
+12.5 Profiling Your `awk' Programs
+==================================
+
+You may produce execution traces of your `awk' programs. This is done
+by passing the option `--profile' to `gawk'. When `gawk' 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 `gawk' will write the profile:
+
+ gawk --profile=myprog.prof -f myprog.awk data1 data2
+
+In the preceding example, `gawk' places the profile in `myprog.prof'
+instead of in `awkprof.out'.
+
+ Here is a sample session showing a simple `awk' program, its input
+data, and the results from running `gawk' with the `--profile' option.
+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 the `gawk'
+profiler on this program and data. (This example also illustrates that
+`awk' programmers sometimes get up very early in the morning to work.)
+
+ # gawk profile, created Mon Sep 29 05:16:21 2014
+
+ # BEGIN rule(s)
+
+ BEGIN {
+ 1 print "First BEGIN rule"
+ }
+
+ BEGIN {
+ 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 rule(s)
+
+ END {
+ 1 print "First END rule"
+ }
+
+ END {
+ 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 features of profiling
+output. They are as follows:
+
+ * The program is printed in the order `BEGIN' rules, `BEGINFILE'
+ rules, pattern/action rules, `ENDFILE' rules, `END' rules and
+ functions, listed alphabetically. Multiple `BEGIN' and `END'
+ rules retain their separate identities, as do multiple `BEGINFILE'
+ and `ENDFILE' rules.
+
+ * 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 and five, then multiply the total by
+ four. However, `3 + 5 * 4' has no parentheses, and means `3 + (5
+ * 4)'.
+
+ * 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.
+
+ * `gawk' supplies leading comments in front of the `BEGIN' and `END'
+ rules, the `BEGINFILE' and `ENDFILE' 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 `gawk' creates the
+profiled version by "pretty printing" its internal representation of
+the program. The advantage to this is that `gawk' can produce a
+standard representation. Also, things such as:
+
+ /foo/
+
+come out as:
+
+ /foo/ {
+ print $0
+ }
+
+which is correct, but possibly unexpected.
+
+ Besides creating profiles when a program has completed, `gawk' 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 `gawk' with the `--profile' option
+in the background:
+
+ $ gawk --profile -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 `gawk':
+
+ $ kill -USR1 13992
+
+As usual, the profiled version of the program is written to
+`awkprof.out', or to a different file if one was specified with the
+`--profile' option.
+
+ Along with the regular profile, as shown earlier, the profile file
+includes a trace of any active functions:
+
+ # Function Call Stack:
+
+ # 3. baz
+ # 2. bar
+ # 1. foo
+ # -- main --
+
+ You may send `gawk' 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, `gawk'
+produces the profile and the function call trace and then exits.
+
+ When `gawk' runs on MS-Windows systems, it uses the `INT' and `QUIT'
+signals for producing the profile and, in the case of the `INT' signal,
+`gawk' 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.
+
+ Finally, `gawk' also accepts another option, `--pretty-print'. When
+called this way, `gawk' "pretty prints" the program into `awkprof.out',
+without any execution counts.
+
+ NOTE: Once upon a time, the `--pretty-print' option would also run
+ your program. This is is no longer the case.
+
+ There is a significant difference between the output created when
+profiling, and that created when pretty-printing. Pretty-printed output
+preserves the original comments that were in the program, although their
+placement may not correspond exactly to their original locations in the
+source code.
+
+ However, as a deliberate design decision, profiling output _omits_
+the original program's comments. This allows you to focus on the
+execution count data and helps you avoid the temptation to use the
+profiler for pretty-printing.
+
+ Additionally, pretty-printed output does not have the leading
+indentation that the profiling output does. This makes it easy to
+pretty-print your code once development is completed, and then use the
+result as the final version of your program.
+
+
+File: gawk.info, Node: Advanced Features Summary, Prev: Profiling, Up: Advanced Features
+
+12.6 Summary
+============
+
+ * The `--non-decimal-data' option causes `gawk' to treat octal- and
+ hexadecimal-looking input data as octal and hexadecimal. This
+ option should be used with caution or not at all; use of
+ `strtonum()' is preferable. Note that this option may disappear
+ in a future version of `gawk'.
+
+ * You can take over complete control of sorting in `for (INDX in
+ ARRAY)' array traversal by setting `PROCINFO["sorted_in"]' to the
+ name of a user-defined function that does the comparison of array
+ elements based on index and value.
+
+ * Similarly, you can supply the name of a user-defined comparison
+ function as the third argument to either `asort()' or `asorti()'
+ to control how those functions sort arrays. Or you may provide one
+ of the predefined control strings that work for
+ `PROCINFO["sorted_in"]'.
+
+ * You can use the `|&' operator to create a two-way pipe to a
+ coprocess. You read from the coprocess with `getline' and write
+ to it with `print' or `printf'. Use `close()' to close off the
+ coprocess completely, or optionally, close off one side of the
+ two-way communications.
+
+ * By using special file names with the `|&' operator, you can open a
+ TCP/IP (or UDP/IP) connection to remote hosts in the Internet.
+ `gawk' supports both IPv4 and IPv6.
+
+ * You can generate statement count profiles of your program. This
+ can help you determine which parts of your program may be taking
+ the most time and let you tune them more easily. Sending the
+ `USR1' signal while profiling causes `gawk' to dump the profile
+ and keep going, including a function call stack.
+
+ * You can also just "pretty print" the program. This currently also
+ runs the program, but that will change in the next major release.
+
+
+
+File: gawk.info, Node: Internationalization, Next: Debugger, Prev: Advanced Features, Up: Top
+
+13 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.
+
+ For many years, 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 forced to write in C or 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.
+* I18N Summary:: Summary of I18N stuff.
+
+
+File: gawk.info, Node: I18N and L10N, Next: Explaining gettext, Up: Internationalization
+
+13.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.
+
+
+File: gawk.info, Node: Explaining gettext, Next: Programmer i18n, Prev: I18N and L10N, Up: Internationalization
+
+13.2 GNU `gettext'
+==================
+
+`gawk' uses GNU `gettext' to provide its internationalization features.
+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 reviews 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 template file (`guide.pot'),
+ 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.pot' is copied to a
+ portable object file (`.po') and translations are created and
+ shipped with the application. For example, there might be a
+ `fr.po' for a French translation.
+
+ 5. Each language's `.po' file is converted into a binary message
+ object (`.gmo') 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 `.gmo' 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("%s", 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("%s", _("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) as well as character encoding. This
+ information is accessed via the POSIX character classes in regular
+ expressions, such as `/[[:alnum:]]/' (*note Bracket Expressions::).
+
+`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_TIME'
+ Time- and date-related information, such as 12- or 24-hour clock,
+ month printed before or after the 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'. Therefore, 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.
+
+
+File: gawk.info, Node: Programmer i18n, Next: Translator i18n, Prev: Explaining gettext, Up: Internationalization
+
+13.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]]`)''
+ Return 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]]`)''
+ Return 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 is 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 about argument order as for the `dcgettext()'
+ function apply.
+
+``bindtextdomain(DIRECTORY' [`,' DOMAIN ]`)''
+ Change the directory in which `gettext' looks for `.gmo' files, in
+ case they will not or cannot be placed in the standard locations
+ (e.g., during testing). Return 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:(1)
+
+ if (groggy)
+ message = dcgettext("%d customers disturbing me\n", "adminprog")
+ else
+ message = dcgettext("enjoying %d customers\n", "adminprog")
+ printf(message, ncustomers)
+
+ 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.
+
+ The previous example only works if `ncustomers' is greater than
+ one. This example would be better done with `dcngettext()':
+
+ if (groggy)
+ message = dcngettext("%d customer disturbing me\n",
+ "%d customers disturbing me\n", "adminprog")
+ else
+ message = dcngettext("enjoying %d customer\n",
+ "enjoying %d customers\n", "adminprog")
+ printf(message, ncustomers)
+
+ 4. During development, you might want to put the `.gmo' 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'.
+
+ ---------- Footnotes ----------
+
+ (1) Thanks to Bruno Haible for this example.
+
+
+File: gawk.info, Node: Translator i18n, Next: I18N Example, Prev: Programmer i18n, Up: Internationalization
+
+13.4 Translating `awk' Programs
+===============================
+
+Once a program's translatable strings have been marked, they must be
+extracted to create the initial `.pot' file. As part of translation,
+it is often helpful to rearrange the order in which arguments to
+`printf' are output.
+
+ `gawk''s `--gen-pot' 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.
+
+
+File: gawk.info, Node: String Extraction, Next: Printf Ordering, Up: Translator i18n
+
+13.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-pot' command-line
+option to create the initial `.pot' file:
+
+ gawk --gen-pot -f guide.awk > guide.pot
+
+ When run with `--gen-pot', `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) You should distribute the generated `.pot' file with
+your `awk' program; translators will eventually use it to provide you
+translations that you can also then distribute. *Note I18N Example::,
+for the full list of steps to go through to create and test
+translations for `guide'.
+
+ ---------- Footnotes ----------
+
+ (1) The `xgettext' utility that comes with GNU `gettext' can handle
+`.awk' files.
+
+
+File: gawk.info, Node: Printf Ordering, Next: I18N Portability, Prev: String Extraction, Up: Translator i18n
+
+13.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 specifiers 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 = "Don\47t Panic"
+ > printf "%2$d characters live in \"%1$s\"\n",
+ > string, length(string)
+ > }'
+ -| 11 characters live in "Don't 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 counterintuitive.
+
+ `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.
+
+
+File: gawk.info, Node: I18N Portability, Prev: Printf Ordering, Up: Translator i18n
+
+13.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, because
+ `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, because the positional specifications are primarily for
+ use in _translated_ format strings, and because 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.
+
+
+File: gawk.info, Node: I18N Example, Next: Gawk I18N, Prev: Translator i18n, Up: Internationalization
+
+13.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-pot' to create the `.pot' file:
+
+ $ gawk --gen-pot -f guide.awk > guide.pot
+
+This produces:
+
+ #: guide.awk:4
+ msgid "Don't Panic"
+ msgstr ""
+
+ #: guide.awk:5
+ msgid "The Answer Is"
+ msgstr ""
+
+ This original portable object template 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.pot' file.
+
+ Next, the messages must be translated. Here is a translation to a
+hypothetical dialect of English, called "Mellow":(1)
+
+ $ cp guide.pot 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. We pretend that
+our file is to be used in the `en_US.UTF-8' locale, because we have to
+use a locale name known to the C `gettext' routines. 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.UTF-8 en_US.UTF-8/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 (using the `-o' option) so that `gawk' can find it:
+
+ $ msgfmt guide-mellow.po -o en_US.UTF-8/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.
+
+
+File: gawk.info, Node: Gawk I18N, Next: I18N Summary, Prev: I18N Example, Up: Internationalization
+
+13.6 `gawk' Can Speak Your Language
+===================================
+
+`gawk' itself has been internationalized using the GNU `gettext'
+package. (GNU `gettext' is described in complete detail in *note (GNU
+`gettext' utilities)Top:: gettext, GNU gettext tools.) As of this
+writing, the latest version of GNU `gettext' is version 0.19.4
+(ftp://ftp.gnu.org/gnu/gettext/gettext-0.19.4.tar.gz).
+
+ If a translation of `gawk''s messages exists, then `gawk' produces
+usage messages, warnings, and fatal errors in the local language.
+
+
+File: gawk.info, Node: I18N Summary, Prev: Gawk I18N, Up: Internationalization
+
+13.7 Summary
+============
+
+ * Internationalization means writing a program such that it can use
+ multiple languages without requiring source-code changes.
+ Localization means providing the data necessary for an
+ internationalized program to work in a particular language.
+
+ * `gawk' uses GNU `gettext' to let you internationalize and localize
+ `awk' programs. A program's text domain identifies the program
+ for grouping all messages and other data together.
+
+ * You mark a program's strings for translation by preceding them with
+ an underscore. Once that is done, the strings are extracted into a
+ `.pot' file. This file is copied for each language into a `.po'
+ file, and the `.po' files are compiled into `.gmo' files for use
+ at runtime.
+
+ * You can use position specifications with `sprintf()' and `printf'
+ to rearrange the placement of argument values in formatted strings
+ and output. This is useful for the translations of format control
+ strings.
+
+ * The internationalization features have been designed so that they
+ can be easily worked around in a standard `awk'.
+
+ * `gawk' itself has been internationalized and ships with a number
+ of translations for its messages.
+
+
+
+File: gawk.info, Node: Debugger, Next: Arbitrary Precision Arithmetic, Prev: Internationalization, Up: Top
+
+14 Debugging `awk' Programs
+***************************
+
It would be nice if computer programs worked perfectly the first time
they were run, but in real life, this rarely happens for programs of
any complexity. Thus, most programming languages have facilities
available for "debugging" programs, and now `awk' is no exception.
- The `dgawk' debugger is purposely modeled after the GNU Debugger
+ The `gawk' debugger is purposely modeled after the GNU Debugger
(GDB) (http://www.gnu.org/software/gdb/) command-line debugger. If you
-are familiar with GDB, learning `dgawk' is easy.
+are familiar with GDB, learning how to use `gawk' for debugging your
+program is easy.
* Menu:
-* Debugging:: Introduction to `dgawk'.
-* Sample dgawk session:: Sample `dgawk' session.
-* List of Debugger Commands:: Main `dgawk' Commands.
-* Readline Support:: Readline Support.
-* Dgawk Limitations:: Limitations and future plans.
+* Debugging:: Introduction to `gawk' debugger.
+* Sample Debugging Session:: Sample debugging session.
+* List of Debugger Commands:: Main debugger commands.
+* Readline Support:: Readline support.
+* Limitations:: Limitations and future plans.
+* Debugging Summary:: Debugging summary.

-File: gawk.info, Node: Debugging, Next: Sample dgawk session, Up: Debugger
+File: gawk.info, Node: Debugging, Next: Sample Debugging Session, Up: Debugger
-14.1 Introduction to `dgawk'
-============================
+14.1 Introduction to the `gawk' Debugger
+========================================
This minor node introduces debugging in general and begins the
discussion of debugging in `gawk'.
* Menu:
-* Debugging Concepts:: Debugging In General.
+* Debugging Concepts:: Debugging in General.
* Debugging Terms:: Additional Debugging Concepts.
* Awk Debugging:: Awk Debugging.

File: gawk.info, Node: Debugging Concepts, Next: Debugging Terms, Up: Debugging
-14.1.1 Debugging In General
+14.1.1 Debugging in General
---------------------------
(If you have used debuggers in other languages, you may want to skip
-ahead to the next section on the specific features of the `awk'
+ahead to the next section on the specific features of the `gawk'
debugger.)
- Of course, a debugging program cannot remove bugs for you, since it
-has no way of knowing what you or your users consider a "bug" and what
-is a "feature." (Sometimes, we humans have a hard time with this
+ Of course, a debugging program cannot remove bugs for you, because
+it has no way of knowing what you or your users consider a "bug" versus
+a "feature." (Sometimes, we humans have a hard time with this
ourselves.) In that case, what can you expect from such a tool? The
answer to that depends on the language being debugged, but in general,
you can expect at least the following:
@@ -18782,7 +20717,7 @@ you can expect at least the following:
* The chance to see the values of data in the program at any point in
execution, and also to change that data on the fly, to see how that
- affects what happens afterwards. (This often includes the ability
+ affects what happens afterward. (This often includes the ability
to look at internal data structures besides the variables you
actually defined in your code.)
@@ -18797,15 +20732,14 @@ functional program that you or someone else wrote).

File: gawk.info, Node: Debugging Terms, Next: Awk Debugging, Prev: Debugging Concepts, Up: Debugging
-14.1.2 Additional Debugging Concepts
-------------------------------------
+14.1.2 Debugging Concepts
+-------------------------
Before diving in to the details, we need to introduce several important
-concepts that apply to just about all debuggers, including `dgawk'.
-The following list defines terms used throughout the rest of this
-major node.
+concepts that apply to just about all debuggers. The following list
+defines terms used throughout the rest of this major node:
-"Stack Frame"
+"Stack frame"
Programs generally call functions during the course of their
execution. One function can call another, or a function can call
itself (recursion). You can view the chain of called functions
@@ -18821,11 +20755,11 @@ major node.
needed to manage the call stack. This data area is termed a
"stack frame".
- `gawk' also follows this model, and `dgawk' gives you access to
- the call stack and to each stack frame. You can see the call
- stack, as well as from where each function on the stack was
- invoked. Commands that print the call stack print information about
- each stack frame (as detailed later on).
+ `gawk' also follows this model, and gives you access to the call
+ stack and to each stack frame. You can see the call stack, as well
+ as from where each function on the stack was invoked. Commands
+ that print the call stack print information about each stack frame
+ (as detailed later on).
"Breakpoint"
During debugging, you often wish to let the program run until it
@@ -18841,11 +20775,11 @@ major node.
breakpoints are oriented around the code: stop when a certain
point in the code is reached. A watchpoint, however, specifies
that program execution should stop when a _data value_ is changed.
- This is useful, since sometimes it happens that a variable
- receives an erroneous value, and it's hard to track down where
- this happens just by looking at the code. By using a watchpoint,
- you can stop whenever a variable is assigned to, and usually find
- the errant code quite quickly.
+ This is useful, as sometimes it happens that a variable receives
+ an erroneous value, and it's hard to track down where this happens
+ just by looking at the code. By using a watchpoint, you can stop
+ whenever a variable is assigned to, and usually find the errant
+ code quite quickly.

File: gawk.info, Node: Awk Debugging, Prev: Debugging Terms, Up: Debugging
@@ -18856,68 +20790,71 @@ File: gawk.info, Node: Awk Debugging, Prev: Debugging Terms, Up: Debugging
Debugging an `awk' program has some specific aspects that are not
shared with other programming languages.
- First of all, the fact that `awk' programs usually take input
-line-by-line from a file or files and operate on those lines using
-specific rules makes it especially useful to organize viewing the
-execution of the program in terms of these rules. As we will see, each
-`awk' rule is treated almost like a function call, with its own
-specific block of instructions.
+ First of all, the fact that `awk' programs usually take input line
+by line from a file or files and operate on those lines using specific
+rules makes it especially useful to organize viewing the execution of
+the program in terms of these rules. As we will see, each `awk' rule
+is treated almost like a function call, with its own specific block of
+instructions.
- In addition, since `awk' is by design a very concise language, it is
-easy to lose sight of everything that is going on "inside" each line of
-`awk' code. The debugger provides the opportunity to look at the
+ In addition, because `awk' is by design a very concise language, it
+is easy to lose sight of everything that is going on "inside" each line
+of `awk' code. The debugger provides the opportunity to look at the
individual primitive instructions carried out by the higher-level `awk'
commands.

-File: gawk.info, Node: Sample dgawk session, Next: List of Debugger Commands, Prev: Debugging, Up: Debugger
+File: gawk.info, Node: Sample Debugging Session, Next: List of Debugger Commands, Prev: Debugging, Up: Debugger
-14.2 Sample `dgawk' session
-===========================
+14.2 Sample Debugging Session
+=============================
-In order to illustrate the use of `dgawk', let's look at a sample
-debugging session. We will use the `awk' implementation of the POSIX
-`uniq' command described earlier (*note Uniq Program::) as our example.
+In order to illustrate the use of `gawk' as a debugger, let's look at a
+sample debugging session. We will use the `awk' implementation of the
+POSIX `uniq' command described earlier (*note Uniq Program::) as our
+example.
* Menu:
-* dgawk invocation:: `dgawk' Invocation.
-* Finding The Bug:: Finding The Bug.
+* Debugger Invocation:: How to Start the Debugger.
+* Finding The Bug:: Finding the Bug.

-File: gawk.info, Node: dgawk invocation, Next: Finding The Bug, Up: Sample dgawk session
+File: gawk.info, Node: Debugger Invocation, Next: Finding The Bug, Up: Sample Debugging Session
-14.2.1 `dgawk' Invocation
--------------------------
+14.2.1 How to Start the Debugger
+--------------------------------
-Starting `dgawk' is exactly like running `awk'. The file(s) containing
-the program and any supporting code are given on the command line as
-arguments to one or more `-f' options. (`dgawk' is not designed to
-debug command-line programs, only programs contained in files.) In our
-case, we call `dgawk' like this:
+Starting the debugger is almost exactly like running `gawk' normally,
+except you have to pass an additional option `--debug', or the
+corresponding short option `-D'. The file(s) containing the program
+and any supporting code are given on the command line as arguments to
+one or more `-f' options. (`gawk' is not designed to debug command-line
+programs, only programs contained in files.) In our case, we invoke
+the debugger like this:
- $ dgawk -f getopt.awk -f join.awk -f uniq.awk inputfile
+ $ gawk -D -f getopt.awk -f join.awk -f uniq.awk -1 inputfile
where both `getopt.awk' and `uniq.awk' are in `$AWKPATH'. (Experienced
users of GDB or similar debuggers should note that this syntax is
-slightly different from what they are used to. With `dgawk', the
-arguments for running the program are given in the command line to the
-debugger rather than as part of the `run' command at the debugger
-prompt.)
+slightly different from what they are used to. With the `gawk'
+debugger, you give the arguments for running the program in the command
+line to the debugger rather than as part of the `run' command at the
+debugger prompt.) The `-1' is an option to `uniq.awk'.
Instead of immediately running the program on `inputfile', as `gawk'
-would ordinarily do, `dgawk' merely loads all the program source files,
-compiles them internally, and then gives us a prompt:
+would ordinarily do, the debugger merely loads all the program source
+files, compiles them internally, and then gives us a prompt:
- dgawk>
+ gawk>
from which we can issue commands to the debugger. At this point, no
code has been executed.

-File: gawk.info, Node: Finding The Bug, Prev: dgawk invocation, Up: Sample dgawk session
+File: gawk.info, Node: Finding The Bug, Prev: Debugger Invocation, Up: Sample Debugging Session
-14.2.2 Finding The Bug
+14.2.2 Finding the Bug
----------------------
Let's say that we are having a problem using (a faulty version of)
@@ -18947,62 +20884,62 @@ for a breakpoint in `uniq.awk' is at the beginning of the function
`are_equal()', which compares the current line with the previous one.
To set the breakpoint, use the `b' (breakpoint) command:
- dgawk> b are_equal
- -| Breakpoint 1 set at file `awklib/eg/prog/uniq.awk', line 64
+ gawk> b are_equal
+ -| Breakpoint 1 set at file `awklib/eg/prog/uniq.awk', line 63
The debugger tells us the file and line number where the breakpoint
is. Now type `r' or `run' and the program runs until it hits the
breakpoint for the first time:
- dgawk> r
+ gawk> r
-| Starting program:
-| Stopping in Rule ...
-| Breakpoint 1, are_equal(n, m, clast, cline, alast, aline)
- at `awklib/eg/prog/uniq.awk':64
- -| 64 if (fcount == 0 && charcount == 0)
- dgawk>
+ at `awklib/eg/prog/uniq.awk':63
+ -| 63 if (fcount == 0 && charcount == 0)
+ gawk>
Now we can look at what's going on inside our program. First of all,
let's see how we got to where we are. At the prompt, we type `bt'
-(short for "backtrace"), and `dgawk' responds with a listing of the
-current stack frames:
+(short for "backtrace"), and the debugger responds with a listing of
+the current stack frames:
- dgawk> bt
+ gawk> bt
-| #0 are_equal(n, m, clast, cline, alast, aline)
- at `awklib/eg/prog/uniq.awk':69
- -| #1 in main() at `awklib/eg/prog/uniq.awk':89
+ at `awklib/eg/prog/uniq.awk':68
+ -| #1 in main() at `awklib/eg/prog/uniq.awk':88
This tells us that `are_equal()' was called by the main program at
-line 89 of `uniq.awk'. (This is not a big surprise, since this is the
-only call to `are_equal()' in the program, but in more complex
+line 88 of `uniq.awk'. (This is not a big surprise, because this is
+the only call to `are_equal()' in the program, but in more complex
programs, knowing who called a function and with what parameters can be
the key to finding the source of the problem.)
Now that we're in `are_equal()', we can start looking at the values
of some variables. Let's say we type `p n' (`p' is short for "print").
We would expect to see the value of `n', a parameter to `are_equal()'.
-Actually, `dgawk' gives us:
+Actually, the debugger gives us:
- dgawk> p n
+ gawk> p n
-| n = untyped variable
-In this case, `n' is an uninitialized local variable, since the
+In this case, `n' is an uninitialized local variable, because the
function was called without arguments (*note Function Calls::).
A more useful variable to display might be the current record:
- dgawk> p $0
- -| $0 = string ("gawk is a wonderful program!")
+ gawk> p $0
+ -| $0 = "gawk is a wonderful program!"
-This might be a bit puzzling at first since this is the second line of
-our test input above. Let's look at `NR':
+This might be a bit puzzling at first, as this is the second line of
+our test input. Let's look at `NR':
- dgawk> p NR
- -| NR = number (2)
+ gawk> p NR
+ -| NR = 2
So we can see that `are_equal()' was only called for the second record
-of the file. Of course, this is because our program contained a rule
-for `NR == 1':
+of the file. Of course, this is because our program contains a rule for
+`NR == 1':
NR == 1 {
last = $0
@@ -19011,8 +20948,8 @@ for `NR == 1':
OK, let's just check that that rule worked correctly:
- dgawk> p last
- -| last = string ("awk is a wonderful program!")
+ gawk> p last
+ -| last = "awk is a wonderful program!"
Everything we have done so far has verified that the program has
worked as planned, up to and including the call to `are_equal()', so
@@ -19020,88 +20957,85 @@ the problem must be inside this function. To investigate further, we
must begin "stepping through" the lines of `are_equal()'. We start by
typing `n' (for "next"):
- dgawk> n
- -| 67 if (fcount > 0) {
+ gawk> n
+ -| 66 if (fcount > 0) {
- This tells us that `gawk' is now ready to execute line 67, which
+ This tells us that `gawk' is now ready to execute line 66, which
decides whether to give the lines the special "field skipping" treatment
-indicated by the `-f' command-line option. (Notice that we skipped
-from where we were before at line 64 to here, since the condition in
-line 64
-
- if (fcount == 0 && charcount == 0)
-
-was false.)
+indicated by the `-1' command-line option. (Notice that we skipped
+from where we were before at line 63 to here, because the condition in
+line 63 `if (fcount == 0 && charcount == 0)' was false.)
Continuing to step, we now get to the splitting of the current and
last records:
- dgawk> n
- -| 68 n = split(last, alast)
- dgawk> n
- -| 69 m = split($0, aline)
+ gawk> n
+ -| 67 n = split(last, alast)
+ gawk> n
+ -| 68 m = split($0, aline)
At this point, we should be curious to see what our records were
split into, so we try to look:
- dgawk> p n m alast aline
- -| n = number (5)
- -| m = number (5)
+ gawk> p n m alast aline
+ -| n = 5
+ -| m = untyped variable
-| alast = array, 5 elements
- -| aline = array, 5 elements
+ -| aline = untyped variable
(The `p' command can take more than one argument, similar to `awk''s
`print' statement.)
This is kind of disappointing, though. All we found out is that
-there are five elements in each of our arrays. Useful enough (we now
-know that none of the words were accidentally left out), but what if we
-want to see inside the array?
+there are five elements in `alast'; `m' and `aline' don't have values
+because we are at line 68 but haven't executed it yet. This
+information is useful enough (we now know that none of the words were
+accidentally left out), but what if we want to see inside the array?
The first choice would be to use subscripts:
- dgawk> p alast[0]
+ gawk> p alast[0]
-| "0" not in array `alast'
Oops!
- dgawk> p alast[1]
- -| alast["1"] = string ("awk")
+ gawk> p alast[1]
+ -| alast["1"] = "awk"
- This would be kind of slow for a 100-member array, though, so
-`dgawk' provides a shortcut (reminiscent of another language not to be
+ This would be kind of slow for a 100-member array, though, so `gawk'
+provides a shortcut (reminiscent of another language not to be
mentioned):
- dgawk> p @alast
- -| alast["1"] = string ("awk")
- -| alast["2"] = string ("is")
- -| alast["3"] = string ("a")
- -| alast["4"] = string ("wonderful")
- -| alast["5"] = string ("program!")
+ gawk> p @alast
+ -| alast["1"] = "awk"
+ -| alast["2"] = "is"
+ -| alast["3"] = "a"
+ -| alast["4"] = "wonderful"
+ -| alast["5"] = "program!"
It looks like we got this far OK. Let's take another step or two:
- dgawk> n
- -| 70 clast = join(alast, fcount, n)
- dgawk> n
- -| 71 cline = join(aline, fcount, m)
+ gawk> n
+ -| 69 clast = join(alast, fcount, n)
+ gawk> n
+ -| 70 cline = join(aline, fcount, m)
Well, here we are at our error (sorry to spoil the suspense). What
we had in mind was to join the fields starting from the second one to
make the virtual record to compare, and if the first field was numbered
zero, this would work. Let's look at what we've got:
- dgawk> p cline clast
- -| cline = string ("gawk is a wonderful program!")
- -| clast = string ("awk is a wonderful program!")
+ gawk> p cline clast
+ -| cline = "gawk is a wonderful program!"
+ -| clast = "awk is a wonderful program!"
Hey, those look pretty familiar! They're just our original,
unaltered, input records. A little thinking (the human brain is still
the best debugging tool), and we realize that we were off by one!
- We get out of `dgawk':
+ We get out of the debugger:
- dgawk> q
+ gawk> q
-| The program is running. Exit anyway (y/n)? y
Then we get into an editor:
@@ -19112,12 +21046,13 @@ Then we get into an editor:
and problem solved!

-File: gawk.info, Node: List of Debugger Commands, Next: Readline Support, Prev: Sample dgawk session, Up: Debugger
+File: gawk.info, Node: List of Debugger Commands, Next: Readline Support, Prev: Sample Debugging Session, Up: Debugger
-14.3 Main `dgawk' Commands
-==========================
+14.3 Main Debugger Commands
+===========================
-The `dgawk' command set can be divided into the following categories:
+The `gawk' debugger command set can be divided into the following
+categories:
* Breakpoint control
@@ -19133,32 +21068,32 @@ The `dgawk' command set can be divided into the following categories:
Each of these are discussed in the following subsections. In the
following descriptions, commands which may be abbreviated show the
-abbreviation on a second description line. A `dgawk' command name may
-also be truncated if that partial name is unambiguous. `dgawk' has the
-built-in capability to automatically repeat the previous command when
-just hitting <Enter>. This works for the commands `list', `next',
-`nexti', `step', `stepi' and `continue' executed without any argument.
+abbreviation on a second description line. A debugger command name may
+also be truncated if that partial name is unambiguous. The debugger has
+the built-in capability to automatically repeat the previous command
+just by hitting <Enter>. This works for the commands `list', `next',
+`nexti', `step', `stepi', and `continue' executed without any argument.
* Menu:
-* Breakpoint Control:: Control of breakpoints.
-* Dgawk Execution Control:: Control of execution.
-* Viewing And Changing Data:: Viewing and changing data.
-* Dgawk Stack:: Dealing with the stack.
-* Dgawk Info:: Obtaining information about the program and
- the debugger state.
-* Miscellaneous Dgawk Commands:: Miscellaneous Commands.
+* Breakpoint Control:: Control of Breakpoints.
+* Debugger Execution Control:: Control of Execution.
+* Viewing And Changing Data:: Viewing and Changing Data.
+* Execution Stack:: Dealing with the Stack.
+* Debugger Info:: Obtaining Information about the Program and
+ the Debugger State.
+* Miscellaneous Debugger Commands:: Miscellaneous Commands.

-File: gawk.info, Node: Breakpoint Control, Next: Dgawk Execution Control, Up: List of Debugger Commands
+File: gawk.info, Node: Breakpoint Control, Next: Debugger Execution Control, Up: List of Debugger Commands
-14.3.1 Control Of Breakpoints
+14.3.1 Control of Breakpoints
-----------------------------
-As we saw above, the first thing you probably want to do in a debugging
-session is to get your breakpoints set up, since otherwise your program
-will just run as if it was not under the debugger. The commands for
-controlling breakpoints are:
+As we saw earlier, the first thing you probably want to do in a
+debugging session is to get your breakpoints set up, because your
+program will otherwise just run as if it was not under the debugger.
+The commands for controlling breakpoints are:
`break' [[FILENAME`:']N | FUNCTION] [`"EXPRESSION"']
`b' [[FILENAME`:']N | FUNCTION] [`"EXPRESSION"']
@@ -19180,10 +21115,10 @@ controlling breakpoints are:
it from the breakpoint list using the `delete' command.
With a breakpoint, you may also supply a condition. This is an
- `awk' expression (enclosed in double quotes) that `dgawk'
+ `awk' expression (enclosed in double quotes) that the debugger
evaluates whenever the breakpoint is reached. If the condition is
- true, then `dgawk' stops execution and prompts for a command.
- Otherwise, `dgawk' continues executing the program.
+ true, then the debugger stops execution and prompts for a command.
+ Otherwise, it continues executing the program.
`clear' [[FILENAME`:']N | FUNCTION]
Without any argument, delete any breakpoint at the next instruction
@@ -19205,12 +21140,13 @@ controlling breakpoints are:
`condition' N `"EXPRESSION"'
Add a condition to existing breakpoint or watchpoint N. The
- condition is an `awk' expression that `dgawk' evaluates whenever
- the breakpoint or watchpoint is reached. If the condition is true,
- then `dgawk' stops execution and prompts for a command. Otherwise,
- `dgawk' continues executing the program. If the condition
- expression is not specified, any existing condition is removed;
- i.e., the breakpoint or watchpoint is made unconditional.
+ condition is an `awk' expression _enclosed in double quotes_ that
+ the debugger evaluates whenever the breakpoint or watchpoint is
+ reached. If the condition is true, then the debugger stops
+ execution and prompts for a command. Otherwise, the debugger
+ continues executing the program. If the condition expression is
+ not specified, any existing condition is removed (i.e., the
+ breakpoint or watchpoint is made unconditional).
`delete' [N1 N2 ...] [N-M]
`d' [N1 N2 ...] [N-M]
@@ -19244,7 +21180,7 @@ controlling breakpoints are:
arguments are the same as for `break'.

-File: gawk.info, Node: Dgawk Execution Control, Next: Viewing And Changing Data, Prev: Breakpoint Control, Up: List of Debugger Commands
+File: gawk.info, Node: Debugger Execution Control, Next: Viewing And Changing Data, Prev: Breakpoint Control, Up: List of Debugger Commands
14.3.2 Control of Execution
---------------------------
@@ -19267,14 +21203,14 @@ execution of the program than we saw in our earlier example:
`continue') terminates the list (an implicit `end'), and
subsequent commands are ignored. For example:
- dgawk> commands
+ gawk> commands
> silent
> printf "A silent breakpoint; i = %d\n", i
> info locals
> set i = 10
> continue
> end
- dgawk>
+ gawk>
`continue' [COUNT]
`c' [COUNT]
@@ -19301,15 +21237,15 @@ execution of the program than we saw in our earlier example:
Cancel execution of a function call. If VALUE (either a string or a
number) is specified, it is used as the function's return value.
If used in a frame other than the innermost one (the currently
- executing function, i.e., frame number 0), discard all inner
+ executing function; i.e., frame number 0), discard all inner
frames in addition to the selected one, and the caller of that
frame becomes the innermost frame.
`run'
`r'
- Start/restart execution of the program. When restarting, `dgawk'
- retains the current breakpoints, watchpoints, command history,
- automatic display variables, and debugger options.
+ Start/restart execution of the program. When restarting, the
+ debugger retains the current breakpoints, watchpoints, command
+ history, automatic display variables, and debugger options.
`step' [COUNT]
`s' [COUNT]
@@ -19323,18 +21259,18 @@ execution of the program than we saw in our earlier example:
`si' [COUNT]
Execute one (or COUNT) instruction(s), stepping inside function
calls. (For illustration of what is meant by an "instruction" in
- `gawk', see the output shown under `dump' in *Note Miscellaneous
- Dgawk Commands::.)
+ `gawk', see the output shown under `dump' in *note Miscellaneous
+ Debugger Commands::.)
`until' [[FILENAME`:']N | FUNCTION]
`u' [[FILENAME`:']N | FUNCTION]
Without any argument, continue execution until a line past the
- current line in current stack frame is reached. With an argument,
- continue execution until the specified location is reached, or the
- current stack frame returns.
+ current line in the current stack frame is reached. With an
+ argument, continue execution until the specified location is
+ reached, or the current stack frame returns.

-File: gawk.info, Node: Viewing And Changing Data, Next: Dgawk Stack, Prev: Dgawk Execution Control, Up: List of Debugger Commands
+File: gawk.info, Node: Viewing And Changing Data, Next: Execution Stack, Prev: Debugger Execution Control, Up: List of Debugger Commands
14.3.3 Viewing and Changing Data
--------------------------------
@@ -19346,10 +21282,10 @@ The commands for viewing and changing variables inside of `gawk' are:
of the variable or field is displayed each time the program stops.
Each variable added to the list is identified by a unique number:
- dgawk> display x
+ gawk> display x
-| 10: x = 1
- displays the assigned item number, the variable name and its
+ This displays the assigned item number, the variable name, and its
current value. If the display variable refers to a function
parameter, it is silently deleted from the list as soon as the
execution reaches a context where no such variable of the given
@@ -19374,13 +21310,13 @@ AWK STATEMENTS
Print the value of a `gawk' variable or field. Fields must be
referenced by constants:
- dgawk> print $3
+ gawk> print $3
This prints the third field in the input record (if the specified
field does not exist, it prints `Null field'). A variable can be
- an array element, with the subscripts being constant values. To
- print the contents of an array, prefix the name of the array with
- the `@' symbol:
+ an array element, with the subscripts being constant string
+ values. To print the contents of an array, prefix the name of the
+ array with the `@' symbol:
gawk> print @a
@@ -19395,23 +21331,23 @@ AWK STATEMENTS
`set' VAR`='VALUE
Assign a constant (number or string) value to an `awk' variable or
field. String values must be enclosed between double quotes
- (`"..."').
+ (`"'...`"').
You can also set special `awk' variables, such as `FS', `NF',
- `NR', etc.
+ `NR', and son on.
`watch' VAR | `$'N [`"EXPRESSION"']
`w' VAR | `$'N [`"EXPRESSION"']
- Add variable VAR (or field `$N') to the watch list. `dgawk' then
- stops whenever the value of the variable or field changes. Each
- watched item is assigned a number which can be used to delete it
- from the watch list using the `unwatch' command.
+ Add variable VAR (or field `$N') to the watch list. The debugger
+ then stops whenever the value of the variable or field changes.
+ Each watched item is assigned a number which can be used to delete
+ it from the watch list using the `unwatch' command.
With a watchpoint, you may also supply a condition. This is an
- `awk' expression (enclosed in double quotes) that `dgawk'
+ `awk' expression (enclosed in double quotes) that the debugger
evaluates whenever the watchpoint is reached. If the condition is
- true, then `dgawk' stops execution and prompts for a command.
- Otherwise, `dgawk' continues executing the program.
+ true, then the debugger stops execution and prompts for a command.
+ Otherwise, `gawk' continues executing the program.
`undisplay' [N]
Remove item number N (or all items, if no argument) from the
@@ -19423,9 +21359,9 @@ AWK STATEMENTS

-File: gawk.info, Node: Dgawk Stack, Next: Dgawk Info, Prev: Viewing And Changing Data, Up: List of Debugger Commands
+File: gawk.info, Node: Execution Stack, Next: Debugger Info, Prev: Viewing And Changing Data, Up: List of Debugger Commands
-14.3.4 Dealing With The Stack
+14.3.4 Working with the Stack
-----------------------------
Whenever you run a program which contains any function calls, `gawk'
@@ -19437,11 +21373,13 @@ are:
`backtrace' [COUNT]
`bt' [COUNT]
+`where' [COUNT]
Print a backtrace of all function calls (stack frames), or
innermost COUNT frames if COUNT > 0. Print the outermost COUNT
frames if COUNT < 0. The backtrace displays the name and
arguments to each function, the source file name, and the line
- number.
+ number. The alias `where' for `backtrace' is provided for longtime
+ GDB users who may be used to that command.
`down' [COUNT]
Move COUNT (default 1) frames down the stack toward the innermost
@@ -19449,34 +21387,36 @@ are:
`frame' [N]
`f' [N]
- Select and print (frame number, function and argument names,
- source file, and the source line) stack frame N. Frame 0 is the
- currently executing, or "innermost", frame (function call), frame
- 1 is the frame that called the innermost one. The highest numbered
- frame is the one for the main program.
+ Select and print stack frame N. Frame 0 is the currently
+ executing, or "innermost", frame (function call), frame 1 is the
+ frame that called the innermost one. The highest numbered frame is
+ the one for the main program. The printed information consists of
+ the frame number, function and argument names, source file, and
+ the source line.
`up' [COUNT]
Move COUNT (default 1) frames up the stack toward the outermost
frame. Then select and print the frame.

-File: gawk.info, Node: Dgawk Info, Next: Miscellaneous Dgawk Commands, Prev: Dgawk Stack, Up: List of Debugger Commands
+File: gawk.info, Node: Debugger Info, Next: Miscellaneous Debugger Commands, Prev: Execution Stack, Up: List of Debugger Commands
-14.3.5 Obtaining Information About The Program and The Debugger State
+14.3.5 Obtaining Information About the Program and the Debugger State
---------------------------------------------------------------------
Besides looking at the values of variables, there is often a need to get
other sorts of information about the state of your program and of the
-debugging environment itself. `dgawk' has one command which provides
-this information, appropriately called `info'. `info' is used with one
-of a number of arguments that tell it exactly what you want to know:
+debugging environment itself. The `gawk' debugger has one command which
+provides this information, appropriately called `info'. `info' is used
+with one of a number of arguments that tell it exactly what you want to
+know:
`info' WHAT
`i' WHAT
The value for WHAT should be one of the following:
`args'
- Arguments of the selected frame.
+ List arguments of the selected frame.
`break'
List all currently set breakpoints.
@@ -19485,22 +21425,22 @@ of a number of arguments that tell it exactly what you want to know:
List all items in the automatic display list.
`frame'
- Description of the selected stack frame.
+ Give a description of the selected stack frame.
`functions'
List all function definitions including source file names and
line numbers.
`locals'
- Local variables of the selected frame.
+ List local variables of the selected frame.
`source'
- The name of the current source file. Each time the program
- stops, the current source file is the file containing the
- current instruction. When `dgawk' first starts, the current
- source file is the first file included via the `-f' option.
- The `list FILENAME:LINENO' command can be used at any time to
- change the current source.
+ Print the name of the current source file. Each time the
+ program stops, the current source file is the file containing
+ the current instruction. When the debugger first starts, the
+ current source file is the first file included via the `-f'
+ option. The `list FILENAME:LINENO' command can be used at any
+ time to change the current source.
`sources'
List all program sources.
@@ -19524,7 +21464,7 @@ from a file. The commands are:
`history_size'
The maximum number of lines to keep in the history file
- `./.dgawk_history'. The default is 100.
+ `./.gawk_history'. The default is 100.
`listsize'
The number of lines that `list' prints. The default is 15.
@@ -19535,18 +21475,18 @@ from a file. The commands are:
standard output.
`prompt'
- The debugger prompt. The default is `dgawk> '.
+ The debugger prompt. The default is `gawk> '.
- `save_history [on | off]'
- Save command history to file `./.dgawk_history'. The default
+ `save_history' [`on' | `off']
+ Save command history to file `./.gawk_history'. The default
is `on'.
- `save_options [on | off]'
- Save current options to file `./.dgawkrc' upon exit. The
+ `save_options' [`on' | `off']
+ Save current options to file `./.gawkrc' upon exit. The
default is `on'. Options are read back in to the next
session upon startup.
- `trace [on | off]'
+ `trace' [`on' | `off']
Turn instruction tracing on or off. The default is `off'.
`save' FILENAME
@@ -19560,15 +21500,15 @@ from a file. The commands are:
ignored; they do _not_ repeat the last command. You can't restart
the program by having more than one `run' command in the file.
Also, the list of commands may include additional `source'
- commands; however, `dgawk' will not source the same file more than
- once in order to avoid infinite recursion.
+ commands; however, the `gawk' debugger will not source the same
+ file more than once in order to avoid infinite recursion.
In addition to, or instead of the `source' command, you can use
- the `-R FILE' or `--command=FILE' command-line options to execute
- commands from a file non-interactively (*note Options::.
+ the `-D FILE' or `--debug=FILE' command-line options to execute
+ commands from a file non-interactively (*note Options::).

-File: gawk.info, Node: Miscellaneous Dgawk Commands, Prev: Dgawk Info, Up: List of Debugger Commands
+File: gawk.info, Node: Miscellaneous Debugger Commands, Prev: Debugger Info, Up: List of Debugger Commands
14.3.6 Miscellaneous Commands
-----------------------------
@@ -19584,62 +21524,60 @@ categories, as follows:
partial dump of Davide Brini's obfuscated code (*note Signature
Program::) demonstrates:
- dgawk> dump
+ gawk> dump
-| # BEGIN
-|
- -| [ 2:0x89faef4] Op_rule : [in_rule = BEGIN] [source_file = brini.awk]
- -| [ 3:0x89fa428] Op_push_i : "~" [PERM|STRING|STRCUR]
- -| [ 3:0x89fa464] Op_push_i : "~" [PERM|STRING|STRCUR]
- -| [ 3:0x89fa450] Op_match :
- -| [ 3:0x89fa3ec] Op_store_var : O [do_reference = FALSE]
- -| [ 4:0x89fa48c] Op_push_i : "==" [PERM|STRING|STRCUR]
- -| [ 4:0x89fa4c8] Op_push_i : "==" [PERM|STRING|STRCUR]
- -| [ 4:0x89fa4b4] Op_equal :
- -| [ 4:0x89fa400] Op_store_var : o [do_reference = FALSE]
- -| [ 5:0x89fa4f0] Op_push : o
- -| [ 5:0x89fa4dc] Op_plus_i : 0 [PERM|NUMCUR|NUMBER]
- -| [ 5:0x89fa414] Op_push_lhs : o [do_reference = TRUE]
- -| [ 5:0x89fa4a0] Op_assign_plus :
- -| [ :0x89fa478] Op_pop :
- -| [ 6:0x89fa540] Op_push : O
- -| [ 6:0x89fa554] Op_push_i : "" [PERM|STRING|STRCUR]
- -| [ :0x89fa5a4] Op_no_op :
- -| [ 6:0x89fa590] Op_push : O
- -| [ :0x89fa5b8] Op_concat : [expr_count = 3] [concat_flag = 0]
- -| [ 6:0x89fa518] Op_store_var : x [do_reference = FALSE]
- -| [ 7:0x89fa504] Op_push_loop : [target_continue = 0x89fa568] [target_break = 0x89fa680]
- -| [ 7:0x89fa568] Op_push_lhs : X [do_reference = TRUE]
- -| [ 7:0x89fa52c] Op_postincrement :
- -| [ 7:0x89fa5e0] Op_push : x
- -| [ 7:0x89fa61c] Op_push : o
- -| [ 7:0x89fa5f4] Op_plus :
- -| [ 7:0x89fa644] Op_push : o
- -| [ 7:0x89fa630] Op_plus :
- -| [ 7:0x89fa5cc] Op_leq :
- -| [ :0x89fa57c] Op_jmp_false : [target_jmp = 0x89fa680]
- -| [ 7:0x89fa694] Op_push_i : "%c" [PERM|STRING|STRCUR]
- -| [ :0x89fa6d0] Op_no_op :
- -| [ 7:0x89fa608] Op_assign_concat : c
- -| [ :0x89fa6a8] Op_jmp : [target_jmp = 0x89fa568]
- -| [ :0x89fa680] Op_pop_loop :
+ -| [ 1:0xfcd340] Op_rule : [in_rule = BEGIN] [source_file = brini.awk]
+ -| [ 1:0xfcc240] Op_push_i : "~" [MALLOC|STRING|STRCUR]
+ -| [ 1:0xfcc2a0] Op_push_i : "~" [MALLOC|STRING|STRCUR]
+ -| [ 1:0xfcc280] Op_match :
+ -| [ 1:0xfcc1e0] Op_store_var : O
+ -| [ 1:0xfcc2e0] Op_push_i : "==" [MALLOC|STRING|STRCUR]
+ -| [ 1:0xfcc340] Op_push_i : "==" [MALLOC|STRING|STRCUR]
+ -| [ 1:0xfcc320] Op_equal :
+ -| [ 1:0xfcc200] Op_store_var : o
+ -| [ 1:0xfcc380] Op_push : o
+ -| [ 1:0xfcc360] Op_plus_i : 0 [MALLOC|NUMCUR|NUMBER]
+ -| [ 1:0xfcc220] Op_push_lhs : o [do_reference = true]
+ -| [ 1:0xfcc300] Op_assign_plus :
+ -| [ :0xfcc2c0] Op_pop :
+ -| [ 1:0xfcc400] Op_push : O
+ -| [ 1:0xfcc420] Op_push_i : "" [MALLOC|STRING|STRCUR]
+ -| [ :0xfcc4a0] Op_no_op :
+ -| [ 1:0xfcc480] Op_push : O
+ -| [ :0xfcc4c0] Op_concat : [expr_count = 3] [concat_flag = 0]
+ -| [ 1:0xfcc3c0] Op_store_var : x
+ -| [ 1:0xfcc440] Op_push_lhs : X [do_reference = true]
+ -| [ 1:0xfcc3a0] Op_postincrement :
+ -| [ 1:0xfcc4e0] Op_push : x
+ -| [ 1:0xfcc540] Op_push : o
+ -| [ 1:0xfcc500] Op_plus :
+ -| [ 1:0xfcc580] Op_push : o
+ -| [ 1:0xfcc560] Op_plus :
+ -| [ 1:0xfcc460] Op_leq :
+ -| [ :0xfcc5c0] Op_jmp_false : [target_jmp = 0xfcc5e0]
+ -| [ 1:0xfcc600] Op_push_i : "%c" [MALLOC|STRING|STRCUR]
+ -| [ :0xfcc660] Op_no_op :
+ -| [ 1:0xfcc520] Op_assign_concat : c
+ -| [ :0xfcc620] Op_jmp : [target_jmp = 0xfcc440]
-|
...
-|
- -| [ 8:0x89fa658] Op_K_printf : [expr_count = 17] [redir_type = ""]
- -| [ :0x89fa374] Op_no_op :
- -| [ :0x89fa3d8] Op_atexit :
- -| [ :0x89fa6bc] Op_stop :
- -| [ :0x89fa39c] Op_no_op :
- -| [ :0x89fa3b0] Op_after_beginfile :
- -| [ :0x89fa388] Op_no_op :
- -| [ :0x89fa3c4] Op_after_endfile :
- dgawk>
+ -| [ 2:0xfcc5a0] Op_K_printf : [expr_count = 17] [redir_type = ""]
+ -| [ :0xfcc140] Op_no_op :
+ -| [ :0xfcc1c0] Op_atexit :
+ -| [ :0xfcc640] Op_stop :
+ -| [ :0xfcc180] Op_no_op :
+ -| [ :0xfcd150] Op_after_beginfile :
+ -| [ :0xfcc160] Op_no_op :
+ -| [ :0xfcc1a0] Op_after_endfile :
+ gawk>
`help'
`h'
- Print a list of all of the `dgawk' commands with a short summary
- of their usage. `help COMMAND' prints the information about the
- command COMMAND.
+ Print a list of all of the `gawk' debugger commands with a short
+ summary of their usage. `help COMMAND' prints the information
+ about the command COMMAND.
`list' [`-' | `+' | N | FILENAME`:'N | N-M | FUNCTION]
`l' [`-' | `+' | N | FILENAME`:'N | N-M | FUNCTION]
@@ -19647,7 +21585,7 @@ categories, as follows:
or the file named FILENAME. The possible arguments to `list' are
as follows:
- `-'
+ `-' (Minus)
Print lines before the lines last printed.
`+'
@@ -19672,12 +21610,12 @@ categories, as follows:
`q'
Exit the debugger. Debugging is great fun, but sometimes we all
have to tend to other obligations in life, and sometimes we find
- the bug, and are free to go on to the next one! As we saw above,
- if you are running a program, `dgawk' warns you if you
- accidentally type `q' or `quit', to make sure you really want to
- quit.
+ the bug, and are free to go on to the next one! As we saw
+ earlier, if you are running a program, the debugger warns you if
+ you accidentally type `q' or `quit', to make sure you really want
+ to quit.
-`trace' `on' | `off'
+`trace' [`on' | `off']
Turn on or off a continuous printing of instructions which are
about to be executed, along with printing the `awk' line which they
implement. The default is `off'.
@@ -19688,14 +21626,15 @@ categories, as follows:

-File: gawk.info, Node: Readline Support, Next: Dgawk Limitations, Prev: List of Debugger Commands, Up: Debugger
+File: gawk.info, Node: Readline Support, Next: Limitations, Prev: List of Debugger Commands, Up: Debugger
14.4 Readline Support
=====================
-If `dgawk' is compiled with the `readline' library, you can take
-advantage of that library's command completion and history expansion
-features. The following types of completion are available:
+If `gawk' is compiled with the `readline' library
+(http://cnswww.cns.cwru.edu/php/chet/readline/readline.html), you can
+take advantage of that library's command completion and history
+expansion features. The following types of completion are available:
Command completion
Command names.
@@ -19715,66 +21654,4550 @@ Variable name completion

-File: gawk.info, Node: Dgawk Limitations, Prev: Readline Support, Up: Debugger
+File: gawk.info, Node: Limitations, Next: Debugging Summary, Prev: Readline Support, Up: Debugger
-14.5 Limitations and Future Plans
-=================================
+14.5 Limitations
+================
-We hope you find `dgawk' useful and enjoyable to work with, but as with
-any program, especially in its early releases, it still has some
-limitations. A few which are worth being aware of are:
+We hope you find the `gawk' debugger useful and enjoyable to work with,
+but as with any program, especially in its early releases, it still has
+some limitations. A few which are worth being aware of are:
- * At this point, `dgawk' does not give a detailed explanation of
+ * At this point, the debugger does not give a detailed explanation of
what you did wrong when you type in something it doesn't like.
Rather, it just responds `syntax error'. When you do figure out
what your mistake was, though, you'll feel like a real guru.
- * If you perused the dump of opcodes in *Note Miscellaneous Dgawk
- Commands::, (or if you are already familiar with `gawk' internals),
+ * If you perused the dump of opcodes in *note Miscellaneous Debugger
+ Commands:: (or if you are already familiar with `gawk' internals),
you will realize that much of the internal manipulation of data in
`gawk', as in many interpreters, is done on a stack. `Op_push',
- `Op_pop', etc., are the "bread and butter" of most `gawk' code.
- Unfortunately, as of now, `dgawk' does not allow you to examine
- the stack's contents.
+ `Op_pop', and the like, are the "bread and butter" of most `gawk'
+ code.
- That is, the intermediate results of expression evaluation are on
- the stack, but cannot be printed. Rather, only variables which
- are defined in the program can be printed. Of course, a
- workaround for this is to use more explicit variables at the
- debugging stage and then change back to obscure, perhaps more
- optimal code later.
+ Unfortunately, as of now, the `gawk' debugger does not allow you
+ to examine the stack's contents. That is, the intermediate
+ results of expression evaluation are on the stack, but cannot be
+ printed. Rather, only variables which are defined in the program
+ can be printed. Of course, a workaround for this is to use more
+ explicit variables at the debugging stage and then change back to
+ obscure, perhaps more optimal code later.
* There is no way to look "inside" the process of compiling regular
expressions to see if you got it right. As an `awk' programmer,
- you are expected to know what `/[^[:alnum:][:blank:]]/' means.
+ you are expected to know the meaning of `/[^[:alnum:][:blank:]]/'.
+
+ * The `gawk' debugger is designed to be used by running a program
+ (with all its parameters) on the command line, as described in
+ *note Debugger Invocation::. There is no way (as of now) to
+ attach or "break in" to a running program. This seems reasonable
+ for a language which is used mainly for quickly executing, short
+ programs.
+
+ * The `gawk' debugger only accepts source supplied with the `-f'
+ option.
+
+
+File: gawk.info, Node: Debugging Summary, Prev: Limitations, Up: Debugger
+
+14.6 Summary
+============
+
+ * Programs rarely work correctly the first time. Finding bugs is
+ "debugging" and a program that helps you find bugs is a
+ "debugger". `gawk' has a built-in debugger that works very
+ similarly to the GNU Debugger, GDB.
+
+ * Debuggers let you step through your program one statement at a
+ time, examine and change variable and array values, and do a
+ number of other things that let you understand what your program
+ is actually doing (as opposed to what it is supposed to do).
+
+ * Like most debuggers, the `gawk' debugger works in terms of stack
+ frames, and lets you set both breakpoints (stop at a point in the
+ code) and watchpoints (stop when a data value changes).
+
+ * The debugger command set is fairly complete, providing control over
+ breakpoints, execution, viewing and changing data, working with
+ the stack, getting information, and other tasks.
+
+ * If the `readline' library is available when `gawk' is compiled, it
+ is used by the debugger to provide command-line history and
+ editing.
+
+
+
+File: gawk.info, Node: Arbitrary Precision Arithmetic, Next: Dynamic Extensions, Prev: Debugger, Up: Top
+
+15 Arithmetic and Arbitrary-Precision Arithmetic with `gawk'
+************************************************************
+
+This major node introduces some basic concepts relating to how
+computers do arithmetic and defines some important terms. It then
+proceeds to describe floating-point arithmetic, which is what `awk'
+uses for all its computations, including a discussion of
+arbitrary-precision floating-point arithmetic, which is a feature
+available only in `gawk'. It continues on to present
+arbitrary-precision integers, and concludes with a description of some
+points where `gawk' and the POSIX standard are not quite in agreement.
+
+ NOTE: Most users of `gawk' can safely skip this chapter. But if
+ you want to do scientific calculations with `gawk', this is the
+ place to be.
+
+* Menu:
+
+* Computer Arithmetic:: A quick intro to computer math.
+* Math Definitions:: Defining terms used.
+* MPFR features:: The MPFR features in `gawk'.
+* FP Math Caution:: Things to know.
+* Arbitrary Precision Integers:: Arbitrary Precision Integer Arithmetic with
+ `gawk'.
+* POSIX Floating Point Problems:: Standards Versus Existing Practice.
+* Floating point summary:: Summary of floating point discussion.
+
+
+File: gawk.info, Node: Computer Arithmetic, Next: Math Definitions, Up: Arbitrary Precision Arithmetic
+
+15.1 A General Description of Computer Arithmetic
+=================================================
+
+Until now, we have worked with data as either numbers or strings.
+Ultimately, however, computers represent everything in terms of "binary
+digits", or "bits". A decimal digit can take on any of 10 values: zero
+through nine. A binary digit can take on any of two values, zero or
+one. Using binary, computers (and computer software) can represent and
+manipulate numerical and character data. In general, the more bits you
+can use to represent a particular thing, the greater the range of
+possible values it can take on.
+
+ Modern computers support at least two, and often more, ways to do
+arithmetic. Each kind of arithmetic uses a different representation
+(organization of the bits) for the numbers. The kinds of arithmetic
+that interest us are:
+
+Decimal arithmetic
+ This is the kind of arithmetic you learned in elementary school,
+ using paper and pencil (and/or a calculator). In theory, numbers
+ can have an arbitrary number of digits on either side (or both
+ sides) of the decimal point, and the results of a computation are
+ always exact.
+
+ Some modern system can do decimal arithmetic in hardware, but
+ usually you need a special software library to provide access to
+ these instructions. There are also libraries that do decimal
+ arithmetic entirely in software.
+
+ Despite the fact that some users expect `gawk' to be performing
+ decimal arithmetic,(1) it does not do so.
+
+Integer arithmetic
+ 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.
+
+ In computers, integer values come in two flavors: "signed" and
+ "unsigned". Signed values may be negative or positive, whereas
+ unsigned values are always positive (i.e., greater than or equal
+ to zero).
+
+ In computer systems, integer arithmetic is exact, but the possible
+ range of values is limited. Integer arithmetic is generally
+ faster than floating-point arithmetic.
+
+Floating-point arithmetic
+ Floating-point numbers represent what were called in school "real"
+ numbers (i.e., those that 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 than can integers.
+ The disadvantage is that there are numbers that they cannot
+ represent exactly.
+
+ Modern systems support floating-point arithmetic in hardware, with
+ a limited range of values. There are software libraries that allow
+ the use of arbitrary-precision floating-point calculations.
+
+ POSIX `awk' uses "double-precision" floating-point numbers, which
+ can hold more digits than "single-precision" floating-point
+ numbers. `gawk' has facilities for performing arbitrary-precision
+ floating-point arithmetic, which we describe in more detail
+ shortly.
+
+ Computers work with integer and floating-point values of different
+ranges. Integer values are usually either 32 or 64 bits in size.
+Single-precision floating-point values occupy 32 bits, whereas
+double-precision floating-point values occupy 64 bits. Floating-point
+values are always signed. The possible ranges of values are shown in
+*note table-numeric-ranges::.
+
+Numeric representation Minimum value Maximum value
+---------------------------------------------------------------------------
+32-bit signed integer -2,147,483,648 2,147,483,647
+32-bit unsigned integer 0 4,294,967,295
+64-bit signed integer -9,223,372,036,854,775,8089,223,372,036,854,775,807
+64-bit unsigned integer 0 18,446,744,073,709,551,615
+Single-precision `1.175494e-38' `3.402823e+38'
+floating point
+(approximate)
+Double-precision `2.225074e-308' `1.797693e+308'
+floating point
+(approximate)
+
+Table 15.1: Value ranges for different numeric representations
+
+ ---------- Footnotes ----------
+
+ (1) We don't know why they expect this, but they do.
+
+
+File: gawk.info, Node: Math Definitions, Next: MPFR features, Prev: Computer Arithmetic, Up: Arbitrary Precision Arithmetic
+
+15.2 Other Stuff to Know
+========================
+
+The rest of this major node uses a number of terms. Here are some
+informal definitions that should help you work your way through the
+material here.
+
+"Accuracy"
+ A floating-point calculation's accuracy is how close it comes to
+ the real (paper and pencil) value.
+
+"Error"
+ The difference between what the result of a computation "should be"
+ and what it actually is. It is best to minimize error as much as
+ possible.
+
+"Exponent"
+ The order of magnitude of a value; some number of bits in a
+ floating-point value store the exponent.
+
+"Inf"
+ A special value representing infinity. Operations involving another
+ number and infinity produce infinity.
+
+"NaN"
+ "Not A Number."(1) A special value that results from attempting a
+ calculation that has no answer as a real number. In such a case,
+ programs can either receive a floating-point exception, or get
+ `NaN' back as the result. The IEEE 754 standard recommends that
+ systems return `NaN'. Some examples:
+
+ `sqrt(-1)'
+ This makes sense in the range of complex numbers, but not in
+ the range of real numbers, so the result is `NaN'.
+
+ `log(-8)'
+ -8 is out of the domain of `log()', so the result is `NaN'.
+
+"Normalized"
+ How the significand (see later in this list) is usually stored. The
+ value is adjusted so that the first bit is one, and then that
+ leading one is assumed instead of physically stored. This
+ provides one extra bit of precision.
+
+"Precision"
+ The number of bits used to represent a floating-point number. The
+ more bits, the more digits you can represent. Binary and decimal
+ precisions are related approximately, according to the formula:
+
+ PREC = 3.322 * DPS
+
+ Here, PREC denotes the binary precision (measured in bits) and DPS
+ (short for decimal places) is the decimal digits.
+
+"Rounding mode"
+ How numbers are rounded up or down when necessary. More details
+ are provided later.
+
+"Significand"
+ A floating-point value consists the significand multiplied by 10
+ to the power of the exponent. For example, in `1.2345e67', the
+ significand is `1.2345'.
+
+"Stability"
+ From the Wikipedia article on numerical stability
+ (http://en.wikipedia.org/wiki/Numerical_stability): "Calculations
+ that can be proven not to magnify approximation errors are called
+ "numerically stable"."
+
+ See the Wikipedia article on accuracy and precision
+(http://en.wikipedia.org/wiki/Accuracy_and_precision) for more
+information on some of those terms.
+
+ On modern systems, floating-point hardware uses the representation
+and operations defined by the IEEE 754 standard. Three of the standard
+IEEE 754 types are 32-bit single precision, 64-bit double precision,
+and 128-bit quadruple precision. The standard also specifies extended
+precision formats to allow greater precisions and larger exponent
+ranges. (`awk' uses only the 64-bit double-precision format.)
+
+ *note table-ieee-formats:: lists the precision and exponent field
+values for the basic IEEE 754 binary formats:
+
+Name Total bits Precision Minimum Maximum
+ exponent exponent
+---------------------------------------------------------------------------
+Single 32 24 -126 +127
+Double 64 53 -1022 +1023
+Quadruple 128 113 -16382 +16383
+
+Table 15.2: Basic IEEE format values
+
+ NOTE: The precision numbers include the implied leading one that
+ gives them one extra bit of significand.
+
+ ---------- Footnotes ----------
+
+ (1) Thanks to Michael Brennan for this description, which we have
+paraphrased, and for the examples.
+
+
+File: gawk.info, Node: MPFR features, Next: FP Math Caution, Prev: Math Definitions, Up: Arbitrary Precision Arithmetic
+
+15.3 Arbitrary-Precision Arithmetic Features in `gawk'
+======================================================
+
+By default, `gawk' uses the double-precision floating-point values
+supplied by the hardware of the system it runs on. However, if it was
+compiled to do so, `gawk' uses the GNU MPFR (http://www.mpfr.org) and
+GNU MP (http://gmplib.org) (GMP) libraries for arbitrary-precision
+arithmetic on numbers. You can see if MPFR support is available like
+so:
+
+ $ gawk --version
+ -| GNU Awk 4.1.2, API: 1.1 (GNU MPFR 3.1.0-p3, GNU MP 5.0.2)
+ -| Copyright (C) 1989, 1991-2015 Free Software Foundation.
+ ...
+
+(You may see different version numbers than what's shown here. That's
+OK; what's important is to see that GNU MPFR and GNU MP are listed in
+the output.)
+
+ Additionally, there are a few elements available in the `PROCINFO'
+array to provide information about the MPFR and GMP libraries (*note
+Auto-set::).
+
+ The MPFR library provides precise control over precisions and
+rounding modes, and gives correctly rounded, reproducible,
+platform-independent results. With the `-M' command-line option, all
+floating-point arithmetic operators and numeric functions can yield
+results to any desired precision level supported by MPFR.
+
+ Two predefined variables, `PREC' and `ROUNDMODE', provide control
+over the working precision and the rounding mode. The precision and
+the rounding mode are set globally for every operation to follow.
+*Note Setting precision::, and *note Setting the rounding mode::, for
+more information.
+
+
+File: gawk.info, Node: FP Math Caution, Next: Arbitrary Precision Integers, Prev: MPFR features, Up: Arbitrary Precision Arithmetic
+
+15.4 Floating-Point Arithmetic: Caveat Emptor!
+==============================================
+
+ Math class is tough! -- Teen Talk Barbie, July 1992
+
+ This minor node provides a high level overview of the issues
+involved when doing lots of floating-point arithmetic.(1) The
+discussion applies to both hardware and arbitrary-precision
+floating-point arithmetic.
+
+ CAUTION: The material here is purposely general. If you need to do
+ serious computer arithmetic, you should do some research first,
+ and not rely just on what we tell you.
+
+* Menu:
+
+* Inexactness of computations:: Floating point math is not exact.
+* Getting Accuracy:: Getting more accuracy takes some work.
+* Try To Round:: Add digits and round.
+* Setting precision:: How to set the precision.
+* Setting the rounding mode:: How to set the rounding mode.
+
+ ---------- Footnotes ----------
+
+ (1) There is a very nice paper on floating-point arithmetic
+(http://www.validlab.com/goldberg/paper.pdf) by David Goldberg, "What
+Every Computer Scientist Should Know About Floating-point Arithmetic,"
+`ACM Computing Surveys' *23*, 1 (1991-03), 5-48. This is worth reading
+if you are interested in the details, but it does require a background
+in computer science.
+
+
+File: gawk.info, Node: Inexactness of computations, Next: Getting Accuracy, Up: FP Math Caution
+
+15.4.1 Floating-Point Arithmetic Is Not Exact
+---------------------------------------------
+
+Binary floating-point representations and arithmetic are inexact.
+Simple values like 0.1 cannot be precisely represented using binary
+floating-point numbers, and the limited precision of floating-point
+numbers means that slight changes in the order of operations or the
+precision of intermediate storage can change the result. To make
+matters worse, with arbitrary-precision floating-point arithmetic, you
+can set the precision before starting a computation, but then you
+cannot be sure of the number of significant decimal places in the final
+result.
+
+* Menu:
+
+* Inexact representation:: Numbers are not exactly represented.
+* Comparing FP Values:: How to compare floating point values.
+* Errors accumulate:: Errors get bigger as they go.
+
+
+File: gawk.info, Node: Inexact representation, Next: Comparing FP Values, Up: Inexactness of computations
+
+15.4.1.1 Many Numbers Cannot Be Represented Exactly
+...................................................
+
+So, before you start to write any code, you should think about what you
+really want and what's really happening. Consider the two numbers in
+the following example:
+
+ x = 0.875 # 1/2 + 1/4 + 1/8
+ y = 0.425
+
+ Unlike the number in `y', the number stored in `x' is exactly
+representable in binary because it can be written as a finite sum of
+one or more fractions whose denominators are all powers of two. When
+`gawk' reads a floating-point number from program source, it
+automatically rounds that number to whatever precision your machine
+supports. If you try to print the numeric content of a variable using
+an output format string of `"%.17g"', it may not produce the same
+number as you assigned to it:
+
+ $ gawk 'BEGIN { x = 0.875; y = 0.425
+ > printf("%0.17g, %0.17g\n", x, y) }'
+ -| 0.875, 0.42499999999999999
+
+ Often the error is so small you do not even notice it, and if you do,
+you can always specify how much precision you would like in your output.
+Usually this is a format string like `"%.15g"', which when used in the
+previous example, produces an output identical to the input.
+
+
+File: gawk.info, Node: Comparing FP Values, Next: Errors accumulate, Prev: Inexact representation, Up: Inexactness of computations
+
+15.4.1.2 Be Careful Comparing Values
+....................................
+
+Because the underlying representation can be a little bit off from the
+exact value, comparing floating-point values to see if they are exactly
+equal is generally a bad idea. Here is an example where it does not
+work like you would expect:
+
+ $ gawk 'BEGIN { print (0.1 + 12.2 == 12.3) }'
+ -| 0
+
+ The general wisdom when comparing floating-point values is to see if
+they are within some small range of each other (called a "delta", or
+"tolerance"). You have to decide how small a delta is important to
+you. Code to do this looks something like the following:
+
+ delta = 0.00001 # for example
+ difference = abs(a) - abs(b) # subtract the two values
+ if (difference < delta)
+ # all ok
+ else
+ # not ok
+
+(We assume that you have a simple absolute value function named `abs()'
+defined elsewhere in your program.)
+
+
+File: gawk.info, Node: Errors accumulate, Prev: Comparing FP Values, Up: Inexactness of computations
+
+15.4.1.3 Errors Accumulate
+..........................
+
+The loss of accuracy during a single computation with floating-point
+numbers usually isn't enough to worry about. However, if you compute a
+value which is the result of a sequence of floating-point operations,
+the error can accumulate and greatly affect the computation itself.
+Here is an attempt to compute the value of pi using one of its many
+series representations:
+
+ BEGIN {
+ x = 1.0 / sqrt(3.0)
+ n = 6
+ for (i = 1; i < 30; i++) {
+ n = n * 2.0
+ x = (sqrt(x * x + 1) - 1) / x
+ printf("%.15f\n", n * x)
+ }
+ }
+
+ When run, the early errors propagate through later computations,
+causing the loop to terminate prematurely after attempting to divide by
+zero:
+
+ $ gawk -f pi.awk
+ -| 3.215390309173475
+ -| 3.159659942097510
+ -| 3.146086215131467
+ -| 3.142714599645573
+ ...
+ -| 3.224515243534819
+ -| 2.791117213058638
+ -| 0.000000000000000
+ error--> gawk: pi.awk:6: fatal: division by zero attempted
+
+ Here is an additional example where the inaccuracies in internal
+representations yield an unexpected result:
+
+ $ gawk 'BEGIN {
+ > for (d = 1.1; d <= 1.5; d += 0.1) # loop five times (?)
+ > i++
+ > print i
+ > }'
+ -| 4
+
+
+File: gawk.info, Node: Getting Accuracy, Next: Try To Round, Prev: Inexactness of computations, Up: FP Math Caution
+
+15.4.2 Getting the Accuracy You Need
+------------------------------------
+
+Can arbitrary-precision arithmetic give exact results? There are no
+easy answers. The standard rules of algebra often do not apply when
+using floating-point arithmetic. Among other things, the distributive
+and associative laws do not hold completely, and order of operation may
+be important for your computation. Rounding error, cumulative precision
+loss and underflow are often troublesome.
+
+ When `gawk' tests the expressions `0.1 + 12.2' and `12.3' for
+equality using the machine double-precision arithmetic, it decides that
+they are not equal! (*Note Comparing FP Values::.) You can get the
+result you want by increasing the precision; 56 bits in this case does
+the job:
+
+ $ gawk -M -v PREC=56 'BEGIN { print (0.1 + 12.2 == 12.3) }'
+ -| 1
+
+ If adding more bits is good, perhaps adding even more bits of
+precision is better? Here is what happens if we use an even larger
+value of `PREC':
+
+ $ gawk -M -v PREC=201 'BEGIN { print (0.1 + 12.2 == 12.3) }'
+ -| 0
+
+ This is not a bug in `gawk' or in the MPFR library. It is easy to
+forget that the finite number of bits used to store the value is often
+just an approximation after proper rounding. The test for equality
+succeeds if and only if _all_ bits in the two operands are exactly the
+same. Because this is not necessarily true after floating-point
+computations with a particular precision and effective rounding mode, a
+straight test for equality may not work. Instead, compare the two
+numbers to see if they are within the desirable delta of each other.
+
+ In applications where 15 or fewer decimal places suffice, hardware
+double-precision arithmetic can be adequate, and is usually much faster.
+But you need to keep in mind that every floating-point operation can
+suffer a new rounding error with catastrophic consequences, as
+illustrated by our earlier attempt to compute the value of pi. Extra
+precision can greatly enhance the stability and the accuracy of your
+computation in such cases.
+
+ Repeated addition is not necessarily equivalent to multiplication in
+floating-point arithmetic. In the example in *note Errors accumulate:::
+
+ $ gawk 'BEGIN {
+ > for (d = 1.1; d <= 1.5; d += 0.1) # loop five times (?)
+ > i++
+ > print i
+ > }'
+ -| 4
+
+you may or may not succeed in getting the correct result by choosing an
+arbitrarily large value for `PREC'. Reformulation of the problem at
+hand is often the correct approach in such situations.
+
+
+File: gawk.info, Node: Try To Round, Next: Setting precision, Prev: Getting Accuracy, Up: FP Math Caution
+
+15.4.3 Try a Few Extra Bits of Precision and Rounding
+-----------------------------------------------------
+
+Instead of arbitrary-precision floating-point arithmetic, often all you
+need is an adjustment of your logic or a different order for the
+operations in your calculation. The stability and the accuracy of the
+computation of pi in the earlier example can be enhanced by using the
+following simple algebraic transformation:
+
+ (sqrt(x * x + 1) - 1) / x == x / (sqrt(x * x + 1) + 1)
+
+After making this change, the program converges to pi in under 30
+iterations:
+
+ $ gawk -f pi2.awk
+ -| 3.215390309173473
+ -| 3.159659942097501
+ -| 3.146086215131436
+ -| 3.142714599645370
+ -| 3.141873049979825
+ ...
+ -| 3.141592653589797
+ -| 3.141592653589797
+
+
+File: gawk.info, Node: Setting precision, Next: Setting the rounding mode, Prev: Try To Round, Up: FP Math Caution
+
+15.4.4 Setting the Precision
+----------------------------
+
+`gawk' uses a global working precision; it does not keep track of the
+precision or accuracy of individual numbers. Performing an arithmetic
+operation or calling a built-in function rounds the result to the
+current working precision. The default working precision is 53 bits,
+which you can modify using the predefined variable `PREC'. You can also
+set the value to one of the predefined case-insensitive strings shown
+in *note table-predefined-precision-strings::, to emulate an IEEE 754
+binary format.
+
+`PREC' IEEE 754 Binary Format
+---------------------------------------------------
+`"half"' 16-bit half-precision
+`"single"' Basic 32-bit single precision
+`"double"' Basic 64-bit double precision
+`"quad"' Basic 128-bit quadruple precision
+`"oct"' 256-bit octuple precision
+
+Table 15.3: Predefined precision strings for `PREC'
+
+ The following example illustrates the effects of changing precision
+on arithmetic operations:
+
+ $ gawk -M -v PREC=100 'BEGIN { x = 1.0e-400; print x + 0
+ > PREC = "double"; print x + 0 }'
+ -| 1e-400
+ -| 0
+
+ CAUTION: Be wary of floating-point constants! When reading a
+ floating-point constant from program source code, `gawk' uses the
+ default precision (that of a C `double'), unless overridden by an
+ assignment to the special variable `PREC' on the command line, to
+ store it internally as an MPFR number. Changing the precision
+ using `PREC' in the program text does _not_ change the precision
+ of a constant.
+
+ If you need to represent a floating-point constant at a higher
+ precision than the default and cannot use a command-line
+ assignment to `PREC', you should either specify the constant as a
+ string, or as a rational number, whenever possible. The following
+ example illustrates the differences among various ways to print a
+ floating-point constant:
+
+ $ gawk -M 'BEGIN { PREC = 113; printf("%0.25f\n", 0.1) }'
+ -| 0.1000000000000000055511151
+ $ gawk -M -v PREC=113 'BEGIN { printf("%0.25f\n", 0.1) }'
+ -| 0.1000000000000000000000000
+ $ gawk -M 'BEGIN { PREC = 113; printf("%0.25f\n", "0.1") }'
+ -| 0.1000000000000000000000000
+ $ gawk -M 'BEGIN { PREC = 113; printf("%0.25f\n", 1/10) }'
+ -| 0.1000000000000000000000000
+
+
+File: gawk.info, Node: Setting the rounding mode, Prev: Setting precision, Up: FP Math Caution
+
+15.4.5 Setting the Rounding Mode
+--------------------------------
+
+The `ROUNDMODE' variable provides program level control over the
+rounding mode. The correspondence between `ROUNDMODE' and the IEEE
+rounding modes is shown in *note table-gawk-rounding-modes::.
+
+Rounding Mode IEEE Name `ROUNDMODE'
+---------------------------------------------------------------------------
+Round to nearest, ties to even `roundTiesToEven' `"N"' or `"n"'
+Round toward plus Infinity `roundTowardPositive' `"U"' or `"u"'
+Round toward negative Infinity `roundTowardNegative' `"D"' or `"d"'
+Round toward zero `roundTowardZero' `"Z"' or `"z"'
+Round to nearest, ties away `roundTiesToAway' `"A"' or `"a"'
+from zero
+
+Table 15.4: `gawk' rounding modes
+
+ `ROUNDMODE' has the default value `"N"', which selects the IEEE 754
+rounding mode `roundTiesToEven'. In *note Table 15.4:
+table-gawk-rounding-modes, the value `"A"' selects `roundTiesToAway'.
+This is only available if your version of the MPFR library supports it;
+otherwise, setting `ROUNDMODE' to `"A"' has no effect.
+
+ The default mode `roundTiesToEven' is the most preferred, but the
+least intuitive. This method does the obvious thing for most values, by
+rounding them up or down to the nearest digit. For example, rounding
+1.132 to two digits yields 1.13, and rounding 1.157 yields 1.16.
+
+ However, when it comes to rounding a value that is exactly halfway
+between, things do not work the way you probably learned in school. In
+this case, the number is rounded to the nearest even digit. So
+rounding 0.125 to two digits rounds down to 0.12, but rounding 0.6875
+to three digits rounds up to 0.688. You probably have already
+encountered this rounding mode when using `printf' to format
+floating-point numbers. For example:
+
+ BEGIN {
+ x = -4.5
+ for (i = 1; i < 10; i++) {
+ x += 1.0
+ printf("%4.1f => %2.0f\n", x, x)
+ }
+ }
+
+produces the following output when run on the author's system:(1)
+
+ -3.5 => -4
+ -2.5 => -2
+ -1.5 => -2
+ -0.5 => 0
+ 0.5 => 0
+ 1.5 => 2
+ 2.5 => 2
+ 3.5 => 4
+ 4.5 => 4
+
+ The theory behind `roundTiesToEven' is that it more or less evenly
+distributes upward and downward rounds of exact halves, which might
+cause any accumulating round-off error to cancel itself out. This is the
+default rounding mode for IEEE 754 computing functions and operators.
+
+ The other rounding modes are rarely used. Round toward positive
+infinity (`roundTowardPositive') and round toward negative infinity
+(`roundTowardNegative') are often used to implement interval
+arithmetic, where you adjust the rounding mode to calculate upper and
+lower bounds for the range of output. The `roundTowardZero' mode can be
+used for converting floating-point numbers to integers. The rounding
+mode `roundTiesToAway' rounds the result to the nearest number and
+selects the number with the larger magnitude if a tie occurs.
+
+ Some numerical analysts will tell you that your choice of rounding
+style has tremendous impact on the final outcome, and advise you to
+wait until final output for any rounding. Instead, you can often avoid
+round-off error problems by setting the precision initially to some
+value sufficiently larger than the final desired precision, so that the
+accumulation of round-off error does not influence the outcome. If you
+suspect that results from your computation are sensitive to
+accumulation of round-off error, look for a significant difference in
+output when you change the rounding mode to be sure.
+
+ ---------- Footnotes ----------
+
+ (1) It is possible for the output to be completely different if the
+C library in your system does not use the IEEE 754 even-rounding rule
+to round halfway cases for `printf'.
+
+
+File: gawk.info, Node: Arbitrary Precision Integers, Next: POSIX Floating Point Problems, Prev: FP Math Caution, Up: Arbitrary Precision Arithmetic
+
+15.5 Arbitrary-Precision Integer Arithmetic with `gawk'
+=======================================================
+
+When given the `-M' option, `gawk' performs all integer arithmetic
+using GMP arbitrary-precision integers. Any number that looks like an
+integer in a source or data file is stored as an arbitrary-precision
+integer. The size of the integer is limited only by the available
+memory. For example, the following computes 5^4^3^2, the result of
+which is beyond the limits of ordinary hardware double-precision
+floating-point values:
+
+ $ gawk -M 'BEGIN {
+ > x = 5^4^3^2
+ > print "number of digits =", length(x)
+ > print substr(x, 1, 20), "...", substr(x, length(x) - 19, 20)
+ > }'
+ -| number of digits = 183231
+ -| 62060698786608744707 ... 92256259918212890625
+
+ If instead you were to compute the same value using
+arbitrary-precision floating-point values, the precision needed for
+correct output (using the formula `prec = 3.322 * dps'), would be 3.322
+x 183231, or 608693.
+
+ The result from an arithmetic operation with an integer and a
+floating-point value is a floating-point value with a precision equal
+to the working precision. The following program calculates the eighth
+term in Sylvester's sequence(1) using a recurrence:
+
+ $ gawk -M 'BEGIN {
+ > s = 2.0
+ > for (i = 1; i <= 7; i++)
+ > s = s * (s - 1) + 1
+ > print s
+ > }'
+ -| 113423713055421845118910464
+
+ The output differs from the actual number,
+113,423,713,055,421,844,361,000,443, because the default precision of
+53 bits is not enough to represent the floating-point results exactly.
+You can either increase the precision (100 bits is enough in this
+case), or replace the floating-point constant `2.0' with an integer, to
+perform all computations using integer arithmetic to get the correct
+output.
+
+ Sometimes `gawk' must implicitly convert an arbitrary-precision
+integer into an arbitrary-precision floating-point value. This is
+primarily because the MPFR library does not always provide the relevant
+interface to process arbitrary-precision integers or mixed-mode numbers
+as needed by an operation or function. In such a case, the precision is
+set to the minimum value necessary for exact conversion, and the working
+precision is not used for this purpose. If this is not what you need or
+want, you can employ a subterfuge, and convert the integer to floating
+point first, like this:
+
+ gawk -M 'BEGIN { n = 13; print (n + 0.0) % 2.0 }'
+
+ You can avoid this issue altogether by specifying the number as a
+floating-point value to begin with:
+
+ gawk -M 'BEGIN { n = 13.0; print n % 2.0 }'
+
+ Note that for this particular example, it is likely best to just use
+the following:
+
+ gawk -M 'BEGIN { n = 13; print n % 2 }'
+
+ When dividing two arbitrary precision integers with either `/' or
+`%', the result is typically an arbitrary precision floating point
+value (unless the denominator evenly divides into the numerator). In
+order to do integer division or remainder with arbitrary precision
+integers, use the built-in `div()' function (*note Numeric Functions::).
+
+ You can simulate the `div()' function in standard `awk' using this
+user-defined function:
+
+ # div --- do integer division
+
+ function div(numerator, denominator, result)
+ {
+ split("", result)
+
+ numerator = int(numerator)
+ denominator = int(denominator)
+ result["quotient"] = int(numerator / denominator)
+ result["remainder"] = int(numerator % denominator)
+
+ return 0.0
+ }
+
+ The following example program, contributed by Katie Wasserman, uses
+`div()' to compute the digits of pi to as many places as you choose to
+set:
+
+ # pi.awk --- compute the digits of pi
+
+ BEGIN {
+ digits = 100000
+ two = 2 * 10 ^ digits
+ pi = two
+ for (m = digits * 4; m > 0; --m) {
+ d = m * 2 + 1
+ x = pi * m
+ div(x, d, result)
+ pi = result["quotient"]
+ pi = pi + two
+ }
+ print pi
+ }
+
+ When asked about the algorithm used, Katie replied:
+
+ It's not that well known but it's not that obscure either. It's
+ Euler's modification to Newton's method for calculating pi. Take
+ a look at lines (23) - (25) here:
+ `http://mathworld.wolfram.com/PiFormulas.htm'.
+
+ The algorithm I wrote simply expands the multiply by 2 and works
+ from the innermost expression outwards. I used this to program HP
+ calculators because it's quite easy to modify for tiny memory
+ devices with smallish word sizes. See
+ `http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/articles.cgi?read=899'.
+
+ ---------- Footnotes ----------
+
+ (1) Weisstein, Eric W. `Sylvester's Sequence'. From MathWorld--A
+Wolfram Web Resource
+(`http://mathworld.wolfram.com/SylvestersSequence.html').
+
+
+File: gawk.info, Node: POSIX Floating Point Problems, Next: Floating point summary, Prev: Arbitrary Precision Integers, Up: Arbitrary Precision Arithmetic
+
+15.6 Standards Versus Existing Practice
+=======================================
+
+Historically, `awk' has converted any non-numeric looking string to the
+numeric value zero, when required. Furthermore, the original
+definition of the language and the original POSIX standards specified
+that `awk' only understands decimal numbers (base 10), and not octal
+(base 8) or hexadecimal numbers (base 16).
+
+ Changes in the language of the 2001 and 2004 POSIX standards can be
+interpreted to imply that `awk' should support additional features.
+These features are:
+
+ * Interpretation of floating-point data values specified in
+ hexadecimal notation (e.g., `0xDEADBEEF'). (Note: data values,
+ _not_ source code constants.)
+
+ * Support for the special IEEE 754 floating-point values "Not A
+ Number" (NaN), positive Infinity ("inf"), and negative Infinity
+ ("-inf"). In particular, the format for these values is as
+ specified by the ISO 1999 C standard, which ignores case and can
+ allow implementation-dependent additional characters after the
+ `nan' and allow either `inf' or `infinity'.
+
+ The first problem is that both of these are clear changes to
+historical practice:
+
+ * The `gawk' maintainer feels that supporting hexadecimal
+ floating-point values, in particular, is ugly, and was never
+ intended by the original designers to be part of the language.
+
+ * Allowing completely alphabetic strings to have valid numeric
+ values is also a very severe departure from historical practice.
+
+ The second problem is that the `gawk' maintainer feels that this
+interpretation of the standard, which requires a certain amount of
+"language lawyering" to arrive at in the first place, was not even
+intended by the standard developers. In other words, "we see how you
+got where you are, but we don't think that that's where you want to be."
+
+ Recognizing these issues, but attempting to provide compatibility
+with the earlier versions of the standard, the 2008 POSIX standard
+added explicit wording to allow, but not require, that `awk' support
+hexadecimal floating-point values and special values for "Not A Number"
+and infinity.
+
+ Although the `gawk' maintainer continues to feel that providing
+those features is inadvisable, nevertheless, on systems that support
+IEEE floating point, it seems reasonable to provide _some_ way to
+support NaN and Infinity values. The solution implemented in `gawk' is
+as follows:
+
+ * With the `--posix' command-line option, `gawk' becomes "hands
+ off." String values are passed directly to the system library's
+ `strtod()' function, and if it successfully returns a numeric
+ value, that is what's used.(1) By definition, the results are not
+ portable across different systems. They are also a little
+ surprising:
+
+ $ echo nanny | gawk --posix '{ print $1 + 0 }'
+ -| nan
+ $ echo 0xDeadBeef | gawk --posix '{ print $1 + 0 }'
+ -| 3735928559
+
+ * Without `--posix', `gawk' interprets the four strings `+inf',
+ `-inf', `+nan', and `-nan' specially, producing the corresponding
+ special numeric values. The leading sign acts a signal to `gawk'
+ (and the user) that the value is really numeric. Hexadecimal
+ floating point is not supported (unless you also use
+ `--non-decimal-data', which is _not_ recommended). For example:
+
+ $ echo nanny | gawk '{ print $1 + 0 }'
+ -| 0
+ $ echo +nan | gawk '{ print $1 + 0 }'
+ -| nan
+ $ echo 0xDeadBeef | gawk '{ print $1 + 0 }'
+ -| 0
+
+ `gawk' ignores case in the four special values. Thus `+nan' and
+ `+NaN' are the same.
+
+ ---------- Footnotes ----------
+
+ (1) You asked for it, you got it.
+
+
+File: gawk.info, Node: Floating point summary, Prev: POSIX Floating Point Problems, Up: Arbitrary Precision Arithmetic
+
+15.7 Summary
+============
+
+ * Most computer arithmetic is done using either integers or
+ floating-point values. Standard `awk' uses double-precision
+ floating-point values.
+
+ * In the early 1990s, Barbie mistakenly said "Math class is tough!"
+ Although math isn't tough, floating-point arithmetic isn't the same
+ as pencil and paper math, and care must be taken:
+
+ - Not all numbers can be represented exactly.
+
+ - Comparing values should use a delta, instead of being done
+ directly with `==' and `!='.
+
+ - Errors accumulate.
+
+ - Operations are not always truly associative or distributive.
+
+ * Increasing the accuracy can help, but it is not a panacea.
+
+ * Often, increasing the accuracy and then rounding to the desired
+ number of digits produces reasonable results.
+
+ * Use `-M' (or `--bignum') to enable MPFR arithmetic. Use `PREC' to
+ set the precision in bits, and `ROUNDMODE' to set the IEEE 754
+ rounding mode.
+
+ * With `-M', `gawk' performs arbitrary-precision integer arithmetic
+ using the GMP library. This is faster and more space efficient
+ than using MPFR for the same calculations.
+
+ * There are several "dark corners" with respect to floating-point
+ numbers where `gawk' disagrees with the POSIX standard. It pays
+ to be aware of them.
+
+ * Overall, there is no need to be unduly suspicious about the
+ results from floating-point arithmetic. The lesson to remember is
+ that floating-point arithmetic is always more complex than
+ arithmetic using pencil and paper. In order to take advantage of
+ the power of computer floating point, you need to know its
+ limitations and work within them. For most casual use of
+ floating-point arithmetic, you will often get the expected result
+ if you simply round the display of your final results to the
+ correct number of significant decimal digits.
+
+ * As general advice, avoid presenting numerical data in a manner that
+ implies better precision than is actually the case.
+
+
+
+File: gawk.info, Node: Dynamic Extensions, Next: Language History, Prev: Arbitrary Precision Arithmetic, Up: Top
+
+16 Writing Extensions for `gawk'
+********************************
+
+It is possible to add new functions written in C or C++ to `gawk' using
+dynamically loaded libraries. This facility is available on systems
+that support the C `dlopen()' and `dlsym()' functions. This major node
+describes how to create extensions using code written in C or C++.
+
+ If you don't know anything about C programming, you can safely skip
+this major node, although you may wish to review the documentation on
+the extensions that come with `gawk' (*note Extension Samples::), and
+the information on the `gawkextlib' project (*note gawkextlib::). The
+sample extensions are automatically built and installed when `gawk' is.
+
+ NOTE: When `--sandbox' is specified, extensions are disabled
+ (*note Options::).
+
+* Menu:
+
+* Extension Intro:: What is an extension.
+* Plugin License:: A note about licensing.
+* Extension Mechanism Outline:: An outline of how it works.
+* Extension API Description:: A full description of the API.
+* Finding Extensions:: How `gawk' finds compiled extensions.
+* Extension Example:: Example C code for an extension.
+* Extension Samples:: The sample extensions that ship with
+ `gawk'.
+* gawkextlib:: The `gawkextlib' project.
+* Extension summary:: Extension summary.
+* Extension Exercises:: Exercises.
+
+
+File: gawk.info, Node: Extension Intro, Next: Plugin License, Up: Dynamic Extensions
+
+16.1 Introduction
+=================
+
+An "extension" (sometimes called a "plug-in") is a piece of external
+compiled code that `gawk' can load at runtime to provide additional
+functionality, over and above the built-in capabilities described in
+the rest of this Info file.
+
+ Extensions are useful because they allow you (of course) to extend
+`gawk''s functionality. For example, they can provide access to system
+calls (such as `chdir()' to change directory) and to other C library
+routines that could be of use. As with most software, "the sky is the
+limit;" if you can imagine something that you might want to do and can
+write in C or C++, you can write an extension to do it!
+
+ Extensions are written in C or C++, using the "application
+programming interface" (API) defined for this purpose by the `gawk'
+developers. The rest of this major node explains the facilities that
+the API provides and how to use them, and presents a small example
+extension. In addition, it documents the sample extensions included in
+the `gawk' distribution, and describes the `gawkextlib' project. *Note
+Extension Design::, for a discussion of the extension mechanism goals
+and design.
+
+
+File: gawk.info, Node: Plugin License, Next: Extension Mechanism Outline, Prev: Extension Intro, Up: Dynamic Extensions
+
+16.2 Extension Licensing
+========================
+
+Every dynamic extension must be distributed under a license that is
+compatible with the GNU GPL (*note Copying::).
+
+ In order for the extension to tell `gawk' that it is properly
+licensed, the extension must define the global symbol
+`plugin_is_GPL_compatible'. If this symbol does not exist, `gawk'
+emits a fatal error and exits when it tries to load your extension.
+
+ The declared type of the symbol should be `int'. It does not need
+to be in any allocated section, though. The code merely asserts that
+the symbol exists in the global scope. Something like this is enough:
+
+ int plugin_is_GPL_compatible;
+
+
+File: gawk.info, Node: Extension Mechanism Outline, Next: Extension API Description, Prev: Plugin License, Up: Dynamic Extensions
+
+16.3 How It Works at a High Level
+=================================
+
+Communication between `gawk' and an extension is two-way. First, when
+an extension is loaded, `gawk' passes it a pointer to a `struct' whose
+fields are function pointers. This is shown in *note
+figure-load-extension::.
+
+ API
+ Struct
+ +---+
+ | |
+ +---+
+ +---------------| |
+ | +---+ dl_load(api_p, id);
+ | | | ___________________
+ | +---+ |
+ | +---------| | __________________ |
+ | | +---+ ||
+ | | | | ||
+ | | +---+ ||
+ | | +---| | ||
+ | | | +---+ \ || /
+ | | | \ /
+ v v v \/
++-------+-+---+-+---+-+------------------+--------------------+
+| |x| |x| |x| |OOOOOOOOOOOOOOOOOOOO|
+| |x| |x| |x| |OOOOOOOOOOOOOOOOOOOO|
+| |x| |x| |x| |OOOOOOOOOOOOOOOOOOOO|
++-------+-+---+-+---+-+------------------+--------------------+
+
+ gawk Main Program Address Space Extension
+Figure 16.1: Loading the extension
+
+ The extension can call functions inside `gawk' through these
+function pointers, at runtime, without needing (link-time) access to
+`gawk''s symbols. One of these function pointers is to a function for
+"registering" new functions. This is shown in *note
+figure-register-new-function::.
+
+ register_ext_func({ "chdir", do_chdir, 1 });
+
+ +--------------------------------------------+
+ | |
+ V |
++-------+-+---+-+---+-+------------------+--------------+-+---+
+| |x| |x| |x| |OOOOOOOOOOOOOO|X|OOO|
+| |x| |x| |x| |OOOOOOOOOOOOOO|X|OOO|
+| |x| |x| |x| |OOOOOOOOOOOOOO|X|OOO|
++-------+-+---+-+---+-+------------------+--------------+-+---+
+
+ gawk Main Program Address Space Extension
+Figure 16.2: Registering a new function
+
+ In the other direction, the extension registers its new functions
+with `gawk' by passing function pointers to the functions that provide
+the new feature (`do_chdir()', for example). `gawk' associates the
+function pointer with a name and can then call it, using a defined
+calling convention. This is shown in *note figure-call-new-function::.
+
+ BEGIN {
+ chdir("/path") (*fnptr)(1);
+ }
+ +--------------------------------------------+
+ | |
+ | V
++-------+-+---+-+---+-+------------------+--------------+-+---+
+| |x| |x| |x| |OOOOOOOOOOOOOO|X|OOO|
+| |x| |x| |x| |OOOOOOOOOOOOOO|X|OOO|
+| |x| |x| |x| |OOOOOOOOOOOOOO|X|OOO|
++-------+-+---+-+---+-+------------------+--------------+-+---+
+
+ gawk Main Program Address Space Extension
+Figure 16.3: Calling the new function
+
+ The `do_XXX()' function, in turn, then uses the function pointers in
+the API `struct' to do its work, such as updating variables or arrays,
+printing messages, setting `ERRNO', and so on.
+
+ Convenience macros make calling through the function pointers look
+like regular function calls so that extension code is quite readable
+and understandable.
+
+ Although all of this sounds somewhat complicated, the result is that
+extension code is quite straightforward to write and to read. You can
+see this in the sample extension `filefuncs.c' (*note Extension
+Example::) and also in the `testext.c' code for testing the APIs.
+
+ Some other bits and pieces:
+
+ * The API provides access to `gawk''s `do_XXX' values, reflecting
+ command-line options, like `do_lint', `do_profiling' and so on
+ (*note Extension API Variables::). These are informational: an
+ extension cannot affect their values inside `gawk'. In addition,
+ attempting to assign to them produces a compile-time error.
+
+ * The API also provides major and minor version numbers, so that an
+ extension can check if the `gawk' it is loaded with supports the
+ facilities it was compiled with. (Version mismatches "shouldn't"
+ happen, but we all know how _that_ goes.) *Note Extension
+ Versioning::, for details.
+
+
+File: gawk.info, Node: Extension API Description, Next: Finding Extensions, Prev: Extension Mechanism Outline, Up: Dynamic Extensions
+
+16.4 API Description
+====================
+
+C or C++ code for an extension must include the header file
+`gawkapi.h', which declares the functions and defines the data types
+used to communicate with `gawk'. This (rather large) minor node
+describes the API in detail.
+
+* Menu:
+
+* Extension API Functions Introduction:: Introduction to the API functions.
+* General Data Types:: The data types.
+* Memory Allocation Functions:: Functions for allocating memory.
+* Constructor Functions:: Functions for creating values.
+* Registration Functions:: Functions to register things with
+ `gawk'.
+* Printing Messages:: Functions for printing messages.
+* Updating `ERRNO':: Functions for updating `ERRNO'.
+* Requesting Values:: How to get a value.
+* Accessing Parameters:: Functions for accessing parameters.
+* Symbol Table Access:: Functions for accessing global
+ variables.
+* Array Manipulation:: Functions for working with arrays.
+* Extension API Variables:: Variables provided by the API.
+* Extension API Boilerplate:: Boilerplate code for using the API.
+
+
+File: gawk.info, Node: Extension API Functions Introduction, Next: General Data Types, Up: Extension API Description
+
+16.4.1 Introduction
+-------------------
+
+Access to facilities within `gawk' are made available by calling
+through function pointers passed into your extension.
+
+ API function pointers are provided for the following kinds of
+operations:
+
+ * Allocating, reallocating, and releasing memory.
+
+ * Registration functions. You may register:
+
+ - Extension functions
+
+ - Exit callbacks
+
+ - A version string
+
+ - Input parsers
+
+ - Output wrappers
+
+ - Two-way processors
+
+ All of these are discussed in detail, later in this major node.
+
+ * Printing fatal, warning, and "lint" warning messages.
+
+ * Updating `ERRNO', or unsetting it.
+
+ * Accessing parameters, including converting an undefined parameter
+ into an array.
+
+ * Symbol table access: retrieving a global variable, creating one,
+ or changing one.
+
+ * Creating and releasing cached values; this provides an efficient
+ way to use values for multiple variables and can be a big
+ performance win.
+
+ * Manipulating arrays:
+
+ - Retrieving, adding, deleting, and modifying elements
+
+ - Getting the count of elements in an array
+
+ - Creating a new array
+
+ - Clearing an array
+
+ - Flattening an array for easy C style looping over all its
+ indices and elements
+
+ Some points about using the API:
+
+ * The following types, macros, and/or functions are referenced in
+ `gawkapi.h'. For correct use, you must therefore include the
+ corresponding standard header file _before_ including `gawkapi.h':
+
+ C Entity Header File
+ -------------------------------------------
+ `EOF' `<stdio.h>'
+ Values for `errno' `<errno.h>'
+ `FILE' `<stdio.h>'
+ `NULL' `<stddef.h>'
+ `memcpy()' `<string.h>'
+ `memset()' `<string.h>'
+ `size_t' `<sys/types.h>'
+ `struct stat' `<sys/stat.h>'
+
+ Due to portability concerns, especially to systems that are not
+ fully standards-compliant, it is your responsibility to include
+ the correct files in the correct way. This requirement is
+ necessary in order to keep `gawkapi.h' clean, instead of becoming
+ a portability hodge-podge as can be seen in some parts of the
+ `gawk' source code.
+
+ * The `gawkapi.h' file may be included more than once without ill
+ effect. Doing so, however, is poor coding practice.
+
+ * Although the API only uses ISO C 90 features, there is an
+ exception; the "constructor" functions use the `inline' keyword.
+ If your compiler does not support this keyword, you should either
+ place `-Dinline=''' on your command line, or use the GNU Autotools
+ and include a `config.h' file in your extensions.
+
+ * All pointers filled in by `gawk' point to memory managed by `gawk'
+ and should be treated by the extension as read-only. Memory for
+ _all_ strings passed into `gawk' from the extension _must_ come
+ from calling one of `gawk_malloc()', `gawk_calloc()' or
+ `gawk_realloc()', and is managed by `gawk' from then on.
+
+ * The API defines several simple `struct's that map values as seen
+ from `awk'. A value can be a `double', a string, or an array (as
+ in multidimensional arrays, or when creating a new array). String
+ values maintain both pointer and length, because embedded NUL
+ characters are allowed.
+
+ NOTE: By intent, strings are maintained using the current
+ multibyte encoding (as defined by `LC_XXX' environment
+ variables) and not using wide characters. This matches how
+ `gawk' stores strings internally and also how characters are
+ likely to be input and output from files.
+
+ * When retrieving a value (such as a parameter or that of a global
+ variable or array element), the extension requests a specific type
+ (number, string, scalar, value cookie, array, or "undefined").
+ When the request is "undefined," the returned value will have the
+ real underlying type.
+
+ However, if the request and actual type don't match, the access
+ function returns "false" and fills in the type of the actual value
+ that is there, so that the extension can, e.g., print an error
+ message (such as "scalar passed where array expected").
+
+
+ You may call the API functions by using the function pointers
+directly, but the interface is not so pretty. To make extension code
+look more like regular code, the `gawkapi.h' header file defines several
+macros that you should use in your code. This minor node presents the
+macros as if they were functions.
+
+
+File: gawk.info, Node: General Data Types, Next: Memory Allocation Functions, Prev: Extension API Functions Introduction, Up: Extension API Description
+
+16.4.2 General-Purpose Data Types
+---------------------------------
+
+ I have a true love/hate relationship with unions. -- Arnold
+ Robbins
+
+ That's the thing about unions: the compiler will arrange things so
+ they can accommodate both love and hate. -- Chet Ramey
+
+ The extension API defines a number of simple types and structures for
+general-purpose use. Additional, more specialized, data structures are
+introduced in subsequent minor nodes, together with the functions that
+use them.
+
+`typedef void *awk_ext_id_t;'
+ A value of this type is received from `gawk' when an extension is
+ loaded. That value must then be passed back to `gawk' as the
+ first parameter of each API function.
+
+`#define awk_const ...'
+ This macro expands to `const' when compiling an extension, and to
+ nothing when compiling `gawk' itself. This makes certain fields
+ in the API data structures unwritable from extension code, while
+ allowing `gawk' to use them as it needs to.
+
+`typedef enum awk_bool {'
+` awk_false = 0,'
+` awk_true'
+`} awk_bool_t;'
+ A simple boolean type.
+
+`typedef struct awk_string {'
+` char *str; /* data */'
+` size_t len; /* length thereof, in chars */'
+`} awk_string_t;'
+ This represents a mutable string. `gawk' owns the memory pointed
+ to if it supplied the value. Otherwise, it takes ownership of the
+ memory pointed to. _Such memory must come from calling one of the
+ `gawk_malloc()', `gawk_calloc()', or `gawk_realloc()' functions!_
+
+ As mentioned earlier, strings are maintained using the current
+ multibyte encoding.
+
+`typedef enum {'
+` AWK_UNDEFINED,'
+` AWK_NUMBER,'
+` AWK_STRING,'
+` AWK_ARRAY,'
+` AWK_SCALAR, /* opaque access to a variable */'
+` AWK_VALUE_COOKIE /* for updating a previously created value */'
+`} awk_valtype_t;'
+ This `enum' indicates the type of a value. It is used in the
+ following `struct'.
+
+`typedef struct awk_value {'
+` awk_valtype_t val_type;'
+` union {'
+` awk_string_t s;'
+` double d;'
+` awk_array_t a;'
+` awk_scalar_t scl;'
+` awk_value_cookie_t vc;'
+` } u;'
+`} awk_value_t;'
+ An "`awk' value." The `val_type' member indicates what kind of
+ value the `union' holds, and each member is of the appropriate
+ type.
+
+`#define str_value u.s'
+`#define num_value u.d'
+`#define array_cookie u.a'
+`#define scalar_cookie u.scl'
+`#define value_cookie u.vc'
+ These macros make accessing the fields of the `awk_value_t' more
+ readable.
+
+`typedef void *awk_scalar_t;'
+ Scalars can be represented as an opaque type. These values are
+ obtained from `gawk' and then passed back into it. This is
+ discussed in a general fashion in the text following this list,
+ and in more detail in *note Symbol table by cookie::.
+
+`typedef void *awk_value_cookie_t;'
+ A "value cookie" is an opaque type representing a cached value.
+ This is also discussed in a general fashion in the text following
+ this list, and in more detail in *note Cached values::.
+
+
+ Scalar values in `awk' are either numbers or strings. The
+`awk_value_t' struct represents values. The `val_type' member
+indicates what is in the `union'.
+
+ Representing numbers is easy--the API uses a C `double'. Strings
+require more work. Because `gawk' allows embedded NUL bytes in string
+values, a string must be represented as a pair containing a
+data-pointer and length. This is the `awk_string_t' type.
+
+ Identifiers (i.e., the names of global variables) can be associated
+with either scalar values or with arrays. In addition, `gawk' provides
+true arrays of arrays, where any given array element can itself be an
+array. Discussion of arrays is delayed until *note Array
+Manipulation::.
+
+ The various macros listed earlier make it easier to use the elements
+of the `union' as if they were fields in a `struct'; this is a common
+coding practice in C. Such code is easier to write and to read, but it
+remains _your_ responsibility to make sure that the `val_type' member
+correctly reflects the type of the value in the `awk_value_t'.
+
+ Conceptually, the first three members of the `union' (number, string,
+and array) are all that is needed for working with `awk' values.
+However, because the API provides routines for accessing and changing
+the value of global scalar variables only by using the variable's name,
+there is a performance penalty: `gawk' must find the variable each time
+it is accessed and changed. This turns out to be a real issue, not
+just a theoretical one.
+
+ Thus, if you know that your extension will spend considerable time
+reading and/or changing the value of one or more scalar variables, you
+can obtain a "scalar cookie"(1) object for that variable, and then use
+the cookie for getting the variable's value or for changing the
+variable's value. This is the `awk_scalar_t' type and `scalar_cookie'
+macro. Given a scalar cookie, `gawk' can directly retrieve or modify
+the value, as required, without having to find it first.
+
+ The `awk_value_cookie_t' type and `value_cookie' macro are similar.
+If you know that you wish to use the same numeric or string _value_ for
+one or more variables, you can create the value once, retaining a
+"value cookie" for it, and then pass in that value cookie whenever you
+wish to set the value of a variable. This saves both storage space
+within the running `gawk' process as well as the time needed to create
+the value.
+
+ ---------- Footnotes ----------
+
+ (1) See the "cookie" entry in the Jargon file
+(http://catb.org/jargon/html/C/cookie.html) for a definition of
+"cookie", and the "magic cookie" entry in the Jargon file
+(http://catb.org/jargon/html/M/magic-cookie.html) for a nice example.
+See also the entry for "Cookie" in the *note Glossary::.
+
+
+File: gawk.info, Node: Memory Allocation Functions, Next: Constructor Functions, Prev: General Data Types, Up: Extension API Description
+
+16.4.3 Memory Allocation Functions and Convenience Macros
+---------------------------------------------------------
- * `dgawk' is designed to be used by running a program (with all its
- parameters) on the command line, as described in *Note dgawk
- invocation::. There is no way (as of now) to attach or "break in"
- to a running program. This seems reasonable for a language which
- is used mainly for quickly executing, short programs.
+The API provides a number of "memory allocation" functions for
+allocating memory that can be passed to `gawk', as well as a number of
+convenience macros. This node presents them all as function
+prototypes, in the way that extension code would use them:
- * `dgawk' only accepts source supplied with the `-f' option.
+`void *gawk_malloc(size_t size);'
+ Call the correct version of `malloc()' to allocate storage that may
+ be passed to `gawk'.
- Look forward to a future release when these and other missing
-features may be added, and of course feel free to try to add them
-yourself!
+`void *gawk_calloc(size_t nmemb, size_t size);'
+ Call the correct version of `calloc()' to allocate storage that may
+ be passed to `gawk'.
+
+`void *gawk_realloc(void *ptr, size_t size);'
+ Call the correct version of `realloc()' to allocate storage that
+ may be passed to `gawk'.
+
+`void gawk_free(void *ptr);'
+ Call the correct version of `free()' to release storage that was
+ allocated with `gawk_malloc()', `gawk_calloc()' or
+ `gawk_realloc()'.
+
+ The API has to provide these functions because it is possible for an
+extension to be compiled and linked against a different version of the
+C library than was used for the `gawk' executable.(1) If `gawk' were to
+use its version of `free()' when the memory came from an unrelated
+version of `malloc()', unexpected behavior would likely result.
+
+ Two convenience macros may be used for allocating storage from
+`gawk_malloc()' and `gawk_realloc()'. If the allocation fails, they
+cause `gawk' to exit with a fatal error message. They should be used
+as if they were procedure calls that do not return a value.
+
+`#define emalloc(pointer, type, size, message) ...'
+ The arguments to this macro are as follows:
+
+ `pointer'
+ The pointer variable to point at the allocated storage.
+
+ `type'
+ The type of the pointer variable. This is used to create a
+ cast for the call to `gawk_malloc()'.
+
+ `size'
+ The total number of bytes to be allocated.
+
+ `message'
+ A message to be prefixed to the fatal error message.
+ Typically this is the name of the function using the macro.
+
+ For example, you might allocate a string value like so:
+
+ awk_value_t result;
+ char *message;
+ const char greet[] = "Don't Panic!";
+
+ emalloc(message, char *, sizeof(greet), "myfunc");
+ strcpy(message, greet);
+ make_malloced_string(message, strlen(message), & result);
+
+`#define erealloc(pointer, type, size, message) ...'
+ This is like `emalloc()', but it calls `gawk_realloc()', instead
+ of `gawk_malloc()'. The arguments are the same as for the
+ `emalloc()' macro.
+
+ ---------- Footnotes ----------
+
+ (1) This is more common on MS-Windows systems, but can happen on
+Unix-like systems as well.
+
+
+File: gawk.info, Node: Constructor Functions, Next: Registration Functions, Prev: Memory Allocation Functions, Up: Extension API Description
+
+16.4.4 Constructor Functions
+----------------------------
+
+The API provides a number of "constructor" functions for creating
+string and numeric values, as well as a number of convenience macros.
+This node presents them all as function prototypes, in the way that
+extension code would use them:
+
+`static inline awk_value_t *'
+`make_const_string(const char *string, size_t length, awk_value_t *result)'
+ This function creates a string value in the `awk_value_t' variable
+ pointed to by `result'. It expects `string' to be a C string
+ constant (or other string data), and automatically creates a
+ _copy_ of the data for storage in `result'. It returns `result'.
+
+`static inline awk_value_t *'
+`make_malloced_string(const char *string, size_t length, awk_value_t *result)'
+ This function creates a string value in the `awk_value_t' variable
+ pointed to by `result'. It expects `string' to be a `char *' value
+ pointing to data previously obtained from `gawk_malloc()',
+ `gawk_calloc()' or `gawk_realloc()'. The idea here is that the
+ data is passed directly to `gawk', which assumes responsibility
+ for it. It returns `result'.
+
+`static inline awk_value_t *'
+`make_null_string(awk_value_t *result)'
+ This specialized function creates a null string (the "undefined"
+ value) in the `awk_value_t' variable pointed to by `result'. It
+ returns `result'.
+
+`static inline awk_value_t *'
+`make_number(double num, awk_value_t *result)'
+ This function simply creates a numeric value in the `awk_value_t'
+ variable pointed to by `result'.
+
+
+File: gawk.info, Node: Registration Functions, Next: Printing Messages, Prev: Constructor Functions, Up: Extension API Description
+
+16.4.5 Registration Functions
+-----------------------------
+
+This minor node describes the API functions for registering parts of
+your extension with `gawk'.
+
+* Menu:
+
+* Extension Functions:: Registering extension functions.
+* Exit Callback Functions:: Registering an exit callback.
+* Extension Version String:: Registering a version string.
+* Input Parsers:: Registering an input parser.
+* Output Wrappers:: Registering an output wrapper.
+* Two-way processors:: Registering a two-way processor.
+
+
+File: gawk.info, Node: Extension Functions, Next: Exit Callback Functions, Up: Registration Functions
+
+16.4.5.1 Registering An Extension Function
+..........................................
+
+Extension functions are described by the following record:
+
+ typedef struct awk_ext_func {
+ const char *name;
+ awk_value_t *(*function)(int num_actual_args, awk_value_t *result);
+ size_t num_expected_args;
+ } awk_ext_func_t;
+
+ The fields are:
+
+`const char *name;'
+ The name of the new function. `awk' level code calls the function
+ by this name. This is a regular C string.
+
+ Function names must obey the rules for `awk' identifiers. That is,
+ they must begin with either an English letter or an underscore,
+ which may be followed by any number of letters, digits, and
+ underscores. Letter case in function names is significant.
+
+`awk_value_t *(*function)(int num_actual_args, awk_value_t *result);'
+ This is a pointer to the C function that provides the extension's
+ functionality. The function must fill in `*result' with either a
+ number or a string. `gawk' takes ownership of any string memory.
+ As mentioned earlier, string memory *must* come from one of
+ `gawk_malloc()', `gawk_calloc()', or `gawk_realloc()'.
+
+ The `num_actual_args' argument tells the C function how many
+ actual parameters were passed from the calling `awk' code.
+
+ The function must return the value of `result'. This is for the
+ convenience of the calling code inside `gawk'.
+
+`size_t num_expected_args;'
+ This is the number of arguments the function expects to receive.
+ Each extension function may decide what to do if the number of
+ arguments isn't what it expected. As with real `awk' functions, it
+ is likely OK to ignore extra arguments.
+
+ Once you have a record representing your extension function, you
+register it with `gawk' using this API function:
+
+`awk_bool_t add_ext_func(const char *namespace, const awk_ext_func_t *func);'
+ This function returns true upon success, false otherwise. The
+ `namespace' parameter is currently not used; you should pass in an
+ empty string (`""'). The `func' pointer is the address of a
+ `struct' representing your function, as just described.
+
+
+File: gawk.info, Node: Exit Callback Functions, Next: Extension Version String, Prev: Extension Functions, Up: Registration Functions
+
+16.4.5.2 Registering An Exit Callback Function
+..............................................
+
+An "exit callback" function is a function that `gawk' calls before it
+exits. Such functions are useful if you have general "cleanup" tasks
+that should be performed in your extension (such as closing database
+connections or other resource deallocations). You can register such a
+function with `gawk' using the following function:
+
+`void awk_atexit(void (*funcp)(void *data, int exit_status),'
+` void *arg0);'
+ The parameters are:
+
+ `funcp'
+ A pointer to the function to be called before `gawk' exits.
+ The `data' parameter will be the original value of `arg0'.
+ The `exit_status' parameter is the exit status value that
+ `gawk' intends to pass to the `exit()' system call.
+
+ `arg0'
+ A pointer to private data which `gawk' saves in order to pass
+ to the function pointed to by `funcp'.
+
+ Exit callback functions are called in last-in-first-out (LIFO)
+order--that is, in the reverse order in which they are registered with
+`gawk'.
+
+
+File: gawk.info, Node: Extension Version String, Next: Input Parsers, Prev: Exit Callback Functions, Up: Registration Functions
+
+16.4.5.3 Registering An Extension Version String
+................................................
+
+You can register a version string which indicates the name and version
+of your extension, with `gawk', as follows:
+
+`void register_ext_version(const char *version);'
+ Register the string pointed to by `version' with `gawk'. Note
+ that `gawk' does _not_ copy the `version' string, so it should not
+ be changed.
+
+ `gawk' prints all registered extension version strings when it is
+invoked with the `--version' option.
+
+
+File: gawk.info, Node: Input Parsers, Next: Output Wrappers, Prev: Extension Version String, Up: Registration Functions
+
+16.4.5.4 Customized Input Parsers
+.................................
+
+By default, `gawk' reads text files as its input. It uses the value of
+`RS' to find the end of the record, and then uses `FS' (or
+`FIELDWIDTHS' or `FPAT') to split it into fields (*note Reading
+Files::). Additionally, it sets the value of `RT' (*note Built-in
+Variables::).
+
+ If you want, you can provide your own custom input parser. An input
+parser's job is to return a record to the `gawk' record processing
+code, along with indicators for the value and length of the data to be
+used for `RT', if any.
+
+ To provide an input parser, you must first provide two functions
+(where XXX is a prefix name for your extension):
+
+`awk_bool_t XXX_can_take_file(const awk_input_buf_t *iobuf);'
+ This function examines the information available in `iobuf' (which
+ we discuss shortly). Based on the information there, it decides
+ if the input parser should be used for this file. If so, it
+ should return true. Otherwise, it should return false. It should
+ not change any state (variable values, etc.) within `gawk'.
+
+`awk_bool_t XXX_take_control_of(awk_input_buf_t *iobuf);'
+ When `gawk' decides to hand control of the file over to the input
+ parser, it calls this function. This function in turn must fill
+ in certain fields in the `awk_input_buf_t' structure, and ensure
+ that certain conditions are true. It should then return true. If
+ an error of some kind occurs, it should not fill in any fields,
+ and should return false; then `gawk' will not use the input parser.
+ The details are presented shortly.
+
+ Your extension should package these functions inside an
+`awk_input_parser_t', which looks like this:
+
+ typedef struct awk_input_parser {
+ const char *name; /* name of parser */
+ awk_bool_t (*can_take_file)(const awk_input_buf_t *iobuf);
+ awk_bool_t (*take_control_of)(awk_input_buf_t *iobuf);
+ awk_const struct awk_input_parser *awk_const next; /* for gawk */
+ } awk_input_parser_t;
+
+ The fields are:
+
+`const char *name;'
+ The name of the input parser. This is a regular C string.
+
+`awk_bool_t (*can_take_file)(const awk_input_buf_t *iobuf);'
+ A pointer to your `XXX_can_take_file()' function.
+
+`awk_bool_t (*take_control_of)(awk_input_buf_t *iobuf);'
+ A pointer to your `XXX_take_control_of()' function.
+
+`awk_const struct input_parser *awk_const next;'
+ This is for use by `gawk'; therefore it is marked `awk_const' so
+ that the extension cannot modify it.
+
+ The steps are as follows:
+
+ 1. Create a `static awk_input_parser_t' variable and initialize it
+ appropriately.
+
+ 2. When your extension is loaded, register your input parser with
+ `gawk' using the `register_input_parser()' API function (described
+ next).
+
+ An `awk_input_buf_t' looks like this:
+
+ typedef struct awk_input {
+ const char *name; /* filename */
+ int fd; /* file descriptor */
+ #define INVALID_HANDLE (-1)
+ void *opaque; /* private data for input parsers */
+ int (*get_record)(char **out, struct awk_input *iobuf,
+ int *errcode, char **rt_start, size_t *rt_len);
+ ssize_t (*read_func)();
+ void (*close_func)(struct awk_input *iobuf);
+ struct stat sbuf; /* stat buf */
+ } awk_input_buf_t;
+
+ The fields can be divided into two categories: those for use
+(initially, at least) by `XXX_can_take_file()', and those for use by
+`XXX_take_control_of()'. The first group of fields and their uses are
+as follows:
+
+`const char *name;'
+ The name of the file.
+
+`int fd;'
+ A file descriptor for the file. If `gawk' was able to open the
+ file, then `fd' will _not_ be equal to `INVALID_HANDLE'.
+ Otherwise, it will.
+
+`struct stat sbuf;'
+ If the file descriptor is valid, then `gawk' will have filled in
+ this structure via a call to the `fstat()' system call.
+
+ The `XXX_can_take_file()' function should examine these fields and
+decide if the input parser should be used for the file. The decision
+can be made based upon `gawk' state (the value of a variable defined
+previously by the extension and set by `awk' code), the name of the
+file, whether or not the file descriptor is valid, the information in
+the `struct stat', or any combination of these factors.
+
+ Once `XXX_can_take_file()' has returned true, and `gawk' has decided
+to use your input parser, it calls `XXX_take_control_of()'. That
+function then fills one of either the `get_record' field or the
+`read_func' field in the `awk_input_buf_t'. It must also ensure that
+`fd' is _not_ set to `INVALID_HANDLE'. The following list describes
+the fields that may be filled by `XXX_take_control_of()':
+
+`void *opaque;'
+ This is used to hold any state information needed by the input
+ parser for this file. It is "opaque" to `gawk'. The input parser
+ is not required to use this pointer.
+
+`int (*get_record)(char **out,'
+` struct awk_input *iobuf,'
+` int *errcode,'
+` char **rt_start,'
+` size_t *rt_len);'
+ This function pointer should point to a function that creates the
+ input records. Said function is the core of the input parser.
+ Its behavior is described in the text following this list.
+
+`ssize_t (*read_func)();'
+ This function pointer should point to function that has the same
+ behavior as the standard POSIX `read()' system call. It is an
+ alternative to the `get_record' pointer. Its behavior is also
+ described in the text following this list.
+
+`void (*close_func)(struct awk_input *iobuf);'
+ This function pointer should point to a function that does the
+ "tear down." It should release any resources allocated by
+ `XXX_take_control_of()'. It may also close the file. If it does
+ so, it should set the `fd' field to `INVALID_HANDLE'.
+
+ If `fd' is still not `INVALID_HANDLE' after the call to this
+ function, `gawk' calls the regular `close()' system call.
+
+ Having a "tear down" function is optional. If your input parser
+ does not need it, do not set this field. Then, `gawk' calls the
+ regular `close()' system call on the file descriptor, so it should
+ be valid.
+
+ The `XXX_get_record()' function does the work of creating input
+records. The parameters are as follows:
+
+`char **out'
+ This is a pointer to a `char *' variable which is set to point to
+ the record. `gawk' makes its own copy of the data, so the
+ extension must manage this storage.
+
+`struct awk_input *iobuf'
+ This is the `awk_input_buf_t' for the file. The fields should be
+ used for reading data (`fd') and for managing private state
+ (`opaque'), if any.
+
+`int *errcode'
+ If an error occurs, `*errcode' should be set to an appropriate
+ code from `<errno.h>'.
+
+`char **rt_start'
+`size_t *rt_len'
+ If the concept of a "record terminator" makes sense, then
+ `*rt_start' should be set to point to the data to be used for
+ `RT', and `*rt_len' should be set to the length of the data.
+ Otherwise, `*rt_len' should be set to zero. `gawk' makes its own
+ copy of this data, so the extension must manage this storage.
+
+ The return value is the length of the buffer pointed to by `*out',
+or `EOF' if end-of-file was reached or an error occurred.
+
+ It is guaranteed that `errcode' is a valid pointer, so there is no
+need to test for a `NULL' value. `gawk' sets `*errcode' to zero, so
+there is no need to set it unless an error occurs.
+
+ If an error does occur, the function should return `EOF' and set
+`*errcode' to a value greater than zero. In that case, if `*errcode'
+does not equal zero, `gawk' automatically updates the `ERRNO' variable
+based on the value of `*errcode'. (In general, setting `*errcode =
+errno' should do the right thing.)
+
+ As an alternative to supplying a function that returns an input
+record, you may instead supply a function that simply reads bytes, and
+let `gawk' parse the data into records. If you do so, the data should
+be returned in the multibyte encoding of the current locale. Such a
+function should follow the same behavior as the `read()' system call,
+and you fill in the `read_func' pointer with its address in the
+`awk_input_buf_t' structure.
+
+ By default, `gawk' sets the `read_func' pointer to point to the
+`read()' system call. So your extension need not set this field
+explicitly.
+
+ NOTE: You must choose one method or the other: either a function
+ that returns a record, or one that returns raw data. In
+ particular, if you supply a function to get a record, `gawk' will
+ call it, and never call the raw read function.
+
+ `gawk' ships with a sample extension that reads directories,
+returning records for each entry in the directory (*note Extension
+Sample Readdir::). You may wish to use that code as a guide for writing
+your own input parser.
+
+ When writing an input parser, you should think about (and document)
+how it is expected to interact with `awk' code. You may want it to
+always be called, and take effect as appropriate (as the `readdir'
+extension does). Or you may want it to take effect based upon the
+value of an `awk' variable, as the XML extension from the `gawkextlib'
+project does (*note gawkextlib::). In the latter case, code in a
+`BEGINFILE' section can look at `FILENAME' and `ERRNO' to decide
+whether or not to activate an input parser (*note BEGINFILE/ENDFILE::).
+
+ You register your input parser with the following function:
+
+`void register_input_parser(awk_input_parser_t *input_parser);'
+ Register the input parser pointed to by `input_parser' with `gawk'.
+
+
+File: gawk.info, Node: Output Wrappers, Next: Two-way processors, Prev: Input Parsers, Up: Registration Functions
+
+16.4.5.5 Customized Output Wrappers
+...................................
+
+An "output wrapper" is the mirror image of an input parser. It allows
+an extension to take over the output to a file opened with the `>' or
+`>>' I/O redirection operators (*note Redirection::).
+
+ The output wrapper is very similar to the input parser structure:
+
+ typedef struct awk_output_wrapper {
+ const char *name; /* name of the wrapper */
+ awk_bool_t (*can_take_file)(const awk_output_buf_t *outbuf);
+ awk_bool_t (*take_control_of)(awk_output_buf_t *outbuf);
+ awk_const struct awk_output_wrapper *awk_const next; /* for gawk */
+ } awk_output_wrapper_t;
+
+ The members are as follows:
+
+`const char *name;'
+ This is the name of the output wrapper.
+
+`awk_bool_t (*can_take_file)(const awk_output_buf_t *outbuf);'
+ This points to a function that examines the information in the
+ `awk_output_buf_t' structure pointed to by `outbuf'. It should
+ return true if the output wrapper wants to take over the file, and
+ false otherwise. It should not change any state (variable values,
+ etc.) within `gawk'.
+
+`awk_bool_t (*take_control_of)(awk_output_buf_t *outbuf);'
+ The function pointed to by this field is called when `gawk'
+ decides to let the output wrapper take control of the file. It
+ should fill in appropriate members of the `awk_output_buf_t'
+ structure, as described next, and return true if successful, false
+ otherwise.
+
+`awk_const struct output_wrapper *awk_const next;'
+ This is for use by `gawk'; therefore it is marked `awk_const' so
+ that the extension cannot modify it.
+
+ The `awk_output_buf_t' structure looks like this:
+
+ typedef struct awk_output_buf {
+ const char *name; /* name of output file */
+ const char *mode; /* mode argument to fopen */
+ FILE *fp; /* stdio file pointer */
+ awk_bool_t redirected; /* true if a wrapper is active */
+ void *opaque; /* for use by output wrapper */
+ size_t (*gawk_fwrite)(const void *buf, size_t size, size_t count,
+ FILE *fp, void *opaque);
+ int (*gawk_fflush)(FILE *fp, void *opaque);
+ int (*gawk_ferror)(FILE *fp, void *opaque);
+ int (*gawk_fclose)(FILE *fp, void *opaque);
+ } awk_output_buf_t;
+
+ Here too, your extension will define `XXX_can_take_file()' and
+`XXX_take_control_of()' functions that examine and update data members
+in the `awk_output_buf_t'. The data members are as follows:
+
+`const char *name;'
+ The name of the output file.
+
+`const char *mode;'
+ The mode string (as would be used in the second argument to
+ `fopen()') with which the file was opened.
+
+`FILE *fp;'
+ The `FILE' pointer from `<stdio.h>'. `gawk' opens the file before
+ attempting to find an output wrapper.
+
+`awk_bool_t redirected;'
+ This field must be set to true by the `XXX_take_control_of()'
+ function.
+
+`void *opaque;'
+ This pointer is opaque to `gawk'. The extension should use it to
+ store a pointer to any private data associated with the file.
+
+`size_t (*gawk_fwrite)(const void *buf, size_t size, size_t count,'
+` FILE *fp, void *opaque);'
+`int (*gawk_fflush)(FILE *fp, void *opaque);'
+`int (*gawk_ferror)(FILE *fp, void *opaque);'
+`int (*gawk_fclose)(FILE *fp, void *opaque);'
+ These pointers should be set to point to functions that perform
+ the equivalent function as the `<stdio.h>' functions do, if
+ appropriate. `gawk' uses these function pointers for all output.
+ `gawk' initializes the pointers to point to internal, "pass
+ through" functions that just call the regular `<stdio.h>'
+ functions, so an extension only needs to redefine those functions
+ that are appropriate for what it does.
+
+ The `XXX_can_take_file()' function should make a decision based upon
+the `name' and `mode' fields, and any additional state (such as `awk'
+variable values) that is appropriate.
+
+ When `gawk' calls `XXX_take_control_of()', that function should fill
+in the other fields, as appropriate, except for `fp', which it should
+just use normally.
+
+ You register your output wrapper with the following function:
+
+`void register_output_wrapper(awk_output_wrapper_t *output_wrapper);'
+ Register the output wrapper pointed to by `output_wrapper' with
+ `gawk'.
+
+
+File: gawk.info, Node: Two-way processors, Prev: Output Wrappers, Up: Registration Functions
+
+16.4.5.6 Customized Two-way Processors
+......................................
+
+A "two-way processor" combines an input parser and an output wrapper for
+two-way I/O with the `|&' operator (*note Redirection::). It makes
+identical use of the `awk_input_parser_t' and `awk_output_buf_t'
+structures as described earlier.
+
+ A two-way processor is represented by the following structure:
+
+ typedef struct awk_two_way_processor {
+ const char *name; /* name of the two-way processor */
+ awk_bool_t (*can_take_two_way)(const char *name);
+ awk_bool_t (*take_control_of)(const char *name,
+ awk_input_buf_t *inbuf,
+ awk_output_buf_t *outbuf);
+ awk_const struct awk_two_way_processor *awk_const next; /* for gawk */
+ } awk_two_way_processor_t;
+
+ The fields are as follows:
+
+`const char *name;'
+ The name of the two-way processor.
+
+`awk_bool_t (*can_take_two_way)(const char *name);'
+ This function returns true if it wants to take over two-way I/O
+ for this file name. It should not change any state (variable
+ values, etc.) within `gawk'.
+
+`awk_bool_t (*take_control_of)(const char *name,'
+` awk_input_buf_t *inbuf,'
+` awk_output_buf_t *outbuf);'
+ This function should fill in the `awk_input_buf_t' and
+ `awk_outut_buf_t' structures pointed to by `inbuf' and `outbuf',
+ respectively. These structures were described earlier.
+
+`awk_const struct two_way_processor *awk_const next;'
+ This is for use by `gawk'; therefore it is marked `awk_const' so
+ that the extension cannot modify it.
+
+ As with the input parser and output processor, you provide "yes I
+can take this" and "take over for this" functions,
+`XXX_can_take_two_way()' and `XXX_take_control_of()'.
+
+ You register your two-way processor with the following function:
+
+`void register_two_way_processor(awk_two_way_processor_t *two_way_processor);'
+ Register the two-way processor pointed to by `two_way_processor'
+ with `gawk'.
+
+
+File: gawk.info, Node: Printing Messages, Next: Updating `ERRNO', Prev: Registration Functions, Up: Extension API Description
+
+16.4.6 Printing Messages
+------------------------
+
+You can print different kinds of warning messages from your extension,
+as described here. Note that for these functions, you must pass in the
+extension id received from `gawk' when the extension was loaded:(1)
+
+`void fatal(awk_ext_id_t id, const char *format, ...);'
+ Print a message and then cause `gawk' to exit immediately.
+
+`void warning(awk_ext_id_t id, const char *format, ...);'
+ Print a warning message.
+
+`void lintwarn(awk_ext_id_t id, const char *format, ...);'
+ Print a "lint warning." Normally this is the same as printing a
+ warning message, but if `gawk' was invoked with `--lint=fatal',
+ then lint warnings become fatal error messages.
+
+ All of these functions are otherwise like the C `printf()' family of
+functions, where the `format' parameter is a string with literal
+characters and formatting codes intermixed.
+
+ ---------- Footnotes ----------
+
+ (1) Because the API uses only ISO C 90 features, it cannot make use
+of the ISO C 99 variadic macro feature to hide that parameter. More's
+the pity.
+
+
+File: gawk.info, Node: Updating `ERRNO', Next: Requesting Values, Prev: Printing Messages, Up: Extension API Description
+
+16.4.7 Updating `ERRNO'
+-----------------------
+
+The following functions allow you to update the `ERRNO' variable:
+
+`void update_ERRNO_int(int errno_val);'
+ Set `ERRNO' to the string equivalent of the error code in
+ `errno_val'. The value should be one of the defined error codes in
+ `<errno.h>', and `gawk' turns it into a (possibly translated)
+ string using the C `strerror()' function.
+
+`void update_ERRNO_string(const char *string);'
+ Set `ERRNO' directly to the string value of `ERRNO'. `gawk' makes
+ a copy of the value of `string'.
+
+`void unset_ERRNO(void);'
+ Unset `ERRNO'.
+
+
+File: gawk.info, Node: Requesting Values, Next: Accessing Parameters, Prev: Updating `ERRNO', Up: Extension API Description
+
+16.4.8 Requesting Values
+------------------------
+
+All of the functions that return values from `gawk' work in the same
+way. You pass in an `awk_valtype_t' value to indicate what kind of
+value you expect. If the actual value matches what you requested, the
+function returns true and fills in the `awk_value_t' result.
+Otherwise, the function returns false, and the `val_type' member
+indicates the type of the actual value. You may then print an error
+message, or reissue the request for the actual value type, as
+appropriate. This behavior is summarized in *note
+table-value-types-returned::.
+
+ Type of Actual Value
+--------------------------------------------------------------------------
+
+ String Number Array Undefined
+------------------------------------------------------------------------------
+ String String String false false
+ Number Number if can Number false false
+ be converted,
+ else false
+Type Array false false Array false
+Requested Scalar Scalar Scalar false false
+ Undefined String Number Array Undefined
+ Value false false false false
+ Cookie
+
+Table 16.1: API value types returned
+
+
+File: gawk.info, Node: Accessing Parameters, Next: Symbol Table Access, Prev: Requesting Values, Up: Extension API Description
+
+16.4.9 Accessing and Updating Parameters
+----------------------------------------
+
+Two functions give you access to the arguments (parameters) passed to
+your extension function. They are:
+
+`awk_bool_t get_argument(size_t count,'
+` awk_valtype_t wanted,'
+` awk_value_t *result);'
+ Fill in the `awk_value_t' structure pointed to by `result' with
+ the `count''th argument. Return true if the actual type matches
+ `wanted', false otherwise. In the latter case, `result->val_type'
+ indicates the actual type (*note Table 16.1:
+ table-value-types-returned.). Counts are zero based--the first
+ argument is numbered zero, the second one, and so on. `wanted'
+ indicates the type of value expected.
+
+`awk_bool_t set_argument(size_t count, awk_array_t array);'
+ Convert a parameter that was undefined into an array; this provides
+ call-by-reference for arrays. Return false if `count' is too big,
+ or if the argument's type is not undefined. *Note Array
+ Manipulation::, for more information on creating arrays.
+
+
+File: gawk.info, Node: Symbol Table Access, Next: Array Manipulation, Prev: Accessing Parameters, Up: Extension API Description
+
+16.4.10 Symbol Table Access
+---------------------------
+
+Two sets of routines provide access to global variables, and one set
+allows you to create and release cached values.
+
+* Menu:
+
+* Symbol table by name:: Accessing variables by name.
+* Symbol table by cookie:: Accessing variables by ``cookie''.
+* Cached values:: Creating and using cached values.
+
+
+File: gawk.info, Node: Symbol table by name, Next: Symbol table by cookie, Up: Symbol Table Access
+
+16.4.10.1 Variable Access and Update by Name
+............................................
+
+The following routines provide the ability to access and update global
+`awk'-level variables by name. In compiler terminology, identifiers of
+different kinds are termed "symbols", thus the "sym" in the routines'
+names. The data structure which stores information about symbols is
+termed a "symbol table".
+
+`awk_bool_t sym_lookup(const char *name,'
+` awk_valtype_t wanted,'
+` awk_value_t *result);'
+ Fill in the `awk_value_t' structure pointed to by `result' with
+ the value of the variable named by the string `name', which is a
+ regular C string. `wanted' indicates the type of value expected.
+ Return true if the actual type matches `wanted', false otherwise.
+ In the latter case, `result->val_type' indicates the actual type
+ (*note Table 16.1: table-value-types-returned.).
+
+`awk_bool_t sym_update(const char *name, awk_value_t *value);'
+ Update the variable named by the string `name', which is a regular
+ C string. The variable is added to `gawk''s symbol table if it is
+ not there. Return true if everything worked, false otherwise.
+
+ Changing types (scalar to array or vice versa) of an existing
+ variable is _not_ allowed, nor may this routine be used to update
+ an array. This routine cannot be used to update any of the
+ predefined variables (such as `ARGC' or `NF').
+
+ An extension can look up the value of `gawk''s special variables.
+However, with the exception of the `PROCINFO' array, an extension
+cannot change any of those variables.
+
+ CAUTION: It is possible for the lookup of `PROCINFO' to fail. This
+ happens if the `awk' program being run does not reference
+ `PROCINFO'; in this case, `gawk' doesn't bother to create the
+ array and populate it.
+
+
+File: gawk.info, Node: Symbol table by cookie, Next: Cached values, Prev: Symbol table by name, Up: Symbol Table Access
+
+16.4.10.2 Variable Access and Update by Cookie
+..............................................
+
+A "scalar cookie" is an opaque handle that provides access to a global
+variable or array. It is an optimization that avoids looking up
+variables in `gawk''s symbol table every time access is needed. This
+was discussed earlier in *note General Data Types::.
+
+ The following functions let you work with scalar cookies:
+
+`awk_bool_t sym_lookup_scalar(awk_scalar_t cookie,'
+` awk_valtype_t wanted,'
+` awk_value_t *result);'
+ Retrieve the current value of a scalar cookie. Once you have
+ obtained a scalar cookie using `sym_lookup()', you can use this
+ function to get its value more efficiently. Return false if the
+ value cannot be retrieved.
+
+`awk_bool_t sym_update_scalar(awk_scalar_t cookie, awk_value_t *value);'
+ Update the value associated with a scalar cookie. Return false if
+ the new value is not of type `AWK_STRING' or `AWK_NUMBER'. Here
+ too, the predefined variables may not be updated.
+
+ It is not obvious at first glance how to work with scalar cookies or
+what their raison d'e^tre really is. In theory, the `sym_lookup()' and
+`sym_update()' routines are all you really need to work with variables.
+For example, you might have code that looks up the value of a variable,
+evaluates a condition, and then possibly changes the value of the
+variable based on the result of that evaluation, like so:
+
+ /* do_magic --- do something really great */
+
+ static awk_value_t *
+ do_magic(int nargs, awk_value_t *result)
+ {
+ awk_value_t value;
+
+ if ( sym_lookup("MAGIC_VAR", AWK_NUMBER, & value)
+ && some_condition(value.num_value)) {
+ value.num_value += 42;
+ sym_update("MAGIC_VAR", & value);
+ }
+
+ return make_number(0.0, result);
+ }
+
+This code looks (and is) simple and straightforward. So what's the
+problem?
+
+ Well, consider what happens if `awk'-level code associated with your
+extension calls the `magic()' function (implemented in C by
+`do_magic()'), once per record, while processing hundreds of thousands
+or millions of records. The `MAGIC_VAR' variable is looked up in the
+symbol table once or twice per function call!
+
+ The symbol table lookup is really pure overhead; it is considerably
+more efficient to get a cookie that represents the variable, and use
+that to get the variable's value and update it as needed.(1)
+
+ Thus, the way to use cookies is as follows. First, install your
+extension's variable in `gawk''s symbol table using `sym_update()', as
+usual. Then get a scalar cookie for the variable using `sym_lookup()':
+
+ static awk_scalar_t magic_var_cookie; /* cookie for MAGIC_VAR */
+
+ static void
+ my_extension_init()
+ {
+ awk_value_t value;
+
+ /* install initial value */
+ sym_update("MAGIC_VAR", make_number(42.0, & value));
+
+ /* get the cookie */
+ sym_lookup("MAGIC_VAR", AWK_SCALAR, & value);
+
+ /* save the cookie */
+ magic_var_cookie = value.scalar_cookie;
+ ...
+ }
+
+ Next, use the routines in this section for retrieving and updating
+the value through the cookie. Thus, `do_magic()' now becomes something
+like this:
+
+ /* do_magic --- do something really great */
+
+ static awk_value_t *
+ do_magic(int nargs, awk_value_t *result)
+ {
+ awk_value_t value;
+
+ if ( sym_lookup_scalar(magic_var_cookie, AWK_NUMBER, & value)
+ && some_condition(value.num_value)) {
+ value.num_value += 42;
+ sym_update_scalar(magic_var_cookie, & value);
+ }
+ ...
+
+ return make_number(0.0, result);
+ }
+
+ NOTE: The previous code omitted error checking for presentation
+ purposes. Your extension code should be more robust and carefully
+ check the return values from the API functions.
+
+ ---------- Footnotes ----------
+
+ (1) The difference is measurable and quite real. Trust us.
+
+
+File: gawk.info, Node: Cached values, Prev: Symbol table by cookie, Up: Symbol Table Access
+
+16.4.10.3 Creating and Using Cached Values
+..........................................
+
+The routines in this section allow you to create and release cached
+values. As with scalar cookies, in theory, cached values are not
+necessary. You can create numbers and strings using the functions in
+*note Constructor Functions::. You can then assign those values to
+variables using `sym_update()' or `sym_update_scalar()', as you like.
+
+ However, you can understand the point of cached values if you
+remember that _every_ string value's storage _must_ come from
+`gawk_malloc()', `gawk_calloc()', or `gawk_realloc()'. If you have 20
+variables, all of which have the same string value, you must create 20
+identical copies of the string.(1)
+
+ It is clearly more efficient, if possible, to create a value once,
+and then tell `gawk' to reuse the value for multiple variables. That is
+what the routines in this section let you do. The functions are as
+follows:
+
+`awk_bool_t create_value(awk_value_t *value, awk_value_cookie_t *result);'
+ Create a cached string or numeric value from `value' for efficient
+ later assignment. Only values of type `AWK_NUMBER' and
+ `AWK_STRING' are allowed. Any other type is rejected.
+ `AWK_UNDEFINED' could be allowed, but doing so would result in
+ inferior performance.
+
+`awk_bool_t release_value(awk_value_cookie_t vc);'
+ Release the memory associated with a value cookie obtained from
+ `create_value()'.
+
+ You use value cookies in a fashion similar to the way you use scalar
+cookies. In the extension initialization routine, you create the value
+cookie:
+
+ static awk_value_cookie_t answer_cookie; /* static value cookie */
+
+ static void
+ my_extension_init()
+ {
+ awk_value_t value;
+ char *long_string;
+ size_t long_string_len;
+
+ /* code from earlier */
+ ...
+ /* ... fill in long_string and long_string_len ... */
+ make_malloced_string(long_string, long_string_len, & value);
+ create_value(& value, & answer_cookie); /* create cookie */
+ ...
+ }
+
+ Once the value is created, you can use it as the value of any number
+of variables:
+
+ static awk_value_t *
+ do_magic(int nargs, awk_value_t *result)
+ {
+ awk_value_t new_value;
+
+ ... /* as earlier */
+
+ value.val_type = AWK_VALUE_COOKIE;
+ value.value_cookie = answer_cookie;
+ sym_update("VAR1", & value);
+ sym_update("VAR2", & value);
+ ...
+ sym_update("VAR100", & value);
+ ...
+ }
+
+Using value cookies in this way saves considerable storage, as all of
+`VAR1' through `VAR100' share the same value.
+
+ You might be wondering, "Is this sharing problematic? What happens
+if `awk' code assigns a new value to `VAR1', are all the others changed
+too?"
+
+ That's a great question. The answer is that no, it's not a problem.
+Internally, `gawk' uses "reference-counted strings". This means that
+many variables can share the same string value, and `gawk' keeps track
+of the usage. When a variable's value changes, `gawk' simply
+decrements the reference count on the old value and updates the
+variable to use the new value.
+
+ Finally, as part of your cleanup action (*note Exit Callback
+Functions::) you should release any cached values that you created,
+using `release_value()'.
+
+ ---------- Footnotes ----------
+
+ (1) Numeric values are clearly less problematic, requiring only a C
+`double' to store.
+
+
+File: gawk.info, Node: Array Manipulation, Next: Extension API Variables, Prev: Symbol Table Access, Up: Extension API Description
+
+16.4.11 Array Manipulation
+--------------------------
+
+The primary data structure(1) in `awk' is the associative array (*note
+Arrays::). Extensions need to be able to manipulate `awk' arrays. The
+API provides a number of data structures for working with arrays,
+functions for working with individual elements, and functions for
+working with arrays as a whole. This includes the ability to "flatten"
+an array so that it is easy for C code to traverse every element in an
+array. The array data structures integrate nicely with the data
+structures for values to make it easy to both work with and create true
+arrays of arrays (*note General Data Types::).
+
+* Menu:
+
+* Array Data Types:: Data types for working with arrays.
+* Array Functions:: Functions for working with arrays.
+* Flattening Arrays:: How to flatten arrays.
+* Creating Arrays:: How to create and populate arrays.
+
+ ---------- Footnotes ----------
+
+ (1) OK, the only data structure.
+
+
+File: gawk.info, Node: Array Data Types, Next: Array Functions, Up: Array Manipulation
+
+16.4.11.1 Array Data Types
+..........................
+
+The data types associated with arrays are as follows:
+
+`typedef void *awk_array_t;'
+ If you request the value of an array variable, you get back an
+ `awk_array_t' value. This value is opaque(1) to the extension; it
+ uniquely identifies the array but can only be used by passing it
+ into API functions or receiving it from API functions. This is
+ very similar to way `FILE *' values are used with the `<stdio.h>'
+ library routines.
+
+`typedef struct awk_element {'
+` /* convenience linked list pointer, not used by gawk */'
+` struct awk_element *next;'
+` enum {'
+` AWK_ELEMENT_DEFAULT = 0, /* set by gawk */'
+` AWK_ELEMENT_DELETE = 1 /* set by extension */'
+` } flags;'
+` awk_value_t index;'
+` awk_value_t value;'
+`} awk_element_t;'
+ The `awk_element_t' is a "flattened" array element. `awk' produces
+ an array of these inside the `awk_flat_array_t' (see the next
+ item). Individual elements may be marked for deletion. New
+ elements must be added individually, one at a time, using the
+ separate API for that purpose. The fields are as follows:
+
+ `struct awk_element *next;'
+ This pointer is for the convenience of extension writers. It
+ allows an extension to create a linked list of new elements
+ that can then be added to an array in a loop that traverses
+ the list.
+
+ `enum { ... } flags;'
+ A set of flag values that convey information between the
+ extension and `gawk'. Currently there is only one:
+ `AWK_ELEMENT_DELETE'. Setting it causes `gawk' to delete the
+ element from the original array upon release of the flattened
+ array.
+
+ `index'
+ `value'
+ The index and value of the element, respectively. _All_
+ memory pointed to by `index' and `value' belongs to `gawk'.
+
+`typedef struct awk_flat_array {'
+` awk_const void *awk_const opaque1; /* for use by gawk */'
+` awk_const void *awk_const opaque2; /* for use by gawk */'
+` awk_const size_t count; /* how many elements */'
+` awk_element_t elements[1]; /* will be extended */'
+`} awk_flat_array_t;'
+ This is a flattened array. When an extension gets one of these
+ from `gawk', the `elements' array is of actual size `count'. The
+ `opaque1' and `opaque2' pointers are for use by `gawk'; therefore
+ they are marked `awk_const' so that the extension cannot modify
+ them.
+
+ ---------- Footnotes ----------
+
+ (1) It is also a "cookie," but the `gawk' developers did not wish to
+overuse this term.
+
+
+File: gawk.info, Node: Array Functions, Next: Flattening Arrays, Prev: Array Data Types, Up: Array Manipulation
+
+16.4.11.2 Array Functions
+.........................
+
+The following functions relate to individual array elements.
+
+`awk_bool_t get_element_count(awk_array_t a_cookie, size_t *count);'
+ For the array represented by `a_cookie', place in `*count' the
+ number of elements it contains. A subarray counts as a single
+ element. Return false if there is an error.
+
+`awk_bool_t get_array_element(awk_array_t a_cookie,'
+` const awk_value_t *const index,'
+` awk_valtype_t wanted,'
+` awk_value_t *result);'
+ For the array represented by `a_cookie', return in `*result' the
+ value of the element whose index is `index'. `wanted' specifies
+ the type of value you wish to retrieve. Return false if `wanted'
+ does not match the actual type or if `index' is not in the array
+ (*note Table 16.1: table-value-types-returned.).
+
+ The value for `index' can be numeric, in which case `gawk'
+ converts it to a string. Using non-integral values is possible, but
+ requires that you understand how such values are converted to
+ strings (*note Conversion::); thus using integral values is safest.
+
+ As with _all_ strings passed into `gawk' from an extension, the
+ string value of `index' must come from `gawk_malloc()',
+ `gawk_calloc()' or `gawk_realloc()', and `gawk' releases the
+ storage.
+
+`awk_bool_t set_array_element(awk_array_t a_cookie,'
+` const awk_value_t *const index,'
+` const awk_value_t *const value);'
+ In the array represented by `a_cookie', create or modify the
+ element whose index is given by `index'. The `ARGV' and `ENVIRON'
+ arrays may not be changed, although the `PROCINFO' array can be.
+
+`awk_bool_t set_array_element_by_elem(awk_array_t a_cookie,'
+` awk_element_t element);'
+ Like `set_array_element()', but take the `index' and `value' from
+ `element'. This is a convenience macro.
+
+`awk_bool_t del_array_element(awk_array_t a_cookie,'
+` const awk_value_t* const index);'
+ Remove the element with the given index from the array represented
+ by `a_cookie'. Return true if the element was removed, or false
+ if the element did not exist in the array.
+
+ The following functions relate to arrays as a whole:
+
+`awk_array_t create_array(void);'
+ Create a new array to which elements may be added. *Note Creating
+ Arrays::, for a discussion of how to create a new array and add
+ elements to it.
+
+`awk_bool_t clear_array(awk_array_t a_cookie);'
+ Clear the array represented by `a_cookie'. Return false if there
+ was some kind of problem, true otherwise. The array remains an
+ array, but after calling this function, it has no elements. This
+ is equivalent to using the `delete' statement (*note Delete::).
+
+`awk_bool_t flatten_array(awk_array_t a_cookie, awk_flat_array_t **data);'
+ For the array represented by `a_cookie', create an
+ `awk_flat_array_t' structure and fill it in. Set the pointer whose
+ address is passed as `data' to point to this structure. Return
+ true upon success, or false otherwise. *Note Flattening Arrays::,
+ for a discussion of how to flatten an array and work with it.
+
+`awk_bool_t release_flattened_array(awk_array_t a_cookie,'
+` awk_flat_array_t *data);'
+ When done with a flattened array, release the storage using this
+ function. You must pass in both the original array cookie, and
+ the address of the created `awk_flat_array_t' structure. The
+ function returns true upon success, false otherwise.
+
+
+File: gawk.info, Node: Flattening Arrays, Next: Creating Arrays, Prev: Array Functions, Up: Array Manipulation
+
+16.4.11.3 Working With All The Elements of an Array
+...................................................
+
+To "flatten" an array is to create a structure that represents the full
+array in a fashion that makes it easy for C code to traverse the entire
+array. Test code in `extension/testext.c' does this, and also serves
+as a nice example showing how to use the APIs.
+
+ We walk through that part of the code one step at a time. First,
+the `gawk' script that drives the test extension:
+
+ @load "testext"
+ BEGIN {
+ n = split("blacky rusty sophie raincloud lucky", pets)
+ printf("pets has %d elements\n", length(pets))
+ ret = dump_array_and_delete("pets", "3")
+ printf("dump_array_and_delete(pets) returned %d\n", ret)
+ if ("3" in pets)
+ printf("dump_array_and_delete() did NOT remove index \"3\"!\n")
+ else
+ printf("dump_array_and_delete() did remove index \"3\"!\n")
+ print ""
+ }
+
+This code creates an array with `split()' (*note String Functions::)
+and then calls `dump_array_and_delete()'. That function looks up the
+array whose name is passed as the first argument, and deletes the
+element at the index passed in the second argument. The `awk' code
+then prints the return value and checks if the element was indeed
+deleted. Here is the C code that implements `dump_array_and_delete()'.
+It has been edited slightly for presentation.
+
+ The first part declares variables, sets up the default return value
+in `result', and checks that the function was called with the correct
+number of arguments:
+
+ static awk_value_t *
+ dump_array_and_delete(int nargs, awk_value_t *result)
+ {
+ awk_value_t value, value2, value3;
+ awk_flat_array_t *flat_array;
+ size_t count;
+ char *name;
+ int i;
+
+ assert(result != NULL);
+ make_number(0.0, result);
+
+ if (nargs != 2) {
+ printf("dump_array_and_delete: nargs not right "
+ "(%d should be 2)\n", nargs);
+ goto out;
+ }
+
+ The function then proceeds in steps, as follows. First, retrieve the
+name of the array, passed as the first argument. Then retrieve the
+array itself. If either operation fails, print error messages and
+return:
+
+ /* get argument named array as flat array and print it */
+ if (get_argument(0, AWK_STRING, & value)) {
+ name = value.str_value.str;
+ if (sym_lookup(name, AWK_ARRAY, & value2))
+ printf("dump_array_and_delete: sym_lookup of %s passed\n",
+ name);
+ else {
+ printf("dump_array_and_delete: sym_lookup of %s failed\n",
+ name);
+ goto out;
+ }
+ } else {
+ printf("dump_array_and_delete: get_argument(0) failed\n");
+ goto out;
+ }
+
+ For testing purposes and to make sure that the C code sees the same
+number of elements as the `awk' code, the second step is to get the
+count of elements in the array and print it:
+
+ if (! get_element_count(value2.array_cookie, & count)) {
+ printf("dump_array_and_delete: get_element_count failed\n");
+ goto out;
+ }
+
+ printf("dump_array_and_delete: incoming size is %lu\n",
+ (unsigned long) count);
+
+ The third step is to actually flatten the array, and then to double
+check that the count in the `awk_flat_array_t' is the same as the count
+just retrieved:
+
+ if (! flatten_array(value2.array_cookie, & flat_array)) {
+ printf("dump_array_and_delete: could not flatten array\n");
+ goto out;
+ }
+
+ if (flat_array->count != count) {
+ printf("dump_array_and_delete: flat_array->count (%lu)"
+ " != count (%lu)\n",
+ (unsigned long) flat_array->count,
+ (unsigned long) count);
+ goto out;
+ }
+
+ The fourth step is to retrieve the index of the element to be
+deleted, which was passed as the second argument. Remember that
+argument counts passed to `get_argument()' are zero-based, thus the
+second argument is numbered one:
+
+ if (! get_argument(1, AWK_STRING, & value3)) {
+ printf("dump_array_and_delete: get_argument(1) failed\n");
+ goto out;
+ }
+
+ The fifth step is where the "real work" is done. The function loops
+over every element in the array, printing the index and element values.
+In addition, upon finding the element with the index that is supposed
+to be deleted, the function sets the `AWK_ELEMENT_DELETE' bit in the
+`flags' field of the element. When the array is released, `gawk'
+traverses the flattened array, and deletes any elements which have this
+flag bit set:
+
+ for (i = 0; i < flat_array->count; i++) {
+ printf("\t%s[\"%.*s\"] = %s\n",
+ name,
+ (int) flat_array->elements[i].index.str_value.len,
+ flat_array->elements[i].index.str_value.str,
+ valrep2str(& flat_array->elements[i].value));
+
+ if (strcmp(value3.str_value.str,
+ flat_array->elements[i].index.str_value.str) == 0) {
+ flat_array->elements[i].flags |= AWK_ELEMENT_DELETE;
+ printf("dump_array_and_delete: marking element \"%s\" "
+ "for deletion\n",
+ flat_array->elements[i].index.str_value.str);
+ }
+ }
+
+ The sixth step is to release the flattened array. This tells `gawk'
+that the extension is no longer using the array, and that it should
+delete any elements marked for deletion. `gawk' also frees any storage
+that was allocated, so you should not use the pointer (`flat_array' in
+this code) once you have called `release_flattened_array()':
+
+ if (! release_flattened_array(value2.array_cookie, flat_array)) {
+ printf("dump_array_and_delete: could not release flattened array\n");
+ goto out;
+ }
+
+ Finally, because everything was successful, the function sets the
+return value to success, and returns:
+
+ make_number(1.0, result);
+ out:
+ return result;
+ }
+
+ Here is the output from running this part of the test:
+
+ pets has 5 elements
+ dump_array_and_delete: sym_lookup of pets passed
+ dump_array_and_delete: incoming size is 5
+ pets["1"] = "blacky"
+ pets["2"] = "rusty"
+ pets["3"] = "sophie"
+ dump_array_and_delete: marking element "3" for deletion
+ pets["4"] = "raincloud"
+ pets["5"] = "lucky"
+ dump_array_and_delete(pets) returned 1
+ dump_array_and_delete() did remove index "3"!
+
+
+File: gawk.info, Node: Creating Arrays, Prev: Flattening Arrays, Up: Array Manipulation
+
+16.4.11.4 How To Create and Populate Arrays
+...........................................
+
+Besides working with arrays created by `awk' code, you can create
+arrays and populate them as you see fit, and then `awk' code can access
+them and manipulate them.
+
+ There are two important points about creating arrays from extension
+code:
+
+ * You must install a new array into `gawk''s symbol table
+ immediately upon creating it. Once you have done so, you can then
+ populate the array.
+
+ Similarly, if installing a new array as a subarray of an existing
+ array, you must add the new array to its parent before adding any
+ elements to it.
+
+ Thus, the correct way to build an array is to work "top down."
+ Create the array, and immediately install it in `gawk''s symbol
+ table using `sym_update()', or install it as an element in a
+ previously existing array using `set_array_element()'. We show
+ example code shortly.
+
+ * Due to `gawk' internals, after using `sym_update()' to install an
+ array into `gawk', you have to retrieve the array cookie from the
+ value passed in to `sym_update()' before doing anything else with
+ it, like so:
+
+ awk_value_t value;
+ awk_array_t new_array;
+
+ new_array = create_array();
+ val.val_type = AWK_ARRAY;
+ val.array_cookie = new_array;
+
+ /* install array in the symbol table */
+ sym_update("array", & val);
+
+ new_array = val.array_cookie; /* YOU MUST DO THIS */
+
+ If installing an array as a subarray, you must also retrieve the
+ value of the array cookie after the call to `set_element()'.
+
+ The following C code is a simple test extension to create an array
+with two regular elements and with a subarray. The leading `#include'
+directives and boilerplate variable declarations (*note Extension API
+Boilerplate::) are omitted for brevity. The first step is to create a
+new array and then install it in the symbol table:
+
+ /* create_new_array --- create a named array */
+
+ static void
+ create_new_array()
+ {
+ awk_array_t a_cookie;
+ awk_array_t subarray;
+ awk_value_t index, value;
+
+ a_cookie = create_array();
+ value.val_type = AWK_ARRAY;
+ value.array_cookie = a_cookie;
+
+ if (! sym_update("new_array", & value))
+ printf("create_new_array: sym_update(\"new_array\") failed!\n");
+ a_cookie = value.array_cookie;
+
+Note how `a_cookie' is reset from the `array_cookie' field in the
+`value' structure.
+
+ The second step is to install two regular values into `new_array':
+
+ (void) make_const_string("hello", 5, & index);
+ (void) make_const_string("world", 5, & value);
+ if (! set_array_element(a_cookie, & index, & value)) {
+ printf("fill_in_array: set_array_element failed\n");
+ return;
+ }
+
+ (void) make_const_string("answer", 6, & index);
+ (void) make_number(42.0, & value);
+ if (! set_array_element(a_cookie, & index, & value)) {
+ printf("fill_in_array: set_array_element failed\n");
+ return;
+ }
+
+ The third step is to create the subarray and install it:
+
+ (void) make_const_string("subarray", 8, & index);
+ subarray = create_array();
+ value.val_type = AWK_ARRAY;
+ value.array_cookie = subarray;
+ if (! set_array_element(a_cookie, & index, & value)) {
+ printf("fill_in_array: set_array_element failed\n");
+ return;
+ }
+ subarray = value.array_cookie;
+
+ The final step is to populate the subarray with its own element:
+
+ (void) make_const_string("foo", 3, & index);
+ (void) make_const_string("bar", 3, & value);
+ if (! set_array_element(subarray, & index, & value)) {
+ printf("fill_in_array: set_array_element failed\n");
+ return;
+ }
+ }
+
+ Here is a sample script that loads the extension and then dumps the
+array:
+
+ @load "subarray"
+
+ function dumparray(name, array, i)
+ {
+ for (i in array)
+ if (isarray(array[i]))
+ dumparray(name "[\"" i "\"]", array[i])
+ else
+ printf("%s[\"%s\"] = %s\n", name, i, array[i])
+ }
+
+ BEGIN {
+ dumparray("new_array", new_array);
+ }
+
+ Here is the result of running the script:
+
+ $ AWKLIBPATH=$PWD ./gawk -f subarray.awk
+ -| new_array["subarray"]["foo"] = bar
+ -| new_array["hello"] = world
+ -| new_array["answer"] = 42
+
+(*Note Finding Extensions::, for more information on the `AWKLIBPATH'
+environment variable.)
+
+
+File: gawk.info, Node: Extension API Variables, Next: Extension API Boilerplate, Prev: Array Manipulation, Up: Extension API Description
+
+16.4.12 API Variables
+---------------------
+
+The API provides two sets of variables. The first provides information
+about the version of the API (both with which the extension was
+compiled, and with which `gawk' was compiled). The second provides
+information about how `gawk' was invoked.
+
+* Menu:
+
+* Extension Versioning:: API Version information.
+* Extension API Informational Variables:: Variables providing information about
+ `gawk''s invocation.
+
+
+File: gawk.info, Node: Extension Versioning, Next: Extension API Informational Variables, Up: Extension API Variables
+
+16.4.12.1 API Version Constants and Variables
+.............................................
+
+The API provides both a "major" and a "minor" version number. The API
+versions are available at compile time as constants:
+
+`GAWK_API_MAJOR_VERSION'
+ The major version of the API.
+
+`GAWK_API_MINOR_VERSION'
+ The minor version of the API.
+
+ The minor version increases when new functions are added to the API.
+Such new functions are always added to the end of the API `struct'.
+
+ The major version increases (and the minor version is reset to zero)
+if any of the data types change size or member order, or if any of the
+existing functions change signature.
+
+ It could happen that an extension may be compiled against one version
+of the API but loaded by a version of `gawk' using a different version.
+For this reason, the major and minor API versions of the running `gawk'
+are included in the API `struct' as read-only constant integers:
+
+`api->major_version'
+ The major version of the running `gawk'.
+
+`api->minor_version'
+ The minor version of the running `gawk'.
+
+ It is up to the extension to decide if there are API
+incompatibilities. Typically a check like this is enough:
+
+ if (api->major_version != GAWK_API_MAJOR_VERSION
+ || api->minor_version < GAWK_API_MINOR_VERSION) {
+ fprintf(stderr, "foo_extension: version mismatch with gawk!\n");
+ fprintf(stderr, "\tmy version (%d, %d), gawk version (%d, %d)\n",
+ GAWK_API_MAJOR_VERSION, GAWK_API_MINOR_VERSION,
+ api->major_version, api->minor_version);
+ exit(1);
+ }
+
+ Such code is included in the boilerplate `dl_load_func()' macro
+provided in `gawkapi.h' (discussed later, in *note Extension API
+Boilerplate::).
+
+
+File: gawk.info, Node: Extension API Informational Variables, Prev: Extension Versioning, Up: Extension API Variables
+
+16.4.12.2 Informational Variables
+.................................
+
+The API provides access to several variables that describe whether the
+corresponding command-line options were enabled when `gawk' was
+invoked. The variables are:
+
+`do_debug'
+ This variable is true if `gawk' was invoked with `--debug' option.
+
+`do_lint'
+ This variable is true if `gawk' was invoked with `--lint' option.
+
+`do_mpfr'
+ This variable is true if `gawk' was invoked with `--bignum' option.
+
+`do_profile'
+ This variable is true if `gawk' was invoked with `--profile'
+ option.
+
+`do_sandbox'
+ This variable is true if `gawk' was invoked with `--sandbox'
+ option.
+
+`do_traditional'
+ This variable is true if `gawk' was invoked with `--traditional'
+ option.
+
+ The value of `do_lint' can change if `awk' code modifies the `LINT'
+predefined variable (*note Built-in Variables::). The others should
+not change during execution.

-File: gawk.info, Node: Language History, Next: Installation, Prev: Debugger, Up: Top
+File: gawk.info, Node: Extension API Boilerplate, Prev: Extension API Variables, Up: Extension API Description
+
+16.4.13 Boilerplate Code
+------------------------
+
+As mentioned earlier (*note Extension Mechanism Outline::), the function
+definitions as presented are really macros. To use these macros, your
+extension must provide a small amount of boilerplate code (variables and
+functions) toward the top of your source file, using predefined names
+as described here. The boilerplate needed is also provided in comments
+in the `gawkapi.h' header file:
+
+ /* Boiler plate code: */
+ int plugin_is_GPL_compatible;
+
+ static gawk_api_t *const api;
+ static awk_ext_id_t ext_id;
+ static const char *ext_version = NULL; /* or ... = "some string" */
+
+ static awk_ext_func_t func_table[] = {
+ { "name", do_name, 1 },
+ /* ... */
+ };
+
+ /* EITHER: */
+
+ static awk_bool_t (*init_func)(void) = NULL;
+
+ /* OR: */
+
+ static awk_bool_t
+ init_my_extension(void)
+ {
+ ...
+ }
+
+ static awk_bool_t (*init_func)(void) = init_my_extension;
+
+ dl_load_func(func_table, some_name, "name_space_in_quotes")
+
+ These variables and functions are as follows:
+
+`int plugin_is_GPL_compatible;'
+ This asserts that the extension is compatible with the GNU GPL
+ (*note Copying::). If your extension does not have this, `gawk'
+ will not load it (*note Plugin License::).
+
+`static gawk_api_t *const api;'
+ This global `static' variable should be set to point to the
+ `gawk_api_t' pointer that `gawk' passes to your `dl_load()'
+ function. This variable is used by all of the macros.
+
+`static awk_ext_id_t ext_id;'
+ This global static variable should be set to the `awk_ext_id_t'
+ value that `gawk' passes to your `dl_load()' function. This
+ variable is used by all of the macros.
+
+`static const char *ext_version = NULL; /* or ... = "some string" */'
+ This global `static' variable should be set either to `NULL', or
+ to point to a string giving the name and version of your extension.
+
+`static awk_ext_func_t func_table[] = { ... };'
+ This is an array of one or more `awk_ext_func_t' structures as
+ described earlier (*note Extension Functions::). It can then be
+ looped over for multiple calls to `add_ext_func()'.
+
+`static awk_bool_t (*init_func)(void) = NULL;'
+` OR'
+`static awk_bool_t init_my_extension(void) { ... }'
+`static awk_bool_t (*init_func)(void) = init_my_extension;'
+ If you need to do some initialization work, you should define a
+ function that does it (creates variables, opens files, etc.) and
+ then define the `init_func' pointer to point to your function.
+ The function should return `awk_false' upon failure, or `awk_true'
+ if everything goes well.
+
+ If you don't need to do any initialization, define the pointer and
+ initialize it to `NULL'.
+
+`dl_load_func(func_table, some_name, "name_space_in_quotes")'
+ This macro expands to a `dl_load()' function that performs all the
+ necessary initializations.
+
+ The point of all the variables and arrays is to let the `dl_load()'
+function (from the `dl_load_func()' macro) do all the standard work. It
+does the following:
+
+ 1. Check the API versions. If the extension major version does not
+ match `gawk''s, or if the extension minor version is greater than
+ `gawk''s, it prints a fatal error message and exits.
+
+ 2. Load the functions defined in `func_table'. If any of them fails
+ to load, it prints a warning message but continues on.
+
+ 3. If the `init_func' pointer is not `NULL', call the function it
+ points to. If it returns `awk_false', print a warning message.
+
+ 4. If `ext_version' is not `NULL', register the version string with
+ `gawk'.
+
+
+File: gawk.info, Node: Finding Extensions, Next: Extension Example, Prev: Extension API Description, Up: Dynamic Extensions
+
+16.5 How `gawk' Finds Extensions
+================================
+
+Compiled extensions have to be installed in a directory where `gawk'
+can find them. If `gawk' is configured and built in the default
+fashion, the directory in which to find extensions is
+`/usr/local/lib/gawk'. You can also specify a search path with a list
+of directories to search for compiled extensions. *Note AWKLIBPATH
+Variable::, for more information.
+
+
+File: gawk.info, Node: Extension Example, Next: Extension Samples, Prev: Finding Extensions, Up: Dynamic Extensions
+
+16.6 Example: Some File Functions
+=================================
+
+ No matter where you go, there you are. -- Buckaroo Banzai
+
+ 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). In order to illustrate
+the API in action, this minor node implements these functions for
+`gawk' in an extension.
+
+* 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.
+
+
+File: gawk.info, Node: Internal File Description, Next: Internal File Ops, Up: Extension Example
+
+16.6.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:
+
+ @load "filefuncs"
+ ...
+ 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"
+ 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 Time Functions::).
+
+`"pmode"'
+ The file's "printable mode." This is a string representation of
+ the file's type and permissions, such as 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.
+
+`"devbsize"'
+ The size of a block for the element indexed by `"blocks"'. This
+ information is derived from either the `DEV_BSIZE' constant
+ defined in `<sys/param.h>' on most systems, or the `S_BLKSIZE'
+ constant in `<sys/stat.h>' on BSD systems. For some other
+ systems, "a priori" knowledge is used to provide a value. Where no
+ value can be determined, it defaults to 512.
+
+ 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.
+
+
+File: gawk.info, Node: Internal File Ops, Next: Using Internal File Ops, Prev: Internal File Description, Up: Extension Example
+
+16.6.2 C Code for `chdir()' and `stat()'
+----------------------------------------
+
+Here is the C code for these extensions.(1)
+
+ The file includes a number of standard header files, and then
+includes the `gawkapi.h' header file which provides the API definitions.
+Those are followed by the necessary variable declarations to make use
+of the API macros and boilerplate code (*note Extension API
+Boilerplate::):
+
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+
+ #include <stdio.h>
+ #include <assert.h>
+ #include <errno.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
+
+ #include <sys/types.h>
+ #include <sys/stat.h>
+
+ #include "gawkapi.h"
+
+ #include "gettext.h"
+ #define _(msgid) gettext(msgid)
+ #define N_(msgid) msgid
+
+ #include "gawkfts.h"
+ #include "stack.h"
+
+ static const gawk_api_t *api; /* for convenience macros to work */
+ static awk_ext_id_t *ext_id;
+ static awk_bool_t init_filefuncs(void);
+ static awk_bool_t (*init_func)(void) = init_filefuncs;
+ static const char *ext_version = "filefuncs extension: version 1.0";
+
+ int plugin_is_GPL_compatible;
+
+ By convention, for an `awk' function `foo()', the C function that
+implements it is called `do_foo()'. The function should have two
+arguments: the first is an `int' usually called `nargs', that
+represents the number of actual arguments for the function. The second
+is a pointer to an `awk_value_t', usually named `result':
+
+ /* do_chdir --- provide dynamically loaded chdir() function for gawk */
+
+ static awk_value_t *
+ do_chdir(int nargs, awk_value_t *result)
+ {
+ awk_value_t newdir;
+ int ret = -1;
+
+ assert(result != NULL);
+
+ if (do_lint && nargs != 1)
+ lintwarn(ext_id,
+ _("chdir: called with incorrect number of arguments, "
+ "expecting 1"));
+
+ The `newdir' variable represents the new directory to change to,
+which is retrieved with `get_argument()'. Note that the first argument
+is numbered zero.
+
+ If the argument is retrieved successfully, the function calls the
+`chdir()' system call. If the `chdir()' fails, `ERRNO' is updated:
+
+ if (get_argument(0, AWK_STRING, & newdir)) {
+ ret = chdir(newdir.str_value.str);
+ if (ret < 0)
+ update_ERRNO_int(errno);
+ }
+
+ Finally, the function returns the return value to the `awk' level:
+
+ return make_number(ret, result);
+ }
+
+ The `stat()' extension 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(unsigned long fmode)
+ {
+ ...
+ }
+
+ Next comes a function for reading symbolic links, which is also
+omitted here for brevity:
+
+ /* read_symlink --- read a symbolic link into an allocated buffer.
+ ... */
+
+ static char *
+ read_symlink(const char *fname, size_t bufsize, ssize_t *linksize)
+ {
+ ...
+ }
+
+ Two helper functions simplify entering values in the array that will
+contain the result of the `stat()':
+
+ /* array_set --- set an array element */
+
+ static void
+ array_set(awk_array_t array, const char *sub, awk_value_t *value)
+ {
+ awk_value_t index;
+
+ set_array_element(array,
+ make_const_string(sub, strlen(sub), & index),
+ value);
+
+ }
+
+ /* array_set_numeric --- set an array element with a number */
+
+ static void
+ array_set_numeric(awk_array_t array, const char *sub, double num)
+ {
+ awk_value_t tmp;
+
+ array_set(array, sub, make_number(num, & tmp));
+ }
+
+ The following function does most of the work to fill in the
+`awk_array_t' result array with values obtained from a valid `struct
+stat'. It is done in a separate function to support the `stat()'
+function for `gawk' and also to support the `fts()' extension which is
+included in the same file but whose code is not shown here (*note
+Extension Sample File Functions::).
+
+ The first part of the function is variable declarations, including a
+table to map file types to strings:
+
+ /* fill_stat_array --- do the work to fill an array with stat info */
+
+ static int
+ fill_stat_array(const char *name, awk_array_t array, struct stat *sbuf)
+ {
+ char *pmode; /* printable mode */
+ const char *type = "unknown";
+ awk_value_t tmp;
+ static struct ftype_map {
+ unsigned int mask;
+ const char *type;
+ } ftype_map[] = {
+ { S_IFREG, "file" },
+ { S_IFBLK, "blockdev" },
+ { S_IFCHR, "chardev" },
+ { S_IFDIR, "directory" },
+ #ifdef S_IFSOCK
+ { S_IFSOCK, "socket" },
+ #endif
+ #ifdef S_IFIFO
+ { S_IFIFO, "fifo" },
+ #endif
+ #ifdef S_IFLNK
+ { S_IFLNK, "symlink" },
+ #endif
+ #ifdef S_IFDOOR /* Solaris weirdness */
+ { S_IFDOOR, "door" },
+ #endif /* S_IFDOOR */
+ };
+ int j, k;
+
+ The destination array is cleared, and then code fills in various
+elements based on values in the `struct stat':
+
+ /* empty out the array */
+ clear_array(array);
+
+ /* fill in the array */
+ array_set(array, "name", make_const_string(name, strlen(name),
+ & tmp));
+ array_set_numeric(array, "dev", sbuf->st_dev);
+ array_set_numeric(array, "ino", sbuf->st_ino);
+ array_set_numeric(array, "mode", sbuf->st_mode);
+ array_set_numeric(array, "nlink", sbuf->st_nlink);
+ array_set_numeric(array, "uid", sbuf->st_uid);
+ array_set_numeric(array, "gid", sbuf->st_gid);
+ array_set_numeric(array, "size", sbuf->st_size);
+ array_set_numeric(array, "blocks", sbuf->st_blocks);
+ array_set_numeric(array, "atime", sbuf->st_atime);
+ array_set_numeric(array, "mtime", sbuf->st_mtime);
+ array_set_numeric(array, "ctime", 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)) {
+ array_set_numeric(array, "rdev", sbuf->st_rdev);
+ array_set_numeric(array, "major", major(sbuf->st_rdev));
+ array_set_numeric(array, "minor", minor(sbuf->st_rdev));
+ }
+
+The latter part of the function makes selective additions to the
+destination array, depending upon the availability of certain members
+and/or the type of the file. It then returns zero, for success:
+
+ #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+ array_set_numeric(array, "blksize", sbuf->st_blksize);
+ #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
+
+ pmode = format_mode(sbuf->st_mode);
+ array_set(array, "pmode", make_const_string(pmode, strlen(pmode),
+ & tmp));
+
+ /* for symbolic links, add a linkval field */
+ if (S_ISLNK(sbuf->st_mode)) {
+ char *buf;
+ ssize_t linksize;
+
+ if ((buf = read_symlink(name, sbuf->st_size,
+ & linksize)) != NULL)
+ array_set(array, "linkval",
+ make_malloced_string(buf, linksize, & tmp));
+ else
+ warning(ext_id, _("stat: unable to read symbolic link `%s'"),
+ name);
+ }
+
+ /* add a type field */
+ type = "unknown"; /* shouldn't happen */
+ for (j = 0, k = sizeof(ftype_map)/sizeof(ftype_map[0]); j < k; j++) {
+ if ((sbuf->st_mode & S_IFMT) == ftype_map[j].mask) {
+ type = ftype_map[j].type;
+ break;
+ }
+ }
+
+ array_set(array, "type", make_const_string(type, strlen(type), & tmp));
+
+ return 0;
+ }
+
+ The third argument to `stat()' was not discussed previously. This
+argument is optional. If present, it causes `do_stat()' to use the
+`stat()' system call instead of the `lstat()' system call. This is
+done by using a function pointer: `statfunc'. `statfunc' is
+initialized to point to `lstat()' (instead of `stat()') to get the file
+information, in case the file is a symbolic link. However, if there
+were three arguments, `statfunc' is set point to `stat()', instead.
+
+ Here is the `do_stat()' function, which starts with variable
+declarations and argument checking:
+
+ /* do_stat --- provide a stat() function for gawk */
+
+ static awk_value_t *
+ do_stat(int nargs, awk_value_t *result)
+ {
+ awk_value_t file_param, array_param;
+ char *name;
+ awk_array_t array;
+ int ret;
+ struct stat sbuf;
+ /* default is lstat() */
+ int (*statfunc)(const char *path, struct stat *sbuf) = lstat;
+
+ assert(result != NULL);
+
+ if (nargs != 2 && nargs != 3) {
+ if (do_lint)
+ lintwarn(ext_id,
+ _("stat: called with wrong number of arguments"));
+ return make_number(-1, result);
+ }
+
+ Then comes the actual work. First, the function gets the arguments.
+Next, it gets the information for the file. If the called function
+(`lstat()' or `stat()') returns an error, the code sets `ERRNO' and
+returns:
+
+ /* file is first arg, array to hold results is second */
+ if ( ! get_argument(0, AWK_STRING, & file_param)
+ || ! get_argument(1, AWK_ARRAY, & array_param)) {
+ warning(ext_id, _("stat: bad parameters"));
+ return make_number(-1, result);
+ }
+
+ if (nargs == 3) {
+ statfunc = stat;
+ }
+
+ name = file_param.str_value.str;
+ array = array_param.array_cookie;
+
+ /* always empty out the array */
+ clear_array(array);
+
+ /* stat the file, if error, set ERRNO and return */
+ ret = statfunc(name, & sbuf);
+ if (ret < 0) {
+ update_ERRNO_int(errno);
+ return make_number(ret, result);
+ }
+
+ The tedious work is done by `fill_stat_array()', shown earlier.
+When done, the function returns the result from `fill_stat_array()':
+
+ ret = fill_stat_array(name, array, & sbuf);
+
+ return make_number(ret, result);
+ }
+
+ Finally, it's necessary to provide the "glue" that loads the new
+function(s) into `gawk'.
+
+ The `filefuncs' extension also provides an `fts()' function, which
+we omit here. For its sake there is an initialization function:
+
+ /* init_filefuncs --- initialization routine */
+
+ static awk_bool_t
+ init_filefuncs(void)
+ {
+ ...
+ }
+
+ We are almost done. We need an array of `awk_ext_func_t' structures
+for loading each function into `gawk':
+
+ static awk_ext_func_t func_table[] = {
+ { "chdir", do_chdir, 1 },
+ { "stat", do_stat, 2 },
+ #ifndef __MINGW32__
+ { "fts", do_fts, 3 },
+ #endif
+ };
+
+ Each extension must have a routine named `dl_load()' to load
+everything that needs to be loaded. It is simplest to use the
+`dl_load_func()' macro in `gawkapi.h':
+
+ /* define the dl_load() function using the boilerplate macro */
+
+ dl_load_func(func_table, filefuncs, "")
+
+ And that's it!
+
+ ---------- Footnotes ----------
+
+ (1) This version is edited slightly for presentation. See
+`extension/filefuncs.c' in the `gawk' distribution for the complete
+version.
+
+
+File: gawk.info, Node: Using Internal File Ops, Prev: Internal File Ops, Up: Extension Example
+
+16.6.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 `gawkapi.h' header file, the following steps(1)
+create a GNU/Linux shared library:
+
+ $ gcc -fPIC -shared -DHAVE_CONFIG_H -c -O -g -IIDIR filefuncs.c
+ $ gcc -o filefuncs.so -shared filefuncs.o
+
+ Once the library exists, it is loaded by using the `@load' keyword:
+
+ # file testff.awk
+ @load "filefuncs"
+
+ BEGIN {
+ "pwd" | getline curdir # save current directory
+ close("pwd")
+
+ chdir("/tmp")
+ system("pwd") # test it
+ chdir(curdir) # go back
+
+ 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"])
+ }
+
+ The `AWKLIBPATH' environment variable tells `gawk' where to find
+extensions (*note Finding Extensions::). We set it to the current
+directory and run the program:
+
+ $ AWKLIBPATH=$PWD gawk -f testff.awk
+ -| /tmp
+ -| Info for testff.awk
+ -| ret = 0
+ -| data["blksize"] = 4096
+ -| data["devbsize"] = 512
+ -| data["mtime"] = 1412004710
+ -| data["mode"] = 33204
+ -| data["type"] = file
+ -| data["dev"] = 2053
+ -| data["gid"] = 1000
+ -| data["ino"] = 10358899
+ -| data["ctime"] = 1412004710
+ -| data["blocks"] = 8
+ -| data["nlink"] = 1
+ -| data["name"] = testff.awk
+ -| data["atime"] = 1412004716
+ -| data["pmode"] = -rw-rw-r--
+ -| data["size"] = 666
+ -| data["uid"] = 1000
+ -| testff.awk modified: 09 29 2014 18:31:50
+ -|
+ -| Info for JUNK
+ -| ret = -1
+ -| JUNK modified: 01 01 1970 02:00:00
+
+ ---------- Footnotes ----------
+
+ (1) In practice, you would probably want to use the GNU Autotools
+(Automake, Autoconf, Libtool, and `gettext') to configure and build
+your libraries. Instructions for doing so are beyond the scope of this
+Info file. *Note gawkextlib::, for Internet links to the tools.
+
+
+File: gawk.info, Node: Extension Samples, Next: gawkextlib, Prev: Extension Example, Up: Dynamic Extensions
+
+16.7 The Sample Extensions in the `gawk' Distribution
+=====================================================
+
+This minor node provides brief overviews of the sample extensions that
+come in the `gawk' distribution. Some of them are intended for
+production use (e.g., the `filefuncs', `readdir' and `inplace'
+extensions). Others mainly provide example code that shows how to use
+the extension API.
+
+* Menu:
+
+* Extension Sample File Functions:: The file functions sample.
+* Extension Sample Fnmatch:: An interface to `fnmatch()'.
+* Extension Sample Fork:: An interface to `fork()' and other
+ process functions.
+* Extension Sample Inplace:: Enabling in-place file editing.
+* Extension Sample Ord:: Character to value to character
+ conversions.
+* Extension Sample Readdir:: An interface to `readdir()'.
+* Extension Sample Revout:: Reversing output sample output wrapper.
+* Extension Sample Rev2way:: Reversing data sample two-way processor.
+* Extension Sample Read write array:: Serializing an array to a file.
+* Extension Sample Readfile:: Reading an entire file into a string.
+* Extension Sample Time:: An interface to `gettimeofday()'
+ and `sleep()'.
+* Extension Sample API Tests:: Tests for the API.
+
+
+File: gawk.info, Node: Extension Sample File Functions, Next: Extension Sample Fnmatch, Up: Extension Samples
+
+16.7.1 File-Related Functions
+-----------------------------
+
+The `filefuncs' extension provides three different functions, as
+follows. The usage is:
+
+`@load "filefuncs"'
+ This is how you load the extension.
+
+`result = chdir("/some/directory")'
+ The `chdir()' function is a direct hook to the `chdir()' system
+ call to change the current directory. It returns zero upon
+ success or less than zero upon error. In the latter case, it
+ updates `ERRNO'.
+
+`result = stat("/some/path", statdata' [`, follow']`)'
+ The `stat()' function provides a hook into the `stat()' system
+ call. It returns zero upon success or less than zero upon error.
+ In the latter case, it updates `ERRNO'.
+
+ By default, it uses the `lstat()' system call. However, if passed
+ a third argument, it uses `stat()' instead.
+
+ In all cases, it clears the `statdata' array. When the call is
+ successful, `stat()' fills the `statdata' array with information
+ retrieved from the filesystem, as follows:
+
+ Subscript Field in `struct stat' File type
+ ------------------------------------------------------------
+ `"name"' The file name All
+ `"dev"' `st_dev' All
+ `"ino"' `st_ino' All
+ `"mode"' `st_mode' All
+ `"nlink"' `st_nlink' All
+ `"uid"' `st_uid' All
+ `"gid"' `st_gid' All
+ `"size"' `st_size' All
+ `"atime"' `st_atime' All
+ `"mtime"' `st_mtime' All
+ `"ctime"' `st_ctime' All
+ `"rdev"' `st_rdev' Device files
+ `"major"' `st_major' Device files
+ `"minor"' `st_minor' Device files
+ `"blksize"'`st_blksize' All
+ `"pmode"' A human-readable version of the All
+ mode value, such as printed by
+ `ls'. For example,
+ `"-rwxr-xr-x"'
+ `"linkval"'The value of the symbolic link Symbolic
+ links
+ `"type"' The type of the file as a string. All
+ One of `"file"', `"blockdev"',
+ `"chardev"', `"directory"',
+ `"socket"', `"fifo"', `"symlink"',
+ `"door"', or `"unknown"'. Not
+ all systems support all file
+ types.
+
+`flags = or(FTS_PHYSICAL, ...)'
+`result = fts(pathlist, flags, filedata)'
+ Walk the file trees provided in `pathlist' and fill in the
+ `filedata' array as described next. `flags' is the bitwise OR of
+ several predefined values, also described in a moment. Return
+ zero if there were no errors, otherwise return -1.
+
+ The `fts()' function provides a hook to the C library `fts()'
+routines for traversing file hierarchies. Instead of returning data
+about one file at a time in a stream, it fills in a multidimensional
+array with data about each file and directory encountered in the
+requested hierarchies.
+
+ The arguments are as follows:
+
+`pathlist'
+ An array of file names. The element values are used; the index
+ values are ignored.
+
+`flags'
+ This should be the bitwise OR of one or more of the following
+ predefined constant flag values. At least one of `FTS_LOGICAL' or
+ `FTS_PHYSICAL' must be provided; otherwise `fts()' returns an
+ error value and sets `ERRNO'. The flags are:
+
+ `FTS_LOGICAL'
+ Do a "logical" file traversal, where the information returned
+ for a symbolic link refers to the linked-to file, and not to
+ the symbolic link itself. This flag is mutually exclusive
+ with `FTS_PHYSICAL'.
+
+ `FTS_PHYSICAL'
+ Do a "physical" file traversal, where the information
+ returned for a symbolic link refers to the symbolic link
+ itself. This flag is mutually exclusive with `FTS_LOGICAL'.
+
+ `FTS_NOCHDIR'
+ As a performance optimization, the C library `fts()' routines
+ change directory as they traverse a file hierarchy. This
+ flag disables that optimization.
+
+ `FTS_COMFOLLOW'
+ Immediately follow a symbolic link named in `pathlist',
+ whether or not `FTS_LOGICAL' is set.
+
+ `FTS_SEEDOT'
+ By default, the C library `fts()' routines do not return
+ entries for `.' (dot) and `..' (dot-dot). This option causes
+ entries for dot-dot to also be included. (The extension
+ always includes an entry for dot; more on this in a moment.)
+
+ `FTS_XDEV'
+ During a traversal, do not cross onto a different mounted
+ filesystem.
+
+`filedata'
+ The `filedata' array is first cleared. Then, `fts()' creates an
+ element in `filedata' for every element in `pathlist'. The index
+ is the name of the directory or file given in `pathlist'. The
+ element for this index is itself an array. There are two cases:
+
+ _The path is a file_
+ In this case, the array contains two or three elements:
+
+ `"path"'
+ The full path to this file, starting from the "root"
+ that was given in the `pathlist' array.
+
+ `"stat"'
+ This element is itself an array, containing the same
+ information as provided by the `stat()' function
+ described earlier for its `statdata' argument. The
+ element may not be present if the `stat()' system call
+ for the file failed.
+
+ `"error"'
+ If some kind of error was encountered, the array will
+ also contain an element named `"error"', which is a
+ string describing the error.
+
+ _The path is a directory_
+ In this case, the array contains one element for each entry
+ in the directory. If an entry is a file, that element is the
+ same as for files, just described. If the entry is a
+ directory, that element is (recursively) an array describing
+ the subdirectory. If `FTS_SEEDOT' was provided in the flags,
+ then there will also be an element named `".."'. This
+ element will be an array containing the data as provided by
+ `stat()'.
+
+ In addition, there will be an element whose index is `"."'.
+ This element is an array containing the same two or three
+ elements as for a file: `"path"', `"stat"', and `"error"'.
+
+ The `fts()' function returns zero if there were no errors.
+Otherwise it returns -1.
+
+ NOTE: The `fts()' extension does not exactly mimic the interface
+ of the C library `fts()' routines, choosing instead to provide an
+ interface that is based on associative arrays, which is more
+ comfortable to use from an `awk' program. This includes the lack
+ of a comparison function, because `gawk' already provides powerful
+ array sorting facilities. Although an `fts_read()'-like interface
+ could have been provided, this felt less natural than simply
+ creating a multidimensional array to represent the file hierarchy
+ and its information.
+
+ See `test/fts.awk' in the `gawk' distribution for an example use of
+the `fts()' extension function.
+
+
+File: gawk.info, Node: Extension Sample Fnmatch, Next: Extension Sample Fork, Prev: Extension Sample File Functions, Up: Extension Samples
+
+16.7.2 Interface to `fnmatch()'
+-------------------------------
+
+This extension provides an interface to the C library `fnmatch()'
+function. The usage is:
+
+`@load "fnmatch"'
+ This is how you load the extension.
+
+`result = fnmatch(pattern, string, flags)'
+ The return value is zero on success, `FNM_NOMATCH' if the string
+ did not match the pattern, or a different nonzero value if an
+ error occurred.
+
+ In addition to the `fnmatch()' function, the `fnmatch' extension
+adds one constant (`FNM_NOMATCH'), and an array of flag values named
+`FNM'.
+
+ The arguments to `fnmatch()' are:
+
+`pattern'
+ The file name wildcard to match.
+
+`string'
+ The file name string.
+
+`flag'
+ Either zero, or the bitwise OR of one or more of the flags in the
+ `FNM' array.
+
+ The flags are as follows:
+
+Array element Corresponding flag defined by `fnmatch()'
+--------------------------------------------------------------------------
+`FNM["CASEFOLD"]' `FNM_CASEFOLD'
+`FNM["FILE_NAME"]' `FNM_FILE_NAME'
+`FNM["LEADING_DIR"]'`FNM_LEADING_DIR'
+`FNM["NOESCAPE"]' `FNM_NOESCAPE'
+`FNM["PATHNAME"]' `FNM_PATHNAME'
+`FNM["PERIOD"]' `FNM_PERIOD'
+
+ Here is an example:
+
+ @load "fnmatch"
+ ...
+ flags = or(FNM["PERIOD"], FNM["NOESCAPE"])
+ if (fnmatch("*.a", "foo.c", flags) == FNM_NOMATCH)
+ print "no match"
+
+
+File: gawk.info, Node: Extension Sample Fork, Next: Extension Sample Inplace, Prev: Extension Sample Fnmatch, Up: Extension Samples
+
+16.7.3 Interface to `fork()', `wait()', and `waitpid()'
+-------------------------------------------------------
+
+The `fork' extension adds three functions, as follows:
+
+`@load "fork"'
+ This is how you load the extension.
+
+`pid = fork()'
+ This function creates a new process. The return value is zero in
+ the child and the process-ID number of the child in the parent, or
+ -1 upon error. In the latter case, `ERRNO' indicates the problem.
+ In the child, `PROCINFO["pid"]' and `PROCINFO["ppid"]' are updated
+ to reflect the correct values.
+
+`ret = waitpid(pid)'
+ This function takes a numeric argument, which is the process-ID to
+ wait for. The return value is that of the `waitpid()' system call.
+
+`ret = wait()'
+ This function waits for the first child to die. The return value
+ is that of the `wait()' system call.
+
+ There is no corresponding `exec()' function.
+
+ Here is an example:
+
+ @load "fork"
+ ...
+ if ((pid = fork()) == 0)
+ print "hello from the child"
+ else
+ print "hello from the parent"
+
+
+File: gawk.info, Node: Extension Sample Inplace, Next: Extension Sample Ord, Prev: Extension Sample Fork, Up: Extension Samples
+
+16.7.4 Enabling In-Place File Editing
+-------------------------------------
+
+The `inplace' extension emulates GNU `sed''s `-i' option which performs
+"in place" editing of each input file. It uses the bundled
+`inplace.awk' include file to invoke the extension properly:
+
+ # inplace --- load and invoke the inplace extension.
+
+ @load "inplace"
+
+ # Please set INPLACE_SUFFIX to make a backup copy. For example, you may
+ # want to set INPLACE_SUFFIX to .bak on the command line or in a BEGIN rule.
+
+ BEGINFILE {
+ inplace_begin(FILENAME, INPLACE_SUFFIX)
+ }
+
+ ENDFILE {
+ inplace_end(FILENAME, INPLACE_SUFFIX)
+ }
+
+ For each regular file that is processed, the extension redirects
+standard output to a temporary file configured to have the same owner
+and permissions as the original. After the file has been processed,
+the extension restores standard output to its original destination. If
+`INPLACE_SUFFIX' is not an empty string, the original file is linked to
+a backup file name created by appending that suffix. Finally, the
+temporary file is renamed to the original file name.
+
+ If any error occurs, the extension issues a fatal error to terminate
+processing immediately without damaging the original file.
+
+ Here are some simple examples:
+
+ $ gawk -i inplace '{ gsub(/foo/, "bar") }; { print }' file1 file2 file3
+
+ To keep a backup copy of the original files, try this:
+
+ $ gawk -i inplace -v INPLACE_SUFFIX=.bak '{ gsub(/foo/, "bar") }
+ > { print }' file1 file2 file3
+
+
+File: gawk.info, Node: Extension Sample Ord, Next: Extension Sample Readdir, Prev: Extension Sample Inplace, Up: Extension Samples
+
+16.7.5 Character and Numeric values: `ord()' and `chr()'
+--------------------------------------------------------
+
+The `ordchr' extension adds two functions, named `ord()' and `chr()',
+as follows:
+
+`@load "ordchr"'
+ This is how you load the extension.
+
+`number = ord(string)'
+ Return the numeric value of the first character in `string'.
+
+`char = chr(number)'
+ Return a string whose first character is that represented by
+ `number'.
+
+ These functions are inspired by the Pascal language functions of the
+same name. Here is an example:
+
+ @load "ordchr"
+ ...
+ printf("The numeric value of 'A' is %d\n", ord("A"))
+ printf("The string value of 65 is %s\n", chr(65))
+
+
+File: gawk.info, Node: Extension Sample Readdir, Next: Extension Sample Revout, Prev: Extension Sample Ord, Up: Extension Samples
+
+16.7.6 Reading Directories
+--------------------------
+
+The `readdir' extension adds an input parser for directories. The
+usage is as follows:
+
+ @load "readdir"
+
+ When this extension is in use, instead of skipping directories named
+on the command line (or with `getline'), they are read, with each entry
+returned as a record.
+
+ The record consists of three fields. The first two are the inode
+number and the file name, separated by a forward slash character. On
+systems where the directory entry contains the file type, the record
+has a third field (also separated by a slash) which is a single letter
+indicating the type of the file. The letters and their corresponding
+file types are shown in *note table-readdir-file-types::.
+
+Letter File Type
+--------------------------------------------------------------------------
+`b' Block device
+`c' Character device
+`d' Directory
+`f' Regular file
+`l' Symbolic link
+`p' Named pipe (FIFO)
+`s' Socket
+`u' Anything else (unknown)
+
+Table 16.2: File types returned by the `readdir' extension
+
+ On systems without the file type information, the third field is
+always `u'.
+
+ NOTE: On GNU/Linux systems, there are filesystems that don't
+ support the `d_type' entry (see the readdir(3) manual page), and
+ so the file type is always `u'. You can use the `filefuncs'
+ extension to call `stat()' in order to get correct type
+ information.
+
+ Here is an example:
+
+ @load "readdir"
+ ...
+ BEGIN { FS = "/" }
+ { print "file name is", $2 }
+
+
+File: gawk.info, Node: Extension Sample Revout, Next: Extension Sample Rev2way, Prev: Extension Sample Readdir, Up: Extension Samples
+
+16.7.7 Reversing Output
+-----------------------
+
+The `revoutput' extension adds a simple output wrapper that reverses
+the characters in each output line. Its main purpose is to show how to
+write an output wrapper, although it may be mildly amusing for the
+unwary. Here is an example:
+
+ @load "revoutput"
+
+ BEGIN {
+ REVOUT = 1
+ print "don't panic" > "/dev/stdout"
+ }
+
+ The output from this program is: `cinap t'nod'.
+
+
+File: gawk.info, Node: Extension Sample Rev2way, Next: Extension Sample Read write array, Prev: Extension Sample Revout, Up: Extension Samples
+
+16.7.8 Two-Way I/O Example
+--------------------------
+
+The `revtwoway' extension adds a simple two-way processor that reverses
+the characters in each line sent to it for reading back by the `awk'
+program. Its main purpose is to show how to write a two-way processor,
+although it may also be mildly amusing. The following example shows
+how to use it:
+
+ @load "revtwoway"
+
+ BEGIN {
+ cmd = "/magic/mirror"
+ print "don't panic" |& cmd
+ cmd |& getline result
+ print result
+ close(cmd)
+ }
+
+ The output from this program is: `cinap t'nod'.
+
+
+File: gawk.info, Node: Extension Sample Read write array, Next: Extension Sample Readfile, Prev: Extension Sample Rev2way, Up: Extension Samples
+
+16.7.9 Dumping and Restoring an Array
+-------------------------------------
+
+The `rwarray' extension adds two functions, named `writea()' and
+`reada()', as follows:
+
+`@load "rwarray"'
+ This is how you load the extension.
+
+`ret = writea(file, array)'
+ This function takes a string argument, which is the name of the
+ file to which to dump the array, and the array itself as the
+ second argument. `writea()' understands arrays of arrays. It
+ returns one on success, or zero upon failure.
+
+`ret = reada(file, array)'
+ `reada()' is the inverse of `writea()'; it reads the file named as
+ its first argument, filling in the array named as the second
+ argument. It clears the array first. Here too, the return value
+ is one on success and zero upon failure.
+
+ The array created by `reada()' is identical to that written by
+`writea()' in the sense that the contents are the same. However, due to
+implementation issues, the array traversal order of the re-created
+array is likely to be different from that of the original array. As
+array traversal order in `awk' is by default undefined, this is
+(technically) not a problem. If you need to guarantee a particular
+traversal order, use the array sorting features in `gawk' to do so
+(*note Array Sorting::).
+
+ The file contains binary data. All integral values are written in
+network byte order. However, double-precision floating-point values
+are written as native binary data. Thus, arrays containing only string
+data can theoretically be dumped on systems with one byte order and
+restored on systems with a different one, but this has not been tried.
+
+ Here is an example:
+
+ @load "rwarray"
+ ...
+ ret = writea("arraydump.bin", array)
+ ...
+ ret = reada("arraydump.bin", array)
+
+
+File: gawk.info, Node: Extension Sample Readfile, Next: Extension Sample Time, Prev: Extension Sample Read write array, Up: Extension Samples
+
+16.7.10 Reading an Entire File
+------------------------------
+
+The `readfile' extension adds a single function named `readfile()', and
+an input parser:
+
+`@load "readfile"'
+ This is how you load the extension.
+
+`result = readfile("/some/path")'
+ The argument is the name of the file to read. The return value is
+ a string containing the entire contents of the requested file.
+ Upon error, the function returns the empty string and sets `ERRNO'.
+
+`BEGIN { PROCINFO["readfile"] = 1 }'
+ In addition, the extension adds an input parser that is activated
+ if `PROCINFO["readfile"]' exists. When activated, each input file
+ is returned in its entirety as `$0'. `RT' is set to the null
+ string.
+
+ Here is an example:
+
+ @load "readfile"
+ ...
+ contents = readfile("/path/to/file");
+ if (contents == "" && ERRNO != "") {
+ print("problem reading file", ERRNO) > "/dev/stderr"
+ ...
+ }
+
+
+File: gawk.info, Node: Extension Sample Time, Next: Extension Sample API Tests, Prev: Extension Sample Readfile, Up: Extension Samples
+
+16.7.11 Extension Time Functions
+--------------------------------
+
+The `time' extension adds two functions, named `gettimeofday()' and
+`sleep()', as follows:
+
+`@load "time"'
+ This is how you load the extension.
+
+`the_time = gettimeofday()'
+ Return the time in seconds that has elapsed since 1970-01-01 UTC
+ as a floating-point value. If the time is unavailable on this
+ platform, return -1 and set `ERRNO'. The returned time should
+ have sub-second precision, but the actual precision may vary based
+ on the platform. If the standard C `gettimeofday()' system call
+ is available on this platform, then it simply returns the value.
+ Otherwise, if on MS-Windows, it tries to use
+ `GetSystemTimeAsFileTime()'.
+
+`result = sleep(SECONDS)'
+ Attempt to sleep for SECONDS seconds. If SECONDS is negative, or
+ the attempt to sleep fails, return -1 and set `ERRNO'. Otherwise,
+ return zero after sleeping for the indicated amount of time. Note
+ that SECONDS may be a floating-point (non-integral) value.
+ Implementation details: depending on platform availability, this
+ function tries to use `nanosleep()' or `select()' to implement the
+ delay.
+
+
+File: gawk.info, Node: Extension Sample API Tests, Prev: Extension Sample Time, Up: Extension Samples
+
+16.7.12 API Tests
+-----------------
+
+The `testext' extension exercises parts of the extension API that are
+not tested by the other samples. The `extension/testext.c' file
+contains both the C code for the extension and `awk' test code inside C
+comments that run the tests. The testing framework extracts the `awk'
+code and runs the tests. See the source file for more information.
+
+
+File: gawk.info, Node: gawkextlib, Next: Extension summary, Prev: Extension Samples, Up: Dynamic Extensions
+
+16.8 The `gawkextlib' Project
+=============================
+
+The `gawkextlib' (http://sourceforge.net/projects/gawkextlib/) project
+provides a number of `gawk' extensions, including one for processing
+XML files. This is the evolution of the original `xgawk' (XML `gawk')
+project.
+
+ As of this writing, there are six extensions:
+
+ * GD graphics library extension
+
+ * PDF extension
+
+ * PostgreSQL extension
+
+ * MPFR library extension (this provides access to a number of MPFR
+ functions which `gawk''s native MPFR support does not)
+
+ * Redis extension
+
+ * XML parser extension, using the Expat
+ (http://expat.sourceforge.net) XML parsing library
+
+ You can check out the code for the `gawkextlib' project using the
+Git (http://git-scm.com) distributed source code control system. The
+command is as follows:
+
+ git clone git://git.code.sf.net/p/gawkextlib/code gawkextlib-code
+
+ You will need to have the Expat (http://expat.sourceforge.net) XML
+parser library installed in order to build and use the XML extension.
+
+ In addition, you must have the GNU Autotools installed (Autoconf
+(http://www.gnu.org/software/autoconf), Automake
+(http://www.gnu.org/software/automake), Libtool
+(http://www.gnu.org/software/libtool), and GNU `gettext'
+(http://www.gnu.org/software/gettext)).
+
+ The simple recipe for building and testing `gawkextlib' is as
+follows. First, build and install `gawk':
+
+ cd .../path/to/gawk/code
+ ./configure --prefix=/tmp/newgawk Install in /tmp/newgawk for now
+ make && make check Build and check that all is OK
+ make install Install gawk
+
+ Next, build `gawkextlib' and test it:
+
+ cd .../path/to/gawkextlib-code
+ ./update-autotools Generate configure, etc.
+ You may have to run this command twice
+ ./configure --with-gawk=/tmp/newgawk Configure, point at "installed" gawk
+ make && make check Build and check that all is OK
+ make install Install the extensions
+
+ If you have installed `gawk' in the standard way, then you will
+likely not need the `--with-gawk' option when configuring `gawkextlib'.
+You may also need to use the `sudo' utility to install both `gawk' and
+`gawkextlib', depending upon how your system works.
+
+ If you write an extension that you wish to share with other `gawk'
+users, consider doing so through the `gawkextlib' project. See the
+project's website for more information.
+
+
+File: gawk.info, Node: Extension summary, Next: Extension Exercises, Prev: gawkextlib, Up: Dynamic Extensions
+
+16.9 Summary
+============
+
+ * You can write extensions (sometimes called plug-ins) for `gawk' in
+ C or C++ using the application programming interface (API) defined
+ by the `gawk' developers.
+
+ * Extensions must have a license compatible with the GNU General
+ Public License (GPL), and they must assert that fact by declaring
+ a variable named `plugin_is_GPL_compatible'.
+
+ * Communication between `gawk' and an extension is two-way. `gawk'
+ passes a `struct' to the extension which contains various data
+ fields and function pointers. The extension can then call into
+ `gawk' via the supplied function pointers to accomplish certain
+ tasks.
+
+ * One of these tasks is to "register" the name and implementation of
+ new `awk'-level functions with `gawk'. The implementation takes
+ the form of a C function pointer with a defined signature. By
+ convention, implementation functions are named `do_XXXX()' for
+ some `awk'-level function `XXXX()'.
+
+ * The API is defined in a header file named `gawkpi.h'. You must
+ include a number of standard header files _before_ including it in
+ your source file.
+
+ * API function pointers are provided for the following kinds of
+ operations:
+
+ * Allocating, reallocating, and releasing memory
+
+ * Registration functions (you may register extension functions,
+ exit callbacks, a version string, input parsers, output
+ wrappers, and two-way processors)
+
+ * Printing fatal, warning, and "lint" warning messages
+
+ * Updating `ERRNO', or unsetting it
+
+ * Accessing parameters, including converting an undefined
+ parameter into an array
+
+ * Symbol table access (retrieving a global variable, creating
+ one, or changing one)
+
+ * Creating and releasing cached values; this provides an
+ efficient way to use values for multiple variables and can be
+ a big performance win
+
+ * Manipulating arrays (retrieving, adding, deleting, and
+ modifying elements; getting the count of elements in an array;
+ creating a new array; clearing an array; and flattening an
+ array for easy C style looping over all its indices and
+ elements)
+
+ * The API defines a number of standard data types for representing
+ `awk' values, array elements, and arrays.
+
+ * The API provide convenience functions for constructing values. It
+ also provides memory management functions to ensure compatibility
+ between memory allocated by `gawk' and memory allocated by an
+ extension.
+
+ * _All_ memory passed from `gawk' to an extension must be treated as
+ read-only by the extension.
+
+ * _All_ memory passed from an extension to `gawk' must come from the
+ API's memory allocation functions. `gawk' takes responsibility for
+ the memory and releases it when appropriate.
+
+ * The API provides information about the running version of `gawk' so
+ that an extension can make sure it is compatible with the `gawk'
+ that loaded it.
+
+ * It is easiest to start a new extension by copying the boilerplate
+ code described in this major node. Macros in the `gawkapi.h'
+ header file make this easier to do.
+
+ * The `gawk' distribution includes a number of small but useful
+ sample extensions. The `gawkextlib' project includes several more,
+ larger, extensions. If you wish to write an extension and
+ contribute it to the community of `gawk' users, the `gawkextlib'
+ project is the place to do so.
+
+
+
+File: gawk.info, Node: Extension Exercises, Prev: Extension summary, Up: Dynamic Extensions
+
+16.10 Exercises
+===============
+
+ 1. Add functions to implement system calls such as `chown()',
+ `chmod()', and `umask()' to the file operations extension
+ presented in *note Internal File Ops::.
+
+ 2. (Hard.) How would you provide namespaces in `gawk', so that the
+ names of functions in different extensions don't conflict with
+ each other? If you come up with a really good scheme, contact the
+ `gawk' maintainer to tell him about it.
+
+ 3. Write a wrapper script that provides an interface similar to `sed
+ -i' for the "inplace" extension presented in *note Extension
+ Sample Inplace::.
+
+
+
+File: gawk.info, Node: Language History, Next: Installation, Prev: Dynamic Extensions, 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'
+the POSIX specification. Many longtime `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 some 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.
+4.3-Reno. Subsequent versions of Berkeley Unix, and, for a while, some
+systems derived from 4.4BSD-Lite, used 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:
@@ -19787,9 +26210,11 @@ you can find more information.
`awk'.
* POSIX/GNU:: The extensions in `gawk' not in POSIX
`awk'.
+* Feature History:: The history of the features in `gawk'.
* Common Extensions:: Common Extensions Summary.
* Ranges and Locales:: How locales used to affect regexp ranges.
* Contributors:: The major contributors to `gawk'.
+* History summary:: History summary.

File: gawk.info, Node: V7/SVR3.1, Next: SVR4, Up: Language History
@@ -19822,7 +26247,7 @@ the changes, with cross-references to further details:
Functions::).
* The `ARGC', `ARGV', `FNR', `RLENGTH', `RSTART', and `SUBSEP'
- built-in variables (*note Built-in Variables::).
+ predefined variables (*note Built-in Variables::).
* Assignable `$0' (*note Changing Fields::).
@@ -19843,18 +26268,16 @@ the changes, with cross-references to further details:
Functions::), rather than using only the first character of `FS'.
* Dynamic regexps as operands of the `~' and `!~' operators (*note
- Regexp Usage::).
+ Computed Regexps::).
* 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.)
+ Sequences::).
* Redirection of input for the `getline' function (*note Getline::).
* Multiple `BEGIN' and `END' rules (*note BEGIN/END::).
- * Multidimensional arrays (*note Multi-dimensional::).
+ * Multidimensional arrays (*note Multidimensional::).

File: gawk.info, Node: SVR4, Next: POSIX, Prev: V7/SVR3.1, Up: Language History
@@ -19872,7 +26295,7 @@ The System V Release 4 (1989) version of Unix `awk' added these features
* The `-v' option for assigning variables before program execution
begins (*note Options::).
- * The `--' option for terminating command-line options.
+ * The `--' signal for terminating command-line options.
* The `\a', `\v', and `\x' escape sequences (*note Escape
Sequences::).
@@ -19887,8 +26310,8 @@ The System V Release 4 (1989) version of Unix `awk' added these features
`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::).
+ (`"%*.*d"') in the argument list of `printf' and `sprintf()'
+ (*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 ~
@@ -19915,12 +26338,24 @@ introduced the following changes into the language:
* The concept of a numeric string and tighter comparison rules to go
with it (*note Typing and Comparison::).
- * The use of built-in variables as function parameter names is
- forbidden (*note Definition Syntax::.
+ * The use of predefined variables as function parameter names is
+ forbidden (*note Definition Syntax::).
* More complete documentation of many of the previously undocumented
features of the language.
+ In 2012, a number of extensions that had been commonly available for
+many years were finally added to POSIX. They are:
+
+ * The `fflush()' built-in function for flushing buffered output
+ (*note I/O Functions::).
+
+ * The `nextfile' statement (*note Nextfile Statement::).
+
+ * The ability to delete all of an array at once with `delete ARRAY'
+ (*note Delete::).
+
+
*Note Common Extensions::, for a list of common extensions not
permitted by the POSIX standard.
@@ -19937,9 +26372,9 @@ Brian Kernighan has made his version available via his home page (*note
Other Versions::).
This minor node describes common extensions that originally appeared
-in his version of `awk'.
+in his version of `awk':
- * The `**' and `**=' operators (*note Arithmetic Ops:: and *Note
+ * The `**' and `**=' operators (*note Arithmetic Ops:: and *note
Assignment Ops::).
* The use of `func' as an abbreviation for `function' (*note
@@ -19953,7 +26388,7 @@ in his version of `awk'.
available in his `awk'.

-File: gawk.info, Node: POSIX/GNU, Next: Common Extensions, Prev: BTL, Up: Language History
+File: gawk.info, Node: POSIX/GNU, Next: Feature History, Prev: BTL, Up: Language History
A.5 Extensions in `gawk' Not in POSIX `awk'
===========================================
@@ -19966,7 +26401,7 @@ can all be disabled with either the `--traditional' or `--posix' options
node summarizes the additional features over POSIX `awk' that are in
the current version of `gawk'.
- * Additional built-in variables:
+ * Additional predefined variables:
- The `ARGIND' `BINMODE', `ERRNO', `FIELDWIDTHS', `FPAT',
`IGNORECASE', `LINT', `PROCINFO', `RT', and `TEXTDOMAIN'
@@ -19979,7 +26414,7 @@ the current version of `gawk'.
- The `/inet', `/inet4', and `/inet6' special files for TCP/IP
networking using `|&' to specify which version of the IP
- protocol to use. (*note TCP/IP Networking::).
+ protocol to use (*note TCP/IP Networking::).
* Changes and/or additions to the language:
@@ -20001,18 +26436,13 @@ the current version of `gawk'.
- Indirect function calls (*note Indirect Calls::).
- Directories on the command line produce a warning and are
- skipped (*note Command line directories::).
+ skipped (*note Command-line directories::).
* New keywords:
- - The `BEGINFILE' and `ENDFILE' special patterns. (*note
+ - The `BEGINFILE' and `ENDFILE' special patterns (*note
BEGINFILE/ENDFILE::).
- - The ability to delete all of an array at once with `delete
- ARRAY' (*note Delete::).
-
- - The `nextfile' statement (*note Nextfile Statement::).
-
- The `switch' statement (*note Switch Statement::).
* Changes to standard `awk' functions:
@@ -20021,7 +26451,7 @@ the current version of `gawk'.
one end of a two-way pipe to a coprocess (*note Two-way
I/O::).
- - POSIX compliance for `gsub()' and `sub()'.
+ - POSIX compliance for `gsub()' and `sub()' with `--posix'.
- The `length()' function accepts an array argument and returns
the number of elements in the array (*note String
@@ -20035,44 +26465,50 @@ the current version of `gawk'.
translations easier (*note Printf Ordering::).
- The `split()' function's additional optional fourth argument
- which is an array to hold the text of the field separators.
+ which is an array to hold the text of the field separators
(*note String Functions::).
* Additional functions only in `gawk':
- - The `and()', `compl()', `lshift()', `or()', `rshift()', and
- `xor()' functions for bit manipulation (*note Bitwise
- Functions::).
+ - The `gensub()', `patsplit()', and `strtonum()' functions for
+ more powerful text manipulation (*note String Functions::).
- 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 functions dynamically (*note Dynamic Extensions::).
+ - The `mktime()', `systime()', and `strftime()' functions for
+ working with timestamps (*note Time Functions::).
- - The `fflush()' function from Brian Kernighan's version of
- `awk' (*note I/O Functions::).
+ - The `and()', `compl()', `lshift()', `or()', `rshift()', and
+ `xor()' functions for bit manipulation (*note Bitwise
+ Functions::).
- - The `gensub()', `patsplit()', and `strtonum()' functions for
- more powerful text manipulation (*note String Functions::).
+ - The `isarray()' function to check if a variable is an array
+ or not (*note Type Functions::).
- - The `mktime()', `systime()', and `strftime()' functions for
- working with timestamps (*note Time Functions::).
+ - The `bindtextdomain()', `dcgettext()' and `dcngettext()'
+ functions for internationalization (*note Programmer i18n::).
* Changes and/or additions in the command-line options:
- The `AWKPATH' environment variable for specifying a path
search for the `-f' command-line option (*note Options::).
- - The ability to use GNU-style long-named options that start
- with `--' and the `--characters-as-bytes', `--compat',
- `--dump-variables', `--exec', `--gen-pot', `--lint',
- `--lint-old', `--non-decimal-data', `--posix', `--profile',
- `--re-interval', `--sandbox', `--source', `--traditional', and
- `--use-lc-numeric' options (*note Options::).
+ - The `AWKLIBPATH' environment variable for specifying a path
+ search for the `-l' command-line option (*note Options::).
+
+ - The `-b', `-c', `-C', `-d', `-D', `-e', `-E', `-g', `-h',
+ `-i', `-l', `-L', `-M', `-n', `-N', `-o', `-O', `-p', `-P',
+ `-r', `-S', `-t', and `-V' short options. Also, the ability
+ to use GNU-style long-named options that start with `--' and
+ the `--assign', `--bignum', `--characters-as-bytes',
+ `--copyright', `--debug', `--dump-variables', `--exec',
+ `--field-separator', `--file', `--gen-pot', `--help',
+ `--include', `--lint', `--lint-old', `--load',
+ `--non-decimal-data', `--optimize', `--posix',
+ `--pretty-print', `--profile', `--re-interval', `--sandbox',
+ `--source', `--traditional', `--use-lc-numeric', and
+ `--version' long options (*note Options::).
* Support for the following obsolete systems was removed from the
code and the documentation for `gawk' version 4.0:
@@ -20099,38 +26535,433 @@ the current version of `gawk'.
- Prestandard VAX C compiler for VAX/VMS
+ - GCC for VAX and Alpha has not been tested for a while.
+
+
+ * Support for the following obsolete systems was removed from the
+ code for `gawk' version 4.1:
+
+ - Ultrix
+
+ * Support for MirBSD was removed at `gawk' version 4.2.
+
+
+
+File: gawk.info, Node: Feature History, Next: Common Extensions, Prev: POSIX/GNU, Up: Language History
+
+A.6 History of `gawk' Features
+==============================
+
+This minor node describes the features in `gawk' over and above those
+in POSIX `awk', in the order they were added to `gawk'.
+
+ 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::).
+
+ * Additional command-line options (*note Options::):
+
+ - The `-W lint' option to provide error and portability checking
+ for both the source code and at runtime.
+
+ - The `-W compat' option to turn off the GNU extensions.
+
+ - The `-W posix' option for full POSIX compliance.
+
+ 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:
+
+ * New variables (*note Built-in Variables::):
+
+ - `ARGIND', which tracks the movement of `FILENAME' through
+ `ARGV'.
+
+ - `ERRNO', which contains the system error message when
+ `getline' returns -1 or `close()' fails.
+
+ * The `/dev/pid', `/dev/ppid', `/dev/pgrpid', and `/dev/user'
+ special file names. These have since been removed.
+
+ * The ability to delete all of an array at once with `delete ARRAY'
+ (*note Delete::).
+
+ * Command-line option changes (*note Options::):
+
+ - The ability to use GNU-style long-named options that start
+ with `--'.
+
+ - The `--source' option for mixing command-line and library-file
+ source code.
+
+ Version 3.0 of `gawk' introduced the following features:
+
+ * New or changed variables:
+
+ - `IGNORECASE' changed, now applying to string comparison as
+ well as regexp operations (*note Case-sensitivity::).
+
+ - `RT', which 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 `fflush()' function from BWK `awk' (then at Bell Laboratories;
+ *note I/O Functions::).
+
+ * New command-line options:
+
+ - 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 from BWK `awk'. (Brian was still at Bell
+ Laboratories at the time.) This was later removed from both
+ his `awk' and from `gawk'.
+
+ - 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. This has since been removed.
+
+
+ Version 3.1 of `gawk' introduced the following features:
+
+ * New variables (*note Built-in Variables::):
+
+ - `BINMODE', for non-POSIX systems, which allows binary I/O for
+ input and/or output files (*note PC Using::).
+
+ - `LINT', which dynamically controls lint warnings.
+
+ - `PROCINFO', an array for providing process-related
+ information.
+
+ - `TEXTDOMAIN', for setting an application's
+ internationalization text domain (*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::).
+
+ * A number of new built-in functions:
+
+ - The `asort()' and `asorti()' functions for sorting arrays
+ (*note Array Sorting::).
+
+ - The `bindtextdomain()', `dcgettext()' and `dcngettext()'
+ functions for internationalization (*note Programmer i18n::).
+
+ - The `extension()' function and the ability to add new
+ built-in functions dynamically (*note Dynamic Extensions::).
+
+ - The `mktime()' function for creating timestamps (*note Time
+ Functions::).
+
+ - The `and()', `or()', `xor()', `compl()', `lshift()',
+ `rshift()', and `strtonum()' functions (*note Bitwise
+ Functions::).
+
+ * The support for `next file' as two words was removed completely
+ (*note Nextfile Statement::).
+
+ * Additional command-line options (*note Options::):
+
+ - The `--dump-variables' option to print a list of all global
+ variables.
+
+ - The `--exec' option, for use in CGI scripts.
+
+ - 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 `--use-lc-numeric' option to force `gawk' to use the
+ locale's decimal point for parsing input data (*note
+ Conversion::).
+
+ * 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. This was later removed.
+
+ * Tandem support. This was later removed.
+
+ * The Atari port became officially unsupported and was later removed
+ entirely.
+
+ * The source code changed to use ISO C standard-style function
+ definitions.
+
+ * POSIX compliance for `sub()' and `gsub()' (*note Gory Details::).
+
+ * The `length()' function was extended to accept an array argument
+ and return the number of elements in the array (*note String
+ Functions::).
+
+ * The `strftime()' function acquired a third argument to enable
+ printing times as UTC (*note Time Functions::).
+
+ Version 4.0 of `gawk' introduced the following features:
+
+ * Variable additions:
+
+ - `FPAT', which allows you to specify a regexp that matches the
+ fields, instead of matching the field separator (*note
+ Splitting By Content::).
+
+ - If `PROCINFO["sorted_in"]' exists, `for(iggy in foo)' loops
+ sort the indices before looping over them. The value of this
+ element provides control over how the indices are sorted
+ before the loop traversal starts (*note Controlling
+ Scanning::).
+
+ - `PROCINFO["strftime"]', which holds the default format for
+ `strftime()' (*note Time Functions::).
+
+ * The special files `/dev/pid', `/dev/ppid', `/dev/pgrpid' and
+ `/dev/user' were removed.
+
+ * Support for IPv6 was added via the `/inet6' special file.
+ `/inet4' forces IPv4 and `/inet' chooses the system default, which
+ is probably IPv4 (*note TCP/IP Networking::).
+
+ * The use of `\s' and `\S' escape sequences in regular expressions
+ (*note GNU Regexp Operators::).
+
+ * Interval expressions became part of default regular expressions
+ (*note Regexp Operators::).
+
+ * POSIX character classes work even with `--traditional' (*note
+ Regexp Operators::).
+
+ * `break' and `continue' became invalid outside a loop, even with
+ `--traditional' (*note Break Statement::, and also see *note
+ Continue Statement::).
+
+ * `fflush()', `nextfile', and `delete ARRAY' are allowed if
+ `--posix' or `--traditional', since they are all now part of POSIX.
+
+ * An optional third argument to `asort()' and `asorti()', specifying
+ how to sort (*note String Functions::).
+
+ * The behavior of `fflush()' changed to match BWK `awk' and for
+ POSIX; now both `fflush()' and `fflush("")' flush all open output
+ redirections (*note I/O Functions::).
+
+ * The `isarray()' function which distinguishes if an item is an array
+ or not, to make it possible to traverse arrays of arrays (*note
+ Type Functions::).
+
+ * The `patsplit()' function which gives the same capability as
+ `FPAT', for splitting (*note String Functions::).
+
+ * An optional fourth argument to the `split()' function, which is an
+ array to hold the values of the separators (*note String
+ Functions::).
+
+ * Arrays of arrays (*note Arrays of Arrays::).
+
+ * The `BEGINFILE' and `ENDFILE' special patterns (*note
+ BEGINFILE/ENDFILE::).
+
+ * Indirect function calls (*note Indirect Calls::).
+
+ * `switch' / `case' are enabled by default (*note Switch
+ Statement::).
+
+ * Command-line option changes (*note Options::):
+
+ - The `-b' and `--characters-as-bytes' options which prevent
+ `gawk' from treating input as a multibyte string.
+
+ - The redundant `--compat', `--copyleft', and `--usage' long
+ options were removed.
+
+ - The `--gen-po' option was finally renamed to the correct
+ `--gen-pot'.
+
+ - The `--sandbox' option which disables certain features.
+
+ - All long options acquired corresponding short options, for
+ use in `#!' scripts.
+
+ * Directories named on the command line now produce a warning, not a
+ fatal error, unless `--posix' or `--traditional' are used (*note
+ Command-line directories::).
+
+ * The `gawk' internals were rewritten, bringing the `dgawk' debugger
+ and possibly improved performance (*note Debugger::).
+
+ * Per the GNU Coding Standards, dynamic extensions must now define a
+ global symbol indicating that they are GPL-compatible (*note
+ Plugin License::).
+
+ * In POSIX mode, string comparisons use `strcoll()' / `wcscoll()'
+ (*note POSIX String Comparison::).
+
+ * The option for raw sockets was removed, since it was never
+ implemented (*note TCP/IP Networking::).
+
+ * Ranges of the form `[d-h]' are treated as if they were in the C
+ locale, no matter what kind of regexp is being used, and even if
+ `--posix' (*note Ranges and Locales::).
+
+ * Support was removed for the following systems:
+
+ - Atari
+
+ - Amiga
+
+ - BeOS
+
+ - Cray
+
+ - MIPS RiscOS
+
+ - MS-DOS with Microsoft Compiler
+
+ - MS-Windows with Microsoft Compiler
+
+ - NeXT
+
+ - SunOS 3.x, Sun 386 (Road Runner)
+
+ - Tandem (non-POSIX)
+
+ - Prestandard VAX C compiler for VAX/VMS
+
+ Version 4.1 of `gawk' introduced the following features:
+
+ * Three new arrays: `SYMTAB', `FUNCTAB', and
+ `PROCINFO["identifiers"]' (*note Auto-set::).
+
+ * The three executables `gawk', `pgawk', and `dgawk', were merged
+ into one, named just `gawk'. As a result the command-line options
+ changed.
+
+ * Command-line option changes (*note Options::):
+
+ - The `-D' option invokes the debugger.
+
+ - The `-i' and `--include' options load `awk' library files.
+
+ - The `-l' and `--load' options load compiled dynamic
+ extensions.
+
+ - The `-M' and `--bignum' options enable MPFR.
+
+ - The `-o' option only does pretty-printing.
+
+ - The `-p' option is used for profiling.
+
+ - The `-R' option was removed.
+
+ * Support for high precision arithmetic with MPFR. (*note Arbitrary
+ Precision Arithmetic::).
+
+ * The `and()', `or()' and `xor()' functions changed to allow any
+ number of arguments, with a minimum of two (*note Bitwise
+ Functions::).
+
+ * The dynamic extension interface was completely redone (*note
+ Dynamic Extensions::).

-File: gawk.info, Node: Common Extensions, Next: Ranges and Locales, Prev: POSIX/GNU, Up: Language History
+File: gawk.info, Node: Common Extensions, Next: Ranges and Locales, Prev: Feature History, Up: Language History
-A.6 Common Extensions Summary
+A.7 Common Extensions Summary
=============================
-This minor node summarizes the common extensions supported by `gawk',
-Brian Kernighan's `awk', and `mawk', the three most widely-used freely
-available versions of `awk' (*note Other Versions::).
-
-Feature BWK Awk Mawk GNU Awk
---------------------------------------------------------
-`\x' Escape sequence X X X
-`RS' as regexp X X
-`FS' as null string X X X
-`/dev/stdin' special file X X
-`/dev/stdout' special file X X X
-`/dev/stderr' special file X X X
-`**' and `**=' operators X X
-`func' keyword X X
-`nextfile' statement X X X
-`delete' without subscript X X X
-`length()' of an array X X
-`fflush()' function X X X
-`BINMODE' variable X X
+The following table summarizes the common extensions supported by
+`gawk', Brian Kernighan's `awk', and `mawk', the three most widely used
+freely available versions of `awk' (*note Other Versions::).
+
+Feature BWK Awk Mawk GNU Awk Now standard
+-----------------------------------------------------------------------
+`\x' Escape sequence X X X
+`FS' as null string X X X
+`/dev/stdin' special file X X X
+`/dev/stdout' special file X X X
+`/dev/stderr' special file X X X
+`delete' without subscript X X X X
+`fflush()' function X X X X
+`length()' of an array X X X
+`nextfile' statement X X X X
+`**' and `**=' operators X X
+`func' keyword X X
+`BINMODE' variable X X
+`RS' as regexp X X
+Time-related functions X X

File: gawk.info, Node: Ranges and Locales, Next: Contributors, Prev: Common Extensions, Up: Language History
-A.7 Regexp Ranges and Locales: A Long Sad Story
+A.8 Regexp Ranges and Locales: A Long Sad Story
===============================================
This minor node describes the confusing history of ranges within
@@ -20143,20 +26974,20 @@ first character in the range and the last character in the range,
inclusive. Ordering was based on the numeric value of each character
in the machine's native character set. Thus, on ASCII-based systems,
`[a-z]' matched all the lowercase letters, and only the lowercase
-letters, since the numeric values for the letters from `a' through `z'
-were contigous. (On an EBCDIC system, the range `[a-z]' includes
+letters, as the numeric values for the letters from `a' through `z'
+were contiguous. (On an EBCDIC system, the range `[a-z]' includes
additional, non-alphabetic characters as well.)
Almost all introductory Unix literature explained range expressions
as working in this fashion, and in particular, would teach that the
"correct" way to match lowercase letters was with `[a-z]', and that
-`[A-Z]' was the the "correct" way to match uppercase letters. And
-indeed, this was true.
+`[A-Z]' was the "correct" way to match uppercase letters. And indeed,
+this was true.(1)
- The 1993 POSIX standard introduced the idea of locales (*note
-Locales::). Since many locales include other letters besides the plain
-twenty-six letters of the American English alphabet, the POSIX standard
-added character classes (*note Bracket Expressions::) as a way to match
+ The 1992 POSIX standard introduced the idea of locales (*note
+Locales::). Because many locales include other letters besides the
+plain 26 letters of the English alphabet, the POSIX standard added
+character classes (*note Bracket Expressions::) as a way to match
different kinds of characters besides the traditional ones in the ASCII
character set.
@@ -20166,16 +26997,16 @@ like `[a-dx-z]' is still equivalent to `[abcdxyz]', as in ASCII. But
outside those locales, the ordering was defined to be based on
"collation order".
- In many locales, `A' and `a' are both less than `B'. In other
-words, these locales sort characters in dictionary order, and
-`[a-dx-z]' is typically not equivalent to `[abcdxyz]'; instead it might
-be equivalent to `[aBbCcdXxYyz]', for example.
+ What does that mean? In many locales, `A' and `a' are both less
+than `B'. In other words, these locales sort characters in dictionary
+order, and `[a-dx-z]' is typically not equivalent to `[abcdxyz]';
+instead it might be equivalent to `[ABCXYabcdxyz]', for example.
- This point needs to be emphasized: Much literature teaches that you
+ This point needs to be emphasized: much literature teaches that you
should use `[a-z]' to match a lowercase character. But on systems with
-non-ASCII locales, this also matched all of the uppercase characters
-except `Z'! This was a continuous cause of confusion, even well into
-the twenty-first century.
+non-ASCII locales, this also matches all of the uppercase characters
+except `A' or `Z'! This was a continuous cause of confusion, even well
+into the twenty-first century.
To demonstrate these issues, the following example uses the `sub()'
function, which does text replacement (*note String Functions::). Here,
@@ -20184,9 +27015,9 @@ the intent is to remove trailing uppercase characters:
$ echo something1234abc | gawk-3.1.8 '{ sub("[A-Z]*$", ""); print }'
-| something1234a
-This output is unexpected, since the `bc' 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).
+This output is unexpected, as the `bc' 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).
Similar considerations apply to other ranges. For example, `["-/]'
is perfectly valid in ASCII, but is not valid in many Unicode locales,
@@ -20203,37 +27034,43 @@ like "why does `[A-Z]' match lowercase letters?!?"
This situation existed for close to 10 years, if not more, and the
`gawk' maintainer grew weary of trying to explain that `gawk' was being
-nicely standards-compliant, and that the issue was in the user's
+nicely standards compliant, and that the issue was in the user's
locale. During the development of version 4.0, he modified `gawk' to
always treat ranges in the original, pre-POSIX fashion, unless
-`--posix' was used (*note Options::).
+`--posix' was used (*note Options::).(2)
Fortunately, shortly before the final release of `gawk' 4.0, the
maintainer learned that the 2008 standard had changed the definition of
ranges, such that outside the `"C"' and `"POSIX"' locales, the meaning
-of range expressions was _undefined_.(1)
+of range expressions was _undefined_.(3)
By using this lovely technical term, the standard gives license to
implementors to implement ranges in whatever way they choose. The
`gawk' maintainer chose to apply the pre-POSIX meaning in all cases:
-the default regexp matching; with `--traditional', and with `--posix';
+the default regexp matching; with `--traditional' and with `--posix';
in all cases, `gawk' remains POSIX compliant.
---------- Footnotes ----------
- (1) See the standard
+ (1) And Life was good.
+
+ (2) And thus was born the Campaign for Rational Range Interpretation
+(or RRI). A number of GNU tools have either implemented this change, or
+will soon. Thanks to Karl Berry for coining the phrase "Rational Range
+Interpretation."
+
+ (3) See the standard
(http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03_05)
and its rationale
(http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap09.html#tag_21_09_03_05).

-File: gawk.info, Node: Contributors, Prev: Ranges and Locales, Up: Language History
+File: gawk.info, Node: Contributors, Next: History summary, Prev: Ranges and Locales, Up: Language History
-A.8 Major Contributors to `gawk'
+A.9 Major Contributors to `gawk'
================================
- Always give credit where credit is due.
- Anonymous
+ 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:
@@ -20274,8 +27111,8 @@ Info file, in approximate chronological order:
* Michal Jaegermann provided the port to Atari systems and its
documentation. (This port is no longer supported.) 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.
+ to provide portability checking, 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.
(With Fred's sad passing, this is no longer supported.)
@@ -20294,7 +27131,8 @@ Info file, in approximate chronological order:
various PC platforms.
* Christos Zoulas provided the `extension()' built-in function for
- dynamically adding new modules.
+ dynamically adding new functions. (This was obsoleted at `gawk'
+ 4.1.)
* Ju"rgen Kahrs contributed the initial version of the TCP/IP
networking code and documentation, and motivated the inclusion of
@@ -20327,18 +27165,86 @@ Info file, in approximate chronological order:
statements.
* Patrick T.J. McPhee contributed the code for dynamic loading in
- Windows32 environments. (This is no longer supported)
+ Windows32 environments. (This is no longer supported.)
+
+ * Anders Wallin helped keep the VMS port going for several years.
+
+ * Assaf Gordon contributed the code to implement the `--sandbox'
+ option.
+
+ * John Haque made the following contributions:
+
+ - The modifications to convert `gawk' into a byte-code
+ interpreter, including the debugger.
+
+ - The addition of true arrays of arrays.
+
+ - The additional modifications for support of
+ arbitrary-precision arithmetic.
+
+ - The initial text of *note Arbitrary Precision Arithmetic::.
+
+ - The work to merge the three versions of `gawk' into one, for
+ the 4.1 release.
- * John Haque reworked the `gawk' internals to use a byte-code engine,
- providing the `dgawk' debugger for `awk' programs.
+ - Improved array internals for arrays indexed by integers.
- * Efraim Yawitz contributed the original text for *Note Debugger::.
+ - The improved array sorting features were driven by John
+ together with Pat Rankin.
+
+ * Panos Papadopoulos contributed the original text for *note Include
+ Files::.
+
+ * Efraim Yawitz contributed the original text for *note Debugger::.
+
+ * The development of the extension API first released with `gawk'
+ 4.1 was driven primarily by Arnold Robbins and Andrew Schorr, with
+ notable contributions from the rest of the development team.
+
+ * John Malmberg contributed significant improvements to the OpenVMS
+ port and the related documentation.
+
+ * Antonio Giovanni Colombo rewrote a number of examples in the early
+ chapters that were severely dated, for which I am incredibly
+ grateful.
* Arnold Robbins has been working on `gawk' since 1988, at first
helping David Trueman, and as the primary maintainer since around
1994.

+File: gawk.info, Node: History summary, Prev: Contributors, Up: Language History
+
+A.10 Summary
+============
+
+ * The `awk' language has evolved over time. The first release was
+ with V7 Unix circa 1978. In 1987, for System V Release 3.1, major
+ additions, including user-defined functions, were made to the
+ language. Additional changes were made for System V Release 4, in
+ 1989. Since then, further minor changes happen under the auspices
+ of the POSIX standard.
+
+ * Brian Kernighan's `awk' provides a small number of extensions that
+ are implemented in common with other versions of `awk'.
+
+ * `gawk' provides a large number of extensions over POSIX `awk'.
+ They can be disabled with either the `--traditional' or `--posix'
+ options.
+
+ * The interaction of POSIX locales and regexp matching in `gawk' has
+ been confusing over the years. Today, `gawk' implements Rational
+ Range Interpretation, where ranges of the form `[a-z]' match
+ _only_ the characters numerically between `a' through `z' in the
+ machine's native character set. Usually this is ASCII but it can
+ be EBCDIC on IBM S/390 systems.
+
+ * Many people have contributed to `gawk' development over the years.
+ We hope that the list provided in this major node is complete and
+ gives the appropriate credit where credit is due.
+
+
+
File: gawk.info, Node: Installation, Next: Notes, Prev: Language History, Up: Top
Appendix B Installing `gawk'
@@ -20347,8 +27253,8 @@ 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.
+contributed. *Note Bugs::, for the email addresses of the people who
+maintain the respective ports.
* Menu:
@@ -20359,6 +27265,7 @@ people who did the respective ports.
* Bugs:: Reporting Problems and Bugs.
* Other Versions:: Other freely available `awk'
implementations.
+* Installation summary:: Summary of installation.

File: gawk.info, Node: Gawk Distribution, Next: Unix Installation, Up: Installation
@@ -20381,7 +27288,7 @@ 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:
+There are two ways to get GNU software:
* Copy it from someone else who already has it.
@@ -20390,10 +27297,10 @@ There are three ways to get GNU software:
supported. If you have the `wget' program, you can use a command
like the following:
- wget http://ftp.gnu.org/gnu/gawk/gawk-4.0.0.tar.gz
+ wget http://ftp.gnu.org/gnu/gawk/gawk-4.1.2.tar.gz
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
+up-to-date list of mirror sites is available from the main FSF website
(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.
@@ -20409,26 +27316,25 @@ compression programs: `gzip', `bzip2', and `xz'. For simplicity, the
rest of these instructions assume you are using the one compressed with
the GNU Zip program, `gzip'.
- Once you have the distribution (for example, `gawk-4.0.0.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:
+ Once you have the distribution (e.g., `gawk-4.1.2.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-4.0.0.tar.gz | tar -xvpf -
+ gzip -d -c gawk-4.1.2.tar.gz | tar -xvpf -
On a system with GNU `tar', you can let `tar' do the decompression
for you:
- tar -xvpzf gawk-4.0.0.tar.gz
+ tar -xvpzf gawk-4.1.2.tar.gz
-Extracting the archive creates a directory named `gawk-4.0.0' in the
+Extracting the archive creates a directory named `gawk-4.1.2' 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 0, but when retrieving distributions, you should get the
+level is 2, 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 70 denote "beta" or
nonproduction software; you might not want to retrieve such a version
@@ -20450,6 +27356,13 @@ to different non-Unix operating systems:
Various `.c', `.y', and `.h' files
The actual `gawk' source code.
+`ABOUT-NLS'
+ Information about GNU `gettext' and translations.
+
+`AUTHORS'
+ A file with some information about the authorship of `gawk'. It
+ exists only to satisfy the pedants at the Free Software Foundation.
+
`README'
`README_d/README.*'
Descriptive files: `README' for `gawk' under Unix and the rest for
@@ -20475,16 +27388,6 @@ Various `.c', `.y', and `.h' files
`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 behaviors in the POSIX standard for `awk' which
are left undefined, or where `gawk' may not comply fully, as well
@@ -20492,8 +27395,9 @@ Various `.c', `.y', and `.h' files
does not.
`doc/awkforai.txt'
- A short article describing why `gawk' is a good language for
- Artificial Intelligence (AI) programming.
+ Pointers to the original draft of a short article describing why
+ `gawk' is a good language for artificial intelligence (AI)
+ programming.
`doc/bc_notes'
A brief description of `gawk''s "byte code" internals.
@@ -20515,11 +27419,18 @@ Various `.c', `.y', and `.h' files
The `troff' source for a manual page describing `gawk'. This is
distributed for the convenience of Unix users.
-`doc/gawk.texi'
+`doc/gawktexi.in'
+`doc/sidebar.awk'
The Texinfo source file for this Info file. It should be
- processed with TeX (via `texi2dvi' or `texi2pdf') to produce a
- printed document, and with `makeinfo' to produce an Info or HTML
- file.
+ processed by `doc/sidebar.awk' before processing with `texi2dvi'
+ or `texi2pdf' to produce a printed document, and with `makeinfo'
+ to produce an Info or HTML file. The `Makefile' takes care of
+ this processing and produces printable output via `texi2dvi' or
+ `texi2pdf'.
+
+`doc/gawk.texi'
+ The file produced after processing `gawktexi.in' with
+ `sidebar.awk'.
`doc/gawk.info'
The generated Info file for this Info file.
@@ -20536,7 +27447,9 @@ Various `.c', `.y', and `.h' files
`doc/igawk.1'
The `troff' source for a manual page describing the `igawk'
- program presented in *Note Igawk Program::.
+ program presented in *note Igawk Program::. (Since `gawk' can do
+ its own `@include' processing, neither `igawk' nor `igawk.1' are
+ installed.)
`doc/Makefile.in'
The input file used during the configuration process to generate
@@ -20544,20 +27457,26 @@ Various `.c', `.y', and `.h' files
`Makefile.am'
`*/Makefile.am'
- Files used by the GNU `automake' software for generating the
- `Makefile.in' files used by `autoconf' and `configure'.
+ Files used by the GNU Automake software for generating the
+ `Makefile.in' files used by Autoconf and `configure'.
`Makefile.in'
`aclocal.m4'
+`bisonfix.awk'
+`config.guess'
`configh.in'
`configure.ac'
`configure'
`custom.h'
+`depcomp'
+`install-sh'
`missing_d/*'
+`mkinstalldirs'
`m4/*'
- These files and subdirectories are used when configuring `gawk'
- for various Unix systems. They are explained in *Note Unix
- Installation::.
+ These files and subdirectories are used when configuring and
+ compiling `gawk' for various Unix systems. Most of them are
+ explained in *note Unix Installation::. The rest are there to
+ support the main infrastructure.
`po/*'
The `po' library contains message translations.
@@ -20571,12 +27490,23 @@ Various `.c', `.y', and `.h' files
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'.
+ `Makefile.in'. The library functions from *note Library
+ Functions::, 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'.
+
+`extension/*'
+ The source code, manual pages, and infrastructure files for the
+ sample extensions included with `gawk'. *Note Dynamic
+ Extensions::, for more information.
+
+`extras/*'
+ Additional non-essential files. Currently, this directory
+ contains some shell startup files to be installed in
+ `/etc/profile.d' to aid in manipulating the `AWKPATH' and
+ `AWKLIBPATH' environment variables. *Note Shell Startup Files::,
+ for more information.
`posix/*'
Files needed for building `gawk' on POSIX-compliant systems.
@@ -20586,8 +27516,8 @@ Various `.c', `.y', and `.h' files
PC Installation::, for details).
`vms/*'
- Files needed for building `gawk' under VMS (*note VMS
- Installation::, for details).
+ Files needed for building `gawk' under Vax/VMS and OpenVMS (*note
+ VMS Installation::, for details).
`test/*'
A test suite for `gawk'. You can use `make check' from the
@@ -20598,7 +27528,7 @@ Various `.c', `.y', and `.h' files

File: gawk.info, Node: Unix Installation, Next: Non-Unix Installation, Prev: Gawk Distribution, Up: Installation
-B.2 Compiling and Installing `gawk' on Unix-like Systems
+B.2 Compiling and Installing `gawk' on Unix-Like Systems
========================================================
Usually, you can compile and install `gawk' by typing only two
@@ -20608,13 +27538,14 @@ configure `gawk' for your system yourself.
* Menu:
* Quick Installation:: Compiling `gawk' under Unix.
+* Shell Startup Files:: Shell convenience functions.
* Additional Configuration Options:: Other compile-time options.
* Configuration Philosophy:: How it's all supposed to work.

-File: gawk.info, Node: Quick Installation, Next: Additional Configuration Options, Up: Unix Installation
+File: gawk.info, Node: Quick Installation, Next: Shell Startup Files, Up: Unix Installation
-B.2.1 Compiling `gawk' for Unix-like Systems
+B.2.1 Compiling `gawk' for Unix-Like Systems
--------------------------------------------
The normal installation steps should work on all modern commercial
@@ -20622,12 +27553,12 @@ Unix-derived systems, GNU/Linux, BSD-based systems, and the Cygwin
environment for MS-Windows.
After you have extracted the `gawk' distribution, `cd' to
-`gawk-4.0.0'. Like most GNU software, `gawk' is configured
-automatically for your 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 (Autoconf)Top:: autoconf,Autoconf--Generating Automatic
-Configuration Scripts.)
+`gawk-4.1.2'. As with most GNU software, you configure `gawk' for your
+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
+(Autoconf)Top:: autoconf,Autoconf--Generating Automatic Configuration
+Scripts.)
To configure `gawk', simply run `configure':
@@ -20657,18 +27588,65 @@ 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::).
+failure is not described there, send in a bug report (*note Bugs::).
+
+ Of course, once you've built `gawk', it is likely that you will wish
+to install it. To do so, you need to run the command `make install',
+as a user with the appropriate permissions. How to do this varies by
+system, but on many systems you can use the `sudo' command to do so.
+The command then becomes `sudo make install'. It is likely that you
+will be asked for your password, and you will have to have been set up
+previously as a user who is allowed to run the `sudo' command.

-File: gawk.info, Node: Additional Configuration Options, Next: Configuration Philosophy, Prev: Quick Installation, Up: Unix Installation
+File: gawk.info, Node: Shell Startup Files, Next: Additional Configuration Options, Prev: Quick Installation, Up: Unix Installation
+
+B.2.2 Shell Startup Files
+-------------------------
+
+The distribution contains shell startup files `gawk.sh' and `gawk.csh'
+containing functions to aid in manipulating the `AWKPATH' and
+`AWKLIBPATH' environment variables. On a Fedora system, these files
+should be installed in `/etc/profile.d'; on other platforms, the
+appropriate location may be different.
+
+`gawkpath_default'
+ Reset the `AWKPATH' environment variable to its default value.
+
+`gawkpath_prepend'
+ Add the argument to the front of the `AWKPATH' environment
+ variable.
+
+`gawkpath_append'
+ Add the argument to the end of the `AWKPATH' environment variable.
+
+`gawklibpath_default'
+ Reset the `AWKLIBPATH' environment variable to its default value.
+
+`gawklibpath_prepend'
+ Add the argument to the front of the `AWKLIBPATH' environment
+ variable.
+
+`gawklibpath_append'
+ Add the argument to the end of the `AWKLIBPATH' environment
+ variable.
+
-B.2.2 Additional Configuration Options
+
+File: gawk.info, Node: Additional Configuration Options, Next: Configuration Philosophy, Prev: Shell Startup Files, Up: Unix Installation
+
+B.2.3 Additional Configuration Options
--------------------------------------
There are several additional options you may use on the `configure'
command line when compiling `gawk' from scratch, including:
+`--disable-extensions'
+ Disable configuring and building the sample extensions in the
+ `extension' directory. This is useful for cross-compiling. The
+ default action is to dynamically check if the extensions can be
+ configured and compiled.
+
`--disable-lint'
Disable all lint checking within `gawk'. The `--lint' and
`--lint-old' options (*note Options::) are accepted, but silently
@@ -20676,8 +27654,8 @@ command line when compiling `gawk' from scratch, including:
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
+ cuts almost 23K bytes off the size of the `gawk' executable on
+ GNU/Linux x86_64 systems. Results on other systems and with other
compilers are likely to vary. Using this option may bring you
some slight performance improvement.
@@ -20690,16 +27668,16 @@ command line when compiling `gawk' from scratch, including:
improvement.
`--with-whiny-user-strftime'
- Force use of the included version of the `strftime()' function for
- deficient systems.
+ Force use of the included version of the C `strftime()' function
+ for deficient systems.
Use the command `./configure --help' to see the full list of options
-that `configure' supplies.
+supplied by `configure'.

File: gawk.info, Node: Configuration Philosophy, Prev: Additional Configuration Options, Up: Unix Installation
-B.2.3 The Configuration Process
+B.2.4 The Configuration Process
-------------------------------
This minor node is of interest only if you know something about using
@@ -20723,21 +27701,21 @@ 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
operating system. For example, there may not be an `st_blksize'
-element in the `stat' structure. In this case, `HAVE_ST_BLKSIZE' is
-undefined.
+element in the `stat' structure. In this case,
+`HAVE_STRUCT_STAT_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
+available. To get around this, edit the `custom.h' file. 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'.
+any constants that `configure' defined and should not have. The
+`custom.h' file is automatically included by the `config.h' file.
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.ac' is the input for `autoconf'.
-You may be able to change this file and generate a new version of
+Autoconf will not work on your system in some other fashion. If you do
+have a problem, the `configure.ac' file 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.ac' and/or `custom.h'.
@@ -20763,16 +27741,16 @@ File: gawk.info, Node: PC Installation, Next: VMS Installation, Up: Non-Unix
B.3.1 Installation on PC Operating Systems
------------------------------------------
-This minor node covers installation and usage of `gawk' on x86 machines
-running MS-DOS, any version of MS-Windows, or OS/2. In this minor
-node, the term "Windows32" refers to any of Microsoft
-Windows-95/98/ME/NT/2000/XP/Vista/7.
+This minor node covers installation and usage of `gawk' on Intel
+architecture machines running MS-DOS, any version of MS-Windows, or
+OS/2. In this minor node, the term "Windows32" refers to any of
+Microsoft Windows-95/98/ME/NT/2000/XP/Vista/7/8.
- The limitations of MS-DOS (and MS-DOS shells under Windows32 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
+ The limitations of MS-DOS (and MS-DOS shells under the other
+operating systems) 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, refer to `README_d/README.pc' in the
distribution.
* Menu:
@@ -20832,13 +27810,13 @@ B.3.1.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). The file
-`README_d/README.pc' in the `gawk' distribution contains additional
-notes, and `pc/Makefile' contains important information on compilation
-options.
+development tools from DJ Delorie (DJGPP: MS-DOS only), MinGW
+(Windows32) or Eberhard Mattes (EMX: MS-DOS, Windows32 and OS/2). 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 and Windows32, copy the files in the `pc'
+To build `gawk' for MS-DOS and Windows32, copy the files in the `pc'
directory (_except_ for `ChangeLog') to the directory with the rest of
the `gawk' sources, then invoke `make' with the appropriate target name
as an argument to build `gawk'. The `Makefile' copied from the `pc'
@@ -20851,7 +27829,7 @@ MS-DOS and Windows32 versions. A list of targets is printed if the
`gawk' using the DJGPP tools, enter `make djgpp'. (The DJGPP tools
needed for the build may be found at
`ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/'.) To build a native
-MS-Windows binary of `gawk', type `make mingw32'.
+MS-Windows binary of `gawk' using the MinGW tools, type `make mingw32'.
The 32 bit EMX version of `gawk' works "out of the box" under OS/2.
However, it is highly recommended to use GCC 2.95.3 for the compilation.
@@ -20898,7 +27876,12 @@ other set of (self-consistent) environment variables and compiler flags.
NOTE: Ancient 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 `ftp://hobbes.nmsu.edu/pub/os2/'.
+ the latest version on `ftp://hobbes.nmsu.edu/pub/os2/'.(1)
+
+ ---------- Footnotes ----------
+
+ (1) As of November 2014, this site is still there, but the author
+could not find a package for GNU Make.

File: gawk.info, Node: PC Testing, Next: PC Using, Prev: PC Compiling, Up: PC Installation
@@ -20931,20 +27914,19 @@ File: gawk.info, Node: PC Using, Next: Cygwin, Prev: PC Testing, Up: PC Inst
B.3.1.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.
+Under MS-DOS and MS-Windows, the Cygwin and MinGW environments support
+both the `|&' operator and TCP/IP networking (*note TCP/IP
+Networking::). EMX (OS/2 only) supports at least the `|&' operator.
The MS-DOS and MS-Windows versions of `gawk' search for program
-files as described in *Note AWKPATH Variable::. However, semicolons
+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
-MS-Windows and MS-DOS versions is `".;c:/lib/awk;c:/gnu/lib/awk"'.
+`AWKPATH' is not set or is empty, then the default search path 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
+an option of the `configure' script as 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
@@ -20952,7 +27934,7 @@ 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"'.
+`.;c:/usr/share/awk;e:/usr/share/awk'.
An `sh'-like shell (as opposed to `command.com' under MS-DOS or
`cmd.exe' under MS-Windows or OS/2) may be useful for `awk' programming.
@@ -20960,15 +27942,14 @@ The DJGPP collection of tools includes an MS-DOS port of Bash, and
several shells are available for OS/2, including `ksh'.
Under MS-Windows, OS/2 and MS-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
-(c.e.) allows control over these translations and is interpreted as
-follows:
+programs) silently translate end-of-line `\r\n' to `\n' on input and
+`\n' to `\r\n' on output. A special `BINMODE' variable (c.e.) allows
+control over these translations and is interpreted as follows:
- * If `BINMODE' is `"r"', or one, then binary mode is set on read
+ * If `BINMODE' is `"r"' or one, then binary mode is set on read
(i.e., no translations on reads).
- * If `BINMODE' is `"w"', or two, then binary mode is set on write
+ * If `BINMODE' is `"w"' or two, then binary mode is set on write
(i.e., no translations on writes).
* If `BINMODE' is `"rw"' or `"wr"' or three, binary mode is set for
@@ -20989,11 +27970,11 @@ and cannot be changed mid-stream.
Versions::). `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
+(under `gnu/lib/awk' in some of the prepared binary 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
MS-DOS-style end-of-line.
To illustrate, the following examples set binary mode on writes for
@@ -21010,7 +27991,7 @@ 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 }" ...
+ gawk -v RS="\r\n" -e "BEGIN { BINMODE = 1 }" ...
or:
@@ -21027,24 +28008,20 @@ B.3.1.5 Using `gawk' In The Cygwin Environment
`gawk' can be built and used "out of the box" under MS-Windows if you
are using the Cygwin environment (http://www.cygwin.com). 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 programs. Compilation and installation for Cygwin is the
+environment provides an excellent simulation of GNU/Linux, using the
+GNU tools, such as Bash, the GNU Compiler Collection (GCC), GNU Make,
+and other GNU programs. Compilation and installation for Cygwin is the
same as for a Unix system:
- tar -xvpzf gawk-4.0.0.tar.gz
- cd gawk-4.0.0
+ tar -xvpzf gawk-4.1.2.tar.gz
+ cd gawk-4.1.2
./configure
- make
+ make && make check
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 on MS-Windows.
-

File: gawk.info, Node: MSYS, Prev: Cygwin, Up: PC Installation
@@ -21057,13 +28034,13 @@ use the `BINMODE' variable.
This can cause problems with other Unix-like components that have
been ported to MS-Windows that expect `gawk' to do automatic
-translation of `"\r\n"', since it won't. Caveat Emptor!
+translation of `"\r\n"', because it won't.

File: gawk.info, Node: VMS Installation, Prev: PC Installation, Up: Non-Unix Installation
-B.3.2 How to Compile and Install `gawk' on VMS
-----------------------------------------------
+B.3.2 Compiling and Installing `gawk' on Vax/VMS and OpenVMS
+------------------------------------------------------------
This node describes how to compile and install `gawk' under VMS. The
older designation "VMS" is used throughout to refer to OpenVMS.
@@ -21071,51 +28048,118 @@ older designation "VMS" is used throughout to refer to OpenVMS.
* Menu:
* VMS Compilation:: How to compile `gawk' under VMS.
+* VMS Dynamic Extensions:: Compiling `gawk' dynamic extensions on
+ VMS.
* VMS Installation Details:: How to install `gawk' under VMS.
* VMS Running:: How to run `gawk' under VMS.
+* VMS GNV:: The VMS GNV Project.
* VMS Old Gawk:: An old version comes with some VMS systems.

-File: gawk.info, Node: VMS Compilation, Next: VMS Installation Details, Up: VMS Installation
+File: gawk.info, Node: VMS Compilation, Next: VMS Dynamic Extensions, Up: VMS Installation
B.3.2.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:
+`Makefile' for use with the `MMS' and `MMK' utilities. From the source
+directory, use either:
+
+ $ @[.vms]vmsbuild.com
- $ @[.VMS]VMSBUILD.COM
+or:
+
+ $ MMS/DESCRIPTION=[.vms]descrip.mms gawk
or:
- $ MMS/DESCRIPTION=[.VMS]DESCRIP.MMS GAWK
+ $ MMK/DESCRIPTION=[.vms]descrip.mms gawk
+
+ `MMK' is an open source, free, near-clone of `MMS' and can better
+handle ODS-5 volumes with upper- and lowercase file names. `MMK' is
+available from `https://github.com/endlesssoftware/mmk'.
- Older versions of `gawk' could be built with VAX C or GNU C on
-VAX/VMS, as well as with DEC C, but that is no longer supported. DEC C
-(also briefly known as "Compaq C" and now known as "HP C," but referred
-to here as "DEC C") is required. Both `VMSBUILD.COM' and `DESCRIP.MMS'
-contain some obsolete support for the older compilers but are set up to
-use DEC C by default.
+ With ODS-5 volumes and extended parsing enabled, the case of the
+target parameter may need to be exact.
- `gawk' has been tested under Alpha/VMS 7.3-1 using Compaq C V6.4,
-and on Alpha/VMS 7.3, Alpha/VMS 7.3-2, and IA64/VMS 8.3.(1)
+ `gawk' has been tested under VAX/VMS 7.3 and Alpha/VMS 7.3-1 using
+Compaq C V6.4, and Alpha/VMS 7.3, Alpha/VMS 7.3-2, and IA64/VMS 8.3.
+The most recent builds used HP C V7.3 on Alpha VMS 8.3 and both Alpha
+and IA64 VMS 8.4 used HP C 7.3.(1)
+
+ *Note VMS GNV::, for information on building `gawk' as a PCSI kit
+that is compatible with the GNV product.
---------- Footnotes ----------
(1) The IA64 architecture is also known as "Itanium."

-File: gawk.info, Node: VMS Installation Details, Next: VMS Running, Prev: VMS Compilation, Up: VMS Installation
+File: gawk.info, Node: VMS Dynamic Extensions, Next: VMS Installation Details, Prev: VMS Compilation, Up: VMS Installation
+
+B.3.2.2 Compiling `gawk' Dynamic Extensions on VMS
+..................................................
+
+The extensions that have been ported to VMS can be built using one of
+the following commands:
+
+ $ MMS/DESCRIPTION=[.vms]descrip.mms extensions
+
+or:
+
+ $ MMK/DESCRIPTION=[.vms]descrip.mms extensions
+
+ `gawk' uses `AWKLIBPATH' as either an environment variable or a
+logical name to find the dynamic extensions.
+
+ Dynamic extensions need to be compiled with the same compiler
+options for floating-point, pointer size, and symbol name handling as
+were used to compile `gawk' itself. Alpha and Itanium should use IEEE
+floating point. The pointer size is 32 bits, and the symbol name
+handling should be exact case with CRC shortening for symbols longer
+than 32 bits.
-B.3.2.2 Installing `gawk' on VMS
+ For Alpha and Itanium:
+
+ /name=(as_is,short)
+ /float=ieee/ieee_mode=denorm_results
+
+ For VAX:
+
+ /name=(as_is,short)
+
+ Compile time macros need to be defined before the first VMS-supplied
+header file is included, as follows:
+
+ #if (__CRTL_VER >= 70200000) && !defined (__VAX)
+ #define _LARGEFILE 1
+ #endif
+
+ #ifndef __VAX
+ #ifdef __CRTL_VER
+ #if __CRTL_VER >= 80200000
+ #define _USE_STD_STAT 1
+ #endif
+ #endif
+ #endif
+
+ If you are writing your own extensions to run on VMS, you must
+supply these definitions yourself. The `config.h' file created when
+building `gawk' on VMS does this for you; if instead you use that file
+or a similar one, then you must remember to include it before any
+VMS-supplied header files.
+
+
+File: gawk.info, Node: VMS Installation Details, Next: VMS Running, Prev: VMS Dynamic Extensions, Up: VMS Installation
+
+B.3.2.3 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:
+To use `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
+ $ 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
@@ -21123,9 +28167,27 @@ symbol should be placed in the `login.com' of any user who wants to run
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:
+ If your `gawk' was installed by a PCSI kit into the `GNV$GNU:'
+directory tree, the program will be known as
+`GNV$GNU:[bin]gnv$gawk.exe' and the help file will be
+`GNV$GNU:[vms_help]gawk.hlp'.
+
+ The PCSI kit also installs a `GNV$GNU:[vms_bin]gawk_verb.cld' file
+which can be used to add `gawk' and `awk' as DCL commands.
+
+ For just the current process you can use:
- $ LIBRARY/HELP SYS$HELP:HELPLIB [.VMS]GAWK.HLP
+ $ set command gnv$gnu:[vms_bin]gawk_verb.cld
+
+ Or the system manager can use `GNV$GNU:[vms_bin]gawk_verb.cld' to
+add the `gawk' and `awk' to the system wide `DCLTABLES'.
+
+ The DCL syntax is documented in the `gawk.hlp' file.
+
+ Optionally, the `gawk.hlp' 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
@@ -21142,14 +28204,14 @@ 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.
+appends the suffix `.awk' to the file name and retries the file search.
If `AWK_LIBRARY' has no definition, a default value of `SYS$LIBRARY:'
is used for it.

-File: gawk.info, Node: VMS Running, Next: VMS Old Gawk, Prev: VMS Installation Details, Up: VMS Installation
+File: gawk.info, Node: VMS Running, Next: VMS GNV, Prev: VMS Installation Details, Up: VMS Installation
-B.3.2.3 Running `gawk' on VMS
+B.3.2.4 Running `gawk' on VMS
.............................
Command-line parsing and quoting conventions are significantly different
@@ -21168,12 +28230,40 @@ 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 parsing 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.
+single parameter (as in the quoted string program), the command becomes
+ambiguous. To work around this, the normally optional `--' flag is
+required to force Unix-style parsing 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 `exit' value is a Unix-style value and is encoded into a VMS exit
+status value when the program exits.
+
+ The VMS severity bits will be set based on the `exit' value. A
+failure is indicated by 1 and VMS sets the `ERROR' status. A fatal
+error is indicated by 2 and VMS sets the `FATAL' status. All other
+values will have the `SUCCESS' status. The exit value is encoded to
+comply with VMS coding standards and will have the `C_FACILITY_NO' of
+`0x350000' with the constant `0xA000' added to the number shifted over
+by 3 bits to make room for the severity codes.
+
+ To extract the actual `gawk' exit code from the VMS status use:
+
+ unix_status = (vms_status .and. &x7f8) / 8
+
+A C program that uses `exec()' to call `gawk' will get the original
+Unix-style exit value.
+
+ Older versions of `gawk' for VMS treated a Unix exit code 0 as 1, a
+failure as 2, a fatal error as 4, and passed all the other numbers
+through. This violated the VMS exit status coding requirements.
+
+ VAX/VMS floating point uses unbiased rounding. *Note Round
+Function::.
+
+ VMS reports time values in GMT unless one of the `SYS$TIMEZONE_RULE'
+or `TZ' logical names is set. Older versions of VMS, such as VAX/VMS
+7.3 do not set these logical names.
The default search path, when looking for `awk' program files
specified by the `-f' option, is `"SYS$DISK:[],AWK_LIBRARY:"'. The
@@ -21183,9 +28273,27 @@ When defining it, the value should be quoted so that it retains a single
translation and not a multitranslation `RMS' searchlist.

-File: gawk.info, Node: VMS Old Gawk, Prev: VMS Running, Up: VMS Installation
+File: gawk.info, Node: VMS GNV, Next: VMS Old Gawk, Prev: VMS Running, Up: VMS Installation
+
+B.3.2.5 The VMS GNV Project
+...........................
+
+The VMS GNV package provides a build environment similar to POSIX with
+ports of a collection of open source tools. The `gawk' found in the GNV
+base kit is an older port. Currently the GNV project is being
+reorganized to supply individual PCSI packages for each component. See
+`https://sourceforge.net/p/gnv/wiki/InstallingGNVPackages/'.
+
+ The normal build procedure for `gawk' produces a program that is
+suitable for use with GNV.
+
+ The file `vms/gawk_build_steps.txt' in the distribution documents
+the procedure for building a VMS PCSI kit that is compatible with GNV.
+
+
+File: gawk.info, Node: VMS Old Gawk, Prev: VMS GNV, Up: VMS Installation
-B.3.2.4 Some VMS Systems Have An Old Version of `gawk'
+B.3.2.6 Some VMS Systems Have An Old Version of `gawk'
......................................................
Some versions of VMS have an old version of `gawk'. To access it,
@@ -21202,15 +28310,15 @@ File: gawk.info, Node: Bugs, Next: Other Versions, Prev: Non-Unix Installatio
B.4 Reporting Problems and Bugs
===============================
- There is nothing more dangerous than a bored archeologist.
- The Hitchhiker's Guide to the Galaxy
+ There is nothing more dangerous than a bored archaeologist. --
+ Douglas Adams, `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.
+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
+ Before reporting a bug, make sure you have really found a genuine
+bug. Carefully reread the documentation and see if it 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!
@@ -21223,75 +28331,76 @@ 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.
- Please include the version number of `gawk' you are using. You can
-get this information with the command `gawk --version'.
+ Make sure to include the version number of `gawk' you are using.
+You can get this information with the command `gawk --version'.
- Once you have a precise problem, send email to <bug-gawk@gnu.org>.
+ Once you have a precise problem description, send email to
+<bug-gawk@gnu.org>.
- Using this address automatically sends a copy of your mail to me.
-If necessary, I can be reached directly at <arnold@skeeve.com>. 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._
+ The `gawk' maintainers subscribe to this address and thus they will
+receive your bug report. Although you can send mail to the maintainers
+directly, the bug reporting address is preferred because the email list
+is archived at the GNU Project. _All email must be in English. This is
+the only language understood in common by all the maintainers._
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. Really.
+ Usenet/Internet newsgroup `comp.lang.awk'. The `gawk' developers
+ do occasionally read this newsgroup, but there is no guarantee
+ that we will see your posting. The steps described here are the
+ only officially recognized way for reporting bugs. Really.
NOTE: Many distributions of GNU/Linux and the various BSD-based
operating systems have their own bug reporting systems. If you
- report a bug using your distribution's bug reporting system,
- _please_ also send a copy to <bug-gawk@gnu.org>.
+ report a bug using your distribution's bug reporting system, you
+ should also send a copy to <bug-gawk@gnu.org>.
- This is for two reasons. First, while some distributions forward
- bug reports "upstream" to the GNU mailing list, many don't, so
- there is a good chance that the `gawk' maintainer won't even see
- the bug report! Second, mail to the GNU list is archived, and
- having everything at the GNU project keeps things self-contained
- and not dependant on other web sites.
+ This is for two reasons. First, although some distributions
+ forward bug reports "upstream" to the GNU mailing list, many
+ don't, so there is a good chance that the `gawk' maintainers
+ won't even see the bug report! Second, mail to the GNU list is
+ archived, and having everything at the GNU project keeps things
+ self-contained and not dependant on other organizations.
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.
+just obscure features, ask on the bug list; we will try to help you out
+if we can.
- 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.
+ If you find bugs in one of the non-Unix ports of `gawk', send an
+email to the bug list, with a copy 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:
+ The people maintaining the various `gawk' ports are:
+Unix and POSIX systems Arnold Robbins, <arnold@skeeve.com>.
MS-DOS with DJGPP Scott Deifik, <scottd.mail@sbcglobal.net>.
-MS-Windows with MINGW Eli Zaretskii, <eliz@gnu.org>.
+MS-Windows with MinGW Eli Zaretskii, <eliz@gnu.org>.
OS/2 Andreas Buening, <andreas.buening@nexgo.de>.
-VMS Pat Rankin, <r.pat.rankin@gmail.com>
+VMS John Malmberg, <wb8tyw@qsl.net>.
z/OS (OS/390) Dave Pitts, <dpitts@cozx.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.
+ If your bug is also reproducible under Unix, send a copy of your
+report to the <bug-gawk@gnu.org> email list as well.

-File: gawk.info, Node: Other Versions, Prev: Bugs, Up: Installation
+File: gawk.info, Node: Other Versions, Next: Installation summary, Prev: Bugs, Up: Installation
B.5 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
+ `// Do C++ comments work? answer: yes! of course' -- Michael
+ Brennan
- There are a number of other freely available `awk' implementations.
+There are a number of other freely available `awk' implementations.
This minor node briefly describes where to get them:
Unix `awk'
Brian Kernighan, one of the original designers of Unix `awk', has
made his implementation of `awk' freely available. You can
- retrieve this version via the World Wide Web from his home page
+ retrieve this version via his home page
(http://www.cs.princeton.edu/~bwk). It is available in several
archive formats:
@@ -21304,12 +28413,25 @@ Unix `awk'
Zip file
`http://www.cs.princeton.edu/~bwk/btl.mirror/awk.zip'
+ You can also retrieve it from Git Hub:
+
+ git clone git://github.com/onetrueawk/awk bwkawk
+
+ This command creates a copy of the Git (http://git-scm.com)
+ repository in a directory named `bwkawk'. If you leave that
+ argument off the `git' command line, the repository copy is
+ created in a directory named `awk'.
+
This version requires an ISO C (1990 standard) compiler; the C
compiler from GCC (the GNU Compiler Collection) works quite nicely.
*Note Common Extensions::, for a list of extensions in this `awk'
that are not in POSIX `awk'.
+ As a side note, Dan Bornstein has created a Git repository tracking
+ all the versions of BWK `awk' that he could find. It's available
+ at `git://github.com/danfuzz/one-true-awk'.
+
`mawk'
Michael Brennan wrote an independent implementation of `awk',
called `mawk'. It is available under the GPL (*note Copying::),
@@ -21321,8 +28443,8 @@ Unix `awk'
In 2009, Thomas Dickey took on `mawk' maintenance. Basic
information is available on the project's web page
- (http://www.invisible-island.net/mawk/mawk.html). The download
- URL is `http://invisible-island.net/datafiles/release/mawk.tar.gz'.
+ (http://www.invisible-island.net/mawk). The download URL is
+ `http://invisible-island.net/datafiles/release/mawk.tar.gz'.
Once you have it, `gunzip' may be used to decompress this file.
Installation is similar to `gawk''s (*note Unix Installation::).
@@ -21345,11 +28467,12 @@ Unix `awk'
since approximately 2003.
`pawk'
- Nelson H.F. Beebe at the University of Utah has modified Brian
- Kernighan's `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-20030606.tar.gz' or
+ Nelson H.F. Beebe at the University of Utah has modified BWK `awk'
+ to provide timing and profiling information. It is different from
+ `gawk' with the `--profile' option (*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-20030606.tar.gz' or
`http://www.math.utah.edu/pub/pawk/pawk-20030606.tar.gz'.
Busybox Awk
@@ -21362,14 +28485,21 @@ Busybox Awk
(http://busybox.net).
The OpenSolaris POSIX `awk'
- The version of `awk' in `/usr/xpg4/bin' on Solaris is more-or-less
- POSIX-compliant. It is based on the `awk' from Mortice Kern
- Systems for PCs. The source code can be downloaded from the
- OpenSolaris web site (http://www.opensolaris.org). This author
- was able to make it compile and work under GNU/Linux with 1-2
- hours of work. Making it more generally portable (using GNU
- Autoconf and/or Automake) would take more work, and this has not
- been done, at least to our knowledge.
+ The versions of `awk' in `/usr/xpg4/bin' and `/usr/xpg6/bin' on
+ Solaris are more-or-less POSIX-compliant. They are based on the
+ `awk' from Mortice Kern Systems for PCs. We were able to make
+ this code compile and work under GNU/Linux with 1-2 hours of work.
+ Making it more generally portable (using GNU Autoconf and/or
+ Automake) would take more work, and this has not been done, at
+ least to our knowledge.
+
+ The source code used to be available from the OpenSolaris website.
+ However, that project was ended and the website shut down.
+ Fortunately, the Illumos project
+ (http://wiki.illumos.org/display/illumos/illumos+Home) makes this
+ implementation available. You can view the files one at a time
+ from
+ `https://github.com/joyent/illumos-joyent/blob/master/usr/src/cmd/awk_xpg4'.
`jawk'
This is an interpreter for `awk' written in Java. It claims to be
@@ -21380,10 +28510,16 @@ The OpenSolaris POSIX `awk'
Libmawk
This is an embeddable `awk' interpreter derived from `mawk'. For
- more information see `http://repo.hu/projects/libmawk/'.
+ more information, see `http://repo.hu/projects/libmawk/'.
+
+`pawk'
+ This is a Python module that claims to bring `awk'-like features
+ to Python. See `https://github.com/alecthomas/pawk' for more
+ information. (This is not related to Nelson Beebe's modified
+ version of BWK `awk', described earlier.)
QSE Awk
- This is an embeddable `awk' interpreter. For more information see
+ This is an embeddable `awk' interpreter. For more information, see
`http://code.google.com/p/qse/' and `http://awk.info/?tools/qse'.
`QTawk'
@@ -21393,12 +28529,42 @@ QSE Awk
`http://www.quiktrim.org/QTawk.html' for more information,
including the manual and a download link.
-`xgawk'
- XML `gawk'. This is a fork of the `gawk' 3.1.6 source base to
- support processing XML files. It has a number of interesting
- extensions which should one day be integrated into the main `gawk'
- code base. For more information, see the XMLgawk project web site
- (http://xmlgawk.sourceforge.net).
+ The project may also be frozen; no new code changes have been made
+ since approximately 2008.
+
+Other versions
+ See also the "Versions and implementations" section of the
+ Wikipedia article
+ (http://en.wikipedia.org/wiki/Awk_language#Versions_and_implementations)
+ for information on additional versions.
+
+
+
+File: gawk.info, Node: Installation summary, Prev: Other Versions, Up: Installation
+
+B.6 Summary
+===========
+
+ * The `gawk' distribution is available from GNU project's main
+ distribution site, `ftp.gnu.org'. The canonical build recipe is:
+
+ wget http://ftp.gnu.org/gnu/gawk/gawk-4.1.2.tar.gz
+ tar -xvpzf gawk-4.1.2.tar.gz
+ cd gawk-4.1.2
+ ./configure && make && make check
+
+ * `gawk' may be built on non-POSIX systems as well. The currently
+ supported systems are MS-Windows using DJGPP, MSYS, MinGW and
+ Cygwin, OS/2 using EMX, and both Vax/VMS and OpenVMS.
+ Instructions for each system are included in this major node.
+
+ * Bug reports should be sent via email to <bug-gawk@gnu.org>. Bug
+ reports should be in English, and should include the version of
+ `gawk', how it was compiled, and a short program and data file
+ which demonstrate the problem.
+
+ * There are a number of other freely available `awk'
+ implementations. Many are POSIX compliant; others are less so.

@@ -21416,9 +28582,11 @@ and maintainers of `gawk'. Everything in it applies specifically to
* 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.
+* Implementation Limitations:: Some limitations of the implementation.
+* Extension Design:: Design notes about the extension API.
+* Old Extension Mechanism:: Some compatibility for old extensions.
+* Notes summary:: Summary of implementation notes.

File: gawk.info, Node: Compatibility Mode, Next: Additions, Up: Notes
@@ -21436,7 +28604,7 @@ one more option available on the command line:
`-Y'
`--parsedebug'
- Prints out the parse stack information as the program is being
+ Print out the parse stack information as the program is being
parsed.
This option is intended only for serious `gawk' developers and not
@@ -21444,7 +28612,7 @@ for the casual user. It probably has not even been compiled into your
version of `gawk', since it slows down execution.

-File: gawk.info, Node: Additions, Next: Dynamic Extensions, Prev: Compatibility Mode, Up: Notes
+File: gawk.info, Node: Additions, Next: Future Extensions, Prev: Compatibility Mode, Up: Notes
C.2 Making Additions to `gawk'
==============================
@@ -21464,6 +28632,8 @@ as well as any considerations you should bear in mind.
`gawk'.
* New Ports:: Porting `gawk' to a new operating
system.
+* Derived Files:: Why derived files are kept in the Git
+ repository.

File: gawk.info, Node: Accessing The Source, Next: Adding Code, Up: Additions
@@ -21471,7 +28641,7 @@ File: gawk.info, Node: Accessing The Source, Next: Adding Code, Up: Additions
C.2.1 Accessing The `gawk' Git Repository
-----------------------------------------
-As `gawk' is Free Software, the source code is always available. *Note
+As `gawk' is Free Software, the source code is always available. *note
Gawk Distribution::, describes how to get and build the formal,
released versions of `gawk'.
@@ -21479,26 +28649,25 @@ released versions of `gawk'.
changes, you will probably wish to work with the development version.
To do so, you will need to access the `gawk' source code repository.
The code is maintained using the Git distributed version control system
-(http://git-scm.com/). You will need to install it if your system
+(http://git-scm.com). You will need to install it if your system
doesn't have it. Once you have done so, use the command:
git clone git://git.savannah.gnu.org/gawk.git
-This will clone the `gawk' repository. If you are behind a firewall
-that will not allow you to use the Git native protocol, you can still
-access the repository using:
+This clones the `gawk' repository. If you are behind a firewall that
+does not allow you to use the Git native protocol, you can still access
+the repository using:
git clone http://git.savannah.gnu.org/r/gawk.git
Once you have made changes, you can use `git diff' to produce a
-patch, and send that to the `gawk' maintainer; see *Note Bugs:: for how
-to do that.
-
- Finally, if you cannot install Git (e.g., if it hasn't been ported
-yet to your operating system), you can use the Git-CVS gateway to check
-out a copy using CVS, as follows:
+patch, and send that to the `gawk' maintainer; see *note Bugs::, for
+how to do that.
- cvs -d:pserver:anonymous@pserver.git.sv.gnu.org:/gawk.git co -d gawk master
+ Once upon a time there was Git-CVS gateway for use by people who
+could not install Git. However, this gateway no longer works, so you
+may have better luck using a more modern version control system like
+Bazaar, that has a Git plug-in for working with Git repositories.

File: gawk.info, Node: Adding Code, Next: New Ports, Prev: Accessing The Source, Up: Additions
@@ -21509,12 +28678,12 @@ C.2.2 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 to include your changes:
+possible to include them:
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.
+ writing it as an extension (*note Dynamic Extensions::). If
+ that's not possible, continue with the rest of the steps in this
+ list.
2. Be prepared to sign the appropriate paperwork. In order for the
FSF to distribute your changes, you must either place those
@@ -21526,17 +28695,17 @@ possible to include your changes:
3. 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'.)
+ version of `gawk', or better yet, relative to the latest code in
+ the Git repository. If your version of `gawk' is very old, I may
+ not be able to integrate your changes at all. (*Note Getting::,
+ for information on getting the latest version of `gawk'.)
4. 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 web site
- (http://www.gnu.org/prep/standards_toc.html). Texinfo, Info, and
- DVI versions are also available.)
+ GNU Project's website (http://www.gnu.org/prep/standards_toc.html).
+ Texinfo, Info, and DVI versions are also available.)
5. Use the `gawk' coding style. The C code for `gawk' follows the
instructions in the `GNU Coding Standards', with minor exceptions.
@@ -21575,9 +28744,9 @@ possible to include your changes:
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 `true' and `false' for `bool' values, the `NULL' symbolic
+ constant for pointer values, and the character constant
+ `'\0'' where appropriate, instead of `1' and `0'.
* Provide one-line descriptive comments for each function.
@@ -21613,9 +28782,10 @@ possible to include your changes:
7. Submit changes as unified diffs. Use `diff -u -r -N' to compare
the original `gawk' source tree with your version. 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 the GNU version of `diff', or best of all, `git diff' or
+ `git format-patch'. Send the output produced by `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
@@ -21624,7 +28794,8 @@ possible to include your 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.
+ making it easier for me to accept patches. It is simplest if you
+ just make this part of your diff.
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
@@ -21632,7 +28803,7 @@ isn't possible for me to do that with a minimum of extra work, then I
probably will not.

-File: gawk.info, Node: New Ports, Prev: Adding Code, Up: Additions
+File: gawk.info, Node: New Ports, Next: Derived Files, Prev: Adding Code, Up: Additions
C.2.3 Porting `gawk' to a New Operating System
----------------------------------------------
@@ -21640,7 +28811,7 @@ C.2.3 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
+ 1. Follow the guidelines in *note Adding Code::, concerning coding
style, submission of diffs, and so on.
2. Be prepared to sign the appropriate paperwork. In order for the
@@ -21665,18 +28836,24 @@ steps:
people. 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 `dfa.c', `dfa.h', `getopt1.c', `getopt.c', `getopt.h',
- `install-sh', `mkinstalldirs', `regcomp.c', `regex.c',
- `regexec.c', `regexex.c', `regex.h', `regex_internal.c', and
- `regex_internal.h'.
-
- 5. Be willing to continue to maintain the port. Non-Unix operating
+ are `dfa.c', `dfa.h', `getopt.c', `getopt.h', `getopt1.c',
+ `getopt_int.h', `gettext.h', `regcomp.c', `regex.c', `regex.h',
+ `regex_internal.c', `regex_internal.h', and `regexec.c'.
+
+ 5. A number of other files are provided by the GNU Autotools
+ (Autoconf, Automake, and GNU `gettext'). You should not change
+ them either, unless it is for a very good reason. The files are
+ `ABOUT-NLS', `config.guess', `config.rpath', `config.sub',
+ `depcomp', `INSTALL', `install-sh', `missing', `mkinstalldirs',
+ `xalloc.h', and `ylwrap'.
+
+ 6. 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.
+ to compile and run `gawk' on their systems. If no-one volunteers
+ to maintain a port, it becomes unsupported and it may be necessary
+ to remove it from the distribution.
- 6. Supply an appropriate `gawkmisc.???' file. Each port has its own
+ 7. 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
@@ -21692,7 +28869,7 @@ steps:
(Currently, this is only an issue for the PC operating system
ports.)
- 7. Supply a `Makefile' as well as any other C source and header files
+ 8. 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
@@ -21702,7 +28879,7 @@ steps:
avoid using names for your files that duplicate the names of files
in the main source directory.
- 8. Update the documentation. Please write a section (or sections)
+ 9. 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.
@@ -21714,681 +28891,479 @@ code that is already there.
style and brace layout that suits your taste.

-File: gawk.info, Node: Dynamic Extensions, Next: Future Extensions, Prev: Additions, Up: Notes
+File: gawk.info, Node: Derived Files, Prev: New Ports, Up: Additions
-C.3 Adding New Built-in Functions to `gawk'
-===========================================
+C.2.4 Why Generated Files Are Kept In Git
+-----------------------------------------
- Danger Will Robinson! Danger!!
- Warning! Warning!
- The Robot
+If you look at the `gawk' source in the Git repository, you will notice
+that it includes files that are automatically generated by GNU
+infrastructure tools, such as `Makefile.in' from Automake and even
+`configure' from Autoconf.
- 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 C `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.
+ This is different from many Free Software projects that do not store
+the derived files, because that keeps the repository less cluttered,
+and it is easier to see the substantive changes when comparing versions
+and trying to understand what changed between commits.
- 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, at some future time.
+ However, there are several reasons why the `gawk' maintainer likes
+to have everything in the repository.
- 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, nor will there
- ever be such a guarantee.
+ First, because it is then easy to reproduce any given version
+completely, without relying upon the availability of (older, likely
+obsolete, and maybe even impossible to find) other tools.
- NOTE: When `--sandbox' is specified, extensions are disabled
- (*note Options::.
+ As an extreme example, if you ever even think about trying to
+compile, oh, say, the V7 `awk', you will discover that not only do you
+have to bootstrap the V7 `yacc' to do so, but you also need the V7
+`lex'. And the latter is pretty much impossible to bring up on a
+modern GNU/Linux system.(1)
-* Menu:
+ (Or, let's say `gawk' 1.2 required `bison' whatever-it-was in 1989
+and that there was no `awkgram.c' file in the repository. Is there a
+guarantee that we could find that `bison' version? Or that _it_ would
+build?)
-* Internals:: A brief look at some `gawk' internals.
-* Plugin License:: A note about licensing.
-* Sample Library:: A example of new functions.
+ If the repository has all the generated files, then it's easy to
+just check them out and build. (Or _easier_, depending upon how far
+back we go.)
-
-File: gawk.info, Node: Internals, Next: Plugin License, Up: Dynamic Extensions
+ And that brings us to the second (and stronger) reason why all the
+files really need to be in Git. It boils down to who do you cater
+to--the `gawk' developer(s), or the user who just wants to check out a
+version and try it out?
-C.3.1 A Minimal Introduction to `gawk' Internals
-------------------------------------------------
+ The `gawk' maintainer wants it to be possible for any interested
+`awk' user in the world to just clone the repository, check out the
+branch of interest and build it. Without their having to have the
+correct version(s) of the autotools.(2) That is the point of the
+`bootstrap.sh' file. It touches the various other files in the right
+order such that
-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.
-
-`void force_wstring(NODE *n)'
- Similarly, this macro guarantees that a `NODE''s wide-string value
- is current. It may end up calling an internal `gawk' function.
- It also guarantees that the wide string is zero-terminated.
-
-`nargs'
- Inside an extension function, this is the actual number of
- parameters passed to the current 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->wstptr'
-`n->wstlen'
- The data and length of a `NODE''s wide-string value, respectively.
- Use `force_wstring()' to make sure these values are current.
-
-`n->type'
- The type of the `NODE'. This is a C `enum'. Values should be one
- of `Node_var', `Node_var_new', 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)'
- Finds, and installs if necessary, array elements. `symbol' is the
- array, `subs' is the subscript. This is usually a value created
- with `make_string()' (see below).
-
-`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 *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 unref(NODE *n)'
- This macro releases the memory associated with a `NODE' allocated
- with `make_string()' or `make_number()'. Understanding of `gawk'
- memory management is helpful.
-
-`void make_builtin(const 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(int nargs)
- {
- ...
- }
+ # The canonical incantation for building GNU software:
+ ./bootstrap.sh && ./configure && make
-`NODE *get_argument(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(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.
-
-`get_scalar_argument(i, opt)'
- This is a convenience macro that calls `get_actual_argument()'.
-
-`get_array_argument(i, opt)'
- This is a convenience macro that calls `get_actual_argument()'.
-
-`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' global 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 error value
- provided as the argument. It is provided as a convenience.
-
-`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'
- arrays, so you can refer to them for examples.
-
-`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''s
- `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''s
- `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'.
-
- 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.
-
- The following boilerplate code shows how to do this:
-
- NODE *the_arg;
-
- /* assume need 3rd arg, 0-based */
- the_arg = get_array_argument(2, FALSE);
-
- Again, you should spend time studying the `gawk' internals; don't
-just blindly copy this code.
-
-
-File: gawk.info, Node: Plugin License, Next: Sample Library, Prev: Internals, Up: Dynamic Extensions
-
-C.3.2 Extension Licensing
--------------------------
+will _just work_.
-Every dynamic extension should define the global symbol
-`plugin_is_GPL_compatible' to assert that it has been licensed under a
-GPL-compatible license. If this symbol does not exist, `gawk' will
-emit a fatal error and exit.
+ This is extremely important for the `master' and `gawk-X.Y-stable'
+branches.
- The declared type of the symbol should be `int'. It does not need
-to be in any allocated section, though. The code merely asserts that
-the symbol exists in the global scope. Something like this is enough:
+ Further, the `gawk' maintainer would argue that it's also important
+for the `gawk' developers. When he tried to check out the `xgawk'
+branch(3) to build it, he couldn't. (No `ltmain.sh' file, and he had no
+idea how to create it, and that was not the only problem.)
- int plugin_is_GPL_compatible;
+ He felt _extremely_ frustrated. With respect to that branch, the
+maintainer is no different than Jane User who wants to try to build
+`gawk-4.1-stable' or `master' from the repository.
-
-File: gawk.info, Node: Sample Library, Prev: Plugin License, Up: Dynamic Extensions
+ Thus, the maintainer thinks that it's not just important, but
+critical, that for any given branch, the above incantation _just works_.
-C.3.3 Example: Directory and File Operation Built-ins
------------------------------------------------------
+ A third reason to have all the files is that without them, using `git
+bisect' to try to find the commit that introduced a bug is exceedingly
+difficult. The maintainer tried to do that on another project that
+requires running bootstrapping scripts just to create `configure' and
+so on; it was really painful. When the repository is self-contained,
+using `git bisect' in it is very easy.
-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.
+ What are some of the consequences and/or actions to take?
-* Menu:
+ 1. We don't mind that there are differing files in the different
+ branches as a result of different versions of the autotools.
-* 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.
+ A. It's the maintainer's job to merge them and he will deal with
+ it.
-
-File: gawk.info, Node: Internal File Description, Next: Internal File Ops, Up: Sample Library
+ B. He is really good at `git diff x y > /tmp/diff1 ; gvim
+ /tmp/diff1' to remove the diffs that aren't of interest in
+ order to review code.
-C.3.3.1 Using `chdir()' and `stat()'
-....................................
+ 2. It would certainly help if everyone used the same versions of the
+ GNU tools as he does, which in general are the latest released
+ versions of Automake, Autoconf, `bison', and GNU `gettext'.
-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:
+ Installing from source is quite easy. It's how the maintainer
+ worked for years (and still works). He had `/usr/local/bin' at
+ the front of his `PATH' and just did:
- ...
- newdir = "/home/arnold/funstuff"
- ret = chdir(newdir)
- if (ret < 0) {
- printf("could not change to %s: %s\n",
- newdir, ERRNO) > "/dev/stderr"
- exit 1
- }
- ...
+ wget http://ftp.gnu.org/gnu/PACKAGE/PACKAGE-X.Y.Z.tar.gz
+ tar -xpzvf PACKAGE-X.Y.Z.tar.gz
+ cd PACKAGE-X.Y.Z
+ ./configure && make && make check
+ make install # as root
- 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:
+ Most of the above was originally written by the maintainer to other
+`gawk' developers. It raised the objection from one of the developers
+"... that anybody pulling down the source from Git is not an end user."
- 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"])
+ However, this is not true. There are "power `awk' users" who can
+build `gawk' (using the magic incantation shown previously) but who
+can't program in C. Thus, the major branches should be kept buildable
+all the time.
- The `stat()' function always clears the data array, even if the
-`stat()' fails. It fills in the following elements:
+ It was then suggested that there be a `cron' job to create nightly
+tarballs of "the source." Here, the problem is that there are source
+trees, corresponding to the various branches! So, nightly tarballs
+aren't the answer, especially as the repository can go for weeks
+without significant change being introduced.
-`"name"'
- The name of the file that was `stat()''ed.
+ Fortunately, the Git server can meet this need. For any given branch
+named BRANCHNAME, use:
-`"dev"'
-`"ino"'
- The file's device and inode numbers, respectively.
+ wget http://git.savannah.gnu.org/cgit/gawk.git/snapshot/gawk-BRANCHNAME.tar.gz
-`"mode"'
- The file's mode, as a numeric value. This includes both the file's
- type and its permissions.
+to retrieve a snapshot of the given branch.
-`"nlink"'
- The number of hard links (directory entries) the file has.
+ ---------- Footnotes ----------
-`"uid"'
-`"gid"'
- The numeric user and group ID numbers of the file's owner.
+ (1) We tried. It was painful.
-`"size"'
- The size in bytes of the file.
+ (2) There is one GNU program that is (in our opinion) severely
+difficult to bootstrap from the Git repository. For example, on the
+author's old (but still working) PowerPC Macintosh with Mac OS X 10.5,
+it was necessary to bootstrap a ton of software, starting with Git
+itself, in order to try to work with the latest code. It's not
+pleasant, and especially on older systems, it's a big waste of time.
-`"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.
+ Starting with the latest tarball was no picnic either. The
+maintainers had dropped `.gz' and `.bz2' files and only distribute
+`.tar.xz' files. It was necessary to bootstrap `xz' first!
-`"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::).
+ (3) A branch (since removed) created by one of the other developers
+that did not include the generated files.
-`"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"'.
+
+File: gawk.info, Node: Future Extensions, Next: Implementation Limitations, Prev: Additions, Up: Notes
-`"type"'
- A printable string representation of the file's type. The value
- is one of the following:
+C.3 Probable Future Extensions
+==============================
- `"blockdev"'
- `"chardev"'
- The file is a block or character device ("special file").
+ AWK is a language similar to PERL, only considerably more elegant.
+ -- Arnold Robbins
- `"directory"'
- The file is a directory.
+ Hey! -- Larry Wall
- `"fifo"'
- The file is a named-pipe (also known as a FIFO).
+ The `TODO' file in the `master' branch of the `gawk' Git repository
+lists possible future enhancements. Some of these relate to the source
+code, and others to possible new features. Please see that file for
+the list. *Note Additions::, if you are interested in tackling any of
+the projects listed there.
- `"file"'
- The file is just a regular file.
+
+File: gawk.info, Node: Implementation Limitations, Next: Extension Design, Prev: Future Extensions, Up: Notes
- `"socket"'
- The file is an `AF_UNIX' ("Unix domain") socket in the
- filesystem.
+C.4 Some Limitations of the Implementation
+==========================================
- `"symlink"'
- The file is a symbolic link.
+This following table describes limits of `gawk' on a Unix-like system
+(although it is variable even then). Other systems may have different
+limits.
- 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::):
+Item Limit
+--------------------------------------------------------------------------
+Characters in a character 2^(number of bits per byte)
+class
+Length of input record `MAX_INT'
+Length of output record Unlimited
+Length of source line Unlimited
+Number of fields in a record `MAX_LONG'
+Number of file redirections Unlimited
+Number of input records in `MAX_LONG'
+one file
+Number of input records `MAX_LONG'
+total
+Number of pipe redirections min(number of processes per user, number
+ of open files)
+Numeric values Double-precision floating point (if not
+ using MPFR)
+Size of a field `MAX_INT'
+Size of a literal string `MAX_INT'
+Size of a printf string `MAX_INT'
+
+
+File: gawk.info, Node: Extension Design, Next: Old Extension Mechanism, Prev: Implementation Limitations, Up: Notes
+
+C.5 Extension API Design
+========================
-`"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.
+This minor node documents the design of the extension API, including a
+discussion of some of the history and problems that needed to be solved.
-`"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).
+ The first version of extensions for `gawk' was developed in the
+mid-1990s and released with `gawk' 3.1 in the late 1990s. The basic
+mechanisms and design remained unchanged for close to 15 years, until
+2012.
-`"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.
+ The old extension mechanism used data types and functions from
+`gawk' itself, with a "clever hack" to install extension functions.
-
-File: gawk.info, Node: Internal File Ops, Next: Using Internal File Ops, Prev: Internal File Description, Up: Sample Library
+ `gawk' included some sample extensions, of which a few were really
+useful. However, it was clear from the outset that the extension
+mechanism was bolted onto the side and was not really well thought out.
-C.3.3.2 C Code for `chdir()' and `stat()'
-.........................................
+* Menu:
-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)
+* Old Extension Problems:: Problems with the old mechanism.
+* Extension New Mechanism Goals:: Goals for the new mechanism.
+* Extension Other Design Decisions:: Some other design decisions.
+* Extension Future Growth:: Some room for future growth.
- #include "awk.h"
+
+File: gawk.info, Node: Old Extension Problems, Next: Extension New Mechanism Goals, Up: Extension Design
- #include <sys/sysmacros.h>
+C.5.1 Problems With The Old Mechanism
+-------------------------------------
- int plugin_is_GPL_compatible;
+The old extension mechanism had several problems:
- /* do_chdir --- provide dynamically loaded chdir() builtin for gawk */
+ * It depended heavily upon `gawk' internals. Any time the `NODE'
+ structure(1) changed, an extension would have to be recompiled.
+ Furthermore, to really write extensions required understanding
+ something about `gawk''s internal functions. There was some
+ documentation in this Info file, but it was quite minimal.
- static NODE *
- do_chdir(int nargs)
- {
- NODE *newdir;
- int ret = -1;
+ * Being able to call into `gawk' from an extension required linker
+ facilities that are common on Unix-derived systems but that did
+ not work on MS-Windows systems; users wanting extensions on
+ MS-Windows had to statically link them into `gawk', even though
+ MS-Windows supports dynamic loading of shared objects.
- if (do_lint && nargs != 1)
- lintwarn("chdir: called with incorrect number of arguments");
+ * The API would change occasionally as `gawk' changed; no
+ compatibility between versions was ever offered or planned for.
- newdir = get_scalar_argument(0, FALSE);
+ Despite the drawbacks, the `xgawk' project developers forked `gawk'
+and developed several significant extensions. They also enhanced
+`gawk''s facilities relating to file inclusion and shared object access.
- 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.
+ A new API was desired for a long time, but only in 2012 did the
+`gawk' maintainer and the `xgawk' developers finally start working on
+it together. More information about the `xgawk' project is provided in
+*note gawkextlib::.
- By convention, for an `awk' function `foo', the function that
-implements it is called `do_foo'. The function should take a `int'
-argument, usually called `nargs', that represents the number of defined
-arguments for the function. The `newdir' variable represents the new
-directory to change to, retrieved with `get_scalar_argument()'. Note
-that the first argument is numbered zero.
+ ---------- Footnotes ----------
- 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.
+ (1) A critical central data structure inside `gawk'.
- (void) force_string(newdir);
- ret = chdir(newdir->stptr);
- if (ret < 0)
- update_ERRNO();
+
+File: gawk.info, Node: Extension New Mechanism Goals, Next: Extension Other Design Decisions, Prev: Old Extension Problems, Up: Extension Design
- Finally, the function returns the return value to the `awk' level:
+C.5.2 Goals For A New Mechanism
+-------------------------------
- return make_number((AWKNUM) ret);
- }
+Some goals for the new API were:
- 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:
+ * The API should be independent of `gawk' internals. Changes in
+ `gawk' internals should not be visible to the writer of an
+ extension function.
- /* format_mode --- turn a stat mode field into something readable */
+ * The API should provide _binary_ compatibility across `gawk'
+ releases as long as the API itself does not change.
- static char *
- format_mode(unsigned long fmode)
- {
- ...
- }
+ * The API should enable extensions written in C or C++ to have
+ roughly the same "appearance" to `awk'-level code as `awk'
+ functions do. This means that extensions should have:
- Next comes the `do_stat()' function. It starts with variable
-declarations and argument checking:
+ - The ability to access function parameters.
- /* do_stat --- provide a stat() function for gawk */
+ - The ability to turn an undefined parameter into an array
+ (call by reference).
- static NODE *
- do_stat(int nargs)
- {
- NODE *file, *array, *tmp;
- struct stat sbuf;
- int ret;
- NODE **aptr;
- char *pmode; /* printable mode */
- char *type = "unknown";
+ - The ability to create, access and update global variables.
- if (do_lint && nargs > 2)
- lintwarn("stat: called with too many arguments");
+ - Easy access to all the elements of an array at once ("array
+ flattening") in order to loop over all the element in an easy
+ fashion for C code.
- Then comes the actual work. First, the function gets the arguments.
-Then, it always clears the array. The code use `lstat()' (instead of
-`stat()') to get the file information, in case the file is a symbolic
-link. If there's an error, it sets `ERRNO' and returns:
+ - The ability to create arrays (including `gawk''s true arrays
+ of arrays).
- /* file is first arg, array to hold results is second */
- file = get_scalar_argument(0, FALSE);
- array = get_array_argument(1, FALSE);
+ Some additional important goals were:
- /* empty out the array */
- assoc_clear(array);
+ * The API should use only features in ISO C 90, so that extensions
+ can be written using the widest range of C and C++ compilers. The
+ header should include the appropriate `#ifdef __cplusplus' and
+ `extern "C"' magic so that a C++ compiler could be used. (If
+ using C++, the runtime system has to be smart enough to call any
+ constructors and destructors, as `gawk' is a C program. As of this
+ writing, this has not been tested.)
- /* lstat the file, if error, set ERRNO and return */
- (void) force_string(file);
- ret = lstat(file->stptr, & sbuf);
- if (ret < 0) {
- update_ERRNO();
- return make_number((AWKNUM) ret);
- }
+ * The API mechanism should not require access to `gawk''s symbols(1)
+ by the compile-time or dynamic linker, in order to enable creation
+ of extensions that also work on MS-Windows.
- 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:
+ During development, it became clear that there were other features
+that should be available to extensions, which were also subsequently
+provided:
- /* fill in the array */
- aptr = assoc_lookup(array, tmp = make_string("name", 4));
- *aptr = dupnode(file);
- unref(tmp);
+ * Extensions should have the ability to hook into `gawk''s I/O
+ redirection mechanism. In particular, the `xgawk' developers
+ provided a so-called "open hook" to take over reading records.
+ During development, this was generalized to allow extensions to
+ hook into input processing, output processing, and two-way I/O.
- aptr = assoc_lookup(array, tmp = make_string("mode", 4));
- *aptr = make_number((AWKNUM) sbuf.st_mode);
- unref(tmp);
+ * An extension should be able to provide a "call back" function to
+ perform cleanup actions when `gawk' exits.
- aptr = assoc_lookup(array, tmp = make_string("pmode", 5));
- pmode = format_mode(sbuf.st_mode);
- *aptr = make_string(pmode, strlen(pmode));
- unref(tmp);
+ * An extension should be able to provide a version string so that
+ `gawk''s `--version' option can provide information about
+ extensions as well.
- When done, return the `lstat()' return value:
+ The requirement to avoid access to `gawk''s symbols is, at first
+glance, a difficult one to meet.
+ One design, apparently used by Perl and Ruby and maybe others, would
+be to make the mainline `gawk' code into a library, with the `gawk'
+utility a small C `main()' function linked against the library.
- return make_number((AWKNUM) ret);
- }
+ This seemed like the tail wagging the dog, complicating build and
+installation and making a simple copy of the `gawk' executable from one
+system to another (or one place to another on the same system!) into a
+chancy operation.
- 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:
+ Pat Rankin suggested the solution that was adopted. *Note Extension
+Mechanism Outline::, for the details.
- /* dlload --- load new builtins in this library */
+ ---------- Footnotes ----------
- NODE *
- dlload(NODE *tree, void *dl)
- {
- make_builtin("chdir", do_chdir, 1);
- make_builtin("stat", do_stat, 2);
- return make_number((AWKNUM) 0);
- }
+ (1) The "symbols" are the variables and functions defined inside
+`gawk'. Access to these symbols by code external to `gawk' loaded
+dynamically at runtime is problematic on MS-Windows.
- And that's it! As an exercise, consider adding functions to
-implement system calls such as `chown()', `chmod()', and `umask()'.
+
+File: gawk.info, Node: Extension Other Design Decisions, Next: Extension Future Growth, Prev: Extension New Mechanism Goals, Up: Extension Design
- ---------- Footnotes ----------
+C.5.3 Other Design Decisions
+----------------------------
- (1) This version is edited slightly for presentation. See
-`extension/filefuncs.c' in the `gawk' distribution for the complete
-version.
+As an arbitrary design decision, extensions can read the values of
+predefined variables and arrays (such as `ARGV' and `FS'), but cannot
+change them, with the exception of `PROCINFO'.
-
-File: gawk.info, Node: Using Internal File Ops, Prev: Internal File Ops, Up: Sample Library
+ The reason for this is to prevent an extension function from
+affecting the flow of an `awk' program outside its control. While a
+real `awk' function can do what it likes, that is at the discretion of
+the programmer. An extension function should provide a service or make
+a C API available for use within `awk', and not mess with `FS' or
+`ARGC' and `ARGV'.
-C.3.3.3 Integrating the Extensions
-..................................
+ In addition, it becomes easy to start down a slippery slope. How
+much access to `gawk' facilities do extensions need? Do they need
+`getline'? What about calling `gsub()' or compiling regular
+expressions? What about calling into `awk' functions? (_That_ would be
+messy.)
-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:
+ In order to avoid these issues, the `gawk' developers chose to start
+with the simplest, most basic features that are still truly useful.
- $ gcc -fPIC -shared -DHAVE_CONFIG_H -c -O -g -IIDIR filefuncs.c
- $ ld -o filefuncs.so -shared filefuncs.o
+ Another decision is that although `gawk' provides nice things like
+MPFR, and arrays indexed internally by integers, these features are not
+being brought out to the API in order to keep things simple and close to
+traditional `awk' semantics. (In fact, arrays indexed internally by
+integers are so transparent that they aren't even documented!)
- 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:
+ Additionally, all functions in the API check that their pointer
+input parameters are not `NULL'. If they are, they return an error.
+(It is a good idea for extension code to verify that pointers received
+from `gawk' are not `NULL'. Such a thing should not happen, but the
+`gawk' developers are only human, and they have been known to
+occasionally make mistakes.)
- # file testff.awk
- BEGIN {
- extension("./filefuncs.so", "dlload")
+ With time, the API will undoubtedly evolve; the `gawk' developers
+expect this to be driven by user needs. For now, the current API seems
+to provide a minimal yet powerful set of features for creating
+extensions.
- chdir(".") # no-op
+
+File: gawk.info, Node: Extension Future Growth, Prev: Extension Other Design Decisions, Up: Extension Design
- 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"])
+C.5.4 Room For Future Growth
+----------------------------
- 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"])
- }
+The API can later be expanded, in two ways:
- Here are the results of running the program:
+ * `gawk' passes an "extension id" into the extension when it first
+ loads the extension. The extension then passes this id back to
+ `gawk' with each function call. This mechanism allows `gawk' to
+ identify the extension calling into it, should it need to know.
- $ gawk -f testff.awk
- -| Info for testff.awk
- -| ret = 0
- -| data["size"] = 607
- -| data["ino"] = 14945891
- -| data["name"] = testff.awk
- -| data["pmode"] = -rw-rw-r--
- -| data["nlink"] = 1
- -| data["atime"] = 1293993369
- -| data["mtime"] = 1288520752
- -| data["mode"] = 33204
- -| data["blksize"] = 4096
- -| data["dev"] = 2054
- -| data["type"] = file
- -| data["gid"] = 500
- -| data["uid"] = 500
- -| data["blocks"] = 8
- -| data["ctime"] = 1290113572
- -| testff.awk modified: 10 31 10 12:25:52
- -|
- -| Info for JUNK
- -| ret = -1
- -| JUNK modified: 01 01 70 02:00:00
+ * Similarly, the extension passes a "name space" into `gawk' when it
+ registers each extension function. This accommodates a possible
+ future mechanism for grouping extension functions and possibly
+ avoiding name conflicts.
+
+ Of course, as of this writing, no decisions have been made with
+respect to any of the above.

-File: gawk.info, Node: Future Extensions, Prev: Dynamic Extensions, Up: Notes
+File: gawk.info, Node: Old Extension Mechanism, Next: Notes summary, Prev: Extension Design, Up: Notes
-C.4 Probable Future Extensions
-==============================
+C.6 Compatibility For Old Extensions
+====================================
- AWK is a language similar to PERL, only considerably more elegant.
- Arnold Robbins
+*note Dynamic Extensions::, describes the supported API and mechanisms
+for writing extensions for `gawk'. This API was introduced in version
+4.1. However, for many years `gawk' provided an extension mechanism
+that required knowledge of `gawk' internals and that was not as well
+designed.
- Hey!
- Larry Wall
+ In order to provide a transition period, `gawk' version 4.1
+continues to support the original extension mechanism. This will be
+true for the life of exactly one major release. This support will be
+withdrawn, and removed from the source code, at the next major release.
- 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.
+ Briefly, original-style extensions should be compiled by including
+the `awk.h' header file in the extension source code. Additionally, you
+must define the identifier `GAWK' when building (use `-DGAWK' with
+Unix-style compilers). Otherwise, the definitions in `gawkapi.h' will
+cause conflicts with those in `awk.h' and your extension will not
+compile.
- Following is a list of probable future changes visible at the `awk'
-language level:
+ Just as in previous versions, you load an old-style extension with
+the `extension()' built-in function (which is not otherwise documented).
+This function in turn finds and loads the shared object file containing
+the extension and calls its `dl_load()' C routine.
-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.
+ Because original-style and new-style extensions use different
+initialization routines (`dl_load()' versus `dlload()'), they may safely
+be installed in the same directory (to be found by `AWKLIBPATH')
+without conflict.
-`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.
+ The `gawk' development team strongly recommends that you convert any
+old extensions that you may have to use the new API described in *note
+Dynamic Extensions::.
-Databases
- It may be possible to map a GDBM/NDBM/SDBM file into an `awk'
- array.
+
+File: gawk.info, Node: Notes summary, Prev: Old Extension Mechanism, Up: Notes
-More `lint' warnings
- There are more things that could be checked for portability.
+C.7 Summary
+===========
+
+ * `gawk''s extensions can be disabled with either the
+ `--traditional' option or with the `--posix' option. The
+ `--parsedebug' option is available if `gawk' is compiled with
+ `-DDEBUG'.
- Following is a list of probable improvements that will make `gawk''s
-source code easier to work with:
+ * The source code for `gawk' is maintained in a publicly accessible
+ Git repository. Anyone may check it out and view the source.
-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'.
+ * Contributions to `gawk' are welcome. Following the steps outlined
+ in this major node will make it easier to integrate your
+ contributions into the code base. This applies both to new
+ feature contributions and to ports to additional operating systems.
-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.
+ * `gawk' has some limits--generally those that are imposed by the
+ machine architecture.
-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.
+ * The extension API design was intended to solve a number of problems
+ with the previous extension mechanism, enable features needed by
+ the `xgawk' project, and provide binary compatibility going
+ forward.
- Finally, the programs in the test suite could use documenting in
-this Info file.
+ * The previous extension mechanism is still supported in version 4.1
+ of `gawk', but it _will_ be removed in the next major release.
- *Note Additions::, if you are interested in tackling any of these
-projects.

File: gawk.info, Node: Basic Concepts, Next: Glossary, Prev: Notes, Up: Top
@@ -22407,7 +29382,6 @@ introductory texts that you should refer to instead.)
* 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.

File: gawk.info, Node: Basic High Level, Next: Basic Data Typing, Up: Basic Concepts
@@ -22416,12 +29390,13 @@ 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 and produce results. See *note figure-general-flow::.
- _______
- +------+ / \ +---------+
- | Data | -----> < Program > -----> | Results |
- +------+ \_______/ +---------+
+ _______
++------+ / \ +---------+
+| Data | -----> < Program > -----> | Results |
++------+ \_______/ +---------+
+Figure D.1: General Program Flow
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
@@ -22429,19 +29404,20 @@ 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 |
- +---------+
+basic set of steps, as shown in *note figure-process-flow:::
+
+ ______
++----------------+ / More \ No +----------+
+| Initialization | -------> < Data > -------> | Clean Up |
++----------------+ ^ \ ? / +----------+
+ | +--+-+
+ | | Yes
+ | |
+ | V
+ | +---------+
+ +-----+ Process |
+ +---------+
+Figure D.2: Basic Program Steps
Initialization
These are the things you do before actually starting to process
@@ -22506,7 +29482,7 @@ such as C, C++, or Ada, and then translated, or "compiled", into a form
that the computer can execute directly.

-File: gawk.info, Node: Basic Data Typing, Next: Floating Point Issues, Prev: Basic High Level, Up: Basic Concepts
+File: gawk.info, Node: Basic Data Typing, Prev: Basic High Level, Up: Basic Concepts
D.2 Data Values in a Computer
=============================
@@ -22526,34 +29502,10 @@ 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 systems, this range is -2,147,483,648 to 2,147,483,647. However,
-many systems now support a range from -9,223,372,036,854,775,808 to
-9,223,372,036,854,775,807.
-
- 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 systems, the
-range is from 0 to 4,294,967,295. However, many systems now support a
-range from 0 to 18,446,744,073,709,551,615.
-
- 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.
+ *note Computer Arithmetic::, provided a basic introduction to numeric
+types (integer and floating-point) and how they are used in a computer.
+Please review that information, including a number of caveats that were
+presented.
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
@@ -22564,15 +29516,19 @@ 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.)
+(Remember grade school? 42 = 4 x 10 + 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::.
+represents (1 x 8) + (0 x 4) + (1 x 2) + (0 x 1), or decimal 10. Octal
+and hexadecimal are discussed more in *note Nondecimal-numbers::.
+
+ 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.
Programs are written in programming languages. Hundreds, if not
thousands, of programming languages exist. One of the most popular is
@@ -22591,218 +29547,6 @@ In 1999, a revised ISO C standard was approved and released. Where it
makes sense, POSIX `awk' is compatible with 1999 ISO C.

-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
-(http://www.validlab.com/goldberg/paper.pdf) by David Goldberg, "What
-Every Computer Scientist Should Know About Floating-point Arithmetic,"
-`ACM Computing Surveys' *23*, 1 (1991-03), 5-48. This is worth reading
-if you are interested in the details, but it does require a background
-in computer science.
-
-* Menu:
-
-* String Conversion Precision:: The String Value Can Lie.
-* Unexpected Results:: Floating Point Numbers Are Not Abstract
- Numbers.
-* POSIX Floating Point Problems:: Standards Versus Existing Practice.
-
-
-File: gawk.info, Node: String Conversion Precision, Next: Unexpected Results, Up: Floating Point Issues
-
-D.3.1 The String Value Can Lie
-------------------------------
-
-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:
-
- {
- sum = $1 + $2
- # see it for what it is
- printf("sum = %.12g\n", sum)
- # use CONVFMT
- a = "<" sum ">"
- print "a =", a
- # use OFMT
- print "sum =", sum
- }
-
-This program shows the full value of the sum of `$1' and `$2' 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 3.654321 1.2345678 | awk -f values.awk
- -| sum = 4.8888888
- -| a = <4.88889>
- -| sum = 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.(1)
-
- ---------- Footnotes ----------
-
- (1) Pathological cases can require up to 752 digits (!), but we
-doubt that you need to worry about this.
-
-
-File: gawk.info, Node: Unexpected Results, Next: POSIX Floating Point Problems, Prev: String Conversion Precision, Up: Floating Point Issues
-
-D.3.2 Floating Point Numbers Are Not Abstract Numbers
------------------------------------------------------
-
-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.
-
-
-File: gawk.info, Node: POSIX Floating Point Problems, Prev: Unexpected Results, Up: Floating Point Issues
-
-D.3.3 Standards Versus Existing Practice
-----------------------------------------
-
-Historically, `awk' has converted any non-numeric looking string to the
-numeric value zero, when required. Furthermore, the original
-definition of the language and the original POSIX standards specified
-that `awk' only understands decimal numbers (base 10), and not octal
-(base 8) or hexadecimal numbers (base 16).
-
- Changes in the language of the 2001 and 2004 POSIX standard can be
-interpreted to imply that `awk' should support additional features.
-These features are:
-
- * Interpretation of floating point data values specified in
- hexadecimal notation (`0xDEADBEEF'). (Note: data values, _not_
- source code constants.)
-
- * Support for the special IEEE 754 floating point values "Not A
- Number" (NaN), positive Infinity ("inf") and negative Infinity
- ("-inf"). In particular, the format for these values is as
- specified by the ISO 1999 C standard, which ignores case and can
- allow machine-dependent additional characters after the `nan' and
- allow either `inf' or `infinity'.
-
- The first problem is that both of these are clear changes to
-historical practice:
-
- * The `gawk' maintainer feels that supporting hexadecimal floating
- point values, in particular, is ugly, and was never intended by the
- original designers to be part of the language.
-
- * Allowing completely alphabetic strings to have valid numeric
- values is also a very severe departure from historical practice.
-
- The second problem is that the `gawk' maintainer feels that this
-interpretation of the standard, which requires a certain amount of
-"language lawyering" to arrive at in the first place, was not even
-intended by the standard developers. In other words, "we see how you
-got where you are, but we don't think that that's where you want to be."
-
- The 2008 POSIX standard added explicit wording to allow, but not
-require, that `awk' support hexadecimal floating point values and
-special values for "Not A Number" and infinity.
-
- Although the `gawk' maintainer continues to feel that providing
-those features is inadvisable, nevertheless, on systems that support
-IEEE floating point, it seems reasonable to provide _some_ way to
-support NaN and Infinity values. The solution implemented in `gawk' is
-as follows:
-
- * With the `--posix' command-line option, `gawk' becomes "hands
- off." String values are passed directly to the system library's
- `strtod()' function, and if it successfully returns a numeric
- value, that is what's used.(1) By definition, the results are not
- portable across different systems. They are also a little
- surprising:
-
- $ echo nanny | gawk --posix '{ print $1 + 0 }'
- -| nan
- $ echo 0xDeadBeef | gawk --posix '{ print $1 + 0 }'
- -| 3735928559
-
- * Without `--posix', `gawk' interprets the four strings `+inf',
- `-inf', `+nan', and `-nan' specially, producing the corresponding
- special numeric values. The leading sign acts a signal to `gawk'
- (and the user) that the value is really numeric. Hexadecimal
- floating point is not supported (unless you also use
- `--non-decimal-data', which is _not_ recommended). For example:
-
- $ echo nanny | gawk '{ print $1 + 0 }'
- -| 0
- $ echo +nan | gawk '{ print $1 + 0 }'
- -| nan
- $ echo 0xDeadBeef | gawk '{ print $1 + 0 }'
- -| 0
-
- `gawk' does ignore case in the four special values. Thus `+nan'
- and `+NaN' are the same.
-
- ---------- Footnotes ----------
-
- (1) You asked for it, you got it.
-
-
File: gawk.info, Node: Glossary, Next: Copying, Prev: Basic Concepts, Up: Top
Glossary
@@ -22811,8 +29555,12 @@ 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::.)
+ Actions are always enclosed in braces. (*Note Action Overview::.)
+
+Ada
+ A programming language originally defined by the U.S. Department of
+ Defense for embedded programming. It was designed to enforce good
+ Software Engineering practices.
Amazing `awk' Assembler
Henry Spencer at the University of Toronto wrote a retargetable
@@ -22822,11 +29570,6 @@ Amazing `awk' Assembler
been better written in another language. You can get it from
`http://awk.info/?awk100/aaa'.
-Ada
- A programming language originally defined by the U.S. Department of
- Defense for embedded programming. It was designed to enforce good
- Software Engineering practices.
-
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'
@@ -22878,9 +29621,6 @@ 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
@@ -22888,7 +29628,7 @@ Bit
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::.
+ 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
@@ -22901,9 +29641,13 @@ Boolean 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.
+ originally written by Steven R. Bourne at Bell Laboratories. Many
+ shells (Bash, `ksh', `pdksh', `zsh') are generally upwardly
+ compatible with the Bourne shell.
+
+Braces
+ The characters `{' and `}'. Braces are used in `awk' for
+ delimiting actions, compound statements, and function bodies.
Built-in Function
The `awk' language provides built-in functions that perform various
@@ -22923,14 +29667,6 @@ Built-in Variable
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
@@ -22950,8 +29686,8 @@ Character Set
ASCII (American Standard Code for Information Interchange). Many
European countries use an extension of ASCII known as ISO-8859-1
(ISO Latin-1). The Unicode character set (http://www.unicode.org)
- is becoming increasingly popular and standard, and is particularly
- widely used on GNU/Linux systems.
+ is increasingly popular and standard, and is particularly widely
+ used on GNU/Linux systems.
CHEM
A preprocessor for `pic' that reads descriptions of molecules and
@@ -22959,9 +29695,11 @@ CHEM
Brian Kernighan and Jon Bentley, and is available from
`http://netlib.sandia.gov/netlib/typesetting/chem.gz'.
-Coprocess
- A subordinate program with which two-way communications is
- possible.
+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::.)
Compiler
A program that translates human-readable source code into
@@ -22985,15 +29723,16 @@ Conditional Expression
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::.)
+Cookie
+ A peculiar goodie, token, saying or remembrance produced by or
+ presented to a program. (With thanks to Professor Doug McIlroy.)
+
+Coprocess
+ A subordinate program with which two-way communications is
+ possible.
Curly Braces
- The characters `{' and `}'. Curly braces are used in `awk' for
- delimiting actions, compound statements, and function bodies.
+ See "Braces."
Dark Corner
An area in the language where specifications often were (or still
@@ -23032,15 +29771,15 @@ Dynamic Regular Expression
`"foo"', but it may also be an expression whose value can vary.
(*Note Computed Regexps::.)
+Empty String
+ See "Null String."
+
Environment
- A collection of strings, of the form NAME`='VAL, that each program
+ 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 most systems are represented as seconds since the epoch,
@@ -23066,12 +29805,12 @@ FDL
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
+ change by setting the predefined 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. If you
wish to specify the contents of fields instead of the field
- separator, you can use the built-in variable `FPAT' to do so.
- (*Note Field Separators::, *Note Constant Size::, and *Note
+ separator, you can use the predefined variable `FPAT' to do so.
+ (*Note Field Separators::, *note Constant Size::, and *note
Splitting By Content::.)
Flag
@@ -23084,31 +29823,31 @@ Floating-Point Number
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 strings contained in the
- built-in variables `CONVFMT' and `OFMT'. (*Note Control Letters::.)
+ Format strings control the appearance of output in the
+ `strftime()' and `sprintf()' functions, and in the `printf'
+ statement as well. Also, data conversions from numbers to strings
+ are controlled by the format strings contained in the predefined
+ variables `CONVFMT' and `OFMT'. (*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.
+FSF
+ See "Free Software Foundation."
+
+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::.)
+
`gawk'
The GNU implementation of `awk'.
@@ -23143,8 +29882,8 @@ 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).
- *Note Nondecimal-numbers::.
+ indicate their base. Thus, `0x12' is 18 ((1 x 16) + 2). *Note
+ Nondecimal-numbers::.
I/O
Abbreviation for "Input/Output," the act of moving data into and/or
@@ -23175,12 +29914,16 @@ Interval Expression
originally 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.
+ The International Organization for Standardization. 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. See the ISO website
+ (http://www.iso.org/iso/home/about.htm) for more information about
+ the name of the organization and its language-independent
+ three-letter acronym.
Java
A modern programming language originally developed by Sun
@@ -23197,19 +29940,19 @@ Keyword
`gawk''s keywords are: `BEGIN', `BEGINFILE', `END', `ENDFILE',
`break', `case', `continue', `default' `delete', `do...while',
`else', `exit', `for...in', `for', `function', `func', `if',
- `nextfile', `next', `switch', and `while'.
+ `next', `nextfile', `switch', and `while'.
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."
+Linux
+ See "GNU/Linux."
+
Localization
The process of providing the data necessary for an
internationalized program to work in a particular language.
@@ -23253,11 +29996,7 @@ Number
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). *Note
- Nondecimal-numbers::.
-
-P1003.1, P1003.2
- See "POSIX."
+ Thus, `013' is 11 ((1 x 8) + 3). *Note Nondecimal-numbers::.
Pattern
Patterns tell `awk' which input records are interesting to which
@@ -23269,6 +30008,11 @@ Pattern
the input record against a regular expression. (*Note Pattern
Overview::.)
+PEBKAC
+ An acronym describing what is possibly the most frequent source of
+ computer usage problems. (Problem Exists Between Keyboard And
+ Chair.)
+
POSIX
The name for a series of standards that specify a Portable
Operating System interface. The "IX" denotes the Unix heritage of
@@ -23293,9 +30037,9 @@ Range (of input lines)
specify single lines. (*Note Pattern Overview::.)
Recursion
- When a function calls itself, either directly or indirectly. As
- long as this is not clear, refer to the entry for "recursion." If
- this is clear, stop, and proceed to the next entry.
+ When a function calls itself, either directly or indirectly. If
+ this is clear, stop, and proceed to the next entry. Otherwise,
+ refer to the entry for "recursion."
Redirection
Redirection means performing input from something other than the
@@ -23306,7 +30050,7 @@ Redirection
`|', and `|&' operators. You can redirect the output of the
`print' and `printf' statements to a file or a system command,
using the `>', `>>', `|', and `|&' operators. (*Note Getline::,
- and *Note Redirection::.)
+ and *note Redirection::.)
Regexp
See "Regular Expression."
@@ -23347,13 +30091,13 @@ Search Path
source files. In the shell, a list of directories to search for
executable programs.
+`sed'
+ See "Stream Editor."
+
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
@@ -23376,8 +30120,8 @@ Single Precision
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'.
+ some ancient 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.
@@ -23411,7 +30155,7 @@ Text Domain
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."
+ `strftime()', and `systime()'. See also "Epoch," "GMT," and "UTC."
Unix
A computer operating system originally developed in the early
@@ -23440,7 +30184,6 @@ GNU General Public License
**************************
Version 3, 29 June 2007
-
Copyright (C) 2007 Free Software Foundation, Inc. `http://fsf.org/'
Everyone is permitted to copy and distribute verbatim copies of this
@@ -24163,7 +30906,6 @@ GNU Free Documentation License
******************************
Version 1.3, 3 November 2008
-
Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
`http://fsf.org/'
@@ -24651,8 +31393,8 @@ Index
* Menu:
-* ! (exclamation point), ! operator: Boolean Ops. (line 67)
-* ! (exclamation point), ! operator <1>: Egrep Program. (line 170)
+* ! (exclamation point), ! operator: Boolean Ops. (line 69)
+* ! (exclamation point), ! operator <1>: Egrep Program. (line 175)
* ! (exclamation point), ! operator <2>: Ranges. (line 48)
* ! (exclamation point), ! operator: Precedence. (line 52)
* ! (exclamation point), != operator <1>: Precedence. (line 65)
@@ -24664,163 +31406,170 @@ Index
* ! (exclamation point), !~ operator <3>: Comparison Operators.
(line 11)
* ! (exclamation point), !~ operator <4>: Regexp Constants. (line 6)
-* ! (exclamation point), !~ operator <5>: Computed Regexps. (line 6)
-* ! (exclamation point), !~ operator <6>: Case-sensitivity. (line 26)
+* ! (exclamation point), !~ operator <5>: Case-sensitivity. (line 26)
+* ! (exclamation point), !~ operator <6>: Computed Regexps. (line 6)
* ! (exclamation point), !~ operator: Regexp Usage. (line 19)
-* " (double quote) <1>: Quoting. (line 37)
-* " (double quote): Read Terminal. (line 25)
-* " (double quote), regexp constants: Computed Regexps. (line 28)
+* " (double quote), in regexp constants: Computed Regexps. (line 29)
+* " (double quote), in shell commands: Quoting. (line 54)
* # (number sign), #! (executable scripts): Executable Scripts.
(line 6)
-* # (number sign), #! (executable scripts), portability issues with: Executable Scripts.
- (line 6)
* # (number sign), commenting: Comments. (line 6)
-* $ (dollar sign): Regexp Operators. (line 35)
* $ (dollar sign), $ field operator <1>: Precedence. (line 43)
* $ (dollar sign), $ field operator: Fields. (line 19)
* $ (dollar sign), incrementing fields and arrays: Increment Ops.
(line 30)
+* $ (dollar sign), regexp operator: Regexp Operators. (line 35)
* % (percent sign), % operator: Precedence. (line 55)
* % (percent sign), %= operator <1>: Precedence. (line 95)
-* % (percent sign), %= operator: Assignment Ops. (line 129)
+* % (percent sign), %= operator: Assignment Ops. (line 130)
* & (ampersand), && operator <1>: Precedence. (line 86)
-* & (ampersand), && operator: Boolean Ops. (line 57)
+* & (ampersand), && operator: Boolean Ops. (line 59)
* & (ampersand), gsub()/gensub()/sub() functions and: Gory Details.
(line 6)
-* ' (single quote) <1>: Quoting. (line 31)
-* ' (single quote) <2>: Long. (line 33)
* ' (single quote): One-shot. (line 15)
+* ' (single quote) in gawk command lines: Long. (line 35)
+* ' (single quote), in shell commands: Quoting. (line 48)
* ' (single quote), vs. apostrophe: Comments. (line 27)
-* ' (single quote), with double quotes: Quoting. (line 53)
-* () (parentheses): Regexp Operators. (line 79)
-* () (parentheses), pgawk program: Profiling. (line 141)
+* ' (single quote), with double quotes: Quoting. (line 73)
+* () (parentheses), in a profile: Profiling. (line 146)
+* () (parentheses), regexp operator: Regexp Operators. (line 81)
* * (asterisk), * operator, as multiplication operator: Precedence.
(line 55)
* * (asterisk), * operator, as regexp operator: Regexp Operators.
- (line 87)
-* * (asterisk), * operator, null strings, matching: Gory Details.
- (line 163)
+ (line 89)
+* * (asterisk), * operator, null strings, matching: String Functions.
+ (line 536)
* * (asterisk), ** operator <1>: Precedence. (line 49)
* * (asterisk), ** operator: Arithmetic Ops. (line 81)
* * (asterisk), **= operator <1>: Precedence. (line 95)
-* * (asterisk), **= operator: Assignment Ops. (line 129)
+* * (asterisk), **= operator: Assignment Ops. (line 130)
* * (asterisk), *= operator <1>: Precedence. (line 95)
-* * (asterisk), *= operator: Assignment Ops. (line 129)
-* + (plus sign): Regexp Operators. (line 102)
+* * (asterisk), *= operator: Assignment Ops. (line 130)
* + (plus sign), + operator: Precedence. (line 52)
-* + (plus sign), ++ (decrement/increment operators): Increment Ops.
- (line 11)
* + (plus sign), ++ operator <1>: Precedence. (line 46)
-* + (plus sign), ++ operator: Increment Ops. (line 40)
+* + (plus sign), ++ operator: Increment Ops. (line 11)
* + (plus sign), += operator <1>: Precedence. (line 95)
* + (plus sign), += operator: Assignment Ops. (line 82)
+* + (plus sign), regexp operator: Regexp Operators. (line 105)
* , (comma), in range patterns: Ranges. (line 6)
* - (hyphen), - operator: Precedence. (line 52)
-* - (hyphen), -- (decrement/increment) operator: Precedence. (line 46)
+* - (hyphen), -- operator <1>: Precedence. (line 46)
* - (hyphen), -- operator: Increment Ops. (line 48)
* - (hyphen), -= operator <1>: Precedence. (line 95)
-* - (hyphen), -= operator: Assignment Ops. (line 129)
+* - (hyphen), -= operator: Assignment Ops. (line 130)
* - (hyphen), filenames beginning with: Options. (line 59)
* - (hyphen), in bracket expressions: Bracket Expressions. (line 17)
* --assign option: Options. (line 32)
-* --c option: Options. (line 78)
+* --bignum option: Options. (line 205)
* --characters-as-bytes option: Options. (line 68)
-* --command option: Options. (line 231)
-* --copyright option: Options. (line 85)
-* --disable-lint configuration option: Additional Configuration Options.
+* --copyright option: Options. (line 88)
+* --debug option: Options. (line 108)
+* --disable-extensions configuration option: Additional Configuration Options.
(line 9)
+* --disable-lint configuration option: Additional Configuration Options.
+ (line 15)
* --disable-nls configuration option: Additional Configuration Options.
- (line 24)
-* --dump-variables option <1>: Library Names. (line 45)
-* --dump-variables option: Options. (line 90)
-* --exec option: Options. (line 113)
+ (line 30)
+* --dump-variables option: Options. (line 93)
+* --dump-variables option, using for library functions: Library Names.
+ (line 45)
+* --exec option: Options. (line 125)
* --field-separator option: Options. (line 21)
* --file option: Options. (line 25)
* --gen-pot option <1>: String Extraction. (line 6)
-* --gen-pot option: Options. (line 135)
-* --help option: Options. (line 142)
-* --L option: Options. (line 245)
-* --lint option <1>: Options. (line 147)
+* --gen-pot option: Options. (line 147)
+* --help option: Options. (line 154)
+* --include option: Options. (line 159)
+* --lint option <1>: Options. (line 185)
* --lint option: Command Line. (line 20)
-* --lint-old option: Options. (line 245)
+* --lint-old option: Options. (line 295)
+* --load option: Options. (line 173)
* --non-decimal-data option <1>: Nondecimal Data. (line 6)
-* --non-decimal-data option: Options. (line 166)
+* --non-decimal-data option: Options. (line 211)
* --non-decimal-data option, strtonum() function and: Nondecimal Data.
- (line 36)
-* --optimize option: Options. (line 179)
-* --posix option: Options. (line 199)
-* --posix option, --traditional option and: Options. (line 218)
-* --profile option <1>: Profiling. (line 15)
-* --profile option: Options. (line 186)
-* --re-interval option: Options. (line 224)
-* --sandbox option: Options. (line 236)
+ (line 35)
+* --optimize option: Options. (line 236)
+* --posix option: Options. (line 254)
+* --posix option, --traditional option and: Options. (line 273)
+* --pretty-print option: Options. (line 225)
+* --profile option <1>: Profiling. (line 12)
+* --profile option: Options. (line 242)
+* --re-interval option: Options. (line 279)
+* --sandbox option: Options. (line 286)
* --sandbox option, disabling system() function: I/O Functions.
- (line 85)
+ (line 128)
* --sandbox option, input redirection with getline: Getline. (line 19)
* --sandbox option, output redirection with print, printf: Redirection.
(line 6)
-* --source option: Options. (line 105)
-* --traditional option: Options. (line 78)
-* --traditional option, --posix option and: Options. (line 218)
-* --use-lc-numeric option: Options. (line 174)
-* --version option: Options. (line 250)
+* --source option: Options. (line 117)
+* --traditional option: Options. (line 81)
+* --traditional option, --posix option and: Options. (line 273)
+* --use-lc-numeric option: Options. (line 220)
+* --version option: Options. (line 300)
* --with-whiny-user-strftime configuration option: Additional Configuration Options.
- (line 29)
+ (line 35)
* -b option: Options. (line 68)
-* -C option: Options. (line 85)
-* -d option: Options. (line 90)
-* -E option: Options. (line 113)
-* -e option: Options. (line 105)
-* -F option: Command Line Field Separator.
- (line 6)
+* -C option: Options. (line 88)
+* -c option: Options. (line 81)
+* -D option: Options. (line 108)
+* -d option: Options. (line 93)
+* -e option: Options. (line 336)
+* -E option: Options. (line 125)
+* -e option: Options. (line 117)
* -f option: Options. (line 25)
* -F option: Options. (line 21)
* -f option: Long. (line 12)
-* -F option, -Ft sets FS to TAB: Options. (line 258)
-* -f option, on command line: Options. (line 263)
-* -g option: Options. (line 135)
-* -h option: Options. (line 142)
-* -l option: Options. (line 147)
-* -N option: Options. (line 174)
-* -n option: Options. (line 166)
-* -O option: Options. (line 179)
-* -P option: Options. (line 199)
-* -p option: Options. (line 186)
-* -R option: Options. (line 231)
-* -r option: Options. (line 224)
-* -S option: Options. (line 236)
-* -V option: Options. (line 250)
+* -F option, -Ft sets FS to TAB: Options. (line 308)
+* -F option, command-line: Command Line Field Separator.
+ (line 6)
+* -f option, multiple uses: Options. (line 313)
+* -g option: Options. (line 147)
+* -h option: Options. (line 154)
+* -i option: Options. (line 159)
+* -L option: Options. (line 295)
+* -l option: Options. (line 173)
+* -M option: Options. (line 205)
+* -N option: Options. (line 220)
+* -n option: Options. (line 211)
+* -O option: Options. (line 236)
+* -o option: Options. (line 225)
+* -P option: Options. (line 254)
+* -p option: Options. (line 242)
+* -r option: Options. (line 279)
+* -S option: Options. (line 286)
+* -v option: Assignment Options. (line 12)
+* -V option: Options. (line 300)
* -v option: Options. (line 32)
-* -v option, variables, assigning: Assignment Options. (line 12)
* -W option: Options. (line 46)
-* . (period): Regexp Operators. (line 43)
-* .mo files: Explaining gettext. (line 41)
-* .mo files, converting from .po: I18N Example. (line 62)
-* .mo files, specifying directory of <1>: Programmer i18n. (line 47)
-* .mo files, specifying directory of: Explaining gettext. (line 53)
+* . (period), regexp operator: Regexp Operators. (line 44)
+* .gmo files: Explaining gettext. (line 42)
+* .gmo files, specifying directory of <1>: Programmer i18n. (line 47)
+* .gmo files, specifying directory of: Explaining gettext. (line 54)
+* .mo files, converting from .po: I18N Example. (line 64)
* .po files <1>: Translator i18n. (line 6)
-* .po files: Explaining gettext. (line 36)
-* .po files, converting to .mo: I18N Example. (line 62)
-* .pot files: Explaining gettext. (line 30)
-* / (forward slash): Regexp. (line 10)
+* .po files: Explaining gettext. (line 37)
+* .po files, converting to .mo: I18N Example. (line 64)
+* .pot files: Explaining gettext. (line 31)
+* / (forward slash) to enclose regular expressions: Regexp. (line 10)
* / (forward slash), / operator: Precedence. (line 55)
* / (forward slash), /= operator <1>: Precedence. (line 95)
-* / (forward slash), /= operator: Assignment Ops. (line 129)
+* / (forward slash), /= operator: Assignment Ops. (line 130)
* / (forward slash), /= operator, vs. /=.../ regexp constant: Assignment Ops.
(line 148)
* / (forward slash), patterns and: Expression Patterns. (line 24)
* /= operator vs. /=.../ regexp constant: Assignment Ops. (line 148)
-* /dev/... special files (gawk): Special FD. (line 46)
-* /dev/fd/N special files: Special FD. (line 46)
+* /dev/... special files: Special FD. (line 48)
+* /dev/fd/N special files (gawk): Special FD. (line 48)
* /inet/... special files (gawk): TCP/IP Networking. (line 6)
* /inet4/... special files (gawk): TCP/IP Networking. (line 6)
* /inet6/... special files (gawk): TCP/IP Networking. (line 6)
-* ; (semicolon): Statements/Lines. (line 91)
-* ; (semicolon), AWKPATH variable and: PC Using. (line 11)
+* ; (semicolon), AWKPATH variable and: PC Using. (line 10)
* ; (semicolon), separating statements in actions <1>: Statements.
(line 10)
-* ; (semicolon), separating statements in actions: Action Overview.
+* ; (semicolon), separating statements in actions <2>: Action Overview.
(line 19)
+* ; (semicolon), separating statements in actions: Statements/Lines.
+ (line 91)
* < (left angle bracket), < operator <1>: Precedence. (line 65)
* < (left angle bracket), < operator: Comparison Operators.
(line 11)
@@ -24841,19 +31590,20 @@ Index
(line 11)
* > (right angle bracket), >> operator (I/O) <1>: Precedence. (line 65)
* > (right angle bracket), >> operator (I/O): Redirection. (line 50)
-* ? (question mark) regexp operator <1>: GNU Regexp Operators.
- (line 59)
-* ? (question mark) regexp operator: Regexp Operators. (line 111)
* ? (question mark), ?: operator: Precedence. (line 92)
-* [] (square brackets): Regexp Operators. (line 55)
-* \ (backslash) <1>: Regexp Operators. (line 18)
-* \ (backslash) <2>: Quoting. (line 31)
-* \ (backslash) <3>: Comments. (line 50)
-* \ (backslash): Read Terminal. (line 25)
-* \ (backslash), \" escape sequence: Escape Sequences. (line 76)
+* ? (question mark), regexp operator <1>: GNU Regexp Operators.
+ (line 59)
+* ? (question mark), regexp operator: Regexp Operators. (line 111)
+* @-notation for indirect function calls: Indirect Calls. (line 47)
+* @include directive: Include Files. (line 8)
+* @load directive: Loading Shared Libraries.
+ (line 8)
+* [] (square brackets), regexp operator: Regexp Operators. (line 56)
+* \ (backslash): Comments. (line 50)
+* \ (backslash), \" escape sequence: Escape Sequences. (line 85)
* \ (backslash), \' operator (gawk): GNU Regexp Operators.
(line 56)
-* \ (backslash), \/ escape sequence: Escape Sequences. (line 69)
+* \ (backslash), \/ escape sequence: Escape Sequences. (line 76)
* \ (backslash), \< operator (gawk): GNU Regexp Operators.
(line 30)
* \ (backslash), \> operator (gawk): GNU Regexp Operators.
@@ -24881,9 +31631,8 @@ Index
* \ (backslash), \x escape sequence: Escape Sequences. (line 61)
* \ (backslash), \y operator (gawk): GNU Regexp Operators.
(line 38)
-* \ (backslash), as field separators: Command Line Field Separator.
- (line 27)
-* \ (backslash), continuing lines and <1>: Egrep Program. (line 220)
+* \ (backslash), as field separator: Command Line Field Separator.
+ (line 24)
* \ (backslash), continuing lines and: Statements/Lines. (line 19)
* \ (backslash), continuing lines and, comments and: Statements/Lines.
(line 76)
@@ -24894,162 +31643,179 @@ Index
* \ (backslash), in bracket expressions: Bracket Expressions. (line 17)
* \ (backslash), in escape sequences: Escape Sequences. (line 6)
* \ (backslash), in escape sequences, POSIX and: Escape Sequences.
- (line 113)
-* \ (backslash), regexp constants: Computed Regexps. (line 28)
-* ^ (caret) <1>: GNU Regexp Operators.
- (line 59)
-* ^ (caret): Regexp Operators. (line 22)
+ (line 108)
+* \ (backslash), in regexp constants: Computed Regexps. (line 29)
+* \ (backslash), in shell commands: Quoting. (line 48)
+* \ (backslash), regexp operator: Regexp Operators. (line 18)
* ^ (caret), ^ operator: Precedence. (line 49)
* ^ (caret), ^= operator <1>: Precedence. (line 95)
-* ^ (caret), ^= operator: Assignment Ops. (line 129)
+* ^ (caret), ^= operator: Assignment Ops. (line 130)
* ^ (caret), in bracket expressions: Bracket Expressions. (line 17)
-* ^, in FS: Regexp Field Splitting.
+* ^ (caret), in FS: Regexp Field Splitting.
+ (line 59)
+* ^ (caret), regexp operator <1>: GNU Regexp Operators.
(line 59)
-* _ (underscore), _ C macro: Explaining gettext. (line 70)
+* ^ (caret), regexp operator: Regexp Operators. (line 22)
+* _ (underscore), C macro: Explaining gettext. (line 71)
* _ (underscore), in names of private variables: Library Names.
(line 29)
* _ (underscore), translatable string: Programmer i18n. (line 69)
-* _gr_init() user-defined function: Group Functions. (line 82)
+* _gr_init() user-defined function: Group Functions. (line 83)
+* _ord_init() user-defined function: Ordinal Functions. (line 16)
* _pw_init() user-defined function: Passwd Functions. (line 105)
* accessing fields: Fields. (line 6)
+* accessing global variables from extensions: Symbol Table Access.
+ (line 6)
* account information <1>: Group Functions. (line 6)
* account information: Passwd Functions. (line 16)
* actions: Action Overview. (line 6)
* actions, control statements in: Statements. (line 6)
* actions, default: Very Simple. (line 34)
* actions, empty: Very Simple. (line 39)
-* Ada programming language: Glossary. (line 20)
+* Ada programming language: Glossary. (line 11)
* adding, features to gawk: Adding Code. (line 6)
* adding, fields: Changing Fields. (line 53)
-* adding, functions to gawk: Dynamic Extensions. (line 10)
-* advanced features, buffering: I/O Functions. (line 98)
-* advanced features, close() function: Close Files And Pipes.
- (line 131)
-* advanced features, constants, values of: Nondecimal-numbers.
- (line 67)
-* advanced features, data files as single record: Records. (line 175)
-* advanced features, fixed-width data: Constant Size. (line 9)
-* advanced features, FNR/NR variables: Auto-set. (line 207)
+* advanced features, fixed-width data: Constant Size. (line 6)
* advanced features, gawk: Advanced Features. (line 6)
-* advanced features, gawk, network programming: TCP/IP Networking.
- (line 6)
-* advanced features, gawk, nondecimal input data: Nondecimal Data.
+* advanced features, network programming: TCP/IP Networking. (line 6)
+* advanced features, nondecimal input data: Nondecimal Data. (line 6)
+* advanced features, processes, communicating with: Two-way I/O.
(line 6)
-* advanced features, gawk, processes, communicating with: Two-way I/O.
- (line 23)
-* advanced features, network connections, See Also networks, connections: Advanced Features.
- (line 6)
-* advanced features, null strings, matching: Gory Details. (line 163)
-* advanced features, operators, precedence: Increment Ops. (line 61)
-* advanced features, piping into sh: Redirection. (line 143)
-* advanced features, regexp constants: Assignment Ops. (line 148)
* advanced features, specifying field content: Splitting By Content.
(line 9)
-* Aho, Alfred <1>: Contributors. (line 12)
+* Aho, Alfred <1>: Contributors. (line 11)
* Aho, Alfred: History. (line 17)
-* alarm clock example program: Alarm Program. (line 9)
-* alarm.awk program: Alarm Program. (line 29)
-* algorithms: Basic High Level. (line 66)
-* Alpha (DEC): Manual History. (line 28)
-* amazing awk assembler (aaa): Glossary. (line 12)
-* amazingly workable formatter (awf): Glossary. (line 25)
+* alarm clock example program: Alarm Program. (line 11)
+* alarm.awk program: Alarm Program. (line 31)
+* algorithms: Basic High Level. (line 68)
+* allocating memory for extensions: Memory Allocation Functions.
+ (line 6)
+* amazing awk assembler (aaa): Glossary. (line 16)
+* amazingly workable formatter (awf): Glossary. (line 24)
* ambiguity, syntactic: /= operator vs. /=.../ regexp constant: Assignment Ops.
(line 148)
* ampersand (&), && operator <1>: Precedence. (line 86)
-* ampersand (&), && operator: Boolean Ops. (line 57)
+* ampersand (&), && operator: Boolean Ops. (line 59)
* ampersand (&), gsub()/gensub()/sub() functions and: Gory Details.
(line 6)
-* anagram.awk program: Anagram Program. (line 22)
+* anagram.awk program: Anagram Program. (line 21)
+* anagrams, finding: Anagram Program. (line 6)
+* and: Bitwise Functions. (line 40)
* AND bitwise operation: Bitwise Functions. (line 6)
* and Boolean-logic operator: Boolean Ops. (line 6)
-* and() function (gawk): Bitwise Functions. (line 39)
-* ANSI: Glossary. (line 35)
-* archeologists: Bugs. (line 6)
-* ARGC/ARGV variables <1>: ARGC and ARGV. (line 6)
-* ARGC/ARGV variables: Auto-set. (line 11)
+* ANSI: Glossary. (line 34)
+* API informational variables: Extension API Informational Variables.
+ (line 6)
+* API version: Extension Versioning.
+ (line 6)
+* arbitrary precision: Arbitrary Precision Arithmetic.
+ (line 6)
+* arbitrary precision integers: Arbitrary Precision Integers.
+ (line 6)
+* archaeologists: Bugs. (line 6)
+* arctangent: Numeric Functions. (line 11)
+* ARGC/ARGV variables: Auto-set. (line 15)
* ARGC/ARGV variables, command-line arguments: Other Arguments.
- (line 12)
-* ARGC/ARGV variables, portability and: Executable Scripts. (line 43)
-* ARGIND variable: Auto-set. (line 40)
-* ARGIND variable, command-line arguments: Other Arguments. (line 12)
+ (line 15)
+* ARGC/ARGV variables, how to use: ARGC and ARGV. (line 6)
+* ARGC/ARGV variables, portability and: Executable Scripts. (line 59)
+* ARGIND variable: Auto-set. (line 44)
+* ARGIND variable, command-line arguments: Other Arguments. (line 15)
* arguments, command-line <1>: ARGC and ARGV. (line 6)
-* arguments, command-line <2>: Auto-set. (line 11)
+* arguments, command-line <2>: Auto-set. (line 15)
* arguments, command-line: Other Arguments. (line 6)
* arguments, command-line, invoking awk: Command Line. (line 6)
-* arguments, in function calls: Function Calls. (line 16)
+* arguments, in function calls: Function Calls. (line 18)
* arguments, processing: Getopt Function. (line 6)
-* arguments, retrieving: Internals. (line 111)
+* ARGV array, indexing into: Other Arguments. (line 15)
* arithmetic operators: Arithmetic Ops. (line 6)
+* array manipulation in extensions: Array Manipulation. (line 6)
+* array members: Reference to Elements.
+ (line 6)
+* array scanning order, controlling: Controlling Scanning.
+ (line 14)
+* array, number of elements: String Functions. (line 201)
* arrays: Arrays. (line 6)
+* arrays of arrays: Arrays of Arrays. (line 6)
+* arrays, an example of using: Array Example. (line 6)
+* arrays, and IGNORECASE variable: Array Intro. (line 94)
* arrays, as parameters to functions: Pass By Value/Reference.
- (line 47)
+ (line 44)
* arrays, associative: Array Intro. (line 50)
-* arrays, associative, clearing: Internals. (line 68)
-* arrays, associative, library functions and: Library Names. (line 57)
+* arrays, associative, library functions and: Library Names. (line 58)
* arrays, deleting entire contents: Delete. (line 39)
-* arrays, elements, assigning: Assigning Elements. (line 6)
+* arrays, elements that don't exist: Reference to Elements.
+ (line 23)
+* arrays, elements, assigning values: Assigning Elements. (line 6)
* arrays, elements, deleting: Delete. (line 6)
-* arrays, elements, installing: Internals. (line 72)
-* arrays, elements, order of: Scanning an Array. (line 48)
-* arrays, elements, referencing: Reference to Elements.
- (line 6)
-* arrays, elements, retrieving number of: String Functions. (line 29)
+* arrays, elements, order of access by in operator: Scanning an Array.
+ (line 48)
+* arrays, elements, retrieving number of: String Functions. (line 42)
* arrays, for statement and: Scanning an Array. (line 20)
-* arrays, IGNORECASE variable and: Array Intro. (line 92)
* arrays, indexing: Array Intro. (line 50)
* arrays, merging into strings: Join Function. (line 6)
-* arrays, multidimensional: Multi-dimensional. (line 10)
-* arrays, multidimensional, scanning: Multi-scanning. (line 11)
-* arrays, names of: Arrays. (line 18)
+* arrays, multidimensional: Multidimensional. (line 10)
+* arrays, multidimensional, scanning: Multiscanning. (line 11)
+* arrays, numeric subscripts: Numeric Array Subscripts.
+ (line 6)
+* arrays, referencing elements: Reference to Elements.
+ (line 6)
* arrays, scanning: Scanning an Array. (line 6)
* arrays, sorting: Array Sorting Functions.
(line 6)
-* arrays, sorting, IGNORECASE variable and: Array Sorting Functions.
- (line 78)
-* arrays, sparse: Array Intro. (line 71)
-* arrays, subscripts: Numeric Array Subscripts.
- (line 6)
+* arrays, sorting, and IGNORECASE variable: Array Sorting Functions.
+ (line 83)
+* arrays, sparse: Array Intro. (line 72)
* arrays, subscripts, uninitialized variables as: Uninitialized Subscripts.
(line 6)
+* arrays, unassigned elements: Reference to Elements.
+ (line 18)
* artificial intelligence, gawk and: Distribution contents.
- (line 55)
-* ASCII <1>: Glossary. (line 141)
+ (line 52)
+* ASCII <1>: Glossary. (line 133)
* ASCII: Ordinal Functions. (line 45)
-* asort() function (gawk) <1>: Array Sorting Functions.
+* asort <1>: Array Sorting Functions.
(line 6)
-* asort() function (gawk): String Functions. (line 29)
+* asort: String Functions. (line 42)
* asort() function (gawk), arrays, sorting: Array Sorting Functions.
(line 6)
-* asorti() function (gawk): String Functions. (line 77)
+* asorti <1>: Array Sorting Functions.
+ (line 6)
+* asorti: String Functions. (line 42)
+* asorti() function (gawk), arrays, sorting: Array Sorting Functions.
+ (line 6)
* assert() function (C library): Assert Function. (line 6)
* assert() user-defined function: Assert Function. (line 28)
* assertions: Assert Function. (line 6)
+* assign values to variables, in debugger: Viewing And Changing Data.
+ (line 59)
* assignment operators: Assignment Ops. (line 6)
* assignment operators, evaluation order: Assignment Ops. (line 111)
* assignment operators, lvalues/rvalues: Assignment Ops. (line 32)
* assignments as filenames: Ignoring Assigns. (line 6)
-* assoc_clear() internal function: Internals. (line 68)
-* assoc_lookup() internal function: Internals. (line 72)
* associative arrays: Array Intro. (line 50)
* asterisk (*), * operator, as multiplication operator: Precedence.
(line 55)
* asterisk (*), * operator, as regexp operator: Regexp Operators.
- (line 87)
-* asterisk (*), * operator, null strings, matching: Gory Details.
- (line 163)
+ (line 89)
+* asterisk (*), * operator, null strings, matching: String Functions.
+ (line 536)
* asterisk (*), ** operator <1>: Precedence. (line 49)
* asterisk (*), ** operator: Arithmetic Ops. (line 81)
* asterisk (*), **= operator <1>: Precedence. (line 95)
-* asterisk (*), **= operator: Assignment Ops. (line 129)
+* asterisk (*), **= operator: Assignment Ops. (line 130)
* asterisk (*), *= operator <1>: Precedence. (line 95)
-* asterisk (*), *= operator: Assignment Ops. (line 129)
-* atan2() function: Numeric Functions. (line 11)
-* awf (amazingly workable formatter) program: Glossary. (line 25)
-* awk language, POSIX version: Assignment Ops. (line 136)
+* asterisk (*), *= operator: Assignment Ops. (line 130)
+* atan2: Numeric Functions. (line 11)
+* automatic displays, in debugger: Debugger Info. (line 24)
+* awf (amazingly workable formatter) program: Glossary. (line 24)
+* awk debugging, enabling: Options. (line 108)
+* awk language, POSIX version: Assignment Ops. (line 137)
+* awk profiling, enabling: Options. (line 242)
* awk programs <1>: Two Rules. (line 6)
* awk programs <2>: Executable Scripts. (line 6)
* awk programs: Getting Started. (line 12)
-* awk programs, complex: When. (line 29)
+* awk programs, complex: When. (line 27)
* awk programs, documenting <1>: Library Names. (line 6)
* awk programs, documenting: Comments. (line 6)
* awk programs, examples of: Sample Programs. (line 6)
@@ -25061,7 +31827,6 @@ Index
* awk programs, location of: Options. (line 25)
* awk programs, one-line examples: Very Simple. (line 45)
* awk programs, profiling: Profiling. (line 6)
-* awk programs, profiling, enabling: Options. (line 186)
* awk programs, running <1>: Long. (line 6)
* awk programs, running: Running gawk. (line 6)
* awk programs, running, from shell scripts: One-shot. (line 22)
@@ -25070,25 +31835,24 @@ Index
(line 6)
* awk, function of: Getting Started. (line 6)
* awk, gawk and <1>: This Manual. (line 14)
-* awk, gawk and: Preface. (line 23)
+* awk, gawk and: Preface. (line 21)
* awk, history of: History. (line 17)
-* awk, implementation issues, pipes: Redirection. (line 135)
+* awk, implementation issues, pipes: Redirection. (line 129)
* awk, implementations: Other Versions. (line 6)
* awk, implementations, limits: Getline Notes. (line 14)
* awk, invoking: Command Line. (line 6)
* awk, new vs. old: Names. (line 6)
-* awk, new vs. old, OFMT variable: Conversion. (line 55)
-* awk, POSIX and: Preface. (line 23)
-* awk, POSIX and, See Also POSIX awk: Preface. (line 23)
+* awk, new vs. old, OFMT variable: Strings And Numbers. (line 57)
+* awk, POSIX and: Preface. (line 21)
+* awk, POSIX and, See Also POSIX awk: Preface. (line 21)
* awk, regexp constants and: Comparison Operators.
(line 103)
-* awk, See Also gawk: Preface. (line 36)
+* awk, See Also gawk: Preface. (line 34)
* awk, terms describing: This Manual. (line 6)
* awk, uses for <1>: When. (line 6)
* awk, uses for <2>: Getting Started. (line 12)
-* awk, uses for: Preface. (line 23)
-* awk, versions of <1>: V7/SVR3.1. (line 6)
-* awk, versions of: Names. (line 10)
+* awk, uses for: Preface. (line 21)
+* awk, versions of: V7/SVR3.1. (line 6)
* awk, versions of, changes between SVR3.1 and SVR4: SVR4. (line 6)
* awk, versions of, changes between SVR4 and POSIX awk: POSIX.
(line 6)
@@ -25096,23 +31860,19 @@ Index
* awk, versions of, See Also Brian Kernighan's awk <1>: Other Versions.
(line 13)
* awk, versions of, See Also Brian Kernighan's awk: BTL. (line 6)
-* awk.h file (internal): Internals. (line 15)
-* awka compiler for awk: Other Versions. (line 55)
-* AWKNUM internal type: Internals. (line 19)
-* AWKPATH environment variable <1>: PC Using. (line 11)
+* awka compiler for awk: Other Versions. (line 68)
+* AWKLIBPATH environment variable: AWKLIBPATH Variable. (line 6)
+* AWKPATH environment variable <1>: PC Using. (line 10)
* AWKPATH environment variable: AWKPATH Variable. (line 6)
-* awkprof.out file: Profiling. (line 10)
+* awkprof.out file: Profiling. (line 6)
* awksed.awk program: Simple Sed. (line 25)
-* awkvars.out file: Options. (line 90)
+* awkvars.out file: Options. (line 93)
* b debugger command (alias for break): Breakpoint Control. (line 11)
-* backslash (\) <1>: Regexp Operators. (line 18)
-* backslash (\) <2>: Quoting. (line 31)
-* backslash (\) <3>: Comments. (line 50)
-* backslash (\): Read Terminal. (line 25)
-* backslash (\), \" escape sequence: Escape Sequences. (line 76)
+* backslash (\): Comments. (line 50)
+* backslash (\), \" escape sequence: Escape Sequences. (line 85)
* backslash (\), \' operator (gawk): GNU Regexp Operators.
(line 56)
-* backslash (\), \/ escape sequence: Escape Sequences. (line 69)
+* backslash (\), \/ escape sequence: Escape Sequences. (line 76)
* backslash (\), \< operator (gawk): GNU Regexp Operators.
(line 30)
* backslash (\), \> operator (gawk): GNU Regexp Operators.
@@ -25140,9 +31900,8 @@ Index
* backslash (\), \x escape sequence: Escape Sequences. (line 61)
* backslash (\), \y operator (gawk): GNU Regexp Operators.
(line 38)
-* backslash (\), as field separators: Command Line Field Separator.
- (line 27)
-* backslash (\), continuing lines and <1>: Egrep Program. (line 220)
+* backslash (\), as field separator: Command Line Field Separator.
+ (line 24)
* backslash (\), continuing lines and: Statements/Lines. (line 19)
* backslash (\), continuing lines and, comments and: Statements/Lines.
(line 76)
@@ -25153,198 +31912,238 @@ Index
* backslash (\), in bracket expressions: Bracket Expressions. (line 17)
* backslash (\), in escape sequences: Escape Sequences. (line 6)
* backslash (\), in escape sequences, POSIX and: Escape Sequences.
- (line 113)
-* backslash (\), regexp constants: Computed Regexps. (line 28)
-* backtrace debugger command: Dgawk Stack. (line 13)
-* BBS-list file: Sample Data Files. (line 6)
-* Beebe, Nelson <1>: Other Versions. (line 69)
-* Beebe, Nelson: Acknowledgments. (line 60)
-* BEGIN pattern <1>: BEGIN/END. (line 6)
-* BEGIN pattern <2>: Field Separators. (line 44)
-* BEGIN pattern: Records. (line 29)
+ (line 108)
+* backslash (\), in regexp constants: Computed Regexps. (line 29)
+* backslash (\), in shell commands: Quoting. (line 48)
+* backslash (\), regexp operator: Regexp Operators. (line 18)
+* backtrace debugger command: Execution Stack. (line 13)
+* Beebe, Nelson H.F. <1>: Other Versions. (line 82)
+* Beebe, Nelson H.F.: Acknowledgments. (line 60)
+* BEGIN pattern <1>: Using BEGIN/END. (line 6)
+* BEGIN pattern <2>: BEGIN/END. (line 6)
+* BEGIN pattern: Field Separators. (line 45)
+* BEGIN pattern, and profiling: Profiling. (line 62)
* BEGIN pattern, assert() user-defined function and: Assert Function.
(line 83)
-* BEGIN pattern, Boolean patterns and: Expression Patterns. (line 73)
+* BEGIN pattern, Boolean patterns and: Expression Patterns. (line 69)
* BEGIN pattern, exit statement and: Exit Statement. (line 12)
* BEGIN pattern, getline and: Getline Notes. (line 19)
* BEGIN pattern, headings, adding: Print Examples. (line 43)
* BEGIN pattern, next/nextfile statements and <1>: Next Statement.
- (line 45)
+ (line 44)
* BEGIN pattern, next/nextfile statements and: I/O And BEGIN/END.
(line 37)
* BEGIN pattern, OFS/ORS variables, assigning values to: Output Separators.
- (line 20)
+ (line 21)
* BEGIN pattern, operators and: Using BEGIN/END. (line 17)
-* BEGIN pattern, pgawk program: Profiling. (line 65)
* BEGIN pattern, print statement and: I/O And BEGIN/END. (line 16)
* BEGIN pattern, pwcat program: Passwd Functions. (line 143)
-* BEGIN pattern, running awk programs and: Cut Program. (line 68)
+* BEGIN pattern, running awk programs and: Cut Program. (line 63)
* BEGIN pattern, TEXTDOMAIN variable and: Programmer i18n. (line 60)
* BEGINFILE pattern: BEGINFILE/ENDFILE. (line 6)
* BEGINFILE pattern, Boolean patterns and: Expression Patterns.
- (line 73)
-* beginfile() user-defined function: Filetrans Function. (line 62)
+ (line 69)
+* beginfile() user-defined function: Filetrans Function. (line 61)
+* Bentley, Jon: Glossary. (line 143)
* Benzinger, Michael: Contributors. (line 97)
+* Berry, Karl <1>: Ranges and Locales. (line 74)
* Berry, Karl: Acknowledgments. (line 33)
-* binary input/output: User-modified. (line 10)
-* bindtextdomain() function (C library): Explaining gettext. (line 49)
-* bindtextdomain() function (gawk) <1>: Programmer i18n. (line 47)
-* bindtextdomain() function (gawk): I18N Functions. (line 12)
+* binary input/output: User-modified. (line 15)
+* bindtextdomain <1>: Programmer i18n. (line 47)
+* bindtextdomain: I18N Functions. (line 12)
+* bindtextdomain() function (C library): Explaining gettext. (line 50)
* bindtextdomain() function (gawk), portability and: I18N Portability.
(line 33)
-* BINMODE variable <1>: PC Using. (line 34)
-* BINMODE variable: User-modified. (line 10)
-* bits2str() user-defined function: Bitwise Functions. (line 68)
+* BINMODE variable <1>: PC Using. (line 33)
+* BINMODE variable: User-modified. (line 15)
+* bit-manipulation functions: Bitwise Functions. (line 6)
+* bits2str() user-defined function: Bitwise Functions. (line 71)
+* bitwise AND: Bitwise Functions. (line 40)
+* bitwise complement: Bitwise Functions. (line 44)
+* bitwise OR: Bitwise Functions. (line 50)
+* bitwise XOR: Bitwise Functions. (line 56)
* bitwise, complement: Bitwise Functions. (line 25)
* bitwise, operations: Bitwise Functions. (line 6)
* bitwise, shift: Bitwise Functions. (line 32)
* body, in actions: Statements. (line 10)
* body, in loops: While Statement. (line 14)
* Boolean expressions: Boolean Ops. (line 6)
-* Boolean expressions, as patterns: Expression Patterns. (line 41)
+* Boolean expressions, as patterns: Expression Patterns. (line 38)
* Boolean operators, See Boolean expressions: Boolean Ops. (line 6)
* Bourne shell, quoting rules for: Quoting. (line 18)
+* braces ({}): Profiling. (line 142)
* braces ({}), actions and: Action Overview. (line 19)
-* braces ({}), pgawk program: Profiling. (line 137)
* braces ({}), statements, grouping: Statements. (line 10)
* bracket expressions <1>: Bracket Expressions. (line 6)
-* bracket expressions: Regexp Operators. (line 55)
+* bracket expressions: Regexp Operators. (line 56)
* bracket expressions, character classes: Bracket Expressions.
- (line 30)
+ (line 32)
* bracket expressions, collating elements: Bracket Expressions.
- (line 69)
+ (line 79)
* bracket expressions, collating symbols: Bracket Expressions.
- (line 76)
-* bracket expressions, complemented: Regexp Operators. (line 63)
+ (line 86)
+* bracket expressions, complemented: Regexp Operators. (line 64)
* bracket expressions, equivalence classes: Bracket Expressions.
- (line 82)
-* bracket expressions, non-ASCII: Bracket Expressions. (line 69)
+ (line 92)
+* bracket expressions, non-ASCII: Bracket Expressions. (line 79)
* bracket expressions, range expressions: Bracket Expressions.
(line 6)
* break debugger command: Breakpoint Control. (line 11)
* break statement: Break Statement. (line 6)
+* breakpoint: Debugging Terms. (line 33)
+* breakpoint at location, how to delete: Breakpoint Control. (line 36)
+* breakpoint commands: Debugger Execution Control.
+ (line 10)
+* breakpoint condition: Breakpoint Control. (line 54)
+* breakpoint, delete by number: Breakpoint Control. (line 64)
+* breakpoint, how to disable or enable: Breakpoint Control. (line 69)
+* breakpoint, setting: Breakpoint Control. (line 11)
* Brennan, Michael <1>: Other Versions. (line 6)
* Brennan, Michael <2>: Simple Sed. (line 25)
-* Brennan, Michael <3>: Two-way I/O. (line 6)
-* Brennan, Michael: Delete. (line 52)
-* Brian Kernighan's awk, extensions <1>: Other Versions. (line 13)
+* Brennan, Michael <3>: Delete. (line 56)
+* Brennan, Michael <4>: Acknowledgments. (line 78)
+* Brennan, Michael <5>: Foreword4. (line 33)
+* Brennan, Michael: Foreword3. (line 84)
+* Brian Kernighan's awk <1>: I/O Functions. (line 43)
+* Brian Kernighan's awk <2>: Gory Details. (line 19)
+* Brian Kernighan's awk <3>: String Functions. (line 492)
+* Brian Kernighan's awk <4>: Delete. (line 51)
+* Brian Kernighan's awk <5>: Nextfile Statement. (line 47)
+* Brian Kernighan's awk <6>: Continue Statement. (line 44)
+* Brian Kernighan's awk <7>: Break Statement. (line 51)
+* Brian Kernighan's awk <8>: I/O And BEGIN/END. (line 16)
+* Brian Kernighan's awk <9>: Concatenation. (line 36)
+* Brian Kernighan's awk <10>: Getline/Pipe. (line 62)
+* Brian Kernighan's awk <11>: Regexp Field Splitting.
+ (line 67)
+* Brian Kernighan's awk <12>: GNU Regexp Operators.
+ (line 82)
+* Brian Kernighan's awk <13>: Escape Sequences. (line 112)
+* Brian Kernighan's awk: When. (line 21)
* Brian Kernighan's awk, extensions: BTL. (line 6)
+* Brian Kernighan's awk, source code: Other Versions. (line 13)
+* Brini, Davide: Signature Program. (line 6)
+* Brink, Jeroen: DOS Quoting. (line 10)
* Broder, Alan J.: Contributors. (line 88)
* Brown, Martin: Contributors. (line 82)
* BSD-based operating systems: Glossary. (line 611)
-* bt debugger command (alias for backtrace): Dgawk Stack. (line 13)
-* Buening, Andreas <1>: Bugs. (line 71)
+* bt debugger command (alias for backtrace): Execution Stack. (line 13)
+* Buening, Andreas <1>: Bugs. (line 70)
* Buening, Andreas <2>: Contributors. (line 92)
* Buening, Andreas: Acknowledgments. (line 60)
-* buffering, input/output <1>: Two-way I/O. (line 70)
-* buffering, input/output: I/O Functions. (line 130)
-* buffering, interactive vs. noninteractive: I/O Functions. (line 98)
-* buffers, flushing: I/O Functions. (line 29)
+* buffering, input/output <1>: Two-way I/O. (line 52)
+* buffering, input/output: I/O Functions. (line 140)
+* buffering, interactive vs. noninteractive: I/O Functions. (line 75)
+* buffers, flushing: I/O Functions. (line 32)
* buffers, operators for: GNU Regexp Operators.
(line 48)
* bug reports, email address, bug-gawk@gnu.org: Bugs. (line 30)
* bug-gawk@gnu.org bug reporting address: Bugs. (line 30)
* built-in functions: Functions. (line 6)
* built-in functions, evaluation order: Calling Built-in. (line 30)
-* built-in variables: Built-in Variables. (line 6)
-* built-in variables, -v option, setting with: Options. (line 40)
-* built-in variables, conveying information: Auto-set. (line 6)
-* built-in variables, user-modifiable: User-modified. (line 6)
-* Busybox Awk: Other Versions. (line 78)
+* Busybox Awk: Other Versions. (line 92)
+* c.e., See common extensions: Conventions. (line 51)
* call by reference: Pass By Value/Reference.
- (line 47)
+ (line 44)
* call by value: Pass By Value/Reference.
- (line 18)
-* caret (^) <1>: GNU Regexp Operators.
- (line 59)
-* caret (^): Regexp Operators. (line 22)
+ (line 15)
+* call stack, display in debugger: Execution Stack. (line 13)
* caret (^), ^ operator: Precedence. (line 49)
* caret (^), ^= operator <1>: Precedence. (line 95)
-* caret (^), ^= operator: Assignment Ops. (line 129)
+* caret (^), ^= operator: Assignment Ops. (line 130)
* caret (^), in bracket expressions: Bracket Expressions. (line 17)
+* caret (^), regexp operator <1>: GNU Regexp Operators.
+ (line 59)
+* caret (^), regexp operator: Regexp Operators. (line 22)
* case keyword: Switch Statement. (line 6)
-* case sensitivity, array indices and: Array Intro. (line 92)
+* case sensitivity, and regexps: User-modified. (line 76)
+* case sensitivity, and string comparisons: User-modified. (line 76)
+* case sensitivity, array indices and: Array Intro. (line 94)
* case sensitivity, converting case: String Functions. (line 522)
-* case sensitivity, example programs: Library Functions. (line 42)
+* case sensitivity, example programs: Library Functions. (line 53)
* case sensitivity, gawk: Case-sensitivity. (line 26)
-* case sensitivity, regexps and <1>: User-modified. (line 82)
* case sensitivity, regexps and: Case-sensitivity. (line 6)
-* case sensitivity, string comparisons and: User-modified. (line 82)
-* CGI, awk scripts for: Options. (line 113)
-* character lists, See bracket expressions: Regexp Operators. (line 55)
-* character sets (machine character encodings) <1>: Glossary. (line 141)
+* CGI, awk scripts for: Options. (line 125)
+* character classes, See bracket expressions: Regexp Operators.
+ (line 56)
+* character lists in regular expression: Bracket Expressions. (line 6)
+* character lists, See bracket expressions: Regexp Operators. (line 56)
+* character sets (machine character encodings) <1>: Glossary. (line 133)
* character sets (machine character encodings): Ordinal Functions.
(line 45)
* character sets, See Also bracket expressions: Regexp Operators.
- (line 55)
+ (line 56)
* characters, counting: Wc Program. (line 6)
* characters, transliterating: Translate Program. (line 6)
* characters, values of as numbers: Ordinal Functions. (line 6)
* Chassell, Robert J.: Acknowledgments. (line 33)
-* chdir() function, implementing in gawk: Sample Library. (line 6)
-* chem utility: Glossary. (line 151)
+* chdir() extension function: Extension Sample File Functions.
+ (line 12)
+* chem utility: Glossary. (line 143)
+* chr() extension function: Extension Sample Ord.
+ (line 15)
* chr() user-defined function: Ordinal Functions. (line 16)
* clear debugger command: Breakpoint Control. (line 36)
* Cliff random numbers: Cliff Random Function.
(line 6)
* cliff_rand() user-defined function: Cliff Random Function.
(line 12)
-* close() function <1>: I/O Functions. (line 10)
-* close() function <2>: Close Files And Pipes.
+* close <1>: I/O Functions. (line 10)
+* close: Close Files And Pipes.
(line 18)
-* close() function <3>: Getline/Pipe. (line 24)
-* close() function: Getline/Variable/File.
- (line 30)
-* close() function, return values: Close Files And Pipes.
- (line 131)
-* close() function, two-way pipes and: Two-way I/O. (line 77)
-* Close, Diane <1>: Contributors. (line 21)
-* Close, Diane: Manual History. (line 41)
-* close_func() input method: Internals. (line 151)
-* collating elements: Bracket Expressions. (line 69)
-* collating symbols: Bracket Expressions. (line 76)
+* close file or coprocess: I/O Functions. (line 10)
+* close() function, portability: Close Files And Pipes.
+ (line 81)
+* close() function, return value: Close Files And Pipes.
+ (line 133)
+* close() function, two-way pipes and: Two-way I/O. (line 59)
+* Close, Diane <1>: Contributors. (line 20)
+* Close, Diane: Manual History. (line 34)
+* Collado, Manuel: Acknowledgments. (line 60)
+* collating elements: Bracket Expressions. (line 79)
+* collating symbols: Bracket Expressions. (line 86)
+* Colombo, Antonio <1>: Contributors. (line 140)
* Colombo, Antonio: Acknowledgments. (line 60)
* columns, aligning: Print Examples. (line 70)
* columns, cutting: Cut Program. (line 6)
* comma (,), in range patterns: Ranges. (line 6)
+* command completion, in debugger: Readline Support. (line 6)
* command line, arguments <1>: ARGC and ARGV. (line 6)
-* command line, arguments <2>: Auto-set. (line 11)
+* command line, arguments <2>: Auto-set. (line 15)
* command line, arguments: Other Arguments. (line 6)
-* command line, directories on: Command line directories.
+* command line, directories on: Command-line directories.
(line 6)
* command line, formats: Running gawk. (line 12)
* command line, FS on, setting: Command Line Field Separator.
(line 6)
* command line, invoking awk from: Command Line. (line 6)
-* command line, options <1>: Command Line Field Separator.
- (line 6)
-* command line, options <2>: Options. (line 6)
-* command line, options: Long. (line 12)
+* command line, option -f: Long. (line 12)
+* command line, options: Options. (line 6)
* command line, options, end of: Options. (line 54)
* command line, variables, assigning on: Assignment Options. (line 6)
* command-line options, processing: Getopt Function. (line 6)
* command-line options, string extraction: String Extraction. (line 6)
-* commands debugger command: Dgawk Execution Control.
+* commands debugger command: Debugger Execution Control.
+ (line 10)
+* commands to execute at breakpoint: Debugger Execution Control.
(line 10)
* commenting: Comments. (line 6)
* commenting, backslash continuation and: Statements/Lines. (line 76)
-* common extensions, ** operator: Arithmetic Ops. (line 36)
-* common extensions, **= operator: Assignment Ops. (line 136)
-* common extensions, /dev/stderr special file: Special FD. (line 46)
-* common extensions, /dev/stdin special file: Special FD. (line 46)
-* common extensions, /dev/stdout special file: Special FD. (line 46)
+* common extensions, ** operator: Arithmetic Ops. (line 30)
+* common extensions, **= operator: Assignment Ops. (line 137)
+* common extensions, /dev/stderr special file: Special FD. (line 48)
+* common extensions, /dev/stdin special file: Special FD. (line 48)
+* common extensions, /dev/stdout special file: Special FD. (line 48)
* common extensions, \x escape sequence: Escape Sequences. (line 61)
-* common extensions, BINMODE variable: PC Using. (line 34)
+* common extensions, BINMODE variable: PC Using. (line 33)
* common extensions, delete to delete entire arrays: Delete. (line 39)
-* common extensions, fflush() function: I/O Functions. (line 25)
-* common extensions, func keyword: Definition Syntax. (line 83)
+* common extensions, func keyword: Definition Syntax. (line 93)
* common extensions, length() applied to an array: String Functions.
- (line 196)
-* common extensions, nextfile statement: Nextfile Statement. (line 6)
-* common extensions, RS as a regexp: Records. (line 115)
+ (line 201)
+* common extensions, RS as a regexp: gawk split records. (line 6)
* common extensions, single character fields: Single Character Fields.
(line 6)
-* comp.lang.awk newsgroup: Bugs. (line 38)
+* comp.lang.awk newsgroup: Bugs. (line 39)
* comparison expressions: Typing and Comparison.
(line 9)
* comparison expressions, as patterns: Expression Patterns. (line 14)
@@ -25356,93 +32155,113 @@ Index
(line 60)
* compatibility mode (gawk), octal numbers: Nondecimal-numbers.
(line 60)
-* compatibility mode (gawk), specifying: Options. (line 78)
-* compiled programs <1>: Glossary. (line 161)
-* compiled programs: Basic High Level. (line 14)
+* compatibility mode (gawk), specifying: Options. (line 81)
+* compiled programs <1>: Glossary. (line 155)
+* compiled programs: Basic High Level. (line 15)
* compiling gawk for Cygwin: Cygwin. (line 6)
* compiling gawk for MS-DOS and MS-Windows: PC Compiling. (line 13)
* compiling gawk for VMS: VMS Compilation. (line 6)
* compiling gawk with EMX for OS/2: PC Compiling. (line 28)
-* compl() function (gawk): Bitwise Functions. (line 42)
+* compl: Bitwise Functions. (line 44)
* complement, bitwise: Bitwise Functions. (line 25)
* compound statements, control statements and: Statements. (line 10)
-* concatenating: Concatenation. (line 9)
+* concatenating: Concatenation. (line 8)
* condition debugger command: Breakpoint Control. (line 54)
* conditional expressions: Conditional Exp. (line 6)
-* configuration option, --disable-lint: Additional Configuration Options.
+* configuration option, --disable-extensions: Additional Configuration Options.
(line 9)
+* configuration option, --disable-lint: Additional Configuration Options.
+ (line 15)
* configuration option, --disable-nls: Additional Configuration Options.
- (line 24)
+ (line 30)
* configuration option, --with-whiny-user-strftime: Additional Configuration Options.
- (line 29)
+ (line 35)
* configuration options, gawk: Additional Configuration Options.
(line 6)
+* constant regexps: Regexp Usage. (line 57)
* constants, nondecimal: Nondecimal Data. (line 6)
+* constants, numeric: Scalar Constants. (line 6)
* constants, types of: Constants. (line 6)
+* continue program, in debugger: Debugger Execution Control.
+ (line 33)
* continue statement: Continue Statement. (line 6)
* control statements: Statements. (line 6)
-* converting, case: String Functions. (line 522)
-* converting, dates to timestamps: Time Functions. (line 74)
-* converting, during subscripting: Numeric Array Subscripts.
+* controlling array scanning order: Controlling Scanning.
+ (line 14)
+* convert string to lower case: String Functions. (line 523)
+* convert string to number: String Functions. (line 390)
+* convert string to upper case: String Functions. (line 529)
+* converting integer array subscripts: Numeric Array Subscripts.
(line 31)
-* converting, numbers to strings <1>: Bitwise Functions. (line 107)
-* converting, numbers to strings: Conversion. (line 6)
-* converting, strings to numbers <1>: Bitwise Functions. (line 107)
-* converting, strings to numbers: Conversion. (line 6)
-* CONVFMT variable <1>: User-modified. (line 28)
-* CONVFMT variable: Conversion. (line 29)
-* CONVFMT variable, array subscripts and: Numeric Array Subscripts.
+* converting, dates to timestamps: Time Functions. (line 76)
+* converting, numbers to strings <1>: Bitwise Functions. (line 110)
+* converting, numbers to strings: Strings And Numbers. (line 6)
+* converting, strings to numbers <1>: Bitwise Functions. (line 110)
+* converting, strings to numbers: Strings And Numbers. (line 6)
+* CONVFMT variable <1>: User-modified. (line 30)
+* CONVFMT variable: Strings And Numbers. (line 29)
+* CONVFMT variable, and array subscripts: Numeric Array Subscripts.
(line 6)
-* coprocesses <1>: Two-way I/O. (line 44)
-* coprocesses: Redirection. (line 102)
+* cookie: Glossary. (line 177)
+* coprocesses <1>: Two-way I/O. (line 25)
+* coprocesses: Redirection. (line 96)
* coprocesses, closing: Close Files And Pipes.
(line 6)
* coprocesses, getline from: Getline/Coprocess. (line 6)
-* cos() function: Numeric Functions. (line 14)
+* cos: Numeric Functions. (line 15)
+* cosine: Numeric Functions. (line 15)
* counting: Wc Program. (line 6)
* csh utility: Statements/Lines. (line 44)
-* csh utility, POSIXLY_CORRECT environment variable: Options. (line 305)
-* csh utility, |& operator, comparison with: Two-way I/O. (line 44)
-* ctime() user-defined function: Function Example. (line 72)
-* currency symbols, localization: Explaining gettext. (line 103)
+* csh utility, POSIXLY_CORRECT environment variable: Options. (line 354)
+* csh utility, |& operator, comparison with: Two-way I/O. (line 25)
+* ctime() user-defined function: Function Example. (line 74)
+* currency symbols, localization: Explaining gettext. (line 104)
+* current system time: Time Functions. (line 66)
* custom.h file: Configuration Philosophy.
(line 30)
+* customized input parser: Input Parsers. (line 6)
+* customized output wrapper: Output Wrappers. (line 6)
+* customized two-way processor: Two-way processors. (line 6)
* cut utility: Cut Program. (line 6)
* cut.awk program: Cut Program. (line 45)
-* d debugger command (alias for delete): Breakpoint Control. (line 63)
-* d.c., See dark corner: Conventions. (line 38)
-* dark corner <1>: Glossary. (line 193)
-* dark corner <2>: Truth Values. (line 24)
-* dark corner <3>: Assignment Ops. (line 148)
-* dark corner: Conventions. (line 38)
+* d debugger command (alias for delete): Breakpoint Control. (line 64)
+* d.c., See dark corner: Conventions. (line 42)
+* dark corner <1>: Glossary. (line 188)
+* dark corner: Conventions. (line 42)
+* dark corner, "0" is actually true: Truth Values. (line 24)
+* dark corner, /= operator vs. /=.../ regexp constant: Assignment Ops.
+ (line 148)
* dark corner, ^, in FS: Regexp Field Splitting.
(line 59)
* dark corner, array subscripts: Uninitialized Subscripts.
(line 43)
* dark corner, break statement: Break Statement. (line 51)
* dark corner, close() function: Close Files And Pipes.
- (line 131)
+ (line 133)
* dark corner, command-line arguments: Assignment Options. (line 43)
-* dark corner, continue statement: Continue Statement. (line 43)
-* dark corner, CONVFMT variable: Conversion. (line 40)
-* dark corner, escape sequences: Other Arguments. (line 31)
+* dark corner, continue statement: Continue Statement. (line 44)
+* dark corner, CONVFMT variable: Strings And Numbers. (line 40)
+* dark corner, escape sequences: Other Arguments. (line 38)
* dark corner, escape sequences, for metacharacters: Escape Sequences.
- (line 136)
+ (line 143)
* dark corner, exit statement: Exit Statement. (line 30)
-* dark corner, field separators: Field Splitting Summary.
- (line 47)
-* dark corner, FILENAME variable <1>: Auto-set. (line 92)
+* dark corner, field separators: Full Line Fields. (line 22)
+* dark corner, FILENAME variable <1>: Auto-set. (line 104)
* dark corner, FILENAME variable: Getline Notes. (line 19)
-* dark corner, FNR/NR variables: Auto-set. (line 207)
+* dark corner, FNR/NR variables: Auto-set. (line 328)
* dark corner, format-control characters: Control Letters. (line 18)
* dark corner, FS as null string: Single Character Fields.
(line 20)
-* dark corner, input files: Records. (line 98)
+* dark corner, input files: awk split records. (line 111)
* dark corner, invoking awk: Command Line. (line 16)
-* dark corner, length() function: String Functions. (line 182)
+* dark corner, length() function: String Functions. (line 187)
+* dark corner, locale's decimal point character: Locale influences conversions.
+ (line 17)
* dark corner, multiline records: Multiple Line. (line 35)
* dark corner, NF variable, decrementing: Changing Fields. (line 107)
* dark corner, OFMT variable: OFMT. (line 27)
+* dark corner, regexp as second argument to index(): String Functions.
+ (line 165)
* dark corner, regexp constants: Using Constant Regexps.
(line 6)
* dark corner, regexp constants, /= operator and: Assignment Ops.
@@ -25450,301 +32269,339 @@ Index
* dark corner, regexp constants, as arguments to user-defined functions: Using Constant Regexps.
(line 43)
* dark corner, split() function: String Functions. (line 361)
-* dark corner, strings, storing: Records. (line 191)
-* dark corner, value of ARGV[0]: Auto-set. (line 35)
-* data, fixed-width: Constant Size. (line 9)
-* data-driven languages: Basic High Level. (line 83)
+* dark corner, strings, storing: gawk split records. (line 83)
+* dark corner, value of ARGV[0]: Auto-set. (line 39)
+* data, fixed-width: Constant Size. (line 6)
+* data-driven languages: Basic High Level. (line 85)
* database, group, reading: Group Functions. (line 6)
* database, users, reading: Passwd Functions. (line 6)
* date utility, GNU: Time Functions. (line 17)
-* date utility, POSIX: Time Functions. (line 261)
-* dates, converting to timestamps: Time Functions. (line 74)
+* date utility, POSIX: Time Functions. (line 254)
+* dates, converting to timestamps: Time Functions. (line 76)
* dates, information related to, localization: Explaining gettext.
- (line 115)
+ (line 112)
* Davies, Stephen <1>: Contributors. (line 74)
* Davies, Stephen: Acknowledgments. (line 60)
-* dcgettext() function (gawk) <1>: Programmer i18n. (line 19)
-* dcgettext() function (gawk): I18N Functions. (line 22)
+* Day, Robert P.J.: Acknowledgments. (line 78)
+* dcgettext <1>: Programmer i18n. (line 19)
+* dcgettext: I18N Functions. (line 22)
* dcgettext() function (gawk), portability and: I18N Portability.
(line 33)
-* dcngettext() function (gawk) <1>: Programmer i18n. (line 36)
-* dcngettext() function (gawk): I18N Functions. (line 28)
+* dcngettext <1>: Programmer i18n. (line 36)
+* dcngettext: I18N Functions. (line 28)
* dcngettext() function (gawk), portability and: I18N Portability.
(line 33)
-* deadlocks: Two-way I/O. (line 70)
+* deadlocks: Two-way I/O. (line 52)
* debugger commands, b (break): Breakpoint Control. (line 11)
-* debugger commands, backtrace: Dgawk Stack. (line 13)
+* debugger commands, backtrace: Execution Stack. (line 13)
* debugger commands, break: Breakpoint Control. (line 11)
-* debugger commands, bt (backtrace): Dgawk Stack. (line 13)
-* debugger commands, c (continue): Dgawk Execution Control.
+* debugger commands, bt (backtrace): Execution Stack. (line 13)
+* debugger commands, c (continue): Debugger Execution Control.
(line 33)
* debugger commands, clear: Breakpoint Control. (line 36)
-* debugger commands, commands: Dgawk Execution Control.
+* debugger commands, commands: Debugger Execution Control.
(line 10)
* debugger commands, condition: Breakpoint Control. (line 54)
-* debugger commands, continue: Dgawk Execution Control.
+* debugger commands, continue: Debugger Execution Control.
(line 33)
-* debugger commands, d (delete): Breakpoint Control. (line 63)
-* debugger commands, delete: Breakpoint Control. (line 63)
-* debugger commands, disable: Breakpoint Control. (line 68)
+* debugger commands, d (delete): Breakpoint Control. (line 64)
+* debugger commands, delete: Breakpoint Control. (line 64)
+* debugger commands, disable: Breakpoint Control. (line 69)
* debugger commands, display: Viewing And Changing Data.
(line 8)
-* debugger commands, down: Dgawk Stack. (line 21)
-* debugger commands, dump: Miscellaneous Dgawk Commands.
+* debugger commands, down: Execution Stack. (line 23)
+* debugger commands, dump: Miscellaneous Debugger Commands.
(line 9)
-* debugger commands, e (enable): Breakpoint Control. (line 72)
-* debugger commands, enable: Breakpoint Control. (line 72)
-* debugger commands, end: Dgawk Execution Control.
+* debugger commands, e (enable): Breakpoint Control. (line 73)
+* debugger commands, enable: Breakpoint Control. (line 73)
+* debugger commands, end: Debugger Execution Control.
(line 10)
* debugger commands, eval: Viewing And Changing Data.
(line 23)
-* debugger commands, f (frame): Dgawk Stack. (line 25)
-* debugger commands, finish: Dgawk Execution Control.
+* debugger commands, f (frame): Execution Stack. (line 27)
+* debugger commands, finish: Debugger Execution Control.
(line 39)
-* debugger commands, frame: Dgawk Stack. (line 25)
-* debugger commands, h (help): Miscellaneous Dgawk Commands.
- (line 68)
-* debugger commands, help: Miscellaneous Dgawk Commands.
- (line 68)
-* debugger commands, i (info): Dgawk Info. (line 12)
-* debugger commands, ignore: Breakpoint Control. (line 86)
-* debugger commands, info: Dgawk Info. (line 12)
-* debugger commands, l (list): Miscellaneous Dgawk Commands.
- (line 74)
-* debugger commands, list: Miscellaneous Dgawk Commands.
- (line 74)
-* debugger commands, n (next): Dgawk Execution Control.
+* debugger commands, frame: Execution Stack. (line 27)
+* debugger commands, h (help): Miscellaneous Debugger Commands.
+ (line 66)
+* debugger commands, help: Miscellaneous Debugger Commands.
+ (line 66)
+* debugger commands, i (info): Debugger Info. (line 13)
+* debugger commands, ignore: Breakpoint Control. (line 87)
+* debugger commands, info: Debugger Info. (line 13)
+* debugger commands, l (list): Miscellaneous Debugger Commands.
+ (line 72)
+* debugger commands, list: Miscellaneous Debugger Commands.
+ (line 72)
+* debugger commands, n (next): Debugger Execution Control.
(line 43)
-* debugger commands, next: Dgawk Execution Control.
+* debugger commands, next: Debugger Execution Control.
(line 43)
-* debugger commands, nexti: Dgawk Execution Control.
+* debugger commands, nexti: Debugger Execution Control.
(line 49)
-* debugger commands, ni (nexti): Dgawk Execution Control.
+* debugger commands, ni (nexti): Debugger Execution Control.
(line 49)
-* debugger commands, o (option): Dgawk Info. (line 56)
-* debugger commands, option: Dgawk Info. (line 56)
+* debugger commands, o (option): Debugger Info. (line 57)
+* debugger commands, option: Debugger Info. (line 57)
* debugger commands, p (print): Viewing And Changing Data.
(line 36)
* debugger commands, print: Viewing And Changing Data.
(line 36)
* debugger commands, printf: Viewing And Changing Data.
(line 54)
-* debugger commands, q (quit): Miscellaneous Dgawk Commands.
- (line 101)
-* debugger commands, quit: Miscellaneous Dgawk Commands.
- (line 101)
-* debugger commands, r (run): Dgawk Execution Control.
+* debugger commands, q (quit): Miscellaneous Debugger Commands.
+ (line 99)
+* debugger commands, quit: Miscellaneous Debugger Commands.
+ (line 99)
+* debugger commands, r (run): Debugger Execution Control.
(line 62)
-* debugger commands, return: Dgawk Execution Control.
+* debugger commands, return: Debugger Execution Control.
(line 54)
-* debugger commands, run: Dgawk Execution Control.
+* debugger commands, run: Debugger Execution Control.
(line 62)
-* debugger commands, s (step): Dgawk Execution Control.
+* debugger commands, s (step): Debugger Execution Control.
(line 68)
* debugger commands, set: Viewing And Changing Data.
(line 59)
-* debugger commands, si (stepi): Dgawk Execution Control.
+* debugger commands, si (stepi): Debugger Execution Control.
(line 76)
-* debugger commands, silent: Dgawk Execution Control.
+* debugger commands, silent: Debugger Execution Control.
(line 10)
-* debugger commands, step: Dgawk Execution Control.
+* debugger commands, step: Debugger Execution Control.
(line 68)
-* debugger commands, stepi: Dgawk Execution Control.
+* debugger commands, stepi: Debugger Execution Control.
(line 76)
-* debugger commands, t (tbreak): Breakpoint Control. (line 89)
-* debugger commands, tbreak: Breakpoint Control. (line 89)
-* debugger commands, trace: Miscellaneous Dgawk Commands.
- (line 110)
-* debugger commands, u (until): Dgawk Execution Control.
+* debugger commands, t (tbreak): Breakpoint Control. (line 90)
+* debugger commands, tbreak: Breakpoint Control. (line 90)
+* debugger commands, trace: Miscellaneous Debugger Commands.
+ (line 108)
+* debugger commands, u (until): Debugger Execution Control.
(line 83)
* debugger commands, undisplay: Viewing And Changing Data.
(line 80)
-* debugger commands, until: Dgawk Execution Control.
+* debugger commands, until: Debugger Execution Control.
(line 83)
* debugger commands, unwatch: Viewing And Changing Data.
(line 84)
-* debugger commands, up: Dgawk Stack. (line 33)
+* debugger commands, up: Execution Stack. (line 36)
* debugger commands, w (watch): Viewing And Changing Data.
(line 67)
* debugger commands, watch: Viewing And Changing Data.
(line 67)
+* debugger commands, where (backtrace): Execution Stack. (line 13)
+* debugger default list amount: Debugger Info. (line 69)
+* debugger history file: Debugger Info. (line 80)
+* debugger history size: Debugger Info. (line 65)
+* debugger options: Debugger Info. (line 57)
+* debugger prompt: Debugger Info. (line 77)
+* debugger, how to start: Debugger Invocation. (line 6)
+* debugger, read commands from a file: Debugger Info. (line 96)
+* debugging awk programs: Debugger. (line 6)
* debugging gawk, bug reports: Bugs. (line 9)
-* decimal point character, locale specific: Options. (line 215)
+* decimal point character, locale specific: Options. (line 270)
* decrement operators: Increment Ops. (line 35)
* default keyword: Switch Statement. (line 6)
* Deifik, Scott <1>: Bugs. (line 70)
-* Deifik, Scott <2>: Contributors. (line 54)
+* Deifik, Scott <2>: Contributors. (line 53)
* Deifik, Scott: Acknowledgments. (line 60)
-* delete debugger command: Breakpoint Control. (line 63)
+* delete ARRAY: Delete. (line 39)
+* delete breakpoint at location: Breakpoint Control. (line 36)
+* delete breakpoint by number: Breakpoint Control. (line 64)
+* delete debugger command: Breakpoint Control. (line 64)
* delete statement: Delete. (line 6)
+* delete watchpoint: Viewing And Changing Data.
+ (line 84)
* deleting elements in arrays: Delete. (line 6)
* deleting entire arrays: Delete. (line 39)
-* dgawk: Debugger. (line 6)
-* differences between gawk and awk: String Functions. (line 196)
+* Demaille, Akim: Acknowledgments. (line 60)
+* describe call stack frame, in debugger: Debugger Info. (line 27)
+* differences between gawk and awk: String Functions. (line 201)
* differences in awk and gawk, ARGC/ARGV variables: ARGC and ARGV.
- (line 88)
-* differences in awk and gawk, ARGIND variable: Auto-set. (line 40)
+ (line 90)
+* differences in awk and gawk, ARGIND variable: Auto-set. (line 44)
* differences in awk and gawk, array elements, deleting: Delete.
(line 39)
+* differences in awk and gawk, AWKLIBPATH environment variable: AWKLIBPATH Variable.
+ (line 6)
* differences in awk and gawk, AWKPATH environment variable: AWKPATH Variable.
(line 6)
* differences in awk and gawk, BEGIN/END patterns: I/O And BEGIN/END.
(line 16)
+* differences in awk and gawk, BEGINFILE/ENDFILE patterns: BEGINFILE/ENDFILE.
+ (line 6)
* differences in awk and gawk, BINMODE variable <1>: PC Using.
- (line 34)
+ (line 33)
* differences in awk and gawk, BINMODE variable: User-modified.
- (line 23)
+ (line 15)
* differences in awk and gawk, close() function: Close Files And Pipes.
(line 81)
-* differences in awk and gawk, ERRNO variable: Auto-set. (line 72)
-* differences in awk and gawk, error messages: Special FD. (line 16)
+* differences in awk and gawk, command-line directories: Command-line directories.
+ (line 6)
+* differences in awk and gawk, ERRNO variable: Auto-set. (line 88)
+* differences in awk and gawk, error messages: Special FD. (line 19)
* differences in awk and gawk, FIELDWIDTHS variable: User-modified.
- (line 35)
-* differences in awk and gawk, FPAT variable: User-modified. (line 45)
+ (line 37)
+* differences in awk and gawk, FPAT variable: User-modified. (line 43)
+* differences in awk and gawk, FUNCTAB variable: Auto-set. (line 130)
* differences in awk and gawk, function arguments (gawk): Calling Built-in.
(line 16)
* differences in awk and gawk, getline command: Getline. (line 19)
* differences in awk and gawk, IGNORECASE variable: User-modified.
- (line 82)
+ (line 76)
* differences in awk and gawk, implementation limitations <1>: Redirection.
- (line 135)
+ (line 129)
* differences in awk and gawk, implementation limitations: Getline Notes.
(line 14)
* differences in awk and gawk, indirect function calls: Indirect Calls.
(line 6)
* differences in awk and gawk, input/output operators <1>: Redirection.
- (line 102)
+ (line 96)
* differences in awk and gawk, input/output operators: Getline/Coprocess.
(line 6)
* differences in awk and gawk, line continuations: Conditional Exp.
(line 34)
-* differences in awk and gawk, LINT variable: User-modified. (line 98)
+* differences in awk and gawk, LINT variable: User-modified. (line 88)
* differences in awk and gawk, match() function: String Functions.
- (line 259)
-* differences in awk and gawk, next/nextfile statements: Nextfile Statement.
- (line 6)
+ (line 263)
* differences in awk and gawk, print/printf statements: Format Modifiers.
(line 13)
-* differences in awk and gawk, PROCINFO array: Auto-set. (line 123)
-* differences in awk and gawk, record separators: Records. (line 112)
+* differences in awk and gawk, PROCINFO array: Auto-set. (line 144)
+* differences in awk and gawk, read timeouts: Read Timeout. (line 6)
+* differences in awk and gawk, record separators: awk split records.
+ (line 125)
* differences in awk and gawk, regexp constants: Using Constant Regexps.
(line 43)
* differences in awk and gawk, regular expressions: Case-sensitivity.
(line 26)
-* differences in awk and gawk, RS/RT variables: Records. (line 167)
-* differences in awk and gawk, RT variable: Auto-set. (line 196)
+* differences in awk and gawk, RS/RT variables: gawk split records.
+ (line 58)
+* differences in awk and gawk, RT variable: Auto-set. (line 279)
* differences in awk and gawk, single-character fields: Single Character Fields.
(line 6)
* differences in awk and gawk, split() function: String Functions.
(line 349)
* differences in awk and gawk, strings: Scalar Constants. (line 20)
-* differences in awk and gawk, strings, storing: Records. (line 187)
-* differences in awk and gawk, strtonum() function (gawk): String Functions.
- (line 404)
+* differences in awk and gawk, strings, storing: gawk split records.
+ (line 77)
+* differences in awk and gawk, SYMTAB variable: Auto-set. (line 283)
* differences in awk and gawk, TEXTDOMAIN variable: User-modified.
- (line 153)
+ (line 151)
* differences in awk and gawk, trunc-mod operation: Arithmetic Ops.
(line 66)
-* directories, changing: Sample Library. (line 6)
-* directories, command line: Command line directories.
+* directories, command-line: Command-line directories.
+ (line 6)
+* directories, searching: Programs Exercises. (line 70)
+* directories, searching for loadable extensions: AWKLIBPATH Variable.
(line 6)
-* directories, searching <1>: Igawk Program. (line 368)
-* directories, searching: AWKPATH Variable. (line 6)
-* disable debugger command: Breakpoint Control. (line 68)
+* directories, searching for source files: AWKPATH Variable. (line 6)
+* disable breakpoint: Breakpoint Control. (line 69)
+* disable debugger command: Breakpoint Control. (line 69)
* display debugger command: Viewing And Changing Data.
(line 8)
+* display debugger options: Debugger Info. (line 57)
+* div: Numeric Functions. (line 18)
* division: Arithmetic Ops. (line 44)
-* do-while statement <1>: Do Statement. (line 6)
-* do-while statement: Regexp Usage. (line 19)
+* do-while statement: Do Statement. (line 6)
+* do-while statement, use of regexps in: Regexp Usage. (line 19)
* documentation, of awk programs: Library Names. (line 6)
* documentation, online: Manual History. (line 11)
* documents, searching: Dupword Program. (line 6)
-* dollar sign ($): Regexp Operators. (line 35)
* dollar sign ($), $ field operator <1>: Precedence. (line 43)
* dollar sign ($), $ field operator: Fields. (line 19)
* dollar sign ($), incrementing fields and arrays: Increment Ops.
(line 30)
-* double precision floating-point: Basic Data Typing. (line 36)
-* double quote (") <1>: Quoting. (line 37)
-* double quote ("): Read Terminal. (line 25)
-* double quote ("), regexp constants: Computed Regexps. (line 28)
-* down debugger command: Dgawk Stack. (line 21)
+* dollar sign ($), regexp operator: Regexp Operators. (line 35)
+* double quote ("), in regexp constants: Computed Regexps. (line 29)
+* double quote ("), in shell commands: Quoting. (line 54)
+* down debugger command: Execution Stack. (line 23)
* Drepper, Ulrich: Acknowledgments. (line 52)
-* DuBois, John: Acknowledgments. (line 60)
-* dump debugger command: Miscellaneous Dgawk Commands.
+* Duman, Patrice: Acknowledgments. (line 74)
+* dump all variables of a program: Options. (line 93)
+* dump debugger command: Miscellaneous Debugger Commands.
(line 9)
-* dupnode() internal function: Internals. (line 87)
* dupword.awk program: Dupword Program. (line 31)
-* e debugger command (alias for enable): Breakpoint Control. (line 72)
+* dynamic profiling: Profiling. (line 178)
+* dynamically loaded extensions: Dynamic Extensions. (line 6)
+* e debugger command (alias for enable): Breakpoint Control. (line 73)
* EBCDIC: Ordinal Functions. (line 45)
+* effective group ID of gawk user: Auto-set. (line 149)
+* effective user ID of gawk user: Auto-set. (line 153)
* egrep utility <1>: Egrep Program. (line 6)
-* egrep utility: Bracket Expressions. (line 24)
+* egrep utility: Bracket Expressions. (line 26)
* egrep.awk program: Egrep Program. (line 54)
-* elements in arrays: Reference to Elements.
- (line 6)
-* elements in arrays, assigning: Assigning Elements. (line 6)
+* elements in arrays, assigning values: Assigning Elements. (line 6)
* elements in arrays, deleting: Delete. (line 6)
-* elements in arrays, order of: Scanning an Array. (line 48)
+* elements in arrays, order of access by in operator: Scanning an Array.
+ (line 48)
* elements in arrays, scanning: Scanning an Array. (line 6)
+* elements of arrays: Reference to Elements.
+ (line 6)
* email address for bug reports, bug-gawk@gnu.org: Bugs. (line 30)
* EMISTERED: TCP/IP Networking. (line 6)
+* empty array elements: Reference to Elements.
+ (line 18)
* empty pattern: Empty. (line 6)
+* empty strings: awk split records. (line 115)
* empty strings, See null strings: Regexp Field Splitting.
(line 43)
-* enable debugger command: Breakpoint Control. (line 72)
-* end debugger command: Dgawk Execution Control.
+* enable breakpoint: Breakpoint Control. (line 73)
+* enable debugger command: Breakpoint Control. (line 73)
+* end debugger command: Debugger Execution Control.
(line 10)
+* END pattern <1>: Using BEGIN/END. (line 6)
* END pattern: BEGIN/END. (line 6)
+* END pattern, and profiling: Profiling. (line 62)
* END pattern, assert() user-defined function and: Assert Function.
(line 75)
-* END pattern, backslash continuation and: Egrep Program. (line 220)
-* END pattern, Boolean patterns and: Expression Patterns. (line 73)
+* END pattern, Boolean patterns and: Expression Patterns. (line 69)
* END pattern, exit statement and: Exit Statement. (line 12)
* END pattern, next/nextfile statements and <1>: Next Statement.
- (line 45)
+ (line 44)
* END pattern, next/nextfile statements and: I/O And BEGIN/END.
(line 37)
* END pattern, operators and: Using BEGIN/END. (line 17)
-* END pattern, pgawk program: Profiling. (line 65)
* END pattern, print statement and: I/O And BEGIN/END. (line 16)
* ENDFILE pattern: BEGINFILE/ENDFILE. (line 6)
-* ENDFILE pattern, Boolean patterns and: Expression Patterns. (line 73)
-* endfile() user-defined function: Filetrans Function. (line 62)
-* endgrent() function (C library): Group Functions. (line 215)
-* endgrent() user-defined function: Group Functions. (line 218)
-* endpwent() function (C library): Passwd Functions. (line 210)
-* endpwent() user-defined function: Passwd Functions. (line 213)
-* ENVIRON array <1>: Internals. (line 140)
+* ENDFILE pattern, Boolean patterns and: Expression Patterns. (line 69)
+* endfile() user-defined function: Filetrans Function. (line 61)
+* endgrent() function (C library): Group Functions. (line 211)
+* endgrent() user-defined function: Group Functions. (line 214)
+* endpwent() function (C library): Passwd Functions. (line 207)
+* endpwent() user-defined function: Passwd Functions. (line 210)
+* English, Steve: Advanced Features. (line 6)
* ENVIRON array: Auto-set. (line 60)
-* environment variables: Auto-set. (line 60)
-* epoch, definition of: Glossary. (line 239)
+* environment variables used by gawk: Environment Variables.
+ (line 6)
+* environment variables, in ENVIRON array: Auto-set. (line 60)
+* epoch, definition of: Glossary. (line 234)
* equals sign (=), = operator: Assignment Ops. (line 6)
* equals sign (=), == operator <1>: Precedence. (line 65)
* equals sign (=), == operator: Comparison Operators.
(line 11)
-* EREs (Extended Regular Expressions): Bracket Expressions. (line 24)
-* ERRNO variable <1>: Internals. (line 130)
-* ERRNO variable <2>: TCP/IP Networking. (line 54)
-* ERRNO variable <3>: Auto-set. (line 72)
-* ERRNO variable <4>: BEGINFILE/ENDFILE. (line 26)
-* ERRNO variable <5>: Close Files And Pipes.
- (line 139)
-* ERRNO variable: Getline. (line 19)
-* error handling: Special FD. (line 16)
-* error handling, ERRNO variable and: Auto-set. (line 72)
+* EREs (Extended Regular Expressions): Bracket Expressions. (line 26)
+* ERRNO variable <1>: TCP/IP Networking. (line 54)
+* ERRNO variable: Auto-set. (line 88)
+* ERRNO variable, with BEGINFILE pattern: BEGINFILE/ENDFILE. (line 26)
+* ERRNO variable, with close() function: Close Files And Pipes.
+ (line 141)
+* ERRNO variable, with getline command: Getline. (line 19)
+* error handling: Special FD. (line 19)
+* error handling, ERRNO variable and: Auto-set. (line 88)
* error output: Special FD. (line 6)
* escape processing, gsub()/gensub()/sub() functions: Gory Details.
(line 6)
-* escape sequences: Escape Sequences. (line 6)
+* escape sequences, in strings: Escape Sequences. (line 6)
* eval debugger command: Viewing And Changing Data.
(line 23)
-* evaluation order: Increment Ops. (line 61)
-* evaluation order, concatenation: Concatenation. (line 42)
+* evaluate expressions, in debugger: Viewing And Changing Data.
+ (line 23)
+* evaluation order: Increment Ops. (line 60)
+* evaluation order, concatenation: Concatenation. (line 41)
* evaluation order, functions: Calling Built-in. (line 30)
* examining fields: Fields. (line 6)
-* exclamation point (!), ! operator <1>: Egrep Program. (line 170)
+* exclamation point (!), ! operator <1>: Egrep Program. (line 175)
* exclamation point (!), ! operator <2>: Precedence. (line 52)
-* exclamation point (!), ! operator: Boolean Ops. (line 67)
+* exclamation point (!), ! operator: Boolean Ops. (line 69)
* exclamation point (!), != operator <1>: Precedence. (line 65)
* exclamation point (!), != operator: Comparison Operators.
(line 11)
@@ -25754,13 +32611,18 @@ Index
* exclamation point (!), !~ operator <3>: Comparison Operators.
(line 11)
* exclamation point (!), !~ operator <4>: Regexp Constants. (line 6)
-* exclamation point (!), !~ operator <5>: Computed Regexps. (line 6)
-* exclamation point (!), !~ operator <6>: Case-sensitivity. (line 26)
+* exclamation point (!), !~ operator <5>: Case-sensitivity. (line 26)
+* exclamation point (!), !~ operator <6>: Computed Regexps. (line 6)
* exclamation point (!), !~ operator: Regexp Usage. (line 19)
* exit statement: Exit Statement. (line 6)
* exit status, of gawk: Exit Status. (line 6)
-* exp() function: Numeric Functions. (line 17)
-* expand utility: Very Simple. (line 69)
+* exit status, of VMS: VMS Running. (line 28)
+* exit the debugger: Miscellaneous Debugger Commands.
+ (line 99)
+* exp: Numeric Functions. (line 33)
+* expand utility: Very Simple. (line 73)
+* Expat XML parser library: gawkextlib. (line 33)
+* exponent: Numeric Functions. (line 33)
* expressions: Expressions. (line 6)
* expressions, as patterns: Expression Patterns. (line 6)
* expressions, assignment: Assignment Ops. (line 6)
@@ -25771,63 +32633,75 @@ Index
* expressions, matching, See comparison expressions: Typing and Comparison.
(line 9)
* expressions, selecting: Conditional Exp. (line 6)
-* Extended Regular Expressions (EREs): Bracket Expressions. (line 24)
-* eXtensible Markup Language (XML): Internals. (line 151)
-* extension() function (gawk): Using Internal File Ops.
- (line 15)
-* extensions, Brian Kernighan's awk <1>: Other Versions. (line 13)
+* Extended Regular Expressions (EREs): Bracket Expressions. (line 26)
+* extension API: Extension API Description.
+ (line 6)
+* extension API informational variables: Extension API Informational Variables.
+ (line 6)
+* extension API version: Extension Versioning.
+ (line 6)
+* extension API, version number: Auto-set. (line 246)
+* extension example: Extension Example. (line 6)
+* extension registration: Registration Functions.
+ (line 6)
+* extension search path: Finding Extensions. (line 6)
+* extensions distributed with gawk: Extension Samples. (line 6)
+* extensions, allocating memory: Memory Allocation Functions.
+ (line 6)
+* extensions, Brian Kernighan's awk <1>: Common Extensions. (line 6)
* extensions, Brian Kernighan's awk: BTL. (line 6)
-* extensions, common, ** operator: Arithmetic Ops. (line 36)
-* extensions, common, **= operator: Assignment Ops. (line 136)
-* extensions, common, /dev/stderr special file: Special FD. (line 46)
-* extensions, common, /dev/stdin special file: Special FD. (line 46)
-* extensions, common, /dev/stdout special file: Special FD. (line 46)
+* extensions, common, ** operator: Arithmetic Ops. (line 30)
+* extensions, common, **= operator: Assignment Ops. (line 137)
+* extensions, common, /dev/stderr special file: Special FD. (line 48)
+* extensions, common, /dev/stdin special file: Special FD. (line 48)
+* extensions, common, /dev/stdout special file: Special FD. (line 48)
* extensions, common, \x escape sequence: Escape Sequences. (line 61)
-* extensions, common, BINMODE variable: PC Using. (line 34)
+* extensions, common, BINMODE variable: PC Using. (line 33)
* extensions, common, delete to delete entire arrays: Delete. (line 39)
-* extensions, common, fflush() function: I/O Functions. (line 25)
-* extensions, common, func keyword: Definition Syntax. (line 83)
+* extensions, common, fflush() function: I/O Functions. (line 43)
+* extensions, common, func keyword: Definition Syntax. (line 93)
* extensions, common, length() applied to an array: String Functions.
- (line 196)
-* extensions, common, nextfile statement: Nextfile Statement. (line 6)
-* extensions, common, RS as a regexp: Records. (line 115)
+ (line 201)
+* extensions, common, RS as a regexp: gawk split records. (line 6)
* extensions, common, single character fields: Single Character Fields.
(line 6)
* extensions, in gawk, not in POSIX awk: POSIX/GNU. (line 6)
-* extract.awk program: Extract Program. (line 78)
+* extensions, loading, @load directive: Loading Shared Libraries.
+ (line 8)
+* extensions, mawk: Common Extensions. (line 6)
+* extensions, where to find: gawkextlib. (line 6)
+* extract.awk program: Extract Program. (line 79)
* extraction, of marked strings (internationalization): String Extraction.
(line 6)
-* f debugger command (alias for frame): Dgawk Stack. (line 25)
+* f debugger command (alias for frame): Execution Stack. (line 27)
* false, logical: Truth Values. (line 6)
* FDL (Free Documentation License): GNU Free Documentation License.
- (line 6)
+ (line 7)
* features, adding to gawk: Adding Code. (line 6)
-* features, advanced, See advanced features: Obsolete. (line 6)
* features, deprecated: Obsolete. (line 6)
* features, undocumented: Undocumented. (line 6)
-* Fenlason, Jay <1>: Contributors. (line 19)
+* Fenlason, Jay <1>: Contributors. (line 18)
* Fenlason, Jay: History. (line 30)
-* fflush() function: I/O Functions. (line 25)
+* fflush: I/O Functions. (line 28)
* field numbers: Nonconstant Fields. (line 6)
* field operator $: Fields. (line 19)
* field operators, dollar sign as: Fields. (line 19)
-* field separators <1>: User-modified. (line 56)
-* field separators: Field Separators. (line 14)
-* field separators, choice of: Field Separators. (line 50)
-* field separators, FIELDWIDTHS variable and: User-modified. (line 35)
-* field separators, FPAT variable and: User-modified. (line 45)
-* field separators, in multiline records: Multiple Line. (line 41)
-* field separators, on command line: Command Line Field Separator.
+* field separator, in multiline records: Multiple Line. (line 41)
+* field separator, on command line: Command Line Field Separator.
(line 6)
-* field separators, POSIX and <1>: Field Splitting Summary.
- (line 41)
+* field separator, POSIX and: Full Line Fields. (line 16)
+* field separators <1>: User-modified. (line 50)
+* field separators: Field Separators. (line 15)
+* field separators, choice of: Field Separators. (line 51)
+* field separators, FIELDWIDTHS variable and: User-modified. (line 37)
+* field separators, FPAT variable and: User-modified. (line 43)
* field separators, POSIX and: Fields. (line 6)
* field separators, regular expressions as <1>: Regexp Field Splitting.
(line 6)
-* field separators, regular expressions as: Field Separators. (line 50)
+* field separators, regular expressions as: Field Separators. (line 51)
* field separators, See Also OFS: Changing Fields. (line 64)
-* field separators, spaces as: Cut Program. (line 109)
-* fields <1>: Basic High Level. (line 71)
+* field separators, spaces as: Cut Program. (line 103)
+* fields <1>: Basic High Level. (line 73)
* fields <2>: Fields. (line 6)
* fields: Reading Files. (line 14)
* fields, adding: Changing Fields. (line 53)
@@ -25837,141 +32711,151 @@ Index
* fields, number of: Fields. (line 33)
* fields, numbers: Nonconstant Fields. (line 6)
* fields, printing: Print Examples. (line 21)
-* fields, separating: Field Separators. (line 14)
+* fields, separating: Field Separators. (line 15)
* fields, single-character: Single Character Fields.
(line 6)
-* FIELDWIDTHS variable <1>: User-modified. (line 35)
+* FIELDWIDTHS variable <1>: User-modified. (line 37)
* FIELDWIDTHS variable: Constant Size. (line 22)
* file descriptors: Special FD. (line 6)
-* file names, distinguishing: Auto-set. (line 52)
+* file inclusion, @include directive: Include Files. (line 8)
+* file names, distinguishing: Auto-set. (line 56)
* file names, in compatibility mode: Special Caveats. (line 9)
-* file names, standard streams in gawk: Special FD. (line 46)
-* FILENAME variable <1>: Auto-set. (line 92)
+* file names, standard streams in gawk: Special FD. (line 48)
+* FILENAME variable <1>: Auto-set. (line 104)
* FILENAME variable: Reading Files. (line 6)
* FILENAME variable, getline, setting with: Getline Notes. (line 19)
* filenames, assignments as: Ignoring Assigns. (line 6)
-* files, .mo: Explaining gettext. (line 41)
-* files, .mo, converting from .po: I18N Example. (line 62)
-* files, .mo, specifying directory of <1>: Programmer i18n. (line 47)
-* files, .mo, specifying directory of: Explaining gettext. (line 53)
+* files, .gmo: Explaining gettext. (line 42)
+* files, .gmo, specifying directory of <1>: Programmer i18n. (line 47)
+* files, .gmo, specifying directory of: Explaining gettext. (line 54)
+* files, .mo, converting from .po: I18N Example. (line 64)
* files, .po <1>: Translator i18n. (line 6)
-* files, .po: Explaining gettext. (line 36)
-* files, .po, converting to .mo: I18N Example. (line 62)
-* files, .pot: Explaining gettext. (line 30)
-* files, /dev/... special files: Special FD. (line 46)
+* files, .po: Explaining gettext. (line 37)
+* files, .po, converting to .mo: I18N Example. (line 64)
+* files, .pot: Explaining gettext. (line 31)
+* files, /dev/... special files: Special FD. (line 48)
* files, /inet/... (gawk): TCP/IP Networking. (line 6)
* files, /inet4/... (gawk): TCP/IP Networking. (line 6)
* files, /inet6/... (gawk): TCP/IP Networking. (line 6)
-* files, as single records: Records. (line 196)
* files, awk programs in: Long. (line 6)
-* files, awkprof.out: Profiling. (line 10)
-* files, awkvars.out: Options. (line 90)
+* files, awkprof.out: Profiling. (line 6)
+* files, awkvars.out: Options. (line 93)
* files, closing: I/O Functions. (line 10)
* files, descriptors, See file descriptors: Special FD. (line 6)
* files, group: Group Functions. (line 6)
-* files, information about, retrieving: Sample Library. (line 6)
* files, initialization and cleanup: Filetrans Function. (line 6)
* files, input, See input files: Read Terminal. (line 17)
* files, log, timestamps in: Time Functions. (line 6)
* files, managing: Data File Management.
(line 6)
* files, managing, data file boundaries: Filetrans Function. (line 6)
-* files, message object: Explaining gettext. (line 41)
+* files, message object: Explaining gettext. (line 42)
* files, message object, converting from portable object files: I18N Example.
- (line 62)
+ (line 64)
* files, message object, specifying directory of <1>: Programmer i18n.
(line 47)
* files, message object, specifying directory of: Explaining gettext.
- (line 53)
-* files, multiple passes over: Other Arguments. (line 49)
+ (line 54)
+* files, multiple passes over: Other Arguments. (line 56)
* files, multiple, duplicating output into: Tee Program. (line 6)
* files, output, See output files: Close Files And Pipes.
(line 6)
* files, password: Passwd Functions. (line 16)
* files, portable object <1>: Translator i18n. (line 6)
-* files, portable object: Explaining gettext. (line 36)
-* files, portable object template: Explaining gettext. (line 30)
+* files, portable object: Explaining gettext. (line 37)
+* files, portable object template: Explaining gettext. (line 31)
* files, portable object, converting to message object files: I18N Example.
- (line 62)
-* files, portable object, generating: Options. (line 135)
-* files, processing, ARGIND variable and: Auto-set. (line 47)
+ (line 64)
+* files, portable object, generating: Options. (line 147)
+* files, processing, ARGIND variable and: Auto-set. (line 51)
* files, reading: Rewind Function. (line 6)
* files, reading, multiline records: Multiple Line. (line 6)
* files, searching for regular expressions: Egrep Program. (line 6)
* files, skipping: File Checking. (line 6)
-* files, source, search path for: Igawk Program. (line 368)
+* files, source, search path for: Programs Exercises. (line 70)
* files, splitting: Split Program. (line 6)
* files, Texinfo, extracting programs from: Extract Program. (line 6)
-* finish debugger command: Dgawk Execution Control.
+* find substring in string: String Functions. (line 156)
+* finding extensions: Finding Extensions. (line 6)
+* finish debugger command: Debugger Execution Control.
(line 39)
-* Fish, Fred: Contributors. (line 51)
-* fixed-width data: Constant Size. (line 9)
+* Fish, Fred: Contributors. (line 50)
+* fixed-width data: Constant Size. (line 6)
* flag variables <1>: Tee Program. (line 20)
-* flag variables: Boolean Ops. (line 67)
-* floating-point, numbers <1>: Unexpected Results. (line 6)
-* floating-point, numbers: Basic Data Typing. (line 21)
-* floating-point, numbers, AWKNUM internal type: Internals. (line 19)
-* FNR variable <1>: Auto-set. (line 102)
+* flag variables: Boolean Ops. (line 69)
+* floating-point, numbers, arbitrary precision: Arbitrary Precision Arithmetic.
+ (line 6)
+* floating-point, VAX/VMS: VMS Running. (line 50)
+* flush buffered output: I/O Functions. (line 28)
+* fnmatch() extension function: Extension Sample Fnmatch.
+ (line 12)
+* FNR variable <1>: Auto-set. (line 114)
* FNR variable: Records. (line 6)
-* FNR variable, changing: Auto-set. (line 207)
+* FNR variable, changing: Auto-set. (line 328)
* for statement: For Statement. (line 6)
-* for statement, in arrays: Scanning an Array. (line 20)
-* force_number() internal function: Internals. (line 27)
-* force_string() internal function: Internals. (line 32)
-* force_wstring() internal function: Internals. (line 37)
+* for statement, looping over arrays: Scanning an Array. (line 20)
+* fork() extension function: Extension Sample Fork.
+ (line 11)
+* format specifiers: Basic Printf. (line 15)
* format specifiers, mixing regular with positional specifiers: Printf Ordering.
(line 57)
* format specifiers, printf statement: Control Letters. (line 6)
* format specifiers, strftime() function (gawk): Time Functions.
- (line 87)
-* format strings: Basic Printf. (line 15)
+ (line 89)
+* format time string: Time Functions. (line 48)
* formats, numeric output: OFMT. (line 6)
* formatting output: Printf. (line 6)
-* forward slash (/): Regexp. (line 10)
+* formatting strings: String Functions. (line 383)
+* forward slash (/) to enclose regular expressions: Regexp. (line 10)
* forward slash (/), / operator: Precedence. (line 55)
* forward slash (/), /= operator <1>: Precedence. (line 95)
-* forward slash (/), /= operator: Assignment Ops. (line 129)
+* forward slash (/), /= operator: Assignment Ops. (line 130)
* forward slash (/), /= operator, vs. /=.../ regexp constant: Assignment Ops.
(line 148)
* forward slash (/), patterns and: Expression Patterns. (line 24)
-* FPAT variable <1>: User-modified. (line 45)
+* FPAT variable <1>: User-modified. (line 43)
* FPAT variable: Splitting By Content.
- (line 26)
-* frame debugger command: Dgawk Stack. (line 25)
+ (line 25)
+* frame debugger command: Execution Stack. (line 27)
* Free Documentation License (FDL): GNU Free Documentation License.
- (line 6)
-* Free Software Foundation (FSF) <1>: Glossary. (line 301)
+ (line 7)
+* Free Software Foundation (FSF) <1>: Glossary. (line 288)
* Free Software Foundation (FSF) <2>: Getting. (line 10)
* Free Software Foundation (FSF): Manual History. (line 6)
* FreeBSD: Glossary. (line 611)
-* FS variable <1>: User-modified. (line 56)
-* FS variable: Field Separators. (line 14)
+* FS variable <1>: User-modified. (line 50)
+* FS variable: Field Separators. (line 15)
* FS variable, --field-separator option and: Options. (line 21)
* FS variable, as null string: Single Character Fields.
(line 20)
-* FS variable, as TAB character: Options. (line 211)
-* FS variable, changing value of: Field Separators. (line 34)
-* FS variable, running awk programs and: Cut Program. (line 68)
+* FS variable, as TAB character: Options. (line 266)
+* FS variable, changing value of: Field Separators. (line 35)
+* FS variable, running awk programs and: Cut Program. (line 63)
* FS variable, setting from command line: Command Line Field Separator.
(line 6)
* FS, containing ^: Regexp Field Splitting.
(line 59)
-* FSF (Free Software Foundation) <1>: Glossary. (line 301)
+* FS, in multiline records: Multiple Line. (line 41)
+* FSF (Free Software Foundation) <1>: Glossary. (line 288)
* FSF (Free Software Foundation) <2>: Getting. (line 10)
* FSF (Free Software Foundation): Manual History. (line 6)
+* fts() extension function: Extension Sample File Functions.
+ (line 61)
+* FUNCTAB array: Auto-set. (line 130)
* function calls: Function Calls. (line 6)
* function calls, indirect: Indirect Calls. (line 6)
+* function calls, indirect, @-notation for: Indirect Calls. (line 47)
+* function definition example: Function Example. (line 6)
* function pointers: Indirect Calls. (line 6)
* functions, arrays as parameters to: Pass By Value/Reference.
- (line 47)
+ (line 44)
* functions, built-in <1>: Functions. (line 6)
* functions, built-in: Function Calls. (line 10)
-* functions, built-in, adding to gawk: Dynamic Extensions. (line 10)
* functions, built-in, evaluation order: Calling Built-in. (line 30)
-* functions, defining: Definition Syntax. (line 6)
+* functions, defining: Definition Syntax. (line 9)
* functions, library: Library Functions. (line 6)
* functions, library, assertions: Assert Function. (line 6)
-* functions, library, associative arrays and: Library Names. (line 57)
+* functions, library, associative arrays and: Library Names. (line 58)
* functions, library, C library: Getopt Function. (line 6)
* functions, library, character values as numbers: Ordinal Functions.
(line 6)
@@ -25984,259 +32868,278 @@ Index
(line 6)
* functions, library, managing data files: Data File Management.
(line 6)
-* functions, library, managing time: Gettimeofday Function.
+* functions, library, managing time: Getlocaltime Function.
(line 6)
* functions, library, merging arrays into strings: Join Function.
(line 6)
* functions, library, rounding numbers: Round Function. (line 6)
* functions, library, user database, reading: Passwd Functions.
(line 6)
-* functions, names of <1>: Definition Syntax. (line 20)
-* functions, names of: Arrays. (line 18)
-* functions, recursive: Definition Syntax. (line 73)
-* functions, return values, setting: Internals. (line 130)
+* functions, names of: Definition Syntax. (line 23)
+* functions, recursive: Definition Syntax. (line 83)
* functions, string-translation: I18N Functions. (line 6)
* functions, undefined: Pass By Value/Reference.
- (line 71)
+ (line 68)
* functions, user-defined: User-defined. (line 6)
-* functions, user-defined, calling: Calling A Function. (line 6)
-* functions, user-defined, counts: Profiling. (line 132)
+* functions, user-defined, calling: Function Caveats. (line 6)
+* functions, user-defined, counts, in a profile: Profiling. (line 137)
* functions, user-defined, library of: Library Functions. (line 6)
* functions, user-defined, next/nextfile statements and <1>: Nextfile Statement.
- (line 44)
+ (line 47)
* functions, user-defined, next/nextfile statements and: Next Statement.
- (line 45)
-* G-d: Acknowledgments. (line 81)
-* Garfinkle, Scott: Contributors. (line 35)
-* gawk, ARGIND variable in: Other Arguments. (line 12)
+ (line 44)
+* G-d: Acknowledgments. (line 94)
+* Garfinkle, Scott: Contributors. (line 34)
+* gawk program, dynamic profiling: Profiling. (line 178)
+* gawk version: Auto-set. (line 221)
+* gawk, ARGIND variable in: Other Arguments. (line 15)
* gawk, awk and <1>: This Manual. (line 14)
-* gawk, awk and: Preface. (line 23)
-* gawk, bitwise operations in: Bitwise Functions. (line 39)
+* gawk, awk and: Preface. (line 21)
+* gawk, bitwise operations in: Bitwise Functions. (line 40)
* gawk, break statement in: Break Statement. (line 51)
-* gawk, built-in variables and: Built-in Variables. (line 14)
-* gawk, character classes and: Bracket Expressions. (line 90)
+* gawk, character classes and: Bracket Expressions. (line 100)
* gawk, coding style in: Adding Code. (line 38)
-* gawk, command-line options: GNU Regexp Operators.
+* gawk, command-line options, and regular expressions: GNU Regexp Operators.
(line 70)
-* gawk, comparison operators and: Comparison Operators.
- (line 50)
* gawk, configuring: Configuration Philosophy.
(line 6)
* gawk, configuring, options: Additional Configuration Options.
(line 6)
-* gawk, continue statement in: Continue Statement. (line 43)
+* gawk, continue statement in: Continue Statement. (line 44)
* gawk, distribution: Distribution contents.
(line 6)
* gawk, ERRNO variable in <1>: TCP/IP Networking. (line 54)
-* gawk, ERRNO variable in <2>: Auto-set. (line 72)
+* gawk, ERRNO variable in <2>: Auto-set. (line 88)
* gawk, ERRNO variable in <3>: BEGINFILE/ENDFILE. (line 26)
* gawk, ERRNO variable in <4>: Close Files And Pipes.
- (line 139)
+ (line 141)
* gawk, ERRNO variable in: Getline. (line 19)
-* gawk, escape sequences: Escape Sequences. (line 125)
-* gawk, extensions, disabling: Options. (line 199)
+* gawk, escape sequences: Escape Sequences. (line 120)
+* gawk, extensions, disabling: Options. (line 254)
* gawk, features, adding: Adding Code. (line 6)
* gawk, features, advanced: Advanced Features. (line 6)
-* gawk, fflush() function in: I/O Functions. (line 44)
-* gawk, field separators and: User-modified. (line 77)
-* gawk, FIELDWIDTHS variable in <1>: User-modified. (line 35)
+* gawk, field separators and: User-modified. (line 71)
+* gawk, FIELDWIDTHS variable in <1>: User-modified. (line 37)
* gawk, FIELDWIDTHS variable in: Constant Size. (line 22)
* gawk, file names in: Special Files. (line 6)
* gawk, format-control characters: Control Letters. (line 18)
-* gawk, FPAT variable in <1>: User-modified. (line 45)
+* gawk, FPAT variable in <1>: User-modified. (line 43)
* gawk, FPAT variable in: Splitting By Content.
- (line 26)
+ (line 25)
+* gawk, FUNCTAB array in: Auto-set. (line 130)
* gawk, function arguments and: Calling Built-in. (line 16)
-* gawk, functions, adding: Dynamic Extensions. (line 10)
* gawk, hexadecimal numbers and: Nondecimal-numbers. (line 42)
* gawk, IGNORECASE variable in <1>: Array Sorting Functions.
- (line 78)
-* gawk, IGNORECASE variable in <2>: String Functions. (line 29)
-* gawk, IGNORECASE variable in <3>: Array Intro. (line 92)
-* gawk, IGNORECASE variable in <4>: User-modified. (line 82)
+ (line 83)
+* gawk, IGNORECASE variable in <2>: String Functions. (line 58)
+* gawk, IGNORECASE variable in <3>: Array Intro. (line 94)
+* gawk, IGNORECASE variable in <4>: User-modified. (line 76)
* gawk, IGNORECASE variable in: Case-sensitivity. (line 26)
* gawk, implementation issues: Notes. (line 6)
* gawk, implementation issues, debugging: Compatibility Mode. (line 6)
* gawk, implementation issues, downward compatibility: Compatibility Mode.
(line 6)
* gawk, implementation issues, limits: Getline Notes. (line 14)
-* gawk, implementation issues, pipes: Redirection. (line 135)
+* gawk, implementation issues, pipes: Redirection. (line 129)
* gawk, installing: Installation. (line 6)
-* gawk, internals: Internals. (line 6)
* gawk, internationalization and, See internationalization: Internationalization.
(line 13)
* gawk, interpreter, adding code to: Using Internal File Ops.
(line 6)
* gawk, interval expressions and: Regexp Operators. (line 139)
* gawk, line continuation in: Conditional Exp. (line 34)
-* gawk, LINT variable in: User-modified. (line 98)
+* gawk, LINT variable in: User-modified. (line 88)
* gawk, list of contributors to: Contributors. (line 6)
-* gawk, MS-DOS version of: PC Using. (line 11)
-* gawk, MS-Windows version of: PC Using. (line 11)
+* gawk, MS-DOS version of: PC Using. (line 10)
+* gawk, MS-Windows version of: PC Using. (line 10)
* gawk, newlines in: Statements/Lines. (line 12)
* gawk, octal numbers and: Nondecimal-numbers. (line 42)
-* gawk, OS/2 version of: PC Using. (line 11)
-* gawk, PROCINFO array in <1>: Two-way I/O. (line 116)
-* gawk, PROCINFO array in <2>: Time Functions. (line 46)
-* gawk, PROCINFO array in: Auto-set. (line 123)
+* gawk, OS/2 version of: PC Using. (line 16)
+* gawk, predefined variables and: Built-in Variables. (line 14)
+* gawk, PROCINFO array in <1>: Two-way I/O. (line 99)
+* gawk, PROCINFO array in <2>: Time Functions. (line 47)
+* gawk, PROCINFO array in: Auto-set. (line 144)
* gawk, regexp constants and: Using Constant Regexps.
(line 28)
* gawk, regular expressions, case sensitivity: Case-sensitivity.
(line 26)
* gawk, regular expressions, operators: GNU Regexp Operators.
(line 6)
-* gawk, regular expressions, precedence: Regexp Operators. (line 157)
-* gawk, RT variable in <1>: Auto-set. (line 196)
-* gawk, RT variable in <2>: Getline/Variable/File.
- (line 10)
-* gawk, RT variable in <3>: Multiple Line. (line 129)
-* gawk, RT variable in: Records. (line 112)
-* gawk, See Also awk: Preface. (line 36)
+* gawk, regular expressions, precedence: Regexp Operators. (line 161)
+* gawk, RT variable in <1>: Auto-set. (line 279)
+* gawk, RT variable in <2>: Multiple Line. (line 129)
+* gawk, RT variable in: awk split records. (line 125)
+* gawk, See Also awk: Preface. (line 34)
* gawk, source code, obtaining: Getting. (line 6)
* gawk, splitting fields and: Constant Size. (line 87)
* gawk, string-translation functions: I18N Functions. (line 6)
-* gawk, TEXTDOMAIN variable in: User-modified. (line 153)
+* gawk, SYMTAB array in: Auto-set. (line 283)
+* gawk, TEXTDOMAIN variable in: User-modified. (line 151)
* gawk, timestamps: Time Functions. (line 6)
-* gawk, uses for: Preface. (line 36)
-* gawk, versions of, information about, printing: Options. (line 250)
+* gawk, uses for: Preface. (line 34)
+* gawk, versions of, information about, printing: Options. (line 300)
* gawk, VMS version of: VMS Installation. (line 6)
* gawk, word-boundary operator: GNU Regexp Operators.
(line 63)
-* General Public License (GPL): Glossary. (line 310)
+* gawkextlib: gawkextlib. (line 6)
+* gawkextlib project: gawkextlib. (line 6)
+* gawklibpath_append shell function: Shell Startup Files. (line 29)
+* gawklibpath_default shell function: Shell Startup Files. (line 22)
+* gawklibpath_prepend shell function: Shell Startup Files. (line 25)
+* gawkpath_append shell function: Shell Startup Files. (line 19)
+* gawkpath_default shell function: Shell Startup Files. (line 12)
+* gawkpath_prepend shell function: Shell Startup Files. (line 15)
+* General Public License (GPL): Glossary. (line 305)
* General Public License, See GPL: Manual History. (line 11)
-* gensub() function (gawk) <1>: String Functions. (line 86)
-* gensub() function (gawk): Using Constant Regexps.
+* generate time values: Time Functions. (line 25)
+* gensub <1>: String Functions. (line 90)
+* gensub: Using Constant Regexps.
(line 43)
* gensub() function (gawk), escape processing: Gory Details. (line 6)
-* get_actual_argument() internal function: Internals. (line 116)
-* get_argument() internal function: Internals. (line 111)
-* get_array_argument() internal macro: Internals. (line 127)
-* get_record() input method: Internals. (line 151)
-* get_scalar_argument() internal macro: Internals. (line 124)
* getaddrinfo() function (C library): TCP/IP Networking. (line 38)
* getgrent() function (C library): Group Functions. (line 6)
* getgrent() user-defined function: Group Functions. (line 6)
-* getgrgid() function (C library): Group Functions. (line 186)
-* getgrgid() user-defined function: Group Functions. (line 189)
-* getgrnam() function (C library): Group Functions. (line 175)
-* getgrnam() user-defined function: Group Functions. (line 180)
-* getgruser() function (C library): Group Functions. (line 195)
-* getgruser() function, user-defined: Group Functions. (line 198)
+* getgrgid() function (C library): Group Functions. (line 182)
+* getgrgid() user-defined function: Group Functions. (line 185)
+* getgrnam() function (C library): Group Functions. (line 171)
+* getgrnam() user-defined function: Group Functions. (line 176)
+* getgruser() function (C library): Group Functions. (line 191)
+* getgruser() function, user-defined: Group Functions. (line 194)
* getline command: Reading Files. (line 20)
* getline command, _gr_init() user-defined function: Group Functions.
- (line 82)
+ (line 83)
* getline command, _pw_init() function: Passwd Functions. (line 154)
* getline command, coprocesses, using from <1>: Close Files And Pipes.
(line 6)
* getline command, coprocesses, using from: Getline/Coprocess.
(line 6)
-* getline command, deadlock and: Two-way I/O. (line 70)
+* getline command, deadlock and: Two-way I/O. (line 52)
* getline command, explicit input with: Getline. (line 6)
* getline command, FILENAME variable and: Getline Notes. (line 19)
* getline command, return values: Getline. (line 19)
* getline command, variants: Getline Summary. (line 6)
+* getline from a file: Getline/File. (line 6)
+* getline into a variable: Getline/Variable. (line 6)
* getline statement, BEGINFILE/ENDFILE patterns and: BEGINFILE/ENDFILE.
(line 54)
+* getlocaltime() user-defined function: Getlocaltime Function.
+ (line 16)
* getopt() function (C library): Getopt Function. (line 15)
* getopt() user-defined function: Getopt Function. (line 108)
* getpwent() function (C library): Passwd Functions. (line 16)
* getpwent() user-defined function: Passwd Functions. (line 16)
-* getpwnam() function (C library): Passwd Functions. (line 177)
-* getpwnam() user-defined function: Passwd Functions. (line 182)
-* getpwuid() function (C library): Passwd Functions. (line 188)
-* getpwuid() user-defined function: Passwd Functions. (line 192)
+* getpwnam() function (C library): Passwd Functions. (line 174)
+* getpwnam() user-defined function: Passwd Functions. (line 179)
+* getpwuid() function (C library): Passwd Functions. (line 185)
+* getpwuid() user-defined function: Passwd Functions. (line 189)
* gettext library: Explaining gettext. (line 6)
-* gettext library, locale categories: Explaining gettext. (line 80)
-* gettext() function (C library): Explaining gettext. (line 62)
-* gettimeofday() user-defined function: Gettimeofday Function.
- (line 16)
+* gettext library, locale categories: Explaining gettext. (line 81)
+* gettext() function (C library): Explaining gettext. (line 63)
+* gettimeofday() extension function: Extension Sample Time.
+ (line 12)
+* git utility <1>: Adding Code. (line 111)
+* git utility <2>: Accessing The Source.
+ (line 10)
+* git utility <3>: Other Versions. (line 29)
+* git utility: gawkextlib. (line 27)
+* Git, use of for gawk source code: Derived Files. (line 6)
* GNITS mailing list: Acknowledgments. (line 52)
-* GNU awk, See gawk: Preface. (line 49)
+* GNU awk, See gawk: Preface. (line 51)
* GNU Free Documentation License: GNU Free Documentation License.
- (line 6)
-* GNU General Public License: Glossary. (line 310)
-* GNU Lesser General Public License: Glossary. (line 397)
+ (line 7)
+* GNU General Public License: Glossary. (line 305)
+* GNU Lesser General Public License: Glossary. (line 396)
* GNU long options <1>: Options. (line 6)
* GNU long options: Command Line. (line 13)
-* GNU long options, printing list of: Options. (line 142)
-* GNU Project <1>: Glossary. (line 319)
+* GNU long options, printing list of: Options. (line 154)
+* GNU Project <1>: Glossary. (line 314)
* GNU Project: Manual History. (line 11)
* GNU/Linux <1>: Glossary. (line 611)
* GNU/Linux <2>: I18N Example. (line 55)
* GNU/Linux: Manual History. (line 28)
-* GPL (General Public License) <1>: Glossary. (line 310)
+* Gordon, Assaf: Contributors. (line 105)
+* GPL (General Public License) <1>: Glossary. (line 305)
* GPL (General Public License): Manual History. (line 11)
-* GPL (General Public License), printing: Options. (line 85)
+* GPL (General Public License), printing: Options. (line 88)
* grcat program: Group Functions. (line 16)
-* Grigera, Juan: Contributors. (line 58)
+* Grigera, Juan: Contributors. (line 57)
* group database, reading: Group Functions. (line 6)
* group file: Group Functions. (line 6)
+* group ID of gawk user: Auto-set. (line 194)
* groups, information about: Group Functions. (line 6)
-* gsub() function <1>: String Functions. (line 139)
-* gsub() function: Using Constant Regexps.
+* gsub <1>: String Functions. (line 140)
+* gsub: Using Constant Regexps.
(line 43)
* gsub() function, arguments of: String Functions. (line 462)
* gsub() function, escape processing: Gory Details. (line 6)
-* h debugger command (alias for help): Miscellaneous Dgawk Commands.
- (line 68)
-* Hankerson, Darrel <1>: Contributors. (line 61)
+* h debugger command (alias for help): Miscellaneous Debugger Commands.
+ (line 66)
+* Hankerson, Darrel <1>: Contributors. (line 60)
* Hankerson, Darrel: Acknowledgments. (line 60)
-* Haque, John <1>: Contributors. (line 103)
-* Haque, John: Acknowledgments. (line 60)
+* Haque, John: Contributors. (line 108)
* Hartholz, Elaine: Acknowledgments. (line 38)
* Hartholz, Marshall: Acknowledgments. (line 38)
* Hasegawa, Isamu: Contributors. (line 94)
-* help debugger command: Miscellaneous Dgawk Commands.
- (line 68)
+* help debugger command: Miscellaneous Debugger Commands.
+ (line 66)
* hexadecimal numbers: Nondecimal-numbers. (line 6)
-* hexadecimal values, enabling interpretation of: Options. (line 166)
+* hexadecimal values, enabling interpretation of: Options. (line 211)
+* history expansion, in debugger: Readline Support. (line 6)
* histsort.awk program: History Sorting. (line 25)
* Hughes, Phil: Acknowledgments. (line 43)
-* HUP signal: Profiling. (line 204)
+* HUP signal, for dynamic profiling: Profiling. (line 210)
* hyphen (-), - operator: Precedence. (line 52)
-* hyphen (-), -- (decrement/increment) operators: Precedence. (line 46)
+* hyphen (-), -- operator <1>: Precedence. (line 46)
* hyphen (-), -- operator: Increment Ops. (line 48)
* hyphen (-), -= operator <1>: Precedence. (line 95)
-* hyphen (-), -= operator: Assignment Ops. (line 129)
+* hyphen (-), -= operator: Assignment Ops. (line 130)
* hyphen (-), filenames beginning with: Options. (line 59)
* hyphen (-), in bracket expressions: Bracket Expressions. (line 17)
-* i debugger command (alias for info): Dgawk Info. (line 12)
+* i debugger command (alias for info): Debugger Info. (line 13)
* id utility: Id Program. (line 6)
* id.awk program: Id Program. (line 30)
-* if statement <1>: If Statement. (line 6)
-* if statement: Regexp Usage. (line 19)
+* if statement: If Statement. (line 6)
* if statement, actions, changing: Ranges. (line 25)
+* if statement, use of regexps in: Regexp Usage. (line 19)
* igawk.sh program: Igawk Program. (line 124)
-* ignore debugger command: Breakpoint Control. (line 86)
-* IGNORECASE variable <1>: Array Sorting Functions.
- (line 78)
-* IGNORECASE variable <2>: String Functions. (line 29)
-* IGNORECASE variable <3>: Array Intro. (line 92)
-* IGNORECASE variable <4>: User-modified. (line 82)
-* IGNORECASE variable: Case-sensitivity. (line 26)
-* IGNORECASE variable, array sorting and: Array Sorting Functions.
- (line 78)
-* IGNORECASE variable, array subscripts and: Array Intro. (line 92)
+* ignore breakpoint: Breakpoint Control. (line 87)
+* ignore debugger command: Breakpoint Control. (line 87)
+* IGNORECASE variable: User-modified. (line 76)
+* IGNORECASE variable, and array indices: Array Intro. (line 94)
+* IGNORECASE variable, and array sorting functions: Array Sorting Functions.
+ (line 83)
* IGNORECASE variable, in example programs: Library Functions.
- (line 42)
+ (line 53)
+* IGNORECASE variable, with ~ and !~ operators: Case-sensitivity.
+ (line 26)
+* Illumos: Other Versions. (line 109)
+* Illumos, POSIX-compliant awk: Other Versions. (line 109)
* implementation issues, gawk: Notes. (line 6)
* implementation issues, gawk, debugging: Compatibility Mode. (line 6)
-* implementation issues, gawk, limits <1>: Redirection. (line 135)
+* implementation issues, gawk, limits <1>: Redirection. (line 129)
* implementation issues, gawk, limits: Getline Notes. (line 14)
-* in operator <1>: Id Program. (line 93)
-* in operator <2>: For Statement. (line 75)
-* in operator <3>: Precedence. (line 83)
+* in operator <1>: For Statement. (line 76)
+* in operator <2>: Precedence. (line 83)
* in operator: Comparison Operators.
(line 11)
-* in operator, arrays and <1>: Scanning an Array. (line 17)
-* in operator, arrays and: Reference to Elements.
- (line 37)
+* in operator, index existence in multidimensional arrays: Multidimensional.
+ (line 43)
+* in operator, order of array access: Scanning an Array. (line 48)
+* in operator, testing if array element exists: Reference to Elements.
+ (line 38)
+* in operator, use in loops: Scanning an Array. (line 17)
+* including files, @include directive: Include Files. (line 8)
* increment operators: Increment Ops. (line 6)
-* index() function: String Functions. (line 155)
+* index: String Functions. (line 156)
* indexing arrays: Array Intro. (line 50)
* indirect function calls: Indirect Calls. (line 6)
-* info debugger command: Dgawk Info. (line 12)
+* indirect function calls, @-notation: Indirect Calls. (line 47)
+* infinite precision: Arbitrary Precision Arithmetic.
+ (line 6)
+* info debugger command: Debugger Info. (line 13)
* initialization, automatic: More Complex. (line 38)
+* inplace extension: Extension Sample Inplace.
+ (line 6)
* input files: Reading Files. (line 6)
* input files, closing: Close Files And Pipes.
(line 6)
@@ -26244,8 +33147,9 @@ Index
* input files, examples: Sample Data Files. (line 6)
* input files, reading: Reading Files. (line 6)
* input files, running awk without: Read Terminal. (line 6)
-* input files, variable assignments and: Other Arguments. (line 19)
-* input pipeline: Getline/Pipe. (line 6)
+* input files, variable assignments and: Other Arguments. (line 26)
+* input pipeline: Getline/Pipe. (line 9)
+* input record, length of: String Functions. (line 178)
* input redirection: Getline/File. (line 6)
* input, data, nondecimal: Nondecimal Data. (line 6)
* input, explicit: Getline. (line 6)
@@ -26254,111 +33158,88 @@ Index
* input, splitting into records: Records. (line 6)
* input, standard <1>: Special FD. (line 6)
* input, standard: Read Terminal. (line 6)
-* input/output, binary: User-modified. (line 10)
+* input/output functions: I/O Functions. (line 6)
+* input/output, binary: User-modified. (line 15)
* input/output, from BEGIN and END: I/O And BEGIN/END. (line 6)
-* input/output, two-way: Two-way I/O. (line 44)
+* input/output, two-way: Two-way I/O. (line 25)
* insomnia, cure for: Alarm Program. (line 6)
* installation, VMS: VMS Installation. (line 6)
* installing gawk: Installation. (line 6)
-* INT signal (MS-Windows): Profiling. (line 207)
-* int() function: Numeric Functions. (line 22)
-* integers: Basic Data Typing. (line 21)
-* integers, unsigned: Basic Data Typing. (line 30)
-* interacting with other programs: I/O Functions. (line 63)
-* internal constant, INVALID_HANDLE: Internals. (line 151)
-* internal function, assoc_clear(): Internals. (line 68)
-* internal function, assoc_lookup(): Internals. (line 72)
-* internal function, dupnode(): Internals. (line 87)
-* internal function, force_number(): Internals. (line 27)
-* internal function, force_string(): Internals. (line 32)
-* internal function, force_wstring(): Internals. (line 37)
-* internal function, get_actual_argument(): Internals. (line 116)
-* internal function, get_argument(): Internals. (line 111)
-* internal function, iop_alloc(): Internals. (line 151)
-* internal function, make_builtin(): Internals. (line 97)
-* internal function, make_number(): Internals. (line 82)
-* internal function, make_string(): Internals. (line 77)
-* internal function, register_deferred_variable(): Internals. (line 140)
-* internal function, register_open_hook(): Internals. (line 151)
-* internal function, unref(): Internals. (line 92)
-* internal function, update_ERRNO(): Internals. (line 130)
-* internal function, update_ERRNO_saved(): Internals. (line 135)
-* internal macro, get_array_argument(): Internals. (line 127)
-* internal macro, get_scalar_argument(): Internals. (line 124)
-* internal structure, IOBUF: Internals. (line 151)
-* internal type, AWKNUM: Internals. (line 19)
-* internal type, NODE: Internals. (line 23)
-* internal variable, nargs: Internals. (line 42)
-* internal variable, stlen: Internals. (line 46)
-* internal variable, stptr: Internals. (line 46)
-* internal variable, type: Internals. (line 59)
-* internal variable, vname: Internals. (line 64)
-* internal variable, wstlen: Internals. (line 54)
-* internal variable, wstptr: Internals. (line 54)
+* instruction tracing, in debugger: Debugger Info. (line 89)
+* int: Numeric Functions. (line 38)
+* INT signal (MS-Windows): Profiling. (line 213)
+* integer array indices: Numeric Array Subscripts.
+ (line 31)
+* integers, arbitrary precision: Arbitrary Precision Integers.
+ (line 6)
+* integers, unsigned: Computer Arithmetic. (line 41)
+* interacting with other programs: I/O Functions. (line 106)
* internationalization <1>: I18N and L10N. (line 6)
* internationalization: I18N Functions. (line 6)
* internationalization, localization <1>: Internationalization.
(line 13)
-* internationalization, localization: User-modified. (line 153)
+* internationalization, localization: User-modified. (line 151)
* internationalization, localization, character classes: Bracket Expressions.
- (line 90)
+ (line 100)
* internationalization, localization, gawk and: Internationalization.
(line 13)
* internationalization, localization, locale categories: Explaining gettext.
- (line 80)
+ (line 81)
* internationalization, localization, marked strings: Programmer i18n.
(line 14)
* internationalization, localization, portability and: I18N Portability.
(line 6)
* internationalizing a program: Explaining gettext. (line 6)
-* interpreted programs <1>: Glossary. (line 361)
-* interpreted programs: Basic High Level. (line 14)
-* interval expressions: Regexp Operators. (line 116)
-* INVALID_HANDLE internal constant: Internals. (line 151)
+* interpreted programs <1>: Glossary. (line 356)
+* interpreted programs: Basic High Level. (line 15)
+* interval expressions, regexp operator: Regexp Operators. (line 116)
* inventory-shipped file: Sample Data Files. (line 32)
-* IOBUF internal structure: Internals. (line 151)
-* iop_alloc() internal function: Internals. (line 151)
-* isarray() function (gawk): Type Functions. (line 11)
-* ISO: Glossary. (line 372)
-* ISO 8859-1: Glossary. (line 141)
-* ISO Latin-1: Glossary. (line 141)
+* invoke shell command: I/O Functions. (line 106)
+* isarray: Type Functions. (line 11)
+* ISO: Glossary. (line 367)
+* ISO 8859-1: Glossary. (line 133)
+* ISO Latin-1: Glossary. (line 133)
* Jacobs, Andrew: Passwd Functions. (line 90)
-* Jaegermann, Michal <1>: Contributors. (line 46)
+* Jaegermann, Michal <1>: Contributors. (line 45)
* Jaegermann, Michal: Acknowledgments. (line 60)
-* Java implementation of awk: Other Versions. (line 96)
-* Java programming language: Glossary. (line 380)
-* jawk: Other Versions. (line 96)
+* Java implementation of awk: Other Versions. (line 117)
+* Java programming language: Glossary. (line 379)
+* jawk: Other Versions. (line 117)
* Jedi knights: Undocumented. (line 6)
+* Johansen, Chris: Signature Program. (line 25)
* join() user-defined function: Join Function. (line 18)
* Kahrs, Ju"rgen <1>: Contributors. (line 70)
* Kahrs, Ju"rgen: Acknowledgments. (line 60)
* Kasal, Stepan: Acknowledgments. (line 60)
* Kenobi, Obi-Wan: Undocumented. (line 6)
-* Kernighan, Brian <1>: Basic Data Typing. (line 74)
-* Kernighan, Brian <2>: Other Versions. (line 13)
-* Kernighan, Brian <3>: Contributors. (line 12)
-* Kernighan, Brian <4>: BTL. (line 6)
-* Kernighan, Brian <5>: Concatenation. (line 6)
-* Kernighan, Brian <6>: Acknowledgments. (line 75)
-* Kernighan, Brian <7>: Conventions. (line 34)
+* Kernighan, Brian <1>: Glossary. (line 143)
+* Kernighan, Brian <2>: Basic Data Typing. (line 54)
+* Kernighan, Brian <3>: Other Versions. (line 13)
+* Kernighan, Brian <4>: Contributors. (line 11)
+* Kernighan, Brian <5>: BTL. (line 6)
+* Kernighan, Brian <6>: Library Functions. (line 12)
+* Kernighan, Brian <7>: Concatenation. (line 6)
+* Kernighan, Brian <8>: Getline/Pipe. (line 6)
+* Kernighan, Brian <9>: Acknowledgments. (line 78)
+* Kernighan, Brian <10>: Conventions. (line 38)
* Kernighan, Brian: History. (line 17)
-* kill command, dynamic profiling: Profiling. (line 182)
+* kill command, dynamic profiling: Profiling. (line 187)
* Knights, jedi: Undocumented. (line 6)
-* Kwok, Conrad: Contributors. (line 35)
-* l debugger command (alias for list): Miscellaneous Dgawk Commands.
- (line 74)
+* Kwok, Conrad: Contributors. (line 34)
+* l debugger command (alias for list): Miscellaneous Debugger Commands.
+ (line 72)
* labels.awk program: Labels Program. (line 51)
-* languages, data-driven: Basic High Level. (line 83)
-* LC_ALL locale category: Explaining gettext. (line 120)
-* LC_COLLATE locale category: Explaining gettext. (line 93)
-* LC_CTYPE locale category: Explaining gettext. (line 97)
-* LC_MESSAGES locale category: Explaining gettext. (line 87)
+* Langston, Peter: Advanced Features. (line 6)
+* languages, data-driven: Basic High Level. (line 85)
+* LC_ALL locale category: Explaining gettext. (line 117)
+* LC_COLLATE locale category: Explaining gettext. (line 94)
+* LC_CTYPE locale category: Explaining gettext. (line 98)
+* LC_MESSAGES locale category: Explaining gettext. (line 88)
* LC_MESSAGES locale category, bindtextdomain() function (gawk): Programmer i18n.
- (line 88)
-* LC_MONETARY locale category: Explaining gettext. (line 103)
-* LC_NUMERIC locale category: Explaining gettext. (line 107)
-* LC_RESPONSE locale category: Explaining gettext. (line 111)
-* LC_TIME locale category: Explaining gettext. (line 115)
+ (line 101)
+* LC_MONETARY locale category: Explaining gettext. (line 104)
+* LC_NUMERIC locale category: Explaining gettext. (line 108)
+* LC_TIME locale category: Explaining gettext. (line 112)
* left angle bracket (<), < operator <1>: Precedence. (line 65)
* left angle bracket (<), < operator: Comparison Operators.
(line 11)
@@ -26366,16 +33247,19 @@ Index
* left angle bracket (<), <= operator <1>: Precedence. (line 65)
* left angle bracket (<), <= operator: Comparison Operators.
(line 11)
+* left shift: Bitwise Functions. (line 47)
* left shift, bitwise: Bitwise Functions. (line 32)
* leftmost longest match: Multiple Line. (line 26)
-* length() function: String Functions. (line 166)
-* Lesser General Public License (LGPL): Glossary. (line 397)
-* LGPL (Lesser General Public License): Glossary. (line 397)
-* libmawk: Other Versions. (line 104)
+* length: String Functions. (line 171)
+* length of input record: String Functions. (line 178)
+* length of string: String Functions. (line 171)
+* Lesser General Public License (LGPL): Glossary. (line 396)
+* LGPL (Lesser General Public License): Glossary. (line 396)
+* libmawk: Other Versions. (line 125)
* libraries of awk functions: Library Functions. (line 6)
* libraries of awk functions, assertions: Assert Function. (line 6)
* libraries of awk functions, associative arrays and: Library Names.
- (line 57)
+ (line 58)
* libraries of awk functions, character values as numbers: Ordinal Functions.
(line 6)
* libraries of awk functions, command-line options: Getopt Function.
@@ -26386,7 +33270,7 @@ Index
(line 6)
* libraries of awk functions, managing, data files: Data File Management.
(line 6)
-* libraries of awk functions, managing, time: Gettimeofday Function.
+* libraries of awk functions, managing, time: Getlocaltime Function.
(line 6)
* libraries of awk functions, merging arrays into strings: Join Function.
(line 6)
@@ -26395,7 +33279,7 @@ Index
* libraries of awk functions, user database, reading: Passwd Functions.
(line 6)
* line breaks: Statements/Lines. (line 6)
-* line continuations: Boolean Ops. (line 62)
+* line continuations: Boolean Ops. (line 64)
* line continuations, gawk: Conditional Exp. (line 34)
* line continuations, in print statement: Print Examples. (line 76)
* line continuations, with C shell: More Complex. (line 30)
@@ -26404,182 +33288,197 @@ Index
* lines, duplicate, removing: History Sorting. (line 6)
* lines, matching ranges of: Ranges. (line 6)
* lines, skipping between markers: Ranges. (line 43)
-* lint checking: User-modified. (line 98)
+* lint checking: User-modified. (line 88)
* lint checking, array elements: Delete. (line 34)
* lint checking, array subscripts: Uninitialized Subscripts.
(line 43)
* lint checking, empty programs: Command Line. (line 16)
-* lint checking, issuing warnings: Options. (line 147)
+* lint checking, issuing warnings: Options. (line 185)
* lint checking, POSIXLY_CORRECT environment variable: Options.
- (line 289)
+ (line 339)
* lint checking, undefined functions: Pass By Value/Reference.
- (line 88)
-* LINT variable: User-modified. (line 98)
+ (line 85)
+* LINT variable: User-modified. (line 88)
* Linux <1>: Glossary. (line 611)
* Linux <2>: I18N Example. (line 55)
* Linux: Manual History. (line 28)
-* list debugger command: Miscellaneous Dgawk Commands.
- (line 74)
-* local variables: Variable Scope. (line 6)
-* locale categories: Explaining gettext. (line 80)
-* locale decimal point character: Options. (line 215)
+* list all global variables, in debugger: Debugger Info. (line 48)
+* list debugger command: Miscellaneous Debugger Commands.
+ (line 72)
+* list function definitions, in debugger: Debugger Info. (line 30)
+* loading extensions, @load directive: Loading Shared Libraries.
+ (line 8)
+* loading, extensions: Options. (line 173)
+* local variables, in a function: Variable Scope. (line 6)
+* locale categories: Explaining gettext. (line 81)
+* locale decimal point character: Options. (line 270)
* locale, definition of: Locales. (line 6)
* localization: I18N and L10N. (line 6)
* localization, See internationalization, localization: I18N and L10N.
(line 6)
+* log: Numeric Functions. (line 43)
* log files, timestamps in: Time Functions. (line 6)
-* log() function: Numeric Functions. (line 29)
+* logarithm: Numeric Functions. (line 43)
* logical false/true: Truth Values. (line 6)
* logical operators, See Boolean expressions: Boolean Ops. (line 6)
* login information: Passwd Functions. (line 16)
* long options: Command Line. (line 13)
* loops: While Statement. (line 6)
-* loops, continue statements and: For Statement. (line 64)
-* loops, count for header: Profiling. (line 126)
+* loops, break statement and: Break Statement. (line 6)
+* loops, continue statements and: For Statement. (line 65)
+* loops, count for header, in a profile: Profiling. (line 131)
+* loops, do-while: Do Statement. (line 6)
* loops, exiting: Break Statement. (line 6)
+* loops, for, array scanning: Scanning an Array. (line 6)
+* loops, for, iterative: For Statement. (line 6)
* loops, See Also while statement: While Statement. (line 6)
-* Lost In Space: Dynamic Extensions. (line 6)
+* loops, while: While Statement. (line 6)
* ls utility: More Complex. (line 15)
-* lshift() function (gawk): Bitwise Functions. (line 45)
+* lshift: Bitwise Functions. (line 47)
* lvalues/rvalues: Assignment Ops. (line 32)
+* mail-list file: Sample Data Files. (line 6)
* mailing labels, printing: Labels Program. (line 6)
* mailing list, GNITS: Acknowledgments. (line 52)
-* make_builtin() internal function: Internals. (line 97)
-* make_number() internal function: Internals. (line 82)
-* make_string() internal function: Internals. (line 77)
+* Malmberg, John <1>: Bugs. (line 70)
+* Malmberg, John: Acknowledgments. (line 60)
+* Malmberg, John E.: Contributors. (line 137)
* mark parity: Ordinal Functions. (line 45)
* marked string extraction (internationalization): String Extraction.
(line 6)
* marked strings, extracting: String Extraction. (line 6)
-* Marx, Groucho: Increment Ops. (line 61)
-* match() function: String Functions. (line 206)
+* Marx, Groucho: Increment Ops. (line 60)
+* match: String Functions. (line 211)
+* match regexp in string: String Functions. (line 211)
* match() function, RSTART/RLENGTH variables: String Functions.
- (line 223)
+ (line 228)
* matching, expressions, See comparison expressions: Typing and Comparison.
(line 9)
* matching, leftmost longest: Multiple Line. (line 26)
-* matching, null strings: Gory Details. (line 163)
-* mawk program: Other Versions. (line 35)
+* matching, null strings: String Functions. (line 536)
+* mawk utility <1>: Other Versions. (line 48)
+* mawk utility <2>: Nextfile Statement. (line 47)
+* mawk utility <3>: Concatenation. (line 36)
+* mawk utility <4>: Getline/Pipe. (line 62)
+* mawk utility: Escape Sequences. (line 120)
+* maximum precision supported by MPFR library: Auto-set. (line 235)
+* McIlroy, Doug: Glossary. (line 177)
* McPhee, Patrick: Contributors. (line 100)
-* memory, releasing: Internals. (line 92)
-* message object files: Explaining gettext. (line 41)
+* message object files: Explaining gettext. (line 42)
* message object files, converting from portable object files: I18N Example.
- (line 62)
+ (line 64)
* message object files, specifying directory of <1>: Programmer i18n.
(line 47)
* message object files, specifying directory of: Explaining gettext.
- (line 53)
-* metacharacters, escape sequences for: Escape Sequences. (line 132)
-* mktime() function (gawk): Time Functions. (line 24)
+ (line 54)
+* messages from extensions: Printing Messages. (line 6)
+* metacharacters in regular expressions: Regexp Operators. (line 6)
+* metacharacters, escape sequences for: Escape Sequences. (line 139)
+* minimum precision supported by MPFR library: Auto-set. (line 238)
+* mktime: Time Functions. (line 25)
* modifiers, in format specifiers: Format Modifiers. (line 6)
-* monetary information, localization: Explaining gettext. (line 103)
-* msgfmt utility: I18N Example. (line 62)
-* n debugger command (alias for next): Dgawk Execution Control.
+* monetary information, localization: Explaining gettext. (line 104)
+* Moore, Duncan: Getline Notes. (line 40)
+* msgfmt utility: I18N Example. (line 64)
+* multiple precision: Arbitrary Precision Arithmetic.
+ (line 6)
+* multiple-line records: Multiple Line. (line 6)
+* n debugger command (alias for next): Debugger Execution Control.
(line 43)
-* names, arrays/variables <1>: Library Names. (line 6)
-* names, arrays/variables: Arrays. (line 18)
+* names, arrays/variables: Library Names. (line 6)
* names, functions <1>: Library Names. (line 6)
-* names, functions: Definition Syntax. (line 20)
-* namespace issues <1>: Library Names. (line 6)
-* namespace issues: Arrays. (line 18)
-* namespace issues, functions: Definition Syntax. (line 20)
-* nargs internal variable: Internals. (line 42)
-* nawk utility: Names. (line 17)
-* negative zero: Unexpected Results. (line 28)
+* names, functions: Definition Syntax. (line 23)
+* namespace issues: Library Names. (line 6)
+* namespace issues, functions: Definition Syntax. (line 23)
* NetBSD: Glossary. (line 611)
* networks, programming: TCP/IP Networking. (line 6)
* networks, support for: Special Network. (line 6)
-* newlines <1>: Boolean Ops. (line 67)
-* newlines <2>: Options. (line 205)
+* newlines <1>: Boolean Ops. (line 69)
+* newlines <2>: Options. (line 260)
* newlines: Statements/Lines. (line 6)
* newlines, as field separators: Default Field Splitting.
(line 6)
-* newlines, as record separators: Records. (line 20)
+* newlines, as record separators: awk split records. (line 12)
* newlines, in dynamic regexps: Computed Regexps. (line 59)
* newlines, in regexp constants: Computed Regexps. (line 69)
* newlines, printing: Print Examples. (line 12)
* newlines, separating statements in actions <1>: Statements. (line 10)
* newlines, separating statements in actions: Action Overview.
(line 19)
-* next debugger command: Dgawk Execution Control.
+* next debugger command: Debugger Execution Control.
(line 43)
+* next file statement: Feature History. (line 169)
* next statement <1>: Next Statement. (line 6)
-* next statement: Boolean Ops. (line 85)
+* next statement: Boolean Ops. (line 95)
* next statement, BEGIN/END patterns and: I/O And BEGIN/END. (line 37)
* next statement, BEGINFILE/ENDFILE patterns and: BEGINFILE/ENDFILE.
(line 49)
-* next statement, user-defined functions and: Next Statement. (line 45)
+* next statement, user-defined functions and: Next Statement. (line 44)
* nextfile statement: Nextfile Statement. (line 6)
* nextfile statement, BEGIN/END patterns and: I/O And BEGIN/END.
(line 37)
* nextfile statement, BEGINFILE/ENDFILE patterns and: BEGINFILE/ENDFILE.
(line 26)
* nextfile statement, user-defined functions and: Nextfile Statement.
- (line 44)
-* nexti debugger command: Dgawk Execution Control.
+ (line 47)
+* nexti debugger command: Debugger Execution Control.
(line 49)
-* NF variable <1>: Auto-set. (line 107)
+* NF variable <1>: Auto-set. (line 119)
* NF variable: Fields. (line 33)
* NF variable, decrementing: Changing Fields. (line 107)
-* ni debugger command (alias for nexti): Dgawk Execution Control.
+* ni debugger command (alias for nexti): Debugger Execution Control.
(line 49)
* noassign.awk program: Ignoring Assigns. (line 15)
-* NODE internal type: Internals. (line 23)
-* nodes, duplicating: Internals. (line 87)
+* non-existent array elements: Reference to Elements.
+ (line 23)
* not Boolean-logic operator: Boolean Ops. (line 6)
-* NR variable <1>: Auto-set. (line 118)
+* NR variable <1>: Auto-set. (line 139)
* NR variable: Records. (line 6)
-* NR variable, changing: Auto-set. (line 207)
-* null strings <1>: Basic Data Typing. (line 50)
+* NR variable, changing: Auto-set. (line 328)
+* null strings <1>: Basic Data Typing. (line 26)
* null strings <2>: Truth Values. (line 6)
* null strings <3>: Regexp Field Splitting.
(line 43)
-* null strings: Records. (line 102)
-* null strings, array elements and: Delete. (line 27)
+* null strings: awk split records. (line 115)
+* null strings in gawk arguments, quoting and: Quoting. (line 82)
+* null strings, and deleting array elements: Delete. (line 27)
* null strings, as array subscripts: Uninitialized Subscripts.
(line 43)
-* null strings, converting numbers to strings: Conversion. (line 21)
-* null strings, matching: Gory Details. (line 163)
-* null strings, quoting and: Quoting. (line 62)
+* null strings, converting numbers to strings: Strings And Numbers.
+ (line 21)
+* null strings, matching: String Functions. (line 536)
+* number as string of bits: Bitwise Functions. (line 110)
+* number of array elements: String Functions. (line 201)
* number sign (#), #! (executable scripts): Executable Scripts.
(line 6)
-* number sign (#), #! (executable scripts), portability issues with: Executable Scripts.
- (line 6)
* number sign (#), commenting: Comments. (line 6)
-* numbers: Internals. (line 82)
* numbers, as array subscripts: Numeric Array Subscripts.
(line 6)
* numbers, as values of characters: Ordinal Functions. (line 6)
* numbers, Cliff random: Cliff Random Function.
(line 6)
-* numbers, converting <1>: Bitwise Functions. (line 107)
-* numbers, converting: Conversion. (line 6)
-* numbers, converting, to strings: User-modified. (line 28)
-* numbers, floating-point: Basic Data Typing. (line 21)
-* numbers, floating-point, AWKNUM internal type: Internals. (line 19)
+* numbers, converting <1>: Bitwise Functions. (line 110)
+* numbers, converting: Strings And Numbers. (line 6)
+* numbers, converting, to strings: User-modified. (line 30)
* numbers, hexadecimal: Nondecimal-numbers. (line 6)
-* numbers, NODE internal type: Internals. (line 23)
* numbers, octal: Nondecimal-numbers. (line 6)
-* numbers, random: Numeric Functions. (line 63)
* numbers, rounding: Round Function. (line 6)
-* numeric, constants: Scalar Constants. (line 6)
+* numeric constants: Scalar Constants. (line 6)
+* numeric functions: Numeric Functions. (line 6)
* numeric, output format: OFMT. (line 6)
* numeric, strings: Variable Typing. (line 6)
-* numeric, values: Internals. (line 27)
-* o debugger command (alias for option): Dgawk Info. (line 56)
-* oawk utility: Names. (line 17)
+* o debugger command (alias for option): Debugger Info. (line 57)
* obsolete features: Obsolete. (line 6)
* octal numbers: Nondecimal-numbers. (line 6)
-* octal values, enabling interpretation of: Options. (line 166)
-* OFMT variable <1>: User-modified. (line 115)
-* OFMT variable <2>: Conversion. (line 55)
+* octal values, enabling interpretation of: Options. (line 211)
+* OFMT variable <1>: User-modified. (line 105)
+* OFMT variable <2>: Strings And Numbers. (line 57)
* OFMT variable: OFMT. (line 15)
* OFMT variable, POSIX awk and: OFMT. (line 27)
-* OFS variable <1>: User-modified. (line 124)
+* OFS variable <1>: User-modified. (line 113)
* OFS variable <2>: Output Separators. (line 6)
* OFS variable: Changing Fields. (line 64)
* OpenBSD: Glossary. (line 611)
-* OpenSolaris: Other Versions. (line 86)
+* OpenSolaris: Other Versions. (line 100)
* operating systems, BSD-based: Manual History. (line 28)
* operating systems, PC, gawk on: PC Using. (line 6)
* operating systems, PC, gawk on, installing: PC Installation.
@@ -26598,44 +33497,44 @@ Index
* operators, input/output <1>: Precedence. (line 65)
* operators, input/output <2>: Redirection. (line 22)
* operators, input/output <3>: Getline/Coprocess. (line 6)
-* operators, input/output <4>: Getline/Pipe. (line 6)
+* operators, input/output <4>: Getline/Pipe. (line 9)
* operators, input/output: Getline/File. (line 6)
* operators, logical, See Boolean expressions: Boolean Ops. (line 6)
* operators, precedence <1>: Precedence. (line 6)
-* operators, precedence: Increment Ops. (line 61)
+* operators, precedence: Increment Ops. (line 60)
* operators, relational, See operators, comparison: Typing and Comparison.
(line 9)
-* operators, short-circuit: Boolean Ops. (line 57)
-* operators, string: Concatenation. (line 9)
+* operators, short-circuit: Boolean Ops. (line 59)
+* operators, string: Concatenation. (line 8)
* operators, string-matching: Regexp Usage. (line 19)
* operators, string-matching, for buffers: GNU Regexp Operators.
(line 48)
* operators, word-boundary (gawk): GNU Regexp Operators.
(line 63)
-* option debugger command: Dgawk Info. (line 56)
-* options, command-line <1>: Command Line Field Separator.
- (line 6)
-* options, command-line <2>: Options. (line 6)
-* options, command-line: Long. (line 12)
+* option debugger command: Debugger Info. (line 57)
+* options, command-line: Options. (line 6)
* options, command-line, end of: Options. (line 54)
* options, command-line, invoking awk: Command Line. (line 6)
* options, command-line, processing: Getopt Function. (line 6)
* options, deprecated: Obsolete. (line 6)
* options, long <1>: Options. (line 6)
* options, long: Command Line. (line 13)
-* options, printing list of: Options. (line 142)
+* options, printing list of: Options. (line 154)
+* or: Bitwise Functions. (line 50)
* OR bitwise operation: Bitwise Functions. (line 6)
* or Boolean-logic operator: Boolean Ops. (line 6)
-* or() function (gawk): Bitwise Functions. (line 48)
+* ord() extension function: Extension Sample Ord.
+ (line 12)
* ord() user-defined function: Ordinal Functions. (line 16)
-* order of evaluation, concatenation: Concatenation. (line 42)
-* ORS variable <1>: User-modified. (line 129)
-* ORS variable: Output Separators. (line 20)
+* order of evaluation, concatenation: Concatenation. (line 41)
+* ORS variable <1>: User-modified. (line 118)
+* ORS variable: Output Separators. (line 21)
* output field separator, See OFS variable: Changing Fields. (line 64)
* output record separator, See ORS variable: Output Separators.
- (line 20)
+ (line 21)
* output redirection: Redirection. (line 6)
-* output, buffering: I/O Functions. (line 29)
+* output wrapper: Output Wrappers. (line 6)
+* output, buffering: I/O Functions. (line 32)
* output, duplicating into files: Tee Program. (line 6)
* output, files, closing: Close Files And Pipes.
(line 6)
@@ -26643,139 +33542,139 @@ Index
* output, formatted: Printf. (line 6)
* output, pipes: Redirection. (line 57)
* output, printing, See printing: Printing. (line 6)
-* output, records: Output Separators. (line 20)
+* output, records: Output Separators. (line 21)
* output, standard: Special FD. (line 6)
* p debugger command (alias for print): Viewing And Changing Data.
(line 36)
-* P1003.1 POSIX standard: Glossary. (line 454)
-* P1003.2 POSIX standard: Glossary. (line 454)
-* parameters, number of: Internals. (line 42)
-* parentheses (): Regexp Operators. (line 79)
-* parentheses (), pgawk program: Profiling. (line 141)
+* Papadopoulos, Panos: Contributors. (line 128)
+* parent process ID of gawk process: Auto-set. (line 203)
+* parentheses (), in a profile: Profiling. (line 146)
+* parentheses (), regexp operator: Regexp Operators. (line 81)
* password file: Passwd Functions. (line 16)
-* patsplit() function: String Functions. (line 293)
+* patsplit: String Functions. (line 297)
* patterns: Patterns and Actions.
(line 6)
* patterns, comparison expressions as: Expression Patterns. (line 14)
-* patterns, counts: Profiling. (line 113)
+* patterns, counts, in a profile: Profiling. (line 118)
* patterns, default: Very Simple. (line 34)
* patterns, empty: Empty. (line 6)
* patterns, expressions as: Regexp Patterns. (line 6)
* patterns, ranges in: Ranges. (line 6)
-* patterns, regexp constants as: Expression Patterns. (line 36)
+* patterns, regexp constants as: Expression Patterns. (line 34)
* patterns, types of: Pattern Overview. (line 15)
* pawk (profiling version of Brian Kernighan's awk): Other Versions.
- (line 69)
+ (line 82)
+* pawk, awk-like facilities for Python: Other Versions. (line 129)
* PC operating systems, gawk on: PC Using. (line 6)
* PC operating systems, gawk on, installing: PC Installation. (line 6)
* percent sign (%), % operator: Precedence. (line 55)
* percent sign (%), %= operator <1>: Precedence. (line 95)
-* percent sign (%), %= operator: Assignment Ops. (line 129)
-* period (.): Regexp Operators. (line 43)
+* percent sign (%), %= operator: Assignment Ops. (line 130)
+* period (.), regexp operator: Regexp Operators. (line 44)
* Perl: Future Extensions. (line 6)
* Peters, Arno: Contributors. (line 85)
-* Peterson, Hal: Contributors. (line 40)
-* pgawk program: Profiling. (line 6)
-* pgawk program, awkprof.out file: Profiling. (line 10)
-* pgawk program, dynamic profiling: Profiling. (line 174)
-* pipes, closing: Close Files And Pipes.
+* Peterson, Hal: Contributors. (line 39)
+* pipe, closing: Close Files And Pipes.
(line 6)
-* pipes, input: Getline/Pipe. (line 6)
-* pipes, output: Redirection. (line 57)
-* Pitts, Dave <1>: Bugs. (line 73)
+* pipe, input: Getline/Pipe. (line 9)
+* pipe, output: Redirection. (line 57)
+* Pitts, Dave <1>: Bugs. (line 70)
* Pitts, Dave: Acknowledgments. (line 60)
-* plus sign (+): Regexp Operators. (line 102)
+* Plauger, P.J.: Library Functions. (line 12)
+* plug-in: Extension Intro. (line 6)
* plus sign (+), + operator: Precedence. (line 52)
-* plus sign (+), ++ (decrement/increment operators): Increment Ops.
- (line 11)
* plus sign (+), ++ operator <1>: Precedence. (line 46)
-* plus sign (+), ++ operator: Increment Ops. (line 40)
+* plus sign (+), ++ operator: Increment Ops. (line 11)
* plus sign (+), += operator <1>: Precedence. (line 95)
* plus sign (+), += operator: Assignment Ops. (line 82)
+* plus sign (+), regexp operator: Regexp Operators. (line 105)
* pointers to functions: Indirect Calls. (line 6)
-* portability: Escape Sequences. (line 94)
-* portability, #! (executable scripts): Executable Scripts. (line 34)
+* portability: Escape Sequences. (line 103)
+* portability, #! (executable scripts): Executable Scripts. (line 33)
* portability, ** operator and: Arithmetic Ops. (line 81)
-* portability, **= operator and: Assignment Ops. (line 142)
-* portability, ARGV variable: Executable Scripts. (line 43)
+* portability, **= operator and: Assignment Ops. (line 143)
+* portability, ARGV variable: Executable Scripts. (line 59)
* portability, backslash continuation and: Statements/Lines. (line 30)
* portability, backslash in escape sequences: Escape Sequences.
- (line 113)
+ (line 108)
* portability, close() function and: Close Files And Pipes.
(line 81)
-* portability, data files as single record: Records. (line 175)
-* portability, deleting array elements: Delete. (line 52)
-* portability, example programs: Library Functions. (line 31)
-* portability, fflush() function and: I/O Functions. (line 29)
-* portability, functions, defining: Definition Syntax. (line 99)
+* portability, data files as single record: gawk split records.
+ (line 65)
+* portability, deleting array elements: Delete. (line 56)
+* portability, example programs: Library Functions. (line 42)
+* portability, functions, defining: Definition Syntax. (line 109)
* portability, gawk: New Ports. (line 6)
-* portability, gettext library and: Explaining gettext. (line 10)
+* portability, gettext library and: Explaining gettext. (line 11)
* portability, internationalization and: I18N Portability. (line 6)
-* portability, length() function: String Functions. (line 175)
-* portability, new awk vs. old awk: Conversion. (line 55)
+* portability, length() function: String Functions. (line 180)
+* portability, new awk vs. old awk: Strings And Numbers. (line 57)
* portability, next statement in user-defined functions: Pass By Value/Reference.
- (line 91)
+ (line 88)
* portability, NF variable, decrementing: Changing Fields. (line 115)
-* portability, operators: Increment Ops. (line 61)
+* portability, operators: Increment Ops. (line 60)
* portability, operators, not in POSIX awk: Precedence. (line 98)
-* portability, POSIXLY_CORRECT environment variable: Options. (line 310)
+* portability, POSIXLY_CORRECT environment variable: Options. (line 359)
* portability, substr() function: String Functions. (line 512)
* portable object files <1>: Translator i18n. (line 6)
-* portable object files: Explaining gettext. (line 36)
+* portable object files: Explaining gettext. (line 37)
* portable object files, converting to message object files: I18N Example.
- (line 62)
-* portable object files, generating: Options. (line 135)
-* portable object template files: Explaining gettext. (line 30)
+ (line 64)
+* portable object files, generating: Options. (line 147)
+* portable object template files: Explaining gettext. (line 31)
* porting gawk: New Ports. (line 6)
* positional specifiers, printf statement <1>: Printf Ordering.
(line 6)
* positional specifiers, printf statement: Format Modifiers. (line 13)
* positional specifiers, printf statement, mixing with regular formats: Printf Ordering.
(line 57)
-* positive zero: Unexpected Results. (line 28)
-* POSIX awk <1>: Assignment Ops. (line 136)
+* POSIX awk <1>: Assignment Ops. (line 137)
* POSIX awk: This Manual. (line 14)
* POSIX awk, ** operator and: Precedence. (line 98)
-* POSIX awk, **= operator and: Assignment Ops. (line 142)
+* POSIX awk, **= operator and: Assignment Ops. (line 143)
* POSIX awk, < operator and: Getline/File. (line 26)
-* POSIX awk, arithmetic operators and: Arithmetic Ops. (line 36)
+* POSIX awk, arithmetic operators and: Arithmetic Ops. (line 30)
* POSIX awk, backslashes in string constants: Escape Sequences.
- (line 113)
+ (line 108)
* POSIX awk, BEGIN/END patterns: I/O And BEGIN/END. (line 16)
-* POSIX awk, bracket expressions and: Bracket Expressions. (line 24)
+* POSIX awk, bracket expressions and: Bracket Expressions. (line 26)
* POSIX awk, bracket expressions and, character classes: Bracket Expressions.
- (line 30)
+ (line 32)
* POSIX awk, break statement and: Break Statement. (line 51)
* POSIX awk, changes in awk versions: POSIX. (line 6)
-* POSIX awk, continue statement and: Continue Statement. (line 43)
-* POSIX awk, CONVFMT variable and: User-modified. (line 28)
-* POSIX awk, date utility and: Time Functions. (line 261)
-* POSIX awk, field separators and <1>: Field Splitting Summary.
- (line 41)
+* POSIX awk, continue statement and: Continue Statement. (line 44)
+* POSIX awk, CONVFMT variable and: User-modified. (line 30)
+* POSIX awk, date utility and: Time Functions. (line 254)
+* POSIX awk, field separators and <1>: Full Line Fields. (line 16)
* POSIX awk, field separators and: Fields. (line 6)
-* POSIX awk, FS variable and: User-modified. (line 66)
-* POSIX awk, function keyword in: Definition Syntax. (line 83)
-* POSIX awk, functions and, gsub()/sub(): Gory Details. (line 53)
-* POSIX awk, functions and, length(): String Functions. (line 175)
+* POSIX awk, FS variable and: User-modified. (line 60)
+* POSIX awk, function keyword in: Definition Syntax. (line 93)
+* POSIX awk, functions and, gsub()/sub(): Gory Details. (line 90)
+* POSIX awk, functions and, length(): String Functions. (line 180)
* POSIX awk, GNU long options and: Options. (line 15)
* POSIX awk, interval expressions in: Regexp Operators. (line 135)
-* POSIX awk, next/nextfile statements and: Next Statement. (line 45)
+* POSIX awk, next/nextfile statements and: Next Statement. (line 44)
* POSIX awk, numeric strings and: Variable Typing. (line 6)
-* POSIX awk, OFMT variable and <1>: Conversion. (line 55)
+* POSIX awk, OFMT variable and <1>: Strings And Numbers. (line 57)
* POSIX awk, OFMT variable and: OFMT. (line 27)
-* POSIX awk, period (.), using: Regexp Operators. (line 50)
-* POSIX awk, printf format strings and: Format Modifiers. (line 159)
-* POSIX awk, regular expressions and: Regexp Operators. (line 157)
+* POSIX awk, period (.), using: Regexp Operators. (line 51)
+* POSIX awk, printf format strings and: Format Modifiers. (line 158)
+* POSIX awk, regular expressions and: Regexp Operators. (line 161)
* POSIX awk, timestamps and: Time Functions. (line 6)
-* POSIX awk, | I/O operator and: Getline/Pipe. (line 52)
-* POSIX mode: Options. (line 199)
-* POSIX, awk and: Preface. (line 23)
+* POSIX awk, | I/O operator and: Getline/Pipe. (line 55)
+* POSIX mode: Options. (line 254)
+* POSIX, awk and: Preface. (line 21)
* POSIX, gawk extensions not included in: POSIX/GNU. (line 6)
* POSIX, programs, implementing in awk: Clones. (line 6)
-* POSIXLY_CORRECT environment variable: Options. (line 289)
+* POSIXLY_CORRECT environment variable: Options. (line 339)
+* PREC variable: User-modified. (line 123)
* precedence <1>: Precedence. (line 6)
-* precedence: Increment Ops. (line 61)
-* precedence, regexp operators: Regexp Operators. (line 152)
+* precedence: Increment Ops. (line 60)
+* precedence, regexp operators: Regexp Operators. (line 156)
+* predefined variables: Built-in Variables. (line 6)
+* predefined variables, -v option, setting with: Options. (line 40)
+* predefined variables, conveying information: Auto-set. (line 6)
+* predefined variables, user-modifiable: User-modified. (line 6)
* print debugger command: Viewing And Changing Data.
(line 36)
* print statement: Printing. (line 16)
@@ -26783,10 +33682,12 @@ Index
* print statement, commas, omitting: Print Examples. (line 31)
* print statement, I/O operators in: Precedence. (line 71)
* print statement, line continuations and: Print Examples. (line 76)
-* print statement, OFMT variable and: User-modified. (line 124)
+* print statement, OFMT variable and: User-modified. (line 113)
* print statement, See Also redirection, of output: Redirection.
(line 17)
* print statement, sprintf() function and: Round Function. (line 6)
+* print variables, in debugger: Viewing And Changing Data.
+ (line 36)
* printf debugger command: Viewing And Changing Data.
(line 54)
* printf statement <1>: Printf. (line 6)
@@ -26806,120 +33707,138 @@ Index
* printf statement, sprintf() function and: Round Function. (line 6)
* printf statement, syntax of: Basic Printf. (line 6)
* printing: Printing. (line 6)
-* printing, list of options: Options. (line 142)
+* printing messages from extensions: Printing Messages. (line 6)
+* printing, list of options: Options. (line 154)
* printing, mailing labels: Labels Program. (line 6)
* printing, unduplicated lines of text: Uniq Program. (line 6)
* printing, user information: Id Program. (line 6)
* private variables: Library Names. (line 11)
-* processes, two-way communications with: Two-way I/O. (line 23)
+* process group idIDof gawk process: Auto-set. (line 197)
+* process ID of gawk process: Auto-set. (line 200)
+* processes, two-way communications with: Two-way I/O. (line 6)
* processing data: Basic High Level. (line 6)
-* PROCINFO array <1>: Internals. (line 140)
-* PROCINFO array <2>: Id Program. (line 15)
-* PROCINFO array <3>: Group Functions. (line 6)
-* PROCINFO array <4>: Passwd Functions. (line 6)
-* PROCINFO array <5>: Two-way I/O. (line 116)
-* PROCINFO array <6>: Time Functions. (line 46)
-* PROCINFO array <7>: Auto-set. (line 123)
-* PROCINFO array: Obsolete. (line 11)
+* PROCINFO array <1>: Passwd Functions. (line 6)
+* PROCINFO array <2>: Time Functions. (line 47)
+* PROCINFO array: Auto-set. (line 144)
+* PROCINFO array, and communications via ptys: Two-way I/O. (line 99)
+* PROCINFO array, and group membership: Group Functions. (line 6)
+* PROCINFO array, and user and group ID numbers: Id Program. (line 15)
+* PROCINFO array, testing the field splitting: Passwd Functions.
+ (line 154)
+* PROCINFO array, uses: Auto-set. (line 256)
+* PROCINFO, values of sorted_in: Controlling Scanning.
+ (line 26)
* profiling awk programs: Profiling. (line 6)
-* profiling awk programs, dynamically: Profiling. (line 174)
-* profiling gawk, See pgawk program: Profiling. (line 6)
+* profiling awk programs, dynamically: Profiling. (line 178)
+* program identifiers: Auto-set. (line 162)
* program, definition of: Getting Started. (line 21)
-* programmers, attractiveness of: Two-way I/O. (line 6)
* programming conventions, --non-decimal-data option: Nondecimal Data.
- (line 36)
-* programming conventions, ARGC/ARGV variables: Auto-set. (line 31)
+ (line 35)
+* programming conventions, ARGC/ARGV variables: Auto-set. (line 35)
* programming conventions, exit statement: Exit Statement. (line 38)
* programming conventions, function parameters: Return Statement.
(line 45)
* programming conventions, functions, calling: Calling Built-in.
(line 10)
* programming conventions, functions, writing: Definition Syntax.
- (line 55)
-* programming conventions, gawk internals: Internal File Ops. (line 33)
+ (line 65)
+* programming conventions, gawk extensions: Internal File Ops.
+ (line 45)
* programming conventions, private variable names: Library Names.
(line 23)
* programming language, recipe for: History. (line 6)
-* Programming languages, Ada: Glossary. (line 20)
+* programming languages, Ada: Glossary. (line 11)
* programming languages, data-driven vs. procedural: Getting Started.
(line 12)
-* Programming languages, Java: Glossary. (line 380)
-* programming, basic steps: Basic High Level. (line 19)
+* programming languages, Java: Glossary. (line 379)
+* programming, basic steps: Basic High Level. (line 20)
* programming, concepts: Basic Concepts. (line 6)
* pwcat program: Passwd Functions. (line 23)
-* q debugger command (alias for quit): Miscellaneous Dgawk Commands.
- (line 101)
-* QSE Awk: Other Versions. (line 108)
-* question mark (?) regexp operator <1>: GNU Regexp Operators.
- (line 59)
-* question mark (?) regexp operator: Regexp Operators. (line 111)
+* q debugger command (alias for quit): Miscellaneous Debugger Commands.
+ (line 99)
+* QSE Awk: Other Versions. (line 135)
+* Quanstrom, Erik: Alarm Program. (line 8)
* question mark (?), ?: operator: Precedence. (line 92)
-* QuikTrim Awk: Other Versions. (line 112)
-* quit debugger command: Miscellaneous Dgawk Commands.
- (line 101)
-* QUIT signal (MS-Windows): Profiling. (line 207)
-* quoting <1>: Comments. (line 27)
-* quoting <2>: Long. (line 26)
-* quoting: Read Terminal. (line 25)
-* quoting, rules for: Quoting. (line 6)
-* quoting, tricks for: Quoting. (line 71)
-* r debugger command (alias for run): Dgawk Execution Control.
+* question mark (?), regexp operator <1>: GNU Regexp Operators.
+ (line 59)
+* question mark (?), regexp operator: Regexp Operators. (line 111)
+* QuikTrim Awk: Other Versions. (line 139)
+* quit debugger command: Miscellaneous Debugger Commands.
+ (line 99)
+* QUIT signal (MS-Windows): Profiling. (line 213)
+* quoting in gawk command lines: Long. (line 26)
+* quoting in gawk command lines, tricks for: Quoting. (line 91)
+* quoting, for small awk programs: Comments. (line 27)
+* r debugger command (alias for run): Debugger Execution Control.
(line 62)
* Rakitzis, Byron: History Sorting. (line 25)
-* rand() function: Numeric Functions. (line 33)
+* Ramey, Chet <1>: General Data Types. (line 6)
+* Ramey, Chet: Acknowledgments. (line 60)
+* rand: Numeric Functions. (line 48)
* random numbers, Cliff: Cliff Random Function.
(line 6)
* random numbers, rand()/srand() functions: Numeric Functions.
- (line 33)
-* random numbers, seed of: Numeric Functions. (line 63)
+ (line 48)
+* random numbers, seed of: Numeric Functions. (line 78)
* range expressions (regexps): Bracket Expressions. (line 6)
* range patterns: Ranges. (line 6)
-* Rankin, Pat <1>: Bugs. (line 72)
-* Rankin, Pat <2>: Contributors. (line 38)
-* Rankin, Pat <3>: Assignment Ops. (line 100)
+* range patterns, line continuation and: Ranges. (line 65)
+* Rankin, Pat <1>: Contributors. (line 37)
+* Rankin, Pat <2>: Assignment Ops. (line 100)
* Rankin, Pat: Acknowledgments. (line 60)
+* reada() extension function: Extension Sample Read write array.
+ (line 18)
* readable data files, checking: File Checking. (line 6)
* readable.awk program: File Checking. (line 11)
+* readdir extension: Extension Sample Readdir.
+ (line 9)
+* readfile() extension function: Extension Sample Readfile.
+ (line 12)
+* readfile() user-defined function: Readfile Function. (line 30)
+* reading input files: Reading Files. (line 6)
* recipe for a programming language: History. (line 6)
-* record separators <1>: User-modified. (line 134)
-* record separators: Records. (line 14)
-* record separators, changing: Records. (line 81)
-* record separators, regular expressions as: Records. (line 112)
+* record separators <1>: User-modified. (line 132)
+* record separators: awk split records. (line 6)
+* record separators, changing: awk split records. (line 85)
+* record separators, regular expressions as: awk split records.
+ (line 125)
* record separators, with multiline records: Multiple Line. (line 10)
-* records <1>: Basic High Level. (line 71)
+* records <1>: Basic High Level. (line 73)
* records: Reading Files. (line 14)
* records, multiline: Multiple Line. (line 6)
* records, printing: Print. (line 22)
* records, splitting input into: Records. (line 6)
-* records, terminating: Records. (line 112)
-* records, treating files as: Records. (line 196)
-* recursive functions: Definition Syntax. (line 73)
+* records, terminating: awk split records. (line 125)
+* records, treating files as: gawk split records. (line 93)
+* recursive functions: Definition Syntax. (line 83)
+* redirect gawk output, in debugger: Debugger Info. (line 72)
* redirection of input: Getline/File. (line 6)
* redirection of output: Redirection. (line 6)
* reference counting, sorting arrays: Array Sorting Functions.
- (line 72)
+ (line 77)
+* regexp: Regexp. (line 6)
* regexp constants <1>: Comparison Operators.
(line 103)
* regexp constants <2>: Regexp Constants. (line 6)
* regexp constants: Regexp Usage. (line 57)
* regexp constants, /=.../, /= operator and: Assignment Ops. (line 148)
-* regexp constants, as patterns: Expression Patterns. (line 36)
+* regexp constants, as patterns: Expression Patterns. (line 34)
* regexp constants, in gawk: Using Constant Regexps.
(line 28)
-* regexp constants, slashes vs. quotes: Computed Regexps. (line 28)
-* regexp constants, vs. string constants: Computed Regexps. (line 38)
-* regexp, See regular expressions: Regexp. (line 6)
-* register_deferred_variable() internal function: Internals. (line 140)
-* register_open_hook() internal function: Internals. (line 151)
+* regexp constants, slashes vs. quotes: Computed Regexps. (line 29)
+* regexp constants, vs. string constants: Computed Regexps. (line 39)
+* register extension: Registration Functions.
+ (line 6)
* regular expressions: Regexp. (line 6)
-* regular expressions as field separators: Field Separators. (line 50)
+* regular expressions as field separators: Field Separators. (line 51)
* regular expressions, anchors in: Regexp Operators. (line 22)
* regular expressions, as field separators: Regexp Field Splitting.
(line 6)
* regular expressions, as patterns <1>: Regexp Patterns. (line 6)
* regular expressions, as patterns: Regexp Usage. (line 6)
-* regular expressions, as record separators: Records. (line 112)
-* regular expressions, case sensitivity <1>: User-modified. (line 82)
+* regular expressions, as record separators: awk split records.
+ (line 125)
+* regular expressions, case sensitivity <1>: User-modified. (line 76)
* regular expressions, case sensitivity: Case-sensitivity. (line 6)
* regular expressions, computed: Computed Regexps. (line 6)
* regular expressions, constants, See regexp constants: Regexp Usage.
@@ -26929,7 +33848,7 @@ Index
(line 59)
* regular expressions, gawk, command-line options: GNU Regexp Operators.
(line 70)
-* regular expressions, interval expressions and: Options. (line 224)
+* regular expressions, interval expressions and: Options. (line 279)
* regular expressions, leftmost longest match: Leftmost Longest.
(line 6)
* regular expressions, operators <1>: Regexp Operators. (line 6)
@@ -26941,16 +33860,21 @@ Index
* regular expressions, operators, gawk: GNU Regexp Operators.
(line 6)
* regular expressions, operators, precedence of: Regexp Operators.
- (line 152)
+ (line 156)
* regular expressions, searching for: Egrep Program. (line 6)
* relational operators, See comparison operators: Typing and Comparison.
(line 9)
-* return debugger command: Dgawk Execution Control.
+* replace in string: String Functions. (line 408)
+* return debugger command: Debugger Execution Control.
(line 54)
* return statement, user-defined functions: Return Statement. (line 6)
-* return values, close() function: Close Files And Pipes.
- (line 131)
-* rev() user-defined function: Function Example. (line 52)
+* return value, close() function: Close Files And Pipes.
+ (line 133)
+* rev() user-defined function: Function Example. (line 54)
+* revoutput extension: Extension Sample Revout.
+ (line 11)
+* revtwoway extension: Extension Sample Rev2way.
+ (line 12)
* rewind() user-defined function: Rewind Function. (line 16)
* right angle bracket (>), > operator <1>: Precedence. (line 65)
* right angle bracket (>), > operator: Comparison Operators.
@@ -26961,249 +33885,327 @@ Index
(line 11)
* right angle bracket (>), >> operator (I/O) <1>: Precedence. (line 65)
* right angle bracket (>), >> operator (I/O): Redirection. (line 50)
+* right shift: Bitwise Functions. (line 53)
* right shift, bitwise: Bitwise Functions. (line 32)
-* Ritchie, Dennis: Basic Data Typing. (line 74)
-* RLENGTH variable: Auto-set. (line 183)
-* RLENGTH variable, match() function and: String Functions. (line 223)
+* Ritchie, Dennis: Basic Data Typing. (line 54)
+* RLENGTH variable: Auto-set. (line 266)
+* RLENGTH variable, match() function and: String Functions. (line 228)
* Robbins, Arnold <1>: Future Extensions. (line 6)
-* Robbins, Arnold <2>: Bugs. (line 32)
-* Robbins, Arnold <3>: Contributors. (line 108)
-* Robbins, Arnold <4>: Alarm Program. (line 6)
-* Robbins, Arnold <5>: Passwd Functions. (line 90)
-* Robbins, Arnold <6>: Getline/Pipe. (line 36)
+* Robbins, Arnold <2>: Bugs. (line 70)
+* Robbins, Arnold <3>: Contributors. (line 144)
+* Robbins, Arnold <4>: General Data Types. (line 6)
+* Robbins, Arnold <5>: Alarm Program. (line 6)
+* Robbins, Arnold <6>: Passwd Functions. (line 90)
+* Robbins, Arnold <7>: Getline/Pipe. (line 39)
* Robbins, Arnold: Command Line Field Separator.
- (line 80)
-* Robbins, Bill: Getline/Pipe. (line 36)
-* Robbins, Harry: Acknowledgments. (line 81)
-* Robbins, Jean: Acknowledgments. (line 81)
+ (line 71)
+* Robbins, Bill: Getline/Pipe. (line 39)
+* Robbins, Harry: Acknowledgments. (line 94)
+* Robbins, Jean: Acknowledgments. (line 94)
* Robbins, Miriam <1>: Passwd Functions. (line 90)
-* Robbins, Miriam <2>: Getline/Pipe. (line 36)
-* Robbins, Miriam: Acknowledgments. (line 81)
-* Robinson, Will: Dynamic Extensions. (line 6)
-* robot, the: Dynamic Extensions. (line 6)
-* Rommel, Kai Uwe: Contributors. (line 43)
+* Robbins, Miriam <2>: Getline/Pipe. (line 39)
+* Robbins, Miriam: Acknowledgments. (line 94)
+* Rommel, Kai Uwe: Contributors. (line 42)
+* round to nearest integer: Numeric Functions. (line 38)
* round() user-defined function: Round Function. (line 16)
* rounding numbers: Round Function. (line 6)
-* RS variable <1>: User-modified. (line 134)
-* RS variable: Records. (line 20)
+* ROUNDMODE variable: User-modified. (line 127)
+* RS variable <1>: User-modified. (line 132)
+* RS variable: awk split records. (line 12)
* RS variable, multiline records and: Multiple Line. (line 17)
-* rshift() function (gawk): Bitwise Functions. (line 51)
-* RSTART variable: Auto-set. (line 189)
-* RSTART variable, match() function and: String Functions. (line 223)
-* RT variable <1>: Auto-set. (line 196)
-* RT variable <2>: Getline/Variable/File.
- (line 10)
-* RT variable <3>: Multiple Line. (line 129)
-* RT variable: Records. (line 112)
-* Rubin, Paul <1>: Contributors. (line 16)
+* rshift: Bitwise Functions. (line 53)
+* RSTART variable: Auto-set. (line 272)
+* RSTART variable, match() function and: String Functions. (line 228)
+* RT variable <1>: Auto-set. (line 279)
+* RT variable <2>: Multiple Line. (line 129)
+* RT variable: awk split records. (line 125)
+* Rubin, Paul <1>: Contributors. (line 15)
* Rubin, Paul: History. (line 30)
* rule, definition of: Getting Started. (line 21)
-* run debugger command: Dgawk Execution Control.
+* run debugger command: Debugger Execution Control.
(line 62)
* rvalues/lvalues: Assignment Ops. (line 32)
-* s debugger command (alias for step): Dgawk Execution Control.
+* s debugger command (alias for step): Debugger Execution Control.
(line 68)
-* sandbox mode: Options. (line 236)
+* sample debugging session: Sample Debugging Session.
+ (line 6)
+* sandbox mode: Options. (line 286)
+* save debugger options: Debugger Info. (line 84)
+* scalar or array: Type Functions. (line 11)
* scalar values: Basic Data Typing. (line 13)
+* scanning arrays: Scanning an Array. (line 6)
+* scanning multidimensional arrays: Multiscanning. (line 11)
+* Schorr, Andrew <1>: Contributors. (line 133)
+* Schorr, Andrew <2>: Auto-set. (line 311)
* Schorr, Andrew: Acknowledgments. (line 60)
* Schreiber, Bert: Acknowledgments. (line 38)
* Schreiber, Rita: Acknowledgments. (line 38)
-* search paths <1>: VMS Running. (line 29)
-* search paths <2>: PC Using. (line 11)
-* search paths <3>: Igawk Program. (line 368)
-* search paths: AWKPATH Variable. (line 6)
-* search paths, for source files <1>: VMS Running. (line 29)
-* search paths, for source files <2>: PC Using. (line 11)
-* search paths, for source files <3>: Igawk Program. (line 368)
+* search and replace in strings: String Functions. (line 90)
+* search in string: String Functions. (line 156)
+* search paths <1>: VMS Running. (line 57)
+* search paths <2>: PC Using. (line 10)
+* search paths: Programs Exercises. (line 70)
+* search paths, for loadable extensions: AWKLIBPATH Variable. (line 6)
+* search paths, for source files <1>: VMS Running. (line 57)
+* search paths, for source files <2>: PC Using. (line 10)
+* search paths, for source files <3>: Programs Exercises. (line 70)
* search paths, for source files: AWKPATH Variable. (line 6)
-* searching: String Functions. (line 155)
* searching, files for regular expressions: Egrep Program. (line 6)
* searching, for words: Dupword Program. (line 6)
-* sed utility <1>: Glossary. (line 12)
+* sed utility <1>: Glossary. (line 16)
* sed utility <2>: Simple Sed. (line 6)
-* sed utility: Field Splitting Summary.
- (line 47)
-* semicolon (;): Statements/Lines. (line 91)
-* semicolon (;), AWKPATH variable and: PC Using. (line 11)
+* sed utility: Full Line Fields. (line 22)
+* seeding random number generator: Numeric Functions. (line 78)
+* semicolon (;), AWKPATH variable and: PC Using. (line 10)
* semicolon (;), separating statements in actions <1>: Statements.
(line 10)
-* semicolon (;), separating statements in actions: Action Overview.
+* semicolon (;), separating statements in actions <2>: Action Overview.
(line 19)
-* separators, field: User-modified. (line 56)
-* separators, field, FIELDWIDTHS variable and: User-modified. (line 35)
-* separators, field, FPAT variable and: User-modified. (line 45)
+* semicolon (;), separating statements in actions: Statements/Lines.
+ (line 91)
+* separators, field: User-modified. (line 50)
+* separators, field, FIELDWIDTHS variable and: User-modified. (line 37)
+* separators, field, FPAT variable and: User-modified. (line 43)
* separators, field, POSIX and: Fields. (line 6)
-* separators, for records <1>: User-modified. (line 134)
-* separators, for records: Records. (line 14)
-* separators, for records, regular expressions as: Records. (line 112)
+* separators, for records <1>: User-modified. (line 132)
+* separators, for records: awk split records. (line 6)
+* separators, for records, regular expressions as: awk split records.
+ (line 125)
* separators, for statements in actions: Action Overview. (line 19)
-* separators, subscript: User-modified. (line 147)
+* separators, subscript: User-modified. (line 145)
+* set breakpoint: Breakpoint Control. (line 11)
* set debugger command: Viewing And Changing Data.
(line 59)
-* shells, piping commands into: Redirection. (line 143)
+* set directory of message catalogs: I18N Functions. (line 12)
+* set watchpoint: Viewing And Changing Data.
+ (line 67)
+* shadowing of variable values: Definition Syntax. (line 71)
+* shell quoting, rules for: Quoting. (line 6)
+* shells, piping commands into: Redirection. (line 136)
* shells, quoting: Using Shell Variables.
(line 12)
* shells, quoting, rules for: Quoting. (line 18)
* shells, scripts: One-shot. (line 22)
+* shells, sea: Undocumented. (line 8)
* shells, variables: Using Shell Variables.
(line 6)
* shift, bitwise: Bitwise Functions. (line 32)
-* short-circuit operators: Boolean Ops. (line 57)
-* si debugger command (alias for stepi): Dgawk Execution Control.
+* short-circuit operators: Boolean Ops. (line 59)
+* show all source files, in debugger: Debugger Info. (line 45)
+* show breakpoints: Debugger Info. (line 21)
+* show function arguments, in debugger: Debugger Info. (line 18)
+* show local variables, in debugger: Debugger Info. (line 34)
+* show name of current source file, in debugger: Debugger Info.
+ (line 37)
+* show watchpoints: Debugger Info. (line 51)
+* si debugger command (alias for stepi): Debugger Execution Control.
(line 76)
* side effects <1>: Increment Ops. (line 11)
-* side effects: Concatenation. (line 42)
+* side effects: Concatenation. (line 41)
* side effects, array indexing: Reference to Elements.
- (line 42)
+ (line 43)
* side effects, asort() function: Array Sorting Functions.
- (line 22)
+ (line 24)
* side effects, assignment expressions: Assignment Ops. (line 23)
* side effects, Boolean operators: Boolean Ops. (line 30)
* side effects, conditional expressions: Conditional Exp. (line 22)
* side effects, decrement/increment operators: Increment Ops. (line 11)
* side effects, FILENAME variable: Getline Notes. (line 19)
-* side effects, function calls: Function Calls. (line 54)
+* side effects, function calls: Function Calls. (line 57)
* side effects, statements: Action Overview. (line 32)
-* SIGHUP signal: Profiling. (line 204)
-* SIGINT signal (MS-Windows): Profiling. (line 207)
-* signals, HUP/SIGHUP: Profiling. (line 204)
-* signals, INT/SIGINT (MS-Windows): Profiling. (line 207)
-* signals, QUIT/SIGQUIT (MS-Windows): Profiling. (line 207)
-* signals, USR1/SIGUSR1: Profiling. (line 182)
-* SIGQUIT signal (MS-Windows): Profiling. (line 207)
-* SIGUSR1 signal: Profiling. (line 182)
-* silent debugger command: Dgawk Execution Control.
+* sidebar, A Constant's Base Does Not Affect Its Value: Nondecimal-numbers.
+ (line 64)
+* sidebar, Backslash Before Regular Characters: Escape Sequences.
+ (line 106)
+* sidebar, Changing FS Does Not Affect the Fields: Full Line Fields.
+ (line 14)
+* sidebar, Changing NR and FNR: Auto-set. (line 326)
+* sidebar, Controlling Output Buffering with system(): I/O Functions.
+ (line 138)
+* sidebar, Escape Sequences for Metacharacters: Escape Sequences.
+ (line 137)
+* sidebar, FS and IGNORECASE: Field Splitting Summary.
+ (line 38)
+* sidebar, Interactive Versus Noninteractive Buffering: I/O Functions.
+ (line 73)
+* sidebar, Matching the Null String: String Functions. (line 534)
+* sidebar, Operator Evaluation Order: Increment Ops. (line 58)
+* sidebar, Piping into sh: Redirection. (line 134)
+* sidebar, Pre-POSIX awk Used OFMT for String Conversion: Strings And Numbers.
+ (line 55)
+* sidebar, Recipe for a Programming Language: History. (line 6)
+* sidebar, RS = "\0" Is Not Portable: gawk split records. (line 63)
+* sidebar, So Why Does gawk Have BEGINFILE and ENDFILE?: Filetrans Function.
+ (line 82)
+* sidebar, Syntactic Ambiguities Between /= and Regular Expressions: Assignment Ops.
+ (line 146)
+* sidebar, Understanding #!: Executable Scripts. (line 31)
+* sidebar, Understanding $0: Changing Fields. (line 134)
+* sidebar, Using \n in Bracket Expressions of Dynamic Regexps: Computed Regexps.
+ (line 57)
+* sidebar, Using close()'s Return Value: Close Files And Pipes.
+ (line 131)
+* SIGHUP signal, for dynamic profiling: Profiling. (line 210)
+* SIGINT signal (MS-Windows): Profiling. (line 213)
+* signals, HUP/SIGHUP, for profiling: Profiling. (line 210)
+* signals, INT/SIGINT (MS-Windows): Profiling. (line 213)
+* signals, QUIT/SIGQUIT (MS-Windows): Profiling. (line 213)
+* signals, USR1/SIGUSR1, for profiling: Profiling. (line 187)
+* signature program: Signature Program. (line 6)
+* SIGQUIT signal (MS-Windows): Profiling. (line 213)
+* SIGUSR1 signal, for dynamic profiling: Profiling. (line 187)
+* silent debugger command: Debugger Execution Control.
(line 10)
-* sin() function: Numeric Functions. (line 74)
-* single precision floating-point: Basic Data Typing. (line 36)
-* single quote (') <1>: Quoting. (line 31)
-* single quote (') <2>: Long. (line 33)
+* sin: Numeric Functions. (line 89)
+* sine: Numeric Functions. (line 89)
* single quote ('): One-shot. (line 15)
+* single quote (') in gawk command lines: Long. (line 35)
+* single quote ('), in shell commands: Quoting. (line 48)
* single quote ('), vs. apostrophe: Comments. (line 27)
-* single quote ('), with double quotes: Quoting. (line 53)
+* single quote ('), with double quotes: Quoting. (line 73)
* single-character fields: Single Character Fields.
(line 6)
+* single-step execution, in the debugger: Debugger Execution Control.
+ (line 43)
* Skywalker, Luke: Undocumented. (line 6)
-* sleep utility: Alarm Program. (line 109)
-* Solaris, POSIX-compliant awk: Other Versions. (line 86)
+* sleep utility: Alarm Program. (line 110)
+* sleep() extension function: Extension Sample Time.
+ (line 22)
+* Solaris, POSIX-compliant awk: Other Versions. (line 100)
+* sort array: String Functions. (line 42)
+* sort array indices: String Functions. (line 42)
* sort function, arrays, sorting: Array Sorting Functions.
(line 6)
* sort utility: Word Sorting. (line 50)
-* sort utility, coprocesses and: Two-way I/O. (line 83)
+* sort utility, coprocesses and: Two-way I/O. (line 65)
* sorting characters in different languages: Explaining gettext.
- (line 93)
-* source code, awka: Other Versions. (line 55)
+ (line 94)
+* source code, awka: Other Versions. (line 68)
* source code, Brian Kernighan's awk: Other Versions. (line 13)
-* source code, Busybox Awk: Other Versions. (line 78)
+* source code, Busybox Awk: Other Versions. (line 92)
* source code, gawk: Gawk Distribution. (line 6)
-* source code, jawk: Other Versions. (line 96)
-* source code, libmawk: Other Versions. (line 104)
-* source code, mawk: Other Versions. (line 35)
-* source code, mixing: Options. (line 105)
-* source code, pawk: Other Versions. (line 69)
-* source code, QSE Awk: Other Versions. (line 108)
-* source code, QuikTrim Awk: Other Versions. (line 112)
-* source code, Solaris awk: Other Versions. (line 86)
-* source code, xgawk: Other Versions. (line 119)
-* source files, search path for: Igawk Program. (line 368)
-* sparse arrays: Array Intro. (line 71)
-* Spencer, Henry: Glossary. (line 12)
+* source code, Illumos awk: Other Versions. (line 109)
+* source code, jawk: Other Versions. (line 117)
+* source code, libmawk: Other Versions. (line 125)
+* source code, mawk: Other Versions. (line 48)
+* source code, mixing: Options. (line 117)
+* source code, pawk: Other Versions. (line 82)
+* source code, pawk (Python version): Other Versions. (line 129)
+* source code, QSE Awk: Other Versions. (line 135)
+* source code, QuikTrim Awk: Other Versions. (line 139)
+* source code, Solaris awk: Other Versions. (line 100)
+* source files, search path for: Programs Exercises. (line 70)
+* sparse arrays: Array Intro. (line 72)
+* Spencer, Henry: Glossary. (line 16)
+* split: String Functions. (line 316)
+* split string into array: String Functions. (line 297)
* split utility: Split Program. (line 6)
-* split() function: String Functions. (line 315)
-* split() function, array elements, deleting: Delete. (line 57)
+* split() function, array elements, deleting: Delete. (line 61)
* split.awk program: Split Program. (line 30)
-* sprintf() function <1>: String Functions. (line 380)
-* sprintf() function: OFMT. (line 15)
-* sprintf() function, OFMT variable and: User-modified. (line 124)
+* sprintf <1>: String Functions. (line 383)
+* sprintf: OFMT. (line 15)
+* sprintf() function, OFMT variable and: User-modified. (line 113)
* sprintf() function, print/printf statements and: Round Function.
(line 6)
-* sqrt() function: Numeric Functions. (line 77)
-* square brackets ([]): Regexp Operators. (line 55)
-* srand() function: Numeric Functions. (line 81)
-* Stallman, Richard <1>: Glossary. (line 301)
-* Stallman, Richard <2>: Contributors. (line 24)
+* sqrt: Numeric Functions. (line 92)
+* square brackets ([]), regexp operator: Regexp Operators. (line 56)
+* square root: Numeric Functions. (line 92)
+* srand: Numeric Functions. (line 96)
+* stack frame: Debugging Terms. (line 10)
+* Stallman, Richard <1>: Glossary. (line 288)
+* Stallman, Richard <2>: Contributors. (line 23)
* Stallman, Richard <3>: Acknowledgments. (line 18)
* Stallman, Richard: Manual History. (line 6)
* standard error: Special FD. (line 6)
* standard input <1>: Special FD. (line 6)
* standard input: Read Terminal. (line 6)
* standard output: Special FD. (line 6)
-* stat() function, implementing in gawk: Sample Library. (line 6)
+* starting the debugger: Debugger Invocation. (line 6)
+* stat() extension function: Extension Sample File Functions.
+ (line 18)
* statements, compound, control statements and: Statements. (line 10)
* statements, control, in actions: Statements. (line 6)
* statements, multiple: Statements/Lines. (line 91)
-* step debugger command: Dgawk Execution Control.
+* step debugger command: Debugger Execution Control.
(line 68)
-* stepi debugger command: Dgawk Execution Control.
+* stepi debugger command: Debugger Execution Control.
(line 76)
-* stlen internal variable: Internals. (line 46)
-* stptr internal variable: Internals. (line 46)
+* stop automatic display, in debugger: Viewing And Changing Data.
+ (line 80)
* stream editors <1>: Simple Sed. (line 6)
-* stream editors: Field Splitting Summary.
- (line 47)
-* strftime() function (gawk): Time Functions. (line 47)
+* stream editors: Full Line Fields. (line 22)
+* strftime: Time Functions. (line 48)
* string constants: Scalar Constants. (line 15)
-* string constants, vs. regexp constants: Computed Regexps. (line 38)
+* string constants, vs. regexp constants: Computed Regexps. (line 39)
* string extraction (internationalization): String Extraction.
(line 6)
-* string operators: Concatenation. (line 9)
+* string length: String Functions. (line 171)
+* string operators: Concatenation. (line 8)
+* string, regular expression match: String Functions. (line 211)
+* string-manipulation functions: String Functions. (line 6)
* string-matching operators: Regexp Usage. (line 19)
-* strings: Internals. (line 77)
-* strings, converting <1>: Bitwise Functions. (line 107)
-* strings, converting: Conversion. (line 6)
-* strings, converting, numbers to: User-modified. (line 28)
-* strings, empty, See null strings: Records. (line 102)
+* string-translation functions: I18N Functions. (line 6)
+* strings splitting, example: String Functions. (line 335)
+* strings, converting <1>: Bitwise Functions. (line 110)
+* strings, converting: Strings And Numbers. (line 6)
+* strings, converting letter case: String Functions. (line 522)
+* strings, converting, numbers to: User-modified. (line 30)
+* strings, empty, See null strings: awk split records. (line 115)
* strings, extracting: String Extraction. (line 6)
* strings, for localization: Programmer i18n. (line 14)
-* strings, length of: Scalar Constants. (line 20)
+* strings, length limitations: Scalar Constants. (line 20)
* strings, merging arrays into: Join Function. (line 6)
-* strings, NODE internal type: Internals. (line 23)
* strings, null: Regexp Field Splitting.
(line 43)
* strings, numeric: Variable Typing. (line 6)
-* strings, splitting: String Functions. (line 335)
-* strtonum() function (gawk): String Functions. (line 387)
+* strtonum: String Functions. (line 390)
* strtonum() function (gawk), --non-decimal-data option and: Nondecimal Data.
- (line 36)
-* sub() function <1>: String Functions. (line 408)
-* sub() function: Using Constant Regexps.
+ (line 35)
+* sub <1>: String Functions. (line 408)
+* sub: Using Constant Regexps.
(line 43)
* sub() function, arguments of: String Functions. (line 462)
* sub() function, escape processing: Gory Details. (line 6)
-* subscript separators: User-modified. (line 147)
-* subscripts in arrays, multidimensional: Multi-dimensional. (line 10)
-* subscripts in arrays, multidimensional, scanning: Multi-scanning.
+* subscript separators: User-modified. (line 145)
+* subscripts in arrays, multidimensional: Multidimensional. (line 10)
+* subscripts in arrays, multidimensional, scanning: Multiscanning.
(line 11)
* subscripts in arrays, numbers as: Numeric Array Subscripts.
(line 6)
* subscripts in arrays, uninitialized variables as: Uninitialized Subscripts.
(line 6)
-* SUBSEP variable: User-modified. (line 147)
-* SUBSEP variable, multidimensional arrays: Multi-dimensional.
+* SUBSEP variable: User-modified. (line 145)
+* SUBSEP variable, and multidimensional arrays: Multidimensional.
(line 16)
-* substr() function: String Functions. (line 481)
-* Sumner, Andrew: Other Versions. (line 55)
+* substitute in string: String Functions. (line 90)
+* substr: String Functions. (line 481)
+* substring: String Functions. (line 481)
+* Sumner, Andrew: Other Versions. (line 68)
+* supplementary groups of gawk process: Auto-set. (line 251)
* switch statement: Switch Statement. (line 6)
+* SYMTAB array: Auto-set. (line 283)
* syntactic ambiguity: /= operator vs. /=.../ regexp constant: Assignment Ops.
(line 148)
-* system() function: I/O Functions. (line 63)
-* systime() function (gawk): Time Functions. (line 64)
-* t debugger command (alias for tbreak): Breakpoint Control. (line 89)
-* tbreak debugger command: Breakpoint Control. (line 89)
-* Tcl: Library Names. (line 57)
+* system: I/O Functions. (line 106)
+* systime: Time Functions. (line 66)
+* t debugger command (alias for tbreak): Breakpoint Control. (line 90)
+* tbreak debugger command: Breakpoint Control. (line 90)
+* Tcl: Library Names. (line 58)
* TCP/IP: TCP/IP Networking. (line 6)
* TCP/IP, support for: Special Network. (line 6)
* tee utility: Tee Program. (line 6)
* tee.awk program: Tee Program. (line 26)
-* terminating records: Records. (line 112)
-* testbits.awk program: Bitwise Functions. (line 68)
+* temporary breakpoint: Breakpoint Control. (line 90)
+* terminating records: awk split records. (line 125)
+* testbits.awk program: Bitwise Functions. (line 71)
+* testext extension: Extension Sample API Tests.
+ (line 6)
* Texinfo <1>: Adding Code. (line 99)
* Texinfo <2>: Distribution contents.
- (line 79)
+ (line 77)
* Texinfo <3>: Extract Program. (line 12)
* Texinfo <4>: Dupword Program. (line 17)
-* Texinfo <5>: Library Functions. (line 22)
-* Texinfo <6>: Sample Data Files. (line 66)
+* Texinfo <5>: Library Functions. (line 33)
* Texinfo: Conventions. (line 6)
* Texinfo, chapter beginnings in files: Regexp Operators. (line 22)
* Texinfo, extracting programs from source files: Extract Program.
@@ -27211,128 +34213,130 @@ Index
* text, printing: Print. (line 22)
* text, printing, unduplicated lines of: Uniq Program. (line 6)
* TEXTDOMAIN variable <1>: Programmer i18n. (line 9)
-* TEXTDOMAIN variable: User-modified. (line 153)
+* TEXTDOMAIN variable: User-modified. (line 151)
* TEXTDOMAIN variable, BEGIN pattern and: Programmer i18n. (line 60)
* TEXTDOMAIN variable, portability and: I18N Portability. (line 20)
-* textdomain() function (C library): Explaining gettext. (line 27)
+* textdomain() function (C library): Explaining gettext. (line 28)
* tilde (~), ~ operator <1>: Expression Patterns. (line 24)
* tilde (~), ~ operator <2>: Precedence. (line 80)
* tilde (~), ~ operator <3>: Comparison Operators.
(line 11)
* tilde (~), ~ operator <4>: Regexp Constants. (line 6)
-* tilde (~), ~ operator <5>: Computed Regexps. (line 6)
-* tilde (~), ~ operator <6>: Case-sensitivity. (line 26)
+* tilde (~), ~ operator <5>: Case-sensitivity. (line 26)
+* tilde (~), ~ operator <6>: Computed Regexps. (line 6)
* tilde (~), ~ operator: Regexp Usage. (line 19)
-* time, alarm clock example program: Alarm Program. (line 9)
-* time, localization and: Explaining gettext. (line 115)
-* time, managing: Gettimeofday Function.
+* time functions: Time Functions. (line 6)
+* time, alarm clock example program: Alarm Program. (line 11)
+* time, localization and: Explaining gettext. (line 112)
+* time, managing: Getlocaltime Function.
(line 6)
* time, retrieving: Time Functions. (line 17)
+* timeout, reading input: Read Timeout. (line 6)
* timestamps: Time Functions. (line 6)
-* timestamps, converting dates to: Time Functions. (line 74)
-* timestamps, formatted: Gettimeofday Function.
+* timestamps, converting dates to: Time Functions. (line 76)
+* timestamps, formatted: Getlocaltime Function.
(line 6)
-* tolower() function: String Functions. (line 523)
-* toupper() function: String Functions. (line 529)
+* tolower: String Functions. (line 523)
+* toupper: String Functions. (line 529)
* tr utility: Translate Program. (line 6)
-* trace debugger command: Miscellaneous Dgawk Commands.
- (line 110)
+* trace debugger command: Miscellaneous Debugger Commands.
+ (line 108)
+* traceback, display in debugger: Execution Stack. (line 13)
+* translate string: I18N Functions. (line 22)
* translate.awk program: Translate Program. (line 55)
-* troubleshooting, --non-decimal-data option: Options. (line 166)
+* treating files, as single records: gawk split records. (line 93)
+* troubleshooting, --non-decimal-data option: Options. (line 211)
* troubleshooting, == operator: Comparison Operators.
(line 37)
-* troubleshooting, awk uses FS not IFS: Field Separators. (line 29)
+* troubleshooting, awk uses FS not IFS: Field Separators. (line 30)
* troubleshooting, backslash before nonspecial character: Escape Sequences.
- (line 113)
+ (line 108)
* troubleshooting, division: Arithmetic Ops. (line 44)
* troubleshooting, fatal errors, field widths, specifying: Constant Size.
(line 22)
* troubleshooting, fatal errors, printf format strings: Format Modifiers.
- (line 159)
-* troubleshooting, fflush() function: I/O Functions. (line 51)
-* troubleshooting, function call syntax: Function Calls. (line 28)
+ (line 158)
+* troubleshooting, fflush() function: I/O Functions. (line 62)
+* troubleshooting, function call syntax: Function Calls. (line 30)
* troubleshooting, gawk: Compatibility Mode. (line 6)
* troubleshooting, gawk, bug reports: Bugs. (line 9)
* troubleshooting, gawk, fatal errors, function arguments: Calling Built-in.
(line 16)
* troubleshooting, getline function: File Checking. (line 25)
* troubleshooting, gsub()/sub() functions: String Functions. (line 472)
-* troubleshooting, match() function: String Functions. (line 288)
-* troubleshooting, patsplit() function: String Functions. (line 311)
+* troubleshooting, match() function: String Functions. (line 292)
* troubleshooting, print statement, omitting commas: Print Examples.
(line 31)
-* troubleshooting, printing: Redirection. (line 118)
-* troubleshooting, quotes with file names: Special FD. (line 68)
+* troubleshooting, printing: Redirection. (line 112)
+* troubleshooting, quotes with file names: Special FD. (line 62)
* troubleshooting, readable data files: File Checking. (line 6)
* troubleshooting, regexp constants vs. string constants: Computed Regexps.
- (line 38)
-* troubleshooting, string concatenation: Concatenation. (line 27)
+ (line 39)
+* troubleshooting, string concatenation: Concatenation. (line 26)
* troubleshooting, substr() function: String Functions. (line 499)
-* troubleshooting, system() function: I/O Functions. (line 85)
+* troubleshooting, system() function: I/O Functions. (line 128)
* troubleshooting, typographical errors, global variables: Options.
- (line 95)
+ (line 98)
* true, logical: Truth Values. (line 6)
-* Trueman, David <1>: Contributors. (line 31)
+* Trueman, David <1>: Contributors. (line 30)
* Trueman, David <2>: Acknowledgments. (line 47)
* Trueman, David: History. (line 30)
* trunc-mod operation: Arithmetic Ops. (line 66)
* truth values: Truth Values. (line 6)
-* type conversion: Conversion. (line 21)
-* type internal variable: Internals. (line 59)
-* u debugger command (alias for until): Dgawk Execution Control.
+* type conversion: Strings And Numbers. (line 21)
+* u debugger command (alias for until): Debugger Execution Control.
(line 83)
+* unassigned array elements: Reference to Elements.
+ (line 18)
* undefined functions: Pass By Value/Reference.
- (line 71)
-* underscore (_), _ C macro: Explaining gettext. (line 70)
+ (line 68)
+* underscore (_), C macro: Explaining gettext. (line 71)
* underscore (_), in names of private variables: Library Names.
(line 29)
* underscore (_), translatable string: Programmer i18n. (line 69)
* undisplay debugger command: Viewing And Changing Data.
(line 80)
* undocumented features: Undocumented. (line 6)
-* Unicode: Glossary. (line 141)
+* Unicode <1>: Glossary. (line 133)
+* Unicode <2>: Ranges and Locales. (line 61)
+* Unicode: Ordinal Functions. (line 45)
* uninitialized variables, as array subscripts: Uninitialized Subscripts.
(line 6)
* uniq utility: Uniq Program. (line 6)
* uniq.awk program: Uniq Program. (line 65)
* Unix: Glossary. (line 611)
* Unix awk, backslashes in escape sequences: Escape Sequences.
- (line 125)
+ (line 120)
* Unix awk, close() function and: Close Files And Pipes.
- (line 131)
+ (line 133)
* Unix awk, password files, field separators and: Command Line Field Separator.
- (line 72)
+ (line 62)
* Unix, awk scripts and: Executable Scripts. (line 6)
-* UNIXROOT variable, on OS/2 systems: PC Using. (line 17)
-* unref() internal function: Internals. (line 92)
-* unsigned integers: Basic Data Typing. (line 30)
-* until debugger command: Dgawk Execution Control.
+* UNIXROOT variable, on OS/2 systems: PC Using. (line 16)
+* unsigned integers: Computer Arithmetic. (line 41)
+* until debugger command: Debugger Execution Control.
(line 83)
* unwatch debugger command: Viewing And Changing Data.
(line 84)
-* up debugger command: Dgawk Stack. (line 33)
-* update_ERRNO() internal function: Internals. (line 130)
-* update_ERRNO_saved() internal function: Internals. (line 135)
+* up debugger command: Execution Stack. (line 36)
* user database, reading: Passwd Functions. (line 6)
-* user-defined, functions: User-defined. (line 6)
-* user-defined, functions, counts: Profiling. (line 132)
+* user-defined functions: User-defined. (line 6)
+* user-defined, functions, counts, in a profile: Profiling. (line 137)
* user-defined, variables: Variables. (line 6)
* user-modifiable variables: User-modified. (line 6)
* users, information about, printing: Id Program. (line 6)
* users, information about, retrieving: Passwd Functions. (line 16)
-* USR1 signal: Profiling. (line 182)
+* USR1 signal, for dynamic profiling: Profiling. (line 187)
* values, numeric: Basic Data Typing. (line 13)
* values, string: Basic Data Typing. (line 13)
+* variable assignments and input files: Other Arguments. (line 26)
* variable typing: Typing and Comparison.
(line 9)
* variables <1>: Basic Data Typing. (line 6)
* variables: Other Features. (line 6)
* variables, assigning on command line: Assignment Options. (line 6)
-* variables, built-in <1>: Built-in Variables. (line 6)
-* variables, built-in: Using Variables. (line 20)
-* variables, built-in, -v option, setting with: Options. (line 40)
-* variables, built-in, conveying information: Auto-set. (line 6)
-* variables, flag: Boolean Ops. (line 67)
+* variables, built-in: Using Variables. (line 23)
+* variables, flag: Boolean Ops. (line 69)
* variables, getline command into, using <1>: Getline/Variable/Coprocess.
(line 6)
* variables, getline command into, using <2>: Getline/Variable/Pipe.
@@ -27341,52 +34345,65 @@ Index
(line 6)
* variables, getline command into, using: Getline/Variable. (line 6)
* variables, global, for library functions: Library Names. (line 11)
-* variables, global, printing list of: Options. (line 90)
-* variables, initializing: Using Variables. (line 20)
-* variables, local: Variable Scope. (line 6)
-* variables, names of: Arrays. (line 18)
+* variables, global, printing list of: Options. (line 93)
+* variables, initializing: Using Variables. (line 23)
+* variables, local to a function: Variable Scope. (line 6)
+* variables, predefined: Built-in Variables. (line 6)
+* variables, predefined -v option, setting with: Options. (line 40)
+* variables, predefined conveying information: Auto-set. (line 6)
* variables, private: Library Names. (line 11)
* variables, setting: Options. (line 32)
-* variables, shadowing: Definition Syntax. (line 61)
+* variables, shadowing: Definition Syntax. (line 71)
* variables, types of: Assignment Ops. (line 40)
* variables, types of, comparison expressions and: Typing and Comparison.
(line 9)
* variables, uninitialized, as array subscripts: Uninitialized Subscripts.
(line 6)
* variables, user-defined: Variables. (line 6)
-* vertical bar (|): Regexp Operators. (line 69)
+* version of gawk: Auto-set. (line 221)
+* version of gawk extension API: Auto-set. (line 246)
+* version of GNU MP library: Auto-set. (line 232)
+* version of GNU MPFR library: Auto-set. (line 228)
+* vertical bar (|): Regexp Operators. (line 70)
* vertical bar (|), | operator (I/O) <1>: Precedence. (line 65)
-* vertical bar (|), | operator (I/O): Getline/Pipe. (line 6)
-* vertical bar (|), |& operator (I/O) <1>: Two-way I/O. (line 44)
+* vertical bar (|), | operator (I/O): Getline/Pipe. (line 9)
+* vertical bar (|), |& operator (I/O) <1>: Two-way I/O. (line 25)
* vertical bar (|), |& operator (I/O) <2>: Precedence. (line 65)
* vertical bar (|), |& operator (I/O): Getline/Coprocess. (line 6)
* vertical bar (|), || operator <1>: Precedence. (line 89)
-* vertical bar (|), || operator: Boolean Ops. (line 57)
+* vertical bar (|), || operator: Boolean Ops. (line 59)
* Vinschen, Corinna: Acknowledgments. (line 60)
-* vname internal variable: Internals. (line 64)
* w debugger command (alias for watch): Viewing And Changing Data.
(line 67)
* w utility: Constant Size. (line 22)
+* wait() extension function: Extension Sample Fork.
+ (line 22)
+* waitpid() extension function: Extension Sample Fork.
+ (line 18)
* walk_array() user-defined function: Walking Arrays. (line 14)
* Wall, Larry <1>: Future Extensions. (line 6)
* Wall, Larry: Array Intro. (line 6)
-* Wallin, Anders: Acknowledgments. (line 60)
-* warnings, issuing: Options. (line 147)
+* Wallin, Anders: Contributors. (line 103)
+* warnings, issuing: Options. (line 185)
* watch debugger command: Viewing And Changing Data.
(line 67)
+* watchpoint: Debugging Terms. (line 42)
* wc utility: Wc Program. (line 6)
* wc.awk program: Wc Program. (line 46)
-* Weinberger, Peter <1>: Contributors. (line 12)
+* Weinberger, Peter <1>: Contributors. (line 11)
* Weinberger, Peter: History. (line 17)
-* while statement <1>: While Statement. (line 6)
-* while statement: Regexp Usage. (line 19)
+* where debugger command: Execution Stack. (line 13)
+* where debugger command (alias for backtrace): Execution Stack.
+ (line 13)
+* while statement: While Statement. (line 6)
+* while statement, use of regexps in: Regexp Usage. (line 19)
* whitespace, as field separators: Default Field Splitting.
(line 6)
* whitespace, functions, calling: Calling Built-in. (line 10)
-* whitespace, newlines as: Options. (line 205)
-* Williams, Kent: Contributors. (line 35)
+* whitespace, newlines as: Options. (line 260)
+* Williams, Kent: Contributors. (line 34)
* Woehlke, Matthew: Contributors. (line 79)
-* Woods, John: Contributors. (line 28)
+* Woods, John: Contributors. (line 27)
* word boundaries, matching: GNU Regexp Operators.
(line 38)
* word, regexp definition of: GNU Regexp Operators.
@@ -27397,869 +34414,599 @@ Index
* words, counting: Wc Program. (line 6)
* words, duplicate, searching for: Dupword Program. (line 6)
* words, usage counts, generating: Word Sorting. (line 6)
-* wstlen internal variable: Internals. (line 54)
-* wstptr internal variable: Internals. (line 54)
-* xgawk: Other Versions. (line 119)
+* writea() extension function: Extension Sample Read write array.
+ (line 12)
* xgettext utility: String Extraction. (line 13)
-* XML (eXtensible Markup Language): Internals. (line 151)
+* xor: Bitwise Functions. (line 56)
* XOR bitwise operation: Bitwise Functions. (line 6)
-* xor() function (gawk): Bitwise Functions. (line 54)
-* Yawitz, Efraim: Contributors. (line 106)
+* Yawitz, Efraim: Contributors. (line 131)
* Zaretskii, Eli <1>: Bugs. (line 70)
-* Zaretskii, Eli <2>: Contributors. (line 56)
+* Zaretskii, Eli <2>: Contributors. (line 55)
* Zaretskii, Eli: Acknowledgments. (line 60)
-* zero, negative vs. positive: Unexpected Results. (line 28)
* zerofile.awk program: Empty Files. (line 21)
-* Zoulas, Christos: Contributors. (line 67)
+* Zoulas, Christos: Contributors. (line 66)
+* {} (braces): Profiling. (line 142)
* {} (braces), actions and: Action Overview. (line 19)
-* {} (braces), pgawk program: Profiling. (line 137)
* {} (braces), statements, grouping: Statements. (line 10)
-* | (vertical bar): Regexp Operators. (line 69)
+* | (vertical bar): Regexp Operators. (line 70)
* | (vertical bar), | operator (I/O) <1>: Precedence. (line 65)
* | (vertical bar), | operator (I/O) <2>: Redirection. (line 57)
-* | (vertical bar), | operator (I/O): Getline/Pipe. (line 6)
-* | (vertical bar), |& operator (I/O) <1>: Two-way I/O. (line 44)
+* | (vertical bar), | operator (I/O): Getline/Pipe. (line 9)
+* | (vertical bar), |& operator (I/O) <1>: Two-way I/O. (line 25)
* | (vertical bar), |& operator (I/O) <2>: Precedence. (line 65)
-* | (vertical bar), |& operator (I/O) <3>: Redirection. (line 102)
+* | (vertical bar), |& operator (I/O) <3>: Redirection. (line 96)
* | (vertical bar), |& operator (I/O): Getline/Coprocess. (line 6)
* | (vertical bar), |& operator (I/O), pipes, closing: Close Files And Pipes.
- (line 118)
+ (line 121)
* | (vertical bar), || operator <1>: Precedence. (line 89)
-* | (vertical bar), || operator: Boolean Ops. (line 57)
+* | (vertical bar), || operator: Boolean Ops. (line 59)
* ~ (tilde), ~ operator <1>: Expression Patterns. (line 24)
* ~ (tilde), ~ operator <2>: Precedence. (line 80)
* ~ (tilde), ~ operator <3>: Comparison Operators.
(line 11)
* ~ (tilde), ~ operator <4>: Regexp Constants. (line 6)
-* ~ (tilde), ~ operator <5>: Computed Regexps. (line 6)
-* ~ (tilde), ~ operator <6>: Case-sensitivity. (line 26)
+* ~ (tilde), ~ operator <5>: Case-sensitivity. (line 26)
+* ~ (tilde), ~ operator <6>: Computed Regexps. (line 6)
* ~ (tilde), ~ operator: Regexp Usage. (line 19)

Tag Table:
-<<<<<<< HEAD
-Node: Top1345
-Node: Foreword33439
-Node: Preface37784
-Ref: Preface-Footnote-140837
-Ref: Preface-Footnote-240943
-Node: History41175
-Node: Names43566
-Ref: Names-Footnote-145043
-Node: This Manual45115
-Ref: This Manual-Footnote-150062
-Node: Conventions50162
-Node: Manual History52296
-Ref: Manual History-Footnote-155566
-Ref: Manual History-Footnote-255607
-Node: How To Contribute55681
-Node: Acknowledgments56825
-Node: Getting Started61156
-Node: Running gawk63535
-Node: One-shot64721
-Node: Read Terminal65946
-Ref: Read Terminal-Footnote-167596
-Ref: Read Terminal-Footnote-267872
-Node: Long68043
-Node: Executable Scripts69419
-Ref: Executable Scripts-Footnote-171288
-Ref: Executable Scripts-Footnote-271390
-Node: Comments71841
-Node: Quoting74308
-Node: DOS Quoting78931
-Node: Sample Data Files79606
-Node: Very Simple82638
-Node: Two Rules87237
-Node: More Complex89384
-Ref: More Complex-Footnote-192314
-Node: Statements/Lines92399
-Ref: Statements/Lines-Footnote-196861
-Node: Other Features97126
-Node: When98054
-Node: Invoking Gawk100201
-Node: Command Line101586
-Node: Options102369
-Ref: Options-Footnote-1115806
-Node: Other Arguments115831
-Node: Naming Standard Input118489
-Node: Environment Variables119583
-Node: AWKPATH Variable120027
-Ref: AWKPATH Variable-Footnote-1122624
-Node: Other Environment Variables122884
-Node: Exit Status125224
-Node: Include Files125899
-Node: Obsolete129384
-Node: Undocumented130070
-Node: Regexp130311
-Node: Regexp Usage131700
-Node: Escape Sequences133726
-Node: Regexp Operators139489
-Ref: Regexp Operators-Footnote-1146686
-Ref: Regexp Operators-Footnote-2146833
-Node: Bracket Expressions146931
-Ref: table-char-classes148821
-Node: GNU Regexp Operators151344
-Node: Case-sensitivity155067
-Ref: Case-sensitivity-Footnote-1158035
-Ref: Case-sensitivity-Footnote-2158270
-Node: Leftmost Longest158378
-Node: Computed Regexps159579
-Node: Reading Files162989
-Node: Records164930
-Ref: Records-Footnote-1173604
-Node: Fields173641
-Ref: Fields-Footnote-1176674
-Node: Nonconstant Fields176760
-Node: Changing Fields178962
-Node: Field Separators184940
-Node: Default Field Splitting187569
-Node: Regexp Field Splitting188686
-Node: Single Character Fields192028
-Node: Command Line Field Separator193087
-Node: Field Splitting Summary196528
-Ref: Field Splitting Summary-Footnote-1199720
-Node: Constant Size199821
-Node: Splitting By Content204405
-Ref: Splitting By Content-Footnote-1208131
-Node: Multiple Line208171
-Ref: Multiple Line-Footnote-1214018
-Node: Getline214197
-Node: Plain Getline216425
-Node: Getline/Variable218514
-Node: Getline/File219655
-Node: Getline/Variable/File220977
-Ref: Getline/Variable/File-Footnote-1222576
-Node: Getline/Pipe222663
-Node: Getline/Variable/Pipe225223
-Node: Getline/Coprocess226330
-Node: Getline/Variable/Coprocess227573
-Node: Getline Notes228287
-Node: Getline Summary230229
-Ref: table-getline-variants230572
-Node: Command line directories231428
-Node: Printing232053
-Node: Print233684
-Node: Print Examples235021
-Node: Output Separators237805
-Node: OFMT239565
-Node: Printf240923
-Node: Basic Printf241829
-Node: Control Letters243368
-Node: Format Modifiers247180
-Node: Printf Examples253189
-Node: Redirection255904
-Node: Special Files262888
-Node: Special FD263421
-Ref: Special FD-Footnote-1267046
-Node: Special Network267120
-Node: Special Caveats267970
-Node: Close Files And Pipes268766
-Ref: Close Files And Pipes-Footnote-1275789
-Ref: Close Files And Pipes-Footnote-2275937
-Node: Expressions276087
-Node: Values277219
-Node: Constants277895
-Node: Scalar Constants278575
-Ref: Scalar Constants-Footnote-1279434
-Node: Nondecimal-numbers279616
-Node: Regexp Constants282675
-Node: Using Constant Regexps283150
-Node: Variables286205
-Node: Using Variables286860
-Node: Assignment Options288584
-Node: Conversion290456
-Ref: table-locale-affects295832
-Ref: Conversion-Footnote-1296456
-Node: All Operators296565
-Node: Arithmetic Ops297195
-Node: Concatenation299700
-Ref: Concatenation-Footnote-1302493
-Node: Assignment Ops302613
-Ref: table-assign-ops307601
-Node: Increment Ops309009
-Node: Truth Values and Conditions312479
-Node: Truth Values313562
-Node: Typing and Comparison314611
-Node: Variable Typing315400
-Ref: Variable Typing-Footnote-1319297
-Node: Comparison Operators319419
-Ref: table-relational-ops319829
-Node: POSIX String Comparison323378
-Ref: POSIX String Comparison-Footnote-1324334
-Node: Boolean Ops324472
-Ref: Boolean Ops-Footnote-1328550
-Node: Conditional Exp328641
-Node: Function Calls330373
-Node: Precedence333967
-Node: Locales337636
-Node: Patterns and Actions338725
-Node: Pattern Overview339779
-Node: Regexp Patterns341445
-Node: Expression Patterns341988
-Node: Ranges345673
-Node: BEGIN/END348639
-Node: Using BEGIN/END349401
-Ref: Using BEGIN/END-Footnote-1352132
-Node: I/O And BEGIN/END352238
-Node: BEGINFILE/ENDFILE354520
-Node: Empty357413
-Node: Using Shell Variables357729
-Node: Action Overview360014
-Node: Statements362371
-Node: If Statement364225
-Node: While Statement365724
-Node: Do Statement367768
-Node: For Statement368924
-Node: Switch Statement372076
-Node: Break Statement374173
-Node: Continue Statement376163
-Node: Next Statement377950
-Node: Nextfile Statement380340
-Node: Exit Statement382885
-Node: Built-in Variables385301
-Node: User-modified386396
-Ref: User-modified-Footnote-1394422
-Node: Auto-set394484
-Ref: Auto-set-Footnote-1403775
-Node: ARGC and ARGV403980
-Node: Arrays407831
-Node: Array Basics409336
-Node: Array Intro410047
-Node: Reference to Elements414365
-Node: Assigning Elements416635
-Node: Array Example417126
-Node: Scanning an Array418858
-Node: Delete421524
-Ref: Delete-Footnote-1423959
-Node: Numeric Array Subscripts424016
-Node: Uninitialized Subscripts426199
-Node: Multi-dimensional427827
-Node: Multi-scanning430921
-Node: Arrays of Arrays432505
-Node: Functions437082
-Node: Built-in437904
-Node: Calling Built-in438982
-Node: Numeric Functions440970
-Ref: Numeric Functions-Footnote-1444735
-Ref: Numeric Functions-Footnote-2445092
-Ref: Numeric Functions-Footnote-3445140
-Node: String Functions445409
-Ref: String Functions-Footnote-1468906
-Ref: String Functions-Footnote-2469035
-Ref: String Functions-Footnote-3469283
-Node: Gory Details469370
-Ref: table-sub-escapes471049
-Ref: table-sub-posix-92472403
-Ref: table-sub-proposed473746
-Ref: table-posix-sub475096
-Ref: table-gensub-escapes476642
-Ref: Gory Details-Footnote-1477849
-Ref: Gory Details-Footnote-2477900
-Node: I/O Functions478051
-Ref: I/O Functions-Footnote-1484706
-Node: Time Functions484853
-Ref: Time Functions-Footnote-1495745
-Ref: Time Functions-Footnote-2495813
-Ref: Time Functions-Footnote-3495971
-Ref: Time Functions-Footnote-4496082
-Ref: Time Functions-Footnote-5496194
-Ref: Time Functions-Footnote-6496421
-Node: Bitwise Functions496687
-Ref: table-bitwise-ops497245
-Ref: Bitwise Functions-Footnote-1501405
-Node: Type Functions501589
-Node: I18N Functions502059
-Node: User-defined503686
-Node: Definition Syntax504490
-Ref: Definition Syntax-Footnote-1509400
-Node: Function Example509469
-Node: Function Caveats512063
-Node: Calling A Function512484
-Node: Variable Scope513599
-Node: Pass By Value/Reference515574
-Node: Return Statement519014
-Node: Dynamic Typing521995
-Node: Indirect Calls522730
-Node: Internationalization532415
-Node: I18N and L10N533841
-Node: Explaining gettext534527
-Ref: Explaining gettext-Footnote-1539593
-Ref: Explaining gettext-Footnote-2539777
-Node: Programmer i18n539942
-Node: Translator i18n544142
-Node: String Extraction544935
-Ref: String Extraction-Footnote-1545896
-Node: Printf Ordering545982
-Ref: Printf Ordering-Footnote-1548766
-Node: I18N Portability548830
-Ref: I18N Portability-Footnote-1551279
-Node: I18N Example551342
-Ref: I18N Example-Footnote-1553977
-Node: Gawk I18N554049
-Node: Advanced Features554666
-Node: Nondecimal Data556179
-Node: Array Sorting557762
-Node: Controlling Array Traversal558462
-Node: Controlling Scanning With A Function559209
-Node: Controlling Scanning566912
-Ref: Controlling Scanning-Footnote-1570713
-Node: Array Sorting Functions571029
-Ref: Array Sorting Functions-Footnote-1574545
-Ref: Array Sorting Functions-Footnote-2574638
-Node: Two-way I/O574832
-Ref: Two-way I/O-Footnote-1580264
-Node: TCP/IP Networking580334
-Node: Profiling583178
-Node: Library Functions590652
-Ref: Library Functions-Footnote-1593659
-Node: Library Names593830
-Ref: Library Names-Footnote-1597301
-Ref: Library Names-Footnote-2597521
-Node: General Functions597607
-Node: Strtonum Function598560
-Node: Assert Function601490
-Node: Round Function604816
-Node: Cliff Random Function606359
-Node: Ordinal Functions607375
-Ref: Ordinal Functions-Footnote-1610445
-Ref: Ordinal Functions-Footnote-2610697
-Node: Join Function610906
-Ref: Join Function-Footnote-1612677
-Node: Gettimeofday Function612877
-Node: Data File Management616592
-Node: Filetrans Function617224
-Node: Rewind Function621363
-Node: File Checking622750
-Node: Empty Files623844
-Node: Ignoring Assigns626074
-Node: Getopt Function627627
-Ref: Getopt Function-Footnote-1638931
-Node: Passwd Functions639134
-Ref: Passwd Functions-Footnote-1648109
-Node: Group Functions648197
-Node: Walking Arrays656281
-Node: Sample Programs657850
-Node: Running Examples658515
-Node: Clones659243
-Node: Cut Program660467
-Node: Egrep Program670312
-Ref: Egrep Program-Footnote-1678085
-Node: Id Program678195
-Node: Split Program681811
-Ref: Split Program-Footnote-1685330
-Node: Tee Program685458
-Node: Uniq Program688261
-Node: Wc Program695690
-Ref: Wc Program-Footnote-1699956
-Ref: Wc Program-Footnote-2700156
-Node: Miscellaneous Programs700248
-Node: Dupword Program701436
-Node: Alarm Program703467
-Node: Translate Program708216
-Ref: Translate Program-Footnote-1712603
-Ref: Translate Program-Footnote-2712831
-Node: Labels Program712965
-Ref: Labels Program-Footnote-1716336
-Node: Word Sorting716420
-Node: History Sorting720304
-Node: Extract Program722143
-Ref: Extract Program-Footnote-1729626
-Node: Simple Sed729754
-Node: Igawk Program732816
-Ref: Igawk Program-Footnote-1747973
-Ref: Igawk Program-Footnote-2748174
-Node: Anagram Program748312
-Node: Signature Program751380
-Node: Debugger752480
-Node: Debugging753391
-Node: Debugging Concepts753804
-Node: Debugging Terms755660
-Node: Awk Debugging758283
-Node: Sample dgawk session759175
-Node: dgawk invocation759667
-Node: Finding The Bug760849
-Node: List of Debugger Commands767335
-Node: Breakpoint Control768646
-Node: Dgawk Execution Control772282
-Node: Viewing And Changing Data775633
-Node: Dgawk Stack778970
-Node: Dgawk Info780430
-Node: Miscellaneous Dgawk Commands784378
-Node: Readline Support789806
-Node: Dgawk Limitations790644
-Node: Language History792833
-Node: V7/SVR3.1794345
-Node: SVR4796666
-Node: POSIX798108
-Node: BTL799116
-Node: POSIX/GNU799850
-Node: Common Extensions805001
-Node: Ranges and Locales806108
-Ref: Ranges and Locales-Footnote-1810715
-Node: Contributors810936
-Node: Installation815198
-Node: Gawk Distribution816092
-Node: Getting816576
-Node: Extracting817402
-Node: Distribution contents819094
-Node: Unix Installation824316
-Node: Quick Installation824933
-Node: Additional Configuration Options826895
-Node: Configuration Philosophy828372
-Node: Non-Unix Installation830714
-Node: PC Installation831172
-Node: PC Binary Installation832471
-Node: PC Compiling834319
-Node: PC Testing837263
-Node: PC Using838439
-Node: Cygwin842624
-Node: MSYS843624
-Node: VMS Installation844138
-Node: VMS Compilation844741
-Ref: VMS Compilation-Footnote-1845748
-Node: VMS Installation Details845806
-Node: VMS Running847441
-Node: VMS Old Gawk849048
-Node: Bugs849522
-=======
-Node: Top1346
-Node: Foreword33440
-Node: Preface37785
-Ref: Preface-Footnote-140838
-Ref: Preface-Footnote-240944
-Node: History41176
-Node: Names43567
-Ref: Names-Footnote-145044
-Node: This Manual45116
-Ref: This Manual-Footnote-150063
-Node: Conventions50163
-Node: Manual History52297
-Ref: Manual History-Footnote-155567
-Ref: Manual History-Footnote-255608
-Node: How To Contribute55682
-Node: Acknowledgments56826
-Node: Getting Started61157
-Node: Running gawk63536
-Node: One-shot64722
-Node: Read Terminal65947
-Ref: Read Terminal-Footnote-167597
-Ref: Read Terminal-Footnote-267873
-Node: Long68044
-Node: Executable Scripts69420
-Ref: Executable Scripts-Footnote-171289
-Ref: Executable Scripts-Footnote-271391
-Node: Comments71842
-Node: Quoting74309
-Node: DOS Quoting78932
-Node: Sample Data Files79607
-Node: Very Simple82639
-Node: Two Rules87238
-Node: More Complex89385
-Ref: More Complex-Footnote-192315
-Node: Statements/Lines92400
-Ref: Statements/Lines-Footnote-196862
-Node: Other Features97127
-Node: When98055
-Node: Invoking Gawk100202
-Node: Command Line101587
-Node: Options102370
-Ref: Options-Footnote-1115807
-Node: Other Arguments115832
-Node: Naming Standard Input118490
-Node: Environment Variables119584
-Node: AWKPATH Variable120028
-Ref: AWKPATH Variable-Footnote-1122625
-Node: Other Environment Variables122885
-Node: Exit Status125225
-Node: Include Files125900
-Node: Obsolete129385
-Node: Undocumented130071
-Node: Regexp130312
-Node: Regexp Usage131701
-Node: Escape Sequences133727
-Node: Regexp Operators139490
-Ref: Regexp Operators-Footnote-1146687
-Ref: Regexp Operators-Footnote-2146834
-Node: Bracket Expressions146932
-Ref: table-char-classes148822
-Node: GNU Regexp Operators151345
-Node: Case-sensitivity155068
-Ref: Case-sensitivity-Footnote-1158036
-Ref: Case-sensitivity-Footnote-2158271
-Node: Leftmost Longest158379
-Node: Computed Regexps159580
-Node: Reading Files162990
-Node: Records164931
-Ref: Records-Footnote-1173605
-Node: Fields173642
-Ref: Fields-Footnote-1176675
-Node: Nonconstant Fields176761
-Node: Changing Fields178963
-Node: Field Separators184941
-Node: Default Field Splitting187570
-Node: Regexp Field Splitting188687
-Node: Single Character Fields192029
-Node: Command Line Field Separator193088
-Node: Field Splitting Summary196529
-Ref: Field Splitting Summary-Footnote-1199721
-Node: Constant Size199822
-Node: Splitting By Content204406
-Ref: Splitting By Content-Footnote-1208132
-Node: Multiple Line208172
-Ref: Multiple Line-Footnote-1214019
-Node: Getline214198
-Node: Plain Getline216426
-Node: Getline/Variable218515
-Node: Getline/File219656
-Node: Getline/Variable/File220978
-Ref: Getline/Variable/File-Footnote-1222577
-Node: Getline/Pipe222664
-Node: Getline/Variable/Pipe225224
-Node: Getline/Coprocess226331
-Node: Getline/Variable/Coprocess227574
-Node: Getline Notes228288
-Node: Getline Summary230230
-Ref: table-getline-variants230573
-Node: Command line directories231429
-Node: Printing232054
-Node: Print233685
-Node: Print Examples235022
-Node: Output Separators237806
-Node: OFMT239566
-Node: Printf240924
-Node: Basic Printf241830
-Node: Control Letters243369
-Node: Format Modifiers247181
-Node: Printf Examples253190
-Node: Redirection255905
-Node: Special Files262889
-Node: Special FD263422
-Ref: Special FD-Footnote-1267047
-Node: Special Network267121
-Node: Special Caveats267971
-Node: Close Files And Pipes268767
-Ref: Close Files And Pipes-Footnote-1275790
-Ref: Close Files And Pipes-Footnote-2275938
-Node: Expressions276088
-Node: Values277220
-Node: Constants277896
-Node: Scalar Constants278576
-Ref: Scalar Constants-Footnote-1279435
-Node: Nondecimal-numbers279617
-Node: Regexp Constants282676
-Node: Using Constant Regexps283151
-Node: Variables286206
-Node: Using Variables286861
-Node: Assignment Options288585
-Node: Conversion290457
-Ref: table-locale-affects295833
-Ref: Conversion-Footnote-1296457
-Node: All Operators296566
-Node: Arithmetic Ops297196
-Node: Concatenation299701
-Ref: Concatenation-Footnote-1302494
-Node: Assignment Ops302614
-Ref: table-assign-ops307602
-Node: Increment Ops309010
-Node: Truth Values and Conditions312480
-Node: Truth Values313563
-Node: Typing and Comparison314612
-Node: Variable Typing315401
-Ref: Variable Typing-Footnote-1319298
-Node: Comparison Operators319420
-Ref: table-relational-ops319830
-Node: POSIX String Comparison323379
-Ref: POSIX String Comparison-Footnote-1324335
-Node: Boolean Ops324473
-Ref: Boolean Ops-Footnote-1328551
-Node: Conditional Exp328642
-Node: Function Calls330374
-Node: Precedence333968
-Node: Locales337637
-Node: Patterns and Actions338726
-Node: Pattern Overview339780
-Node: Regexp Patterns341446
-Node: Expression Patterns341989
-Node: Ranges345674
-Node: BEGIN/END348640
-Node: Using BEGIN/END349402
-Ref: Using BEGIN/END-Footnote-1352133
-Node: I/O And BEGIN/END352239
-Node: BEGINFILE/ENDFILE354521
-Node: Empty357414
-Node: Using Shell Variables357730
-Node: Action Overview360015
-Node: Statements362372
-Node: If Statement364226
-Node: While Statement365725
-Node: Do Statement367769
-Node: For Statement368925
-Node: Switch Statement372077
-Node: Break Statement374174
-Node: Continue Statement376164
-Node: Next Statement377951
-Node: Nextfile Statement380341
-Node: Exit Statement382886
-Node: Built-in Variables385302
-Node: User-modified386397
-Ref: User-modified-Footnote-1394423
-Node: Auto-set394485
-Ref: Auto-set-Footnote-1403776
-Node: ARGC and ARGV403981
-Node: Arrays407832
-Node: Array Basics409337
-Node: Array Intro410048
-Node: Reference to Elements414366
-Node: Assigning Elements416636
-Node: Array Example417127
-Node: Scanning an Array418859
-Node: Delete421525
-Ref: Delete-Footnote-1423960
-Node: Numeric Array Subscripts424017
-Node: Uninitialized Subscripts426200
-Node: Multi-dimensional427828
-Node: Multi-scanning430922
-Node: Arrays of Arrays432506
-Node: Functions437083
-Node: Built-in437905
-Node: Calling Built-in438983
-Node: Numeric Functions440971
-Ref: Numeric Functions-Footnote-1444736
-Ref: Numeric Functions-Footnote-2445093
-Ref: Numeric Functions-Footnote-3445141
-Node: String Functions445410
-Ref: String Functions-Footnote-1468907
-Ref: String Functions-Footnote-2469036
-Ref: String Functions-Footnote-3469284
-Node: Gory Details469371
-Ref: table-sub-escapes471050
-Ref: table-sub-posix-92472404
-Ref: table-sub-proposed473747
-Ref: table-posix-sub475097
-Ref: table-gensub-escapes476643
-Ref: Gory Details-Footnote-1477850
-Ref: Gory Details-Footnote-2477901
-Node: I/O Functions478052
-Ref: I/O Functions-Footnote-1484707
-Node: Time Functions484854
-Ref: Time Functions-Footnote-1495746
-Ref: Time Functions-Footnote-2495814
-Ref: Time Functions-Footnote-3495972
-Ref: Time Functions-Footnote-4496083
-Ref: Time Functions-Footnote-5496195
-Ref: Time Functions-Footnote-6496422
-Node: Bitwise Functions496688
-Ref: table-bitwise-ops497246
-Ref: Bitwise Functions-Footnote-1501406
-Node: Type Functions501590
-Node: I18N Functions502060
-Node: User-defined503687
-Node: Definition Syntax504491
-Ref: Definition Syntax-Footnote-1509401
-Node: Function Example509470
-Node: Function Caveats512064
-Node: Calling A Function512485
-Node: Variable Scope513600
-Node: Pass By Value/Reference515575
-Node: Return Statement519015
-Node: Dynamic Typing521996
-Node: Indirect Calls522731
-Node: Internationalization532416
-Node: I18N and L10N533842
-Node: Explaining gettext534528
-Ref: Explaining gettext-Footnote-1539594
-Ref: Explaining gettext-Footnote-2539778
-Node: Programmer i18n539943
-Node: Translator i18n544143
-Node: String Extraction544936
-Ref: String Extraction-Footnote-1545897
-Node: Printf Ordering545983
-Ref: Printf Ordering-Footnote-1548767
-Node: I18N Portability548831
-Ref: I18N Portability-Footnote-1551280
-Node: I18N Example551343
-Ref: I18N Example-Footnote-1553978
-Node: Gawk I18N554050
-Node: Advanced Features554667
-Node: Nondecimal Data556180
-Node: Array Sorting557763
-Node: Controlling Array Traversal558463
-Node: Controlling Scanning With A Function559210
-Node: Controlling Scanning566913
-Ref: Controlling Scanning-Footnote-1570714
-Node: Array Sorting Functions571030
-Ref: Array Sorting Functions-Footnote-1574546
-Ref: Array Sorting Functions-Footnote-2574639
-Node: Two-way I/O574833
-Ref: Two-way I/O-Footnote-1580265
-Node: TCP/IP Networking580335
-Node: Profiling583179
-Node: Library Functions590653
-Ref: Library Functions-Footnote-1593660
-Node: Library Names593831
-Ref: Library Names-Footnote-1597302
-Ref: Library Names-Footnote-2597522
-Node: General Functions597608
-Node: Strtonum Function598561
-Node: Assert Function601491
-Node: Round Function604817
-Node: Cliff Random Function606360
-Node: Ordinal Functions607376
-Ref: Ordinal Functions-Footnote-1610446
-Ref: Ordinal Functions-Footnote-2610698
-Node: Join Function610907
-Ref: Join Function-Footnote-1612678
-Node: Gettimeofday Function612878
-Node: Data File Management616593
-Node: Filetrans Function617225
-Node: Rewind Function621364
-Node: File Checking622751
-Node: Empty Files623845
-Node: Ignoring Assigns626075
-Node: Getopt Function627628
-Ref: Getopt Function-Footnote-1638932
-Node: Passwd Functions639135
-Ref: Passwd Functions-Footnote-1648110
-Node: Group Functions648198
-Node: Walking Arrays656282
-Node: Sample Programs657851
-Node: Running Examples658516
-Node: Clones659244
-Node: Cut Program660468
-Node: Egrep Program670313
-Ref: Egrep Program-Footnote-1678086
-Node: Id Program678196
-Node: Split Program681812
-Ref: Split Program-Footnote-1685331
-Node: Tee Program685459
-Node: Uniq Program688262
-Node: Wc Program695691
-Ref: Wc Program-Footnote-1699957
-Ref: Wc Program-Footnote-2700157
-Node: Miscellaneous Programs700249
-Node: Dupword Program701437
-Node: Alarm Program703468
-Node: Translate Program708217
-Ref: Translate Program-Footnote-1712604
-Ref: Translate Program-Footnote-2712832
-Node: Labels Program712966
-Ref: Labels Program-Footnote-1716337
-Node: Word Sorting716421
-Node: History Sorting720305
-Node: Extract Program722144
-Ref: Extract Program-Footnote-1729627
-Node: Simple Sed729755
-Node: Igawk Program732817
-Ref: Igawk Program-Footnote-1747974
-Ref: Igawk Program-Footnote-2748175
-Node: Anagram Program748313
-Node: Signature Program751381
-Node: Debugger752481
-Node: Debugging753392
-Node: Debugging Concepts753805
-Node: Debugging Terms755661
-Node: Awk Debugging758284
-Node: Sample dgawk session759176
-Node: dgawk invocation759668
-Node: Finding The Bug760850
-Node: List of Debugger Commands767336
-Node: Breakpoint Control768647
-Node: Dgawk Execution Control772283
-Node: Viewing And Changing Data775634
-Node: Dgawk Stack778971
-Node: Dgawk Info780431
-Node: Miscellaneous Dgawk Commands784379
-Node: Readline Support789807
-Node: Dgawk Limitations790645
-Node: Language History792834
-Node: V7/SVR3.1794346
-Node: SVR4796667
-Node: POSIX798109
-Node: BTL799117
-Node: POSIX/GNU799851
-Node: Common Extensions805002
-Node: Ranges and Locales806109
-Ref: Ranges and Locales-Footnote-1810716
-Node: Contributors810937
-Node: Installation815199
-Node: Gawk Distribution816093
-Node: Getting816577
-Node: Extracting817403
-Node: Distribution contents819095
-Node: Unix Installation824317
-Node: Quick Installation824934
-Node: Additional Configuration Options826896
-Node: Configuration Philosophy828373
-Node: Non-Unix Installation830715
-Node: PC Installation831173
-Node: PC Binary Installation832472
-Node: PC Compiling834320
-Node: PC Testing837264
-Node: PC Using838440
-Node: Cygwin842625
-Node: MSYS843625
-Node: VMS Installation844139
-Node: VMS Compilation844742
-Ref: VMS Compilation-Footnote-1845749
-Node: VMS Installation Details845807
-Node: VMS Running847442
-Node: VMS Old Gawk849049
-Node: Bugs849523
->>>>>>> gawk-4.0-stable
-Node: Other Versions853375
-Node: Notes858656
-Node: Compatibility Mode859348
-Node: Additions860131
-Node: Accessing The Source860943
-Node: Adding Code862368
-Node: New Ports868335
-Node: Dynamic Extensions872448
-Node: Internals873824
-<<<<<<< HEAD
-Node: Plugin License882343
-Node: Sample Library882977
-Node: Internal File Description883663
-Node: Internal File Ops887378
-Ref: Internal File Ops-Footnote-1892102
-Node: Using Internal File Ops892242
-Node: Future Extensions894619
-Node: Basic Concepts897123
-Node: Basic High Level897880
-Ref: Basic High Level-Footnote-1901915
-Node: Basic Data Typing902100
-Node: Floating Point Issues906625
-Node: String Conversion Precision907708
-Ref: String Conversion Precision-Footnote-1909408
-Node: Unexpected Results909517
-Node: POSIX Floating Point Problems911343
-Ref: POSIX Floating Point Problems-Footnote-1915048
-Node: Glossary915086
-Node: Copying940062
-Node: GNU Free Documentation License977619
-Node: Index1002756
-=======
-Node: Plugin License882927
-Node: Sample Library883561
-Node: Internal File Description884247
-Node: Internal File Ops887962
-Ref: Internal File Ops-Footnote-1892743
-Node: Using Internal File Ops892883
-Node: Future Extensions895260
-Node: Basic Concepts897764
-Node: Basic High Level898521
-Ref: Basic High Level-Footnote-1902556
-Node: Basic Data Typing902741
-Node: Floating Point Issues907266
-Node: String Conversion Precision908349
-Ref: String Conversion Precision-Footnote-1910049
-Node: Unexpected Results910158
-Node: POSIX Floating Point Problems911984
-Ref: POSIX Floating Point Problems-Footnote-1915689
-Node: Glossary915727
-Node: Copying940703
-Node: GNU Free Documentation License978260
-Node: Index1003397
->>>>>>> gawk-4.0-stable
+Node: Top1204
+Node: Foreword342225
+Node: Foreword446669
+Node: Preface48200
+Ref: Preface-Footnote-151071
+Ref: Preface-Footnote-251178
+Ref: Preface-Footnote-351411
+Node: History51553
+Node: Names53904
+Ref: Names-Footnote-154997
+Node: This Manual55143
+Ref: This Manual-Footnote-161643
+Node: Conventions61743
+Node: Manual History64080
+Ref: Manual History-Footnote-167073
+Ref: Manual History-Footnote-267114
+Node: How To Contribute67188
+Node: Acknowledgments68317
+Node: Getting Started73134
+Node: Running gawk75573
+Node: One-shot76763
+Node: Read Terminal78027
+Node: Long80058
+Node: Executable Scripts81571
+Ref: Executable Scripts-Footnote-184360
+Node: Comments84463
+Node: Quoting86945
+Node: DOS Quoting92463
+Node: Sample Data Files93138
+Node: Very Simple95733
+Node: Two Rules100632
+Node: More Complex102518
+Node: Statements/Lines105380
+Ref: Statements/Lines-Footnote-1109835
+Node: Other Features110100
+Node: When111036
+Ref: When-Footnote-1112790
+Node: Intro Summary112855
+Node: Invoking Gawk113739
+Node: Command Line115253
+Node: Options116051
+Ref: Options-Footnote-1131846
+Ref: Options-Footnote-2132075
+Node: Other Arguments132100
+Node: Naming Standard Input135048
+Node: Environment Variables136141
+Node: AWKPATH Variable136699
+Ref: AWKPATH Variable-Footnote-1140106
+Ref: AWKPATH Variable-Footnote-2140151
+Node: AWKLIBPATH Variable140411
+Node: Other Environment Variables141667
+Node: Exit Status145185
+Node: Include Files145861
+Node: Loading Shared Libraries149450
+Node: Obsolete150877
+Node: Undocumented151569
+Node: Invoking Summary151836
+Node: Regexp153499
+Node: Regexp Usage154953
+Node: Escape Sequences156990
+Node: Regexp Operators163230
+Ref: Regexp Operators-Footnote-1170640
+Ref: Regexp Operators-Footnote-2170787
+Node: Bracket Expressions170885
+Ref: table-char-classes172900
+Node: Leftmost Longest175825
+Node: Computed Regexps177127
+Node: GNU Regexp Operators180524
+Node: Case-sensitivity184197
+Ref: Case-sensitivity-Footnote-1187082
+Ref: Case-sensitivity-Footnote-2187317
+Node: Regexp Summary187425
+Node: Reading Files188892
+Node: Records190986
+Node: awk split records191719
+Node: gawk split records196634
+Ref: gawk split records-Footnote-1201178
+Node: Fields201215
+Ref: Fields-Footnote-1203991
+Node: Nonconstant Fields204077
+Ref: Nonconstant Fields-Footnote-1206320
+Node: Changing Fields206524
+Node: Field Separators212453
+Node: Default Field Splitting215158
+Node: Regexp Field Splitting216275
+Node: Single Character Fields219625
+Node: Command Line Field Separator220684
+Node: Full Line Fields223896
+Ref: Full Line Fields-Footnote-1225413
+Ref: Full Line Fields-Footnote-2225459
+Node: Field Splitting Summary225560
+Node: Constant Size227634
+Node: Splitting By Content232223
+Ref: Splitting By Content-Footnote-1236217
+Node: Multiple Line236380
+Ref: Multiple Line-Footnote-1242266
+Node: Getline242445
+Node: Plain Getline244657
+Node: Getline/Variable247297
+Node: Getline/File248445
+Node: Getline/Variable/File249829
+Ref: Getline/Variable/File-Footnote-1251432
+Node: Getline/Pipe251519
+Node: Getline/Variable/Pipe254202
+Node: Getline/Coprocess255333
+Node: Getline/Variable/Coprocess256585
+Node: Getline Notes257324
+Node: Getline Summary260116
+Ref: table-getline-variants260528
+Node: Read Timeout261357
+Ref: Read Timeout-Footnote-1265181
+Node: Command-line directories265239
+Node: Input Summary266144
+Node: Input Exercises269445
+Node: Printing270173
+Node: Print271950
+Node: Print Examples273407
+Node: Output Separators276186
+Node: OFMT278204
+Node: Printf279558
+Node: Basic Printf280343
+Node: Control Letters281913
+Node: Format Modifiers285896
+Node: Printf Examples291905
+Node: Redirection294391
+Node: Special FD301232
+Ref: Special FD-Footnote-1304392
+Node: Special Files304466
+Node: Other Inherited Files305083
+Node: Special Network306083
+Node: Special Caveats306945
+Node: Close Files And Pipes307896
+Ref: Close Files And Pipes-Footnote-1315078
+Ref: Close Files And Pipes-Footnote-2315226
+Node: Output Summary315376
+Node: Output Exercises316374
+Node: Expressions317054
+Node: Values318239
+Node: Constants318917
+Node: Scalar Constants319608
+Ref: Scalar Constants-Footnote-1320467
+Node: Nondecimal-numbers320717
+Node: Regexp Constants323735
+Node: Using Constant Regexps324260
+Node: Variables327403
+Node: Using Variables328058
+Node: Assignment Options329969
+Node: Conversion331844
+Node: Strings And Numbers332368
+Ref: Strings And Numbers-Footnote-1335433
+Node: Locale influences conversions335542
+Ref: table-locale-affects338289
+Node: All Operators338877
+Node: Arithmetic Ops339507
+Node: Concatenation342012
+Ref: Concatenation-Footnote-1344831
+Node: Assignment Ops344937
+Ref: table-assign-ops349916
+Node: Increment Ops351188
+Node: Truth Values and Conditions354626
+Node: Truth Values355711
+Node: Typing and Comparison356760
+Node: Variable Typing357570
+Node: Comparison Operators361223
+Ref: table-relational-ops361633
+Node: POSIX String Comparison365128
+Ref: POSIX String Comparison-Footnote-1366200
+Node: Boolean Ops366338
+Ref: Boolean Ops-Footnote-1370817
+Node: Conditional Exp370908
+Node: Function Calls372635
+Node: Precedence376515
+Node: Locales380176
+Node: Expressions Summary381808
+Node: Patterns and Actions384368
+Node: Pattern Overview385488
+Node: Regexp Patterns387167
+Node: Expression Patterns387710
+Node: Ranges391420
+Node: BEGIN/END394526
+Node: Using BEGIN/END395287
+Ref: Using BEGIN/END-Footnote-1398021
+Node: I/O And BEGIN/END398127
+Node: BEGINFILE/ENDFILE400441
+Node: Empty403342
+Node: Using Shell Variables403659
+Node: Action Overview405932
+Node: Statements408258
+Node: If Statement410106
+Node: While Statement411601
+Node: Do Statement413630
+Node: For Statement414774
+Node: Switch Statement417931
+Node: Break Statement420313
+Node: Continue Statement422354
+Node: Next Statement424181
+Node: Nextfile Statement426562
+Node: Exit Statement429192
+Node: Built-in Variables431595
+Node: User-modified432728
+Ref: User-modified-Footnote-1440409
+Node: Auto-set440471
+Ref: Auto-set-Footnote-1454163
+Ref: Auto-set-Footnote-2454368
+Node: ARGC and ARGV454424
+Node: Pattern Action Summary458642
+Node: Arrays461069
+Node: Array Basics462398
+Node: Array Intro463242
+Ref: figure-array-elements465206
+Ref: Array Intro-Footnote-1467732
+Node: Reference to Elements467860
+Node: Assigning Elements470312
+Node: Array Example470803
+Node: Scanning an Array472561
+Node: Controlling Scanning475577
+Ref: Controlling Scanning-Footnote-1480773
+Node: Numeric Array Subscripts481089
+Node: Uninitialized Subscripts483274
+Node: Delete484891
+Ref: Delete-Footnote-1487634
+Node: Multidimensional487691
+Node: Multiscanning490788
+Node: Arrays of Arrays492377
+Node: Arrays Summary497136
+Node: Functions499228
+Node: Built-in500127
+Node: Calling Built-in501205
+Node: Numeric Functions503196
+Ref: Numeric Functions-Footnote-1508015
+Ref: Numeric Functions-Footnote-2508372
+Ref: Numeric Functions-Footnote-3508420
+Node: String Functions508692
+Ref: String Functions-Footnote-1532167
+Ref: String Functions-Footnote-2532296
+Ref: String Functions-Footnote-3532544
+Node: Gory Details532631
+Ref: table-sub-escapes534412
+Ref: table-sub-proposed535932
+Ref: table-posix-sub537296
+Ref: table-gensub-escapes538832
+Ref: Gory Details-Footnote-1539664
+Node: I/O Functions539815
+Ref: I/O Functions-Footnote-1547033
+Node: Time Functions547180
+Ref: Time Functions-Footnote-1557668
+Ref: Time Functions-Footnote-2557736
+Ref: Time Functions-Footnote-3557894
+Ref: Time Functions-Footnote-4558005
+Ref: Time Functions-Footnote-5558117
+Ref: Time Functions-Footnote-6558344
+Node: Bitwise Functions558610
+Ref: table-bitwise-ops559172
+Ref: Bitwise Functions-Footnote-1563481
+Node: Type Functions563650
+Node: I18N Functions564801
+Node: User-defined566446
+Node: Definition Syntax567251
+Ref: Definition Syntax-Footnote-1572658
+Node: Function Example572729
+Ref: Function Example-Footnote-1575648
+Node: Function Caveats575670
+Node: Calling A Function576188
+Node: Variable Scope577146
+Node: Pass By Value/Reference580134
+Node: Return Statement583629
+Node: Dynamic Typing586610
+Node: Indirect Calls587539
+Ref: Indirect Calls-Footnote-1598841
+Node: Functions Summary598969
+Node: Library Functions601671
+Ref: Library Functions-Footnote-1605280
+Ref: Library Functions-Footnote-2605423
+Node: Library Names605594
+Ref: Library Names-Footnote-1609048
+Ref: Library Names-Footnote-2609271
+Node: General Functions609357
+Node: Strtonum Function610460
+Node: Assert Function613482
+Node: Round Function616806
+Node: Cliff Random Function618347
+Node: Ordinal Functions619363
+Ref: Ordinal Functions-Footnote-1622426
+Ref: Ordinal Functions-Footnote-2622678
+Node: Join Function622889
+Ref: Join Function-Footnote-1624658
+Node: Getlocaltime Function624858
+Node: Readfile Function628602
+Node: Shell Quoting630572
+Node: Data File Management631973
+Node: Filetrans Function632605
+Node: Rewind Function636661
+Node: File Checking638048
+Ref: File Checking-Footnote-1639380
+Node: Empty Files639581
+Node: Ignoring Assigns641560
+Node: Getopt Function643111
+Ref: Getopt Function-Footnote-1654573
+Node: Passwd Functions654773
+Ref: Passwd Functions-Footnote-1663610
+Node: Group Functions663698
+Ref: Group Functions-Footnote-1671592
+Node: Walking Arrays671805
+Node: Library Functions Summary673408
+Node: Library Exercises674809
+Node: Sample Programs676089
+Node: Running Examples676859
+Node: Clones677587
+Node: Cut Program678811
+Node: Egrep Program688530
+Ref: Egrep Program-Footnote-1696028
+Node: Id Program696138
+Node: Split Program699783
+Ref: Split Program-Footnote-1703231
+Node: Tee Program703359
+Node: Uniq Program706148
+Node: Wc Program713567
+Ref: Wc Program-Footnote-1717817
+Node: Miscellaneous Programs717911
+Node: Dupword Program719124
+Node: Alarm Program721155
+Node: Translate Program725959
+Ref: Translate Program-Footnote-1730524
+Node: Labels Program730794
+Ref: Labels Program-Footnote-1734145
+Node: Word Sorting734229
+Node: History Sorting738300
+Node: Extract Program740136
+Node: Simple Sed747661
+Node: Igawk Program750729
+Ref: Igawk Program-Footnote-1765053
+Ref: Igawk Program-Footnote-2765254
+Ref: Igawk Program-Footnote-3765376
+Node: Anagram Program765491
+Node: Signature Program768548
+Node: Programs Summary769795
+Node: Programs Exercises770988
+Ref: Programs Exercises-Footnote-1775119
+Node: Advanced Features775210
+Node: Nondecimal Data777158
+Node: Array Sorting778748
+Node: Controlling Array Traversal779445
+Ref: Controlling Array Traversal-Footnote-1787778
+Node: Array Sorting Functions787896
+Ref: Array Sorting Functions-Footnote-1791785
+Node: Two-way I/O791981
+Ref: Two-way I/O-Footnote-1796926
+Ref: Two-way I/O-Footnote-2797112
+Node: TCP/IP Networking797194
+Node: Profiling800067
+Node: Advanced Features Summary808344
+Node: Internationalization810277
+Node: I18N and L10N811757
+Node: Explaining gettext812443
+Ref: Explaining gettext-Footnote-1817468
+Ref: Explaining gettext-Footnote-2817652
+Node: Programmer i18n817817
+Ref: Programmer i18n-Footnote-1822683
+Node: Translator i18n822732
+Node: String Extraction823526
+Ref: String Extraction-Footnote-1824657
+Node: Printf Ordering824743
+Ref: Printf Ordering-Footnote-1827529
+Node: I18N Portability827593
+Ref: I18N Portability-Footnote-1830048
+Node: I18N Example830111
+Ref: I18N Example-Footnote-1832914
+Node: Gawk I18N832986
+Node: I18N Summary833624
+Node: Debugger834963
+Node: Debugging835985
+Node: Debugging Concepts836426
+Node: Debugging Terms838279
+Node: Awk Debugging840851
+Node: Sample Debugging Session841745
+Node: Debugger Invocation842265
+Node: Finding The Bug843649
+Node: List of Debugger Commands850124
+Node: Breakpoint Control851457
+Node: Debugger Execution Control855153
+Node: Viewing And Changing Data858517
+Node: Execution Stack861895
+Node: Debugger Info863532
+Node: Miscellaneous Debugger Commands867549
+Node: Readline Support872578
+Node: Limitations873470
+Node: Debugging Summary875584
+Node: Arbitrary Precision Arithmetic876752
+Node: Computer Arithmetic878168
+Ref: table-numeric-ranges881766
+Ref: Computer Arithmetic-Footnote-1882625
+Node: Math Definitions882682
+Ref: table-ieee-formats885970
+Ref: Math Definitions-Footnote-1886574
+Node: MPFR features886679
+Node: FP Math Caution888350
+Ref: FP Math Caution-Footnote-1889400
+Node: Inexactness of computations889769
+Node: Inexact representation890728
+Node: Comparing FP Values892085
+Node: Errors accumulate893167
+Node: Getting Accuracy894600
+Node: Try To Round897262
+Node: Setting precision898161
+Ref: table-predefined-precision-strings898845
+Node: Setting the rounding mode900634
+Ref: table-gawk-rounding-modes900998
+Ref: Setting the rounding mode-Footnote-1904453
+Node: Arbitrary Precision Integers904632
+Ref: Arbitrary Precision Integers-Footnote-1909531
+Node: POSIX Floating Point Problems909680
+Ref: POSIX Floating Point Problems-Footnote-1913553
+Node: Floating point summary913591
+Node: Dynamic Extensions915785
+Node: Extension Intro917337
+Node: Plugin License918603
+Node: Extension Mechanism Outline919400
+Ref: figure-load-extension919828
+Ref: figure-register-new-function921308
+Ref: figure-call-new-function922312
+Node: Extension API Description924298
+Node: Extension API Functions Introduction925748
+Node: General Data Types930572
+Ref: General Data Types-Footnote-1936311
+Node: Memory Allocation Functions936610
+Ref: Memory Allocation Functions-Footnote-1939449
+Node: Constructor Functions939545
+Node: Registration Functions941279
+Node: Extension Functions941964
+Node: Exit Callback Functions944261
+Node: Extension Version String945509
+Node: Input Parsers946174
+Node: Output Wrappers956053
+Node: Two-way processors960568
+Node: Printing Messages962772
+Ref: Printing Messages-Footnote-1963848
+Node: Updating `ERRNO'964000
+Node: Requesting Values964740
+Ref: table-value-types-returned965468
+Node: Accessing Parameters966425
+Node: Symbol Table Access967656
+Node: Symbol table by name968170
+Node: Symbol table by cookie970151
+Ref: Symbol table by cookie-Footnote-1974295
+Node: Cached values974358
+Ref: Cached values-Footnote-1977857
+Node: Array Manipulation977948
+Ref: Array Manipulation-Footnote-1979046
+Node: Array Data Types979083
+Ref: Array Data Types-Footnote-1981738
+Node: Array Functions981830
+Node: Flattening Arrays985684
+Node: Creating Arrays992576
+Node: Extension API Variables997347
+Node: Extension Versioning997983
+Node: Extension API Informational Variables999884
+Node: Extension API Boilerplate1000949
+Node: Finding Extensions1004758
+Node: Extension Example1005318
+Node: Internal File Description1006090
+Node: Internal File Ops1010157
+Ref: Internal File Ops-Footnote-11021827
+Node: Using Internal File Ops1021967
+Ref: Using Internal File Ops-Footnote-11024350
+Node: Extension Samples1024623
+Node: Extension Sample File Functions1026149
+Node: Extension Sample Fnmatch1033787
+Node: Extension Sample Fork1035278
+Node: Extension Sample Inplace1036493
+Node: Extension Sample Ord1038168
+Node: Extension Sample Readdir1039004
+Ref: table-readdir-file-types1039880
+Node: Extension Sample Revout1040691
+Node: Extension Sample Rev2way1041281
+Node: Extension Sample Read write array1042021
+Node: Extension Sample Readfile1043961
+Node: Extension Sample Time1045056
+Node: Extension Sample API Tests1046405
+Node: gawkextlib1046896
+Node: Extension summary1049554
+Node: Extension Exercises1053243
+Node: Language History1053965
+Node: V7/SVR3.11055621
+Node: SVR41057802
+Node: POSIX1059247
+Node: BTL1060636
+Node: POSIX/GNU1061370
+Node: Feature History1066994
+Node: Common Extensions1080092
+Node: Ranges and Locales1081416
+Ref: Ranges and Locales-Footnote-11086034
+Ref: Ranges and Locales-Footnote-21086061
+Ref: Ranges and Locales-Footnote-31086295
+Node: Contributors1086516
+Node: History summary1092057
+Node: Installation1093427
+Node: Gawk Distribution1094373
+Node: Getting1094857
+Node: Extracting1095680
+Node: Distribution contents1097315
+Node: Unix Installation1103380
+Node: Quick Installation1104063
+Node: Shell Startup Files1106474
+Node: Additional Configuration Options1107553
+Node: Configuration Philosophy1109292
+Node: Non-Unix Installation1111661
+Node: PC Installation1112119
+Node: PC Binary Installation1113438
+Node: PC Compiling1115286
+Ref: PC Compiling-Footnote-11118307
+Node: PC Testing1118416
+Node: PC Using1119592
+Node: Cygwin1123707
+Node: MSYS1124530
+Node: VMS Installation1125030
+Node: VMS Compilation1125822
+Ref: VMS Compilation-Footnote-11127044
+Node: VMS Dynamic Extensions1127102
+Node: VMS Installation Details1128786
+Node: VMS Running1131038
+Node: VMS GNV1133874
+Node: VMS Old Gawk1134608
+Node: Bugs1135078
+Node: Other Versions1138961
+Node: Installation summary1145385
+Node: Notes1146441
+Node: Compatibility Mode1147306
+Node: Additions1148088
+Node: Accessing The Source1149013
+Node: Adding Code1150448
+Node: New Ports1156613
+Node: Derived Files1161095
+Ref: Derived Files-Footnote-11166570
+Ref: Derived Files-Footnote-21166604
+Ref: Derived Files-Footnote-31167200
+Node: Future Extensions1167314
+Node: Implementation Limitations1167920
+Node: Extension Design1169168
+Node: Old Extension Problems1170322
+Ref: Old Extension Problems-Footnote-11171839
+Node: Extension New Mechanism Goals1171896
+Ref: Extension New Mechanism Goals-Footnote-11175256
+Node: Extension Other Design Decisions1175445
+Node: Extension Future Growth1177553
+Node: Old Extension Mechanism1178389
+Node: Notes summary1180151
+Node: Basic Concepts1181337
+Node: Basic High Level1182018
+Ref: figure-general-flow1182290
+Ref: figure-process-flow1182889
+Ref: Basic High Level-Footnote-11186118
+Node: Basic Data Typing1186303
+Node: Glossary1189631
+Node: Copying1214789
+Node: GNU Free Documentation License1252345
+Node: Index1277481

End Tag Table
diff --git a/doc/gawk.texi b/doc/gawk.texi
index fc569ffc..a4567760 100644
--- a/doc/gawk.texi
+++ b/doc/gawk.texi
@@ -1,4 +1,10 @@
+% ****************************************************
+% * DO NOT MODIFY THIS FILE!!!! *
+% * It was generated from gawktexi.in by sidebar.awk *
+% * Edit gawktexi.in instead. *
+% ****************************************************
\input texinfo @c -*-texinfo-*-
+@c vim: filetype=texinfo
@c %**start of header (This is for running Texinfo on a region.)
@setfilename gawk.info
@settitle The GNU Awk User's Guide
@@ -13,6 +19,31 @@
* awk: (gawk)Invoking gawk. Text scanning and processing.
@end direntry
+@ifset FOR_PRINT
+@tex
+\gdef\xrefprintnodename#1{``#1''}
+@end tex
+@end ifset
+
+@ifclear FOR_PRINT
+@c With early 2014 texinfo.tex, restore PDF links and colors
+@tex
+\gdef\linkcolor{0.5 0.09 0.12} % Dark Red
+\gdef\urlcolor{0.5 0.09 0.12} % Also
+\global\urefurlonlylinktrue
+@end tex
+@end ifclear
+
+@ifnotdocbook
+@set BULLET @bullet{}
+@set MINUS @minus{}
+@end ifnotdocbook
+
+@ifdocbook
+@set BULLET
+@set MINUS
+@end ifdocbook
+
@set xref-automatic-section-title
@c The following information should be updated here only!
@@ -20,15 +51,18 @@
@c applies to and all the info about who's publishing this edition
@c These apply across the board.
-@set UPDATE-MONTH June, 2011
-@set VERSION 4.0
-@set PATCHLEVEL 0
-
-@set FSF
+@set UPDATE-MONTH September, 2014
+@set VERSION 4.1
+@set PATCHLEVEL 2
+@ifset FOR_PRINT
+@set TITLE Effective awk Programming
+@end ifset
+@ifclear FOR_PRINT
@set TITLE GAWK: Effective AWK Programming
+@end ifclear
@set SUBTITLE A User's Guide for GNU Awk
-@set EDITION 4
+@set EDITION 4.1
@iftex
@set DOCUMENT book
@@ -38,6 +72,7 @@
@set SUBSECTION subsection
@set DARKCORNER @inmargin{@image{lflashlight,1cm}, @image{rflashlight,1cm}}
@set COMMONEXT (c.e.)
+@set PAGE page
@end iftex
@ifinfo
@set DOCUMENT Info file
@@ -47,6 +82,7 @@
@set SUBSECTION node
@set DARKCORNER (d.c.)
@set COMMONEXT (c.e.)
+@set PAGE screen
@end ifinfo
@ifhtml
@set DOCUMENT Web page
@@ -56,6 +92,7 @@
@set SUBSECTION subsection
@set DARKCORNER (d.c.)
@set COMMONEXT (c.e.)
+@set PAGE screen
@end ifhtml
@ifdocbook
@set DOCUMENT book
@@ -65,7 +102,18 @@
@set SUBSECTION subsection
@set DARKCORNER (d.c.)
@set COMMONEXT (c.e.)
+@set PAGE page
@end ifdocbook
+@ifxml
+@set DOCUMENT book
+@set CHAPTER chapter
+@set APPENDIX appendix
+@set SECTION section
+@set SUBSECTION subsection
+@set DARKCORNER (d.c.)
+@set COMMONEXT (c.e.)
+@set PAGE page
+@end ifxml
@ifplaintext
@set DOCUMENT book
@set CHAPTER chapter
@@ -74,22 +122,94 @@
@set SUBSECTION subsection
@set DARKCORNER (d.c.)
@set COMMONEXT (c.e.)
+@set PAGE page
@end ifplaintext
+@ifdocbook
+@c empty on purpose
+@set PART1
+@set PART2
+@set PART3
+@set PART4
+@end ifdocbook
+
+@ifnotdocbook
+@set PART1 Part I:@*
+@set PART2 Part II:@*
+@set PART3 Part III:@*
+@set PART4 Part IV:@*
+@end ifnotdocbook
+
@c some special symbols
@iftex
@set LEQ @math{@leq}
+@set PI @math{@pi}
@end iftex
+@ifdocbook
+@set LEQ @inlineraw{docbook, &le;}
+@set PI @inlineraw{docbook, &pgr;}
+@end ifdocbook
@ifnottex
+@ifnotdocbook
@set LEQ <=
+@set PI @i{pi}
+@end ifnotdocbook
@end ifnottex
@ifnottex
+@ifnotdocbook
@macro ii{text}
@i{\text\}
@end macro
+@end ifnotdocbook
@end ifnottex
+@ifdocbook
+@macro ii{text}
+@inlineraw{docbook,<lineannotation>\text\</lineannotation>}
+@end macro
+@end ifdocbook
+
+@c hack for docbook, where comma shouldn't always follow an @ref{}
+@ifdocbook
+@macro DBREF{text}
+@ref{\text\}
+@end macro
+@macro DBXREF{text}
+@xref{\text\}
+@end macro
+@macro DBPXREF{text}
+@pxref{\text\}
+@end macro
+@end ifdocbook
+
+@ifnotdocbook
+@macro DBREF{text}
+@ref{\text\},
+@end macro
+@macro DBXREF{text}
+@xref{\text\},
+@end macro
+@macro DBPXREF{text}
+@pxref{\text\},
+@end macro
+@end ifnotdocbook
+
+@ifclear FOR_PRINT
+@set FN file name
+@set FFN File Name
+@set DF data file
+@set DDF Data File
+@set PVERSION version
+@end ifclear
+@ifset FOR_PRINT
+@set FN filename
+@set FFN Filename
+@set DF datafile
+@set DDF Datafile
+@set PVERSION version
+@end ifset
+
@c For HTML, spell out email addresses, to avoid problems with
@c address harvesters for spammers.
@ifhtml
@@ -103,19 +223,36 @@
@end macro
@end ifnothtml
-@set FN file name
-@set FFN File Name
-@set DF data file
-@set DDF Data File
-@set PVERSION version
-@set CTL Ctrl
+@c Indexing macros
+@ifinfo
+
+@macro cindexawkfunc{name}
+@cindex @code{\name\}
+@end macro
+
+@macro cindexgawkfunc{name}
+@cindex @code{\name\}
+@end macro
+
+@end ifinfo
+
+@ifnotinfo
+
+@macro cindexawkfunc{name}
+@cindex @code{\name\()} function
+@end macro
+
+@macro cindexgawkfunc{name}
+@cindex @code{\name\()} function (@command{gawk})
+@end macro
+@end ifnotinfo
@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.
+1. Use at least texinfo.tex 2014-01-30.15
+2. When using @docbook, if the last line is part of a paragraph, end
+it with a space and @c so that the lines won't run together. This is a
+quirk of the language / makeinfo, and isn't going to change.
@end ignore
@c merge the function and variable indexes into the concept index
@@ -131,6 +268,10 @@ Some comments on the layout for TeX.
@syncodeindex fn cp
@syncodeindex vr cp
@end ifxml
+@ifdocbook
+@synindex fn cp
+@synindex vr cp
+@end ifdocbook
@c If "finalout" is commented out, the printed output will show
@c black boxes that mark lines that are too long. Thus, it is
@@ -142,9 +283,30 @@ Some comments on the layout for TeX.
@end iftex
@copying
-Copyright @copyright{} 1989, 1991, 1992, 1993, 1996, 1997, 1998, 1999,
-2000, 2001, 2002, 2003, 2004, 2005, 2007, 2009, 2010, 2011
+@docbook
+<para>
+&ldquo;To boldly go where no man has gone before&rdquo; is a
+Registered Trademark of Paramount Pictures Corporation.</para>
+
+<para>Published by:</para>
+
+<literallayout class="normal">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</email>
+URL: <ulink url="http://www.gnu.org">http://www.gnu.org/</ulink></literallayout>
+
+<literallayout class="normal">Copyright &copy; 1989, 1991, 1992, 1993, 1996&ndash;2005, 2007, 2009&ndash;2014
Free Software Foundation, Inc.
+All Rights Reserved.</literallayout>
+@end docbook
+
+@ifnotdocbook
+Copyright @copyright{} 1989, 1991, 1992, 1993, 1996--2005, 2007, 2009--2015 @*
+Free Software Foundation, Inc.
+@end ifnotdocbook
@sp 2
This is Edition @value{EDITION} of @cite{@value{TITLE}: @value{SUBTITLE}},
@@ -154,19 +316,24 @@ 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.3 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
+Invariant Sections being ``GNU General Public License'', with the
+Front-Cover Texts being ``A GNU Manual'', and with the Back-Cover Texts
+as in (a) below.
+@ifclear FOR_PRINT
+A copy of the license is included in the section entitled
``GNU Free Documentation License''.
+@end ifclear
+@ifset FOR_PRINT
+A copy of the license
+may be found on the Internet at
+@uref{http://www.gnu.org/software/gawk/manual/html_node/GNU-Free-Documentation-License.html,
+the GNU Project's website}.
+@end ifset
@enumerate a
@item
-``A GNU Manual''
-
-@item
-``You have the freedom to
-copy and modify this GNU manual. Buying copies from the FSF
-supports it in developing GNU and promoting software freedom.''
+The FSF's Back-Cover Text is: ``You have the freedom to
+copy and modify this GNU manual.''
@end enumerate
@end copying
@@ -184,6 +351,7 @@ supports it in developing GNU and promoting software freedom.''
@c during editing and review.
@setchapternewpage odd
+@shorttitlepage GNU Awk
@titlepage
@title @value{TITLE}
@subtitle @value{SUBTITLE}
@@ -191,6 +359,7 @@ supports it in developing GNU and promoting software freedom.''
@subtitle @value{UPDATE-MONTH}
@author Arnold D. Robbins
+@ifnotdocbook
@c Include the Distribution inside the titlepage environment so
@c that headings are turned off. Headings on and off do not work.
@@ -215,6 +384,7 @@ URL: @uref{http://www.gnu.org/} @*
ISBN 1-882114-28-0 @*
@sp 2
@insertcopying
+@end ifnotdocbook
@end titlepage
@c Thanks to Bob Chassell for directions on doing dedications.
@@ -223,15 +393,13 @@ ISBN 1-882114-28-0 @*
@page
@w{ }
@sp 9
-@center @i{To Miriam, for making me complete.}
+@center @i{To my parents, for their love, and for the wonderful example they set for me.}
@sp 1
-@center @i{To Chana, for the joy you bring us.}
+@center @i{To my wife, Miriam, for making me complete.
+Thank you for building your life together with me.}
@sp 1
-@center @i{To Rivka, for the exponential increase.}
+@center @i{To our children, Chana, Rivka, Nachum, and Malka, for enrichening our lives in innumerable ways.}
@sp 1
-@center @i{To Nachum, for the added dimension.}
-@sp 1
-@center @i{To Malka, for the new beginning.}
@w{ }
@page
@w{ }
@@ -239,6 +407,17 @@ ISBN 1-882114-28-0 @*
@headings on
@end iftex
+@docbook
+<dedication>
+<para>To my parents, for their love, and for the wonderful
+example they set for me.</para>
+<para>To my wife Miriam, for making me complete.
+Thank you for building your life together with me.</para>
+<para>To our children Chana, Rivka, Nachum and Malka,
+for enrichening our lives in innumerable ways.</para>
+</dedication>
+@end docbook
+
@iftex
@headings off
@evenheading @thispage@ @ @ @strong{@value{TITLE}} @| @|
@@ -247,6 +426,7 @@ ISBN 1-882114-28-0 @*
@ifnottex
@ifnotxml
+@ifnotdocbook
@node Top
@top General Introduction
@c Preface node should come right after the Top
@@ -258,12 +438,14 @@ particular records in a file and perform operations upon them.
@insertcopying
+@end ifnotdocbook
@end ifnotxml
@end ifnottex
@menu
-* Foreword:: Some nice words about this
+* Foreword3:: Some nice words about this
@value{DOCUMENT}.
+* Foreword4:: More nice words.
* Preface:: What this @value{DOCUMENT} is about; brief
history and acknowledgments.
* Getting Started:: A basic introduction to using
@@ -283,20 +465,24 @@ particular records in a file and perform operations upon them.
* 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}.
* Library Functions:: A Library of @command{awk} Functions.
* Sample Programs:: Many @command{awk} programs with complete
explanations.
-* Debugger:: The @code{dgawk} debugger.
+* Advanced Features:: Stuff for advanced users, specific to
+ @command{gawk}.
+* Internationalization:: Getting @command{gawk} to speak your
+ language.
+* Debugger:: The @code{gawk} debugger.
+* Arbitrary Precision Arithmetic:: Arbitrary precision arithmetic with
+ @command{gawk}.
+* Dynamic Extensions:: Adding new built-in functions to
+ @command{gawk}.
* 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.
+* Notes:: Notes about adding things to @command{gawk}
+ and possible future work.
* Basic Concepts:: A very quick introduction to programming
concepts.
* Glossary:: An explanation of some unfamiliar terms.
@@ -306,460 +492,605 @@ particular records in a file and perform operations upon them.
* 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.
-* DOS Quoting:: Quoting in Windows Batch Files.
-* 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.
-* Command Line:: How to run @command{awk}.
-* Options:: Command-line options and their
- meanings.
-* Other Arguments:: Input file names and variable
- assignments.
-* Naming Standard Input:: How to specify standard input with
- other files.
-* Environment Variables:: The environment variables
- @command{gawk} uses.
-* AWKPATH Variable:: Searching directories for @command{awk}
- programs.
-* Other Environment Variables:: The environment variables.
-* Exit Status:: @command{gawk}'s exit status.
-* Include Files:: Including other files into your
- program.
-* Obsolete:: Obsolete Options and/or features.
-* Undocumented:: Undocumented Options and Features.
-* Regexp Usage:: How to Use Regular Expressions.
-* Escape Sequences:: How to write nonprinting characters.
-* Regexp Operators:: Regular Expression Operators.
-* Bracket Expressions:: 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.
-* 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.
-* Default Field Splitting:: How fields are normally separated.
-* 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.
-* Splitting By Content:: Defining Fields By Content
-* 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.
-* Command line directories:: What happens if you put a directory on
- the command line.
-* 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 Network:: Special files for network
- communications.
-* Special Caveats:: Things to watch out for.
-* Close Files And Pipes:: Closing Input and Output Files and
- Pipes.
-* Values:: Constants, Variables, and Regular
- Expressions.
-* 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.
-* All Operators:: @command{gawk}'s operators.
-* 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 and Conditions:: Testing for true and false.
-* 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.
-* Variable Typing:: String type versus numeric type.
-* Comparison Operators:: The comparison operators.
-* POSIX String Comparison:: String comparison with POSIX rules.
-* 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.
-* Locales:: How the locale affects things.
-* 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.
-* BEGINFILE/ENDFILE:: Two special patterns for advanced
- control.
-* 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 Basics:: The basics of arrays.
-* 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.
-* Arrays of Arrays:: True multidimensional arrays.
-* 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.
-* Type Functions:: Functions for type information.
-* 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.
-* Calling A Function:: Don't use spaces.
-* Variable Scope:: Controlling variable scope.
-* Pass By Value/Reference:: Passing parameters.
-* Return Statement:: Specifying the value a function
- returns.
-* Dynamic Typing:: How variable types can change at
- runtime.
-* Indirect Calls:: Choosing the function to call 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.
-* Array Sorting:: Facilities for controlling array
- traversal and sorting arrays.
-* Controlling Array Traversal:: How to use PROCINFO["sorted_in"].
-* Controlling Scanning With A Function:: Using a function to control scanning.
-* Controlling Scanning:: Controlling the order in which arrays
- are scanned.
-* Array Sorting Functions:: How to use @code{asort()} and
- @code{asorti()}.
-* Two-way I/O:: Two-way communications with another
- process.
-* TCP/IP Networking:: Using @command{gawk} for network
- programming.
-* Profiling:: Profiling your @command{awk} programs.
-* Library Names:: How to best name private global
- variables in library functions.
-* General Functions:: Functions that are of general use.
-* 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.
-* 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.
-* Walking Arrays:: A function to walk arrays of arrays.
-* 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.
-* Anagram Program:: Finding anagrams from a dictionary.
-* Signature Program:: People do amazing things with too much
- time on their hands.
-* Debugging:: Introduction to @command{dgawk}.
-* Debugging Concepts:: Debugging In General.
-* Debugging Terms:: Additional Debugging Concepts.
-* Awk Debugging:: Awk Debugging.
-* Sample dgawk session:: Sample @command{dgawk} session.
-* dgawk invocation:: @command{dgawk} Invocation.
-* Finding The Bug:: Finding The Bug.
-* List of Debugger Commands:: Main @command{dgawk} Commands.
-* Breakpoint Control:: Control of breakpoints.
-* Dgawk Execution Control:: Control of execution.
-* Viewing And Changing Data:: Viewing and changing data.
-* Dgawk Stack:: Dealing with the stack.
-* Dgawk Info:: Obtaining information about the program
- and the debugger state.
-* Miscellaneous Dgawk Commands:: Miscellaneous Commands.
-* Readline Support:: Readline Support.
-* Dgawk Limitations:: Limitations and future plans.
-* 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 Brian Kernighan's
- version of @command{awk}.
-* POSIX/GNU:: The extensions in @command{gawk} not in
- POSIX @command{awk}.
-* Common Extensions:: Common Extensions Summary.
-* Ranges and Locales:: How locales used to affect regexp
- ranges.
-* 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.
-* 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 Testing:: Testing @command{gawk} on PC systems.
-* PC Using:: Running @command{gawk} on MS-DOS,
- Windows32 and OS/2.
-* Cygwin:: Building and running @command{gawk} for
- Cygwin.
-* MSYS:: Using @command{gawk} In The MSYS
- Environment.
-* 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 Old Gawk:: An old version comes with some VMS
- systems.
-* 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}.
-* Accessing The Source:: Accessing the Git repository.
-* 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.
-* Plugin License:: A note about licensing.
-* 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.
-* String Conversion Precision:: The String Value Can Lie.
-* Unexpected Results:: Floating Point Numbers Are Not Abstract
- Numbers.
-* POSIX Floating Point Problems:: Standards Versus Existing Practice.
+* 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 the
+ keyboard 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.
+* DOS Quoting:: Quoting in Windows Batch Files.
+* 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.
+* Intro Summary:: Summary of the introduction.
+* Command Line:: How to run @command{awk}.
+* Options:: Command-line options and their
+ meanings.
+* Other Arguments:: Input file names and variable
+ assignments.
+* Naming Standard Input:: How to specify standard input with
+ other files.
+* Environment Variables:: The environment variables
+ @command{gawk} uses.
+* AWKPATH Variable:: Searching directories for
+ @command{awk} programs.
+* AWKLIBPATH Variable:: Searching directories for
+ @command{awk} shared libraries.
+* Other Environment Variables:: The environment variables.
+* Exit Status:: @command{gawk}'s exit status.
+* Include Files:: Including other files into your
+ program.
+* Loading Shared Libraries:: Loading shared libraries into your
+ program.
+* Obsolete:: Obsolete Options and/or features.
+* Undocumented:: Undocumented Options and Features.
+* Invoking Summary:: Invocation summary.
+* Regexp Usage:: How to Use Regular Expressions.
+* Escape Sequences:: How to write nonprinting characters.
+* Regexp Operators:: Regular Expression Operators.
+* Bracket Expressions:: What can go between @samp{[...]}.
+* Leftmost Longest:: How much text matches.
+* Computed Regexps:: Using Dynamic Regexps.
+* GNU Regexp Operators:: Operators specific to GNU software.
+* Case-sensitivity:: How to do case-insensitive matching.
+* Regexp Summary:: Regular expressions summary.
+* Records:: Controlling how data is split into
+ records.
+* awk split records:: How standard @command{awk} splits
+ records.
+* gawk split records:: How @command{gawk} splits 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.
+* Default Field Splitting:: How fields are normally separated.
+* 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.
+* Full Line Fields:: Making the full line be a single
+ field.
+* Field Splitting Summary:: Some final points and a summary table.
+* Constant Size:: Reading constant width data.
+* Splitting By Content:: Defining Fields By Content
+* Multiple Line:: Reading multiline 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.
+* Read Timeout:: Reading input with a timeout.
+* Command-line directories:: What happens if you put a directory on
+ the command line.
+* Input Summary:: Input summary.
+* Input Exercises:: Exercises.
+* 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 FD:: Special files for I/O.
+* Special Files:: File name interpretation in
+ @command{gawk}. @command{gawk} allows
+ access to inherited file descriptors.
+* Other Inherited Files:: Accessing other open files with
+ @command{gawk}.
+* 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.
+* Output Summary:: Output summary.
+* Output Exercises:: Exercises.
+* Values:: Constants, Variables, and Regular
+ Expressions.
+* 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.
+* Strings And Numbers:: How @command{awk} Converts Between
+ Strings And Numbers.
+* Locale influences conversions:: How the locale may affect conversions.
+* All Operators:: @command{gawk}'s operators.
+* 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 and Conditions:: Testing for true and false.
+* 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.
+* Variable Typing:: String type versus numeric type.
+* Comparison Operators:: The comparison operators.
+* POSIX String Comparison:: String comparison with POSIX rules.
+* 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.
+* Locales:: How the locale affects things.
+* Expressions Summary:: Expressions summary.
+* 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.
+* BEGINFILE/ENDFILE:: Two special patterns for advanced
+ control.
+* 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 predefined 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}.
+* Pattern Action Summary:: Patterns and Actions summary.
+* Array Basics:: The basics of arrays.
+* 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.
+* Controlling Scanning:: Controlling the order in which arrays
+ are scanned.
+* Numeric Array Subscripts:: How to use numbers as subscripts in
+ @command{awk}.
+* Uninitialized Subscripts:: Using Uninitialized variables as
+ subscripts.
+* Delete:: The @code{delete} statement removes an
+ element from an array.
+* Multidimensional:: Emulating multidimensional arrays in
+ @command{awk}.
+* Multiscanning:: Scanning multidimensional arrays.
+* Arrays of Arrays:: True multidimensional arrays.
+* Arrays Summary:: Summary of arrays.
+* 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.
+* Type Functions:: Functions for type information.
+* 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.
+* Calling A Function:: Don't use spaces.
+* Variable Scope:: Controlling variable scope.
+* Pass By Value/Reference:: Passing parameters.
+* Return Statement:: Specifying the value a function
+ returns.
+* Dynamic Typing:: How variable types can change at
+ runtime.
+* Indirect Calls:: Choosing the function to call at
+ runtime.
+* Functions Summary:: Summary of functions.
+* Library Names:: How to best name private global
+ variables in library functions.
+* General Functions:: Functions that are of general use.
+* 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.
+* Getlocaltime Function:: A function to get formatted times.
+* Readfile Function:: A function to read an entire file at
+ once.
+* Shell Quoting:: A function to quote strings for the
+ shell.
+* 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.
+* Walking Arrays:: A function to walk arrays of arrays.
+* Library Functions Summary:: Summary of library functions.
+* Library Exercises:: Exercises.
+* 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.
+* Anagram Program:: Finding anagrams from a dictionary.
+* Signature Program:: People do amazing things with too much
+ time on their hands.
+* Programs Summary:: Summary of programs.
+* Programs Exercises:: Exercises.
+* Nondecimal Data:: Allowing nondecimal input data.
+* Array Sorting:: Facilities for controlling array
+ traversal and sorting arrays.
+* Controlling Array Traversal:: How to use PROCINFO["sorted_in"].
+* Array Sorting Functions:: How to use @code{asort()} and
+ @code{asorti()}.
+* Two-way I/O:: Two-way communications with another
+ process.
+* TCP/IP Networking:: Using @command{gawk} for network
+ programming.
+* Profiling:: Profiling your @command{awk} programs.
+* Advanced Features Summary:: Summary of advanced features.
+* I18N and L10N:: Internationalization and Localization.
+* Explaining gettext:: How GNU @command{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.
+* I18N Summary:: Summary of I18N stuff.
+* Debugging:: Introduction to @command{gawk}
+ debugger.
+* Debugging Concepts:: Debugging in General.
+* Debugging Terms:: Additional Debugging Concepts.
+* Awk Debugging:: Awk Debugging.
+* Sample Debugging Session:: Sample debugging session.
+* Debugger Invocation:: How to Start the Debugger.
+* Finding The Bug:: Finding the Bug.
+* List of Debugger Commands:: Main debugger commands.
+* Breakpoint Control:: Control of Breakpoints.
+* Debugger Execution Control:: Control of Execution.
+* Viewing And Changing Data:: Viewing and Changing Data.
+* Execution Stack:: Dealing with the Stack.
+* Debugger Info:: Obtaining Information about the
+ Program and the Debugger State.
+* Miscellaneous Debugger Commands:: Miscellaneous Commands.
+* Readline Support:: Readline support.
+* Limitations:: Limitations and future plans.
+* Debugging Summary:: Debugging summary.
+* Computer Arithmetic:: A quick intro to computer math.
+* Math Definitions:: Defining terms used.
+* MPFR features:: The MPFR features in @command{gawk}.
+* FP Math Caution:: Things to know.
+* Inexactness of computations:: Floating point math is not exact.
+* Inexact representation:: Numbers are not exactly represented.
+* Comparing FP Values:: How to compare floating point values.
+* Errors accumulate:: Errors get bigger as they go.
+* Getting Accuracy:: Getting more accuracy takes some work.
+* Try To Round:: Add digits and round.
+* Setting precision:: How to set the precision.
+* Setting the rounding mode:: How to set the rounding mode.
+* Arbitrary Precision Integers:: Arbitrary Precision Integer Arithmetic
+ with @command{gawk}.
+* POSIX Floating Point Problems:: Standards Versus Existing Practice.
+* Floating point summary:: Summary of floating point discussion.
+* Extension Intro:: What is an extension.
+* Plugin License:: A note about licensing.
+* Extension Mechanism Outline:: An outline of how it works.
+* Extension API Description:: A full description of the API.
+* Extension API Functions Introduction:: Introduction to the API functions.
+* General Data Types:: The data types.
+* Memory Allocation Functions:: Functions for allocating memory.
+* Constructor Functions:: Functions for creating values.
+* Registration Functions:: Functions to register things with
+ @command{gawk}.
+* Extension Functions:: Registering extension functions.
+* Exit Callback Functions:: Registering an exit callback.
+* Extension Version String:: Registering a version string.
+* Input Parsers:: Registering an input parser.
+* Output Wrappers:: Registering an output wrapper.
+* Two-way processors:: Registering a two-way processor.
+* Printing Messages:: Functions for printing messages.
+* Updating @code{ERRNO}:: Functions for updating @code{ERRNO}.
+* Requesting Values:: How to get a value.
+* Accessing Parameters:: Functions for accessing parameters.
+* Symbol Table Access:: Functions for accessing global
+ variables.
+* Symbol table by name:: Accessing variables by name.
+* Symbol table by cookie:: Accessing variables by ``cookie''.
+* Cached values:: Creating and using cached values.
+* Array Manipulation:: Functions for working with arrays.
+* Array Data Types:: Data types for working with arrays.
+* Array Functions:: Functions for working with arrays.
+* Flattening Arrays:: How to flatten arrays.
+* Creating Arrays:: How to create and populate arrays.
+* Extension API Variables:: Variables provided by the API.
+* Extension Versioning:: API Version information.
+* Extension API Informational Variables:: Variables providing information about
+ @command{gawk}'s invocation.
+* Extension API Boilerplate:: Boilerplate code for using the API.
+* Finding Extensions:: How @command{gawk} finds compiled
+ extensions.
+* Extension Example:: Example C code for an extension.
+* 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.
+* Extension Samples:: The sample extensions that ship with
+ @code{gawk}.
+* Extension Sample File Functions:: The file functions sample.
+* Extension Sample Fnmatch:: An interface to @code{fnmatch()}.
+* Extension Sample Fork:: An interface to @code{fork()} and
+ other process functions.
+* Extension Sample Inplace:: Enabling in-place file editing.
+* Extension Sample Ord:: Character to value to character
+ conversions.
+* Extension Sample Readdir:: An interface to @code{readdir()}.
+* Extension Sample Revout:: Reversing output sample output
+ wrapper.
+* Extension Sample Rev2way:: Reversing data sample two-way
+ processor.
+* Extension Sample Read write array:: Serializing an array to a file.
+* Extension Sample Readfile:: Reading an entire file into a string.
+* Extension Sample Time:: An interface to @code{gettimeofday()}
+ and @code{sleep()}.
+* Extension Sample API Tests:: Tests for the API.
+* gawkextlib:: The @code{gawkextlib} project.
+* Extension summary:: Extension summary.
+* Extension Exercises:: Exercises.
+* 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 Brian Kernighan's
+ version of @command{awk}.
+* POSIX/GNU:: The extensions in @command{gawk} not
+ in POSIX @command{awk}.
+* Feature History:: The history of the features in
+ @command{gawk}.
+* Common Extensions:: Common Extensions Summary.
+* Ranges and Locales:: How locales used to affect regexp
+ ranges.
+* Contributors:: The major contributors to
+ @command{gawk}.
+* History summary:: History summary.
+* 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.
+* Shell Startup Files:: Shell convenience functions.
+* Additional Configuration Options:: Other compile-time options.
+* Configuration Philosophy:: How it's all supposed to work.
+* Non-Unix Installation:: Installation on Other Operating
+ Systems.
+* 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 Testing:: Testing @command{gawk} on PC systems.
+* PC Using:: Running @command{gawk} on MS-DOS,
+ Windows32 and OS/2.
+* Cygwin:: Building and running @command{gawk}
+ for Cygwin.
+* MSYS:: Using @command{gawk} In The MSYS
+ Environment.
+* VMS Installation:: Installing @command{gawk} on VMS.
+* VMS Compilation:: How to compile @command{gawk} under
+ VMS.
+* VMS Dynamic Extensions:: Compiling @command{gawk} dynamic
+ extensions on VMS.
+* VMS Installation Details:: How to install @command{gawk} under
+ VMS.
+* VMS Running:: How to run @command{gawk} under VMS.
+* VMS GNV:: The VMS GNV Project.
+* VMS Old Gawk:: An old version comes with some VMS
+ systems.
+* Bugs:: Reporting Problems and Bugs.
+* Other Versions:: Other freely available @command{awk}
+ implementations.
+* Installation summary:: Summary of installation.
+* Compatibility Mode:: How to disable certain @command{gawk}
+ extensions.
+* Additions:: Making Additions To @command{gawk}.
+* Accessing The Source:: Accessing the Git repository.
+* Adding Code:: Adding code to the main body of
+ @command{gawk}.
+* New Ports:: Porting @command{gawk} to a new
+ operating system.
+* Derived Files:: Why derived files are kept in the Git
+ repository.
+* Future Extensions:: New features that may be implemented
+ one day.
+* Implementation Limitations:: Some limitations of the
+ implementation.
+* Extension Design:: Design notes about the extension API.
+* Old Extension Problems:: Problems with the old mechanism.
+* Extension New Mechanism Goals:: Goals for the new mechanism.
+* Extension Other Design Decisions:: Some other design decisions.
+* Extension Future Growth:: Some room for future growth.
+* Old Extension Mechanism:: Some compatibility for old extensions.
+* Notes summary:: Summary of implementation notes.
+* Basic High Level:: The high level view.
+* Basic Data Typing:: A very quick intro to data types.
@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.
+To my parents, for their love, and for the wonderful
+example they set for me.
@sp 1
-@center To Rivka, for the exponential increase.
+To my wife Miriam, for making me complete.
+Thank you for building your life together with me.
@sp 1
-@center To Nachum, for the added dimension.
-@sp 1
-@center To Malka, for the new beginning.
+To our children Chana, Rivka, Nachum and Malka,
+for enrichening our lives in innumerable ways.
@end ifinfo
@summarycontents
@contents
-@node Foreword
-@unnumbered Foreword
+@node Foreword3
+@unnumbered Foreword to the Third Edition
+
+@c This bit is post-processed by a script which turns the chapter
+@c tag into a preface tag, and moves this stuff to before the title.
+@c Bleah.
+@docbook
+ <prefaceinfo>
+ <author>
+ <firstname>Michael</firstname>
+ <surname>Brennan</surname>
+ <!-- can't put mawk into command tags. sigh. -->
+ <affiliation><jobtitle>Author of mawk</jobtitle></affiliation>
+ </author>
+ <date>March 2001</date>
+ </prefaceinfo>
+@end docbook
Arnold Robbins and I are good friends. We were introduced
@c 11 years ago
@@ -769,21 +1100,23 @@ 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
+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
+books on Unix, I found the gray AWK book, a.k.a.@:
+Alfred V.@: Aho, Brian W.@: Kernighan, and
+Peter J.@: Weinberger's @cite{The AWK Programming Language} (Addison-Wesley,
+1988). @command{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
+data manipulations to a 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}.''
+language described in the gray book. I discovered that my computer
+had ``old @command{awk}'' and the 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.
@@ -801,7 +1134,7 @@ 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},
+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.
@@ -810,7 +1143,7 @@ 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.
+after publication of @cite{The AWK Programming Language}.
Frankly, if our roles had
been reversed, I would not have been so open and we probably would
@@ -829,7 +1162,7 @@ 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,
+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.
@@ -837,7 +1170,7 @@ 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
+Consequently, there is often a payoff to prototyping 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.
@@ -845,21 +1178,37 @@ 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
+@ifnotdocbook
+@math{n}
+@end ifnotdocbook
+@ifdocbook
+@i{n}
+@end ifdocbook
+lines of input, exhibited
@tex
$\sim\! Cn^2$
@end tex
@ifnottex
+@ifnotdocbook
~ C n^2
+@end ifnotdocbook
@end ifnottex
+@docbook
+<emphasis>&sim; Cn<superscript>2</superscript></emphasis> @c
+@end docbook
performance, while
theory predicted
@tex
$\sim\! Cn\log n$
@end tex
@ifnottex
+@ifnotdocbook
~ C n log n
+@end ifnotdocbook
@end ifnottex
+@docbook
+<emphasis>&sim; Cn log n</emphasis> @c
+@end docbook
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
@@ -869,11 +1218,69 @@ 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.
+@ifnotdocbook
+@cindex Brennan, Michael
+@display
+Michael Brennan
+Author of @command{mawk}
+March 2001
+@end display
+@end ifnotdocbook
+
+@node Foreword4
+@unnumbered Foreword to the Fourth Edition
+
+@c This bit is post-processed by a script which turns the chapter
+@c tag into a preface tag, and moves this stuff to before the title.
+@c Bleah.
+@docbook
+ <prefaceinfo>
+ <author>
+ <firstname>Michael</firstname>
+ <surname>Brennan</surname>
+ <!-- can't put mawk into command tags. sigh. -->
+ <affiliation><jobtitle>Author of mawk</jobtitle></affiliation>
+ </author>
+ <date>October 2014</date>
+ </prefaceinfo>
+@end docbook
+
+Some things don't change. Thirteen years ago I wrote:
+``If you use AWK or want to learn how, then read this book.''
+True then, and still true today.
+
+Learning to use a programming language is about more than mastering the
+syntax. One needs to acquire an understanding of how to use the
+features of the language to solve practical programming problems.
+A focus of this book is many examples that show how to use AWK.
+
+Some things do change. Our computers are much faster and have more memory.
+Consequently, speed and storage inefficiencies of a high-level language
+matter less. Prototyping in AWK and then rewriting in C for performance
+reasons happens less, because more often the prototype is fast enough.
+
+Of course, there are computing operations that are best done in C or C++.
+With @command{gawk} 4.1 and later, you do not have to choose between writing
+your program in AWK or in C/C++. You can write most of your
+program in AWK and the aspects that require C/C++ capabilities can be written
+in C/C++, and then the pieces glued together when the @command{gawk} module loads
+the C/C++ module as a dynamic plug-in.
+@c Chapter 16
+@ref{Dynamic Extensions},
+has all the
+details, and, as expected, many examples to help you learn the ins and outs.
+
+I enjoy programming in AWK and had fun (re)reading this book.
+I think you will too.
+
+@ifnotdocbook
+@cindex Brennan, Michael
@display
Michael Brennan
Author of @command{mawk}
-March, 2001
+October 2014
@end display
+@end ifnotdocbook
@node Preface
@unnumbered Preface
@@ -882,29 +1289,39 @@ March, 2001
@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 Java 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.
+@c This bit is post-processed by a script which turns the chapter
+@c tag into a preface tag, and moves this stuff to before the title.
+@c Bleah.
+@docbook
+ <prefaceinfo>
+ <author>
+ <firstname>Arnold</firstname>
+ <surname>Robbins</surname>
+ <affiliation><jobtitle>Nof Ayalon</jobtitle></affiliation>
+ <affiliation><jobtitle>Israel</jobtitle></affiliation>
+ </author>
+ <date>December 2014</date>
+ </prefaceinfo>
+@end docbook
+
+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. Such jobs are often easy 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}; if you
-invoke it with the proper options or environment variables
-(@pxref{Options}), it is fully
-compatible with
-the POSIX@footnote{The 2008 POSIX standard can be found online at
-@url{http://www.opengroup.org/onlinepubs/9699919799/}.}
+invoke it with the proper options or environment variables,
+it is fully compatible with
+the POSIX@footnote{The 2008 POSIX standard is accessible online at
+@w{@url{http://www.opengroup.org/onlinepubs/9699919799/}.}}
specification of the @command{awk} language
and with the Unix version of @command{awk} maintained
by Brian Kernighan.
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
+So most of the time, we don't distinguish between @command{gawk} and other
@command{awk} implementations.
@cindex @command{awk}, POSIX and, See Also POSIX @command{awk}
@@ -913,9 +1330,9 @@ Thus, we usually don't distinguish between @command{gawk} and other
@cindex @command{gawk}, @command{awk} and
@cindex @command{awk}, @command{gawk} and
@cindex @command{awk}, uses for
-Using @command{awk} allows you to:
+Using @command{awk} you can:
-@itemize @bullet
+@itemize @value{BULLET}
@item
Manage small, personal databases
@@ -926,7 +1343,7 @@ Generate reports
Validate data
@item
-Produce indexes and perform other document preparation tasks
+Produce indexes and perform other document-preparation tasks
@item
Experiment with algorithms that you can adapt later to other computer
@@ -940,7 +1357,7 @@ In addition,
@command{gawk}
provides facilities that make it easy to:
-@itemize @bullet
+@itemize @value{BULLET}
@item
Extract bits and pieces of data for processing
@@ -949,11 +1366,17 @@ Sort data
@item
Perform simple network communications
+
+@item
+Profile and debug @command{awk} programs
+
+@item
+Extend the language with functions written in C or C++
@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
+system commands, such as @command{cat} and @command{ls},@footnote{These utilities
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
@@ -964,15 +1387,20 @@ 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 Intel@registeredsymbol{}-architecture PC-based computers
-up through large-scale systems,
-such as Crays. @command{gawk} has also been ported to Mac OS X,
-Microsoft Windows (all versions) and OS/2 PCs,
-and VMS.
-(Some other, obsolete systems to which @command{gawk} was once ported
-are no longer supported and the code for those systems
-has been removed.)
+``GNU @command{awk}''). @command{gawk} runs on a broad range of Unix systems,
+ranging from Intel-architecture PC-based computers
+up through large-scale systems.
+@command{gawk} has also been ported to Mac OS X,
+Microsoft Windows
+@ifset FOR_PRINT
+(all versions),
+@end ifset
+@ifclear FOR_PRINT
+(all versions) and OS/2 PCs,
+@end ifclear
+and OpenVMS.@footnote{Some other, obsolete systems to which @command{gawk}
+was once ported are no longer supported and the code for those systems
+has been removed.}
@menu
* History:: The history of @command{gawk} and
@@ -991,27 +1419,54 @@ has been removed.)
@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
+@cindex sidebar, Recipe for a Programming Language
+@ifdocbook
+@docbook
+<sidebar><title>Recipe for a Programming Language</title>
+@end docbook
+
@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
+
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{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
+
+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 cartouche
+@end ifnotdocbook
@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
+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
@@ -1022,22 +1477,22 @@ The version in System V Release 4 (1989) 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.
+Both the @command{gawk} designers and the original @command{awk} designers at Bell Laboratories
+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.
+Paul Rubin wrote @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 1994, I became the primary maintainer.
Current development focuses on bug fixes,
-performance improvements, standards compliance, and occasionally, new features.
+performance improvements, standards compliance, and, occasionally, new features.
-In May of 1997, J@"urgen Kahrs felt the need for network access
+In May 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
@@ -1048,41 +1503,39 @@ with @command{gawk} @value{PVERSION} 3.1.
John Haque rewrote the @command{gawk} internals, in the process providing
an @command{awk}-level debugger. This version became available as
-@command{gawk} @value{PVERSION} 4.0, in 2011.
+@command{gawk} @value{PVERSION} 4.0 in 2011.
-@xref{Contributors},
-for a complete list of those who made important contributions to @command{gawk}.
+@DBXREF{Contributors}
+for a full list of those who have made important contributions to @command{gawk}.
@node Names
-@section A Rose by Any Other Name
+@unnumberedsec 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}).
+is often referred to as ``new @command{awk}.''
+By analogy, the original version of @command{awk} is
+referred to as ``old @command{awk}.''
-@cindex @command{awk}, versions of
-Because of this, there are systems with 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
-we 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}!)
+Today, on most systems, when you run the @command{awk} utility
+you get some version of new @command{awk}.@footnote{Only
+Solaris systems still use an old @command{awk} for the
+default @command{awk} utility. A more modern @command{awk} lives in
+@file{/usr/xpg6/bin} on these systems.} If your system's standard
+@command{awk} is the old one, you will see something like this
+if you try the test program:
+
+@example
+$ @kbd{awk 1 /dev/null}
+@error{} awk: syntax error near line 1
+@error{} awk: bailing out near line 1
+@end example
+
+@noindent
+In this case, you should find a version of new @command{awk},
+or just install @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},
@@ -1090,7 +1543,7 @@ 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
+@unnumberedsec Using This Book
@cindex @command{awk}, terms describing
The term @command{awk} refers to a particular program as well as to the language you
@@ -1100,7 +1553,7 @@ and the program ``the @command{awk} utility.''
This @value{DOCUMENT} explains
both how to write programs in 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 term ``@command{awk} program'' refers to a program written by you in
the @command{awk} programming language.
@cindex @command{gawk}, @command{awk} and
@@ -1110,52 +1563,79 @@ 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
+and other @command{awk}
+@ifclear FOR_PRINT
+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.
+@end ifclear
+@ifset FOR_PRINT
+implementations.
+@end ifset
+Finally, it notes any @command{gawk} features that are not in
+the POSIX standard for @command{awk}.
@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 and HTML versions of the document.
+expert user and for the Info and
+@uref{http://www.gnu.org/software/gawk/manual/, HTML}
+versions of the @value{DOCUMENT}.
@end ifnotinfo
-There are
-subsections labeled
-as @strong{Advanced Notes}
+There are sidebars
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.''
+@ifclear FOR_PRINT
+All appear in the index, under the heading ``sidebar.''
+@end ifclear
Most of the time, the examples use complete @command{awk} programs.
Some of the more advanced sections show only the part of the @command{awk}
-program that illustrates the concept currently being described.
+program that illustrates the concept being described.
-While this @value{DOCUMENT} is aimed principally at people who have not been
+Although 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{Library Functions}, and
+@ifnotdocbook
+in
+@end ifnotdocbook
@ref{Sample Programs},
should be of interest.
+This @value{DOCUMENT} is split into several parts, as follows:
+
+@c FULLXREF ON
+
+@itemize @value{BULLET}
+@item
+Part I describes the @command{awk} language and the @command{gawk} program in detail.
+It starts with the basics, and continues through all of the features of @command{awk}.
+It contains the following chapters:
+
+@c nested
+@itemize @value{MINUS}
+@item
@ref{Getting Started},
provides the essentials you need to know to begin using @command{awk}.
+@item
@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.
+@item
@ref{Regexp},
introduces regular expressions in general, and in particular the flavors
supported by POSIX @command{awk} and @command{gawk}.
+@item
@ref{Reading Files},
describes how @command{awk} reads your data.
It introduces the concepts of records and fields, as well
@@ -1163,55 +1643,106 @@ as the @code{getline} command.
I/O redirection is first described here.
Network I/O is also briefly introduced here.
+@item
@ref{Printing},
describes how @command{awk} programs can produce output with
@code{print} and @code{printf}.
+@item
@ref{Expressions},
describes expressions, which are the basic building blocks
for getting most things done in a program.
+@item
@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
+doing something when a record is matched, and the predefined variables
@command{awk} and @command{gawk} use.
+@item
@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}. It also describes how @command{gawk}
-provides arrays of arrays.
+covers @command{awk}'s one-and-only data structure: the associative array.
+Deleting array elements and whole arrays is described, as well as
+sorting arrays in @command{gawk}. The @value{CHAPTER} also describes how
+@command{gawk} provides arrays of arrays.
+@item
@ref{Functions},
-describes the built-in functions @command{awk} and
-@command{gawk} provide, as well as how to define
-your own functions.
+describes the built-in functions @command{awk} and @command{gawk} provide,
+as well as how to define your own functions. It also discusses how
+@command{gawk} lets you call functions indirectly.
+@end itemize
-@ref{Internationalization},
-describes special features in @command{gawk} for translating program
-messages into different languages at runtime.
+@item
+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.
+This part contains the following chapters:
+
+@c nested
+@itemize @value{MINUS}
+@item
+@ref{Library Functions}, provides a number of functions meant to
+be used from main @command{awk} programs.
+
+@item
+@ref{Sample Programs},
+provides many sample @command{awk} programs.
+@end itemize
+
+Reading these two chapters allows you to see @command{awk}
+solving real problems.
+@item
+Part III focuses on features specific to @command{gawk}.
+It contains the following chapters:
+
+@c nested
+@itemize @value{MINUS}
+@item
@ref{Advanced Features},
-describes a number of @command{gawk}-specific advanced features.
+describes a number of advanced features.
Of particular note
-are the abilities to have two-way communications with another process,
+are the abilities to control the order of array traversal,
+have two-way communications with another process,
perform TCP/IP networking, and
profile your @command{awk} programs.
-@ref{Library Functions}, and
-@ref{Sample Programs},
-provide many sample @command{awk} programs.
-Reading them allows you to see @command{awk}
-solving real problems.
+@item
+@ref{Internationalization},
+describes special features for translating program
+messages into different languages at runtime.
+
+@item
+@ref{Debugger}, describes the @command{gawk} debugger.
+
+@item
+@ref{Arbitrary Precision Arithmetic},
+describes advanced arithmetic facilities.
-@ref{Debugger}, describes the @command{awk} debugger,
-@command{dgawk}.
+@item
+@ref{Dynamic Extensions}, describes how to add new variables and
+functions to @command{gawk} by writing extensions in C or C++.
+@end itemize
+
+@item
+@ifclear FOR_PRINT
+Part IV provides the appendices, the Glossary, and two licenses that cover
+the @command{gawk} source code and this @value{DOCUMENT}, respectively.
+It contains the following appendices:
+@end ifclear
+@ifset FOR_PRINT
+Part IV provides the following appendices,
+including the GNU General Public License:
+@end ifset
+@itemize @value{MINUS}
+@item
@ref{Language History},
describes how the @command{awk} language has evolved since
-its first release to present. It also describes how @command{gawk}
+its first release to the present. It also describes how @command{gawk}
has acquired features over time.
+@item
@ref{Installation},
describes how to get @command{gawk}, how to compile it
on POSIX-compatible systems,
@@ -1219,35 +1750,85 @@ and how to compile and use it on different
non-POSIX systems. It also describes how to report bugs
in @command{gawk} and where to get other freely
available @command{awk} implementations.
+@end itemize
+
+@ifset FOR_PRINT
+@itemize @value{MINUS}
+@item
+@ref{Copying},
+presents the license that covers the @command{gawk} source code.
+@end itemize
+
+The version of this @value{DOCUMENT} distributed with @command{gawk}
+contains additional appendices and other end material.
+To save space, we have omitted them from the
+printed edition. You may find them online, as follows:
+
+@itemize @value{BULLET}
+@item
+@uref{http://www.gnu.org/software/gawk/manual/html_node/Notes.html,
+The appendix on implementation notes}
+describes how to disable @command{gawk}'s extensions, how to contribute
+new code to @command{gawk}, where to find information on some possible
+future directions for @command{gawk} development, and the design decisions
+behind the extension API.
+@item
+@uref{http://www.gnu.org/software/gawk/manual/html_node/Basic-Concepts.html,
+The appendix on basic concepts}
+provides some very cursory background material for those who
+are completely unfamiliar with computer programming.
+
+@item
+@uref{http://www.gnu.org/software/gawk/manual/html_node/Glossary.html,
+The Glossary}
+defines most, if not all, of the significant terms used
+throughout the @value{DOCUMENT}. If you find terms that you aren't familiar with,
+try looking them up here.
+
+@item
+@uref{http://www.gnu.org/software/gawk/manual/html_node/GNU-Free-Documentation-License.html,
+The GNU FDL}
+is the license that covers this @value{DOCUMENT}.
+@end itemize
+
+Some of the chapters have exercise sections; these have also been
+omitted from the print edition but are available online.
+@end ifset
+
+@ifclear FOR_PRINT
+@itemize @value{MINUS}
+@item
@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.
+and some possible future directions for @command{gawk} development.
+@item
@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.
+The @ref{Glossary}, defines most, if not all, of the significant terms used
+throughout the @value{DOCUMENT}. If you find terms that you aren't familiar with,
+try looking them up here.
+@item
@ref{Copying}, and
@ref{GNU Free Documentation License},
present the licenses that cover the @command{gawk} source code
and this @value{DOCUMENT}, respectively.
+@end itemize
+@end ifclear
+@end itemize
+
+@c FULLXREF OFF
@node Conventions
-@section Typographical Conventions
+@unnumberedsec Typographical Conventions
@cindex Texinfo
-This @value{DOCUMENT} is written in @uref{http://texinfo.org, Texinfo},
+This @value{DOCUMENT} is written in @uref{http://www.gnu.org/software/texinfo/, Texinfo},
the GNU documentation formatting language.
A single Texinfo source file is used to produce both the printed and online
versions of the documentation.
@@ -1259,12 +1840,19 @@ are slightly different than in other books you may have read.
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
+Examples you would type at the command line are preceded by the common
shell primary and secondary prompts, @samp{$} and @samp{>}.
Input that you type is shown @kbd{like this}.
+@c 8/2014: @print{} is stripped from the texi to make docbook.
+@ifclear FOR_PRINT
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
+@end ifclear
+@ifset FOR_PRINT
+Output from the command, usually its standard output, appears
+@code{like this}.
+@end ifset
+Error messages and other output on the command's standard error are preceded
by the glyph ``@error{}''. For example:
@example
@@ -1289,17 +1877,31 @@ Finally, @value{FN}s are indicated like this: @file{/path/to/ourfile}.
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
+another key, at the same time. For example, a @kbd{Ctrl-d} is typed
by first pressing and holding the @kbd{CONTROL} key, next
-pressing the @kbd{d} key and finally releasing both keys.
+pressing the @kbd{d} key, and finally releasing both keys.
+
+For the sake of brevity, throughout this @value{DOCUMENT}, we refer to
+Brian Kernighan's version of @command{awk} as ``BWK @command{awk}.''
+(@DBXREF{Other Versions} for information on his and other versions.)
+
+@ifset FOR_PRINT
+@quotation NOTE
+Notes of interest look like this.
+@end quotation
+
+@quotation CAUTION
+Cautionary or warning notes look like this.
+@end quotation
+@end ifset
@c fakenode --- for prepinfo
-@subsubheading Dark Corners
+@unnumberedsubsec 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
+@i{Dark corners are basically fractal---no matter how much
+you illuminate, there's always a smaller but darker one.}
+@author Brian Kernighan
@end quotation
@cindex d.c., See dark corner
@@ -1313,18 +1915,25 @@ the picture of a flashlight in the margin, as shown here.
@value{DARKCORNER}
@end iftex
@ifnottex
-``(d.c.)''.
+``(d.c.).''
@end ifnottex
+@ifclear FOR_PRINT
They also appear in the index under the heading ``dark corner.''
+@end ifclear
-As noted by the opening quote, though, any
-coverage of dark corners
-is, by definition, incomplete.
+But, as noted by the opening quote, any coverage of dark
+corners is by definition incomplete.
+@cindex c.e., See common extensions
Extensions to the standard @command{awk} language that are supported by
more than one @command{awk} implementation are marked
+@ifclear FOR_PRINT
``@value{COMMONEXT},'' and listed in the index under ``common extensions''
and ``extensions, common.''
+@end ifclear
+@ifset FOR_PRINT
+``@value{COMMONEXT}'' for ``common extension.''
+@end ifset
@node Manual History
@unnumberedsec The GNU Project and This Book
@@ -1341,25 +1950,28 @@ Emacs editor. GNU Emacs is the most widely used version of Emacs today.
@cindex GPL (General Public License)
@cindex General Public License, See GPL
@cindex documentation, online
-The GNU@footnote{GNU stands for ``GNU's not Unix.''}
+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
+The FSF uses the GNU General Public License (GPL) to ensure that
+its software's
+source code is always available to the end user.
+@ifclear FOR_PRINT
+A copy of the GPL is included
@ifnotinfo
in this @value{DOCUMENT}
@end ifnotinfo
for your reference
(@pxref{Copying}).
+@end ifclear
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/software/gawk/manual/, their web site}.
+@uref{http://www.gnu.org/software/gawk/manual/, GNU's website}.
+@ifclear FOR_PRINT
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
@@ -1370,109 +1982,84 @@ 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@registeredsymbol{},
+system for Intel,
Power Architecture,
Sun SPARC, IBM S/390, and other
systems.@footnote{The terminology ``GNU/Linux'' is explained
in the @ref{Glossary}.}
Many GNU/Linux distributions are
available for download from the Internet.
-
-(There are numerous other freely available, Unix-like operating systems
-based on the
-Berkeley Software Distribution, and some of them use recent versions
-of @command{gawk} for their versions of @command{awk}.
-@uref{http://www.netbsd.org, NetBSD},
-@uref{http://www.freebsd.org, FreeBSD},
-and
-@uref{http://www.openbsd.org, OpenBSD}
-are three of the most popular ones, but there
-are others.)
+@end ifclear
@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
+source code for the @value{DOCUMENT} comes with @command{gawk}.
+@ifclear FOR_PRINT
+(Take a moment to check the Free Documentation
License in @ref{GNU Free Documentation License}.)
+@end ifclear
@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.
+The @value{DOCUMENT} itself has gone through multiple previous editions.
Paul Rubin wrote the very first draft of @cite{The GAWK Manual};
-it was around 40 pages in size.
+it was around 40 pages long.
Diane Close and Richard Stallman improved it, yielding a
version that was
-around 90 pages long and barely described the original, ``old''
+around 90 pages 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.
+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}.
+@ifset FOR_PRINT
+SSC published two editions of the @value{DOCUMENT} under the
+title @cite{Effective awk Programming}, and O'Reilly published
+the third edition in 2001.
+@end ifset
This edition maintains the basic structure of the previous editions.
-For Edition 4.0, the content has been thoroughly reviewed
-and updated. All references to versions prior to 4.0 have been
-removed.
-Of significant note for this edition is @ref{Debugger}.
-
-@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.
+For FSF edition 4.0, the content was thoroughly reviewed and updated. All
+references to @command{gawk} versions prior to 4.0 were removed.
+Of significant note for that edition was the addition of @ref{Debugger}.
+
+For FSF edition
+@ifclear FOR_PRINT
+@value{EDITION},
+@end ifclear
+@ifset FOR_PRINT
+@value{EDITION}
+(the fourth edition as published by O'Reilly),
+@end ifset
+the content has been reorganized into parts,
+and the major new additions are @ref{Arbitrary Precision Arithmetic},
+and @ref{Dynamic Extensions}.
+
+This @value{DOCUMENT} will undoubtedly continue to evolve. If you
+find an error in the @value{DOCUMENT}, please report it! @DBXREF{Bugs}
+for information on submitting problem reports electronically.
+
+@ifset FOR_PRINT
+@c fakenode --- for prepinfo
+@unnumberedsec How to Stay Current
+
+You may have a newer version of @command{gawk} than the
+one described here. To find out what has changed,
+you should first look at the @file{NEWS} file in the @command{gawk}
+distribution, which provides a high-level summary of the changes in
+each release.
+You can then look at the @uref{http://www.gnu.org/software/gawk/manual/,
+online version} of this @value{DOCUMENT} to read about any new features.
+@end ifset
+
+@ifclear FOR_PRINT
@node How To Contribute
@unnumberedsec How to Contribute
@@ -1489,20 +2076,26 @@ However, I found that I could not dedicate enough time to managing
contributed code: the archive did not grow and the domain went unused
for several years.
-Fortunately, late in 2008, a volunteer took on the task of setting up
-an @command{awk}-related web site---@uref{http://awk.info}---and did a very
+Late in 2008, a volunteer took on the task of setting up
+an @command{awk}-related website---@uref{http://awk.info}---and did a very
nice job.
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 see @uref{http://awk.info/?contribute} for how to
-contribute it to the web site.
+contribute it to the website.
+
+@ignore
+As of this writing, this website is in search of a maintainer; please
+contact me if you are interested.
+@end ignore
@ignore
Other links:
http://www.reddit.com/r/linux/comments/dtect/composing_music_in_awk/
@end ignore
+@end ifclear
@node Acknowledgments
@unnumberedsec Acknowledgments
@@ -1513,7 +2106,7 @@ The initial draft of @cite{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 @cite{A Supplemental Document for @command{awk}} by John W.@:
+manual. The paper @cite{A Supplemental Document for 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.
@@ -1524,12 +2117,18 @@ 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.
+@ifclear FOR_PRINT
Earlier editions of this @value{DOCUMENT} had the following acknowledgements:
+@end ifclear
+@ifset FOR_PRINT
+The previous edition of this @value{DOCUMENT} had
+the following acknowledgements:
+@end ifset
@quotation
The following people (in alphabetical order)
provided helpful comments on various
-versions of this book,
+versions of this book:
Rick Adams,
Dr.@: Nelson H.F. Beebe,
Karl Berry,
@@ -1557,7 +2156,7 @@ 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}.
+@cite{How to Gawk Politely}.
Karl Berry helped significantly with the @TeX{} part of Texinfo.
@cindex Hartholz, Marshall
@@ -1588,64 +2187,91 @@ 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.
-Chuck Toporek, Mary Sheehan, and Claire Coutier of O'Reilly & Associates contributed
+Chuck Toporek, Mary Sheehan, and Claire Cloutier of O'Reilly & Associates contributed
significant editorial help for this @value{DOCUMENT} for the
3.1 release of @command{gawk}.
@end quotation
-@cindex Beebe, Nelson
+@cindex Beebe, Nelson H.F.@:
@cindex Buening, Andreas
+@cindex Collado, Manuel
@cindex Colombo, Antonio
@cindex Davies, Stephen
@cindex Deifik, Scott
-@cindex DuBois, John
+@cindex Demaille, Akim
@cindex Hankerson, Darrel
-@cindex Haque, John
@cindex Jaegermann, Michal
@cindex Kahrs, J@"urgen
@cindex Kasal, Stepan
+@cindex Malmberg, John
@cindex Pitts, Dave
+@cindex Ramey, Chet
@cindex Rankin, Pat
@cindex Schorr, Andrew
@cindex Vinschen, Corinna
-@cindex Wallin, Anders
@cindex Zaretskii, Eli
+
Dr.@: Nelson Beebe,
Andreas Buening,
+Dr.@: Manuel Collado,
Antonio Colombo,
Stephen Davies,
Scott Deifik,
-John H. DuBois III,
+Akim Demaille,
Darrel Hankerson,
Michal Jaegermann,
J@"urgen Kahrs,
-Dave Pitts,
Stepan Kasal,
+John Malmberg,
+Dave Pitts,
+Chet Ramey,
Pat Rankin,
Andrew Schorr,
Corinna Vinschen,
-Anders Wallin,
and Eli Zaretskii
(in alphabetical order)
-make up the current
-@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.
-
-John Haque contributed the modifications to convert @command{gawk}
-into a byte-code interpreter, including the debugger. Stephen Davies
-contributed to the effort to bring the byte-code changes into the mainstream
-code base.
-Efraim Yawitz contributed the initial text of @ref{Debugger}.
+make up the current @command{gawk} ``crack portability team.'' Without
+their hard work and help, @command{gawk} would not be nearly the robust,
+portable program it is today. It has been and continues to be a pleasure
+working with this team of fine people.
+
+Notable code and documentation contributions were made by
+a number of people. @DBXREF{Contributors} for the full list.
+
+@ifset FOR_PRINT
+@cindex Oram, Andy
+Thanks to Andy Oram of O'Reilly Media for initiating
+the fourth edition and for his support during the work.
+Thanks to Jasmine Kwityn for her copyediting work.
+@end ifset
+
+Thanks to Michael Brennan for the Forewords.
+
+@cindex Duman, Patrice
+@cindex Berry, Karl
+Thanks to Patrice Dumas for the new @command{makeinfo} program.
+Thanks to Karl Berry, who continues to work to keep
+the Texinfo markup language sane.
@cindex Kernighan, Brian
-I would like to thank Brian Kernighan for invaluable assistance during the
-testing and debugging of @command{gawk}, and for ongoing
+@cindex Brennan, Michael
+@cindex Day, Robert P.J.@:
+Robert P.J.@: Day, Michael Brennan, and Brian Kernighan kindly acted as
+reviewers for the 2015 edition of this @value{DOCUMENT}. Their feedback
+helped improve the final work.
+
+I would also like to thank Brian Kernighan for his invaluable assistance during the
+testing and debugging of @command{gawk}, and for his ongoing
help and advice in clarifying numerous points about the language.
- We could not have done nearly as good a job on either @command{gawk}
+We could not have done nearly as good a job on either @command{gawk}
or its documentation without his help.
+Brian is in a class by himself as a programmer and technical
+author. I have to thank him (yet again) for his ongoing friendship
+and for being a role model to me for close to 30 years!
+Having him as a reviewer is an exciting privilege. It has also
+been extremely humbling@enddots{}
+
@cindex Robbins, Miriam
@cindex Robbins, Jean
@cindex Robbins, Harry
@@ -1658,63 +2284,56 @@ 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.
+@iftex
@sp 2
@noindent
Arnold Robbins @*
Nof Ayalon @*
-ISRAEL @*
-March, 2011
+Israel @*
+December 2014
+@end iftex
-@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:
+@ifnotinfo
+@part @value{PART1}The @command{awk} Language
+@end ifnotinfo
-@itemize @bullet
-@item
-@ref{Getting Started}.
+@ifdocbook
-@item
-@ref{Regexp}.
+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}. Included also are many, but not all,
+of the features of @command{gawk}. This part contains the
+following chapters:
+@itemize @value{BULLET}
@item
-@ref{Reading Files}.
+@ref{Getting Started}
@item
-@ref{Printing}.
+@ref{Invoking Gawk}
@item
-@ref{Expressions}.
+@ref{Regexp}
@item
-@ref{Patterns and Actions}.
+@ref{Reading Files}
@item
-@ref{Arrays}.
+@ref{Printing}
@item
-@ref{Functions}.
+@ref{Expressions}
@item
-@ref{Internationalization}.
+@ref{Patterns and Actions}
@item
-@ref{Advanced Features}.
+@ref{Arrays}
@item
-@ref{Invoking Gawk}.
+@ref{Functions}
@end itemize
-
-@page
-@evenheading @thispage@ @ @ @strong{@value{TITLE}} @| @|
-@oddheading @| @| @strong{@thischapter}@ @ @ @thispage
-@end iftex
-@end ignore
+@end ifdocbook
@node Getting Started
@chapter Getting Started with @command{awk}
@@ -1727,17 +2346,17 @@ and @command{gawk}. It contains the following chapters:
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
+@command{awk} continues to process 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.
+because @command{awk} programs are @dfn{data driven} (i.e., 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
+detail, every step the program should 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
@@ -1747,15 +2366,15 @@ read and write.
@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
+@dfn{rules} (it may also contain @dfn{function definitions},
+an advanced feature that we will ignore for now;
+@pxref{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}
+Syntactically, a rule consists of a @dfn{pattern} followed by an
+@dfn{action}. The action is enclosed in braces to separate it from the
+pattern. Newlines usually separate rules. Therefore, an @command{awk}
program looks like this:
@example
@@ -1778,6 +2397,7 @@ program looks like this:
* Other Features:: Other Features of @command{awk}.
* When:: When to use @command{gawk} and when to use
other things.
+* Intro Summary:: Summary of the introduction.
@end menu
@node Running gawk
@@ -1806,7 +2426,7 @@ variations of each.
@menu
* One-shot:: Running a short throwaway @command{awk}
program.
-* Read Terminal:: Using no input files (input from terminal
+* Read Terminal:: Using no input files (input from the keyboard
instead).
* Long:: Putting permanent @command{awk} programs in
files.
@@ -1828,8 +2448,8 @@ 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.
+where @var{program} consists of a series of patterns and
+actions, as described earlier.
@cindex single quote (@code{'})
@cindex @code{'} (single quote)
@@ -1848,11 +2468,12 @@ 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.
+Later in this chapter, in
+@ifdocbook
+the section
+@end ifdocbook
@ref{Very Simple},
-@ifnotinfo
-later in this @value{CHAPTER},
-@end ifnotinfo
-presents several short,
+we'll see examples of several short,
self-contained programs.
@node Read Terminal
@@ -1870,10 +2491,15 @@ awk '@var{program}'
@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, it is @kbd{@value{CTL}-z}.)
+which usually means whatever you type on the keyboard. This continues
+until you indicate end-of-file by typing @kbd{Ctrl-d}.
+@ifset FOR_PRINT
+(On non-POSIX operating systems, the end-of-file character may be different.)
+@end ifset
+@ifclear FOR_PRINT
+(On non-POSIX operating systems, the end-of-file character may be different.
+For example, on OS/2, it is @kbd{Ctrl-z}.)
+@end ifclear
@cindex files, input, See input files
@cindex input files, running @command{awk} without
@@ -1881,33 +2507,31 @@ For example, on OS/2, it is @kbd{@value{CTL}-z}.)
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@footnote{If you use Bash as your shell, you should execute
-the command @samp{set +H} before running this program interactively,
-to disable the C shell-style command history, which treats
-@samp{!} as a special character. We recommend putting this command into
-your personal startup file.}
-(@code{BEGIN} is a feature we haven't discussed yet):
+programming:
@example
-$ @kbd{awk "BEGIN @{ print \"Don't Panic!\" @}"}
+$ @kbd{awk 'BEGIN @{ print "Don\47t 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.}
+@command{awk} executes statements associated with @code{BEGIN} before
+reading any input. If there are no other statements in your program,
+as is the case here, @command{awk} just stops, instead of trying to read
+input it doesn't know how to process.
+The @samp{\47} is a magic way (explained later) of getting a single quote into
+the program, without having to engage in ugly shell quoting tricks.
+
+@quotation NOTE
+If you use Bash as your shell, you should execute the
+command @samp{set +H} before running this program interactively, to
+disable the C shell-style command history, which treats @samp{!} as a
+special character. We recommend putting this command into your personal
+startup file.
+@end quotation
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).
+keyboard to its standard output (why this works is explained shortly):
@example
$ @kbd{awk '@{ print @}'}
@@ -1919,7 +2543,7 @@ $ @kbd{awk '@{ print @}'}
@print{} Four score and seven years ago, ...
@kbd{What, me worry?}
@print{} What, me worry?
-@kbd{@value{CTL}-d}
+@kbd{Ctrl-d}
@end example
@node Long
@@ -1928,7 +2552,7 @@ $ @kbd{awk '@{ print @}'}
@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
+Sometimes @command{awk} programs are very long. In these cases, 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:
@@ -1936,12 +2560,12 @@ more convenient to put the program into a separate file. In order to tell
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:
+@cindex @option{-f} option
+@cindex command line, option @option{-f}
+The @option{-f} instructs the @command{awk} utility to get the
+@command{awk} program from the file @var{source-file} (@pxref{Options}).
+Any @value{FN} can be used for @var{source-file}. For example, you
+could put the program:
@example
BEGIN @{ print "Don't Panic!" @}
@@ -1958,10 +2582,10 @@ awk -f advice
does the same thing as this one:
@example
-awk "BEGIN @{ print \"Don't Panic!\" @}"
+awk 'BEGIN @{ print "Don\47t Panic!" @}'
@end example
-@cindex quoting
+@cindex quoting in @command{gawk} command lines
@noindent
This was explained earlier
(@pxref{Read Terminal}).
@@ -1970,12 +2594,12 @@ specify with @option{-f}, because most @value{FN}s don't contain any of the shel
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.
+(Also, placing the program in a file allows us to use a literal single quote in the program
+text, instead of the magic @samp{\47}.)
-@c STARTOFRANGE sq1x
-@cindex single quote (@code{'})
-@c STARTOFRANGE qs2x
-@cindex @code{'} (single quote)
-If you want to clearly identify your @command{awk} program files as such,
+@cindex single quote (@code{'}) in @command{gawk} command lines
+@cindex @code{'} (single quote) in @command{gawk} command lines
+If you want to clearly identify an @command{awk} program file 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.
@@ -1984,15 +2608,13 @@ affect the execution of the @command{awk} program but it does make
@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
+@cindex number sign (@code{#}), @code{#!} (executable scripts)
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 systems.@footnote{The @samp{#!} mechanism works on
-GNU/Linux systems, BSD-based systems and commercial Unix systems.}
+GNU/Linux systems, BSD-based systems, and commercial Unix systems.}
For example, you could update the file @file{advice} to look like this:
@example
@@ -2004,14 +2626,7 @@ BEGIN @{ print "Don't Panic!" @}
@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
+at the shell and the system arranges to run @command{awk} as if you had
typed @samp{awk -f advice}:
@example
@@ -2029,10 +2644,32 @@ 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 sidebar, Understanding @samp{#!}
+@ifdocbook
+@docbook
+<sidebar><title>Understanding @samp{#!}</title>
+@end docbook
+
@cindex portability, @code{#!} (executable scripts)
+@command{awk} is an @dfn{interpreted} language. This means that the
+@command{awk} utility reads your program and then processes your data
+according to the instructions in your program. (This is different
+from a @dfn{compiled} language such as C, where your program is first
+compiled into machine code that is executed directly by your system's
+processor.) The @command{awk} utility is thus termed an @dfn{interpreter}.
+Many modern languages are interpreted.
+
+The line beginning with @samp{#!} lists the full @value{FN} of an
+interpreter to run and a single 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. (Note that on
+many systems @command{awk} may be found in @file{/usr/bin} instead of
+in @file{/bin}.)
+
Some systems limit the length of the interpreter name to 32 characters.
Often, this can be dealt with by using a symbolic link.
@@ -2044,8 +2681,7 @@ 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]}
+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
@@ -2054,6 +2690,58 @@ of your script (@samp{advice}). @value{DARKCORNER}
Don't rely on the value of @code{ARGV[0]}
to provide your script name.
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{Understanding @samp{#!}}
+
+
+@cindex portability, @code{#!} (executable scripts)
+
+@command{awk} is an @dfn{interpreted} language. This means that the
+@command{awk} utility reads your program and then processes your data
+according to the instructions in your program. (This is different
+from a @dfn{compiled} language such as C, where your program is first
+compiled into machine code that is executed directly by your system's
+processor.) The @command{awk} utility is thus termed an @dfn{interpreter}.
+Many modern languages are interpreted.
+
+The line beginning with @samp{#!} lists the full @value{FN} of an
+interpreter to run and a single 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. (Note that on
+many systems @command{awk} may be found in @file{/usr/bin} instead of
+in @file{/bin}.)
+
+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}). @value{DARKCORNER}
+Don't rely on the value of @code{ARGV[0]}
+to provide your script name.
+@end cartouche
+@end ifnotdocbook
+
@node Comments
@subsection Comments in @command{awk} Programs
@cindex @code{#} (number sign), commenting
@@ -2067,14 +2755,14 @@ 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
+In the @command{awk} language, a comment starts with the number 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.
+@command{awk} language ignores the rest of a line following a number sign.
For example, we could have put the following into @file{advice}:
@example
-# This program prints a nice friendly message. It helps
+# 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
@@ -2084,13 +2772,14 @@ 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 quoting, for small awk programs
@cindex single quote (@code{'}), vs.@: apostrophe
@cindex @code{'} (single quote), vs.@: apostrophe
@quotation CAUTION
As mentioned in
@ref{One-shot},
-you can enclose small to medium programs in single quotes, in order to keep
+you can enclose short to medium-sized 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
@@ -2100,7 +2789,7 @@ runs, it will probably print strange messages about syntax errors.
For example, look at the following:
@example
-$ @kbd{awk '@{ print "hello" @} # let's be cute'}
+$ @kbd{awk 'BEGIN @{ print "hello" @} # let's be cute'}
>
@end example
@@ -2119,19 +2808,19 @@ $ @kbd{awk '@{ print "hello" @} # let's be cute'}
@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.
+because backslashes are not special inside single quotes.
The next @value{SUBSECTION} describes the shell's quoting rules.
@end quotation
@node Quoting
-@subsection Shell-Quoting Issues
-@cindex quoting, rules for
+@subsection Shell Quoting Issues
+@cindex shell quoting, rules for
@menu
* DOS Quoting:: Quoting in Windows Batch Files.
@end menu
-For short to medium length @command{awk} programs, it is most convenient
+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
@@ -2148,7 +2837,27 @@ 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 the C shell, you're on your own.
-@itemize @bullet
+Before diving into the rules, we introduce a concept that appears
+throughout this @value{DOCUMENT}, which is that of the @dfn{null},
+or empty, 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{""}. In the shell, it can be written using single
+or double quotes: @code{""} or @code{''}. Although the null string has
+no characters in it, it does exist. For example, consider this command:
+
+@example
+$ @kbd{echo ""}
+@end example
+
+@noindent
+Here, the @command{echo} utility receives a single argument, even
+though that argument has no characters in it. In the rest of this
+@value{DOCUMENT}, we use the terms @dfn{null string} and @dfn{empty string}
+interchangeably. Now, on to the quoting rules:
+
+@itemize @value{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
@@ -2160,26 +2869,26 @@ 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)
+@cindex @code{\} (backslash), in shell commands
+@cindex backslash (@code{\}), in shell commands
+@cindex single quote (@code{'}), in shell commands
+@cindex @code{'} (single quote), in shell commands
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},
+@DBREF{Comments}
for an example of what happens if you try.
@item
-@cindex double quote (@code{"})
-@cindex @code{"} (double quote)
+@cindex double quote (@code{"}), in shell commands
+@cindex @code{"} (double quote), in shell commands
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,
+Because 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
@@ -2188,8 +2897,14 @@ Thus, the example seen
@ifnotinfo
previously
@end ifnotinfo
-in @ref{Read Terminal},
-is applicable:
+in @ref{Read Terminal}:
+
+@example
+awk 'BEGIN @{ print "Don\47t Panic!" @}'
+@end example
+
+@noindent
+could instead be written this way:
@example
$ @kbd{awk "BEGIN @{ print \"Don't Panic!\" @}"}
@@ -2202,7 +2917,7 @@ 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.
+command-line argument, while explicit null objects are kept.
For example, to specify that the field separator @code{FS} should
be set to the null string, use:
@@ -2211,7 +2926,7 @@ awk -F "" '@var{program}' @var{files} # correct
@end example
@noindent
-@cindex null strings, quoting and
+@cindex null strings in @command{gawk} arguments, quoting and
Don't use this:
@example
@@ -2219,12 +2934,12 @@ 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
+In the second case, @command{awk} attempts 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
+@cindex quoting in @command{gawk} command lines, tricks for
Mixing single and double quotes is difficult. You have to resort
to shell quoting tricks, like this:
@@ -2235,7 +2950,7 @@ $ @kbd{awk 'BEGIN @{ print "Here is a single quote <'"'"'>" @}'}
@noindent
This program consists of three concatenated quoted strings. The first and the
-third are single-quoted, the second is double-quoted.
+third are single-quoted, and the second is double-quoted.
This can be ``simplified'' to:
@@ -2256,8 +2971,6 @@ $ @kbd{awk "BEGIN @{ 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 more advanced @command{awk} programs.
@@ -2274,19 +2987,22 @@ $ @kbd{awk 'BEGIN @{ print "Here is a double quote <\42>" @}'}
@end example
@noindent
-This works nicely, except that you should comment clearly what the
+This works nicely, but 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 ">" @}'
+$ @kbd{awk -v sq="'" 'BEGIN @{ print "Here is a single quote <" sq ">" @}'}
@print{} Here is a single quote <'>
@end example
+(Here, the two string constants and the value of @code{sq} are concatenated
+into a single string that is printed by @code{print}.)
+
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.
+the shell won't be part of the picture and you can say what you mean.
@node DOS Quoting
@subsubsection Quoting in MS-Windows Batch Files
@@ -2323,6 +3039,7 @@ Although this @value{DOCUMENT} generally only worries about POSIX systems and th
POSIX shell, the following issue arises often enough for many users that
it is worth addressing.
+@cindex Brink, Jeroen
The ``shells'' on Microsoft Windows systems use the double-quote
character for quoting, and make it difficult or impossible to include an
escaped double-quote character in a command-line script.
@@ -2336,43 +3053,43 @@ gawk "@{ print \"\042\" $0 \"\042\" @}" @var{file}
@node Sample Data Files
@section @value{DDF}s for the Examples
-@c For gawk >= 4.0, update these data files. No-one has such slow modems!
@cindex input files, examples
-@cindex @code{BBS-list} file
+@cindex @code{mail-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.
+@value{DF}s. The first, @file{mail-list}, represents a list of peoples' names
+together with their email addresses and information about those people.
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:
+In @file{mail-list}, each record contains the name of a person,
+his/her phone number, his/her email address, and a code for his/her relationship
+with the author of the list.
+The columns are aligned using spaces.
+An @samp{A} in the last column
+means that the person is an acquaintance. An @samp{F} in the last
+column means that the person is a friend.
+An @samp{R} means that the person is a relative:
-@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 file eg/data/mail-list
+Amelia 555-5553 amelia.zodiacusque@@gmail.com F
+Anthony 555-3412 anthony.asserturo@@hotmail.com A
+Becky 555-7685 becky.algebrarum@@gmail.com A
+Bill 555-1675 bill.drowning@@hotmail.com A
+Broderick 555-0542 broderick.aliquotiens@@yahoo.com R
+Camilla 555-2912 camilla.infusarum@@skynet.be R
+Fabius 555-1234 fabius.undevicesimus@@ucb.edu F
+Julie 555-6699 julie.perscrutabor@@skeeve.com F
+Martin 555-6480 martin.codicibus@@hotmail.com A
+Samuel 555-3430 samuel.lanceolis@@shu.edu A
+Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R
@c endfile
@end example
@@ -2384,6 +3101,7 @@ 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.
+An empty line separates the data for the two years:
@example
@c file eg/data/inventory-shipped
@@ -2407,45 +3125,30 @@ 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
+The sample files are included in the @command{gawk} distribution,
+in the directory @file{awklib/eg/data}.
@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
+input file @file{mail-list} for the character string @samp{li} (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''):
+as ``a string of pearls'' or ``a string of cars in a train''):
@example
-awk '/foo/ @{ print $0 @}' BBS-list
+awk '/li/ @{ print $0 @}' mail-list
@end example
@noindent
-When lines containing @samp{foo} are found, they are printed because
+When lines containing @samp{li} 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}
+You will notice that slashes (@samp{/}) surround the string @samp{li}
+in the @command{awk} program. The slashes indicate that @samp{li}
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}).
@@ -2457,11 +3160,11 @@ interpret any of it as special shell characters.
Here is what this program prints:
@example
-$ @kbd{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
+$ @kbd{awk '/li/ @{ print $0 @}' mail-list}
+@print{} Amelia 555-5553 amelia.zodiacusque@@gmail.com F
+@print{} Broderick 555-0542 broderick.aliquotiens@@yahoo.com R
+@print{} Julie 555-6699 julie.perscrutabor@@skeeve.com F
+@print{} Samuel 555-3430 samuel.lanceolis@@shu.edu A
@end example
@cindex actions, default
@@ -2472,18 +3175,18 @@ 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
+Thus, we could leave out the action (the @code{print} statement and the
braces) in the previous example and the result would be the same:
-@command{awk} prints all lines matching the pattern @samp{foo}. By comparison,
-omitting the @code{print} statement but retaining the curly braces makes an
+@command{awk} prints all lines matching the pattern @samp{li}. By comparison,
+omitting the @code{print} statement but retaining the 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
+Many practical @command{awk} programs are just a line or two long. 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!)
+of the program will give you a good idea of what is going on, but you'll
+need to 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}.
@@ -2492,36 +3195,41 @@ 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
+@itemize @value{BULLET}
@item
-Print the length of the longest input line:
+Print every line that is longer than 80 characters:
@example
-awk '@{ if (length($0) > max) max = length($0) @}
- END @{ print max @}' data
+awk 'length($0) > 80' data
@end example
+The sole rule has a relational expression as its pattern and has no
+action---so it uses the default action, printing the record.
+
@item
-Print every line that is longer than 80 characters:
+Print the length of the longest input line:
@example
-awk 'length($0) > 80' data
+awk '@{ if (length($0) > max) max = length($0) @}
+ END @{ print max @}' 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.
+The code associated with @code{END} executes after all
+input has been read; it's the other side of the coin to @code{BEGIN}.
@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 @}'
+expand data | awk '@{ if (x < length($0)) x = length($0) @}
+ 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.
+This example differs slightly from the previous one:
+the input is processed by the @command{expand} utility to change TABs
+into spaces, so the widths compared are actually the right-margin columns,
+as opposed to the number of input characters on each line.
@item
Print every line that has at least one field:
@@ -2547,7 +3255,7 @@ Print the total number of bytes used by @var{files}:
@example
ls -l @var{files} | awk '@{ x += $5 @}
- END @{ print "total bytes: " x @}'
+ END @{ print "total bytes: " x @}'
@end example
@item
@@ -2582,7 +3290,7 @@ Print the even-numbered lines in the @value{DF}:
awk 'NR % 2 == 0' data
@end example
-If you use the expression @samp{NR % 2 == 1} instead,
+If you used the expression @samp{NR % 2 == 1} instead,
the program would print the odd-numbered lines.
@end itemize
@@ -2591,15 +3299,20 @@ the program would print the odd-numbered lines.
@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
+time. For each line, @command{awk} tries the patterns of each rule.
+If several patterns match, then several actions execute in the order in
which they appear in the @command{awk} program. If no patterns match, then
-no actions are run.
+no actions 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}).
+@DBPXREF{Next Statement}
+@ifdocbook
+and @DBREF{Nextfile Statement}.)
+@end ifdocbook
+@ifnotdocbook
+and also @pxref{Nextfile Statement}.)
+@end ifnotdocbook
This continues until the program reaches the end of the file.
For example, the following @command{awk} program contains two rules:
@@ -2619,29 +3332,23 @@ This program prints every line that contains the string
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}:
+@file{mail-list} and @file{inventory-shipped}:
@example
$ @kbd{awk '/12/ @{ print $0 @}}
-> @kbd{/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
+> @kbd{/21/ @{ print $0 @}' mail-list inventory-shipped}
+@print{} Anthony 555-3412 anthony.asserturo@@hotmail.com A
+@print{} Camilla 555-2912 camilla.infusarum@@skynet.be R
+@print{} Fabius 555-1234 fabius.undevicesimus@@ucb.edu F
+@print{} Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R
+@print{} Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R
@print{} Jan 21 36 64 620
@print{} Apr 21 70 74 514
@end example
@noindent
-Note how the line beginning with @samp{sabafoo}
-in @file{BBS-list} was printed twice, once for each rule.
+Note how the line beginning with @samp{Jean-Paul}
+in @file{mail-list} was printed twice, once for each rule.
@node More Complex
@section A More Complex Example
@@ -2654,8 +3361,8 @@ features that haven't been covered yet, so don't worry if you don't
understand all the details:
@example
-LC_ALL=C ls -l | awk '$6 == "Nov" @{ sum += $5 @}
- END @{ print sum @}'
+ls -l | awk '$6 == "Nov" @{ sum += $5 @}
+ END @{ print sum @}'
@end example
@cindex @command{ls} utility
@@ -2679,21 +3386,20 @@ the file was last modified. Its output looks like this:
@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
+the number of links to the file, and the third field identifies the file's owner.
+The fourth field identifies the file's group.
+The fifth field contains the file's size 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 @value{FN}.@footnote{The @samp{LC_ALL=C} is
-needed to produce this traditional-style output from @command{ls}.}
+contains the @value{FN}.
@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
+@samp{Nov} for its sixth field, @command{awk} performs the action
+@samp{sum += $5}. 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
@@ -2720,7 +3426,7 @@ separate rule, like this:
@example
awk '/12/ @{ print $0 @}
- /21/ @{ print $0 @}' BBS-list inventory-shipped
+ /21/ @{ print $0 @}' mail-list inventory-shipped
@end example
@cindex @command{gawk}, newlines in
@@ -2760,7 +3466,7 @@ We have generally not used backslash continuation in our sample programs.
@command{gawk} places 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
+for clarity, we have kept most statements short in the 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
@@ -2780,7 +3486,7 @@ lines in the middle of a regular expression or a string.
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 Bash. But the C shell behaves
-differently! There, you must use two backslashes in a row, followed by
+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 @command{awk} program must be escaped with a backslash. To illustrate:
@@ -2821,11 +3527,11 @@ 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
-> @}'
+$ @kbd{gawk 'BEGIN @{ print "dont panic" # a friendly \}
+> @kbd{ BEGIN rule}
+> @kbd{@}'}
@error{} gawk: cmd. line:2: BEGIN rule
-@error{} gawk: cmd. line:2: ^ parse error
+@error{} gawk: cmd. line:2: ^ syntax error
@end example
@noindent
@@ -2835,8 +3541,8 @@ 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{;})
+@cindex @code{;} (semicolon), separating statements in actions
+@cindex semicolon (@code{;}), separating statements in actions
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{;}).
@@ -2871,9 +3577,9 @@ performing bit manipulation, for runtime string translation (internationalizatio
determining the type of a variable,
and array sorting.
-As we develop our presentation of the @command{awk} language, we introduce
+As we develop our presentation of the @command{awk} language, we will introduce
most of the variables and many of the functions. They are described
-systematically in @ref{Built-in Variables}, and
+systematically in @DBREF{Built-in Variables} and in
@ref{Built-in}.
@node When
@@ -2896,34 +3602,74 @@ 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.
+@cindex Brian Kernighan's @command{awk}
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
+retargetable assembler for
+@ifclear FOR_PRINT
+eight-bit microprocessors (@pxref{Glossary}, for more information),
+@end ifclear
+@ifset FOR_PRINT
+eight-bit microprocessors,
+@end ifset
+and a microcode assembler for a special-purpose Prolog
computer.
-While the original @command{awk}'s capabilities were strained by tasks
-of such complexity, modern versions are more capable. Even Brian Kernighan's
-version of @command{awk} has fewer predefined limits, and those
-that it has are much larger than they used to be.
+The original @command{awk}'s capabilities were strained by tasks
+of such complexity, but modern versions are more capable.
@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.
+If you find yourself writing @command{awk} scripts of more than, say,
+a few hundred lines, you might consider using a different programming
+language. The shell is good at string and pattern matching; in addition,
+it allows powerful use of the system utilities. Python offers a nice
+balance between high-level ease of programming and access to system
+facilities.@footnote{Other popular scripting languages include Ruby
+and Perl.}
+
+@node Intro Summary
+@section Summary
+
+@c FIXME: Review this chapter for summary of builtin functions called.
+@itemize @value{BULLET}
+@item
+Programs in @command{awk} consist of @var{pattern}--@var{action} pairs.
+
+@item
+An @var{action} without a @var{pattern} always runs. The default
+@var{action} for a pattern without one is @samp{@{ print $0 @}}.
+
+@item
+Use either
+@samp{awk '@var{program}' @var{files}}
+or
+@samp{awk -f @var{program-file} @var{files}}
+to run @command{awk}.
+
+@item
+You may use the special @samp{#!} header line to create @command{awk}
+programs that are directly executable.
+
+@item
+Comments in @command{awk} programs start with @samp{#} and continue to
+the end of the same line.
+
+@item
+Be aware of quoting issues when writing @command{awk} programs as
+part of a larger shell script (or MS-Windows batch file).
+
+@item
+You may use backslash continuation to continue a source line.
+Lines are automatically continued after
+a comma, open brace, question mark, colon,
+@samp{||}, @samp{&&}, @code{do}, and @code{else}.
+@end itemize
@node Invoking Gawk
@chapter Running @command{awk} and @command{gawk}
-This @value{CHAPTER} covers how to run awk, both POSIX-standard
+This @value{CHAPTER} covers how to run @command{awk}, both POSIX-standard
and @command{gawk}-specific command-line options, and what
@command{awk} and
-@command{gawk} do with non-option arguments.
+@command{gawk} do with nonoption arguments.
It then proceeds to cover how @command{gawk} searches for source files,
reading standard input along with other files, @command{gawk}'s
environment variables, @command{gawk}'s exit status, using include files,
@@ -2942,8 +3688,10 @@ things in this @value{CHAPTER} that don't interest you right now.
* Environment Variables:: The environment variables @command{gawk} uses.
* Exit Status:: @command{gawk}'s exit status.
* Include Files:: Including other files into your program.
+* Loading Shared Libraries:: Loading shared libraries into your program.
* Obsolete:: Obsolete Options and/or features.
* Undocumented:: Undocumented Options and Features.
+* Invoking Summary:: Invocation summary.
@end menu
@node Command Line
@@ -2957,15 +3705,15 @@ 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
+@display
+@command{awk} [@var{options}] @option{-f} @var{progfile} [@option{--}] @var{file} @dots{}
+@command{awk} [@var{options}] [@option{--}] @code{'@var{program}'} @var{file} @dots{}
+@end display
@cindex GNU long options
@cindex long options
@cindex options, long
-Besides traditional one-letter POSIX-style options, @command{gawk} also
+In addition to traditional one-letter POSIX-style options, @command{gawk} also
supports GNU long options.
@cindex dark corner, invoking @command{awk}
@@ -2976,7 +3724,7 @@ It is possible to invoke @command{awk} with an empty program:
awk '' datafile1 datafile2
@end example
-@cindex @code{--lint} option
+@cindex @option{--lint} option
@noindent
Doing so makes little sense, though; @command{awk} exits
silently when given an empty program.
@@ -2987,20 +3735,16 @@ 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
+to be uniquely identified. If the option takes an argument, either the
+keyword is 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
@@ -3016,27 +3760,27 @@ The following list describes options mandated by the POSIX standard:
@table @code
@item -F @var{fs}
@itemx --field-separator @var{fs}
-@cindex @code{-F} option
-@cindex @code{--field-separator} option
+@cindex @option{-F} option
+@cindex @option{--field-separator} option
@cindex @code{FS} variable, @code{--field-separator} option and
Set 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 @option{-f} option
+@cindex @option{--file} option
@cindex @command{awk} programs, location of
-Read @command{awk} program source from @var{source-file}
-instead of in the first non-option argument.
+Read the @command{awk} program source from @var{source-file}
+instead of in the first nonoption argument.
This option may be given multiple times; the @command{awk}
-program consists of the concatenation the contents of
+program consists of the concatenation of the contents of
each specified @var{source-file}.
@item -v @var{var}=@var{val}
@itemx --assign @var{var}=@var{val}
-@cindex @code{-v} option
-@cindex @code{--assign} option
+@cindex @option{-v} option
+@cindex @option{--assign} option
@cindex variables, setting
Set the variable @var{var} to the value @var{val} @emph{before}
execution of the program begins. Such variable values are available
@@ -3047,17 +3791,17 @@ 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
+@cindex predefined variables, @code{-v} option@comma{} setting with
+@cindex variables, predefined @code{-v} option@comma{} setting with
@quotation 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.
+initial value you may have given.
@end quotation
@item -W @var{gawk-opt}
-@cindex @code{-W} option
+@cindex @option{-W} option
Provide an implementation-specific option.
This is the POSIX convention for providing implementation-specific options.
These options
@@ -3082,53 +3826,59 @@ by the user that could start with @samp{-}.
It is also useful for passing options on to the @command{awk}
program; see @ref{Getopt Function}.
@end table
-@c ENDOFRANGE gnulo
-@c ENDOFRANGE longo
The following list describes @command{gawk}-specific options:
-@table @code
-@item -b
-@itemx --characters-as-bytes
-@cindex @code{-b} option
-@cindex @code{--characters-as-bytes} option
+@c Have to use @asis here to get docbook to come out right.
+@table @asis
+@item @option{-b}
+@itemx @option{--characters-as-bytes}
+@cindex @option{-b} option
+@cindex @option{--characters-as-bytes} option
Cause @command{gawk} to treat all input data as single-byte characters.
+In addition, all output written with @code{print} or @code{printf}
+is treated as single-byte characters.
+
Normally, @command{gawk} follows the POSIX standard and attempts to process
-its input data according to the current locale. This can often involve
+its input data according to the current locale (@pxref{Locales}). This can often involve
converting multibyte characters into wide characters (internally), and
can lead to problems or confusion if the input data does not contain valid
-multibyte characters. This option is an easy way to tell @command{gawk}:
-``hands off my data!''.
+multibyte characters. This option is an easy way to tell @command{gawk},
+``Hands off my data!''
-@item -c
-@itemx --traditional
-@cindex @code{--c} option
-@cindex @code{--traditional} option
+@item @option{-c}
+@itemx @option{--traditional}
+@cindex @option{-c} option
+@cindex @option{--traditional} option
@cindex compatibility mode (@command{gawk}), specifying
Specify @dfn{compatibility mode}, in which the GNU extensions to
the @command{awk} language are disabled, so that @command{gawk} behaves just
-like Brian Kernighan's version @command{awk}.
+like BWK @command{awk}.
@xref{POSIX/GNU},
-which summarizes the extensions. Also see
+which summarizes the extensions.
+@ifclear FOR_PRINT
+Also see
@ref{Compatibility Mode}.
+@end ifclear
-@item -C
-@itemx --copyright
-@cindex @code{-C} option
-@cindex @code{--copyright} option
+@item @option{-C}
+@itemx @option{--copyright}
+@cindex @option{-C} option
+@cindex @option{--copyright} option
@cindex GPL (General Public License), printing
Print the short version of the General Public License and then exit.
-@item -d@r{[}@var{file}@r{]}
-@itemx --dump-variables@r{[}=@var{file}@r{]}
-@cindex @code{-d} option
-@cindex @code{--dump-variables} option
-@cindex @code{awkvars.out} file
-@cindex files, @code{awkvars.out}
+@item @option{-d}[@var{file}]
+@itemx @option{--dump-variables}[@code{=}@var{file}]
+@cindex @option{-d} option
+@cindex @option{--dump-variables} option
+@cindex dump all variables of a program
+@cindex @file{awkvars.out} file
+@cindex files, @file{awkvars.out}
@cindex variables, global, printing list of
Print a sorted list of global variables, their types, and final values
to @var{file}. If no @var{file} is provided, print this
-list to the file named @file{awkvars.out} in the current directory.
+list to a file named @file{awkvars.out} in the current directory.
No space is allowed between the @option{-d} and @var{file}, if
@var{file} is supplied.
@@ -3141,10 +3891,24 @@ 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 -e @var{program-text}
-@itemx --source @var{program-text}
-@cindex @code{-e} option
-@cindex @code{--source} option
+@item @option{-D}[@var{file}]
+@itemx @option{--debug}[@code{=}@var{file}]
+@cindex @option{-D} option
+@cindex @option{--debug} option
+@cindex @command{awk} debugging, enabling
+Enable debugging of @command{awk} programs
+(@pxref{Debugging}).
+By default, the debugger reads commands interactively from the keyboard
+(standard input).
+The optional @var{file} argument allows you to specify a file with a list
+of commands for the debugger to execute noninteractively.
+No space is allowed between the @option{-D} and @var{file}, if
+@var{file} is supplied.
+
+@item @option{-e} @var{program-text}
+@itemx @option{--source} @var{program-text}
+@cindex @option{-e} option
+@cindex @option{--source} option
@cindex source code, mixing
Provide program source code in the @var{program-text}.
This option allows you to mix source code in files with source
@@ -3153,16 +3917,16 @@ This is particularly useful
when you have library functions that you want to use from your command-line
programs (@pxref{AWKPATH Variable}).
-@item -E @var{file}
-@itemx --exec @var{file}
-@cindex @code{-E} option
-@cindex @code{--exec} option
+@item @option{-E} @var{file}
+@itemx @option{--exec} @var{file}
+@cindex @option{-E} option
+@cindex @option{--exec} option
@cindex @command{awk} programs, location of
@cindex CGI, @command{awk} scripts for
Similar to @option{-f}, read @command{awk} program text from @var{file}.
There are two differences from @option{-f}:
-@itemize @bullet
+@itemize @value{BULLET}
@item
This option terminates option processing; anything
else on the command line is passed on directly to the @command{awk} program.
@@ -3175,7 +3939,13 @@ Command-line variable assignments of the form
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
+code (via @option{-e}) to the CGI application.@footnote{For more detail,
+please see Section 4.4 of @uref{http://www.ietf.org/rfc/rfc3875,
+RFC 3875}. Also see the
+@uref{http://lists.gnu.org/archive/html/bug-gawk/2014-11/msg00022.html,
+explanatory note sent to the @command{gawk} bug
+mailing list}.}
+This option should be used
with @samp{#!} scripts (@pxref{Executable Scripts}), like so:
@example
@@ -3184,36 +3954,69 @@ with @samp{#!} scripts (@pxref{Executable Scripts}), like so:
@var{awk program here @dots{}}
@end example
-@item -g
-@itemx --gen-pot
-@cindex @code{-g} option
-@cindex @code{--gen-pot} option
+@item @option{-g}
+@itemx @option{--gen-pot}
+@cindex @option{-g} option
+@cindex @option{--gen-pot} option
@cindex portable object files, generating
@cindex files, portable object, generating
Analyze the source program and
-generate a GNU @code{gettext} Portable Object Template file on standard
+generate a GNU @command{gettext} portable object template file on standard
output for all string constants that have been marked for translation.
@xref{Internationalization},
for information about this option.
-@item -h
-@itemx --help
-@cindex @code{-h} option
-@cindex @code{--help} option
+@item @option{-h}
+@itemx @option{--help}
+@cindex @option{-h} option
+@cindex @option{--help} option
@cindex GNU long options, printing list of
@cindex options, printing list of
@cindex printing, list of options
-Print a ``usage'' message summarizing the short and long style options
+Print a ``usage'' message summarizing the short- and long-style options
that @command{gawk} accepts and then exit.
-@item -L @r{[}value@r{]}
-@itemx --lint@r{[}=value@r{]}
-@cindex @code{-l} option
-@cindex @code{--lint} option
+@item @option{-i} @var{source-file}
+@itemx @option{--include} @var{source-file}
+@cindex @option{-i} option
+@cindex @option{--include} option
+@cindex @command{awk} programs, location of
+Read an @command{awk} source library from @var{source-file}. This option
+is completely equivalent to using the @code{@@include} directive inside
+your program. It is very similar to the @option{-f} option,
+but there are two important differences. First, when @option{-i} is
+used, the program source is not loaded if it has been previously
+loaded, whereas with @option{-f}, @command{gawk} always loads the file.
+Second, because this option is intended to be used with code libraries,
+@command{gawk} does not recognize such files as constituting main program
+input. Thus, after processing an @option{-i} argument, @command{gawk}
+still expects to find the main source code via the @option{-f} option
+or on the command line.
+
+@item @option{-l} @var{ext}
+@itemx @option{--load} @var{ext}
+@cindex @option{-l} option
+@cindex @option{--load} option
+@cindex loading, extensions
+Load a dynamic extension named @var{ext}. Extensions
+are stored as system shared libraries.
+This option searches for the library using the @env{AWKLIBPATH}
+environment variable. The correct library suffix for your platform will be
+supplied by default, so it need not be specified in the extension name.
+The extension initialization routine should be named @code{dl_load()}.
+An alternative is to use the @code{@@load} keyword inside the program to load
+a shared library. This advanced feature is described in detail in @ref{Dynamic Extensions}.
+
+@item @option{-L}[@var{value}]
+@itemx @option{--lint}[@code{=}@var{value}]
+@cindex @option{-l} option
+@cindex @option{--lint} option
@cindex lint checking, issuing warnings
@cindex warnings, issuing
Warn about constructs that are dubious or nonportable to
other @command{awk} implementations.
+No space is allowed between the @option{-L} and @var{value}, if
+@var{value} is supplied.
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},
@@ -3229,10 +4032,18 @@ when eliminating problems pointed out by @option{--lint}, you should take
care to search for all occurrences of each inappropriate construct. As
@command{awk} programs are usually short, doing so is not burdensome.
-@item -n
-@itemx --non-decimal-data
-@cindex @code{-n} option
-@cindex @code{--non-decimal-data} option
+@item @option{-M}
+@itemx @option{--bignum}
+@cindex @option{-M} option
+@cindex @option{--bignum} option
+Force arbitrary-precision arithmetic on numbers. This option has no effect
+if @command{gawk} is not compiled to use the GNU MPFR and MP libraries
+(@pxref{Arbitrary Precision Arithmetic}).
+
+@item @option{-n}
+@itemx @option{--non-decimal-data}
+@cindex @option{-n} option
+@cindex @option{--non-decimal-data} option
@cindex hexadecimal values@comma{} enabling interpretation of
@cindex octal values@comma{} enabling interpretation of
@cindex troubleshooting, @code{--non-decimal-data} option
@@ -3241,30 +4052,46 @@ values in input data
(@pxref{Nondecimal Data}).
@quotation CAUTION
-This option can severely break old programs.
-Use with care.
+This option can severely break old programs. Use with care. Also note
+that this option may disappear in a future version of @command{gawk}.
@end quotation
-@item -N
-@itemx --use-lc-numeric
-@cindex @code{-N} option
-@cindex @code{--use-lc-numeric} option
+@item @option{-N}
+@itemx @option{--use-lc-numeric}
+@cindex @option{-N} option
+@cindex @option{--use-lc-numeric} option
Force the use of the locale's decimal point character
when parsing numeric input data (@pxref{Locales}).
-@item -O
-@itemx --optimize
-@cindex @code{--optimize} option
-@cindex @code{-O} option
+@item @option{-o}[@var{file}]
+@itemx @option{--pretty-print}[@code{=}@var{file}]
+@cindex @option{-o} option
+@cindex @option{--pretty-print} option
+Enable pretty-printing of @command{awk} programs.
+By default, the output program is created in a file named @file{awkprof.out}
+(@pxref{Profiling}).
+The optional @var{file} argument allows you to specify a different
+@value{FN} for the output.
+No space is allowed between the @option{-o} and @var{file}, if
+@var{file} is supplied.
+
+@quotation NOTE
+In the past, this option would also execute your program.
+This is no longer the case.
+@end quotation
+
+@item @option{-O}
+@itemx @option{--optimize}
+@cindex @option{--optimize} option
+@cindex @option{-O} option
Enable some optimizations on the internal representation of the program.
-At the moment this includes just simple constant folding. The @command{gawk}
-maintainer hopes to add more optimizations over time.
-
-@item -p@r{[}@var{file}@r{]}
-@itemx --profile@r{[}=@var{file}@r{]}
-@cindex @code{-p} option
-@cindex @code{--profile} option
-@cindex @command{awk} programs, profiling, enabling
+At the moment, this includes just simple constant folding.
+
+@item @option{-p}[@var{file}]
+@itemx @option{--profile}[@code{=}@var{file}]
+@cindex @option{-p} option
+@cindex @option{--profile} option
+@cindex @command{awk} profiling, enabling
Enable profiling of @command{awk} programs
(@pxref{Profiling}).
By default, profiles are created in a file named @file{awkprof.out}.
@@ -3273,27 +4100,25 @@ The optional @var{file} argument allows you to specify a different
No space is allowed between the @option{-p} and @var{file}, if
@var{file} is supplied.
-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.
+The profile contains execution counts for each statement in the program
+in the left margin, and function call counts for each function.
-@item -P
-@itemx --posix
-@cindex @code{-P} option
-@cindex @code{--posix} option
+@item @option{-P}
+@itemx @option{--posix}
+@cindex @option{-P} option
+@cindex @option{--posix} option
@cindex POSIX mode
@cindex @command{gawk}, extensions@comma{} disabling
Operate in strict POSIX mode. This disables all @command{gawk}
extensions (just like @option{--traditional}) and
disables all extensions not allowed by POSIX.
-@xref{Common Extensions}, for a summary of the extensions
+@DBXREF{Common Extensions} for a summary of the extensions
in @command{gawk} that are disabled by this option.
Also,
the following additional
restrictions apply:
-@itemize @bullet
+@itemize @value{BULLET}
@cindex newlines
@cindex whitespace, newlines as
@@ -3309,7 +4134,7 @@ Newlines are not allowed after @samp{?} or @samp{:}
@cindex @code{FS} variable, as TAB character
@item
-Specifying @samp{-Ft} on the command-line does not set the value
+Specifying @samp{-Ft} on the command line does not set the value
of @code{FS} to be a single TAB character
(@pxref{Field Separators}).
@@ -3322,36 +4147,28 @@ data (@pxref{Locales}).
@c @cindex automatic warnings
@c @cindex warnings, automatic
-@cindex @code{--traditional} option, @code{--posix} option and
-@cindex @code{--posix} option, @code{--traditional} option and
+@cindex @option{--traditional} option, @code{--posix} option and
+@cindex @option{--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.
+issues a warning if both options are supplied.
-@item -r
-@itemx --re-interval
-@cindex @code{-r} option
-@cindex @code{--re-interval} option
+@item @option{-r}
+@itemx @option{--re-interval}
+@cindex @option{-r} option
+@cindex @option{--re-interval} option
@cindex regular expressions, interval expressions and
Allow interval expressions
(@pxref{Regexp Operators})
in regexps.
This is now @command{gawk}'s default behavior.
-Nevertheless, this option remains both for backward compatibility,
-and for use in combination with the @option{--traditional} option.
-
-@item -R @var{file}
-@itemx --command=@var{file}
-@cindex @code{-R} option
-@cindex @code{--command} option
-@command{dgawk} only.
-Read @command{dgawk} debugger options and commands from @var{file}.
-@xref{Dgawk Info}, for more information.
-
-@item -S
-@itemx --sandbox
-@cindex @code{-S} option
-@cindex @code{--sandbox} option
+Nevertheless, this option remains (both for backward compatibility
+and for use in combination with @option{--traditional}).
+
+@item @option{-S}
+@itemx @option{--sandbox}
+@cindex @option{-S} option
+@cindex @option{--sandbox} option
@cindex sandbox mode
Disable the @code{system()} function,
input redirections with @code{getline},
@@ -3359,20 +4176,20 @@ output redirections with @code{print} and @code{printf},
and dynamic extensions.
This is particularly useful when you want to run @command{awk} scripts
from questionable sources and need to make sure the scripts
-can't access your system (other than the specified input data file).
+can't access your system (other than the specified input @value{DF}).
-@item -t
-@itemx --lint-old
-@cindex @code{--L} option
-@cindex @code{--lint-old} option
+@item @option{-t}
+@itemx @option{--lint-old}
+@cindex @option{-L} option
+@cindex @option{--lint-old} option
Warn about constructs that are not available in the original version of
@command{awk} from Version 7 Unix
(@pxref{V7/SVR3.1}).
-@item -V
-@itemx --version
-@cindex @code{-V} option
-@cindex @code{--version} option
+@item @option{-V}
+@itemx @option{--version}
+@cindex @option{-V} option
+@cindex @option{--version} option
@cindex @command{gawk}, versions of, information about@comma{} printing
Print version information for this particular copy of @command{gawk}.
This allows you to determine if your copy of @command{gawk} is up to date
@@ -3386,43 +4203,44 @@ 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
+@cindex @option{-F} option, @option{-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
+@cindex @option{-f} option, multiple uses
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.
+of having to be included in each individual program.
+The @option{-i} option is similar in this regard.
(As mentioned in
@ref{Definition Syntax},
function names must be unique.)
With standard @command{awk}, library functions can still be used, even
-if the program is entered at the terminal,
+if the program is entered at the keyboard,
by specifying @samp{-f /dev/tty}. After typing your program,
-type @kbd{@value{CTL}-d} (the end-of-file character) to terminate it.
+type @kbd{Ctrl-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
+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}).
-The @option{--source} option may also be used multiple times on the command line.
-
-@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
+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{-e} option. This does not require you to
+preempt the standard input for your source code; it allows you to easily
+mix command-line and library source code (@pxref{AWKPATH Variable}).
+As with @option{-f}, the @option{-e} and @option{-i}
+options may also be used multiple times on the command line.
+
+@cindex @option{-e} option
+If no @option{-f} or @option{-e} option is specified, then @command{gawk}
+uses the first nonoption command-line argument as the text of the
program source code.
@cindex @env{POSIXLY_CORRECT} environment variable
@@ -3430,7 +4248,7 @@ program source code.
@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.
+you had supplied @option{--posix}.
Many GNU programs look for this environment variable to suppress
extensions that conflict with POSIX, but @command{gawk} behaves
differently: it suppresses all extensions, even those that do not
@@ -3461,8 +4279,6 @@ setenv POSIXLY_CORRECT true
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
@@ -3473,22 +4289,32 @@ 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.
-(See
-@ref{Assignment Options}.)
+file at all. (See @ref{Assignment Options}.) In the following example,
+@var{count=1} is a variable assignment, not a @value{FN}:
+
+@example
+awk -f program.awk file1 count=1 file2
+@end example
@cindex @command{gawk}, @code{ARGIND} variable in
@cindex @code{ARGIND} variable, command-line arguments
+@cindex @code{ARGV} array, indexing into
@cindex @code{ARGC}/@code{ARGV} variables, command-line arguments
-All these arguments are made available to your @command{awk} program in the
+All the command-line 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
+sets @code{ARGIND} to the index in @code{ARGV} of the
current element.
+@c FIXME: One day, move the ARGC and ARGV node closer to here.
+Changing @code{ARGC} and @code{ARGV} in your @command{awk} program lets
+you control how @command{awk} processes the input files; this is described
+in more detail in @ref{ARGC and ARGV}.
+
@cindex input files, variable assignments and
+@cindex variable assignments and input files
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
@@ -3507,7 +4333,7 @@ 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
+In some very early 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
@@ -3519,7 +4345,7 @@ 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
+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:
@@ -3561,11 +4387,12 @@ with @code{getline}.
Some other versions of @command{awk} also support this, but it
is not standard.
(Some operating systems provide a @file{/dev/stdin} file
-in the file system, however, @command{gawk} always processes
+in the filesystem; however, @command{gawk} always processes
this @value{FN} itself.)
@node Environment Variables
@section The Environment Variables @command{gawk} Uses
+@cindex environment variables used by @command{gawk}
A number of environment variables influence how @command{gawk}
behaves.
@@ -3573,104 +4400,153 @@ behaves.
@menu
* AWKPATH Variable:: Searching directories for @command{awk}
programs.
+* AWKLIBPATH Variable:: Searching directories for @command{awk} shared
+ libraries.
* Other Environment Variables:: The environment variables.
@end menu
@node AWKPATH Variable
@subsection The @env{AWKPATH} Environment Variable
@cindex @env{AWKPATH} environment variable
-@cindex directories, searching
-@cindex search paths
+@cindex directories, searching for source files
@cindex search paths, for source files
-@cindex differences in @command{awk} and @command{gawk}, @code{AWKPATH} environment variable
+@cindex differences in @command{awk} and @command{gawk}, @env{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.
+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
+implementations, you must supply a precise pathname 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
+But with @command{gawk}, if the @value{FN} supplied to the @option{-f}
+or @option{-i} options
+does not contain a directory separator @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
+separated by colons.@footnote{Semicolons on MS-Windows and MS-DOS.}
+@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.}
+or if it has an empty value,
+@command{gawk} uses a default path (described shortly).
-The search path feature is particularly useful for building libraries
+The search path feature is particularly helpful 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.
+the command line with a short @value{FN}. Otherwise, you would have to
+type the full @value{FN} for each file.
-By using both the @option{--source} and @option{-f} options, your command-line
+By using the @option{-i} or @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
-To include
-the current directory in the path, either place
-@file{.} explicitly in the path or write 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{::}).)
-This path search mechanism is similar
+If the source code file is not found after the initial search, the path is searched
+again after adding the suffix @samp{.awk} to the @value{FN}.
+
+@command{gawk}'s path search mechanism is similar
to the shell's.
-@c someday, @cite{The Bourne Again Shell}....
+(See @uref{http://www.gnu.org/software/bash/manual/,
+@cite{The Bourne-Again SHell manual}}.)
+It treats a null entry in the path as indicating the current
+directory.
+(A null entry is indicated by starting or ending the path with a
+colon or by placing two colons next to each other [@samp{::}].)
-However, @command{gawk} always looks in the current directory @emph{before}
-searching @env{AWKPATH}, so there is no real reason to include
-the current directory in the search path.
-@c Prior to 4.0, gawk searched the current directory after the
-@c path search, but it's not worth documenting it.
+@quotation NOTE
+To include the current directory in the path, either place @file{.}
+as an entry in the path or write a null entry in the path.
+
+Different past versions of @command{gawk} would also look explicitly in
+the current directory, either before or after the path search. As of
+@value{PVERSION} 4.1.2, this no longer happens; if you wish to look
+in the current directory, you must include @file{.} either as a separate
+entry or as a null entry in the search path.
@end quotation
-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.
+The default value for @env{AWKPATH} is
+@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 @code{$(datadir)} generated when
+@command{gawk} was configured. You probably don't need to worry about this,
+though.} Since @file{.} is included at the beginning, @command{gawk}
+searches first in the current directory and then in @file{/usr/local/share/awk}.
+In practice, this means that you will rarely need to change the
+value of @env{AWKPATH}.
+
+@xref{Shell Startup Files}, for information on functions that help to
+manipulate the @env{AWKPATH} variable.
-While you can change @code{ENVIRON["AWKPATH"]} within your @command{awk}
+@command{gawk} places the value of the search path that it used into
+@code{ENVIRON["AWKPATH"]}. This provides access to the actual search
+path value from within an @command{awk} program.
+
+Although 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 AWKLIBPATH Variable
+@subsection The @env{AWKLIBPATH} Environment Variable
+@cindex @env{AWKLIBPATH} environment variable
+@cindex directories, searching for loadable extensions
+@cindex search paths, for loadable extensions
+@cindex differences in @command{awk} and @command{gawk}, @code{AWKLIBPATH} environment variable
+
+The @env{AWKLIBPATH} environment variable is similar to the @env{AWKPATH}
+variable, but it is used to search for loadable extensions (stored as
+system shared libraries) specified with the @option{-l} option rather
+than for source files. If the extension is not found, the path is
+searched again after adding the appropriate shared library suffix for
+the platform. For example, on GNU/Linux systems, the suffix @samp{.so}
+is used. The search path specified is also used for extensions loaded
+via the @code{@@load} keyword (@pxref{Loading Shared Libraries}).
+
+If @env{AWKLIBPATH} does not exist in the environment, or if it has
+an empty value, @command{gawk} uses a default path; this
+is typically @samp{/usr/local/lib/gawk}, although it can vary depending
+upon how @command{gawk} was built.
+
+@xref{Shell Startup Files}, for information on functions that help to
+manipulate the @env{AWKLIBPATH} variable.
+
+@command{gawk} places the value of the search path that it used into
+@code{ENVIRON["AWKLIBPATH"]}. This provides access to the actual search
+path value from within an @command{awk} program.
+
@node Other Environment Variables
@subsection Other Environment Variables
A number of other environment variables affect @command{gawk}'s
behavior, but they are more specialized. Those in the following
-list are meant to be used by regular users.
+list are meant to be used by regular users:
@table @env
-@item POSIXLY_CORRECT
-Causes @command{gawk} to switch POSIX compatibility
-mode, disabling all traditional and GNU extensions.
-@xref{Options}.
-
-@item GAWK_SOCK_RETRIES
-Controls the number of time @command{gawk} will attempt to
-retry a two-way TCP/IP (socket) connection before giving up.
-@xref{TCP/IP Networking}.
-
@item GAWK_MSEC_SLEEP
Specifies the interval between connection retries,
in milliseconds. On systems that do not support
the @code{usleep()} system call,
the value is rounded up to an integral number of seconds.
+
+@item GAWK_READ_TIMEOUT
+Specifies the time, in milliseconds, for @command{gawk} to
+wait for input before returning with an error.
+@xref{Read Timeout}.
+
+@item GAWK_SOCK_RETRIES
+Controls the number of times @command{gawk} attempts to
+retry a two-way TCP/IP (socket) connection before giving up.
+@xref{TCP/IP Networking}.
+
+@item POSIXLY_CORRECT
+Causes @command{gawk} to switch to POSIX-compatibility
+mode, disabling all traditional and GNU extensions.
+@xref{Options}.
@end table
The environment variables in the following list are meant
@@ -3678,13 +4554,18 @@ for use by the @command{gawk} developers for testing and tuning.
They are subject to change. The variables are:
@table @env
-@item AVG_CHAIN_MAX
-The average number of items @command{gawk} will maintain on a
-hash chain for managing arrays.
+@item AWKBUFSIZE
+This variable only affects @command{gawk} on POSIX-compliant systems.
+With a value of @samp{exact}, @command{gawk} uses the size of each input
+file as the size of the memory buffer to allocate for I/O. Otherwise,
+the value should be a number, and @command{gawk} uses that number as
+the size of the buffer to allocate. (When this variable is not set,
+@command{gawk} uses the smaller of the file's size and the ``default''
+blocksize, which is usually the filesystem's I/O blocksize.)
@item AWK_HASH
If this variable exists with a value of @samp{gst}, @command{gawk}
-will switch to using the hash function from GNU Smalltalk for
+switches to using the hash function from GNU Smalltalk for
managing arrays.
This function may be marginally faster than the standard function.
@@ -3694,6 +4575,14 @@ files one line at a time, instead of reading in blocks. This exists
for debugging problems on filesystems on non-POSIX operating systems
where I/O is performed in records, not in blocks.
+@item GAWK_MSG_SRC
+If this variable exists, @command{gawk} includes the @value{FN}
+and line number within the @command{gawk} source code
+from which warning and/or fatal messages
+are generated. Its purpose is to help isolate the source of a
+message, as there are multiple places that produce the
+same warning or error message.
+
@item GAWK_NO_DFA
If this variable exists, @command{gawk} does not use the DFA regexp matcher
for ``does it match'' kinds of tests. This can cause @command{gawk}
@@ -3706,9 +4595,17 @@ coordinate with each other.)
This specifies the amount by which @command{gawk} should grow its
internal evaluation stack, when needed.
+@item INT_CHAIN_MAX
+This specifies intended maximum number of items @command{gawk} will maintain on a
+hash chain for managing arrays indexed by integers.
+
+@item STR_CHAIN_MAX
+This specifies intended maximum number of items @command{gawk} will maintain on a
+hash chain for managing arrays indexed by strings.
+
@item TIDYMEM
If this variable exists, @command{gawk} uses the @code{mtrace()} library
-calls from GNU LIBC to help track down possible memory leaks.
+calls from the GNU C library to help track down possible memory leaks.
@end table
@node Exit Status
@@ -3727,25 +4624,29 @@ If an error occurs, @command{gawk} exits with the value of
the C constant @code{EXIT_FAILURE}. This is usually one.
If @command{gawk} exits because of a fatal error, the exit
-status is 2. On non-POSIX systems, this value may be mapped
+status is two. On non-POSIX systems, this value may be mapped
to @code{EXIT_FAILURE}.
@node Include Files
-@section Including Other Files Into Your Program
+@section Including Other Files into Your Program
@c Panos Papadopoulos <panos1962@gmail.com> contributed the original
@c text for this section.
This @value{SECTION} describes a feature that is specific to @command{gawk}.
-The @samp{@@include} keyword can be used to read external @command{awk} source
+@cindex @code{@@include} directive
+@cindex file inclusion, @code{@@include} directive
+@cindex including files, @code{@@include} directive
+The @code{@@include} keyword can be used to read external @command{awk} source
files. This gives you the ability to split large @command{awk} source files
into smaller, more manageable pieces, and also lets you reuse common @command{awk}
code from various @command{awk} scripts. In other words, you can group
-together @command{awk} functions, used to carry out specific tasks,
+together @command{awk} functions used to carry out specific tasks
into external files. These files can be used just like function libraries,
-using the @samp{@@include} keyword in conjunction with the @code{AWKPATH}
-environment variable.
+using the @code{@@include} keyword in conjunction with the @env{AWKPATH}
+environment variable. Note that source files may also be included
+using the @option{-i} option.
Let's see an example.
We'll start with two (trivial) @command{awk} scripts, namely
@@ -3772,19 +4673,19 @@ produces the following result:
@example
$ @kbd{gawk -f test2}
-@print{} This is file test1.
-@print{} This is file test2.
+@print{} This is script test1.
+@print{} This is script test2.
@end example
-@code{gawk} runs the @file{test2} script which includes @file{test1}
-using the @samp{@@include}
-keyword. So, to include external @command{awk} source files you just
-use @samp{@@include} followed by the name of the file to be included,
+@code{gawk} runs the @file{test2} script, which includes @file{test1}
+using the @code{@@include}
+keyword. So, to include external @command{awk} source files, you just
+use @code{@@include} followed by the name of the file to be included,
enclosed in double quotes.
@quotation NOTE
Keep in mind that this is a language construct and the @value{FN} cannot
-be a string variable, but rather just a literal string in double quotes.
+be a string variable, but rather just a literal string constant in double quotes.
@end quotation
The files to be included may be nested; e.g., given a third
@@ -3803,9 +4704,9 @@ following results:
@example
$ @kbd{gawk -f test3}
-@print{} This is file test1.
-@print{} This is file test2.
-@print{} This is file test3.
+@print{} This is script test1.
+@print{} This is script test2.
+@print{} This is script test3.
@end example
The @value{FN} can, of course, be a pathname. For example:
@@ -3815,57 +4716,99 @@ The @value{FN} can, of course, be a pathname. For example:
@end example
@noindent
-or:
+and:
@example
@@include "/usr/awklib/network"
@end example
@noindent
-are valid. The @code{AWKPATH} environment variable can be of great
-value when using @samp{@@include}. The same rules for the use
-of the @code{AWKPATH} variable in command-line file searches
+are both valid. The @env{AWKPATH} environment variable can be of great
+value when using @code{@@include}. The same rules for the use
+of the @env{AWKPATH} variable in command-line file searches
(@pxref{AWKPATH Variable}) apply to
-@samp{@@include} also.
+@code{@@include} also.
This is very helpful in constructing @command{gawk} function libraries.
-If you have a large script with useful, general purpose @command{awk}
+If you have a large script with useful, general-purpose @command{awk}
functions, you can break it down into library files and put those files
-in a special directory. You can then include those ``libraries,'' using
-either the full pathnames of the files, or by setting the @code{AWKPATH}
-environment variable accordingly and then using @samp{@@include} with
-just the file part of the full pathname. Of course you can have more
-than one directory to keep library files; the more complex the working
+in a special directory. You can then include those ``libraries,''
+either by using the full pathnames of the files, or by setting the @env{AWKPATH}
+environment variable accordingly and then using @code{@@include} with
+just the file part of the full pathname. Of course,
+you can keep library files in more than one directory;
+the more complex the working
environment is, the more directories you may need to organize the files
to be included.
Given the ability to specify multiple @option{-f} options, the
-@samp{@@include} mechanism is not strictly necessary.
-However, the @samp{@@include} keyword
+@code{@@include} mechanism is not strictly necessary.
+However, the @code{@@include} keyword
can help you in constructing self-contained @command{gawk} programs,
thus reducing the need for writing complex and tedious command lines.
-In particular, @samp{@@include} is very useful for writing CGI scripts
+In particular, @code{@@include} is very useful for writing CGI scripts
to be run from web pages.
As mentioned in @ref{AWKPATH Variable}, the current directory is always
-searched first for source files, before searching in @env{AWKPATH},
-and this also applies to files named with @samp{@@include}.
+searched first for source files, before searching in @env{AWKPATH};
+this also applies to files named with @code{@@include}.
+
+@node Loading Shared Libraries
+@section Loading Dynamic Extensions into Your Program
+
+This @value{SECTION} describes a feature that is specific to @command{gawk}.
+
+@cindex @code{@@load} directive
+@cindex loading extensions, @code{@@load} directive
+@cindex extensions, loading, @code{@@load} directive
+The @code{@@load} keyword can be used to read external @command{awk} extensions
+(stored as system shared libraries).
+This allows you to link in compiled code that may offer superior
+performance and/or give you access to extended capabilities not supported
+by the @command{awk} language. The @env{AWKLIBPATH} variable is used to
+search for the extension. Using @code{@@load} is completely equivalent
+to using the @option{-l} command-line option.
+
+If the extension is not initially found in @env{AWKLIBPATH}, another
+search is conducted after appending the platform's default shared library
+suffix to the @value{FN}. For example, on GNU/Linux systems, the suffix
+@samp{.so} is used:
+
+@example
+$ @kbd{gawk '@@load "ordchr"; BEGIN @{print chr(65)@}'}
+@print{} A
+@end example
+
+@noindent
+This is equivalent to the following example:
+
+@example
+$ @kbd{gawk -lordchr 'BEGIN @{print chr(65)@}'}
+@print{} A
+@end example
+
+@noindent
+For command-line usage, the @option{-l} option is more convenient,
+but @code{@@load} is useful for embedding inside an @command{awk} source file
+that requires access to an extension.
+
+@ref{Dynamic Extensions}, describes how to write extensions (in C or C++)
+that can be loaded with either @code{@@load} or the @option{-l} option.
+It also describes the @code{ordchr} extension.
@node Obsolete
@section Obsolete Options and/or Features
-@cindex features, advanced, See advanced features
+@c update this section for each release!
+
@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
+previous releases of @command{gawk} that either are not available in the
+current version or 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{PROCINFO} array
The process-related special files @file{/dev/pid}, @file{/dev/ppid},
@file{/dev/pgrpid}, and @file{/dev/user} were deprecated in @command{gawk}
3.1, but still worked. As of @value{PVERSION} 4.0, they are no longer
@@ -3887,10 +4830,11 @@ in case some option becomes obsolete in a future version of @command{gawk}.
@cindex Jedi knights
@cindex Knights, jedi
@quotation
-@i{Use the Source, Luke!}@*
-Obi-Wan
+@i{Use the Source, Luke!}
+@author Obi-Wan
@end quotation
+@cindex shells, sea
This @value{SECTION} intentionally left
blank.
@@ -3903,7 +4847,7 @@ blank.
@table @code
@item -W nostalgia
@itemx --nostalgia
-Print the message @code{"awk: bailing out near line 1"} and dump core.
+Print the message @samp{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.
@@ -3919,15 +4863,15 @@ 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
+because it is bad style. The correct way to write such a program
+is either:
@example
awk '@{ sum += $1 @} ; END @{ print sum @}'
@end example
@noindent
-or
+or:
@example
awk '@{ sum += $1 @}
@@ -3935,8 +4879,7 @@ awk '@{ sum += $1 @}
@end example
@noindent
-@xref{Statements/Lines}, for a fuller
-explanation.
+@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}.
@@ -3947,35 +4890,62 @@ long-undocumented ``feature'' of Unix @code{awk}.
@end ignore
-@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:
+@node Invoking Summary
+@section Summary
-@itemize @bullet
+@itemize @value{BULLET}
@item
-@ref{Library Functions}.
+Use either
+@samp{awk '@var{program}' @var{files}}
+or
+@samp{awk -f @var{program-file} @var{files}}
+to run @command{awk}.
@item
-@ref{Sample Programs}.
+The three standard options for all versions of @command{awk} are
+@option{-f}, @option{-F}, and @option{-v}. @command{gawk} supplies these
+and many others, as well as corresponding GNU-style long options.
-@end itemize
+@item
+Nonoption command-line arguments are usually treated as @value{FN}s,
+unless they have the form @samp{@var{var}=@var{value}}, in which case
+they are taken as variable assignments to be performed at that point
+in processing the input.
-@page
-@evenheading @thispage@ @ @ @strong{@value{TITLE}} @| @|
-@oddheading @| @| @strong{@thischapter}@ @ @ @thispage
-@end iftex
-@end ignore
+@item
+All nonoption command-line arguments, excluding the program text,
+are placed in the @code{ARGV} array. Adjusting @code{ARGC} and @code{ARGV}
+affects how @command{awk} processes input.
+
+@item
+You can use a single minus sign (@samp{-}) to refer to standard input
+on the command line. @command{gawk} also lets you use the special
+@value{FN} @file{/dev/stdin}.
+
+@item
+@command{gawk} pays attention to a number of environment variables.
+@env{AWKPATH}, @env{AWKLIBPATH}, and @env{POSIXLY_CORRECT} are the
+most important ones.
+
+@item
+@command{gawk}'s exit status conveys information to the program
+that invoked it. Use the @code{exit} statement from within
+an @command{awk} program to set the exit status.
+
+@item
+@command{gawk} allows you to include other @command{awk} source files into
+your program using the @code{@@include} statement and/or the @option{-i}
+and @option{-f} command-line options.
+
+@item
+@command{gawk} allows you to load additional functions written in C
+or C++ using the @code{@@load} statement and/or the @option{-l} option.
+(This advanced feature is described later, in @ref{Dynamic Extensions}.)
+@end itemize
@node Regexp
@chapter Regular Expressions
-@cindex regexp, See regular expressions
-@c STARTOFRANGE regexp
+@cindex regexp
@cindex regular expressions
A @dfn{regular expression}, or @dfn{regexp}, is a way of describing a
@@ -3983,16 +4953,16 @@ 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)
+@cindex forward slash (@code{/}) to enclose regular expressions
+@cindex @code{/} (forward slash) to enclose regular expressions
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
+Thus, the pattern @code{/foo/} matches any input record containing
+the three adjacent characters @samp{foo} @emph{anywhere} in the record. Other
kinds of regexps let you specify more complicated classes of strings.
@ifnotinfo
@@ -4006,10 +4976,11 @@ regular expressions work, we present more complicated instances.
* Escape Sequences:: How to write nonprinting characters.
* Regexp Operators:: Regular Expression Operators.
* Bracket Expressions:: 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.
+* GNU Regexp Operators:: Operators specific to GNU software.
+* Case-sensitivity:: How to do case-insensitive matching.
+* Regexp Summary:: Regular expressions summary.
@end menu
@node Regexp Usage
@@ -4020,15 +4991,15 @@ 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:
+following prints the second field of each record where the string
+@samp{li} appears anywhere in the record:
@example
-$ @kbd{awk '/foo/ @{ print $2 @}' BBS-list}
-@print{} 555-1234
+$ @kbd{awk '/li/ @{ print $2 @}' mail-list}
+@print{} 555-5553
+@print{} 555-0542
@print{} 555-6699
-@print{} 555-6480
-@print{} 555-2127
+@print{} 555-3430
@end example
@cindex regular expressions, operators
@@ -4040,9 +5011,9 @@ $ @kbd{awk '/foo/ @{ print $2 @}' BBS-list}
@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
+@cindex @code{if} statement, use of regexps in
+@cindex @code{while} statement, use of regexps in
+@cindex @code{do}-@code{while} statement, use of regexps in
@c @cindex statements, @code{if}
@c @cindex statements, @code{while}
@c @cindex statements, @code{do}
@@ -4053,17 +5024,16 @@ 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:
+For example, the following is true if the expression @var{exp} (taken
+as a string) matches @var{regexp}:
@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:
+This example matches, or selects, all input records with the uppercase
+letter @samp{J} somewhere in the first field:
@example
$ @kbd{awk '$1 ~ /J/' inventory-shipped}
@@ -4101,6 +5071,7 @@ $ @kbd{awk '$1 !~ /J/' inventory-shipped}
@end example
@cindex regexp constants
+@cindex constant regexps
@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
@@ -4109,7 +5080,7 @@ a @dfn{regexp constant}, much like @code{5.27} is a numeric constant and
@node Escape Sequences
@section Escape Sequences
-@cindex escape sequences
+@cindex escape sequences, in strings
@cindex backslash (@code{\}), in escape sequences
@cindex @code{\} (backslash), in escape sequences
Some characters cannot be included literally in string constants
@@ -4132,11 +5103,11 @@ string or regexp. Thus, the string whose contents are the two characters
@samp{"} and @samp{\} must be written @code{"\"\\"}.
Other escape sequences represent unprintable characters
-such as TAB or newline. While there is nothing to stop you from entering most
+such as TAB or newline. There is nothing to stop you from entering most
unprintable characters directly in a string constant or regexp constant,
-they may look ugly.
+but they may look ugly.
-The following table lists
+The following list presents
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:
@@ -4149,39 +5120,39 @@ A literal backslash, @samp{\}.
@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.)
+The ``alert'' character, @kbd{Ctrl-g}, ASCII code 7 (BEL).
+(This often 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).
+Backspace, @kbd{Ctrl-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).
+Formfeed, @kbd{Ctrl-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).
+Newline, @kbd{Ctrl-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).
+Carriage return, @kbd{Ctrl-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).
+Horizontal TAB, @kbd{Ctrl-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).
+Vertical TAB, @kbd{Ctrl-k}, ASCII code 11 (VT).
@cindex @code{\} (backslash), @code{\}@var{nnn} escape sequence
@cindex backslash (@code{\}), @code{\}@var{nnn} escape sequence
@@ -4199,20 +5170,34 @@ between @samp{0} and @samp{7}. For example, the code for the ASCII ESC
@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. @value{COMMONEXT}
-However, using more than two hexadecimal digits produces
-undefined results. (The @samp{\x} escape sequence is not allowed in
-POSIX @command{awk}.)
+or @samp{a}--@samp{f}). A maximum of two digts are allowed after
+the @samp{\x}. Any further hexadecimal digits are treated as simple
+letters or numbers. @value{COMMONEXT}
+(The @samp{\x} escape sequence is not allowed in POSIX awk.)
+
+@quotation CAUTION
+In ISO C, the escape sequence continues until the first nonhexadecimal
+digit is seen.
+@c FIXME: Add exact version here.
+For many years, @command{gawk} would continue incorporating
+hexadecimal digits into the value until a non-hexadecimal digit
+or the end of the string was encountered.
+However, using more than two hexadecimal digits produced
+undefined results.
+As of @value{PVERSION} @strong{FIXME:} 4.3.0, only two digits
+are processed.
+@end quotation
@cindex @code{\} (backslash), @code{\/} escape sequence
@cindex backslash (@code{\}), @code{\/} escape sequence
@item \/
A literal slash (necessary for regexp constants only).
This sequence 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,
+constant that contains a slash
+(such as @code{/.*:\/home\/[[:alnum:]]+:.*/}; the @samp{[[:alnum:]]}
+notation is discussed in @ref{Bracket Expressions}).
+Because the regexp is delimited by
+slashes, you need to escape any 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
@@ -4220,8 +5205,10 @@ in order to tell @command{awk} to keep processing the rest of the regexp.
@item \"
A literal double quote (necessary for string constants only).
This sequence 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,
+constant that contains a double quote
+(such as @code{"He said \"hi!\" to her."}).
+Because the string is delimited by
+double quotes, you need to escape any quote that is part of the string,
in order to tell @command{awk} to keep processing the rest of the string.
@end table
@@ -4231,7 +5218,7 @@ with a backslash have special meaning in regexps.
In a regexp, a backslash before any character that is not in the previous list
and not listed in
-@ref{GNU Regexp Operators},
+@DBREF{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}.
@@ -4240,29 +5227,58 @@ characters @samp{a+b}.
@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.
+shown in the previous list or that is not an operator.
-To summarize:
+@c 11/2014: Moved so as to not stack sidebars
+@cindex sidebar, Backslash Before Regular Characters
+@ifdocbook
+@docbook
+<sidebar><title>Backslash Before Regular Characters</title>
+@end docbook
-@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.
+@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
-@item
-@command{gawk} processes both regexp constants and dynamic regexps
-(@pxref{Computed Regexps}),
-for the special operators listed in
-@ref{GNU Regexp Operators}.
+@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
+@cindex Brian Kernighan's @command{awk}
+@table @asis
+@item Strip the backslash out
+This is what BWK @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
+@cindex @command{mawk} utility
+@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
+
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{Backslash Before Regular Characters}
-@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
@@ -4275,9 +5291,10 @@ leaves what happens as undefined. There are two choices:
@c @cindex automatic warnings
@c @cindex warnings, automatic
+@cindex Brian Kernighan's @command{awk}
@table @asis
@item Strip the backslash out
-This is what Brian Kernighan's @command{awk} and @command{gawk} both do.
+This is what BWK @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.)
@@ -4288,14 +5305,68 @@ two backslashes in the string: @samp{FS = @w{"[ \t]+\\|[ \t]+"}}.)
@cindex @command{gawk}, escape sequences
@cindex Unix @command{awk}, backslashes in escape sequences
+@cindex @command{mawk} utility
@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
+@end cartouche
+@end ifnotdocbook
+
+To summarize:
+
+@itemize @value{BULLET}
+@item
+The escape sequences in the preceding list 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
+
+@cindex sidebar, Escape Sequences for Metacharacters
+@ifdocbook
+@docbook
+<sidebar><title>Escape Sequences for Metacharacters</title>
+@end docbook
+
+@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/}.
+
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{Escape Sequences for Metacharacters}
+
-@c fakenode --- for prepinfo
-@subheading Advanced Notes: Escape Sequences for Metacharacters
@cindex metacharacters, escape sequences for
Suppose you use an octal or hexadecimal
@@ -4313,11 +5384,13 @@ 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/}.
+@end cartouche
+@end ifnotdocbook
@node Regexp Operators
@section Regular Expression Operators
-@c STARTOFRANGE regexpo
@cindex regular expressions, operators
+@cindex metacharacters in regular expressions
You can combine regular expressions with special characters,
called @dfn{regular expression operators} or @dfn{metacharacters}, to
@@ -4327,57 +5400,61 @@ The escape sequences described
@ifnotinfo
earlier
@end ifnotinfo
-in @ref{Escape Sequences},
+in @DBREF{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:
+sequences and that are not listed here stand for themselves:
-@table @code
-@cindex backslash (@code{\})
-@cindex @code{\} (backslash)
-@item \
-This is used to suppress the special meaning of a character when
+@c Use @asis so the docbook comes out ok. Sigh.
+@table @asis
+@cindex backslash (@code{\}), regexp operator
+@cindex @code{\} (backslash), regexp operator
+@item @code{\}
+This suppresses 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
+@cindex @code{^} (caret), regexp operator
+@cindex caret (@code{^}), regexp operator
+@item @code{^}
+This matches the beginning of a string. @samp{^@@chapter}
+matches @samp{@@chapter} at the beginning of a string,
+for example, 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.
+a line (the point right after a @samp{\n} newline character) 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 $
+@cindex @code{$} (dollar sign), regexp operator
+@cindex dollar sign (@code{$}), regexp operator
+@item @code{$}
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.
+and does not match the end of a line
+(the point right before a @samp{\n} newline character)
+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 . @r{(period)}
+@cindex @code{.} (period), regexp operator
+@cindex period (@code{.}), regexp operator
+@item @code{.} (period)
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
@@ -4392,12 +5469,13 @@ 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 @code{[]} (square brackets), regexp operator
+@cindex square brackets (@code{[]}), regexp operator
@cindex bracket expressions
@cindex character sets, See Also bracket expressions
@cindex character lists, See bracket expressions
-@item [@dots{}]
+@cindex character classes, See bracket expressions
+@item @code{[}@dots{}@code{]}
This is called a @dfn{bracket expression}.@footnote{In other literature,
you may see a bracket expression referred to as either a
@dfn{character set}, a @dfn{character class}, or a @dfn{character list}.}
@@ -4409,7 +5487,7 @@ is given in
@ref{Bracket Expressions}.
@cindex bracket expressions, complemented
-@item [^ @dots{}]
+@item @code{[^}@dots{}@code{]}
This is a @dfn{complemented bracket expression}. 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]}
@@ -4418,20 +5496,19 @@ or @samp{k}.
@cindex @code{|} (vertical bar)
@cindex vertical bar (@code{|})
-@item |
+@item @code{|}
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.
+alternatives. The @samp{|} has the lowest precedence of all the regular
+expression operators. For example, @samp{^P|[aeiouy]} matches any string
+that matches either @samp{^P} or @samp{[aeiouy]}. This means it matches
+any string that starts with @samp{P} or contains (anywhere within it)
+a lowercase English vowel.
The alternation applies to the largest possible regexps on either side.
-@cindex @code{()} (parentheses)
-@cindex parentheses @code{()}
-@item (@dots{})
+@cindex @code{()} (parentheses), regexp operator
+@cindex parentheses @code{()}, regexp operator
+@item @code{(}@dots{}@code{)}
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,
@@ -4442,47 +5519,42 @@ explained further on in this list.)
@cindex @code{*} (asterisk), @code{*} operator, as regexp operator
@cindex asterisk (@code{*}), @code{*} operator, as regexp operator
-@item *
+@item @code{*}
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 +
+There are two subtle points to understand about how @samp{*} works.
+First, the @samp{*} applies only to the single preceding regular expression
+component (e.g., in @samp{ph*}, it applies just to the @samp{h}).
+To cause @samp{*} to apply to a larger subexpression, use parentheses:
+@samp{(ph)*} matches @samp{ph}, @samp{phph}, @samp{phphph}, and so on.
+
+Second, @samp{*} finds as many repetitions as possible. If the text
+to be matched is @samp{phhhhhhhhhhhhhhooey}, @samp{ph*} matches all of
+the @samp{h}s.
+
+@cindex @code{+} (plus sign), regexp operator
+@cindex plus sign (@code{+}), regexp operator
+@item @code{+}
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:
+@samp{wh*y} would match all three.
-@example
-awk '/\(c[ad]+r x\)/ @{ print @}' sample
-@end example
-
-@cindex @code{?} (question mark) regexp operator
-@cindex question mark (@code{?}) regexp operator
-@item ?
+@cindex @code{?} (question mark), regexp operator
+@cindex question mark (@code{?}), regexp operator
+@item @code{?}
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}@}
+@cindex interval expressions, regexp operator
+@item @code{@{}@var{n}@code{@}}
+@itemx @code{@{}@var{n}@code{,@}}
+@itemx @code{@{}@var{n}@code{,}@var{m}@code{@}}
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.
@@ -4496,10 +5568,10 @@ is repeated at least @var{n} times:
Matches @samp{whhhy}, but not @samp{why} or @samp{whhhhy}.
@item wh@{3,5@}y
-Matches @samp{whhhy}, @samp{whhhhy}, or @samp{whhhhhy}, only.
+Matches @samp{whhhy}, @samp{whhhhy}, or @samp{whhhhhy} only.
@item wh@{2,@}y
-Matches @samp{whhy} or @samp{whhhy}, and so on.
+Matches @samp{whhy}, @samp{whhhy}, and so on.
@end table
@cindex POSIX @command{awk}, interval expressions in
@@ -4524,6 +5596,10 @@ 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.}
+
+Finally, when @samp{@{} and @samp{@}} appear in regexp constants
+in a way that cannot be interpreted as an interval expression
+(such as @code{/q@{a@}/}), then they stand for themselves.
@end table
@cindex precedence, regexp operators
@@ -4544,23 +5620,22 @@ usage as a syntax error.
If @command{gawk} is in compatibility mode (@pxref{Options}), interval
expressions are not available in regular expressions.
-@c ENDOFRANGE regexpo
@node Bracket Expressions
@section Using Bracket Expressions
-@c STARTOFRANGE charlist
@cindex bracket expressions
@cindex bracket expressions, range expressions
@cindex range expressions (regexps)
+@cindex character lists in regular expression
-As mentioned earlier, a bracket expression matches any character amongst
+As mentioned earlier, a bracket expression matches any character among
those listed between the opening and closing square brackets.
Within a bracket expression, a @dfn{range expression} consists of two
characters separated by a hyphen. It matches any single character that
sorts between the two characters, based upon the system's native character
set. For example, @samp{[0-9]} is equivalent to @samp{[0123456789]}.
-(See @ref{Ranges and Locales}, for an explanation of how the POSIX
+(See @DBREF{Ranges and Locales} for an explanation of how the POSIX
standard and @command{gawk} have changed over time. This is mainly
of historical interest.)
@@ -4579,12 +5654,15 @@ bracket expression, put a @samp{\} in front of it. For example:
@noindent
matches either @samp{d} or @samp{]}.
+Additionally, if you place @samp{]} right after the opening
+@samp{[}, the closing bracket is treated as one of the
+characters to be matched.
@cindex POSIX @command{awk}, bracket expressions and
@cindex Extended Regular Expressions (EREs)
@cindex EREs (Extended Regular Expressions)
@cindex @command{egrep} utility
-This treatment of @samp{\} in bracket expressions
+The treatment of @samp{\} in bracket expressions
is compatible with other @command{awk}
implementations and is also mandated by POSIX.
The regular expressions in @command{awk} are a superset
@@ -4608,23 +5686,23 @@ a keyword denoting the class, and @samp{:]}.
POSIX standard.
@float Table,table-char-classes
-@caption{POSIX Character 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{[: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.
+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
@@ -4636,6 +5714,17 @@ With the POSIX character classes, you can write
@code{/[[:alnum:]]/} to match the alphabetic
and numeric characters in your character set.
+@c Thanks to
+@c Date: Tue, 01 Jul 2014 07:39:51 +0200
+@c From: Hermann Peifer <peifer@gmx.eu>
+Some utilities that match regular expressions provide a nonstandard
+@code{[:ascii:]} character class; @command{awk} does not. However, you
+can simulate such a construct using @code{[\x00-\x7F]}. This matches
+all values numerically between zero and 127, which is the defined
+range of the ASCII character set. Use a complemented character list
+(@code{[^\x00-\x7F]}) to match any single-byte characters that are not
+in the ASCII range.
+
@cindex bracket expressions, collating elements
@cindex bracket expressions, non-ASCII
@cindex collating elements
@@ -4653,8 +5742,8 @@ These sequences are:
@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}.
+then @samp{[[.ch.]]} is a regexp that matches this collating element, whereas
+@samp{[ch]} is a regexp that matches either @samp{c} or @samp{h}.
@cindex bracket expressions, equivalence classes
@item Equivalence classes
@@ -4662,7 +5751,7 @@ 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
+``e,'' ``@`e,'' and ``@'e.'' In this case, @samp{[[=e=]]} is a regexp
that matches any of @samp{e}, @samp{@'e}, or @samp{@`e}.
@end table
@@ -4677,16 +5766,207 @@ expression matching currently recognize only POSIX character classes;
they do not recognize collating symbols or equivalence classes.
@end quotation
@c maybe one day ...
-@c ENDOFRANGE charlist
+
+@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 to make a change to the input
+record. (@code{sub()} replaces the first instance of any text matched
+by the first argument with the string provided as the second argument;
+@pxref{String Functions}). 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
+$ @kbd{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
+
+@cindex regular expressions, computed
+@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 then used as the
+regexp. A regexp computed in this way is called a @dfn{dynamic
+regexp} or a @dfn{computed 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.
+
+@quotation NOTE
+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.
+@end quotation
+
+@cindex regexp constants, slashes vs.@: quotes
+@cindex @code{\} (backslash), in regexp constants
+@cindex backslash (@code{\}), in regexp constants
+@cindex @code{"} (double quote), in regexp constants
+@cindex double quote (@code{"}), in 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 @value{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
+
+@cindex sidebar, Using @code{\n} in Bracket Expressions of Dynamic Regexps
+@ifdocbook
+@docbook
+<sidebar><title>Using @code{\n} in Bracket Expressions of Dynamic Regexps</title>
+@end docbook
+
+@cindex regular expressions, dynamic, with embedded newlines
+@cindex newlines, in dynamic regexps
+
+Some older versions of @command{awk} do not allow the newline
+character to be used inside a bracket expression for a dynamic regexp:
+
+@example
+$ @kbd{awk '$0 ~ "[ \t\n]"'}
+@error{} awk: newline in character class [
+@error{} ]...
+@error{} source line number 1
+@error{} context is
+@error{} $0 ~ "[ >>> \t\n]" <<<
+@end example
+
+@cindex newlines, in regexp constants
+But a newline in a regexp constant works with no problem:
+
+@example
+$ @kbd{awk '$0 ~ /[ \t\n]/'}
+@kbd{here is a sample line}
+@print{} here is a sample line
+@kbd{Ctrl-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.
+
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{Using @code{\n} in Bracket Expressions of Dynamic Regexps}
+
+
+@cindex regular expressions, dynamic, with embedded newlines
+@cindex newlines, in dynamic regexps
+
+Some older versions of @command{awk} do not allow the newline
+character to be used inside a bracket expression for a dynamic regexp:
+
+@example
+$ @kbd{awk '$0 ~ "[ \t\n]"'}
+@error{} awk: newline in character class [
+@error{} ]...
+@error{} source line number 1
+@error{} context is
+@error{} $0 ~ "[ >>> \t\n]" <<<
+@end example
+
+@cindex newlines, in regexp constants
+But a newline in a regexp constant works with no problem:
+
+@example
+$ @kbd{awk '$0 ~ /[ \t\n]/'}
+@kbd{here is a sample line}
+@print{} here is a sample line
+@kbd{Ctrl-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.
+@end cartouche
+@end ifnotdocbook
@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
@@ -4706,7 +5986,7 @@ or underscores (@samp{_}):
@item \s
Matches any whitespace character.
Think of it as shorthand for
-@w{@code{[[:space:]]}}.
+@w{@samp{[[:space:]]}}.
@c @cindex operators, @code{\S} (@command{gawk})
@cindex backslash (@code{\}), @code{\S} operator (@command{gawk})
@@ -4714,7 +5994,7 @@ Think of it as shorthand for
@item \S
Matches any character that is not whitespace.
Think of it as shorthand for
-@w{@code{[^[:space:]]}}.
+@w{@samp{[^[:space:]]}}.
@c @cindex operators, @code{\w} (@command{gawk})
@cindex backslash (@code{\}), @code{\w} operator (@command{gawk})
@@ -4722,7 +6002,7 @@ Think of it as shorthand for
@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:]_]}}.
+@w{@samp{[[:alnum:]_]}}.
@c @cindex operators, @code{\W} (@command{gawk})
@cindex backslash (@code{\}), @code{\W} operator (@command{gawk})
@@ -4730,7 +6010,7 @@ letter, digit, or underscore. Think of it as shorthand for
@item \W
Matches any character that is not word-constituent.
Think of it as shorthand for
-@w{@code{[^[:alnum:]_]}}.
+@w{@samp{[^[:alnum:]_]}}.
@c @cindex operators, @code{\<} (@command{gawk})
@cindex backslash (@code{\}), @code{\<} operator (@command{gawk})
@@ -4770,9 +6050,9 @@ word-constituent characters. For example,
@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.
+@dfn{buffer} is, naturally, an Emacs buffer.
+Other GNU programs, including @command{gawk},
+consider the entire string to match as the buffer.
The operators are:
@table @code
@@ -4791,10 +6071,10 @@ Matches the empty string at the
end of a buffer (string).
@end table
-@cindex @code{^} (caret)
-@cindex caret (@code{^})
-@cindex @code{?} (question mark) regexp operator
-@cindex question mark (@code{?}) regexp operator
+@cindex @code{^} (caret), regexp operator
+@cindex caret (@code{^}), regexp operator
+@cindex @code{?} (question mark), regexp operator
+@cindex question mark (@code{?}), regexp operator
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
@@ -4811,11 +6091,8 @@ 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
+@cindex @command{gawk}, command-line options, and regular expressions
The various command-line options
(@pxref{Options})
control how @command{gawk} interprets characters in regexps:
@@ -4829,20 +6106,23 @@ previously described
GNU regexp operators.
@end ifnotinfo
@ifnottex
+@ifnotdocbook
GNU regexp operators described
in @ref{Regexp Operators}.
+@end ifnotdocbook
@end ifnottex
@item @code{--posix}
-Only POSIX regexps are supported; the GNU operators are not special
+Match only POSIX regexps; the GNU operators are not special
(e.g., @samp{\w} matches a literal @samp{w}). Interval expressions
are allowed.
+@cindex Brian Kernighan's @command{awk}
@item @code{--traditional}
-Traditional Unix @command{awk} regexps are matched. The GNU operators
+Match traditional Unix @command{awk} regexps. The GNU operators
are not special, and interval expressions are not available.
-The POSIX character classes (@code{[[:alnum:]]}, etc.) are supported,
-as Brian Kernighan's @command{awk} does support them.
+Because BWK @command{awk} supports them,
+the POSIX character classes (@samp{[[:alnum:]]}, etc.) are available.
Characters described by octal and hexadecimal escape sequences are
treated literally, even if they represent regexp metacharacters.
@@ -4851,15 +6131,11 @@ Allow interval expressions in regexps, if @option{--traditional}
has been provided.
Otherwise, interval expressions are available by default.
@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 bracket
@@ -4893,16 +6169,18 @@ This works in any POSIX-compliant @command{awk}.
@cindex tilde (@code{~}), @code{~} operator
@cindex @code{!} (exclamation point), @code{!~} operator
@cindex exclamation point (@code{!}), @code{!~} operator
-@cindex @code{IGNORECASE} variable
+@cindex @code{IGNORECASE} variable, with @code{~} and @code{!~} operators
@cindex @command{gawk}, @code{IGNORECASE} variable in
@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:
+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"
@@ -4913,7 +6191,7 @@ 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
+case insensitive and other rules case sensitive, as 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
@@ -4924,16 +6202,13 @@ and
However, this is somewhat obscure and we don't recommend it.}
To do this, use either bracket expressions 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.
+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.
-
-Both regexp and string comparison
-operations are affected by @code{IGNORECASE}.
+a program case insensitive without having to edit it.
@c @cindex ISO 8859-1
@c @cindex ISO Latin-1
@@ -4952,168 +6227,57 @@ the right thing.}
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:
+@node Regexp Summary
+@section Summary
-@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
-$ @kbd{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 then used as the
-regexp. A regexp 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.
-
-@quotation NOTE
-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.
-@end quotation
-
-@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 @value{BULLET}
+@item
+Regular expressions describe sets of strings to be matched.
+In @command{awk}, regular expression constants are written enclosed
+between slashes: @code{/}@dots{}@code{/}.
-@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.
+Regexp constants may be used standalone in patterns and
+in conditional expressions, or as part of matching expressions
+using the @samp{~} and @samp{!~} operators.
@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.
+Escape sequences let you represent nonprintable characters and
+also let you represent regexp metacharacters as literal characters
+to be matched.
@item
-Using regexp constants is better form; it shows clearly that you
-intend a regexp match.
-@end itemize
+Regexp operators provide grouping, alternation, and repetition.
-@c fakenode --- for prepinfo
-@subheading Advanced Notes: Using @code{\n} in Bracket Expressions of Dynamic Regexps
-@cindex regular expressions, dynamic, with embedded newlines
-@cindex newlines, in dynamic regexps
+@item
+Bracket expressions give you a shorthand for specifying sets
+of characters that can match at a particular point in a regexp.
+Within bracket expressions, POSIX character classes let you specify
+certain groups of characters in a locale-independent fashion.
-Some commercial versions of @command{awk} do not allow the newline
-character to be used inside a bracket expression for a dynamic regexp:
+@item
+Regular expressions match the leftmost longest text in the string being
+matched. This matters for cases where you need to know the extent of
+the match, such as for text substitution and when the record separator
+is a regexp.
-@example
-$ @kbd{awk '$0 ~ "[ \t\n]"'}
-@error{} awk: newline in character class [
-@error{} ]...
-@error{} source line number 1
-@error{} context is
-@error{} >>> <<<
-@end example
+@item
+Matching expressions may use dynamic regexps (i.e., string values
+treated as regular expressions).
-@cindex newlines, in regexp constants
-But a newline in a regexp constant works with no problem:
+@item
+@command{gawk}'s @code{IGNORECASE} variable lets you control the
+case sensitivity of regexp matching. In other @command{awk}
+versions, use @code{tolower()} or @code{toupper()}.
-@example
-$ @kbd{awk '$0 ~ /[ \t\n]/'}
-@kbd{here is a sample line}
-@print{} here is a sample line
-@kbd{@value{CTL}-d}
-@end example
+@end itemize
-@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 Reading Files
@chapter Reading Input Files
-@c STARTOFRANGE infir
+@cindex reading input files
@cindex input files, reading
@cindex input files
@cindex @code{FILENAME} variable
@@ -5123,7 +6287,7 @@ standard input (by default, this is the keyboard, but often it is a pipe from an
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
+The name of the current input file can be found in the predefined variable
@code{FILENAME}
(@pxref{Built-in Variables}).
@@ -5150,32 +6314,38 @@ used with it do not have to be named on the @command{awk} command line
* Field Separators:: The field separator and how to change it.
* Constant Size:: Reading constant width data.
* Splitting By Content:: Defining Fields By Content
-* Multiple Line:: Reading multi-line records.
+* Multiple Line:: Reading multiline records.
* Getline:: Reading files under explicit program control
using the @code{getline} function.
-* Command line directories:: What happens if you put a directory on the
+* Read Timeout:: Reading input with a timeout.
+* Command-line directories:: What happens if you put a directory on the
command line.
+* Input Summary:: Input summary.
+* Input Exercises:: Exercises.
@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}, records 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.
+@command{awk} divides the input for your program into records and fields.
+It keeps track of the number of records that have been read so far from
+the current input file. This value is stored in a predefined variable
+called @code{FNR}, which is reset to zero every time a new file is started.
+Another predefined variable, @code{NR}, records 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.
+
+@menu
+* awk split records:: How standard @command{awk} splits records.
+* gawk split records:: How @command{gawk} splits records.
+@end menu
+
+@node awk split records
+@subsection Record Splitting with Standard @command{awk}
@cindex separators, for records
@cindex record separators
@@ -5183,7 +6353,7 @@ 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}.
+assigning the character to the predefined variable @code{RS}.
@cindex newlines, as record separators
@cindex @code{RS} variable
@@ -5192,75 +6362,86 @@ 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
+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
+awk 'BEGIN @{ RS = "u" @}
+ @{ print $0 @}' mail-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
+changes the value of @code{RS} to @samp{u}, before reading any input.
+This is a string whose first character is the letter ``u''; as a result, records
+are separated by the letter ``u.'' 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
-$ @kbd{awk 'BEGIN @{ RS = "/" @}}
-> @kbd{@{ 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
+with each @samp{u} changed to a newline. Here are the results of running
+the program on @file{mail-list}:
+
+@example
+$ @kbd{awk 'BEGIN @{ RS = "u" @}}
+> @kbd{@{ print $0 @}' mail-list}
+@print{} Amelia 555-5553 amelia.zodiac
+@print{} sq
+@print{} e@@gmail.com F
+@print{} Anthony 555-3412 anthony.assert
+@print{} ro@@hotmail.com A
+@print{} Becky 555-7685 becky.algebrar
+@print{} m@@gmail.com A
+@print{} Bill 555-1675 bill.drowning@@hotmail.com A
+@print{} Broderick 555-0542 broderick.aliq
+@print{} otiens@@yahoo.com R
+@print{} Camilla 555-2912 camilla.inf
+@print{} sar
+@print{} m@@skynet.be R
+@print{} Fabi
+@print{} s 555-1234 fabi
+@print{} s.
+@print{} ndevicesim
+@print{} s@@
+@print{} cb.ed
+@print{} F
+@print{} J
+@print{} lie 555-6699 j
+@print{} lie.perscr
+@print{} tabor@@skeeve.com F
+@print{} Martin 555-6480 martin.codicib
+@print{} s@@hotmail.com A
+@print{} Sam
+@print{} el 555-3430 sam
+@print{} el.lanceolis@@sh
+@print{} .ed
+@print{} A
+@print{} Jean-Pa
+@print{} l 555-2127 jeanpa
+@print{} l.campanor
+@print{} m@@ny
+@print{} .ed
+@print{} R
@print{}
@end example
@noindent
-Note that the entry for the @samp{camelot} BBS is not split.
+Note that the entry for the name @samp{Bill} is not split.
In the original @value{DF}
(@pxref{Sample Data Files}),
the line looks like this:
@example
-camelot 555-0542 300 C
+Bill 555-1675 bill.drowning@@hotmail.com A
@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
+It contains no @samp{u} so there is no reason to split the record,
+unlike the others which have one or more occurrences of the @samp{u}.
+In fact, this record is treated as part of the previous record;
+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!
@@ -5271,36 +6452,47 @@ using the variable-assignment feature
(@pxref{Other Arguments}):
@example
-awk '@{ print $0 @}' RS="/" BBS-list
+awk '@{ print $0 @}' RS="u" mail-list
@end example
@noindent
-This sets @code{RS} to @samp{/} before processing @file{BBS-list}.
+This sets @code{RS} to @samp{u} before processing @file{mail-list}.
+
+Using an alphabetic character such as @samp{u} for the record separator
+is highly likely to produce strange results.
+Using an unusual character such as @samp{/} is more likely to
+produce correct behavior in the majority of cases, but there
+are no guarantees. The moral is: Know Your Data.
-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}:
+When using regular characters as the record separator,
+there is one unusual case that occurs when @command{gawk} is
+being fully POSIX-compliant (@pxref{Options}).
+Then, the following (extreme) pipeline prints a surprising @samp{1}:
@example
-$ echo | awk 'BEGIN @{ RS = "a" @} ; @{ print NF @}'
+$ @kbd{echo | gawk --posix '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.
+(In the normal case, @command{gawk} treats the newline as whitespace,
+printing @samp{0} as the result. Most other versions of @command{awk}
+also act this way.)
@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 empty strings
@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.
+@DBXREF{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
@@ -5319,6 +6511,9 @@ 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}.
+@node gawk split records
+@subsection Record Splitting with @command{gawk}
+
@cindex common extensions, @code{RS} as a regexp
@cindex extensions, common@comma{} @code{RS} as a regexp
When using @command{gawk},
@@ -5350,22 +6545,22 @@ with optional leading and/or trailing whitespace:
@example
$ @kbd{echo record 1 AAAA record 2 BBBB record 3 |}
> @kbd{gawk 'BEGIN @{ RS = "\n|( *[[:upper:]]+ *)" @}}
-> @kbd{@{ 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{}
+> @kbd{@{ 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
+The square brackets delineate the contents of @code{RT}, letting you
+see the leading and trailing whitespace. The final value of
+@code{RT} is a newline.
+@DBXREF{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
+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.
@@ -5378,8 +6573,8 @@ 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}.
+that happens to contain newline characters.
+It is thus best to avoid anchor metacharacters in the value of @code{RS}.
@end quotation
@cindex differences in @command{awk} and @command{gawk}, @code{RS}/@code{RT} variables
@@ -5388,19 +6583,71 @@ 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.
+@code{RS} determines the end of the record.
-@c fakenode --- for prepinfo
-@subheading Advanced Notes: @code{RS = "\0"} Is Not Portable
+@cindex sidebar, @code{RS = "\0"} Is Not Portable
+@ifdocbook
+@docbook
+<sidebar><title>@code{RS = "\0"} Is Not Portable</title>
+@end docbook
+
+@cindex portability, data files 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.
+
+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.
+This works for certain special files, such as @file{/proc/environ} on
+GNU/Linux systems, where the @sc{nul} character is in fact the record separator.
+However, this usage is @emph{not} portable
+to most other @command{awk} implementations.
-@cindex advanced features, @value{DF}s as single record
-@cindex portability, @value{DF}s as single record
+@cindex dark corner, strings, storing
+Almost 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}
+
+It happens that recent versions of @command{mawk} can use the @sc{nul}
+character as a record separator. However, this is a special case:
+@command{mawk} does not allow embedded @sc{nul} characters in strings.
+(This may change in a future version of @command{mawk}.)
+
+@cindex records, treating files as
+@cindex treating files, as single records
+@DBXREF{Readfile Function} for an interesting way to read
+whole files. If you are using @command{gawk}, see @DBREF{Extension Sample
+Readfile} for another option.
+
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{@code{RS = "\0"} Is Not Portable}
+
+
+@cindex portability, data files 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
@@ -5413,23 +6660,30 @@ BEGIN @{ RS = "\0" @} # whole file becomes one record?
@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.
+This works for certain special files, such as @file{/proc/environ} on
+GNU/Linux systems, where the @sc{nul} character is in fact the record separator.
However, this usage is @emph{not} portable
-to other @command{awk} implementations.
+to most other @command{awk} implementations.
@cindex dark corner, strings, storing
-All other @command{awk} implementations@footnote{At least that we know
+Almost 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}
+It happens that recent versions of @command{mawk} can use the @sc{nul}
+character as a record separator. However, this is a special case:
+@command{mawk} does not allow embedded @sc{nul} characters in strings.
+(This may change in a future version of @command{mawk}.)
+
@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
+@cindex treating files, as single records
+@DBXREF{Readfile Function} for an interesting way to read
+whole files. If you are using @command{gawk}, see @DBREF{Extension Sample
+Readfile} for another option.
+@end cartouche
+@end ifnotdocbook
@node Fields
@section Examining Fields
@@ -5437,7 +6691,6 @@ record onto the end of the previous ones.
@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
@@ -5448,9 +6701,9 @@ 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
+considered whitespace for separating fields.} other characters
+that are considered whitespace by other languages
+(such as formfeed, vertical tab, etc.) are @emph{not} considered
whitespace by @command{awk}.
The purpose of fields is to make it more convenient for you to refer to
@@ -5462,12 +6715,12 @@ simple @command{awk} programs so powerful.
@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
+You use a dollar-sign (@samp{$})
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.)
+@code{$127} is the 127th field in the record.)
For example, suppose the following is a line of input:
@example
@@ -5483,7 +6736,7 @@ field.
@cindex @code{NF} variable
@cindex fields, number of
-@code{NF} is a built-in variable whose value is the number of fields
+@code{NF} is a predefined 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}.
@@ -5493,45 +6746,38 @@ 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
+a special case: it represents the whole input record. Use it
when you are not interested in specific fields.
Here are some more examples:
@example
-$ @kbd{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
+$ @kbd{awk '$1 ~ /li/ @{ print $0 @}' mail-list}
+@print{} Amelia 555-5553 amelia.zodiacusque@@gmail.com F
+@print{} Julie 555-6699 julie.perscrutabor@@skeeve.com F
@end example
@noindent
-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.
+This example prints each record in the file @file{mail-list} whose first
+field contains the string @samp{li}.
-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:
+By contrast, the following example looks for @samp{li} in @emph{the
+entire record} and prints the first and last fields for each matching
+input record:
@example
-$ @kbd{awk '/foo/ @{ print $1, $NF @}' BBS-list}
-@print{} fooey B
-@print{} foot B
-@print{} macfoo A
-@print{} sabafoo C
+$ @kbd{awk '/li/ @{ print $1, $NF @}' mail-list}
+@print{} Amelia F
+@print{} Broderick R
+@print{} Julie F
+@print{} Samuel A
@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
+A field number need not 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.
@@ -5543,14 +6789,14 @@ awk '@{ print $NR @}'
@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
+first record, two in the second, and so on. 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
+awk '@{ print $(2*2) @}' mail-list
@end example
@command{awk} evaluates the expression @samp{(2*2)} and uses
@@ -5558,9 +6804,13 @@ 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
+operator@footnote{A @dfn{binary operator}, such as @samp{*} for
+multiplication, is one that takes two operands. The distinction
+is required, because @command{awk} also has unary (one-operand)
+and ternary (three-operand) operators.}
+in the field-number expression. This example, then, prints the
+type of relationship (the fourth field) for every line of the file
+@file{mail-list}. (All of the @command{awk} operators are listed, in
order of decreasing precedence, in
@ref{Precedence}.)
@@ -5574,14 +6824,13 @@ 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
+variable @code{NF} (also @pxref{Built-in Variables}). Thus, 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
@@ -5608,7 +6857,7 @@ 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
+For this to work, the text in @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
@@ -5630,12 +6879,12 @@ $ @kbd{awk '@{ $2 = $2 - 10; print $0 @}' inventory-shipped}
@dots{}
@end example
-It is also possible to also assign contents to fields that are out
+It is also possible to assign contents to fields that are out
of range. For example:
@example
-$ awk '@{ $6 = ($5 + $4 + $3 + $2)
-> print $6 @}' inventory-shipped
+$ @kbd{awk '@{ $6 = ($5 + $4 + $3 + $2)}
+> @kbd{ print $6 @}' inventory-shipped}
@print{} 168
@print{} 297
@print{} 301
@@ -5681,9 +6930,9 @@ else
@noindent
should print @samp{everything is normal}, because @code{NF+1} is certain
-to be out of range. (@xref{If Statement},
+to be out of range. (@DBXREF{If Statement}
for more information about @command{awk}'s @code{if-else} statements.
-@xref{Typing and Comparison},
+@DBXREF{Typing and Comparison}
for more information about the @samp{!=} operator.)
It is important to note that making an assignment to an existing field
@@ -5699,7 +6948,7 @@ $ @kbd{echo a b c d | awk '@{ OFS = ":"; $2 = ""}
@end example
@noindent
-The field is still there; it just has an empty value, denoted by
+The field is still there; it just has an empty value, delimited by
the two colons between @samp{a} and @samp{c}.
This example shows what happens if you create a new field:
@@ -5723,8 +6972,8 @@ after the new value of @code{NF} and recomputes @code{$0}.
Here is an example:
@example
-$ echo a b c d e f | awk '@{ print "NF =", NF;
-> NF = 3; print $0 @}'
+$ @kbd{echo a b c d e f | awk '@{ print "NF =", NF;}
+> @kbd{ NF = 3; print $0 @}'}
@print{} NF = 6
@print{} a b c
@end example
@@ -5732,7 +6981,7 @@ $ echo a b c d e f | awk '@{ print "NF =", NF;
@cindex portability, @code{NF} variable@comma{} decrementing
@quotation CAUTION
Some versions of @command{awk} don't
-rebuild @code{$0} when @code{NF} is decremented. Caveat emptor.
+rebuild @code{$0} when @code{NF} is decremented.
@end quotation
Finally, there are times when it is convenient to force
@@ -5746,7 +6995,7 @@ print $0 # or whatever else with $0
@end example
@noindent
-This forces @command{awk} rebuild the record. It does help
+This forces @command{awk} to 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
@@ -5756,24 +7005,54 @@ This also applies to any built-in function that updates @code{$0},
such as @code{sub()} and @code{gsub()}
(@pxref{String Functions}).
-@c fakenode --- for prepinfo
-@subheading Advanced Notes: Understanding @code{$0}
+@cindex sidebar, Understanding @code{$0}
+@ifdocbook
+@docbook
+<sidebar><title>Understanding @code{$0}</title>
+@end docbook
+
+
+It is important to remember that @code{$0} is the @emph{full}
+record, exactly as it was read from the input. This includes
+any leading or trailing whitespace, and the exact whitespace (or other
+characters) that separate the fields.
+
+It is a common error to try to change the field separators
+in a record simply by setting @code{FS} and @code{OFS}, and then
+expecting a plain @samp{print} or @samp{print $0} to print the
+modified record.
+
+But this does not work, because nothing was done to change the record
+itself. Instead, you must force the record to be rebuilt, typically
+with a statement such as @samp{$1 = $1}, as described earlier.
+
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{Understanding @code{$0}}
+
+
It is important to remember that @code{$0} is the @emph{full}
record, exactly as it was read from the input. This includes
any leading or trailing whitespace, and the exact whitespace (or other
characters) that separate the fields.
-It is a not-uncommon error to try to change the field separators
+It is a common error to try to change the field separators
in a record simply by setting @code{FS} and @code{OFS}, and then
expecting a plain @samp{print} or @samp{print $0} to print the
modified record.
-But this does not work, since nothing was done to change the record
+But this does not work, because nothing was done to change the record
itself. Instead, you must force the record to be rebuilt, typically
with a statement such as @samp{$1 = $1}, as described earlier.
+@end cartouche
+@end ifnotdocbook
-@c ENDOFRANGE ficon
@node Field Separators
@section Specifying How Fields Are Separated
@@ -5782,15 +7061,14 @@ with a statement such as @samp{$1 = $1}, as described earlier.
* Default Field Splitting:: How fields are normally separated.
* 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.
+* Command Line Field Separator:: Setting @code{FS} from the command line.
+* Full Line Fields:: Making the full line be a single field.
* 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.
@@ -5811,7 +7089,7 @@ is split into three fields: @samp{m}, @samp{@bullet{}g}, and
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}.
+The field separator is represented by the predefined 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 Bash).
@@ -5819,7 +7097,7 @@ the Unix Bourne shell, @command{sh}, or 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
+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
@@ -5890,9 +7168,7 @@ 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
@@ -5950,7 +7226,7 @@ $ @kbd{echo ' a b c d ' | awk 'BEGIN @{ FS = "[ \t\n]+" @}}
@cindex null strings
@cindex strings, null
@cindex empty strings, See null strings
-In this case, the first field is @dfn{null} or empty.
+In this case, the first field is null, or empty.
The stripping of leading and trailing whitespace also comes into
play whenever @code{$0} is recomputed. For instance, study this pipeline:
@@ -5965,37 +7241,37 @@ $ @kbd{echo ' a b c d' | awk '@{ print; $2 = $2; print @}'}
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}.
+separated by the value of @code{OFS} (which is a space by default).
+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}.
@cindex @code{FS}, containing @code{^}
-@cindex @code{^}, in @code{FS}
+@cindex @code{^} (caret), in @code{FS}
@cindex dark corner, @code{^}, in @code{FS}
There is an additional subtlety to be aware of when using regular expressions
for field splitting.
-It is not well-specified in the POSIX standard, or anywhere else, what @samp{^}
+It is not well specified in the POSIX standard, or anywhere else, what @samp{^}
means when splitting fields. Does the @samp{^} match only at the beginning of
the entire record? Or is each field separator a new string? It turns out that
different @command{awk} versions answer this question differently, and you
should not rely on any specific behavior in your programs.
@value{DARKCORNER}
-As a point of information, Brian Kernighan's @command{awk} allows @samp{^}
+@cindex Brian Kernighan's @command{awk}
+As a point of information, BWK @command{awk} allows @samp{^}
to match only at the beginning of the record. @command{gawk}
also works this way. For example:
@example
$ @kbd{echo 'xxAA xxBxx C' |}
> @kbd{gawk -F '(^x+)|( +)' '@{ for (i = 1; i <= NF; i++)}
-> @kbd{printf "-->%s<--\n", $i @}'}
+> @kbd{ printf "-->%s<--\n", $i @}'}
@print{} --><--
@print{} -->AA<--
@print{} -->xxBxx<--
@print{} -->C<--
@end example
-@c ENDOFRANGE regexpfs
-@c ENDOFRANGE fsregexp
@node Single Character Fields
@subsection Making Each Character a Separate Field
@@ -6024,7 +7300,7 @@ $ @kbd{echo a b | gawk 'BEGIN @{ FS = "" @}}
@end example
@cindex dark corner, @code{FS} as null string
-@cindex FS variable, as null string
+@cindex @code{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.
@@ -6036,10 +7312,8 @@ 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 @option{-F} option, command-line
+@cindex field separator, on command line
@cindex command line, @code{FS} on@comma{} setting
@cindex @code{FS} variable, setting from command line
@@ -6053,15 +7327,10 @@ awk -F, '@var{program}' @var{input-files}
@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.
+option (@option{-f}) specifies a file containing an @command{awk} program.
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}.
+same way as assignments to the predefined 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:
@@ -6072,8 +7341,8 @@ awk -F\\\\ '@dots{}' files @dots{}
@end example
@noindent
-@cindex @code{\} (backslash), as field separators
-@cindex backslash (@code{\}), as field separators
+@cindex @code{\} (backslash), as field separator
+@cindex backslash (@code{\}), as field separator
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
@@ -6088,111 +7357,140 @@ 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.
+Use @samp{-F '\t'} when not in compatibility mode to specify that TABs
+separate fields.
-As an 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}:
+As an example, let's use an @command{awk} program file called @file{edu.awk}
+that contains the pattern @code{/edu/} and the action @samp{print $1}:
@example
-/300/ @{ print $1 @}
+/edu/ @{ 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
+program on the file @file{mail-list}. The following command prints a
+list of the names of the people that work at or attend a university, and
the first three digits of their phone numbers:
-@c tweaked to make the tex output look better in @smallbook
@example
-$ @kbd{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
+$ @kbd{awk -F- -f edu.awk mail-list}
+@print{} Fabius 555
+@print{} Samuel 555
+@print{} Jean
@end example
@noindent
-Note the second line of output. The second line
+Note the third line of output. The third line
in the original file looked like this:
@example
-alpo-net 555-3412 2400/1200/300 A
+Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R
@end example
-The @samp{-} as part of the system's name was used as the field
+The @samp{-} as part of the person'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 login name and the second is
-the user's (encrypted or shadow) password. A password file entry might look
-like this:
+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 login name and the second is the user's
+encrypted or shadow password. (A shadow password is indicated by the
+presence of a single @samp{x} in the second field.) A password file
+entry might look like this:
@cindex Robbins, Arnold
@example
-arnold:xyzzy:2076:10:Arnold Robbins:/home/arnold:/bin/bash
+arnold:x: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:
+the entries for users whose full name is not indicated:
@example
-awk -F: '$2 == ""' /etc/passwd
+awk -F: '$5 == ""' /etc/passwd
@end example
-@node Field Splitting Summary
-@subsection Field-Splitting Summary
+@node Full Line Fields
+@subsection Making the Full Line Be a Single Field
-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 = "\\.."}.
+Occasionally, it's useful to treat the whole input line as a
+single field. This can be done easily and portably simply by
+setting @code{FS} to @code{"\n"} (a newline):@footnote{Thanks to
+Andrew Schorr for this tip.}
-The following table summarizes how fields are split, based on the value
-of @code{FS} (@samp{==} means ``is equal to''):
+@example
+awk -F'\n' '@var{program}' @var{files @dots{}}
+@end example
-@table @code
-@item FS == " "
-Fields are separated by runs of whitespace. Leading and trailing
-whitespace are ignored. This is the default.
+@noindent
+When you do this, @code{$1} is the same as @code{$0}.
-@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.
+@cindex sidebar, Changing @code{FS} Does Not Affect the Fields
+@ifdocbook
+@docbook
+<sidebar><title>Changing @code{FS} Does Not Affect the Fields</title>
+@end docbook
-@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
+@cindex POSIX @command{awk}, field separators and
+@cindex field separator, 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 older 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 the full first line of the file, something like:
+
+@example
+root:x:0:0:Root:/:
+@end example
+
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{Changing @code{FS} Does Not Affect the Fields}
+
-@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
+@cindex field separator, 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}
@@ -6227,14 +7525,56 @@ root
@noindent
on an incorrect implementation of @command{awk}, while @command{gawk}
-prints something like:
+prints the full first line of the file, something like:
@example
-root:nSijPlPhZZwgE:0:0:Root:/:
+root:x:0:0:Root:/:
@end example
+@end cartouche
+@end ifnotdocbook
+
+@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 list 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 common extension; it is not specified by the POSIX standard.)
+@end table
+
+@cindex sidebar, @code{FS} and @code{IGNORECASE}
+@ifdocbook
+@docbook
+<sidebar><title>@code{FS} and @code{IGNORECASE}</title>
+@end docbook
-@c fakenode --- for prepinfo
-@subheading Advanced Notes: @code{FS} and @code{IGNORECASE}
The @code{IGNORECASE} variable
(@pxref{User-modified})
@@ -6252,37 +7592,59 @@ print $1
@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}
+do it for you (e.g., @samp{FS = "[c]"}). In this case, @code{IGNORECASE}
will take effect.
-@c ENDOFRANGE fisepr
-@c ENDOFRANGE fisepg
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{@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.
+@end cartouche
+@end ifnotdocbook
+
@node Constant Size
@section Reading Fixed-Width Data
-@ifnotinfo
-@quotation NOTE
+@cindex data, fixed-width
+@cindex fixed-width data
+@cindex advanced features, fixed-width data
+
+@c O'Reilly doesn't like it as a note the first thing in the section.
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} provides 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.
+@command{gawk} provides 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
@@ -6321,20 +7683,15 @@ dave ttyq4 26Jun9115days 46 46 wnewmail
@end group
@end example
-The following program takes the above input, converts the idle time to
+The following program takes this 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
+ sub(/^ +/, "", idle) # strip leading spaces
if (idle == "")
idle = 0
if (idle ~ /:/) @{
@@ -6348,6 +7705,11 @@ NR > 2 @{
@}
@end example
+@quotation NOTE
+The preceding program uses a number of @command{awk} features that
+haven't been introduced yet.
+@end quotation
+
Running the program on the data produces the following results:
@example
@@ -6371,10 +7733,6 @@ 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,
@@ -6391,31 +7749,22 @@ if (PROCINFO["FS"] == "FS")
else if (PROCINFO["FS"] == "FIELDWIDTHS")
@var{fixed-width field splitting} @dots{}
else
- @var{content-based field splitting} @dots{} (see next @value{SECTION})
+ @var{content-based field splitting} @dots{} @ii{(see next @value{SECTION})}
@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},
+(@DBPXREF{Passwd Functions}
for an example of such a function).
@node Splitting By Content
-@section Defining Fields By Content
+@section Defining Fields by Content
-@ifnotinfo
-@quotation NOTE
+@c O'Reilly doesn't like it as a note the first thing in the section.
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 advanced features, specifying field content
Normally, when using @code{FS}, @command{gawk} defines the fields as the
@@ -6426,14 +7775,16 @@ However, there are times when you really want to define the fields by
what they are, and not by what they are not.
The most notorious such case
-is so-called @dfn{comma separated value} (CSV) data. Many spreadsheet programs,
+is so-called @dfn{comma-separated values} (CSV) data. Many spreadsheet programs,
for example, can export their data into text files, where each record is
terminated with a newline, and fields are separated by commas. If only
commas separated the data, there wouldn't be an issue. The problem comes when
-one of the fields contains an @emph{embedded} comma. While there is no
-formal standard specification for CSV data@footnote{At least, we don't know of one.},
-in such cases, most programs embed the field in double quotes. So we might
-have data like this:
+one of the fields contains an @emph{embedded} comma.
+In such cases, most programs embed the field in double quotes.@footnote{The
+CSV format lacked a formal standard definition for many years.
+@uref{http://www.ietf.org/rfc/rfc4180.txt, RFC 4180}
+standardizes the most common practices.}
+So we might have data like this:
@example
@c file eg/misc/addresses.csv
@@ -6447,7 +7798,7 @@ The @code{FPAT} variable offers a solution for cases like this.
The value of @code{FPAT} should be a string that provides a regular expression.
This regular expression describes the contents of each field.
-In the case of CSV data as presented above, each field is either ``anything that
+In the case of CSV data as presented here, each field is either ``anything that
is not a comma,'' or ``a double quote, anything that is not a double quote, and a
closing double quote.'' If written as a regular expression constant
(@pxref{Regexp}),
@@ -6504,16 +7855,18 @@ if (substr($i, 1, 1) == "\"") @{
As with @code{FS}, the @code{IGNORECASE} variable (@pxref{User-modified})
affects field splitting with @code{FPAT}.
+Assigning a value to @code{FPAT} overrides field splitting
+with @code{FS} and with @code{FIELDWIDTHS}.
Similar to @code{FIELDWIDTHS}, the value of @code{PROCINFO["FS"]}
will be @code{"FPAT"} if content-based field splitting is being used.
@quotation NOTE
Some programs export CSV data that contains embedded newlines between
the double quotes. @command{gawk} provides no way to deal with this.
-Since there is no formal specification for CSV data, there isn't much
+Even though a formal specification for CSV data exists, there isn't much
more to be done;
the @code{FPAT} mechanism provides an elegant solution for the majority
-of cases, and the @command{gawk} maintainer is satisfied with that.
+of cases, and the @command{gawk} developers are satisfied with that.
@end quotation
As written, the regexp used for @code{FPAT} requires that each field
@@ -6527,14 +7880,18 @@ FPAT = "([^,]*)|(\"[^\"]+\")"
Finally, the @code{patsplit()} function makes the same functionality
available for splitting regular strings (@pxref{String Functions}).
+To recap, @command{gawk} provides three independent methods
+to split input records into fields. @command{gawk} uses whichever
+mechanism was last chosen based on which of the three
+variables---@code{FS}, @code{FIELDWIDTHS}, and @code{FPAT}---was
+last assigned to.
+
@node Multiple Line
@section Multiple-Line Records
-@c STARTOFRANGE recm
+@cindex multiple-line records
@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
@@ -6574,14 +7931,15 @@ 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
+However, 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
+@cindex field separator, in multiline records
+@cindex @code{FS}, 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
@@ -6647,7 +8005,7 @@ BEGIN @{ RS = "" ; FS = "\n" @}
Running the program produces the following output:
@example
-$ awk -f addrs.awk addresses
+$ @kbd{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
@@ -6659,12 +8017,9 @@ $ awk -f addrs.awk addresses
@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
+@DBXREF{Labels Program} for a more realistic program dealing with
+address lists. The following list summarizes how records are split,
+based on the value of
@ifinfo
@code{RS}.
(@samp{==} means ``is equal to.'')
@@ -6699,22 +8054,18 @@ POSIX standard.)
@cindex @command{gawk}, @code{RT} variable in
@cindex @code{RT} variable
-In all cases, @command{gawk} sets @code{RT} to the input text that matched the
-value specified by @code{RS}.
+If not in compatibility mode (@pxref{Options}), @command{gawk} sets
+@code{RT} to the input text that matched the value specified by @code{RS}.
But if the input file ended without any text that matches @code{RS},
then @command{gawk} sets @code{RT} to the null string.
-@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
+input stream---either the standard input (usually your keyboard, 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
@@ -6725,15 +8076,27 @@ The @code{getline} command is used in several different ways and should
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.
+rest of
+@ifinfo
+this @value{DOCUMENT}
+@end ifinfo
+@ifhtml
+this @value{DOCUMENT}
+@end ifhtml
+@ifnotinfo
+@ifnothtml
+Parts I and II
+@end ifnothtml
+@end ifnotinfo
+and have a good knowledge of how @command{awk} works.
@cindex @command{gawk}, @code{ERRNO} variable in
-@cindex @code{ERRNO} variable
+@cindex @code{ERRNO} variable, with @command{getline} command
@cindex differences in @command{awk} and @command{gawk}, @code{getline} command
@cindex @code{getline} command, return values
-@cindex @code{--sandbox} option, input redirection with @command{getline}
+@cindex @option{--sandbox} option, input redirection with @code{getline}
-The @code{getline} command returns one if it finds a record and zero if
+The @code{getline} command returns 1 if it finds a record and 0 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
@@ -6744,7 +8107,7 @@ represents a shell command.
@quotation NOTE
When @option{--sandbox} is specified (@pxref{Options}),
-reading lines from files, pipes and coprocesses is disabled.
+reading lines from files, pipes, and coprocesses is disabled.
@end quotation
@menu
@@ -6773,44 +8136,63 @@ finished processing the current record, but want to do some special
processing on the next record @emph{right now}. For example:
@example
+# Remove text between /* and */, inclusive
@{
- 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), "*/")
- offset = t + 2
- while (u == 0) @{
- if (getline <= 0) @{
- m = "unexpected EOF or error"
- m = (m ": " ERRNO)
- print m > "/dev/stderr"
+ if ((i = index($0, "/*")) != 0) @{
+ out = substr($0, 1, i - 1) # leading part of the string
+ rest = substr($0, i + 2) # ... */ ...
+ j = index(rest, "*/") # is */ in trailing part?
+ if (j > 0) @{
+ rest = substr(rest, j + 2) # remove comment
+ @} else @{
+ while (j == 0) @{
+ # get more text
+ if (getline <= 0) @{
+ print("unexpected EOF or error:", ERRNO) > "/dev/stderr"
exit
- @}
- u = index($0, "*/")
- offset = 0
- @}
- # substr() expression will be "" if */
- # occurred at end of line
- $0 = tmp substr($0, offset + u + 2)
- @}
- print $0
+ @}
+ # build up the line using string concatenation
+ rest = rest $0
+ j = index(rest, "*/") # is */ in trailing part?
+ if (j != 0) @{
+ rest = substr(rest, j + 2)
+ break
+ @}
+ @}
+ @}
+ # build up the output line using string concatenation
+ $0 = out rest
+ @}
+ print $0
@}
@end example
+@c 8/2014: Here is some sample input:
+@ignore
+mon/*comment*/key
+rab/*commen
+t*/bit
+horse /*comment*/more text
+part 1 /*comment*/part 2 /*comment*/part 3
+no comment
+@end ignore
+
This @command{awk} program deletes C-style comments (@samp{/* @dots{}
-*/}) from the input. By replacing the @samp{print $0} with other
+*/}) from the input.
+It uses a number of features we haven't covered yet, including
+string concatenation
+(@pxref{Concatenation})
+and the @code{index()} and @code{substr()} built-in
+functions
+(@pxref{String Functions}).
+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}.
+@code{NR}, @code{FNR}, @code{RT}, and the value of @code{$0}.
@quotation NOTE
The new value of @code{$0} is used to test
@@ -6824,6 +8206,7 @@ rule in the program. @xref{Next Statement}.
@node Getline/Variable
@subsection Using @code{getline} into a Variable
+@cindex @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
@@ -6867,13 +8250,15 @@ 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
+@code{NR}, @code{FNR}, and @code{RT} (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 @code{getline} from a file
@cindex input redirection
@cindex redirection of input
@cindex @code{<} (left angle bracket), @code{<} operator (I/O)
@@ -6902,15 +8287,16 @@ 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}.
+@code{RT} is also set.
@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 all @command{awk} implementations.
+because the concatenation operator (not discussed yet; @pxref{Concatenation})
+is not parenthesized. You should write it as @samp{getline < (dir "/" file)} if
+you want your program to be portable to all @command{awk} implementations.
@node Getline/Variable/File
@subsection Using @code{getline} into a Variable from a File
@@ -6918,12 +8304,10 @@ to be portable to all @command{awk} implementations.
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}
+@var{file}, and put it in the variable @var{var}. As earlier, @var{file}
is a string-valued expression that specifies the file from which to read.
-@cindex @command{gawk}, @code{RT} variable in
-@cindex @code{RT} variable
-In this version of @code{getline}, none of the built-in variables are
+In this version of @code{getline}, none of the predefined variables are
changed and the record is not split into fields. The only variable
changed is @var{var}.@footnote{This is not quite true. @code{RT} could
be changed if @code{RS} is a regular expression.}
@@ -6945,28 +8329,35 @@ Such a record is replaced by the contents of the file
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.
+the @code{@@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
+@code{@@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)
+@code{@@include} statements
+(i.e., @code{@@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.
+@DBXREF{Igawk Program} for a program
+that does handle nested @code{@@include} statements.
@node Getline/Pipe
@subsection Using @code{getline} from a Pipe
+@c From private email, dated October 2, 1988. Used by permission, March 2013.
+@cindex Kernighan, Brian
+@quotation
+@i{Omniscience has much to recommend it.
+Failing that, attention to details would be useful.}
+@author Brian Kernighan
+@end quotation
+
@cindex @code{|} (vertical bar), @code{|} operator (I/O)
@cindex vertical bar (@code{|}), @code{|} operator (I/O)
@cindex input pipeline
-@cindex pipes, input
+@cindex pipe, input
@cindex operators, input/output
The output of a command can also be piped into @code{getline}, using
@samp{@var{command} | getline}. In
@@ -6990,14 +8381,14 @@ produced by running the rest of the line as a shell command:
@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
+@ifnotdocbook
@xref{Close Files And Pipes}.
+@end ifnotdocbook
@end ifnottex
-@c Exercise!!
@c This example is unrealistic, since you could just use system
Given the input:
@@ -7026,13 +8417,14 @@ bletch
@end example
@noindent
-Notice that this program ran the command @command{who} and printed the previous result.
+Notice that this program ran the command @command{who} and printed the 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.
+@code{RT} is set.
@cindex POSIX @command{awk}, @code{|} I/O operator and
@c Thanks to Paul Eggert for initial wording here
@@ -7043,12 +8435,14 @@ 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 all @command{awk} implementations.
+@cindex Brian Kernighan's @command{awk}
+@cindex @command{mawk} utility
@quotation NOTE
Unfortunately, @command{gawk} has not been consistent in its treatment
of a construct like @samp{@w{"echo "} "date" | getline}.
Most versions, including the current version, treat it at as
@samp{@w{("echo "} "date") | getline}.
-(This how Brian Kernighan's @command{awk} behaves.)
+(This is also how BWK @command{awk} behaves.)
Some versions changed and treated it as
@samp{@w{"echo "} ("date" | getline)}.
(This is how @command{mawk} behaves.)
@@ -7075,8 +8469,8 @@ BEGIN @{
@}
@end example
-In this version of @code{getline}, none of the built-in variables are
-changed and the record is not split into fields.
+In this version of @code{getline}, none of the predefined variables are
+changed and the record is not split into fields. However, @code{RT} is set.
@ifinfo
@c Thanks to Paul Eggert for initial wording here
@@ -7122,7 +8516,7 @@ The values of @code{NR} and
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}.
+and of @code{NF} and @code{RT}.
Coprocesses are an advanced feature. They are discussed here only because
this is the @value{SECTION} on @code{getline}.
@@ -7137,9 +8531,10 @@ 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
+In this version of @code{getline}, none of the predefined variables are
changed and the record is not split into fields. The only variable
changed is @var{var}.
+However, @code{RT} is set.
@ifinfo
Coprocesses are an advanced feature. They are discussed here only because
@@ -7153,7 +8548,7 @@ where coprocesses are discussed in more detail.
Here are some miscellaneous points about @code{getline} that
you should bear in mind:
-@itemize @bullet
+@itemize @value{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
@@ -7165,7 +8560,7 @@ However, the new record is tested against any subsequent rules.
@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}
+Some very old @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.
@@ -7183,7 +8578,7 @@ 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},
+(See @ref{BEGIN/END};
also @pxref{Auto-set}.)
@item
@@ -7192,16 +8587,45 @@ Using @code{FILENAME} with @code{getline}
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
+and @code{NF} 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.
@item
-@ref{Getline Summary}, presents a table summarizing the
+@DBREF{Getline Summary} presents a table summarizing the
@code{getline} variants and which variables they can affect.
It is worth noting that those variants which do not use redirection
can cause @code{FILENAME} to be updated if they cause
@command{awk} to start reading a new input file.
+
+@item
+@cindex Moore, Duncan
+If the variable being assigned is an expression with side effects,
+different versions of @command{awk} behave differently upon encountering
+end-of-file. Some versions don't evaluate the expression; many versions
+(including @command{gawk}) do. Here is an example, due to Duncan Moore:
+
+@ignore
+Date: Sun, 01 Apr 2012 11:49:33 +0100
+From: Duncan Moore <duncan.moore@@gmx.com>
+@end ignore
+
+@example
+BEGIN @{
+ system("echo 1 > f")
+ while ((getline a[++c] < "f") > 0) @{ @}
+ print c
+@}
+@end example
+
+@noindent
+Here, the side effect is the @samp{++c}. Is @code{c} incremented if
+end of file is encountered, before the element in @code{a} is assigned?
+
+@command{gawk} treats @code{getline} like a function call, and evaluates
+the expression @samp{a[++c]} before attempting to read from @file{f}.
+However, some versions of @command{awk} only evaluate the expression once they
+know that there is a string value to be assigned.
@end itemize
@node Getline Summary
@@ -7210,46 +8634,258 @@ can cause @code{FILENAME} to be updated if they cause
@ref{table-getline-variants}
summarizes the eight variants of @code{getline},
-listing which built-in variables are set by each one,
+listing which predefined variables are set by each one,
and whether the variant is standard or a @command{gawk} extension.
+Note: for each variant, @command{gawk} sets the @code{RT} predefined variable.
@float Table,table-getline-variants
-@caption{getline Variants and What They Set}
+@caption{@code{getline} variants and what they set}
@multitable @columnfractions .33 .38 .27
-@headitem Variant @tab Effect @tab Standard / Extension
-@item @code{getline} @tab Sets @code{$0}, @code{NF}, @code{FNR}, and @code{NR} @tab Standard
-@item @code{getline} @var{var} @tab Sets @var{var}, @code{FNR}, and @code{NR} @tab Standard
-@item @code{getline <} @var{file} @tab Sets @code{$0} and @code{NF} @tab Standard
-@item @code{getline @var{var} < @var{file}} @tab Sets @var{var} @tab Standard
-@item @var{command} @code{| getline} @tab Sets @code{$0} and @code{NF} @tab Standard
-@item @var{command} @code{| getline} @var{var} @tab Sets @var{var} @tab Standard
-@item @var{command} @code{|& getline} @tab Sets @code{$0} and @code{NF} @tab Extension
-@item @var{command} @code{|& getline} @var{var} @tab Sets @var{var} @tab Extension
+@headitem Variant @tab Effect @tab @command{awk} / @command{gawk}
+@item @code{getline} @tab Sets @code{$0}, @code{NF}, @code{FNR}, @code{NR}, and @code{RT} @tab @command{awk}
+@item @code{getline} @var{var} @tab Sets @var{var}, @code{FNR}, @code{NR}, and @code{RT} @tab @command{awk}
+@item @code{getline <} @var{file} @tab Sets @code{$0}, @code{NF}, and @code{RT} @tab @command{awk}
+@item @code{getline @var{var} < @var{file}} @tab Sets @var{var} and @code{RT} @tab @command{awk}
+@item @var{command} @code{| getline} @tab Sets @code{$0}, @code{NF}, and @code{RT} @tab @command{awk}
+@item @var{command} @code{| getline} @var{var} @tab Sets @var{var} and @code{RT} @tab @command{awk}
+@item @var{command} @code{|& getline} @tab Sets @code{$0}, @code{NF}, and @code{RT} @tab @command{gawk}
+@item @var{command} @code{|& getline} @var{var} @tab Sets @var{var} and @code{RT} @tab @command{gawk}
@end multitable
@end float
-@c ENDOFRANGE getl
-@c ENDOFRANGE inex
-@c ENDOFRANGE infir
-@node Command line directories
-@section Directories On The Command Line
-@cindex directories, command line
+@node Read Timeout
+@section Reading Input with a Timeout
+@cindex timeout, reading input
+
+@cindex differences in @command{awk} and @command{gawk}, read timeouts
+This @value{SECTION} describes a feature that is specific to @command{gawk}.
+
+You may specify a timeout in milliseconds for reading input from the keyboard,
+a pipe, or two-way communication, including TCP/IP sockets. This can be done
+on a per input, command, or connection basis, by setting a special element
+in the @code{PROCINFO} array (@pxref{Auto-set}):
+
+@example
+PROCINFO["input_name", "READ_TIMEOUT"] = @var{timeout in milliseconds}
+@end example
+
+When set, this causes @command{gawk} to time out and return failure
+if no data is available to read within the specified timeout period.
+For example, a TCP client can decide to give up on receiving
+any response from the server after a certain amount of time:
+
+@example
+Service = "/inet/tcp/0/localhost/daytime"
+PROCINFO[Service, "READ_TIMEOUT"] = 100
+if ((Service |& getline) > 0)
+ print $0
+else if (ERRNO != "")
+ print ERRNO
+@end example
+
+Here is how to read interactively from the user@footnote{This assumes
+that standard input is the keyboard.} without waiting
+for more than five seconds:
+
+@example
+PROCINFO["/dev/stdin", "READ_TIMEOUT"] = 5000
+while ((getline < "/dev/stdin") > 0)
+ print $0
+@end example
+
+@command{gawk} terminates the read operation if input does not
+arrive after waiting for the timeout period, returns failure
+and sets @code{ERRNO} to an appropriate string value.
+A negative or zero value for the timeout is the same as specifying
+no timeout at all.
+
+A timeout can also be set for reading from the keyboard in the implicit
+loop that reads input records and matches them against patterns,
+like so:
+
+@example
+$ @kbd{gawk 'BEGIN @{ PROCINFO["-", "READ_TIMEOUT"] = 5000 @}}
+> @kbd{@{ print "You entered: " $0 @}'}
+@kbd{gawk}
+@print{} You entered: gawk
+@end example
+
+In this case, failure to respond within five seconds results in the following
+error message:
+
+@example
+@error{} gawk: cmd. line:2: (FILENAME=- FNR=1) fatal: error reading input file `-': Connection timed out
+@end example
+
+The timeout can be set or changed at any time, and will take effect on the
+next attempt to read from the input device. In the following example,
+we start with a timeout value of one second, and progressively
+reduce it by one-tenth of a second until we wait indefinitely
+for the input to arrive:
+
+@example
+PROCINFO[Service, "READ_TIMEOUT"] = 1000
+while ((Service |& getline) > 0) @{
+ print $0
+ PROCINFO[Service, "READ_TIMEOUT"] -= 100
+@}
+@end example
+
+@quotation NOTE
+You should not assume that the read operation will block
+exactly after the tenth record has been printed. It is possible that
+@command{gawk} will read and buffer more than one record's
+worth of data the first time. Because of this, changing the value
+of timeout like in the preceding example is not very useful.
+@end quotation
+
+If the @code{PROCINFO} element is not present and the
+@env{GAWK_READ_TIMEOUT} environment variable exists,
+@command{gawk} uses its value to initialize the timeout value.
+The exclusive use of the environment variable to specify timeout
+has the disadvantage of not being able to control it
+on a per command or connection basis.
+
+@command{gawk} considers a timeout event to be an error even though
+the attempt to read from the underlying device may
+succeed in a later attempt. This is a limitation, and it also
+means that you cannot use this to multiplex input from
+two or more sources.
+
+Assigning a timeout value prevents read operations from
+blocking indefinitely. But bear in mind that there are other ways
+@command{gawk} can stall waiting for an input device to be ready.
+A network client can sometimes take a long time to establish
+a connection before it can start reading any data,
+or the attempt to open a FIFO special file for reading can block
+indefinitely until some other process opens it for writing.
+
+@node Command-line directories
+@section Directories on the Command Line
+@cindex differences in @command{awk} and @command{gawk}, command-line directories
+@cindex directories, command-line
@cindex command line, directories on
According to the POSIX standard, files named on the @command{awk}
-command line must be text files. It is a fatal error if they are not.
+command line must be text files; it is a fatal error if they are not.
Most versions of @command{awk} treat a directory on the command line as
a fatal error.
By default, @command{gawk} produces a warning for a directory on the
-command line, but otherwise ignores it. If either of the @option{--posix}
+command line, but otherwise ignores it. This makes it easier to use
+shell wildcards with your @command{awk} program:
+
+@example
+$ @kbd{gawk -f whizprog.awk *} @ii{Directories could kill this program}
+@end example
+
+If either of the @option{--posix}
or @option{--traditional} options is given, then @command{gawk} reverts
to treating a directory on the command line as a fatal error.
+@DBXREF{Extension Sample Readdir} for a way to treat directories
+as usable data from an @command{awk} program.
+
+@node Input Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+Input is split into records based on the value of @code{RS}.
+The possibilities are as follows:
+
+@multitable @columnfractions .25 .35 .40
+@headitem Value of @code{RS} @tab Records are split on @dots{} @tab @command{awk} / @command{gawk}
+@item Any single character @tab That character @tab @command{awk}
+@item The empty string (@code{""}) @tab Runs of two or more newlines @tab @command{awk}
+@item A regexp @tab Text that matches the regexp @tab @command{gawk}
+@end multitable
+
+@item
+@code{FNR} indicates how many records have been read from the current input file;
+@code{NR} indicates how many records have been read in total.
+
+@item
+@command{gawk} sets @code{RT} to the text matched by @code{RS}.
+
+@item
+After splitting the input into records, @command{awk} further splits
+the record into individual fields, named @code{$1}, @code{$2}, and so
+on. @code{$0} is the whole record, and @code{NF} indicates how many
+fields there are. The default way to split fields is between whitespace
+characters.
+
+@item
+Fields may be referenced using a variable, as in @code{$NF}. Fields
+may also be assigned values, which causes the value of @code{$0} to be
+recomputed when it is later referenced. Assigning to a field with a number
+greater than @code{NF} creates the field and rebuilds the record, using
+@code{OFS} to separate the fields. Incrementing @code{NF} does the same
+thing. Decrementing @code{NF} throws away fields and rebuilds the record.
+
+@item
+Field splitting is more complicated than record splitting:
+
+@multitable @columnfractions .40 .45 .15
+@headitem Field separator value @tab Fields are split @dots{} @tab @command{awk} / @command{gawk}
+@item @code{FS == " "} @tab On runs of whitespace @tab @command{awk}
+@item @code{FS == @var{any single character}} @tab On that character @tab @command{awk}
+@item @code{FS == @var{regexp}} @tab On text matching the regexp @tab @command{awk}
+@item @code{FS == ""} @tab Each individual character is a separate field @tab @command{gawk}
+@item @code{FIELDWIDTHS == @var{list of columns}} @tab Based on character position @tab @command{gawk}
+@item @code{FPAT == @var{regexp}} @tab On the text surrounding text matching the regexp @tab @command{gawk}
+@end multitable
+
+@item
+Using @samp{FS = "\n"} causes the entire record to be a single field
+(assuming that newlines separate records).
+
+@item
+@code{FS} may be set from the command line using the @option{-F} option.
+This can also be done using command-line variable assignment.
+
+@item
+Use @code{PROCINFO["FS"]} to see how fields are being split.
+
+@item
+Use @code{getline} in its various forms to read additional records,
+from the default input stream, from a file, or from a pipe or coprocess.
+
+@item
+Use @code{PROCINFO[@var{file}, "READ_TIMEOUT"]} to cause reads to timeout
+for @var{file}.
+
+@item
+Directories on the command line are fatal for standard @command{awk};
+@command{gawk} ignores them if not in POSIX mode.
+
+@end itemize
+
+@c EXCLUDE START
+@node Input Exercises
+@section Exercises
+
+@enumerate
+@item
+Using the @code{FIELDWIDTHS} variable (@pxref{Constant Size}),
+write a program to read election data, where each record represents
+one voter's votes. Come up with a way to define which columns are
+associated with each ballot item, and print the total votes,
+including abstentions, for each item.
+
+@item
+@ref{Plain Getline}, presented a program to remove C-style
+comments (@samp{/* @dots{} */}) from the input. That program
+does not work if one comment ends on one line and another one
+starts later on the same line.
+That can be fixed by making one simple change. What is it?
+
+@end enumerate
+@c EXCLUDE END
+
@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,
@@ -7260,12 +8896,11 @@ 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
+(For the exceptions, @DBPXREF{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}
@@ -7281,17 +8916,20 @@ and discusses the @code{close()} built-in function.
* Printf:: The @code{printf} statement.
* Redirection:: How to redirect output to multiple files and
pipes.
+* Special FD:: Special files for I/O.
* 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.
+* Output Summary:: Output summary.
+* Output Exercises:: Exercises.
@end menu
@node Print
@section The @code{print} Statement
-The @code{print} statement is used for producing output with simple, standardized
-formatting. Specify only the strings or numbers to print, in a
+Use the @code{print} statement to produce output with simple, standardized
+formatting. You 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:
@@ -7314,13 +8952,17 @@ expression. Numeric values are converted to strings and then printed.
@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.
+line, use @samp{print ""}.
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.
+Note that the @code{print} statement is a statement and not an
+expression---you can't use it in the pattern part of a
+@var{pattern}-@var{action} statement, for example.
+
@node Print Examples
@section @code{print} Statement Examples
@@ -7330,9 +8972,22 @@ 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 following is an example of printing a string that contains embedded
+@ifinfo
+newlines
(the @samp{\n} is an escape sequence, used to represent the newline
character; @pxref{Escape Sequences}):
+@end ifinfo
+@ifhtml
+newlines
+(the @samp{\n} is an escape sequence, used to represent the newline
+character; @pxref{Escape Sequences}):
+@end ifhtml
+@ifnotinfo
+@ifnothtml
+newlines:
+@end ifnothtml
+@end ifnotinfo
@example
$ @kbd{awk 'BEGIN @{ print "line one\nline two\nline three" @}'}
@@ -7374,10 +9029,9 @@ $ @kbd{awk '@{ print $1 $2 @}' inventory-shipped}
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:
+(@code{$1}) and green crates shipped (@code{$2}). We do this using
+a @code{BEGIN} rule (@pxref{BEGIN/END}) so that the headings are only
+printed once:
@example
awk 'BEGIN @{ print "Month Crates"
@@ -7426,7 +9080,6 @@ 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
@@ -7437,15 +9090,15 @@ 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 simply 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.
+predefined variable @code{OFS}. The initial value of this variable
+is the string @w{@code{" "}} (i.e., 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.
+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
@@ -7463,26 +9116,32 @@ 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
$ @kbd{awk 'BEGIN @{ OFS = ";"; ORS = "\n\n" @}}
-> @kbd{@{ print $1, $2 @}' BBS-list}
-@print{} aardvark;555-5553
+> @kbd{@{ print $1, $2 @}' mail-list}
+@print{} Amelia;555-5553
@print{}
-@print{} alpo-net;555-3412
+@print{} Anthony;555-3412
+@print{}
+@print{} Becky;555-7685
+@print{}
+@print{} Bill;555-1675
+@print{}
+@print{} Broderick;555-0542
+@print{}
+@print{} Camilla;555-2912
+@print{}
+@print{} Fabius;555-1234
+@print{}
+@print{} Julie;555-6699
+@print{}
+@print{} Martin;555-6480
+@print{}
+@print{} Samuel;555-3430
+@print{}
+@print{} Jean-Paul;555-2127
@print{}
-@print{} barfly;555-7685
-@dots{}
@end example
If the value of @code{ORS} does not contain a newline, the program's output
@@ -7504,16 +9163,16 @@ numbers can be formatted. The different format specifications are discussed
more fully in
@ref{Control Letters}.
-@cindex @code{sprintf()} function
+@cindexawkfunc{sprintf}
@cindex @code{OFMT} variable
@cindex output, format specifier@comma{} @code{OFMT}
-The built-in variable @code{OFMT} contains the default format specification
+The predefined variable @code{OFMT} contains the 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:
+by supplying a different format specification
+for the value of @code{OFMT}, as shown in the following example:
@example
$ @kbd{awk 'BEGIN @{}
@@ -7533,7 +9192,6 @@ if @code{OFMT} contains anything but a floating-point conversion specification.
@node Printf
@section Using @code{printf} Statements for Fancier Printing
-@c STARTOFRANGE printfs
@cindex @code{printf} statement
@cindex output, formatted
@cindex formatting output
@@ -7543,9 +9201,7 @@ With @code{printf} you can
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). You do this by supplying a string, called
-the @dfn{format string}, that controls how and where to print the other
-arguments.
+after the decimal point).
@menu
* Basic Printf:: Syntax of the @code{printf} statement.
@@ -7565,12 +9221,12 @@ 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 an output redirection
-(@pxref{Redirection}).
+As for @code{print}, the entire list of arguments may optionally be
+enclosed in parentheses. Here too, the parentheses are necessary if any
+of the item expressions use the @samp{>} relational operator; otherwise,
+it can be confused with an output redirection (@pxref{Redirection}).
-@cindex format strings
+@cindex format specifiers
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
@@ -7591,14 +9247,14 @@ on @code{printf} statements. For example:
@example
$ @kbd{awk 'BEGIN @{}
> @kbd{ORS = "\nOUCH!\n"; OFS = "+"}
-> @kbd{msg = "Dont Panic!"}
+> @kbd{msg = "Don\47t Panic!"}
> @kbd{printf "%s\n", msg}
> @kbd{@}'}
-@print{} Dont Panic!
+@print{} Don't Panic!
@end example
@noindent
-Here, neither the @samp{+} nor the @samp{OUCH} appear in
+Here, neither the @samp{+} nor the @samp{OUCH!} appear in
the output message.
@node Control Letters
@@ -7613,25 +9269,16 @@ 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
-Print a number as an ASCII character; thus, @samp{printf "%c",
+@c @asis for docbook to come out right
+@table @asis
+@item @code{%c}
+Print a number as a character; thus, @samp{printf "%c",
65} outputs the letter @samp{A}. The output for a string value is
the first character of the string.
@cindex dark corner, format-control characters
@cindex @command{gawk}, format-control characters
@quotation NOTE
-@ignore
-The @samp{%c} format does @emph{not} handle values outside the range
-0--255. On most systems, values from 0--127 are within the range of
-ASCII and will yield an ASCII character. Values in the range 128--255
-may format as characters in some extended character set, or they may not.
-System 390 (IBM architecture mainframe) systems use 8-bit characters,
-and thus values from 0--255 yield the corresponding EBCDIC character.
-Any value above 255 is treated as modulo 255; i.e., the lowest eight bits
-of the value are used. The locale and character set are always ignored.
-@end ignore
The POSIX standard says the first character of a string is printed.
In locales with multibyte characters, @command{gawk} attempts to
convert the leading bytes of the string into a valid wide character
@@ -7639,6 +9286,8 @@ and then to print the multibyte encoding of that character.
Similarly, when printing a numeric value, @command{gawk} allows the
value to be within the numeric range of values that can be held
in a wide character.
+If the conversion to multibyte encoding fails, @command{gawk}
+uses the low eight bits of the value as the character to print.
Other @command{awk} versions generally restrict themselves to printing
the first byte of a string or to numeric values within the range of
@@ -7646,12 +9295,12 @@ a single byte (0--255).
@end quotation
-@item %d@r{,} %i
+@item @code{%d}, @code{%i}
Print a decimal integer.
The two control letters are equivalent.
(The @samp{%i} specification is for compatibility with ISO C.)
-@item %e@r{,} %E
+@item @code{%e}, @code{%E}
Print a number in scientific (exponential) notation;
for example:
@@ -7666,7 +9315,7 @@ which follow the decimal point.
discussed in the next @value{SUBSECTION}.)
@samp{%E} uses @samp{E} instead of @samp{e} in the output.
-@item %f
+@item @code{%f}
Print a number in floating-point notation.
For example:
@@ -7680,45 +9329,46 @@ 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
+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}.
+@samp{inf} or @samp{infinity}.
+The special ``not a number'' value formats as @samp{-nan} or @samp{nan}
+(@pxref{Math Definitions}).
-@item %F
+@item @code{%F}
Like @samp{%f} but the infinity and ``not a number'' values are spelled
using uppercase letters.
The @samp{%F} format is a POSIX extension to ISO C; not all systems
support it. On those that don't, @command{gawk} uses @samp{%f} instead.
-@item %g@r{,} %G
+@item @code{%g}, @code{%G}
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
+@item @code{%o}
Print an unsigned octal integer
(@pxref{Nondecimal-numbers}).
-@item %s
+@item @code{%s}
Print a string.
-@item %u
+@item @code{%u}
Print 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.)
+are floating point; it is provided primarily for compatibility with C.)
-@item %x@r{,} %X
+@item @code{%x}, @code{%X}
Print an unsigned hexadecimal integer;
@samp{%X} uses the letters @samp{A} through @samp{F}
instead of @samp{a} through @samp{f}
(@pxref{Nondecimal-numbers}).
-@item %%
+@item @code{%%}
Print a single @samp{%}.
This does not consume an
argument and it ignores any modifiers.
@@ -7739,13 +9389,12 @@ values or do something else entirely.
@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
+We 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:
@@ -7753,7 +9402,7 @@ 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
+@c the code{} 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}.
@@ -7776,9 +9425,9 @@ 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.
+For now, we ignore them.
-@item -
+@item - (Minus)
The minus sign, used before the width modifier (see later on in
this list),
says to left-justify
@@ -7803,7 +9452,7 @@ 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.
+Use an ``alternative 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.
@@ -7812,7 +9461,7 @@ contains a decimal point.
For @samp{%g} and @samp{%G}, trailing zeros are not removed from the result.
@item 0
-A leading @samp{0} (zero) acts as a flag that indicates that output should be
+A leading @samp{0} (zero) acts as a flag indicating that output should be
padded with zeros instead of spaces.
This applies only to the numeric output formats.
This flag only has an effect when the field width is wider than the
@@ -7820,7 +9469,7 @@ value to print.
@item '
A single quote or apostrophe character is a POSIX extension to ISO C.
-It indicates that the integer part of a floating point value, or the
+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:
@@ -7829,7 +9478,7 @@ For example:
$ @kbd{cat thousands.awk} @ii{Show source program}
@print{} BEGIN @{ printf "%'d\n", 1234567 @}
$ @kbd{LC_ALL=C gawk -f thousands.awk}
-@print{} 1234567 @ii{Results in "C" locale}
+@print{} 1234567 @ii{Results in} "C" @ii{locale}
$ @kbd{LC_ALL=en_US.UTF-8 gawk -f thousands.awk}
@print{} 1,234,567 @ii{Results in US English UTF locale}
@end example
@@ -7901,7 +9550,7 @@ 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
+capability (e.g., @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:
@@ -7939,15 +9588,12 @@ 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 them.
-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
+C programmers may be used to supplying additional modifiers (@samp{h},
+@samp{j}, @samp{l}, @samp{L}, @samp{t}, and @samp{z}) in @code{printf}
+format strings. These are not valid in @command{awk}. Most @command{awk}
+implementations silently ignore them. 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.
@node Printf Examples
@subsection Examples Using @code{printf}
@@ -7956,30 +9602,30 @@ The following simple example shows
how to use @code{printf} to make an aligned table:
@example
-awk '@{ printf "%-10s %s\n", $1, $2 @}' BBS-list
+awk '@{ printf "%-10s %s\n", $1, $2 @}' mail-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 names of the people (@code{$1}) in the file
+@file{mail-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
-$ @kbd{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
+$ @kbd{awk '@{ printf "%-10s %s\n", $1, $2 @}' mail-list}
+@print{} Amelia 555-5553
+@print{} Anthony 555-3412
+@print{} Becky 555-7685
+@print{} Bill 555-1675
+@print{} Broderick 555-0542
+@print{} Camilla 555-2912
+@print{} Fabius 555-1234
+@print{} Julie 555-6699
+@print{} Martin 555-6480
+@print{} Samuel 555-3430
+@print{} Jean-Paul 555-2127
@end example
In this case, the phone numbers had to be printed as strings because
@@ -7992,7 +9638,7 @@ 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
+tops of the columns. This is done using a @code{BEGIN} rule
(@pxref{BEGIN/END})
so that the headers are only printed once, at the beginning of
the @command{awk} program:
@@ -8000,17 +9646,17 @@ the @command{awk} program:
@example
awk 'BEGIN @{ print "Name Number"
print "---- ------" @}
- @{ printf "%-10s %s\n", $1, $2 @}' BBS-list
+ @{ printf "%-10s %s\n", $1, $2 @}' mail-list
@end example
-The above example mixes @code{print} and @code{printf} statements in
+The preceding example mixes @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
+ @{ printf "%-10s %s\n", $1, $2 @}' mail-list
@end example
@noindent
@@ -8025,23 +9671,16 @@ 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
+ @{ printf format, $1, $2 @}' mail-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
-@cindex @code{--sandbox} option, output redirection with @code{print}, @code{printf}
+@cindex @option{--sandbox} option, output redirection with @code{print}, @code{printf}
So far, the output from @code{print} and @code{printf} has gone
to the standard
output, usually the screen. Both @code{print} and @code{printf} can
@@ -8050,7 +9689,7 @@ This is called @dfn{redirection}.
@quotation NOTE
When @option{--sandbox} is specified (@pxref{Options}),
-redirecting output to files and pipes is disabled.
+redirecting output to files, pipes and coprocesses is disabled.
@end quotation
A redirection appears after the @code{print} or @code{printf} statement.
@@ -8058,11 +9697,11 @@ 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
+@cindex @code{print} statement, See Also redirection@comma{} of output
+@cindex @code{printf} statement, See Also redirection@comma{} 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,
+to a coprocess. We show them all for the @code{print} statement,
but they work identically for @code{printf}:
@table @code
@@ -8080,20 +9719,20 @@ 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
+is how an @command{awk} program can write a list of peoples' names to one
file named @file{name-list}, and a list of phone numbers to another file
named @file{phone-list}:
@example
$ @kbd{awk '@{ print $2 > "phone-list"}
-> @kbd{print $1 > "name-list" @}' BBS-list}
+> @kbd{print $1 > "name-list" @}' mail-list}
$ @kbd{cat phone-list}
@print{} 555-5553
@print{} 555-3412
@dots{}
$ @kbd{cat name-list}
-@print{} aardvark
-@print{} alpo-net
+@print{} Amelia
+@print{} Anthony
@dots{}
@end example
@@ -8111,7 +9750,7 @@ 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 pipe, output
@cindex output, pipes
@item print @var{items} | @var{command}
It is possible to send output to another program through a pipe
@@ -8122,7 +9761,7 @@ 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
+files, one unsorted list of peoples' names, and one list sorted in reverse
alphabetical order:
@ignore
@@ -8135,7 +9774,7 @@ alone for now and let's hope no-one notices.
@example
awk '@{ print $1 > "names.unsorted"
command = "sort -r > names.sorted"
- print $1 | command @}' BBS-list
+ print $1 | command @}' mail-list
@end example
The unsorted list is written with an ordinary redirection, while
@@ -8147,27 +9786,21 @@ 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
+print("Awk script failed:", $0) | report
+print("at record number", FNR, "of", FILENAME) | 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},
+@DBXREF{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 (if you mean to refer to that same file or command)
-@command{awk} requires that the string value be spelled identically
+@command{awk} requires that the string value be written identically
every time.
@cindex coprocesses
@@ -8184,9 +9817,9 @@ but subsidiary to, the @command{awk} program.
This feature is a @command{gawk} extension, and is not available in
POSIX @command{awk}.
-@xref{Getline/Coprocess},
+@DBXREF{Getline/Coprocess}
for a brief discussion.
-@xref{Two-way I/O},
+@DBXREF{Two-way I/O}
for a more complete discussion.
@end table
@@ -8210,7 +9843,7 @@ print "Avoid improbability generators" >> "guide.txt"
@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
+use @samp{>} for all the @code{print} statements, because the output file
is only opened once. (It happens that if you mix @samp{>} and @samp{>>}
that output is produced in the expected order. However, mixing the operators
for the same file is definitely poor style, and is confusing to readers
@@ -8226,7 +9859,9 @@ As mentioned earlier
many
@end ifnotinfo
@ifnottex
+@ifnotdocbook
Many
+@end ifnotdocbook
@end ifnottex
older
@command{awk} implementations limit the number of pipelines that an @command{awk}
@@ -8234,9 +9869,12 @@ 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 sidebar, Piping into @command{sh}
+@ifdocbook
+@docbook
+<sidebar><title>Piping into @command{sh}</title>
+@end docbook
+
@cindex shells, piping commands into
A particularly powerful way to use redirection is to build command lines
@@ -8258,26 +9896,49 @@ uppercase characters converted to lowercase
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
+@DBXREF{Shell Quoting} for a function that can help in generating
+command lines to be fed to the shell.
-@command{gawk} provides a number of special @value{FN}s that it interprets
-internally. These @value{FN}s provide access to standard file descriptors
-and TCP/IP networking.
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
-@menu
-* Special FD:: Special files for I/O.
-* Special Network:: Special files for network communications.
-* Special Caveats:: Things to watch out for.
-@end menu
+@ifnotdocbook
+@cartouche
+@center @b{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.
+
+@DBXREF{Shell Quoting} for a function that can help in generating
+command lines to be fed to the shell.
+@end cartouche
+@end ifnotdocbook
@node Special FD
-@subsection Special Files for Standard Descriptors
+@section Special Files for Standard Pre-Opened Data Streams
@cindex standard input
@cindex input, standard
@cindex standard output
@@ -8288,9 +9949,12 @@ and TCP/IP networking.
@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 keyboard and screen, but
+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 open streams (and any other open file or pipe)
+are often referred to by the technical term @dfn{file descriptors}.
+
+These streams are, by default, connected to your keyboard and screen, 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
@@ -8299,7 +9963,7 @@ 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
+In traditional implementations of @command{awk}, the only way to write an error
message to standard error in an @command{awk} program is as follows:
@example
@@ -8309,7 +9973,8 @@ print "Serious error detected!" | "cat 1>&2"
@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
+@c 8/2014: Mike Brennan says not to cite this as inefficient. So, fixed.
+This is far from elegant, and it also requires a
separate process. So people writing @command{awk} programs often
don't do this. Instead, they send the error messages to the
screen, like this:
@@ -8324,19 +9989,19 @@ that is connected to your keyboard and screen. It represents the
``terminal,''@footnote{The ``tty'' in @file{/dev/tty} stands for
``Teletype,'' a serial terminal.} which on modern systems is a keyboard
and screen, not a serial console.)
-This usually has the same effect but not always: although the
+This generally has the same effect but not always: although the
standard error stream is usually the screen, it can be redirected; when
that happens, writing to the screen 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. @value{COMMONEXT}. It also provides syntax for accessing
-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}
+@command{gawk}, BWK @command{awk}, and @command{mawk} provide
+special @value{FN}s for accessing the three standard streams.
+If the @value{FN} matches one of these special names when @command{gawk}
+(or one of the others) redirects input or output, then it directly uses
+the descriptor 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 common extensions, @code{/dev/stdin} special file
@@ -8345,10 +10010,10 @@ has been ported to, not just those that are POSIX-compliant:
@cindex extensions, common@comma{} @code{/dev/stdin} special file
@cindex extensions, common@comma{} @code{/dev/stdout} special file
@cindex extensions, common@comma{} @code{/dev/stderr} special file
-@cindex @value{FN}s, standard streams in @command{gawk}
-@cindex @code{/dev/@dots{}} special files (@command{gawk})
+@cindex file names, standard streams in @command{gawk}
+@cindex @code{/dev/@dots{}} special files
@cindex files, @code{/dev/@dots{}} special files
-@cindex @code{/dev/fd/@var{N}} special files
+@cindex @code{/dev/fd/@var{N}} special files (@command{gawk})
@table @file
@item /dev/stdin
The standard input (file descriptor 0).
@@ -8358,38 +10023,64 @@ 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:
+With these facilities,
+the proper way to write an error message then becomes:
@example
print "Serious error detected!" > "/dev/stderr"
@end example
-@cindex troubleshooting, quotes with @value{FN}s
+@cindex troubleshooting, quotes with file names
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? :-)
-Finally, using the @code{close()} function on a @value{FN} of the
-form @code{"/dev/fd/@var{N}"}, for file descriptor numbers
-above two, will actually close the given file descriptor.
+@command{gawk} does not treat these @value{FN}s as special when
+in POSIX-compatibility mode. However, because BWK @command{awk}
+supports them, @command{gawk} does support them even when
+invoked with the @option{--traditional} option (@pxref{Options}).
-The @file{/dev/stdin}, @file{/dev/stdout}, and @file{/dev/stderr}
-special files are also recognized internally by several other
-versions of @command{awk}.
+@node Special Files
+@section Special @value{FFN}s in @command{gawk}
+@cindex @command{gawk}, file names in
+
+Besides access to standard input, standard output, and standard error,
+@command{gawk} provides access to any open file descriptor.
+Additionally, there are special @value{FN}s reserved for
+TCP/IP networking.
+
+@menu
+* Other Inherited Files:: Accessing other open files with
+ @command{gawk}.
+* Special Network:: Special files for network communications.
+* Special Caveats:: Things to watch out for.
+@end menu
+
+@node Other Inherited Files
+@subsection Accessing Other Open Files With @command{gawk}
+
+Besides the @code{/dev/stdin}, @code{/dev/stdout}, and @code{/dev/stderr}
+special @value{FN}s mentioned earlier, @command{gawk} provides syntax
+for accessing any other inherited open file:
+
+@table @file
+@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 essentially aliases for @file{/dev/fd/0}, @file{/dev/fd/1}, and
+@file{/dev/fd/2}, respectively. However, those names are more self-explanatory.
+
+Note that using @code{close()} on a @value{FN} of the
+form @code{"/dev/fd/@var{N}"}, for file descriptor numbers
+above two, does actually close the given file descriptor.
@node Special Network
@subsection Special Files for Network Communications
@@ -8405,7 +10096,7 @@ This is done using a special @value{FN} of the form:
@file{/@var{net-type}/@var{protocol}/@var{local-port}/@var{remote-host}/@var{remote-port}}
@end example
-The @var{net-type} is one of @samp{inet}, @samp{inet4} or @samp{inet6}.
+The @var{net-type} is one of @samp{inet}, @samp{inet4}, or @samp{inet6}.
The @var{protocol} is one of @samp{tcp} or @samp{udp},
and the other fields represent the other essential pieces of information
for making a networking connection.
@@ -8419,15 +10110,20 @@ Full discussion is delayed until
@node Special Caveats
@subsection Special @value{FFN} Caveats
-Here is a list of things to bear in mind when using the
+Here are some 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
+@itemize @value{BULLET}
+@cindex compatibility mode (@command{gawk}), file names
+@cindex file names, in compatibility mode
@item
-Recognition of these special @value{FN}s is disabled if @command{gawk} is in
-compatibility mode (@pxref{Options}).
+Recognition of the @value{FN}s for the three standard pre-opened
+files is disabled only in POSIX mode.
+
+@item
+Recognition of the other special @value{FN}s is disabled if @command{gawk} is in
+compatibility mode (either @option{--traditional} or @option{--posix};
+@pxref{Options}).
@item
@command{gawk} @emph{always}
@@ -8439,18 +10135,13 @@ 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 pipe, closing
@cindex coprocesses, closing
@cindex @code{getline} command, coprocesses@comma{} using from
@@ -8467,7 +10158,7 @@ the @value{FN} or command associated with it, 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
+@cindexawkfunc{close}
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
@@ -8519,7 +10210,7 @@ close(sortcom)
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
+@itemize @value{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
@@ -8552,6 +10243,7 @@ a separate message.
@cindex differences in @command{awk} and @command{gawk}, @code{close()} function
@cindex portability, @code{close()} function and
+@cindex @code{close()} function, portability
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
@@ -8587,15 +10279,17 @@ 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.
+@code{close()} silently does nothing if given an argument that
+does not represent a file, pipe, or coprocess that was opened with
+a redirection. In such a case, it returns a negative value,
+indicating an error. In addition, @command{gawk} sets @code{ERRNO}
+to a string indicating the error.
-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.
+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 with a
+redirection, so @command{awk} silently does nothing, except return
+a negative value.
@cindex @code{|} (vertical bar), @code{|&} operator (I/O), pipes@comma{} closing
When using the @samp{|&} operator to communicate with a coprocess,
@@ -8607,24 +10301,85 @@ 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
+As this is an advanced feature, discussion is
delayed until
@ref{Two-way I/O},
-which discusses it in more detail and gives an example.
+which describes it in more detail and gives an example.
+
+@cindex sidebar, Using @code{close()}'s Return Value
+@ifdocbook
+@docbook
+<sidebar><title>Using @code{close()}'s Return Value</title>
+@end docbook
-@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 @code{close()} function, return value
+@cindex return value@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
+In many older versions of Unix @command{awk}, the @code{close()} function
+is actually a statement.
+@value{DARKCORNER}
+It is a syntax error to try and use the return
value from @code{close()}:
+
+@example
+command = "@dots{}"
+command | getline info
+retval = close(command) # syntax error in many Unix awks
+@end example
+
+@cindex @command{gawk}, @code{ERRNO} variable in
+@cindex @code{ERRNO} variable, with @command{close()} function
+@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 predefined 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 nonzero otherwise. In general,
+different implementations vary in what they report when closing
+pipes; thus the return value cannot be used portably.
@value{DARKCORNER}
+In POSIX mode (@pxref{Options}), @command{gawk} just returns zero
+when closing a pipe.
+
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{Using @code{close()}'s Return Value}
+
+
+@cindex dark corner, @code{close()} function
+@cindex @code{close()} function, return value
+@cindex return value@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 older versions of Unix @command{awk}, the @code{close()} function
+is actually a statement.
+@value{DARKCORNER}
+It is a syntax error to try and use the return
+value from @code{close()}:
@example
command = "@dots{}"
@@ -8633,12 +10388,12 @@ retval = close(command) # syntax error in many Unix awks
@end example
@cindex @command{gawk}, @code{ERRNO} variable in
-@cindex @code{ERRNO} variable
+@cindex @code{ERRNO} variable, with @command{close()} function
@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
+In these cases, @command{gawk} sets the predefined variable
@code{ERRNO} to a string describing the problem.
In @command{gawk},
@@ -8660,16 +10415,75 @@ pipes; thus the return value cannot be used portably.
@value{DARKCORNER}
In POSIX mode (@pxref{Options}), @command{gawk} just returns zero
when closing a pipe.
+@end cartouche
+@end ifnotdocbook
+
+
+@node Output Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+The @code{print} statement prints comma-separated expressions. Each
+expression is separated by the value of @code{OFS} and terminated by
+the value of @code{ORS}. @code{OFMT} provides the conversion format
+for numeric values for the @code{print} statement.
+
+@item
+The @code{printf} statement provides finer-grained control over output,
+with format control letters for different data types and various flags
+that modify the behavior of the format control letters.
+
+@item
+Output from both @code{print} and @code{printf} may be redirected to
+files, pipes, and coprocesses.
+
+@item
+@command{gawk} provides special @value{FN}s for access to standard input,
+output, and error, and for network communications.
+
+@item
+Use @code{close()} to close open file, pipe, and coprocess redirections.
+For coprocesses, it is possible to close only one direction of the
+communications.
+
+@end itemize
+
+@c EXCLUDE START
+@node Output Exercises
+@section Exercises
+
+@enumerate
+@item
+Rewrite the program:
+
+@example
+awk 'BEGIN @{ print "Month Crates"
+ print "----- ------" @}
+ @{ print $1, " ", $2 @}' inventory-shipped
+@end example
+
+@noindent
+from @ref{Output Separators}, by using a new value of @code{OFS}.
+
+@item
+Use the @code{printf} statement to line up the headings and table data
+for the @file{inventory-shipped} example that was covered in @ref{Print}.
+
+@item
+What happens if you forget the double quotes when redirecting
+output, as follows:
+
+@example
+BEGIN @{ print "Serious error detected!" > /dev/stderr @}
+@end example
+
+@end enumerate
+@c EXCLUDE END
-@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
@@ -8691,10 +10505,11 @@ combinations of these with various operators.
* Function Calls:: A function call is an expression.
* Precedence:: How various operators nest.
* Locales:: How the locale affects things.
+* Expressions Summary:: Expressions summary.
@end menu
@node Values
-@section Constants, Variables and Conversions
+@section Constants, Variables, and Conversions
Expressions are built up from values and the operations performed
upon them. This @value{SECTION} describes the elementary objects
@@ -8710,6 +10525,7 @@ which provide the values used in expressions.
@node Constants
@subsection Constant Expressions
+
@cindex constants, types of
The simplest type of expression is the @dfn{constant}, which always has
@@ -8718,7 +10534,7 @@ 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.
+have different forms, but are internally stored in an identical manner.
@menu
* Scalar Constants:: Numeric and string constants.
@@ -8729,13 +10545,14 @@ have different forms, but are stored identically internally.
@node Scalar Constants
@subsubsection Numeric and String Constants
-@cindex numeric, constants
+@cindex constants, numeric
+@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.}
+including integers, uses double-precision floating-point numbers.
+On most modern systems, these are in IEEE 754 standard format.
+@xref{Arbitrary Precision Arithmetic}, for much more information.}
Here are some examples of numeric constants that all
have the same value:
@@ -8747,7 +10564,7 @@ have the same value:
@cindex string constants
A string constant consists of a sequence of characters enclosed in
-double-quotation marks. For example:
+double quotation marks. For example:
@example
"parrot"
@@ -8755,7 +10572,7 @@ double-quotation marks. For example:
@noindent
@cindex differences in @command{awk} and @command{gawk}, strings
-@cindex strings, length of
+@cindex strings, length limitations
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).
@@ -8769,13 +10586,13 @@ implementations may have difficulty with some character codes.
@cindex numbers, octal
@cindex numbers, hexadecimal
-In @command{awk}, all numbers are in decimal; i.e., base 10. Many other
+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.
+In octal, the numbers go 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, and so on.
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
+In hexadecimal, there are 16 digits. Because 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}
@@ -8827,11 +10644,12 @@ you can use the @code{strtonum()} function
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},
+see @DBREF{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:
+Unlike some early C implementations, @samp{8} and @samp{9} are not
+valid in octal constants. For example, @command{gawk} treats @samp{018}
+as decimal 18:
@example
$ @kbd{gawk 'BEGIN @{ print "021 is", 021 ; print 018 @}'}
@@ -8846,9 +10664,35 @@ 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
+@cindex sidebar, A Constant's Base Does Not Affect Its Value
+@ifdocbook
+@docbook
+<sidebar><title>A Constant's Base Does Not Affect Its Value</title>
+@end docbook
+
+
+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
+$ @kbd{gawk 'BEGIN @{ printf "0x11 is <%s>\n", 0x11 @}'}
+@print{} 0x11 is <17>
+@end example
+
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{A Constant's Base Does Not Affect Its Value}
+
+
Once a numeric constant has
been converted internally into a number,
@@ -8861,11 +10705,12 @@ numbers to strings:
$ @kbd{gawk 'BEGIN @{ printf "0x11 is <%s>\n", 0x11 @}'}
@print{} 0x11 is <17>
@end example
+@end cartouche
+@end ifnotdocbook
@node Regexp Constants
@subsubsection Regular Expression Constants
-@c STARTOFRANGE rec
@cindex regexp constants
@cindex @code{~} (tilde), @code{~} operator
@cindex tilde (@code{~}), @code{~} operator
@@ -8875,8 +10720,8 @@ 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
+(which are typically just ordinary strings or variables that contain a regexp,
+but could be a more complex expression).
@node Using Constant Regexps
@subsection Using Regular Expression Constants
@@ -8888,7 +10733,7 @@ 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/)}
+in a pattern (i.e., @samp{($0 ~ /foo/)}).
@value{DARKCORNER}
@xref{Expression Patterns}.
This means that the following two code segments:
@@ -8909,7 +10754,7 @@ if (/barfly/ || /camelot/)
@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
+Boolean expression is valid, but does not do what its author probably
intended:
@example
@@ -8943,22 +10788,21 @@ upon the contents of the current input record.
@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
+@cindexgawkfunc{gensub}
+@cindexawkfunc{sub}
+@cindexawkfunc{gsub}
Constant regular expressions are also used as the first argument for
the @code{gensub()}, @code{sub()}, and @code{gsub()} functions, as the
second argument of the @code{match()} function,
-and as the third argument of the @code{patsplit()} function
+and as the third argument of the @code{split()} and @code{patsplit()} functions
(@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:
+Because some built-in functions accept regexp constants as arguments,
+it can be confusing when attempting to use regexp constants as arguments
+to user-defined functions (@pxref{User-defined}). For example:
@example
function mysub(pat, repl, str, global)
@@ -8981,14 +10825,13 @@ function mysub(pat, repl, str, global)
@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
+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
+a parameter to a user-defined function, because passing a truth value in
this way is probably not what was intended.
-@c ENDOFRANGE rec
@node Variables
@subsection Variables
@@ -9002,7 +10845,7 @@ on the @command{awk} command line.
@menu
* Using Variables:: Using variables in your programs.
-* Assignment Options:: Setting variables on the command-line and a
+* Assignment Options:: Setting variables on the command line and a
summary of command-line syntax. This is an
advanced method of input.
@end menu
@@ -9013,7 +10856,11 @@ on the @command{awk} command line.
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}
+with a digit.
+Here, a @dfn{letter} is any one of the 52 upper- and lowercase
+English letters. Other characters that may be defined as letters
+in non-English locales are not valid in variable names.
+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
@@ -9022,24 +10869,24 @@ variable's current value. Variables are given new values with
@dfn{decrement operators}.
@xref{Assignment Ops}.
In addition, the @code{sub()} and @code{gsub()} functions can
-change a variable's value, and the @code{match()}, @code{patsplit()}
-and @code{split()} functions can change the contents of their
+change a variable's value, and the @code{match()}, @code{split()},
+and @code{patsplit()} functions can change the contents of their
array parameters. @xref{String Functions}.
@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
+record). @DBXREF{Built-in Variables} for a list of the predefined variables.
+These predefined 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.
+@command{awk}. All predefined 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 explicitly
-``initialize'' a variable in @command{awk},
+initialize a variable in @command{awk},
which is what you would do in C and in most other traditional languages.
@node Assignment Options
@@ -9056,7 +10903,7 @@ Such an assignment has the following form:
@var{variable}=@var{text}
@end example
-@cindex @code{-v} option, variables@comma{} assigning
+@cindex @option{-v} option
@noindent
With it, a variable is set either at the beginning of the
@command{awk} run or in between input files.
@@ -9071,14 +10918,14 @@ as in the following:
the variable is set at the very beginning, even before the
@code{BEGIN} rules execute. 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
+(@DBXREF{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
+awk '@{ print $n @}' n=4 inventory-shipped n=2 mail-list
@end example
@noindent
@@ -9087,10 +10934,10 @@ 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
@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}:
+second field is printed in lines from @file{mail-list}:
@example
-$ @kbd{awk '@{ print $n @}' n=4 inventory-shipped n=2 BBS-list}
+$ @kbd{awk '@{ print $n @}' n=4 inventory-shipped n=2 mail-list}
@print{} 15
@print{} 24
@dots{}
@@ -9111,6 +10958,19 @@ sequences
@node Conversion
@subsection Conversion of Strings and Numbers
+Number-to-string and string-to-number conversion are generally
+straightforward. There can be subtleties to be aware of;
+this @value{SECTION} discusses this important facet of @command{awk}.
+
+@menu
+* Strings And Numbers:: How @command{awk} Converts Between Strings And
+ Numbers.
+* Locale influences conversions:: How the locale may affect conversions.
+@end menu
+
+@node Strings And Numbers
+@subsubsection How @command{awk} Converts Between Strings and Numbers
+
@cindex converting, strings to numbers
@cindex strings, converting
@cindex numbers, converting
@@ -9140,19 +11000,19 @@ string, concatenate that number with the empty string, @code{""}.
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"}
+@code{"2.5"} converts to 2.5, @code{"1e3"} converts to 1,000, 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}).
+by the @command{awk} predefined 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
+@code{CONVFMT}'s default value is @code{"%.6g"}, which creates a value with
at most six significant digits. For some applications, you might want to
change it to specify more precision.
On most modern machines,
@@ -9180,6 +11040,12 @@ b = a ""
@code{b} has the value @code{"12"}, not @code{"12.00"}.
@value{DARKCORNER}
+@cindex sidebar, Pre-POSIX @command{awk} Used @code{OFMT} for String Conversion
+@ifdocbook
+@docbook
+<sidebar><title>Pre-POSIX @command{awk} Used @code{OFMT} for String Conversion</title>
+@end docbook
+
@cindex POSIX @command{awk}, @code{OFMT} variable and
@cindex @code{OFMT} variable
@cindex portability, new @command{awk} vs.@: old @command{awk}
@@ -9191,64 +11057,91 @@ specifies the output format to use when printing numbers with @code{print}.
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.
-
-And, 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.
+@DBXREF{Print} for more information on the @code{print} statement.
+
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{Pre-POSIX @command{awk} Used @code{OFMT} for String Conversion}
+
+@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.
+@DBXREF{Print} for more information on the @code{print} statement.
+@end cartouche
+@end ifnotdocbook
+
+@node Locale influences conversions
+@subsubsection Locales Can Influence Conversion
+
+Where you are can matter when it comes to converting between numbers and
+strings. The local character set and language---the @dfn{locale}---can
+affect numeric formats. In particular, for @command{awk} programs,
+it affects the decimal point character and the thousands-separator
+character. The @code{"C"} locale, and most English-language locales,
+use the period character (@samp{.}) as the decimal point and don't
+have a thousands separator. However, many (if not most) European and
+non-English locales use the comma (@samp{,}) as the decimal point
+character. European locales often use either a space or a period as
+the thousands separator, if they have one.
+
+@cindex dark corner, locale's 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.
-Here are some examples indicating the difference in behavior,
-on a GNU/Linux system:
+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. @value{DARKCORNER} In all cases, numbers in source code and
+in input data cannot have a thousands separator. Here are some examples
+indicating the difference in behavior, on a GNU/Linux system:
@example
+$ @kbd{export POSIXLY_CORRECT=1} @ii{Force POSIX behavior}
$ @kbd{gawk 'BEGIN @{ printf "%g\n", 3.1415927 @}'}
@print{} 3.14159
-$ @kbd{LC_ALL=en_DK gawk 'BEGIN @{ printf "%g\n", 3.1415927 @}'}
+$ @kbd{LC_ALL=en_DK.utf-8 gawk 'BEGIN @{ printf "%g\n", 3.1415927 @}'}
@print{} 3,14159
$ @kbd{echo 4,321 | gawk '@{ print $1 + 1 @}'}
@print{} 5
-$ @kbd{echo 4,321 | LC_ALL=en_DK gawk '@{ print $1 + 1 @}'}
+$ @kbd{echo 4,321 | LC_ALL=en_DK.utf-8 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 @code{en_DK.utf-8} 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, 4.321.
+treats @samp{4,321} as 4, while in the Danish locale, it's treated
+as the full number including the fractional part, 4.321.
Some earlier versions of @command{gawk} fully complied with this aspect
of the standard. However, many users in non-English locales complained
-about this behavior, since their data used a period as the decimal
+about this behavior, because their data used a period as the decimal
point, so the default behavior was restored to use a period as the
decimal point character. You can use the @option{--use-lc-numeric}
option (@pxref{Options}) to force @command{gawk} to use the locale's
decimal point character. (@command{gawk} also uses the locale's decimal
point character when in POSIX mode, either via @option{--posix}, or the
-@env{POSIXLY_CORRECT} environment variable.)
+@env{POSIXLY_CORRECT} environment variable, as shown previously.)
@ref{table-locale-affects} describes the cases in which the locale's decimal
point character is used and when a period is used. Some of these
features have not been described yet.
@float Table,table-locale-affects
-@caption{Locale Decimal Point versus A Period}
+@caption{Locale decimal point versus a period}
@multitable @columnfractions .15 .20 .45
@headitem Feature @tab Default @tab @option{--posix} or @option{--use-lc-numeric}
@item @code{%'g} @tab Use locale @tab Use locale
@@ -9258,13 +11151,13 @@ features have not been described yet.
@end multitable
@end float
-Finally, modern day formal standards and IEEE standard floating point
+Finally, modern day formal standards and IEEE standard floating-point
representation can have an unusual but important effect on the way
@command{gawk} converts some special string values to numbers. The details
are presented in @ref{POSIX Floating Point Problems}.
@node All Operators
-@section Operators: Doing Something With Values
+@section Operators: Doing Something with Values
This @value{SECTION} introduces the @dfn{operators} which make use
of the values provided by constants and variables.
@@ -9315,16 +11208,10 @@ $ @kbd{awk '@{ sum = $2 + $3 + $4 ; avg = sum / 3}
@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:
+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 common extensions, @code{**} operator
@cindex extensions, common@comma{} @code{**} operator
@cindex POSIX @command{awk}, arithmetic operators and
@@ -9334,6 +11221,12 @@ Exponentiation; @var{x} raised to the @var{y} power. @samp{2 ^ 3} has
the value eight; the character sequence @samp{**} is equivalent to
@samp{^}. @value{COMMONEXT}
+@item - @var{x}
+Negation.
+
+@item + @var{x}
+Unary plus; the expression is converted to a number.
+
@item @var{x} * @var{y}
Multiplication.
@@ -9343,7 +11236,7 @@ Multiplication.
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,
+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.)
@@ -9375,7 +11268,7 @@ 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:
+@samp{@var{x} % @var{y}} is negative if @var{x} is negative. Thus:
@example
-17 % 8 = -1
@@ -9383,7 +11276,7 @@ One possibly undesirable effect of this definition of remainder is that
In other @command{awk} implementations, the signedness of the remainder
may be machine-dependent.
-@c !!! what does posix say?
+@c FIXME !!! what does posix say?
@cindex portability, @code{**} operator and
@cindex @code{*} (asterisk), @code{**} operator
@@ -9398,8 +11291,8 @@ For maximum portability, do not use the @samp{**} operator.
@subsection String Concatenation
@cindex Kernighan, Brian
@quotation
-@i{It seemed like a good idea at the time.}@*
-Brian Kernighan
+@i{It seemed like a good idea at the time.}
+@author Brian Kernighan
@end quotation
@cindex string operators
@@ -9410,9 +11303,9 @@ specific operator to represent it. Instead, concatenation is performed by
writing expressions next to one another, with no operator. For example:
@example
-$ @kbd{awk '@{ print "Field number one: " $1 @}' BBS-list}
-@print{} Field number one: aardvark
-@print{} Field number one: alpo-net
+$ @kbd{awk '@{ print "Field number one: " $1 @}' mail-list}
+@print{} Field number one: Amelia
+@print{} Field number one: Anthony
@dots{}
@end example
@@ -9420,15 +11313,15 @@ Without the space in the string constant after the @samp{:}, the line
runs together. For example:
@example
-$ @kbd{awk '@{ print "Field number one:" $1 @}' BBS-list}
-@print{} Field number one:aardvark
-@print{} Field number one:alpo-net
+$ @kbd{awk '@{ print "Field number one:" $1 @}' mail-list}
+@print{} Field number one:Amelia
+@print{} Field number one:Anthony
@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
+often necessary to ensure that it happens at the right time by using
parentheses to enclose the items to concatenate. For example,
you might expect that the
following code fragment concatenates @code{file} and @code{name}:
@@ -9439,9 +11332,11 @@ name = "name"
print "something meaningful" > file name
@end example
+@cindex Brian Kernighan's @command{awk}
+@cindex @command{mawk} utility
@noindent
This produces a syntax error with some versions of Unix
-@command{awk}.@footnote{It happens that Brian Kernighan's
+@command{awk}.@footnote{It happens that BWK
@command{awk}, @command{gawk} and @command{mawk} all ``get it right,''
but you should not rely on this.}
It is necessary to use the following:
@@ -9467,7 +11362,7 @@ BEGIN @{
@end example
@noindent
-It is not defined whether the assignment to @code{a} happens
+It is not defined whether the second 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}.
@@ -9526,16 +11421,13 @@ Otherwise, it's parsed as follows:
@end display
As mentioned earlier,
-when doing concatenation, @emph{parenthesize}. Otherwise,
+when mixing concatenation with other operators, @emph{parenthesize}. Otherwise,
you're never quite sure what you'll get.
@node Assignment Ops
@subsection 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
@@ -9589,8 +11481,8 @@ 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
+A variable's type is simply the type of whatever value was last assigned
+to it. In the following program fragment, the variable
@code{foo} has a numeric value at first, and a string value later on:
@example
@@ -9688,9 +11580,17 @@ 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).
+and
+@ifnotdocbook
+@DBPXREF{Numeric Functions}
+@end ifnotdocbook
+@ifdocbook
+@DBREF{Numeric Functions}
+@end ifdocbook
+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:
@@ -9720,20 +11620,20 @@ to a number.
@cindex @code{*} (asterisk), @code{**=} operator
@cindex asterisk (@code{*}), @code{**=} operator
@float Table,table-assign-ops
-@caption{Arithmetic Assignment Operators}
+@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}.
+@item @var{lvalue} @code{+=} @var{increment} @tab Add @var{increment} to the value of @var{lvalue}
+@item @var{lvalue} @code{-=} @var{decrement} @tab Subtract @var{decrement} from the value of @var{lvalue}
+@item @var{lvalue} @code{*=} @var{coefficient} @tab Multiply the value of @var{lvalue} by @var{coefficient}
+@item @var{lvalue} @code{/=} @var{divisor} @tab Divide the value of @var{lvalue} by @var{divisor}
+@item @var{lvalue} @code{%=} @var{modulus} @tab Set @var{lvalue} to its remainder by @var{modulus}
@cindex common extensions, @code{**=} operator
@cindex extensions, common@comma{} @code{**=} operator
@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}. @value{COMMONEXT}
+@item @var{lvalue} @code{**=} @var{power} @tab Raise @var{lvalue} to the power @var{power} @value{COMMONEXT}
@end multitable
@end float
@@ -9744,9 +11644,12 @@ 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 sidebar, Syntactic Ambiguities Between @samp{/=} and Regular Expressions
+@ifdocbook
+@docbook
+<sidebar><title>Syntactic Ambiguities Between @samp{/=} and Regular Expressions</title>
+@end docbook
+
@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
@@ -9755,18 +11658,64 @@ For maximum portability, do not use the @samp{**=} operator.
@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 dark corner, @code{/=} operator vs. @code{/=@dots{}/} regexp constant
+@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 @code{/=} assignment
+operator and regexp constants whose first character is an @samp{=}.
+@value{DARKCORNER}
+This is most notable in some commercial @command{awk} versions.
+For example:
+
+@example
+$ @kbd{awk /==/ /dev/null}
+@error{} awk: syntax error at source line 1
+@error{} context is
+@error{} >>> /= <<<
+@error{} awk: bailing out at source line 1
+@end example
+
+@noindent
+A workaround is:
+
+@example
+awk '/[=]=/' /dev/null
+@end example
+
+@command{gawk} does not have this problem; BWK @command{awk}
+and @command{mawk} also do not.
+
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{Syntactic Ambiguities Between @samp{/=} and Regular Expressions}
+
+
+@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, @code{/=} operator vs. @code{/=@dots{}/} regexp constant
@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 @code{/=} assignment
operator and regexp constants whose first character is an @samp{=}.
@value{DARKCORNER}
-This is most notable in commercial @command{awk} versions.
+This is most notable in some commercial @command{awk} versions.
For example:
@example
-$ awk /==/ /dev/null
+$ @kbd{awk /==/ /dev/null}
@error{} awk: syntax error at source line 1
@error{} context is
@error{} >>> /= <<<
@@ -9780,20 +11729,15 @@ A workaround is:
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
+@command{gawk} does not have this problem; BWK @command{awk}
+and @command{mawk} also do not.
+@end cartouche
+@end ifnotdocbook
@node Increment Ops
@subsection 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
@@ -9801,16 +11745,15 @@ the increment operators add no power to the @command{awk} language; however, the
are convenient abbreviations for very common operations.
@cindex side effects
-@cindex @code{+} (plus sign), @code{++} (decrement/increment operators)
-@cindex plus sign (@code{+}), @code{++} (decrement/increment operators)
+@cindex @code{+} (plus sign), @code{++} operator
+@cindex plus sign (@code{+}), @code{++} operator
@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
+To @dfn{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
+expression. (The assignment expression @samp{v += 1} is completely equivalent.)
+Writing the @samp{++} after the variable specifies @dfn{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++}
@@ -9820,9 +11763,20 @@ 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
+@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).
+long as you stick to numbers that are fairly small (less than
+@iftex
+@math{10^{12}}).
+@end iftex
+@ifnottex
+@ifnotdocbook
+10e12).
+@end ifnotdocbook
+@end ifnottex
+@docbook
+10<superscript>12</superscript>). @c
+@end docbook
@cindex @code{$} (dollar sign), incrementing fields and arrays
@cindex dollar sign (@code{$}), incrementing fields and arrays
@@ -9863,9 +11817,64 @@ as the value of the expression.
like @samp{@var{lvalue}++}, but instead of adding, it subtracts.)
@end table
-@c fakenode --- for prepinfo
-@subheading Advanced Notes: Operator Evaluation Order
-@cindex advanced features, operators@comma{} precedence
+@cindex sidebar, Operator Evaluation Order
+@ifdocbook
+@docbook
+<sidebar><title>Operator Evaluation Order</title>
+@end docbook
+
+@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!}
+@author 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.
+
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{Operator Evaluation Order}
+
+
@cindex precedence
@cindex operators, precedence
@cindex portability, operators
@@ -9873,8 +11882,8 @@ like @samp{@var{lvalue}++}, but instead of adding, it subtracts.)
@cindex Marx, Groucho
@quotation
@i{Doctor, doctor! It hurts when I do this!@*
-So don't do that!}@*
-Groucho Marx
+So don't do that!}
+@author Groucho Marx
@end quotation
@noindent
@@ -9907,15 +11916,14 @@ 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
+@end cartouche
+@end ifnotdocbook
@node Truth Values and Conditions
@section Truth Values and Conditions
-In certain contexts, expression values also serve as ``truth values;'' i.e.,
-they determine what should happen next as the program runs. This
+In certain contexts, expression values also serve as ``truth values''; (i.e.,
+they determine what should happen next as the program runs). This
@value{SECTION} describes how @command{awk} defines ``true'' and ``false''
and how values are compared.
@@ -9962,7 +11970,7 @@ BEGIN @{
@}
@end example
-@cindex dark corner
+@cindex dark corner, @code{"0"} is actually true
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}
@@ -9970,21 +11978,17 @@ the string constant @code{"0"} is actually true, because it is non-null.
@node Typing and Comparison
@subsection Variable Typing and Comparison Expressions
@quotation
-@i{The Guide is definitive. Reality is frequently inaccurate.}@*
-The Hitchhiker's Guide to the Galaxy
+@i{The Guide is definitive. Reality is frequently inaccurate.}
+@author Douglas Adams, @cite{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
@@ -9999,25 +12003,21 @@ compares variables.
@end menu
@node Variable Typing
-@subsubsection String Type Versus Numeric Type
+@subsubsection String Type versus Numeric Type
@cindex numeric, strings
@cindex strings, numeric
@cindex POSIX @command{awk}, numeric strings and
-The 1992 POSIX standard introduced
+The 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.
-The various versions of the POSIX standard did not get the rules
-quite right for several editions. Fortunately, as of at least the
-2008 standard (and possibly earlier), the standard has been fixed,
-and variable typing follows these rules:@footnote{@command{gawk} has
-followed these rules for many years,
-and it is gratifying that the POSIX standard is also now correct.}
+Variable typing follows these rules:
+
-@itemize @bullet
+@itemize @value{BULLET}
@item
A numeric constant or the result of a numeric operation has the @var{numeric}
attribute.
@@ -10029,7 +12029,7 @@ attribute.
@item
Fields, @code{getline} input, @code{FILENAME}, @code{ARGV} elements,
@code{ENVIRON} elements, and the elements of an array created by
-@code{patsplit()}, @code{split()} and @code{match()} that are numeric
+@code{match()}, @code{split()}, and @code{patsplit()} that are numeric
strings have the @var{strnum} attribute. Otherwise, they have
the @var{string} attribute. Uninitialized variables also have the
@var{strnum} attribute.
@@ -10103,6 +12103,7 @@ STRNUM &&string &numeric &numeric\cr
}}}
@end tex
@ifnottex
+@ifnotdocbook
@display
+----------------------------------------------
| STRING NUMERIC STRNUM
@@ -10115,7 +12116,51 @@ NUMERIC | string numeric numeric
STRNUM | string numeric numeric
--------+----------------------------------------------
@end display
+@end ifnotdocbook
@end ifnottex
+@docbook
+<informaltable>
+<tgroup cols="4">
+<colspec colname="1" align="left"/>
+<colspec colname="2" align="left"/>
+<colspec colname="3" align="left"/>
+<colspec colname="4" align="left"/>
+<thead>
+<row>
+<entry/>
+<entry>STRING</entry>
+<entry>NUMERIC</entry>
+<entry>STRNUM</entry>
+</row>
+</thead>
+
+<tbody>
+<row>
+<entry><emphasis role="bold">STRING</emphasis></entry>
+<entry>string</entry>
+<entry>string</entry>
+<entry>string</entry>
+</row>
+
+<row>
+<entry><emphasis role="bold">NUMERIC</emphasis></entry>
+<entry>string</entry>
+<entry>numeric</entry>
+<entry>numeric</entry>
+</row>
+
+<row>
+<entry><emphasis role="bold">STRNUM</emphasis></entry>
+<entry>string</entry>
+<entry>numeric</entry>
+<entry>numeric</entry>
+</row>
+
+</tbody>
+</tgroup>
+</informaltable>
+
+@end docbook
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
@@ -10123,7 +12168,7 @@ made of characters and is therefore also a string.
Thus, for example, the string constant @w{@code{" +3.14"}},
when it appears in program source code,
is a string---even though it looks numeric---and
-is @emph{never} treated as number for comparison
+is @emph{never} treated as a number for comparison
purposes.
In short, when one operand is a ``pure'' string, such as a string
@@ -10134,27 +12179,28 @@ This point bears additional emphasis: All user input is made of characters,
and so is first and foremost of @var{string} type; input strings
that look numeric are additionally given the @var{strnum} attribute.
Thus, the six-character input string @w{@samp{ +3.14}} receives the
-@var{strnum} attribute. In contrast, the eight-character literal
-@w{@code{" +3.14"}} appearing in program text is a string constant.
+@var{strnum} attribute. In contrast, the eight characters
+@w{@code{" +3.14"}} appearing in program text comprise a string constant.
The following examples print @samp{1} when the comparison between
the two different constants is true, @samp{0} otherwise:
+@c 22.9.2014: Tested with mawk and BWK awk, got same results.
@example
-$ @kbd{echo ' +3.14' | gawk '@{ print $0 == " +3.14" @}'} @ii{True}
+$ @kbd{echo ' +3.14' | awk '@{ print($0 == " +3.14") @}'} @ii{True}
@print{} 1
-$ @kbd{echo ' +3.14' | gawk '@{ print $0 == "+3.14" @}'} @ii{False}
+$ @kbd{echo ' +3.14' | awk '@{ print($0 == "+3.14") @}'} @ii{False}
@print{} 0
-$ @kbd{echo ' +3.14' | gawk '@{ print $0 == "3.14" @}'} @ii{False}
+$ @kbd{echo ' +3.14' | awk '@{ print($0 == "3.14") @}'} @ii{False}
@print{} 0
-$ @kbd{echo ' +3.14' | gawk '@{ print $0 == 3.14 @}'} @ii{True}
+$ @kbd{echo ' +3.14' | awk '@{ print($0 == 3.14) @}'} @ii{True}
@print{} 1
-$ @kbd{echo ' +3.14' | gawk '@{ print $1 == " +3.14" @}'} @ii{False}
+$ @kbd{echo ' +3.14' | awk '@{ print($1 == " +3.14") @}'} @ii{False}
@print{} 0
-$ @kbd{echo ' +3.14' | gawk '@{ print $1 == "+3.14" @}'} @ii{True}
+$ @kbd{echo ' +3.14' | awk '@{ print($1 == "+3.14") @}'} @ii{True}
@print{} 1
-$ @kbd{echo ' +3.14' | gawk '@{ print $1 == "3.14" @}'} @ii{False}
+$ @kbd{echo ' +3.14' | awk '@{ print($1 == "3.14") @}'} @ii{False}
@print{} 0
-$ @kbd{echo ' +3.14' | gawk '@{ print $1 == 3.14 @}'} @ii{True}
+$ @kbd{echo ' +3.14' | awk '@{ print($1 == 3.14) @}'} @ii{True}
@print{} 1
@end example
@@ -10184,18 +12230,18 @@ operators}, which are a superset of those in C.
@cindex exclamation point (@code{!}), @code{!~} operator
@cindex @code{in} operator
@float Table,table-relational-ops
-@caption{Relational Operators}
+@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}.
+@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
@@ -10228,30 +12274,29 @@ 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:
+The following list of expressions illustrates the kinds of comparisons
+@command{awk} performs, as well as what the result of each comparison is:
@table @code
@item 1.5 <= 2.0
-numeric comparison (true)
+Numeric comparison (true)
@item "abc" >= "xyz"
-string comparison (false)
+String comparison (false)
@item 1.5 != " +2"
-string comparison (true)
+String comparison (true)
@item "1e2" < "3"
-string comparison (true)
+String comparison (true)
@item a = 2; b = "2"
@itemx a == b
-string comparison (true)
+String comparison (true)
@item a = 2; b = " +2"
-@item a == b
-string comparison (false)
+@itemx a == b
+String comparison (false)
@end table
In this example:
@@ -10296,15 +12341,15 @@ has the value one if @code{x} contains @samp{foo}, such as
@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
+either a regexp constant (@code{/}@dots{}@code{/}) 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
+A constant regular
+expression in slashes by itself is also an expression.
@code{/@var{regexp}/} is an abbreviation for the following comparison expression:
@example
@@ -10318,10 +12363,12 @@ One special place where @code{/foo/} is @emph{not} an abbreviation for
where this is discussed in more detail.
@node POSIX String Comparison
-@subsubsection String Comparison With POSIX Rules
+@subsubsection String Comparison with POSIX Rules
The POSIX standard says that string comparison is performed based
-on the locale's collating order. This is usually very different
+on the locale's @dfn{collating order}. This is the order in which
+characters sort, as defined by the locale (for more discussion,
+@pxref{Locales}). This order is usually very different
from the results obtained when doing straight character-by-character
comparison.@footnote{Technically, string comparison is supposed
to behave the same way as if the strings are compared with the C
@@ -10329,7 +12376,7 @@ to behave the same way as if the strings are compared with the C
Because this behavior differs considerably from existing practice,
@command{gawk} only implements it when in POSIX mode (@pxref{Options}).
-Here is an example to illustrate the difference, in an @samp{en_US.UTF-8}
+Here is an example to illustrate the difference, in an @code{en_US.UTF-8}
locale:
@example
@@ -10341,19 +12388,13 @@ $ @kbd{gawk --posix 'BEGIN @{ printf("ABC < abc = %s\n",}
@print{} ABC < abc = FALSE
@end example
-@c ENDOFRANGE comex
-@c ENDOFRANGE excom
-@c ENDOFRANGE vartypc
-@c ENDOFRANGE varting
@node Boolean Ops
@subsection 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
@@ -10384,10 +12425,10 @@ The Boolean operators are:
@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}:
+both @samp{edu} and @samp{li}:
@example
-if ($0 ~ /2400/ && $0 ~ /foo/) print
+if ($0 ~ /edu/ && $0 ~ /li/) print
@end example
@cindex side effects, Boolean operators
@@ -10400,16 +12441,19 @@ 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:
+that contain @emph{either} @samp{edu} or
+@samp{li}:
@example
-if ($0 ~ /2400/ || $0 ~ /foo/) print
+if ($0 ~ /edu/ || $0 ~ /li/) 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.
+(Thus, this test never really distinguishes records that contain both
+@samp{edu} and @samp{li}---as soon as @samp{edu} is matched,
+the full test succeeds.)
@item ! @var{boolean}
True if @var{boolean} is false. For example,
@@ -10419,7 +12463,7 @@ variable is not defined:
@example
BEGIN @{ if (! ("HOME" in ENVIRON))
- print "no home!" @}
+ print "no home!" @}
@end example
(The @code{in} operator is described in
@@ -10438,7 +12482,7 @@ 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
+Statements that end with @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}).
@@ -10457,7 +12501,7 @@ program is one way to print lines in between special bracketing lines:
@example
$1 == "START" @{ interested = ! interested; next @}
-interested == 1 @{ print @}
+interested @{ print @}
$1 == "END" @{ interested = ! interested; next @}
@end example
@@ -10477,6 +12521,16 @@ bogus input data, but the point is to illustrate the use of `!',
so we'll leave well enough alone.
@end ignore
+Most commonly, the @samp{!} operator is used in the conditions of
+@code{if} and @code{while} statements, where it often makes more
+sense to phrase the logic in the negative:
+
+@example
+if (! @var{some condition} || @var{some other condition}) @{
+ @var{@dots{} do whatever processing @dots{}}
+@}
+@end example
+
@cindex @code{next} statement
@quotation NOTE
The @code{next} statement is discussed in
@@ -10486,8 +12540,6 @@ 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
@subsection Conditional Expressions
@@ -10545,7 +12597,7 @@ 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.
+(@pxref{Options}), this extension is disabled.
@node Function Calls
@section Function Calls
@@ -10559,11 +12611,13 @@ 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
+of these. @DBXREF{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},
+@DBXREF{User-defined}
for instructions on how to do this.
+Finally, @command{gawk} lets you write functions in C or C++
+that may be called from your program (@pxref{Dynamic Extensions}).
@cindex arguments, in function calls
The way to use a function is with a @dfn{function call} expression,
@@ -10582,7 +12636,7 @@ rand() @ii{no arguments}
@cindex troubleshooting, function call syntax
@quotation CAUTION
-Do not put any space between the function name and the open-parenthesis!
+Do not put any space between the function name and the opening 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.
@@ -10603,9 +12657,11 @@ 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
+@DBXREF{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
+treated as local variables. Such local variables act like the
+empty string if referenced where a string value is required,
+and like zero if referenced where a numeric value is required
(@pxref{User-defined}).
As an advanced feature, @command{gawk} provides indirect function calls,
@@ -10614,12 +12670,12 @@ when you write the source code to your program. We defer discussion of
this feature until later; see @ref{Indirect Calls}.
@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}.
-The following program reads numbers, one number per line, and prints the
-square root of each one:
+Like every other expression, the function call has a value, often
+called the @dfn{return value}, which is computed by the function
+based on the arguments you give it. In this example, the return value
+of @samp{sqrt(@var{argument})} is the square root of @var{argument}.
+The following program reads numbers, one number per line, and prints
+the square root of each one:
@example
$ @kbd{awk '@{ print "The square root of", $1, "is", sqrt($1) @}'}
@@ -10629,7 +12685,7 @@ $ @kbd{awk '@{ print "The square root of", $1, "is", sqrt($1) @}'}
@print{} The square root of 3 is 1.73205
@kbd{5}
@print{} The square root of 5 is 2.23607
-@kbd{@value{CTL}-d}
+@kbd{Ctrl-d}
@end example
A function can also have side effects, such as assigning
@@ -10662,9 +12718,7 @@ $ @kbd{awk -f matchit.awk}
@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
@@ -10704,31 +12758,31 @@ expression because the first @samp{$} has higher precedence than the
@samp{++}; to avoid the problem the expression can be rewritten as
@samp{$($0++)--}.
-This table presents @command{awk}'s operators, in order of highest
+This list 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{})
+@c @asis for docbook to come out right
+@table @asis
+@item @code{(}@dots{}@code{)}
Grouping.
@cindex @code{$} (dollar sign), @code{$} field operator
@cindex dollar sign (@code{$}), @code{$} field operator
-@item $
+@item @code{$}
Field reference.
@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 ++ --
+@cindex @code{-} (hyphen), @code{--} operator
+@cindex hyphen (@code{-}), @code{--} operator
+@item @code{++ --}
Increment, decrement.
@cindex @code{^} (caret), @code{^} operator
@cindex caret (@code{^}), @code{^} operator
@cindex @code{*} (asterisk), @code{**} operator
@cindex asterisk (@code{*}), @code{**} operator
-@item ^ **
+@item @code{^ **}
Exponentiation. These operators group right-to-left.
@cindex @code{+} (plus sign), @code{+} operator
@@ -10737,7 +12791,7 @@ Exponentiation. These operators group right-to-left.
@cindex hyphen (@code{-}), @code{-} operator
@cindex @code{!} (exclamation point), @code{!} operator
@cindex exclamation point (@code{!}), @code{!} operator
-@item + - !
+@item @code{+ - !}
Unary plus, minus, logical ``not.''
@cindex @code{*} (asterisk), @code{*} operator, as multiplication operator
@@ -10746,17 +12800,17 @@ Unary plus, minus, logical ``not.''
@cindex forward slash (@code{/}), @code{/} operator
@cindex @code{%} (percent sign), @code{%} operator
@cindex percent sign (@code{%}), @code{%} operator
-@item * / %
+@item @code{* / %}
Multiplication, division, remainder.
@cindex @code{+} (plus sign), @code{+} operator
@cindex plus sign (@code{+}), @code{+} operator
@cindex @code{-} (hyphen), @code{-} operator
@cindex hyphen (@code{-}), @code{-} operator
-@item + -
+@item @code{+ -}
Addition, subtraction.
-@item @r{String Concatenation}
+@item String concatenation
There is no special symbol for concatenation.
The operands are simply written side by side
(@pxref{Concatenation}).
@@ -10782,7 +12836,7 @@ The operands are simply written side by side
@cindex @code{|} (vertical bar), @code{|&} operator (I/O)
@cindex vertical bar (@code{|}), @code{|&} operator (I/O)
@cindex operators, input/output
-@item < <= == != > >= >> | |&
+@item @code{< <= == != > >= >> | |&}
Relational and redirection.
The relational operators and the redirections have the same precedence
level. Characters such as @samp{>} serve both as relationals and as
@@ -10795,7 +12849,7 @@ 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}),
+parentheses. Such combinations (e.g., @samp{print foo > a ? b : c}),
result in syntax errors.
The correct way to write this statement is @samp{print foo > (a ? b : c)}.
@@ -10803,26 +12857,26 @@ The correct way to write this statement is @samp{print foo > (a ? b : c)}.
@cindex tilde (@code{~}), @code{~} operator
@cindex @code{!} (exclamation point), @code{!~} operator
@cindex exclamation point (@code{!}), @code{!~} operator
-@item ~ !~
+@item @code{~ !~}
Matching, nonmatching.
@cindex @code{in} operator
-@item in
+@item @code{in}
Array membership.
@cindex @code{&} (ampersand), @code{&&} operator
@cindex ampersand (@code{&}), @code{&&} operator
-@item &&
+@item @code{&&}
Logical ``and''.
@cindex @code{|} (vertical bar), @code{||} operator
@cindex vertical bar (@code{|}), @code{||} operator
-@item ||
+@item @code{||}
Logical ``or''.
@cindex @code{?} (question mark), @code{?:} operator
@cindex question mark (@code{?}), @code{?:} operator
-@item ?:
+@item @code{?:}
Conditional. This operator groups right-to-left.
@cindex @code{+} (plus sign), @code{+=} operator
@@ -10839,7 +12893,7 @@ Conditional. This operator groups right-to-left.
@cindex percent sign (@code{%}), @code{%=} operator
@cindex @code{^} (caret), @code{^=} operator
@cindex caret (@code{^}), @code{^=} operator
-@item = += -= *= /= %= ^= **=
+@item @code{= += -= *= /= %= ^= **=}
Assignment. These operators group right-to-left.
@end table
@@ -10849,46 +12903,118 @@ Assignment. These operators group right-to-left.
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
@node Locales
-@section Where You Are Makes A Difference
+@section Where You Are Makes a Difference
@cindex locale, definition of
-Modern systems support the notion of @dfn{locales}: a way to tell
-the system about the local character set and language.
+Modern systems support the notion of @dfn{locales}: a way to tell the
+system about the local character set and language. The ISO C standard
+defines a default @code{"C"} locale, which is an environment that is
+typical of what many C programmers are used to.
-Once upon a time, the locale setting used to affect regexp matching
-(@pxref{Ranges and Locales}), but this is no longer true.
+Once upon a time, the locale setting used to affect regexp matching,
+but this is no longer true (@pxref{Ranges and Locales}).
-Locales can affect record splitting.
-For the normal case of @samp{RS = "\n"}, the locale is largely irrelevant.
-For other single-character record separators, setting @samp{LC_ALL=C}
-in the environment
-will give you much better performance when reading records. Otherwise,
+Locales can affect record splitting. For the normal case of @samp{RS =
+"\n"}, the locale is largely irrelevant. For other single-character
+record separators, setting @samp{LC_ALL=C} in the environment 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.
-According to POSIX, string comparison is also affected by locales
-(similar to regular expressions). The details are presented in
-@ref{POSIX String Comparison}.
+Locales can affect how dates and times are formatted (@pxref{Time
+Functions}). For example, a common way to abbreviate the date September
+4, 2015, in the United States is ``9/4/15.'' In many countries in
+Europe, however, it is abbreviated ``4.9.15.'' Thus, the @samp{%x}
+specification in a @code{"US"} locale might produce @samp{9/4/15},
+while in a @code{"EUROPE"} locale, it might produce @samp{4.9.15}.
+
+According to POSIX, string comparison is also affected by locales (similar
+to regular expressions). The details are presented in @ref{POSIX String
+Comparison}.
Finally, the locale affects the value of the decimal point character
-used when @command{gawk} parses input data. This is discussed in
-detail in @ref{Conversion}.
+used when @command{gawk} parses input data. This is discussed in detail
+in @ref{Conversion}.
+
+@node Expressions Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+Expressions are the basic elements of computation in programs. They are
+built from constants, variables, function calls, and combinations of the
+various kinds of values with operators.
+
+@item
+@command{awk} supplies three kinds of constants: numeric, string, and
+regexp. @command{gawk} lets you specify numeric constants in octal
+and hexadecimal (bases 8 and 16) as well as decimal (base 10).
+In certain contexts, a standalone regexp constant such as @code{/foo/}
+has the same meaning as @samp{$0 ~ /foo/}.
+
+@item
+Variables hold values between uses in computations. A number of built-in
+variables provide information to your @command{awk} program, and a number
+of others let you control how @command{awk} behaves.
+
+@item
+Numbers are automatically converted to strings, and strings to numbers,
+as needed by @command{awk}. Numeric values are converted as if they were
+formatted with @code{sprintf()} using the format in @code{CONVFMT}.
+Locales can influence the conversions.
+
+@item
+@command{awk} provides the usual arithmetic operators (addition,
+subtraction, multiplication, division, modulus), and unary plus and minus.
+It also provides comparison operators, boolean operators, array membership
+testing, and regexp
+matching operators. String concatenation is accomplished by placing
+two expressions next to each other; there is no explicit operator.
+The three-operand @samp{?:} operator provides an ``if-else'' test within
+expressions.
+
+@item
+Assignment operators provide convenient shorthands for common arithmetic
+operations.
+
+@item
+In @command{awk}, a value is considered to be true if it is non-zero
+@emph{or} non-null. Otherwise, the value is false.
+
+@item
+A variable's type is set upon each assignment and may change over its
+lifetime. The type determines how it behaves in comparisons (string
+or numeric).
+
+@item
+Function calls return a value which may be used as part of a larger
+expression. Expressions used to pass parameter values are fully
+evaluated before the function is called. @command{awk} provides
+built-in and user-defined functions; this is described in
+@ref{Functions}.
+
+@item
+Operator precedence specifies the order in which operations are performed,
+unless explicitly overridden by parentheses. @command{awk}'s operator
+precedence is compatible with that of C.
+
+@item
+Locales can affect the format of data as output by an @command{awk}
+program, and occasionally the format for data read as input.
+
+@end itemize
-@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.
+actions, and @command{awk}'s predefined variables.
The pattern-action rules and the statements available for use
within actions form the core of @command{awk} programming.
@@ -10903,7 +13029,8 @@ building something useful.
* Action Overview:: What goes into an action.
* Statements:: Describes the various control statements in
detail.
-* Built-in Variables:: Summarizes the built-in variables.
+* Built-in Variables:: Summarizes the predefined variables.
+* Pattern Action Summary:: Patterns and Actions summary.
@end menu
@node Pattern Overview
@@ -10934,10 +13061,10 @@ 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}.
+@item @var{begpat}, @var{endpat}
+A pair of patterns separated by a comma, specifying a @dfn{range} of records.
+The range includes both the initial record that matches @var{begpat} and
+the final record that matches @var{endpat}.
(@xref{Ranges}.)
@item BEGIN
@@ -10948,8 +13075,8 @@ Special patterns for you to supply startup or cleanup actions for your
@item BEGINFILE
@itemx ENDFILE
-Special patterns for you to supply startup or cleanup actions to
-done on a per file basis.
+Special patterns for you to supply startup or cleanup actions to be
+done on a per-file basis.
(@xref{BEGINFILE/ENDFILE}.)
@item @var{empty}
@@ -10999,7 +13126,7 @@ 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}:
+whose first field is precisely @samp{li}:
@cindex @code{/} (forward slash), patterns and
@cindex forward slash (@code{/}), patterns and
@@ -11008,68 +13135,64 @@ whose first field is precisely @samp{foo}:
@cindex @code{!} (exclamation point), @code{!~} operator
@cindex exclamation point (@code{!}), @code{!~} operator
@example
-$ @kbd{awk '$1 == "foo" @{ print $2 @}' BBS-list}
+$ @kbd{awk '$1 == "li" @{ print $2 @}' mail-list}
@end example
@noindent
-(There is no output, because there is no BBS site with the exact name @samp{foo}.)
+(There is no output, because there is no person with the exact name @samp{li}.)
Contrast this with the following regular expression match, which
-accepts any record with a first field that contains @samp{foo}:
+accepts any record with a first field that contains @samp{li}:
@example
-$ @kbd{awk '$1 ~ /foo/ @{ print $2 @}' BBS-list}
-@print{} 555-1234
+$ @kbd{awk '$1 ~ /li/ @{ print $2 @}' mail-list}
+@print{} 555-5553
@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}.
+pattern. The expression @code{/li/} has the value one if @samp{li}
+appears in the current input record. Thus, as a pattern, @code{/li/}
+matches any record containing @samp{li}.
@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}:
+@file{mail-list} that contain both @samp{edu} and @samp{li}:
@example
-$ @kbd{awk '/2400/ && /foo/' BBS-list}
-@print{} fooey 555-1234 2400/1200/300 B
+$ @kbd{awk '/edu/ && /li/' mail-list}
+@print{} Samuel 555-3430 samuel.lanceolis@@shu.edu A
@end example
The following command prints all records in
-@file{BBS-list} that contain @emph{either} @samp{2400} or @samp{foo}
+@file{mail-list} that contain @emph{either} @samp{edu} or @samp{li}
(or both, of course):
@example
-$ @kbd{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
+$ @kbd{awk '/edu/ || /li/' mail-list}
+@print{} Amelia 555-5553 amelia.zodiacusque@@gmail.com F
+@print{} Broderick 555-0542 broderick.aliquotiens@@yahoo.com R
+@print{} Fabius 555-1234 fabius.undevicesimus@@ucb.edu F
+@print{} Julie 555-6699 julie.perscrutabor@@skeeve.com F
+@print{} Samuel 555-3430 samuel.lanceolis@@shu.edu A
+@print{} Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R
@end example
The following command prints all records in
-@file{BBS-list} that do @emph{not} contain the string @samp{foo}:
+@file{mail-list} that do @emph{not} contain the string @samp{li}:
@example
-$ @kbd{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
+$ @kbd{awk '! /li/' mail-list}
+@print{} Anthony 555-3412 anthony.asserturo@@hotmail.com A
+@print{} Becky 555-7685 becky.algebrarum@@gmail.com A
+@print{} Bill 555-1675 bill.drowning@@hotmail.com A
+@print{} Camilla 555-2912 camilla.infusarum@@skynet.be R
+@print{} Fabius 555-1234 fabius.undevicesimus@@ucb.edu F
+@print{} Martin 555-6480 martin.codicibus@@hotmail.com A
+@print{} Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R
@end example
@cindex @code{BEGIN} pattern, Boolean patterns and
@@ -11080,7 +13203,7 @@ 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}, @code{END},
-@code{BEGINFILE} and @code{ENDFILE},
+@code{BEGINFILE}, and @code{ENDFILE},
which never match any input record, are not expressions and cannot
appear inside Boolean patterns.
@@ -11113,7 +13236,7 @@ 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
+input record; when this succeeds, the range pattern is @dfn{turned off} again
for the following record. Then the range pattern goes back to checking
@var{begpat} against each record.
@@ -11173,12 +13296,15 @@ $ @kbd{echo Yes | gawk '(/1/,/2/) || /Yes/'}
@error{} gawk: cmd. line:1: ^ syntax error
@end example
+@cindex range patterns, line continuation and
+As a minor point of interest, although it is poor style,
+POSIX allows you to put a newline after the comma in
+a range pattern. @value{DARKCORNER}
+
@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.
@@ -11186,7 +13312,7 @@ 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}
+``@code{BEGIN} and @code{END} blocks'' by longtime @command{awk}
programmers.
@menu
@@ -11197,28 +13323,30 @@ programmers.
@node Using BEGIN/END
@subsubsection Startup and Cleanup Actions
+@cindex @code{BEGIN} pattern
+@cindex @code{END} pattern
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
$ @kbd{awk '}
-> @kbd{BEGIN @{ print "Analysis of \"foo\"" @}}
-> @kbd{/foo/ @{ ++n @}}
-> @kbd{END @{ print "\"foo\" appears", n, "times." @}' BBS-list}
-@print{} Analysis of "foo"
-@print{} "foo" appears 4 times.
+> @kbd{BEGIN @{ print "Analysis of \"li\"" @}}
+> @kbd{/li/ @{ ++n @}}
+> @kbd{END @{ print "\"li\" appears in", n, "records." @}' mail-list}
+@print{} Analysis of "li"
+@print{} "li" appears in 4 records.
@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
+This program finds the number of records in the input file @file{mail-list}
+that contain the string @samp{li}. 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
+initialize the counter @code{n} to zero, as @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
+record containing the pattern @samp{li} 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
@@ -11243,7 +13371,7 @@ 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
+@DBXREF{Options} for more information on
using library functions.
@xref{Library Functions},
for a number of useful library functions.
@@ -11260,7 +13388,7 @@ rule checks the @code{FNR} and @code{NR} variables.
@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
+There are several (sometimes subtle) points to be aware of 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,
@@ -11271,6 +13399,7 @@ 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 Brian Kernighan's @command{awk}
@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
@@ -11283,18 +13412,19 @@ 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 Brian Kernighan's @command{awk}, and possibly
-other implementations, do not.
+In fact, all of BWK @command{awk}, @command{mawk}, and @command{gawk}
+preserve the value of @code{$0} for use in @code{END} rules. Be aware,
+however, that some other implementations and many older versions
+of Unix @command{awk} 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 record. Many long time @command{awk} programmers use an unadorned
+empty record. Many longtime @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
+at least in @command{gawk}. It is also poor style, because 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
@@ -11304,33 +13434,48 @@ line is needed in the output, the program should print one explicitly.
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
+are not valid in an @code{END} rule, because all the input has been read.
+(@DBXREF{Next Statement} and
+@ifnotdocbook
+@DBPXREF{Nextfile Statement}.)
+@end ifnotdocbook
+@ifdocbook
+@DBREF{Nextfile Statement}.)
+@end ifdocbook
@node BEGINFILE/ENDFILE
@subsection The @code{BEGINFILE} and @code{ENDFILE} Special Patterns
@cindex @code{BEGINFILE} pattern
@cindex @code{ENDFILE} pattern
+@cindex differences in @command{awk} and @command{gawk}, @code{BEGINFILE}/@code{ENDFILE} patterns
This @value{SECTION} describes a @command{gawk}-specific feature.
Two special kinds of rule, @code{BEGINFILE} and @code{ENDFILE}, give
you ``hooks'' into @command{gawk}'s command-line file processing loop.
-As with the @code{BEGIN} and @code{END} rules (@pxref{BEGIN/END}), all
-@code{BEGINFILE} rules in a program are merged, in the order they are
+As with the @code{BEGIN} and @code{END} rules
+@ifnottex
+@ifnotdocbook
+(@pxref{BEGIN/END}),
+@end ifnotdocbook
+@end ifnottex
+@iftex
+(see the previous section),
+@end iftex
+@ifdocbook
+(see the previous section),
+@end ifdocbook
+all @code{BEGINFILE} rules in a program are merged, in the order they are
read by @command{gawk}, and all @code{ENDFILE} rules are merged as well.
The body of the @code{BEGINFILE} rules is executed just before
@command{gawk} reads the first record from a file. @code{FILENAME}
is set to the name of the current file, and @code{FNR} is set to zero.
-The @code{BEGINFILE} rule provides you the opportunity for two tasks
+The @code{BEGINFILE} rule provides you the opportunity to accomplish two tasks
that would otherwise be difficult or impossible to perform:
-@itemize @bullet
+@itemize @value{BULLET}
@item
You can test if the file is readable. Normally, it is a fatal error if a
file named on the command line cannot be opened for reading. However,
@@ -11338,7 +13483,7 @@ you can bypass the fatal error and move on to the next file on the
command line.
@cindex @command{gawk}, @code{ERRNO} variable in
-@cindex @code{ERRNO} variable
+@cindex @code{ERRNO} variable, with @code{BEGINFILE} pattern
@cindex @code{nextfile} statement, @code{BEGINFILE}/@code{ENDFILE} patterns and
You do this by checking if the @code{ERRNO} variable is not the empty
string; if so, then @command{gawk} was not able to open the file. In
@@ -11348,10 +13493,11 @@ the file entirely. Otherwise, @command{gawk} exits with the usual
fatal error.
@item
-If you have written extensions that modify the record handling (by inserting
-an ``open hook''), you can invoke them at this point, before @command{gawk}
-has started processing the file. (This is a @emph{very} advanced feature,
-currently used only by the @uref{http://xmlgawk.sourceforge.net, XMLgawk project}.)
+If you have written extensions that modify the record handling (by
+inserting an ``input parser,'' @pxref{Input Parsers}), you can invoke
+them at this point, before @command{gawk} has started processing the file.
+(This is a @emph{very} advanced feature, currently used only by the
+@uref{http://gawkextlib.sourceforge.net, @code{gawkextlib} project}.)
@end itemize
The @code{ENDFILE} rule is called when @command{gawk} has finished processing
@@ -11367,20 +13513,20 @@ level of the @command{awk} program.
@cindex @code{next} statement, @code{BEGINFILE}/@code{ENDFILE} patterns and
The @code{next} statement (@pxref{Next Statement}) is not allowed inside
-either a @code{BEGINFILE} or and @code{ENDFILE} rule. The @code{nextfile}
-statement (@pxref{Nextfile Statement}) is allowed only inside a
+either a @code{BEGINFILE} or an @code{ENDFILE} rule. The @code{nextfile}
+statement is allowed only inside a
@code{BEGINFILE} rule, but not inside an @code{ENDFILE} rule.
@cindex @code{getline} statement, @code{BEGINFILE}/@code{ENDFILE} patterns and
The @code{getline} statement (@pxref{Getline}) is restricted inside
-both @code{BEGINFILE} and @code{ENDFILE}. Only the @samp{getline
-@var{variable} < @var{file}} form is allowed.
+both @code{BEGINFILE} and @code{ENDFILE}: only redirected
+forms of @code{getline} are allowed.
@code{BEGINFILE} and @code{ENDFILE} are @command{gawk} extensions.
In most other @command{awk} implementations, or if @command{gawk} is in
compatibility mode (@pxref{Options}), they are not special.
-@c FIXME: For 4.1 maybe deal with this?
+@c FIXME: For 4.2 maybe deal with this?
@ignore
Date: Tue, 17 May 2011 02:06:10 PDT
From: rankin@pactechdata.com (Pat Rankin)
@@ -11411,12 +13557,11 @@ An empty (i.e., nonexistent) pattern is considered to match @emph{every}
input record. For example, the program:
@example
-awk '@{ print $1 @}' BBS-list
+awk '@{ print $1 @}' mail-list
@end example
@noindent
prints the first field of every record.
-@c ENDOFRANGE pat
@node Using Shell Variables
@section Using Shell Variables in Programs
@@ -11432,9 +13577,9 @@ 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
+A 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:
+For example, consider the following program:
@example
printf "Enter search pattern: "
@@ -11444,11 +13589,11 @@ awk "/$pattern/ "'@{ nmatches++ @}
@end example
@noindent
-the @command{awk} program consists of two pieces of quoted text
+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 first part is double quoted, which allows substitution of
the @code{pattern} shell variable inside the quotes.
-The second part is single-quoted.
+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
@@ -11458,8 +13603,8 @@ 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
+to assign the shell variable's value to an @command{awk} variable.
+Then use dynamic regexps to match the pattern
(@pxref{Computed Regexps}).
The following shows how to redo the
previous example using this technique:
@@ -11477,7 +13622,7 @@ 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
+provides more flexibility, as 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.
@@ -11497,13 +13642,13 @@ 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{]} @{ @var{action} @}
- @var{pattern} @r{[}@{ @var{action} @}@r{]}
+@display
+[@var{pattern}] @code{@{ @var{action} @}}
+ @var{pattern} [@code{@{ @var{action} @}}]
@dots{}
-function @var{name}(@var{args}) @{ @dots{} @}
+@code{function @var{name}(@var{args}) @{ @dots{} @}}
@dots{}
-@end example
+@end display
@cindex @code{@{@}} (braces), actions and
@cindex braces (@code{@{@}}), actions and
@@ -11512,11 +13657,11 @@ function @var{name}(@var{args}) @{ @dots{} @}
@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
+in braces (@samp{@{@r{@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
+The 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
+all. However, if you omit the action entirely, omit the braces as
well. An omitted action is equivalent to @samp{@{ print $0 @}}:
@example
@@ -11542,16 +13687,15 @@ programs. The @command{awk} language gives you C-like constructs
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.
+Enclose one or more statements in 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}),
+statement (@pxref{Next Statement})
and the @code{nextfile} statement
(@pxref{Nextfile Statement}).
@@ -11566,11 +13710,8 @@ For deleting array elements.
@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,
@@ -11591,7 +13732,7 @@ 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
+single @dfn{compound statement} with braces, separating them with
newlines or semicolons.
@menu
@@ -11619,9 +13760,9 @@ newlines or semicolons.
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
+@display
+@code{if (@var{condition}) @var{then-body}} [@code{else @var{else-body}}]
+@end display
@noindent
The @var{condition} is an expression that controls what the rest of the
@@ -11639,13 +13780,13 @@ else
print "x is odd"
@end example
-In this example, if the expression @samp{x % 2 == 0} is true (that is,
+In this example, if the expression @samp{x % 2 == 0} is true (i.e.,
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
+braces), then a semicolon must separate @var{then-body} from
the @code{else}.
To illustrate this, the previous example can be rewritten as:
@@ -11664,6 +13805,7 @@ the first thing on its line.
@subsection The @code{while} Statement
@cindex @code{while} statement
@cindex loops
+@cindex loops, @code{while}
@cindex loops, See Also @code{while} statement
In programming, a @dfn{loop} is a part of a program that can
@@ -11689,20 +13831,21 @@ If the @var{condition} is true, it executes the statement @var{body}.
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
+@var{condition} is tested again, and if it is still true, @var{body}
+executes again. This process repeats until the @var{condition} is no longer
+true. If the @var{condition} is initially false, the body of the loop
+never executes 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++
- @}
+awk '
+@{
+ i = 1
+ while (i <= 3) @{
+ print $i
+ i++
+ @}
@}' inventory-shipped
@end example
@@ -11716,7 +13859,7 @@ 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
+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.
@@ -11724,6 +13867,7 @@ program is harder to read without it.
@node Do Statement
@subsection The @code{do}-@code{while} Statement
@cindex @code{do}-@code{while} statement
+@cindex loops, @code{do}-@code{while}
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
@@ -11735,14 +13879,14 @@ do
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}
+Even if the @var{condition} is false at the start, the @var{body}
+executes 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}
+ @var{body}
@end example
@noindent
@@ -11752,23 +13896,24 @@ The following is an example of a @code{do} statement:
@example
@{
- i = 1
- do @{
- print $0
- i++
- @} while (i <= 10)
+ 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
+realistic example, because 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
+@cindex loops, @code{for}, iterative
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:
@@ -11792,9 +13937,10 @@ compares it against the desired number of iterations.
For example:
@example
-awk '@{
- for (i = 1; i <= 3; i++)
- print $i
+awk '
+@{
+ for (i = 1; i <= 3; i++)
+ print $i
@}' inventory-shipped
@end example
@@ -11822,7 +13968,7 @@ between 1 and 100:
@example
for (i = 1; i <= 100; i *= 2)
- print i
+ print i
@end example
If there is nothing to be done, any of the three expressions in the
@@ -11857,7 +14003,7 @@ 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.
@cindex @code{in} operator
-There is an alternate version of the @code{for} loop, for iterating over
+There is an alternative version of the @code{for} loop, for iterating over
all the indices of an array:
@example
@@ -11866,7 +14012,7 @@ for (i in array)
@end example
@noindent
-@xref{Scanning an Array},
+@DBXREF{Scanning an Array}
for more information on this version of the @code{for} loop.
@node Switch Statement
@@ -11875,6 +14021,10 @@ for more information on this version of the @code{for} loop.
@cindex @code{case} keyword
@cindex @code{default} keyword
+This @value{SECTION} describes a @command{gawk}-specific feature.
+If @command{gawk} is in compatibility mode (@pxref{Options}),
+it is not available.
+
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
@@ -11882,7 +14032,7 @@ are checked for a match in the order they are defined. If no suitable
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
+@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}
@@ -11904,41 +14054,44 @@ case is made, the case statement bodies execute until a @code{break},
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
+while ((c = getopt(ARGC, ARGV, "aksx")) != -1) @{
+ switch (c) @{
+ case "a":
+ # report size of all files
+ all_files = TRUE;
+ break
+ case "k":
+ BLOCK_SIZE = 1024 # 1K block size
+ break
+ case "s":
+ # do sums only
+ sum_only = TRUE
+ break
+ case "x":
+ # don't cross filesystems
+ fts_flags = or(fts_flags, FTS_XDEV)
+ break
+ case "?":
+ default:
+ usage()
+ break
+ @}
@}
@end example
-Note that if none of the statements specified above halt execution
+Note that if none of the statements specified here 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.
-
-This @code{switch} statement is a @command{gawk} extension.
-If @command{gawk} is in compatibility mode
-(@pxref{Options}),
-it is not available.
+next @code{case} until execution halts. In this example, the
+@code{case} for @code{"?"} falls through to the @code{default}
+case, which is to call a function named @code{usage()}.
+(The @code{getopt()} function being called here is
+described in @ref{Getopt Function}.)
@node Break Statement
@subsection The @code{break} Statement
@cindex @code{break} statement
@cindex loops, exiting
+@cindex loops, @code{break} statement and
The @code{break} statement jumps out of the innermost @code{for},
@code{while}, or @code{do} loop that encloses it. The following example
@@ -11948,15 +14101,15 @@ 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
+ 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
@@ -11974,17 +14127,17 @@ 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
+ 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
@@ -11998,6 +14151,7 @@ This is discussed in @ref{Switch Statement}.
@cindex POSIX @command{awk}, @code{break} statement and
@cindex dark corner, @code{break} statement
@cindex @command{gawk}, @code{break} statement in
+@cindex Brian Kernighan's @command{awk}
The @code{break} statement has no meaning when
used outside the body of a loop or @code{switch}.
However, although it was never documented,
@@ -12005,7 +14159,7 @@ 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}).
@value{DARKCORNER}
-Recent versions of Brian Kernighan's @command{awk} no longer allow this usage,
+Recent versions of BWK @command{awk} no longer allow this usage,
nor does @command{gawk}.
@node Continue Statement
@@ -12054,7 +14208,8 @@ BEGIN @{
@end example
@noindent
-This program loops forever once @code{x} reaches 5.
+This program loops forever once @code{x} reaches 5, because
+the increment (@samp{x++}) is never reached.
@c @cindex @code{continue}, outside of loops
@c @cindex historical features
@@ -12062,15 +14217,16 @@ This program loops forever once @code{x} reaches 5.
@cindex POSIX @command{awk}, @code{continue} statement and
@cindex dark corner, @code{continue} statement
@cindex @command{gawk}, @code{continue} statement in
+@cindex Brian Kernighan's @command{awk}
The @code{continue} statement has no special meaning with respect to the
-@code{switch} statement, nor does it any meaning when used outside the body of
-a loop. Historical versions of @command{awk} treated a @code{continue}
+@code{switch} statement, nor does it have any 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}).
@value{DARKCORNER}
-Recent versions of Brian Kernighan's @command{awk} no longer work this way, nor
+Recent versions of BWK @command{awk} no longer work this way, nor
does @command{gawk}.
@node Next Statement
@@ -12103,9 +14259,8 @@ the beginning, in the following manner:
@example
NF != 4 @{
- err = sprintf("%s:%d: skipped: NF != 4\n", FILENAME, FNR)
- print err > "/dev/stderr"
- next
+ printf("%s:%d: skipped: NF != 4\n", FILENAME, FNR) > "/dev/stderr"
+ next
@}
@end example
@@ -12114,7 +14269,7 @@ 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
+For more detail, see
@ref{Special Files}.
If the @code{next} statement causes the end of the input to be reached,
@@ -12131,70 +14286,74 @@ The @code{next} statement is not allowed inside @code{BEGINFILE} 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.
+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 does not disallow it,
+most 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.
@node Nextfile Statement
-@subsection Using @command{gawk}'s @code{nextfile} Statement
+@subsection The @code{nextfile} Statement
@cindex @code{nextfile} statement
-@cindex differences in @command{awk} and @command{gawk}, @code{next}/@code{nextfile} statements
-@cindex common extensions, @code{nextfile} statement
-@cindex extensions, common@comma{} @code{nextfile} statement
-@command{gawk} provides the @code{nextfile} statement,
-which is similar to the @code{next} statement. @value{COMMONEXT}
+The @code{nextfile} statement
+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
+@code{nextfile} statement instructs @command{awk} 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,
-any @code{ENDFILE} rules are executed except in the case as
-mentioned below, @code{FILENAME} is
+@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,
-any @code{BEGINFILE} rules are executed, and processing
+@code{FNR} is reset to one,
+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. An exception to this is
-when the @code{nextfile} is invoked during execution of any statement in an
-@code{END} rule; In this case, it causes the program to stop immediately. @xref{BEGIN/END}.
+when @code{nextfile} is invoked during execution of any statement in an
+@code{END} rule; in this case, it causes the program to stop immediately.
+@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}
+Without @code{nextfile},
+in order to move on to the next @value{DF}, a program
+would have to continue scanning the unwanted records. The @code{nextfile}
statement accomplishes this much more efficiently.
-In addition, @code{nextfile} is useful inside a @code{BEGINFILE}
+In @command{gawk}, execution of @code{nextfile} causes additional things
+to happen: any @code{ENDFILE} rules are executed if @command{gawk} is
+not currently in an @code{END} or @code{BEGINFILE} rule, @code{ARGIND} is
+incremented, and any @code{BEGINFILE} rules are executed. (@code{ARGIND}
+hasn't been introduced yet. @xref{Built-in Variables}.)
+
+With @command{gawk}, @code{nextfile} is useful inside a @code{BEGINFILE}
rule to skip over a file that would otherwise cause @command{gawk}
to exit with a fatal error. In this case, @code{ENDFILE} rules are not
executed. @xref{BEGINFILE/ENDFILE}.
-While one might think that @samp{close(FILENAME)} would accomplish
+Although it might seem 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}.
+@quotation NOTE
+For many years, @code{nextfile} was a
+common extension. In September 2012, it was accepted for
+inclusion into the POSIX standard.
+See @uref{http://austingroupbugs.net/view.php?id=607, the Austin Group website}.
+@end quotation
+
@cindex functions, user-defined, @code{next}/@code{nextfile} statements and
@cindex @code{nextfile} statement, user-defined functions and
-The current version of the Brian Kernighan's @command{awk} (@pxref{Other
-Versions}) also supports @code{nextfile}. However, it doesn't allow the
+@cindex Brian Kernighan's @command{awk}
+@cindex @command{mawk} utility
+The current version of BWK @command{awk}, and @command{mawk}
+also support @code{nextfile}. However, they don'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,
@@ -12208,9 +14367,9 @@ 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
+@display
+@code{exit} [@var{return code}]
+@end display
@cindex @code{BEGIN} pattern, @code{exit} statement and
@cindex @code{END} pattern, @code{exit} statement and
@@ -12226,14 +14385,14 @@ 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.
-Any @code{ENDFILE} rules are also skipped; they are not executed.
+@code{END} rule if there is one. @command{gawk} also skips
+any @code{ENDFILE} rules; they do not execute.
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},
+@DBXREF{Assert Function}
for an example that does this.
@cindex dark corner, @code{exit} statement
@@ -12243,9 +14402,8 @@ status code for the @command{awk} process. If no argument is supplied,
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}
-@xref{Exit Status}, for more information.
+@command{awk} uses the previously supplied exit value. @value{DARKCORNER}
+@DBXREF{Exit Status} for more information.
@cindex programming conventions, @code{exit} statement
For example, suppose an error condition occurs that is difficult or
@@ -12256,12 +14414,12 @@ 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")
+ 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
@@ -12271,16 +14429,11 @@ Negative values, and values of 127 or greater, may not produce consistent
results across different operating systems.
@end quotation
-@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
+@section Predefined Variables
+@cindex predefined variables
+@cindex variables, predefined
Most @command{awk} variables are available to use for your own
purposes; they never change unless your program assigns values to
@@ -12291,10 +14444,10 @@ 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.
+@cindex @command{gawk}, predefined variables and
+This @value{SECTION} documents all of @command{gawk}'s predefined variables,
+most of which are also documented in the @value{CHAPTER}s describing
+their areas of activity.
@menu
* User-modified:: Built-in variables that you change to control
@@ -12305,51 +14458,43 @@ describing their areas of activity.
@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
+@subsection Built-In Variables That Control @command{awk}
+@cindex predefined variables, user-modifiable
@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{#}).}
+control how @command{awk} does certain things.
+
+The variables that are specific to @command{gawk} are marked with a pound
+sign (@samp{#}). These variables are @command{gawk} extensions. In other
+@command{awk} implementations or if @command{gawk} is in compatibility
+mode (@pxref{Options}), they are not special. (Any exceptions are noted
+in the description of each variable.)
@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.
-A numeric value less than zero is treated as zero, and a numeric value greater than
-three is treated as three.
-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 treated the same as @code{"rw"},
-but causes @command{gawk}
-to generate 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.
+@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.
+A numeric value less than zero is treated as zero, and a numeric value
+greater than three is treated as three. 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 treated the same as @code{"rw"}, but causes @command{gawk}
+to generate a warning message. @code{BINMODE} is described in more
+detail in @ref{PC Using}. @command{mawk} (@pxref{Other Versions}),
+also supports this variable, but only using numeric values.
@cindex @code{CONVFMT} variable
@cindex POSIX @command{awk}, @code{CONVFMT} variable and
@cindex numbers, converting, to strings
@cindex strings, converting, numbers to
-@item CONVFMT
+@item @code{CONVFMT}
This string controls conversion of numbers to
strings (@pxref{Conversion}).
It works by being passed, in effect, as the first argument to the
@@ -12364,16 +14509,11 @@ Its default value is @code{"%.6g"}.
@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}
+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} and @code{FPAT} for field splitting.
-@xref{Constant Size}, for more information.
-
-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}.
+@DBXREF{Constant Size} for more information.
@cindex @command{gawk}, @code{FPAT} variable in
@cindex @code{FPAT} variable
@@ -12381,24 +14521,18 @@ exclusively on the value of @code{FS}.
@cindex field separators, @code{FPAT} variable and
@cindex separators, field, @code{FPAT} variable and
@item FPAT #
-This is a regular expression (as a string) that tells @command{gawk}
+A regular expression (as a string) that tells @command{gawk}
to create the fields based on text that matches the regular expression.
Assigning a value to @code{FPAT}
overrides the use of @code{FS} and @code{FIELDWIDTHS} for field splitting.
-@xref{Splitting By Content}, for more information.
-
-If @command{gawk} is in compatibility mode
-(@pxref{Options}), then @code{FPAT}
-has no special meaning, and field-splitting operations occur based
-exclusively on the value of @code{FS}.
+@DBXREF{Splitting By Content} for more information.
@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
+The input field separator (@pxref{Field Separators}).
+The value is a single-character string or a multicharacter 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.
@@ -12431,8 +14565,8 @@ is to simply say @samp{FS = FS}, perhaps with an explanatory comment.
@cindex @command{gawk}, @code{IGNORECASE} variable in
@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 case sensitivity, and string comparisons
+@cindex case sensitivity, and regexps
@cindex regular expressions, case sensitivity
@item IGNORECASE #
If @code{IGNORECASE} is nonzero or non-null, then all string comparisons
@@ -12447,18 +14581,13 @@ and it does not affect field splitting when using a single-character
field separator.
@xref{Case-sensitivity}.
-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 @command{gawk}, @code{LINT} variable in
@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.
+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
@@ -12479,13 +14608,13 @@ of @command{awk} being executed.
@cindex numbers, converting, to strings
@cindex strings, converting, numbers to
@item OFMT
-This string controls conversion of numbers to
+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
+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
@@ -12500,15 +14629,26 @@ 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
+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{PREC} variable
+@item PREC #
+The working precision of arbitrary-precision floating-point numbers,
+53 bits by default (@pxref{Setting precision}).
+
+@cindex @code{ROUNDMODE} variable
+@item ROUNDMODE #
+The rounding mode to use for arbitrary-precision arithmetic on
+numbers, by default @code{"N"} (@samp{roundTiesToEven} in
+the IEEE 754 standard; @pxref{Setting the rounding mode}).
+
@cindex @code{RS} variable
@cindex separators, for records
@cindex record separators
-@item RS
-This is @command{awk}'s input record separator. Its default value is a string
+@item @code{RS}
+The 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
@@ -12527,53 +14667,46 @@ 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
+@item @code{SUBSEP}
+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}).
+(@pxref{Multidimensional}).
@cindex @command{gawk}, @code{TEXTDOMAIN} variable in
@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
+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
+@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
+@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
+@cindex predefined variables, conveying information
+@cindex variables, predefined 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{#}).}
+information to your program.
-@table @code
+The variables that are specific to @command{gawk} are marked with a pound
+sign (@samp{#}). These variables are @command{gawk} extensions. In other
+@command{awk} implementations or if @command{gawk} is in compatibility
+mode (@pxref{Options}), they are not special:
+
+@c @asis for docbook
+@table @asis
@cindex @code{ARGC}/@code{ARGV} variables
@cindex arguments, command-line
@cindex command line, arguments
-@item ARGC@r{,} ARGV
+@item @code{ARGC}, @code{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}.
@@ -12585,16 +14718,16 @@ In the following example:
$ @kbd{awk 'BEGIN @{}
> @kbd{for (i = 0; i < ARGC; i++)}
> @kbd{print ARGV[i]}
-> @kbd{@}' inventory-shipped BBS-list}
+> @kbd{@}' inventory-shipped mail-list}
@print{} awk
@print{} inventory-shipped
-@print{} BBS-list
+@print{} mail-list
@end example
@noindent
@code{ARGV[0]} contains @samp{awk}, @code{ARGV[1]}
contains @samp{inventory-shipped}, and @code{ARGV[2]} contains
-@samp{BBS-list}. The value of @code{ARGC} is three, one more than the
+@samp{mail-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.
@@ -12607,13 +14740,13 @@ 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
+@DBXREF{ARGC and ARGV} for information
about how @command{awk} uses these variables.
@value{DARKCORNER}
@cindex @code{ARGIND} variable
@cindex differences in @command{awk} and @command{gawk}, @code{ARGIND} variable
-@item ARGIND #
+@item @code{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}.
@@ -12625,128 +14758,138 @@ 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
+@cindex file names, 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.
+program, @command{gawk} automatically sets it to a new value when it
+opens the next file.
@cindex @code{ENVIRON} array
-@cindex environment variables
-@item ENVIRON
+@cindex environment variables, in @code{ENVIRON} array
+@item @code{ENVIRON}
An associative array containing 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.)
+@code{ENVIRON["HOME"]} might be @code{/home/arnold}.
+
+For POSIX @command{awk}, 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.
+
+However, beginning with version 4.2, if not in POSIX
+compatibility mode, @command{gawk} does update its own environment when
+@code{ENVIRON} is changed, thus changing the environment seen by programs
+that it creates. You should therefore be especially careful if you
+modify @code{ENVIRON["PATH"]"}, which is the search path for finding
+executable programs.
+
+This can also affect the running @command{gawk} program, since some of the
+built-in functions may pay attention to certain environment variables.
+The most notable instance of this is @code{mktime()} (@pxref{Time
+Functions}), which pays attention the value of the @env{TZ} environment
+variable on many systems.
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}).
+@w{@code{ENVIRON["AWKPATH"]}} and
+@w{@code{ENVIRON["AWKLIBPATH"]}};
+@DBPXREF{AWKPATH Variable} and
+@ifdocbook
+@DBREF{AWKLIBPATH Variable}).
+@end ifdocbook
+@ifnotdocbook
+@pxref{AWKLIBPATH Variable}).
+@end ifnotdocbook
@cindex @command{gawk}, @code{ERRNO} variable in
@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.
-
-In addition, @command{gawk} clears @code{ERRNO}
-before opening each command-line input file. This enables checking if
-the file is readable inside a @code{BEGINFILE} pattern (@pxref{BEGINFILE/ENDFILE}).
-
-Otherwise,
-@code{ERRNO} works similarly to the C variable @code{errno}.
-Except for the case just mentioned,
-@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.
+@item @code{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.
+
+In addition, @command{gawk} clears @code{ERRNO} before opening each
+command-line input file. This enables checking if the file is readable
+inside a @code{BEGINFILE} pattern (@pxref{BEGINFILE/ENDFILE}).
+
+Otherwise, @code{ERRNO} works similarly to the C variable @code{errno}.
+Except for the case just mentioned, @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.
@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.
+@item @code{FILENAME}
+The name of the current input file. 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} changes each
+time a new file is read (@pxref{Reading Files}). Inside a @code{BEGIN}
+rule, the value of @code{FILENAME} is @code{""}, because 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{Records}). It is reinitialized
-to zero each time a new input file is started.
+@item @code{FNR}
+The current record number in the current file. @command{awk} increments
+@code{FNR} each time it reads a new record (@pxref{Records}).
+@command{awk} resets @code{FNR} to zero each time it starts a new
+input file.
@cindex @code{NF} variable
-@item NF
+@item @code{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
+Unlike most of the variables described in this @value{SUBSECTION},
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{FUNCTAB} array
+@cindex @command{gawk}, @code{FUNCTAB} array in
+@cindex differences in @command{awk} and @command{gawk}, @code{FUNCTAB} variable
+@item @code{FUNCTAB #}
+An array whose indices and corresponding values are the names of all
+the built-in, user-defined, and extension functions in the program.
+
+@quotation NOTE
+Attempting to use the @code{delete} statement with the @code{FUNCTAB}
+array causes a fatal error. Any attempt to assign to an element of
+@code{FUNCTAB} also causes a fatal error.
+@end quotation
+
@cindex @code{NR} variable
-@item NR
+@item @code{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.
+@command{awk} increments @code{NR} each time it reads a new record.
@cindex @command{gawk}, @code{PROCINFO} array in
@cindex @code{PROCINFO} array
@cindex differences in @command{awk} and @command{gawk}, @code{PROCINFO} array
-@item PROCINFO #
+@item @code{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
+@cindex effective group ID of @command{gawk} user
@item PROCINFO["egid"]
The value of the @code{getegid()} system call.
@item PROCINFO["euid"]
+@cindex effective user ID of @command{gawk} user
The value of the @code{geteuid()} system call.
@item PROCINFO["FS"]
@@ -12755,23 +14898,62 @@ This is
@code{"FIELDWIDTHS"} if field splitting with @code{FIELDWIDTHS} is in effect,
or @code{"FPAT"} if field matching with @code{FPAT} is in effect.
+@item PROCINFO["identifiers"]
+@cindex program identifiers
+A subarray, indexed by the names of all identifiers used in the text of
+the AWK program. An @dfn{identifier} is simply the name of a variable
+(be it scalar or array), built-in function, user-defined function, or
+extension function. For each identifier, the value of the element is
+one of the following:
+
+@table @code
+@item "array"
+The identifier is an array.
+
+@item "builtin"
+The identifier is a built-in function.
+
+@item "extension"
+The identifier is an extension function loaded via
+@code{@@load} or @option{-l}.
+
+@item "scalar"
+The identifier is a scalar.
+
+@item "untyped"
+The identifier is untyped (could be used as a scalar or array,
+@command{gawk} doesn't know yet).
+
+@item "user"
+The identifier is a user-defined function.
+@end table
+
+@noindent
+The values indicate what @command{gawk} knows about the identifiers
+after it has finished parsing the program; they are @emph{not} updated
+while the program runs.
+
@item PROCINFO["gid"]
+@cindex group ID of @command{gawk} user
The value of the @code{getgid()} system call.
@item PROCINFO["pgrpid"]
+@cindex process group idIDof @command{gawk} process
The process group ID of the current process.
@item PROCINFO["pid"]
+@cindex process ID of @command{gawk} process
The process ID of the current process.
@item PROCINFO["ppid"]
+@cindex parent process ID of @command{gawk} process
The parent process ID of the current process.
@item PROCINFO["sorted_in"]
If this element exists in @code{PROCINFO}, its value controls the
order in which array indices will be processed by
-@samp{for (index in array) @dots{}} loops.
-Since this is an advanced feature, we defer the
+@samp{for (@var{indx} in @var{array})} loops.
+This is an advanced feature, so we defer the
full description until later; see
@ref{Scanning an Array}.
@@ -12784,9 +14966,50 @@ Assigning a new value to this element changes the default.
The value of the @code{getuid()} system call.
@item PROCINFO["version"]
+@cindex version of @command{gawk}
+@cindex @command{gawk} version
The version of @command{gawk}.
@end table
+The following additional elements in the array
+are available to provide information about the MPFR and GMP libraries
+if your version of @command{gawk} supports arbitrary-precision arithmetic
+(@pxref{Arbitrary Precision Arithmetic}):
+
+@table @code
+@cindex version of GNU MPFR library
+@item PROCINFO["mpfr_version"]
+The version of the GNU MPFR library.
+
+@item PROCINFO["gmp_version"]
+@cindex version of GNU MP library
+The version of the GNU MP library.
+
+@item PROCINFO["prec_max"]
+@cindex maximum precision supported by MPFR library
+The maximum precision supported by MPFR.
+
+@item PROCINFO["prec_min"]
+@cindex minimum precision supported by MPFR library
+The minimum precision required by MPFR.
+@end table
+
+The following additional elements in the array are available to provide
+information about the version of the extension API, if your version
+of @command{gawk} supports dynamic loading of extension functions
+(@pxref{Dynamic Extensions}):
+
+@table @code
+@item PROCINFO["api_major"]
+@cindex version of @command{gawk} extension API
+@cindex extension API, version number
+The major version of the extension API.
+
+@item PROCINFO["api_minor"]
+The minor version of the extension API.
+@end table
+
+@cindex supplementary groups of @command{gawk} process
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
@@ -12794,19 +15017,23 @@ to test for these elements
(@pxref{Reference to Elements}).
@cindex @command{gawk}, @code{PROCINFO} array in
-@cindex @code{PROCINFO} array
-The @code{PROCINFO} array is also used to cause coprocesses
-to communicate over pseudo-ttys instead of through two-way pipes;
-this is discussed further in @ref{Two-way I/O}.
+@cindex @code{PROCINFO} array, uses
+The @code{PROCINFO} array has the following additional uses:
-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.
+@itemize @value{BULLET}
+@item
+It may be used to provide a timeout when reading from any
+open input file, pipe, or coprocess.
+@DBXREF{Read Timeout} for more information.
+
+@item
+It may be used to cause coprocesses to communicate over pseudo-ttys
+instead of through two-way pipes; this is discussed further in
+@ref{Two-way I/O}.
+@end itemize
@cindex @code{RLENGTH} variable
-@item RLENGTH
+@item @code{RLENGTH}
The length of the substring matched by the
@code{match()} function
(@pxref{String Functions}).
@@ -12814,7 +15041,7 @@ The length of the substring matched by the
is the length of the matched string, or @minus{}1 if no match is found.
@cindex @code{RSTART} variable
-@item RSTART
+@item @code{RSTART}
The start-index in characters of the substring that is matched by the
@code{match()} function
(@pxref{String Functions}).
@@ -12825,24 +15052,75 @@ if no match was found.
@cindex @command{gawk}, @code{RT} variable in
@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.
+@item @code{RT #}
+The input text that matched the text denoted by @code{RS},
+the record separator. It is set every time a record is read.
-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 @command{gawk}, @code{SYMTAB} array in
+@cindex @code{SYMTAB} array
+@cindex differences in @command{awk} and @command{gawk}, @code{SYMTAB} variable
+@item @code{SYMTAB #}
+An array whose indices are the names of all defined global variables and
+arrays in the program. @code{SYMTAB} makes @command{gawk}'s symbol table
+visible to the @command{awk} programmer. It is built as @command{gawk}
+parses the program and is complete before the program starts to run.
+
+The array may be used for indirect access to read or write the value of
+a variable:
+
+@example
+foo = 5
+SYMTAB["foo"] = 4
+print foo # prints 4
+@end example
+
+@noindent
+The @code{isarray()} function (@pxref{Type Functions}) may be used to test
+if an element in @code{SYMTAB} is an array.
+Also, you may not use the @code{delete} statement with the
+@code{SYMTAB} array.
+
+You may use an index for @code{SYMTAB} that is not a predefined identifier:
+
+@example
+SYMTAB["xxx"] = 5
+print SYMTAB["xxx"]
+@end example
+
+@noindent
+This works as expected: in this case @code{SYMTAB} acts just like
+a regular array. The only difference is that you can't then delete
+@code{SYMTAB["xxx"]}.
+
+@cindex Schorr, Andrew
+The @code{SYMTAB} array is more interesting than it looks. Andrew Schorr
+points out that it effectively gives @command{awk} data pointers. Consider his
+example:
+
+@example
+# Indirect multiply of any variable by amount, return result
+
+function multiply(variable, amount)
+@{
+ return SYMTAB[variable] *= amount
+@}
+@end example
+
+@quotation NOTE
+In order to avoid severe time-travel paradoxes,@footnote{Not to mention difficult
+implementation issues.} neither @code{FUNCTAB} nor @code{SYMTAB}
+are available as elements within the @code{SYMTAB} array.
+@end quotation
@end table
-@c ENDOFRANGE bvconi
-@c ENDOFRANGE vbconi
-@c fakenode --- for prepinfo
-@subheading Advanced Notes: Changing @code{NR} and @code{FNR}
+@cindex sidebar, Changing @code{NR} and @code{FNR}
+@ifdocbook
+@docbook
+<sidebar><title>Changing @code{NR} and @code{FNR}</title>
+@end docbook
+
@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
@@ -12871,13 +15149,55 @@ 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.
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{Changing @code{NR} and @code{FNR}}
+
+
+@cindex @code{NR} variable, changing
+@cindex @code{FNR} variable, changing
+@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}
+The following example shows this:
+
+@example
+$ @kbd{echo '1}
+> @kbd{2}
+> @kbd{3}
+> @kbd{4' | awk 'NR == 2 @{ NR = 17 @}}
+> @kbd{@{ print NR @}'}
+@print{} 1
+@print{} 17
+@print{} 18
+@print{} 19
+@end example
+
+@noindent
+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.
+@end cartouche
+@end ifnotdocbook
+
@node ARGC and ARGV
@subsection Using @code{ARGC} and @code{ARGV}
-@cindex @code{ARGC}/@code{ARGV} variables
+@cindex @code{ARGC}/@code{ARGV} variables, how to use
@cindex arguments, command-line
@cindex command line, arguments
-@ref{Auto-set},
+@DBREF{Auto-set}
presented the following program describing the information contained in @code{ARGC}
and @code{ARGV}:
@@ -12885,16 +15205,16 @@ and @code{ARGV}:
$ @kbd{awk 'BEGIN @{}
> @kbd{for (i = 0; i < ARGC; i++)}
> @kbd{print ARGV[i]}
-> @kbd{@}' inventory-shipped BBS-list}
+> @kbd{@}' inventory-shipped mail-list}
@print{} awk
@print{} inventory-shipped
-@print{} BBS-list
+@print{} mail-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}.
+@samp{mail-list}.
Notice that the @command{awk} program is not entered in @code{ARGV}. The
other command-line options, with their arguments, are also not
entered. This includes variable assignments done with the @option{-v}
@@ -12947,11 +15267,26 @@ use the @code{delete} statement to remove elements from
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
+@DBXREF{Split Program} and
+@ifnotdocbook
+@DBPXREF{Tee Program}
+@end ifnotdocbook
+@ifdocbook
+@DBREF{Tee Program}
+@end ifdocbook
+for examples
of each way of removing elements from @code{ARGV}.
+
+To actually get options into an @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.awk -- -v -q file1 file2 @dots{}
+@end example
+
The following fragment processes @code{ARGV} in order to examine, and
-then remove, command-line options:
+then remove, the previously mentioned command-line options:
@example
BEGIN @{
@@ -12971,36 +15306,104 @@ BEGIN @{
@}
@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 -q 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
+Ending the @command{awk} options with @option{--} isn't
+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
+options that it might otherwise recognize. The previous command line with
@command{gawk} would be:
@example
-gawk -f myprog -q -v file1 file2 @dots{}
+gawk -f myprog.awk -q -v file1 file2 @dots{}
@end example
@noindent
-Because @option{-q} is not a valid @command{gawk} option,
-it and the following @option{-v}
-are passed on to the @command{awk} program.
-(@xref{Getopt Function}, for an @command{awk} library function
-that parses command-line options.)
+Because @option{-q} is not a valid @command{gawk} option, it and the
+following @option{-v} are passed on to the @command{awk} program.
+(@DBXREF{Getopt Function} for an @command{awk} library function that
+parses command-line options.)
+
+When designing your program, you should choose options that don't
+conflict with @command{gawk}'s, because it will process any options
+that it accepts before passing the rest of the command line on to
+your program. Using @samp{#!} with the @option{-E} option may help
+(@DBXREF{Executable Scripts}
+and
+@ifnotdocbook
+@DBPXREF{Options}).
+@end ifnotdocbook
+@ifdocbook
+@DBREF{Options}).
+@end ifdocbook
+
+@node Pattern Action Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+Pattern-action pairs make up the basic elements of an @command{awk}
+program. Patterns are either normal expressions, range expressions,
+regexp constants, one of the special keywords @code{BEGIN}, @code{END},
+@code{BEGINFILE}, @code{ENDFILE}, or empty. The action executes if
+the current record matches the pattern. Empty (missing) patterns match
+all records.
+
+@item
+I/O from @code{BEGIN} and @code{END} rules have certain constraints.
+This is also true, only more so, for @code{BEGINFILE} and @code{ENDFILE}
+rules. The latter two give you ``hooks'' into @command{gawk}'s file
+processing, allowing you to recover from a file that otherwise would
+cause a fatal error (such as a file that cannot be opened).
+
+@item
+Shell variables can be used in @command{awk} programs by careful
+use of shell quoting. It is easier to pass a shell variable into
+@command{awk} by using the @option{-v} option and an @command{awk}
+variable.
+
+@item
+Actions consist of statements enclosed in curly braces. Statements
+are built up from expressions, control statements, compound statements,
+input and output statements, and deletion statements.
+
+@item
+The control statements in @command{awk} are @code{if}-@code{else},
+@code{while}, @code{for}, and @code{do}-@code{while}. @command{gawk}
+adds the @code{switch} statement. There are two flavors of @code{for}
+statement: one for performing general looping, and the other for iterating
+through an array.
+
+@item
+@code{break} and @code{continue} let you exit early or start the next
+iteration of a loop (or get out of a @code{switch}).
+
+@item
+@code{next} and @code{nextfile} let you read the next record and start
+over at the top of your program, or skip to the next input file and
+start over, respectively.
+
+@item
+The @code{exit} statement terminates your program. When executed
+from an action (or function body) it transfers control to the
+@code{END} statements. From an @code{END} statement body, it exits
+immediately. You may pass an optional numeric value to be used
+as @command{awk}'s exit status.
+
+@item
+Some predefined variables provide control over @command{awk}, mainly for I/O.
+Other variables convey information from @command{awk} to your program.
+
+@item
+@code{ARGC} and @code{ARGV} make the command-line arguments available
+to your program. Manipulating them from a @code{BEGIN} rule lets you
+control how @command{awk} will process the provided @value{DF}s.
+
+@end itemize
@node Arrays
@chapter Arrays in @command{awk}
-@c STARTOFRANGE arrs
@cindex arrays
An @dfn{array} is a table of values called @dfn{elements}. The
@@ -13014,29 +15417,19 @@ It also describes how @command{awk} simulates multidimensional
arrays, as well as some of the less obvious points about array usage.
The @value{CHAPTER} moves on to discuss @command{gawk}'s facility
for sorting arrays, and ends with a brief description of @command{gawk}'s
-ability to support true multidimensional arrays.
-
-@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.
+ability to support true arrays of arrays.
@menu
* Array Basics:: The basics of arrays.
-* 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
+* Delete:: The @code{delete} statement removes an element
+ from an array.
+* Multidimensional:: Emulating multidimensional arrays in
@command{awk}.
* Arrays of Arrays:: True multidimensional arrays.
+* Arrays Summary:: Summary of arrays.
@end menu
@node Array Basics
@@ -13054,6 +15447,8 @@ an array.
* Scanning an Array:: A variation of the @code{for} statement. It
loops through the indices of an array's
existing elements.
+* Controlling Scanning:: Controlling the order in which arrays are
+ scanned.
@end menu
@node Array Intro
@@ -13062,8 +15457,8 @@ an array.
@cindex Wall, Larry
@quotation
@i{Doing linear scans over an associative array is like trying to club someone
-to death with a loaded Uzi.}@*
-Larry Wall
+to death with a loaded Uzi.}
+@author Larry Wall
@end quotation
The @command{awk} language provides one-dimensional arrays
@@ -13076,7 +15471,7 @@ 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,
+Additionally, any number or string, not just consecutive integers,
may be used as an array index.
In most other languages, arrays must be @dfn{declared} before use,
@@ -13096,65 +15491,107 @@ 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:
+@code{""}, and 30
+@ifnotdocbook
+as shown in @ref{figure-array-elements}:
+@end ifnotdocbook
+@ifdocbook
+as shown in @inlineraw{docbook, <xref linkend="figure-array-elements"/>}:
+@end ifdocbook
-@c @strong{FIXME: 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
-@ifnottex
-@example
-+---------+---------+--------+---------+
-| 8 | "foo" | "" | 30 | @r{Value}
-+---------+---------+--------+---------+
- 0 1 2 3 @r{Index}
-@end example
-@end ifnottex
+@ifnotdocbook
+@float Figure,figure-array-elements
+@caption{A contiguous array}
+@ifinfo
+@center @image{array-elements, , , Basic Program Stages, txt}
+@end ifinfo
+@ifnotinfo
+@center @image{array-elements, , , Basic Program Stages}
+@end ifnotinfo
+@end float
+@end ifnotdocbook
+
+@docbook
+<figure id="figure-array-elements" float="0">
+<title>A contiguous array</title>
+<mediaobject>
+<imageobject role="web"><imagedata fileref="array-elements.png" format="PNG"/></imageobject>
+</mediaobject>
+</figure>
+@end docbook
@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
+that each array is a collection of pairs---an index and its corresponding
array element value:
+@ifnotdocbook
@example
@r{Index} 3 @r{Value} 30
@r{Index} 1 @r{Value} "foo"
@r{Index} 0 @r{Value} 8
@r{Index} 2 @r{Value} ""
@end example
+@end ifnotdocbook
+
+@docbook
+<informaltable>
+<tgroup cols="2">
+<colspec colname="1" align="center"/>
+<colspec colname="2" align="center"/>
+<thead>
+<row>
+<entry>Index</entry>
+<entry>Value</entry>
+</row>
+</thead>
+
+<tbody>
+<row>
+<entry><literal>3</literal></entry>
+<entry><literal>30</literal></entry>
+</row>
+
+<row>
+<entry><literal>1</literal></entry>
+<entry><literal>"foo"</literal></entry>
+</row>
+
+<row>
+<entry><literal>0</literal></entry>
+<entry><literal>8</literal></entry>
+</row>
+
+<row>
+<entry><literal>2</literal></entry>
+<entry><literal>""</literal></entry>
+</row>
+
+</tbody>
+</tgroup>
+</informaltable>
+
+@end docbook
@noindent
-The pairs are shown in jumbled order because their order is irrelevant.
+The pairs are shown in jumbled order because their order is
+irrelevant.@footnote{The ordering will vary among @command{awk}
+implementations, which typically use hash tables to store array elements
+and values.}
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:
+@ifnotdocbook
@example
@r{Index} 10 @r{Value} "number ten"
@r{Index} 3 @r{Value} 30
@@ -13162,6 +15599,51 @@ whose value is @w{@code{"number ten"}}. The result is:
@r{Index} 0 @r{Value} 8
@r{Index} 2 @r{Value} ""
@end example
+@end ifnotdocbook
+
+@docbook
+<informaltable>
+<tgroup cols="2">
+<colspec colname="1" align="center"/>
+<colspec colname="2" align="center"/>
+<thead>
+<row>
+<entry>Index</entry>
+<entry>Value</entry>
+</row>
+</thead>
+<tbody>
+
+<row>
+<entry><literal>10</literal></entry>
+<entry><literal>"number ten"</literal></entry>
+</row>
+
+<row>
+<entry><literal>3</literal></entry>
+<entry><literal>30</literal></entry>
+</row>
+
+<row>
+<entry><literal>1</literal></entry>
+<entry><literal>"foo"</literal></entry>
+</row>
+
+<row>
+<entry><literal>0</literal></entry>
+<entry><literal>8</literal></entry>
+</row>
+
+<row>
+<entry><literal>2</literal></entry>
+<entry><literal>""</literal></entry>
+</row>
+
+</tbody>
+</tgroup>
+</informaltable>
+
+@end docbook
@noindent
@cindex sparse arrays
@@ -13174,28 +15656,68 @@ 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:
+@ifnotdocbook
@example
@r{Index} "dog" @r{Value} "chien"
@r{Index} "cat" @r{Value} "chat"
@r{Index} "one" @r{Value} "un"
@r{Index} 1 @r{Value} "un"
@end example
+@end ifnotdocbook
+
+@docbook
+<informaltable>
+<tgroup cols="2">
+<colspec colname="1" align="center"/>
+<colspec colname="2" align="center"/>
+<thead>
+<row>
+<entry>Index</entry>
+<entry>Value</entry>
+</row>
+</thead>
+<tbody>
+<row>
+<entry><literal>"dog"</literal></entry>
+<entry><literal>"chien"</literal></entry>
+</row>
+
+<row>
+<entry><literal>"cat"</literal></entry>
+<entry><literal>"chat"</literal></entry>
+</row>
+
+<row>
+<entry><literal>"one"</literal></entry>
+<entry><literal>"un"</literal></entry>
+</row>
+
+<row>
+<entry><literal>1</literal></entry>
+<entry><literal>"un"</literal></entry>
+</row>
+
+</tbody>
+</tgroup>
+</informaltable>
+
+@end docbook
@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}
+(In fact, array subscripts are always strings.
+There are some subtleties to how numbers work when used as
+array subscripts; this is discussed in more detail in
+@ref{Numeric Array Subscripts}.)
+Here, the number @code{1} isn't double quoted, because @command{awk}
automatically converts it to a string.
@cindex @command{gawk}, @code{IGNORECASE} variable in
-@cindex @code{IGNORECASE} variable
@cindex case sensitivity, array indices and
-@cindex arrays, @code{IGNORECASE} variable and
-@cindex @code{IGNORECASE} variable, array subscripts and
+@cindex arrays, and @code{IGNORECASE} variable
+@cindex @code{IGNORECASE} variable, and array indices
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.
@@ -13206,13 +15728,12 @@ that array's indices are consecutive integers starting at one.
@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
@subsection Referring to an Array Element
-@cindex arrays, elements, referencing
-@cindex elements in arrays
+@cindex arrays, referencing elements
+@cindex array members
+@cindex elements of arrays
The principal way to use an array is to refer to one of its elements.
An array reference is an expression as follows:
@@ -13229,11 +15750,16 @@ 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}.
+@cindex arrays, unassigned elements
+@cindex unassigned array elements
+@cindex empty array elements
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}).
+@cindex non-existent array elements
+@cindex arrays, elements that don't exist
@quotation NOTE
A reference to an element that does not exist @emph{automatically} creates
that array element, with the null string as its value. (In some cases,
@@ -13248,25 +15774,28 @@ if (a["foo"] != "") @dots{}
@end example
@noindent
-This is incorrect, since this will @emph{create} @code{a["foo"]}
-if it didn't exist before!
+This is incorrect for two reasons. First, it @emph{creates} @code{a["foo"]}
+if it didn't exist before! Second, it is valid (if a bit unusual) to set
+an array element equal to the empty string.
@end quotation
@c @cindex arrays, @code{in} operator and
-@cindex @code{in} operator, arrays and
+@cindex @code{in} operator, testing if array element exists
To determine whether an element exists in an array at a certain index, use
the following expression:
@example
-@var{ind} in @var{array}
+@var{indx} in @var{array}
@end example
@cindex side effects, array indexing
@noindent
-This expression tests whether the particular index @var{ind} exists,
+This expression tests whether the particular index @var{indx} 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{ind}]}
+The expression has the value one (true) if @code{@var{array}[@var{indx}]}
exists and zero (false) if it does not exist.
+(We use @var{indx} here, because @samp{index} is the name of a built-in
+function.)
For example, this statement tests whether the array @code{frequencies}
contains the index @samp{2}:
@@ -13288,8 +15817,8 @@ if (frequencies[2] != "")
@node Assigning Elements
@subsection Assigning Array Elements
-@cindex arrays, elements, assigning
-@cindex elements in arrays, assigning
+@cindex arrays, elements, assigning values
+@cindex elements in arrays, assigning values
Array elements can be assigned values just like
@command{awk} variables:
@@ -13306,6 +15835,7 @@ assign to that element of the array.
@node Array Example
@subsection Basic Array Example
+@cindex arrays, an example of using
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
@@ -13319,14 +15849,14 @@ begin with a number:
@example
@c file eg/misc/arraymax.awk
@{
- if ($1 > max)
- max = $1
- arr[$1] = $0
+ if ($1 > max)
+ max = $1
+ arr[$1] = $0
@}
END @{
- for (x = 1; x <= max; x++)
- print arr[x]
+ for (x = 1; x <= max; x++)
+ print arr[x]
@}
@c endfile
@end example
@@ -13366,16 +15896,18 @@ program's @code{END} rule, as follows:
@example
END @{
- for (x = 1; x <= max; x++)
- if (x in arr)
- print arr[x]
+ for (x = 1; x <= max; x++)
+ if (x in arr)
+ print arr[x]
@}
@end example
@node Scanning an Array
@subsection Scanning All Elements of an Array
@cindex elements in arrays, scanning
+@cindex scanning arrays
@cindex arrays, scanning
+@cindex loops, @code{for}, array 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
@@ -13388,16 +15920,16 @@ an array:
@example
for (@var{var} in @var{array})
- @var{body}
+ @var{body}
@end example
@noindent
-@cindex @code{in} operator, arrays and
+@cindex @code{in} operator, use in loops
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
+@cindex @code{for} statement, looping over 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
@@ -13405,7 +15937,7 @@ 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},
+@DBXREF{String Functions}
for more information on the built-in function @code{length()}.
@example
@@ -13428,143 +15960,228 @@ END @{
@end example
@noindent
-@xref{Word Sorting},
+@DBXREF{Word Sorting}
for a more detailed example of this type.
-@cindex arrays, elements, order of
-@cindex elements in arrays, order of
+@cindex arrays, elements, order of access by @code{in} operator
+@cindex elements in arrays, order of access by @code{in} operator
+@cindex @code{in} operator, order of array access
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 normally 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.
-
-As an extension, @command{gawk} makes it possible for you to
-loop over the elements of an array in order, based on the value of
-@code{PROCINFO["sorted_in"]} (@pxref{Auto-set}).
-This is an advanced feature, so discussion of it is delayed
-until @ref{Controlling Array Traversal}.
-
-In addition, @command{gawk} provides built-in functions for
-sorting arrays; see @ref{Array Sorting Functions}.
-
-@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
+@command{awk} and in standard @command{awk} 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.
-To remove an individual element of an array, use the @code{delete}
-statement:
+As a point of information, @command{gawk} sets up the list of elements
+to be iterated over before the loop starts, and does not change it.
+But not all @command{awk} versions do so. Consider this program, named
+@file{loopcheck.awk}:
@example
-delete @var{array}[@var{index-expression}]
+BEGIN @{
+ a["here"] = "here"
+ a["is"] = "is"
+ a["a"] = "a"
+ a["loop"] = "loop"
+ for (i in a) @{
+ j++
+ a[j] = j
+ print i
+ @}
+@}
@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 been given a value.
-The following is an example of deleting elements in an array:
+Here is what happens when run with @command{gawk} (and @command{mawk}):
@example
-for (i in frequencies)
- delete frequencies[i]
+$ @kbd{gawk -f loopcheck.awk}
+@print{} here
+@print{} loop
+@print{} a
+@print{} is
@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):
+Contrast this to BWK @command{awk}:
@example
-delete foo[4]
-if (4 in foo)
- print "This will never be printed"
+$ @kbd{nawk -f loopcheck.awk}
+@print{} loop
+@print{} here
+@print{} is
+@print{} a
+@print{} 1
@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:
+@node Controlling Scanning
+@subsection Using Predefined Array Scanning Orders with @command{gawk}
-@example
-foo[4] = ""
-if (4 in foo)
- print "This is printed, even though foo[4] is empty"
-@end example
+This @value{SUBSECTION} describes a feature that is specific to @command{gawk}.
-@cindex lint checking, array elements
-It is not an error to delete an element that does not exist.
-However, 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.
+By default, when a @code{for} loop traverses an array, the order
+is undefined, meaning that the @command{awk} implementation
+determines the order in which the array is traversed.
+This order is usually based on the internal implementation of arrays
+and will vary from one version of @command{awk} to the next.
-@cindex common extensions, @code{delete} to delete entire arrays
-@cindex extensions, common@comma{} @code{delete} to delete entire arrays
-@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
-@value{COMMONEXT}
-by leaving off the subscript in the @code{delete} statement,
-as follows:
+@cindex array scanning order, controlling
+@cindex controlling array scanning order
+Often, though, you may wish to do something simple, such as
+``traverse the array by comparing the indices in ascending order,''
+or ``traverse the array by comparing the values in descending order.''
+@command{gawk} provides two mechanisms which give you this control.
-@example
-delete @var{array}
-@end example
+@itemize @value{BULLET}
+@item
+Set @code{PROCINFO["sorted_in"]} to one of a set of predefined values.
+We describe this now.
-This ability is a @command{gawk} extension; it is not available in
-compatibility mode (@pxref{Options}).
+@item
+Set @code{PROCINFO["sorted_in"]} to the name of a user-defined function
+to use for comparison of array elements. This advanced feature
+is described later in @ref{Array Sorting}.
+@end itemize
-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 @code{PROCINFO}, values of @code{sorted_in}
+The following special values for @code{PROCINFO["sorted_in"]} are available:
-@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.}
+@table @code
+@item "@@unsorted"
+Array elements are processed in arbitrary order, which is the default
+@command{awk} behavior.
+
+@item "@@ind_str_asc"
+Order by indices in ascending order compared as strings; this is the most basic sort.
+(Internally, array indices are always strings, so with @samp{a[2*5] = 1}
+the index is @code{"10"} rather than numeric 10.)
+
+@item "@@ind_num_asc"
+Order by indices in ascending order but force them to be treated as numbers in the process.
+Any index with a non-numeric value will end up positioned as if it were zero.
+
+@item "@@val_type_asc"
+Order by element values in ascending order (rather than by indices).
+Ordering is by the type assigned to the element
+(@pxref{Typing and Comparison}).
+All numeric values come before all string values,
+which in turn come before all subarrays.
+(Subarrays have not been described yet;
+@pxref{Arrays of Arrays}.)
+
+@item "@@val_str_asc"
+Order by element values in ascending order (rather than by indices). Scalar values are
+compared as strings. Subarrays, if present, come out last.
+
+@item "@@val_num_asc"
+Order by element values in ascending order (rather than by indices). Scalar values are
+compared as numbers. Subarrays, if present, come out last.
+When numeric values are equal, the string values are used to provide
+an ordering: this guarantees consistent results across different
+versions of the C @code{qsort()} function,@footnote{When two elements
+compare as equal, the C @code{qsort()} function does not guarantee
+that they will maintain their original relative order after sorting.
+Using the string value to provide a unique ordering when the numeric
+values are equal ensures that @command{gawk} behaves consistently
+across different environments.} which @command{gawk} uses internally
+to perform the sorting.
+
+@item "@@ind_str_desc"
+String indices ordered from high to low.
+
+@item "@@ind_num_desc"
+Numeric indices ordered from high to low.
+
+@item "@@val_type_desc"
+Element values, based on type, ordered from high to low.
+Subarrays, if present, come out first.
+
+@item "@@val_str_desc"
+Element values, treated as strings, ordered from high to low.
+Subarrays, if present, come out first.
+
+@item "@@val_num_desc"
+Element values, treated as numbers, ordered from high to low.
+Subarrays, if present, come out first.
+@end table
+
+The array traversal order is determined before the @code{for} loop
+starts to run. Changing @code{PROCINFO["sorted_in"]} in the loop body
+does not affect the loop.
+For example:
@example
-split("", array)
+$ @kbd{gawk '}
+> @kbd{BEGIN @{}
+> @kbd{ a[4] = 4}
+> @kbd{ a[3] = 3}
+> @kbd{ for (i in a)}
+> @kbd{ print i, a[i]}
+> @kbd{@}'}
+@print{} 4 4
+@print{} 3 3
+$ @kbd{gawk '}
+> @kbd{BEGIN @{}
+> @kbd{ PROCINFO["sorted_in"] = "@@ind_str_asc"}
+> @kbd{ a[4] = 4}
+> @kbd{ a[3] = 3}
+> @kbd{ for (i in a)}
+> @kbd{ print i, a[i]}
+> @kbd{@}'}
+@print{} 3 3
+@print{} 4 4
@end example
-@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.
+When sorting an array by element values, if a value happens to be
+a subarray then it is considered to be greater than any string or
+numeric value, regardless of what the subarray itself contains,
+and all subarrays are treated as being equal to each other. Their
+order relative to each other is determined by their index strings.
-@quotation 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:
+Here are some additional things to bear in mind about sorted
+array traversal:
+
+@itemize @value{BULLET}
+@item
+The value of @code{PROCINFO["sorted_in"]} is global. That is, it affects
+all array traversal @code{for} loops. If you need to change it within your
+own code, you should see if it's defined and save and restore the value:
@example
-a[1] = 3
-delete a
-a = 3
+@dots{}
+if ("sorted_in" in PROCINFO) @{
+ save_sorted = PROCINFO["sorted_in"]
+ PROCINFO["sorted_in"] = "@@val_str_desc" # or whatever
+@}
+@dots{}
+if (save_sorted)
+ PROCINFO["sorted_in"] = save_sorted
@end example
-@end quotation
+
+@item
+As already mentioned, the default array traversal order is represented by
+@code{"@@unsorted"}. You can also get the default behavior by assigning
+the null string to @code{PROCINFO["sorted_in"]} or by just deleting the
+@code{"sorted_in"} element from the @code{PROCINFO} array with
+the @code{delete} statement.
+(The @code{delete} statement hasn't been described yet; @pxref{Delete}.)
+@end itemize
+
+In addition, @command{gawk} provides built-in functions for
+sorting arrays; see @ref{Array Sorting Functions}.
@node Numeric Array Subscripts
@section Using Numbers to Subscript Arrays
@cindex numbers, as array subscripts
-@cindex arrays, subscripts
+@cindex arrays, numeric subscripts
@cindex subscripts in arrays, numbers as
-@cindex @code{CONVFMT} variable, array subscripts and
+@cindex @code{CONVFMT} variable, and array subscripts
An important aspect to remember about arrays 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
+This means that the value of the predefined variable @code{CONVFMT} can
affect how your program accesses elements of an array. For example:
@example
@@ -13587,12 +16204,13 @@ 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 different from @code{"12.153"}.
+because @code{"12.15"} is different from @code{"12.153"}.
-@cindex converting, during subscripting
+@cindex converting integer array subscripts
+@cindex integer array indices
According to the rules for conversions
(@pxref{Conversion}), integer
-values are always converted to strings as integers, no matter what the
+values always convert to strings as integers, no matter what the
value of @code{CONVFMT} may happen to be. So the usual case of
the following works:
@@ -13604,19 +16222,19 @@ for (i = 1; i <= maxsub; i++)
The ``integer values always convert to strings as integers'' rule
has an additional consequence for array indexing.
Octal and hexadecimal constants
+@ifnotdocbook
(@pxref{Nondecimal-numbers})
+@end ifnotdocbook
+@ifdocbook
+(covered in @ref{Nondecimal-numbers})
+@end ifdocbook
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!
+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 since they can sometimes have a subtle
+things work as you would expect them to. But it is useful to have a precise
+knowledge of the actual rules, as they can sometimes have a subtle
effect on your programs.
@node Uninitialized Subscripts
@@ -13636,14 +16254,14 @@ $ @kbd{echo 'line 1}
> @kbd{line 2}
> @kbd{line 3' | awk '@{ l[lines] = $0; ++lines @}}
> @kbd{END @{}
-> @kbd{for (i = lines-1; i >= 0; --i)}
+> @kbd{for (i = lines - 1; i >= 0; i--)}
> @kbd{print l[i]}
> @kbd{@}'}
@print{} line 3
@print{} line 2
@end example
-Unfortunately, the very first line of input data did not come out in the
+Unfortunately, the very first line of input data did not appear in the
output!
Upon first glance, we would think that this program should have worked.
@@ -13660,7 +16278,7 @@ The following version of the program works correctly:
@example
@{ l[lines++] = $0 @}
END @{
- for (i = lines - 1; i >= 0; --i)
+ for (i = lines - 1; i >= 0; i--)
print l[i]
@}
@end example
@@ -13679,23 +16297,136 @@ Even though it is somewhat unusual, the null string
if @option{--lint} is provided
on the command line (@pxref{Options}).
-@node Multi-dimensional
+@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-expression}]
+@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 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, and deleting array elements
+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.
+However, 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 common extensions, @code{delete} to delete entire arrays
+@cindex extensions, common@comma{} @code{delete} to delete entire arrays
+@cindex arrays, deleting entire contents
+@cindex deleting entire arrays
+@cindex @code{delete} @var{array}
+@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
+
+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.
+
+This form of the @code{delete} statement is also supported
+by BWK @command{awk} and @command{mawk}, as well as
+by a number of other implementations.
+
+@cindex Brian Kernighan's @command{awk}
+@quotation NOTE
+For many years, using @code{delete} without a subscript was a common
+extension. In September 2012, it was accepted for inclusion into the
+POSIX standard. See @uref{http://austingroupbugs.net/view.php?id=544,
+the Austin Group website}.
+@end quotation
+
+@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.
+
+@quotation CAUTION
+Deleting all the elements from an array does not change its type; you cannot
+clear 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
+@end quotation
+
+@node Multidimensional
@section Multidimensional Arrays
@menu
-* Multi-scanning:: Scanning multidimensional arrays.
+* Multiscanning:: Scanning multidimensional arrays.
@end menu
@cindex subscripts in arrays, multidimensional
@cindex arrays, multidimensional
-A multidimensional array is an array in which an element is identified
+A @dfn{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
+two-dimensional array requires two indices. The usual way (in many
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
+@cindex @code{SUBSEP} variable, and multidimensional arrays
Multidimensional arrays are supported in @command{awk} through
concatenation of indices into one string.
@command{awk} converts the indices into strings
@@ -13727,16 +16458,18 @@ combined strings that are ambiguous. Suppose that @code{SUBSEP} is
"b@@c"]}} are indistinguishable because both are actually
stored as @samp{foo["a@@b@@c"]}.
+@cindex @code{in} operator, index existence in multidimensional arrays
To test whether a particular index sequence exists in a
multidimensional array, use the same operator (@code{in}) that is
-used for single dimensional arrays. Write the whole sequence of indices
+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}
+if ((@var{subscript1}, @var{subscript2}, @dots{}) in @var{array})
+ @dots{}
@end example
-The following example treats its input as a two-dimensional array of
+Here is an example that 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:
@@ -13781,16 +16514,18 @@ the program produces the following output:
3 2 1 6
@end example
-@node Multi-scanning
+@node Multiscanning
@subsection 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'' array. There cannot be one, because, in truth,
+@command{awk} does not have
+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
+@cindex scanning multidimensional arrays
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
@@ -13813,7 +16548,7 @@ 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
+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
@@ -13832,11 +16567,13 @@ separate indices is recovered.
@node Arrays of Arrays
@section Arrays of Arrays
+@cindex arrays of arrays
-@command{gawk} supports arrays of
+@command{gawk} goes beyond standard @command{awk}'s multidimensional
+array access and provides true arrays of
arrays. Elements of a subarray are referred to by their own indices
enclosed in square brackets, just like the elements of the main array.
-For example, the following creates a two-element subarray at index @samp{1}
+For example, the following creates a two-element subarray at index @code{1}
of the main array @code{a}:
@example
@@ -13848,7 +16585,7 @@ This simulates a true two-dimensional array. Each subarray element can
contain another subarray as a value, which in turn can hold other arrays
as well. In this way, you can create arrays of three or more dimensions.
The indices can be any @command{awk} expression, including scalars
-separated by commas (that is, a regular @command{awk} simulated
+separated by commas (i.e., a regular @command{awk} simulated
multidimensional subscript). So the following is valid in
@command{gawk}:
@@ -13859,14 +16596,15 @@ a[1][3][1, "name"] = "barney"
Each subarray and the main array can be of different length. In fact, the
elements of an array or its subarray do not all have to have the same
type. This means that the main array and any of its subarrays can be
-non-rectangular, or jagged in structure. One can assign a scalar value to
-the index @samp{4} of the main array @code{a}:
+non-rectangular, or jagged in structure. You can assign a scalar value to
+the index @code{4} of the main array @code{a}, even though @code{a[1]}
+is itself an array and not a scalar:
@example
a[4] = "An element in a jagged array"
@end example
-
-The terms @dfn{dimension}, @dfn{row} and @dfn{column} are
+
+The terms @dfn{dimension}, @dfn{row}, and @dfn{column} are
meaningless when applied
to such an array, but we will use ``dimension'' henceforth to imply the
maximum number of indices needed to refer to an existing element. The
@@ -13881,7 +16619,7 @@ a[4][5][6][7] = "An element in a four-dimensional array"
@end example
@noindent
-This removes the scalar value from index @samp{4} and then inserts a
+This removes the scalar value from index @code{4} and then inserts a
subarray of subarray of subarray containing a scalar. You can also
delete an entire subarray or subarray of subarrays:
@@ -13922,14 +16660,14 @@ The @samp{for (item in array)} statement (@pxref{Scanning an Array})
can be nested to scan all the
elements of an array of arrays if it is rectangular in structure. In order
to print the contents (scalar values) of a two-dimensional array of arrays
-(i.e., in which each first-level element is itself an
-array, not necessarily of the same length)
+(i.e., in which each first-level element is itself an
+array, not necessarily of the same length)
you could use the following code:
@example
for (i in array)
for (j in array[i])
- print array[i][j]
+ print array[i][j]
@end example
The @code{isarray()} function (@pxref{Type Functions})
@@ -13939,15 +16677,17 @@ lets you test if an array element is itself an array:
for (i in array) @{
if (isarray(array[i]) @{
for (j in array[i]) @{
- print array[i][j]
+ print array[i][j]
@}
@}
+ else
+ print array[i]
@}
@end example
If the structure of a jagged array of arrays is known in advance,
you can often devise workarounds using control statements. For example,
-the following code prints the elements of our main array @code{a}:
+the following code prints the elements of our main array @code{a}:
@example
for (i in a) @{
@@ -13957,13 +16697,13 @@ for (i in a) @{
print a[i][j][k]
@} else
print a[i][j]
- @}
+ @}
@}
@end example
@noindent
-@xref{Walking Arrays}, for a user-defined function that will ``walk'' an
-arbitrarily-dimensioned array of arrays.
+@DBXREF{Walking Arrays} for a user-defined function that ``walks'' an
+arbitrarily dimensioned array of arrays.
Recall that a reference to an uninitialized array element yields a value
of @code{""}, the null string. This has one important implication when you
@@ -13982,20 +16722,76 @@ creating an arbitrary index:
$ @kbd{gawk 'BEGIN @{ b[1][1] = ""; split("a b c d", b[1]); print b[1][1] @}'}
@print{} a
@end example
-@c ENDOFRANGE arrs
+
+@node Arrays Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+Standard @command{awk} provides one-dimensional associative arrays
+(arrays indexed by string values). All arrays are associative; numeric
+indices are converted automatically to strings.
+
+@item
+Array elements are referenced as @code{@var{array}[@var{indx}]}.
+Referencing an element creates it if it did not exist previously.
+
+@item
+The proper way to see if an array has an element with a given index
+is to use the @code{in} operator: @samp{@var{indx} in @var{array}}.
+
+@item
+Use @samp{for (@var{indx} in @var{array}) @dots{}} to scan through all the
+individual elements of an array. In the body of the loop, @var{indx} takes
+on the value of each element's index in turn.
+
+@item
+The order in which a @samp{for (@var{indx} in @var{array})} loop
+traverses an array is undefined in POSIX @command{awk} and varies among
+implementations. @command{gawk} lets you control the order by assigning
+special predefined values to @code{PROCINFO["sorted_in"]}.
+
+@item
+Use @samp{delete @var{array}[@var{indx}]} to delete an individual element.
+To delete all of the elements in an array,
+use @samp{delete @var{array}}.
+This latter feature has been a common extension for many
+years and is now standard, but may not be supported by all commercial
+versions of @command{awk}.
+
+@item
+Standard @command{awk} simulates multidimensional arrays by separating
+subscript values with a comma. The values are concatenated into a
+single string, separated by the value of @code{SUBSEP}. The fact
+that such a subscript was created in this way is not retained; thus
+changing @code{SUBSEP} may have unexpected consequences. You can use
+@samp{(@var{sub1}, @var{sub2}, @dots{}) in @var{array}} to see if such
+a multidimensional subscript exists in @var{array}.
+
+@item
+@command{gawk} provides true arrays of arrays. You use a separate
+set of square brackets for each dimension in such an array:
+@code{data[row][col]}, for example. Array elements may thus be either
+scalar values (number or string) or another array.
+
+@item
+Use the @code{isarray()} built-in function to determine if an array
+element is itself a subarray.
+
+@end itemize
+
@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, sort arrays, and internationalize and localize programs.
+bit manipulation, sort arrays,
+provide type information, 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.
@@ -14006,10 +16802,11 @@ The second half of this @value{CHAPTER} describes these
* Built-in:: Summarizes the built-in functions.
* User-defined:: Describes User-defined functions in detail.
* Indirect Calls:: Choosing the function to call at runtime.
+* Functions Summary:: Summary of functions.
@end menu
@node Built-in
-@section Built-in Functions
+@section Built-In Functions
@dfn{Built-in} functions are always available for
your @command{awk} program to call. This @value{SECTION} defines all
@@ -14032,7 +16829,7 @@ but are summarized here for your convenience.
@end menu
@node Calling Built-in
-@subsection Calling Built-in Functions
+@subsection Calling Built-In Functions
To call one of @command{awk}'s built-in functions, write the name of
the function followed
@@ -14042,7 +16839,7 @@ 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, but nonetheless it is good practice to avoid using whitespace
+opening parenthesis, but nonetheless 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.
@@ -14079,7 +16876,7 @@ right to left. For example:
@example
i = 5
-j = atan2(i++, i *= 2)
+j = atan2(++i, i *= 2)
@end example
If the order of evaluation is left to right, then @code{i} first becomes
@@ -14090,41 +16887,68 @@ two arguments 11 and 10.
@node Numeric Functions
@subsection Numeric Functions
+@cindex 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 atan2(@var{y}, @var{x})
-@cindex @code{atan2()} function
+@c @asis for docbook
+@table @asis
+@item @code{atan2(@var{y}, @var{x})}
+@cindexawkfunc{atan2}
+@cindex arctangent
Return the arctangent of @code{@var{y} / @var{x}} in radians.
+You can use @samp{pi = atan2(0, -1)} to retrieve the value of
+@value{PI}.
-@item cos(@var{x})
-@cindex @code{cos()} function
+@item @code{cos(@var{x})}
+@cindexawkfunc{cos}
+@cindex cosine
Return the cosine of @var{x}, with @var{x} in radians.
-@item exp(@var{x})
-@cindex @code{exp()} function
+@item @code{div(@var{numerator}, @var{denominator}, @var{result})}
+@cindexawkfunc{div}
+@cindex div
+Perform integer division, similar to the standard C function of the
+same name. First, truncate @code{numerator} and @code{denominator}
+towards zero, creating integer values. Clear the @code{result}
+array, and then set @code{result["quotient"]} to the result of
+@samp{numerator / denominator}, truncated towards zero to an integer,
+and set @code{result["remainder"]} to the result of @samp{numerator %
+denominator}, truncated towards zero to an integer. This function is
+primarily intended for use with arbitrary length integers; it avoids
+creating MPFR arbitrary precision floating-point values (@pxref{Arbitrary
+Precision Integers}).
+
+This function is a @code{gawk} extension. It is not available in
+compatibility mode (@pxref{Options}).
+
+@item @code{exp(@var{x})}
+@cindexawkfunc{exp}
+@cindex exponent
Return the exponential of @var{x} (@code{e ^ @var{x}}) or report
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 int(@var{x})
-@cindex @code{int()} function
+@item @code{int(@var{x})}
+@cindexawkfunc{int}
+@cindex round to nearest integer
Return 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 log(@var{x})
-@cindex @code{log()} function
+@item @code{log(@var{x})}
+@cindexawkfunc{log}
+@cindex logarithm
Return the natural logarithm of @var{x}, if @var{x} is positive;
-otherwise, report an error.
+otherwise, return @code{NaN} (``not a number'') on IEEE 754 systems.
+Additionally, @command{gawk} prints a warning message when @code{x}
+is negative.
-@item rand()
-@cindex @code{rand()} function
+@item @code{rand()}
+@cindexawkfunc{rand}
@cindex random numbers, @code{rand()}/@code{srand()} functions
Return a random number. The values of @code{rand()} are
uniformly distributed between zero and one.
@@ -14140,8 +16964,9 @@ 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())
+function randint(n)
+@{
+ return int(n * rand())
@}
@end example
@@ -14161,12 +16986,11 @@ 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))
+ printf("%d points\n", roll(6) + roll(6) + roll(6))
@}
@end example
-@cindex numbers, random
+@cindex seeding random number generator
@cindex random numbers, seed of
@quotation CAUTION
In most @command{awk} implementations, including @command{gawk},
@@ -14181,25 +17005,27 @@ the seed to a value that is different in each run. To do this,
use @code{srand()}.
@end quotation
-@item sin(@var{x})
-@cindex @code{sin()} function
+@item @code{sin(@var{x})}
+@cindexawkfunc{sin}
+@cindex sine
Return the sine of @var{x}, with @var{x} in radians.
-@item sqrt(@var{x})
-@cindex @code{sqrt()} function
+@item @code{sqrt(@var{x})}
+@cindexawkfunc{sqrt}
+@cindex square root
Return the positive square root of @var{x}.
@command{gawk} prints a warning message
if @var{x} is negative. Thus, @code{sqrt(4)} is 2.
-@item srand(@r{[}@var{x}@r{]})
-@cindex @code{srand()} function
+@item @code{srand(}[@var{x}]@code{)}
+@cindexawkfunc{srand}
Set 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
+that although 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.
@@ -14218,27 +17044,43 @@ 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.
+
+POSIX does not specify the initial seed; it differs among @command{awk}
+implementations.
@end table
@node String Functions
@subsection String-Manipulation Functions
+@cindex string-manipulation functions
+
+The functions in this @value{SECTION} look at or change the text of one
+or more strings.
+
+@code{gawk} understands locales (@pxref{Locales}), and does all
+string processing in terms of @emph{characters}, not @emph{bytes}.
+This distinction is particularly important to understand for locales
+where one character may be represented by multiple bytes. Thus, for
+example, @code{length()} returns the number of characters in a string,
+and not the number of bytes used to represent those characters. Similarly,
+@code{index()} works with character indices, and not byte indices.
-The functions in this @value{SECTION} look at or change the text of one or more
-strings.
-@code{gawk} understands locales (@pxref{Locales}), and does all string processing in terms of
-@emph{characters}, not @emph{bytes}. This distinction is particularly important
-to understand for locales where one character
-may be represented by multiple bytes. Thus, for example, @code{length()}
-returns the number of characters in a string, and not the number of bytes
-used to represent those characters, Similarly, @code{index()} works with
-character indices, and not byte indices.
+@quotation CAUTION
+A number of functions deal with indices into strings. For these
+functions, the first character of a string is at position (index) one.
+This is different from C and the languages descended from it, where the
+first character is at position zero. You need to remember this when
+doing index calculations, particularly if you are used to C.
+@end quotation
In the following list, optional parameters are enclosed in square brackets@w{ ([ ]).}
Several functions perform string substitution; the full discussion is
provided in the description of the @code{sub()} function, which comes
-towards the end since the list is presented in alphabetic order.
+toward the end, because the list is presented alphabetically.
+
Those functions that are specific to @command{gawk} are marked with a
-pound sign@w{ (@samp{#}):}
+pound sign (@samp{#}). They are not available in compatibility mode
+(@pxref{Options}):
+
@menu
* Gory Details:: More than you want to know about @samp{\} and
@@ -14246,32 +17088,38 @@ pound sign@w{ (@samp{#}):}
@code{gensub()}.
@end menu
-@table @code
-@item asort(@var{source} @r{[}, @var{dest} @r{[}, @var{how} @r{]} @r{]}) #
+@c @asis for docbook
+@table @asis
+@item @code{asort(}@var{source} [@code{,} @var{dest} [@code{,} @var{how} ] ]@code{) #}
+@itemx @code{asorti(}@var{source} [@code{,} @var{dest} [@code{,} @var{how} ] ]@code{) #}
+@cindexgawkfunc{asorti}
+@cindex sort array
@cindex arrays, elements, retrieving number of
-@cindex @code{asort()} function (@command{gawk})
+@cindexgawkfunc{asort}
+@cindex sort array indices
+These two functions are similar in behavior, so they are described
+together.
+
+@quotation NOTE
+The following description ignores the third argument, @var{how}, as it
+requires understanding features that we have not discussed yet. Thus,
+the discussion here is a deliberate simplification. (We do provide all
+the details later on; see @DBREF{Array Sorting Functions} for the full story.)
+@end quotation
+
+Both functions return the number of elements in the array @var{source}.
+For @command{asort()}, @command{gawk} sorts the values of @var{source}
+and replaces the indices of the sorted values of @var{source} 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.
+
@cindex @command{gawk}, @code{IGNORECASE} variable in
-@cindex @code{IGNORECASE} variable
-Return the number of elements in the array @var{source}.
-@command{gawk} sorts the contents of @var{source}
-and replaces the indices
-of the sorted values of @var{source} 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. The optional third
-argument @var{how} is a string which controls the rule for comparing values,
-and the sort direction. A single space is required between the
-comparison mode, @samp{string} or @samp{number}, and the direction specification,
-@samp{ascending} or @samp{descending}. You can omit direction and/or mode
-in which case it will default to @samp{ascending} and @samp{string}, respectively.
-An empty string "" is the same as the default @code{"ascending string"}
-for the value of @var{how}. If the @samp{source} array contains subarrays as values,
-they will come out last(first) in the @samp{dest} array for @samp{ascending}(@samp{descending})
-order specification. The value of @code{IGNORECASE} affects the sorting.
-The third argument can also be a user-defined function name in which case
-the value returned by the function is used to order the array elements
-before constructing the result array.
-@xref{Array Sorting Functions}, for more information.
+When comparing strings, @code{IGNORECASE} affects the sorting
+(@pxref{Array Sorting Functions}). If the
+@var{source} array contains subarrays as values (@pxref{Arrays of
+Arrays}), they will come last, after all scalar values.
+Subarrays are @emph{not} recursively sorted.
For example, if the contents of @code{a} are as follows:
@@ -14297,32 +17145,21 @@ a[2] = "de"
a[3] = "sac"
@end example
-In order to reverse the direction of the sorted results in the above example,
-@code{asort()} can be called with three arguments as follows:
+The @code{asorti()} function works similarly to @code{asort()}, however,
+the @emph{indices} are sorted, instead of the values. Thus, in the
+previous example, starting with the same initial set of indices and
+values in @code{a}, calling @samp{asorti(a)} would yield:
@example
-asort(a, a, "descending")
+a[1] = "first"
+a[2] = "last"
+a[3] = "middle"
@end example
-The @code{asort()} function is described in more detail in
-@ref{Array Sorting Functions}.
-@code{asort()} is a @command{gawk} extension; it is not available
-in compatibility mode (@pxref{Options}).
-
-@item asorti(@var{source} @r{[}, @var{dest} @r{[}, @var{how} @r{]} @r{]}) #
-@cindex @code{asorti()} function (@command{gawk})
-Return 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. (Here too,
-@code{IGNORECASE} affects the sorting.)
-
-The @code{asorti()} function is described in more detail in
-@ref{Array Sorting Functions}.
-@code{asorti()} is a @command{gawk} extension; it is not available
-in compatibility mode (@pxref{Options}).
-
-@item gensub(@var{regexp}, @var{replacement}, @var{how} @r{[}, @var{target}@r{]}) #
-@cindex @code{gensub()} function (@command{gawk})
+@item @code{gensub(@var{regexp}, @var{replacement}, @var{how}} [@code{, @var{target}}]@code{) #}
+@cindexgawkfunc{gensub}
+@cindex search and replace in strings
+@cindex substitute in string
Search the target string @var{target} for matches of the regular
expression @var{regexp}. If @var{how} is a string beginning with
@samp{g} or @samp{G} (short for ``global''), then replace all matches of @var{regexp} with
@@ -14331,7 +17168,7 @@ which match of @var{regexp} to replace. If no @var{target} is supplied,
use @code{$0}. It returns the modified string as the result
of the function and the original target string is @emph{not} changed.
-@code{gensub()} is a general substitution function. It's purpose is
+@code{gensub()} is a general substitution function. Its purpose is
to provide more features than the standard @code{sub()} and @code{gsub()}
functions.
@@ -14381,11 +17218,8 @@ 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 gsub(@var{regexp}, @var{replacement} @r{[}, @var{target}@r{]})
-@cindex @code{gsub()} function
+@item @code{gsub(@var{regexp}, @var{replacement}} [@code{, @var{target}}]@code{)}
+@cindexawkfunc{gsub}
Search @var{target} for
@emph{all} of the longest, leftmost, @emph{nonoverlapping} matching
substrings it can find and replace them with @var{replacement}.
@@ -14406,9 +17240,10 @@ 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 index(@var{in}, @var{find})
-@cindex @code{index()} function
-@cindex searching
+@item @code{index(@var{in}, @var{find})}
+@cindexawkfunc{index}
+@cindex search in string
+@cindex find substring in string
Search the string @var{in} for the first occurrence of the string
@var{find}, and return the position in characters where that occurrence
begins in the string @var{in}. Consider the following example:
@@ -14420,17 +17255,37 @@ $ @kbd{awk 'BEGIN @{ print index("peanut", "an") @}'}
@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
+@cindex dark corner, regexp as second argument to @code{index()}
+With BWK @command{awk} and @command{gawk},
+it is a fatal error to use a regexp constant for @var{find}.
+Other implementations allow it, simply treating the regexp
+constant as an expression meaning @samp{$0 ~ /regexp/}. @value{DARKCORNER}.
+
+@item @code{length(}[@var{string}]@code{)}
+@cindexawkfunc{length}
+@cindex string length
+@cindex length of string
Return 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 five. By
-contrast, @code{length(15 * 35)} works out to three. In this example, 15 * 35 =
-525, and 525 is then converted to the string @code{"525"}, which has
+contrast, @code{length(15 * 35)} works out to three. In this example,
+@iftex
+@math{15 @cdot 35 = 525},
+@end iftex
+@ifnottex
+@ifnotdocbook
+15 * 35 = 525,
+@end ifnotdocbook
+@end ifnottex
+@docbook
+15 &sdot; 35 = 525, @c
+@end docbook
+and 525 is then converted to the string @code{"525"}, which has
three characters.
+@cindex length of input record
+@cindex input record, length of
If no argument is supplied, @code{length()} returns the length of @code{$0}.
@c @cindex historical features
@@ -14469,6 +17324,8 @@ warning about this.
@cindex common extensions, @code{length()} applied to an array
@cindex extensions, common@comma{} @code{length()} applied to an array
@cindex differences between @command{gawk} and @command{awk}
+@cindex number of array elements
+@cindex array, number of elements
With @command{gawk} and several other @command{awk} implementations, when given an
array argument, the @code{length()} function returns the number of elements
in the array. @value{COMMONEXT}
@@ -14481,18 +17338,20 @@ If @option{--lint} is provided on the command line
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
+@item @code{match(@var{string}, @var{regexp}} [@code{, @var{array}}]@code{)}
+@cindexawkfunc{match}
+@cindex string, regular expression match
+@cindex match regexp in string
Search @var{string} for the
longest, leftmost substring matched by the regular expression,
-@var{regexp} and return the character position, or @dfn{index},
+@var{regexp} and return the character position (index)
at which that substring begins (one, if it starts at the beginning of
@var{string}). If no match is found, return zero.
The @var{regexp} argument may be either a regexp constant
-(@code{/@dots{}/}) or a string constant (@code{"@dots{}"}).
+(@code{/}@dots{}@code{/}) or a string constant (@code{"}@dots{}@code{"}).
In the latter case, the string is treated as a regexp to be matched.
-@xref{Computed Regexps}, for a
+@DBXREF{Computed Regexps} for a
discussion of the difference between the two forms, and the
implications for writing your program correctly.
@@ -14505,8 +17364,8 @@ for @code{match()}, the order is the same as for the @samp{~} operator:
@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
+The @code{match()} function sets the predefined variable @code{RSTART} to
+the index. It also sets the predefined 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.
@@ -14515,13 +17374,12 @@ 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
+ if ($1 == "FIND")
+ regex = $2
+ else @{
+ where = match($0, regex)
+ if (where != 0)
+ print "Match of", regex, "found at", where, "in", $0
@}
@}
@c endfile
@@ -14586,7 +17444,7 @@ $ @kbd{echo foooobazbarrrrr |}
@end example
There may not be subscripts for the start and index for every parenthesized
-subexpression, since they may not all have matched text; thus they
+subexpression, because they may not all have matched text; thus they
should be tested for with the @code{in} operator
(@pxref{Reference to Elements}).
@@ -14596,8 +17454,9 @@ The @var{array} argument to @code{match()} is a
(@pxref{Options}),
using a third argument is a fatal error.
-@item patsplit(@var{string}, @var{array} @r{[}, @var{fieldpat} @r{[}, @var{seps} @r{]} @r{]}) #
-@cindex @code{patsplit()} function
+@item @code{patsplit(@var{string}, @var{array}} [@code{, @var{fieldpat}} [@code{, @var{seps}} ] ]@code{) #}
+@cindexgawkfunc{patsplit}
+@cindex split string into array
Divide
@var{string} into pieces defined by @var{fieldpat}
and store the pieces in @var{array} and the separator strings in the
@@ -14616,38 +17475,31 @@ Any leading separator will be in @code{@var{seps}[0]}.
The @code{patsplit()} function splits strings into pieces in a
manner similar to the way input lines are split into fields using @code{FPAT}
-(@pxref{Splitting By Content}.
+(@pxref{Splitting By Content}).
Before splitting the string, @code{patsplit()} deletes any previously existing
elements in the arrays @var{array} and @var{seps}.
-@cindex troubleshooting, @code{patsplit()} function
-The @code{patsplit()} function is a
-@command{gawk} extension. In compatibility mode
-(@pxref{Options}),
-it is not available.
-
-@item split(@var{string}, @var{array} @r{[}, @var{fieldsep} @r{[}, @var{seps} @r{]} @r{]})
-@cindex @code{split()} function
+@item @code{split(@var{string}, @var{array}} [@code{, @var{fieldsep}} [@code{, @var{seps}} ] ]@code{)}
+@cindexawkfunc{split}
Divide @var{string} into pieces separated by @var{fieldsep}
and store the pieces in @var{array} and the separator strings in the
@var{seps} 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;
-@pxref{Regexp Field Splitting}).
+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.
-@var{seps} is a @command{gawk} extension with @code{@var{seps}[@var{i}]}
+@var{seps} is a @command{gawk} extension with @code{@var{seps}[@var{i}]}
being the separator string
-between @code{@var{array}[@var{i}]} and @code{@var{array}[@var{i}+1]}.
+between @code{@var{array}[@var{i}]} and @code{@var{array}[@var{i}+1]}.
If @var{fieldsep} is a single
-space then any leading whitespace goes into @code{@var{seps}[0]} and
+space then any leading whitespace goes into @code{@var{seps}[0]} and
any trailing
-whitespace goes into @code{@var{seps}[@var{n}]} where @var{n} is the
-return value of
-@code{split()} (that is, the number of elements in @var{array}).
+whitespace goes into @code{@var{seps}[@var{n}]} where @var{n} is the
+return value of
+@code{split()} (i.e., the number of elements in @var{array}).
The @code{split()} function splits strings into pieces in a
manner similar to the way input lines are split into fields. For example:
@@ -14657,7 +17509,7 @@ split("cul-de-sac", a, "-", seps)
@end example
@noindent
-@cindex strings, splitting
+@cindex strings splitting, example
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:
@@ -14683,7 +17535,7 @@ As with input field-splitting, when the value of @var{fieldsep} is
the elements of
@var{array} but not in @var{seps}, and the elements
are separated by runs of whitespace.
-Also as with input field-splitting, if @var{fieldsep} is the null string, each
+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.
@value{COMMONEXT}
@@ -14697,7 +17549,7 @@ the third argument to be a regexp constant (@code{/abc/}) as well as a
string.
@value{DARKCORNER}
The POSIX standard allows this as well.
-@xref{Computed Regexps}, for a
+@DBXREF{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.
@@ -14712,8 +17564,11 @@ 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
+In POSIX mode (@pxref{Options}), the fourth argument is not allowed.
+
+@item @code{sprintf(@var{format}, @var{expression1}, @dots{})}
+@cindexawkfunc{sprintf}
+@cindex formatting strings
Return (without printing) the string that @code{printf} would
have printed out with the same arguments
(@pxref{Printf}).
@@ -14726,8 +17581,9 @@ pival = sprintf("pi = %.2f (approx.)", 22/7)
@noindent
assigns the string @w{@samp{pi = 3.14 (approx.)}} to the variable @code{pival}.
-@cindex @code{strtonum()} function (@command{gawk})
-@item strtonum(@var{str}) #
+@cindexgawkfunc{strtonum}
+@cindex convert string to number
+@item @code{strtonum(@var{str}) #}
Examine @var{str} and return 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
@@ -14744,17 +17600,14 @@ 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.}
+@DBXREF{Nondecimal Data} for more information.}
Note also that @code{strtonum()} uses the current locale's decimal point
for recognizing numbers (@pxref{Locales}).
-@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
+@item @code{sub(@var{regexp}, @var{replacement}} [@code{, @var{target}}]@code{)}
+@cindexawkfunc{sub}
+@cindex replace in string
Search @var{target}, which is treated as a string, for the
leftmost, longest substring matched by the regular expression @var{regexp}.
Modify the entire string
@@ -14763,9 +17616,9 @@ The modified string becomes the new value of @var{target}.
Return the number of substitutions made (zero or one).
The @var{regexp} argument may be either a regexp constant
-(@code{/@dots{}/}) or a string constant (@code{"@dots{}"}).
+(@code{/}@dots{}@code{/}) or a string constant (@code{"}@dots{}@code{"}).
In the latter case, the string is treated as a regexp to be matched.
-@xref{Computed Regexps}, for a
+@DBXREF{Computed Regexps} for a
discussion of the difference between the two forms, and the
implications for writing your program correctly.
@@ -14853,8 +17706,9 @@ 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 substr(@var{string}, @var{start} @r{[}, @var{length}@r{]})
-@cindex @code{substr()} function
+@item @code{substr(@var{string}, @var{start}} [@code{, @var{length}} ]@code{)}
+@cindexawkfunc{substr}
+@cindex substring
Return 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
@@ -14868,9 +17722,10 @@ suffix is also returned
if @var{length} is greater than the number of characters remaining
in the string, counting from character @var{start}.
+@cindex Brian Kernighan's @command{awk}
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:
-Brian Kernighan's @command{awk} acts this way, and therefore @command{gawk}
+BWK @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.
@@ -14910,24 +17765,79 @@ 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
+@cindex strings, converting letter case
+@item @code{tolower(@var{string})}
+@cindexawkfunc{tolower}
+@cindex convert string to lower case
Return 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
+@item @code{toupper(@var{string})}
+@cindexawkfunc{toupper}
+@cindex convert string to upper case
Return 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
+@cindex sidebar, Matching the Null String
+@ifdocbook
+@docbook
+<sidebar><title>Matching the Null String</title>
+@end docbook
+
+@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
+$ @kbd{echo abc | awk '@{ gsub(/m*/, "X"); print @}'}
+@print{} XaXbXcX
+@end example
+
+@noindent
+Although this makes a certain amount of sense, it can be surprising.
+
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{Matching the Null String}
+
+
+@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
+$ @kbd{echo abc | awk '@{ gsub(/m*/, "X"); print @}'}
+@print{} XaXbXcX
+@end example
+
+@noindent
+Although this makes a certain amount of sense, it can be surprising.
+@end cartouche
+@end ifnotdocbook
+
+
@node Gory Details
-@subsubsection More About @samp{\} and @samp{&} with @code{sub()}, @code{gsub()}, and @code{gensub()}
+@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
@@ -14937,23 +17847,30 @@ Nonalphabetic characters are left unchanged. For example,
@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
+
+@quotation CAUTION
+This subsubsection has been reported to cause headaches.
+You might want to skip it upon first reading.
+@end quotation
+
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.
+and builds an internal copy of it to execute.
Then there is the runtime level, which is when @command{awk} actually scans the
replacement string to determine what to generate.
+@cindex Brian Kernighan's @command{awk}
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, you must type two backslashes at the lexical level.
When a character that is not valid for an escape sequence follows the
-@samp{\}, Brian Kernighan's @command{awk} and @command{gawk} both simply remove the initial
+@samp{\}, BWK @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"}.
@@ -14967,36 +17884,37 @@ 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 @code{sub()} and @code{gsub()}}
+@caption{Historical escape sequence processing for @code{sub()} and @code{gsub()}}
@tex
\vbox{\bigskip
-% This table has lots of &'s and \'s, so unspecialize them.
+% We need more characters for escape and tab ...
+\catcode`_ = 0
+\catcode`! = 4
+% ... since this table has lots of &'s and \'s, so we unspecialize them.
\catcode`\& = \other \catcode`\\ = \other
-% 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
+_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}
+_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}
+@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
@@ -15004,13 +17922,13 @@ through unchanged. This is illustrated in @ref{table-sub-escapes}.
@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}
+ @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
@@ -15026,109 +17944,44 @@ 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
+Several editions of the POSIX standard attempted to fix this problem
+but weren't successful. The details are irrelevant at this point in time.
-@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
+At one point, 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
+to produce a @samp{\} preceding the matched text.
+This is shown in
@ref{table-sub-proposed}.
@float Table,table-sub-proposed
-@caption{Proposed rules for sub and backslash}
+@caption{GNU @command{awk} rules for @code{sub()} and backslash}
@tex
\vbox{\bigskip
-% This table has lots of &'s and \'s, so unspecialize them.
+% We need more characters for escape and tab ...
+\catcode`_ = 0
+\catcode`! = 4
+% ... since this table has lots of &'s and \'s, so we unspecialize them.
\catcode`\& = \other \catcode`\\ = \other
-% 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
+_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}
+_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 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
@@ -15137,10 +17990,10 @@ to produce a @samp{\} preceding the matched text. This is shown in
@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{\\\&} 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
@@ -15153,13 +18006,13 @@ 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.
+@command{gawk} 3.0 and 3.1 follow these rules for @code{sub()} and
+@code{gsub()}. The POSIX standard took much longer to be revised than
+was expected. In addition, the @command{gawk} maintainer's proposal was
+lost during the standardization process. The final rules are
+somewhat simpler. The results are similar except for one case.
+@cindex POSIX @command{awk}, functions and, @code{gsub()}/@code{sub()}
The 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.
@@ -15169,28 +18022,29 @@ These rules are presented in @ref{table-posix-sub}.
@caption{POSIX rules for @code{sub()} and @code{gsub()}}
@tex
\vbox{\bigskip
-% This table has lots of &'s and \'s, so unspecialize them.
+% We need more characters for escape and tab ...
+\catcode`_ = 0
+\catcode`! = 4
+% ... since this table has lots of &'s and \'s, so we unspecialize them.
\catcode`\& = \other \catcode`\\ = \other
-% 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
+_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}
+_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 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
@@ -15199,10 +18053,10 @@ These rules are presented in @ref{table-posix-sub}.
@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{\\\&} 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
@@ -15214,12 +18068,12 @@ is seen as @samp{\\} and produces @samp{\} instead of @samp{\\}.
Starting with @value{PVERSION} 3.1.4, @command{gawk} followed the POSIX rules
when @option{--posix} is specified (@pxref{Options}). Otherwise,
-it continued to follow the 1996 proposed rules, since
+it continued to follow the proposed rules, as
that had been its behavior for many years.
-When @value{PVERSION} 4.0.0, was released, the @command{gawk} maintainer
+When @value{PVERSION} 4.0.0 was released, the @command{gawk} maintainer
made the POSIX rules the default, breaking well over a decade's worth
-of backwards compatibility.@footnote{This was rather naive of him, despite
+of backward compatibility.@footnote{This was rather naive of him, despite
there being a note in this section indicating that the next major version
would move to the POSIX rules.} Needless to say, this was a bad idea,
and as of @value{PVERSION} 4.0.1, @command{gawk} resumed its historical
@@ -15234,34 +18088,35 @@ 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 @code{gensub()}}
+@caption{Escape sequence processing for @code{gensub()}}
@tex
\vbox{\bigskip
-% This table has lots of &'s and \'s, so unspecialize them.
+% We need more characters for escape and tab ...
+\catcode`_ = 0
+\catcode`! = 4
+% ... since this table has lots of &'s and \'s, so we unspecialize them.
\catcode`\& = \other \catcode`\\ = \other
-% 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
+_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}
+_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}
+@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
@@ -15269,12 +18124,12 @@ as shown in @ref{table-gensub-escapes}.
@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}
+ @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
@@ -15285,40 +18140,22 @@ 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
-$ @kbd{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
+@cindex 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
+@table @asis
+@item @code{close(}@var{filename} [@code{,} @var{how}]@code{)}
+@cindexawkfunc{close}
@cindex files, closing
+@cindex close file or coprocess
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},
+@DBXREF{Close Files And Pipes}
for more information.
When closing a coprocess, it is occasionally useful to first close
@@ -15330,46 +18167,59 @@ 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
-@cindex common extensions, @code{fflush()} function
-@cindex extensions, common@comma{} @code{fflush()} function
+Note that the second argument to @code{close()} is a @command{gawk}
+extension; it is not available in compatibility mode (@pxref{Options}).
+
+@item @code{fflush(}[@var{filename}]@code{)}
+@cindexawkfunc{fflush}
+@cindex flush buffered output
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. @value{COMMONEXT}.
+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
+Many utility programs @dfn{buffer} their output (i.e., they save information
to write to a disk file or the screen in memory until there is enough
-for it to be worthwhile to send the data to the output device.
+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.
+it is necessary to force a program to @dfn{flush} its buffers (i.e.,
+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 Brian Kernighan's
-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 extensions, common@comma{} @code{fflush()} function
+@cindex Brian Kernighan's @command{awk}
+Brian Kernighan added @code{fflush()} to his @command{awk} in April
+1992. For two decades, it was a common extension. In December
+2012, it was accepted for inclusion into the POSIX standard.
+See @uref{http://austingroupbugs.net/view.php?id=634, the Austin Group website}.
-@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.
-Brian Kernighan's @command{awk} also supports these extensions.
+POSIX standardizes @code{fflush()} as follows: if there
+is no argument, or if the argument is the null string (@w{@code{""}}),
+then @command{awk} flushes the buffers for @emph{all} open output files
+and pipes.
+
+@quotation NOTE
+Prior to @value{PVERSION} 4.0.2, @command{gawk}
+would flush only the standard output if there was no argument,
+and flush all output files and pipes if the argument was the null
+string. This was changed in order to be compatible with Brian
+Kernighan's @command{awk}, in the hope that standardizing this
+feature in POSIX would then be easier (which indeed helped).
+
+With @command{gawk},
+you can use @samp{fflush("/dev/stdout")} if you wish to flush
+only the standard output.
+@end quotation
@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.
+otherwise, it returns non-zero. (@command{gawk} 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}.
@@ -15379,8 +18229,109 @@ 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 sidebar, Interactive Versus Noninteractive Buffering
+@ifdocbook
+@docbook
+<sidebar><title>Interactive Versus Noninteractive Buffering</title>
+@end docbook
+
+@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. On modern
+systems, this means your keyboard and screen.}
+
+@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
+$ @kbd{awk '@{ print $1 + $2 @}'}
+@kbd{1 1}
+@print{} 2
+@kbd{2 3}
+@print{} 5
+@kbd{Ctrl-d}
+@end example
+
+@noindent
+Each line of output is printed immediately. Compare that behavior
+with this example:
+
+@example
+$ @kbd{awk '@{ print $1 + $2 @}' | cat}
+@kbd{1 1}
+@kbd{2 3}
+@kbd{Ctrl-d}
+@print{} 2
+@print{} 5
+@end example
+
+@noindent
+Here, no output is printed until after the @kbd{Ctrl-d} is typed, because
+it is all buffered and sent down the pipe to @command{cat} in one shot.
+
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{Interactive Versus Noninteractive 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. On modern
+systems, this means your keyboard and screen.}
+
+@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
+$ @kbd{awk '@{ print $1 + $2 @}'}
+@kbd{1 1}
+@print{} 2
+@kbd{2 3}
+@print{} 5
+@kbd{Ctrl-d}
+@end example
+
+@noindent
+Each line of output is printed immediately. Compare that behavior
+with this example:
+
+@example
+$ @kbd{awk '@{ print $1 + $2 @}' | cat}
+@kbd{1 1}
+@kbd{2 3}
+@kbd{Ctrl-d}
+@print{} 2
+@print{} 5
+@end example
+
+@noindent
+Here, no output is printed until after the @kbd{Ctrl-d} is typed, because
+it is all buffered and sent down the pipe to @command{cat} in one shot.
+@end cartouche
+@end ifnotdocbook
+
+@item @code{system(@var{command})}
+@cindexawkfunc{system}
+@cindex invoke shell command
@cindex interacting with other programs
Execute the operating-system
command @var{command} and then return to the @command{awk} program.
@@ -15411,7 +18362,7 @@ close("/bin/sh")
@noindent
@cindex troubleshooting, @code{system()} function
-@cindex @code{--sandbox} option, disabling @code{system()} function
+@cindex @option{--sandbox} option, disabling @code{system()} function
However, if your @command{awk}
program is interactive, @code{system()} is useful for running large
self-contained programs, such as a shell or an editor.
@@ -15425,59 +18376,83 @@ When @option{--sandbox} is specified, the @code{system()} function is disabled
@end table
-@c fakenode --- for prepinfo
-@subheading Advanced Notes: Interactive Versus Noninteractive Buffering
-@cindex advanced features, buffering
-@cindex buffering, interactive vs.@: noninteractive
+@cindex sidebar, Controlling Output Buffering with @code{system()}
+@ifdocbook
+@docbook
+<sidebar><title>Controlling Output Buffering with @code{system()}</title>
+@end docbook
-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. On modern
-systems, this means your keyboard and screen.}
+@cindex buffers, flushing
+@cindex buffering, input/output
+@cindex output, buffering
-@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:
+The @code{fflush()} function provides explicit control over output buffering for
+individual files and pipes. However, its use is not portable to many older
+@command{awk} implementations. An alternative method to flush output
+buffers is to call @code{system()} with a null string as its argument:
@example
-$ @kbd{awk '@{ print $1 + $2 @}'}
-@kbd{1 1}
-@print{} 2
-@kbd{2 3}
-@print{} 5
-@kbd{@value{CTL}-d}
+system("") # flush output
@end example
@noindent
-Each line of output is printed immediately. Compare that behavior
-with this example:
+@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. Although 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
-$ @kbd{awk '@{ print $1 + $2 @}' | cat}
-@kbd{1 1}
-@kbd{2 3}
-@kbd{@value{CTL}-d}
-@print{} 2
-@print{} 5
+BEGIN @{
+ print "first print"
+ system("echo system echo")
+ print "second print"
+@}
@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.
+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.
+
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{Controlling Output Buffering with @code{system()}}
+
-@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
+individual files and pipes. However, its use is not portable to many older
@command{awk} implementations. An alternative method to flush output
buffers is to call @code{system()} with a null string as its argument:
@@ -15489,7 +18464,7 @@ system("") # flush output
@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
+idiom is not only useful, it is also efficient. Although 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
@@ -15526,17 +18501,16 @@ second print
If @command{awk} did not flush its buffers before calling @code{system()},
you would see the latter (undesirable) output.
+@end cartouche
+@end ifnotdocbook
@node Time Functions
@subsection Time Functions
+@cindex time 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
@@ -15545,10 +18519,26 @@ 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.''}
+1970-01-01 00:00:00 UTC, not counting leap
+@ifclear FOR_PRINT
+seconds.@footnote{@xref{Glossary}, especially the entries ``Epoch'' and ``UTC.''}
+@end ifclear
+@ifset FOR_PRINT
+seconds.
+@end ifset
All known POSIX-compliant systems support timestamps from 0 through
-@math{2^{31} - 1}, which is sufficient to represent times through
+@iftex
+@math{2^{31} - 1},
+@end iftex
+@ifnottex
+@ifnotdocbook
+2^31 - 1,
+@end ifnotdocbook
+@end ifnottex
+@docbook
+2<superscript>31</superscript> &minus; 1, @c
+@end docbook
+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.
@@ -15558,15 +18548,18 @@ epoch.
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
+not specified in the POSIX standard.@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.}
+However, recent versions
+of @command{mawk} (@pxref{Other Versions}) also support these functions.
Optional parameters are enclosed in square brackets ([ ]):
-@table @code
-@item mktime(@var{datespec})
-@cindex @code{mktime()} function (@command{gawk})
+@c @asis for docbook
+@table @asis
+@item @code{mktime(@var{datespec})}
+@cindexgawkfunc{mktime}
+@cindex generate time values
Turn @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
@@ -15594,9 +18587,9 @@ is out of range, @code{mktime()} returns @minus{}1.
@cindex @command{gawk}, @code{PROCINFO} array in
@cindex @code{PROCINFO} array
-@item strftime(@r{[}@var{format} @r{[}, @var{timestamp} @r{[}, @var{utc-flag}@r{]]]})
-@c STARTOFRANGE strf
-@cindex @code{strftime()} function (@command{gawk})
+@item @code{strftime(}[@var{format} [@code{,} @var{timestamp} [@code{,} @var{utc-flag}] ] ]@code{)}
+@cindexgawkfunc{strftime}
+@cindex format time string
Format the time specified by @var{timestamp}
based on the contents of the @var{format} string and return the result.
It is similar to the function of the same name in ISO C.
@@ -15606,18 +18599,19 @@ Mean Time). Otherwise, the value is formatted for the local time zone.
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
+Without a @var{format} argument, @code{strftime()} uses
the value of @code{PROCINFO["strftime"]} as the format string
(@pxref{Built-in Variables}).
The default string value is
@code{@w{"%a %b %e %H:%M:%S %Z %Y"}}. This format string produces
output that is equivalent to that of the @command{date} utility.
You can assign a new value to @code{PROCINFO["strftime"]} to
-change the default format.
+change the default format; see the following list for the various format directives.
-@item systime()
-@cindex @code{systime()} function (@command{gawk})
+@item @code{systime()}
+@cindexgawkfunc{systime}
@cindex timestamps
+@cindex current system time
Return 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.
@@ -15689,10 +18683,10 @@ This is the ISO 8601 date format.
@item %g
The year modulo 100 of the ISO 8601 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 8601 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.
+For example, January 1, 2012, is in week 53 of 2011. Thus, the year
+of its ISO 8601 week number is 2011, even though its year is 2012.
+Similarly, December 31, 2012, is in week 1 of 2013. Thus, the year
+of its ISO week number is 2013, even though its year is 2012.
@item %G
The full year of the ISO week number, as a decimal number.
@@ -15773,7 +18767,7 @@ The locale's ``appropriate'' time representation.
The year modulo 100 as a decimal number (00--99).
@item %Y
-The full year as a decimal number (e.g., 2011).
+The full year as a decimal number (e.g., 2015).
@c @cindex RFC 822
@c @cindex RFC 1036
@@ -15787,7 +18781,7 @@ 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
+``Alternative 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''
@@ -15800,24 +18794,13 @@ Other internationalization features are described in
A literal @samp{%}.
@end table
-If a conversion specifier is not one of the above, the behavior is
+If a conversion specifier is not one of those just listed, 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, 2012 in the United States is ``9/4/12.''
-In many countries in Europe, however, it is abbreviated ``4.9.12.''
-Thus, the @samp{%x} specification in a @code{"US"} locale might produce
-@samp{9/4/12}, while in a @code{"EUROPE"} locale, it might produce
-@samp{4.9.12}. The ISO C standard defines a default @code{"C"}
-locale, which is an environment that is typical of what many C programmers
-are used to.
-
For systems that are not yet fully standards-compliant,
@command{gawk} supplies a copy of
@code{strftime()} from the GNU C Library.
@@ -15838,11 +18821,11 @@ Single-digit numbers are padded with a space.
@ignore
@item %N
The ``Emperor/Era'' name.
-Equivalent to @code{%C}.
+Equivalent to @samp{%C}.
@item %o
The ``Emperor/Era'' year.
-Equivalent to @code{%y}.
+Equivalent to @samp{%y}.
@end ignore
@item %s
@@ -15853,9 +18836,8 @@ The time as a decimal timestamp in seconds since the epoch.
The date in VMS format (e.g., @samp{20-JUN-1991}).
@end ignore
@end table
-@c ENDOFRANGE strf
-Additionally, the alternate representations are recognized but their
+Additionally, the alternative representations are recognized but their
normal representations are used.
@cindex @code{date} utility, POSIX
@@ -15869,8 +18851,8 @@ 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 Wednesday, March 30, 2011.
+$ @kbd{date '+Today is %A, %B %d, %Y.'}
+@print{} Today is Monday, September 22, 2014.
@end example
Here is the @command{gawk} version of the @command{date} utility.
@@ -15890,7 +18872,7 @@ case $1 in
esac
gawk 'BEGIN @{
- format = "%a %b %e %H:%M:%S %Z %Y"
+ format = PROCINFO["strftime"]
exitval = 0
if (ARGC > 2)
@@ -15904,26 +18886,18 @@ gawk 'BEGIN @{
exit exitval
@}' "$@@"
@end example
-@c ENDOFRANGE tst
-@c ENDOFRANGE logftst
-@c ENDOFRANGE filogtst
-@c ENDOFRANGE gawtst
@node Bitwise Functions
@subsection Bit-Manipulation Functions
-@c STARTOFRANGE bit
+@cindex bit-manipulation functions
@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
+@i{I can explain it for you, but I can't understand it for you.}
+@author Anonymous
@end quotation
Many languages provide the ability to perform @dfn{bitwise} operations
@@ -15932,8 +18906,10 @@ 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}.
+@c 11/2014: Postprocessing turns the docbook informaltable
+@c into a table. Hurray for scripting!
@float Table,table-bitwise-ops
-@caption{Bitwise Operations}
+@caption{Bitwise operations}
@ifnottex
@ifnotdocbook
@display
@@ -15977,9 +18953,7 @@ Operands | 0 | 1 | 0 | 1 | 0 | 1
@end tex
@docbook
-<!-- FIXME: Fix ID and add xref in text. -->
-<table id="table-bitwise-ops">
-<title>Bitwise Operations</title>
+<informaltable>
<tgroup cols="7" colsep="1">
<colspec colname="c1"/>
@@ -16039,7 +19013,7 @@ Operands | 0 | 1 | 0 | 1 | 0 | 1
</tbody>
</tgroup>
-</table>
+</informaltable>
@end docbook
@end float
@@ -16063,42 +19037,47 @@ 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.}
+fill with 1's.}
@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:
+If you start over again with @samp{10111001} and shift it left by three
+bits, you end up with @samp{11001000}. The following list describes
+@command{gawk}'s built-in functions that implement the bitwise operations.
+Optional parameters are enclosed in square brackets ([ ]):
@cindex @command{gawk}, bitwise operations in
@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{compl()} function (@command{gawk})
-@item compl(@var{val})
+@cindexgawkfunc{and}
+@cindex bitwise AND
+@item @code{and(}@var{v1}@code{,} @var{v2} [@code{,} @dots{}]@code{)}
+Return the bitwise AND of the arguments. There must be at least two.
+
+@cindexgawkfunc{compl}
+@cindex bitwise complement
+@item @code{compl(@var{val})}
Return the bitwise complement of @var{val}.
-@cindex @code{lshift()} function (@command{gawk})
-@item lshift(@var{val}, @var{count})
+@cindexgawkfunc{lshift}
+@cindex left shift
+@item @code{lshift(@var{val}, @var{count})}
Return the value of @var{val}, shifted left by @var{count} bits.
-@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}.
+@cindexgawkfunc{or}
+@cindex bitwise OR
+@item @code{or(}@var{v1}@code{,} @var{v2} [@code{,} @dots{}]@code{)}
+Return the bitwise OR of the arguments. There must be at least two.
-@cindex @code{rshift()} function (@command{gawk})
-@item rshift(@var{val}, @var{count})
+@cindexgawkfunc{rshift}
+@cindex right shift
+@item @code{rshift(@var{val}, @var{count})}
Return the value of @var{val}, shifted right by @var{count} bits.
-@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}.
+@cindexgawkfunc{xor}
+@cindex bitwise XOR
+@item @code{xor(}@var{v1}@code{,} @var{v2} [@code{,} @dots{}]@code{)}
+Return the bitwise XOR of the arguments. There must be at least two.
@end table
-For all of these functions, first the double precision floating-point value is
+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
@@ -16185,6 +19164,7 @@ $ @kbd{gawk -f testbits.awk}
@cindex strings, converting
@cindex numbers, converting
@cindex converting, numbers to strings
+@cindex number as string of bits
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,
@@ -16196,7 +19176,7 @@ 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"}.
+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.
@@ -16205,30 +19185,42 @@ 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 Type Functions
@subsection Getting Type Information
@command{gawk} provides a single function that lets you distinguish
an array from a scalar variable. This is necessary for writing code
-that traverses every element of a true multidimensional array
+that traverses every element of an array of arrays
(@pxref{Arrays of Arrays}).
@table @code
-@cindex @code{isarray()} function (@command{gawk})
+@cindexgawkfunc{isarray}
+@cindex scalar or array
@item isarray(@var{x})
Return a true value if @var{x} is an array. Otherwise return false.
@end table
+@code{isarray()} is meant for use in two circumstances. The first is when
+traversing a multidimensional array: you can test if an element is itself
+an array or not. The second is inside the body of a user-defined function
+(not discussed yet; @pxref{User-defined}), to test if a parameter is an
+array or not.
+
+@quotation NOTE
+Using @code{isarray()} at the global level to test
+variables makes no sense. Because you are the one writing the program, you
+are supposed to know if your variables are arrays or not. And in fact,
+due to the way @command{gawk} works, if you pass the name of a variable
+that has not been previously used to @code{isarray()}, @command{gawk}
+ends up turning it into a scalar.
+@end quotation
+
@node I18N Functions
@subsection String-Translation Functions
@cindex @command{gawk}, string-translation functions
@cindex functions, string-translation
+@cindex string-translation functions
@cindex internationalization
@cindex @command{awk} programs, internationalizing
@@ -16239,9 +19231,10 @@ The descriptions here are purposely brief.
for the full story.
Optional parameters are enclosed in square brackets ([ ]):
-@table @code
-@cindex @code{bindtextdomain()} function (@command{gawk})
-@item bindtextdomain(@var{directory} @r{[}, @var{domain}@r{]})
+@table @asis
+@cindexgawkfunc{bindtextdomain}
+@cindex set directory of message catalogs
+@item @code{bindtextdomain(@var{directory}} [@code{,} @var{domain}]@code{)}
Set 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
@@ -16253,15 +19246,16 @@ If @var{directory} is the null string (@code{""}), then
@code{bindtextdomain()} returns the current binding for the
given @var{domain}.
-@cindex @code{dcgettext()} function (@command{gawk})
-@item dcgettext(@var{string} @r{[}, @var{domain} @r{[}, @var{category}@r{]]})
+@cindexgawkfunc{dcgettext}
+@cindex translate string
+@item @code{dcgettext(@var{string}} [@code{,} @var{domain} [@code{,} @var{category}] ]@code{)}
Return 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{]]})
+@cindexgawkfunc{dcngettext}
+@item @code{dcngettext(@var{string1}, @var{string2}, @var{number}} [@code{,} @var{domain} [@code{,} @var{category}] ]@code{)}
Return 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
@@ -16270,20 +19264,16 @@ 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"}.
@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 user-defined functions
@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.
+them (i.e., to tell @command{awk} what they should do).
@menu
* Definition Syntax:: How to write definitions and what they mean.
@@ -16297,7 +19287,12 @@ them, i.e., to tell @command{awk} what they should do.
@node Definition Syntax
@subsection Function Definition Syntax
-@c STARTOFRANGE fdef
+@quotation
+@i{It's entirely fair to say that the @command{awk} syntax for local
+variable definitions is appallingly awful.}
+@author Brian Kernighan
+@end quotation
+
@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
@@ -16309,12 +19304,12 @@ entire program before starting to execute any of it.
The definition of a function named @var{name} looks like this:
-@example
-function @var{name}(@r{[}@var{parameter-list}@r{]})
-@{
+@display
+@code{function} @var{name}@code{(}[@var{parameter-list}]@code{)}
+@code{@{}
@var{body-of-function}
-@}
-@end example
+@code{@}}
+@end display
@cindex names, functions
@cindex functions, names of
@@ -16323,20 +19318,28 @@ function @var{name}(@r{[}@var{parameter-list}@r{]})
Here, @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.
+Here too, only the 52 upper- and lowercase English letters may
+be used in a function name.
Within a single @command{awk} program, any particular name can only be
used as a variable, array, or function.
@var{parameter-list} is an optional 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.
+the call.
+
A function cannot have two parameters with the same name, nor may it
have a parameter with the same name as the function itself.
+In addition, according to the POSIX standard, function parameters
+cannot have the same name as one of the special predefined variables
+(@pxref{Built-in Variables}). Not all versions of @command{awk} enforce
+this restriction.
-In addition, according to the POSIX standard, function parameters cannot have the same
-name as one of the special built-in variables
-(@pxref{Built-in Variables}. Not all versions of @command{awk}
-enforce this restriction.
+Local variables act like the empty string if referenced where a string
+value is required, and like zero if referenced where a numeric value
+is required. This is the same as regular variables that have never been
+assigned a value. (There is more to understand about local variables;
+@pxref{Dynamic Typing}.)
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
@@ -16363,6 +19366,7 @@ 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
+@cindex shadowing of variable values
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
@@ -16383,7 +19387,7 @@ function. When this happens, we say the function is @dfn{recursive}.
The act of a function calling itself is called @dfn{recursion}.
All the built-in functions return a value to their caller.
-User-defined functions can do also, using the @code{return} statement,
+User-defined functions can do so also, using the @code{return} statement,
which is described in detail in @ref{Return Statement}.
Many of the subsequent examples in this @value{SECTION} use
the @code{return} statement.
@@ -16407,13 +19411,13 @@ func foo() @{ a = sqrt($1) ; print a @}
@end example
@noindent
-Instead it defines a rule that, for each record, concatenates the value
+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.@footnote{This program won't actually run,
-since @code{foo()} is undefined.})
+because @code{foo()} is undefined.})
@cindex portability, functions@comma{} defining
To ensure that your @command{awk} programs are portable, always use the
@@ -16421,6 +19425,7 @@ keyword @code{function} when defining a function.
@node Function Example
@subsection Function Definition Examples
+@cindex function definition example
Here is an example of a user-defined function, called @code{myprint()}, that
takes a number and prints it in a specific format:
@@ -16458,13 +19463,14 @@ this program, using our function to format the results, prints:
21.2
@end example
-This function deletes all the elements in an array:
+This function deletes all the elements in an array (recall that the
+extra whitespace signifies the start of the local variable list):
@example
function delarray(a, i)
@{
for (i in a)
- delete a[i]
+ delete a[i]
@}
@end example
@@ -16475,22 +19481,24 @@ 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 contents of an entire array is a relatively recent@footnote{Late in 2012.}
+addition to the POSIX standard.)
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.
+In this case, the recursion terminates when the input string is
+already empty:
+@c 8/2014: Thanks to Mike Brennan for the improved formulation
@cindex @code{rev()} user-defined function
@example
-function rev(str, start)
+function rev(str)
@{
- if (start == 0)
+ if (str == "")
return ""
- return (substr(str, start, 1) rev(str, start - 1))
+ return (rev(substr(str, 2)) substr(str, 1, 1))
@}
@end example
@@ -16499,11 +19507,11 @@ this way:
@example
$ @kbd{echo "Don't Panic!" |}
-> @kbd{gawk --source '@{ print rev($0, length($0)) @}' -f rev.awk}
+> @kbd{gawk -e '@{ print rev($0) @}' -f rev.awk}
@print{} !cinaP t'noD
@end example
-The C @code{ctime()} function takes a timestamp and returns it in a string,
+The C @code{ctime()} function takes a timestamp and returns it as a string,
formatted in a well-known fashion.
The following example uses the built-in @code{strftime()} function
(@pxref{Time Functions})
@@ -16519,19 +19527,26 @@ to create an @command{awk} version of @code{ctime()}:
function ctime(ts, format)
@{
format = "%a %b %e %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
+
+You might think that @code{ctime()} could use @code{PROCINFO["strftime"]}
+for its format string. That would be a mistake, because @code{ctime()} is
+supposed to return the time formatted in a standard fashion, and user-level
+code could have changed @code{PROCINFO["strftime"]}.
@node Function Caveats
@subsection Calling User-Defined Functions
-@c STARTOFRANGE fudc
-This section describes how to call a user-defined function.
+@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.
@menu
* Calling A Function:: Don't use spaces.
@@ -16540,12 +19555,7 @@ This section describes how to call a user-defined function.
@end menu
@node Calling A Function
-@subsubsection Writing A Function Call
-
-@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.
+@subsubsection Writing a Function Call
A function call consists of the function name followed by the arguments
in parentheses. @command{awk} expressions are what you write in the
@@ -16560,7 +19570,7 @@ foo(x y, "lose", 4 * z)
@quotation CAUTION
Whitespace characters (spaces and TABs) are not allowed
-between the function name and the open-parenthesis of the argument list.
+between the function name and the opening 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
@@ -16570,9 +19580,10 @@ an error.
@node Variable Scope
@subsubsection Controlling Variable Scope
-@cindex local variables
-@cindex variables, local
-There is no way to make a variable local to a @code{@{ @dots{} @}} block in
+@cindex local variables, in a function
+@cindex variables, local to a function
+Unlike many languages,
+there is no way to make a variable local to a @code{@{} @dots{} @code{@}} block in
@command{awk}, but you can make a variable local to a function. It is
good practice to do so whenever a variable is needed only in that
function.
@@ -16599,7 +19610,7 @@ function foo(j)
print "foo's i=" i
@}
-BEGIN @{
+BEGIN @{
i = 10
print "top's i=" i
foo(0)
@@ -16622,13 +19633,13 @@ top's i=3
@end example
If you want @code{i} to be local to both @code{foo()} and @code{bar()} do as
-follows (the extra-space before @code{i} is a coding convention to
+follows (the extra space before @code{i} is a coding convention to
indicate that @code{i} is a local variable, not an argument):
@example
function bar( i)
@{
- for (i = 0; i < 3; i++)
+ for (i = 0; i < 3; i++)
print "bar's i=" i
@}
@@ -16640,10 +19651,10 @@ function foo(j, i)
print "foo's i=" i
@}
-BEGIN @{
+BEGIN @{
i = 10
print "top's i=" i
- foo(0)
+ foo(0)
print "top's i=" i
@}
@end example
@@ -16660,22 +19671,58 @@ foo's i=1
top's i=10
@end example
+Besides scalar values (strings and numbers), you may also have
+local arrays. By using a parameter name as an array, @command{awk}
+treats it as an array, and it is local to the function.
+In addition, recursive calls create new arrays.
+Consider this example:
+
+@example
+function some_func(p1, a)
+@{
+ if (p1++ > 3)
+ return
+
+ a[p1] = p1
+
+ some_func(p1)
+
+ printf("At level %d, index %d %s found in a\n",
+ p1, (p1 - 1), (p1 - 1) in a ? "is" : "is not")
+ printf("At level %d, index %d %s found in a\n",
+ p1, p1, p1 in a ? "is" : "is not")
+ print ""
+@}
+
+BEGIN @{
+ some_func(1)
+@}
+@end example
+
+When run, this program produces the following output:
+
+@example
+At level 4, index 3 is not found in a
+At level 4, index 4 is found in a
+
+At level 3, index 2 is not found in a
+At level 3, index 3 is found in a
+
+At level 2, index 1 is not found in a
+At level 2, index 2 is found in a
+@end example
+
@node Pass By Value/Reference
-@subsubsection Passing Function Arguments By Value Or By Reference
+@subsubsection Passing Function Arguments by Value Or by Reference
In @command{awk}, when you declare a function, there is no way to
declare explicitly whether the arguments are passed @dfn{by value} or
@dfn{by reference}.
-Instead the passing convention is determined at runtime when
+Instead, the passing convention is determined at runtime when
the function is called according to the following rule:
-
-@itemize
-@item
-If the argument is an array variable, then it is passed by reference,
-@item
-Otherwise the argument is passed by value.
-@end itemize
+if the argument is an array variable, then it is passed by reference.
+Otherwise, the argument is passed by value.
@cindex call by value
Passing an argument by value means that when a function is called, it
@@ -16744,7 +19791,7 @@ BEGIN @{
@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}.
+@code{changeit()} stores @code{"two"} in the second element of @code{a}.
@end quotation
@cindex undefined functions
@@ -16776,11 +19823,17 @@ If @option{--lint} is specified
@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})
+error if you use either the @code{next} statement
+or the @code{nextfile} statement
+(@pxref{Next Statement}, and
+@ifdocbook
+@ref{Nextfile Statement})
+@end ifdocbook
+@ifnotdocbook
+@pxref{Nextfile Statement})
+@end ifnotdocbook
inside a user-defined function.
@command{gawk} does not have this limitation.
-@c ENDOFRANGE fudc
@node Return Statement
@subsection The @code{return} Statement
@@ -16792,14 +19845,14 @@ This statement returns control to the calling part of the @command{awk} program.
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
+@display
+@code{return} [@var{expression}]
+@end display
The @var{expression} part is optional.
Due most likely to an oversight, POSIX does not define what the return
value is if you omit the @var{expression}. Technically speaking, this
-make the returned value undefined, and therefore, unpredictable.
+makes the returned value undefined, and therefore, unpredictable.
In practice, though, all versions of @command{awk} simply return the
null string, which acts like zero if used in a numeric context.
@@ -16833,8 +19886,8 @@ function maxelt(vec, i, ret)
@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
+there is nothing to stop you from passing more than one argument
+to @code{maxelt()} but the results would be strange. The extra space before
@code{i} in the function parameter list indicates that @code{i} and
@code{ret} are local variables.
You should follow this convention when defining functions.
@@ -16901,9 +19954,13 @@ BEGIN @{
@}
@end example
+In this example, the first call to @code{foo()} generates
+a fatal error, so @command{awk} will not report the second
+error. If you comment out that call, though, then @command{awk}
+does report the second error.
+
Usually, such things aren't a big issue, but it's worth
being aware of them.
-@c ENDOFRANGE udfunc
@node Indirect Calls
@section Indirect Function Calls
@@ -16914,7 +19971,7 @@ being aware of them.
@cindex pointers to functions
@cindex differences in @command{awk} and @command{gawk}, indirect function calls
-This section describes a @command{gawk}-specific extension.
+This section describes an advanced, @command{gawk}-specific extension.
Often, you may wish to defer the choice of function to call until runtime.
For example, you may have different kinds of records, each of which
@@ -16960,20 +20017,23 @@ To process the data, you might write initially:
@noindent
This style of programming works, but can be awkward. With @dfn{indirect}
function calls, you tell @command{gawk} to use the @emph{value} of a
-variable as the name of the function to call.
+variable as the @emph{name} of the function to call.
+@cindex @code{@@}-notation for indirect function calls
+@cindex indirect function calls, @code{@@}-notation
+@cindex function calls, indirect, @code{@@}-notation for
The syntax is similar to that of a regular function call: an identifier
-immediately followed by a left parenthesis, any arguments, and then
-a closing right parenthesis, with the addition of a leading @samp{@@}
+immediately followed by an opening parenthesis, any arguments, and then
+a closing parenthesis, with the addition of a leading @samp{@@}
character:
@example
the_func = "sum"
-result = @@the_func() # calls the `sum' function
+result = @@the_func() # calls the sum() function
@end example
Here is a full program that processes the previously shown data,
-using indirect function calls.
+using indirect function calls:
@example
@c file eg/prog/indirectcall.awk
@@ -17014,12 +20074,11 @@ function sum(first, last, ret, i)
These two functions expect to work on fields; thus the parameters
@code{first} and @code{last} indicate where in the fields to start and end.
-Otherwise they perform the expected computations and are not unusual.
+Otherwise they perform the expected computations and are not unusual:
@example
@c file eg/prog/indirectcall.awk
# For each record, print the class name and the requested statistics
-
@{
class_name = $1
gsub(/_/, " ", class_name) # Replace _ with spaces
@@ -17060,11 +20119,11 @@ $ @kbd{gawk -f indirectcall.awk class_data1}
@print{} Biology 101:
@print{} sum: <352.8>
@print{} average: <88.2>
-@print{}
+@print{}
@print{} Chemistry 305:
@print{} sum: <356.4>
@print{} average: <89.1>
-@print{}
+@print{}
@print{} English 401:
@print{} sum: <376.1>
@print{} average: <94.025>
@@ -17090,8 +20149,9 @@ We can do something similar using @command{gawk}, like this:
@ignore
@c file eg/lib/quicksort.awk
#
-# Arnold Robbins, arnold@skeeve.com, Public Domain
+# Arnold Robbins, arnold@@skeeve.com, Public Domain
# January 2009
+
@c endfile
@end ignore
@@ -17124,7 +20184,7 @@ function quicksort(data, left, right, less_than, i, last)
# quicksort_swap --- helper function for quicksort, should really be inline
-function quicksort_swap(data, i, j, temp)
+function quicksort_swap(data, i, j, temp)
@{
temp = data[i]
data[i] = data[j]
@@ -17164,7 +20224,7 @@ or equal to), which yields data sorted in descending order.
Next comes a sorting function. It is parameterized with the starting and
ending field numbers and the comparison function. It builds an array with
-the data and calls @code{quicksort} appropriately, and then formats the
+the data and calls @code{quicksort()} appropriately, and then formats the
results as a single string:
@example
@@ -17185,7 +20245,7 @@ function do_sort(first, last, compare, data, i, retval)
retval = data[1]
for (i = 2; i in data; i++)
retval = retval " " data[i]
-
+
return retval
@}
@c endfile
@@ -17212,7 +20272,7 @@ function rsort(first, last)
@c endfile
@end example
-Here is an extended version of the data file:
+Here is an extended version of the @value{DF}:
@example
@c file eg/data/class_data2
@@ -17231,13 +20291,13 @@ $ @kbd{gawk -f quicksort.awk -f indirectcall.awk class_data2}
@print{} average: <88.2>
@print{} sort: <78.5 87.0 92.4 94.9>
@print{} rsort: <94.9 92.4 87.0 78.5>
-@print{}
+@print{}
@print{} Chemistry 305:
@print{} sum: <356.4>
@print{} average: <89.1>
@print{} sort: <75.2 88.2 94.7 98.3>
@print{} rsort: <98.3 94.7 88.2 75.2>
-@print{}
+@print{}
@print{} English 401:
@print{} sum: <376.1>
@print{} average: <94.025>
@@ -17245,2082 +20305,232 @@ $ @kbd{gawk -f quicksort.awk -f indirectcall.awk class_data2}
@print{} rsort: <100.0 95.6 93.4 87.1>
@end example
-Remember that you must supply a leading @samp{@@} in front of an indirect function call.
-
-Unfortunately, indirect function calls cannot be used with the built-in functions. However,
-you can generally write ``wrapper'' functions which call the built-in ones, and those can
-be called indirectly. (Other than, perhaps, the mathematical functions, there is not a lot
-of reason to try to call the built-in functions indirectly.)
-
-@command{gawk} does its best to make indirect function calls efficient.
-For example, in the following case:
-
-@example
-for (i = 1; i <= n; i++)
- @@the_func()
-@end example
-
-@noindent
-@code{gawk} will look up the actual function to call only once.
-
-@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
-For many years, 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 forced to write in C or 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}.
-Therefore, 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.
-
-@cindex @code{.pot} files
-@cindex files, @code{.pot}
-@cindex portable object template files
-@cindex files, portable object template
-@item
-Messages from the application are extracted from the source code and
-collected into a portable object template file (@file{guide.pot}),
-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.pot}
-is copied to a portable object file (@code{.po})
-and translations are created and shipped with the application.
-For example, there might be a @file{fr.po} for a French translation.
-
-@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("%s", 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(@dots{})} 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("%s", _("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:
-1,234.56 versus 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 the 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{]]})
-Return 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.
-
-@quotation 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.
-@end quotation
-
-@cindex @code{dcngettext()} function (@command{gawk})
-@item dcngettext(@var{string1}, @var{string2}, @var{number} @r{[}, @var{domain} @r{[}, @var{category}@r{]]})
-Return 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 about argument order 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{]})
-Change 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).
-Return 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:
+Another example where indirect functions calls are useful can be found in
+processing arrays. @DBREF{Walking Arrays} presented a simple function
+for ``walking'' an array of arrays. That function simply printed the
+name and value of each scalar array element. However, it is easy to
+generalize that function, by passing in the name of a function to call
+when walking an array. The modified function looks like this:
@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-pot} 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-pot} 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-pot} 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-pot} command-line option to create
-the initial @file{.pot} file:
-
-@example
-$ @kbd{gawk --gen-pot -f guide.awk > guide.pot}
-@end example
-
-@cindex @code{xgettext} utility
-When run with @option{--gen-pot}, @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{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, @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 specifiers 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
-$ @kbd{gawk 'BEGIN @{}
-> @kbd{string = "Dont Panic"}
-> @kbd{printf _"%2$d characters live in \"%1$s\"\n",}
-> @kbd{string, length(string)}
-> @kbd{@}'}
-@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
-$ @kbd{gawk 'BEGIN @{}
-> @kbd{printf("%*.*s\n", 10, 20, "hello")}
-> @kbd{printf("%3$*2$.*1$s\n", 20, 10, "hello")}
-> @kbd{@}'}
-@print{} hello
-@print{} hello
-@end example
-
-@quotation NOTE
-When using @samp{*} with a positional specifier, the @samp{*}
-comes first, then the integer position, and then the @samp{$}.
-This is somewhat counterintuitive.
-@end quotation
-
-@cindex @code{printf} statement, positional specifiers, mixing with regular formats
-@cindex positional specifiers, @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:
-
-@example
-$ @kbd{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 example
-
-@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)
+@c file eg/lib/processarray.awk
+function process_array(arr, name, process, do_arrays, i, new_name)
@{
- 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?"
+ for (i in arr) @{
+ new_name = (name "[" i "]")
+ if (isarray(arr[i])) @{
+ if (do_arrays)
+ @@process(new_name, arr[i])
+ process_array(arr[i], new_name, process, do_arrays)
+ @} else
+ @@process(new_name, arr[i])
+ @}
@}
@c endfile
@end example
-@noindent
-Run @samp{gawk --gen-pot} to create the @file{.pot} file:
-
-@example
-$ @kbd{gawk --gen-pot -f guide.awk > guide.pot}
-@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 template 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.pot} 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.pot 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
-$ @kbd{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
-$ @kbd{msgfmt guide-mellow.po}
-$ @kbd{mv messages en_US/LC_MESSAGES/guide.mo}
-@end example
-
-Finally, we run the program to test it:
-
-@example
-$ @kbd{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
-$ @kbd{gawk --posix -f guide.awk -f libintl.awk}
-@print{} Don't Panic
-@print{} The Answer Is 42
-@print{} Pardon me, Zaphod who?
-@end example
-
-@node Gawk I18N
-@section @command{gawk} Can Speak Your Language
-
-@command{gawk} itself has been internationalized
-using the GNU @code{gettext} package.
-(GNU @code{gettext} is described in
-complete detail in
-@ifinfo
-@inforef{Top, , GNU @code{gettext} utilities, gettext, GNU gettext tools}.)
-@end ifinfo
-@ifnotinfo
-@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.18.1.tar.gz, @value{PVERSION} 0.18.1}.
-
-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.
-Then, @command{gawk}'s special features for sorting arrays are presented.
-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. 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.
-* Array Sorting:: Facilities for controlling array traversal and
- sorting arrays.
-* Two-way I/O:: Two-way communications with another process.
-* TCP/IP Networking:: Using @command{gawk} for network programming.
-* 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
-$ @kbd{echo 0123 123 0x123 |}
-> @kbd{gawk --non-decimal-data '@{ printf "%d, %d, %d\n",}
-> @kbd{$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
-$ @kbd{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
-$ @kbd{echo 0123 123 0x123 | gawk --non-decimal-data '}
-> @kbd{@{ print $1, $2, $3}
-> @kbd{print $1 + 0, $2 + 0, $3 + 0 @}'}
-@print{} 0123 123 0x123
-@print{} 83 123 291
-@end example
-
-Because it is common to have decimal data with leading zeros, and because
-using this facility could lead to surprising results, the default is to leave it
-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
-@quotation 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.
-@end quotation
-
-@node Array Sorting
-@section Controlling Array Traversal and Array Sorting
-
-@command{gawk} lets you control the order in which @samp{for (i in array)} loops
-will traverse an array.
-
-In addition, two built-in functions, @code{asort()} and @code{asorti()},
-let you sort arrays based on the array values and indices, respectively.
-These two functions also provide control over the sorting criteria used
-to order the elements during sorting.
-
-@menu
-* Controlling Array Traversal:: How to use PROCINFO["sorted_in"].
-* Array Sorting Functions:: How to use @code{asort()} and @code{asorti()}.
-@end menu
-
-@node Controlling Array Traversal
-@subsection Controlling Array Traversal
-
-By default, the order in which a @samp{for (i in array)} loop
-scans an array is not defined; it is generally based upon
-the internal implementation of arrays inside @command{awk}.
-
-Often, though, it is desirable to be able to loop over the elements
-in a particular order that you, the programmer, choose. @command{gawk}
-lets you do this; this @value{SUBSECTION} describes how.
-
-@menu
-* Controlling Scanning With A Function:: Using a function to control scanning.
-* Controlling Scanning:: Controlling the order in which arrays
- are scanned.
-@end menu
-
-@node Controlling Scanning With A Function
-@subsubsection Array Scanning Using A User-defined Function
-
-The value of @code{PROCINFO["sorted_in"]} can be a function name.
-This lets you traverse an array based on any custom criterion.
-The array elements are ordered according to the return value of this
-function. The comparison function should be defined with at least
-four arguments:
-
-@example
-function comp_func(i1, v1, i2, v2)
-@{
- @var{compare elements 1 and 2 in some fashion}
- @var{return < 0; 0; or > 0}
-@}
-@end example
-
-Here, @var{i1} and @var{i2} are the indices, and @var{v1} and @var{v2}
-are the corresponding values of the two elements being compared.
-Either @var{v1} or @var{v2}, or both, can be arrays if the array being
-traversed contains subarrays as values. The three possible return values
-are interpreted this way:
+The arguments are as follows:
@table @code
-@item comp_func(i1, v1, i2, v2) < 0
-Index @var{i1} comes before index @var{i2} during loop traversal.
+@item arr
+The array.
-@item comp_func(i1, v1, i2, v2) == 0
-Indices @var{i1} and @var{i2}
-come together but the relative order with respect to each other is undefined.
+@item name
+The name of the array (a string).
-@item comp_func(i1, v1, i2, v2) > 0
-Index @var{i1} comes after index @var{i2} during loop traversal.
-@end table
+@item process
+The name of the function to call.
-Our first comparison function can be used to scan an array in
-numerical order of the indices:
-
-@example
-function cmp_num_idx(i1, v1, i2, v2)
-@{
- # numerical index comparison, ascending order
- return (i1 - i2)
-@}
-@end example
-
-Our second function traverses an array based on the string order of
-the element values rather than by indices:
-
-@example
-function cmp_str_val(i1, v1, i2, v2)
-@{
- # string value comparison, ascending order
- v1 = v1 ""
- v2 = v2 ""
- if (v1 < v2)
- return -1
- return (v1 != v2)
-@}
-@end example
+@item do_arrays
+If this is true, the function can handle elements that are subarrays.
+@end table
-The third
-comparison function makes all numbers, and numeric strings without
-any leading or trailing spaces, come out first during loop traversal:
+If subarrays are to be processed, that is done before walking them further.
-@example
-function cmp_num_str_val(i1, v1, i2, v2, n1, n2)
-@{
- # numbers before string value comparison, ascending order
- n1 = v1 + 0
- n2 = v2 + 0
- if (n1 == v1)
- return (n2 == v2) ? (n1 - n2) : -1
- else if (n2 == v2)
- return 1
- return (v1 < v2) ? -1 : (v1 != v2)
-@}
-@end example
-
-Here is a main program to demonstrate how @command{gawk}
-behaves using each of the previous functions:
+When run with the following scaffolding, the function produces the same
+results as does the earlier @code{walk_array()} function:
@example
BEGIN @{
- data["one"] = 10
- data["two"] = 20
- data[10] = "one"
- data[100] = 100
- data[20] = "two"
-
- f[1] = "cmp_num_idx"
- f[2] = "cmp_str_val"
- f[3] = "cmp_num_str_val"
- for (i = 1; i <= 3; i++) @{
- printf("Sort function: %s\n", f[i])
- PROCINFO["sorted_in"] = f[i]
- for (j in data)
- printf("\tdata[%s] = %s\n", j, data[j])
- print ""
- @}
-@}
-@end example
-
-Here are the results when the program is run:
-@page
-
-@example
-$ @kbd{gawk -f compdemo.awk}
-@print{} Sort function: cmp_num_idx @ii{Sort by numeric index}
-@print{} data[two] = 20
-@print{} data[one] = 10 @ii{Both strings are numerically zero}
-@print{} data[10] = one
-@print{} data[20] = two
-@print{} data[100] = 100
-@print{}
-@print{} Sort function: cmp_str_val @ii{Sort by element values as strings}
-@print{} data[one] = 10
-@print{} data[100] = 100 @ii{String 100 is less than string 20}
-@print{} data[two] = 20
-@print{} data[10] = one
-@print{} data[20] = two
-@print{}
-@print{} Sort function: cmp_num_str_val @ii{Sort all numbers before all strings}
-@print{} data[one] = 10
-@print{} data[two] = 20
-@print{} data[100] = 100
-@print{} data[10] = one
-@print{} data[20] = two
-@end example
-
-Consider sorting the entries of a GNU/Linux system password file
-according to login names. The following program sorts records
-by a specific field position and can be used for this purpose:
-
-@example
-# sort.awk --- simple program to sort by field position
-# field position is specified by the global variable POS
-
-function cmp_field(i1, v1, i2, v2)
-@{
- # comparison by value, as string, and ascending order
- return v1[POS] < v2[POS] ? -1 : (v1[POS] != v2[POS])
-@}
-
-@{
- for (i = 1; i <= NF; i++)
- a[NR][i] = $i
-@}
-
-END @{
- PROCINFO["sorted_in"] = "cmp_field"
- if (POS < 1 || POS > NF)
- POS = 1
- for (i in a) @{
- for (j = 1; j <= NF; j++)
- printf("%s%c", a[i][j], j < NF ? ":" : "")
- print ""
- @}
-@}
-@end example
-
-The first field in each entry of the password file is the user's login name,
-and the fields are seperated by colons.
-Each record defines a subarray (@pxref{Arrays of Arrays}),
-with each field as an element in the subarray.
-Running the program produces the
-following output:
-
-@example
-$ @kbd{gawk -vPOS=1 -F: -f sort.awk /etc/passwd}
-@print{} adm:x:3:4:adm:/var/adm:/sbin/nologin
-@print{} apache:x:48:48:Apache:/var/www:/sbin/nologin
-@print{} avahi:x:70:70:Avahi daemon:/:/sbin/nologin
-@dots{}
-@end example
-
-The comparison should normally always return the same value when given a
-specific pair of array elements as its arguments. If inconsistent
-results are returned then the order is undefined. This behavior can be
-exploited to introduce random order into otherwise seemingly
-ordered data:
-
-@example
-function cmp_randomize(i1, v1, i2, v2)
-@{
- # random order
- return (2 - 4 * rand())
-@}
-@end example
-
-As mentioned above, the order of the indices is arbitrary if two
-elements compare equal. This is usually not a problem, but letting
-the tied elements come out in arbitrary order can be an issue, especially
-when comparing item values. The partial ordering of the equal elements
-may change during the next loop traversal, if other elements are added or
-removed from the array. One way to resolve ties when comparing elements
-with otherwise equal values is to include the indices in the comparison
-rules. Note that doing this may make the loop traversal less efficient,
-so consider it only if necessary. The following comparison functions
-force a deterministic order, and are based on the fact that the
-indices of two elements are never equal:
+ a[1] = 1
+ a[2][1] = 21
+ a[2][2] = 22
+ a[3] = 3
+ a[4][1][1] = 411
+ a[4][2] = 42
-@example
-function cmp_numeric(i1, v1, i2, v2)
-@{
- # numerical value (and index) comparison, descending order
- return (v1 != v2) ? (v2 - v1) : (i2 - i1)
+ process_array(a, "a", "do_print", 0)
@}
-function cmp_string(i1, v1, i2, v2)
+function do_print(name, element)
@{
- # string value (and index) comparison, descending order
- v1 = v1 i1
- v2 = v2 i2
- return (v1 > v2) ? -1 : (v1 != v2)
+ printf "%s = %s\n", name, element
@}
@end example
-@c Avoid using the term ``stable'' when describing the unpredictable behavior
-@c if two items compare equal. Usually, the goal of a "stable algorithm"
-@c is to maintain the original order of the items, which is a meaningless
-@c concept for a list constructed from a hash.
-
-A custom comparison function can often simplify ordered loop
-traversal, and the sky is really the limit when it comes to
-designing such a function.
-
-When string comparisons are made during a sort, either for element
-values where one or both aren't numbers, or for element indices
-handled as strings, the value of @code{IGNORECASE}
-(@pxref{Built-in Variables}) controls whether
-the comparisons treat corresponding uppercase and lowercase letters as
-equivalent or distinct.
-
-Another point to keep in mind is that in the case of subarrays
-the element values can themselves be arrays; a production comparison
-function should use the @code{isarray()} function
-(@pxref{Type Functions}),
-to check for this, and choose a defined sorting order for subarrays.
-
-All sorting based on @code{PROCINFO["sorted_in"]}
-is disabled in POSIX mode,
-since the @code{PROCINFO} array is not special in that case.
-
-As a side note, sorting the array indices before traversing
-the array has been reported to add 15% to 20% overhead to the
-execution time of @command{awk} programs. For this reason,
-sorted array traversal is not the default.
-
-@c The @command{gawk}
-@c maintainers believe that only the people who wish to use a
-@c feature should have to pay for it.
-
-@node Controlling Scanning
-@subsubsection Controlling Array Scanning Order
-
-As described in
-@iftex
-the previous subsubsection,
-@end iftex
-@ifnottex
-@ref{Controlling Scanning With A Function},
-@end ifnottex
-you can provide the name of a function as the value of
-@code{PROCINFO["sorted_in"]} to specify custom sorting criteria.
-
-Often, though, you may wish to do something simple, such as
-``sort based on comparing the indices in ascending order,''
-or ``sort based on comparing the values in descending order.''
-Having to write a simple comparison function for this purpose
-for use in all of your programs becomes tedious.
-For the common simple cases, @command{gawk} provides
-the option of supplying special names that do the requested
-sorting for you.
-You can think of them as ``predefined'' sorting functions,
-if you like, although the names purposely include characters
-that are not valid in real @command{awk} function names.
-
-The following special values are available:
-
-@table @code
-@item "@@ind_str_asc"
-Order by indices compared as strings; this is the most basic sort.
-(Internally, array indices are always strings, so with @samp{a[2*5] = 1}
-the index is @code{"10"} rather than numeric 10.)
-
-@item "@@ind_num_asc"
-Order by indices but force them to be treated as numbers in the process.
-Any index with a non-numeric value will end up positioned as if it were zero.
-
-@item "@@val_type_asc"
-Order by element values rather than indices.
-Ordering is by the type assigned to the element
-(@pxref{Typing and Comparison}).
-All numeric values come before all string values,
-which in turn come before all subarrays.
-
-@item "@@val_str_asc"
-Order by element values rather than by indices. Scalar values are
-compared as strings. Subarrays, if present, come out last.
-
-@item "@@val_num_asc"
-Order by element values rather than by indices. Scalar values are
-compared as numbers. Subarrays, if present, come out last.
-When numeric values are equal, the string values are used to provide
-an ordering: this guarantees consistent results across different
-versions of the C @code{qsort()} function.@footnote{When two elements
-compare as equal, the C @code{qsort()} function does not guarantee
-that they will maintain their original relative order after sorting.
-Using the string value to provide a unique ordering when the numeric
-values are equal ensures that @command{gawk} behaves consistently
-across different environments.}
-
-@item "@@ind_str_desc"
-Reverse order from the most basic sort.
-
-@item "@@ind_num_desc"
-Numeric indices ordered from high to low.
-
-@item "@@val_type_desc"
-Element values, based on type, in descending order.
-
-@item "@@val_str_desc"
-Element values, treated as strings, ordered from high to low.
-Subarrays, if present, come out first.
-
-@item "@@val_num_desc"
-Element values, treated as numbers, ordered from high to low.
-Subarrays, if present, come out first.
-
-@item "@@unsorted"
-Array elements are processed in arbitrary order, which is the normal
-@command{awk} behavior. You can also get the normal behavior by just
-deleting the @code{"sorted_in"} element from the @code{PROCINFO} array,
-if it previously had a value assigned to it.
-@end table
-
-The array traversal order is determined before the @code{for} loop
-starts to run. Changing @code{PROCINFO["sorted_in"]} in the loop body
-will not affect the loop.
-
-For example:
-
-@example
-$ @kbd{gawk 'BEGIN @{}
-> @kbd{ a[4] = 4}
-> @kbd{ a[3] = 3}
-> @kbd{ for (i in a)}
-> @kbd{ print i, a[i]}
-> @kbd{@}'}
-@print{} 4 4
-@print{} 3 3
-$ @kbd{gawk 'BEGIN @{}
-> @kbd{ PROCINFO["sorted_in"] = "@@ind_str_asc"}
-> @kbd{ a[4] = 4}
-> @kbd{ a[3] = 3}
-> @kbd{ for (i in a)}
-> @kbd{ print i, a[i]}
-> @kbd{@}'}
-@print{} 3 3
-@print{} 4 4
-@end example
-
-When sorting an array by element values, if a value happens to be
-a subarray then it is considered to be greater than any string or
-numeric value, regardless of what the subarray itself contains,
-and all subarrays are treated as being equal to each other. Their
-order relative to each other is determined by their index strings.
-
-@node Array Sorting Functions
-@subsection 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
-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
+Remember that you must supply a leading @samp{@@} in front of an indirect function call.
-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 array elements are compared as strings.
+Starting with @value{PVERSION} 4.1.2 of @command{gawk}, indirect function
+calls may also be used with built-in functions and with extension functions
+(@pxref{Dynamic Extensions}). The only thing you cannot do is pass a regular
+expression constant to a built-in function through an indirect function
+call.@footnote{This may change in a future version; recheck the documentation that
+comes with your version of @command{gawk} to see if it has.}
-@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:
+@command{gawk} does its best to make indirect function calls efficient.
+For example, in the following case:
@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.
-
-@code{asort()} accepts a third string argument
-to control comparison of array elements.
-As with @code{PROCINFO["sorted_in"]}, this argument may be the
-name of a user-defined function, or one of the predefined names
-that @command{gawk} provides
-(@pxref{Controlling Scanning With A Function}).
-
-@quotation NOTE
-In all cases, the sorted element values consist of the original
-array's element values. The ability to control comparison merely
-affects the way in which they are sorted.
-@end quotation
-
-Often, what's needed is to sort on the values of the @emph{indices}
-instead of the values of the elements.
-To do that, 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++) @{
- @ii{Work with sorted indices directly:}
- @var{do something with} dest[i]
- @dots{}
- @ii{Access original array via sorted indices:}
- @var{do something with} source[dest[i]]
- @}
-@}
-@end example
-
-Similar to @code{asort()},
-in all cases, the sorted element values consist of the original
-array's indices. The ability to control comparison merely
-affects the way in which they are sorted.
-
-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.@footnote{You
-may also use one of the predefined sorting names that sorts in
-decreasing order.}
-
-@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.
-
-@c Document It And Call It A Feature. Sigh.
-@cindex @command{gawk}, @code{IGNORECASE} variable in
-@cindex @code{IGNORECASE} variable
-@cindex arrays, sorting, @code{IGNORECASE} variable and
-@cindex @code{IGNORECASE} variable, array sorting and
-Because @code{IGNORECASE} affects string comparisons, the value
-of @code{IGNORECASE} also affects sorting for both @code{asort()} and @code{asorti()}.
-Note also that the locale's sorting order does @emph{not}
-come into play; comparisons are based on character values only.@footnote{This
-is true because locale-based comparison occurs only when in POSIX
-compatibility mode, and since @code{asort()} and @code{asorti()} are
-@command{gawk} extensions, they are not available in that case.}
-Caveat Emptor.
-
-@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{|&} operator (I/O)
-@cindex @command{csh} utility, @code{|&} operator, comparison with
-However, with @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 @samp{|&} operator
-(borrowed from the Korn shell, @command{ksh}):@footnote{This is very
-different from the same operator in the C shell.}
-
-@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 coprocess.
-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 coprocess 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}.
-
-@cindex @command{gawk}, @code{PROCINFO} array in
-@cindex @code{PROCINFO} array
-You may also 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, save in convenience variable
-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/@dots{}} special files (@command{gawk})
-@cindex files, @code{/inet/@dots{}} (@command{gawk})
-@cindex @code{/inet4/@dots{}} special files (@command{gawk})
-@cindex files, @code{/inet4/@dots{}} (@command{gawk})
-@cindex @code{/inet6/@dots{}} special files (@command{gawk})
-@cindex files, @code{/inet6/@dots{}} (@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 network 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 one of @samp{/inet/},
-@samp{/inet4/} or @samp{/inet6}.
-
-The full syntax of the special @value{FN} is
-@file{/@var{net-type}/@var{protocol}/@var{local-port}/@var{remote-host}/@var{remote-port}}.
-The components are:
-
-@table @var
-@item net-type
-Specifies the kind of Internet connection to make.
-Use @samp{/inet4/} to force IPv4, and
-@samp{/inet6/} to force IPv6.
-Plain @samp{/inet/} (which used to be the only option) uses
-the system default, most likely IPv4.
-
-@item protocol
-The protocol to use over IP. This must be either @samp{tcp}, or
-@samp{udp}, for a TCP or UDP IP connection,
-respectively. The use of TCP is recommended for most applications.
-
-@item local-port
-@cindex @code{getaddrinfo()} 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{getaddrinfo()} 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
-
-@cindex @command{gawk}, @code{ERRNO} variable in
-@cindex @code{ERRNO} variable
-@quotation NOTE
-Failure in opening a two-way socket will result in a non-fatal error
-being returned to the calling code. The value of @code{ERRNO} indicates
-the error (@pxref{Auto-set}).
-@end quotation
-
-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
-See
-@inforef{Top, , General Introduction, gawkinet, TCP/IP Internetworking with @command{gawk}},
-@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.
-
-@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
-
-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
+ @@the_func()
@end example
@noindent
-In the above example, @command{pgawk} places the profile in
-@file{myprog.prof} instead of in @file{awkprof.out}.
-
-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" @}
+@code{gawk} looks up the actual function to call only once.
-END @{ print "First END rule" @}
-
-/foo/ @{
- print "matched /foo/, gosh"
- for (i = 1; i <= 3; i++)
- sing()
-@}
+@node Functions Summary
+@section Summary
-@{
- 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 features of profiling output.
-They are as follows:
-
-@itemize @bullet
+@itemize @value{BULLET}
@item
-The program is printed in the order @code{BEGIN} rule,
-@code{BEGINFILE} rule,
-pattern/action rules,
-@code{ENDFILE} rule, @code{END} rule and functions, listed
-alphabetically.
-Multiple @code{BEGIN} and @code{END} rules are merged together,
-as are multiple @code{BEGINFILE} and @code{ENDFILE} rules.
+@command{awk} provides built-in functions and lets you define your own
+functions.
-@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.
+POSIX @command{awk} provides three kinds of built-in functions: numeric,
+string, and I/O. @command{gawk} provides functions that sort arrays, work
+with values representing time, do bit manipulation, determine variable
+type (array versus scalar), and internationalize and localize programs.
+@command{gawk} also provides several extensions to some of standard
+functions, typically in the form of additional arguments.
@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.
+Functions accept zero or more arguments and return a value. The
+expressions that provide the argument values are completely evaluated
+before the function is called. Order of evaluation is not defined.
+The return value can be ignored.
-@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.)
+The handling of backslash in @code{sub()} and @code{gsub()} is not simple.
+It is more straightforward in @command{gawk}'s @code{gensub()} function,
+but that function still requires care in its use.
-@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.
+User-defined functions provide important capabilities but come with
+some syntactic inelegancies. In a function call, there cannot be any
+space between the function name and the opening left parenthesis of the
+argument list. Also, there is no provision for local variables, so the
+convention is to add extra parameters, and to separate them visually
+from the real parameters by extra whitespace.
-@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.
+User-defined functions may call other user-defined (and built-in)
+functions and may call themselves recursively. Function parameters
+``hide'' any global variables of the same names.
+You cannot use the name of a reserved variable (such as @code{ARGC})
+as the name of a parameter in user-defined functions.
-@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)}.
+Scalar values are passed to user-defined functions by value. Array
+parameters are passed by reference; any changes made by the function to
+array parameters are thus visible after the function has returned.
-@ignore
@item
-All string concatenations are parenthesized too.
-(This could be made a bit smarter.)
-@end ignore
+Use the @code{return} statement to return from a user-defined function.
+An optional expression becomes the function's return value. Only scalar
+values may be returned by a function.
@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.
+If a variable that has never been used is passed to a user-defined
+function, how that function treats the variable can set its nature:
+either scalar or array.
@item
-@command{pgawk} supplies leading comments in
-front of the @code{BEGIN} and @code{END} rules,
-the pattern/action rules, and the functions.
+@command{gawk} provides indirect function calls using a special syntax.
+By setting a variable to the name of a function, you can
+determine at runtime what function will be called at that point in the
+program. This is equivalent to function pointers in C and C++.
@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},
-@code{END}, @code{BEGINFILE}, and @code{ENDFILE} 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
-$ @kbd{pgawk -f myprog &}
-[1] 13992
-@end example
-
-@cindex @command{kill} command@comma{} dynamic profiling
-@cindex @code{USR1} signal
-@cindex @code{SIGUSR1} 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
-$ @kbd{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.
+@ifnotinfo
+@part @value{PART2}Problem Solving with @command{awk}
+@end ifnotinfo
-@cindex @code{HUP} signal
-@cindex @code{SIGHUP} 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.
+@ifdocbook
+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:
-@cindex @code{INT} signal (MS-Windows)
-@cindex @code{SIGINT} signal (MS-Windows)
-@cindex signals, @code{INT}/@code{SIGINT} (MS-Windows)
-@cindex @code{QUIT} signal (MS-Windows)
-@cindex @code{SIGQUIT} signal (MS-Windows)
-@cindex signals, @code{QUIT}/@code{SIGQUIT} (MS-Windows)
-When @command{pgawk} runs on MS-Windows systems, 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.
+@itemize @value{BULLET}
+@item
+@ref{Library Functions}
-Finally, regular @command{gawk} also accepts the @option{--profile} option.
-When called this way, @command{gawk} ``pretty prints'' the program into
-@file{awkprof.out}, without any execution counts.
-@c ENDOFRANGE advgaw
-@c ENDOFRANGE gawadv
-@c ENDOFRANGE pgawk
-@c ENDOFRANGE awkp
-@c ENDOFRANGE proawk
+@item
+@ref{Sample Programs}
+@end itemize
+@end ifdocbook
@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
+@DBREF{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.
+@cindex Kernighan, Brian
+@cindex Plauger, P.J.@:
+In their seminal 1976 book, @cite{Software Tools},@footnote{Sadly, over 35
+years later, many of the lessons taught by this book have yet to be
+learned by a vast number of practicing programmers.} Brian Kernighan
+and P.J.@: Plauger wrote:
+
+@quotation
+Good Programming is not learned from generalities, but by seeing how
+significant programs can be made clean, easy to read, easy to maintain and
+modify, human-engineered, efficient and reliable, by the application of
+common sense and good programming practices. Careful study and imitation
+of good programs leads to better writing.
+@end quotation
+
+In fact, they felt this idea was so important that they placed this
+statement on the cover of their book. Because we believe strongly
+that their statement is correct, this @value{CHAPTER} and @ref{Sample
+Programs}, provide a good-sized body of code for you to read and, we hope,
+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},
+@DBREF{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.)
+@ifclear FOR_PRINT
If you have written one or more useful, general-purpose @command{awk} functions
and would like to contribute them to the @command{awk} user community, see
@ref{How To Contribute}, for more information.
+@end ifclear
@cindex portability, example programs
The programs in this @value{CHAPTER} and in
@ref{Sample Programs},
-freely use features that are @command{gawk}-specific.
+freely use @command{gawk}-specific features.
Rewriting these programs for different implementations of @command{awk}
-is pretty straightforward.
+is pretty straightforward:
-@itemize @bullet
+@itemize @value{BULLET}
@item
Diagnostic error messages are sent to @file{/dev/stderr}.
Use @samp{| "cat 1>&2"} instead of @samp{> "/dev/stderr"} if your system
@@ -19364,6 +20574,8 @@ comparisons use only lowercase letters.
* Passwd Functions:: Functions for getting user information.
* Group Functions:: Functions for getting group information.
* Walking Arrays:: A function to walk arrays of arrays.
+* Library Functions Summary:: Summary of library functions.
+* Library Exercises:: Exercises.
@end menu
@node Library Names
@@ -19386,7 +20598,7 @@ 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
+Such variables are called @dfn{private}, as 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
@@ -19406,12 +20618,12 @@ with the user's program.
@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
+@code{_pw_byname()} in the user database routines
(@pxref{Passwd Functions}).
-This convention is recommended, since it even further decreases the
+This convention is recommended, as 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.@footnote{While all the library routines could have
+function names.@footnote{Although all the library routines could have
been rewritten to use this convention, this was not done, in order to
show how our own @command{awk} programming style has evolved and to
provide some basis for this discussion.}
@@ -19423,9 +20635,9 @@ 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}.
+not one of @command{awk}'s predefined variables, such as @code{FS}.
-@cindex @code{--dump-variables} option
+@cindex @option{--dump-variables} option, using for library functions
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
@@ -19437,8 +20649,9 @@ are very difficult to track down:
function lib_func(x, y, l1, l2)
@{
@dots{}
- @var{use variable} some_var # some_var should be local
- @dots{} # but is not by oversight
+ # some_var should be local but by oversight is not
+ @var{use variable} some_var
+ @dots{}
@}
@end example
@@ -19450,7 +20663,7 @@ 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},
+@DBREF{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}},
@@ -19477,11 +20690,13 @@ programming use.
* 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.
+* Getlocaltime Function:: A function to get formatted times.
+* Readfile Function:: A function to read an entire file at once.
+* Shell Quoting:: A function to quote strings for the shell.
@end menu
@node Strtonum Function
-@subsection Converting Strings To Numbers
+@subsection Converting Strings to Numbers
The @code{strtonum()} function (@pxref{String Functions})
is a @command{gawk} extension. The following function
@@ -19497,11 +20712,12 @@ provides an implementation for other versions of @command{awk}:
#
# Arnold Robbins, arnold@@skeeve.com, Public Domain
# February, 2004
+# Revised June, 2014
@c endfile
@end ignore
@c file eg/lib/strtonum.awk
-function mystrtonum(str, ret, chars, n, i, k, c)
+function mystrtonum(str, ret, n, i, k, c)
@{
if (str ~ /^0[0-7]*$/) @{
# octal
@@ -19509,12 +20725,13 @@ function mystrtonum(str, ret, chars, n, i, k, c)
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
+ # index() returns 0 if c not in string,
+ # includes c == "0"
+ k = index("1234567", c)
ret = ret * 8 + k
@}
- @} else if (str ~ /^0[xX][[:xdigit:]]+/) @{
+ @} else if (str ~ /^0[xX][[:xdigit:]]+$/) @{
# hexadecimal
str = substr(str, 3) # lop off leading 0x
n = length(str)
@@ -19522,10 +20739,9 @@ function mystrtonum(str, ret, chars, n, i, k, c)
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
+ # index() returns 0 if c not in string,
+ # includes c == "0"
+ k = index("123456789abcdef", c)
ret = ret * 16 + k
@}
@@ -19547,8 +20763,8 @@ function mystrtonum(str, ret, chars, n, i, k, c)
# a[5] = "123.45"
# a[6] = "1.e3"
# a[7] = "1.32"
-# a[7] = "1.32E2"
-#
+# a[8] = "1.32E2"
+#
# for (i = 1; i in a; i++)
# print a[i], strtonum(a[i]), mystrtonum(a[i])
# @}
@@ -19558,9 +20774,12 @@ function mystrtonum(str, ret, chars, n, i, k, c)
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.
+string. It sets @code{k} to the index in @code{"1234567"} of the current
+octal digit.
+The return value will either be the same number as the digit, or zero
+if the character is not there, which will be true for a @samp{0}.
+This is safe, because the regexp test in the @code{if} ensures that
+only octal values are converted.
Similar logic applies to the code that checks for and converts a
hexadecimal value, which starts with @samp{0x} or @samp{0X}.
@@ -19579,13 +20798,9 @@ be tested with @command{gawk} and the results compared to the built-in
@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
@@ -19593,7 +20808,7 @@ 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
+and corresponding @code{assert()} macro that a 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
@@ -19701,10 +20916,6 @@ most likely causing the program to hang as it waits for input.
There is a simple workaround to this:
make sure that such a @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
@@ -19719,9 +20930,9 @@ with an @code{exit} statement.
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,
+subroutine. On many machines, @code{sprintf()} rounding is @dfn{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., @code{"%.0f"}),
you should check what your system does. The following function does
@@ -19770,7 +20981,7 @@ function round(x, ival, aval, fraction)
@c don't include test harness in the file that gets installed
# test harness
-@{ print $0, round($0) @}
+# @{ print $0, round($0) @}
@end example
@node Cliff Random Function
@@ -19837,6 +21048,7 @@ reason to build them into the @command{awk} interpreter:
@cindex @code{ord()} user-defined function
@cindex @code{chr()} user-defined function
+@cindex @code{_ord_init()} user-defined function
@example
@c file eg/lib/ord.awk
# ord.awk --- do ord and chr
@@ -19883,8 +21095,9 @@ function _ord_init( low, high, i, t)
@cindex character sets (machine character encodings)
@cindex ASCII
@cindex EBCDIC
+@cindex Unicode
@cindex mark parity
-Some explanation of the numbers used by @code{chr} is worthwhile.
+Some explanation of the numbers used by @code{_ord_init()} is worthwhile.
The most prominent character set in use today is ASCII.@footnote{This
is changing; many systems use Unicode, a very large character set
that includes ASCII as a subset. On systems with full Unicode support,
@@ -19895,7 +21108,7 @@ Although an
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 loop from 0 to 255.}
+you can simplify @code{_ord_init()} to loop from 0 to 255.}
In the now distant past,
at least one minicomputer manufacturer
@c Pr1me, blech
@@ -19904,7 +21117,7 @@ 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,
+There are other character sets in use on some older systems, but
they are not really worth worrying about:
@example
@@ -19924,8 +21137,7 @@ function chr(c)
@c endfile
#### test code ####
-# BEGIN \
-# @{
+# BEGIN @{
# for (;;) @{
# printf("enter a character: ")
# if (getline var <= 0)
@@ -19959,7 +21171,7 @@ 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()}
+assumption, as the array was likely created with @code{split()}
(@pxref{String Functions}):
@cindex @code{join()} user-defined function
@@ -20002,7 +21214,7 @@ 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
+@node Getlocaltime Function
@subsection Managing the Time of Day
@cindex libraries of @command{awk} functions, managing, time
@@ -20010,20 +21222,20 @@ more difficult than they really need to be.}
@cindex timestamps, formatted
@cindex time, managing
The @code{systime()} and @code{strftime()} functions described in
-@ref{Time Functions},
+@DBREF{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
+in human-readable form. Although @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
+The following function, @code{getlocaltime()}, 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
+@cindex @code{getlocaltime()} user-defined function
@example
@c file eg/lib/gettime.awk
-# gettimeofday.awk --- get the time of day in a usable format
+# getlocaltime.awk --- get the time of day in a usable format
@c endfile
@ignore
@c file eg/lib/gettime.awk
@@ -20056,7 +21268,7 @@ time formatted in the same way as the @command{date} utility:
# time["weeknum"] -- week number, Sunday first day
# time["altweeknum"] -- week number, Monday first day
-function gettimeofday(time, ret, now, i)
+function getlocaltime(time, ret, now, i)
@{
# get time once, avoids unnecessary system calls
now = systime()
@@ -20096,21 +21308,174 @@ function gettimeofday(time, ret, now, i)
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},
+@DBREF{Alarm Program}
uses this function.
-A more general design for the @code{gettimeofday()} function would have
+A more general design for the @code{getlocaltime()} function would have
allowed the user to supply an optional timestamp value to use instead
of the current time.
+@node Readfile Function
+@subsection Reading a Whole File At Once
+
+Often, it is convenient to have the entire contents of a file available
+in memory as a single string. A straightforward but naive way to
+do that might be as follows:
+
+@example
+function readfile(file, tmp, contents)
+@{
+ if ((getline tmp < file) < 0)
+ return
+
+ contents = tmp
+ while (getline tmp < file) > 0)
+ contents = contents RT tmp
+
+ close(file)
+ return contents
+@}
+@end example
+
+This function reads from @code{file} one record at a time, building
+up the full contents of the file in the local variable @code{contents}.
+It works, but is not necessarily efficient.
+
+The following function, based on a suggestion by Denis Shirokov,
+reads the entire contents of the named file in one shot:
+
+@cindex @code{readfile()} user-defined function
+@example
+@c file eg/lib/readfile.awk
+# readfile.awk --- read an entire file at once
+@c endfile
+@ignore
+@c file eg/lib/readfile.awk
+#
+# Original idea by Denis Shirokov, cosmogen@@gmail.com, April 2013
+#
+@c endfile
+@end ignore
+@c file eg/lib/readfile.awk
+
+function readfile(file, tmp, save_rs)
+@{
+ save_rs = RS
+ RS = "^$"
+ getline tmp < file
+ close(file)
+ RS = save_rs
+
+ return tmp
+@}
+@c endfile
+@end example
+
+It works by setting @code{RS} to @samp{^$}, a regular expression that
+will never match if the file has contents. @command{gawk} reads data from
+the file into @code{tmp} attempting to match @code{RS}. The match fails
+after each read, but fails quickly, such that @command{gawk} fills
+@code{tmp} with the entire contents of the file.
+(@DBXREF{Records} for information on @code{RT} and @code{RS}.)
+
+In the case that @code{file} is empty, the return value is the null
+string. Thus calling code may use something like:
+
+@example
+contents = readfile("/some/path")
+if (length(contents) == 0)
+ # file was empty @dots{}
+@end example
+
+This tests the result to see if it is empty or not. An equivalent
+test would be @samp{contents == ""}.
+
+@xref{Extension Sample Readfile}, for an extension function that
+also reads an entire file into memory.
+
+@node Shell Quoting
+@subsection Quoting Strings to Pass to the Shell
+
+@c included by permission
+@ignore
+Date: Sun, 27 Jul 2014 17:16:16 -0700
+Message-ID: <CAKuGj+iCF_obaCLDUX60aSAgbfocFVtguG39GyeoNxTFby5sqQ@mail.gmail.com>
+Subject: Useful awk function
+From: Mike Brennan <mike@madronabluff.com>
+To: Arnold Robbins <arnold@skeeve.com>
+@end ignore
+
+Michael Brennan offers the following programming pattern,
+which he uses frequently:
+
+@example
+#! /bin/sh
+
+awkp='
+ @dots{}
+ '
+
+@var{input_program} | awk "$awkp" | /bin/sh
+@end example
+
+For example, a program of his named @command{flac-edit} has this form:
+
+@example
+$ @kbd{flac-edit -song="Whoope! That's Great" file.flac}
+@end example
+
+It generates the following output, which is to be piped to
+the shell (@file{/bin/sh}):
+
+@example
+chmod +w file.flac
+metaflac --remove-tag=TITLE file.flac
+LANG=en_US.88591 metaflac --set-tag=TITLE='Whoope! That'"'"'s Great' file.flac
+chmod -w file.flac
+@end example
+
+Note the need for shell quoting. The function @code{shell_quote()}
+does it. @code{SINGLE} is the one-character string @code{"'"} and
+@code{QSINGLE} is the three-character string @code{"\"'\""}:
+
+@example
+@c file eg/lib/shellquote.awk
+# shell_quote --- quote an argument for passing to the shell
+@c endfile
+@ignore
+@c file eg/lib/shellquote.awk
+#
+# Michael Brennan
+# brennan@@madronabluff.com
+# September 2014
+@c endfile
+@end ignore
+@c file eg/lib/shellquote.awk
+
+function shell_quote(s, # parameter
+ SINGLE, QSINGLE, i, X, n, ret) # locals
+@{
+ if (s == "")
+ return "\"\""
+
+ SINGLE = "\x27" # single quote
+ QSINGLE = "\"\x27\""
+ n = split(s, X, SINGLE)
+
+ ret = SINGLE X[1] SINGLE
+ for (i = 2; i <= n; i++)
+ ret = ret QSINGLE SINGLE X[i] SINGLE
+
+ return ret
+@}
+@c endfile
+@end example
+
@node 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
+@cindex libraries of @command{awk} functions, managing, data files
+@cindex functions, library, managing data files
This @value{SECTION} presents functions that are useful for managing
command-line @value{DF}s.
@@ -20125,9 +21490,9 @@ command-line @value{DF}s.
@node Filetrans Function
@subsection Noting @value{DDF} Boundaries
-@cindex files, managing, @value{DF} boundaries
+@cindex files, managing, data file boundaries
@cindex files, initialization and cleanup
-The @code{BEGIN} and @code{END} rules are each executed exactly once at
+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
@@ -20159,15 +21524,14 @@ Besides solving the problem in only nine(!) lines of code, it does so
@c # Arnold Robbins, arnold@@skeeve.com, Public Domain
@c # January 1992
-FILENAME != _oldfilename \
-@{
+FILENAME != _oldfilename @{
if (_oldfilename != "")
endfile(_oldfilename)
_oldfilename = FILENAME
beginfile(FILENAME)
@}
-END @{ endfile(FILENAME) @}
+END @{ endfile(FILENAME) @}
@end example
This file must be loaded before the user's ``main'' program, so that the
@@ -20200,7 +21564,7 @@ The following version solves the problem:
@example
@c file eg/lib/ftrans.awk
-# ftrans.awk --- handle data file transitions
+# ftrans.awk --- handle datafile transitions
#
# user supplies beginfile() and endfile() functions
@c endfile
@@ -20220,16 +21584,43 @@ FNR == 1 @{
beginfile(FILENAME)
@}
-END @{ endfile(_filename_) @}
+END @{ endfile(_filename_) @}
@c endfile
@end example
-@ref{Wc Program},
+@DBREF{Wc Program}
shows how this library function can be used and
how it simplifies writing the main program.
-@c fakenode --- for prepinfo
-@subheading Advanced Notes: So Why Does @command{gawk} have @code{BEGINFILE} and @code{ENDFILE}?
+@cindex sidebar, So Why Does @command{gawk} Have @code{BEGINFILE} and @code{ENDFILE}?
+@ifdocbook
+@docbook
+<sidebar><title>So Why Does @command{gawk} Have @code{BEGINFILE} and @code{ENDFILE}?</title>
+@end docbook
+
+
+You are probably wondering, if @code{beginfile()} and @code{endfile()}
+functions can do the job, why does @command{gawk} have
+@code{BEGINFILE} and @code{ENDFILE} patterns (@pxref{BEGINFILE/ENDFILE})?
+
+Good question. Normally, if @command{awk} cannot open a file, this
+causes an immediate fatal error. In this case, there is no way for a
+user-defined function to deal with the problem, as the mechanism for
+calling it relies on the file being open and at the first record. Thus,
+the main reason for @code{BEGINFILE} is to give you a ``hook'' to catch
+files that cannot be processed. @code{ENDFILE} exists for symmetry,
+and because it provides an easy way to do per-file cleanup processing.
+
+@docbook
+</sidebar>
+@end docbook
+@end ifdocbook
+
+@ifnotdocbook
+@cartouche
+@center @b{So Why Does @command{gawk} Have @code{BEGINFILE} and @code{ENDFILE}?}
+
+
You are probably wondering, if @code{beginfile()} and @code{endfile()}
functions can do the job, why does @command{gawk} have
@@ -20237,11 +21628,13 @@ functions can do the job, why does @command{gawk} have
Good question. Normally, if @command{awk} cannot open a file, this
causes an immediate fatal error. In this case, there is no way for a
-user-defined function to deal with the problem, since the mechanism for
+user-defined function to deal with the problem, as the mechanism for
calling it relies on the file being open and at the first record. Thus,
the main reason for @code{BEGINFILE} is to give you a ``hook'' to catch
files that cannot be processed. @code{ENDFILE} exists for symmetry,
and because it provides an easy way to do per-file cleanup processing.
+@end cartouche
+@end ifnotdocbook
@node Rewind Function
@subsection Rereading the Current File
@@ -20290,34 +21683,26 @@ function rewind( i)
@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}).
+The @code{rewind()} function relies on the @code{ARGIND} variable
+(@pxref{Auto-set}), which is specific to @command{gawk}. It also
+relies on the @code{nextfile} keyword (@pxref{Nextfile Statement}).
+Because of this, you should not call it from an @code{ENDFILE} rule.
+(This isn't necessary anyway, because @command{gawk} goes to the next
+file as soon as an @code{ENDFILE} rule finishes!)
@node File Checking
@subsection Checking for Readable @value{DDF}s
-@cindex troubleshooting, readable @value{DF}s
-@cindex readable @value{DF}s@comma{} checking
+@cindex troubleshooting, readable data files
+@cindex readable data files@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:
+it stops with a fatal error. There are times when you might want to
+just ignore such files and keep going.@footnote{The @code{BEGINFILE}
+special pattern (@pxref{BEGINFILE/ENDFILE}) provides an alternative
+mechanism for dealing with files that can't be opened. However, the
+code here provides a portable solution.} You can do this by prepending
+the following program to your @command{awk} program:
@cindex @code{readable.awk} program
@example
@@ -20336,7 +21721,7 @@ program:
BEGIN @{
for (i = 1; i < ARGC; i++) @{
- if (ARGV[i] ~ /^[[:alpha:]_][[:alnum:]_]*=.*/ \
+ if (ARGV[i] ~ /^[a-zA-Z_][a-zA-Z0-9_]*=.*/ \
|| ARGV[i] == "-" || ARGV[i] == "/dev/stdin")
continue # assignment or standard input
else if ((getline junk < ARGV[i]) < 0) # unreadable
@@ -20351,14 +21736,19 @@ BEGIN @{
@cindex troubleshooting, @code{getline} function
This works, because the @code{getline} won't be fatal.
Removing the element from @code{ARGV} with @code{delete}
-skips the file (since it's no longer in the list).
+skips the file (because it's no longer in the list).
See also @ref{ARGC and ARGV}.
+Because @command{awk} variable names only allow the English letters,
+the regular expression check purposely does not use character classes
+such as @samp{[:alpha:]} and @samp{[:alnum:]}
+(@pxref{Bracket Expressions})
+
@node Empty Files
-@subsection Checking For Zero-length 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
+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
@@ -20417,46 +21807,6 @@ the end of the command-line arguments. Note that the test in the
condition of the @code{for} loop uses the @samp{<=} operator,
not @samp{<}.
-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
@@ -20465,7 +21815,7 @@ END @{
Occasionally, you might not want @command{awk} to process command-line
variable assignments
(@pxref{Assignment Options}).
-In particular, if you have a @value{FN} that contain an @samp{=} character,
+In particular, if you have a @value{FN} that contains 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}
@@ -20490,7 +21840,7 @@ a library file does the trick:
function disable_assigns(argc, argv, i)
@{
for (i = 1; i < argc; i++)
- if (argv[i] ~ /^[[:alpha:]_][[:alnum:]_]*=.*/)
+ if (argv[i] ~ /^[a-zA-Z_][a-zA-Z0-9_]*=.*/)
argv[i] = ("./" argv[i])
@}
@@ -20516,30 +21866,22 @@ 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 on
+Most utilities on POSIX-compatible systems take options 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
+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.
@@ -20594,7 +21936,6 @@ 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
@@ -20644,8 +21985,7 @@ 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.}
-@c FIXME: could use split(str, a, "") to do it more easily.
+We have left it alone, as using @code{substr()} is more portable.}
The discussion that follows walks through the code a bit at a time:
@@ -20677,7 +22017,7 @@ The discussion that follows walks through the code a bit at a time:
# <c> a character representing the current option
# Private Data:
-# _opti -- index in multi-flag option, e.g., -abc
+# _opti -- index in multiflag option, e.g., -abc
@c endfile
@end example
@@ -20733,8 +22073,7 @@ it is not an option, and it ends option processing. Continuing on:
i = index(options, thisopt)
if (i == 0) @{
if (Opterr)
- printf("%c -- invalid option\n",
- thisopt) > "/dev/stderr"
+ printf("%c -- invalid option\n", thisopt) > "/dev/stderr"
if (_opti >= length(argv[Optind])) @{
Optind++
_opti = 0
@@ -20814,9 +22153,9 @@ next element in @code{argv}. If neither condition is true, then only
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()}
+@code{Opterr} is set to one, because 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
+is set to one, because there's no reason to look at the program name, which is
in @code{ARGV[0]}:
@example
@@ -20828,7 +22167,7 @@ BEGIN @{
# test program
if (_getopt_test) @{
while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
- printf("c = <%c>, optarg = <%s>\n",
+ printf("c = <%c>, Optarg = <%s>\n",
_go_c, Optarg)
printf("non-option arguments:\n")
for (; Optind < ARGC; Optind++)
@@ -20844,52 +22183,55 @@ result of two sample runs of the test program:
@example
$ @kbd{awk -f getopt.awk -v _getopt_test=1 -- -a -cbARG bax -x}
-@print{} c = <a>, optarg = <>
-@print{} c = <c>, optarg = <>
-@print{} c = <b>, optarg = <ARG>
+@print{} c = <a>, Optarg = <>
+@print{} c = <c>, Optarg = <>
+@print{} c = <b>, Optarg = <ARG>
@print{} non-option arguments:
@print{} ARGV[3] = <bax>
@print{} ARGV[4] = <-x>
$ @kbd{awk -f getopt.awk -v _getopt_test=1 -- -a -x -- xyz abc}
-@print{} c = <a>, optarg = <>
+@print{} c = <a>, Optarg = <>
@error{} x -- invalid option
-@print{} c = <?>, optarg = <>
+@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.
+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.
@quotation NOTE
-After @code{getopt()} is through, it is the responsibility of the user level
-code 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 @code{getopt()} is through,
+user-level code must 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.
@end quotation
+Using @samp{#!} with the @option{-E} option may help avoid
+conflicts between your program's options and @command{gawk}'s options,
+as @option{-E} causes @command{gawk} to abandon processing of
+further options
+(@DBPXREF{Executable Scripts} and
+@ifnotdocbook
+@pxref{Options}).
+@end ifnotdocbook
+@ifdocbook
+@ref{Options}).
+@end ifdocbook
+
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 functions, library, user database@comma{} reading
@cindex user database@comma{} reading
-@c STARTOFRANGE dataur
@cindex database, users@comma{} reading
@cindex @code{PROCINFO} array
The @code{PROCINFO} array
@@ -20900,7 +22242,7 @@ 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},
+user database. @DBXREF{Group Functions}
for a similar suite that retrieves information from the group database.
@cindex @code{getpwent()} function (C library)
@@ -20919,7 +22261,7 @@ The ``password'' comes from the original user database file,
encrypted passwords (hence the name).
@cindex @command{pwcat} program
-While an @command{awk} program could simply read @file{/etc/passwd}
+Although 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
@@ -20931,14 +22273,12 @@ 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
+ * Generate a printable version of the password database.
*/
@c endfile
@ignore
@@ -21016,12 +22356,12 @@ 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
+(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.)
+(Similar comments about @code{long} versus @code{int} apply here.)
@item Full name
The user's full name, and perhaps other information associated with the
@@ -21043,7 +22383,7 @@ A few lines representative of @command{pwcat}'s output are as follows:
@cindex Robbins, Miriam
@example
$ @kbd{pwcat}
-@print{} root:3Ov02d5VaUPB6:0:1:Operator:/:/bin/sh
+@print{} root:x:0:1:Operator:/:/bin/sh
@print{} nobody:*:65534:65534::/:
@print{} daemon:*:1:1::/:
@print{} sys:*:2:2::/:/bin/csh
@@ -21118,33 +22458,29 @@ The @code{BEGIN} rule sets a private variable to the directory where
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
+The function @code{_pw_init()} fills three copies of the user information
+into 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, since @code{_pw_init()}
+The variable @code{_pw_inited} is used for efficiency, as @code{_pw_init()}
needs to be called only once.
+@cindex @code{PROCINFO} array, testing the field splitting
@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
+Doing so is necessary, as 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.
-
-@cindex @code{PROCINFO} array
-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
+or her own way of splitting records and fields.
+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 @code{FPAT},
or on some other @command{awk} implementation.
The code that checks for using @code{FPAT}, using @code{using_fpat}
-and @code{PROCINFO["FS"]} is similar.
+and @code{PROCINFO["FS"]}, is similar.
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.
@@ -21174,10 +22510,9 @@ function getpwnam(name)
@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:
+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
@@ -21238,28 +22573,20 @@ In turn, calling @code{_pw_init()} is not too expensive, because the
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,
+this is not necessary, as most @command{awk} programs are I/O-bound,
and such a change would clutter up the code.
-The @command{id} program in @ref{Id Program},
+The @command{id} program in @DBREF{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 functions, library, group database@comma{} reading
@cindex group database, reading
-@c STARTOFRANGE datagr
@cindex database, group, reading
-@cindex @code{PROCINFO} array
+@cindex @code{PROCINFO} array, and group membership
@cindex @code{getgrent()} function (C library)
@cindex @code{getgrent()} user-defined function
@cindex groups@comma{} information about
@@ -21267,7 +22594,7 @@ uses these functions.
@cindex group file
@cindex files, group
Much of the discussion presented in
-@ref{Passwd Functions},
+@DBREF{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
@@ -21285,7 +22612,7 @@ is as follows:
/*
* grcat.c
*
- * Generate a printable version of the group database
+ * Generate a printable version of the group database.
*/
@c endfile
@ignore
@@ -21372,12 +22699,12 @@ it is usually empty or set to @samp{*}.
@item Group ID Number
The group's numeric group ID number;
-this number must be unique within the file.
+the association of name to number must be 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 user names. These users are members of the group.
+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}
@@ -21420,8 +22747,7 @@ There are several, modeled after the C library functions of the same names:
@c line break on _gr_init for smallbook
@c file eg/lib/groupawk.in
-BEGIN \
-@{
+BEGIN @{
# Change to suit your system
_gr_awklib = "/usr/local/libexec/awk/"
@}
@@ -21454,8 +22780,7 @@ function _gr_init( oldfs, oldrs, olddol0, grcat,
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
+ _gr_groupsbyuser[a[i]] = gr_groupsbyuser[a[i]] " " $1
else
_gr_groupsbyuser[a[i]] = $1
@@ -21494,7 +22819,7 @@ is being used, and to restore the appropriate field splitting mechanism.
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 user name (@code{@w{_gr_groupsbyuser}}),
+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
@@ -21502,16 +22827,16 @@ 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:johny,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 user names are
-simply concatenated onto the previous list of users. (There is actually a
+group ID number is already seen. If it is, the usernames are
+simply concatenated onto the previous list of users.@footnote{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}.)
+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} or @code{FPAT} if necessary), @code{RS}, and @code{$0},
@@ -21553,7 +22878,7 @@ function getgrgid(gid)
@cindex @code{getgruser()} function (C library)
The @code{getgruser()} function does not have a C counterpart. It takes a
-user name and returns the list of groups that have the user as a member:
+username and returns the list of groups that have the user as a member:
@cindex @code{getgruser()} function, user-defined
@example
@@ -21582,7 +22907,6 @@ function getgrent()
@}
@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
@@ -21607,13 +22931,13 @@ 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},
+The @command{id} program in @DBREF{Id Program}
uses these functions.
@node Walking Arrays
@section Traversing Arrays of Arrays
-@ref{Arrays of Arrays}, described how @command{gawk}
+@DBREF{Arrays of Arrays} described how @command{gawk}
provides arrays of arrays. In particular, any element of
an array may be either a scalar, or another array. The
@code{isarray()} function (@pxref{Type Functions})
@@ -21663,32 +22987,139 @@ When run, the program produces the following output:
@example
$ @kbd{gawk -f walk_array.awk}
-@print{} a[4][1][1] = 411
-@print{} a[4][2] = 42
@print{} a[1] = 1
@print{} a[2][1] = 21
@print{} a[2][2] = 22
@print{} a[3] = 3
+@print{} a[4][1][1] = 411
+@print{} a[4][2] = 42
@end example
-@c ENDOFRANGE libfgdata
-@c ENDOFRANGE flibgdata
-@c ENDOFRANGE gdatar
-@c ENDOFRANGE libf
-@c ENDOFRANGE flib
-@c ENDOFRANGE fudlib
-@c ENDOFRANGE datagr
+
+@node Library Functions Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+Reading programs is an excellent way to learn Good Programming.
+The functions and programs provided in this @value{CHAPTER} and the next
+are intended to serve that purpose.
+
+@item
+When writing general-purpose library functions, put some thought into how
+to name any global variables so that they won't conflict with variables
+from a user's program.
+
+@item
+The functions presented here fit into the following categories:
+
+@c nested list
+@table @asis
+@item General problems
+Number-to-string conversion, assertions, rounding, random number
+generation, converting characters to numbers, joining strings, getting
+easily usable time-of-day information, and reading a whole file in
+one shot.
+
+@item Managing @value{DF}s
+Noting @value{DF} boundaries, rereading the current file, checking for
+readable files, checking for zero-length files, and treating assignments
+as @value{FN}s.
+
+@item Processing command-line options
+An @command{awk} version of the standard C @code{getopt()} function.
+
+@item Reading the user and group databases
+Two sets of routines that parallel the C library versions.
+
+@item Traversing arrays of arrays
+A simple function to traverse an array of arrays to any depth.
+@end table
+@c end nested list
+
+@end itemize
+
+@c EXCLUDE START
+@node Library Exercises
+@section Exercises
+
+@enumerate
+@item
+In @ref{Empty Files}, we presented the @file{zerofile.awk} program,
+which made use of @command{gawk}'s @code{ARGIND} variable. Can this
+problem be solved without relying on @code{ARGIND}? If so, how?
+
+@ignore
+# zerofile2.awk --- same thing, portably
+
+BEGIN @{
+ ARGIND = Argind = 0
+ for (i = 1; i < ARGC; i++)
+ Fnames[ARGV[i]]++
+
+@}
+FNR == 1 @{
+ while (ARGV[ARGIND] != FILENAME)
+ ARGIND++
+ Seen[FILENAME]++
+ if (Seen[FILENAME] == Fnames[FILENAME])
+ do
+ ARGIND++
+ while (ARGV[ARGIND] != FILENAME)
+@}
+ARGIND > Argind + 1 @{
+ for (Argind++; Argind < ARGIND; Argind++)
+ zerofile(ARGV[Argind], Argind)
+@}
+ARGIND != Argind @{
+ Argind = ARGIND
+@}
+END @{
+ if (ARGIND < ARGC - 1)
+ ARGIND = ARGC - 1
+ if (ARGIND > Argind)
+ for (Argind++; Argind <= ARGIND; Argind++)
+ zerofile(ARGV[Argind], Argind)
+@}
+@end ignore
+
+@item
+As a related challenge, revise that code to handle the case where
+an intervening value in @code{ARGV} is a variable assignment.
+
+@item
+@DBREF{Walking Arrays} presented a function that walked a multidimensional
+array to print it out. However, walking an array and processing
+each element is a general-purpose operation. Generalize the
+@code{walk_array()} function by adding an additional parameter named
+@code{process}.
+
+Then, inside the loop, instead of printing the array element's index and
+value, use the indirect function call syntax (@pxref{Indirect Calls})
+on @code{process}, passing it the index and the value.
+
+When calling @code{walk_array()}, you would pass the name of a
+user-defined function that expects to receive an index and a value,
+and then processes the element.
+
+Test your new version by printing the array; you should end up with
+output identical to that of the original version.
+
+@end enumerate
+@c EXCLUDE END
+
@node Sample Programs
@chapter Practical @command{awk} Programs
-@c STARTOFRANGE awkpex
@cindex @command{awk} programs, examples of
+@c FULLXREF ON
@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.
+@c FULLXREF OFF
@ifnotinfo
There are three sections.
The first describes how to run the programs presented
@@ -21715,6 +23146,8 @@ Many of these programs use library functions presented in
* Running Examples:: How to run these examples.
* Clones:: Clones of common utilities.
* Miscellaneous Programs:: Some interesting @command{awk} programs.
+* Programs Summary:: Summary of programs.
+* Programs Exercises:: Exercises.
@end menu
@node Running Examples
@@ -21747,7 +23180,6 @@ cut.awk -- -c1-8 myfiles > results
@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 implemented in
@@ -21775,14 +23207,11 @@ The programs are presented in alphabetical order.
@end menu
@node Cut Program
-@subsection Cutting out Fields and Columns
+@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.
@@ -21853,28 +23282,16 @@ supplied:
# Requires getopt() and join() library functions
@group
-function usage( e1, e2)
+function usage()
@{
- e1 = "usage: cut [-f list] [-d c] [-s] [files...]"
- e2 = "usage: cut [-c list] [files...]"
- print e1 > "/dev/stderr"
- print e2 > "/dev/stderr"
+ print("usage: cut [-f list] [-d c] [-s] [files...]") > "/dev/stderr"
+ print("usage: cut [-c list] [files...]") > "/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.
@@ -21889,8 +23306,7 @@ string:
@example
@c file eg/prog/cut.awk
-BEGIN \
-@{
+BEGIN @{
FS = "\t" # default
OFS = FS
while ((c = getopt(ARGC, ARGV, "sf:c:d:")) != -1) @{
@@ -21903,7 +23319,7 @@ BEGIN \
OFS = ""
@} else if (c == "d") @{
if (length(Optarg) > 1) @{
- printf("Using first character of %s" \
+ printf("cut: using first character of %s" \
" for delimiter\n", Optarg) > "/dev/stderr"
Optarg = substr(Optarg, 1, 1)
@}
@@ -21912,7 +23328,7 @@ BEGIN \
if (FS == " ") # defeat awk semantics
FS = "[ ]"
@} else if (c == "s")
- suppress++
+ suppress = 1
else
usage()
@}
@@ -21984,7 +23400,7 @@ function set_fieldlist( n, m, i, j, k, f, g)
m = split(f[i], g, "-")
@group
if (m != 2 || g[1] >= g[2]) @{
- printf("bad field list: %s\n",
+ printf("cut: bad field list: %s\n",
f[i]) > "/dev/stderr"
exit 1
@}
@@ -22021,7 +23437,7 @@ complete field list, including filler fields:
@example
@c file eg/prog/cut.awk
-function set_charlist( field, i, j, f, g, t,
+function set_charlist( field, i, j, f, g, n, m, t,
filler, last, len)
@{
field = 1 # count total fields
@@ -22031,7 +23447,7 @@ function set_charlist( field, i, j, f, g, t,
if (index(f[i], "-") != 0) @{ # range
m = split(f[i], g, "-")
if (m != 2 || g[1] >= g[2]) @{
- printf("bad character list: %s\n",
+ printf("cut: bad character list: %s\n",
f[i]) > "/dev/stderr"
exit 1
@}
@@ -22065,7 +23481,7 @@ function set_charlist( field, i, j, f, g, t,
@c endfile
@end example
-Next is the rule that actually processes the data. If the @option{-s} option
+Next is the rule that 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
@@ -22081,7 +23497,7 @@ written out between the fields:
@example
@c file eg/prog/cut.awk
@{
- if (by_fields && suppress && index($0, FS) != 0)
+ if (by_fields && suppress && index($0, FS) == 0)
next
for (i = 1; i <= nfields; i++) @{
@@ -22097,26 +23513,19 @@ written out between the fields:
@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
+variable to do the character-based cutting. It is possible in
other @command{awk} implementations to use @code{substr()}
-(@pxref{String Functions}),
+(@pxref{String Functions}), but
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
@@ -22124,9 +23533,9 @@ expressions that are almost identical to those available in @command{awk}
(@pxref{Regexp}).
You invoke it as follows:
-@example
-egrep @r{[} @var{options} @r{]} '@var{pattern}' @var{files} @dots{}
-@end example
+@display
+@command{egrep} [@var{options}] @code{'@var{pattern}'} @var{files} @dots{}
+@end display
The @var{pattern} is a regular expression. In typical usage, the regular
expression is quoted to prevent the shell from expanding any of the
@@ -22170,7 +23579,7 @@ and the file transition library program
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
+@code{IGNORECASE} predefined variable
(@pxref{Built-in Variables}):
@cindex @code{egrep.awk} program
@@ -22244,7 +23653,7 @@ matched lines in the output:
@c endfile
@end example
-The last two lines are commented out, since they are not needed in
+The last two lines are commented out, as they are not needed in
@command{gawk}. They should be uncommented if you have to use another version
of @command{awk}.
@@ -22254,9 +23663,7 @@ 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
+commented out as it is not necessary with @command{gawk}:
@example
@c file eg/prog/egrep.awk
@@ -22308,6 +23715,11 @@ function endfile(file)
@c endfile
@end example
+The @code{BEGINFILE} and @code{ENDFILE} special patterns
+(@pxref{BEGINFILE/ENDFILE}) could be used, but then the program would be
+@command{gawk}-specific. Additionally, this example was written before
+@command{gawk} acquired @code{BEGINFILE} and @code{ENDFILE}.
+
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
@@ -22362,11 +23774,8 @@ 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
+END @{
+ exit (total == 0)
@}
@c endfile
@end example
@@ -22376,36 +23785,18 @@ and then exits:
@example
@c file eg/prog/egrep.awk
-function usage( e)
+function usage()
@{
- e = "Usage: egrep [-csvil] [-e pat] [files ...]"
- e = e "\n\tegrep [-csvil] pat [files ...]"
- print e > "/dev/stderr"
+ print("Usage: egrep [-csvil] [-e pat] [files ...]") > "/dev/stderr"
+ print("\n\tegrep [-csvil] pat [files ...]") > "/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
+@subsection Printing Out User Information
@cindex printing, user information
@cindex users, information about, printing
@@ -22418,10 +23809,10 @@ corresponding user and group names. The output might look like this:
@example
$ @kbd{id}
-@print{} uid=500(arnold) gid=500(arnold) groups=6(disk),7(lp),19(floppy)
+@print{} uid=1000(arnold) gid=1000(arnold) groups=1000(arnold),4(adm),7(lp),27(sudo)
@end example
-@cindex @code{PROCINFO} array
+@cindex @code{PROCINFO} array, and user and group ID numbers
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
@@ -22454,6 +23845,8 @@ numbers:
# Arnold Robbins, arnold@@skeeve.com, Public Domain
# May 1993
# Revised February 1996
+# Revised May 2014
+# Revised September 2014
@c endfile
@end ignore
@@ -22463,8 +23856,7 @@ numbers:
# egid=5(blat) groups=9(nine),2(two),1(one)
@group
-BEGIN \
-@{
+BEGIN @{
uid = PROCINFO["uid"]
euid = PROCINFO["euid"]
gid = PROCINFO["gid"]
@@ -22473,34 +23865,22 @@ BEGIN \
printf("uid=%d", uid)
pw = getpwuid(uid)
- if (pw != "") @{
- split(pw, a, ":")
- printf("(%s)", a[1])
- @}
+ pr_first_field(pw)
if (euid != uid) @{
printf(" euid=%d", euid)
pw = getpwuid(euid)
- if (pw != "") @{
- split(pw, a, ":")
- printf("(%s)", a[1])
- @}
+ pr_first_field(pw)
@}
printf(" gid=%d", gid)
pw = getgrgid(gid)
- if (pw != "") @{
- split(pw, a, ":")
- printf("(%s)", a[1])
- @}
+ pr_first_field(pw)
if (egid != gid) @{
printf(" egid=%d", egid)
pw = getgrgid(egid)
- if (pw != "") @{
- split(pw, a, ":")
- printf("(%s)", a[1])
- @}
+ pr_first_field(pw)
@}
for (i = 1; ("group" i) in PROCINFO; i++) @{
@@ -22509,49 +23889,51 @@ BEGIN \
group = PROCINFO["group" i]
printf("%d", group)
pw = getgrgid(group)
- if (pw != "") @{
- split(pw, a, ":")
- printf("(%s)", a[1])
- @}
+ pr_first_field(pw)
if (("group" (i+1)) in PROCINFO)
printf(",")
@}
print ""
@}
+
+function pr_first_field(str, a)
+@{
+ if (str != "") @{
+ split(str, a, ":")
+ printf("(%s)", a[1])
+ @}
+@}
@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.
+@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
+in the array (@pxref{Reference to Elements}). 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
+The @code{pr_first_field()} function simply isolates out some
+code that is used repeatedly, making the whole program
+shorter and cleaner. In particular, moving the check for
+the empty string into this function saves several lines of code.
+
@node Split Program
@subsection Splitting a Large File into Pieces
@c FIXME: One day, update to current POSIX version of split
-@c STARTOFRANGE filspl
@cindex files, splitting
@cindex @code{split} utility
The @command{split} program splits large text files into smaller pieces.
@@ -22559,16 +23941,16 @@ Usage is as follows:@footnote{This is the traditional usage. The
POSIX usage is different, but not relevant for what the program
aims to demonstrate.}
-@example
-split @r{[}-@var{count}@r{]} file @r{[} @var{prefix} @r{]}
-@end example
+@display
+@command{split} [@code{-@var{count}}] [@var{file}] [@var{prefix}]
+@end display
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
+1,000 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
+preceded with a minus (e.g., @samp{-500} for files with 500 lines in them
+instead of 1,000). 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.
@@ -22580,7 +23962,7 @@ 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
+count of lines. The @value{DF} name is skipped over and the final argument
is used as the prefix for the output @value{FN}s:
@cindex @code{split.awk} program
@@ -22595,11 +23977,12 @@ is used as the prefix for the output @value{FN}s:
#
# Arnold Robbins, arnold@@skeeve.com, Public Domain
# May 1993
+# Revised slightly, May 2014
@c endfile
@end ignore
@c file eg/prog/split.awk
-# usage: split [-num] [file] [outname]
+# usage: split [-count] [file] [outname]
BEGIN @{
outfile = "x" # default
@@ -22608,14 +23991,14 @@ BEGIN @{
usage()
i = 1
- if (ARGV[i] ~ /^-[[:digit:]]+$/) @{
+ if (i in ARGV && ARGV[i] ~ /^-[[:digit:]]+$/) @{
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
+ i++ # skip datafile name
if (i in ARGV) @{
outfile = ARGV[i]
ARGV[i] = ""
@@ -22662,40 +24045,30 @@ moves to the next letter in the alphabet and @code{s2} starts over again at
@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)
+function usage()
@{
- e = "usage: split [-num] [file] [outname]"
- print e > "/dev/stderr"
+ print("usage: split [-num] [file] [outname]") > "/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 Exercise: Fix these problems.
-@c BFD...
-@c ENDOFRANGE filspl
+@ifset FOR_PRINT
+You might want to consider how to eliminate the use of
+@code{ord()} and @code{chr()}; this can be done in such a
+way as to solve the EBCDIC issue as well.
+@end ifset
+
@node Tee Program
@subsection Duplicating Output into Multiple Files
@@ -22707,17 +24080,17 @@ 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
+@display
+@command{tee} [@option{-a}] @var{file} @dots{}
+@end display
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
+@code{ARGV[0]} is not needed, so it is not copied.
+@code{tee} cannot use @code{ARGV} directly, because @command{awk} attempts to
process each @value{FN} in @code{ARGV} as input data.
@cindex flag variables
@@ -22746,8 +24119,7 @@ Finally, @command{awk} is forced to read the standard input by setting
@c endfile
@end ignore
@c file eg/prog/tee.awk
-BEGIN \
-@{
+BEGIN @{
for (i = 1; i < ARGC; i++)
copy[i] = ARGV[i]
@@ -22767,7 +24139,7 @@ BEGIN \
@c endfile
@end example
-The following single rule does all the work. Since there is no pattern, it is
+The following single rule does all the work. Because 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:
@@ -22798,7 +24170,7 @@ for (i in copy)
@end example
@noindent
-This is more concise but it is also less efficient. The @samp{if} is
+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
@@ -22809,8 +24181,7 @@ Finally, the @code{END} rule cleans up by closing all the output files:
@example
@c file eg/prog/tee.awk
-END \
-@{
+END @{
for (i in copy)
close(copy[i])
@}
@@ -22822,9 +24193,7 @@ END \
@c FIXME: One day, update to current POSIX version of uniq
-@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
@@ -22832,18 +24201,18 @@ 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
+@display
+@command{uniq} [@option{-udc} [@code{-@var{n}}]] [@code{+@var{n}}] [@var{inputfile} [@var{outputfile}]]
+@end display
The options for @command{uniq} are:
@table @code
@item -d
-Print only repeated lines.
+Print only repeated (duplicated) lines.
@item -u
-Print only nonrepeated lines.
+Print only nonrepeated (unique) lines.
@item -c
Count lines. This option overrides @option{-d} and @option{-u}. Both repeated
@@ -22858,11 +24227,11 @@ by runs of spaces and/or TABs.
Skip @var{n} characters before comparing lines. Any fields specified with
@samp{-@var{n}} are skipped first.
-@item @var{input file}
+@item @var{inputfile}
Data is read from the input file named on the command line, instead of from
the standard input.
-@item @var{output file}
+@item @var{outputfile}
The generated output is sent to the named output file, instead of to the
standard output.
@end table
@@ -22912,10 +24281,9 @@ standard output, @file{/dev/stdout}:
@end ignore
@c file eg/prog/uniq.awk
-function usage( e)
+function usage()
@{
- e = "Usage: uniq [-udc [-n]] [+n] [ in [ out ]]"
- print e > "/dev/stderr"
+ print("Usage: uniq [-udc [-n]] [+n] [ in [ out ]]") > "/dev/stderr"
exit 1
@}
@@ -22925,8 +24293,7 @@ function usage( e)
# -n skip n fields
# +n skip n characters, skip fields first
-BEGIN \
-@{
+BEGIN @{
count = 1
outputfile = "/dev/stdout"
opts = "udc0:1:2:3:4:5:6:7:8:9:"
@@ -22938,7 +24305,7 @@ BEGIN \
else if (c == "c")
do_count++
else if (index("0123456789", c) != 0) @{
- # getopt requires args to options
+ # getopt() requires args to options
# this messes us up for things like -5
if (Optarg ~ /^[[:digit:]]+$/)
fcount = (c Optarg) + 0
@@ -22970,22 +24337,20 @@ BEGIN \
@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:
+@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()} 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
@@ -23021,10 +24386,10 @@ 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.
+because 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.
+Nothing is printed, as 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}
@@ -23075,35 +24440,51 @@ END @{
@}
@c endfile
@end example
-@c ENDOFRANGE prunt
-@c ENDOFRANGE tpul
+
+@c FIXME: Include this?
+@ignore
+This program does not follow our recommended convention of naming
+global variables with a leading capital letter. Doing that would
+make the program a little easier to follow.
+@end ignore
+
+@ifset FOR_PRINT
+The logic for choosing which lines to print represents a @dfn{state
+machine}, which is ``a device that can be in one of a set number of stable
+conditions depending on its previous condition and on the present values
+of its inputs.''@footnote{This is the definition returned from entering
+@code{define: state machine} into Google.}
+Brian Kernighan suggests that
+``an alternative approach to state machines is to just read
+the input into an array, then use indexing. It's almost always
+easier code, and for most inputs where you would use this, just
+as fast.'' Consider how to rewrite the logic to follow this
+suggestion.
+@end ifset
+
+
@node Wc Program
@subsection Counting Things
@c FIXME: One day, update to current POSIX version of wc
-@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
+@display
+@command{wc} [@option{-lwc}] [@var{files} @dots{}]
+@end display
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:
+the files. The options and their meanings are as follows:
@table @code
@item -l
@@ -23120,7 +24501,7 @@ 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
+because @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.
@@ -23199,18 +24580,10 @@ function beginfile(file)
@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 FIXME: ONE DAY: make the above footnote an exercise,
-@c instead of giving away the answer.
+The @code{endfile()} function adds the current file's numbers to the
+running totals of lines, words, and characters. 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}:
@example
@c file eg/prog/wc.awk
@@ -23233,7 +24606,7 @@ function endfile(file)
@end example
There is one rule that is executed for each line. It adds the length of
-the record, plus one, to @code{chars}.@footnote{Since @command{gawk}
+the record, plus one, to @code{chars}.@footnote{Because @command{gawk}
understands multibyte locales, this code counts characters, not bytes.}
Adding one plus the record length
is needed because the newline character separating records (the value
@@ -23270,12 +24643,6 @@ END @{
@}
@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
@@ -23376,13 +24743,37 @@ word, comparing it to the previous one:
@cindex insomnia, cure for
@cindex Robbins, Arnold
@quotation
-@i{Nothing cures insomnia like a ringing alarm clock.}@*
-Arnold Robbins
+@i{Nothing cures insomnia like a ringing alarm clock.}
+@author Arnold Robbins
+@end quotation
+@cindex Quanstrom, Erik
+@ignore
+Date: Sat, 15 Feb 2014 16:47:09 -0500
+Subject: Re: 9atom install question
+Message-ID: <l2jcvx6j6mey60xnrkb0hhob.1392500829294@email.android.com>
+From: Erik Quanstrom <quanstro@quanstro.net>
+To: Aharon Robbins <arnold@skeeve.com>
+
+yes.
+
+- erik
+
+Aharon Robbins <arnold@skeeve.com> wrote:
+
+>> sleep is for web developers.
+>
+>Can I quote you, in the gawk manual?
+>
+>Thanks,
+>
+>Arnold
+@end ignore
+@quotation
+@i{Sleep is for web developers.}
+@author Erik Quanstrom
@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,
@@ -23390,8 +24781,8 @@ 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}.
+This program uses the @code{getlocaltime()} function from
+@ref{Getlocaltime 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
@@ -23410,7 +24801,7 @@ Here is the program:
@c file eg/prog/alarm.awk
# alarm.awk --- set an alarm
#
-# Requires gettimeofday() library function
+# Requires getlocaltime() library function
@c endfile
@ignore
@c file eg/prog/alarm.awk
@@ -23424,8 +24815,7 @@ Here is the program:
@c file eg/prog/alarm.awk
# usage: alarm time [ "message" [ count [ delay ] ] ]
-BEGIN \
-@{
+BEGIN @{
# Initial argument sanity checking
usage1 = "usage: alarm time ['message' [count [delay]]]"
usage2 = sprintf("\t(%s) time ::= hh:mm", ARGV[1])
@@ -23482,7 +24872,7 @@ is how long to wait before setting off the alarm:
minute = atime[2] + 0 # force numeric
# get current broken down time
- gettimeofday(now)
+ getlocaltime(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.,
@@ -23500,7 +24890,7 @@ is how long to wait before setting off the alarm:
# how long to sleep for
naptime = target - current
if (naptime <= 0) @{
- print "time is in the past!" > "/dev/stderr"
+ print "alarm: time is in the past!" > "/dev/stderr"
exit 1
@}
@c endfile
@@ -23535,13 +24925,10 @@ seconds are necessary:
@}
@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
@@ -23552,24 +24939,21 @@ often used to map uppercase letters into lowercase for further processing:
@end example
@command{tr} requires two lists of characters.@footnote{On some older
-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,
+systems, including Solaris, the system version of @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.
+
+Once upon a time,
@c early or mid-1989!
-a user proposed that a transliteration function should
-be added to @command{gawk}.
+a user proposed adding a transliteration function
+to @command{gawk}.
@c Wishing to avoid gratuitous new features,
@c at least theoretically
The following program was written to
@@ -23577,16 +24961,12 @@ 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:
+The @command{translate} program was written long before @command{gawk}
+acquired the ability to split each character in a string into separate
+array elements. Thus, it makes repeated use of the @code{substr()},
+@code{index()}, and @code{gsub()} built-in functions (@pxref{String
+Functions}). There are two functions. The first, @code{stranslate()},
+takes three arguments:
@table @code
@item from
@@ -23605,7 +24985,7 @@ loop goes through @code{from}, one character at a time. For each character
in @code{from}, if the character appears in @code{target},
it is replaced with the corresponding @code{to} character.
-The @code{translate()} function simply calls @code{stranslate()} using @code{$0}
+The @code{translate()} function 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.
@@ -23677,29 +25057,31 @@ BEGIN @{
@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.
+It is possible to do character transliteration in a user-level
+function, but it is not necessarily efficient, and we (the @command{gawk}
+developers) started to consider adding a built-in function. However,
+shortly after writing this program, we learned that Brian Kernighan
+had added the @code{toupper()} and @code{tolower()} functions to his
+@command{awk} (@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
+
+Another obvious improvement is to enable the use of ranges,
+such as @samp{a-z}, as allowed by the @command{tr} utility.
+Look at the code for @file{cut.awk} (@pxref{Cut Program})
+for inspiration.
+
@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.''}
@@ -23717,13 +25099,24 @@ 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).
+It sets @code{MAXLINES} to 100, because 100 is the maximum number
+of lines on the page
+@iftex
+(@math{20 @cdot 5 = 100}).
+@end iftex
+@ifnottex
+@ifnotdocbook
+(20 * 5 = 100).
+@end ifnotdocbook
+@end ifnottex
+@docbook
+(20 &sdot; 5 = 100). @c
+@end docbook
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
+@code{line[2]} next to @code{line[7]}, and so on. Two loops
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.
@@ -23811,24 +25204,20 @@ function printpage( i, j)
Count++
@}
-END \
-@{
+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
When working with large amounts of text, it can be interesting to know
how often different words appear. For example, an author may overuse
-certain words, in which case she might wish to find synonyms to substitute
+certain words, in which case he or she might wish to find synonyms to substitute
for words that appear too often. This @value{SUBSECTION} develops a
program for counting words and presenting the frequency information
in a useful format.
@@ -23836,7 +25225,7 @@ in a useful format.
At first glance, a program like this would seem to do the job:
@example
-# Print list of word frequencies
+# wordfreq-first-try.awk --- print list of word frequencies
@{
for (i = 1; i <= NF; i++)
@@ -23858,13 +25247,13 @@ it prints the counts.
This program has several problems that prevent it from being
useful on real text files:
-@itemize @bullet
+@itemize @value{BULLET}
@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.
+as the same word. This is undesirable, because words are capitalized
+if they begin sentences in normal text, and a frequency analyzer should
+not be sensitive to capitalization.
@item
Words are detected using the @command{awk} convention that fields are
@@ -23905,6 +25294,10 @@ END @{
@}
@end example
+The regexp @code{/[^[:alnum:]_[:blank:]]/} might have been written
+@code{/[[:punct:]]/}, but then underscores would also be removed,
+and we want to keep them.
+
Assuming we have saved this program in a file named @file{wordfreq.awk},
and that the data is in @file{file1}, the following pipeline:
@@ -23945,12 +25338,10 @@ 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}),
@@ -24014,16 +25405,14 @@ information. For example, using the following @code{print} statement in the
print data[lines[i]], lines[i]
@end example
+@noindent
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
@@ -24036,29 +25425,30 @@ The nodes
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
+If you want to experiment with these programs, it is tedious 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 @uref{http://texinfo.org, Texinfo},
+This @value{DOCUMENT} is written in @uref{http://www.gnu.org/software/texinfo/, Texinfo},
the GNU project's document formatting language.
A single Texinfo source file can be used to produce both
-printed and online documentation.
+printed documentation, with @TeX{}, and online documentation.
@ifnotinfo
-Texinfo is fully documented in the book
+(Texinfo is fully documented in the book
@cite{Texinfo---The GNU Documentation Format},
-available from the Free Software Foundation.
+available from the Free Software Foundation,
+and also available @uref{http://www.gnu.org/software/texinfo/manual/texinfo/, online}.)
@end ifnotinfo
@ifinfo
-The Texinfo language is described fully, starting with
-@inforef{Top, , Texinfo, texinfo,Texinfo---The GNU Documentation Format}.
+(The Texinfo language is described fully, starting with
+@inforef{Top, , Texinfo, texinfo,Texinfo---The GNU Documentation Format}.)
@end ifinfo
For our purposes, it is enough to know three things about Texinfo input
files:
-@itemize @bullet
+@itemize @value{BULLET}
@item
The ``at'' symbol (@samp{@@}) is special in Texinfo, much as
the backslash (@samp{\}) is in C
@@ -24092,7 +25482,7 @@ Lines containing @samp{@@group} and @samp{@@end group} are simply removed.
(@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
+(@file{gawktexi.in}) 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.
@@ -24113,7 +25503,7 @@ It also prints some final advice:
@@example
@@c file examples/messages.awk
-END @@@{ print "Always avoid bored archeologists!" @@@}
+END @@@{ print "Always avoid bored archaeologists!" @@@}
@@c end file
@@end example
@dots{}
@@ -24129,8 +25519,7 @@ 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
+# extract.awk --- extract files and run programs from texinfo files
@c endfile
@ignore
@c file eg/prog/extract.awk
@@ -24144,10 +25533,9 @@ exits with a zero exit status, signifying OK:
BEGIN @{ IGNORECASE = 1 @}
-/^@@c(omment)?[ \t]+system/ \
-@{
+/^@@c(omment)?[ \t]+system/ @{
if (NF < 3) @{
- e = (FILENAME ":" FNR)
+ e = ("extract: " FILENAME ":" FNR)
e = (e ": badly formed `system' line")
print e > "/dev/stderr"
next
@@ -24156,7 +25544,7 @@ BEGIN @{ IGNORECASE = 1 @}
$2 = ""
stat = system($0)
if (stat != 0) @{
- e = (FILENAME ":" FNR)
+ e = ("extract: " FILENAME ":" FNR)
e = (e ": warning: system returned " stat)
print e > "/dev/stderr"
@}
@@ -24166,13 +25554,7 @@ BEGIN @{ IGNORECASE = 1 @}
@noindent
The variable @code{e} is used so that the rule
-fits nicely on the
-@ifnotinfo
-page.
-@end ifnotinfo
-@ifnottex
-screen.
-@end ifnottex
+fits nicely on the @value{PAGE}.
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
@@ -24199,20 +25581,18 @@ the array @code{a}, using the @code{split()} function
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.@footnote{This program was written before @command{gawk} had the
-@code{gensub()} function. Consider how you might use it to simplify the code.}
+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
+value of @code{SUBSEP} (@pxref{Multidimensional}),
+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/ \
-@{
+/^@@c(omment)?[ \t]+file/ @{
if (NF != 3) @{
- e = (FILENAME ":" FNR ": badly formed `file' line")
+ e = ("extract: " FILENAME ":" FNR ": badly formed `file' line")
print e > "/dev/stderr"
next
@}
@@ -24257,21 +25637,20 @@ 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
+only closed when a new @value{DF} name 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"
+ printf("extract: %s:%d: unexpected EOF or error\n",
+ FILENAME, FNR) > "/dev/stderr"
exit 1
@}
@end group
@@ -24282,8 +25661,6 @@ END @{
@}
@c endfile
@end example
-@c ENDOFRANGE texse
-@c ENDOFRANGE fitex
@node Simple Sed
@subsection A Simple Stream Editor
@@ -24294,22 +25671,22 @@ 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
+Although @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
+@var{command1} < orig.data | sed 's/old/new/g' | @var{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
+@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
+additional arguments are treated as @value{DF} names to process. If none
are provided, the standard input is used:
@cindex Brennan, Michael
@@ -24386,36 +25763,14 @@ 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,
+Finally, the single rule handles the printing scheme outlined earlier,
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
In @ref{Include Files}, we saw how @command{gawk} provides a built-in
file-inclusion capability. However, this is a @command{gawk} extension.
@@ -24449,8 +25804,8 @@ BEGIN @{
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.
+and also allows @dfn{nested} includes (i.e., a file that is included
+with @code{@@include} can contain further @code{@@include} statements).
@command{igawk} makes an effort to only include files once, so that nested
includes don't accidentally include a library function twice.
@@ -24476,24 +25831,24 @@ a shell variable that will be expanded. There are two cases:
@enumerate a
@item
-Literal text, provided with @option{--source} or @option{--source=}. This
+Literal text, provided with @option{-e} 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.
+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.
+Because the file-inclusion program works the way @command{gawk} does, this
+gets the text of the file included in 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
+@code{@@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).
+arguments that the user supplied (such as the @value{DF} names).
@end enumerate
This program uses shell variables extensively: for storing command-line arguments,
@@ -24508,24 +25863,25 @@ argument is @samp{debug}.
The next part loops through all the command-line arguments.
There are several cases of interest:
-@table @code
-@item --
+@c @asis for docbook
+@table @asis
+@item @option{--}
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
+@item @option{-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
+@item @option{-v}, @option{-F}
These are saved and passed on to @command{gawk}.
-@item -f@r{,} --file@r{,} --file=@r{,} -Wfile=
+@item @option{-f}, @option{--file}, @option{--file=}, @option{-Wfile=}
The @value{FN} is appended to the shell variable @code{program} with an
-@samp{@@include} statement.
+@code{@@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}
@@ -24533,10 +25889,10 @@ utilities to do this work. Unfortunately, some versions of @command{echo} evalu
escape sequences in their arguments, possibly mangling the program text.
Using @command{expr} avoids this problem.)
-@item --source@r{,} --source=@r{,} -Wsource=
+@item @option{--source}, @option{--source=}, @option{-Wsource=}
The source text is appended to @code{program}.
-@item --version@r{,} -Wversion
+@item @option{--version}, @option{-Wversion}
@command{igawk} prints its version number, runs @samp{gawk --version}
to get the @command{gawk} version information, and then exits.
@end table
@@ -24547,6 +25903,7 @@ 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,
+the shell variable
@code{program} contains the complete text of the original @command{awk}
program.
@@ -24643,14 +26000,14 @@ fi
@c endfile
@end example
-The @command{awk} program to process @samp{@@include} directives
+The @command{awk} program to process @code{@@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}
+@value{FN}s and @code{@@include} statements are managed using a stack.
+As each @code{@@include} is encountered, the current @value{FN} is
+``pushed'' onto the stack and the file named in the @code{@@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
@@ -24668,8 +26025,8 @@ 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}
+@samp{getline junk < t} can loop forever if the file exists but is empty.}
+If the file can be read, it is closed and the @value{FN}
is returned:
@ignore
@@ -24724,10 +26081,10 @@ BEGIN @{
@c endfile
@end example
-The stack is initialized with @code{ARGV[1]}, which will be @file{/dev/stdin}.
+The stack is initialized with @code{ARGV[1]}, which will be @code{"/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}.
+do not start with @code{@@include} are printed verbatim.
+If the line does start with @code{@@include}, the @value{FN} is in @code{$2}.
@code{pathto()} is called to generate the full path. If it cannot, then the program
prints an error message and continues.
@@ -24755,7 +26112,7 @@ the program is done:
fpath = pathto($2)
@group
if (fpath == "") @{
- printf("igawk:%s:%d: cannot find %s\n",
+ printf("igawk: %s:%d: cannot find %s\n",
input[stackptr], FNR, $2) > "/dev/stderr"
continue
@}
@@ -24779,9 +26136,10 @@ 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
+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}.
@@ -24795,15 +26153,17 @@ 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.
+Run @command{gawk} with the @code{@@include}-processing program (the
+value of the @code{expand_prog} shell variable) reading 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.
+Standard input is the contents of the user's program,
+from the shell variable @code{program}.
+Feed its contents 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.
+Save the results of this processing 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,
@@ -24819,7 +26179,7 @@ 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
+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.
@@ -24834,27 +26194,25 @@ eval gawk $opts -- '"$processed_program"' '"$@@"'
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 fifth version of this program.
+This version of @command{igawk} represents the fifth version of this program.
There are four key simplifications that make the program work better:
-@itemize @bullet
+@itemize @value{BULLET}
@item
-Using @samp{@@include} even for the files named with @option{-f} makes building
+Using @code{@@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.
+@code{@@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.
+nested @code{@@include} statements.
@item
Instead of saving the expanded program in a temporary file, putting it in a shell variable
@@ -24871,68 +26229,32 @@ 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.
-@ignore
-With @command{igawk},
-there is no real reason to build @samp{@@include} processing into
-@command{gawk} itself.
-@end ignore
-
-@cindex search paths
-@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.
+features to a program; they can often be layered on top.@footnote{@command{gawk}
+does @code{@@include} processing itself in order to support the use
+of @command{awk} programs as Web CGI scripts.}
-@c Exercise: make this change
-@c ENDOFRANGE libfex
-@c ENDOFRANGE flibex
-@c ENDOFRANGE awkpex
@node Anagram Program
-@subsection Finding Anagrams From A Dictionary
+@subsection Finding Anagrams from a Dictionary
+@cindex anagrams, finding
An interesting programming challenge is to
search for @dfn{anagrams} in a
word list (such as
@file{/usr/share/dict/words} on many GNU/Linux systems).
One word is an anagram of another if both words contain
the same letters
-(for example, ``babbling'' and ``blabbing'').
+(e.g., ``babbling'' and ``blabbing'').
-An elegant algorithm is presented in Column 2, Problem C of
-Jon Bentley's @cite{Programming Pearls}, second edition.
-The idea is to give words that are anagrams a common signature,
-sort all the words together by their signature, and then print them.
-Dr.@: Bentley observes that taking the letters in each word and
-sorting them produces that common signature.
+Column 2, Problem C, of Jon Bentley's @cite{Programming Pearls}, Second
+Edition, presents an elegant algorithm. The idea is to give words that
+are anagrams a common signature, sort all the words together by their
+signature, and then print them. Dr.@: Bentley observes that taking the
+letters in each word and sorting them produces that common signature.
The following program uses arrays of arrays to bring together
words with the same signature and array sorting to print the words
-in sorted order.
+in sorted order:
@cindex @code{anagram.awk} program
@example
@@ -25003,7 +26325,7 @@ function word2key(word, a, i, n, result)
Finally, the @code{END} rule traverses the array
and prints out the anagram lists. It sends the output
-to the system @command{sort} command, since otherwise
+to the system @command{sort} command because otherwise
the anagrams would appear in arbitrary order:
@example
@@ -25031,20 +26353,23 @@ Here is some partial output when the program is run:
@example
$ @kbd{gawk -f anagram.awk /usr/share/dict/words | grep '^b'}
@dots{}
-babbled blabbed
-babbler blabber brabble
-babblers blabbers brabbles
-babbling blabbing
-babbly blabby
-babel bable
-babels beslab
-babery yabber
+babbled blabbed
+babbler blabber brabble
+babblers blabbers brabbles
+babbling blabbing
+babbly blabby
+babel bable
+babels beslab
+babery yabber
@dots{}
@end example
+
@node Signature Program
-@subsection And Now For Something Completely Different
+@subsection And Now for Something Completely Different
+@cindex signature program
+@cindex Brini, Davide
The following program was written by Davide Brini
@c (@email{dave_br@@gmx.com})
and is published on @uref{http://backreference.org/2011/02/03/obfuscated-awk/,
@@ -25069,7 +26394,10 @@ X*(X-x)-o*o,(x+X)*o*o+o,x*(X-x)-O-O,x-O+(O+o+X+x)*(o+O),X*X-X*(x-O)-x+O,
O+X*(o*(o+O)+O),+x+O+X*o,x*(x-o),(o+X+x)*o*o-(x-O-O),O+(X-x)*(X+O),x-O@}'
@end example
-We leave it to you to determine what the program does.
+@cindex Johansen, Chris
+We leave it to you to determine what the program does. (If you are
+truly desperate to understand it, see Chris Johansen's explanation,
+which is embedded in the Texinfo source file for this @value{DOCUMENT}.)
@ignore
To: "Arnold Robbins" <arnold@skeeve.com>
@@ -25078,28 +26406,28 @@ Subject: The GNU Awk User's Guide, Section 13.3.11
From: "Chris Johansen" <johansen@main.nc.us>
Message-ID: <op.v0iw6wlv7finx3@asusodin.thrudvang.lan>
-Arnold, you don't know me, but we have a tenuous connection. My wife is
+Arnold, you don't know me, but we have a tenuous connection. My wife is
Barbara A. Field, FAIA, GIT '65 (B. Arch.).
-I have had a couple of paper copies of "Effective Awk Programming" for
-years, and now I'm going through a Kindle version of "The GNU Awk User's
-Guide" again. When I got to section 13.3.11, I reformatted and lightly
+I have had a couple of paper copies of "Effective Awk Programming" for
+years, and now I'm going through a Kindle version of "The GNU Awk User's
+Guide" again. When I got to section 13.3.11, I reformatted and lightly
commented Davide Brin's signature script to understand its workings.
-It occurs to me that this might have pedagogical value as an example
-(although imperfect) of the value of whitespace and comments, and a
-starting point for that discussion. It certainly helped _me_ understand
-what's going on. You are welcome to it, as-is or modified (subject to
+It occurs to me that this might have pedagogical value as an example
+(although imperfect) of the value of whitespace and comments, and a
+starting point for that discussion. It certainly helped _me_ understand
+what's going on. You are welcome to it, as-is or modified (subject to
Davide's constraints, of course, which I think I have met).
-If I were to include it in a future edition, I would put it at some
-distance from section 13.3.11, say, as a note or an appendix, so as not to
+If I were to include it in a future edition, I would put it at some
+distance from section 13.3.11, say, as a note or an appendix, so as not to
be a "spoiler" to the puzzle.
Best regards,
---
+--
Chris Johansen {johansen at main dot nc dot us}
- . . . collapsing the probability wave function, sending ripples of
+ . . . collapsing the probability wave function, sending ripples of
certainty through the space-time continuum.
@@ -25108,7 +26436,7 @@ certainty through the space-time continuum.
# From "13.3.11 And Now For Something Completely Different"
# http://www.gnu.org/software/gawk/manual/html_node/Signature-Program.html#Signature-Program
-# Copyright © 2008 Davide Brini
+# Copyright © 2008 Davide Brini
# Copying and distribution of the code published in this page, with
# or without modification, are permitted in any medium without
@@ -25149,58 +26477,2317 @@ BEGIN {
}
@end ignore
-@c The original text for this chapter was contributed by Efraim Yawitz.
-@c FIXME: Add more indexing.
+@node Programs Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+The programs provided in this @value{CHAPTER}
+continue on the theme that reading programs is an excellent way to learn
+Good Programming.
+
+@item
+Using @samp{#!} to make @command{awk} programs directly runnable makes
+them easier to use. Otherwise, invoke the program using @samp{awk
+-f @dots{}}.
+
+@item
+Reimplementing standard POSIX programs in @command{awk} is a pleasant
+exercise; @command{awk}'s expressive power lets you write such programs
+in relatively few lines of code, yet they are functionally complete
+and usable.
+
+@item
+One of standard @command{awk}'s weaknesses is working with individual
+characters. The ability to use @code{split()} with the empty string as
+the separator can considerably simplify such tasks.
+
+@item
+The library functions from @ref{Library Functions}, proved their
+usefulness for a number of real (if small) programs.
+
+@item
+Besides reinventing POSIX wheels, other programs solved a selection of
+interesting problems, such as finding duplicates words in text, printing
+mailing labels, and finding anagrams.
+
+@end itemize
+
+@c EXCLUDE START
+@node Programs Exercises
+@section Exercises
+
+@enumerate
+@item
+Rewrite @file{cut.awk} (@pxref{Cut Program})
+using @code{split()} with @code{""} as the separator.
+
+@item
+In @ref{Egrep Program}, we mentioned that @samp{egrep -i} could be
+simulated in versions of @command{awk} without @code{IGNORECASE} by
+using @code{tolower()} on the line and the pattern. In a footnote there,
+we also mentioned that this solution has a bug: the translated line is
+output, and not the original one. Fix this problem.
+@c Exercise: Fix this, w/array and new line as key to original line
+
+@item
+The POSIX version of @command{id} takes options that control which
+information is printed. Modify the @command{awk} version
+(@pxref{Id Program}) to accept the same arguments and perform in the
+same way.
+
+@item
+The @code{split.awk} program (@pxref{Split Program}) assumes
+that letters are contiguous in the character set,
+which isn't true for EBCDIC systems.
+Fix this problem.
+(Hint: Consider a different way to work through the alphabet,
+without relying on @code{ord()} and @code{chr()}.)
+
+@item
+In @file{uniq.awk} (@pxref{Uniq Program}, the
+logic for choosing which lines to print represents a @dfn{state
+machine}, which is ``a device that can be in one of a set number of stable
+conditions depending on its previous condition and on the present values
+of its inputs.''@footnote{This is the definition returned from entering
+@code{define: state machine} into Google.}
+Brian Kernighan suggests that
+``an alternative approach to state machines is to just read
+the input into an array, then use indexing. It's almost always
+easier code, and for most inputs where you would use this, just
+as fast.'' Rewrite the logic to follow this
+suggestion.
+
+
+@item
+Why can't the @file{wc.awk} program (@pxref{Wc Program}) just
+use the value of @code{FNR} in @code{endfile()}?
+Hint: Examine the code in @ref{Filetrans Function}.
+
+@ignore
+@command{wc} can't just use the value of @code{FNR} in
+@code{endfile()}. If you examine the code in @ref{Filetrans Function},
+you will see that @code{FNR} has already been reset by the time
+@code{endfile()} is called.
+@end ignore
+
+@item
+Manipulation of individual characters in the @command{translate} program
+(@pxref{Translate Program}) is painful using standard @command{awk}
+functions. Given that @command{gawk} can split strings into individual
+characters using @code{""} as the separator, how might you use this
+feature to simplify the program?
+
+@item
+The @file{extract.awk} program (@pxref{Extract Program}) was written
+before @command{gawk} had the @code{gensub()} function. Use it
+to simplify the code.
+
+@item
+Compare the performance of the @file{awksed.awk} program
+(@pxref{Simple Sed}) with the more straightforward:
+
+@example
+BEGIN @{
+ pat = ARGV[1]
+ repl = ARGV[2]
+ ARGV[1] = ARGV[2] = ""
+@}
+
+@{ gsub(pat, repl); print @}
+@end example
+
+@item
+What are the advantages and disadvantages of @file{awksed.awk} versus
+the real @command{sed} utility?
+
+@ignore
+ Advantage: egrep regexps
+ speed (?)
+ Disadvantage: no & in replacement text
+
+Others?
+@end ignore
+
+@item
+In @ref{Igawk Program}, we mentioned that 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. What problem does this engender though?
+@c answer, reading from "-" or /dev/stdin
+
+@cindex search paths
+@cindex search paths, for source files
+@cindex source files@comma{} search path for
+@cindex files, source@comma{} search path for
+@cindex directories, searching
+@item
+As an additional example of the idea that it is not always necessary to
+add new features to a program, 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 @code{@@include}
+directives, @file{default.awk} could simply contain @code{@@include}
+statements for the desired library functions.
+Make this change.
+
+@item
+Modify @file{anagram.awk} (@pxref{Anagram Program}), to avoid
+the use of the external @command{sort} utility.
+
+@end enumerate
+@c EXCLUDE END
+
+@ifnotinfo
+@part @value{PART3}Moving Beyond Standard @command{awk} with @command{gawk}
+@end ifnotinfo
+
+@ifdocbook
+Part III focuses on features specific to @command{gawk}.
+It contains the following chapters:
+
+@itemize @value{BULLET}
+@item
+@ref{Advanced Features}
+
+@item
+@ref{Internationalization}
+
+@item
+@ref{Debugger}
+
+@item
+@ref{Arbitrary Precision Arithmetic}
+
+@item
+@ref{Dynamic Extensions}
+@end itemize
+@end ifdocbook
+
+@node Advanced Features
+@chapter Advanced Features of @command{gawk}
+@cindex @command{gawk}, features, advanced
+@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
+@cindex Langston, Peter
+@cindex English, Steve
+@quotation
+@i{Write documentation as if whoever reads it is
+a violent psychopath who knows where you live.}
+@author 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.
+Then, @command{gawk}'s special features for sorting arrays are presented.
+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. Finally, @command{gawk}
+can @dfn{profile} an @command{awk} program, making it possible to tune
+it for performance.
+
+@c FULLXREF ON
+A number of advanced features require separate @value{CHAPTER}s of their
+own:
+
+@itemize @value{BULLET}
+@item
+@ref{Internationalization}, discusses how to internationalize
+your @command{awk} programs, so that they can speak multiple
+national languages.
+
+@item
+@ref{Debugger}, describes @command{gawk}'s built-in command-line
+debugger for debugging @command{awk} programs.
+
+@item
+@ref{Arbitrary Precision Arithmetic}, describes how you can use
+@command{gawk} to perform arbitrary-precision arithmetic.
+
+@item
+@ref{Dynamic Extensions},
+discusses the ability to dynamically add new built-in functions to
+@command{gawk}.
+@end itemize
+@c FULLXREF OFF
+
+@menu
+* Nondecimal Data:: Allowing nondecimal input data.
+* Array Sorting:: Facilities for controlling array traversal and
+ sorting arrays.
+* Two-way I/O:: Two-way communications with another process.
+* TCP/IP Networking:: Using @command{gawk} for network programming.
+* Profiling:: Profiling your @command{awk} programs.
+* Advanced Features Summary:: Summary of advanced features.
+@end menu
+
+@node Nondecimal Data
+@section Allowing Nondecimal Input Data
+@cindex @option{--non-decimal-data} option
+@cindex advanced features, 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 values in your input data:
+
+@example
+$ @kbd{echo 0123 123 0x123 |}
+> @kbd{gawk --non-decimal-data '@{ printf "%d, %d, %d\n", $1, $2, $3 @}'}
+@print{} 83, 123, 291
+@end example
+
+For this feature to work, write your program so that
+@command{gawk} treats your data as numeric:
+
+@example
+$ @kbd{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 need to add zero to a field to force it to
+be treated as a number. For example:
+
+@example
+$ @kbd{echo 0123 123 0x123 | gawk --non-decimal-data '}
+> @kbd{@{ print $1, $2, $3}
+> @kbd{print $1 + 0, $2 + 0, $3 + 0 @}'}
+@print{} 0123 123 0x123
+@print{} 83 123 291
+@end example
+
+Because it is common to have decimal data with leading zeros, and because
+using this facility could lead to surprising results, the default is to leave it
+disabled. If you want it, you must explicitly request it.
+
+@cindex programming conventions, @code{--non-decimal-data} option
+@cindex @option{--non-decimal-data} option, @code{strtonum()} function and
+@cindex @code{strtonum()} function (@command{gawk}), @code{--non-decimal-data} option and
+@quotation 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{String Functions}).
+This makes your programs easier to write and easier to read, and
+leads to less surprising results.
+
+This option may disappear in a future version of @command{gawk}.
+@end quotation
+
+@node Array Sorting
+@section Controlling Array Traversal and Array Sorting
+
+@command{gawk} lets you control the order in which a @samp{for (i in array)}
+loop traverses an array.
+
+In addition, two built-in functions, @code{asort()} and @code{asorti()},
+let you sort arrays based on the array values and indices, respectively.
+These two functions also provide control over the sorting criteria used
+to order the elements during sorting.
+
+@menu
+* Controlling Array Traversal:: How to use PROCINFO["sorted_in"].
+* Array Sorting Functions:: How to use @code{asort()} and @code{asorti()}.
+@end menu
+
+@node Controlling Array Traversal
+@subsection Controlling Array Traversal
+
+By default, the order in which a @samp{for (i in array)} loop
+scans an array is not defined; it is generally based upon
+the internal implementation of arrays inside @command{awk}.
+
+Often, though, it is desirable to be able to loop over the elements
+in a particular order that you, the programmer, choose. @command{gawk}
+lets you do this.
+
+@DBREF{Controlling Scanning} describes how you can assign special,
+predefined values to @code{PROCINFO["sorted_in"]} in order to
+control the order in which @command{gawk} traverses an array
+during a @code{for} loop.
+
+In addition, the value of @code{PROCINFO["sorted_in"]} can be a
+function name.@footnote{This is why the predefined sorting orders
+start with an @samp{@@} character, which cannot be part of an identifier.}
+This lets you traverse an array based on any custom criterion.
+The array elements are ordered according to the return value of this
+function. The comparison function should be defined with at least
+four arguments:
+
+@example
+function comp_func(i1, v1, i2, v2)
+@{
+ @var{compare elements 1 and 2 in some fashion}
+ @var{return < 0; 0; or > 0}
+@}
+@end example
+
+Here, @var{i1} and @var{i2} are the indices, and @var{v1} and @var{v2}
+are the corresponding values of the two elements being compared.
+Either @var{v1} or @var{v2}, or both, can be arrays if the array being
+traversed contains subarrays as values.
+(@DBXREF{Arrays of Arrays} for more information about subarrays.)
+The three possible return values are interpreted as follows:
+
+@table @code
+@item comp_func(i1, v1, i2, v2) < 0
+Index @var{i1} comes before index @var{i2} during loop traversal.
+
+@item comp_func(i1, v1, i2, v2) == 0
+Indices @var{i1} and @var{i2}
+come together but the relative order with respect to each other is undefined.
+
+@item comp_func(i1, v1, i2, v2) > 0
+Index @var{i1} comes after index @var{i2} during loop traversal.
+@end table
+
+Our first comparison function can be used to scan an array in
+numerical order of the indices:
+
+@example
+function cmp_num_idx(i1, v1, i2, v2)
+@{
+ # numerical index comparison, ascending order
+ return (i1 - i2)
+@}
+@end example
+
+Our second function traverses an array based on the string order of
+the element values rather than by indices:
+
+@example
+function cmp_str_val(i1, v1, i2, v2)
+@{
+ # string value comparison, ascending order
+ v1 = v1 ""
+ v2 = v2 ""
+ if (v1 < v2)
+ return -1
+ return (v1 != v2)
+@}
+@end example
+
+The third
+comparison function makes all numbers, and numeric strings without
+any leading or trailing spaces, come out first during loop traversal:
+
+@example
+function cmp_num_str_val(i1, v1, i2, v2, n1, n2)
+@{
+ # numbers before string value comparison, ascending order
+ n1 = v1 + 0
+ n2 = v2 + 0
+ if (n1 == v1)
+ return (n2 == v2) ? (n1 - n2) : -1
+ else if (n2 == v2)
+ return 1
+ return (v1 < v2) ? -1 : (v1 != v2)
+@}
+@end example
+
+Here is a main program to demonstrate how @command{gawk}
+behaves using each of the previous functions:
+
+@example
+BEGIN @{
+ data["one"] = 10
+ data["two"] = 20
+ data[10] = "one"
+ data[100] = 100
+ data[20] = "two"
+
+ f[1] = "cmp_num_idx"
+ f[2] = "cmp_str_val"
+ f[3] = "cmp_num_str_val"
+ for (i = 1; i <= 3; i++) @{
+ printf("Sort function: %s\n", f[i])
+ PROCINFO["sorted_in"] = f[i]
+ for (j in data)
+ printf("\tdata[%s] = %s\n", j, data[j])
+ print ""
+ @}
+@}
+@end example
+
+Here are the results when the program is run:
+
+@example
+$ @kbd{gawk -f compdemo.awk}
+@print{} Sort function: cmp_num_idx @ii{Sort by numeric index}
+@print{} data[two] = 20
+@print{} data[one] = 10 @ii{Both strings are numerically zero}
+@print{} data[10] = one
+@print{} data[20] = two
+@print{} data[100] = 100
+@print{}
+@print{} Sort function: cmp_str_val @ii{Sort by element values as strings}
+@print{} data[one] = 10
+@print{} data[100] = 100 @ii{String 100 is less than string 20}
+@print{} data[two] = 20
+@print{} data[10] = one
+@print{} data[20] = two
+@print{}
+@print{} Sort function: cmp_num_str_val @ii{Sort all numeric values before all strings}
+@print{} data[one] = 10
+@print{} data[two] = 20
+@print{} data[100] = 100
+@print{} data[10] = one
+@print{} data[20] = two
+@end example
+
+Consider sorting the entries of a GNU/Linux system password file
+according to login name. The following program sorts records
+by a specific field position and can be used for this purpose:
+
+@example
+# passwd-sort.awk --- simple program to sort by field position
+# field position is specified by the global variable POS
+
+function cmp_field(i1, v1, i2, v2)
+@{
+ # comparison by value, as string, and ascending order
+ return v1[POS] < v2[POS] ? -1 : (v1[POS] != v2[POS])
+@}
+
+@{
+ for (i = 1; i <= NF; i++)
+ a[NR][i] = $i
+@}
+
+END @{
+ PROCINFO["sorted_in"] = "cmp_field"
+ if (POS < 1 || POS > NF)
+ POS = 1
+ for (i in a) @{
+ for (j = 1; j <= NF; j++)
+ printf("%s%c", a[i][j], j < NF ? ":" : "")
+ print ""
+ @}
+@}
+@end example
+
+The first field in each entry of the password file is the user's login name,
+and the fields are separated by colons.
+Each record defines a subarray,
+with each field as an element in the subarray.
+Running the program produces the
+following output:
+
+@example
+$ @kbd{gawk -v POS=1 -F: -f sort.awk /etc/passwd}
+@print{} adm:x:3:4:adm:/var/adm:/sbin/nologin
+@print{} apache:x:48:48:Apache:/var/www:/sbin/nologin
+@print{} avahi:x:70:70:Avahi daemon:/:/sbin/nologin
+@dots{}
+@end example
+
+The comparison should normally always return the same value when given a
+specific pair of array elements as its arguments. If inconsistent
+results are returned, then the order is undefined. This behavior can be
+exploited to introduce random order into otherwise seemingly
+ordered data:
+
+@example
+function cmp_randomize(i1, v1, i2, v2)
+@{
+ # random order (caution: this may never terminate!)
+ return (2 - 4 * rand())
+@}
+@end example
+
+As already mentioned, the order of the indices is arbitrary if two
+elements compare equal. This is usually not a problem, but letting
+the tied elements come out in arbitrary order can be an issue, especially
+when comparing item values. The partial ordering of the equal elements
+may change the next time the array is traversed, if other elements are added or
+removed from the array. One way to resolve ties when comparing elements
+with otherwise equal values is to include the indices in the comparison
+rules. Note that doing this may make the loop traversal less efficient,
+so consider it only if necessary. The following comparison functions
+force a deterministic order, and are based on the fact that the
+(string) indices of two elements are never equal:
+
+@example
+function cmp_numeric(i1, v1, i2, v2)
+@{
+ # numerical value (and index) comparison, descending order
+ return (v1 != v2) ? (v2 - v1) : (i2 - i1)
+@}
+
+function cmp_string(i1, v1, i2, v2)
+@{
+ # string value (and index) comparison, descending order
+ v1 = v1 i1
+ v2 = v2 i2
+ return (v1 > v2) ? -1 : (v1 != v2)
+@}
+@end example
+
+@c Avoid using the term ``stable'' when describing the unpredictable behavior
+@c if two items compare equal. Usually, the goal of a "stable algorithm"
+@c is to maintain the original order of the items, which is a meaningless
+@c concept for a list constructed from a hash.
+
+A custom comparison function can often simplify ordered loop
+traversal, and the sky is really the limit when it comes to
+designing such a function.
+
+When string comparisons are made during a sort, either for element
+values where one or both aren't numbers, or for element indices
+handled as strings, the value of @code{IGNORECASE}
+(@pxref{Built-in Variables}) controls whether
+the comparisons treat corresponding upper- and lowercase letters as
+equivalent or distinct.
+
+Another point to keep in mind is that in the case of subarrays,
+the element values can themselves be arrays; a production comparison
+function should use the @code{isarray()} function
+(@pxref{Type Functions}),
+to check for this, and choose a defined sorting order for subarrays.
+
+All sorting based on @code{PROCINFO["sorted_in"]}
+is disabled in POSIX mode,
+because the @code{PROCINFO} array is not special in that case.
+
+As a side note, sorting the array indices before traversing
+the array has been reported to add 15% to 20% overhead to the
+execution time of @command{awk} programs. For this reason,
+sorted array traversal is not the default.
+
+@c The @command{gawk}
+@c maintainers believe that only the people who wish to use a
+@c feature should have to pay for it.
+
+@node Array Sorting Functions
+@subsection Sorting Array Values and Indices with @command{gawk}
+
+@cindex arrays, sorting
+@cindexgawkfunc{asort}
+@cindex @code{asort()} function (@command{gawk}), arrays@comma{} sorting
+@cindexgawkfunc{asorti}
+@cindex @code{asorti()} function (@command{gawk}), arrays@comma{} sorting
+@cindex sort function, arrays, sorting
+In most @command{awk} implementations, sorting an array requires writing
+a @code{sort()} function. This can be educational for exploring
+different sorting algorithms, but 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 default comparison is based on the type of the elements
+(@pxref{Typing and Comparison}).
+All numeric values come before all string values,
+which in turn come before all subarrays.
+
+@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, use the
+@code{asorti()} function. The interface and behavior are 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++) @{
+ @ii{Work with sorted indices directly:}
+ @var{do something with} dest[i]
+ @dots{}
+ @ii{Access original array via sorted indices:}
+ @var{do something with} source[dest[i]]
+ @}
+@}
+@end example
+
+So far, so good. Now it starts to get interesting. Both @code{asort()}
+and @code{asorti()} accept a third string argument to control comparison
+of array elements. When we introduced @code{asort()} and @code{asorti()}
+in @ref{String Functions}, we ignored this third argument; however,
+now is the time to describe how this argument affects these two functions.
+
+Basically, the third argument specifies how the array is to be sorted.
+There are two possibilities. As with @code{PROCINFO["sorted_in"]},
+this argument may be one of the predefined names that @command{gawk}
+provides (@pxref{Controlling Scanning}), or it may be the name of a
+user-defined function (@pxref{Controlling Array Traversal}).
+
+In the latter case, @emph{the function can compare elements in any way
+it chooses}, taking into account just the indices, just the values,
+or both. This is extremely powerful.
+
+Once the array is sorted, @code{asort()} takes the @emph{values} in
+their final order, and uses them to fill in the result array, whereas
+@code{asorti()} takes the @emph{indices} in their final order, and uses
+them to fill in the result array.
+
+@cindex reference counting, sorting arrays
+@quotation NOTE
+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.
+@end quotation
+
+@c Document It And Call It A Feature. Sigh.
+@cindex @command{gawk}, @code{IGNORECASE} variable in
+@cindex arrays, sorting, and @code{IGNORECASE} variable
+@cindex @code{IGNORECASE} variable, and array sorting functions
+Because @code{IGNORECASE} affects string comparisons, the value
+of @code{IGNORECASE} also affects sorting for both @code{asort()} and @code{asorti()}.
+Note also that the locale's sorting order does @emph{not}
+come into play; comparisons are based on character values only.@footnote{This
+is true because locale-based comparison occurs only when in
+POSIX-compatibility mode, and because @code{asort()} and @code{asorti()} are
+@command{gawk} extensions, they are not available in that case.}
+
+@node Two-way I/O
+@section Two-Way Communications with Another Process
+
+@c 8/2014. Neither Mike nor BWK saw this as relevant. Commenting it out.
+@ignore
+@cindex Brennan, Michael
+@cindex programmers, attractiveness of
+@smallexample
+@c Path: cssun.mathcs.emory.edu!gatech!newsxfer3.itd.umich.edu!news-peer.sprintlink.net!news-sea-19.sprintlink.net!news-in-west.sprintlink.net!news.sprintlink.net!Sprint!204.94.52.5!news.whidbey.com!brennan
+From: brennan@@whidbey.com (Mike Brennan)
+Newsgroups: comp.lang.awk
+Subject: Re: Learn the SECRET to Attract Women Easily
+Date: 4 Aug 1997 17:34:46 GMT
+@c Organization: WhidbeyNet
+@c Lines: 12
+Message-ID: <5s53rm$eca@@news.whidbey.com>
+@c References: <5s20dn$2e1@chronicle.concentric.net>
+@c Reply-To: brennan@whidbey.com
+@c NNTP-Posting-Host: asn202.whidbey.com
+@c X-Newsreader: slrn (0.9.4.1 UNIX)
+@c Xref: cssun.mathcs.emory.edu comp.lang.awk:5403
+
+On 3 Aug 1997 13:17:43 GMT, Want More Dates???
+<tracy78@@kilgrona.com> wrote:
+>Learn the SECRET to Attract Women Easily
+>
+>The SCENT(tm) Pheromone Sex Attractant For Men to Attract Women
+
+The scent of awk programmers is a lot more attractive to women than
+the scent of perl programmers.
+--
+Mike Brennan
+@c brennan@@whidbey.com
+@end smallexample
+@end ignore
+
+@cindex advanced features, 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.@footnote{Michael
+Brennan suggests the use of @command{rand()} to generate unique
+@value{FN}s. This is a valid point; nevertheless, temporary files
+remain more difficult to use than two-way pipes.} @c 8/2014
+
+@cindex coprocesses
+@cindex input/output, two-way
+@cindex @code{|} (vertical bar), @code{|&} operator (I/O)
+@cindex vertical bar (@code{|}), @code{|&} operator (I/O)
+@cindex @command{csh} utility, @code{|&} operator, comparison with
+However, with @command{gawk}, it is possible to
+open a @emph{two-way} pipe to another process. The second process is
+termed a @dfn{coprocess}, as it runs in parallel with @command{gawk}.
+The two-way connection is created using the @samp{|&} operator
+(borrowed from the Korn shell, @command{ksh}):@footnote{This is very
+different from the same operator in the C shell and in Bash.}
+
+@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 @value{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 coprocess.
+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 coprocess 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}.
+This is not strictly necessary here, but it's good to know how to do this.
+
+@cindex @command{gawk}, @code{PROCINFO} array in
+@cindex @code{PROCINFO} array, and communications via ptys
+You may also 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, save in convenience variable
+PROCINFO[command, "pty"] = 1 # update PROCINFO
+print @dots{} |& command # start two-way pipe
+@dots{}
+@end example
+
+@noindent
+Using ptys usually 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, network programming
+@cindex networks, programming
+@cindex TCP/IP
+@cindex @code{/inet/@dots{}} special files (@command{gawk})
+@cindex files, @code{/inet/@dots{}} (@command{gawk})
+@cindex @code{/inet4/@dots{}} special files (@command{gawk})
+@cindex files, @code{/inet4/@dots{}} (@command{gawk})
+@cindex @code{/inet6/@dots{}} special files (@command{gawk})
+@cindex files, @code{/inet6/@dots{}} (@command{gawk})
+@cindex @code{EMISTERED}
+@ifnotdocbook
+@quotation
+@code{EMRED}:@*
+@ @ @ @ @i{A host is a host from coast to coast,@*
+@ @ @ @ and nobody talks to a host that's close,@*
+@ @ @ @ unless the host that isn't close@*
+@ @ @ @ is busy, hung, or dead.}
+@author Mike O'Brien (aka Mr.@: Protocol)
+@end quotation
+@end ifnotdocbook
+
+@docbook
+<blockquote>
+<attribution>Mike O'Brien (aka Mr.&nbsp;Protocol)</attribution>
+<literallayout class="normal"><literal>EMISTERED</literal>:
+&nbsp;&nbsp;&nbsp;&nbsp;<emphasis>A host is a host from coast to coast,</emphasis>
+&nbsp;&nbsp;&nbsp;&nbsp;<emphasis>and no-one can talk to host that's close,</emphasis>
+&nbsp;&nbsp;&nbsp;&nbsp;<emphasis>unless the host that isn't close</emphasis>
+&nbsp;&nbsp;&nbsp;&nbsp;<emphasis>is busy, hung, or dead.</emphasis></literallayout>
+</blockquote>
+@end docbook
+
+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 network 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 one of @samp{/inet/},
+@samp{/inet4/}, or @samp{/inet6/}.
+
+The full syntax of the special @value{FN} is
+@file{/@var{net-type}/@var{protocol}/@var{local-port}/@var{remote-host}/@var{remote-port}}.
+The components are:
+
+@table @var
+@item net-type
+Specifies the kind of Internet connection to make.
+Use @samp{/inet4/} to force IPv4, and
+@samp{/inet6/} to force IPv6.
+Plain @samp{/inet/} (which used to be the only option) uses
+the system default, most likely IPv4.
+
+@item protocol
+The protocol to use over IP. This must be either @samp{tcp}, or
+@samp{udp}, for a TCP or UDP IP connection,
+respectively. TCP should be used for most applications.
+
+@item local-port
+@cindex @code{getaddrinfo()} 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{getaddrinfo()} 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
+
+@cindex @command{gawk}, @code{ERRNO} variable in
+@cindex @code{ERRNO} variable
+@quotation NOTE
+Failure in opening a two-way socket will result in a non-fatal error
+being returned to the calling code. The value of @code{ERRNO} indicates
+the error (@pxref{Auto-set}).
+@end quotation
+
+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
+See
+@inforef{Top, , General Introduction, gawkinet, TCP/IP Internetworking with @command{gawk}},
+@end ifinfo
+@ifnotinfo
+See
+@uref{http://www.gnu.org/software/gawk/manual/gawkinet/,
+@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 Profiling
+@section Profiling Your @command{awk} Programs
+@cindex @command{awk} programs, profiling
+@cindex profiling @command{awk} programs
+@cindex @code{awkprof.out} file
+@cindex files, @code{awkprof.out}
+
+You may produce execution traces of your @command{awk} programs.
+This is done by passing the option @option{--profile} to @command{gawk}.
+When @command{gawk} 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 @option{--profile} option
+As shown in the following example,
+the @option{--profile} option can be used to change the name of the file
+where @command{gawk} will write the profile:
+
+@example
+gawk --profile=myprog.prof -f myprog.awk data1 data2
+@end example
+
+@noindent
+In the preceding example, @command{gawk} places the profile in
+@file{myprog.prof} instead of in @file{awkprof.out}.
+
+Here is a sample session showing a simple @command{awk} program,
+its input data, and the results from running @command{gawk} with the
+@option{--profile} option. 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 the
+@command{gawk} profiler on this program and data. (This example also
+illustrates that @command{awk} programmers sometimes get up very early
+in the morning to work.)
+
+@cindex @code{BEGIN} pattern, and profiling
+@cindex @code{END} pattern, and profiling
+@example
+ # gawk profile, created Mon Sep 29 05:16:21 2014
+
+ # BEGIN rule(s)
+
+ BEGIN @{
+ 1 print "First BEGIN rule"
+ @}
+
+ BEGIN @{
+ 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 rule(s)
+
+ END @{
+ 1 print "First END rule"
+ @}
+
+ END @{
+ 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 features of profiling output.
+They are as follows:
+
+@itemize @value{BULLET}
+@item
+The program is printed in the order @code{BEGIN} rules,
+@code{BEGINFILE} rules,
+pattern/action rules,
+@code{ENDFILE} rules, @code{END} rules and functions, listed
+alphabetically.
+Multiple @code{BEGIN} and @code{END} rules retain their
+separate identities, as do
+multiple @code{BEGINFILE} and @code{ENDFILE} rules.
+
+@cindex patterns, counts, in a profile
+@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, in a profile
+@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, in a profile
+@cindex user-defined, functions, counts, in a profile
+@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)
+@cindex braces (@code{@{@}})
+@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), in a profile
+@cindex parentheses @code{()}, in a profile
+@item
+Parentheses are used only where needed, as indicated by the structure
+of the program and the precedence rules.
+For example, @samp{(3 + 5) * 4} means add three and five, then multiply
+the total by four. However, @samp{3 + 5 * 4} has no parentheses, and
+means @samp{3 + (5 * 4)}.
+
+@ignore
+@item
+All string concatenations are parenthesized too.
+(This could be made a bit smarter.)
+@end ignore
+
+@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{gawk} supplies leading comments in
+front of the @code{BEGIN} and @code{END} rules,
+the @code{BEGINFILE} and @code{ENDFILE} 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{gawk} creates the
+profiled version by ``pretty printing'' its internal representation of
+the program. The advantage to this is that @command{gawk} can produce
+a standard representation.
+Also, things such as:
+
+@example
+/foo/
+@end example
+
+@noindent
+come out as:
+
+@example
+/foo/ @{
+ print $0
+@}
+@end example
+
+@noindent
+which is correct, but possibly unexpected.
+
+@cindex profiling @command{awk} programs, dynamically
+@cindex @command{gawk} program, dynamic profiling
+@cindex dynamic profiling
+Besides creating profiles when a program has completed,
+@command{gawk} 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{gawk} with the @option{--profile}
+option in the background:
+
+@example
+$ @kbd{gawk --profile -f myprog &}
+[1] 13992
+@end example
+
+@cindex @command{kill} command@comma{} dynamic profiling
+@cindex @code{USR1} signal, for dynamic profiling
+@cindex @code{SIGUSR1} signal, for dynamic profiling
+@cindex signals, @code{USR1}/@code{SIGUSR1}, for profiling
+@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{gawk}:
+
+@example
+$ @kbd{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 one was specified with
+the @option{--profile} option.
+
+Along with the regular profile, as shown earlier, the profile file
+includes a trace of any active functions:
+
+@example
+# Function Call Stack:
+
+# 3. baz
+# 2. bar
+# 1. foo
+# -- main --
+@end example
+
+You may send @command{gawk} 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, for dynamic profiling
+@cindex @code{SIGHUP} signal, for dynamic profiling
+@cindex signals, @code{HUP}/@code{SIGHUP}, for profiling
+If you use the @code{HUP} signal instead of the @code{USR1} signal,
+@command{gawk} produces the profile and the function call trace and then exits.
+
+@cindex @code{INT} signal (MS-Windows)
+@cindex @code{SIGINT} signal (MS-Windows)
+@cindex signals, @code{INT}/@code{SIGINT} (MS-Windows)
+@cindex @code{QUIT} signal (MS-Windows)
+@cindex @code{SIGQUIT} signal (MS-Windows)
+@cindex signals, @code{QUIT}/@code{SIGQUIT} (MS-Windows)
+When @command{gawk} runs on MS-Windows systems, it uses the
+@code{INT} and @code{QUIT} signals for producing the profile and, in
+the case of the @code{INT} signal, @command{gawk} 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{Ctrl-@key{C}} or @kbd{Ctrl-@key{BREAK}} key, while the
+@code{QUIT} signal is generated by the @kbd{Ctrl-@key{\}} key.
+
+Finally, @command{gawk} also accepts another option, @option{--pretty-print}.
+When called this way, @command{gawk} ``pretty prints'' the program into
+@file{awkprof.out}, without any execution counts.
+
+@quotation NOTE
+Once upon a time, the @option{--pretty-print} option would also run
+your program. This is is no longer the case.
+@end quotation
+
+There is a significant difference between the output created when
+profiling, and that created when pretty-printing. Pretty-printed output
+preserves the original comments that were in the program, although their
+placement may not correspond exactly to their original locations in the
+source code.
+
+However, as a deliberate design decision, profiling output @emph{omits}
+the original program's comments. This allows you to focus on the
+execution count data and helps you avoid the temptation to use the
+profiler for pretty-printing.
+
+Additionally, pretty-printed output does not have the leading indentation
+that the profiling output does. This makes it easy to pretty-print your
+code once development is completed, and then use the result as the final
+version of your program.
+
+@node Advanced Features Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+The @option{--non-decimal-data} option causes @command{gawk} to treat
+octal- and hexadecimal-looking input data as octal and hexadecimal.
+This option should be used with caution or not at all; use of @code{strtonum()}
+is preferable.
+Note that this option may disappear in a future version of @command{gawk}.
+
+@item
+You can take over complete control of sorting in @samp{for (@var{indx} in @var{array})}
+array traversal by setting @code{PROCINFO["sorted_in"]} to the name of a user-defined
+function that does the comparison of array elements based on index and value.
+
+@item
+Similarly, you can supply the name of a user-defined comparison function as the
+third argument to either @code{asort()} or @command{asorti()} to control how
+those functions sort arrays. Or you may provide one of the predefined control
+strings that work for @code{PROCINFO["sorted_in"]}.
+
+@item
+You can use the @samp{|&} operator to create a two-way pipe to a coprocess.
+You read from the coprocess with @code{getline} and write to it with @code{print}
+or @code{printf}. Use @code{close()} to close off the coprocess completely, or
+optionally, close off one side of the two-way communications.
+
+@item
+By using special @value{FN}s with the @samp{|&} operator, you can open a
+TCP/IP (or UDP/IP) connection to remote hosts in the Internet. @command{gawk}
+supports both IPv4 and IPv6.
+
+@item
+You can generate statement count profiles of your program. This can help you
+determine which parts of your program may be taking the most time and let
+you tune them more easily. Sending the @code{USR1} signal while profiling causes
+@command{gawk} to dump the profile and keep going, including a function call stack.
+
+@item
+You can also just ``pretty print'' the program. This currently also runs
+the program, but that will change in the next major release.
+
+@end itemize
+
+
+@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.
+
+@cindex internationalization, localization
+@cindex @command{gawk}, internationalization and, See internationalization
+@cindex internationalization, localization, @command{gawk} and
+For many years, 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 forced to write in C or C++ when internationalization is
+a requirement.
+
+@menu
+* I18N and L10N:: Internationalization and Localization.
+* Explaining gettext:: How GNU @command{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.
+* I18N Summary:: Summary of I18N stuff.
+@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 @command{gettext}
+
+@cindex internationalizing a program
+@cindex @command{gettext} library
+@command{gawk} uses GNU @command{gettext} to provide its internationalization
+features.
+The facilities in GNU @command{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 @command{gettext}.
+Therefore, these features are not available
+if you are using one of those operating systems. Sorry.}
+
+@cindex portability, @command{gettext} library and
+When using GNU @command{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 reviews 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
+(@command{"guide"}) to the @command{gettext} library,
+by calling the @code{textdomain()} function.
+
+@cindex @code{.pot} files
+@cindex files, @code{.pot}
+@cindex portable object template files
+@cindex files, portable object template
+@item
+Messages from the application are extracted from the source code and
+collected into a portable object template file (@file{guide.pot}),
+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.pot}
+is copied to a portable object file (@code{.po})
+and translations are created and shipped with the application.
+For example, there might be a @file{fr.po} for a French translation.
+
+@cindex @code{.gmo} files
+@cindex files, @code{.gmo}
+@cindex message object files
+@cindex files, message object
+@item
+Each language's @file{.po} file is converted into a binary
+message object (@file{.gmo}) 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 @command{gettext}
+to use @file{.gmo} files in a different directory than the standard
+one by using the @code{bindtextdomain()} function.
+
+@cindex @code{.gmo} files, specifying directory of
+@cindex files, @code{.gmo}, 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("%s", 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), C macro
+@cindex underscore (@code{_}), C macro
+The GNU @command{gettext} developers, recognizing that typing
+@samp{gettext(@dots{})} 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("%s", _("Don't Panic!\n"));
+@end example
+
+@cindex internationalization, localization, locale categories
+@cindex @command{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 @command{gettext} knows about are:
+
+@table @code
+@cindex @code{LC_MESSAGES} locale category
+@item LC_MESSAGES
+Text messages. This is the default category for @command{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) as well as character encoding.
+@ignore
+In June 2001 Bruno Haible wrote:
+- Description of LC_CTYPE: It determines both
+ 1. character encoding,
+ 2. character type information.
+ (For example, in both KOI8-R and ISO-8859-5 the character type information
+ is the same - cyrillic letters could as 'alpha' - but the encoding is
+ different.)
+@end ignore
+This information is accessed via the
+POSIX character classes in regular expressions,
+such as @code{/[[:alnum:]]/}
+(@pxref{Bracket Expressions}).
+
+@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:
+1,234.56 versus 1.234,56.}
+
+@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 the 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 @command{gettext}.)
+@end table
+
+@node Programmer i18n
+@section Internationalizing @command{awk} Programs
+@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 @command{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.
+
+@cindexgawkfunc{dcgettext}
+@item @code{dcgettext(@var{string}} [@code{,} @var{domain} [@code{,} @var{category}]]@code{)}
+Return 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.
+
+@quotation 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.
+@end quotation
+
+@cindexgawkfunc{dcngettext}
+@item @code{dcngettext(@var{string1}, @var{string2}, @var{number}} [@code{,} @var{domain} [@code{,} @var{category}]]@code{)}
+Return 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} is 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 about argument order as for the @code{dcgettext()} function apply.
+
+@cindex @code{.gmo} files, specifying directory of
+@cindex files, @code{.gmo}, specifying directory of
+@cindex message object files, specifying directory of
+@cindex files, message object, specifying directory of
+@cindexgawkfunc{bindtextdomain}
+@item @code{bindtextdomain(@var{directory}} [@code{,} @var{domain} ]@code{)}
+Change the directory in which
+@command{gettext} looks for @file{.gmo} files, in case they
+will not or cannot be placed in the standard locations
+(e.g., during testing).
+Return 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:@footnote{Thanks to Bruno Haible for this
+example.}
+
+@example
+if (groggy)
+ message = dcgettext("%d customers disturbing me\n", "adminprog")
+else
+ message = dcgettext("enjoying %d customers\n", "adminprog")
+printf(message, ncustomers)
+@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.
+
+The previous example only works if @code{ncustomers} is greater than one.
+This example would be better done with @code{dcngettext()}:
+
+@example
+if (groggy)
+ message = dcngettext("%d customer disturbing me\n",
+ "%d customers disturbing me\n", "adminprog")
+else
+ message = dcngettext("enjoying %d customer\n",
+ "enjoying %d customers\n", "adminprog")
+printf(message, ncustomers)
+@end example
+
+
+@cindex @code{LC_MESSAGES} locale category, @code{bindtextdomain()} function (@command{gawk})
+@item
+During development, you might want to put the @file{.gmo}
+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
+
+@DBXREF{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{.pot} 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-pot} 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 @option{--gen-pot} option
+@cindex command-line options, string extraction
+@cindex string extraction (internationalization)
+@cindex marked string extraction (internationalization)
+@cindex extraction, of marked strings (internationalization)
+
+@cindex @option{--gen-pot} 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-pot} command-line option to create
+the initial @file{.pot} file:
+
+@example
+gawk --gen-pot -f guide.awk > guide.pot
+@end example
+
+@cindex @code{xgettext} utility
+When run with @option{--gen-pot}, @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 @command{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{The
+@command{xgettext} utility that comes with GNU
+@command{gettext} can handle @file{.awk} files.}
+You should distribute the generated @file{.pot} file with
+your @command{awk} program; translators will eventually use it
+to provide you translations that you can also then distribute.
+@DBXREF{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, @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 @command{gettext} manual.}
+
+@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 specifiers 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
+$ @kbd{gawk 'BEGIN @{}
+> @kbd{string = "Don\47t Panic"}
+> @kbd{printf "%2$d characters live in \"%1$s\"\n",}
+> @kbd{string, length(string)}
+> @kbd{@}'}
+@print{} 11 characters live in "Don't 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
+$ @kbd{gawk 'BEGIN @{}
+> @kbd{printf("%*.*s\n", 10, 20, "hello")}
+> @kbd{printf("%3$*2$.*1$s\n", 20, 10, "hello")}
+> @kbd{@}'}
+@print{} hello
+@print{} hello
+@end example
+
+@quotation NOTE
+When using @samp{*} with a positional specifier, the @samp{*}
+comes first, then the integer position, and then the @samp{$}.
+This is somewhat counterintuitive.
+@end quotation
+
+@cindex @code{printf} statement, positional specifiers, mixing with regular formats
+@cindex positional specifiers, @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:
+
+@example
+$ @kbd{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 example
+
+@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 @value{BULLET}
+@cindex @code{TEXTDOMAIN} variable, portability and
+@item
+Assignments to @code{TEXTDOMAIN} won't have any effect,
+because @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, because the positional specifications are primarily for use in
+@emph{translated} format strings, and because non-GNU @command{awk}s never
+retrieve the translated string, this should not be a problem in practice.
+@end itemize
+
+@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-pot} to create the @file{.pot} file:
+
+@example
+$ @kbd{gawk --gen-pot -f guide.awk > guide.pot}
+@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 template 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.pot} 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
+$ @kbd{cp guide.pot 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.
+We pretend that our file is to be used in the @code{en_US.UTF-8} locale,
+because we have to use a locale name known to the C @command{gettext} routines.
+The directory layout shown here is standard for GNU @command{gettext} on
+GNU/Linux systems. Other versions of @command{gettext} may use a different
+layout:
+
+@example
+$ @kbd{mkdir en_US.UTF-8 en_US.UTF-8/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 (using
+the @option{-o} option) so that @command{gawk} can find it:
+
+@example
+$ @kbd{msgfmt guide-mellow.po -o en_US.UTF-8/LC_MESSAGES/guide.mo}
+@end example
+
+Finally, we run the program to test it:
+
+@example
+$ @kbd{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
+$ @kbd{gawk --posix -f guide.awk -f libintl.awk}
+@print{} Don't Panic
+@print{} The Answer Is 42
+@print{} Pardon me, Zaphod who?
+@end example
+
+@node Gawk I18N
+@section @command{gawk} Can Speak Your Language
+
+@command{gawk} itself has been internationalized
+using the GNU @command{gettext} package.
+(GNU @command{gettext} is described in
+complete detail in
+@ifinfo
+@inforef{Top, , GNU @command{gettext} utilities, gettext, GNU gettext tools}.)
+@end ifinfo
+@ifnotinfo
+@uref{http://www.gnu.org/software/gettext/manual/,
+@cite{GNU gettext tools}}.)
+@end ifnotinfo
+As of this writing, the latest version of GNU @command{gettext} is
+@uref{ftp://ftp.gnu.org/gnu/gettext/gettext-0.19.4.tar.gz,
+@value{PVERSION} 0.19.4}.
+
+If a translation of @command{gawk}'s messages exists,
+then @command{gawk} produces usage messages, warnings,
+and fatal errors in the local language.
+
+@node I18N Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+Internationalization means writing a program such that it can use multiple
+languages without requiring source-code changes. Localization means
+providing the data necessary for an internationalized program to work
+in a particular language.
+
+@item
+@command{gawk} uses GNU @command{gettext} to let you internationalize
+and localize @command{awk} programs. A program's text domain identifies
+the program for grouping all messages and other data together.
+
+@item
+You mark a program's strings for translation by preceding them with
+an underscore. Once that is done, the strings are extracted into a
+@file{.pot} file. This file is copied for each language into a @file{.po}
+file, and the @file{.po} files are compiled into @file{.gmo} files for
+use at runtime.
+
+@item
+You can use position specifications with @code{sprintf()} and
+@code{printf} to rearrange the placement of argument values in formatted
+strings and output. This is useful for the translations of format
+control strings.
+
+@item
+The internationalization features have been designed so that they
+can be easily worked around in a standard @command{awk}.
+
+@item
+@command{gawk} itself has been internationalized and ships with
+a number of translations for its messages.
+
+@end itemize
+
@node Debugger
-@chapter @command{dgawk}: The @command{awk} Debugger
-@cindex @command{dgawk}
+@chapter Debugging @command{awk} Programs
+@cindex debugging @command{awk} programs
+
+@c The original text for this chapter was contributed by Efraim Yawitz.
+@c FIXME: Add more indexing.
It would be nice if computer programs worked perfectly the first time they
were run, but in real life, this rarely happens for programs of
any complexity. Thus, most programming languages have facilities available
for ``debugging'' programs, and now @command{awk} is no exception.
-The @command{dgawk} debugger is purposely modeled after
+The @command{gawk} debugger is purposely modeled after
@uref{http://www.gnu.org/software/gdb/, the GNU Debugger (GDB)}
command-line debugger. If you are familiar with GDB, learning
-@command{dgawk} is easy.
+how to use @command{gawk} for debugging your program is easy.
@menu
-* Debugging:: Introduction to @command{dgawk}.
-* Sample dgawk session:: Sample @command{dgawk} session.
-* List of Debugger Commands:: Main @command{dgawk} Commands.
-* Readline Support:: Readline Support.
-* Dgawk Limitations:: Limitations and future plans.
+* Debugging:: Introduction to @command{gawk} debugger.
+* Sample Debugging Session:: Sample debugging session.
+* List of Debugger Commands:: Main debugger commands.
+* Readline Support:: Readline support.
+* Limitations:: Limitations and future plans.
+* Debugging Summary:: Debugging summary.
@end menu
@node Debugging
-@section Introduction to @command{dgawk}
+@section Introduction to the @command{gawk} Debugger
This @value{SECTION} introduces debugging in general and begins
the discussion of debugging in @command{gawk}.
@menu
-* Debugging Concepts:: Debugging In General.
+* Debugging Concepts:: Debugging in General.
* Debugging Terms:: Additional Debugging Concepts.
* Awk Debugging:: Awk Debugging.
@end menu
@node Debugging Concepts
-@subsection Debugging In General
+@subsection Debugging in General
(If you have used debuggers in other languages, you may want to skip
-ahead to the next section on the specific features of the @command{awk}
+ahead to the next section on the specific features of the @command{gawk}
debugger.)
-Of course, a debugging program cannot remove bugs for you, since it has
-no way of knowing what you or your users consider a ``bug'' and what is a
+Of course, a debugging program cannot remove bugs for you, because it has
+no way of knowing what you or your users consider a ``bug'' versus a
``feature.'' (Sometimes, we humans have a hard time with this ourselves.)
In that case, what can you expect from such a tool? The answer to that
depends on the language being debugged, but in general, you can expect at
least the following:
-@itemize @bullet
+@itemize @value{BULLET}
@item
The ability to watch a program execute its instructions one by one,
giving you, the programmer, the opportunity to think about what is happening
@@ -25215,7 +28802,7 @@ having to change your source files.
@item
The chance to see the values of data in the program at any point in
execution, and also to change that data on the fly, to see how that
-affects what happens afterwards. (This often includes the ability
+affects what happens afterward. (This often includes the ability
to look at internal data structures besides the variables you actually
defined in your code.)
@@ -25230,16 +28817,16 @@ is going wrong (or, for that matter, to better comprehend a perfectly
functional program that you or someone else wrote).
@node Debugging Terms
-@subsection Additional Debugging Concepts
+@subsection Debugging Concepts
Before diving in to the details, we need to introduce several
-important concepts that apply to just about all debuggers, including
-@command{dgawk}.
+important concepts that apply to just about all debuggers.
The following list defines terms used throughout the rest of
-this @value{CHAPTER}.
+this @value{CHAPTER}:
@table @dfn
-@item Stack Frame
+@cindex stack frame
+@item Stack frame
Programs generally call functions during the course of their execution.
One function can call another, or a function can call itself (recursion).
You can view the chain of called functions (main program calls A, which
@@ -25253,13 +28840,14 @@ that contains the function's parameters, local variables, and return value,
as well as any other ``bookkeeping'' information needed to manage the
call stack. This data area is termed a @dfn{stack frame}.
-@command{gawk} also follows this model, and @command{dgawk} gives you
+@command{gawk} also follows this model, and gives you
access to the call stack and to each stack frame. You can see the
call stack, as well as from where each function on the stack was
invoked. Commands that print the call stack print information about
each stack frame (as detailed later on).
@item Breakpoint
+@cindex breakpoint
During debugging, you often wish to let the program run until it
reaches a certain point, and then continue execution from there one
statement (or instruction) at a time. The way to do this is to set
@@ -25269,10 +28857,11 @@ take over control of the program's execution. You can add and remove
as many breakpoints as you like.
@item Watchpoint
+@cindex watchpoint
A watchpoint is similar to a breakpoint. The difference is that
breakpoints are oriented around the code: stop when a certain point in the
code is reached. A watchpoint, however, specifies that program execution
-should stop when a @emph{data value} is changed. This is useful, since
+should stop when a @emph{data value} is changed. This is useful, as
sometimes it happens that a variable receives an erroneous value, and it's
hard to track down where this happens just by looking at the code.
By using a watchpoint, you can stop whenever a variable is assigned to,
@@ -25286,60 +28875,65 @@ Debugging an @command{awk} program has some specific aspects that are
not shared with other programming languages.
First of all, the fact that @command{awk} programs usually take input
-line-by-line from a file or files and operate on those lines using specific
+line by line from a file or files and operate on those lines using specific
rules makes it especially useful to organize viewing the execution of
the program in terms of these rules. As we will see, each @command{awk}
rule is treated almost like a function call, with its own specific block
of instructions.
-In addition, since @command{awk} is by design a very concise language,
+In addition, because @command{awk} is by design a very concise language,
it is easy to lose sight of everything that is going on ``inside''
each line of @command{awk} code. The debugger provides the opportunity
to look at the individual primitive instructions carried out
by the higher-level @command{awk} commands.
-@node Sample dgawk session
-@section Sample @command{dgawk} session
+@node Sample Debugging Session
+@section Sample Debugging Session
+@cindex sample debugging session
-In order to illustrate the use of @command{dgawk}, let's look at a sample
+In order to illustrate the use of @command{gawk} as a debugger, let's look at a sample
debugging session. We will use the @command{awk} implementation of the
POSIX @command{uniq} command described earlier (@pxref{Uniq Program})
as our example.
@menu
-* dgawk invocation:: @command{dgawk} Invocation.
-* Finding The Bug:: Finding The Bug.
+* Debugger Invocation:: How to Start the Debugger.
+* Finding The Bug:: Finding the Bug.
@end menu
-@node dgawk invocation
-@subsection @command{dgawk} Invocation
+@node Debugger Invocation
+@subsection How to Start the Debugger
+@cindex starting the debugger
+@cindex debugger, how to start
-Starting @command{dgawk} is exactly like running @command{awk}. The
-file(s) containing the program and any supporting code are given on the
-command line as arguments to one or more @option{-f} options.
-(@command{dgawk} is not designed to debug command-line
-programs, only programs contained in files.) In our case,
-we call @command{dgawk} like this:
+Starting the debugger is almost exactly like running @command{gawk} normally,
+except you have to pass an additional option @option{--debug}, or the
+corresponding short option @option{-D}. The file(s) containing the
+program and any supporting code are given on the command line as arguments
+to one or more @option{-f} options. (@command{gawk} is not designed
+to debug command-line programs, only programs contained in files.)
+In our case, we invoke the debugger like this:
@example
-$ @kbd{dgawk -f getopt.awk -f join.awk -f uniq.awk inputfile}
+$ @kbd{gawk -D -f getopt.awk -f join.awk -f uniq.awk -1 inputfile}
@end example
@noindent
where both @file{getopt.awk} and @file{uniq.awk} are in @env{$AWKPATH}.
(Experienced users of GDB or similar debuggers should note that
this syntax is slightly different from what they are used to.
-With @command{dgawk}, the arguments for running the program are given
+With the @command{gawk} debugger, you give the arguments for running the program
in the command line to the debugger rather than as part of the @code{run}
command at the debugger prompt.)
+The @option{-1} is an option to @file{uniq.awk}.
Instead of immediately running the program on @file{inputfile}, as
-@command{gawk} would ordinarily do, @command{dgawk} merely loads all
+@command{gawk} would ordinarily do, the debugger merely loads all
the program source files, compiles them internally, and then gives
us a prompt:
@example
-dgawk>
+gawk>
@end example
@noindent
@@ -25347,7 +28941,7 @@ from which we can issue commands to the debugger. At this point, no
code has been executed.
@node Finding The Bug
-@subsection Finding The Bug
+@subsection Finding the Bug
Let's say that we are having a problem using (a faulty version of)
@file{uniq.awk} in the ``field-skipping'' mode, and it doesn't seem to be
@@ -25383,8 +28977,8 @@ a breakpoint in @file{uniq.awk} is at the beginning of the function
the breakpoint, use the @code{b} (breakpoint) command:
@example
-dgawk> @kbd{b are_equal}
-@print{} Breakpoint 1 set at file `awklib/eg/prog/uniq.awk', line 64
+gawk> @kbd{b are_equal}
+@print{} Breakpoint 1 set at file `awklib/eg/prog/uniq.awk', line 63
@end example
The debugger tells us the file and line number where the breakpoint is.
@@ -25392,29 +28986,29 @@ Now type @samp{r} or @samp{run} and the program runs until it hits
the breakpoint for the first time:
@example
-dgawk> @kbd{r}
+gawk> @kbd{r}
@print{} Starting program:
@print{} Stopping in Rule ...
@print{} Breakpoint 1, are_equal(n, m, clast, cline, alast, aline)
- at `awklib/eg/prog/uniq.awk':64
-@print{} 64 if (fcount == 0 && charcount == 0)
-dgawk>
+ at `awklib/eg/prog/uniq.awk':63
+@print{} 63 if (fcount == 0 && charcount == 0)
+gawk>
@end example
Now we can look at what's going on inside our program. First of all,
let's see how we got to where we are. At the prompt, we type @samp{bt}
-(short for ``backtrace''), and @command{dgawk} responds with a
+(short for ``backtrace''), and the debugger responds with a
listing of the current stack frames:
@example
-dgawk> @kbd{bt}
+gawk> @kbd{bt}
@print{} #0 are_equal(n, m, clast, cline, alast, aline)
- at `awklib/eg/prog/uniq.awk':69
-@print{} #1 in main() at `awklib/eg/prog/uniq.awk':89
+ at `awklib/eg/prog/uniq.awk':68
+@print{} #1 in main() at `awklib/eg/prog/uniq.awk':88
@end example
This tells us that @code{are_equal()} was called by the main program at
-line 89 of @file{uniq.awk}. (This is not a big surprise, since this
+line 88 of @file{uniq.awk}. (This is not a big surprise, because this
is the only call to @code{are_equal()} in the program, but in more complex
programs, knowing who called a function and with what parameters can be
the key to finding the source of the problem.)
@@ -25422,37 +29016,37 @@ the key to finding the source of the problem.)
Now that we're in @code{are_equal()}, we can start looking at the values
of some variables. Let's say we type @samp{p n}
(@code{p} is short for ``print''). We would expect to see the value of
-@code{n}, a parameter to @code{are_equal()}. Actually, @command{dgawk}
+@code{n}, a parameter to @code{are_equal()}. Actually, the debugger
gives us:
@example
-dgawk> @kbd{p n}
+gawk> @kbd{p n}
@print{} n = untyped variable
@end example
@noindent
-In this case, @code{n} is an uninitialized local variable, since the
+In this case, @code{n} is an uninitialized local variable, because the
function was called without arguments (@pxref{Function Calls}).
A more useful variable to display might be the current record:
@example
-dgawk> @kbd{p $0}
-@print{} $0 = string ("gawk is a wonderful program!")
+gawk> @kbd{p $0}
+@print{} $0 = "gawk is a wonderful program!"
@end example
@noindent
-This might be a bit puzzling at first since this is the second line of
-our test input above. Let's look at @code{NR}:
+This might be a bit puzzling at first, as this is the second line of
+our test input. Let's look at @code{NR}:
@example
-dgawk> @kbd{p NR}
-@print{} NR = number (2)
+gawk> @kbd{p NR}
+@print{} NR = 2
@end example
@noindent
So we can see that @code{are_equal()} was only called for the second record
-of the file. Of course, this is because our program contained a rule for
+of the file. Of course, this is because our program contains a rule for
@samp{NR == 1}:
@example
@@ -25465,8 +29059,8 @@ NR == 1 @{
OK, let's just check that that rule worked correctly:
@example
-dgawk> @kbd{p last}
-@print{} last = string ("awk is a wonderful program!")
+gawk> @kbd{p last}
+@print{} last = "awk is a wonderful program!"
@end example
Everything we have done so far has verified that the program has worked as
@@ -25476,41 +29070,35 @@ be inside this function. To investigate further, we must begin
@samp{n} (for ``next''):
@example
-dgawk> @kbd{n}
-@print{} 67 if (fcount > 0) @{
+gawk> @kbd{n}
+@print{} 66 if (fcount > 0) @{
@end example
-This tells us that @command{gawk} is now ready to execute line 67, which
+This tells us that @command{gawk} is now ready to execute line 66, which
decides whether to give the lines the special ``field skipping'' treatment
-indicated by the @option{-f} command-line option. (Notice that we skipped
-from where we were before at line 64 to here, since the condition in line 64
-
-@example
-if (fcount == 0 && charcount == 0)
-@end example
-
-@noindent
-was false.)
+indicated by the @option{-1} command-line option. (Notice that we skipped
+from where we were before at line 63 to here, because the condition in line 63
+@samp{if (fcount == 0 && charcount == 0)} was false.)
Continuing to step, we now get to the splitting of the current and
last records:
@example
-dgawk> @kbd{n}
-@print{} 68 n = split(last, alast)
-dgawk> @kbd{n}
-@print{} 69 m = split($0, aline)
+gawk> @kbd{n}
+@print{} 67 n = split(last, alast)
+gawk> @kbd{n}
+@print{} 68 m = split($0, aline)
@end example
At this point, we should be curious to see what our records were split
into, so we try to look:
@example
-dgawk> @kbd{p n m alast aline}
-@print{} n = number (5)
-@print{} m = number (5)
+gawk> @kbd{p n m alast aline}
+@print{} n = 5
+@print{} m = untyped variable
@print{} alast = array, 5 elements
-@print{} aline = array, 5 elements
+@print{} aline = untyped variable
@end example
@noindent
@@ -25518,14 +29106,16 @@ dgawk> @kbd{p n m alast aline}
@command{awk}'s @code{print} statement.)
This is kind of disappointing, though. All we found out is that there
-are five elements in each of our arrays. Useful enough (we now know that
+are five elements in @code{alast}; @code{m} and @code{aline} don't have
+values because we are at line 68 but haven't executed it yet.
+This information is useful enough (we now know that
none of the words were accidentally left out), but what if we want to see
inside the array?
The first choice would be to use subscripts:
@example
-dgawk> @kbd{p alast[0]}
+gawk> @kbd{p alast[0]}
@print{} "0" not in array `alast'
@end example
@@ -25533,31 +29123,31 @@ dgawk> @kbd{p alast[0]}
Oops!
@example
-dgawk> @kbd{p alast[1]}
-@print{} alast["1"] = string ("awk")
+gawk> @kbd{p alast[1]}
+@print{} alast["1"] = "awk"
@end example
This would be kind of slow for a 100-member array, though, so
-@command{dgawk} provides a shortcut (reminiscent of another language
+@command{gawk} provides a shortcut (reminiscent of another language
not to be mentioned):
@example
-dgawk> @kbd{p @@alast}
-@print{} alast["1"] = string ("awk")
-@print{} alast["2"] = string ("is")
-@print{} alast["3"] = string ("a")
-@print{} alast["4"] = string ("wonderful")
-@print{} alast["5"] = string ("program!")
+gawk> @kbd{p @@alast}
+@print{} alast["1"] = "awk"
+@print{} alast["2"] = "is"
+@print{} alast["3"] = "a"
+@print{} alast["4"] = "wonderful"
+@print{} alast["5"] = "program!"
@end example
It looks like we got this far OK. Let's take another step
or two:
@example
-dgawk> @kbd{n}
-@print{} 70 clast = join(alast, fcount, n)
-dgawk> @kbd{n}
-@print{} 71 cline = join(aline, fcount, m)
+gawk> @kbd{n}
+@print{} 69 clast = join(alast, fcount, n)
+gawk> @kbd{n}
+@print{} 70 cline = join(aline, fcount, m)
@end example
Well, here we are at our error (sorry to spoil the suspense). What we
@@ -25566,19 +29156,19 @@ the virtual record to compare, and if the first field was numbered zero,
this would work. Let's look at what we've got:
@example
-dgawk> @kbd{p cline clast}
-@print{} cline = string ("gawk is a wonderful program!")
-@print{} clast = string ("awk is a wonderful program!")
+gawk> @kbd{p cline clast}
+@print{} cline = "gawk is a wonderful program!"
+@print{} clast = "awk is a wonderful program!"
@end example
Hey, those look pretty familiar! They're just our original, unaltered,
input records. A little thinking (the human brain is still the best
debugging tool), and we realize that we were off by one!
-We get out of @command{dgawk}:
+We get out of the debugger:
@example
-dgawk> @kbd{q}
+gawk> @kbd{q}
@print{} The program is running. Exit anyway (y/n)? @kbd{y}
@end example
@@ -25594,12 +29184,12 @@ cline = join(aline, fcount+1, m)
and problem solved!
@node List of Debugger Commands
-@section Main @command{dgawk} Commands
+@section Main Debugger Commands
-The @command{dgawk} command set can be divided into the
+The @command{gawk} debugger command set can be divided into the
following categories:
-@itemize @bullet{}
+@itemize @value{BULLET}
@item
Breakpoint control
@@ -25623,28 +29213,29 @@ Miscellaneous
Each of these are discussed in the following subsections.
In the following descriptions, commands which may be abbreviated
show the abbreviation on a second description line.
-A @command{dgawk} command name may also be truncated if that partial
-name is unambiguous. @command{dgawk} has the built-in capability to
-automatically repeat the previous command when just hitting @key{Enter}.
-This works for the commands @code{list}, @code{next}, @code{nexti}, @code{step}, @code{stepi}
-and @code{continue} executed without any argument.
+A debugger command name may also be truncated if that partial
+name is unambiguous. The debugger has the built-in capability to
+automatically repeat the previous command just by hitting @key{Enter}.
+This works for the commands @code{list}, @code{next}, @code{nexti},
+@code{step}, @code{stepi}, and @code{continue} executed without any
+argument.
@menu
-* Breakpoint Control:: Control of breakpoints.
-* Dgawk Execution Control:: Control of execution.
-* Viewing And Changing Data:: Viewing and changing data.
-* Dgawk Stack:: Dealing with the stack.
-* Dgawk Info:: Obtaining information about the program and
- the debugger state.
-* Miscellaneous Dgawk Commands:: Miscellaneous Commands.
+* Breakpoint Control:: Control of Breakpoints.
+* Debugger Execution Control:: Control of Execution.
+* Viewing And Changing Data:: Viewing and Changing Data.
+* Execution Stack:: Dealing with the Stack.
+* Debugger Info:: Obtaining Information about the Program and
+ the Debugger State.
+* Miscellaneous Debugger Commands:: Miscellaneous Commands.
@end menu
@node Breakpoint Control
-@subsection Control Of Breakpoints
+@subsection Control of Breakpoints
-As we saw above, the first thing you probably want to do in a debugging
-session is to get your breakpoints set up, since otherwise your program
-will just run as if it was not under the debugger. The commands for
+As we saw earlier, the first thing you probably want to do in a debugging
+session is to get your breakpoints set up, because your program
+will otherwise just run as if it was not under the debugger. The commands for
controlling breakpoints are:
@table @asis
@@ -25652,21 +29243,24 @@ controlling breakpoints are:
@cindex debugger commands, @code{break}
@cindex @code{break} debugger command
@cindex @code{b} debugger command (alias for @code{break})
+@cindex set breakpoint
+@cindex breakpoint, setting
@item @code{break} [[@var{filename}@code{:}]@var{n} | @var{function}] [@code{"@var{expression}"}]
@itemx @code{b} [[@var{filename}@code{:}]@var{n} | @var{function}] [@code{"@var{expression}"}]
Without any argument, set a breakpoint at the next instruction
to be executed in the selected stack frame.
Arguments can be one of the following:
+@c @asis for docbook
@c nested table
-@table @var
-@item n
+@table @asis
+@item @var{n}
Set a breakpoint at line number @var{n} in the current source file.
-@item filename@code{:}n
+@item @var{filename}@code{:}@var{n}
Set a breakpoint at line number @var{n} in source file @var{filename}.
-@item function
+@item @var{function}
Set a breakpoint at entry to (the first instruction of)
function @var{function}.
@end table
@@ -25675,13 +29269,15 @@ Each breakpoint is assigned a number which can be used to delete it from
the breakpoint list using the @code{delete} command.
With a breakpoint, you may also supply a condition. This is an
-@command{awk} expression (enclosed in double quotes) that @command{dgawk}
+@command{awk} expression (enclosed in double quotes) that the debugger
evaluates whenever the breakpoint is reached. If the condition is true,
-then @command{dgawk} stops execution and prompts for a command. Otherwise,
-@command{dgawk} continues executing the program.
+then the debugger stops execution and prompts for a command. Otherwise,
+it continues executing the program.
@cindex debugger commands, @code{clear}
@cindex @code{clear} debugger command
+@cindex delete breakpoint at location
+@cindex breakpoint at location, how to delete
@item @code{clear} [[@var{filename}@code{:}]@var{n} | @var{function}]
Without any argument, delete any breakpoint at the next instruction
to be executed in the selected stack frame. If the program stops at
@@ -25689,32 +29285,36 @@ a breakpoint, this deletes that breakpoint so that the program
does not stop at that location again. Arguments can be one of the following:
@c nested table
-@table @var
-@item n
+@table @asis
+@item @var{n}
Delete breakpoint(s) set at line number @var{n} in the current source file.
-@item filename@code{:}n
+@item @var{filename}@code{:}@var{n}
Delete breakpoint(s) set at line number @var{n} in source file @var{filename}.
-@item function
+@item @var{function}
Delete breakpoint(s) set at entry to function @var{function}.
@end table
@cindex debugger commands, @code{condition}
@cindex @code{condition} debugger command
+@cindex breakpoint condition
@item @code{condition} @var{n} @code{"@var{expression}"}
Add a condition to existing breakpoint or watchpoint @var{n}. The
-condition is an @command{awk} expression that @command{dgawk} evaluates
+condition is an @command{awk} expression @emph{enclosed in double quotes}
+that the debugger evaluates
whenever the breakpoint or watchpoint is reached. If the condition is true, then
-@command{dgawk} stops execution and prompts for a command. Otherwise,
-@command{dgawk} continues executing the program. If the condition expression is
-not specified, any existing condition is removed; i.e., the breakpoint or
-watchpoint is made unconditional.
+the debugger stops execution and prompts for a command. Otherwise,
+the debugger continues executing the program. If the condition expression is
+not specified, any existing condition is removed (i.e., the breakpoint or
+watchpoint is made unconditional).
@cindex debugger commands, @code{d} (@code{delete})
@cindex debugger commands, @code{delete}
@cindex @code{delete} debugger command
@cindex @code{d} debugger command (alias for @code{delete})
+@cindex delete breakpoint by number
+@cindex breakpoint, delete by number
@item @code{delete} [@var{n1 n2} @dots{}] [@var{n}--@var{m}]
@itemx @code{d} [@var{n1 n2} @dots{}] [@var{n}--@var{m}]
Delete specified breakpoints or a range of breakpoints. Deletes
@@ -25722,6 +29322,8 @@ all defined breakpoints if no argument is supplied.
@cindex debugger commands, @code{disable}
@cindex @code{disable} debugger command
+@cindex disable breakpoint
+@cindex breakpoint, how to disable or enable
@item @code{disable} [@var{n1 n2} @dots{} | @var{n}--@var{m}]
Disable specified breakpoints or a range of breakpoints. Without
any argument, disables all breakpoints.
@@ -25730,6 +29332,7 @@ any argument, disables all breakpoints.
@cindex debugger commands, @code{enable}
@cindex @code{enable} debugger command
@cindex @code{e} debugger command (alias for @code{enable})
+@cindex enable breakpoint
@item @code{enable} [@code{del} | @code{once}] [@var{n1 n2} @dots{}] [@var{n}--@var{m}]
@itemx @code{e} [@code{del} | @code{once}] [@var{n1 n2} @dots{}] [@var{n}--@var{m}]
Enable specified breakpoints or a range of breakpoints. Without
@@ -25749,6 +29352,7 @@ the program stops at the breakpoint.
@cindex debugger commands, @code{ignore}
@cindex @code{ignore} debugger command
+@cindex ignore breakpoint
@item @code{ignore} @var{n} @var{count}
Ignore breakpoint number @var{n} the next @var{count} times it is
hit.
@@ -25757,13 +29361,14 @@ hit.
@cindex debugger commands, @code{tbreak}
@cindex @code{tbreak} debugger command
@cindex @code{t} debugger command (alias for @code{tbreak})
+@cindex temporary breakpoint
@item @code{tbreak} [[@var{filename}@code{:}]@var{n} | @var{function}]
@itemx @code{t} [[@var{filename}@code{:}]@var{n} | @var{function}]
Set a temporary breakpoint (enabled for only one stop).
The arguments are the same as for @code{break}.
@end table
-@node Dgawk Execution Control
+@node Debugger Execution Control
@subsection Control of Execution
Now that your breakpoints are ready, you can start running the program
@@ -25777,6 +29382,8 @@ execution of the program than we saw in our earlier example:
@cindex @code{silent} debugger command
@cindex debugger commands, @code{end}
@cindex @code{end} debugger command
+@cindex breakpoint commands
+@cindex commands to execute at breakpoint
@item @code{commands} [@var{n}]
@itemx @code{silent}
@itemx @dots{}
@@ -25792,18 +29399,19 @@ in the list that resumes execution (e.g., @code{continue}) terminates the list
For example:
@example
-dgawk> @kbd{commands}
+gawk> @kbd{commands}
> @kbd{silent}
> @kbd{printf "A silent breakpoint; i = %d\n", i}
> @kbd{info locals}
> @kbd{set i = 10}
> @kbd{continue}
> @kbd{end}
-dgawk>
+gawk>
@end example
@cindex debugger commands, @code{c} (@code{continue})
@cindex debugger commands, @code{continue}
+@cindex continue program, in debugger
@item @code{continue} [@var{count}]
@itemx @code{c} [@var{count}]
Resume program execution. If continued from a breakpoint and @var{count} is
@@ -25820,6 +29428,7 @@ Print the returned value.
@cindex debugger commands, @code{next}
@cindex @code{next} debugger command
@cindex @code{n} debugger command (alias for @code{next})
+@cindex single-step execution, in the debugger
@item @code{next} [@var{count}]
@itemx @code{n} [@var{count}]
Continue execution to the next source line, stepping over function calls.
@@ -25839,7 +29448,7 @@ Execute one (or @var{count}) instruction(s), stepping over function calls.
@item @code{return} [@var{value}]
Cancel execution of a function call. If @var{value} (either a string or a
number) is specified, it is used as the function's return value. If used in a
-frame other than the innermost one (the currently executing function, i.e.,
+frame other than the innermost one (the currently executing function; i.e.,
frame number 0), discard all inner frames in addition to the selected one,
and the caller of that frame becomes the innermost frame.
@@ -25849,7 +29458,7 @@ and the caller of that frame becomes the innermost frame.
@cindex @code{r} debugger command (alias for @code{run})
@item @code{run}
@itemx @code{r}
-Start/restart execution of the program. When restarting, @command{dgawk}
+Start/restart execution of the program. When restarting, the debugger
retains the current breakpoints, watchpoints, command history,
automatic display variables, and debugger options.
@@ -25872,7 +29481,7 @@ stopping, unless it encounters a breakpoint or watchpoint.
@itemx @code{si} [@var{count}]
Execute one (or @var{count}) instruction(s), stepping inside function calls.
(For illustration of what is meant by an ``instruction'' in @command{gawk},
-see the output shown under @code{dump} in @ref{Miscellaneous Dgawk Commands}.)
+see the output shown under @code{dump} in @ref{Miscellaneous Debugger Commands}.)
@cindex debugger commands, @code{u} (@code{until})
@cindex debugger commands, @code{until}
@@ -25881,7 +29490,7 @@ see the output shown under @code{dump} in @ref{Miscellaneous Dgawk Commands}.)
@item @code{until} [[@var{filename}@code{:}]@var{n} | @var{function}]
@itemx @code{u} [[@var{filename}@code{:}]@var{n} | @var{function}]
Without any argument, continue execution until a line past the current
-line in current stack frame is reached. With an argument,
+line in the current stack frame is reached. With an argument,
continue execution until the specified location is reached, or the current
stack frame returns.
@end table
@@ -25900,12 +29509,12 @@ The value of the variable or field is displayed each time the program stops.
Each variable added to the list is identified by a unique number:
@example
-dgawk> @kbd{display x}
+gawk> @kbd{display x}
@print{} 10: x = 1
@end example
@noindent
-displays the assigned item number, the variable name and its current value.
+This displays the assigned item number, the variable name, and its current value.
If the display variable refers to a function parameter, it is silently
deleted from the list as soon as the execution reaches a context where
no such variable of the given name exists.
@@ -25914,6 +29523,7 @@ items on the list.
@cindex debugger commands, @code{eval}
@cindex @code{eval} debugger command
+@cindex evaluate expressions, in debugger
@item @code{eval "@var{awk statements}"}
Evaluate @var{awk statements} in the context of the running program.
You can do anything that an @command{awk} program would do: assign
@@ -25931,19 +29541,20 @@ parameters defined by the program.
@cindex debugger commands, @code{print}
@cindex @code{print} debugger command
@cindex @code{p} debugger command (alias for @code{print})
+@cindex print variables, in debugger
@item @code{print} @var{var1}[@code{,} @var{var2} @dots{}]
@itemx @code{p} @var{var1}[@code{,} @var{var2} @dots{}]
Print the value of a @command{gawk} variable or field.
Fields must be referenced by constants:
@example
-dgawk> @kbd{print $3}
+gawk> @kbd{print $3}
@end example
@noindent
This prints the third field in the input record (if the specified field does not
exist, it prints @samp{Null field}). A variable can be an array element, with
-the subscripts being constant values. To print the contents of an array,
+the subscripts being constant string values. To print the contents of an array,
prefix the name of the array with the @samp{@@} symbol:
@example
@@ -25964,48 +29575,52 @@ No newline is printed unless one is specified.
@cindex debugger commands, @code{set}
@cindex @code{set} debugger command
+@cindex assign values to variables, in debugger
@item @code{set} @var{var}@code{=}@var{value}
Assign a constant (number or string) value to an @command{awk} variable
or field.
-String values must be enclosed between double quotes (@code{"@dots{}"}).
+String values must be enclosed between double quotes (@code{"}@dots{}@code{"}).
You can also set special @command{awk} variables, such as @code{FS},
-@code{NF}, @code{NR}, etc.
+@code{NF}, @code{NR}, and son on.
@cindex debugger commands, @code{w} (@code{watch})
@cindex debugger commands, @code{watch}
@cindex @code{watch} debugger command
@cindex @code{w} debugger command (alias for @code{watch})
+@cindex set watchpoint
@item @code{watch} @var{var} | @code{$}@var{n} [@code{"@var{expression}"}]
@itemx @code{w} @var{var} | @code{$}@var{n} [@code{"@var{expression}"}]
Add variable @var{var} (or field @code{$@var{n}}) to the watch list.
-@command{dgawk} then stops whenever
+The debugger then stops whenever
the value of the variable or field changes. Each watched item is assigned a
number which can be used to delete it from the watch list using the
@code{unwatch} command.
With a watchpoint, you may also supply a condition. This is an
-@command{awk} expression (enclosed in double quotes) that @command{dgawk}
+@command{awk} expression (enclosed in double quotes) that the debugger
evaluates whenever the watchpoint is reached. If the condition is true,
-then @command{dgawk} stops execution and prompts for a command. Otherwise,
-@command{dgawk} continues executing the program.
+then the debugger stops execution and prompts for a command. Otherwise,
+@command{gawk} continues executing the program.
@cindex debugger commands, @code{undisplay}
@cindex @code{undisplay} debugger command
+@cindex stop automatic display, in debugger
@item @code{undisplay} [@var{n}]
Remove item number @var{n} (or all items, if no argument) from the
automatic display list.
@cindex debugger commands, @code{unwatch}
@cindex @code{unwatch} debugger command
+@cindex delete watchpoint
@item @code{unwatch} [@var{n}]
Remove item number @var{n} (or all items, if no argument) from the
watch list.
@end table
-@node Dgawk Stack
-@subsection Dealing With The Stack
+@node Execution Stack
+@subsection Working with the Stack
Whenever you run a program which contains any function calls,
@command{gawk} maintains a stack of all of the function calls leading up
@@ -26016,14 +29631,22 @@ functions which called the one you are in. The commands for doing this are:
@table @asis
@cindex debugger commands, @code{bt} (@code{backtrace})
@cindex debugger commands, @code{backtrace}
+@cindex debugger commands, @code{where} (@code{backtrace})
@cindex @code{backtrace} debugger command
@cindex @code{bt} debugger command (alias for @code{backtrace})
+@cindex @code{where} debugger command
+@cindex @code{where} debugger command (alias for @code{backtrace})
+@cindex call stack, display in debugger
+@cindex traceback, display in debugger
@item @code{backtrace} [@var{count}]
@itemx @code{bt} [@var{count}]
+@itemx @code{where} [@var{count}]
Print a backtrace of all function calls (stack frames), or innermost @var{count}
frames if @var{count} > 0. Print the outermost @var{count} frames if
@var{count} < 0. The backtrace displays the name and arguments to each
function, the source @value{FN}, and the line number.
+The alias @code{where} for @code{backtrace} is provided for longtime
+GDB users who may be used to that command.
@cindex debugger commands, @code{down}
@cindex @code{down} debugger command
@@ -26037,10 +29660,11 @@ Then select and print the frame.
@cindex @code{f} debugger command (alias for @code{frame})
@item @code{frame} [@var{n}]
@itemx @code{f} [@var{n}]
-Select and print (frame number, function and argument names, source file,
-and the source line) stack frame @var{n}. Frame 0 is the currently executing,
-or @dfn{innermost}, frame (function call), frame 1 is the frame that called the
-innermost one. The highest numbered frame is the one for the main program.
+Select and print stack frame @var{n}. Frame 0 is the currently executing,
+or @dfn{innermost}, frame (function call), frame 1 is the frame that
+called the innermost one. The highest numbered frame is the one for the
+main program. The printed information consists of the frame number,
+function and argument names, source file, and the source line.
@cindex debugger commands, @code{up}
@cindex @code{up} debugger command
@@ -26049,12 +29673,12 @@ Move @var{count} (default 1) frames up the stack toward the outermost frame.
Then select and print the frame.
@end table
-@node Dgawk Info
-@subsection Obtaining Information About The Program and The Debugger State
+@node Debugger Info
+@subsection Obtaining Information About the Program and the Debugger State
Besides looking at the values of variables, there is often a need to get
other sorts of information about the state of your program and of the
-debugging environment itself. @command{dgawk} has one command which
+debugging environment itself. The @command{gawk} debugger has one command which
provides this information, appropriately called @code{info}. @code{info}
is used with one of a number of arguments that tell it exactly what
you want to know:
@@ -26071,39 +29695,49 @@ The value for @var{what} should be one of the following:
@c nested table
@table @code
@item args
-Arguments of the selected frame.
+@cindex show function arguments, in debugger
+List arguments of the selected frame.
@item break
+@cindex show breakpoints
List all currently set breakpoints.
@item display
+@cindex automatic displays, in debugger
List all items in the automatic display list.
@item frame
-Description of the selected stack frame.
+@cindex describe call stack frame, in debugger
+Give a description of the selected stack frame.
@item functions
-List all function definitions including source file names and
+@cindex list function definitions, in debugger
+List all function definitions including source @value{FN}s and
line numbers.
@item locals
-Local variables of the selected frame.
+@cindex show local variables, in debugger
+List local variables of the selected frame.
@item source
-The name of the current source file. Each time the program stops, the
+@cindex show name of current source file, in debugger
+Print the name of the current source file. Each time the program stops, the
current source file is the file containing the current instruction.
-When @command{dgawk} first starts, the current source file is the first file
+When the debugger first starts, the current source file is the first file
included via the @option{-f} option. The
@samp{list @var{filename}:@var{lineno}} command can
be used at any time to change the current source.
@item sources
+@cindex show all source files, in debugger
List all program sources.
@item variables
+@cindex list all global variables, in debugger
List all global variables.
@item watch
+@cindex show watchpoints
List all items in the watch list.
@end table
@end table
@@ -26117,6 +29751,8 @@ from a file. The commands are:
@cindex debugger commands, @code{option}
@cindex @code{option} debugger command
@cindex @code{o} debugger command (alias for @code{option})
+@cindex display debugger options
+@cindex debugger options
@item @code{option} [@var{name}[@code{=}@var{value}]]
@itemx @code{o} [@var{name}[@code{=}@var{value}]]
Without an argument, display the available debugger options
@@ -26126,32 +29762,40 @@ a new value to the named option.
The available options are:
@c nested table
-@table @code
-@item history_size
-The maximum number of lines to keep in the history file @file{./.dgawk_history}.
+@c asis for docbook
+@table @asis
+@item @code{history_size}
+@cindex debugger history size
+The maximum number of lines to keep in the history file @file{./.gawk_history}.
The default is 100.
-@item listsize
+@item @code{listsize}
+@cindex debugger default list amount
The number of lines that @code{list} prints. The default is 15.
-@item outfile
+@item @code{outfile}
+@cindex redirect @command{gawk} output, in debugger
Send @command{gawk} output to a file; debugger output still goes
to standard output. An empty string (@code{""}) resets output to
standard output.
-@item prompt
-The debugger prompt. The default is @samp{@w{dgawk> }}.
+@item @code{prompt}
+@cindex debugger prompt
+The debugger prompt. The default is @samp{@w{gawk> }}.
-@item save_history @r{[}on @r{|} off@r{]}
-Save command history to file @file{./.dgawk_history}.
+@item @code{save_history} [@code{on} | @code{off}]
+@cindex debugger history file
+Save command history to file @file{./.gawk_history}.
The default is @code{on}.
-@item save_options @r{[}on @r{|} off@r{]}
-Save current options to file @file{./.dgawkrc} upon exit.
+@item @code{save_options} [@code{on} | @code{off}]
+@cindex save debugger options
+Save current options to file @file{./.gawkrc} upon exit.
The default is @code{on}.
Options are read back in to the next session upon startup.
-@item trace @r{[}on @r{|} off@r{]}
+@item @code{trace} [@code{on} | @code{off}]
+@cindex instruction tracing, in debugger
Turn instruction tracing on or off. The default is @code{off}.
@end table
@@ -26160,6 +29804,7 @@ Save the commands from the current session to the given @value{FN},
so that they can be replayed using the @command{source} command.
@item @code{source} @var{filename}
+@cindex debugger, read commands from a file
Run command(s) from a file; an error in any command does not
terminate execution of subsequent commands. Comments (lines starting
with @samp{#}) are allowed in a command file.
@@ -26167,16 +29812,16 @@ Empty lines are ignored; they do @emph{not}
repeat the last command.
You can't restart the program by having more than one @code{run}
command in the file. Also, the list of commands may include additional
-@code{source} commands; however, @command{dgawk} will not source the
+@code{source} commands; however, the @command{gawk} debugger will not source the
same file more than once in order to avoid infinite recursion.
In addition to, or instead of the @code{source} command, you can use
-the @option{-R @var{file}} or @option{--command=@var{file}} command-line
+the @option{-D @var{file}} or @option{--debug=@var{file}} command-line
options to execute commands from a file non-interactively
-(@pxref{Options}.
+(@pxref{Options}).
@end table
-@node Miscellaneous Dgawk Commands
+@node Miscellaneous Debugger Commands
@subsection Miscellaneous Commands
There are a few more commands which do not fit into the
@@ -26193,57 +29838,56 @@ commands in a program. This can be very enlightening, as the following
partial dump of Davide Brini's obfuscated code
(@pxref{Signature Program}) demonstrates:
+@c FIXME: This will need updating if num-handler branch is ever merged in.
@smallexample
-dgawk> @kbd{dump}
+gawk> @kbd{dump}
@print{} # BEGIN
@print{}
-@print{} [ 2:0x89faef4] Op_rule : [in_rule = BEGIN] [source_file = brini.awk]
-@print{} [ 3:0x89fa428] Op_push_i : "~" [PERM|STRING|STRCUR]
-@print{} [ 3:0x89fa464] Op_push_i : "~" [PERM|STRING|STRCUR]
-@print{} [ 3:0x89fa450] Op_match :
-@print{} [ 3:0x89fa3ec] Op_store_var : O [do_reference = FALSE]
-@print{} [ 4:0x89fa48c] Op_push_i : "==" [PERM|STRING|STRCUR]
-@print{} [ 4:0x89fa4c8] Op_push_i : "==" [PERM|STRING|STRCUR]
-@print{} [ 4:0x89fa4b4] Op_equal :
-@print{} [ 4:0x89fa400] Op_store_var : o [do_reference = FALSE]
-@print{} [ 5:0x89fa4f0] Op_push : o
-@print{} [ 5:0x89fa4dc] Op_plus_i : 0 [PERM|NUMCUR|NUMBER]
-@print{} [ 5:0x89fa414] Op_push_lhs : o [do_reference = TRUE]
-@print{} [ 5:0x89fa4a0] Op_assign_plus :
-@print{} [ :0x89fa478] Op_pop :
-@print{} [ 6:0x89fa540] Op_push : O
-@print{} [ 6:0x89fa554] Op_push_i : "" [PERM|STRING|STRCUR]
-@print{} [ :0x89fa5a4] Op_no_op :
-@print{} [ 6:0x89fa590] Op_push : O
-@print{} [ :0x89fa5b8] Op_concat : [expr_count = 3] [concat_flag = 0]
-@print{} [ 6:0x89fa518] Op_store_var : x [do_reference = FALSE]
-@print{} [ 7:0x89fa504] Op_push_loop : [target_continue = 0x89fa568] [target_break = 0x89fa680]
-@print{} [ 7:0x89fa568] Op_push_lhs : X [do_reference = TRUE]
-@print{} [ 7:0x89fa52c] Op_postincrement :
-@print{} [ 7:0x89fa5e0] Op_push : x
-@print{} [ 7:0x89fa61c] Op_push : o
-@print{} [ 7:0x89fa5f4] Op_plus :
-@print{} [ 7:0x89fa644] Op_push : o
-@print{} [ 7:0x89fa630] Op_plus :
-@print{} [ 7:0x89fa5cc] Op_leq :
-@print{} [ :0x89fa57c] Op_jmp_false : [target_jmp = 0x89fa680]
-@print{} [ 7:0x89fa694] Op_push_i : "%c" [PERM|STRING|STRCUR]
-@print{} [ :0x89fa6d0] Op_no_op :
-@print{} [ 7:0x89fa608] Op_assign_concat : c
-@print{} [ :0x89fa6a8] Op_jmp : [target_jmp = 0x89fa568]
-@print{} [ :0x89fa680] Op_pop_loop :
-@print{}
+@print{} [ 1:0xfcd340] Op_rule : [in_rule = BEGIN] [source_file = brini.awk]
+@print{} [ 1:0xfcc240] Op_push_i : "~" [MALLOC|STRING|STRCUR]
+@print{} [ 1:0xfcc2a0] Op_push_i : "~" [MALLOC|STRING|STRCUR]
+@print{} [ 1:0xfcc280] Op_match :
+@print{} [ 1:0xfcc1e0] Op_store_var : O
+@print{} [ 1:0xfcc2e0] Op_push_i : "==" [MALLOC|STRING|STRCUR]
+@print{} [ 1:0xfcc340] Op_push_i : "==" [MALLOC|STRING|STRCUR]
+@print{} [ 1:0xfcc320] Op_equal :
+@print{} [ 1:0xfcc200] Op_store_var : o
+@print{} [ 1:0xfcc380] Op_push : o
+@print{} [ 1:0xfcc360] Op_plus_i : 0 [MALLOC|NUMCUR|NUMBER]
+@print{} [ 1:0xfcc220] Op_push_lhs : o [do_reference = true]
+@print{} [ 1:0xfcc300] Op_assign_plus :
+@print{} [ :0xfcc2c0] Op_pop :
+@print{} [ 1:0xfcc400] Op_push : O
+@print{} [ 1:0xfcc420] Op_push_i : "" [MALLOC|STRING|STRCUR]
+@print{} [ :0xfcc4a0] Op_no_op :
+@print{} [ 1:0xfcc480] Op_push : O
+@print{} [ :0xfcc4c0] Op_concat : [expr_count = 3] [concat_flag = 0]
+@print{} [ 1:0xfcc3c0] Op_store_var : x
+@print{} [ 1:0xfcc440] Op_push_lhs : X [do_reference = true]
+@print{} [ 1:0xfcc3a0] Op_postincrement :
+@print{} [ 1:0xfcc4e0] Op_push : x
+@print{} [ 1:0xfcc540] Op_push : o
+@print{} [ 1:0xfcc500] Op_plus :
+@print{} [ 1:0xfcc580] Op_push : o
+@print{} [ 1:0xfcc560] Op_plus :
+@print{} [ 1:0xfcc460] Op_leq :
+@print{} [ :0xfcc5c0] Op_jmp_false : [target_jmp = 0xfcc5e0]
+@print{} [ 1:0xfcc600] Op_push_i : "%c" [MALLOC|STRING|STRCUR]
+@print{} [ :0xfcc660] Op_no_op :
+@print{} [ 1:0xfcc520] Op_assign_concat : c
+@print{} [ :0xfcc620] Op_jmp : [target_jmp = 0xfcc440]
+@print{}
@dots{}
-@print{}
-@print{} [ 8:0x89fa658] Op_K_printf : [expr_count = 17] [redir_type = ""]
-@print{} [ :0x89fa374] Op_no_op :
-@print{} [ :0x89fa3d8] Op_atexit :
-@print{} [ :0x89fa6bc] Op_stop :
-@print{} [ :0x89fa39c] Op_no_op :
-@print{} [ :0x89fa3b0] Op_after_beginfile :
-@print{} [ :0x89fa388] Op_no_op :
-@print{} [ :0x89fa3c4] Op_after_endfile :
-dgawk>
+@print{}
+@print{} [ 2:0xfcc5a0] Op_K_printf : [expr_count = 17] [redir_type = ""]
+@print{} [ :0xfcc140] Op_no_op :
+@print{} [ :0xfcc1c0] Op_atexit :
+@print{} [ :0xfcc640] Op_stop :
+@print{} [ :0xfcc180] Op_no_op :
+@print{} [ :0xfcd150] Op_after_beginfile :
+@print{} [ :0xfcc160] Op_no_op :
+@print{} [ :0xfcc1a0] Op_after_endfile :
+gawk>
@end smallexample
@cindex debugger commands, @code{h} (@code{help})
@@ -26252,7 +29896,7 @@ dgawk>
@cindex @code{h} debugger command (alias for @code{help})
@item @code{help}
@itemx @code{h}
-Print a list of all of the @command{dgawk} commands with a short
+Print a list of all of the @command{gawk} debugger commands with a short
summary of their usage. @samp{help @var{command}} prints the information
about the command @var{command}.
@@ -26260,15 +29904,15 @@ about the command @var{command}.
@cindex debugger commands, @code{list}
@cindex @code{list} debugger command
@cindex @code{l} debugger command (alias for @code{list})
-@item @code{list} [@code{-} | @code{+} | @var{n} | @var{filename@code{:}n} | @var{n}--@var{m} | @var{function}]
-@itemx @code{l} [@code{-} | @code{+} | @var{n} | @var{filename@code{:}n} | @var{n}--@var{m} | @var{function}]
+@item @code{list} [@code{-} | @code{+} | @var{n} | @var{filename}@code{:}@var{n} | @var{n}--@var{m} | @var{function}]
+@itemx @code{l} [@code{-} | @code{+} | @var{n} | @var{filename}@code{:}@var{n} | @var{n}--@var{m} | @var{function}]
Print the specified lines (default 15) from the current source file
or the file named @var{filename}. The possible arguments to @code{list}
are as follows:
@c nested table
@table @asis
-@item @code{-}
+@item @code{-} (Minus)
Print lines before the lines last printed.
@item @code{+}
@@ -26281,7 +29925,7 @@ Print lines centered around line number @var{n}.
@item @var{n}--@var{m}
Print lines from @var{n} to @var{m}.
-@item @var{filename@code{:}n}
+@item @var{filename}@code{:}@var{n}
Print lines centered around line number @var{n} in
source file @var{filename}. This command may change the current source file.
@@ -26294,17 +29938,18 @@ function @var{function}. This command may change the current source file.
@cindex debugger commands, @code{quit}
@cindex @code{quit} debugger command
@cindex @code{q} debugger command (alias for @code{quit})
+@cindex exit the debugger
@item @code{quit}
@itemx @code{q}
Exit the debugger. Debugging is great fun, but sometimes we all have
to tend to other obligations in life, and sometimes we find the bug,
-and are free to go on to the next one! As we saw above, if you are
-running a program, @command{dgawk} warns you if you accidentally type
+and are free to go on to the next one! As we saw earlier, if you are
+running a program, the debugger warns you if you accidentally type
@samp{q} or @samp{quit}, to make sure you really want to quit.
@cindex debugger commands, @code{trace}
@cindex @code{trace} debugger command
-@item @code{trace} @code{on} @r{|} @code{off}
+@item @code{trace} [@code{on} | @code{off}]
Turn on or off a continuous printing of instructions which are about to
be executed, along with printing the @command{awk} line which they
implement. The default is @code{off}.
@@ -26317,10 +29962,14 @@ fairly self-explanatory, and using @code{stepi} and @code{nexti} while
@node Readline Support
@section Readline Support
+@cindex command completion, in debugger
+@cindex history expansion, in debugger
-If @command{dgawk} is compiled with the @code{readline} library, you
-can take advantage of that library's command completion and history expansion
-features. The following types of completion are available:
+If @command{gawk} is compiled with
+@uref{http://cnswww.cns.cwru.edu/php/chet/readline/readline.html,
+the @code{readline} library}, you can take advantage of that library's
+command completion and history expansion features. The following types
+of completion are available:
@table @asis
@item Command completion
@@ -26350,29 +29999,32 @@ and
@end table
-@node Dgawk Limitations
-@section Limitations and Future Plans
+@node Limitations
+@section Limitations
-We hope you find @command{dgawk} useful and enjoyable to work with,
+We hope you find the @command{gawk} debugger useful and enjoyable to work with,
but as with any program, especially in its early releases, it still has
some limitations. A few which are worth being aware of are:
-@itemize @bullet{}
+@itemize @value{BULLET}
@item
-At this point, @command{dgawk} does not give a detailed explanation of
+At this point, the debugger does not give a detailed explanation of
what you did wrong when you type in something it doesn't like. Rather, it just
responds @samp{syntax error}. When you do figure out what your mistake was,
though, you'll feel like a real guru.
@item
-If you perused the dump of opcodes in @ref{Miscellaneous Dgawk Commands},
+@c NOTE: no comma after the ref{} on purpose, due to following
+@c parenthetical remark.
+If you perused the dump of opcodes in @ref{Miscellaneous Debugger Commands}
(or if you are already familiar with @command{gawk} internals),
you will realize that much of the internal manipulation of data
in @command{gawk}, as in many interpreters, is done on a stack.
-@code{Op_push}, @code{Op_pop}, etc., are the ``bread and butter'' of
-most @command{gawk} code. Unfortunately, as of now, @command{dgawk}
-does not allow you to examine the stack's contents.
+@code{Op_push}, @code{Op_pop}, and the like, are the ``bread and butter'' of
+most @command{gawk} code.
+Unfortunately, as of now, the @command{gawk}
+debugger does not allow you to examine the stack's contents.
That is, the intermediate results of expression evaluation are on the
stack, but cannot be printed. Rather, only variables which are defined
in the program can be printed. Of course, a workaround for
@@ -26382,78 +30034,5231 @@ change back to obscure, perhaps more optimal code later.
@item
There is no way to look ``inside'' the process of compiling
regular expressions to see if you got it right. As an @command{awk}
-programmer, you are expected to know what @code{/[^[:alnum:][:blank:]]/}
-means.
+programmer, you are expected to know the meaning of
+@code{/[^[:alnum:][:blank:]]/}.
@item
-@command{dgawk} is designed to be used by running a program (with all its
-parameters) on the command line, as described in @ref{dgawk invocation}.
+The @command{gawk} debugger is designed to be used by running a program (with all its
+parameters) on the command line, as described in @ref{Debugger Invocation}.
There is no way (as of now) to attach or ``break in'' to a running program.
This seems reasonable for a language which is used mainly for quickly
executing, short programs.
@item
-@command{dgawk} only accepts source supplied with the @option{-f} option.
+The @command{gawk} debugger only accepts source supplied with the @option{-f} option.
@end itemize
+@ignore
Look forward to a future release when these and other missing features may
be added, and of course feel free to try to add them yourself!
+@end ignore
-@ignore
-@c Try this
+@node Debugging Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+Programs rarely work correctly the first time. Finding bugs
+is @dfn{debugging} and a program that helps you find bugs is a
+@dfn{debugger}. @command{gawk} has a built-in debugger that works very
+similarly to the GNU Debugger, GDB.
+
+@item
+Debuggers let you step through your program one statement at a time,
+examine and change variable and array values, and do a number of other
+things that let you understand what your program is actually doing (as
+opposed to what it is supposed to do).
+
+@item
+Like most debuggers, the @command{gawk} debugger works in terms of stack
+frames, and lets you set both breakpoints (stop at a point in the code)
+and watchpoints (stop when a data value changes).
+
+@item
+The debugger command set is fairly complete, providing control over
+breakpoints, execution, viewing and changing data, working with the stack,
+getting information, and other tasks.
+
+@item
+If the @code{readline} library is available when @command{gawk} is
+compiled, it is used by the debugger to provide command-line history
+and editing.
+
+@end itemize
+
+@node Arbitrary Precision Arithmetic
+@chapter Arithmetic and Arbitrary-Precision Arithmetic with @command{gawk}
+@cindex arbitrary precision
+@cindex multiple precision
+@cindex infinite precision
+@cindex floating-point, numbers@comma{} arbitrary precision
+
+This @value{CHAPTER} introduces some basic concepts relating to
+how computers do arithmetic and defines some important terms.
+It then proceeds to describe floating-point arithmetic,
+which is what @command{awk} uses for all its computations, including a
+discussion of arbitrary-precision floating-point arithmetic, which is
+a feature available only in @command{gawk}. It continues on to present
+arbitrary-precision integers, and concludes with a description of some
+points where @command{gawk} and the POSIX standard are not quite in
+agreement.
+
+@quotation NOTE
+Most users of @command{gawk} can safely skip this chapter.
+But if you want to do scientific calculations with @command{gawk},
+this is the place to be.
+@end quotation
+
+@menu
+* Computer Arithmetic:: A quick intro to computer math.
+* Math Definitions:: Defining terms used.
+* MPFR features:: The MPFR features in @command{gawk}.
+* FP Math Caution:: Things to know.
+* Arbitrary Precision Integers:: Arbitrary Precision Integer Arithmetic with
+ @command{gawk}.
+* POSIX Floating Point Problems:: Standards Versus Existing Practice.
+* Floating point summary:: Summary of floating point discussion.
+@end menu
+
+@node Computer Arithmetic
+@section A General Description of Computer Arithmetic
+
+Until now, we have worked with data as either numbers or
+strings. Ultimately, however, computers represent everything in terms
+of @dfn{binary digits}, or @dfn{bits}. A decimal digit can take on any
+of 10 values: zero through nine. A binary digit can take on any of two
+values, zero or one. Using binary, computers (and computer software)
+can represent and manipulate numerical and character data. In general,
+the more bits you can use to represent a particular thing, the greater
+the range of possible values it can take on.
+
+Modern computers support at least two, and often more, ways to do
+arithmetic. Each kind of arithmetic uses a different representation
+(organization of the bits) for the numbers. The kinds of arithmetic
+that interest us are:
+
+@table @asis
+@item Decimal arithmetic
+This is the kind of arithmetic you learned in elementary school, using
+paper and pencil (and/or a calculator). In theory, numbers can have an
+arbitrary number of digits on either side (or both sides) of the decimal
+point, and the results of a computation are always exact.
+
+Some modern system can do decimal arithmetic in hardware, but usually you
+need a special software library to provide access to these instructions.
+There are also libraries that do decimal arithmetic entirely in software.
+
+Despite the fact that some users expect @command{gawk} to be performing
+decimal arithmetic,@footnote{We don't know why they expect this, but
+they do.} it does not do so.
+
+@item Integer arithmetic
+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.
+
+@cindex unsigned integers
+@cindex integers, unsigned
+In computers, integer values come in two flavors: @dfn{signed} and
+@dfn{unsigned}. Signed values may be negative or positive, whereas
+unsigned values are always positive (i.e., greater than or equal
+to zero).
+
+In computer systems, integer arithmetic is exact, but the possible
+range of values is limited. Integer arithmetic is generally faster than
+floating-point arithmetic.
+
+@item Floating-point arithmetic
+Floating-point numbers represent what were called in school ``real''
+numbers (i.e., those that 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 than can integers. The disadvantage is that
+there are numbers that they cannot represent exactly.
+
+Modern systems support floating-point arithmetic in hardware, with a
+limited range of values. There are software libraries that allow
+the use of arbitrary-precision floating-point calculations.
+
+POSIX @command{awk} uses @dfn{double-precision} floating-point numbers, which
+can hold more digits than @dfn{single-precision} floating-point numbers.
+@command{gawk} has facilities for performing arbitrary-precision
+floating-point arithmetic, which we describe in more detail shortly.
+@end table
+
+Computers work with integer and floating-point values of different
+ranges. Integer values are usually either 32 or 64 bits in size.
+Single-precision floating-point values occupy 32 bits, whereas double-precision
+floating-point values occupy 64 bits. Floating-point values are always
+signed. The possible ranges of values are shown in @ref{table-numeric-ranges}.
+
+@float Table,table-numeric-ranges
+@caption{Value ranges for different numeric representations}
+@multitable @columnfractions .34 .33 .33
+@headitem Numeric representation @tab Minimum value @tab Maximum value
+@item 32-bit signed integer @tab @minus{}2,147,483,648 @tab 2,147,483,647
+@item 32-bit unsigned integer @tab 0 @tab 4,294,967,295
+@item 64-bit signed integer @tab @minus{}9,223,372,036,854,775,808 @tab 9,223,372,036,854,775,807
+@item 64-bit unsigned integer @tab 0 @tab 18,446,744,073,709,551,615
+@item Single-precision floating point (approximate) @tab @code{1.175494e-38} @tab @code{3.402823e+38}
+@item Double-precision floating point (approximate) @tab @code{2.225074e-308} @tab @code{1.797693e+308}
+@end multitable
+@end float
+
+@node Math Definitions
+@section Other Stuff to Know
+
+The rest of this @value{CHAPTER} uses a number of terms. Here are some
+informal definitions that should help you work your way through the material
+here.
+
+@table @dfn
+@item Accuracy
+A floating-point calculation's accuracy is how close it comes
+to the real (paper and pencil) value.
+
+@item Error
+The difference between what the result of a computation ``should be''
+and what it actually is. It is best to minimize error as much
+as possible.
+
+@item Exponent
+The order of magnitude of a value;
+some number of bits in a floating-point value store the exponent.
+
+@item Inf
+A special value representing infinity. Operations involving another
+number and infinity produce infinity.
+
+@item NaN
+``Not A Number.''@footnote{Thanks to Michael Brennan for this description,
+which we have paraphrased, and for the examples.} A special value that
+results from attempting a calculation that has no answer as a real number.
+In such a case, programs can either receive a floating-point exception,
+or get @code{NaN} back as the result. The IEEE 754 standard recommends
+that systems return @code{NaN}. Some examples:
+
+@table @code
+@item sqrt(-1)
+This makes sense in the range of complex numbers, but not in the
+range of real numbers, so the result is @code{NaN}.
+
+@item log(-8)
+@minus{}8 is out of the domain of @code{log()}, so the result is @code{NaN}.
+@end table
+
+@item Normalized
+How the significand (see later in this list) is usually stored. The
+value is adjusted so that the first bit is one, and then that leading
+one is assumed instead of physically stored. This provides one
+extra bit of precision.
+
+@item Precision
+The number of bits used to represent a floating-point number.
+The more bits, the more digits you can represent.
+Binary and decimal precisions are related approximately, according to the
+formula:
+
+@display
@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:
+@math{prec = 3.322 @cdot dps}
+@end iftex
+@ifnottex
+@ifnotdocbook
+@var{prec} = 3.322 * @var{dps}
+@end ifnotdocbook
+@end ifnottex
+@docbook
+<emphasis>prec</emphasis> = 3.322 &sdot; <emphasis>dps</emphasis> @c
+@end docbook
+@end display
+
+@noindent
+Here, @var{prec} denotes the binary precision
+(measured in bits) and @var{dps} (short for decimal places)
+is the decimal digits.
+
+@item Rounding mode
+How numbers are rounded up or down when necessary.
+More details are provided later.
+
+@item Significand
+A floating-point value consists the significand multiplied by 10
+to the power of the exponent. For example, in @code{1.2345e67},
+the significand is @code{1.2345}.
+
+@item Stability
+From @uref{http://en.wikipedia.org/wiki/Numerical_stability,
+the Wikipedia article on numerical stability}:
+``Calculations that can be proven not to magnify approximation errors
+are called @dfn{numerically stable}.''
+@end table
+
+See @uref{http://en.wikipedia.org/wiki/Accuracy_and_precision,
+the Wikipedia article on accuracy and precision} for more information
+on some of those terms.
+
+On modern systems, floating-point hardware uses the representation and
+operations defined by the IEEE 754 standard.
+Three of the standard IEEE 754 types are 32-bit single precision,
+64-bit double precision, and 128-bit quadruple precision.
+The standard also specifies extended precision formats
+to allow greater precisions and larger exponent ranges.
+(@command{awk} uses only the 64-bit double-precision format.)
+
+@ref{table-ieee-formats} lists the precision and exponent
+field values for the basic IEEE 754 binary formats:
+
+@float Table,table-ieee-formats
+@caption{Basic IEEE format values}
+@multitable @columnfractions .20 .20 .20 .20 .20
+@headitem Name @tab Total bits @tab Precision @tab Minimum exponent @tab Maximum exponent
+@item Single @tab 32 @tab 24 @tab @minus{}126 @tab +127
+@item Double @tab 64 @tab 53 @tab @minus{}1022 @tab +1023
+@item Quadruple @tab 128 @tab 113 @tab @minus{}16382 @tab +16383
+@end multitable
+@end float
+
+@quotation NOTE
+The precision numbers include the implied leading one that gives them
+one extra bit of significand.
+@end quotation
+
+@node MPFR features
+@section Arbitrary-Precision Arithmetic Features in @command{gawk}
+
+By default, @command{gawk} uses the double-precision floating-point values
+supplied by the hardware of the system it runs on. However, if it was
+compiled to do so, @command{gawk} uses the @uref{http://www.mpfr.org,
+GNU MPFR} and @uref{http://gmplib.org, GNU MP} (GMP) libraries for
+arbitrary-precision arithmetic on numbers. You can see if MPFR support
+is available like so:
+
+@example
+$ @kbd{gawk --version}
+@print{} GNU Awk 4.1.2, API: 1.1 (GNU MPFR 3.1.0-p3, GNU MP 5.0.2)
+@print{} Copyright (C) 1989, 1991-2015 Free Software Foundation.
+@dots{}
+@end example
+
+@noindent
+(You may see different version numbers than what's shown here. That's OK;
+what's important is to see that GNU MPFR and GNU MP are listed in
+the output.)
+
+Additionally, there are a few elements available in the @code{PROCINFO}
+array to provide information about the MPFR and GMP libraries
+(@pxref{Auto-set}).
+
+The MPFR library provides precise control over precisions and rounding
+modes, and gives correctly rounded, reproducible, platform-independent
+results. With the @option{-M} command-line option,
+all floating-point arithmetic operators and numeric functions
+can yield results to any desired precision level supported by MPFR.
+
+Two predefined variables, @code{PREC} and @code{ROUNDMODE},
+provide control over the working precision and the rounding mode.
+The precision and the rounding mode are set globally for every operation
+to follow.
+@DBXREF{Setting precision} and @DBREF{Setting the rounding mode}
+for more information.
+
+@node FP Math Caution
+@section Floating-Point Arithmetic: Caveat Emptor!
+
+@quotation
+@i{Math class is tough!}
+@author Teen Talk Barbie, July 1992
+@end quotation
+
+This @value{SECTION} provides a high level overview of the issues
+involved when doing lots of floating-point arithmetic.@footnote{There
+is a very nice @uref{http://www.validlab.com/goldberg/paper.pdf,
+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. This is
+worth reading if you are interested in the details, but it does require
+a background in computer science.}
+The discussion applies to both hardware and arbitrary-precision
+floating-point arithmetic.
+
+@quotation CAUTION
+The material here is purposely general. If you need to do serious
+computer arithmetic, you should do some research first, and not
+rely just on what we tell you.
+@end quotation
+
+@menu
+* Inexactness of computations:: Floating point math is not exact.
+* Getting Accuracy:: Getting more accuracy takes some work.
+* Try To Round:: Add digits and round.
+* Setting precision:: How to set the precision.
+* Setting the rounding mode:: How to set the rounding mode.
+@end menu
+
+@node Inexactness of computations
+@subsection Floating-Point Arithmetic Is Not Exact
+
+Binary floating-point representations and arithmetic are inexact.
+Simple values like 0.1 cannot be precisely represented using
+binary floating-point numbers, and the limited precision of
+floating-point numbers means that slight changes in
+the order of operations or the precision of intermediate storage
+can change the result. To make matters worse, with arbitrary-precision
+floating-point arithmetic, you can set the precision before starting a
+computation, but then you cannot be sure of the number of significant
+decimal places in the final result.
+
+@menu
+* Inexact representation:: Numbers are not exactly represented.
+* Comparing FP Values:: How to compare floating point values.
+* Errors accumulate:: Errors get bigger as they go.
+@end menu
+
+@node Inexact representation
+@subsubsection Many Numbers Cannot Be Represented Exactly
+
+So, before you start to write any code, you should think
+about what you really want and what's really happening. Consider the
+two numbers in the following example:
+
+@example
+x = 0.875 # 1/2 + 1/4 + 1/8
+y = 0.425
+@end example
+
+Unlike the number in @code{y}, the number stored in @code{x}
+is exactly representable
+in binary because it can be written as a finite sum of one or
+more fractions whose denominators are all powers of two.
+When @command{gawk} reads a floating-point number from
+program source, it automatically rounds that number to whatever
+precision your machine supports. If you try to print the numeric
+content of a variable using an output format string of @code{"%.17g"},
+it may not produce the same number as you assigned to it:
+
+@example
+$ @kbd{gawk 'BEGIN @{ x = 0.875; y = 0.425}
+> @kbd{ printf("%0.17g, %0.17g\n", x, y) @}'}
+@print{} 0.875, 0.42499999999999999
+@end example
+
+Often the error is so small you do not even notice it, and if you do,
+you can always specify how much precision you would like in your output.
+Usually this is a format string like @code{"%.15g"}, which when
+used in the previous example, produces an output identical to the input.
+
+@node Comparing FP Values
+@subsubsection Be Careful Comparing Values
+
+Because the underlying representation can be a little bit off from the exact value,
+comparing floating-point values to see if they are exactly equal is generally a bad idea.
+Here is an example where it does not work like you would expect:
+
+@example
+$ @kbd{gawk 'BEGIN @{ print (0.1 + 12.2 == 12.3) @}'}
+@print{} 0
+@end example
+
+The general wisdom when comparing floating-point values is to see if
+they are within some small range of each other (called a @dfn{delta},
+or @dfn{tolerance}).
+You have to decide how small a delta is important to you. Code to do
+this looks something like the following:
+
+@example
+delta = 0.00001 # for example
+difference = abs(a) - abs(b) # subtract the two values
+if (difference < delta)
+ # all ok
+else
+ # not ok
+@end example
+
+@noindent
+(We assume that you have a simple absolute value function named
+@code{abs()} defined elsewhere in your program.)
+
+@node Errors accumulate
+@subsubsection Errors Accumulate
+
+The loss of accuracy during a single computation with floating-point
+numbers usually isn't enough to worry about. However, if you compute a
+value which is the result of a sequence of floating-point operations,
+the error can accumulate and greatly affect the computation itself.
+Here is an attempt to compute the value of @value{PI} using one of its
+many series representations:
+
+@example
+BEGIN @{
+ x = 1.0 / sqrt(3.0)
+ n = 6
+ for (i = 1; i < 30; i++) @{
+ n = n * 2.0
+ x = (sqrt(x * x + 1) - 1) / x
+ printf("%.15f\n", n * x)
+ @}
+@}
+@end example
+
+When run, the early errors propagate through later computations,
+causing the loop to terminate prematurely after attempting to divide by zero:
+
+@example
+$ @kbd{gawk -f pi.awk}
+@print{} 3.215390309173475
+@print{} 3.159659942097510
+@print{} 3.146086215131467
+@print{} 3.142714599645573
+@dots{}
+@print{} 3.224515243534819
+@print{} 2.791117213058638
+@print{} 0.000000000000000
+@error{} gawk: pi.awk:6: fatal: division by zero attempted
+@end example
+
+Here is an additional example where the inaccuracies in internal representations
+yield an unexpected result:
+
+@example
+$ @kbd{gawk 'BEGIN @{}
+> @kbd{for (d = 1.1; d <= 1.5; d += 0.1) # loop five times (?)}
+> @kbd{i++}
+> @kbd{print i}
+> @kbd{@}'}
+@print{} 4
+@end example
+
+@node Getting Accuracy
+@subsection Getting the Accuracy You Need
+
+Can arbitrary-precision arithmetic give exact results? There are
+no easy answers. The standard rules of algebra often do not apply
+when using floating-point arithmetic.
+Among other things, the distributive and associative laws
+do not hold completely, and order of operation may be important
+for your computation. Rounding error, cumulative precision loss
+and underflow are often troublesome.
+
+When @command{gawk} tests the expressions @samp{0.1 + 12.2} and
+@samp{12.3} for equality using the machine double-precision arithmetic,
+it decides that they are not equal! (@xref{Comparing FP Values}.)
+You can get the result you want by increasing the precision; 56 bits in
+this case does the job:
-@itemize @bullet
+@example
+$ @kbd{gawk -M -v PREC=56 'BEGIN @{ print (0.1 + 12.2 == 12.3) @}'}
+@print{} 1
+@end example
+
+If adding more bits is good, perhaps adding even more bits of
+precision is better?
+Here is what happens if we use an even larger value of @code{PREC}:
+
+@example
+$ @kbd{gawk -M -v PREC=201 'BEGIN @{ print (0.1 + 12.2 == 12.3) @}'}
+@print{} 0
+@end example
+
+This is not a bug in @command{gawk} or in the MPFR library.
+It is easy to forget that the finite number of bits used to store the value
+is often just an approximation after proper rounding.
+The test for equality succeeds if and only if @emph{all} bits in the two operands
+are exactly the same. Because this is not necessarily true after floating-point
+computations with a particular precision and effective rounding mode,
+a straight test for equality may not work. Instead, compare the
+two numbers to see if they are within the desirable delta of each other.
+
+In applications where 15 or fewer decimal places suffice,
+hardware double-precision arithmetic can be adequate, and is usually much faster.
+But you need to keep in mind that every floating-point operation
+can suffer a new rounding error with catastrophic consequences, as illustrated
+by our earlier attempt to compute the value of @value{PI}.
+Extra precision can greatly enhance the stability and the accuracy
+of your computation in such cases.
+
+Repeated addition is not necessarily equivalent to multiplication
+in floating-point arithmetic. In the example in
+@ref{Errors accumulate}:
+
+@example
+$ @kbd{gawk 'BEGIN @{}
+> @kbd{for (d = 1.1; d <= 1.5; d += 0.1) # loop five times (?)}
+> @kbd{i++}
+> @kbd{print i}
+> @kbd{@}'}
+@print{} 4
+@end example
+
+@noindent
+you may or may not succeed in getting the correct result by choosing
+an arbitrarily large value for @code{PREC}. Reformulation of
+the problem at hand is often the correct approach in such situations.
+
+@node Try To Round
+@subsection Try a Few Extra Bits of Precision and Rounding
+
+Instead of arbitrary-precision floating-point arithmetic,
+often all you need is an adjustment of your logic
+or a different order for the operations in your calculation.
+The stability and the accuracy of the computation of @value{PI}
+in the earlier example can be enhanced by using the following
+simple algebraic transformation:
+
+@example
+(sqrt(x * x + 1) - 1) / x @equiv{} x / (sqrt(x * x + 1) + 1)
+@end example
+
+@noindent
+After making this change, the program converges to
+@value{PI} in under 30 iterations:
+
+@example
+$ @kbd{gawk -f pi2.awk}
+@print{} 3.215390309173473
+@print{} 3.159659942097501
+@print{} 3.146086215131436
+@print{} 3.142714599645370
+@print{} 3.141873049979825
+@dots{}
+@print{} 3.141592653589797
+@print{} 3.141592653589797
+@end example
+
+@node Setting precision
+@subsection Setting the Precision
+
+@command{gawk} uses a global working precision; it does not keep track of
+the precision or accuracy of individual numbers. Performing an arithmetic
+operation or calling a built-in function rounds the result to the current
+working precision. The default working precision is 53 bits, which you can
+modify using the predefined variable @code{PREC}. You can also set the
+value to one of the predefined case-insensitive strings
+shown in @ref{table-predefined-precision-strings},
+to emulate an IEEE 754 binary format.
+
+@float Table,table-predefined-precision-strings
+@caption{Predefined precision strings for @code{PREC}}
+@multitable {@code{"double"}} {12345678901234567890123456789012345}
+@headitem @code{PREC} @tab IEEE 754 Binary Format
+@item @code{"half"} @tab 16-bit half-precision
+@item @code{"single"} @tab Basic 32-bit single precision
+@item @code{"double"} @tab Basic 64-bit double precision
+@item @code{"quad"} @tab Basic 128-bit quadruple precision
+@item @code{"oct"} @tab 256-bit octuple precision
+@end multitable
+@end float
+
+The following example illustrates the effects of changing precision
+on arithmetic operations:
+
+@example
+$ @kbd{gawk -M -v PREC=100 'BEGIN @{ x = 1.0e-400; print x + 0}
+> @kbd{PREC = "double"; print x + 0 @}'}
+@print{} 1e-400
+@print{} 0
+@end example
+
+@quotation CAUTION
+Be wary of floating-point constants! When reading a floating-point
+constant from program source code, @command{gawk} uses the default
+precision (that of a C @code{double}), unless overridden by an assignment
+to the special variable @code{PREC} on the command line, to store it
+internally as an MPFR number. Changing the precision using @code{PREC}
+in the program text does @emph{not} change the precision of a constant.
+
+If you need to represent a floating-point constant at a higher precision
+than the default and cannot use a command-line assignment to @code{PREC},
+you should either specify the constant as a string, or as a rational
+number, whenever possible. The following example illustrates the
+differences among various ways to print a floating-point constant:
+@end quotation
+
+@example
+$ @kbd{gawk -M 'BEGIN @{ PREC = 113; printf("%0.25f\n", 0.1) @}'}
+@print{} 0.1000000000000000055511151
+$ @kbd{gawk -M -v PREC=113 'BEGIN @{ printf("%0.25f\n", 0.1) @}'}
+@print{} 0.1000000000000000000000000
+$ @kbd{gawk -M 'BEGIN @{ PREC = 113; printf("%0.25f\n", "0.1") @}'}
+@print{} 0.1000000000000000000000000
+$ @kbd{gawk -M 'BEGIN @{ PREC = 113; printf("%0.25f\n", 1/10) @}'}
+@print{} 0.1000000000000000000000000
+@end example
+
+@node Setting the rounding mode
+@subsection Setting the Rounding Mode
+
+The @code{ROUNDMODE} variable provides
+program level control over the rounding mode.
+The correspondence between @code{ROUNDMODE} and the IEEE
+rounding modes is shown in @ref{table-gawk-rounding-modes}.
+
+@float Table,table-gawk-rounding-modes
+@caption{@command{gawk} rounding modes}
+@multitable @columnfractions .45 .30 .25
+@headitem Rounding Mode @tab IEEE Name @tab @code{ROUNDMODE}
+@item Round to nearest, ties to even @tab @code{roundTiesToEven} @tab @code{"N"} or @code{"n"}
+@item Round toward plus Infinity @tab @code{roundTowardPositive} @tab @code{"U"} or @code{"u"}
+@item Round toward negative Infinity @tab @code{roundTowardNegative} @tab @code{"D"} or @code{"d"}
+@item Round toward zero @tab @code{roundTowardZero} @tab @code{"Z"} or @code{"z"}
+@item Round to nearest, ties away from zero @tab @code{roundTiesToAway} @tab @code{"A"} or @code{"a"}
+@end multitable
+@end float
+
+@code{ROUNDMODE} has the default value @code{"N"}, which
+selects the IEEE 754 rounding mode @code{roundTiesToEven}.
+In @ref{table-gawk-rounding-modes}, the value @code{"A"} selects
+@code{roundTiesToAway}. This is only available if your version of the
+MPFR library supports it; otherwise, setting @code{ROUNDMODE} to @code{"A"}
+has no effect.
+
+The default mode @code{roundTiesToEven} is the most preferred,
+but the least intuitive. This method does the obvious thing for most values,
+by rounding them up or down to the nearest digit.
+For example, rounding 1.132 to two digits yields 1.13,
+and rounding 1.157 yields 1.16.
+
+However, when it comes to rounding a value that is exactly halfway between,
+things do not work the way you probably learned in school.
+In this case, the number is rounded to the nearest even digit.
+So rounding 0.125 to two digits rounds down to 0.12,
+but rounding 0.6875 to three digits rounds up to 0.688.
+You probably have already encountered this rounding mode when
+using @code{printf} to format floating-point numbers.
+For example:
+
+@example
+BEGIN @{
+ x = -4.5
+ for (i = 1; i < 10; i++) @{
+ x += 1.0
+ printf("%4.1f => %2.0f\n", x, x)
+ @}
+@}
+@end example
+
+@noindent
+produces the following output when run on the author's system:@footnote{It
+is possible for the output to be completely different if the
+C library in your system does not use the IEEE 754 even-rounding
+rule to round halfway cases for @code{printf}.}
+
+@example
+-3.5 => -4
+-2.5 => -2
+-1.5 => -2
+-0.5 => 0
+ 0.5 => 0
+ 1.5 => 2
+ 2.5 => 2
+ 3.5 => 4
+ 4.5 => 4
+@end example
+
+The theory behind @code{roundTiesToEven} is that it more or less evenly
+distributes upward and downward rounds of exact halves, which might
+cause any accumulating round-off error to cancel itself out. This is the
+default rounding mode for IEEE 754 computing functions and operators.
+
+The other rounding modes are rarely used. Round toward positive infinity
+(@code{roundTowardPositive}) and round toward negative infinity
+(@code{roundTowardNegative}) are often used to implement interval
+arithmetic, where you adjust the rounding mode to calculate upper and
+lower bounds for the range of output. The @code{roundTowardZero} mode can
+be used for converting floating-point numbers to integers. The rounding
+mode @code{roundTiesToAway} rounds the result to the nearest number and
+selects the number with the larger magnitude if a tie occurs.
+
+Some numerical analysts will tell you that your choice of rounding
+style has tremendous impact on the final outcome, and advise you to
+wait until final output for any rounding. Instead, you can often avoid
+round-off error problems by setting the precision initially to some
+value sufficiently larger than the final desired precision, so that
+the accumulation of round-off error does not influence the outcome.
+If you suspect that results from your computation are sensitive to
+accumulation of round-off error, look for a significant difference in
+output when you change the rounding mode to be sure.
+
+@node Arbitrary Precision Integers
+@section Arbitrary-Precision Integer Arithmetic with @command{gawk}
+@cindex integers, arbitrary precision
+@cindex arbitrary precision integers
+
+When given the @option{-M} option,
+@command{gawk} performs all integer arithmetic using GMP arbitrary-precision
+integers. Any number that looks like an integer in a source
+or @value{DF} is stored as an arbitrary-precision integer. The size
+of the integer is limited only by the available memory. For example,
+the following computes
+@iftex
+@math{5^{4^{3^{2}}}},
+@end iftex
+@ifnottex
+@ifnotdocbook
+5^4^3^2,
+@end ifnotdocbook
+@end ifnottex
+@docbook
+5<superscript>4<superscript>3<superscript>2</superscript></superscript></superscript>, @c
+@end docbook
+the result of which is beyond the
+limits of ordinary hardware double-precision floating-point values:
+
+@example
+$ @kbd{gawk -M 'BEGIN @{}
+> @kbd{x = 5^4^3^2}
+> @kbd{print "number of digits =", length(x)}
+> @kbd{print substr(x, 1, 20), "...", substr(x, length(x) - 19, 20)}
+> @kbd{@}'}
+@print{} number of digits = 183231
+@print{} 62060698786608744707 ... 92256259918212890625
+@end example
+
+If instead you were to compute the same value using arbitrary-precision
+floating-point values, the precision needed for correct output (using
+the formula
+@iftex
+@math{prec = 3.322 @cdot dps}),
+would be @math{3.322 @cdot 183231},
+@end iftex
+@ifnottex
+@ifnotdocbook
+@samp{prec = 3.322 * dps}),
+would be 3.322 x 183231,
+@end ifnotdocbook
+@end ifnottex
+@docbook
+<emphasis>prec</emphasis> = 3.322 &sdot; <emphasis>dps</emphasis>),
+would be
+<emphasis>prec</emphasis> = 3.322 &sdot; 183231, @c
+@end docbook
+or 608693.
+
+The result from an arithmetic operation with an integer and a floating-point value
+is a floating-point value with a precision equal to the working precision.
+The following program calculates the eighth term in
+Sylvester's sequence@footnote{Weisstein, Eric W.
+@cite{Sylvester's Sequence}. From MathWorld---A Wolfram Web Resource
+@w{(@url{http://mathworld.wolfram.com/SylvestersSequence.html}).}}
+using a recurrence:
+
+@example
+$ @kbd{gawk -M 'BEGIN @{}
+> @kbd{s = 2.0}
+> @kbd{for (i = 1; i <= 7; i++)}
+> @kbd{s = s * (s - 1) + 1}
+> @kbd{print s}
+> @kbd{@}'}
+@print{} 113423713055421845118910464
+@end example
+
+The output differs from the actual number, 113,423,713,055,421,844,361,000,443,
+because the default precision of 53 bits is not enough to represent the
+floating-point results exactly. You can either increase the precision
+(100 bits is enough in this case), or replace the floating-point constant
+@samp{2.0} with an integer, to perform all computations using integer
+arithmetic to get the correct output.
+
+Sometimes @command{gawk} must implicitly convert an arbitrary-precision
+integer into an arbitrary-precision floating-point value. This is
+primarily because the MPFR library does not always provide the relevant
+interface to process arbitrary-precision integers or mixed-mode numbers
+as needed by an operation or function. In such a case, the precision is
+set to the minimum value necessary for exact conversion, and the working
+precision is not used for this purpose. If this is not what you need or
+want, you can employ a subterfuge, and convert the integer to floating
+point first, like this:
+
+@example
+gawk -M 'BEGIN @{ n = 13; print (n + 0.0) % 2.0 @}'
+@end example
+
+You can avoid this issue altogether by specifying the number as a floating-point value
+to begin with:
+
+@example
+gawk -M 'BEGIN @{ n = 13.0; print n % 2.0 @}'
+@end example
+
+Note that for this particular example, it is likely best
+to just use the following:
+
+@example
+gawk -M 'BEGIN @{ n = 13; print n % 2 @}'
+@end example
+
+When dividing two arbitrary precision integers with either
+@samp{/} or @samp{%}, the result is typically an arbitrary
+precision floating point value (unless the denominator evenly
+divides into the numerator). In order to do integer division
+or remainder with arbitrary precision integers, use the built-in
+@code{div()} function (@pxref{Numeric Functions}).
+
+You can simulate the @code{div()} function in standard @command{awk}
+using this user-defined function:
+
+@example
+@c file eg/lib/div.awk
+# div --- do integer division
+
+@c endfile
+@ignore
+@c file eg/lib/div.awk
+#
+# Arnold Robbins, arnold@@skeeve.com, Public Domain
+# July, 2014
+
+@c endfile
+
+@end ignore
+@c file eg/lib/div.awk
+function div(numerator, denominator, result)
+@{
+ split("", result)
+
+ numerator = int(numerator)
+ denominator = int(denominator)
+ result["quotient"] = int(numerator / denominator)
+ result["remainder"] = int(numerator % denominator)
+
+ return 0.0
+@}
+@c endfile
+@end example
+
+The following example program, contributed by Katie Wasserman,
+uses @code{div()} to
+compute the digits of @value{PI} to as many places as you
+choose to set:
+
+@example
+@c file eg/prog/pi.awk
+# pi.awk --- compute the digits of pi
+@c endfile
+@c endfile
+@ignore
+@c file eg/prog/pi.awk
+#
+# Katie Wasserman, katie@@wass.net
+# August 2014
+@c endfile
+@end ignore
+@c file eg/prog/pi.awk
+
+BEGIN @{
+ digits = 100000
+ two = 2 * 10 ^ digits
+ pi = two
+ for (m = digits * 4; m > 0; --m) @{
+ d = m * 2 + 1
+ x = pi * m
+ div(x, d, result)
+ pi = result["quotient"]
+ pi = pi + two
+ @}
+ print pi
+@}
+@c endfile
+@end example
+
+@ignore
+Date: Wed, 20 Aug 2014 10:19:11 -0400
+To: arnold@skeeve.com
+From: Katherine Wasserman <katie@wass.net>
+Subject: Re: computation of digits of pi?
+
+Arnold,
+
+>The program that you sent to compute the digits of pi using div(). Is
+>that some standard algorithm that every math student knows? If so,
+>what's it called?
+
+It's not that well known but it's not that obscure either
+
+It's Euler's modification to Newton's method for calculating pi.
+
+Take a look at lines (23) - (25) here: http://mathworld.wolfram.com/PiFormulas.htm
+
+The algorithm I wrote simply expands the multiply by 2 and works from the innermost expression outwards. I used this to program HP calculators because it's quite easy to modify for tiny memory devices with smallish word sizes.
+
+http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/articles.cgi?read=899
+
+-Katie
+@end ignore
+
+When asked about the algorithm used, Katie replied:
+
+@quotation
+It's not that well known but it's not that obscure either.
+It's Euler's modification to Newton's method for calculating pi.
+Take a look at lines (23) - (25) here: @uref{http://mathworld.wolfram.com/PiFormulas.htm}.
+
+The algorithm I wrote simply expands the multiply by 2 and works from
+the innermost expression outwards. I used this to program HP calculators
+because it's quite easy to modify for tiny memory devices with smallish
+word sizes. See
+@uref{http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/articles.cgi?read=899}.
+@end quotation
+
+@node POSIX Floating Point Problems
+@section Standards Versus Existing Practice
+
+Historically, @command{awk} has converted any non-numeric looking string
+to the numeric value zero, when required. Furthermore, the original
+definition of the language and the original POSIX standards specified that
+@command{awk} only understands decimal numbers (base 10), and not octal
+(base 8) or hexadecimal numbers (base 16).
+
+Changes in the language of the
+2001 and 2004 POSIX standards can be interpreted to imply that @command{awk}
+should support additional features. These features are:
+
+@itemize @value{BULLET}
@item
-@ref{Language History}.
+Interpretation of floating-point data values specified in hexadecimal
+notation (e.g., @code{0xDEADBEEF}). (Note: data values, @emph{not}
+source code constants.)
@item
-@ref{Installation}.
+Support for the special IEEE 754 floating-point values ``Not A Number''
+(NaN), positive Infinity (``inf''), and negative Infinity (``@minus{}inf'').
+In particular, the format for these values is as specified by the ISO 1999
+C standard, which ignores case and can allow implementation-dependent additional
+characters after the @samp{nan} and allow either @samp{inf} or @samp{infinity}.
+@end itemize
+The first problem is that both of these are clear changes to historical
+practice:
+
+@itemize @value{BULLET}
@item
-@ref{Notes}.
+The @command{gawk} maintainer feels that supporting hexadecimal
+floating-point values, in particular, is ugly, and was never intended by the
+original designers to be part of the language.
@item
-@ref{Basic Concepts}.
+Allowing completely alphabetic strings to have valid numeric
+values is also a very severe departure from historical practice.
+@end itemize
+
+The second problem is that the @code{gawk} maintainer feels that this
+interpretation of the standard, which requires a certain amount of
+``language lawyering'' to arrive at in the first place, was not even
+intended by the standard developers. In other words, ``we see how you
+got where you are, but we don't think that that's where you want to be.''
+
+Recognizing these issues, but attempting to provide compatibility
+with the earlier versions of the standard,
+the 2008 POSIX standard added explicit wording to allow, but not require,
+that @command{awk} support hexadecimal floating-point values and
+special values for ``Not A Number'' and infinity.
+Although the @command{gawk} maintainer continues to feel that
+providing those features is inadvisable,
+nevertheless, on systems that support IEEE floating point, it seems
+reasonable to provide @emph{some} way to support NaN and Infinity values.
+The solution implemented in @command{gawk} is as follows:
+
+@itemize @value{BULLET}
@item
-@ref{Glossary}.
+With the @option{--posix} command-line option, @command{gawk} becomes
+``hands off.'' String values are passed directly to the system library's
+@code{strtod()} function, and if it successfully returns a numeric value,
+that is what's used.@footnote{You asked for it, you got it.}
+By definition, the results are not portable across
+different systems. They are also a little surprising:
+
+@example
+$ @kbd{echo nanny | gawk --posix '@{ print $1 + 0 @}'}
+@print{} nan
+$ @kbd{echo 0xDeadBeef | gawk --posix '@{ print $1 + 0 @}'}
+@print{} 3735928559
+@end example
@item
-@ref{Copying}.
+Without @option{--posix}, @command{gawk} interprets the four strings
+@samp{+inf},
+@samp{-inf},
+@samp{+nan},
+and
+@samp{-nan}
+specially, producing the corresponding special numeric values.
+The leading sign acts a signal to @command{gawk} (and the user)
+that the value is really numeric. Hexadecimal floating point is
+not supported (unless you also use @option{--non-decimal-data},
+which is @emph{not} recommended). For example:
+
+@example
+$ @kbd{echo nanny | gawk '@{ print $1 + 0 @}'}
+@print{} 0
+$ @kbd{echo +nan | gawk '@{ print $1 + 0 @}'}
+@print{} nan
+$ @kbd{echo 0xDeadBeef | gawk '@{ print $1 + 0 @}'}
+@print{} 0
+@end example
+
+@command{gawk} ignores case in the four special values.
+Thus @samp{+nan} and @samp{+NaN} are the same.
+@end itemize
+@node Floating point summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+Most computer arithmetic is done using either integers or floating-point
+values. Standard @command{awk} uses double-precision
+floating-point values.
+
+@item
+In the early 1990s, Barbie mistakenly said ``Math class is tough!''
+Although math isn't tough, floating-point arithmetic isn't the same
+as pencil and paper math, and care must be taken:
+
+@c nested list
+@itemize @value{MINUS}
@item
-@ref{GNU Free Documentation License}.
+Not all numbers can be represented exactly.
+
+@item
+Comparing values should use a delta, instead of being done directly
+with @samp{==} and @samp{!=}.
+
+@item
+Errors accumulate.
+
+@item
+Operations are not always truly associative or distributive.
@end itemize
-@page
-@evenheading @thispage@ @ @ @strong{@value{TITLE}} @| @|
-@oddheading @| @| @strong{@thischapter}@ @ @ @thispage
-@end iftex
+@item
+Increasing the accuracy can help, but it is not a panacea.
+
+@item
+Often, increasing the accuracy and then rounding to the desired
+number of digits produces reasonable results.
+
+@item
+Use @option{-M} (or @option{--bignum}) to enable MPFR
+arithmetic. Use @code{PREC} to set the precision in bits, and
+@code{ROUNDMODE} to set the IEEE 754 rounding mode.
+
+@item
+With @option{-M}, @command{gawk} performs
+arbitrary-precision integer arithmetic using the GMP library.
+This is faster and more space efficient than using MPFR for
+the same calculations.
+
+@item
+There are several ``dark corners'' with respect to floating-point
+numbers where @command{gawk} disagrees with the POSIX standard.
+It pays to be aware of them.
+
+@item
+Overall, there is no need to be unduly suspicious about the results from
+floating-point arithmetic. The lesson to remember is that floating-point
+arithmetic is always more complex than arithmetic using pencil and
+paper. In order to take advantage of the power of computer floating point,
+you need to know its limitations and work within them. For most casual
+use of floating-point arithmetic, you will often get the expected result
+if you simply round the display of your final results to the correct number
+of significant decimal digits.
+
+@item
+As general advice, avoid presenting numerical data in a manner that
+implies better precision than is actually the case.
+
+@end itemize
+
+@node Dynamic Extensions
+@chapter Writing Extensions for @command{gawk}
+@cindex dynamically loaded extensions
+
+It is possible to add new functions written in C or C++ to @command{gawk} using
+dynamically loaded libraries. This facility is available on systems
+that support the C @code{dlopen()} and @code{dlsym()}
+functions. This @value{CHAPTER} describes how to create extensions
+using code written in C or C++.
+
+If you don't know anything about C programming, you can safely skip this
+@value{CHAPTER}, although you may wish to review the documentation on the
+extensions that come with @command{gawk} (@pxref{Extension Samples}),
+and the information on the @code{gawkextlib} project (@pxref{gawkextlib}).
+The sample extensions are automatically built and installed when
+@command{gawk} is.
+
+@quotation NOTE
+When @option{--sandbox} is specified, extensions are disabled
+(@pxref{Options}).
+@end quotation
+
+@menu
+* Extension Intro:: What is an extension.
+* Plugin License:: A note about licensing.
+* Extension Mechanism Outline:: An outline of how it works.
+* Extension API Description:: A full description of the API.
+* Finding Extensions:: How @command{gawk} finds compiled extensions.
+* Extension Example:: Example C code for an extension.
+* Extension Samples:: The sample extensions that ship with
+ @code{gawk}.
+* gawkextlib:: The @code{gawkextlib} project.
+* Extension summary:: Extension summary.
+* Extension Exercises:: Exercises.
+@end menu
+
+@node Extension Intro
+@section Introduction
+
+@cindex plug-in
+An @dfn{extension} (sometimes called a @dfn{plug-in}) is a piece of
+external compiled code that @command{gawk} can load at runtime to
+provide additional functionality, over and above the built-in capabilities
+described in the rest of this @value{DOCUMENT}.
+
+Extensions are useful because they allow you (of course) to extend
+@command{gawk}'s functionality. For example, they can provide access to
+system calls (such as @code{chdir()} to change directory) and to other
+C library routines that could be of use. As with most software,
+``the sky is the limit;'' if you can imagine something that you might
+want to do and can write in C or C++, you can write an extension to do it!
+
+Extensions are written in C or C++, using the @dfn{application programming
+interface} (API) defined for this purpose by the @command{gawk}
+developers. The rest of this @value{CHAPTER} explains
+the facilities that the API provides and how to use
+them, and presents a small example extension. In addition, it documents
+the sample extensions included in the @command{gawk} distribution,
+and describes the @code{gawkextlib} project.
+@ifclear FOR_PRINT
+@xref{Extension Design}, for a discussion of the extension mechanism
+goals and design.
+@end ifclear
+@ifset FOR_PRINT
+See @uref{http://www.gnu.org/software/gawk/manual/html_node/Extension-Design.html}
+for a discussion of the extension mechanism
+goals and design.
+@end ifset
+
+@node Plugin License
+@section Extension Licensing
+
+Every dynamic extension must be distributed under a license that is
+compatible with the GNU GPL (@pxref{Copying}).
+
+In order for the extension to tell @command{gawk} that it is
+properly licensed, the extension must define the global symbol
+@code{plugin_is_GPL_compatible}. If this symbol does not exist,
+@command{gawk} emits a fatal error and exits when it tries to load
+your extension.
+
+The declared type of the symbol should be @code{int}. It does not need
+to be in any allocated section, though. The code merely asserts that
+the symbol exists in the global scope. Something like this is enough:
+
+@example
+int plugin_is_GPL_compatible;
+@end example
+
+@node Extension Mechanism Outline
+@section How It Works at a High Level
+
+Communication between
+@command{gawk} and an extension is two-way. First, when an extension
+is loaded, @command{gawk} passes it a pointer to a @code{struct} whose fields are
+function pointers.
+@ifnotdocbook
+This is shown in @ref{figure-load-extension}.
+@end ifnotdocbook
+@ifdocbook
+This is shown in @inlineraw{docbook, <xref linkend="figure-load-extension"/>}.
+@end ifdocbook
+
+@ifnotdocbook
+@float Figure,figure-load-extension
+@caption{Loading the extension}
+@c FIXME: One day, it should not be necessary to have two cases,
+@c but rather just the one without the "txt" final argument.
+@c This applies to the other figures as well.
+@ifinfo
+@center @image{api-figure1, , , Loading the extension, txt}
+@end ifinfo
+@ifnotinfo
+@center @image{api-figure1, , , Loading the extension}
+@end ifnotinfo
+@end float
+@end ifnotdocbook
+
+@docbook
+<figure id="figure-load-extension" float="0">
+<title>Loading the extension</title>
+<mediaobject>
+<imageobject role="web"><imagedata fileref="api-figure1.png" format="PNG"/></imageobject>
+</mediaobject>
+</figure>
+@end docbook
+
+The extension can call functions inside @command{gawk} through these
+function pointers, at runtime, without needing (link-time) access
+to @command{gawk}'s symbols. One of these function pointers is to a
+function for ``registering'' new functions.
+@ifnotdocbook
+This is shown in @ref{figure-register-new-function}.
+@end ifnotdocbook
+@ifdocbook
+This is shown in @inlineraw{docbook, <xref linkend="figure-register-new-function"/>}.
+@end ifdocbook
+
+@ifnotdocbook
+@float Figure,figure-register-new-function
+@caption{Registering a new function}
+@ifinfo
+@center @image{api-figure2, , , Registering a new Function, txt}
+@end ifinfo
+@ifnotinfo
+@center @image{api-figure2, , , Registering a new Function}
+@end ifnotinfo
+@end float
+@end ifnotdocbook
+
+@docbook
+<figure id="figure-register-new-function" float="0">
+<title>Registering a new function</title>
+<mediaobject>
+<imageobject role="web"><imagedata fileref="api-figure2.png" format="PNG"/></imageobject>
+</mediaobject>
+</figure>
+@end docbook
+
+In the other direction, the extension registers its new functions
+with @command{gawk} by passing function pointers to the functions that
+provide the new feature (@code{do_chdir()}, for example). @command{gawk}
+associates the function pointer with a name and can then call it, using a
+defined calling convention.
+@ifnotdocbook
+This is shown in @ref{figure-call-new-function}.
+@end ifnotdocbook
+@ifdocbook
+This is shown in @inlineraw{docbook, <xref linkend="figure-call-new-function"/>}.
+@end ifdocbook
+
+@ifnotdocbook
+@float Figure,figure-call-new-function
+@caption{Calling the new function}
+@ifinfo
+@center @image{api-figure3, , , Calling the new function, txt}
+@end ifinfo
+@ifnotinfo
+@center @image{api-figure3, , , Calling the new function}
+@end ifnotinfo
+@end float
+@end ifnotdocbook
+
+@docbook
+<figure id="figure-call-new-function" float="0">
+<title>Calling the new function</title>
+<mediaobject>
+<imageobject role="web"><imagedata fileref="api-figure3.png" format="PNG"/></imageobject>
+</mediaobject>
+</figure>
+@end docbook
+
+The @code{do_@var{xxx}()} function, in turn, then uses the function
+pointers in the API @code{struct} to do its work, such as updating
+variables or arrays, printing messages, setting @code{ERRNO}, and so on.
+
+Convenience macros make calling through the function pointers look
+like regular function calls so that extension code is quite readable
+and understandable.
+
+Although all of this sounds somewhat complicated, the result is that
+extension code is quite straightforward to write and to read. You can
+see this in the sample extension @file{filefuncs.c} (@pxref{Extension
+Example}) and also in the @file{testext.c} code for testing the APIs.
+
+Some other bits and pieces:
+
+@itemize @value{BULLET}
+@item
+The API provides access to @command{gawk}'s @code{do_@var{xxx}} values,
+reflecting command-line options, like @code{do_lint}, @code{do_profiling}
+and so on (@pxref{Extension API Variables}).
+These are informational: an extension cannot affect their values
+inside @command{gawk}. In addition, attempting to assign to them
+produces a compile-time error.
+
+@item
+The API also provides major and minor version numbers, so that an
+extension can check if the @command{gawk} it is loaded with supports the
+facilities it was compiled with. (Version mismatches ``shouldn't''
+happen, but we all know how @emph{that} goes.)
+@DBXREF{Extension Versioning} for details.
+@end itemize
+
+@node Extension API Description
+@section API Description
+@cindex extension API
+
+C or C++ code for an extension must include the header file
+@file{gawkapi.h}, which declares the functions and defines the data
+types used to communicate with @command{gawk}.
+This (rather large) @value{SECTION} describes the API in detail.
+
+@menu
+* Extension API Functions Introduction:: Introduction to the API functions.
+* General Data Types:: The data types.
+* Memory Allocation Functions:: Functions for allocating memory.
+* Constructor Functions:: Functions for creating values.
+* Registration Functions:: Functions to register things with
+ @command{gawk}.
+* Printing Messages:: Functions for printing messages.
+* Updating @code{ERRNO}:: Functions for updating @code{ERRNO}.
+* Requesting Values:: How to get a value.
+* Accessing Parameters:: Functions for accessing parameters.
+* Symbol Table Access:: Functions for accessing global
+ variables.
+* Array Manipulation:: Functions for working with arrays.
+* Extension API Variables:: Variables provided by the API.
+* Extension API Boilerplate:: Boilerplate code for using the API.
+@end menu
+
+@node Extension API Functions Introduction
+@subsection Introduction
+
+Access to facilities within @command{gawk} are made available
+by calling through function pointers passed into your extension.
+
+API function pointers are provided for the following kinds of operations:
+
+@itemize @value{BULLET}
+@item
+Allocating, reallocating, and releasing memory.
+
+@item
+Registration functions. You may register:
+
+@c nested list
+@itemize @value{MINUS}
+@item
+Extension functions
+@item
+Exit callbacks
+@item
+A version string
+@item
+Input parsers
+@item
+Output wrappers
+@item
+Two-way processors
+@end itemize
+
+All of these are discussed in detail, later in this @value{CHAPTER}.
+
+@item
+Printing fatal, warning, and ``lint'' warning messages.
+
+@item
+Updating @code{ERRNO}, or unsetting it.
+
+@item
+Accessing parameters, including converting an undefined parameter into
+an array.
+
+@item
+Symbol table access: retrieving a global variable, creating one,
+or changing one.
+
+@item
+Creating and releasing cached values; this provides an
+efficient way to use values for multiple variables and
+can be a big performance win.
+
+@item
+Manipulating arrays:
+
+@itemize @value{MINUS}
+@item
+Retrieving, adding, deleting, and modifying elements
+
+@item
+Getting the count of elements in an array
+
+@item
+Creating a new array
+
+@item
+Clearing an array
+
+@item
+Flattening an array for easy C style looping over all its indices and elements
+@end itemize
+@end itemize
+
+Some points about using the API:
+
+@itemize @value{BULLET}
+@item
+The following types, macros, and/or functions are referenced
+in @file{gawkapi.h}. For correct use, you must therefore include the
+corresponding standard header file @emph{before} including @file{gawkapi.h}:
+
+@multitable {@code{memset()}, @code{memcpy()}} {@code{<sys/types.h>}}
+@headitem C Entity @tab Header File
+@item @code{EOF} @tab @code{<stdio.h>}
+@item Values for @code{errno} @tab @code{<errno.h>}
+@item @code{FILE} @tab @code{<stdio.h>}
+@item @code{NULL} @tab @code{<stddef.h>}
+@item @code{memcpy()} @tab @code{<string.h>}
+@item @code{memset()} @tab @code{<string.h>}
+@item @code{size_t} @tab @code{<sys/types.h>}
+@item @code{struct stat} @tab @code{<sys/stat.h>}
+@end multitable
+
+Due to portability concerns, especially to systems that are not
+fully standards-compliant, it is your responsibility
+to include the correct files in the correct way. This requirement
+is necessary in order to keep @file{gawkapi.h} clean, instead of becoming
+a portability hodge-podge as can be seen in some parts of
+the @command{gawk} source code.
+
+@item
+The @file{gawkapi.h} file may be included more than once without ill effect.
+Doing so, however, is poor coding practice.
+
+@item
+Although the API only uses ISO C 90 features, there is an exception; the
+``constructor'' functions use the @code{inline} keyword. If your compiler
+does not support this keyword, you should either place
+@samp{-Dinline=''} on your command line, or use the GNU Autotools and include a
+@file{config.h} file in your extensions.
+
+@item
+All pointers filled in by @command{gawk} point to memory
+managed by @command{gawk} and should be treated by the extension as
+read-only. Memory for @emph{all} strings passed into @command{gawk}
+from the extension @emph{must} come from calling one of
+@code{gawk_malloc()}, @code{gawk_calloc()} or @code{gawk_realloc()},
+and is managed by @command{gawk} from then on.
+
+@item
+The API defines several simple @code{struct}s that map values as seen
+from @command{awk}. A value can be a @code{double}, a string, or an
+array (as in multidimensional arrays, or when creating a new array).
+String values maintain both pointer and length, because embedded @sc{nul}
+characters are allowed.
+
+@quotation NOTE
+By intent, strings are maintained using the current multibyte encoding (as
+defined by @env{LC_@var{xxx}} environment variables) and not using wide
+characters. This matches how @command{gawk} stores strings internally
+and also how characters are likely to be input and output from files.
+@end quotation
+
+@item
+When retrieving a value (such as a parameter or that of a global variable
+or array element), the extension requests a specific type (number, string,
+scalar, value cookie, array, or ``undefined''). When the request is
+``undefined,'' the returned value will have the real underlying type.
+
+However, if the request and actual type don't match, the access function
+returns ``false'' and fills in the type of the actual value that is there,
+so that the extension can, e.g., print an error message
+(such as ``scalar passed where array expected'').
+
+@c This is documented in the header file and needs some expanding upon.
+@c The table there should be presented here
+@end itemize
+
+You may call the API functions by using the function pointers
+directly, but the interface is not so pretty. To make extension code look
+more like regular code, the @file{gawkapi.h} header file defines several
+macros that you should use in your code. This @value{SECTION} presents
+the macros as if they were functions.
+
+@node General Data Types
+@subsection General-Purpose Data Types
+
+@cindex Robbins, Arnold
+@cindex Ramey, Chet
+@quotation
+@i{I have a true love/hate relationship with unions.}
+@author Arnold Robbins
+@end quotation
+
+@quotation
+@i{That's the thing about unions: the compiler will arrange things so they
+can accommodate both love and hate.}
+@author Chet Ramey
+@end quotation
+
+The extension API defines a number of simple types and structures for
+general-purpose use. Additional, more specialized, data structures are
+introduced in subsequent @value{SECTION}s, together with the functions
+that use them.
+
+@table @code
+@item typedef void *awk_ext_id_t;
+A value of this type is received from @command{gawk} when an extension is loaded.
+That value must then be passed back to @command{gawk} as the first parameter of
+each API function.
+
+@item #define awk_const @dots{}
+This macro expands to @samp{const} when compiling an extension,
+and to nothing when compiling @command{gawk} itself. This makes
+certain fields in the API data structures unwritable from extension code,
+while allowing @command{gawk} to use them as it needs to.
+
+@item typedef enum awk_bool @{
+@itemx @ @ @ @ awk_false = 0,
+@itemx @ @ @ @ awk_true
+@itemx @} awk_bool_t;
+A simple boolean type.
+
+@item typedef struct awk_string @{
+@itemx @ @ @ @ char *str;@ @ @ @ @ @ /* data */
+@itemx @ @ @ @ size_t len;@ @ @ @ @ /* length thereof, in chars */
+@itemx @} awk_string_t;
+This represents a mutable string. @command{gawk}
+owns the memory pointed to if it supplied
+the value. Otherwise, it takes ownership of the memory pointed to.
+@emph{Such memory must come from calling one of the
+@code{gawk_malloc()}, @code{gawk_calloc()}, or
+@code{gawk_realloc()} functions!}
+
+As mentioned earlier, strings are maintained using the current
+multibyte encoding.
+
+@item typedef enum @{
+@itemx @ @ @ @ AWK_UNDEFINED,
+@itemx @ @ @ @ AWK_NUMBER,
+@itemx @ @ @ @ AWK_STRING,
+@itemx @ @ @ @ AWK_ARRAY,
+@itemx @ @ @ @ AWK_SCALAR,@ @ @ @ @ @ @ @ @ /* opaque access to a variable */
+@itemx @ @ @ @ AWK_VALUE_COOKIE@ @ @ @ /* for updating a previously created value */
+@itemx @} awk_valtype_t;
+This @code{enum} indicates the type of a value.
+It is used in the following @code{struct}.
+
+@item typedef struct awk_value @{
+@itemx @ @ @ @ awk_valtype_t val_type;
+@itemx @ @ @ @ union @{
+@itemx @ @ @ @ @ @ @ @ awk_string_t@ @ @ @ @ @ @ s;
+@itemx @ @ @ @ @ @ @ @ double@ @ @ @ @ @ @ @ @ @ @ @ @ d;
+@itemx @ @ @ @ @ @ @ @ awk_array_t@ @ @ @ @ @ @ @ a;
+@itemx @ @ @ @ @ @ @ @ awk_scalar_t@ @ @ @ @ @ @ scl;
+@itemx @ @ @ @ @ @ @ @ awk_value_cookie_t@ vc;
+@itemx @ @ @ @ @} u;
+@itemx @} awk_value_t;
+An ``@command{awk} value.''
+The @code{val_type} member indicates what kind of value the
+@code{union} holds, and each member is of the appropriate type.
+
+@item #define str_value@ @ @ @ @ @ u.s
+@itemx #define num_value@ @ @ @ @ @ u.d
+@itemx #define array_cookie@ @ @ u.a
+@itemx #define scalar_cookie@ @ u.scl
+@itemx #define value_cookie@ @ @ u.vc
+These macros make accessing the fields of the @code{awk_value_t} more
+readable.
+
+@item typedef void *awk_scalar_t;
+Scalars can be represented as an opaque type. These values are obtained
+from @command{gawk} and then passed back into it. This is discussed
+in a general fashion in the text following this list, and in more detail in
+@ref{Symbol table by cookie}.
+
+@item typedef void *awk_value_cookie_t;
+A ``value cookie'' is an opaque type representing a cached value.
+This is also discussed in a general fashion in the text following this list,
+and in more detail in @ref{Cached values}.
+
+@end table
+
+Scalar values in @command{awk} are either numbers or strings. The
+@code{awk_value_t} struct represents values. The @code{val_type} member
+indicates what is in the @code{union}.
+
+Representing numbers is easy---the API uses a C @code{double}. Strings
+require more work. Because @command{gawk} allows embedded @sc{nul} bytes
+in string values, a string must be represented as a pair containing a
+data-pointer and length. This is the @code{awk_string_t} type.
+
+Identifiers (i.e., the names of global variables) can be associated
+with either scalar values or with arrays. In addition, @command{gawk}
+provides true arrays of arrays, where any given array element can
+itself be an array. Discussion of arrays is delayed until
+@ref{Array Manipulation}.
+
+The various macros listed earlier make it easier to use the elements
+of the @code{union} as if they were fields in a @code{struct}; this
+is a common coding practice in C. Such code is easier to write and to
+read, but it remains @emph{your} responsibility to make sure that
+the @code{val_type} member correctly reflects the type of the value in
+the @code{awk_value_t}.
+
+Conceptually, the first three members of the @code{union} (number, string,
+and array) are all that is needed for working with @command{awk} values.
+However, because the API provides routines for accessing and changing
+the value of global scalar variables only by using the variable's name,
+there is a performance penalty: @command{gawk} must find the variable
+each time it is accessed and changed. This turns out to be a real issue,
+not just a theoretical one.
+
+Thus, if you know that your extension will spend considerable time
+reading and/or changing the value of one or more scalar variables, you
+can obtain a @dfn{scalar cookie}@footnote{See
+@uref{http://catb.org/jargon/html/C/cookie.html, the ``cookie'' entry in the Jargon file} for a
+definition of @dfn{cookie}, and @uref{http://catb.org/jargon/html/M/magic-cookie.html,
+the ``magic cookie'' entry in the Jargon file} for a nice example.
+@ifclear FOR_PRINT
+See also the entry for ``Cookie'' in the @ref{Glossary}.
+@end ifclear
+}
+object for that variable, and then use
+the cookie for getting the variable's value or for changing the variable's
+value.
+This is the @code{awk_scalar_t} type and @code{scalar_cookie} macro.
+Given a scalar cookie, @command{gawk} can directly retrieve or
+modify the value, as required, without having to find it first.
+
+The @code{awk_value_cookie_t} type and @code{value_cookie} macro are similar.
+If you know that you wish to
+use the same numeric or string @emph{value} for one or more variables,
+you can create the value once, retaining a @dfn{value cookie} for it,
+and then pass in that value cookie whenever you wish to set the value of a
+variable. This saves both storage space within the running @command{gawk}
+process as well as the time needed to create the value.
+
+@node Memory Allocation Functions
+@subsection Memory Allocation Functions and Convenience Macros
+@cindex allocating memory for extensions
+@cindex extensions, allocating memory
+
+The API provides a number of @dfn{memory allocation} functions for
+allocating memory that can be passed to @command{gawk}, as well as a number of
+convenience macros.
+This @value{SUBSECTION} presents them all as function prototypes, in
+the way that extension code would use them:
+
+@table @code
+@item void *gawk_malloc(size_t size);
+Call the correct version of @code{malloc()} to allocate storage that may
+be passed to @command{gawk}.
+
+@item void *gawk_calloc(size_t nmemb, size_t size);
+Call the correct version of @code{calloc()} to allocate storage that may
+be passed to @command{gawk}.
+
+@item void *gawk_realloc(void *ptr, size_t size);
+Call the correct version of @code{realloc()} to allocate storage that may
+be passed to @command{gawk}.
+
+@item void gawk_free(void *ptr);
+Call the correct version of @code{free()} to release storage that was
+allocated with @code{gawk_malloc()}, @code{gawk_calloc()} or @code{gawk_realloc()}.
+@end table
+
+The API has to provide these functions because it is possible
+for an extension to be compiled and linked against a different
+version of the C library than was used for the @command{gawk}
+executable.@footnote{This is more common on MS-Windows systems, but
+can happen on Unix-like systems as well.} If @command{gawk} were
+to use its version of @code{free()} when the memory came from an
+unrelated version of @code{malloc()}, unexpected behavior would
+likely result.
+
+Two convenience macros may be used for allocating storage
+from @code{gawk_malloc()} and
+@code{gawk_realloc()}. If the allocation fails, they cause @command{gawk}
+to exit with a fatal error message. They should be used as if they were
+procedure calls that do not return a value.
+
+@table @code
+@item #define emalloc(pointer, type, size, message) @dots{}
+The arguments to this macro are as follows:
+
+@c nested table
+@table @code
+@item pointer
+The pointer variable to point at the allocated storage.
+
+@item type
+The type of the pointer variable. This is used to create a cast for
+the call to @code{gawk_malloc()}.
+
+@item size
+The total number of bytes to be allocated.
+
+@item message
+A message to be prefixed to the fatal error message. Typically this is the name
+of the function using the macro.
+@end table
+
+@noindent
+For example, you might allocate a string value like so:
+
+@example
+awk_value_t result;
+char *message;
+const char greet[] = "Don't Panic!";
+
+emalloc(message, char *, sizeof(greet), "myfunc");
+strcpy(message, greet);
+make_malloced_string(message, strlen(message), & result);
+@end example
+
+@item #define erealloc(pointer, type, size, message) @dots{}
+This is like @code{emalloc()}, but it calls @code{gawk_realloc()},
+instead of @code{gawk_malloc()}.
+The arguments are the same as for the @code{emalloc()} macro.
+@end table
+
+@node Constructor Functions
+@subsection Constructor Functions
+
+The API provides a number of @dfn{constructor} functions for creating
+string and numeric values, as well as a number of convenience macros.
+This @value{SUBSECTION} presents them all as function prototypes, in
+the way that extension code would use them:
+
+@table @code
+@item static inline awk_value_t *
+@itemx make_const_string(const char *string, size_t length, awk_value_t *result)
+This function creates a string value in the @code{awk_value_t} variable
+pointed to by @code{result}. It expects @code{string} to be a C string constant
+(or other string data), and automatically creates a @emph{copy} of the data
+for storage in @code{result}. It returns @code{result}.
+
+@item static inline awk_value_t *
+@itemx make_malloced_string(const char *string, size_t length, awk_value_t *result)
+This function creates a string value in the @code{awk_value_t} variable
+pointed to by @code{result}. It expects @code{string} to be a @samp{char *}
+value pointing to data previously obtained from @code{gawk_malloc()}, @code{gawk_calloc()} or @code{gawk_realloc()}. The idea here
+is that the data is passed directly to @command{gawk}, which assumes
+responsibility for it. It returns @code{result}.
+
+@item static inline awk_value_t *
+@itemx make_null_string(awk_value_t *result)
+This specialized function creates a null string (the ``undefined'' value)
+in the @code{awk_value_t} variable pointed to by @code{result}.
+It returns @code{result}.
+
+@item static inline awk_value_t *
+@itemx make_number(double num, awk_value_t *result)
+This function simply creates a numeric value in the @code{awk_value_t} variable
+pointed to by @code{result}.
+@end table
+
+@node Registration Functions
+@subsection Registration Functions
+@cindex register extension
+@cindex extension registration
+
+This @value{SECTION} describes the API functions for
+registering parts of your extension with @command{gawk}.
+
+@menu
+* Extension Functions:: Registering extension functions.
+* Exit Callback Functions:: Registering an exit callback.
+* Extension Version String:: Registering a version string.
+* Input Parsers:: Registering an input parser.
+* Output Wrappers:: Registering an output wrapper.
+* Two-way processors:: Registering a two-way processor.
+@end menu
+
+@node Extension Functions
+@subsubsection Registering An Extension Function
+
+Extension functions are described by the following record:
+
+@example
+typedef struct awk_ext_func @{
+@ @ @ @ const char *name;
+@ @ @ @ awk_value_t *(*function)(int num_actual_args, awk_value_t *result);
+@ @ @ @ size_t num_expected_args;
+@} awk_ext_func_t;
+@end example
+
+The fields are:
+
+@table @code
+@item const char *name;
+The name of the new function.
+@command{awk} level code calls the function by this name.
+This is a regular C string.
+
+Function names must obey the rules for @command{awk}
+identifiers. That is, they must begin with either an English letter
+or an underscore, which may be followed by any number of
+letters, digits, and underscores.
+Letter case in function names is significant.
+
+@item awk_value_t *(*function)(int num_actual_args, awk_value_t *result);
+This is a pointer to the C function that provides the extension's
+functionality.
+The function must fill in @code{*result} with either a number
+or a string. @command{gawk} takes ownership of any string memory.
+As mentioned earlier, string memory @strong{must} come from one of
+@code{gawk_malloc()}, @code{gawk_calloc()}, or @code{gawk_realloc()}.
+
+The @code{num_actual_args} argument tells the C function how many
+actual parameters were passed from the calling @command{awk} code.
+
+The function must return the value of @code{result}.
+This is for the convenience of the calling code inside @command{gawk}.
+
+@item size_t num_expected_args;
+This is the number of arguments the function expects to receive.
+Each extension function may decide what to do if the number of
+arguments isn't what it expected. As with real @command{awk} functions, it
+is likely OK to ignore extra arguments.
+@end table
+
+Once you have a record representing your extension function, you register
+it with @command{gawk} using this API function:
+
+@table @code
+@item awk_bool_t add_ext_func(const char *namespace, const awk_ext_func_t *func);
+This function returns true upon success, false otherwise.
+The @code{namespace} parameter is currently not used; you should pass in an
+empty string (@code{""}). The @code{func} pointer is the address of a
+@code{struct} representing your function, as just described.
+@end table
+
+@node Exit Callback Functions
+@subsubsection Registering An Exit Callback Function
+
+An @dfn{exit callback} function is a function that
+@command{gawk} calls before it exits.
+Such functions are useful if you have general ``cleanup'' tasks
+that should be performed in your extension (such as closing database
+connections or other resource deallocations).
+You can register such
+a function with @command{gawk} using the following function:
+
+@table @code
+@item void awk_atexit(void (*funcp)(void *data, int exit_status),
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ void *arg0);
+The parameters are:
+
+@c nested table
+@table @code
+@item funcp
+A pointer to the function to be called before @command{gawk} exits. The @code{data}
+parameter will be the original value of @code{arg0}.
+The @code{exit_status} parameter is the exit status value that
+@command{gawk} intends to pass to the @code{exit()} system call.
+
+@item arg0
+A pointer to private data which @command{gawk} saves in order to pass to
+the function pointed to by @code{funcp}.
+@end table
+@end table
+
+Exit callback functions are called in last-in-first-out (LIFO)
+order---that is, in the reverse order in which they are registered with
+@command{gawk}.
+
+@node Extension Version String
+@subsubsection Registering An Extension Version String
+
+You can register a version string which indicates the name and
+version of your extension, with @command{gawk}, as follows:
+
+@table @code
+@item void register_ext_version(const char *version);
+Register the string pointed to by @code{version} with @command{gawk}.
+Note that @command{gawk} does @emph{not} copy the @code{version} string, so
+it should not be changed.
+@end table
+
+@command{gawk} prints all registered extension version strings when it
+is invoked with the @option{--version} option.
+
+@node Input Parsers
+@subsubsection Customized Input Parsers
+@cindex customized input parser
+
+By default, @command{gawk} reads text files as its input. It uses the value
+of @code{RS} to find the end of the record, and then uses @code{FS}
+(or @code{FIELDWIDTHS} or @code{FPAT}) to split it into fields (@pxref{Reading Files}).
+Additionally, it sets the value of @code{RT} (@pxref{Built-in Variables}).
+
+If you want, you can provide your own custom input parser. An input
+parser's job is to return a record to the @command{gawk} record processing
+code, along with indicators for the value and length of the data to be
+used for @code{RT}, if any.
+
+To provide an input parser, you must first provide two functions
+(where @var{XXX} is a prefix name for your extension):
+
+@table @code
+@item awk_bool_t @var{XXX}_can_take_file(const awk_input_buf_t *iobuf);
+This function examines the information available in @code{iobuf}
+(which we discuss shortly). Based on the information there, it
+decides if the input parser should be used for this file.
+If so, it should return true. Otherwise, it should return false.
+It should not change any state (variable values, etc.) within @command{gawk}.
+
+@item awk_bool_t @var{XXX}_take_control_of(awk_input_buf_t *iobuf);
+When @command{gawk} decides to hand control of the file over to the
+input parser, it calls this function. This function in turn must fill
+in certain fields in the @code{awk_input_buf_t} structure, and ensure
+that certain conditions are true. It should then return true. If an
+error of some kind occurs, it should not fill in any fields, and should
+return false; then @command{gawk} will not use the input parser.
+The details are presented shortly.
+@end table
+
+Your extension should package these functions inside an
+@code{awk_input_parser_t}, which looks like this:
+
+@example
+typedef struct awk_input_parser @{
+ const char *name; /* name of parser */
+ awk_bool_t (*can_take_file)(const awk_input_buf_t *iobuf);
+ awk_bool_t (*take_control_of)(awk_input_buf_t *iobuf);
+ awk_const struct awk_input_parser *awk_const next; /* for gawk */
+@} awk_input_parser_t;
+@end example
+
+The fields are:
+
+@table @code
+@item const char *name;
+The name of the input parser. This is a regular C string.
+
+@item awk_bool_t (*can_take_file)(const awk_input_buf_t *iobuf);
+A pointer to your @code{@var{XXX}_can_take_file()} function.
+
+@item awk_bool_t (*take_control_of)(awk_input_buf_t *iobuf);
+A pointer to your @code{@var{XXX}_take_control_of()} function.
+
+@item awk_const struct input_parser *awk_const next;
+This is for use by @command{gawk};
+therefore it is marked @code{awk_const} so that the extension cannot
+modify it.
+@end table
+
+The steps are as follows:
+
+@enumerate
+@item
+Create a @code{static awk_input_parser_t} variable and initialize it
+appropriately.
+
+@item
+When your extension is loaded, register your input parser with
+@command{gawk} using the @code{register_input_parser()} API function
+(described next).
+@end enumerate
+
+An @code{awk_input_buf_t} looks like this:
+
+@example
+typedef struct awk_input @{
+ const char *name; /* filename */
+ int fd; /* file descriptor */
+#define INVALID_HANDLE (-1)
+ void *opaque; /* private data for input parsers */
+ int (*get_record)(char **out, struct awk_input *iobuf,
+ int *errcode, char **rt_start, size_t *rt_len);
+ ssize_t (*read_func)();
+ void (*close_func)(struct awk_input *iobuf);
+ struct stat sbuf; /* stat buf */
+@} awk_input_buf_t;
+@end example
+
+The fields can be divided into two categories: those for use (initially,
+at least) by @code{@var{XXX}_can_take_file()}, and those for use by
+@code{@var{XXX}_take_control_of()}. The first group of fields and their uses
+are as follows:
+
+@table @code
+@item const char *name;
+The name of the file.
+
+@item int fd;
+A file descriptor for the file. If @command{gawk} was able to
+open the file, then @code{fd} will @emph{not} be equal to
+@code{INVALID_HANDLE}. Otherwise, it will.
+
+@item struct stat sbuf;
+If the file descriptor is valid, then @command{gawk} will have filled
+in this structure via a call to the @code{fstat()} system call.
+@end table
+
+The @code{@var{XXX}_can_take_file()} function should examine these
+fields and decide if the input parser should be used for the file.
+The decision can be made based upon @command{gawk} state (the value
+of a variable defined previously by the extension and set by
+@command{awk} code), the name of the
+file, whether or not the file descriptor is valid, the information
+in the @code{struct stat}, or any combination of these factors.
+
+Once @code{@var{XXX}_can_take_file()} has returned true, and
+@command{gawk} has decided to use your input parser, it calls
+@code{@var{XXX}_take_control_of()}. That function then fills one of
+either the @code{get_record} field or the @code{read_func} field in
+the @code{awk_input_buf_t}. It must also ensure that @code{fd} is @emph{not}
+set to @code{INVALID_HANDLE}. The following list describes the fields that
+may be filled by @code{@var{XXX}_take_control_of()}:
+
+@table @code
+@item void *opaque;
+This is used to hold any state information needed by the input parser
+for this file. It is ``opaque'' to @command{gawk}. The input parser
+is not required to use this pointer.
+
+@item int@ (*get_record)(char@ **out,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ struct@ awk_input *iobuf,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ int *errcode,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ char **rt_start,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ size_t *rt_len);
+This function pointer should point to a function that creates the input
+records. Said function is the core of the input parser. Its behavior
+is described in the text following this list.
+
+@item ssize_t (*read_func)();
+This function pointer should point to function that has the
+same behavior as the standard POSIX @code{read()} system call.
+It is an alternative to the @code{get_record} pointer. Its behavior
+is also described in the text following this list.
+
+@item void (*close_func)(struct awk_input *iobuf);
+This function pointer should point to a function that does
+the ``tear down.'' It should release any resources allocated by
+@code{@var{XXX}_take_control_of()}. It may also close the file. If it
+does so, it should set the @code{fd} field to @code{INVALID_HANDLE}.
+
+If @code{fd} is still not @code{INVALID_HANDLE} after the call to this
+function, @command{gawk} calls the regular @code{close()} system call.
+
+Having a ``tear down'' function is optional. If your input parser does
+not need it, do not set this field. Then, @command{gawk} calls the
+regular @code{close()} system call on the file descriptor, so it should
+be valid.
+@end table
+
+The @code{@var{XXX}_get_record()} function does the work of creating
+input records. The parameters are as follows:
+
+@table @code
+@item char **out
+This is a pointer to a @code{char *} variable which is set to point
+to the record. @command{gawk} makes its own copy of the data, so
+the extension must manage this storage.
+
+@item struct awk_input *iobuf
+This is the @code{awk_input_buf_t} for the file. The fields should be
+used for reading data (@code{fd}) and for managing private state
+(@code{opaque}), if any.
+
+@item int *errcode
+If an error occurs, @code{*errcode} should be set to an appropriate
+code from @code{<errno.h>}.
+
+@item char **rt_start
+@itemx size_t *rt_len
+If the concept of a ``record terminator'' makes sense, then
+@code{*rt_start} should be set to point to the data to be used for
+@code{RT}, and @code{*rt_len} should be set to the length of the
+data. Otherwise, @code{*rt_len} should be set to zero.
+@code{gawk} makes its own copy of this data, so the
+extension must manage this storage.
+@end table
+
+The return value is the length of the buffer pointed to by
+@code{*out}, or @code{EOF} if end-of-file was reached or an
+error occurred.
+
+It is guaranteed that @code{errcode} is a valid pointer, so there is no
+need to test for a @code{NULL} value. @command{gawk} sets @code{*errcode}
+to zero, so there is no need to set it unless an error occurs.
+
+If an error does occur, the function should return @code{EOF} and set
+@code{*errcode} to a value greater than zero. In that case, if @code{*errcode}
+does not equal zero, @command{gawk} automatically updates
+the @code{ERRNO} variable based on the value of @code{*errcode}.
+(In general, setting @samp{*errcode = errno} should do the right thing.)
+
+As an alternative to supplying a function that returns an input record,
+you may instead supply a function that simply reads bytes, and let
+@command{gawk} parse the data into records. If you do so, the data
+should be returned in the multibyte encoding of the current locale.
+Such a function should follow the same behavior as the @code{read()}
+system call, and you fill in the @code{read_func} pointer with its
+address in the @code{awk_input_buf_t} structure.
+
+By default, @command{gawk} sets the @code{read_func} pointer to
+point to the @code{read()} system call. So your extension need not
+set this field explicitly.
+
+@quotation NOTE
+You must choose one method or the other: either a function that
+returns a record, or one that returns raw data. In particular,
+if you supply a function to get a record, @command{gawk} will
+call it, and never call the raw read function.
+@end quotation
+
+@command{gawk} ships with a sample extension that reads directories,
+returning records for each entry in the directory (@pxref{Extension
+Sample Readdir}). You may wish to use that code as a guide for writing
+your own input parser.
+
+When writing an input parser, you should think about (and document)
+how it is expected to interact with @command{awk} code. You may want
+it to always be called, and take effect as appropriate (as the
+@code{readdir} extension does). Or you may want it to take effect
+based upon the value of an @code{awk} variable, as the XML extension
+from the @code{gawkextlib} project does (@pxref{gawkextlib}).
+In the latter case, code in a @code{BEGINFILE} section
+can look at @code{FILENAME} and @code{ERRNO} to decide whether or
+not to activate an input parser (@pxref{BEGINFILE/ENDFILE}).
+
+You register your input parser with the following function:
+
+@table @code
+@item void register_input_parser(awk_input_parser_t *input_parser);
+Register the input parser pointed to by @code{input_parser} with
+@command{gawk}.
+@end table
+
+@node Output Wrappers
+@subsubsection Customized Output Wrappers
+@cindex customized output wrapper
+
+@cindex output wrapper
+An @dfn{output wrapper} is the mirror image of an input parser.
+It allows an extension to take over the output to a file opened
+with the @samp{>} or @samp{>>} I/O redirection operators (@pxref{Redirection}).
+
+The output wrapper is very similar to the input parser structure:
+
+@example
+typedef struct awk_output_wrapper @{
+ const char *name; /* name of the wrapper */
+ awk_bool_t (*can_take_file)(const awk_output_buf_t *outbuf);
+ awk_bool_t (*take_control_of)(awk_output_buf_t *outbuf);
+ awk_const struct awk_output_wrapper *awk_const next; /* for gawk */
+@} awk_output_wrapper_t;
+@end example
+
+The members are as follows:
+
+@table @code
+@item const char *name;
+This is the name of the output wrapper.
+
+@item awk_bool_t (*can_take_file)(const awk_output_buf_t *outbuf);
+This points to a function that examines the information in
+the @code{awk_output_buf_t} structure pointed to by @code{outbuf}.
+It should return true if the output wrapper wants to take over the
+file, and false otherwise. It should not change any state (variable
+values, etc.) within @command{gawk}.
+
+@item awk_bool_t (*take_control_of)(awk_output_buf_t *outbuf);
+The function pointed to by this field is called when @command{gawk}
+decides to let the output wrapper take control of the file. It should
+fill in appropriate members of the @code{awk_output_buf_t} structure,
+as described next, and return true if successful, false otherwise.
+
+@item awk_const struct output_wrapper *awk_const next;
+This is for use by @command{gawk};
+therefore it is marked @code{awk_const} so that the extension cannot
+modify it.
+@end table
+
+The @code{awk_output_buf_t} structure looks like this:
+
+@example
+typedef struct awk_output_buf @{
+ const char *name; /* name of output file */
+ const char *mode; /* mode argument to fopen */
+ FILE *fp; /* stdio file pointer */
+ awk_bool_t redirected; /* true if a wrapper is active */
+ void *opaque; /* for use by output wrapper */
+ size_t (*gawk_fwrite)(const void *buf, size_t size, size_t count,
+ FILE *fp, void *opaque);
+ int (*gawk_fflush)(FILE *fp, void *opaque);
+ int (*gawk_ferror)(FILE *fp, void *opaque);
+ int (*gawk_fclose)(FILE *fp, void *opaque);
+@} awk_output_buf_t;
+@end example
+
+Here too, your extension will define @code{@var{XXX}_can_take_file()}
+and @code{@var{XXX}_take_control_of()} functions that examine and update
+data members in the @code{awk_output_buf_t}.
+The data members are as follows:
+
+@table @code
+@item const char *name;
+The name of the output file.
+
+@item const char *mode;
+The mode string (as would be used in the second argument to @code{fopen()})
+with which the file was opened.
+
+@item FILE *fp;
+The @code{FILE} pointer from @code{<stdio.h>}. @command{gawk} opens the file
+before attempting to find an output wrapper.
+
+@item awk_bool_t redirected;
+This field must be set to true by the @code{@var{XXX}_take_control_of()} function.
+
+@item void *opaque;
+This pointer is opaque to @command{gawk}. The extension should use it to store
+a pointer to any private data associated with the file.
+
+@item size_t (*gawk_fwrite)(const void *buf, size_t size, size_t count,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ FILE *fp, void *opaque);
+@itemx int (*gawk_fflush)(FILE *fp, void *opaque);
+@itemx int (*gawk_ferror)(FILE *fp, void *opaque);
+@itemx int (*gawk_fclose)(FILE *fp, void *opaque);
+These pointers should be set to point to functions that perform
+the equivalent function as the @code{<stdio.h>} functions do, if appropriate.
+@command{gawk} uses these function pointers for all output.
+@command{gawk} initializes the pointers to point to internal, ``pass through''
+functions that just call the regular @code{<stdio.h>} functions, so an
+extension only needs to redefine those functions that are appropriate for
+what it does.
+@end table
+
+The @code{@var{XXX}_can_take_file()} function should make a decision based
+upon the @code{name} and @code{mode} fields, and any additional state
+(such as @command{awk} variable values) that is appropriate.
+
+When @command{gawk} calls @code{@var{XXX}_take_control_of()}, that function should fill
+in the other fields, as appropriate, except for @code{fp}, which it should just
+use normally.
+
+You register your output wrapper with the following function:
+
+@table @code
+@item void register_output_wrapper(awk_output_wrapper_t *output_wrapper);
+Register the output wrapper pointed to by @code{output_wrapper} with
+@command{gawk}.
+@end table
+
+@node Two-way processors
+@subsubsection Customized Two-way Processors
+@cindex customized two-way processor
+
+A @dfn{two-way processor} combines an input parser and an output wrapper for
+two-way I/O with the @samp{|&} operator (@pxref{Redirection}). It makes identical
+use of the @code{awk_input_parser_t} and @code{awk_output_buf_t} structures
+as described earlier.
+
+A two-way processor is represented by the following structure:
+
+@example
+typedef struct awk_two_way_processor @{
+ const char *name; /* name of the two-way processor */
+ awk_bool_t (*can_take_two_way)(const char *name);
+ awk_bool_t (*take_control_of)(const char *name,
+ awk_input_buf_t *inbuf,
+ awk_output_buf_t *outbuf);
+ awk_const struct awk_two_way_processor *awk_const next; /* for gawk */
+@} awk_two_way_processor_t;
+@end example
+
+The fields are as follows:
+
+@table @code
+@item const char *name;
+The name of the two-way processor.
+
+@item awk_bool_t (*can_take_two_way)(const char *name);
+This function returns true if it wants to take over two-way I/O for this @value{FN}.
+It should not change any state (variable
+values, etc.) within @command{gawk}.
+
+@item awk_bool_t (*take_control_of)(const char *name,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_input_buf_t *inbuf,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_output_buf_t *outbuf);
+This function should fill in the @code{awk_input_buf_t} and
+@code{awk_outut_buf_t} structures pointed to by @code{inbuf} and
+@code{outbuf}, respectively. These structures were described earlier.
+
+@item awk_const struct two_way_processor *awk_const next;
+This is for use by @command{gawk};
+therefore it is marked @code{awk_const} so that the extension cannot
+modify it.
+@end table
+
+As with the input parser and output processor, you provide
+``yes I can take this'' and ``take over for this'' functions,
+@code{@var{XXX}_can_take_two_way()} and @code{@var{XXX}_take_control_of()}.
+
+You register your two-way processor with the following function:
+
+@table @code
+@item void register_two_way_processor(awk_two_way_processor_t *two_way_processor);
+Register the two-way processor pointed to by @code{two_way_processor} with
+@command{gawk}.
+@end table
+
+@node Printing Messages
+@subsection Printing Messages
+@cindex printing messages from extensions
+@cindex messages from extensions
+
+You can print different kinds of warning messages from your
+extension, as described here. Note that for these functions,
+you must pass in the extension id received from @command{gawk}
+when the extension was loaded:@footnote{Because the API uses only ISO C 90
+features, it cannot make use of the ISO C 99 variadic macro feature to hide
+that parameter. More's the pity.}
+
+@table @code
+@item void fatal(awk_ext_id_t id, const char *format, ...);
+Print a message and then cause @command{gawk} to exit immediately.
+
+@item void warning(awk_ext_id_t id, const char *format, ...);
+Print a warning message.
+
+@item void lintwarn(awk_ext_id_t id, const char *format, ...);
+Print a ``lint warning.'' Normally this is the same as printing a
+warning message, but if @command{gawk} was invoked with @samp{--lint=fatal},
+then lint warnings become fatal error messages.
+@end table
+
+All of these functions are otherwise like the C @code{printf()}
+family of functions, where the @code{format} parameter is a string
+with literal characters and formatting codes intermixed.
+
+@node Updating @code{ERRNO}
+@subsection Updating @code{ERRNO}
+
+The following functions allow you to update the @code{ERRNO}
+variable:
+
+@table @code
+@item void update_ERRNO_int(int errno_val);
+Set @code{ERRNO} to the string equivalent of the error code
+in @code{errno_val}. The value should be one of the defined
+error codes in @code{<errno.h>}, and @command{gawk} turns it
+into a (possibly translated) string using the C @code{strerror()} function.
+
+@item void update_ERRNO_string(const char *string);
+Set @code{ERRNO} directly to the string value of @code{ERRNO}.
+@command{gawk} makes a copy of the value of @code{string}.
+
+@item void unset_ERRNO(void);
+Unset @code{ERRNO}.
+@end table
+
+@node Requesting Values
+@subsection Requesting Values
+
+All of the functions that return values from @command{gawk}
+work in the same way. You pass in an @code{awk_valtype_t} value
+to indicate what kind of value you expect. If the actual value
+matches what you requested, the function returns true and fills
+in the @code{awk_value_t} result.
+Otherwise, the function returns false, and the @code{val_type}
+member indicates the type of the actual value. You may then
+print an error message, or reissue the request for the actual
+value type, as appropriate. This behavior is summarized in
+@ref{table-value-types-returned}.
+
+@float Table,table-value-types-returned
+@caption{API value types returned}
+@docbook
+<informaltable>
+<tgroup cols="6">
+ <colspec colwidth="16.6*"/>
+ <colspec colwidth="16.6*"/>
+ <colspec colwidth="19.8*" colname="c3"/>
+ <colspec colwidth="15*" colname="c4"/>
+ <colspec colwidth="15*" colname="c5"/>
+ <colspec colwidth="16.6*" colname="c6"/>
+ <spanspec spanname="hspan" namest="c3" nameend="c6" align="center"/>
+ <thead>
+ <row><entry></entry><entry spanname="hspan"><para>Type of Actual Value</para></entry></row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry><para>String</para></entry>
+ <entry><para>Number</para></entry>
+ <entry><para>Array</para></entry>
+ <entry><para>Undefined</para></entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry></entry>
+ <entry><para><emphasis role="bold">String</emphasis></para></entry>
+ <entry><para>String</para></entry>
+ <entry><para>String</para></entry>
+ <entry><para>false</para></entry>
+ <entry><para>false</para></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry><para><emphasis role="bold">Number</emphasis></para></entry>
+ <entry><para>Number if can be converted, else false</para></entry>
+ <entry><para>Number</para></entry>
+ <entry><para>false</para></entry>
+ <entry><para>false</para></entry>
+ </row>
+ <row>
+ <entry><para><emphasis role="bold">Type</emphasis></para></entry>
+ <entry><para><emphasis role="bold">Array</emphasis></para></entry>
+ <entry><para>false</para></entry>
+ <entry><para>false</para></entry>
+ <entry><para>Array</para></entry>
+ <entry><para>false</para></entry>
+ </row>
+ <row>
+ <entry><para><emphasis role="bold">Requested</emphasis></para></entry>
+ <entry><para><emphasis role="bold">Scalar</emphasis></para></entry>
+ <entry><para>Scalar</para></entry>
+ <entry><para>Scalar</para></entry>
+ <entry><para>false</para></entry>
+ <entry><para>false</para></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry><para><emphasis role="bold">Undefined</emphasis></para></entry>
+ <entry><para>String</para></entry>
+ <entry><para>Number</para></entry>
+ <entry><para>Array</para></entry>
+ <entry><para>Undefined</para></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry><para><emphasis role="bold">Value Cookie</emphasis></para></entry>
+ <entry><para>false</para></entry>
+ <entry><para>false</para></entry>
+ <entry><para>false</para>
+ </entry><entry><para>false</para></entry>
+ </row>
+ </tbody>
+</tgroup>
+</informaltable>
+@end docbook
+
+@ifnotplaintext
+@ifnotdocbook
+@multitable @columnfractions .50 .50
+@headitem @tab Type of Actual Value
+@end multitable
+@c 10/2014: Thanks to Karl Berry for this bit to reduce the space:
+@tex
+\vglue-1.1\baselineskip
+@end tex
+@multitable @columnfractions .166 .166 .198 .15 .15 .166
+@headitem @tab @tab String @tab Number @tab Array @tab Undefined
+@item @tab @b{String} @tab String @tab String @tab false @tab false
+@item @tab @b{Number} @tab Number if can be converted, else false @tab Number @tab false @tab false
+@item @b{Type} @tab @b{Array} @tab false @tab false @tab Array @tab false
+@item @b{Requested} @tab @b{Scalar} @tab Scalar @tab Scalar @tab false @tab false
+@item @tab @b{Undefined} @tab String @tab Number @tab Array @tab Undefined
+@item @tab @b{Value Cookie} @tab false @tab false @tab false @tab false
+@end multitable
+@end ifnotdocbook
+@end ifnotplaintext
+@ifplaintext
+@example
+ +-------------------------------------------------+
+ | Type of Actual Value: |
+ +------------+------------+-----------+-----------+
+ | String | Number | Array | Undefined |
++-----------+-----------+------------+------------+-----------+-----------+
+| | String | String | String | false | false |
+| |-----------+------------+------------+-----------+-----------+
+| | Number | Number if | Number | false | false |
+| | | can be | | | |
+| | | converted, | | | |
+| | | else false | | | |
+| |-----------+------------+------------+-----------+-----------+
+| Type | Array | false | false | Array | false |
+| Requested |-----------+------------+------------+-----------+-----------+
+| | Scalar | Scalar | Scalar | false | false |
+| |-----------+------------+------------+-----------+-----------+
+| | Undefined | String | Number | Array | Undefined |
+| |-----------+------------+------------+-----------+-----------+
+| | Value | false | false | false | false |
+| | Cookie | | | | |
++-----------+-----------+------------+------------+-----------+-----------+
+@end example
+@end ifplaintext
+@end float
+
+@node Accessing Parameters
+@subsection Accessing and Updating Parameters
+
+Two functions give you access to the arguments (parameters)
+passed to your extension function. They are:
+
+@table @code
+@item awk_bool_t get_argument(size_t count,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_valtype_t wanted,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_value_t *result);
+Fill in the @code{awk_value_t} structure pointed to by @code{result}
+with the @code{count}'th argument. Return true if the actual
+type matches @code{wanted}, false otherwise. In the latter
+case, @code{result@w{->}val_type} indicates the actual type
+(@pxref{table-value-types-returned}). Counts are zero based---the first
+argument is numbered zero, the second one, and so on. @code{wanted}
+indicates the type of value expected.
+
+@item awk_bool_t set_argument(size_t count, awk_array_t array);
+Convert a parameter that was undefined into an array; this provides
+call-by-reference for arrays. Return false if @code{count} is too big,
+or if the argument's type is not undefined. @DBXREF{Array Manipulation}
+for more information on creating arrays.
+@end table
+
+@node Symbol Table Access
+@subsection Symbol Table Access
+@cindex accessing global variables from extensions
+
+Two sets of routines provide access to global variables, and one set
+allows you to create and release cached values.
+
+@menu
+* Symbol table by name:: Accessing variables by name.
+* Symbol table by cookie:: Accessing variables by ``cookie''.
+* Cached values:: Creating and using cached values.
+@end menu
+
+@node Symbol table by name
+@subsubsection Variable Access and Update by Name
+
+The following routines provide the ability to access and update
+global @command{awk}-level variables by name. In compiler terminology,
+identifiers of different kinds are termed @dfn{symbols}, thus the ``sym''
+in the routines' names. The data structure which stores information
+about symbols is termed a @dfn{symbol table}.
+
+@table @code
+@item awk_bool_t sym_lookup(const char *name,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_valtype_t wanted,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_value_t *result);
+Fill in the @code{awk_value_t} structure pointed to by @code{result}
+with the value of the variable named by the string @code{name}, which is
+a regular C string. @code{wanted} indicates the type of value expected.
+Return true if the actual type matches @code{wanted}, false otherwise.
+In the latter case, @code{result->val_type} indicates the actual type
+(@pxref{table-value-types-returned}).
+
+@item awk_bool_t sym_update(const char *name, awk_value_t *value);
+Update the variable named by the string @code{name}, which is a regular
+C string. The variable is added to @command{gawk}'s symbol table
+if it is not there. Return true if everything worked, false otherwise.
+
+Changing types (scalar to array or vice versa) of an existing variable
+is @emph{not} allowed, nor may this routine be used to update an array.
+This routine cannot be used to update any of the predefined
+variables (such as @code{ARGC} or @code{NF}).
+@end table
+
+An extension can look up the value of @command{gawk}'s special variables.
+However, with the exception of the @code{PROCINFO} array, an extension
+cannot change any of those variables.
+
+@quotation CAUTION
+It is possible for the lookup of @code{PROCINFO} to fail. This happens if
+the @command{awk} program being run does not reference @code{PROCINFO};
+in this case, @command{gawk} doesn't bother to create the array and
+populate it.
+@end quotation
+
+@node Symbol table by cookie
+@subsubsection Variable Access and Update by Cookie
+
+A @dfn{scalar cookie} is an opaque handle that provides access
+to a global variable or array. It is an optimization that
+avoids looking up variables in @command{gawk}'s symbol table every time
+access is needed. This was discussed earlier in @ref{General Data Types}.
+
+The following functions let you work with scalar cookies:
+
+@table @code
+@item awk_bool_t sym_lookup_scalar(awk_scalar_t cookie,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_valtype_t wanted,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_value_t *result);
+Retrieve the current value of a scalar cookie.
+Once you have obtained a scalar cookie using @code{sym_lookup()}, you can
+use this function to get its value more efficiently.
+Return false if the value cannot be retrieved.
+
+@item awk_bool_t sym_update_scalar(awk_scalar_t cookie, awk_value_t *value);
+Update the value associated with a scalar cookie. Return false if
+the new value is not of type @code{AWK_STRING} or @code{AWK_NUMBER}.
+Here too, the predefined variables may not be updated.
+@end table
+
+It is not obvious at first glance how to work with scalar cookies or
+what their @i{raison d'@^etre} really is. In theory, the @code{sym_lookup()}
+and @code{sym_update()} routines are all you really need to work with
+variables. For example, you might have code that looks up the value of
+a variable, evaluates a condition, and then possibly changes the value
+of the variable based on the result of that evaluation, like so:
+
+@example
+/* do_magic --- do something really great */
+
+static awk_value_t *
+do_magic(int nargs, awk_value_t *result)
+@{
+ awk_value_t value;
+
+ if ( sym_lookup("MAGIC_VAR", AWK_NUMBER, & value)
+ && some_condition(value.num_value)) @{
+ value.num_value += 42;
+ sym_update("MAGIC_VAR", & value);
+ @}
+
+ return make_number(0.0, result);
+@}
+@end example
+
+@noindent
+This code looks (and is) simple and straightforward. So what's the problem?
+
+Well, consider what happens if @command{awk}-level code associated
+with your extension calls the @code{magic()} function (implemented in
+C by @code{do_magic()}), once per record, while processing hundreds
+of thousands or millions of records. The @code{MAGIC_VAR} variable is
+looked up in the symbol table once or twice per function call!
+
+The symbol table lookup is really pure overhead; it is considerably
+more efficient to get a cookie that represents the variable, and use
+that to get the variable's value and update it as needed.@footnote{The
+difference is measurable and quite real. Trust us.}
+
+Thus, the way to use cookies is as follows. First, install
+your extension's variable in @command{gawk}'s symbol table using
+@code{sym_update()}, as usual. Then get a scalar cookie for the variable
+using @code{sym_lookup()}:
+
+@example
+static awk_scalar_t magic_var_cookie; /* cookie for MAGIC_VAR */
+
+static void
+my_extension_init()
+@{
+ awk_value_t value;
+
+ /* install initial value */
+ sym_update("MAGIC_VAR", make_number(42.0, & value));
+
+ /* get the cookie */
+ sym_lookup("MAGIC_VAR", AWK_SCALAR, & value);
+
+ /* save the cookie */
+ magic_var_cookie = value.scalar_cookie;
+ @dots{}
+@}
+@end example
+
+Next, use the routines in this section for retrieving and updating
+the value through the cookie. Thus, @code{do_magic()} now becomes
+something like this:
+
+@example
+/* do_magic --- do something really great */
+
+static awk_value_t *
+do_magic(int nargs, awk_value_t *result)
+@{
+ awk_value_t value;
+
+ if ( sym_lookup_scalar(magic_var_cookie, AWK_NUMBER, & value)
+ && some_condition(value.num_value)) @{
+ value.num_value += 42;
+ sym_update_scalar(magic_var_cookie, & value);
+ @}
+ @dots{}
+
+ return make_number(0.0, result);
+@}
+@end example
+
+@quotation NOTE
+The previous code omitted error checking for
+presentation purposes. Your extension code should be more robust
+and carefully check the return values from the API functions.
+@end quotation
+
+@node Cached values
+@subsubsection Creating and Using Cached Values
+
+The routines in this section allow you to create and release
+cached values. As with scalar cookies, in theory, cached values
+are not necessary. You can create numbers and strings using
+the functions in @ref{Constructor Functions}. You can then
+assign those values to variables using @code{sym_update()}
+or @code{sym_update_scalar()}, as you like.
+
+However, you can understand the point of cached values if you remember that
+@emph{every} string value's storage @emph{must} come from @code{gawk_malloc()},
+@code{gawk_calloc()}, or @code{gawk_realloc()}.
+If you have 20 variables, all of which have the same string value, you
+must create 20 identical copies of the string.@footnote{Numeric values
+are clearly less problematic, requiring only a C @code{double} to store.}
+
+It is clearly more efficient, if possible, to create a value once, and
+then tell @command{gawk} to reuse the value for multiple variables. That
+is what the routines in this section let you do. The functions are as follows:
+
+@table @code
+@item awk_bool_t create_value(awk_value_t *value, awk_value_cookie_t *result);
+Create a cached string or numeric value from @code{value} for
+efficient later assignment. Only values of type @code{AWK_NUMBER}
+and @code{AWK_STRING} are allowed. Any other type is rejected.
+@code{AWK_UNDEFINED} could be allowed, but doing so would result in
+inferior performance.
+
+@item awk_bool_t release_value(awk_value_cookie_t vc);
+Release the memory associated with a value cookie obtained
+from @code{create_value()}.
+@end table
+
+You use value cookies in a fashion similar to the way you use scalar cookies.
+In the extension initialization routine, you create the value cookie:
+
+@example
+static awk_value_cookie_t answer_cookie; /* static value cookie */
+
+static void
+my_extension_init()
+@{
+ awk_value_t value;
+ char *long_string;
+ size_t long_string_len;
+
+ /* code from earlier */
+ @dots{}
+ /* @dots{} fill in long_string and long_string_len @dots{} */
+ make_malloced_string(long_string, long_string_len, & value);
+ create_value(& value, & answer_cookie); /* create cookie */
+ @dots{}
+@}
+@end example
+
+Once the value is created, you can use it as the value of any number
+of variables:
+
+@example
+static awk_value_t *
+do_magic(int nargs, awk_value_t *result)
+@{
+ awk_value_t new_value;
+
+ @dots{} /* as earlier */
+
+ value.val_type = AWK_VALUE_COOKIE;
+ value.value_cookie = answer_cookie;
+ sym_update("VAR1", & value);
+ sym_update("VAR2", & value);
+ @dots{}
+ sym_update("VAR100", & value);
+ @dots{}
+@}
+@end example
+
+@noindent
+Using value cookies in this way saves considerable storage, as all of
+@code{VAR1} through @code{VAR100} share the same value.
+
+You might be wondering, ``Is this sharing problematic?
+What happens if @command{awk} code assigns a new value to @code{VAR1},
+are all the others changed too?''
+
+That's a great question. The answer is that no, it's not a problem.
+Internally, @command{gawk} uses @dfn{reference-counted strings}. This means
+that many variables can share the same string value, and @command{gawk}
+keeps track of the usage. When a variable's value changes, @command{gawk}
+simply decrements the reference count on the old value and updates
+the variable to use the new value.
+
+Finally, as part of your cleanup action (@pxref{Exit Callback Functions})
+you should release any cached values that you created, using
+@code{release_value()}.
+
+@node Array Manipulation
+@subsection Array Manipulation
+@cindex array manipulation in extensions
+
+The primary data structure@footnote{OK, the only data structure.} in @command{awk}
+is the associative array (@pxref{Arrays}).
+Extensions need to be able to manipulate @command{awk} arrays.
+The API provides a number of data structures for working with arrays,
+functions for working with individual elements, and functions for
+working with arrays as a whole. This includes the ability to
+``flatten'' an array so that it is easy for C code to traverse
+every element in an array. The array data structures integrate
+nicely with the data structures for values to make it easy to
+both work with and create true arrays of arrays (@pxref{General Data Types}).
+
+@menu
+* Array Data Types:: Data types for working with arrays.
+* Array Functions:: Functions for working with arrays.
+* Flattening Arrays:: How to flatten arrays.
+* Creating Arrays:: How to create and populate arrays.
+@end menu
+
+@node Array Data Types
+@subsubsection Array Data Types
+
+The data types associated with arrays are as follows:
+
+@table @code
+@item typedef void *awk_array_t;
+If you request the value of an array variable, you get back an
+@code{awk_array_t} value. This value is opaque@footnote{It is also
+a ``cookie,'' but the @command{gawk} developers did not wish to overuse this
+term.} to the extension; it uniquely identifies the array but can
+only be used by passing it into API functions or receiving it from API
+functions. This is very similar to way @samp{FILE *} values are used
+with the @code{<stdio.h>} library routines.
+
+@item typedef struct awk_element @{
+@itemx @ @ @ @ /* convenience linked list pointer, not used by gawk */
+@itemx @ @ @ @ struct awk_element *next;
+@itemx @ @ @ @ enum @{
+@itemx @ @ @ @ @ @ @ @ AWK_ELEMENT_DEFAULT = 0,@ @ /* set by gawk */
+@itemx @ @ @ @ @ @ @ @ AWK_ELEMENT_DELETE = 1@ @ @ @ /* set by extension */
+@itemx @ @ @ @ @} flags;
+@itemx @ @ @ @ awk_value_t index;
+@itemx @ @ @ @ awk_value_t value;
+@itemx @} awk_element_t;
+The @code{awk_element_t} is a ``flattened''
+array element. @command{awk} produces an array of these
+inside the @code{awk_flat_array_t} (see the next item).
+Individual elements may be marked for deletion. New elements must be added
+individually, one at a time, using the separate API for that purpose.
+The fields are as follows:
+
+@c nested table
+@table @code
+@item struct awk_element *next;
+This pointer is for the convenience of extension writers. It allows
+an extension to create a linked list of new elements that can then be
+added to an array in a loop that traverses the list.
+
+@item enum @{ @dots{} @} flags;
+A set of flag values that convey information between the extension
+and @command{gawk}. Currently there is only one: @code{AWK_ELEMENT_DELETE}.
+Setting it causes @command{gawk} to delete the
+element from the original array upon release of the flattened array.
+
+@item index
+@itemx value
+The index and value of the element, respectively.
+@emph{All} memory pointed to by @code{index} and @code{value} belongs to @command{gawk}.
+@end table
+
+@item typedef struct awk_flat_array @{
+@itemx @ @ @ @ awk_const void *awk_const opaque1;@ @ @ @ /* for use by gawk */
+@itemx @ @ @ @ awk_const void *awk_const opaque2;@ @ @ @ /* for use by gawk */
+@itemx @ @ @ @ awk_const size_t count;@ @ @ @ @ /* how many elements */
+@itemx @ @ @ @ awk_element_t elements[1];@ @ /* will be extended */
+@itemx @} awk_flat_array_t;
+This is a flattened array. When an extension gets one of these
+from @command{gawk}, the @code{elements} array is of actual
+size @code{count}.
+The @code{opaque1} and @code{opaque2} pointers are for use by @command{gawk};
+therefore they are marked @code{awk_const} so that the extension cannot
+modify them.
+@end table
+
+@node Array Functions
+@subsubsection Array Functions
+
+The following functions relate to individual array elements.
+
+@table @code
+@item awk_bool_t get_element_count(awk_array_t a_cookie, size_t *count);
+For the array represented by @code{a_cookie}, place in @code{*count}
+the number of elements it contains. A subarray counts as a single element.
+Return false if there is an error.
+
+@item awk_bool_t get_array_element(awk_array_t a_cookie,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const awk_value_t *const index,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_valtype_t wanted,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_value_t *result);
+For the array represented by @code{a_cookie}, return in @code{*result}
+the value of the element whose index is @code{index}.
+@code{wanted} specifies the type of value you wish to retrieve.
+Return false if @code{wanted} does not match the actual type or if
+@code{index} is not in the array (@pxref{table-value-types-returned}).
+
+The value for @code{index} can be numeric, in which case @command{gawk}
+converts it to a string. Using non-integral values is possible, but
+requires that you understand how such values are converted to strings
+(@pxref{Conversion}); thus using integral values is safest.
+
+As with @emph{all} strings passed into @code{gawk} from an extension,
+the string value of @code{index} must come from @code{gawk_malloc()},
+@code{gawk_calloc()} or @code{gawk_realloc()}, and
+@command{gawk} releases the storage.
+
+@item awk_bool_t set_array_element(awk_array_t a_cookie,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const@ awk_value_t *const index,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const@ awk_value_t *const value);
+In the array represented by @code{a_cookie}, create or modify
+the element whose index is given by @code{index}.
+The @code{ARGV} and @code{ENVIRON} arrays may not be changed,
+although the @code{PROCINFO} array can be.
+
+@item awk_bool_t set_array_element_by_elem(awk_array_t a_cookie,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_element_t element);
+Like @code{set_array_element()}, but take the @code{index} and @code{value}
+from @code{element}. This is a convenience macro.
+
+@item awk_bool_t del_array_element(awk_array_t a_cookie,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const awk_value_t* const index);
+Remove the element with the given index from the array
+represented by @code{a_cookie}.
+Return true if the element was removed, or false if the element did
+not exist in the array.
+@end table
+
+The following functions relate to arrays as a whole:
+
+@table @code
+@item awk_array_t create_array(void);
+Create a new array to which elements may be added.
+@DBXREF{Creating Arrays} for a discussion of how to
+create a new array and add elements to it.
+
+@item awk_bool_t clear_array(awk_array_t a_cookie);
+Clear the array represented by @code{a_cookie}.
+Return false if there was some kind of problem, true otherwise.
+The array remains an array, but after calling this function, it
+has no elements. This is equivalent to using the @code{delete}
+statement (@pxref{Delete}).
+
+@item awk_bool_t flatten_array(awk_array_t a_cookie, awk_flat_array_t **data);
+For the array represented by @code{a_cookie}, create an @code{awk_flat_array_t}
+structure and fill it in. Set the pointer whose address is passed as @code{data}
+to point to this structure.
+Return true upon success, or false otherwise.
+@ifset FOR_PRINT
+See the next section
+@end ifset
+@ifclear FOR_PRINT
+@xref{Flattening Arrays},
+@end ifclear
+for a discussion of how to
+flatten an array and work with it.
+
+@item awk_bool_t release_flattened_array(awk_array_t a_cookie,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_flat_array_t *data);
+When done with a flattened array, release the storage using this function.
+You must pass in both the original array cookie, and the address of
+the created @code{awk_flat_array_t} structure.
+The function returns true upon success, false otherwise.
+@end table
+
+@node Flattening Arrays
+@subsubsection Working With All The Elements of an Array
+
+To @dfn{flatten} an array is to create a structure that
+represents the full array in a fashion that makes it easy
+for C code to traverse the entire array. Test code
+in @file{extension/testext.c} does this, and also serves
+as a nice example showing how to use the APIs.
+
+We walk through that part of the code one step at a time.
+First, the @command{gawk} script that drives the test extension:
+
+@example
+@@load "testext"
+BEGIN @{
+ n = split("blacky rusty sophie raincloud lucky", pets)
+ printf("pets has %d elements\n", length(pets))
+ ret = dump_array_and_delete("pets", "3")
+ printf("dump_array_and_delete(pets) returned %d\n", ret)
+ if ("3" in pets)
+ printf("dump_array_and_delete() did NOT remove index \"3\"!\n")
+ else
+ printf("dump_array_and_delete() did remove index \"3\"!\n")
+ print ""
+@}
+@end example
+
+@noindent
+This code creates an array with @code{split()} (@pxref{String Functions})
+and then calls @code{dump_array_and_delete()}. That function looks up
+the array whose name is passed as the first argument, and
+deletes the element at the index passed in the second argument.
+The @command{awk} code then prints the return value and checks if the element
+was indeed deleted. Here is the C code that implements
+@code{dump_array_and_delete()}. It has been edited slightly for
+presentation.
+
+The first part declares variables, sets up the default
+return value in @code{result}, and checks that the function
+was called with the correct number of arguments:
+
+@example
+static awk_value_t *
+dump_array_and_delete(int nargs, awk_value_t *result)
+@{
+ awk_value_t value, value2, value3;
+ awk_flat_array_t *flat_array;
+ size_t count;
+ char *name;
+ int i;
+
+ assert(result != NULL);
+ make_number(0.0, result);
+
+ if (nargs != 2) @{
+ printf("dump_array_and_delete: nargs not right "
+ "(%d should be 2)\n", nargs);
+ goto out;
+ @}
+@end example
+
+The function then proceeds in steps, as follows. First, retrieve
+the name of the array, passed as the first argument. Then
+retrieve the array itself. If either operation fails, print
+error messages and return:
+
+@example
+ /* get argument named array as flat array and print it */
+ if (get_argument(0, AWK_STRING, & value)) @{
+ name = value.str_value.str;
+ if (sym_lookup(name, AWK_ARRAY, & value2))
+ printf("dump_array_and_delete: sym_lookup of %s passed\n",
+ name);
+ else @{
+ printf("dump_array_and_delete: sym_lookup of %s failed\n",
+ name);
+ goto out;
+ @}
+ @} else @{
+ printf("dump_array_and_delete: get_argument(0) failed\n");
+ goto out;
+ @}
+@end example
+
+For testing purposes and to make sure that the C code sees
+the same number of elements as the @command{awk} code,
+the second step is to get the count of elements in the array
+and print it:
+
+@example
+ if (! get_element_count(value2.array_cookie, & count)) @{
+ printf("dump_array_and_delete: get_element_count failed\n");
+ goto out;
+ @}
+
+ printf("dump_array_and_delete: incoming size is %lu\n",
+ (unsigned long) count);
+@end example
+
+The third step is to actually flatten the array, and then
+to double check that the count in the @code{awk_flat_array_t}
+is the same as the count just retrieved:
+
+@example
+ if (! flatten_array(value2.array_cookie, & flat_array)) @{
+ printf("dump_array_and_delete: could not flatten array\n");
+ goto out;
+ @}
+
+ if (flat_array->count != count) @{
+ printf("dump_array_and_delete: flat_array->count (%lu)"
+ " != count (%lu)\n",
+ (unsigned long) flat_array->count,
+ (unsigned long) count);
+ goto out;
+ @}
+@end example
+
+The fourth step is to retrieve the index of the element
+to be deleted, which was passed as the second argument.
+Remember that argument counts passed to @code{get_argument()}
+are zero-based, thus the second argument is numbered one:
+
+@example
+ if (! get_argument(1, AWK_STRING, & value3)) @{
+ printf("dump_array_and_delete: get_argument(1) failed\n");
+ goto out;
+ @}
+@end example
+
+The fifth step is where the ``real work'' is done. The function
+loops over every element in the array, printing the index and
+element values. In addition, upon finding the element with the
+index that is supposed to be deleted, the function sets the
+@code{AWK_ELEMENT_DELETE} bit in the @code{flags} field
+of the element. When the array is released, @command{gawk}
+traverses the flattened array, and deletes any elements which
+have this flag bit set:
+
+@example
+ for (i = 0; i < flat_array->count; i++) @{
+ printf("\t%s[\"%.*s\"] = %s\n",
+ name,
+ (int) flat_array->elements[i].index.str_value.len,
+ flat_array->elements[i].index.str_value.str,
+ valrep2str(& flat_array->elements[i].value));
+
+ if (strcmp(value3.str_value.str,
+ flat_array->elements[i].index.str_value.str) == 0) @{
+ flat_array->elements[i].flags |= AWK_ELEMENT_DELETE;
+ printf("dump_array_and_delete: marking element \"%s\" "
+ "for deletion\n",
+ flat_array->elements[i].index.str_value.str);
+ @}
+ @}
+@end example
+
+The sixth step is to release the flattened array. This tells
+@command{gawk} that the extension is no longer using the array,
+and that it should delete any elements marked for deletion.
+@command{gawk} also frees any storage that was allocated,
+so you should not use the pointer (@code{flat_array} in this
+code) once you have called @code{release_flattened_array()}:
+
+@example
+ if (! release_flattened_array(value2.array_cookie, flat_array)) @{
+ printf("dump_array_and_delete: could not release flattened array\n");
+ goto out;
+ @}
+@end example
+
+Finally, because everything was successful, the function sets the
+return value to success, and returns:
+
+@example
+ make_number(1.0, result);
+out:
+ return result;
+@}
+@end example
+
+Here is the output from running this part of the test:
+
+@example
+pets has 5 elements
+dump_array_and_delete: sym_lookup of pets passed
+dump_array_and_delete: incoming size is 5
+ pets["1"] = "blacky"
+ pets["2"] = "rusty"
+ pets["3"] = "sophie"
+dump_array_and_delete: marking element "3" for deletion
+ pets["4"] = "raincloud"
+ pets["5"] = "lucky"
+dump_array_and_delete(pets) returned 1
+dump_array_and_delete() did remove index "3"!
+@end example
+
+@node Creating Arrays
+@subsubsection How To Create and Populate Arrays
+
+Besides working with arrays created by @command{awk} code, you can
+create arrays and populate them as you see fit, and then @command{awk}
+code can access them and manipulate them.
+
+There are two important points about creating arrays from extension code:
+
+@itemize @value{BULLET}
+@item
+You must install a new array into @command{gawk}'s symbol
+table immediately upon creating it. Once you have done so,
+you can then populate the array.
+
+@ignore
+Strictly speaking, this is required only
+for arrays that will have subarrays as elements; however it is
+a good idea to always do this. This restriction may be relaxed
+in a subsequent revision of the API.
+@end ignore
+
+Similarly, if installing a new array as a subarray of an existing array,
+you must add the new array to its parent before adding any elements to it.
+
+Thus, the correct way to build an array is to work ``top down.'' Create
+the array, and immediately install it in @command{gawk}'s symbol table
+using @code{sym_update()}, or install it as an element in a previously
+existing array using @code{set_array_element()}. We show example code shortly.
+
+@item
+Due to @command{gawk} internals, after using @code{sym_update()} to install an array
+into @command{gawk}, you have to retrieve the array cookie from the value
+passed in to @command{sym_update()} before doing anything else with it, like so:
+
+@example
+awk_value_t value;
+awk_array_t new_array;
+
+new_array = create_array();
+val.val_type = AWK_ARRAY;
+val.array_cookie = new_array;
+
+/* install array in the symbol table */
+sym_update("array", & val);
+
+new_array = val.array_cookie; /* YOU MUST DO THIS */
+@end example
+
+If installing an array as a subarray, you must also retrieve the value
+of the array cookie after the call to @code{set_element()}.
+@end itemize
+
+The following C code is a simple test extension to create an array
+with two regular elements and with a subarray. The leading @code{#include}
+directives and boilerplate variable declarations
+(@pxref{Extension API Boilerplate})
+are omitted for brevity.
+The first step is to create a new array and then install it
+in the symbol table:
+
+@example
+@ignore
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "gawkapi.h"
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+static const char *ext_version = "testarray extension: version 1.0";
+
+int plugin_is_GPL_compatible;
+
+@end ignore
+/* create_new_array --- create a named array */
+
+static void
+create_new_array()
+@{
+ awk_array_t a_cookie;
+ awk_array_t subarray;
+ awk_value_t index, value;
+
+ a_cookie = create_array();
+ value.val_type = AWK_ARRAY;
+ value.array_cookie = a_cookie;
+
+ if (! sym_update("new_array", & value))
+ printf("create_new_array: sym_update(\"new_array\") failed!\n");
+ a_cookie = value.array_cookie;
+@end example
+
+@noindent
+Note how @code{a_cookie} is reset from the @code{array_cookie} field in
+the @code{value} structure.
+
+The second step is to install two regular values into @code{new_array}:
+
+@example
+ (void) make_const_string("hello", 5, & index);
+ (void) make_const_string("world", 5, & value);
+ if (! set_array_element(a_cookie, & index, & value)) @{
+ printf("fill_in_array: set_array_element failed\n");
+ return;
+ @}
+
+ (void) make_const_string("answer", 6, & index);
+ (void) make_number(42.0, & value);
+ if (! set_array_element(a_cookie, & index, & value)) @{
+ printf("fill_in_array: set_array_element failed\n");
+ return;
+ @}
+@end example
+
+The third step is to create the subarray and install it:
+
+@example
+ (void) make_const_string("subarray", 8, & index);
+ subarray = create_array();
+ value.val_type = AWK_ARRAY;
+ value.array_cookie = subarray;
+ if (! set_array_element(a_cookie, & index, & value)) @{
+ printf("fill_in_array: set_array_element failed\n");
+ return;
+ @}
+ subarray = value.array_cookie;
+@end example
+
+The final step is to populate the subarray with its own element:
+
+@example
+ (void) make_const_string("foo", 3, & index);
+ (void) make_const_string("bar", 3, & value);
+ if (! set_array_element(subarray, & index, & value)) @{
+ printf("fill_in_array: set_array_element failed\n");
+ return;
+ @}
+@}
+@ignore
+static awk_ext_func_t func_table[] = @{
+ @{ NULL, NULL, 0 @}
+@};
+
+/* init_testarray --- additional initialization function */
+
+static awk_bool_t init_testarray(void)
+@{
+ create_new_array();
+
+ return awk_true;
+@}
+
+static awk_bool_t (*init_func)(void) = init_testarray;
+
+dl_load_func(func_table, testarray, "")
+@end ignore
+@end example
+
+Here is a sample script that loads the extension
+and then dumps the array:
+
+@example
+@@load "subarray"
+
+function dumparray(name, array, i)
+@{
+ for (i in array)
+ if (isarray(array[i]))
+ dumparray(name "[\"" i "\"]", array[i])
+ else
+ printf("%s[\"%s\"] = %s\n", name, i, array[i])
+@}
+
+BEGIN @{
+ dumparray("new_array", new_array);
+@}
+@end example
+
+Here is the result of running the script:
+
+@example
+$ @kbd{AWKLIBPATH=$PWD ./gawk -f subarray.awk}
+@print{} new_array["subarray"]["foo"] = bar
+@print{} new_array["hello"] = world
+@print{} new_array["answer"] = 42
+@end example
+
+@noindent
+(@DBXREF{Finding Extensions} for more information on the
+@env{AWKLIBPATH} environment variable.)
+
+@node Extension API Variables
+@subsection API Variables
+
+The API provides two sets of variables. The first provides information
+about the version of the API (both with which the extension was compiled,
+and with which @command{gawk} was compiled). The second provides
+information about how @command{gawk} was invoked.
+
+@menu
+* Extension Versioning:: API Version information.
+* Extension API Informational Variables:: Variables providing information about
+ @command{gawk}'s invocation.
+@end menu
+
+@node Extension Versioning
+@subsubsection API Version Constants and Variables
+@cindex API version
+@cindex extension API version
+
+The API provides both a ``major'' and a ``minor'' version number.
+The API versions are available at compile time as constants:
+
+@table @code
+@item GAWK_API_MAJOR_VERSION
+The major version of the API.
+
+@item GAWK_API_MINOR_VERSION
+The minor version of the API.
+@end table
+
+The minor version increases when new functions are added to the API. Such
+new functions are always added to the end of the API @code{struct}.
+
+The major version increases (and the minor version is reset to zero) if any
+of the data types change size or member order, or if any of the existing
+functions change signature.
+
+It could happen that an extension may be compiled against one version
+of the API but loaded by a version of @command{gawk} using a different
+version. For this reason, the major and minor API versions of the
+running @command{gawk} are included in the API @code{struct} as read-only
+constant integers:
+
+@table @code
+@item api->major_version
+The major version of the running @command{gawk}.
+
+@item api->minor_version
+The minor version of the running @command{gawk}.
+@end table
+
+It is up to the extension to decide if there are API incompatibilities.
+Typically a check like this is enough:
+
+@example
+if (api->major_version != GAWK_API_MAJOR_VERSION
+ || api->minor_version < GAWK_API_MINOR_VERSION) @{
+ fprintf(stderr, "foo_extension: version mismatch with gawk!\n");
+ fprintf(stderr, "\tmy version (%d, %d), gawk version (%d, %d)\n",
+ GAWK_API_MAJOR_VERSION, GAWK_API_MINOR_VERSION,
+ api->major_version, api->minor_version);
+ exit(1);
+@}
+@end example
+
+Such code is included in the boilerplate @code{dl_load_func()} macro
+provided in @file{gawkapi.h} (discussed later, in
+@ref{Extension API Boilerplate}).
+
+@node Extension API Informational Variables
+@subsubsection Informational Variables
+@cindex API informational variables
+@cindex extension API informational variables
+
+The API provides access to several variables that describe
+whether the corresponding command-line options were enabled when
+@command{gawk} was invoked. The variables are:
+
+@table @code
+@item do_debug
+This variable is true if @command{gawk} was invoked with @option{--debug} option.
+
+@item do_lint
+This variable is true if @command{gawk} was invoked with @option{--lint} option.
+
+@item do_mpfr
+This variable is true if @command{gawk} was invoked with @option{--bignum} option.
+
+@item do_profile
+This variable is true if @command{gawk} was invoked with @option{--profile} option.
+
+@item do_sandbox
+This variable is true if @command{gawk} was invoked with @option{--sandbox} option.
+
+@item do_traditional
+This variable is true if @command{gawk} was invoked with @option{--traditional} option.
+@end table
+
+The value of @code{do_lint} can change if @command{awk} code
+modifies the @code{LINT} predefined variable (@pxref{Built-in Variables}).
+The others should not change during execution.
+
+@node Extension API Boilerplate
+@subsection Boilerplate Code
+
+As mentioned earlier (@pxref{Extension Mechanism Outline}), the function
+definitions as presented are really macros. To use these macros, your
+extension must provide a small amount of boilerplate code (variables and
+functions) toward the top of your source file, using predefined names
+as described here. The boilerplate needed is also provided in comments
+in the @file{gawkapi.h} header file:
+
+@example
+/* Boiler plate code: */
+int plugin_is_GPL_compatible;
+
+static gawk_api_t *const api;
+static awk_ext_id_t ext_id;
+static const char *ext_version = NULL; /* or @dots{} = "some string" */
+
+static awk_ext_func_t func_table[] = @{
+ @{ "name", do_name, 1 @},
+ /* @dots{} */
+@};
+
+/* EITHER: */
+
+static awk_bool_t (*init_func)(void) = NULL;
+
+/* OR: */
+
+static awk_bool_t
+init_my_extension(void)
+@{
+ @dots{}
+@}
+
+static awk_bool_t (*init_func)(void) = init_my_extension;
+
+dl_load_func(func_table, some_name, "name_space_in_quotes")
+@end example
+
+These variables and functions are as follows:
+
+@table @code
+@item int plugin_is_GPL_compatible;
+This asserts that the extension is compatible with
+@ifclear FOR_PRINT
+the GNU GPL (@pxref{Copying}).
+@end ifclear
+@ifset FOR_PRINT
+the GNU GPL.
+@end ifset
+If your extension does not have this, @command{gawk}
+will not load it (@pxref{Plugin License}).
+
+@item static gawk_api_t *const api;
+This global @code{static} variable should be set to point to
+the @code{gawk_api_t} pointer that @command{gawk} passes to your
+@code{dl_load()} function. This variable is used by all of the macros.
+
+@item static awk_ext_id_t ext_id;
+This global static variable should be set to the @code{awk_ext_id_t}
+value that @command{gawk} passes to your @code{dl_load()} function.
+This variable is used by all of the macros.
+
+@item static const char *ext_version = NULL; /* or @dots{} = "some string" */
+This global @code{static} variable should be set either
+to @code{NULL}, or to point to a string giving the name and version of
+your extension.
+
+@item static awk_ext_func_t func_table[] = @{ @dots{} @};
+This is an array of one or more @code{awk_ext_func_t} structures
+as described earlier (@pxref{Extension Functions}).
+It can then be looped over for multiple calls to
+@code{add_ext_func()}.
+
+@c Use @var{OR} for docbook
+@item static awk_bool_t (*init_func)(void) = NULL;
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @var{OR}
+@itemx static awk_bool_t init_my_extension(void) @{ @dots{} @}
+@itemx static awk_bool_t (*init_func)(void) = init_my_extension;
+If you need to do some initialization work, you should define a
+function that does it (creates variables, opens files, etc.)
+and then define the @code{init_func} pointer to point to your
+function.
+The function should return @code{awk_false} upon failure, or @code{awk_true}
+if everything goes well.
+
+If you don't need to do any initialization, define the pointer and
+initialize it to @code{NULL}.
+
+@item dl_load_func(func_table, some_name, "name_space_in_quotes")
+This macro expands to a @code{dl_load()} function that performs
+all the necessary initializations.
+@end table
+
+The point of all the variables and arrays is to let the
+@code{dl_load()} function (from the @code{dl_load_func()}
+macro) do all the standard work. It does the following:
+
+@enumerate 1
+@item
+Check the API versions. If the extension major version does not match
+@command{gawk}'s, or if the extension minor version is greater than
+@command{gawk}'s, it prints a fatal error message and exits.
+
+@item
+Load the functions defined in @code{func_table}.
+If any of them fails to load, it prints a warning message but
+continues on.
+
+@item
+If the @code{init_func} pointer is not @code{NULL}, call the
+function it points to. If it returns @code{awk_false}, print a
+warning message.
+
+@item
+If @code{ext_version} is not @code{NULL}, register
+the version string with @command{gawk}.
+@end enumerate
+
+@node Finding Extensions
+@section How @command{gawk} Finds Extensions
+@cindex extension search path
+@cindex finding extensions
+
+Compiled extensions have to be installed in a directory where
+@command{gawk} can find them. If @command{gawk} is configured and
+built in the default fashion, the directory in which to find
+extensions is @file{/usr/local/lib/gawk}. You can also specify a search
+path with a list of directories to search for compiled extensions.
+@DBXREF{AWKLIBPATH Variable} for more information.
+
+@node Extension Example
+@section Example: Some File Functions
+@cindex extension example
+
+@quotation
+@i{No matter where you go, there you are.}
+@author Buckaroo Banzai
+@end quotation
+
+@c It's enough to show chdir and stat, no need for fts
+
+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).
+In order to illustrate the API in action, this @value{SECTION} implements
+these functions for @command{gawk} in an extension.
+
+@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
+@subsection 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
+@@load "filefuncs"
+@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"
+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{Time Functions}).
+
+@item "pmode"
+The file's ``printable mode.'' This is a string representation of
+the file's type and permissions, such as 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
+
+@c 5/2013: Thanks to Corinna Vinschen for this information.
+@item "devbsize"
+The size of a block for the element indexed by @code{"blocks"}.
+This information is derived from either the @code{DEV_BSIZE}
+constant defined in @code{<sys/param.h>} on most systems,
+or the @code{S_BLKSIZE} constant in @code{<sys/stat.h>} on BSD systems.
+For some other systems, @dfn{a priori} knowledge is used to provide
+a value. Where no value can be determined, it defaults to 512.
+@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
+@subsection C Code for @code{chdir()} and @code{stat()}
+
+Here is the C code for these extensions.@footnote{This version is
+edited slightly for presentation. See @file{extension/filefuncs.c}
+in the @command{gawk} distribution for the complete version.}
+
+The file includes a number of standard header files, and then includes
+the @file{gawkapi.h} header file which provides the API definitions.
+Those are followed by the necessary variable declarations
+to make use of the API macros and boilerplate code
+(@pxref{Extension API Boilerplate}):
+
+@example
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "gawkapi.h"
+
+#include "gettext.h"
+#define _(msgid) gettext(msgid)
+#define N_(msgid) msgid
+
+#include "gawkfts.h"
+#include "stack.h"
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+static awk_bool_t init_filefuncs(void);
+static awk_bool_t (*init_func)(void) = init_filefuncs;
+static const char *ext_version = "filefuncs extension: version 1.0";
+
+int plugin_is_GPL_compatible;
+@end example
+
+@cindex programming conventions, @command{gawk} extensions
+By convention, for an @command{awk} function @code{foo()}, the C function
+that implements it is called @code{do_foo()}. The function should have
+two arguments: the first is an @code{int} usually called @code{nargs},
+that represents the number of actual arguments for the function.
+The second is a pointer to an @code{awk_value_t}, usually named
+@code{result}:
+
+@example
+/* do_chdir --- provide dynamically loaded chdir() function for gawk */
+
+static awk_value_t *
+do_chdir(int nargs, awk_value_t *result)
+@{
+ awk_value_t newdir;
+ int ret = -1;
+
+ assert(result != NULL);
+
+ if (do_lint && nargs != 1)
+ lintwarn(ext_id,
+ _("chdir: called with incorrect number of arguments, "
+ "expecting 1"));
+@end example
+
+The @code{newdir}
+variable represents the new directory to change to, which is retrieved
+with @code{get_argument()}. Note that the first argument is
+numbered zero.
+
+If the argument is retrieved successfully, the function calls the
+@code{chdir()} system call. If the @code{chdir()} fails, @code{ERRNO}
+is updated:
+
+@example
+ if (get_argument(0, AWK_STRING, & newdir)) @{
+ ret = chdir(newdir.str_value.str);
+ if (ret < 0)
+ update_ERRNO_int(errno);
+ @}
+@end example
+
+Finally, the function returns the return value to the @command{awk} level:
+
+@example
+ return make_number(ret, result);
+@}
+@end example
+
+The @code{stat()} extension 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:
+
+@example
+/* format_mode --- turn a stat mode field into something readable */
+
+static char *
+format_mode(unsigned long fmode)
+@{
+ @dots{}
+@}
+@end example
+
+Next comes a function for reading symbolic links, which is also
+omitted here for brevity:
+
+@example
+/* read_symlink --- read a symbolic link into an allocated buffer.
+ @dots{} */
+
+static char *
+read_symlink(const char *fname, size_t bufsize, ssize_t *linksize)
+@{
+ @dots{}
+@}
+@end example
+
+Two helper functions simplify entering values in the
+array that will contain the result of the @code{stat()}:
+
+@example
+/* array_set --- set an array element */
+
+static void
+array_set(awk_array_t array, const char *sub, awk_value_t *value)
+@{
+ awk_value_t index;
+
+ set_array_element(array,
+ make_const_string(sub, strlen(sub), & index),
+ value);
+
+@}
+
+/* array_set_numeric --- set an array element with a number */
+
+static void
+array_set_numeric(awk_array_t array, const char *sub, double num)
+@{
+ awk_value_t tmp;
+
+ array_set(array, sub, make_number(num, & tmp));
+@}
+@end example
+
+The following function does most of the work to fill in
+the @code{awk_array_t} result array with values obtained
+from a valid @code{struct stat}. It is done in a separate function
+to support the @code{stat()} function for @command{gawk} and also
+to support the @code{fts()} extension which is included in
+the same file but whose code is not shown here
+(@pxref{Extension Sample File Functions}).
+
+The first part of the function is variable declarations,
+including a table to map file types to strings:
+
+@example
+/* fill_stat_array --- do the work to fill an array with stat info */
+
+static int
+fill_stat_array(const char *name, awk_array_t array, struct stat *sbuf)
+@{
+ char *pmode; /* printable mode */
+ const char *type = "unknown";
+ awk_value_t tmp;
+ static struct ftype_map @{
+ unsigned int mask;
+ const char *type;
+ @} ftype_map[] = @{
+ @{ S_IFREG, "file" @},
+ @{ S_IFBLK, "blockdev" @},
+ @{ S_IFCHR, "chardev" @},
+ @{ S_IFDIR, "directory" @},
+#ifdef S_IFSOCK
+ @{ S_IFSOCK, "socket" @},
+#endif
+#ifdef S_IFIFO
+ @{ S_IFIFO, "fifo" @},
+#endif
+#ifdef S_IFLNK
+ @{ S_IFLNK, "symlink" @},
+#endif
+#ifdef S_IFDOOR /* Solaris weirdness */
+ @{ S_IFDOOR, "door" @},
+#endif /* S_IFDOOR */
+ @};
+ int j, k;
+@end example
+
+The destination array is cleared, and then code fills in
+various elements based on values in the @code{struct stat}:
+
+@example
+ /* empty out the array */
+ clear_array(array);
+
+ /* fill in the array */
+ array_set(array, "name", make_const_string(name, strlen(name),
+ & tmp));
+ array_set_numeric(array, "dev", sbuf->st_dev);
+ array_set_numeric(array, "ino", sbuf->st_ino);
+ array_set_numeric(array, "mode", sbuf->st_mode);
+ array_set_numeric(array, "nlink", sbuf->st_nlink);
+ array_set_numeric(array, "uid", sbuf->st_uid);
+ array_set_numeric(array, "gid", sbuf->st_gid);
+ array_set_numeric(array, "size", sbuf->st_size);
+ array_set_numeric(array, "blocks", sbuf->st_blocks);
+ array_set_numeric(array, "atime", sbuf->st_atime);
+ array_set_numeric(array, "mtime", sbuf->st_mtime);
+ array_set_numeric(array, "ctime", 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)) @{
+ array_set_numeric(array, "rdev", sbuf->st_rdev);
+ array_set_numeric(array, "major", major(sbuf->st_rdev));
+ array_set_numeric(array, "minor", minor(sbuf->st_rdev));
+ @}
+@end example
+
+@noindent
+The latter part of the function makes selective additions
+to the destination array, depending upon the availability of
+certain members and/or the type of the file. It then returns zero,
+for success:
+
+@example
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+ array_set_numeric(array, "blksize", sbuf->st_blksize);
+#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
+
+ pmode = format_mode(sbuf->st_mode);
+ array_set(array, "pmode", make_const_string(pmode, strlen(pmode),
+ & tmp));
+
+ /* for symbolic links, add a linkval field */
+ if (S_ISLNK(sbuf->st_mode)) @{
+ char *buf;
+ ssize_t linksize;
+
+ if ((buf = read_symlink(name, sbuf->st_size,
+ & linksize)) != NULL)
+ array_set(array, "linkval",
+ make_malloced_string(buf, linksize, & tmp));
+ else
+ warning(ext_id, _("stat: unable to read symbolic link `%s'"),
+ name);
+ @}
+
+ /* add a type field */
+ type = "unknown"; /* shouldn't happen */
+ for (j = 0, k = sizeof(ftype_map)/sizeof(ftype_map[0]); j < k; j++) @{
+ if ((sbuf->st_mode & S_IFMT) == ftype_map[j].mask) @{
+ type = ftype_map[j].type;
+ break;
+ @}
+ @}
+
+ array_set(array, "type", make_const_string(type, strlen(type), & tmp));
+
+ return 0;
+@}
+@end example
+
+The third argument to @code{stat()} was not discussed previously. This
+argument is optional. If present, it causes @code{do_stat()} to use
+the @code{stat()} system call instead of the @code{lstat()} system
+call. This is done by using a function pointer: @code{statfunc}.
+@code{statfunc} is initialized to point to @code{lstat()} (instead
+of @code{stat()}) to get the file information, in case the file is a
+symbolic link. However, if there were three arguments, @code{statfunc}
+is set point to @code{stat()}, instead.
+
+Here is the @code{do_stat()} function, which starts with
+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 awk_value_t *
+do_stat(int nargs, awk_value_t *result)
+@{
+ awk_value_t file_param, array_param;
+ char *name;
+ awk_array_t array;
+ int ret;
+ struct stat sbuf;
+ /* default is lstat() */
+ int (*statfunc)(const char *path, struct stat *sbuf) = lstat;
+
+ assert(result != NULL);
+
+ if (nargs != 2 && nargs != 3) @{
+ if (do_lint)
+ lintwarn(ext_id,
+ _("stat: called with wrong number of arguments"));
+ return make_number(-1, result);
+ @}
+@end example
+
+Then comes the actual work. First, the function gets the arguments.
+Next, it gets the information for the file. If the called function
+(@code{lstat()} or @code{stat()}) returns an error, the code sets
+@code{ERRNO} and returns:
+
+@example
+ /* file is first arg, array to hold results is second */
+ if ( ! get_argument(0, AWK_STRING, & file_param)
+ || ! get_argument(1, AWK_ARRAY, & array_param)) @{
+ warning(ext_id, _("stat: bad parameters"));
+ return make_number(-1, result);
+ @}
+
+ if (nargs == 3) @{
+ statfunc = stat;
+ @}
+
+ name = file_param.str_value.str;
+ array = array_param.array_cookie;
+
+ /* always empty out the array */
+ clear_array(array);
+
+ /* stat the file, if error, set ERRNO and return */
+ ret = statfunc(name, & sbuf);
+ if (ret < 0) @{
+ update_ERRNO_int(errno);
+ return make_number(ret, result);
+ @}
+@end example
+
+The tedious work is done by @code{fill_stat_array()}, shown
+earlier. When done, the function returns the result from @code{fill_stat_array()}:
+
+@example
+ ret = fill_stat_array(name, array, & sbuf);
+
+ return make_number(ret, result);
+@}
+@end example
+
+Finally, it's necessary to provide the ``glue'' that loads the
+new function(s) into @command{gawk}.
+
+The @code{filefuncs} extension also provides an @code{fts()}
+function, which we omit here. For its sake there is an initialization
+function:
+
+@example
+/* init_filefuncs --- initialization routine */
+
+static awk_bool_t
+init_filefuncs(void)
+@{
+ @dots{}
+@}
+@end example
+
+We are almost done. We need an array of @code{awk_ext_func_t}
+structures for loading each function into @command{gawk}:
+
+@example
+static awk_ext_func_t func_table[] = @{
+ @{ "chdir", do_chdir, 1 @},
+ @{ "stat", do_stat, 2 @},
+#ifndef __MINGW32__
+ @{ "fts", do_fts, 3 @},
+#endif
+@};
+@end example
+
+Each extension must have a routine named @code{dl_load()} to load
+everything that needs to be loaded. It is simplest to use the
+@code{dl_load_func()} macro in @code{gawkapi.h}:
+
+@example
+/* define the dl_load() function using the boilerplate macro */
+
+dl_load_func(func_table, filefuncs, "")
+@end example
+
+And that's it!
+
+@node Using Internal File Ops
+@subsection 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 @file{gawkapi.h} header file,
+the following steps@footnote{In practice, you would probably want to
+use the GNU Autotools (Automake, Autoconf, Libtool, and @command{gettext}) to
+configure and build your libraries. Instructions for doing so are beyond
+the scope of this @value{DOCUMENT}. @DBXREF{gawkextlib} for Internet links to
+the tools.} create a GNU/Linux shared library:
+
+@example
+$ @kbd{gcc -fPIC -shared -DHAVE_CONFIG_H -c -O -g -I@var{idir} filefuncs.c}
+$ @kbd{gcc -o filefuncs.so -shared filefuncs.o}
+@end example
+
+Once the library exists, it is loaded by using the @code{@@load} keyword:
+
+@example
+# file testff.awk
+@@load "filefuncs"
+
+BEGIN @{
+ "pwd" | getline curdir # save current directory
+ close("pwd")
+
+ chdir("/tmp")
+ system("pwd") # test it
+ chdir(curdir) # go back
+
+ 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"])
+@}
+@end example
+
+The @env{AWKLIBPATH} environment variable tells
+@command{gawk} where to find extensions (@pxref{Finding Extensions}).
+We set it to the current directory and run the program:
+
+@example
+$ @kbd{AWKLIBPATH=$PWD gawk -f testff.awk}
+@print{} /tmp
+@print{} Info for testff.awk
+@print{} ret = 0
+@print{} data["blksize"] = 4096
+@print{} data["devbsize"] = 512
+@print{} data["mtime"] = 1412004710
+@print{} data["mode"] = 33204
+@print{} data["type"] = file
+@print{} data["dev"] = 2053
+@print{} data["gid"] = 1000
+@print{} data["ino"] = 10358899
+@print{} data["ctime"] = 1412004710
+@print{} data["blocks"] = 8
+@print{} data["nlink"] = 1
+@print{} data["name"] = testff.awk
+@print{} data["atime"] = 1412004716
+@print{} data["pmode"] = -rw-rw-r--
+@print{} data["size"] = 666
+@print{} data["uid"] = 1000
+@print{} testff.awk modified: 09 29 2014 18:31:50
+@print{}
+@print{} Info for JUNK
+@print{} ret = -1
+@print{} JUNK modified: 01 01 1970 02:00:00
+@end example
+
+@node Extension Samples
+@section The Sample Extensions in the @command{gawk} Distribution
+@cindex extensions distributed with @command{gawk}
+
+This @value{SECTION} provides brief overviews of the sample extensions
+that come in the @command{gawk} distribution. Some of them are intended
+for production use (e.g., the @code{filefuncs}, @code{readdir} and
+@code{inplace} extensions). Others mainly provide example code that
+shows how to use the extension API.
+
+@menu
+* Extension Sample File Functions:: The file functions sample.
+* Extension Sample Fnmatch:: An interface to @code{fnmatch()}.
+* Extension Sample Fork:: An interface to @code{fork()} and other
+ process functions.
+* Extension Sample Inplace:: Enabling in-place file editing.
+* Extension Sample Ord:: Character to value to character
+ conversions.
+* Extension Sample Readdir:: An interface to @code{readdir()}.
+* Extension Sample Revout:: Reversing output sample output wrapper.
+* Extension Sample Rev2way:: Reversing data sample two-way processor.
+* Extension Sample Read write array:: Serializing an array to a file.
+* Extension Sample Readfile:: Reading an entire file into a string.
+* Extension Sample Time:: An interface to @code{gettimeofday()}
+ and @code{sleep()}.
+* Extension Sample API Tests:: Tests for the API.
+@end menu
+
+@node Extension Sample File Functions
+@subsection File-Related Functions
+
+The @code{filefuncs} extension provides three different functions, as follows.
+The usage is:
+
+@table @asis
+@item @code{@@load "filefuncs"}
+This is how you load the extension.
+
+@cindex @code{chdir()} extension function
+@item @code{result = chdir("/some/directory")}
+The @code{chdir()} function is a direct hook to the @code{chdir()}
+system call to change the current directory. It returns zero
+upon success or less than zero upon error. In the latter case, it updates
+@code{ERRNO}.
+
+@cindex @code{stat()} extension function
+@item @code{result = stat("/some/path", statdata} [@code{, follow}]@code{)}
+The @code{stat()} function provides a hook into the
+@code{stat()} system call.
+It returns zero upon success or less than zero upon error.
+In the latter case, it updates @code{ERRNO}.
+
+By default, it uses the @code{lstat()} system call. However, if passed
+a third argument, it uses @code{stat()} instead.
+
+In all cases, it clears the @code{statdata} array.
+When the call is successful, @code{stat()} fills the @code{statdata}
+array with information retrieved from the filesystem, as follows:
+
+@multitable @columnfractions .15 .50 .20
+@headitem Subscript @tab Field in @code{struct stat} @tab File type
+@item @code{"name"} @tab The @value{FN} @tab All
+@item @code{"dev"} @tab @code{st_dev} @tab All
+@item @code{"ino"} @tab @code{st_ino} @tab All
+@item @code{"mode"} @tab @code{st_mode} @tab All
+@item @code{"nlink"} @tab @code{st_nlink} @tab All
+@item @code{"uid"} @tab @code{st_uid} @tab All
+@item @code{"gid"} @tab @code{st_gid} @tab All
+@item @code{"size"} @tab @code{st_size} @tab All
+@item @code{"atime"} @tab @code{st_atime} @tab All
+@item @code{"mtime"} @tab @code{st_mtime} @tab All
+@item @code{"ctime"} @tab @code{st_ctime} @tab All
+@item @code{"rdev"} @tab @code{st_rdev} @tab Device files
+@item @code{"major"} @tab @code{st_major} @tab Device files
+@item @code{"minor"} @tab @code{st_minor} @tab Device files
+@item @code{"blksize"} @tab @code{st_blksize} @tab All
+@item @code{"pmode"} @tab A human-readable version of the mode value, such as printed by
+@command{ls}. For example, @code{"-rwxr-xr-x"} @tab All
+@item @code{"linkval"} @tab The value of the symbolic link @tab Symbolic links
+@item @code{"type"} @tab The type of the file as a string. One of
+@code{"file"},
+@code{"blockdev"},
+@code{"chardev"},
+@code{"directory"},
+@code{"socket"},
+@code{"fifo"},
+@code{"symlink"},
+@code{"door"},
+or
+@code{"unknown"}.
+Not all systems support all file types. @tab All
+@end multitable
+
+@cindex @code{fts()} extension function
+@item @code{flags = or(FTS_PHYSICAL, ...)}
+@itemx @code{result = fts(pathlist, flags, filedata)}
+Walk the file trees provided in @code{pathlist} and fill in the
+@code{filedata} array as described next. @code{flags} is the bitwise
+OR of several predefined values, also described in a moment.
+Return zero if there were no errors, otherwise return @minus{}1.
+@end table
+
+The @code{fts()} function provides a hook to the C library @code{fts()}
+routines for traversing file hierarchies. Instead of returning data
+about one file at a time in a stream, it fills in a multidimensional
+array with data about each file and directory encountered in the requested
+hierarchies.
+
+The arguments are as follows:
+
+@table @code
+@item pathlist
+An array of @value{FN}s. The element values are used; the index values are ignored.
+
+@item flags
+This should be the bitwise OR of one or more of the following
+predefined constant flag values. At least one of
+@code{FTS_LOGICAL} or @code{FTS_PHYSICAL} must be provided; otherwise
+@code{fts()} returns an error value and sets @code{ERRNO}.
+The flags are:
+
+@c nested table
+@table @code
+@item FTS_LOGICAL
+Do a ``logical'' file traversal, where the information returned for
+a symbolic link refers to the linked-to file, and not to the symbolic
+link itself. This flag is mutually exclusive with @code{FTS_PHYSICAL}.
+
+@item FTS_PHYSICAL
+Do a ``physical'' file traversal, where the information returned for a
+symbolic link refers to the symbolic link itself. This flag is mutually
+exclusive with @code{FTS_LOGICAL}.
+
+@item FTS_NOCHDIR
+As a performance optimization, the C library @code{fts()} routines
+change directory as they traverse a file hierarchy. This flag disables
+that optimization.
+
+@item FTS_COMFOLLOW
+Immediately follow a symbolic link named in @code{pathlist},
+whether or not @code{FTS_LOGICAL} is set.
+
+@item FTS_SEEDOT
+By default, the C library @code{fts()} routines do not return entries for
+@file{.} (dot) and @file{..} (dot-dot). This option causes entries for
+dot-dot to also be included. (The extension always includes an entry
+for dot; more on this in a moment.)
+
+@item FTS_XDEV
+During a traversal, do not cross onto a different mounted filesystem.
+@end table
+
+@item filedata
+The @code{filedata} array is first cleared. Then, @code{fts()} creates
+an element in @code{filedata} for every element in @code{pathlist}.
+The index is the name of the directory or file given in @code{pathlist}.
+The element for this index is itself an array. There are two cases:
+
+@c nested table
+@table @emph
+@item The path is a file
+In this case, the array contains two or three elements:
+
+@c doubly nested table
+@table @code
+@item "path"
+The full path to this file, starting from the ``root'' that was given
+in the @code{pathlist} array.
+
+@item "stat"
+This element is itself an array, containing the same information as provided
+by the @code{stat()} function described earlier for its
+@code{statdata} argument. The element may not be present if
+the @code{stat()} system call for the file failed.
+
+@item "error"
+If some kind of error was encountered, the array will also
+contain an element named @code{"error"}, which is a string describing the error.
+@end table
+
+@item The path is a directory
+In this case, the array contains one element for each entry in the
+directory. If an entry is a file, that element is the same as for files, just
+described. If the entry is a directory, that element is (recursively)
+an array describing the subdirectory. If @code{FTS_SEEDOT} was provided
+in the flags, then there will also be an element named @code{".."}. This
+element will be an array containing the data as provided by @code{stat()}.
+
+In addition, there will be an element whose index is @code{"."}.
+This element is an array containing the same two or three elements as
+for a file: @code{"path"}, @code{"stat"}, and @code{"error"}.
+@end table
+@end table
+
+The @code{fts()} function returns zero if there were no errors.
+Otherwise it returns @minus{}1.
+
+@quotation NOTE
+The @code{fts()} extension does not exactly mimic the
+interface of the C library @code{fts()} routines, choosing instead to
+provide an interface that is based on associative arrays, which is
+more comfortable to use from an @command{awk} program. This includes the
+lack of a comparison function, because @command{gawk} already provides
+powerful array sorting facilities. Although an @code{fts_read()}-like
+interface could have been provided, this felt less natural than simply
+creating a multidimensional array to represent the file hierarchy and
+its information.
+@end quotation
+
+See @file{test/fts.awk} in the @command{gawk} distribution for an example
+use of the @code{fts()} extension function.
+
+@node Extension Sample Fnmatch
+@subsection Interface to @code{fnmatch()}
+
+This extension provides an interface to the C library
+@code{fnmatch()} function. The usage is:
+
+@table @code
+@item @@load "fnmatch"
+This is how you load the extension.
+
+@cindex @code{fnmatch()} extension function
+@item result = fnmatch(pattern, string, flags)
+The return value is zero on success, @code{FNM_NOMATCH}
+if the string did not match the pattern, or
+a different nonzero value if an error occurred.
+@end table
+
+In addition to the @code{fnmatch()} function, the @code{fnmatch} extension
+adds one constant (@code{FNM_NOMATCH}), and an array of flag values
+named @code{FNM}.
+
+The arguments to @code{fnmatch()} are:
+
+@table @code
+@item pattern
+The @value{FN} wildcard to match.
+
+@item string
+The @value{FN} string.
+
+@item flag
+Either zero, or the bitwise OR of one or more of the
+flags in the @code{FNM} array.
+@end table
+
+The flags are as follows:
+
+@multitable @columnfractions .25 .75
+@headitem Array element @tab Corresponding flag defined by @code{fnmatch()}
+@item @code{FNM["CASEFOLD"]} @tab @code{FNM_CASEFOLD}
+@item @code{FNM["FILE_NAME"]} @tab @code{FNM_FILE_NAME}
+@item @code{FNM["LEADING_DIR"]} @tab @code{FNM_LEADING_DIR}
+@item @code{FNM["NOESCAPE"]} @tab @code{FNM_NOESCAPE}
+@item @code{FNM["PATHNAME"]} @tab @code{FNM_PATHNAME}
+@item @code{FNM["PERIOD"]} @tab @code{FNM_PERIOD}
+@end multitable
+
+Here is an example:
+
+@example
+@@load "fnmatch"
+@dots{}
+flags = or(FNM["PERIOD"], FNM["NOESCAPE"])
+if (fnmatch("*.a", "foo.c", flags) == FNM_NOMATCH)
+ print "no match"
+@end example
+
+@node Extension Sample Fork
+@subsection Interface to @code{fork()}, @code{wait()}, and @code{waitpid()}
+
+The @code{fork} extension adds three functions, as follows:
+
+@table @code
+@item @@load "fork"
+This is how you load the extension.
+
+@cindex @code{fork()} extension function
+@item pid = fork()
+This function creates a new process. The return value is zero in the
+child and the process-ID number of the child in the parent, or @minus{}1
+upon error. In the latter case, @code{ERRNO} indicates the problem.
+In the child, @code{PROCINFO["pid"]} and @code{PROCINFO["ppid"]} are
+updated to reflect the correct values.
+
+@cindex @code{waitpid()} extension function
+@item ret = waitpid(pid)
+This function takes a numeric argument, which is the process-ID to
+wait for. The return value is that of the
+@code{waitpid()} system call.
+
+@cindex @code{wait()} extension function
+@item ret = wait()
+This function waits for the first child to die.
+The return value is that of the
+@code{wait()} system call.
+@end table
+
+There is no corresponding @code{exec()} function.
+
+Here is an example:
+
+@example
+@@load "fork"
+@dots{}
+if ((pid = fork()) == 0)
+ print "hello from the child"
+else
+ print "hello from the parent"
+@end example
+
+@node Extension Sample Inplace
+@subsection Enabling In-Place File Editing
+
+@cindex @code{inplace} extension
+The @code{inplace} extension emulates GNU @command{sed}'s @option{-i} option
+which performs ``in place'' editing of each input file.
+It uses the bundled @file{inplace.awk} include file to invoke the extension
+properly:
+
+@example
+@c file eg/lib/inplace.awk
+@group
+# inplace --- load and invoke the inplace extension.
+
+@@load "inplace"
+
+# Please set INPLACE_SUFFIX to make a backup copy. For example, you may
+# want to set INPLACE_SUFFIX to .bak on the command line or in a BEGIN rule.
+
+BEGINFILE @{
+ inplace_begin(FILENAME, INPLACE_SUFFIX)
+@}
+
+ENDFILE @{
+ inplace_end(FILENAME, INPLACE_SUFFIX)
+@}
+@end group
+@c endfile
+@end example
+
+For each regular file that is processed, the extension redirects
+standard output to a temporary file configured to have the same owner
+and permissions as the original. After the file has been processed,
+the extension restores standard output to its original destination.
+If @code{INPLACE_SUFFIX} is not an empty string, the original file is
+linked to a backup @value{FN} created by appending that suffix. Finally,
+the temporary file is renamed to the original @value{FN}.
+
+If any error occurs, the extension issues a fatal error to terminate
+processing immediately without damaging the original file.
+
+Here are some simple examples:
+
+@example
+$ @kbd{gawk -i inplace '@{ gsub(/foo/, "bar") @}; @{ print @}' file1 file2 file3}
+@end example
+
+To keep a backup copy of the original files, try this:
+
+@example
+$ @kbd{gawk -i inplace -v INPLACE_SUFFIX=.bak '@{ gsub(/foo/, "bar") @}}
+> @kbd{@{ print @}' file1 file2 file3}
+@end example
+
+@node Extension Sample Ord
+@subsection Character and Numeric values: @code{ord()} and @code{chr()}
+
+The @code{ordchr} extension adds two functions, named
+@code{ord()} and @code{chr()}, as follows:
+
+@table @code
+@item @@load "ordchr"
+This is how you load the extension.
+
+@cindex @code{ord()} extension function
+@item number = ord(string)
+Return the numeric value of the first character in @code{string}.
+
+@cindex @code{chr()} extension function
+@item char = chr(number)
+Return a string whose first character is that represented by @code{number}.
+@end table
+
+These functions are inspired by the Pascal language functions
+of the same name. Here is an example:
+
+@example
+@@load "ordchr"
+@dots{}
+printf("The numeric value of 'A' is %d\n", ord("A"))
+printf("The string value of 65 is %s\n", chr(65))
+@end example
+
+@node Extension Sample Readdir
+@subsection Reading Directories
+
+The @code{readdir} extension adds an input parser for directories.
+The usage is as follows:
+
+@cindex @code{readdir} extension
+@example
+@@load "readdir"
+@end example
+
+When this extension is in use, instead of skipping directories named
+on the command line (or with @code{getline}),
+they are read, with each entry returned as a record.
+
+The record consists of three fields. The first two are the inode number and the
+@value{FN}, separated by a forward slash character.
+On systems where the directory entry contains the file type, the record
+has a third field (also separated by a slash) which is a single letter
+indicating the type of the file. The letters and their corresponding file
+types are shown in @ref{table-readdir-file-types}.
+
+@float Table,table-readdir-file-types
+@caption{File types returned by the @code{readdir} extension}
+@multitable @columnfractions .1 .9
+@headitem Letter @tab File Type
+@item @code{b} @tab Block device
+@item @code{c} @tab Character device
+@item @code{d} @tab Directory
+@item @code{f} @tab Regular file
+@item @code{l} @tab Symbolic link
+@item @code{p} @tab Named pipe (FIFO)
+@item @code{s} @tab Socket
+@item @code{u} @tab Anything else (unknown)
+@end multitable
+@end float
+
+On systems without the file type information, the third field is always
+@samp{u}.
+
+@quotation NOTE
+On GNU/Linux systems, there are filesystems that don't support the
+@code{d_type} entry (see the @i{readdir}(3) manual page), and so the file
+type is always @samp{u}. You can use the @code{filefuncs} extension to call
+@code{stat()} in order to get correct type information.
+@end quotation
+
+Here is an example:
+
+@example
+@@load "readdir"
+@dots{}
+BEGIN @{ FS = "/" @}
+@{ print "file name is", $2 @}
+@end example
+
+@node Extension Sample Revout
+@subsection Reversing Output
+
+The @code{revoutput} extension adds a simple output wrapper that reverses
+the characters in each output line. Its main purpose is to show how to
+write an output wrapper, although it may be mildly amusing for the unwary.
+Here is an example:
+
+@cindex @code{revoutput} extension
+@example
+@@load "revoutput"
+
+BEGIN @{
+ REVOUT = 1
+ print "don't panic" > "/dev/stdout"
+@}
+@end example
+
+The output from this program is:
+@samp{cinap t'nod}.
+
+@node Extension Sample Rev2way
+@subsection Two-Way I/O Example
+
+The @code{revtwoway} extension adds a simple two-way processor that
+reverses the characters in each line sent to it for reading back by
+the @command{awk} program. Its main purpose is to show how to write
+a two-way processor, although it may also be mildly amusing.
+The following example shows how to use it:
+
+@cindex @code{revtwoway} extension
+@example
+@@load "revtwoway"
+
+BEGIN @{
+ cmd = "/magic/mirror"
+ print "don't panic" |& cmd
+ cmd |& getline result
+ print result
+ close(cmd)
+@}
+@end example
+
+The output from this program
+@ifnotinfo
+also is:
+@end ifnotinfo
+@ifinfo
+is:
+@end ifinfo
+@samp{cinap t'nod}.
+
+@node Extension Sample Read write array
+@subsection Dumping and Restoring an Array
+
+The @code{rwarray} extension adds two functions,
+named @code{writea()} and @code{reada()}, as follows:
+
+@table @code
+@item @@load "rwarray"
+This is how you load the extension.
+
+@cindex @code{writea()} extension function
+@item ret = writea(file, array)
+This function takes a string argument, which is the name of the file
+to which to dump the array, and the array itself as the second argument.
+@code{writea()} understands arrays of arrays. It returns one on
+success, or zero upon failure.
+
+@cindex @code{reada()} extension function
+@item ret = reada(file, array)
+@code{reada()} is the inverse of @code{writea()};
+it reads the file named as its first argument, filling in
+the array named as the second argument. It clears the array first.
+Here too, the return value is one on success and zero upon failure.
+@end table
+
+The array created by @code{reada()} is identical to that written by
+@code{writea()} in the sense that the contents are the same. However,
+due to implementation issues, the array traversal order of the re-created
+array is likely to be different from that of the original array. As array
+traversal order in @command{awk} is by default undefined, this is (technically)
+not a problem. If you need to guarantee a particular traversal
+order, use the array sorting features in @command{gawk} to do so
+(@pxref{Array Sorting}).
+
+The file contains binary data. All integral values are written in network
+byte order. However, double-precision floating-point values are written
+as native binary data. Thus, arrays containing only string data can
+theoretically be dumped on systems with one byte order and restored on
+systems with a different one, but this has not been tried.
+
+Here is an example:
+
+@example
+@@load "rwarray"
+@dots{}
+ret = writea("arraydump.bin", array)
+@dots{}
+ret = reada("arraydump.bin", array)
+@end example
+
+@node Extension Sample Readfile
+@subsection Reading an Entire File
+
+The @code{readfile} extension adds a single function
+named @code{readfile()}, and an input parser:
+
+@table @code
+@item @@load "readfile"
+This is how you load the extension.
+
+@cindex @code{readfile()} extension function
+@item result = readfile("/some/path")
+The argument is the name of the file to read. The return value is a
+string containing the entire contents of the requested file. Upon error,
+the function returns the empty string and sets @code{ERRNO}.
+
+@item BEGIN @{ PROCINFO["readfile"] = 1 @}
+In addition, the extension adds an input parser that is activated if
+@code{PROCINFO["readfile"]} exists.
+When activated, each input file is returned in its entirety as @code{$0}.
+@code{RT} is set to the null string.
+@end table
+
+Here is an example:
+
+@example
+@@load "readfile"
+@dots{}
+contents = readfile("/path/to/file");
+if (contents == "" && ERRNO != "") @{
+ print("problem reading file", ERRNO) > "/dev/stderr"
+ ...
+@}
+@end example
+
+@node Extension Sample Time
+@subsection Extension Time Functions
+
+The @code{time} extension adds two functions, named @code{gettimeofday()}
+and @code{sleep()}, as follows:
+
+@table @code
+@item @@load "time"
+This is how you load the extension.
+
+@cindex @code{gettimeofday()} extension function
+@item the_time = gettimeofday()
+Return the time in seconds that has elapsed since 1970-01-01 UTC as a
+floating-point value. If the time is unavailable on this platform, return
+@minus{}1 and set @code{ERRNO}. The returned time should have sub-second
+precision, but the actual precision may vary based on the platform.
+If the standard C @code{gettimeofday()} system call is available on this
+platform, then it simply returns the value. Otherwise, if on MS-Windows,
+it tries to use @code{GetSystemTimeAsFileTime()}.
+
+@cindex @code{sleep()} extension function
+@item result = sleep(@var{seconds})
+Attempt to sleep for @var{seconds} seconds. If @var{seconds} is negative,
+or the attempt to sleep fails, return @minus{}1 and set @code{ERRNO}.
+Otherwise, return zero after sleeping for the indicated amount of time.
+Note that @var{seconds} may be a floating-point (non-integral) value.
+Implementation details: depending on platform availability, this function
+tries to use @code{nanosleep()} or @code{select()} to implement the delay.
+@end table
+
+@node Extension Sample API Tests
+@subsection API Tests
+@cindex @code{testext} extension
+
+The @code{testext} extension exercises parts of the extension API that
+are not tested by the other samples. The @file{extension/testext.c}
+file contains both the C code for the extension and @command{awk}
+test code inside C comments that run the tests. The testing framework
+extracts the @command{awk} code and runs the tests. See the source file
+for more information.
+
+@node gawkextlib
+@section The @code{gawkextlib} Project
+@cindex @code{gawkextlib}
+@cindex extensions, where to find
+
+@cindex @code{gawkextlib} project
+The @uref{http://sourceforge.net/projects/gawkextlib/, @code{gawkextlib}}
+project provides a number of @command{gawk} extensions, including one for
+processing XML files. This is the evolution of the original @command{xgawk}
+(XML @command{gawk}) project.
+
+As of this writing, there are six extensions:
+
+@itemize @value{BULLET}
+@item
+GD graphics library extension
+
+@item
+PDF extension
+
+@item
+PostgreSQL extension
+
+@item
+MPFR library extension
+(this provides access to a number of MPFR functions which @command{gawk}'s
+native MPFR support does not)
+
+@item
+Redis extension
+
+@item
+XML parser extension, using the @uref{http://expat.sourceforge.net, Expat}
+XML parsing library
+@end itemize
+
+@cindex @command{git} utility
+You can check out the code for the @code{gawkextlib} project
+using the @uref{http://git-scm.com, Git} distributed source
+code control system. The command is as follows:
+
+@example
+git clone git://git.code.sf.net/p/gawkextlib/code gawkextlib-code
+@end example
+
+@cindex Expat XML parser library
+You will need to have the @uref{http://expat.sourceforge.net, Expat}
+XML parser library installed in order to build and use the XML extension.
+
+In addition, you must have the GNU Autotools installed
+(@uref{http://www.gnu.org/software/autoconf, Autoconf},
+@uref{http://www.gnu.org/software/automake, Automake},
+@uref{http://www.gnu.org/software/libtool, Libtool},
+and
+@uref{http://www.gnu.org/software/gettext, GNU @command{gettext}}).
+
+The simple recipe for building and testing @code{gawkextlib} is as follows.
+First, build and install @command{gawk}:
+
+@example
+cd .../path/to/gawk/code
+./configure --prefix=/tmp/newgawk @ii{Install in /tmp/newgawk for now}
+make && make check @ii{Build and check that all is OK}
+make install @ii{Install gawk}
+@end example
+
+Next, build @code{gawkextlib} and test it:
+
+@example
+cd .../path/to/gawkextlib-code
+./update-autotools @ii{Generate configure, etc.}
+ @ii{You may have to run this command twice}
+./configure --with-gawk=/tmp/newgawk @ii{Configure, point at ``installed'' gawk}
+make && make check @ii{Build and check that all is OK}
+make install @ii{Install the extensions}
+@end example
+
+If you have installed @command{gawk} in the standard way, then you
+will likely not need the @option{--with-gawk} option when configuring
+@code{gawkextlib}. You may also need to use the @command{sudo} utility
+to install both @command{gawk} and @code{gawkextlib}, depending upon
+how your system works.
+
+If you write an extension that you wish to share with other
+@command{gawk} users, consider doing so through the
+@code{gawkextlib} project.
+See the project's website for more information.
+
+@node Extension summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+You can write extensions (sometimes called plug-ins) for @command{gawk}
+in C or C++ using the application programming interface (API) defined
+by the @command{gawk} developers.
+
+@item
+Extensions must have a license compatible with the GNU General Public
+License (GPL), and they must assert that fact by declaring a variable
+named @code{plugin_is_GPL_compatible}.
+
+@item
+Communication between @command{gawk} and an extension is two-way.
+@command{gawk} passes a @code{struct} to the extension which contains
+various data fields and function pointers. The extension can then call
+into @command{gawk} via the supplied function pointers to accomplish
+certain tasks.
+
+@item
+One of these tasks is to ``register'' the name and implementation of
+new @command{awk}-level functions with @command{gawk}. The implementation
+takes the form of a C function pointer with a defined signature.
+By convention, implementation functions are named @code{do_@var{XXXX}()}
+for some @command{awk}-level function @code{@var{XXXX}()}.
+
+@item
+The API is defined in a header file named @file{gawkpi.h}. You must include
+a number of standard header files @emph{before} including it in your source file.
+
+@item
+API function pointers are provided for the following kinds of operations:
+
+@itemize @value{BULLET}
+@item
+Allocating, reallocating, and releasing memory
+
+@item
+Registration functions (you may register
+extension functions,
+exit callbacks,
+a version string,
+input parsers,
+output wrappers,
+and two-way processors)
+
+@item
+Printing fatal, warning, and ``lint'' warning messages
+
+@item
+Updating @code{ERRNO}, or unsetting it
+
+@item
+Accessing parameters, including converting an undefined parameter into
+an array
+
+@item
+Symbol table access (retrieving a global variable, creating one,
+or changing one)
+
+@item
+Creating and releasing cached values; this provides an
+efficient way to use values for multiple variables and
+can be a big performance win
+
+@item
+Manipulating arrays
+(retrieving, adding, deleting, and modifying elements;
+getting the count of elements in an array;
+creating a new array;
+clearing an array;
+and
+flattening an array for easy C style looping over all its indices and elements)
+@end itemize
+
+@item
+The API defines a number of standard data types for representing
+@command{awk} values, array elements, and arrays.
+
+@item
+The API provide convenience functions for constructing values.
+It also provides memory management functions to ensure compatibility
+between memory allocated by @command{gawk} and memory allocated by an
+extension.
+
+@item
+@emph{All} memory passed from @command{gawk} to an extension must be
+treated as read-only by the extension.
+
+@item
+@emph{All} memory passed from an extension to @command{gawk} must come from
+the API's memory allocation functions. @command{gawk} takes responsibility for
+the memory and releases it when appropriate.
+
+@item
+The API provides information about the running version of @command{gawk} so
+that an extension can make sure it is compatible with the @command{gawk}
+that loaded it.
+
+@item
+It is easiest to start a new extension by copying the boilerplate code
+described in this @value{CHAPTER}. Macros in the @file{gawkapi.h} header
+file make this easier to do.
+
+@item
+The @command{gawk} distribution includes a number of small but useful
+sample extensions. The @code{gawkextlib} project includes several more,
+larger, extensions. If you wish to write an extension and contribute it
+to the community of @command{gawk} users, the @code{gawkextlib} project
+is the place to do so.
+
+@end itemize
+
+@c EXCLUDE START
+@node Extension Exercises
+@section Exercises
+
+@enumerate
+@item
+Add functions to implement system calls such as @code{chown()},
+@code{chmod()}, and @code{umask()} to the file operations extension
+presented in @ref{Internal File Ops}.
+
+@item
+(Hard.)
+How would you provide namespaces in @command{gawk}, so that the
+names of functions in different extensions don't conflict with each other?
+If you come up with a really good scheme, contact the @command{gawk}
+maintainer to tell him about it.
+
+@item
+Write a wrapper script that provides an interface similar to
+@samp{sed -i} for the ``inplace'' extension presented in
+@ref{Extension Sample Inplace}.
+
+@end enumerate
+@c EXCLUDE END
+
+@ifnotinfo
+@part @value{PART4}Appendices
+@end ifnotinfo
+
+@ifdocbook
+
+@ifclear FOR_PRINT
+Part IV contains the appendices (including the two licenses that cover
+the @command{gawk} source code and this @value{DOCUMENT}, respectively)
+and the Glossary:
+@end ifclear
+
+@ifset FOR_PRINT
+Part IV contains three appendices, the last of which is the license that
+covers the @command{gawk} source code:
+@end ifset
+
+@itemize @value{BULLET}
+@item
+@ref{Language History}
+
+@item
+@ref{Installation}
+
+@ifclear FOR_PRINT
+@item
+@ref{Notes}
+
+@item
+@ref{Basic Concepts}
+
+@item
+@ref{Glossary}
+@end ifclear
+
+@item
+@ref{Copying}
+
+@ifclear FOR_PRINT
+@item
+@ref{GNU Free Documentation License}
+@end ifclear
+@end itemize
+@end ifdocbook
@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 some 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.
-
-@c FIXME: Try to determine whether it was 3.1 or 3.2 that had new awk.
+This @value{DOCUMENT} describes the GNU implementation of @command{awk},
+which follows the POSIX specification. Many longtime @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, for a while, some systems derived from 4.4BSD-Lite, used 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.
+
+@ifset FOR_PRINT
+To save space, we have omitted
+information on the history of features in @command{gawk} from this
+edition. You can find it in the
+@uref{http://www.gnu.org/software/gawk/manual/html_node/Feature-History.html,
+online documentation}.
+@end ifset
@menu
* V7/SVR3.1:: The major changes between V7 and System V
@@ -26465,16 +35270,16 @@ of the @value{DOCUMENT} where you can find more information.
@command{awk}.
* POSIX/GNU:: The extensions in @command{gawk} not in POSIX
@command{awk}.
+* Feature History:: The history of the features in @command{gawk}.
* Common Extensions:: Common Extensions Summary.
* Ranges and Locales:: How locales used to affect regexp ranges.
* Contributors:: The major contributors to @command{gawk}.
+* History summary:: History summary.
@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
@@ -26482,7 +35287,7 @@ Version 7 Unix (1978) and the new version that was first made generally availabl
System V Release 3.1 (1987). This @value{SECTION} summarizes the changes, with
cross-references to further details:
-@itemize @bullet
+@itemize @value{BULLET}
@item
The requirement for @samp{;} to separate rules on a line
(@pxref{Statements/Lines}).
@@ -26512,7 +35317,7 @@ The built-in functions @code{close()} and @code{system()}
@item
The @code{ARGC}, @code{ARGV}, @code{FNR}, @code{RLENGTH}, @code{RSTART},
-and @code{SUBSEP} built-in variables (@pxref{Built-in Variables}).
+and @code{SUBSEP} predefined variables (@pxref{Built-in Variables}).
@item
Assignable @code{$0} (@pxref{Changing Fields}).
@@ -26543,14 +35348,11 @@ of @code{FS}.
@item
Dynamic regexps as operands of the @samp{~} and @samp{!~} operators
-(@pxref{Regexp Usage}).
+(@pxref{Computed Regexps}).
@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
@@ -26562,9 +35364,8 @@ Multiple @code{BEGIN} and @code{END} rules
@item
Multidimensional arrays
-(@pxref{Multi-dimensional}).
+(@pxref{Multidimensional}).
@end itemize
-@c ENDOFRANGE gawkv1
@node SVR4
@appendixsec Changes Between SVR3.1 and SVR4
@@ -26573,7 +35374,7 @@ Multidimensional arrays
The System V Release 4 (1989) version of Unix @command{awk} added these features
(some of which originated in @command{gawk}):
-@itemize @bullet
+@itemize @value{BULLET}
@item
The @code{ENVIRON} array (@pxref{Built-in Variables}).
@c gawk and MKS awk
@@ -26589,7 +35390,7 @@ The @option{-v} option for assigning variables before program execution begins
@c GNU, Bell Laboratories & MKS together
@item
-The @option{--} option for terminating command-line options.
+The @option{--} signal for terminating command-line options.
@item
The @samp{\a}, @samp{\v}, and @samp{\x} escape sequences
@@ -26612,7 +35413,7 @@ A cleaner specification for the @samp{%c} format-control letter in the
@item
The ability to dynamically pass the field width and precision (@code{"%*.*d"})
-in the argument list of the @code{printf} function
+in the argument list of @code{printf} and @code{sprintf()}
(@pxref{Control Letters}).
@item
@@ -26633,7 +35434,7 @@ Processing of escape sequences inside command-line variable assignments
The POSIX Command Language and Utilities standard for @command{awk} (1992)
introduced the following changes into the language:
-@itemize @bullet
+@itemize @value{BULLET}
@item
The use of @option{-W} for implementation-specific options
(@pxref{Options}).
@@ -26647,21 +35448,38 @@ The concept of a numeric string and tighter comparison rules to go
with it (@pxref{Typing and Comparison}).
@item
-The use of built-in variables as function parameter names is forbidden
-(@pxref{Definition Syntax}.
+The use of predefined variables as function parameter names is forbidden
+(@pxref{Definition Syntax}).
@item
More complete documentation of many of the previously undocumented
features of the language.
@end itemize
-@xref{Common Extensions}, for a list of common extensions
+In 2012, a number of extensions that had been commonly available for
+many years were finally added to POSIX. They are:
+
+@itemize @value{BULLET}
+@item
+The @code{fflush()} built-in function for flushing buffered output
+(@pxref{I/O Functions}).
+
+@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
+
+@DBXREF{Common Extensions} for a list of common extensions
not permitted by the POSIX standard.
The 2008 POSIX standard can be found online at
@url{http://www.opengroup.org/onlinepubs/9699919799/}.
-@c ENDOFRANGE gawkv
@node BTL
@appendixsec Extensions in Brian Kernighan's @command{awk}
@@ -26675,9 +35493,9 @@ has made his version available via his home page
(@pxref{Other Versions}).
This @value{SECTION} describes common extensions that
-originally appeared in his version of @command{awk}.
+originally appeared in his version of @command{awk}:
-@itemize @bullet
+@itemize @value{BULLET}
@item
The @samp{**} and @samp{**=} operators
(@pxref{Arithmetic Ops}
@@ -26695,23 +35513,20 @@ The @code{fflush()} built-in function for flushing buffered output
@ignore
@item
The @code{SYMTAB} array, that allows access to @command{awk}'s internal symbol
-table. This feature is not documented, largely because
+table. This feature was never documented for his @command{awk}, largely because
it is somewhat shakily implemented. For instance, you cannot access arrays
or array elements through it.
@end ignore
@end itemize
-@xref{Common Extensions}, for a full list of the extensions
+@DBXREF{Common Extensions} for a full list of the extensions
available in his @command{awk}.
@node POSIX/GNU
@appendixsec Extensions in @command{gawk} Not in POSIX @command{awk}
-@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.
They can all be disabled with either the @option{--traditional} or
@@ -26722,12 +35537,12 @@ A number of features have come and gone over the years. This @value{SECTION}
summarizes the additional features over POSIX @command{awk} that are
in the current version of @command{gawk}.
-@itemize @bullet
+@itemize @value{BULLET}
@item
-Additional built-in variables:
+Additional predefined variables:
-@itemize @minus
+@itemize @value{MINUS}
@item
The
@code{ARGIND}
@@ -26748,7 +35563,7 @@ variables
@item
Special files in I/O redirections:
-@itemize @minus{}
+@itemize @value{MINUS}
@item
The @file{/dev/stdin}, @file{/dev/stdout}, @file{/dev/stderr} and
@file{/dev/fd/@var{N}} special @value{FN}s
@@ -26757,14 +35572,14 @@ The @file{/dev/stdin}, @file{/dev/stdout}, @file{/dev/stderr} and
@item
The @file{/inet}, @file{/inet4}, and @samp{/inet6} special files for
TCP/IP networking using @samp{|&} to specify which version of the
-IP protocol to use.
+IP protocol to use
(@pxref{TCP/IP Networking}).
@end itemize
@item
Changes and/or additions to the language:
-@itemize @minus{}
+@itemize @value{MINUS}
@item
The @samp{\x} escape sequence
(@pxref{Escape Sequences}).
@@ -26797,26 +35612,18 @@ Indirect function calls
@item
Directories on the command line produce a warning and are skipped
-(@pxref{Command line directories}).
+(@pxref{Command-line directories}).
@end itemize
@item
New keywords:
-@itemize @minus{}
+@itemize @value{MINUS}
@item
-The @code{BEGINFILE} and @code{ENDFILE} special patterns.
+The @code{BEGINFILE} and @code{ENDFILE} special patterns
(@pxref{BEGINFILE/ENDFILE}).
@item
-The ability to delete all of an array at once with @samp{delete @var{array}}
-(@pxref{Delete}).
-
-@item
-The @code{nextfile} statement
-(@pxref{Nextfile Statement}).
-
-@item
The @code{switch} statement
(@pxref{Switch Statement}).
@end itemize
@@ -26824,14 +35631,14 @@ The @code{switch} statement
@item
Changes to standard @command{awk} functions:
-@itemize @minus
+@itemize @value{MINUS}
@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
-POSIX compliance for @code{gsub()} and @code{sub()}.
+POSIX compliance for @code{gsub()} and @code{sub()} with @option{--posix}.
@item
The @code{length()} function accepts an array argument
@@ -26850,14 +35657,28 @@ making translations easier
@item
The @code{split()} function's additional optional fourth
-argument which is an array to hold the text of the field separators.
+argument which is an array to hold the text of the field separators
(@pxref{String Functions}).
@end itemize
@item
Additional functions only in @command{gawk}:
-@itemize @minus
+@itemize @value{MINUS}
+@item
+The @code{gensub()}, @code{patsplit()}, and @code{strtonum()} functions
+for more powerful text manipulation
+(@pxref{String Functions}).
+
+@item
+The @code{asort()} and @code{asorti()} functions for sorting arrays
+(@pxref{Array Sorting}).
+
+@item
+The @code{mktime()}, @code{systime()}, and @code{strftime()}
+functions for working with timestamps
+(@pxref{Time Functions}).
+
@item
The
@code{and()},
@@ -26869,71 +35690,92 @@ and
@code{xor()}
functions for bit manipulation
(@pxref{Bitwise Functions}).
+@c In 4.1, and(), or() and xor() grew the ability to take > 2 arguments
@item
-The @code{asort()} and @code{asorti()} functions for sorting arrays
-(@pxref{Array Sorting}).
+The @code{isarray()} function to check if a variable is an array or not
+(@pxref{Type Functions}).
@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 functions dynamically
-(@pxref{Dynamic Extensions}).
-
-@item
-The @code{fflush()} function from Brian Kernighan's
-version of @command{awk}
-(@pxref{I/O Functions}).
-
-@item
-The @code{gensub()}, @code{patsplit()}, and @code{strtonum()} functions
-for more powerful text manipulation
-(@pxref{String Functions}).
-
-@item
-The @code{mktime()}, @code{systime()}, and @code{strftime()}
-functions for working with timestamps
-(@pxref{Time Functions}).
@end itemize
-
@item
Changes and/or additions in the command-line options:
-@itemize @minus
+@itemize @value{MINUS}
@item
The @env{AWKPATH} environment variable for specifying a path search for
the @option{-f} command-line option
(@pxref{Options}).
@item
-The ability to use GNU-style long-named options that start with @option{--}
+The @env{AWKLIBPATH} environment variable for specifying a path search for
+the @option{-l} command-line option
+(@pxref{Options}).
+
+@item
+The
+@option{-b},
+@option{-c},
+@option{-C},
+@option{-d},
+@option{-D},
+@option{-e},
+@option{-E},
+@option{-g},
+@option{-h},
+@option{-i},
+@option{-l},
+@option{-L},
+@option{-M},
+@option{-n},
+@option{-N},
+@option{-o},
+@option{-O},
+@option{-p},
+@option{-P},
+@option{-r},
+@option{-S},
+@option{-t},
+and
+@option{-V}
+short options. Also, the
+ability to use GNU-style long-named options that start with @option{--}
and the
+@option{--assign},
+@option{--bignum},
@option{--characters-as-bytes},
-@option{--compat},
+@option{--copyright},
+@option{--debug},
@option{--dump-variables},
@option{--exec},
+@option{--field-separator},
+@option{--file},
@option{--gen-pot},
+@option{--help},
+@option{--include},
@option{--lint},
@option{--lint-old},
+@option{--load},
@option{--non-decimal-data},
+@option{--optimize},
@option{--posix},
+@option{--pretty-print},
@option{--profile},
@option{--re-interval},
@option{--sandbox},
@option{--source},
@option{--traditional},
+@option{--use-lc-numeric},
and
-@option{--use-lc-numeric}
-options
+@option{--version}
+long options
(@pxref{Options}).
@end itemize
-
@c new ports
@item
@@ -26941,7 +35783,7 @@ Support for the following obsolete systems was removed from the code
and the documentation for @command{gawk} @value{PVERSION} 4.0:
@c nested table
-@itemize @minus
+@itemize @value{MINUS}
@item
Amiga
@@ -26975,39 +35817,668 @@ Tandem (non-POSIX)
@item
Prestandard VAX C compiler for VAX/VMS
+@item
+GCC for VAX and Alpha has not been tested for a while.
+
+@end itemize
+
+@item
+Support for the following obsolete systems was removed from the code
+for @command{gawk} @value{PVERSION} 4.1:
+
+@c nested table
+@itemize @value{MINUS}
+@item
+Ultrix
@end itemize
+@item
+@c FIXME: Verify the version here.
+Support for MirBSD was removed at @command{gawk} @value{PVERSION} 4.2.
+
@end itemize
@c XXX ADD MORE STUFF HERE
-@c ENDOFRANGE fripls
-@c ENDOFRANGE exgnot
-@c ENDOFRANGE posnot
+
+@c This does not need to be in the formal book.
+@ifclear FOR_PRINT
+@node Feature History
+@appendixsec History of @command{gawk} Features
+
+@ignore
+See the thread:
+https://groups.google.com/forum/#!topic/comp.lang.awk/SAUiRuff30c
+This motivated me to add this section.
+@end ignore
+
+@ignore
+I've tried to follow this general order, esp.@: for the 3.0 and 3.1 sections:
+ variables
+ special files
+ language changes (e.g., hex constants)
+ differences in standard awk functions
+ new gawk functions
+ new keywords
+ new command-line options
+ behavioral changes
+ new ports
+Within each category, be alphabetical.
+@end ignore
+
+This @value{SECTION} describes the features in @command{gawk}
+over and above those in POSIX @command{awk},
+in the order they were added to @command{gawk}.
+
+Version 2.10 of @command{gawk} introduced the following features:
+
+@itemize @value{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 @value{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
+Additional command-line options
+(@pxref{Options}):
+
+@itemize @value{MINUS}
+@item
+The @option{-W lint} option to provide error and portability checking
+for both the source code and at runtime.
+
+@item
+The @option{-W compat} option to turn off the GNU extensions.
+
+@item
+The @option{-W posix} option for full POSIX compliance.
+@end itemize
+@end itemize
+
+Version 2.14 of @command{gawk} introduced the following feature:
+
+@itemize @value{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 @value{BULLET}
+@item
+New variables (@pxref{Built-in Variables}):
+
+@itemize @value{MINUS}
+@item
+@code{ARGIND}, which tracks the movement of @code{FILENAME}
+through @code{ARGV}.
+
+@item
+@code{ERRNO}, which contains the system error message when
+@code{getline} returns @minus{}1 or @code{close()} fails.
+@end itemize
+
+@item
+The @file{/dev/pid}, @file{/dev/ppid}, @file{/dev/pgrpid}, and
+@file{/dev/user} special @value{FN}s. These have since been removed.
+
+@item
+The ability to delete all of an array at once with @samp{delete @var{array}}
+(@pxref{Delete}).
+
+@item
+Command-line option changes
+(@pxref{Options}):
+
+@itemize @value{MINUS}
+@item
+The ability to use GNU-style long-named options that start with @option{--}.
+
+@item
+The @option{--source} option for mixing command-line and library-file
+source code.
+@end itemize
+@end itemize
+
+Version 3.0 of @command{gawk} introduced the following features:
+
+@itemize @value{BULLET}
+@item
+New or changed variables:
+
+@itemize @value{MINUS}
+@item
+@code{IGNORECASE} changed, now applying to string comparison as well
+as regexp operations
+(@pxref{Case-sensitivity}).
+
+@item
+@code{RT}, which contains the input text that matched @code{RS}
+(@pxref{Records}).
+@end itemize
+
+@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 @code{fflush()} function from
+BWK @command{awk}
+(then at Bell Laboratories;
+@pxref{I/O Functions}).
+
+@item
+New command-line options:
+
+@itemize @value{MINUS}
+@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 from BWK @command{awk}. (Brian was
+still at Bell Laboratories at the time.) This was later removed from
+both his @command{awk} and from @command{gawk}.
+
+@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}).
+@end itemize
+
+@item
+The use of GNU Autoconf to control the configuration process
+(@pxref{Quick Installation}).
+
+@item
+Amiga support.
+This has since been removed.
+
+@end itemize
+
+Version 3.1 of @command{gawk} introduced the following features:
+
+@itemize @value{BULLET}
+@item
+New variables
+(@pxref{Built-in Variables}):
+
+@itemize @value{MINUS}
+@item
+@code{BINMODE}, for non-POSIX systems,
+which allows binary I/O for input and/or output files
+(@pxref{PC Using}).
+
+@item
+@code{LINT}, which dynamically controls lint warnings.
+
+@item
+@code{PROCINFO}, an array for providing process-related information.
+
+@item
+@code{TEXTDOMAIN}, for setting an application's internationalization text domain
+(@pxref{Internationalization}).
+@end itemize
+
+@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
+A number of new built-in functions:
+
+@itemize @value{MINUS}
+@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()} function and the ability to add
+new built-in functions dynamically
+(@pxref{Dynamic Extensions}).
+
+@item
+The @code{mktime()} function for creating timestamps
+(@pxref{Time Functions}).
+
+@item
+The @code{and()}, @code{or()}, @code{xor()}, @code{compl()},
+@code{lshift()}, @code{rshift()}, and @code{strtonum()} functions
+(@pxref{Bitwise Functions}).
+@end itemize
+
+@item
+@cindex @code{next file} statement
+The support for @samp{next file} as two words was removed completely
+(@pxref{Nextfile Statement}).
+
+@item
+Additional command-line options
+(@pxref{Options}):
+
+@itemize @value{MINUS}
+@item
+The @option{--dump-variables} option to print a list of all global variables.
+
+@item
+The @option{--exec} option, for use in CGI scripts.
+
+@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{--use-lc-numeric} option to force @command{gawk}
+to use the locale's decimal point for parsing input data
+(@pxref{Conversion}).
+@end itemize
+
+@item
+The use of GNU Automake to help in standardizing the configuration process
+(@pxref{Quick Installation}).
+
+@item
+The use of GNU @command{gettext} for @command{gawk}'s own message output
+(@pxref{Gawk I18N}).
+
+@item
+BeOS support. This was later removed.
+
+@item
+Tandem support. This was later removed.
+
+@item
+The Atari port became officially unsupported and was
+later removed entirely.
+
+@item
+The source code changed to use ISO C standard-style function definitions.
+
+@item
+POSIX compliance for @code{sub()} and @code{gsub()}
+(@pxref{Gory Details}).
+
+@item
+The @code{length()} function was extended to accept an array argument
+and return the number of elements in the array
+(@pxref{String Functions}).
+
+@item
+The @code{strftime()} function acquired a third argument to
+enable printing times as UTC
+(@pxref{Time Functions}).
+@end itemize
+
+Version 4.0 of @command{gawk} introduced the following features:
+
+@itemize @value{BULLET}
+
+@item
+Variable additions:
+
+@itemize @value{MINUS}
+@item
+@code{FPAT}, which allows you to specify a regexp that matches
+the fields, instead of matching the field separator
+(@pxref{Splitting By Content}).
+
+@item
+If @code{PROCINFO["sorted_in"]} exists, @samp{for(iggy in foo)} loops sort the
+indices before looping over them. The value of this element
+provides control over how the indices are sorted before the loop
+traversal starts
+(@pxref{Controlling Scanning}).
+
+@item
+@code{PROCINFO["strftime"]}, which holds
+the default format for @code{strftime()}
+(@pxref{Time Functions}).
+@end itemize
+
+@item
+The special files @file{/dev/pid}, @file{/dev/ppid}, @file{/dev/pgrpid}
+and @file{/dev/user} were removed.
+
+@item
+Support for IPv6 was added via the @file{/inet6} special file.
+@file{/inet4} forces IPv4 and @file{/inet} chooses the system
+default, which is probably IPv4
+(@pxref{TCP/IP Networking}).
+
+@item
+The use of @samp{\s} and @samp{\S} escape sequences in regular expressions
+(@pxref{GNU Regexp Operators}).
+
+@item
+Interval expressions became part of default regular expressions
+(@pxref{Regexp Operators}).
+
+@item
+POSIX character classes work even with @option{--traditional}
+(@pxref{Regexp Operators}).
+
+@item
+@code{break} and @code{continue} became invalid outside a loop,
+even with @option{--traditional}
+(@pxref{Break Statement}, and also see
+@ref{Continue Statement}).
+
+@item
+@code{fflush()}, @code{nextfile}, and @samp{delete @var{array}}
+are allowed if @option{--posix} or @option{--traditional}, since they
+are all now part of POSIX.
+
+@item
+An optional third argument to
+@code{asort()} and @code{asorti()}, specifying how to sort
+(@pxref{String Functions}).
+
+@item
+The behavior of @code{fflush()} changed to match BWK @command{awk}
+and for POSIX; now both @samp{fflush()} and @samp{fflush("")}
+flush all open output redirections
+(@pxref{I/O Functions}).
+
+@item
+The @code{isarray()}
+function which distinguishes if an item is an array
+or not, to make it possible to traverse arrays of arrays
+(@pxref{Type Functions}).
+
+@item
+The @code{patsplit()}
+function which gives the same capability as @code{FPAT}, for splitting
+(@pxref{String Functions}).
+
+@item
+An optional fourth argument to the @code{split()} function,
+which is an array to hold the values of the separators
+(@pxref{String Functions}).
+
+@item
+Arrays of arrays
+(@pxref{Arrays of Arrays}).
+
+@item
+The @code{BEGINFILE} and @code{ENDFILE} special patterns
+(@pxref{BEGINFILE/ENDFILE}).
+
+@item
+Indirect function calls
+(@pxref{Indirect Calls}).
+
+@item
+@code{switch} / @code{case} are enabled by default
+(@pxref{Switch Statement}).
+
+@item
+Command-line option changes
+(@pxref{Options}):
+
+@itemize @value{MINUS}
+@item
+The @option{-b} and @option{--characters-as-bytes} options
+which prevent @command{gawk} from treating input as a multibyte string.
+
+@item
+The redundant @option{--compat}, @option{--copyleft}, and @option{--usage}
+long options were removed.
+
+@item
+The @option{--gen-po} option was finally renamed to the correct @option{--gen-pot}.
+
+@item
+The @option{--sandbox} option which disables certain features.
+
+@item
+All long options acquired corresponding short options, for use in @samp{#!} scripts.
+@end itemize
+
+@item
+Directories named on the command line now produce a warning, not a fatal
+error, unless @option{--posix} or @option{--traditional} are used
+(@pxref{Command-line directories}).
+
+@item
+The @command{gawk} internals were rewritten, bringing the @command{dgawk}
+debugger and possibly improved performance
+(@pxref{Debugger}).
+
+@item
+Per the GNU Coding Standards, dynamic extensions must now define
+a global symbol indicating that they are GPL-compatible
+(@pxref{Plugin License}).
+
+@item
+In POSIX mode, string comparisons use @code{strcoll()} / @code{wcscoll()}
+(@pxref{POSIX String Comparison}).
+
+@item
+The option for raw sockets was removed, since it was never implemented
+(@pxref{TCP/IP Networking}).
+
+@item
+Ranges of the form @samp{[d-h]} are treated as if they were in the
+C locale, no matter what kind of regexp is being used, and even if
+@option{--posix}
+(@pxref{Ranges and Locales}).
+
+@item
+Support was removed for the following systems:
+
+@itemize @value{MINUS}
+@item
+Atari
+
+@item
+Amiga
+
+@item
+BeOS
+
+@item
+Cray
+
+@item
+MIPS RiscOS
+
+@item
+MS-DOS with Microsoft Compiler
+
+@item
+MS-Windows with Microsoft Compiler
+
+@item
+NeXT
+
+@item
+SunOS 3.x, Sun 386 (Road Runner)
+
+@item
+Tandem (non-POSIX)
+
+@item
+Prestandard VAX C compiler for VAX/VMS
+@end itemize
+@end itemize
+
+Version 4.1 of @command{gawk} introduced the following features:
+
+@itemize @value{BULLET}
+
+@item
+Three new arrays:
+@code{SYMTAB}, @code{FUNCTAB}, and @code{PROCINFO["identifiers"]}
+(@pxref{Auto-set}).
+
+@item
+The three executables @command{gawk}, @command{pgawk}, and @command{dgawk}, were merged into
+one, named just @command{gawk}. As a result the command-line options changed.
+
+@item
+Command-line option changes
+(@pxref{Options}):
+
+@itemize @value{MINUS}
+@item
+The @option{-D} option invokes the debugger.
+
+@item
+The @option{-i} and @option{--include} options
+load @command{awk} library files.
+
+@item
+The @option{-l} and @option{--load} options load compiled dynamic extensions.
+
+@item
+The @option{-M} and @option{--bignum} options enable MPFR.
+
+@item
+The @option{-o} option only does pretty-printing.
+
+@item
+The @option{-p} option is used for profiling.
+
+@item
+The @option{-R} option was removed.
+@end itemize
+
+@item
+Support for high precision arithmetic with MPFR.
+(@pxref{Arbitrary Precision Arithmetic}).
+
+@item
+The @code{and()}, @code{or()} and @code{xor()} functions
+changed to allow any number of arguments,
+with a minimum of two
+(@pxref{Bitwise Functions}).
+
+@item
+The dynamic extension interface was completely redone
+(@pxref{Dynamic Extensions}).
+
+@end itemize
+
+@c XXX ADD MORE STUFF HERE
+@end ifclear
@node Common Extensions
@appendixsec Common Extensions Summary
-This @value{SECTION} summarizes the common extensions supported
+@cindex extensions, Brian Kernighan's @command{awk}
+@cindex extensions, @command{mawk}
+The following table summarizes the common extensions supported
by @command{gawk}, Brian Kernighan's @command{awk}, and @command{mawk},
-the three most widely-used freely available versions of @command{awk}
+the three most widely used freely available versions of @command{awk}
(@pxref{Other Versions}).
-@multitable {@file{/dev/stderr} special file} {BWK Awk} {Mawk} {GNU Awk}
-@headitem Feature @tab BWK Awk @tab Mawk @tab GNU Awk
-@item @samp{\x} Escape sequence @tab X @tab X @tab X
-@item @code{RS} as regexp @tab @tab X @tab X
-@item @code{FS} as null string @tab X @tab X @tab X
-@item @file{/dev/stdin} special file @tab X @tab @tab X
-@item @file{/dev/stdout} special file @tab X @tab X @tab X
-@item @file{/dev/stderr} special file @tab X @tab X @tab X
-@item @code{**} and @code{**=} operators @tab X @tab @tab X
-@item @code{func} keyword @tab X @tab @tab X
-@item @code{nextfile} statement @tab X @tab X @tab X
-@item @code{delete} without subscript @tab X @tab X @tab X
-@item @code{length()} of an array @tab X @tab @tab X
-@item @code{fflush()} function @tab X @tab X @tab X
-@item @code{BINMODE} variable @tab @tab X @tab X
+@multitable {@file{/dev/stderr} special file} {BWK Awk} {Mawk} {GNU Awk} {Now standard}
+@headitem Feature @tab BWK Awk @tab Mawk @tab GNU Awk @tab Now standard
+@item @samp{\x} Escape sequence @tab X @tab X @tab X @tab
+@item @code{FS} as null string @tab X @tab X @tab X @tab
+@item @file{/dev/stdin} special file @tab X @tab X @tab X @tab
+@item @file{/dev/stdout} special file @tab X @tab X @tab X @tab
+@item @file{/dev/stderr} special file @tab X @tab X @tab X @tab
+@item @code{delete} without subscript @tab X @tab X @tab X @tab X
+@item @code{fflush()} function @tab X @tab X @tab X @tab X
+@item @code{length()} of an array @tab X @tab X @tab X @tab
+@item @code{nextfile} statement @tab X @tab X @tab X @tab X
+@item @code{**} and @code{**=} operators @tab X @tab @tab X @tab
+@item @code{func} keyword @tab X @tab @tab X @tab
+@item @code{BINMODE} variable @tab @tab X @tab X @tab
+@item @code{RS} as regexp @tab @tab X @tab X @tab
+@item Time-related functions @tab @tab X @tab X @tab
@end multitable
@node Ranges and Locales
@@ -27022,20 +36493,20 @@ character ranges (such as @samp{[a-z]}) to match any character between
the first character in the range and the last character in the range,
inclusive. Ordering was based on the numeric value of each character
in the machine's native character set. Thus, on ASCII-based systems,
-@code{[a-z]} matched all the lowercase letters, and only the lowercase
-letters, since the numeric values for the letters from @samp{a} through
-@samp{z} were contigous. (On an EBCDIC system, the range @samp{[a-z]}
+@samp{[a-z]} matched all the lowercase letters, and only the lowercase
+letters, as the numeric values for the letters from @samp{a} through
+@samp{z} were contiguous. (On an EBCDIC system, the range @samp{[a-z]}
includes additional, non-alphabetic characters as well.)
Almost all introductory Unix literature explained range expressions
as working in this fashion, and in particular, would teach that the
``correct'' way to match lowercase letters was with @samp{[a-z]}, and
-that @samp{[A-Z]} was the the ``correct'' way to match uppercase letters.
-And indeed, this was true.
+that @samp{[A-Z]} was the ``correct'' way to match uppercase letters.
+And indeed, this was true.@footnote{And Life was good.}
-The 1993 POSIX standard introduced the idea of locales (@pxref{Locales}).
-Since many locales include other letters besides the plain twenty-six
-letters of the American English alphabet, the POSIX standard added
+The 1992 POSIX standard introduced the idea of locales (@pxref{Locales}).
+Because many locales include other letters besides the plain 26
+letters of the English alphabet, the POSIX standard added
character classes (@pxref{Bracket Expressions}) as a way to match
different kinds of characters besides the traditional ones in the ASCII
character set.
@@ -27046,15 +36517,16 @@ In the @code{"C"} and @code{"POSIX"} locales, a range expression like
But outside those locales, the ordering was defined to be based on
@dfn{collation order}.
+What does that mean?
In many locales, @samp{A} and @samp{a} are both less than @samp{B}.
In other words, these locales sort characters in dictionary order,
and @samp{[a-dx-z]} is typically not equivalent to @samp{[abcdxyz]};
-instead it might be equivalent to @samp{[aBbCcdXxYyz]}, for example.
+instead it might be equivalent to @samp{[ABCXYabcdxyz]}, for example.
-This point needs to be emphasized: Much literature teaches that you should
+This point needs to be emphasized: much literature teaches that you should
use @samp{[a-z]} to match a lowercase character. But on systems with
-non-ASCII locales, this also matched all of the uppercase characters
-except @samp{Z}! This was a continuous cause of confusion, even well
+non-ASCII locales, this also matches all of the uppercase characters
+except @samp{A} or @samp{Z}! This was a continuous cause of confusion, even well
into the twenty-first century.
To demonstrate these issues, the following example uses the @code{sub()}
@@ -27067,14 +36539,15 @@ $ @kbd{echo something1234abc | gawk-3.1.8 '@{ sub("[A-Z]*$", ""); print @}'}
@end example
@noindent
-This output is unexpected, since the @samp{bc} at the end of
+This output is unexpected, as the @samp{bc} 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).
+@cindex Unicode
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}.
+such as @code{en_US.UTF-8}.
Early versions of @command{gawk} used regexp matching code that was not
locale aware, so ranges had their traditional interpretation.
@@ -27083,20 +36556,24 @@ When @command{gawk} switched to using locale-aware regexp matchers,
the problems began; especially as both GNU/Linux and commercial Unix
vendors started implementing non-ASCII locales, @emph{and making them
the default}. Perhaps the most frequently asked question became something
-like ``why does @code{[A-Z]} match lowercase letters?!?''
+like ``why does @samp{[A-Z]} match lowercase letters?!?''
+@cindex Berry, Karl
This situation existed for close to 10 years, if not more, and
the @command{gawk} maintainer grew weary of trying to explain that
-@command{gawk} was being nicely standards-compliant, and that the issue
-was in the user's locale. During the development of version 4.0,
+@command{gawk} was being nicely standards compliant, and that the issue
+was in the user's locale. During the development of @value{PVERSION} 4.0,
he modified @command{gawk} to always treat ranges in the original,
-pre-POSIX fashion, unless @option{--posix} was used (@pxref{Options}).
+pre-POSIX fashion, unless @option{--posix} was used (@pxref{Options}).@footnote{And
+thus was born the Campaign for Rational Range Interpretation (or
+RRI). A number of GNU tools have either implemented this change,
+or will soon. Thanks to Karl Berry for coining the phrase ``Rational
+Range Interpretation.''}
Fortunately, shortly before the final release of @command{gawk} 4.0,
the maintainer learned that the 2008 standard had changed the
definition of ranges, such that outside the @code{"C"} and @code{"POSIX"}
-locales, the meaning of range expressions was
-@emph{undefined}.@footnote{See
+locales, the meaning of range expressions was @emph{undefined}.@footnote{See
@uref{http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03_05, the standard}
and
@uref{http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap09.html#tag_21_09_03_05, its rationale}.}
@@ -27104,21 +36581,21 @@ and
By using this lovely technical term, the standard gives license
to implementors to implement ranges in whatever way they choose.
The @command{gawk} maintainer chose to apply the pre-POSIX meaning in all
-cases: the default regexp matching; with @option{--traditional}, and with
+cases: the default regexp matching; with @option{--traditional} and with
@option{--posix}; in all cases, @command{gawk} remains POSIX compliant.
@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
+@i{Always give credit where credit is due.}
+@author Anonymous
@end quotation
This @value{SECTION} names the major contributors to @command{gawk}
and/or this @value{DOCUMENT}, in approximate chronological order:
-@itemize @bullet
+@itemize @value{BULLET}
@item
@cindex Aho, Alfred
@cindex Weinberger, Peter
@@ -27198,8 +36675,8 @@ provided the initial port to OS/2 and its documentation.
Michal Jaegermann
provided the port to Atari systems and its documentation.
(This port is no longer supported.)
-He continues to provide portability checking with DEC Alpha
-systems, and has done a lot of work to make sure @command{gawk}
+He continues to provide portability checking,
+and has done a lot of work to make sure @command{gawk}
works on non-32-bit systems.
@item
@@ -27238,7 +36715,8 @@ the various PC platforms.
@cindex Zoulas, Christos
Christos Zoulas
provided the @code{extension()}
-built-in function for dynamically adding new modules.
+built-in function for dynamically adding new functions.
+(This was obsoleted at @command{gawk} 4.1.)
@item
@cindex Kahrs, J@"urgen
@@ -27269,7 +36747,7 @@ provided the port to BeOS and its documentation.
@cindex Peters, Arno
Arno Peters
did the initial work to convert @command{gawk} to use
-GNU Automake and GNU @code{gettext}.
+GNU Automake and GNU @command{gettext}.
@item
@cindex Broder, Alan J.@:
@@ -27296,40 +36774,128 @@ 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.
-(This is no longer supported)
+(This is no longer supported.)
+
+@item
+@cindex Wallin, Anders
+Anders Wallin helped keep the VMS port going for several years.
+
+@item
+@cindex Gordon, Assaf
+Assaf Gordon contributed the code to implement the
+@option{--sandbox} option.
@item
@cindex Haque, John
-John Haque
-reworked the @command{gawk} internals to use a byte-code engine,
-providing the @command{dgawk} debugger for @command{awk} programs.
+John Haque made the following contributions:
+
+@itemize @value{MINUS}
+@item
+The modifications to convert @command{gawk}
+into a byte-code interpreter, including the debugger.
+
+@item
+The addition of true arrays of arrays.
+
+@item
+The additional modifications for support of arbitrary-precision arithmetic.
+
+@item
+The initial text of
+@ref{Arbitrary Precision Arithmetic}.
+
+@item
+The work to merge the three versions of @command{gawk}
+into one, for the 4.1 release.
+
+@item
+Improved array internals for arrays indexed by integers.
+
+@item
+The improved array sorting features were driven by John together
+with Pat Rankin.
+@end itemize
+
+@cindex Papadopoulos, Panos
+@item
+Panos Papadopoulos contributed the original text for @ref{Include Files}.
@item
@cindex Yawitz, Efraim
Efraim Yawitz contributed the original text for @ref{Debugger}.
@item
+@cindex Schorr, Andrew
+The development of the extension API first released with
+@command{gawk} 4.1 was driven primarily by
+Arnold Robbins and Andrew Schorr, with notable contributions from
+the rest of the development team.
+
+@cindex Malmberg, John E.
+@item
+John Malmberg contributed significant improvements to the
+OpenVMS port and the related documentation.
+
+@item
+@cindex Colombo, Antonio
+Antonio Giovanni Colombo rewrote a number of examples in the early
+chapters that were severely dated, for which I am incredibly grateful.
+
+@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 History summary
+@appendixsec Summary
+
+@itemize @value{BULLET}
+@item
+The @command{awk} language has evolved over time. The first release
+was with V7 Unix circa 1978. In 1987, for System V Release 3.1,
+major additions, including user-defined functions, were made to the language.
+Additional changes were made for System V Release 4, in 1989.
+Since then, further minor changes happen under the auspices of the
+POSIX standard.
+
+@item
+Brian Kernighan's @command{awk} provides a small number of extensions
+that are implemented in common with other versions of @command{awk}.
+
+@item
+@command{gawk} provides a large number of extensions over POSIX @command{awk}.
+They can be disabled with either the @option{--traditional} or @option{--posix}
+options.
+
+@item
+The interaction of POSIX locales and regexp matching in @command{gawk} has been confusing over
+the years. Today, @command{gawk} implements Rational Range Interpretation, where
+ranges of the form @samp{[a-z]} match @emph{only} the characters numerically between
+@samp{a} through @samp{z} in the machine's native character set. Usually this is ASCII
+but it can be EBCDIC on IBM S/390 systems.
+
+@item
+Many people have contributed to @command{gawk} development over the years.
+We hope that the list provided in this @value{CHAPTER} is complete and gives
+the appropriate credit where credit is due.
+
+@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 operating systems, See Also GNU/Linux@comma{} PC operating systems@comma{} Unix
@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
+@DBXREF{Bugs}
+for the email addresses of the people who maintain
the respective ports.
@menu
@@ -27340,6 +36906,7 @@ the respective ports.
* Bugs:: Reporting Problems and Bugs.
* Other Versions:: Other freely available @command{awk}
implementations.
+* Installation summary:: Summary of installation.
@end menu
@node Gawk Distribution
@@ -27359,9 +36926,9 @@ subdirectories.
@node Getting
@appendixsubsec Getting the @command{gawk} Distribution
@cindex @command{gawk}, source code@comma{} obtaining
-There are three ways to get GNU software:
+There are two ways to get GNU software:
-@itemize @bullet
+@itemize @value{BULLET}
@item
Copy it from someone else who already has it.
@@ -27382,7 +36949,7 @@ wget http://ftp.gnu.org/gnu/gawk/gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz
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}.
+@uref{http://www.gnu.org/order/ftp.html, the main FSF website}.
Try to use one of the mirrors; they
will be less busy, and you can usually find one closer to your site.
@@ -27393,14 +36960,13 @@ different compression programs: @command{gzip}, @command{bzip2},
and @command{xz}. For simplicity, the rest of these instructions assume
you are using the one compressed with the GNU Zip program, @code{gzip}.
-Once you have the distribution (for example,
+Once you have the distribution (e.g.,
@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
@@ -27432,7 +36998,6 @@ 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,
@@ -27448,6 +37013,13 @@ The actual @command{gawk} source code.
@end table
@table @file
+@item ABOUT-NLS
+Information about GNU @command{gettext} and translations.
+
+@item AUTHORS
+A file with some information about the authorship of @command{gawk}.
+It exists only to satisfy the pedants at the Free Software Foundation.
+
@item README
@itemx README_d/README.*
Descriptive files: @file{README} for @command{gawk} under Unix and the
@@ -27471,16 +37043,6 @@ An older list of changes to @command{gawk}.
@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 behaviors in the POSIX standard for @command{awk} which
are left undefined, or where @command{gawk} may not comply fully, as well
@@ -27488,8 +37050,9 @@ as a list of things that the POSIX standard should describe but does not.
@cindex artificial intelligence@comma{} @command{gawk} and
@item doc/awkforai.txt
-A short article describing why @command{gawk} is a good language for
-Artificial Intelligence (AI) programming.
+Pointers to the original draft of
+a short article describing why @command{gawk} is a good language for
+artificial intelligence (AI) programming.
@item doc/bc_notes
A brief description of @command{gawk}'s ``byte code'' internals.
@@ -27512,12 +37075,19 @@ 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
+@item doc/gawktexi.in
+@itemx doc/sidebar.awk
The Texinfo source file for this @value{DOCUMENT}.
-It should be processed with @TeX{}
-(via @command{texi2dvi} or @command{texi2pdf})
+It should be processed by @file{doc/sidebar.awk}
+before processing with @command{texi2dvi} or @command{texi2pdf}
to produce a printed document, and
with @command{makeinfo} to produce an Info or HTML file.
+The @file{Makefile} takes care of this processing and produces
+printable output via @command{texi2dvi} or @command{texi2pdf}.
+
+@item doc/gawk.texi
+The file produced after processing @file{gawktexi.in}
+with @file{sidebar.awk}.
@item doc/gawk.info
The generated Info file for this @value{DOCUMENT}.
@@ -27543,6 +37113,8 @@ The generated Info file for
The @command{troff} source for a manual page describing the @command{igawk}
program presented in
@ref{Igawk Program}.
+(Since @command{gawk} can do its own @code{@@include} processing,
+neither @command{igawk} nor @file{igawk.1} are installed.)
@item doc/Makefile.in
The input file used during the configuration process to generate the
@@ -27550,21 +37122,27 @@ 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
+Files used by the GNU Automake software for generating
+the @file{Makefile.in} files used by Autoconf and
@command{configure}.
@item Makefile.in
@itemx aclocal.m4
+@itemx bisonfix.awk
+@itemx config.guess
@itemx configh.in
@itemx configure.ac
@itemx configure
@itemx custom.h
+@itemx depcomp
+@itemx install-sh
@itemx missing_d/*
+@itemx mkinstalldirs
@itemx m4/*
-These files and subdirectories are used when configuring @command{gawk}
-for various Unix systems. They are explained in
-@ref{Unix Installation}.
+These files and subdirectories are used when configuring and compiling
+@command{gawk} for various Unix systems. Most of them are explained
+in @ref{Unix Installation}. The rest are there to support the main
+infrastructure.
@item po/*
The @file{po} library contains message translations.
@@ -27581,23 +37159,35 @@ source file for this @value{DOCUMENT}. It also contains a @file{Makefile.in} fil
@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 extension/*
+The source code, manual pages, and infrastructure files for
+the sample extensions included with @command{gawk}.
+@xref{Dynamic Extensions}, for more information.
+
+@item extras/*
+Additional non-essential files. Currently, this directory contains some shell
+startup files to be installed in @file{/etc/profile.d} to aid in manipulating
+the @env{AWKPATH} and @env{AWKLIBPATH} environment variables.
+@xref{Shell Startup Files}, for more information.
+
@item posix/*
Files needed for building @command{gawk} on POSIX-compliant systems.
@item pc/*
-Files needed for building @command{gawk} under MS-Windows and OS/2
-(@pxref{PC Installation}, for details).
+Files needed for building @command{gawk} under MS-Windows
+@ifclear FOR_PRINT
+and OS/2
+@end ifclear
+(@DBPXREF{PC Installation} for details).
@item vms/*
-Files needed for building @command{gawk} under VMS
-(@pxref{VMS Installation}, for details).
+Files needed for building @command{gawk} under Vax/VMS and OpenVMS
+(@DBPXREF{VMS Installation} for details).
@item test/*
A test suite for
@@ -27606,10 +37196,9 @@ 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-like Systems
+@appendixsec Compiling and Installing @command{gawk} on Unix-Like Systems
Usually, you can compile and install @command{gawk} by typing only two
commands. However, if you use an unusual system, you may need
@@ -27617,33 +37206,33 @@ to configure @command{gawk} for your system yourself.
@menu
* Quick Installation:: Compiling @command{gawk} under Unix.
+* Shell Startup Files:: Shell convenience functions.
* 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-like Systems
+@appendixsubsec Compiling @command{gawk} for Unix-Like Systems
The normal installation steps should work on all modern commercial
Unix-derived systems, GNU/Linux, BSD-based systems, and the Cygwin
environment for MS-Windows.
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 system by running the @command{configure} program.
-This program is a Bourne shell script that is generated automatically using
-GNU @command{autoconf}.
+to @file{gawk-@value{VERSION}.@value{PATCHLEVEL}}. As with most GNU
+software, you configure @command{gawk} for your system by running the
+@command{configure} program. This program is a Bourne shell script that
+is generated automatically using GNU Autoconf.
@ifnotinfo
-(The @command{autoconf} software is
+(The Autoconf software is
described fully in
@cite{Autoconf---Generating Automatic Configuration Scripts},
which can be found online at
@uref{http://www.gnu.org/software/autoconf/manual/index.html,
-the Free Software Foundation's web site}.)
+the Free Software Foundation's website}.)
@end ifnotinfo
@ifinfo
-(The @command{autoconf} software is described fully starting with
+(The Autoconf software is described fully starting with
@inforef{Top, , Autoconf, autoconf,Autoconf---Generating Automatic Configuration Scripts}.)
@end ifinfo
@@ -27687,7 +37276,54 @@ 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}).
+send in a bug report (@pxref{Bugs}).
+
+Of course, once you've built @command{gawk}, it is likely that you will
+wish to install it. To do so, you need to run the command @samp{make
+install}, as a user with the appropriate permissions. How to do this
+varies by system, but on many systems you can use the @command{sudo}
+command to do so. The command then becomes @samp{sudo make install}. It
+is likely that you will be asked for your password, and you will have
+to have been set up previously as a user who is allowed to run the
+@command{sudo} command.
+
+@node Shell Startup Files
+@appendixsubsec Shell Startup Files
+
+The distribution contains shell startup files @file{gawk.sh} and
+@file{gawk.csh} containing functions to aid in manipulating
+the @env{AWKPATH} and @env{AWKLIBPATH} environment variables.
+On a Fedora system, these files should be installed in @file{/etc/profile.d};
+on other platforms, the appropriate location may be different.
+
+@table @command
+
+@cindex @command{gawkpath_default} shell function
+@item gawkpath_default
+Reset the @env{AWKPATH} environment variable to its default value.
+
+@cindex @command{gawkpath_prepend} shell function
+@item gawkpath_prepend
+Add the argument to the front of the @env{AWKPATH} environment variable.
+
+@cindex @command{gawkpath_append} shell function
+@item gawkpath_append
+Add the argument to the end of the @env{AWKPATH} environment variable.
+
+@cindex @command{gawklibpath_default} shell function
+@item gawklibpath_default
+Reset the @env{AWKLIBPATH} environment variable to its default value.
+
+@cindex @command{gawklibpath_prepend} shell function
+@item gawklibpath_prepend
+Add the argument to the front of the @env{AWKLIBPATH} environment variable.
+
+@cindex @command{gawklibpath_append} shell function
+@item gawklibpath_append
+Add the argument to the end of the @env{AWKLIBPATH} environment variable.
+
+@end table
+
@node Additional Configuration Options
@appendixsubsec Additional Configuration Options
@@ -27699,7 +37335,15 @@ command line when compiling @command{gawk} from scratch, including:
@table @code
-@cindex @code{--disable-lint} configuration option
+@cindex @option{--disable-extensions} configuration option
+@cindex configuration option, @code{--disable-extensions}
+@item --disable-extensions
+Disable configuring and building the sample extensions in the
+@file{extension} directory. This is useful for cross-compiling.
+The default action is to dynamically check if the extensions
+can be configured and compiled.
+
+@cindex @option{--disable-lint} configuration option
@cindex configuration option, @code{--disable-lint}
@item --disable-lint
Disable all lint checking within @code{gawk}. The
@@ -27711,30 +37355,30 @@ Similarly, setting the @code{LINT} variable
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
+cuts almost 23K bytes off the size of the @command{gawk}
+executable on GNU/Linux x86_64 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 @option{--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.
-@cindex @code{--with-whiny-user-strftime} configuration option
+@cindex @option{--with-whiny-user-strftime} configuration option
@cindex configuration option, @code{--with-whiny-user-strftime}
@item --with-whiny-user-strftime
-Force use of the included version of the @code{strftime()}
+Force use of the included version of the C @code{strftime()}
function for deficient systems.
@end table
Use the command @samp{./configure --help} to see the full list of
-options that @command{configure} supplies.
+options supplied by @command{configure}.
@node Configuration Philosophy
@appendixsubsec The Configuration Process
@@ -27763,24 +37407,24 @@ they can be correctly included, what (supposedly) standard functions
are actually available in your C libraries, and various miscellaneous
facts about your operating system. 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.
+@samp{HAVE_STRUCT_STAT_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}.
+available. To get around this, edit the @file{custom.h} file.
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}.
+should not have. The @file{custom.h} file is automatically included by
+the @file{config.h} file.
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.ac} is the input for
-@command{autoconf}. You may be able to change this file and generate a
+Autoconf will not work on your system in some other fashion.
+If you do have a problem, the @file{configure.ac} file is the input for
+Autoconf. You may be able to change this file and generate a
new version of @command{configure} that works on your system
-(@pxref{Bugs},
+(@DBPXREF{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.ac}
and/or @file{custom.h}.
@@ -27805,17 +37449,23 @@ various non-Unix 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
+This @value{SECTION} covers installation and usage of @command{gawk}
+on Intel architecture machines
+@ifclear FOR_PRINT
running MS-DOS, any version of MS-Windows, or OS/2.
+@end ifclear
+@ifset FOR_PRINT
+running MS-DOS and any version of MS-Windows.
+@end ifset
In this @value{SECTION}, the term ``Windows32''
-refers to any of Microsoft Windows-95/98/ME/NT/2000/XP/Vista/7.
+refers to any of Microsoft Windows-95/98/ME/NT/2000/XP/Vista/7/8.
-The limitations of MS-DOS (and MS-DOS shells under Windows32 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.
+The limitations of MS-DOS (and MS-DOS shells under the other operating
+systems) 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, refer to @file{README_d/README.pc} in
+the distribution.
@menu
* PC Binary Installation:: Installing a prepared distribution.
@@ -27829,6 +37479,7 @@ distribution.
* MSYS:: Using @command{gawk} In The MSYS Environment.
@end menu
+@ifclear FOR_PRINT
@node PC Binary Installation
@appendixsubsubsec Installing a Prepared Distribution for PC Systems
@@ -27867,13 +37518,21 @@ install-info --info-dir=x:/usr/info x:/usr/info/gawkinet.info
The binary distribution may contain a separate file containing additional
or more detailed installation instructions.
+@end ifclear
@node PC Compiling
@appendixsubsubsec Compiling @command{gawk} for PC Operating Systems
+@ifclear FOR_PRINT
@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). The file
+development tools from DJ Delorie (DJGPP: MS-DOS only), MinGW (Windows32) or Eberhard
+Mattes (EMX: MS-DOS, Windows32 and OS/2).
+@end ifclear
+@ifset FOR_PRINT
+@command{gawk} can be compiled for MS-DOS and Windows32 using the GNU
+development tools from DJ Delorie (DJGPP: MS-DOS only) or MinGW (Windows32).
+@end ifset
+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.
@@ -27893,8 +37552,10 @@ MS-DOS and Windows32 versions. A list of targets is printed if the
build @command{gawk} using the DJGPP tools, enter @samp{make djgpp}.
(The DJGPP tools needed for the build may be found at
@uref{ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/}.) To build a
-native MS-Windows binary of @command{gawk}, type @samp{make mingw32}.
+native MS-Windows binary of @command{gawk} using the MinGW tools,
+type @samp{make mingw32}.
+@ifclear FOR_PRINT
@cindex compiling @command{gawk} with EMX for OS/2
The 32 bit EMX version of @command{gawk} works ``out of the box'' under OS/2.
However, it is highly recommended to use GCC 2.95.3 for the compilation.
@@ -27929,7 +37590,7 @@ and @option{--libexecdir=c:/usr/lib}.
@end ignore
@ignore
-The internal @code{gettext} library tends to be problematic. It is therefore recommended
+The internal @command{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
@@ -27966,8 +37627,11 @@ Ancient 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{ftp://hobbes.nmsu.edu/pub/os2/}.
+@uref{ftp://hobbes.nmsu.edu/pub/os2/}.@footnote{As of November 2014,
+this site is still there, but the author could not find a package
+for GNU Make.}
@end quotation
+@end ifclear
@node PC Testing
@appendixsubsubsec Testing @command{gawk} on PC Operating Systems
@@ -27979,6 +37643,7 @@ be converted so that they have the usual MS-DOS-style end-of-line markers.
Alternatively, run @command{make check CMP="diff -a"} to use GNU @command{diff}
in text mode instead of @command{cmp} to compare the resulting files.
+@ifclear FOR_PRINT
Most
of the tests work properly with Stewartson's shell along with the
companion utilities or appropriate GNU utilities. However, some editing of
@@ -27991,71 +37656,82 @@ On OS/2 the @code{pid} test fails because @code{spawnl()} is used instead of
@code{fork()}/@code{execl()} to start child processes.
Also the @code{mbfw1} and @code{mbprintf1} tests fail because the needed
multibyte functionality is not available.
-
+@end ifclear
@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.
+Under MS-DOS and MS-Windows, the Cygwin and MinGW environments support
+both the @samp{|&} operator and TCP/IP networking
+(@pxref{TCP/IP Networking}).
+@ifclear FOR_PRINT
+EMX (OS/2 only) supports at least the @samp{|&} operator.
+@end ifclear
@cindex search paths
@cindex search paths, for source files
-@cindex @command{gawk}, OS/2 version of
@cindex @command{gawk}, MS-DOS version of
@cindex @command{gawk}, MS-Windows version of
-@cindex @code{;} (semicolon), @code{AWKPATH} variable and
-@cindex semicolon (@code{;}), @code{AWKPATH} variable and
-@cindex @code{AWKPATH} environment variable
+@cindex @code{;} (semicolon), @env{AWKPATH} variable and
+@cindex semicolon (@code{;}), @env{AWKPATH} variable and
+@cindex @env{AWKPATH} environment variable
The MS-DOS and MS-Windows 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 MS-Windows and MS-DOS versions is
-@code{@w{".;c:/lib/awk;c:/gnu/lib/awk"}}.
+search path is @samp{@w{.;c:/lib/awk;c:/gnu/lib/awk}}.
+@ifclear FOR_PRINT
+@cindex @command{gawk}, OS/2 version of
@cindex @code{UNIXROOT} variable, on OS/2 systems
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.
+the @command{configure} script as 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
+systems whose drive @samp{c:} might not support long @value{FN}s 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"}}.
+@samp{@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 MS-Windows or OS/2) may be useful for @command{awk} programming.
The DJGPP collection of tools includes an MS-DOS port of Bash,
and several shells are available for OS/2, including @command{ksh}.
+@end ifclear
+@ifset FOR_PRINT
+An @command{sh}-like shell (as opposed to @command{command.com} under MS-DOS
+or @command{cmd.exe} under MS-Windows) may be useful for @command{awk} programming.
+The DJGPP collection of tools includes an MS-DOS port of Bash.
+@end ifset
@cindex common extensions, @code{BINMODE} variable
@cindex extensions, common@comma{} @code{BINMODE} variable
@cindex differences in @command{awk} and @command{gawk}, @code{BINMODE} variable
@cindex @code{BINMODE} variable
-Under MS-Windows, OS/2 and MS-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 @value{COMMONEXT}
+@ifclear FOR_PRINT
+Under MS-Windows, OS/2 and MS-DOS,
+@end ifclear
+@ifset FOR_PRINT
+Under MS-Windows and MS-DOS,
+@end ifset
+@command{gawk} (and many other text programs) silently
+translate end-of-line @samp{\r\n} to @samp{\n} on input and @samp{\n}
+to @samp{\r\n} on output. A special @code{BINMODE} variable @value{COMMONEXT}
allows control over these translations and is interpreted as follows:
-@itemize @bullet
+@itemize @value{BULLET}
@item
-If @code{BINMODE} is @code{"r"}, or one,
+If @code{BINMODE} is @code{"r"} or one,
then
binary mode is set on read (i.e., no translations on reads).
@item
-If @code{BINMODE} is @code{"w"}, or two,
+If @code{BINMODE} is @code{"w"} or two,
then
binary mode is set on write (i.e., no translations on writes).
@@ -28086,7 +37762,7 @@ The name @code{BINMODE} was chosen to match @command{mawk}
@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
+prepared binary 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
@@ -28114,7 +37790,7 @@ 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{}
+gawk -v RS="\r\n" -e "BEGIN @{ BINMODE = 1 @}" @dots{}
@end example
@noindent
@@ -28134,7 +37810,7 @@ moved into the @code{BEGIN} rule.
@command{gawk} can be built and used ``out of the box'' under MS-Windows
if you are using the @uref{http://www.cygwin.com, Cygwin environment}.
-This environment provides an excellent simulation of Unix, using the
+This environment provides an excellent simulation of GNU/Linux, using the
GNU tools, such as Bash, the GNU Compiler Collection (GCC), GNU Make,
and other GNU programs. Compilation and installation for Cygwin is the
same as for a Unix system:
@@ -28143,20 +37819,13 @@ same as for a Unix system:
tar -xvpzf gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz
cd gawk-@value{VERSION}.@value{PATCHLEVEL}
./configure
-make
+make && make check
@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 on MS-Windows.
-@end quotation
-
@node MSYS
@appendixsubsubsec Using @command{gawk} In The MSYS Environment
@@ -28166,10 +37835,10 @@ need to use the @code{BINMODE} variable.
This can cause problems with other Unix-like components that have
been ported to MS-Windows that expect @command{gawk} to do automatic
-translation of @code{"\r\n"}, since it won't. Caveat Emptor!
+translation of @code{"\r\n"}, because it won't.
@node VMS Installation
-@appendixsubsec How to Compile and Install @command{gawk} on VMS
+@appendixsubsec Compiling and Installing @command{gawk} on Vax/VMS and OpenVMS
@c based on material from Pat Rankin <rankin@eql.caltech.edu>
@c now rankin@pactechdata.com
@@ -28182,8 +37851,11 @@ The older designation ``VMS'' is used throughout to refer to OpenVMS.
@menu
* VMS Compilation:: How to compile @command{gawk} under VMS.
+* VMS Dynamic Extensions:: Compiling @command{gawk} dynamic extensions on
+ VMS.
* VMS Installation Details:: How to install @command{gawk} under VMS.
* VMS Running:: How to run @command{gawk} under VMS.
+* VMS GNV:: The VMS GNV Project.
* VMS Old Gawk:: An old version comes with some VMS systems.
@end menu
@@ -28191,41 +37863,115 @@ The older designation ``VMS'' is used throughout to refer to OpenVMS.
@appendixsubsubsec Compiling @command{gawk} on VMS
@cindex compiling @command{gawk} for 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:
+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} and @code{MMK} utilities.
+From the source directory, use either:
+
+@example
+$ @kbd{@@[.vms]vmsbuild.com}
+@end example
+
+@noindent
+or:
+
+@example
+$ @kbd{MMS/DESCRIPTION=[.vms]descrip.mms gawk}
+@end example
+
+@noindent
+or:
+
+@example
+$ @kbd{MMK/DESCRIPTION=[.vms]descrip.mms gawk}
+@end example
+
+@command{MMK} is an open source, free, near-clone of @command{MMS} and
+can better handle ODS-5 volumes with upper- and lowercase @value{FN}s.
+@command{MMK} is available from @uref{https://github.com/endlesssoftware/mmk}.
+
+With ODS-5 volumes and extended parsing enabled, the case of the target
+parameter may need to be exact.
+
+@command{gawk} has been tested under VAX/VMS 7.3 and Alpha/VMS 7.3-1
+using Compaq C V6.4, and Alpha/VMS 7.3, Alpha/VMS 7.3-2, and IA64/VMS 8.3.
+The most recent builds used HP C V7.3 on Alpha VMS 8.3 and both
+Alpha and IA64 VMS 8.4 used HP C 7.3.@footnote{The IA64 architecture
+is also known as ``Itanium.''}
+
+@DBXREF{VMS GNV} for information on building
+@command{gawk} as a PCSI kit that is compatible with the GNV product.
+
+@node VMS Dynamic Extensions
+@appendixsubsubsec Compiling @command{gawk} Dynamic Extensions on VMS
+
+The extensions that have been ported to VMS can be built using one of
+the following commands:
@example
-$ @kbd{@@[.VMS]VMSBUILD.COM}
+$ @kbd{MMS/DESCRIPTION=[.vms]descrip.mms extensions}
@end example
@noindent
or:
@example
-$ @kbd{MMS/DESCRIPTION=[.VMS]DESCRIP.MMS GAWK}
+$ @kbd{MMK/DESCRIPTION=[.vms]descrip.mms extensions}
+@end example
+
+@command{gawk} uses @code{AWKLIBPATH} as either an environment variable
+or a logical name to find the dynamic extensions.
+
+Dynamic extensions need to be compiled with the same compiler options for
+floating-point, pointer size, and symbol name handling as were used
+to compile @command{gawk} itself.
+Alpha and Itanium should use IEEE floating point. The pointer size is 32 bits,
+and the symbol name handling should be exact case with CRC shortening for
+symbols longer than 32 bits.
+
+For Alpha and Itanium:
+
+@example
+/name=(as_is,short)
+/float=ieee/ieee_mode=denorm_results
+@end example
+
+For VAX:
+
+@example
+/name=(as_is,short)
@end example
-Older versions of @command{gawk} could be built with VAX C or
-GNU C on VAX/VMS, as well as with DEC C, but that is no longer
-supported. DEC C (also briefly known as ``Compaq C'' and now known
-as ``HP C,'' but referred to here as ``DEC C'') is required. Both
-@code{VMSBUILD.COM} and @code{DESCRIP.MMS} contain some obsolete support
-for the older compilers but are set up to use DEC C by default.
+Compile time macros need to be defined before the first VMS-supplied
+header file is included, as follows:
-@command{gawk} has been tested under Alpha/VMS 7.3-1 using Compaq C V6.4,
-and on Alpha/VMS 7.3, Alpha/VMS 7.3-2, and IA64/VMS 8.3.@footnote{The IA64
-architecture is also known as ``Itanium.''}
+@example
+#if (__CRTL_VER >= 70200000) && !defined (__VAX)
+#define _LARGEFILE 1
+#endif
+
+#ifndef __VAX
+#ifdef __CRTL_VER
+#if __CRTL_VER >= 80200000
+#define _USE_STD_STAT 1
+#endif
+#endif
+#endif
+@end example
+
+If you are writing your own extensions to run on VMS, you must supply these
+definitions yourself. The @file{config.h} file created when building @command{gawk}
+on VMS does this for you; if instead you use that file or a similar one, then you
+must remember to include it before any VMS-supplied header files.
@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:
+To use @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
-$ @kbd{GAWK :== $disk1:[gnubin]GAWK}
+$ @kbd{GAWK :== $disk1:[gnubin]gawk}
@end example
@noindent
@@ -28237,10 +37983,29 @@ 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:
+If your @command{gawk} was installed by a PCSI kit into the
+@file{GNV$GNU:} directory tree, the program will be known as
+@file{GNV$GNU:[bin]gnv$gawk.exe} and the help file will be
+@file{GNV$GNU:[vms_help]gawk.hlp}.
+
+The PCSI kit also installs a @file{GNV$GNU:[vms_bin]gawk_verb.cld} file
+which can be used to add @command{gawk} and @command{awk} as DCL commands.
+
+For just the current process you can use:
@example
-$ @kbd{LIBRARY/HELP SYS$HELP:HELPLIB [.VMS]GAWK.HLP}
+$ @kbd{set command gnv$gnu:[vms_bin]gawk_verb.cld}
+@end example
+
+Or the system manager can use @file{GNV$GNU:[vms_bin]gawk_verb.cld} to
+add the @command{gawk} and @command{awk} to the system wide @samp{DCLTABLES}.
+
+The DCL syntax is documented in the @file{gawk.hlp} file.
+
+Optionally, the @file{gawk.hlp} entry can be loaded into a VMS help library:
+
+@example
+$ @kbd{LIBRARY/HELP sys$help:helplib [.vms]gawk.hlp}
@end example
@noindent
@@ -28262,7 +38027,7 @@ for @command{awk} program files. For the @option{-f} option, if the specified
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
+@command{gawk} appends the suffix @samp{.awk} to the @value{FN} and retries
the file search. If @samp{AWK_LIBRARY} has no definition, a default value
of @samp{SYS$LIBRARY:} is used for it.
@@ -28288,12 +38053,45 @@ 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
+single parameter (as in the quoted string program), the command
becomes ambiguous. To work around this, the normally optional @option{--}
flag is required to force Unix-style parsing 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.
+@cindex exit status, of VMS
+The @code{exit} value is a Unix-style value and is encoded into a VMS exit
+status value when the program exits.
+
+The VMS severity bits will be set based on the @code{exit} value.
+A failure is indicated by 1 and VMS sets the @code{ERROR} status.
+A fatal error is indicated by 2 and VMS sets the @code{FATAL} status.
+All other values will have the @code{SUCCESS} status. The exit value is
+encoded to comply with VMS coding standards and will have the
+@code{C_FACILITY_NO} of @code{0x350000} with the constant @code{0xA000}
+added to the number shifted over by 3 bits to make room for the severity codes.
+
+To extract the actual @command{gawk} exit code from the VMS status use:
+
+@example
+unix_status = (vms_status .and. &x7f8) / 8
+@end example
+
+@noindent
+A C program that uses @code{exec()} to call @command{gawk} will get the original
+Unix-style exit value.
+
+Older versions of @command{gawk} for VMS treated a Unix exit code 0 as 1, a failure
+as 2, a fatal error as 4, and passed all the other numbers through.
+This violated the VMS exit status coding requirements.
+
+@cindex floating-point, VAX/VMS
+VAX/VMS floating point uses unbiased rounding. @xref{Round Function}.
+
+VMS reports time values in GMT unless one of the @code{SYS$TIMEZONE_RULE}
+or @code{TZ} logical names is set. Older versions of VMS, such as VAX/VMS
+7.3 do not set these logical names.
+
@c @cindex directory search
@c @cindex path, search
@cindex search paths
@@ -28305,6 +38103,21 @@ of @env{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 GNV
+@appendixsubsubsec The VMS GNV Project
+
+The VMS GNV package provides a build environment similar to POSIX with ports
+of a collection of open source tools. The @command{gawk} found in the GNV
+base kit is an older port. Currently the GNV project is being reorganized
+to supply individual PCSI packages for each component.
+See @w{@uref{https://sourceforge.net/p/gnv/wiki/InstallingGNVPackages/}.}
+
+The normal build procedure for @command{gawk} produces a program that
+is suitable for use with GNV.
+
+The file @file{vms/gawk_build_steps.txt} in the distribution documents
+the procedure for building a VMS PCSI kit that is compatible with GNV.
+
@ignore
@c The VMS POSIX product, also known as POSIX for OpenVMS, is long defunct
@c and building gawk for it has not been tested in many years, but these
@@ -28355,28 +38168,24 @@ $ @kbd{gawk :== $sys$common:[syshlp.examples.tcpip.snmp]gawk.exe}
This is apparently @value{PVERSION} 2.15.6, which is extremely old. We
recommend compiling and using the current version.
-@c ENDOFRANGE opgawx
-@c ENDOFRANGE pcgawon
@node Bugs
@appendixsec Reporting Problems and Bugs
-@cindex archeologists
+@cindex archaeologists
@quotation
-@i{There is nothing more dangerous than a bored archeologist.}@*
-The Hitchhiker's Guide to the Galaxy
+@i{There is nothing more dangerous than a bored archaeologist.}
+@author Douglas Adams, @cite{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
+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
+Before reporting a bug, make sure you have really found a genuine bug.
+Carefully reread the documentation and see if it 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!
@@ -28388,86 +38197,87 @@ 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.
-Please include the version number of @command{gawk} you are using.
+Make sure to include the version number of @command{gawk} you are using.
You can get this information with the command @samp{gawk --version}.
@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
+Once you have a precise problem description, send email to
@EMAIL{bug-gawk@@gnu.org,bug-gawk at gnu dot org}.
-@cindex Robbins, Arnold
-Using this address automatically sends a copy of your
-mail to me. If necessary, I can be reached directly at
-@EMAIL{arnold@@skeeve.com,arnold at skeeve dot com}.
-The bug reporting address is preferred since the
+The @command{gawk} maintainers subscribe to this address and
+thus they will receive your bug report.
+Although you can send mail to the maintainers directly,
+the bug reporting address is preferred because the
email list is archived at the GNU Project.
-@emph{All email should be in English, since that is my native language.}
+@emph{All email must be in English. This is the only language
+understood in common by all the maintainers.}
@cindex @code{comp.lang.awk} newsgroup
@quotation 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.
+The @command{gawk} developers do occasionally read this newsgroup,
+but there is no guarantee that we will see your posting. The steps described
+here are the only officially recognized way for reporting bugs.
Really.
@end quotation
@quotation NOTE
Many distributions of GNU/Linux and the various BSD-based operating systems
have their own bug reporting systems. If you report a bug using your distribution's
-bug reporting system, @emph{please} also send a copy to
+bug reporting system, you should also send a copy to
@EMAIL{bug-gawk@@gnu.org,bug-gawk at gnu dot org}.
-This is for two reasons. First, while some distributions forward
+This is for two reasons. First, although some distributions forward
bug reports ``upstream'' to the GNU mailing list, many don't, so there is a good
-chance that the @command{gawk} maintainer won't even see the bug report! Second,
+chance that the @command{gawk} maintainers won't even see the bug report! Second,
mail to the GNU list is archived, and having everything at the GNU project
-keeps things self-contained and not dependant on other web sites.
+keeps things self-contained and not dependant on other organizations.
@end quotation
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.
+features, ask on the bug list; we will try to help you out if we can.
-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}.
+If you find bugs in one of the non-Unix ports of @command{gawk},
+send an email to the bug list, with a copy 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:
+The people maintaining the various @command{gawk} ports are:
-@multitable {MS-Windows with MINGW} {123456789012345678901234567890123456789001234567890}
+@c put the index entries outside the table, for docbook
+@cindex Buening, Andreas
@cindex Deifik, Scott
+@cindex Malmberg, John
+@cindex Pitts, Dave
+@cindex Robbins, Arnold
+@cindex Zaretskii, Eli
+@multitable {MS-Windows with MinGW} {123456789012345678901234567890123456789001234567890}
+@item Unix and POSIX systems @tab Arnold Robbins, @EMAIL{arnold@@skeeve.com,arnold at skeeve dot com}.
+
@item MS-DOS with DJGPP @tab Scott Deifik, @EMAIL{scottd.mail@@sbcglobal.net,scottd dot mail at sbcglobal dot net}.
-@cindex Zaretskii, Eli
-@item MS-Windows with MINGW @tab Eli Zaretskii, @EMAIL{eliz@@gnu.org,eliz at gnu dot org}.
+@item MS-Windows with MinGW @tab Eli Zaretskii, @EMAIL{eliz@@gnu.org,eliz at gnu dot org}.
-@cindex Buening, Andreas
+@c Leave this in the print version on purpose.
+@c OS/2 is not mentioned anywhere else in the print version though.
@item OS/2 @tab Andreas Buening, @EMAIL{andreas.buening@@nexgo.de,andreas dot buening at nexgo dot de}.
-@cindex Rankin, Pat
-@item VMS @tab Pat Rankin, @EMAIL{r.pat.rankin@@gmail.com,r.pat.rankin at gmail.com}
+@item VMS @tab John Malmberg, @EMAIL{wb8tyw@@qsl.net,wb8tyw at qsl.net}.
-@cindex Pitts, Dave
@item z/OS (OS/390) @tab Dave Pitts, @EMAIL{dpitts@@cozx.com,dpitts at cozx dot com}.
@end multitable
-If your bug is also reproducible under Unix, please send a copy of your
+If your bug is also reproducible under Unix, send a copy of your
report to the @EMAIL{bug-gawk@@gnu.org,bug-gawk at gnu dot 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)
@@ -28477,11 +38287,20 @@ Date: Wed, 4 Sep 1996 08:11:48 -0700 (PDT)
@end ignore
@cindex Brennan, Michael
+@ifnotdocbook
@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
+@ @ @ @ @ @ @code{// Do C++ comments work? answer: yes! of course}
+@author Michael Brennan
@end quotation
+@end ifnotdocbook
+
+@docbook
+<blockquote><attribution>Michael Brennan</attribution>
+<literallayout><emphasis>It's kind of fun to put comments like this in your awk code.</emphasis>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<literal>// Do C++ comments work? answer: yes! of course</literal></literallayout>
+</blockquote>
+@end docbook
There are a number of other freely available @command{awk} implementations.
This @value{SECTION} briefly describes where to get them:
@@ -28490,13 +38309,12 @@ This @value{SECTION} briefly describes where to get them:
@cindex Kernighan, Brian
@cindex source code, Brian Kernighan's @command{awk}
@cindex @command{awk}, versions of, See Also Brian Kernighan's @command{awk}
-@cindex extensions, Brian Kernighan's @command{awk}
-@cindex Brian Kernighan's @command{awk}, extensions
+@cindex Brian Kernighan's @command{awk}, source code
@item Unix @command{awk}
Brian Kernighan, one of the original designers of Unix @command{awk},
has made his implementation of
@command{awk} freely available.
-You can retrieve this version via the World Wide Web from
+You can retrieve this version via
@uref{http://www.cs.princeton.edu/~bwk, his home page}.
It is available in several archive formats:
@@ -28511,21 +38329,41 @@ It is available in several archive formats:
@uref{http://www.cs.princeton.edu/~bwk/btl.mirror/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.
+@cindex @command{git} utility
+You can also retrieve it from Git Hub:
-@xref{Common Extensions},
+@example
+git clone git://github.com/onetrueawk/awk bwkawk
+@end example
+
+@noindent
+This command creates a copy of the @uref{http://git-scm.com, Git}
+repository in a directory named @file{bwkawk}. If you leave that argument
+off the @command{git} command line, the repository copy is created in a
+directory named @file{awk}.
+
+This version requires an ISO C (1990 standard) compiler; the C compiler
+from GCC (the GNU Compiler Collection) works quite nicely.
+
+@DBXREF{Common Extensions}
for a list of extensions in this @command{awk} that are not in POSIX @command{awk}.
+As a side note, Dan Bornstein has created a Git repository tracking
+all the versions of BWK @command{awk} that he could find. It's
+available at @uref{git://github.com/danfuzz/one-true-awk}.
+
@cindex Brennan, Michael
-@cindex @command{mawk} program
+@cindex @command{mawk} utility
@cindex source code, @command{mawk}
@item @command{mawk}
Michael Brennan wrote an independent implementation of @command{awk},
-called @command{mawk}. It is available under the GPL
-(@pxref{Copying}),
+called @command{mawk}. It is available under the
+@ifclear FOR_PRINT
+GPL (@pxref{Copying}),
+@end ifclear
+@ifset FOR_PRINT
+GPL,
+@end ifset
just as @command{gawk} is.
The original distribution site for the @command{mawk} source code
@@ -28534,7 +38372,7 @@ no longer has it. A copy is available at
In 2009, Thomas Dickey took on @command{mawk} maintenance.
Basic information is available on
-@uref{http://www.invisible-island.net/mawk/mawk.html, the project's web page}.
+@uref{http://www.invisible-island.net/mawk, the project's web page}.
The download URL is
@url{http://invisible-island.net/datafiles/release/mawk.tar.gz}.
@@ -28543,7 +38381,7 @@ Once you have it,
is similar to @command{gawk}'s
(@pxref{Unix Installation}).
-@xref{Common Extensions},
+@DBXREF{Common Extensions}
for a list of extensions in @command{mawk} that are not in POSIX @command{awk}.
@cindex Sumner, Andrew
@@ -28566,13 +38404,13 @@ To get @command{awka}, go to @url{http://sourceforge.net/projects/awka}.
The project seems to be frozen; no new code changes have been made
since approximately 2003.
-@cindex Beebe, Nelson
+@cindex Beebe, Nelson H.F.@:
@cindex @command{pawk} (profiling version of Brian Kernighan's @command{awk})
@cindex source code, @command{pawk}
@item @command{pawk}
Nelson H.F.@: Beebe at the University of Utah has modified
-Brian Kernighan's @command{awk} to provide timing and profiling information.
-It is different from @command{pgawk}
+BWK @command{awk} to provide timing and profiling information.
+It is different from @command{gawk} with the @option{--profile} option
(@pxref{Profiling}),
in that it uses CPU-based profiling, not line-count
profiling. You may find it at either
@@ -28594,16 +38432,23 @@ information, see the @uref{http://busybox.net, project's home page}.
@cindex Solaris, POSIX-compliant @command{awk}
@cindex source code, Solaris @command{awk}
@item The OpenSolaris POSIX @command{awk}
-The version of @command{awk} in @file{/usr/xpg4/bin} on Solaris is
-more-or-less
-POSIX-compliant. It is based on the @command{awk} from Mortice Kern
-Systems for PCs. The source code can be downloaded from
-the @uref{http://www.opensolaris.org, OpenSolaris web site}.
-This author was able to make it compile and work under GNU/Linux
+The versions of @command{awk} in @file{/usr/xpg4/bin} and
+@file{/usr/xpg6/bin} on Solaris are more-or-less POSIX-compliant.
+They are based on the @command{awk} from Mortice Kern Systems for PCs.
+We were able to make this code compile and work under GNU/Linux
with 1--2 hours of work. Making it more generally portable (using
GNU Autoconf and/or Automake) would take more work, and this
has not been done, at least to our knowledge.
+@cindex Illumos
+@cindex Illumos, POSIX-compliant @command{awk}
+@cindex source code, Illumos @command{awk}
+The source code used to be available from the OpenSolaris website.
+However, that project was ended and the website shut down. Fortunately, the
+@uref{http://wiki.illumos.org/display/illumos/illumos+Home, Illumos project}
+makes this implementation available. You can view the files one at a time from
+@uref{https://github.com/joyent/illumos-joyent/blob/master/usr/src/cmd/awk_xpg4}.
+
@cindex @command{jawk}
@cindex Java implementation of @command{awk}
@cindex source code, @command{jawk}
@@ -28618,13 +38463,21 @@ from POSIX @command{awk}. More information is available on the
@cindex libmawk
@cindex source code, libmawk
This is an embeddable @command{awk} interpreter derived from
-@command{mawk}. For more information see
+@command{mawk}. For more information, see
@uref{http://repo.hu/projects/libmawk/}.
+@item @code{pawk}
+@cindex source code, @command{pawk} (Python version)
+@cindex @code{pawk}, @command{awk}-like facilities for Python
+This is a Python module that claims to bring @command{awk}-like
+features to Python. See @uref{https://github.com/alecthomas/pawk}
+for more information. (This is not related to Nelson Beebe's
+modified version of BWK @command{awk}, described earlier.)
+
@item @w{QSE Awk}
@cindex QSE Awk
@cindex source code, QSE Awk
-This is an embeddable @command{awk} interpreter. For more information
+This is an embeddable @command{awk} interpreter. For more information,
see @uref{http://code.google.com/p/qse/} and @uref{http://awk.info/?tools/qse}.
@item @command{QTawk}
@@ -28636,27 +38489,57 @@ under the GPL. It has a large number of extensions over standard
See @uref{http://www.quiktrim.org/QTawk.html} for more information,
including the manual and a download link.
-@item @command{xgawk}
-@cindex @command{xgawk}
-@cindex source code, @command{xgawk}
-XML @command{gawk}.
-This is a fork of the @command{gawk} 3.1.6 source base
-to support processing XML files. It has a number of
-interesting extensions which should one day be integrated
-into the main @command{gawk} code base.
-For more information, see
-@uref{http://xmlgawk.sourceforge.net, the XMLgawk project web site}.
+The project may also be frozen; no new code changes have been made
+since approximately 2008.
+
+@item Other versions
+See also the ``Versions and implementations'' section of the
+@uref{http://en.wikipedia.org/wiki/Awk_language#Versions_and_implementations,
+Wikipedia article} for information on additional versions.
@end table
-@c ENDOFRANGE gligawk
-@c ENDOFRANGE ingawk
-@c ENDOFRANGE awkim
+@node Installation summary
+@appendixsec Summary
+
+@itemize @value{BULLET}
+@item
+The @command{gawk} distribution is available from GNU project's main
+distribution site, @code{ftp.gnu.org}. The canonical build recipe is:
+
+@example
+wget http://ftp.gnu.org/gnu/gawk/gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz
+tar -xvpzf gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz
+cd gawk-@value{VERSION}.@value{PATCHLEVEL}
+./configure && make && make check
+@end example
+
+@item
+@command{gawk} may be built on non-POSIX systems as well. The currently
+supported systems are MS-Windows using DJGPP, MSYS, MinGW and Cygwin,
+@ifclear FOR_PRINT
+OS/2 using EMX,
+@end ifclear
+and both Vax/VMS and OpenVMS.
+Instructions for each system are included in this @value{CHAPTER}.
+
+@item
+Bug reports should be sent via email to @email{bug-gawk@@gnu.org}.
+Bug reports should be in English, and should include the version of @command{gawk},
+how it was compiled, and a short program and @value{DF} which demonstrate
+the problem.
+
+@item
+There are a number of other freely available @command{awk}
+implementations. Many are POSIX compliant; others are less so.
+
+@end itemize
+
+
+@ifclear FOR_PRINT
@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 implementers and
@@ -28667,9 +38550,11 @@ maintainers of @command{gawk}. Everything in it applies specifically to
* 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.
+* Implementation Limitations:: Some limitations of the implementation.
+* Extension Design:: Design notes about the extension API.
+* Old Extension Mechanism:: Some compatibility for old extensions.
+* Notes summary:: Summary of implementation notes.
@end menu
@node Compatibility Mode
@@ -28690,7 +38575,7 @@ is one more option available on the command line:
@table @code
@item -Y
@itemx --parsedebug
-Prints out the parse stack information as the program is being parsed.
+Print out the parse stack information as the program is being parsed.
@end table
This option is intended only for serious @command{gawk} developers
@@ -28714,20 +38599,23 @@ as well as any considerations you should bear in mind.
@command{gawk}.
* New Ports:: Porting @command{gawk} to a new operating
system.
+* Derived Files:: Why derived files are kept in the Git
+ repository.
@end menu
@node Accessing The Source
@appendixsubsec Accessing The @command{gawk} Git Repository
As @command{gawk} is Free Software, the source code is always available.
-@ref{Gawk Distribution}, describes how to get and build the formal,
+@DBREF{Gawk Distribution} describes how to get and build the formal,
released versions of @command{gawk}.
+@cindex @command{git} utility
However, if you want to modify @command{gawk} and contribute back your
changes, you will probably wish to work with the development version.
To do so, you will need to access the @command{gawk} source code
repository. The code is maintained using the
-@uref{http://git-scm.com/, Git distributed version control system}.
+@uref{http://git-scm.com, Git distributed version control system}.
You will need to install it if your system doesn't have it.
Once you have done so, use the command:
@@ -28736,8 +38624,8 @@ git clone git://git.savannah.gnu.org/gawk.git
@end example
@noindent
-This will clone the @command{gawk} repository. If you are behind a
-firewall that will not allow you to use the Git native protocol, you
+This clones the @command{gawk} repository. If you are behind a
+firewall that does not allow you to use the Git native protocol, you
can still access the repository using:
@example
@@ -28745,35 +38633,29 @@ git clone http://git.savannah.gnu.org/r/gawk.git
@end example
Once you have made changes, you can use @samp{git diff} to produce a
-patch, and send that to the @command{gawk} maintainer; see @ref{Bugs}
+patch, and send that to the @command{gawk} maintainer; see @ref{Bugs},
for how to do that.
-Finally, if you cannot install Git (e.g., if it hasn't been ported
-yet to your operating system), you can use the Git--CVS gateway
-to check out a copy using CVS, as follows:
-
-@example
-cvs -d:pserver:anonymous@@pserver.git.sv.gnu.org:/gawk.git co -d gawk master
-@end example
+Once upon a time there was Git--CVS gateway for use by people who could
+not install Git. However, this gateway no longer works, so you may have
+better luck using a more modern version control system like Bazaar,
+that has a Git plug-in for working with Git repositories.
@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 to include your changes:
+make it possible to include them:
@enumerate 1
@item
Before building the new feature into @command{gawk} itself,
-consider writing it as an extension module
+consider writing it as an extension
(@pxref{Dynamic Extensions}).
If that's not possible, continue with the rest of the steps in this list.
@@ -28790,14 +38672,15 @@ or @EMAIL{assign@@gnu.org,assign at gnu dot org}.
@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.
+the most recent distributed version of @command{gawk}, or better yet,
+relative to the latest code in the Git repository. If your version of
+@command{gawk} is very old, I may not be able to integrate your changes at all.
(@xref{Getting},
for information on getting the latest version of @command{gawk}.)
@item
@ifnotinfo
-Follow the @cite{GNU Coding Standards}.
+Follow the @uref{http://www.gnu.org/prep/standards/, @cite{GNU Coding Standards}}.
@end ifnotinfo
@ifinfo
See @inforef{Top, , Version, standards, GNU Coding Standards}.
@@ -28806,7 +38689,7 @@ 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
-@uref{http://www.gnu.org/prep/standards_toc.html, web site}.
+@uref{http://www.gnu.org/prep/standards_toc.html, website}.
Texinfo, Info, and DVI versions are also available.)
@cindex @command{gawk}, coding style in
@@ -28818,7 +38701,7 @@ 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
+@itemize @value{BULLET}
@item
Use ANSI/ISO style (prototype) function headers when defining functions.
@@ -28857,7 +38740,8 @@ 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
+Use @code{true} and @code{false} for @code{bool} values,
+the @code{NULL} symbolic constant for pointer values,
and the character constant @code{'\0'} where appropriate, instead of @code{1}
and @code{0}.
@@ -28900,12 +38784,14 @@ If possible, please update the @command{man} page as well.
You will also have to sign paperwork for your documentation changes.
+@cindex @command{git} utility
@item
Submit changes as unified diffs.
Use @samp{diff -u -r -N} to compare
the original @command{gawk} source tree with your version.
-I recommend using the GNU version of @command{diff}.
-Send the output produced by either run of @command{diff} to me when you
+I recommend using the GNU version of @command{diff}, or best of all,
+@samp{git diff} or @samp{git format-patch}.
+Send the output produced by @command{diff} to me when you
submit your changes.
(@xref{Bugs}, for the electronic mail
information.)
@@ -28919,15 +38805,13 @@ not do so, particularly if there are lots of changes.
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.
+It is simplest if you just make this part of your diff.
@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
@@ -28954,11 +38838,9 @@ 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
@item
When doing a port, bear in mind that your code must coexist peacefully
@@ -28978,15 +38860,44 @@ A number of the files that come with @command{gawk} are maintained by other
people. 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{dfa.c}, @file{dfa.h}, @file{getopt1.c}, @file{getopt.c},
-@file{getopt.h}, @file{install-sh}, @file{mkinstalldirs}, @file{regcomp.c},
-@file{regex.c}, @file{regexec.c}, @file{regexex.c}, @file{regex.h},
-@file{regex_internal.c}, and @file{regex_internal.h}.
+The files are
+@file{dfa.c},
+@file{dfa.h},
+@file{getopt.c},
+@file{getopt.h},
+@file{getopt1.c},
+@file{getopt_int.h},
+@file{gettext.h},
+@file{regcomp.c},
+@file{regex.c},
+@file{regex.h},
+@file{regex_internal.c},
+@file{regex_internal.h},
+and
+@file{regexec.c}.
+
+@item
+A number of other files are provided by the GNU
+Autotools (Autoconf, Automake, and GNU @command{gettext}).
+You should not change them either, unless it is for a very
+good reason. The files are
+@file{ABOUT-NLS},
+@file{config.guess},
+@file{config.rpath},
+@file{config.sub},
+@file{depcomp},
+@file{INSTALL},
+@file{install-sh},
+@file{missing},
+@file{mkinstalldirs},
+@file{xalloc.h},
+and
+@file{ylwrap}.
@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
+the code needed to compile and run @command{gawk} on their systems. If no-one
volunteers to maintain a port, it becomes unsupported and it may
be necessary to remove it from the distribution.
@@ -29031,789 +38942,197 @@ 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
+@node Derived Files
+@appendixsubsec Why Generated Files Are Kept In Git
-@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}
-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 C @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}.
+@cindex Git, use of for @command{gawk} source code
+@c From emails written March 22, 2012, to the gawk developers list.
-@quotation 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,
-at some future time.
-
-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, nor will there ever be such a guarantee.
-@end quotation
+If you look at the @command{gawk} source in the Git
+repository, you will notice that it includes files that are automatically
+generated by GNU infrastructure tools, such as @file{Makefile.in} from
+Automake and even @file{configure} from Autoconf.
-@quotation NOTE
-When @option{--sandbox} is specified, extensions are disabled
-(@pxref{Options}.
-@end quotation
+This is different from many Free Software projects that do not store
+the derived files, because that keeps the repository less cluttered,
+and it is easier to see the substantive changes when comparing versions
+and trying to understand what changed between commits.
-@menu
-* Internals:: A brief look at some @command{gawk} internals.
-* Plugin License:: A note about licensing.
-* Sample Library:: A example of new functions.
-@end menu
+However, there are several reasons why the @command{gawk} maintainer
+likes to have everything in the repository.
-@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:
+First, because it is then easy to reproduce any given version completely,
+without relying upon the availability of (older, likely obsolete, and
+maybe even impossible to find) other tools.
-@table @code
-@cindex floating-point, numbers, @code{AWKNUM} internal type
-@cindex numbers, floating-point, @code{AWKNUM} internal type
-@cindex @code{AWKNUM} internal type
-@cindex internal type, @code{AWKNUM}
-@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 internal type, @code{NODE}
-@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 internal function, @code{force_number()}
-@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
-@cindex internal function, @code{force_string()}
-@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{force_wstring()} internal function
-@cindex internal function, @code{force_wstring()}
-@item void force_wstring(NODE *n)
-Similarly, this
-macro guarantees that a @code{NODE}'s wide-string value is current.
-It may end up calling an internal @command{gawk} function.
-It also guarantees that the wide string is zero-terminated.
-
-@cindex parameters@comma{} number of
-@cindex @code{nargs} internal variable
-@cindex internal variable, @code{nargs}
-@item nargs
-Inside an extension function, this is the actual number of
-parameters passed to the current function.
-
-@cindex @code{stptr} internal variable
-@cindex internal variable, @code{stptr}
-@cindex @code{stlen} internal variable
-@cindex internal variable, @code{stlen}
-@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{wstptr} internal variable
-@cindex internal variable, @code{wstptr}
-@cindex @code{wstlen} internal variable
-@cindex internal variable, @code{wstlen}
-@item n->wstptr
-@itemx n->wstlen
-The data and length of a @code{NODE}'s wide-string value, respectively.
-Use @code{force_wstring()} to make sure these values are current.
-
-@cindex @code{type} internal variable
-@cindex internal variable, @code{type}
-@item n->type
-The type of the @code{NODE}. This is a C @code{enum}. Values should
-be one of @code{Node_var}, @code{Node_var_new}, or @code{Node_var_array}
-for function parameters.
-
-@cindex @code{vname} internal variable
-@cindex internal variable, @code{vname}
-@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
-@cindex internal function, @code{assoc_clear()}
-@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
-@cindex internal function, @code{assoc_lookup()}
-@item NODE **assoc_lookup(NODE *symbol, NODE *subs)
-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{make_string()} (see below).
-
-@cindex strings
-@cindex @code{make_string()} internal function
-@cindex internal function, @code{make_string()}
-@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
-@cindex internal function, @code{make_number()}
-@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 nodes@comma{} duplicating
-@cindex @code{dupnode()} internal function
-@cindex internal function, @code{dupnode()}
-@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{unref()} internal function
-@cindex internal function, @code{unref()}
-@item void unref(NODE *n)
-This macro releases the memory associated with a @code{NODE}
-allocated with @code{make_string()} or @code{make_number()}.
-Understanding of @command{gawk} memory management is helpful.
-
-@cindex @code{make_builtin()} internal function
-@cindex internal function, @code{make_builtin()}
-@item void make_builtin(const 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(int nargs)
-@{
- @dots{}
-@}
-@end example
-
-@cindex arguments, retrieving
-@cindex @code{get_argument()} internal function
-@cindex internal function, @code{get_argument()}
-@item NODE *get_argument(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
-@cindex internal function, @code{get_actual_argument()}
-@item NODE *get_actual_argument(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.
-
-@cindex @code{get_scalar_argument()} internal macro
-@cindex internal macro, @code{get_scalar_argument()}
-@item get_scalar_argument(i, opt)
-This is a convenience macro that calls @code{get_actual_argument()}.
-
-@cindex @code{get_array_argument()} internal macro
-@cindex internal macro, @code{get_array_argument()}
-@item get_array_argument(i, opt)
-This is a convenience macro that calls @code{get_actual_argument()}.
-
-@cindex functions, return values@comma{} setting
-
-@cindex @code{ERRNO} variable
-@cindex @code{update_ERRNO()} internal function
-@cindex internal function, @code{update_ERRNO()}
-@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} global variable.
-It is provided as a convenience.
-
-@cindex @code{ERRNO} variable
-@cindex @code{update_ERRNO_saved()} internal function
-@cindex internal function, @code{update_ERRNO_saved()}
-@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 error
-value provided as the argument.
-It is provided as a convenience.
-
-@cindex @code{ENVIRON} array
-@cindex @code{PROCINFO} array
-@cindex @code{register_deferred_variable()} internal function
-@cindex internal function, @code{register_deferred_variable()}
-@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 @code{NODE} containing the
-newly created variable. This function is used to implement the builtin
-@code{ENVIRON} and @code{PROCINFO} arrays, so you can refer to them
-for examples.
-
-@cindex @code{IOBUF} internal structure
-@cindex internal structure, @code{IOBUF}
-@cindex @code{iop_alloc()} internal function
-@cindex internal function, @code{iop_alloc()}
-@cindex @code{get_record()} input method
-@cindex @code{close_func}() input method
-@cindex @code{INVALID_HANDLE} internal constant
-@cindex internal constant, @code{INVALID_HANDLE}
-@cindex XML (eXtensible Markup Language)
-@cindex eXtensible Markup Language (XML)
-@cindex @code{register_open_hook()} internal function
-@cindex internal function, @code{register_open_hook()}
-@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-@code{NULL}. If any hook returns a non-@code{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}'s
-@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}'s
-@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}.
-@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.
-
-The following boilerplate code shows how to do this:
-
-@example
-NODE *the_arg;
-
-/* assume need 3rd arg, 0-based */
-the_arg = get_array_argument(2, FALSE);
-@end example
-
-Again, you should spend time studying the @command{gawk} internals;
-don't just blindly copy this code.
-@c ENDOFRANGE gawint
-
-@node Plugin License
-@appendixsubsec Extension Licensing
-
-Every dynamic extension should define the global symbol
-@code{plugin_is_GPL_compatible} to assert that it has been licensed under
-a GPL-compatible license. If this symbol does not exist, @command{gawk}
-will emit a fatal error and exit.
-
-The declared type of the symbol should be @code{int}. It does not need
-to be in any allocated section, though. The code merely asserts that
-the symbol exists in the global scope. Something like this is enough:
-
-@example
-int plugin_is_GPL_compatible;
-@end example
-
-@node Sample Library
-@appendixsubsec Example: 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
+As an extreme example, if you ever even think about trying to compile,
+oh, say, the V7 @command{awk}, you will discover that not only do you
+have to bootstrap the V7 @command{yacc} to do so, but you also need the
+V7 @command{lex}. And the latter is pretty much impossible to bring up
+on a modern GNU/Linux system.@footnote{We tried. It was painful.}
-@node Internal File Description
-@appendixsubsubsec Using @code{chdir()} and @code{stat()}
+(Or, let's say @command{gawk} 1.2 required @command{bison} whatever-it-was
+in 1989 and that there was no @file{awkgram.c} file in the repository. Is
+there a guarantee that we could find that @command{bison} version? Or that
+@emph{it} would build?)
-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:
+If the repository has all the generated files, then it's easy to just check
+them out and build. (Or @emph{easier}, depending upon how far back we go.)
-@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
+And that brings us to the second (and stronger) reason why all the files
+really need to be in Git. It boils down to who do you cater
+to---the @command{gawk} developer(s), or the user who just wants to check
+out a version and try it out?
-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.
+The @command{gawk} maintainer
+wants it to be possible for any interested @command{awk} user in the
+world to just clone the repository, check out the branch of interest and
+build it. Without their having to have the correct version(s) of the
+autotools.@footnote{There is one GNU program that is (in our opinion)
+severely difficult to bootstrap from the Git repository. For
+example, on the author's old (but still working) PowerPC Macintosh with
+Mac OS X 10.5, it was necessary to bootstrap a ton of software, starting
+with Git itself, in order to try to work with the latest code.
+It's not pleasant, and especially on older systems, it's a big waste
+of time.
-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:
+Starting with the latest tarball was no picnic either. The maintainers
+had dropped @file{.gz} and @file{.bz2} files and only distribute
+@file{.tar.xz} files. It was necessary to bootstrap @command{xz} first!}
+That is the point of the @file{bootstrap.sh} file. It touches the
+various other files in the right order such that
-@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"])
+# The canonical incantation for building GNU software:
+./bootstrap.sh && ./configure && make
@end example
-The @code{stat()} function always clears the data array, even if
-the @code{stat()} fails. It fills in the following elements:
+@noindent
+will @emph{just work}.
-@table @code
-@item "name"
-The name of the file that was @code{stat()}'ed.
+This is extremely important for the @code{master} and
+@code{gawk-@var{X}.@var{Y}-stable} branches.
-@item "dev"
-@itemx "ino"
-The file's device and inode numbers, respectively.
+Further, the @command{gawk} maintainer would argue that it's also
+important for the @command{gawk} developers. When he tried to check out
+the @code{xgawk} branch@footnote{A branch (since removed) created by one of the other
+developers that did not include the generated files.} to build it, he
+couldn't. (No @file{ltmain.sh} file, and he had no idea how to create it,
+and that was not the only problem.)
-@item "mode"
-The file's mode, as a numeric value. This includes both the file's
-type and its permissions.
+He felt @emph{extremely} frustrated. With respect to that branch,
+the maintainer is no different than Jane User who wants to try to build
+@code{gawk-4.1-stable} or @code{master} from the repository.
-@item "nlink"
-The number of hard links (directory entries) the file has.
+Thus, the maintainer thinks that it's not just important, but critical,
+that for any given branch, the above incantation @emph{just works}.
-@item "uid"
-@itemx "gid"
-The numeric user and group ID numbers of the file's owner.
+@c Added 9/2014:
+A third reason to have all the files is that without them, using @samp{git
+bisect} to try to find the commit that introduced a bug is exceedingly
+difficult. The maintainer tried to do that on another project that
+requires running bootstrapping scripts just to create @command{configure}
+and so on; it was really painful. When the repository is self-contained,
+using @command{git bisect} in it is very easy.
-@item "size"
-The size in bytes of the file.
+@c So - that's my reasoning and philosophy.
-@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.
+What are some of the consequences and/or actions to take?
-@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}).
+@enumerate 1
+@item
+We don't mind that there are differing files in the different branches
+as a result of different versions of the autotools.
-@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"}.
+@enumerate A
+@item
+It's the maintainer's job to merge them and he will deal with it.
-@item "type"
-A printable string representation of the file's type. The value
-is one of the following:
+@item
+He is really good at @samp{git diff x y > /tmp/diff1 ; gvim /tmp/diff1} to
+remove the diffs that aren't of interest in order to review code.
+@end enumerate
-@table @code
-@item "blockdev"
-@itemx "chardev"
-The file is a block or character device (``special file'').
+@item
+It would certainly help if everyone used the same versions of the GNU tools
+as he does, which in general are the latest released versions of
+Automake,
+Autoconf,
+@command{bison},
+and
+GNU @command{gettext}.
@ignore
-@item "door"
-The file is a Solaris ``door'' (special file used for
-interprocess communications).
+If it would help if I sent out an ``I just upgraded to version x.y
+of tool Z'' kind of message to this list, I can do that. Up until
+now it hasn't been a real issue since I'm the only one who's been
+dorking with the configuration machinery.
@end ignore
-@item "directory"
-The file is a directory.
+@c @enumerate A
+@c @item
+Installing from source is quite easy. It's how the maintainer worked for years
+(and still works).
+He had @file{/usr/local/bin} at the front of his @env{PATH} and just did:
-@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. See
-@file{extension/filefuncs.c} in the @command{gawk} distribution
-for the complete version.}
-
-@c break line for page breaking
@example
-#include "awk.h"
-
-#include <sys/sysmacros.h>
-
-int plugin_is_GPL_compatible;
-
-/* do_chdir --- provide dynamically loaded chdir() builtin for gawk */
-
-static NODE *
-do_chdir(int nargs)
-@{
- NODE *newdir;
- int ret = -1;
-
- if (do_lint && nargs != 1)
- lintwarn("chdir: called with incorrect number of arguments");
-
- newdir = get_scalar_argument(0, FALSE);
-@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{int} argument, usually called @code{nargs}, that
-represents the number of defined arguments for the function. The @code{newdir}
-variable represents the new directory to change to, retrieved
-with @code{get_scalar_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.
-
-@example
- (void) force_string(newdir);
- ret = chdir(newdir->stptr);
- if (ret < 0)
- update_ERRNO();
-@end example
-
-Finally, the function returns the return value to the @command{awk} level:
-
-@example
- return make_number((AWKNUM) ret);
-@}
+wget http://ftp.gnu.org/gnu/@var{package}/@var{package}-@var{x}.@var{y}.@var{z}.tar.gz
+tar -xpzvf @var{package}-@var{x}.@var{y}.@var{z}.tar.gz
+cd @var{package}-@var{x}.@var{y}.@var{z}
+./configure && make && make check
+make install # as root
@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(unsigned long fmode)
-@{
- @dots{}
-@}
-@end example
-
-Next comes the @code{do_stat()} function. It starts with
-variable declarations and argument checking:
-
+@c @item
@ignore
-Changed message for page breaking. Used to be:
- "stat: called with incorrect number of arguments (%d), should be 2",
+These days the maintainer uses Ubuntu 12.04 which is medium current, but
+he is already doing the above for Automake, Autoconf, and @command{bison}.
@end ignore
-@example
-/* do_stat --- provide a stat() function for gawk */
-
-static NODE *
-do_stat(int nargs)
-@{
- NODE *file, *array, *tmp;
- struct stat sbuf;
- int ret;
- NODE **aptr;
- char *pmode; /* printable mode */
- char *type = "unknown";
-
- if (do_lint && nargs > 2)
- lintwarn("stat: called with too many arguments");
-@end example
-
-Then comes the actual work. First, the function gets the arguments.
-Then, it always clears the array.
-The code use @code{lstat()} (instead of @code{stat()})
-to get the file information,
-in case the file is a symbolic link.
-If there's an error, it sets @code{ERRNO} and returns:
-
-@c comment made multiline for page breaking
-@example
- /* file is first arg, array to hold results is second */
- file = get_scalar_argument(0, FALSE);
- array = get_array_argument(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();
- return make_number((AWKNUM) ret);
- @}
-@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 = make_string("name", 4));
- *aptr = dupnode(file);
- unref(tmp);
-
- aptr = assoc_lookup(array, tmp = make_string("mode", 4));
- *aptr = make_number((AWKNUM) sbuf.st_mode);
- unref(tmp);
-
- aptr = assoc_lookup(array, tmp = make_string("pmode", 5));
- pmode = format_mode(sbuf.st_mode);
- *aptr = make_string(pmode, strlen(pmode));
- unref(tmp);
-@end example
-
-When done, return the @code{lstat()} return value:
-
-@example
-
- return make_number((AWKNUM) ret);
-@}
-@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(NODE *tree, void *dl)
-@{
- make_builtin("chdir", do_chdir, 1);
- make_builtin("stat", do_stat, 2);
- return make_number((AWKNUM) 0);
-@}
-@end example
+@ignore
+(C. Rant: Recent Linux versions with GNOME 3 really suck. What
+ are all those people thinking? Fedora 15 was such a bust it drove
+ me to Ubuntu, but Ubuntu 11.04 and 11.10 are totally unusable from
+ a UI perspective. Bleah.)
+@end ignore
+@c @end enumerate
-And that's it! As an exercise, consider adding functions to
-implement system calls such as @code{chown()}, @code{chmod()},
-and @code{umask()}.
+@ignore
+@item
+If someone still feels really strongly about all this, then perhaps they
+can have two branches, one for their development with just the clean
+changes, and one that is buildable (xgawk and xgawk-buildable, maybe).
+Or, as I suggested in another mail, make commits in pairs, the first with
+the "real" changes and the second with "everything else needed for
+ building".
+@end ignore
+@end enumerate
-@node Using Internal File Ops
-@appendixsubsubsec Integrating the Extensions
+Most of the above was originally written by the maintainer to other
+@command{gawk} developers. It raised the objection from one of
+the developers ``@dots{} that anybody pulling down the source from
+Git is not an end user.''
-@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:
+However, this is not true. There are ``power @command{awk} users''
+who can build @command{gawk} (using the magic incantation shown previously)
+but who can't program in C. Thus, the major branches should be
+kept buildable all the time.
-@example
-$ @kbd{gcc -fPIC -shared -DHAVE_CONFIG_H -c -O -g -I@var{idir} filefuncs.c}
-$ @kbd{ld -o filefuncs.so -shared filefuncs.o}
-@end example
+It was then suggested that there be a @command{cron} job to create
+nightly tarballs of ``the source.'' Here, the problem is that there
+are source trees, corresponding to the various branches! So,
+nightly tarballs aren't the answer, especially as the repository can go
+for weeks without significant change being introduced.
-@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:
+Fortunately, the Git server can meet this need. For any given
+branch named @var{branchname}, use:
@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"])
-
- 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"])
-@}
+wget http://git.savannah.gnu.org/cgit/gawk.git/snapshot/gawk-@var{branchname}.tar.gz
@end example
-Here are the results of running the program:
-
-@example
-$ @kbd{gawk -f testff.awk}
-@print{} Info for testff.awk
-@print{} ret = 0
-@print{} data["size"] = 607
-@print{} data["ino"] = 14945891
-@print{} data["name"] = testff.awk
-@print{} data["pmode"] = -rw-rw-r--
-@print{} data["nlink"] = 1
-@print{} data["atime"] = 1293993369
-@print{} data["mtime"] = 1288520752
-@print{} data["mode"] = 33204
-@print{} data["blksize"] = 4096
-@print{} data["dev"] = 2054
-@print{} data["type"] = file
-@print{} data["gid"] = 500
-@print{} data["uid"] = 500
-@print{} data["blocks"] = 8
-@print{} data["ctime"] = 1290113572
-@print{} testff.awk modified: 10 31 10 12:25:52
-@print{}
-@print{} Info for JUNK
-@print{} ret = -1
-@print{} JUNK modified: 01 01 70 02:00:00
-@end example
-@c ENDOFRANGE filre
-@c ENDOFRANGE dirch
-@c ENDOFRANGE statg
-@c ENDOFRANGE chdirg
-@c ENDOFRANGE gladfgaw
-@c ENDOFRANGE adfugaw
-@c ENDOFRANGE fubadgaw
+@noindent
+to retrieve a snapshot of the given branch.
@node Future Extensions
@appendixsec Probable Future Extensions
@@ -29855,80 +39174,349 @@ Larry
@cindex Wall, Larry
@cindex Robbins, Arnold
@quotation
-@i{AWK is a language similar to PERL, only considerably more elegant.}@*
-Arnold Robbins
+@i{AWK is a language similar to PERL, only considerably more elegant.}
+@author Arnold Robbins
+@end quotation
-@i{Hey!}@*
-Larry Wall
+@quotation
+@i{Hey!}
+@author 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.
+The @file{TODO} file in the @code{master} branch of the @command{gawk}
+Git repository lists possible future enhancements. Some of these relate
+to the source code, and others to possible new features. Please see
+that file for the list.
+@xref{Additions},
+if you are interested in tackling any of the projects listed there.
+
+@node Implementation Limitations
+@appendixsec Some Limitations of the Implementation
+
+This following table describes limits of @command{gawk} on a Unix-like
+system (although it is variable even then). Other systems may have
+different limits.
+
+@multitable @columnfractions .40 .60
+@headitem Item @tab Limit
+@item Characters in a character class @tab 2^(number of bits per byte)
+@item Length of input record @tab @code{MAX_INT}
+@item Length of output record @tab Unlimited
+@item Length of source line @tab Unlimited
+@item Number of fields in a record @tab @code{MAX_LONG}
+@item Number of file redirections @tab Unlimited
+@item Number of input records in one file @tab @code{MAX_LONG}
+@item Number of input records total @tab @code{MAX_LONG}
+@item Number of pipe redirections @tab min(number of processes per user, number of open files)
+@item Numeric values @tab Double-precision floating point (if not using MPFR)
+@item Size of a field @tab @code{MAX_INT}
+@item Size of a literal string @tab @code{MAX_INT}
+@item Size of a printf string @tab @code{MAX_INT}
+@end multitable
-Following is a list of probable future changes visible at the
-@command{awk} language level:
+@node Extension Design
+@appendixsec Extension API Design
-@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 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
+This @value{SECTION} documents the design of the extension API,
+including a discussion of some of the history and problems that needed
+to be solved.
-Following is a list of probable improvements that will make @command{gawk}'s
-source code easier to work with:
+The first version of extensions for @command{gawk} was developed in
+the mid-1990s and released with @command{gawk} 3.1 in the late 1990s.
+The basic mechanisms and design remained unchanged for close to 15 years,
+until 2012.
-@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.
-@end table
+The old extension mechanism used data types and functions from
+@command{gawk} itself, with a ``clever hack'' to install extension
+functions.
-Finally,
-the programs in the test suite could use documenting in this @value{DOCUMENT}.
+@command{gawk} included some sample extensions, of which a few were
+really useful. However, it was clear from the outset that the extension
+mechanism was bolted onto the side and was not really well thought out.
+
+@menu
+* Old Extension Problems:: Problems with the old mechanism.
+* Extension New Mechanism Goals:: Goals for the new mechanism.
+* Extension Other Design Decisions:: Some other design decisions.
+* Extension Future Growth:: Some room for future growth.
+@end menu
+
+@node Old Extension Problems
+@appendixsubsec Problems With The Old Mechanism
+
+The old extension mechanism had several problems:
+
+@itemize @value{BULLET}
+@item
+It depended heavily upon @command{gawk} internals. Any time the
+@code{NODE} structure@footnote{A critical central data structure
+inside @command{gawk}.} changed, an extension would have to be
+recompiled. Furthermore, to really write extensions required understanding
+something about @command{gawk}'s internal functions. There was some
+documentation in this @value{DOCUMENT}, but it was quite minimal.
+
+@item
+Being able to call into @command{gawk} from an extension required linker
+facilities that are common on Unix-derived systems but that did
+not work on MS-Windows systems; users wanting extensions on MS-Windows
+had to statically link them into @command{gawk}, even though MS-Windows supports
+dynamic loading of shared objects.
+
+@item
+The API would change occasionally as @command{gawk} changed; no compatibility
+between versions was ever offered or planned for.
+@end itemize
+
+Despite the drawbacks, the @command{xgawk} project developers forked
+@command{gawk} and developed several significant extensions. They also
+enhanced @command{gawk}'s facilities relating to file inclusion and
+shared object access.
+
+A new API was desired for a long time, but only in 2012 did the
+@command{gawk} maintainer and the @command{xgawk} developers finally
+start working on it together. More information about the @command{xgawk}
+project is provided in @ref{gawkextlib}.
+
+@node Extension New Mechanism Goals
+@appendixsubsec Goals For A New Mechanism
+
+Some goals for the new API were:
+
+@itemize @value{BULLET}
+@item
+The API should be independent of @command{gawk} internals. Changes in
+@command{gawk} internals should not be visible to the writer of an
+extension function.
+
+@item
+The API should provide @emph{binary} compatibility across @command{gawk}
+releases as long as the API itself does not change.
+
+@item
+The API should enable extensions written in C or C++ to have roughly the
+same ``appearance'' to @command{awk}-level code as @command{awk}
+functions do. This means that extensions should have:
+
+@itemize @value{MINUS}
+@item
+The ability to access function parameters.
+
+@item
+The ability to turn an undefined parameter into an array (call by reference).
+
+@item
+The ability to create, access and update global variables.
+
+@item
+Easy access to all the elements of an array at once (``array flattening'')
+in order to loop over all the element in an easy fashion for C code.
+
+@item
+The ability to create arrays (including @command{gawk}'s true
+arrays of arrays).
+@end itemize
+@end itemize
+
+Some additional important goals were:
+
+@itemize @value{BULLET}
+@item
+The API should use only features in ISO C 90, so that extensions
+can be written using the widest range of C and C++ compilers. The header
+should include the appropriate @samp{#ifdef __cplusplus} and @samp{extern "C"}
+magic so that a C++ compiler could be used. (If using C++, the runtime
+system has to be smart enough to call any constructors and destructors,
+as @command{gawk} is a C program. As of this writing, this has not been
+tested.)
+
+@item
+The API mechanism should not require access to @command{gawk}'s
+symbols@footnote{The @dfn{symbols} are the variables and functions
+defined inside @command{gawk}. Access to these symbols by code
+external to @command{gawk} loaded dynamically at runtime is
+problematic on MS-Windows.} by the compile-time or dynamic linker,
+in order to enable creation of extensions that also work on MS-Windows.
+@end itemize
+
+During development, it became clear that there were other features
+that should be available to extensions, which were also subsequently
+provided:
+
+@itemize @value{BULLET}
+@item
+Extensions should have the ability to hook into @command{gawk}'s
+I/O redirection mechanism. In particular, the @command{xgawk}
+developers provided a so-called ``open hook'' to take over reading
+records. During development, this was generalized to allow
+extensions to hook into input processing, output processing, and
+two-way I/O.
+
+@item
+An extension should be able to provide a ``call back'' function
+to perform cleanup actions when @command{gawk} exits.
+
+@item
+An extension should be able to provide a version string so that
+@command{gawk}'s @option{--version} option can provide information
+about extensions as well.
+@end itemize
+
+The requirement to avoid access to @command{gawk}'s symbols is, at first
+glance, a difficult one to meet.
+
+One design, apparently used by Perl and Ruby and maybe others, would
+be to make the mainline @command{gawk} code into a library, with the
+@command{gawk} utility a small C @code{main()} function linked against
+the library.
+
+This seemed like the tail wagging the dog, complicating build and
+installation and making a simple copy of the @command{gawk} executable
+from one system to another (or one place to another on the same
+system!) into a chancy operation.
+
+Pat Rankin suggested the solution that was adopted.
+@xref{Extension Mechanism Outline}, for the details.
+
+@node Extension Other Design Decisions
+@appendixsubsec Other Design Decisions
+
+As an arbitrary design decision, extensions can read the values of
+predefined variables and arrays (such as @code{ARGV} and @code{FS}), but cannot
+change them, with the exception of @code{PROCINFO}.
+
+The reason for this is to prevent an extension function from affecting
+the flow of an @command{awk} program outside its control. While a real
+@command{awk} function can do what it likes, that is at the discretion
+of the programmer. An extension function should provide a service or
+make a C API available for use within @command{awk}, and not mess with
+@code{FS} or @code{ARGC} and @code{ARGV}.
+
+In addition, it becomes easy to start down a slippery slope. How
+much access to @command{gawk} facilities do extensions need?
+Do they need @code{getline}? What about calling @code{gsub()} or
+compiling regular expressions? What about calling into @command{awk}
+functions? (@emph{That} would be messy.)
+
+In order to avoid these issues, the @command{gawk} developers chose
+to start with the simplest, most basic features that are still truly useful.
+
+Another decision is that although @command{gawk} provides nice things like
+MPFR, and arrays indexed internally by integers, these features are not
+being brought out to the API in order to keep things simple and close to
+traditional @command{awk} semantics. (In fact, arrays indexed internally
+by integers are so transparent that they aren't even documented!)
+
+Additionally, all functions in the API check that their pointer
+input parameters are not @code{NULL}. If they are, they return an error.
+(It is a good idea for extension code to verify that
+pointers received from @command{gawk} are not @code{NULL}.
+Such a thing should not happen, but the @command{gawk} developers
+are only human, and they have been known to occasionally make
+mistakes.)
+
+With time, the API will undoubtedly evolve; the @command{gawk} developers
+expect this to be driven by user needs. For now, the current API seems
+to provide a minimal yet powerful set of features for creating extensions.
+
+@node Extension Future Growth
+@appendixsubsec Room For Future Growth
+
+The API can later be expanded, in two ways:
+
+@itemize @value{BULLET}
+@item
+@command{gawk} passes an ``extension id'' into the extension when it
+first loads the extension. The extension then passes this id back
+to @command{gawk} with each function call. This mechanism allows
+@command{gawk} to identify the extension calling into it, should it need
+to know.
+
+@item
+Similarly, the extension passes a ``name space'' into @command{gawk}
+when it registers each extension function. This accommodates a possible future
+mechanism for grouping extension functions and possibly avoiding name
+conflicts.
+@end itemize
+
+Of course, as of this writing, no decisions have been made with respect
+to any of the above.
+
+@node Old Extension Mechanism
+@appendixsec Compatibility For Old Extensions
+
+@ref{Dynamic Extensions}, describes the supported API and mechanisms
+for writing extensions for @command{gawk}. This API was introduced
+in @value{PVERSION} 4.1. However, for many years @command{gawk}
+provided an extension mechanism that required knowledge of @command{gawk}
+internals and that was not as well designed.
+
+In order to provide a transition period, @command{gawk} @value{PVERSION} 4.1
+continues to support the original extension mechanism.
+This will be true for the life of exactly one major release. This support
+will be withdrawn, and removed from the source code, at the next major
+release.
+
+Briefly, original-style extensions should be compiled by including the
+@file{awk.h} header file in the extension source code. Additionally,
+you must define the identifier @samp{GAWK} when building (use
+@samp{-DGAWK} with Unix-style compilers). Otherwise, the definitions
+in @file{gawkapi.h} will cause conflicts with those in @file{awk.h}
+and your extension will not compile.
+
+Just as in previous versions, you load an old-style extension with the
+@code{extension()} built-in function (which is not otherwise documented).
+This function in turn finds and loads the shared object file containing
+the extension and calls its @code{dl_load()} C routine.
+
+Because original-style and new-style extensions use different initialization
+routines (@code{dl_load()} versus @code{dlload()}), they may safely
+be installed in the same directory (to be found by @env{AWKLIBPATH})
+without conflict.
+
+The @command{gawk} development team strongly recommends that you
+convert any old extensions that you may have to use the new API
+described in @ref{Dynamic Extensions}.
+
+@node Notes summary
+@appendixsec Summary
+
+@itemize @value{BULLET}
+@item
+@command{gawk}'s extensions can be disabled with either the
+@option{--traditional} option or with the @option{--posix} option.
+The @option{--parsedebug} option is available if @command{gawk} is
+compiled with @samp{-DDEBUG}.
+
+@item
+The source code for @command{gawk} is maintained in a publicly
+accessible Git repository. Anyone may check it out and view the source.
+
+@item
+Contributions to @command{gawk} are welcome. Following the steps
+outlined in this @value{CHAPTER} will make it easier to integrate
+your contributions into the code base.
+This applies both to new feature contributions and to ports to
+additional operating systems.
+
+@item
+@command{gawk} has some limits---generally those that are imposed by
+the machine architecture.
+
+@item
+The extension API design was intended to solve a number of problems
+with the previous extension mechanism, enable features needed by
+the @code{xgawk} project, and provide binary compatibility going forward.
+
+@item
+The previous extension mechanism is still supported in @value{PVERSION} 4.1
+of @command{gawk}, but it @emph{will} be removed in the next major release.
+
+@end itemize
-@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
@@ -29942,7 +39530,6 @@ 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
@@ -29951,18 +39538,33 @@ other introductory texts that you should refer to instead.)
@cindex processing data
At the most basic level, the job of a program is to process
some input data and produce results.
+@ifnotdocbook
+See @ref{figure-general-flow}.
+@end ifnotdocbook
+@ifdocbook
+See @inlineraw{docbook, <xref linkend="figure-general-flow"/>}.
+@end ifdocbook
-@iftex
-@image{general-program}
-@end iftex
-@ifnottex
-@example
- _______
-+------+ / \ +---------+
-| Data | -----> < Program > -----> | Results |
-+------+ \_______/ +---------+
-@end example
-@end ifnottex
+@ifnotdocbook
+@float Figure,figure-general-flow
+@caption{General Program Flow}
+@ifinfo
+@center @image{general-program, , , General program flow, txt}
+@end ifinfo
+@ifnotinfo
+@center @image{general-program, , , General program flow}
+@end ifnotinfo
+@end float
+@end ifnotdocbook
+
+@docbook
+<figure id="figure-general-flow" float="0">
+<title>General Program Flow</title>
+<mediaobject>
+<imageobject role="web"><imagedata fileref="general-program.png" format="PNG"/></imageobject>
+</mediaobject>
+</figure>
+@end docbook
@cindex compiled programs
@cindex interpreted programs
@@ -29978,26 +39580,34 @@ 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:
+of the following, very basic set of steps,
+@ifnotdocbook
+as shown in @ref{figure-process-flow}:
+@end ifnotdocbook
+@ifdocbook
+as shown in @inlineraw{docbook, <xref linkend="figure-process-flow"/>}:
+@end ifdocbook
-@iftex
-@image{process-flow}
-@end iftex
-@ifnottex
-@example
- ______
-+----------------+ / More \ No +----------+
-| Initialization | -------> < Data > -------> | Clean Up |
-+----------------+ ^ \ ? / +----------+
- | +--+-+
- | | Yes
- | |
- | V
- | +---------+
- +-----+ Process |
- +---------+
-@end example
-@end ifnottex
+@ifnotdocbook
+@float Figure,figure-process-flow
+@caption{Basic Program Steps}
+@ifinfo
+@center @image{process-flow, , , Basic Program Stages, txt}
+@end ifinfo
+@ifnotinfo
+@center @image{process-flow, , , Basic Program Stages}
+@end ifnotinfo
+@end float
+@end ifnotdocbook
+
+@docbook
+<figure id="figure-process-flow" float="0">
+<title>Basic Program Stages</title>
+<mediaobject>
+<imageobject role="web"><imagedata fileref="process-flow.png" format="PNG"/></imageobject>
+</mediaobject>
+</figure>
+@end docbook
@table @asis
@item Initialization
@@ -30093,47 +39703,10 @@ 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 systems,
-this range is @minus{}2,147,483,648 to 2,147,483,647.
-However, many systems now support a range from
-@minus{}9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.
-
-@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 systems,
-the range is from 0 to 4,294,967,295.
-However, many systems now support a range from
-0 to 18,446,744,073,709,551,615.
-
-@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.
+@ref{Computer Arithmetic}, provided a basic introduction to numeric
+types (integer and floating-point) and how they are used in a computer.
+Please review that information, including a number of caveats that
+were presented.
@cindex null strings
While you are probably used to the idea of a number without a value (i.e., zero),
@@ -30146,17 +39719,22 @@ 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.)
+column. (Remember grade school? 42 = 4 x 10 + 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.
+Thus, binary 1010 represents (1 x 8) + (0 x 4) + (1 x 2)
++ (0 x 1), or decimal 10.
Octal and hexadecimal are discussed more in
@ref{Nondecimal-numbers}.
+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.
+
Programs are written in programming languages.
Hundreds, if not thousands, of programming languages exist.
One of the most popular is the C programming language.
@@ -30176,240 +39754,6 @@ standard for C. This standard became an ISO standard in 1990.
In 1999, a revised ISO C standard was approved and released.
Where it makes sense, POSIX @command{awk} is compatible with 1999 ISO C.
-@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
-@uref{http://www.validlab.com/goldberg/paper.pdf, 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.
-This is worth reading if you are interested in the details,
-but it does require a background in computer science.
-
-@menu
-* String Conversion Precision:: The String Value Can Lie.
-* Unexpected Results:: Floating Point Numbers Are Not Abstract
- Numbers.
-* POSIX Floating Point Problems:: Standards Versus Existing Practice.
-@end menu
-
-@node String Conversion Precision
-@appendixsubsec The String Value Can Lie
-
-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
-@{
- sum = $1 + $2
- # see it for what it is
- printf("sum = %.12g\n", sum)
- # use CONVFMT
- a = "<" sum ">"
- print "a =", a
- # use OFMT
- print "sum =", sum
-@}
-@end example
-
-@noindent
-This program shows the full value of the sum of @code{$1} and @code{$2}
-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
-$ @kbd{echo 3.654321 1.2345678 | awk -f values.awk}
-@print{} sum = 4.8888888
-@print{} a = <4.88889>
-@print{} sum = 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.}
-
-@node Unexpected Results
-@appendixsubsec Floating Point Numbers Are Not Abstract Numbers
-
-@cindex floating-point, numbers
-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
-$ @kbd{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:
-
-@example
-$ @kbd{gawk 'BEGIN @{ mz = -0 ; pz = 0}
-> @kbd{printf "-0 = %g, +0 = %g, (-0 == +0) -> %d\n", mz, pz, mz == pz}
-> @kbd{printf "mz == 0 -> %d, pz == 0 -> %d\n", mz == 0, pz == 0}
-> @kbd{@}'}
-@print{} -0 = -0, +0 = 0, (-0 == +0) -> 1
-@print{} mz == 0 -> 1, pz == 0 -> 1
-@end example
-
-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.
-
-@node POSIX Floating Point Problems
-@appendixsubsec Standards Versus Existing Practice
-
-Historically, @command{awk} has converted any non-numeric looking string
-to the numeric value zero, when required. Furthermore, the original
-definition of the language and the original POSIX standards specified that
-@command{awk} only understands decimal numbers (base 10), and not octal
-(base 8) or hexadecimal numbers (base 16).
-
-Changes in the language of the
-2001 and 2004 POSIX standard can be interpreted to imply that @command{awk}
-should support additional features. These features are:
-
-@itemize @bullet
-@item
-Interpretation of floating point data values specified in hexadecimal
-notation (@samp{0xDEADBEEF}). (Note: data values, @emph{not}
-source code constants.)
-
-@item
-Support for the special IEEE 754 floating point values ``Not A Number''
-(NaN), positive Infinity (``inf'') and negative Infinity (``@minus{}inf'').
-In particular, the format for these values is as specified by the ISO 1999
-C standard, which ignores case and can allow machine-dependent additional
-characters after the @samp{nan} and allow either @samp{inf} or @samp{infinity}.
-@end itemize
-
-The first problem is that both of these are clear changes to historical
-practice:
-
-@itemize @bullet
-@item
-The @command{gawk} maintainer feels that supporting hexadecimal floating
-point values, in particular, is ugly, and was never intended by the
-original designers to be part of the language.
-
-@item
-Allowing completely alphabetic strings to have valid numeric
-values is also a very severe departure from historical practice.
-@end itemize
-
-The second problem is that the @code{gawk} maintainer feels that this
-interpretation of the standard, which requires a certain amount of
-``language lawyering'' to arrive at in the first place, was not even
-intended by the standard developers. In other words, ``we see how you
-got where you are, but we don't think that that's where you want to be.''
-
-The 2008 POSIX standard added explicit wording to allow, but not require,
-that @command{awk} support hexadecimal floating point values and
-special values for ``Not A Number'' and infinity.
-
-Although the @command{gawk} maintainer continues to feel that
-providing those features is inadvisable,
-nevertheless, on systems that support IEEE floating point, it seems
-reasonable to provide @emph{some} way to support NaN and Infinity values.
-The solution implemented in @command{gawk} is as follows:
-
-@itemize @bullet
-@item
-With the @option{--posix} command-line option, @command{gawk} becomes
-``hands off.'' String values are passed directly to the system library's
-@code{strtod()} function, and if it successfully returns a numeric value,
-that is what's used.@footnote{You asked for it, you got it.}
-By definition, the results are not portable across
-different systems. They are also a little surprising:
-
-@example
-$ @kbd{echo nanny | gawk --posix '@{ print $1 + 0 @}'}
-@print{} nan
-$ @kbd{echo 0xDeadBeef | gawk --posix '@{ print $1 + 0 @}'}
-@print{} 3735928559
-@end example
-
-@item
-Without @option{--posix}, @command{gawk} interprets the four strings
-@samp{+inf},
-@samp{-inf},
-@samp{+nan},
-and
-@samp{-nan}
-specially, producing the corresponding special numeric values.
-The leading sign acts a signal to @command{gawk} (and the user)
-that the value is really numeric. Hexadecimal floating point is
-not supported (unless you also use @option{--non-decimal-data},
-which is @emph{not} recommended). For example:
-
-@example
-$ @kbd{echo nanny | gawk '@{ print $1 + 0 @}'}
-@print{} 0
-$ @kbd{echo +nan | gawk '@{ print $1 + 0 @}'}
-@print{} nan
-$ @kbd{echo 0xDeadBeef | gawk '@{ print $1 + 0 @}'}
-@print{} 0
-@end example
-
-@command{gawk} does ignore case in the four special values.
-Thus @samp{+nan} and @samp{+NaN} are the same.
-@end itemize
-
-@c ENDOFRANGE procon
@node Glossary
@unnumbered Glossary
@@ -30418,9 +39762,16 @@ Thus @samp{+nan} and @samp{+NaN} are the same.
@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.
+rule's action. Actions are always enclosed in braces.
(@xref{Action Overview}.)
+@cindex Ada programming language
+@cindex programming languages, Ada
+@item Ada
+A programming language originally defined by the U.S.@: Department of
+Defense for embedded programming. It was designed to enforce good
+Software Engineering practices.
+
@cindex Spencer, Henry
@cindex @command{sed} utility
@cindex amazing @command{awk} assembler (@command{aaa})
@@ -30432,13 +39783,6 @@ microcomputers. It is a good example of a program that would have been
better written in another language.
You can get it from @uref{http://awk.info/?awk100/aaa}.
-@cindex Ada programming language
-@cindex Programming languages, Ada
-@item Ada
-A programming language originally defined by the U.S.@: Department of
-Defense for embedded programming. It was designed to enforce good
-Software Engineering practices.
-
@cindex amazingly workable formatter (@command{awf})
@cindex @command{awf} (amazingly workable formatter) program
@item Amazingly Workable Formatter (@command{awf})
@@ -30501,9 +39845,6 @@ The GNU version of the standard 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
@@ -30526,10 +39867,15 @@ 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.
+originally written by Steven R.@: Bourne at Bell Laboratories.
Many shells (Bash, @command{ksh}, @command{pdksh}, @command{zsh}) are
generally upwardly compatible with the Bourne shell.
+@item Braces
+The characters @samp{@{} and @samp{@}}. Braces are used in
+@command{awk} for delimiting actions, compound statements, and function
+bodies.
+
@item Built-in Function
The @command{awk} language provides built-in functions that perform various
numerical, I/O-related, and string computations. Examples are
@@ -30575,14 +39921,6 @@ 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}
@@ -30606,9 +39944,11 @@ 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).
The @uref{http://www.unicode.org, Unicode character set} is
-becoming increasingly popular and standard, and is particularly
+increasingly popular and standard, and is particularly
widely used on GNU/Linux systems.
+@cindex Kernighan, Brian
+@cindex Bentley, Jon
@cindex @command{chem} utility
@item CHEM
A preprocessor for @command{pic} that reads descriptions of molecules
@@ -30617,8 +39957,12 @@ It was written in @command{awk}
by Brian Kernighan and Jon Bentley, and is available from
@uref{http://netlib.sandia.gov/netlib/typesetting/chem.gz}.
-@item Coprocess
-A subordinate program with which two-way communications is possible.
+@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}.)
@cindex compiled programs
@item Compiler
@@ -30646,17 +39990,56 @@ 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}.)
+@cindex McIlroy, Doug
+@cindex cookie
+@item Cookie
+A peculiar goodie, token, saying or remembrance
+produced by or presented to a program. (With thanks to Professor Doug McIlroy.)
+@ignore
+From: Doug McIlroy <doug@cs.dartmouth.edu>
+Date: Sat, 13 Oct 2012 19:55:25 -0400
+To: arnold@skeeve.com
+Subject: Re: origin of the term "cookie"?
+
+I believe the term "cookie", for a more or less inscrutable
+saying or crumb of information, was injected into Unix
+jargon by Bob Morris, who used the word quite frequently.
+It had no fixed meaning as it now does in browsers.
+
+The word had been around long before it was recognized in
+the 8th edition glossary (earlier editions had no glossary):
+
+cookie a peculiar goodie, token, saying or remembrance
+returned by or presented to a program. [I would say that
+"returned by" would better read "produced by", and assume
+responsibility for the inexactitude.]
+
+Doug McIlroy
+
+From: Doug McIlroy <doug@cs.dartmouth.edu>
+Date: Sun, 14 Oct 2012 10:08:43 -0400
+To: arnold@skeeve.com
+Subject: Re: origin of the term "cookie"?
+
+> Can I forward your email to Eric Raymond, for possible addition to the
+> Jargon File?
+
+Sure. I might add that I don't know how "cookie" entered Morris's
+vocabulary. Certainly "values of beta give rise to dom!" (see google)
+was an early, if not the earliest Unix cookie. The fact that it was
+found lying around on a model 37 teletype (which had Greek beta in
+its type box) suggests that maybe it was seen to be like milk and
+cookies laid out for Santa Claus. Morris was wont to make such
+connections.
+
+Doug
+@end ignore
+
+@item Coprocess
+A subordinate program with which two-way communications is possible.
@item Curly Braces
-The characters @samp{@{} and @samp{@}}. Curly braces are used in
-@command{awk} for delimiting actions, compound statements, and function
-bodies.
+See ``Braces.''
@cindex dark corner
@item Dark Corner
@@ -30700,15 +40083,15 @@ 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 Empty String
+See ``Null String.''
+
@item Environment
-A collection of strings, of the form @var{name@code{=}val}, that each
+A collection of strings, of the form @samp{@var{name}=@var{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.
@@ -30735,11 +40118,11 @@ 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
+change by setting the predefined 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.
If you wish to specify the contents of fields instead of the field
-separator, you can use the built-in variable @code{FPAT} to do so.
+separator, you can use the predefined variable @code{FPAT} to do so.
(@xref{Field Separators},
@ref{Constant Size},
and
@@ -30755,25 +40138,16 @@ 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
+Format strings control the appearance of output in the
+@code{strftime()} and @code{sprintf()} functions, and in the
@code{printf} statement as well. Also, data conversions from numbers to strings
-are controlled by the format strings contained in the built-in variables
+are controlled by the format strings contained in the predefined variables
@code{CONVFMT} and @code{OFMT}. (@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
@@ -30783,6 +40157,15 @@ 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 FSF
+See ``Free Software Foundation.''
+
+@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 @command{gawk}
The GNU implementation of @command{awk}.
@@ -30825,7 +40208,7 @@ 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).
+to indicate their base. Thus, @code{0x12} is 18 ((1 x 16) + 2).
@xref{Nondecimal-numbers}.
@item I/O
@@ -30859,15 +40242,18 @@ in @command{awk} programs.
@cindex ISO
@item ISO
-The International Standards Organization.
+The International Organization for Standardization.
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.
+See @uref{http://www.iso.org/iso/home/about.htm, the ISO website} for more
+information about the name of the organization and its language-independent
+three-letter acronym.
@cindex Java programming language
-@cindex Programming languages, Java
+@cindex programming languages, Java
@item Java
A modern programming language originally developed by Sun Microsystems
(now Oracle) supporting Object-Oriented programming. Although usually
@@ -30896,8 +40282,8 @@ meaning. Keywords are reserved and may not be used as variable names.
@code{function},
@code{func},
@code{if},
-@code{nextfile},
@code{next},
+@code{nextfile},
@code{switch},
and
@code{while}.
@@ -30910,12 +40296,12 @@ 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 Linux
+See ``GNU/Linux.''
+
@item Localization
The process of providing the data necessary for an
internationalized program to work in a particular language.
@@ -30958,14 +40344,9 @@ Ancient @command{awk} implementations used 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).
+to indicate their base. Thus, @code{013} is 11 ((1 x 8) + 3).
@xref{Nondecimal-numbers}.
-@cindex P1003.1 POSIX standard
-@cindex P1003.2 POSIX standard
-@item P1003.1, P1003.2
-See ``POSIX.''
-
@item Pattern
Patterns tell @command{awk} which input records are interesting to which
rules.
@@ -30975,9 +40356,13 @@ 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 PEBKAC
+An acronym describing what is possibly the most frequent
+source of computer usage problems. (Problem Exists Between
+Keyboard And Chair.)
+
@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
@@ -31002,8 +40387,8 @@ specify single lines. (@xref{Pattern Overview}.)
@item Recursion
When a function calls itself, either directly or indirectly.
-As long as this is not clear, refer to the entry for ``recursion.''
If this is clear, stop, and proceed to the next entry.
+Otherwise, refer to the entry for ``recursion.''
@item Redirection
Redirection means performing input from something other than the standard input
@@ -31054,12 +40439,12 @@ Regular variables are scalars; arrays and functions are not.
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 Seed
+The initial value, or starting point, for a sequence of random numbers.
+
@item Shell
The command interpreter for Unix and POSIX-compliant systems.
The shell works both interactively, and as a programming language
@@ -31082,7 +40467,7 @@ expressions, and function calls have side effects.
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
+This is the type used by some ancient versions of @command{awk} to store
numeric values. It is the C type @code{float}.
@item Space
@@ -31119,7 +40504,7 @@ into the local language.
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.''
+See also ``Epoch,'' ``GMT,'' and ``UTC.''
@cindex Linux
@cindex GNU/Linux
@@ -31148,13 +40533,20 @@ A sequence of space, TAB, or newline characters occurring inside an input
record or a string.
@end table
+@end ifclear
+
@c The GNU General Public License.
@node Copying
@unnumbered GNU General Public License
+@ifnotdocbook
@center Version 3, 29 June 2007
+@end ifnotdocbook
+@docbook
+<subtitle>Version 3, 29 June 2007</subtitle>
+@end docbook
@c This file is intended to be included within another document,
-@c hence no sectioning command or @node.
+@c hence no sectioning command or @node.
@display
Copyright @copyright{} 2007 Free Software Foundation, Inc. @url{http://fsf.org/}
@@ -31376,7 +40768,7 @@ terms of section 4, provided that you also meet all of these
conditions:
@enumerate a
-@item
+@item
The work must carry prominent notices stating that you modified it,
and giving a relevant date.
@@ -31826,7 +41218,7 @@ state 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 a brief idea of what it does.}
+@var{one line to give the program's name and a brief 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
@@ -31849,7 +41241,7 @@ If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
@smallexample
-@var{program} Copyright (C) @var{year} @var{name of author}
+@var{program} Copyright (C) @var{year} @var{name of author}
This program comes with ABSOLUTELY NO WARRANTY; for details type @samp{show w}.
This is free software, and you are welcome to redistribute it
under certain conditions; type @samp{show c} for details.
@@ -31872,14 +41264,21 @@ applications with the library. If this is what you want to do, use
the GNU Lesser General Public License instead of this License. But
first, please read @url{http://www.gnu.org/philosophy/why-not-lgpl.html}.
-
+@ifclear FOR_PRINT
@c The GNU Free Documentation License.
@node GNU Free Documentation License
@unnumbered GNU Free Documentation License
+@ifnotdocbook
+@center Version 1.3, 3 November 2008
+@end ifnotdocbook
+
+@docbook
+<subtitle>Version 1.3, 3 November 2008</subtitle>
+@end docbook
+
@cindex FDL (Free Documentation License)
@cindex Free Documentation License (FDL)
@cindex GNU Free Documentation License
-@center Version 1.3, 3 November 2008
@c This file is intended to be included within another document,
@c hence no sectioning command or @node.
@@ -32380,12 +41779,12 @@ 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:
+@end ifclear
+@ifnotdocbook
@node Index
@unnumbered Index
+@end ifnotdocbook
@printindex cp
@bye
@@ -32398,9 +41797,6 @@ Unresolved Issues:
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
@@ -32424,16 +41820,18 @@ Consistency issues:
Use --foo, not -Wfoo when describing long options
Use "Bell Laboratories", but not "Bell Labs".
Use "behavior" instead of "behaviour".
+ Use "coprocess" instead of "co-process".
Use "zeros" instead of "zeroes".
Use "nonzero" not "non-zero".
Use "runtime" not "run time" or "run-time".
- Use "command-line" not "command line".
+ Use "command-line" as an adjective and "command line" as a noun.
Use "online" not "on-line".
Use "whitespace" not "white space".
Use "Input/Output", not "input/output". Also "I/O", not "i/o".
Use "lefthand"/"righthand", not "left-hand"/"right-hand".
Use "workaround", not "work-around".
Use "startup"/"cleanup", not "start-up"/"clean-up"
+ Use "filesystem", not "file system"
Use @code{do}, and not @code{do}-@code{while}, except where
actually discussing the do-while.
Use "versus" in text and "vs." in index entries
@@ -32448,8 +41846,6 @@ Consistency issues:
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.
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
@@ -32473,6 +41869,7 @@ Consistency issues:
Use MS-Windows not MS Windows
Use MS-DOS not MS-DOS
Use an empty set of parentheses after built-in and awk function names.
+ Use "multiFOO" without a hyphen.
Date: Wed, 13 Apr 94 15:20:52 -0400
From: rms@gnu.org (Richard Stallman)
@@ -32495,14 +41892,37 @@ 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?
+Better sidebars can almost sort of be done with:
+
+ @ifdocbook
+ @macro @sidebar{title, content}
+ @inlinefmt{docbook, <sidebar><title>}
+ \title\
+ @inlinefmt{docbook, </title>}
+ \content\
+ @inlinefmt{docbook, </sidebar>}
+ @end macro
+ @end ifdocbook
+
+
+ @ifnotdocbook
+ @macro @sidebar{title, content}
+ @cartouche
+ @center @b{\title\}
+
+ \content\
+ @end cartouche
+ @end macro
+ @end ifnotdocbook
+
+But to use it you have to say
+
+ @sidebar{Title Here,
+ @include file-with-content
+ }
+
+which sorta sucks.
-% 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
+TODO:
+Check that all dark corners are indexed properly.
diff --git a/doc/gawkinet.info b/doc/gawkinet.info
index 0a0d69d8..d726be0b 100644
--- a/doc/gawkinet.info
+++ b/doc/gawkinet.info
@@ -6,7 +6,7 @@ START-INFO-DIR-ENTRY
* Gawkinet: (gawkinet). TCP/IP Internetworking With `gawk'.
END-INFO-DIR-ENTRY
- This is Edition 1.3 of `TCP/IP Internetworking With `gawk'', for the
+ This is Edition 1.3 of `TCP/IP Internetworking with `gawk'', for the
4.0.0 (or later) version of the GNU implementation of AWK.
@@ -30,7 +30,7 @@ texts being (a) (see below), and with the Back-Cover Texts being (b)
This file documents the networking features in GNU `awk'.
- This is Edition 1.3 of `TCP/IP Internetworking With `gawk'', for the
+ This is Edition 1.3 of `TCP/IP Internetworking with `gawk'', for the
4.0.0 (or later) version of the GNU implementation of AWK.
@@ -61,7 +61,7 @@ General Introduction
This file documents the networking features in GNU Awk (`gawk') version
4.0 and later.
- This is Edition 1.3 of `TCP/IP Internetworking With `gawk'', for the
+ This is Edition 1.3 of `TCP/IP Internetworking with `gawk'', for the
4.0.0 (or later) version of the GNU implementation of AWK.
diff --git a/doc/gawkinet.texi b/doc/gawkinet.texi
index eb0f2d81..10223239 100644
--- a/doc/gawkinet.texi
+++ b/doc/gawkinet.texi
@@ -60,7 +60,7 @@
@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 TITLE TCP/IP Internetworking with @command{gawk}
@set EDITION 1.3
@set UPDATE-MONTH December, 2010
@c gawk versions:
@@ -597,7 +597,7 @@ 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 input/output, two-way, See Also @command{gawk}@comma{} 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
@@ -1144,9 +1144,9 @@ or the application cannot tolerate virtual circuit overhead.
@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
+@cindex networks, @command{gawk} and, service@comma{} establishing
@c last comma is part of tertiary
-@cindex @command{gawk}, networking, service, establishing
+@cindex @command{gawk}, networking, service@comma{} 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.
diff --git a/doc/gawktexi.in b/doc/gawktexi.in
new file mode 100644
index 00000000..34c47270
--- /dev/null
+++ b/doc/gawktexi.in
@@ -0,0 +1,41021 @@
+\input texinfo @c -*-texinfo-*-
+@c vim: filetype=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
+
+@ifset FOR_PRINT
+@tex
+\gdef\xrefprintnodename#1{``#1''}
+@end tex
+@end ifset
+
+@ifclear FOR_PRINT
+@c With early 2014 texinfo.tex, restore PDF links and colors
+@tex
+\gdef\linkcolor{0.5 0.09 0.12} % Dark Red
+\gdef\urlcolor{0.5 0.09 0.12} % Also
+\global\urefurlonlylinktrue
+@end tex
+@end ifclear
+
+@ifnotdocbook
+@set BULLET @bullet{}
+@set MINUS @minus{}
+@end ifnotdocbook
+
+@ifdocbook
+@set BULLET
+@set MINUS
+@end ifdocbook
+
+@set xref-automatic-section-title
+
+@c The following information should be updated here only!
+@c This sets the edition of the document, the version of gawk it
+@c applies to and all the info about who's publishing this edition
+
+@c These apply across the board.
+@set UPDATE-MONTH September, 2014
+@set VERSION 4.1
+@set PATCHLEVEL 2
+
+@ifset FOR_PRINT
+@set TITLE Effective awk Programming
+@end ifset
+@ifclear FOR_PRINT
+@set TITLE GAWK: Effective AWK Programming
+@end ifclear
+@set SUBTITLE A User's Guide for GNU Awk
+@set EDITION 4.1
+
+@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}}
+@set COMMONEXT (c.e.)
+@set PAGE page
+@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.)
+@set COMMONEXT (c.e.)
+@set PAGE screen
+@end ifinfo
+@ifhtml
+@set DOCUMENT Web page
+@set CHAPTER chapter
+@set APPENDIX appendix
+@set SECTION section
+@set SUBSECTION subsection
+@set DARKCORNER (d.c.)
+@set COMMONEXT (c.e.)
+@set PAGE screen
+@end ifhtml
+@ifdocbook
+@set DOCUMENT book
+@set CHAPTER chapter
+@set APPENDIX appendix
+@set SECTION section
+@set SUBSECTION subsection
+@set DARKCORNER (d.c.)
+@set COMMONEXT (c.e.)
+@set PAGE page
+@end ifdocbook
+@ifxml
+@set DOCUMENT book
+@set CHAPTER chapter
+@set APPENDIX appendix
+@set SECTION section
+@set SUBSECTION subsection
+@set DARKCORNER (d.c.)
+@set COMMONEXT (c.e.)
+@set PAGE page
+@end ifxml
+@ifplaintext
+@set DOCUMENT book
+@set CHAPTER chapter
+@set APPENDIX appendix
+@set SECTION section
+@set SUBSECTION subsection
+@set DARKCORNER (d.c.)
+@set COMMONEXT (c.e.)
+@set PAGE page
+@end ifplaintext
+
+@ifdocbook
+@c empty on purpose
+@set PART1
+@set PART2
+@set PART3
+@set PART4
+@end ifdocbook
+
+@ifnotdocbook
+@set PART1 Part I:@*
+@set PART2 Part II:@*
+@set PART3 Part III:@*
+@set PART4 Part IV:@*
+@end ifnotdocbook
+
+@c some special symbols
+@iftex
+@set LEQ @math{@leq}
+@set PI @math{@pi}
+@end iftex
+@ifdocbook
+@set LEQ @inlineraw{docbook, &le;}
+@set PI @inlineraw{docbook, &pgr;}
+@end ifdocbook
+@ifnottex
+@ifnotdocbook
+@set LEQ <=
+@set PI @i{pi}
+@end ifnotdocbook
+@end ifnottex
+
+@ifnottex
+@ifnotdocbook
+@macro ii{text}
+@i{\text\}
+@end macro
+@end ifnotdocbook
+@end ifnottex
+
+@ifdocbook
+@macro ii{text}
+@inlineraw{docbook,<lineannotation>\text\</lineannotation>}
+@end macro
+@end ifdocbook
+
+@c hack for docbook, where comma shouldn't always follow an @ref{}
+@ifdocbook
+@macro DBREF{text}
+@ref{\text\}
+@end macro
+@macro DBXREF{text}
+@xref{\text\}
+@end macro
+@macro DBPXREF{text}
+@pxref{\text\}
+@end macro
+@end ifdocbook
+
+@ifnotdocbook
+@macro DBREF{text}
+@ref{\text\},
+@end macro
+@macro DBXREF{text}
+@xref{\text\},
+@end macro
+@macro DBPXREF{text}
+@pxref{\text\},
+@end macro
+@end ifnotdocbook
+
+@ifclear FOR_PRINT
+@set FN file name
+@set FFN File Name
+@set DF data file
+@set DDF Data File
+@set PVERSION version
+@end ifclear
+@ifset FOR_PRINT
+@set FN filename
+@set FFN Filename
+@set DF datafile
+@set DDF Datafile
+@set PVERSION version
+@end ifset
+
+@c For HTML, spell out email addresses, to avoid problems with
+@c address harvesters for spammers.
+@ifhtml
+@macro EMAIL{real,spelled}
+``\spelled\''
+@end macro
+@end ifhtml
+@ifnothtml
+@macro EMAIL{real,spelled}
+@email{\real\}
+@end macro
+@end ifnothtml
+
+@c Indexing macros
+@ifinfo
+
+@macro cindexawkfunc{name}
+@cindex @code{\name\}
+@end macro
+
+@macro cindexgawkfunc{name}
+@cindex @code{\name\}
+@end macro
+
+@end ifinfo
+
+@ifnotinfo
+
+@macro cindexawkfunc{name}
+@cindex @code{\name\()} function
+@end macro
+
+@macro cindexgawkfunc{name}
+@cindex @code{\name\()} function (@command{gawk})
+@end macro
+@end ifnotinfo
+
+@ignore
+Some comments on the layout for TeX.
+1. Use at least texinfo.tex 2014-01-30.15
+2. When using @docbook, if the last line is part of a paragraph, end
+it with a space and @c so that the lines won't run together. This is a
+quirk of the language / makeinfo, and isn't going to change.
+@end ignore
+
+@c merge the function and variable indexes into the concept index
+@ifinfo
+@synindex fn cp
+@synindex vr cp
+@end ifinfo
+@iftex
+@syncodeindex fn cp
+@syncodeindex vr cp
+@end iftex
+@ifxml
+@syncodeindex fn cp
+@syncodeindex vr cp
+@end ifxml
+@ifdocbook
+@synindex fn cp
+@synindex vr cp
+@end ifdocbook
+
+@c If "finalout" is commented out, the printed output will show
+@c black boxes that mark lines that are too long. Thus, it is
+@c unwise to comment it out when running a master in case there are
+@c overfulls which are deemed okay.
+
+@iftex
+@finalout
+@end iftex
+
+@copying
+@docbook
+<para>
+&ldquo;To boldly go where no man has gone before&rdquo; is a
+Registered Trademark of Paramount Pictures Corporation.</para>
+
+<para>Published by:</para>
+
+<literallayout class="normal">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</email>
+URL: <ulink url="http://www.gnu.org">http://www.gnu.org/</ulink></literallayout>
+
+<literallayout class="normal">Copyright &copy; 1989, 1991, 1992, 1993, 1996&ndash;2005, 2007, 2009&ndash;2014
+Free Software Foundation, Inc.
+All Rights Reserved.</literallayout>
+@end docbook
+
+@ifnotdocbook
+Copyright @copyright{} 1989, 1991, 1992, 1993, 1996--2005, 2007, 2009--2015 @*
+Free Software Foundation, Inc.
+@end ifnotdocbook
+@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.3 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being ``GNU General Public License'', with the
+Front-Cover Texts being ``A GNU Manual'', and with the Back-Cover Texts
+as in (a) below.
+@ifclear FOR_PRINT
+A copy of the license is included in the section entitled
+``GNU Free Documentation License''.
+@end ifclear
+@ifset FOR_PRINT
+A copy of the license
+may be found on the Internet at
+@uref{http://www.gnu.org/software/gawk/manual/html_node/GNU-Free-Documentation-License.html,
+the GNU Project's website}.
+@end ifset
+
+@enumerate a
+@item
+The FSF's Back-Cover Text is: ``You have the freedom to
+copy and modify this GNU manual.''
+@end enumerate
+@end copying
+
+@c Comment out the "smallbook" for technical review. Saves
+@c considerable paper. Remember to turn it back on *before*
+@c starting the page-breaking work.
+
+@c 4/2002: Karl Berry recommends commenting out this and the
+@c `@setchapternewpage odd', and letting users use `texi2dvi -t'
+@c if they want to waste paper.
+@c @smallbook
+
+
+@c Uncomment this for the release. Leaving it off saves paper
+@c during editing and review.
+@setchapternewpage odd
+
+@shorttitlepage GNU Awk
+@titlepage
+@title @value{TITLE}
+@subtitle @value{SUBTITLE}
+@subtitle Edition @value{EDITION}
+@subtitle @value{UPDATE-MONTH}
+@author Arnold D. Robbins
+
+@ifnotdocbook
+@c Include the Distribution inside the titlepage environment so
+@c that headings are turned off. Headings on and off do not work.
+
+@page
+@vskip 0pt plus 1filll
+``To boldly go where no man has gone before'' 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
+@end ifnotdocbook
+@end titlepage
+
+@c Thanks to Bob Chassell for directions on doing dedications.
+@iftex
+@headings off
+@page
+@w{ }
+@sp 9
+@center @i{To my parents, for their love, and for the wonderful example they set for me.}
+@sp 1
+@center @i{To my wife, Miriam, for making me complete.
+Thank you for building your life together with me.}
+@sp 1
+@center @i{To our children, Chana, Rivka, Nachum, and Malka, for enrichening our lives in innumerable ways.}
+@sp 1
+@w{ }
+@page
+@w{ }
+@page
+@headings on
+@end iftex
+
+@docbook
+<dedication>
+<para>To my parents, for their love, and for the wonderful
+example they set for me.</para>
+<para>To my wife Miriam, for making me complete.
+Thank you for building your life together with me.</para>
+<para>To our children Chana, Rivka, Nachum and Malka,
+for enrichening our lives in innumerable ways.</para>
+</dedication>
+@end docbook
+
+@iftex
+@headings off
+@evenheading @thispage@ @ @ @strong{@value{TITLE}} @| @|
+@oddheading @| @| @strong{@thischapter}@ @ @ @thispage
+@end iftex
+
+@ifnottex
+@ifnotxml
+@ifnotdocbook
+@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 ifnotdocbook
+@end ifnotxml
+@end ifnottex
+
+@menu
+* Foreword3:: Some nice words about this
+ @value{DOCUMENT}.
+* Foreword4:: More nice words.
+* 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.
+* Invoking Gawk:: How to run @command{gawk}.
+* 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.
+* Library Functions:: A Library of @command{awk} Functions.
+* Sample Programs:: Many @command{awk} programs with complete
+ explanations.
+* Advanced Features:: Stuff for advanced users, specific to
+ @command{gawk}.
+* Internationalization:: Getting @command{gawk} to speak your
+ language.
+* Debugger:: The @code{gawk} debugger.
+* Arbitrary Precision Arithmetic:: Arbitrary precision arithmetic with
+ @command{gawk}.
+* Dynamic Extensions:: Adding new built-in functions to
+ @command{gawk}.
+* Language History:: The evolution of the @command{awk}
+ language.
+* Installation:: Installing @command{gawk} under various
+ operating systems.
+* Notes:: Notes about adding things to @command{gawk}
+ and possible future work.
+* Basic Concepts:: A very quick introduction 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 the
+ keyboard 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.
+* DOS Quoting:: Quoting in Windows Batch Files.
+* 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.
+* Intro Summary:: Summary of the introduction.
+* Command Line:: How to run @command{awk}.
+* Options:: Command-line options and their
+ meanings.
+* Other Arguments:: Input file names and variable
+ assignments.
+* Naming Standard Input:: How to specify standard input with
+ other files.
+* Environment Variables:: The environment variables
+ @command{gawk} uses.
+* AWKPATH Variable:: Searching directories for
+ @command{awk} programs.
+* AWKLIBPATH Variable:: Searching directories for
+ @command{awk} shared libraries.
+* Other Environment Variables:: The environment variables.
+* Exit Status:: @command{gawk}'s exit status.
+* Include Files:: Including other files into your
+ program.
+* Loading Shared Libraries:: Loading shared libraries into your
+ program.
+* Obsolete:: Obsolete Options and/or features.
+* Undocumented:: Undocumented Options and Features.
+* Invoking Summary:: Invocation summary.
+* Regexp Usage:: How to Use Regular Expressions.
+* Escape Sequences:: How to write nonprinting characters.
+* Regexp Operators:: Regular Expression Operators.
+* Bracket Expressions:: What can go between @samp{[...]}.
+* Leftmost Longest:: How much text matches.
+* Computed Regexps:: Using Dynamic Regexps.
+* GNU Regexp Operators:: Operators specific to GNU software.
+* Case-sensitivity:: How to do case-insensitive matching.
+* Regexp Summary:: Regular expressions summary.
+* Records:: Controlling how data is split into
+ records.
+* awk split records:: How standard @command{awk} splits
+ records.
+* gawk split records:: How @command{gawk} splits 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.
+* Default Field Splitting:: How fields are normally separated.
+* 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.
+* Full Line Fields:: Making the full line be a single
+ field.
+* Field Splitting Summary:: Some final points and a summary table.
+* Constant Size:: Reading constant width data.
+* Splitting By Content:: Defining Fields By Content
+* Multiple Line:: Reading multiline 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.
+* Read Timeout:: Reading input with a timeout.
+* Command-line directories:: What happens if you put a directory on
+ the command line.
+* Input Summary:: Input summary.
+* Input Exercises:: Exercises.
+* 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 FD:: Special files for I/O.
+* Special Files:: File name interpretation in
+ @command{gawk}. @command{gawk} allows
+ access to inherited file descriptors.
+* Other Inherited Files:: Accessing other open files with
+ @command{gawk}.
+* 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.
+* Output Summary:: Output summary.
+* Output Exercises:: Exercises.
+* Values:: Constants, Variables, and Regular
+ Expressions.
+* 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.
+* Strings And Numbers:: How @command{awk} Converts Between
+ Strings And Numbers.
+* Locale influences conversions:: How the locale may affect conversions.
+* All Operators:: @command{gawk}'s operators.
+* 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 and Conditions:: Testing for true and false.
+* 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.
+* Variable Typing:: String type versus numeric type.
+* Comparison Operators:: The comparison operators.
+* POSIX String Comparison:: String comparison with POSIX rules.
+* 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.
+* Locales:: How the locale affects things.
+* Expressions Summary:: Expressions summary.
+* 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.
+* BEGINFILE/ENDFILE:: Two special patterns for advanced
+ control.
+* 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 predefined 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}.
+* Pattern Action Summary:: Patterns and Actions summary.
+* Array Basics:: The basics of arrays.
+* 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.
+* Controlling Scanning:: Controlling the order in which arrays
+ are scanned.
+* Numeric Array Subscripts:: How to use numbers as subscripts in
+ @command{awk}.
+* Uninitialized Subscripts:: Using Uninitialized variables as
+ subscripts.
+* Delete:: The @code{delete} statement removes an
+ element from an array.
+* Multidimensional:: Emulating multidimensional arrays in
+ @command{awk}.
+* Multiscanning:: Scanning multidimensional arrays.
+* Arrays of Arrays:: True multidimensional arrays.
+* Arrays Summary:: Summary of arrays.
+* 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.
+* Type Functions:: Functions for type information.
+* 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.
+* Calling A Function:: Don't use spaces.
+* Variable Scope:: Controlling variable scope.
+* Pass By Value/Reference:: Passing parameters.
+* Return Statement:: Specifying the value a function
+ returns.
+* Dynamic Typing:: How variable types can change at
+ runtime.
+* Indirect Calls:: Choosing the function to call at
+ runtime.
+* Functions Summary:: Summary of functions.
+* Library Names:: How to best name private global
+ variables in library functions.
+* General Functions:: Functions that are of general use.
+* 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.
+* Getlocaltime Function:: A function to get formatted times.
+* Readfile Function:: A function to read an entire file at
+ once.
+* Shell Quoting:: A function to quote strings for the
+ shell.
+* 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.
+* Walking Arrays:: A function to walk arrays of arrays.
+* Library Functions Summary:: Summary of library functions.
+* Library Exercises:: Exercises.
+* 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.
+* Anagram Program:: Finding anagrams from a dictionary.
+* Signature Program:: People do amazing things with too much
+ time on their hands.
+* Programs Summary:: Summary of programs.
+* Programs Exercises:: Exercises.
+* Nondecimal Data:: Allowing nondecimal input data.
+* Array Sorting:: Facilities for controlling array
+ traversal and sorting arrays.
+* Controlling Array Traversal:: How to use PROCINFO["sorted_in"].
+* Array Sorting Functions:: How to use @code{asort()} and
+ @code{asorti()}.
+* Two-way I/O:: Two-way communications with another
+ process.
+* TCP/IP Networking:: Using @command{gawk} for network
+ programming.
+* Profiling:: Profiling your @command{awk} programs.
+* Advanced Features Summary:: Summary of advanced features.
+* I18N and L10N:: Internationalization and Localization.
+* Explaining gettext:: How GNU @command{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.
+* I18N Summary:: Summary of I18N stuff.
+* Debugging:: Introduction to @command{gawk}
+ debugger.
+* Debugging Concepts:: Debugging in General.
+* Debugging Terms:: Additional Debugging Concepts.
+* Awk Debugging:: Awk Debugging.
+* Sample Debugging Session:: Sample debugging session.
+* Debugger Invocation:: How to Start the Debugger.
+* Finding The Bug:: Finding the Bug.
+* List of Debugger Commands:: Main debugger commands.
+* Breakpoint Control:: Control of Breakpoints.
+* Debugger Execution Control:: Control of Execution.
+* Viewing And Changing Data:: Viewing and Changing Data.
+* Execution Stack:: Dealing with the Stack.
+* Debugger Info:: Obtaining Information about the
+ Program and the Debugger State.
+* Miscellaneous Debugger Commands:: Miscellaneous Commands.
+* Readline Support:: Readline support.
+* Limitations:: Limitations and future plans.
+* Debugging Summary:: Debugging summary.
+* Computer Arithmetic:: A quick intro to computer math.
+* Math Definitions:: Defining terms used.
+* MPFR features:: The MPFR features in @command{gawk}.
+* FP Math Caution:: Things to know.
+* Inexactness of computations:: Floating point math is not exact.
+* Inexact representation:: Numbers are not exactly represented.
+* Comparing FP Values:: How to compare floating point values.
+* Errors accumulate:: Errors get bigger as they go.
+* Getting Accuracy:: Getting more accuracy takes some work.
+* Try To Round:: Add digits and round.
+* Setting precision:: How to set the precision.
+* Setting the rounding mode:: How to set the rounding mode.
+* Arbitrary Precision Integers:: Arbitrary Precision Integer Arithmetic
+ with @command{gawk}.
+* POSIX Floating Point Problems:: Standards Versus Existing Practice.
+* Floating point summary:: Summary of floating point discussion.
+* Extension Intro:: What is an extension.
+* Plugin License:: A note about licensing.
+* Extension Mechanism Outline:: An outline of how it works.
+* Extension API Description:: A full description of the API.
+* Extension API Functions Introduction:: Introduction to the API functions.
+* General Data Types:: The data types.
+* Memory Allocation Functions:: Functions for allocating memory.
+* Constructor Functions:: Functions for creating values.
+* Registration Functions:: Functions to register things with
+ @command{gawk}.
+* Extension Functions:: Registering extension functions.
+* Exit Callback Functions:: Registering an exit callback.
+* Extension Version String:: Registering a version string.
+* Input Parsers:: Registering an input parser.
+* Output Wrappers:: Registering an output wrapper.
+* Two-way processors:: Registering a two-way processor.
+* Printing Messages:: Functions for printing messages.
+* Updating @code{ERRNO}:: Functions for updating @code{ERRNO}.
+* Requesting Values:: How to get a value.
+* Accessing Parameters:: Functions for accessing parameters.
+* Symbol Table Access:: Functions for accessing global
+ variables.
+* Symbol table by name:: Accessing variables by name.
+* Symbol table by cookie:: Accessing variables by ``cookie''.
+* Cached values:: Creating and using cached values.
+* Array Manipulation:: Functions for working with arrays.
+* Array Data Types:: Data types for working with arrays.
+* Array Functions:: Functions for working with arrays.
+* Flattening Arrays:: How to flatten arrays.
+* Creating Arrays:: How to create and populate arrays.
+* Extension API Variables:: Variables provided by the API.
+* Extension Versioning:: API Version information.
+* Extension API Informational Variables:: Variables providing information about
+ @command{gawk}'s invocation.
+* Extension API Boilerplate:: Boilerplate code for using the API.
+* Finding Extensions:: How @command{gawk} finds compiled
+ extensions.
+* Extension Example:: Example C code for an extension.
+* 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.
+* Extension Samples:: The sample extensions that ship with
+ @code{gawk}.
+* Extension Sample File Functions:: The file functions sample.
+* Extension Sample Fnmatch:: An interface to @code{fnmatch()}.
+* Extension Sample Fork:: An interface to @code{fork()} and
+ other process functions.
+* Extension Sample Inplace:: Enabling in-place file editing.
+* Extension Sample Ord:: Character to value to character
+ conversions.
+* Extension Sample Readdir:: An interface to @code{readdir()}.
+* Extension Sample Revout:: Reversing output sample output
+ wrapper.
+* Extension Sample Rev2way:: Reversing data sample two-way
+ processor.
+* Extension Sample Read write array:: Serializing an array to a file.
+* Extension Sample Readfile:: Reading an entire file into a string.
+* Extension Sample Time:: An interface to @code{gettimeofday()}
+ and @code{sleep()}.
+* Extension Sample API Tests:: Tests for the API.
+* gawkextlib:: The @code{gawkextlib} project.
+* Extension summary:: Extension summary.
+* Extension Exercises:: Exercises.
+* 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 Brian Kernighan's
+ version of @command{awk}.
+* POSIX/GNU:: The extensions in @command{gawk} not
+ in POSIX @command{awk}.
+* Feature History:: The history of the features in
+ @command{gawk}.
+* Common Extensions:: Common Extensions Summary.
+* Ranges and Locales:: How locales used to affect regexp
+ ranges.
+* Contributors:: The major contributors to
+ @command{gawk}.
+* History summary:: History summary.
+* 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.
+* Shell Startup Files:: Shell convenience functions.
+* Additional Configuration Options:: Other compile-time options.
+* Configuration Philosophy:: How it's all supposed to work.
+* Non-Unix Installation:: Installation on Other Operating
+ Systems.
+* 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 Testing:: Testing @command{gawk} on PC systems.
+* PC Using:: Running @command{gawk} on MS-DOS,
+ Windows32 and OS/2.
+* Cygwin:: Building and running @command{gawk}
+ for Cygwin.
+* MSYS:: Using @command{gawk} In The MSYS
+ Environment.
+* VMS Installation:: Installing @command{gawk} on VMS.
+* VMS Compilation:: How to compile @command{gawk} under
+ VMS.
+* VMS Dynamic Extensions:: Compiling @command{gawk} dynamic
+ extensions on VMS.
+* VMS Installation Details:: How to install @command{gawk} under
+ VMS.
+* VMS Running:: How to run @command{gawk} under VMS.
+* VMS GNV:: The VMS GNV Project.
+* VMS Old Gawk:: An old version comes with some VMS
+ systems.
+* Bugs:: Reporting Problems and Bugs.
+* Other Versions:: Other freely available @command{awk}
+ implementations.
+* Installation summary:: Summary of installation.
+* Compatibility Mode:: How to disable certain @command{gawk}
+ extensions.
+* Additions:: Making Additions To @command{gawk}.
+* Accessing The Source:: Accessing the Git repository.
+* Adding Code:: Adding code to the main body of
+ @command{gawk}.
+* New Ports:: Porting @command{gawk} to a new
+ operating system.
+* Derived Files:: Why derived files are kept in the Git
+ repository.
+* Future Extensions:: New features that may be implemented
+ one day.
+* Implementation Limitations:: Some limitations of the
+ implementation.
+* Extension Design:: Design notes about the extension API.
+* Old Extension Problems:: Problems with the old mechanism.
+* Extension New Mechanism Goals:: Goals for the new mechanism.
+* Extension Other Design Decisions:: Some other design decisions.
+* Extension Future Growth:: Some room for future growth.
+* Old Extension Mechanism:: Some compatibility for old extensions.
+* Notes summary:: Summary of implementation notes.
+* Basic High Level:: The high level view.
+* Basic Data Typing:: A very quick intro to data types.
+@end detailmenu
+@end menu
+
+@c dedication for Info file
+@ifinfo
+To my parents, for their love, and for the wonderful
+example they set for me.
+@sp 1
+To my wife Miriam, for making me complete.
+Thank you for building your life together with me.
+@sp 1
+To our children Chana, Rivka, Nachum and Malka,
+for enrichening our lives in innumerable ways.
+@end ifinfo
+
+@summarycontents
+@contents
+
+@node Foreword3
+@unnumbered Foreword to the Third Edition
+
+@c This bit is post-processed by a script which turns the chapter
+@c tag into a preface tag, and moves this stuff to before the title.
+@c Bleah.
+@docbook
+ <prefaceinfo>
+ <author>
+ <firstname>Michael</firstname>
+ <surname>Brennan</surname>
+ <!-- can't put mawk into command tags. sigh. -->
+ <affiliation><jobtitle>Author of mawk</jobtitle></affiliation>
+ </author>
+ <date>March 2001</date>
+ </prefaceinfo>
+@end docbook
+
+Arnold Robbins and I are good friends. We were introduced
+@c 11 years ago
+in 1990
+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.@:
+Alfred V.@: Aho, Brian W.@: Kernighan, and
+Peter J.@: Weinberger's @cite{The AWK Programming Language} (Addison-Wesley,
+1988). @command{awk}'s simple programming paradigm---find a pattern in the
+input and then perform an action---often reduced complex or tedious
+data manipulations to a 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 gray book. I discovered that my computer
+had ``old @command{awk}'' and the 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
+GNU/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 @cite{The AWK Programming Language}.
+
+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 Laboratories 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 prototyping 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
+@ifnotdocbook
+@math{n}
+@end ifnotdocbook
+@ifdocbook
+@i{n}
+@end ifdocbook
+lines of input, exhibited
+@tex
+$\sim\! Cn^2$
+@end tex
+@ifnottex
+@ifnotdocbook
+~ C n^2
+@end ifnotdocbook
+@end ifnottex
+@docbook
+<emphasis>&sim; Cn<superscript>2</superscript></emphasis> @c
+@end docbook
+performance, while
+theory predicted
+@tex
+$\sim\! Cn\log n$
+@end tex
+@ifnottex
+@ifnotdocbook
+~ C n log n
+@end ifnotdocbook
+@end ifnottex
+@docbook
+<emphasis>&sim; Cn log n</emphasis> @c
+@end docbook
+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.
+
+@ifnotdocbook
+@cindex Brennan, Michael
+@display
+Michael Brennan
+Author of @command{mawk}
+March 2001
+@end display
+@end ifnotdocbook
+
+@node Foreword4
+@unnumbered Foreword to the Fourth Edition
+
+@c This bit is post-processed by a script which turns the chapter
+@c tag into a preface tag, and moves this stuff to before the title.
+@c Bleah.
+@docbook
+ <prefaceinfo>
+ <author>
+ <firstname>Michael</firstname>
+ <surname>Brennan</surname>
+ <!-- can't put mawk into command tags. sigh. -->
+ <affiliation><jobtitle>Author of mawk</jobtitle></affiliation>
+ </author>
+ <date>October 2014</date>
+ </prefaceinfo>
+@end docbook
+
+Some things don't change. Thirteen years ago I wrote:
+``If you use AWK or want to learn how, then read this book.''
+True then, and still true today.
+
+Learning to use a programming language is about more than mastering the
+syntax. One needs to acquire an understanding of how to use the
+features of the language to solve practical programming problems.
+A focus of this book is many examples that show how to use AWK.
+
+Some things do change. Our computers are much faster and have more memory.
+Consequently, speed and storage inefficiencies of a high-level language
+matter less. Prototyping in AWK and then rewriting in C for performance
+reasons happens less, because more often the prototype is fast enough.
+
+Of course, there are computing operations that are best done in C or C++.
+With @command{gawk} 4.1 and later, you do not have to choose between writing
+your program in AWK or in C/C++. You can write most of your
+program in AWK and the aspects that require C/C++ capabilities can be written
+in C/C++, and then the pieces glued together when the @command{gawk} module loads
+the C/C++ module as a dynamic plug-in.
+@c Chapter 16
+@ref{Dynamic Extensions},
+has all the
+details, and, as expected, many examples to help you learn the ins and outs.
+
+I enjoy programming in AWK and had fun (re)reading this book.
+I think you will too.
+
+@ifnotdocbook
+@cindex Brennan, Michael
+@display
+Michael Brennan
+Author of @command{mawk}
+October 2014
+@end display
+@end ifnotdocbook
+
+@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.
+
+@c This bit is post-processed by a script which turns the chapter
+@c tag into a preface tag, and moves this stuff to before the title.
+@c Bleah.
+@docbook
+ <prefaceinfo>
+ <author>
+ <firstname>Arnold</firstname>
+ <surname>Robbins</surname>
+ <affiliation><jobtitle>Nof Ayalon</jobtitle></affiliation>
+ <affiliation><jobtitle>Israel</jobtitle></affiliation>
+ </author>
+ <date>December 2014</date>
+ </prefaceinfo>
+@end docbook
+
+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. Such jobs are often easy 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}; if you
+invoke it with the proper options or environment variables,
+it is fully compatible with
+the POSIX@footnote{The 2008 POSIX standard is accessible online at
+@w{@url{http://www.opengroup.org/onlinepubs/9699919799/}.}}
+specification of the @command{awk} language
+and with the Unix version of @command{awk} maintained
+by Brian Kernighan.
+This means that all
+properly written @command{awk} programs should work with @command{gawk}.
+So most of the time, we 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} you can:
+
+@itemize @value{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 @value{BULLET}
+@item
+Extract bits and pieces of data for processing
+
+@item
+Sort data
+
+@item
+Perform simple network communications
+
+@item
+Profile and debug @command{awk} programs
+
+@item
+Extend the language with functions written in C or C++
+@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 utilities
+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 @command{awk}''). @command{gawk} runs on a broad range of Unix systems,
+ranging from Intel-architecture PC-based computers
+up through large-scale systems.
+@command{gawk} has also been ported to Mac OS X,
+Microsoft Windows
+@ifset FOR_PRINT
+(all versions),
+@end ifset
+@ifclear FOR_PRINT
+(all versions) and OS/2 PCs,
+@end ifclear
+and OpenVMS.@footnote{Some other, obsolete systems to which @command{gawk}
+was once ported are no longer supported and the code for those systems
+has been removed.}
+
+@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
+@sidebar 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
+
+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 sidebar
+
+@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 (1987).
+The version in System V Release 4 (1989) 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 @command{awk} designers at Bell Laboratories
+provided feedback for the POSIX specification.
+
+@cindex Rubin, Paul
+@cindex Fenlason, Jay
+@cindex Trueman, David
+Paul Rubin wrote @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 1994, I became the primary maintainer.
+Current development focuses on bug fixes,
+performance improvements, standards compliance, and, occasionally, new features.
+
+In May 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.
+
+John Haque rewrote the @command{gawk} internals, in the process providing
+an @command{awk}-level debugger. This version became available as
+@command{gawk} @value{PVERSION} 4.0 in 2011.
+
+@DBXREF{Contributors}
+for a full list of those who have made important contributions to @command{gawk}.
+
+@node Names
+@unnumberedsec 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}.''
+By analogy, the original version of @command{awk} is
+referred to as ``old @command{awk}.''
+
+Today, on most systems, when you run the @command{awk} utility
+you get some version of new @command{awk}.@footnote{Only
+Solaris systems still use an old @command{awk} for the
+default @command{awk} utility. A more modern @command{awk} lives in
+@file{/usr/xpg6/bin} on these systems.} If your system's standard
+@command{awk} is the old one, you will see something like this
+if you try the test program:
+
+@example
+$ @kbd{awk 1 /dev/null}
+@error{} awk: syntax error near line 1
+@error{} awk: bailing out near line 1
+@end example
+
+@noindent
+In this case, you should find a version of new @command{awk},
+or just install @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
+@unnumberedsec 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 how to write programs in the @command{awk} language and how to
+run the @command{awk} utility.
+The term ``@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}
+@ifclear FOR_PRINT
+implementations.@footnote{All such differences
+appear in the index under the
+entry ``differences in @command{awk} and @command{gawk}.''}
+@end ifclear
+@ifset FOR_PRINT
+implementations.
+@end ifset
+Finally, it notes any @command{gawk} features that are not in
+the POSIX standard for @command{awk}.
+
+@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 Info and
+@uref{http://www.gnu.org/software/gawk/manual/, HTML}
+versions of the @value{DOCUMENT}.
+@end ifnotinfo
+
+There are sidebars
+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.
+@ifclear FOR_PRINT
+All appear in the index, under the heading ``sidebar.''
+@end ifclear
+
+Most of the time, the examples use complete @command{awk} programs.
+Some of the more advanced sections show only the part of the @command{awk}
+program that illustrates the concept being described.
+
+Although 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
+@ifnotdocbook
+in
+@end ifnotdocbook
+@ref{Sample Programs},
+should be of interest.
+
+This @value{DOCUMENT} is split into several parts, as follows:
+
+@c FULLXREF ON
+
+@itemize @value{BULLET}
+@item
+Part I describes the @command{awk} language and the @command{gawk} program in detail.
+It starts with the basics, and continues through all of the features of @command{awk}.
+It contains the following chapters:
+
+@c nested
+@itemize @value{MINUS}
+@item
+@ref{Getting Started},
+provides the essentials you need to know to begin using @command{awk}.
+
+@item
+@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.
+
+@item
+@ref{Regexp},
+introduces regular expressions in general, and in particular the flavors
+supported by POSIX @command{awk} and @command{gawk}.
+
+@item
+@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.
+Network I/O is also briefly introduced here.
+
+@item
+@ref{Printing},
+describes how @command{awk} programs can produce output with
+@code{print} and @code{printf}.
+
+@item
+@ref{Expressions},
+describes expressions, which are the basic building blocks
+for getting most things done in a program.
+
+@item
+@ref{Patterns and Actions},
+describes how to write patterns for matching records, actions for
+doing something when a record is matched, and the predefined variables
+@command{awk} and @command{gawk} use.
+
+@item
+@ref{Arrays},
+covers @command{awk}'s one-and-only data structure: the associative array.
+Deleting array elements and whole arrays is described, as well as
+sorting arrays in @command{gawk}. The @value{CHAPTER} also describes how
+@command{gawk} provides arrays of arrays.
+
+@item
+@ref{Functions},
+describes the built-in functions @command{awk} and @command{gawk} provide,
+as well as how to define your own functions. It also discusses how
+@command{gawk} lets you call functions indirectly.
+@end itemize
+
+@item
+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.
+This part contains the following chapters:
+
+@c nested
+@itemize @value{MINUS}
+@item
+@ref{Library Functions}, provides a number of functions meant to
+be used from main @command{awk} programs.
+
+@item
+@ref{Sample Programs},
+provides many sample @command{awk} programs.
+@end itemize
+
+Reading these two chapters allows you to see @command{awk}
+solving real problems.
+
+@item
+Part III focuses on features specific to @command{gawk}.
+It contains the following chapters:
+
+@c nested
+@itemize @value{MINUS}
+@item
+@ref{Advanced Features},
+describes a number of advanced features.
+Of particular note
+are the abilities to control the order of array traversal,
+have two-way communications with another process,
+perform TCP/IP networking, and
+profile your @command{awk} programs.
+
+@item
+@ref{Internationalization},
+describes special features for translating program
+messages into different languages at runtime.
+
+@item
+@ref{Debugger}, describes the @command{gawk} debugger.
+
+@item
+@ref{Arbitrary Precision Arithmetic},
+describes advanced arithmetic facilities.
+
+@item
+@ref{Dynamic Extensions}, describes how to add new variables and
+functions to @command{gawk} by writing extensions in C or C++.
+@end itemize
+
+@item
+@ifclear FOR_PRINT
+Part IV provides the appendices, the Glossary, and two licenses that cover
+the @command{gawk} source code and this @value{DOCUMENT}, respectively.
+It contains the following appendices:
+@end ifclear
+@ifset FOR_PRINT
+Part IV provides the following appendices,
+including the GNU General Public License:
+@end ifset
+
+@itemize @value{MINUS}
+@item
+@ref{Language History},
+describes how the @command{awk} language has evolved since
+its first release to the present. It also describes how @command{gawk}
+has acquired features over time.
+
+@item
+@ref{Installation},
+describes how to get @command{gawk}, how to compile it
+on POSIX-compatible systems,
+and how to compile and use it on different
+non-POSIX systems. It also describes how to report bugs
+in @command{gawk} and where to get other freely
+available @command{awk} implementations.
+@end itemize
+
+@ifset FOR_PRINT
+@itemize @value{MINUS}
+@item
+@ref{Copying},
+presents the license that covers the @command{gawk} source code.
+@end itemize
+
+The version of this @value{DOCUMENT} distributed with @command{gawk}
+contains additional appendices and other end material.
+To save space, we have omitted them from the
+printed edition. You may find them online, as follows:
+
+@itemize @value{BULLET}
+@item
+@uref{http://www.gnu.org/software/gawk/manual/html_node/Notes.html,
+The appendix on implementation notes}
+describes how to disable @command{gawk}'s extensions, how to contribute
+new code to @command{gawk}, where to find information on some possible
+future directions for @command{gawk} development, and the design decisions
+behind the extension API.
+
+@item
+@uref{http://www.gnu.org/software/gawk/manual/html_node/Basic-Concepts.html,
+The appendix on basic concepts}
+provides some very cursory background material for those who
+are completely unfamiliar with computer programming.
+
+@item
+@uref{http://www.gnu.org/software/gawk/manual/html_node/Glossary.html,
+The Glossary}
+defines most, if not all, of the significant terms used
+throughout the @value{DOCUMENT}. If you find terms that you aren't familiar with,
+try looking them up here.
+
+@item
+@uref{http://www.gnu.org/software/gawk/manual/html_node/GNU-Free-Documentation-License.html,
+The GNU FDL}
+is the license that covers this @value{DOCUMENT}.
+@end itemize
+
+Some of the chapters have exercise sections; these have also been
+omitted from the print edition but are available online.
+@end ifset
+
+@ifclear FOR_PRINT
+@itemize @value{MINUS}
+@item
+@ref{Notes},
+describes how to disable @command{gawk}'s extensions, as
+well as how to contribute new code to @command{gawk},
+and some possible future directions for @command{gawk} development.
+
+@item
+@ref{Basic Concepts},
+provides some very cursory background material for those who
+are completely unfamiliar with computer programming.
+
+The @ref{Glossary}, defines most, if not all, of the significant terms used
+throughout the @value{DOCUMENT}. If you find terms that you aren't familiar with,
+try looking them up here.
+
+@item
+@ref{Copying}, and
+@ref{GNU Free Documentation License},
+present the licenses that cover the @command{gawk} source code
+and this @value{DOCUMENT}, respectively.
+@end itemize
+@end ifclear
+@end itemize
+
+@c FULLXREF OFF
+
+@node Conventions
+@unnumberedsec Typographical Conventions
+
+@cindex Texinfo
+This @value{DOCUMENT} is written in @uref{http://www.gnu.org/software/texinfo/, 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{>}.
+Input that you type is shown @kbd{like this}.
+@c 8/2014: @print{} is stripped from the texi to make docbook.
+@ifclear FOR_PRINT
+Output from the command is preceded by the glyph ``@print{}''.
+This typically represents the command's standard output.
+@end ifclear
+@ifset FOR_PRINT
+Output from the command, usually its standard output, appears
+@code{like this}.
+@end ifset
+Error messages and other output on the command's standard error are preceded
+by the glyph ``@error{}''. For example:
+
+@example
+$ @kbd{echo hi on stdout}
+@print{} hi on stdout
+$ @kbd{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}.
+Options look like this: @option{-f}.
+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.
+Finally, @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{Ctrl-d} is typed
+by first pressing and holding the @kbd{CONTROL} key, next
+pressing the @kbd{d} key, and finally releasing both keys.
+
+For the sake of brevity, throughout this @value{DOCUMENT}, we refer to
+Brian Kernighan's version of @command{awk} as ``BWK @command{awk}.''
+(@DBXREF{Other Versions} for information on his and other versions.)
+
+@ifset FOR_PRINT
+@quotation NOTE
+Notes of interest look like this.
+@end quotation
+
+@quotation CAUTION
+Cautionary or warning notes look like this.
+@end quotation
+@end ifset
+
+@c fakenode --- for prepinfo
+@unnumberedsubsec 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.}
+@author Brian Kernighan
+@end quotation
+
+@cindex d.c., See dark corner
+@cindex dark corner
+Until the POSIX standard (and @cite{@value{TITLE}}),
+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
+@ifclear FOR_PRINT
+They also appear in the index under the heading ``dark corner.''
+@end ifclear
+
+But, as noted by the opening quote, any coverage of dark
+corners is by definition incomplete.
+
+@cindex c.e., See common extensions
+Extensions to the standard @command{awk} language that are supported by
+more than one @command{awk} implementation are marked
+@ifclear FOR_PRINT
+``@value{COMMONEXT},'' and listed in the index under ``common extensions''
+and ``extensions, common.''
+@end ifclear
+@ifset FOR_PRINT
+``@value{COMMONEXT}'' for ``common extension.''
+@end ifset
+
+@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
+its software's
+source code is always available to the end user.
+@ifclear FOR_PRINT
+A copy of the GPL is included
+@ifnotinfo
+in this @value{DOCUMENT}
+@end ifnotinfo
+for your reference
+(@pxref{Copying}).
+@end ifclear
+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/software/gawk/manual/, GNU's website}.
+
+@ifclear FOR_PRINT
+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 remains in an early
+stage of development.
+
+@cindex Linux
+@cindex GNU/Linux
+@cindex operating systems, BSD-based
+Until the GNU operating system is more fully developed, you should
+consider using GNU/Linux, a freely distributable, Unix-like operating
+system for Intel,
+Power Architecture,
+Sun SPARC, IBM S/390, and other
+systems.@footnote{The terminology ``GNU/Linux'' is explained
+in the @ref{Glossary}.}
+Many GNU/Linux distributions are
+available for download from the Internet.
+@end ifclear
+
+@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}.
+@ifclear FOR_PRINT
+(Take a moment to check the Free Documentation
+License in @ref{GNU Free Documentation License}.)
+@end ifclear
+@end ifnotinfo
+
+@cindex Close, Diane
+The @value{DOCUMENT} itself has gone through multiple previous editions.
+Paul Rubin wrote the very first draft of @cite{The GAWK Manual};
+it was around 40 pages long.
+Diane Close and Richard Stallman improved it, yielding a
+version that was
+around 90 pages 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}.
+@ifset FOR_PRINT
+SSC published two editions of the @value{DOCUMENT} under the
+title @cite{Effective awk Programming}, and O'Reilly published
+the third edition in 2001.
+@end ifset
+
+This edition maintains the basic structure of the previous editions.
+For FSF edition 4.0, the content was thoroughly reviewed and updated. All
+references to @command{gawk} versions prior to 4.0 were removed.
+Of significant note for that edition was the addition of @ref{Debugger}.
+
+For FSF edition
+@ifclear FOR_PRINT
+@value{EDITION},
+@end ifclear
+@ifset FOR_PRINT
+@value{EDITION}
+(the fourth edition as published by O'Reilly),
+@end ifset
+the content has been reorganized into parts,
+and the major new additions are @ref{Arbitrary Precision Arithmetic},
+and @ref{Dynamic Extensions}.
+
+This @value{DOCUMENT} will undoubtedly continue to evolve. If you
+find an error in the @value{DOCUMENT}, please report it! @DBXREF{Bugs}
+for information on submitting problem reports electronically.
+
+@ifset FOR_PRINT
+@c fakenode --- for prepinfo
+@unnumberedsec How to Stay Current
+
+You may have a newer version of @command{gawk} than the
+one described here. To find out what has changed,
+you should first look at the @file{NEWS} file in the @command{gawk}
+distribution, which provides a high-level summary of the changes in
+each release.
+
+You can then look at the @uref{http://www.gnu.org/software/gawk/manual/,
+online version} of this @value{DOCUMENT} to read about any new features.
+@end ifset
+
+@ifclear FOR_PRINT
+@node How To Contribute
+@unnumberedsec How to Contribute
+
+As the maintainer of GNU @command{awk}, I once thought that I would be
+able to manage a collection of publicly available @command{awk} programs
+and I even solicited contributions. Making things available on the Internet
+helps keep the @command{gawk} distribution down to manageable size.
+
+The initial collection of material, such as it is, is still available
+at @uref{ftp://ftp.freefriends.org/arnold/Awkstuff}. In the hopes of
+doing something more broad, I acquired the @code{awk.info} domain.
+
+However, I found that I could not dedicate enough time to managing
+contributed code: the archive did not grow and the domain went unused
+for several years.
+
+Late in 2008, a volunteer took on the task of setting up
+an @command{awk}-related website---@uref{http://awk.info}---and did a very
+nice job.
+
+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 see @uref{http://awk.info/?contribute} for how to
+contribute it to the website.
+
+@ignore
+As of this writing, this website is in search of a maintainer; please
+contact me if you are interested.
+@end ignore
+
+@ignore
+Other links:
+
+http://www.reddit.com/r/linux/comments/dtect/composing_music_in_awk/
+@end ignore
+@end ifclear
+
+@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 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.
+
+@ifclear FOR_PRINT
+Earlier editions of this @value{DOCUMENT} had the following acknowledgements:
+@end ifclear
+@ifset FOR_PRINT
+The previous edition of this @value{DOCUMENT} had
+the following acknowledgements:
+@end ifset
+
+@quotation
+The following people (in alphabetical order)
+provided helpful comments on various
+versions of this book:
+Rick Adams,
+Dr.@: Nelson H.F. Beebe,
+Karl Berry,
+Dr.@: Michael Brennan,
+Rich Burridge,
+Claire Cloutier,
+Diane Close,
+Scott Deifik,
+Christopher (``Topher'') Eliot,
+Jeffrey Friedl,
+Dr.@: Darrel Hankerson,
+Michal Jaegermann,
+Dr.@: Richard J.@: LeBlanc,
+Michael Lijewski,
+Pat Rankin,
+Miriam Robbins,
+Mary Sheehan,
+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.
+
+Chuck Toporek, Mary Sheehan, and Claire Cloutier of O'Reilly & Associates contributed
+significant editorial help for this @value{DOCUMENT} for the
+3.1 release of @command{gawk}.
+@end quotation
+
+@cindex Beebe, Nelson H.F.@:
+@cindex Buening, Andreas
+@cindex Collado, Manuel
+@cindex Colombo, Antonio
+@cindex Davies, Stephen
+@cindex Deifik, Scott
+@cindex Demaille, Akim
+@cindex Hankerson, Darrel
+@cindex Jaegermann, Michal
+@cindex Kahrs, J@"urgen
+@cindex Kasal, Stepan
+@cindex Malmberg, John
+@cindex Pitts, Dave
+@cindex Ramey, Chet
+@cindex Rankin, Pat
+@cindex Schorr, Andrew
+@cindex Vinschen, Corinna
+@cindex Zaretskii, Eli
+
+Dr.@: Nelson Beebe,
+Andreas Buening,
+Dr.@: Manuel Collado,
+Antonio Colombo,
+Stephen Davies,
+Scott Deifik,
+Akim Demaille,
+Darrel Hankerson,
+Michal Jaegermann,
+J@"urgen Kahrs,
+Stepan Kasal,
+John Malmberg,
+Dave Pitts,
+Chet Ramey,
+Pat Rankin,
+Andrew Schorr,
+Corinna Vinschen,
+and Eli Zaretskii
+(in alphabetical order)
+make up the current @command{gawk} ``crack portability team.'' Without
+their hard work and help, @command{gawk} would not be nearly the robust,
+portable program it is today. It has been and continues to be a pleasure
+working with this team of fine people.
+
+Notable code and documentation contributions were made by
+a number of people. @DBXREF{Contributors} for the full list.
+
+@ifset FOR_PRINT
+@cindex Oram, Andy
+Thanks to Andy Oram of O'Reilly Media for initiating
+the fourth edition and for his support during the work.
+Thanks to Jasmine Kwityn for her copyediting work.
+@end ifset
+
+Thanks to Michael Brennan for the Forewords.
+
+@cindex Duman, Patrice
+@cindex Berry, Karl
+Thanks to Patrice Dumas for the new @command{makeinfo} program.
+Thanks to Karl Berry, who continues to work to keep
+the Texinfo markup language sane.
+
+@cindex Kernighan, Brian
+@cindex Brennan, Michael
+@cindex Day, Robert P.J.@:
+Robert P.J.@: Day, Michael Brennan, and Brian Kernighan kindly acted as
+reviewers for the 2015 edition of this @value{DOCUMENT}. Their feedback
+helped improve the final work.
+
+I would also like to thank Brian Kernighan for his invaluable assistance during the
+testing and debugging of @command{gawk}, and for his ongoing
+help and advice 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.
+
+Brian is in a class by himself as a programmer and technical
+author. I have to thank him (yet again) for his ongoing friendship
+and for being a role model to me for close to 30 years!
+Having him as a reviewer is an exciting privilege. It has also
+been extremely humbling@enddots{}
+
+@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.
+@iftex
+@sp 2
+@noindent
+Arnold Robbins @*
+Nof Ayalon @*
+Israel @*
+December 2014
+@end iftex
+
+@ifnotinfo
+@part @value{PART1}The @command{awk} Language
+@end ifnotinfo
+
+@ifdocbook
+
+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}. Included also are many, but not all,
+of the features of @command{gawk}. This part contains the
+following chapters:
+
+@itemize @value{BULLET}
+@item
+@ref{Getting Started}
+
+@item
+@ref{Invoking Gawk}
+
+@item
+@ref{Regexp}
+
+@item
+@ref{Reading Files}
+
+@item
+@ref{Printing}
+
+@item
+@ref{Expressions}
+
+@item
+@ref{Patterns and Actions}
+
+@item
+@ref{Arrays}
+
+@item
+@ref{Functions}
+@end itemize
+@end ifdocbook
+
+@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} continues to process 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} (i.e., 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 should 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;
+@pxref{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 @dfn{pattern} followed by an
+@dfn{action}. The action is enclosed in 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.
+* Intro Summary:: Summary of the introduction.
+@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 the keyboard
+ 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 patterns and
+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.
+
+Later in this chapter, in
+@ifdocbook
+the section
+@end ifdocbook
+@ref{Very Simple},
+we'll see examples of several short,
+self-contained programs.
+
+@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 keyboard. This continues
+until you indicate end-of-file by typing @kbd{Ctrl-d}.
+@ifset FOR_PRINT
+(On non-POSIX operating systems, the end-of-file character may be different.)
+@end ifset
+@ifclear FOR_PRINT
+(On non-POSIX operating systems, the end-of-file character may be different.
+For example, on OS/2, it is @kbd{Ctrl-z}.)
+@end ifclear
+
+@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:
+
+@example
+$ @kbd{awk 'BEGIN @{ print "Don\47t Panic!" @}'}
+@print{} Don't Panic!
+@end example
+
+@command{awk} executes statements associated with @code{BEGIN} before
+reading any input. If there are no other statements in your program,
+as is the case here, @command{awk} just stops, instead of trying to read
+input it doesn't know how to process.
+The @samp{\47} is a magic way (explained later) of getting a single quote into
+the program, without having to engage in ugly shell quoting tricks.
+
+@quotation NOTE
+If you use Bash as your shell, you should execute the
+command @samp{set +H} before running this program interactively, to
+disable the C shell-style command history, which treats @samp{!} as a
+special character. We recommend putting this command into your personal
+startup file.
+@end quotation
+
+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
+$ @kbd{awk '@{ print @}'}
+@kbd{Now is the time for all good men}
+@print{} Now is the time for all good men
+@kbd{to come to the aid of their country.}
+@print{} to come to the aid of their country.
+@kbd{Four score and seven years ago, ...}
+@print{} Four score and seven years ago, ...
+@kbd{What, me worry?}
+@print{} What, me worry?
+@kbd{Ctrl-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 @command{awk} programs are very long. In these cases, 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 @option{-f} option
+@cindex command line, option @option{-f}
+The @option{-f} instructs the @command{awk} utility to get the
+@command{awk} program from the file @var{source-file} (@pxref{Options}).
+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\47t Panic!" @}'
+@end example
+
+@cindex quoting in @command{gawk} command lines
+@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.
+(Also, placing the program in a file allows us to use a literal single quote in the program
+text, instead of the magic @samp{\47}.)
+
+@cindex single quote (@code{'}) in @command{gawk} command lines
+@cindex @code{'} (single quote) in @command{gawk} command lines
+If you want to clearly identify an @command{awk} program file 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 Unix, @command{awk} scripts and
+@cindex number sign (@code{#}), @code{#!} (executable scripts)
+
+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 systems.@footnote{The @samp{#!} mechanism works on
+GNU/Linux systems, BSD-based systems, and commercial Unix systems.}
+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} as if you had
+typed @samp{awk -f advice}:
+
+@example
+$ @kbd{chmod +x advice}
+$ @kbd{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}.
+
+@sidebar Understanding @samp{#!}
+@cindex portability, @code{#!} (executable scripts)
+
+@command{awk} is an @dfn{interpreted} language. This means that the
+@command{awk} utility reads your program and then processes your data
+according to the instructions in your program. (This is different
+from a @dfn{compiled} language such as C, where your program is first
+compiled into machine code that is executed directly by your system's
+processor.) The @command{awk} utility is thus termed an @dfn{interpreter}.
+Many modern languages are interpreted.
+
+The line beginning with @samp{#!} lists the full @value{FN} of an
+interpreter to run and a single 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. (Note that on
+many systems @command{awk} may be found in @file{/usr/bin} instead of
+in @file{/bin}.)
+
+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}). @value{DARKCORNER}
+Don't rely on the value of @code{ARGV[0]}
+to provide your script name.
+@end sidebar
+
+@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 number 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 number 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, for small awk programs
+@cindex single quote (@code{'}), vs.@: apostrophe
+@cindex @code{'} (single quote), vs.@: apostrophe
+@quotation CAUTION
+As mentioned in
+@ref{One-shot},
+you can enclose short to medium-sized 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
+$ @kbd{awk 'BEGIN @{ 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
+$ @kbd{awk '@{ print "hello" @} # let's be cute'}
+> @kbd{'}
+@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,
+because backslashes are not special inside single quotes.
+The next @value{SUBSECTION} describes the shell's quoting rules.
+@end quotation
+
+@node Quoting
+@subsection Shell Quoting Issues
+@cindex shell quoting, rules for
+
+@menu
+* DOS Quoting:: Quoting in Windows Batch Files.
+@end menu
+
+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 Bash, the GNU Bourne-Again
+Shell). If you use the C shell, you're on your own.
+
+Before diving into the rules, we introduce a concept that appears
+throughout this @value{DOCUMENT}, which is that of the @dfn{null},
+or empty, 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{""}. In the shell, it can be written using single
+or double quotes: @code{""} or @code{''}. Although the null string has
+no characters in it, it does exist. For example, consider this command:
+
+@example
+$ @kbd{echo ""}
+@end example
+
+@noindent
+Here, the @command{echo} utility receives a single argument, even
+though that argument has no characters in it. In the rest of this
+@value{DOCUMENT}, we use the terms @dfn{null string} and @dfn{empty string}
+interchangeably. Now, on to the quoting rules:
+
+@itemize @value{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), in shell commands
+@cindex backslash (@code{\}), in shell commands
+@cindex single quote (@code{'}), in shell commands
+@cindex @code{'} (single quote), in shell commands
+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
+@DBREF{Comments}
+for an example of what happens if you try.
+
+@item
+@cindex double quote (@code{"}), in shell commands
+@cindex @code{"} (double quote), in shell commands
+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.
+
+Because 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}:
+
+@example
+awk 'BEGIN @{ print "Don\47t Panic!" @}'
+@end example
+
+@noindent
+could instead be written this way:
+
+@example
+$ @kbd{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 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 in @command{gawk} arguments, quoting and
+Don't use this:
+
+@example
+awk -F"" '@var{program}' @var{files} # wrong!
+@end example
+
+@noindent
+In the second case, @command{awk} attempts 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 in @command{gawk} command lines, tricks for
+Mixing single and double quotes is difficult. You have to resort
+to shell quoting tricks, like this:
+
+@example
+$ @kbd{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, and the second is double-quoted.
+
+This can be ``simplified'' to:
+
+@example
+$ @kbd{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
+$ @kbd{awk "BEGIN @{ print \"Here is a single quote <'>\" @}"}
+@print{} Here is a single quote <'>
+@end example
+
+@noindent
+This option is also painful, because double quotes, backslashes, and dollar signs
+are very common in more advanced @command{awk} programs.
+
+A third option is to use the octal escape sequence equivalents
+(@pxref{Escape Sequences})
+for the
+single- and double-quote characters, like so:
+
+@example
+$ @kbd{awk 'BEGIN @{ print "Here is a single quote <\47>" @}'}
+@print{} Here is a single quote <'>
+$ @kbd{awk 'BEGIN @{ print "Here is a double quote <\42>" @}'}
+@print{} Here is a double quote <">
+@end example
+
+@noindent
+This works nicely, but you should comment clearly what the
+escapes mean.
+
+A fourth option is to use command-line variable assignment, like this:
+
+@example
+$ @kbd{awk -v sq="'" 'BEGIN @{ print "Here is a single quote <" sq ">" @}'}
+@print{} Here is a single quote <'>
+@end example
+
+(Here, the two string constants and the value of @code{sq} are concatenated
+into a single string that is printed by @code{print}.)
+
+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 DOS Quoting
+@subsubsection Quoting in MS-Windows Batch Files
+
+@ignore
+Date: Wed, 21 May 2008 09:58:43 +0200 (CEST)
+From: jeroen.brink@inter.NL.net
+Subject: (g)awk "contribution"
+To: arnold@skeeve.com
+Message-id: <42220.193.172.132.34.1211356723.squirrel@webmail.internl.net>
+
+Hello Arnold,
+
+maybe you can help me out. Found your email on the GNU/awk online manual
+pages.
+
+I've searched hard to figure out how, on Windows, to print double quotes.
+Couldn't find it in the Quotes area, nor on google or elsewhere. Finally i
+figured out how to do this myself.
+
+How to print all lines in a file surrounded by double quotes (on Windows):
+
+gawk "{ print \"\042\" $0 \"\042\" }" <file>
+
+Maybe this is a helpfull tip for other (Windows) gawk users. However, i
+don't have a clue as to where to "publish" this tip! Do you?
+
+Kind regards,
+
+Jeroen Brink
+@end ignore
+
+Although this @value{DOCUMENT} generally only worries about POSIX systems and the
+POSIX shell, the following issue arises often enough for many users that
+it is worth addressing.
+
+@cindex Brink, Jeroen
+The ``shells'' on Microsoft Windows systems use the double-quote
+character for quoting, and make it difficult or impossible to include an
+escaped double-quote character in a command-line script.
+The following example, courtesy of Jeroen Brink, shows
+how to print all lines in a file surrounded by double quotes:
+
+@example
+gawk "@{ print \"\042\" $0 \"\042\" @}" @var{file}
+@end example
+
+
+@node Sample Data Files
+@section @value{DDF}s for the Examples
+
+@cindex input files, examples
+@cindex @code{mail-list} file
+Many of the examples in this @value{DOCUMENT} take their input from two sample
+@value{DF}s. The first, @file{mail-list}, represents a list of peoples' names
+together with their email addresses and information about those people.
+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 @file{mail-list}, each record contains the name of a person,
+his/her phone number, his/her email address, and a code for his/her relationship
+with the author of the list.
+The columns are aligned using spaces.
+An @samp{A} in the last column
+means that the person is an acquaintance. An @samp{F} in the last
+column means that the person is a friend.
+An @samp{R} means that the person is a relative:
+
+@example
+@c system if test ! -d eg ; then mkdir eg ; fi
+@c system if test ! -d eg/lib ; then mkdir eg/lib ; fi
+@c system if test ! -d eg/data ; then mkdir eg/data ; fi
+@c system if test ! -d eg/prog ; then mkdir eg/prog ; fi
+@c system if test ! -d eg/misc ; then mkdir eg/misc ; fi
+@c file eg/data/mail-list
+Amelia 555-5553 amelia.zodiacusque@@gmail.com F
+Anthony 555-3412 anthony.asserturo@@hotmail.com A
+Becky 555-7685 becky.algebrarum@@gmail.com A
+Bill 555-1675 bill.drowning@@hotmail.com A
+Broderick 555-0542 broderick.aliquotiens@@yahoo.com R
+Camilla 555-2912 camilla.infusarum@@skynet.be R
+Fabius 555-1234 fabius.undevicesimus@@ucb.edu F
+Julie 555-6699 julie.perscrutabor@@skeeve.com F
+Martin 555-6480 martin.codicibus@@hotmail.com A
+Samuel 555-3430 samuel.lanceolis@@shu.edu A
+Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R
+@c endfile
+@end example
+
+@cindex @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.
+An empty line separates the data for the two years:
+
+@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
+
+The sample files are included in the @command{gawk} distribution,
+in the directory @file{awklib/eg/data}.
+
+@node Very Simple
+@section Some Simple Examples
+
+The following command runs a simple @command{awk} program that searches the
+input file @file{mail-list} for the character string @samp{li} (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 '/li/ @{ print $0 @}' mail-list
+@end example
+
+@noindent
+When lines containing @samp{li} 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{li}
+in the @command{awk} program. The slashes indicate that @samp{li}
+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
+$ @kbd{awk '/li/ @{ print $0 @}' mail-list}
+@print{} Amelia 555-5553 amelia.zodiacusque@@gmail.com F
+@print{} Broderick 555-0542 broderick.aliquotiens@@yahoo.com R
+@print{} Julie 555-6699 julie.perscrutabor@@skeeve.com F
+@print{} Samuel 555-3430 samuel.lanceolis@@shu.edu A
+@end example
+
+@cindex 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
+braces) in the previous example and the result would be the same:
+@command{awk} prints all lines matching the pattern @samp{li}. By comparison,
+omitting the @code{print} statement but retaining the 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 long. 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 you'll
+need to 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 @value{BULLET}
+@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 has no
+action---so it uses the default action, printing the record.
+
+@item
+Print the length of the longest input line:
+
+@example
+awk '@{ if (length($0) > max) max = length($0) @}
+ END @{ print max @}' data
+@end example
+
+The code associated with @code{END} executes after all
+input has been read; it's the other side of the coin to @code{BEGIN}.
+
+@cindex @command{expand} utility
+@item
+Print the length of the longest line in @file{data}:
+
+@example
+expand data | awk '@{ if (x < length($0)) x = length($0) @}
+ END @{ print "maximum line length is " x @}'
+@end example
+
+This example differs slightly from the previous one:
+the input is processed by the @command{expand} utility to change TABs
+into spaces, so the widths compared are actually the right-margin columns,
+as opposed to the number of input characters on each line.
+
+@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
+@c Remember that awk does floating point division,
+@c no need for (x+1023) / 1024
+@example
+ls -l @var{files} | awk '@{ x += $5 @}
+ END @{ print "total K-bytes:", x / 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 used 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 rule.
+If several patterns match, then several actions execute in the order in
+which they appear in the @command{awk} program. If no patterns match, then
+no actions run.
+
+After processing all the rules that match the line (and perhaps there are none),
+@command{awk} reads the next line. (However,
+@DBPXREF{Next Statement}
+@ifdocbook
+and @DBREF{Nextfile Statement}.)
+@end ifdocbook
+@ifnotdocbook
+and also @pxref{Nextfile Statement}.)
+@end ifnotdocbook
+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{mail-list} and @file{inventory-shipped}:
+
+@example
+$ @kbd{awk '/12/ @{ print $0 @}}
+> @kbd{/21/ @{ print $0 @}' mail-list inventory-shipped}
+@print{} Anthony 555-3412 anthony.asserturo@@hotmail.com A
+@print{} Camilla 555-2912 camilla.infusarum@@skynet.be R
+@print{} Fabius 555-1234 fabius.undevicesimus@@ucb.edu F
+@print{} Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R
+@print{} Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R
+@print{} Jan 21 36 64 620
+@print{} Apr 21 70 74 514
+@end example
+
+@noindent
+Note how the line beginning with @samp{Jean-Paul}
+in @file{mail-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{ls} utility
+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).
+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 file's owner.
+The fourth field identifies the file's group.
+The fifth field contains the file's size 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 @value{FN}.
+
+@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, @command{awk} performs the action
+@samp{sum += $5}. 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 @}' mail-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 our sample programs.
+@command{gawk} places 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 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}
+@quotation 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 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 @command{awk} program must be escaped with a backslash. To illustrate:
+
+@example
+% @kbd{awk 'BEGIN @{ \}
+? @kbd{ print \\}
+? @kbd{ "hello, world" \}
+? @kbd{@}'}
+@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
+$ @kbd{awk 'BEGIN @{}
+> @kbd{print \}
+> @kbd{"hello, world"}
+> @kbd{@}'}
+@print{} hello, world
+@end example
+@end quotation
+
+@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
+$ @kbd{gawk 'BEGIN @{ print "dont panic" # a friendly \}
+> @kbd{ BEGIN rule}
+> @kbd{@}'}
+@error{} gawk: cmd. line:2: BEGIN rule
+@error{} gawk: cmd. line:2: ^ syntax 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), separating statements in actions
+@cindex semicolon (@code{;}), separating statements in actions
+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, for runtime string translation (internationalization),
+determining the type of a variable,
+and array sorting.
+
+As we develop our presentation of the @command{awk} language, we will introduce
+most of the variables and many of the functions. They are described
+systematically in @DBREF{Built-in Variables} and in
+@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 keyboard,
+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.
+
+@cindex Brian Kernighan's @command{awk}
+Complex programs have been written in @command{awk}, including a complete
+retargetable assembler for
+@ifclear FOR_PRINT
+eight-bit microprocessors (@pxref{Glossary}, for more information),
+@end ifclear
+@ifset FOR_PRINT
+eight-bit microprocessors,
+@end ifset
+and a microcode assembler for a special-purpose Prolog
+computer.
+The original @command{awk}'s capabilities were strained by tasks
+of such complexity, but modern versions are more capable.
+
+@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. The shell is good at string and pattern matching; in addition,
+it allows powerful use of the system utilities. Python offers a nice
+balance between high-level ease of programming and access to system
+facilities.@footnote{Other popular scripting languages include Ruby
+and Perl.}
+
+@node Intro Summary
+@section Summary
+
+@c FIXME: Review this chapter for summary of builtin functions called.
+@itemize @value{BULLET}
+@item
+Programs in @command{awk} consist of @var{pattern}--@var{action} pairs.
+
+@item
+An @var{action} without a @var{pattern} always runs. The default
+@var{action} for a pattern without one is @samp{@{ print $0 @}}.
+
+@item
+Use either
+@samp{awk '@var{program}' @var{files}}
+or
+@samp{awk -f @var{program-file} @var{files}}
+to run @command{awk}.
+
+@item
+You may use the special @samp{#!} header line to create @command{awk}
+programs that are directly executable.
+
+@item
+Comments in @command{awk} programs start with @samp{#} and continue to
+the end of the same line.
+
+@item
+Be aware of quoting issues when writing @command{awk} programs as
+part of a larger shell script (or MS-Windows batch file).
+
+@item
+You may use backslash continuation to continue a source line.
+Lines are automatically continued after
+a comma, open brace, question mark, colon,
+@samp{||}, @samp{&&}, @code{do}, and @code{else}.
+@end itemize
+
+@node Invoking Gawk
+@chapter Running @command{awk} and @command{gawk}
+
+This @value{CHAPTER} covers how to run @command{awk}, both POSIX-standard
+and @command{gawk}-specific command-line options, and what
+@command{awk} and
+@command{gawk} do with nonoption arguments.
+It then proceeds to cover how @command{gawk} searches for source files,
+reading standard input along with other files, @command{gawk}'s
+environment variables, @command{gawk}'s exit status, using include files,
+and obsolete and undocumented options and/or features.
+
+Many of the options and features described here are discussed in
+more detail later in the @value{DOCUMENT}; feel free to skip over
+things in this @value{CHAPTER} that don't interest you right now.
+
+@menu
+* Command Line:: How to run @command{awk}.
+* Options:: Command-line options and their meanings.
+* Other Arguments:: Input file names and variable assignments.
+* Naming Standard Input:: How to specify standard input with other
+ files.
+* Environment Variables:: The environment variables @command{gawk} uses.
+* Exit Status:: @command{gawk}'s exit status.
+* Include Files:: Including other files into your program.
+* Loading Shared Libraries:: Loading shared libraries into your program.
+* Obsolete:: Obsolete Options and/or features.
+* Undocumented:: Undocumented Options and Features.
+* Invoking Summary:: Invocation summary.
+@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:
+
+@display
+@command{awk} [@var{options}] @option{-f} @var{progfile} [@option{--}] @var{file} @dots{}
+@command{awk} [@var{options}] [@option{--}] @code{'@var{program}'} @var{file} @dots{}
+@end display
+
+@cindex GNU long options
+@cindex long options
+@cindex options, long
+In addition to 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 @option{--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
+@cindex options, command-line
+@cindex command line, options
+@cindex GNU long options
+@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, either the
+keyword is 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 short option.
+The long and short options are
+interchangeable in all contexts.
+The following list describes options mandated by the POSIX standard:
+
+@table @code
+@item -F @var{fs}
+@itemx --field-separator @var{fs}
+@cindex @option{-F} option
+@cindex @option{--field-separator} option
+@cindex @code{FS} variable, @code{--field-separator} option and
+Set the @code{FS} variable to @var{fs}
+(@pxref{Field Separators}).
+
+@item -f @var{source-file}
+@itemx --file @var{source-file}
+@cindex @option{-f} option
+@cindex @option{--file} option
+@cindex @command{awk} programs, location of
+Read the @command{awk} program source from @var{source-file}
+instead of in the first nonoption argument.
+This option may be given multiple times; the @command{awk}
+program consists of the concatenation of the contents of
+each specified @var{source-file}.
+
+@item -v @var{var}=@var{val}
+@itemx --assign @var{var}=@var{val}
+@cindex @option{-v} option
+@cindex @option{--assign} option
+@cindex variables, setting
+Set 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 predefined variables, @code{-v} option@comma{} setting with
+@cindex variables, predefined @code{-v} option@comma{} setting with
+@quotation 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
+initial value you may have given.
+@end quotation
+
+@item -W @var{gawk-opt}
+@cindex @option{-W} option
+Provide an implementation-specific option.
+This is the POSIX convention for providing implementation-specific options.
+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
+Signal 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{-}.
+It is also useful for passing options on to the @command{awk}
+program; see @ref{Getopt Function}.
+@end table
+
+The following list describes @command{gawk}-specific options:
+
+@c Have to use @asis here to get docbook to come out right.
+@table @asis
+@item @option{-b}
+@itemx @option{--characters-as-bytes}
+@cindex @option{-b} option
+@cindex @option{--characters-as-bytes} option
+Cause @command{gawk} to treat all input data as single-byte characters.
+In addition, all output written with @code{print} or @code{printf}
+is treated as single-byte characters.
+
+Normally, @command{gawk} follows the POSIX standard and attempts to process
+its input data according to the current locale (@pxref{Locales}). This can often involve
+converting multibyte characters into wide characters (internally), and
+can lead to problems or confusion if the input data does not contain valid
+multibyte characters. This option is an easy way to tell @command{gawk},
+``Hands off my data!''
+
+@item @option{-c}
+@itemx @option{--traditional}
+@cindex @option{-c} option
+@cindex @option{--traditional} option
+@cindex compatibility mode (@command{gawk}), specifying
+Specify @dfn{compatibility mode}, in which the GNU extensions to
+the @command{awk} language are disabled, so that @command{gawk} behaves just
+like BWK @command{awk}.
+@xref{POSIX/GNU},
+which summarizes the extensions.
+@ifclear FOR_PRINT
+Also see
+@ref{Compatibility Mode}.
+@end ifclear
+
+@item @option{-C}
+@itemx @option{--copyright}
+@cindex @option{-C} option
+@cindex @option{--copyright} option
+@cindex GPL (General Public License), printing
+Print the short version of the General Public License and then exit.
+
+@item @option{-d}[@var{file}]
+@itemx @option{--dump-variables}[@code{=}@var{file}]
+@cindex @option{-d} option
+@cindex @option{--dump-variables} option
+@cindex dump all variables of a program
+@cindex @file{awkvars.out} file
+@cindex files, @file{awkvars.out}
+@cindex variables, global, printing list of
+Print a sorted list of global variables, their types, and final values
+to @var{file}. If no @var{file} is provided, print this
+list to a file named @file{awkvars.out} in the current directory.
+No space is allowed between the @option{-d} and @var{file}, if
+@var{file} is supplied.
+
+@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 @option{-D}[@var{file}]
+@itemx @option{--debug}[@code{=}@var{file}]
+@cindex @option{-D} option
+@cindex @option{--debug} option
+@cindex @command{awk} debugging, enabling
+Enable debugging of @command{awk} programs
+(@pxref{Debugging}).
+By default, the debugger reads commands interactively from the keyboard
+(standard input).
+The optional @var{file} argument allows you to specify a file with a list
+of commands for the debugger to execute noninteractively.
+No space is allowed between the @option{-D} and @var{file}, if
+@var{file} is supplied.
+
+@item @option{-e} @var{program-text}
+@itemx @option{--source} @var{program-text}
+@cindex @option{-e} option
+@cindex @option{--source} option
+@cindex source code, mixing
+Provide program source code in the @var{program-text}.
+This option allows you to mix source code in files with source
+code that you enter on the command line.
+This is particularly useful
+when you have library functions that you want to use from your command-line
+programs (@pxref{AWKPATH Variable}).
+
+@item @option{-E} @var{file}
+@itemx @option{--exec} @var{file}
+@cindex @option{-E} option
+@cindex @option{--exec} option
+@cindex @command{awk} programs, location of
+@cindex CGI, @command{awk} scripts for
+Similar to @option{-f}, read @command{awk} program text from @var{file}.
+There are two differences from @option{-f}:
+
+@itemize @value{BULLET}
+@item
+This option terminates option processing; anything
+else on the command line is passed on directly to the @command{awk} program.
+
+@item
+Command-line variable assignments of the form
+@samp{@var{var}=@var{value}} are disallowed.
+@end itemize
+
+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{-e}) to the CGI application.@footnote{For more detail,
+please see Section 4.4 of @uref{http://www.ietf.org/rfc/rfc3875,
+RFC 3875}. Also see the
+@uref{http://lists.gnu.org/archive/html/bug-gawk/2014-11/msg00022.html,
+explanatory note sent to the @command{gawk} bug
+mailing list}.}
+This option should be used
+with @samp{#!} scripts (@pxref{Executable Scripts}), like so:
+
+@example
+#! /usr/local/bin/gawk -E
+
+@var{awk program here @dots{}}
+@end example
+
+@item @option{-g}
+@itemx @option{--gen-pot}
+@cindex @option{-g} option
+@cindex @option{--gen-pot} option
+@cindex portable object files, generating
+@cindex files, portable object, generating
+Analyze the source program and
+generate a GNU @command{gettext} portable object template file on standard
+output for all string constants that have been marked for translation.
+@xref{Internationalization},
+for information about this option.
+
+@item @option{-h}
+@itemx @option{--help}
+@cindex @option{-h} option
+@cindex @option{--help} option
+@cindex GNU long options, printing list of
+@cindex options, printing list of
+@cindex printing, list of options
+Print a ``usage'' message summarizing the short- and long-style options
+that @command{gawk} accepts and then exit.
+
+@item @option{-i} @var{source-file}
+@itemx @option{--include} @var{source-file}
+@cindex @option{-i} option
+@cindex @option{--include} option
+@cindex @command{awk} programs, location of
+Read an @command{awk} source library from @var{source-file}. This option
+is completely equivalent to using the @code{@@include} directive inside
+your program. It is very similar to the @option{-f} option,
+but there are two important differences. First, when @option{-i} is
+used, the program source is not loaded if it has been previously
+loaded, whereas with @option{-f}, @command{gawk} always loads the file.
+Second, because this option is intended to be used with code libraries,
+@command{gawk} does not recognize such files as constituting main program
+input. Thus, after processing an @option{-i} argument, @command{gawk}
+still expects to find the main source code via the @option{-f} option
+or on the command line.
+
+@item @option{-l} @var{ext}
+@itemx @option{--load} @var{ext}
+@cindex @option{-l} option
+@cindex @option{--load} option
+@cindex loading, extensions
+Load a dynamic extension named @var{ext}. Extensions
+are stored as system shared libraries.
+This option searches for the library using the @env{AWKLIBPATH}
+environment variable. The correct library suffix for your platform will be
+supplied by default, so it need not be specified in the extension name.
+The extension initialization routine should be named @code{dl_load()}.
+An alternative is to use the @code{@@load} keyword inside the program to load
+a shared library. This advanced feature is described in detail in @ref{Dynamic Extensions}.
+
+@item @option{-L}[@var{value}]
+@itemx @option{--lint}[@code{=}@var{value}]
+@cindex @option{-l} option
+@cindex @option{--lint} option
+@cindex lint checking, issuing warnings
+@cindex warnings, issuing
+Warn about constructs that are dubious or nonportable to
+other @command{awk} implementations.
+No space is allowed between the @option{-L} and @var{value}, if
+@var{value} is supplied.
+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.)
+
+Some warnings are only printed once, even if the dubious constructs they
+warn about occur multiple times in your @command{awk} program. Thus,
+when eliminating problems pointed out by @option{--lint}, you should take
+care to search for all occurrences of each inappropriate construct. As
+@command{awk} programs are usually short, doing so is not burdensome.
+
+@item @option{-M}
+@itemx @option{--bignum}
+@cindex @option{-M} option
+@cindex @option{--bignum} option
+Force arbitrary-precision arithmetic on numbers. This option has no effect
+if @command{gawk} is not compiled to use the GNU MPFR and MP libraries
+(@pxref{Arbitrary Precision Arithmetic}).
+
+@item @option{-n}
+@itemx @option{--non-decimal-data}
+@cindex @option{-n} option
+@cindex @option{--non-decimal-data} option
+@cindex hexadecimal values@comma{} enabling interpretation of
+@cindex octal values@comma{} enabling interpretation of
+@cindex troubleshooting, @code{--non-decimal-data} option
+Enable automatic interpretation of octal and hexadecimal
+values in input data
+(@pxref{Nondecimal Data}).
+
+@quotation CAUTION
+This option can severely break old programs. Use with care. Also note
+that this option may disappear in a future version of @command{gawk}.
+@end quotation
+
+@item @option{-N}
+@itemx @option{--use-lc-numeric}
+@cindex @option{-N} option
+@cindex @option{--use-lc-numeric} option
+Force the use of the locale's decimal point character
+when parsing numeric input data (@pxref{Locales}).
+
+@item @option{-o}[@var{file}]
+@itemx @option{--pretty-print}[@code{=}@var{file}]
+@cindex @option{-o} option
+@cindex @option{--pretty-print} option
+Enable pretty-printing of @command{awk} programs.
+By default, the output program is created in a file named @file{awkprof.out}
+(@pxref{Profiling}).
+The optional @var{file} argument allows you to specify a different
+@value{FN} for the output.
+No space is allowed between the @option{-o} and @var{file}, if
+@var{file} is supplied.
+
+@quotation NOTE
+In the past, this option would also execute your program.
+This is no longer the case.
+@end quotation
+
+@item @option{-O}
+@itemx @option{--optimize}
+@cindex @option{--optimize} option
+@cindex @option{-O} option
+Enable some optimizations on the internal representation of the program.
+At the moment, this includes just simple constant folding.
+
+@item @option{-p}[@var{file}]
+@itemx @option{--profile}[@code{=}@var{file}]
+@cindex @option{-p} option
+@cindex @option{--profile} option
+@cindex @command{awk} 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.
+No space is allowed between the @option{-p} and @var{file}, if
+@var{file} is supplied.
+
+The profile contains execution counts for each statement in the program
+in the left margin, and function call counts for each function.
+
+@item @option{-P}
+@itemx @option{--posix}
+@cindex @option{-P} option
+@cindex @option{--posix} option
+@cindex POSIX mode
+@cindex @command{gawk}, extensions@comma{} disabling
+Operate in strict POSIX mode. This disables all @command{gawk}
+extensions (just like @option{--traditional}) and
+disables all extensions not allowed by POSIX.
+@DBXREF{Common Extensions} for a summary of the extensions
+in @command{gawk} that are disabled by this option.
+Also,
+the following additional
+restrictions apply:
+
+@itemize @value{BULLET}
+
+@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}).
+
+
+@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 locale decimal point character
+@cindex decimal point character, locale specific
+@item
+The locale's decimal point character is used for parsing input
+data (@pxref{Locales}).
+@end itemize
+
+@c @cindex automatic warnings
+@c @cindex warnings, automatic
+@cindex @option{--traditional} option, @code{--posix} option and
+@cindex @option{--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}
+issues a warning if both options are supplied.
+
+@item @option{-r}
+@itemx @option{--re-interval}
+@cindex @option{-r} option
+@cindex @option{--re-interval} option
+@cindex regular expressions, interval expressions and
+Allow interval expressions
+(@pxref{Regexp Operators})
+in regexps.
+This is now @command{gawk}'s default behavior.
+Nevertheless, this option remains (both for backward compatibility
+and for use in combination with @option{--traditional}).
+
+@item @option{-S}
+@itemx @option{--sandbox}
+@cindex @option{-S} option
+@cindex @option{--sandbox} option
+@cindex sandbox mode
+Disable the @code{system()} function,
+input redirections with @code{getline},
+output redirections with @code{print} and @code{printf},
+and dynamic extensions.
+This is particularly useful when you want to run @command{awk} scripts
+from questionable sources and need to make sure the scripts
+can't access your system (other than the specified input @value{DF}).
+
+@item @option{-t}
+@itemx @option{--lint-old}
+@cindex @option{-L} option
+@cindex @option{--lint-old} option
+Warn about constructs that are not available in the original version of
+@command{awk} from Version 7 Unix
+(@pxref{V7/SVR3.1}).
+
+@item @option{-V}
+@itemx @option{--version}
+@cindex @option{-V} option
+@cindex @option{--version} option
+@cindex @command{gawk}, versions of, information about@comma{} printing
+Print 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 @option{-F} option, @option{-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 @option{-f} option, multiple uses
+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 in each individual program.
+The @option{-i} option is similar in this regard.
+(As mentioned in
+@ref{Definition Syntax},
+function names must be unique.)
+
+With standard @command{awk}, library functions can still be used, even
+if the program is entered at the keyboard,
+by specifying @samp{-f /dev/tty}. After typing your program,
+type @kbd{Ctrl-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{-e} option. This does not require you to
+preempt the standard input for your source code; it allows you to easily
+mix command-line and library source code (@pxref{AWKPATH Variable}).
+As with @option{-f}, the @option{-e} and @option{-i}
+options may also be used multiple times on the command line.
+
+@cindex @option{-e} option
+If no @option{-f} or @option{-e} option is specified, then @command{gawk}
+uses the first nonoption command-line argument as the text of the
+program source code.
+
+@cindex @env{POSIXLY_CORRECT} environment variable
+@cindex lint checking, @env{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 @option{--posix}.
+Many GNU programs look for this environment variable to suppress
+extensions that conflict with POSIX, but @command{gawk} behaves
+differently: it suppresses all extensions, even those that do not
+conflict with POSIX, and behaves in
+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 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, @env{POSIXLY_CORRECT} environment variable
+For a C shell-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, @env{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.
+
+@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. (See @ref{Assignment Options}.) In the following example,
+@var{count=1} is a variable assignment, not a @value{FN}:
+
+@example
+awk -f program.awk file1 count=1 file2
+@end example
+
+@cindex @command{gawk}, @code{ARGIND} variable in
+@cindex @code{ARGIND} variable, command-line arguments
+@cindex @code{ARGV} array, indexing into
+@cindex @code{ARGC}/@code{ARGV} variables, command-line arguments
+All the command-line 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 @code{ARGIND} to the index in @code{ARGV} of the
+current element.
+
+@c FIXME: One day, move the ARGC and ARGV node closer to here.
+Changing @code{ARGC} and @code{ARGV} in your @command{awk} program lets
+you control how @command{awk} processes the input files; this is described
+in more detail in @ref{ARGC and ARGV}.
+
+@cindex input files, variable assignments and
+@cindex variable assignments and input files
+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 very early 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 Naming Standard Input
+@section Naming Standard Input
+
+Often, you may wish to read standard input together with other files.
+For example, you may wish to read one file, read standard input coming
+from a pipe, and then read another file.
+
+The way to name the standard input, with all versions of @command{awk},
+is to use a single, standalone minus sign or dash, @samp{-}. For example:
+
+@example
+@var{some_command} | awk -f myprog.awk file1 - file2
+@end example
+
+@noindent
+Here, @command{awk} first reads @file{file1}, then it reads
+the output of @var{some_command}, and finally it reads
+@file{file2}.
+
+You may also use @code{"-"} to name standard input when reading
+files with @code{getline} (@pxref{Getline/File}).
+
+In addition, @command{gawk} allows you to specify the special
+@value{FN} @file{/dev/stdin}, both on the command line and
+with @code{getline}.
+Some other versions of @command{awk} also support this, but it
+is not standard.
+(Some operating systems provide a @file{/dev/stdin} file
+in the filesystem; however, @command{gawk} always processes
+this @value{FN} itself.)
+
+@node Environment Variables
+@section The Environment Variables @command{gawk} Uses
+@cindex environment variables used by @command{gawk}
+
+A number of environment variables influence how @command{gawk}
+behaves.
+
+@menu
+* AWKPATH Variable:: Searching directories for @command{awk}
+ programs.
+* AWKLIBPATH Variable:: Searching directories for @command{awk} shared
+ libraries.
+* Other Environment Variables:: The environment variables.
+@end menu
+
+@node AWKPATH Variable
+@subsection The @env{AWKPATH} Environment Variable
+@cindex @env{AWKPATH} environment variable
+@cindex directories, searching for source files
+@cindex search paths, for source files
+@cindex differences in @command{awk} and @command{gawk}, @env{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 pathname for each program
+file, unless the file is in the current directory.
+But with @command{gawk}, if the @value{FN} supplied to the @option{-f}
+or @option{-i} options
+does not contain a directory separator @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.@footnote{Semicolons on MS-Windows and MS-DOS.}
+@command{gawk} gets its search path from the
+@env{AWKPATH} environment variable. If that variable does not exist,
+or if it has an empty value,
+@command{gawk} uses a default path (described shortly).
+
+The search path feature is particularly helpful 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, you would have to
+type the full @value{FN} for each file.
+
+By using the @option{-i} or @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}.
+
+If the source code file is not found after the initial search, the path is searched
+again after adding the suffix @samp{.awk} to the @value{FN}.
+
+@command{gawk}'s path search mechanism is similar
+to the shell's.
+(See @uref{http://www.gnu.org/software/bash/manual/,
+@cite{The Bourne-Again SHell manual}}.)
+It treats a null entry in the path as indicating the current
+directory.
+(A null entry is indicated by starting or ending the path with a
+colon or by placing two colons next to each other [@samp{::}].)
+
+@quotation NOTE
+To include the current directory in the path, either place @file{.}
+as an entry in the path or write a null entry in the path.
+
+Different past versions of @command{gawk} would also look explicitly in
+the current directory, either before or after the path search. As of
+@value{PVERSION} 4.1.2, this no longer happens; if you wish to look
+in the current directory, you must include @file{.} either as a separate
+entry or as a null entry in the search path.
+@end quotation
+
+The default value for @env{AWKPATH} is
+@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 @code{$(datadir)} generated when
+@command{gawk} was configured. You probably don't need to worry about this,
+though.} Since @file{.} is included at the beginning, @command{gawk}
+searches first in the current directory and then in @file{/usr/local/share/awk}.
+In practice, this means that you will rarely need to change the
+value of @env{AWKPATH}.
+
+@xref{Shell Startup Files}, for information on functions that help to
+manipulate the @env{AWKPATH} variable.
+
+@command{gawk} places the value of the search path that it used into
+@code{ENVIRON["AWKPATH"]}. This provides access to the actual search
+path value from within an @command{awk} program.
+
+Although 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 AWKLIBPATH Variable
+@subsection The @env{AWKLIBPATH} Environment Variable
+@cindex @env{AWKLIBPATH} environment variable
+@cindex directories, searching for loadable extensions
+@cindex search paths, for loadable extensions
+@cindex differences in @command{awk} and @command{gawk}, @code{AWKLIBPATH} environment variable
+
+The @env{AWKLIBPATH} environment variable is similar to the @env{AWKPATH}
+variable, but it is used to search for loadable extensions (stored as
+system shared libraries) specified with the @option{-l} option rather
+than for source files. If the extension is not found, the path is
+searched again after adding the appropriate shared library suffix for
+the platform. For example, on GNU/Linux systems, the suffix @samp{.so}
+is used. The search path specified is also used for extensions loaded
+via the @code{@@load} keyword (@pxref{Loading Shared Libraries}).
+
+If @env{AWKLIBPATH} does not exist in the environment, or if it has
+an empty value, @command{gawk} uses a default path; this
+is typically @samp{/usr/local/lib/gawk}, although it can vary depending
+upon how @command{gawk} was built.
+
+@xref{Shell Startup Files}, for information on functions that help to
+manipulate the @env{AWKLIBPATH} variable.
+
+@command{gawk} places the value of the search path that it used into
+@code{ENVIRON["AWKLIBPATH"]}. This provides access to the actual search
+path value from within an @command{awk} program.
+
+@node Other Environment Variables
+@subsection Other Environment Variables
+
+A number of other environment variables affect @command{gawk}'s
+behavior, but they are more specialized. Those in the following
+list are meant to be used by regular users:
+
+@table @env
+@item GAWK_MSEC_SLEEP
+Specifies the interval between connection retries,
+in milliseconds. On systems that do not support
+the @code{usleep()} system call,
+the value is rounded up to an integral number of seconds.
+
+@item GAWK_READ_TIMEOUT
+Specifies the time, in milliseconds, for @command{gawk} to
+wait for input before returning with an error.
+@xref{Read Timeout}.
+
+@item GAWK_SOCK_RETRIES
+Controls the number of times @command{gawk} attempts to
+retry a two-way TCP/IP (socket) connection before giving up.
+@xref{TCP/IP Networking}.
+
+@item POSIXLY_CORRECT
+Causes @command{gawk} to switch to POSIX-compatibility
+mode, disabling all traditional and GNU extensions.
+@xref{Options}.
+@end table
+
+The environment variables in the following list are meant
+for use by the @command{gawk} developers for testing and tuning.
+They are subject to change. The variables are:
+
+@table @env
+@item AWKBUFSIZE
+This variable only affects @command{gawk} on POSIX-compliant systems.
+With a value of @samp{exact}, @command{gawk} uses the size of each input
+file as the size of the memory buffer to allocate for I/O. Otherwise,
+the value should be a number, and @command{gawk} uses that number as
+the size of the buffer to allocate. (When this variable is not set,
+@command{gawk} uses the smaller of the file's size and the ``default''
+blocksize, which is usually the filesystem's I/O blocksize.)
+
+@item AWK_HASH
+If this variable exists with a value of @samp{gst}, @command{gawk}
+switches to using the hash function from GNU Smalltalk for
+managing arrays.
+This function may be marginally faster than the standard function.
+
+@item AWKREADFUNC
+If this variable exists, @command{gawk} switches to reading source
+files one line at a time, instead of reading in blocks. This exists
+for debugging problems on filesystems on non-POSIX operating systems
+where I/O is performed in records, not in blocks.
+
+@item GAWK_MSG_SRC
+If this variable exists, @command{gawk} includes the @value{FN}
+and line number within the @command{gawk} source code
+from which warning and/or fatal messages
+are generated. Its purpose is to help isolate the source of a
+message, as there are multiple places that produce the
+same warning or error message.
+
+@item GAWK_NO_DFA
+If this variable exists, @command{gawk} does not use the DFA regexp matcher
+for ``does it match'' kinds of tests. This can cause @command{gawk}
+to be slower. Its purpose is to help isolate differences between the
+two regexp matchers that @command{gawk} uses internally. (There aren't
+supposed to be differences, but occasionally theory and practice don't
+coordinate with each other.)
+
+@item GAWK_STACKSIZE
+This specifies the amount by which @command{gawk} should grow its
+internal evaluation stack, when needed.
+
+@item INT_CHAIN_MAX
+This specifies intended maximum number of items @command{gawk} will maintain on a
+hash chain for managing arrays indexed by integers.
+
+@item STR_CHAIN_MAX
+This specifies intended maximum number of items @command{gawk} will maintain on a
+hash chain for managing arrays indexed by strings.
+
+@item TIDYMEM
+If this variable exists, @command{gawk} uses the @code{mtrace()} library
+calls from the GNU C library to help track down possible memory leaks.
+@end table
+
+@node Exit Status
+@section @command{gawk}'s Exit Status
+
+@cindex exit status, of @command{gawk}
+If the @code{exit} statement is used with a value
+(@pxref{Exit Statement}), then @command{gawk} exits with
+the numeric value given to it.
+
+Otherwise, if there were no problems during execution,
+@command{gawk} exits with the value of the C constant
+@code{EXIT_SUCCESS}. This is usually zero.
+
+If an error occurs, @command{gawk} exits with the value of
+the C constant @code{EXIT_FAILURE}. This is usually one.
+
+If @command{gawk} exits because of a fatal error, the exit
+status is two. On non-POSIX systems, this value may be mapped
+to @code{EXIT_FAILURE}.
+
+@node Include Files
+@section Including Other Files into Your Program
+
+@c Panos Papadopoulos <panos1962@gmail.com> contributed the original
+@c text for this section.
+
+This @value{SECTION} describes a feature that is specific to @command{gawk}.
+
+@cindex @code{@@include} directive
+@cindex file inclusion, @code{@@include} directive
+@cindex including files, @code{@@include} directive
+The @code{@@include} keyword can be used to read external @command{awk} source
+files. This gives you the ability to split large @command{awk} source files
+into smaller, more manageable pieces, and also lets you reuse common @command{awk}
+code from various @command{awk} scripts. In other words, you can group
+together @command{awk} functions used to carry out specific tasks
+into external files. These files can be used just like function libraries,
+using the @code{@@include} keyword in conjunction with the @env{AWKPATH}
+environment variable. Note that source files may also be included
+using the @option{-i} option.
+
+Let's see an example.
+We'll start with two (trivial) @command{awk} scripts, namely
+@file{test1} and @file{test2}. Here is the @file{test1} script:
+
+@example
+BEGIN @{
+ print "This is script test1."
+@}
+@end example
+
+@noindent
+and here is @file{test2}:
+
+@example
+@@include "test1"
+BEGIN @{
+ print "This is script test2."
+@}
+@end example
+
+Running @command{gawk} with @file{test2}
+produces the following result:
+
+@example
+$ @kbd{gawk -f test2}
+@print{} This is script test1.
+@print{} This is script test2.
+@end example
+
+@code{gawk} runs the @file{test2} script, which includes @file{test1}
+using the @code{@@include}
+keyword. So, to include external @command{awk} source files, you just
+use @code{@@include} followed by the name of the file to be included,
+enclosed in double quotes.
+
+@quotation NOTE
+Keep in mind that this is a language construct and the @value{FN} cannot
+be a string variable, but rather just a literal string constant in double quotes.
+@end quotation
+
+The files to be included may be nested; e.g., given a third
+script, namely @file{test3}:
+
+@example
+@@include "test2"
+BEGIN @{
+ print "This is script test3."
+@}
+@end example
+
+@noindent
+Running @command{gawk} with the @file{test3} script produces the
+following results:
+
+@example
+$ @kbd{gawk -f test3}
+@print{} This is script test1.
+@print{} This is script test2.
+@print{} This is script test3.
+@end example
+
+The @value{FN} can, of course, be a pathname. For example:
+
+@example
+@@include "../io_funcs"
+@end example
+
+@noindent
+and:
+
+@example
+@@include "/usr/awklib/network"
+@end example
+
+@noindent
+are both valid. The @env{AWKPATH} environment variable can be of great
+value when using @code{@@include}. The same rules for the use
+of the @env{AWKPATH} variable in command-line file searches
+(@pxref{AWKPATH Variable}) apply to
+@code{@@include} also.
+
+This is very helpful in constructing @command{gawk} function libraries.
+If you have a large script with useful, general-purpose @command{awk}
+functions, you can break it down into library files and put those files
+in a special directory. You can then include those ``libraries,''
+either by using the full pathnames of the files, or by setting the @env{AWKPATH}
+environment variable accordingly and then using @code{@@include} with
+just the file part of the full pathname. Of course,
+you can keep library files in more than one directory;
+the more complex the working
+environment is, the more directories you may need to organize the files
+to be included.
+
+Given the ability to specify multiple @option{-f} options, the
+@code{@@include} mechanism is not strictly necessary.
+However, the @code{@@include} keyword
+can help you in constructing self-contained @command{gawk} programs,
+thus reducing the need for writing complex and tedious command lines.
+In particular, @code{@@include} is very useful for writing CGI scripts
+to be run from web pages.
+
+As mentioned in @ref{AWKPATH Variable}, the current directory is always
+searched first for source files, before searching in @env{AWKPATH};
+this also applies to files named with @code{@@include}.
+
+@node Loading Shared Libraries
+@section Loading Dynamic Extensions into Your Program
+
+This @value{SECTION} describes a feature that is specific to @command{gawk}.
+
+@cindex @code{@@load} directive
+@cindex loading extensions, @code{@@load} directive
+@cindex extensions, loading, @code{@@load} directive
+The @code{@@load} keyword can be used to read external @command{awk} extensions
+(stored as system shared libraries).
+This allows you to link in compiled code that may offer superior
+performance and/or give you access to extended capabilities not supported
+by the @command{awk} language. The @env{AWKLIBPATH} variable is used to
+search for the extension. Using @code{@@load} is completely equivalent
+to using the @option{-l} command-line option.
+
+If the extension is not initially found in @env{AWKLIBPATH}, another
+search is conducted after appending the platform's default shared library
+suffix to the @value{FN}. For example, on GNU/Linux systems, the suffix
+@samp{.so} is used:
+
+@example
+$ @kbd{gawk '@@load "ordchr"; BEGIN @{print chr(65)@}'}
+@print{} A
+@end example
+
+@noindent
+This is equivalent to the following example:
+
+@example
+$ @kbd{gawk -lordchr 'BEGIN @{print chr(65)@}'}
+@print{} A
+@end example
+
+@noindent
+For command-line usage, the @option{-l} option is more convenient,
+but @code{@@load} is useful for embedding inside an @command{awk} source file
+that requires access to an extension.
+
+@ref{Dynamic Extensions}, describes how to write extensions (in C or C++)
+that can be loaded with either @code{@@load} or the @option{-l} option.
+It also describes the @code{ordchr} extension.
+
+@node Obsolete
+@section Obsolete Options and/or Features
+
+@c update this section for each release!
+
+@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 either are not available in the
+current version or are still supported but deprecated (meaning that
+they will @emph{not} be in the next release).
+
+The process-related special files @file{/dev/pid}, @file{/dev/ppid},
+@file{/dev/pgrpid}, and @file{/dev/user} were deprecated in @command{gawk}
+3.1, but still worked. As of @value{PVERSION} 4.0, they are no longer
+interpreted specially by @command{gawk}. (Use @code{PROCINFO} instead;
+see @ref{Auto-set}.)
+
+@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!}
+@author Obi-Wan
+@end quotation
+
+@cindex shells, sea
+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 @samp{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 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}.
+
+@end ignore
+
+@node Invoking Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+Use either
+@samp{awk '@var{program}' @var{files}}
+or
+@samp{awk -f @var{program-file} @var{files}}
+to run @command{awk}.
+
+@item
+The three standard options for all versions of @command{awk} are
+@option{-f}, @option{-F}, and @option{-v}. @command{gawk} supplies these
+and many others, as well as corresponding GNU-style long options.
+
+@item
+Nonoption command-line arguments are usually treated as @value{FN}s,
+unless they have the form @samp{@var{var}=@var{value}}, in which case
+they are taken as variable assignments to be performed at that point
+in processing the input.
+
+@item
+All nonoption command-line arguments, excluding the program text,
+are placed in the @code{ARGV} array. Adjusting @code{ARGC} and @code{ARGV}
+affects how @command{awk} processes input.
+
+@item
+You can use a single minus sign (@samp{-}) to refer to standard input
+on the command line. @command{gawk} also lets you use the special
+@value{FN} @file{/dev/stdin}.
+
+@item
+@command{gawk} pays attention to a number of environment variables.
+@env{AWKPATH}, @env{AWKLIBPATH}, and @env{POSIXLY_CORRECT} are the
+most important ones.
+
+@item
+@command{gawk}'s exit status conveys information to the program
+that invoked it. Use the @code{exit} statement from within
+an @command{awk} program to set the exit status.
+
+@item
+@command{gawk} allows you to include other @command{awk} source files into
+your program using the @code{@@include} statement and/or the @option{-i}
+and @option{-f} command-line options.
+
+@item
+@command{gawk} allows you to load additional functions written in C
+or C++ using the @code{@@load} statement and/or the @option{-l} option.
+(This advanced feature is described later, in @ref{Dynamic Extensions}.)
+@end itemize
+
+@node Regexp
+@chapter Regular Expressions
+@cindex 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{/}) to enclose regular expressions
+@cindex @code{/} (forward slash) to enclose regular expressions
+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}.
+Thus, the pattern @code{/foo/} matches any input record containing
+the three adjacent 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 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.
+* Bracket Expressions:: What can go between @samp{[...]}.
+* Leftmost Longest:: How much text matches.
+* Computed Regexps:: Using Dynamic Regexps.
+* GNU Regexp Operators:: Operators specific to GNU software.
+* Case-sensitivity:: How to do case-insensitive matching.
+* Regexp Summary:: Regular expressions summary.
+@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 where the string
+@samp{li} appears anywhere in the record:
+
+@example
+$ @kbd{awk '/li/ @{ print $2 @}' mail-list}
+@print{} 555-5553
+@print{} 555-0542
+@print{} 555-6699
+@print{} 555-3430
+@end example
+
+@cindex regular expressions, operators
+@cindex operators, string-matching
+@c @cindex operators, @code{~}
+@cindex string-matching operators
+@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{!~}
+@cindex @code{if} statement, use of regexps in
+@cindex @code{while} statement, use of regexps in
+@cindex @code{do}-@code{while} statement, use of regexps in
+@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, the following is true if the expression @var{exp} (taken
+as a string) matches @var{regexp}:
+
+@example
+@var{exp} ~ /@var{regexp}/
+@end example
+
+@noindent
+This example matches, or selects, all input records with the uppercase
+letter @samp{J} somewhere in the first field:
+
+@example
+$ @kbd{awk '$1 ~ /J/' inventory-shipped}
+@print{} Jan 13 25 15 115
+@print{} Jun 31 42 75 492
+@print{} Jul 24 34 67 436
+@print{} Jan 21 36 64 620
+@end example
+
+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
+$ @kbd{awk '$1 !~ /J/' inventory-shipped}
+@print{} Feb 15 32 24 226
+@print{} Mar 15 24 34 228
+@print{} Apr 31 52 63 420
+@print{} May 16 34 29 208
+@dots{}
+@end example
+
+@cindex regexp constants
+@cindex constant regexps
+@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, in strings
+@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
+$ @kbd{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{"\"\\"}.
+
+Other escape sequences represent unprintable characters
+such as TAB or newline. There is nothing to stop you from entering most
+unprintable characters directly in a string constant or regexp constant,
+but they may look ugly.
+
+The following list presents
+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{Ctrl-g}, ASCII code 7 (BEL).
+(This often makes some sort of audible noise.)
+
+@cindex @code{\} (backslash), @code{\b} escape sequence
+@cindex backslash (@code{\}), @code{\b} escape sequence
+@item \b
+Backspace, @kbd{Ctrl-h}, ASCII code 8 (BS).
+
+@cindex @code{\} (backslash), @code{\f} escape sequence
+@cindex backslash (@code{\}), @code{\f} escape sequence
+@item \f
+Formfeed, @kbd{Ctrl-l}, ASCII code 12 (FF).
+
+@cindex @code{\} (backslash), @code{\n} escape sequence
+@cindex backslash (@code{\}), @code{\n} escape sequence
+@item \n
+Newline, @kbd{Ctrl-j}, ASCII code 10 (LF).
+
+@cindex @code{\} (backslash), @code{\r} escape sequence
+@cindex backslash (@code{\}), @code{\r} escape sequence
+@item \r
+Carriage return, @kbd{Ctrl-m}, ASCII code 13 (CR).
+
+@cindex @code{\} (backslash), @code{\t} escape sequence
+@cindex backslash (@code{\}), @code{\t} escape sequence
+@item \t
+Horizontal TAB, @kbd{Ctrl-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{Ctrl-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
+@cindex common extensions, @code{\x} escape sequence
+@cindex extensions, common@comma{} @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}). A maximum of two digts are allowed after
+the @samp{\x}. Any further hexadecimal digits are treated as simple
+letters or numbers. @value{COMMONEXT}
+(The @samp{\x} escape sequence is not allowed in POSIX awk.)
+
+@quotation CAUTION
+In ISO C, the escape sequence continues until the first nonhexadecimal
+digit is seen.
+@c FIXME: Add exact version here.
+For many years, @command{gawk} would continue incorporating
+hexadecimal digits into the value until a non-hexadecimal digit
+or the end of the string was encountered.
+However, using more than two hexadecimal digits produced
+undefined results.
+As of @value{PVERSION} @strong{FIXME:} 4.3.0, only two digits
+are processed.
+@end quotation
+
+@cindex @code{\} (backslash), @code{\/} escape sequence
+@cindex backslash (@code{\}), @code{\/} escape sequence
+@item \/
+A literal slash (necessary for regexp constants only).
+This sequence is used when you want to write a regexp
+constant that contains a slash
+(such as @code{/.*:\/home\/[[:alnum:]]+:.*/}; the @samp{[[:alnum:]]}
+notation is discussed in @ref{Bracket Expressions}).
+Because the regexp is delimited by
+slashes, you need to escape any 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 sequence is used when you want to write a string
+constant that contains a double quote
+(such as @code{"He said \"hi!\" to her."}).
+Because the string is delimited by
+double quotes, you need to escape any 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
+@DBREF{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 or that is not an operator.
+
+@c 11/2014: Moved so as to not stack sidebars
+@sidebar 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
+@cindex Brian Kernighan's @command{awk}
+@table @asis
+@item Strip the backslash out
+This is what BWK @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
+@cindex @command{mawk} utility
+@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
+@end sidebar
+
+To summarize:
+
+@itemize @value{BULLET}
+@item
+The escape sequences in the preceding list 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
+
+@sidebar 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/}.
+@end sidebar
+
+@node Regexp Operators
+@section Regular Expression Operators
+@cindex regular expressions, operators
+@cindex metacharacters in regular expressions
+
+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 @DBREF{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 here stand for themselves:
+
+@c Use @asis so the docbook comes out ok. Sigh.
+@table @asis
+@cindex backslash (@code{\}), regexp operator
+@cindex @code{\} (backslash), regexp operator
+@item @code{\}
+This suppresses 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), regexp operator
+@cindex caret (@code{^}), regexp operator
+@item @code{^}
+This matches the beginning of a string. @samp{^@@chapter}
+matches @samp{@@chapter} at the beginning of a string,
+for example, 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 (the point right after a @samp{\n} newline character) 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), regexp operator
+@cindex dollar sign (@code{$}), regexp operator
+@item @code{$}
+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
+(the point right before a @samp{\n} newline character)
+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), regexp operator
+@cindex period (@code{.}), regexp operator
+@item @code{.} (period)
+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), regexp operator
+@cindex square brackets (@code{[]}), regexp operator
+@cindex bracket expressions
+@cindex character sets, See Also bracket expressions
+@cindex character lists, See bracket expressions
+@cindex character classes, See bracket expressions
+@item @code{[}@dots{}@code{]}
+This is called a @dfn{bracket expression}.@footnote{In other literature,
+you may see a bracket expression referred to as either a
+@dfn{character set}, a @dfn{character class}, or a @dfn{character list}.}
+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 bracket expression
+is given in
+@ref{Bracket Expressions}.
+
+@cindex bracket expressions, complemented
+@item @code{[^}@dots{}@code{]}
+This is a @dfn{complemented bracket expression}. 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 @code{|}
+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|[aeiouy]} matches any string
+that matches either @samp{^P} or @samp{[aeiouy]}. This means it matches
+any string that starts with @samp{P} or contains (anywhere within it)
+a lowercase English vowel.
+
+The alternation applies to the largest possible regexps on either side.
+
+@cindex @code{()} (parentheses), regexp operator
+@cindex parentheses @code{()}, regexp operator
+@item @code{(}@dots{}@code{)}
+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 @code{*}
+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.
+
+There are two subtle points to understand about how @samp{*} works.
+First, the @samp{*} applies only to the single preceding regular expression
+component (e.g., in @samp{ph*}, it applies just to the @samp{h}).
+To cause @samp{*} to apply to a larger subexpression, use parentheses:
+@samp{(ph)*} matches @samp{ph}, @samp{phph}, @samp{phphph}, and so on.
+
+Second, @samp{*} finds as many repetitions as possible. If the text
+to be matched is @samp{phhhhhhhhhhhhhhooey}, @samp{ph*} matches all of
+the @samp{h}s.
+
+@cindex @code{+} (plus sign), regexp operator
+@cindex plus sign (@code{+}), regexp operator
+@item @code{+}
+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.
+
+@cindex @code{?} (question mark), regexp operator
+@cindex question mark (@code{?}), regexp operator
+@item @code{?}
+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, regexp operator
+@item @code{@{}@var{n}@code{@}}
+@itemx @code{@{}@var{n}@code{,@}}
+@itemx @code{@{}@var{n}@code{,}@var{m}@code{@}}
+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}, @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
+Initially, because old programs may use @samp{@{} and @samp{@}} in regexp
+constants,
+@command{gawk} did @emph{not} match interval expressions
+in regexps.
+
+However, beginning with @value{PVERSION} 4.0,
+@command{gawk} does match interval expressions by default.
+This is because compatibility with POSIX has become more
+important to most @command{gawk} users than compatibility with
+old programs.
+
+For 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.}
+
+Finally, when @samp{@{} and @samp{@}} appear in regexp constants
+in a way that cannot be interpreted as an interval expression
+(such as @code{/q@{a@}/}), then they stand for themselves.
+@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, @code{/+/} 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}), interval
+expressions are not available in regular expressions.
+
+@node Bracket Expressions
+@section Using Bracket Expressions
+@cindex bracket expressions
+@cindex bracket expressions, range expressions
+@cindex range expressions (regexps)
+@cindex character lists in regular expression
+
+As mentioned earlier, a bracket expression matches any character among
+those listed between the opening and closing square brackets.
+
+Within a bracket expression, a @dfn{range expression} consists of two
+characters separated by a hyphen. It matches any single character that
+sorts between the two characters, based upon the system's native character
+set. For example, @samp{[0-9]} is equivalent to @samp{[0123456789]}.
+(See @DBREF{Ranges and Locales} for an explanation of how the POSIX
+standard and @command{gawk} have changed over time. This is mainly
+of historical interest.)
+
+@cindex @code{\} (backslash), in bracket expressions
+@cindex backslash (@code{\}), in bracket expressions
+@cindex @code{^} (caret), in bracket expressions
+@cindex caret (@code{^}), in bracket expressions
+@cindex @code{-} (hyphen), in bracket expressions
+@cindex hyphen (@code{-}), in bracket expressions
+To include one of the characters @samp{\}, @samp{]}, @samp{-}, or @samp{^} in a
+bracket expression, put a @samp{\} in front of it. For example:
+
+@example
+[d\]]
+@end example
+
+@noindent
+matches either @samp{d} or @samp{]}.
+Additionally, if you place @samp{]} right after the opening
+@samp{[}, the closing bracket is treated as one of the
+characters to be matched.
+
+@cindex POSIX @command{awk}, bracket expressions and
+@cindex Extended Regular Expressions (EREs)
+@cindex EREs (Extended Regular Expressions)
+@cindex @command{egrep} utility
+The treatment of @samp{\} in bracket expressions
+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 bracket expressions, character classes
+@cindex POSIX @command{awk}, bracket expressions and, character classes
+@dfn{Character classes} are a 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 bracket expression. 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.
+With the POSIX character classes, you can write
+@code{/[[:alnum:]]/} to match the alphabetic
+and numeric characters in your character set.
+
+@c Thanks to
+@c Date: Tue, 01 Jul 2014 07:39:51 +0200
+@c From: Hermann Peifer <peifer@gmx.eu>
+Some utilities that match regular expressions provide a nonstandard
+@code{[:ascii:]} character class; @command{awk} does not. However, you
+can simulate such a construct using @code{[\x00-\x7F]}. This matches
+all values numerically between zero and 127, which is the defined
+range of the ASCII character set. Use a complemented character list
+(@code{[^\x00-\x7F]}) to match any single-byte characters that are not
+in the ASCII range.
+
+@cindex bracket expressions, collating elements
+@cindex bracket expressions, non-ASCII
+@cindex collating elements
+Two additional special sequences can appear in bracket expressions.
+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 bracket expressions, 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 @samp{[[.ch.]]} is a regexp that matches this collating element, whereas
+@samp{[ch]} is a regexp that matches either @samp{c} or @samp{h}.
+
+@cindex bracket expressions, 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, @samp{[[=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}, bracket expressions and, character classes
+@quotation 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.
+@end quotation
+@c maybe one day ...
+
+@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 to make a change to the input
+record. (@code{sub()} replaces the first instance of any text matched
+by the first argument with the string provided as the second argument;
+@pxref{String Functions}). 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
+$ @kbd{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
+
+@cindex regular expressions, computed
+@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 then used as the
+regexp. A regexp computed in this way is called a @dfn{dynamic
+regexp} or a @dfn{computed 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.
+
+@quotation NOTE
+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.
+@end quotation
+
+@cindex regexp constants, slashes vs.@: quotes
+@cindex @code{\} (backslash), in regexp constants
+@cindex backslash (@code{\}), in regexp constants
+@cindex @code{"} (double quote), in regexp constants
+@cindex double quote (@code{"}), in 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 @value{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
+
+@sidebar Using @code{\n} in Bracket Expressions of Dynamic Regexps
+@cindex regular expressions, dynamic, with embedded newlines
+@cindex newlines, in dynamic regexps
+
+Some older versions of @command{awk} do not allow the newline
+character to be used inside a bracket expression for a dynamic regexp:
+
+@example
+$ @kbd{awk '$0 ~ "[ \t\n]"'}
+@error{} awk: newline in character class [
+@error{} ]...
+@error{} source line number 1
+@error{} context is
+@error{} $0 ~ "[ >>> \t\n]" <<<
+@end example
+
+@cindex newlines, in regexp constants
+But a newline in a regexp constant works with no problem:
+
+@example
+$ @kbd{awk '$0 ~ /[ \t\n]/'}
+@kbd{here is a sample line}
+@print{} here is a sample line
+@kbd{Ctrl-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.
+@end sidebar
+
+@node GNU Regexp Operators
+@section @command{gawk}-Specific Regexp Operators
+
+@c This section adapted (long ago) from the regex-0.12 manual
+
+@cindex regular expressions, operators, @command{gawk}
+@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{\s} (@command{gawk})
+@cindex backslash (@code{\}), @code{\s} operator (@command{gawk})
+@cindex @code{\} (backslash), @code{\s} operator (@command{gawk})
+@item \s
+Matches any whitespace character.
+Think of it as shorthand for
+@w{@samp{[[:space:]]}}.
+
+@c @cindex operators, @code{\S} (@command{gawk})
+@cindex backslash (@code{\}), @code{\S} operator (@command{gawk})
+@cindex @code{\} (backslash), @code{\S} operator (@command{gawk})
+@item \S
+Matches any character that is not whitespace.
+Think of it as shorthand for
+@w{@samp{[^[:space:]]}}.
+
+@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{@samp{[[: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{@samp{[^[: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.
+Other GNU programs, including @command{gawk},
+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), regexp operator
+@cindex caret (@code{^}), regexp operator
+@cindex @code{?} (question mark), regexp operator
+@cindex question mark (@code{?}), regexp operator
+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.
+
+@cindex regular expressions, @command{gawk}, command-line options
+@cindex @command{gawk}, command-line options, and regular expressions
+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
+@ifnotdocbook
+GNU regexp operators described
+in @ref{Regexp Operators}.
+@end ifnotdocbook
+@end ifnottex
+
+@item @code{--posix}
+Match only POSIX regexps; the GNU operators are not special
+(e.g., @samp{\w} matches a literal @samp{w}). Interval expressions
+are allowed.
+
+@cindex Brian Kernighan's @command{awk}
+@item @code{--traditional}
+Match traditional Unix @command{awk} regexps. The GNU operators
+are not special, and interval expressions are not available.
+Because BWK @command{awk} supports them,
+the POSIX character classes (@samp{[[:alnum:]]}, etc.) are available.
+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, if @option{--traditional}
+has been provided.
+Otherwise, interval expressions are available by default.
+@end table
+
+@node Case-sensitivity
+@section Case Sensitivity in Matching
+
+@cindex regular expressions, case sensitivity
+@cindex case sensitivity, regexps and
+Case is normally significant in regular expressions, both when matching
+ordinary characters (i.e., not metacharacters) and inside bracket
+expressions. 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 bracket
+expression---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, with @code{~} and @code{!~} operators
+@cindex @command{gawk}, @code{IGNORECASE} variable in
+@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, as 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 bracket expressions 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.
+
+@c @cindex ISO 8859-1
+@c @cindex ISO Latin-1
+In multibyte locales,
+the equivalences between upper-
+and lowercase characters are tested based on the wide-character values of
+the locale's character set.
+Otherwise, the characters are tested 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.@footnote{If you don't understand this,
+don't worry about it; it just means that @command{gawk} does
+the right thing.}
+
+The value of @code{IGNORECASE} has no effect if @command{gawk} is in
+compatibility mode (@pxref{Options}).
+Case is always significant in compatibility mode.
+
+@node Regexp Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+Regular expressions describe sets of strings to be matched.
+In @command{awk}, regular expression constants are written enclosed
+between slashes: @code{/}@dots{}@code{/}.
+
+@item
+Regexp constants may be used standalone in patterns and
+in conditional expressions, or as part of matching expressions
+using the @samp{~} and @samp{!~} operators.
+
+@item
+Escape sequences let you represent nonprintable characters and
+also let you represent regexp metacharacters as literal characters
+to be matched.
+
+@item
+Regexp operators provide grouping, alternation, and repetition.
+
+@item
+Bracket expressions give you a shorthand for specifying sets
+of characters that can match at a particular point in a regexp.
+Within bracket expressions, POSIX character classes let you specify
+certain groups of characters in a locale-independent fashion.
+
+@item
+Regular expressions match the leftmost longest text in the string being
+matched. This matters for cases where you need to know the extent of
+the match, such as for text substitution and when the record separator
+is a regexp.
+
+@item
+Matching expressions may use dynamic regexps (i.e., string values
+treated as regular expressions).
+
+@item
+@command{gawk}'s @code{IGNORECASE} variable lets you control the
+case sensitivity of regexp matching. In other @command{awk}
+versions, use @code{tolower()} or @code{toupper()}.
+
+@end itemize
+
+
+@node Reading Files
+@chapter Reading Input Files
+
+@cindex reading input files
+@cindex input files, reading
+@cindex input files
+@cindex @code{FILENAME} variable
+In the typical @command{awk} program,
+@command{awk} reads all input 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 predefined 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.
+* Splitting By Content:: Defining Fields By Content
+* Multiple Line:: Reading multiline records.
+* Getline:: Reading files under explicit program control
+ using the @code{getline} function.
+* Read Timeout:: Reading input with a timeout.
+* Command-line directories:: What happens if you put a directory on the
+ command line.
+* Input Summary:: Input summary.
+* Input Exercises:: Exercises.
+@end menu
+
+@node Records
+@section How Input Is Split into Records
+
+@cindex input, splitting into records
+@cindex records, splitting input into
+@cindex @code{NR} variable
+@cindex @code{FNR} variable
+@command{awk} divides the input for your program into records and fields.
+It keeps track of the number of records that have been read so far from
+the current input file. This value is stored in a predefined variable
+called @code{FNR}, which is reset to zero every time a new file is started.
+Another predefined variable, @code{NR}, records 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.
+
+@menu
+* awk split records:: How standard @command{awk} splits records.
+* gawk split records:: How @command{gawk} splits records.
+@end menu
+
+@node awk split records
+@subsection Record Splitting with Standard @command{awk}
+
+@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 predefined 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:
+
+@example
+awk 'BEGIN @{ RS = "u" @}
+ @{ print $0 @}' mail-list
+@end example
+
+@noindent
+changes the value of @code{RS} to @samp{u}, before reading any input.
+This is a string whose first character is the letter ``u''; as a result, records
+are separated by the letter ``u.'' 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 @samp{u} changed to a newline. Here are the results of running
+the program on @file{mail-list}:
+
+@example
+$ @kbd{awk 'BEGIN @{ RS = "u" @}}
+> @kbd{@{ print $0 @}' mail-list}
+@print{} Amelia 555-5553 amelia.zodiac
+@print{} sq
+@print{} e@@gmail.com F
+@print{} Anthony 555-3412 anthony.assert
+@print{} ro@@hotmail.com A
+@print{} Becky 555-7685 becky.algebrar
+@print{} m@@gmail.com A
+@print{} Bill 555-1675 bill.drowning@@hotmail.com A
+@print{} Broderick 555-0542 broderick.aliq
+@print{} otiens@@yahoo.com R
+@print{} Camilla 555-2912 camilla.inf
+@print{} sar
+@print{} m@@skynet.be R
+@print{} Fabi
+@print{} s 555-1234 fabi
+@print{} s.
+@print{} ndevicesim
+@print{} s@@
+@print{} cb.ed
+@print{} F
+@print{} J
+@print{} lie 555-6699 j
+@print{} lie.perscr
+@print{} tabor@@skeeve.com F
+@print{} Martin 555-6480 martin.codicib
+@print{} s@@hotmail.com A
+@print{} Sam
+@print{} el 555-3430 sam
+@print{} el.lanceolis@@sh
+@print{} .ed
+@print{} A
+@print{} Jean-Pa
+@print{} l 555-2127 jeanpa
+@print{} l.campanor
+@print{} m@@ny
+@print{} .ed
+@print{} R
+@print{}
+@end example
+
+@noindent
+Note that the entry for the name @samp{Bill} is not split.
+In the original @value{DF}
+(@pxref{Sample Data Files}),
+the line looks like this:
+
+@example
+Bill 555-1675 bill.drowning@@hotmail.com A
+@end example
+
+@noindent
+It contains no @samp{u} so there is no reason to split the record,
+unlike the others which have one or more occurrences of the @samp{u}.
+In fact, this record is treated as part of the previous record;
+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="u" mail-list
+@end example
+
+@noindent
+This sets @code{RS} to @samp{u} before processing @file{mail-list}.
+
+Using an alphabetic character such as @samp{u} for the record separator
+is highly likely to produce strange results.
+Using an unusual character such as @samp{/} is more likely to
+produce correct behavior in the majority of cases, but there
+are no guarantees. The moral is: Know Your Data.
+
+When using regular characters as the record separator,
+there is one unusual case that occurs when @command{gawk} is
+being fully POSIX-compliant (@pxref{Options}).
+Then, the following (extreme) pipeline prints a surprising @samp{1}:
+
+@example
+$ @kbd{echo | gawk --posix '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.
+(In the normal case, @command{gawk} treats the newline as whitespace,
+printing @samp{0} as the result. Most other versions of @command{awk}
+also act this way.)
+
+@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 empty strings
+@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.
+@DBXREF{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 @command{gawk}, @code{RT} variable in
+@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}.
+
+@node gawk split records
+@subsection Record Splitting with @command{gawk}
+
+@cindex common extensions, @code{RS} as a regexp
+@cindex extensions, common@comma{} @code{RS} as a regexp
+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}). @value{COMMONEXT}
+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.
+
+If the input file ended without any text that matches @code{RS},
+@command{gawk} sets @code{RT} to the null string.
+
+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
+$ @kbd{echo record 1 AAAA record 2 BBBB record 3 |}
+> @kbd{gawk 'BEGIN @{ RS = "\n|( *[[:upper:]]+ *)" @}}
+> @kbd{@{ 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 square brackets delineate the contents of @code{RT}, letting you
+see the leading and trailing whitespace. The final value of
+@code{RT} is a newline.
+@DBXREF{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.
+It is thus best to avoid anchor metacharacters 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} determines the end of the record.
+
+@sidebar @code{RS = "\0"} Is Not Portable
+@cindex portability, data files 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.
+
+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.
+This works for certain special files, such as @file{/proc/environ} on
+GNU/Linux systems, where the @sc{nul} character is in fact the record separator.
+However, this usage is @emph{not} portable
+to most other @command{awk} implementations.
+
+@cindex dark corner, strings, storing
+Almost 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}
+
+It happens that recent versions of @command{mawk} can use the @sc{nul}
+character as a record separator. However, this is a special case:
+@command{mawk} does not allow embedded @sc{nul} characters in strings.
+(This may change in a future version of @command{mawk}.)
+
+@cindex records, treating files as
+@cindex treating files, as single records
+@DBXREF{Readfile Function} for an interesting way to read
+whole files. If you are using @command{gawk}, see @DBREF{Extension Sample
+Readfile} for another option.
+@end sidebar
+
+@node Fields
+@section Examining Fields
+
+@cindex examining fields
+@cindex fields
+@cindex accessing fields
+@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 @command{awk} utility 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
+that are considered whitespace by other languages
+(such as formfeed, vertical tab, etc.) 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 field operator @code{$}
+@cindex @code{$} (dollar sign), @code{$} field operator
+@cindex dollar sign (@code{$}), @code{$} field operator
+@cindex field operators@comma{} dollar sign as
+You use a dollar-sign (@samp{$})
+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 127th 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 predefined 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. Use it
+when you are not interested in specific fields.
+Here are some more examples:
+
+@example
+$ @kbd{awk '$1 ~ /li/ @{ print $0 @}' mail-list}
+@print{} Amelia 555-5553 amelia.zodiacusque@@gmail.com F
+@print{} Julie 555-6699 julie.perscrutabor@@skeeve.com F
+@end example
+
+@noindent
+This example prints each record in the file @file{mail-list} whose first
+field contains the string @samp{li}.
+
+By contrast, the following example looks for @samp{li} in @emph{the
+entire record} and prints the first and last fields for each matching
+input record:
+
+@example
+$ @kbd{awk '/li/ @{ print $1, $NF @}' mail-list}
+@print{} Amelia F
+@print{} Broderick R
+@print{} Julie F
+@print{} Samuel A
+@end example
+
+@node Nonconstant Fields
+@section Nonconstant Field Numbers
+@cindex fields, numbers
+@cindex field numbers
+
+A field number need not 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, and so on. 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) @}' mail-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@footnote{A @dfn{binary operator}, such as @samp{*} for
+multiplication, is one that takes two operands. The distinction
+is required, because @command{awk} also has unary (one-operand)
+and ternary (three-operand) operators.}
+in the field-number expression. This example, then, prints the
+type of relationship (the fourth field) for every line of the file
+@file{mail-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}). Thus, 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
+
+@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
+$ @kbd{awk '@{ nboxes = $3 ; $3 = $3 - 10}
+> @kbd{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 @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
+$ @kbd{awk '@{ $2 = $2 - 10; print $0 @}' inventory-shipped}
+@print{} Jan 3 25 15 115
+@print{} Feb 5 32 24 226
+@print{} Mar 5 24 34 228
+@dots{}
+@end example
+
+It is also possible to assign contents to fields that are out
+of range. For example:
+
+@example
+$ @kbd{awk '@{ $6 = ($5 + $4 + $3 + $2)}
+> @kbd{ 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. (@DBXREF{If Statement}
+for more information about @command{awk}'s @code{if-else} statements.
+@DBXREF{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
+$ @kbd{echo a b c d | awk '@{ OFS = ":"; $2 = ""}
+> @kbd{print $0; print NF @}'}
+@print{} a::c:d
+@print{} 4
+@end example
+
+@noindent
+The field is still there; it just has an empty value, delimited by
+the two colons between @samp{a} and @samp{c}.
+This example shows what happens if you create a new field:
+
+@example
+$ @kbd{echo a b c d | awk '@{ OFS = ":"; $2 = ""; $6 = "new"}
+> @kbd{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.
+
+@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
+$ @kbd{echo a b c d e f | awk '@{ print "NF =", NF;}
+> @kbd{ NF = 3; print $0 @}'}
+@print{} NF = 6
+@print{} a b c
+@end example
+
+@cindex portability, @code{NF} variable@comma{} decrementing
+@quotation CAUTION
+Some versions of @command{awk} don't
+rebuild @code{$0} when @code{NF} is decremented.
+@end quotation
+
+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} to 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}).
+
+@sidebar Understanding @code{$0}
+
+It is important to remember that @code{$0} is the @emph{full}
+record, exactly as it was read from the input. This includes
+any leading or trailing whitespace, and the exact whitespace (or other
+characters) that separate the fields.
+
+It is a common error to try to change the field separators
+in a record simply by setting @code{FS} and @code{OFS}, and then
+expecting a plain @samp{print} or @samp{print $0} to print the
+modified record.
+
+But this does not work, because nothing was done to change the record
+itself. Instead, you must force the record to be rebuilt, typically
+with a statement such as @samp{$1 = $1}, as described earlier.
+@end sidebar
+
+
+@node Field Separators
+@section Specifying How Fields Are Separated
+
+@menu
+* Default Field Splitting:: How fields are normally separated.
+* 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.
+* Full Line Fields:: Making the full line be a single field.
+* Field Splitting Summary:: Some final points and a summary table.
+@end menu
+
+@cindex @code{FS} variable
+@cindex fields, separating
+@cindex field separators
+@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 predefined 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 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.)
+
+
+@node Default Field Splitting
+@subsection Whitespace Normally Separates Fields
+
+@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
+
+@cindex regular expressions, as field separators
+@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
+$ @kbd{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
+$ @kbd{echo ' a b c d ' | awk 'BEGIN @{ FS = "[ \t\n]+" @}}
+> @kbd{@{ 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 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
+$ @kbd{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} (which is a space by default).
+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}.
+
+@cindex @code{FS}, containing @code{^}
+@cindex @code{^} (caret), in @code{FS}
+@cindex dark corner, @code{^}, in @code{FS}
+There is an additional subtlety to be aware of when using regular expressions
+for field splitting.
+It is not well specified in the POSIX standard, or anywhere else, what @samp{^}
+means when splitting fields. Does the @samp{^} match only at the beginning of
+the entire record? Or is each field separator a new string? It turns out that
+different @command{awk} versions answer this question differently, and you
+should not rely on any specific behavior in your programs.
+@value{DARKCORNER}
+
+@cindex Brian Kernighan's @command{awk}
+As a point of information, BWK @command{awk} allows @samp{^}
+to match only at the beginning of the record. @command{gawk}
+also works this way. For example:
+
+@example
+$ @kbd{echo 'xxAA xxBxx C' |}
+> @kbd{gawk -F '(^x+)|( +)' '@{ for (i = 1; i <= NF; i++)}
+> @kbd{ printf "-->%s<--\n", $i @}'}
+@print{} --><--
+@print{} -->AA<--
+@print{} -->xxBxx<--
+@print{} -->C<--
+@end example
+
+@node Single Character Fields
+@subsection Making Each Character a Separate Field
+
+@cindex common extensions, single character fields
+@cindex extensions, common@comma{} single character fields
+@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}. @value{COMMONEXT}
+In this case,
+each individual character in the record becomes a separate field.
+For example:
+
+@example
+$ @kbd{echo a b | gawk 'BEGIN @{ FS = "" @}}
+> @kbd{@{}
+> @kbd{for (i = 1; i <= NF; i = i + 1)}
+> @kbd{print "Field", i, "is", $i}
+> @kbd{@}'}
+@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 @code{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 @option{-F} option, command-line
+@cindex field separator, 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.
+
+The value used for the argument to @option{-F} is processed in exactly the
+same way as assignments to the predefined 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 separator
+@cindex backslash (@code{\}), as field separator
+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.
+Use @samp{-F '\t'} when not in compatibility mode to specify that TABs
+separate fields.
+
+As an example, let's use an @command{awk} program file called @file{edu.awk}
+that contains the pattern @code{/edu/} and the action @samp{print $1}:
+
+@example
+/edu/ @{ print $1 @}
+@end example
+
+Let's also set @code{FS} to be the @samp{-} character and run the
+program on the file @file{mail-list}. The following command prints a
+list of the names of the people that work at or attend a university, and
+the first three digits of their phone numbers:
+
+@example
+$ @kbd{awk -F- -f edu.awk mail-list}
+@print{} Fabius 555
+@print{} Samuel 555
+@print{} Jean
+@end example
+
+@noindent
+Note the third line of output. The third line
+in the original file looked like this:
+
+@example
+Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R
+@end example
+
+The @samp{-} as part of the person'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 login name and the second is the user's
+encrypted or shadow password. (A shadow password is indicated by the
+presence of a single @samp{x} in the second field.) A password file
+entry might look like this:
+
+@cindex Robbins, Arnold
+@example
+arnold:x:2076:10:Arnold Robbins:/home/arnold:/bin/bash
+@end example
+
+The following program searches the system password file and prints
+the entries for users whose full name is not indicated:
+
+@example
+awk -F: '$5 == ""' /etc/passwd
+@end example
+
+@node Full Line Fields
+@subsection Making the Full Line Be a Single Field
+
+Occasionally, it's useful to treat the whole input line as a
+single field. This can be done easily and portably simply by
+setting @code{FS} to @code{"\n"} (a newline):@footnote{Thanks to
+Andrew Schorr for this tip.}
+
+@example
+awk -F'\n' '@var{program}' @var{files @dots{}}
+@end example
+
+@noindent
+When you do this, @code{$1} is the same as @code{$0}.
+
+@sidebar Changing @code{FS} Does Not Affect the Fields
+
+@cindex POSIX @command{awk}, field separators and
+@cindex field separator, 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 older 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 the full first line of the file, something like:
+
+@example
+root:x:0:0:Root:/:
+@end example
+@end sidebar
+
+@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 list 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 common extension; it is not specified by the POSIX standard.)
+@end table
+
+@sidebar @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.
+@end sidebar
+
+
+@node Constant Size
+@section Reading Fixed-Width Data
+
+@cindex data, fixed-width
+@cindex fixed-width data
+@cindex advanced features, fixed-width data
+
+@c O'Reilly doesn't like it as a note the first thing in the section.
+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.
+
+@command{gawk} provides 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
+@cindex @command{gawk}, @code{FIELDWIDTHS} variable in
+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 this input, converts the idle time to
+number of seconds, and prints out the first two fields and the calculated
+idle time:
+
+@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
+
+@quotation NOTE
+The preceding program uses a number of @command{awk} features that
+haven't been introduced yet.
+@end quotation
+
+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!)
+
+@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 if (PROCINFO["FS"] == "FIELDWIDTHS")
+ @var{fixed-width field splitting} @dots{}
+else
+ @var{content-based field splitting} @dots{} @ii{(see next @value{SECTION})}
+@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
+(@DBPXREF{Passwd Functions}
+for an example of such a function).
+
+@node Splitting By Content
+@section Defining Fields by Content
+
+@c O'Reilly doesn't like it as a note the first thing in the section.
+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.
+
+@cindex advanced features, specifying field content
+Normally, when using @code{FS}, @command{gawk} defines the fields as the
+parts of the record that occur in between each field separator. In other
+words, @code{FS} defines what a field @emph{is not}, instead of what a field
+@emph{is}.
+However, there are times when you really want to define the fields by
+what they are, and not by what they are not.
+
+The most notorious such case
+is so-called @dfn{comma-separated values} (CSV) data. Many spreadsheet programs,
+for example, can export their data into text files, where each record is
+terminated with a newline, and fields are separated by commas. If only
+commas separated the data, there wouldn't be an issue. The problem comes when
+one of the fields contains an @emph{embedded} comma.
+In such cases, most programs embed the field in double quotes.@footnote{The
+CSV format lacked a formal standard definition for many years.
+@uref{http://www.ietf.org/rfc/rfc4180.txt, RFC 4180}
+standardizes the most common practices.}
+So we might have data like this:
+
+@example
+@c file eg/misc/addresses.csv
+Robbins,Arnold,"1234 A Pretty Street, NE",MyTown,MyState,12345-6789,USA
+@c endfile
+@end example
+
+@cindex @command{gawk}, @code{FPAT} variable in
+@cindex @code{FPAT} variable
+The @code{FPAT} variable offers a solution for cases like this.
+The value of @code{FPAT} should be a string that provides a regular expression.
+This regular expression describes the contents of each field.
+
+In the case of CSV data as presented here, each field is either ``anything that
+is not a comma,'' or ``a double quote, anything that is not a double quote, and a
+closing double quote.'' If written as a regular expression constant
+(@pxref{Regexp}),
+we would have @code{/([^,]+)|("[^"]+")/}.
+Writing this as a string requires us to escape the double quotes, leading to:
+
+@example
+FPAT = "([^,]+)|(\"[^\"]+\")"
+@end example
+
+Putting this to use, here is a simple program to parse the data:
+
+@example
+@c file eg/misc/simple-csv.awk
+BEGIN @{
+ FPAT = "([^,]+)|(\"[^\"]+\")"
+@}
+
+@{
+ print "NF = ", NF
+ for (i = 1; i <= NF; i++) @{
+ printf("$%d = <%s>\n", i, $i)
+ @}
+@}
+@c endfile
+@end example
+
+When run, we get the following:
+
+@example
+$ @kbd{gawk -f simple-csv.awk addresses.csv}
+NF = 7
+$1 = <Robbins>
+$2 = <Arnold>
+$3 = <"1234 A Pretty Street, NE">
+$4 = <MyTown>
+$5 = <MyState>
+$6 = <12345-6789>
+$7 = <USA>
+@end example
+
+Note the embedded comma in the value of @code{$3}.
+
+A straightforward improvement when processing CSV data of this sort
+would be to remove the quotes when they occur, with something like this:
+
+@example
+if (substr($i, 1, 1) == "\"") @{
+ len = length($i)
+ $i = substr($i, 2, len - 2) # Get text within the two quotes
+@}
+@end example
+
+As with @code{FS}, the @code{IGNORECASE} variable (@pxref{User-modified})
+affects field splitting with @code{FPAT}.
+
+Assigning a value to @code{FPAT} overrides field splitting
+with @code{FS} and with @code{FIELDWIDTHS}.
+Similar to @code{FIELDWIDTHS}, the value of @code{PROCINFO["FS"]}
+will be @code{"FPAT"} if content-based field splitting is being used.
+
+@quotation NOTE
+Some programs export CSV data that contains embedded newlines between
+the double quotes. @command{gawk} provides no way to deal with this.
+Even though a formal specification for CSV data exists, there isn't much
+more to be done;
+the @code{FPAT} mechanism provides an elegant solution for the majority
+of cases, and the @command{gawk} developers are satisfied with that.
+@end quotation
+
+As written, the regexp used for @code{FPAT} requires that each field
+have a least one character. A straightforward modification
+(changing changed the first @samp{+} to @samp{*}) allows fields to be empty:
+
+@example
+FPAT = "([^,]*)|(\"[^\"]+\")"
+@end example
+
+Finally, the @code{patsplit()} function makes the same functionality
+available for splitting regular strings (@pxref{String Functions}).
+
+To recap, @command{gawk} provides three independent methods
+to split input records into fields. @command{gawk} uses whichever
+mechanism was last chosen based on which of the three
+variables---@code{FS}, @code{FIELDWIDTHS}, and @code{FPAT}---was
+last assigned to.
+
+@node Multiple Line
+@section Multiple-Line Records
+
+@cindex multiple-line records
+@cindex records, multiline
+@cindex input, multiline records
+@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
+However, 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 separator, in multiline records
+@cindex @code{FS}, 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 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 = @w{" "}}.}
+
+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 separator 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
+$ @kbd{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
+
+@DBXREF{Labels Program} for a more realistic program dealing with
+address lists. The following list 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.
+When @code{FS} is a single character, then
+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 @command{gawk}, @code{RT} variable in
+@cindex @code{RT} variable
+If not in compatibility mode (@pxref{Options}), @command{gawk} sets
+@code{RT} to the input text that matched the value specified by @code{RS}.
+But if the input file ended without any text that matches @code{RS},
+then @command{gawk} sets @code{RT} to the null string.
+
+@node Getline
+@section Explicit Input with @code{getline}
+
+@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 keyboard, 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
+@ifinfo
+this @value{DOCUMENT}
+@end ifinfo
+@ifhtml
+this @value{DOCUMENT}
+@end ifhtml
+@ifnotinfo
+@ifnothtml
+Parts I and II
+@end ifnothtml
+@end ifnotinfo
+and have a good knowledge of how @command{awk} works.
+
+@cindex @command{gawk}, @code{ERRNO} variable in
+@cindex @code{ERRNO} variable, with @command{getline} command
+@cindex differences in @command{awk} and @command{gawk}, @code{getline} command
+@cindex @code{getline} command, return values
+@cindex @option{--sandbox} option, input redirection with @code{getline}
+
+The @code{getline} command returns 1 if it finds a record and 0 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.
+
+@quotation NOTE
+When @option{--sandbox} is specified (@pxref{Options}),
+reading lines from files, pipes, and coprocesses is disabled.
+@end quotation
+
+@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
+# Remove text between /* and */, inclusive
+@{
+ if ((i = index($0, "/*")) != 0) @{
+ out = substr($0, 1, i - 1) # leading part of the string
+ rest = substr($0, i + 2) # ... */ ...
+ j = index(rest, "*/") # is */ in trailing part?
+ if (j > 0) @{
+ rest = substr(rest, j + 2) # remove comment
+ @} else @{
+ while (j == 0) @{
+ # get more text
+ if (getline <= 0) @{
+ print("unexpected EOF or error:", ERRNO) > "/dev/stderr"
+ exit
+ @}
+ # build up the line using string concatenation
+ rest = rest $0
+ j = index(rest, "*/") # is */ in trailing part?
+ if (j != 0) @{
+ rest = substr(rest, j + 2)
+ break
+ @}
+ @}
+ @}
+ # build up the output line using string concatenation
+ $0 = out rest
+ @}
+ print $0
+@}
+@end example
+
+@c 8/2014: Here is some sample input:
+@ignore
+mon/*comment*/key
+rab/*commen
+t*/bit
+horse /*comment*/more text
+part 1 /*comment*/part 2 /*comment*/part 3
+no comment
+@end ignore
+
+This @command{awk} program deletes C-style comments (@samp{/* @dots{}
+*/}) from the input.
+It uses a number of features we haven't covered yet, including
+string concatenation
+(@pxref{Concatenation})
+and the @code{index()} and @code{substr()} built-in
+functions
+(@pxref{String Functions}).
+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.)
+
+This form of the @code{getline} command sets @code{NF},
+@code{NR}, @code{FNR}, @code{RT}, 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 @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}, @code{FNR}, and @code{RT} (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 @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}.
+@code{RT} is also set.
+
+@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 (not discussed yet; @pxref{Concatenation})
+is not parenthesized. You should write it as @samp{getline < (dir "/" file)} if
+you want your program to be portable to all @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 earlier, @var{file}
+is a string-valued expression that specifies the file from which to read.
+
+In this version of @code{getline}, none of the predefined variables are
+changed and the record is not split into fields. The only variable
+changed is @var{var}.@footnote{This is not quite true. @code{RT} could
+be changed if @code{RS} is a regular expression.}
+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 @code{@@include} line.
+
+The @code{close()} function is called to ensure that if two identical
+@code{@@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
+@code{@@include} statements
+(i.e., @code{@@include} statements in included files)
+the way a true macro preprocessor would.
+@DBXREF{Igawk Program} for a program
+that does handle nested @code{@@include} statements.
+
+@node Getline/Pipe
+@subsection Using @code{getline} from a Pipe
+
+@c From private email, dated October 2, 1988. Used by permission, March 2013.
+@cindex Kernighan, Brian
+@quotation
+@i{Omniscience has much to recommend it.
+Failing that, attention to details would be useful.}
+@author Brian Kernighan
+@end quotation
+
+@cindex @code{|} (vertical bar), @code{|} operator (I/O)
+@cindex vertical bar (@code{|}), @code{|} operator (I/O)
+@cindex input pipeline
+@cindex pipe, 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) # Remove "@@execute"
+ while ((tmp | getline) > 0)
+ print
+ close(tmp)
+ @} else
+ print
+@}
+@end example
+
+@noindent
+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
+@ifnotdocbook
+@xref{Close Files And Pipes}.
+@end ifnotdocbook
+@end ifnottex
+@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 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.
+@code{RT} is set.
+
+@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 all @command{awk} implementations.
+
+@cindex Brian Kernighan's @command{awk}
+@cindex @command{mawk} utility
+@quotation NOTE
+Unfortunately, @command{gawk} has not been consistent in its treatment
+of a construct like @samp{@w{"echo "} "date" | getline}.
+Most versions, including the current version, treat it at as
+@samp{@w{("echo "} "date") | getline}.
+(This is also how BWK @command{awk} behaves.)
+Some versions changed and treated it as
+@samp{@w{"echo "} ("date" | getline)}.
+(This is how @command{mawk} behaves.)
+In short, @emph{always} use explicit parentheses, and then you won't
+have to worry.
+@end quotation
+
+@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 predefined variables are
+changed and the record is not split into fields. However, @code{RT} is set.
+
+@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 to 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} and @code{RT}.
+
+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 predefined variables are
+changed and the record is not split into fields. The only variable
+changed is @var{var}.
+However, @code{RT} is set.
+
+@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 @value{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
+Some very old @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}
+(See @ref{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{NF} 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.
+
+@item
+@DBREF{Getline Summary} presents a table summarizing the
+@code{getline} variants and which variables they can affect.
+It is worth noting that those variants which do not use redirection
+can cause @code{FILENAME} to be updated if they cause
+@command{awk} to start reading a new input file.
+
+@item
+@cindex Moore, Duncan
+If the variable being assigned is an expression with side effects,
+different versions of @command{awk} behave differently upon encountering
+end-of-file. Some versions don't evaluate the expression; many versions
+(including @command{gawk}) do. Here is an example, due to Duncan Moore:
+
+@ignore
+Date: Sun, 01 Apr 2012 11:49:33 +0100
+From: Duncan Moore <duncan.moore@@gmx.com>
+@end ignore
+
+@example
+BEGIN @{
+ system("echo 1 > f")
+ while ((getline a[++c] < "f") > 0) @{ @}
+ print c
+@}
+@end example
+
+@noindent
+Here, the side effect is the @samp{++c}. Is @code{c} incremented if
+end of file is encountered, before the element in @code{a} is assigned?
+
+@command{gawk} treats @code{getline} like a function call, and evaluates
+the expression @samp{a[++c]} before attempting to read from @file{f}.
+However, some versions of @command{awk} only evaluate the expression once they
+know that there is a string value to be assigned.
+@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 predefined variables are set by each one,
+and whether the variant is standard or a @command{gawk} extension.
+Note: for each variant, @command{gawk} sets the @code{RT} predefined variable.
+
+@float Table,table-getline-variants
+@caption{@code{getline} variants and what they set}
+@multitable @columnfractions .33 .38 .27
+@headitem Variant @tab Effect @tab @command{awk} / @command{gawk}
+@item @code{getline} @tab Sets @code{$0}, @code{NF}, @code{FNR}, @code{NR}, and @code{RT} @tab @command{awk}
+@item @code{getline} @var{var} @tab Sets @var{var}, @code{FNR}, @code{NR}, and @code{RT} @tab @command{awk}
+@item @code{getline <} @var{file} @tab Sets @code{$0}, @code{NF}, and @code{RT} @tab @command{awk}
+@item @code{getline @var{var} < @var{file}} @tab Sets @var{var} and @code{RT} @tab @command{awk}
+@item @var{command} @code{| getline} @tab Sets @code{$0}, @code{NF}, and @code{RT} @tab @command{awk}
+@item @var{command} @code{| getline} @var{var} @tab Sets @var{var} and @code{RT} @tab @command{awk}
+@item @var{command} @code{|& getline} @tab Sets @code{$0}, @code{NF}, and @code{RT} @tab @command{gawk}
+@item @var{command} @code{|& getline} @var{var} @tab Sets @var{var} and @code{RT} @tab @command{gawk}
+@end multitable
+@end float
+
+@node Read Timeout
+@section Reading Input with a Timeout
+@cindex timeout, reading input
+
+@cindex differences in @command{awk} and @command{gawk}, read timeouts
+This @value{SECTION} describes a feature that is specific to @command{gawk}.
+
+You may specify a timeout in milliseconds for reading input from the keyboard,
+a pipe, or two-way communication, including TCP/IP sockets. This can be done
+on a per input, command, or connection basis, by setting a special element
+in the @code{PROCINFO} array (@pxref{Auto-set}):
+
+@example
+PROCINFO["input_name", "READ_TIMEOUT"] = @var{timeout in milliseconds}
+@end example
+
+When set, this causes @command{gawk} to time out and return failure
+if no data is available to read within the specified timeout period.
+For example, a TCP client can decide to give up on receiving
+any response from the server after a certain amount of time:
+
+@example
+Service = "/inet/tcp/0/localhost/daytime"
+PROCINFO[Service, "READ_TIMEOUT"] = 100
+if ((Service |& getline) > 0)
+ print $0
+else if (ERRNO != "")
+ print ERRNO
+@end example
+
+Here is how to read interactively from the user@footnote{This assumes
+that standard input is the keyboard.} without waiting
+for more than five seconds:
+
+@example
+PROCINFO["/dev/stdin", "READ_TIMEOUT"] = 5000
+while ((getline < "/dev/stdin") > 0)
+ print $0
+@end example
+
+@command{gawk} terminates the read operation if input does not
+arrive after waiting for the timeout period, returns failure
+and sets @code{ERRNO} to an appropriate string value.
+A negative or zero value for the timeout is the same as specifying
+no timeout at all.
+
+A timeout can also be set for reading from the keyboard in the implicit
+loop that reads input records and matches them against patterns,
+like so:
+
+@example
+$ @kbd{gawk 'BEGIN @{ PROCINFO["-", "READ_TIMEOUT"] = 5000 @}}
+> @kbd{@{ print "You entered: " $0 @}'}
+@kbd{gawk}
+@print{} You entered: gawk
+@end example
+
+In this case, failure to respond within five seconds results in the following
+error message:
+
+@example
+@error{} gawk: cmd. line:2: (FILENAME=- FNR=1) fatal: error reading input file `-': Connection timed out
+@end example
+
+The timeout can be set or changed at any time, and will take effect on the
+next attempt to read from the input device. In the following example,
+we start with a timeout value of one second, and progressively
+reduce it by one-tenth of a second until we wait indefinitely
+for the input to arrive:
+
+@example
+PROCINFO[Service, "READ_TIMEOUT"] = 1000
+while ((Service |& getline) > 0) @{
+ print $0
+ PROCINFO[Service, "READ_TIMEOUT"] -= 100
+@}
+@end example
+
+@quotation NOTE
+You should not assume that the read operation will block
+exactly after the tenth record has been printed. It is possible that
+@command{gawk} will read and buffer more than one record's
+worth of data the first time. Because of this, changing the value
+of timeout like in the preceding example is not very useful.
+@end quotation
+
+If the @code{PROCINFO} element is not present and the
+@env{GAWK_READ_TIMEOUT} environment variable exists,
+@command{gawk} uses its value to initialize the timeout value.
+The exclusive use of the environment variable to specify timeout
+has the disadvantage of not being able to control it
+on a per command or connection basis.
+
+@command{gawk} considers a timeout event to be an error even though
+the attempt to read from the underlying device may
+succeed in a later attempt. This is a limitation, and it also
+means that you cannot use this to multiplex input from
+two or more sources.
+
+Assigning a timeout value prevents read operations from
+blocking indefinitely. But bear in mind that there are other ways
+@command{gawk} can stall waiting for an input device to be ready.
+A network client can sometimes take a long time to establish
+a connection before it can start reading any data,
+or the attempt to open a FIFO special file for reading can block
+indefinitely until some other process opens it for writing.
+
+@node Command-line directories
+@section Directories on the Command Line
+@cindex differences in @command{awk} and @command{gawk}, command-line directories
+@cindex directories, command-line
+@cindex command line, directories on
+
+According to the POSIX standard, files named on the @command{awk}
+command line must be text files; it is a fatal error if they are not.
+Most versions of @command{awk} treat a directory on the command line as
+a fatal error.
+
+By default, @command{gawk} produces a warning for a directory on the
+command line, but otherwise ignores it. This makes it easier to use
+shell wildcards with your @command{awk} program:
+
+@example
+$ @kbd{gawk -f whizprog.awk *} @ii{Directories could kill this program}
+@end example
+
+If either of the @option{--posix}
+or @option{--traditional} options is given, then @command{gawk} reverts
+to treating a directory on the command line as a fatal error.
+
+@DBXREF{Extension Sample Readdir} for a way to treat directories
+as usable data from an @command{awk} program.
+
+@node Input Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+Input is split into records based on the value of @code{RS}.
+The possibilities are as follows:
+
+@multitable @columnfractions .25 .35 .40
+@headitem Value of @code{RS} @tab Records are split on @dots{} @tab @command{awk} / @command{gawk}
+@item Any single character @tab That character @tab @command{awk}
+@item The empty string (@code{""}) @tab Runs of two or more newlines @tab @command{awk}
+@item A regexp @tab Text that matches the regexp @tab @command{gawk}
+@end multitable
+
+@item
+@code{FNR} indicates how many records have been read from the current input file;
+@code{NR} indicates how many records have been read in total.
+
+@item
+@command{gawk} sets @code{RT} to the text matched by @code{RS}.
+
+@item
+After splitting the input into records, @command{awk} further splits
+the record into individual fields, named @code{$1}, @code{$2}, and so
+on. @code{$0} is the whole record, and @code{NF} indicates how many
+fields there are. The default way to split fields is between whitespace
+characters.
+
+@item
+Fields may be referenced using a variable, as in @code{$NF}. Fields
+may also be assigned values, which causes the value of @code{$0} to be
+recomputed when it is later referenced. Assigning to a field with a number
+greater than @code{NF} creates the field and rebuilds the record, using
+@code{OFS} to separate the fields. Incrementing @code{NF} does the same
+thing. Decrementing @code{NF} throws away fields and rebuilds the record.
+
+@item
+Field splitting is more complicated than record splitting:
+
+@multitable @columnfractions .40 .45 .15
+@headitem Field separator value @tab Fields are split @dots{} @tab @command{awk} / @command{gawk}
+@item @code{FS == " "} @tab On runs of whitespace @tab @command{awk}
+@item @code{FS == @var{any single character}} @tab On that character @tab @command{awk}
+@item @code{FS == @var{regexp}} @tab On text matching the regexp @tab @command{awk}
+@item @code{FS == ""} @tab Each individual character is a separate field @tab @command{gawk}
+@item @code{FIELDWIDTHS == @var{list of columns}} @tab Based on character position @tab @command{gawk}
+@item @code{FPAT == @var{regexp}} @tab On the text surrounding text matching the regexp @tab @command{gawk}
+@end multitable
+
+@item
+Using @samp{FS = "\n"} causes the entire record to be a single field
+(assuming that newlines separate records).
+
+@item
+@code{FS} may be set from the command line using the @option{-F} option.
+This can also be done using command-line variable assignment.
+
+@item
+Use @code{PROCINFO["FS"]} to see how fields are being split.
+
+@item
+Use @code{getline} in its various forms to read additional records,
+from the default input stream, from a file, or from a pipe or coprocess.
+
+@item
+Use @code{PROCINFO[@var{file}, "READ_TIMEOUT"]} to cause reads to timeout
+for @var{file}.
+
+@item
+Directories on the command line are fatal for standard @command{awk};
+@command{gawk} ignores them if not in POSIX mode.
+
+@end itemize
+
+@c EXCLUDE START
+@node Input Exercises
+@section Exercises
+
+@enumerate
+@item
+Using the @code{FIELDWIDTHS} variable (@pxref{Constant Size}),
+write a program to read election data, where each record represents
+one voter's votes. Come up with a way to define which columns are
+associated with each ballot item, and print the total votes,
+including abstentions, for each item.
+
+@item
+@ref{Plain Getline}, presented a program to remove C-style
+comments (@samp{/* @dots{} */}) from the input. That program
+does not work if one comment ends on one line and another one
+starts later on the same line.
+That can be fixed by making one simple change. What is it?
+
+@end enumerate
+@c EXCLUDE END
+
+@node Printing
+@chapter Printing Output
+
+@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, @DBPXREF{Output Separators} and
+@ref{OFMT}.)
+For printing with specifications, you need the @code{printf} statement
+(@pxref{Printf}).
+
+@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 FD:: Special files for I/O.
+* 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.
+* Output Summary:: Output summary.
+* Output Exercises:: Exercises.
+@end menu
+
+@node Print
+@section The @code{print} Statement
+
+Use the @code{print} statement to produce output with simple, standardized
+formatting. You 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 an output 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 ""}.
+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.
+
+Note that the @code{print} statement is a statement and not an
+expression---you can't use it in the pattern part of a
+@var{pattern}-@var{action} statement, for example.
+
+@node Print Examples
+@section @code{print} Statement Examples
+
+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 containing 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
+@ifinfo
+newlines
+(the @samp{\n} is an escape sequence, used to represent the newline
+character; @pxref{Escape Sequences}):
+@end ifinfo
+@ifhtml
+newlines
+(the @samp{\n} is an escape sequence, used to represent the newline
+character; @pxref{Escape Sequences}):
+@end ifhtml
+@ifnotinfo
+@ifnothtml
+newlines:
+@end ifnothtml
+@end ifnotinfo
+
+@example
+$ @kbd{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
+$ @kbd{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
+$ @kbd{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
+a @code{BEGIN} rule (@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
+
+@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 simply the default. Any string of
+characters may be used as the @dfn{output field separator} by setting the
+predefined variable @code{OFS}. The initial value of this variable
+is the string @w{@code{" "}} (i.e., 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:
+
+
+@example
+$ @kbd{awk 'BEGIN @{ OFS = ";"; ORS = "\n\n" @}}
+> @kbd{@{ print $1, $2 @}' mail-list}
+@print{} Amelia;555-5553
+@print{}
+@print{} Anthony;555-3412
+@print{}
+@print{} Becky;555-7685
+@print{}
+@print{} Bill;555-1675
+@print{}
+@print{} Broderick;555-0542
+@print{}
+@print{} Camilla;555-2912
+@print{}
+@print{} Fabius;555-1234
+@print{}
+@print{} Julie;555-6699
+@print{}
+@print{} Martin;555-6480
+@print{}
+@print{} Samuel;555-3430
+@print{}
+@print{} Jean-Paul;555-2127
+@print{}
+@end example
+
+If the value of @code{ORS} does not contain a newline, the program's output
+runs together on a single line.
+
+@node OFMT
+@section Controlling Numeric Output with @code{print}
+@cindex numeric, output format
+@cindex formats@comma{} numeric output
+When printing numeric values with the @code{print} statement,
+@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}.
+
+@cindexawkfunc{sprintf}
+@cindex @code{OFMT} variable
+@cindex output, format specifier@comma{} @code{OFMT}
+The predefined variable @code{OFMT} contains the 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 a different format specification
+for the value of @code{OFMT}, as shown in the following example:
+
+@example
+$ @kbd{awk 'BEGIN @{}
+> @kbd{OFMT = "%.0f" # print numbers as integers (rounds)}
+> @kbd{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
+
+@cindex @code{printf} statement
+@cindex output, formatted
+@cindex formatting output
+For more precise control over the output format than what is
+provided by @code{print}, use @code{printf}.
+With @code{printf} you can
+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).
+
+@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
+As for @code{print}, the entire list of arguments may optionally be
+enclosed in parentheses. Here too, the parentheses are necessary if any
+of the item expressions use the @samp{>} relational operator; otherwise,
+it can be confused with an output redirection (@pxref{Redirection}).
+
+@cindex format specifiers
+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
+$ @kbd{awk 'BEGIN @{}
+> @kbd{ORS = "\nOUCH!\n"; OFS = "+"}
+> @kbd{msg = "Don\47t Panic!"}
+> @kbd{printf "%s\n", msg}
+> @kbd{@}'}
+@print{} Don't Panic!
+@end example
+
+@noindent
+Here, neither the @samp{+} nor the @samp{OUCH!} appear in
+the output message.
+
+@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:
+
+@c @asis for docbook to come out right
+@table @asis
+@item @code{%c}
+Print a number as a character; thus, @samp{printf "%c",
+65} outputs the letter @samp{A}. The output for a string value is
+the first character of the string.
+
+@cindex dark corner, format-control characters
+@cindex @command{gawk}, format-control characters
+@quotation NOTE
+The POSIX standard says the first character of a string is printed.
+In locales with multibyte characters, @command{gawk} attempts to
+convert the leading bytes of the string into a valid wide character
+and then to print the multibyte encoding of that character.
+Similarly, when printing a numeric value, @command{gawk} allows the
+value to be within the numeric range of values that can be held
+in a wide character.
+If the conversion to multibyte encoding fails, @command{gawk}
+uses the low eight bits of the value as the character to print.
+
+Other @command{awk} versions generally restrict themselves to printing
+the first byte of a string or to numeric values within the range of
+a single byte (0--255).
+@end quotation
+
+
+@item @code{%d}, @code{%i}
+Print a decimal integer.
+The two control letters are equivalent.
+(The @samp{%i} specification is for compatibility with ISO C.)
+
+@item @code{%e}, @code{%E}
+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 @code{%f}
+Print 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} or @samp{infinity}.
+The special ``not a number'' value formats as @samp{-nan} or @samp{nan}
+(@pxref{Math Definitions}).
+
+@item @code{%F}
+Like @samp{%f} but the infinity and ``not a number'' values are spelled
+using uppercase letters.
+
+The @samp{%F} format is a POSIX extension to ISO C; not all systems
+support it. On those that don't, @command{gawk} uses @samp{%f} instead.
+
+@item @code{%g}, @code{%G}
+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 @code{%o}
+Print an unsigned octal integer
+(@pxref{Nondecimal-numbers}).
+
+@item @code{%s}
+Print a string.
+
+@item @code{%u}
+Print 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 @code{%x}, @code{%X}
+Print an unsigned hexadecimal integer;
+@samp{%X} uses the letters @samp{A} through @samp{F}
+instead of @samp{a} through @samp{f}
+(@pxref{Nondecimal-numbers}).
+
+@item @code{%%}
+Print a single @samp{%}.
+This 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 @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
+
+@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 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 code{} 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 ignore them.
+
+@item - (Minus)
+The minus sign, used before the width modifier (see later on in
+this list),
+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 list),
+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 ``alternative 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}, @samp{%f}, and @samp{%F}, the result always
+contains a decimal point.
+For @samp{%g} and @samp{%G}, trailing zeros are not removed from the result.
+
+@item 0
+A leading @samp{0} (zero) acts as a flag indicating that output should be
+padded with zeros instead of spaces.
+This applies only to the numeric output formats.
+This flag only has an effect when the field width is wider than the
+value to print.
+
+@item '
+A single quote or apostrophe 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} @ii{Show source program}
+@print{} BEGIN @{ printf "%'d\n", 1234567 @}
+$ @kbd{LC_ALL=C gawk -f thousands.awk}
+@print{} 1234567 @ii{Results in} "C" @ii{locale}
+$ @kbd{LC_ALL=en_US.UTF-8 gawk -f thousands.awk}
+@print{} 1,234,567 @ii{Results in US English UTF locale}
+@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
+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{%d}, @code{%i}, @code{%o}, @code{%u}, @code{%x}, @code{%X}
+Minimum number of digits to print.
+
+@item @code{%e}, @code{%E}, @code{%f}, @code{%F}
+Number of digits to the right of the decimal point.
+
+@item @code{%g}, @code{%G}
+Maximum number of significant digits.
+
+@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 (e.g., @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 modifiers (@samp{h},
+@samp{j}, @samp{l}, @samp{L}, @samp{t}, and @samp{z}) in @code{printf}
+format strings. These are not valid in @command{awk}. Most @command{awk}
+implementations silently ignore them. 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.
+
+@node Printf Examples
+@subsection Examples Using @code{printf}
+
+The following simple example shows
+how to use @code{printf} to make an aligned table:
+
+@example
+awk '@{ printf "%-10s %s\n", $1, $2 @}' mail-list
+@end example
+
+@noindent
+This command
+prints the names of the people (@code{$1}) in the file
+@file{mail-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
+$ @kbd{awk '@{ printf "%-10s %s\n", $1, $2 @}' mail-list}
+@print{} Amelia 555-5553
+@print{} Anthony 555-3412
+@print{} Becky 555-7685
+@print{} Bill 555-1675
+@print{} Broderick 555-0542
+@print{} Camilla 555-2912
+@print{} Fabius 555-1234
+@print{} Julie 555-6699
+@print{} Martin 555-6480
+@print{} Samuel 555-3430
+@print{} Jean-Paul 555-2127
+@end example
+
+In 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 a @code{BEGIN} rule
+(@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 @}' mail-list
+@end example
+
+The preceding example mixes @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 @}' mail-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 @}' mail-list
+@end example
+
+
+@node Redirection
+@section Redirecting Output of @code{print} and @code{printf}
+
+@cindex output redirection
+@cindex redirection of output
+@cindex @option{--sandbox} option, output redirection with @code{print}, @code{printf}
+So far, the output from @code{print} and @code{printf} has gone
+to the standard
+output, usually the screen. Both @code{print} and @code{printf} can
+also send their output to other places.
+This is called @dfn{redirection}.
+
+@quotation NOTE
+When @option{--sandbox} is specified (@pxref{Options}),
+redirecting output to files, pipes and coprocesses is disabled.
+@end quotation
+
+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@comma{} of output
+@cindex @code{printf} statement, See Also redirection@comma{} 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. We show them all 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 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 peoples' names to one
+file named @file{name-list}, and a list of phone numbers to another file
+named @file{phone-list}:
+
+@example
+$ @kbd{awk '@{ print $2 > "phone-list"}
+> @kbd{print $1 > "name-list" @}' mail-list}
+$ @kbd{cat phone-list}
+@print{} 555-5553
+@print{} 555-3412
+@dots{}
+$ @kbd{cat name-list}
+@print{} Amelia
+@print{} Anthony
+@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 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 pipe, output
+@cindex output, pipes
+@item print @var{items} | @var{command}
+It is possible to send output to another program through a pipe
+instead of into a file. This 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 peoples' 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 @}' mail-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
+print("at record number", FNR, "of", FILENAME) | report
+close(report)
+@end example
+
+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.
+@DBXREF{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 (if you mean to refer to that same file or command)
+@command{awk} requires that the string value be written 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 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}.
+@DBXREF{Getline/Coprocess}
+for a brief discussion.
+@DBXREF{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, because the output file
+is only opened once. (It happens that if you mix @samp{>} and @samp{>>}
+that output is produced in the expected order. However, mixing the operators
+for the same file is definitely poor style, and is confusing to readers
+of your program.)
+
+@cindex differences in @command{awk} and @command{gawk}, implementation limitations
+@cindex implementation issues, @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
+@ifnotdocbook
+Many
+@end ifnotdocbook
+@end ifnottex
+older
+@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.
+
+@sidebar 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.
+
+@DBXREF{Shell Quoting} for a function that can help in generating
+command lines to be fed to the shell.
+@end sidebar
+
+@node Special FD
+@section Special Files for Standard Pre-Opened Data Streams
+@cindex standard input
+@cindex input, standard
+@cindex standard output
+@cindex output, standard
+@cindex error output
+@cindex standard error
+@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 open streams (and any other open file or pipe)
+are often referred to by the technical term @dfn{file descriptors}.
+
+These streams are, by default, connected to your keyboard and screen, 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 traditional 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.
+@c 8/2014: Mike Brennan says not to cite this as inefficient. So, fixed.
+This is far from elegant, and it also requires a
+separate process. So people writing @command{awk} programs often
+don't do this. Instead, they send the error messages to the
+screen, like this:
+
+@example
+print "Serious error detected!" > "/dev/tty"
+@end example
+
+@noindent
+(@file{/dev/tty} is a special file supplied by the operating system
+that is connected to your keyboard and screen. It represents the
+``terminal,''@footnote{The ``tty'' in @file{/dev/tty} stands for
+``Teletype,'' a serial terminal.} which on modern systems is a keyboard
+and screen, not a serial console.)
+This generally has the same effect but not always: although the
+standard error stream is usually the screen, it can be redirected; when
+that happens, writing to the screen 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}, BWK @command{awk}, and @command{mawk} provide
+special @value{FN}s for accessing the three standard streams.
+If the @value{FN} matches one of these special names when @command{gawk}
+(or one of the others) redirects input or output, then it directly uses
+the descriptor 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 common extensions, @code{/dev/stdin} special file
+@cindex common extensions, @code{/dev/stdout} special file
+@cindex common extensions, @code{/dev/stderr} special file
+@cindex extensions, common@comma{} @code{/dev/stdin} special file
+@cindex extensions, common@comma{} @code{/dev/stdout} special file
+@cindex extensions, common@comma{} @code{/dev/stderr} special file
+@cindex file names, standard streams in @command{gawk}
+@cindex @code{/dev/@dots{}} special files
+@cindex files, @code{/dev/@dots{}} special files
+@cindex @code{/dev/fd/@var{N}} special files (@command{gawk})
+@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).
+@end table
+
+With these facilities,
+the proper way to write an error message then becomes:
+
+@example
+print "Serious error detected!" > "/dev/stderr"
+@end example
+
+@cindex troubleshooting, quotes with file names
+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.
+
+@command{gawk} does not treat these @value{FN}s as special when
+in POSIX-compatibility mode. However, because BWK @command{awk}
+supports them, @command{gawk} does support them even when
+invoked with the @option{--traditional} option (@pxref{Options}).
+
+@node Special Files
+@section Special @value{FFN}s in @command{gawk}
+@cindex @command{gawk}, file names in
+
+Besides access to standard input, standard output, and standard error,
+@command{gawk} provides access to any open file descriptor.
+Additionally, there are special @value{FN}s reserved for
+TCP/IP networking.
+
+@menu
+* Other Inherited Files:: Accessing other open files with
+ @command{gawk}.
+* Special Network:: Special files for network communications.
+* Special Caveats:: Things to watch out for.
+@end menu
+
+@node Other Inherited Files
+@subsection Accessing Other Open Files With @command{gawk}
+
+Besides the @code{/dev/stdin}, @code{/dev/stdout}, and @code{/dev/stderr}
+special @value{FN}s mentioned earlier, @command{gawk} provides syntax
+for accessing any other inherited open file:
+
+@table @file
+@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 essentially aliases for @file{/dev/fd/0}, @file{/dev/fd/1}, and
+@file{/dev/fd/2}, respectively. However, those names are more self-explanatory.
+
+Note that using @code{close()} on a @value{FN} of the
+form @code{"/dev/fd/@var{N}"}, for file descriptor numbers
+above two, does actually close the given file descriptor.
+
+@node Special Network
+@subsection Special Files for Network Communications
+@cindex networks, support for
+@cindex TCP/IP, support for
+
+@command{gawk} 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{/@var{net-type}/@var{protocol}/@var{local-port}/@var{remote-host}/@var{remote-port}}
+@end example
+
+The @var{net-type} is one of @samp{inet}, @samp{inet4}, or @samp{inet6}.
+The @var{protocol} is one of @samp{tcp} or @samp{udp},
+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 are some things to bear in mind when using the
+special @value{FN}s that @command{gawk} provides:
+
+@itemize @value{BULLET}
+@cindex compatibility mode (@command{gawk}), file names
+@cindex file names, in compatibility mode
+@item
+Recognition of the @value{FN}s for the three standard pre-opened
+files is disabled only in POSIX mode.
+
+@item
+Recognition of the other special @value{FN}s is disabled if @command{gawk} is in
+compatibility mode (either @option{--traditional} or @option{--posix};
+@pxref{Options}).
+
+@item
+@command{gawk} @emph{always}
+interprets these special @value{FN}s.
+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
+
+@node Close Files And Pipes
+@section Closing Input and Output Redirections
+@cindex files, output, See output files
+@cindex input files, closing
+@cindex output, files@comma{} closing
+@cindex pipe, closing
+@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, @command{awk} remembers
+the @value{FN} or command associated with it, 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.
+
+@cindexawkfunc{close}
+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 @value{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
+@cindex @code{close()} function, portability
+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()} silently does nothing if given an argument that
+does not represent a file, pipe, or coprocess that was opened with
+a redirection. In such a case, it returns a negative value,
+indicating an error. In addition, @command{gawk} sets @code{ERRNO}
+to a string indicating the error.
+
+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 with a
+redirection, so @command{awk} silently does nothing, except return
+a negative value.
+
+@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, discussion is
+delayed until
+@ref{Two-way I/O},
+which describes it in more detail and gives an example.
+
+@sidebar Using @code{close()}'s Return Value
+@cindex dark corner, @code{close()} function
+@cindex @code{close()} function, return value
+@cindex return value@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 older versions of Unix @command{awk}, the @code{close()} function
+is actually a statement.
+@value{DARKCORNER}
+It is a syntax error to try and use the return
+value from @code{close()}:
+
+@example
+command = "@dots{}"
+command | getline info
+retval = close(command) # syntax error in many Unix awks
+@end example
+
+@cindex @command{gawk}, @code{ERRNO} variable in
+@cindex @code{ERRNO} variable, with @command{close()} function
+@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 predefined 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 nonzero otherwise. In general,
+different implementations vary in what they report when closing
+pipes; thus the return value cannot be used portably.
+@value{DARKCORNER}
+In POSIX mode (@pxref{Options}), @command{gawk} just returns zero
+when closing a pipe.
+@end sidebar
+
+
+@node Output Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+The @code{print} statement prints comma-separated expressions. Each
+expression is separated by the value of @code{OFS} and terminated by
+the value of @code{ORS}. @code{OFMT} provides the conversion format
+for numeric values for the @code{print} statement.
+
+@item
+The @code{printf} statement provides finer-grained control over output,
+with format control letters for different data types and various flags
+that modify the behavior of the format control letters.
+
+@item
+Output from both @code{print} and @code{printf} may be redirected to
+files, pipes, and coprocesses.
+
+@item
+@command{gawk} provides special @value{FN}s for access to standard input,
+output, and error, and for network communications.
+
+@item
+Use @code{close()} to close open file, pipe, and coprocess redirections.
+For coprocesses, it is possible to close only one direction of the
+communications.
+
+@end itemize
+
+@c EXCLUDE START
+@node Output Exercises
+@section Exercises
+
+@enumerate
+@item
+Rewrite the program:
+
+@example
+awk 'BEGIN @{ print "Month Crates"
+ print "----- ------" @}
+ @{ print $1, " ", $2 @}' inventory-shipped
+@end example
+
+@noindent
+from @ref{Output Separators}, by using a new value of @code{OFS}.
+
+@item
+Use the @code{printf} statement to line up the headings and table data
+for the @file{inventory-shipped} example that was covered in @ref{Print}.
+
+@item
+What happens if you forget the double quotes when redirecting
+output, as follows:
+
+@example
+BEGIN @{ print "Serious error detected!" > /dev/stderr @}
+@end example
+
+@end enumerate
+@c EXCLUDE END
+
+
+@node Expressions
+@chapter Expressions
+@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
+* Values:: Constants, Variables, and Regular Expressions.
+* All Operators:: @command{gawk}'s operators.
+* Truth Values and Conditions:: Testing for true and false.
+* Function Calls:: A function call is an expression.
+* Precedence:: How various operators nest.
+* Locales:: How the locale affects things.
+* Expressions Summary:: Expressions summary.
+@end menu
+
+@node Values
+@section Constants, Variables, and Conversions
+
+Expressions are built up from values and the operations performed
+upon them. This @value{SECTION} describes the elementary objects
+which provide the values used in expressions.
+
+@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.
+@end menu
+
+@node Constants
+@subsection 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 internally stored in an identical manner.
+
+@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
+@subsubsection Numeric and String Constants
+
+@cindex constants, numeric
+@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.
+@xref{Arbitrary Precision Arithmetic}, for much more information.}
+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 limitations
+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
+@subsubsection 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, and so on.
+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. Because 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 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
+$ @kbd{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 @DBREF{Bitwise Functions}
+for more information.
+
+Unlike some early C implementations, @samp{8} and @samp{9} are not
+valid in octal constants. For example, @command{gawk} treats @samp{018}
+as decimal 18:
+
+@example
+$ @kbd{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.
+
+@sidebar A Constant's Base Does Not Affect Its Value
+
+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
+$ @kbd{gawk 'BEGIN @{ printf "0x11 is <%s>\n", 0x11 @}'}
+@print{} 0x11 is <17>
+@end example
+@end sidebar
+
+@node Regexp Constants
+@subsubsection Regular Expression Constants
+
+@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 typically just ordinary strings or variables that contain a regexp,
+but could be a more complex expression).
+
+@node Using Constant Regexps
+@subsection 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 its author 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} really 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.
+
+@cindex differences in @command{awk} and @command{gawk}, regexp constants
+@cindex dark corner, regexp constants, as arguments to user-defined functions
+@cindexgawkfunc{gensub}
+@cindexawkfunc{sub}
+@cindexawkfunc{gsub}
+Constant regular expressions are also used as the first argument for
+the @code{gensub()}, @code{sub()}, and @code{gsub()} functions, as the
+second argument of the @code{match()} function,
+and as the third argument of the @code{split()} and @code{patsplit()} functions
+(@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}
+Because some built-in functions accept regexp constants as arguments,
+it can be confusing 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, because passing a truth value in
+this way is probably not what was intended.
+
+@node Variables
+@subsection 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
+@subsubsection 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.
+Here, a @dfn{letter} is any one of the 52 upper- and lowercase
+English letters. Other characters that may be defined as letters
+in non-English locales are not valid in variable names.
+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}.
+In addition, the @code{sub()} and @code{gsub()} functions can
+change a variable's value, and the @code{match()}, @code{split()},
+and @code{patsplit()} functions can change the contents of their
+array parameters. @xref{String Functions}.
+
+@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). @DBXREF{Built-in Variables} for a list of the predefined variables.
+These predefined variables can be used and assigned just like all other
+variables, but their values are also used or changed automatically by
+@command{awk}. All predefined 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 explicitly
+initialize a variable in @command{awk},
+which is what you would do in C and in most other traditional languages.
+
+@node Assignment Options
+@subsubsection 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 @option{-v} option
+@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 execute. The @option{-v} option and its assignment
+must precede all the @value{FN} arguments, as well as the program text.
+(@DBXREF{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 mail-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
+@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{mail-list}:
+
+@example
+$ @kbd{awk '@{ print $n @}' n=4 inventory-shipped n=2 mail-list}
+@print{} 15
+@print{} 24
+@dots{}
+@print{} 555-5553
+@print{} 555-3412
+@dots{}
+@end example
+
+@cindex 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
+@subsection Conversion of Strings and Numbers
+
+Number-to-string and string-to-number conversion are generally
+straightforward. There can be subtleties to be aware of;
+this @value{SECTION} discusses this important facet of @command{awk}.
+
+@menu
+* Strings And Numbers:: How @command{awk} Converts Between Strings And
+ Numbers.
+* Locale influences conversions:: How the locale may affect conversions.
+@end menu
+
+@node Strings And Numbers
+@subsubsection How @command{awk} Converts Between Strings and Numbers
+
+@cindex converting, strings to numbers
+@cindex strings, converting
+@cindex numbers, converting
+@cindex converting, numbers to strings
+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 that number with the empty string, @code{""}.
+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 1,000, 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} predefined 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 creates a value with
+at most six significant digits. For some applications, you might want to
+change it to specify more precision.
+On most modern machines,
+17 digits is usually 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 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}
+
+@sidebar Pre-POSIX @command{awk} Used @code{OFMT} for String Conversion
+@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.
+@DBXREF{Print} for more information on the @code{print} statement.
+@end sidebar
+
+@node Locale influences conversions
+@subsubsection Locales Can Influence Conversion
+
+Where you are can matter when it comes to converting between numbers and
+strings. The local character set and language---the @dfn{locale}---can
+affect numeric formats. In particular, for @command{awk} programs,
+it affects the decimal point character and the thousands-separator
+character. The @code{"C"} locale, and most English-language locales,
+use the period character (@samp{.}) as the decimal point and don't
+have a thousands separator. However, many (if not most) European and
+non-English locales use the comma (@samp{,}) as the decimal point
+character. European locales often use either a space or a period as
+the thousands separator, if they have one.
+
+@cindex dark corner, locale's 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. @value{DARKCORNER} In all cases, numbers in source code and
+in input data cannot have a thousands separator. Here are some examples
+indicating the difference in behavior, on a GNU/Linux system:
+
+@example
+$ @kbd{export POSIXLY_CORRECT=1} @ii{Force POSIX behavior}
+$ @kbd{gawk 'BEGIN @{ printf "%g\n", 3.1415927 @}'}
+@print{} 3.14159
+$ @kbd{LC_ALL=en_DK.utf-8 gawk 'BEGIN @{ printf "%g\n", 3.1415927 @}'}
+@print{} 3,14159
+$ @kbd{echo 4,321 | gawk '@{ print $1 + 1 @}'}
+@print{} 5
+$ @kbd{echo 4,321 | LC_ALL=en_DK.utf-8 gawk '@{ print $1 + 1 @}'}
+@print{} 5,321
+@end example
+
+@noindent
+The @code{en_DK.utf-8} 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 4, while in the Danish locale, it's treated
+as the full number including the fractional part, 4.321.
+
+Some earlier versions of @command{gawk} fully complied with this aspect
+of the standard. However, many users in non-English locales complained
+about this behavior, because their data used a period as the decimal
+point, so the default behavior was restored to use a period as the
+decimal point character. You can use the @option{--use-lc-numeric}
+option (@pxref{Options}) to force @command{gawk} to use the locale's
+decimal point character. (@command{gawk} also uses the locale's decimal
+point character when in POSIX mode, either via @option{--posix}, or the
+@env{POSIXLY_CORRECT} environment variable, as shown previously.)
+
+@ref{table-locale-affects} describes the cases in which the locale's decimal
+point character is used and when a period is used. Some of these
+features have not been described yet.
+
+@float Table,table-locale-affects
+@caption{Locale decimal point versus a period}
+@multitable @columnfractions .15 .20 .45
+@headitem Feature @tab Default @tab @option{--posix} or @option{--use-lc-numeric}
+@item @code{%'g} @tab Use locale @tab Use locale
+@item @code{%g} @tab Use period @tab Use locale
+@item Input @tab Use period @tab Use locale
+@item @code{strtonum()} @tab Use period @tab Use locale
+@end multitable
+@end float
+
+Finally, modern day formal standards and IEEE standard floating-point
+representation can have an unusual but important effect on the way
+@command{gawk} converts some special string values to numbers. The details
+are presented in @ref{POSIX Floating Point Problems}.
+
+@node All Operators
+@section Operators: Doing Something with Values
+
+This @value{SECTION} introduces the @dfn{operators} which make use
+of the values provided by constants and variables.
+
+@menu
+* 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.
+@end menu
+
+@node Arithmetic Ops
+@subsection 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 program takes the file @file{grades} and prints the average
+of the scores:
+
+@example
+$ @kbd{awk '@{ sum = $2 + $3 + $4 ; avg = sum / 3}
+> @kbd{print $1, avg @}' grades}
+@print{} Pat 85
+@print{} Sandy 83
+@print{} Chris 84.3333
+@end example
+
+The following list provides the arithmetic operators in @command{awk},
+in order from the highest precedence to the lowest:
+
+@table @code
+@cindex common extensions, @code{**} operator
+@cindex extensions, common@comma{} @code{**} operator
+@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{^}. @value{COMMONEXT}
+
+@item - @var{x}
+Negation.
+
+@item + @var{x}
+Unary plus; the expression is converted to a number.
+
+@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 @samp{@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
+@samp{@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 FIXME !!! 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
+@subsection String Concatenation
+@cindex Kernighan, Brian
+@quotation
+@i{It seemed like a good idea at the time.}
+@author 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
+$ @kbd{awk '@{ print "Field number one: " $1 @}' mail-list}
+@print{} Field number one: Amelia
+@print{} Field number one: Anthony
+@dots{}
+@end example
+
+Without the space in the string constant after the @samp{:}, the line
+runs together. For example:
+
+@example
+$ @kbd{awk '@{ print "Field number one:" $1 @}' mail-list}
+@print{} Field number one:Amelia
+@print{} Field number one:Anthony
+@dots{}
+@end example
+
+@cindex troubleshooting, string concatenation
+Because string concatenation does not have an explicit operator, it is
+often necessary to ensure that it happens at the right time by using
+parentheses to enclose the items to concatenate. For example,
+you might expect that the
+following code fragment concatenates @code{file} and @code{name}:
+
+@example
+file = "file"
+name = "name"
+print "something meaningful" > file name
+@end example
+
+@cindex Brian Kernighan's @command{awk}
+@cindex @command{mawk} utility
+@noindent
+This produces a syntax error with some versions of Unix
+@command{awk}.@footnote{It happens that BWK
+@command{awk}, @command{gawk} and @command{mawk} all ``get it right,''
+but you should not rely on this.}
+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 second 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
+$ @kbd{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 this way:
+
+@example
+$ @kbd{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 mixing concatenation with other operators, @emph{parenthesize}. Otherwise,
+you're never quite sure what you'll get.
+
+@node Assignment Ops
+@subsection Assignment Expressions
+@cindex assignment operators
+@cindex operators, assignment
+@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 was last assigned
+to it. 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
+@ifnotdocbook
+@DBPXREF{Numeric Functions}
+@end ifnotdocbook
+@ifdocbook
+@DBREF{Numeric Functions}
+@end ifdocbook
+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 Add @var{increment} to the value of @var{lvalue}
+@item @var{lvalue} @code{-=} @var{decrement} @tab Subtract @var{decrement} from the value of @var{lvalue}
+@item @var{lvalue} @code{*=} @var{coefficient} @tab Multiply the value of @var{lvalue} by @var{coefficient}
+@item @var{lvalue} @code{/=} @var{divisor} @tab Divide the value of @var{lvalue} by @var{divisor}
+@item @var{lvalue} @code{%=} @var{modulus} @tab Set @var{lvalue} to its remainder by @var{modulus}
+@cindex common extensions, @code{**=} operator
+@cindex extensions, common@comma{} @code{**=} operator
+@cindex @command{awk} language, POSIX version
+@cindex POSIX @command{awk}
+@item @var{lvalue} @code{^=} @var{power} @tab
+@item @var{lvalue} @code{**=} @var{power} @tab Raise @var{lvalue} to the power @var{power} @value{COMMONEXT}
+@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
+
+@sidebar Syntactic Ambiguities Between @samp{/=} and Regular Expressions
+@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, @code{/=} operator vs. @code{/=@dots{}/} regexp constant
+@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 @code{/=} assignment
+operator and regexp constants whose first character is an @samp{=}.
+@value{DARKCORNER}
+This is most notable in some commercial @command{awk} versions.
+For example:
+
+@example
+$ @kbd{awk /==/ /dev/null}
+@error{} awk: syntax error at source line 1
+@error{} context is
+@error{} >>> /= <<<
+@error{} awk: bailing out at source line 1
+@end example
+
+@noindent
+A workaround is:
+
+@example
+awk '/[=]=/' /dev/null
+@end example
+
+@command{gawk} does not have this problem; BWK @command{awk}
+and @command{mawk} also do not.
+@end sidebar
+
+@node Increment Ops
+@subsection Increment and Decrement Operators
+
+@cindex increment operators
+@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), @code{++} operator
+@cindex plus sign (@code{+}), @code{++} operator
+@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 @dfn{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 @dfn{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
+@iftex
+@math{10^{12}}).
+@end iftex
+@ifnottex
+@ifnotdocbook
+10e12).
+@end ifnotdocbook
+@end ifnottex
+@docbook
+10<superscript>12</superscript>). @c
+@end docbook
+
+@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}
+Increment @var{lvalue}, returning the new value as the
+value of the expression.
+
+@item @var{lvalue}++
+Increment @var{lvalue}, returning the @emph{old} value of @var{lvalue}
+as the value of the expression.
+
+@cindex @code{-} (hyphen), @code{--} operator
+@cindex hyphen (@code{-}), @code{--} operator
+@item --@var{lvalue}
+Decrement @var{lvalue}, returning the new value as the
+value of the expression.
+(This expression is
+like @samp{++@var{lvalue}}, but instead of adding, it subtracts.)
+
+@item @var{lvalue}--
+Decrement @var{lvalue}, returning the @emph{old} value of @var{lvalue}
+as the value of the expression.
+(This expression is
+like @samp{@var{lvalue}++}, but instead of adding, it subtracts.)
+@end table
+
+@sidebar Operator Evaluation Order
+@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!}
+@author 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.
+@end sidebar
+
+@node Truth Values and Conditions
+@section Truth Values and Conditions
+
+In certain contexts, expression values also serve as ``truth values''; (i.e.,
+they determine what should happen next as the program runs). This
+@value{SECTION} describes how @command{awk} defines ``true'' and ``false''
+and how values are compared.
+
+@menu
+* 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.
+@end menu
+
+@node Truth Values
+@subsection 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, @code{"0"} is actually true
+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
+@subsection Variable Typing and Comparison Expressions
+@quotation
+@i{The Guide is definitive. Reality is frequently inaccurate.}
+@author Douglas Adams, @cite{The Hitchhiker's Guide to the Galaxy}
+@end quotation
+
+@cindex comparison expressions
+@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
+@cindex variable typing
+@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.
+We look now at how variables are typed, and how @command{awk}
+compares variables.
+
+@menu
+* Variable Typing:: String type versus numeric type.
+* Comparison Operators:: The comparison operators.
+* POSIX String Comparison:: String comparison with POSIX rules.
+@end menu
+
+@node Variable Typing
+@subsubsection String Type versus Numeric Type
+
+@cindex numeric, strings
+@cindex strings, numeric
+@cindex POSIX @command{awk}, numeric strings and
+The 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.
+Variable typing follows these rules:
+
+
+@itemize @value{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{match()}, @code{split()}, and @code{patsplit()} 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
+@ifnotdocbook
+@display
+ +----------------------------------------------
+ | STRING NUMERIC STRNUM
+--------+----------------------------------------------
+ |
+STRING | string string string
+ |
+NUMERIC | string numeric numeric
+ |
+STRNUM | string numeric numeric
+--------+----------------------------------------------
+@end display
+@end ifnotdocbook
+@end ifnottex
+@docbook
+<informaltable>
+<tgroup cols="4">
+<colspec colname="1" align="left"/>
+<colspec colname="2" align="left"/>
+<colspec colname="3" align="left"/>
+<colspec colname="4" align="left"/>
+<thead>
+<row>
+<entry/>
+<entry>STRING</entry>
+<entry>NUMERIC</entry>
+<entry>STRNUM</entry>
+</row>
+</thead>
+
+<tbody>
+<row>
+<entry><emphasis role="bold">STRING</emphasis></entry>
+<entry>string</entry>
+<entry>string</entry>
+<entry>string</entry>
+</row>
+
+<row>
+<entry><emphasis role="bold">NUMERIC</emphasis></entry>
+<entry>string</entry>
+<entry>numeric</entry>
+<entry>numeric</entry>
+</row>
+
+<row>
+<entry><emphasis role="bold">STRNUM</emphasis></entry>
+<entry>string</entry>
+<entry>numeric</entry>
+<entry>numeric</entry>
+</row>
+
+</tbody>
+</tgroup>
+</informaltable>
+
+@end docbook
+
+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"}},
+when it appears in program source code,
+is a string---even though it looks numeric---and
+is @emph{never} treated as a 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.
+
+This point bears additional emphasis: All user input is made of characters,
+and so is first and foremost of @var{string} type; input strings
+that look numeric are additionally given the @var{strnum} attribute.
+Thus, the six-character input string @w{@samp{ +3.14}} receives the
+@var{strnum} attribute. In contrast, the eight characters
+@w{@code{" +3.14"}} appearing in program text comprise a string constant.
+The following examples print @samp{1} when the comparison between
+the two different constants is true, @samp{0} otherwise:
+
+@c 22.9.2014: Tested with mawk and BWK awk, got same results.
+@example
+$ @kbd{echo ' +3.14' | awk '@{ print($0 == " +3.14") @}'} @ii{True}
+@print{} 1
+$ @kbd{echo ' +3.14' | awk '@{ print($0 == "+3.14") @}'} @ii{False}
+@print{} 0
+$ @kbd{echo ' +3.14' | awk '@{ print($0 == "3.14") @}'} @ii{False}
+@print{} 0
+$ @kbd{echo ' +3.14' | awk '@{ print($0 == 3.14) @}'} @ii{True}
+@print{} 1
+$ @kbd{echo ' +3.14' | awk '@{ print($1 == " +3.14") @}'} @ii{False}
+@print{} 0
+$ @kbd{echo ' +3.14' | awk '@{ print($1 == "+3.14") @}'} @ii{True}
+@print{} 1
+$ @kbd{echo ' +3.14' | awk '@{ print($1 == "3.14") @}'} @ii{False}
+@print{} 0
+$ @kbd{echo ' +3.14' | awk '@{ print($1 == 3.14) @}'} @ii{True}
+@print{} 1
+@end example
+
+@node Comparison Operators
+@subsubsection Comparison Operators
+
+@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.
+
+The following list of expressions illustrates the kinds of comparisons
+@command{awk} performs, as well as what the result of each 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"
+@itemx a == b
+String comparison (false)
+@end table
+
+In this example:
+
+@example
+$ @kbd{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{}@code{/}) 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
+A constant regular
+expression in slashes by itself is also an expression.
+@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.
+
+@node POSIX String Comparison
+@subsubsection String Comparison with POSIX Rules
+
+The POSIX standard says that string comparison is performed based
+on the locale's @dfn{collating order}. This is the order in which
+characters sort, as defined by the locale (for more discussion,
+@pxref{Locales}). This order is usually very different
+from the results obtained when doing straight character-by-character
+comparison.@footnote{Technically, string comparison is supposed
+to behave the same way as if the strings are compared with the C
+@code{strcoll()} function.}
+
+Because this behavior differs considerably from existing practice,
+@command{gawk} only implements it when in POSIX mode (@pxref{Options}).
+Here is an example to illustrate the difference, in an @code{en_US.UTF-8}
+locale:
+
+@example
+$ @kbd{gawk 'BEGIN @{ printf("ABC < abc = %s\n",}
+> @kbd{("ABC" < "abc" ? "TRUE" : "FALSE")) @}'}
+@print{} ABC < abc = TRUE
+$ @kbd{gawk --posix 'BEGIN @{ printf("ABC < abc = %s\n",}
+> @kbd{("ABC" < "abc" ? "TRUE" : "FALSE")) @}'}
+@print{} ABC < abc = FALSE
+@end example
+
+
+@node Boolean Ops
+@subsection Boolean Expressions
+@cindex and Boolean-logic operator
+@cindex or Boolean-logic operator
+@cindex not Boolean-logic operator
+@cindex expressions, Boolean
+@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{edu} and @samp{li}:
+
+@example
+if ($0 ~ /edu/ && $0 ~ /li/) 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{edu} or
+@samp{li}:
+
+@example
+if ($0 ~ /edu/ || $0 ~ /li/) 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.
+(Thus, this test never really distinguishes records that contain both
+@samp{edu} and @samp{li}---as soon as @samp{edu} is matched,
+the full test succeeds.)
+
+@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 end with @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 @{ 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.@footnote{This
+program has a bug; it prints lines starting with @samp{END}. How
+would you fix it?}
+
+@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
+
+Most commonly, the @samp{!} operator is used in the conditions of
+@code{if} and @code{while} statements, where it often makes more
+sense to phrase the logic in the negative:
+
+@example
+if (! @var{some condition} || @var{some other condition}) @{
+ @var{@dots{} do whatever processing @dots{}}
+@}
+@end example
+
+@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
+
+@node Conditional Exp
+@subsection 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}), 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. @DBXREF{Built-in} for a list of built-in
+functions and their descriptions. In addition, you can define
+functions for use in your program.
+@DBXREF{User-defined}
+for instructions on how to do this.
+Finally, @command{gawk} lets you write functions in C or C++
+that may be called from your program (@pxref{Dynamic Extensions}).
+
+@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) @ii{one argument}
+atan2(y, x) @ii{two arguments}
+rand() @ii{no arguments}
+@end example
+
+@cindex troubleshooting, function call syntax
+@quotation CAUTION
+Do not put any space between the function name and the opening 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.
+@end quotation
+
+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.
+@DBXREF{Built-in} for full details. If arguments
+are omitted in calls to user-defined functions, then those arguments are
+treated as local variables. Such local variables act like the
+empty string if referenced where a string value is required,
+and like zero if referenced where a numeric value is required
+(@pxref{User-defined}).
+
+As an advanced feature, @command{gawk} provides indirect function calls,
+which is a way to choose the function to call at runtime, instead of
+when you write the source code to your program. We defer discussion of
+this feature until later; see @ref{Indirect Calls}.
+
+@cindex side effects, function calls
+Like every other expression, the function call has a value, often
+called the @dfn{return value}, which is computed by the function
+based on the arguments you give it. In this example, the return value
+of @samp{sqrt(@var{argument})} is the square root of @var{argument}.
+The following program reads numbers, one number per line, and prints
+the square root of each one:
+
+@example
+$ @kbd{awk '@{ print "The square root of", $1, "is", sqrt($1) @}'}
+@kbd{1}
+@print{} The square root of 1 is 1
+@kbd{3}
+@print{} The square root of 3 is 1.73205
+@kbd{5}
+@print{} The square root of 5 is 2.23607
+@kbd{Ctrl-d}
+@end example
+
+A function can also have side effects, such as assigning
+values to certain variables or doing I/O.
+This program shows how the @code{match()} function
+(@pxref{String Functions})
+changes the variables @code{RSTART} and @code{RLENGTH}:
+
+@example
+@{
+ if (match($1, $2))
+ print RSTART, RLENGTH
+ else
+ print "no match"
+@}
+@end example
+
+@noindent
+Here is a sample run:
+
+@example
+$ @kbd{awk -f matchit.awk}
+@kbd{aaccdd c+}
+@print{} 3 2
+@kbd{foo bar}
+@print{} no match
+@kbd{abcdefg e}
+@print{} 5 1
+@end example
+
+@node Precedence
+@section Operator Precedence (How Operators Nest)
+@cindex precedence
+@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)}.
+
+Normally the precedence of prefix unary operators does not matter,
+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.
+Also, operators cannot be combined in a way that violates the
+precedence rules; for example, @samp{$$0++--} is not a valid
+expression because the first @samp{$} has higher precedence than the
+@samp{++}; to avoid the problem the expression can be rewritten as
+@samp{$($0++)--}.
+
+This list presents @command{awk}'s operators, in order of highest
+to lowest precedence:
+
+@c @asis for docbook to come out right
+@table @asis
+@item @code{(}@dots{}@code{)}
+Grouping.
+
+@cindex @code{$} (dollar sign), @code{$} field operator
+@cindex dollar sign (@code{$}), @code{$} field operator
+@item @code{$}
+Field reference.
+
+@cindex @code{+} (plus sign), @code{++} operator
+@cindex plus sign (@code{+}), @code{++} operator
+@cindex @code{-} (hyphen), @code{--} operator
+@cindex hyphen (@code{-}), @code{--} operator
+@item @code{++ --}
+Increment, decrement.
+
+@cindex @code{^} (caret), @code{^} operator
+@cindex caret (@code{^}), @code{^} operator
+@cindex @code{*} (asterisk), @code{**} operator
+@cindex asterisk (@code{*}), @code{**} operator
+@item @code{^ **}
+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 @code{+ - !}
+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 @code{* / %}
+Multiplication, division, remainder.
+
+@cindex @code{+} (plus sign), @code{+} operator
+@cindex plus sign (@code{+}), @code{+} operator
+@cindex @code{-} (hyphen), @code{-} operator
+@cindex hyphen (@code{-}), @code{-} operator
+@item @code{+ -}
+Addition, subtraction.
+
+@item String concatenation
+There is no special symbol for 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 @code{< <= == != > >= >> | |&}
+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 (e.g., @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 @code{~ !~}
+Matching, nonmatching.
+
+@cindex @code{in} operator
+@item @code{in}
+Array membership.
+
+@cindex @code{&} (ampersand), @code{&&} operator
+@cindex ampersand (@code{&}), @code{&&} operator
+@item @code{&&}
+Logical ``and''.
+
+@cindex @code{|} (vertical bar), @code{||} operator
+@cindex vertical bar (@code{|}), @code{||} operator
+@item @code{||}
+Logical ``or''.
+
+@cindex @code{?} (question mark), @code{?:} operator
+@cindex question mark (@code{?}), @code{?:} operator
+@item @code{?:}
+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 @code{= += -= *= /= %= ^= **=}
+Assignment. These operators group right-to-left.
+@end table
+
+@cindex POSIX @command{awk}, @code{**} operator and
+@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
+
+@node Locales
+@section Where You Are Makes a Difference
+@cindex locale, definition of
+
+Modern systems support the notion of @dfn{locales}: a way to tell the
+system about the local character set and language. The ISO C standard
+defines a default @code{"C"} locale, which is an environment that is
+typical of what many C programmers are used to.
+
+Once upon a time, the locale setting used to affect regexp matching,
+but this is no longer true (@pxref{Ranges and Locales}).
+
+Locales can affect record splitting. For the normal case of @samp{RS =
+"\n"}, the locale is largely irrelevant. For other single-character
+record separators, setting @samp{LC_ALL=C} in the environment 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.
+
+Locales can affect how dates and times are formatted (@pxref{Time
+Functions}). For example, a common way to abbreviate the date September
+4, 2015, in the United States is ``9/4/15.'' In many countries in
+Europe, however, it is abbreviated ``4.9.15.'' Thus, the @samp{%x}
+specification in a @code{"US"} locale might produce @samp{9/4/15},
+while in a @code{"EUROPE"} locale, it might produce @samp{4.9.15}.
+
+According to POSIX, string comparison is also affected by locales (similar
+to regular expressions). The details are presented in @ref{POSIX String
+Comparison}.
+
+Finally, the locale affects the value of the decimal point character
+used when @command{gawk} parses input data. This is discussed in detail
+in @ref{Conversion}.
+
+@node Expressions Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+Expressions are the basic elements of computation in programs. They are
+built from constants, variables, function calls, and combinations of the
+various kinds of values with operators.
+
+@item
+@command{awk} supplies three kinds of constants: numeric, string, and
+regexp. @command{gawk} lets you specify numeric constants in octal
+and hexadecimal (bases 8 and 16) as well as decimal (base 10).
+In certain contexts, a standalone regexp constant such as @code{/foo/}
+has the same meaning as @samp{$0 ~ /foo/}.
+
+@item
+Variables hold values between uses in computations. A number of built-in
+variables provide information to your @command{awk} program, and a number
+of others let you control how @command{awk} behaves.
+
+@item
+Numbers are automatically converted to strings, and strings to numbers,
+as needed by @command{awk}. Numeric values are converted as if they were
+formatted with @code{sprintf()} using the format in @code{CONVFMT}.
+Locales can influence the conversions.
+
+@item
+@command{awk} provides the usual arithmetic operators (addition,
+subtraction, multiplication, division, modulus), and unary plus and minus.
+It also provides comparison operators, boolean operators, array membership
+testing, and regexp
+matching operators. String concatenation is accomplished by placing
+two expressions next to each other; there is no explicit operator.
+The three-operand @samp{?:} operator provides an ``if-else'' test within
+expressions.
+
+@item
+Assignment operators provide convenient shorthands for common arithmetic
+operations.
+
+@item
+In @command{awk}, a value is considered to be true if it is non-zero
+@emph{or} non-null. Otherwise, the value is false.
+
+@item
+A variable's type is set upon each assignment and may change over its
+lifetime. The type determines how it behaves in comparisons (string
+or numeric).
+
+@item
+Function calls return a value which may be used as part of a larger
+expression. Expressions used to pass parameter values are fully
+evaluated before the function is called. @command{awk} provides
+built-in and user-defined functions; this is described in
+@ref{Functions}.
+
+@item
+Operator precedence specifies the order in which operations are performed,
+unless explicitly overridden by parentheses. @command{awk}'s operator
+precedence is compatible with that of C.
+
+@item
+Locales can affect the format of data as output by an @command{awk}
+program, and occasionally the format for data read as input.
+
+@end itemize
+
+
+@node Patterns and Actions
+@chapter Patterns, Actions, and Variables
+@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 predefined 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 predefined variables.
+* Pattern Action Summary:: Patterns and Actions summary.
+@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.
+* BEGINFILE/ENDFILE:: Two special patterns for advanced control.
+* 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{begpat}, @var{endpat}
+A pair of patterns separated by a comma, specifying a @dfn{range} of records.
+The range includes both the initial record that matches @var{begpat} and
+the final record that matches @var{endpat}.
+(@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 BEGINFILE
+@itemx ENDFILE
+Special patterns for you to supply startup or cleanup actions to be
+done on a per-file basis.
+(@xref{BEGINFILE/ENDFILE}.)
+
+@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{li}:
+
+@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
+$ @kbd{awk '$1 == "li" @{ print $2 @}' mail-list}
+@end example
+
+@noindent
+(There is no output, because there is no person with the exact name @samp{li}.)
+Contrast this with the following regular expression match, which
+accepts any record with a first field that contains @samp{li}:
+
+@example
+$ @kbd{awk '$1 ~ /li/ @{ print $2 @}' mail-list}
+@print{} 555-5553
+@print{} 555-6699
+@end example
+
+@cindex regexp constants, as patterns
+@cindex patterns, regexp constants as
+pattern. The expression @code{/li/} has the value one if @samp{li}
+appears in the current input record. Thus, as a pattern, @code{/li/}
+matches any record containing @samp{li}.
+
+@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{mail-list} that contain both @samp{edu} and @samp{li}:
+
+@example
+$ @kbd{awk '/edu/ && /li/' mail-list}
+@print{} Samuel 555-3430 samuel.lanceolis@@shu.edu A
+@end example
+
+The following command prints all records in
+@file{mail-list} that contain @emph{either} @samp{edu} or @samp{li}
+(or both, of course):
+
+@example
+$ @kbd{awk '/edu/ || /li/' mail-list}
+@print{} Amelia 555-5553 amelia.zodiacusque@@gmail.com F
+@print{} Broderick 555-0542 broderick.aliquotiens@@yahoo.com R
+@print{} Fabius 555-1234 fabius.undevicesimus@@ucb.edu F
+@print{} Julie 555-6699 julie.perscrutabor@@skeeve.com F
+@print{} Samuel 555-3430 samuel.lanceolis@@shu.edu A
+@print{} Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R
+@end example
+
+The following command prints all records in
+@file{mail-list} that do @emph{not} contain the string @samp{li}:
+
+@example
+$ @kbd{awk '! /li/' mail-list}
+@print{} Anthony 555-3412 anthony.asserturo@@hotmail.com A
+@print{} Becky 555-7685 becky.algebrarum@@gmail.com A
+@print{} Bill 555-1675 bill.drowning@@hotmail.com A
+@print{} Camilla 555-2912 camilla.infusarum@@skynet.be R
+@print{} Fabius 555-1234 fabius.undevicesimus@@ucb.edu F
+@print{} Martin 555-6480 martin.codicibus@@hotmail.com A
+@print{} Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R
+@end example
+
+@cindex @code{BEGIN} pattern, Boolean patterns and
+@cindex @code{END} pattern, Boolean patterns and
+@cindex @code{BEGINFILE} pattern, Boolean patterns and
+@cindex @code{ENDFILE} 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}, @code{END},
+@code{BEGINFILE}, and @code{ENDFILE},
+which never match any input record, are not expressions and cannot
+appear inside Boolean patterns.
+
+The precedence of the different operators which can appear in
+patterns is described in @ref{Precedence}.
+
+@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 @dfn{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{!} (exclamation point), @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
+$ @kbd{echo Yes | gawk '(/1/,/2/) || /Yes/'}
+@error{} gawk: cmd. line:1: (/1/,/2/) || /Yes/
+@error{} gawk: cmd. line:1: ^ syntax error
+@end example
+
+@cindex range patterns, line continuation and
+As a minor point of interest, although it is poor style,
+POSIX allows you to put a newline after the comma in
+a range pattern. @value{DARKCORNER}
+
+@node BEGIN/END
+@subsection The @code{BEGIN} and @code{END} Special Patterns
+
+@cindex @code{BEGIN} pattern
+@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 longtime @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
+
+@cindex @code{BEGIN} pattern
+@cindex @code{END} pattern
+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
+$ @kbd{awk '}
+> @kbd{BEGIN @{ print "Analysis of \"li\"" @}}
+> @kbd{/li/ @{ ++n @}}
+> @kbd{END @{ print "\"li\" appears in", n, "records." @}' mail-list}
+@print{} Analysis of "li"
+@print{} "li" appears in 4 records.
+@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{mail-list}
+that contain the string @samp{li}. 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, as @command{awk} does this
+automatically (@pxref{Variables}).
+The second rule increments the variable @code{n} every time a
+record containing the pattern @samp{li} 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.
+@DBXREF{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 @code{BEGIN} rules and no
+other rules, then the program exits after the @code{BEGIN} rule is
+run.@footnote{The original version of @command{awk} kept
+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 be aware of 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 Brian Kernighan's @command{awk}
+@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, all of BWK @command{awk}, @command{mawk}, and @command{gawk}
+preserve the value of @code{$0} for use in @code{END} rules. Be aware,
+however, that some other implementations and many older versions
+of Unix @command{awk} 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 record. Many longtime @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, because 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, because all the input has been read.
+(@DBXREF{Next Statement} and
+@ifnotdocbook
+@DBPXREF{Nextfile Statement}.)
+@end ifnotdocbook
+@ifdocbook
+@DBREF{Nextfile Statement}.)
+@end ifdocbook
+
+@node BEGINFILE/ENDFILE
+@subsection The @code{BEGINFILE} and @code{ENDFILE} Special Patterns
+@cindex @code{BEGINFILE} pattern
+@cindex @code{ENDFILE} pattern
+@cindex differences in @command{awk} and @command{gawk}, @code{BEGINFILE}/@code{ENDFILE} patterns
+
+This @value{SECTION} describes a @command{gawk}-specific feature.
+
+Two special kinds of rule, @code{BEGINFILE} and @code{ENDFILE}, give
+you ``hooks'' into @command{gawk}'s command-line file processing loop.
+As with the @code{BEGIN} and @code{END} rules
+@ifnottex
+@ifnotdocbook
+(@pxref{BEGIN/END}),
+@end ifnotdocbook
+@end ifnottex
+@iftex
+(see the previous section),
+@end iftex
+@ifdocbook
+(see the previous section),
+@end ifdocbook
+all @code{BEGINFILE} rules in a program are merged, in the order they are
+read by @command{gawk}, and all @code{ENDFILE} rules are merged as well.
+
+The body of the @code{BEGINFILE} rules is executed just before
+@command{gawk} reads the first record from a file. @code{FILENAME}
+is set to the name of the current file, and @code{FNR} is set to zero.
+
+The @code{BEGINFILE} rule provides you the opportunity to accomplish two tasks
+that would otherwise be difficult or impossible to perform:
+
+@itemize @value{BULLET}
+@item
+You can test if the file is readable. Normally, it is a fatal error if a
+file named on the command line cannot be opened for reading. However,
+you can bypass the fatal error and move on to the next file on the
+command line.
+
+@cindex @command{gawk}, @code{ERRNO} variable in
+@cindex @code{ERRNO} variable, with @code{BEGINFILE} pattern
+@cindex @code{nextfile} statement, @code{BEGINFILE}/@code{ENDFILE} patterns and
+You do this by checking if the @code{ERRNO} variable is not the empty
+string; if so, then @command{gawk} was not able to open the file. In
+this case, your program can execute the @code{nextfile} statement
+(@pxref{Nextfile Statement}). This causes @command{gawk} to skip
+the file entirely. Otherwise, @command{gawk} exits with the usual
+fatal error.
+
+@item
+If you have written extensions that modify the record handling (by
+inserting an ``input parser,'' @pxref{Input Parsers}), you can invoke
+them at this point, before @command{gawk} has started processing the file.
+(This is a @emph{very} advanced feature, currently used only by the
+@uref{http://gawkextlib.sourceforge.net, @code{gawkextlib} project}.)
+@end itemize
+
+The @code{ENDFILE} rule is called when @command{gawk} has finished processing
+the last record in an input file. For the last input file,
+it will be called before any @code{END} rules.
+The @code{ENDFILE} rule is executed even for empty input files.
+
+Normally, when an error occurs when reading input in the normal input
+processing loop, the error is fatal. However, if an @code{ENDFILE}
+rule is present, the error becomes non-fatal, and instead @code{ERRNO}
+is set. This makes it possible to catch and process I/O errors at the
+level of the @command{awk} program.
+
+@cindex @code{next} statement, @code{BEGINFILE}/@code{ENDFILE} patterns and
+The @code{next} statement (@pxref{Next Statement}) is not allowed inside
+either a @code{BEGINFILE} or an @code{ENDFILE} rule. The @code{nextfile}
+statement is allowed only inside a
+@code{BEGINFILE} rule, but not inside an @code{ENDFILE} rule.
+
+@cindex @code{getline} statement, @code{BEGINFILE}/@code{ENDFILE} patterns and
+The @code{getline} statement (@pxref{Getline}) is restricted inside
+both @code{BEGINFILE} and @code{ENDFILE}: only redirected
+forms of @code{getline} are allowed.
+
+@code{BEGINFILE} and @code{ENDFILE} are @command{gawk} extensions.
+In most other @command{awk} implementations, or if @command{gawk} is in
+compatibility mode (@pxref{Options}), they are not special.
+
+@c FIXME: For 4.2 maybe deal with this?
+@ignore
+Date: Tue, 17 May 2011 02:06:10 PDT
+From: rankin@pactechdata.com (Pat Rankin)
+Message-Id: <110517015127.20240f4a@pactechdata.com>
+Subject: BEGINFILE
+To: arnold@skeeve.com
+
+ The documentation for BEGINFILE states that FNR is 0, which seems
+pretty obvious. It doesn't mention what the value of $0 is, and that's
+not obvious. I think setting it to null before starting the BEGINFILE
+action would be preferable to leaving whatever was there in the last
+record of the previous file.
+
+ ENDFILE can retain the last record in $0. I guess it has to if
+the END rule's actions see that value too. But the beginning of a new
+file doesn't just mean that the old one has been closed; the old file
+is being superseded, so leaving the old data around feels wrong to me.
+[If the user wants to keep it on hand, he or she can use an ENDFILE
+rule to grab it before moving on to the next file.]
+@end ignore
+
+@node 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 @}' mail-list
+@end example
+
+@noindent
+prints the first field of every record.
+
+@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
+A common method is to use shell quoting to substitute
+the variable's value into the program inside the script.
+For example, consider the following program:
+
+@example
+printf "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} shell 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.
+Then use dynamic regexps to match the pattern
+(@pxref{Computed Regexps}).
+The following shows how to redo the
+previous example using this technique:
+
+@example
+printf "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, as 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:
+
+@display
+[@var{pattern}] @code{@{ @var{action} @}}
+ @var{pattern} [@code{@{ @var{action} @}}]
+@dots{}
+@code{function @var{name}(@var{args}) @{ @dots{} @}}
+@dots{}
+@end display
+
+@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 braces (@samp{@{@r{@dots{}}@}}). Each statement specifies one
+thing to do. The statements are separated by newlines or semicolons.
+The 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 braces as
+well. An omitted action is equivalent to @samp{@{ print $0 @}}:
+
+@example
+/foo/ @{ @} @ii{match @code{foo}, do nothing --- empty action}
+/foo/ @ii{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
+Enclose one or more statements in 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
+@cindex control statements
+@cindex statements, control, in actions
+@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 @command{awk}'s
+control statements are patterned after 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 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:
+
+@display
+@code{if (@var{condition}) @var{then-body}} [@code{else @var{else-body}}]
+@end display
+
+@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 (i.e.,
+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
+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, @code{while}
+@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}
+executes again. This process repeats until the @var{condition} is no longer
+true. If the @var{condition} is initially false, the body of the loop
+never executes 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
+@cindex loops, @code{do}-@code{while}
+
+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}
+executes 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, because 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
+@cindex loops, @code{for}, iterative
+
+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.
+
+@cindex @code{in} operator
+There is an alternative 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
+@DBXREF{Scanning an Array}
+for more information on this version of the @code{for} loop.
+
+@node Switch Statement
+@subsection The @code{switch} Statement
+@cindex @code{switch} statement
+@cindex @code{case} keyword
+@cindex @code{default} keyword
+
+This @value{SECTION} describes a @command{gawk}-specific feature.
+If @command{gawk} is in compatibility mode (@pxref{Options}),
+it is not available.
+
+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, the case statement bodies execute 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
+while ((c = getopt(ARGC, ARGV, "aksx")) != -1) @{
+ switch (c) @{
+ case "a":
+ # report size of all files
+ all_files = TRUE;
+ break
+ case "k":
+ BLOCK_SIZE = 1024 # 1K block size
+ break
+ case "s":
+ # do sums only
+ sum_only = TRUE
+ break
+ case "x":
+ # don't cross filesystems
+ fts_flags = or(fts_flags, FTS_XDEV)
+ break
+ case "?":
+ default:
+ usage()
+ break
+ @}
+@}
+@end example
+
+Note that if none of the statements specified here halt execution
+of a matched @code{case} statement, execution falls through to the
+next @code{case} until execution halts. In this example, the
+@code{case} for @code{"?"} falls through to the @code{default}
+case, which is to call a function named @code{usage()}.
+(The @code{getopt()} function being called here is
+described in @ref{Getopt Function}.)
+
+@node Break Statement
+@subsection The @code{break} Statement
+@cindex @code{break} statement
+@cindex loops, exiting
+@cindex loops, @code{break} statement and
+
+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}.)
+
+The 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
+
+The @code{break} statement is also used to break out of the
+@code{switch} statement.
+This is discussed in @ref{Switch Statement}.
+
+@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
+@cindex Brian Kernighan's @command{awk}
+The @code{break} statement has no meaning when
+used outside the body of a loop or @code{switch}.
+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}).
+@value{DARKCORNER}
+Recent versions of BWK @command{awk} no longer allow this usage,
+nor does @command{gawk}.
+
+@node Continue Statement
+@subsection The @code{continue} Statement
+
+@cindex @code{continue} statement
+Similar to @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, because
+the increment (@samp{x++}) is never reached.
+
+@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
+@cindex Brian Kernighan's @command{awk}
+The @code{continue} statement has no special meaning with respect to the
+@code{switch} statement, nor does it have any 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}).
+@value{DARKCORNER}
+Recent versions of BWK @command{awk} no longer work this way, nor
+does @command{gawk}.
+
+@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 @{
+ printf("%s:%d: skipped: NF != 4\n", FILENAME, FNR) > "/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}.
+
+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}.
+
+The @code{next} statement is not allowed inside @code{BEGINFILE} and
+@code{ENDFILE} rules. @xref{BEGINFILE/ENDFILE}.
+
+@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 does not disallow it,
+most 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.
+
+@node Nextfile Statement
+@subsection The @code{nextfile} Statement
+@cindex @code{nextfile} statement
+
+The @code{nextfile} statement
+is similar to the @code{next} statement.
+However, instead of abandoning processing of the current record, the
+@code{nextfile} statement instructs @command{awk} to stop processing the
+current @value{DF}.
+
+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,
+and processing
+starts over with the first rule in the program.
+If the @code{nextfile} statement causes the end of the input to be reached,
+then the code in any @code{END} rules is executed. An exception to this is
+when @code{nextfile} is invoked during execution of any statement in an
+@code{END} rule; in this case, it causes the program to stop immediately.
+@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.
+Without @code{nextfile},
+in order to move on to the next @value{DF}, a program
+would have to continue scanning the unwanted records. The @code{nextfile}
+statement accomplishes this much more efficiently.
+
+In @command{gawk}, execution of @code{nextfile} causes additional things
+to happen: any @code{ENDFILE} rules are executed if @command{gawk} is
+not currently in an @code{END} or @code{BEGINFILE} rule, @code{ARGIND} is
+incremented, and any @code{BEGINFILE} rules are executed. (@code{ARGIND}
+hasn't been introduced yet. @xref{Built-in Variables}.)
+
+With @command{gawk}, @code{nextfile} is useful inside a @code{BEGINFILE}
+rule to skip over a file that would otherwise cause @command{gawk}
+to exit with a fatal error. In this case, @code{ENDFILE} rules are not
+executed. @xref{BEGINFILE/ENDFILE}.
+
+Although it might seem 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}.
+
+@quotation NOTE
+For many years, @code{nextfile} was a
+common extension. In September 2012, it was accepted for
+inclusion into the POSIX standard.
+See @uref{http://austingroupbugs.net/view.php?id=607, the Austin Group website}.
+@end quotation
+
+@cindex functions, user-defined, @code{next}/@code{nextfile} statements and
+@cindex @code{nextfile} statement, user-defined functions and
+@cindex Brian Kernighan's @command{awk}
+@cindex @command{mawk} utility
+The current version of BWK @command{awk}, and @command{mawk}
+also support @code{nextfile}. However, they don'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.
+
+@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:
+
+@display
+@code{exit} [@var{return code}]
+@end display
+
+@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 in the body 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. @command{gawk} also skips
+any @code{ENDFILE} rules; they do not execute.
+
+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.
+@DBXREF{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} causes @command{awk} to return a ``success'' status.
+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}
+@DBXREF{Exit Status} for more information.
+
+@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
+
+@quotation NOTE
+For full portability, exit values should be between zero and 126, inclusive.
+Negative values, and values of 127 or greater, may not produce consistent
+results across different operating systems.
+@end quotation
+
+
+@node Built-in Variables
+@section Predefined Variables
+@cindex predefined variables
+@cindex variables, predefined
+
+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}, predefined variables and
+This @value{SECTION} documents all of @command{gawk}'s predefined variables,
+most of which are also documented in the @value{CHAPTER}s 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}
+@cindex predefined variables, user-modifiable
+@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 (@samp{#}). These variables are @command{gawk} extensions. In other
+@command{awk} implementations or if @command{gawk} is in compatibility
+mode (@pxref{Options}), they are not special. (Any exceptions are noted
+in the description of each variable.)
+
+@table @code
+@cindex @code{BINMODE} variable
+@cindex binary input/output
+@cindex input/output, binary
+@cindex differences in @command{awk} and @command{gawk}, @code{BINMODE} variable
+@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.
+A numeric value less than zero is treated as zero, and a numeric value
+greater than three is treated as three. 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 treated the same as @code{"rw"}, but causes @command{gawk}
+to generate a warning message. @code{BINMODE} is described in more
+detail in @ref{PC Using}. @command{mawk} (@pxref{Other Versions}),
+also supports this variable, but only using numeric values.
+
+@cindex @code{CONVFMT} variable
+@cindex POSIX @command{awk}, @code{CONVFMT} variable and
+@cindex numbers, converting, to strings
+@cindex strings, converting, numbers to
+@item @code{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 @command{gawk}, @code{FIELDWIDTHS} variable in
+@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 #
+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} and @code{FPAT} for field splitting.
+@DBXREF{Constant Size} for more information.
+
+@cindex @command{gawk}, @code{FPAT} variable in
+@cindex @code{FPAT} variable
+@cindex differences in @command{awk} and @command{gawk}, @code{FPAT} variable
+@cindex field separators, @code{FPAT} variable and
+@cindex separators, field, @code{FPAT} variable and
+@item FPAT #
+A regular expression (as a string) that tells @command{gawk}
+to create the fields based on text that matches the regular expression.
+Assigning a value to @code{FPAT}
+overrides the use of @code{FS} and @code{FIELDWIDTHS} for field splitting.
+@DBXREF{Splitting By Content} for more information.
+
+@cindex @code{FS} variable
+@cindex separators, field
+@cindex field separators
+@item FS
+The input field separator (@pxref{Field Separators}).
+The value is a single-character string or a multicharacter 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.
+Nonetheless, some other versions of @command{awk} also treat
+@code{""} specially.)
+
+@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} or @code{FPAT}
+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 @command{gawk}, @code{IGNORECASE} variable in
+@cindex @code{IGNORECASE} variable
+@cindex differences in @command{awk} and @command{gawk}, @code{IGNORECASE} variable
+@cindex case sensitivity, and string comparisons
+@cindex case sensitivity, and regexps
+@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{patsplit()},
+@code{split()}, and @code{sub()}
+functions, record termination with @code{RS}, and field splitting with
+@code{FS} and @code{FPAT}, 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{LINT} variable in
+@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.
+
+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
+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}
+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
+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{PREC} variable
+@item PREC #
+The working precision of arbitrary-precision floating-point numbers,
+53 bits by default (@pxref{Setting precision}).
+
+@cindex @code{ROUNDMODE} variable
+@item ROUNDMODE #
+The rounding mode to use for arbitrary-precision arithmetic on
+numbers, by default @code{"N"} (@samp{roundTiesToEven} in
+the IEEE 754 standard; @pxref{Setting the rounding mode}).
+
+@cindex @code{RS} variable
+@cindex separators, for records
+@cindex record separators
+@item @code{RS}
+The 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 @code{SUBSEP}
+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{Multidimensional}).
+
+@cindex @command{gawk}, @code{TEXTDOMAIN} variable in
+@cindex @code{TEXTDOMAIN} variable
+@cindex differences in @command{awk} and @command{gawk}, @code{TEXTDOMAIN} variable
+@cindex internationalization, localization
+@item TEXTDOMAIN #
+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"}.
+@end table
+
+@node Auto-set
+@subsection Built-In Variables That Convey Information
+
+@cindex predefined variables, conveying information
+@cindex variables, predefined 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 (@samp{#}). These variables are @command{gawk} extensions. In other
+@command{awk} implementations or if @command{gawk} is in compatibility
+mode (@pxref{Options}), they are not special:
+
+@c @asis for docbook
+@table @asis
+@cindex @code{ARGC}/@code{ARGV} variables
+@cindex arguments, command-line
+@cindex command line, arguments
+@item @code{ARGC}, @code{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
+$ @kbd{awk 'BEGIN @{}
+> @kbd{for (i = 0; i < ARGC; i++)}
+> @kbd{print ARGV[i]}
+> @kbd{@}' inventory-shipped mail-list}
+@print{} awk
+@print{} inventory-shipped
+@print{} mail-list
+@end example
+
+@noindent
+@code{ARGV[0]} contains @samp{awk}, @code{ARGV[1]}
+contains @samp{inventory-shipped}, and @code{ARGV[2]} contains
+@samp{mail-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.
+
+@cindex dark corner, value of @code{ARGV[0]}
+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.
+@DBXREF{ARGC and ARGV} for information
+about how @command{awk} uses these variables.
+@value{DARKCORNER}
+
+@cindex @code{ARGIND} variable
+@cindex differences in @command{awk} and @command{gawk}, @code{ARGIND} variable
+@item @code{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 file names, 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 it
+opens the next file.
+
+@cindex @code{ENVIRON} array
+@cindex environment variables, in @code{ENVIRON} array
+@item @code{ENVIRON}
+An associative array containing 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 @code{/home/arnold}.
+
+For POSIX @command{awk}, 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.
+
+However, beginning with version 4.2, if not in POSIX
+compatibility mode, @command{gawk} does update its own environment when
+@code{ENVIRON} is changed, thus changing the environment seen by programs
+that it creates. You should therefore be especially careful if you
+modify @code{ENVIRON["PATH"]"}, which is the search path for finding
+executable programs.
+
+This can also affect the running @command{gawk} program, since some of the
+built-in functions may pay attention to certain environment variables.
+The most notable instance of this is @code{mktime()} (@pxref{Time
+Functions}), which pays attention the value of the @env{TZ} environment
+variable on many systems.
+
+Some operating systems may not have environment variables.
+On such systems, the @code{ENVIRON} array is empty (except for
+@w{@code{ENVIRON["AWKPATH"]}} and
+@w{@code{ENVIRON["AWKLIBPATH"]}};
+@DBPXREF{AWKPATH Variable} and
+@ifdocbook
+@DBREF{AWKLIBPATH Variable}).
+@end ifdocbook
+@ifnotdocbook
+@pxref{AWKLIBPATH Variable}).
+@end ifnotdocbook
+
+@cindex @command{gawk}, @code{ERRNO} variable in
+@cindex @code{ERRNO} variable
+@cindex differences in @command{awk} and @command{gawk}, @code{ERRNO} variable
+@cindex error handling, @code{ERRNO} variable and
+@item @code{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.
+
+In addition, @command{gawk} clears @code{ERRNO} before opening each
+command-line input file. This enables checking if the file is readable
+inside a @code{BEGINFILE} pattern (@pxref{BEGINFILE/ENDFILE}).
+
+Otherwise, @code{ERRNO} works similarly to the C variable @code{errno}.
+Except for the case just mentioned, @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.
+
+@cindex @code{FILENAME} variable
+@cindex dark corner, @code{FILENAME} variable
+@item @code{FILENAME}
+The name of the current input file. 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} changes each
+time a new file is read (@pxref{Reading Files}). Inside a @code{BEGIN}
+rule, the value of @code{FILENAME} is @code{""}, because 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 @code{FNR}
+The current record number in the current file. @command{awk} increments
+@code{FNR} each time it reads a new record (@pxref{Records}).
+@command{awk} resets @code{FNR} to zero each time it starts a new
+input file.
+
+@cindex @code{NF} variable
+@item @code{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 @value{SUBSECTION},
+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{FUNCTAB} array
+@cindex @command{gawk}, @code{FUNCTAB} array in
+@cindex differences in @command{awk} and @command{gawk}, @code{FUNCTAB} variable
+@item @code{FUNCTAB #}
+An array whose indices and corresponding values are the names of all
+the built-in, user-defined, and extension functions in the program.
+
+@quotation NOTE
+Attempting to use the @code{delete} statement with the @code{FUNCTAB}
+array causes a fatal error. Any attempt to assign to an element of
+@code{FUNCTAB} also causes a fatal error.
+@end quotation
+
+@cindex @code{NR} variable
+@item @code{NR}
+The number of input records @command{awk} has processed since
+the beginning of the program's execution
+(@pxref{Records}).
+@command{awk} increments @code{NR} each time it reads a new record.
+
+@cindex @command{gawk}, @code{PROCINFO} array in
+@cindex @code{PROCINFO} array
+@cindex differences in @command{awk} and @command{gawk}, @code{PROCINFO} array
+@item @code{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
+@cindex effective group ID of @command{gawk} user
+@item PROCINFO["egid"]
+The value of the @code{getegid()} system call.
+
+@item PROCINFO["euid"]
+@cindex effective user ID of @command{gawk} user
+The value of the @code{geteuid()} system call.
+
+@item PROCINFO["FS"]
+This is
+@code{"FS"} if field splitting with @code{FS} is in effect,
+@code{"FIELDWIDTHS"} if field splitting with @code{FIELDWIDTHS} is in effect,
+or @code{"FPAT"} if field matching with @code{FPAT} is in effect.
+
+@item PROCINFO["identifiers"]
+@cindex program identifiers
+A subarray, indexed by the names of all identifiers used in the text of
+the AWK program. An @dfn{identifier} is simply the name of a variable
+(be it scalar or array), built-in function, user-defined function, or
+extension function. For each identifier, the value of the element is
+one of the following:
+
+@table @code
+@item "array"
+The identifier is an array.
+
+@item "builtin"
+The identifier is a built-in function.
+
+@item "extension"
+The identifier is an extension function loaded via
+@code{@@load} or @option{-l}.
+
+@item "scalar"
+The identifier is a scalar.
+
+@item "untyped"
+The identifier is untyped (could be used as a scalar or array,
+@command{gawk} doesn't know yet).
+
+@item "user"
+The identifier is a user-defined function.
+@end table
+
+@noindent
+The values indicate what @command{gawk} knows about the identifiers
+after it has finished parsing the program; they are @emph{not} updated
+while the program runs.
+
+@item PROCINFO["gid"]
+@cindex group ID of @command{gawk} user
+The value of the @code{getgid()} system call.
+
+@item PROCINFO["pgrpid"]
+@cindex process group idIDof @command{gawk} process
+The process group ID of the current process.
+
+@item PROCINFO["pid"]
+@cindex process ID of @command{gawk} process
+The process ID of the current process.
+
+@item PROCINFO["ppid"]
+@cindex parent process ID of @command{gawk} process
+The parent process ID of the current process.
+
+@item PROCINFO["sorted_in"]
+If this element exists in @code{PROCINFO}, its value controls the
+order in which array indices will be processed by
+@samp{for (@var{indx} in @var{array})} loops.
+This is an advanced feature, so we defer the
+full description until later; see
+@ref{Scanning an Array}.
+
+@item PROCINFO["strftime"]
+The default time format string for @code{strftime()}.
+Assigning a new value to this element changes the default.
+@xref{Time Functions}.
+
+@item PROCINFO["uid"]
+The value of the @code{getuid()} system call.
+
+@item PROCINFO["version"]
+@cindex version of @command{gawk}
+@cindex @command{gawk} version
+The version of @command{gawk}.
+@end table
+
+The following additional elements in the array
+are available to provide information about the MPFR and GMP libraries
+if your version of @command{gawk} supports arbitrary-precision arithmetic
+(@pxref{Arbitrary Precision Arithmetic}):
+
+@table @code
+@cindex version of GNU MPFR library
+@item PROCINFO["mpfr_version"]
+The version of the GNU MPFR library.
+
+@item PROCINFO["gmp_version"]
+@cindex version of GNU MP library
+The version of the GNU MP library.
+
+@item PROCINFO["prec_max"]
+@cindex maximum precision supported by MPFR library
+The maximum precision supported by MPFR.
+
+@item PROCINFO["prec_min"]
+@cindex minimum precision supported by MPFR library
+The minimum precision required by MPFR.
+@end table
+
+The following additional elements in the array are available to provide
+information about the version of the extension API, if your version
+of @command{gawk} supports dynamic loading of extension functions
+(@pxref{Dynamic Extensions}):
+
+@table @code
+@item PROCINFO["api_major"]
+@cindex version of @command{gawk} extension API
+@cindex extension API, version number
+The major version of the extension API.
+
+@item PROCINFO["api_minor"]
+The minor version of the extension API.
+@end table
+
+@cindex supplementary groups of @command{gawk} process
+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}).
+
+@cindex @command{gawk}, @code{PROCINFO} array in
+@cindex @code{PROCINFO} array, uses
+The @code{PROCINFO} array has the following additional uses:
+
+@itemize @value{BULLET}
+@item
+It may be used to provide a timeout when reading from any
+open input file, pipe, or coprocess.
+@DBXREF{Read Timeout} for more information.
+
+@item
+It may be used to cause coprocesses to communicate over pseudo-ttys
+instead of through two-way pipes; this is discussed further in
+@ref{Two-way I/O}.
+@end itemize
+
+@cindex @code{RLENGTH} variable
+@item @code{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 @code{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 @command{gawk}, @code{RT} variable in
+@cindex @code{RT} variable
+@cindex differences in @command{awk} and @command{gawk}, @code{RT} variable
+@item @code{RT #}
+The input text that matched the text denoted by @code{RS},
+the record separator. It is set every time a record is read.
+
+@cindex @command{gawk}, @code{SYMTAB} array in
+@cindex @code{SYMTAB} array
+@cindex differences in @command{awk} and @command{gawk}, @code{SYMTAB} variable
+@item @code{SYMTAB #}
+An array whose indices are the names of all defined global variables and
+arrays in the program. @code{SYMTAB} makes @command{gawk}'s symbol table
+visible to the @command{awk} programmer. It is built as @command{gawk}
+parses the program and is complete before the program starts to run.
+
+The array may be used for indirect access to read or write the value of
+a variable:
+
+@example
+foo = 5
+SYMTAB["foo"] = 4
+print foo # prints 4
+@end example
+
+@noindent
+The @code{isarray()} function (@pxref{Type Functions}) may be used to test
+if an element in @code{SYMTAB} is an array.
+Also, you may not use the @code{delete} statement with the
+@code{SYMTAB} array.
+
+You may use an index for @code{SYMTAB} that is not a predefined identifier:
+
+@example
+SYMTAB["xxx"] = 5
+print SYMTAB["xxx"]
+@end example
+
+@noindent
+This works as expected: in this case @code{SYMTAB} acts just like
+a regular array. The only difference is that you can't then delete
+@code{SYMTAB["xxx"]}.
+
+@cindex Schorr, Andrew
+The @code{SYMTAB} array is more interesting than it looks. Andrew Schorr
+points out that it effectively gives @command{awk} data pointers. Consider his
+example:
+
+@example
+# Indirect multiply of any variable by amount, return result
+
+function multiply(variable, amount)
+@{
+ return SYMTAB[variable] *= amount
+@}
+@end example
+
+@quotation NOTE
+In order to avoid severe time-travel paradoxes,@footnote{Not to mention difficult
+implementation issues.} neither @code{FUNCTAB} nor @code{SYMTAB}
+are available as elements within the @code{SYMTAB} array.
+@end quotation
+@end table
+
+@sidebar Changing @code{NR} and @code{FNR}
+@cindex @code{NR} variable, changing
+@cindex @code{FNR} variable, changing
+@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}
+The following example shows this:
+
+@example
+$ @kbd{echo '1}
+> @kbd{2}
+> @kbd{3}
+> @kbd{4' | awk 'NR == 2 @{ NR = 17 @}}
+> @kbd{@{ print NR @}'}
+@print{} 1
+@print{} 17
+@print{} 18
+@print{} 19
+@end example
+
+@noindent
+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.
+@end sidebar
+
+@node ARGC and ARGV
+@subsection Using @code{ARGC} and @code{ARGV}
+@cindex @code{ARGC}/@code{ARGV} variables, how to use
+@cindex arguments, command-line
+@cindex command line, arguments
+
+@DBREF{Auto-set}
+presented the following program describing the information contained in @code{ARGC}
+and @code{ARGV}:
+
+@example
+$ @kbd{awk 'BEGIN @{}
+> @kbd{for (i = 0; i < ARGC; i++)}
+> @kbd{print ARGV[i]}
+> @kbd{@}' inventory-shipped mail-list}
+@print{} awk
+@print{} inventory-shipped
+@print{} mail-list
+@end example
+
+@noindent
+In this example, @code{ARGV[0]} contains @samp{awk}, @code{ARGV[1]}
+contains @samp{inventory-shipped}, and @code{ARGV[2]} contains
+@samp{mail-list}.
+Notice that the @command{awk} program is not entered in @code{ARGV}. The
+other 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.
+Given the following program in a file named @file{showargs.awk}:
+
+@example
+BEGIN @{
+ printf "A=%d, B=%d\n", A, B
+ for (i = 0; i < ARGC; i++)
+ printf "\tARGV[%d] = %s\n", i, ARGV[i]
+@}
+END @{ printf "A=%d, B=%d\n", A, B @}
+@end example
+
+@noindent
+Running it produces the following:
+
+@example
+$ @kbd{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.
+@DBXREF{Split Program} and
+@ifnotdocbook
+@DBPXREF{Tee Program}
+@end ifnotdocbook
+@ifdocbook
+@DBREF{Tee Program}
+@end ifdocbook
+for examples
+of each way of removing elements from @code{ARGV}.
+
+To actually get options into an @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.awk -- -v -q file1 file2 @dots{}
+@end example
+
+The following fragment processes @code{ARGV} in order to examine, and
+then remove, the previously mentioned command-line options:
+
+@example
+BEGIN @{
+ for (i = 1; i < ARGC; i++) @{
+ if (ARGV[i] == "-v")
+ verbose = 1
+ else if (ARGV[i] == "-q")
+ debug = 1
+ else if (ARGV[i] ~ /^-./) @{
+ e = sprintf("%s: unrecognized option -- %c",
+ ARGV[0], substr(ARGV[i], 2, 1))
+ print e > "/dev/stderr"
+ @} else
+ break
+ delete ARGV[i]
+ @}
+@}
+@end example
+
+@cindex differences in @command{awk} and @command{gawk}, @code{ARGC}/@code{ARGV} variables
+Ending the @command{awk} options with @option{--} isn't
+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 command line with
+@command{gawk} would be:
+
+@example
+gawk -f myprog.awk -q -v file1 file2 @dots{}
+@end example
+
+@noindent
+Because @option{-q} is not a valid @command{gawk} option, it and the
+following @option{-v} are passed on to the @command{awk} program.
+(@DBXREF{Getopt Function} for an @command{awk} library function that
+parses command-line options.)
+
+When designing your program, you should choose options that don't
+conflict with @command{gawk}'s, because it will process any options
+that it accepts before passing the rest of the command line on to
+your program. Using @samp{#!} with the @option{-E} option may help
+(@DBXREF{Executable Scripts}
+and
+@ifnotdocbook
+@DBPXREF{Options}).
+@end ifnotdocbook
+@ifdocbook
+@DBREF{Options}).
+@end ifdocbook
+
+@node Pattern Action Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+Pattern-action pairs make up the basic elements of an @command{awk}
+program. Patterns are either normal expressions, range expressions,
+regexp constants, one of the special keywords @code{BEGIN}, @code{END},
+@code{BEGINFILE}, @code{ENDFILE}, or empty. The action executes if
+the current record matches the pattern. Empty (missing) patterns match
+all records.
+
+@item
+I/O from @code{BEGIN} and @code{END} rules have certain constraints.
+This is also true, only more so, for @code{BEGINFILE} and @code{ENDFILE}
+rules. The latter two give you ``hooks'' into @command{gawk}'s file
+processing, allowing you to recover from a file that otherwise would
+cause a fatal error (such as a file that cannot be opened).
+
+@item
+Shell variables can be used in @command{awk} programs by careful
+use of shell quoting. It is easier to pass a shell variable into
+@command{awk} by using the @option{-v} option and an @command{awk}
+variable.
+
+@item
+Actions consist of statements enclosed in curly braces. Statements
+are built up from expressions, control statements, compound statements,
+input and output statements, and deletion statements.
+
+@item
+The control statements in @command{awk} are @code{if}-@code{else},
+@code{while}, @code{for}, and @code{do}-@code{while}. @command{gawk}
+adds the @code{switch} statement. There are two flavors of @code{for}
+statement: one for performing general looping, and the other for iterating
+through an array.
+
+@item
+@code{break} and @code{continue} let you exit early or start the next
+iteration of a loop (or get out of a @code{switch}).
+
+@item
+@code{next} and @code{nextfile} let you read the next record and start
+over at the top of your program, or skip to the next input file and
+start over, respectively.
+
+@item
+The @code{exit} statement terminates your program. When executed
+from an action (or function body) it transfers control to the
+@code{END} statements. From an @code{END} statement body, it exits
+immediately. You may pass an optional numeric value to be used
+as @command{awk}'s exit status.
+
+@item
+Some predefined variables provide control over @command{awk}, mainly for I/O.
+Other variables convey information from @command{awk} to your program.
+
+@item
+@code{ARGC} and @code{ARGV} make the command-line arguments available
+to your program. Manipulating them from a @code{BEGIN} rule lets you
+control how @command{awk} will process the provided @value{DF}s.
+
+@end itemize
+
+@node Arrays
+@chapter Arrays in @command{awk}
+@cindex arrays
+
+An @dfn{array} is a table of values called @dfn{elements}. The
+elements of an array are distinguished by their @dfn{indices}. 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} moves on to discuss @command{gawk}'s facility
+for sorting arrays, and ends with a brief description of @command{gawk}'s
+ability to support true arrays of arrays.
+
+@menu
+* Array Basics:: The basics of arrays.
+* Numeric Array Subscripts:: How to use numbers as subscripts in
+ @command{awk}.
+* Uninitialized Subscripts:: Using Uninitialized variables as subscripts.
+* Delete:: The @code{delete} statement removes an element
+ from an array.
+* Multidimensional:: Emulating multidimensional arrays in
+ @command{awk}.
+* Arrays of Arrays:: True multidimensional arrays.
+* Arrays Summary:: Summary of arrays.
+@end menu
+
+@node Array Basics
+@section The Basics of Arrays
+
+This @value{SECTION} presents the basics: working with elements
+in arrays one at a time, and traversing all of the elements in
+an array.
+
+@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.
+* Controlling Scanning:: Controlling the order in which arrays are
+ scanned.
+@end menu
+
+@node Array Intro
+@subsection Introduction to Arrays
+
+@cindex Wall, Larry
+@quotation
+@i{Doing linear scans over an associative array is like trying to club someone
+to death with a loaded Uzi.}
+@author Larry Wall
+@end quotation
+
+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, 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
+@ifnotdocbook
+as shown in @ref{figure-array-elements}:
+@end ifnotdocbook
+@ifdocbook
+as shown in @inlineraw{docbook, <xref linkend="figure-array-elements"/>}:
+@end ifdocbook
+
+@ifnotdocbook
+@float Figure,figure-array-elements
+@caption{A contiguous array}
+@ifinfo
+@center @image{array-elements, , , Basic Program Stages, txt}
+@end ifinfo
+@ifnotinfo
+@center @image{array-elements, , , Basic Program Stages}
+@end ifnotinfo
+@end float
+@end ifnotdocbook
+
+@docbook
+<figure id="figure-array-elements" float="0">
+<title>A contiguous array</title>
+<mediaobject>
+<imageobject role="web"><imagedata fileref="array-elements.png" format="PNG"/></imageobject>
+</mediaobject>
+</figure>
+@end docbook
+
+@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.
+
+@cindex arrays, indexing
+@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:
+
+@ifnotdocbook
+@example
+@r{Index} 3 @r{Value} 30
+@r{Index} 1 @r{Value} "foo"
+@r{Index} 0 @r{Value} 8
+@r{Index} 2 @r{Value} ""
+@end example
+@end ifnotdocbook
+
+@docbook
+<informaltable>
+<tgroup cols="2">
+<colspec colname="1" align="center"/>
+<colspec colname="2" align="center"/>
+<thead>
+<row>
+<entry>Index</entry>
+<entry>Value</entry>
+</row>
+</thead>
+
+<tbody>
+<row>
+<entry><literal>3</literal></entry>
+<entry><literal>30</literal></entry>
+</row>
+
+<row>
+<entry><literal>1</literal></entry>
+<entry><literal>"foo"</literal></entry>
+</row>
+
+<row>
+<entry><literal>0</literal></entry>
+<entry><literal>8</literal></entry>
+</row>
+
+<row>
+<entry><literal>2</literal></entry>
+<entry><literal>""</literal></entry>
+</row>
+
+</tbody>
+</tgroup>
+</informaltable>
+
+@end docbook
+
+@noindent
+The pairs are shown in jumbled order because their order is
+irrelevant.@footnote{The ordering will vary among @command{awk}
+implementations, which typically use hash tables to store array elements
+and values.}
+
+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:
+
+@ifnotdocbook
+@example
+@r{Index} 10 @r{Value} "number ten"
+@r{Index} 3 @r{Value} 30
+@r{Index} 1 @r{Value} "foo"
+@r{Index} 0 @r{Value} 8
+@r{Index} 2 @r{Value} ""
+@end example
+@end ifnotdocbook
+
+@docbook
+<informaltable>
+<tgroup cols="2">
+<colspec colname="1" align="center"/>
+<colspec colname="2" align="center"/>
+<thead>
+<row>
+<entry>Index</entry>
+<entry>Value</entry>
+</row>
+</thead>
+<tbody>
+
+<row>
+<entry><literal>10</literal></entry>
+<entry><literal>"number ten"</literal></entry>
+</row>
+
+<row>
+<entry><literal>3</literal></entry>
+<entry><literal>30</literal></entry>
+</row>
+
+<row>
+<entry><literal>1</literal></entry>
+<entry><literal>"foo"</literal></entry>
+</row>
+
+<row>
+<entry><literal>0</literal></entry>
+<entry><literal>8</literal></entry>
+</row>
+
+<row>
+<entry><literal>2</literal></entry>
+<entry><literal>""</literal></entry>
+</row>
+
+</tbody>
+</tgroup>
+</informaltable>
+
+@end docbook
+
+@noindent
+@cindex 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:
+
+@ifnotdocbook
+@example
+@r{Index} "dog" @r{Value} "chien"
+@r{Index} "cat" @r{Value} "chat"
+@r{Index} "one" @r{Value} "un"
+@r{Index} 1 @r{Value} "un"
+@end example
+@end ifnotdocbook
+
+@docbook
+<informaltable>
+<tgroup cols="2">
+<colspec colname="1" align="center"/>
+<colspec colname="2" align="center"/>
+<thead>
+<row>
+<entry>Index</entry>
+<entry>Value</entry>
+</row>
+</thead>
+<tbody>
+<row>
+<entry><literal>"dog"</literal></entry>
+<entry><literal>"chien"</literal></entry>
+</row>
+
+<row>
+<entry><literal>"cat"</literal></entry>
+<entry><literal>"chat"</literal></entry>
+</row>
+
+<row>
+<entry><literal>"one"</literal></entry>
+<entry><literal>"un"</literal></entry>
+</row>
+
+<row>
+<entry><literal>1</literal></entry>
+<entry><literal>"un"</literal></entry>
+</row>
+
+</tbody>
+</tgroup>
+</informaltable>
+
+@end docbook
+
+@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.
+There are some subtleties to how numbers work when used as
+array subscripts; this is discussed in more detail in
+@ref{Numeric Array Subscripts}.)
+Here, the number @code{1} isn't double quoted, because @command{awk}
+automatically converts it to a string.
+
+@cindex @command{gawk}, @code{IGNORECASE} variable in
+@cindex case sensitivity, array indices and
+@cindex arrays, and @code{IGNORECASE} variable
+@cindex @code{IGNORECASE} variable, and array indices
+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.
+
+@node Reference to Elements
+@subsection Referring to an Array Element
+@cindex arrays, referencing elements
+@cindex array members
+@cindex elements of 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-expression}]
+@end example
+
+@noindent
+Here, @var{array} is the name of an array. The expression @var{index-expression} 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}.
+
+@cindex arrays, unassigned elements
+@cindex unassigned array elements
+@cindex empty array elements
+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}).
+
+@cindex non-existent array elements
+@cindex arrays, elements that don't exist
+@quotation NOTE
+A reference to an element that does not exist @emph{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}.)
+
+Novice @command{awk} programmers often make the mistake of checking if
+an element exists by checking if the value is empty:
+
+@example
+# Check if "foo" exists in a: @ii{Incorrect!}
+if (a["foo"] != "") @dots{}
+@end example
+
+@noindent
+This is incorrect for two reasons. First, it @emph{creates} @code{a["foo"]}
+if it didn't exist before! Second, it is valid (if a bit unusual) to set
+an array element equal to the empty string.
+@end quotation
+
+@c @cindex arrays, @code{in} operator and
+@cindex @code{in} operator, testing if array element exists
+To determine whether an element exists in an array at a certain index, use
+the following expression:
+
+@example
+@var{indx} in @var{array}
+@end example
+
+@cindex side effects, array indexing
+@noindent
+This expression tests whether the particular index @var{indx} 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{indx}]}
+exists and zero (false) if it does not exist.
+(We use @var{indx} here, because @samp{index} is the name of a built-in
+function.)
+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
+@subsection Assigning Array Elements
+@cindex arrays, elements, assigning values
+@cindex elements in arrays, assigning values
+
+Array elements can be assigned values just like
+@command{awk} variables:
+
+@example
+@var{array}[@var{index-expression}] = @var{value}
+@end example
+
+@noindent
+@var{array} is the name of an array. The expression
+@var{index-expression} 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
+@subsection Basic Array Example
+@cindex arrays, an example of using
+
+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
+@subsection Scanning All Elements of an Array
+@cindex elements in arrays, scanning
+@cindex scanning arrays
+@cindex arrays, scanning
+@cindex loops, @code{for}, array 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, use in loops
+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, looping over 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.
+@DBXREF{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
+@DBXREF{Word Sorting}
+for a more detailed example of this type.
+
+@cindex arrays, elements, order of access by @code{in} operator
+@cindex elements in arrays, order of access by @code{in} operator
+@cindex @code{in} operator, order of array access
+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 in standard @command{awk} 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.
+
+As a point of information, @command{gawk} sets up the list of elements
+to be iterated over before the loop starts, and does not change it.
+But not all @command{awk} versions do so. Consider this program, named
+@file{loopcheck.awk}:
+
+@example
+BEGIN @{
+ a["here"] = "here"
+ a["is"] = "is"
+ a["a"] = "a"
+ a["loop"] = "loop"
+ for (i in a) @{
+ j++
+ a[j] = j
+ print i
+ @}
+@}
+@end example
+
+Here is what happens when run with @command{gawk} (and @command{mawk}):
+
+@example
+$ @kbd{gawk -f loopcheck.awk}
+@print{} here
+@print{} loop
+@print{} a
+@print{} is
+@end example
+
+Contrast this to BWK @command{awk}:
+
+@example
+$ @kbd{nawk -f loopcheck.awk}
+@print{} loop
+@print{} here
+@print{} is
+@print{} a
+@print{} 1
+@end example
+
+@node Controlling Scanning
+@subsection Using Predefined Array Scanning Orders with @command{gawk}
+
+This @value{SUBSECTION} describes a feature that is specific to @command{gawk}.
+
+By default, when a @code{for} loop traverses an array, the order
+is undefined, meaning that the @command{awk} implementation
+determines the order in which the array is traversed.
+This order is usually based on the internal implementation of arrays
+and will vary from one version of @command{awk} to the next.
+
+@cindex array scanning order, controlling
+@cindex controlling array scanning order
+Often, though, you may wish to do something simple, such as
+``traverse the array by comparing the indices in ascending order,''
+or ``traverse the array by comparing the values in descending order.''
+@command{gawk} provides two mechanisms which give you this control.
+
+@itemize @value{BULLET}
+@item
+Set @code{PROCINFO["sorted_in"]} to one of a set of predefined values.
+We describe this now.
+
+@item
+Set @code{PROCINFO["sorted_in"]} to the name of a user-defined function
+to use for comparison of array elements. This advanced feature
+is described later in @ref{Array Sorting}.
+@end itemize
+
+@cindex @code{PROCINFO}, values of @code{sorted_in}
+The following special values for @code{PROCINFO["sorted_in"]} are available:
+
+@table @code
+@item "@@unsorted"
+Array elements are processed in arbitrary order, which is the default
+@command{awk} behavior.
+
+@item "@@ind_str_asc"
+Order by indices in ascending order compared as strings; this is the most basic sort.
+(Internally, array indices are always strings, so with @samp{a[2*5] = 1}
+the index is @code{"10"} rather than numeric 10.)
+
+@item "@@ind_num_asc"
+Order by indices in ascending order but force them to be treated as numbers in the process.
+Any index with a non-numeric value will end up positioned as if it were zero.
+
+@item "@@val_type_asc"
+Order by element values in ascending order (rather than by indices).
+Ordering is by the type assigned to the element
+(@pxref{Typing and Comparison}).
+All numeric values come before all string values,
+which in turn come before all subarrays.
+(Subarrays have not been described yet;
+@pxref{Arrays of Arrays}.)
+
+@item "@@val_str_asc"
+Order by element values in ascending order (rather than by indices). Scalar values are
+compared as strings. Subarrays, if present, come out last.
+
+@item "@@val_num_asc"
+Order by element values in ascending order (rather than by indices). Scalar values are
+compared as numbers. Subarrays, if present, come out last.
+When numeric values are equal, the string values are used to provide
+an ordering: this guarantees consistent results across different
+versions of the C @code{qsort()} function,@footnote{When two elements
+compare as equal, the C @code{qsort()} function does not guarantee
+that they will maintain their original relative order after sorting.
+Using the string value to provide a unique ordering when the numeric
+values are equal ensures that @command{gawk} behaves consistently
+across different environments.} which @command{gawk} uses internally
+to perform the sorting.
+
+@item "@@ind_str_desc"
+String indices ordered from high to low.
+
+@item "@@ind_num_desc"
+Numeric indices ordered from high to low.
+
+@item "@@val_type_desc"
+Element values, based on type, ordered from high to low.
+Subarrays, if present, come out first.
+
+@item "@@val_str_desc"
+Element values, treated as strings, ordered from high to low.
+Subarrays, if present, come out first.
+
+@item "@@val_num_desc"
+Element values, treated as numbers, ordered from high to low.
+Subarrays, if present, come out first.
+@end table
+
+The array traversal order is determined before the @code{for} loop
+starts to run. Changing @code{PROCINFO["sorted_in"]} in the loop body
+does not affect the loop.
+For example:
+
+@example
+$ @kbd{gawk '}
+> @kbd{BEGIN @{}
+> @kbd{ a[4] = 4}
+> @kbd{ a[3] = 3}
+> @kbd{ for (i in a)}
+> @kbd{ print i, a[i]}
+> @kbd{@}'}
+@print{} 4 4
+@print{} 3 3
+$ @kbd{gawk '}
+> @kbd{BEGIN @{}
+> @kbd{ PROCINFO["sorted_in"] = "@@ind_str_asc"}
+> @kbd{ a[4] = 4}
+> @kbd{ a[3] = 3}
+> @kbd{ for (i in a)}
+> @kbd{ print i, a[i]}
+> @kbd{@}'}
+@print{} 3 3
+@print{} 4 4
+@end example
+
+When sorting an array by element values, if a value happens to be
+a subarray then it is considered to be greater than any string or
+numeric value, regardless of what the subarray itself contains,
+and all subarrays are treated as being equal to each other. Their
+order relative to each other is determined by their index strings.
+
+Here are some additional things to bear in mind about sorted
+array traversal:
+
+@itemize @value{BULLET}
+@item
+The value of @code{PROCINFO["sorted_in"]} is global. That is, it affects
+all array traversal @code{for} loops. If you need to change it within your
+own code, you should see if it's defined and save and restore the value:
+
+@example
+@dots{}
+if ("sorted_in" in PROCINFO) @{
+ save_sorted = PROCINFO["sorted_in"]
+ PROCINFO["sorted_in"] = "@@val_str_desc" # or whatever
+@}
+@dots{}
+if (save_sorted)
+ PROCINFO["sorted_in"] = save_sorted
+@end example
+
+@item
+As already mentioned, the default array traversal order is represented by
+@code{"@@unsorted"}. You can also get the default behavior by assigning
+the null string to @code{PROCINFO["sorted_in"]} or by just deleting the
+@code{"sorted_in"} element from the @code{PROCINFO} array with
+the @code{delete} statement.
+(The @code{delete} statement hasn't been described yet; @pxref{Delete}.)
+@end itemize
+
+In addition, @command{gawk} provides built-in functions for
+sorting arrays; see @ref{Array Sorting Functions}.
+
+@node Numeric Array Subscripts
+@section Using Numbers to Subscript Arrays
+
+@cindex numbers, as array subscripts
+@cindex arrays, numeric subscripts
+@cindex subscripts in arrays, numbers as
+@cindex @code{CONVFMT} variable, and array subscripts
+An important aspect to remember about arrays 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 predefined 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,
+because @code{"12.15"} is different from @code{"12.153"}.
+
+@cindex converting integer array subscripts
+@cindex integer array indices
+According to the rules for conversions
+(@pxref{Conversion}), integer
+values always convert 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++)
+ @ii{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
+@ifnotdocbook
+(@pxref{Nondecimal-numbers})
+@end ifnotdocbook
+@ifdocbook
+(covered in @ref{Nondecimal-numbers})
+@end ifdocbook
+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 you would expect them to. But it is useful to have a precise
+knowledge of the actual rules, as they can sometimes 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
+$ @kbd{echo 'line 1}
+> @kbd{line 2}
+> @kbd{line 3' | awk '@{ l[lines] = $0; ++lines @}}
+> @kbd{END @{}
+> @kbd{for (i = lines - 1; i >= 0; i--)}
+> @kbd{print l[i]}
+> @kbd{@}'}
+@print{} line 3
+@print{} line 2
+@end example
+
+Unfortunately, the very first line of input data did not appear in the
+output!
+
+Upon first glance, we would think that 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 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-expression}]
+@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 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, and deleting array elements
+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.
+However, 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 common extensions, @code{delete} to delete entire arrays
+@cindex extensions, common@comma{} @code{delete} to delete entire arrays
+@cindex arrays, deleting entire contents
+@cindex deleting entire arrays
+@cindex @code{delete} @var{array}
+@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
+
+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.
+
+This form of the @code{delete} statement is also supported
+by BWK @command{awk} and @command{mawk}, as well as
+by a number of other implementations.
+
+@cindex Brian Kernighan's @command{awk}
+@quotation NOTE
+For many years, using @code{delete} without a subscript was a common
+extension. In September 2012, it was accepted for inclusion into the
+POSIX standard. See @uref{http://austingroupbugs.net/view.php?id=544,
+the Austin Group website}.
+@end quotation
+
+@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.
+
+@quotation CAUTION
+Deleting all the elements from an array does not change its type; you cannot
+clear 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
+@end quotation
+
+@node Multidimensional
+@section Multidimensional Arrays
+
+@menu
+* Multiscanning:: Scanning multidimensional arrays.
+@end menu
+
+@cindex subscripts in arrays, multidimensional
+@cindex arrays, multidimensional
+A @dfn{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 many
+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, and 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"]}.
+
+@cindex @code{in} operator, index existence in multidimensional arrays
+To test whether a particular index sequence exists in a
+multidimensional array, use the same operator (@code{in}) that is
+used for single-dimensional arrays. Write the whole sequence of indices
+in parentheses, separated by commas, as the left operand:
+
+@example
+if ((@var{subscript1}, @var{subscript2}, @dots{}) in @var{array})
+ @dots{}
+@end example
+
+Here is an example that 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 Multiscanning
+@subsection Scanning Multidimensional Arrays
+
+There is no special @code{for} statement for scanning a
+``multidimensional'' array. There cannot be one, because, in truth,
+@command{awk} does not have
+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
+@cindex scanning multidimensional arrays
+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 Arrays of Arrays
+@section Arrays of Arrays
+@cindex arrays of arrays
+
+@command{gawk} goes beyond standard @command{awk}'s multidimensional
+array access and provides true arrays of
+arrays. Elements of a subarray are referred to by their own indices
+enclosed in square brackets, just like the elements of the main array.
+For example, the following creates a two-element subarray at index @code{1}
+of the main array @code{a}:
+
+@example
+a[1][1] = 1
+a[1][2] = 2
+@end example
+
+This simulates a true two-dimensional array. Each subarray element can
+contain another subarray as a value, which in turn can hold other arrays
+as well. In this way, you can create arrays of three or more dimensions.
+The indices can be any @command{awk} expression, including scalars
+separated by commas (i.e., a regular @command{awk} simulated
+multidimensional subscript). So the following is valid in
+@command{gawk}:
+
+@example
+a[1][3][1, "name"] = "barney"
+@end example
+
+Each subarray and the main array can be of different length. In fact, the
+elements of an array or its subarray do not all have to have the same
+type. This means that the main array and any of its subarrays can be
+non-rectangular, or jagged in structure. You can assign a scalar value to
+the index @code{4} of the main array @code{a}, even though @code{a[1]}
+is itself an array and not a scalar:
+
+@example
+a[4] = "An element in a jagged array"
+@end example
+
+The terms @dfn{dimension}, @dfn{row}, and @dfn{column} are
+meaningless when applied
+to such an array, but we will use ``dimension'' henceforth to imply the
+maximum number of indices needed to refer to an existing element. The
+type of any element that has already been assigned cannot be changed
+by assigning a value of a different type. You have to first delete the
+current element, which effectively makes @command{gawk} forget about
+the element at that index:
+
+@example
+delete a[4]
+a[4][5][6][7] = "An element in a four-dimensional array"
+@end example
+
+@noindent
+This removes the scalar value from index @code{4} and then inserts a
+subarray of subarray of subarray containing a scalar. You can also
+delete an entire subarray or subarray of subarrays:
+
+@example
+delete a[4][5]
+a[4][5] = "An element in subarray a[4]"
+@end example
+
+But recall that you can not delete the main array @code{a} and then use it
+as a scalar.
+
+The built-in functions which take array arguments can also be used
+with subarrays. For example, the following code fragment uses @code{length()}
+(@pxref{String Functions})
+to determine the number of elements in the main array @code{a} and
+its subarrays:
+
+@example
+print length(a), length(a[1]), length(a[1][3])
+@end example
+
+@noindent
+This results in the following output for our main array @code{a}:
+
+@example
+2, 3, 1
+@end example
+
+@noindent
+The @samp{@var{subscript} in @var{array}} expression
+(@pxref{Reference to Elements}) works similarly for both
+regular @command{awk}-style
+arrays and arrays of arrays. For example, the tests @samp{1 in a},
+@samp{3 in a[1]}, and @samp{(1, "name") in a[1][3]} all evaluate to
+one (true) for our array @code{a}.
+
+The @samp{for (item in array)} statement (@pxref{Scanning an Array})
+can be nested to scan all the
+elements of an array of arrays if it is rectangular in structure. In order
+to print the contents (scalar values) of a two-dimensional array of arrays
+(i.e., in which each first-level element is itself an
+array, not necessarily of the same length)
+you could use the following code:
+
+@example
+for (i in array)
+ for (j in array[i])
+ print array[i][j]
+@end example
+
+The @code{isarray()} function (@pxref{Type Functions})
+lets you test if an array element is itself an array:
+
+@example
+for (i in array) @{
+ if (isarray(array[i]) @{
+ for (j in array[i]) @{
+ print array[i][j]
+ @}
+ @}
+ else
+ print array[i]
+@}
+@end example
+
+If the structure of a jagged array of arrays is known in advance,
+you can often devise workarounds using control statements. For example,
+the following code prints the elements of our main array @code{a}:
+
+@example
+for (i in a) @{
+ for (j in a[i]) @{
+ if (j == 3) @{
+ for (k in a[i][j])
+ print a[i][j][k]
+ @} else
+ print a[i][j]
+ @}
+@}
+@end example
+
+@noindent
+@DBXREF{Walking Arrays} for a user-defined function that ``walks'' an
+arbitrarily dimensioned array of arrays.
+
+Recall that a reference to an uninitialized array element yields a value
+of @code{""}, the null string. This has one important implication when you
+intend to use a subarray as an argument to a function, as illustrated by
+the following example:
+
+@example
+$ @kbd{gawk 'BEGIN @{ split("a b c d", b[1]); print b[1][1] @}'}
+@error{} gawk: cmd. line:1: fatal: split: second argument is not an array
+@end example
+
+The way to work around this is to first force @code{b[1]} to be an array by
+creating an arbitrary index:
+
+@example
+$ @kbd{gawk 'BEGIN @{ b[1][1] = ""; split("a b c d", b[1]); print b[1][1] @}'}
+@print{} a
+@end example
+
+@node Arrays Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+Standard @command{awk} provides one-dimensional associative arrays
+(arrays indexed by string values). All arrays are associative; numeric
+indices are converted automatically to strings.
+
+@item
+Array elements are referenced as @code{@var{array}[@var{indx}]}.
+Referencing an element creates it if it did not exist previously.
+
+@item
+The proper way to see if an array has an element with a given index
+is to use the @code{in} operator: @samp{@var{indx} in @var{array}}.
+
+@item
+Use @samp{for (@var{indx} in @var{array}) @dots{}} to scan through all the
+individual elements of an array. In the body of the loop, @var{indx} takes
+on the value of each element's index in turn.
+
+@item
+The order in which a @samp{for (@var{indx} in @var{array})} loop
+traverses an array is undefined in POSIX @command{awk} and varies among
+implementations. @command{gawk} lets you control the order by assigning
+special predefined values to @code{PROCINFO["sorted_in"]}.
+
+@item
+Use @samp{delete @var{array}[@var{indx}]} to delete an individual element.
+To delete all of the elements in an array,
+use @samp{delete @var{array}}.
+This latter feature has been a common extension for many
+years and is now standard, but may not be supported by all commercial
+versions of @command{awk}.
+
+@item
+Standard @command{awk} simulates multidimensional arrays by separating
+subscript values with a comma. The values are concatenated into a
+single string, separated by the value of @code{SUBSEP}. The fact
+that such a subscript was created in this way is not retained; thus
+changing @code{SUBSEP} may have unexpected consequences. You can use
+@samp{(@var{sub1}, @var{sub2}, @dots{}) in @var{array}} to see if such
+a multidimensional subscript exists in @var{array}.
+
+@item
+@command{gawk} provides true arrays of arrays. You use a separate
+set of square brackets for each dimension in such an array:
+@code{data[row][col]}, for example. Array elements may thus be either
+scalar values (number or string) or another array.
+
+@item
+Use the @code{isarray()} built-in function to determine if an array
+element is itself a subarray.
+
+@end itemize
+
+
+@node Functions
+@chapter Functions
+
+@cindex functions, built-in
+@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, sort arrays,
+provide type information, 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.
+* Indirect Calls:: Choosing the function to call at runtime.
+* Functions Summary:: Summary of functions.
+@end menu
+
+@node Built-in
+@section Built-In Functions
+
+@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.
+* Type Functions:: Functions for type information.
+* 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
+opening parenthesis, but nonetheless 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
+@cindex numeric functions
+
+The following list describes all of
+the built-in functions that work with numbers.
+Optional parameters are enclosed in square brackets@w{ ([ ]):}
+
+@c @asis for docbook
+@table @asis
+@item @code{atan2(@var{y}, @var{x})}
+@cindexawkfunc{atan2}
+@cindex arctangent
+Return the arctangent of @code{@var{y} / @var{x}} in radians.
+You can use @samp{pi = atan2(0, -1)} to retrieve the value of
+@value{PI}.
+
+@item @code{cos(@var{x})}
+@cindexawkfunc{cos}
+@cindex cosine
+Return the cosine of @var{x}, with @var{x} in radians.
+
+@item @code{div(@var{numerator}, @var{denominator}, @var{result})}
+@cindexawkfunc{div}
+@cindex div
+Perform integer division, similar to the standard C function of the
+same name. First, truncate @code{numerator} and @code{denominator}
+towards zero, creating integer values. Clear the @code{result}
+array, and then set @code{result["quotient"]} to the result of
+@samp{numerator / denominator}, truncated towards zero to an integer,
+and set @code{result["remainder"]} to the result of @samp{numerator %
+denominator}, truncated towards zero to an integer. This function is
+primarily intended for use with arbitrary length integers; it avoids
+creating MPFR arbitrary precision floating-point values (@pxref{Arbitrary
+Precision Integers}).
+
+This function is a @code{gawk} extension. It is not available in
+compatibility mode (@pxref{Options}).
+
+@item @code{exp(@var{x})}
+@cindexawkfunc{exp}
+@cindex exponent
+Return the exponential of @var{x} (@code{e ^ @var{x}}) or report
+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 @code{int(@var{x})}
+@cindexawkfunc{int}
+@cindex round to nearest integer
+Return 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 @code{log(@var{x})}
+@cindexawkfunc{log}
+@cindex logarithm
+Return the natural logarithm of @var{x}, if @var{x} is positive;
+otherwise, return @code{NaN} (``not a number'') on IEEE 754 systems.
+Additionally, @command{gawk} prints a warning message when @code{x}
+is negative.
+
+@item @code{rand()}
+@cindexawkfunc{rand}
+@cindex random numbers, @code{rand()}/@code{srand()} functions
+Return 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()}
+on many Unix systems
+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 seeding random number generator
+@cindex random numbers, seed of
+@quotation 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}.@footnote{@command{mawk}
+uses a different seed each time.} 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()}.
+@end quotation
+
+@item @code{sin(@var{x})}
+@cindexawkfunc{sin}
+@cindex sine
+Return the sine of @var{x}, with @var{x} in radians.
+
+@item @code{sqrt(@var{x})}
+@cindexawkfunc{sqrt}
+@cindex square root
+Return the positive square root of @var{x}.
+@command{gawk} prints a warning message
+if @var{x} is negative. Thus, @code{sqrt(4)} is 2.
+
+@item @code{srand(}[@var{x}]@code{)}
+@cindexawkfunc{srand}
+Set 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 although 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.
+
+@quotation CAUTION
+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}.
+@end quotation
+
+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.
+
+POSIX does not specify the initial seed; it differs among @command{awk}
+implementations.
+@end table
+
+@node String Functions
+@subsection String-Manipulation Functions
+@cindex string-manipulation functions
+
+The functions in this @value{SECTION} look at or change the text of one
+or more strings.
+
+@code{gawk} understands locales (@pxref{Locales}), and does all
+string processing in terms of @emph{characters}, not @emph{bytes}.
+This distinction is particularly important to understand for locales
+where one character may be represented by multiple bytes. Thus, for
+example, @code{length()} returns the number of characters in a string,
+and not the number of bytes used to represent those characters. Similarly,
+@code{index()} works with character indices, and not byte indices.
+
+@quotation CAUTION
+A number of functions deal with indices into strings. For these
+functions, the first character of a string is at position (index) one.
+This is different from C and the languages descended from it, where the
+first character is at position zero. You need to remember this when
+doing index calculations, particularly if you are used to C.
+@end quotation
+
+In the following list, optional parameters are enclosed in square brackets@w{ ([ ]).}
+Several functions perform string substitution; the full discussion is
+provided in the description of the @code{sub()} function, which comes
+toward the end, because the list is presented alphabetically.
+
+Those functions that are specific to @command{gawk} are marked with a
+pound sign (@samp{#}). They are not available in compatibility mode
+(@pxref{Options}):
+
+
+@menu
+* Gory Details:: More than you want to know about @samp{\} and
+ @samp{&} with @code{sub()}, @code{gsub()}, and
+ @code{gensub()}.
+@end menu
+
+@c @asis for docbook
+@table @asis
+@item @code{asort(}@var{source} [@code{,} @var{dest} [@code{,} @var{how} ] ]@code{) #}
+@itemx @code{asorti(}@var{source} [@code{,} @var{dest} [@code{,} @var{how} ] ]@code{) #}
+@cindexgawkfunc{asorti}
+@cindex sort array
+@cindex arrays, elements, retrieving number of
+@cindexgawkfunc{asort}
+@cindex sort array indices
+These two functions are similar in behavior, so they are described
+together.
+
+@quotation NOTE
+The following description ignores the third argument, @var{how}, as it
+requires understanding features that we have not discussed yet. Thus,
+the discussion here is a deliberate simplification. (We do provide all
+the details later on; see @DBREF{Array Sorting Functions} for the full story.)
+@end quotation
+
+Both functions return the number of elements in the array @var{source}.
+For @command{asort()}, @command{gawk} sorts the values of @var{source}
+and replaces the indices of the sorted values of @var{source} 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.
+
+@cindex @command{gawk}, @code{IGNORECASE} variable in
+When comparing strings, @code{IGNORECASE} affects the sorting
+(@pxref{Array Sorting Functions}). If the
+@var{source} array contains subarrays as values (@pxref{Arrays of
+Arrays}), they will come last, after all scalar values.
+Subarrays are @emph{not} recursively sorted.
+
+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{asorti()} function works similarly to @code{asort()}, however,
+the @emph{indices} are sorted, instead of the values. Thus, in the
+previous example, starting with the same initial set of indices and
+values in @code{a}, calling @samp{asorti(a)} would yield:
+
+@example
+a[1] = "first"
+a[2] = "last"
+a[3] = "middle"
+@end example
+
+@item @code{gensub(@var{regexp}, @var{replacement}, @var{how}} [@code{, @var{target}}]@code{) #}
+@cindexgawkfunc{gensub}
+@cindex search and replace in strings
+@cindex substitute in string
+Search the target string @var{target} for matches of the regular
+expression @var{regexp}. If @var{how} is a string beginning with
+@samp{g} or @samp{G} (short for ``global''), then replace all matches of @var{regexp} with
+@var{replacement}. Otherwise, @var{how} is treated as a number indicating
+which match of @var{regexp} to replace. If no @var{target} is supplied,
+use @code{$0}. It returns the modified string as the result
+of the function and the original target string is @emph{not} changed.
+
+@code{gensub()} is a general substitution function. Its purpose is
+to provide more features than the standard @code{sub()} and @code{gsub()}
+functions.
+
+@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
+$ @kbd{gawk '}
+> @kbd{BEGIN @{}
+> @kbd{a = "abc def"}
+> @kbd{b = gensub(/(.+) (.+)/, "\\2 \\1", "g", a)}
+> @kbd{print b}
+> @kbd{@}'}
+@print{} def abc
+@end example
+
+@noindent
+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
+$ @kbd{echo a b c a b c |}
+> @kbd{gawk '@{ print gensub(/a/, "AA", 2) @}'}
+@print{} a b c AA b c
+@end example
+
+In this case, @code{$0} is 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}.
+
+@item @code{gsub(@var{regexp}, @var{replacement}} [@code{, @var{target}}]@code{)}
+@cindexawkfunc{gsub}
+Search @var{target} for
+@emph{all} of the longest, leftmost, @emph{nonoverlapping} matching
+substrings it can find and replace them with @var{replacement}.
+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 @code{index(@var{in}, @var{find})}
+@cindexawkfunc{index}
+@cindex search in string
+@cindex find substring in string
+Search the string @var{in} for the first occurrence of the string
+@var{find}, and return the position in characters where that occurrence
+begins in the string @var{in}. Consider the following example:
+
+@example
+$ @kbd{awk 'BEGIN @{ print index("peanut", "an") @}'}
+@print{} 3
+@end example
+
+@noindent
+If @var{find} is not found, @code{index()} returns zero.
+
+@cindex dark corner, regexp as second argument to @code{index()}
+With BWK @command{awk} and @command{gawk},
+it is a fatal error to use a regexp constant for @var{find}.
+Other implementations allow it, simply treating the regexp
+constant as an expression meaning @samp{$0 ~ /regexp/}. @value{DARKCORNER}.
+
+@item @code{length(}[@var{string}]@code{)}
+@cindexawkfunc{length}
+@cindex string length
+@cindex length of string
+Return 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 five. By
+contrast, @code{length(15 * 35)} works out to three. In this example,
+@iftex
+@math{15 @cdot 35 = 525},
+@end iftex
+@ifnottex
+@ifnotdocbook
+15 * 35 = 525,
+@end ifnotdocbook
+@end ifnottex
+@docbook
+15 &sdot; 35 = 525, @c
+@end docbook
+and 525 is then converted to the string @code{"525"}, which has
+three characters.
+
+@cindex length of input record
+@cindex input record, length of
+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 considered poor practice,
+although the 2008 POSIX standard explicitly allows it, to
+support historical practice. For programs to be maximally portable,
+always supply the parentheses.
+@end quotation
+
+@cindex dark corner, @code{length()} function
+If @code{length()} is called with a variable that has not been used,
+@command{gawk} forces the variable to be a scalar. Other
+implementations of @command{awk} leave the variable without a type.
+@value{DARKCORNER}
+Consider:
+
+@example
+$ @kbd{gawk 'BEGIN @{ print length(x) ; x[1] = 1 @}'}
+@print{} 0
+@error{} gawk: fatal: attempt to use scalar `x' as array
+
+$ @kbd{nawk 'BEGIN @{ print length(x) ; x[1] = 1 @}'}
+@print{} 0
+@end example
+
+@noindent
+If @option{--lint} has
+been specified on the command line, @command{gawk} issues a
+warning about this.
+
+@cindex common extensions, @code{length()} applied to an array
+@cindex extensions, common@comma{} @code{length()} applied to an array
+@cindex differences between @command{gawk} and @command{awk}
+@cindex number of array elements
+@cindex array, number of elements
+With @command{gawk} and several other @command{awk} implementations, when given an
+array argument, the @code{length()} function returns the number of elements
+in the array. @value{COMMONEXT}
+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 @code{match(@var{string}, @var{regexp}} [@code{, @var{array}}]@code{)}
+@cindexawkfunc{match}
+@cindex string, regular expression match
+@cindex match regexp in string
+Search @var{string} for the
+longest, leftmost substring matched by the regular expression,
+@var{regexp} and return the character position (index)
+at which that substring begins (one, if it starts at the beginning of
+@var{string}). If no match is found, return zero.
+
+The @var{regexp} argument may be either a regexp constant
+(@code{/}@dots{}@code{/}) or a string constant (@code{"}@dots{}@code{"}).
+In the latter case, the string is treated as a regexp to be matched.
+@DBXREF{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 predefined variable @code{RSTART} to
+the index. It also sets the predefined 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 zeroth 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
+$ @kbd{echo foooobazbarrrrr |}
+> @kbd{gawk '@{ match($0, /(fo+).+(bar*)/, arr)}
+> @kbd{print arr[1], arr[2] @}'}
+@print{} foooo barrrrr
+@end example
+
+In addition,
+multidimensional subscripts are available providing
+the start index and length of each matched subexpression:
+
+@example
+$ @kbd{echo foooobazbarrrrr |}
+> @kbd{gawk '@{ match($0, /(fo+).+(bar*)/, arr)}
+> @kbd{print arr[1], arr[2]}
+> @kbd{print arr[1, "start"], arr[1, "length"]}
+> @kbd{print arr[2, "start"], arr[2, "length"]}
+> @kbd{@}'}
+@print{} foooo barrrrr
+@print{} 1 5
+@print{} 9 7
+@end example
+
+There may not be subscripts for the start and index for every parenthesized
+subexpression, because 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 @code{patsplit(@var{string}, @var{array}} [@code{, @var{fieldpat}} [@code{, @var{seps}} ] ]@code{) #}
+@cindexgawkfunc{patsplit}
+@cindex split string into array
+Divide
+@var{string} into pieces defined by @var{fieldpat}
+and store the pieces in @var{array} and the separator strings in the
+@var{seps} array. The first piece is stored in
+@code{@var{array}[1]}, the second piece in @code{@var{array}[2]}, and so
+forth. The third argument, @var{fieldpat}, is
+a regexp describing the fields in @var{string} (just as @code{FPAT} is
+a regexp describing the fields in input records).
+It may be either a regexp constant or a string.
+If @var{fieldpat} is omitted, the value of @code{FPAT} is used.
+@code{patsplit()} returns the number of elements created.
+@code{@var{seps}[@var{i}]} is
+the separator string
+between @code{@var{array}[@var{i}]} and @code{@var{array}[@var{i}+1]}.
+Any leading separator will be in @code{@var{seps}[0]}.
+
+The @code{patsplit()} function splits strings into pieces in a
+manner similar to the way input lines are split into fields using @code{FPAT}
+(@pxref{Splitting By Content}).
+
+Before splitting the string, @code{patsplit()} deletes any previously existing
+elements in the arrays @var{array} and @var{seps}.
+
+@item @code{split(@var{string}, @var{array}} [@code{, @var{fieldsep}} [@code{, @var{seps}} ] ]@code{)}
+@cindexawkfunc{split}
+Divide @var{string} into pieces separated by @var{fieldsep}
+and store the pieces in @var{array} and the separator strings in the
+@var{seps} 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.
+@var{seps} is a @command{gawk} extension with @code{@var{seps}[@var{i}]}
+being the separator string
+between @code{@var{array}[@var{i}]} and @code{@var{array}[@var{i}+1]}.
+If @var{fieldsep} is a single
+space then any leading whitespace goes into @code{@var{seps}[0]} and
+any trailing
+whitespace goes into @code{@var{seps}[@var{n}]} where @var{n} is the
+return value of
+@code{split()} (i.e., the number of elements in @var{array}).
+
+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, "-", seps)
+@end example
+
+@noindent
+@cindex strings splitting, example
+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
+
+and sets the contents of the array @code{seps} as follows:
+
+@example
+seps[1] = "-"
+seps[2] = "-"
+@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 in values assigned to
+the elements of
+@var{array} but not in @var{seps}, 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.
+@value{COMMONEXT}
+
+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.
+@DBXREF{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 arrays @var{array} and @var{seps}.
+
+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}.
+
+In POSIX mode (@pxref{Options}), the fourth argument is not allowed.
+
+@item @code{sprintf(@var{format}, @var{expression1}, @dots{})}
+@cindexawkfunc{sprintf}
+@cindex formatting strings
+Return (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{@samp{pi = 3.14 (approx.)}} to the variable @code{pival}.
+
+@cindexgawkfunc{strtonum}
+@cindex convert string to number
+@item @code{strtonum(@var{str}) #}
+Examine @var{str} and return 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
+$ @kbd{echo 0x11 |}
+> @kbd{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.
+@DBXREF{Nondecimal Data} for more information.}
+
+Note also that @code{strtonum()} uses the current locale's decimal point
+for recognizing numbers (@pxref{Locales}).
+
+@item @code{sub(@var{regexp}, @var{replacement}} [@code{, @var{target}}]@code{)}
+@cindexawkfunc{sub}
+@cindex replace in string
+Search @var{target}, which is treated as a string, for the
+leftmost, longest substring matched by the regular expression @var{regexp}.
+Modify the entire string
+by replacing the matched text with @var{replacement}.
+The modified string becomes the new value of @var{target}.
+Return the number of substitutions made (zero or one).
+
+The @var{regexp} argument may be either a regexp constant
+(@code{/}@dots{}@code{/}) or a string constant (@code{"}@dots{}@code{"}).
+In the latter case, the string is treated as a regexp to be matched.
+@DBXREF{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 substitution, 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{@samp{wither, water, everywhere}}, by replacing the
+leftmost longest occurrence of @samp{at} with @samp{ith}.
+
+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
+$ @kbd{awk 'BEGIN @{}
+> @kbd{str = "daabaaa"}
+> @kbd{sub(/a+/, "C&C", str)}
+> @kbd{print str}
+> @kbd{@}'}
+@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 element.
+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
+like 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 such erroneous code.
+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 @code{substr(@var{string}, @var{start}} [@code{, @var{length}} ]@code{)}
+@cindexawkfunc{substr}
+@cindex substring
+Return 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, @code{substr()} 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}.
+
+@cindex Brian Kernighan's @command{awk}
+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:
+BWK @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} treat
+@code{substr()} as assignable, 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 strings, converting letter case
+@item @code{tolower(@var{string})}
+@cindexawkfunc{tolower}
+@cindex convert string to lower case
+Return 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 @code{toupper(@var{string})}
+@cindexawkfunc{toupper}
+@cindex convert string to upper case
+Return 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
+
+@sidebar Matching the Null String
+@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
+$ @kbd{echo abc | awk '@{ gsub(/m*/, "X"); print @}'}
+@print{} XaXbXcX
+@end example
+
+@noindent
+Although this makes a certain amount of sense, it can be surprising.
+@end sidebar
+
+
+@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
+
+@quotation CAUTION
+This subsubsection has been reported to cause headaches.
+You might want to skip it upon first reading.
+@end quotation
+
+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 to execute.
+Then there is the runtime level, which is when @command{awk} actually scans the
+replacement string to determine what to generate.
+
+@cindex Brian Kernighan's @command{awk}
+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, you must type two backslashes at the lexical level.
+When a character that is not valid for an escape sequence follows the
+@samp{\}, BWK @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 @code{sub()} and @code{gsub()}}
+@tex
+\vbox{\bigskip
+% We need more characters for escape and tab ...
+\catcode`_ = 0
+\catcode`! = 4
+% ... since this table has lots of &'s and \'s, so we unspecialize them.
+\catcode`\& = \other \catcode`\\ = \other
+_halign{_hfil#!_qquad_hfil#!_qquad#_hfil_cr
+ 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.
+
+Several editions of the POSIX standard attempted to fix this problem
+but weren't successful. The details are irrelevant at this point in time.
+
+At one point, 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{GNU @command{awk} rules for @code{sub()} and backslash}
+@tex
+\vbox{\bigskip
+% We need more characters for escape and tab ...
+\catcode`_ = 0
+\catcode`! = 4
+% ... since this table has lots of &'s and \'s, so we unspecialize them.
+\catcode`\& = \other \catcode`\\ = \other
+_halign{_hfil#!_qquad_hfil#!_qquad#_hfil_cr
+ 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 rules for @code{sub()} and
+@code{gsub()}. The POSIX standard took much longer to be revised than
+was expected. In addition, the @command{gawk} maintainer's proposal was
+lost during the standardization process. The final rules are
+somewhat simpler. The results are similar except for one case.
+
+@cindex POSIX @command{awk}, functions and, @code{gsub()}/@code{sub()}
+The 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-sub}.
+
+@float Table,table-posix-sub
+@caption{POSIX rules for @code{sub()} and @code{gsub()}}
+@tex
+\vbox{\bigskip
+% We need more characters for escape and tab ...
+\catcode`_ = 0
+\catcode`! = 4
+% ... since this table has lots of &'s and \'s, so we unspecialize them.
+\catcode`\& = \other \catcode`\\ = \other
+_halign{_hfil#!_qquad_hfil#!_qquad#_hfil_cr
+ 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 @value{PVERSION} 3.1.4, @command{gawk} followed the POSIX rules
+when @option{--posix} is specified (@pxref{Options}). Otherwise,
+it continued to follow the proposed rules, as
+that had been its behavior for many years.
+
+When @value{PVERSION} 4.0.0 was released, the @command{gawk} maintainer
+made the POSIX rules the default, breaking well over a decade's worth
+of backward compatibility.@footnote{This was rather naive of him, despite
+there being a note in this section indicating that the next major version
+would move to the POSIX rules.} Needless to say, this was a bad idea,
+and as of @value{PVERSION} 4.0.1, @command{gawk} resumed its historical
+behavior, and only follows the POSIX rules when @option{--posix} is given.
+
+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 @code{gensub()}}
+@tex
+\vbox{\bigskip
+% We need more characters for escape and tab ...
+\catcode`_ = 0
+\catcode`! = 4
+% ... since this table has lots of &'s and \'s, so we unspecialize them.
+\catcode`\& = \other \catcode`\\ = \other
+_halign{_hfil#!_qquad_hfil#!_qquad#_hfil_cr
+ 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.
+
+@node I/O Functions
+@subsection Input/Output Functions
+@cindex input/output functions
+
+The following functions relate to input/output (I/O).
+Optional parameters are enclosed in square brackets ([ ]):
+
+@table @asis
+@item @code{close(}@var{filename} [@code{,} @var{how}]@code{)}
+@cindexawkfunc{close}
+@cindex files, closing
+@cindex close file or coprocess
+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.
+@DBXREF{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.
+
+Note that the second argument to @code{close()} is a @command{gawk}
+extension; it is not available in compatibility mode (@pxref{Options}).
+
+@item @code{fflush(}[@var{filename}]@code{)}
+@cindexawkfunc{fflush}
+@cindex flush buffered output
+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 buffers, flushing
+@cindex output, buffering
+Many utility programs @dfn{buffer} their output (i.e., they save information
+to write to a disk file or the screen 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 (i.e.,
+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.
+
+@cindex extensions, common@comma{} @code{fflush()} function
+@cindex Brian Kernighan's @command{awk}
+Brian Kernighan added @code{fflush()} to his @command{awk} in April
+1992. For two decades, it was a common extension. In December
+2012, it was accepted for inclusion into the POSIX standard.
+See @uref{http://austingroupbugs.net/view.php?id=634, the Austin Group website}.
+
+POSIX standardizes @code{fflush()} as follows: if there
+is no argument, or if the argument is the null string (@w{@code{""}}),
+then @command{awk} flushes the buffers for @emph{all} open output files
+and pipes.
+
+@quotation NOTE
+Prior to @value{PVERSION} 4.0.2, @command{gawk}
+would flush only the standard output if there was no argument,
+and flush all output files and pipes if the argument was the null
+string. This was changed in order to be compatible with Brian
+Kernighan's @command{awk}, in the hope that standardizing this
+feature in POSIX would then be easier (which indeed helped).
+
+With @command{gawk},
+you can use @samp{fflush("/dev/stdout")} if you wish to flush
+only the standard output.
+@end quotation
+
+@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 non-zero. (@command{gawk} 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.
+
+@sidebar Interactive Versus Noninteractive 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. On modern
+systems, this means your keyboard and screen.}
+
+@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
+$ @kbd{awk '@{ print $1 + $2 @}'}
+@kbd{1 1}
+@print{} 2
+@kbd{2 3}
+@print{} 5
+@kbd{Ctrl-d}
+@end example
+
+@noindent
+Each line of output is printed immediately. Compare that behavior
+with this example:
+
+@example
+$ @kbd{awk '@{ print $1 + $2 @}' | cat}
+@kbd{1 1}
+@kbd{2 3}
+@kbd{Ctrl-d}
+@print{} 2
+@print{} 5
+@end example
+
+@noindent
+Here, no output is printed until after the @kbd{Ctrl-d} is typed, because
+it is all buffered and sent down the pipe to @command{cat} in one shot.
+@end sidebar
+
+@item @code{system(@var{command})}
+@cindexawkfunc{system}
+@cindex invoke shell command
+@cindex interacting with other programs
+Execute the operating-system
+command @var{command} and then return to the @command{awk} program.
+Return @var{command}'s exit status.
+
+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
+@cindex @option{--sandbox} option, disabling @code{system()} function
+However, if your @command{awk}
+program is interactive, @code{system()} is useful for running 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.
+
+@quotation NOTE
+When @option{--sandbox} is specified, the @code{system()} function is disabled
+(@pxref{Options}).
+@end quotation
+
+@end table
+
+@sidebar Controlling Output Buffering with @code{system()}
+@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 older
+@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. Although 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.
+@end sidebar
+
+@node Time Functions
+@subsection Time Functions
+@cindex time functions
+
+@cindex timestamps
+@cindex log files, timestamps in
+@cindex files, log@comma{} timestamps in
+@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
+@ifclear FOR_PRINT
+seconds.@footnote{@xref{Glossary}, especially the entries ``Epoch'' and ``UTC.''}
+@end ifclear
+@ifset FOR_PRINT
+seconds.
+@end ifset
+All known POSIX-compliant systems support timestamps from 0 through
+@iftex
+@math{2^{31} - 1},
+@end iftex
+@ifnottex
+@ifnotdocbook
+2^31 - 1,
+@end ifnotdocbook
+@end ifnottex
+@docbook
+2<superscript>31</superscript> &minus; 1, @c
+@end docbook
+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.@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.}
+However, recent versions
+of @command{mawk} (@pxref{Other Versions}) also support these functions.
+Optional parameters are enclosed in square brackets ([ ]):
+
+@c @asis for docbook
+@table @asis
+@item @code{mktime(@var{datespec})}
+@cindexgawkfunc{mktime}
+@cindex generate time values
+Turn @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.
+
+@cindex @command{gawk}, @code{PROCINFO} array in
+@cindex @code{PROCINFO} array
+@item @code{strftime(}[@var{format} [@code{,} @var{timestamp} [@code{,} @var{utc-flag}] ] ]@code{)}
+@cindexgawkfunc{strftime}
+@cindex format time string
+Format the time specified by @var{timestamp}
+based on the contents of the @var{format} string and return the result.
+It is similar to the function of the same name in ISO C.
+If @var{utc-flag} is present and is either nonzero or non-null, the value
+is formatted as UTC (Coordinated Universal Time, formerly GMT or Greenwich
+Mean Time). Otherwise, the value is formatted for the local time zone.
+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.
+Without a @var{format} argument, @code{strftime()} uses
+the value of @code{PROCINFO["strftime"]} as the format string
+(@pxref{Built-in Variables}).
+The default string value is
+@code{@w{"%a %b %e %H:%M:%S %Z %Y"}}. This format string produces
+output that is equivalent to that of the @command{date} utility.
+You can assign a new value to @code{PROCINFO["strftime"]} to
+change the default format; see the following list for the various format directives.
+
+@item @code{systime()}
+@cindexgawkfunc{systime}
+@cindex timestamps
+@cindex current system time
+Return 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.
+@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{Unfortunately,
+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 part of the current year.
+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 8601 week number, as a decimal number (00--99).
+For example, January 1, 2012, is in week 53 of 2011. Thus, the year
+of its ISO 8601 week number is 2011, even though its year is 2012.
+Similarly, December 31, 2012, is in week 1 of 2013. Thus, the year
+of its ISO week number is 2013, even though its year is 2012.
+
+@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., 2015).
+
+@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
+``Alternative 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 those just listed, 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.}
+
+For systems that are not yet fully standards-compliant,
+@command{gawk} supplies a copy of
+@code{strftime()} from the GNU C Library.
+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.
+
+@ignore
+@item %N
+The ``Emperor/Era'' name.
+Equivalent to @samp{%C}.
+
+@item %o
+The ``Emperor/Era'' year.
+Equivalent to @samp{%y}.
+@end ignore
+
+@item %s
+The time as a decimal timestamp in seconds since the epoch.
+
+@ignore
+@item %v
+The date in VMS format (e.g., @samp{20-JUN-1991}).
+@end ignore
+@end table
+
+Additionally, the alternative representations are recognized but their
+normal representations are used.
+
+@cindex @code{date} utility, POSIX
+@cindex POSIX @command{awk}, @code{date} utility and
+The following 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
+$ @kbd{date '+Today is %A, %B %d, %Y.'}
+@print{} Today is Monday, September 22, 2014.
+@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 POSIX 'date' command
+
+case $1 in
+-u) TZ=UTC0 # use UTC
+ export TZ
+ shift ;;
+esac
+
+gawk 'BEGIN @{
+ format = PROCINFO["strftime"]
+ 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
+
+@node Bitwise Functions
+@subsection Bit-Manipulation Functions
+@cindex bit-manipulation functions
+@cindex bitwise, operations
+@cindex AND bitwise operation
+@cindex OR bitwise operation
+@cindex XOR bitwise operation
+@cindex operations, bitwise
+@quotation
+@i{I can explain it for you, but I can't understand it for you.}
+@author 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}.
+
+@c 11/2014: Postprocessing turns the docbook informaltable
+@c into a table. Hurray for scripting!
+@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
+<informaltable>
+
+<tgroup cols="7" colsep="1">
+<colspec colname="c1"/>
+<colspec colname="c2"/>
+<colspec colname="c3"/>
+<colspec colname="c4"/>
+<colspec colname="c5"/>
+<colspec colname="c6"/>
+<colspec colname="c7"/>
+<spanspec spanname="optitle" namest="c2" nameend="c7" align="center"/>
+<spanspec spanname="andspan" namest="c2" nameend="c3" align="center"/>
+<spanspec spanname="orspan" namest="c4" nameend="c5" align="center"/>
+<spanspec spanname="xorspan" namest="c6" nameend="c7" align="center"/>
+
+<tbody>
+<row>
+<entry colsep="0"></entry>
+<entry spanname="optitle"><emphasis role="bold">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>
+</informaltable>
+@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.}
+@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}. The following list describes
+@command{gawk}'s built-in functions that implement the bitwise operations.
+Optional parameters are enclosed in square brackets ([ ]):
+
+@cindex @command{gawk}, bitwise operations in
+@table @code
+@cindexgawkfunc{and}
+@cindex bitwise AND
+@item @code{and(}@var{v1}@code{,} @var{v2} [@code{,} @dots{}]@code{)}
+Return the bitwise AND of the arguments. There must be at least two.
+
+@cindexgawkfunc{compl}
+@cindex bitwise complement
+@item @code{compl(@var{val})}
+Return the bitwise complement of @var{val}.
+
+@cindexgawkfunc{lshift}
+@cindex left shift
+@item @code{lshift(@var{val}, @var{count})}
+Return the value of @var{val}, shifted left by @var{count} bits.
+
+@cindexgawkfunc{or}
+@cindex bitwise OR
+@item @code{or(}@var{v1}@code{,} @var{v2} [@code{,} @dots{}]@code{)}
+Return the bitwise OR of the arguments. There must be at least two.
+
+@cindexgawkfunc{rshift}
+@cindex right shift
+@item @code{rshift(@var{val}, @var{count})}
+Return the value of @var{val}, shifted right by @var{count} bits.
+
+@cindexgawkfunc{xor}
+@cindex bitwise XOR
+@item @code{xor(}@var{v1}@code{,} @var{v2} [@code{,} @dots{}]@code{)}
+Return the bitwise XOR of the arguments. There must be at least two.
+@end table
+
+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
+@example
+@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 example
+
+@noindent
+This program produces the following output when run:
+
+@example
+$ @kbd{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 example
+
+@cindex converting, strings to numbers
+@cindex strings, converting
+@cindex numbers, converting
+@cindex converting, numbers to strings
+@cindex number as string of bits
+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.
+
+@node Type Functions
+@subsection Getting Type Information
+
+@command{gawk} provides a single function that lets you distinguish
+an array from a scalar variable. This is necessary for writing code
+that traverses every element of an array of arrays
+(@pxref{Arrays of Arrays}).
+
+@table @code
+@cindexgawkfunc{isarray}
+@cindex scalar or array
+@item isarray(@var{x})
+Return a true value if @var{x} is an array. Otherwise return false.
+@end table
+
+@code{isarray()} is meant for use in two circumstances. The first is when
+traversing a multidimensional array: you can test if an element is itself
+an array or not. The second is inside the body of a user-defined function
+(not discussed yet; @pxref{User-defined}), to test if a parameter is an
+array or not.
+
+@quotation NOTE
+Using @code{isarray()} at the global level to test
+variables makes no sense. Because you are the one writing the program, you
+are supposed to know if your variables are arrays or not. And in fact,
+due to the way @command{gawk} works, if you pass the name of a variable
+that has not been previously used to @code{isarray()}, @command{gawk}
+ends up turning it into a scalar.
+@end quotation
+
+@node I18N Functions
+@subsection String-Translation Functions
+@cindex @command{gawk}, string-translation functions
+@cindex functions, string-translation
+@cindex string-translation functions
+@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 @asis
+@cindexgawkfunc{bindtextdomain}
+@cindex set directory of message catalogs
+@item @code{bindtextdomain(@var{directory}} [@code{,} @var{domain}]@code{)}
+Set 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}.
+
+@cindexgawkfunc{dcgettext}
+@cindex translate string
+@item @code{dcgettext(@var{string}} [@code{,} @var{domain} [@code{,} @var{category}] ]@code{)}
+Return 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"}.
+
+@cindexgawkfunc{dcngettext}
+@item @code{dcngettext(@var{string1}, @var{string2}, @var{number}} [@code{,} @var{domain} [@code{,} @var{category}] ]@code{)}
+Return 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"}.
+@end table
+
+@node User-defined
+@section User-Defined Functions
+
+@cindex user-defined functions
+@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
+
+@quotation
+@i{It's entirely fair to say that the @command{awk} syntax for local
+variable definitions is appallingly awful.}
+@author Brian Kernighan
+@end quotation
+
+@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:
+
+@display
+@code{function} @var{name}@code{(}[@var{parameter-list}]@code{)}
+@code{@{}
+ @var{body-of-function}
+@code{@}}
+@end display
+
+@cindex names, functions
+@cindex functions, names of
+@cindex namespace issues, functions
+@noindent
+Here, @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.
+Here too, only the 52 upper- and lowercase English letters may
+be used in a function name.
+Within a single @command{awk} program, any particular name can only be
+used as a variable, array, or function.
+
+@var{parameter-list} is an optional 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.
+
+A function cannot have two parameters with the same name, nor may it
+have a parameter with the same name as the function itself.
+In addition, according to the POSIX standard, function parameters
+cannot have the same name as one of the special predefined variables
+(@pxref{Built-in Variables}). Not all versions of @command{awk} enforce
+this restriction.
+
+Local variables act like the empty string if referenced where a string
+value is required, and like zero if referenced where a numeric value
+is required. This is the same as regular variables that have never been
+assigned a value. (There is more to understand about local variables;
+@pxref{Dynamic Typing}.)
+
+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
+@cindex shadowing of variable values
+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}.
+
+All the built-in functions return a value to their caller.
+User-defined functions can do so also, using the @code{return} statement,
+which is described in detail in @ref{Return Statement}.
+Many of the subsequent examples in this @value{SECTION} use
+the @code{return} statement.
+
+@cindex common extensions, @code{func} keyword
+@cindex extensions, common@comma{} @code{func} keyword
+@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}. @value{COMMONEXT}
+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.@footnote{This program won't actually run,
+because @code{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
+@cindex function definition example
+
+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 input:
+
+@example
+ 1.2 3.4 5.6 7.8
+ 9.10 11.12 -13.14 15.16
+17.18 19.20 21.22 23.24
+@end example
+
+@noindent
+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 (recall that the
+extra whitespace signifies the start of the local variable list):
+
+@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 relatively recent@footnote{Late in 2012.}
+addition to the POSIX standard.)
+
+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 input string is
+already empty:
+
+@c 8/2014: Thanks to Mike Brennan for the improved formulation
+@cindex @code{rev()} user-defined function
+@example
+function rev(str)
+@{
+ if (str == "")
+ return ""
+
+ return (rev(substr(str, 2)) substr(str, 1, 1))
+@}
+@end example
+
+If this function is in a file named @file{rev.awk}, it can be tested
+this way:
+
+@example
+$ @kbd{echo "Don't Panic!" |}
+> @kbd{gawk -e '@{ print rev($0) @}' -f rev.awk}
+@print{} !cinaP t'noD
+@end example
+
+The C @code{ctime()} function takes a timestamp and returns it as 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
+@example
+@c file eg/lib/ctime.awk
+# ctime.awk
+#
+# awk version of C ctime(3) function
+
+function ctime(ts, format)
+@{
+ format = "%a %b %e %H:%M:%S %Z %Y"
+
+ if (ts == 0)
+ ts = systime() # use current time as default
+ return strftime(format, ts)
+@}
+@c endfile
+@end example
+
+You might think that @code{ctime()} could use @code{PROCINFO["strftime"]}
+for its format string. That would be a mistake, because @code{ctime()} is
+supposed to return the time formatted in a standard fashion, and user-level
+code could have changed @code{PROCINFO["strftime"]}.
+
+@node Function Caveats
+@subsection Calling User-Defined Functions
+
+@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.
+
+@menu
+* Calling A Function:: Don't use spaces.
+* Variable Scope:: Controlling variable scope.
+* Pass By Value/Reference:: Passing parameters.
+@end menu
+
+@node Calling A Function
+@subsubsection Writing a Function Call
+
+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 become 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
+
+@quotation CAUTION
+Whitespace characters (spaces and TABs) are not allowed
+between the function name and the opening 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.
+@end quotation
+
+@node Variable Scope
+@subsubsection Controlling Variable Scope
+
+@cindex local variables, in a function
+@cindex variables, local to a function
+Unlike many languages,
+there is no way to make a variable local to a @code{@{} @dots{} @code{@}} block in
+@command{awk}, but you can make a variable local to a function. It is
+good practice to do so whenever a variable is needed only in that
+function.
+
+To make a variable local to a function, simply declare the variable as
+an argument after the actual function arguments
+(@pxref{Definition Syntax}).
+Look at the following example where variable
+@code{i} is a global variable used by both functions @code{foo()} and
+@code{bar()}:
+
+@example
+function bar()
+@{
+ for (i = 0; i < 3; i++)
+ print "bar's i=" i
+@}
+
+function foo(j)
+@{
+ i = j + 1
+ print "foo's i=" i
+ bar()
+ print "foo's i=" i
+@}
+
+BEGIN @{
+ i = 10
+ print "top's i=" i
+ foo(0)
+ print "top's i=" i
+@}
+@end example
+
+Running this script produces the following, because the @code{i} in
+functions @code{foo()} and @code{bar()} and at the top level refer to the same
+variable instance:
+
+@example
+top's i=10
+foo's i=1
+bar's i=0
+bar's i=1
+bar's i=2
+foo's i=3
+top's i=3
+@end example
+
+If you want @code{i} to be local to both @code{foo()} and @code{bar()} do as
+follows (the extra space before @code{i} is a coding convention to
+indicate that @code{i} is a local variable, not an argument):
+
+@example
+function bar( i)
+@{
+ for (i = 0; i < 3; i++)
+ print "bar's i=" i
+@}
+
+function foo(j, i)
+@{
+ i = j + 1
+ print "foo's i=" i
+ bar()
+ print "foo's i=" i
+@}
+
+BEGIN @{
+ i = 10
+ print "top's i=" i
+ foo(0)
+ print "top's i=" i
+@}
+@end example
+
+Running the corrected script produces the following:
+
+@example
+top's i=10
+foo's i=1
+bar's i=0
+bar's i=1
+bar's i=2
+foo's i=1
+top's i=10
+@end example
+
+Besides scalar values (strings and numbers), you may also have
+local arrays. By using a parameter name as an array, @command{awk}
+treats it as an array, and it is local to the function.
+In addition, recursive calls create new arrays.
+Consider this example:
+
+@example
+function some_func(p1, a)
+@{
+ if (p1++ > 3)
+ return
+
+ a[p1] = p1
+
+ some_func(p1)
+
+ printf("At level %d, index %d %s found in a\n",
+ p1, (p1 - 1), (p1 - 1) in a ? "is" : "is not")
+ printf("At level %d, index %d %s found in a\n",
+ p1, p1, p1 in a ? "is" : "is not")
+ print ""
+@}
+
+BEGIN @{
+ some_func(1)
+@}
+@end example
+
+When run, this program produces the following output:
+
+@example
+At level 4, index 3 is not found in a
+At level 4, index 4 is found in a
+
+At level 3, index 2 is not found in a
+At level 3, index 3 is found in a
+
+At level 2, index 1 is not found in a
+At level 2, index 2 is found in a
+@end example
+
+@node Pass By Value/Reference
+@subsubsection Passing Function Arguments by Value Or by Reference
+
+In @command{awk}, when you declare a function, there is no way to
+declare explicitly whether the arguments are passed @dfn{by value} or
+@dfn{by reference}.
+
+Instead, the passing convention is determined at runtime when
+the function is called according to the following rule:
+if the argument is an array variable, then it is passed by reference.
+Otherwise, the argument is passed by value.
+
+@cindex call by value
+Passing an argument by value means that when a function is called, it
+is given a @emph{copy} of the value of this argument.
+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 termed @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 either the @code{next} statement
+or the @code{nextfile} statement
+(@pxref{Next Statement}, and
+@ifdocbook
+@ref{Nextfile Statement})
+@end ifdocbook
+@ifnotdocbook
+@pxref{Nextfile Statement})
+@end ifnotdocbook
+inside a user-defined function.
+@command{gawk} does not have this limitation.
+
+@node Return Statement
+@subsection The @code{return} Statement
+@cindex @code{return} statement@comma{} user-defined functions
+
+As seen in several earlier examples,
+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:
+
+@display
+@code{return} [@var{expression}]
+@end display
+
+The @var{expression} part is optional.
+Due most likely to an oversight, POSIX does not define what the return
+value is if you omit the @var{expression}. Technically speaking, this
+makes the returned value undefined, and therefore, unpredictable.
+In practice, though, all versions of @command{awk} simply return the
+null string, which acts like zero if used in a numeric context.
+
+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 technically, the function returns an unpredictable value.
+In practice, it returns the empty string. @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, C++ or Java, or to a @code{procedure} in Ada. Thus, it may be appropriate to not
+return any value; simply bear in mind that you should not be using the
+return value of such a function.
+
+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;
+there is nothing to stop you from passing more than one argument
+to @code{maxelt()} but the results would be strange. The extra space before
+@code{i} in the function parameter list indicates that @code{i} and
+@code{ret} are local variables.
+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 99,385 is the largest value
+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 scalar 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
+
+In this example, the first call to @code{foo()} generates
+a fatal error, so @command{awk} will not report the second
+error. If you comment out that call, though, then @command{awk}
+does report the second error.
+
+Usually, such things aren't a big issue, but it's worth
+being aware of them.
+
+@node Indirect Calls
+@section Indirect Function Calls
+
+@cindex indirect function calls
+@cindex function calls, indirect
+@cindex function pointers
+@cindex pointers to functions
+@cindex differences in @command{awk} and @command{gawk}, indirect function calls
+
+This section describes an advanced, @command{gawk}-specific extension.
+
+Often, you may wish to defer the choice of function to call until runtime.
+For example, you may have different kinds of records, each of which
+should be processed differently.
+
+Normally, you would have to use a series of @code{if}-@code{else}
+statements to decide which function to call. By using @dfn{indirect}
+function calls, you can specify the name of the function to call as a
+string variable, and then call the function. Let's look at an example.
+
+Suppose you have a file with your test scores for the classes you
+are taking. The first field is the class name. The following fields
+are the functions to call to process the data, up to a ``marker''
+field @samp{data:}. Following the marker, to the end of the record,
+are the various numeric test scores.
+
+Here is the initial file; you wish to get the sum and the average of
+your test scores:
+
+@example
+@c file eg/data/class_data1
+Biology_101 sum average data: 87.0 92.4 78.5 94.9
+Chemistry_305 sum average data: 75.2 98.3 94.7 88.2
+English_401 sum average data: 100.0 95.6 87.1 93.4
+@c endfile
+@end example
+
+To process the data, you might write initially:
+
+@example
+@{
+ class = $1
+ for (i = 2; $i != "data:"; i++) @{
+ if ($i == "sum")
+ sum() # processes the whole record
+ else if ($i == "average")
+ average()
+ @dots{} # and so on
+ @}
+@}
+@end example
+
+@noindent
+This style of programming works, but can be awkward. With @dfn{indirect}
+function calls, you tell @command{gawk} to use the @emph{value} of a
+variable as the @emph{name} of the function to call.
+
+@cindex @code{@@}-notation for indirect function calls
+@cindex indirect function calls, @code{@@}-notation
+@cindex function calls, indirect, @code{@@}-notation for
+The syntax is similar to that of a regular function call: an identifier
+immediately followed by an opening parenthesis, any arguments, and then
+a closing parenthesis, with the addition of a leading @samp{@@}
+character:
+
+@example
+the_func = "sum"
+result = @@the_func() # calls the sum() function
+@end example
+
+Here is a full program that processes the previously shown data,
+using indirect function calls:
+
+@example
+@c file eg/prog/indirectcall.awk
+# indirectcall.awk --- Demonstrate indirect function calls
+@c endfile
+@ignore
+@c file eg/prog/indirectcall.awk
+#
+# Arnold Robbins, arnold@skeeve.com, Public Domain
+# January 2009
+@c endfile
+@end ignore
+
+@c file eg/prog/indirectcall.awk
+# average --- return the average of the values in fields $first - $last
+
+function average(first, last, sum, i)
+@{
+ sum = 0;
+ for (i = first; i <= last; i++)
+ sum += $i
+
+ return sum / (last - first + 1)
+@}
+
+# sum --- return the sum of the values in fields $first - $last
+
+function sum(first, last, ret, i)
+@{
+ ret = 0;
+ for (i = first; i <= last; i++)
+ ret += $i
+
+ return ret
+@}
+@c endfile
+@end example
+
+These two functions expect to work on fields; thus the parameters
+@code{first} and @code{last} indicate where in the fields to start and end.
+Otherwise they perform the expected computations and are not unusual:
+
+@example
+@c file eg/prog/indirectcall.awk
+# For each record, print the class name and the requested statistics
+@{
+ class_name = $1
+ gsub(/_/, " ", class_name) # Replace _ with spaces
+
+ # find start
+ for (i = 1; i <= NF; i++) @{
+ if ($i == "data:") @{
+ start = i + 1
+ break
+ @}
+ @}
+
+ printf("%s:\n", class_name)
+ for (i = 2; $i != "data:"; i++) @{
+ the_function = $i
+ printf("\t%s: <%s>\n", $i, @@the_function(start, NF) "")
+ @}
+ print ""
+@}
+@c endfile
+@end example
+
+This is the main processing for each record. It prints the class name (with
+underscores replaced with spaces). It then finds the start of the actual data,
+saving it in @code{start}.
+The last part of the code loops through each function name (from @code{$2} up to
+the marker, @samp{data:}), calling the function named by the field. The indirect
+function call itself occurs as a parameter in the call to @code{printf}.
+(The @code{printf} format string uses @samp{%s} as the format specifier so that we
+can use functions that return strings, as well as numbers. Note that the result
+from the indirect call is concatenated with the empty string, in order to force
+it to be a string value.)
+
+Here is the result of running the program:
+
+@example
+$ @kbd{gawk -f indirectcall.awk class_data1}
+@print{} Biology 101:
+@print{} sum: <352.8>
+@print{} average: <88.2>
+@print{}
+@print{} Chemistry 305:
+@print{} sum: <356.4>
+@print{} average: <89.1>
+@print{}
+@print{} English 401:
+@print{} sum: <376.1>
+@print{} average: <94.025>
+@end example
+
+The ability to use indirect function calls is more powerful than you may
+think at first. The C and C++ languages provide ``function pointers,'' which
+are a mechanism for calling a function chosen at runtime. One of the most
+well-known uses of this ability is the C @code{qsort()} function, which sorts
+an array using the famous ``quick sort'' algorithm
+(see @uref{http://en.wikipedia.org/wiki/Quick_sort, the Wikipedia article}
+for more information). To use this function, you supply a pointer to a comparison
+function. This mechanism allows you to sort arbitrary data in an arbitrary
+fashion.
+
+We can do something similar using @command{gawk}, like this:
+
+@example
+@c file eg/lib/quicksort.awk
+# quicksort.awk --- Quicksort algorithm, with user-supplied
+# comparison function
+@c endfile
+@ignore
+@c file eg/lib/quicksort.awk
+#
+# Arnold Robbins, arnold@@skeeve.com, Public Domain
+# January 2009
+
+@c endfile
+
+@end ignore
+@c file eg/lib/quicksort.awk
+# quicksort --- C.A.R. Hoare's quick sort algorithm. See Wikipedia
+# or almost any algorithms or computer science text
+@c endfile
+@ignore
+@c file eg/lib/quicksort.awk
+#
+# Adapted from K&R-II, page 110
+@c endfile
+@end ignore
+@c file eg/lib/quicksort.awk
+
+function quicksort(data, left, right, less_than, i, last)
+@{
+ if (left >= right) # do nothing if array contains fewer
+ return # than two elements
+
+ quicksort_swap(data, left, int((left + right) / 2))
+ last = left
+ for (i = left + 1; i <= right; i++)
+ if (@@less_than(data[i], data[left]))
+ quicksort_swap(data, ++last, i)
+ quicksort_swap(data, left, last)
+ quicksort(data, left, last - 1, less_than)
+ quicksort(data, last + 1, right, less_than)
+@}
+
+# quicksort_swap --- helper function for quicksort, should really be inline
+
+function quicksort_swap(data, i, j, temp)
+@{
+ temp = data[i]
+ data[i] = data[j]
+ data[j] = temp
+@}
+@c endfile
+@end example
+
+The @code{quicksort()} function receives the @code{data} array, the starting and ending
+indices to sort (@code{left} and @code{right}), and the name of a function that
+performs a ``less than'' comparison. It then implements the quick sort algorithm.
+
+To make use of the sorting function, we return to our previous example. The
+first thing to do is write some comparison functions:
+
+@example
+@c file eg/prog/indirectcall.awk
+# num_lt --- do a numeric less than comparison
+
+function num_lt(left, right)
+@{
+ return ((left + 0) < (right + 0))
+@}
+
+# num_ge --- do a numeric greater than or equal to comparison
+
+function num_ge(left, right)
+@{
+ return ((left + 0) >= (right + 0))
+@}
+@c endfile
+@end example
+
+The @code{num_ge()} function is needed to perform a descending sort; when used
+to perform a ``less than'' test, it actually does the opposite (greater than
+or equal to), which yields data sorted in descending order.
+
+Next comes a sorting function. It is parameterized with the starting and
+ending field numbers and the comparison function. It builds an array with
+the data and calls @code{quicksort()} appropriately, and then formats the
+results as a single string:
+
+@example
+@c file eg/prog/indirectcall.awk
+# do_sort --- sort the data according to `compare'
+# and return it as a string
+
+function do_sort(first, last, compare, data, i, retval)
+@{
+ delete data
+ for (i = 1; first <= last; first++) @{
+ data[i] = $first
+ i++
+ @}
+
+ quicksort(data, 1, i-1, compare)
+
+ retval = data[1]
+ for (i = 2; i in data; i++)
+ retval = retval " " data[i]
+
+ return retval
+@}
+@c endfile
+@end example
+
+Finally, the two sorting functions call @code{do_sort()}, passing in the
+names of the two comparison functions:
+
+@example
+@c file eg/prog/indirectcall.awk
+# sort --- sort the data in ascending order and return it as a string
+
+function sort(first, last)
+@{
+ return do_sort(first, last, "num_lt")
+@}
+
+# rsort --- sort the data in descending order and return it as a string
+
+function rsort(first, last)
+@{
+ return do_sort(first, last, "num_ge")
+@}
+@c endfile
+@end example
+
+Here is an extended version of the @value{DF}:
+
+@example
+@c file eg/data/class_data2
+Biology_101 sum average sort rsort data: 87.0 92.4 78.5 94.9
+Chemistry_305 sum average sort rsort data: 75.2 98.3 94.7 88.2
+English_401 sum average sort rsort data: 100.0 95.6 87.1 93.4
+@c endfile
+@end example
+
+Finally, here are the results when the enhanced program is run:
+
+@example
+$ @kbd{gawk -f quicksort.awk -f indirectcall.awk class_data2}
+@print{} Biology 101:
+@print{} sum: <352.8>
+@print{} average: <88.2>
+@print{} sort: <78.5 87.0 92.4 94.9>
+@print{} rsort: <94.9 92.4 87.0 78.5>
+@print{}
+@print{} Chemistry 305:
+@print{} sum: <356.4>
+@print{} average: <89.1>
+@print{} sort: <75.2 88.2 94.7 98.3>
+@print{} rsort: <98.3 94.7 88.2 75.2>
+@print{}
+@print{} English 401:
+@print{} sum: <376.1>
+@print{} average: <94.025>
+@print{} sort: <87.1 93.4 95.6 100.0>
+@print{} rsort: <100.0 95.6 93.4 87.1>
+@end example
+
+Another example where indirect functions calls are useful can be found in
+processing arrays. @DBREF{Walking Arrays} presented a simple function
+for ``walking'' an array of arrays. That function simply printed the
+name and value of each scalar array element. However, it is easy to
+generalize that function, by passing in the name of a function to call
+when walking an array. The modified function looks like this:
+
+@example
+@c file eg/lib/processarray.awk
+function process_array(arr, name, process, do_arrays, i, new_name)
+@{
+ for (i in arr) @{
+ new_name = (name "[" i "]")
+ if (isarray(arr[i])) @{
+ if (do_arrays)
+ @@process(new_name, arr[i])
+ process_array(arr[i], new_name, process, do_arrays)
+ @} else
+ @@process(new_name, arr[i])
+ @}
+@}
+@c endfile
+@end example
+
+The arguments are as follows:
+
+@table @code
+@item arr
+The array.
+
+@item name
+The name of the array (a string).
+
+@item process
+The name of the function to call.
+
+@item do_arrays
+If this is true, the function can handle elements that are subarrays.
+@end table
+
+If subarrays are to be processed, that is done before walking them further.
+
+When run with the following scaffolding, the function produces the same
+results as does the earlier @code{walk_array()} function:
+
+@example
+BEGIN @{
+ a[1] = 1
+ a[2][1] = 21
+ a[2][2] = 22
+ a[3] = 3
+ a[4][1][1] = 411
+ a[4][2] = 42
+
+ process_array(a, "a", "do_print", 0)
+@}
+
+function do_print(name, element)
+@{
+ printf "%s = %s\n", name, element
+@}
+@end example
+
+Remember that you must supply a leading @samp{@@} in front of an indirect function call.
+
+Starting with @value{PVERSION} 4.1.2 of @command{gawk}, indirect function
+calls may also be used with built-in functions and with extension functions
+(@pxref{Dynamic Extensions}). The only thing you cannot do is pass a regular
+expression constant to a built-in function through an indirect function
+call.@footnote{This may change in a future version; recheck the documentation that
+comes with your version of @command{gawk} to see if it has.}
+
+@command{gawk} does its best to make indirect function calls efficient.
+For example, in the following case:
+
+@example
+for (i = 1; i <= n; i++)
+ @@the_func()
+@end example
+
+@noindent
+@code{gawk} looks up the actual function to call only once.
+
+@node Functions Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+@command{awk} provides built-in functions and lets you define your own
+functions.
+
+@item
+POSIX @command{awk} provides three kinds of built-in functions: numeric,
+string, and I/O. @command{gawk} provides functions that sort arrays, work
+with values representing time, do bit manipulation, determine variable
+type (array versus scalar), and internationalize and localize programs.
+@command{gawk} also provides several extensions to some of standard
+functions, typically in the form of additional arguments.
+
+@item
+Functions accept zero or more arguments and return a value. The
+expressions that provide the argument values are completely evaluated
+before the function is called. Order of evaluation is not defined.
+The return value can be ignored.
+
+@item
+The handling of backslash in @code{sub()} and @code{gsub()} is not simple.
+It is more straightforward in @command{gawk}'s @code{gensub()} function,
+but that function still requires care in its use.
+
+@item
+User-defined functions provide important capabilities but come with
+some syntactic inelegancies. In a function call, there cannot be any
+space between the function name and the opening left parenthesis of the
+argument list. Also, there is no provision for local variables, so the
+convention is to add extra parameters, and to separate them visually
+from the real parameters by extra whitespace.
+
+@item
+User-defined functions may call other user-defined (and built-in)
+functions and may call themselves recursively. Function parameters
+``hide'' any global variables of the same names.
+You cannot use the name of a reserved variable (such as @code{ARGC})
+as the name of a parameter in user-defined functions.
+
+@item
+Scalar values are passed to user-defined functions by value. Array
+parameters are passed by reference; any changes made by the function to
+array parameters are thus visible after the function has returned.
+
+@item
+Use the @code{return} statement to return from a user-defined function.
+An optional expression becomes the function's return value. Only scalar
+values may be returned by a function.
+
+@item
+If a variable that has never been used is passed to a user-defined
+function, how that function treats the variable can set its nature:
+either scalar or array.
+
+@item
+@command{gawk} provides indirect function calls using a special syntax.
+By setting a variable to the name of a function, you can
+determine at runtime what function will be called at that point in the
+program. This is equivalent to function pointers in C and C++.
+
+@end itemize
+
+
+@ifnotinfo
+@part @value{PART2}Problem Solving with @command{awk}
+@end ifnotinfo
+
+@ifdocbook
+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 @value{BULLET}
+@item
+@ref{Library Functions}
+
+@item
+@ref{Sample Programs}
+@end itemize
+@end ifdocbook
+
+@node Library Functions
+@chapter A Library of @command{awk} Functions
+@cindex libraries of @command{awk} functions
+@cindex functions, library
+@cindex functions, user-defined, library of
+
+@DBREF{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.
+
+@cindex Kernighan, Brian
+@cindex Plauger, P.J.@:
+In their seminal 1976 book, @cite{Software Tools},@footnote{Sadly, over 35
+years later, many of the lessons taught by this book have yet to be
+learned by a vast number of practicing programmers.} Brian Kernighan
+and P.J.@: Plauger wrote:
+
+@quotation
+Good Programming is not learned from generalities, but by seeing how
+significant programs can be made clean, easy to read, easy to maintain and
+modify, human-engineered, efficient and reliable, by the application of
+common sense and good programming practices. Careful study and imitation
+of good programs leads to better writing.
+@end quotation
+
+In fact, they felt this idea was so important that they placed this
+statement on the cover of their book. Because we believe strongly
+that their statement is correct, this @value{CHAPTER} and @ref{Sample
+Programs}, provide a good-sized body of code for you to read and, we hope,
+to learn from.
+
+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
+@DBREF{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.)
+
+@ifclear FOR_PRINT
+If you have written one or more useful, general-purpose @command{awk} functions
+and would like to contribute them to the @command{awk} user community, see
+@ref{How To Contribute}, for more information.
+@end ifclear
+
+@cindex portability, example programs
+The programs in this @value{CHAPTER} and in
+@ref{Sample Programs},
+freely use @command{gawk}-specific features.
+Rewriting these programs for different implementations of @command{awk}
+is pretty straightforward:
+
+@itemize @value{BULLET}
+@item
+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}.
+
+@item
+A number of programs use @code{nextfile}
+(@pxref{Nextfile Statement})
+to skip any remaining input in the input file.
+
+@item
+@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.
+@end itemize
+
+@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.
+* Walking Arrays:: A function to walk arrays of arrays.
+* Library Functions Summary:: Summary of library functions.
+* Library Exercises:: Exercises.
+@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}, as 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 @code{i} or @code{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, as 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.@footnote{Although all the library routines could have
+been rewritten to use this convention, this was not done, in order to
+show how our 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 predefined variables, such as @code{FS}.
+
+@cindex @option{--dump-variables} option, using for library functions
+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{}
+ # some_var should be local but by oversight is not
+ @var{use variable} some_var
+ @dots{}
+@}
+@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
+@DBREF{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
+* 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.
+* Getlocaltime Function:: A function to get formatted times.
+* Readfile Function:: A function to read an entire file at once.
+* Shell Quoting:: A function to quote strings for the shell.
+@end menu
+
+@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
+# mystrtonum --- convert string to number
+
+@c endfile
+@ignore
+@c file eg/lib/strtonum.awk
+#
+# Arnold Robbins, arnold@@skeeve.com, Public Domain
+# February, 2004
+# Revised June, 2014
+
+@c endfile
+@end ignore
+@c file eg/lib/strtonum.awk
+function mystrtonum(str, ret, n, i, k, c)
+@{
+ if (str ~ /^0[0-7]*$/) @{
+ # octal
+ n = length(str)
+ ret = 0
+ for (i = 1; i <= n; i++) @{
+ c = substr(str, i, 1)
+ # index() returns 0 if c not in string,
+ # includes c == "0"
+ k = index("1234567", c)
+
+ ret = ret * 8 + k
+ @}
+ @} else if (str ~ /^0[xX][[:xdigit:]]+$/) @{
+ # 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)
+ # index() returns 0 if c not in string,
+ # includes c == "0"
+ k = index("123456789abcdef", c)
+
+ ret = ret * 16 + k
+ @}
+ @} else if (str ~ \
+ /^[-+]?([0-9]+([.][0-9]*([Ee][0-9]+)?)?|([.][0-9]+([Ee][-+]?[0-9]+)?))$/) @{
+ # 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[8] = "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{"1234567"} of the current
+octal digit.
+The return value will either be the same number as the digit, or zero
+if the character is not there, which will be true for a @samp{0}.
+This is safe, because the regexp test in the @code{if} ensures that
+only octal values are converted.
+
+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) regexp for a
+regular decimal integer or floating-point number, 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
+
+@cindex assertions
+@cindex @code{assert()} function (C library)
+@cindex libraries of @command{awk} functions, assertions
+@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 a 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@@skeeve.com, 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 that such a @code{BEGIN} rule always ends
+with an @code{exit} statement.
+
+@node Round Function
+@subsection Rounding Numbers
+
+@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 @dfn{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., @code{"%.0f"}),
+you should check what your system does. The following function does
+traditional rounding; it might be useful if your @command{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@@skeeve.com, 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 ival # ensure no decimals
+
+ 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
+ @}
+@}
+@c endfile
+@c don't include test harness in the file that gets installed
+
+# test harness
+# @{ print $0, round($0) @}
+@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
+@uref{http://mathworld.wolfram.com/CliffRandomNumberGenerator.html, Cliff random number generator}
+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@@skeeve.com, 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
+@cindex @code{_ord_init()} 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@@skeeve.com, Public Domain
+# 16 January, 1992
+# 20 July, 1992, revised
+@c endfile
+@end ignore
+@c file eg/lib/ord.awk
+
+BEGIN @{ _ord_init() @}
+
+function _ord_init( 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 (machine character encodings)
+@cindex ASCII
+@cindex EBCDIC
+@cindex Unicode
+@cindex mark parity
+Some explanation of the numbers used by @code{_ord_init()} is worthwhile.
+The most prominent character set in use today is ASCII.@footnote{This
+is changing; many systems use Unicode, a very large character set
+that includes ASCII as a subset. On systems with full Unicode support,
+a character can occupy up to 32 bits, making simple tests such as
+used here prohibitively expensive.}
+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 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.
+There are other character sets in use on some older systems, but
+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, as 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@@skeeve.com, 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 space 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 Getlocaltime 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
+@DBREF{Time Functions}
+provide the minimum functionality necessary for dealing with the time of day
+in human-readable form. Although @code{strftime()} is extensive, the control
+formats are not necessarily easy to remember or intuitively obvious when
+reading a program.
+
+The following function, @code{getlocaltime()}, 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{getlocaltime()} user-defined function
+@example
+@c file eg/lib/gettime.awk
+# getlocaltime.awk --- get the time of day in a usable format
+@c endfile
+@ignore
+@c file eg/lib/gettime.awk
+#
+# Arnold Robbins, arnold@@skeeve.com, Public Domain, May 1993
+#
+@c endfile
+@end ignore
+@c file eg/lib/gettime.awk
+
+# 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 getlocaltime(time, ret, now, i)
+@{
+ # get time once, avoids unnecessary system calls
+ now = systime()
+
+ # return date(1)-style output
+ ret = strftime("%a %b %e %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
+@DBREF{Alarm Program}
+uses this function.
+A more general design for the @code{getlocaltime()} function would have
+allowed the user to supply an optional timestamp value to use instead
+of the current time.
+
+@node Readfile Function
+@subsection Reading a Whole File At Once
+
+Often, it is convenient to have the entire contents of a file available
+in memory as a single string. A straightforward but naive way to
+do that might be as follows:
+
+@example
+function readfile(file, tmp, contents)
+@{
+ if ((getline tmp < file) < 0)
+ return
+
+ contents = tmp
+ while (getline tmp < file) > 0)
+ contents = contents RT tmp
+
+ close(file)
+ return contents
+@}
+@end example
+
+This function reads from @code{file} one record at a time, building
+up the full contents of the file in the local variable @code{contents}.
+It works, but is not necessarily efficient.
+
+The following function, based on a suggestion by Denis Shirokov,
+reads the entire contents of the named file in one shot:
+
+@cindex @code{readfile()} user-defined function
+@example
+@c file eg/lib/readfile.awk
+# readfile.awk --- read an entire file at once
+@c endfile
+@ignore
+@c file eg/lib/readfile.awk
+#
+# Original idea by Denis Shirokov, cosmogen@@gmail.com, April 2013
+#
+@c endfile
+@end ignore
+@c file eg/lib/readfile.awk
+
+function readfile(file, tmp, save_rs)
+@{
+ save_rs = RS
+ RS = "^$"
+ getline tmp < file
+ close(file)
+ RS = save_rs
+
+ return tmp
+@}
+@c endfile
+@end example
+
+It works by setting @code{RS} to @samp{^$}, a regular expression that
+will never match if the file has contents. @command{gawk} reads data from
+the file into @code{tmp} attempting to match @code{RS}. The match fails
+after each read, but fails quickly, such that @command{gawk} fills
+@code{tmp} with the entire contents of the file.
+(@DBXREF{Records} for information on @code{RT} and @code{RS}.)
+
+In the case that @code{file} is empty, the return value is the null
+string. Thus calling code may use something like:
+
+@example
+contents = readfile("/some/path")
+if (length(contents) == 0)
+ # file was empty @dots{}
+@end example
+
+This tests the result to see if it is empty or not. An equivalent
+test would be @samp{contents == ""}.
+
+@xref{Extension Sample Readfile}, for an extension function that
+also reads an entire file into memory.
+
+@node Shell Quoting
+@subsection Quoting Strings to Pass to the Shell
+
+@c included by permission
+@ignore
+Date: Sun, 27 Jul 2014 17:16:16 -0700
+Message-ID: <CAKuGj+iCF_obaCLDUX60aSAgbfocFVtguG39GyeoNxTFby5sqQ@mail.gmail.com>
+Subject: Useful awk function
+From: Mike Brennan <mike@madronabluff.com>
+To: Arnold Robbins <arnold@skeeve.com>
+@end ignore
+
+Michael Brennan offers the following programming pattern,
+which he uses frequently:
+
+@example
+#! /bin/sh
+
+awkp='
+ @dots{}
+ '
+
+@var{input_program} | awk "$awkp" | /bin/sh
+@end example
+
+For example, a program of his named @command{flac-edit} has this form:
+
+@example
+$ @kbd{flac-edit -song="Whoope! That's Great" file.flac}
+@end example
+
+It generates the following output, which is to be piped to
+the shell (@file{/bin/sh}):
+
+@example
+chmod +w file.flac
+metaflac --remove-tag=TITLE file.flac
+LANG=en_US.88591 metaflac --set-tag=TITLE='Whoope! That'"'"'s Great' file.flac
+chmod -w file.flac
+@end example
+
+Note the need for shell quoting. The function @code{shell_quote()}
+does it. @code{SINGLE} is the one-character string @code{"'"} and
+@code{QSINGLE} is the three-character string @code{"\"'\""}:
+
+@example
+@c file eg/lib/shellquote.awk
+# shell_quote --- quote an argument for passing to the shell
+@c endfile
+@ignore
+@c file eg/lib/shellquote.awk
+#
+# Michael Brennan
+# brennan@@madronabluff.com
+# September 2014
+@c endfile
+@end ignore
+@c file eg/lib/shellquote.awk
+
+function shell_quote(s, # parameter
+ SINGLE, QSINGLE, i, X, n, ret) # locals
+@{
+ if (s == "")
+ return "\"\""
+
+ SINGLE = "\x27" # single quote
+ QSINGLE = "\"\x27\""
+ n = split(s, X, SINGLE)
+
+ ret = SINGLE X[1] SINGLE
+ for (i = 2; i <= n; i++)
+ ret = ret QSINGLE SINGLE X[i] SINGLE
+
+ return ret
+@}
+@c endfile
+@end example
+
+@node Data File Management
+@section @value{DDF} Management
+
+@cindex files, managing
+@cindex libraries of @command{awk} functions, managing, data files
+@cindex functions, library, managing data files
+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, data file 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@@skeeve.com, 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
+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 datafile transitions
+#
+# user supplies beginfile() and endfile() functions
+@c endfile
+@ignore
+@c file eg/lib/ftrans.awk
+#
+# Arnold Robbins, arnold@@skeeve.com, Public Domain
+# November 1992
+@c endfile
+@end ignore
+@c file eg/lib/ftrans.awk
+
+FNR == 1 @{
+ if (_filename_ != "")
+ endfile(_filename_)
+ _filename_ = FILENAME
+ beginfile(FILENAME)
+@}
+
+END @{ endfile(_filename_) @}
+@c endfile
+@end example
+
+@DBREF{Wc Program}
+shows how this library function can be used and
+how it simplifies writing the main program.
+
+@sidebar So Why Does @command{gawk} Have @code{BEGINFILE} and @code{ENDFILE}?
+
+You are probably wondering, if @code{beginfile()} and @code{endfile()}
+functions can do the job, why does @command{gawk} have
+@code{BEGINFILE} and @code{ENDFILE} patterns (@pxref{BEGINFILE/ENDFILE})?
+
+Good question. Normally, if @command{awk} cannot open a file, this
+causes an immediate fatal error. In this case, there is no way for a
+user-defined function to deal with the problem, as the mechanism for
+calling it relies on the file being open and at the first record. Thus,
+the main reason for @code{BEGINFILE} is to give you a ``hook'' to catch
+files that cannot be processed. @code{ENDFILE} exists for symmetry,
+and because it provides an easy way to do per-file cleanup processing.
+@end sidebar
+
+@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@@skeeve.com, 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
+
+The @code{rewind()} function relies on the @code{ARGIND} variable
+(@pxref{Auto-set}), which is specific to @command{gawk}. It also
+relies on the @code{nextfile} keyword (@pxref{Nextfile Statement}).
+Because of this, you should not call it from an @code{ENDFILE} rule.
+(This isn't necessary anyway, because @command{gawk} goes to the next
+file as soon as an @code{ENDFILE} rule finishes!)
+
+@node File Checking
+@subsection Checking for Readable @value{DDF}s
+
+@cindex troubleshooting, readable data files
+@cindex readable data files@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.@footnote{The @code{BEGINFILE}
+special pattern (@pxref{BEGINFILE/ENDFILE}) provides an alternative
+mechanism for dealing with files that can't be opened. However, the
+code here provides a portable solution.} 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@@skeeve.com, Public Domain
+# October 2000
+# December 2010
+@c endfile
+@end ignore
+@c file eg/lib/readable.awk
+
+BEGIN @{
+ for (i = 1; i < ARGC; i++) @{
+ if (ARGV[i] ~ /^[a-zA-Z_][a-zA-Z0-9_]*=.*/ \
+ || ARGV[i] == "-" || ARGV[i] == "/dev/stdin")
+ continue # 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
+This works, because the @code{getline} won't be fatal.
+Removing the element from @code{ARGV} with @code{delete}
+skips the file (because it's no longer in the list).
+See also @ref{ARGC and ARGV}.
+
+Because @command{awk} variable names only allow the English letters,
+the regular expression check purposely does not use character classes
+such as @samp{[:alpha:]} and @samp{[:alnum:]}
+(@pxref{Bracket Expressions})
+
+@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@@skeeve.com, Public Domain
+# June 2003
+@c endfile
+@end ignore
+@c file eg/lib/zerofile.awk
+
+BEGIN @{ Argind = 0 @}
+
+ARGIND > Argind + 1 @{
+ for (Argind++; Argind < ARGIND; Argind++)
+ zerofile(ARGV[Argind], Argind)
+@}
+
+ARGIND != Argind @{ Argind = ARGIND @}
+
+END @{
+ if (ARGIND > Argind)
+ for (Argind++; Argind <= ARGIND; Argind++)
+ zerofile(ARGV[Argind], Argind)
+@}
+@c endfile
+@end example
+
+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 @samp{<}.
+
+@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 a @value{FN} that contains 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@@skeeve.com, Public Domain
+# October 1999
+@c endfile
+@end ignore
+@c file eg/lib/noassign.awk
+
+function disable_assigns(argc, argv, i)
+@{
+ for (i = 1; i < argc; i++)
+ if (argv[i] ~ /^[a-zA-Z_][a-zA-Z0-9_]*=.*/)
+ argv[i] = ("./" argv[i])
+@}
+
+BEGIN @{
+ if (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.
+
+@node Getopt Function
+@section Processing Command-Line Options
+
+@cindex libraries of @command{awk} functions, command-line options
+@cindex functions, library, command-line options
+@cindex command-line options, processing
+@cindex options, command-line, processing
+@cindex functions, library, C library
+@cindex arguments, processing
+Most utilities on POSIX-compatible systems take options 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 be 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.
+@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, as 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@@skeeve.com, 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 multiflag option, e.g., -abc
+@c endfile
+@end example
+
+The function starts out with comments presenting
+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] !~ /^-[^:[:space:]]/) @{
+ _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{/^-[^:[:space:]/}},
+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. Continuing on:
+
+@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 @code{"?"}.
+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, because the default behavior is for @code{getopt()}
+to print a diagnostic message upon seeing an invalid option. @code{Optind}
+is set to one, because 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
+$ @kbd{awk -f getopt.awk -v _getopt_test=1 -- -a -cbARG bax -x}
+@print{} c = <a>, Optarg = <>
+@print{} c = <c>, Optarg = <>
+@print{} c = <b>, Optarg = <ARG>
+@print{} non-option arguments:
+@print{} ARGV[3] = <bax>
+@print{} ARGV[4] = <-x>
+
+$ @kbd{awk -f getopt.awk -v _getopt_test=1 -- -a -x -- xyz abc}
+@print{} c = <a>, Optarg = <>
+@error{} x -- 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.
+
+@quotation NOTE
+After @code{getopt()} is through,
+user-level code must 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.
+@end quotation
+
+Using @samp{#!} with the @option{-E} option may help avoid
+conflicts between your program's options and @command{gawk}'s options,
+as @option{-E} causes @command{gawk} to abandon processing of
+further options
+(@DBPXREF{Executable Scripts} and
+@ifnotdocbook
+@pxref{Options}).
+@end ifnotdocbook
+@ifdocbook
+@ref{Options}).
+@end ifdocbook
+
+Several of the sample programs presented in
+@ref{Sample Programs},
+use @code{getopt()} to process their arguments.
+
+@node Passwd Functions
+@section Reading the User Database
+
+@cindex libraries of @command{awk} functions, user database, reading
+@cindex functions, library, user database@comma{} reading
+@cindex user database@comma{} reading
+@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. @DBXREF{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
+Although 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:
+
+@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@@skeeve.com, May 1993
+ * Public Domain
+ * December 2010, move to ANSI C definition for main().
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+@c endfile
+@end ignore
+@c file eg/lib/pwcat.c
+#include <stdio.h>
+#include <pwd.h>
+
+@c endfile
+@ignore
+@c file eg/lib/pwcat.c
+#if defined (STDC_HEADERS)
+#include <stdlib.h>
+#endif
+
+@c endfile
+@end ignore
+@c file eg/lib/pwcat.c
+int
+main(int argc, char **argv)
+@{
+ struct passwd *p;
+
+ while ((p = getpwent()) != NULL)
+@c endfile
+@ignore
+@c file eg/lib/pwcat.c
+#ifdef ZOS_USS
+ printf("%s:%ld:%ld:%s:%s\n",
+ p->pw_name, (long) p->pw_uid,
+ (long) p->pw_gid, p->pw_dir, p->pw_shell);
+#else
+@c endfile
+@end ignore
+@c file eg/lib/pwcat.c
+ printf("%s:%s:%ld:%ld:%s:%s:%s\n",
+ p->pw_name, p->pw_passwd, (long) p->pw_uid,
+ (long) p->pw_gid, p->pw_gecos, p->pw_dir, p->pw_shell);
+@c endfile
+@ignore
+@c file eg/lib/pwcat.c
+#endif
+@c endfile
+@end ignore
+@c file eg/lib/pwcat.c
+
+ endpwent();
+ return 0;
+@}
+@c endfile
+@end example
+
+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:
+
+@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} versus @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 Bash.
+@end table
+
+A few lines representative of @command{pwcat}'s output are as follows:
+
+@cindex Jacobs, Andrew
+@cindex Robbins, Arnold
+@cindex Robbins, Miriam
+@example
+$ @kbd{pwcat}
+@print{} root:x: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:
+
+@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@@skeeve.com, Public Domain
+# May 1993
+# Revised October 2000
+# Revised December 2010
+@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, using_fpat)
+@{
+ if (_pw_inited)
+ return
+
+ oldfs = FS
+ oldrs = RS
+ olddol0 = $0
+ using_fw = (PROCINFO["FS"] == "FIELDWIDTHS")
+ using_fpat = (PROCINFO["FS"] == "FPAT")
+ FS = ":"
+ RS = "\n"
+
+ pwcat = _pw_awklib "pwcat"
+ while ((pwcat | getline) > 0) @{
+ _pw_byname[$1] = $0
+ _pw_byuid[$3] = $0
+ _pw_bycount[++_pw_total] = $0
+ @}
+ close(pwcat)
+ _pw_count = 0
+ _pw_inited = 1
+ FS = oldfs
+ if (using_fw)
+ FIELDWIDTHS = FIELDWIDTHS
+ else if (using_fpat)
+ FPAT = FPAT
+ RS = oldrs
+ $0 = olddol0
+@}
+@c endfile
+@end example
+
+@cindex @code{BEGIN} 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()} fills three copies of the user information
+into 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, as @code{_pw_init()}
+needs to be called only once.
+
+@cindex @code{PROCINFO} array, testing the field splitting
+@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, as 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.
+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 @code{FPAT},
+or on some other @command{awk} implementation.
+
+The code that checks for using @code{FPAT}, using @code{using_fpat}
+and @code{PROCINFO["FS"]}, is similar.
+
+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} or @code{FPAT}
+if necessary), @code{RS}, and @code{$0}.
+The use of @code{@w{_pw_count}} is explained shortly.
+
+@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
+relies on the array reference to a nonexistent
+element to create the element with the null string as its value:
+
+@cindex @code{getpwnam()} user-defined function
+@example
+@group
+@c file eg/lib/passwdawk.in
+function getpwnam(name)
+@{
+ _pw_init()
+ return _pw_byname[name]
+@}
+@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()
+ return _pw_byuid[uid]
+@}
+@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 is 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, as most @command{awk} programs are I/O-bound,
+and such a change would clutter up the code.
+
+The @command{id} program in @DBREF{Id Program}
+uses these functions.
+
+@node Group Functions
+@section Reading the Group Database
+
+@cindex libraries of @command{awk} functions, group database, reading
+@cindex functions, library, group database@comma{} reading
+@cindex group database, reading
+@cindex database, group, reading
+@cindex @code{PROCINFO} array, and group membership
+@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
+@DBREF{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 may 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.
+@command{grcat}, a C program that ``cats'' the group database,
+is as follows:
+
+@cindex @command{grcat} program
+@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@@skeeve.com, May 1993
+ * Public Domain
+ * December 2010, move to ANSI C definition for main().
+ */
+
+/* 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(int argc, char **argv)
+@{
+ struct group *g;
+ int i;
+
+ while ((g = getgrent()) != NULL) @{
+@c endfile
+@ignore
+@c file eg/lib/grcat.c
+#ifdef ZOS_USS
+ printf("%s:%ld:", g->gr_name, (long) g->gr_gid);
+#else
+@c endfile
+@end ignore
+@c file eg/lib/grcat.c
+ printf("%s:%s:%ld:", g->gr_name, g->gr_passwd,
+ (long) g->gr_gid);
+@c endfile
+@ignore
+@c file eg/lib/grcat.c
+#endif
+@c endfile
+@end ignore
+@c file eg/lib/grcat.c
+ for (i = 0; g->gr_mem[i] != NULL; i++) @{
+ printf("%s", g->gr_mem[i]);
+@group
+ if (g->gr_mem[i+1] != NULL)
+ putchar(',');
+ @}
+@end group
+ putchar('\n');
+ @}
+ endgrent();
+ return 0;
+@}
+@c endfile
+@ignore
+@c file eg/lib/grcat.c
+#endif /* HAVE_GETGRENT */
+@c endfile
+@end ignore
+@end example
+
+Each line in the group database represents one group. The fields are
+separated with colons and represent the following information:
+
+@table @asis
+@item Group Name
+The group's name.
+
+@item Group Password
+The group's encrypted password. In practice, this field is never used;
+it is usually empty or set to @samp{*}.
+
+@item Group ID Number
+The group's numeric group ID number;
+the association of name to number must be 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
+
+Here is what running @command{grcat} might produce:
+
+@example
+$ @kbd{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@@skeeve.com, Public Domain
+# May 1993
+# Revised October 2000
+# Revised December 2010
+@c endfile
+@end ignore
+@c line break on _gr_init for smallbook
+@c file eg/lib/groupawk.in
+
+BEGIN @{
+ # Change to suit your system
+ _gr_awklib = "/usr/local/libexec/awk/"
+@}
+
+function _gr_init( oldfs, oldrs, olddol0, grcat,
+ using_fw, using_fpat, n, a, i)
+@{
+ if (_gr_inited)
+ return
+
+ oldfs = FS
+ oldrs = RS
+ olddol0 = $0
+ using_fw = (PROCINFO["FS"] == "FIELDWIDTHS")
+ using_fpat = (PROCINFO["FS"] == "FPAT")
+ FS = ":"
+ RS = "\n"
+
+ grcat = _gr_awklib "grcat"
+ while ((grcat | getline) > 0) @{
+ if ($1 in _gr_byname)
+ _gr_byname[$1] = _gr_byname[$1] "," $4
+ else
+ _gr_byname[$1] = $0
+ if ($3 in _gr_bygid)
+ _gr_bygid[$3] = _gr_bygid[$3] "," $4
+ else
+ _gr_bygid[$3] = $0
+
+ n = split($4, a, "[ \t]*,[ \t]*")
+ for (i = 1; i <= n; i++)
+ if (a[i] in _gr_groupsbyuser)
+ _gr_groupsbyuser[a[i]] = gr_groupsbyuser[a[i]] " " $1
+ else
+ _gr_groupsbyuser[a[i]] = $1
+
+ _gr_bycount[++_gr_count] = $0
+ @}
+ close(grcat)
+ _gr_count = 0
+ _gr_inited++
+ FS = oldfs
+ if (using_fw)
+ FIELDWIDTHS = FIELDWIDTHS
+ else if (using_fpat)
+ FPAT = FPAT
+ 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{RS}, and
+@code{$0}, and then sets @code{FS} and @code{RS} to the correct values for
+scanning the group information.
+It also takes care to note whether @code{FIELDWIDTHS} or @code{FPAT}
+is being used, and to restore the appropriate field splitting mechanism.
+
+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:johny,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, the usernames are
+simply concatenated onto the previous list of users.@footnote{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} or @code{FPAT} 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, it
+relies on the array reference to a nonexistent
+element to create the element with the null string as its value:
+
+@cindex @code{getgrnam()} user-defined function
+@example
+@c file eg/lib/groupawk.in
+function getgrnam(group)
+@{
+ _gr_init()
+ return _gr_byname[group]
+@}
+@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()
+ return _gr_bygid[gid]
+@}
+@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()
+ return _gr_groupsbyuser[user]
+@}
+@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
+
+@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 @DBREF{Id Program}
+uses these functions.
+
+@node Walking Arrays
+@section Traversing Arrays of Arrays
+
+@DBREF{Arrays of Arrays} described how @command{gawk}
+provides arrays of arrays. In particular, any element of
+an array may be either a scalar, or another array. The
+@code{isarray()} function (@pxref{Type Functions})
+lets you distinguish an array
+from a scalar.
+The following function, @code{walk_array()}, recursively traverses
+an array, printing each element's indices and value.
+You call it with the array and a string representing the name
+of the array:
+
+@cindex @code{walk_array()} user-defined function
+@example
+@c file eg/lib/walkarray.awk
+function walk_array(arr, name, i)
+@{
+ for (i in arr) @{
+ if (isarray(arr[i]))
+ walk_array(arr[i], (name "[" i "]"))
+ else
+ printf("%s[%s] = %s\n", name, i, arr[i])
+ @}
+@}
+@c endfile
+@end example
+
+@noindent
+It works by looping over each element of the array. If any given
+element is itself an array, the function calls itself recursively,
+passing the subarray and a new string representing the current index.
+Otherwise, the function simply prints the element's name, index, and value.
+Here is a main program to demonstrate:
+
+@example
+BEGIN @{
+ a[1] = 1
+ a[2][1] = 21
+ a[2][2] = 22
+ a[3] = 3
+ a[4][1][1] = 411
+ a[4][2] = 42
+
+ walk_array(a, "a")
+@}
+@end example
+
+When run, the program produces the following output:
+
+@example
+$ @kbd{gawk -f walk_array.awk}
+@print{} a[1] = 1
+@print{} a[2][1] = 21
+@print{} a[2][2] = 22
+@print{} a[3] = 3
+@print{} a[4][1][1] = 411
+@print{} a[4][2] = 42
+@end example
+
+
+@node Library Functions Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+Reading programs is an excellent way to learn Good Programming.
+The functions and programs provided in this @value{CHAPTER} and the next
+are intended to serve that purpose.
+
+@item
+When writing general-purpose library functions, put some thought into how
+to name any global variables so that they won't conflict with variables
+from a user's program.
+
+@item
+The functions presented here fit into the following categories:
+
+@c nested list
+@table @asis
+@item General problems
+Number-to-string conversion, assertions, rounding, random number
+generation, converting characters to numbers, joining strings, getting
+easily usable time-of-day information, and reading a whole file in
+one shot.
+
+@item Managing @value{DF}s
+Noting @value{DF} boundaries, rereading the current file, checking for
+readable files, checking for zero-length files, and treating assignments
+as @value{FN}s.
+
+@item Processing command-line options
+An @command{awk} version of the standard C @code{getopt()} function.
+
+@item Reading the user and group databases
+Two sets of routines that parallel the C library versions.
+
+@item Traversing arrays of arrays
+A simple function to traverse an array of arrays to any depth.
+@end table
+@c end nested list
+
+@end itemize
+
+@c EXCLUDE START
+@node Library Exercises
+@section Exercises
+
+@enumerate
+@item
+In @ref{Empty Files}, we presented the @file{zerofile.awk} program,
+which made use of @command{gawk}'s @code{ARGIND} variable. Can this
+problem be solved without relying on @code{ARGIND}? If so, how?
+
+@ignore
+# zerofile2.awk --- same thing, portably
+
+BEGIN @{
+ ARGIND = Argind = 0
+ for (i = 1; i < ARGC; i++)
+ Fnames[ARGV[i]]++
+
+@}
+FNR == 1 @{
+ while (ARGV[ARGIND] != FILENAME)
+ ARGIND++
+ Seen[FILENAME]++
+ if (Seen[FILENAME] == Fnames[FILENAME])
+ do
+ ARGIND++
+ while (ARGV[ARGIND] != FILENAME)
+@}
+ARGIND > Argind + 1 @{
+ for (Argind++; Argind < ARGIND; Argind++)
+ zerofile(ARGV[Argind], Argind)
+@}
+ARGIND != Argind @{
+ Argind = ARGIND
+@}
+END @{
+ if (ARGIND < ARGC - 1)
+ ARGIND = ARGC - 1
+ if (ARGIND > Argind)
+ for (Argind++; Argind <= ARGIND; Argind++)
+ zerofile(ARGV[Argind], Argind)
+@}
+@end ignore
+
+@item
+As a related challenge, revise that code to handle the case where
+an intervening value in @code{ARGV} is a variable assignment.
+
+@item
+@DBREF{Walking Arrays} presented a function that walked a multidimensional
+array to print it out. However, walking an array and processing
+each element is a general-purpose operation. Generalize the
+@code{walk_array()} function by adding an additional parameter named
+@code{process}.
+
+Then, inside the loop, instead of printing the array element's index and
+value, use the indirect function call syntax (@pxref{Indirect Calls})
+on @code{process}, passing it the index and the value.
+
+When calling @code{walk_array()}, you would pass the name of a
+user-defined function that expects to receive an index and a value,
+and then processes the element.
+
+Test your new version by printing the array; you should end up with
+output identical to that of the original version.
+
+@end enumerate
+@c EXCLUDE END
+
+
+@node Sample Programs
+@chapter Practical @command{awk} Programs
+@cindex @command{awk} programs, examples of
+
+@c FULLXREF ON
+@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.
+@c FULLXREF OFF
+@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 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.
+* Programs Summary:: Summary of programs.
+* Programs Exercises:: Exercises.
+@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
+@cindex POSIX, programs@comma{} implementing in @command{awk}
+
+This @value{SECTION} presents a number of POSIX utilities 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.
+Nor may all of these programs be fully compliant with the most recent
+POSIX standard. This is not a problem; 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
+@cindex @command{cut} utility
+@cindex fields, cutting
+@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@@skeeve.com, 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()
+@{
+ print("usage: cut [-f list] [-d c] [-s] [files...]") > "/dev/stderr"
+ print("usage: cut [-c list] [files...]") > "/dev/stderr"
+ exit 1
+@}
+@end group
+@c endfile
+@end example
+
+@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 rule then sets the output field separator to be the
+same as the input field separator. A loop using @code{getopt()} steps
+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("cut: 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 = 1
+ else
+ usage()
+ @}
+
+ # Clear out options
+ for (i = 1; i < Optind; i++)
+ ARGV[i] = ""
+@c endfile
+@end example
+
+@cindex field separators, spaces as
+The code must take
+special care 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 remember that after @code{getopt()} is through
+(as described in @ref{Getopt Function}),
+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()} splits the field list apart at the commas
+into an array. Then, for each element of the array, it looks to
+see if the element is actually a range, and if so, splits it apart.
+The function checks the range
+to make sure that 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("cut: 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, n, m, 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("cut: 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 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. It is possible in
+other @command{awk} implementations to use @code{substr()}
+(@pxref{String Functions}), but
+it is also extremely painful.
+The @code{FIELDWIDTHS} variable supplies an elegant solution to the problem
+of picking the input line apart by characters.
+
+
+@node Egrep Program
+@subsection Searching for Regular Expressions in Files
+
+@cindex regular expressions, searching for
+@cindex searching, files for regular expressions
+@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}).
+You invoke it as follows:
+
+@display
+@command{egrep} [@var{options}] @code{'@var{pattern}'} @var{files} @dots{}
+@end display
+
+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} predefined 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@@skeeve.com, 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, as 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 as it is not necessary with @command{gawk}:
+
+@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 @code{BEGINFILE} and @code{ENDFILE} special patterns
+(@pxref{BEGINFILE/ENDFILE}) could be used, but then the program would be
+@command{gawk}-specific. Additionally, this example was written before
+@command{gawk} acquired @code{BEGINFILE} and @code{ENDFILE}.
+
+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.
+
+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{!} (exclamation point), @code{!} operator
+@cindex exclamation point (@code{!}), @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 @{
+ exit (total == 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()
+@{
+ print("Usage: egrep [-csvil] [-e pat] [files ...]") > "/dev/stderr"
+ print("\n\tegrep [-csvil] pat [files ...]") > "/dev/stderr"
+ exit 1
+@}
+@c endfile
+@end example
+
+
+@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
+$ @kbd{id}
+@print{} uid=1000(arnold) gid=1000(arnold) groups=1000(arnold),4(adm),7(lp),27(sudo)
+@end example
+
+@cindex @code{PROCINFO} array, and user and group ID numbers
+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@@skeeve.com, Public Domain
+# May 1993
+# Revised February 1996
+# Revised May 2014
+# Revised September 2014
+
+@c endfile
+@end ignore
+@c file eg/prog/id.awk
+# 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)
+ pr_first_field(pw)
+
+ if (euid != uid) @{
+ printf(" euid=%d", euid)
+ pw = getpwuid(euid)
+ pr_first_field(pw)
+ @}
+
+ printf(" gid=%d", gid)
+ pw = getgrgid(gid)
+ pr_first_field(pw)
+
+ if (egid != gid) @{
+ printf(" egid=%d", egid)
+ pw = getgrgid(egid)
+ pr_first_field(pw)
+ @}
+
+ for (i = 1; ("group" i) in PROCINFO; i++) @{
+ if (i == 1)
+ printf(" groups=")
+ group = PROCINFO["group" i]
+ printf("%d", group)
+ pw = getgrgid(group)
+ pr_first_field(pw)
+ if (("group" (i+1)) in PROCINFO)
+ printf(",")
+ @}
+
+ print ""
+@}
+
+function pr_first_field(str, a)
+@{
+ if (str != "") @{
+ split(str, a, ":")
+ printf("(%s)", a[1])
+ @}
+@}
+@c endfile
+@end example
+
+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 (@pxref{Reference to Elements}). 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.
+
+The @code{pr_first_field()} function simply isolates out some
+code that is used repeatedly, making the whole program
+shorter and cleaner. In particular, moving the check for
+the empty string into this function saves several lines of code.
+
+
+@node Split Program
+@subsection Splitting a Large File into Pieces
+
+@c FIXME: One day, update to current POSIX version of split
+
+@cindex files, splitting
+@cindex @code{split} utility
+The @command{split} program splits large text files into smaller pieces.
+Usage is as follows:@footnote{This is the traditional usage. The
+POSIX usage is different, but not relevant for what the program
+aims to demonstrate.}
+
+@display
+@command{split} [@code{-@var{count}}] [@var{file}] [@var{prefix}]
+@end display
+
+By default,
+the output files are named @file{xaa}, @file{xab}, and so on. Each file has
+1,000 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 1,000). 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 @command{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 @value{DF} name 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@@skeeve.com, Public Domain
+# May 1993
+# Revised slightly, May 2014
+
+@c endfile
+@end ignore
+@c file eg/prog/split.awk
+# usage: split [-count] [file] [outname]
+
+BEGIN @{
+ outfile = "x" # default
+ count = 1000
+ if (ARGC > 4)
+ usage()
+
+ i = 1
+ if (i in ARGV && ARGV[i] ~ /^-[[:digit:]]+$/) @{
+ count = -ARGV[i]
+ ARGV[i] = ""
+ i++
+ @}
+ # test argv in case reading from stdin instead of file
+ if (i in ARGV)
+ i++ # skip datafile 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
+
+@noindent
+The @code{usage()} function simply prints an error message and exits:
+
+@example
+@c file eg/prog/split.awk
+function usage()
+@{
+ print("usage: split [-num] [file] [outname]") > "/dev/stderr"
+ exit 1
+@}
+@c endfile
+@end example
+
+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.
+
+@ifset FOR_PRINT
+You might want to consider how to eliminate the use of
+@code{ord()} and @code{chr()}; this can be done in such a
+way as to solve the EBCDIC issue as well.
+@end ifset
+
+
+@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:
+
+@display
+@command{tee} [@option{-a}] @var{file} @dots{}
+@end display
+
+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 needed, so it is not copied.
+@code{tee} cannot use @code{ARGV} directly, because @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:
+
+@cindex @code{tee.awk} program
+@example
+@c file eg/prog/tee.awk
+# tee.awk --- tee in awk
+#
+# Copy standard input to all named output files.
+# Append content if -a option is supplied.
+#
+@c endfile
+@ignore
+@c file eg/prog/tee.awk
+# Arnold Robbins, arnold@@skeeve.com, Public Domain
+# May 1993
+# Revised December 1995
+
+@c endfile
+@end ignore
+@c file eg/prog/tee.awk
+BEGIN @{
+ for (i = 1; i < ARGC; i++)
+ 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 following single rule does all the work. Because 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 FIXME: One day, update to current POSIX version of uniq
+
+@cindex printing, unduplicated lines of text
+@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:
+
+@display
+@command{uniq} [@option{-udc} [@code{-@var{n}}]] [@code{+@var{n}}] [@var{inputfile} [@var{outputfile}]]
+@end display
+
+The options for @command{uniq} are:
+
+@table @code
+@item -d
+Print only repeated (duplicated) lines.
+
+@item -u
+Print only nonrepeated (unique) 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{inputfile}
+Data is read from the input file named on the command line, instead of from
+the standard input.
+
+@item @var{outputfile}
+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 comments.
+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@@skeeve.com, Public Domain
+# May 1993
+@c endfile
+@end ignore
+@c file eg/prog/uniq.awk
+
+function usage()
+@{
+ print("Usage: uniq [-udc [-n]] [+n] [ in [ out ]]") > "/dev/stderr"
+ exit 1
+@}
+
+# -c count lines. overrides -d and -u
+# -d only repeated lines
+# -u only nonrepeated 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 ~ /^[[:digit:]]+$/)
+ fcount = (c Optarg) + 0
+ else @{
+ fcount = c + 0
+ Optind--
+ @}
+ @} else
+ usage()
+ @}
+
+ if (ARGV[Optind] ~ /^\+[[:digit:]]+$/) @{
+ 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()} 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},
+because 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, as 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
+ close(outputfile)
+@}
+@c endfile
+@end example
+
+@c FIXME: Include this?
+@ignore
+This program does not follow our recommended convention of naming
+global variables with a leading capital letter. Doing that would
+make the program a little easier to follow.
+@end ignore
+
+@ifset FOR_PRINT
+The logic for choosing which lines to print represents a @dfn{state
+machine}, which is ``a device that can be in one of a set number of stable
+conditions depending on its previous condition and on the present values
+of its inputs.''@footnote{This is the definition returned from entering
+@code{define: state machine} into Google.}
+Brian Kernighan suggests that
+``an alternative approach to state machines is to just read
+the input into an array, then use indexing. It's almost always
+easier code, and for most inputs where you would use this, just
+as fast.'' Consider how to rewrite the logic to follow this
+suggestion.
+@end ifset
+
+
+
+@node Wc Program
+@subsection Counting Things
+
+@c FIXME: One day, update to current POSIX version of wc
+
+@cindex counting
+@cindex input files, counting elements in
+@cindex words, counting
+@cindex characters, counting
+@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:
+
+@display
+@command{wc} [@option{-lwc}] [@var{files} @dots{}]
+@end display
+
+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 as follows:
+
+@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,
+because @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 program 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@@skeeve.com, 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}:
+
+@example
+@c file eg/prog/wc.awk
+function beginfile(file)
+@{
+ lines = words = chars = 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. 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}:
+
+@example
+@c file eg/prog/wc.awk
+function endfile(file)
+@{
+ tlines += lines
+ twords += words
+ tchars += chars
+ 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}.@footnote{Because @command{gawk}
+understands multibyte locales, this code counts characters, not bytes.}
+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
+
+@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.
+* Anagram Program:: Finding anagrams from a dictionary.
+* Signature Program:: People do amazing things with too much time on
+ their hands.
+@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
+@iftex
+the
+@end iftex
+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@@skeeve.com, Public Domain
+# December 1991
+# Revised October 2000
+
+@c endfile
+@end ignore
+@c file eg/prog/dupword.awk
+@{
+ $0 = tolower($0)
+ gsub(/[^[:alnum:][:blank:]]/, " ");
+ $0 = $0 # 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.}
+@author Arnold Robbins
+@end quotation
+@cindex Quanstrom, Erik
+@ignore
+Date: Sat, 15 Feb 2014 16:47:09 -0500
+Subject: Re: 9atom install question
+Message-ID: <l2jcvx6j6mey60xnrkb0hhob.1392500829294@email.android.com>
+From: Erik Quanstrom <quanstro@quanstro.net>
+To: Aharon Robbins <arnold@skeeve.com>
+
+yes.
+
+- erik
+
+Aharon Robbins <arnold@skeeve.com> wrote:
+
+>> sleep is for web developers.
+>
+>Can I quote you, in the gawk manual?
+>
+>Thanks,
+>
+>Arnold
+@end ignore
+@quotation
+@i{Sleep is for web developers.}
+@author Erik Quanstrom
+@end quotation
+
+@cindex time, alarm clock example program
+@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{getlocaltime()} function from
+@ref{Getlocaltime 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.)
+Just for a change, this program uses a @code{switch} statement
+(@pxref{Switch Statement}), but the processing could be done with a series of
+@code{if}-@code{else} statements instead.
+Here is the program:
+
+@cindex @code{alarm.awk} program
+@example
+@c file eg/prog/alarm.awk
+# alarm.awk --- set an alarm
+#
+# Requires getlocaltime() library function
+@c endfile
+@ignore
+@c file eg/prog/alarm.awk
+#
+# Arnold Robbins, arnold@@skeeve.com, Public Domain
+# May 1993
+# Revised December 2010
+
+@c endfile
+@end ignore
+@c file eg/prog/alarm.awk
+# 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
+ @}
+ switch (ARGC) @{
+ case 5:
+ delay = ARGV[4] + 0
+ # fall through
+ case 4:
+ count = ARGV[3] + 0
+ # fall through
+ case 3:
+ message = ARGV[2]
+ break
+ default:
+ if (ARGV[1] !~ /[[:digit:]]?[[:digit:]]:[[:digit:]]@{2@}/) @{
+ print usage1 > "/dev/stderr"
+ print usage2 > "/dev/stderr"
+ exit 1
+ @}
+ break
+ @}
+
+ # 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
+ getlocaltime(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 "alarm: 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
+
+@node Translate Program
+@subsection Transliterating Characters
+
+@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
+systems, including Solaris, the system version of @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.
+
+Once upon a time,
+@c early or mid-1989!
+a user proposed adding a transliteration function
+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 was written long before @command{gawk}
+acquired the ability to split each character in a string into separate
+array elements. Thus, it makes repeated use of the @code{substr()},
+@code{index()}, and @code{gsub()} built-in functions (@pxref{String
+Functions}). 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},
+it is replaced with the corresponding @code{to} character.
+
+The @code{translate()} function 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@@skeeve.com, Public Domain
+# August 1989
+# February 2009 - bug fix
+
+@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, ltarget, t_ar, i, c,
+ result)
+@{
+ lf = length(from)
+ lt = length(to)
+ ltarget = length(target)
+ 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 <= ltarget; i++) @{
+ c = substr(target, i, 1)
+ if (c in t_ar)
+ c = t_ar[c]
+ result = result c
+ @}
+ return result
+@}
+
+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
+
+It is possible to do character transliteration in a user-level
+function, but it is not necessarily efficient, and we (the @command{gawk}
+developers) started to consider adding a built-in function. However,
+shortly after writing this program, we learned that Brian Kernighan
+had added the @code{toupper()} and @code{tolower()} functions to his
+@command{awk} (@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.
+
+Another obvious improvement is to enable the use of ranges,
+such as @samp{a-z}, as allowed by the @command{tr} utility.
+Look at the code for @file{cut.awk} (@pxref{Cut Program})
+for inspiration.
+
+
+@node Labels Program
+@subsection Printing Mailing Labels
+
+@cindex printing, mailing labels
+@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, two across and 10 down. The addresses are guaranteed to be no more
+than five 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, because 100 is the maximum number
+of lines on the page
+@iftex
+(@math{20 @cdot 5 = 100}).
+@end iftex
+@ifnottex
+@ifnotdocbook
+(20 * 5 = 100).
+@end ifnotdocbook
+@end ifnottex
+@docbook
+(20 &sdot; 5 = 100). @c
+@end docbook
+
+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
+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
+
+@noindent
+The @code{printf} format string @samp{%-41s} left-aligns
+the data and prints it within a fixed-width field.
+
+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 two blank lines at the top and two 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@@skeeve.com, Public Domain
+# June 1992
+# December 2010, minor edits
+@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
+
+ delete line
+@}
+
+# 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
+
+@node Word Sorting
+@subsection Generating Word-Usage Counts
+
+@cindex words, usage counts@comma{} generating
+
+When working with large amounts of text, it can be interesting to know
+how often different words appear. For example, an author may overuse
+certain words, in which case he or she might wish to find synonyms to substitute
+for words that appear too often. This @value{SUBSECTION} develops a
+program for counting words and presenting the frequency information
+in a useful format.
+
+At first glance, a program like this would seem to do the job:
+
+@example
+# wordfreq-first-try.awk --- 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
+
+The program relies on @command{awk}'s default field splitting
+mechanism to break each line up into ``words,'' and uses an
+associative array named @code{freq}, indexed by each word, to count
+the number of times the word occurs. In the @code{END} rule,
+it prints the counts.
+
+This program has several problems that prevent it from being
+useful on real text files:
+
+@itemize @value{BULLET}
+@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, because words are capitalized
+if they begin sentences in normal text, and a frequency analyzer should
+not be sensitive to capitalization.
+
+@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 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 first problem can be solved by using @code{tolower()} to remove case
+distinctions. The second problem can be solved by using @code{gsub()}
+to remove punctuation characters. Finally, we solve the third problem
+by using 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]++
+@}
+
+@c endfile
+END @{
+ for (word in freq)
+ printf "%s\t%d\n", word, freq[word]
+@}
+@end example
+
+The regexp @code{/[^[:alnum:]_[:blank:]]/} might have been written
+@code{/[[:punct:]]/}, but then underscores would also be removed,
+and we want to keep them.
+
+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 screen.
+
+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.
+
+@node History Sorting
+@subsection Removing Duplicates from Unsorted Text
+
+@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@@skeeve.com, Public Domain
+# May 1993
+@c endfile
+@end ignore
+@c file eg/prog/histsort.awk
+
+@group
+@{
+ if (data[$0]++ == 0)
+ lines[++count] = $0
+@}
+@end group
+
+@group
+END @{
+ for (i = 1; i <= count; i++)
+ print lines[i]
+@}
+@end group
+@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
+
+@noindent
+This works because @code{data[$0]} is incremented each time a line is
+seen.
+
+@node Extract Program
+@subsection Extracting Programs from Texinfo Source Files
+
+@cindex Texinfo, extracting programs from source files
+@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 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 @uref{http://www.gnu.org/software/texinfo/, Texinfo},
+the GNU project's document formatting language.
+A single Texinfo source file can be used to produce both
+printed documentation, with @TeX{}, and online documentation.
+@ifnotinfo
+(Texinfo is fully documented in the book
+@cite{Texinfo---The GNU Documentation Format},
+available from the Free Software Foundation,
+and also available @uref{http://www.gnu.org/software/texinfo/manual/texinfo/, online}.)
+@end ifnotinfo
+@ifinfo
+(The Texinfo language is described fully, starting with
+@inforef{Top, , Texinfo, texinfo,Texinfo---The GNU Documentation Format}.)
+@end ifinfo
+
+For our purposes, it is enough to know three things about Texinfo input
+files:
+
+@itemize @value{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,
+so 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{gawktexi.in}) 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 archaeologists!" @@@}
+@@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@@skeeve.com, Public Domain
+# May 1993
+# Revised September 2000
+@c endfile
+@end ignore
+@c file eg/prog/extract.awk
+
+BEGIN @{ IGNORECASE = 1 @}
+
+/^@@c(omment)?[ \t]+system/ @{
+ if (NF < 3) @{
+ e = ("extract: " FILENAME ":" FNR)
+ e = (e ": badly formed `system' line")
+ print e > "/dev/stderr"
+ next
+ @}
+ $1 = ""
+ $2 = ""
+ stat = system($0)
+ if (stat != 0) @{
+ e = ("extract: " 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 rule
+fits nicely on the @value{PAGE}.
+
+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 @code{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} (@pxref{Multidimensional}),
+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 = ("extract: " 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 @value{DF} name 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:
+
+@example
+@c file eg/prog/extract.awk
+@group
+function unexpected_eof()
+@{
+ printf("extract: %s:%d: unexpected EOF or error\n",
+ FILENAME, FNR) > "/dev/stderr"
+ exit 1
+@}
+@end group
+
+END @{
+ if (curfile)
+ close(curfile)
+@}
+@c endfile
+@end example
+
+@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.
+Although @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
+@var{command1} < orig.data | sed 's/old/new/g' | @var{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 @value{DF} names 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@@skeeve.com, 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 earlier,
+using @code{print} or @code{printf} as appropriate, depending upon the
+value of @code{RT}.
+
+@node Igawk Program
+@subsection An Easy Way to Use Library Functions
+
+@cindex libraries of @command{awk} functions, example program for using
+@cindex functions, library, example program for using
+In @ref{Include Files}, we saw how @command{gawk} provides a built-in
+file-inclusion capability. However, this is a @command{gawk} extension.
+This @value{SECTION} provides the motivation for making file inclusion
+available for standard @command{awk}, and shows how to do it using a
+combination of shell and @command{awk} programming.
+
+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 @code{@@include} can contain further @code{@@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{-e} 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.
+Because the file-inclusion program works the way @command{gawk} does, this
+gets the text of the file included in the program at the correct point.
+@end enumerate
+
+@item
+Run an @command{awk} program (naturally) over the shell variable's contents to expand
+@code{@@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 @value{DF} names).
+@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:
+
+@c @asis for docbook
+@table @asis
+@item @option{--}
+This ends the arguments to @command{igawk}. Anything else should be passed on
+to the user's @command{awk} program without being evaluated.
+
+@item @option{-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 @option{-v}, @option{-F}
+These are saved and passed on to @command{gawk}.
+
+@item @option{-f}, @option{--file}, @option{--file=}, @option{-Wfile=}
+The @value{FN} is appended to the shell variable @code{program} with an
+@code{@@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 @option{--source}, @option{--source=}, @option{-Wsource=}
+The source text is appended to @code{program}.
+
+@item @option{--version}, @option{-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,
+the shell variable
+@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@@skeeve.com, Public Domain
+# July 1993
+# December 2010, minor edits
+@c endfile
+@end ignore
+@c file eg/prog/igawk.sh
+
+if [ "$1" = debug ]
+then
+ set -x
+ shift
+fi
+
+# A literal newline, so that program text is formatted 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 3.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 @code{@@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 @code{@@include} statements are managed using a stack.
+As each @code{@@include} is encountered, the current @value{FN} is
+``pushed'' onto the stack and the file named in the @code{@@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.
+Similarly, if the @value{FN} is @code{"-"}, then that string is
+used as-is. 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.}
+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
+
+ if (file == "-")
+ 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 @code{"/dev/stdin"}.
+The main loop comes next. Input lines are read in succession. Lines that
+do not start with @code{@@include} are printed verbatim.
+If the line does start with @code{@@include}, the @value{FN} is in @code{$2}.
+@code{pathto()} is called to generate the full path. If it cannot, then the program
+prints an error message and continues.
+
+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 inside the parentheses is substituted
+into the command line.
+Because the result is used in a variable assignment,
+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 @code{@@include}-processing program (the
+value of the @code{expand_prog} shell variable) reading standard input.
+
+@item
+Standard input is the contents of the user's program,
+from the shell variable @code{program}.
+Feed its contents to @command{gawk} via a here document.
+
+@item
+Save the results of this processing 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 the fifth version of this program.
+There are four key simplifications that make the program work better:
+
+@itemize @value{BULLET}
+@item
+Using @code{@@include} even for the files named with @option{-f} makes building
+the initial collected @command{awk} program much simpler; all the
+@code{@@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.
+
+@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 @code{@@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.@footnote{@command{gawk}
+does @code{@@include} processing itself in order to support the use
+of @command{awk} programs as Web CGI scripts.}
+
+
+@node Anagram Program
+@subsection Finding Anagrams from a Dictionary
+
+@cindex anagrams, finding
+An interesting programming challenge is to
+search for @dfn{anagrams} in a
+word list (such as
+@file{/usr/share/dict/words} on many GNU/Linux systems).
+One word is an anagram of another if both words contain
+the same letters
+(e.g., ``babbling'' and ``blabbing'').
+
+Column 2, Problem C, of Jon Bentley's @cite{Programming Pearls}, Second
+Edition, presents an elegant algorithm. The idea is to give words that
+are anagrams a common signature, sort all the words together by their
+signature, and then print them. Dr.@: Bentley observes that taking the
+letters in each word and sorting them produces that common signature.
+
+The following program uses arrays of arrays to bring together
+words with the same signature and array sorting to print the words
+in sorted order:
+
+@cindex @code{anagram.awk} program
+@example
+@c file eg/prog/anagram.awk
+# anagram.awk --- An implementation of the anagram finding algorithm
+# from Jon Bentley's "Programming Pearls", 2nd edition.
+# Addison Wesley, 2000, ISBN 0-201-65788-0.
+# Column 2, Problem C, section 2.8, pp 18-20.
+@c endfile
+@ignore
+@c file eg/prog/anagram.awk
+#
+# This program requires gawk 4.0 or newer.
+# Required gawk-specific features:
+# - True multidimensional arrays
+# - split() with "" as separator splits out individual characters
+# - asort() and asorti() functions
+#
+# See http://savannah.gnu.org/projects/gawk.
+#
+# Arnold Robbins
+# arnold@@skeeve.com
+# Public Domain
+# January, 2011
+@c endfile
+@end ignore
+@c file eg/prog/anagram.awk
+
+/'s$/ @{ next @} # Skip possessives
+@c endfile
+@end example
+
+The program starts with a header, and then a rule to skip
+possessives in the dictionary file. The next rule builds
+up the data structure. The first dimension of the array
+is indexed by the signature; the second dimension is the word
+itself:
+
+@example
+@c file eg/prog/anagram.awk
+@{
+ key = word2key($1) # Build signature
+ data[key][$1] = $1 # Store word with signature
+@}
+@c endfile
+@end example
+
+The @code{word2key()} function creates the signature.
+It splits the word apart into individual letters,
+sorts the letters, and then joins them back together:
+
+@example
+@c file eg/prog/anagram.awk
+# word2key --- split word apart into letters, sort, joining back together
+
+function word2key(word, a, i, n, result)
+@{
+ n = split(word, a, "")
+ asort(a)
+
+ for (i = 1; i <= n; i++)
+ result = result a[i]
+
+ return result
+@}
+@c endfile
+@end example
+
+Finally, the @code{END} rule traverses the array
+and prints out the anagram lists. It sends the output
+to the system @command{sort} command because otherwise
+the anagrams would appear in arbitrary order:
+
+@example
+@c file eg/prog/anagram.awk
+END @{
+ sort = "sort"
+ for (key in data) @{
+ # Sort words with same key
+ nwords = asorti(data[key], words)
+ if (nwords == 1)
+ continue
+
+ # And print. Minor glitch: trailing space at end of each line
+ for (j = 1; j <= nwords; j++)
+ printf("%s ", words[j]) | sort
+ print "" | sort
+ @}
+ close(sort)
+@}
+@c endfile
+@end example
+
+Here is some partial output when the program is run:
+
+@example
+$ @kbd{gawk -f anagram.awk /usr/share/dict/words | grep '^b'}
+@dots{}
+babbled blabbed
+babbler blabber brabble
+babblers blabbers brabbles
+babbling blabbing
+babbly blabby
+babel bable
+babels beslab
+babery yabber
+@dots{}
+@end example
+
+
+@node Signature Program
+@subsection And Now for Something Completely Different
+
+@cindex signature program
+@cindex Brini, Davide
+The following program was written by Davide Brini
+@c (@email{dave_br@@gmx.com})
+and is published on @uref{http://backreference.org/2011/02/03/obfuscated-awk/,
+his website}.
+It serves as his signature in the Usenet group @code{comp.lang.awk}.
+He supplies the following copyright terms:
+
+@quotation
+Copyright @copyright{} 2008 Davide Brini
+
+Copying and distribution of the code published in this page, with or without
+modification, are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+@end quotation
+
+Here is the program:
+
+@example
+awk 'BEGIN@{O="~"~"~";o="=="=="==";o+=+o;x=O""O;while(X++<=x+o+o)c=c"%c";
+printf c,(x-O)*(x-O),x*(x-o)-o,x*(x-O)+x-O-o,+x*(x-O)-x+o,X*(o*o+O)+x-O,
+X*(X-x)-o*o,(x+X)*o*o+o,x*(X-x)-O-O,x-O+(O+o+X+x)*(o+O),X*X-X*(x-O)-x+O,
+O+X*(o*(o+O)+O),+x+O+X*o,x*(x-o),(o+X+x)*o*o-(x-O-O),O+(X-x)*(X+O),x-O@}'
+@end example
+
+@cindex Johansen, Chris
+We leave it to you to determine what the program does. (If you are
+truly desperate to understand it, see Chris Johansen's explanation,
+which is embedded in the Texinfo source file for this @value{DOCUMENT}.)
+
+@ignore
+To: "Arnold Robbins" <arnold@skeeve.com>
+Date: Sat, 20 Aug 2011 13:50:46 -0400
+Subject: The GNU Awk User's Guide, Section 13.3.11
+From: "Chris Johansen" <johansen@main.nc.us>
+Message-ID: <op.v0iw6wlv7finx3@asusodin.thrudvang.lan>
+
+Arnold, you don't know me, but we have a tenuous connection. My wife is
+Barbara A. Field, FAIA, GIT '65 (B. Arch.).
+
+I have had a couple of paper copies of "Effective Awk Programming" for
+years, and now I'm going through a Kindle version of "The GNU Awk User's
+Guide" again. When I got to section 13.3.11, I reformatted and lightly
+commented Davide Brin's signature script to understand its workings.
+
+It occurs to me that this might have pedagogical value as an example
+(although imperfect) of the value of whitespace and comments, and a
+starting point for that discussion. It certainly helped _me_ understand
+what's going on. You are welcome to it, as-is or modified (subject to
+Davide's constraints, of course, which I think I have met).
+
+If I were to include it in a future edition, I would put it at some
+distance from section 13.3.11, say, as a note or an appendix, so as not to
+be a "spoiler" to the puzzle.
+
+Best regards,
+--
+Chris Johansen {johansen at main dot nc dot us}
+ . . . collapsing the probability wave function, sending ripples of
+certainty through the space-time continuum.
+
+
+#! /usr/bin/gawk -f
+
+# From "13.3.11 And Now For Something Completely Different"
+# http://www.gnu.org/software/gawk/manual/html_node/Signature-Program.html#Signature-Program
+
+# Copyright © 2008 Davide Brini
+
+# Copying and distribution of the code published in this page, with
+# or without modification, are permitted in any medium without
+# royalty provided the copyright notice and this notice are preserved.
+
+BEGIN {
+ O = "~" ~ "~"; # 1
+ o = "==" == "=="; # 1
+ o += +o; # 2
+ x = O "" O; # 11
+
+
+ while ( X++ <= x + o + o ) c = c "%c";
+
+ # O is 1
+ # o is 2
+ # x is 11
+ # X is 17
+ # c is "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c"
+
+ printf c,
+ ( x - O )*( x - O), # 100 d
+ x*( x - o ) - o, # 97 a
+ x*( x - O ) + x - O - o, # 118 v
+ +x*( x - O ) - x + o, # 101 e
+ X*( o*o + O ) + x - O, # 95 _
+ X*( X - x ) - o*o, # 98 b
+ ( x + X )*o*o + o, # 114 r
+ x*( X - x ) - O - O, # 64 @
+ x - O + ( O + o + X + x )*( o + O ), # 103 g
+ X*X - X*( x - O ) - x + O, # 109 m
+ O + X*( o*( o + O ) + O ), # 120 x
+ +x + O + X*o, # 46 .
+ x*( x - o), # 99 c
+ ( o + X + x )*o*o - ( x - O - O ), # 111 0
+ O + ( X - x )*( X + O ), # 109 m
+ x - O # 10 \n
+}
+@end ignore
+
+@node Programs Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+The programs provided in this @value{CHAPTER}
+continue on the theme that reading programs is an excellent way to learn
+Good Programming.
+
+@item
+Using @samp{#!} to make @command{awk} programs directly runnable makes
+them easier to use. Otherwise, invoke the program using @samp{awk
+-f @dots{}}.
+
+@item
+Reimplementing standard POSIX programs in @command{awk} is a pleasant
+exercise; @command{awk}'s expressive power lets you write such programs
+in relatively few lines of code, yet they are functionally complete
+and usable.
+
+@item
+One of standard @command{awk}'s weaknesses is working with individual
+characters. The ability to use @code{split()} with the empty string as
+the separator can considerably simplify such tasks.
+
+@item
+The library functions from @ref{Library Functions}, proved their
+usefulness for a number of real (if small) programs.
+
+@item
+Besides reinventing POSIX wheels, other programs solved a selection of
+interesting problems, such as finding duplicates words in text, printing
+mailing labels, and finding anagrams.
+
+@end itemize
+
+@c EXCLUDE START
+@node Programs Exercises
+@section Exercises
+
+@enumerate
+@item
+Rewrite @file{cut.awk} (@pxref{Cut Program})
+using @code{split()} with @code{""} as the separator.
+
+@item
+In @ref{Egrep Program}, we mentioned that @samp{egrep -i} could be
+simulated in versions of @command{awk} without @code{IGNORECASE} by
+using @code{tolower()} on the line and the pattern. In a footnote there,
+we also mentioned that this solution has a bug: the translated line is
+output, and not the original one. Fix this problem.
+@c Exercise: Fix this, w/array and new line as key to original line
+
+@item
+The POSIX version of @command{id} takes options that control which
+information is printed. Modify the @command{awk} version
+(@pxref{Id Program}) to accept the same arguments and perform in the
+same way.
+
+@item
+The @code{split.awk} program (@pxref{Split Program}) assumes
+that letters are contiguous in the character set,
+which isn't true for EBCDIC systems.
+Fix this problem.
+(Hint: Consider a different way to work through the alphabet,
+without relying on @code{ord()} and @code{chr()}.)
+
+@item
+In @file{uniq.awk} (@pxref{Uniq Program}, the
+logic for choosing which lines to print represents a @dfn{state
+machine}, which is ``a device that can be in one of a set number of stable
+conditions depending on its previous condition and on the present values
+of its inputs.''@footnote{This is the definition returned from entering
+@code{define: state machine} into Google.}
+Brian Kernighan suggests that
+``an alternative approach to state machines is to just read
+the input into an array, then use indexing. It's almost always
+easier code, and for most inputs where you would use this, just
+as fast.'' Rewrite the logic to follow this
+suggestion.
+
+
+@item
+Why can't the @file{wc.awk} program (@pxref{Wc Program}) just
+use the value of @code{FNR} in @code{endfile()}?
+Hint: Examine the code in @ref{Filetrans Function}.
+
+@ignore
+@command{wc} can't just use the value of @code{FNR} in
+@code{endfile()}. If you examine the code in @ref{Filetrans Function},
+you will see that @code{FNR} has already been reset by the time
+@code{endfile()} is called.
+@end ignore
+
+@item
+Manipulation of individual characters in the @command{translate} program
+(@pxref{Translate Program}) is painful using standard @command{awk}
+functions. Given that @command{gawk} can split strings into individual
+characters using @code{""} as the separator, how might you use this
+feature to simplify the program?
+
+@item
+The @file{extract.awk} program (@pxref{Extract Program}) was written
+before @command{gawk} had the @code{gensub()} function. Use it
+to simplify the code.
+
+@item
+Compare the performance of the @file{awksed.awk} program
+(@pxref{Simple Sed}) with the more straightforward:
+
+@example
+BEGIN @{
+ pat = ARGV[1]
+ repl = ARGV[2]
+ ARGV[1] = ARGV[2] = ""
+@}
+
+@{ gsub(pat, repl); print @}
+@end example
+
+@item
+What are the advantages and disadvantages of @file{awksed.awk} versus
+the real @command{sed} utility?
+
+@ignore
+ Advantage: egrep regexps
+ speed (?)
+ Disadvantage: no & in replacement text
+
+Others?
+@end ignore
+
+@item
+In @ref{Igawk Program}, we mentioned that 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. What problem does this engender though?
+@c answer, reading from "-" or /dev/stdin
+
+@cindex search paths
+@cindex search paths, for source files
+@cindex source files@comma{} search path for
+@cindex files, source@comma{} search path for
+@cindex directories, searching
+@item
+As an additional example of the idea that it is not always necessary to
+add new features to a program, 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 @code{@@include}
+directives, @file{default.awk} could simply contain @code{@@include}
+statements for the desired library functions.
+Make this change.
+
+@item
+Modify @file{anagram.awk} (@pxref{Anagram Program}), to avoid
+the use of the external @command{sort} utility.
+
+@end enumerate
+@c EXCLUDE END
+
+@ifnotinfo
+@part @value{PART3}Moving Beyond Standard @command{awk} with @command{gawk}
+@end ifnotinfo
+
+@ifdocbook
+Part III focuses on features specific to @command{gawk}.
+It contains the following chapters:
+
+@itemize @value{BULLET}
+@item
+@ref{Advanced Features}
+
+@item
+@ref{Internationalization}
+
+@item
+@ref{Debugger}
+
+@item
+@ref{Arbitrary Precision Arithmetic}
+
+@item
+@ref{Dynamic Extensions}
+@end itemize
+@end ifdocbook
+
+@node Advanced Features
+@chapter Advanced Features of @command{gawk}
+@cindex @command{gawk}, features, advanced
+@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
+@cindex Langston, Peter
+@cindex English, Steve
+@quotation
+@i{Write documentation as if whoever reads it is
+a violent psychopath who knows where you live.}
+@author 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.
+Then, @command{gawk}'s special features for sorting arrays are presented.
+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. Finally, @command{gawk}
+can @dfn{profile} an @command{awk} program, making it possible to tune
+it for performance.
+
+@c FULLXREF ON
+A number of advanced features require separate @value{CHAPTER}s of their
+own:
+
+@itemize @value{BULLET}
+@item
+@ref{Internationalization}, discusses how to internationalize
+your @command{awk} programs, so that they can speak multiple
+national languages.
+
+@item
+@ref{Debugger}, describes @command{gawk}'s built-in command-line
+debugger for debugging @command{awk} programs.
+
+@item
+@ref{Arbitrary Precision Arithmetic}, describes how you can use
+@command{gawk} to perform arbitrary-precision arithmetic.
+
+@item
+@ref{Dynamic Extensions},
+discusses the ability to dynamically add new built-in functions to
+@command{gawk}.
+@end itemize
+@c FULLXREF OFF
+
+@menu
+* Nondecimal Data:: Allowing nondecimal input data.
+* Array Sorting:: Facilities for controlling array traversal and
+ sorting arrays.
+* Two-way I/O:: Two-way communications with another process.
+* TCP/IP Networking:: Using @command{gawk} for network programming.
+* Profiling:: Profiling your @command{awk} programs.
+* Advanced Features Summary:: Summary of advanced features.
+@end menu
+
+@node Nondecimal Data
+@section Allowing Nondecimal Input Data
+@cindex @option{--non-decimal-data} option
+@cindex advanced features, 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 values in your input data:
+
+@example
+$ @kbd{echo 0123 123 0x123 |}
+> @kbd{gawk --non-decimal-data '@{ printf "%d, %d, %d\n", $1, $2, $3 @}'}
+@print{} 83, 123, 291
+@end example
+
+For this feature to work, write your program so that
+@command{gawk} treats your data as numeric:
+
+@example
+$ @kbd{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 need to add zero to a field to force it to
+be treated as a number. For example:
+
+@example
+$ @kbd{echo 0123 123 0x123 | gawk --non-decimal-data '}
+> @kbd{@{ print $1, $2, $3}
+> @kbd{print $1 + 0, $2 + 0, $3 + 0 @}'}
+@print{} 0123 123 0x123
+@print{} 83 123 291
+@end example
+
+Because it is common to have decimal data with leading zeros, and because
+using this facility could lead to surprising results, the default is to leave it
+disabled. If you want it, you must explicitly request it.
+
+@cindex programming conventions, @code{--non-decimal-data} option
+@cindex @option{--non-decimal-data} option, @code{strtonum()} function and
+@cindex @code{strtonum()} function (@command{gawk}), @code{--non-decimal-data} option and
+@quotation 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{String Functions}).
+This makes your programs easier to write and easier to read, and
+leads to less surprising results.
+
+This option may disappear in a future version of @command{gawk}.
+@end quotation
+
+@node Array Sorting
+@section Controlling Array Traversal and Array Sorting
+
+@command{gawk} lets you control the order in which a @samp{for (i in array)}
+loop traverses an array.
+
+In addition, two built-in functions, @code{asort()} and @code{asorti()},
+let you sort arrays based on the array values and indices, respectively.
+These two functions also provide control over the sorting criteria used
+to order the elements during sorting.
+
+@menu
+* Controlling Array Traversal:: How to use PROCINFO["sorted_in"].
+* Array Sorting Functions:: How to use @code{asort()} and @code{asorti()}.
+@end menu
+
+@node Controlling Array Traversal
+@subsection Controlling Array Traversal
+
+By default, the order in which a @samp{for (i in array)} loop
+scans an array is not defined; it is generally based upon
+the internal implementation of arrays inside @command{awk}.
+
+Often, though, it is desirable to be able to loop over the elements
+in a particular order that you, the programmer, choose. @command{gawk}
+lets you do this.
+
+@DBREF{Controlling Scanning} describes how you can assign special,
+predefined values to @code{PROCINFO["sorted_in"]} in order to
+control the order in which @command{gawk} traverses an array
+during a @code{for} loop.
+
+In addition, the value of @code{PROCINFO["sorted_in"]} can be a
+function name.@footnote{This is why the predefined sorting orders
+start with an @samp{@@} character, which cannot be part of an identifier.}
+This lets you traverse an array based on any custom criterion.
+The array elements are ordered according to the return value of this
+function. The comparison function should be defined with at least
+four arguments:
+
+@example
+function comp_func(i1, v1, i2, v2)
+@{
+ @var{compare elements 1 and 2 in some fashion}
+ @var{return < 0; 0; or > 0}
+@}
+@end example
+
+Here, @var{i1} and @var{i2} are the indices, and @var{v1} and @var{v2}
+are the corresponding values of the two elements being compared.
+Either @var{v1} or @var{v2}, or both, can be arrays if the array being
+traversed contains subarrays as values.
+(@DBXREF{Arrays of Arrays} for more information about subarrays.)
+The three possible return values are interpreted as follows:
+
+@table @code
+@item comp_func(i1, v1, i2, v2) < 0
+Index @var{i1} comes before index @var{i2} during loop traversal.
+
+@item comp_func(i1, v1, i2, v2) == 0
+Indices @var{i1} and @var{i2}
+come together but the relative order with respect to each other is undefined.
+
+@item comp_func(i1, v1, i2, v2) > 0
+Index @var{i1} comes after index @var{i2} during loop traversal.
+@end table
+
+Our first comparison function can be used to scan an array in
+numerical order of the indices:
+
+@example
+function cmp_num_idx(i1, v1, i2, v2)
+@{
+ # numerical index comparison, ascending order
+ return (i1 - i2)
+@}
+@end example
+
+Our second function traverses an array based on the string order of
+the element values rather than by indices:
+
+@example
+function cmp_str_val(i1, v1, i2, v2)
+@{
+ # string value comparison, ascending order
+ v1 = v1 ""
+ v2 = v2 ""
+ if (v1 < v2)
+ return -1
+ return (v1 != v2)
+@}
+@end example
+
+The third
+comparison function makes all numbers, and numeric strings without
+any leading or trailing spaces, come out first during loop traversal:
+
+@example
+function cmp_num_str_val(i1, v1, i2, v2, n1, n2)
+@{
+ # numbers before string value comparison, ascending order
+ n1 = v1 + 0
+ n2 = v2 + 0
+ if (n1 == v1)
+ return (n2 == v2) ? (n1 - n2) : -1
+ else if (n2 == v2)
+ return 1
+ return (v1 < v2) ? -1 : (v1 != v2)
+@}
+@end example
+
+Here is a main program to demonstrate how @command{gawk}
+behaves using each of the previous functions:
+
+@example
+BEGIN @{
+ data["one"] = 10
+ data["two"] = 20
+ data[10] = "one"
+ data[100] = 100
+ data[20] = "two"
+
+ f[1] = "cmp_num_idx"
+ f[2] = "cmp_str_val"
+ f[3] = "cmp_num_str_val"
+ for (i = 1; i <= 3; i++) @{
+ printf("Sort function: %s\n", f[i])
+ PROCINFO["sorted_in"] = f[i]
+ for (j in data)
+ printf("\tdata[%s] = %s\n", j, data[j])
+ print ""
+ @}
+@}
+@end example
+
+Here are the results when the program is run:
+
+@example
+$ @kbd{gawk -f compdemo.awk}
+@print{} Sort function: cmp_num_idx @ii{Sort by numeric index}
+@print{} data[two] = 20
+@print{} data[one] = 10 @ii{Both strings are numerically zero}
+@print{} data[10] = one
+@print{} data[20] = two
+@print{} data[100] = 100
+@print{}
+@print{} Sort function: cmp_str_val @ii{Sort by element values as strings}
+@print{} data[one] = 10
+@print{} data[100] = 100 @ii{String 100 is less than string 20}
+@print{} data[two] = 20
+@print{} data[10] = one
+@print{} data[20] = two
+@print{}
+@print{} Sort function: cmp_num_str_val @ii{Sort all numeric values before all strings}
+@print{} data[one] = 10
+@print{} data[two] = 20
+@print{} data[100] = 100
+@print{} data[10] = one
+@print{} data[20] = two
+@end example
+
+Consider sorting the entries of a GNU/Linux system password file
+according to login name. The following program sorts records
+by a specific field position and can be used for this purpose:
+
+@example
+# passwd-sort.awk --- simple program to sort by field position
+# field position is specified by the global variable POS
+
+function cmp_field(i1, v1, i2, v2)
+@{
+ # comparison by value, as string, and ascending order
+ return v1[POS] < v2[POS] ? -1 : (v1[POS] != v2[POS])
+@}
+
+@{
+ for (i = 1; i <= NF; i++)
+ a[NR][i] = $i
+@}
+
+END @{
+ PROCINFO["sorted_in"] = "cmp_field"
+ if (POS < 1 || POS > NF)
+ POS = 1
+ for (i in a) @{
+ for (j = 1; j <= NF; j++)
+ printf("%s%c", a[i][j], j < NF ? ":" : "")
+ print ""
+ @}
+@}
+@end example
+
+The first field in each entry of the password file is the user's login name,
+and the fields are separated by colons.
+Each record defines a subarray,
+with each field as an element in the subarray.
+Running the program produces the
+following output:
+
+@example
+$ @kbd{gawk -v POS=1 -F: -f sort.awk /etc/passwd}
+@print{} adm:x:3:4:adm:/var/adm:/sbin/nologin
+@print{} apache:x:48:48:Apache:/var/www:/sbin/nologin
+@print{} avahi:x:70:70:Avahi daemon:/:/sbin/nologin
+@dots{}
+@end example
+
+The comparison should normally always return the same value when given a
+specific pair of array elements as its arguments. If inconsistent
+results are returned, then the order is undefined. This behavior can be
+exploited to introduce random order into otherwise seemingly
+ordered data:
+
+@example
+function cmp_randomize(i1, v1, i2, v2)
+@{
+ # random order (caution: this may never terminate!)
+ return (2 - 4 * rand())
+@}
+@end example
+
+As already mentioned, the order of the indices is arbitrary if two
+elements compare equal. This is usually not a problem, but letting
+the tied elements come out in arbitrary order can be an issue, especially
+when comparing item values. The partial ordering of the equal elements
+may change the next time the array is traversed, if other elements are added or
+removed from the array. One way to resolve ties when comparing elements
+with otherwise equal values is to include the indices in the comparison
+rules. Note that doing this may make the loop traversal less efficient,
+so consider it only if necessary. The following comparison functions
+force a deterministic order, and are based on the fact that the
+(string) indices of two elements are never equal:
+
+@example
+function cmp_numeric(i1, v1, i2, v2)
+@{
+ # numerical value (and index) comparison, descending order
+ return (v1 != v2) ? (v2 - v1) : (i2 - i1)
+@}
+
+function cmp_string(i1, v1, i2, v2)
+@{
+ # string value (and index) comparison, descending order
+ v1 = v1 i1
+ v2 = v2 i2
+ return (v1 > v2) ? -1 : (v1 != v2)
+@}
+@end example
+
+@c Avoid using the term ``stable'' when describing the unpredictable behavior
+@c if two items compare equal. Usually, the goal of a "stable algorithm"
+@c is to maintain the original order of the items, which is a meaningless
+@c concept for a list constructed from a hash.
+
+A custom comparison function can often simplify ordered loop
+traversal, and the sky is really the limit when it comes to
+designing such a function.
+
+When string comparisons are made during a sort, either for element
+values where one or both aren't numbers, or for element indices
+handled as strings, the value of @code{IGNORECASE}
+(@pxref{Built-in Variables}) controls whether
+the comparisons treat corresponding upper- and lowercase letters as
+equivalent or distinct.
+
+Another point to keep in mind is that in the case of subarrays,
+the element values can themselves be arrays; a production comparison
+function should use the @code{isarray()} function
+(@pxref{Type Functions}),
+to check for this, and choose a defined sorting order for subarrays.
+
+All sorting based on @code{PROCINFO["sorted_in"]}
+is disabled in POSIX mode,
+because the @code{PROCINFO} array is not special in that case.
+
+As a side note, sorting the array indices before traversing
+the array has been reported to add 15% to 20% overhead to the
+execution time of @command{awk} programs. For this reason,
+sorted array traversal is not the default.
+
+@c The @command{gawk}
+@c maintainers believe that only the people who wish to use a
+@c feature should have to pay for it.
+
+@node Array Sorting Functions
+@subsection Sorting Array Values and Indices with @command{gawk}
+
+@cindex arrays, sorting
+@cindexgawkfunc{asort}
+@cindex @code{asort()} function (@command{gawk}), arrays@comma{} sorting
+@cindexgawkfunc{asorti}
+@cindex @code{asorti()} function (@command{gawk}), arrays@comma{} sorting
+@cindex sort function, arrays, sorting
+In most @command{awk} implementations, sorting an array requires writing
+a @code{sort()} function. This can be educational for exploring
+different sorting algorithms, but 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 default comparison is based on the type of the elements
+(@pxref{Typing and Comparison}).
+All numeric values come before all string values,
+which in turn come before all subarrays.
+
+@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, use the
+@code{asorti()} function. The interface and behavior are 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++) @{
+ @ii{Work with sorted indices directly:}
+ @var{do something with} dest[i]
+ @dots{}
+ @ii{Access original array via sorted indices:}
+ @var{do something with} source[dest[i]]
+ @}
+@}
+@end example
+
+So far, so good. Now it starts to get interesting. Both @code{asort()}
+and @code{asorti()} accept a third string argument to control comparison
+of array elements. When we introduced @code{asort()} and @code{asorti()}
+in @ref{String Functions}, we ignored this third argument; however,
+now is the time to describe how this argument affects these two functions.
+
+Basically, the third argument specifies how the array is to be sorted.
+There are two possibilities. As with @code{PROCINFO["sorted_in"]},
+this argument may be one of the predefined names that @command{gawk}
+provides (@pxref{Controlling Scanning}), or it may be the name of a
+user-defined function (@pxref{Controlling Array Traversal}).
+
+In the latter case, @emph{the function can compare elements in any way
+it chooses}, taking into account just the indices, just the values,
+or both. This is extremely powerful.
+
+Once the array is sorted, @code{asort()} takes the @emph{values} in
+their final order, and uses them to fill in the result array, whereas
+@code{asorti()} takes the @emph{indices} in their final order, and uses
+them to fill in the result array.
+
+@cindex reference counting, sorting arrays
+@quotation NOTE
+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.
+@end quotation
+
+@c Document It And Call It A Feature. Sigh.
+@cindex @command{gawk}, @code{IGNORECASE} variable in
+@cindex arrays, sorting, and @code{IGNORECASE} variable
+@cindex @code{IGNORECASE} variable, and array sorting functions
+Because @code{IGNORECASE} affects string comparisons, the value
+of @code{IGNORECASE} also affects sorting for both @code{asort()} and @code{asorti()}.
+Note also that the locale's sorting order does @emph{not}
+come into play; comparisons are based on character values only.@footnote{This
+is true because locale-based comparison occurs only when in
+POSIX-compatibility mode, and because @code{asort()} and @code{asorti()} are
+@command{gawk} extensions, they are not available in that case.}
+
+@node Two-way I/O
+@section Two-Way Communications with Another Process
+
+@c 8/2014. Neither Mike nor BWK saw this as relevant. Commenting it out.
+@ignore
+@cindex Brennan, Michael
+@cindex programmers, attractiveness of
+@smallexample
+@c Path: cssun.mathcs.emory.edu!gatech!newsxfer3.itd.umich.edu!news-peer.sprintlink.net!news-sea-19.sprintlink.net!news-in-west.sprintlink.net!news.sprintlink.net!Sprint!204.94.52.5!news.whidbey.com!brennan
+From: brennan@@whidbey.com (Mike Brennan)
+Newsgroups: comp.lang.awk
+Subject: Re: Learn the SECRET to Attract Women Easily
+Date: 4 Aug 1997 17:34:46 GMT
+@c Organization: WhidbeyNet
+@c Lines: 12
+Message-ID: <5s53rm$eca@@news.whidbey.com>
+@c References: <5s20dn$2e1@chronicle.concentric.net>
+@c Reply-To: brennan@whidbey.com
+@c NNTP-Posting-Host: asn202.whidbey.com
+@c X-Newsreader: slrn (0.9.4.1 UNIX)
+@c Xref: cssun.mathcs.emory.edu comp.lang.awk:5403
+
+On 3 Aug 1997 13:17:43 GMT, Want More Dates???
+<tracy78@@kilgrona.com> wrote:
+>Learn the SECRET to Attract Women Easily
+>
+>The SCENT(tm) Pheromone Sex Attractant For Men to Attract Women
+
+The scent of awk programmers is a lot more attractive to women than
+the scent of perl programmers.
+--
+Mike Brennan
+@c brennan@@whidbey.com
+@end smallexample
+@end ignore
+
+@cindex advanced features, 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.@footnote{Michael
+Brennan suggests the use of @command{rand()} to generate unique
+@value{FN}s. This is a valid point; nevertheless, temporary files
+remain more difficult to use than two-way pipes.} @c 8/2014
+
+@cindex coprocesses
+@cindex input/output, two-way
+@cindex @code{|} (vertical bar), @code{|&} operator (I/O)
+@cindex vertical bar (@code{|}), @code{|&} operator (I/O)
+@cindex @command{csh} utility, @code{|&} operator, comparison with
+However, with @command{gawk}, it is possible to
+open a @emph{two-way} pipe to another process. The second process is
+termed a @dfn{coprocess}, as it runs in parallel with @command{gawk}.
+The two-way connection is created using the @samp{|&} operator
+(borrowed from the Korn shell, @command{ksh}):@footnote{This is very
+different from the same operator in the C shell and in Bash.}
+
+@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 @value{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 coprocess.
+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 coprocess 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}.
+This is not strictly necessary here, but it's good to know how to do this.
+
+@cindex @command{gawk}, @code{PROCINFO} array in
+@cindex @code{PROCINFO} array, and communications via ptys
+You may also 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, save in convenience variable
+PROCINFO[command, "pty"] = 1 # update PROCINFO
+print @dots{} |& command # start two-way pipe
+@dots{}
+@end example
+
+@noindent
+Using ptys usually 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, network programming
+@cindex networks, programming
+@cindex TCP/IP
+@cindex @code{/inet/@dots{}} special files (@command{gawk})
+@cindex files, @code{/inet/@dots{}} (@command{gawk})
+@cindex @code{/inet4/@dots{}} special files (@command{gawk})
+@cindex files, @code{/inet4/@dots{}} (@command{gawk})
+@cindex @code{/inet6/@dots{}} special files (@command{gawk})
+@cindex files, @code{/inet6/@dots{}} (@command{gawk})
+@cindex @code{EMISTERED}
+@ifnotdocbook
+@quotation
+@code{EMRED}:@*
+@ @ @ @ @i{A host is a host from coast to coast,@*
+@ @ @ @ and nobody talks to a host that's close,@*
+@ @ @ @ unless the host that isn't close@*
+@ @ @ @ is busy, hung, or dead.}
+@author Mike O'Brien (aka Mr.@: Protocol)
+@end quotation
+@end ifnotdocbook
+
+@docbook
+<blockquote>
+<attribution>Mike O'Brien (aka Mr.&nbsp;Protocol)</attribution>
+<literallayout class="normal"><literal>EMISTERED</literal>:
+&nbsp;&nbsp;&nbsp;&nbsp;<emphasis>A host is a host from coast to coast,</emphasis>
+&nbsp;&nbsp;&nbsp;&nbsp;<emphasis>and no-one can talk to host that's close,</emphasis>
+&nbsp;&nbsp;&nbsp;&nbsp;<emphasis>unless the host that isn't close</emphasis>
+&nbsp;&nbsp;&nbsp;&nbsp;<emphasis>is busy, hung, or dead.</emphasis></literallayout>
+</blockquote>
+@end docbook
+
+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 network 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 one of @samp{/inet/},
+@samp{/inet4/}, or @samp{/inet6/}.
+
+The full syntax of the special @value{FN} is
+@file{/@var{net-type}/@var{protocol}/@var{local-port}/@var{remote-host}/@var{remote-port}}.
+The components are:
+
+@table @var
+@item net-type
+Specifies the kind of Internet connection to make.
+Use @samp{/inet4/} to force IPv4, and
+@samp{/inet6/} to force IPv6.
+Plain @samp{/inet/} (which used to be the only option) uses
+the system default, most likely IPv4.
+
+@item protocol
+The protocol to use over IP. This must be either @samp{tcp}, or
+@samp{udp}, for a TCP or UDP IP connection,
+respectively. TCP should be used for most applications.
+
+@item local-port
+@cindex @code{getaddrinfo()} 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{getaddrinfo()} 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
+
+@cindex @command{gawk}, @code{ERRNO} variable in
+@cindex @code{ERRNO} variable
+@quotation NOTE
+Failure in opening a two-way socket will result in a non-fatal error
+being returned to the calling code. The value of @code{ERRNO} indicates
+the error (@pxref{Auto-set}).
+@end quotation
+
+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
+See
+@inforef{Top, , General Introduction, gawkinet, TCP/IP Internetworking with @command{gawk}},
+@end ifinfo
+@ifnotinfo
+See
+@uref{http://www.gnu.org/software/gawk/manual/gawkinet/,
+@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 Profiling
+@section Profiling Your @command{awk} Programs
+@cindex @command{awk} programs, profiling
+@cindex profiling @command{awk} programs
+@cindex @code{awkprof.out} file
+@cindex files, @code{awkprof.out}
+
+You may produce execution traces of your @command{awk} programs.
+This is done by passing the option @option{--profile} to @command{gawk}.
+When @command{gawk} 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 @option{--profile} option
+As shown in the following example,
+the @option{--profile} option can be used to change the name of the file
+where @command{gawk} will write the profile:
+
+@example
+gawk --profile=myprog.prof -f myprog.awk data1 data2
+@end example
+
+@noindent
+In the preceding example, @command{gawk} places the profile in
+@file{myprog.prof} instead of in @file{awkprof.out}.
+
+Here is a sample session showing a simple @command{awk} program,
+its input data, and the results from running @command{gawk} with the
+@option{--profile} option. 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 the
+@command{gawk} profiler on this program and data. (This example also
+illustrates that @command{awk} programmers sometimes get up very early
+in the morning to work.)
+
+@cindex @code{BEGIN} pattern, and profiling
+@cindex @code{END} pattern, and profiling
+@example
+ # gawk profile, created Mon Sep 29 05:16:21 2014
+
+ # BEGIN rule(s)
+
+ BEGIN @{
+ 1 print "First BEGIN rule"
+ @}
+
+ BEGIN @{
+ 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 rule(s)
+
+ END @{
+ 1 print "First END rule"
+ @}
+
+ END @{
+ 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 features of profiling output.
+They are as follows:
+
+@itemize @value{BULLET}
+@item
+The program is printed in the order @code{BEGIN} rules,
+@code{BEGINFILE} rules,
+pattern/action rules,
+@code{ENDFILE} rules, @code{END} rules and functions, listed
+alphabetically.
+Multiple @code{BEGIN} and @code{END} rules retain their
+separate identities, as do
+multiple @code{BEGINFILE} and @code{ENDFILE} rules.
+
+@cindex patterns, counts, in a profile
+@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, in a profile
+@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, in a profile
+@cindex user-defined, functions, counts, in a profile
+@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)
+@cindex braces (@code{@{@}})
+@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), in a profile
+@cindex parentheses @code{()}, in a profile
+@item
+Parentheses are used only where needed, as indicated by the structure
+of the program and the precedence rules.
+For example, @samp{(3 + 5) * 4} means add three and five, then multiply
+the total by four. However, @samp{3 + 5 * 4} has no parentheses, and
+means @samp{3 + (5 * 4)}.
+
+@ignore
+@item
+All string concatenations are parenthesized too.
+(This could be made a bit smarter.)
+@end ignore
+
+@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{gawk} supplies leading comments in
+front of the @code{BEGIN} and @code{END} rules,
+the @code{BEGINFILE} and @code{ENDFILE} 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{gawk} creates the
+profiled version by ``pretty printing'' its internal representation of
+the program. The advantage to this is that @command{gawk} can produce
+a standard representation.
+Also, things such as:
+
+@example
+/foo/
+@end example
+
+@noindent
+come out as:
+
+@example
+/foo/ @{
+ print $0
+@}
+@end example
+
+@noindent
+which is correct, but possibly unexpected.
+
+@cindex profiling @command{awk} programs, dynamically
+@cindex @command{gawk} program, dynamic profiling
+@cindex dynamic profiling
+Besides creating profiles when a program has completed,
+@command{gawk} 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{gawk} with the @option{--profile}
+option in the background:
+
+@example
+$ @kbd{gawk --profile -f myprog &}
+[1] 13992
+@end example
+
+@cindex @command{kill} command@comma{} dynamic profiling
+@cindex @code{USR1} signal, for dynamic profiling
+@cindex @code{SIGUSR1} signal, for dynamic profiling
+@cindex signals, @code{USR1}/@code{SIGUSR1}, for profiling
+@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{gawk}:
+
+@example
+$ @kbd{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 one was specified with
+the @option{--profile} option.
+
+Along with the regular profile, as shown earlier, the profile file
+includes a trace of any active functions:
+
+@example
+# Function Call Stack:
+
+# 3. baz
+# 2. bar
+# 1. foo
+# -- main --
+@end example
+
+You may send @command{gawk} 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, for dynamic profiling
+@cindex @code{SIGHUP} signal, for dynamic profiling
+@cindex signals, @code{HUP}/@code{SIGHUP}, for profiling
+If you use the @code{HUP} signal instead of the @code{USR1} signal,
+@command{gawk} produces the profile and the function call trace and then exits.
+
+@cindex @code{INT} signal (MS-Windows)
+@cindex @code{SIGINT} signal (MS-Windows)
+@cindex signals, @code{INT}/@code{SIGINT} (MS-Windows)
+@cindex @code{QUIT} signal (MS-Windows)
+@cindex @code{SIGQUIT} signal (MS-Windows)
+@cindex signals, @code{QUIT}/@code{SIGQUIT} (MS-Windows)
+When @command{gawk} runs on MS-Windows systems, it uses the
+@code{INT} and @code{QUIT} signals for producing the profile and, in
+the case of the @code{INT} signal, @command{gawk} 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{Ctrl-@key{C}} or @kbd{Ctrl-@key{BREAK}} key, while the
+@code{QUIT} signal is generated by the @kbd{Ctrl-@key{\}} key.
+
+Finally, @command{gawk} also accepts another option, @option{--pretty-print}.
+When called this way, @command{gawk} ``pretty prints'' the program into
+@file{awkprof.out}, without any execution counts.
+
+@quotation NOTE
+Once upon a time, the @option{--pretty-print} option would also run
+your program. This is is no longer the case.
+@end quotation
+
+There is a significant difference between the output created when
+profiling, and that created when pretty-printing. Pretty-printed output
+preserves the original comments that were in the program, although their
+placement may not correspond exactly to their original locations in the
+source code.
+
+However, as a deliberate design decision, profiling output @emph{omits}
+the original program's comments. This allows you to focus on the
+execution count data and helps you avoid the temptation to use the
+profiler for pretty-printing.
+
+Additionally, pretty-printed output does not have the leading indentation
+that the profiling output does. This makes it easy to pretty-print your
+code once development is completed, and then use the result as the final
+version of your program.
+
+@node Advanced Features Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+The @option{--non-decimal-data} option causes @command{gawk} to treat
+octal- and hexadecimal-looking input data as octal and hexadecimal.
+This option should be used with caution or not at all; use of @code{strtonum()}
+is preferable.
+Note that this option may disappear in a future version of @command{gawk}.
+
+@item
+You can take over complete control of sorting in @samp{for (@var{indx} in @var{array})}
+array traversal by setting @code{PROCINFO["sorted_in"]} to the name of a user-defined
+function that does the comparison of array elements based on index and value.
+
+@item
+Similarly, you can supply the name of a user-defined comparison function as the
+third argument to either @code{asort()} or @command{asorti()} to control how
+those functions sort arrays. Or you may provide one of the predefined control
+strings that work for @code{PROCINFO["sorted_in"]}.
+
+@item
+You can use the @samp{|&} operator to create a two-way pipe to a coprocess.
+You read from the coprocess with @code{getline} and write to it with @code{print}
+or @code{printf}. Use @code{close()} to close off the coprocess completely, or
+optionally, close off one side of the two-way communications.
+
+@item
+By using special @value{FN}s with the @samp{|&} operator, you can open a
+TCP/IP (or UDP/IP) connection to remote hosts in the Internet. @command{gawk}
+supports both IPv4 and IPv6.
+
+@item
+You can generate statement count profiles of your program. This can help you
+determine which parts of your program may be taking the most time and let
+you tune them more easily. Sending the @code{USR1} signal while profiling causes
+@command{gawk} to dump the profile and keep going, including a function call stack.
+
+@item
+You can also just ``pretty print'' the program. This currently also runs
+the program, but that will change in the next major release.
+
+@end itemize
+
+
+@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.
+
+@cindex internationalization, localization
+@cindex @command{gawk}, internationalization and, See internationalization
+@cindex internationalization, localization, @command{gawk} and
+For many years, 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 forced to write in C or C++ when internationalization is
+a requirement.
+
+@menu
+* I18N and L10N:: Internationalization and Localization.
+* Explaining gettext:: How GNU @command{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.
+* I18N Summary:: Summary of I18N stuff.
+@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 @command{gettext}
+
+@cindex internationalizing a program
+@cindex @command{gettext} library
+@command{gawk} uses GNU @command{gettext} to provide its internationalization
+features.
+The facilities in GNU @command{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 @command{gettext}.
+Therefore, these features are not available
+if you are using one of those operating systems. Sorry.}
+
+@cindex portability, @command{gettext} library and
+When using GNU @command{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 reviews 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
+(@command{"guide"}) to the @command{gettext} library,
+by calling the @code{textdomain()} function.
+
+@cindex @code{.pot} files
+@cindex files, @code{.pot}
+@cindex portable object template files
+@cindex files, portable object template
+@item
+Messages from the application are extracted from the source code and
+collected into a portable object template file (@file{guide.pot}),
+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.pot}
+is copied to a portable object file (@code{.po})
+and translations are created and shipped with the application.
+For example, there might be a @file{fr.po} for a French translation.
+
+@cindex @code{.gmo} files
+@cindex files, @code{.gmo}
+@cindex message object files
+@cindex files, message object
+@item
+Each language's @file{.po} file is converted into a binary
+message object (@file{.gmo}) 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 @command{gettext}
+to use @file{.gmo} files in a different directory than the standard
+one by using the @code{bindtextdomain()} function.
+
+@cindex @code{.gmo} files, specifying directory of
+@cindex files, @code{.gmo}, 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("%s", 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), C macro
+@cindex underscore (@code{_}), C macro
+The GNU @command{gettext} developers, recognizing that typing
+@samp{gettext(@dots{})} 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("%s", _("Don't Panic!\n"));
+@end example
+
+@cindex internationalization, localization, locale categories
+@cindex @command{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 @command{gettext} knows about are:
+
+@table @code
+@cindex @code{LC_MESSAGES} locale category
+@item LC_MESSAGES
+Text messages. This is the default category for @command{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) as well as character encoding.
+@ignore
+In June 2001 Bruno Haible wrote:
+- Description of LC_CTYPE: It determines both
+ 1. character encoding,
+ 2. character type information.
+ (For example, in both KOI8-R and ISO-8859-5 the character type information
+ is the same - cyrillic letters could as 'alpha' - but the encoding is
+ different.)
+@end ignore
+This information is accessed via the
+POSIX character classes in regular expressions,
+such as @code{/[[:alnum:]]/}
+(@pxref{Bracket Expressions}).
+
+@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:
+1,234.56 versus 1.234,56.}
+
+@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 the 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 @command{gettext}.)
+@end table
+
+@node Programmer i18n
+@section Internationalizing @command{awk} Programs
+@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 @command{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.
+
+@cindexgawkfunc{dcgettext}
+@item @code{dcgettext(@var{string}} [@code{,} @var{domain} [@code{,} @var{category}]]@code{)}
+Return 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.
+
+@quotation 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.
+@end quotation
+
+@cindexgawkfunc{dcngettext}
+@item @code{dcngettext(@var{string1}, @var{string2}, @var{number}} [@code{,} @var{domain} [@code{,} @var{category}]]@code{)}
+Return 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} is 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 about argument order as for the @code{dcgettext()} function apply.
+
+@cindex @code{.gmo} files, specifying directory of
+@cindex files, @code{.gmo}, specifying directory of
+@cindex message object files, specifying directory of
+@cindex files, message object, specifying directory of
+@cindexgawkfunc{bindtextdomain}
+@item @code{bindtextdomain(@var{directory}} [@code{,} @var{domain} ]@code{)}
+Change the directory in which
+@command{gettext} looks for @file{.gmo} files, in case they
+will not or cannot be placed in the standard locations
+(e.g., during testing).
+Return 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:@footnote{Thanks to Bruno Haible for this
+example.}
+
+@example
+if (groggy)
+ message = dcgettext("%d customers disturbing me\n", "adminprog")
+else
+ message = dcgettext("enjoying %d customers\n", "adminprog")
+printf(message, ncustomers)
+@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.
+
+The previous example only works if @code{ncustomers} is greater than one.
+This example would be better done with @code{dcngettext()}:
+
+@example
+if (groggy)
+ message = dcngettext("%d customer disturbing me\n",
+ "%d customers disturbing me\n", "adminprog")
+else
+ message = dcngettext("enjoying %d customer\n",
+ "enjoying %d customers\n", "adminprog")
+printf(message, ncustomers)
+@end example
+
+
+@cindex @code{LC_MESSAGES} locale category, @code{bindtextdomain()} function (@command{gawk})
+@item
+During development, you might want to put the @file{.gmo}
+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
+
+@DBXREF{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{.pot} 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-pot} 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 @option{--gen-pot} option
+@cindex command-line options, string extraction
+@cindex string extraction (internationalization)
+@cindex marked string extraction (internationalization)
+@cindex extraction, of marked strings (internationalization)
+
+@cindex @option{--gen-pot} 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-pot} command-line option to create
+the initial @file{.pot} file:
+
+@example
+gawk --gen-pot -f guide.awk > guide.pot
+@end example
+
+@cindex @code{xgettext} utility
+When run with @option{--gen-pot}, @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 @command{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{The
+@command{xgettext} utility that comes with GNU
+@command{gettext} can handle @file{.awk} files.}
+You should distribute the generated @file{.pot} file with
+your @command{awk} program; translators will eventually use it
+to provide you translations that you can also then distribute.
+@DBXREF{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, @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 @command{gettext} manual.}
+
+@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 specifiers 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
+$ @kbd{gawk 'BEGIN @{}
+> @kbd{string = "Don\47t Panic"}
+> @kbd{printf "%2$d characters live in \"%1$s\"\n",}
+> @kbd{string, length(string)}
+> @kbd{@}'}
+@print{} 11 characters live in "Don't 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
+$ @kbd{gawk 'BEGIN @{}
+> @kbd{printf("%*.*s\n", 10, 20, "hello")}
+> @kbd{printf("%3$*2$.*1$s\n", 20, 10, "hello")}
+> @kbd{@}'}
+@print{} hello
+@print{} hello
+@end example
+
+@quotation NOTE
+When using @samp{*} with a positional specifier, the @samp{*}
+comes first, then the integer position, and then the @samp{$}.
+This is somewhat counterintuitive.
+@end quotation
+
+@cindex @code{printf} statement, positional specifiers, mixing with regular formats
+@cindex positional specifiers, @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:
+
+@example
+$ @kbd{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 example
+
+@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 @value{BULLET}
+@cindex @code{TEXTDOMAIN} variable, portability and
+@item
+Assignments to @code{TEXTDOMAIN} won't have any effect,
+because @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, because the positional specifications are primarily for use in
+@emph{translated} format strings, and because non-GNU @command{awk}s never
+retrieve the translated string, this should not be a problem in practice.
+@end itemize
+
+@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-pot} to create the @file{.pot} file:
+
+@example
+$ @kbd{gawk --gen-pot -f guide.awk > guide.pot}
+@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 template 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.pot} 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
+$ @kbd{cp guide.pot 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.
+We pretend that our file is to be used in the @code{en_US.UTF-8} locale,
+because we have to use a locale name known to the C @command{gettext} routines.
+The directory layout shown here is standard for GNU @command{gettext} on
+GNU/Linux systems. Other versions of @command{gettext} may use a different
+layout:
+
+@example
+$ @kbd{mkdir en_US.UTF-8 en_US.UTF-8/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 (using
+the @option{-o} option) so that @command{gawk} can find it:
+
+@example
+$ @kbd{msgfmt guide-mellow.po -o en_US.UTF-8/LC_MESSAGES/guide.mo}
+@end example
+
+Finally, we run the program to test it:
+
+@example
+$ @kbd{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
+$ @kbd{gawk --posix -f guide.awk -f libintl.awk}
+@print{} Don't Panic
+@print{} The Answer Is 42
+@print{} Pardon me, Zaphod who?
+@end example
+
+@node Gawk I18N
+@section @command{gawk} Can Speak Your Language
+
+@command{gawk} itself has been internationalized
+using the GNU @command{gettext} package.
+(GNU @command{gettext} is described in
+complete detail in
+@ifinfo
+@inforef{Top, , GNU @command{gettext} utilities, gettext, GNU gettext tools}.)
+@end ifinfo
+@ifnotinfo
+@uref{http://www.gnu.org/software/gettext/manual/,
+@cite{GNU gettext tools}}.)
+@end ifnotinfo
+As of this writing, the latest version of GNU @command{gettext} is
+@uref{ftp://ftp.gnu.org/gnu/gettext/gettext-0.19.4.tar.gz,
+@value{PVERSION} 0.19.4}.
+
+If a translation of @command{gawk}'s messages exists,
+then @command{gawk} produces usage messages, warnings,
+and fatal errors in the local language.
+
+@node I18N Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+Internationalization means writing a program such that it can use multiple
+languages without requiring source-code changes. Localization means
+providing the data necessary for an internationalized program to work
+in a particular language.
+
+@item
+@command{gawk} uses GNU @command{gettext} to let you internationalize
+and localize @command{awk} programs. A program's text domain identifies
+the program for grouping all messages and other data together.
+
+@item
+You mark a program's strings for translation by preceding them with
+an underscore. Once that is done, the strings are extracted into a
+@file{.pot} file. This file is copied for each language into a @file{.po}
+file, and the @file{.po} files are compiled into @file{.gmo} files for
+use at runtime.
+
+@item
+You can use position specifications with @code{sprintf()} and
+@code{printf} to rearrange the placement of argument values in formatted
+strings and output. This is useful for the translations of format
+control strings.
+
+@item
+The internationalization features have been designed so that they
+can be easily worked around in a standard @command{awk}.
+
+@item
+@command{gawk} itself has been internationalized and ships with
+a number of translations for its messages.
+
+@end itemize
+
+
+@node Debugger
+@chapter Debugging @command{awk} Programs
+@cindex debugging @command{awk} programs
+
+@c The original text for this chapter was contributed by Efraim Yawitz.
+@c FIXME: Add more indexing.
+
+It would be nice if computer programs worked perfectly the first time they
+were run, but in real life, this rarely happens for programs of
+any complexity. Thus, most programming languages have facilities available
+for ``debugging'' programs, and now @command{awk} is no exception.
+
+The @command{gawk} debugger is purposely modeled after
+@uref{http://www.gnu.org/software/gdb/, the GNU Debugger (GDB)}
+command-line debugger. If you are familiar with GDB, learning
+how to use @command{gawk} for debugging your program is easy.
+
+@menu
+* Debugging:: Introduction to @command{gawk} debugger.
+* Sample Debugging Session:: Sample debugging session.
+* List of Debugger Commands:: Main debugger commands.
+* Readline Support:: Readline support.
+* Limitations:: Limitations and future plans.
+* Debugging Summary:: Debugging summary.
+@end menu
+
+@node Debugging
+@section Introduction to the @command{gawk} Debugger
+
+This @value{SECTION} introduces debugging in general and begins
+the discussion of debugging in @command{gawk}.
+
+@menu
+* Debugging Concepts:: Debugging in General.
+* Debugging Terms:: Additional Debugging Concepts.
+* Awk Debugging:: Awk Debugging.
+@end menu
+
+@node Debugging Concepts
+@subsection Debugging in General
+
+(If you have used debuggers in other languages, you may want to skip
+ahead to the next section on the specific features of the @command{gawk}
+debugger.)
+
+Of course, a debugging program cannot remove bugs for you, because it has
+no way of knowing what you or your users consider a ``bug'' versus a
+``feature.'' (Sometimes, we humans have a hard time with this ourselves.)
+In that case, what can you expect from such a tool? The answer to that
+depends on the language being debugged, but in general, you can expect at
+least the following:
+
+@itemize @value{BULLET}
+@item
+The ability to watch a program execute its instructions one by one,
+giving you, the programmer, the opportunity to think about what is happening
+on a time scale of seconds, minutes, or hours, rather than the nanosecond
+time scale at which the code usually runs.
+
+@item
+The opportunity to not only passively observe the operation of your
+program, but to control it and try different paths of execution, without
+having to change your source files.
+
+@item
+The chance to see the values of data in the program at any point in
+execution, and also to change that data on the fly, to see how that
+affects what happens afterward. (This often includes the ability
+to look at internal data structures besides the variables you actually
+defined in your code.)
+
+@item
+The ability to obtain additional information about your program's state
+or even its internal structure.
+@end itemize
+
+All of these tools provide a great amount of help in using your own
+skills and understanding of the goals of your program to find where it
+is going wrong (or, for that matter, to better comprehend a perfectly
+functional program that you or someone else wrote).
+
+@node Debugging Terms
+@subsection Debugging Concepts
+
+Before diving in to the details, we need to introduce several
+important concepts that apply to just about all debuggers.
+The following list defines terms used throughout the rest of
+this @value{CHAPTER}:
+
+@table @dfn
+@cindex stack frame
+@item Stack frame
+Programs generally call functions during the course of their execution.
+One function can call another, or a function can call itself (recursion).
+You can view the chain of called functions (main program calls A, which
+calls B, which calls C), as a stack of executing functions: the currently
+running function is the topmost one on the stack, and when it finishes
+(returns), the next one down then becomes the active function.
+Such a stack is termed a @dfn{call stack}.
+
+For each function on the call stack, the system maintains a data area
+that contains the function's parameters, local variables, and return value,
+as well as any other ``bookkeeping'' information needed to manage the
+call stack. This data area is termed a @dfn{stack frame}.
+
+@command{gawk} also follows this model, and gives you
+access to the call stack and to each stack frame. You can see the
+call stack, as well as from where each function on the stack was
+invoked. Commands that print the call stack print information about
+each stack frame (as detailed later on).
+
+@item Breakpoint
+@cindex breakpoint
+During debugging, you often wish to let the program run until it
+reaches a certain point, and then continue execution from there one
+statement (or instruction) at a time. The way to do this is to set
+a @dfn{breakpoint} within the program. A breakpoint is where the
+execution of the program should break off (stop), so that you can
+take over control of the program's execution. You can add and remove
+as many breakpoints as you like.
+
+@item Watchpoint
+@cindex watchpoint
+A watchpoint is similar to a breakpoint. The difference is that
+breakpoints are oriented around the code: stop when a certain point in the
+code is reached. A watchpoint, however, specifies that program execution
+should stop when a @emph{data value} is changed. This is useful, as
+sometimes it happens that a variable receives an erroneous value, and it's
+hard to track down where this happens just by looking at the code.
+By using a watchpoint, you can stop whenever a variable is assigned to,
+and usually find the errant code quite quickly.
+@end table
+
+@node Awk Debugging
+@subsection Awk Debugging
+
+Debugging an @command{awk} program has some specific aspects that are
+not shared with other programming languages.
+
+First of all, the fact that @command{awk} programs usually take input
+line by line from a file or files and operate on those lines using specific
+rules makes it especially useful to organize viewing the execution of
+the program in terms of these rules. As we will see, each @command{awk}
+rule is treated almost like a function call, with its own specific block
+of instructions.
+
+In addition, because @command{awk} is by design a very concise language,
+it is easy to lose sight of everything that is going on ``inside''
+each line of @command{awk} code. The debugger provides the opportunity
+to look at the individual primitive instructions carried out
+by the higher-level @command{awk} commands.
+
+@node Sample Debugging Session
+@section Sample Debugging Session
+@cindex sample debugging session
+
+In order to illustrate the use of @command{gawk} as a debugger, let's look at a sample
+debugging session. We will use the @command{awk} implementation of the
+POSIX @command{uniq} command described earlier (@pxref{Uniq Program})
+as our example.
+
+@menu
+* Debugger Invocation:: How to Start the Debugger.
+* Finding The Bug:: Finding the Bug.
+@end menu
+
+@node Debugger Invocation
+@subsection How to Start the Debugger
+@cindex starting the debugger
+@cindex debugger, how to start
+
+Starting the debugger is almost exactly like running @command{gawk} normally,
+except you have to pass an additional option @option{--debug}, or the
+corresponding short option @option{-D}. The file(s) containing the
+program and any supporting code are given on the command line as arguments
+to one or more @option{-f} options. (@command{gawk} is not designed
+to debug command-line programs, only programs contained in files.)
+In our case, we invoke the debugger like this:
+
+@example
+$ @kbd{gawk -D -f getopt.awk -f join.awk -f uniq.awk -1 inputfile}
+@end example
+
+@noindent
+where both @file{getopt.awk} and @file{uniq.awk} are in @env{$AWKPATH}.
+(Experienced users of GDB or similar debuggers should note that
+this syntax is slightly different from what they are used to.
+With the @command{gawk} debugger, you give the arguments for running the program
+in the command line to the debugger rather than as part of the @code{run}
+command at the debugger prompt.)
+The @option{-1} is an option to @file{uniq.awk}.
+
+Instead of immediately running the program on @file{inputfile}, as
+@command{gawk} would ordinarily do, the debugger merely loads all
+the program source files, compiles them internally, and then gives
+us a prompt:
+
+@example
+gawk>
+@end example
+
+@noindent
+from which we can issue commands to the debugger. At this point, no
+code has been executed.
+
+@node Finding The Bug
+@subsection Finding the Bug
+
+Let's say that we are having a problem using (a faulty version of)
+@file{uniq.awk} in the ``field-skipping'' mode, and it doesn't seem to be
+catching lines which should be identical when skipping the first field,
+such as:
+
+@example
+awk is a wonderful program!
+gawk is a wonderful program!
+@end example
+
+This could happen if we were thinking (C-like) of the fields in a record
+as being numbered in a zero-based fashion, so instead of the lines:
+
+@example
+clast = join(alast, fcount+1, n)
+cline = join(aline, fcount+1, m)
+@end example
+
+@noindent
+we wrote:
+
+@example
+clast = join(alast, fcount, n)
+cline = join(aline, fcount, m)
+@end example
+
+The first thing we usually want to do when trying to investigate a
+problem like this is to put a breakpoint in the program so that we can
+watch it at work and catch what it is doing wrong. A reasonable spot for
+a breakpoint in @file{uniq.awk} is at the beginning of the function
+@code{are_equal()}, which compares the current line with the previous one. To set
+the breakpoint, use the @code{b} (breakpoint) command:
+
+@example
+gawk> @kbd{b are_equal}
+@print{} Breakpoint 1 set at file `awklib/eg/prog/uniq.awk', line 63
+@end example
+
+The debugger tells us the file and line number where the breakpoint is.
+Now type @samp{r} or @samp{run} and the program runs until it hits
+the breakpoint for the first time:
+
+@example
+gawk> @kbd{r}
+@print{} Starting program:
+@print{} Stopping in Rule ...
+@print{} Breakpoint 1, are_equal(n, m, clast, cline, alast, aline)
+ at `awklib/eg/prog/uniq.awk':63
+@print{} 63 if (fcount == 0 && charcount == 0)
+gawk>
+@end example
+
+Now we can look at what's going on inside our program. First of all,
+let's see how we got to where we are. At the prompt, we type @samp{bt}
+(short for ``backtrace''), and the debugger responds with a
+listing of the current stack frames:
+
+@example
+gawk> @kbd{bt}
+@print{} #0 are_equal(n, m, clast, cline, alast, aline)
+ at `awklib/eg/prog/uniq.awk':68
+@print{} #1 in main() at `awklib/eg/prog/uniq.awk':88
+@end example
+
+This tells us that @code{are_equal()} was called by the main program at
+line 88 of @file{uniq.awk}. (This is not a big surprise, because this
+is the only call to @code{are_equal()} in the program, but in more complex
+programs, knowing who called a function and with what parameters can be
+the key to finding the source of the problem.)
+
+Now that we're in @code{are_equal()}, we can start looking at the values
+of some variables. Let's say we type @samp{p n}
+(@code{p} is short for ``print''). We would expect to see the value of
+@code{n}, a parameter to @code{are_equal()}. Actually, the debugger
+gives us:
+
+@example
+gawk> @kbd{p n}
+@print{} n = untyped variable
+@end example
+
+@noindent
+In this case, @code{n} is an uninitialized local variable, because the
+function was called without arguments (@pxref{Function Calls}).
+
+A more useful variable to display might be the current record:
+
+@example
+gawk> @kbd{p $0}
+@print{} $0 = "gawk is a wonderful program!"
+@end example
+
+@noindent
+This might be a bit puzzling at first, as this is the second line of
+our test input. Let's look at @code{NR}:
+
+@example
+gawk> @kbd{p NR}
+@print{} NR = 2
+@end example
+
+@noindent
+So we can see that @code{are_equal()} was only called for the second record
+of the file. Of course, this is because our program contains a rule for
+@samp{NR == 1}:
+
+@example
+NR == 1 @{
+ last = $0
+ next
+@}
+@end example
+
+OK, let's just check that that rule worked correctly:
+
+@example
+gawk> @kbd{p last}
+@print{} last = "awk is a wonderful program!"
+@end example
+
+Everything we have done so far has verified that the program has worked as
+planned, up to and including the call to @code{are_equal()}, so the problem must
+be inside this function. To investigate further, we must begin
+``stepping through'' the lines of @code{are_equal()}. We start by typing
+@samp{n} (for ``next''):
+
+@example
+gawk> @kbd{n}
+@print{} 66 if (fcount > 0) @{
+@end example
+
+This tells us that @command{gawk} is now ready to execute line 66, which
+decides whether to give the lines the special ``field skipping'' treatment
+indicated by the @option{-1} command-line option. (Notice that we skipped
+from where we were before at line 63 to here, because the condition in line 63
+@samp{if (fcount == 0 && charcount == 0)} was false.)
+
+Continuing to step, we now get to the splitting of the current and
+last records:
+
+@example
+gawk> @kbd{n}
+@print{} 67 n = split(last, alast)
+gawk> @kbd{n}
+@print{} 68 m = split($0, aline)
+@end example
+
+At this point, we should be curious to see what our records were split
+into, so we try to look:
+
+@example
+gawk> @kbd{p n m alast aline}
+@print{} n = 5
+@print{} m = untyped variable
+@print{} alast = array, 5 elements
+@print{} aline = untyped variable
+@end example
+
+@noindent
+(The @code{p} command can take more than one argument, similar to
+@command{awk}'s @code{print} statement.)
+
+This is kind of disappointing, though. All we found out is that there
+are five elements in @code{alast}; @code{m} and @code{aline} don't have
+values because we are at line 68 but haven't executed it yet.
+This information is useful enough (we now know that
+none of the words were accidentally left out), but what if we want to see
+inside the array?
+
+The first choice would be to use subscripts:
+
+@example
+gawk> @kbd{p alast[0]}
+@print{} "0" not in array `alast'
+@end example
+
+@noindent
+Oops!
+
+@example
+gawk> @kbd{p alast[1]}
+@print{} alast["1"] = "awk"
+@end example
+
+This would be kind of slow for a 100-member array, though, so
+@command{gawk} provides a shortcut (reminiscent of another language
+not to be mentioned):
+
+@example
+gawk> @kbd{p @@alast}
+@print{} alast["1"] = "awk"
+@print{} alast["2"] = "is"
+@print{} alast["3"] = "a"
+@print{} alast["4"] = "wonderful"
+@print{} alast["5"] = "program!"
+@end example
+
+It looks like we got this far OK. Let's take another step
+or two:
+
+@example
+gawk> @kbd{n}
+@print{} 69 clast = join(alast, fcount, n)
+gawk> @kbd{n}
+@print{} 70 cline = join(aline, fcount, m)
+@end example
+
+Well, here we are at our error (sorry to spoil the suspense). What we
+had in mind was to join the fields starting from the second one to make
+the virtual record to compare, and if the first field was numbered zero,
+this would work. Let's look at what we've got:
+
+@example
+gawk> @kbd{p cline clast}
+@print{} cline = "gawk is a wonderful program!"
+@print{} clast = "awk is a wonderful program!"
+@end example
+
+Hey, those look pretty familiar! They're just our original, unaltered,
+input records. A little thinking (the human brain is still the best
+debugging tool), and we realize that we were off by one!
+
+We get out of the debugger:
+
+@example
+gawk> @kbd{q}
+@print{} The program is running. Exit anyway (y/n)? @kbd{y}
+@end example
+
+@noindent
+Then we get into an editor:
+
+@example
+clast = join(alast, fcount+1, n)
+cline = join(aline, fcount+1, m)
+@end example
+
+@noindent
+and problem solved!
+
+@node List of Debugger Commands
+@section Main Debugger Commands
+
+The @command{gawk} debugger command set can be divided into the
+following categories:
+
+@itemize @value{BULLET}
+
+@item
+Breakpoint control
+
+@item
+Execution control
+
+@item
+Viewing and changing data
+
+@item
+Working with the stack
+
+@item
+Getting information
+
+@item
+Miscellaneous
+@end itemize
+
+Each of these are discussed in the following subsections.
+In the following descriptions, commands which may be abbreviated
+show the abbreviation on a second description line.
+A debugger command name may also be truncated if that partial
+name is unambiguous. The debugger has the built-in capability to
+automatically repeat the previous command just by hitting @key{Enter}.
+This works for the commands @code{list}, @code{next}, @code{nexti},
+@code{step}, @code{stepi}, and @code{continue} executed without any
+argument.
+
+@menu
+* Breakpoint Control:: Control of Breakpoints.
+* Debugger Execution Control:: Control of Execution.
+* Viewing And Changing Data:: Viewing and Changing Data.
+* Execution Stack:: Dealing with the Stack.
+* Debugger Info:: Obtaining Information about the Program and
+ the Debugger State.
+* Miscellaneous Debugger Commands:: Miscellaneous Commands.
+@end menu
+
+@node Breakpoint Control
+@subsection Control of Breakpoints
+
+As we saw earlier, the first thing you probably want to do in a debugging
+session is to get your breakpoints set up, because your program
+will otherwise just run as if it was not under the debugger. The commands for
+controlling breakpoints are:
+
+@table @asis
+@cindex debugger commands, @code{b} (@code{break})
+@cindex debugger commands, @code{break}
+@cindex @code{break} debugger command
+@cindex @code{b} debugger command (alias for @code{break})
+@cindex set breakpoint
+@cindex breakpoint, setting
+@item @code{break} [[@var{filename}@code{:}]@var{n} | @var{function}] [@code{"@var{expression}"}]
+@itemx @code{b} [[@var{filename}@code{:}]@var{n} | @var{function}] [@code{"@var{expression}"}]
+Without any argument, set a breakpoint at the next instruction
+to be executed in the selected stack frame.
+Arguments can be one of the following:
+
+@c @asis for docbook
+@c nested table
+@table @asis
+@item @var{n}
+Set a breakpoint at line number @var{n} in the current source file.
+
+@item @var{filename}@code{:}@var{n}
+Set a breakpoint at line number @var{n} in source file @var{filename}.
+
+@item @var{function}
+Set a breakpoint at entry to (the first instruction of)
+function @var{function}.
+@end table
+
+Each breakpoint is assigned a number which can be used to delete it from
+the breakpoint list using the @code{delete} command.
+
+With a breakpoint, you may also supply a condition. This is an
+@command{awk} expression (enclosed in double quotes) that the debugger
+evaluates whenever the breakpoint is reached. If the condition is true,
+then the debugger stops execution and prompts for a command. Otherwise,
+it continues executing the program.
+
+@cindex debugger commands, @code{clear}
+@cindex @code{clear} debugger command
+@cindex delete breakpoint at location
+@cindex breakpoint at location, how to delete
+@item @code{clear} [[@var{filename}@code{:}]@var{n} | @var{function}]
+Without any argument, delete any breakpoint at the next instruction
+to be executed in the selected stack frame. If the program stops at
+a breakpoint, this deletes that breakpoint so that the program
+does not stop at that location again. Arguments can be one of the following:
+
+@c nested table
+@table @asis
+@item @var{n}
+Delete breakpoint(s) set at line number @var{n} in the current source file.
+
+@item @var{filename}@code{:}@var{n}
+Delete breakpoint(s) set at line number @var{n} in source file @var{filename}.
+
+@item @var{function}
+Delete breakpoint(s) set at entry to function @var{function}.
+@end table
+
+@cindex debugger commands, @code{condition}
+@cindex @code{condition} debugger command
+@cindex breakpoint condition
+@item @code{condition} @var{n} @code{"@var{expression}"}
+Add a condition to existing breakpoint or watchpoint @var{n}. The
+condition is an @command{awk} expression @emph{enclosed in double quotes}
+that the debugger evaluates
+whenever the breakpoint or watchpoint is reached. If the condition is true, then
+the debugger stops execution and prompts for a command. Otherwise,
+the debugger continues executing the program. If the condition expression is
+not specified, any existing condition is removed (i.e., the breakpoint or
+watchpoint is made unconditional).
+
+@cindex debugger commands, @code{d} (@code{delete})
+@cindex debugger commands, @code{delete}
+@cindex @code{delete} debugger command
+@cindex @code{d} debugger command (alias for @code{delete})
+@cindex delete breakpoint by number
+@cindex breakpoint, delete by number
+@item @code{delete} [@var{n1 n2} @dots{}] [@var{n}--@var{m}]
+@itemx @code{d} [@var{n1 n2} @dots{}] [@var{n}--@var{m}]
+Delete specified breakpoints or a range of breakpoints. Deletes
+all defined breakpoints if no argument is supplied.
+
+@cindex debugger commands, @code{disable}
+@cindex @code{disable} debugger command
+@cindex disable breakpoint
+@cindex breakpoint, how to disable or enable
+@item @code{disable} [@var{n1 n2} @dots{} | @var{n}--@var{m}]
+Disable specified breakpoints or a range of breakpoints. Without
+any argument, disables all breakpoints.
+
+@cindex debugger commands, @code{e} (@code{enable})
+@cindex debugger commands, @code{enable}
+@cindex @code{enable} debugger command
+@cindex @code{e} debugger command (alias for @code{enable})
+@cindex enable breakpoint
+@item @code{enable} [@code{del} | @code{once}] [@var{n1 n2} @dots{}] [@var{n}--@var{m}]
+@itemx @code{e} [@code{del} | @code{once}] [@var{n1 n2} @dots{}] [@var{n}--@var{m}]
+Enable specified breakpoints or a range of breakpoints. Without
+any argument, enables all breakpoints.
+Optionally, you can specify how to enable the breakpoint:
+
+@c nested table
+@table @code
+@item del
+Enable the breakpoint(s) temporarily, then delete it when
+the program stops at the breakpoint.
+
+@item once
+Enable the breakpoint(s) temporarily, then disable it when
+the program stops at the breakpoint.
+@end table
+
+@cindex debugger commands, @code{ignore}
+@cindex @code{ignore} debugger command
+@cindex ignore breakpoint
+@item @code{ignore} @var{n} @var{count}
+Ignore breakpoint number @var{n} the next @var{count} times it is
+hit.
+
+@cindex debugger commands, @code{t} (@code{tbreak})
+@cindex debugger commands, @code{tbreak}
+@cindex @code{tbreak} debugger command
+@cindex @code{t} debugger command (alias for @code{tbreak})
+@cindex temporary breakpoint
+@item @code{tbreak} [[@var{filename}@code{:}]@var{n} | @var{function}]
+@itemx @code{t} [[@var{filename}@code{:}]@var{n} | @var{function}]
+Set a temporary breakpoint (enabled for only one stop).
+The arguments are the same as for @code{break}.
+@end table
+
+@node Debugger Execution Control
+@subsection Control of Execution
+
+Now that your breakpoints are ready, you can start running the program
+and observing its behavior. There are more commands for controlling
+execution of the program than we saw in our earlier example:
+
+@table @asis
+@cindex debugger commands, @code{commands}
+@cindex @code{commands} debugger command
+@cindex debugger commands, @code{silent}
+@cindex @code{silent} debugger command
+@cindex debugger commands, @code{end}
+@cindex @code{end} debugger command
+@cindex breakpoint commands
+@cindex commands to execute at breakpoint
+@item @code{commands} [@var{n}]
+@itemx @code{silent}
+@itemx @dots{}
+@itemx @code{end}
+Set a list of commands to be executed upon stopping at
+a breakpoint or watchpoint. @var{n} is the breakpoint or watchpoint number.
+Without a number, the last one set is used. The actual commands follow,
+starting on the next line, and terminated by the @code{end} command.
+If the command @code{silent} is in the list, the usual messages about
+stopping at a breakpoint and the source line are not printed. Any command
+in the list that resumes execution (e.g., @code{continue}) terminates the list
+(an implicit @code{end}), and subsequent commands are ignored.
+For example:
+
+@example
+gawk> @kbd{commands}
+> @kbd{silent}
+> @kbd{printf "A silent breakpoint; i = %d\n", i}
+> @kbd{info locals}
+> @kbd{set i = 10}
+> @kbd{continue}
+> @kbd{end}
+gawk>
+@end example
+
+@cindex debugger commands, @code{c} (@code{continue})
+@cindex debugger commands, @code{continue}
+@cindex continue program, in debugger
+@item @code{continue} [@var{count}]
+@itemx @code{c} [@var{count}]
+Resume program execution. If continued from a breakpoint and @var{count} is
+specified, ignores the breakpoint at that location the next @var{count} times
+before stopping.
+
+@cindex debugger commands, @code{finish}
+@cindex @code{finish} debugger command
+@item @code{finish}
+Execute until the selected stack frame returns.
+Print the returned value.
+
+@cindex debugger commands, @code{n} (@code{next})
+@cindex debugger commands, @code{next}
+@cindex @code{next} debugger command
+@cindex @code{n} debugger command (alias for @code{next})
+@cindex single-step execution, in the debugger
+@item @code{next} [@var{count}]
+@itemx @code{n} [@var{count}]
+Continue execution to the next source line, stepping over function calls.
+The argument @var{count} controls how many times to repeat the action, as
+in @code{step}.
+
+@cindex debugger commands, @code{ni} (@code{nexti})
+@cindex debugger commands, @code{nexti}
+@cindex @code{nexti} debugger command
+@cindex @code{ni} debugger command (alias for @code{nexti})
+@item @code{nexti} [@var{count}]
+@itemx @code{ni} [@var{count}]
+Execute one (or @var{count}) instruction(s), stepping over function calls.
+
+@cindex debugger commands, @code{return}
+@cindex @code{return} debugger command
+@item @code{return} [@var{value}]
+Cancel execution of a function call. If @var{value} (either a string or a
+number) is specified, it is used as the function's return value. If used in a
+frame other than the innermost one (the currently executing function; i.e.,
+frame number 0), discard all inner frames in addition to the selected one,
+and the caller of that frame becomes the innermost frame.
+
+@cindex debugger commands, @code{r} (@code{run})
+@cindex debugger commands, @code{run}
+@cindex @code{run} debugger command
+@cindex @code{r} debugger command (alias for @code{run})
+@item @code{run}
+@itemx @code{r}
+Start/restart execution of the program. When restarting, the debugger
+retains the current breakpoints, watchpoints, command history,
+automatic display variables, and debugger options.
+
+@cindex debugger commands, @code{s} (@code{step})
+@cindex debugger commands, @code{step}
+@cindex @code{step} debugger command
+@cindex @code{s} debugger command (alias for @code{step})
+@item @code{step} [@var{count}]
+@itemx @code{s} [@var{count}]
+Continue execution until control reaches a different source line in the
+current stack frame. @code{step} steps inside any function called within
+the line. If the argument @var{count} is supplied, steps that many times before
+stopping, unless it encounters a breakpoint or watchpoint.
+
+@cindex debugger commands, @code{si} (@code{stepi})
+@cindex debugger commands, @code{stepi}
+@cindex @code{stepi} debugger command
+@cindex @code{si} debugger command (alias for @code{stepi})
+@item @code{stepi} [@var{count}]
+@itemx @code{si} [@var{count}]
+Execute one (or @var{count}) instruction(s), stepping inside function calls.
+(For illustration of what is meant by an ``instruction'' in @command{gawk},
+see the output shown under @code{dump} in @ref{Miscellaneous Debugger Commands}.)
+
+@cindex debugger commands, @code{u} (@code{until})
+@cindex debugger commands, @code{until}
+@cindex @code{until} debugger command
+@cindex @code{u} debugger command (alias for @code{until})
+@item @code{until} [[@var{filename}@code{:}]@var{n} | @var{function}]
+@itemx @code{u} [[@var{filename}@code{:}]@var{n} | @var{function}]
+Without any argument, continue execution until a line past the current
+line in the current stack frame is reached. With an argument,
+continue execution until the specified location is reached, or the current
+stack frame returns.
+@end table
+
+@node Viewing And Changing Data
+@subsection Viewing and Changing Data
+
+The commands for viewing and changing variables inside of @command{gawk} are:
+
+@table @asis
+@cindex debugger commands, @code{display}
+@cindex @code{display} debugger command
+@item @code{display} [@var{var} | @code{$}@var{n}]
+Add variable @var{var} (or field @code{$@var{n}}) to the display list.
+The value of the variable or field is displayed each time the program stops.
+Each variable added to the list is identified by a unique number:
+
+@example
+gawk> @kbd{display x}
+@print{} 10: x = 1
+@end example
+
+@noindent
+This displays the assigned item number, the variable name, and its current value.
+If the display variable refers to a function parameter, it is silently
+deleted from the list as soon as the execution reaches a context where
+no such variable of the given name exists.
+Without argument, @code{display} displays the current values of
+items on the list.
+
+@cindex debugger commands, @code{eval}
+@cindex @code{eval} debugger command
+@cindex evaluate expressions, in debugger
+@item @code{eval "@var{awk statements}"}
+Evaluate @var{awk statements} in the context of the running program.
+You can do anything that an @command{awk} program would do: assign
+values to variables, call functions, and so on.
+
+@item @code{eval} @var{param}, @dots{}
+@itemx @var{awk statements}
+@itemx @code{end}
+This form of @code{eval} is similar, but it allows you to define
+``local variables'' that exist in the context of the
+@var{awk statements}, instead of using variables or function
+parameters defined by the program.
+
+@cindex debugger commands, @code{p} (@code{print})
+@cindex debugger commands, @code{print}
+@cindex @code{print} debugger command
+@cindex @code{p} debugger command (alias for @code{print})
+@cindex print variables, in debugger
+@item @code{print} @var{var1}[@code{,} @var{var2} @dots{}]
+@itemx @code{p} @var{var1}[@code{,} @var{var2} @dots{}]
+Print the value of a @command{gawk} variable or field.
+Fields must be referenced by constants:
+
+@example
+gawk> @kbd{print $3}
+@end example
+
+@noindent
+This prints the third field in the input record (if the specified field does not
+exist, it prints @samp{Null field}). A variable can be an array element, with
+the subscripts being constant string values. To print the contents of an array,
+prefix the name of the array with the @samp{@@} symbol:
+
+@example
+gawk> @kbd{print @@a}
+@end example
+
+@noindent
+This prints the indices and the corresponding values for all elements in
+the array @code{a}.
+
+@cindex debugger commands, @code{printf}
+@cindex @code{printf} debugger command
+@item @code{printf} @var{format} [@code{,} @var{arg} @dots{}]
+Print formatted text. The @var{format} may include escape sequences,
+such as @samp{\n}
+(@pxref{Escape Sequences}).
+No newline is printed unless one is specified.
+
+@cindex debugger commands, @code{set}
+@cindex @code{set} debugger command
+@cindex assign values to variables, in debugger
+@item @code{set} @var{var}@code{=}@var{value}
+Assign a constant (number or string) value to an @command{awk} variable
+or field.
+String values must be enclosed between double quotes (@code{"}@dots{}@code{"}).
+
+You can also set special @command{awk} variables, such as @code{FS},
+@code{NF}, @code{NR}, and son on.
+
+@cindex debugger commands, @code{w} (@code{watch})
+@cindex debugger commands, @code{watch}
+@cindex @code{watch} debugger command
+@cindex @code{w} debugger command (alias for @code{watch})
+@cindex set watchpoint
+@item @code{watch} @var{var} | @code{$}@var{n} [@code{"@var{expression}"}]
+@itemx @code{w} @var{var} | @code{$}@var{n} [@code{"@var{expression}"}]
+Add variable @var{var} (or field @code{$@var{n}}) to the watch list.
+The debugger then stops whenever
+the value of the variable or field changes. Each watched item is assigned a
+number which can be used to delete it from the watch list using the
+@code{unwatch} command.
+
+With a watchpoint, you may also supply a condition. This is an
+@command{awk} expression (enclosed in double quotes) that the debugger
+evaluates whenever the watchpoint is reached. If the condition is true,
+then the debugger stops execution and prompts for a command. Otherwise,
+@command{gawk} continues executing the program.
+
+@cindex debugger commands, @code{undisplay}
+@cindex @code{undisplay} debugger command
+@cindex stop automatic display, in debugger
+@item @code{undisplay} [@var{n}]
+Remove item number @var{n} (or all items, if no argument) from the
+automatic display list.
+
+@cindex debugger commands, @code{unwatch}
+@cindex @code{unwatch} debugger command
+@cindex delete watchpoint
+@item @code{unwatch} [@var{n}]
+Remove item number @var{n} (or all items, if no argument) from the
+watch list.
+
+@end table
+
+@node Execution Stack
+@subsection Working with the Stack
+
+Whenever you run a program which contains any function calls,
+@command{gawk} maintains a stack of all of the function calls leading up
+to where the program is right now. You can see how you got to where you are,
+and also move around in the stack to see what the state of things was in the
+functions which called the one you are in. The commands for doing this are:
+
+@table @asis
+@cindex debugger commands, @code{bt} (@code{backtrace})
+@cindex debugger commands, @code{backtrace}
+@cindex debugger commands, @code{where} (@code{backtrace})
+@cindex @code{backtrace} debugger command
+@cindex @code{bt} debugger command (alias for @code{backtrace})
+@cindex @code{where} debugger command
+@cindex @code{where} debugger command (alias for @code{backtrace})
+@cindex call stack, display in debugger
+@cindex traceback, display in debugger
+@item @code{backtrace} [@var{count}]
+@itemx @code{bt} [@var{count}]
+@itemx @code{where} [@var{count}]
+Print a backtrace of all function calls (stack frames), or innermost @var{count}
+frames if @var{count} > 0. Print the outermost @var{count} frames if
+@var{count} < 0. The backtrace displays the name and arguments to each
+function, the source @value{FN}, and the line number.
+The alias @code{where} for @code{backtrace} is provided for longtime
+GDB users who may be used to that command.
+
+@cindex debugger commands, @code{down}
+@cindex @code{down} debugger command
+@item @code{down} [@var{count}]
+Move @var{count} (default 1) frames down the stack toward the innermost frame.
+Then select and print the frame.
+
+@cindex debugger commands, @code{f} (@code{frame})
+@cindex debugger commands, @code{frame}
+@cindex @code{frame} debugger command
+@cindex @code{f} debugger command (alias for @code{frame})
+@item @code{frame} [@var{n}]
+@itemx @code{f} [@var{n}]
+Select and print stack frame @var{n}. Frame 0 is the currently executing,
+or @dfn{innermost}, frame (function call), frame 1 is the frame that
+called the innermost one. The highest numbered frame is the one for the
+main program. The printed information consists of the frame number,
+function and argument names, source file, and the source line.
+
+@cindex debugger commands, @code{up}
+@cindex @code{up} debugger command
+@item @code{up} [@var{count}]
+Move @var{count} (default 1) frames up the stack toward the outermost frame.
+Then select and print the frame.
+@end table
+
+@node Debugger Info
+@subsection Obtaining Information About the Program and the Debugger State
+
+Besides looking at the values of variables, there is often a need to get
+other sorts of information about the state of your program and of the
+debugging environment itself. The @command{gawk} debugger has one command which
+provides this information, appropriately called @code{info}. @code{info}
+is used with one of a number of arguments that tell it exactly what
+you want to know:
+
+@table @asis
+@cindex debugger commands, @code{i} (@code{info})
+@cindex debugger commands, @code{info}
+@cindex @code{info} debugger command
+@cindex @code{i} debugger command (alias for @code{info})
+@item @code{info} @var{what}
+@itemx @code{i} @var{what}
+The value for @var{what} should be one of the following:
+
+@c nested table
+@table @code
+@item args
+@cindex show function arguments, in debugger
+List arguments of the selected frame.
+
+@item break
+@cindex show breakpoints
+List all currently set breakpoints.
+
+@item display
+@cindex automatic displays, in debugger
+List all items in the automatic display list.
+
+@item frame
+@cindex describe call stack frame, in debugger
+Give a description of the selected stack frame.
+
+@item functions
+@cindex list function definitions, in debugger
+List all function definitions including source @value{FN}s and
+line numbers.
+
+@item locals
+@cindex show local variables, in debugger
+List local variables of the selected frame.
+
+@item source
+@cindex show name of current source file, in debugger
+Print the name of the current source file. Each time the program stops, the
+current source file is the file containing the current instruction.
+When the debugger first starts, the current source file is the first file
+included via the @option{-f} option. The
+@samp{list @var{filename}:@var{lineno}} command can
+be used at any time to change the current source.
+
+@item sources
+@cindex show all source files, in debugger
+List all program sources.
+
+@item variables
+@cindex list all global variables, in debugger
+List all global variables.
+
+@item watch
+@cindex show watchpoints
+List all items in the watch list.
+@end table
+@end table
+
+Additional commands give you control over the debugger, the ability to
+save the debugger's state, and the ability to run debugger commands
+from a file. The commands are:
+
+@table @asis
+@cindex debugger commands, @code{o} (@code{option})
+@cindex debugger commands, @code{option}
+@cindex @code{option} debugger command
+@cindex @code{o} debugger command (alias for @code{option})
+@cindex display debugger options
+@cindex debugger options
+@item @code{option} [@var{name}[@code{=}@var{value}]]
+@itemx @code{o} [@var{name}[@code{=}@var{value}]]
+Without an argument, display the available debugger options
+and their current values. @samp{option @var{name}} shows the current
+value of the named option. @samp{option @var{name}=@var{value}} assigns
+a new value to the named option.
+The available options are:
+
+@c nested table
+@c asis for docbook
+@table @asis
+@item @code{history_size}
+@cindex debugger history size
+The maximum number of lines to keep in the history file @file{./.gawk_history}.
+The default is 100.
+
+@item @code{listsize}
+@cindex debugger default list amount
+The number of lines that @code{list} prints. The default is 15.
+
+@item @code{outfile}
+@cindex redirect @command{gawk} output, in debugger
+Send @command{gawk} output to a file; debugger output still goes
+to standard output. An empty string (@code{""}) resets output to
+standard output.
+
+@item @code{prompt}
+@cindex debugger prompt
+The debugger prompt. The default is @samp{@w{gawk> }}.
+
+@item @code{save_history} [@code{on} | @code{off}]
+@cindex debugger history file
+Save command history to file @file{./.gawk_history}.
+The default is @code{on}.
+
+@item @code{save_options} [@code{on} | @code{off}]
+@cindex save debugger options
+Save current options to file @file{./.gawkrc} upon exit.
+The default is @code{on}.
+Options are read back in to the next session upon startup.
+
+@item @code{trace} [@code{on} | @code{off}]
+@cindex instruction tracing, in debugger
+Turn instruction tracing on or off. The default is @code{off}.
+@end table
+
+@item @code{save} @var{filename}
+Save the commands from the current session to the given @value{FN},
+so that they can be replayed using the @command{source} command.
+
+@item @code{source} @var{filename}
+@cindex debugger, read commands from a file
+Run command(s) from a file; an error in any command does not
+terminate execution of subsequent commands. Comments (lines starting
+with @samp{#}) are allowed in a command file.
+Empty lines are ignored; they do @emph{not}
+repeat the last command.
+You can't restart the program by having more than one @code{run}
+command in the file. Also, the list of commands may include additional
+@code{source} commands; however, the @command{gawk} debugger will not source the
+same file more than once in order to avoid infinite recursion.
+
+In addition to, or instead of the @code{source} command, you can use
+the @option{-D @var{file}} or @option{--debug=@var{file}} command-line
+options to execute commands from a file non-interactively
+(@pxref{Options}).
+@end table
+
+@node Miscellaneous Debugger Commands
+@subsection Miscellaneous Commands
+
+There are a few more commands which do not fit into the
+previous categories, as follows:
+
+@table @asis
+@cindex debugger commands, @code{dump}
+@cindex @code{dump} debugger command
+@item @code{dump} [@var{filename}]
+Dump bytecode of the program to standard output or to the file
+named in @var{filename}. This prints a representation of the internal
+instructions which @command{gawk} executes to implement the @command{awk}
+commands in a program. This can be very enlightening, as the following
+partial dump of Davide Brini's obfuscated code
+(@pxref{Signature Program}) demonstrates:
+
+@c FIXME: This will need updating if num-handler branch is ever merged in.
+@smallexample
+gawk> @kbd{dump}
+@print{} # BEGIN
+@print{}
+@print{} [ 1:0xfcd340] Op_rule : [in_rule = BEGIN] [source_file = brini.awk]
+@print{} [ 1:0xfcc240] Op_push_i : "~" [MALLOC|STRING|STRCUR]
+@print{} [ 1:0xfcc2a0] Op_push_i : "~" [MALLOC|STRING|STRCUR]
+@print{} [ 1:0xfcc280] Op_match :
+@print{} [ 1:0xfcc1e0] Op_store_var : O
+@print{} [ 1:0xfcc2e0] Op_push_i : "==" [MALLOC|STRING|STRCUR]
+@print{} [ 1:0xfcc340] Op_push_i : "==" [MALLOC|STRING|STRCUR]
+@print{} [ 1:0xfcc320] Op_equal :
+@print{} [ 1:0xfcc200] Op_store_var : o
+@print{} [ 1:0xfcc380] Op_push : o
+@print{} [ 1:0xfcc360] Op_plus_i : 0 [MALLOC|NUMCUR|NUMBER]
+@print{} [ 1:0xfcc220] Op_push_lhs : o [do_reference = true]
+@print{} [ 1:0xfcc300] Op_assign_plus :
+@print{} [ :0xfcc2c0] Op_pop :
+@print{} [ 1:0xfcc400] Op_push : O
+@print{} [ 1:0xfcc420] Op_push_i : "" [MALLOC|STRING|STRCUR]
+@print{} [ :0xfcc4a0] Op_no_op :
+@print{} [ 1:0xfcc480] Op_push : O
+@print{} [ :0xfcc4c0] Op_concat : [expr_count = 3] [concat_flag = 0]
+@print{} [ 1:0xfcc3c0] Op_store_var : x
+@print{} [ 1:0xfcc440] Op_push_lhs : X [do_reference = true]
+@print{} [ 1:0xfcc3a0] Op_postincrement :
+@print{} [ 1:0xfcc4e0] Op_push : x
+@print{} [ 1:0xfcc540] Op_push : o
+@print{} [ 1:0xfcc500] Op_plus :
+@print{} [ 1:0xfcc580] Op_push : o
+@print{} [ 1:0xfcc560] Op_plus :
+@print{} [ 1:0xfcc460] Op_leq :
+@print{} [ :0xfcc5c0] Op_jmp_false : [target_jmp = 0xfcc5e0]
+@print{} [ 1:0xfcc600] Op_push_i : "%c" [MALLOC|STRING|STRCUR]
+@print{} [ :0xfcc660] Op_no_op :
+@print{} [ 1:0xfcc520] Op_assign_concat : c
+@print{} [ :0xfcc620] Op_jmp : [target_jmp = 0xfcc440]
+@print{}
+@dots{}
+@print{}
+@print{} [ 2:0xfcc5a0] Op_K_printf : [expr_count = 17] [redir_type = ""]
+@print{} [ :0xfcc140] Op_no_op :
+@print{} [ :0xfcc1c0] Op_atexit :
+@print{} [ :0xfcc640] Op_stop :
+@print{} [ :0xfcc180] Op_no_op :
+@print{} [ :0xfcd150] Op_after_beginfile :
+@print{} [ :0xfcc160] Op_no_op :
+@print{} [ :0xfcc1a0] Op_after_endfile :
+gawk>
+@end smallexample
+
+@cindex debugger commands, @code{h} (@code{help})
+@cindex debugger commands, @code{help}
+@cindex @code{help} debugger command
+@cindex @code{h} debugger command (alias for @code{help})
+@item @code{help}
+@itemx @code{h}
+Print a list of all of the @command{gawk} debugger commands with a short
+summary of their usage. @samp{help @var{command}} prints the information
+about the command @var{command}.
+
+@cindex debugger commands, @code{l} (@code{list})
+@cindex debugger commands, @code{list}
+@cindex @code{list} debugger command
+@cindex @code{l} debugger command (alias for @code{list})
+@item @code{list} [@code{-} | @code{+} | @var{n} | @var{filename}@code{:}@var{n} | @var{n}--@var{m} | @var{function}]
+@itemx @code{l} [@code{-} | @code{+} | @var{n} | @var{filename}@code{:}@var{n} | @var{n}--@var{m} | @var{function}]
+Print the specified lines (default 15) from the current source file
+or the file named @var{filename}. The possible arguments to @code{list}
+are as follows:
+
+@c nested table
+@table @asis
+@item @code{-} (Minus)
+Print lines before the lines last printed.
+
+@item @code{+}
+Print lines after the lines last printed.
+@code{list} without any argument does the same thing.
+
+@item @var{n}
+Print lines centered around line number @var{n}.
+
+@item @var{n}--@var{m}
+Print lines from @var{n} to @var{m}.
+
+@item @var{filename}@code{:}@var{n}
+Print lines centered around line number @var{n} in
+source file @var{filename}. This command may change the current source file.
+
+@item @var{function}
+Print lines centered around beginning of the
+function @var{function}. This command may change the current source file.
+@end table
+
+@cindex debugger commands, @code{q} (@code{quit})
+@cindex debugger commands, @code{quit}
+@cindex @code{quit} debugger command
+@cindex @code{q} debugger command (alias for @code{quit})
+@cindex exit the debugger
+@item @code{quit}
+@itemx @code{q}
+Exit the debugger. Debugging is great fun, but sometimes we all have
+to tend to other obligations in life, and sometimes we find the bug,
+and are free to go on to the next one! As we saw earlier, if you are
+running a program, the debugger warns you if you accidentally type
+@samp{q} or @samp{quit}, to make sure you really want to quit.
+
+@cindex debugger commands, @code{trace}
+@cindex @code{trace} debugger command
+@item @code{trace} [@code{on} | @code{off}]
+Turn on or off a continuous printing of instructions which are about to
+be executed, along with printing the @command{awk} line which they
+implement. The default is @code{off}.
+
+It is to be hoped that most of the ``opcodes'' in these instructions are
+fairly self-explanatory, and using @code{stepi} and @code{nexti} while
+@code{trace} is on will make them into familiar friends.
+
+@end table
+
+@node Readline Support
+@section Readline Support
+@cindex command completion, in debugger
+@cindex history expansion, in debugger
+
+If @command{gawk} is compiled with
+@uref{http://cnswww.cns.cwru.edu/php/chet/readline/readline.html,
+the @code{readline} library}, you can take advantage of that library's
+command completion and history expansion features. The following types
+of completion are available:
+
+@table @asis
+@item Command completion
+Command names.
+
+@item Source @value{FN} completion
+Source @value{FN}s. Relevant commands are
+@code{break},
+@code{clear},
+@code{list},
+@code{tbreak},
+and
+@code{until}.
+
+@item Argument completion
+Non-numeric arguments to a command.
+Relevant commands are @code{enable} and @code{info}.
+
+@item Variable name completion
+Global variable names, and function arguments in the current context
+if the program is running. Relevant commands are
+@code{display},
+@code{print},
+@code{set},
+and
+@code{watch}.
+
+@end table
+
+@node Limitations
+@section Limitations
+
+We hope you find the @command{gawk} debugger useful and enjoyable to work with,
+but as with any program, especially in its early releases, it still has
+some limitations. A few which are worth being aware of are:
+
+@itemize @value{BULLET}
+@item
+At this point, the debugger does not give a detailed explanation of
+what you did wrong when you type in something it doesn't like. Rather, it just
+responds @samp{syntax error}. When you do figure out what your mistake was,
+though, you'll feel like a real guru.
+
+@item
+@c NOTE: no comma after the ref{} on purpose, due to following
+@c parenthetical remark.
+If you perused the dump of opcodes in @ref{Miscellaneous Debugger Commands}
+(or if you are already familiar with @command{gawk} internals),
+you will realize that much of the internal manipulation of data
+in @command{gawk}, as in many interpreters, is done on a stack.
+@code{Op_push}, @code{Op_pop}, and the like, are the ``bread and butter'' of
+most @command{gawk} code.
+
+Unfortunately, as of now, the @command{gawk}
+debugger does not allow you to examine the stack's contents.
+That is, the intermediate results of expression evaluation are on the
+stack, but cannot be printed. Rather, only variables which are defined
+in the program can be printed. Of course, a workaround for
+this is to use more explicit variables at the debugging stage and then
+change back to obscure, perhaps more optimal code later.
+
+@item
+There is no way to look ``inside'' the process of compiling
+regular expressions to see if you got it right. As an @command{awk}
+programmer, you are expected to know the meaning of
+@code{/[^[:alnum:][:blank:]]/}.
+
+@item
+The @command{gawk} debugger is designed to be used by running a program (with all its
+parameters) on the command line, as described in @ref{Debugger Invocation}.
+There is no way (as of now) to attach or ``break in'' to a running program.
+This seems reasonable for a language which is used mainly for quickly
+executing, short programs.
+
+@item
+The @command{gawk} debugger only accepts source supplied with the @option{-f} option.
+@end itemize
+
+@ignore
+Look forward to a future release when these and other missing features may
+be added, and of course feel free to try to add them yourself!
+@end ignore
+
+@node Debugging Summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+Programs rarely work correctly the first time. Finding bugs
+is @dfn{debugging} and a program that helps you find bugs is a
+@dfn{debugger}. @command{gawk} has a built-in debugger that works very
+similarly to the GNU Debugger, GDB.
+
+@item
+Debuggers let you step through your program one statement at a time,
+examine and change variable and array values, and do a number of other
+things that let you understand what your program is actually doing (as
+opposed to what it is supposed to do).
+
+@item
+Like most debuggers, the @command{gawk} debugger works in terms of stack
+frames, and lets you set both breakpoints (stop at a point in the code)
+and watchpoints (stop when a data value changes).
+
+@item
+The debugger command set is fairly complete, providing control over
+breakpoints, execution, viewing and changing data, working with the stack,
+getting information, and other tasks.
+
+@item
+If the @code{readline} library is available when @command{gawk} is
+compiled, it is used by the debugger to provide command-line history
+and editing.
+
+@end itemize
+
+@node Arbitrary Precision Arithmetic
+@chapter Arithmetic and Arbitrary-Precision Arithmetic with @command{gawk}
+@cindex arbitrary precision
+@cindex multiple precision
+@cindex infinite precision
+@cindex floating-point, numbers@comma{} arbitrary precision
+
+This @value{CHAPTER} introduces some basic concepts relating to
+how computers do arithmetic and defines some important terms.
+It then proceeds to describe floating-point arithmetic,
+which is what @command{awk} uses for all its computations, including a
+discussion of arbitrary-precision floating-point arithmetic, which is
+a feature available only in @command{gawk}. It continues on to present
+arbitrary-precision integers, and concludes with a description of some
+points where @command{gawk} and the POSIX standard are not quite in
+agreement.
+
+@quotation NOTE
+Most users of @command{gawk} can safely skip this chapter.
+But if you want to do scientific calculations with @command{gawk},
+this is the place to be.
+@end quotation
+
+@menu
+* Computer Arithmetic:: A quick intro to computer math.
+* Math Definitions:: Defining terms used.
+* MPFR features:: The MPFR features in @command{gawk}.
+* FP Math Caution:: Things to know.
+* Arbitrary Precision Integers:: Arbitrary Precision Integer Arithmetic with
+ @command{gawk}.
+* POSIX Floating Point Problems:: Standards Versus Existing Practice.
+* Floating point summary:: Summary of floating point discussion.
+@end menu
+
+@node Computer Arithmetic
+@section A General Description of Computer Arithmetic
+
+Until now, we have worked with data as either numbers or
+strings. Ultimately, however, computers represent everything in terms
+of @dfn{binary digits}, or @dfn{bits}. A decimal digit can take on any
+of 10 values: zero through nine. A binary digit can take on any of two
+values, zero or one. Using binary, computers (and computer software)
+can represent and manipulate numerical and character data. In general,
+the more bits you can use to represent a particular thing, the greater
+the range of possible values it can take on.
+
+Modern computers support at least two, and often more, ways to do
+arithmetic. Each kind of arithmetic uses a different representation
+(organization of the bits) for the numbers. The kinds of arithmetic
+that interest us are:
+
+@table @asis
+@item Decimal arithmetic
+This is the kind of arithmetic you learned in elementary school, using
+paper and pencil (and/or a calculator). In theory, numbers can have an
+arbitrary number of digits on either side (or both sides) of the decimal
+point, and the results of a computation are always exact.
+
+Some modern system can do decimal arithmetic in hardware, but usually you
+need a special software library to provide access to these instructions.
+There are also libraries that do decimal arithmetic entirely in software.
+
+Despite the fact that some users expect @command{gawk} to be performing
+decimal arithmetic,@footnote{We don't know why they expect this, but
+they do.} it does not do so.
+
+@item Integer arithmetic
+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.
+
+@cindex unsigned integers
+@cindex integers, unsigned
+In computers, integer values come in two flavors: @dfn{signed} and
+@dfn{unsigned}. Signed values may be negative or positive, whereas
+unsigned values are always positive (i.e., greater than or equal
+to zero).
+
+In computer systems, integer arithmetic is exact, but the possible
+range of values is limited. Integer arithmetic is generally faster than
+floating-point arithmetic.
+
+@item Floating-point arithmetic
+Floating-point numbers represent what were called in school ``real''
+numbers (i.e., those that 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 than can integers. The disadvantage is that
+there are numbers that they cannot represent exactly.
+
+Modern systems support floating-point arithmetic in hardware, with a
+limited range of values. There are software libraries that allow
+the use of arbitrary-precision floating-point calculations.
+
+POSIX @command{awk} uses @dfn{double-precision} floating-point numbers, which
+can hold more digits than @dfn{single-precision} floating-point numbers.
+@command{gawk} has facilities for performing arbitrary-precision
+floating-point arithmetic, which we describe in more detail shortly.
+@end table
+
+Computers work with integer and floating-point values of different
+ranges. Integer values are usually either 32 or 64 bits in size.
+Single-precision floating-point values occupy 32 bits, whereas double-precision
+floating-point values occupy 64 bits. Floating-point values are always
+signed. The possible ranges of values are shown in @ref{table-numeric-ranges}.
+
+@float Table,table-numeric-ranges
+@caption{Value ranges for different numeric representations}
+@multitable @columnfractions .34 .33 .33
+@headitem Numeric representation @tab Minimum value @tab Maximum value
+@item 32-bit signed integer @tab @minus{}2,147,483,648 @tab 2,147,483,647
+@item 32-bit unsigned integer @tab 0 @tab 4,294,967,295
+@item 64-bit signed integer @tab @minus{}9,223,372,036,854,775,808 @tab 9,223,372,036,854,775,807
+@item 64-bit unsigned integer @tab 0 @tab 18,446,744,073,709,551,615
+@item Single-precision floating point (approximate) @tab @code{1.175494e-38} @tab @code{3.402823e+38}
+@item Double-precision floating point (approximate) @tab @code{2.225074e-308} @tab @code{1.797693e+308}
+@end multitable
+@end float
+
+@node Math Definitions
+@section Other Stuff to Know
+
+The rest of this @value{CHAPTER} uses a number of terms. Here are some
+informal definitions that should help you work your way through the material
+here.
+
+@table @dfn
+@item Accuracy
+A floating-point calculation's accuracy is how close it comes
+to the real (paper and pencil) value.
+
+@item Error
+The difference between what the result of a computation ``should be''
+and what it actually is. It is best to minimize error as much
+as possible.
+
+@item Exponent
+The order of magnitude of a value;
+some number of bits in a floating-point value store the exponent.
+
+@item Inf
+A special value representing infinity. Operations involving another
+number and infinity produce infinity.
+
+@item NaN
+``Not A Number.''@footnote{Thanks to Michael Brennan for this description,
+which we have paraphrased, and for the examples.} A special value that
+results from attempting a calculation that has no answer as a real number.
+In such a case, programs can either receive a floating-point exception,
+or get @code{NaN} back as the result. The IEEE 754 standard recommends
+that systems return @code{NaN}. Some examples:
+
+@table @code
+@item sqrt(-1)
+This makes sense in the range of complex numbers, but not in the
+range of real numbers, so the result is @code{NaN}.
+
+@item log(-8)
+@minus{}8 is out of the domain of @code{log()}, so the result is @code{NaN}.
+@end table
+
+@item Normalized
+How the significand (see later in this list) is usually stored. The
+value is adjusted so that the first bit is one, and then that leading
+one is assumed instead of physically stored. This provides one
+extra bit of precision.
+
+@item Precision
+The number of bits used to represent a floating-point number.
+The more bits, the more digits you can represent.
+Binary and decimal precisions are related approximately, according to the
+formula:
+
+@display
+@iftex
+@math{prec = 3.322 @cdot dps}
+@end iftex
+@ifnottex
+@ifnotdocbook
+@var{prec} = 3.322 * @var{dps}
+@end ifnotdocbook
+@end ifnottex
+@docbook
+<emphasis>prec</emphasis> = 3.322 &sdot; <emphasis>dps</emphasis> @c
+@end docbook
+@end display
+
+@noindent
+Here, @var{prec} denotes the binary precision
+(measured in bits) and @var{dps} (short for decimal places)
+is the decimal digits.
+
+@item Rounding mode
+How numbers are rounded up or down when necessary.
+More details are provided later.
+
+@item Significand
+A floating-point value consists the significand multiplied by 10
+to the power of the exponent. For example, in @code{1.2345e67},
+the significand is @code{1.2345}.
+
+@item Stability
+From @uref{http://en.wikipedia.org/wiki/Numerical_stability,
+the Wikipedia article on numerical stability}:
+``Calculations that can be proven not to magnify approximation errors
+are called @dfn{numerically stable}.''
+@end table
+
+See @uref{http://en.wikipedia.org/wiki/Accuracy_and_precision,
+the Wikipedia article on accuracy and precision} for more information
+on some of those terms.
+
+On modern systems, floating-point hardware uses the representation and
+operations defined by the IEEE 754 standard.
+Three of the standard IEEE 754 types are 32-bit single precision,
+64-bit double precision, and 128-bit quadruple precision.
+The standard also specifies extended precision formats
+to allow greater precisions and larger exponent ranges.
+(@command{awk} uses only the 64-bit double-precision format.)
+
+@ref{table-ieee-formats} lists the precision and exponent
+field values for the basic IEEE 754 binary formats:
+
+@float Table,table-ieee-formats
+@caption{Basic IEEE format values}
+@multitable @columnfractions .20 .20 .20 .20 .20
+@headitem Name @tab Total bits @tab Precision @tab Minimum exponent @tab Maximum exponent
+@item Single @tab 32 @tab 24 @tab @minus{}126 @tab +127
+@item Double @tab 64 @tab 53 @tab @minus{}1022 @tab +1023
+@item Quadruple @tab 128 @tab 113 @tab @minus{}16382 @tab +16383
+@end multitable
+@end float
+
+@quotation NOTE
+The precision numbers include the implied leading one that gives them
+one extra bit of significand.
+@end quotation
+
+@node MPFR features
+@section Arbitrary-Precision Arithmetic Features in @command{gawk}
+
+By default, @command{gawk} uses the double-precision floating-point values
+supplied by the hardware of the system it runs on. However, if it was
+compiled to do so, @command{gawk} uses the @uref{http://www.mpfr.org,
+GNU MPFR} and @uref{http://gmplib.org, GNU MP} (GMP) libraries for
+arbitrary-precision arithmetic on numbers. You can see if MPFR support
+is available like so:
+
+@example
+$ @kbd{gawk --version}
+@print{} GNU Awk 4.1.2, API: 1.1 (GNU MPFR 3.1.0-p3, GNU MP 5.0.2)
+@print{} Copyright (C) 1989, 1991-2015 Free Software Foundation.
+@dots{}
+@end example
+
+@noindent
+(You may see different version numbers than what's shown here. That's OK;
+what's important is to see that GNU MPFR and GNU MP are listed in
+the output.)
+
+Additionally, there are a few elements available in the @code{PROCINFO}
+array to provide information about the MPFR and GMP libraries
+(@pxref{Auto-set}).
+
+The MPFR library provides precise control over precisions and rounding
+modes, and gives correctly rounded, reproducible, platform-independent
+results. With the @option{-M} command-line option,
+all floating-point arithmetic operators and numeric functions
+can yield results to any desired precision level supported by MPFR.
+
+Two predefined variables, @code{PREC} and @code{ROUNDMODE},
+provide control over the working precision and the rounding mode.
+The precision and the rounding mode are set globally for every operation
+to follow.
+@DBXREF{Setting precision} and @DBREF{Setting the rounding mode}
+for more information.
+
+@node FP Math Caution
+@section Floating-Point Arithmetic: Caveat Emptor!
+
+@quotation
+@i{Math class is tough!}
+@author Teen Talk Barbie, July 1992
+@end quotation
+
+This @value{SECTION} provides a high level overview of the issues
+involved when doing lots of floating-point arithmetic.@footnote{There
+is a very nice @uref{http://www.validlab.com/goldberg/paper.pdf,
+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. This is
+worth reading if you are interested in the details, but it does require
+a background in computer science.}
+The discussion applies to both hardware and arbitrary-precision
+floating-point arithmetic.
+
+@quotation CAUTION
+The material here is purposely general. If you need to do serious
+computer arithmetic, you should do some research first, and not
+rely just on what we tell you.
+@end quotation
+
+@menu
+* Inexactness of computations:: Floating point math is not exact.
+* Getting Accuracy:: Getting more accuracy takes some work.
+* Try To Round:: Add digits and round.
+* Setting precision:: How to set the precision.
+* Setting the rounding mode:: How to set the rounding mode.
+@end menu
+
+@node Inexactness of computations
+@subsection Floating-Point Arithmetic Is Not Exact
+
+Binary floating-point representations and arithmetic are inexact.
+Simple values like 0.1 cannot be precisely represented using
+binary floating-point numbers, and the limited precision of
+floating-point numbers means that slight changes in
+the order of operations or the precision of intermediate storage
+can change the result. To make matters worse, with arbitrary-precision
+floating-point arithmetic, you can set the precision before starting a
+computation, but then you cannot be sure of the number of significant
+decimal places in the final result.
+
+@menu
+* Inexact representation:: Numbers are not exactly represented.
+* Comparing FP Values:: How to compare floating point values.
+* Errors accumulate:: Errors get bigger as they go.
+@end menu
+
+@node Inexact representation
+@subsubsection Many Numbers Cannot Be Represented Exactly
+
+So, before you start to write any code, you should think
+about what you really want and what's really happening. Consider the
+two numbers in the following example:
+
+@example
+x = 0.875 # 1/2 + 1/4 + 1/8
+y = 0.425
+@end example
+
+Unlike the number in @code{y}, the number stored in @code{x}
+is exactly representable
+in binary because it can be written as a finite sum of one or
+more fractions whose denominators are all powers of two.
+When @command{gawk} reads a floating-point number from
+program source, it automatically rounds that number to whatever
+precision your machine supports. If you try to print the numeric
+content of a variable using an output format string of @code{"%.17g"},
+it may not produce the same number as you assigned to it:
+
+@example
+$ @kbd{gawk 'BEGIN @{ x = 0.875; y = 0.425}
+> @kbd{ printf("%0.17g, %0.17g\n", x, y) @}'}
+@print{} 0.875, 0.42499999999999999
+@end example
+
+Often the error is so small you do not even notice it, and if you do,
+you can always specify how much precision you would like in your output.
+Usually this is a format string like @code{"%.15g"}, which when
+used in the previous example, produces an output identical to the input.
+
+@node Comparing FP Values
+@subsubsection Be Careful Comparing Values
+
+Because the underlying representation can be a little bit off from the exact value,
+comparing floating-point values to see if they are exactly equal is generally a bad idea.
+Here is an example where it does not work like you would expect:
+
+@example
+$ @kbd{gawk 'BEGIN @{ print (0.1 + 12.2 == 12.3) @}'}
+@print{} 0
+@end example
+
+The general wisdom when comparing floating-point values is to see if
+they are within some small range of each other (called a @dfn{delta},
+or @dfn{tolerance}).
+You have to decide how small a delta is important to you. Code to do
+this looks something like the following:
+
+@example
+delta = 0.00001 # for example
+difference = abs(a) - abs(b) # subtract the two values
+if (difference < delta)
+ # all ok
+else
+ # not ok
+@end example
+
+@noindent
+(We assume that you have a simple absolute value function named
+@code{abs()} defined elsewhere in your program.)
+
+@node Errors accumulate
+@subsubsection Errors Accumulate
+
+The loss of accuracy during a single computation with floating-point
+numbers usually isn't enough to worry about. However, if you compute a
+value which is the result of a sequence of floating-point operations,
+the error can accumulate and greatly affect the computation itself.
+Here is an attempt to compute the value of @value{PI} using one of its
+many series representations:
+
+@example
+BEGIN @{
+ x = 1.0 / sqrt(3.0)
+ n = 6
+ for (i = 1; i < 30; i++) @{
+ n = n * 2.0
+ x = (sqrt(x * x + 1) - 1) / x
+ printf("%.15f\n", n * x)
+ @}
+@}
+@end example
+
+When run, the early errors propagate through later computations,
+causing the loop to terminate prematurely after attempting to divide by zero:
+
+@example
+$ @kbd{gawk -f pi.awk}
+@print{} 3.215390309173475
+@print{} 3.159659942097510
+@print{} 3.146086215131467
+@print{} 3.142714599645573
+@dots{}
+@print{} 3.224515243534819
+@print{} 2.791117213058638
+@print{} 0.000000000000000
+@error{} gawk: pi.awk:6: fatal: division by zero attempted
+@end example
+
+Here is an additional example where the inaccuracies in internal representations
+yield an unexpected result:
+
+@example
+$ @kbd{gawk 'BEGIN @{}
+> @kbd{for (d = 1.1; d <= 1.5; d += 0.1) # loop five times (?)}
+> @kbd{i++}
+> @kbd{print i}
+> @kbd{@}'}
+@print{} 4
+@end example
+
+@node Getting Accuracy
+@subsection Getting the Accuracy You Need
+
+Can arbitrary-precision arithmetic give exact results? There are
+no easy answers. The standard rules of algebra often do not apply
+when using floating-point arithmetic.
+Among other things, the distributive and associative laws
+do not hold completely, and order of operation may be important
+for your computation. Rounding error, cumulative precision loss
+and underflow are often troublesome.
+
+When @command{gawk} tests the expressions @samp{0.1 + 12.2} and
+@samp{12.3} for equality using the machine double-precision arithmetic,
+it decides that they are not equal! (@xref{Comparing FP Values}.)
+You can get the result you want by increasing the precision; 56 bits in
+this case does the job:
+
+@example
+$ @kbd{gawk -M -v PREC=56 'BEGIN @{ print (0.1 + 12.2 == 12.3) @}'}
+@print{} 1
+@end example
+
+If adding more bits is good, perhaps adding even more bits of
+precision is better?
+Here is what happens if we use an even larger value of @code{PREC}:
+
+@example
+$ @kbd{gawk -M -v PREC=201 'BEGIN @{ print (0.1 + 12.2 == 12.3) @}'}
+@print{} 0
+@end example
+
+This is not a bug in @command{gawk} or in the MPFR library.
+It is easy to forget that the finite number of bits used to store the value
+is often just an approximation after proper rounding.
+The test for equality succeeds if and only if @emph{all} bits in the two operands
+are exactly the same. Because this is not necessarily true after floating-point
+computations with a particular precision and effective rounding mode,
+a straight test for equality may not work. Instead, compare the
+two numbers to see if they are within the desirable delta of each other.
+
+In applications where 15 or fewer decimal places suffice,
+hardware double-precision arithmetic can be adequate, and is usually much faster.
+But you need to keep in mind that every floating-point operation
+can suffer a new rounding error with catastrophic consequences, as illustrated
+by our earlier attempt to compute the value of @value{PI}.
+Extra precision can greatly enhance the stability and the accuracy
+of your computation in such cases.
+
+Repeated addition is not necessarily equivalent to multiplication
+in floating-point arithmetic. In the example in
+@ref{Errors accumulate}:
+
+@example
+$ @kbd{gawk 'BEGIN @{}
+> @kbd{for (d = 1.1; d <= 1.5; d += 0.1) # loop five times (?)}
+> @kbd{i++}
+> @kbd{print i}
+> @kbd{@}'}
+@print{} 4
+@end example
+
+@noindent
+you may or may not succeed in getting the correct result by choosing
+an arbitrarily large value for @code{PREC}. Reformulation of
+the problem at hand is often the correct approach in such situations.
+
+@node Try To Round
+@subsection Try a Few Extra Bits of Precision and Rounding
+
+Instead of arbitrary-precision floating-point arithmetic,
+often all you need is an adjustment of your logic
+or a different order for the operations in your calculation.
+The stability and the accuracy of the computation of @value{PI}
+in the earlier example can be enhanced by using the following
+simple algebraic transformation:
+
+@example
+(sqrt(x * x + 1) - 1) / x @equiv{} x / (sqrt(x * x + 1) + 1)
+@end example
+
+@noindent
+After making this change, the program converges to
+@value{PI} in under 30 iterations:
+
+@example
+$ @kbd{gawk -f pi2.awk}
+@print{} 3.215390309173473
+@print{} 3.159659942097501
+@print{} 3.146086215131436
+@print{} 3.142714599645370
+@print{} 3.141873049979825
+@dots{}
+@print{} 3.141592653589797
+@print{} 3.141592653589797
+@end example
+
+@node Setting precision
+@subsection Setting the Precision
+
+@command{gawk} uses a global working precision; it does not keep track of
+the precision or accuracy of individual numbers. Performing an arithmetic
+operation or calling a built-in function rounds the result to the current
+working precision. The default working precision is 53 bits, which you can
+modify using the predefined variable @code{PREC}. You can also set the
+value to one of the predefined case-insensitive strings
+shown in @ref{table-predefined-precision-strings},
+to emulate an IEEE 754 binary format.
+
+@float Table,table-predefined-precision-strings
+@caption{Predefined precision strings for @code{PREC}}
+@multitable {@code{"double"}} {12345678901234567890123456789012345}
+@headitem @code{PREC} @tab IEEE 754 Binary Format
+@item @code{"half"} @tab 16-bit half-precision
+@item @code{"single"} @tab Basic 32-bit single precision
+@item @code{"double"} @tab Basic 64-bit double precision
+@item @code{"quad"} @tab Basic 128-bit quadruple precision
+@item @code{"oct"} @tab 256-bit octuple precision
+@end multitable
+@end float
+
+The following example illustrates the effects of changing precision
+on arithmetic operations:
+
+@example
+$ @kbd{gawk -M -v PREC=100 'BEGIN @{ x = 1.0e-400; print x + 0}
+> @kbd{PREC = "double"; print x + 0 @}'}
+@print{} 1e-400
+@print{} 0
+@end example
+
+@quotation CAUTION
+Be wary of floating-point constants! When reading a floating-point
+constant from program source code, @command{gawk} uses the default
+precision (that of a C @code{double}), unless overridden by an assignment
+to the special variable @code{PREC} on the command line, to store it
+internally as an MPFR number. Changing the precision using @code{PREC}
+in the program text does @emph{not} change the precision of a constant.
+
+If you need to represent a floating-point constant at a higher precision
+than the default and cannot use a command-line assignment to @code{PREC},
+you should either specify the constant as a string, or as a rational
+number, whenever possible. The following example illustrates the
+differences among various ways to print a floating-point constant:
+@end quotation
+
+@example
+$ @kbd{gawk -M 'BEGIN @{ PREC = 113; printf("%0.25f\n", 0.1) @}'}
+@print{} 0.1000000000000000055511151
+$ @kbd{gawk -M -v PREC=113 'BEGIN @{ printf("%0.25f\n", 0.1) @}'}
+@print{} 0.1000000000000000000000000
+$ @kbd{gawk -M 'BEGIN @{ PREC = 113; printf("%0.25f\n", "0.1") @}'}
+@print{} 0.1000000000000000000000000
+$ @kbd{gawk -M 'BEGIN @{ PREC = 113; printf("%0.25f\n", 1/10) @}'}
+@print{} 0.1000000000000000000000000
+@end example
+
+@node Setting the rounding mode
+@subsection Setting the Rounding Mode
+
+The @code{ROUNDMODE} variable provides
+program level control over the rounding mode.
+The correspondence between @code{ROUNDMODE} and the IEEE
+rounding modes is shown in @ref{table-gawk-rounding-modes}.
+
+@float Table,table-gawk-rounding-modes
+@caption{@command{gawk} rounding modes}
+@multitable @columnfractions .45 .30 .25
+@headitem Rounding Mode @tab IEEE Name @tab @code{ROUNDMODE}
+@item Round to nearest, ties to even @tab @code{roundTiesToEven} @tab @code{"N"} or @code{"n"}
+@item Round toward plus Infinity @tab @code{roundTowardPositive} @tab @code{"U"} or @code{"u"}
+@item Round toward negative Infinity @tab @code{roundTowardNegative} @tab @code{"D"} or @code{"d"}
+@item Round toward zero @tab @code{roundTowardZero} @tab @code{"Z"} or @code{"z"}
+@item Round to nearest, ties away from zero @tab @code{roundTiesToAway} @tab @code{"A"} or @code{"a"}
+@end multitable
+@end float
+
+@code{ROUNDMODE} has the default value @code{"N"}, which
+selects the IEEE 754 rounding mode @code{roundTiesToEven}.
+In @ref{table-gawk-rounding-modes}, the value @code{"A"} selects
+@code{roundTiesToAway}. This is only available if your version of the
+MPFR library supports it; otherwise, setting @code{ROUNDMODE} to @code{"A"}
+has no effect.
+
+The default mode @code{roundTiesToEven} is the most preferred,
+but the least intuitive. This method does the obvious thing for most values,
+by rounding them up or down to the nearest digit.
+For example, rounding 1.132 to two digits yields 1.13,
+and rounding 1.157 yields 1.16.
+
+However, when it comes to rounding a value that is exactly halfway between,
+things do not work the way you probably learned in school.
+In this case, the number is rounded to the nearest even digit.
+So rounding 0.125 to two digits rounds down to 0.12,
+but rounding 0.6875 to three digits rounds up to 0.688.
+You probably have already encountered this rounding mode when
+using @code{printf} to format floating-point numbers.
+For example:
+
+@example
+BEGIN @{
+ x = -4.5
+ for (i = 1; i < 10; i++) @{
+ x += 1.0
+ printf("%4.1f => %2.0f\n", x, x)
+ @}
+@}
+@end example
+
+@noindent
+produces the following output when run on the author's system:@footnote{It
+is possible for the output to be completely different if the
+C library in your system does not use the IEEE 754 even-rounding
+rule to round halfway cases for @code{printf}.}
+
+@example
+-3.5 => -4
+-2.5 => -2
+-1.5 => -2
+-0.5 => 0
+ 0.5 => 0
+ 1.5 => 2
+ 2.5 => 2
+ 3.5 => 4
+ 4.5 => 4
+@end example
+
+The theory behind @code{roundTiesToEven} is that it more or less evenly
+distributes upward and downward rounds of exact halves, which might
+cause any accumulating round-off error to cancel itself out. This is the
+default rounding mode for IEEE 754 computing functions and operators.
+
+The other rounding modes are rarely used. Round toward positive infinity
+(@code{roundTowardPositive}) and round toward negative infinity
+(@code{roundTowardNegative}) are often used to implement interval
+arithmetic, where you adjust the rounding mode to calculate upper and
+lower bounds for the range of output. The @code{roundTowardZero} mode can
+be used for converting floating-point numbers to integers. The rounding
+mode @code{roundTiesToAway} rounds the result to the nearest number and
+selects the number with the larger magnitude if a tie occurs.
+
+Some numerical analysts will tell you that your choice of rounding
+style has tremendous impact on the final outcome, and advise you to
+wait until final output for any rounding. Instead, you can often avoid
+round-off error problems by setting the precision initially to some
+value sufficiently larger than the final desired precision, so that
+the accumulation of round-off error does not influence the outcome.
+If you suspect that results from your computation are sensitive to
+accumulation of round-off error, look for a significant difference in
+output when you change the rounding mode to be sure.
+
+@node Arbitrary Precision Integers
+@section Arbitrary-Precision Integer Arithmetic with @command{gawk}
+@cindex integers, arbitrary precision
+@cindex arbitrary precision integers
+
+When given the @option{-M} option,
+@command{gawk} performs all integer arithmetic using GMP arbitrary-precision
+integers. Any number that looks like an integer in a source
+or @value{DF} is stored as an arbitrary-precision integer. The size
+of the integer is limited only by the available memory. For example,
+the following computes
+@iftex
+@math{5^{4^{3^{2}}}},
+@end iftex
+@ifnottex
+@ifnotdocbook
+5^4^3^2,
+@end ifnotdocbook
+@end ifnottex
+@docbook
+5<superscript>4<superscript>3<superscript>2</superscript></superscript></superscript>, @c
+@end docbook
+the result of which is beyond the
+limits of ordinary hardware double-precision floating-point values:
+
+@example
+$ @kbd{gawk -M 'BEGIN @{}
+> @kbd{x = 5^4^3^2}
+> @kbd{print "number of digits =", length(x)}
+> @kbd{print substr(x, 1, 20), "...", substr(x, length(x) - 19, 20)}
+> @kbd{@}'}
+@print{} number of digits = 183231
+@print{} 62060698786608744707 ... 92256259918212890625
+@end example
+
+If instead you were to compute the same value using arbitrary-precision
+floating-point values, the precision needed for correct output (using
+the formula
+@iftex
+@math{prec = 3.322 @cdot dps}),
+would be @math{3.322 @cdot 183231},
+@end iftex
+@ifnottex
+@ifnotdocbook
+@samp{prec = 3.322 * dps}),
+would be 3.322 x 183231,
+@end ifnotdocbook
+@end ifnottex
+@docbook
+<emphasis>prec</emphasis> = 3.322 &sdot; <emphasis>dps</emphasis>),
+would be
+<emphasis>prec</emphasis> = 3.322 &sdot; 183231, @c
+@end docbook
+or 608693.
+
+The result from an arithmetic operation with an integer and a floating-point value
+is a floating-point value with a precision equal to the working precision.
+The following program calculates the eighth term in
+Sylvester's sequence@footnote{Weisstein, Eric W.
+@cite{Sylvester's Sequence}. From MathWorld---A Wolfram Web Resource
+@w{(@url{http://mathworld.wolfram.com/SylvestersSequence.html}).}}
+using a recurrence:
+
+@example
+$ @kbd{gawk -M 'BEGIN @{}
+> @kbd{s = 2.0}
+> @kbd{for (i = 1; i <= 7; i++)}
+> @kbd{s = s * (s - 1) + 1}
+> @kbd{print s}
+> @kbd{@}'}
+@print{} 113423713055421845118910464
+@end example
+
+The output differs from the actual number, 113,423,713,055,421,844,361,000,443,
+because the default precision of 53 bits is not enough to represent the
+floating-point results exactly. You can either increase the precision
+(100 bits is enough in this case), or replace the floating-point constant
+@samp{2.0} with an integer, to perform all computations using integer
+arithmetic to get the correct output.
+
+Sometimes @command{gawk} must implicitly convert an arbitrary-precision
+integer into an arbitrary-precision floating-point value. This is
+primarily because the MPFR library does not always provide the relevant
+interface to process arbitrary-precision integers or mixed-mode numbers
+as needed by an operation or function. In such a case, the precision is
+set to the minimum value necessary for exact conversion, and the working
+precision is not used for this purpose. If this is not what you need or
+want, you can employ a subterfuge, and convert the integer to floating
+point first, like this:
+
+@example
+gawk -M 'BEGIN @{ n = 13; print (n + 0.0) % 2.0 @}'
+@end example
+
+You can avoid this issue altogether by specifying the number as a floating-point value
+to begin with:
+
+@example
+gawk -M 'BEGIN @{ n = 13.0; print n % 2.0 @}'
+@end example
+
+Note that for this particular example, it is likely best
+to just use the following:
+
+@example
+gawk -M 'BEGIN @{ n = 13; print n % 2 @}'
+@end example
+
+When dividing two arbitrary precision integers with either
+@samp{/} or @samp{%}, the result is typically an arbitrary
+precision floating point value (unless the denominator evenly
+divides into the numerator). In order to do integer division
+or remainder with arbitrary precision integers, use the built-in
+@code{div()} function (@pxref{Numeric Functions}).
+
+You can simulate the @code{div()} function in standard @command{awk}
+using this user-defined function:
+
+@example
+@c file eg/lib/div.awk
+# div --- do integer division
+
+@c endfile
+@ignore
+@c file eg/lib/div.awk
+#
+# Arnold Robbins, arnold@@skeeve.com, Public Domain
+# July, 2014
+
+@c endfile
+
+@end ignore
+@c file eg/lib/div.awk
+function div(numerator, denominator, result)
+@{
+ split("", result)
+
+ numerator = int(numerator)
+ denominator = int(denominator)
+ result["quotient"] = int(numerator / denominator)
+ result["remainder"] = int(numerator % denominator)
+
+ return 0.0
+@}
+@c endfile
+@end example
+
+The following example program, contributed by Katie Wasserman,
+uses @code{div()} to
+compute the digits of @value{PI} to as many places as you
+choose to set:
+
+@example
+@c file eg/prog/pi.awk
+# pi.awk --- compute the digits of pi
+@c endfile
+@c endfile
+@ignore
+@c file eg/prog/pi.awk
+#
+# Katie Wasserman, katie@@wass.net
+# August 2014
+@c endfile
+@end ignore
+@c file eg/prog/pi.awk
+
+BEGIN @{
+ digits = 100000
+ two = 2 * 10 ^ digits
+ pi = two
+ for (m = digits * 4; m > 0; --m) @{
+ d = m * 2 + 1
+ x = pi * m
+ div(x, d, result)
+ pi = result["quotient"]
+ pi = pi + two
+ @}
+ print pi
+@}
+@c endfile
+@end example
+
+@ignore
+Date: Wed, 20 Aug 2014 10:19:11 -0400
+To: arnold@skeeve.com
+From: Katherine Wasserman <katie@wass.net>
+Subject: Re: computation of digits of pi?
+
+Arnold,
+
+>The program that you sent to compute the digits of pi using div(). Is
+>that some standard algorithm that every math student knows? If so,
+>what's it called?
+
+It's not that well known but it's not that obscure either
+
+It's Euler's modification to Newton's method for calculating pi.
+
+Take a look at lines (23) - (25) here: http://mathworld.wolfram.com/PiFormulas.htm
+
+The algorithm I wrote simply expands the multiply by 2 and works from the innermost expression outwards. I used this to program HP calculators because it's quite easy to modify for tiny memory devices with smallish word sizes.
+
+http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/articles.cgi?read=899
+
+-Katie
+@end ignore
+
+When asked about the algorithm used, Katie replied:
+
+@quotation
+It's not that well known but it's not that obscure either.
+It's Euler's modification to Newton's method for calculating pi.
+Take a look at lines (23) - (25) here: @uref{http://mathworld.wolfram.com/PiFormulas.htm}.
+
+The algorithm I wrote simply expands the multiply by 2 and works from
+the innermost expression outwards. I used this to program HP calculators
+because it's quite easy to modify for tiny memory devices with smallish
+word sizes. See
+@uref{http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/articles.cgi?read=899}.
+@end quotation
+
+@node POSIX Floating Point Problems
+@section Standards Versus Existing Practice
+
+Historically, @command{awk} has converted any non-numeric looking string
+to the numeric value zero, when required. Furthermore, the original
+definition of the language and the original POSIX standards specified that
+@command{awk} only understands decimal numbers (base 10), and not octal
+(base 8) or hexadecimal numbers (base 16).
+
+Changes in the language of the
+2001 and 2004 POSIX standards can be interpreted to imply that @command{awk}
+should support additional features. These features are:
+
+@itemize @value{BULLET}
+@item
+Interpretation of floating-point data values specified in hexadecimal
+notation (e.g., @code{0xDEADBEEF}). (Note: data values, @emph{not}
+source code constants.)
+
+@item
+Support for the special IEEE 754 floating-point values ``Not A Number''
+(NaN), positive Infinity (``inf''), and negative Infinity (``@minus{}inf'').
+In particular, the format for these values is as specified by the ISO 1999
+C standard, which ignores case and can allow implementation-dependent additional
+characters after the @samp{nan} and allow either @samp{inf} or @samp{infinity}.
+@end itemize
+
+The first problem is that both of these are clear changes to historical
+practice:
+
+@itemize @value{BULLET}
+@item
+The @command{gawk} maintainer feels that supporting hexadecimal
+floating-point values, in particular, is ugly, and was never intended by the
+original designers to be part of the language.
+
+@item
+Allowing completely alphabetic strings to have valid numeric
+values is also a very severe departure from historical practice.
+@end itemize
+
+The second problem is that the @code{gawk} maintainer feels that this
+interpretation of the standard, which requires a certain amount of
+``language lawyering'' to arrive at in the first place, was not even
+intended by the standard developers. In other words, ``we see how you
+got where you are, but we don't think that that's where you want to be.''
+
+Recognizing these issues, but attempting to provide compatibility
+with the earlier versions of the standard,
+the 2008 POSIX standard added explicit wording to allow, but not require,
+that @command{awk} support hexadecimal floating-point values and
+special values for ``Not A Number'' and infinity.
+
+Although the @command{gawk} maintainer continues to feel that
+providing those features is inadvisable,
+nevertheless, on systems that support IEEE floating point, it seems
+reasonable to provide @emph{some} way to support NaN and Infinity values.
+The solution implemented in @command{gawk} is as follows:
+
+@itemize @value{BULLET}
+@item
+With the @option{--posix} command-line option, @command{gawk} becomes
+``hands off.'' String values are passed directly to the system library's
+@code{strtod()} function, and if it successfully returns a numeric value,
+that is what's used.@footnote{You asked for it, you got it.}
+By definition, the results are not portable across
+different systems. They are also a little surprising:
+
+@example
+$ @kbd{echo nanny | gawk --posix '@{ print $1 + 0 @}'}
+@print{} nan
+$ @kbd{echo 0xDeadBeef | gawk --posix '@{ print $1 + 0 @}'}
+@print{} 3735928559
+@end example
+
+@item
+Without @option{--posix}, @command{gawk} interprets the four strings
+@samp{+inf},
+@samp{-inf},
+@samp{+nan},
+and
+@samp{-nan}
+specially, producing the corresponding special numeric values.
+The leading sign acts a signal to @command{gawk} (and the user)
+that the value is really numeric. Hexadecimal floating point is
+not supported (unless you also use @option{--non-decimal-data},
+which is @emph{not} recommended). For example:
+
+@example
+$ @kbd{echo nanny | gawk '@{ print $1 + 0 @}'}
+@print{} 0
+$ @kbd{echo +nan | gawk '@{ print $1 + 0 @}'}
+@print{} nan
+$ @kbd{echo 0xDeadBeef | gawk '@{ print $1 + 0 @}'}
+@print{} 0
+@end example
+
+@command{gawk} ignores case in the four special values.
+Thus @samp{+nan} and @samp{+NaN} are the same.
+@end itemize
+
+@node Floating point summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+Most computer arithmetic is done using either integers or floating-point
+values. Standard @command{awk} uses double-precision
+floating-point values.
+
+@item
+In the early 1990s, Barbie mistakenly said ``Math class is tough!''
+Although math isn't tough, floating-point arithmetic isn't the same
+as pencil and paper math, and care must be taken:
+
+@c nested list
+@itemize @value{MINUS}
+@item
+Not all numbers can be represented exactly.
+
+@item
+Comparing values should use a delta, instead of being done directly
+with @samp{==} and @samp{!=}.
+
+@item
+Errors accumulate.
+
+@item
+Operations are not always truly associative or distributive.
+@end itemize
+
+@item
+Increasing the accuracy can help, but it is not a panacea.
+
+@item
+Often, increasing the accuracy and then rounding to the desired
+number of digits produces reasonable results.
+
+@item
+Use @option{-M} (or @option{--bignum}) to enable MPFR
+arithmetic. Use @code{PREC} to set the precision in bits, and
+@code{ROUNDMODE} to set the IEEE 754 rounding mode.
+
+@item
+With @option{-M}, @command{gawk} performs
+arbitrary-precision integer arithmetic using the GMP library.
+This is faster and more space efficient than using MPFR for
+the same calculations.
+
+@item
+There are several ``dark corners'' with respect to floating-point
+numbers where @command{gawk} disagrees with the POSIX standard.
+It pays to be aware of them.
+
+@item
+Overall, there is no need to be unduly suspicious about the results from
+floating-point arithmetic. The lesson to remember is that floating-point
+arithmetic is always more complex than arithmetic using pencil and
+paper. In order to take advantage of the power of computer floating point,
+you need to know its limitations and work within them. For most casual
+use of floating-point arithmetic, you will often get the expected result
+if you simply round the display of your final results to the correct number
+of significant decimal digits.
+
+@item
+As general advice, avoid presenting numerical data in a manner that
+implies better precision than is actually the case.
+
+@end itemize
+
+@node Dynamic Extensions
+@chapter Writing Extensions for @command{gawk}
+@cindex dynamically loaded extensions
+
+It is possible to add new functions written in C or C++ to @command{gawk} using
+dynamically loaded libraries. This facility is available on systems
+that support the C @code{dlopen()} and @code{dlsym()}
+functions. This @value{CHAPTER} describes how to create extensions
+using code written in C or C++.
+
+If you don't know anything about C programming, you can safely skip this
+@value{CHAPTER}, although you may wish to review the documentation on the
+extensions that come with @command{gawk} (@pxref{Extension Samples}),
+and the information on the @code{gawkextlib} project (@pxref{gawkextlib}).
+The sample extensions are automatically built and installed when
+@command{gawk} is.
+
+@quotation NOTE
+When @option{--sandbox} is specified, extensions are disabled
+(@pxref{Options}).
+@end quotation
+
+@menu
+* Extension Intro:: What is an extension.
+* Plugin License:: A note about licensing.
+* Extension Mechanism Outline:: An outline of how it works.
+* Extension API Description:: A full description of the API.
+* Finding Extensions:: How @command{gawk} finds compiled extensions.
+* Extension Example:: Example C code for an extension.
+* Extension Samples:: The sample extensions that ship with
+ @code{gawk}.
+* gawkextlib:: The @code{gawkextlib} project.
+* Extension summary:: Extension summary.
+* Extension Exercises:: Exercises.
+@end menu
+
+@node Extension Intro
+@section Introduction
+
+@cindex plug-in
+An @dfn{extension} (sometimes called a @dfn{plug-in}) is a piece of
+external compiled code that @command{gawk} can load at runtime to
+provide additional functionality, over and above the built-in capabilities
+described in the rest of this @value{DOCUMENT}.
+
+Extensions are useful because they allow you (of course) to extend
+@command{gawk}'s functionality. For example, they can provide access to
+system calls (such as @code{chdir()} to change directory) and to other
+C library routines that could be of use. As with most software,
+``the sky is the limit;'' if you can imagine something that you might
+want to do and can write in C or C++, you can write an extension to do it!
+
+Extensions are written in C or C++, using the @dfn{application programming
+interface} (API) defined for this purpose by the @command{gawk}
+developers. The rest of this @value{CHAPTER} explains
+the facilities that the API provides and how to use
+them, and presents a small example extension. In addition, it documents
+the sample extensions included in the @command{gawk} distribution,
+and describes the @code{gawkextlib} project.
+@ifclear FOR_PRINT
+@xref{Extension Design}, for a discussion of the extension mechanism
+goals and design.
+@end ifclear
+@ifset FOR_PRINT
+See @uref{http://www.gnu.org/software/gawk/manual/html_node/Extension-Design.html}
+for a discussion of the extension mechanism
+goals and design.
+@end ifset
+
+@node Plugin License
+@section Extension Licensing
+
+Every dynamic extension must be distributed under a license that is
+compatible with the GNU GPL (@pxref{Copying}).
+
+In order for the extension to tell @command{gawk} that it is
+properly licensed, the extension must define the global symbol
+@code{plugin_is_GPL_compatible}. If this symbol does not exist,
+@command{gawk} emits a fatal error and exits when it tries to load
+your extension.
+
+The declared type of the symbol should be @code{int}. It does not need
+to be in any allocated section, though. The code merely asserts that
+the symbol exists in the global scope. Something like this is enough:
+
+@example
+int plugin_is_GPL_compatible;
+@end example
+
+@node Extension Mechanism Outline
+@section How It Works at a High Level
+
+Communication between
+@command{gawk} and an extension is two-way. First, when an extension
+is loaded, @command{gawk} passes it a pointer to a @code{struct} whose fields are
+function pointers.
+@ifnotdocbook
+This is shown in @ref{figure-load-extension}.
+@end ifnotdocbook
+@ifdocbook
+This is shown in @inlineraw{docbook, <xref linkend="figure-load-extension"/>}.
+@end ifdocbook
+
+@ifnotdocbook
+@float Figure,figure-load-extension
+@caption{Loading the extension}
+@c FIXME: One day, it should not be necessary to have two cases,
+@c but rather just the one without the "txt" final argument.
+@c This applies to the other figures as well.
+@ifinfo
+@center @image{api-figure1, , , Loading the extension, txt}
+@end ifinfo
+@ifnotinfo
+@center @image{api-figure1, , , Loading the extension}
+@end ifnotinfo
+@end float
+@end ifnotdocbook
+
+@docbook
+<figure id="figure-load-extension" float="0">
+<title>Loading the extension</title>
+<mediaobject>
+<imageobject role="web"><imagedata fileref="api-figure1.png" format="PNG"/></imageobject>
+</mediaobject>
+</figure>
+@end docbook
+
+The extension can call functions inside @command{gawk} through these
+function pointers, at runtime, without needing (link-time) access
+to @command{gawk}'s symbols. One of these function pointers is to a
+function for ``registering'' new functions.
+@ifnotdocbook
+This is shown in @ref{figure-register-new-function}.
+@end ifnotdocbook
+@ifdocbook
+This is shown in @inlineraw{docbook, <xref linkend="figure-register-new-function"/>}.
+@end ifdocbook
+
+@ifnotdocbook
+@float Figure,figure-register-new-function
+@caption{Registering a new function}
+@ifinfo
+@center @image{api-figure2, , , Registering a new Function, txt}
+@end ifinfo
+@ifnotinfo
+@center @image{api-figure2, , , Registering a new Function}
+@end ifnotinfo
+@end float
+@end ifnotdocbook
+
+@docbook
+<figure id="figure-register-new-function" float="0">
+<title>Registering a new function</title>
+<mediaobject>
+<imageobject role="web"><imagedata fileref="api-figure2.png" format="PNG"/></imageobject>
+</mediaobject>
+</figure>
+@end docbook
+
+In the other direction, the extension registers its new functions
+with @command{gawk} by passing function pointers to the functions that
+provide the new feature (@code{do_chdir()}, for example). @command{gawk}
+associates the function pointer with a name and can then call it, using a
+defined calling convention.
+@ifnotdocbook
+This is shown in @ref{figure-call-new-function}.
+@end ifnotdocbook
+@ifdocbook
+This is shown in @inlineraw{docbook, <xref linkend="figure-call-new-function"/>}.
+@end ifdocbook
+
+@ifnotdocbook
+@float Figure,figure-call-new-function
+@caption{Calling the new function}
+@ifinfo
+@center @image{api-figure3, , , Calling the new function, txt}
+@end ifinfo
+@ifnotinfo
+@center @image{api-figure3, , , Calling the new function}
+@end ifnotinfo
+@end float
+@end ifnotdocbook
+
+@docbook
+<figure id="figure-call-new-function" float="0">
+<title>Calling the new function</title>
+<mediaobject>
+<imageobject role="web"><imagedata fileref="api-figure3.png" format="PNG"/></imageobject>
+</mediaobject>
+</figure>
+@end docbook
+
+The @code{do_@var{xxx}()} function, in turn, then uses the function
+pointers in the API @code{struct} to do its work, such as updating
+variables or arrays, printing messages, setting @code{ERRNO}, and so on.
+
+Convenience macros make calling through the function pointers look
+like regular function calls so that extension code is quite readable
+and understandable.
+
+Although all of this sounds somewhat complicated, the result is that
+extension code is quite straightforward to write and to read. You can
+see this in the sample extension @file{filefuncs.c} (@pxref{Extension
+Example}) and also in the @file{testext.c} code for testing the APIs.
+
+Some other bits and pieces:
+
+@itemize @value{BULLET}
+@item
+The API provides access to @command{gawk}'s @code{do_@var{xxx}} values,
+reflecting command-line options, like @code{do_lint}, @code{do_profiling}
+and so on (@pxref{Extension API Variables}).
+These are informational: an extension cannot affect their values
+inside @command{gawk}. In addition, attempting to assign to them
+produces a compile-time error.
+
+@item
+The API also provides major and minor version numbers, so that an
+extension can check if the @command{gawk} it is loaded with supports the
+facilities it was compiled with. (Version mismatches ``shouldn't''
+happen, but we all know how @emph{that} goes.)
+@DBXREF{Extension Versioning} for details.
+@end itemize
+
+@node Extension API Description
+@section API Description
+@cindex extension API
+
+C or C++ code for an extension must include the header file
+@file{gawkapi.h}, which declares the functions and defines the data
+types used to communicate with @command{gawk}.
+This (rather large) @value{SECTION} describes the API in detail.
+
+@menu
+* Extension API Functions Introduction:: Introduction to the API functions.
+* General Data Types:: The data types.
+* Memory Allocation Functions:: Functions for allocating memory.
+* Constructor Functions:: Functions for creating values.
+* Registration Functions:: Functions to register things with
+ @command{gawk}.
+* Printing Messages:: Functions for printing messages.
+* Updating @code{ERRNO}:: Functions for updating @code{ERRNO}.
+* Requesting Values:: How to get a value.
+* Accessing Parameters:: Functions for accessing parameters.
+* Symbol Table Access:: Functions for accessing global
+ variables.
+* Array Manipulation:: Functions for working with arrays.
+* Extension API Variables:: Variables provided by the API.
+* Extension API Boilerplate:: Boilerplate code for using the API.
+@end menu
+
+@node Extension API Functions Introduction
+@subsection Introduction
+
+Access to facilities within @command{gawk} are made available
+by calling through function pointers passed into your extension.
+
+API function pointers are provided for the following kinds of operations:
+
+@itemize @value{BULLET}
+@item
+Allocating, reallocating, and releasing memory.
+
+@item
+Registration functions. You may register:
+
+@c nested list
+@itemize @value{MINUS}
+@item
+Extension functions
+@item
+Exit callbacks
+@item
+A version string
+@item
+Input parsers
+@item
+Output wrappers
+@item
+Two-way processors
+@end itemize
+
+All of these are discussed in detail, later in this @value{CHAPTER}.
+
+@item
+Printing fatal, warning, and ``lint'' warning messages.
+
+@item
+Updating @code{ERRNO}, or unsetting it.
+
+@item
+Accessing parameters, including converting an undefined parameter into
+an array.
+
+@item
+Symbol table access: retrieving a global variable, creating one,
+or changing one.
+
+@item
+Creating and releasing cached values; this provides an
+efficient way to use values for multiple variables and
+can be a big performance win.
+
+@item
+Manipulating arrays:
+
+@itemize @value{MINUS}
+@item
+Retrieving, adding, deleting, and modifying elements
+
+@item
+Getting the count of elements in an array
+
+@item
+Creating a new array
+
+@item
+Clearing an array
+
+@item
+Flattening an array for easy C style looping over all its indices and elements
+@end itemize
+@end itemize
+
+Some points about using the API:
+
+@itemize @value{BULLET}
+@item
+The following types, macros, and/or functions are referenced
+in @file{gawkapi.h}. For correct use, you must therefore include the
+corresponding standard header file @emph{before} including @file{gawkapi.h}:
+
+@multitable {@code{memset()}, @code{memcpy()}} {@code{<sys/types.h>}}
+@headitem C Entity @tab Header File
+@item @code{EOF} @tab @code{<stdio.h>}
+@item Values for @code{errno} @tab @code{<errno.h>}
+@item @code{FILE} @tab @code{<stdio.h>}
+@item @code{NULL} @tab @code{<stddef.h>}
+@item @code{memcpy()} @tab @code{<string.h>}
+@item @code{memset()} @tab @code{<string.h>}
+@item @code{size_t} @tab @code{<sys/types.h>}
+@item @code{struct stat} @tab @code{<sys/stat.h>}
+@end multitable
+
+Due to portability concerns, especially to systems that are not
+fully standards-compliant, it is your responsibility
+to include the correct files in the correct way. This requirement
+is necessary in order to keep @file{gawkapi.h} clean, instead of becoming
+a portability hodge-podge as can be seen in some parts of
+the @command{gawk} source code.
+
+@item
+The @file{gawkapi.h} file may be included more than once without ill effect.
+Doing so, however, is poor coding practice.
+
+@item
+Although the API only uses ISO C 90 features, there is an exception; the
+``constructor'' functions use the @code{inline} keyword. If your compiler
+does not support this keyword, you should either place
+@samp{-Dinline=''} on your command line, or use the GNU Autotools and include a
+@file{config.h} file in your extensions.
+
+@item
+All pointers filled in by @command{gawk} point to memory
+managed by @command{gawk} and should be treated by the extension as
+read-only. Memory for @emph{all} strings passed into @command{gawk}
+from the extension @emph{must} come from calling one of
+@code{gawk_malloc()}, @code{gawk_calloc()} or @code{gawk_realloc()},
+and is managed by @command{gawk} from then on.
+
+@item
+The API defines several simple @code{struct}s that map values as seen
+from @command{awk}. A value can be a @code{double}, a string, or an
+array (as in multidimensional arrays, or when creating a new array).
+String values maintain both pointer and length, because embedded @sc{nul}
+characters are allowed.
+
+@quotation NOTE
+By intent, strings are maintained using the current multibyte encoding (as
+defined by @env{LC_@var{xxx}} environment variables) and not using wide
+characters. This matches how @command{gawk} stores strings internally
+and also how characters are likely to be input and output from files.
+@end quotation
+
+@item
+When retrieving a value (such as a parameter or that of a global variable
+or array element), the extension requests a specific type (number, string,
+scalar, value cookie, array, or ``undefined''). When the request is
+``undefined,'' the returned value will have the real underlying type.
+
+However, if the request and actual type don't match, the access function
+returns ``false'' and fills in the type of the actual value that is there,
+so that the extension can, e.g., print an error message
+(such as ``scalar passed where array expected'').
+
+@c This is documented in the header file and needs some expanding upon.
+@c The table there should be presented here
+@end itemize
+
+You may call the API functions by using the function pointers
+directly, but the interface is not so pretty. To make extension code look
+more like regular code, the @file{gawkapi.h} header file defines several
+macros that you should use in your code. This @value{SECTION} presents
+the macros as if they were functions.
+
+@node General Data Types
+@subsection General-Purpose Data Types
+
+@cindex Robbins, Arnold
+@cindex Ramey, Chet
+@quotation
+@i{I have a true love/hate relationship with unions.}
+@author Arnold Robbins
+@end quotation
+
+@quotation
+@i{That's the thing about unions: the compiler will arrange things so they
+can accommodate both love and hate.}
+@author Chet Ramey
+@end quotation
+
+The extension API defines a number of simple types and structures for
+general-purpose use. Additional, more specialized, data structures are
+introduced in subsequent @value{SECTION}s, together with the functions
+that use them.
+
+@table @code
+@item typedef void *awk_ext_id_t;
+A value of this type is received from @command{gawk} when an extension is loaded.
+That value must then be passed back to @command{gawk} as the first parameter of
+each API function.
+
+@item #define awk_const @dots{}
+This macro expands to @samp{const} when compiling an extension,
+and to nothing when compiling @command{gawk} itself. This makes
+certain fields in the API data structures unwritable from extension code,
+while allowing @command{gawk} to use them as it needs to.
+
+@item typedef enum awk_bool @{
+@itemx @ @ @ @ awk_false = 0,
+@itemx @ @ @ @ awk_true
+@itemx @} awk_bool_t;
+A simple boolean type.
+
+@item typedef struct awk_string @{
+@itemx @ @ @ @ char *str;@ @ @ @ @ @ /* data */
+@itemx @ @ @ @ size_t len;@ @ @ @ @ /* length thereof, in chars */
+@itemx @} awk_string_t;
+This represents a mutable string. @command{gawk}
+owns the memory pointed to if it supplied
+the value. Otherwise, it takes ownership of the memory pointed to.
+@emph{Such memory must come from calling one of the
+@code{gawk_malloc()}, @code{gawk_calloc()}, or
+@code{gawk_realloc()} functions!}
+
+As mentioned earlier, strings are maintained using the current
+multibyte encoding.
+
+@item typedef enum @{
+@itemx @ @ @ @ AWK_UNDEFINED,
+@itemx @ @ @ @ AWK_NUMBER,
+@itemx @ @ @ @ AWK_STRING,
+@itemx @ @ @ @ AWK_ARRAY,
+@itemx @ @ @ @ AWK_SCALAR,@ @ @ @ @ @ @ @ @ /* opaque access to a variable */
+@itemx @ @ @ @ AWK_VALUE_COOKIE@ @ @ @ /* for updating a previously created value */
+@itemx @} awk_valtype_t;
+This @code{enum} indicates the type of a value.
+It is used in the following @code{struct}.
+
+@item typedef struct awk_value @{
+@itemx @ @ @ @ awk_valtype_t val_type;
+@itemx @ @ @ @ union @{
+@itemx @ @ @ @ @ @ @ @ awk_string_t@ @ @ @ @ @ @ s;
+@itemx @ @ @ @ @ @ @ @ double@ @ @ @ @ @ @ @ @ @ @ @ @ d;
+@itemx @ @ @ @ @ @ @ @ awk_array_t@ @ @ @ @ @ @ @ a;
+@itemx @ @ @ @ @ @ @ @ awk_scalar_t@ @ @ @ @ @ @ scl;
+@itemx @ @ @ @ @ @ @ @ awk_value_cookie_t@ vc;
+@itemx @ @ @ @ @} u;
+@itemx @} awk_value_t;
+An ``@command{awk} value.''
+The @code{val_type} member indicates what kind of value the
+@code{union} holds, and each member is of the appropriate type.
+
+@item #define str_value@ @ @ @ @ @ u.s
+@itemx #define num_value@ @ @ @ @ @ u.d
+@itemx #define array_cookie@ @ @ u.a
+@itemx #define scalar_cookie@ @ u.scl
+@itemx #define value_cookie@ @ @ u.vc
+These macros make accessing the fields of the @code{awk_value_t} more
+readable.
+
+@item typedef void *awk_scalar_t;
+Scalars can be represented as an opaque type. These values are obtained
+from @command{gawk} and then passed back into it. This is discussed
+in a general fashion in the text following this list, and in more detail in
+@ref{Symbol table by cookie}.
+
+@item typedef void *awk_value_cookie_t;
+A ``value cookie'' is an opaque type representing a cached value.
+This is also discussed in a general fashion in the text following this list,
+and in more detail in @ref{Cached values}.
+
+@end table
+
+Scalar values in @command{awk} are either numbers or strings. The
+@code{awk_value_t} struct represents values. The @code{val_type} member
+indicates what is in the @code{union}.
+
+Representing numbers is easy---the API uses a C @code{double}. Strings
+require more work. Because @command{gawk} allows embedded @sc{nul} bytes
+in string values, a string must be represented as a pair containing a
+data-pointer and length. This is the @code{awk_string_t} type.
+
+Identifiers (i.e., the names of global variables) can be associated
+with either scalar values or with arrays. In addition, @command{gawk}
+provides true arrays of arrays, where any given array element can
+itself be an array. Discussion of arrays is delayed until
+@ref{Array Manipulation}.
+
+The various macros listed earlier make it easier to use the elements
+of the @code{union} as if they were fields in a @code{struct}; this
+is a common coding practice in C. Such code is easier to write and to
+read, but it remains @emph{your} responsibility to make sure that
+the @code{val_type} member correctly reflects the type of the value in
+the @code{awk_value_t}.
+
+Conceptually, the first three members of the @code{union} (number, string,
+and array) are all that is needed for working with @command{awk} values.
+However, because the API provides routines for accessing and changing
+the value of global scalar variables only by using the variable's name,
+there is a performance penalty: @command{gawk} must find the variable
+each time it is accessed and changed. This turns out to be a real issue,
+not just a theoretical one.
+
+Thus, if you know that your extension will spend considerable time
+reading and/or changing the value of one or more scalar variables, you
+can obtain a @dfn{scalar cookie}@footnote{See
+@uref{http://catb.org/jargon/html/C/cookie.html, the ``cookie'' entry in the Jargon file} for a
+definition of @dfn{cookie}, and @uref{http://catb.org/jargon/html/M/magic-cookie.html,
+the ``magic cookie'' entry in the Jargon file} for a nice example.
+@ifclear FOR_PRINT
+See also the entry for ``Cookie'' in the @ref{Glossary}.
+@end ifclear
+}
+object for that variable, and then use
+the cookie for getting the variable's value or for changing the variable's
+value.
+This is the @code{awk_scalar_t} type and @code{scalar_cookie} macro.
+Given a scalar cookie, @command{gawk} can directly retrieve or
+modify the value, as required, without having to find it first.
+
+The @code{awk_value_cookie_t} type and @code{value_cookie} macro are similar.
+If you know that you wish to
+use the same numeric or string @emph{value} for one or more variables,
+you can create the value once, retaining a @dfn{value cookie} for it,
+and then pass in that value cookie whenever you wish to set the value of a
+variable. This saves both storage space within the running @command{gawk}
+process as well as the time needed to create the value.
+
+@node Memory Allocation Functions
+@subsection Memory Allocation Functions and Convenience Macros
+@cindex allocating memory for extensions
+@cindex extensions, allocating memory
+
+The API provides a number of @dfn{memory allocation} functions for
+allocating memory that can be passed to @command{gawk}, as well as a number of
+convenience macros.
+This @value{SUBSECTION} presents them all as function prototypes, in
+the way that extension code would use them:
+
+@table @code
+@item void *gawk_malloc(size_t size);
+Call the correct version of @code{malloc()} to allocate storage that may
+be passed to @command{gawk}.
+
+@item void *gawk_calloc(size_t nmemb, size_t size);
+Call the correct version of @code{calloc()} to allocate storage that may
+be passed to @command{gawk}.
+
+@item void *gawk_realloc(void *ptr, size_t size);
+Call the correct version of @code{realloc()} to allocate storage that may
+be passed to @command{gawk}.
+
+@item void gawk_free(void *ptr);
+Call the correct version of @code{free()} to release storage that was
+allocated with @code{gawk_malloc()}, @code{gawk_calloc()} or @code{gawk_realloc()}.
+@end table
+
+The API has to provide these functions because it is possible
+for an extension to be compiled and linked against a different
+version of the C library than was used for the @command{gawk}
+executable.@footnote{This is more common on MS-Windows systems, but
+can happen on Unix-like systems as well.} If @command{gawk} were
+to use its version of @code{free()} when the memory came from an
+unrelated version of @code{malloc()}, unexpected behavior would
+likely result.
+
+Two convenience macros may be used for allocating storage
+from @code{gawk_malloc()} and
+@code{gawk_realloc()}. If the allocation fails, they cause @command{gawk}
+to exit with a fatal error message. They should be used as if they were
+procedure calls that do not return a value.
+
+@table @code
+@item #define emalloc(pointer, type, size, message) @dots{}
+The arguments to this macro are as follows:
+
+@c nested table
+@table @code
+@item pointer
+The pointer variable to point at the allocated storage.
+
+@item type
+The type of the pointer variable. This is used to create a cast for
+the call to @code{gawk_malloc()}.
+
+@item size
+The total number of bytes to be allocated.
+
+@item message
+A message to be prefixed to the fatal error message. Typically this is the name
+of the function using the macro.
+@end table
+
+@noindent
+For example, you might allocate a string value like so:
+
+@example
+awk_value_t result;
+char *message;
+const char greet[] = "Don't Panic!";
+
+emalloc(message, char *, sizeof(greet), "myfunc");
+strcpy(message, greet);
+make_malloced_string(message, strlen(message), & result);
+@end example
+
+@item #define erealloc(pointer, type, size, message) @dots{}
+This is like @code{emalloc()}, but it calls @code{gawk_realloc()},
+instead of @code{gawk_malloc()}.
+The arguments are the same as for the @code{emalloc()} macro.
+@end table
+
+@node Constructor Functions
+@subsection Constructor Functions
+
+The API provides a number of @dfn{constructor} functions for creating
+string and numeric values, as well as a number of convenience macros.
+This @value{SUBSECTION} presents them all as function prototypes, in
+the way that extension code would use them:
+
+@table @code
+@item static inline awk_value_t *
+@itemx make_const_string(const char *string, size_t length, awk_value_t *result)
+This function creates a string value in the @code{awk_value_t} variable
+pointed to by @code{result}. It expects @code{string} to be a C string constant
+(or other string data), and automatically creates a @emph{copy} of the data
+for storage in @code{result}. It returns @code{result}.
+
+@item static inline awk_value_t *
+@itemx make_malloced_string(const char *string, size_t length, awk_value_t *result)
+This function creates a string value in the @code{awk_value_t} variable
+pointed to by @code{result}. It expects @code{string} to be a @samp{char *}
+value pointing to data previously obtained from @code{gawk_malloc()}, @code{gawk_calloc()} or @code{gawk_realloc()}. The idea here
+is that the data is passed directly to @command{gawk}, which assumes
+responsibility for it. It returns @code{result}.
+
+@item static inline awk_value_t *
+@itemx make_null_string(awk_value_t *result)
+This specialized function creates a null string (the ``undefined'' value)
+in the @code{awk_value_t} variable pointed to by @code{result}.
+It returns @code{result}.
+
+@item static inline awk_value_t *
+@itemx make_number(double num, awk_value_t *result)
+This function simply creates a numeric value in the @code{awk_value_t} variable
+pointed to by @code{result}.
+@end table
+
+@node Registration Functions
+@subsection Registration Functions
+@cindex register extension
+@cindex extension registration
+
+This @value{SECTION} describes the API functions for
+registering parts of your extension with @command{gawk}.
+
+@menu
+* Extension Functions:: Registering extension functions.
+* Exit Callback Functions:: Registering an exit callback.
+* Extension Version String:: Registering a version string.
+* Input Parsers:: Registering an input parser.
+* Output Wrappers:: Registering an output wrapper.
+* Two-way processors:: Registering a two-way processor.
+@end menu
+
+@node Extension Functions
+@subsubsection Registering An Extension Function
+
+Extension functions are described by the following record:
+
+@example
+typedef struct awk_ext_func @{
+@ @ @ @ const char *name;
+@ @ @ @ awk_value_t *(*function)(int num_actual_args, awk_value_t *result);
+@ @ @ @ size_t num_expected_args;
+@} awk_ext_func_t;
+@end example
+
+The fields are:
+
+@table @code
+@item const char *name;
+The name of the new function.
+@command{awk} level code calls the function by this name.
+This is a regular C string.
+
+Function names must obey the rules for @command{awk}
+identifiers. That is, they must begin with either an English letter
+or an underscore, which may be followed by any number of
+letters, digits, and underscores.
+Letter case in function names is significant.
+
+@item awk_value_t *(*function)(int num_actual_args, awk_value_t *result);
+This is a pointer to the C function that provides the extension's
+functionality.
+The function must fill in @code{*result} with either a number
+or a string. @command{gawk} takes ownership of any string memory.
+As mentioned earlier, string memory @strong{must} come from one of
+@code{gawk_malloc()}, @code{gawk_calloc()}, or @code{gawk_realloc()}.
+
+The @code{num_actual_args} argument tells the C function how many
+actual parameters were passed from the calling @command{awk} code.
+
+The function must return the value of @code{result}.
+This is for the convenience of the calling code inside @command{gawk}.
+
+@item size_t num_expected_args;
+This is the number of arguments the function expects to receive.
+Each extension function may decide what to do if the number of
+arguments isn't what it expected. As with real @command{awk} functions, it
+is likely OK to ignore extra arguments.
+@end table
+
+Once you have a record representing your extension function, you register
+it with @command{gawk} using this API function:
+
+@table @code
+@item awk_bool_t add_ext_func(const char *namespace, const awk_ext_func_t *func);
+This function returns true upon success, false otherwise.
+The @code{namespace} parameter is currently not used; you should pass in an
+empty string (@code{""}). The @code{func} pointer is the address of a
+@code{struct} representing your function, as just described.
+@end table
+
+@node Exit Callback Functions
+@subsubsection Registering An Exit Callback Function
+
+An @dfn{exit callback} function is a function that
+@command{gawk} calls before it exits.
+Such functions are useful if you have general ``cleanup'' tasks
+that should be performed in your extension (such as closing database
+connections or other resource deallocations).
+You can register such
+a function with @command{gawk} using the following function:
+
+@table @code
+@item void awk_atexit(void (*funcp)(void *data, int exit_status),
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ void *arg0);
+The parameters are:
+
+@c nested table
+@table @code
+@item funcp
+A pointer to the function to be called before @command{gawk} exits. The @code{data}
+parameter will be the original value of @code{arg0}.
+The @code{exit_status} parameter is the exit status value that
+@command{gawk} intends to pass to the @code{exit()} system call.
+
+@item arg0
+A pointer to private data which @command{gawk} saves in order to pass to
+the function pointed to by @code{funcp}.
+@end table
+@end table
+
+Exit callback functions are called in last-in-first-out (LIFO)
+order---that is, in the reverse order in which they are registered with
+@command{gawk}.
+
+@node Extension Version String
+@subsubsection Registering An Extension Version String
+
+You can register a version string which indicates the name and
+version of your extension, with @command{gawk}, as follows:
+
+@table @code
+@item void register_ext_version(const char *version);
+Register the string pointed to by @code{version} with @command{gawk}.
+Note that @command{gawk} does @emph{not} copy the @code{version} string, so
+it should not be changed.
+@end table
+
+@command{gawk} prints all registered extension version strings when it
+is invoked with the @option{--version} option.
+
+@node Input Parsers
+@subsubsection Customized Input Parsers
+@cindex customized input parser
+
+By default, @command{gawk} reads text files as its input. It uses the value
+of @code{RS} to find the end of the record, and then uses @code{FS}
+(or @code{FIELDWIDTHS} or @code{FPAT}) to split it into fields (@pxref{Reading Files}).
+Additionally, it sets the value of @code{RT} (@pxref{Built-in Variables}).
+
+If you want, you can provide your own custom input parser. An input
+parser's job is to return a record to the @command{gawk} record processing
+code, along with indicators for the value and length of the data to be
+used for @code{RT}, if any.
+
+To provide an input parser, you must first provide two functions
+(where @var{XXX} is a prefix name for your extension):
+
+@table @code
+@item awk_bool_t @var{XXX}_can_take_file(const awk_input_buf_t *iobuf);
+This function examines the information available in @code{iobuf}
+(which we discuss shortly). Based on the information there, it
+decides if the input parser should be used for this file.
+If so, it should return true. Otherwise, it should return false.
+It should not change any state (variable values, etc.) within @command{gawk}.
+
+@item awk_bool_t @var{XXX}_take_control_of(awk_input_buf_t *iobuf);
+When @command{gawk} decides to hand control of the file over to the
+input parser, it calls this function. This function in turn must fill
+in certain fields in the @code{awk_input_buf_t} structure, and ensure
+that certain conditions are true. It should then return true. If an
+error of some kind occurs, it should not fill in any fields, and should
+return false; then @command{gawk} will not use the input parser.
+The details are presented shortly.
+@end table
+
+Your extension should package these functions inside an
+@code{awk_input_parser_t}, which looks like this:
+
+@example
+typedef struct awk_input_parser @{
+ const char *name; /* name of parser */
+ awk_bool_t (*can_take_file)(const awk_input_buf_t *iobuf);
+ awk_bool_t (*take_control_of)(awk_input_buf_t *iobuf);
+ awk_const struct awk_input_parser *awk_const next; /* for gawk */
+@} awk_input_parser_t;
+@end example
+
+The fields are:
+
+@table @code
+@item const char *name;
+The name of the input parser. This is a regular C string.
+
+@item awk_bool_t (*can_take_file)(const awk_input_buf_t *iobuf);
+A pointer to your @code{@var{XXX}_can_take_file()} function.
+
+@item awk_bool_t (*take_control_of)(awk_input_buf_t *iobuf);
+A pointer to your @code{@var{XXX}_take_control_of()} function.
+
+@item awk_const struct input_parser *awk_const next;
+This is for use by @command{gawk};
+therefore it is marked @code{awk_const} so that the extension cannot
+modify it.
+@end table
+
+The steps are as follows:
+
+@enumerate
+@item
+Create a @code{static awk_input_parser_t} variable and initialize it
+appropriately.
+
+@item
+When your extension is loaded, register your input parser with
+@command{gawk} using the @code{register_input_parser()} API function
+(described next).
+@end enumerate
+
+An @code{awk_input_buf_t} looks like this:
+
+@example
+typedef struct awk_input @{
+ const char *name; /* filename */
+ int fd; /* file descriptor */
+#define INVALID_HANDLE (-1)
+ void *opaque; /* private data for input parsers */
+ int (*get_record)(char **out, struct awk_input *iobuf,
+ int *errcode, char **rt_start, size_t *rt_len);
+ ssize_t (*read_func)();
+ void (*close_func)(struct awk_input *iobuf);
+ struct stat sbuf; /* stat buf */
+@} awk_input_buf_t;
+@end example
+
+The fields can be divided into two categories: those for use (initially,
+at least) by @code{@var{XXX}_can_take_file()}, and those for use by
+@code{@var{XXX}_take_control_of()}. The first group of fields and their uses
+are as follows:
+
+@table @code
+@item const char *name;
+The name of the file.
+
+@item int fd;
+A file descriptor for the file. If @command{gawk} was able to
+open the file, then @code{fd} will @emph{not} be equal to
+@code{INVALID_HANDLE}. Otherwise, it will.
+
+@item struct stat sbuf;
+If the file descriptor is valid, then @command{gawk} will have filled
+in this structure via a call to the @code{fstat()} system call.
+@end table
+
+The @code{@var{XXX}_can_take_file()} function should examine these
+fields and decide if the input parser should be used for the file.
+The decision can be made based upon @command{gawk} state (the value
+of a variable defined previously by the extension and set by
+@command{awk} code), the name of the
+file, whether or not the file descriptor is valid, the information
+in the @code{struct stat}, or any combination of these factors.
+
+Once @code{@var{XXX}_can_take_file()} has returned true, and
+@command{gawk} has decided to use your input parser, it calls
+@code{@var{XXX}_take_control_of()}. That function then fills one of
+either the @code{get_record} field or the @code{read_func} field in
+the @code{awk_input_buf_t}. It must also ensure that @code{fd} is @emph{not}
+set to @code{INVALID_HANDLE}. The following list describes the fields that
+may be filled by @code{@var{XXX}_take_control_of()}:
+
+@table @code
+@item void *opaque;
+This is used to hold any state information needed by the input parser
+for this file. It is ``opaque'' to @command{gawk}. The input parser
+is not required to use this pointer.
+
+@item int@ (*get_record)(char@ **out,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ struct@ awk_input *iobuf,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ int *errcode,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ char **rt_start,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ size_t *rt_len);
+This function pointer should point to a function that creates the input
+records. Said function is the core of the input parser. Its behavior
+is described in the text following this list.
+
+@item ssize_t (*read_func)();
+This function pointer should point to function that has the
+same behavior as the standard POSIX @code{read()} system call.
+It is an alternative to the @code{get_record} pointer. Its behavior
+is also described in the text following this list.
+
+@item void (*close_func)(struct awk_input *iobuf);
+This function pointer should point to a function that does
+the ``tear down.'' It should release any resources allocated by
+@code{@var{XXX}_take_control_of()}. It may also close the file. If it
+does so, it should set the @code{fd} field to @code{INVALID_HANDLE}.
+
+If @code{fd} is still not @code{INVALID_HANDLE} after the call to this
+function, @command{gawk} calls the regular @code{close()} system call.
+
+Having a ``tear down'' function is optional. If your input parser does
+not need it, do not set this field. Then, @command{gawk} calls the
+regular @code{close()} system call on the file descriptor, so it should
+be valid.
+@end table
+
+The @code{@var{XXX}_get_record()} function does the work of creating
+input records. The parameters are as follows:
+
+@table @code
+@item char **out
+This is a pointer to a @code{char *} variable which is set to point
+to the record. @command{gawk} makes its own copy of the data, so
+the extension must manage this storage.
+
+@item struct awk_input *iobuf
+This is the @code{awk_input_buf_t} for the file. The fields should be
+used for reading data (@code{fd}) and for managing private state
+(@code{opaque}), if any.
+
+@item int *errcode
+If an error occurs, @code{*errcode} should be set to an appropriate
+code from @code{<errno.h>}.
+
+@item char **rt_start
+@itemx size_t *rt_len
+If the concept of a ``record terminator'' makes sense, then
+@code{*rt_start} should be set to point to the data to be used for
+@code{RT}, and @code{*rt_len} should be set to the length of the
+data. Otherwise, @code{*rt_len} should be set to zero.
+@code{gawk} makes its own copy of this data, so the
+extension must manage this storage.
+@end table
+
+The return value is the length of the buffer pointed to by
+@code{*out}, or @code{EOF} if end-of-file was reached or an
+error occurred.
+
+It is guaranteed that @code{errcode} is a valid pointer, so there is no
+need to test for a @code{NULL} value. @command{gawk} sets @code{*errcode}
+to zero, so there is no need to set it unless an error occurs.
+
+If an error does occur, the function should return @code{EOF} and set
+@code{*errcode} to a value greater than zero. In that case, if @code{*errcode}
+does not equal zero, @command{gawk} automatically updates
+the @code{ERRNO} variable based on the value of @code{*errcode}.
+(In general, setting @samp{*errcode = errno} should do the right thing.)
+
+As an alternative to supplying a function that returns an input record,
+you may instead supply a function that simply reads bytes, and let
+@command{gawk} parse the data into records. If you do so, the data
+should be returned in the multibyte encoding of the current locale.
+Such a function should follow the same behavior as the @code{read()}
+system call, and you fill in the @code{read_func} pointer with its
+address in the @code{awk_input_buf_t} structure.
+
+By default, @command{gawk} sets the @code{read_func} pointer to
+point to the @code{read()} system call. So your extension need not
+set this field explicitly.
+
+@quotation NOTE
+You must choose one method or the other: either a function that
+returns a record, or one that returns raw data. In particular,
+if you supply a function to get a record, @command{gawk} will
+call it, and never call the raw read function.
+@end quotation
+
+@command{gawk} ships with a sample extension that reads directories,
+returning records for each entry in the directory (@pxref{Extension
+Sample Readdir}). You may wish to use that code as a guide for writing
+your own input parser.
+
+When writing an input parser, you should think about (and document)
+how it is expected to interact with @command{awk} code. You may want
+it to always be called, and take effect as appropriate (as the
+@code{readdir} extension does). Or you may want it to take effect
+based upon the value of an @code{awk} variable, as the XML extension
+from the @code{gawkextlib} project does (@pxref{gawkextlib}).
+In the latter case, code in a @code{BEGINFILE} section
+can look at @code{FILENAME} and @code{ERRNO} to decide whether or
+not to activate an input parser (@pxref{BEGINFILE/ENDFILE}).
+
+You register your input parser with the following function:
+
+@table @code
+@item void register_input_parser(awk_input_parser_t *input_parser);
+Register the input parser pointed to by @code{input_parser} with
+@command{gawk}.
+@end table
+
+@node Output Wrappers
+@subsubsection Customized Output Wrappers
+@cindex customized output wrapper
+
+@cindex output wrapper
+An @dfn{output wrapper} is the mirror image of an input parser.
+It allows an extension to take over the output to a file opened
+with the @samp{>} or @samp{>>} I/O redirection operators (@pxref{Redirection}).
+
+The output wrapper is very similar to the input parser structure:
+
+@example
+typedef struct awk_output_wrapper @{
+ const char *name; /* name of the wrapper */
+ awk_bool_t (*can_take_file)(const awk_output_buf_t *outbuf);
+ awk_bool_t (*take_control_of)(awk_output_buf_t *outbuf);
+ awk_const struct awk_output_wrapper *awk_const next; /* for gawk */
+@} awk_output_wrapper_t;
+@end example
+
+The members are as follows:
+
+@table @code
+@item const char *name;
+This is the name of the output wrapper.
+
+@item awk_bool_t (*can_take_file)(const awk_output_buf_t *outbuf);
+This points to a function that examines the information in
+the @code{awk_output_buf_t} structure pointed to by @code{outbuf}.
+It should return true if the output wrapper wants to take over the
+file, and false otherwise. It should not change any state (variable
+values, etc.) within @command{gawk}.
+
+@item awk_bool_t (*take_control_of)(awk_output_buf_t *outbuf);
+The function pointed to by this field is called when @command{gawk}
+decides to let the output wrapper take control of the file. It should
+fill in appropriate members of the @code{awk_output_buf_t} structure,
+as described next, and return true if successful, false otherwise.
+
+@item awk_const struct output_wrapper *awk_const next;
+This is for use by @command{gawk};
+therefore it is marked @code{awk_const} so that the extension cannot
+modify it.
+@end table
+
+The @code{awk_output_buf_t} structure looks like this:
+
+@example
+typedef struct awk_output_buf @{
+ const char *name; /* name of output file */
+ const char *mode; /* mode argument to fopen */
+ FILE *fp; /* stdio file pointer */
+ awk_bool_t redirected; /* true if a wrapper is active */
+ void *opaque; /* for use by output wrapper */
+ size_t (*gawk_fwrite)(const void *buf, size_t size, size_t count,
+ FILE *fp, void *opaque);
+ int (*gawk_fflush)(FILE *fp, void *opaque);
+ int (*gawk_ferror)(FILE *fp, void *opaque);
+ int (*gawk_fclose)(FILE *fp, void *opaque);
+@} awk_output_buf_t;
+@end example
+
+Here too, your extension will define @code{@var{XXX}_can_take_file()}
+and @code{@var{XXX}_take_control_of()} functions that examine and update
+data members in the @code{awk_output_buf_t}.
+The data members are as follows:
+
+@table @code
+@item const char *name;
+The name of the output file.
+
+@item const char *mode;
+The mode string (as would be used in the second argument to @code{fopen()})
+with which the file was opened.
+
+@item FILE *fp;
+The @code{FILE} pointer from @code{<stdio.h>}. @command{gawk} opens the file
+before attempting to find an output wrapper.
+
+@item awk_bool_t redirected;
+This field must be set to true by the @code{@var{XXX}_take_control_of()} function.
+
+@item void *opaque;
+This pointer is opaque to @command{gawk}. The extension should use it to store
+a pointer to any private data associated with the file.
+
+@item size_t (*gawk_fwrite)(const void *buf, size_t size, size_t count,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ FILE *fp, void *opaque);
+@itemx int (*gawk_fflush)(FILE *fp, void *opaque);
+@itemx int (*gawk_ferror)(FILE *fp, void *opaque);
+@itemx int (*gawk_fclose)(FILE *fp, void *opaque);
+These pointers should be set to point to functions that perform
+the equivalent function as the @code{<stdio.h>} functions do, if appropriate.
+@command{gawk} uses these function pointers for all output.
+@command{gawk} initializes the pointers to point to internal, ``pass through''
+functions that just call the regular @code{<stdio.h>} functions, so an
+extension only needs to redefine those functions that are appropriate for
+what it does.
+@end table
+
+The @code{@var{XXX}_can_take_file()} function should make a decision based
+upon the @code{name} and @code{mode} fields, and any additional state
+(such as @command{awk} variable values) that is appropriate.
+
+When @command{gawk} calls @code{@var{XXX}_take_control_of()}, that function should fill
+in the other fields, as appropriate, except for @code{fp}, which it should just
+use normally.
+
+You register your output wrapper with the following function:
+
+@table @code
+@item void register_output_wrapper(awk_output_wrapper_t *output_wrapper);
+Register the output wrapper pointed to by @code{output_wrapper} with
+@command{gawk}.
+@end table
+
+@node Two-way processors
+@subsubsection Customized Two-way Processors
+@cindex customized two-way processor
+
+A @dfn{two-way processor} combines an input parser and an output wrapper for
+two-way I/O with the @samp{|&} operator (@pxref{Redirection}). It makes identical
+use of the @code{awk_input_parser_t} and @code{awk_output_buf_t} structures
+as described earlier.
+
+A two-way processor is represented by the following structure:
+
+@example
+typedef struct awk_two_way_processor @{
+ const char *name; /* name of the two-way processor */
+ awk_bool_t (*can_take_two_way)(const char *name);
+ awk_bool_t (*take_control_of)(const char *name,
+ awk_input_buf_t *inbuf,
+ awk_output_buf_t *outbuf);
+ awk_const struct awk_two_way_processor *awk_const next; /* for gawk */
+@} awk_two_way_processor_t;
+@end example
+
+The fields are as follows:
+
+@table @code
+@item const char *name;
+The name of the two-way processor.
+
+@item awk_bool_t (*can_take_two_way)(const char *name);
+This function returns true if it wants to take over two-way I/O for this @value{FN}.
+It should not change any state (variable
+values, etc.) within @command{gawk}.
+
+@item awk_bool_t (*take_control_of)(const char *name,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_input_buf_t *inbuf,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_output_buf_t *outbuf);
+This function should fill in the @code{awk_input_buf_t} and
+@code{awk_outut_buf_t} structures pointed to by @code{inbuf} and
+@code{outbuf}, respectively. These structures were described earlier.
+
+@item awk_const struct two_way_processor *awk_const next;
+This is for use by @command{gawk};
+therefore it is marked @code{awk_const} so that the extension cannot
+modify it.
+@end table
+
+As with the input parser and output processor, you provide
+``yes I can take this'' and ``take over for this'' functions,
+@code{@var{XXX}_can_take_two_way()} and @code{@var{XXX}_take_control_of()}.
+
+You register your two-way processor with the following function:
+
+@table @code
+@item void register_two_way_processor(awk_two_way_processor_t *two_way_processor);
+Register the two-way processor pointed to by @code{two_way_processor} with
+@command{gawk}.
+@end table
+
+@node Printing Messages
+@subsection Printing Messages
+@cindex printing messages from extensions
+@cindex messages from extensions
+
+You can print different kinds of warning messages from your
+extension, as described here. Note that for these functions,
+you must pass in the extension id received from @command{gawk}
+when the extension was loaded:@footnote{Because the API uses only ISO C 90
+features, it cannot make use of the ISO C 99 variadic macro feature to hide
+that parameter. More's the pity.}
+
+@table @code
+@item void fatal(awk_ext_id_t id, const char *format, ...);
+Print a message and then cause @command{gawk} to exit immediately.
+
+@item void warning(awk_ext_id_t id, const char *format, ...);
+Print a warning message.
+
+@item void lintwarn(awk_ext_id_t id, const char *format, ...);
+Print a ``lint warning.'' Normally this is the same as printing a
+warning message, but if @command{gawk} was invoked with @samp{--lint=fatal},
+then lint warnings become fatal error messages.
+@end table
+
+All of these functions are otherwise like the C @code{printf()}
+family of functions, where the @code{format} parameter is a string
+with literal characters and formatting codes intermixed.
+
+@node Updating @code{ERRNO}
+@subsection Updating @code{ERRNO}
+
+The following functions allow you to update the @code{ERRNO}
+variable:
+
+@table @code
+@item void update_ERRNO_int(int errno_val);
+Set @code{ERRNO} to the string equivalent of the error code
+in @code{errno_val}. The value should be one of the defined
+error codes in @code{<errno.h>}, and @command{gawk} turns it
+into a (possibly translated) string using the C @code{strerror()} function.
+
+@item void update_ERRNO_string(const char *string);
+Set @code{ERRNO} directly to the string value of @code{ERRNO}.
+@command{gawk} makes a copy of the value of @code{string}.
+
+@item void unset_ERRNO(void);
+Unset @code{ERRNO}.
+@end table
+
+@node Requesting Values
+@subsection Requesting Values
+
+All of the functions that return values from @command{gawk}
+work in the same way. You pass in an @code{awk_valtype_t} value
+to indicate what kind of value you expect. If the actual value
+matches what you requested, the function returns true and fills
+in the @code{awk_value_t} result.
+Otherwise, the function returns false, and the @code{val_type}
+member indicates the type of the actual value. You may then
+print an error message, or reissue the request for the actual
+value type, as appropriate. This behavior is summarized in
+@ref{table-value-types-returned}.
+
+@float Table,table-value-types-returned
+@caption{API value types returned}
+@docbook
+<informaltable>
+<tgroup cols="6">
+ <colspec colwidth="16.6*"/>
+ <colspec colwidth="16.6*"/>
+ <colspec colwidth="19.8*" colname="c3"/>
+ <colspec colwidth="15*" colname="c4"/>
+ <colspec colwidth="15*" colname="c5"/>
+ <colspec colwidth="16.6*" colname="c6"/>
+ <spanspec spanname="hspan" namest="c3" nameend="c6" align="center"/>
+ <thead>
+ <row><entry></entry><entry spanname="hspan"><para>Type of Actual Value</para></entry></row>
+ <row>
+ <entry></entry>
+ <entry></entry>
+ <entry><para>String</para></entry>
+ <entry><para>Number</para></entry>
+ <entry><para>Array</para></entry>
+ <entry><para>Undefined</para></entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry></entry>
+ <entry><para><emphasis role="bold">String</emphasis></para></entry>
+ <entry><para>String</para></entry>
+ <entry><para>String</para></entry>
+ <entry><para>false</para></entry>
+ <entry><para>false</para></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry><para><emphasis role="bold">Number</emphasis></para></entry>
+ <entry><para>Number if can be converted, else false</para></entry>
+ <entry><para>Number</para></entry>
+ <entry><para>false</para></entry>
+ <entry><para>false</para></entry>
+ </row>
+ <row>
+ <entry><para><emphasis role="bold">Type</emphasis></para></entry>
+ <entry><para><emphasis role="bold">Array</emphasis></para></entry>
+ <entry><para>false</para></entry>
+ <entry><para>false</para></entry>
+ <entry><para>Array</para></entry>
+ <entry><para>false</para></entry>
+ </row>
+ <row>
+ <entry><para><emphasis role="bold">Requested</emphasis></para></entry>
+ <entry><para><emphasis role="bold">Scalar</emphasis></para></entry>
+ <entry><para>Scalar</para></entry>
+ <entry><para>Scalar</para></entry>
+ <entry><para>false</para></entry>
+ <entry><para>false</para></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry><para><emphasis role="bold">Undefined</emphasis></para></entry>
+ <entry><para>String</para></entry>
+ <entry><para>Number</para></entry>
+ <entry><para>Array</para></entry>
+ <entry><para>Undefined</para></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry><para><emphasis role="bold">Value Cookie</emphasis></para></entry>
+ <entry><para>false</para></entry>
+ <entry><para>false</para></entry>
+ <entry><para>false</para>
+ </entry><entry><para>false</para></entry>
+ </row>
+ </tbody>
+</tgroup>
+</informaltable>
+@end docbook
+
+@ifnotplaintext
+@ifnotdocbook
+@multitable @columnfractions .50 .50
+@headitem @tab Type of Actual Value
+@end multitable
+@c 10/2014: Thanks to Karl Berry for this bit to reduce the space:
+@tex
+\vglue-1.1\baselineskip
+@end tex
+@multitable @columnfractions .166 .166 .198 .15 .15 .166
+@headitem @tab @tab String @tab Number @tab Array @tab Undefined
+@item @tab @b{String} @tab String @tab String @tab false @tab false
+@item @tab @b{Number} @tab Number if can be converted, else false @tab Number @tab false @tab false
+@item @b{Type} @tab @b{Array} @tab false @tab false @tab Array @tab false
+@item @b{Requested} @tab @b{Scalar} @tab Scalar @tab Scalar @tab false @tab false
+@item @tab @b{Undefined} @tab String @tab Number @tab Array @tab Undefined
+@item @tab @b{Value Cookie} @tab false @tab false @tab false @tab false
+@end multitable
+@end ifnotdocbook
+@end ifnotplaintext
+@ifplaintext
+@example
+ +-------------------------------------------------+
+ | Type of Actual Value: |
+ +------------+------------+-----------+-----------+
+ | String | Number | Array | Undefined |
++-----------+-----------+------------+------------+-----------+-----------+
+| | String | String | String | false | false |
+| |-----------+------------+------------+-----------+-----------+
+| | Number | Number if | Number | false | false |
+| | | can be | | | |
+| | | converted, | | | |
+| | | else false | | | |
+| |-----------+------------+------------+-----------+-----------+
+| Type | Array | false | false | Array | false |
+| Requested |-----------+------------+------------+-----------+-----------+
+| | Scalar | Scalar | Scalar | false | false |
+| |-----------+------------+------------+-----------+-----------+
+| | Undefined | String | Number | Array | Undefined |
+| |-----------+------------+------------+-----------+-----------+
+| | Value | false | false | false | false |
+| | Cookie | | | | |
++-----------+-----------+------------+------------+-----------+-----------+
+@end example
+@end ifplaintext
+@end float
+
+@node Accessing Parameters
+@subsection Accessing and Updating Parameters
+
+Two functions give you access to the arguments (parameters)
+passed to your extension function. They are:
+
+@table @code
+@item awk_bool_t get_argument(size_t count,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_valtype_t wanted,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_value_t *result);
+Fill in the @code{awk_value_t} structure pointed to by @code{result}
+with the @code{count}'th argument. Return true if the actual
+type matches @code{wanted}, false otherwise. In the latter
+case, @code{result@w{->}val_type} indicates the actual type
+(@pxref{table-value-types-returned}). Counts are zero based---the first
+argument is numbered zero, the second one, and so on. @code{wanted}
+indicates the type of value expected.
+
+@item awk_bool_t set_argument(size_t count, awk_array_t array);
+Convert a parameter that was undefined into an array; this provides
+call-by-reference for arrays. Return false if @code{count} is too big,
+or if the argument's type is not undefined. @DBXREF{Array Manipulation}
+for more information on creating arrays.
+@end table
+
+@node Symbol Table Access
+@subsection Symbol Table Access
+@cindex accessing global variables from extensions
+
+Two sets of routines provide access to global variables, and one set
+allows you to create and release cached values.
+
+@menu
+* Symbol table by name:: Accessing variables by name.
+* Symbol table by cookie:: Accessing variables by ``cookie''.
+* Cached values:: Creating and using cached values.
+@end menu
+
+@node Symbol table by name
+@subsubsection Variable Access and Update by Name
+
+The following routines provide the ability to access and update
+global @command{awk}-level variables by name. In compiler terminology,
+identifiers of different kinds are termed @dfn{symbols}, thus the ``sym''
+in the routines' names. The data structure which stores information
+about symbols is termed a @dfn{symbol table}.
+
+@table @code
+@item awk_bool_t sym_lookup(const char *name,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_valtype_t wanted,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_value_t *result);
+Fill in the @code{awk_value_t} structure pointed to by @code{result}
+with the value of the variable named by the string @code{name}, which is
+a regular C string. @code{wanted} indicates the type of value expected.
+Return true if the actual type matches @code{wanted}, false otherwise.
+In the latter case, @code{result->val_type} indicates the actual type
+(@pxref{table-value-types-returned}).
+
+@item awk_bool_t sym_update(const char *name, awk_value_t *value);
+Update the variable named by the string @code{name}, which is a regular
+C string. The variable is added to @command{gawk}'s symbol table
+if it is not there. Return true if everything worked, false otherwise.
+
+Changing types (scalar to array or vice versa) of an existing variable
+is @emph{not} allowed, nor may this routine be used to update an array.
+This routine cannot be used to update any of the predefined
+variables (such as @code{ARGC} or @code{NF}).
+@end table
+
+An extension can look up the value of @command{gawk}'s special variables.
+However, with the exception of the @code{PROCINFO} array, an extension
+cannot change any of those variables.
+
+@quotation CAUTION
+It is possible for the lookup of @code{PROCINFO} to fail. This happens if
+the @command{awk} program being run does not reference @code{PROCINFO};
+in this case, @command{gawk} doesn't bother to create the array and
+populate it.
+@end quotation
+
+@node Symbol table by cookie
+@subsubsection Variable Access and Update by Cookie
+
+A @dfn{scalar cookie} is an opaque handle that provides access
+to a global variable or array. It is an optimization that
+avoids looking up variables in @command{gawk}'s symbol table every time
+access is needed. This was discussed earlier in @ref{General Data Types}.
+
+The following functions let you work with scalar cookies:
+
+@table @code
+@item awk_bool_t sym_lookup_scalar(awk_scalar_t cookie,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_valtype_t wanted,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_value_t *result);
+Retrieve the current value of a scalar cookie.
+Once you have obtained a scalar cookie using @code{sym_lookup()}, you can
+use this function to get its value more efficiently.
+Return false if the value cannot be retrieved.
+
+@item awk_bool_t sym_update_scalar(awk_scalar_t cookie, awk_value_t *value);
+Update the value associated with a scalar cookie. Return false if
+the new value is not of type @code{AWK_STRING} or @code{AWK_NUMBER}.
+Here too, the predefined variables may not be updated.
+@end table
+
+It is not obvious at first glance how to work with scalar cookies or
+what their @i{raison d'@^etre} really is. In theory, the @code{sym_lookup()}
+and @code{sym_update()} routines are all you really need to work with
+variables. For example, you might have code that looks up the value of
+a variable, evaluates a condition, and then possibly changes the value
+of the variable based on the result of that evaluation, like so:
+
+@example
+/* do_magic --- do something really great */
+
+static awk_value_t *
+do_magic(int nargs, awk_value_t *result)
+@{
+ awk_value_t value;
+
+ if ( sym_lookup("MAGIC_VAR", AWK_NUMBER, & value)
+ && some_condition(value.num_value)) @{
+ value.num_value += 42;
+ sym_update("MAGIC_VAR", & value);
+ @}
+
+ return make_number(0.0, result);
+@}
+@end example
+
+@noindent
+This code looks (and is) simple and straightforward. So what's the problem?
+
+Well, consider what happens if @command{awk}-level code associated
+with your extension calls the @code{magic()} function (implemented in
+C by @code{do_magic()}), once per record, while processing hundreds
+of thousands or millions of records. The @code{MAGIC_VAR} variable is
+looked up in the symbol table once or twice per function call!
+
+The symbol table lookup is really pure overhead; it is considerably
+more efficient to get a cookie that represents the variable, and use
+that to get the variable's value and update it as needed.@footnote{The
+difference is measurable and quite real. Trust us.}
+
+Thus, the way to use cookies is as follows. First, install
+your extension's variable in @command{gawk}'s symbol table using
+@code{sym_update()}, as usual. Then get a scalar cookie for the variable
+using @code{sym_lookup()}:
+
+@example
+static awk_scalar_t magic_var_cookie; /* cookie for MAGIC_VAR */
+
+static void
+my_extension_init()
+@{
+ awk_value_t value;
+
+ /* install initial value */
+ sym_update("MAGIC_VAR", make_number(42.0, & value));
+
+ /* get the cookie */
+ sym_lookup("MAGIC_VAR", AWK_SCALAR, & value);
+
+ /* save the cookie */
+ magic_var_cookie = value.scalar_cookie;
+ @dots{}
+@}
+@end example
+
+Next, use the routines in this section for retrieving and updating
+the value through the cookie. Thus, @code{do_magic()} now becomes
+something like this:
+
+@example
+/* do_magic --- do something really great */
+
+static awk_value_t *
+do_magic(int nargs, awk_value_t *result)
+@{
+ awk_value_t value;
+
+ if ( sym_lookup_scalar(magic_var_cookie, AWK_NUMBER, & value)
+ && some_condition(value.num_value)) @{
+ value.num_value += 42;
+ sym_update_scalar(magic_var_cookie, & value);
+ @}
+ @dots{}
+
+ return make_number(0.0, result);
+@}
+@end example
+
+@quotation NOTE
+The previous code omitted error checking for
+presentation purposes. Your extension code should be more robust
+and carefully check the return values from the API functions.
+@end quotation
+
+@node Cached values
+@subsubsection Creating and Using Cached Values
+
+The routines in this section allow you to create and release
+cached values. As with scalar cookies, in theory, cached values
+are not necessary. You can create numbers and strings using
+the functions in @ref{Constructor Functions}. You can then
+assign those values to variables using @code{sym_update()}
+or @code{sym_update_scalar()}, as you like.
+
+However, you can understand the point of cached values if you remember that
+@emph{every} string value's storage @emph{must} come from @code{gawk_malloc()},
+@code{gawk_calloc()}, or @code{gawk_realloc()}.
+If you have 20 variables, all of which have the same string value, you
+must create 20 identical copies of the string.@footnote{Numeric values
+are clearly less problematic, requiring only a C @code{double} to store.}
+
+It is clearly more efficient, if possible, to create a value once, and
+then tell @command{gawk} to reuse the value for multiple variables. That
+is what the routines in this section let you do. The functions are as follows:
+
+@table @code
+@item awk_bool_t create_value(awk_value_t *value, awk_value_cookie_t *result);
+Create a cached string or numeric value from @code{value} for
+efficient later assignment. Only values of type @code{AWK_NUMBER}
+and @code{AWK_STRING} are allowed. Any other type is rejected.
+@code{AWK_UNDEFINED} could be allowed, but doing so would result in
+inferior performance.
+
+@item awk_bool_t release_value(awk_value_cookie_t vc);
+Release the memory associated with a value cookie obtained
+from @code{create_value()}.
+@end table
+
+You use value cookies in a fashion similar to the way you use scalar cookies.
+In the extension initialization routine, you create the value cookie:
+
+@example
+static awk_value_cookie_t answer_cookie; /* static value cookie */
+
+static void
+my_extension_init()
+@{
+ awk_value_t value;
+ char *long_string;
+ size_t long_string_len;
+
+ /* code from earlier */
+ @dots{}
+ /* @dots{} fill in long_string and long_string_len @dots{} */
+ make_malloced_string(long_string, long_string_len, & value);
+ create_value(& value, & answer_cookie); /* create cookie */
+ @dots{}
+@}
+@end example
+
+Once the value is created, you can use it as the value of any number
+of variables:
+
+@example
+static awk_value_t *
+do_magic(int nargs, awk_value_t *result)
+@{
+ awk_value_t new_value;
+
+ @dots{} /* as earlier */
+
+ value.val_type = AWK_VALUE_COOKIE;
+ value.value_cookie = answer_cookie;
+ sym_update("VAR1", & value);
+ sym_update("VAR2", & value);
+ @dots{}
+ sym_update("VAR100", & value);
+ @dots{}
+@}
+@end example
+
+@noindent
+Using value cookies in this way saves considerable storage, as all of
+@code{VAR1} through @code{VAR100} share the same value.
+
+You might be wondering, ``Is this sharing problematic?
+What happens if @command{awk} code assigns a new value to @code{VAR1},
+are all the others changed too?''
+
+That's a great question. The answer is that no, it's not a problem.
+Internally, @command{gawk} uses @dfn{reference-counted strings}. This means
+that many variables can share the same string value, and @command{gawk}
+keeps track of the usage. When a variable's value changes, @command{gawk}
+simply decrements the reference count on the old value and updates
+the variable to use the new value.
+
+Finally, as part of your cleanup action (@pxref{Exit Callback Functions})
+you should release any cached values that you created, using
+@code{release_value()}.
+
+@node Array Manipulation
+@subsection Array Manipulation
+@cindex array manipulation in extensions
+
+The primary data structure@footnote{OK, the only data structure.} in @command{awk}
+is the associative array (@pxref{Arrays}).
+Extensions need to be able to manipulate @command{awk} arrays.
+The API provides a number of data structures for working with arrays,
+functions for working with individual elements, and functions for
+working with arrays as a whole. This includes the ability to
+``flatten'' an array so that it is easy for C code to traverse
+every element in an array. The array data structures integrate
+nicely with the data structures for values to make it easy to
+both work with and create true arrays of arrays (@pxref{General Data Types}).
+
+@menu
+* Array Data Types:: Data types for working with arrays.
+* Array Functions:: Functions for working with arrays.
+* Flattening Arrays:: How to flatten arrays.
+* Creating Arrays:: How to create and populate arrays.
+@end menu
+
+@node Array Data Types
+@subsubsection Array Data Types
+
+The data types associated with arrays are as follows:
+
+@table @code
+@item typedef void *awk_array_t;
+If you request the value of an array variable, you get back an
+@code{awk_array_t} value. This value is opaque@footnote{It is also
+a ``cookie,'' but the @command{gawk} developers did not wish to overuse this
+term.} to the extension; it uniquely identifies the array but can
+only be used by passing it into API functions or receiving it from API
+functions. This is very similar to way @samp{FILE *} values are used
+with the @code{<stdio.h>} library routines.
+
+@item typedef struct awk_element @{
+@itemx @ @ @ @ /* convenience linked list pointer, not used by gawk */
+@itemx @ @ @ @ struct awk_element *next;
+@itemx @ @ @ @ enum @{
+@itemx @ @ @ @ @ @ @ @ AWK_ELEMENT_DEFAULT = 0,@ @ /* set by gawk */
+@itemx @ @ @ @ @ @ @ @ AWK_ELEMENT_DELETE = 1@ @ @ @ /* set by extension */
+@itemx @ @ @ @ @} flags;
+@itemx @ @ @ @ awk_value_t index;
+@itemx @ @ @ @ awk_value_t value;
+@itemx @} awk_element_t;
+The @code{awk_element_t} is a ``flattened''
+array element. @command{awk} produces an array of these
+inside the @code{awk_flat_array_t} (see the next item).
+Individual elements may be marked for deletion. New elements must be added
+individually, one at a time, using the separate API for that purpose.
+The fields are as follows:
+
+@c nested table
+@table @code
+@item struct awk_element *next;
+This pointer is for the convenience of extension writers. It allows
+an extension to create a linked list of new elements that can then be
+added to an array in a loop that traverses the list.
+
+@item enum @{ @dots{} @} flags;
+A set of flag values that convey information between the extension
+and @command{gawk}. Currently there is only one: @code{AWK_ELEMENT_DELETE}.
+Setting it causes @command{gawk} to delete the
+element from the original array upon release of the flattened array.
+
+@item index
+@itemx value
+The index and value of the element, respectively.
+@emph{All} memory pointed to by @code{index} and @code{value} belongs to @command{gawk}.
+@end table
+
+@item typedef struct awk_flat_array @{
+@itemx @ @ @ @ awk_const void *awk_const opaque1;@ @ @ @ /* for use by gawk */
+@itemx @ @ @ @ awk_const void *awk_const opaque2;@ @ @ @ /* for use by gawk */
+@itemx @ @ @ @ awk_const size_t count;@ @ @ @ @ /* how many elements */
+@itemx @ @ @ @ awk_element_t elements[1];@ @ /* will be extended */
+@itemx @} awk_flat_array_t;
+This is a flattened array. When an extension gets one of these
+from @command{gawk}, the @code{elements} array is of actual
+size @code{count}.
+The @code{opaque1} and @code{opaque2} pointers are for use by @command{gawk};
+therefore they are marked @code{awk_const} so that the extension cannot
+modify them.
+@end table
+
+@node Array Functions
+@subsubsection Array Functions
+
+The following functions relate to individual array elements.
+
+@table @code
+@item awk_bool_t get_element_count(awk_array_t a_cookie, size_t *count);
+For the array represented by @code{a_cookie}, place in @code{*count}
+the number of elements it contains. A subarray counts as a single element.
+Return false if there is an error.
+
+@item awk_bool_t get_array_element(awk_array_t a_cookie,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const awk_value_t *const index,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_valtype_t wanted,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_value_t *result);
+For the array represented by @code{a_cookie}, return in @code{*result}
+the value of the element whose index is @code{index}.
+@code{wanted} specifies the type of value you wish to retrieve.
+Return false if @code{wanted} does not match the actual type or if
+@code{index} is not in the array (@pxref{table-value-types-returned}).
+
+The value for @code{index} can be numeric, in which case @command{gawk}
+converts it to a string. Using non-integral values is possible, but
+requires that you understand how such values are converted to strings
+(@pxref{Conversion}); thus using integral values is safest.
+
+As with @emph{all} strings passed into @code{gawk} from an extension,
+the string value of @code{index} must come from @code{gawk_malloc()},
+@code{gawk_calloc()} or @code{gawk_realloc()}, and
+@command{gawk} releases the storage.
+
+@item awk_bool_t set_array_element(awk_array_t a_cookie,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const@ awk_value_t *const index,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const@ awk_value_t *const value);
+In the array represented by @code{a_cookie}, create or modify
+the element whose index is given by @code{index}.
+The @code{ARGV} and @code{ENVIRON} arrays may not be changed,
+although the @code{PROCINFO} array can be.
+
+@item awk_bool_t set_array_element_by_elem(awk_array_t a_cookie,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_element_t element);
+Like @code{set_array_element()}, but take the @code{index} and @code{value}
+from @code{element}. This is a convenience macro.
+
+@item awk_bool_t del_array_element(awk_array_t a_cookie,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const awk_value_t* const index);
+Remove the element with the given index from the array
+represented by @code{a_cookie}.
+Return true if the element was removed, or false if the element did
+not exist in the array.
+@end table
+
+The following functions relate to arrays as a whole:
+
+@table @code
+@item awk_array_t create_array(void);
+Create a new array to which elements may be added.
+@DBXREF{Creating Arrays} for a discussion of how to
+create a new array and add elements to it.
+
+@item awk_bool_t clear_array(awk_array_t a_cookie);
+Clear the array represented by @code{a_cookie}.
+Return false if there was some kind of problem, true otherwise.
+The array remains an array, but after calling this function, it
+has no elements. This is equivalent to using the @code{delete}
+statement (@pxref{Delete}).
+
+@item awk_bool_t flatten_array(awk_array_t a_cookie, awk_flat_array_t **data);
+For the array represented by @code{a_cookie}, create an @code{awk_flat_array_t}
+structure and fill it in. Set the pointer whose address is passed as @code{data}
+to point to this structure.
+Return true upon success, or false otherwise.
+@ifset FOR_PRINT
+See the next section
+@end ifset
+@ifclear FOR_PRINT
+@xref{Flattening Arrays},
+@end ifclear
+for a discussion of how to
+flatten an array and work with it.
+
+@item awk_bool_t release_flattened_array(awk_array_t a_cookie,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_flat_array_t *data);
+When done with a flattened array, release the storage using this function.
+You must pass in both the original array cookie, and the address of
+the created @code{awk_flat_array_t} structure.
+The function returns true upon success, false otherwise.
+@end table
+
+@node Flattening Arrays
+@subsubsection Working With All The Elements of an Array
+
+To @dfn{flatten} an array is to create a structure that
+represents the full array in a fashion that makes it easy
+for C code to traverse the entire array. Test code
+in @file{extension/testext.c} does this, and also serves
+as a nice example showing how to use the APIs.
+
+We walk through that part of the code one step at a time.
+First, the @command{gawk} script that drives the test extension:
+
+@example
+@@load "testext"
+BEGIN @{
+ n = split("blacky rusty sophie raincloud lucky", pets)
+ printf("pets has %d elements\n", length(pets))
+ ret = dump_array_and_delete("pets", "3")
+ printf("dump_array_and_delete(pets) returned %d\n", ret)
+ if ("3" in pets)
+ printf("dump_array_and_delete() did NOT remove index \"3\"!\n")
+ else
+ printf("dump_array_and_delete() did remove index \"3\"!\n")
+ print ""
+@}
+@end example
+
+@noindent
+This code creates an array with @code{split()} (@pxref{String Functions})
+and then calls @code{dump_array_and_delete()}. That function looks up
+the array whose name is passed as the first argument, and
+deletes the element at the index passed in the second argument.
+The @command{awk} code then prints the return value and checks if the element
+was indeed deleted. Here is the C code that implements
+@code{dump_array_and_delete()}. It has been edited slightly for
+presentation.
+
+The first part declares variables, sets up the default
+return value in @code{result}, and checks that the function
+was called with the correct number of arguments:
+
+@example
+static awk_value_t *
+dump_array_and_delete(int nargs, awk_value_t *result)
+@{
+ awk_value_t value, value2, value3;
+ awk_flat_array_t *flat_array;
+ size_t count;
+ char *name;
+ int i;
+
+ assert(result != NULL);
+ make_number(0.0, result);
+
+ if (nargs != 2) @{
+ printf("dump_array_and_delete: nargs not right "
+ "(%d should be 2)\n", nargs);
+ goto out;
+ @}
+@end example
+
+The function then proceeds in steps, as follows. First, retrieve
+the name of the array, passed as the first argument. Then
+retrieve the array itself. If either operation fails, print
+error messages and return:
+
+@example
+ /* get argument named array as flat array and print it */
+ if (get_argument(0, AWK_STRING, & value)) @{
+ name = value.str_value.str;
+ if (sym_lookup(name, AWK_ARRAY, & value2))
+ printf("dump_array_and_delete: sym_lookup of %s passed\n",
+ name);
+ else @{
+ printf("dump_array_and_delete: sym_lookup of %s failed\n",
+ name);
+ goto out;
+ @}
+ @} else @{
+ printf("dump_array_and_delete: get_argument(0) failed\n");
+ goto out;
+ @}
+@end example
+
+For testing purposes and to make sure that the C code sees
+the same number of elements as the @command{awk} code,
+the second step is to get the count of elements in the array
+and print it:
+
+@example
+ if (! get_element_count(value2.array_cookie, & count)) @{
+ printf("dump_array_and_delete: get_element_count failed\n");
+ goto out;
+ @}
+
+ printf("dump_array_and_delete: incoming size is %lu\n",
+ (unsigned long) count);
+@end example
+
+The third step is to actually flatten the array, and then
+to double check that the count in the @code{awk_flat_array_t}
+is the same as the count just retrieved:
+
+@example
+ if (! flatten_array(value2.array_cookie, & flat_array)) @{
+ printf("dump_array_and_delete: could not flatten array\n");
+ goto out;
+ @}
+
+ if (flat_array->count != count) @{
+ printf("dump_array_and_delete: flat_array->count (%lu)"
+ " != count (%lu)\n",
+ (unsigned long) flat_array->count,
+ (unsigned long) count);
+ goto out;
+ @}
+@end example
+
+The fourth step is to retrieve the index of the element
+to be deleted, which was passed as the second argument.
+Remember that argument counts passed to @code{get_argument()}
+are zero-based, thus the second argument is numbered one:
+
+@example
+ if (! get_argument(1, AWK_STRING, & value3)) @{
+ printf("dump_array_and_delete: get_argument(1) failed\n");
+ goto out;
+ @}
+@end example
+
+The fifth step is where the ``real work'' is done. The function
+loops over every element in the array, printing the index and
+element values. In addition, upon finding the element with the
+index that is supposed to be deleted, the function sets the
+@code{AWK_ELEMENT_DELETE} bit in the @code{flags} field
+of the element. When the array is released, @command{gawk}
+traverses the flattened array, and deletes any elements which
+have this flag bit set:
+
+@example
+ for (i = 0; i < flat_array->count; i++) @{
+ printf("\t%s[\"%.*s\"] = %s\n",
+ name,
+ (int) flat_array->elements[i].index.str_value.len,
+ flat_array->elements[i].index.str_value.str,
+ valrep2str(& flat_array->elements[i].value));
+
+ if (strcmp(value3.str_value.str,
+ flat_array->elements[i].index.str_value.str) == 0) @{
+ flat_array->elements[i].flags |= AWK_ELEMENT_DELETE;
+ printf("dump_array_and_delete: marking element \"%s\" "
+ "for deletion\n",
+ flat_array->elements[i].index.str_value.str);
+ @}
+ @}
+@end example
+
+The sixth step is to release the flattened array. This tells
+@command{gawk} that the extension is no longer using the array,
+and that it should delete any elements marked for deletion.
+@command{gawk} also frees any storage that was allocated,
+so you should not use the pointer (@code{flat_array} in this
+code) once you have called @code{release_flattened_array()}:
+
+@example
+ if (! release_flattened_array(value2.array_cookie, flat_array)) @{
+ printf("dump_array_and_delete: could not release flattened array\n");
+ goto out;
+ @}
+@end example
+
+Finally, because everything was successful, the function sets the
+return value to success, and returns:
+
+@example
+ make_number(1.0, result);
+out:
+ return result;
+@}
+@end example
+
+Here is the output from running this part of the test:
+
+@example
+pets has 5 elements
+dump_array_and_delete: sym_lookup of pets passed
+dump_array_and_delete: incoming size is 5
+ pets["1"] = "blacky"
+ pets["2"] = "rusty"
+ pets["3"] = "sophie"
+dump_array_and_delete: marking element "3" for deletion
+ pets["4"] = "raincloud"
+ pets["5"] = "lucky"
+dump_array_and_delete(pets) returned 1
+dump_array_and_delete() did remove index "3"!
+@end example
+
+@node Creating Arrays
+@subsubsection How To Create and Populate Arrays
+
+Besides working with arrays created by @command{awk} code, you can
+create arrays and populate them as you see fit, and then @command{awk}
+code can access them and manipulate them.
+
+There are two important points about creating arrays from extension code:
+
+@itemize @value{BULLET}
+@item
+You must install a new array into @command{gawk}'s symbol
+table immediately upon creating it. Once you have done so,
+you can then populate the array.
+
+@ignore
+Strictly speaking, this is required only
+for arrays that will have subarrays as elements; however it is
+a good idea to always do this. This restriction may be relaxed
+in a subsequent revision of the API.
+@end ignore
+
+Similarly, if installing a new array as a subarray of an existing array,
+you must add the new array to its parent before adding any elements to it.
+
+Thus, the correct way to build an array is to work ``top down.'' Create
+the array, and immediately install it in @command{gawk}'s symbol table
+using @code{sym_update()}, or install it as an element in a previously
+existing array using @code{set_array_element()}. We show example code shortly.
+
+@item
+Due to @command{gawk} internals, after using @code{sym_update()} to install an array
+into @command{gawk}, you have to retrieve the array cookie from the value
+passed in to @command{sym_update()} before doing anything else with it, like so:
+
+@example
+awk_value_t value;
+awk_array_t new_array;
+
+new_array = create_array();
+val.val_type = AWK_ARRAY;
+val.array_cookie = new_array;
+
+/* install array in the symbol table */
+sym_update("array", & val);
+
+new_array = val.array_cookie; /* YOU MUST DO THIS */
+@end example
+
+If installing an array as a subarray, you must also retrieve the value
+of the array cookie after the call to @code{set_element()}.
+@end itemize
+
+The following C code is a simple test extension to create an array
+with two regular elements and with a subarray. The leading @code{#include}
+directives and boilerplate variable declarations
+(@pxref{Extension API Boilerplate})
+are omitted for brevity.
+The first step is to create a new array and then install it
+in the symbol table:
+
+@example
+@ignore
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "gawkapi.h"
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+static const char *ext_version = "testarray extension: version 1.0";
+
+int plugin_is_GPL_compatible;
+
+@end ignore
+/* create_new_array --- create a named array */
+
+static void
+create_new_array()
+@{
+ awk_array_t a_cookie;
+ awk_array_t subarray;
+ awk_value_t index, value;
+
+ a_cookie = create_array();
+ value.val_type = AWK_ARRAY;
+ value.array_cookie = a_cookie;
+
+ if (! sym_update("new_array", & value))
+ printf("create_new_array: sym_update(\"new_array\") failed!\n");
+ a_cookie = value.array_cookie;
+@end example
+
+@noindent
+Note how @code{a_cookie} is reset from the @code{array_cookie} field in
+the @code{value} structure.
+
+The second step is to install two regular values into @code{new_array}:
+
+@example
+ (void) make_const_string("hello", 5, & index);
+ (void) make_const_string("world", 5, & value);
+ if (! set_array_element(a_cookie, & index, & value)) @{
+ printf("fill_in_array: set_array_element failed\n");
+ return;
+ @}
+
+ (void) make_const_string("answer", 6, & index);
+ (void) make_number(42.0, & value);
+ if (! set_array_element(a_cookie, & index, & value)) @{
+ printf("fill_in_array: set_array_element failed\n");
+ return;
+ @}
+@end example
+
+The third step is to create the subarray and install it:
+
+@example
+ (void) make_const_string("subarray", 8, & index);
+ subarray = create_array();
+ value.val_type = AWK_ARRAY;
+ value.array_cookie = subarray;
+ if (! set_array_element(a_cookie, & index, & value)) @{
+ printf("fill_in_array: set_array_element failed\n");
+ return;
+ @}
+ subarray = value.array_cookie;
+@end example
+
+The final step is to populate the subarray with its own element:
+
+@example
+ (void) make_const_string("foo", 3, & index);
+ (void) make_const_string("bar", 3, & value);
+ if (! set_array_element(subarray, & index, & value)) @{
+ printf("fill_in_array: set_array_element failed\n");
+ return;
+ @}
+@}
+@ignore
+static awk_ext_func_t func_table[] = @{
+ @{ NULL, NULL, 0 @}
+@};
+
+/* init_testarray --- additional initialization function */
+
+static awk_bool_t init_testarray(void)
+@{
+ create_new_array();
+
+ return awk_true;
+@}
+
+static awk_bool_t (*init_func)(void) = init_testarray;
+
+dl_load_func(func_table, testarray, "")
+@end ignore
+@end example
+
+Here is a sample script that loads the extension
+and then dumps the array:
+
+@example
+@@load "subarray"
+
+function dumparray(name, array, i)
+@{
+ for (i in array)
+ if (isarray(array[i]))
+ dumparray(name "[\"" i "\"]", array[i])
+ else
+ printf("%s[\"%s\"] = %s\n", name, i, array[i])
+@}
+
+BEGIN @{
+ dumparray("new_array", new_array);
+@}
+@end example
+
+Here is the result of running the script:
+
+@example
+$ @kbd{AWKLIBPATH=$PWD ./gawk -f subarray.awk}
+@print{} new_array["subarray"]["foo"] = bar
+@print{} new_array["hello"] = world
+@print{} new_array["answer"] = 42
+@end example
+
+@noindent
+(@DBXREF{Finding Extensions} for more information on the
+@env{AWKLIBPATH} environment variable.)
+
+@node Extension API Variables
+@subsection API Variables
+
+The API provides two sets of variables. The first provides information
+about the version of the API (both with which the extension was compiled,
+and with which @command{gawk} was compiled). The second provides
+information about how @command{gawk} was invoked.
+
+@menu
+* Extension Versioning:: API Version information.
+* Extension API Informational Variables:: Variables providing information about
+ @command{gawk}'s invocation.
+@end menu
+
+@node Extension Versioning
+@subsubsection API Version Constants and Variables
+@cindex API version
+@cindex extension API version
+
+The API provides both a ``major'' and a ``minor'' version number.
+The API versions are available at compile time as constants:
+
+@table @code
+@item GAWK_API_MAJOR_VERSION
+The major version of the API.
+
+@item GAWK_API_MINOR_VERSION
+The minor version of the API.
+@end table
+
+The minor version increases when new functions are added to the API. Such
+new functions are always added to the end of the API @code{struct}.
+
+The major version increases (and the minor version is reset to zero) if any
+of the data types change size or member order, or if any of the existing
+functions change signature.
+
+It could happen that an extension may be compiled against one version
+of the API but loaded by a version of @command{gawk} using a different
+version. For this reason, the major and minor API versions of the
+running @command{gawk} are included in the API @code{struct} as read-only
+constant integers:
+
+@table @code
+@item api->major_version
+The major version of the running @command{gawk}.
+
+@item api->minor_version
+The minor version of the running @command{gawk}.
+@end table
+
+It is up to the extension to decide if there are API incompatibilities.
+Typically a check like this is enough:
+
+@example
+if (api->major_version != GAWK_API_MAJOR_VERSION
+ || api->minor_version < GAWK_API_MINOR_VERSION) @{
+ fprintf(stderr, "foo_extension: version mismatch with gawk!\n");
+ fprintf(stderr, "\tmy version (%d, %d), gawk version (%d, %d)\n",
+ GAWK_API_MAJOR_VERSION, GAWK_API_MINOR_VERSION,
+ api->major_version, api->minor_version);
+ exit(1);
+@}
+@end example
+
+Such code is included in the boilerplate @code{dl_load_func()} macro
+provided in @file{gawkapi.h} (discussed later, in
+@ref{Extension API Boilerplate}).
+
+@node Extension API Informational Variables
+@subsubsection Informational Variables
+@cindex API informational variables
+@cindex extension API informational variables
+
+The API provides access to several variables that describe
+whether the corresponding command-line options were enabled when
+@command{gawk} was invoked. The variables are:
+
+@table @code
+@item do_debug
+This variable is true if @command{gawk} was invoked with @option{--debug} option.
+
+@item do_lint
+This variable is true if @command{gawk} was invoked with @option{--lint} option.
+
+@item do_mpfr
+This variable is true if @command{gawk} was invoked with @option{--bignum} option.
+
+@item do_profile
+This variable is true if @command{gawk} was invoked with @option{--profile} option.
+
+@item do_sandbox
+This variable is true if @command{gawk} was invoked with @option{--sandbox} option.
+
+@item do_traditional
+This variable is true if @command{gawk} was invoked with @option{--traditional} option.
+@end table
+
+The value of @code{do_lint} can change if @command{awk} code
+modifies the @code{LINT} predefined variable (@pxref{Built-in Variables}).
+The others should not change during execution.
+
+@node Extension API Boilerplate
+@subsection Boilerplate Code
+
+As mentioned earlier (@pxref{Extension Mechanism Outline}), the function
+definitions as presented are really macros. To use these macros, your
+extension must provide a small amount of boilerplate code (variables and
+functions) toward the top of your source file, using predefined names
+as described here. The boilerplate needed is also provided in comments
+in the @file{gawkapi.h} header file:
+
+@example
+/* Boiler plate code: */
+int plugin_is_GPL_compatible;
+
+static gawk_api_t *const api;
+static awk_ext_id_t ext_id;
+static const char *ext_version = NULL; /* or @dots{} = "some string" */
+
+static awk_ext_func_t func_table[] = @{
+ @{ "name", do_name, 1 @},
+ /* @dots{} */
+@};
+
+/* EITHER: */
+
+static awk_bool_t (*init_func)(void) = NULL;
+
+/* OR: */
+
+static awk_bool_t
+init_my_extension(void)
+@{
+ @dots{}
+@}
+
+static awk_bool_t (*init_func)(void) = init_my_extension;
+
+dl_load_func(func_table, some_name, "name_space_in_quotes")
+@end example
+
+These variables and functions are as follows:
+
+@table @code
+@item int plugin_is_GPL_compatible;
+This asserts that the extension is compatible with
+@ifclear FOR_PRINT
+the GNU GPL (@pxref{Copying}).
+@end ifclear
+@ifset FOR_PRINT
+the GNU GPL.
+@end ifset
+If your extension does not have this, @command{gawk}
+will not load it (@pxref{Plugin License}).
+
+@item static gawk_api_t *const api;
+This global @code{static} variable should be set to point to
+the @code{gawk_api_t} pointer that @command{gawk} passes to your
+@code{dl_load()} function. This variable is used by all of the macros.
+
+@item static awk_ext_id_t ext_id;
+This global static variable should be set to the @code{awk_ext_id_t}
+value that @command{gawk} passes to your @code{dl_load()} function.
+This variable is used by all of the macros.
+
+@item static const char *ext_version = NULL; /* or @dots{} = "some string" */
+This global @code{static} variable should be set either
+to @code{NULL}, or to point to a string giving the name and version of
+your extension.
+
+@item static awk_ext_func_t func_table[] = @{ @dots{} @};
+This is an array of one or more @code{awk_ext_func_t} structures
+as described earlier (@pxref{Extension Functions}).
+It can then be looped over for multiple calls to
+@code{add_ext_func()}.
+
+@c Use @var{OR} for docbook
+@item static awk_bool_t (*init_func)(void) = NULL;
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @var{OR}
+@itemx static awk_bool_t init_my_extension(void) @{ @dots{} @}
+@itemx static awk_bool_t (*init_func)(void) = init_my_extension;
+If you need to do some initialization work, you should define a
+function that does it (creates variables, opens files, etc.)
+and then define the @code{init_func} pointer to point to your
+function.
+The function should return @code{awk_false} upon failure, or @code{awk_true}
+if everything goes well.
+
+If you don't need to do any initialization, define the pointer and
+initialize it to @code{NULL}.
+
+@item dl_load_func(func_table, some_name, "name_space_in_quotes")
+This macro expands to a @code{dl_load()} function that performs
+all the necessary initializations.
+@end table
+
+The point of all the variables and arrays is to let the
+@code{dl_load()} function (from the @code{dl_load_func()}
+macro) do all the standard work. It does the following:
+
+@enumerate 1
+@item
+Check the API versions. If the extension major version does not match
+@command{gawk}'s, or if the extension minor version is greater than
+@command{gawk}'s, it prints a fatal error message and exits.
+
+@item
+Load the functions defined in @code{func_table}.
+If any of them fails to load, it prints a warning message but
+continues on.
+
+@item
+If the @code{init_func} pointer is not @code{NULL}, call the
+function it points to. If it returns @code{awk_false}, print a
+warning message.
+
+@item
+If @code{ext_version} is not @code{NULL}, register
+the version string with @command{gawk}.
+@end enumerate
+
+@node Finding Extensions
+@section How @command{gawk} Finds Extensions
+@cindex extension search path
+@cindex finding extensions
+
+Compiled extensions have to be installed in a directory where
+@command{gawk} can find them. If @command{gawk} is configured and
+built in the default fashion, the directory in which to find
+extensions is @file{/usr/local/lib/gawk}. You can also specify a search
+path with a list of directories to search for compiled extensions.
+@DBXREF{AWKLIBPATH Variable} for more information.
+
+@node Extension Example
+@section Example: Some File Functions
+@cindex extension example
+
+@quotation
+@i{No matter where you go, there you are.}
+@author Buckaroo Banzai
+@end quotation
+
+@c It's enough to show chdir and stat, no need for fts
+
+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).
+In order to illustrate the API in action, this @value{SECTION} implements
+these functions for @command{gawk} in an extension.
+
+@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
+@subsection 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
+@@load "filefuncs"
+@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"
+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{Time Functions}).
+
+@item "pmode"
+The file's ``printable mode.'' This is a string representation of
+the file's type and permissions, such as 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
+
+@c 5/2013: Thanks to Corinna Vinschen for this information.
+@item "devbsize"
+The size of a block for the element indexed by @code{"blocks"}.
+This information is derived from either the @code{DEV_BSIZE}
+constant defined in @code{<sys/param.h>} on most systems,
+or the @code{S_BLKSIZE} constant in @code{<sys/stat.h>} on BSD systems.
+For some other systems, @dfn{a priori} knowledge is used to provide
+a value. Where no value can be determined, it defaults to 512.
+@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
+@subsection C Code for @code{chdir()} and @code{stat()}
+
+Here is the C code for these extensions.@footnote{This version is
+edited slightly for presentation. See @file{extension/filefuncs.c}
+in the @command{gawk} distribution for the complete version.}
+
+The file includes a number of standard header files, and then includes
+the @file{gawkapi.h} header file which provides the API definitions.
+Those are followed by the necessary variable declarations
+to make use of the API macros and boilerplate code
+(@pxref{Extension API Boilerplate}):
+
+@example
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "gawkapi.h"
+
+#include "gettext.h"
+#define _(msgid) gettext(msgid)
+#define N_(msgid) msgid
+
+#include "gawkfts.h"
+#include "stack.h"
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+static awk_bool_t init_filefuncs(void);
+static awk_bool_t (*init_func)(void) = init_filefuncs;
+static const char *ext_version = "filefuncs extension: version 1.0";
+
+int plugin_is_GPL_compatible;
+@end example
+
+@cindex programming conventions, @command{gawk} extensions
+By convention, for an @command{awk} function @code{foo()}, the C function
+that implements it is called @code{do_foo()}. The function should have
+two arguments: the first is an @code{int} usually called @code{nargs},
+that represents the number of actual arguments for the function.
+The second is a pointer to an @code{awk_value_t}, usually named
+@code{result}:
+
+@example
+/* do_chdir --- provide dynamically loaded chdir() function for gawk */
+
+static awk_value_t *
+do_chdir(int nargs, awk_value_t *result)
+@{
+ awk_value_t newdir;
+ int ret = -1;
+
+ assert(result != NULL);
+
+ if (do_lint && nargs != 1)
+ lintwarn(ext_id,
+ _("chdir: called with incorrect number of arguments, "
+ "expecting 1"));
+@end example
+
+The @code{newdir}
+variable represents the new directory to change to, which is retrieved
+with @code{get_argument()}. Note that the first argument is
+numbered zero.
+
+If the argument is retrieved successfully, the function calls the
+@code{chdir()} system call. If the @code{chdir()} fails, @code{ERRNO}
+is updated:
+
+@example
+ if (get_argument(0, AWK_STRING, & newdir)) @{
+ ret = chdir(newdir.str_value.str);
+ if (ret < 0)
+ update_ERRNO_int(errno);
+ @}
+@end example
+
+Finally, the function returns the return value to the @command{awk} level:
+
+@example
+ return make_number(ret, result);
+@}
+@end example
+
+The @code{stat()} extension 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:
+
+@example
+/* format_mode --- turn a stat mode field into something readable */
+
+static char *
+format_mode(unsigned long fmode)
+@{
+ @dots{}
+@}
+@end example
+
+Next comes a function for reading symbolic links, which is also
+omitted here for brevity:
+
+@example
+/* read_symlink --- read a symbolic link into an allocated buffer.
+ @dots{} */
+
+static char *
+read_symlink(const char *fname, size_t bufsize, ssize_t *linksize)
+@{
+ @dots{}
+@}
+@end example
+
+Two helper functions simplify entering values in the
+array that will contain the result of the @code{stat()}:
+
+@example
+/* array_set --- set an array element */
+
+static void
+array_set(awk_array_t array, const char *sub, awk_value_t *value)
+@{
+ awk_value_t index;
+
+ set_array_element(array,
+ make_const_string(sub, strlen(sub), & index),
+ value);
+
+@}
+
+/* array_set_numeric --- set an array element with a number */
+
+static void
+array_set_numeric(awk_array_t array, const char *sub, double num)
+@{
+ awk_value_t tmp;
+
+ array_set(array, sub, make_number(num, & tmp));
+@}
+@end example
+
+The following function does most of the work to fill in
+the @code{awk_array_t} result array with values obtained
+from a valid @code{struct stat}. It is done in a separate function
+to support the @code{stat()} function for @command{gawk} and also
+to support the @code{fts()} extension which is included in
+the same file but whose code is not shown here
+(@pxref{Extension Sample File Functions}).
+
+The first part of the function is variable declarations,
+including a table to map file types to strings:
+
+@example
+/* fill_stat_array --- do the work to fill an array with stat info */
+
+static int
+fill_stat_array(const char *name, awk_array_t array, struct stat *sbuf)
+@{
+ char *pmode; /* printable mode */
+ const char *type = "unknown";
+ awk_value_t tmp;
+ static struct ftype_map @{
+ unsigned int mask;
+ const char *type;
+ @} ftype_map[] = @{
+ @{ S_IFREG, "file" @},
+ @{ S_IFBLK, "blockdev" @},
+ @{ S_IFCHR, "chardev" @},
+ @{ S_IFDIR, "directory" @},
+#ifdef S_IFSOCK
+ @{ S_IFSOCK, "socket" @},
+#endif
+#ifdef S_IFIFO
+ @{ S_IFIFO, "fifo" @},
+#endif
+#ifdef S_IFLNK
+ @{ S_IFLNK, "symlink" @},
+#endif
+#ifdef S_IFDOOR /* Solaris weirdness */
+ @{ S_IFDOOR, "door" @},
+#endif /* S_IFDOOR */
+ @};
+ int j, k;
+@end example
+
+The destination array is cleared, and then code fills in
+various elements based on values in the @code{struct stat}:
+
+@example
+ /* empty out the array */
+ clear_array(array);
+
+ /* fill in the array */
+ array_set(array, "name", make_const_string(name, strlen(name),
+ & tmp));
+ array_set_numeric(array, "dev", sbuf->st_dev);
+ array_set_numeric(array, "ino", sbuf->st_ino);
+ array_set_numeric(array, "mode", sbuf->st_mode);
+ array_set_numeric(array, "nlink", sbuf->st_nlink);
+ array_set_numeric(array, "uid", sbuf->st_uid);
+ array_set_numeric(array, "gid", sbuf->st_gid);
+ array_set_numeric(array, "size", sbuf->st_size);
+ array_set_numeric(array, "blocks", sbuf->st_blocks);
+ array_set_numeric(array, "atime", sbuf->st_atime);
+ array_set_numeric(array, "mtime", sbuf->st_mtime);
+ array_set_numeric(array, "ctime", 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)) @{
+ array_set_numeric(array, "rdev", sbuf->st_rdev);
+ array_set_numeric(array, "major", major(sbuf->st_rdev));
+ array_set_numeric(array, "minor", minor(sbuf->st_rdev));
+ @}
+@end example
+
+@noindent
+The latter part of the function makes selective additions
+to the destination array, depending upon the availability of
+certain members and/or the type of the file. It then returns zero,
+for success:
+
+@example
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+ array_set_numeric(array, "blksize", sbuf->st_blksize);
+#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
+
+ pmode = format_mode(sbuf->st_mode);
+ array_set(array, "pmode", make_const_string(pmode, strlen(pmode),
+ & tmp));
+
+ /* for symbolic links, add a linkval field */
+ if (S_ISLNK(sbuf->st_mode)) @{
+ char *buf;
+ ssize_t linksize;
+
+ if ((buf = read_symlink(name, sbuf->st_size,
+ & linksize)) != NULL)
+ array_set(array, "linkval",
+ make_malloced_string(buf, linksize, & tmp));
+ else
+ warning(ext_id, _("stat: unable to read symbolic link `%s'"),
+ name);
+ @}
+
+ /* add a type field */
+ type = "unknown"; /* shouldn't happen */
+ for (j = 0, k = sizeof(ftype_map)/sizeof(ftype_map[0]); j < k; j++) @{
+ if ((sbuf->st_mode & S_IFMT) == ftype_map[j].mask) @{
+ type = ftype_map[j].type;
+ break;
+ @}
+ @}
+
+ array_set(array, "type", make_const_string(type, strlen(type), & tmp));
+
+ return 0;
+@}
+@end example
+
+The third argument to @code{stat()} was not discussed previously. This
+argument is optional. If present, it causes @code{do_stat()} to use
+the @code{stat()} system call instead of the @code{lstat()} system
+call. This is done by using a function pointer: @code{statfunc}.
+@code{statfunc} is initialized to point to @code{lstat()} (instead
+of @code{stat()}) to get the file information, in case the file is a
+symbolic link. However, if there were three arguments, @code{statfunc}
+is set point to @code{stat()}, instead.
+
+Here is the @code{do_stat()} function, which starts with
+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 awk_value_t *
+do_stat(int nargs, awk_value_t *result)
+@{
+ awk_value_t file_param, array_param;
+ char *name;
+ awk_array_t array;
+ int ret;
+ struct stat sbuf;
+ /* default is lstat() */
+ int (*statfunc)(const char *path, struct stat *sbuf) = lstat;
+
+ assert(result != NULL);
+
+ if (nargs != 2 && nargs != 3) @{
+ if (do_lint)
+ lintwarn(ext_id,
+ _("stat: called with wrong number of arguments"));
+ return make_number(-1, result);
+ @}
+@end example
+
+Then comes the actual work. First, the function gets the arguments.
+Next, it gets the information for the file. If the called function
+(@code{lstat()} or @code{stat()}) returns an error, the code sets
+@code{ERRNO} and returns:
+
+@example
+ /* file is first arg, array to hold results is second */
+ if ( ! get_argument(0, AWK_STRING, & file_param)
+ || ! get_argument(1, AWK_ARRAY, & array_param)) @{
+ warning(ext_id, _("stat: bad parameters"));
+ return make_number(-1, result);
+ @}
+
+ if (nargs == 3) @{
+ statfunc = stat;
+ @}
+
+ name = file_param.str_value.str;
+ array = array_param.array_cookie;
+
+ /* always empty out the array */
+ clear_array(array);
+
+ /* stat the file, if error, set ERRNO and return */
+ ret = statfunc(name, & sbuf);
+ if (ret < 0) @{
+ update_ERRNO_int(errno);
+ return make_number(ret, result);
+ @}
+@end example
+
+The tedious work is done by @code{fill_stat_array()}, shown
+earlier. When done, the function returns the result from @code{fill_stat_array()}:
+
+@example
+ ret = fill_stat_array(name, array, & sbuf);
+
+ return make_number(ret, result);
+@}
+@end example
+
+Finally, it's necessary to provide the ``glue'' that loads the
+new function(s) into @command{gawk}.
+
+The @code{filefuncs} extension also provides an @code{fts()}
+function, which we omit here. For its sake there is an initialization
+function:
+
+@example
+/* init_filefuncs --- initialization routine */
+
+static awk_bool_t
+init_filefuncs(void)
+@{
+ @dots{}
+@}
+@end example
+
+We are almost done. We need an array of @code{awk_ext_func_t}
+structures for loading each function into @command{gawk}:
+
+@example
+static awk_ext_func_t func_table[] = @{
+ @{ "chdir", do_chdir, 1 @},
+ @{ "stat", do_stat, 2 @},
+#ifndef __MINGW32__
+ @{ "fts", do_fts, 3 @},
+#endif
+@};
+@end example
+
+Each extension must have a routine named @code{dl_load()} to load
+everything that needs to be loaded. It is simplest to use the
+@code{dl_load_func()} macro in @code{gawkapi.h}:
+
+@example
+/* define the dl_load() function using the boilerplate macro */
+
+dl_load_func(func_table, filefuncs, "")
+@end example
+
+And that's it!
+
+@node Using Internal File Ops
+@subsection 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 @file{gawkapi.h} header file,
+the following steps@footnote{In practice, you would probably want to
+use the GNU Autotools (Automake, Autoconf, Libtool, and @command{gettext}) to
+configure and build your libraries. Instructions for doing so are beyond
+the scope of this @value{DOCUMENT}. @DBXREF{gawkextlib} for Internet links to
+the tools.} create a GNU/Linux shared library:
+
+@example
+$ @kbd{gcc -fPIC -shared -DHAVE_CONFIG_H -c -O -g -I@var{idir} filefuncs.c}
+$ @kbd{gcc -o filefuncs.so -shared filefuncs.o}
+@end example
+
+Once the library exists, it is loaded by using the @code{@@load} keyword:
+
+@example
+# file testff.awk
+@@load "filefuncs"
+
+BEGIN @{
+ "pwd" | getline curdir # save current directory
+ close("pwd")
+
+ chdir("/tmp")
+ system("pwd") # test it
+ chdir(curdir) # go back
+
+ 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"])
+@}
+@end example
+
+The @env{AWKLIBPATH} environment variable tells
+@command{gawk} where to find extensions (@pxref{Finding Extensions}).
+We set it to the current directory and run the program:
+
+@example
+$ @kbd{AWKLIBPATH=$PWD gawk -f testff.awk}
+@print{} /tmp
+@print{} Info for testff.awk
+@print{} ret = 0
+@print{} data["blksize"] = 4096
+@print{} data["devbsize"] = 512
+@print{} data["mtime"] = 1412004710
+@print{} data["mode"] = 33204
+@print{} data["type"] = file
+@print{} data["dev"] = 2053
+@print{} data["gid"] = 1000
+@print{} data["ino"] = 10358899
+@print{} data["ctime"] = 1412004710
+@print{} data["blocks"] = 8
+@print{} data["nlink"] = 1
+@print{} data["name"] = testff.awk
+@print{} data["atime"] = 1412004716
+@print{} data["pmode"] = -rw-rw-r--
+@print{} data["size"] = 666
+@print{} data["uid"] = 1000
+@print{} testff.awk modified: 09 29 2014 18:31:50
+@print{}
+@print{} Info for JUNK
+@print{} ret = -1
+@print{} JUNK modified: 01 01 1970 02:00:00
+@end example
+
+@node Extension Samples
+@section The Sample Extensions in the @command{gawk} Distribution
+@cindex extensions distributed with @command{gawk}
+
+This @value{SECTION} provides brief overviews of the sample extensions
+that come in the @command{gawk} distribution. Some of them are intended
+for production use (e.g., the @code{filefuncs}, @code{readdir} and
+@code{inplace} extensions). Others mainly provide example code that
+shows how to use the extension API.
+
+@menu
+* Extension Sample File Functions:: The file functions sample.
+* Extension Sample Fnmatch:: An interface to @code{fnmatch()}.
+* Extension Sample Fork:: An interface to @code{fork()} and other
+ process functions.
+* Extension Sample Inplace:: Enabling in-place file editing.
+* Extension Sample Ord:: Character to value to character
+ conversions.
+* Extension Sample Readdir:: An interface to @code{readdir()}.
+* Extension Sample Revout:: Reversing output sample output wrapper.
+* Extension Sample Rev2way:: Reversing data sample two-way processor.
+* Extension Sample Read write array:: Serializing an array to a file.
+* Extension Sample Readfile:: Reading an entire file into a string.
+* Extension Sample Time:: An interface to @code{gettimeofday()}
+ and @code{sleep()}.
+* Extension Sample API Tests:: Tests for the API.
+@end menu
+
+@node Extension Sample File Functions
+@subsection File-Related Functions
+
+The @code{filefuncs} extension provides three different functions, as follows.
+The usage is:
+
+@table @asis
+@item @code{@@load "filefuncs"}
+This is how you load the extension.
+
+@cindex @code{chdir()} extension function
+@item @code{result = chdir("/some/directory")}
+The @code{chdir()} function is a direct hook to the @code{chdir()}
+system call to change the current directory. It returns zero
+upon success or less than zero upon error. In the latter case, it updates
+@code{ERRNO}.
+
+@cindex @code{stat()} extension function
+@item @code{result = stat("/some/path", statdata} [@code{, follow}]@code{)}
+The @code{stat()} function provides a hook into the
+@code{stat()} system call.
+It returns zero upon success or less than zero upon error.
+In the latter case, it updates @code{ERRNO}.
+
+By default, it uses the @code{lstat()} system call. However, if passed
+a third argument, it uses @code{stat()} instead.
+
+In all cases, it clears the @code{statdata} array.
+When the call is successful, @code{stat()} fills the @code{statdata}
+array with information retrieved from the filesystem, as follows:
+
+@multitable @columnfractions .15 .50 .20
+@headitem Subscript @tab Field in @code{struct stat} @tab File type
+@item @code{"name"} @tab The @value{FN} @tab All
+@item @code{"dev"} @tab @code{st_dev} @tab All
+@item @code{"ino"} @tab @code{st_ino} @tab All
+@item @code{"mode"} @tab @code{st_mode} @tab All
+@item @code{"nlink"} @tab @code{st_nlink} @tab All
+@item @code{"uid"} @tab @code{st_uid} @tab All
+@item @code{"gid"} @tab @code{st_gid} @tab All
+@item @code{"size"} @tab @code{st_size} @tab All
+@item @code{"atime"} @tab @code{st_atime} @tab All
+@item @code{"mtime"} @tab @code{st_mtime} @tab All
+@item @code{"ctime"} @tab @code{st_ctime} @tab All
+@item @code{"rdev"} @tab @code{st_rdev} @tab Device files
+@item @code{"major"} @tab @code{st_major} @tab Device files
+@item @code{"minor"} @tab @code{st_minor} @tab Device files
+@item @code{"blksize"} @tab @code{st_blksize} @tab All
+@item @code{"pmode"} @tab A human-readable version of the mode value, such as printed by
+@command{ls}. For example, @code{"-rwxr-xr-x"} @tab All
+@item @code{"linkval"} @tab The value of the symbolic link @tab Symbolic links
+@item @code{"type"} @tab The type of the file as a string. One of
+@code{"file"},
+@code{"blockdev"},
+@code{"chardev"},
+@code{"directory"},
+@code{"socket"},
+@code{"fifo"},
+@code{"symlink"},
+@code{"door"},
+or
+@code{"unknown"}.
+Not all systems support all file types. @tab All
+@end multitable
+
+@cindex @code{fts()} extension function
+@item @code{flags = or(FTS_PHYSICAL, ...)}
+@itemx @code{result = fts(pathlist, flags, filedata)}
+Walk the file trees provided in @code{pathlist} and fill in the
+@code{filedata} array as described next. @code{flags} is the bitwise
+OR of several predefined values, also described in a moment.
+Return zero if there were no errors, otherwise return @minus{}1.
+@end table
+
+The @code{fts()} function provides a hook to the C library @code{fts()}
+routines for traversing file hierarchies. Instead of returning data
+about one file at a time in a stream, it fills in a multidimensional
+array with data about each file and directory encountered in the requested
+hierarchies.
+
+The arguments are as follows:
+
+@table @code
+@item pathlist
+An array of @value{FN}s. The element values are used; the index values are ignored.
+
+@item flags
+This should be the bitwise OR of one or more of the following
+predefined constant flag values. At least one of
+@code{FTS_LOGICAL} or @code{FTS_PHYSICAL} must be provided; otherwise
+@code{fts()} returns an error value and sets @code{ERRNO}.
+The flags are:
+
+@c nested table
+@table @code
+@item FTS_LOGICAL
+Do a ``logical'' file traversal, where the information returned for
+a symbolic link refers to the linked-to file, and not to the symbolic
+link itself. This flag is mutually exclusive with @code{FTS_PHYSICAL}.
+
+@item FTS_PHYSICAL
+Do a ``physical'' file traversal, where the information returned for a
+symbolic link refers to the symbolic link itself. This flag is mutually
+exclusive with @code{FTS_LOGICAL}.
+
+@item FTS_NOCHDIR
+As a performance optimization, the C library @code{fts()} routines
+change directory as they traverse a file hierarchy. This flag disables
+that optimization.
+
+@item FTS_COMFOLLOW
+Immediately follow a symbolic link named in @code{pathlist},
+whether or not @code{FTS_LOGICAL} is set.
+
+@item FTS_SEEDOT
+By default, the C library @code{fts()} routines do not return entries for
+@file{.} (dot) and @file{..} (dot-dot). This option causes entries for
+dot-dot to also be included. (The extension always includes an entry
+for dot; more on this in a moment.)
+
+@item FTS_XDEV
+During a traversal, do not cross onto a different mounted filesystem.
+@end table
+
+@item filedata
+The @code{filedata} array is first cleared. Then, @code{fts()} creates
+an element in @code{filedata} for every element in @code{pathlist}.
+The index is the name of the directory or file given in @code{pathlist}.
+The element for this index is itself an array. There are two cases:
+
+@c nested table
+@table @emph
+@item The path is a file
+In this case, the array contains two or three elements:
+
+@c doubly nested table
+@table @code
+@item "path"
+The full path to this file, starting from the ``root'' that was given
+in the @code{pathlist} array.
+
+@item "stat"
+This element is itself an array, containing the same information as provided
+by the @code{stat()} function described earlier for its
+@code{statdata} argument. The element may not be present if
+the @code{stat()} system call for the file failed.
+
+@item "error"
+If some kind of error was encountered, the array will also
+contain an element named @code{"error"}, which is a string describing the error.
+@end table
+
+@item The path is a directory
+In this case, the array contains one element for each entry in the
+directory. If an entry is a file, that element is the same as for files, just
+described. If the entry is a directory, that element is (recursively)
+an array describing the subdirectory. If @code{FTS_SEEDOT} was provided
+in the flags, then there will also be an element named @code{".."}. This
+element will be an array containing the data as provided by @code{stat()}.
+
+In addition, there will be an element whose index is @code{"."}.
+This element is an array containing the same two or three elements as
+for a file: @code{"path"}, @code{"stat"}, and @code{"error"}.
+@end table
+@end table
+
+The @code{fts()} function returns zero if there were no errors.
+Otherwise it returns @minus{}1.
+
+@quotation NOTE
+The @code{fts()} extension does not exactly mimic the
+interface of the C library @code{fts()} routines, choosing instead to
+provide an interface that is based on associative arrays, which is
+more comfortable to use from an @command{awk} program. This includes the
+lack of a comparison function, because @command{gawk} already provides
+powerful array sorting facilities. Although an @code{fts_read()}-like
+interface could have been provided, this felt less natural than simply
+creating a multidimensional array to represent the file hierarchy and
+its information.
+@end quotation
+
+See @file{test/fts.awk} in the @command{gawk} distribution for an example
+use of the @code{fts()} extension function.
+
+@node Extension Sample Fnmatch
+@subsection Interface to @code{fnmatch()}
+
+This extension provides an interface to the C library
+@code{fnmatch()} function. The usage is:
+
+@table @code
+@item @@load "fnmatch"
+This is how you load the extension.
+
+@cindex @code{fnmatch()} extension function
+@item result = fnmatch(pattern, string, flags)
+The return value is zero on success, @code{FNM_NOMATCH}
+if the string did not match the pattern, or
+a different nonzero value if an error occurred.
+@end table
+
+In addition to the @code{fnmatch()} function, the @code{fnmatch} extension
+adds one constant (@code{FNM_NOMATCH}), and an array of flag values
+named @code{FNM}.
+
+The arguments to @code{fnmatch()} are:
+
+@table @code
+@item pattern
+The @value{FN} wildcard to match.
+
+@item string
+The @value{FN} string.
+
+@item flag
+Either zero, or the bitwise OR of one or more of the
+flags in the @code{FNM} array.
+@end table
+
+The flags are as follows:
+
+@multitable @columnfractions .25 .75
+@headitem Array element @tab Corresponding flag defined by @code{fnmatch()}
+@item @code{FNM["CASEFOLD"]} @tab @code{FNM_CASEFOLD}
+@item @code{FNM["FILE_NAME"]} @tab @code{FNM_FILE_NAME}
+@item @code{FNM["LEADING_DIR"]} @tab @code{FNM_LEADING_DIR}
+@item @code{FNM["NOESCAPE"]} @tab @code{FNM_NOESCAPE}
+@item @code{FNM["PATHNAME"]} @tab @code{FNM_PATHNAME}
+@item @code{FNM["PERIOD"]} @tab @code{FNM_PERIOD}
+@end multitable
+
+Here is an example:
+
+@example
+@@load "fnmatch"
+@dots{}
+flags = or(FNM["PERIOD"], FNM["NOESCAPE"])
+if (fnmatch("*.a", "foo.c", flags) == FNM_NOMATCH)
+ print "no match"
+@end example
+
+@node Extension Sample Fork
+@subsection Interface to @code{fork()}, @code{wait()}, and @code{waitpid()}
+
+The @code{fork} extension adds three functions, as follows:
+
+@table @code
+@item @@load "fork"
+This is how you load the extension.
+
+@cindex @code{fork()} extension function
+@item pid = fork()
+This function creates a new process. The return value is zero in the
+child and the process-ID number of the child in the parent, or @minus{}1
+upon error. In the latter case, @code{ERRNO} indicates the problem.
+In the child, @code{PROCINFO["pid"]} and @code{PROCINFO["ppid"]} are
+updated to reflect the correct values.
+
+@cindex @code{waitpid()} extension function
+@item ret = waitpid(pid)
+This function takes a numeric argument, which is the process-ID to
+wait for. The return value is that of the
+@code{waitpid()} system call.
+
+@cindex @code{wait()} extension function
+@item ret = wait()
+This function waits for the first child to die.
+The return value is that of the
+@code{wait()} system call.
+@end table
+
+There is no corresponding @code{exec()} function.
+
+Here is an example:
+
+@example
+@@load "fork"
+@dots{}
+if ((pid = fork()) == 0)
+ print "hello from the child"
+else
+ print "hello from the parent"
+@end example
+
+@node Extension Sample Inplace
+@subsection Enabling In-Place File Editing
+
+@cindex @code{inplace} extension
+The @code{inplace} extension emulates GNU @command{sed}'s @option{-i} option
+which performs ``in place'' editing of each input file.
+It uses the bundled @file{inplace.awk} include file to invoke the extension
+properly:
+
+@example
+@c file eg/lib/inplace.awk
+@group
+# inplace --- load and invoke the inplace extension.
+
+@@load "inplace"
+
+# Please set INPLACE_SUFFIX to make a backup copy. For example, you may
+# want to set INPLACE_SUFFIX to .bak on the command line or in a BEGIN rule.
+
+BEGINFILE @{
+ inplace_begin(FILENAME, INPLACE_SUFFIX)
+@}
+
+ENDFILE @{
+ inplace_end(FILENAME, INPLACE_SUFFIX)
+@}
+@end group
+@c endfile
+@end example
+
+For each regular file that is processed, the extension redirects
+standard output to a temporary file configured to have the same owner
+and permissions as the original. After the file has been processed,
+the extension restores standard output to its original destination.
+If @code{INPLACE_SUFFIX} is not an empty string, the original file is
+linked to a backup @value{FN} created by appending that suffix. Finally,
+the temporary file is renamed to the original @value{FN}.
+
+If any error occurs, the extension issues a fatal error to terminate
+processing immediately without damaging the original file.
+
+Here are some simple examples:
+
+@example
+$ @kbd{gawk -i inplace '@{ gsub(/foo/, "bar") @}; @{ print @}' file1 file2 file3}
+@end example
+
+To keep a backup copy of the original files, try this:
+
+@example
+$ @kbd{gawk -i inplace -v INPLACE_SUFFIX=.bak '@{ gsub(/foo/, "bar") @}}
+> @kbd{@{ print @}' file1 file2 file3}
+@end example
+
+@node Extension Sample Ord
+@subsection Character and Numeric values: @code{ord()} and @code{chr()}
+
+The @code{ordchr} extension adds two functions, named
+@code{ord()} and @code{chr()}, as follows:
+
+@table @code
+@item @@load "ordchr"
+This is how you load the extension.
+
+@cindex @code{ord()} extension function
+@item number = ord(string)
+Return the numeric value of the first character in @code{string}.
+
+@cindex @code{chr()} extension function
+@item char = chr(number)
+Return a string whose first character is that represented by @code{number}.
+@end table
+
+These functions are inspired by the Pascal language functions
+of the same name. Here is an example:
+
+@example
+@@load "ordchr"
+@dots{}
+printf("The numeric value of 'A' is %d\n", ord("A"))
+printf("The string value of 65 is %s\n", chr(65))
+@end example
+
+@node Extension Sample Readdir
+@subsection Reading Directories
+
+The @code{readdir} extension adds an input parser for directories.
+The usage is as follows:
+
+@cindex @code{readdir} extension
+@example
+@@load "readdir"
+@end example
+
+When this extension is in use, instead of skipping directories named
+on the command line (or with @code{getline}),
+they are read, with each entry returned as a record.
+
+The record consists of three fields. The first two are the inode number and the
+@value{FN}, separated by a forward slash character.
+On systems where the directory entry contains the file type, the record
+has a third field (also separated by a slash) which is a single letter
+indicating the type of the file. The letters and their corresponding file
+types are shown in @ref{table-readdir-file-types}.
+
+@float Table,table-readdir-file-types
+@caption{File types returned by the @code{readdir} extension}
+@multitable @columnfractions .1 .9
+@headitem Letter @tab File Type
+@item @code{b} @tab Block device
+@item @code{c} @tab Character device
+@item @code{d} @tab Directory
+@item @code{f} @tab Regular file
+@item @code{l} @tab Symbolic link
+@item @code{p} @tab Named pipe (FIFO)
+@item @code{s} @tab Socket
+@item @code{u} @tab Anything else (unknown)
+@end multitable
+@end float
+
+On systems without the file type information, the third field is always
+@samp{u}.
+
+@quotation NOTE
+On GNU/Linux systems, there are filesystems that don't support the
+@code{d_type} entry (see the @i{readdir}(3) manual page), and so the file
+type is always @samp{u}. You can use the @code{filefuncs} extension to call
+@code{stat()} in order to get correct type information.
+@end quotation
+
+Here is an example:
+
+@example
+@@load "readdir"
+@dots{}
+BEGIN @{ FS = "/" @}
+@{ print "file name is", $2 @}
+@end example
+
+@node Extension Sample Revout
+@subsection Reversing Output
+
+The @code{revoutput} extension adds a simple output wrapper that reverses
+the characters in each output line. Its main purpose is to show how to
+write an output wrapper, although it may be mildly amusing for the unwary.
+Here is an example:
+
+@cindex @code{revoutput} extension
+@example
+@@load "revoutput"
+
+BEGIN @{
+ REVOUT = 1
+ print "don't panic" > "/dev/stdout"
+@}
+@end example
+
+The output from this program is:
+@samp{cinap t'nod}.
+
+@node Extension Sample Rev2way
+@subsection Two-Way I/O Example
+
+The @code{revtwoway} extension adds a simple two-way processor that
+reverses the characters in each line sent to it for reading back by
+the @command{awk} program. Its main purpose is to show how to write
+a two-way processor, although it may also be mildly amusing.
+The following example shows how to use it:
+
+@cindex @code{revtwoway} extension
+@example
+@@load "revtwoway"
+
+BEGIN @{
+ cmd = "/magic/mirror"
+ print "don't panic" |& cmd
+ cmd |& getline result
+ print result
+ close(cmd)
+@}
+@end example
+
+The output from this program
+@ifnotinfo
+also is:
+@end ifnotinfo
+@ifinfo
+is:
+@end ifinfo
+@samp{cinap t'nod}.
+
+@node Extension Sample Read write array
+@subsection Dumping and Restoring an Array
+
+The @code{rwarray} extension adds two functions,
+named @code{writea()} and @code{reada()}, as follows:
+
+@table @code
+@item @@load "rwarray"
+This is how you load the extension.
+
+@cindex @code{writea()} extension function
+@item ret = writea(file, array)
+This function takes a string argument, which is the name of the file
+to which to dump the array, and the array itself as the second argument.
+@code{writea()} understands arrays of arrays. It returns one on
+success, or zero upon failure.
+
+@cindex @code{reada()} extension function
+@item ret = reada(file, array)
+@code{reada()} is the inverse of @code{writea()};
+it reads the file named as its first argument, filling in
+the array named as the second argument. It clears the array first.
+Here too, the return value is one on success and zero upon failure.
+@end table
+
+The array created by @code{reada()} is identical to that written by
+@code{writea()} in the sense that the contents are the same. However,
+due to implementation issues, the array traversal order of the re-created
+array is likely to be different from that of the original array. As array
+traversal order in @command{awk} is by default undefined, this is (technically)
+not a problem. If you need to guarantee a particular traversal
+order, use the array sorting features in @command{gawk} to do so
+(@pxref{Array Sorting}).
+
+The file contains binary data. All integral values are written in network
+byte order. However, double-precision floating-point values are written
+as native binary data. Thus, arrays containing only string data can
+theoretically be dumped on systems with one byte order and restored on
+systems with a different one, but this has not been tried.
+
+Here is an example:
+
+@example
+@@load "rwarray"
+@dots{}
+ret = writea("arraydump.bin", array)
+@dots{}
+ret = reada("arraydump.bin", array)
+@end example
+
+@node Extension Sample Readfile
+@subsection Reading an Entire File
+
+The @code{readfile} extension adds a single function
+named @code{readfile()}, and an input parser:
+
+@table @code
+@item @@load "readfile"
+This is how you load the extension.
+
+@cindex @code{readfile()} extension function
+@item result = readfile("/some/path")
+The argument is the name of the file to read. The return value is a
+string containing the entire contents of the requested file. Upon error,
+the function returns the empty string and sets @code{ERRNO}.
+
+@item BEGIN @{ PROCINFO["readfile"] = 1 @}
+In addition, the extension adds an input parser that is activated if
+@code{PROCINFO["readfile"]} exists.
+When activated, each input file is returned in its entirety as @code{$0}.
+@code{RT} is set to the null string.
+@end table
+
+Here is an example:
+
+@example
+@@load "readfile"
+@dots{}
+contents = readfile("/path/to/file");
+if (contents == "" && ERRNO != "") @{
+ print("problem reading file", ERRNO) > "/dev/stderr"
+ ...
+@}
+@end example
+
+@node Extension Sample Time
+@subsection Extension Time Functions
+
+The @code{time} extension adds two functions, named @code{gettimeofday()}
+and @code{sleep()}, as follows:
+
+@table @code
+@item @@load "time"
+This is how you load the extension.
+
+@cindex @code{gettimeofday()} extension function
+@item the_time = gettimeofday()
+Return the time in seconds that has elapsed since 1970-01-01 UTC as a
+floating-point value. If the time is unavailable on this platform, return
+@minus{}1 and set @code{ERRNO}. The returned time should have sub-second
+precision, but the actual precision may vary based on the platform.
+If the standard C @code{gettimeofday()} system call is available on this
+platform, then it simply returns the value. Otherwise, if on MS-Windows,
+it tries to use @code{GetSystemTimeAsFileTime()}.
+
+@cindex @code{sleep()} extension function
+@item result = sleep(@var{seconds})
+Attempt to sleep for @var{seconds} seconds. If @var{seconds} is negative,
+or the attempt to sleep fails, return @minus{}1 and set @code{ERRNO}.
+Otherwise, return zero after sleeping for the indicated amount of time.
+Note that @var{seconds} may be a floating-point (non-integral) value.
+Implementation details: depending on platform availability, this function
+tries to use @code{nanosleep()} or @code{select()} to implement the delay.
+@end table
+
+@node Extension Sample API Tests
+@subsection API Tests
+@cindex @code{testext} extension
+
+The @code{testext} extension exercises parts of the extension API that
+are not tested by the other samples. The @file{extension/testext.c}
+file contains both the C code for the extension and @command{awk}
+test code inside C comments that run the tests. The testing framework
+extracts the @command{awk} code and runs the tests. See the source file
+for more information.
+
+@node gawkextlib
+@section The @code{gawkextlib} Project
+@cindex @code{gawkextlib}
+@cindex extensions, where to find
+
+@cindex @code{gawkextlib} project
+The @uref{http://sourceforge.net/projects/gawkextlib/, @code{gawkextlib}}
+project provides a number of @command{gawk} extensions, including one for
+processing XML files. This is the evolution of the original @command{xgawk}
+(XML @command{gawk}) project.
+
+As of this writing, there are six extensions:
+
+@itemize @value{BULLET}
+@item
+GD graphics library extension
+
+@item
+PDF extension
+
+@item
+PostgreSQL extension
+
+@item
+MPFR library extension
+(this provides access to a number of MPFR functions which @command{gawk}'s
+native MPFR support does not)
+
+@item
+Redis extension
+
+@item
+XML parser extension, using the @uref{http://expat.sourceforge.net, Expat}
+XML parsing library
+@end itemize
+
+@cindex @command{git} utility
+You can check out the code for the @code{gawkextlib} project
+using the @uref{http://git-scm.com, Git} distributed source
+code control system. The command is as follows:
+
+@example
+git clone git://git.code.sf.net/p/gawkextlib/code gawkextlib-code
+@end example
+
+@cindex Expat XML parser library
+You will need to have the @uref{http://expat.sourceforge.net, Expat}
+XML parser library installed in order to build and use the XML extension.
+
+In addition, you must have the GNU Autotools installed
+(@uref{http://www.gnu.org/software/autoconf, Autoconf},
+@uref{http://www.gnu.org/software/automake, Automake},
+@uref{http://www.gnu.org/software/libtool, Libtool},
+and
+@uref{http://www.gnu.org/software/gettext, GNU @command{gettext}}).
+
+The simple recipe for building and testing @code{gawkextlib} is as follows.
+First, build and install @command{gawk}:
+
+@example
+cd .../path/to/gawk/code
+./configure --prefix=/tmp/newgawk @ii{Install in /tmp/newgawk for now}
+make && make check @ii{Build and check that all is OK}
+make install @ii{Install gawk}
+@end example
+
+Next, build @code{gawkextlib} and test it:
+
+@example
+cd .../path/to/gawkextlib-code
+./update-autotools @ii{Generate configure, etc.}
+ @ii{You may have to run this command twice}
+./configure --with-gawk=/tmp/newgawk @ii{Configure, point at ``installed'' gawk}
+make && make check @ii{Build and check that all is OK}
+make install @ii{Install the extensions}
+@end example
+
+If you have installed @command{gawk} in the standard way, then you
+will likely not need the @option{--with-gawk} option when configuring
+@code{gawkextlib}. You may also need to use the @command{sudo} utility
+to install both @command{gawk} and @code{gawkextlib}, depending upon
+how your system works.
+
+If you write an extension that you wish to share with other
+@command{gawk} users, consider doing so through the
+@code{gawkextlib} project.
+See the project's website for more information.
+
+@node Extension summary
+@section Summary
+
+@itemize @value{BULLET}
+@item
+You can write extensions (sometimes called plug-ins) for @command{gawk}
+in C or C++ using the application programming interface (API) defined
+by the @command{gawk} developers.
+
+@item
+Extensions must have a license compatible with the GNU General Public
+License (GPL), and they must assert that fact by declaring a variable
+named @code{plugin_is_GPL_compatible}.
+
+@item
+Communication between @command{gawk} and an extension is two-way.
+@command{gawk} passes a @code{struct} to the extension which contains
+various data fields and function pointers. The extension can then call
+into @command{gawk} via the supplied function pointers to accomplish
+certain tasks.
+
+@item
+One of these tasks is to ``register'' the name and implementation of
+new @command{awk}-level functions with @command{gawk}. The implementation
+takes the form of a C function pointer with a defined signature.
+By convention, implementation functions are named @code{do_@var{XXXX}()}
+for some @command{awk}-level function @code{@var{XXXX}()}.
+
+@item
+The API is defined in a header file named @file{gawkpi.h}. You must include
+a number of standard header files @emph{before} including it in your source file.
+
+@item
+API function pointers are provided for the following kinds of operations:
+
+@itemize @value{BULLET}
+@item
+Allocating, reallocating, and releasing memory
+
+@item
+Registration functions (you may register
+extension functions,
+exit callbacks,
+a version string,
+input parsers,
+output wrappers,
+and two-way processors)
+
+@item
+Printing fatal, warning, and ``lint'' warning messages
+
+@item
+Updating @code{ERRNO}, or unsetting it
+
+@item
+Accessing parameters, including converting an undefined parameter into
+an array
+
+@item
+Symbol table access (retrieving a global variable, creating one,
+or changing one)
+
+@item
+Creating and releasing cached values; this provides an
+efficient way to use values for multiple variables and
+can be a big performance win
+
+@item
+Manipulating arrays
+(retrieving, adding, deleting, and modifying elements;
+getting the count of elements in an array;
+creating a new array;
+clearing an array;
+and
+flattening an array for easy C style looping over all its indices and elements)
+@end itemize
+
+@item
+The API defines a number of standard data types for representing
+@command{awk} values, array elements, and arrays.
+
+@item
+The API provide convenience functions for constructing values.
+It also provides memory management functions to ensure compatibility
+between memory allocated by @command{gawk} and memory allocated by an
+extension.
+
+@item
+@emph{All} memory passed from @command{gawk} to an extension must be
+treated as read-only by the extension.
+
+@item
+@emph{All} memory passed from an extension to @command{gawk} must come from
+the API's memory allocation functions. @command{gawk} takes responsibility for
+the memory and releases it when appropriate.
+
+@item
+The API provides information about the running version of @command{gawk} so
+that an extension can make sure it is compatible with the @command{gawk}
+that loaded it.
+
+@item
+It is easiest to start a new extension by copying the boilerplate code
+described in this @value{CHAPTER}. Macros in the @file{gawkapi.h} header
+file make this easier to do.
+
+@item
+The @command{gawk} distribution includes a number of small but useful
+sample extensions. The @code{gawkextlib} project includes several more,
+larger, extensions. If you wish to write an extension and contribute it
+to the community of @command{gawk} users, the @code{gawkextlib} project
+is the place to do so.
+
+@end itemize
+
+@c EXCLUDE START
+@node Extension Exercises
+@section Exercises
+
+@enumerate
+@item
+Add functions to implement system calls such as @code{chown()},
+@code{chmod()}, and @code{umask()} to the file operations extension
+presented in @ref{Internal File Ops}.
+
+@item
+(Hard.)
+How would you provide namespaces in @command{gawk}, so that the
+names of functions in different extensions don't conflict with each other?
+If you come up with a really good scheme, contact the @command{gawk}
+maintainer to tell him about it.
+
+@item
+Write a wrapper script that provides an interface similar to
+@samp{sed -i} for the ``inplace'' extension presented in
+@ref{Extension Sample Inplace}.
+
+@end enumerate
+@c EXCLUDE END
+
+@ifnotinfo
+@part @value{PART4}Appendices
+@end ifnotinfo
+
+@ifdocbook
+
+@ifclear FOR_PRINT
+Part IV contains the appendices (including the two licenses that cover
+the @command{gawk} source code and this @value{DOCUMENT}, respectively)
+and the Glossary:
+@end ifclear
+
+@ifset FOR_PRINT
+Part IV contains three appendices, the last of which is the license that
+covers the @command{gawk} source code:
+@end ifset
+
+@itemize @value{BULLET}
+@item
+@ref{Language History}
+
+@item
+@ref{Installation}
+
+@ifclear FOR_PRINT
+@item
+@ref{Notes}
+
+@item
+@ref{Basic Concepts}
+
+@item
+@ref{Glossary}
+@end ifclear
+
+@item
+@ref{Copying}
+
+@ifclear FOR_PRINT
+@item
+@ref{GNU Free Documentation License}
+@end ifclear
+@end itemize
+@end ifdocbook
+
+@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 longtime @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, for a while, some systems derived from 4.4BSD-Lite, used 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.
+
+@ifset FOR_PRINT
+To save space, we have omitted
+information on the history of features in @command{gawk} from this
+edition. You can find it in the
+@uref{http://www.gnu.org/software/gawk/manual/html_node/Feature-History.html,
+online documentation}.
+@end ifset
+
+@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 Brian Kernighan's version of
+ @command{awk}.
+* POSIX/GNU:: The extensions in @command{gawk} not in POSIX
+ @command{awk}.
+* Feature History:: The history of the features in @command{gawk}.
+* Common Extensions:: Common Extensions Summary.
+* Ranges and Locales:: How locales used to affect regexp ranges.
+* Contributors:: The major contributors to @command{gawk}.
+* History summary:: History summary.
+@end menu
+
+@node V7/SVR3.1
+@appendixsec Major Changes Between V7 and SVR3.1
+@cindex @command{awk}, versions of
+@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 @value{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} predefined variables (@pxref{Built-in Variables}).
+
+@item
+Assignable @code{$0} (@pxref{Changing Fields}).
+
+@item
+The conditional expression using the ternary operator @samp{?:}
+(@pxref{Conditional Exp}).
+
+@item
+The expression @samp{@var{index-variable} in @var{array}} outside of @code{for}
+statements (@pxref{Reference to Elements}).
+
+@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}), rather than using only the first character
+of @code{FS}.
+
+@item
+Dynamic regexps as operands of the @samp{~} and @samp{!~} operators
+(@pxref{Computed Regexps}).
+
+@item
+The escape sequences @samp{\b}, @samp{\f}, and @samp{\r}
+(@pxref{Escape Sequences}).
+
+@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{Multidimensional}).
+@end itemize
+
+@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 @value{BULLET}
+@item
+The @code{ENVIRON} array (@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{--} signal 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 @code{printf} and @code{sprintf()}
+(@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 @value{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
+The use of predefined variables as function parameter names is forbidden
+(@pxref{Definition Syntax}).
+
+@item
+More complete documentation of many of the previously undocumented
+features of the language.
+@end itemize
+
+In 2012, a number of extensions that had been commonly available for
+many years were finally added to POSIX. They are:
+
+@itemize @value{BULLET}
+@item
+The @code{fflush()} built-in function for flushing buffered output
+(@pxref{I/O Functions}).
+
+@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
+
+@DBXREF{Common Extensions} for a list of common extensions
+not permitted by the POSIX standard.
+
+The 2008 POSIX standard can be found online at
+@url{http://www.opengroup.org/onlinepubs/9699919799/}.
+
+
+@node BTL
+@appendixsec Extensions in Brian Kernighan's @command{awk}
+
+@cindex @command{awk}, versions of, See Also Brian Kernighan's @command{awk}
+@cindex extensions, Brian Kernighan's @command{awk}
+@cindex Brian Kernighan's @command{awk}, extensions
+@cindex Kernighan, Brian
+Brian Kernighan
+has made his version available via his home page
+(@pxref{Other Versions}).
+
+This @value{SECTION} describes common extensions that
+originally appeared in his version of @command{awk}:
+
+@itemize @value{BULLET}
+@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}).
+
+@item
+The @code{fflush()} built-in function for flushing buffered output
+(@pxref{I/O Functions}).
+
+@ignore
+@item
+The @code{SYMTAB} array, that allows access to @command{awk}'s internal symbol
+table. This feature was never documented for his @command{awk}, largely because
+it is somewhat shakily implemented. For instance, you cannot access arrays
+or array elements through it.
+@end ignore
+@end itemize
+
+@DBXREF{Common Extensions} for a full list of the extensions
+available in his @command{awk}.
+
+@node POSIX/GNU
+@appendixsec Extensions in @command{gawk} Not in POSIX @command{awk}
+
+@cindex compatibility mode (@command{gawk}), extensions
+@cindex extensions, in @command{gawk}, not in POSIX @command{awk}
+@cindex POSIX, @command{gawk} extensions not included in
+The GNU implementation, @command{gawk}, adds a large number of features.
+They can all be disabled with either the @option{--traditional} or
+@option{--posix} options
+(@pxref{Options}).
+
+A number of features have come and gone over the years. This @value{SECTION}
+summarizes the additional features over POSIX @command{awk} that are
+in the current version of @command{gawk}.
+
+@itemize @value{BULLET}
+
+@item
+Additional predefined variables:
+
+@itemize @value{MINUS}
+@item
+The
+@code{ARGIND}
+@code{BINMODE},
+@code{ERRNO},
+@code{FIELDWIDTHS},
+@code{FPAT},
+@code{IGNORECASE},
+@code{LINT},
+@code{PROCINFO},
+@code{RT},
+and
+@code{TEXTDOMAIN}
+variables
+(@pxref{Built-in Variables}).
+@end itemize
+
+@item
+Special files in I/O redirections:
+
+@itemize @value{MINUS}
+@item
+The @file{/dev/stdin}, @file{/dev/stdout}, @file{/dev/stderr} and
+@file{/dev/fd/@var{N}} special @value{FN}s
+(@pxref{Special Files}).
+
+@item
+The @file{/inet}, @file{/inet4}, and @samp{/inet6} special files for
+TCP/IP networking using @samp{|&} to specify which version of the
+IP protocol to use
+(@pxref{TCP/IP Networking}).
+@end itemize
+
+@item
+Changes and/or additions to the language:
+
+@itemize @value{MINUS}
+@item
+The @samp{\x} escape sequence
+(@pxref{Escape Sequences}).
+
+@item
+Full support for both POSIX and GNU regexps
+(@pxref{Regexp}).
+
+@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 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
+Indirect function calls
+(@pxref{Indirect Calls}).
+
+@item
+Directories on the command line produce a warning and are skipped
+(@pxref{Command-line directories}).
+@end itemize
+
+@item
+New keywords:
+
+@itemize @value{MINUS}
+@item
+The @code{BEGINFILE} and @code{ENDFILE} special patterns
+(@pxref{BEGINFILE/ENDFILE}).
+
+@item
+The @code{switch} statement
+(@pxref{Switch Statement}).
+@end itemize
+
+@item
+Changes to standard @command{awk} functions:
+
+@itemize @value{MINUS}
+@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
+POSIX compliance for @code{gsub()} and @code{sub()} with @option{--posix}.
+
+@item
+The @code{length()} function accepts an array argument
+and returns the number of elements in the array
+(@pxref{String Functions}).
+
+@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{split()} function's additional optional fourth
+argument which is an array to hold the text of the field separators
+(@pxref{String Functions}).
+@end itemize
+
+@item
+Additional functions only in @command{gawk}:
+
+@itemize @value{MINUS}
+@item
+The @code{gensub()}, @code{patsplit()}, and @code{strtonum()} functions
+for more powerful text manipulation
+(@pxref{String Functions}).
+
+@item
+The @code{asort()} and @code{asorti()} functions for sorting arrays
+(@pxref{Array Sorting}).
+
+@item
+The @code{mktime()}, @code{systime()}, and @code{strftime()}
+functions for working with timestamps
+(@pxref{Time Functions}).
+
+@item
+The
+@code{and()},
+@code{compl()},
+@code{lshift()},
+@code{or()},
+@code{rshift()},
+and
+@code{xor()}
+functions for bit manipulation
+(@pxref{Bitwise Functions}).
+@c In 4.1, and(), or() and xor() grew the ability to take > 2 arguments
+
+@item
+The @code{isarray()} function to check if a variable is an array or not
+(@pxref{Type Functions}).
+
+@item
+The @code{bindtextdomain()}, @code{dcgettext()} and @code{dcngettext()}
+functions for internationalization
+(@pxref{Programmer i18n}).
+@end itemize
+
+@item
+Changes and/or additions in the command-line options:
+
+@itemize @value{MINUS}
+@item
+The @env{AWKPATH} environment variable for specifying a path search for
+the @option{-f} command-line option
+(@pxref{Options}).
+
+@item
+The @env{AWKLIBPATH} environment variable for specifying a path search for
+the @option{-l} command-line option
+(@pxref{Options}).
+
+@item
+The
+@option{-b},
+@option{-c},
+@option{-C},
+@option{-d},
+@option{-D},
+@option{-e},
+@option{-E},
+@option{-g},
+@option{-h},
+@option{-i},
+@option{-l},
+@option{-L},
+@option{-M},
+@option{-n},
+@option{-N},
+@option{-o},
+@option{-O},
+@option{-p},
+@option{-P},
+@option{-r},
+@option{-S},
+@option{-t},
+and
+@option{-V}
+short options. Also, the
+ability to use GNU-style long-named options that start with @option{--}
+and the
+@option{--assign},
+@option{--bignum},
+@option{--characters-as-bytes},
+@option{--copyright},
+@option{--debug},
+@option{--dump-variables},
+@option{--exec},
+@option{--field-separator},
+@option{--file},
+@option{--gen-pot},
+@option{--help},
+@option{--include},
+@option{--lint},
+@option{--lint-old},
+@option{--load},
+@option{--non-decimal-data},
+@option{--optimize},
+@option{--posix},
+@option{--pretty-print},
+@option{--profile},
+@option{--re-interval},
+@option{--sandbox},
+@option{--source},
+@option{--traditional},
+@option{--use-lc-numeric},
+and
+@option{--version}
+long options
+(@pxref{Options}).
+@end itemize
+
+@c new ports
+
+@item
+Support for the following obsolete systems was removed from the code
+and the documentation for @command{gawk} @value{PVERSION} 4.0:
+
+@c nested table
+@itemize @value{MINUS}
+@item
+Amiga
+
+@item
+Atari
+
+@item
+BeOS
+
+@item
+Cray
+
+@item
+MIPS RiscOS
+
+@item
+MS-DOS with the Microsoft Compiler
+
+@item
+MS-Windows with the Microsoft Compiler
+
+@item
+NeXT
+
+@item
+SunOS 3.x, Sun 386 (Road Runner)
+
+@item
+Tandem (non-POSIX)
+
+@item
+Prestandard VAX C compiler for VAX/VMS
+
+@item
+GCC for VAX and Alpha has not been tested for a while.
+
+@end itemize
+
+@item
+Support for the following obsolete systems was removed from the code
+for @command{gawk} @value{PVERSION} 4.1:
+
+@c nested table
+@itemize @value{MINUS}
+@item
+Ultrix
+@end itemize
+
+@item
+@c FIXME: Verify the version here.
+Support for MirBSD was removed at @command{gawk} @value{PVERSION} 4.2.
+
+@end itemize
+
+@c XXX ADD MORE STUFF HERE
+
+
+@c This does not need to be in the formal book.
+@ifclear FOR_PRINT
+@node Feature History
+@appendixsec History of @command{gawk} Features
+
+@ignore
+See the thread:
+https://groups.google.com/forum/#!topic/comp.lang.awk/SAUiRuff30c
+This motivated me to add this section.
+@end ignore
+
+@ignore
+I've tried to follow this general order, esp.@: for the 3.0 and 3.1 sections:
+ variables
+ special files
+ language changes (e.g., hex constants)
+ differences in standard awk functions
+ new gawk functions
+ new keywords
+ new command-line options
+ behavioral changes
+ new ports
+Within each category, be alphabetical.
+@end ignore
+
+This @value{SECTION} describes the features in @command{gawk}
+over and above those in POSIX @command{awk},
+in the order they were added to @command{gawk}.
+
+Version 2.10 of @command{gawk} introduced the following features:
+
+@itemize @value{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 @value{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
+Additional command-line options
+(@pxref{Options}):
+
+@itemize @value{MINUS}
+@item
+The @option{-W lint} option to provide error and portability checking
+for both the source code and at runtime.
+
+@item
+The @option{-W compat} option to turn off the GNU extensions.
+
+@item
+The @option{-W posix} option for full POSIX compliance.
+@end itemize
+@end itemize
+
+Version 2.14 of @command{gawk} introduced the following feature:
+
+@itemize @value{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 @value{BULLET}
+@item
+New variables (@pxref{Built-in Variables}):
+
+@itemize @value{MINUS}
+@item
+@code{ARGIND}, which tracks the movement of @code{FILENAME}
+through @code{ARGV}.
+
+@item
+@code{ERRNO}, which contains the system error message when
+@code{getline} returns @minus{}1 or @code{close()} fails.
+@end itemize
+
+@item
+The @file{/dev/pid}, @file{/dev/ppid}, @file{/dev/pgrpid}, and
+@file{/dev/user} special @value{FN}s. These have since been removed.
+
+@item
+The ability to delete all of an array at once with @samp{delete @var{array}}
+(@pxref{Delete}).
+
+@item
+Command-line option changes
+(@pxref{Options}):
+
+@itemize @value{MINUS}
+@item
+The ability to use GNU-style long-named options that start with @option{--}.
+
+@item
+The @option{--source} option for mixing command-line and library-file
+source code.
+@end itemize
+@end itemize
+
+Version 3.0 of @command{gawk} introduced the following features:
+
+@itemize @value{BULLET}
+@item
+New or changed variables:
+
+@itemize @value{MINUS}
+@item
+@code{IGNORECASE} changed, now applying to string comparison as well
+as regexp operations
+(@pxref{Case-sensitivity}).
+
+@item
+@code{RT}, which contains the input text that matched @code{RS}
+(@pxref{Records}).
+@end itemize
+
+@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 @code{fflush()} function from
+BWK @command{awk}
+(then at Bell Laboratories;
+@pxref{I/O Functions}).
+
+@item
+New command-line options:
+
+@itemize @value{MINUS}
+@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 from BWK @command{awk}. (Brian was
+still at Bell Laboratories at the time.) This was later removed from
+both his @command{awk} and from @command{gawk}.
+
+@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}).
+@end itemize
+
+@item
+The use of GNU Autoconf to control the configuration process
+(@pxref{Quick Installation}).
+
+@item
+Amiga support.
+This has since been removed.
+
+@end itemize
+
+Version 3.1 of @command{gawk} introduced the following features:
+
+@itemize @value{BULLET}
+@item
+New variables
+(@pxref{Built-in Variables}):
+
+@itemize @value{MINUS}
+@item
+@code{BINMODE}, for non-POSIX systems,
+which allows binary I/O for input and/or output files
+(@pxref{PC Using}).
+
+@item
+@code{LINT}, which dynamically controls lint warnings.
+
+@item
+@code{PROCINFO}, an array for providing process-related information.
+
+@item
+@code{TEXTDOMAIN}, for setting an application's internationalization text domain
+(@pxref{Internationalization}).
+@end itemize
+
+@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
+A number of new built-in functions:
+
+@itemize @value{MINUS}
+@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()} function and the ability to add
+new built-in functions dynamically
+(@pxref{Dynamic Extensions}).
+
+@item
+The @code{mktime()} function for creating timestamps
+(@pxref{Time Functions}).
+
+@item
+The @code{and()}, @code{or()}, @code{xor()}, @code{compl()},
+@code{lshift()}, @code{rshift()}, and @code{strtonum()} functions
+(@pxref{Bitwise Functions}).
+@end itemize
+
+@item
+@cindex @code{next file} statement
+The support for @samp{next file} as two words was removed completely
+(@pxref{Nextfile Statement}).
+
+@item
+Additional command-line options
+(@pxref{Options}):
+
+@itemize @value{MINUS}
+@item
+The @option{--dump-variables} option to print a list of all global variables.
+
+@item
+The @option{--exec} option, for use in CGI scripts.
+
+@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{--use-lc-numeric} option to force @command{gawk}
+to use the locale's decimal point for parsing input data
+(@pxref{Conversion}).
+@end itemize
+
+@item
+The use of GNU Automake to help in standardizing the configuration process
+(@pxref{Quick Installation}).
+
+@item
+The use of GNU @command{gettext} for @command{gawk}'s own message output
+(@pxref{Gawk I18N}).
+
+@item
+BeOS support. This was later removed.
+
+@item
+Tandem support. This was later removed.
+
+@item
+The Atari port became officially unsupported and was
+later removed entirely.
+
+@item
+The source code changed to use ISO C standard-style function definitions.
+
+@item
+POSIX compliance for @code{sub()} and @code{gsub()}
+(@pxref{Gory Details}).
+
+@item
+The @code{length()} function was extended to accept an array argument
+and return the number of elements in the array
+(@pxref{String Functions}).
+
+@item
+The @code{strftime()} function acquired a third argument to
+enable printing times as UTC
+(@pxref{Time Functions}).
+@end itemize
+
+Version 4.0 of @command{gawk} introduced the following features:
+
+@itemize @value{BULLET}
+
+@item
+Variable additions:
+
+@itemize @value{MINUS}
+@item
+@code{FPAT}, which allows you to specify a regexp that matches
+the fields, instead of matching the field separator
+(@pxref{Splitting By Content}).
+
+@item
+If @code{PROCINFO["sorted_in"]} exists, @samp{for(iggy in foo)} loops sort the
+indices before looping over them. The value of this element
+provides control over how the indices are sorted before the loop
+traversal starts
+(@pxref{Controlling Scanning}).
+
+@item
+@code{PROCINFO["strftime"]}, which holds
+the default format for @code{strftime()}
+(@pxref{Time Functions}).
+@end itemize
+
+@item
+The special files @file{/dev/pid}, @file{/dev/ppid}, @file{/dev/pgrpid}
+and @file{/dev/user} were removed.
+
+@item
+Support for IPv6 was added via the @file{/inet6} special file.
+@file{/inet4} forces IPv4 and @file{/inet} chooses the system
+default, which is probably IPv4
+(@pxref{TCP/IP Networking}).
+
+@item
+The use of @samp{\s} and @samp{\S} escape sequences in regular expressions
+(@pxref{GNU Regexp Operators}).
+
+@item
+Interval expressions became part of default regular expressions
+(@pxref{Regexp Operators}).
+
+@item
+POSIX character classes work even with @option{--traditional}
+(@pxref{Regexp Operators}).
+
+@item
+@code{break} and @code{continue} became invalid outside a loop,
+even with @option{--traditional}
+(@pxref{Break Statement}, and also see
+@ref{Continue Statement}).
+
+@item
+@code{fflush()}, @code{nextfile}, and @samp{delete @var{array}}
+are allowed if @option{--posix} or @option{--traditional}, since they
+are all now part of POSIX.
+
+@item
+An optional third argument to
+@code{asort()} and @code{asorti()}, specifying how to sort
+(@pxref{String Functions}).
+
+@item
+The behavior of @code{fflush()} changed to match BWK @command{awk}
+and for POSIX; now both @samp{fflush()} and @samp{fflush("")}
+flush all open output redirections
+(@pxref{I/O Functions}).
+
+@item
+The @code{isarray()}
+function which distinguishes if an item is an array
+or not, to make it possible to traverse arrays of arrays
+(@pxref{Type Functions}).
+
+@item
+The @code{patsplit()}
+function which gives the same capability as @code{FPAT}, for splitting
+(@pxref{String Functions}).
+
+@item
+An optional fourth argument to the @code{split()} function,
+which is an array to hold the values of the separators
+(@pxref{String Functions}).
+
+@item
+Arrays of arrays
+(@pxref{Arrays of Arrays}).
+
+@item
+The @code{BEGINFILE} and @code{ENDFILE} special patterns
+(@pxref{BEGINFILE/ENDFILE}).
+
+@item
+Indirect function calls
+(@pxref{Indirect Calls}).
+
+@item
+@code{switch} / @code{case} are enabled by default
+(@pxref{Switch Statement}).
+
+@item
+Command-line option changes
+(@pxref{Options}):
+
+@itemize @value{MINUS}
+@item
+The @option{-b} and @option{--characters-as-bytes} options
+which prevent @command{gawk} from treating input as a multibyte string.
+
+@item
+The redundant @option{--compat}, @option{--copyleft}, and @option{--usage}
+long options were removed.
+
+@item
+The @option{--gen-po} option was finally renamed to the correct @option{--gen-pot}.
+
+@item
+The @option{--sandbox} option which disables certain features.
+
+@item
+All long options acquired corresponding short options, for use in @samp{#!} scripts.
+@end itemize
+
+@item
+Directories named on the command line now produce a warning, not a fatal
+error, unless @option{--posix} or @option{--traditional} are used
+(@pxref{Command-line directories}).
+
+@item
+The @command{gawk} internals were rewritten, bringing the @command{dgawk}
+debugger and possibly improved performance
+(@pxref{Debugger}).
+
+@item
+Per the GNU Coding Standards, dynamic extensions must now define
+a global symbol indicating that they are GPL-compatible
+(@pxref{Plugin License}).
+
+@item
+In POSIX mode, string comparisons use @code{strcoll()} / @code{wcscoll()}
+(@pxref{POSIX String Comparison}).
+
+@item
+The option for raw sockets was removed, since it was never implemented
+(@pxref{TCP/IP Networking}).
+
+@item
+Ranges of the form @samp{[d-h]} are treated as if they were in the
+C locale, no matter what kind of regexp is being used, and even if
+@option{--posix}
+(@pxref{Ranges and Locales}).
+
+@item
+Support was removed for the following systems:
+
+@itemize @value{MINUS}
+@item
+Atari
+
+@item
+Amiga
+
+@item
+BeOS
+
+@item
+Cray
+
+@item
+MIPS RiscOS
+
+@item
+MS-DOS with Microsoft Compiler
+
+@item
+MS-Windows with Microsoft Compiler
+
+@item
+NeXT
+
+@item
+SunOS 3.x, Sun 386 (Road Runner)
+
+@item
+Tandem (non-POSIX)
+
+@item
+Prestandard VAX C compiler for VAX/VMS
+@end itemize
+@end itemize
+
+Version 4.1 of @command{gawk} introduced the following features:
+
+@itemize @value{BULLET}
+
+@item
+Three new arrays:
+@code{SYMTAB}, @code{FUNCTAB}, and @code{PROCINFO["identifiers"]}
+(@pxref{Auto-set}).
+
+@item
+The three executables @command{gawk}, @command{pgawk}, and @command{dgawk}, were merged into
+one, named just @command{gawk}. As a result the command-line options changed.
+
+@item
+Command-line option changes
+(@pxref{Options}):
+
+@itemize @value{MINUS}
+@item
+The @option{-D} option invokes the debugger.
+
+@item
+The @option{-i} and @option{--include} options
+load @command{awk} library files.
+
+@item
+The @option{-l} and @option{--load} options load compiled dynamic extensions.
+
+@item
+The @option{-M} and @option{--bignum} options enable MPFR.
+
+@item
+The @option{-o} option only does pretty-printing.
+
+@item
+The @option{-p} option is used for profiling.
+
+@item
+The @option{-R} option was removed.
+@end itemize
+
+@item
+Support for high precision arithmetic with MPFR.
+(@pxref{Arbitrary Precision Arithmetic}).
+
+@item
+The @code{and()}, @code{or()} and @code{xor()} functions
+changed to allow any number of arguments,
+with a minimum of two
+(@pxref{Bitwise Functions}).
+
+@item
+The dynamic extension interface was completely redone
+(@pxref{Dynamic Extensions}).
+
+@end itemize
+
+@c XXX ADD MORE STUFF HERE
+@end ifclear
+
+@node Common Extensions
+@appendixsec Common Extensions Summary
+
+@cindex extensions, Brian Kernighan's @command{awk}
+@cindex extensions, @command{mawk}
+The following table summarizes the common extensions supported
+by @command{gawk}, Brian Kernighan's @command{awk}, and @command{mawk},
+the three most widely used freely available versions of @command{awk}
+(@pxref{Other Versions}).
+
+@multitable {@file{/dev/stderr} special file} {BWK Awk} {Mawk} {GNU Awk} {Now standard}
+@headitem Feature @tab BWK Awk @tab Mawk @tab GNU Awk @tab Now standard
+@item @samp{\x} Escape sequence @tab X @tab X @tab X @tab
+@item @code{FS} as null string @tab X @tab X @tab X @tab
+@item @file{/dev/stdin} special file @tab X @tab X @tab X @tab
+@item @file{/dev/stdout} special file @tab X @tab X @tab X @tab
+@item @file{/dev/stderr} special file @tab X @tab X @tab X @tab
+@item @code{delete} without subscript @tab X @tab X @tab X @tab X
+@item @code{fflush()} function @tab X @tab X @tab X @tab X
+@item @code{length()} of an array @tab X @tab X @tab X @tab
+@item @code{nextfile} statement @tab X @tab X @tab X @tab X
+@item @code{**} and @code{**=} operators @tab X @tab @tab X @tab
+@item @code{func} keyword @tab X @tab @tab X @tab
+@item @code{BINMODE} variable @tab @tab X @tab X @tab
+@item @code{RS} as regexp @tab @tab X @tab X @tab
+@item Time-related functions @tab @tab X @tab X @tab
+@end multitable
+
+@node Ranges and Locales
+@appendixsec Regexp Ranges and Locales: A Long Sad Story
+
+This @value{SECTION} describes the confusing history of ranges within
+regular expressions and their interactions with locales, and how this
+affected different versions of @command{gawk}.
+
+The original Unix tools that worked with regular expressions defined
+character ranges (such as @samp{[a-z]}) to match any character between
+the first character in the range and the last character in the range,
+inclusive. Ordering was based on the numeric value of each character
+in the machine's native character set. Thus, on ASCII-based systems,
+@samp{[a-z]} matched all the lowercase letters, and only the lowercase
+letters, as the numeric values for the letters from @samp{a} through
+@samp{z} were contiguous. (On an EBCDIC system, the range @samp{[a-z]}
+includes additional, non-alphabetic characters as well.)
+
+Almost all introductory Unix literature explained range expressions
+as working in this fashion, and in particular, would teach that the
+``correct'' way to match lowercase letters was with @samp{[a-z]}, and
+that @samp{[A-Z]} was the ``correct'' way to match uppercase letters.
+And indeed, this was true.@footnote{And Life was good.}
+
+The 1992 POSIX standard introduced the idea of locales (@pxref{Locales}).
+Because many locales include other letters besides the plain 26
+letters of the English alphabet, the POSIX standard added
+character classes (@pxref{Bracket Expressions}) as a way to match
+different kinds of characters besides the traditional ones in the ASCII
+character set.
+
+However, the standard @emph{changed} the interpretation of range expressions.
+In the @code{"C"} and @code{"POSIX"} locales, a range expression like
+@samp{[a-dx-z]} is still equivalent to @samp{[abcdxyz]}, as in ASCII.
+But outside those locales, the ordering was defined to be based on
+@dfn{collation order}.
+
+What does that mean?
+In many locales, @samp{A} and @samp{a} are both less than @samp{B}.
+In other words, these locales sort characters in dictionary order,
+and @samp{[a-dx-z]} is typically not equivalent to @samp{[abcdxyz]};
+instead it might be equivalent to @samp{[ABCXYabcdxyz]}, for example.
+
+This point needs to be emphasized: much literature teaches that you should
+use @samp{[a-z]} to match a lowercase character. But on systems with
+non-ASCII locales, this also matches all of the uppercase characters
+except @samp{A} or @samp{Z}! This was a continuous cause of confusion, even well
+into the twenty-first century.
+
+To demonstrate these issues, 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
+$ @kbd{echo something1234abc | gawk-3.1.8 '@{ sub("[A-Z]*$", ""); print @}'}
+@print{} something1234a
+@end example
+
+@noindent
+This output is unexpected, as the @samp{bc} 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).
+
+@cindex Unicode
+Similar considerations apply to other ranges. For example, @samp{["-/]}
+is perfectly valid in ASCII, but is not valid in many Unicode locales,
+such as @code{en_US.UTF-8}.
+
+Early versions of @command{gawk} used regexp matching code that was not
+locale aware, so ranges had their traditional interpretation.
+
+When @command{gawk} switched to using locale-aware regexp matchers,
+the problems began; especially as both GNU/Linux and commercial Unix
+vendors started implementing non-ASCII locales, @emph{and making them
+the default}. Perhaps the most frequently asked question became something
+like ``why does @samp{[A-Z]} match lowercase letters?!?''
+
+@cindex Berry, Karl
+This situation existed for close to 10 years, if not more, and
+the @command{gawk} maintainer grew weary of trying to explain that
+@command{gawk} was being nicely standards compliant, and that the issue
+was in the user's locale. During the development of @value{PVERSION} 4.0,
+he modified @command{gawk} to always treat ranges in the original,
+pre-POSIX fashion, unless @option{--posix} was used (@pxref{Options}).@footnote{And
+thus was born the Campaign for Rational Range Interpretation (or
+RRI). A number of GNU tools have either implemented this change,
+or will soon. Thanks to Karl Berry for coining the phrase ``Rational
+Range Interpretation.''}
+
+Fortunately, shortly before the final release of @command{gawk} 4.0,
+the maintainer learned that the 2008 standard had changed the
+definition of ranges, such that outside the @code{"C"} and @code{"POSIX"}
+locales, the meaning of range expressions was @emph{undefined}.@footnote{See
+@uref{http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03_05, the standard}
+and
+@uref{http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap09.html#tag_21_09_03_05, its rationale}.}
+
+By using this lovely technical term, the standard gives license
+to implementors to implement ranges in whatever way they choose.
+The @command{gawk} maintainer chose to apply the pre-POSIX meaning in all
+cases: the default regexp matching; with @option{--traditional} and with
+@option{--posix}; in all cases, @command{gawk} remains POSIX compliant.
+
+@node Contributors
+@appendixsec Major Contributors to @command{gawk}
+@cindex @command{gawk}, list of contributors to
+@quotation
+@i{Always give credit where credit is due.}
+@author Anonymous
+@end quotation
+
+This @value{SECTION} names the major contributors to @command{gawk}
+and/or this @value{DOCUMENT}, in approximate chronological order:
+
+@itemize @value{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 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 Rankin, Pat
+Pat Rankin
+provided the VMS port and its documentation.
+
+@item
+@cindex Peterson, Hal
+Hal Peterson
+provided help in porting @command{gawk} to Cray systems.
+(This is no longer supported.)
+
+@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.
+(This port is no longer supported.)
+He continues to provide portability checking,
+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.
+(With Fred's sad passing, this is no longer supported.)
+
+@item
+@cindex Deifik, Scott
+Scott Deifik
+currently maintains the MS-DOS port using DJGPP.
+
+@item
+@cindex Zaretskii, Eli
+Eli Zaretskii
+currently maintains the MS-Windows port using MinGW.
+
+
+@item
+@cindex Grigera, Juan
+Juan Grigera
+provided a port to Windows32 systems.
+(This is no longer supported.)
+
+@item
+@cindex Hankerson, Darrel
+For many years,
+Dr.@: Darrel Hankerson
+acted as coordinator for the various ports to different PC platforms
+and created binary distributions for various PC operating systems.
+He was 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 functions.
+(This was obsoleted at @command{gawk} 4.1.)
+
+@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 initial port to Tandem systems and its documentation.
+(However, this is no longer supported.)
+He was also instrumental in the initial work to integrate the
+byte-code internals into the @command{gawk} code base.
+
+@item
+@cindex Woehlke, Matthew
+Matthew Woehlke
+provided improvements for Tandem's POSIX-compliant systems.
+
+@item
+@cindex Brown, Martin
+Martin Brown
+provided the port to BeOS and its documentation.
+(This is no longer supported.)
+
+@item
+@cindex Peters, Arno
+Arno Peters
+did the initial work to convert @command{gawk} to use
+GNU Automake and GNU @command{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 optional third argument to the
+@code{match()} function.
+
+@item
+@cindex Buening, Andreas
+Andreas Buening
+updated the @command{gawk} port for OS/2.
+
+@item
+@cindex Hasegawa, Isamu
+Isamu Hasegawa,
+of IBM in Japan, contributed support for multibyte characters.
+
+@item
+@cindex Benzinger, Michael
+Michael Benzinger contributed the initial code for @code{switch} statements.
+
+@item
+@cindex McPhee, Patrick
+Patrick T.J.@: McPhee contributed the code for dynamic loading in Windows32
+environments.
+(This is no longer supported.)
+
+@item
+@cindex Wallin, Anders
+Anders Wallin helped keep the VMS port going for several years.
+
+@item
+@cindex Gordon, Assaf
+Assaf Gordon contributed the code to implement the
+@option{--sandbox} option.
+
+@item
+@cindex Haque, John
+John Haque made the following contributions:
+
+@itemize @value{MINUS}
+@item
+The modifications to convert @command{gawk}
+into a byte-code interpreter, including the debugger.
+
+@item
+The addition of true arrays of arrays.
+
+@item
+The additional modifications for support of arbitrary-precision arithmetic.
+
+@item
+The initial text of
+@ref{Arbitrary Precision Arithmetic}.
+
+@item
+The work to merge the three versions of @command{gawk}
+into one, for the 4.1 release.
+
+@item
+Improved array internals for arrays indexed by integers.
+
+@item
+The improved array sorting features were driven by John together
+with Pat Rankin.
+@end itemize
+
+@cindex Papadopoulos, Panos
+@item
+Panos Papadopoulos contributed the original text for @ref{Include Files}.
+
+@item
+@cindex Yawitz, Efraim
+Efraim Yawitz contributed the original text for @ref{Debugger}.
+
+@item
+@cindex Schorr, Andrew
+The development of the extension API first released with
+@command{gawk} 4.1 was driven primarily by
+Arnold Robbins and Andrew Schorr, with notable contributions from
+the rest of the development team.
+
+@cindex Malmberg, John E.
+@item
+John Malmberg contributed significant improvements to the
+OpenVMS port and the related documentation.
+
+@item
+@cindex Colombo, Antonio
+Antonio Giovanni Colombo rewrote a number of examples in the early
+chapters that were severely dated, for which I am incredibly grateful.
+
+@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 History summary
+@appendixsec Summary
+
+@itemize @value{BULLET}
+@item
+The @command{awk} language has evolved over time. The first release
+was with V7 Unix circa 1978. In 1987, for System V Release 3.1,
+major additions, including user-defined functions, were made to the language.
+Additional changes were made for System V Release 4, in 1989.
+Since then, further minor changes happen under the auspices of the
+POSIX standard.
+
+@item
+Brian Kernighan's @command{awk} provides a small number of extensions
+that are implemented in common with other versions of @command{awk}.
+
+@item
+@command{gawk} provides a large number of extensions over POSIX @command{awk}.
+They can be disabled with either the @option{--traditional} or @option{--posix}
+options.
+
+@item
+The interaction of POSIX locales and regexp matching in @command{gawk} has been confusing over
+the years. Today, @command{gawk} implements Rational Range Interpretation, where
+ranges of the form @samp{[a-z]} match @emph{only} the characters numerically between
+@samp{a} through @samp{z} in the machine's native character set. Usually this is ASCII
+but it can be EBCDIC on IBM S/390 systems.
+
+@item
+Many people have contributed to @command{gawk} development over the years.
+We hope that the list provided in this @value{CHAPTER} is complete and gives
+the appropriate credit where credit is due.
+
+@end itemize
+
+@node Installation
+@appendix Installing @command{gawk}
+
+@c last two commas are part of see also
+@cindex operating systems, See Also GNU/Linux@comma{} PC operating systems@comma{} Unix
+@cindex @command{gawk}, installing
+@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.
+@DBXREF{Bugs}
+for the email addresses of the people who maintain
+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.
+* Bugs:: Reporting Problems and Bugs.
+* Other Versions:: Other freely available @command{awk}
+ implementations.
+* Installation summary:: Summary of installation.
+@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 two ways to get GNU software:
+
+@itemize @value{BULLET}
+@item
+Copy it from someone else who already has it.
+
+@cindex FSF (Free Software Foundation)
+@cindex Free Software Foundation (FSF)
+@item
+Retrieve @command{gawk}
+from the Internet host
+@code{ftp.gnu.org}, in the directory @file{/gnu/gawk}.
+Both anonymous @command{ftp} and @code{http} access are supported.
+If you have the @command{wget} program, you can use a command like
+the following:
+
+@example
+wget http://ftp.gnu.org/gnu/gawk/gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz
+@end example
+@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 website}.
+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 several @code{tar} files compressed with
+different compression programs: @command{gzip}, @command{bzip2},
+and @command{xz}. For simplicity, the rest of these instructions assume
+you are using the one compressed with the GNU Zip program, @code{gzip}.
+
+Once you have the distribution (e.g.,
+@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
+gzip -d -c gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz | tar -xvpf -
+@end example
+
+On a system with GNU @command{tar}, you can let @command{tar}
+do the decompression for you:
+
+@example
+tar -xvpzf gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz
+@end example
+
+@noindent
+Extracting the archive
+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 70 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 or GNU/Linux 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
+@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 ABOUT-NLS
+Information about GNU @command{gettext} and translations.
+
+@item AUTHORS
+A file with some information about the authorship of @command{gawk}.
+It exists only to satisfy the pedants at the Free Software Foundation.
+
+@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 ChangeLog.0
+An older list of source code changes.
+
+@item NEWS
+A list of changes to @command{gawk} since the last release or patch.
+
+@item NEWS.0
+An older list of changes to @command{gawk}.
+
+@item COPYING
+The GNU General Public License.
+
+@item POSIX.STD
+A description of behaviors in the POSIX standard for @command{awk} which
+are left undefined, or where @command{gawk} may not comply fully, as well
+as a list of things that the POSIX standard should describe but does not.
+
+@cindex artificial intelligence@comma{} @command{gawk} and
+@item doc/awkforai.txt
+Pointers to the original draft of
+a short article describing why @command{gawk} is a good language for
+artificial intelligence (AI) programming.
+
+@item doc/bc_notes
+A brief description of @command{gawk}'s ``byte code'' internals.
+
+@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/gawktexi.in
+@itemx doc/sidebar.awk
+The Texinfo source file for this @value{DOCUMENT}.
+It should be processed by @file{doc/sidebar.awk}
+before processing with @command{texi2dvi} or @command{texi2pdf}
+to produce a printed document, and
+with @command{makeinfo} to produce an Info or HTML file.
+The @file{Makefile} takes care of this processing and produces
+printable output via @command{texi2dvi} or @command{texi2pdf}.
+
+@item doc/gawk.texi
+The file produced after processing @file{gawktexi.in}
+with @file{sidebar.awk}.
+
+@item doc/gawk.info
+The generated Info file for this @value{DOCUMENT}.
+
+@item doc/gawkinet.texi
+The Texinfo source file for
+@ifinfo
+@inforef{Top, , General Introduction, gawkinet, TCP/IP Internetworking with @command{gawk}}.
+@end ifinfo
+@ifnotinfo
+@cite{TCP/IP Internetworking with @command{gawk}}.
+@end ifnotinfo
+It should be processed with @TeX{}
+(via @command{texi2dvi} or @command{texi2pdf})
+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}.
+(Since @command{gawk} can do its own @code{@@include} processing,
+neither @command{igawk} nor @file{igawk.1} are installed.)
+
+@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 Automake software for generating
+the @file{Makefile.in} files used by Autoconf and
+@command{configure}.
+
+@item Makefile.in
+@itemx aclocal.m4
+@itemx bisonfix.awk
+@itemx config.guess
+@itemx configh.in
+@itemx configure.ac
+@itemx configure
+@itemx custom.h
+@itemx depcomp
+@itemx install-sh
+@itemx missing_d/*
+@itemx mkinstalldirs
+@itemx m4/*
+These files and subdirectories are used when configuring and compiling
+@command{gawk} for various Unix systems. Most of them are explained
+in @ref{Unix Installation}. The rest are there to support the main
+infrastructure.
+
+@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},
+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 extension/*
+The source code, manual pages, and infrastructure files for
+the sample extensions included with @command{gawk}.
+@xref{Dynamic Extensions}, for more information.
+
+@item extras/*
+Additional non-essential files. Currently, this directory contains some shell
+startup files to be installed in @file{/etc/profile.d} to aid in manipulating
+the @env{AWKPATH} and @env{AWKLIBPATH} environment variables.
+@xref{Shell Startup Files}, for more information.
+
+@item posix/*
+Files needed for building @command{gawk} on POSIX-compliant systems.
+
+@item pc/*
+Files needed for building @command{gawk} under MS-Windows
+@ifclear FOR_PRINT
+and OS/2
+@end ifclear
+(@DBPXREF{PC Installation} for details).
+
+@item vms/*
+Files needed for building @command{gawk} under Vax/VMS and OpenVMS
+(@DBPXREF{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
+
+@node Unix Installation
+@appendixsec Compiling and Installing @command{gawk} on Unix-Like Systems
+
+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.
+* Shell Startup Files:: Shell convenience functions.
+* 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-Like Systems
+
+The normal installation steps should work on all modern commercial
+Unix-derived systems, GNU/Linux, BSD-based systems, and the Cygwin
+environment for MS-Windows.
+
+After you have extracted the @command{gawk} distribution, @command{cd}
+to @file{gawk-@value{VERSION}.@value{PATCHLEVEL}}. As with most GNU
+software, you configure @command{gawk} for your system by running the
+@command{configure} program. This program is a Bourne shell script that
+is generated automatically using GNU Autoconf.
+@ifnotinfo
+(The Autoconf software is
+described fully in
+@cite{Autoconf---Generating Automatic Configuration Scripts},
+which can be found online at
+@uref{http://www.gnu.org/software/autoconf/manual/index.html,
+the Free Software Foundation's website}.)
+@end ifnotinfo
+@ifinfo
+(The Autoconf software is described fully starting with
+@inforef{Top, , Autoconf, autoconf,Autoconf---Generating Automatic Configuration Scripts}.)
+@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,
+send in a bug report (@pxref{Bugs}).
+
+Of course, once you've built @command{gawk}, it is likely that you will
+wish to install it. To do so, you need to run the command @samp{make
+install}, as a user with the appropriate permissions. How to do this
+varies by system, but on many systems you can use the @command{sudo}
+command to do so. The command then becomes @samp{sudo make install}. It
+is likely that you will be asked for your password, and you will have
+to have been set up previously as a user who is allowed to run the
+@command{sudo} command.
+
+@node Shell Startup Files
+@appendixsubsec Shell Startup Files
+
+The distribution contains shell startup files @file{gawk.sh} and
+@file{gawk.csh} containing functions to aid in manipulating
+the @env{AWKPATH} and @env{AWKLIBPATH} environment variables.
+On a Fedora system, these files should be installed in @file{/etc/profile.d};
+on other platforms, the appropriate location may be different.
+
+@table @command
+
+@cindex @command{gawkpath_default} shell function
+@item gawkpath_default
+Reset the @env{AWKPATH} environment variable to its default value.
+
+@cindex @command{gawkpath_prepend} shell function
+@item gawkpath_prepend
+Add the argument to the front of the @env{AWKPATH} environment variable.
+
+@cindex @command{gawkpath_append} shell function
+@item gawkpath_append
+Add the argument to the end of the @env{AWKPATH} environment variable.
+
+@cindex @command{gawklibpath_default} shell function
+@item gawklibpath_default
+Reset the @env{AWKLIBPATH} environment variable to its default value.
+
+@cindex @command{gawklibpath_prepend} shell function
+@item gawklibpath_prepend
+Add the argument to the front of the @env{AWKLIBPATH} environment variable.
+
+@cindex @command{gawklibpath_append} shell function
+@item gawklibpath_append
+Add the argument to the end of the @env{AWKLIBPATH} environment variable.
+
+@end table
+
+
+@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 @option{--disable-extensions} configuration option
+@cindex configuration option, @code{--disable-extensions}
+@item --disable-extensions
+Disable configuring and building the sample extensions in the
+@file{extension} directory. This is useful for cross-compiling.
+The default action is to dynamically check if the extensions
+can be configured and compiled.
+
+@cindex @option{--disable-lint} configuration option
+@cindex configuration option, @code{--disable-lint}
+@item --disable-lint
+Disable 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 23K bytes off the size of the @command{gawk}
+executable on GNU/Linux x86_64 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 @option{--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.
+
+@cindex @option{--with-whiny-user-strftime} configuration option
+@cindex configuration option, @code{--with-whiny-user-strftime}
+@item --with-whiny-user-strftime
+Force use of the included version of the C @code{strftime()}
+function for deficient systems.
+@end table
+
+Use the command @samp{./configure --help} to see the full list of
+options supplied by @command{configure}.
+
+@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 Unix-like operating systems.
+
+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.
+The @command{gawk} source code requires using an ISO C compiler (the 1990
+standard).
+
+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 operating system. For example, there may not be an
+@code{st_blksize} element in the @code{stat} structure. In this case,
+@samp{HAVE_STRUCT_STAT_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{custom.h} file.
+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. The @file{custom.h} file is automatically included by
+the @file{config.h} file.
+
+It is also possible that the @command{configure} program generated by
+Autoconf will not work on your system in some other fashion.
+If you do have a problem, the @file{configure.ac} file is the input for
+Autoconf. You may be able to change this file and generate a
+new version of @command{configure} that works on your system
+(@DBPXREF{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.ac}
+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
+* PC Installation:: Installing and Compiling @command{gawk} on
+ MS-DOS and OS/2.
+* VMS Installation:: Installing @command{gawk} on VMS.
+@end menu
+
+@c Rewritten by Scott Deifik <scottd.mail@sbcglobal.net>
+@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 Intel architecture machines
+@ifclear FOR_PRINT
+running MS-DOS, any version of MS-Windows, or OS/2.
+@end ifclear
+@ifset FOR_PRINT
+running MS-DOS and any version of MS-Windows.
+@end ifset
+In this @value{SECTION}, the term ``Windows32''
+refers to any of Microsoft Windows-95/98/ME/NT/2000/XP/Vista/7/8.
+
+The limitations of MS-DOS (and MS-DOS shells under the other operating
+systems) 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, 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 Testing:: Testing @command{gawk} on PC systems.
+* PC Using:: Running @command{gawk} on MS-DOS, Windows32
+ and OS/2.
+* Cygwin:: Building and running @command{gawk} for
+ Cygwin.
+* MSYS:: Using @command{gawk} In The MSYS Environment.
+@end menu
+
+@ifclear FOR_PRINT
+@node PC Binary Installation
+@appendixsubsubsec Installing a Prepared Distribution for PC Systems
+
+If you have received a binary distribution prepared by the MS-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}.
+Note that the files can be installed anywhere provided @env{AWKPATH} is
+set properly.
+
+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
+
+The binary distribution may contain a separate file containing additional
+or more detailed installation instructions.
+@end ifclear
+
+@node PC Compiling
+@appendixsubsubsec Compiling @command{gawk} for PC Operating Systems
+
+@ifclear FOR_PRINT
+@command{gawk} can be compiled for MS-DOS, Windows32, and OS/2 using the GNU
+development tools from DJ Delorie (DJGPP: MS-DOS only), MinGW (Windows32) or Eberhard
+Mattes (EMX: MS-DOS, Windows32 and OS/2).
+@end ifclear
+@ifset FOR_PRINT
+@command{gawk} can be compiled for MS-DOS and Windows32 using the GNU
+development tools from DJ Delorie (DJGPP: MS-DOS only) or MinGW (Windows32).
+@end ifset
+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.
+
+@cindex compiling @command{gawk} for MS-DOS and MS-Windows
+To build @command{gawk} for MS-DOS and Windows32, copy the files in
+the @file{pc} directory (@emph{except} for @file{ChangeLog}) to the
+directory with the rest of the @command{gawk} sources, then invoke
+@command{make} with the appropriate target name as an argument to
+build @command{gawk}. The @file{Makefile} copied from the @file{pc}
+directory contains a configuration section with comments and may need
+to be edited in order to work with your @command{make} utility.
+
+The @file{Makefile} supports a number of targets for building various
+MS-DOS and Windows32 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 needed for the build may be found at
+@uref{ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/}.) To build a
+native MS-Windows binary of @command{gawk} using the MinGW tools,
+type @samp{make mingw32}.
+
+@ifclear FOR_PRINT
+@cindex compiling @command{gawk} with EMX for OS/2
+The 32 bit EMX version of @command{gawk} works ``out of the box'' under OS/2.
+However, it is highly recommended to use GCC 2.95.3 for the compilation.
+In principle, it is possible to compile @command{gawk} the following way:
+
+@example
+$ @kbd{./configure}
+$ @kbd{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
+$ @kbd{CFLAGS="-O2 -Zomf -Zmt"}
+$ @kbd{export CFLAGS}
+$ @kbd{LDFLAGS="-s -Zcrtdll -Zlinker /exepack:2 -Zlinker /pm:vio -Zstack 0x6000"}
+$ @kbd{export LDFLAGS}
+$ @kbd{RANLIB="echo"}
+$ @kbd{export RANLIB}
+$ @kbd{./configure --prefix=c:/usr}
+$ @kbd{make AR=emxomfar}
+@end example
+
+These are just suggestions for use with GCC 2.x. You may use any other set of
+(self-consistent) environment variables and compiler flags.
+
+@ignore
+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}.
+@end ignore
+
+@ignore
+The internal @command{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
+$ @kbd{LIBS="-lgcc"}
+$ @kbd{export LIBS}
+@end example
+
+You can also get an @code{a.out} executable if you prefer:
+
+@example
+$ @kbd{CFLAGS="-O2 -Zmt"}
+$ @kbd{export CFLAGS}
+$ @kbd{LDFLAGS="-s -Zstack 0x6000"}
+$ @kbd{LIBS="-lgcc"}
+$ @kbd{unset RANLIB}
+@c $ ./configure --prefix=c:/usr --without-included-gettext
+$ @kbd{./configure --prefix=c:/usr}
+$ @kbd{make}
+@end example
+
+@quotation NOTE
+Compilation of @code{a.out} executables also works with GCC 3.2.
+Versions later than GCC 3.2 have not been tested successfully.
+@end quotation
+
+@samp{make install} works as expected with the EMX build.
+
+@quotation NOTE
+Ancient 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{ftp://hobbes.nmsu.edu/pub/os2/}.@footnote{As of November 2014,
+this site is still there, but the author could not find a package
+for GNU Make.}
+@end quotation
+@end ifclear
+
+@node PC Testing
+@appendixsubsubsec Testing @command{gawk} on PC Operating Systems
+
+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 MS-DOS-style end-of-line markers.
+Alternatively, run @command{make check CMP="diff -a"} to use GNU @command{diff}
+in text mode instead of @command{cmp} to compare the resulting files.
+
+@ifclear FOR_PRINT
+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}.
+
+On OS/2 the @code{pid} test fails because @code{spawnl()} is used instead of
+@code{fork()}/@code{execl()} to start child processes.
+Also the @code{mbfw1} and @code{mbprintf1} tests fail because the needed
+multibyte functionality is not available.
+@end ifclear
+
+@node PC Using
+@appendixsubsubsec Using @command{gawk} on PC Operating Systems
+@cindex operating systems, PC, @command{gawk} on
+@cindex PC operating systems, @command{gawk} on
+
+Under MS-DOS and MS-Windows, the Cygwin and MinGW environments support
+both the @samp{|&} operator and TCP/IP networking
+(@pxref{TCP/IP Networking}).
+@ifclear FOR_PRINT
+EMX (OS/2 only) supports at least the @samp{|&} operator.
+@end ifclear
+
+@cindex search paths
+@cindex search paths, for source files
+@cindex @command{gawk}, MS-DOS version of
+@cindex @command{gawk}, MS-Windows version of
+@cindex @code{;} (semicolon), @env{AWKPATH} variable and
+@cindex semicolon (@code{;}), @env{AWKPATH} variable and
+@cindex @env{AWKPATH} environment variable
+The MS-DOS and MS-Windows 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 is @samp{@w{.;c:/lib/awk;c:/gnu/lib/awk}}.
+
+@ifclear FOR_PRINT
+@cindex @command{gawk}, OS/2 version of
+@cindex @code{UNIXROOT} variable, on OS/2 systems
+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 as 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 @value{FN}s 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
+@samp{@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 MS-Windows or OS/2) may be useful for @command{awk} programming.
+The DJGPP collection of tools includes an MS-DOS port of Bash,
+and several shells are available for OS/2, including @command{ksh}.
+@end ifclear
+@ifset FOR_PRINT
+An @command{sh}-like shell (as opposed to @command{command.com} under MS-DOS
+or @command{cmd.exe} under MS-Windows) may be useful for @command{awk} programming.
+The DJGPP collection of tools includes an MS-DOS port of Bash.
+@end ifset
+
+@cindex common extensions, @code{BINMODE} variable
+@cindex extensions, common@comma{} @code{BINMODE} variable
+@cindex differences in @command{awk} and @command{gawk}, @code{BINMODE} variable
+@cindex @code{BINMODE} variable
+@ifclear FOR_PRINT
+Under MS-Windows, OS/2 and MS-DOS,
+@end ifclear
+@ifset FOR_PRINT
+Under MS-Windows and MS-DOS,
+@end ifset
+@command{gawk} (and many other text programs) silently
+translate end-of-line @samp{\r\n} to @samp{\n} on input and @samp{\n}
+to @samp{\r\n} on output. A special @code{BINMODE} variable @value{COMMONEXT}
+allows control over these translations and is interpreted as follows:
+
+@itemize @value{BULLET}
+@item
+If @code{BINMODE} is @code{"r"} or one,
+then
+binary mode is set on read (i.e., no translations on reads).
+
+@item
+If @code{BINMODE} is @code{"w"} or two,
+then
+binary mode is set on write (i.e., no translations on writes).
+
+@item
+If @code{BINMODE} is @code{"rw"} or @code{"wr"} or three,
+binary mode is set for both read and write.
+
+@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}).
+@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 binary 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 MS-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'' MS-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" -e "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
+@cindex compiling @command{gawk} for Cygwin
+
+@command{gawk} can be built and used ``out of the box'' under MS-Windows
+if you are using the @uref{http://www.cygwin.com, Cygwin environment}.
+This environment provides an excellent simulation of GNU/Linux, using the
+GNU tools, such as Bash, the GNU Compiler Collection (GCC), GNU Make,
+and other GNU programs. 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 && make check
+@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.
+
+@node MSYS
+@appendixsubsubsec Using @command{gawk} In The MSYS Environment
+
+In the MSYS environment under MS-Windows, @command{gawk} automatically
+uses binary mode for reading and writing files. Thus there is no
+need to use the @code{BINMODE} variable.
+
+This can cause problems with other Unix-like components that have
+been ported to MS-Windows that expect @command{gawk} to do automatic
+translation of @code{"\r\n"}, because it won't.
+
+@node VMS Installation
+@appendixsubsec Compiling and Installing @command{gawk} on Vax/VMS and OpenVMS
+
+@c based on material from Pat Rankin <rankin@eql.caltech.edu>
+@c now rankin@pactechdata.com
+@c now r.pat.rankin@gmail.com
+
+@cindex @command{gawk}, VMS version of
+@cindex installation, VMS
+This @value{SUBSECTION} describes how to compile and install @command{gawk} under VMS.
+The older designation ``VMS'' is used throughout to refer to OpenVMS.
+
+@menu
+* VMS Compilation:: How to compile @command{gawk} under VMS.
+* VMS Dynamic Extensions:: Compiling @command{gawk} dynamic extensions on
+ VMS.
+* VMS Installation Details:: How to install @command{gawk} under VMS.
+* VMS Running:: How to run @command{gawk} under VMS.
+* VMS GNV:: The VMS GNV Project.
+* VMS Old Gawk:: An old version comes with some VMS systems.
+@end menu
+
+@node VMS Compilation
+@appendixsubsubsec Compiling @command{gawk} on VMS
+@cindex compiling @command{gawk} for 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} and @code{MMK} utilities.
+From the source directory, use either:
+
+@example
+$ @kbd{@@[.vms]vmsbuild.com}
+@end example
+
+@noindent
+or:
+
+@example
+$ @kbd{MMS/DESCRIPTION=[.vms]descrip.mms gawk}
+@end example
+
+@noindent
+or:
+
+@example
+$ @kbd{MMK/DESCRIPTION=[.vms]descrip.mms gawk}
+@end example
+
+@command{MMK} is an open source, free, near-clone of @command{MMS} and
+can better handle ODS-5 volumes with upper- and lowercase @value{FN}s.
+@command{MMK} is available from @uref{https://github.com/endlesssoftware/mmk}.
+
+With ODS-5 volumes and extended parsing enabled, the case of the target
+parameter may need to be exact.
+
+@command{gawk} has been tested under VAX/VMS 7.3 and Alpha/VMS 7.3-1
+using Compaq C V6.4, and Alpha/VMS 7.3, Alpha/VMS 7.3-2, and IA64/VMS 8.3.
+The most recent builds used HP C V7.3 on Alpha VMS 8.3 and both
+Alpha and IA64 VMS 8.4 used HP C 7.3.@footnote{The IA64 architecture
+is also known as ``Itanium.''}
+
+@DBXREF{VMS GNV} for information on building
+@command{gawk} as a PCSI kit that is compatible with the GNV product.
+
+@node VMS Dynamic Extensions
+@appendixsubsubsec Compiling @command{gawk} Dynamic Extensions on VMS
+
+The extensions that have been ported to VMS can be built using one of
+the following commands:
+
+@example
+$ @kbd{MMS/DESCRIPTION=[.vms]descrip.mms extensions}
+@end example
+
+@noindent
+or:
+
+@example
+$ @kbd{MMK/DESCRIPTION=[.vms]descrip.mms extensions}
+@end example
+
+@command{gawk} uses @code{AWKLIBPATH} as either an environment variable
+or a logical name to find the dynamic extensions.
+
+Dynamic extensions need to be compiled with the same compiler options for
+floating-point, pointer size, and symbol name handling as were used
+to compile @command{gawk} itself.
+Alpha and Itanium should use IEEE floating point. The pointer size is 32 bits,
+and the symbol name handling should be exact case with CRC shortening for
+symbols longer than 32 bits.
+
+For Alpha and Itanium:
+
+@example
+/name=(as_is,short)
+/float=ieee/ieee_mode=denorm_results
+@end example
+
+For VAX:
+
+@example
+/name=(as_is,short)
+@end example
+
+Compile time macros need to be defined before the first VMS-supplied
+header file is included, as follows:
+
+@example
+#if (__CRTL_VER >= 70200000) && !defined (__VAX)
+#define _LARGEFILE 1
+#endif
+
+#ifndef __VAX
+#ifdef __CRTL_VER
+#if __CRTL_VER >= 80200000
+#define _USE_STD_STAT 1
+#endif
+#endif
+#endif
+@end example
+
+If you are writing your own extensions to run on VMS, you must supply these
+definitions yourself. The @file{config.h} file created when building @command{gawk}
+on VMS does this for you; if instead you use that file or a similar one, then you
+must remember to include it before any VMS-supplied header files.
+
+@node VMS Installation Details
+@appendixsubsubsec Installing @command{gawk} on VMS
+
+To use @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
+$ @kbd{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}.
+
+If your @command{gawk} was installed by a PCSI kit into the
+@file{GNV$GNU:} directory tree, the program will be known as
+@file{GNV$GNU:[bin]gnv$gawk.exe} and the help file will be
+@file{GNV$GNU:[vms_help]gawk.hlp}.
+
+The PCSI kit also installs a @file{GNV$GNU:[vms_bin]gawk_verb.cld} file
+which can be used to add @command{gawk} and @command{awk} as DCL commands.
+
+For just the current process you can use:
+
+@example
+$ @kbd{set command gnv$gnu:[vms_bin]gawk_verb.cld}
+@end example
+
+Or the system manager can use @file{GNV$GNU:[vms_bin]gawk_verb.cld} to
+add the @command{gawk} and @command{awk} to the system wide @samp{DCLTABLES}.
+
+The DCL syntax is documented in the @file{gawk.hlp} file.
+
+Optionally, the @file{gawk.hlp} entry can be loaded into a VMS help library:
+
+@example
+$ @kbd{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
+$ @kbd{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 @value{FN} and retries
+the file search. If @samp{AWK_LIBRARY} has no definition, a default value
+of @samp{SYS$LIBRARY:} is used for it.
+
+@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
+$ @kbd{gawk -- "BEGIN @{print ""Hello, World!""@}"}
+$ @kbd{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), the command
+becomes ambiguous. To work around this, the normally optional @option{--}
+flag is required to force Unix-style parsing 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.
+
+@cindex exit status, of VMS
+The @code{exit} value is a Unix-style value and is encoded into a VMS exit
+status value when the program exits.
+
+The VMS severity bits will be set based on the @code{exit} value.
+A failure is indicated by 1 and VMS sets the @code{ERROR} status.
+A fatal error is indicated by 2 and VMS sets the @code{FATAL} status.
+All other values will have the @code{SUCCESS} status. The exit value is
+encoded to comply with VMS coding standards and will have the
+@code{C_FACILITY_NO} of @code{0x350000} with the constant @code{0xA000}
+added to the number shifted over by 3 bits to make room for the severity codes.
+
+To extract the actual @command{gawk} exit code from the VMS status use:
+
+@example
+unix_status = (vms_status .and. &x7f8) / 8
+@end example
+
+@noindent
+A C program that uses @code{exec()} to call @command{gawk} will get the original
+Unix-style exit value.
+
+Older versions of @command{gawk} for VMS treated a Unix exit code 0 as 1, a failure
+as 2, a fatal error as 4, and passed all the other numbers through.
+This violated the VMS exit status coding requirements.
+
+@cindex floating-point, VAX/VMS
+VAX/VMS floating point uses unbiased rounding. @xref{Round Function}.
+
+VMS reports time values in GMT unless one of the @code{SYS$TIMEZONE_RULE}
+or @code{TZ} logical names is set. Older versions of VMS, such as VAX/VMS
+7.3 do not set these logical names.
+
+@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 @env{AWKPATH} can be used to override this default. The format
+of @env{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 GNV
+@appendixsubsubsec The VMS GNV Project
+
+The VMS GNV package provides a build environment similar to POSIX with ports
+of a collection of open source tools. The @command{gawk} found in the GNV
+base kit is an older port. Currently the GNV project is being reorganized
+to supply individual PCSI packages for each component.
+See @w{@uref{https://sourceforge.net/p/gnv/wiki/InstallingGNVPackages/}.}
+
+The normal build procedure for @command{gawk} produces a program that
+is suitable for use with GNV.
+
+The file @file{vms/gawk_build_steps.txt} in the distribution documents
+the procedure for building a VMS PCSI kit that is compatible with GNV.
+
+@ignore
+@c The VMS POSIX product, also known as POSIX for OpenVMS, is long defunct
+@c and building gawk for it has not been tested in many years, but these
+@c old instructions might still work if anyone is still using it.
+
+@node VMS POSIX
+@appendixsubsubsec 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> @kbd{CC=vms/posix-cc.sh configure}
+psx> @kbd{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.
+@end ignore
+
+@node VMS Old Gawk
+@appendixsubsubsec Some VMS Systems Have An Old Version of @command{gawk}
+
+@c Thanks to "gerard labadie" <gerard.labadie@gmail.com>
+
+Some versions of VMS have an old version of @command{gawk}. To access it,
+define a symbol, as follows:
+
+@example
+$ @kbd{gawk :== $sys$common:[syshlp.examples.tcpip.snmp]gawk.exe}
+@end example
+
+This is apparently @value{PVERSION} 2.15.6, which is extremely old. We
+recommend compiling and using the current version.
+
+
+@node Bugs
+@appendixsec Reporting Problems and Bugs
+@cindex archaeologists
+@quotation
+@i{There is nothing more dangerous than a bored archaeologist.}
+@author Douglas Adams, @cite{The Hitchhiker's Guide to the Galaxy}
+@end quotation
+@c the radio show, not the book. :-)
+
+@cindex debugging @command{gawk}, bug reports
+@cindex troubleshooting, @command{gawk}, bug reports
+If you have problems with @command{gawk} or think that you have found a bug,
+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 really found a genuine bug.
+Carefully reread the documentation and see if it 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.
+
+Make sure to include the version number of @command{gawk} you are using.
+You can get this information with the command @samp{gawk --version}.
+
+@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 description, send email to
+@EMAIL{bug-gawk@@gnu.org,bug-gawk at gnu dot org}.
+
+The @command{gawk} maintainers subscribe to this address and
+thus they will receive your bug report.
+Although you can send mail to the maintainers directly,
+the bug reporting address is preferred because the
+email list is archived at the GNU Project.
+@emph{All email must be in English. This is the only language
+understood in common by all the maintainers.}
+
+@cindex @code{comp.lang.awk} newsgroup
+@quotation CAUTION
+Do @emph{not} try to report bugs in @command{gawk} by
+posting to the Usenet/Internet newsgroup @code{comp.lang.awk}.
+The @command{gawk} developers do occasionally read this newsgroup,
+but there is no guarantee that we will see your posting. The steps described
+here are the only officially recognized way for reporting bugs.
+Really.
+@end quotation
+
+@quotation NOTE
+Many distributions of GNU/Linux and the various BSD-based operating systems
+have their own bug reporting systems. If you report a bug using your distribution's
+bug reporting system, you should also send a copy to
+@EMAIL{bug-gawk@@gnu.org,bug-gawk at gnu dot org}.
+
+This is for two reasons. First, although some distributions forward
+bug reports ``upstream'' to the GNU mailing list, many don't, so there is a good
+chance that the @command{gawk} maintainers won't even see the bug report! Second,
+mail to the GNU list is archived, and having everything at the GNU project
+keeps things self-contained and not dependant on other organizations.
+@end quotation
+
+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 on the bug list; we will try to help you out if we can.
+
+If you find bugs in one of the non-Unix ports of @command{gawk},
+send an email to the bug list, with a copy 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 various @command{gawk} ports are:
+
+@c put the index entries outside the table, for docbook
+@cindex Buening, Andreas
+@cindex Deifik, Scott
+@cindex Malmberg, John
+@cindex Pitts, Dave
+@cindex Robbins, Arnold
+@cindex Zaretskii, Eli
+@multitable {MS-Windows with MinGW} {123456789012345678901234567890123456789001234567890}
+@item Unix and POSIX systems @tab Arnold Robbins, @EMAIL{arnold@@skeeve.com,arnold at skeeve dot com}.
+
+@item MS-DOS with DJGPP @tab Scott Deifik, @EMAIL{scottd.mail@@sbcglobal.net,scottd dot mail at sbcglobal dot net}.
+
+@item MS-Windows with MinGW @tab Eli Zaretskii, @EMAIL{eliz@@gnu.org,eliz at gnu dot org}.
+
+@c Leave this in the print version on purpose.
+@c OS/2 is not mentioned anywhere else in the print version though.
+@item OS/2 @tab Andreas Buening, @EMAIL{andreas.buening@@nexgo.de,andreas dot buening at nexgo dot de}.
+
+@item VMS @tab John Malmberg, @EMAIL{wb8tyw@@qsl.net,wb8tyw at qsl.net}.
+
+@item z/OS (OS/390) @tab Dave Pitts, @EMAIL{dpitts@@cozx.com,dpitts at cozx dot com}.
+@end multitable
+
+If your bug is also reproducible under Unix, send a copy of your
+report to the @EMAIL{bug-gawk@@gnu.org,bug-gawk at gnu dot org} email list as well.
+
+@node Other Versions
+@appendixsec Other Freely Available @command{awk} Implementations
+@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
+@ifnotdocbook
+@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}
+@author Michael Brennan
+@end quotation
+@end ifnotdocbook
+
+@docbook
+<blockquote><attribution>Michael Brennan</attribution>
+<literallayout><emphasis>It's kind of fun to put comments like this in your awk code.</emphasis>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<literal>// Do C++ comments work? answer: yes! of course</literal></literallayout>
+</blockquote>
+@end docbook
+
+There are a number of other freely available @command{awk} implementations.
+This @value{SECTION} briefly describes where to get them:
+
+@table @asis
+@cindex Kernighan, Brian
+@cindex source code, Brian Kernighan's @command{awk}
+@cindex @command{awk}, versions of, See Also Brian Kernighan's @command{awk}
+@cindex Brian Kernighan's @command{awk}, source code
+@item Unix @command{awk}
+Brian Kernighan, one of the original designers of Unix @command{awk},
+has made his implementation of
+@command{awk} freely available.
+You can retrieve this version via
+@uref{http://www.cs.princeton.edu/~bwk, his home page}.
+It is available in several archive formats:
+
+@table @asis
+@item Shell archive
+@uref{http://www.cs.princeton.edu/~bwk/btl.mirror/awk.shar}
+
+@item Compressed @command{tar} file
+@uref{http://www.cs.princeton.edu/~bwk/btl.mirror/awk.tar.gz}
+
+@item Zip file
+@uref{http://www.cs.princeton.edu/~bwk/btl.mirror/awk.zip}
+@end table
+
+@cindex @command{git} utility
+You can also retrieve it from Git Hub:
+
+@example
+git clone git://github.com/onetrueawk/awk bwkawk
+@end example
+
+@noindent
+This command creates a copy of the @uref{http://git-scm.com, Git}
+repository in a directory named @file{bwkawk}. If you leave that argument
+off the @command{git} command line, the repository copy is created in a
+directory named @file{awk}.
+
+This version requires an ISO C (1990 standard) compiler; the C compiler
+from GCC (the GNU Compiler Collection) works quite nicely.
+
+@DBXREF{Common Extensions}
+for a list of extensions in this @command{awk} that are not in POSIX @command{awk}.
+
+As a side note, Dan Bornstein has created a Git repository tracking
+all the versions of BWK @command{awk} that he could find. It's
+available at @uref{git://github.com/danfuzz/one-true-awk}.
+
+@cindex Brennan, Michael
+@cindex @command{mawk} utility
+@cindex source code, @command{mawk}
+@item @command{mawk}
+Michael Brennan wrote an independent implementation of @command{awk},
+called @command{mawk}. It is available under the
+@ifclear FOR_PRINT
+GPL (@pxref{Copying}),
+@end ifclear
+@ifset FOR_PRINT
+GPL,
+@end ifset
+just as @command{gawk} is.
+
+The original distribution site for the @command{mawk} source code
+no longer has it. A copy is available at
+@uref{http://www.skeeve.com/gawk/mawk1.3.3.tar.gz}.
+
+In 2009, Thomas Dickey took on @command{mawk} maintenance.
+Basic information is available on
+@uref{http://www.invisible-island.net/mawk, the project's web page}.
+The download URL is
+@url{http://invisible-island.net/datafiles/release/mawk.tar.gz}.
+
+Once you have it,
+@command{gunzip} may be used to decompress this file. Installation
+is similar to @command{gawk}'s
+(@pxref{Unix Installation}).
+
+@DBXREF{Common Extensions}
+for a list of extensions in @command{mawk} that are not in POSIX @command{awk}.
+
+@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 @url{http://sourceforge.net/projects/awka}.
+@c You can reach Andrew Sumner at @email{andrew@@zbcom.net}.
+@c andrewsumner@@yahoo.net
+
+The project seems to be frozen; no new code changes have been made
+since approximately 2003.
+
+@cindex Beebe, Nelson H.F.@:
+@cindex @command{pawk} (profiling version of Brian Kernighan's @command{awk})
+@cindex source code, @command{pawk}
+@item @command{pawk}
+Nelson H.F.@: Beebe at the University of Utah has modified
+BWK @command{awk} to provide timing and profiling information.
+It is different from @command{gawk} with the @option{--profile} option
+(@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-20030606.tar.gz}
+or
+@uref{http://www.math.utah.edu/pub/pawk/pawk-20030606.tar.gz}.
+
+@item Busybox Awk
+@cindex Busybox Awk
+@cindex source code, Busybox Awk
+Busybox is a GPL-licensed program providing small versions of many
+applications within a single executable. It is aimed at embedded systems.
+It includes a full implementation of POSIX @command{awk}. When building
+it, be careful not to do @samp{make install} as it will overwrite
+copies of other applications in your @file{/usr/local/bin}. For more
+information, see the @uref{http://busybox.net, project's home page}.
+
+@cindex OpenSolaris
+@cindex Solaris, POSIX-compliant @command{awk}
+@cindex source code, Solaris @command{awk}
+@item The OpenSolaris POSIX @command{awk}
+The versions of @command{awk} in @file{/usr/xpg4/bin} and
+@file{/usr/xpg6/bin} on Solaris are more-or-less POSIX-compliant.
+They are based on the @command{awk} from Mortice Kern Systems for PCs.
+We were able to make this code compile and work under GNU/Linux
+with 1--2 hours of work. Making it more generally portable (using
+GNU Autoconf and/or Automake) would take more work, and this
+has not been done, at least to our knowledge.
+
+@cindex Illumos
+@cindex Illumos, POSIX-compliant @command{awk}
+@cindex source code, Illumos @command{awk}
+The source code used to be available from the OpenSolaris website.
+However, that project was ended and the website shut down. Fortunately, the
+@uref{http://wiki.illumos.org/display/illumos/illumos+Home, Illumos project}
+makes this implementation available. You can view the files one at a time from
+@uref{https://github.com/joyent/illumos-joyent/blob/master/usr/src/cmd/awk_xpg4}.
+
+@cindex @command{jawk}
+@cindex Java implementation of @command{awk}
+@cindex source code, @command{jawk}
+@item @command{jawk}
+This is an interpreter for @command{awk} written in Java. It claims
+to be a full interpreter, although because it uses Java facilities
+for I/O and for regexp matching, the language it supports is different
+from POSIX @command{awk}. More information is available on the
+@uref{http://jawk.sourceforge.net, project's home page}.
+
+@item Libmawk
+@cindex libmawk
+@cindex source code, libmawk
+This is an embeddable @command{awk} interpreter derived from
+@command{mawk}. For more information, see
+@uref{http://repo.hu/projects/libmawk/}.
+
+@item @code{pawk}
+@cindex source code, @command{pawk} (Python version)
+@cindex @code{pawk}, @command{awk}-like facilities for Python
+This is a Python module that claims to bring @command{awk}-like
+features to Python. See @uref{https://github.com/alecthomas/pawk}
+for more information. (This is not related to Nelson Beebe's
+modified version of BWK @command{awk}, described earlier.)
+
+@item @w{QSE Awk}
+@cindex QSE Awk
+@cindex source code, QSE Awk
+This is an embeddable @command{awk} interpreter. For more information,
+see @uref{http://code.google.com/p/qse/} and @uref{http://awk.info/?tools/qse}.
+
+@item @command{QTawk}
+@cindex QuikTrim Awk
+@cindex source code, QuikTrim Awk
+This is an independent implementation of @command{awk} distributed
+under the GPL. It has a large number of extensions over standard
+@command{awk} and may not be 100% syntactically compatible with it.
+See @uref{http://www.quiktrim.org/QTawk.html} for more information,
+including the manual and a download link.
+
+The project may also be frozen; no new code changes have been made
+since approximately 2008.
+
+@item Other versions
+See also the ``Versions and implementations'' section of the
+@uref{http://en.wikipedia.org/wiki/Awk_language#Versions_and_implementations,
+Wikipedia article} for information on additional versions.
+
+@end table
+
+@node Installation summary
+@appendixsec Summary
+
+@itemize @value{BULLET}
+@item
+The @command{gawk} distribution is available from GNU project's main
+distribution site, @code{ftp.gnu.org}. The canonical build recipe is:
+
+@example
+wget http://ftp.gnu.org/gnu/gawk/gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz
+tar -xvpzf gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz
+cd gawk-@value{VERSION}.@value{PATCHLEVEL}
+./configure && make && make check
+@end example
+
+@item
+@command{gawk} may be built on non-POSIX systems as well. The currently
+supported systems are MS-Windows using DJGPP, MSYS, MinGW and Cygwin,
+@ifclear FOR_PRINT
+OS/2 using EMX,
+@end ifclear
+and both Vax/VMS and OpenVMS.
+Instructions for each system are included in this @value{CHAPTER}.
+
+@item
+Bug reports should be sent via email to @email{bug-gawk@@gnu.org}.
+Bug reports should be in English, and should include the version of @command{gawk},
+how it was compiled, and a short program and @value{DF} which demonstrate
+the problem.
+
+@item
+There are a number of other freely available @command{awk}
+implementations. Many are POSIX compliant; others are less so.
+
+@end itemize
+
+
+@ifclear FOR_PRINT
+@node Notes
+@appendix Implementation Notes
+@cindex @command{gawk}, implementation issues
+@cindex implementation issues, @command{gawk}
+
+This appendix contains information mainly of interest to implementers 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}.
+* Future Extensions:: New features that may be implemented one day.
+* Implementation Limitations:: Some limitations of the implementation.
+* Extension Design:: Design notes about the extension API.
+* Old Extension Mechanism:: Some compatibility for old extensions.
+* Notes summary:: Summary of implementation notes.
+@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 -Y
+@itemx --parsedebug
+Print 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
+* Accessing The Source:: Accessing the Git repository.
+* Adding Code:: Adding code to the main body of
+ @command{gawk}.
+* New Ports:: Porting @command{gawk} to a new operating
+ system.
+* Derived Files:: Why derived files are kept in the Git
+ repository.
+@end menu
+
+@node Accessing The Source
+@appendixsubsec Accessing The @command{gawk} Git Repository
+
+As @command{gawk} is Free Software, the source code is always available.
+@DBREF{Gawk Distribution} describes how to get and build the formal,
+released versions of @command{gawk}.
+
+@cindex @command{git} utility
+However, if you want to modify @command{gawk} and contribute back your
+changes, you will probably wish to work with the development version.
+To do so, you will need to access the @command{gawk} source code
+repository. The code is maintained using the
+@uref{http://git-scm.com, Git distributed version control system}.
+You will need to install it if your system doesn't have it.
+Once you have done so, use the command:
+
+@example
+git clone git://git.savannah.gnu.org/gawk.git
+@end example
+
+@noindent
+This clones the @command{gawk} repository. If you are behind a
+firewall that does not allow you to use the Git native protocol, you
+can still access the repository using:
+
+@example
+git clone http://git.savannah.gnu.org/r/gawk.git
+@end example
+
+Once you have made changes, you can use @samp{git diff} to produce a
+patch, and send that to the @command{gawk} maintainer; see @ref{Bugs},
+for how to do that.
+
+Once upon a time there was Git--CVS gateway for use by people who could
+not install Git. However, this gateway no longer works, so you may have
+better luck using a more modern version control system like Bazaar,
+that has a Git plug-in for working with Git repositories.
+
+@node Adding Code
+@appendixsubsec Adding New Features
+
+@cindex adding, features to @command{gawk}
+@cindex features, adding to @command{gawk}
+@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 to include them:
+
+@enumerate 1
+@item
+Before building the new feature into @command{gawk} itself,
+consider writing it as an extension
+(@pxref{Dynamic Extensions}).
+If that's not possible, continue with the rest of the steps in this list.
+
+@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{assign@@gnu.org,assign at gnu dot org}.
+
+@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}, or better yet,
+relative to the latest code in the Git repository. If your version of
+@command{gawk} is very old, I may not be able to integrate your changes at all.
+(@xref{Getting},
+for information on getting the latest version of @command{gawk}.)
+
+@item
+@ifnotinfo
+Follow the @uref{http://www.gnu.org/prep/standards/, @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
+@uref{http://www.gnu.org/prep/standards_toc.html, website}.
+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 @value{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 @code{true} and @code{false} for @code{bool} values,
+the @code{NULL} symbolic constant for pointer values,
+and the character constant @code{'\0'} where appropriate, instead of @code{1}
+and @code{0}.
+
+@item
+Provide one-line descriptive comments for each function.
+
+@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()}.
+
+@item
+Do not use comparisons of the form @samp{! strcmp(a, b)} or similar.
+As Henry Spencer once said, ``@code{strcmp()} is not a boolean!''
+Instead, use @samp{strcmp(a, b) == 0}.
+
+@item
+If adding new bit flag values, use explicit hexadecimal constants
+(@code{0x001}, @code{0x002}, @code{0x004}, and son on) instead of
+shifting one left by successive amounts (@samp{(1<<0)}, @samp{(1<<1)},
+and so on).
+@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
+
+@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.
+
+@cindex @command{git} utility
+@item
+Submit changes as unified diffs.
+Use @samp{diff -u -r -N} to compare
+the original @command{gawk} source tree with your version.
+I recommend using the GNU version of @command{diff}, or best of all,
+@samp{git diff} or @samp{git format-patch}.
+Send the output produced by @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.
+It is simplest if you just make this part of your diff.
+@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.
+
+@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
+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 @emph{many} people have done so
+already. If you have questions, please contact me, or
+@email{gnu@@gnu.org}.
+
+@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. 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{dfa.c},
+@file{dfa.h},
+@file{getopt.c},
+@file{getopt.h},
+@file{getopt1.c},
+@file{getopt_int.h},
+@file{gettext.h},
+@file{regcomp.c},
+@file{regex.c},
+@file{regex.h},
+@file{regex_internal.c},
+@file{regex_internal.h},
+and
+@file{regexec.c}.
+
+@item
+A number of other files are provided by the GNU
+Autotools (Autoconf, Automake, and GNU @command{gettext}).
+You should not change them either, unless it is for a very
+good reason. The files are
+@file{ABOUT-NLS},
+@file{config.guess},
+@file{config.rpath},
+@file{config.sub},
+@file{depcomp},
+@file{INSTALL},
+@file{install-sh},
+@file{missing},
+@file{mkinstalldirs},
+@file{xalloc.h},
+and
+@file{ylwrap}.
+
+@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 no-one
+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.
+@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 Derived Files
+@appendixsubsec Why Generated Files Are Kept In Git
+
+@cindex Git, use of for @command{gawk} source code
+@c From emails written March 22, 2012, to the gawk developers list.
+
+If you look at the @command{gawk} source in the Git
+repository, you will notice that it includes files that are automatically
+generated by GNU infrastructure tools, such as @file{Makefile.in} from
+Automake and even @file{configure} from Autoconf.
+
+This is different from many Free Software projects that do not store
+the derived files, because that keeps the repository less cluttered,
+and it is easier to see the substantive changes when comparing versions
+and trying to understand what changed between commits.
+
+However, there are several reasons why the @command{gawk} maintainer
+likes to have everything in the repository.
+
+First, because it is then easy to reproduce any given version completely,
+without relying upon the availability of (older, likely obsolete, and
+maybe even impossible to find) other tools.
+
+As an extreme example, if you ever even think about trying to compile,
+oh, say, the V7 @command{awk}, you will discover that not only do you
+have to bootstrap the V7 @command{yacc} to do so, but you also need the
+V7 @command{lex}. And the latter is pretty much impossible to bring up
+on a modern GNU/Linux system.@footnote{We tried. It was painful.}
+
+(Or, let's say @command{gawk} 1.2 required @command{bison} whatever-it-was
+in 1989 and that there was no @file{awkgram.c} file in the repository. Is
+there a guarantee that we could find that @command{bison} version? Or that
+@emph{it} would build?)
+
+If the repository has all the generated files, then it's easy to just check
+them out and build. (Or @emph{easier}, depending upon how far back we go.)
+
+And that brings us to the second (and stronger) reason why all the files
+really need to be in Git. It boils down to who do you cater
+to---the @command{gawk} developer(s), or the user who just wants to check
+out a version and try it out?
+
+The @command{gawk} maintainer
+wants it to be possible for any interested @command{awk} user in the
+world to just clone the repository, check out the branch of interest and
+build it. Without their having to have the correct version(s) of the
+autotools.@footnote{There is one GNU program that is (in our opinion)
+severely difficult to bootstrap from the Git repository. For
+example, on the author's old (but still working) PowerPC Macintosh with
+Mac OS X 10.5, it was necessary to bootstrap a ton of software, starting
+with Git itself, in order to try to work with the latest code.
+It's not pleasant, and especially on older systems, it's a big waste
+of time.
+
+Starting with the latest tarball was no picnic either. The maintainers
+had dropped @file{.gz} and @file{.bz2} files and only distribute
+@file{.tar.xz} files. It was necessary to bootstrap @command{xz} first!}
+That is the point of the @file{bootstrap.sh} file. It touches the
+various other files in the right order such that
+
+@example
+# The canonical incantation for building GNU software:
+./bootstrap.sh && ./configure && make
+@end example
+
+@noindent
+will @emph{just work}.
+
+This is extremely important for the @code{master} and
+@code{gawk-@var{X}.@var{Y}-stable} branches.
+
+Further, the @command{gawk} maintainer would argue that it's also
+important for the @command{gawk} developers. When he tried to check out
+the @code{xgawk} branch@footnote{A branch (since removed) created by one of the other
+developers that did not include the generated files.} to build it, he
+couldn't. (No @file{ltmain.sh} file, and he had no idea how to create it,
+and that was not the only problem.)
+
+He felt @emph{extremely} frustrated. With respect to that branch,
+the maintainer is no different than Jane User who wants to try to build
+@code{gawk-4.1-stable} or @code{master} from the repository.
+
+Thus, the maintainer thinks that it's not just important, but critical,
+that for any given branch, the above incantation @emph{just works}.
+
+@c Added 9/2014:
+A third reason to have all the files is that without them, using @samp{git
+bisect} to try to find the commit that introduced a bug is exceedingly
+difficult. The maintainer tried to do that on another project that
+requires running bootstrapping scripts just to create @command{configure}
+and so on; it was really painful. When the repository is self-contained,
+using @command{git bisect} in it is very easy.
+
+@c So - that's my reasoning and philosophy.
+
+What are some of the consequences and/or actions to take?
+
+@enumerate 1
+@item
+We don't mind that there are differing files in the different branches
+as a result of different versions of the autotools.
+
+@enumerate A
+@item
+It's the maintainer's job to merge them and he will deal with it.
+
+@item
+He is really good at @samp{git diff x y > /tmp/diff1 ; gvim /tmp/diff1} to
+remove the diffs that aren't of interest in order to review code.
+@end enumerate
+
+@item
+It would certainly help if everyone used the same versions of the GNU tools
+as he does, which in general are the latest released versions of
+Automake,
+Autoconf,
+@command{bison},
+and
+GNU @command{gettext}.
+
+@ignore
+If it would help if I sent out an ``I just upgraded to version x.y
+of tool Z'' kind of message to this list, I can do that. Up until
+now it hasn't been a real issue since I'm the only one who's been
+dorking with the configuration machinery.
+@end ignore
+
+@c @enumerate A
+@c @item
+Installing from source is quite easy. It's how the maintainer worked for years
+(and still works).
+He had @file{/usr/local/bin} at the front of his @env{PATH} and just did:
+
+@example
+wget http://ftp.gnu.org/gnu/@var{package}/@var{package}-@var{x}.@var{y}.@var{z}.tar.gz
+tar -xpzvf @var{package}-@var{x}.@var{y}.@var{z}.tar.gz
+cd @var{package}-@var{x}.@var{y}.@var{z}
+./configure && make && make check
+make install # as root
+@end example
+
+@c @item
+@ignore
+These days the maintainer uses Ubuntu 12.04 which is medium current, but
+he is already doing the above for Automake, Autoconf, and @command{bison}.
+@end ignore
+
+@ignore
+(C. Rant: Recent Linux versions with GNOME 3 really suck. What
+ are all those people thinking? Fedora 15 was such a bust it drove
+ me to Ubuntu, but Ubuntu 11.04 and 11.10 are totally unusable from
+ a UI perspective. Bleah.)
+@end ignore
+@c @end enumerate
+
+@ignore
+@item
+If someone still feels really strongly about all this, then perhaps they
+can have two branches, one for their development with just the clean
+changes, and one that is buildable (xgawk and xgawk-buildable, maybe).
+Or, as I suggested in another mail, make commits in pairs, the first with
+the "real" changes and the second with "everything else needed for
+ building".
+@end ignore
+@end enumerate
+
+Most of the above was originally written by the maintainer to other
+@command{gawk} developers. It raised the objection from one of
+the developers ``@dots{} that anybody pulling down the source from
+Git is not an end user.''
+
+However, this is not true. There are ``power @command{awk} users''
+who can build @command{gawk} (using the magic incantation shown previously)
+but who can't program in C. Thus, the major branches should be
+kept buildable all the time.
+
+It was then suggested that there be a @command{cron} job to create
+nightly tarballs of ``the source.'' Here, the problem is that there
+are source trees, corresponding to the various branches! So,
+nightly tarballs aren't the answer, especially as the repository can go
+for weeks without significant change being introduced.
+
+Fortunately, the Git server can meet this need. For any given
+branch named @var{branchname}, use:
+
+@example
+wget http://git.savannah.gnu.org/cgit/gawk.git/snapshot/gawk-@var{branchname}.tar.gz
+@end example
+
+@noindent
+to retrieve a snapshot of the given branch.
+
+@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.}
+@author Arnold Robbins
+@end quotation
+
+@quotation
+@i{Hey!}
+@author Larry Wall
+@end quotation
+
+The @file{TODO} file in the @code{master} branch of the @command{gawk}
+Git repository lists possible future enhancements. Some of these relate
+to the source code, and others to possible new features. Please see
+that file for the list.
+@xref{Additions},
+if you are interested in tackling any of the projects listed there.
+
+@node Implementation Limitations
+@appendixsec Some Limitations of the Implementation
+
+This following table describes limits of @command{gawk} on a Unix-like
+system (although it is variable even then). Other systems may have
+different limits.
+
+@multitable @columnfractions .40 .60
+@headitem Item @tab Limit
+@item Characters in a character class @tab 2^(number of bits per byte)
+@item Length of input record @tab @code{MAX_INT}
+@item Length of output record @tab Unlimited
+@item Length of source line @tab Unlimited
+@item Number of fields in a record @tab @code{MAX_LONG}
+@item Number of file redirections @tab Unlimited
+@item Number of input records in one file @tab @code{MAX_LONG}
+@item Number of input records total @tab @code{MAX_LONG}
+@item Number of pipe redirections @tab min(number of processes per user, number of open files)
+@item Numeric values @tab Double-precision floating point (if not using MPFR)
+@item Size of a field @tab @code{MAX_INT}
+@item Size of a literal string @tab @code{MAX_INT}
+@item Size of a printf string @tab @code{MAX_INT}
+@end multitable
+
+@node Extension Design
+@appendixsec Extension API Design
+
+This @value{SECTION} documents the design of the extension API,
+including a discussion of some of the history and problems that needed
+to be solved.
+
+The first version of extensions for @command{gawk} was developed in
+the mid-1990s and released with @command{gawk} 3.1 in the late 1990s.
+The basic mechanisms and design remained unchanged for close to 15 years,
+until 2012.
+
+The old extension mechanism used data types and functions from
+@command{gawk} itself, with a ``clever hack'' to install extension
+functions.
+
+@command{gawk} included some sample extensions, of which a few were
+really useful. However, it was clear from the outset that the extension
+mechanism was bolted onto the side and was not really well thought out.
+
+@menu
+* Old Extension Problems:: Problems with the old mechanism.
+* Extension New Mechanism Goals:: Goals for the new mechanism.
+* Extension Other Design Decisions:: Some other design decisions.
+* Extension Future Growth:: Some room for future growth.
+@end menu
+
+@node Old Extension Problems
+@appendixsubsec Problems With The Old Mechanism
+
+The old extension mechanism had several problems:
+
+@itemize @value{BULLET}
+@item
+It depended heavily upon @command{gawk} internals. Any time the
+@code{NODE} structure@footnote{A critical central data structure
+inside @command{gawk}.} changed, an extension would have to be
+recompiled. Furthermore, to really write extensions required understanding
+something about @command{gawk}'s internal functions. There was some
+documentation in this @value{DOCUMENT}, but it was quite minimal.
+
+@item
+Being able to call into @command{gawk} from an extension required linker
+facilities that are common on Unix-derived systems but that did
+not work on MS-Windows systems; users wanting extensions on MS-Windows
+had to statically link them into @command{gawk}, even though MS-Windows supports
+dynamic loading of shared objects.
+
+@item
+The API would change occasionally as @command{gawk} changed; no compatibility
+between versions was ever offered or planned for.
+@end itemize
+
+Despite the drawbacks, the @command{xgawk} project developers forked
+@command{gawk} and developed several significant extensions. They also
+enhanced @command{gawk}'s facilities relating to file inclusion and
+shared object access.
+
+A new API was desired for a long time, but only in 2012 did the
+@command{gawk} maintainer and the @command{xgawk} developers finally
+start working on it together. More information about the @command{xgawk}
+project is provided in @ref{gawkextlib}.
+
+@node Extension New Mechanism Goals
+@appendixsubsec Goals For A New Mechanism
+
+Some goals for the new API were:
+
+@itemize @value{BULLET}
+@item
+The API should be independent of @command{gawk} internals. Changes in
+@command{gawk} internals should not be visible to the writer of an
+extension function.
+
+@item
+The API should provide @emph{binary} compatibility across @command{gawk}
+releases as long as the API itself does not change.
+
+@item
+The API should enable extensions written in C or C++ to have roughly the
+same ``appearance'' to @command{awk}-level code as @command{awk}
+functions do. This means that extensions should have:
+
+@itemize @value{MINUS}
+@item
+The ability to access function parameters.
+
+@item
+The ability to turn an undefined parameter into an array (call by reference).
+
+@item
+The ability to create, access and update global variables.
+
+@item
+Easy access to all the elements of an array at once (``array flattening'')
+in order to loop over all the element in an easy fashion for C code.
+
+@item
+The ability to create arrays (including @command{gawk}'s true
+arrays of arrays).
+@end itemize
+@end itemize
+
+Some additional important goals were:
+
+@itemize @value{BULLET}
+@item
+The API should use only features in ISO C 90, so that extensions
+can be written using the widest range of C and C++ compilers. The header
+should include the appropriate @samp{#ifdef __cplusplus} and @samp{extern "C"}
+magic so that a C++ compiler could be used. (If using C++, the runtime
+system has to be smart enough to call any constructors and destructors,
+as @command{gawk} is a C program. As of this writing, this has not been
+tested.)
+
+@item
+The API mechanism should not require access to @command{gawk}'s
+symbols@footnote{The @dfn{symbols} are the variables and functions
+defined inside @command{gawk}. Access to these symbols by code
+external to @command{gawk} loaded dynamically at runtime is
+problematic on MS-Windows.} by the compile-time or dynamic linker,
+in order to enable creation of extensions that also work on MS-Windows.
+@end itemize
+
+During development, it became clear that there were other features
+that should be available to extensions, which were also subsequently
+provided:
+
+@itemize @value{BULLET}
+@item
+Extensions should have the ability to hook into @command{gawk}'s
+I/O redirection mechanism. In particular, the @command{xgawk}
+developers provided a so-called ``open hook'' to take over reading
+records. During development, this was generalized to allow
+extensions to hook into input processing, output processing, and
+two-way I/O.
+
+@item
+An extension should be able to provide a ``call back'' function
+to perform cleanup actions when @command{gawk} exits.
+
+@item
+An extension should be able to provide a version string so that
+@command{gawk}'s @option{--version} option can provide information
+about extensions as well.
+@end itemize
+
+The requirement to avoid access to @command{gawk}'s symbols is, at first
+glance, a difficult one to meet.
+
+One design, apparently used by Perl and Ruby and maybe others, would
+be to make the mainline @command{gawk} code into a library, with the
+@command{gawk} utility a small C @code{main()} function linked against
+the library.
+
+This seemed like the tail wagging the dog, complicating build and
+installation and making a simple copy of the @command{gawk} executable
+from one system to another (or one place to another on the same
+system!) into a chancy operation.
+
+Pat Rankin suggested the solution that was adopted.
+@xref{Extension Mechanism Outline}, for the details.
+
+@node Extension Other Design Decisions
+@appendixsubsec Other Design Decisions
+
+As an arbitrary design decision, extensions can read the values of
+predefined variables and arrays (such as @code{ARGV} and @code{FS}), but cannot
+change them, with the exception of @code{PROCINFO}.
+
+The reason for this is to prevent an extension function from affecting
+the flow of an @command{awk} program outside its control. While a real
+@command{awk} function can do what it likes, that is at the discretion
+of the programmer. An extension function should provide a service or
+make a C API available for use within @command{awk}, and not mess with
+@code{FS} or @code{ARGC} and @code{ARGV}.
+
+In addition, it becomes easy to start down a slippery slope. How
+much access to @command{gawk} facilities do extensions need?
+Do they need @code{getline}? What about calling @code{gsub()} or
+compiling regular expressions? What about calling into @command{awk}
+functions? (@emph{That} would be messy.)
+
+In order to avoid these issues, the @command{gawk} developers chose
+to start with the simplest, most basic features that are still truly useful.
+
+Another decision is that although @command{gawk} provides nice things like
+MPFR, and arrays indexed internally by integers, these features are not
+being brought out to the API in order to keep things simple and close to
+traditional @command{awk} semantics. (In fact, arrays indexed internally
+by integers are so transparent that they aren't even documented!)
+
+Additionally, all functions in the API check that their pointer
+input parameters are not @code{NULL}. If they are, they return an error.
+(It is a good idea for extension code to verify that
+pointers received from @command{gawk} are not @code{NULL}.
+Such a thing should not happen, but the @command{gawk} developers
+are only human, and they have been known to occasionally make
+mistakes.)
+
+With time, the API will undoubtedly evolve; the @command{gawk} developers
+expect this to be driven by user needs. For now, the current API seems
+to provide a minimal yet powerful set of features for creating extensions.
+
+@node Extension Future Growth
+@appendixsubsec Room For Future Growth
+
+The API can later be expanded, in two ways:
+
+@itemize @value{BULLET}
+@item
+@command{gawk} passes an ``extension id'' into the extension when it
+first loads the extension. The extension then passes this id back
+to @command{gawk} with each function call. This mechanism allows
+@command{gawk} to identify the extension calling into it, should it need
+to know.
+
+@item
+Similarly, the extension passes a ``name space'' into @command{gawk}
+when it registers each extension function. This accommodates a possible future
+mechanism for grouping extension functions and possibly avoiding name
+conflicts.
+@end itemize
+
+Of course, as of this writing, no decisions have been made with respect
+to any of the above.
+
+@node Old Extension Mechanism
+@appendixsec Compatibility For Old Extensions
+
+@ref{Dynamic Extensions}, describes the supported API and mechanisms
+for writing extensions for @command{gawk}. This API was introduced
+in @value{PVERSION} 4.1. However, for many years @command{gawk}
+provided an extension mechanism that required knowledge of @command{gawk}
+internals and that was not as well designed.
+
+In order to provide a transition period, @command{gawk} @value{PVERSION} 4.1
+continues to support the original extension mechanism.
+This will be true for the life of exactly one major release. This support
+will be withdrawn, and removed from the source code, at the next major
+release.
+
+Briefly, original-style extensions should be compiled by including the
+@file{awk.h} header file in the extension source code. Additionally,
+you must define the identifier @samp{GAWK} when building (use
+@samp{-DGAWK} with Unix-style compilers). Otherwise, the definitions
+in @file{gawkapi.h} will cause conflicts with those in @file{awk.h}
+and your extension will not compile.
+
+Just as in previous versions, you load an old-style extension with the
+@code{extension()} built-in function (which is not otherwise documented).
+This function in turn finds and loads the shared object file containing
+the extension and calls its @code{dl_load()} C routine.
+
+Because original-style and new-style extensions use different initialization
+routines (@code{dl_load()} versus @code{dlload()}), they may safely
+be installed in the same directory (to be found by @env{AWKLIBPATH})
+without conflict.
+
+The @command{gawk} development team strongly recommends that you
+convert any old extensions that you may have to use the new API
+described in @ref{Dynamic Extensions}.
+
+@node Notes summary
+@appendixsec Summary
+
+@itemize @value{BULLET}
+@item
+@command{gawk}'s extensions can be disabled with either the
+@option{--traditional} option or with the @option{--posix} option.
+The @option{--parsedebug} option is available if @command{gawk} is
+compiled with @samp{-DDEBUG}.
+
+@item
+The source code for @command{gawk} is maintained in a publicly
+accessible Git repository. Anyone may check it out and view the source.
+
+@item
+Contributions to @command{gawk} are welcome. Following the steps
+outlined in this @value{CHAPTER} will make it easier to integrate
+your contributions into the code base.
+This applies both to new feature contributions and to ports to
+additional operating systems.
+
+@item
+@command{gawk} has some limits---generally those that are imposed by
+the machine architecture.
+
+@item
+The extension API design was intended to solve a number of problems
+with the previous extension mechanism, enable features needed by
+the @code{xgawk} project, and provide binary compatibility going forward.
+
+@item
+The previous extension mechanism is still supported in @value{PVERSION} 4.1
+of @command{gawk}, but it @emph{will} be removed in the next major release.
+
+@end itemize
+
+
+@node Basic Concepts
+@appendix Basic Programming Concepts
+@cindex programming, concepts
+@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.
+@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.
+@ifnotdocbook
+See @ref{figure-general-flow}.
+@end ifnotdocbook
+@ifdocbook
+See @inlineraw{docbook, <xref linkend="figure-general-flow"/>}.
+@end ifdocbook
+
+@ifnotdocbook
+@float Figure,figure-general-flow
+@caption{General Program Flow}
+@ifinfo
+@center @image{general-program, , , General program flow, txt}
+@end ifinfo
+@ifnotinfo
+@center @image{general-program, , , General program flow}
+@end ifnotinfo
+@end float
+@end ifnotdocbook
+
+@docbook
+<figure id="figure-general-flow" float="0">
+<title>General Program Flow</title>
+<mediaobject>
+<imageobject role="web"><imagedata fileref="general-program.png" format="PNG"/></imageobject>
+</mediaobject>
+</figure>
+@end docbook
+
+@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++, 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,
+@ifnotdocbook
+as shown in @ref{figure-process-flow}:
+@end ifnotdocbook
+@ifdocbook
+as shown in @inlineraw{docbook, <xref linkend="figure-process-flow"/>}:
+@end ifdocbook
+
+@ifnotdocbook
+@float Figure,figure-process-flow
+@caption{Basic Program Steps}
+@ifinfo
+@center @image{process-flow, , , Basic Program Stages, txt}
+@end ifinfo
+@ifnotinfo
+@center @image{process-flow, , , Basic Program Stages}
+@end ifnotinfo
+@end float
+@end ifnotdocbook
+
+@docbook
+<figure id="figure-process-flow" float="0">
+<title>Basic Program Stages</title>
+<mediaobject>
+<imageobject role="web"><imagedata fileref="process-flow.png" format="PNG"/></imageobject>
+</mediaobject>
+</figure>
+@end docbook
+
+@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 do 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.
+
+@ref{Computer Arithmetic}, provided a basic introduction to numeric
+types (integer and floating-point) and how they are used in a computer.
+Please review that information, including a number of caveats that
+were presented.
+
+@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 = 4 x 10 + 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 x 8) + (0 x 4) + (1 x 2)
++ (0 x 1), or decimal 10.
+Octal and hexadecimal are discussed more in
+@ref{Nondecimal-numbers}.
+
+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.
+
+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.
+In 1999, a revised ISO C standard was approved and released.
+Where it makes sense, POSIX @command{awk} is compatible with 1999 ISO C.
+
+
+@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 braces.
+(@xref{Action Overview}.)
+
+@cindex Ada programming language
+@cindex programming languages, Ada
+@item Ada
+A programming language originally defined by the U.S.@: Department of
+Defense for embedded programming. It was designed to enforce good
+Software Engineering practices.
+
+@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{http://awk.info/?awk100/aaa}.
+
+@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
+from @uref{http://awk.info/?tools/awf}.
+
+@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 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 have essentially
+disappeared.
+
+@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 at Bell Laboratories.
+Many shells (Bash, @command{ksh}, @command{pdksh}, @command{zsh}) are
+generally upwardly compatible with the Bourne shell.
+
+@item Braces
+The characters @samp{@{} and @samp{@}}. Braces are used in
+@command{awk} for delimiting actions, compound statements, and function
+bodies.
+
+@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,
+array sorting, type checking,
+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{FPAT},
+@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 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.
+
+@item C++
+A popular object-oriented programming language derived from C.
+
+@cindex ASCII
+@cindex ISO 8859-1
+@cindex ISO Latin-1
+@cindex character sets (machine character encodings)
+@cindex Unicode
+@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).
+The @uref{http://www.unicode.org, Unicode character set} is
+increasingly popular and standard, and is particularly
+widely used on GNU/Linux systems.
+
+@cindex Kernighan, Brian
+@cindex Bentley, Jon
+@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://netlib.sandia.gov/netlib/typesetting/chem.gz}.
+
+@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}.)
+
+@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}.)
+
+@cindex McIlroy, Doug
+@cindex cookie
+@item Cookie
+A peculiar goodie, token, saying or remembrance
+produced by or presented to a program. (With thanks to Professor Doug McIlroy.)
+@ignore
+From: Doug McIlroy <doug@cs.dartmouth.edu>
+Date: Sat, 13 Oct 2012 19:55:25 -0400
+To: arnold@skeeve.com
+Subject: Re: origin of the term "cookie"?
+
+I believe the term "cookie", for a more or less inscrutable
+saying or crumb of information, was injected into Unix
+jargon by Bob Morris, who used the word quite frequently.
+It had no fixed meaning as it now does in browsers.
+
+The word had been around long before it was recognized in
+the 8th edition glossary (earlier editions had no glossary):
+
+cookie a peculiar goodie, token, saying or remembrance
+returned by or presented to a program. [I would say that
+"returned by" would better read "produced by", and assume
+responsibility for the inexactitude.]
+
+Doug McIlroy
+
+From: Doug McIlroy <doug@cs.dartmouth.edu>
+Date: Sun, 14 Oct 2012 10:08:43 -0400
+To: arnold@skeeve.com
+Subject: Re: origin of the term "cookie"?
+
+> Can I forward your email to Eric Raymond, for possible addition to the
+> Jargon File?
+
+Sure. I might add that I don't know how "cookie" entered Morris's
+vocabulary. Certainly "values of beta give rise to dom!" (see google)
+was an early, if not the earliest Unix cookie. The fact that it was
+found lying around on a model 37 teletype (which had Greek beta in
+its type box) suggests that maybe it was seen to be like milk and
+cookies laid out for Santa Claus. Morris was wont to make such
+connections.
+
+Doug
+@end ignore
+
+@item Coprocess
+A subordinate program with which two-way communications is possible.
+
+@item Curly Braces
+See ``Braces.''
+
+@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 Debugger
+A program used to help developers remove ``bugs'' from (de-bug)
+their programs.
+
+@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 Empty String
+See ``Null String.''
+
+@item Environment
+A collection of strings, of the form @samp{@var{name}=@var{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}.
+
+@cindex epoch, definition of
+@item Epoch
+The date used as the ``beginning of time'' for timestamps.
+Time values in most 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 Extension
+An additional feature or change to a programming language or
+utility not defined by that language's or utility's standard.
+@command{gawk} has (too) many extensions over POSIX @command{awk}.
+
+@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 predefined 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.
+If you wish to specify the contents of fields instead of the field
+separator, you can use the predefined variable @code{FPAT} to do so.
+(@xref{Field Separators},
+@ref{Constant Size},
+and
+@ref{Splitting By Content}.)
+
+@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 control the appearance of output in the
+@code{strftime()} and @code{sprintf()} functions, and in the
+@code{printf} statement as well. Also, data conversions from numbers to strings
+are controlled by the format strings contained in the predefined variables
+@code{CONVFMT} and @code{OFMT}. (@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}.)
+
+@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 FSF
+See ``Free Software Foundation.''
+
+@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 @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 internally 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.
+The Linux kernel 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 x 16) + 2).
+@xref{Nondecimal-numbers}.
+
+@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 originally available
+in @command{awk} programs.
+
+@cindex ISO
+@item ISO
+The International Organization for Standardization.
+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.
+See @uref{http://www.iso.org/iso/home/about.htm, the ISO website} for more
+information about the name of the organization and its language-independent
+three-letter acronym.
+
+@cindex Java programming language
+@cindex programming languages, Java
+@item Java
+A modern programming language originally developed by Sun Microsystems
+(now Oracle) supporting Object-Oriented programming. Although usually
+implemented by compiling to the instructions for a standard virtual
+machine (the JVM), the language can be compiled to native code.
+
+@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{BEGINFILE},
+@code{END},
+@code{ENDFILE},
+@code{break},
+@code{case},
+@code{continue},
+@code{default}
+@code{delete},
+@code{do@dots{}while},
+@code{else},
+@code{exit},
+@code{for@dots{}in},
+@code{for},
+@code{function},
+@code{func},
+@code{if},
+@code{next},
+@code{nextfile},
+@code{switch},
+and
+@code{while}.
+
+@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 LGPL
+See ``Lesser General Public License.''
+
+@item Linux
+See ``GNU/Linux.''
+
+@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 No-op
+An operation that does nothing.
+
+@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.
+Ancient @command{awk} implementations used 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 ((1 x 8) + 3).
+@xref{Nondecimal-numbers}.
+
+@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 PEBKAC
+An acronym describing what is possibly the most frequent
+source of computer usage problems. (Problem Exists Between
+Keyboard And Chair.)
+
+@item 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
+@command{awk} users is
+@cite{IEEE Standard for Information Technology, Standard 1003.1-2008}.
+The 2008 POSIX standard can be found online at
+@url{http://www.opengroup.org/onlinepubs/9699919799/}.
+
+@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 is clear, stop, and proceed to the next entry.
+Otherwise, 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 input to the @code{getline} statement using
+the @samp{<}, @samp{|}, and @samp{|&} operators.
+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.
+(@xref{Getline},
+and @ref{Redirection}.)
+
+@item Regexp
+See ``Regular Expression.''
+
+@item Regular Expression
+A regular expression (``regexp'' for short) is a pattern that denotes a
+set of strings, possibly an infinite set. For example, the regular expression
+@samp{R.*xp} matches any string starting with the letter @samp{R}
+and ending with the letters @samp{xp}. In @command{awk}, regular expressions are
+used in patterns and in conditional expressions. Regular expressions may contain
+escape sequences. (@xref{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 @command{sed}
+See ``Stream Editor.''
+
+@item Seed
+The initial value, or starting point, for a sequence of random numbers.
+
+@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 ancient 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,'' ``GMT,'' 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, @uref{http://www.netbsd.org, NetBSD},
+@uref{http://www.freebsd.org, FreeBSD}, and @uref{http://www.openbsd.org, 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
+
+@end ifclear
+
+@c The GNU General Public License.
+@node Copying
+@unnumbered GNU General Public License
+@ifnotdocbook
+@center Version 3, 29 June 2007
+@end ifnotdocbook
+@docbook
+<subtitle>Version 3, 29 June 2007</subtitle>
+@end docbook
+
+@c This file is intended to be included within another document,
+@c hence no sectioning command or @node.
+
+@display
+Copyright @copyright{} 2007 Free Software Foundation, Inc. @url{http://fsf.org/}
+
+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
+@heading Preamble
+
+The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom
+to share and change all versions of a program---to make sure it remains
+free software for all its users. We, the Free Software Foundation,
+use the GNU General Public License for most of our software; it
+applies also to any other work released this way by its authors. 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
+them 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 prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you
+have certain responsibilities if you distribute copies of the
+software, or if you modify it: responsibilities to respect the freedom
+of others.
+
+For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. 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.
+
+Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the
+manufacturer can do so. This is fundamentally incompatible with the
+aim of protecting users' freedom to change the software. The
+systematic pattern of such abuse occurs in the area of products for
+individuals to use, which is precisely where it is most unacceptable.
+Therefore, we have designed this version of the GPL to prohibit the
+practice for those products. If such problems arise substantially in
+other domains, we stand ready to extend this provision to those
+domains in future versions of the GPL, as needed to protect the
+freedom of users.
+
+Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish
+to avoid the special danger that patents applied to a free program
+could make it effectively proprietary. To prevent this, the GPL
+assures that patents cannot be used to render the program non-free.
+
+The precise terms and conditions for copying, distribution and
+modification follow.
+
+@c fakenode --- for prepinfo
+@heading TERMS AND CONDITIONS
+
+@enumerate 0
+@item Definitions.
+
+``This License'' refers to version 3 of the GNU General Public License.
+
+``Copyright'' also means copyright-like laws that apply to other kinds
+of works, such as semiconductor masks.
+
+``The Program'' refers to any copyrightable work licensed under this
+License. Each licensee is addressed as ``you''. ``Licensees'' and
+``recipients'' may be individuals or organizations.
+
+To ``modify'' a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of
+an exact copy. The resulting work is called a ``modified version'' of
+the earlier work or a work ``based on'' the earlier work.
+
+A ``covered work'' means either the unmodified Program or a work based
+on the Program.
+
+To ``propagate'' a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+To ``convey'' a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user
+through a computer network, with no transfer of a copy, is not
+conveying.
+
+An interactive user interface displays ``Appropriate Legal Notices'' to
+the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+@item Source Code.
+
+The ``source code'' for a work means the preferred form of the work for
+making modifications to it. ``Object code'' means any non-source form
+of a work.
+
+A ``Standard Interface'' means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+The ``System Libraries'' of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+``Major Component'', in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+The ``Corresponding Source'' for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+The Corresponding Source need not include anything that users can
+regenerate automatically from other parts of the Corresponding Source.
+
+The Corresponding Source for a work in source code form is that same
+work.
+
+@item Basic Permissions.
+
+All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+You may make, run and propagate covered works that you do not convey,
+without conditions so long as your license otherwise remains in force.
+You may convey covered works to others for the sole purpose of having
+them make modifications exclusively for you, or provide you with
+facilities for running those works, provided that you comply with the
+terms of this License in conveying all material for which you do not
+control copyright. Those thus making or running the covered works for
+you must do so exclusively on your behalf, under your direction and
+control, on terms that prohibit them from making any copies of your
+copyrighted material outside their relationship with you.
+
+Conveying under any other circumstances is permitted solely under the
+conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+@item Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such
+circumvention is effected by exercising rights under this License with
+respect to the covered work, and you disclaim any intention to limit
+operation or modification of the work as a means of enforcing, against
+the work's users, your or third parties' legal rights to forbid
+circumvention of technological measures.
+
+@item Conveying Verbatim Copies.
+
+You may convey 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;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+@item Conveying Modified Source Versions.
+
+You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these
+conditions:
+
+@enumerate a
+@item
+The work must carry prominent notices stating that you modified it,
+and giving a relevant date.
+
+@item
+The work must carry prominent notices stating that it is released
+under this License and any conditions added under section 7. This
+requirement modifies the requirement in section 4 to ``keep intact all
+notices''.
+
+@item
+You must license the entire work, as a whole, under this License to
+anyone who comes into possession of a copy. This License will
+therefore apply, along with any applicable section 7 additional terms,
+to the whole of the work, and all its parts, regardless of how they
+are packaged. This License gives no permission to license the work in
+any other way, but it does not invalidate such permission if you have
+separately received it.
+
+@item
+If the work has interactive user interfaces, each must display
+Appropriate Legal Notices; however, if the Program has interactive
+interfaces that do not display Appropriate Legal Notices, your work
+need not make them do so.
+@end enumerate
+
+A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+``aggregate'' if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+@item Conveying Non-Source Forms.
+
+You may convey a covered work in object code form under the terms of
+sections 4 and 5, provided that you also convey the machine-readable
+Corresponding Source under the terms of this License, in one of these
+ways:
+
+@enumerate a
+@item
+Convey the object code in, or embodied in, a physical product
+(including a physical distribution medium), accompanied by the
+Corresponding Source fixed on a durable physical medium customarily
+used for software interchange.
+
+@item
+Convey the object code in, or embodied in, a physical product
+(including a physical distribution medium), accompanied by a written
+offer, valid for at least three years and valid for as long as you
+offer spare parts or customer support for that product model, to give
+anyone who possesses the object code either (1) a copy of the
+Corresponding Source for all the software in the product that is
+covered by this License, on a durable physical medium customarily used
+for software interchange, for a price no more than your reasonable
+cost of physically performing this conveying of source, or (2) access
+to copy the Corresponding Source from a network server at no charge.
+
+@item
+Convey individual copies of the object code with a copy of the written
+offer to provide the Corresponding Source. This alternative is
+allowed only occasionally and noncommercially, and only if you
+received the object code with such an offer, in accord with subsection
+6b.
+
+@item
+Convey the object code by offering access from a designated place
+(gratis or for a charge), and offer equivalent access to the
+Corresponding Source in the same way through the same place at no
+further charge. You need not require recipients to copy the
+Corresponding Source along with the object code. If the place to copy
+the object code is a network server, the Corresponding Source may be
+on a different server (operated by you or a third party) that supports
+equivalent copying facilities, provided you maintain clear directions
+next to the object code saying where to find the Corresponding Source.
+Regardless of what server hosts the Corresponding Source, you remain
+obligated to ensure that it is available for as long as needed to
+satisfy these requirements.
+
+@item
+Convey the object code using peer-to-peer transmission, provided you
+inform other peers where the object code and Corresponding Source of
+the work are being offered to the general public at no charge under
+subsection 6d.
+
+@end enumerate
+
+A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+A ``User Product'' is either (1) a ``consumer product'', which means any
+tangible personal property which is normally used for personal,
+family, or household purposes, or (2) anything designed or sold for
+incorporation into a dwelling. In determining whether a product is a
+consumer product, doubtful cases shall be resolved in favor of
+coverage. For a particular product received by a particular user,
+``normally used'' refers to a typical or common use of that class of
+product, regardless of the status of the particular user or of the way
+in which the particular user actually uses, or expects or is expected
+to use, the product. A product is a consumer product regardless of
+whether the product has substantial commercial, industrial or
+non-consumer uses, unless such uses represent the only significant
+mode of use of the product.
+
+``Installation Information'' for a User Product means any methods,
+procedures, authorization keys, or other information required to
+install and execute modified versions of a covered work in that User
+Product from a modified version of its Corresponding Source. The
+information must suffice to ensure that the continued functioning of
+the modified object code is in no case prevented or interfered with
+solely because modification has been made.
+
+If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or
+updates for a work that has been modified or installed by the
+recipient, or for the User Product in which it has been modified or
+installed. Access to a network may be denied when the modification
+itself materially and adversely affects the operation of the network
+or violates the rules and protocols for communication across the
+network.
+
+Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+@item Additional Terms.
+
+``Additional permissions'' are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders
+of that material) supplement the terms of this License with terms:
+
+@enumerate a
+@item
+Disclaiming warranty or limiting liability differently from the terms
+of sections 15 and 16 of this License; or
+
+@item
+Requiring preservation of specified reasonable legal notices or author
+attributions in that material or in the Appropriate Legal Notices
+displayed by works containing it; or
+
+@item
+Prohibiting misrepresentation of the origin of that material, or
+requiring that modified versions of such material be marked in
+reasonable ways as different from the original version; or
+
+@item
+Limiting the use for publicity purposes of names of licensors or
+authors of the material; or
+
+@item
+Declining to grant rights under trademark law for use of some trade
+names, trademarks, or service marks; or
+
+@item
+Requiring indemnification of licensors and authors of that material by
+anyone who conveys the material (or modified versions of it) with
+contractual assumptions of liability to the recipient, for any
+liability that these contractual assumptions directly impose on those
+licensors and authors.
+@end enumerate
+
+All other non-permissive additional terms are considered ``further
+restrictions'' within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions; the
+above requirements apply either way.
+
+@item Termination.
+
+You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+However, if you cease all violation of this License, then your license
+from a particular copyright holder is reinstated (a) provisionally,
+unless and until the copyright holder explicitly and finally
+terminates your license, and (b) permanently, if the copyright holder
+fails to notify you of the violation by some reasonable means prior to
+60 days after the cessation.
+
+Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+@item Acceptance Not Required for Having Copies.
+
+You are not required to accept this License in order to receive or run
+a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+@item Automatic Licensing of Downstream Recipients.
+
+Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+An ``entity transaction'' is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+@item Patents.
+
+A ``contributor'' is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's ``contributor version''.
+
+A contributor's ``essential patent claims'' are all patent claims owned
+or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, ``control'' includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+In the following three paragraphs, a ``patent license'' is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To ``grant'' such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. ``Knowingly relying'' means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+A patent license is ``discriminatory'' if it does not include within the
+scope of its coverage, prohibits the exercise of, or is conditioned on
+the non-exercise of one or more of the rights that are specifically
+granted under this License. You may not convey a covered work if you
+are a party to an arrangement with a third party that is in the
+business of distributing software, under which you make payment to the
+third party based on the extent of your activity of conveying the
+work, and under which the third party grants, to any of the parties
+who would receive the covered work from you, a discriminatory patent
+license (a) in connection with copies of the covered work conveyed by
+you (or copies made from those copies), or (b) primarily for and in
+connection with specific products or compilations that contain the
+covered work, unless you entered into that arrangement, or that patent
+license was granted, prior to 28 March 2007.
+
+Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+@item No Surrender of Others' Freedom.
+
+If 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 convey
+a covered work so as to satisfy simultaneously your obligations under
+this License and any other pertinent obligations, then as a
+consequence you may not convey it at all. For example, if you agree
+to terms that obligate you to collect a royalty for further conveying
+from those to whom you convey the Program, the only way you could
+satisfy both those terms and this License would be to refrain entirely
+from conveying the Program.
+
+@item Use with the GNU Affero General Public License.
+
+Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+@item Revised Versions of this License.
+
+The Free Software Foundation may publish revised and/or new versions
+of the GNU 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 that a certain numbered version of the GNU General Public
+License ``or any later version'' applies to it, you have the option of
+following the terms and conditions either of that numbered version or
+of any later version published by the Free Software Foundation. If
+the Program does not specify a version number of the GNU General
+Public License, you may choose any version ever published by the Free
+Software Foundation.
+
+If the Program specifies that a proxy can decide which future versions
+of the GNU General Public License can be used, that proxy's public
+statement of acceptance of a version permanently authorizes you to
+choose that version for the Program.
+
+Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+@item Disclaimer of Warranty.
+
+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 Limitation of Liability.
+
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR
+CONVEYS 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.
+
+@item Interpretation of Sections 15 and 16.
+
+If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+@end enumerate
+
+@c fakenode --- for prepinfo
+@heading END OF TERMS AND CONDITIONS
+
+@c fakenode --- for prepinfo
+@heading 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
+state 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 a brief 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 3 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, see @url{http://www.gnu.org/licenses/}.
+@end smallexample
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+@smallexample
+@var{program} Copyright (C) @var{year} @var{name of author}
+This program comes with ABSOLUTELY NO WARRANTY; for details type @samp{show w}.
+This is free software, and you are welcome to redistribute it
+under certain conditions; type @samp{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, your
+program's commands might be different; for a GUI interface, you would
+use an ``about box''.
+
+You should also get your employer (if you work as a programmer) or school,
+if any, to sign a ``copyright disclaimer'' for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+@url{http://www.gnu.org/licenses/}.
+
+The GNU 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. But
+first, please read @url{http://www.gnu.org/philosophy/why-not-lgpl.html}.
+
+@ifclear FOR_PRINT
+@c The GNU Free Documentation License.
+@node GNU Free Documentation License
+@unnumbered GNU Free Documentation License
+@ifnotdocbook
+@center Version 1.3, 3 November 2008
+@end ifnotdocbook
+
+@docbook
+<subtitle>Version 1.3, 3 November 2008</subtitle>
+@end docbook
+
+@cindex FDL (Free Documentation License)
+@cindex Free Documentation License (FDL)
+@cindex GNU Free Documentation License
+
+@c This file is intended to be included within another document,
+@c hence no sectioning command or @node.
+
+@display
+Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+@uref{http://fsf.org/}
+
+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.
+
+The ``publisher'' means any person or entity that distributes copies
+of the Document to the public.
+
+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 in 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 Warranty 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 under this License. Any attempt
+otherwise to copy, modify, sublicense, or distribute it is void, and
+will automatically terminate your rights under this License.
+
+However, if you cease all violation of this License, then your license
+from a particular copyright holder is reinstated (a) provisionally,
+unless and until the copyright holder explicitly and finally
+terminates your license, and (b) permanently, if the copyright holder
+fails to notify you of the violation by some reasonable means prior to
+60 days after the cessation.
+
+Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, receipt of a copy of some or all of the same material does
+not give you any rights to use it.
+
+@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. If the Document
+specifies that a proxy can decide which future versions of this
+License can be used, that proxy's public statement of acceptance of a
+version permanently authorizes you to choose that version for the
+Document.
+
+@item
+RELICENSING
+
+``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any
+World Wide Web server that publishes copyrightable works and also
+provides prominent facilities for anybody to edit those works. A
+public wiki that anybody can edit is an example of such a server. A
+``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the
+site means any set of copyrightable works thus published on the MMC
+site.
+
+``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0
+license published by Creative Commons Corporation, a not-for-profit
+corporation with a principal place of business in San Francisco,
+California, as well as future copyleft versions of that license
+published by that same organization.
+
+``Incorporate'' means to publish or republish a Document, in whole or
+in part, as part of another Document.
+
+An MMC is ``eligible for relicensing'' if it is licensed under this
+License, and if all works that were first published under this License
+somewhere other than this MMC, and subsequently incorporated in whole
+or in part into the MMC, (1) had no cover texts or invariant sections,
+and (2) were thus incorporated prior to November 1, 2008.
+
+The operator of an MMC Site may republish an MMC contained in the site
+under CC-BY-SA on the same site at any time before August 1, 2009,
+provided the MMC is eligible for relicensing.
+
+@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.3
+ 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@dots{}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.
+
+@end ifclear
+
+@ifnotdocbook
+@node Index
+@unnumbered Index
+@end ifnotdocbook
+@printindex cp
+
+@bye
+
+Unresolved Issues:
+------------------
+1. From ADR.
+
+ Robert J. Chassell points out that awk programs should have some indication
+ of how to use them. It would be useful to perhaps have a "programming
+ style" section of the manual that would include this and other tips.
+
+Consistency issues:
+ /.../ regexps are in @code, not @samp
+ ".." strings are in @code, not @samp
+ no @print before @dots
+ values of expressions in the text (@code{x} has the value 15),
+ should be in roman, not @code
+ Use TAB and not tab
+ Use ESC and not ESCAPE
+ Use space and not blank to describe the space bar's character
+ The term "blank" is thus basically reserved for "blank lines" etc.
+ To make dark corners work, the @value{DARKCORNER} has to be outside
+ closing `.' of a sentence and after (pxref{...}).
+ " " should have an @w{} around it
+ Use "non-" only with language names or acronyms, or the words bug and option and null
+ Use @command{ftp} when talking about anonymous ftp
+ Use uppercase and lowercase, not "upper-case" and "lower-case"
+ or "upper case" and "lower case"
+ Use "single precision" and "double precision", not "single-precision" or "double-precision"
+ Use alphanumeric, not alpha-numeric
+ Use POSIX-compliant, not POSIX compliant
+ Use --foo, not -Wfoo when describing long options
+ Use "Bell Laboratories", but not "Bell Labs".
+ Use "behavior" instead of "behaviour".
+ Use "coprocess" instead of "co-process".
+ Use "zeros" instead of "zeroes".
+ Use "nonzero" not "non-zero".
+ Use "runtime" not "run time" or "run-time".
+ Use "command-line" as an adjective and "command line" as a noun.
+ Use "online" not "on-line".
+ Use "whitespace" not "white space".
+ Use "Input/Output", not "input/output". Also "I/O", not "i/o".
+ Use "lefthand"/"righthand", not "left-hand"/"right-hand".
+ Use "workaround", not "work-around".
+ Use "startup"/"cleanup", not "start-up"/"clean-up"
+ Use "filesystem", not "file system"
+ Use @code{do}, and not @code{do}-@code{while}, except where
+ actually discussing the do-while.
+ Use "versus" in text and "vs." in index entries
+ Use @code{"C"} for the C locale, not ``C'' or @samp{C}.
+ The words "a", "and", "as", "between", "for", "from", "in", "of",
+ "on", "that", "the", "to", "with", and "without",
+ should not be capitalized in @chapter, @section etc.
+ "Into" and "How" should.
+ Search for @dfn; make sure important items are also indexed.
+ "e.g." should always be followed by a comma.
+ "i.e." should always be followed by a comma.
+ The numbers zero through ten should be spelled out, except when
+ talking about file descriptor numbers. > 10 and < 0, it's
+ ok to use numbers.
+ For most cases, do NOT put a comma before "and", "or" or "but".
+ But exercise taste with this rule.
+ Don't show the awk command with a program in quotes when it's
+ just the program. I.e.
+
+ {
+ ....
+ }
+
+ not
+ awk '{
+ ...
+ }'
+
+ Do show it when showing command-line arguments, data files, etc, even
+ if there is no output shown.
+
+ Use numbered lists only to show a sequential series of steps.
+
+ Use @code{xxx} for the xxx operator in indexing statements, not @samp.
+ Use MS-Windows not MS Windows
+ Use MS-DOS not MS-DOS
+ Use an empty set of parentheses after built-in and awk function names.
+ Use "multiFOO" without a hyphen.
+
+Date: Wed, 13 Apr 94 15:20:52 -0400
+From: rms@gnu.org (Richard Stallman)
+To: gnu-prog@gnu.org
+Subject: A reminder: no pathnames in GNU
+
+It's a GNU convention to use the term "file name" for the name of a
+file, never "pathname". We use the term "path" for search paths,
+which are lists of file names. Using it for a single file name as
+well is potentially confusing to users.
+
+So please check any documentation you maintain, if you think you might
+have used "pathname".
+
+Note that "file name" should be two words when it appears as ordinary
+text. It's ok as one word when it's a metasyntactic variable, though.
+
+------------------------
+ORA uses filename, thus the macro.
+
+Suggestions:
+------------
+
+Better sidebars can almost sort of be done with:
+
+ @ifdocbook
+ @macro @sidebar{title, content}
+ @inlinefmt{docbook, <sidebar><title>}
+ \title\
+ @inlinefmt{docbook, </title>}
+ \content\
+ @inlinefmt{docbook, </sidebar>}
+ @end macro
+ @end ifdocbook
+
+
+ @ifnotdocbook
+ @macro @sidebar{title, content}
+ @cartouche
+ @center @b{\title\}
+
+ \content\
+ @end cartouche
+ @end macro
+ @end ifnotdocbook
+
+But to use it you have to say
+
+ @sidebar{Title Here,
+ @include file-with-content
+ }
+
+which sorta sucks.
+
+TODO:
+Check that all dark corners are indexed properly.
diff --git a/doc/general-program.pdf b/doc/general-program.pdf
index c79b9efa..f4f7572c 100644
--- a/doc/general-program.pdf
+++ b/doc/general-program.pdf
Binary files differ
diff --git a/doc/general-program.png b/doc/general-program.png
new file mode 100644
index 00000000..7737261f
--- /dev/null
+++ b/doc/general-program.png
Binary files differ
diff --git a/doc/general-program.txt b/doc/general-program.txt
new file mode 100644
index 00000000..cb85c294
--- /dev/null
+++ b/doc/general-program.txt
@@ -0,0 +1,4 @@
+ _______
++------+ / \ +---------+
+| Data | -----> < Program > -----> | Results |
++------+ \_______/ +---------+
diff --git a/doc/macros b/doc/macros
index 112e3c86..59fca206 100644
--- a/doc/macros
+++ b/doc/macros
@@ -1,10 +1,10 @@
.\" SSC Reference card macros
.\"
-.\" Copyright (C) 1996, Specialized System Consultants Inc. (SSC)
+.\" Copyright (C) 1996, 2012 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
+.\" the Free Software Foundation; either version 3 of the License, or
.\" (at your option) any later version.
.\"
.\" These macros are distributed in the hope that it will be useful,
diff --git a/doc/process-flow.pdf b/doc/process-flow.pdf
index 23d567d2..3ff5f9e8 100644
--- a/doc/process-flow.pdf
+++ b/doc/process-flow.pdf
Binary files differ
diff --git a/doc/process-flow.png b/doc/process-flow.png
new file mode 100644
index 00000000..97f467f4
--- /dev/null
+++ b/doc/process-flow.png
Binary files differ
diff --git a/doc/process-flow.txt b/doc/process-flow.txt
new file mode 100644
index 00000000..d7296385
--- /dev/null
+++ b/doc/process-flow.txt
@@ -0,0 +1,11 @@
+ ______
++----------------+ / More \ No +----------+
+| Initialization | -------> < Data > -------> | Clean Up |
++----------------+ ^ \ ? / +----------+
+ | +--+-+
+ | | Yes
+ | |
+ | V
+ | +---------+
+ +-----+ Process |
+ +---------+
diff --git a/doc/sidebar.awk b/doc/sidebar.awk
new file mode 100644
index 00000000..bb381aa3
--- /dev/null
+++ b/doc/sidebar.awk
@@ -0,0 +1,67 @@
+# sidebar.awk --- add support for sidebars, other stuff to gawk.texi
+
+# Copyright (C) 2013 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 3 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
+
+BEGIN {
+ print "% ****************************************************"
+ print "% * DO NOT MODIFY THIS FILE!!!! *"
+ print "% * It was generated from gawktexi.in by sidebar.awk *"
+ print "% * Edit gawktexi.in instead. *"
+ print "% ****************************************************"
+}
+
+/^@sidebar/ {
+ sub(/^@sidebar[[:space:]]+/, "", $0)
+ title = $0
+ body = ""
+ collecting = 1
+ next
+}
+
+/^@end[[:space:]]+sidebar[[:space:]]*$/ {
+ collecting = 0
+ printf "@cindex sidebar, %s\n", title
+ printf "@ifdocbook\n"
+ printf "@docbook\n"
+ printf "<sidebar><title>%s</title>\n", title
+ printf "@end docbook\n"
+ print body
+ print ""
+ printf "@docbook\n"
+ printf "</sidebar>\n"
+ printf "@end docbook\n"
+ printf "@end ifdocbook\n\n"
+
+ printf "@ifnotdocbook\n"
+ printf "@cartouche\n"
+ printf "@center @b{%s}\n\n", title
+ print body
+ printf "@end cartouche\n"
+ printf "@end ifnotdocbook\n"
+ body = ""
+ next
+}
+
+collecting == 1 {
+ body = body RS $0
+ next
+}
+
+{ print }
diff --git a/doc/texinfo.tex b/doc/texinfo.tex
index 1130b8fc..370d4505 100644
--- a/doc/texinfo.tex
+++ b/doc/texinfo.tex
@@ -3,11 +3,11 @@
% Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
%
-\def\texinfoversion{2010-12-23.17}
+\def\texinfoversion{2014-12-03.16}
%
% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-% 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+% 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 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
@@ -24,13 +24,14 @@
%
% 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.)
+% restriction. This Exception is an additional permission under section 7
+% of the GNU General Public License, version 3 ("GPLv3").
%
% 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).
+% http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or
+% http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or
+% http://www.gnu.org/software/texinfo/ (the Texinfo home page)
% The texinfo.tex in any given distribution could well be out
% of date, so if that's what you're using, please check.
%
@@ -95,7 +96,9 @@
\let\ptexraggedright=\raggedright
\let\ptexrbrace=\}
\let\ptexslash=\/
+\let\ptexsp=\sp
\let\ptexstar=\*
+\let\ptexsup=\sup
\let\ptext=\t
\let\ptextop=\top
{\catcode`\'=\active \global\let\ptexquoteright'}% active in plain's math mode
@@ -116,10 +119,11 @@
% 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\putworderror\undefined \gdef\putworderror{error}\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\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
@@ -158,15 +162,18 @@
\def\spaceisspace{\catcode`\ =\spacecat}
% sometimes characters are active, so we need control sequences.
+\chardef\ampChar = `\&
\chardef\colonChar = `\:
\chardef\commaChar = `\,
\chardef\dashChar = `\-
\chardef\dotChar = `\.
\chardef\exclamChar= `\!
+\chardef\hashChar = `\#
\chardef\lquoteChar= `\`
\chardef\questChar = `\?
\chardef\rquoteChar= `\'
\chardef\semiChar = `\;
+\chardef\slashChar = `\/
\chardef\underChar = `\_
% Ignore a token.
@@ -215,7 +222,7 @@
\tracingmacros2
\tracingrestores1
\showboxbreadth\maxdimen \showboxdepth\maxdimen
- \ifx\eTeXversion\undefined\else % etex gives us more logging
+ \ifx\eTeXversion\thisisundefined\else % etex gives us more logging
\tracingscantokens1
\tracingifs1
\tracinggroups1
@@ -226,6 +233,13 @@
\errorcontextlines16
}%
+% @errormsg{MSG}. Do the index-like expansions on MSG, but if things
+% aren't perfect, it's not the end of the world, being an error message,
+% after all.
+%
+\def\errormsg{\begingroup \indexnofonts \doerrormsg}
+\def\doerrormsg#1{\errmessage{#1}}
+
% 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.
%
@@ -269,9 +283,9 @@
\toks6=\expandafter{\prevsectiondefs}%
\toks8=\expandafter{\lastcolordefs}%
\mark{%
- \the\toks0 \the\toks2
- \noexpand\or \the\toks4 \the\toks6
- \noexpand\else \the\toks8
+ \the\toks0 \the\toks2 % 0: top marks (\last...)
+ \noexpand\or \the\toks4 \the\toks6 % 1: bottom marks (default, \prev...)
+ \noexpand\else \the\toks8 % 2: color marks
}%
}
% \topmark doesn't work for the very first chapter (after the title
@@ -310,10 +324,13 @@
%
% Do this outside of the \shipout so @code etc. will be expanded in
% the headline as they should be, not taken literally (outputting ''code).
+ \def\commmonheadfootline{\let\hsize=\pagewidth \texinfochars}
+ %
\ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi
- \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+ \global\setbox\headlinebox = \vbox{\commmonheadfootline \makeheadline}%
+ %
\ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi
- \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
+ \global\setbox\footlinebox = \vbox{\commmonheadfootline \makefootline}%
%
{%
% Have to do this stuff outside the \shipout because we want it to
@@ -545,7 +562,7 @@
}
\def\inenvironment#1{%
\ifx#1\empty
- out of any environment%
+ outside of any environment%
\else
in environment \expandafter\string#1%
\fi
@@ -557,7 +574,7 @@
\parseargdef\end{%
\if 1\csname iscond.#1\endcsname
\else
- % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03
+ % The general wording of \badenverr may not be ideal.
\expandafter\checkenv\csname#1\endcsname
\csname E#1\endcsname
\endgroup
@@ -583,7 +600,7 @@
\def\:{\spacefactor=1000 }
% @* forces a line break.
-\def\*{\hfil\break\hbox{}\ignorespaces}
+\def\*{\unskip\hfil\break\hbox{}\ignorespaces}
% @/ allows a line break.
\let\/=\allowbreak
@@ -608,7 +625,7 @@
\else\ifx\temp\offword \plainnonfrenchspacing
\else
\errhelp = \EMsimple
- \errmessage{Unknown @frenchspacing option `\temp', must be on/off}%
+ \errmessage{Unknown @frenchspacing option `\temp', must be on|off}%
\fi\fi
}
@@ -690,15 +707,6 @@ where each line of input produces a line of output.}
\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.
@@ -849,6 +857,7 @@ where each line of input produces a line of output.}
\makevalueexpandable % we want to expand any @value in FILE.
\turnoffactive % and allow special characters in the expansion
\indexnofonts % Allow `@@' and other weird things in file names.
+ \wlog{texinfo.tex: doing @include of #1^^J}%
\edef\temp{\noexpand\input #1 }%
%
% This trickery is to read FILE outside of a group, in case it makes
@@ -884,7 +893,7 @@ where each line of input produces a line of output.}
\def\popthisfilestack{\errthisfilestackempty}
\def\errthisfilestackempty{\errmessage{Internal error:
the stack of filenames is empty.}}
-
+%
\def\thisfile{}
% @center line
@@ -892,36 +901,46 @@ where each line of input produces a line of output.}
%
\parseargdef\center{%
\ifhmode
- \let\next\centerH
+ \let\centersub\centerH
\else
- \let\next\centerV
+ \let\centersub\centerV
\fi
- \next{\hfil \ignorespaces#1\unskip \hfil}%
+ \centersub{\hfil \ignorespaces#1\unskip \hfil}%
+ \let\centersub\relax % don't let the definition persist, just in case
}
-\def\centerH#1{%
- {%
- \hfil\break
- \advance\hsize by -\leftskip
- \advance\hsize by -\rightskip
- \line{#1}%
- \break
- }%
+\def\centerH#1{{%
+ \hfil\break
+ \advance\hsize by -\leftskip
+ \advance\hsize by -\rightskip
+ \line{#1}%
+ \break
+}}
+%
+\newcount\centerpenalty
+\def\centerV#1{%
+ % The idea here is the same as in \startdefun, \cartouche, etc.: if
+ % @center is the first thing after a section heading, we need to wipe
+ % out the negative parskip inserted by \sectionheading, but still
+ % prevent a page break here.
+ \centerpenalty = \lastpenalty
+ \ifnum\centerpenalty>10000 \vskip\parskip \fi
+ \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi
+ \line{\kern\leftskip #1\kern\rightskip}%
}
-\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
@@ -993,24 +1012,15 @@ where each line of input produces a line of output.}
% paragraph.
%
\gdef\dosuppressfirstparagraphindent{%
- \gdef\indent{%
- \restorefirstparagraphindent
- \indent
- }%
- \gdef\noindent{%
- \restorefirstparagraphindent
- \noindent
- }%
- \global\everypar = {%
- \kern -\parindent
- \restorefirstparagraphindent
- }%
+ \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 = {}%
+ \global\let\indent = \ptexindent
+ \global\let\noindent = \ptexnoindent
+ \global\everypar = {}%
}
@@ -1078,9 +1088,8 @@ where each line of input produces a line of output.}
\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
+% can be set). So we test for \relax and 0 as well as being undefined.
+\ifx\pdfoutput\thisisundefined
\else
\ifx\pdfoutput\relax
\else
@@ -1095,50 +1104,24 @@ where each line of input produces a line of output.}
% for display in the outlines, and in other places. Thus, we have to
% double any backslashes. Otherwise, a name like "\node" will be
% interpreted as a newline (\n), followed by o, d, e. Not good.
-% http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html
-% (and related messages, the final outcome is that it is up to the TeX
-% user to double the backslashes and otherwise make the string valid, so
-% that's what we do).
-
-% double active backslashes.
-%
-{\catcode`\@=0 \catcode`\\=\active
- @gdef@activebackslashdouble{%
- @catcode`@\=@active
- @let\=@doublebackslash}
-}
-
-% To handle parens, we must adopt a different approach, since parens are
-% not active characters. hyperref.dtx (which has the same problem as
-% us) handles it with this amazing macro to replace tokens, with minor
-% changes for Texinfo. It is included here under the GPL by permission
-% from the author, Heiko Oberdiek.
-%
-% #1 is the tokens to replace.
-% #2 is the replacement.
-% #3 is the control sequence with the string.
-%
-\def\HyPsdSubst#1#2#3{%
- \def\HyPsdReplace##1#1##2\END{%
- ##1%
- \ifx\\##2\\%
- \else
- #2%
- \HyReturnAfterFi{%
- \HyPsdReplace##2\END
- }%
- \fi
- }%
- \xdef#3{\expandafter\HyPsdReplace#3#1\END}%
-}
-\long\def\HyReturnAfterFi#1\fi{\fi#1}
-
-% #1 is a control sequence in which to do the replacements.
-\def\backslashparens#1{%
- \xdef#1{#1}% redefine it as its expansion; the definition is simply
- % \lastnode when called from \setref -> \pdfmkdest.
- \HyPsdSubst{(}{\realbackslash(}{#1}%
- \HyPsdSubst{)}{\realbackslash)}{#1}%
+%
+% See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and
+% related messages. The final outcome is that it is up to the TeX user
+% to double the backslashes and otherwise make the string valid, so
+% that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to
+% do this reliably, so we use it.
+
+% #1 is a control sequence in which to do the replacements,
+% which we \xdef.
+\def\txiescapepdf#1{%
+ \ifx\pdfescapestring\thisisundefined
+ % No primitive available; should we give a warning or log?
+ % Many times it won't matter.
+ \else
+ % The expandable \pdfescapestring primitive escapes parentheses,
+ % backslashes, and other special chars.
+ \xdef#1{\pdfescapestring{#1}}%
+ \fi
}
\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images
@@ -1148,10 +1131,12 @@ output) for that.)}
\ifpdf
%
- % Color manipulation macros based on pdfcolor.tex,
+ % Color manipulation macros using ideas from pdfcolor.tex,
% except using rgb instead of cmyk; the latter is said to render as a
% very dark gray on-screen and a very dark halftone in print, instead
- % of actual black.
+ % of actual black. The dark red here is dark enough to print on paper as
+ % nearly black, but still distinguishable for online viewing. We use
+ % black by default, though.
\def\rgbDarkRed{0.50 0.09 0.12}
\def\rgbBlack{0 0 0}
%
@@ -1197,32 +1182,34 @@ output) for that.)}
%
% #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto).
\def\dopdfimage#1#2#3{%
- \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
- \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
+ \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
+ \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
%
- % pdftex (and the PDF format) support .png, .jpg, .pdf (among
- % others). Let's try in that order.
+ % pdftex (and the PDF format) support .pdf, .png, .jpg (among
+ % others). Let's try in that order, PDF first since if
+ % someone has a scalable image, presumably better to use that than a
+ % bitmap.
\let\pdfimgext=\empty
\begingroup
- \openin 1 #1.png \ifeof 1
- \openin 1 #1.jpg \ifeof 1
- \openin 1 #1.jpeg \ifeof 1
- \openin 1 #1.JPG \ifeof 1
- \openin 1 #1.pdf \ifeof 1
- \openin 1 #1.PDF \ifeof 1
+ \openin 1 #1.pdf \ifeof 1
+ \openin 1 #1.PDF \ifeof 1
+ \openin 1 #1.png \ifeof 1
+ \openin 1 #1.jpg \ifeof 1
+ \openin 1 #1.jpeg \ifeof 1
+ \openin 1 #1.JPG \ifeof 1
\errhelp = \nopdfimagehelp
\errmessage{Could not find image file #1 for pdf}%
- \else \gdef\pdfimgext{PDF}%
+ \else \gdef\pdfimgext{JPG}%
\fi
- \else \gdef\pdfimgext{pdf}%
+ \else \gdef\pdfimgext{jpeg}%
\fi
- \else \gdef\pdfimgext{JPG}%
+ \else \gdef\pdfimgext{jpg}%
\fi
- \else \gdef\pdfimgext{jpeg}%
+ \else \gdef\pdfimgext{png}%
\fi
- \else \gdef\pdfimgext{jpg}%
+ \else \gdef\pdfimgext{PDF}%
\fi
- \else \gdef\pdfimgext{png}%
+ \else \gdef\pdfimgext{pdf}%
\fi
\closein 1
\endgroup
@@ -1234,8 +1221,8 @@ output) for that.)}
\else
\immediate\pdfximage
\fi
- \ifdim \wd0 >0pt width \imagewidth \fi
- \ifdim \wd2 >0pt height \imageheight \fi
+ \ifdim \wd0 >0pt width \pdfimagewidth \fi
+ \ifdim \wd2 >0pt height \pdfimageheight \fi
\ifnum\pdftexversion<13
#1.\pdfimgext
\else
@@ -1250,20 +1237,18 @@ output) for that.)}
% such as \, aren't expanded when present in a section title.
\indexnofonts
\turnoffactive
- \activebackslashdouble
\makevalueexpandable
\def\pdfdestname{#1}%
- \backslashparens\pdfdestname
+ \txiescapepdf\pdfdestname
\safewhatsit{\pdfdest name{\pdfdestname} xyz}%
}}
%
% used to mark target names; must be expandable.
\def\pdfmkpgn#1{#1}
%
- % by default, use a color that is dark enough to print on paper as
- % nearly black, but still distinguishable for online viewing.
- \def\urlcolor{\rgbDarkRed}
- \def\linkcolor{\rgbDarkRed}
+ % by default, use black for everything.
+ \def\urlcolor{\rgbBlack}
+ \def\linkcolor{\rgbBlack}
\def\endlink{\setcolor{\maincolor}\pdfendlink}
%
% Adding outlines to PDF; macros for calculating structure of outlines
@@ -1285,28 +1270,22 @@ output) for that.)}
% 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 worth the trouble, since most documents are normally structured.
- \def\pdfoutlinedest{#3}%
+ \edef\pdfoutlinedest{#3}%
\ifx\pdfoutlinedest\empty
\def\pdfoutlinedest{#4}%
\else
- % Doubled backslashes in the name.
- {\activebackslashdouble \xdef\pdfoutlinedest{#3}%
- \backslashparens\pdfoutlinedest}%
+ \txiescapepdf\pdfoutlinedest
\fi
%
- % Also double the backslashes in the display string.
- {\activebackslashdouble \xdef\pdfoutlinetext{#1}%
- \backslashparens\pdfoutlinetext}%
+ % Also escape PDF chars in the display string.
+ \edef\pdfoutlinetext{#1}%
+ \txiescapepdf\pdfoutlinetext
%
\pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}%
}
%
\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\partentry##1##2##3##4{}% ignore parts in the outlines
\def\numchapentry##1##2##3##4{%
@@ -1362,25 +1341,41 @@ output) for that.)}
% 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.
+ % TODO this right, we have to translate 8-bit characters to
+ % their "best" equivalent, based on the @documentencoding. Too
+ % much work for too little return. Just use the ASCII equivalents
+ % we use for the index sort strings.
+ %
\indexnofonts
\setupdatafile
+ % We can have normal brace characters in the PDF outlines, unlike
+ % Texinfo index files. So set that up.
+ \def\{{\lbracecharliteral}%
+ \def\}{\rbracecharliteral}%
\catcode`\\=\active \otherbackslash
\input \tocreadfilename
\endgroup
}
+ {\catcode`[=1 \catcode`]=2
+ \catcode`{=\other \catcode`}=\other
+ \gdef\lbracecharliteral[{]%
+ \gdef\rbracecharliteral[}]%
+ ]
%
\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
+ \addtokens{\filename}{\PP}%
+ \advance\filenamelength by 1
\fi
\nextsp}
- \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax}
+ \def\getfilename#1{%
+ \filenamelength=0
+ % If we don't expand the argument now, \skipspaces will get
+ % snagged on things like "@value{foo}".
+ \edef\temp{#1}%
+ \expandafter\skipspaces\temp|\relax
+ }
\ifnum\pdftexversion < 14
\let \startlink \pdfannotlink
\else
@@ -1477,9 +1472,6 @@ output) for that.)}
\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.
@@ -1491,6 +1483,7 @@ output) for that.)}
% can get a sort of poor man's double spacing by redefining this.
\def\baselinefactor{1}
%
+\newdimen\textleading
\def\setleading#1{%
\dimen0 = #1\relax
\normalbaselineskip = \baselinefactor\dimen0
@@ -1512,7 +1505,7 @@ output) for that.)}
% if we are producing pdf, and we have \pdffontattr, then define cmaps.
% (\pdffontattr was introduced many years ago, but people still run
% older pdftex's; it's easy to conditionalize, so we do.)
-\ifpdf \ifx\pdffontattr\undefined \else
+\ifpdf \ifx\pdffontattr\thisisundefined \else
\begingroup
\catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
\catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
@@ -1763,28 +1756,34 @@ end
\fi\fi
-% Set the font macro #1 to the font named #2, adding on the
-% specified font prefix (normally `cm').
+% Set the font macro #1 to the font named \fontprefix#2.
% #3 is the font's design size, #4 is a scale factor, #5 is the CMap
-% encoding (currently only OT1, OT1IT and OT1TT are allowed, pass
-% empty to omit).
+% encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit).
+% Example:
+% #1 = \textrm
+% #2 = \rmshape
+% #3 = 10
+% #4 = \mainmagstep
+% #5 = OT1
+%
\def\setfont#1#2#3#4#5{%
\font#1=\fontprefix#2#3 scaled #4
\csname cmap#5\endcsname#1%
}
% This is what gets called when #5 of \setfont is empty.
\let\cmap\gobble
-% emacs-page end of cmaps
+%
+% (end of cmaps)
% 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
+\ifx\fontprefix\thisisundefined
\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\rmbshape{bx} % where the normal face is bold
\def\bfshape{b}
\def\bxshape{bx}
\def\ttshape{tt}
@@ -1799,8 +1798,7 @@ end
\def\scshape{csc}
\def\scbshape{csc}
-% Definitions for a main text size of 11pt. This is the default in
-% Texinfo.
+% Definitions for a main text size of 11pt. (The default in Texinfo.)
%
\def\definetextfontsizexi{%
% Text fonts (11.2pt, magstep1).
@@ -1925,7 +1923,7 @@ end
\textleading = 13.2pt % line spacing for 11pt CM
\textfonts % reset the current fonts
\rm
-} % end of 11pt text font size definitions
+} % end of 11pt text font size definitions, \definetextfontsizexi
% Definitions to make the main text be 10pt Computer Modern, with
@@ -2057,7 +2055,7 @@ end
\textleading = 12pt % line spacing for 10pt CM
\textfonts % reset the current fonts
\rm
-} % end of 10pt text font size definitions
+} % end of 10pt text font size definitions, \definetextfontsizex
% We provide the user-level command
@@ -2070,7 +2068,7 @@ end
%
\parseargdef\fonttextsize{%
\def\textsizearg{#1}%
- \wlog{doing @fonttextsize \textsizearg}%
+ %\wlog{doing @fonttextsize \textsizearg}%
%
% Set \globaldefs so that documents can use this inside @tex, since
% makeinfo 4.8 does not support it, but we need it nonetheless.
@@ -2085,12 +2083,9 @@ end
\endgroup
}
-
% 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).
+% we have to define the \textfont of the standard families. We don't
+% bother to reset \scriptfont and \scriptscriptfont; awaiting user need.
%
\def\resetmathfonts{%
\textfont0=\tenrm \textfont1=\teni \textfont2=\tensy
@@ -2104,8 +2099,8 @@ end
% \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.
+% and \lllsize (three sizes lower). These relative commands are used
+% in, e.g., the LaTeX logo and acronyms.
%
% This all needs generalizing, badly.
%
@@ -2141,7 +2136,7 @@ end
\let\tenttsl=\secttsl
\def\curfontsize{sec}%
\def\lsize{subsec}\def\lllsize{reduced}%
- \resetmathfonts \setleading{16pt}}
+ \resetmathfonts \setleading{17pt}}
\def\subsecfonts{%
\let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
\let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
@@ -2252,12 +2247,14 @@ end
% Markup style setup for left and right quotes.
\defmarkupstylesetup\markupsetuplq{%
- \expandafter\let\expandafter \temp \csname markupsetuplq\currentmarkupstyle\endcsname
+ \expandafter\let\expandafter \temp
+ \csname markupsetuplq\currentmarkupstyle\endcsname
\ifx\temp\relax \markupsetuplqdefault \else \temp \fi
}
\defmarkupstylesetup\markupsetuprq{%
- \expandafter\let\expandafter \temp \csname markupsetuprq\currentmarkupstyle\endcsname
+ \expandafter\let\expandafter \temp
+ \csname markupsetuprq\currentmarkupstyle\endcsname
\ifx\temp\relax \markupsetuprqdefault \else \temp \fi
}
@@ -2270,8 +2267,6 @@ end
\gdef\markupsetcodequoteleft{\let`\codequoteleft}
\gdef\markupsetcodequoteright{\let'\codequoteright}
-
-\gdef\markupsetnoligaturesquoteleft{\let`\noligaturesquoteleft}
}
\let\markupsetuplqcode \markupsetcodequoteleft
@@ -2280,6 +2275,9 @@ end
\let\markupsetuplqexample \markupsetcodequoteleft
\let\markupsetuprqexample \markupsetcodequoteright
%
+\let\markupsetuplqkbd \markupsetcodequoteleft
+\let\markupsetuprqkbd \markupsetcodequoteright
+%
\let\markupsetuplqsamp \markupsetcodequoteleft
\let\markupsetuprqsamp \markupsetcodequoteright
%
@@ -2289,14 +2287,11 @@ end
\let\markupsetuplqverbatim \markupsetcodequoteleft
\let\markupsetuprqverbatim \markupsetcodequoteright
-\let\markupsetuplqkbd \markupsetnoligaturesquoteleft
-
-% Allow an option to not replace quotes with a regular directed right
-% quote/apostrophe (char 0x27), but instead use the undirected quote
-% from cmtt (char 0x0d). The undirected quote is ugly, so don't make it
-% the default, but it works for pasting with more pdf viewers (at least
-% evince), the lilypond developers report. xpdf does work with the
-% regular 0x27.
+% Allow an option to not use regular directed right quote/apostrophe
+% (char 0x27), but instead the undirected quote from cmtt (char 0x0d).
+% The undirected quote is ugly, so don't make it the default, but it
+% works for pasting with more pdf viewers (at least evince), the
+% lilypond developers report. xpdf does work with the regular 0x27.
%
\def\codequoteright{%
\expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax
@@ -2320,6 +2315,36 @@ end
\else \char'22 \fi
}
+% Commands to set the quote options.
+%
+\parseargdef\codequoteundirected{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxicodequoteundirected\endcsname
+ = t%
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxicodequoteundirected\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @codequoteundirected value `\temp', must be on|off}%
+ \fi\fi
+}
+%
+\parseargdef\codequotebacktick{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxicodequotebacktick\endcsname
+ = t%
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxicodequotebacktick\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @codequotebacktick value `\temp', must be on|off}%
+ \fi\fi
+}
+
% [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font.
\def\noligaturesquoteleft{\relax\lq}
@@ -2346,20 +2371,29 @@ end
\ifx\next,%
\else\ifx\next-%
\else\ifx\next.%
+ \else\ifx\next\.%
+ \else\ifx\next\comma%
\else\ptexslash
- \fi\fi\fi}
+ \fi\fi\fi\fi\fi
+ \aftersmartic
+}
-% like \smartslanted except unconditionally uses \ttsl, and no ic.
-% @var is set to this for defun arguments.
+% Unconditional use \ttsl, and no ic. @var is set to this for defuns.
\def\ttslanted#1{{\ttsl #1}}
% @cite is like \smartslanted except unconditionally use \sl. We never want
% ttsl for book titles, do we?
\def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection}
+\def\aftersmartic{}
+\def\var#1{%
+ \let\saveaftersmartic = \aftersmartic
+ \def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}%
+ \smartslanted{#1}%
+}
+
\let\i=\smartitalic
\let\slanted=\smartslanted
-\def\var#1{\smartslanted{#1}}
\let\dfn=\smartslanted
\let\emph=\smartitalic
@@ -2409,34 +2443,12 @@ end
% @samp.
\def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}}
-% definition of @key that produces a lozenge. Doesn't adjust to text size.
-%\setfont\keyrm\rmshape{8}{1000}{OT1}
-%\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}}}}
-
-% definition of @key with no lozenge. If the current font is already
-% monospace, don't change it; that way, we respect @kbdinputstyle. But
-% if it isn't monospace, then use \tt.
-%
-\def\key#1{{\setupmarkupstyle{key}%
- \nohyphenation
- \ifmonospace\else\tt\fi
- #1}\null}
+% @indicateurl is \samp, that is, with quotes.
+\let\indicateurl=\samp
-% ctrl is no longer a Texinfo command.
-\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.
+% @code (and similar) prints in typewriter, but with spaces the same
+% size as normal in the surrounding text, without hyphenation, etc.
+% This is a subroutine for that.
\def\tclose#1{%
{%
% Change normal interword space to be same as for the current font.
@@ -2455,18 +2467,18 @@ end
\plainfrenchspacing
#1%
}%
- \null
+ \null % reset spacefactor to 1000
}
% We *must* turn on hyphenation at `-' and `_' in @code.
+% (But see \codedashfinish below.)
% 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.
+% and arrange explicitly to hyphenate at a dash. -- rms.
{
\catcode`\-=\active \catcode`\_=\active
\catcode`\'=\active \catcode`\`=\active
@@ -2480,15 +2492,38 @@ end
\let-\codedash
\let_\codeunder
\else
- \let-\realdash
+ \let-\normaldash
\let_\realunder
\fi
+ % Given -foo (with a single dash), we do not want to allow a break
+ % after the hyphen.
+ \global\let\codedashprev=\codedash
+ %
\codex
}
+ %
+ \gdef\codedash{\futurelet\next\codedashfinish}
+ \gdef\codedashfinish{%
+ \normaldash % always output the dash character itself.
+ %
+ % Now, output a discretionary to allow a line break, unless
+ % (a) the next character is a -, or
+ % (b) the preceding character is a -.
+ % E.g., given --posix, we do not want to allow a break after either -.
+ % Given --foo-bar, we do want to allow a break between the - and the b.
+ \ifx\next\codedash \else
+ \ifx\codedashprev\codedash
+ \else \discretionary{}{}{}\fi
+ \fi
+ % we need the space after the = for the case when \next itself is a
+ % space token; it would get swallowed otherwise. As in @code{- a}.
+ \global\let\codedashprev= \next
+ }
}
+\def\normaldash{-}
+%
+\def\codex #1{\tclose{#1}\endgroup}
-\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.)
@@ -2500,12 +2535,11 @@ end
\discretionary{}{}{}}%
{\_}%
}
-\def\codex #1{\tclose{#1}\endgroup}
% An additional complication: the above will allow breaks after, e.g.,
-% each of the four underscores in __typeof__. This is undesirable in
-% some manuals, especially if they don't have long identifiers in
-% general. @allowcodebreaks provides a way to control this.
+% each of the four underscores in __typeof__. This is bad.
+% @allowcodebreaks provides a document-level way to turn breaking at -
+% and _ on and off.
%
\newif\ifallowcodebreaks \allowcodebreakstrue
@@ -2520,83 +2554,135 @@ end
\allowcodebreaksfalse
\else
\errhelp = \EMsimple
- \errmessage{Unknown @allowcodebreaks option `\txiarg'}%
+ \errmessage{Unknown @allowcodebreaks option `\txiarg', must be true|false}%
\fi\fi
}
-% @kbd is like @code, except that if the argument is just one @key command,
-% then @kbd has no effect.
-\def\kbd#1{{\setupmarkupstyle{kbd}\def\look{#1}\expandafter\kbdfoo\look??\par}}
-
-% @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\txiarg{#1}%
- \ifx\txiarg\worddistinct
- \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
- \else\ifx\txiarg\wordexample
- \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
- \else\ifx\txiarg\wordcode
- \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
- \else
- \errhelp = \EMsimple
- \errmessage{Unknown @kbdinputstyle option `\txiarg'}%
- \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\setupmarkupstyle{kbd}\look}}\fi
-\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi}
-
-% For @indicateurl, @env, @command quotes seem unnecessary, so use \code.
-\let\indicateurl=\code
-\let\env=\code
+% For @command, @env, @file, @option quotes seem unnecessary,
+% so use \code rather than \samp.
\let\command=\code
-
-% @clicksequence{File @click{} Open ...}
-\def\clicksequence#1{\begingroup #1\endgroup}
-
-% @clickstyle @arrow (by default)
-\parseargdef\clickstyle{\def\click{#1}}
-\def\click{\arrow}
-
-% @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
+\let\env=\code
+\let\file=\code
+\let\option=\code
+
+% @uref (abbreviation for `urlref') aka @url 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.
+
+% TeX-only option to allow changing PDF output to show only the second
+% arg (if given), and not the url (which is then just the link target).
+\newif\ifurefurlonlylink
+
+% The main macro is \urefbreak, which allows breaking at expected
+% places within the url. (There used to be another version, which
+% didn't support automatic breaking.)
+\def\urefbreak{\begingroup \urefcatcodes \dourefbreak}
+\let\uref=\urefbreak
+%
+\def\dourefbreak#1{\urefbreakfinish #1,,,\finish}
+\def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example
\unsepspaces
\pdfurl{#1}%
\setbox0 = \hbox{\ignorespaces #3}%
\ifdim\wd0 > 0pt
\unhbox0 % third arg given, show only that
\else
- \setbox0 = \hbox{\ignorespaces #2}%
+ \setbox0 = \hbox{\ignorespaces #2}% look for second arg
\ifdim\wd0 > 0pt
\ifpdf
- \unhbox0 % PDF: 2nd arg given, show only it
+ \ifurefurlonlylink
+ % PDF plus option to not display url, show just arg
+ \unhbox0
+ \else
+ % PDF, normally display both arg and url for consistency,
+ % visibility, if the pdf is eventually used to print, etc.
+ \unhbox0\ (\urefcode{#1})%
+ \fi
\else
- \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url
+ \unhbox0\ (\urefcode{#1})% DVI, always show arg and url
\fi
\else
- \code{#1}% only url given, so show it
+ \urefcode{#1}% only url given, so show it
\fi
\fi
\endlink
\endgroup}
+% Allow line breaks around only a few characters (only).
+\def\urefcatcodes{%
+ \catcode\ampChar=\active \catcode\dotChar=\active
+ \catcode\hashChar=\active \catcode\questChar=\active
+ \catcode\slashChar=\active
+}
+{
+ \urefcatcodes
+ %
+ \global\def\urefcode{\begingroup
+ \setupmarkupstyle{code}%
+ \urefcatcodes
+ \let&\urefcodeamp
+ \let.\urefcodedot
+ \let#\urefcodehash
+ \let?\urefcodequest
+ \let/\urefcodeslash
+ \codex
+ }
+ %
+ % By default, they are just regular characters.
+ \global\def&{\normalamp}
+ \global\def.{\normaldot}
+ \global\def#{\normalhash}
+ \global\def?{\normalquest}
+ \global\def/{\normalslash}
+}
+
+% we put a little stretch before and after the breakable chars, to help
+% line breaking of long url's. The unequal skips make look better in
+% cmtt at least, especially for dots.
+\def\urefprestretchamount{.13em}
+\def\urefpoststretchamount{.1em}
+\def\urefprestretch{\urefprebreak \hskip0pt plus\urefprestretchamount\relax}
+\def\urefpoststretch{\urefpostbreak \hskip0pt plus\urefprestretchamount\relax}
+%
+\def\urefcodeamp{\urefprestretch \&\urefpoststretch}
+\def\urefcodedot{\urefprestretch .\urefpoststretch}
+\def\urefcodehash{\urefprestretch \#\urefpoststretch}
+\def\urefcodequest{\urefprestretch ?\urefpoststretch}
+\def\urefcodeslash{\futurelet\next\urefcodeslashfinish}
+{
+ \catcode`\/=\active
+ \global\def\urefcodeslashfinish{%
+ \urefprestretch \slashChar
+ % Allow line break only after the final / in a sequence of
+ % slashes, to avoid line break between the slashes in http://.
+ \ifx\next/\else \urefpoststretch \fi
+ }
+}
+
+% One more complication: by default we'll break after the special
+% characters, but some people like to break before the special chars, so
+% allow that. Also allow no breaking at all, for manual control.
+%
+\parseargdef\urefbreakstyle{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\wordnone
+ \def\urefprebreak{\nobreak}\def\urefpostbreak{\nobreak}
+ \else\ifx\txiarg\wordbefore
+ \def\urefprebreak{\allowbreak}\def\urefpostbreak{\nobreak}
+ \else\ifx\txiarg\wordafter
+ \def\urefprebreak{\nobreak}\def\urefpostbreak{\allowbreak}
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @urefbreakstyle setting `\txiarg'}%
+ \fi\fi\fi
+}
+\def\wordafter{after}
+\def\wordbefore{before}
+\def\wordnone{none}
+
+\urefbreakstyle after
+
% @url synonym for @uref, since that's how everyone uses it.
%
\let\url=\uref
@@ -2618,6 +2704,67 @@ end
\let\email=\uref
\fi
+% @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\txiarg{#1}%
+ \ifx\txiarg\worddistinct
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+ \else\ifx\txiarg\wordexample
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+ \else\ifx\txiarg\wordcode
+ \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @kbdinputstyle setting `\txiarg'}%
+ \fi\fi\fi
+}
+\def\worddistinct{distinct}
+\def\wordexample{example}
+\def\wordcode{code}
+
+% Default is `distinct'.
+\kbdinputstyle distinct
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+\def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}}
+
+\def\xkey{\key}
+\def\kbdsub#1#2#3\par{%
+ \def\one{#1}\def\three{#3}\def\threex{??}%
+ \ifx\one\xkey\ifx\threex\three \key{#2}%
+ \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
+ \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
+}
+
+% definition of @key that produces a lozenge. Doesn't adjust to text size.
+%\setfont\keyrm\rmshape{8}{1000}{OT1}
+%\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}}}}
+
+% definition of @key with no lozenge. If the current font is already
+% monospace, don't change it; that way, we respect @kbdinputstyle. But
+% if it isn't monospace, then use \tt.
+%
+\def\key#1{{\setupmarkupstyle{key}%
+ \nohyphenation
+ \ifmonospace\else\tt\fi
+ #1}\null}
+
+% @clicksequence{File @click{} Open ...}
+\def\clicksequence#1{\begingroup #1\endgroup}
+
+% @clickstyle @arrow (by default)
+\parseargdef\clickstyle{\def\click{#1}}
+\def\click{\arrow}
+
% 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.
%
@@ -2639,6 +2786,7 @@ end
\ifx\temp\empty \else
\space ({\unsepspaces \ignorespaces \temp \unskip})%
\fi
+ \null % reset \spacefactor=1000
}
% @abbr for "Comput. J." and the like.
@@ -2651,6 +2799,7 @@ end
\ifx\temp\empty \else
\space ({\unsepspaces \ignorespaces \temp \unskip})%
\fi
+ \null % reset \spacefactor=1000
}
% @asis just yields its argument. Used with @table, for example.
@@ -2692,6 +2841,8 @@ end
\let\v=\check
\let\~=\tilde
\let\dotaccent=\dot
+ % have to provide another name for sup operator
+ \let\mathopsup=\sup
$\finishmath
}
\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex.
@@ -2715,20 +2866,89 @@ end
}
}
+% for @sub and @sup, if in math mode, just do a normal sub/superscript.
+% If in text, use math to place as sub/superscript, but switch
+% into text mode, with smaller fonts. This is a different font than the
+% one used for real math sub/superscripts (8pt vs. 7pt), but let's not
+% fix it (significant additions to font machinery) until someone notices.
+%
+\def\sub{\ifmmode \expandafter\sb \else \expandafter\finishsub\fi}
+\def\finishsub#1{$\sb{\hbox{\selectfonts\lllsize #1}}$}%
+%
+\def\sup{\ifmmode \expandafter\ptexsp \else \expandafter\finishsup\fi}
+\def\finishsup#1{$\ptexsp{\hbox{\selectfonts\lllsize #1}}$}%
+
+% ctrl is no longer a Texinfo command, but leave this definition for fun.
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+% @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}.
+% Ignore unless FMTNAME == tex; then it is like @iftex and @tex,
+% except specified as a normal braced arg, so no newlines to worry about.
+%
+\def\outfmtnametex{tex}
+%
+\long\def\inlinefmt#1{\doinlinefmt #1,\finish}
+\long\def\doinlinefmt#1,#2,\finish{%
+ \def\inlinefmtname{#1}%
+ \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi
+}
+%
+% @inlinefmtifelse{FMTNAME,THEN-TEXT,ELSE-TEXT} expands THEN-TEXT if
+% FMTNAME is tex, else ELSE-TEXT.
+\long\def\inlinefmtifelse#1{\doinlinefmtifelse #1,,,\finish}
+\long\def\doinlinefmtifelse#1,#2,#3,#4,\finish{%
+ \def\inlinefmtname{#1}%
+ \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\else \ignorespaces #3\fi
+}
+%
+% For raw, must switch into @tex before parsing the argument, to avoid
+% setting catcodes prematurely. Doing it this way means that, for
+% example, @inlineraw{html, foo{bar} gets a parse error instead of being
+% ignored. But this isn't important because if people want a literal
+% *right* brace they would have to use a command anyway, so they may as
+% well use a command to get a left brace too. We could re-use the
+% delimiter character idea from \verb, but it seems like overkill.
+%
+\long\def\inlineraw{\tex \doinlineraw}
+\long\def\doinlineraw#1{\doinlinerawtwo #1,\finish}
+\def\doinlinerawtwo#1,#2,\finish{%
+ \def\inlinerawname{#1}%
+ \ifx\inlinerawname\outfmtnametex \ignorespaces #2\fi
+ \endgroup % close group opened by \tex.
+}
+
+% @inlineifset{VAR, TEXT} expands TEXT if VAR is @set.
+%
+\long\def\inlineifset#1{\doinlineifset #1,\finish}
+\long\def\doinlineifset#1,#2,\finish{%
+ \def\inlinevarname{#1}%
+ \expandafter\ifx\csname SET\inlinevarname\endcsname\relax
+ \else\ignorespaces#2\fi
+}
+
+% @inlineifclear{VAR, TEXT} expands TEXT if VAR is not @set.
+%
+\long\def\inlineifclear#1{\doinlineifclear #1,\finish}
+\long\def\doinlineifclear#1,#2,\finish{%
+ \def\inlinevarname{#1}%
+ \expandafter\ifx\csname SET\inlinevarname\endcsname\relax \ignorespaces#2\fi
+}
+
\message{glyphs,}
% and logos.
-% @@ prints an @.
+% @@ prints an @, as does @atchar{}.
\def\@{\char64 }
+\let\atchar=\@
-% Used to generate quoted braces. Unless we're in typewriter, use
-% \ecfont because the CM text fonts do not have braces, and we don't
-% want to switch into math.
+% @{ @} @lbracechar{} @rbracechar{} all generate brace characters.
+% Unless we're in typewriter, use \ecfont because the CM text fonts do
+% not have braces, and we don't want to switch into math.
\def\mylbrace{{\ifmonospace\else\ecfont\fi \char123}}
\def\myrbrace{{\ifmonospace\else\ecfont\fi \char125}}
-\let\{=\mylbrace
-\let\}=\myrbrace
+\let\{=\mylbrace \let\lbracechar=\{
+\let\}=\myrbrace \let\rbracechar=\}
\begingroup
% Definitions to produce \{ and \} commands for indices,
% and @{ and @} for the aux/toc files.
@@ -2856,7 +3076,7 @@ end
{\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 \reducedsf error\kern-1.5pt}
+\setbox0 = \hbox{\kern-.75pt \reducedsf \putworderror\kern-1.5pt}
%
\setbox\errorbox=\hbox to \dimen0{\hfil
\hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
@@ -2977,12 +3197,17 @@ end
% hopefully nobody will notice/care.
\edef\ecsize{\csname\curfontsize ecsize\endcsname}%
\edef\nominalsize{\csname\curfontsize nominalsize\endcsname}%
- \ifx\curfontstyle\bfstylename
- % bold:
- \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
+ \ifmonospace
+ % typewriter:
+ \font\thisecfont = ectt\ecsize \space at \nominalsize
\else
- % regular:
- \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
+ \ifx\curfontstyle\bfstylename
+ % bold:
+ \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
+ \else
+ % regular:
+ \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
+ \fi
\fi
\thisecfont
}
@@ -3005,7 +3230,7 @@ end
% 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
+\ifx\Orb\thisisundefined
\def\Orb{\mathhexbox20D}
\fi
@@ -3033,8 +3258,9 @@ end
\newif\ifsetshortcontentsaftertitlepage
\let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
-\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
- \endgroup\page\hbox{}\page}
+\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.
@@ -3094,14 +3320,28 @@ end
\finishedtitlepagetrue
}
-%%% Macros to be used within @titlepage:
+% Settings used for typesetting titles: no hyphenation, no indentation,
+% don't worry much about spacing, ragged right. This should be used
+% inside a \vbox, and fonts need to be set appropriately first. Because
+% it is always used for titles, nothing else, we call \rmisbold. \par
+% should be specified before the end of the \vbox, since a vbox is a group.
+%
+\def\raggedtitlesettings{%
+ \rmisbold
+ \hyphenpenalty=10000
+ \parindent=0pt
+ \tolerance=5000
+ \ptexraggedright
+}
+
+% Macros to be used within @titlepage:
\let\subtitlerm=\tenrm
\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
\parseargdef\title{%
\checkenv\titlepage
- \leftline{\titlefonts\rmisbold #1}
+ \vbox{\titlefonts \raggedtitlesettings #1\par}%
% print a rule at the page bottom also.
\finishedtitlepagefalse
\vskip4pt \hrule height 4pt width \hsize \vskip4pt
@@ -3127,7 +3367,7 @@ end
}
-%%% Set up page headings and footings.
+% Set up page headings and footings.
\let\thispage=\folio
@@ -3279,7 +3519,7 @@ end
% 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
+\ifx\today\thisisundefined
\def\today{%
\number\day\space
\ifcase\month
@@ -3449,7 +3689,7 @@ end
\parskip=\smallskipamount
\ifdim\parskip=0pt \parskip=2pt \fi
%
- % Try typesetting the item mark that if the document erroneously says
+ % Try typesetting the item mark so that if the document erroneously says
% something like @itemize @samp (intending @table), there's an error
% right away at the @itemize. It's not the best error message in the
% world, but it's better than leaving it to the @item. This means if
@@ -3699,19 +3939,23 @@ end
}
% 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. \everycr resets \everytab so we don't have to
+%
+% @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. \everycr below resets \everytab so we don't have to
% undo it ourselves.
\def\headitemfont{\b}% for people to use in the template row; not changeable
\def\headitem{%
\checkenv\multitable
\crcr
+ \gdef\headitemcrhook{\nobreak}% attempt to avoid page break after headings
\global\everytab={\bf}% can't use \headitemfont since the parsing differs
\the\everytab % for the first item
}%
%
+% default for tables with no headings.
+\let\headitemcrhook=\relax
+%
% 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 again encounter the problem the 1sp was intended to solve.
@@ -3742,15 +3986,15 @@ end
%
\everycr = {%
\noalign{%
- \global\everytab={}%
+ \global\everytab={}% Reset from possible headitem.
\global\colcount=0 % Reset the column counter.
- % Check for saved footnotes, etc.
+ %
+ % 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.
+ %
+ % Perhaps a \nobreak, then reset:
+ \headitemcrhook
+ \global\let\headitemcrhook=\relax
}%
}%
%
@@ -3826,18 +4070,18 @@ end
\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.
+% 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.
+\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.
+\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller
+ % than skip between lines in the table.
\fi}
@@ -3989,7 +4233,7 @@ end
\def\value{\begingroup\makevalueexpandable\valuexxx}
\def\valuexxx#1{\expandablevalue{#1}\endgroup}
{
- \catcode`\- = \active \catcode`\_ = \active
+ \catcode`\-=\active \catcode`\_=\active
%
\gdef\makevalueexpandable{%
\let\value = \expandablevalue
@@ -3998,7 +4242,7 @@ end
% ..., 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
+ \let-\normaldash \let_\normalunderscore
}
}
@@ -4009,7 +4253,12 @@ end
% 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).
-%
+%
+% Unfortunately, this has the consequence that when _ is in the *value*
+% of an @set, it does not print properly in the roman fonts (get the cmr
+% dot accent at position 126 instead). No fix comes to mind, and it's
+% been this way since 2003 or earlier, so just ignore it.
+%
\def\expandablevalue#1{%
\expandafter\ifx\csname SET#1\endcsname\relax
{[No value for ``#1'']}%
@@ -4021,8 +4270,9 @@ end
% @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.
+%
+% To get the special treatment we need for `@end ifset,' we call
+% \makecond and then redefine.
%
\makecond{ifset}
\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
@@ -4038,7 +4288,7 @@ end
}
\def\ifsetfail{\doignore{ifset}}
-% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% @ifclear VAR ... @end executes 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
@@ -4049,6 +4299,35 @@ end
\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
\def\ifclearfail{\doignore{ifclear}}
+% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written
+% without the @) is in fact defined. We can only feasibly check at the
+% TeX level, so something like `mathcode' is going to considered
+% defined even though it is not a Texinfo command.
+%
+\makecond{ifcommanddefined}
+\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}}
+%
+\def\doifcmddefined#1#2{{%
+ \makevalueexpandable
+ \let\next=\empty
+ \expandafter\ifx\csname #2\endcsname\relax
+ #1% If not defined, \let\next as above.
+ \fi
+ \expandafter
+ }\next
+}
+\def\ifcmddefinedfail{\doignore{ifcommanddefined}}
+
+% @ifcommandnotdefined CMD ... handled similar to @ifclear above.
+\makecond{ifcommandnotdefined}
+\def\ifcommandnotdefined{%
+ \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}}
+\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}}
+
+% Set the `txicommandconditionals' variable, so documents have a way to
+% test if the @ifcommand...defined conditionals are available.
+\set txicommandconditionals
+
% @dircategory CATEGORY -- specify a category of the dir file
% which this file should belong to. Ignore this in TeX.
\let\dircategory=\comment
@@ -4157,7 +4436,7 @@ end
% complicated, when \tex is in effect and \{ is a \delimiter again.
% We can't use \lbracecmd and \rbracecmd because texindex assumes
% braces and backslashes are used only as delimiters. Perhaps we
- % should define @lbrace and @rbrace commands a la @comma.
+ % should use @lbracechar and @rbracechar?
\def\{{{\tt\char123}}%
\def\}{{\tt\char125}}%
%
@@ -4178,8 +4457,7 @@ end
% @end macro
% ...
% @funindex commtest
- %
- % The above is not enough to reproduce the bug, but it gives the flavor.
+ % This is not enough to reproduce the bug, but it gives the flavor.
%
% Sample whatsit resulting:
% .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}}
@@ -4285,6 +4563,7 @@ end
\definedummyword\guillemetright
\definedummyword\guilsinglleft
\definedummyword\guilsinglright
+ \definedummyword\lbracechar
\definedummyword\leq
\definedummyword\minus
\definedummyword\ogonek
@@ -4297,6 +4576,7 @@ end
\definedummyword\quoteleft
\definedummyword\quoteright
\definedummyword\quotesinglbase
+ \definedummyword\rbracechar
\definedummyword\result
\definedummyword\textdegree
%
@@ -4348,7 +4628,9 @@ end
\definedummyword\t
%
% Commands that take arguments.
+ \definedummyword\abbr
\definedummyword\acronym
+ \definedummyword\anchor
\definedummyword\cite
\definedummyword\code
\definedummyword\command
@@ -4358,7 +4640,9 @@ end
\definedummyword\emph
\definedummyword\env
\definedummyword\file
+ \definedummyword\image
\definedummyword\indicateurl
+ \definedummyword\inforef
\definedummyword\kbd
\definedummyword\key
\definedummyword\math
@@ -4374,8 +4658,21 @@ end
\definedummyword\verb
\definedummyword\w
\definedummyword\xref
+ %
+ % Consider:
+ % @macro mkind{arg1,arg2}
+ % @cindex \arg2\
+ % @end macro
+ % @mkind{foo, bar}
+ % The space after the comma will end up in the temporary definition
+ % that we make for arg2 (see \parsemargdef ff.). We want all this to be
+ % expanded for the sake of the index, so we end up just seeing "bar".
+ \let\xeatspaces = \eatspaces
}
+% For testing: output @{ and @} in index sort strings as \{ and \}.
+\newif\ifusebracesinindexes
+
% \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
@@ -4404,8 +4701,16 @@ end
% Unfortunately, texindex is not prepared to handle braces in the
% content at all. So for index sorting, we map @{ and @} to strings
% starting with |, since that ASCII character is between ASCII { and }.
- \def\{{|a}%
- \def\}{|b}%
+ \ifusebracesinindexes
+ \def\lbracechar{\lbracecmd}%
+ \def\rbracechar{\rbracecmd}%
+ \else
+ \def\lbracechar{|a}%
+ \def\rbracechar{|b}%
+ \fi
+ \let\{=\lbracechar
+ \let\}=\rbracechar
+ %
%
% Non-English letters.
\def\AA{AA}%
@@ -4581,10 +4886,9 @@ end
%
% ..., ready, GO:
%
-\def\safewhatsit#1{%
-\ifhmode
+\def\safewhatsit#1{\ifhmode
#1%
-\else
+ \else
% \lastskip and \lastpenalty cannot both be nonzero simultaneously.
\whatsitskip = \lastskip
\edef\lastskipmacro{\the\lastskip}%
@@ -4608,7 +4912,6 @@ end
% 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.
@@ -4621,8 +4924,7 @@ end
% (the whatsit from the \write), so we must insert a \nobreak.
\nobreak\vskip\whatsitskip
\fi
-\fi
-}
+\fi}
% The index entry written in the file actually looks like
% \entry {sortstring}{page}{topic}
@@ -5242,7 +5544,8 @@ end
\global\let\subsubsection = \appendixsubsubsec
}
-\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+% normally unnmhead0 calls unnumberedzzz:
+\outer\parseargdef\unnumbered{\unnmhead0{#1}}
\def\unnumberedzzz#1{%
\global\secno=0 \global\subsecno=0 \global\subsubsecno=0
\global\advance\unnumberedno by 1
@@ -5286,40 +5589,47 @@ end
\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
+% normally calls appendixsectionzzz:
+\outer\parseargdef\appendixsection{\apphead1{#1}}
\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
+% normally calls unnumberedseczzz:
+\outer\parseargdef\unnumberedsec{\unnmhead1{#1}}
\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
+%
+% normally calls numberedsubseczzz:
+\outer\parseargdef\numberedsubsec{\numhead2{#1}}
\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
+% normally calls appendixsubseczzz:
+\outer\parseargdef\appendixsubsec{\apphead2{#1}}
\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
+% normally calls unnumberedsubseczzz:
+\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}}
\def\unnumberedsubseczzz#1{%
\global\subsubsecno=0 \global\advance\subsecno by 1
\sectionheading{#1}{subsec}{Ynothing}%
@@ -5327,21 +5637,25 @@ end
}
% Subsubsections.
-\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz
+%
+% normally numberedsubsubseczzz:
+\outer\parseargdef\numberedsubsubsec{\numhead3{#1}}
\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
+% normally appendixsubsubseczzz:
+\outer\parseargdef\appendixsubsubsec{\apphead3{#1}}
\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
+% normally unnumberedsubsubseczzz:
+\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}}
\def\unnumberedsubsubseczzz#1{%
\global\advance\subsubsecno by 1
\sectionheading{#1}{subsubsec}{Ynothing}%
@@ -5357,14 +5671,6 @@ end
% 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
@@ -5372,10 +5678,8 @@ end
\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
\def\chapheadingzzz#1{%
- {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
- \parindent=0pt\ptexraggedright
- \rmisbold #1\hfill}}%
- \bigskip \par\penalty 200\relax
+ \vbox{\chapfonts \raggedtitlesettings #1\par}%
+ \nobreak\bigskip \nobreak
\suppressfirstparagraphindent
}
@@ -5391,14 +5695,13 @@ end
% (including whitespace, linebreaking, etc. around it),
% given all the information in convenient, parsed form.
-%%% Args are the skip and penalty (usually negative)
+% 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
+% Define plain chapter starts, and page on/off switching for it.
\def\chapbreak{\dobreak \chapheadingskip {-4000}}
\def\chappager{\par\vfill\supereject}
% Because \domark is called before \chapoddpage, the filler page will
@@ -5440,13 +5743,16 @@ end
%
% #1 is the text, #2 is the section type (Ynumbered, Ynothing,
% Yappendix, Yomitfromtoc), #3 the chapter number.
+% Not used for @heading series.
%
% To test against our argument.
\def\Ynothingkeyword{Ynothing}
-\def\Yomitfromtockeyword{Yomitfromtoc}
\def\Yappendixkeyword{Yappendix}
+\def\Yomitfromtockeyword{Yomitfromtoc}
%
\def\chapmacro#1#2#3{%
+ \checkenv{}% chapters, etc., should not start inside an environment.
+ %
% Insert the first mark before the heading break (see notes for \domark).
\let\prevchapterdefs=\lastchapterdefs
\let\prevsectiondefs=\lastsectiondefs
@@ -5499,6 +5805,7 @@ end
%
{%
\chapfonts \rmisbold
+ \let\footnote=\errfootnoteheading % give better error message
%
% Have to define \lastsection before calling \donoderef, because the
% xref code eventually uses it. On the other hand, it has to be called
@@ -5535,8 +5842,7 @@ end
%
% Typeset the actual heading.
\nobreak % Avoid page breaks at the interline glue.
- \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright
- \hangindent=\wd0 \centerparametersmaybe
+ \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe
\unhbox0 #1\par}%
}%
\nobreak\bigskip % no page break after a chapter title
@@ -5558,18 +5864,18 @@ end
\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
%
\def\unnchfopen #1{%
-\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
- \parindent=0pt\ptexraggedright
- \rmisbold #1\hfill}}\bigskip \par\nobreak
+ \chapoddpage
+ \vbox{\chapfonts \raggedtitlesettings #1\par}%
+ \nobreak\bigskip\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 {\rmisbold #1}\hfill}}\bigskip \par\nobreak
+ \chapoddpage
+ \vbox{\chapfonts \raggedtitlesettings \hfill #1\hfill}%
+ \nobreak\bigskip \nobreak
}
\def\CHAPFopen{%
\global\let\chapmacro=\chfopen
@@ -5593,20 +5899,29 @@ end
% 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.
+% #1 is the text of the title,
+% #2 is the section level (sec/subsec/subsubsec),
+% #3 is the section type (Ynumbered, Ynothing, Yappendix, Yomitfromtoc),
+% #4 is the section number.
%
\def\seckeyword{sec}
%
\def\sectionheading#1#2#3#4{%
{%
- % Switch to the right set of fonts.
- \csname #2fonts\endcsname \rmisbold
- %
\def\sectionlevel{#2}%
\def\temptype{#3}%
%
+ % It is ok for the @heading series commands to appear inside an
+ % environment (it's been historically allowed, though the logic is
+ % dubious), but not the others.
+ \ifx\temptype\Yomitfromtockeyword\else
+ \checkenv{}% non-@*heading should not be in an environment.
+ \fi
+ \let\footnote=\errfootnoteheading
+ %
+ % Switch to the right set of fonts.
+ \csname #2fonts\endcsname \rmisbold
+ %
% Insert first mark before the heading break (see notes for \domark).
\let\prevsectiondefs=\lastsectiondefs
\ifx\temptype\Ynothingkeyword
@@ -5658,7 +5973,7 @@ end
%
% Now the second mark, after the heading break. No break points
% between here and the heading.
- \let\prevsectiondefs=\lastsectiondefs
+ \global\let\prevsectiondefs=\lastsectiondefs
\domark
%
% Only insert the space after the number if we have a section number.
@@ -5712,15 +6027,15 @@ end
%
% 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.)
+ % discardable item.) However, when a paragraph is not started next
+ % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out
+ % or the negative glue will cause weirdly wrong output, typically
+ % obscuring the section heading with something else.
\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
+ % This is so the last item on the main vertical list is a known
+ % \penalty > 10000, so \startdefun, etc., can recognize the situation
+ % and do the needful.
\penalty 10001
}
@@ -6025,14 +6340,15 @@ end
\catcode `\|=\other
\catcode `\<=\other
\catcode `\>=\other
- \catcode`\`=\other
- \catcode`\'=\other
+ \catcode `\`=\other
+ \catcode `\'=\other
\escapechar=`\\
%
% ' is active in math mode (mathcode"8000). So reset it, and all our
% other math active characters (just in case), to plain's definitions.
\mathactive
%
+ % Inverse of the list at the beginning of the file.
\let\b=\ptexb
\let\bullet=\ptexbullet
\let\c=\ptexc
@@ -6048,9 +6364,11 @@ end
\let\+=\tabalign
\let\}=\ptexrbrace
\let\/=\ptexslash
+ \let\sp=\ptexsp
\let\*=\ptexstar
+ %\let\sup=\ptexsup % do not redefine, we want @sup to work in math mode
\let\t=\ptext
- \expandafter \let\csname top\endcsname=\ptextop % outer
+ \expandafter \let\csname top\endcsname=\ptextop % we've made it outer
\let\frenchspacing=\plainfrenchspacing
%
\def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
@@ -6134,8 +6452,12 @@ end
% 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 = t%
+ %
+ % If this cartouche directly follows a sectioning command, we need the
+ % \parskip glue (backspaced over by default) or the cartouche can
+ % collide with the section heading.
+ \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi
+ %
\vbox\bgroup
\baselineskip=0pt\parskip=0pt\lineskip=0pt
\carttop
@@ -6149,7 +6471,7 @@ end
\lineskip=\normlskip
\parskip=\normpskip
\vskip -\parskip
- \comment % For explanation, see the end of \def\group.
+ \comment % For explanation, see the end of def\group.
}
\def\Ecartouche{%
\ifhmode\par\fi
@@ -6169,7 +6491,7 @@ end
\newdimen\nonfillparindent
\def\nonfillstart{%
\aboveenvbreak
- \hfuzz = 12pt % Don't be fussy
+ \ifdim\hfuzz < 12pt \hfuzz = 12pt \fi % 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
@@ -6296,9 +6618,13 @@ end
% @raggedright does more-or-less normal line breaking but no right
-% justification. From plain.tex.
+% justification. From plain.tex. Don't stretch around special
+% characters in urls in this environment, since the stretch at the right
+% should be enough.
\envdef\raggedright{%
- \rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax
+ \rightskip0pt plus2.4em \spaceskip.3333em \xspaceskip.5em\relax
+ \def\urefprestretchamount{0pt}%
+ \def\urefpoststretchamount{0pt}%
}
\let\Eraggedright\par
@@ -6327,16 +6653,9 @@ end
\makedispenvdef{quotation}{\quotationstart}
%
\def\quotationstart{%
- {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
- \parindent=0pt
- %
- % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+ \indentedblockstart % same as \indentedblock, but increase right margin too.
\ifx\nonarrowing\relax
- \advance\leftskip by \lispnarrowing
\advance\rightskip by \lispnarrowing
- \exdentamount = \lispnarrowing
- \else
- \let\nonarrowing = \relax
\fi
\parsearg\quotationlabel
}
@@ -6346,7 +6665,7 @@ end
%
\def\Equotation{%
\par
- \ifx\quotationauthor\undefined\else
+ \ifx\quotationauthor\thisisundefined\else
% indent a bit.
\leftline{\kern 2\leftskip \sl ---\quotationauthor}%
\fi
@@ -6362,6 +6681,32 @@ end
\fi
}
+% @indentedblock is like @quotation, but indents only on the left and
+% has no optional argument.
+%
+\makedispenvdef{indentedblock}{\indentedblockstart}
+%
+\def\indentedblockstart{%
+ {\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
+ \exdentamount = \lispnarrowing
+ \else
+ \let\nonarrowing = \relax
+ \fi
+}
+
+% Keep a nonzero parskip for the environment, since we're doing normal filling.
+%
+\def\Eindentedblock{%
+ \par
+ {\parskip=0pt \afterenvbreak}%
+}
+\def\Esmallindentedblock{\Eindentedblock}
+
% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
% If we want to allow any <char> as delimiter,
@@ -6505,6 +6850,7 @@ end
\makevalueexpandable
\setupverbatim
\indexnofonts % Allow `@@' and other weird things in file names.
+ \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}%
\input #1
\afterenvbreak
}%
@@ -6554,7 +6900,7 @@ end
% commands also insert a nobreak penalty, and we don't want to allow
% a break between a section heading and a defun.
%
- % As a minor refinement, we avoid "club" headers by signalling
+ % As a further refinement, we avoid "club" headers by signalling
% with penalty of 10003 after the very first @deffn in the
% sequence (see above), and penalty of 10002 after any following
% @def command.
@@ -6621,13 +6967,36 @@ end
\def\domakedefun#1#2#3{%
\envdef#1{%
\startdefun
+ \doingtypefnfalse % distinguish typed functions from all else
\parseargusing\activeparens{\printdefunline#3}%
}%
\def#2{\dodefunx#1}%
\def#3%
}
-%%% Untyped functions:
+\newif\ifdoingtypefn % doing typed function?
+\newif\ifrettypeownline % typeset return type on its own line?
+
+% @deftypefnnewline on|off says whether the return type of typed functions
+% are printed on their own line. This affects @deftypefn, @deftypefun,
+% @deftypeop, and @deftypemethod.
+%
+\parseargdef\deftypefnnewline{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxideftypefnnl\endcsname
+ = \empty
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxideftypefnnl\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @txideftypefnnl value `\temp',
+ must be on|off}%
+ \fi\fi
+}
+
+% Untyped functions:
% @deffn category name args
\makedefun{deffn}{\deffngeneral{}}
@@ -6646,7 +7015,7 @@ end
\defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
}
-%%% Typed functions:
+% Typed functions:
% @deftypefn category type name args
\makedefun{deftypefn}{\deftypefngeneral{}}
@@ -6661,10 +7030,11 @@ end
%
\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
\dosubind{fn}{\code{#4}}{#1}%
+ \doingtypefntrue
\defname{#2}{#3}{#4}\defunargs{#5\unskip}%
}
-%%% Typed variables:
+% Typed variables:
% @deftypevr category type var args
\makedefun{deftypevr}{\deftypecvgeneral{}}
@@ -6682,7 +7052,7 @@ end
\defname{#2}{#3}{#4}\defunargs{#5\unskip}%
}
-%%% Untyped variables:
+% Untyped variables:
% @defvr category var args
\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
@@ -6693,7 +7063,8 @@ end
% \defcvof {category of}class var args
\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
-%%% Type:
+% Types:
+
% @deftp category name args
\makedefun{deftp}#1 #2 #3\endheader{%
\doind{tp}{\code{#2}}%
@@ -6721,25 +7092,49 @@ end
% We are followed by (but not passed) the arguments, if any.
%
\def\defname#1#2#3{%
+ \par
% 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
+ % Determine if we are typesetting the return type of a typed function
+ % on a line by itself.
+ \rettypeownlinefalse
+ \ifdoingtypefn % doing a typed function specifically?
+ % then check user option for putting return type on its own line:
+ \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else
+ \rettypeownlinetrue
+ \fi
+ \fi
+ %
+ % How we'll format the category 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.
+ % Figure out line sizes for the paragraph shape. We'll always have at
+ % least two.
+ \tempnum = 2
+ %
% 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
+ %
+ % If doing a return type on its own line, we'll have another line.
+ \ifrettypeownline
+ \advance\tempnum by 1
+ \def\maybeshapeline{0in \hsize}%
+ \else
+ \def\maybeshapeline{}%
+ \fi
+ %
% 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.
+ % The final paragraph shape:
+ \parshape \tempnum 0in \dimen0 \maybeshapeline \defargsindent \dimen2
+ %
+ % Put the category name at the right margin.
\noindent
\hbox to 0pt{%
\hfil\box0 \kern-\hsize
@@ -6761,8 +7156,16 @@ end
% . 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
+ \def\temp{#2}% text of the return type
+ \ifx\temp\empty\else
+ \tclose{\temp}% typeset the return type
+ \ifrettypeownline
+ % put return type on its own line; prohibit line break following:
+ \hfil\vadjust{\nobreak}\break
+ \else
+ \space % type on same line, so just followed by a space
+ \fi
+ \fi % no return type
#3% output function name
}%
{\rm\enskip}% hskip 0.5 em of \tenrm
@@ -6782,7 +7185,10 @@ end
\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.
+ % want a way to get ttsl. We used to recommend @var for that, so
+ % leave the code in, but it's strange for @var to lead to typewriter.
+ % Nowadays we recommend @code, since the difference between a ttsl hyphen
+ % and a tt hyphen is pretty tiny. @code also disables ?` !`.
\def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}%
#1%
\sl\hyphenchar\font=45
@@ -6880,7 +7286,7 @@ end
% 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
+\ifx\eTeXversion\thisisundefined
\newwrite\macscribble
\def\scantokens#1{%
\toks0={#1}%
@@ -6905,12 +7311,14 @@ end
% ... and for \example:
\spaceisspace
%
- % The \empty here causes a following catcode 5 newline to be eaten
- % as part of reading whitespace after a control sequence. It does
- % not eat a catcode 13 newline. There's no good way to handle the
- % two cases. See the Macro Details node in the manual for the
- % workaround we currently have to recommend for macros and
+ % The \empty here causes a following catcode 5 newline to be eaten as
+ % part of reading whitespace after a control sequence. It does not
+ % eat a catcode 13 newline. There's no good way to handle the two
+ % cases (untried: maybe e-TeX's \everyeof could help, though plain TeX
+ % would then have different behavior). See the Macro Details node in
+ % the manual for the workaround we recommend for macros and
% line-oriented commands.
+ %
\scantokens{#1\empty}%
\endgroup}
@@ -7024,7 +7432,6 @@ end
%
% \anythingelse will almost certainly be an error of some kind.
-
% \mbodybackslash is the definition of \ in @macro bodies.
% It maps \foo\ => \csname macarg.foo\endcsname => #N
% where N is the macro parameter number.
@@ -7045,9 +7452,15 @@ end
\def\macroxxx#1{%
\getargs{#1}% now \macname is the macname and \argl the arglist
\ifx\argl\empty % no arguments
- \paramno=0
+ \paramno=0\relax
\else
\expandafter\parsemargdef \argl;%
+ \if\paramno>256\relax
+ \ifx\eTeXversion\thisisundefined
+ \errhelp = \EMsimple
+ \errmessage{You need eTeX to compile a file with macros with more than 256 arguments}
+ \fi
+ \fi
\fi
\if1\csname ismacro.\the\macname\endcsname
\message{Warning: redefining \the\macname}%
@@ -7097,9 +7510,17 @@ end
\def\getmacname#1 #2\relax{\macname={#1}}
\def\getmacargs#1{\def\argl{#1}}
+% For macro processing make @ a letter so that we can make Texinfo private macro names.
+\edef\texiatcatcode{\the\catcode`\@}
+\catcode `@=11\relax
+
% 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.
+% so \defmacro knows what to do. Define \macarg.BLAH for each BLAH
+% in the params list to some hook where the argument is to be expanded. If
+% there are less than 10 arguments that hook is to be replaced by ##N where N
+% is the position in that list, that is to say the macro arguments are to be
+% defined `a la TeX in the macro body.
+%
% That gets used by \mbodybackslash (above).
%
% We need to get `macro parameter char #' into several definitions.
@@ -7109,12 +7530,32 @@ end
%
% The same technique is used to protect \eatspaces till just before
% the macro is used.
-
+%
+% If there are 10 or more arguments, a different technique is used, where the
+% hook remains in the body, and when macro is to be expanded the body is
+% processed again to replace the arguments.
+%
+% In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the
+% argument N value and then \edef the body (nothing else will expand because of
+% the catcode regime underwhich the body was input).
+%
+% If you compile with TeX (not eTeX), and you have macros with 10 or more
+% arguments, no macro can have more than 256 arguments (else error).
\def\parsemargdef#1;{%
\paramno=0\def\paramlist{}%
\let\hash\relax
\let\xeatspaces\relax
\parsemargdefxxx#1,;,%
+ % In case that there are 10 or more arguments we parse again the arguments
+ % list to set new definitions for the \macarg.BLAH macros corresponding to
+ % each BLAH argument. It was anyhow needed to parse already once this list
+ % in order to count the arguments, and as macros with at most 9 arguments
+ % are by far more frequent than macro with 10 or more arguments, defining
+ % twice the \macarg.BLAH macros does not cost too much processing power.
+ \ifnum\paramno<10\relax\else
+ \paramno0\relax
+ \parsemmanyargdef@@#1,;,% 10 or more arguments
+ \fi
}
\def\parsemargdefxxx#1,{%
\if#1;\let\next=\relax
@@ -7125,16 +7566,205 @@ end
\edef\paramlist{\paramlist\hash\the\paramno,}%
\fi\next}
+\def\parsemmanyargdef@@#1,{%
+ \if#1;\let\next=\relax
+ \else
+ \let\next=\parsemmanyargdef@@
+ \edef\tempb{\eatspaces{#1}}%
+ \expandafter\def\expandafter\tempa
+ \expandafter{\csname macarg.\tempb\endcsname}%
+ % Note that we need some extra \noexpand\noexpand, this is because we
+ % don't want \the to be expanded in the \parsermacbody as it uses an
+ % \xdef .
+ \expandafter\edef\tempa
+ {\noexpand\noexpand\noexpand\the\toks\the\paramno}%
+ \advance\paramno by 1\relax
+ \fi\next}
+
% These two commands read recursive and nonrecursive macro bodies.
% (They're different since rec and nonrec macros end differently.)
%
+
+\catcode `\@\texiatcatcode
\long\def\parsemacbody#1@end macro%
{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
\long\def\parsermacbody#1@end rmacro%
{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\catcode `\@=11\relax
+
+\let\endargs@\relax
+\let\nil@\relax
+\def\nilm@{\nil@}%
+\long\def\nillm@{\nil@}%
+
+% This macro is expanded during the Texinfo macro expansion, not during its
+% definition. It gets all the arguments values and assigns them to macros
+% macarg.ARGNAME
+%
+% #1 is the macro name
+% #2 is the list of argument names
+% #3 is the list of argument values
+\def\getargvals@#1#2#3{%
+ \def\macargdeflist@{}%
+ \def\saveparamlist@{#2}% Need to keep a copy for parameter expansion.
+ \def\paramlist{#2,\nil@}%
+ \def\macroname{#1}%
+ \begingroup
+ \macroargctxt
+ \def\argvaluelist{#3,\nil@}%
+ \def\@tempa{#3}%
+ \ifx\@tempa\empty
+ \setemptyargvalues@
+ \else
+ \getargvals@@
+ \fi
+}
+
+%
+\def\getargvals@@{%
+ \ifx\paramlist\nilm@
+ % Some sanity check needed here that \argvaluelist is also empty.
+ \ifx\argvaluelist\nillm@
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Too many arguments in macro `\macroname'!}%
+ \fi
+ \let\next\macargexpandinbody@
+ \else
+ \ifx\argvaluelist\nillm@
+ % No more arguments values passed to macro. Set remaining named-arg
+ % macros to empty.
+ \let\next\setemptyargvalues@
+ \else
+ % pop current arg name into \@tempb
+ \def\@tempa##1{\pop@{\@tempb}{\paramlist}##1\endargs@}%
+ \expandafter\@tempa\expandafter{\paramlist}%
+ % pop current argument value into \@tempc
+ \def\@tempa##1{\longpop@{\@tempc}{\argvaluelist}##1\endargs@}%
+ \expandafter\@tempa\expandafter{\argvaluelist}%
+ % Here \@tempb is the current arg name and \@tempc is the current arg value.
+ % First place the new argument macro definition into \@tempd
+ \expandafter\macname\expandafter{\@tempc}%
+ \expandafter\let\csname macarg.\@tempb\endcsname\relax
+ \expandafter\def\expandafter\@tempe\expandafter{%
+ \csname macarg.\@tempb\endcsname}%
+ \edef\@tempd{\long\def\@tempe{\the\macname}}%
+ \push@\@tempd\macargdeflist@
+ \let\next\getargvals@@
+ \fi
+ \fi
+ \next
+}
-% This defines the macro itself. There are six cases: recursive and
-% nonrecursive macros of zero, one, and many arguments.
+\def\push@#1#2{%
+ \expandafter\expandafter\expandafter\def
+ \expandafter\expandafter\expandafter#2%
+ \expandafter\expandafter\expandafter{%
+ \expandafter#1#2}%
+}
+
+% Replace arguments by their values in the macro body, and place the result
+% in macro \@tempa
+\def\macvalstoargs@{%
+ % To do this we use the property that token registers that are \the'ed
+ % within an \edef expand only once. So we are going to place all argument
+ % values into respective token registers.
+ %
+ % First we save the token context, and initialize argument numbering.
+ \begingroup
+ \paramno0\relax
+ % Then, for each argument number #N, we place the corresponding argument
+ % value into a new token list register \toks#N
+ \expandafter\putargsintokens@\saveparamlist@,;,%
+ % Then, we expand the body so that argument are replaced by their
+ % values. The trick for values not to be expanded themselves is that they
+ % are within tokens and that tokens expand only once in an \edef .
+ \edef\@tempc{\csname mac.\macroname .body\endcsname}%
+ % Now we restore the token stack pointer to free the token list registers
+ % which we have used, but we make sure that expanded body is saved after
+ % group.
+ \expandafter
+ \endgroup
+ \expandafter\def\expandafter\@tempa\expandafter{\@tempc}%
+ }
+
+\def\macargexpandinbody@{%
+ %% Define the named-macro outside of this group and then close this group.
+ \expandafter
+ \endgroup
+ \macargdeflist@
+ % First the replace in body the macro arguments by their values, the result
+ % is in \@tempa .
+ \macvalstoargs@
+ % Then we point at the \norecurse or \gobble (for recursive) macro value
+ % with \@tempb .
+ \expandafter\let\expandafter\@tempb\csname mac.\macroname .recurse\endcsname
+ % Depending on whether it is recursive or not, we need some tailing
+ % \egroup .
+ \ifx\@tempb\gobble
+ \let\@tempc\relax
+ \else
+ \let\@tempc\egroup
+ \fi
+ % And now we do the real job:
+ \edef\@tempd{\noexpand\@tempb{\macroname}\noexpand\scanmacro{\@tempa}\@tempc}%
+ \@tempd
+}
+
+\def\putargsintokens@#1,{%
+ \if#1;\let\next\relax
+ \else
+ \let\next\putargsintokens@
+ % First we allocate the new token list register, and give it a temporary
+ % alias \@tempb .
+ \toksdef\@tempb\the\paramno
+ % Then we place the argument value into that token list register.
+ \expandafter\let\expandafter\@tempa\csname macarg.#1\endcsname
+ \expandafter\@tempb\expandafter{\@tempa}%
+ \advance\paramno by 1\relax
+ \fi
+ \next
+}
+
+% Save the token stack pointer into macro #1
+\def\texisavetoksstackpoint#1{\edef#1{\the\@cclvi}}
+% Restore the token stack pointer from number in macro #1
+\def\texirestoretoksstackpoint#1{\expandafter\mathchardef\expandafter\@cclvi#1\relax}
+% newtoks that can be used non \outer .
+\def\texinonouternewtoks{\alloc@ 5\toks \toksdef \@cclvi}
+
+% Tailing missing arguments are set to empty
+\def\setemptyargvalues@{%
+ \ifx\paramlist\nilm@
+ \let\next\macargexpandinbody@
+ \else
+ \expandafter\setemptyargvaluesparser@\paramlist\endargs@
+ \let\next\setemptyargvalues@
+ \fi
+ \next
+}
+
+\def\setemptyargvaluesparser@#1,#2\endargs@{%
+ \expandafter\def\expandafter\@tempa\expandafter{%
+ \expandafter\def\csname macarg.#1\endcsname{}}%
+ \push@\@tempa\macargdeflist@
+ \def\paramlist{#2}%
+}
+
+% #1 is the element target macro
+% #2 is the list macro
+% #3,#4\endargs@ is the list value
+\def\pop@#1#2#3,#4\endargs@{%
+ \def#1{#3}%
+ \def#2{#4}%
+}
+\long\def\longpop@#1#2#3,#4\endargs@{%
+ \long\def#1{#3}%
+ \long\def#2{#4}%
+}
+
+% This defines a Texinfo @macro. There are eight cases: recursive and
+% nonrecursive macros of zero, one, up to nine, 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.
@@ -7153,17 +7783,25 @@ end
\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}}%
+ \else
+ \ifnum\paramno<10\relax % at most 9
+ \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}}%
+ \else % 10 or more
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\getargvals@{\the\macname}{\argl}%
+ }%
+ \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp
+ \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble
+ \fi
\fi
\else
\ifcase\paramno
@@ -7180,23 +7818,33 @@ end
\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}%
+ \else % at most 9
+ \ifnum\paramno<10\relax
+ \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}%
+ \else % 10 or more:
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\getargvals@{\the\macname}{\argl}%
+ }%
+ \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp
+ \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\norecurse
+ \fi
\fi
\fi}
+\catcode `\@\texiatcatcode\relax
+
\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
% \braceorline decides whether the next nonwhitespace character is a
@@ -7235,7 +7883,8 @@ end
% @inforef is relatively simple.
\def\inforef #1{\inforefzzz #1,,,,**}
-\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+\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
@@ -7296,11 +7945,32 @@ end
\toks0 = \expandafter{\lastsection}%
\immediate \writexrdef{title}{\the\toks0 }%
\immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
- \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, during \shipout
+ \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout
}%
\fi
}
+% @xrefautosectiontitle on|off says whether @section(ing) names are used
+% automatically in xrefs, if the third arg is not explicitly specified.
+% This was provided as a "secret" @set xref-automatic-section-title
+% variable, now it's official.
+%
+\parseargdef\xrefautomaticsectiontitle{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETxref-automatic-section-title\endcsname
+ = \empty
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETxref-automatic-section-title\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @xrefautomaticsectiontitle value `\temp',
+ must be on|off}%
+ \fi\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
@@ -7309,26 +7979,41 @@ end
\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
\def\ref#1{\xrefX[#1,,,,,,,]}
+%
+\newbox\toprefbox
+\newbox\printedrefnamebox
+\newbox\infofilenamebox
+\newbox\printedmanualbox
+%
\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
\unsepspaces
- \def\printedmanual{\ignorespaces #5}%
+ %
+ % Get args without leading/trailing spaces.
\def\printedrefname{\ignorespaces #3}%
- \setbox1=\hbox{\printedmanual\unskip}%
- \setbox0=\hbox{\printedrefname\unskip}%
- \ifdim \wd0 = 0pt
+ \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}%
+ %
+ \def\infofilename{\ignorespaces #4}%
+ \setbox\infofilenamebox = \hbox{\infofilename\unskip}%
+ %
+ \def\printedmanual{\ignorespaces #5}%
+ \setbox\printedmanualbox = \hbox{\printedmanual\unskip}%
+ %
+ % If the printed reference name (arg #3) was not explicitly given in
+ % the @xref, figure out what we want to use.
+ \ifdim \wd\printedrefnamebox = 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.
+ \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax
+ % Not auto section-title: use 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.
+ % Auto section-title: use chapter/section title inside
+ % the square brackets if we have it.
+ \ifdim \wd\printedmanualbox > 0pt
+ % It is in another manual, so we don't have it; use node name.
\def\printedrefname{\ignorespaces #1}%
\else
\ifhavexrefs
- % We know the real title if we have the xref values.
+ % We (should) know the real title if we have the xref values.
\def\printedrefname{\refx{#1-title}{}}%
\else
% Otherwise just copy the Info node name.
@@ -7342,13 +8027,20 @@ end
\ifpdf
{\indexnofonts
\turnoffactive
+ \makevalueexpandable
% This expands tokens, so do it after making catcode changes, so _
- % etc. don't get their TeX definitions.
+ % etc. don't get their TeX definitions. This ignores all spaces in
+ % #4, including (wrongly) those in the middle of the filename.
\getfilename{#4}%
%
- % See comments at \activebackslashdouble.
- {\activebackslashdouble \xdef\pdfxrefdest{#1}%
- \backslashparens\pdfxrefdest}%
+ % This (wrongly) does not take account of leading or trailing
+ % spaces in #1, which should be ignored.
+ \edef\pdfxrefdest{#1}%
+ \ifx\pdfxrefdest\empty
+ \def\pdfxrefdest{Top}% no empty targets
+ \else
+ \txiescapepdf\pdfxrefdest % escape PDF special chars
+ \fi
%
\leavevmode
\startlink attr{/Border [0 0 0]}%
@@ -7375,29 +8067,42 @@ end
\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
+ \ifdim\wd\printedrefnamebox = 0pt
\refx{#1-snt}{}%
\else
\printedrefname
\fi
%
- % if the user also gave the printed manual name (fifth arg), append
+ % If the user also gave the printed manual name (fifth arg), append
% "in MANUALNAME".
- \ifdim \wd1 > 0pt
+ \ifdim \wd\printedmanualbox > 0pt
\space \putwordin{} \cite{\printedmanual}%
\fi
\else
% node/anchor (non-float) references.
+ %
+ % If we use \unhbox 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 \wd\printedmanualbox > 0pt
+ % Cross-manual reference with a printed manual name.
+ %
+ \crossmanualxref{\cite{\printedmanual\unskip}}%
+ %
+ \else\ifdim \wd\infofilenamebox > 0pt
+ % Cross-manual reference with only an info filename (arg 4), no
+ % printed manual name (arg 5). This is essentially the same as
+ % the case above; we output the filename, since we have nothing else.
+ %
+ \crossmanualxref{\code{\infofilename\unskip}}%
%
- % 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
+ % Reference within this manual.
+ %
% _ (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
@@ -7409,7 +8114,7 @@ end
\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.
+ % output the `[mynode]' via the macro below so it can be overridden.
\xrefprintnodename\printedrefname
%
% But we always want a comma and a space:
@@ -7417,11 +8122,37 @@ end
%
% output the `page 3'.
\turnoffactive \putwordpage\tie\refx{#1-pg}{}%
- \fi
+ \fi\fi
\fi
\endlink
\endgroup}
+% Output a cross-manual xref to #1. Used just above (twice).
+%
+% Only include the text "Section ``foo'' in" if the foo is neither
+% missing or Top. Thus, @xref{,,,foo,The Foo Manual} outputs simply
+% "see The Foo Manual", the idea being to refer to the whole manual.
+%
+% But, this being TeX, we can't easily compare our node name against the
+% string "Top" while ignoring the possible spaces before and after in
+% the input. By adding the arbitrary 7sp below, we make it much less
+% likely that a real node name would have the same width as "Top" (e.g.,
+% in a monospaced font). Hopefully it will never happen in practice.
+%
+% For the same basic reason, we retypeset the "Top" at every
+% reference, since the current font is indeterminate.
+%
+\def\crossmanualxref#1{%
+ \setbox\toprefbox = \hbox{Top\kern7sp}%
+ \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}%
+ \ifdim \wd2 > 7sp % nonempty?
+ \ifdim \wd2 = \wd\toprefbox \else % same as Top?
+ \putwordSection{} ``\printedrefname'' \putwordin{}\space
+ \fi
+ \fi
+ #1%
+}
+
% 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
@@ -7637,15 +8368,13 @@ end
% space to prevent strange expansion errors.)
\def\supereject{\par\penalty -20000\footnoteno =0 }
-% @footnotestyle is meaningful for info output only.
+% @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}$}%
%
@@ -7669,6 +8398,11 @@ end
%
\gdef\dofootnote{%
\insert\footins\bgroup
+ %
+ % Nested footnotes are not supported in TeX, that would take a lot
+ % more work. (\startsavinginserts does not suffice.)
+ \let\footnote=\errfootnotenest
+ %
% 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.
@@ -7700,17 +8434,30 @@ end
% expands into a box, it must come within the paragraph, lest it
% provide a place where TeX can split the footnote.
\footstrut
+ %
+ % Invoke rest of plain TeX footnote routine.
\futurelet\next\fo@t
}
}%end \catcode `\@=11
+\def\errfootnotenest{%
+ \errhelp=\EMsimple
+ \errmessage{Nested footnotes not supported in texinfo.tex,
+ even though they work in makeinfo; sorry}
+}
+
+\def\errfootnoteheading{%
+ \errhelp=\EMsimple
+ \errmessage{Footnotes in chapters, sections, etc., are not supported}
+}
+
% 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.
% Similarly, 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.
@@ -7787,7 +8534,7 @@ end
it from ftp://tug.org/tex/epsf.tex.}
%
\def\image#1{%
- \ifx\epsfbox\undefined
+ \ifx\epsfbox\thisisundefined
\ifwarnednoepsf \else
\errhelp = \noepsfhelp
\errmessage{epsf.tex not found, images will be ignored}%
@@ -7811,6 +8558,13 @@ end
% If the image is by itself, center it.
\ifvmode
\imagevmodetrue
+ \else \ifx\centersub\centerV
+ % for @center @image, we need a vbox so we can have our vertical space
+ \imagevmodetrue
+ \vbox\bgroup % vbox has better behavior than vtop herev
+ \fi\fi
+ %
+ \ifimagevmode
\nobreak\medskip
% Usually we'll have text after the image which will insert
% \parskip glue, so insert it here too to equalize the space
@@ -7820,9 +8574,13 @@ end
\fi
%
% Leave vertical mode so that indentation from an enclosing
- % environment such as @quotation is respected. On the other hand, if
- % it's at the top level, we don't want the normal paragraph indentation.
- \noindent
+ % environment such as @quotation is respected.
+ % However, if we're at the top level, we don't want the
+ % normal paragraph indentation.
+ % On the other hand, if we are in the case of @center @image, we don't
+ % want to start a paragraph, which will create a hsize-width box and
+ % eradicate the centering.
+ \ifx\centersub\centerV\else \noindent \fi
%
% Output the image.
\ifpdf
@@ -7834,7 +8592,10 @@ end
\epsfbox{#1.eps}%
\fi
%
- \ifimagevmode \medskip \fi % space after the standalone image
+ \ifimagevmode
+ \medskip % space after a standalone image
+ \fi
+ \ifx\centersub\centerV \egroup \fi
\endgroup}
@@ -8113,20 +8874,20 @@ end
{
\catcode`\_ = \active
\globaldefs=1
-\parseargdef\documentlanguage{\begingroup
- \let_=\normalunderscore % normal _ character for filenames
+\parseargdef\documentlanguage{%
\tex % read txi-??.tex file in plain TeX.
% Read the file by the name they passed if it exists.
+ \let_ = \normalunderscore % normal _ character for filename test
\openin 1 txi-#1.tex
\ifeof 1
- \documentlanguagetrywithoutunderscore{#1_\finish}%
+ \documentlanguagetrywithoutunderscore #1_\finish
\else
\globaldefs = 1 % everything in the txi-LL files needs to persist
\input txi-#1.tex
\fi
\closein 1
\endgroup % end raw TeX
-\endgroup}
+}
%
% If they passed de_DE, and txi-de_DE.tex doesn't exist,
% try txi-de.tex.
@@ -8252,7 +9013,7 @@ directory should work if nowhere else does.}
%
% Latin1 (ISO-8859-1) character definitions.
\def\latonechardefs{%
- \gdef^^a0{~}
+ \gdef^^a0{\tie}
\gdef^^a1{\exclamdown}
\gdef^^a2{\missingcharmsg{CENT SIGN}}
\gdef^^a3{{\pounds}}
@@ -8282,7 +9043,7 @@ directory should work if nowhere else does.}
\gdef^^b9{$^1$}
\gdef^^ba{\ordm}
%
- \gdef^^bb{\guilletright}
+ \gdef^^bb{\guillemetright}
\gdef^^bc{$1\over4$}
\gdef^^bd{$1\over2$}
\gdef^^be{$3\over4$}
@@ -8374,7 +9135,7 @@ directory should work if nowhere else does.}
% Latin2 (ISO-8859-2) character definitions.
\def\lattwochardefs{%
- \gdef^^a0{~}
+ \gdef^^a0{\tie}
\gdef^^a1{\ogonek{A}}
\gdef^^a2{\u{}}
\gdef^^a3{\L}
@@ -8536,6 +9297,18 @@ directory should work if nowhere else does.}
\UTFviiiLoop
\endgroup
+\def\globallet{\global\let} % save some \expandafter's below
+
+% @U{xxxx} to produce U+xxxx, if we support it.
+\def\U#1{%
+ \expandafter\ifx\csname uni:#1\endcsname \relax
+ \errhelp = \EMsimple
+ \errmessage{Unicode character U+#1 not supported, sorry}%
+ \else
+ \csname uni:#1\endcsname
+ \fi
+}
+
\begingroup
\catcode`\"=12
\catcode`\<=12
@@ -8544,10 +9317,9 @@ directory should work if nowhere else does.}
\catcode`\;=12
\catcode`\!=12
\catcode`\~=13
-
\gdef\DeclareUnicodeCharacter#1#2{%
\countUTFz = "#1\relax
- \wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}%
+ %\wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}%
\begingroup
\parseXMLCharref
\def\UTFviiiTwoOctets##1##2{%
@@ -8559,6 +9331,8 @@ directory should work if nowhere else does.}
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter
\gdef\UTFviiiTmp{#2}%
+ % define an additional control sequence for this code point.
+ \expandafter\globallet\csname uni:#1\endcsname \UTFviiiTmp
\endgroup}
\gdef\parseXMLCharref{%
@@ -9223,28 +9997,21 @@ directory should work if nowhere else does.}
\message{and turning on texinfo input format.}
+\def^^L{\par} % remove \outer, so ^L can appear in an @comment
+
% DEL is a comment character, in case @c does not suffice.
\catcode`\^^? = 14
% 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
+\catcode`\"=\other \def\normaldoublequote{"}
+\catcode`\$=\other \def\normaldollar{$}%$ font-lock fix
+\catcode`\+=\other \def\normalplus{+}
+\catcode`\<=\other \def\normalless{<}
+\catcode`\>=\other \def\normalgreater{>}
+\catcode`\^=\other \def\normalcaret{^}
+\catcode`\_=\other \def\normalunderscore{_}
+\catcode`\|=\other \def\normalverticalbar{|}
+\catcode`\~=\other \def\normaltilde{~}
% 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,
@@ -9271,11 +10038,9 @@ directory should work if nowhere else does.}
\catcode`\"=\active
\def\activedoublequote{{\tt\char34}}
\let"=\activedoublequote
-\catcode`\~=\active
-\def~{{\tt\char126}}
+\catcode`\~=\active \def\activetilde{{\tt\char126}} \let~ = \activetilde
\chardef\hat=`\^
-\catcode`\^=\active
-\def^{{\tt \hat}}
+\catcode`\^=\active \def\activehat{{\tt \hat}} \let^ = \activehat
\catcode`\_=\active
\def_{\ifusingtt\normalunderscore\_}
@@ -9285,16 +10050,26 @@ directory should work if nowhere else does.}
\catcode`\|=\active
\def|{{\tt\char124}}
+
\chardef \less=`\<
-\catcode`\<=\active
-\def<{{\tt \less}}
+\catcode`\<=\active \def\activeless{{\tt \less}}\let< = \activeless
\chardef \gtr=`\>
-\catcode`\>=\active
-\def>{{\tt \gtr}}
-\catcode`\+=\active
-\def+{{\tt \char 43}}
-\catcode`\$=\active
-\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
+\catcode`\>=\active \def\activegtr{{\tt \gtr}}\let> = \activegtr
+\catcode`\+=\active \def+{{\tt \char 43}}
+\catcode`\$=\active \def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
+
+% used for headline/footline in the output routine, in case the page
+% breaks in the middle of an @tex block.
+\def\texinfochars{%
+ \let< = \activeless
+ \let> = \activegtr
+ \let~ = \activetilde
+ \let^ = \activehat
+ \markupsetuplqdefault \markupsetuprqdefault
+ \let\b = \strong
+ \let\i = \smartitalic
+ % in principle, all other definitions in \tex have to be undone too.
+}
% 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.
@@ -9322,34 +10097,48 @@ directory should work if nowhere else does.}
% In texinfo, backslash is an active character; it prints the backslash
% in fixed width font.
-\catcode`\\=\active
-@def@normalbackslash{{@tt@backslashcurfont}}
+\catcode`\\=\active % @ for escape char from now on.
+
+% The story here is that in math mode, the \char of \backslashcurfont
+% ends up printing the roman \ from the math symbol font (because \char
+% in math mode uses the \mathcode, and plain.tex sets
+% \mathcode`\\="026E). It seems better for @backslashchar{} to always
+% print a typewriter backslash, hence we use an explicit \mathchar,
+% which is the decimal equivalent of "715c (class 7, e.g., use \fam;
+% ignored family value; char position "5C). We can't use " for the
+% usual hex value because it has already been made active.
+@def@normalbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}}
+@let@backslashchar = @normalbackslash % @backslashchar{} is for user documents.
+
% On startup, @fixbackslash assigns:
% @let \ = @normalbackslash
-
% \rawbackslash defines an active \ to do \backslashcurfont.
% \otherbackslash defines an active \ to be a literal `\' character with
-% catcode other.
+% catcode other. We switch back and forth between these.
@gdef@rawbackslash{@let\=@backslashcurfont}
@gdef@otherbackslash{@let\=@realbackslash}
% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
-% the literal character `\'.
-%
-@def@normalturnoffactive{%
- @let\=@normalbackslash
- @let"=@normaldoublequote
- @let~=@normaltilde
- @let^=@normalcaret
- @let_=@normalunderscore
- @let|=@normalverticalbar
- @let<=@normalless
- @let>=@normalgreater
- @let+=@normalplus
- @let$=@normaldollar %$ font-lock fix
- @markupsetuplqdefault
- @markupsetuprqdefault
- @unsepspaces
+% the literal character `\'. Also revert - to its normal character, in
+% case the active - from code has slipped in.
+%
+{@catcode`- = @active
+ @gdef@normalturnoffactive{%
+ @let-=@normaldash
+ @let"=@normaldoublequote
+ @let$=@normaldollar %$ font-lock fix
+ @let+=@normalplus
+ @let<=@normalless
+ @let>=@normalgreater
+ @let\=@normalbackslash
+ @let^=@normalcaret
+ @let_=@normalunderscore
+ @let|=@normalverticalbar
+ @let~=@normaltilde
+ @markupsetuplqdefault
+ @markupsetuprqdefault
+ @unsepspaces
+ }
}
% Make _ and + \other characters, temporarily.
@@ -9378,10 +10167,19 @@ directory should work if nowhere else does.}
% Say @foo, not \foo, in error messages.
@escapechar = `@@
+% These (along with & and #) are made active for url-breaking, so need
+% active definitions as the normal characters.
+@def@normaldot{.}
+@def@normalquest{?}
+@def@normalslash{/}
+
% These look ok in all fonts, so just make them not special.
-@catcode`@& = @other
-@catcode`@# = @other
-@catcode`@% = @other
+% @hashchar{} gets its own user-level command, because of #line.
+@catcode`@& = @other @def@normalamp{&}
+@catcode`@# = @other @def@normalhash{#}
+@catcode`@% = @other @def@normalpercent{%}
+
+@let @hashchar = @normalhash
@c Finally, make ` and ' active, so that txicodequoteundirected and
@c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we
diff --git a/eval.c b/eval.c
index 76c537e1..95992704 100644
--- a/eval.c
+++ b/eval.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-2011 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-2013 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -29,49 +29,26 @@ extern void after_beginfile(IOBUF **curfile);
extern double pow(double x, double y);
extern double modf(double x, double *yp);
extern double fmod(double x, double y);
-NODE **fcall_list;
+NODE **fcall_list = NULL;
long fcall_count = 0;
int currule = 0;
IOBUF *curfile = NULL; /* current data file */
-int exiting = FALSE;
+bool exiting = false;
-#ifdef DEBUGGING
-extern int pre_execute(INSTRUCTION **);
-extern void post_execute(INSTRUCTION *);
-#else
-#define r_interpret interpret
-#endif
+int (*interpret)(INSTRUCTION *);
+#define MAX_EXEC_HOOKS 10
+static int num_exec_hook = 0;
+static Func_pre_exec pre_execute[MAX_EXEC_HOOKS];
+static Func_post_exec post_execute = NULL;
-/*
- * Flag which executable this is; done here because eval.c is compiled
- * differently for each of them.
- */
-enum exe_mode which_gawk =
-#ifdef PROFILING
- exe_profiling /* pgawk */
-#else
-# ifdef DEBUGGING
- exe_debugging /* dgawk */
-# else
- exe_normal /* normal gawk */
-# endif
-#endif
- ; /* which_gawk */
+extern void frame_popped();
-#if __GNUC__ < 2
-NODE *_t; /* used as a temporary in macros */
-#endif
int OFSlen;
int ORSlen;
int OFMTidx;
int CONVFMTidx;
-/* Profiling stuff */
-#ifdef PROFILING
-#define INCREMENT(n) n++
-#else
-#define INCREMENT(n) /* nothing */
-#endif
+static NODE *node_Boolean[2];
/* This rather ugly macro is for VMS C */
#ifdef C
@@ -226,12 +203,12 @@ load_casetable(void)
#if defined(LC_CTYPE)
int i;
char *cp;
- static int loaded = FALSE;
+ static bool loaded = false;
if (loaded || do_traditional)
return;
- loaded = TRUE;
+ loaded = true;
cp = setlocale(LC_CTYPE, NULL);
/* this is not per standard, but it's pretty safe */
@@ -239,6 +216,7 @@ load_casetable(void)
return;
#ifndef ZOS_USS
+ /* use of isalpha is ok here (see is_alpha in awkgram.y) */
for (i = 0200; i <= 0377; i++) {
if (isalpha(i) && islower(i) && i != toupper(i))
casetable[i] = toupper(i);
@@ -263,7 +241,8 @@ static const char *const nodetypes[] = {
"Node_param_list",
"Node_func",
"Node_ext_func",
- "Node_hashnode",
+ "Node_old_ext_func",
+ "Node_builtin_func",
"Node_array_ref",
"Node_array_tree",
"Node_array_leaf",
@@ -353,6 +332,7 @@ static struct optypetab {
{ "Op_builtin", NULL },
{ "Op_sub_builtin", NULL },
{ "Op_ext_builtin", NULL },
+ { "Op_old_ext_builtin", NULL }, /* temporary */
{ "Op_in_array", " in " },
{ "Op_func_call", NULL },
{ "Op_indirect_func_call", NULL },
@@ -378,9 +358,11 @@ static struct optypetab {
{ "Op_var_update", NULL },
{ "Op_var_assign", NULL },
{ "Op_field_assign", NULL },
+ { "Op_subscript_assign", NULL },
{ "Op_after_beginfile", NULL },
{ "Op_after_endfile", NULL },
{ "Op_func", NULL },
+ { "Op_comment", NULL },
{ "Op_exec_count", NULL },
{ "Op_breakpoint", NULL },
{ "Op_lint", NULL },
@@ -459,6 +441,9 @@ flags2str(int flagval)
{ NUMINT, "NUMINT" },
{ INTIND, "INTIND" },
{ WSTRCUR, "WSTRCUR" },
+ { MPFN, "MPFN" },
+ { MPZN, "MPZN" },
+ { NULL_FIELD, "NULL_FIELD" },
{ ARRAYMAXED, "ARRAYMAXED" },
{ HALFHAT, "HALFHAT" },
{ XARRAY, "XARRAY" },
@@ -546,7 +531,7 @@ posix_compare(NODE *s1, NODE *s2)
* In either case, ret will be the right thing to return.
*/
}
-#if MBS_SUPPORT
+#if ! defined(__DJGPP__)
else {
/* Similar logic, using wide characters */
(void) force_wstring(s1);
@@ -585,6 +570,7 @@ posix_compare(NODE *s1, NODE *s2)
return ret;
}
+
/* cmp_nodes --- compare two nodes, returning negative, 0, positive */
int
@@ -597,28 +583,20 @@ cmp_nodes(NODE *t1, NODE *t2)
if (t1 == t2)
return 0;
- if (t1->flags & MAYBE_NUM)
+ if ((t1->flags & MAYBE_NUM) != 0)
(void) force_number(t1);
- if (t2->flags & MAYBE_NUM)
+ if ((t2->flags & MAYBE_NUM) != 0)
(void) force_number(t2);
- if (t1->flags & INTIND)
+ if ((t1->flags & INTIND) != 0)
t1 = force_string(t1);
- if (t2->flags & INTIND)
- t2 = force_string(t2);
-
- if ((t1->flags & NUMBER) && (t2->flags & NUMBER)) {
- if (t1->numbr == t2->numbr)
- ret = 0;
- /* don't subtract, in case one or both are infinite */
- else if (t1->numbr < t2->numbr)
- ret = -1;
- else
- ret = 1;
- return ret;
- }
+ if ((t2->flags & INTIND) != 0)
+ t2 = force_string(t2);
- t1 = force_string(t1);
- t2 = force_string(t2);
+ if ((t1->flags & NUMBER) != 0 && (t2->flags & NUMBER) != 0)
+ return cmp_numbers(t1, t2);
+
+ (void) force_string(t1);
+ (void) force_string(t2);
len1 = t1->stlen;
len2 = t2->stlen;
ldiff = len1 - len2;
@@ -633,15 +611,14 @@ cmp_nodes(NODE *t1, NODE *t2)
const unsigned char *cp1 = (const unsigned char *) t1->stptr;
const unsigned char *cp2 = (const unsigned char *) t2->stptr;
-#if MBS_SUPPORT
if (gawk_mb_cur_max > 1) {
ret = strncasecmpmbs((const unsigned char *) cp1,
(const unsigned char *) cp2, 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 {
+ /* 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);
@@ -649,8 +626,8 @@ cmp_nodes(NODE *t1, NODE *t2)
return ret;
}
+/* push_frame --- push a frame NODE onto stack */
-#if defined(PROFILING) || defined(DEBUGGING)
static void
push_frame(NODE *f)
{
@@ -672,28 +649,21 @@ push_frame(NODE *f)
fcall_list[1] = f;
}
+
+/* pop_frame --- pop off a frame NODE*/
+
static void
pop_frame()
{
-#ifdef DEBUGGING
- extern void frame_popped();
-#endif
if (fcall_count > 1)
memmove(fcall_list + 1, fcall_list + 2, (fcall_count - 1) * sizeof(NODE *));
fcall_count--;
assert(fcall_count >= 0);
-#ifdef DEBUGGING
- frame_popped();
-#endif
+ if (do_debug)
+ frame_popped();
}
-#else /* not PROFILING or DEBUGGING */
-#define push_frame(p) /* nothing */
-#define pop_frame() /* nothing */
-#endif
-#ifdef PROFILING
-
/* dump_fcall_stack --- print a backtrace of the awk function calls */
void
@@ -722,33 +692,35 @@ dump_fcall_stack(FILE *fp)
fprintf(fp, "\t# %3ld. -- main --\n", k);
}
-#endif /* PROFILING */
/* set_IGNORECASE --- update IGNORECASE as appropriate */
void
set_IGNORECASE()
{
- static short warned = FALSE;
+ static bool warned = false;
+ NODE *n = IGNORECASE_node->var_value;
if ((do_lint || do_traditional) && ! warned) {
- warned = TRUE;
+ 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_node->var_value = force_string(IGNORECASE_node->var_value);
- IGNORECASE = (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);
+ IGNORECASE = false;
+ else if ((n->flags & (STRING|STRCUR)) != 0) {
+ if ((n->flags & MAYBE_NUM) == 0) {
+ (void) force_string(n);
+ IGNORECASE = (n->stlen > 0);
+ } else {
+ (void) force_number(n);
+ IGNORECASE = ! iszero(n);
+ }
+ } else if ((n->flags & (NUMCUR|NUMBER)) != 0)
+ IGNORECASE = ! iszero(n);
else
- IGNORECASE = FALSE; /* shouldn't happen */
-
+ IGNORECASE = false; /* shouldn't happen */
+
set_RS(); /* set_RS() calls set_FS() if need be, for us */
}
@@ -757,26 +729,25 @@ set_IGNORECASE()
void
set_BINMODE()
{
- static short warned = FALSE;
+ static bool warned = false;
char *p;
- NODE *v;
+ NODE *v = BINMODE_node->var_value;
if ((do_lint || do_traditional) && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn(_("`BINMODE' is a gawk extension"));
}
if (do_traditional)
- BINMODE = 0;
- else if ((BINMODE_node->var_value->flags & NUMBER) != 0) {
- BINMODE = (int) force_number(BINMODE_node->var_value);
+ BINMODE = TEXT_TRANSLATE;
+ else if ((v->flags & NUMBER) != 0) {
+ (void) force_number(v);
+ BINMODE = get_number_si(v);
/* Make sure the value is rational. */
- if (BINMODE < 0)
- BINMODE = 0;
- else if (BINMODE > 3)
- BINMODE = 3;
- }
- else if ((BINMODE_node->var_value->flags & STRING) != 0) {
- v = BINMODE_node->var_value;
+ if (BINMODE < TEXT_TRANSLATE)
+ BINMODE = TEXT_TRANSLATE;
+ else if (BINMODE > BINMODE_BOTH)
+ BINMODE = BINMODE_BOTH;
+ } else if ((v->flags & STRING) != 0) {
p = v->stptr;
/*
@@ -795,13 +766,13 @@ set_BINMODE()
BINMODE = p[0] - '0';
break;
case 'r':
- BINMODE = 1;
+ BINMODE = BINMODE_INPUT;
break;
case 'w':
- BINMODE = 2;
+ BINMODE = BINMODE_OUTPUT;
break;
default:
- BINMODE = 3;
+ BINMODE = BINMODE_BOTH;
goto bad_value;
break;
}
@@ -809,24 +780,23 @@ set_BINMODE()
case 2:
switch (p[0]) {
case 'r':
- BINMODE = 3;
+ BINMODE = BINMODE_BOTH;
if (p[1] != 'w')
goto bad_value;
break;
case 'w':
- BINMODE = 3;
+ BINMODE = BINMODE_BOTH;
if (p[1] != 'r')
goto bad_value;
break;
+ }
break;
default:
bad_value:
lintwarn(_("BINMODE value `%s' is invalid, treated as 3"), p);
break;
- }
}
- }
- else
+ } else
BINMODE = 3; /* shouldn't happen */
}
@@ -835,9 +805,35 @@ set_BINMODE()
void
set_OFS()
{
+ static bool first = true;
+ size_t new_ofs_len;
+
+ if (first) /* true when called from init_vars() in main() */
+ first = false;
+ else {
+ /* rebuild $0 using OFS that was current when $0 changed */
+ if (! field0_valid) {
+ get_field(UNLIMITED - 1, NULL);
+ rebuild_record();
+ }
+ }
+
+ /*
+ * Save OFS value for use in building record and in printing.
+ * Can't just have OFS point into the OFS_node since it's
+ * already updated when we come into this routine, and we need
+ * the old value to rebuild the record (see above).
+ */
OFS_node->var_value = force_string(OFS_node->var_value);
- OFS = OFS_node->var_value->stptr;
- OFSlen = OFS_node->var_value->stlen;
+ new_ofs_len = OFS_node->var_value->stlen;
+
+ if (OFS == NULL)
+ emalloc(OFS, char *, new_ofs_len + 2, "set_OFS");
+ else if (OFSlen < new_ofs_len)
+ erealloc(OFS, char *, new_ofs_len + 2, "set_OFS");
+
+ memcpy(OFS, OFS_node->var_value->stptr, OFS_node->var_value->stlen);
+ OFSlen = new_ofs_len;
OFS[OFSlen] = '\0';
}
@@ -952,16 +948,16 @@ set_LINT()
{
#ifndef NO_LINT
int old_lint = do_lint;
+ NODE *n = LINT_node->var_value;
- if ((LINT_node->var_value->flags & (STRING|STRCUR)) != 0) {
- if ((LINT_node->var_value->flags & MAYBE_NUM) == 0) {
+ if ((n->flags & (STRING|STRCUR)) != 0) {
+ if ((n->flags & MAYBE_NUM) == 0) {
const char *lintval;
size_t lintlen;
- NODE *tmp;
- tmp = LINT_node->var_value = force_string(LINT_node->var_value);
- lintval = tmp->stptr;
- lintlen = tmp->stlen;
+ n = force_string(LINT_node->var_value);
+ lintval = n->stptr;
+ lintlen = n->stlen;
if (lintlen > 0) {
do_flags |= DO_LINT_ALL;
if (lintlen == 5 && strncmp(lintval, "fatal", 5) == 0)
@@ -976,14 +972,16 @@ set_LINT()
lintfunc = warning;
}
} else {
- if (force_number(LINT_node->var_value) != 0.0)
+ (void) force_number(n);
+ if (! iszero(n))
do_flags |= DO_LINT_ALL;
else
do_flags &= ~(DO_LINT_ALL|DO_LINT_INVALID);
lintfunc = warning;
}
- } else if ((LINT_node->var_value->flags & (NUMCUR|NUMBER)) != 0) {
- if (force_number(LINT_node->var_value) != 0.0)
+ } else if ((n->flags & (NUMCUR|NUMBER)) != 0) {
+ (void) force_number(n);
+ if (! iszero(n))
do_flags |= DO_LINT_ALL;
else
do_flags &= ~(DO_LINT_ALL|DO_LINT_INVALID);
@@ -997,6 +995,9 @@ set_LINT()
/* explicitly use warning() here, in case lintfunc == r_fatal */
if (old_lint != do_lint && old_lint && ! do_lint)
warning(_("turning off `--lint' due to assignment to `LINT'"));
+
+ /* inform plug-in api of change */
+ update_ext_api();
#endif /* ! NO_LINT */
}
@@ -1018,10 +1019,10 @@ set_TEXTDOMAIN()
*/
}
-/* update_ERRNO_saved --- update the value of ERRNO based on argument */
+/* update_ERRNO_int --- update the value of ERRNO based on argument */
void
-update_ERRNO_saved(int errcode)
+update_ERRNO_int(int errcode)
{
char *cp;
@@ -1034,12 +1035,22 @@ update_ERRNO_saved(int errcode)
ERRNO_node->var_value = make_string(cp, strlen(cp));
}
-/* update_ERRNO --- update the value of ERRNO based on errno */
+/* update_ERRNO_string --- update ERRNO */
+
+void
+update_ERRNO_string(const char *string)
+{
+ unref(ERRNO_node->var_value);
+ ERRNO_node->var_value = make_string(string, strlen(string));
+}
+
+/* unset_ERRNO --- eliminate the value of ERRNO */
void
-update_ERRNO()
+unset_ERRNO(void)
{
- update_ERRNO_saved(errno);
+ unref(ERRNO_node->var_value);
+ ERRNO_node->var_value = dupnode(Nnull_string);
}
/* update_NR --- update the value of NR */
@@ -1047,9 +1058,14 @@ update_ERRNO()
void
update_NR()
{
+#ifdef HAVE_MPFR
+ if (is_mpg_number(NR_node->var_value))
+ (void) mpg_update_var(NR_node);
+ else
+#endif
if (NR_node->var_value->numbr != NR) {
unref(NR_node->var_value);
- NR_node->var_value = make_number((AWKNUM) NR);
+ NR_node->var_value = make_number(NR);
}
}
@@ -1058,11 +1074,14 @@ update_NR()
void
update_NF()
{
- if (NF == -1 || NF_node->var_value->numbr != NF) {
+ long l;
+
+ l = get_number_si(NF_node->var_value);
+ if (NF == -1 || l != NF) {
if (NF == -1)
(void) get_field(UNLIMITED - 1, NULL); /* parse record */
unref(NF_node->var_value);
- NF_node->var_value = make_number((AWKNUM) NF);
+ NF_node->var_value = make_number(NF);
}
}
@@ -1071,9 +1090,14 @@ update_NF()
void
update_FNR()
{
+#ifdef HAVE_MPFR
+ if (is_mpg_number(FNR_node->var_value))
+ (void) mpg_update_var(FNR_node);
+ else
+#endif
if (FNR_node->var_value->numbr != FNR) {
unref(FNR_node->var_value);
- FNR_node->var_value = make_number((AWKNUM) FNR);
+ FNR_node->var_value = make_number(FNR);
}
}
@@ -1098,26 +1122,6 @@ NODE **args_array = NULL;
STACK_ITEM *
grow_stack()
{
- if (stack_ptr == NULL) {
- long newval;
-
- if ((newval = getenv_long("GAWK_STACKSIZE")) > 0)
- STACK_SIZE = newval;
-
- emalloc(stack_bottom, STACK_ITEM *, STACK_SIZE * sizeof(STACK_ITEM), "grow_stack");
- stack_ptr = stack_bottom - 1;
- stack_top = stack_bottom + STACK_SIZE - 1;
-
- /* initialize frame pointer */
- getnode(frame_ptr);
- frame_ptr->type = Node_frame;
- frame_ptr->stack = NULL;
- frame_ptr->func_node = NULL; /* in main */
- frame_ptr->num_tail_calls = 0;
- frame_ptr->vname = NULL;
- return stack_ptr;
- }
-
STACK_SIZE *= 2;
erealloc(stack_bottom, STACK_ITEM *, STACK_SIZE * sizeof(STACK_ITEM), "grow_stack");
stack_top = stack_bottom + STACK_SIZE - 1;
@@ -1132,12 +1136,12 @@ grow_stack()
*/
NODE **
-r_get_lhs(NODE *n, int reference)
+r_get_lhs(NODE *n, bool reference)
{
- int isparam = FALSE;
+ bool isparam = false;
if (n->type == Node_param_list) {
- isparam = TRUE;
+ isparam = true;
n = GET_PARAM(n->param_cnt);
}
@@ -1149,8 +1153,10 @@ r_get_lhs(NODE *n, int reference)
if (n->orig_array->type == Node_var_array)
fatal(_("attempt to use array `%s' in a scalar context"),
array_vname(n));
- n->orig_array->type = Node_var;
- n->orig_array->var_value = dupnode(Nnull_string);
+ if (n->orig_array->type != Node_var) {
+ n->orig_array->type = Node_var;
+ n->orig_array->var_value = Nnull_string;
+ }
/* fall through */
case Node_var_new:
n->type = Node_var;
@@ -1176,7 +1182,7 @@ r_get_lhs(NODE *n, int reference)
/* r_get_field --- get the address of a field node */
static inline NODE **
-r_get_field(NODE *n, Func_ptr *assign, int reference)
+r_get_field(NODE *n, Func_ptr *assign, bool reference)
{
long field_num;
NODE **lhs;
@@ -1191,7 +1197,9 @@ r_get_field(NODE *n, Func_ptr *assign, int reference)
}
}
- field_num = (long) force_number(n);
+ (void) force_number(n);
+ field_num = get_number_si(n);
+
if (field_num < 0)
fatal(_("attempt to access field %ld"), field_num);
@@ -1201,7 +1209,7 @@ r_get_field(NODE *n, Func_ptr *assign, int reference)
*assign = reset_record;
} else
lhs = get_field(field_num, assign);
- if (do_lint && reference && (*lhs == Null_field || *lhs == Nnull_string))
+ if (do_lint && reference && ((*lhs)->flags & NULL_FIELD) != 0)
lintwarn(_("reference to uninitialized field `$%ld'"),
field_num);
return lhs;
@@ -1253,17 +1261,16 @@ setup_frame(INSTRUCTION *pc)
NODE *m, *f, *fp;
NODE **sp = NULL;
int pcount, arg_count, i, j;
- int tail_optimize = FALSE;
+ bool tail_optimize = false;
f = pc->func_body;
pcount = f->param_cnt;
fp = f->fparms;
arg_count = (pc + 1)->expr_count;
-#ifndef DEBUGGING
/* tail recursion optimization */
- tail_optimize = (do_optimize > 1 && (pc + 1)->tail_call);
-#endif
+ tail_optimize = ((pc + 1)->tail_call && do_optimize
+ && ! do_debug && ! do_profile);
if (tail_optimize) {
/* free local vars of calling frame */
@@ -1367,7 +1374,8 @@ setup_frame(INSTRUCTION *pc)
frame_ptr->vname = source; /* save current source */
- push_frame(frame_ptr);
+ if (do_profile || do_debug)
+ push_frame(frame_ptr);
/* save current frame in stack */
PUSH(frame_ptr);
@@ -1416,7 +1424,8 @@ restore_frame(NODE *fp)
* resumes from ri->nexti.
*/
freenode(frame_ptr);
- pop_frame();
+ if (do_profile || do_debug)
+ pop_frame();
/* restore frame */
frame_ptr = fp;
@@ -1447,7 +1456,8 @@ free_arrayfor(NODE *r)
}
-/* unwind_stack --- pop items off the run-time stack;
+/*
+ * unwind_stack --- pop items off the run-time stack;
* 'n' is the # of items left in the stack.
*/
@@ -1481,7 +1491,13 @@ unwind_stack(long n)
freenode(r);
break;
default:
- if (in_main_context())
+ /*
+ * Check `exiting' and don't produce an error for
+ * cases like:
+ * func _fn0() { exit }
+ * BEGIN { ARRAY[_fn0()] }
+ */
+ if (in_main_context() && ! exiting)
fatal(_("unwind_stack: unexpected type `%s'"),
nodetype2str(r->type));
/* else
@@ -1508,30 +1524,30 @@ unwind_stack(long n)
#define pop_stack() (void) unwind_stack(0)
-/*
- * This generated compiler warnings from GCC 4.4. Who knows why.
- *
-#define eval_condition(t) (((t)->flags & MAYBE_NUM) && force_number(t), \
- ((t)->flags & NUMBER) ? ((t)->numbr != 0.0) : ((t)->stlen != 0))
-*/
-
-
static inline int
eval_condition(NODE *t)
{
+ if (t == node_Boolean[false])
+ return false;
+
+ if (t == node_Boolean[true])
+ return true;
+
if ((t->flags & MAYBE_NUM) != 0)
force_number(t);
+ else if ((t->flags & INTIND) != 0)
+ force_string(t);
if ((t->flags & NUMBER) != 0)
- return (t->numbr != 0.0);
+ return ! iszero(t);
return (t->stlen != 0);
}
-/* cmp_scalar -- compare two nodes on the stack */
+/* cmp_scalars -- compare two nodes on the stack */
static inline int
-cmp_scalar()
+cmp_scalars()
{
NODE *t1, *t2;
int di;
@@ -1548,20 +1564,22 @@ cmp_scalar()
return di;
}
-
/* op_assign --- assignment operators excluding = */
static void
op_assign(OPCODE op)
{
NODE **lhs;
- NODE *t1;
+ NODE *t1, *t2;
AWKNUM x = 0.0, x1, x2;
lhs = POP_ADDRESS();
t1 = *lhs;
- x1 = force_number(t1);
- TOP_NUMBER(x2);
+ x1 = force_number(t1)->numbr;
+
+ t2 = TOP_SCALAR();
+ x2 = force_number(t2)->numbr;
+ DEREF(t2);
switch (op) {
case Op_assign_plus:
@@ -1611,7 +1629,6 @@ op_assign(OPCODE op)
REPLACE(t1);
}
-
/* PUSH_CODE --- push a code onto the runtime stack */
void
@@ -1638,7 +1655,8 @@ POP_CODE()
}
-/* Implementation of BEGINFILE and ENDFILE requires saving an execution
+/*
+ * Implementation of BEGINFILE and ENDFILE requires saving an execution
* state and the ability to return to that state. The state is
* defined by the instruction triggering the BEGINFILE/ENDFILE rule, the
* run-time stack, the rule and the source file. The source line is available in
@@ -1707,1178 +1725,92 @@ pop_exec_state(int *rule, char **src, long *sz)
}
-/*
- * r_interpret:
- * code is a list of instructions to run. returns the exit value
- * from the awk code.
- */
-
- /* N.B.:
- * 1) reference counting done for both number and string values.
- * 2) Stack operations:
- * Use REPLACE[_XX] if last stack operation was TOP[_XX],
- * PUSH[_XX] if last operation was POP[_XX] instead.
- * 3) UPREF and DREF -- see awk.h
- */
-
+/* register_exec_hook --- add exec hooks in the interpreter. */
int
-r_interpret(INSTRUCTION *code)
+register_exec_hook(Func_pre_exec preh, Func_post_exec posth)
{
- INSTRUCTION *pc; /* current instruction */
- NODE *r = NULL;
- NODE *m;
- INSTRUCTION *ni;
- NODE *t1, *t2;
- NODE *f; /* function definition */
- NODE **lhs;
- AWKNUM x, x1, x2;
- int di;
- Regexp *rp;
- int stdio_problem = FALSE;
-
-
- if (args_array == NULL)
- emalloc(args_array, NODE **, (max_args + 2)*sizeof(NODE *), "r_interpret");
- else
- erealloc(args_array, NODE **, (max_args + 2)*sizeof(NODE *), "r_interpret");
+ int pos = 0;
-/* array subscript */
-#define mk_sub(n) (n == 1 ? POP_SCALAR() : concat_exp(n, TRUE))
+ /*
+ * multiple post-exec hooks aren't supported. post-exec hook is mainly
+ * for use by the debugger.
+ */
-#ifdef DEBUGGING
-#define JUMPTO(x) do { post_execute(pc); pc = (x); goto top; } while(FALSE)
-#else
-#define JUMPTO(x) do { pc = (x); goto top; } while(FALSE)
-#endif
+ if (! preh || (post_execute && posth))
+ return false;
- pc = code;
+ if (num_exec_hook == MAX_EXEC_HOOKS)
+ return false;
- /* N.B.: always use JUMPTO for next instruction, otherwise bad things
- * may happen. DO NOT add a real loop (for/while) below to
- * replace ' forever {'; this catches failure to use JUMPTO to execute
- * next instruction (e.g. continue statement).
+ /*
+ * Add to the beginning of the array but do not displace the
+ * debugger hook if it exists.
*/
+ if (num_exec_hook > 0) {
+ pos = !! do_debug;
+ if (num_exec_hook > pos)
+ memmove(pre_execute + pos + 1, pre_execute + pos,
+ (num_exec_hook - pos) * sizeof (preh));
+ }
+ pre_execute[pos] = preh;
+ num_exec_hook++;
- /* loop until hit Op_stop instruction */
-
- /* forever { */
-top:
- if (pc->source_line > 0)
- sourceline = pc->source_line;
-
-#ifdef DEBUGGING
- if (! pre_execute(&pc))
- goto top;
-#endif
-
- switch (pc->opcode) {
- case Op_rule:
- currule = pc->in_rule; /* for sole use in Op_K_next, Op_K_nextfile, Op_K_getline* */
- /* fall through */
- case Op_func:
- source = pc->source_file;
- break;
-
- case Op_atexit:
- /* avoid false source indications */
- source = NULL;
- sourceline = 0;
- (void) nextfile(& curfile, TRUE); /* close input data file */
- /*
- * 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;
- break;
-
- case Op_stop:
- return 0;
-
- case Op_push_i:
- m = pc->memory;
- if (! do_traditional && (m->flags & INTLSTR) != 0) {
- char *orig, *trans, save;
-
- save = m->stptr[m->stlen];
- m->stptr[m->stlen] = '\0';
- orig = m->stptr;
- trans = dgettext(TEXTDOMAIN, orig);
- m->stptr[m->stlen] = save;
- m = make_string(trans, strlen(trans));
- } else
- UPREF(m);
- PUSH(m);
- break;
-
- case Op_push:
- case Op_push_arg:
- {
- NODE *save_symbol;
- int isparam = FALSE;
-
- save_symbol = m = pc->memory;
- if (m->type == Node_param_list) {
- isparam = TRUE;
- save_symbol = m = GET_PARAM(m->param_cnt);
- if (m->type == Node_array_ref)
- m = m->orig_array;
- }
-
- switch (m->type) {
- case Node_var:
- if (do_lint && var_uninitialized(m))
- lintwarn(isparam ?
- _("reference to uninitialized argument `%s'") :
- _("reference to uninitialized variable `%s'"),
- save_symbol->vname);
- m = m->var_value;
- UPREF(m);
- PUSH(m);
- break;
-
- case Node_var_new:
- m->type = Node_var;
- m->var_value = dupnode(Nnull_string);
- if (do_lint)
- lintwarn(isparam ?
- _("reference to uninitialized argument `%s'") :
- _("reference to uninitialized variable `%s'"),
- save_symbol->vname);
- m = dupnode(Nnull_string);
- PUSH(m);
- break;
-
- case Node_var_array:
- if (pc->opcode == Op_push_arg)
- PUSH(m);
- else
- fatal(_("attempt to use array `%s' in a scalar context"),
- array_vname(save_symbol));
- break;
-
- default:
- cant_happen();
- }
- }
- break;
-
- case Op_push_param: /* function argument */
- m = pc->memory;
- if (m->type == Node_param_list)
- m = GET_PARAM(m->param_cnt);
- if (m->type == Node_var) {
- m = m->var_value;
- UPREF(m);
- PUSH(m);
- break;
- }
- /* else
- fall through */
- case Op_push_array:
- PUSH(pc->memory);
- break;
-
- case Op_push_lhs:
- lhs = get_lhs(pc->memory, pc->do_reference);
- PUSH_ADDRESS(lhs);
- break;
-
- case Op_subscript:
- t2 = mk_sub(pc->sub_count);
- t1 = POP_ARRAY();
-
- if (do_lint && in_array(t1, t2) == NULL) {
- t2 = force_string(t2);
- lintwarn(_("reference to uninitialized element `%s[\"%.*s\"]'"),
- array_vname(t1), (int) t2->stlen, t2->stptr);
- if (t2->stlen == 0)
- lintwarn(_("subscript of array `%s' is null string"), array_vname(t1));
- }
-
- r = *assoc_lookup(t1, t2);
- DEREF(t2);
- if (r->type == Node_val)
- UPREF(r);
- PUSH(r);
- break;
-
- case Op_sub_array:
- t2 = mk_sub(pc->sub_count);
- t1 = POP_ARRAY();
- r = in_array(t1, t2);
- if (r == NULL) {
- r = make_array();
- r->parent_array = t1;
- *assoc_lookup(t1, t2) = r;
- t2 = force_string(t2);
- r->vname = estrdup(t2->stptr, t2->stlen); /* the subscript in parent array */
- } else if (r->type != Node_var_array) {
- t2 = force_string(t2);
- fatal(_("attempt to use scalar `%s[\"%.*s\"]' as an array"),
- array_vname(t1), (int) t2->stlen, t2->stptr);
- }
-
- DEREF(t2);
- PUSH(r);
- break;
-
- case Op_subscript_lhs:
- t2 = mk_sub(pc->sub_count);
- t1 = POP_ARRAY();
- if (do_lint && in_array(t1, t2) == NULL) {
- t2 = force_string(t2);
- if (pc->do_reference)
- lintwarn(_("reference to uninitialized element `%s[\"%.*s\"]'"),
- array_vname(t1), (int) t2->stlen, t2->stptr);
- if (t2->stlen == 0)
- lintwarn(_("subscript of array `%s' is null string"), array_vname(t1));
- }
-
- lhs = assoc_lookup(t1, t2);
- if ((*lhs)->type == Node_var_array) {
- t2 = force_string(t2);
- fatal(_("attempt to use array `%s[\"%.*s\"]' in a scalar context"),
- array_vname(t1), (int) t2->stlen, t2->stptr);
- }
-
- DEREF(t2);
- PUSH_ADDRESS(lhs);
- break;
-
- case Op_field_spec:
- t1 = TOP_SCALAR();
- lhs = r_get_field(t1, (Func_ptr *) 0, TRUE);
- decr_sp();
- DEREF(t1);
- r = dupnode(*lhs); /* can't use UPREF here */
- PUSH(r);
- break;
-
- case Op_field_spec_lhs:
- t1 = TOP_SCALAR();
- lhs = r_get_field(t1, &pc->target_assign->field_assign, pc->do_reference);
- decr_sp();
- DEREF(t1);
- PUSH_ADDRESS(lhs);
- break;
-
- case Op_lint:
- if (do_lint) {
- switch (pc->lint_type) {
- case LINT_assign_in_cond:
- lintwarn(_("assignment used in conditional context"));
- break;
-
- case LINT_no_effect:
- lintwarn(_("statement has no effect"));
- break;
-
- default:
- cant_happen();
- }
- }
- break;
-
- case Op_K_break:
- case Op_K_continue:
- case Op_jmp:
- JUMPTO(pc->target_jmp);
-
- case Op_jmp_false:
- r = POP_SCALAR();
- di = eval_condition(r);
- DEREF(r);
- if (! di)
- JUMPTO(pc->target_jmp);
- break;
-
- case Op_jmp_true:
- r = POP_SCALAR();
- di = eval_condition(r);
- DEREF(r);
- if (di)
- JUMPTO(pc->target_jmp);
- break;
-
- case Op_and:
- case Op_or:
- t1 = POP_SCALAR();
- di = eval_condition(t1);
- DEREF(t1);
- if ((pc->opcode == Op_and && di)
- || (pc->opcode == Op_or && ! di))
- break;
- r = make_number((AWKNUM) di);
- PUSH(r);
- ni = pc->target_jmp;
- JUMPTO(ni->nexti);
-
- case Op_and_final:
- case Op_or_final:
- t1 = TOP_SCALAR();
- r = make_number((AWKNUM) eval_condition(t1));
- DEREF(t1);
- REPLACE(r);
- break;
-
- case Op_not:
- t1 = TOP_SCALAR();
- r = make_number((AWKNUM) ! eval_condition(t1));
- DEREF(t1);
- REPLACE(r);
- break;
-
- case Op_equal:
- r = make_number((AWKNUM) (cmp_scalar() == 0));
- REPLACE(r);
- break;
-
- case Op_notequal:
- r = make_number((AWKNUM) (cmp_scalar() != 0));
- REPLACE(r);
- break;
-
- case Op_less:
- r = make_number((AWKNUM) (cmp_scalar() < 0));
- REPLACE(r);
- break;
-
- case Op_greater:
- r = make_number((AWKNUM) (cmp_scalar() > 0));
- REPLACE(r);
- break;
-
- case Op_leq:
- r = make_number((AWKNUM) (cmp_scalar() <= 0));
- REPLACE(r);
- break;
-
- case Op_geq:
- r = make_number((AWKNUM) (cmp_scalar() >= 0));
- REPLACE(r);
- break;
-
- case Op_plus_i:
- x2 = force_number(pc->memory);
- goto plus;
-
- case Op_plus:
- POP_NUMBER(x2);
-plus:
- TOP_NUMBER(x1);
- r = make_number(x1 + x2);
- REPLACE(r);
- break;
-
- case Op_minus_i:
- x2 = force_number(pc->memory);
- goto minus;
-
- case Op_minus:
- POP_NUMBER(x2);
-minus:
- TOP_NUMBER(x1);
- r = make_number(x1 - x2);
- REPLACE(r);
- break;
-
- case Op_times_i:
- x2 = force_number(pc->memory);
- goto times;
-
- case Op_times:
- POP_NUMBER(x2);
-times:
- TOP_NUMBER(x1);
- r = make_number(x1 * x2);
- REPLACE(r);
- break;
-
- case Op_exp_i:
- x2 = force_number(pc->memory);
- goto exponent;
-
- case Op_exp:
- POP_NUMBER(x2);
-exponent:
- TOP_NUMBER(x1);
- x = calc_exp(x1, x2);
- r = make_number(x);
- REPLACE(r);
- break;
-
- case Op_quotient_i:
- x2 = force_number(pc->memory);
- goto quotient;
-
- case Op_quotient:
- POP_NUMBER(x2);
-quotient:
- if (x2 == 0)
- fatal(_("division by zero attempted"));
-
- TOP_NUMBER(x1);
- x = x1 / x2;
- r = make_number(x);
- REPLACE(r);
- break;
-
- case Op_mod_i:
- x2 = force_number(pc->memory);
- goto mod;
-
- case Op_mod:
- POP_NUMBER(x2);
-mod:
- if (x2 == 0)
- fatal(_("division by zero attempted in `%%'"));
-
- TOP_NUMBER(x1);
-#ifdef HAVE_FMOD
- x = fmod(x1, x2);
-#else /* ! HAVE_FMOD */
- (void) modf(x1 / x2, &x);
- x = x1 - x * x2;
-#endif /* ! HAVE_FMOD */
- r = make_number(x);
- REPLACE(r);
- break;
-
- case Op_preincrement:
- case Op_predecrement:
- x2 = pc->opcode == Op_preincrement ? 1.0 : -1.0;
- lhs = TOP_ADDRESS();
- t1 = *lhs;
- x1 = force_number(t1);
- if (t1->valref == 1 && t1->flags == (MALLOC|NUMCUR|NUMBER)) {
- /* optimization */
- t1->numbr = x1 + x2;
- } else {
- unref(t1);
- t1 = *lhs = make_number(x1 + x2);
- }
- UPREF(t1);
- REPLACE(t1);
- break;
-
- case Op_postincrement:
- case Op_postdecrement:
- x2 = pc->opcode == Op_postincrement ? 1.0 : -1.0;
- lhs = TOP_ADDRESS();
- t1 = *lhs;
- x1 = force_number(t1);
- if (t1->valref == 1 && t1->flags == (MALLOC|NUMCUR|NUMBER)) {
- /* optimization */
- t1->numbr = x1 + x2;
- } else {
- unref(t1);
- *lhs = make_number(x1 + x2);
- }
- r = make_number(x1);
- REPLACE(r);
- break;
-
- case Op_unary_minus:
- TOP_NUMBER(x1);
- r = make_number(-x1);
- REPLACE(r);
- break;
-
- case Op_store_sub:
- /* array[sub] assignment optimization,
- * see awkgram.y (optimize_assignment)
- */
- t1 = get_array(pc->memory, TRUE); /* array */
- t2 = mk_sub(pc->expr_count); /* subscript */
- lhs = assoc_lookup(t1, t2);
- if ((*lhs)->type == Node_var_array) {
- t2 = force_string(t2);
- fatal(_("attempt to use array `%s[\"%.*s\"]' in a scalar context"),
- array_vname(t1), (int) t2->stlen, t2->stptr);
- }
- DEREF(t2);
- unref(*lhs);
- *lhs = POP_SCALAR();
- break;
-
- case Op_store_var:
- /* simple variable assignment optimization,
- * see awkgram.y (optimize_assignment)
- */
-
- lhs = get_lhs(pc->memory, FALSE);
- unref(*lhs);
- r = pc->initval; /* constant initializer */
- if (r == NULL)
- *lhs = POP_SCALAR();
- else {
- UPREF(r);
- *lhs = r;
- }
- break;
-
- case Op_store_field:
- {
- /* field assignment optimization,
- * see awkgram.y (optimize_assignment)
- */
-
- Func_ptr assign;
- t1 = TOP_SCALAR();
- lhs = r_get_field(t1, &assign, FALSE);
- decr_sp();
- DEREF(t1);
- unref(*lhs);
- *lhs = POP_SCALAR();
- assert(assign != NULL);
- assign();
- }
- break;
-
- case Op_assign_concat:
- /* x = x ... string concatenation optimization */
- lhs = get_lhs(pc->memory, FALSE);
- t1 = force_string(*lhs);
- t2 = POP_STRING();
-
- free_wstr(*lhs);
-
- if (t1 != *lhs) {
- unref(*lhs);
- *lhs = dupnode(t1);
- }
-
- if (t1 != t2 && t1->valref == 1) {
- size_t nlen = t1->stlen + t2->stlen;
-
- erealloc(t1->stptr, char *, nlen + 2, "r_interpret");
- memcpy(t1->stptr + t1->stlen, t2->stptr, t2->stlen);
- t1->stlen = nlen;
- t1->stptr[nlen] = '\0';
- t1->flags &= ~(NUMCUR|NUMBER|NUMINT);
- } else {
- size_t nlen = t1->stlen + t2->stlen;
- char *p;
-
- emalloc(p, char *, nlen + 2, "r_interpret");
- memcpy(p, t1->stptr, t1->stlen);
- memcpy(p + t1->stlen, t2->stptr, t2->stlen);
- unref(*lhs);
- t1 = *lhs = make_str_node(p, nlen, ALREADY_MALLOCED);
- }
- DEREF(t2);
- break;
-
- case Op_assign:
- lhs = POP_ADDRESS();
- r = TOP_SCALAR();
- unref(*lhs);
- *lhs = r;
- UPREF(r);
- REPLACE(r);
- break;
-
- /* numeric assignments */
- case Op_assign_plus:
- case Op_assign_minus:
- case Op_assign_times:
- case Op_assign_quotient:
- case Op_assign_mod:
- case Op_assign_exp:
- op_assign(pc->opcode);
- break;
-
- case Op_var_update: /* update value of NR, FNR or NF */
- pc->update_var();
- break;
-
- case Op_var_assign:
- case Op_field_assign:
- if (pc->assign_ctxt == Op_sub_builtin
- && TOP()->numbr == 0.0 /* top of stack has a number == 0 */
- ) {
- /* There wasn't any substitutions. If the target is a FIELD,
- * this means no field re-splitting or $0 reconstruction.
- * Skip the set_FOO routine if the target is a special variable.
- */
-
- break;
- } else if ((pc->assign_ctxt == Op_K_getline
- || pc->assign_ctxt == Op_K_getline_redir)
- && TOP()->numbr <= 0.0 /* top of stack has a number <= 0 */
- ) {
- /* getline returned EOF or error */
-
- break;
- }
-
- if (pc->opcode == Op_var_assign)
- pc->assign_var();
- else
- pc->field_assign();
- break;
-
- case Op_concat:
- r = concat_exp(pc->expr_count, pc->concat_flag & CSUBSEP);
- PUSH(r);
- break;
-
- case Op_K_case:
- if ((pc + 1)->match_exp) {
- /* match a constant regex against switch expression instead of $0. */
-
- m = POP(); /* regex */
- t2 = TOP_SCALAR(); /* switch expression */
- t2 = force_string(t2);
- rp = re_update(m);
- di = (research(rp, t2->stptr, 0, t2->stlen,
- avoid_dfa(m, t2->stptr, t2->stlen)) >= 0);
- } else {
- t1 = POP_SCALAR(); /* case value */
- t2 = TOP_SCALAR(); /* switch expression */
- di = (cmp_nodes(t2, t1) == 0);
- DEREF(t1);
- }
-
- if (di) {
- /* match found */
-
- t2 = POP_SCALAR();
- DEREF(t2);
- JUMPTO(pc->target_jmp);
- }
- break;
-
- case Op_K_delete:
- t1 = POP_ARRAY();
- do_delete(t1, pc->expr_count);
- stack_adj(-pc->expr_count);
- break;
-
- case Op_K_delete_loop:
- t1 = POP_ARRAY();
- lhs = POP_ADDRESS(); /* item */
- do_delete_loop(t1, lhs);
- break;
-
- case Op_in_array:
- t1 = POP_ARRAY();
- t2 = mk_sub(pc->expr_count);
- di = (in_array(t1, t2) != NULL);
- DEREF(t2);
- PUSH(make_number((AWKNUM) di));
- break;
-
- case Op_arrayfor_init:
- {
- NODE **list = NULL;
- NODE *array, *sort_str;
- size_t num_elems = 0;
- static NODE *sorted_in = NULL;
- const char *how_to_sort = "@unsorted";
-
- /* get the array */
- array = POP_ARRAY();
-
- /* sanity: check if empty */
- if (array_empty(array))
- goto arrayfor;
-
- num_elems = array->table_size;
-
- if (sorted_in == NULL) /* do this once */
- sorted_in = make_string("sorted_in", 9);
-
- sort_str = NULL;
- /*
- * If posix, or if there's no PROCINFO[],
- * there's no ["sorted_in"], so no sorting
- */
- if (! do_posix && PROCINFO_node != NULL)
- sort_str = in_array(PROCINFO_node, sorted_in);
-
- if (sort_str != NULL) {
- sort_str = force_string(sort_str);
- if (sort_str->stlen > 0)
- how_to_sort = sort_str->stptr;
- }
-
- list = assoc_list(array, how_to_sort, SORTED_IN);
-
-arrayfor:
- getnode(r);
- r->type = Node_arrayfor;
- r->for_list = list;
- r->for_list_size = num_elems; /* # of elements in list */
- r->cur_idx = -1; /* current index */
- r->for_array = array; /* array */
- PUSH(r);
-
- if (num_elems == 0)
- JUMPTO(pc->target_jmp); /* Op_arrayfor_final */
- }
- break;
-
- case Op_arrayfor_incr:
- r = TOP(); /* Node_arrayfor */
- if (++r->cur_idx == r->for_list_size) {
- NODE *array;
- array = r->for_array; /* actual array */
- if (do_lint && array->table_size != r->for_list_size)
- lintwarn(_("for loop: array `%s' changed size from %ld to %ld during loop execution"),
- array_vname(array), (long) r->for_list_size, (long) array->table_size);
- JUMPTO(pc->target_jmp); /* Op_arrayfor_final */
- }
-
- t1 = r->for_list[r->cur_idx];
- lhs = get_lhs(pc->array_var, FALSE);
- unref(*lhs);
- *lhs = dupnode(t1);
- break;
-
- case Op_arrayfor_final:
- r = POP();
- assert(r->type == Node_arrayfor);
- free_arrayfor(r);
- break;
-
- case Op_builtin:
- r = pc->builtin(pc->expr_count);
- PUSH(r);
- break;
-
- case Op_ext_builtin:
- {
- int arg_count = pc->expr_count;
-
- PUSH_CODE(pc);
- r = pc->builtin(arg_count);
- (void) POP_CODE();
- while (arg_count-- > 0) {
- t1 = POP();
- if (t1->type == Node_val)
- DEREF(t1);
- }
- PUSH(r);
- }
- break;
-
- case Op_sub_builtin: /* sub, gsub and gensub */
- r = do_sub(pc->expr_count, pc->sub_flags);
- PUSH(r);
- break;
-
- case Op_K_print:
- do_print(pc->expr_count, pc->redir_type);
- break;
-
- case Op_K_printf:
- do_printf(pc->expr_count, pc->redir_type);
- break;
-
- case Op_K_print_rec:
- do_print_rec(pc->expr_count, pc->redir_type);
- break;
-
- case Op_push_re:
- m = pc->memory;
- if (m->type == Node_dynregex) {
- r = POP_STRING();
- unref(m->re_exp);
- m->re_exp = r;
- }
- PUSH(m);
- break;
-
- case Op_match_rec:
- m = pc->memory;
- t1 = *get_field(0, (Func_ptr *) 0);
-match_re:
- rp = re_update(m);
- /*
- * 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 Op_K_case.
- *
- * A new or improved dfa that distinguishes beginning/end of
- * string from beginning/end of line will allow us to get rid of
- * this hack.
- *
- * The avoid_dfa() function is in re.c; it is not very smart.
- */
-
- di = research(rp, t1->stptr, 0, t1->stlen,
- avoid_dfa(m, t1->stptr, t1->stlen));
- di = (di == -1) ^ (pc->opcode != Op_nomatch);
- if(pc->opcode != Op_match_rec) {
- decr_sp();
- DEREF(t1);
- }
- r = make_number((AWKNUM) di);
- PUSH(r);
- break;
-
- case Op_nomatch:
- /* fall through */
- case Op_match:
- m = pc->memory;
- t1 = TOP_STRING();
- if (m->type == Node_dynregex) {
- unref(m->re_exp);
- m->re_exp = t1;
- decr_sp();
- t1 = TOP_STRING();
- }
- goto match_re;
- break;
-
- case Op_indirect_func_call:
- {
- int arg_count;
-
- f = NULL;
- arg_count = (pc + 1)->expr_count;
- t1 = PEEK(arg_count); /* indirect var */
- assert(t1->type == Node_val); /* @a[1](p) not allowed in grammar */
- t1 = force_string(t1);
- if (t1->stlen > 0) {
- /* retrieve function definition node */
- f = pc->func_body;
- if (f != NULL && STREQ(f->vname, t1->stptr)) {
- /* indirect var hasn't been reassigned */
-
- goto func_call;
- }
- f = lookup(t1->stptr);
- }
-
- if (f == NULL || f->type != Node_func)
- fatal(_("function called indirectly through `%s' does not exist"),
- pc->func_name);
- pc->func_body = f; /* save for next call */
-
- goto func_call;
- }
-
- case Op_func_call:
- /* retrieve function definition node */
- f = pc->func_body;
- if (f == NULL) {
- f = lookup(pc->func_name);
- if (f == NULL || (f->type != Node_func && f->type != Node_ext_func))
- fatal(_("function `%s' not defined"), pc->func_name);
- pc->func_body = f; /* save for next call */
- }
-
- if (f->type == Node_ext_func) {
- INSTRUCTION *bc;
- char *fname = pc->func_name;
- int arg_count = (pc + 1)->expr_count;
-
- bc = f->code_ptr;
- assert(bc->opcode == Op_symbol);
- pc->opcode = Op_ext_builtin; /* self modifying code */
- pc->builtin = bc->builtin;
- pc->expr_count = arg_count; /* actual argument count */
- (pc + 1)->func_name = fname; /* name of the builtin */
- (pc + 1)->expr_count = bc->expr_count; /* defined max # of arguments */
- ni = pc;
- JUMPTO(ni);
- }
-
-func_call:
- ni = setup_frame(pc);
-
- /* run the function instructions */
- JUMPTO(ni); /* Op_func */
-
- case Op_K_return:
- m = POP_SCALAR(); /* return value */
-
- ni = pop_fcall();
-
- /* put the return value back on stack */
- PUSH(m);
-
- JUMPTO(ni);
-
- case Op_K_getline_redir:
- if ((currule == BEGINFILE || currule == ENDFILE)
- && pc->into_var == FALSE
- && pc->redir_type == redirect_input)
- fatal(_("`getline' invalid inside `%s' rule"), ruletab[currule]);
- r = do_getline_redir(pc->into_var, pc->redir_type);
- PUSH(r);
- break;
-
- case Op_K_getline: /* no redirection */
- if (currule == BEGINFILE || currule == ENDFILE)
- fatal(_("non-redirected `getline' invalid inside `%s' rule"),
- ruletab[currule]);
-
- do {
- int ret;
- ret = nextfile(& curfile, FALSE);
- if (ret <= 0)
- r = do_getline(pc->into_var, curfile);
- else {
-
- /* Save execution state so that we can return to it
- * from Op_after_beginfile or Op_after_endfile.
- */
-
- push_exec_state(pc, currule, source, stack_ptr);
-
- if (curfile == NULL)
- JUMPTO((pc + 1)->target_endfile);
- else
- JUMPTO((pc + 1)->target_beginfile);
- }
- } while (r == NULL); /* EOF */
-
- PUSH(r);
- break;
-
- case Op_after_endfile:
- /* Find the execution state to return to */
- ni = pop_exec_state(& currule, & source, NULL);
-
- assert(ni->opcode == Op_newfile || ni->opcode == Op_K_getline);
- JUMPTO(ni);
-
- case Op_after_beginfile:
- after_beginfile(& curfile);
-
- /* Find the execution state to return to */
- ni = pop_exec_state(& currule, & source, NULL);
-
- assert(ni->opcode == Op_newfile || ni->opcode == Op_K_getline);
- if (ni->opcode == Op_K_getline
- || curfile == NULL /* skipping directory argument */
- )
- JUMPTO(ni);
-
- break; /* read a record, Op_get_record */
-
- case Op_newfile:
- {
- int ret;
-
- ret = nextfile(& curfile, FALSE);
-
- if (ret < 0) /* end of input */
- JUMPTO(pc->target_jmp); /* end block or Op_atexit */
-
- if (ret == 0) /* read a record */
- JUMPTO((pc + 1)->target_get_record);
-
- /* ret > 0 */
- /* Save execution state for use in Op_after_beginfile or Op_after_endfile. */
-
- push_exec_state(pc, currule, source, stack_ptr);
-
- if (curfile == NULL) /* EOF */
- JUMPTO(pc->target_endfile);
- /* else
- execute beginfile block */
- }
- break;
-
- case Op_get_record:
- {
- int errcode = 0;
-
- ni = pc->target_newfile;
- if (curfile == NULL) {
- /* from non-redirected getline, e.g.:
- * {
- * while (getline > 0) ;
- * }
- */
-
- ni = ni->target_jmp; /* end_block or Op_atexit */
- JUMPTO(ni);
- }
-
- if (inrec(curfile, & errcode) != 0) {
- if (errcode > 0 && (do_traditional || ! pc->has_endfile))
- fatal(_("error reading input file `%s': %s"),
- curfile->name, strerror(errcode));
-
- JUMPTO(ni);
- } /* else
- prog (rule) block */
- }
- break;
-
- case Op_K_nextfile:
- {
- int ret;
-
- if (currule != Rule && currule != BEGINFILE)
- fatal(_("`nextfile' cannot be called from a `%s' rule"),
- ruletab[currule]);
-
- ret = nextfile(& curfile, TRUE); /* skip current file */
-
- if (currule == BEGINFILE) {
- long stack_size;
-
- ni = pop_exec_state(& currule, & source, & stack_size);
-
- assert(ni->opcode == Op_K_getline || ni->opcode == Op_newfile);
-
- /* pop stack returning to the state of Op_K_getline or Op_newfile. */
- unwind_stack(stack_size);
-
- if (ret == 0) {
- /* There was an error opening the file;
- * don't run ENDFILE block(s).
- */
-
- JUMPTO(ni);
- } else {
- /* do run ENDFILE block(s) first. */
-
- /* Execution state to return to in Op_after_endfile. */
- push_exec_state(ni, currule, source, stack_ptr);
-
- JUMPTO(pc->target_endfile);
- }
- } /* else
- Start over with the first rule. */
-
- /* empty the run-time stack to avoid memory leak */
- pop_stack();
-
- /* Push an execution state for Op_after_endfile to return to */
- push_exec_state(pc->target_newfile, currule, source, stack_ptr);
-
- JUMPTO(pc->target_endfile);
- }
- break;
-
- case Op_K_exit:
- exiting = TRUE;
- POP_NUMBER(x1);
- exit_val = (int) x1;
-#ifdef VMS
- if (exit_val == 0)
- exit_val = EXIT_SUCCESS;
- else if (exit_val == 1)
- exit_val = EXIT_FAILURE;
- /* else
- just pass anything else on through */
-#endif
-
- if (currule == BEGINFILE || currule == ENDFILE) {
-
- /* Find the rule of the saved execution state (Op_K_getline/Op_newfile).
- * This is needed to prevent multiple execution of any END rules:
- * gawk 'BEGINFILE { exit(1) } \
- * END { while (getline > 0); }' in1 in2
- */
-
- (void) pop_exec_state(& currule, & source, NULL);
- }
-
- pop_stack(); /* empty stack, don't leak memory */
-
- /* Jump to either the first END block instruction
- * or to Op_atexit.
- */
-
- if (currule == END)
- ni = pc->target_atexit;
- else
- ni = pc->target_end;
- JUMPTO(ni);
-
- case Op_K_next:
- if (currule != Rule)
- fatal(_("`next' cannot be called from a `%s' rule"), ruletab[currule]);
-
- pop_stack();
- JUMPTO(pc->target_jmp); /* Op_get_record, read next record */
-
- case Op_pop:
- r = POP_SCALAR();
- DEREF(r);
- break;
-
- case Op_line_range:
- if (pc->triggered) /* evaluate right expression */
- JUMPTO(pc->target_jmp);
- /* else
- evaluate left expression */
- break;
+ if (posth)
+ post_execute = posth;
- case Op_cond_pair:
- {
- int result;
- INSTRUCTION *ip;
+ return true;
+}
- t1 = TOP_SCALAR(); /* from right hand side expression */
- di = (eval_condition(t1) != 0);
- DEREF(t1);
- ip = pc->line_range; /* Op_line_range */
+/* interpreter routine when not debugging */
+#include "interpret.h"
- if (! ip->triggered && di) {
- /* not already triggered and left expression is TRUE */
- decr_sp();
- ip->triggered = TRUE;
- JUMPTO(ip->target_jmp); /* evaluate right expression */
- }
+/* interpreter routine with exec hook(s). Used when debugging and/or with MPFR. */
+#define r_interpret h_interpret
+#define EXEC_HOOK 1
+#include "interpret.h"
+#undef EXEC_HOOK
+#undef r_interpret
- result = ip->triggered || di;
- ip->triggered ^= di; /* update triggered flag */
- r = make_number((AWKNUM) result); /* final value of condition pair */
- REPLACE(r);
- JUMPTO(pc->target_jmp);
- }
- case Op_exec_count:
- INCREMENT(pc->exec_count);
- break;
+void
+init_interpret()
+{
+ long newval;
- case Op_no_op:
- case Op_K_do:
- case Op_K_while:
- case Op_K_for:
- case Op_K_arrayfor:
- case Op_K_switch:
- case Op_K_default:
- case Op_K_if:
- case Op_K_else:
- case Op_cond_exp:
- break;
+ if ((newval = getenv_long("GAWK_STACKSIZE")) > 0)
+ STACK_SIZE = newval;
- default:
- fatal(_("Sorry, don't know how to interpret `%s'"), opcode2str(pc->opcode));
- }
+ emalloc(stack_bottom, STACK_ITEM *, STACK_SIZE * sizeof(STACK_ITEM), "grow_stack");
+ stack_ptr = stack_bottom - 1;
+ stack_top = stack_bottom + STACK_SIZE - 1;
- JUMPTO(pc->nexti);
+ /* initialize frame pointer */
+ getnode(frame_ptr);
+ frame_ptr->type = Node_frame;
+ frame_ptr->stack = NULL;
+ frame_ptr->func_node = NULL; /* in main */
+ frame_ptr->num_tail_calls = 0;
+ frame_ptr->vname = NULL;
-/* } forever */
+ /* initialize true and false nodes */
+ node_Boolean[false] = make_number(0.0);
+ node_Boolean[true] = make_number(1.0);
+ if (! is_mpg_number(node_Boolean[false])) {
+ node_Boolean[false]->flags |= NUMINT;
+ node_Boolean[true]->flags |= NUMINT;
+ }
- /* not reached */
- return 0;
+ /*
+ * Select the interpreter routine. The version without
+ * any exec hook support (r_interpret) is faster by about
+ * 5%, or more depending on the opcodes.
+ */
-#undef mk_sub
-#undef JUMPTO
+ if (num_exec_hook > 0)
+ interpret = h_interpret;
+ else
+ interpret = r_interpret;
}
+
diff --git a/ext.c b/ext.c
index 19e0eec5..cf813674 100644
--- a/ext.c
+++ b/ext.c
@@ -7,7 +7,7 @@
*/
/*
- * Copyright (C) 1995 - 2001, 2003-2011 the Free Software Foundation, Inc.
+ * Copyright (C) 1995 - 2001, 2003-2014 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -28,88 +28,219 @@
*/
#include "awk.h"
+extern SRCFILE *srcfiles;
#ifdef DYNAMIC
+#define OLD_INIT_FUNC "dlload"
+#define OLD_FINI_FUNC "dlunload"
+
#include <dlfcn.h>
-#ifdef __GNUC__
-static unsigned long long dummy; /* fake out gcc for dynamic loading? */
-#endif
+/*
+ * is_letter --- function to check letters
+ * isalpha() isn't good enough since it can look at the locale.
+ * Underscore counts as a letter in awk identifiers
+ */
+
+static bool
+is_letter(unsigned char c)
+{
+ return (is_alpha(c) || c == '_');
+}
+
+#define INIT_FUNC "dl_load"
+
+/* load_ext --- load an external library */
+
+void
+load_ext(const char *lib_name)
+{
+ int (*install_func)(const gawk_api_t *const, awk_ext_id_t);
+ void *dl;
+ int flags = RTLD_LAZY;
+ int *gpl_compat;
+
+ if (do_sandbox)
+ fatal(_("extensions are not allowed in sandbox mode"));
+
+ if (do_traditional || do_posix)
+ fatal(_("-l / @load are gawk extensions"));
-/* do_ext --- load an extension */
+ if (lib_name == NULL)
+ fatal(_("load_ext: received NULL lib_name"));
+
+ if ((dl = dlopen(lib_name, flags)) == NULL)
+ fatal(_("load_ext: cannot open library `%s' (%s)\n"), lib_name,
+ dlerror());
+
+ /* Per the GNU Coding standards */
+ gpl_compat = (int *) dlsym(dl, "plugin_is_GPL_compatible");
+ if (gpl_compat == NULL)
+ fatal(_("load_ext: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"),
+ lib_name, dlerror());
+
+ install_func = (int (*)(const gawk_api_t *const, awk_ext_id_t))
+ dlsym(dl, INIT_FUNC);
+ if (install_func == NULL)
+ fatal(_("load_ext: library `%s': cannot call function `%s' (%s)\n"),
+ lib_name, INIT_FUNC, dlerror());
+
+ if (install_func(& api_impl, NULL /* ext_id */) == 0)
+ warning(_("load_ext: library `%s' initialization routine `%s' failed\n"),
+ lib_name, INIT_FUNC);
+}
+/* do_ext --- load an extension at run-time: interface to load_ext */
+
NODE *
do_ext(int nargs)
{
- NODE *obj;
- NODE *fun;
- NODE *tmp = NULL;
+ NODE *obj, *init = NULL, *fini = NULL, *ret = NULL;
+ SRCFILE *s;
+ char *init_func = NULL;
+ char *fini_func = NULL;
+
+ if (nargs == 3) {
+ fini = POP_STRING();
+ fini_func = fini->stptr;
+ }
+ if (nargs >= 2) {
+ init = POP_STRING();
+ init_func = init->stptr;
+ }
+ obj = POP_STRING();
+
+ s = add_srcfile(SRC_EXTLIB, obj->stptr, srcfiles, NULL, NULL);
+ if (s != NULL)
+ ret = load_old_ext(s, init_func, fini_func, obj);
+
+ DEREF(obj);
+ if (fini != NULL)
+ DEREF(fini);
+ if (init != NULL)
+ DEREF(init);
+ if (ret == NULL)
+ ret = dupnode(Nnull_string);
+ return ret;
+}
+
+/* load_old_ext --- load an external library */
+
+NODE *
+load_old_ext(SRCFILE *s, const char *init_func, const char *fini_func, NODE *obj)
+{
NODE *(*func)(NODE *, void *);
+ NODE *tmp;
void *dl;
int flags = RTLD_LAZY;
- int fatal_error = FALSE;
int *gpl_compat;
+ const char *lib_name = s->fullpath;
-#ifdef __GNUC__
- AWKNUM junk;
+ if (init_func == NULL || init_func[0] == '\0')
+ init_func = OLD_INIT_FUNC;
- junk = (AWKNUM) dummy;
-#endif
+ if (fini_func == NULL || fini_func[0] == '\0')
+ fini_func = OLD_FINI_FUNC;
if (do_sandbox)
fatal(_("extensions are not allowed in sandbox mode"));
if (do_traditional || do_posix)
- error(_("`extension' is a gawk extension"));
+ fatal(_("`extension' is a gawk extension"));
- fun = POP_STRING();
- obj = POP_STRING();
+ if (lib_name == NULL)
+ fatal(_("extension: received NULL lib_name"));
-#ifdef RTLD_GLOBAL
- flags |= RTLD_GLOBAL;
-#endif
- if ((dl = dlopen(obj->stptr, flags)) == NULL) {
- /* fatal needs `obj', and we need to deallocate it! */
- msg(_("fatal: extension: cannot open `%s' (%s)\n"), obj->stptr,
+ if ((dl = dlopen(lib_name, flags)) == NULL)
+ fatal(_("extension: cannot open library `%s' (%s)"), lib_name,
dlerror());
- fatal_error = TRUE;
- goto done;
- }
/* Per the GNU Coding standards */
gpl_compat = (int *) dlsym(dl, "plugin_is_GPL_compatible");
- if (gpl_compat == NULL) {
- msg(_("fatal: extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"),
- obj->stptr, dlerror());
- fatal_error = TRUE;
- goto done;
- }
+ if (gpl_compat == NULL)
+ fatal(_("extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)"),
+ lib_name, dlerror());
+ func = (NODE *(*)(NODE *, void *)) dlsym(dl, init_func);
+ if (func == NULL)
+ fatal(_("extension: library `%s': cannot call function `%s' (%s)"),
+ lib_name, init_func, dlerror());
+
+ if (obj == NULL) {
+ obj = make_string(lib_name, strlen(lib_name));
+ tmp = (*func)(obj, dl);
+ unref(tmp);
+ unref(obj);
+ tmp = NULL;
+ } else
+ tmp = (*func)(obj, dl);
+
+ s->fini_func = (void (*)(void)) dlsym(dl, fini_func);
+ return tmp;
+}
+
- func = (NODE *(*)(NODE *, void *)) dlsym(dl, fun->stptr);
- if (func == NULL) {
- msg(_("fatal: extension: library `%s': cannot call function `%s' (%s)\n"),
- obj->stptr, fun->stptr, dlerror());
- fatal_error = TRUE;
- goto done;
+/* make_builtin --- register name to be called as func with a builtin body */
+
+awk_bool_t
+make_builtin(const awk_ext_func_t *funcinfo)
+{
+ NODE *symbol, *f;
+ INSTRUCTION *b;
+ const char *sp;
+ char c;
+ const char *name = funcinfo->name;
+ int count = funcinfo->num_expected_args;
+
+ sp = name;
+ if (sp == NULL || *sp == '\0')
+ fatal(_("make_builtin: missing function name"));
+
+ if (! is_letter(*sp))
+ return awk_false;
+
+ for (sp++; (c = *sp++) != '\0';) {
+ if (! is_identchar(c))
+ return awk_false;
}
- tmp = (*func)(obj, dl);
- if (tmp == NULL)
- tmp = dupnode(Nnull_string);
-done:
- DEREF(obj);
- DEREF(fun);
- if (fatal_error)
- gawk_exit(EXIT_FATAL);
- return tmp;
-}
+ f = lookup(name);
+
+ if (f != NULL) {
+ if (f->type == Node_func) {
+ /* user-defined function */
+ fatal(_("make_builtin: can't redefine function `%s'"), name);
+ } else if (f->type == Node_ext_func) {
+ /* multiple extension() calls etc. */
+ if (do_lint)
+ lintwarn(_("make_builtin: function `%s' already defined"), name);
+ return awk_false;
+ } else
+ /* variable name etc. */
+ fatal(_("make_builtin: function name `%s' previously defined"), name);
+ } else if (check_special(name) >= 0)
+ fatal(_("make_builtin: can't use gawk built-in `%s' as function name"), name);
+ if (count < 0)
+ fatal(_("make_builtin: negative argument count for function `%s'"),
+ name);
-/* make_builtin --- register name to be called as func with a builtin body */
+ b = bcalloc(Op_symbol, 1, 0);
+ b->extfunc = funcinfo->function;
+ b->expr_count = count;
+
+ /* NB: extension sub must return something */
+
+ symbol = install_symbol(estrdup(name, strlen(name)), Node_ext_func);
+ symbol->code_ptr = b;
+ track_ext_func(name);
+ return awk_true;
+}
+
+/* make_old_builtin --- register name to be called as func with a builtin body */
void
-make_builtin(const char *name, NODE *(*func)(int), int count)
+make_old_builtin(const char *name, NODE *(*func)(int), int count) /* temporary */
{
NODE *symbol, *f;
INSTRUCTION *b;
@@ -120,9 +251,11 @@ make_builtin(const char *name, NODE *(*func)(int), int count)
if (sp == NULL || *sp == '\0')
fatal(_("extension: missing function name"));
- while ((c = *sp++) != '\0') {
- if ((sp == &name[1] && c != '_' && ! isalpha((unsigned char) c))
- || (sp > &name[1] && ! is_identchar((unsigned char) c)))
+ if (! is_letter(*sp))
+ fatal(_("extension: illegal character `%c' in function name `%s'"), *sp, name);
+
+ for (sp++; (c = *sp++) != '\0';) {
+ if (! is_identchar(c))
fatal(_("extension: illegal character `%c' in function name `%s'"), c, name);
}
@@ -153,8 +286,9 @@ make_builtin(const char *name, NODE *(*func)(int), int count)
/* NB: extension sub must return something */
- symbol = install_symbol(estrdup(name, strlen(name)), Node_ext_func);
+ symbol = install_symbol(estrdup(name, strlen(name)), Node_old_ext_func);
symbol->code_ptr = b;
+ track_ext_func(name);
}
@@ -173,10 +307,20 @@ get_argument(int i)
if (i < 0 || i >= pcount || i >= arg_count)
return NULL;
- i++;
- t = PEEK(i);
- if (t->type == Node_array_ref)
- t = t->orig_array;
+
+ t = PEEK(arg_count - i);
+ if (t->type == Node_param_list)
+ t = GET_PARAM(t->param_cnt);
+
+ if (t->type == Node_array_ref) {
+ if (t->orig_array->type == Node_var) {
+ /* already a scalar, can no longer use it as array */
+ t->type = Node_var;
+ t->var_value = Nnull_string;
+ return t;
+ }
+ return t->orig_array; /* Node_var_new or Node_var_array */
+ }
if (t->type == Node_var) /* See Case Node_var in setup_frame(), eval.c */
return Nnull_string;
/* Node_var_new, Node_var_array or Node_val */
@@ -184,12 +328,13 @@ get_argument(int i)
}
-/* get_actual_argument --- get the i'th scalar or array argument of a
- dynamically linked function, allowed to be optional.
-*/
+/*
+ * get_actual_argument --- get the i'th scalar or array argument of a
+ * dynamically linked function, allowed to be optional.
+ */
NODE *
-get_actual_argument(int i, int optional, int want_array)
+get_actual_argument(int i, bool optional, bool want_array)
{
NODE *t;
char *fname;
@@ -213,7 +358,7 @@ get_actual_argument(int i, int optional, int want_array)
if (t->type == Node_var_new) {
if (want_array)
- return get_array(t, FALSE);
+ return force_array(t, false);
else {
t->type = Node_var;
t->var_value = dupnode(Nnull_string);
@@ -236,15 +381,26 @@ get_actual_argument(int i, int optional, int want_array)
#else
-/* do_ext --- dummy version if extensions not available */
+/* load_ext --- dummy version if extensions not available */
-NODE *
-do_ext(int nargs)
+void
+load_ext(const char *lib_name)
{
- const char *emsg = _("Operation Not Supported");
-
- unref(ERRNO_node->var_value);
- ERRNO_node->var_value = make_string(emsg, strlen(emsg));
- return make_number((AWKNUM) -1);
+ fatal(_("dynamic loading of library not supported"));
}
#endif
+
+/* close_extensions --- execute extension cleanup routines */
+
+void
+close_extensions()
+{
+ SRCFILE *s;
+
+ if (srcfiles == NULL)
+ return;
+
+ for (s = srcfiles->next; s != srcfiles; s = s->next)
+ if (s->stype == SRC_EXTLIB && s->fini_func)
+ (*s->fini_func)();
+}
diff --git a/extension/.gitignore b/extension/.gitignore
new file mode 100644
index 00000000..ee95901f
--- /dev/null
+++ b/extension/.gitignore
@@ -0,0 +1,3 @@
+# ignore files created by libtool
+*.l[oa]
+.libs
diff --git a/extension/ABOUT-NLS b/extension/ABOUT-NLS
new file mode 100644
index 00000000..b1de1b68
--- /dev/null
+++ b/extension/ABOUT-NLS
@@ -0,0 +1,1282 @@
+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.
+
+1.1 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. Installers may use special
+options at configuration time for changing the default behaviour. The
+command:
+
+ ./configure --disable-nls
+
+will _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' library
+and will decide to use it. If not, you may have to to use the
+`--with-libintl-prefix' option to tell `configure' where to look for it.
+
+ 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.2 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. If you happen to have the `LC_ALL' or some other
+`LC_xxx' environment variables set, you should unset them before
+setting `LANG', otherwise the setting of `LANG' will not have the
+desired effect. 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 language 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.3 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://translationproject.org/', in the "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 `coordinator@translationproject.org' 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 skills are praised more than
+programming skills, here.
+
+1.4 Available Packages
+======================
+
+Languages are not equally supported in all packages. The following
+matrix shows the current state of internationalization, as of June
+2010. 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 an ar as ast az be be@latin bg bn_IN bs ca
+ +--------------------------------------------------+
+ a2ps | [] [] |
+ aegis | |
+ ant-phone | |
+ anubis | |
+ aspell | [] [] |
+ bash | |
+ bfd | |
+ bibshelf | [] |
+ binutils | |
+ bison | |
+ bison-runtime | [] |
+ bluez-pin | [] [] |
+ bombono-dvd | |
+ buzztard | |
+ cflow | |
+ clisp | |
+ coreutils | [] [] |
+ cpio | |
+ cppi | |
+ cpplib | [] |
+ cryptsetup | |
+ dfarc | |
+ dialog | [] [] |
+ dico | |
+ diffutils | [] |
+ dink | |
+ doodle | |
+ e2fsprogs | [] |
+ enscript | [] |
+ exif | |
+ fetchmail | [] |
+ findutils | [] |
+ flex | [] |
+ freedink | |
+ gas | |
+ gawk | [] [] |
+ gcal | [] |
+ gcc | |
+ gettext-examples | [] [] [] [] |
+ gettext-runtime | [] [] |
+ gettext-tools | [] [] |
+ gip | [] |
+ gjay | |
+ gliv | [] |
+ glunarclock | [] [] |
+ gnubiff | |
+ gnucash | [] |
+ gnuedu | |
+ gnulib | |
+ gnunet | |
+ gnunet-gtk | |
+ gnutls | |
+ gold | |
+ gpe-aerial | |
+ gpe-beam | |
+ gpe-bluetooth | |
+ gpe-calendar | |
+ gpe-clock | [] |
+ gpe-conf | |
+ gpe-contacts | |
+ gpe-edit | |
+ gpe-filemanager | |
+ gpe-go | |
+ gpe-login | |
+ gpe-ownerinfo | [] |
+ gpe-package | |
+ gpe-sketchbook | |
+ gpe-su | [] |
+ gpe-taskmanager | [] |
+ gpe-timesheet | [] |
+ gpe-today | [] |
+ gpe-todo | |
+ gphoto2 | |
+ gprof | [] |
+ gpsdrive | |
+ gramadoir | |
+ grep | |
+ grub | [] [] |
+ gsasl | |
+ gss | |
+ gst-plugins-bad | [] |
+ gst-plugins-base | [] |
+ gst-plugins-good | [] |
+ gst-plugins-ugly | [] |
+ gstreamer | [] [] [] |
+ gtick | |
+ gtkam | [] |
+ gtkorphan | [] |
+ gtkspell | [] [] [] |
+ gutenprint | |
+ hello | [] |
+ help2man | |
+ hylafax | |
+ idutils | |
+ indent | [] [] |
+ iso_15924 | |
+ iso_3166 | [] [] [] [] [] [] [] |
+ iso_3166_2 | |
+ iso_4217 | |
+ iso_639 | [] [] [] [] |
+ iso_639_3 | |
+ jwhois | |
+ kbd | |
+ keytouch | [] |
+ keytouch-editor | |
+ keytouch-keyboa... | [] |
+ klavaro | [] |
+ latrine | |
+ ld | [] |
+ leafpad | [] [] |
+ libc | [] [] |
+ libexif | () |
+ libextractor | |
+ libgnutls | |
+ libgpewidget | |
+ libgpg-error | |
+ libgphoto2 | |
+ libgphoto2_port | |
+ libgsasl | |
+ libiconv | [] |
+ libidn | |
+ lifelines | |
+ liferea | [] [] |
+ lilypond | |
+ linkdr | [] |
+ lordsawar | |
+ lprng | |
+ lynx | [] |
+ m4 | |
+ mailfromd | |
+ mailutils | |
+ make | |
+ man-db | |
+ man-db-manpages | |
+ minicom | |
+ mkisofs | |
+ myserver | |
+ nano | [] [] |
+ opcodes | |
+ parted | |
+ pies | |
+ popt | |
+ psmisc | |
+ pspp | [] |
+ pwdutils | |
+ radius | [] |
+ recode | [] [] |
+ rosegarden | |
+ rpm | |
+ rush | |
+ sarg | |
+ screem | |
+ scrollkeeper | [] [] [] |
+ sed | [] [] |
+ sharutils | [] [] |
+ shishi | |
+ skencil | |
+ solfege | |
+ solfege-manual | |
+ soundtracker | |
+ sp | |
+ sysstat | |
+ tar | [] |
+ texinfo | |
+ tin | |
+ unicode-han-tra... | |
+ unicode-transla... | |
+ util-linux-ng | [] |
+ vice | |
+ vmm | |
+ vorbis-tools | |
+ wastesedge | |
+ wdiff | |
+ wget | [] [] |
+ wyslij-po | |
+ xchat | [] [] [] [] |
+ xdg-user-dirs | [] [] [] [] [] [] [] [] [] |
+ xkeyboard-config | [] [] |
+ +--------------------------------------------------+
+ af am an ar as ast az be be@latin bg bn_IN bs ca
+ 6 0 1 2 3 19 1 10 3 28 3 1 38
+
+ crh cs da de el en en_GB en_ZA eo es et eu fa
+ +-------------------------------------------------+
+ a2ps | [] [] [] [] [] [] [] |
+ aegis | [] [] [] |
+ ant-phone | [] () |
+ anubis | [] [] |
+ aspell | [] [] [] [] [] |
+ bash | [] [] [] |
+ bfd | [] |
+ bibshelf | [] [] [] |
+ binutils | [] |
+ bison | [] [] |
+ bison-runtime | [] [] [] [] |
+ bluez-pin | [] [] [] [] [] [] |
+ bombono-dvd | [] |
+ buzztard | [] [] [] |
+ cflow | [] [] |
+ clisp | [] [] [] [] |
+ coreutils | [] [] [] [] |
+ cpio | |
+ cppi | |
+ cpplib | [] [] [] |
+ cryptsetup | [] |
+ dfarc | [] [] [] |
+ dialog | [] [] [] [] [] |
+ dico | |
+ diffutils | [] [] [] [] [] [] |
+ dink | [] [] [] |
+ doodle | [] |
+ e2fsprogs | [] [] [] |
+ enscript | [] [] [] |
+ exif | () [] [] |
+ fetchmail | [] [] () [] [] [] |
+ findutils | [] [] [] |
+ flex | [] [] |
+ freedink | [] [] [] |
+ gas | [] |
+ gawk | [] [] [] |
+ gcal | [] |
+ gcc | [] [] |
+ gettext-examples | [] [] [] [] |
+ gettext-runtime | [] [] [] [] |
+ gettext-tools | [] [] [] |
+ gip | [] [] [] [] |
+ gjay | [] |
+ gliv | [] [] [] |
+ glunarclock | [] [] |
+ gnubiff | () |
+ gnucash | [] () () () () |
+ gnuedu | [] [] |
+ gnulib | [] [] |
+ gnunet | |
+ gnunet-gtk | [] |
+ gnutls | [] [] |
+ gold | [] |
+ gpe-aerial | [] [] [] [] |
+ gpe-beam | [] [] [] [] |
+ gpe-bluetooth | [] [] |
+ gpe-calendar | [] |
+ gpe-clock | [] [] [] [] |
+ gpe-conf | [] [] [] |
+ gpe-contacts | [] [] [] |
+ gpe-edit | [] [] |
+ gpe-filemanager | [] [] [] |
+ gpe-go | [] [] [] [] |
+ gpe-login | [] [] |
+ gpe-ownerinfo | [] [] [] [] |
+ gpe-package | [] [] [] |
+ gpe-sketchbook | [] [] [] [] |
+ gpe-su | [] [] [] [] |
+ gpe-taskmanager | [] [] [] [] |
+ gpe-timesheet | [] [] [] [] |
+ gpe-today | [] [] [] [] |
+ gpe-todo | [] [] [] |
+ gphoto2 | [] [] () [] [] [] |
+ gprof | [] [] [] |
+ gpsdrive | [] [] [] |
+ gramadoir | [] [] [] |
+ grep | [] |
+ grub | [] [] |
+ gsasl | [] |
+ gss | |
+ gst-plugins-bad | [] [] [] [] [] |
+ gst-plugins-base | [] [] [] [] [] |
+ gst-plugins-good | [] [] [] [] [] [] |
+ gst-plugins-ugly | [] [] [] [] [] [] |
+ gstreamer | [] [] [] [] [] |
+ gtick | [] () [] |
+ gtkam | [] [] () [] [] |
+ gtkorphan | [] [] [] [] |
+ gtkspell | [] [] [] [] [] [] [] |
+ gutenprint | [] [] [] |
+ hello | [] [] [] [] |
+ help2man | [] |
+ hylafax | [] [] |
+ idutils | [] [] |
+ indent | [] [] [] [] [] [] [] |
+ iso_15924 | [] () [] [] |
+ iso_3166 | [] [] [] [] () [] [] [] () |
+ iso_3166_2 | () |
+ iso_4217 | [] [] [] () [] [] |
+ iso_639 | [] [] [] [] () [] [] |
+ iso_639_3 | [] |
+ jwhois | [] |
+ kbd | [] [] [] [] [] |
+ keytouch | [] [] |
+ keytouch-editor | [] [] |
+ keytouch-keyboa... | [] |
+ klavaro | [] [] [] [] |
+ latrine | [] () |
+ ld | [] [] |
+ leafpad | [] [] [] [] [] [] |
+ libc | [] [] [] [] |
+ libexif | [] [] () |
+ libextractor | |
+ libgnutls | [] |
+ libgpewidget | [] [] |
+ libgpg-error | [] [] |
+ libgphoto2 | [] () |
+ libgphoto2_port | [] () [] |
+ libgsasl | |
+ libiconv | [] [] [] [] [] |
+ libidn | [] [] [] |
+ lifelines | [] () |
+ liferea | [] [] [] [] [] |
+ lilypond | [] [] [] |
+ linkdr | [] [] [] |
+ lordsawar | [] |
+ lprng | |
+ lynx | [] [] [] [] |
+ m4 | [] [] [] [] |
+ mailfromd | |
+ mailutils | [] |
+ make | [] [] [] |
+ man-db | |
+ man-db-manpages | |
+ minicom | [] [] [] [] |
+ mkisofs | |
+ myserver | |
+ nano | [] [] [] |
+ opcodes | [] [] |
+ parted | [] [] |
+ pies | |
+ popt | [] [] [] [] [] |
+ psmisc | [] [] [] |
+ pspp | [] |
+ pwdutils | [] |
+ radius | [] |
+ recode | [] [] [] [] [] [] |
+ rosegarden | () () () |
+ rpm | [] [] [] |
+ rush | |
+ sarg | |
+ screem | |
+ scrollkeeper | [] [] [] [] [] |
+ sed | [] [] [] [] [] [] |
+ sharutils | [] [] [] [] |
+ shishi | |
+ skencil | [] () [] |
+ solfege | [] [] [] |
+ solfege-manual | [] [] |
+ soundtracker | [] [] [] |
+ sp | [] |
+ sysstat | [] [] [] |
+ tar | [] [] [] [] |
+ texinfo | [] [] [] |
+ tin | [] [] |
+ unicode-han-tra... | |
+ unicode-transla... | |
+ util-linux-ng | [] [] [] [] |
+ vice | () () |
+ vmm | [] |
+ vorbis-tools | [] [] |
+ wastesedge | [] |
+ wdiff | [] [] |
+ wget | [] [] [] |
+ wyslij-po | |
+ xchat | [] [] [] [] [] |
+ xdg-user-dirs | [] [] [] [] [] [] [] [] [] |
+ xkeyboard-config | [] [] [] [] [] [] |
+ +-------------------------------------------------+
+ crh cs da de el en en_GB en_ZA eo es et eu fa
+ 5 64 105 117 18 1 8 0 28 89 18 19 0
+
+ fi fr ga gl gu he hi hr hu hy id is it ja ka kn
+ +----------------------------------------------------+
+ a2ps | [] [] [] [] |
+ aegis | [] [] |
+ ant-phone | [] [] |
+ anubis | [] [] [] [] |
+ aspell | [] [] [] [] |
+ bash | [] [] [] [] |
+ bfd | [] [] [] |
+ bibshelf | [] [] [] [] [] |
+ binutils | [] [] [] |
+ bison | [] [] [] [] |
+ bison-runtime | [] [] [] [] [] [] |
+ bluez-pin | [] [] [] [] [] [] [] [] |
+ bombono-dvd | [] |
+ buzztard | [] |
+ cflow | [] [] [] |
+ clisp | [] |
+ coreutils | [] [] [] [] [] |
+ cpio | [] [] [] [] |
+ cppi | [] [] |
+ cpplib | [] [] [] |
+ cryptsetup | [] [] [] |
+ dfarc | [] [] [] |
+ dialog | [] [] [] [] [] [] [] |
+ dico | |
+ diffutils | [] [] [] [] [] [] [] [] [] |
+ dink | [] |
+ doodle | [] [] |
+ e2fsprogs | [] [] |
+ enscript | [] [] [] [] |
+ exif | [] [] [] [] [] [] |
+ fetchmail | [] [] [] [] |
+ findutils | [] [] [] [] [] [] |
+ flex | [] [] [] |
+ freedink | [] [] [] |
+ gas | [] [] |
+ gawk | [] [] [] [] () [] |
+ gcal | [] |
+ gcc | [] |
+ gettext-examples | [] [] [] [] [] [] [] |
+ gettext-runtime | [] [] [] [] [] [] |
+ gettext-tools | [] [] [] [] |
+ gip | [] [] [] [] [] [] |
+ gjay | [] |
+ gliv | [] () |
+ glunarclock | [] [] [] [] |
+ gnubiff | () [] () |
+ gnucash | () () () () () [] |
+ gnuedu | [] [] |
+ gnulib | [] [] [] [] [] [] |
+ gnunet | |
+ gnunet-gtk | [] |
+ gnutls | [] [] |
+ gold | [] [] |
+ gpe-aerial | [] [] [] |
+ gpe-beam | [] [] [] [] |
+ gpe-bluetooth | [] [] [] [] |
+ gpe-calendar | [] [] |
+ gpe-clock | [] [] [] [] [] |
+ gpe-conf | [] [] [] [] |
+ gpe-contacts | [] [] [] [] |
+ gpe-edit | [] [] [] |
+ gpe-filemanager | [] [] [] [] |
+ gpe-go | [] [] [] [] [] |
+ gpe-login | [] [] [] |
+ gpe-ownerinfo | [] [] [] [] [] |
+ gpe-package | [] [] [] |
+ gpe-sketchbook | [] [] [] [] |
+ gpe-su | [] [] [] [] [] [] |
+ gpe-taskmanager | [] [] [] [] [] |
+ gpe-timesheet | [] [] [] [] [] |
+ gpe-today | [] [] [] [] [] [] [] |
+ gpe-todo | [] [] [] |
+ gphoto2 | [] [] [] [] [] [] |
+ gprof | [] [] [] [] |
+ gpsdrive | [] [] [] |
+ gramadoir | [] [] [] |
+ grep | [] [] |
+ grub | [] [] [] [] |
+ gsasl | [] [] [] [] [] |
+ gss | [] [] [] [] [] |
+ gst-plugins-bad | [] [] [] [] [] [] |
+ gst-plugins-base | [] [] [] [] [] [] |
+ gst-plugins-good | [] [] [] [] [] [] |
+ gst-plugins-ugly | [] [] [] [] [] [] |
+ gstreamer | [] [] [] [] [] |
+ gtick | [] [] [] [] [] |
+ gtkam | [] [] [] [] [] |
+ gtkorphan | [] [] [] |
+ gtkspell | [] [] [] [] [] [] [] [] [] |
+ gutenprint | [] [] [] [] |
+ hello | [] [] [] |
+ help2man | [] [] |
+ hylafax | [] |
+ idutils | [] [] [] [] [] [] |
+ indent | [] [] [] [] [] [] [] [] |
+ iso_15924 | [] () [] [] |
+ iso_3166 | [] () [] [] [] [] [] [] [] [] [] [] |
+ iso_3166_2 | () [] [] [] |
+ iso_4217 | [] () [] [] [] [] |
+ iso_639 | [] () [] [] [] [] [] [] [] |
+ iso_639_3 | () [] [] |
+ jwhois | [] [] [] [] [] |
+ kbd | [] [] |
+ keytouch | [] [] [] [] [] [] |
+ keytouch-editor | [] [] [] [] [] |
+ keytouch-keyboa... | [] [] [] [] [] |
+ klavaro | [] [] |
+ latrine | [] [] [] |
+ ld | [] [] [] [] |
+ leafpad | [] [] [] [] [] [] [] () |
+ libc | [] [] [] [] [] |
+ libexif | [] |
+ libextractor | |
+ libgnutls | [] [] |
+ libgpewidget | [] [] [] [] |
+ libgpg-error | [] [] |
+ libgphoto2 | [] [] [] |
+ libgphoto2_port | [] [] [] |
+ libgsasl | [] [] [] [] [] |
+ libiconv | [] [] [] [] [] [] |
+ libidn | [] [] [] [] |
+ lifelines | () |
+ liferea | [] [] [] [] |
+ lilypond | [] [] |
+ linkdr | [] [] [] [] [] |
+ lordsawar | |
+ lprng | [] |
+ lynx | [] [] [] [] [] |
+ m4 | [] [] [] [] [] [] |
+ mailfromd | |
+ mailutils | [] [] |
+ make | [] [] [] [] [] [] [] [] [] |
+ man-db | [] [] |
+ man-db-manpages | [] |
+ minicom | [] [] [] [] [] |
+ mkisofs | [] [] [] [] |
+ myserver | |
+ nano | [] [] [] [] [] [] |
+ opcodes | [] [] [] [] |
+ parted | [] [] [] [] |
+ pies | |
+ popt | [] [] [] [] [] [] [] [] [] |
+ psmisc | [] [] [] |
+ pspp | |
+ pwdutils | [] [] |
+ radius | [] [] |
+ recode | [] [] [] [] [] [] [] [] |
+ rosegarden | () () () () () |
+ rpm | [] [] |
+ rush | |
+ sarg | [] |
+ screem | [] [] |
+ scrollkeeper | [] [] [] [] |
+ sed | [] [] [] [] [] [] [] [] |
+ sharutils | [] [] [] [] [] [] [] |
+ shishi | [] |
+ skencil | [] |
+ solfege | [] [] [] [] |
+ solfege-manual | [] [] |
+ soundtracker | [] [] |
+ sp | [] () |
+ sysstat | [] [] [] [] [] |
+ tar | [] [] [] [] [] [] [] |
+ texinfo | [] [] [] [] |
+ tin | [] |
+ unicode-han-tra... | |
+ unicode-transla... | [] [] |
+ util-linux-ng | [] [] [] [] [] [] |
+ vice | () () () |
+ vmm | [] |
+ vorbis-tools | [] |
+ wastesedge | () () |
+ wdiff | [] |
+ wget | [] [] [] [] [] [] [] [] |
+ wyslij-po | [] [] [] |
+ xchat | [] [] [] [] [] [] [] [] [] |
+ xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] [] [] [] |
+ xkeyboard-config | [] [] [] [] [] |
+ +----------------------------------------------------+
+ fi fr ga gl gu he hi hr hu hy id is it ja ka kn
+ 105 121 53 20 4 8 3 5 53 2 120 5 84 67 0 4
+
+ ko ku ky lg lt lv mk ml mn mr ms mt nb nds ne
+ +-----------------------------------------------+
+ a2ps | [] |
+ aegis | |
+ ant-phone | |
+ anubis | [] [] |
+ aspell | [] |
+ bash | |
+ bfd | |
+ bibshelf | [] [] |
+ binutils | |
+ bison | [] |
+ bison-runtime | [] [] [] [] [] |
+ bluez-pin | [] [] [] [] [] |
+ bombono-dvd | |
+ buzztard | |
+ cflow | |
+ clisp | |
+ coreutils | [] |
+ cpio | |
+ cppi | |
+ cpplib | |
+ cryptsetup | |
+ dfarc | [] |
+ dialog | [] [] [] [] [] |
+ dico | |
+ diffutils | [] [] |
+ dink | |
+ doodle | |
+ e2fsprogs | |
+ enscript | |
+ exif | [] |
+ fetchmail | |
+ findutils | |
+ flex | |
+ freedink | [] |
+ gas | |
+ gawk | |
+ gcal | |
+ gcc | |
+ gettext-examples | [] [] [] [] |
+ gettext-runtime | [] |
+ gettext-tools | [] |
+ gip | [] [] |
+ gjay | |
+ gliv | |
+ glunarclock | [] |
+ gnubiff | |
+ gnucash | () () () () |
+ gnuedu | |
+ gnulib | |
+ gnunet | |
+ gnunet-gtk | |
+ gnutls | [] |
+ gold | |
+ gpe-aerial | [] |
+ gpe-beam | [] |
+ gpe-bluetooth | [] [] |
+ gpe-calendar | [] |
+ gpe-clock | [] [] [] [] [] |
+ gpe-conf | [] [] |
+ gpe-contacts | [] [] |
+ gpe-edit | [] |
+ gpe-filemanager | [] [] |
+ gpe-go | [] [] [] |
+ gpe-login | [] |
+ gpe-ownerinfo | [] [] |
+ gpe-package | [] [] |
+ gpe-sketchbook | [] [] |
+ gpe-su | [] [] [] [] [] [] |
+ gpe-taskmanager | [] [] [] [] [] [] |
+ gpe-timesheet | [] [] |
+ gpe-today | [] [] [] [] |
+ gpe-todo | [] [] |
+ gphoto2 | |
+ gprof | [] |
+ gpsdrive | |
+ gramadoir | |
+ grep | |
+ grub | |
+ gsasl | |
+ gss | |
+ gst-plugins-bad | [] [] [] [] |
+ gst-plugins-base | [] [] |
+ gst-plugins-good | [] [] |
+ gst-plugins-ugly | [] [] [] [] [] |
+ gstreamer | |
+ gtick | |
+ gtkam | [] |
+ gtkorphan | [] [] |
+ gtkspell | [] [] [] [] [] [] [] |
+ gutenprint | |
+ hello | [] [] [] |
+ help2man | |
+ hylafax | |
+ idutils | |
+ indent | |
+ iso_15924 | [] [] |
+ iso_3166 | [] [] () [] [] [] [] [] |
+ iso_3166_2 | |
+ iso_4217 | [] [] |
+ iso_639 | [] [] |
+ iso_639_3 | [] |
+ jwhois | [] |
+ kbd | |
+ keytouch | [] |
+ keytouch-editor | [] |
+ keytouch-keyboa... | [] |
+ klavaro | [] |
+ latrine | [] |
+ ld | |
+ leafpad | [] [] [] |
+ libc | [] |
+ libexif | |
+ libextractor | |
+ libgnutls | [] |
+ libgpewidget | [] [] |
+ libgpg-error | |
+ libgphoto2 | |
+ libgphoto2_port | |
+ libgsasl | |
+ libiconv | |
+ libidn | |
+ lifelines | |
+ liferea | |
+ lilypond | |
+ linkdr | |
+ lordsawar | |
+ lprng | |
+ lynx | |
+ m4 | |
+ mailfromd | |
+ mailutils | |
+ make | [] |
+ man-db | |
+ man-db-manpages | |
+ minicom | [] |
+ mkisofs | |
+ myserver | |
+ nano | [] [] |
+ opcodes | |
+ parted | |
+ pies | |
+ popt | [] [] [] |
+ psmisc | |
+ pspp | |
+ pwdutils | |
+ radius | |
+ recode | |
+ rosegarden | |
+ rpm | |
+ rush | |
+ sarg | |
+ screem | |
+ scrollkeeper | [] [] |
+ sed | |
+ sharutils | |
+ shishi | |
+ skencil | |
+ solfege | [] |
+ solfege-manual | |
+ soundtracker | |
+ sp | |
+ sysstat | [] |
+ tar | [] |
+ texinfo | [] |
+ tin | |
+ unicode-han-tra... | |
+ unicode-transla... | |
+ util-linux-ng | |
+ vice | |
+ vmm | |
+ vorbis-tools | |
+ wastesedge | |
+ wdiff | |
+ wget | [] |
+ wyslij-po | |
+ xchat | [] [] [] |
+ xdg-user-dirs | [] [] [] [] [] [] [] [] |
+ xkeyboard-config | [] [] [] |
+ +-----------------------------------------------+
+ ko ku ky lg lt lv mk ml mn mr ms mt nb nds ne
+ 20 5 10 1 13 48 4 2 2 4 24 10 20 3 1
+
+ nl nn or pa pl ps pt pt_BR ro ru rw sk sl sq sr
+ +---------------------------------------------------+
+ a2ps | [] [] [] [] [] [] [] [] |
+ aegis | [] [] [] |
+ ant-phone | [] [] |
+ anubis | [] [] [] |
+ aspell | [] [] [] [] [] |
+ bash | [] [] |
+ bfd | [] |
+ bibshelf | [] [] |
+ binutils | [] [] |
+ bison | [] [] [] |
+ bison-runtime | [] [] [] [] [] [] [] |
+ bluez-pin | [] [] [] [] [] [] [] [] |
+ bombono-dvd | [] () |
+ buzztard | [] [] |
+ cflow | [] |
+ clisp | [] [] |
+ coreutils | [] [] [] [] [] [] |
+ cpio | [] [] [] |
+ cppi | [] |
+ cpplib | [] |
+ cryptsetup | [] |
+ dfarc | [] |
+ dialog | [] [] [] [] |
+ dico | [] |
+ diffutils | [] [] [] [] [] [] |
+ dink | () |
+ doodle | [] [] |
+ e2fsprogs | [] [] |
+ enscript | [] [] [] [] [] |
+ exif | [] [] [] () [] |
+ fetchmail | [] [] [] [] |
+ findutils | [] [] [] [] [] |
+ flex | [] [] [] [] [] |
+ freedink | [] [] |
+ gas | |
+ gawk | [] [] [] [] |
+ gcal | |
+ gcc | [] |
+ gettext-examples | [] [] [] [] [] [] [] [] |
+ gettext-runtime | [] [] [] [] [] [] [] [] [] |
+ gettext-tools | [] [] [] [] [] [] |
+ gip | [] [] [] [] [] |
+ gjay | |
+ gliv | [] [] [] [] [] [] |
+ glunarclock | [] [] [] [] [] |
+ gnubiff | [] () |
+ gnucash | [] () () () |
+ gnuedu | [] |
+ gnulib | [] [] [] [] |
+ gnunet | |
+ gnunet-gtk | |
+ gnutls | [] [] |
+ gold | |
+ gpe-aerial | [] [] [] [] [] [] [] |
+ gpe-beam | [] [] [] [] [] [] [] |
+ gpe-bluetooth | [] [] |
+ gpe-calendar | [] [] [] [] |
+ gpe-clock | [] [] [] [] [] [] [] [] |
+ gpe-conf | [] [] [] [] [] [] [] |
+ gpe-contacts | [] [] [] [] [] |
+ gpe-edit | [] [] [] |
+ gpe-filemanager | [] [] [] |
+ gpe-go | [] [] [] [] [] [] [] [] |
+ gpe-login | [] [] |
+ gpe-ownerinfo | [] [] [] [] [] [] [] [] |
+ gpe-package | [] [] |
+ gpe-sketchbook | [] [] [] [] [] [] [] |
+ gpe-su | [] [] [] [] [] [] [] [] |
+ gpe-taskmanager | [] [] [] [] [] [] [] [] |
+ gpe-timesheet | [] [] [] [] [] [] [] [] |
+ gpe-today | [] [] [] [] [] [] [] [] |
+ gpe-todo | [] [] [] [] [] |
+ gphoto2 | [] [] [] [] [] [] [] [] |
+ gprof | [] [] [] |
+ gpsdrive | [] [] |
+ gramadoir | [] [] |
+ grep | [] [] [] [] |
+ grub | [] [] [] |
+ gsasl | [] [] [] [] |
+ gss | [] [] [] |
+ gst-plugins-bad | [] [] [] [] [] [] |
+ gst-plugins-base | [] [] [] [] [] |
+ gst-plugins-good | [] [] [] [] [] |
+ gst-plugins-ugly | [] [] [] [] [] [] |
+ gstreamer | [] [] [] [] [] |
+ gtick | [] [] [] |
+ gtkam | [] [] [] [] [] [] |
+ gtkorphan | [] |
+ gtkspell | [] [] [] [] [] [] [] [] [] [] |
+ gutenprint | [] [] |
+ hello | [] [] [] [] |
+ help2man | [] [] |
+ hylafax | [] |
+ idutils | [] [] [] [] [] |
+ indent | [] [] [] [] [] [] [] |
+ iso_15924 | [] [] [] [] |
+ iso_3166 | [] [] [] [] [] () [] [] [] [] [] [] [] [] |
+ iso_3166_2 | [] [] [] |
+ iso_4217 | [] [] [] [] [] [] [] [] |
+ iso_639 | [] [] [] [] [] [] [] [] [] |
+ iso_639_3 | [] [] |
+ jwhois | [] [] [] [] |
+ kbd | [] [] [] |
+ keytouch | [] [] [] |
+ keytouch-editor | [] [] [] |
+ keytouch-keyboa... | [] [] [] |
+ klavaro | [] [] |
+ latrine | [] [] |
+ ld | |
+ leafpad | [] [] [] [] [] [] [] [] [] |
+ libc | [] [] [] [] |
+ libexif | [] [] () [] |
+ libextractor | |
+ libgnutls | [] [] |
+ libgpewidget | [] [] [] |
+ libgpg-error | [] [] |
+ libgphoto2 | [] [] |
+ libgphoto2_port | [] [] [] [] [] |
+ libgsasl | [] [] [] [] [] |
+ libiconv | [] [] [] [] [] |
+ libidn | [] [] |
+ lifelines | [] [] |
+ liferea | [] [] [] [] [] () () [] |
+ lilypond | [] |
+ linkdr | [] [] [] |
+ lordsawar | |
+ lprng | [] |
+ lynx | [] [] [] |
+ m4 | [] [] [] [] [] |
+ mailfromd | [] |
+ mailutils | [] |
+ make | [] [] [] [] |
+ man-db | [] [] [] |
+ man-db-manpages | [] [] [] |
+ minicom | [] [] [] [] |
+ mkisofs | [] [] [] |
+ myserver | |
+ nano | [] [] [] [] |
+ opcodes | [] [] |
+ parted | [] [] [] [] |
+ pies | [] |
+ popt | [] [] [] [] |
+ psmisc | [] [] [] |
+ pspp | [] [] |
+ pwdutils | [] |
+ radius | [] [] [] |
+ recode | [] [] [] [] [] [] [] [] |
+ rosegarden | () () |
+ rpm | [] [] [] |
+ rush | [] [] |
+ sarg | |
+ screem | |
+ scrollkeeper | [] [] [] [] [] [] [] [] |
+ sed | [] [] [] [] [] [] [] [] [] |
+ sharutils | [] [] [] [] |
+ shishi | [] |
+ skencil | [] [] |
+ solfege | [] [] [] [] |
+ solfege-manual | [] [] [] |
+ soundtracker | [] |
+ sp | |
+ sysstat | [] [] [] [] |
+ tar | [] [] [] [] |
+ texinfo | [] [] [] [] |
+ tin | [] |
+ unicode-han-tra... | |
+ unicode-transla... | |
+ util-linux-ng | [] [] [] [] [] |
+ vice | [] |
+ vmm | [] |
+ vorbis-tools | [] [] |
+ wastesedge | [] |
+ wdiff | [] [] |
+ wget | [] [] [] [] [] [] [] |
+ wyslij-po | [] [] [] |
+ xchat | [] [] [] [] [] [] [] [] [] |
+ xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] [] [] [] [] |
+ xkeyboard-config | [] [] [] |
+ +---------------------------------------------------+
+ nl nn or pa pl ps pt pt_BR ro ru rw sk sl sq sr
+ 135 10 4 7 105 1 29 62 47 91 3 54 46 9 37
+
+ sv sw ta te tg th tr uk vi wa zh_CN zh_HK zh_TW
+ +---------------------------------------------------+
+ a2ps | [] [] [] [] [] | 27
+ aegis | [] | 9
+ ant-phone | [] [] [] [] | 9
+ anubis | [] [] [] [] | 15
+ aspell | [] [] [] | 20
+ bash | [] [] [] | 12
+ bfd | [] | 6
+ bibshelf | [] [] [] | 16
+ binutils | [] [] | 8
+ bison | [] [] | 12
+ bison-runtime | [] [] [] [] [] [] | 29
+ bluez-pin | [] [] [] [] [] [] [] [] | 37
+ bombono-dvd | [] | 4
+ buzztard | [] | 7
+ cflow | [] [] [] | 9
+ clisp | | 10
+ coreutils | [] [] [] [] | 22
+ cpio | [] [] [] [] [] [] | 13
+ cppi | [] [] | 5
+ cpplib | [] [] [] [] [] [] | 14
+ cryptsetup | [] [] | 7
+ dfarc | [] | 9
+ dialog | [] [] [] [] [] [] [] | 30
+ dico | [] | 2
+ diffutils | [] [] [] [] [] [] | 30
+ dink | | 4
+ doodle | [] [] | 7
+ e2fsprogs | [] [] [] | 11
+ enscript | [] [] [] [] | 17
+ exif | [] [] [] | 16
+ fetchmail | [] [] [] | 17
+ findutils | [] [] [] [] [] | 20
+ flex | [] [] [] [] | 15
+ freedink | [] | 10
+ gas | [] | 4
+ gawk | [] [] [] [] | 18
+ gcal | [] [] | 5
+ gcc | [] [] [] | 7
+ gettext-examples | [] [] [] [] [] [] [] | 34
+ gettext-runtime | [] [] [] [] [] [] [] | 29
+ gettext-tools | [] [] [] [] [] [] | 22
+ gip | [] [] [] [] | 22
+ gjay | [] | 3
+ gliv | [] [] [] | 14
+ glunarclock | [] [] [] [] [] | 19
+ gnubiff | [] [] | 4
+ gnucash | () [] () [] () | 10
+ gnuedu | [] [] | 7
+ gnulib | [] [] [] [] | 16
+ gnunet | [] | 1
+ gnunet-gtk | [] [] [] | 5
+ gnutls | [] [] [] | 10
+ gold | [] | 4
+ gpe-aerial | [] [] [] | 18
+ gpe-beam | [] [] [] | 19
+ gpe-bluetooth | [] [] [] | 13
+ gpe-calendar | [] [] [] [] | 12
+ gpe-clock | [] [] [] [] [] | 28
+ gpe-conf | [] [] [] [] | 20
+ gpe-contacts | [] [] [] | 17
+ gpe-edit | [] [] [] | 12
+ gpe-filemanager | [] [] [] [] | 16
+ gpe-go | [] [] [] [] [] | 25
+ gpe-login | [] [] [] | 11
+ gpe-ownerinfo | [] [] [] [] [] | 25
+ gpe-package | [] [] [] | 13
+ gpe-sketchbook | [] [] [] | 20
+ gpe-su | [] [] [] [] [] | 30
+ gpe-taskmanager | [] [] [] [] [] | 29
+ gpe-timesheet | [] [] [] [] [] | 25
+ gpe-today | [] [] [] [] [] [] | 30
+ gpe-todo | [] [] [] [] | 17
+ gphoto2 | [] [] [] [] [] | 24
+ gprof | [] [] [] | 15
+ gpsdrive | [] [] [] | 11
+ gramadoir | [] [] [] | 11
+ grep | [] [] [] | 10
+ grub | [] [] [] | 14
+ gsasl | [] [] [] [] | 14
+ gss | [] [] [] | 11
+ gst-plugins-bad | [] [] [] [] | 26
+ gst-plugins-base | [] [] [] [] [] | 24
+ gst-plugins-good | [] [] [] [] | 24
+ gst-plugins-ugly | [] [] [] [] [] | 29
+ gstreamer | [] [] [] [] | 22
+ gtick | [] [] [] | 13
+ gtkam | [] [] [] | 20
+ gtkorphan | [] [] [] | 14
+ gtkspell | [] [] [] [] [] [] [] [] [] | 45
+ gutenprint | [] | 10
+ hello | [] [] [] [] [] [] | 21
+ help2man | [] [] | 7
+ hylafax | [] | 5
+ idutils | [] [] [] [] | 17
+ indent | [] [] [] [] [] [] | 30
+ iso_15924 | () [] () [] [] | 16
+ iso_3166 | [] [] () [] [] () [] [] [] () | 53
+ iso_3166_2 | () [] () [] | 9
+ iso_4217 | [] () [] [] () [] [] | 26
+ iso_639 | [] [] [] () [] () [] [] [] [] | 38
+ iso_639_3 | [] () | 8
+ jwhois | [] [] [] [] [] | 16
+ kbd | [] [] [] [] [] | 15
+ keytouch | [] [] [] | 16
+ keytouch-editor | [] [] [] | 14
+ keytouch-keyboa... | [] [] [] | 14
+ klavaro | [] | 11
+ latrine | [] [] [] | 10
+ ld | [] [] [] [] | 11
+ leafpad | [] [] [] [] [] [] | 33
+ libc | [] [] [] [] [] | 21
+ libexif | [] () | 7
+ libextractor | [] | 1
+ libgnutls | [] [] [] | 9
+ libgpewidget | [] [] [] | 14
+ libgpg-error | [] [] [] | 9
+ libgphoto2 | [] [] | 8
+ libgphoto2_port | [] [] [] [] | 14
+ libgsasl | [] [] [] | 13
+ libiconv | [] [] [] [] | 21
+ libidn | () [] [] | 11
+ lifelines | [] | 4
+ liferea | [] [] [] | 21
+ lilypond | [] | 7
+ linkdr | [] [] [] [] [] | 17
+ lordsawar | | 1
+ lprng | [] | 3
+ lynx | [] [] [] [] | 17
+ m4 | [] [] [] [] | 19
+ mailfromd | [] [] | 3
+ mailutils | [] | 5
+ make | [] [] [] [] | 21
+ man-db | [] [] [] | 8
+ man-db-manpages | | 4
+ minicom | [] [] | 16
+ mkisofs | [] [] | 9
+ myserver | | 0
+ nano | [] [] [] [] | 21
+ opcodes | [] [] [] | 11
+ parted | [] [] [] [] [] | 15
+ pies | [] [] | 3
+ popt | [] [] [] [] [] [] | 27
+ psmisc | [] [] | 11
+ pspp | | 4
+ pwdutils | [] [] | 6
+ radius | [] [] | 9
+ recode | [] [] [] [] | 28
+ rosegarden | () | 0
+ rpm | [] [] [] | 11
+ rush | [] [] | 4
+ sarg | | 1
+ screem | [] | 3
+ scrollkeeper | [] [] [] [] [] | 27
+ sed | [] [] [] [] [] | 30
+ sharutils | [] [] [] [] [] | 22
+ shishi | [] | 3
+ skencil | [] [] | 7
+ solfege | [] [] [] [] | 16
+ solfege-manual | [] | 8
+ soundtracker | [] [] [] | 9
+ sp | [] | 3
+ sysstat | [] [] | 15
+ tar | [] [] [] [] [] [] | 23
+ texinfo | [] [] [] [] [] | 17
+ tin | | 4
+ unicode-han-tra... | | 0
+ unicode-transla... | | 2
+ util-linux-ng | [] [] [] [] | 20
+ vice | () () | 1
+ vmm | [] | 4
+ vorbis-tools | [] | 6
+ wastesedge | | 2
+ wdiff | [] [] | 7
+ wget | [] [] [] [] [] | 26
+ wyslij-po | [] [] | 8
+ xchat | [] [] [] [] [] [] | 36
+ xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] | 63
+ xkeyboard-config | [] [] [] | 22
+ +---------------------------------------------------+
+ 85 teams sv sw ta te tg th tr uk vi wa zh_CN zh_HK zh_TW
+ 178 domains 119 1 3 3 0 10 65 51 155 17 98 7 41 2618
+
+ 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 June 2010 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://translationproject.org/extra/matrix.html'.
+
+1.5 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
+`coordinator@translationproject.org' to make the `.pot' files available
+to the translation teams.
+
diff --git a/extension/AUTHORS b/extension/AUTHORS
new file mode 100644
index 00000000..fa9e7fe1
--- /dev/null
+++ b/extension/AUTHORS
@@ -0,0 +1,13 @@
+ Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved.
+
+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.
diff --git a/extension/CMakeLists.txt b/extension/CMakeLists.txt
new file mode 100644
index 00000000..1bb4ceb1
--- /dev/null
+++ b/extension/CMakeLists.txt
@@ -0,0 +1,84 @@
+#
+# extension/CMakeLists.txt --- CMake input file for gawk
+#
+# Copyright (C) 2013
+# 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 3 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 CMake to produce Makefile
+
+# Remove the definition of GAWK because of gawkapi.h.
+remove_definitions(-DGAWK)
+
+MACRO(BuildExtension name sources)
+ add_library (${name} MODULE ${sources} ${ARGN})
+ target_link_libraries(${name} ${EXTRA_LIBS})
+ set_target_properties(${name} PROPERTIES PREFIX "")
+ install(PROGRAMS ${CMAKE_BINARY_DIR}/extension/${name}${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION lib)
+ENDMACRO(BuildExtension)
+
+if (${HAVE_STRUCT_STAT_ST_BLKSIZE})
+ BuildExtension(filefuncs filefuncs.c stack.c gawkfts.c)
+else()
+ message(STATUS "extension filefuncs cannot be built because HAVE_STRUCT_STAT_ST_BLKSIZE is missing")
+endif()
+
+if (HAVE_FNMATCH AND HAVE_FNMATCH_H)
+ BuildExtension(fnmatch fnmatch.c)
+else()
+ message(STATUS "extension fnmatch cannot be built because function fnmatch or fnmatch.h is missing")
+endif()
+
+if (${HAVE_SYS_WAIT_H})
+ BuildExtension(fork fork.c)
+else()
+ message(STATUS "extension fork cannot be built because HAVE_SYS_WAIT_H is missing")
+endif()
+
+if (${HAVE_MKSTEMP})
+ BuildExtension(inplace inplace.c)
+else()
+ message(STATUS "extension inplace cannot be built because HAVE_MKSTEMP is missing")
+endif()
+
+BuildExtension(ordchr ordchr.c)
+
+if (HAVE_DIRENT_H AND HAVE_DIRFD)
+ BuildExtension(readdir readdir.c)
+else()
+ message(STATUS "extension readdir cannot be built because function readdir is missing")
+endif()
+
+BuildExtension(readfile readfile.c)
+
+BuildExtension(revoutput revoutput.c)
+
+if (${HAVE_GETDTABLESIZE})
+ BuildExtension(revtwoway revtwoway.c)
+else()
+ message(STATUS "extension revtwoway cannot be built because function getdtablesize is missing")
+endif()
+
+BuildExtension(rwarray rwarray.c)
+
+BuildExtension(time time.c)
+
+BuildExtension(testext testext.c)
+
diff --git a/extension/COPYING b/extension/COPYING
new file mode 100644
index 00000000..94a9ed02
--- /dev/null
+++ b/extension/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. 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
+them 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 prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. 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.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey 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;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU 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 that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ 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.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+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.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ 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
+state 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 3 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, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program 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, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU 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. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/extension/ChangeLog b/extension/ChangeLog
index dff4cf67..582a3440 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,6 +1,966 @@
+2015-01-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.c (var_test): Adjust for PROCINFO now being there.
+
+2014-11-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * inplace.c (do_inplace_begin): Jump through hoops to silence
+ GCC warnings about return value of chown.
+
+2014-10-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (uninstall-so): Remove *.lib too, per suggestion
+ from Andreas Buening.
+
+2014-10-12 KO Myung-Hun <komh78@gmail.com>
+
+ Fixes for OS/2:
+
+ * Makefile.am (uninstall-so): Remove *.dll and *.a, also.
+
+2014-10-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * inplace.c (do_inplace_begin): Use a cast to void in front
+ of the second call to chown to avoid compiler warnings from clang.
+
+2014-09-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c: Minor edits to sync with documentation.
+ * testext.c: Add test to get PROCINFO, expected to fail.
+
+2014-08-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (RM): Define for makes that don't have it,
+ such as on OpenBSD. Thanks to Jeremie Courreges-Anglas
+ <jca@wxcvbn.org> for the report.
+
+2014-06-13 Paul Gortmaker <paul.gortmaker@windriver.com>
+
+ * Makefile.am (uninstall-so): Came across below bug while cross
+ compiling, and changed both install-data-hook and uninstall-so
+ to use $(DESTDIR) on v4.1.1 before seeing most of the fix in
+ gawk-4.1.1-3-g976f73ab0356; here we ensure uninstall-so also
+ uses the $(DESTDIR) prefix on its use of pkgextensiondir.
+
+2014-04-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (install-data-hook): Use $(DESTDIR) when removing
+ the .la files. Thanks to Lars Wendler <polynomial-c@gentoo.org>
+ for the report and fix.
+
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.1: Release tar ball made.
+
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Bump version before release.
+
+2014-04-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * time.c: Include <time.h> unconditionally to get declaration
+ of nanosleep on Linux. Avoids a warning. Thanks to Michal
+ Jaegermann.
+
+2014-03-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Remove -Wextra to avoid killing compilations
+ on older versions of gcc. Thanks to Antonio Diaz Diaz for
+ the report.
+
+2014-03-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Add AC_HEADER_TIME and AC_HEADER_DIRENT, and
+ rearrange order of macros some. May help on older systems.
+
+2014-03-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * readfile.c: Add an input parser that works off of
+ PROCINFO["readfile"].
+ * readfile.3am: Document same.
+
+2014-03-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkfts.c (MAXPATHLEN): Add a default definition. Thanks to
+ Antonio Diaz Dian and Nelson H.F. Beebe.
+ * readdir.c (PATH_MAX): Add a default definition. Thanks to
+ Nelson H.F. Beebe.
+
+2014-03-08 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * filefuncs.c (read_symlink, do_fts): Replace free with gawk_free.
+ * inplace.c (at_exit, do_inplace_end): Ditto.
+ * readdir.c (dir_close): Ditto.
+ * readfile.c (do_readfile): Ditto.
+ * revtwoway.c (close_two_proc_data): Ditto.
+ * rwarray.c (read_elem): Replace realloc with gawk_realloc.
+ (read_value): Replace malloc and free with gawk_malloc and gawk_free.
+ * testext.c (try_modify_environ): Replace free with gawk_free.
+
+2014-02-12 John E. Malmberg <wb8tyw@qsl.net>
+
+ * time.c: Better hack for nanosleep bug based on feedback from HP.
+
+2013-12-29 John E. Malmberg <wb8tyw@qsl.net>
+
+ * filefuncs.c: Fix compile on VMS.
+ * time.c: Fix compile on VMS.
+
+2013-12-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkfts.c: Wrap include of <sys/param.h> in HAVE_SYS_PARAM_H,
+ as I should have done to start with. For VMS.
+
+2013-12-29 John E. Malmberg <wb8tyw@qsl.net>
+
+ * gawkdirfd.h: Adjust include for VMS.
+ * filefuncs.c: Make it compile on VMS.
+ * fnmatch.c: Make it compile on VMS.
+
+2013-12-21 Mike Frysinger <vapier@gentoo.org>
+
+ * configure.ac: Remove MirBSD and OS/390 hack to create
+ do-nothing Makefile. Should be handled by configure in the
+ parent directory.
+
+2013-12-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure, aclocal.m4: Updated to automake 1.13.4 and
+ libtool 2.4.2.418.
+
+2013-11-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (uninstall-so, uninstall-recursive): Remove the
+ .so files. Keeps make distcheck happy.
+
+2013-11-17 Dmitry V. Levin <ldv@altlinux.org>
+
+ * Makefile.am (dist_man_MANS): Add inplace.3am.
+
+2013-10-23 Michael Haubenwallner <michael.haubenwallner@salomon.at>
+
+ Fix portability for AIX.
+
+ * inplace.c (_XOPEN_SOURCE): Define when not defined yet.
+ (_XOPEN_SOURCE_EXTENDED): Ditto. Needs to define a number.
+
+2013-08-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ Clean up some warnings from -Wextra.
+
+ * gawkfts.c (fts_set): Add cast to void for sp.
+ * inplace.c (at_exit): Add cast to void for data and exit_status.
+ * readdir.c (ftype): Add cast to void for dirname.
+ (dir_get_record): Assign NULL to *rt_start.
+ * revtwoway.c (rev2way_get_record): Add cast to void for errcode.
+ (rev2way_fwrite): Add cast to void for fp.
+ (rev2way_take_control_of): Add cast to void for name.
+ * testext.c (test_array_param, test_scalar, test_scalar_reserved,
+ test_indirect_vars): Add cast to void for nargs.
+
+2013-08-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkdirfd.h: Include ../nonposix.h to get FAKE_FD_VALUE.
+
+2013-08-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c: Change _WIN32 to __MINGW32__ globally, per
+ Eli Zaretskii.
+
+2013-08-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c (do_fts): Add a version for _WIN32 that prints a
+ "not supported" fatal message. This is slightly better than the
+ "fts not found" which is otherwise produced.
+
+2013-07-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkdirfd.h (FAKE_FD_VALUE): Move definition up in the file to give
+ clean compile on MinGW.
+
+2013-06-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac (AC_HEADER_MAJOR): New macro added.
+ Add check for limits.h header.
+ * filefuncs.c: Add the right stuff to get the major/minor macros.
+ * readdir.c: Add include of limits.h appropriately wrapped.
+
+ Thanks to ICHII Takashi <ichii386@schweetheart.jp> for the reports
+ and pointers.
+
+2013-06-01 Eli Zaretskii <eliz@gnu.org>
+
+ * filefuncs.c [_WIN32]: Define WIN32_LEAN_AND_MEAN before
+ including windows.h.
+
+ * readdir.c [__MINGW32__]: Define WIN32_LEAN_AND_MEAN before
+ including windows.h.
+
+ * filefuncs.c [HAVE_GETSYSTEMTIMEASFILETIME]: Define
+ WIN32_LEAN_AND_MEAN before including windows.h.
+
+2013-05-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Add <sys/param.h> header check.
+ * filefuncs.c: Include <sys/param.h> if there.
+ (device_blocksize): New function.
+ (fill_stat_array): Call it.
+
+2013-05-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac (AC_STRUCT_ST_BLKSIZE): Replaced with call to
+ AC_CHECK_MEMBERS.
+ * filefuncs.c (fill_stat_array): Change test from ifdef
+ HAVE_ST_BLKSIZE to HAVE_STRUCT_STAT_ST_BLKSIZE.
+
+2013-05-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkdirfd.h [FAKE_FD_VALUE]: Copied here from ../gawkapi.h.
+
+2013-05-16 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (install-data-hook): Remove .la files installed by
+ Automake. Leaves less clutter, if not (yet) less noise.
+
+2013-05-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c (fill_stat_array): For _WIN32 use a blocksize of
+ 4096 for the "blksize" element, per Eli Zaretskii.
+
+ * configure.ac [AC_STRUCT_ST_BLKSIZE]: Add call that was missing.
+ ARGH!!!!
+
+2013-05-14 Eli Zaretskii <eliz@gnu.org>
+
+ * rwarray.c [__MINGW32__]: Include winsock2.h instead of
+ arpa/inet.h.
+
+ * readdir.c [__MINGW32__]: Include windows.h.
+ Include gawkapi.h before gawkdirfd.h, since the former defines
+ FAKE_FD_VALUE needed by the latter.
+ (ftype): Accept an additional argument, the directory that is
+ being read. Callers changed.
+ [!DT_BLK]: Produce the file's type by calling 'stat' on it, if the
+ dirent structure doesn't provide that.
+ (get_inode): New function, to produce inode values on MS-Windows.
+ (dir_get_record): Use it.
+
+ * inplace.c (chown, link) [__MINGW32__]: Redirect to existing
+ library functions.
+ (mkstemp) [__MINGW32__]: New function, for MinGW, which doesn't
+ have it in its library.
+ (do_inplace_end) [__MINGW32__]: Remove the old file before
+ renaming the new, since 'rename' on Windows cannot overwrite
+ existing files.
+
+ * gawkdirfd.h (ENOTSUP): Define to ENOSYS if not already defined.
+ (DIR_TO_FD): If not defined yet, define to FAKE_FD_VALUE.
+
+ * filefuncs.c (get_inode) [_WIN32]: New function, produces the
+ file index used on Windows as its inode.
+ (fill_stat_array) [_WIN32]: Use it.
+
+2013-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.0: Release tar ball made.
+
+2013-04-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Update copyright.
+ For z/OS: If uname output is OS/390, just blast the Makefile,
+ same as for MirBSD.
+
+2013-04-17 Corinna Vinschen <vinschen@redhat.com>
+
+ * Makefile.am (MY_LIBS): Use $(LTLIBINTL) since we use libtool,
+ not LIBINTL.
+
+2013-04-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c, fnmatch.c, fork.c, ordchr.c, readdir.c, readfile.c,
+ revoutput.c, revtwoway.c, rwarray.c, rwarray0.c, stack.c, stack.h,
+ testext.c, time.c: Update copyright year.
+
+ Update to automake 1.13.1:
+
+ * configure, Makefile.in, aclocal.m4: Regenerated.
+
+2013-03-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkdirfd.h: Improve test for doing own dirfd function. Needed
+ for IRIX.
+
+2013-03-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Add AC_OUTPUT_COMMANDS that drops in a do-nothing
+ Makefile for MirBSD, since the extensions can't be built on MirBSD.
+ * configure: Regenerated.
+ * Makefile.am (check-for-shared-lib-support): Update comment some.
+ * gawkfts.c (MAX): Provide for systems that don't (Solaris).
+
+2013-03-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c (fill_stat_array): Adjust computation for block
+ count for WIN32 systems after consultation with Eli Zaretskii.
+
+2013-02-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (check-recursive, all-recursive): Make dependant upon
+ check-for-shared-lib-support.
+ (check-for-shared-lib-support): New target. If gawk doesn't have the
+ API built-in, don't try to build.
+
+2013-02-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * fnmatch.c: Pull in versions of C routine from missing_d
+ if the native system doesn't provide them.
+
+2013-02-11 Eli Zaretskii <eliz@gnu.org>
+
+ * filefuncs.c (S_ISLNK, lstat, readlink, S_IRGRP, S_IWGRP, S_IXGRP,
+ S_IROTH, S_IWOTH, S_IXOTH, S_ISUID, S_ISGID, S_ISVTX, major, minor):
+ Define if needed.
+ (fill_stat_array, init_filefuncs, func_table): Fix for Win 32.
+ * time.c: Port to Win 32.
+
+2013-01-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkdirfd.h: New file.
+ * Makeile.am (filefuncs_la_SOURCES, readdir_la_SOURCES): Use it.
+ * gawkfts.c, readdir.c: Include gawkdirfd.h.
+ * configure.ac (AC_USE_SYSTEM_EXTENSIONS): Added.
+ (GAWK_FUNC_DIRFD, GAWK_PREREQ_DIRFD): New calls.
+ (.developing): Fix check.
+ * alocal.m4: Updated.
+ * configure: Regenerated.
+ * gawkdirfd.h: Fixed for Mac OS X also.
+
+2013-01-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkfts.c: Make include of <limits.h> be unconditional.
+
+2013-01-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ Improve portability. We hope.
+
+ * gawkfts.c (S_ISREG): Define macro if not defined.
+ (_BSD_SOURCE): Define for use with c99 compiler driver.
+ * inplace.c (S_ISREG): Define macro if not defined.
+ (_XOPEN_SOURCE, _XOPEN_SOURCE_EXTENDED): Define for use with c99
+ compiler driver.
+ * filefuncs.c (_BSD_SOURCE): Define for use with c99 compiler driver.
+ * readfile.c (_BSD_SOURCE): Define for use with c99 compiler driver.
+ * revtwoway.c (_BSD_SOURCE): Define for use with c99 compiler driver.
+
+2013-01-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * readfile.c (do_readfile): Free `text' if read fails. Thanks to
+ cppcheck.
+ * inplace.c (do_inplace_begin): Check chown return value in an if
+ to shut up compiler warning.
+
+2013-01-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * inplace.3am: New file.
+ * filefuncs.3am, fnmatch.3am, fork.3am, ordchr.3am, readdir.3am,
+ readfile.3am, revoutput.3am, revtwoway.3am, rwarray.3am,
+ time.3am: Update copyright dates, add reference to inplace(3am).
+
+ * inplace.c (do_inplace_begin): Remove unused variable `p'.
+
+2013-01-10 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * inplace.c (do_inplace_begin): No need to get the 2nd suffix argument,
+ since it is not currently used in this function.
+
+2013-01-08 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * inplace.c: New extension to implement in-place editing.
+ * Makefile.am: Add inplace extension.
+
+2012-12-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.3am, fnmatch.3am: Predefined variables are no
+ longer constants.
+ * filefuncs.c (init_filefuncs): Use sym_update() instead of
+ sym_constant().
+ * fnmatch.c (init_fnmatch): Ditto.
+ * testext.c (init_testext): Ditto.
+
+2012-12-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.2: Release tar ball made.
+
+2012-12-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.c (test_indirect_vars): New test and awk code.
+
+2012-12-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (EXTRA_DIST): Add README.fts.
+
+2012-11-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c readdir.c, revoutput.c, revtwoway.c, rwarray.c,
+ rwarray0.c, testext.c: Use awk_true and awk_false instead of 1 and 0.
+
+2012-11-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * bindarr.c, fileop.c, sparr.c: Make them compile.
+ * steps: Reinstated and updated.
+ * testsparr.awk: Add call to extension().
+
+2011-05-03 John Haque <j.eh@mchsi.com>
+
+ * fileop.c, record.awk, testrecord.sh: New files.
+ * steps: Updated.
+
+2011-05-02 John Haque <j.eh@mchsi.com>
+
+ * bindarr.c, dbarray.awk, testdbarray.awk: New files.
+ * steps: Updated.
+
+2011-04-24 John Haque <j.eh@mchsi.com>
+
+ * spec_array.c, spec_array.h, sparr.c, testsparr.awk: New files.
+ * steps: Updated.
+
+2012-11-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c (do_stat): Optional third argument indicates to
+ use stat(2) instead of lstat(2).
+ * filefuncs.3am: Document same.
+
+2012-11-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * readdir.c: Simplify code to always print file type and not
+ use stat().
+ * readdir.3am: Document same.
+
+2012-11-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.c: In awk code, use printf(...) instead of the form
+ without parentheses everywhere. This makes Nelson happy.
+
+2012-11-14 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ Bug fix for filesystems without d_type in directory entry.
+
+ * readdir.c (open_directory_t): Add more fields for path.
+ (ftype): Take open_directory_t argument. Build the full path
+ for lstat. Adjust calls.
+ (dir_close): Free the storage.
+ (dir_take_control_of): Allocate storage for the path.
+
+2012-11-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Add check for $srcdir/.developing as in
+ the main directory's configure.ac.
+
+2012-11-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * rwarray.3am: Minor edits.
+
+2012-10-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (dist_man_MANS): Update the list.
+
+2012-10-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * revtwoway.3am: Clean up example.
+ * revtwoway.c: Minor cleanup (add translation calls).
+
+2012-10-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * revtwoway.3am: New file.
+
+2012-10-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c (do_stat): Always clear the array.
+
+2012-10-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * readdir.c, revoutput.c, revtwoway.c: Adjust for name change
+ of IOBUF_PUBLIC to awk_input_buf_t. Additional sanitizing in
+ revoutput.c to use `revoutput' everywhere instead of `revout'.
+ * revoutput.3am: New file.
+ * filefuncs.3am, fnmatch.3am, fork.3am, ordchr.3am, readdir.3am,
+ readfile.3am, rwarray.3am, time.3am: Add ref to revoutput(3am).
+
+2012-10-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * textext.c (try_modify_environ): Save array cookie in a separate
+ variable so it isn't clobbered. Thanks to Andrew Schorr, by way
+ of valgrind, for finding the bug.
+
+2012-09-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.c (try_modify_environ): New function and test.
+ (var_test): Modified ARGC test, added additional.
+ (test_scalar_reserved): New function and test.
+ (try_modify_environ): Don't print count of ENVIRON elements.
+
+2012-09-13 Dave Pitts <dpitts@cozx.com>
+
+ * gawkfts.c: Add defines and ifdefs for z/OS.
+ * gawkfts.h: Add defines and ifdefs for z/OS. Fix // comments.
+ * readdir.c (dir_get_record): Adjust sprintf format for z/OS.
+ * rwarray.c: Add defines and ifdefs for z/OS. Fix // comments.
+
+2012-09-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * readdir.c (do_readdir_do_ftype): Set ERRNO for bad arguments.
+ * readdir.3a: Document same, minor fixes.
+
+2012-09-07 Akim Demaille <akim@lrde.epita.fr>
+
+ * extension/gawkfts.h (__THROW): Define if it is not.
+ Copied from getopt.h.
+ * extension/gawkfts.c (fts_alloc): Since FTSENT.fts_statp is
+ defined as a struct stat*, use that type for casts instead of
+ the undefined __fts_stat_t type.
+
+2012-09-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * readdir.c, readdir.3am: Change argument to readdir_do_ftype()
+ to be a string. Update the doc accordingly.
+ * gawkfts.h: Add explanatory comment before defines of API
+ names towards the end. Thanks to Eli Zaretskii for the suggestion.
+
+2012-08-28 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * readdir.c: Have three states, 0, 1, 2 for never, fallback, and
+ always.
+ * readdir.3am: Adjust appropriately.
+
+2012-08-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ Make fts work everywhere by using our own source.
+
+ * README.fts, gawkfts.c, gawkfts.h, fts.3: New files.
+ * Makefile.am (filefuncs_la_SOURCES, EXTRA_DIST): Adjust.
+ * configure.ac: Remove check for fts.h and fts_XXX functions.
+ * filefuncs.c: Remove various ifdefs, change includes around.
+
+2012-08-28 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am: Rename man_MANS to dist_man_MANS to include the man
+ pages in the distribution tarball.
+
+2012-08-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac (AC_SYS_LARGEFILE): Added. Needed for consistency
+ with gawk, to get the same size struct stat everywhere.
+ * filefuncs.c, fnmatch.c, fork.c, ordchr.c, readdir.c, readfile.c,
+ revoutput.c, revtwoway.c, rwarray.c, rwarray0.c, testext.c,
+ time.c: Move include of config.h to top (or add it!)
+
+2012-08-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c, fnmatch.c, fork.c, ordchr.c, readdir.c, readfile.c,
+ revoutput.c, revtwoway.c, rwarray.c, rwarray0.c, testext.c,
+ time.c: Add ext_version string.
+
+2012-08-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * revoutwoway.c: New testing extension for two way processor.
+ * Makefile.am: Build revtwoway extension.
+ * readdir.c: Fix to fall back to stat if d_type is 'u' and
+ do_ftype is one.
+ * readdir.3am: Revise doc that some GNU/Linux filesystems
+ don't support d_type.
+
+2012-08-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ * revoutput.c: New testing extension for output wrapper.
+ * Makefile.am: Build revoutput extension.
+
+2012-08-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ Add fts() to filefuncs.
+
+ * filefuncs.3am: Update doc.
+ * filefuncs.c: Lots of new code.
+ * configure.ac: Add checks for appropriate headers and functions.
+ * stack.h, stack.c: New files.
+ * Makefile.am: Update list of files.
+
+ * readdir.c (dir_can_take_file): Use members in iobuf.
+ * rwarray.c (do_writea): Initialize fp to NULL.
+
+ * filefuncs.3am, fnmatch.3am, fork.3am, ordchr.3am, readdir.3am,
+ readfile.3am, rwarray.3am, time.3am: Updated.
+
+2012-08-03 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * readdir.c (dir_get_record): Fix for systems where ino_t is
+ 64 bit even on 32 bit systems (cygwin).
+
+2012-08-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (man_MANS): Add man page files so that they
+ get installed.
+ * rwarray.3am: New file.
+ * fnmatch.3am, fork.3am, time.3am: Revised.
+
+2012-07-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * rwarray0.c: Renamed from rwarray.c.
+ * rwarray.c: New file using stdio instead of system calls,
+ works on cygwin.
+
+2012-07-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * ABOUT-NLS: New file.
+ * Makefile.am, configure.ac: Revised for gettext.
+
+ * fork.3am, readdir.3am, time.3am: New files.
+ * filefuncs.3am, fnmatch.3am, ordchr.3am, readfile.3am: Revised.
+
+2012-07-29 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * readdir.c (dir_get_record): Adjust to new interface for RT.
+
+2012-07-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * readdir.c (dir_take_control_of): Print error message and
+ set ERRNO if failure. Adjust count of max digits.
+
+2012-07-27 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (*_la_LIBADD): Need to link with $(LIBINTL) for
+ gettext to work on platforms where it is not included in libc.
+
+2012-07-27 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * readdir.c (dir_get_record): Need to set errno to 0 before calling
+ readdir, since readdir sets errno only on failure, not on EOF.
+
+2012-07-27 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * readdir.c (dir_get_record): If readdir fails, set errcode. Otherwise,
+ don't bother to set errcode.
+
+2012-07-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * readdir.c (dir_take_control_of): Fix typo for case where
+ we don't have fopendir (e.g., Mac OS X 10.5).
+
+2012-07-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure.ac: Extremely crude hack to get the value of
+ ENABLE_NLS so that gettext will work in extensions.
+
+ * readdir.c (dir_get_record): Call set_RT.
+ (dir_can_take_file): Make parameter const.
+
+ * testext.c (valrep2str): Add AWK_VALUE_COOKIE.
+
+ * readdir.c: Add readdir_do_ftype function for systems without
+ dirent->d_type. Clean up buffer handling.
+
+2012-07-26 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * readdir.c (dir_get_record): No need to set *errcode to 0.
+ (dir_take_control_of): Remove some paranoia -- no need to test for
+ NULL iobuf, and no need to check dir_can_take_file again.
+
+2012-07-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * readdir.c: New file.
+ * Makefile.am (readdir): New extension.
+
+ * time.c: Fix all calls to update_ERRNO_string.
+
+ * filefuncs.c, fnmatch.c, fork.c, ordchr.c, readfile.c, rwarray.c,
+ time.c: Translate strings.
+
+2012-07-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.3am, fnmatch.3am, ordchr.3am, readfile.3am:
+ new files.
+
+2012-07-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * fnmatch.c: Simplify flag table.
+
+2012-07-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.c (test_scalar): New function and new tests.
+ (init_testext): Add a new variable.
+
+2012-07-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c (fill_stat_array): New function to do the work
+ for stat.
+ (do_stat): Call it.
+
+2012-07-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * fnmatch.c: New file.
+ * Makefile.am: Build fnmatch extension.
+ * configure.ac: Look for fnmatch.h and fnmatch function.
+
+ * fnmatch.c (init_fnmatch): Use sym_constant for FNM_NOMATCH.
+ * testext.c (dl_load): Use sym_constant for answer_num.
+
+ * testext.c (init_testext): Move extra code to here.
+ (init_func): Change to point to init_testext.
+ (dl_load): Deleted.
+ (dl_load_func): Use the macro.
+
+2012-07-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c (array_set, do_stat): Use make_const_string.
+ * fork.c (array_set_numeric): Ditto.
+ * ordchr.c (do_chr): Ditto.
+ * readfile.c (do_readfile): Use make_null_string, make_malloced_string.
+ * rwarray.c (read_elem): Ditto.
+ * testext.c (valrep2str): Add case for AWK_SCALAR.
+ (test_array_elem): Duplicate strings coming from gawk before passing
+ them back in.
+
+ All files: Add null 'init_func' file pointer for dl_load_func
+ to work.
+
+2012-07-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c (do_readfile): Return "" and set ERRNO on error
+ instead of returning -1. Per suggestion from Andrew Schorr.
+
+2012-07-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c (array_set): Adjust for change in set_array_element API.
+ * fork.c (array_set_numeric): Ditto.
+ * rwarray.c (read_array): Use set_array_element_by_elem.
+ (read_value): Add a cast to silence a compiler warning.
+ * testext.c (test_array_elem): Adjust for change in set_array_element
+ API.
+ (fill_in_array): Ditto. Change parameter name to new_array.
+
+2012-06-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * ordchr.c (do_ord, do_chr): Improve argument checking and
+ lint messages.
+
+2012-06-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (EXTRA_DIST): Remove *.awk.
+ * rwarray.awk: Moved to test directory.
+
+2012-06-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am: Enable rwarray extension.
+ * rwarray.c: Redone to use new API.
+ * rwarray.awk: Revamped for new version.
+
+2012-06-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.c (test_array_elem): Add a subarray.
+ (test_array_flatten): Removed: Tests done elsewhere.
+
+2012-06-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.c (fill_in_array): New function.
+ (create_new_array): Most code moved into fill_in_array.
+ (test_array_param): New function.
+
+2012-06-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.c (dump_array_and_delete): Renamed from dump_array.
+ Get second parameter which is index to delete. Update awk test.
+
+2012-06-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c (do_chdir): Change element use to match change types.
+ * fork.c (array_set_numeric): Ditto.
+ * testext.c (valrep2str): New function.
+ (test_array_elem): Add AWK_UNDEFINED for `wanted'. Use valrep2str.
+ Adjust use of element index.
+ (dump_array): Renamed from `dump_procinfo' and implemented.
+ (func_table): Updated.
+
+2012-06-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c (do_chdir, do_stat): Add assert(result != NULL).
+ * fork.c (do_fork, do_waitpid, do_wait): Ditto.
+ * ordchr.c (do_ord, do_chr): Ditto.
+ * readfile.c (do_readfile): Ditto.
+ * time.c (do_gettimeofday, do_sleep): Ditto.
+ * testext.c (All functions): Ditto. Clean up initial testing and use
+ make_number to make default return value up front.
+ (create_new_array, test_array_flatten): New functions.
+ (test_array_elem): Implemented.
+ (at_exit1): Don't printa actual pointer value: not portable.
+ (dl_load): Load up an array also.
+
+2012-06-14 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * time.c (RETURN): Remove obsolete define.
+ (do_sleep): Change update_ERRNO_str argument to request translation.
+
+2012-06-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ Revise API:
+
+ * filefuncs.c (do_chdir): Replace get_curfunc_param with get_argument.
+ (format_mode): Use unsigned masks.
+ (do_stat): Replace get_curfunc_param with get_argument.
+ * fork.c (do_fork): Rearrange arg order in call to sym_lookup
+ (do_waitpid): Replace get_curfunc_param with get_argument.
+ * ordchr.c (do_ord, do_chr): Replace get_curfunc_param with get_argument.
+ * readfile.c (do_readfile): Replace get_curfunc_param with get_argument.
+ * time.c (do_sleep): Replace get_curfunc_param with get_argument.
+ Replace set_ERRNO with update_ERRNO_str for no way to sleep case.
+
+ Work on testext.c:
+
+ * Makefile.am: Add stuff to make testext. Remove doit and steps
+ from EXTRA_DIST.
+ * testext.c: Fill in many of the test routines. Still more to do.
+ Fix up test scripts for each routine.
+ * time.c (do_sleep): Fix use of get_argument to be boolean.
+
+2012-06-10 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am: Add time extension.
+ * configure.ac: To support time extension, check for some headers
+ and functions that are needed.
+ * time.c: New file implementing sleep and gettimeofday.
+
+2012-06-10 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am: Remove comment referring to deleted test extensions
+ arrayparm, dl (zaxxon) and testarg.
+
+2012-06-10 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * arrayparm.c, dl.c, doit, foo.awk, steps, testarg.awk, testarg.c,
+ testarrayparm.awk, testff.awk, testfork.awk, testordchr.awk: Remove
+ unused (obsolete) files.
+
+2012-06-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c (do_stat): Make `type' const char *.
+
+ * testext.c: Functions renamed, some of them filled in. Corresponding
+ awk code for each test added inline.
+
+2012-05-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.c: New file. Outline of tests for extension API.
+
+2012-05-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c: Further cleanup and condensation of code into tables.
+ * fork.c, ordchr.c, readfile.c: Update copyright, general cleanup.
+
+2012-05-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c (array_set_numeric): Don't return a value from
+ a void function.
+
+2012-05-24 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (AM_CPPFLAGS): Use $(srcdir) to work properly when
+ built outside the source directory.
+ * configure.ac (INSTALL): Set location manually since autoconf was
+ not specifying the proper path for install-sh.
+ * filefuncs2.c, ordchr2.c, readfile2.c: Deleted.
+ * filefuncs.c: Install filefuncs2.c and patch for recent API changes.
+ * ordchr.c: Install ordchr2.c and patch for recent API changes.
+ * readfile.c: Install readfile2.c and patch for recent API changes.
+ * fork.c: Port to new API.
+
+2012-05-21 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * configure.ac: New file to run configure with libtool support
+ in this subdirectory.
+ * Makefile.am: Some changes related to running automake in this
+ directory.
+ * AUTHORS, COPYING, INSTALL, NEWS, README: Added files to make automake
+ happy.
+ * aclocal.m4, configure, configh.in: Added autoconf files.
+ * build-aux, m4: New subdirectories for autoconf stuff.
+
+2012-05-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs2.c: New file implementing chdir and stat using the
+ new interface.
+
+ Everything else is temporarily broken.
+
+2012-05-13 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * filefuncs.c (array_set): Add a comment discussing the use of unref
+ on the value returned by assoc_lookup.
+
+2012-05-13 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * xreadlink.[ch]: Remove unused files.
+
+2012-05-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ Sweeping change: Use `bool', `true', and `false' everywhere.
+
+2012-04-11 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * filefuncs.c (array_set): New function to set an array element.
+ (do_set): Use new array_set function to reduce code duplication and
+ to make sure the memory management is handled properly.
+
+2012-04-07 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * filefuncs.c: Remove unnecessary #include <sys/sysmacros.h>.
+ (read_symlink): New function to read symbolic links more robustly.
+ (do_stat): Use read_symlink instead of readlink.
+ * fork.c (do_wait): new function.
+ (dlload): Call make_builtin to add "wait" function.
+
+2012-04-02 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * fork.c (do_fork): Test whether PROCINFO_node exists before updating
+ the pid values. And do so properly using make_number.
+ * readfile.c (do_readfile): Function should be static.
+
+2012-04-01 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * filefuncs.c (do_chdir, do_stat): Replace update_ERRNO() with
+ update_ERRNO_int(errno).
+ * fork.c (do_fork, do_waitpid): Ditto.
+ * readfile.c (do_readfile): Ditto.
+ * rwarray.c (do_writea, do_reada): Ditto.
+
+2012-03-25 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am: Major cleanup. Use libtool options -module and
+ -avoid-version to create the modules properly without my local hack
+ to override the default behavior.
+
+2012-03-25 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * .gitignore: New file to ignore files created by libtool (including
+ binaries and associated metadata).
+
+2012-03-21 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (INCLUDES): Remove -I$(top_srcdir)/intl.
+
+2012-03-20 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am: New file to build and install shared libraries.
+ * arrayparm.c (do_mkarray): Get it to compile by removing 2nd arg
+ to assoc_clear.
+ * filefuncs.c (do_stat): Ditto.
+
2011-08-31 John Haque <j.eh@mchsi.com>
- * arrayparm.c, filefuncs.c, fork.c, ordchr.c, readfile.c,
- rwarray.c, testarg.c: Updated.
+
+ * arrayparm.c, filefuncs.c, fork.c, ordchr.c, readfile.c,
+ rwarray.c, testarg.c: Updated.
+
+2012-03-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.1: Release tar ball made.
2011-06-23 Arnold D. Robbins <arnold@skeeve.com>
diff --git a/extension/INSTALL b/extension/INSTALL
new file mode 100644
index 00000000..6e90e07d
--- /dev/null
+++ b/extension/INSTALL
@@ -0,0 +1,370 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994-1996, 1999-2002, 2004-2012 Free Software Foundation,
+Inc.
+
+ Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved. This file is offered as-is,
+without warranty of any kind.
+
+Basic Installation
+==================
+
+ Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package. The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package. Some packages provide this
+`INSTALL' file but do not implement all of the features documented
+below. The lack of an optional feature in a given package is not
+necessarily a bug. More recommendations for GNU packages can be found
+in *note Makefile Conventions: (standards)Makefile Conventions.
+
+ 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 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.
+
+ Running `configure' might take a while. 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, generally using the just-built uninstalled binaries.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation. When installing into a prefix owned by root, it is
+ recommended that the package be configured and built as a regular
+ user, and only the `make install' phase executed with root
+ privileges.
+
+ 5. Optionally, type `make installcheck' to repeat any self-tests, but
+ this time using the binaries in their final installed location.
+ This target does not install anything. Running this target as a
+ regular user, particularly if the prior `make install' required
+ root privileges, verifies that the installation completed
+ correctly.
+
+ 6. 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.
+
+ 7. Often, you can also type `make uninstall' to remove the installed
+ files again. In practice, not all packages have tested that
+ uninstallation works correctly, even though it is required by the
+ GNU Coding Standards.
+
+ 8. Some packages, particularly those that use Automake, provide `make
+ distcheck', which can by used by developers to test that all other
+ targets like `make install' and `make uninstall' work correctly.
+ This target is generally not run by end users.
+
+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=c99 CFLAGS=-g 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 can use 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 `..'. This
+is known as a "VPATH" build.
+
+ With a non-GNU `make', it is safer 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.
+
+ On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor. Like
+this:
+
+ ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CPP="gcc -E" CXXCPP="g++ -E"
+
+ This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
+
+Installation Names
+==================
+
+ By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX', where PREFIX must be an
+absolute file name.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files 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. In general, the
+default for these options is expressed in terms of `${prefix}', so that
+specifying just `--prefix' will affect all of the other directory
+specifications that were not explicitly provided.
+
+ The most portable way to affect installation locations is to pass the
+correct locations to `configure'; however, many packages provide one or
+both of the following shortcuts of passing variable assignments to the
+`make install' command line to change installation locations without
+having to reconfigure or recompile.
+
+ The first method involves providing an override variable for each
+affected directory. For example, `make install
+prefix=/alternate/directory' will choose an alternate location for all
+directory configuration variables that were expressed in terms of
+`${prefix}'. Any directories that were specified during `configure',
+but not in terms of `${prefix}', must each be overridden at install
+time for the entire installation to be relocated. The approach of
+makefile variable overrides for each directory variable is required by
+the GNU Coding Standards, and ideally causes no recompilation.
+However, some platforms have known limitations with the semantics of
+shared libraries that end up requiring recompilation when using this
+method, particularly noticeable in packages that use GNU Libtool.
+
+ The second method involves providing the `DESTDIR' variable. For
+example, `make install DESTDIR=/alternate/directory' will prepend
+`/alternate/directory' before all installation names. The approach of
+`DESTDIR' overrides is not required by the GNU Coding Standards, and
+does not work on platforms that have drive letters. On the other hand,
+it does better at avoiding recompilation issues, and works well even
+when some directory options were not specified in terms of `${prefix}'
+at `configure' time.
+
+Optional Features
+=================
+
+ 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'.
+
+ 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.
+
+ Some packages offer the ability to configure how verbose the
+execution of `make' will be. For these packages, running `./configure
+--enable-silent-rules' sets the default to minimal output, which can be
+overridden with `make V=1'; while running `./configure
+--disable-silent-rules' sets the default to verbose, which can be
+overridden with `make V=0'.
+
+Particular systems
+==================
+
+ On HP-UX, the default C compiler is not ANSI C compatible. If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+ ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+ HP-UX `make' updates targets which have the same time stamps as
+their prerequisites, which makes it generally unusable when shipped
+generated files such as `configure' are involved. Use GNU `make'
+instead.
+
+ On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file. The option `-nodtk' can be used as
+a workaround. If GNU CC is not installed, it is therefore recommended
+to try
+
+ ./configure CC="cc"
+
+and if that doesn't work, try
+
+ ./configure CC="cc -nodtk"
+
+ On Solaris, don't put `/usr/ucb' early in your `PATH'. This
+directory contains several dysfunctional programs; working variants of
+these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
+in your `PATH', put it _after_ `/usr/bin'.
+
+ On Haiku, software installed for all users goes in `/boot/common',
+not `/usr/local'. It is recommended to use the following options:
+
+ ./configure --prefix=/boot/common
+
+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 option `--target=TYPE' 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).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf limitation. Until the limitation is lifted, you can use
+this workaround:
+
+ CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+ Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+ Print a summary of the options unique to this package's
+ `configure', and exit. The `short' variant lists options used
+ only in the top level, while the `recursive' variant lists options
+ also present in any nested packages.
+
+`--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.
+
+`--prefix=DIR'
+ Use DIR as the installation prefix. *note Installation Names::
+ for more details, including other options available for fine-tuning
+ the installation locations.
+
+`--no-create'
+`-n'
+ Run the configure checks, but stop before creating any output
+ files.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
diff --git a/extension/Makefile.am b/extension/Makefile.am
new file mode 100644
index 00000000..b9dabfe2
--- /dev/null
+++ b/extension/Makefile.am
@@ -0,0 +1,130 @@
+#
+# extension/Makefile.am --- automake input file for gawk
+#
+# Copyright (C) 1995-2006, 2012 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 3 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.
+
+AM_CPPFLAGS = -I$(srcdir)/..
+
+# This variable insures that aclocal runs
+# correctly after changing configure.ac
+ACLOCAL_AMFLAGS = -I m4
+
+# For some make's, e.g. OpenBSD, that don't define this
+RM = rm -f
+
+# Note: rwarray does not currently compile.
+
+pkgextension_LTLIBRARIES = \
+ filefuncs.la \
+ fnmatch.la \
+ fork.la \
+ inplace.la \
+ ordchr.la \
+ readdir.la \
+ readfile.la \
+ revoutput.la \
+ revtwoway.la \
+ rwarray.la \
+ testext.la \
+ time.la
+
+MY_MODULE_FLAGS = -module -avoid-version -no-undefined
+# on Cygwin, gettext requires that we link with -lintl
+MY_LIBS = $(LTLIBINTL)
+
+filefuncs_la_SOURCES = filefuncs.c stack.h stack.c gawkfts.h \
+ gawkfts.c gawkdirfd.h
+filefuncs_la_LDFLAGS = $(MY_MODULE_FLAGS)
+filefuncs_la_LIBADD = $(MY_LIBS)
+
+fnmatch_la_SOURCES = fnmatch.c
+fnmatch_la_LDFLAGS = $(MY_MODULE_FLAGS)
+fnmatch_la_LIBADD = $(MY_LIBS)
+
+fork_la_SOURCES = fork.c
+fork_la_LDFLAGS = $(MY_MODULE_FLAGS)
+fork_la_LIBADD = $(MY_LIBS)
+
+inplace_la_SOURCES = inplace.c
+inplace_la_LDFLAGS = $(MY_MODULE_FLAGS)
+inplace_la_LIBADD = $(MY_LIBS)
+
+ordchr_la_SOURCES = ordchr.c
+ordchr_la_LDFLAGS = $(MY_MODULE_FLAGS)
+ordchr_la_LIBADD = $(MY_LIBS)
+
+readdir_la_SOURCES = readdir.c gawkdirfd.h
+readdir_la_LDFLAGS = $(MY_MODULE_FLAGS)
+readdir_la_LIBADD = $(MY_LIBS)
+
+readfile_la_SOURCES = readfile.c
+readfile_la_LDFLAGS = $(MY_MODULE_FLAGS)
+readfile_la_LIBADD = $(MY_LIBS)
+
+revoutput_la_SOURCES = revoutput.c
+revoutput_la_LDFLAGS = $(MY_MODULE_FLAGS)
+revoutput_la_LIBADD = $(MY_LIBS)
+
+revtwoway_la_SOURCES = revtwoway.c
+revtwoway_la_LDFLAGS = $(MY_MODULE_FLAGS)
+revtwoway_la_LIBADD = $(MY_LIBS)
+
+rwarray_la_SOURCES = rwarray.c
+rwarray_la_LDFLAGS = $(MY_MODULE_FLAGS)
+rwarray_la_LIBADD = $(MY_LIBS)
+
+time_la_SOURCES = time.c
+time_la_LDFLAGS = $(MY_MODULE_FLAGS)
+time_la_LIBADD = $(MY_LIBS)
+
+testext_la_SOURCES = testext.c
+testext_la_LDFLAGS = $(MY_MODULE_FLAGS)
+testext_la_LIBADD = $(MY_LIBS)
+
+install-data-hook:
+ for i in $(pkgextension_LTLIBRARIES) ; do \
+ $(RM) $(DESTDIR)$(pkgextensiondir)/$$i ; \
+ done
+
+# Keep the uninstall check working:
+uninstall-so:
+ $(RM) $(DESTDIR)$(pkgextensiondir)/*.so
+ $(RM) $(DESTDIR)$(pkgextensiondir)/*.dll
+ $(RM) $(DESTDIR)$(pkgextensiondir)/*.a
+ $(RM) $(DESTDIR)$(pkgextensiondir)/*.lib
+
+uninstall-recursive: uninstall-so
+
+EXTRA_DIST = build-aux/config.rpath \
+ ChangeLog \
+ ChangeLog.0 \
+ fts.3 \
+ README.fts
+
+dist_man_MANS = \
+ filefuncs.3am fnmatch.3am fork.3am inplace.3am \
+ ordchr.3am readdir.3am readfile.3am revoutput.3am \
+ revtwoway.3am rwarray.3am time.3am
+
+# gettext requires this
+SUBDIRS =
diff --git a/extension/Makefile.in b/extension/Makefile.in
new file mode 100644
index 00000000..2596d282
--- /dev/null
+++ b/extension/Makefile.in
@@ -0,0 +1,1258 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+
+#
+# extension/Makefile.am --- automake input file for gawk
+#
+# Copyright (C) 1995-2006, 2012 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 3 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
+#
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+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 = .
+DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \
+ $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/configure $(am__configure_deps) \
+ $(srcdir)/configh.in ABOUT-NLS $(top_srcdir)/build-aux/depcomp \
+ $(dist_man_MANS) COPYING build-aux/ChangeLog build-aux/ar-lib \
+ build-aux/compile build-aux/config.guess \
+ build-aux/config.rpath build-aux/config.sub build-aux/depcomp \
+ build-aux/install-sh build-aux/missing build-aux/ltmain.sh \
+ $(top_srcdir)/build-aux/ar-lib $(top_srcdir)/build-aux/compile \
+ $(top_srcdir)/build-aux/config.guess \
+ $(top_srcdir)/build-aux/config.rpath \
+ $(top_srcdir)/build-aux/config.sub \
+ $(top_srcdir)/build-aux/install-sh \
+ $(top_srcdir)/build-aux/ltmain.sh \
+ $(top_srcdir)/build-aux/missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/dirfd.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.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 config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(pkgextensiondir)" \
+ "$(DESTDIR)$(man3dir)"
+LTLIBRARIES = $(pkgextension_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
+filefuncs_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_filefuncs_la_OBJECTS = filefuncs.lo stack.lo gawkfts.lo
+filefuncs_la_OBJECTS = $(am_filefuncs_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+filefuncs_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(filefuncs_la_LDFLAGS) $(LDFLAGS) -o $@
+fnmatch_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_fnmatch_la_OBJECTS = fnmatch.lo
+fnmatch_la_OBJECTS = $(am_fnmatch_la_OBJECTS)
+fnmatch_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(fnmatch_la_LDFLAGS) $(LDFLAGS) -o $@
+fork_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_fork_la_OBJECTS = fork.lo
+fork_la_OBJECTS = $(am_fork_la_OBJECTS)
+fork_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(fork_la_LDFLAGS) $(LDFLAGS) -o $@
+inplace_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_inplace_la_OBJECTS = inplace.lo
+inplace_la_OBJECTS = $(am_inplace_la_OBJECTS)
+inplace_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(inplace_la_LDFLAGS) $(LDFLAGS) -o $@
+ordchr_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_ordchr_la_OBJECTS = ordchr.lo
+ordchr_la_OBJECTS = $(am_ordchr_la_OBJECTS)
+ordchr_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(ordchr_la_LDFLAGS) $(LDFLAGS) -o $@
+readdir_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_readdir_la_OBJECTS = readdir.lo
+readdir_la_OBJECTS = $(am_readdir_la_OBJECTS)
+readdir_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(readdir_la_LDFLAGS) $(LDFLAGS) -o $@
+readfile_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_readfile_la_OBJECTS = readfile.lo
+readfile_la_OBJECTS = $(am_readfile_la_OBJECTS)
+readfile_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(readfile_la_LDFLAGS) $(LDFLAGS) -o $@
+revoutput_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_revoutput_la_OBJECTS = revoutput.lo
+revoutput_la_OBJECTS = $(am_revoutput_la_OBJECTS)
+revoutput_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(revoutput_la_LDFLAGS) $(LDFLAGS) -o $@
+revtwoway_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_revtwoway_la_OBJECTS = revtwoway.lo
+revtwoway_la_OBJECTS = $(am_revtwoway_la_OBJECTS)
+revtwoway_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(revtwoway_la_LDFLAGS) $(LDFLAGS) -o $@
+rwarray_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_rwarray_la_OBJECTS = rwarray.lo
+rwarray_la_OBJECTS = $(am_rwarray_la_OBJECTS)
+rwarray_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(rwarray_la_LDFLAGS) $(LDFLAGS) -o $@
+testext_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_testext_la_OBJECTS = testext.lo
+testext_la_OBJECTS = $(am_testext_la_OBJECTS)
+testext_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(testext_la_LDFLAGS) $(LDFLAGS) -o $@
+time_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_time_la_OBJECTS = time.lo
+time_la_OBJECTS = $(am_time_la_OBJECTS)
+time_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(time_la_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(filefuncs_la_SOURCES) $(fnmatch_la_SOURCES) \
+ $(fork_la_SOURCES) $(inplace_la_SOURCES) $(ordchr_la_SOURCES) \
+ $(readdir_la_SOURCES) $(readfile_la_SOURCES) \
+ $(revoutput_la_SOURCES) $(revtwoway_la_SOURCES) \
+ $(rwarray_la_SOURCES) $(testext_la_SOURCES) $(time_la_SOURCES)
+DIST_SOURCES = $(filefuncs_la_SOURCES) $(fnmatch_la_SOURCES) \
+ $(fork_la_SOURCES) $(inplace_la_SOURCES) $(ordchr_la_SOURCES) \
+ $(readdir_la_SOURCES) $(readfile_la_SOURCES) \
+ $(revoutput_la_SOURCES) $(revtwoway_la_SOURCES) \
+ $(rwarray_la_SOURCES) $(testext_la_SOURCES) $(time_la_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man3dir = $(mandir)/man3
+NROFF = nroff
+MANS = $(dist_man_MANS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ cscope distdir dist dist-all distcheck
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+ $(LISP)configh.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ if test -d "$(distdir)"; then \
+ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -rf "$(distdir)" \
+ || { sleep 5 && rm -rf "$(distdir)"; }; \
+ else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+DIST_TARGETS = dist-gzip
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+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@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+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@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+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@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgextensiondir = @pkgextensiondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CPPFLAGS = -I$(srcdir)/..
+
+# This variable insures that aclocal runs
+# correctly after changing configure.ac
+ACLOCAL_AMFLAGS = -I m4
+
+# For some make's, e.g. OpenBSD, that don't define this
+RM = rm -f
+
+# Note: rwarray does not currently compile.
+pkgextension_LTLIBRARIES = \
+ filefuncs.la \
+ fnmatch.la \
+ fork.la \
+ inplace.la \
+ ordchr.la \
+ readdir.la \
+ readfile.la \
+ revoutput.la \
+ revtwoway.la \
+ rwarray.la \
+ testext.la \
+ time.la
+
+MY_MODULE_FLAGS = -module -avoid-version -no-undefined
+# on Cygwin, gettext requires that we link with -lintl
+MY_LIBS = $(LTLIBINTL)
+filefuncs_la_SOURCES = filefuncs.c stack.h stack.c gawkfts.h \
+ gawkfts.c gawkdirfd.h
+
+filefuncs_la_LDFLAGS = $(MY_MODULE_FLAGS)
+filefuncs_la_LIBADD = $(MY_LIBS)
+fnmatch_la_SOURCES = fnmatch.c
+fnmatch_la_LDFLAGS = $(MY_MODULE_FLAGS)
+fnmatch_la_LIBADD = $(MY_LIBS)
+fork_la_SOURCES = fork.c
+fork_la_LDFLAGS = $(MY_MODULE_FLAGS)
+fork_la_LIBADD = $(MY_LIBS)
+inplace_la_SOURCES = inplace.c
+inplace_la_LDFLAGS = $(MY_MODULE_FLAGS)
+inplace_la_LIBADD = $(MY_LIBS)
+ordchr_la_SOURCES = ordchr.c
+ordchr_la_LDFLAGS = $(MY_MODULE_FLAGS)
+ordchr_la_LIBADD = $(MY_LIBS)
+readdir_la_SOURCES = readdir.c gawkdirfd.h
+readdir_la_LDFLAGS = $(MY_MODULE_FLAGS)
+readdir_la_LIBADD = $(MY_LIBS)
+readfile_la_SOURCES = readfile.c
+readfile_la_LDFLAGS = $(MY_MODULE_FLAGS)
+readfile_la_LIBADD = $(MY_LIBS)
+revoutput_la_SOURCES = revoutput.c
+revoutput_la_LDFLAGS = $(MY_MODULE_FLAGS)
+revoutput_la_LIBADD = $(MY_LIBS)
+revtwoway_la_SOURCES = revtwoway.c
+revtwoway_la_LDFLAGS = $(MY_MODULE_FLAGS)
+revtwoway_la_LIBADD = $(MY_LIBS)
+rwarray_la_SOURCES = rwarray.c
+rwarray_la_LDFLAGS = $(MY_MODULE_FLAGS)
+rwarray_la_LIBADD = $(MY_LIBS)
+time_la_SOURCES = time.c
+time_la_LDFLAGS = $(MY_MODULE_FLAGS)
+time_la_LIBADD = $(MY_LIBS)
+testext_la_SOURCES = testext.c
+testext_la_LDFLAGS = $(MY_MODULE_FLAGS)
+testext_la_LIBADD = $(MY_LIBS)
+EXTRA_DIST = build-aux/config.rpath \
+ ChangeLog \
+ ChangeLog.0 \
+ fts.3 \
+ README.fts
+
+dist_man_MANS = \
+ filefuncs.3am fnmatch.3am fork.3am inplace.3am \
+ ordchr.3am readdir.3am readfile.3am revoutput.3am \
+ revtwoway.3am rwarray.3am time.3am
+
+
+# gettext requires this
+SUBDIRS =
+all: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+am--refresh: Makefile
+ @:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
+ $(am__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)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+ @test -f $@ || rm -f stamp-h1
+ @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
+
+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)
+ ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+
+install-pkgextensionLTLIBRARIES: $(pkgextension_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgextension_LTLIBRARIES)'; test -n "$(pkgextensiondir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgextensiondir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgextensiondir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkgextensiondir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkgextensiondir)"; \
+ }
+
+uninstall-pkgextensionLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgextension_LTLIBRARIES)'; test -n "$(pkgextensiondir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkgextensiondir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkgextensiondir)/$$f"; \
+ done
+
+clean-pkgextensionLTLIBRARIES:
+ -test -z "$(pkgextension_LTLIBRARIES)" || rm -f $(pkgextension_LTLIBRARIES)
+ @list='$(pkgextension_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+filefuncs.la: $(filefuncs_la_OBJECTS) $(filefuncs_la_DEPENDENCIES) $(EXTRA_filefuncs_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(filefuncs_la_LINK) -rpath $(pkgextensiondir) $(filefuncs_la_OBJECTS) $(filefuncs_la_LIBADD) $(LIBS)
+
+fnmatch.la: $(fnmatch_la_OBJECTS) $(fnmatch_la_DEPENDENCIES) $(EXTRA_fnmatch_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(fnmatch_la_LINK) -rpath $(pkgextensiondir) $(fnmatch_la_OBJECTS) $(fnmatch_la_LIBADD) $(LIBS)
+
+fork.la: $(fork_la_OBJECTS) $(fork_la_DEPENDENCIES) $(EXTRA_fork_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(fork_la_LINK) -rpath $(pkgextensiondir) $(fork_la_OBJECTS) $(fork_la_LIBADD) $(LIBS)
+
+inplace.la: $(inplace_la_OBJECTS) $(inplace_la_DEPENDENCIES) $(EXTRA_inplace_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(inplace_la_LINK) -rpath $(pkgextensiondir) $(inplace_la_OBJECTS) $(inplace_la_LIBADD) $(LIBS)
+
+ordchr.la: $(ordchr_la_OBJECTS) $(ordchr_la_DEPENDENCIES) $(EXTRA_ordchr_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(ordchr_la_LINK) -rpath $(pkgextensiondir) $(ordchr_la_OBJECTS) $(ordchr_la_LIBADD) $(LIBS)
+
+readdir.la: $(readdir_la_OBJECTS) $(readdir_la_DEPENDENCIES) $(EXTRA_readdir_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(readdir_la_LINK) -rpath $(pkgextensiondir) $(readdir_la_OBJECTS) $(readdir_la_LIBADD) $(LIBS)
+
+readfile.la: $(readfile_la_OBJECTS) $(readfile_la_DEPENDENCIES) $(EXTRA_readfile_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(readfile_la_LINK) -rpath $(pkgextensiondir) $(readfile_la_OBJECTS) $(readfile_la_LIBADD) $(LIBS)
+
+revoutput.la: $(revoutput_la_OBJECTS) $(revoutput_la_DEPENDENCIES) $(EXTRA_revoutput_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(revoutput_la_LINK) -rpath $(pkgextensiondir) $(revoutput_la_OBJECTS) $(revoutput_la_LIBADD) $(LIBS)
+
+revtwoway.la: $(revtwoway_la_OBJECTS) $(revtwoway_la_DEPENDENCIES) $(EXTRA_revtwoway_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(revtwoway_la_LINK) -rpath $(pkgextensiondir) $(revtwoway_la_OBJECTS) $(revtwoway_la_LIBADD) $(LIBS)
+
+rwarray.la: $(rwarray_la_OBJECTS) $(rwarray_la_DEPENDENCIES) $(EXTRA_rwarray_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(rwarray_la_LINK) -rpath $(pkgextensiondir) $(rwarray_la_OBJECTS) $(rwarray_la_LIBADD) $(LIBS)
+
+testext.la: $(testext_la_OBJECTS) $(testext_la_DEPENDENCIES) $(EXTRA_testext_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(testext_la_LINK) -rpath $(pkgextensiondir) $(testext_la_OBJECTS) $(testext_la_LIBADD) $(LIBS)
+
+time.la: $(time_la_OBJECTS) $(time_la_DEPENDENCIES) $(EXTRA_time_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(time_la_LINK) -rpath $(pkgextensiondir) $(time_la_OBJECTS) $(time_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filefuncs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fnmatch.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fork.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gawkfts.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inplace.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ordchr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readdir.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readfile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/revoutput.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/revtwoway.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rwarray.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stack.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testext.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool config.lt
+install-man3: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man3dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.3[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man3:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man3dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.3[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir)
+
+# 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.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ 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; \
+ ($(am__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"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ 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 || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+ test ! -s cscope.files \
+ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+ -rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+ -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$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 \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -755 \
+ -exec chmod u+rwx,go+rx {} \; -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 $(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__post_remove_distdir)
+
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+ $(am__post_remove_distdir)
+
+dist-lzip: distdir
+ tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+ $(am__post_remove_distdir)
+
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+ $(am__post_remove_distdir)
+
+dist-tarZ: distdir
+ @echo WARNING: "Support for shar distribution archives is" \
+ "deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__post_remove_distdir)
+
+dist-shar: distdir
+ @echo WARNING: "Support for distribution archives compressed with" \
+ "legacy program 'compress' is deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__post_remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__post_remove_distdir)
+
+dist dist-all:
+ $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+ $(am__post_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) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lz*) \
+ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir)
+ chmod u+w $(distdir)
+ mkdir $(distdir)/_build $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build \
+ && ../configure \
+ $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ --srcdir=.. --prefix="$$dc_install_base" \
+ && $(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 \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__post_remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @test -n '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: trying to run $@ with an empty' \
+ '$$(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ $(am__cd) '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+ || { 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
+check: check-recursive
+all-am: Makefile $(LTLIBRARIES) $(MANS) config.h
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(pkgextensiondir)" "$(DESTDIR)$(man3dir)"; 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:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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-recursive
+
+clean-am: clean-generic clean-libtool clean-pkgextensionLTLIBRARIES \
+ 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-libtool distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-man install-pkgextensionLTLIBRARIES
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man: install-man3
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+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-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-pkgextensionLTLIBRARIES
+
+uninstall-man: uninstall-man3
+
+.MAKE: $(am__recursive_targets) all install-am install-data-am \
+ install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
+ am--refresh check check-am clean clean-cscope clean-generic \
+ clean-libtool clean-pkgextensionLTLIBRARIES cscope \
+ cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
+ dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \
+ distcheck distclean distclean-compile distclean-generic \
+ distclean-hdr distclean-libtool distclean-tags distcleancheck \
+ distdir distuninstallcheck dvi dvi-am html html-am info \
+ info-am install install-am install-data install-data-am \
+ install-data-hook install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man3 install-pdf \
+ install-pdf-am install-pkgextensionLTLIBRARIES install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man3 uninstall-pkgextensionLTLIBRARIES
+
+
+install-data-hook:
+ for i in $(pkgextension_LTLIBRARIES) ; do \
+ $(RM) $(DESTDIR)$(pkgextensiondir)/$$i ; \
+ done
+
+# Keep the uninstall check working:
+uninstall-so:
+ $(RM) $(DESTDIR)$(pkgextensiondir)/*.so
+ $(RM) $(DESTDIR)$(pkgextensiondir)/*.dll
+ $(RM) $(DESTDIR)$(pkgextensiondir)/*.a
+ $(RM) $(DESTDIR)$(pkgextensiondir)/*.lib
+
+uninstall-recursive: uninstall-so
+
+# 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:
diff --git a/extension/NEWS b/extension/NEWS
new file mode 100644
index 00000000..b3b2e56f
--- /dev/null
+++ b/extension/NEWS
@@ -0,0 +1,7 @@
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved.
+
+Extensions now build separately.
diff --git a/extension/README b/extension/README
new file mode 100644
index 00000000..aa404700
--- /dev/null
+++ b/extension/README
@@ -0,0 +1,10 @@
+ Copyright (C) 2005, 2006, 2007, 2009, 2010, 2011, 2012
+ Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved.
+
+README:
+
+This directory contain the standard bundled extensions for GNU Awk.
diff --git a/extension/README.fts b/extension/README.fts
new file mode 100644
index 00000000..b8b948c4
--- /dev/null
+++ b/extension/README.fts
@@ -0,0 +1,68 @@
+Wed Aug 29 22:34:24 IDT 2012
+============================
+
+Portability is a myth, a chimera. Like the pot of gold at the end of
+the rainbow, it's always looks like it is just within your reach, but
+in fact, it is seldom, if ever, truly acheivable.
+
+It all started when trying to get the extensions to work on my aged
+PowerPC Macbook G4 running Mac OS X 10.5. That machine is wonderful,
+since it is neither an Intel architecture machine nor is it GNU/Linux;
+two criteria that are becoming increasingly harder to meet over 10%
+into the 21st century.
+
+The readdir extension didn't work. Furthermore, GDB showed that in gawk
+itself, struct stat had one size and layout, while inside the readdir
+code, it had another.
+
+This turned out to be due to the large file nonsense foisted off upon
+us by POSIX. The main gawk configure.ac had AC_SYS_LARGEFILE but the
+extensions' configure.ac did not. OK - a one line fix, rebuild, and
+everything is OK. Right?
+
+Of course not.
+
+Everything was OK on my 64-bit GNU/Linux Intel system, but lo and behold,
+I compiled on a 32-bit GNU/Linux system and suddenly the fts tests
+stopped working. A look at the config.log reveals:
+
+ <fts.h> cannot be used with -D_FILE_OFFSET_BITS==64
+
+Why? Who knows. The comment in the file itself is cryptic:
+
+ /* The fts interface is incompatible with the LFS interface which
+ transparently uses the 64-bit file access functions. */
+ #ifdef __USE_FILE_OFFSET64
+ # error "<fts.h> cannot be used with -D_FILE_OFFSET_BITS==64"
+ #endif
+
+It purports to be English, but says nothing intelligible, and the man
+page sheds no light, either.
+
+Fortunately, the source for fts from NetBSD is reasonably legible,
+freely available, and has a usable license.
+
+So, I try to just plug it in directly. Everything compiles, nothing
+works. There is shared library / weird linker dark voodoo crap going on.
+
+*I* am not a powerful enough Jedi to get around it, and I think it has
+more to do with the Dark Side of the Force than with the Light Side. So
+gawkfts.h now has:
+
+ #define fts_children gawk_fts_children
+ #define fts_close gawk_fts_close
+ #define fts_open gawk_fts_open
+ #define fts_read gawk_fts_read
+ #define fts_set gawk_fts_set
+
+to rename things, and it all compiles and works.
+
+The Plan 9 guys got it right when they threw eveything out and started
+over again. I sure wish I could.
+
+On the bright side, this is stuff that would have had to be done anyway
+for at least MinGW, and maybe for some other systems. So it's not wasted
+effort. But it sure is sad that it's necessary.
+
+Arnold Robbins
+arnold@skeeve.com
diff --git a/extension/aclocal.m4 b/extension/aclocal.m4
new file mode 100644
index 00000000..cd7f9c16
--- /dev/null
+++ b/extension/aclocal.m4
@@ -0,0 +1,1224 @@
+# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 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.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
+
+# Copyright (C) 2002-2013 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.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.14'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.14.1], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.14.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# Copyright (C) 2011-2013 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_AR([ACT-IF-FAIL])
+# -------------------------
+# Try to determine the archiver interface, and trigger the ar-lib wrapper
+# if it is needed. If the detection of archiver interface fails, run
+# ACT-IF-FAIL (default is to abort configure with a proper error message).
+AC_DEFUN([AM_PROG_AR],
+[AC_BEFORE([$0], [LT_INIT])dnl
+AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([ar-lib])dnl
+AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false])
+: ${AR=ar}
+
+AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface],
+ [AC_LANG_PUSH([C])
+ am_cv_ar_interface=ar
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])],
+ [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([am_ar_try])
+ if test "$ac_status" -eq 0; then
+ am_cv_ar_interface=ar
+ else
+ am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([am_ar_try])
+ if test "$ac_status" -eq 0; then
+ am_cv_ar_interface=lib
+ else
+ am_cv_ar_interface=unknown
+ fi
+ fi
+ rm -f conftest.lib libconftest.a
+ ])
+ AC_LANG_POP([C])])
+
+case $am_cv_ar_interface in
+ar)
+ ;;
+lib)
+ # Microsoft lib, so override with the ar-lib wrapper script.
+ # FIXME: It is wrong to rewrite AR.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__AR in this case,
+ # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+ # similar.
+ AR="$am_aux_dir/ar-lib $AR"
+ ;;
+unknown)
+ m4_default([$1],
+ [AC_MSG_ERROR([could not determine $AR interface])])
+ ;;
+esac
+AC_SUBST([AR])dnl
+])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997-2013 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_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+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-2013 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.
+
+
+# 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", "OBJC", "OBJCXX", "UPC", or "GJC".
+# 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
+
+m4_if([$1], [CC], [depcc="$CC" am_compiler_list=],
+ [$1], [CXX], [depcc="$CXX" am_compiler_list=],
+ [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+ [$1], [UPC], [depcc="$UPC" am_compiler_list=],
+ [$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".
+ rm -rf conftest.dir
+ 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
+ am__universal=false
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac])
+
+ 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 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # 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. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ 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
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj 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], [dnl
+AS_HELP_STRING(
+ [--enable-dependency-tracking],
+ [do not reject slow dependency extractors])
+AS_HELP_STRING(
+ [--disable-dependency-tracking],
+ [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999-2013 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_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # Older Autoconf quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ 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.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/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"`
+ # 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'`; 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-2013 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 macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
+# 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.65])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
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+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],
+[AC_DIAGNOSE([obsolete],
+ [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(
+ m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+ [ok:ok],,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])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])
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# 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])],
+ [m4_define([AC_PROG_CC],
+ m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES([CXX])],
+ [m4_define([AC_PROG_CXX],
+ m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES([OBJC])],
+ [m4_define([AC_PROG_OBJC],
+ m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+ [_AM_DEPENDENCIES([OBJCXX])],
+ [m4_define([AC_PROG_OBJCXX],
+ m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+ fi
+fi])
+
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+# 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_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001-2013 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
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST([install_sh])])
+
+# Copyright (C) 2003-2013 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.
+
+# 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-2013 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_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.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
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+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-2013 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_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 is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
+else
+ am_missing_run=
+ AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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_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],
+[m4_foreach_w([_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) 1999-2013 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_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+ [whether $CC understands -c and -o together],
+ [am_cv_prog_cc_c_o],
+ [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 2001-2013 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_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+ ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ (exit $ac_status); }])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 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_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
+esac
+
+# 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 (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ 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
+ 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
+ if test "$[2]" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ 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])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+ [AC_MSG_CHECKING([that generated files are newer than configure])
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2013 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_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+ [--enable-silent-rules],
+ [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+ [--disable-silent-rules],
+ [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+ [am_cv_make_support_nested_variables],
+ [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+ dnl Using '$V' instead of '$(V)' breaks IRIX make.
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2013 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="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006-2013 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_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004-2013 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_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. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+ [m4_case([$1],
+ [ustar],
+ [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+ # There is notably a 21 bits limit for the UID and the GID. In fact,
+ # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+ # and bug#13588).
+ am_max_uid=2097151 # 2^21 - 1
+ am_max_gid=$am_max_uid
+ # The $UID and $GID variables are not portable, so we need to resort
+ # to the POSIX-mandated id(1) utility. Errors in the 'id' calls
+ # below are definitely unexpected, so allow the users to see them
+ # (that is, avoid stderr redirection).
+ am_uid=`id -u || echo unknown`
+ am_gid=`id -g || echo unknown`
+ AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+ if test $am_uid -le $am_max_uid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi
+ AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+ if test $am_gid -le $am_max_gid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi],
+
+ [pax],
+ [],
+
+ [m4_fatal([Unknown tar format])])
+
+ AC_MSG_CHECKING([how to create a $1 tar archive])
+
+ # Go ahead even if we have the value already cached. We do so because we
+ # need to set the values for the 'am__tar' and 'am__untar' variables.
+ _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+ 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])
+ AM_RUN_LOG([cat conftest.dir/file])
+ 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/dirfd.m4])
+m4_include([m4/gettext.m4])
+m4_include([m4/iconv.m4])
+m4_include([m4/intlmacosx.m4])
+m4_include([m4/lib-ld.m4])
+m4_include([m4/lib-link.m4])
+m4_include([m4/lib-prefix.m4])
+m4_include([m4/libtool.m4])
+m4_include([m4/ltoptions.m4])
+m4_include([m4/ltsugar.m4])
+m4_include([m4/ltversion.m4])
+m4_include([m4/lt~obsolete.m4])
+m4_include([m4/nls.m4])
+m4_include([m4/po.m4])
+m4_include([m4/progtest.m4])
diff --git a/extension/arrayparm.c b/extension/arrayparm.c
deleted file mode 100644
index b0aee33d..00000000
--- a/extension/arrayparm.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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, 2011 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 3 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"
-
-int plugin_is_GPL_compatible;
-
-/* do_mkarray --- turn a variable into an array */
-
-/*
- * From awk, call
- *
- * mkarray(var, sub, val)
- */
-
-static NODE *
-do_mkarray(int nargs)
-{
- int ret = -1;
- NODE *var, *sub, *val;
- NODE **elemval;
-
- if (do_lint && nargs > 3)
- lintwarn("mkarray: called with too many arguments");
-
- var = get_array_argument(0, FALSE);
- sub = get_scalar_argument(1, FALSE);
- val = get_scalar_argument(2, FALSE);
-
- 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, NULL);
-
- elemval = assoc_lookup(var, sub);
- *elemval = dupnode(val);
- ret = 0;
-
- /* Set the return value */
- return make_number((AWKNUM) ret);
-}
-
-/* dlload --- load new builtins in this library */
-
-NODE *
-dlload(tree, dl)
-NODE *tree;
-void *dl;
-{
- make_builtin("mkarray", do_mkarray, 3);
-
- return make_number((AWKNUM) 0);
-}
diff --git a/extension/build-aux/ChangeLog b/extension/build-aux/ChangeLog
new file mode 100644
index 00000000..697db607
--- /dev/null
+++ b/extension/build-aux/ChangeLog
@@ -0,0 +1,33 @@
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.1: Release tar ball made.
+
+2014-01-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * config.guess, config.rpath, config.sub, depcomp,
+ install-sh: Updated.
+
+2013-12-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * config.guess: Updated.
+
+2013-12-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * ltmain.sh: Updated to libtool 2.4.2.418.
+
+2013-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.0: Release tar ball made.
+
+2013-04-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ * missing: Updated from Automake 1.13.1.
+
+2012-07-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * config.rpath: New file.
+
+2012-05-21 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * ar-lib, config.guess, config.sub, depcomp, install-sh, ltmain.sh,
+ missing: New files related to autoconf and libtool.
diff --git a/extension/build-aux/ar-lib b/extension/build-aux/ar-lib
new file mode 100755
index 00000000..67f5f36f
--- /dev/null
+++ b/extension/build-aux/ar-lib
@@ -0,0 +1,270 @@
+#! /bin/sh
+# Wrapper for Microsoft lib.exe
+
+me=ar-lib
+scriptversion=2012-03-01.08; # UTC
+
+# Copyright (C) 2010-2012 Free Software Foundation, Inc.
+# Written by Peter Rosin <peda@lysator.liu.se>.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+# 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>.
+
+
+# func_error message
+func_error ()
+{
+ echo "$me: $1" 1>&2
+ exit 1
+}
+
+file_conv=
+
+# func_file_conv build_file
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts.
+func_file_conv ()
+{
+ file=$1
+ case $file in
+ / | /[!/]*) # absolute file, and not a UNC file
+ if test -z "$file_conv"; then
+ # lazily determine how to convert abs files
+ case `uname -s` in
+ MINGW*)
+ file_conv=mingw
+ ;;
+ CYGWIN*)
+ file_conv=cygwin
+ ;;
+ *)
+ file_conv=wine
+ ;;
+ esac
+ fi
+ case $file_conv in
+ mingw)
+ file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+ ;;
+ cygwin)
+ file=`cygpath -m "$file" || echo "$file"`
+ ;;
+ wine)
+ file=`winepath -w "$file" || echo "$file"`
+ ;;
+ esac
+ ;;
+ esac
+}
+
+# func_at_file at_file operation archive
+# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE
+# for each of them.
+# When interpreting the content of the @FILE, do NOT use func_file_conv,
+# since the user would need to supply preconverted file names to
+# binutils ar, at least for MinGW.
+func_at_file ()
+{
+ operation=$2
+ archive=$3
+ at_file_contents=`cat "$1"`
+ eval set x "$at_file_contents"
+ shift
+
+ for member
+ do
+ $AR -NOLOGO $operation:"$member" "$archive" || exit $?
+ done
+}
+
+case $1 in
+ '')
+ func_error "no command. Try '$0 --help' for more information."
+ ;;
+ -h | --h*)
+ cat <<EOF
+Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...]
+
+Members may be specified in a file named with @FILE.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "$me, version $scriptversion"
+ exit $?
+ ;;
+esac
+
+if test $# -lt 3; then
+ func_error "you must specify a program, an action and an archive"
+fi
+
+AR=$1
+shift
+while :
+do
+ if test $# -lt 2; then
+ func_error "you must specify a program, an action and an archive"
+ fi
+ case $1 in
+ -lib | -LIB \
+ | -ltcg | -LTCG \
+ | -machine* | -MACHINE* \
+ | -subsystem* | -SUBSYSTEM* \
+ | -verbose | -VERBOSE \
+ | -wx* | -WX* )
+ AR="$AR $1"
+ shift
+ ;;
+ *)
+ action=$1
+ shift
+ break
+ ;;
+ esac
+done
+orig_archive=$1
+shift
+func_file_conv "$orig_archive"
+archive=$file
+
+# strip leading dash in $action
+action=${action#-}
+
+delete=
+extract=
+list=
+quick=
+replace=
+index=
+create=
+
+while test -n "$action"
+do
+ case $action in
+ d*) delete=yes ;;
+ x*) extract=yes ;;
+ t*) list=yes ;;
+ q*) quick=yes ;;
+ r*) replace=yes ;;
+ s*) index=yes ;;
+ S*) ;; # the index is always updated implicitly
+ c*) create=yes ;;
+ u*) ;; # TODO: don't ignore the update modifier
+ v*) ;; # TODO: don't ignore the verbose modifier
+ *)
+ func_error "unknown action specified"
+ ;;
+ esac
+ action=${action#?}
+done
+
+case $delete$extract$list$quick$replace,$index in
+ yes,* | ,yes)
+ ;;
+ yesyes*)
+ func_error "more than one action specified"
+ ;;
+ *)
+ func_error "no action specified"
+ ;;
+esac
+
+if test -n "$delete"; then
+ if test ! -f "$orig_archive"; then
+ func_error "archive not found"
+ fi
+ for member
+ do
+ case $1 in
+ @*)
+ func_at_file "${1#@}" -REMOVE "$archive"
+ ;;
+ *)
+ func_file_conv "$1"
+ $AR -NOLOGO -REMOVE:"$file" "$archive" || exit $?
+ ;;
+ esac
+ done
+
+elif test -n "$extract"; then
+ if test ! -f "$orig_archive"; then
+ func_error "archive not found"
+ fi
+ if test $# -gt 0; then
+ for member
+ do
+ case $1 in
+ @*)
+ func_at_file "${1#@}" -EXTRACT "$archive"
+ ;;
+ *)
+ func_file_conv "$1"
+ $AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $?
+ ;;
+ esac
+ done
+ else
+ $AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member
+ do
+ $AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $?
+ done
+ fi
+
+elif test -n "$quick$replace"; then
+ if test ! -f "$orig_archive"; then
+ if test -z "$create"; then
+ echo "$me: creating $orig_archive"
+ fi
+ orig_archive=
+ else
+ orig_archive=$archive
+ fi
+
+ for member
+ do
+ case $1 in
+ @*)
+ func_file_conv "${1#@}"
+ set x "$@" "@$file"
+ ;;
+ *)
+ func_file_conv "$1"
+ set x "$@" "$file"
+ ;;
+ esac
+ shift
+ shift
+ done
+
+ if test -n "$orig_archive"; then
+ $AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $?
+ else
+ $AR -NOLOGO -OUT:"$archive" "$@" || exit $?
+ fi
+
+elif test -n "$list"; then
+ if test ! -f "$orig_archive"; then
+ func_error "archive not found"
+ fi
+ $AR -NOLOGO -LIST "$archive" || exit $?
+fi
diff --git a/extension/build-aux/compile b/extension/build-aux/compile
new file mode 100755
index 00000000..531136b0
--- /dev/null
+++ b/extension/build-aux/compile
@@ -0,0 +1,347 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2013 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, see <http://www.gnu.org/licenses/>.
+
+# 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>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" "" $nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+ file=$1
+ case $file in
+ / | /[!/]*) # absolute file, and not a UNC file
+ if test -z "$file_conv"; then
+ # lazily determine how to convert abs files
+ case `uname -s` in
+ MINGW*)
+ file_conv=mingw
+ ;;
+ CYGWIN*)
+ file_conv=cygwin
+ ;;
+ *)
+ file_conv=wine
+ ;;
+ esac
+ fi
+ case $file_conv/,$2, in
+ *,$file_conv,*)
+ ;;
+ mingw/*)
+ file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+ ;;
+ cygwin/*)
+ file=`cygpath -m "$file" || echo "$file"`
+ ;;
+ wine/*)
+ file=`winepath -w "$file" || echo "$file"`
+ ;;
+ esac
+ ;;
+ esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+ func_file_conv "$1"
+ if test -z "$lib_path"; then
+ lib_path=$file
+ else
+ lib_path="$lib_path;$file"
+ fi
+ linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+ lib=$1
+ found=no
+ save_IFS=$IFS
+ IFS=';'
+ for dir in $lib_path $LIB
+ do
+ IFS=$save_IFS
+ if $shared && test -f "$dir/$lib.dll.lib"; then
+ found=yes
+ lib=$dir/$lib.dll.lib
+ break
+ fi
+ if test -f "$dir/$lib.lib"; then
+ found=yes
+ lib=$dir/$lib.lib
+ break
+ fi
+ if test -f "$dir/lib$lib.a"; then
+ found=yes
+ lib=$dir/lib$lib.a
+ break
+ fi
+ done
+ IFS=$save_IFS
+
+ if test "$found" != yes; then
+ lib=$lib.lib
+ fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+ # Assume a capable shell
+ lib_path=
+ shared=:
+ linker_opts=
+ for arg
+ do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ eat=1
+ case $2 in
+ *.o | *.[oO][bB][jJ])
+ func_file_conv "$2"
+ set x "$@" -Fo"$file"
+ shift
+ ;;
+ *)
+ func_file_conv "$2"
+ set x "$@" -Fe"$file"
+ shift
+ ;;
+ esac
+ ;;
+ -I)
+ eat=1
+ func_file_conv "$2" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -I*)
+ func_file_conv "${1#-I}" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -l)
+ eat=1
+ func_cl_dashl "$2"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -l*)
+ func_cl_dashl "${1#-l}"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -L)
+ eat=1
+ func_cl_dashL "$2"
+ ;;
+ -L*)
+ func_cl_dashL "${1#-L}"
+ ;;
+ -static)
+ shared=false
+ ;;
+ -Wl,*)
+ arg=${1#-Wl,}
+ save_ifs="$IFS"; IFS=','
+ for flag in $arg; do
+ IFS="$save_ifs"
+ linker_opts="$linker_opts $flag"
+ done
+ IFS="$save_ifs"
+ ;;
+ -Xlinker)
+ eat=1
+ linker_opts="$linker_opts $2"
+ ;;
+ -*)
+ set x "$@" "$1"
+ shift
+ ;;
+ *.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+ func_file_conv "$1"
+ set x "$@" -Tp"$file"
+ shift
+ ;;
+ *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+ func_file_conv "$1" mingw
+ set x "$@" "$file"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+ done
+ if test -n "$linker_opts"; then
+ linker_opts="-link$linker_opts"
+ fi
+ exec "$@" $linker_opts
+ exit 1
+}
+
+eat=
+
+case $1 in
+ '')
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "compile $scriptversion"
+ exit $?
+ ;;
+ cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+ func_cl_wrapper "$@" # Doesn't return...
+ ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ # So we strip '-o arg' only if arg is an object.
+ eat=1
+ case $2 in
+ *.o | *.obj)
+ ofile=$2
+ ;;
+ *)
+ set x "$@" -o "$2"
+ shift
+ ;;
+ esac
+ ;;
+ *.c)
+ cfile=$1
+ set x "$@" "$1"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+ # If no '-o' option was seen then we might have been invoked from a
+ # pattern rule where we don't need one. That is ok -- this is a
+ # normal compilation that the losing compiler can handle. If no
+ # '.c' file was seen then we are probably linking. That is also
+ # ok.
+ exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file. Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+ if mkdir "$lockdir" >/dev/null 2>&1; then
+ break
+ fi
+ sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+ test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+ test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+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-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/extension/build-aux/config.guess b/extension/build-aux/config.guess
new file mode 100755
index 00000000..4438cd70
--- /dev/null
+++ b/extension/build-aux/config.guess
@@ -0,0 +1,1568 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright 1992-2014 Free Software Foundation, Inc.
+
+timestamp='2014-01-01'
+
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# 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 Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+#
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+
+
+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 1992-2014 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 ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # 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 "$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 ; set_cc_for_build= ;'
+
+# 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
+
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+ ;;
+esac
+
+# 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 tuples: *-*-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 ;;
+ sh5el) machine=sh5le-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 -q __ELF__
+ 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 ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ 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'`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ 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 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ 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 ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ 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 ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ 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 ;;
+ 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 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ 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 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # 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 ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ 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 &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ 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 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????: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 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ 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 ;;
+ *: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
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ 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 ;;
+ *:AIX:*:[4567])
+ 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 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 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
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 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 && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ 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 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ 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 ;;
+ 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 ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ i*:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ 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 ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *: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/[-(].*//'`-${LIBC}
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ 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 -q ld.so.1
+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ cris:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ crisv32:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ frv:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #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-${LIBC}"; exit; }
+ ;;
+ or1k:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ or32:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-${LIBC}
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-${LIBC}
+ exit ;;
+ 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-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ exit ;;
+ x86_64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ 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 ;;
+ 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 ;;
+ 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 ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ 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 ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ 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 ;;
+ 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 ;;
+ 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 i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ 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 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 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; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ 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; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *: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 ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ 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 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
+ elif test "$UNAME_PROCESSOR" = i386 ; then
+ # Avoid executing cc on OS X 10.9, as it ships with a stub
+ # that puts up a graphical alert prompting to install
+ # developer tools. Any system running Mac OS X 10.7 or
+ # later (Darwin 11 and later) is required to have a 64-bit
+ # processor. This is not true of the ARM version of Darwin
+ # that Apple uses in portable devices.
+ UNAME_PROCESSOR=x86_64
+ fi
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *: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 ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-*:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *: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 ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
+esac
+
+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\n"); 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 && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# 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 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ c34*)
+ echo c34-convex-bsd
+ exit ;;
+ c38*)
+ echo c38-convex-bsd
+ exit ;;
+ c4*)
+ echo c4-convex-bsd
+ exit ;;
+ 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
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+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:
diff --git a/extension/build-aux/config.rpath b/extension/build-aux/config.rpath
new file mode 100755
index 00000000..ab6fd995
--- /dev/null
+++ b/extension/build-aux/config.rpath
@@ -0,0 +1,690 @@
+#! /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-2014 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 MSVC,
+# 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/'`
+
+# Code taken from libtool.m4's _LT_CC_BASENAME.
+
+for cc_temp in $CC""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
+
+# Code taken from libtool.m4's _LT_COMPILER_PIC.
+
+wl=
+if test "$GCC" = yes; then
+ wl='-Wl,'
+else
+ case "$host_os" in
+ aix*)
+ wl='-Wl,'
+ ;;
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ wl='-Wl,'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ wl='-Wl,'
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ ecc*)
+ wl='-Wl,'
+ ;;
+ icc* | ifort*)
+ wl='-Wl,'
+ ;;
+ lf95*)
+ wl='-Wl,'
+ ;;
+ nagfor*)
+ wl='-Wl,-Wl,,'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ wl='-Wl,'
+ ;;
+ ccc*)
+ wl='-Wl,'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ wl='-Wl,'
+ ;;
+ como)
+ wl='-lopt='
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ F* | *Sun*Fortran*)
+ wl=
+ ;;
+ *Sun\ C*)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ newsos6)
+ ;;
+ *nto* | *qnx*)
+ ;;
+ osf3* | osf4* | osf5*)
+ wl='-Wl,'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ wl='-Qoption ld '
+ ;;
+ *)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ sunos4*)
+ wl='-Qoption ld '
+ ;;
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ wl='-Wl,'
+ ;;
+ sysv4*MP*)
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ wl='-Wl,'
+ ;;
+ unicos*)
+ wl='-Wl,'
+ ;;
+ uts4*)
+ ;;
+ esac
+fi
+
+# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
+
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+
+case "$host_os" in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # 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
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ # 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'
+ case "$host_os" in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ fi
+ ;;
+ amigaos*)
+ case "$host_cpu" in
+ powerpc)
+ ;;
+ m68k)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+ beos*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ # 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
+ ;;
+ haiku*)
+ ;;
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ netbsd*)
+ ;;
+ solaris*)
+ 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
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+ sunos4*)
+ hardcode_direct=yes
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ if test "$ld_shlibs" = no; then
+ hardcode_libdir_flag_spec=
+ 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
+ ;;
+ aix[4-9]*)
+ 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].*|aix[5-9]*)
+ 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
+ :
+ 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*)
+ case "$host_cpu" in
+ powerpc)
+ ;;
+ m68k)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+ bsdi[45]*)
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ # 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 { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ dgux*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ freebsd2.2*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ freebsd2*)
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ freebsd* | 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*)
+ if test "$with_gnu_ld" = no; then
+ 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
+ fi
+ ;;
+ hpux11*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ ;;
+ *)
+ 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=:
+ ;;
+ *nto* | *qnx*)
+ ;;
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ 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
+ else
+ ld_shlibs=no
+ 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=:
+ ;;
+ 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*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ ;;
+ sysv5* | sco3.2v5* | sco5v6*)
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+ hardcode_libdir_separator=':'
+ ;;
+ uts4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+
+# Check dynamic linker characteristics
+# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
+# Unlike libtool.m4, here we don't care about _all_ names of the library, but
+# only about the one the linker finds when passed -lNAME. This is the last
+# element of library_names_spec in libtool.m4, or possibly two of them if the
+# linker has special search rules.
+library_names_spec= # the last element of library_names_spec in libtool.m4
+libname_spec='lib$name'
+case "$host_os" in
+ aix3*)
+ library_names_spec='$libname.a'
+ ;;
+ aix[4-9]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ amigaos*)
+ case "$host_cpu" in
+ powerpc*)
+ library_names_spec='$libname$shrext' ;;
+ m68k)
+ library_names_spec='$libname.a' ;;
+ esac
+ ;;
+ beos*)
+ library_names_spec='$libname$shrext'
+ ;;
+ bsdi[45]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ shrext=.dll
+ library_names_spec='$libname.dll.a $libname.lib'
+ ;;
+ darwin* | rhapsody*)
+ shrext=.dylib
+ library_names_spec='$libname$shrext'
+ ;;
+ dgux*)
+ library_names_spec='$libname$shrext'
+ ;;
+ freebsd* | dragonfly*)
+ case "$host_os" in
+ freebsd[123]*)
+ library_names_spec='$libname$shrext$versuffix' ;;
+ *)
+ library_names_spec='$libname$shrext' ;;
+ esac
+ ;;
+ gnu*)
+ library_names_spec='$libname$shrext'
+ ;;
+ haiku*)
+ library_names_spec='$libname$shrext'
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $host_cpu in
+ ia64*)
+ shrext=.so
+ ;;
+ hppa*64*)
+ shrext=.sl
+ ;;
+ *)
+ shrext=.sl
+ ;;
+ esac
+ library_names_spec='$libname$shrext'
+ ;;
+ interix[3-9]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ library_names_spec='$libname$shrext'
+ 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* | k*bsd*-gnu | kopensolaris*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ knetbsd*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ netbsd*)
+ library_names_spec='$libname$shrext'
+ ;;
+ newsos6)
+ library_names_spec='$libname$shrext'
+ ;;
+ *nto* | *qnx*)
+ library_names_spec='$libname$shrext'
+ ;;
+ openbsd*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ os2*)
+ libname_spec='$name'
+ shrext=.dll
+ library_names_spec='$libname.a'
+ ;;
+ osf3* | osf4* | osf5*)
+ library_names_spec='$libname$shrext'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sunos4*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ sysv4 | sysv4.3*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv4*MP*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ library_names_spec='$libname$shrext'
+ ;;
+ tpf*)
+ library_names_spec='$libname$shrext'
+ ;;
+ uts4*)
+ library_names_spec='$libname$shrext'
+ ;;
+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_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+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"
+
+# Format of library name prefix.
+libname_spec="$escaped_libname_spec"
+
+# Library names that the linker finds when passed -lNAME.
+library_names_spec="$escaped_library_names_spec"
+
+# 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
diff --git a/extension/build-aux/config.sub b/extension/build-aux/config.sub
new file mode 100755
index 00000000..092cff00
--- /dev/null
+++ b/extension/build-aux/config.sub
@@ -0,0 +1,1793 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright 1992-2014 Free Software Foundation, Inc.
+
+timestamp='2014-01-01'
+
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# 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 Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+#
+# 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.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# 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 1992-2014 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 ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # 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 ;;
+
+ * )
+ 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-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
+ *)
+ 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 | -microblaze*)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -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
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -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/'`
+ ;;
+ -sco5v6*)
+ # 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*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
+ -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 \
+ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | be32 | be64 \
+ | bfin \
+ | c4x | c8051 | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | epiphany \
+ | fido | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | k1om \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+ | open8 \
+ | or1k | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # 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-* \
+ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | k1om-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # 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
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ 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
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-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
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ 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*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
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
+ mingw32)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ 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
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i686-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ 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
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ 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
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ 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 | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ 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
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ 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
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ 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
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ 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
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ 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
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-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
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ 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.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -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* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
+ | -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* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -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* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+ # 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* | -haiku* \
+ | -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
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -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
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ c8051-*)
+ os=-elf
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ 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
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or1k-*)
+ 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
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-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
+ ;;
+ -cnk*|-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
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/extension/build-aux/depcomp b/extension/build-aux/depcomp
new file mode 100755
index 00000000..31788017
--- /dev/null
+++ b/extension/build-aux/depcomp
@@ -0,0 +1,756 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2013-05-30.07; # UTC
+
+# Copyright (C) 1999-2013 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, see <http://www.gnu.org/licenses/>.
+
+# 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 outputting dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit $?
+ ;;
+esac
+
+# Get the directory component of the given path, and save it in the
+# global variables '$dir'. Note that this directory component will
+# be either empty or ending with a '/' character. This is deliberate.
+set_dir_from ()
+{
+ case $1 in
+ */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
+ *) dir=;;
+ esac
+}
+
+# Get the suffix-stripped basename of the given path, and save it the
+# global variable '$base'.
+set_base_from ()
+{
+ base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
+}
+
+# If no dependency file was actually created by the compiler invocation,
+# we still have to create a dummy depfile, to avoid errors with the
+# Makefile "include basename.Plo" scheme.
+make_dummy_depfile ()
+{
+ echo "#dummy" > "$depfile"
+}
+
+# Factor out some common post-processing of the generated depfile.
+# Requires the auxiliary global variable '$tmpdepfile' to be set.
+aix_post_process_depfile ()
+{
+ # If the compiler actually managed to produce a dependency file,
+ # post-process it.
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form 'foo.o: dependency.h'.
+ # Do two passes, one to just change these to
+ # $object: dependency.h
+ # and one to simply output
+ # dependency.h:
+ # which is needed to avoid the deleted-header problem.
+ { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
+ sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
+ } > "$depfile"
+ rm -f "$tmpdepfile"
+ else
+ make_dummy_depfile
+ fi
+}
+
+# A tabulation character.
+tab=' '
+# A newline character.
+nl='
+'
+# Character ranges might be problematic outside the C locale.
+# These definitions help.
+upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
+lower=abcdefghijklmnopqrstuvwxyz
+digits=0123456789
+alpha=${upper}${lower}
+
+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"
+
+# Avoid interferences from the environment.
+gccflag= dashmflag=
+
+# 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
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+ # This is just like msvisualcpp but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+ # This is just like msvc7 but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+ # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
+ gccflag=-qmakedep=gcc,-MF
+ depmode=gcc
+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.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am. Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+ for arg
+ do
+ case $arg in
+ -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+ *) set fnord "$@" "$arg" ;;
+ esac
+ shift # fnord
+ shift # $arg
+ done
+ "$@"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
+## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
+## (see the conditional assignment to $gccflag above).
+## 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). Also, it might not be
+## supported by the other compilers which use the 'gcc' depmode.
+## - 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 -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # 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.
+## 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. hp depmode also adds that space, but also prefixes the VPATH
+## to the object. Take care to not repeat it in the output.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -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
+ ;;
+
+xlc)
+ # 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
+ ;;
+
+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.
+ set_dir_from "$object"
+ set_base_from "$object"
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$base.u
+ tmpdepfile3=$dir.libs/$base.u
+ "$@" -Wc,-M
+ else
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$dir$base.u
+ tmpdepfile3=$dir$base.u
+ "$@" -M
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ aix_post_process_depfile
+ ;;
+
+tcc)
+ # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
+ # FIXME: That version still under development at the moment of writing.
+ # Make that this statement remains true also for stable, released
+ # versions.
+ # It will wrap lines (doesn't matter whether long or short) with a
+ # trailing '\', as in:
+ #
+ # foo.o : \
+ # foo.c \
+ # foo.h \
+ #
+ # It will put a trailing '\' even on the last line, and will use leading
+ # spaces rather than leading tabs (at least since its commit 0394caf7
+ # "Emit spaces for -MD").
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
+ # We have to change lines of the first kind to '$object: \'.
+ sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
+ # And for each line of the second kind, we have to emit a 'dep.h:'
+ # dummy dependency, to avoid the deleted-header problem.
+ sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+## The order of this option in the case statement is important, since the
+## shell code in configure will try each of these formats in the order
+## listed in this file. A plain '-MD' option would be understood by many
+## compilers, so we must ensure this comes after the gcc and icc options.
+pgcc)
+ # Portland's C compiler understands '-MD'.
+ # Will always output deps to 'file.d' where file is the root name of the
+ # source file under compilation, even if file resides in a subdirectory.
+ # The object file name does not affect the name of the '.d' file.
+ # pgcc 10.2 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using '\' :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+ set_dir_from "$object"
+ # Use the source, not the object, to determine the base name, since
+ # that's sadly what pgcc will do too.
+ set_base_from "$source"
+ tmpdepfile=$base.d
+
+ # For projects that build the same source file twice into different object
+ # files, the pgcc approach of using the *source* file root name can cause
+ # problems in parallel builds. Use a locking strategy to avoid stomping on
+ # the same $tmpdepfile.
+ lockdir=$base.d-lock
+ trap "
+ echo '$0: caught signal, cleaning up...' >&2
+ rmdir '$lockdir'
+ exit 1
+ " 1 2 13 15
+ numtries=100
+ i=$numtries
+ while test $i -gt 0; do
+ # mkdir is a portable test-and-set.
+ if mkdir "$lockdir" 2>/dev/null; then
+ # This process acquired the lock.
+ "$@" -MD
+ stat=$?
+ # Release the lock.
+ rmdir "$lockdir"
+ break
+ else
+ # If the lock is being held by a different process, wait
+ # until the winning process is done or we timeout.
+ while test -d "$lockdir" && test $i -gt 0; do
+ sleep 1
+ i=`expr $i - 1`
+ done
+ fi
+ i=`expr $i - 1`
+ done
+ trap - 1 2 13 15
+ if test $i -le 0; then
+ echo "$0: failed to acquire lock after $numtries attempts" >&2
+ echo "$0: check lockdir '$lockdir'" >&2
+ exit 1
+ fi
+
+ if test $stat -ne 0; then
+ 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"
+ ;;
+
+hp2)
+ # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+ # compilers, which have integrated preprocessors. The correct option
+ # to use with these is +Maked; it writes dependencies to a file named
+ # 'foo.d', which lands next to the object file, wherever that
+ # happens to be.
+ # Much of this is similar to the tru64 case; see comments there.
+ set_dir_from "$object"
+ set_base_from "$object"
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir.libs/$base.d
+ "$@" -Wc,+Maked
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ "$@" +Maked
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
+ # Add 'dependent.h:' lines.
+ sed -ne '2,${
+ s/^ *//
+ s/ \\*$//
+ s/$/:/
+ p
+ }' "$tmpdepfile" >> "$depfile"
+ else
+ make_dummy_depfile
+ fi
+ rm -f "$tmpdepfile" "$tmpdepfile2"
+ ;;
+
+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.
+ set_dir_from "$object"
+ set_base_from "$object"
+
+ if test "$libtool" = yes; then
+ # Libtool generates 2 separate objects for the 2 libraries. These
+ # two compilations output dependencies 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$base.o.d # libtool 1.5
+ tmpdepfile2=$dir.libs/$base.o.d # Likewise.
+ tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ # Same post-processing that is required for AIX mode.
+ aix_post_process_depfile
+ ;;
+
+msvc7)
+ if test "$libtool" = yes; then
+ showIncludes=-Wc,-showIncludes
+ else
+ showIncludes=-showIncludes
+ fi
+ "$@" $showIncludes > "$tmpdepfile"
+ stat=$?
+ grep -v '^Note: including file: ' "$tmpdepfile"
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The first sed program below extracts the file names and escapes
+ # backslashes for cygpath. The second sed program outputs the file
+ # name when reading, but also accumulates all include files in the
+ # hold buffer in order to output them again at the end. This only
+ # works with sed implementations that can handle large buffers.
+ sed < "$tmpdepfile" -n '
+/^Note: including file: *\(.*\)/ {
+ s//\1/
+ s/\\/\\\\/g
+ p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+ s/.*/'"$tab"'/
+ G
+ p
+}' >> "$depfile"
+ echo >> "$depfile" # make sure the fragment doesn't end with a backslash
+ rm -f "$tmpdepfile"
+ ;;
+
+msvc7msys)
+ # 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
+ ;;
+
+#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 "X$1" != 'X--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|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this sed invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | 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 "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no eat=no
+ for arg
+ do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ if test $eat = yes; then
+ eat=no
+ continue
+ fi
+ 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.
+ -arch)
+ eat=yes ;;
+ -*|$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"
+ # makedepend may prepend the VPATH from the source file name to the object.
+ # No need to regex-escape $object, excess matching of '.' is harmless.
+ sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process the last invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed '1,2d' "$tmpdepfile" \
+ | tr ' ' "$nl" \
+ | 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 "X$1" != 'X--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 -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [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.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E 2>/dev/null |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+ echo "$tab" >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvcmsys)
+ # 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
+ ;;
+
+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-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/extension/build-aux/install-sh b/extension/build-aux/install-sh
new file mode 100755
index 00000000..04367377
--- /dev/null
+++ b/extension/build-aux/install-sh
@@ -0,0 +1,480 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2013-10-30.23; # UTC
+
+# 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.
+
+tab=' '
+nl='
+'
+IFS=" $tab$nl"
+
+# Set DOITPROG to "echo" to test this script.
+
+doit=${DOITPROG-}
+doit_exec=${doit:-exec}
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+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:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -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.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t) dst_arg=$2
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ shift;;
+
+ -T) no_target_directory=true;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ done
+fi
+
+if test $# -eq 0; 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
+
+if test -z "$dir_arg"; then
+ do_exit='(exit $ret); exit $ret'
+ trap "ret=129; $do_exit" 1
+ trap "ret=130; $do_exit" 2
+ trap "ret=141; $do_exit" 13
+ trap "ret=143; $do_exit" 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names problematic for 'test' and other utilities.
+ case $src in
+ -* | [=\(\)!]) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ 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 "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+ dst=$dst_arg
+
+ # 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: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ dstdir=`dirname "$dst"`
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ [-=\(\)!]*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ oIFS=$IFS
+ IFS=/
+ set -f
+ set fnord $dstdir
+ shift
+ set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test X"$d" = X && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # 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
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $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 $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+ set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ set +f &&
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 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.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/extension/build-aux/ltmain.sh b/extension/build-aux/ltmain.sh
new file mode 100644
index 00000000..555b7637
--- /dev/null
+++ b/extension/build-aux/ltmain.sh
@@ -0,0 +1,11044 @@
+#! /bin/sh
+## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
+## by inline-source v2014-01-03.01
+
+# libtool (GNU libtool) 2.4.3
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996-2014 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.
+
+# GNU Libtool 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.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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, see <http://www.gnu.org/licenses/>.
+
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION=2.4.3
+package_revision=2.4.3
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# Run './libtool --help' for help with using this script from the
+# command line.
+
+
+## ------------------------------- ##
+## User overridable command paths. ##
+## ------------------------------- ##
+
+# After configure completes, it has a better idea of some of the
+# shell tools we need than the defaults used by the functions shared
+# with bootstrap, so set those here where they can still be over-
+# ridden by the user, but otherwise take precedence.
+
+: ${AUTOCONF="autoconf"}
+: ${AUTOMAKE="automake"}
+
+
+## -------------------------- ##
+## Source external libraries. ##
+## -------------------------- ##
+
+# Much of our low-level functionality needs to be sourced from external
+# libraries, which are installed to $pkgauxdir.
+
+# Set a version string for this script.
+scriptversion=2014-01-03.01; # UTC
+
+# General shell script boiler plate, and helper functions.
+# Written by Gary V. Vaughan, 2004
+
+# Copyright (C) 2004-2014 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.
+
+# 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 3 of the License, or
+# (at your option) any later version.
+
+# As a special exception to the GNU General Public License, if you distribute
+# this file as part of a program or library that is built using GNU Libtool,
+# you may include this file under the same distribution terms that you use
+# for the rest of that program.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNES 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, see <http://www.gnu.org/licenses/>.
+
+# Please report bugs or propose patches to gary@gnu.org.
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# Evaluate this file near the top of your script to gain access to
+# the functions and variables defined here:
+#
+# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh
+#
+# If you need to override any of the default environment variable
+# settings, do that before evaluating this file.
+
+
+## -------------------- ##
+## Shell normalisation. ##
+## -------------------- ##
+
+# Some shells need a little help to be as Bourne compatible as possible.
+# Before doing anything else, make sure all that help has been provided!
+
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac
+fi
+
+# NLS nuisances: We save the old values in case they are required later.
+_G_user_locale=
+_G_safe_locale=
+for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+ eval "if test set = \"\${$_G_var+set}\"; then
+ save_$_G_var=\$$_G_var
+ $_G_var=C
+ export $_G_var
+ _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\"
+ _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\"
+ fi"
+done
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Make sure IFS has a sensible default
+sp=' '
+nl='
+'
+IFS="$sp $nl"
+
+# There are apparently some retarded systems that use ';' as a PATH separator!
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+
+## ------------------------- ##
+## Locate command utilities. ##
+## ------------------------- ##
+
+
+# func_executable_p FILE
+# ----------------------
+# Check that FILE is an executable regular file.
+func_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+}
+
+
+# func_path_progs PROGS_LIST CHECK_FUNC [PATH]
+# --------------------------------------------
+# Search for either a program that responds to --version with output
+# containing "GNU", or else returned by CHECK_FUNC otherwise, by
+# trying all the directories in PATH with each of the elements of
+# PROGS_LIST.
+#
+# CHECK_FUNC should accept the path to a candidate program, and
+# set $func_check_prog_result if it truncates its output less than
+# $_G_path_prog_max characters.
+func_path_progs ()
+{
+ _G_progs_list=$1
+ _G_check_func=$2
+ _G_PATH=${3-"$PATH"}
+
+ _G_path_prog_max=0
+ _G_path_prog_found=false
+ _G_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+ for _G_dir in $_G_PATH; do
+ IFS=$_G_save_IFS
+ test -z "$_G_dir" && _G_dir=.
+ for _G_prog_name in $_G_progs_list; do
+ for _exeext in '' .EXE; do
+ _G_path_prog=$_G_dir/$_G_prog_name$_exeext
+ func_executable_p "$_G_path_prog" || continue
+ case `"$_G_path_prog" --version 2>&1` in
+ *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;;
+ *) $_G_check_func $_G_path_prog
+ func_path_progs_result=$func_check_prog_result
+ ;;
+ esac
+ $_G_path_prog_found && break 3
+ done
+ done
+ done
+ IFS=$_G_save_IFS
+ test -z "$func_path_progs_result" && {
+ echo "no acceptable sed could be found in \$PATH" >&2
+ exit 1
+ }
+}
+
+
+# We want to be able to use the functions in this file before configure
+# has figured out where the best binaries are kept, which means we have
+# to search for them ourselves - except when the results are already set
+# where we skip the searches.
+
+# Unless the user overrides by setting SED, search the path for either GNU
+# sed, or the sed that truncates its output the least.
+test -z "$SED" && {
+ _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for _G_i in 1 2 3 4 5 6 7; do
+ _G_sed_script=$_G_sed_script$nl$_G_sed_script
+ done
+ echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed
+ _G_sed_script=
+
+ func_check_prog_sed ()
+ {
+ _G_path_prog=$1
+
+ _G_count=0
+ printf 0123456789 >conftest.in
+ while :
+ do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo '' >> conftest.nl
+ "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break
+ diff conftest.out conftest.nl >/dev/null 2>&1 || break
+ _G_count=`expr $_G_count + 1`
+ if test "$_G_count" -gt "$_G_path_prog_max"; then
+ # Best one so far, save it but keep looking for a better one
+ func_check_prog_result=$_G_path_prog
+ _G_path_prog_max=$_G_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test 10 -lt "$_G_count" && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out
+ }
+
+ func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
+ rm -f conftest.sed
+ SED=$func_path_progs_result
+}
+
+
+# Unless the user overrides by setting GREP, search the path for either GNU
+# grep, or the grep that truncates its output the least.
+test -z "$GREP" && {
+ func_check_prog_grep ()
+ {
+ _G_path_prog=$1
+
+ _G_count=0
+ _G_path_prog_max=0
+ printf 0123456789 >conftest.in
+ while :
+ do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo 'GREP' >> conftest.nl
+ "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break
+ diff conftest.out conftest.nl >/dev/null 2>&1 || break
+ _G_count=`expr $_G_count + 1`
+ if test "$_G_count" -gt "$_G_path_prog_max"; then
+ # Best one so far, save it but keep looking for a better one
+ func_check_prog_result=$_G_path_prog
+ _G_path_prog_max=$_G_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test 10 -lt "$_G_count" && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out
+ }
+
+ func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
+ GREP=$func_path_progs_result
+}
+
+
+## ------------------------------- ##
+## User overridable command paths. ##
+## ------------------------------- ##
+
+# All uppercase variable names are used for environment variables. These
+# variables can be overridden by the user before calling a script that
+# uses them if a suitable command of that name is not already available
+# in the command search PATH.
+
+: ${CP="cp -f"}
+: ${ECHO="printf %s\n"}
+: ${EGREP="$GREP -E"}
+: ${FGREP="$GREP -F"}
+: ${LN_S="ln -s"}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+
+
+## -------------------- ##
+## Useful sed snippets. ##
+## -------------------- ##
+
+sed_dirname='s|/[^/]*$||'
+sed_basename='s|^.*/||'
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s|\([`"$\\]\)|\\\1|g'
+
+# Same as above, but do not quote variable references.
+sed_double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g'
+
+# Sed substitution that converts a w32 file name or path
+# that contains forward slashes, into one that contains
+# (escaped) backslashes. A very naive implementation.
+sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-'\' parameter expansions in output of sed_double_quote_subst that
+# were '\'-ed in input to the same. If an odd number of '\' preceded a
+# '$' in input to sed_double_quote_subst, that '$' was protected from
+# expansion. Since each input '\' is now two '\'s, look for any number
+# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'.
+_G_bs='\\'
+_G_bs2='\\\\'
+_G_bs4='\\\\\\\\'
+_G_dollar='\$'
+sed_double_backslash="\
+ s/$_G_bs4/&\\
+/g
+ s/^$_G_bs2$_G_dollar/$_G_bs&/
+ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g
+ s/\n//g"
+
+
+## ----------------- ##
+## Global variables. ##
+## ----------------- ##
+
+# Except for the global variables explicitly listed below, the following
+# functions in the '^func_' namespace, and the '^require_' namespace
+# variables initialised in the 'Resource management' section, sourcing
+# this file will not pollute your global namespace with anything
+# else. There's no portable way to scope variables in Bourne shell
+# though, so actually running these functions will sometimes place
+# results into a variable named after the function, and often use
+# temporary variables in the '^_G_' namespace. If you are careful to
+# avoid using those namespaces casually in your sourcing script, things
+# should continue to work as you expect. And, of course, you can freely
+# overwrite any of the functions or variables defined here before
+# calling anything to customize them.
+
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
+
+# Allow overriding, eg assuming that you follow the convention of
+# putting '$debug_cmd' at the start of all your functions, you can get
+# bash to show function call trace with:
+#
+# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
+debug_cmd=${debug_cmd-":"}
+exit_cmd=:
+
+# By convention, finish your script with:
+#
+# exit $exit_status
+#
+# so that you can set exit_status to non-zero if you want to indicate
+# something went wrong during execution without actually bailing out at
+# the point of failure.
+exit_status=$EXIT_SUCCESS
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath=$0
+
+# The name of this program.
+progname=`$ECHO "$progpath" |$SED "$sed_basename"`
+
+# Make sure we have an absolute progpath for reexecution:
+case $progpath in
+ [\\/]*|[A-Za-z]:\\*) ;;
+ *[\\/]*)
+ progdir=`$ECHO "$progpath" |$SED "$sed_dirname"`
+ progdir=`cd "$progdir" && pwd`
+ progpath=$progdir/$progname
+ ;;
+ *)
+ _G_IFS=$IFS
+ IFS=${PATH_SEPARATOR-:}
+ for progdir in $PATH; do
+ IFS=$_G_IFS
+ test -x "$progdir/$progname" && break
+ done
+ IFS=$_G_IFS
+ test -n "$progdir" || progdir=`pwd`
+ progpath=$progdir/$progname
+ ;;
+esac
+
+
+## ----------------- ##
+## Standard options. ##
+## ----------------- ##
+
+# The following options affect the operation of the functions defined
+# below, and should be set appropriately depending on run-time para-
+# meters passed on the command line.
+
+opt_dry_run=false
+opt_quiet=false
+opt_verbose=false
+
+# Categories 'all' and 'none' are always available. Append any others
+# you will pass as the first argument to func_warning from your own
+# code.
+warning_categories=
+
+# By default, display warnings according to 'opt_warning_types'. Set
+# 'warning_func' to ':' to elide all warnings, or func_fatal_error to
+# treat the next displayed warning as a fatal error.
+warning_func=func_warn_and_continue
+
+# Set to 'all' to display all warnings, 'none' to suppress all
+# warnings, or a space delimited list of some subset of
+# 'warning_categories' to display only the listed warnings.
+opt_warning_types=all
+
+
+## -------------------- ##
+## Resource management. ##
+## -------------------- ##
+
+# This section contains definitions for functions that each ensure a
+# particular resource (a file, or a non-empty configuration variable for
+# example) is available, and if appropriate to extract default values
+# from pertinent package files. Call them using their associated
+# 'require_*' variable to ensure that they are executed, at most, once.
+#
+# It's entirely deliberate that calling these functions can set
+# variables that don't obey the namespace limitations obeyed by the rest
+# of this file, in order that that they be as useful as possible to
+# callers.
+
+
+# require_term_colors
+# -------------------
+# Allow display of bold text on terminals that support it.
+require_term_colors=func_require_term_colors
+func_require_term_colors ()
+{
+ $debug_cmd
+
+ test -t 1 && {
+ # COLORTERM and USE_ANSI_COLORS environment variables take
+ # precedence, because most terminfo databases neglect to describe
+ # whether color sequences are supported.
+ test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"}
+
+ if test 1 = "$USE_ANSI_COLORS"; then
+ # Standard ANSI escape sequences
+ tc_reset=''
+ tc_bold=''; tc_standout=''
+ tc_red=''; tc_green=''
+ tc_blue=''; tc_cyan=''
+ else
+ # Otherwise trust the terminfo database after all.
+ test -n "`tput sgr0 2>/dev/null`" && {
+ tc_reset=`tput sgr0`
+ test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`
+ tc_standout=$tc_bold
+ test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`
+ test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`
+ test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`
+ test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`
+ test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`
+ }
+ fi
+ }
+
+ require_term_colors=:
+}
+
+
+## ----------------- ##
+## Function library. ##
+## ----------------- ##
+
+# This section contains a variety of useful functions to call in your
+# scripts. Take note of the portable wrappers for features provided by
+# some modern shells, which will fall back to slower equivalents on
+# less featureful shells.
+
+
+# func_append VAR VALUE
+# ---------------------
+# Append VALUE onto the existing contents of VAR.
+
+ # We should try to minimise forks, especially on Windows where they are
+ # unreasonably slow, so skip the feature probes when bash or zsh are
+ # being used:
+ if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then
+ : ${_G_HAVE_ARITH_OP="yes"}
+ : ${_G_HAVE_XSI_OPS="yes"}
+ # The += operator was introduced in bash 3.1
+ case $BASH_VERSION in
+ [12].* | 3.0 | 3.0*) ;;
+ *)
+ : ${_G_HAVE_PLUSEQ_OP="yes"}
+ ;;
+ esac
+ fi
+
+ # _G_HAVE_PLUSEQ_OP
+ # Can be empty, in which case the shell is probed, "yes" if += is
+ # useable or anything else if it does not work.
+ test -z "$_G_HAVE_PLUSEQ_OP" \
+ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
+ && _G_HAVE_PLUSEQ_OP=yes
+
+if test yes = "$_G_HAVE_PLUSEQ_OP"
+then
+ # This is an XSI compatible shell, allowing a faster implementation...
+ eval 'func_append ()
+ {
+ $debug_cmd
+
+ eval "$1+=\$2"
+ }'
+else
+ # ...otherwise fall back to using expr, which is often a shell builtin.
+ func_append ()
+ {
+ $debug_cmd
+
+ eval "$1=\$$1\$2"
+ }
+fi
+
+
+# func_append_quoted VAR VALUE
+# ----------------------------
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+if test yes = "$_G_HAVE_PLUSEQ_OP"; then
+ eval 'func_append_quoted ()
+ {
+ $debug_cmd
+
+ func_quote_for_eval "$2"
+ eval "$1+=\\ \$func_quote_for_eval_result"
+ }'
+else
+ func_append_quoted ()
+ {
+ $debug_cmd
+
+ func_quote_for_eval "$2"
+ eval "$1=\$$1\\ \$func_quote_for_eval_result"
+ }
+fi
+
+
+# func_append_uniq VAR VALUE
+# --------------------------
+# Append unique VALUE onto the existing contents of VAR, assuming
+# entries are delimited by the first character of VALUE. For example:
+#
+# func_append_uniq options " --another-option option-argument"
+#
+# will only append to $options if " --another-option option-argument "
+# is not already present somewhere in $options already (note spaces at
+# each end implied by leading space in second argument).
+func_append_uniq ()
+{
+ $debug_cmd
+
+ eval _G_current_value='`$ECHO $'$1'`'
+ _G_delim=`expr "$2" : '\(.\)'`
+
+ case $_G_delim$_G_current_value$_G_delim in
+ *"$2$_G_delim"*) ;;
+ *) func_append "$@" ;;
+ esac
+}
+
+
+# func_arith TERM...
+# ------------------
+# Set func_arith_result to the result of evaluating TERMs.
+ test -z "$_G_HAVE_ARITH_OP" \
+ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \
+ && _G_HAVE_ARITH_OP=yes
+
+if test yes = "$_G_HAVE_ARITH_OP"; then
+ eval 'func_arith ()
+ {
+ $debug_cmd
+
+ func_arith_result=$(( $* ))
+ }'
+else
+ func_arith ()
+ {
+ $debug_cmd
+
+ func_arith_result=`expr "$@"`
+ }
+fi
+
+
+# func_basename FILE
+# ------------------
+# Set func_basename_result to FILE with everything up to and including
+# the last / stripped.
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ # If this shell supports suffix pattern removal, then use it to avoid
+ # forking. Hide the definitions single quotes in case the shell chokes
+ # on unsupported syntax...
+ _b='func_basename_result=${1##*/}'
+ _d='case $1 in
+ */*) func_dirname_result=${1%/*}$2 ;;
+ * ) func_dirname_result=$3 ;;
+ esac'
+
+else
+ # ...otherwise fall back to using sed.
+ _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`'
+ _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"`
+ if test "X$func_dirname_result" = "X$1"; then
+ func_dirname_result=$3
+ else
+ func_append func_dirname_result "$2"
+ fi'
+fi
+
+eval 'func_basename ()
+{
+ $debug_cmd
+
+ '"$_b"'
+}'
+
+
+# func_dirname FILE APPEND NONDIR_REPLACEMENT
+# -------------------------------------------
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+eval 'func_dirname ()
+{
+ $debug_cmd
+
+ '"$_d"'
+}'
+
+
+# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT
+# --------------------------------------------------------
+# Perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# For efficiency, we do not delegate to the functions above but instead
+# duplicate the functionality here.
+eval 'func_dirname_and_basename ()
+{
+ $debug_cmd
+
+ '"$_b"'
+ '"$_d"'
+}'
+
+
+# func_echo ARG...
+# ----------------
+# Echo program name prefixed message.
+func_echo ()
+{
+ $debug_cmd
+
+ _G_message=$*
+
+ func_echo_IFS=$IFS
+ IFS=$nl
+ for _G_line in $_G_message; do
+ IFS=$func_echo_IFS
+ $ECHO "$progname: $_G_line"
+ done
+ IFS=$func_echo_IFS
+}
+
+
+# func_echo_all ARG...
+# --------------------
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+
+# func_echo_infix_1 INFIX ARG...
+# ------------------------------
+# Echo program name, followed by INFIX on the first line, with any
+# additional lines not showing INFIX.
+func_echo_infix_1 ()
+{
+ $debug_cmd
+
+ $require_term_colors
+
+ _G_infix=$1; shift
+ _G_indent=$_G_infix
+ _G_prefix="$progname: $_G_infix: "
+ _G_message=$*
+
+ # Strip color escape sequences before counting printable length
+ for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan"
+ do
+ test -n "$_G_tc" && {
+ _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"`
+ _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"`
+ }
+ done
+ _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes
+
+ func_echo_infix_1_IFS=$IFS
+ IFS=$nl
+ for _G_line in $_G_message; do
+ IFS=$func_echo_infix_1_IFS
+ $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2
+ _G_prefix=$_G_indent
+ done
+ IFS=$func_echo_infix_1_IFS
+}
+
+
+# func_error ARG...
+# -----------------
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+ $debug_cmd
+
+ $require_term_colors
+
+ func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2
+}
+
+
+# func_fatal_error ARG...
+# -----------------------
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+ $debug_cmd
+
+ func_error "$*"
+ exit $EXIT_FAILURE
+}
+
+
+# func_grep EXPRESSION FILENAME
+# -----------------------------
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+ $debug_cmd
+
+ $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_len STRING
+# ---------------
+# Set func_len_result to the length of STRING. STRING may not
+# start with a hyphen.
+ test -z "$_G_HAVE_XSI_OPS" \
+ && (eval 'x=a/b/c;
+ test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
+ && _G_HAVE_XSI_OPS=yes
+
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ eval 'func_len ()
+ {
+ $debug_cmd
+
+ func_len_result=${#1}
+ }'
+else
+ func_len ()
+ {
+ $debug_cmd
+
+ func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+ }
+fi
+
+
+# func_mkdir_p DIRECTORY-PATH
+# ---------------------------
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+ $debug_cmd
+
+ _G_directory_path=$1
+ _G_dir_list=
+
+ if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then
+
+ # Protect directory names starting with '-'
+ case $_G_directory_path in
+ -*) _G_directory_path=./$_G_directory_path ;;
+ esac
+
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$_G_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ _G_dir_list=$_G_directory_path:$_G_dir_list
+
+ # If the last portion added has no slash in it, the list is done
+ case $_G_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"`
+ done
+ _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'`
+
+ func_mkdir_p_IFS=$IFS; IFS=:
+ for _G_dir in $_G_dir_list; do
+ IFS=$func_mkdir_p_IFS
+ # mkdir can fail with a 'File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$_G_dir" 2>/dev/null || :
+ done
+ IFS=$func_mkdir_p_IFS
+
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$_G_directory_path" || \
+ func_fatal_error "Failed to create '$1'"
+ fi
+}
+
+
+# func_mktempdir [BASENAME]
+# -------------------------
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible. If
+# given, BASENAME is the basename for that directory.
+func_mktempdir ()
+{
+ $debug_cmd
+
+ _G_template=${TMPDIR-/tmp}/${1-$progname}
+
+ if test : = "$opt_dry_run"; then
+ # Return a directory name, but don't create it in dry-run mode
+ _G_tmpdir=$_G_template-$$
+ else
+
+ # If mktemp works, use that first and foremost
+ _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null`
+
+ if test ! -d "$_G_tmpdir"; then
+ # Failing that, at least try and use $RANDOM to avoid a race
+ _G_tmpdir=$_G_template-${RANDOM-0}$$
+
+ func_mktempdir_umask=`umask`
+ umask 0077
+ $MKDIR "$_G_tmpdir"
+ umask $func_mktempdir_umask
+ fi
+
+ # If we're not in dry-run mode, bomb out on failure
+ test -d "$_G_tmpdir" || \
+ func_fatal_error "cannot create temporary directory '$_G_tmpdir'"
+ fi
+
+ $ECHO "$_G_tmpdir"
+}
+
+
+# func_normal_abspath PATH
+# ------------------------
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+func_normal_abspath ()
+{
+ $debug_cmd
+
+ # These SED scripts presuppose an absolute path with a trailing slash.
+ _G_pathcar='s|^/\([^/]*\).*$|\1|'
+ _G_pathcdr='s|^/[^/]*||'
+ _G_removedotparts=':dotsl
+ s|/\./|/|g
+ t dotsl
+ s|/\.$|/|'
+ _G_collapseslashes='s|/\{1,\}|/|g'
+ _G_finalslash='s|/*$|/|'
+
+ # Start from root dir and reassemble the path.
+ func_normal_abspath_result=
+ func_normal_abspath_tpath=$1
+ func_normal_abspath_altnamespace=
+ case $func_normal_abspath_tpath in
+ "")
+ # Empty path, that just means $cwd.
+ func_stripname '' '/' "`pwd`"
+ func_normal_abspath_result=$func_stripname_result
+ return
+ ;;
+ # The next three entries are used to spot a run of precisely
+ # two leading slashes without using negated character classes;
+ # we take advantage of case's first-match behaviour.
+ ///*)
+ # Unusual form of absolute path, do nothing.
+ ;;
+ //*)
+ # Not necessarily an ordinary path; POSIX reserves leading '//'
+ # and for example Cygwin uses it to access remote file shares
+ # over CIFS/SMB, so we conserve a leading double slash if found.
+ func_normal_abspath_altnamespace=/
+ ;;
+ /*)
+ # Absolute path, do nothing.
+ ;;
+ *)
+ # Relative path, prepend $cwd.
+ func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+ ;;
+ esac
+
+ # Cancel out all the simple stuff to save iterations. We also want
+ # the path to end with a slash for ease of parsing, so make sure
+ # there is one (and only one) here.
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"`
+ while :; do
+ # Processed it all yet?
+ if test / = "$func_normal_abspath_tpath"; then
+ # If we ascended to the root using ".." the result may be empty now.
+ if test -z "$func_normal_abspath_result"; then
+ func_normal_abspath_result=/
+ fi
+ break
+ fi
+ func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$_G_pathcar"`
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$_G_pathcdr"`
+ # Figure out what to do with it
+ case $func_normal_abspath_tcomponent in
+ "")
+ # Trailing empty path component, ignore it.
+ ;;
+ ..)
+ # Parent dir; strip last assembled component from result.
+ func_dirname "$func_normal_abspath_result"
+ func_normal_abspath_result=$func_dirname_result
+ ;;
+ *)
+ # Actual path component, append it.
+ func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent"
+ ;;
+ esac
+ done
+ # Restore leading double-slash if one was found on entry.
+ func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+
+# func_notquiet ARG...
+# --------------------
+# Echo program name prefixed message only when not in quiet mode.
+func_notquiet ()
+{
+ $debug_cmd
+
+ $opt_quiet || func_echo ${1+"$@"}
+
+ # A bug in bash halts the script if the last line of a function
+ # fails when set -e is in force, so we need another command to
+ # work around that:
+ :
+}
+
+
+# func_relative_path SRCDIR DSTDIR
+# --------------------------------
+# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR.
+func_relative_path ()
+{
+ $debug_cmd
+
+ func_relative_path_result=
+ func_normal_abspath "$1"
+ func_relative_path_tlibdir=$func_normal_abspath_result
+ func_normal_abspath "$2"
+ func_relative_path_tbindir=$func_normal_abspath_result
+
+ # Ascend the tree starting from libdir
+ while :; do
+ # check if we have found a prefix of bindir
+ case $func_relative_path_tbindir in
+ $func_relative_path_tlibdir)
+ # found an exact match
+ func_relative_path_tcancelled=
+ break
+ ;;
+ $func_relative_path_tlibdir*)
+ # found a matching prefix
+ func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+ func_relative_path_tcancelled=$func_stripname_result
+ if test -z "$func_relative_path_result"; then
+ func_relative_path_result=.
+ fi
+ break
+ ;;
+ *)
+ func_dirname $func_relative_path_tlibdir
+ func_relative_path_tlibdir=$func_dirname_result
+ if test -z "$func_relative_path_tlibdir"; then
+ # Have to descend all the way to the root!
+ func_relative_path_result=../$func_relative_path_result
+ func_relative_path_tcancelled=$func_relative_path_tbindir
+ break
+ fi
+ func_relative_path_result=../$func_relative_path_result
+ ;;
+ esac
+ done
+
+ # Now calculate path; take care to avoid doubling-up slashes.
+ func_stripname '' '/' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ func_stripname '/' '/' "$func_relative_path_tcancelled"
+ if test -n "$func_stripname_result"; then
+ func_append func_relative_path_result "/$func_stripname_result"
+ fi
+
+ # Normalisation. If bindir is libdir, return '.' else relative path.
+ if test -n "$func_relative_path_result"; then
+ func_stripname './' '' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ fi
+
+ test -n "$func_relative_path_result" || func_relative_path_result=.
+
+ :
+}
+
+
+# func_quote_for_eval ARG...
+# --------------------------
+# Aesthetically quote ARGs to be evaled later.
+# This function returns two values:
+# i) func_quote_for_eval_result
+# double-quoted, suitable for a subsequent eval
+# ii) func_quote_for_eval_unquoted_result
+# has all characters that are still active within double
+# quotes backslashified.
+func_quote_for_eval ()
+{
+ $debug_cmd
+
+ func_quote_for_eval_unquoted_result=
+ func_quote_for_eval_result=
+ while test 0 -lt $#; do
+ case $1 in
+ *[\\\`\"\$]*)
+ _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
+ *)
+ _G_unquoted_arg=$1 ;;
+ esac
+ if test -n "$func_quote_for_eval_unquoted_result"; then
+ func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
+ else
+ func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
+ fi
+
+ case $_G_unquoted_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting, command substitution and variable expansion
+ # for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ _G_quoted_arg=\"$_G_unquoted_arg\"
+ ;;
+ *)
+ _G_quoted_arg=$_G_unquoted_arg
+ ;;
+ esac
+
+ if test -n "$func_quote_for_eval_result"; then
+ func_append func_quote_for_eval_result " $_G_quoted_arg"
+ else
+ func_append func_quote_for_eval_result "$_G_quoted_arg"
+ fi
+ shift
+ done
+}
+
+
+# func_quote_for_expand ARG
+# -------------------------
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+ $debug_cmd
+
+ case $1 in
+ *[\\\`\"]*)
+ _G_arg=`$ECHO "$1" | $SED \
+ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
+ *)
+ _G_arg=$1 ;;
+ esac
+
+ case $_G_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting and command substitution for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ _G_arg=\"$_G_arg\"
+ ;;
+ esac
+
+ func_quote_for_expand_result=$_G_arg
+}
+
+
+# func_stripname PREFIX SUFFIX NAME
+# ---------------------------------
+# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ eval 'func_stripname ()
+ {
+ $debug_cmd
+
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary variable first.
+ func_stripname_result=$3
+ func_stripname_result=${func_stripname_result#"$1"}
+ func_stripname_result=${func_stripname_result%"$2"}
+ }'
+else
+ func_stripname ()
+ {
+ $debug_cmd
+
+ case $2 in
+ .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;;
+ *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;;
+ esac
+ }
+fi
+
+
+# func_show_eval CMD [FAIL_EXP]
+# -----------------------------
+# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+ $debug_cmd
+
+ _G_cmd=$1
+ _G_fail_exp=${2-':'}
+
+ func_quote_for_expand "$_G_cmd"
+ eval "func_notquiet $func_quote_for_expand_result"
+
+ $opt_dry_run || {
+ eval "$_G_cmd"
+ _G_status=$?
+ if test 0 -ne "$_G_status"; then
+ eval "(exit $_G_status); $_G_fail_exp"
+ fi
+ }
+}
+
+
+# func_show_eval_locale CMD [FAIL_EXP]
+# ------------------------------------
+# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it. Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+ $debug_cmd
+
+ _G_cmd=$1
+ _G_fail_exp=${2-':'}
+
+ $opt_quiet || {
+ func_quote_for_expand "$_G_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ $opt_dry_run || {
+ eval "$_G_user_locale
+ $_G_cmd"
+ _G_status=$?
+ eval "$_G_safe_locale"
+ if test 0 -ne "$_G_status"; then
+ eval "(exit $_G_status); $_G_fail_exp"
+ fi
+ }
+}
+
+
+# func_tr_sh
+# ----------
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result. All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+ $debug_cmd
+
+ case $1 in
+ [0-9]* | *[!a-zA-Z0-9_]*)
+ func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'`
+ ;;
+ * )
+ func_tr_sh_result=$1
+ ;;
+ esac
+}
+
+
+# func_verbose ARG...
+# -------------------
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+ $debug_cmd
+
+ $opt_verbose && func_echo "$*"
+
+ :
+}
+
+
+# func_warn_and_continue ARG...
+# -----------------------------
+# Echo program name prefixed warning message to standard error.
+func_warn_and_continue ()
+{
+ $debug_cmd
+
+ $require_term_colors
+
+ func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2
+}
+
+
+# func_warning CATEGORY ARG...
+# ----------------------------
+# Echo program name prefixed warning message to standard error. Warning
+# messages can be filtered according to CATEGORY, where this function
+# elides messages where CATEGORY is not listed in the global variable
+# 'opt_warning_types'.
+func_warning ()
+{
+ $debug_cmd
+
+ # CATEGORY must be in the warning_categories list!
+ case " $warning_categories " in
+ *" $1 "*) ;;
+ *) func_internal_error "invalid warning category '$1'" ;;
+ esac
+
+ _G_category=$1
+ shift
+
+ case " $opt_warning_types " in
+ *" $_G_category "*) $warning_func ${1+"$@"} ;;
+ esac
+}
+
+
+# func_sort_ver VER1 VER2
+# -----------------------
+# 'sort -V' is not generally available.
+# Note this deviates from the version comparison in automake
+# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
+# but this should suffice as we won't be specifying old
+# version formats or redundant trailing .0 in bootstrap.conf.
+# If we did want full compatibility then we should probably
+# use m4_version_compare from autoconf.
+func_sort_ver ()
+{
+ $debug_cmd
+
+ printf '%s\n%s\n' "$1" "$2" \
+ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n
+}
+
+# func_lt_ver PREV CURR
+# ---------------------
+# Return true if PREV and CURR are in the correct order according to
+# func_sort_ver, otherwise false. Use it like this:
+#
+# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..."
+func_lt_ver ()
+{
+ $debug_cmd
+
+ test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q`
+}
+
+
+# Local variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-time-zone: "UTC"
+# End:
+#! /bin/sh
+
+# Set a version string for this script.
+scriptversion=2014-01-07.03; # UTC
+
+# A portable, pluggable option parser for Bourne shell.
+# Written by Gary V. Vaughan, 2010
+
+# Copyright (C) 2010-2014 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.
+
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+
+# Please report bugs or propose patches to gary@gnu.org.
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# This file is a library for parsing options in your shell scripts along
+# with assorted other useful supporting features that you can make use
+# of too.
+#
+# For the simplest scripts you might need only:
+#
+# #!/bin/sh
+# . relative/path/to/funclib.sh
+# . relative/path/to/options-parser
+# scriptversion=1.0
+# func_options ${1+"$@"}
+# eval set dummy "$func_options_result"; shift
+# ...rest of your script...
+#
+# In order for the '--version' option to work, you will need to have a
+# suitably formatted comment like the one at the top of this file
+# starting with '# Written by ' and ending with '# warranty; '.
+#
+# For '-h' and '--help' to work, you will also need a one line
+# description of your script's purpose in a comment directly above the
+# '# Written by ' line, like the one at the top of this file.
+#
+# The default options also support '--debug', which will turn on shell
+# execution tracing (see the comment above debug_cmd below for another
+# use), and '--verbose' and the func_verbose function to allow your script
+# to display verbose messages only when your user has specified
+# '--verbose'.
+#
+# After sourcing this file, you can plug processing for additional
+# options by amending the variables from the 'Configuration' section
+# below, and following the instructions in the 'Option parsing'
+# section further down.
+
+## -------------- ##
+## Configuration. ##
+## -------------- ##
+
+# You should override these variables in your script after sourcing this
+# file so that they reflect the customisations you have added to the
+# option parser.
+
+# The usage line for option parsing errors and the start of '-h' and
+# '--help' output messages. You can embed shell variables for delayed
+# expansion at the time the message is displayed, but you will need to
+# quote other shell meta-characters carefully to prevent them being
+# expanded when the contents are evaled.
+usage='$progpath [OPTION]...'
+
+# Short help message in response to '-h' and '--help'. Add to this or
+# override it after sourcing this library to reflect the full set of
+# options your script accepts.
+usage_message="\
+ --debug enable verbose shell tracing
+ -W, --warnings=CATEGORY
+ report the warnings falling in CATEGORY [all]
+ -v, --verbose verbosely report processing
+ --version print version information and exit
+ -h, --help print short or long help message and exit
+"
+
+# Additional text appended to 'usage_message' in response to '--help'.
+long_help_message="
+Warning categories include:
+ 'all' show all warnings
+ 'none' turn off all the warnings
+ 'error' warnings are treated as fatal errors"
+
+# Help message printed before fatal option parsing errors.
+fatal_help="Try '\$progname --help' for more information."
+
+
+
+## ------------------------- ##
+## Hook function management. ##
+## ------------------------- ##
+
+# This section contains functions for adding, removing, and running hooks
+# to the main code. A hook is just a named list of of function, that can
+# be run in order later on.
+
+# func_hookable FUNC_NAME
+# -----------------------
+# Declare that FUNC_NAME will run hooks added with
+# 'func_add_hook FUNC_NAME ...'.
+func_hookable ()
+{
+ $debug_cmd
+
+ func_append hookable_fns " $1"
+}
+
+
+# func_add_hook FUNC_NAME HOOK_FUNC
+# ---------------------------------
+# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must
+# first have been declared "hookable" by a call to 'func_hookable'.
+func_add_hook ()
+{
+ $debug_cmd
+
+ case " $hookable_fns " in
+ *" $1 "*) ;;
+ *) func_fatal_error "'$1' does not accept hook functions." ;;
+ esac
+
+ eval func_append ${1}_hooks '" $2"'
+}
+
+
+# func_remove_hook FUNC_NAME HOOK_FUNC
+# ------------------------------------
+# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
+func_remove_hook ()
+{
+ $debug_cmd
+
+ eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`'
+}
+
+
+# func_run_hooks FUNC_NAME [ARG]...
+# ---------------------------------
+# Run all hook functions registered to FUNC_NAME.
+# It is assumed that the list of hook functions contains nothing more
+# than a whitespace-delimited list of legal shell function names, and
+# no effort is wasted trying to catch shell meta-characters or preserve
+# whitespace.
+func_run_hooks ()
+{
+ $debug_cmd
+
+ case " $hookable_fns " in
+ *" $1 "*) ;;
+ *) func_fatal_error "'$1' does not support hook funcions.n" ;;
+ esac
+
+ eval _G_hook_fns=\$$1_hooks; shift
+
+ for _G_hook in $_G_hook_fns; do
+ eval $_G_hook '"$@"'
+
+ # store returned options list back into positional
+ # parameters for next 'cmd' execution.
+ eval _G_hook_result=\$${_G_hook}_result
+ eval set dummy "$_G_hook_result"; shift
+ done
+
+ func_quote_for_eval ${1+"$@"}
+ func_run_hooks_result=$func_quote_for_eval_result
+}
+
+
+
+## --------------- ##
+## Option parsing. ##
+## --------------- ##
+
+# In order to add your own option parsing hooks, you must accept the
+# full positional parameter list in your hook function, remove any
+# options that you action, and then pass back the remaining unprocessed
+# options in '<hooked_function_name>_result', escaped suitably for
+# 'eval'. Like this:
+#
+# my_options_prep ()
+# {
+# $debug_cmd
+#
+# # Extend the existing usage message.
+# usage_message=$usage_message'
+# -s, --silent don'\''t print informational messages
+# '
+#
+# func_quote_for_eval ${1+"$@"}
+# my_options_prep_result=$func_quote_for_eval_result
+# }
+# func_add_hook func_options_prep my_options_prep
+#
+#
+# my_silent_option ()
+# {
+# $debug_cmd
+#
+# # Note that for efficiency, we parse as many options as we can
+# # recognise in a loop before passing the remainder back to the
+# # caller on the first unrecognised argument we encounter.
+# while test $# -gt 0; do
+# opt=$1; shift
+# case $opt in
+# --silent|-s) opt_silent=: ;;
+# # Separate non-argument short options:
+# -s*) func_split_short_opt "$_G_opt"
+# set dummy "$func_split_short_opt_name" \
+# "-$func_split_short_opt_arg" ${1+"$@"}
+# shift
+# ;;
+# *) set dummy "$_G_opt" "$*"; shift; break ;;
+# esac
+# done
+#
+# func_quote_for_eval ${1+"$@"}
+# my_silent_option_result=$func_quote_for_eval_result
+# }
+# func_add_hook func_parse_options my_silent_option
+#
+#
+# my_option_validation ()
+# {
+# $debug_cmd
+#
+# $opt_silent && $opt_verbose && func_fatal_help "\
+# '--silent' and '--verbose' options are mutually exclusive."
+#
+# func_quote_for_eval ${1+"$@"}
+# my_option_validation_result=$func_quote_for_eval_result
+# }
+# func_add_hook func_validate_options my_option_validation
+#
+# You'll alse need to manually amend $usage_message to reflect the extra
+# options you parse. It's preferable to append if you can, so that
+# multiple option parsing hooks can be added safely.
+
+
+# func_options [ARG]...
+# ---------------------
+# All the functions called inside func_options are hookable. See the
+# individual implementations for details.
+func_hookable func_options
+func_options ()
+{
+ $debug_cmd
+
+ func_options_prep ${1+"$@"}
+ eval func_parse_options \
+ ${func_options_prep_result+"$func_options_prep_result"}
+ eval func_validate_options \
+ ${func_parse_options_result+"$func_parse_options_result"}
+
+ eval func_run_hooks func_options \
+ ${func_validate_options_result+"$func_validate_options_result"}
+
+ # save modified positional parameters for caller
+ func_options_result=$func_run_hooks_result
+}
+
+
+# func_options_prep [ARG]...
+# --------------------------
+# All initialisations required before starting the option parse loop.
+# Note that when calling hook functions, we pass through the list of
+# positional parameters. If a hook function modifies that list, and
+# needs to propogate that back to rest of this script, then the complete
+# modified list must be put in 'func_run_hooks_result' before
+# returning.
+func_hookable func_options_prep
+func_options_prep ()
+{
+ $debug_cmd
+
+ # Option defaults:
+ opt_verbose=false
+ opt_warning_types=
+
+ func_run_hooks func_options_prep ${1+"$@"}
+
+ # save modified positional parameters for caller
+ func_options_prep_result=$func_run_hooks_result
+}
+
+
+# func_parse_options [ARG]...
+# ---------------------------
+# The main option parsing loop.
+func_hookable func_parse_options
+func_parse_options ()
+{
+ $debug_cmd
+
+ func_parse_options_result=
+
+ # this just eases exit handling
+ while test $# -gt 0; do
+ # Defer to hook functions for initial option parsing, so they
+ # get priority in the event of reusing an option name.
+ func_run_hooks func_parse_options ${1+"$@"}
+
+ # Adjust func_parse_options positional parameters to match
+ eval set dummy "$func_run_hooks_result"; shift
+
+ # Break out of the loop if we already parsed every option.
+ test $# -gt 0 || break
+
+ _G_opt=$1
+ shift
+ case $_G_opt in
+ --debug|-x) debug_cmd='set -x'
+ func_echo "enabling shell trace mode"
+ $debug_cmd
+ ;;
+
+ --no-warnings|--no-warning|--no-warn)
+ set dummy --warnings none ${1+"$@"}
+ shift
+ ;;
+
+ --warnings|--warning|-W)
+ test $# = 0 && func_missing_arg $_G_opt && break
+ case " $warning_categories $1" in
+ *" $1 "*)
+ # trailing space prevents matching last $1 above
+ func_append_uniq opt_warning_types " $1"
+ ;;
+ *all)
+ opt_warning_types=$warning_categories
+ ;;
+ *none)
+ opt_warning_types=none
+ warning_func=:
+ ;;
+ *error)
+ opt_warning_types=$warning_categories
+ warning_func=func_fatal_error
+ ;;
+ *)
+ func_fatal_error \
+ "unsupported warning category: '$1'"
+ ;;
+ esac
+ shift
+ ;;
+
+ --verbose|-v) opt_verbose=: ;;
+ --version) func_version ;;
+ -\?|-h) func_usage ;;
+ --help) func_help ;;
+
+ # Separate optargs to long options (plugins may need this):
+ --*=*) func_split_equals "$_G_opt"
+ set dummy "$func_split_equals_lhs" \
+ "$func_split_equals_rhs" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate optargs to short options:
+ -W*)
+ func_split_short_opt "$_G_opt"
+ set dummy "$func_split_short_opt_name" \
+ "$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate non-argument short options:
+ -\?*|-h*|-v*|-x*)
+ func_split_short_opt "$_G_opt"
+ set dummy "$func_split_short_opt_name" \
+ "-$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ --) break ;;
+ -*) func_fatal_help "unrecognised option: '$_G_opt'" ;;
+ *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
+
+ # save modified positional parameters for caller
+ func_quote_for_eval ${1+"$@"}
+ func_parse_options_result=$func_quote_for_eval_result
+}
+
+
+# func_validate_options [ARG]...
+# ------------------------------
+# Perform any sanity checks on option settings and/or unconsumed
+# arguments.
+func_hookable func_validate_options
+func_validate_options ()
+{
+ $debug_cmd
+
+ # Display all warnings if -W was not given.
+ test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
+
+ func_run_hooks func_validate_options ${1+"$@"}
+
+ # Bail if the options were screwed!
+ $exit_cmd $EXIT_FAILURE
+
+ # save modified positional parameters for caller
+ func_validate_options_result=$func_run_hooks_result
+}
+
+
+
+## ----------------- ##
+## Helper functions. ##
+## ----------------- ##
+
+# This section contains the helper functions used by the rest of the
+# hookable option parser framework in ascii-betical order.
+
+
+# func_fatal_help ARG...
+# ----------------------
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+ $debug_cmd
+
+ eval \$ECHO \""Usage: $usage"\"
+ eval \$ECHO \""$fatal_help"\"
+ func_error ${1+"$@"}
+ exit $EXIT_FAILURE
+}
+
+
+# func_help
+# ---------
+# Echo long help message to standard output and exit.
+func_help ()
+{
+ $debug_cmd
+
+ func_usage_message
+ $ECHO "$long_help_message"
+ exit 0
+}
+
+
+# func_missing_arg ARGNAME
+# ------------------------
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+ $debug_cmd
+
+ func_error "Missing argument for '$1'."
+ exit_cmd=exit
+}
+
+
+# func_split_equals STRING
+# ------------------------
+# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
+# splitting STRING at the '=' sign.
+test -z "$_G_HAVE_XSI_OPS" \
+ && (eval 'x=a/b/c;
+ test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
+ && _G_HAVE_XSI_OPS=yes
+
+if test yes = "$_G_HAVE_XSI_OPS"
+then
+ # This is an XSI compatible shell, allowing a faster implementation...
+ eval 'func_split_equals ()
+ {
+ $debug_cmd
+
+ func_split_equals_lhs=${1%%=*}
+ func_split_equals_rhs=${1#*=}
+ test "x$func_split_equals_lhs" = "x$1" \
+ && func_split_equals_rhs=
+ }'
+else
+ # ...otherwise fall back to using expr, which is often a shell builtin.
+ func_split_equals ()
+ {
+ $debug_cmd
+
+ func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'`
+ func_split_equals_rhs=
+ test "x$func_split_equals_lhs" = "x$1" \
+ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'`
+ }
+fi #func_split_equals
+
+
+# func_split_short_opt SHORTOPT
+# -----------------------------
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+if test yes = "$_G_HAVE_XSI_OPS"
+then
+ # This is an XSI compatible shell, allowing a faster implementation...
+ eval 'func_split_short_opt ()
+ {
+ $debug_cmd
+
+ func_split_short_opt_arg=${1#??}
+ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}
+ }'
+else
+ # ...otherwise fall back to using expr, which is often a shell builtin.
+ func_split_short_opt ()
+ {
+ $debug_cmd
+
+ func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'`
+ func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'`
+ }
+fi #func_split_short_opt
+
+
+# func_usage
+# ----------
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+ $debug_cmd
+
+ func_usage_message
+ $ECHO "Run '$progname --help |${PAGER-more}' for full usage"
+ exit 0
+}
+
+
+# func_usage_message
+# ------------------
+# Echo short help message to standard output.
+func_usage_message ()
+{
+ $debug_cmd
+
+ eval \$ECHO \""Usage: $usage"\"
+ echo
+ $SED -n 's|^# ||
+ /^Written by/{
+ x;p;x
+ }
+ h
+ /^Written by/q' < "$progpath"
+ echo
+ eval \$ECHO \""$usage_message"\"
+}
+
+
+# func_version
+# ------------
+# Echo version message to standard output and exit.
+func_version ()
+{
+ $debug_cmd
+
+ printf '%s\n' "$progname $scriptversion"
+ $SED -n '
+ /(C)/!b go
+ :more
+ /\./!{
+ N
+ s|\n# | |
+ b more
+ }
+ :go
+ /^# Written by /,/# warranty; / {
+ s|^# ||
+ s|^# *$||
+ s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
+ p
+ }
+ /^# Written by / {
+ s|^# ||
+ p
+ }
+ /^warranty; /q' < "$progpath"
+
+ exit $?
+}
+
+
+# Local variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-time-zone: "UTC"
+# End:
+
+# Set a version string.
+scriptversion='(GNU libtool) 2.4.3'
+
+
+# func_echo ARG...
+# ----------------
+# Libtool also displays the current mode in messages, so override
+# funclib.sh func_echo with this custom definition.
+func_echo ()
+{
+ $debug_cmd
+
+ _G_message=$*
+
+ func_echo_IFS=$IFS
+ IFS=$nl
+ for _G_line in $_G_message; do
+ IFS=$func_echo_IFS
+ $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line"
+ done
+ IFS=$func_echo_IFS
+}
+
+
+# func_warning ARG...
+# -------------------
+# Libtool warnings are not categorized, so override funclib.sh
+# func_warning with this simpler definition.
+func_warning ()
+{
+ $debug_cmd
+
+ $warning_func ${1+"$@"}
+}
+
+
+## ---------------- ##
+## Options parsing. ##
+## ---------------- ##
+
+# Hook in the functions to make sure our own options are parsed during
+# the option parsing loop.
+
+usage='$progpath [OPTION]... [MODE-ARG]...'
+
+# Short help message in response to '-h'.
+usage_message="Options:
+ --config show all configuration variables
+ --debug enable verbose shell tracing
+ -n, --dry-run display commands without modifying any files
+ --features display basic configuration information and exit
+ --mode=MODE use operation mode MODE
+ --no-warnings equivalent to '-Wnone'
+ --preserve-dup-deps don't remove duplicate dependency libraries
+ --quiet, --silent don't print informational messages
+ --tag=TAG use configuration variables from tag TAG
+ -v, --verbose print more informational messages than default
+ --version print version information
+ -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all]
+ -h, --help, --help-all print short, long, or detailed help message
+"
+
+# Additional text appended to 'usage_message' in response to '--help'.
+long_help_message=$long_help_message"
+
+MODE must be one of the following:
+
+ clean remove files from the build directory
+ compile compile a source file into a libtool object
+ execute automatically set library path, then run a program
+ finish complete the installation of libtool libraries
+ install install libraries or executables
+ link create a library or an executable
+ uninstall remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE. When passed as first option,
+'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that.
+Try '$progname --help --mode=MODE' for a more detailed description of MODE.
+
+When reporting a bug, please describe a test case to reproduce it and
+include the following information:
+
+ host-triplet: $host
+ shell: $SHELL
+ compiler: $LTCC
+ compiler flags: $LTCFLAGS
+ linker: $LD (gnu? $with_gnu_ld)
+ version: $progname (GNU libtool) 2.4.3
+ automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
+ autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q`
+
+Report bugs to <bug-libtool@gnu.org>.
+GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+General help using GNU software: <http://www.gnu.org/gethelp/>."
+
+
+# func_lo2o OBJECT-NAME
+# ---------------------
+# Transform OBJECT-NAME from a '.lo' suffix to the platform specific
+# object suffix.
+
+lo2o=s/\\.lo\$/.$objext/
+o2lo=s/\\.$objext\$/.lo/
+
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ eval 'func_lo2o ()
+ {
+ case $1 in
+ *.lo) func_lo2o_result=${1%.lo}.$objext ;;
+ * ) func_lo2o_result=$1 ;;
+ esac
+ }'
+
+ # func_xform LIBOBJ-OR-SOURCE
+ # ---------------------------
+ # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise)
+ # suffix to a '.lo' libtool-object suffix.
+ eval 'func_xform ()
+ {
+ func_xform_result=${1%.*}.lo
+ }'
+else
+ # ...otherwise fall back to using sed.
+ func_lo2o ()
+ {
+ func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"`
+ }
+
+ func_xform ()
+ {
+ func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'`
+ }
+fi
+
+
+# func_fatal_configuration ARG...
+# -------------------------------
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+ func__fatal_error ${1+"$@"} \
+ "See the $PACKAGE documentation for more information." \
+ "Fatal configuration error."
+}
+
+
+# func_config
+# -----------
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+ re_begincf='^# ### BEGIN LIBTOOL'
+ re_endcf='^# ### END LIBTOOL'
+
+ # Default configuration.
+ $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+ # Now print the configurations for the tags.
+ for tagname in $taglist; do
+ $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+ done
+
+ exit $?
+}
+
+
+# func_features
+# -------------
+# Display the features supported by this script.
+func_features ()
+{
+ echo "host: $host"
+ if test yes = "$build_libtool_libs"; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test yes = "$build_old_libs"; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+
+ exit $?
+}
+
+
+# func_enable_tag TAGNAME
+# -----------------------
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag. We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+ # Global variable:
+ tagname=$1
+
+ re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+ re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+ sed_extractcf=/$re_begincf/,/$re_endcf/p
+
+ # Validate tagname.
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ func_fatal_error "invalid tag name: $tagname"
+ ;;
+ esac
+
+ # Don't test for the "default" C tag, as we know it's
+ # there but not specially marked.
+ case $tagname in
+ CC) ;;
+ *)
+ if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+ taglist="$taglist $tagname"
+
+ # Evaluate the configuration. Be careful to quote the path
+ # and the sed script, to avoid splitting on whitespace, but
+ # also don't use non-portable quotes within backquotes within
+ # quotes we have to do it in 2 steps:
+ extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+ eval "$extractedcf"
+ else
+ func_error "ignoring unknown tag $tagname"
+ fi
+ ;;
+ esac
+}
+
+
+# func_check_version_match
+# ------------------------
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+ if test "$package_revision" != "$macro_revision"; then
+ if test "$VERSION" != "$macro_version"; then
+ if test -z "$macro_version"; then
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ fi
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+ fi
+
+ exit $EXIT_MISMATCH
+ fi
+}
+
+
+# libtool_options_prep [ARG]...
+# -----------------------------
+# Preparation for options parsed by libtool.
+libtool_options_prep ()
+{
+ $debug_mode
+
+ # Option defaults:
+ opt_config=false
+ opt_dlopen=
+ opt_dry_run=false
+ opt_help=false
+ opt_mode=
+ opt_preserve_dup_deps=false
+ opt_quiet=false
+
+ nonopt=
+ preserve_args=
+
+ # Shorthand for --mode=foo, only valid as the first argument
+ case $1 in
+ clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+ compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+ execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+ finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+ link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+ uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+ esac
+
+ # Pass back the list of options.
+ func_quote_for_eval ${1+"$@"}
+ libtool_options_prep_result=$func_quote_for_eval_result
+}
+func_add_hook func_options_prep libtool_options_prep
+
+
+# libtool_parse_options [ARG]...
+# ---------------------------------
+# Provide handling for libtool specific options.
+libtool_parse_options ()
+{
+ $debug_cmd
+
+ # Perform our own loop to consume as many options as possible in
+ # each iteration.
+ while test $# -gt 0; do
+ _G_opt=$1
+ shift
+ case $_G_opt in
+ --dry-run|--dryrun|-n)
+ opt_dry_run=:
+ ;;
+
+ --config) func_config ;;
+
+ --dlopen|-dlopen)
+ opt_dlopen="${opt_dlopen+$opt_dlopen
+}$1"
+ shift
+ ;;
+
+ --preserve-dup-deps)
+ opt_preserve_dup_deps=: ;;
+
+ --features) func_features ;;
+
+ --finish) set dummy --mode finish ${1+"$@"}; shift ;;
+
+ --help) opt_help=: ;;
+
+ --help-all) opt_help=': help-all' ;;
+
+ --mode) test $# = 0 && func_missing_arg $_G_opt && break
+ opt_mode=$1
+ case $1 in
+ # Valid mode arguments:
+ clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $_G_opt"
+ exit_cmd=exit
+ break
+ ;;
+ esac
+ shift
+ ;;
+
+ --no-silent|--no-quiet)
+ opt_quiet=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --no-warnings|--no-warning|--no-warn)
+ opt_warning=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --no-verbose)
+ opt_verbose=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --silent|--quiet)
+ opt_quiet=:
+ opt_verbose=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --tag) test $# = 0 && func_missing_arg $_G_opt && break
+ opt_tag=$1
+ func_append preserve_args " $_G_opt $1"
+ func_enable_tag "$1"
+ shift
+ ;;
+
+ --verbose|-v) opt_quiet=false
+ opt_verbose=:
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ # An option not handled by this hook function:
+ *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
+
+
+ # save modified positional parameters for caller
+ func_quote_for_eval ${1+"$@"}
+ libtool_parse_options_result=$func_quote_for_eval_result
+}
+func_add_hook func_parse_options libtool_parse_options
+
+
+
+# libtool_validate_options [ARG]...
+# ---------------------------------
+# Perform any sanity checks on option settings and/or unconsumed
+# arguments.
+libtool_validate_options ()
+{
+ # save first non-option argument
+ if test 0 -lt $#; then
+ nonopt=$1
+ shift
+ fi
+
+ # preserve --debug
+ test : = "$debug_cmd" || func_append preserve_args " --debug"
+
+ case $host in
+ # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452
+ # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788
+ *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2*)
+ # don't eliminate duplications in $postdeps and $predeps
+ opt_duplicate_compiler_generated_deps=:
+ ;;
+ *)
+ opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+ ;;
+ esac
+
+ $opt_help || {
+ # Sanity checks first:
+ func_check_version_match
+
+ test yes != "$build_libtool_libs" \
+ && test yes != "$build_old_libs" \
+ && func_fatal_configuration "not configured to build any kind of library"
+
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$opt_dlopen" && test execute != "$opt_mode"; then
+ func_error "unrecognized option '-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help=$help
+ help="Try '$progname --help --mode=$opt_mode' for more information."
+ }
+
+ # Pass back the unparsed argument list
+ func_quote_for_eval ${1+"$@"}
+ libtool_validate_options_result=$func_quote_for_eval_result
+}
+func_add_hook func_validate_options libtool_validate_options
+
+
+# Process options as early as possible so that --help and --version
+# can return quickly.
+func_options ${1+"$@"}
+eval set dummy "$func_options_result"; shift
+
+
+
+## ----------- ##
+## Main. ##
+## ----------- ##
+
+magic='%%%MAGIC variable%%%'
+magic_exe='%%%MAGIC EXE variable%%%'
+
+# Global variables.
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# func_generated_by_libtool
+# True iff stdin has been generated by Libtool. This function is only
+# a basic sanity check; it will hardly flush out determined imposters.
+func_generated_by_libtool_p ()
+{
+ $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_p file
+# True iff FILE is a libtool '.la' library or '.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+ test -f "$1" &&
+ $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool '.la' library or '.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs. To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway. Works if 'file' does not exist.
+func_lalib_unsafe_p ()
+{
+ lalib_p=no
+ if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+ for lalib_p_l in 1 2 3 4
+ do
+ read lalib_p_line
+ case $lalib_p_line in
+ \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+ esac
+ done
+ exec 0<&5 5<&-
+ fi
+ test yes = "$lalib_p"
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+ test -f "$1" &&
+ $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+ func_ltwrapper_exec_suffix=
+ case $1 in
+ *.exe) ;;
+ *) func_ltwrapper_exec_suffix=.exe ;;
+ esac
+ $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+ func_dirname_and_basename "$1" "" "."
+ func_stripname '' '.exe' "$func_basename_result"
+ func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+ func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+ $debug_cmd
+
+ save_ifs=$IFS; IFS='~'
+ for cmd in $1; do
+ IFS=$sp$nl
+ eval cmd=\"$cmd\"
+ IFS=$save_ifs
+ func_show_eval "$cmd" "${2-:}"
+ done
+ IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)! Also, sourcing
+# 'FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+ $debug_cmd
+
+ case $1 in
+ */* | *\\*) . "$1" ;;
+ *) . "./$1" ;;
+ esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot. Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+ func_resolve_sysroot_result=$1
+ case $func_resolve_sysroot_result in
+ =*)
+ func_stripname '=' '' "$func_resolve_sysroot_result"
+ func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+ ;;
+ esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+ case $lt_sysroot:$1 in
+ ?*:"$lt_sysroot"*)
+ func_stripname "$lt_sysroot" '' "$1"
+ func_replace_sysroot_result='='$func_stripname_result
+ ;;
+ *)
+ # Including no sysroot.
+ func_replace_sysroot_result=$1
+ ;;
+ esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+ $debug_cmd
+
+ if test -n "$available_tags" && test -z "$tagname"; then
+ CC_quoted=
+ for arg in $CC; do
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case $@ in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+ CC_quoted=
+ for arg in $CC; do
+ # Double-quote args containing other shell metacharacters.
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case "$@ " in
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ func_echo "unable to infer tagged configuration"
+ func_fatal_error "specify a tag with '--tag'"
+# else
+# func_verbose "using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+ write_libobj=$1
+ if test yes = "$build_libtool_libs"; then
+ write_lobj=\'$2\'
+ else
+ write_lobj=none
+ fi
+
+ if test yes = "$build_old_libs"; then
+ write_oldobj=\'$3\'
+ else
+ write_oldobj=none
+ fi
+
+ $opt_dry_run || {
+ cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+ $MV "${write_libobj}T" "$write_libobj"
+ }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+ $debug_cmd
+
+ func_convert_core_file_wine_to_w32_result=$1
+ if test -n "$1"; then
+ # Unfortunately, winepath does not exit with a non-zero error code, so we
+ # are forced to check the contents of stdout. On the other hand, if the
+ # command is not found, the shell will set an exit code of 127 and print
+ # *an error message* to stdout. So we must check for both error code of
+ # zero AND non-empty stdout, which explains the odd construction:
+ func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+ if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then
+ func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+ $SED -e "$sed_naive_backslashify"`
+ else
+ func_convert_core_file_wine_to_w32_result=
+ fi
+ fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+ $debug_cmd
+
+ # unfortunately, winepath doesn't convert paths, only file names
+ func_convert_core_path_wine_to_w32_result=
+ if test -n "$1"; then
+ oldIFS=$IFS
+ IFS=:
+ for func_convert_core_path_wine_to_w32_f in $1; do
+ IFS=$oldIFS
+ func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+ if test -n "$func_convert_core_file_wine_to_w32_result"; then
+ if test -z "$func_convert_core_path_wine_to_w32_result"; then
+ func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result
+ else
+ func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+ fi
+ fi
+ done
+ IFS=$oldIFS
+ fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+ $debug_cmd
+
+ if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+ func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+ if test "$?" -ne 0; then
+ # on failure, ensure result is empty
+ func_cygpath_result=
+ fi
+ else
+ func_cygpath_result=
+ func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'"
+ fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format. Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+ $debug_cmd
+
+ # awkward: cmd appends spaces to result
+ func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+ $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+ $debug_cmd
+
+ if test -z "$2" && test -n "$1"; then
+ func_error "Could not determine host file name corresponding to"
+ func_error " '$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback:
+ func_to_host_file_result=$1
+ fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+ $debug_cmd
+
+ if test -z "$4" && test -n "$3"; then
+ func_error "Could not determine the host path corresponding to"
+ func_error " '$3'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback. This is a deliberately simplistic "conversion" and
+ # should not be "improved". See libtool.info.
+ if test "x$1" != "x$2"; then
+ lt_replace_pathsep_chars="s|$1|$2|g"
+ func_to_host_path_result=`echo "$3" |
+ $SED -e "$lt_replace_pathsep_chars"`
+ else
+ func_to_host_path_result=$3
+ fi
+ fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+ $debug_cmd
+
+ case $4 in
+ $1 ) func_to_host_path_result=$3$func_to_host_path_result
+ ;;
+ esac
+ case $4 in
+ $2 ) func_append func_to_host_path_result "$3"
+ ;;
+ esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via '$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+ $debug_cmd
+
+ $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result. If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+ $debug_cmd
+
+ case ,$2, in
+ *,"$to_tool_file_cmd",*)
+ func_to_tool_file_result=$1
+ ;;
+ *)
+ $to_tool_file_cmd "$1"
+ func_to_tool_file_result=$func_to_host_file_result
+ ;;
+ esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+ func_to_host_file_result=$1
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_to_host_file_result=$func_convert_core_msys_to_w32_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+ # LT_CYGPATH in this case.
+ func_to_host_file_result=`cygpath -m "$1"`
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format. Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ func_convert_core_file_wine_to_w32 "$1"
+ func_to_host_file_result=$func_convert_core_file_wine_to_w32_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_msys_to_w32_result"
+ func_to_host_file_result=$func_cygpath_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set. Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+ func_convert_core_file_wine_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+ func_to_host_file_result=$func_cygpath_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via '$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format. If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+# file name conversion function : func_convert_file_X_to_Y ()
+# path conversion function : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same. If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+ $debug_cmd
+
+ if test -z "$to_host_path_cmd"; then
+ func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+ to_host_path_cmd=func_convert_path_$func_stripname_result
+ fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+ $debug_cmd
+
+ func_init_to_host_path_cmd
+ $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+ func_to_host_path_result=$1
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from ARG. MSYS
+ # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+ # and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result=$func_convert_core_msys_to_w32_result
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format. Requires a wine environment and
+# a working winepath. Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result=$func_convert_core_path_wine_to_w32_result
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+ func_to_host_path_result=$func_cygpath_result
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set. Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from
+ # ARG. msys behavior is inconsistent here, cygpath turns them
+ # into '.;' and ';.', and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+ func_to_host_path_result=$func_cygpath_result
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_dll_def_p FILE
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with _LT_DLL_DEF_P in libtool.m4
+func_dll_def_p ()
+{
+ $debug_cmd
+
+ func_dll_def_p_tmp=`$SED -n \
+ -e 's/^[ ]*//' \
+ -e '/^\(;.*\)*$/d' \
+ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \
+ -e q \
+ "$1"`
+ test DEF = "$func_dll_def_p_tmp"
+}
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+ $debug_cmd
+
+ # Get the compilation command and the source file.
+ base_compile=
+ srcfile=$nonopt # always keep a non-empty value in "srcfile"
+ suppress_opt=yes
+ suppress_output=
+ arg_mode=normal
+ libobj=
+ later=
+ pie_flag=
+
+ for arg
+ do
+ case $arg_mode in
+ arg )
+ # do not "continue". Instead, add this to base_compile
+ lastarg=$arg
+ arg_mode=normal
+ ;;
+
+ target )
+ libobj=$arg
+ arg_mode=normal
+ continue
+ ;;
+
+ normal )
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ test -n "$libobj" && \
+ func_fatal_error "you cannot specify '-o' more than once"
+ arg_mode=target
+ continue
+ ;;
+
+ -pie | -fpie | -fPIE)
+ func_append pie_flag " $arg"
+ continue
+ ;;
+
+ -shared | -static | -prefer-pic | -prefer-non-pic)
+ func_append later " $arg"
+ continue
+ ;;
+
+ -no-suppress)
+ suppress_opt=no
+ continue
+ ;;
+
+ -Xcompiler)
+ arg_mode=arg # the next one goes into the "base_compile" arg list
+ continue # The current "srcfile" will either be retained or
+ ;; # replaced later. I would guess that would be a bug.
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ lastarg=
+ save_ifs=$IFS; IFS=,
+ for arg in $args; do
+ IFS=$save_ifs
+ func_append_quoted lastarg "$arg"
+ done
+ IFS=$save_ifs
+ func_stripname ' ' '' "$lastarg"
+ lastarg=$func_stripname_result
+
+ # Add the arguments to base_compile.
+ func_append base_compile " $lastarg"
+ continue
+ ;;
+
+ *)
+ # Accept the current argument as the source file.
+ # The previous "srcfile" becomes the current argument.
+ #
+ lastarg=$srcfile
+ srcfile=$arg
+ ;;
+ esac # case $arg
+ ;;
+ esac # case $arg_mode
+
+ # Aesthetically quote the previous argument.
+ func_append_quoted base_compile "$lastarg"
+ done # for arg
+
+ case $arg_mode in
+ arg)
+ func_fatal_error "you must specify an argument for -Xcompile"
+ ;;
+ target)
+ func_fatal_error "you must specify a target with '-o'"
+ ;;
+ *)
+ # Get the name of the library object.
+ test -z "$libobj" && {
+ func_basename "$srcfile"
+ libobj=$func_basename_result
+ }
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ case $libobj in
+ *.[cCFSifmso] | \
+ *.ada | *.adb | *.ads | *.asm | \
+ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+ func_xform "$libobj"
+ libobj=$func_xform_result
+ ;;
+ esac
+
+ case $libobj in
+ *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+ *)
+ func_fatal_error "cannot determine name of library object from '$libobj'"
+ ;;
+ esac
+
+ func_infer_tag $base_compile
+
+ for arg in $later; do
+ case $arg in
+ -shared)
+ test yes = "$build_libtool_libs" \
+ || func_fatal_configuration "cannot build a shared library"
+ build_old_libs=no
+ continue
+ ;;
+
+ -static)
+ build_libtool_libs=no
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+ esac
+ done
+
+ func_quote_for_eval "$libobj"
+ test "X$libobj" != "X$func_quote_for_eval_result" \
+ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
+ && func_warning "libobj name '$libobj' may not contain shell special characters."
+ func_dirname_and_basename "$obj" "/" ""
+ objname=$func_basename_result
+ xdir=$func_dirname_result
+ lobj=$xdir$objdir/$objname
+
+ test -z "$base_compile" && \
+ func_fatal_help "you must specify a compilation command"
+
+ # Delete any leftover library objects.
+ if test yes = "$build_old_libs"; then
+ removelist="$obj $lobj $libobj ${libobj}T"
+ else
+ removelist="$lobj $libobj ${libobj}T"
+ fi
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2* | cegcc*)
+ pic_mode=default
+ ;;
+ esac
+ if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test no = "$compiler_c_o"; then
+ output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext
+ lockfile=$output_obj.lock
+ else
+ output_obj=
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test yes = "$need_locks"; then
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test warn = "$need_locks"; then
+ if test -f "$lockfile"; then
+ $ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+ func_append removelist " $output_obj"
+ $ECHO "$srcfile" > "$lockfile"
+ fi
+
+ $opt_dry_run || $RM $removelist
+ func_append removelist " $lockfile"
+ trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+ func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+ srcfile=$func_to_tool_file_result
+ func_quote_for_eval "$srcfile"
+ qsrcfile=$func_quote_for_eval_result
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test yes = "$build_libtool_libs"; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test no != "$pic_mode"; then
+ command="$base_compile $qsrcfile $pic_flag"
+ else
+ # Don't build PIC code
+ command="$base_compile $qsrcfile"
+ fi
+
+ func_mkdir_p "$xdir$objdir"
+
+ if test -z "$output_obj"; then
+ # Place PIC objects in $objdir
+ func_append command " -o $lobj"
+ fi
+
+ func_show_eval_locale "$command" \
+ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+ if test warn = "$need_locks" &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+ func_show_eval '$MV "$output_obj" "$lobj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+
+ # Allow error messages only from the first compilation.
+ if test yes = "$suppress_opt"; then
+ suppress_output=' >/dev/null 2>&1'
+ fi
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test yes = "$build_old_libs"; then
+ if test yes != "$pic_mode"; then
+ # Don't build PIC code
+ command="$base_compile $qsrcfile$pie_flag"
+ else
+ command="$base_compile $qsrcfile $pic_flag"
+ fi
+ if test yes = "$compiler_c_o"; then
+ func_append command " -o $obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ func_append command "$suppress_output"
+ func_show_eval_locale "$command" \
+ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+ if test warn = "$need_locks" &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed
+ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+ func_show_eval '$MV "$output_obj" "$obj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+ fi
+
+ $opt_dry_run || {
+ func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+ # Unlock the critical section if it was locked
+ if test no != "$need_locks"; then
+ removelist=$lockfile
+ $RM "$lockfile"
+ fi
+ }
+
+ exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+ test compile = "$opt_mode" && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+ # We need to display help for each of the modes.
+ case $opt_mode in
+ "")
+ # Generic help is extracted from the usage comments
+ # at the start of this file.
+ func_help
+ ;;
+
+ clean)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ compile)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -no-suppress do not suppress compiler output for multiple passes
+ -prefer-pic try to build PIC objects only
+ -prefer-non-pic try to build non-PIC objects only
+ -shared do not build a '.o' file suitable for static linking
+ -static only build a '.o' file suitable for static linking
+ -Wc,FLAG pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a 'standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix '.c' with the
+library object suffix, '.lo'."
+ ;;
+
+ execute)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to '-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+ finish)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the '--dry-run' option if you just want to see what would be executed."
+ ;;
+
+ install)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the 'install' or 'cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+ -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+ link)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -bindir BINDIR specify path to binaries directory (for systems where
+ libraries must be found in the PATH setting at runtime)
+ -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -objectlist FILE Use a list of object files found in FILE to specify objects
+ -precious-files-regex REGEX
+ don't remove output files matching REGEX
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -shared only do dynamic linking of libtool libraries
+ -shrext SUFFIX override the standard shared library file extension
+ -static do not do any dynamic linking of uninstalled libtool libraries
+ -static-libtool-libs
+ do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+ -weak LIBNAME declare that the target provides the LIBNAME interface
+ -Wc,FLAG
+ -Xcompiler FLAG pass linker-specific FLAG directly to the compiler
+ -Wl,FLAG
+ -Xlinker FLAG pass linker-specific FLAG directly to the linker
+ -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with '-') are ignored.
+
+Every other argument is treated as a filename. Files ending in '.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in '.la', then a libtool library is created,
+only library objects ('.lo' files) may be specified, and '-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created
+using 'ar' and 'ranlib', or on Windows using 'lib'.
+
+If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+ uninstall)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ *)
+ func_fatal_help "invalid operation mode '$opt_mode'"
+ ;;
+ esac
+
+ echo
+ $ECHO "Try '$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+ if test : = "$opt_help"; then
+ func_mode_help
+ else
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ func_mode_help
+ done
+ } | $SED -n '1p; 2,$s/^Usage:/ or: /p'
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ echo
+ func_mode_help
+ done
+ } |
+ $SED '1d
+ /^When reporting/,/^Report/{
+ H
+ d
+ }
+ $x
+ /information about other modes/d
+ /more detailed .*MODE/d
+ s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+ fi
+ exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+ $debug_cmd
+
+ # The first argument is the command name.
+ cmd=$nonopt
+ test -z "$cmd" && \
+ func_fatal_help "you must specify a COMMAND"
+
+ # Handle -dlopen flags immediately.
+ for file in $opt_dlopen; do
+ test -f "$file" \
+ || func_fatal_help "'$file' is not a file"
+
+ dir=
+ case $file in
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "'$lib' is not a valid libtool archive"
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+ func_source "$file"
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && \
+ func_warning "'$file' was not linked with '-export-dynamic'"
+ continue
+ fi
+
+ func_dirname "$file" "" "."
+ dir=$func_dirname_result
+
+ if test -f "$dir/$objdir/$dlname"; then
+ func_append dir "/$objdir"
+ else
+ if test ! -f "$dir/$dlname"; then
+ func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'"
+ fi
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ func_dirname "$file" "" "."
+ dir=$func_dirname_result
+ ;;
+
+ *)
+ func_warning "'-dlopen' is ignored for non-libtool libraries and objects"
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir=$absdir
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic=$magic
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -* | *.la | *.lo ) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if func_ltwrapper_script_p "$file"; then
+ func_source "$file"
+ # Transform arg to wrapped name.
+ file=$progdir/$program
+ elif func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ func_source "$func_ltwrapper_scriptname_result"
+ # Transform arg to wrapped name.
+ file=$progdir/$program
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ func_append_quoted args "$file"
+ done
+
+ if $opt_dry_run; then
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+ echo "export $shlibpath_var"
+ fi
+ $ECHO "$cmd$args"
+ exit $EXIT_SUCCESS
+ else
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved environment variables
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+ do
+ eval "if test \"\${save_$lt_var+set}\" = set; then
+ $lt_var=\$save_$lt_var; export $lt_var
+ else
+ $lt_unset $lt_var
+ fi"
+ done
+
+ # Now prepare to actually exec the command.
+ exec_cmd=\$cmd$args
+ fi
+}
+
+test execute = "$opt_mode" && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+ $debug_cmd
+
+ libs=
+ libdirs=
+ admincmds=
+
+ for opt in "$nonopt" ${1+"$@"}
+ do
+ if test -d "$opt"; then
+ func_append libdirs " $opt"
+
+ elif test -f "$opt"; then
+ if func_lalib_unsafe_p "$opt"; then
+ func_append libs " $opt"
+ else
+ func_warning "'$opt' is not a valid libtool archive"
+ fi
+
+ else
+ func_fatal_error "invalid argument '$opt'"
+ fi
+ done
+
+ if test -n "$libs"; then
+ if test -n "$lt_sysroot"; then
+ sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+ sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+ else
+ sysroot_cmd=
+ fi
+
+ # Remove sysroot references
+ if $opt_dry_run; then
+ for lib in $libs; do
+ echo "removing references to $lt_sysroot and '=' prefixes from $lib"
+ done
+ else
+ tmpdir=`func_mktempdir`
+ for lib in $libs; do
+ $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+ > $tmpdir/tmp-la
+ mv -f $tmpdir/tmp-la $lib
+ done
+ ${RM}r "$tmpdir"
+ fi
+ fi
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $opt_dry_run || eval "$cmds" || func_append admincmds "
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ $opt_quiet && exit $EXIT_SUCCESS
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $ECHO " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use the '-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the '$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the '$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ $ECHO " - use the '$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $ECHO " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'"
+ fi
+ echo
+
+ echo "See any operating system documentation about shared libraries for"
+ case $host in
+ solaris2.[6789]|solaris2.1[0-9])
+ echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+ echo "pages."
+ ;;
+ *)
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ ;;
+ esac
+ echo "----------------------------------------------------------------------"
+ fi
+ exit $EXIT_SUCCESS
+}
+
+test finish = "$opt_mode" && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+ $debug_cmd
+
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" ||
+ # Allow the use of GNU shtool's install command.
+ case $nonopt in *shtool*) :;; *) false;; esac
+ then
+ # Aesthetically quote it.
+ func_quote_for_eval "$nonopt"
+ install_prog="$func_quote_for_eval_result "
+ arg=$1
+ shift
+ else
+ install_prog=
+ arg=$nonopt
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ func_quote_for_eval "$arg"
+ func_append install_prog "$func_quote_for_eval_result"
+ install_shared_prog=$install_prog
+ case " $install_prog " in
+ *[\\\ /]cp\ *) install_cp=: ;;
+ *) install_cp=false ;;
+ esac
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=false
+ stripme=
+ no_mode=:
+ for arg
+ do
+ arg2=
+ if test -n "$dest"; then
+ func_append files " $dest"
+ dest=$arg
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=: ;;
+ -f)
+ if $install_cp; then :; else
+ prev=$arg
+ fi
+ ;;
+ -g | -m | -o)
+ prev=$arg
+ ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*)
+ ;;
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ if test X-m = "X$prev" && test -n "$install_override_mode"; then
+ arg2=$install_override_mode
+ no_mode=false
+ fi
+ prev=
+ else
+ dest=$arg
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ func_quote_for_eval "$arg"
+ func_append install_prog " $func_quote_for_eval_result"
+ if test -n "$arg2"; then
+ func_quote_for_eval "$arg2"
+ fi
+ func_append install_shared_prog " $func_quote_for_eval_result"
+ done
+
+ test -z "$install_prog" && \
+ func_fatal_help "you must specify an install program"
+
+ test -n "$prev" && \
+ func_fatal_help "the '$prev' option requires an argument"
+
+ if test -n "$install_override_mode" && $no_mode; then
+ if $install_cp; then :; else
+ func_quote_for_eval "$install_override_mode"
+ func_append install_shared_prog " -m $func_quote_for_eval_result"
+ fi
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ func_fatal_help "no file or destination specified"
+ else
+ func_fatal_help "you must specify a destination"
+ fi
+ fi
+
+ # Strip any trailing slash from the destination.
+ func_stripname '' '/' "$dest"
+ dest=$func_stripname_result
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=:
+ if $isdir; then
+ destdir=$dest
+ destname=
+ else
+ func_dirname_and_basename "$dest" "" "."
+ destdir=$func_dirname_result
+ destname=$func_basename_result
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files; shift
+ test "$#" -gt 1 && \
+ func_fatal_help "'$dest' is not a directory"
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ func_fatal_help "'$destdir' must be an absolute directory name"
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic=$magic
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ func_append staticlibs " $file"
+ ;;
+
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "'$file' is not a valid libtool archive"
+
+ library_names=
+ old_library=
+ relink_command=
+ func_source "$file"
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append current_libdirs " $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append future_libdirs " $libdir" ;;
+ esac
+ fi
+
+ func_dirname "$file" "/" ""
+ dir=$func_dirname_result
+ func_append dir "$objdir"
+
+ if test -n "$relink_command"; then
+ # Determine the prefix the user has applied to our future dir.
+ inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+ # Don't allow the user to place us outside of our expected
+ # location b/c this prevents finding dependent libraries that
+ # are installed to the same prefix.
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+ test "$inst_prefix_dir" = "$destdir" && \
+ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir"
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ else
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+ fi
+
+ func_warning "relinking '$file'"
+ func_show_eval "$relink_command" \
+ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"'
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names; shift
+ if test -n "$1"; then
+ realname=$1
+ shift
+
+ srcname=$realname
+ test -n "$relink_command" && srcname=${realname}T
+
+ # Install the shared library and build the symlinks.
+ func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+ 'exit $?'
+ tstripme=$stripme
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $realname in
+ *.dll.a)
+ tstripme=
+ ;;
+ esac
+ ;;
+ esac
+ if test -n "$tstripme" && test -n "$striplib"; then
+ func_show_eval "$striplib $destdir/$realname" 'exit $?'
+ fi
+
+ if test "$#" -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ # Try 'ln -sf' first, because the 'ln' binary might depend on
+ # the symlink we replace! Solaris /bin/ln does not understand -f,
+ # so we also need to try rm && ln -s.
+ for linkname
+ do
+ test "$linkname" != "$realname" \
+ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib=$destdir/$realname
+ func_execute_cmds "$postinstall_cmds" 'exit $?'
+ fi
+
+ # Install the pseudo-library for information purposes.
+ func_basename "$file"
+ name=$func_basename_result
+ instname=$dir/${name}i
+ func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile=$destdir/$destname
+ else
+ func_basename "$file"
+ destfile=$func_basename_result
+ destfile=$destdir/$destfile
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ func_lo2o "$destfile"
+ staticdest=$func_lo2o_result
+ ;;
+ *.$objext)
+ staticdest=$destfile
+ destfile=
+ ;;
+ *)
+ func_fatal_help "cannot copy a libtool object to '$destfile'"
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ test -n "$destfile" && \
+ func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+ # Install the old object if enabled.
+ if test yes = "$build_old_libs"; then
+ # Deduce the name of the old-style object file.
+ func_lo2o "$file"
+ staticobj=$func_lo2o_result
+ func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+ fi
+ exit $EXIT_SUCCESS
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile=$destdir/$destname
+ else
+ func_basename "$file"
+ destfile=$func_basename_result
+ destfile=$destdir/$destfile
+ fi
+
+ # If the file is missing, and there is a .exe on the end, strip it
+ # because it is most likely a libtool script we actually want to
+ # install
+ stripped_ext=
+ case $file in
+ *.exe)
+ if test ! -f "$file"; then
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ stripped_ext=.exe
+ fi
+ ;;
+ esac
+
+ # Do a test to see if this is really a libtool program.
+ case $host in
+ *cygwin* | *mingw*)
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ wrapper=$func_ltwrapper_scriptname_result
+ else
+ func_stripname '' '.exe' "$file"
+ wrapper=$func_stripname_result
+ fi
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if func_ltwrapper_script_p "$wrapper"; then
+ notinst_deplibs=
+ relink_command=
+
+ func_source "$wrapper"
+
+ # Check the variables that should have been set.
+ test -z "$generated_by_libtool_version" && \
+ func_fatal_error "invalid libtool wrapper script '$wrapper'"
+
+ finalize=:
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ func_source "$lib"
+ fi
+ libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'`
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ func_warning "'$lib' has not been installed in '$libdir'"
+ finalize=false
+ fi
+ done
+
+ relink_command=
+ func_source "$wrapper"
+
+ outputname=
+ if test no = "$fast_install" && test -n "$relink_command"; then
+ $opt_dry_run || {
+ if $finalize; then
+ tmpdir=`func_mktempdir`
+ func_basename "$file$stripped_ext"
+ file=$func_basename_result
+ outputname=$tmpdir/$file
+ # Replace the output file specification.
+ relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $opt_quiet || {
+ func_quote_for_expand "$relink_command"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ if eval "$relink_command"; then :
+ else
+ func_error "error: relink '$file' with the above command before installing it"
+ $opt_dry_run || ${RM}r "$tmpdir"
+ continue
+ fi
+ file=$outputname
+ else
+ func_warning "cannot relink '$file'"
+ fi
+ }
+ else
+ # Install the binary that we compiled earlier.
+ file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyway
+ case $install_prog,$host in
+ */usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ func_stripname '' '.exe' "$destfile"
+ destfile=$func_stripname_result
+ ;;
+ esac
+ ;;
+ esac
+ func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+ $opt_dry_run || if test -n "$outputname"; then
+ ${RM}r "$tmpdir"
+ fi
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ func_basename "$file"
+ name=$func_basename_result
+
+ # Set up the ranlib parameters.
+ oldlib=$destdir/$name
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+
+ func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+ if test -n "$stripme" && test -n "$old_striplib"; then
+ func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+ fi
+
+ # Do each command in the postinstall commands.
+ func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+ done
+
+ test -n "$future_libdirs" && \
+ func_warning "remember to run '$progname --finish$future_libdirs'"
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ $opt_dry_run && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs'
+ else
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test install = "$opt_mode" && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+ $debug_cmd
+
+ my_outputname=$1
+ my_originator=$2
+ my_pic_p=${3-false}
+ my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'`
+ my_dlsyms=
+
+ if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ my_dlsyms=${my_outputname}S.c
+ else
+ func_error "not configured to extract global symbols from dlpreopened files"
+ fi
+ fi
+
+ if test -n "$my_dlsyms"; then
+ case $my_dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist=$output_objdir/$my_outputname.nm
+
+ func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+ # Parse the name list into a source file.
+ func_verbose "creating $output_objdir/$my_dlsyms"
+
+ $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test yes = "$dlself"; then
+ func_verbose "generating symbol list for '$output'"
+
+ $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ for progfile in $progfiles; do
+ func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+ func_verbose "extracting global C symbols from '$func_to_tool_file_result'"
+ $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $opt_dry_run || {
+ eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $opt_dry_run || {
+ eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols=$output_objdir/$outputname.exp
+ $opt_dry_run || {
+ $RM $export_symbols
+ eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ else
+ $opt_dry_run || {
+ eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+ eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ fi
+ fi
+
+ for dlprefile in $dlprefiles; do
+ func_verbose "extracting global C symbols from '$dlprefile'"
+ func_basename "$dlprefile"
+ name=$func_basename_result
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ # if an import library, we need to obtain dlname
+ if func_win32_import_lib_p "$dlprefile"; then
+ func_tr_sh "$dlprefile"
+ eval "curr_lafile=\$libfile_$func_tr_sh_result"
+ dlprefile_dlbasename=
+ if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+ # Use subshell, to avoid clobbering current variable values
+ dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+ if test -n "$dlprefile_dlname"; then
+ func_basename "$dlprefile_dlname"
+ dlprefile_dlbasename=$func_basename_result
+ else
+ # no lafile. user explicitly requested -dlpreopen <import library>.
+ $sharedlib_from_linklib_cmd "$dlprefile"
+ dlprefile_dlbasename=$sharedlib_from_linklib_result
+ fi
+ fi
+ $opt_dry_run || {
+ if test -n "$dlprefile_dlbasename"; then
+ eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+ else
+ func_warning "Could not compute DLL name from $name"
+ eval '$ECHO ": $name " >> "$nlist"'
+ fi
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+ $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+ }
+ else # not an import lib
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ fi
+ ;;
+ *)
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ ;;
+ esac
+ done
+
+ $opt_dry_run || {
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $MV "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if $GREP -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
+ :
+ else
+ $GREP -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+ fi
+
+ func_show_eval '$RM "${nlist}I"'
+ if test -n "$global_symbol_to_import"; then
+ eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I'
+ fi
+
+ echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols. */
+typedef struct {
+ const char *name;
+ void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];\
+"
+
+ if test -s "$nlist"I; then
+ echo >> "$output_objdir/$my_dlsyms" "\
+static void lt_syminit(void)
+{
+ LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols;
+ for (; symbol->name; ++symbol)
+ {"
+ $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms"
+ echo >> "$output_objdir/$my_dlsyms" "\
+ }
+}"
+ fi
+ echo >> "$output_objdir/$my_dlsyms" "\
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{ {\"$my_originator\", (void *) 0},"
+
+ if test -s "$nlist"I; then
+ echo >> "$output_objdir/$my_dlsyms" "\
+ {\"@INIT@\", (void *) &lt_syminit},"
+ fi
+
+ case $need_lib_prefix in
+ no)
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ *)
+ eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ esac
+ echo >> "$output_objdir/$my_dlsyms" "\
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ } # !$opt_dry_run
+
+ pic_flag_for_symtable=
+ case "$compile_command " in
+ *" -static "*) ;;
+ *)
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+ *-*-hpux*)
+ pic_flag_for_symtable=" $pic_flag" ;;
+ *)
+ $my_pic_p && pic_flag_for_symtable=" $pic_flag"
+ ;;
+ esac
+ ;;
+ esac
+ symtab_cflags=
+ for arg in $LTCFLAGS; do
+ case $arg in
+ -pie | -fpie | -fPIE) ;;
+ *) func_append symtab_cflags " $arg" ;;
+ esac
+ done
+
+ # Now compile the dynamic symbol file.
+ func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+ # Clean up the generated files.
+ func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"'
+
+ # Transform the symbol file into the correct name.
+ symfileobj=$output_objdir/${my_outputname}S.$objext
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ if test -f "$output_objdir/$my_outputname.def"; then
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ else
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ fi
+ ;;
+ *)
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ ;;
+ esac
+ ;;
+ *)
+ func_fatal_error "unknown suffix for '$my_dlsyms'"
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+ fi
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+ $debug_cmd
+
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+ test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+ $debug_cmd
+
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+ test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+ $debug_cmd
+
+ win32_libid_type=unknown
+ win32_fileres=`file -L $1 2>/dev/null`
+ case $win32_fileres in
+ *ar\ archive\ import\ library*) # definitely import
+ win32_libid_type="x86 archive import"
+ ;;
+ *ar\ archive*) # could be an import, or static
+ # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+ $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+ case $nm_interface in
+ "MS dumpbin")
+ if func_cygming_ms_implib_p "$1" ||
+ func_cygming_gnu_implib_p "$1"
+ then
+ win32_nmres=import
+ else
+ win32_nmres=
+ fi
+ ;;
+ *)
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+ $SED -n -e '
+ 1,100{
+ / I /{
+ s|.*|import|
+ p
+ q
+ }
+ }'`
+ ;;
+ esac
+ case $win32_nmres in
+ import*) win32_libid_type="x86 archive import";;
+ *) win32_libid_type="x86 archive static";;
+ esac
+ fi
+ ;;
+ *DLL*)
+ win32_libid_type="x86 DLL"
+ ;;
+ *executable*) # but shell scripts are "executable" too...
+ case $win32_fileres in
+ *MS\ Windows\ PE\ Intel*)
+ win32_libid_type="x86 DLL"
+ ;;
+ esac
+ ;;
+ esac
+ $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+ $debug_cmd
+
+ sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+ $debug_cmd
+
+ match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+ $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+ $SED '/^Contents of section '"$match_literal"':/{
+ # Place marker at beginning of archive member dllname section
+ s/.*/====MARK====/
+ p
+ d
+ }
+ # These lines can sometimes be longer than 43 characters, but
+ # are always uninteresting
+ /:[ ]*file format pe[i]\{,1\}-/d
+ /^In archive [^:]*:/d
+ # Ensure marker is printed
+ /^====MARK====/p
+ # Remove all lines with less than 43 characters
+ /^.\{43\}/!d
+ # From remaining lines, remove first 43 characters
+ s/^.\{43\}//' |
+ $SED -n '
+ # Join marker and all lines until next marker into a single line
+ /^====MARK====/ b para
+ H
+ $ b para
+ b
+ :para
+ x
+ s/\n//g
+ # Remove the marker
+ s/^====MARK====//
+ # Remove trailing dots and whitespace
+ s/[\. \t]*$//
+ # Print
+ /./p' |
+ # we now have a list, one entry per line, of the stringified
+ # contents of the appropriate section of all members of the
+ # archive that possess that section. Heuristic: eliminate
+ # all those that have a first or second character that is
+ # a '.' (that is, objdump's representation of an unprintable
+ # character.) This should work for all archives with less than
+ # 0x302f exports -- but will fail for DLLs whose name actually
+ # begins with a literal '.' or a single character followed by
+ # a '.'.
+ #
+ # Of those that remain, print the first one.
+ $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+ $debug_cmd
+
+ if func_cygming_gnu_implib_p "$1"; then
+ # binutils import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+ elif func_cygming_ms_implib_p "$1"; then
+ # ms-generated import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+ else
+ # unknown
+ sharedlib_from_linklib_result=
+ fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+ $debug_cmd
+
+ f_ex_an_ar_dir=$1; shift
+ f_ex_an_ar_oldlib=$1
+ if test yes = "$lock_old_archive_extraction"; then
+ lockfile=$f_ex_an_ar_oldlib.lock
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ fi
+ func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+ 'stat=$?; rm -f "$lockfile"; exit $stat'
+ if test yes = "$lock_old_archive_extraction"; then
+ $opt_dry_run || rm -f "$lockfile"
+ fi
+ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+ fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+ $debug_cmd
+
+ my_gentop=$1; shift
+ my_oldlibs=${1+"$@"}
+ my_oldobjs=
+ my_xlib=
+ my_xabs=
+ my_xdir=
+
+ for my_xlib in $my_oldlibs; do
+ # Extract the objects.
+ case $my_xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;;
+ *) my_xabs=`pwd`"/$my_xlib" ;;
+ esac
+ func_basename "$my_xlib"
+ my_xlib=$func_basename_result
+ my_xlib_u=$my_xlib
+ while :; do
+ case " $extracted_archives " in
+ *" $my_xlib_u "*)
+ func_arith $extracted_serial + 1
+ extracted_serial=$func_arith_result
+ my_xlib_u=lt$extracted_serial-$my_xlib ;;
+ *) break ;;
+ esac
+ done
+ extracted_archives="$extracted_archives $my_xlib_u"
+ my_xdir=$my_gentop/$my_xlib_u
+
+ func_mkdir_p "$my_xdir"
+
+ case $host in
+ *-darwin*)
+ func_verbose "Extracting $my_xabs"
+ # Do not bother doing anything if just a dry run
+ $opt_dry_run || {
+ darwin_orig_dir=`pwd`
+ cd $my_xdir || exit $?
+ darwin_archive=$my_xabs
+ darwin_curdir=`pwd`
+ func_basename "$darwin_archive"
+ darwin_base_archive=$func_basename_result
+ darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+ if test -n "$darwin_arches"; then
+ darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+ darwin_arch=
+ func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+ for darwin_arch in $darwin_arches; do
+ func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch"
+ $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive"
+ cd "unfat-$$/$darwin_base_archive-$darwin_arch"
+ func_extract_an_archive "`pwd`" "$darwin_base_archive"
+ cd "$darwin_curdir"
+ $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive"
+ done # $darwin_arches
+ ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+ darwin_file=
+ darwin_files=
+ for darwin_file in $darwin_filelist; do
+ darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+ $LIPO -create -output "$darwin_file" $darwin_files
+ done # $darwin_filelist
+ $RM -rf unfat-$$
+ cd "$darwin_orig_dir"
+ else
+ cd $darwin_orig_dir
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ fi # $darwin_arches
+ } # !$opt_dry_run
+ ;;
+ *)
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ ;;
+ esac
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+ done
+
+ func_extract_archives_result=$my_oldobjs
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable. Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take. If 'yes', then the emitted script
+# will assume that the directory where it is stored is
+# the $objdir directory. This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+ func_emit_wrapper_arg1=${1-no}
+
+ $ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# 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+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='$macro_version'
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$ECHO are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ file=\"\$0\""
+
+ qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+ $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+ ECHO=\"$qECHO\"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ that is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options that match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=\$0
+ shift
+ for lt_opt
+ do
+ case \"\$lt_opt\" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+ test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+ lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+ cat \"\$lt_dump_D/\$lt_dump_F\"
+ exit 0
+ ;;
+ --lt-*)
+ \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n \"\$lt_option_debug\"; then
+ echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\"
+ lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+ case $host in
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2* | *-cegcc*)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $ECHO "\
+ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ case \" \$* \" in
+ *\\ --lt-*)
+ for lt_wr_arg
+ do
+ case \$lt_wr_arg in
+ --lt-*) ;;
+ *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+ esac
+ shift
+ done ;;
+ esac
+ func_exec_program_core \${1+\"\$@\"}
+}
+
+ # Parse options
+ func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+ if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+ # special case for '.'
+ if test \"\$thisdir\" = \".\"; then
+ thisdir=\`pwd\`
+ fi
+ # remove .libs from thisdir
+ case \"\$thisdir\" in
+ *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+ $objdir ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test yes = "$fast_install"; then
+ $ECHO "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" ||
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $MKDIR \"\$progdir\"
+ else
+ $RM \"\$progdir/\$file\"
+ fi"
+
+ $ECHO "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ \$ECHO \"\$relink_command_output\" >&2
+ $RM \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $RM \"\$progdir/\$program\";
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $RM \"\$progdir/\$file\"
+ fi"
+ else
+ $ECHO "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ $ECHO "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # fixup the dll searchpath if we need to.
+ #
+ # Fix the DLL searchpath if we need to. Do this before prepending
+ # to shlibpath, because on Windows, both are PATH and uninstalled
+ # libraries must come first.
+ if test -n "$dllsearchpath"; then
+ $ECHO "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ # Export our shlibpath_var if we have one.
+ if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $ECHO "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ $ECHO "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+ func_exec_program \${1+\"\$@\"}
+ fi
+ else
+ # The program doesn't exist.
+ \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2
+ \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+ \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+ cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+ Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+
+ The $output program cannot be directly executed until all the libtool
+ libraries that it depends on are installed.
+
+ This wrapper executable should never be moved out of the build directory.
+ If it is, it will not operate correctly.
+*/
+EOF
+ cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+# include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* declarations of non-ANSI functions */
+#if defined __MINGW32__
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined __CYGWIN__
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined other_platform || defined ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined _MSC_VER
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+# define S_IXUSR _S_IEXEC
+#elif defined __MINGW32__
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+#elif defined __CYGWIN__
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined other platforms ... */
+#endif
+
+#if defined PATH_MAX
+# define LT_PATHMAX PATH_MAX
+#elif defined MAXPATHLEN
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \
+ defined __OS2__
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+# define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+# define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+ if (stale) { free (stale); stale = 0; } \
+} while (0)
+
+#if defined LT_DEBUGWRAPPER
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+ cat <<EOF
+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
+# define externally_visible volatile
+#else
+# define externally_visible __attribute__((externally_visible)) volatile
+#endif
+externally_visible const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+ if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ func_to_host_path "$temp_rpath"
+ cat <<EOF
+const char * LIB_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * LIB_PATH_VALUE = "";
+EOF
+ fi
+
+ if test -n "$dllsearchpath"; then
+ func_to_host_path "$dllsearchpath:"
+ cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE = "";
+EOF
+ fi
+
+ if test yes = "$fast_install"; then
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+ else
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+ fi
+
+
+ cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+ char **newargz;
+ int newargc;
+ char *tmp_pathspec;
+ char *actual_cwrapper_path;
+ char *actual_cwrapper_name;
+ char *target_name;
+ char *lt_argv_zero;
+ int rval = 127;
+
+ int i;
+
+ program_name = (char *) xstrdup (base_name (argv[0]));
+ newargz = XMALLOC (char *, (size_t) argc + 1);
+
+ /* very simple arg parsing; don't want to rely on getopt
+ * also, copy all non cwrapper options to newargz, except
+ * argz[0], which is handled differently
+ */
+ newargc=0;
+ for (i = 1; i < argc; i++)
+ {
+ if (STREQ (argv[i], dumpscript_opt))
+ {
+EOF
+ case $host in
+ *mingw* | *cygwin* )
+ # make stdout use "unix" line endings
+ echo " setmode(1,_O_BINARY);"
+ ;;
+ esac
+
+ cat <<"EOF"
+ lt_dump_script (stdout);
+ return 0;
+ }
+ if (STREQ (argv[i], debug_opt))
+ {
+ lt_debug = 1;
+ continue;
+ }
+ if (STREQ (argv[i], ltwrapper_option_prefix))
+ {
+ /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+ namespace, but it is not one of the ones we know about and
+ have already dealt with, above (inluding dump-script), then
+ report an error. Otherwise, targets might begin to believe
+ they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+ namespace. The first time any user complains about this, we'll
+ need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+ or a configure.ac-settable value.
+ */
+ lt_fatal (__FILE__, __LINE__,
+ "unrecognized %s option: '%s'",
+ ltwrapper_option_prefix, argv[i]);
+ }
+ /* otherwise ... */
+ newargz[++newargc] = xstrdup (argv[i]);
+ }
+ newargz[++newargc] = NULL;
+
+EOF
+ cat <<EOF
+ /* The GNU banner must be the first non-error debug message */
+ lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE) $VERSION\n");
+EOF
+ cat <<"EOF"
+ lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+ tmp_pathspec = find_executable (argv[0]);
+ if (tmp_pathspec == NULL)
+ lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (before symlink chase) at: %s\n",
+ tmp_pathspec);
+
+ actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (after symlink chase) at: %s\n",
+ actual_cwrapper_path);
+ XFREE (tmp_pathspec);
+
+ actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+ strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+ /* wrapper name transforms */
+ strendzap (actual_cwrapper_name, ".exe");
+ tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+ XFREE (actual_cwrapper_name);
+ actual_cwrapper_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ /* target_name transforms -- use actual target program name; might have lt- prefix */
+ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+ strendzap (target_name, ".exe");
+ tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+ XFREE (target_name);
+ target_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) libtool target name: %s\n",
+ target_name);
+EOF
+
+ cat <<EOF
+ newargz[0] =
+ XMALLOC (char, (strlen (actual_cwrapper_path) +
+ strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+ strcpy (newargz[0], actual_cwrapper_path);
+ strcat (newargz[0], "$objdir");
+ strcat (newargz[0], "/");
+EOF
+
+ cat <<"EOF"
+ /* stop here, and copy so we don't have to do this twice */
+ tmp_pathspec = xstrdup (newargz[0]);
+
+ /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+ strcat (newargz[0], actual_cwrapper_name);
+
+ /* DO want the lt- prefix here if it exists, so use target_name */
+ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+ XFREE (tmp_pathspec);
+ tmp_pathspec = NULL;
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ {
+ char* p;
+ while ((p = strchr (newargz[0], '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ }
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+ XFREE (target_name);
+ XFREE (actual_cwrapper_path);
+ XFREE (actual_cwrapper_name);
+
+ lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+ lt_setenv ("DUALCASE", "1"); /* for MSK sh */
+ /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must
+ be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+ because on Windows, both *_VARNAMEs are PATH but uninstalled
+ libraries must come first. */
+ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+ lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+ lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+ nonnull (lt_argv_zero));
+ for (i = 0; i < newargc; i++)
+ {
+ lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+ i, nonnull (newargz[i]));
+ }
+
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ /* execv doesn't actually work on mingw as expected on unix */
+ newargz = prepare_spawn (newargz);
+ rval = (int) _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+ if (rval == -1)
+ {
+ /* failed to start process */
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) failed to launch target \"%s\": %s\n",
+ lt_argv_zero, nonnull (strerror (errno)));
+ return 127;
+ }
+ return rval;
+EOF
+ ;;
+ *)
+ cat <<"EOF"
+ execv (lt_argv_zero, newargz);
+ return rval; /* =127, but avoids unused variable warning */
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+ void *p = (void *) malloc (num);
+ if (!p)
+ lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+ return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+ string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+ const char *base;
+
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+ /* Skip over the disk name in MSDOS pathnames. */
+ if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+ return base;
+}
+
+int
+check_executable (const char *path)
+{
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if ((stat (path, &st) >= 0)
+ && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return 1;
+ else
+ return 0;
+}
+
+int
+make_executable (const char *path)
+{
+ int rval = 0;
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if (stat (path, &st) >= 0)
+ {
+ rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+ }
+ return rval;
+}
+
+/* Searches for the full path of the wrapper. Returns
+ newly allocated full path name if found, NULL otherwise
+ Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+ int has_slash = 0;
+ const char *p;
+ const char *p_next;
+ /* static buffer for getcwd */
+ char tmp[LT_PATHMAX + 1];
+ size_t tmp_len;
+ char *concat_name;
+
+ lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+ nonempty (wrapper));
+
+ if ((wrapper == NULL) || (*wrapper == '\0'))
+ return NULL;
+
+ /* Absolute path? */
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+ if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ else
+ {
+#endif
+ if (IS_DIR_SEPARATOR (wrapper[0]))
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+ }
+#endif
+
+ for (p = wrapper; *p; p++)
+ if (*p == '/')
+ {
+ has_slash = 1;
+ break;
+ }
+ if (!has_slash)
+ {
+ /* no slashes; search PATH */
+ const char *path = getenv ("PATH");
+ if (path != NULL)
+ {
+ for (p = path; *p; p = p_next)
+ {
+ const char *q;
+ size_t p_len;
+ for (q = p; *q; q++)
+ if (IS_PATH_SEPARATOR (*q))
+ break;
+ p_len = (size_t) (q - p);
+ p_next = (*q == '\0' ? q : q + 1);
+ if (p_len == 0)
+ {
+ /* empty path: current directory */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name =
+ XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+ }
+ else
+ {
+ concat_name =
+ XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, p, p_len);
+ concat_name[p_len] = '/';
+ strcpy (concat_name + p_len + 1, wrapper);
+ }
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ }
+ /* not found in PATH; assume curdir */
+ }
+ /* Relative path | not found in path: prepend cwd */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+ return xstrdup (pathspec);
+#else
+ char buf[LT_PATHMAX];
+ struct stat s;
+ char *tmp_pathspec = xstrdup (pathspec);
+ char *p;
+ int has_symlinks = 0;
+ while (strlen (tmp_pathspec) && !has_symlinks)
+ {
+ lt_debugprintf (__FILE__, __LINE__,
+ "checking path component for symlinks: %s\n",
+ tmp_pathspec);
+ if (lstat (tmp_pathspec, &s) == 0)
+ {
+ if (S_ISLNK (s.st_mode) != 0)
+ {
+ has_symlinks = 1;
+ break;
+ }
+
+ /* search backwards for last DIR_SEPARATOR */
+ p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+ while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ p--;
+ if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ {
+ /* no more DIR_SEPARATORS left */
+ break;
+ }
+ *p = '\0';
+ }
+ else
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "error accessing file \"%s\": %s",
+ tmp_pathspec, nonnull (strerror (errno)));
+ }
+ }
+ XFREE (tmp_pathspec);
+
+ if (!has_symlinks)
+ {
+ return xstrdup (pathspec);
+ }
+
+ tmp_pathspec = realpath (pathspec, buf);
+ if (tmp_pathspec == 0)
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "could not follow symlinks for %s", pathspec);
+ }
+ return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+ size_t len, patlen;
+
+ assert (str != NULL);
+ assert (pat != NULL);
+
+ len = strlen (str);
+ patlen = strlen (pat);
+
+ if (patlen <= len)
+ {
+ str += len - patlen;
+ if (STREQ (str, pat))
+ *str = '\0';
+ }
+ return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ if (lt_debug)
+ {
+ (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+ va_start (args, fmt);
+ (void) vfprintf (stderr, fmt, args);
+ va_end (args);
+ }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+ int line, const char *mode,
+ const char *message, va_list ap)
+{
+ fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+ vfprintf (stderr, message, ap);
+ fprintf (stderr, ".\n");
+
+ if (exit_status >= 0)
+ exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+ va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+ return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+ return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_setenv) setting '%s' to '%s'\n",
+ nonnull (name), nonnull (value));
+ {
+#ifdef HAVE_SETENV
+ /* always make a copy, for consistency with !HAVE_SETENV */
+ char *str = xstrdup (value);
+ setenv (name, str, 1);
+#else
+ size_t len = strlen (name) + 1 + strlen (value) + 1;
+ char *str = XMALLOC (char, len);
+ sprintf (str, "%s=%s", name, value);
+ if (putenv (str) != EXIT_SUCCESS)
+ {
+ XFREE (str);
+ }
+#endif
+ }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+ char *new_value;
+ if (orig_value && *orig_value)
+ {
+ size_t orig_value_len = strlen (orig_value);
+ size_t add_len = strlen (add);
+ new_value = XMALLOC (char, add_len + orig_value_len + 1);
+ if (to_end)
+ {
+ strcpy (new_value, orig_value);
+ strcpy (new_value + orig_value_len, add);
+ }
+ else
+ {
+ strcpy (new_value, add);
+ strcpy (new_value + add_len, orig_value);
+ }
+ }
+ else
+ {
+ new_value = xstrdup (add);
+ }
+ return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ /* some systems can't cope with a ':'-terminated path #' */
+ size_t len = strlen (new_value);
+ while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+ {
+ new_value[--len] = '\0';
+ }
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+EOF
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+ Note that spawn() does not by itself call the command interpreter
+ (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+ ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&v);
+ v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+ }) ? "cmd.exe" : "command.com").
+ Instead it simply concatenates the arguments, separated by ' ', and calls
+ CreateProcess(). We must quote the arguments since Win32 CreateProcess()
+ interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+ special way:
+ - Space and tab are interpreted as delimiters. They are not treated as
+ delimiters if they are surrounded by double quotes: "...".
+ - Unescaped double quotes are removed from the input. Their only effect is
+ that within double quotes, space and tab are treated like normal
+ characters.
+ - Backslashes not followed by double quotes are not special.
+ - But 2*n+1 backslashes followed by a double quote become
+ n backslashes followed by a double quote (n >= 0):
+ \" -> "
+ \\\" -> \"
+ \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \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"
+#define SHELL_SPACE_CHARS " \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"
+char **
+prepare_spawn (char **argv)
+{
+ size_t argc;
+ char **new_argv;
+ size_t i;
+
+ /* Count number of arguments. */
+ for (argc = 0; argv[argc] != NULL; argc++)
+ ;
+
+ /* Allocate new argument vector. */
+ new_argv = XMALLOC (char *, argc + 1);
+
+ /* Put quoted arguments into the new argument vector. */
+ for (i = 0; i < argc; i++)
+ {
+ const char *string = argv[i];
+
+ if (string[0] == '\0')
+ new_argv[i] = xstrdup ("\"\"");
+ else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+ {
+ int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+ size_t length;
+ unsigned int backslashes;
+ const char *s;
+ char *quoted_string;
+ char *p;
+
+ length = 0;
+ backslashes = 0;
+ if (quote_around)
+ length++;
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ length += backslashes + 1;
+ length++;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ length += backslashes + 1;
+
+ quoted_string = XMALLOC (char, length + 1);
+
+ p = quoted_string;
+ backslashes = 0;
+ if (quote_around)
+ *p++ = '"';
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ {
+ unsigned int j;
+ for (j = backslashes + 1; j > 0; j--)
+ *p++ = '\\';
+ }
+ *p++ = c;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ {
+ unsigned int j;
+ for (j = backslashes; j > 0; j--)
+ *p++ = '\\';
+ *p++ = '"';
+ }
+ *p = '\0';
+
+ new_argv[i] = quoted_string;
+ }
+ else
+ new_argv[i] = (char *) string;
+ }
+ new_argv[argc] = NULL;
+
+ return new_argv;
+}
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+ func_emit_wrapper yes |
+ $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/ fputs ("\1", f);/p
+g
+D'
+ cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+ $debug_cmd
+
+ case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+ *import*) : ;;
+ *) false ;;
+ esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+ $debug_cmd
+
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # what system we are compiling for in order to pass an extra
+ # flag for every libtool invocation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll that has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args=$nonopt
+ base_compile="$nonopt $@"
+ compile_command=$nonopt
+ finalize_command=$nonopt
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+ inst_prefix_dir=
+ new_inherited_linker_flags=
+
+ avoid_version=no
+ bindir=
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ non_pic_objects=
+ precious_files_regex=
+ prefer_static_libs=no
+ preload=false
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+ weak_libs=
+ single_module=$wl-single_module
+ func_infer_tag $base_compile
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -shared)
+ test yes != "$build_libtool_libs" \
+ && func_fatal_configuration "cannot build a shared library"
+ build_old_libs=no
+ break
+ ;;
+ -all-static | -static | -static-libtool-libs)
+ case $arg in
+ -all-static)
+ if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then
+ func_warning "complete static linking is impossible in this configuration"
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ -static)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=built
+ ;;
+ -static-libtool-libs)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ esac
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test "$#" -gt 0; do
+ arg=$1
+ shift
+ func_quote_for_eval "$arg"
+ qarg=$func_quote_for_eval_unquoted_result
+ func_append libtool_args " $func_quote_for_eval_result"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ func_append compile_command " @OUTPUT@"
+ func_append finalize_command " @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ bindir)
+ bindir=$arg
+ prev=
+ continue
+ ;;
+ dlfiles|dlprefiles)
+ $preload || {
+ # Add the symbol object into the linking commands.
+ func_append compile_command " @SYMFILE@"
+ func_append finalize_command " @SYMFILE@"
+ preload=:
+ }
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test no = "$dlself"; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test dlprefiles = "$prev"; then
+ dlself=yes
+ elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test dlfiles = "$prev"; then
+ func_append dlfiles " $arg"
+ else
+ func_append dlprefiles " $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols=$arg
+ test -f "$arg" \
+ || func_fatal_error "symbol file '$arg' does not exist"
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex=$arg
+ prev=
+ continue
+ ;;
+ framework)
+ case $host in
+ *-*-darwin*)
+ case "$deplibs " in
+ *" $qarg.ltframework "*) ;;
+ *) func_append deplibs " $qarg.ltframework" # this is fixed later
+ ;;
+ esac
+ ;;
+ esac
+ prev=
+ continue
+ ;;
+ inst_prefix)
+ inst_prefix_dir=$arg
+ prev=
+ continue
+ ;;
+ mllvm)
+ # Clang does not use LLVM to link, so we can simply discard any
+ # '-mllvm $arg' options when doing the link step.
+ prev=
+ continue
+ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+ moreargs=
+ for fil in `cat "$save_arg"`
+ do
+# func_append moreargs " $fil"
+ arg=$fil
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test none = "$pic_object" &&
+ test none = "$non_pic_object"; then
+ func_fatal_error "cannot find name of object for '$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ if test none != "$pic_object"; then
+ # Prepend the subdirectory the object is found in.
+ pic_object=$xdir$pic_object
+
+ if test dlfiles = "$prev"; then
+ if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test dlprefiles = "$prev"; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg=$pic_object
+ fi
+
+ # Non-PIC object.
+ if test none != "$non_pic_object"; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object=$xdir$non_pic_object
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test none = "$pic_object"; then
+ arg=$non_pic_object
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object=$pic_object
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "'$arg' is not a valid libtool object"
+ fi
+ fi
+ done
+ else
+ func_fatal_error "link input file '$arg' does not exist"
+ fi
+ arg=$save_arg
+ prev=
+ continue
+ ;;
+ precious_regex)
+ precious_files_regex=$arg
+ prev=
+ continue
+ ;;
+ release)
+ release=-$arg
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ if test rpath = "$prev"; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) func_append rpath " $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) func_append xrpath " $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ shrext)
+ shrext_cmds=$arg
+ prev=
+ continue
+ ;;
+ weak)
+ func_append weak_libs " $arg"
+ prev=
+ continue
+ ;;
+ xcclinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xcompiler)
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xlinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $wl$qarg"
+ prev=
+ func_append compile_command " $wl$qarg"
+ func_append finalize_command " $wl$qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n "$prev"
+
+ prevarg=$arg
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ # See comment for -static flag below, for more details.
+ func_append compile_command " $link_static_flag"
+ func_append finalize_command " $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ func_fatal_error "'-allow-undefined' must not be used because it is the default"
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -bindir)
+ prev=bindir
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ func_fatal_error "more than one -exported-symbols argument is not allowed"
+ fi
+ if test X-export-symbols = "X$arg"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -framework)
+ prev=framework
+ continue
+ ;;
+
+ -inst-prefix-dir)
+ prev=inst_prefix
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix* | /*-*-irix*)
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ func_stripname "-L" '' "$arg"
+ if test -z "$func_stripname_result"; then
+ if test "$#" -gt 0; then
+ func_fatal_error "require no space between '-L' and '$1'"
+ else
+ func_fatal_error "need path for '-L' option"
+ fi
+ fi
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ test -z "$absdir" && \
+ func_fatal_error "cannot determine absolute directory name of '$dir'"
+ dir=$absdir
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "* | *" $arg "*)
+ # Will only happen for absolute or sysroot arguments
+ ;;
+ *)
+ # Preserve sysroot, but never include relative directories
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+ *) func_append deplibs " -L$dir" ;;
+ esac
+ func_append lib_search_path " $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ ::) dllsearchpath=$dir;;
+ *) func_append dllsearchpath ":$dir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test X-lc = "X$arg" || test X-lm = "X$arg"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test X-lc = "X$arg" && continue
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+ # Do not include libc due to us having libc/libc_r.
+ test X-lc = "X$arg" && continue
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C and math libraries are in the System framework
+ func_append deplibs " System.ltframework"
+ continue
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ test X-lc = "X$arg" && continue
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ test X-lc = "X$arg" && continue
+ ;;
+ esac
+ elif test X-lc_r = "X$arg"; then
+ case $host in
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ func_append deplibs " $arg"
+ continue
+ ;;
+
+ -mllvm)
+ prev=mllvm
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ # Tru64 UNIX uses -model [arg] to determine the layout of C++
+ # classes, name mangling, and exception handling.
+ # Darwin uses the -arch flag to determine output architecture.
+ -model|-arch|-isysroot|--sysroot)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ prev=xcompiler
+ continue
+ ;;
+
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case "$new_inherited_linker_flags " in
+ *" $arg "*) ;;
+ * ) func_append new_inherited_linker_flags " $arg" ;;
+ esac
+ continue
+ ;;
+
+ -multi_module)
+ single_module=$wl-multi_module
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # and Darwin in order for the loader to find any dlls it needs.
+ func_warning "'-no-install' is ignored for $host"
+ func_warning "assuming '-no-fast-install' instead"
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -objectlist)
+ prev=objectlist
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -precious-files-regex)
+ prev=precious_regex
+ continue
+ ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ func_stripname '-R' '' "$arg"
+ dir=$func_stripname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ =*)
+ func_stripname '=' '' "$dir"
+ dir=$lt_sysroot$func_stripname_result
+ ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ continue
+ ;;
+
+ -shared)
+ # The effects of -shared are defined in a previous loop.
+ continue
+ ;;
+
+ -shrext)
+ prev=shrext
+ continue
+ ;;
+
+ -static | -static-libtool-libs)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ -version-number)
+ prev=vinfo
+ vinfo_number=yes
+ continue
+ ;;
+
+ -weak)
+ prev=weak
+ continue
+ ;;
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs=$IFS; IFS=,
+ for flag in $args; do
+ IFS=$save_ifs
+ func_quote_for_eval "$flag"
+ func_append arg " $func_quote_for_eval_result"
+ func_append compiler_flags " $func_quote_for_eval_result"
+ done
+ IFS=$save_ifs
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Wl,*)
+ func_stripname '-Wl,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs=$IFS; IFS=,
+ for flag in $args; do
+ IFS=$save_ifs
+ func_quote_for_eval "$flag"
+ func_append arg " $wl$func_quote_for_eval_result"
+ func_append compiler_flags " $wl$func_quote_for_eval_result"
+ func_append linker_flags " $func_quote_for_eval_result"
+ done
+ IFS=$save_ifs
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ -XCClinker)
+ prev=xcclinker
+ continue
+ ;;
+
+ # -msg_* for osf cc
+ -msg_*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ ;;
+
+ # Flags to be passed through unchanged, with rationale:
+ # -64, -mips[0-9] enable 64-bit mode for the SGI compiler
+ # -r[0-9][0-9]* specify processor for the SGI compiler
+ # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+ # +DA*, +DD* enable 64-bit mode for the HP compiler
+ # -q* compiler args for the IBM compiler
+ # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+ # -F/path path to uninstalled frameworks, gcc on darwin
+ # -p, -pg, --coverage, -fprofile-* profiling flags for GCC
+ # -fstack-protector* stack protector flags for GCC
+ # @file GCC response files
+ # -tp=* Portland pgcc target processor selection
+ # --sysroot=* for sysroot support
+ # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+ # -stdlib=* select c++ std lib with clang
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ func_append compiler_flags " $arg"
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ ;;
+
+ *.$objext)
+ # A standard object.
+ func_append objs " $arg"
+ ;;
+
+ *.lo)
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test none = "$pic_object" &&
+ test none = "$non_pic_object"; then
+ func_fatal_error "cannot find name of object for '$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ test none = "$pic_object" || {
+ # Prepend the subdirectory the object is found in.
+ pic_object=$xdir$pic_object
+
+ if test dlfiles = "$prev"; then
+ if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test dlprefiles = "$prev"; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg=$pic_object
+ }
+
+ # Non-PIC object.
+ if test none != "$non_pic_object"; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object=$xdir$non_pic_object
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test none = "$pic_object"; then
+ arg=$non_pic_object
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object=$pic_object
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "'$arg' is not a valid libtool object"
+ fi
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ func_append deplibs " $arg"
+ func_append old_deplibs " $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ func_resolve_sysroot "$arg"
+ if test dlfiles = "$prev"; then
+ # This library was specified with -dlopen.
+ func_append dlfiles " $func_resolve_sysroot_result"
+ prev=
+ elif test dlprefiles = "$prev"; then
+ # The library was specified with -dlpreopen.
+ func_append dlprefiles " $func_resolve_sysroot_result"
+ prev=
+ else
+ func_append deplibs " $func_resolve_sysroot_result"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+ done # argument parsing loop
+
+ test -n "$prev" && \
+ func_fatal_help "the '$prevarg' option requires an argument"
+
+ if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ func_basename "$output"
+ outputname=$func_basename_result
+ libobjs_save=$libobjs
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ func_dirname "$output" "/" ""
+ output_objdir=$func_dirname_result$objdir
+ func_to_tool_file "$output_objdir/"
+ tool_output_objdir=$func_to_tool_file_result
+ # Create the object directory.
+ func_mkdir_p "$output_objdir"
+
+ # Determine the type of output
+ case $output in
+ "")
+ func_fatal_help "you must specify an output file"
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ specialdeplibs=
+
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ if $opt_preserve_dup_deps; then
+ case "$libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append libs " $deplib"
+ done
+
+ if test lib = "$linkmode"; then
+ libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+ # Compute libraries that are listed more than once in $predeps
+ # $postdeps and mark them as special (i.e., whose duplicates are
+ # not to be eliminated).
+ pre_post_deps=
+ if $opt_duplicate_compiler_generated_deps; then
+ for pre_post_dep in $predeps $postdeps; do
+ case "$pre_post_deps " in
+ *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+ esac
+ func_append pre_post_deps " $pre_post_dep"
+ done
+ fi
+ pre_post_deps=
+ fi
+
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+
+ case $linkmode in
+ lib)
+ passes="conv dlpreopen link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ func_fatal_help "libraries can '-dlopen' only libtool libraries: $file"
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=false
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+
+ for pass in $passes; do
+ # The preopen pass in lib mode reverses $deplibs; put it back here
+ # so that -L comes before libs that need it for instance...
+ if test lib,link = "$linkmode,$pass"; then
+ ## FIXME: Find the place where the list is rebuilt in the wrong
+ ## order, and fix it there properly
+ tmp_deplibs=
+ for deplib in $deplibs; do
+ tmp_deplibs="$deplib $tmp_deplibs"
+ done
+ deplibs=$tmp_deplibs
+ fi
+
+ if test lib,link = "$linkmode,$pass" ||
+ test prog,scan = "$linkmode,$pass"; then
+ libs=$deplibs
+ deplibs=
+ fi
+ if test prog = "$linkmode"; then
+ case $pass in
+ dlopen) libs=$dlfiles ;;
+ dlpreopen) libs=$dlprefiles ;;
+ link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+ esac
+ fi
+ if test lib,dlpreopen = "$linkmode,$pass"; then
+ # Collect and forward deplibs of preopened libtool libs
+ for lib in $dlprefiles; do
+ # Ignore non-libtool-libs
+ dependency_libs=
+ func_resolve_sysroot "$lib"
+ case $lib in
+ *.la) func_source "$func_resolve_sysroot_result" ;;
+ esac
+
+ # Collect preopened libtool deplibs, except any this library
+ # has declared as weak libs
+ for deplib in $dependency_libs; do
+ func_basename "$deplib"
+ deplib_base=$func_basename_result
+ case " $weak_libs " in
+ *" $deplib_base "*) ;;
+ *) func_append deplibs " $deplib" ;;
+ esac
+ done
+ done
+ libs=$dlprefiles
+ fi
+ if test dlopen = "$pass"; then
+ # Collect dlpreopened libraries
+ save_deplibs=$deplibs
+ deplibs=
+ fi
+
+ for deplib in $libs; do
+ lib=
+ found=false
+ case $deplib in
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append compiler_flags " $deplib"
+ if test lib = "$linkmode"; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -l*)
+ if test lib != "$linkmode" && test prog != "$linkmode"; then
+ func_warning "'-l' is ignored for archives/objects"
+ continue
+ fi
+ func_stripname '-l' '' "$deplib"
+ name=$func_stripname_result
+ if test lib = "$linkmode"; then
+ searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+ else
+ searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+ fi
+ for searchdir in $searchdirs; do
+ for search_ext in .la $std_shrext .so .a; do
+ # Search the libtool library
+ lib=$searchdir/lib$name$search_ext
+ if test -f "$lib"; then
+ if test .la = "$search_ext"; then
+ found=:
+ else
+ found=false
+ fi
+ break 2
+ fi
+ done
+ done
+ if $found; then
+ # deplib is a libtool library
+ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+ # We need to do some special things here, and not later.
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $deplib "*)
+ if func_lalib_p "$lib"; then
+ library_names=
+ old_library=
+ func_source "$lib"
+ for l in $old_library $library_names; do
+ ll=$l
+ done
+ if test "X$ll" = "X$old_library"; then # only static version available
+ found=false
+ func_dirname "$lib" "" "."
+ ladir=$func_dirname_result
+ lib=$ladir/$old_library
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ fi
+ ;;
+ *) ;;
+ esac
+ fi
+ else
+ # deplib doesn't seem to be a libtool library
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ ;; # -l
+ *.ltframework)
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ if test lib = "$linkmode"; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test conv = "$pass" && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ prog)
+ if test conv = "$pass"; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test scan = "$pass"; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ *)
+ func_warning "'-L' is ignored for archives/objects"
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test link = "$pass"; then
+ func_stripname '-R' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # Make sure the xrpath contains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ lib=$func_resolve_sysroot_result
+ ;;
+ *.$libext)
+ if test conv = "$pass"; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ # Linking convenience modules into shared libraries is allowed,
+ # but linking other static libraries is non-portable.
+ case " $dlpreconveniencelibs " in
+ *" $deplib "*) ;;
+ *)
+ valid_a_lib=false
+ case $deplibs_check_method in
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ valid_a_lib=:
+ fi
+ ;;
+ pass_all)
+ valid_a_lib=:
+ ;;
+ esac
+ if $valid_a_lib; then
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the"
+ $ECHO "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ else
+ echo
+ $ECHO "*** Warning: Trying to link with static lib archive $deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because the file extensions .$libext of this argument makes me believe"
+ echo "*** that it is just a static archive that I should not use here."
+ fi
+ ;;
+ esac
+ continue
+ ;;
+ prog)
+ if test link != "$pass"; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test conv = "$pass"; then
+ deplibs="$deplib $deplibs"
+ elif test prog = "$linkmode"; then
+ if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ func_append newdlprefiles " $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append newdlfiles " $deplib"
+ fi
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=:
+ continue
+ ;;
+ esac # case $deplib
+
+ $found || test -f "$lib" \
+ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'"
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$lib" \
+ || func_fatal_error "'$lib' is not a valid libtool archive"
+
+ func_dirname "$lib" "" "."
+ ladir=$func_dirname_result
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ inherited_linker_flags=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variables installed, or shouldnotlink
+ installed=yes
+ shouldnotlink=no
+ avoidtemprpath=
+
+
+ # Read the .la file
+ func_source "$lib"
+
+ # Convert "-framework foo" to "foo.ltframework"
+ if test -n "$inherited_linker_flags"; then
+ tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+ for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+ case " $new_inherited_linker_flags " in
+ *" $tmp_inherited_linker_flag "*) ;;
+ *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+ esac
+ done
+ fi
+ dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ if test lib,link = "$linkmode,$pass" ||
+ test prog,scan = "$linkmode,$pass" ||
+ { test prog != "$linkmode" && test lib != "$linkmode"; }; then
+ test -n "$dlopen" && func_append dlfiles " $dlopen"
+ test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+ fi
+
+ if test conv = "$pass"; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ func_fatal_error "cannot find name of link library for '$lib'"
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ func_append convenience " $ladir/$objdir/$old_library"
+ func_append old_convenience " $ladir/$objdir/$old_library"
+ elif test prog != "$linkmode" && test lib != "$linkmode"; then
+ func_fatal_error "'$lib' is not a convenience library"
+ fi
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done
+ continue
+ fi # $pass = conv
+
+
+ # Get the name of the library we link against.
+ linklib=
+ if test -n "$old_library" &&
+ { test yes = "$prefer_static_libs" ||
+ test built,no = "$prefer_static_libs,$installed"; }; then
+ linklib=$old_library
+ else
+ for l in $old_library $library_names; do
+ linklib=$l
+ done
+ fi
+ if test -z "$linklib"; then
+ func_fatal_error "cannot find name of link library for '$lib'"
+ fi
+
+ # This library was specified with -dlopen.
+ if test dlopen = "$pass"; then
+ test -z "$libdir" \
+ && func_fatal_error "cannot -dlopen a convenience library: '$lib'"
+ if test -z "$dlname" ||
+ test yes != "$dlopen_support" ||
+ test no = "$build_libtool_libs"
+ then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload. We also need to preload any
+ # dependent libraries so libltdl's deplib preloader doesn't
+ # bomb out in the load deplibs phase.
+ func_append dlprefiles " $lib $dependency_libs"
+ else
+ func_append newdlfiles " $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ func_warning "cannot determine absolute directory name of '$ladir'"
+ func_warning "passing it literally to the linker, although it might fail"
+ abs_ladir=$ladir
+ fi
+ ;;
+ esac
+ func_basename "$lib"
+ laname=$func_basename_result
+
+ # Find the relevant object directory and library name.
+ if test yes = "$installed"; then
+ if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ func_warning "library '$lib' was moved."
+ dir=$ladir
+ absdir=$abs_ladir
+ libdir=$abs_ladir
+ else
+ dir=$lt_sysroot$libdir
+ absdir=$lt_sysroot$libdir
+ fi
+ test yes = "$hardcode_automatic" && avoidtemprpath=yes
+ else
+ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ dir=$ladir
+ absdir=$abs_ladir
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ else
+ dir=$ladir/$objdir
+ absdir=$abs_ladir/$objdir
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ fi
+ fi # $installed = yes
+ func_stripname 'lib' '.la' "$laname"
+ name=$func_stripname_result
+
+ # This library was specified with -dlpreopen.
+ if test dlpreopen = "$pass"; then
+ if test -z "$libdir" && test prog = "$linkmode"; then
+ func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'"
+ fi
+ case $host in
+ # special handling for platforms with PE-DLLs.
+ *cygwin* | *mingw* | *cegcc* )
+ # Linker will automatically link against shared library if both
+ # static and shared are present. Therefore, ensure we extract
+ # symbols from the import library if a shared library is present
+ # (otherwise, the dlopen module name will be incorrect). We do
+ # this by putting the import library name into $newdlprefiles.
+ # We recover the dlopen module name by 'saving' the la file
+ # name in a special purpose variable, and (later) extracting the
+ # dlname from the la file.
+ if test -n "$dlname"; then
+ func_tr_sh "$dir/$linklib"
+ eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+ func_append newdlprefiles " $dir/$linklib"
+ else
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ fi
+ ;;
+ * )
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ func_append newdlprefiles " $dir/$dlname"
+ else
+ func_append newdlprefiles " $dir/$linklib"
+ fi
+ ;;
+ esac
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test lib = "$linkmode"; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs" # used for prog,scan pass
+ fi
+ continue
+ fi
+
+
+ if test prog = "$linkmode" && test link != "$pass"; then
+ func_append newlib_search_path " $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=false
+ if test no != "$link_all_deplibs" || test -z "$library_names" ||
+ test no = "$build_libtool_libs"; then
+ linkalldeplibs=:
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ esac
+ # Need to link against all dependency_libs?
+ if $linkalldeplibs; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ if test prog,link = "$linkmode,$pass"; then
+ if test -n "$library_names" &&
+ { { test no = "$prefer_static_libs" ||
+ test built,yes = "$prefer_static_libs,$installed"; } ||
+ test -z "$old_library"; }; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then
+ # Make sure the rpath contains only unique directories.
+ case $temp_rpath: in
+ *"$absdir:"*) ;;
+ *) func_append temp_rpath "$absdir:" ;;
+ esac
+ fi
+
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi # $linkmode,$pass = prog,link...
+
+ if $alldeplibs &&
+ { test pass_all = "$deplibs_check_method" ||
+ { test yes = "$build_libtool_libs" &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+ fi
+
+ link_static=no # Whether the deplib will be linked statically
+ use_static_libs=$prefer_static_libs
+ if test built = "$use_static_libs" && test yes = "$installed"; then
+ use_static_libs=no
+ fi
+ if test -n "$library_names" &&
+ { test no = "$use_static_libs" || test -z "$old_library"; }; then
+ case $host in
+ *cygwin* | *mingw* | *cegcc*)
+ # No point in relinking DLLs because paths are not encoded
+ func_append notinst_deplibs " $lib"
+ need_relink=no
+ ;;
+ *)
+ if test no = "$installed"; then
+ func_append notinst_deplibs " $lib"
+ need_relink=yes
+ fi
+ ;;
+ esac
+ # This is a shared library
+
+ # Warn about portability, can't link against -module's on some
+ # systems (darwin). Don't bleat about dlopened modules though!
+ dlopenmodule=
+ for dlpremoduletest in $dlprefiles; do
+ if test "X$dlpremoduletest" = "X$lib"; then
+ dlopenmodule=$dlpremoduletest
+ break
+ fi
+ done
+ if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then
+ echo
+ if test prog = "$linkmode"; then
+ $ECHO "*** Warning: Linking the executable $output against the loadable module"
+ else
+ $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+ fi
+ $ECHO "*** $linklib is not portable!"
+ fi
+ if test lib = "$linkmode" &&
+ test yes = "$hardcode_into_libs"; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ shift
+ realname=$1
+ shift
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname=$dlname
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin* | mingw* | *cegcc*)
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix=-$major
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname=$realname
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot=$soname
+ func_basename "$soroot"
+ soname=$func_basename_result
+ func_stripname 'lib' '.dll' "$soname"
+ newlib=libimp-$func_stripname_result.a
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ func_verbose "extracting exported symbol list from '$soname'"
+ func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ func_verbose "generating import library for '$soname'"
+ func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n "$old_archive_from_expsyms_cmds"
+
+ if test prog = "$linkmode" || test relink != "$opt_mode"; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test no = "$hardcode_direct"; then
+ add=$dir/$linklib
+ case $host in
+ *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;;
+ *-*-sysv4*uw2*) add_dir=-L$dir ;;
+ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+ *-*-unixware7*) add_dir=-L$dir ;;
+ *-*-darwin* )
+ # if the lib is a (non-dlopened) module then we cannot
+ # link against it, someone is ignoring the earlier warnings
+ if /usr/bin/file -L $add 2> /dev/null |
+ $GREP ": [^:]* bundle" >/dev/null; then
+ if test "X$dlopenmodule" != "X$lib"; then
+ $ECHO "*** Warning: lib $linklib is a module, not a shared library"
+ if test -z "$old_library"; then
+ echo
+ echo "*** And there doesn't seem to be a static archive available"
+ echo "*** The link will probably fail, sorry"
+ else
+ add=$dir/$old_library
+ fi
+ elif test -n "$old_library"; then
+ add=$dir/$old_library
+ fi
+ fi
+ esac
+ elif test no = "$hardcode_minus_L"; then
+ case $host in
+ *-*-sunos*) add_shlibpath=$dir ;;
+ esac
+ add_dir=-L$dir
+ add=-l$name
+ elif test no = "$hardcode_shlibpath_var"; then
+ add_shlibpath=$dir
+ add=-l$name
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test yes = "$hardcode_direct" &&
+ test no = "$hardcode_direct_absolute"; then
+ add=$dir/$linklib
+ elif test yes = "$hardcode_minus_L"; then
+ add_dir=-L$absdir
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add=-l$name
+ elif test yes = "$hardcode_shlibpath_var"; then
+ add_shlibpath=$dir
+ add=-l$name
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test yes != "$lib_linked"; then
+ func_fatal_configuration "unsupported hardcode properties"
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) func_append compile_shlibpath "$add_shlibpath:" ;;
+ esac
+ fi
+ if test prog = "$linkmode"; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test yes != "$hardcode_direct" &&
+ test yes != "$hardcode_minus_L" &&
+ test yes = "$hardcode_shlibpath_var"; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test prog = "$linkmode" || test relink = "$opt_mode"; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test yes = "$hardcode_direct" &&
+ test no = "$hardcode_direct_absolute"; then
+ add=$libdir/$linklib
+ elif test yes = "$hardcode_minus_L"; then
+ add_dir=-L$libdir
+ add=-l$name
+ elif test yes = "$hardcode_shlibpath_var"; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ add=-l$name
+ elif test yes = "$hardcode_automatic"; then
+ if test -n "$inst_prefix_dir" &&
+ test -f "$inst_prefix_dir$libdir/$linklib"; then
+ add=$inst_prefix_dir$libdir/$linklib
+ else
+ add=$libdir/$linklib
+ fi
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir=-L$libdir
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add=-l$name
+ fi
+
+ if test prog = "$linkmode"; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test prog = "$linkmode"; then
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test unsupported != "$hardcode_direct"; then
+ test -n "$old_library" && linklib=$old_library
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test yes = "$build_libtool_libs"; then
+ # Not a shared library
+ if test pass_all != "$deplibs_check_method"; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ echo
+ $ECHO "*** Warning: This system cannot link to static lib archive $lib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ if test yes = "$module"; then
+ echo "*** But as you try to build a module library, libtool will still create "
+ echo "*** a static module, that should work as long as the dlopening application"
+ echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** 'nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test no = "$build_old_libs"; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test lib = "$linkmode"; then
+ if test -n "$dependency_libs" &&
+ { test yes != "$hardcode_into_libs" ||
+ test yes = "$build_old_libs" ||
+ test yes = "$link_static"; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) func_stripname '-R' '' "$libdir"
+ temp_xrpath=$func_stripname_result
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) func_append xrpath " $temp_xrpath";;
+ esac;;
+ *) func_append temp_deplibs " $libdir";;
+ esac
+ done
+ dependency_libs=$temp_deplibs
+ fi
+
+ func_append newlib_search_path " $absdir"
+ # Link against this library
+ test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result";;
+ *) func_resolve_sysroot "$deplib" ;;
+ esac
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $func_resolve_sysroot_result "*)
+ func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+ esac
+ fi
+ func_append tmp_libs " $func_resolve_sysroot_result"
+ done
+
+ if test no != "$link_all_deplibs"; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ path=
+ case $deplib in
+ -L*) path=$deplib ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ deplib=$func_resolve_sysroot_result
+ func_dirname "$deplib" "" "."
+ dir=$func_dirname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ func_warning "cannot determine absolute directory name of '$dir'"
+ absdir=$dir
+ fi
+ ;;
+ esac
+ if $GREP "^installed=no" $deplib > /dev/null; then
+ case $host in
+ *-*-darwin*)
+ depdepl=
+ eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names"; then
+ for tmp in $deplibrary_names; do
+ depdepl=$tmp
+ done
+ if test -f "$absdir/$objdir/$depdepl"; then
+ depdepl=$absdir/$objdir/$depdepl
+ darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ if test -z "$darwin_install_name"; then
+ darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ fi
+ func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl"
+ func_append linker_flags " -dylib_file $darwin_install_name:$depdepl"
+ path=
+ fi
+ fi
+ ;;
+ *)
+ path=-L$absdir/$objdir
+ ;;
+ esac
+ else
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "'$deplib' is not a valid libtool archive"
+ test "$absdir" != "$libdir" && \
+ func_warning "'$deplib' seems to be moved"
+
+ path=-L$absdir
+ fi
+ ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$path $deplibs" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ if test link = "$pass"; then
+ if test prog = "$linkmode"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+ finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ fi
+ fi
+ dependency_libs=$newdependency_libs
+ if test dlpreopen = "$pass"; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test dlopen != "$pass"; then
+ test conv = "$pass" || {
+ # Make sure lib_search_path contains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) func_append lib_search_path " $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ }
+
+ if test prog,link = "$linkmode,$pass"; then
+ vars="compile_deplibs finalize_deplibs"
+ else
+ vars=deplibs
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ # FIXME: Pedantically, this is the right thing to do, so
+ # that some nasty dependency loop isn't accidentally
+ # broken:
+ #new_libs="$deplib $new_libs"
+ # Pragmatically, this seems to cause very few problems in
+ # practice:
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ -R*) ;;
+ *)
+ # And here is the reason: when a library appears more
+ # than once as an explicit dependence of a library, or
+ # is implicitly linked in more than once by the
+ # compiler, it is considered special, and multiple
+ # occurrences thereof are not removed. Compare this
+ # with having the same library being listed as a
+ # dependency of multiple other libraries: in this case,
+ # we know (pedantically, we assume) the library does not
+ # need to be listed more than once, so we keep only the
+ # last copy. This is not always right, but it is rare
+ # enough that we require users that really mean to play
+ # such unportable linking tricks to link the library
+ # using -Wl,-lname, so that libtool does not consider it
+ # for duplicate removal.
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+ # Last step: remove runtime libs from dependency_libs
+ # (they stay in deplibs)
+ tmp_libs=
+ for i in $dependency_libs; do
+ case " $predeps $postdeps $compiler_lib_search_path " in
+ *" $i "*)
+ i=
+ ;;
+ esac
+ if test -n "$i"; then
+ func_append tmp_libs " $i"
+ fi
+ done
+ dependency_libs=$tmp_libs
+ done # for pass
+ if test prog = "$linkmode"; then
+ dlfiles=$newdlfiles
+ fi
+ if test prog = "$linkmode" || test lib = "$linkmode"; then
+ dlprefiles=$newdlprefiles
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ func_warning "'-dlopen' is ignored for archives"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "'-l' and '-L' are ignored for archives" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "'-rpath' is ignored for archives"
+
+ test -n "$xrpath" && \
+ func_warning "'-R' is ignored for archives"
+
+ test -n "$vinfo" && \
+ func_warning "'-version-info/-version-number' is ignored for archives"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for archives"
+
+ test -n "$export_symbols$export_symbols_regex" && \
+ func_warning "'-export-symbols' is ignored for archives"
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs=$output
+ func_append objs "$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form 'libNAME.la'.
+ case $outputname in
+ lib*)
+ func_stripname 'lib' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ test no = "$module" \
+ && func_fatal_help "libtool library '$output' must begin with 'lib'"
+
+ if test no != "$need_lib_prefix"; then
+ # Add the "lib" prefix for modules if required
+ func_stripname '' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ else
+ func_stripname '' '.la' "$outputname"
+ libname=$func_stripname_result
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test pass_all != "$deplibs_check_method"; then
+ func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs"
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+ $ECHO "*** objects $objs is not portable!"
+ func_append libobjs " $objs"
+ fi
+ fi
+
+ test no = "$dlself" \
+ || func_warning "'-dlopen self' is ignored for libtool libraries"
+
+ set dummy $rpath
+ shift
+ test 1 -lt "$#" \
+ && func_warning "ignoring multiple '-rpath's for a libtool library"
+
+ install_libdir=$1
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test yes = "$build_libtool_libs"; then
+ # Building a libtool convenience library.
+ # Some compilers have problems with a '.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ test -n "$vinfo" && \
+ func_warning "'-version-info/-version-number' is ignored for convenience libraries"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for convenience libraries"
+ else
+
+ # Parse the version information argument.
+ save_ifs=$IFS; IFS=:
+ set dummy $vinfo 0 0 0
+ shift
+ IFS=$save_ifs
+
+ test -n "$7" && \
+ func_fatal_help "too many parameters to '-version-info'"
+
+ # convert absolute version numbers to libtool ages
+ # this retains compatibility with .la files and attempts
+ # to make the code below a bit more comprehensible
+
+ case $vinfo_number in
+ yes)
+ number_major=$1
+ number_minor=$2
+ number_revision=$3
+ #
+ # There are really only two kinds -- those that
+ # use the current revision as the major version
+ # and those that subtract age and use age as
+ # a minor version. But, then there is irix
+ # that has an extra 1 added just for fun
+ #
+ case $version_type in
+ # correct linux to gnu/linux during the next big refactor
+ darwin|linux|osf|windows|none)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age=$number_minor
+ revision=$number_revision
+ ;;
+ freebsd-aout|freebsd-elf|qnx|sunos)
+ current=$number_major
+ revision=$number_minor
+ age=0
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age=$number_minor
+ revision=$number_minor
+ lt_irix_increment=no
+ ;;
+ esac
+ ;;
+ no)
+ current=$1
+ revision=$2
+ age=$3
+ ;;
+ esac
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "CURRENT '$current' must be a nonnegative integer"
+ func_fatal_error "'$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $revision in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "REVISION '$revision' must be a nonnegative integer"
+ func_fatal_error "'$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $age in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "AGE '$age' must be a nonnegative integer"
+ func_fatal_error "'$vinfo' is not valid version information"
+ ;;
+ esac
+
+ if test "$age" -gt "$current"; then
+ func_error "AGE '$age' is greater than the current interface number '$current'"
+ func_fatal_error "'$vinfo' is not valid version information"
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=$major.$age.$revision
+ # Darwin ld doesn't like 0 for these options...
+ func_arith $current + 1
+ minor_current=$func_arith_result
+ xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ # On Darwin other compilers
+ case $CC in
+ nagfor*)
+ verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+ ;;
+ *)
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+ esac
+ ;;
+
+ freebsd-aout)
+ major=.$current
+ versuffix=.$current.$revision
+ ;;
+
+ freebsd-elf)
+ major=.$current
+ versuffix=.$current
+ ;;
+
+ irix | nonstopux)
+ if test no = "$lt_irix_increment"; then
+ func_arith $current - $age
+ else
+ func_arith $current - $age + 1
+ fi
+ major=$func_arith_result
+
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring=$verstring_prefix$major.$revision
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test 0 -ne "$loop"; do
+ func_arith $revision - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring=$verstring_prefix$major.$iface:$verstring
+ done
+
+ # Before this point, $major must not contain '.'.
+ major=.$major
+ versuffix=$major.$revision
+ ;;
+
+ linux) # correct to gnu/linux during the next big refactor
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=$major.$age.$revision
+ ;;
+
+ osf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=.$current.$age.$revision
+ verstring=$current.$age.$revision
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test 0 -ne "$loop"; do
+ func_arith $current - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring=$verstring:$iface.0
+ done
+
+ # Make executables depend on our current version.
+ func_append verstring ":$current.0"
+ ;;
+
+ qnx)
+ major=.$current
+ versuffix=.$current
+ ;;
+
+ sunos)
+ major=.$current
+ versuffix=.$current.$revision
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 file systems.
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix=-$major
+ ;;
+
+ *)
+ func_fatal_configuration "unknown library version type '$version_type'"
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=
+ ;;
+ *)
+ verstring=0.0
+ ;;
+ esac
+ if test no = "$need_version"; then
+ versuffix=
+ else
+ versuffix=.0.0
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test yes,no = "$avoid_version,$need_version"; then
+ major=
+ versuffix=
+ verstring=
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test yes = "$allow_undefined"; then
+ if test unsupported = "$allow_undefined_flag"; then
+ if test yes = "$build_old_libs"; then
+ func_warning "undefined symbols not allowed in $host shared libraries; building static only"
+ build_libtool_libs=no
+ else
+ func_fatal_error "can't build $host shared library unless -no-undefined is specified"
+ fi
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag=$no_undefined_flag
+ fi
+
+ fi
+
+ func_generate_dlsyms "$libname" "$libname" :
+ func_append libobjs " $symfileobj"
+ test " " = "$libobjs" && libobjs=
+
+ if test relink != "$opt_mode"; then
+ # Remove our outputs, but don't remove object files since they
+ # may have been created when compiling PIC objects.
+ removelist=
+ tempremovelist=`$ECHO "$output_objdir/*"`
+ for p in $tempremovelist; do
+ case $p in
+ *.$objext | *.gcno)
+ ;;
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*)
+ if test -n "$precious_files_regex"; then
+ if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+ then
+ continue
+ fi
+ fi
+ func_append removelist " $p"
+ ;;
+ *) ;;
+ esac
+ done
+ test -n "$removelist" && \
+ func_show_eval "${RM}r \$removelist"
+ fi
+
+ # Now set the variables for building old libraries.
+ if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then
+ func_append oldlibs " $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ #for path in $notinst_path; do
+ # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+ # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+ # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+ #done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ func_replace_sysroot "$libdir"
+ func_append temp_xrpath " -R$func_replace_sysroot_result"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles=$dlfiles
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) func_append dlfiles " $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles=$dlprefiles
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) func_append dlprefiles " $lib" ;;
+ esac
+ done
+
+ if test yes = "$build_libtool_libs"; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ func_append deplibs " System.ltframework"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test yes = "$build_libtool_need_lc"; then
+ func_append deplibs " -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=
+ versuffix=
+ major=
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behavior.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $opt_dry_run || $RM conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=
+ ;;
+ esac
+ fi
+ if test -n "$i"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which I believe you do not have"
+ echo "*** because a test_compile did reveal that the linker did not use it for"
+ echo "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ else
+ # Error occurred in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+ ldd_output=`ldd conftest`
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=
+ ;;
+ esac
+ fi
+ if test -n "$i"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because a test_compile did reveal that the linker did not use this one"
+ echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
+ fi
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method; shift
+ file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ if test -n "$file_magic_glob"; then
+ libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+ else
+ libnameglob=$libname
+ fi
+ test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ if test yes = "$want_nocaseglob"; then
+ shopt -s nocaseglob
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ $nocaseglob
+ else
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ fi
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null |
+ $GREP " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib=$potent_lib
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | $SED 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;;
+ *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+ $SED -e 10q |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib"; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib"; then
+ $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a file magic. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib=$potent_lib # see symlink-check above in file_magic test
+ if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+ $EGREP "$match_pattern_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib"; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib"; then
+ $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a regex pattern. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=
+ tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ for i in $predeps $postdeps; do
+ # can't use Xsed below, because $i might contain '/'
+ tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"`
+ done
+ fi
+ case $tmp_deplibs in
+ *[!\ \ ]*)
+ echo
+ if test none = "$deplibs_check_method"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ ;;
+ esac
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library with the System framework
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ if test yes = "$droppeddeps"; then
+ if test yes = "$module"; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ $ECHO "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** 'nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test no = "$build_old_libs"; then
+ oldlibs=$output_objdir/$libname.$libext
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+
+ if test no = "$allow_undefined"; then
+ echo
+ echo "*** Since this library must not contain undefined symbols,"
+ echo "*** because either the platform does not support them or"
+ echo "*** it was explicitly requested with -no-undefined,"
+ echo "*** libtool will only create a static version of it."
+ if test no = "$build_old_libs"; then
+ oldlibs=$output_objdir/$libname.$libext
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ case $host in
+ *-*-darwin*)
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ deplibs=$new_libs
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test yes = "$build_libtool_libs"; then
+ # Remove $wl instances when linking with ld.
+ # FIXME: should test the right _cmds variable.
+ case $archive_cmds in
+ *\$LD\ *) wl= ;;
+ esac
+ if test yes = "$hardcode_into_libs"; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath=$finalize_rpath
+ test relink = "$opt_mode" || rpath=$compile_rpath$rpath
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ func_replace_sysroot "$libdir"
+ libdir=$func_replace_sysroot_result
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs=$libdir
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append dep_rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir=$hardcode_libdirs
+ eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath=$finalize_shlibpath
+ test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval shared_ext=\"$shrext_cmds\"
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ shift
+ realname=$1
+ shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname=$realname
+ fi
+ if test -z "$dlname"; then
+ dlname=$soname
+ fi
+
+ lib=$output_objdir/$realname
+ linknames=
+ for link
+ do
+ func_append linknames " $link"
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ test "X$libobjs" = "X " && libobjs=
+
+ delfiles=
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+ export_symbols=$output_objdir/$libname.uexp
+ func_append delfiles " $export_symbols"
+ fi
+
+ orig_export_symbols=
+ case $host_os in
+ cygwin* | mingw* | cegcc*)
+ if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+ # exporting using user supplied symfile
+ func_dll_def_p "$export_symbols" || {
+ # and it's NOT already a .def file. Must figure out
+ # which of the given symbols are data symbols and tag
+ # them as such. So, trigger use of export_symbols_cmds.
+ # export_symbols gets reassigned inside the "prepare
+ # the list of exported symbols" if statement, so the
+ # include_expsyms logic still works.
+ orig_export_symbols=$export_symbols
+ export_symbols=
+ always_export_symbols=yes
+ }
+ fi
+ ;;
+ esac
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then
+ func_verbose "generating symbol list for '$libname.la'"
+ export_symbols=$output_objdir/$libname.exp
+ $opt_dry_run || $RM $export_symbols
+ cmds=$export_symbols_cmds
+ save_ifs=$IFS; IFS='~'
+ for cmd1 in $cmds; do
+ IFS=$save_ifs
+ # Take the normal branch if the nm_file_list_spec branch
+ # doesn't work or if tool conversion is not needed.
+ case $nm_file_list_spec~$to_tool_file_cmd in
+ *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+ try_normal_branch=yes
+ eval cmd=\"$cmd1\"
+ func_len " $cmd"
+ len=$func_len_result
+ ;;
+ *)
+ try_normal_branch=no
+ ;;
+ esac
+ if test yes = "$try_normal_branch" \
+ && { test "$len" -lt "$max_cmd_len" \
+ || test "$max_cmd_len" -le -1; }
+ then
+ func_show_eval "$cmd" 'exit $?'
+ skipped_export=false
+ elif test -n "$nm_file_list_spec"; then
+ func_basename "$output"
+ output_la=$func_basename_result
+ save_libobjs=$libobjs
+ save_output=$output
+ output=$output_objdir/$output_la.nm
+ func_to_tool_file "$output"
+ libobjs=$nm_file_list_spec$func_to_tool_file_result
+ func_append delfiles " $output"
+ func_verbose "creating $NM input file list: $output"
+ for obj in $save_libobjs; do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > "$output"
+ eval cmd=\"$cmd1\"
+ func_show_eval "$cmd" 'exit $?'
+ output=$save_output
+ libobjs=$save_libobjs
+ skipped_export=false
+ else
+ # The command line is too long to execute in one step.
+ func_verbose "using reloadable object file for export list..."
+ skipped_export=:
+ # Break out early, otherwise skipped_export may be
+ # set to false by a later but shorter cmd.
+ break
+ fi
+ done
+ IFS=$save_ifs
+ if test -n "$export_symbols_regex" && test : != "$skipped_export"; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols=$export_symbols
+ test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test : != "$skipped_export" && test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands, which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+
+ tmp_deplibs=
+ for test_deplib in $deplibs; do
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ func_append tmp_deplibs " $test_deplib"
+ ;;
+ esac
+ done
+ deplibs=$tmp_deplibs
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec" &&
+ test yes = "$compiler_needs_object" &&
+ test -z "$libobjs"; then
+ # extract the archives, so we have objects to list.
+ # TODO: could optimize this to just extract one archive.
+ whole_archive_flag_spec=
+ fi
+ if test -n "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ else
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ fi
+
+ if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ func_append linker_flags " $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test relink = "$opt_mode"; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+ fi
+
+ # Do each of the archive commands.
+ if test yes = "$module" && test -n "$module_cmds"; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ eval test_cmds=\"$module_expsym_cmds\"
+ cmds=$module_expsym_cmds
+ else
+ eval test_cmds=\"$module_cmds\"
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval test_cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
+ else
+ eval test_cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
+ fi
+ fi
+
+ if test : != "$skipped_export" &&
+ func_len " $test_cmds" &&
+ len=$func_len_result &&
+ test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # The command line is too long to link in one step, link piecewise
+ # or, if using GNU ld and skipped_export is not :, use a linker
+ # script.
+
+ # Save the value of $output and $libobjs because we want to
+ # use them later. If we have whole_archive_flag_spec, we
+ # want to use save_libobjs as it was before
+ # whole_archive_flag_spec was expanded, because we can't
+ # assume the linker understands whole_archive_flag_spec.
+ # This may have to be revisited, in case too many
+ # convenience libraries get linked in and end up exceeding
+ # the spec.
+ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ fi
+ save_output=$output
+ func_basename "$output"
+ output_la=$func_basename_result
+
+ # Clear the reloadable object creation command queue and
+ # initialize k to one.
+ test_cmds=
+ concat_cmds=
+ objlist=
+ last_robj=
+ k=1
+
+ if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then
+ output=$output_objdir/$output_la.lnkscript
+ func_verbose "creating GNU ld script: $output"
+ echo 'INPUT (' > $output
+ for obj in $save_libobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ echo ')' >> $output
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$func_to_tool_file_result
+ elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then
+ output=$output_objdir/$output_la.lnk
+ func_verbose "creating linker input file list: $output"
+ : > $output
+ set x $save_libobjs
+ shift
+ firstobj=
+ if test yes = "$compiler_needs_object"; then
+ firstobj="$1 "
+ shift
+ fi
+ for obj
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+ else
+ if test -n "$save_libobjs"; then
+ func_verbose "creating reloadable object files..."
+ output=$output_objdir/$output_la-$k.$objext
+ eval test_cmds=\"$reload_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+
+ # Loop over the list of objects to be linked.
+ for obj in $save_libobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ if test -z "$objlist" ||
+ test "$len" -lt "$max_cmd_len"; then
+ func_append objlist " $obj"
+ else
+ # The command $test_cmds is almost too long, add a
+ # command to the queue.
+ if test 1 -eq "$k"; then
+ # The first file doesn't have a previous command to add.
+ reload_objs=$objlist
+ eval concat_cmds=\"$reload_cmds\"
+ else
+ # All subsequent reloadable object files will link in
+ # the last one created.
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+ fi
+ last_robj=$output_objdir/$output_la-$k.$objext
+ func_arith $k + 1
+ k=$func_arith_result
+ output=$output_objdir/$output_la-$k.$objext
+ objlist=" $obj"
+ func_len " $last_robj"
+ func_arith $len0 + $func_len_result
+ len=$func_arith_result
+ fi
+ done
+ # Handle the remaining objects by creating one last
+ # reloadable object file. All subsequent reloadable object
+ # files will link in the last one created.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds$reload_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ func_append delfiles " $output"
+
+ else
+ output=
+ fi
+
+ ${skipped_export-false} && {
+ func_verbose "generating symbol list for '$libname.la'"
+ export_symbols=$output_objdir/$libname.exp
+ $opt_dry_run || $RM $export_symbols
+ libobjs=$output
+ # Append the command to create the export file.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ }
+
+ test -n "$save_libobjs" &&
+ func_verbose "creating a temporary reloadable object file: $output"
+
+ # Loop through the commands generated above and execute them.
+ save_ifs=$IFS; IFS='~'
+ for cmd in $concat_cmds; do
+ IFS=$save_ifs
+ $opt_quiet || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test relink = "$opt_mode"; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS=$save_ifs
+
+ if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+
+ ${skipped_export-false} && {
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols=$export_symbols
+ test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands, which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+ }
+
+ libobjs=$output
+ # Restore the value of output.
+ output=$save_output
+
+ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ # Expand the library linking commands again to reset the
+ # value of $libobjs for piecewise linking.
+
+ # Do each of the archive commands.
+ if test yes = "$module" && test -n "$module_cmds"; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ cmds=$module_expsym_cmds
+ else
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ cmds=$archive_expsym_cmds
+ else
+ cmds=$archive_cmds
+ fi
+ fi
+ fi
+
+ if test -n "$delfiles"; then
+ # Append the command to remove temporary files to $cmds.
+ eval cmds=\"\$cmds~\$RM $delfiles\"
+ fi
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+
+ save_ifs=$IFS; IFS='~'
+ for cmd in $cmds; do
+ IFS=$sp$nl
+ eval cmd=\"$cmd\"
+ IFS=$save_ifs
+ $opt_quiet || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test relink = "$opt_mode"; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS=$save_ifs
+
+ # Restore the uninstalled library and exit
+ if test relink = "$opt_mode"; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+ if test -n "$convenience"; then
+ if test -z "$whole_archive_flag_spec"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test yes = "$module" || test yes = "$export_dynamic"; then
+ # On all known operating systems, these are identical.
+ dlname=$soname
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ func_warning "'-dlopen' is ignored for objects"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "'-l' and '-L' are ignored for objects" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "'-rpath' is ignored for objects"
+
+ test -n "$xrpath" && \
+ func_warning "'-R' is ignored for objects"
+
+ test -n "$vinfo" && \
+ func_warning "'-version-info' is ignored for objects"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for objects"
+
+ case $output in
+ *.lo)
+ test -n "$objs$old_deplibs" && \
+ func_fatal_error "cannot build library object '$output' from non-libtool objects"
+
+ libobj=$output
+ func_lo2o "$libobj"
+ obj=$func_lo2o_result
+ ;;
+ *)
+ libobj=
+ obj=$output
+ ;;
+ esac
+
+ # Delete the old objects.
+ $opt_dry_run || $RM $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # if reload_cmds runs $LD directly, get rid of -Wl from
+ # whole_archive_flag_spec and hope we can get by with turning comma
+ # into space.
+ case $reload_cmds in
+ *\$LD[\ \$]*) wl= ;;
+ esac
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+ test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+ reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags
+ else
+ gentop=$output_objdir/${obj}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ reload_conv_objs="$reload_objs $func_extract_archives_result"
+ fi
+ fi
+
+ # If we're not building shared, we need to use non_pic_objs
+ test yes = "$build_libtool_libs" || libobjs=$non_pic_objects
+
+ # Create the old-style object.
+ reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs
+
+ output=$obj
+ func_execute_cmds "$reload_cmds" 'exit $?'
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ test yes = "$build_libtool_libs" || {
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ # $show "echo timestamp > $libobj"
+ # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+ exit $EXIT_SUCCESS
+ }
+
+ if test -n "$pic_flag" || test default != "$pic_mode"; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output=$libobj
+ func_execute_cmds "$reload_cmds" 'exit $?'
+ fi
+
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result.exe;;
+ esac
+ test -n "$vinfo" && \
+ func_warning "'-version-info' is ignored for programs"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for programs"
+
+ $preload \
+ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \
+ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ case $host in
+ *-*-darwin*)
+ # Don't allow lazy linking, it breaks C++ global constructors
+ # But is supposedly fixed on 10.4 or later (yay!).
+ if test CXX = "$tagname"; then
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 10.[0123])
+ func_append compile_command " $wl-bind_at_load"
+ func_append finalize_command " $wl-bind_at_load"
+ ;;
+ esac
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $compile_deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $compile_deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ compile_deplibs=$new_libs
+
+
+ func_append compile_command " $compile_deplibs"
+ func_append finalize_command " $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs=$libdir
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ ::) dllsearchpath=$libdir;;
+ *) func_append dllsearchpath ":$libdir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir=$hardcode_libdirs
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath=$rpath
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs=$libdir
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir=$hardcode_libdirs
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath=$rpath
+
+ if test -n "$libobjs" && test yes = "$build_old_libs"; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ fi
+
+ func_generate_dlsyms "$outputname" "@PROGRAM@" false
+
+ # template prelinking step
+ if test -n "$prelink_cmds"; then
+ func_execute_cmds "$prelink_cmds" 'exit $?'
+ fi
+
+ wrappers_required=:
+ case $host in
+ *cegcc* | *mingw32ce*)
+ # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+ wrappers_required=false
+ ;;
+ *cygwin* | *mingw* )
+ test yes = "$build_libtool_libs" || wrappers_required=false
+ ;;
+ *)
+ if test no = "$need_relink" || test yes != "$build_libtool_libs"; then
+ wrappers_required=false
+ fi
+ ;;
+ esac
+ $wrappers_required || {
+ # Replace the output file specification.
+ compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ link_command=$compile_command$compile_rpath
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ exit_status=0
+ func_show_eval "$link_command" 'exit_status=$?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Delete the generated files.
+ if test -f "$output_objdir/${outputname}S.$objext"; then
+ func_show_eval '$RM "$output_objdir/${outputname}S.$objext"'
+ fi
+
+ exit $exit_status
+ }
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test yes = "$no_install"; then
+ # We don't need to create a wrapper script.
+ link_command=$compile_var$compile_command$compile_rpath
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $opt_dry_run || $RM $output
+ # Link the executable and exit
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ case $hardcode_action,$fast_install in
+ relink,*)
+ # Fast installation is not supported
+ link_command=$compile_var$compile_command$compile_rpath
+ relink_command=$finalize_var$finalize_command$finalize_rpath
+
+ func_warning "this platform does not like uninstalled shared libraries"
+ func_warning "'$output' will be relinked during installation"
+ ;;
+ *,yes)
+ link_command=$finalize_var$compile_command$finalize_rpath
+ relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+ ;;
+ *,no)
+ link_command=$compile_var$compile_command$compile_rpath
+ relink_command=$finalize_var$finalize_command$finalize_rpath
+ ;;
+ *,needless)
+ link_command=$finalize_var$compile_command$finalize_rpath
+ relink_command=
+ ;;
+ esac
+
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output_objdir/$outputname"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Now create the wrapper script.
+ func_verbose "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if not in dry run mode.
+ $opt_dry_run || {
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*)
+ exeext=.exe
+ func_stripname '' '.exe' "$outputname"
+ outputname=$func_stripname_result ;;
+ *) exeext= ;;
+ esac
+ case $host in
+ *cygwin* | *mingw* )
+ func_dirname_and_basename "$output" "" "."
+ output_name=$func_basename_result
+ output_path=$func_dirname_result
+ cwrappersource=$output_path/$objdir/lt-$output_name.c
+ cwrapper=$output_path/$output_name.exe
+ $RM $cwrappersource $cwrapper
+ trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_cwrapperexe_src > $cwrappersource
+
+ # The wrapper executable is built using the $host compiler,
+ # because it contains $host paths and files. If cross-
+ # compiling, it, like the target executable, must be
+ # executed on the $host or under an emulation environment.
+ $opt_dry_run || {
+ $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+ $STRIP $cwrapper
+ }
+
+ # Now, create the wrapper script for func_source use:
+ func_ltwrapper_scriptname $cwrapper
+ $RM $func_ltwrapper_scriptname_result
+ trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+ $opt_dry_run || {
+ # note: this script will not be executed, so do not chmod.
+ if test "x$build" = "x$host"; then
+ $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+ else
+ func_emit_wrapper no > $func_ltwrapper_scriptname_result
+ fi
+ }
+ ;;
+ * )
+ $RM $output
+ trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_wrapper no > $output
+ chmod +x $output
+ ;;
+ esac
+ }
+ exit $EXIT_SUCCESS
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ case $build_libtool_libs in
+ convenience)
+ oldobjs="$libobjs_save $symfileobj"
+ addlibs=$convenience
+ build_libtool_libs=no
+ ;;
+ module)
+ oldobjs=$libobjs_save
+ addlibs=$old_convenience
+ build_libtool_libs=no
+ ;;
+ *)
+ oldobjs="$old_deplibs $non_pic_objects"
+ $preload && test -f "$symfileobj" \
+ && func_append oldobjs " $symfileobj"
+ addlibs=$old_convenience
+ ;;
+ esac
+
+ if test -n "$addlibs"; then
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $addlibs
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then
+ cmds=$old_archive_from_new_cmds
+ else
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # POSIX demands no paths to be encoded in archives. We have
+ # to avoid creating archives with duplicate basenames if we
+ # might have to extract them afterwards, e.g., when creating a
+ # static archive out of a convenience library, or when linking
+ # the entirety of a libtool archive into another (currently
+ # not supported by libtool).
+ if (for obj in $oldobjs
+ do
+ func_basename "$obj"
+ $ECHO "$func_basename_result"
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ echo "copying selected object files to avoid basename conflicts..."
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+ func_mkdir_p "$gentop"
+ save_oldobjs=$oldobjs
+ oldobjs=
+ counter=1
+ for obj in $save_oldobjs
+ do
+ func_basename "$obj"
+ objbase=$func_basename_result
+ case " $oldobjs " in
+ " ") oldobjs=$obj ;;
+ *[\ /]"$objbase "*)
+ while :; do
+ # Make sure we don't pick an alternate name that also
+ # overlaps.
+ newobj=lt$counter-$objbase
+ func_arith $counter + 1
+ counter=$func_arith_result
+ case " $oldobjs " in
+ *[\ /]"$newobj "*) ;;
+ *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+ esac
+ done
+ func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+ func_append oldobjs " $gentop/$newobj"
+ ;;
+ *) func_append oldobjs " $obj" ;;
+ esac
+ done
+ fi
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+ eval cmds=\"$old_archive_cmds\"
+
+ func_len " $cmds"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ cmds=$old_archive_cmds
+ elif test -n "$archiver_list_spec"; then
+ func_verbose "using command file archive linking..."
+ for obj in $oldobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > $output_objdir/$libname.libcmd
+ func_to_tool_file "$output_objdir/$libname.libcmd"
+ oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+ cmds=$old_archive_cmds
+ else
+ # the command line is too long to link in one step, link in parts
+ func_verbose "using piecewise archive linking..."
+ save_RANLIB=$RANLIB
+ RANLIB=:
+ objlist=
+ concat_cmds=
+ save_oldobjs=$oldobjs
+ oldobjs=
+ # Is there a better way of finding the last object in the list?
+ for obj in $save_oldobjs
+ do
+ last_oldobj=$obj
+ done
+ eval test_cmds=\"$old_archive_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+ for obj in $save_oldobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ func_append objlist " $obj"
+ if test "$len" -lt "$max_cmd_len"; then
+ :
+ else
+ # the above command should be used before it gets too long
+ oldobjs=$objlist
+ if test "$obj" = "$last_oldobj"; then
+ RANLIB=$save_RANLIB
+ fi
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\"
+ objlist=
+ len=$len0
+ fi
+ done
+ RANLIB=$save_RANLIB
+ oldobjs=$objlist
+ if test -z "$oldobjs"; then
+ eval cmds=\"\$concat_cmds\"
+ else
+ eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+ fi
+ fi
+ fi
+ func_execute_cmds "$cmds" 'exit $?'
+ done
+
+ test -n "$generated" && \
+ func_show_eval "${RM}r$generated"
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test yes = "$build_old_libs" && old_library=$libname.$libext
+ func_verbose "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ if test yes = "$hardcode_automatic"; then
+ relink_command=
+ fi
+
+ # Only create the output if not a dry run.
+ $opt_dry_run || {
+ for installed in no yes; do
+ if test yes = "$installed"; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output=$output_objdir/${outputname}i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ func_basename "$deplib"
+ name=$func_basename_result
+ func_resolve_sysroot "$deplib"
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+ test -z "$libdir" && \
+ func_fatal_error "'$deplib' is not a valid libtool archive"
+ func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ -L*)
+ func_stripname -L '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -L$func_replace_sysroot_result"
+ ;;
+ -R*)
+ func_stripname -R '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -R$func_replace_sysroot_result"
+ ;;
+ *) func_append newdependency_libs " $deplib" ;;
+ esac
+ done
+ dependency_libs=$newdependency_libs
+ newdlfiles=
+
+ for lib in $dlfiles; do
+ case $lib in
+ *.la)
+ func_basename "$lib"
+ name=$func_basename_result
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "'$lib' is not a valid libtool archive"
+ func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ *) func_append newdlfiles " $lib" ;;
+ esac
+ done
+ dlfiles=$newdlfiles
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ *.la)
+ # Only pass preopened files to the pseudo-archive (for
+ # eventual linking with the app. that links it) if we
+ # didn't already link the preopened objects directly into
+ # the library:
+ func_basename "$lib"
+ name=$func_basename_result
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "'$lib' is not a valid libtool archive"
+ func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ esac
+ done
+ dlprefiles=$newdlprefiles
+ else
+ newdlfiles=
+ for lib in $dlfiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlfiles " $abs"
+ done
+ dlfiles=$newdlfiles
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlprefiles " $abs"
+ done
+ dlprefiles=$newdlprefiles
+ fi
+ $RM $output
+ # place dlname in correct position for cygwin
+ # In fact, it would be nice if we could use this code for all target
+ # systems that can't hard-code library paths into their executables
+ # and that have no shared library path variable independent of PATH,
+ # but it turns out we can't easily determine that from inspecting
+ # libtool variables, so we have to hard-code the OSs to which it
+ # applies here; at the moment, that means platforms that use the PE
+ # object format with DLL files. See the long comment at the top of
+ # tests/bindir.at for full details.
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+ # If a -bindir argument was supplied, place the dll there.
+ if test -n "$bindir"; then
+ func_relative_path "$install_libdir" "$bindir"
+ tdlname=$func_relative_path_result/$dlname
+ else
+ # Otherwise fall back on heuristic.
+ tdlname=../bin/$dlname
+ fi
+ ;;
+ esac
+ $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that cannot go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test no,yes = "$installed,$need_relink"; then
+ $ECHO >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ }
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+ ;;
+ esac
+ exit $EXIT_SUCCESS
+}
+
+if test link = "$opt_mode" || test relink = "$opt_mode"; then
+ func_mode_link ${1+"$@"}
+fi
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+ $debug_cmd
+
+ RM=$nonopt
+ files=
+ rmforce=false
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic=$magic
+
+ for arg
+ do
+ case $arg in
+ -f) func_append RM " $arg"; rmforce=: ;;
+ -*) func_append RM " $arg" ;;
+ *) func_append files " $arg" ;;
+ esac
+ done
+
+ test -z "$RM" && \
+ func_fatal_help "you must specify an RM program"
+
+ rmdirs=
+
+ for file in $files; do
+ func_dirname "$file" "" "."
+ dir=$func_dirname_result
+ if test . = "$dir"; then
+ odir=$objdir
+ else
+ odir=$dir/$objdir
+ fi
+ func_basename "$file"
+ name=$func_basename_result
+ test uninstall = "$opt_mode" && odir=$dir
+
+ # Remember odir for removal later, being careful to avoid duplicates
+ if test clean = "$opt_mode"; then
+ case " $rmdirs " in
+ *" $odir "*) ;;
+ *) func_append rmdirs " $odir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if { test -L "$file"; } >/dev/null 2>&1 ||
+ { test -h "$file"; } >/dev/null 2>&1 ||
+ test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif $rmforce; then
+ continue
+ fi
+
+ rmfiles=$file
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if func_lalib_p "$file"; then
+ func_source $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ func_append rmfiles " $odir/$n"
+ done
+ test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+ case $opt_mode in
+ clean)
+ case " $library_names " in
+ *" $dlname "*) ;;
+ *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+ esac
+ test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+ ;;
+ uninstall)
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1'
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1'
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ ;;
+ esac
+ fi
+ ;;
+
+ *.lo)
+ # Possibly a libtool object, so verify it.
+ if func_lalib_p "$file"; then
+
+ # Read the .lo file
+ func_source $dir/$name
+
+ # Add PIC object to the list of files to remove.
+ if test -n "$pic_object" && test none != "$pic_object"; then
+ func_append rmfiles " $dir/$pic_object"
+ fi
+
+ # Add non-PIC object to the list of files to remove.
+ if test -n "$non_pic_object" && test none != "$non_pic_object"; then
+ func_append rmfiles " $dir/$non_pic_object"
+ fi
+ fi
+ ;;
+
+ *)
+ if test clean = "$opt_mode"; then
+ noexename=$name
+ case $file in
+ *.exe)
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ func_stripname '' '.exe' "$name"
+ noexename=$func_stripname_result
+ # $file with .exe has already been added to rmfiles,
+ # add $file without .exe
+ func_append rmfiles " $file"
+ ;;
+ esac
+ # Do a test to see if this is a libtool program.
+ if func_ltwrapper_p "$file"; then
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ relink_command=
+ func_source $func_ltwrapper_scriptname_result
+ func_append rmfiles " $func_ltwrapper_scriptname_result"
+ else
+ relink_command=
+ func_source $dir/$noexename
+ fi
+
+ # note $name still contains .exe if it was in $file originally
+ # as does the version of $file that was added into $rmfiles
+ func_append rmfiles " $odir/$name $odir/${name}S.$objext"
+ if test yes = "$fast_install" && test -n "$relink_command"; then
+ func_append rmfiles " $odir/lt-$name"
+ fi
+ if test "X$noexename" != "X$name"; then
+ func_append rmfiles " $odir/lt-$noexename.c"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ func_show_eval "$RM $rmfiles" 'exit_status=1'
+ done
+
+ # Try to remove the $objdir's in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ func_show_eval "rmdir $dir >/dev/null 2>&1"
+ fi
+ done
+
+ exit $exit_status
+}
+
+if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then
+ func_mode_uninstall ${1+"$@"}
+fi
+
+test -z "$opt_mode" && {
+ help=$generic_help
+ func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+ func_fatal_help "invalid operation mode '$opt_mode'"
+
+if test -n "$exec_cmd"; then
+ eval exec "$exec_cmd"
+ exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# where we disable both kinds of libraries. Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them. This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration. But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/extension/build-aux/missing b/extension/build-aux/missing
new file mode 100755
index 00000000..cdea5149
--- /dev/null
+++ b/extension/build-aux/missing
@@ -0,0 +1,215 @@
+#! /bin/sh
+# Common wrapper for a few potentially missing GNU programs.
+
+scriptversion=2012-06-26.16; # UTC
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Originally written 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, see <http://www.gnu.org/licenses/>.
+
+# 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
+
+case $1 in
+
+ --is-lightweight)
+ # Used by our autoconf macros to check whether the available missing
+ # script is modern enough.
+ exit 0
+ ;;
+
+ --run)
+ # Back-compat with the calling convention used by older automake.
+ shift
+ ;;
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
+to PROGRAM being missing or too old.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+
+Supported PROGRAM values:
+ aclocal autoconf autoheader autom4te automake makeinfo
+ bison yacc flex lex help2man
+
+Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
+'g' are ignored when checking the name.
+
+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
+
+# Run the given program, remember its exit status.
+"$@"; st=$?
+
+# If it succeeded, we are done.
+test $st -eq 0 && exit 0
+
+# Also exit now if we it failed (or wasn't found), and '--version' was
+# passed; such an option is passed most likely to detect whether the
+# program is present and works.
+case $2 in --version|--help) exit $st;; esac
+
+# Exit code 63 means version mismatch. This often happens when the user
+# tries to use an ancient version of a tool on a file that requires a
+# minimum version.
+if test $st -eq 63; then
+ msg="probably too old"
+elif test $st -eq 127; then
+ # Program was missing.
+ msg="missing on your system"
+else
+ # Program was found and executed, but failed. Give up.
+ exit $st
+fi
+
+perl_URL=http://www.perl.org/
+flex_URL=http://flex.sourceforge.net/
+gnu_software_URL=http://www.gnu.org/software
+
+program_details ()
+{
+ case $1 in
+ aclocal|automake)
+ echo "The '$1' program is part of the GNU Automake package:"
+ echo "<$gnu_software_URL/automake>"
+ echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/autoconf>"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ autoconf|autom4te|autoheader)
+ echo "The '$1' program is part of the GNU Autoconf package:"
+ echo "<$gnu_software_URL/autoconf/>"
+ echo "It also requires GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ esac
+}
+
+give_advice ()
+{
+ # Normalize program name to check for.
+ normalized_program=`echo "$1" | sed '
+ s/^gnu-//; t
+ s/^gnu//; t
+ s/^g//; t'`
+
+ printf '%s\n' "'$1' is $msg."
+
+ configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
+ case $normalized_program in
+ autoconf*)
+ echo "You should only need it if you modified 'configure.ac',"
+ echo "or m4 files included by it."
+ program_details 'autoconf'
+ ;;
+ autoheader*)
+ echo "You should only need it if you modified 'acconfig.h' or"
+ echo "$configure_deps."
+ program_details 'autoheader'
+ ;;
+ automake*)
+ echo "You should only need it if you modified 'Makefile.am' or"
+ echo "$configure_deps."
+ program_details 'automake'
+ ;;
+ aclocal*)
+ echo "You should only need it if you modified 'acinclude.m4' or"
+ echo "$configure_deps."
+ program_details 'aclocal'
+ ;;
+ autom4te*)
+ echo "You might have modified some maintainer files that require"
+ echo "the 'automa4te' program to be rebuilt."
+ program_details 'autom4te'
+ ;;
+ bison*|yacc*)
+ echo "You should only need it if you modified a '.y' file."
+ echo "You may want to install the GNU Bison package:"
+ echo "<$gnu_software_URL/bison/>"
+ ;;
+ lex*|flex*)
+ echo "You should only need it if you modified a '.l' file."
+ echo "You may want to install the Fast Lexical Analyzer package:"
+ echo "<$flex_URL>"
+ ;;
+ help2man*)
+ echo "You should only need it if you modified a dependency" \
+ "of a man page."
+ echo "You may want to install the GNU Help2man package:"
+ echo "<$gnu_software_URL/help2man/>"
+ ;;
+ makeinfo*)
+ echo "You should only need it if you modified a '.texi' file, or"
+ echo "any other file indirectly affecting the aspect of the manual."
+ echo "You might want to install the Texinfo package:"
+ echo "<$gnu_software_URL/texinfo/>"
+ echo "The spurious makeinfo call might also be the consequence of"
+ echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
+ echo "want to install GNU make:"
+ echo "<$gnu_software_URL/make/>"
+ ;;
+ *)
+ echo "You might have modified some files without having the proper"
+ echo "tools for further handling them. Check the 'README' file, it"
+ echo "often tells you about the needed prerequisites for installing"
+ echo "this package. You may also peek at any GNU archive site, in"
+ echo "case some other package contains this missing '$1' program."
+ ;;
+ esac
+}
+
+give_advice "$1" | sed -e '1s/^/WARNING: /' \
+ -e '2,$s/^/ /' >&2
+
+# Propagate the correct exit status (expected to be 127 for a program
+# not found, 63 for a program that failed due to version mismatch).
+exit $st
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/extension/configh.in b/extension/configh.in
new file mode 100644
index 00000000..5842f2f4
--- /dev/null
+++ b/extension/configh.in
@@ -0,0 +1,214 @@
+/* configh.in. Generated from configure.ac by autoheader. */
+
+/* the name of the file descriptor member of DIR */
+#undef DIR_FD_MEMBER_NAME
+
+#ifdef DIR_FD_MEMBER_NAME
+# define DIR_TO_FD(Dir_p) ((Dir_p)->DIR_FD_MEMBER_NAME)
+#else
+# define DIR_TO_FD(Dir_p) -1
+#endif
+
+
+/* Define to 1 if translation of program messages to the user's native
+ language is requested. */
+#undef ENABLE_NLS
+
+/* 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 have the declaration of `dirfd', and to 0 if you don't.
+ */
+#undef HAVE_DECL_DIRFD
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the `dirfd' function. */
+#undef HAVE_DIRFD
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the `fdopendir' function. */
+#undef HAVE_FDOPENDIR
+
+/* Define to 1 if you have the `fnmatch' function. */
+#undef HAVE_FNMATCH
+
+/* Define to 1 if you have the <fnmatch.h> header file. */
+#undef HAVE_FNMATCH_H
+
+/* Define to 1 if you have the `getdtablesize' function. */
+#undef HAVE_GETDTABLESIZE
+
+/* Define to 1 if you have the `GetSystemTimeAsFileTime' function. */
+#undef HAVE_GETSYSTEMTIMEASFILETIME
+
+/* Define if the GNU gettext() function is already present or preinstalled. */
+#undef HAVE_GETTEXT
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define if you have the iconv() function and it works. */
+#undef HAVE_ICONV
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `nanosleep' function. */
+#undef HAVE_NANOSLEEP
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if you have the `select' function. */
+#undef HAVE_SELECT
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* 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 `st_blksize' is a member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_BLKSIZE
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_NDIR_H
+
+/* 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/select.h> header file. */
+#undef HAVE_SYS_SELECT_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 the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#undef LT_OBJDIR
+
+/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
+ */
+#undef MAJOR_IN_MKDEV
+
+/* Define to 1 if `major', `minor', and `makedev' are declared in
+ <sysmacros.h>. */
+#undef MAJOR_IN_SYSMACROS
+
+/* 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 home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Version number of package */
+#undef VERSION
+
+/* Enable large inode numbers on Mac OS X 10.5. */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#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 `__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
diff --git a/extension/configure b/extension/configure
new file mode 100755
index 00000000..7ee9c0df
--- /dev/null
+++ b/extension/configure
@@ -0,0 +1,17003 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for GNU Awk Bundled Extensions 4.1.1.
+#
+# Report bugs to <bug-gawk@gnu.org>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 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 more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+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
+IFS=$as_save_IFS
+
+ ;;
+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
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1
+
+ test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org and bug-gawk@gnu.org
+$0: about your system, including any error possibly output
+$0: before this message. Then install a modern shell, or
+$0: manually run the script under such a shell if you do
+$0: have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; 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
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# 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
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
+ # 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 sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='GNU Awk Bundled Extensions'
+PACKAGE_TARNAME='gawk-extensions'
+PACKAGE_VERSION='4.1.1'
+PACKAGE_STRING='GNU Awk Bundled Extensions 4.1.1'
+PACKAGE_BUGREPORT='bug-gawk@gnu.org'
+PACKAGE_URL='http://www.gnu.org/software/gawk-extensions/'
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+gt_needs=
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+pkgextensiondir
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+DLLTOOL
+OBJDUMP
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+SED
+LIBTOOL
+ac_ct_AR
+AR
+POSUB
+LTLIBINTL
+LIBINTL
+INTLLIBS
+LTLIBICONV
+LIBICONV
+INTL_MACOSX_LIBS
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+XGETTEXT_EXTRA_OPTIONS
+MSGMERGE
+XGETTEXT_015
+XGETTEXT
+GMSGFMT_015
+MSGFMT_015
+GMSGFMT
+MSGFMT
+GETTEXT_MACRO_VERSION
+USE_NLS
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+EGREP
+GREP
+CPP
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_dependency_tracking
+enable_silent_rules
+enable_nls
+with_gnu_ld
+enable_rpath
+with_libiconv_prefix
+with_libintl_prefix
+enable_largefile
+enable_static
+enable_shared
+with_pic
+enable_fast_install
+with_sysroot
+enable_libtool_lock
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# 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.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+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
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -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)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$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 ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$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 ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ 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 ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$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_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=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 ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_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'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+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
+ 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
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# 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 the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ 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
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# 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 Bundled Extensions 4.1.1 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 \`..']
+
+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]
+ --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]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/gawk-extensions]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_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 Bundled Extensions 4.1.1:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-dependency-tracking
+ do not reject slow dependency extractors
+ --disable-dependency-tracking
+ speeds up one-time build
+ --enable-silent-rules less verbose build output (undo: "make V=1")
+ --disable-silent-rules verbose build output (undo: "make V=0")
+ --disable-nls do not use Native Language Support
+ --disable-rpath do not hardcode runtime library paths
+ --disable-largefile omit support for large files
+ --enable-static[=PKGS] build static libraries [default=no]
+ --enable-shared[=PKGS] build shared libraries [default=yes]
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=yes]
+ --disable-libtool-lock avoid locking (might break parallel builds)
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --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
+ --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
+ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the
+ compiler's sysroot if not specified).
+
+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>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) 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>.
+GNU Awk Bundled Extensions home page: <http://www.gnu.org/software/gawk-extensions/>.
+General help using GNU software: <http://www.gnu.org/gethelp/>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested 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
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+GNU Awk Bundled Extensions configure 4.1.1
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 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
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## ------------------------------- ##
+## Report this to bug-gawk@gnu.org ##
+## ------------------------------- ##"
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
+# ----------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_c_check_member ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+$as_echo_n "checking for $2.$3... " >&6; }
+if eval \${$4+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ eval "$4=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$4
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_member
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); 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 $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* 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_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
+# ---------------------------------------------
+# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
+# accordingly.
+ac_fn_c_check_decl ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ as_decl_name=`echo $2|sed 's/ *(.*//'`
+ as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
+$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+#ifndef $as_decl_name
+#ifdef __cplusplus
+ (void) $as_decl_use;
+#else
+ (void) $as_decl_name;
+#endif
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_decl
+cat >config.log <<_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 Bundled Extensions $as_me 4.1.1, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+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`
+/usr/bin/hostinfo = `(/usr/bin/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=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&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_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=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append 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
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset 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: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > 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
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+ 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. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+gt_needs="$gt_needs "
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; 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,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_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
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_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.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+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
+
+
+
+
+ac_aux_dir=
+for ac_dir in build-aux "$srcdir"/build-aux; 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
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&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_fn_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"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+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
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM 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.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; 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 | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* 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 -std 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 -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 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
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+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
+
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+ ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+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
+
+
+
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+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
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core 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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.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))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+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=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
+if test "x$ac_cv_header_minix_config_h" = xyes; then :
+ MINIX=yes
+else
+ MINIX=
+fi
+
+
+ if test "$MINIX" = yes; then
+
+$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
+
+
+$as_echo "#define _MINIX 1" >>confdefs.h
+
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
+$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
+if ${ac_cv_safe_to_define___extensions__+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+# define __EXTENSIONS__ 1
+ $ac_includes_default
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_safe_to_define___extensions__=yes
+else
+ ac_cv_safe_to_define___extensions__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
+$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
+ test $ac_cv_safe_to_define___extensions__ = yes &&
+ $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
+
+ $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+ $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
+
+
+
+INSTALL="$ac_aux_dir/install-sh -c"
+export INSTALL
+
+am__api_version='1.14'
+
+# 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.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+ $as_echo_n "(cached) " >&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_fn_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
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+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. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$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'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
+esac
+
+# 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 (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ 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
+ 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".
+ as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
+ alias in your environment" "$LINENO" 5
+ fi
+ if test "$2" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+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 $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
+else
+ am_missing_run=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if ${ac_cv_path_mkdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ test -d ./--version && rmdir ./--version
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+ $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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
+
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-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='\'
+ am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+ fi
+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-extensions'
+ VERSION='4.1.1'
+
+
+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"}
+
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar pax cpio none'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+ $as_echo_n "(cached) " >&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".
+ rm -rf conftest.dir
+ 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
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ 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 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # 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. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ 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
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$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
+
+
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+ fi
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5
+$as_echo_n "checking whether NLS is requested... " >&6; }
+ # Check whether --enable-nls was given.
+if test "${enable_nls+set}" = set; then :
+ enableval=$enable_nls; USE_NLS=$enableval
+else
+ USE_NLS=yes
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5
+$as_echo "$USE_NLS" >&6; }
+
+
+
+
+ GETTEXT_MACRO_VERSION=0.18
+
+
+
+
+# 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MSGFMT+:} false; then :
+ $as_echo_n "(cached) " >&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
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5
+$as_echo "$MSGFMT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_GMSGFMT+:} false; then :
+ $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT=$ac_cv_path_GMSGFMT
+if test -n "$GMSGFMT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5
+$as_echo "$GMSGFMT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+ case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;;
+ *) MSGFMT_015=$MSGFMT ;;
+ esac
+
+ case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;;
+ *) GMSGFMT_015=$GMSGFMT ;;
+ esac
+
+
+
+# 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_XGETTEXT+:} false; then :
+ $as_echo_n "(cached) " >&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
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5
+$as_echo "$XGETTEXT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ rm -f messages.po
+
+ case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;;
+ *) XGETTEXT_015=$XGETTEXT ;;
+ esac
+
+
+
+# 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MSGMERGE+:} false; then :
+ $as_echo_n "(cached) " >&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
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5
+$as_echo "$MSGMERGE" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$localedir" || localedir='${datadir}/locale'
+
+
+ test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS=
+
+
+ ac_config_commands="$ac_config_commands po-directories"
+
+
+
+ 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.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+# Check whether --with-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.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by GCC" >&5
+$as_echo_n "checking for ld used by GCC... " >&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
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${acl_cv_path_LD+:} false; then :
+ $as_echo_n "(cached) " >&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
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${acl_cv_prog_gnu_ld+:} false; then :
+ $as_echo_n "(cached) " >&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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_prog_gnu_ld" >&5
+$as_echo "$acl_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$acl_cv_prog_gnu_ld
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5
+$as_echo_n "checking for shared library run path origin... " >&6; }
+if ${acl_cv_rpath+:} false; then :
+ $as_echo_n "(cached) " >&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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5
+$as_echo "$acl_cv_rpath" >&6; }
+ wl="$acl_cv_wl"
+ acl_libext="$acl_cv_libext"
+ acl_shlibext="$acl_cv_shlibext"
+ acl_libname_spec="$acl_cv_libname_spec"
+ acl_library_names_spec="$acl_cv_library_names_spec"
+ acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
+ acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
+ acl_hardcode_direct="$acl_cv_hardcode_direct"
+ acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
+ # Check whether --enable-rpath was given.
+if test "${enable_rpath+set}" = set; then :
+ enableval=$enable_rpath; :
+else
+ enable_rpath=yes
+fi
+
+
+
+
+ acl_libdirstem=lib
+ acl_libdirstem2=
+ case "$host_os" in
+ solaris*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit host" >&5
+$as_echo_n "checking for 64-bit host... " >&6; }
+if ${gl_cv_solaris_64bit+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#ifdef _LP64
+sixtyfour bits
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "sixtyfour bits" >/dev/null 2>&1; then :
+ gl_cv_solaris_64bit=yes
+else
+ gl_cv_solaris_64bit=no
+fi
+rm -f conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_solaris_64bit" >&5
+$as_echo "$gl_cv_solaris_64bit" >&6; }
+ if test $gl_cv_solaris_64bit = yes; then
+ acl_libdirstem=lib/64
+ case "$host_cpu" in
+ sparc*) acl_libdirstem2=lib/sparcv9 ;;
+ i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
+ esac
+ fi
+ ;;
+ *)
+ searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
+ if test -n "$searchpath"; then
+ acl_save_IFS="${IFS= }"; IFS=":"
+ for searchdir in $searchpath; do
+ if test -d "$searchdir"; then
+ case "$searchdir" in
+ */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
+ */../ | */.. )
+ # Better ignore directories of this form. They are misleading.
+ ;;
+ *) searchdir=`cd "$searchdir" && pwd`
+ case "$searchdir" in
+ */lib64 ) acl_libdirstem=lib64 ;;
+ esac ;;
+ esac
+ fi
+ done
+ IFS="$acl_save_IFS"
+ fi
+ ;;
+ esac
+ test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 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/$acl_libdirstem"
+ if test "$acl_libdirstem2" != "$acl_libdirstem" \
+ && ! test -d "$withval/$acl_libdirstem"; then
+ additional_libdir="$withval/$acl_libdirstem2"
+ fi
+ fi
+ fi
+
+fi
+
+ LIBICONV=
+ LTLIBICONV=
+ INCICONV=
+ LIBICONV_PREFIX=
+ HAVE_LIBICONV=
+ 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=
+ eval libname=\"$acl_libname_spec\" # typically: libname=lib$name
+ if test -n "$acl_shlibext"; then
+ shrext=".$acl_shlibext" # typically: shrext=.so
+ else
+ shrext=
+ fi
+ if test $use_additional = yes; then
+ dir="$additional_libdir"
+ if test -n "$acl_shlibext"; then
+ if test -f "$dir/$libname$shrext"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext"
+ else
+ if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+ ver=`(cd "$dir" && \
+ for f in "$libname$shrext".*; do echo "$f"; done \
+ | sed -e "s,^$libname$shrext\\\\.,," \
+ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+ | sed 1q ) 2>/dev/null`
+ if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext.$ver"
+ fi
+ else
+ eval library_names=\"$acl_library_names_spec\"
+ for f in $library_names; do
+ if test -f "$dir/$f"; then
+ found_dir="$dir"
+ found_so="$dir/$f"
+ break
+ fi
+ done
+ fi
+ fi
+ fi
+ if test "X$found_dir" = "X"; then
+ if test -f "$dir/$libname.$acl_libext"; then
+ found_dir="$dir"
+ found_a="$dir/$libname.$acl_libext"
+ fi
+ fi
+ if test "X$found_dir" != "X"; then
+ if test -f "$dir/$libname.la"; then
+ found_la="$dir/$libname.la"
+ 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 "$acl_shlibext"; then
+ if test -f "$dir/$libname$shrext"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext"
+ else
+ if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+ ver=`(cd "$dir" && \
+ for f in "$libname$shrext".*; do echo "$f"; done \
+ | sed -e "s,^$libname$shrext\\\\.,," \
+ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+ | sed 1q ) 2>/dev/null`
+ if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext.$ver"
+ fi
+ else
+ eval library_names=\"$acl_library_names_spec\"
+ for f in $library_names; do
+ if test -f "$dir/$f"; then
+ found_dir="$dir"
+ found_so="$dir/$f"
+ break
+ fi
+ done
+ fi
+ fi
+ fi
+ if test "X$found_dir" = "X"; then
+ if test -f "$dir/$libname.$acl_libext"; then
+ found_dir="$dir"
+ found_a="$dir/$libname.$acl_libext"
+ fi
+ fi
+ if test "X$found_dir" != "X"; then
+ if test -f "$dir/$libname.la"; then
+ found_la="$dir/$libname.la"
+ 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/$acl_libdirstem" \
+ || test "X$found_dir" = "X/usr/$acl_libdirstem2"; 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 "$acl_hardcode_direct" = yes; then
+ LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so"
+ else
+ if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_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 "$acl_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
+ */$acl_libdirstem | */$acl_libdirstem/)
+ basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
+ if test "$name" = 'iconv'; then
+ LIBICONV_PREFIX="$basedir"
+ fi
+ additional_includedir="$basedir/include"
+ ;;
+ */$acl_libdirstem2 | */$acl_libdirstem2/)
+ basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'`
+ if test "$name" = 'iconv'; then
+ LIBICONV_PREFIX="$basedir"
+ fi
+ 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/$acl_libdirstem" \
+ && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
+ haveit=
+ if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
+ || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; 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 "$acl_hardcode_libdir_separator"; then
+ alldirs=
+ for found_dir in $rpathdirs; do
+ alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
+ done
+ acl_save_libdir="$libdir"
+ libdir="$alldirs"
+ eval flag=\"$acl_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=\"$acl_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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFPreferencesCopyAppValue" >&5
+$as_echo_n "checking for CFPreferencesCopyAppValue... " >&6; }
+if ${gt_cv_func_CFPreferencesCopyAppValue+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gt_save_LIBS="$LIBS"
+ LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <CoreFoundation/CFPreferences.h>
+int
+main ()
+{
+CFPreferencesCopyAppValue(NULL, NULL)
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gt_cv_func_CFPreferencesCopyAppValue=yes
+else
+ gt_cv_func_CFPreferencesCopyAppValue=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS="$gt_save_LIBS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFPreferencesCopyAppValue" >&5
+$as_echo "$gt_cv_func_CFPreferencesCopyAppValue" >&6; }
+ if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then
+
+$as_echo "#define HAVE_CFPREFERENCESCOPYAPPVALUE 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFLocaleCopyCurrent" >&5
+$as_echo_n "checking for CFLocaleCopyCurrent... " >&6; }
+if ${gt_cv_func_CFLocaleCopyCurrent+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gt_save_LIBS="$LIBS"
+ LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <CoreFoundation/CFLocale.h>
+int
+main ()
+{
+CFLocaleCopyCurrent();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gt_cv_func_CFLocaleCopyCurrent=yes
+else
+ gt_cv_func_CFLocaleCopyCurrent=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS="$gt_save_LIBS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFLocaleCopyCurrent" >&5
+$as_echo "$gt_cv_func_CFLocaleCopyCurrent" >&6; }
+ if test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+
+$as_echo "#define HAVE_CFLOCALECOPYCURRENT 1" >>confdefs.h
+
+ 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
+
+
+
+
+
+
+ LIBINTL=
+ LTLIBINTL=
+ POSUB=
+
+ case " $gt_needs " in
+ *" need-formatstring-macros "*) gt_api_version=3 ;;
+ *" need-ngettext "*) gt_api_version=2 ;;
+ *) gt_api_version=1 ;;
+ esac
+ gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc"
+ gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl"
+
+ if test "$USE_NLS" = "yes"; then
+ gt_use_preinstalled_gnugettext=no
+
+
+ if test $gt_api_version -ge 3; then
+ gt_revision_test_code='
+#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
+#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
+#endif
+typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
+'
+ else
+ gt_revision_test_code=
+ fi
+ if test $gt_api_version -ge 2; then
+ gt_expression_test_code=' + * ngettext ("", "", 0)'
+ else
+ gt_expression_test_code=
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libc" >&5
+$as_echo_n "checking for GNU gettext in libc... " >&6; }
+if eval \${$gt_func_gnugettext_libc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern int *_nl_domain_bindings;
+int
+main ()
+{
+bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$gt_func_gnugettext_libc=yes"
+else
+ eval "$gt_func_gnugettext_libc=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$gt_func_gnugettext_libc
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+ if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "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
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5
+$as_echo_n "checking for iconv... " >&6; }
+if ${am_cv_func_iconv+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ am_cv_func_iconv="no, consider installing GNU libiconv"
+ am_cv_lib_iconv=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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
+if ac_fn_c_try_link "$LINENO"; then :
+ am_cv_func_iconv=yes
+fi
+rm -f core 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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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
+if ac_fn_c_try_link "$LINENO"; then :
+ am_cv_lib_iconv=yes
+ am_cv_func_iconv=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS="$am_save_LIBS"
+ fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5
+$as_echo "$am_cv_func_iconv" >&6; }
+ if test "$am_cv_func_iconv" = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working iconv" >&5
+$as_echo_n "checking for working iconv... " >&6; }
+if ${am_cv_func_iconv_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ am_save_LIBS="$LIBS"
+ if test $am_cv_lib_iconv = yes; then
+ LIBS="$LIBS $LIBICONV"
+ fi
+ if test "$cross_compiling" = yes; then :
+ case "$host_os" in
+ aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
+ *) am_cv_func_iconv_works="guessing yes" ;;
+ esac
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <iconv.h>
+#include <string.h>
+int main ()
+{
+ /* Test against AIX 5.1 bug: Failures are not distinguishable from successful
+ returns. */
+ {
+ iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
+ if (cd_utf8_to_88591 != (iconv_t)(-1))
+ {
+ static const char input[] = "\342\202\254"; /* EURO SIGN */
+ char buf[10];
+ const char *inptr = input;
+ size_t inbytesleft = strlen (input);
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_utf8_to_88591,
+ (char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if (res == 0)
+ return 1;
+ }
+ }
+ /* Test against Solaris 10 bug: Failures are not distinguishable from
+ successful returns. */
+ {
+ iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
+ if (cd_ascii_to_88591 != (iconv_t)(-1))
+ {
+ static const char input[] = "\263";
+ char buf[10];
+ const char *inptr = input;
+ size_t inbytesleft = strlen (input);
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_ascii_to_88591,
+ (char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if (res == 0)
+ return 1;
+ }
+ }
+#if 0 /* This bug could be worked around by the caller. */
+ /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */
+ {
+ iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
+ if (cd_88591_to_utf8 != (iconv_t)(-1))
+ {
+ static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+ char buf[50];
+ const char *inptr = input;
+ size_t inbytesleft = strlen (input);
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_88591_to_utf8,
+ (char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if ((int)res > 0)
+ return 1;
+ }
+ }
+#endif
+ /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
+ provided. */
+ if (/* Try standardized names. */
+ iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
+ /* Try IRIX, OSF/1 names. */
+ && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
+ /* Try AIX names. */
+ && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
+ /* Try HP-UX names. */
+ && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
+ return 1;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ am_cv_func_iconv_works=yes
+else
+ am_cv_func_iconv_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ LIBS="$am_save_LIBS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv_works" >&5
+$as_echo "$am_cv_func_iconv_works" >&6; }
+ case "$am_cv_func_iconv_works" in
+ *no) am_func_iconv=no am_cv_lib_iconv=no ;;
+ *) am_func_iconv=yes ;;
+ esac
+ else
+ am_func_iconv=no am_cv_lib_iconv=no
+ fi
+ if test "$am_func_iconv" = yes; then
+
+$as_echo "#define HAVE_ICONV 1" >>confdefs.h
+
+ fi
+ if test "$am_cv_lib_iconv" = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5
+$as_echo_n "checking how to link with libiconv... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5
+$as_echo "$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 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/$acl_libdirstem"
+ if test "$acl_libdirstem2" != "$acl_libdirstem" \
+ && ! test -d "$withval/$acl_libdirstem"; then
+ additional_libdir="$withval/$acl_libdirstem2"
+ fi
+ fi
+ fi
+
+fi
+
+ LIBINTL=
+ LTLIBINTL=
+ INCINTL=
+ LIBINTL_PREFIX=
+ HAVE_LIBINTL=
+ 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=
+ eval libname=\"$acl_libname_spec\" # typically: libname=lib$name
+ if test -n "$acl_shlibext"; then
+ shrext=".$acl_shlibext" # typically: shrext=.so
+ else
+ shrext=
+ fi
+ if test $use_additional = yes; then
+ dir="$additional_libdir"
+ if test -n "$acl_shlibext"; then
+ if test -f "$dir/$libname$shrext"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext"
+ else
+ if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+ ver=`(cd "$dir" && \
+ for f in "$libname$shrext".*; do echo "$f"; done \
+ | sed -e "s,^$libname$shrext\\\\.,," \
+ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+ | sed 1q ) 2>/dev/null`
+ if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext.$ver"
+ fi
+ else
+ eval library_names=\"$acl_library_names_spec\"
+ for f in $library_names; do
+ if test -f "$dir/$f"; then
+ found_dir="$dir"
+ found_so="$dir/$f"
+ break
+ fi
+ done
+ fi
+ fi
+ fi
+ if test "X$found_dir" = "X"; then
+ if test -f "$dir/$libname.$acl_libext"; then
+ found_dir="$dir"
+ found_a="$dir/$libname.$acl_libext"
+ fi
+ fi
+ if test "X$found_dir" != "X"; then
+ if test -f "$dir/$libname.la"; then
+ found_la="$dir/$libname.la"
+ 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 "$acl_shlibext"; then
+ if test -f "$dir/$libname$shrext"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext"
+ else
+ if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+ ver=`(cd "$dir" && \
+ for f in "$libname$shrext".*; do echo "$f"; done \
+ | sed -e "s,^$libname$shrext\\\\.,," \
+ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+ | sed 1q ) 2>/dev/null`
+ if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext.$ver"
+ fi
+ else
+ eval library_names=\"$acl_library_names_spec\"
+ for f in $library_names; do
+ if test -f "$dir/$f"; then
+ found_dir="$dir"
+ found_so="$dir/$f"
+ break
+ fi
+ done
+ fi
+ fi
+ fi
+ if test "X$found_dir" = "X"; then
+ if test -f "$dir/$libname.$acl_libext"; then
+ found_dir="$dir"
+ found_a="$dir/$libname.$acl_libext"
+ fi
+ fi
+ if test "X$found_dir" != "X"; then
+ if test -f "$dir/$libname.la"; then
+ found_la="$dir/$libname.la"
+ 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/$acl_libdirstem" \
+ || test "X$found_dir" = "X/usr/$acl_libdirstem2"; 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 "$acl_hardcode_direct" = yes; then
+ LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so"
+ else
+ if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_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 "$acl_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
+ */$acl_libdirstem | */$acl_libdirstem/)
+ basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
+ if test "$name" = 'intl'; then
+ LIBINTL_PREFIX="$basedir"
+ fi
+ additional_includedir="$basedir/include"
+ ;;
+ */$acl_libdirstem2 | */$acl_libdirstem2/)
+ basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'`
+ if test "$name" = 'intl'; then
+ LIBINTL_PREFIX="$basedir"
+ fi
+ 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/$acl_libdirstem" \
+ && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
+ haveit=
+ if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
+ || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; 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 "$acl_hardcode_libdir_separator"; then
+ alldirs=
+ for found_dir in $rpathdirs; do
+ alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
+ done
+ acl_save_libdir="$libdir"
+ libdir="$alldirs"
+ eval flag=\"$acl_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=\"$acl_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
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libintl" >&5
+$as_echo_n "checking for GNU gettext in libintl... " >&6; }
+if eval \${$gt_func_gnugettext_libintl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gt_save_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $INCINTL"
+ gt_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIBINTL"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);
+int
+main ()
+{
+bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$gt_func_gnugettext_libintl=yes"
+else
+ eval "$gt_func_gnugettext_libintl=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then
+ LIBS="$LIBS $LIBICONV"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);
+int
+main ()
+{
+bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ LIBINTL="$LIBINTL $LIBICONV"
+ LTLIBINTL="$LTLIBINTL $LTLIBICONV"
+ eval "$gt_func_gnugettext_libintl=yes"
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+ CPPFLAGS="$gt_save_CPPFLAGS"
+ LIBS="$gt_save_LIBS"
+fi
+eval ac_res=\$$gt_func_gnugettext_libintl
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ fi
+
+ if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \
+ || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "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
+
+$as_echo "#define ENABLE_NLS 1" >>confdefs.h
+
+ else
+ USE_NLS=no
+ fi
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use NLS" >&5
+$as_echo_n "checking whether to use NLS... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5
+$as_echo "$USE_NLS" >&6; }
+ if test "$USE_NLS" = "yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking where the gettext function comes from" >&5
+$as_echo_n "checking where the gettext function comes from... " >&6; }
+ if test "$gt_use_preinstalled_gnugettext" = "yes"; then
+ if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
+ gt_source="external libintl"
+ else
+ gt_source="libc"
+ fi
+ else
+ gt_source="included intl directory"
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_source" >&5
+$as_echo "$gt_source" >&6; }
+ fi
+
+ if test "$USE_NLS" = "yes"; then
+
+ if test "$gt_use_preinstalled_gnugettext" = "yes"; then
+ if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libintl" >&5
+$as_echo_n "checking how to link with libintl... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBINTL" >&5
+$as_echo "$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
+
+
+$as_echo "#define HAVE_GETTEXT 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_DCGETTEXT 1" >>confdefs.h
+
+ fi
+
+ POSUB=po
+ fi
+
+
+
+ INTLLIBS="$LIBINTL"
+
+
+
+
+
+
+
+
+ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default"
+if test "x$ac_cv_member_struct_stat_st_blksize" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
+_ACEOF
+
+
+fi
+
+
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in ar lib "link -lib"
+ 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+ done
+fi
+if test -z "$AR"; then
+ ac_ct_AR=$AR
+ for ac_prog in ar lib "link -lib"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_AR" && break
+done
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+fi
+
+: ${AR=ar}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5
+$as_echo_n "checking the archiver ($AR) interface... " >&6; }
+if ${am_cv_ar_interface+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ 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
+
+ am_cv_ar_interface=ar
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int some_variable = 0;
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+ (eval $am_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -eq 0; then
+ am_cv_ar_interface=ar
+ else
+ am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+ (eval $am_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -eq 0; then
+ am_cv_ar_interface=lib
+ else
+ am_cv_ar_interface=unknown
+ fi
+ fi
+ rm -f conftest.lib libconftest.a
+
+fi
+rm -f core 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
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5
+$as_echo "$am_cv_ar_interface" >&6; }
+
+case $am_cv_ar_interface in
+ar)
+ ;;
+lib)
+ # Microsoft lib, so override with the ar-lib wrapper script.
+ # FIXME: It is wrong to rewrite AR.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__AR in this case,
+ # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+ # similar.
+ AR="$am_aux_dir/ar-lib $AR"
+ ;;
+unknown)
+ as_fn_error $? "could not determine $AR interface" "$LINENO" 5
+ ;;
+esac
+
+# Check whether --enable-largefile was given.
+if test "${enable_largefile+set}" = set; then :
+ enableval=$enable_largefile;
+fi
+
+if test "$enable_largefile" != no; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
+$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
+if ${ac_cv_sys_largefile_CC+:} false; then :
+ $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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
+ if ac_fn_c_try_compile "$LINENO"; then :
+ break
+fi
+rm -f core conftest.err conftest.$ac_objext
+ CC="$CC -n32"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_largefile_CC=' -n32'; break
+fi
+rm -f core conftest.err conftest.$ac_objext
+ break
+ done
+ CC=$ac_save_CC
+ rm -f conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
+$as_echo "$ac_cv_sys_largefile_CC" >&6; }
+ if test "$ac_cv_sys_largefile_CC" != no; then
+ CC=$CC$ac_cv_sys_largefile_CC
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
+if ${ac_cv_sys_file_offset_bits+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_file_offset_bits=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_file_offset_bits=64; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_file_offset_bits=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
+$as_echo "$ac_cv_sys_file_offset_bits" >&6; }
+case $ac_cv_sys_file_offset_bits in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+;;
+esac
+rm -rf conftest*
+ if test $ac_cv_sys_file_offset_bits = unknown; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
+$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
+if ${ac_cv_sys_large_files+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_large_files=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_large_files=1; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_large_files=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
+$as_echo "$ac_cv_sys_large_files" >&6; }
+case $ac_cv_sys_large_files in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+;;
+esac
+rm -rf conftest*
+ fi
+
+
+fi
+
+# Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_static=no
+fi
+
+
+
+
+
+
+
+
+
+case `pwd` in
+ *\ * | *\ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.2.458.26-92994'
+macro_revision='2.4.3'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO ""
+}
+
+case $ECHO in
+ printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+ print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ 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_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+ then ac_cv_path_FGREP="$GREP -F"
+ else
+ if test -z "$FGREP"; then
+ ac_path_FGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in fgrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_FGREP" || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+ # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'FGREP' >> "conftest.nl"
+ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_FGREP="$ac_path_FGREP"
+ ac_path_FGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_FGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_FGREP"; then
+ as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_FGREP=$FGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test yes = "$GCC"; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&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.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname 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 yes = "$with_gnu_ld"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD=$ac_dir/$ac_prog
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test no != "$with_gnu_ld" && break
+ ;;
+ *)
+ test yes != "$with_gnu_ld" && break
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+else
+ lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi
+fi
+
+LD=$lt_cv_path_LD
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM=$NM
+else
+ lt_nm_to_check=${ac_tool_prefix}nm
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/$lt_tmp_nm
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+ case $build_os in
+ mingw*) lt_bad_file=conftest.nm/nofile ;;
+ *) lt_bad_file=/dev/null ;;
+ esac
+ case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
+ *$lt_bad_file* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break 2
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break 2
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test no != "$lt_cv_path_NM"; then
+ NM=$lt_cv_path_NM
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in dumpbin "link -dump"
+ 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in dumpbin "link -dump"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+ case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols -headers"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+
+ if test : != "$DUMPBIN"; then
+ NM=$DUMPBIN
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ i=0
+ teststring=ABCD
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test 17 != "$i" # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n "$lt_cv_sys_max_cmd_len"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test yes != "$GCC"; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test yes = "$GCC"; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# 'unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[45]*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd* | bitrig*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh;
+ # decide which one to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd=$ECHO
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in ar
+ 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+ done
+fi
+if test -z "$AR"; then
+ ac_ct_AR=$AR
+ for ac_prog in ar
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_AR" && break
+done
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ar_at_file=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test 0 -eq "$ac_status"; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test 0 -ne "$ac_status"; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test no = "$lt_cv_ar_at_file"; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ bitrig* | openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test ia64 = "$host_cpu"; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Gets list of data symbols to import.
+ lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+ # Adjust the below global symbol transforms to fixup imported variables.
+ lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+ lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
+ lt_c_name_lib_hook="\
+ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\
+ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'"
+else
+ # Disable hooks by default.
+ lt_cv_sys_global_symbol_to_import=
+ lt_cdecl_hook=
+ lt_c_name_hook=
+ lt_c_name_lib_hook=
+fi
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function,
+ # D for any global variable and I for any imported variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS=conftstm.$ac_objext
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest$ac_exeext; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test yes = "$pipe_works"; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+ withval=$with_sysroot;
+else
+ with_sysroot=no
+fi
+
+
+lt_sysroot=
+case $with_sysroot in #(
+ yes)
+ if test yes = "$GCC"; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5
+$as_echo "$with_sysroot" >&6; }
+ as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+ ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5
+$as_echo_n "checking for a working dd... " >&6; }
+if ${ac_cv_path_lt_DD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+if test -z "$lt_DD"; then
+ ac_path_lt_DD_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ 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_prog in dd; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_lt_DD" || continue
+if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi
+ $ac_path_lt_DD_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_lt_DD"; then
+ :
+ fi
+else
+ ac_cv_path_lt_DD=$lt_DD
+fi
+
+rm -f conftest.i conftest2.i conftest.out
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5
+$as_echo "$ac_cv_path_lt_DD" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5
+$as_echo_n "checking how to truncate binary pipes... " >&6; }
+if ${lt_cv_truncate_bin+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5
+$as_echo "$lt_cv_truncate_bin" >&6; }
+
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+ enableval=$enable_libtool_lock;
+fi
+
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out what ABI is being produced by ac_compile, and set mode
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE=32
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE=64
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+mips64*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ emul=elf
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ emul="${emul}32"
+ ;;
+ *64-bit*)
+ emul="${emul}64"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *MSB*)
+ emul="${emul}btsmip"
+ ;;
+ *LSB*)
+ emul="${emul}ltsmip"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *N32*)
+ emul="${emul}n32"
+ ;;
+ esac
+ LD="${LD-ld} -m $emul"
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly. Note that the listed cases only cover the
+ # situations where additional linker options are needed (such as when
+ # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+ # vice versa); the common cases where no linker options are needed do
+ # not appear in the list.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ powerpc64le-*linux*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ powerpcle-*linux*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS=$CFLAGS
+ CFLAGS="$CFLAGS -belf"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ 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
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_cc_needs_belf=yes
+else
+ lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext 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
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+ if test yes != "$lt_cv_cc_needs_belf"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS=$SAVE_CFLAGS
+ fi
+ ;;
+*-*solaris*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*|x86_64-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD=${LD-ld}_sol2
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks=$enable_libtool_lock
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$MANIFEST_TOOL"; then
+ ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+ ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+ # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_MANIFEST_TOOL"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_MANIFEST_TOOL" = x; then
+ MANIFEST_TOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+ fi
+else
+ MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&5
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test yes != "$lt_cv_path_mainfest_tool"; then
+ MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+ case $host_os in
+ rhapsody* | darwin*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DSYMUTIL"; then
+ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+ ac_ct_DSYMUTIL=$DSYMUTIL
+ # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DSYMUTIL"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DSYMUTIL" = x; then
+ DSYMUTIL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DSYMUTIL=$ac_ct_DSYMUTIL
+ fi
+else
+ DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NMEDIT"; then
+ ac_cv_prog_NMEDIT="$NMEDIT" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+ ac_ct_NMEDIT=$NMEDIT
+ # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NMEDIT"; then
+ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_NMEDIT="nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NMEDIT" = x; then
+ NMEDIT=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ NMEDIT=$ac_ct_NMEDIT
+ fi
+else
+ NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LIPO"; then
+ ac_cv_prog_LIPO="$LIPO" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+ ac_ct_LIPO=$LIPO
+ # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LIPO"; then
+ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_LIPO="lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LIPO" = x; then
+ LIPO=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ LIPO=$ac_ct_LIPO
+ fi
+else
+ LIPO="$ac_cv_prog_LIPO"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL"; then
+ ac_cv_prog_OTOOL="$OTOOL" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+ ac_ct_OTOOL=$OTOOL
+ # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL"; then
+ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL="otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL" = x; then
+ OTOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL=$ac_ct_OTOOL
+ fi
+else
+ OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL64"; then
+ ac_cv_prog_OTOOL64="$OTOOL64" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+ ac_ct_OTOOL64=$OTOOL64
+ # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL64"; then
+ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL64="otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL64" = x; then
+ OTOOL64=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL64=$ac_ct_OTOOL64
+ fi
+else
+ OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "$LT_MULTI_MODULE"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&5
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ld_exported_symbols_list=yes
+else
+ lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+ echo "$AR cru libconftest.a conftest.o" >&5
+ $AR cru libconftest.a conftest.o 2>&5
+ echo "$RANLIB libconftest.a" >&5
+ $RANLIB libconftest.a 2>&5
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&5
+ elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ 10.[012][,.]*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test yes = "$lt_cv_apple_cc_single_mod"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test yes = "$lt_cv_ld_exported_symbols_list"; then
+ _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+ fi
+ if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+
+for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+# Set options
+
+
+
+ enable_dlopen=no
+
+
+ enable_win32_dll=no
+
+
+ # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+ withval=$with_pic; lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for lt_pkg in $withval; do
+ IFS=$lt_save_ifs
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ pic_mode=default
+fi
+
+
+
+
+
+
+
+
+ # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+ enableval=$enable_fast_install; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS=$ltmain
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+old_CC=$CC
+old_CFLAGS=$CFLAGS
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/${ac_tool_prefix}file"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac
+fi
+
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/file"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac
+fi
+
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC=$CC
+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
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test yes = "$GCC"; then
+ case $cc_basename in
+ nvcc*)
+ lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+ *)
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+ if test yes = "$GCC"; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ lt_prog_compiler_wl='-Xlinker '
+ if test -n "$lt_prog_compiler_pic"; then
+ lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ case $cc_basename in
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='$wl-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ # old Intel for x86_64, which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-qpic'
+ lt_prog_compiler_static='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ *Intel*\ [CF]*Compiler*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ *Portland\ Group*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms that do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_pic_works"; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_static_works"; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links=nottested
+if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test no = "$hard_links"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ' (' and ')$', so one must not match beginning or
+ # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+ # as well as any symbol that contains 'd'.
+ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # 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 yes != "$GCC"; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd* | bitrig*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test yes = "$with_gnu_ld"; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+ *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test yes = "$lt_use_gnu_ld_interface"; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='$wl'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ export_dynamic_flag_spec='$wl--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test ia64 != "$host_cpu"; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ export_dynamic_flag_spec='$wl--export-all-symbols'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ haiku*)
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ link_all_deplibs=yes
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ export_dynamic_flag_spec='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test linux-dietlibc = "$host_os"; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test no = "$tmp_diet"
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ nagfor*) # NAGFOR 5.3
+ tmp_sharedflag='-Wl,-shared' ;;
+ xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ compiler_needs_object=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+
+ if test yes = "$supports_anon_versioning"; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test no = "$ld_shlibs"; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ 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].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='$wl-f,'
+
+ if test yes = "$GCC"; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag="$shared_flag "'$wl-G'
+ fi
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ fi
+ fi
+
+ export_dynamic_flag_spec='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test yes = "$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=/usr/lib:/lib
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=/usr/lib:/lib
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' $wl-bernotok'
+ allow_undefined_flag=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ fi
+ archive_cmds_need_lc=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $wl-bnoentry $compiler_flags $wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # 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.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ file_list_spec='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+ enable_shared_with_static_runtimes=yes
+ exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ old_postinstall_cmds='chmod 644 $oldlib'
+ postlink_cmds='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ enable_shared_with_static_runtimes=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ if test yes = "$lt_cv_ld_force_load"; then
+ whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+ else
+ whole_archive_flag_spec=''
+ fi
+ link_all_deplibs=yes
+ allow_undefined_flag=$_lt_dar_allow_undefined
+ case $cc_basename in
+ ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test yes = "$_lt_dar_can_shared"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+ archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+ module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+
+ else
+ ld_shlibs=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test yes = "$GCC"; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ fi
+ 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
+ export_dynamic_flag_spec='$wl-E'
+ ;;
+
+ hpux10*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test no = "$with_gnu_ld"; then
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='$wl-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler__b=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -b"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler__b=yes
+ fi
+ else
+ lt_cv_prog_compiler__b=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test yes = "$lt_cv_prog_compiler__b"; then
+ archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+ ;;
+ esac
+ fi
+ if test no = "$with_gnu_ld"; then
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='$wl-E'
+
+ # 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*)
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_irix_exported_symbol=yes
+else
+ lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+ if test yes = "$lt_cv_irix_exported_symbol"; then
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+ fi
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ export_dynamic_flag_spec='$wl-E'
+ else
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test yes = "$GCC"; then
+ allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test yes = "$GCC"; then
+ allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+ archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test yes = "$GCC"; then
+ wlarc='$wl'
+ archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='$wl'
+ archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'. GCC discards it without '$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test yes = "$GCC"; then
+ whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test sequent = "$host_vendor"; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='$wl-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='$wl-z,text'
+ allow_undefined_flag='$wl-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='$wl-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+
+ if test sni = "$host_vendor"; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='$wl-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test no = "$ld_shlibs" && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test yes,yes = "$GCC,$enable_shared"; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+ archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test yes = "$GCC"; then
+ case $host_os in
+ darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+ *) lt_awk_arg='/^libraries:/' ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;;
+ *) lt_sed_strip_eq='s|=/|/|g' ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary...
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ # ...but if some path component already ends with the multilib dir we assume
+ # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+ case "$lt_multi_os_dir; $lt_search_path_spec " in
+ "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+ lt_multi_os_dir=
+ ;;
+ esac
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+ elif test -n "$lt_multi_os_dir"; then
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS = " "; FS = "/|\n";} {
+ lt_foo = "";
+ lt_count = 0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo = "/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's|/\([A-Za-z]:\)|\1|g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 supports IA64
+ library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line '#! .'. This would cause the generated library to
+ # depend on '.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test yes = "$aix_use_runtimelinking"; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='$libname$shared_ext'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ library_names_spec='$libname.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec=$LIB
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$major$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ if test 32 = "$HPUX_IA64_MODE"; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+ sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd* | bitrig*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec=/usr/lib
+ need_lib_prefix=no
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ need_version=no
+ else
+ need_version=yes
+ fi
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=.dll
+ need_lib_prefix=no
+ library_names_spec='$libname$shared_ext $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test yes = "$with_gnu_ld"; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+ soname_spec='$libname$shared_ext.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test yes = "$with_gnu_ld"; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+ sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+ sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test yes = "$hardcode_automatic"; then
+
+ # We can hardcode non-existent directories.
+ if test no != "$hardcode_direct" &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" &&
+ test no != "$hardcode_minus_L"; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test relink = "$hardcode_action" ||
+ test yes = "$inherit_rpath"; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+ test no = "$enable_shared"; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+ if test yes != "$enable_dlopen"; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen=load_add_on
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen=LoadLibrary
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+else
+
+ lt_cv_dlopen=dyld
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ tpf*)
+ # Don't try to run any link tests for TPF. We know it's impossible
+ # because TPF is a cross-compiler, and we know how we open DSOs.
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=no
+ ;;
+
+ *)
+ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+ lt_cv_dlopen=shl_load
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+ lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld
+else
+ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_svld_dlopen=yes
+else
+ ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_dld_link=yes
+else
+ ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+ lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test no = "$lt_cv_dlopen"; then
+ enable_dlopen=no
+ else
+ enable_dlopen=yes
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS=$CPPFLAGS
+ test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS=$LDFLAGS
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS=$LIBS
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test yes = "$cross_compiling"; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+ if test yes = "$lt_cv_dlopen_self"; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test yes = "$cross_compiling"; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+ fi
+
+ CPPFLAGS=$save_CPPFLAGS
+ LDFLAGS=$save_LDFLAGS
+ LIBS=$save_LIBS
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP"; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report what library types will actually be built
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test ia64 != "$host_cpu" && test no = "$aix_use_runtimelinking"; then
+ test yes = "$enable_shared" && enable_static=no
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&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
+
+CC=$lt_save_CC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+pkgextensiondir='${libdir}/gawk'
+
+
+if test "$GCC" = yes
+then
+ CFLAGS="$CFLAGS -Wall" # Don't add -Wextra, hurts older gcc
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for special development options" >&5
+$as_echo_n "checking for special development options... " >&6; }
+if test -f $srcdir/../.developing
+then
+ if test "$GCC" = yes
+ then
+ CFLAGS="$CFLAGS -Wall -fno-builtin -g3 -gdwarf-2"
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+for ac_header in fnmatch.h limits.h sys/time.h sys/select.h sys/param.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+ as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
+$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
+if eval \${$as_ac_Header+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$as_ac_Header=yes"
+else
+ eval "$as_ac_Header=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$as_ac_Header
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if ${ac_cv_search_opendir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' dir; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_opendir+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_opendir+:} false; then :
+
+else
+ ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if ${ac_cv_search_opendir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' x; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_opendir+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_opendir+:} false; then :
+
+else
+ ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sys/types.h defines makedev" >&5
+$as_echo_n "checking whether sys/types.h defines makedev... " >&6; }
+if ${ac_cv_header_sys_types_h_makedev+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+int
+main ()
+{
+return makedev(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_header_sys_types_h_makedev=yes
+else
+ ac_cv_header_sys_types_h_makedev=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_types_h_makedev" >&5
+$as_echo "$ac_cv_header_sys_types_h_makedev" >&6; }
+
+if test $ac_cv_header_sys_types_h_makedev = no; then
+ac_fn_c_check_header_mongrel "$LINENO" "sys/mkdev.h" "ac_cv_header_sys_mkdev_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_mkdev_h" = xyes; then :
+
+$as_echo "#define MAJOR_IN_MKDEV 1" >>confdefs.h
+
+fi
+
+
+
+ if test $ac_cv_header_sys_mkdev_h = no; then
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/sysmacros.h" "ac_cv_header_sys_sysmacros_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_sysmacros_h" = xyes; then :
+
+$as_echo "#define MAJOR_IN_SYSMACROS 1" >>confdefs.h
+
+fi
+
+
+ fi
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
+$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
+if ${ac_cv_header_time+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_time=yes
+else
+ ac_cv_header_time=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
+$as_echo "$ac_cv_header_time" >&6; }
+if test $ac_cv_header_time = yes; then
+
+$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
+
+fi
+
+
+for ac_func in fdopendir fnmatch gettimeofday \
+ getdtablesize nanosleep select GetSystemTimeAsFileTime
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+
+
+
+ for ac_func in dirfd
+do :
+ ac_fn_c_check_func "$LINENO" "dirfd" "ac_cv_func_dirfd"
+if test "x$ac_cv_func_dirfd" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DIRFD 1
+_ACEOF
+
+fi
+done
+
+ ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
+ #include <dirent.h>
+"
+if test "x$ac_cv_have_decl_dirfd" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_DIRFD $ac_have_decl
+_ACEOF
+
+ if test $ac_cv_have_decl_dirfd = no; then
+ HAVE_DECL_DIRFD=0
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether dirfd is a macro" >&5
+$as_echo_n "checking whether dirfd is a macro... " >&6; }
+if ${gl_cv_func_dirfd_macro+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <sys/types.h>
+#include <dirent.h>
+#ifdef dirfd
+ dirent_header_defines_dirfd
+#endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "dirent_header_defines_dirfd" >/dev/null 2>&1; then :
+ gl_cv_func_dirfd_macro=yes
+else
+ gl_cv_func_dirfd_macro=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_dirfd_macro" >&5
+$as_echo "$gl_cv_func_dirfd_macro" >&6; }
+
+ # Use the replacement only if we have no function or macro with that name.
+ if test $ac_cv_func_dirfd = no && test $gl_cv_func_dirfd_macro = no; then
+ if test $ac_cv_have_decl_dirfd = yes; then
+ # If the system declares dirfd already, let's declare rpl_dirfd instead.
+ REPLACE_DIRFD=1
+ fi
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to get the file descriptor associated with an open DIR*" >&5
+$as_echo_n "checking how to get the file descriptor associated with an open DIR*... " >&6; }
+if ${gl_cv_sys_dir_fd_member_name+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ dirfd_save_CFLAGS=$CFLAGS
+ for ac_expr in d_fd dd_fd; do
+
+ CFLAGS="$CFLAGS -DDIR_FD_MEMBER_NAME=$ac_expr"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <sys/types.h>
+ #include <dirent.h>
+int
+main ()
+{
+DIR *dir_p = opendir("."); (void) dir_p->DIR_FD_MEMBER_NAME;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ dir_fd_found=yes
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS=$dirfd_save_CFLAGS
+ test "$dir_fd_found" = yes && break
+ done
+ test "$dir_fd_found" = yes || ac_expr=no_such_member
+
+ gl_cv_sys_dir_fd_member_name=$ac_expr
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_sys_dir_fd_member_name" >&5
+$as_echo "$gl_cv_sys_dir_fd_member_name" >&6; }
+ if test $gl_cv_sys_dir_fd_member_name != no_such_member; then
+
+cat >>confdefs.h <<_ACEOF
+#define DIR_FD_MEMBER_NAME $gl_cv_sys_dir_fd_member_name
+_ACEOF
+
+ fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$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
+
+
+ac_config_headers="$ac_config_headers config.h:configh.in"
+
+
+ac_config_files="$ac_config_files Makefile"
+
+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, we kill variables containing newlines.
+# 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.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}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 "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ 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}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $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}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+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
+IFS=$as_save_IFS
+
+ ;;
+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
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; 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
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# 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
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by GNU Awk Bundled Extensions $as_me 4.1.1, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ 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-gawk@gnu.org>.
+GNU Awk Bundled Extensions home page: <http://www.gnu.org/software/gawk-extensions/>.
+General help using GNU software: <http://www.gnu.org/gethelp/>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+GNU Awk Bundled Extensions config.status 4.1.1
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+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=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ 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 || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+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 < 1.5.
+ eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"'
+ # Capture the value of LINGUAS because we need it to compute CATALOGS.
+ LINGUAS="${LINGUAS-%UNSET%}"
+
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_import \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+lt_cv_nm_interface \
+nm_file_list_spec \
+lt_cv_truncate_bin \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "po-directories") CONFIG_COMMANDS="$CONFIG_COMMANDS po-directories" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:configh.in" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ 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 against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries 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[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_tt"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #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.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # 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. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;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&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+ } >"$ac_tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$ac_tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
+ fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$_am_arg" : 'X\(//\)[^/]' \| \
+ X"$_am_arg" : 'X\(//\)$' \| \
+ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+ # Older Autoconf quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ 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.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_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"`
+ # 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'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir=$dirpart/$fdir; as_fn_mkdir_p
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+ ;;
+ "po-directories":C)
+ 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 < 1.5.
+ eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
+ POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
+ else
+ # The set of available languages was given in configure.in.
+ # Hide the ALL_LINGUAS assigment from automake < 1.5.
+ 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 ;;
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options that allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile=${ofile}T
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
+# Copyright (C) 2014 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.
+
+# GNU Libtool 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 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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, see <http://www.gnu.org/licenses/>.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags=''
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm into a list of symbols to manually relocate.
+global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name lister interface.
+nm_interface=$lt_lt_cv_nm_interface
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and where our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# Command to truncate a binary pipe.
+lt_truncate_bin=$lt_lt_cv_truncate_bin
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+ ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# 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 || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/extension/configure.ac b/extension/configure.ac
new file mode 100644
index 00000000..1f876a0e
--- /dev/null
+++ b/extension/configure.ac
@@ -0,0 +1,86 @@
+dnl
+dnl configure.ac --- autoconf input file for gawk
+dnl
+dnl Copyright (C) 2012-2014 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 3 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 Bundled Extensions], 4.1.1, bug-gawk@gnu.org, gawk-extensions)
+
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_AUX_DIR([build-aux])
+
+AC_USE_SYSTEM_EXTENSIONS
+
+INSTALL="$ac_aux_dir/install-sh -c"
+export INSTALL
+
+AM_INIT_AUTOMAKE([-Wall -Werror])
+
+AM_GNU_GETTEXT([external])
+AM_GNU_GETTEXT_VERSION([0.18.1])
+
+dnl checks for structure members
+AC_CHECK_MEMBERS([struct stat.st_blksize])
+
+AM_PROG_AR
+AC_SYS_LARGEFILE
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+dnl AC_PROG_INSTALL
+
+AC_SUBST([pkgextensiondir], ['${libdir}/gawk'])
+
+if test "$GCC" = yes
+then
+ CFLAGS="$CFLAGS -Wall" # Don't add -Wextra, hurts older gcc
+fi
+
+AC_MSG_CHECKING([for special development options])
+if test -f $srcdir/../.developing
+then
+ if test "$GCC" = yes
+ then
+ CFLAGS="$CFLAGS -Wall -fno-builtin -g3 -gdwarf-2"
+ fi
+ AC_MSG_RESULT([yes])
+else
+ AC_MSG_RESULT([no])
+fi
+
+AC_CHECK_HEADERS(fnmatch.h limits.h sys/time.h sys/select.h sys/param.h)
+AC_HEADER_DIRENT
+AC_HEADER_MAJOR
+AC_HEADER_TIME
+
+AC_CHECK_FUNCS(fdopendir fnmatch gettimeofday \
+ getdtablesize nanosleep select GetSystemTimeAsFileTime)
+
+GAWK_FUNC_DIRFD
+GAWK_PREREQ_DIRFD
+
+dnl checks for compiler characteristics
+AC_C_INLINE
+
+AC_CONFIG_HEADERS([config.h:configh.in])
+
+AC_CONFIG_FILES(Makefile)
+AC_OUTPUT
diff --git a/extension/dl.c b/extension/dl.c
deleted file mode 100644
index afc16af5..00000000
--- a/extension/dl.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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, 2011 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 3 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>
-
-int plugin_is_GPL_compatible;
-
-static void *sdl = NULL;
-
-static NODE *
-zaxxon(int nargs)
-{
- NODE *obj;
- int i;
- int comma = 0;
-
- /*
- * Print the arguments
- */
- printf("External linkage zaxxon(");
-
- for (i = 0; i < nargs; i++) {
-
- obj = get_scalar_argument(i, TRUE);
-
- if (obj == NULL)
- break;
-
- force_string(obj);
-
- printf(comma ? ", %s" : "%s", obj->stptr);
- comma = 1;
- }
-
- printf(");\n");
-
- /*
- * Do something useful
- */
- obj = get_scalar_argument(0, FALSE);
-
- 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;
- }
- }
-
- /* Set the return value */
- return make_number((AWKNUM) 3.14);
-}
-
-NODE *
-dlload(tree, dl)
-NODE *tree;
-void *dl;
-{
- sdl = dl;
- make_builtin("zaxxon", zaxxon, 4);
- return make_number((AWKNUM) 0);
-}
diff --git a/extension/doit b/extension/doit
deleted file mode 100755
index 29dff7d8..00000000
--- a/extension/doit
+++ /dev/null
@@ -1 +0,0 @@
-../gawk -f foo.awk
diff --git a/extension/filefuncs.3am b/extension/filefuncs.3am
new file mode 100644
index 00000000..d0eb2acf
--- /dev/null
+++ b/extension/filefuncs.3am
@@ -0,0 +1,370 @@
+.TH FILEFUNCS 3am "Jan 15 2013" "Free Software Foundation" "GNU Awk Extension Modules"
+.SH NAME
+filefuncs \- provide some file related functionality to gawk
+.SH SYNOPSIS
+.ft CW
+@load "filefuncs"
+.sp
+result = chdir("/some/directory")
+.sp
+result = stat("/some/path", statdata [, follow])
+.sp
+flags = or(FTS_PHYSICAL, ...)
+.br
+result = fts(pathlist, flags, filedata)
+.ft R
+.SH DESCRIPTION
+The
+.I filefuncs
+extension adds several functions that provide access to
+file-related facilities.
+.SS chdir()
+The
+.B chdir()
+function is a direct hook to the
+.IR chdir (2)
+system call to change the current directory.
+It returns zero
+upon success or less than zero upon error.
+In the latter case it updates
+.BR ERRNO .
+.SS stat()
+The
+.B stat()
+function provides a hook into the
+.IR stat (2)
+system call.
+It returns zero
+upon success or less than zero upon error.
+In the latter case it updates
+.BR ERRNO .
+By default, it uses
+.IR lstat (2).
+However, if passed a third argument, it uses
+.IR stat (2),
+instead.
+.PP
+In all cases, it clears the
+.B statdata
+array.
+When the call is successful,
+.B stat()
+fills the
+.B statdata
+array with information retrieved from the filesystem, as follows:
+.TP
+\fBstatdata["name"]\fP
+The name of the file.
+.TP
+\fBstatdata["dev"]\fP
+Corresponds to the
+.I st_dev
+field in the
+.IR "struct stat" .
+.TP
+\fBstatdata["ino"]\fP
+Corresponds to the
+.I st_ino
+field in the
+.IR "struct stat" .
+.TP
+\fBstatdata["mode"]\fP
+Corresponds to the
+.I st_mode
+field in the
+.IR "struct stat" .
+.TP
+\fBstatdata["nlink"]\fP
+Corresponds to the
+.I st_nlink
+field in the
+.IR "struct stat" .
+.TP
+\fBstatdata["uid"]\fP
+Corresponds to the
+.I st_uid
+field in the
+.IR "struct stat" .
+.TP
+\fBstatdata["gid"]\fP
+Corresponds to the
+.I st_gid
+field in the
+.IR "struct stat" .
+.TP
+\fBstatdata["size"]\fP
+Corresponds to the
+.I st_size
+field in the
+.IR "struct stat" .
+.TP
+\fBstatdata["atime"]\fP
+Corresponds to the
+.I st_atime
+field in the
+.IR "struct stat" .
+.TP
+\fBstatdata["mtime"]\fP
+Corresponds to the
+.I st_mtime
+field in the
+.IR "struct stat" .
+.TP
+\fBstatdata["ctime"]\fP
+Corresponds to the
+.I st_ctime
+field in the
+.IR "struct stat" .
+.TP
+\fBstatdata["rdev"]\fP
+Corresponds to the
+.I st_rdev
+field in the
+.IR "struct stat" .
+This element is only present for device files.
+.TP
+\fBstatdata["major"]\fP
+Corresponds to the
+.I st_major
+field in the
+.IR "struct stat" .
+This element is only present for device files.
+.TP
+\fBstatdata["minor"]\fP
+Corresponds to the
+.I st_minor
+field in the
+.IR "struct stat" .
+This element is only present for device files.
+.TP
+\fBstatdata["blksize"]\fP
+Corresponds to the
+.I st_blksize
+field in the
+.IR "struct stat" ,
+if this field is present on your system.
+(It is present on all modern systems that we know of.)
+.TP
+\fBstatdata["pmode"]\fP
+A human-readable version of the mode value, such as printed by
+.IR ls (1).
+For example, \fB"-rwxr-xr-x"\fP.
+.TP
+\fBstatdata["linkval"]\fP
+If the named file is a symbolic link, this element will exist
+and its value is the value of the symbolic link (where the
+symbolic link points to).
+.TP
+\fBstatdata["type"]\fP
+The type of the file as a string. One of
+\fB"file"\fP,
+\fB"blockdev"\fP,
+\fB"chardev"\fP,
+\fB"directory"\fP,
+\fB"socket"\fP,
+\fB"fifo"\fP,
+\fB"symlink"\fP,
+\fB"door"\fP,
+or
+\fB"unknown"\fP.
+Not all systems support all file types.
+.SS fts()
+The
+.B fts()
+function provides a hook to the
+.IR fts (3)
+set of routines for traversing file heirarchies.
+Instead of returning data about one file at a time in a stream,
+it fills in a multi-dimensional array with data about each file and
+directory encountered in the requested heirarchies.
+.PP
+The arguments are as follows:
+.TP
+.B pathlist
+An array of filenames. The element values are used; the index values are ignored.
+.TP
+.B flags
+This should be the bitwise OR of one or more of the following
+predefined flag values. At least one of
+.B FTS_LOGICAL
+or
+.B FTS_PHYSICAL
+must be provided; otherwise
+.B fts()
+returns an error value and sets
+.BR ERRNO .
+.RS
+.TP
+.B FTS_LOGICAL
+Do a ``logical'' file traversal, where the information returned for
+a symbolic link refers to the linked-to file, and not to the
+symbolic link itself.
+This flag is mutually exclusive with
+.BR FTS_PHYSICAL .
+.TP
+.B FTS_PHYSICAL
+Do a ``physical'' file traversal, where the information returned for
+a symbolic link refers to the symbolic link itself.
+This flag is mutually exclusive with
+.BR FTS_LOGICAL .
+.TP
+.B FTS_NOCHDIR
+As a performance optimization, the
+.IR fts (3)
+routines change directory as they traverse a file heirarchy.
+This flag disables that optimization.
+.TP
+.B FTS_COMFOLLOW
+Immediatly follow a symbolic link named in
+.BR pathlist ,
+whether or not
+.B FTS_LOGICAL
+is set.
+.TP
+.B FTS_SEEDOT
+By default, the
+.IR fts (3)
+routines do not return entries for ``.'' and ``..''.
+This option causes entries for ``..'' to also be included.
+(The AWK extension always includes an entry for ``.'', see below.)
+.TP
+.B FTS_XDEV
+During a traversal, do not cross onto a different mounted filesystem.
+.RE
+.TP
+.B filedata
+The
+.B filedata
+array is first cleared.
+Then,
+.B fts()
+creates an element in
+.B filedata
+for every element in
+.BR pathlist .
+The index is the name of the directory or file given in
+.BR pathlist .
+The element for this index is itself an array.
+There are two cases.
+.RS
+.TP
+The path is a file.
+In this case, the array contains two or three elements:
+.RS
+.TP
+\fB"path"\fP
+The full path to this file, starting from the ``root'' that was given
+in the
+.B pathlist
+array.
+.TP
+\fB"stat"\fP
+This element is itself an array, containing the same information as provided
+by the
+.B stat()
+function described earlier for its
+.B statdata
+argument.
+The element may not be present if
+.IR stat (2)
+for the file failed.
+.TP
+\fB"error"\fP
+If some kind of error was encountered, the array will also
+contain an element named \fB"error"\fP, which is a string describing the error.
+.RE
+.TP
+The path is a directory.
+In this case, the array contains one element for each entry in the directory.
+If an entry is a file, that element is as for files, just described.
+If the entry is a directory, that element is (recursively), an array describing
+the subdirectory.
+If
+.B FTS_SEEDOT
+was provided in the flags, then there will also be an element named
+\fB".."\fP. This element will be an array containing the data
+as provided by
+.BR stat() .
+.sp
+In addition, there will be an element whose index is \fB"."\fP.
+This element is an array containing the same two or three elements
+as for a file:
+\fB"path"\fP,
+\fB"stat"\fP,
+and
+\fB"error"\fP.
+.RE
+.PP
+The
+.B fts()
+function returns 0 if there were no errors. Otherwise it returns \-1.
+.SH NOTES
+The AWK
+.B fts()
+extension does not exactly mimic the interface of the
+.IR fts (3)
+routines, choosing instead to provide an interface that is based
+on associative arrays, which should be more comfortable to use from
+an AWK program. This includes the lack of a comparison function, since
+.I gawk
+already provides powerful array sorting facilities. While an
+.IR fts_read() \-like
+interface could have been provided, this felt less natural than
+simply creating a multi-dimensional array to represent the file
+heirarchy and its information.
+.PP
+Nothing prevents AWK code from changing the predefined
+.BI FTS_ xx
+values, but doing so is may cause strange results when
+the changed values are passed to
+.BR fts() .
+.SH BUGS
+There are many more file-related functions for which AWK
+interfaces would be desirable.
+.SH EXAMPLE
+See
+.B test/fts.awk
+in the
+.I gawk
+distribution for an example.
+.SH "SEE ALSO"
+.IR "GAWK: Effective AWK Programming" ,
+.IR fnmatch (3am),
+.IR fork (3am),
+.IR inplace (3am),
+.IR ordchr (3am),
+.IR readdir (3am),
+.IR readfile (3am),
+.IR revoutput (3am),
+.IR rwarray (3am),
+.IR time (3am).
+.PP
+.IR chdir (2),
+.IR fts (3),
+.IR stat (2).
+.SH AUTHOR
+Arnold Robbins,
+.BR arnold@skeeve.com .
+.SH COPYING PERMISSIONS
+Copyright \(co 2012, 2013,
+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.
diff --git a/extension/filefuncs.c b/extension/filefuncs.c
index 1a0a86ef..a20e9ff7 100644
--- a/extension/filefuncs.c
+++ b/extension/filefuncs.c
@@ -4,10 +4,13 @@
*
* 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
+ * Arnold Robbins and Andrew Schorr, revised for new extension API, May 2012.
+ * Arnold Robbins, add fts(), August 2012
*/
/*
- * Copyright (C) 2001, 2004, 2005, 2010, 2011 the Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2004, 2005, 2010, 2011, 2012, 2013, 2014
+ * the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -27,30 +30,141 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "awk.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _BSD_SOURCE
+
+#ifdef __VMS
+#if (__CRTL_VER >= 70200000) && !defined (__VAX)
+#define _LARGEFILE 1
+#endif
+
+#ifndef __VAX
+#ifdef __CRTL_VER
+#if __CRTL_VER >= 80200000
+#define _USE_STD_STAT 1
+#endif
+#endif
+#endif
+#define _POSIX_C_SOURCE 1
+#define _XOPEN_SOURCE 1
+#include <stat.h>
+#ifndef S_ISVTX
+#define S_ISVTX (0)
+#endif
+#ifndef major
+#define major(s) (s)
+#endif
+#ifndef minor
+#define minor(s) (0)
+#endif
+#include <unixlib.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif /* HAVE_SYS_PARAM_H */
+
+#ifdef MAJOR_IN_MKDEV
+#include <sys/mkdev.h>
+#elif defined(MAJOR_IN_SYSMACROS)
#include <sys/sysmacros.h>
+#endif
+
+#include "gawkapi.h"
+
+#include "gettext.h"
+#define _(msgid) gettext(msgid)
+#define N_(msgid) msgid
+
+#include "gawkfts.h"
+#include "stack.h"
+
+#ifndef S_IFLNK
+#define lstat stat
+#define S_ISLNK(s) 0
+#define readlink(f,b,bs) (-1)
+#endif
+
+#ifdef __MINGW32__
+#define S_IRGRP S_IRUSR
+#define S_IWGRP S_IWUSR
+#define S_IXGRP S_IXUSR
+#define S_IROTH S_IRUSR
+#define S_IWOTH S_IWUSR
+#define S_IXOTH S_IXUSR
+#define S_ISUID 0
+#define S_ISGID 0
+#define S_ISVTX 0
+#define major(s) (s)
+#define minor(s) (0)
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+/* get_inode --- get the inode of a file */
+static long long
+get_inode(const char *fname)
+{
+ HANDLE fh;
+ BY_HANDLE_FILE_INFORMATION info;
+
+ fh = CreateFile(fname, 0, 0, NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (fh == INVALID_HANDLE_VALUE)
+ return 0;
+ if (GetFileInformationByHandle(fh, &info)) {
+ long long inode = info.nFileIndexHigh;
+
+ inode <<= 32;
+ inode += info.nFileIndexLow;
+ return inode;
+ }
+ return 0;
+}
+#endif
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+static awk_bool_t init_filefuncs(void);
+static awk_bool_t (*init_func)(void) = init_filefuncs;
+static const char *ext_version = "filefuncs extension: version 1.0";
int plugin_is_GPL_compatible;
-/* do_chdir --- provide dynamically loaded chdir() builtin for gawk */
+/* do_chdir --- provide dynamically loaded chdir() function for gawk */
-static NODE *
-do_chdir(int nargs)
+static awk_value_t *
+do_chdir(int nargs, awk_value_t *result)
{
- NODE *newdir;
+ awk_value_t newdir;
int ret = -1;
+ assert(result != NULL);
+
if (do_lint && nargs != 1)
- lintwarn("chdir: called with incorrect number of arguments");
+ lintwarn(ext_id, _("chdir: called with incorrect number of arguments, expecting 1"));
- newdir = get_scalar_argument(0, FALSE);
- (void) force_string(newdir);
- ret = chdir(newdir->stptr);
- if (ret < 0)
- update_ERRNO();
+ if (get_argument(0, AWK_STRING, & newdir)) {
+ ret = chdir(newdir.str_value.str);
+ if (ret < 0)
+ update_ERRNO_int(errno);
+ }
- return make_number((AWKNUM) ret);
+ return make_number(ret, result);
}
/* format_mode --- turn a stat mode field into something readable */
@@ -59,280 +173,704 @@ static char *
format_mode(unsigned long fmode)
{
static char outbuf[12];
- int i;
+ static struct ftype_map {
+ unsigned int mask;
+ int charval;
+ } ftype_map[] = {
+ { S_IFREG, '-' }, /* redundant */
+ { S_IFBLK, 'b' },
+ { S_IFCHR, 'c' },
+ { S_IFDIR, 'd' },
+#ifdef S_IFSOCK
+ { S_IFSOCK, 's' },
+#endif
+#ifdef S_IFIFO
+ { S_IFIFO, 'p' },
+#endif
+#ifdef S_IFLNK
+ { S_IFLNK, 'l' },
+#endif
+#ifdef S_IFDOOR /* Solaris weirdness */
+ { S_IFDOOR, 'D' },
+#endif /* S_IFDOOR */
+ };
+ static struct mode_map {
+ unsigned int mask;
+ int rep;
+ } map[] = {
+ { S_IRUSR, 'r' }, { S_IWUSR, 'w' }, { S_IXUSR, 'x' },
+ { S_IRGRP, 'r' }, { S_IWGRP, 'w' }, { S_IXGRP, 'x' },
+ { S_IROTH, 'r' }, { S_IWOTH, 'w' }, { S_IXOTH, 'x' },
+ };
+ static struct setuid_map {
+ unsigned int mask;
+ int index;
+ int small_rep;
+ int big_rep;
+ } setuid_map[] = {
+ { S_ISUID, 3, 's', 'S' }, /* setuid bit */
+ { S_ISGID, 6, 's', 'l' }, /* setgid without execute == locking */
+ { S_ISVTX, 9, 't', 'T' }, /* the so-called "sticky" bit */
+ };
+ int i, j, k;
strcpy(outbuf, "----------");
+
/* first, get the file type */
i = 0;
- switch (fmode & S_IFMT) {
+ for (j = 0, k = sizeof(ftype_map)/sizeof(ftype_map[0]); j < k; j++) {
+ if ((fmode & S_IFMT) == ftype_map[j].mask) {
+ outbuf[i] = ftype_map[j].charval;
+ break;
+ }
+ }
+
+ /* now the permissions */
+ for (j = 0, k = sizeof(map)/sizeof(map[0]); j < k; j++) {
+ i++;
+ if ((fmode & map[j].mask) != 0)
+ outbuf[i] = map[j].rep;
+ }
+
+ i++;
+ outbuf[i] = '\0';
+
+ /* tweaks for the setuid / setgid / sticky bits */
+ for (j = 0, k = sizeof(setuid_map)/sizeof(setuid_map[0]); j < k; j++) {
+ if (fmode & setuid_map[j].mask) {
+ if (outbuf[setuid_map[j].index] == 'x')
+ outbuf[setuid_map[j].index] = setuid_map[j].small_rep;
+ else
+ outbuf[setuid_map[j].index] = setuid_map[j].big_rep;
+ }
+ }
+
+ return outbuf;
+}
+
+/* read_symlink --- read a symbolic link into an allocated buffer.
+ This is based on xreadlink; the basic problem is that lstat cannot be relied
+ upon to return the proper size for a symbolic link. This happens,
+ for example, on GNU/Linux in the /proc filesystem, where the symbolic link
+ sizes are often 0. */
+
+#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)
+
+static char *
+read_symlink(const char *fname, size_t bufsize, ssize_t *linksize)
+{
+ if (bufsize)
+ bufsize += 2;
+ else
+ bufsize = BUFSIZ * 2;
+
+ /* Make sure that bufsize >= 2 and within range */
+ if (bufsize > MAXSIZE || bufsize < 2)
+ bufsize = MAXSIZE;
+
+ while (1) {
+ char *buf;
+
+ emalloc(buf, char *, bufsize, "read_symlink");
+ if ((*linksize = readlink(fname, buf, bufsize)) < 0) {
+ /* 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 (errno != ERANGE) {
+ gawk_free(buf);
+ return NULL;
+ }
+ }
+ /* N.B. This test is safe because bufsize must be >= 2 */
+ else if ((size_t)*linksize <= bufsize-2) {
+ buf[*linksize] = '\0';
+ return buf;
+ }
+ gawk_free(buf);
+ if (bufsize <= MAXSIZE/2)
+ bufsize *= 2;
+ else if (bufsize < MAXSIZE)
+ bufsize = MAXSIZE;
+ else
+ return NULL;
+ }
+ return NULL;
+}
+
+
+/* device_blocksize --- try to figure out units of st_blocks */
+
+static int
+device_blocksize()
+{
+ /* some of this derived from GNULIB stat-size.h */
+#if defined(DEV_BSIZE)
+ /* <sys/param.h>, most systems */
+ return DEV_BSIZE;
+#elif defined(S_BLKSIZE)
+ /* <sys/stat.h>, BSD systems */
+ return S_BLKSIZE;
+#elif defined hpux || defined __hpux__ || defined __hpux
+ return 1024;
+#elif defined _AIX && defined _I386
+ /* AIX PS/2 counts st_blocks in 4K units. */
+ return 4 * 1024;
+#elif defined __MINGW32__
+ return 1024;
+#else
+ return 512;
+#endif
+}
+
+/* array_set --- set an array element */
+
+static void
+array_set(awk_array_t array, const char *sub, awk_value_t *value)
+{
+ awk_value_t index;
+
+ set_array_element(array,
+ make_const_string(sub, strlen(sub), & index),
+ value);
+
+}
+
+/* array_set_numeric --- set an array element with a number */
+
+static void
+array_set_numeric(awk_array_t array, const char *sub, double num)
+{
+ awk_value_t tmp;
+
+ array_set(array, sub, make_number(num, & tmp));
+}
+
+/* fill_stat_array --- do the work to fill an array with stat info */
+
+static int
+fill_stat_array(const char *name, awk_array_t array, struct stat *sbuf)
+{
+ char *pmode; /* printable mode */
+ const char *type = "unknown";
+ awk_value_t tmp;
+ static struct ftype_map {
+ unsigned int mask;
+ const char *type;
+ } ftype_map[] = {
+ { S_IFREG, "file" },
+ { S_IFBLK, "blockdev" },
+ { S_IFCHR, "chardev" },
+ { S_IFDIR, "directory" },
#ifdef S_IFSOCK
- case S_IFSOCK:
- outbuf[i] = 's';
- break;
+ { S_IFSOCK, "socket" },
+#endif
+#ifdef S_IFIFO
+ { S_IFIFO, "fifo" },
#endif
#ifdef S_IFLNK
- case S_IFLNK:
- outbuf[i] = 'l';
- break;
+ { S_IFLNK, "symlink" },
#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;
+ { S_IFDOOR, "door" },
#endif /* S_IFDOOR */
- case S_IFCHR:
- outbuf[i] = 'c';
- break;
-#ifdef S_IFIFO
- case S_IFIFO:
- outbuf[i] = 'p';
- break;
+ };
+ int j, k;
+
+ /* empty out the array */
+ clear_array(array);
+
+ /* fill in the array */
+ array_set(array, "name", make_const_string(name, strlen(name), & tmp));
+ array_set_numeric(array, "dev", sbuf->st_dev);
+#ifdef __MINGW32__
+ array_set_numeric(array, "ino", (double)get_inode (name));
+#else
+ array_set_numeric(array, "ino", sbuf->st_ino);
+#endif
+ array_set_numeric(array, "mode", sbuf->st_mode);
+ array_set_numeric(array, "nlink", sbuf->st_nlink);
+ array_set_numeric(array, "uid", sbuf->st_uid);
+ array_set_numeric(array, "gid", sbuf->st_gid);
+ array_set_numeric(array, "size", sbuf->st_size);
+#ifdef __MINGW32__
+ array_set_numeric(array, "blocks", (sbuf->st_size + 4095) / 4096);
+#else
+ array_set_numeric(array, "blocks", sbuf->st_blocks);
#endif
+ array_set_numeric(array, "atime", sbuf->st_atime);
+ array_set_numeric(array, "mtime", sbuf->st_mtime);
+ array_set_numeric(array, "ctime", 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)) {
+ array_set_numeric(array, "rdev", sbuf->st_rdev);
+ array_set_numeric(array, "major", major(sbuf->st_rdev));
+ array_set_numeric(array, "minor", minor(sbuf->st_rdev));
}
- 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++;
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+ array_set_numeric(array, "blksize", sbuf->st_blksize);
+#elif defined(__MINGW32__)
+ array_set_numeric(array, "blksize", 4096);
+#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
- 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++;
+ /* the size of a block for st_blocks */
+ array_set_numeric(array, "devbsize", device_blocksize());
- 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++;
+ pmode = format_mode(sbuf->st_mode);
+ array_set(array, "pmode", make_const_string(pmode, strlen(pmode), & tmp));
- outbuf[i] = '\0';
+ /* for symbolic links, add a linkval field */
+ if (S_ISLNK(sbuf->st_mode)) {
+ char *buf;
+ ssize_t linksize;
- if ((fmode & S_ISUID) != 0) {
- if (outbuf[3] == 'x')
- outbuf[3] = 's';
+ if ((buf = read_symlink(name, sbuf->st_size,
+ & linksize)) != NULL)
+ array_set(array, "linkval", make_malloced_string(buf, linksize, & tmp));
else
- outbuf[3] = 'S';
+ warning(ext_id, _("stat: unable to read symbolic link `%s'"), name);
}
- /* setgid without execute == locking */
- if ((fmode & S_ISGID) != 0) {
- if (outbuf[6] == 'x')
- outbuf[6] = 's';
- else
- outbuf[6] = 'l';
+ /* add a type field */
+ type = "unknown"; /* shouldn't happen */
+ for (j = 0, k = sizeof(ftype_map)/sizeof(ftype_map[0]); j < k; j++) {
+ if ((sbuf->st_mode & S_IFMT) == ftype_map[j].mask) {
+ type = ftype_map[j].type;
+ break;
+ }
}
- if ((fmode & S_ISVTX) != 0) {
- if (outbuf[9] == 'x')
- outbuf[9] = 't';
- else
- outbuf[9] = 'T';
- }
+ array_set(array, "type", make_const_string(type, strlen(type), & tmp));
- return outbuf;
+ return 0;
}
/* do_stat --- provide a stat() function for gawk */
-static NODE *
-do_stat(int nargs)
+static awk_value_t *
+do_stat(int nargs, awk_value_t *result)
{
- NODE *file, *array, *tmp;
- struct stat sbuf;
+ awk_value_t file_param, array_param;
+ char *name;
+ awk_array_t array;
int ret;
- NODE **aptr;
- char *pmode; /* printable mode */
- char *type = "unknown";
+ struct stat sbuf;
+ int (*statfunc)(const char *path, struct stat *sbuf) = lstat; /* default */
- if (do_lint && nargs > 2)
- lintwarn("stat: called with too many arguments");
+ assert(result != NULL);
+
+ if (nargs != 2 && nargs != 3) {
+ if (do_lint)
+ lintwarn(ext_id, _("stat: called with wrong number of arguments"));
+ return make_number(-1, result);
+ }
/* file is first arg, array to hold results is second */
- file = get_scalar_argument(0, FALSE);
- array = get_array_argument(1, FALSE);
+ if ( ! get_argument(0, AWK_STRING, & file_param)
+ || ! get_argument(1, AWK_ARRAY, & array_param)) {
+ warning(ext_id, _("stat: bad parameters"));
+ return make_number(-1, result);
+ }
+
+ if (nargs == 3) {
+ statfunc = stat;
+ }
- /* empty out the array */
- assoc_clear(array, NULL);
+ name = file_param.str_value.str;
+ array = array_param.array_cookie;
+
+ /* always empty out the array */
+ clear_array(array);
- /* lstat the file, if error, set ERRNO and return */
- (void) force_string(file);
- ret = lstat(file->stptr, & sbuf);
+ /* stat the file, if error, set ERRNO and return */
+ ret = statfunc(name, & sbuf);
if (ret < 0) {
- update_ERRNO();
- return make_number((AWKNUM) ret);
+ update_ERRNO_int(errno);
+ return make_number(ret, result);
}
- /* fill in the array */
- aptr = assoc_lookup(array, tmp = make_string("name", 4));
- *aptr = dupnode(file);
- unref(tmp);
+ ret = fill_stat_array(name, array, & sbuf);
- aptr = assoc_lookup(array, tmp = make_string("dev", 3));
- *aptr = make_number((AWKNUM) sbuf.st_dev);
- unref(tmp);
+ return make_number(ret, result);
+}
- aptr = assoc_lookup(array, tmp = make_string("ino", 3));
- *aptr = make_number((AWKNUM) sbuf.st_ino);
- unref(tmp);
+/* init_filefuncs --- initialization routine */
- aptr = assoc_lookup(array, tmp = make_string("mode", 4));
- *aptr = make_number((AWKNUM) sbuf.st_mode);
- unref(tmp);
+static awk_bool_t
+init_filefuncs(void)
+{
+ int errors = 0;
+ int i;
+ awk_value_t value;
+
+#ifndef __MINGW32__
+ /* at least right now, only FTS needs initializing */
+ static struct flagtab {
+ const char *name;
+ int value;
+ } opentab[] = {
+#define ENTRY(x) { #x, x }
+ ENTRY(FTS_COMFOLLOW),
+ ENTRY(FTS_LOGICAL),
+ ENTRY(FTS_NOCHDIR),
+ ENTRY(FTS_PHYSICAL),
+ ENTRY(FTS_SEEDOT),
+ ENTRY(FTS_XDEV),
+ { NULL, 0 }
+ };
+
+ for (i = 0; opentab[i].name != NULL; i++) {
+ (void) make_number(opentab[i].value, & value);
+ if (! sym_update(opentab[i].name, & value)) {
+ warning(ext_id, _("fts init: could not create variable %s"),
+ opentab[i].name);
+ errors++;
+ }
+ }
+#endif
+ return errors == 0;
+}
- aptr = assoc_lookup(array, tmp = make_string("nlink", 5));
- *aptr = make_number((AWKNUM) sbuf.st_nlink);
- unref(tmp);
+#ifdef __MINGW32__
+/* do_fts --- walk a heirarchy and fill in an array */
- aptr = assoc_lookup(array, tmp = make_string("uid", 3));
- *aptr = make_number((AWKNUM) sbuf.st_uid);
- unref(tmp);
+/*
+ * Usage from awk:
+ * flags = or(FTS_PHYSICAL, ...)
+ * result = fts(pathlist, flags, filedata)
+ */
- aptr = assoc_lookup(array, tmp = make_string("gid", 3));
- *aptr = make_number((AWKNUM) sbuf.st_gid);
- unref(tmp);
+static awk_value_t *
+do_fts(int nargs, awk_value_t *result)
+{
+ fatal(ext_id, _("fts is not supported on this system"));
- aptr = assoc_lookup(array, tmp = make_string("size", 4));
- *aptr = make_number((AWKNUM) sbuf.st_size);
- unref(tmp);
+ return NULL; /* for the compiler */
+}
- aptr = assoc_lookup(array, tmp = make_string("blocks", 6));
- *aptr = make_number((AWKNUM) sbuf.st_blocks);
- unref(tmp);
+#else /* __MINGW32__ */
- aptr = assoc_lookup(array, tmp = make_string("atime", 5));
- *aptr = make_number((AWKNUM) sbuf.st_atime);
- unref(tmp);
+static int fts_errors = 0;
- aptr = assoc_lookup(array, tmp = make_string("mtime", 5));
- *aptr = make_number((AWKNUM) sbuf.st_mtime);
- unref(tmp);
+/* fill_stat_element --- fill in stat element of array */
- aptr = assoc_lookup(array, tmp = make_string("ctime", 5));
- *aptr = make_number((AWKNUM) sbuf.st_ctime);
- unref(tmp);
+static void
+fill_stat_element(awk_array_t element_array, const char *name, struct stat *sbuf)
+{
+ awk_value_t index, value;
+ awk_array_t stat_array;
+
+ stat_array = create_array();
+ if (stat_array == NULL) {
+ warning(ext_id, _("fill_stat_element: could not create array"));
+ fts_errors++;
+ return;
+ }
+ fill_stat_array(name, stat_array, sbuf);
+ (void) make_const_string("stat", 4, & index);
+ value.val_type = AWK_ARRAY;
+ value.array_cookie = stat_array;
+ if (! set_array_element(element_array, & index, & value)) {
+ warning(ext_id, _("fill_stat_element: could not set element"));
+ fts_errors++;
+ }
+}
- /* 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 = make_string("rdev", 4));
- *aptr = make_number((AWKNUM) sbuf.st_rdev);
- unref(tmp);
-
- aptr = assoc_lookup(array, tmp = make_string("major", 5));
- *aptr = make_number((AWKNUM) major(sbuf.st_rdev));
- unref(tmp);
-
- aptr = assoc_lookup(array, tmp = make_string("minor", 5));
- *aptr = make_number((AWKNUM) minor(sbuf.st_rdev));
- unref(tmp);
+/* fill_path_element --- fill in path element of array */
+
+static void
+fill_path_element(awk_array_t element_array, const char *path)
+{
+ awk_value_t index, value;
+
+ (void) make_const_string("path", 4, & index);
+ (void) make_const_string(path, strlen(path), & value);
+ if (! set_array_element(element_array, & index, & value)) {
+ warning(ext_id, _("fill_path_element: could not set element"));
+ fts_errors++;
}
+}
-#ifdef HAVE_ST_BLKSIZE
- aptr = assoc_lookup(array, tmp = make_string("blksize", 7));
- *aptr = make_number((AWKNUM) sbuf.st_blksize);
- unref(tmp);
-#endif /* HAVE_ST_BLKSIZE */
+/* fill_error_element --- fill in error element of array */
- aptr = assoc_lookup(array, tmp = make_string("pmode", 5));
- pmode = format_mode(sbuf.st_mode);
- *aptr = make_string(pmode, strlen(pmode));
- unref(tmp);
+static void
+fill_error_element(awk_array_t element_array, const int errcode)
+{
+ awk_value_t index, value;
+ const char *err = strerror(errcode);
+
+ (void) make_const_string("error", 5, & index);
+ (void) make_const_string(err, strlen(err), & value);
+ if (! set_array_element(element_array, & index, & value)) {
+ warning(ext_id, _("fill_error_element: could not set element"));
+ fts_errors++;
+ }
+}
- /* for symbolic links, add a linkval field */
- if (S_ISLNK(sbuf.st_mode)) {
- char *buf;
- int linksize;
+/* fill_default_elements --- fill in stat and path elements */
+
+static void
+fill_default_elements(awk_array_t element_array, const FTSENT *const fentry, awk_bool_t bad_ret)
+{
+ /* full path */
+ fill_path_element(element_array, fentry->fts_path);
+
+ /* stat info */
+ if (! bad_ret) {
+ fill_stat_element(element_array,
+ fentry->fts_name,
+ fentry->fts_statp);
+ }
+
+ /* error info */
+ if (bad_ret || fentry->fts_errno != 0) {
+ fill_error_element(element_array, fentry->fts_errno);
+ }
+}
+
+/* process --- process the heirarchy */
+
+static void
+process(FTS *heirarchy, awk_array_t destarray, int seedot)
+{
+ FTSENT *fentry;
+ awk_value_t index, value;
+ awk_array_t element_array, newdir_array, dot_array;
+ awk_bool_t bad_ret = awk_false;
+
+ /* path is full path, pathlen is length thereof */
+ /* name is name in directory, namelen is length thereof */
+ while ((fentry = fts_read(heirarchy)) != NULL) {
+ bad_ret = awk_false;
+
+ switch (fentry->fts_info) {
+ case FTS_D:
+ /* directory */
+ /* create array to hold entries */
+ newdir_array = create_array();
+ if (newdir_array == NULL) {
+ warning(ext_id, _("fts-process: could not create array"));
+ fts_errors++;
+ break;
+ }
+
+ /* store new directory in its parent directory */
+ (void) make_const_string(fentry->fts_name, fentry->fts_namelen, & index);
+ value.val_type = AWK_ARRAY;
+ value.array_cookie = newdir_array;
+ if (! set_array_element(destarray, & index, & value)) {
+ warning(ext_id, _("fts-process: could not set element"));
+ fts_errors++;
+ break;
+ }
+ newdir_array = value.array_cookie;
+
+ /* push current directory */
+ stack_push(destarray);
+
+ /* new directory becomes current */
+ destarray = newdir_array;
+ break;
+
+ case FTS_DNR:
+ case FTS_DC:
+ case FTS_ERR:
+ case FTS_NS:
+ /* error */
+ bad_ret = awk_true;
+ /* fall through */
+
+ case FTS_NSOK:
+ case FTS_SL:
+ case FTS_SLNONE:
+ case FTS_F:
+ case FTS_DOT:
+ /* if see dot, skip "." */
+ if (seedot && strcmp(fentry->fts_name, ".") == 0)
+ break;
- emalloc(buf, char *, sbuf.st_size + 2, "do_stat");
- if (((linksize = readlink(file->stptr, buf,
- sbuf.st_size + 2)) >= 0) &&
- (linksize <= sbuf.st_size)) {
/*
- * set the linkval field only if we are able to
- * retrieve the entire link value successfully.
+ * File case.
+ * destarray is the directory we're reading.
+ * step 1: create new empty array
*/
- buf[linksize] = '\0';
-
- aptr = assoc_lookup(array, tmp = make_string("linkval", 7));
- *aptr = make_str_node(buf, linksize, ALREADY_MALLOCED);
- unref(tmp);
+ element_array = create_array();
+ if (element_array == NULL) {
+ warning(ext_id, _("fts-process: could not create array"));
+ fts_errors++;
+ break;
+ }
+
+ /* step 2: add element array to parent array */
+ (void) make_const_string(fentry->fts_name, fentry->fts_namelen, & index);
+ value.val_type = AWK_ARRAY;
+ value.array_cookie = element_array;
+ if (! set_array_element(destarray, & index, & value)) {
+ warning(ext_id, _("fts-process: could not set element"));
+ fts_errors++;
+ break;
+ }
+
+ /* step 3: fill in path, stat, error elements */
+ fill_default_elements(element_array, fentry, bad_ret);
+ break;
+
+ case FTS_DP:
+ /* create "." subarray */
+ dot_array = create_array();
+
+ /* add it to parent */
+ (void) make_const_string(".", 1, & index);
+ value.val_type = AWK_ARRAY;
+ value.array_cookie = dot_array;
+ if (! set_array_element(destarray, & index, & value)) {
+ warning(ext_id, _("fts-process: could not set element"));
+ fts_errors++;
+ break;
+ }
+
+ /* fill it in with path, stat, error elements */
+ fill_default_elements(dot_array, fentry, bad_ret);
+
+ /* now pop the parent directory off the stack */
+ if (! stack_empty()) {
+ /* pop stack */
+ destarray = stack_pop();
+ }
+
+ break;
+
+ case FTS_DEFAULT:
+ /* nothing to do */
+ break;
}
}
+}
- /* 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
+/* do_fts --- walk a heirarchy and fill in an array */
+
+/*
+ * Usage from awk:
+ * flags = or(FTS_PHYSICAL, ...)
+ * result = fts(pathlist, flags, filedata)
+ */
+
+static awk_value_t *
+do_fts(int nargs, awk_value_t *result)
+{
+ awk_value_t pathlist, flagval, dest;
+ awk_flat_array_t *path_array = NULL;
+ char **pathvector = NULL;
+ FTS *heirarchy;
+ int flags;
+ size_t i, count;
+ int ret = -1;
+ static const int mask = (
+ FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR | FTS_PHYSICAL
+ | FTS_SEEDOT | FTS_XDEV);
+
+ assert(result != NULL);
+ fts_errors = 0; /* ensure a fresh start */
+
+ if (do_lint && nargs != 3)
+ lintwarn(ext_id, _("fts: called with incorrect number of arguments, expecting 3"));
+
+ if (! get_argument(0, AWK_ARRAY, & pathlist)) {
+ warning(ext_id, _("fts: bad first parameter"));
+ update_ERRNO_int(EINVAL);
+ goto out;
}
- aptr = assoc_lookup(array, tmp = make_string("type", 4));
- *aptr = make_string(type, strlen(type));
- unref(tmp);
+ if (! get_argument(1, AWK_NUMBER, & flagval)) {
+ warning(ext_id, _("fts: bad second parameter"));
+ update_ERRNO_int(EINVAL);
+ goto out;
+ }
- return make_number((AWKNUM) ret);
-}
+ if (! get_argument(2, AWK_ARRAY, & dest)) {
+ warning(ext_id, _("fts: bad third parameter"));
+ update_ERRNO_int(EINVAL);
+ goto out;
+ }
-/* dlload --- load new builtins in this library */
+ /* flatten pathlist */
+ if (! flatten_array(pathlist.array_cookie, & path_array)) {
+ warning(ext_id, _("fts: could not flatten array\n"));
+ goto out;
+ }
-NODE *
-dlload(NODE *tree, void *dl)
-{
- make_builtin("chdir", do_chdir, 1);
- make_builtin("stat", do_stat, 2);
+ /* check the flags first, before the array flattening */
+
+ /* get flags */
+ flags = flagval.num_value;
+
+ /* enforce physical or logical but not both, and not no_stat */
+ if ((flags & (FTS_PHYSICAL|FTS_LOGICAL)) == 0
+ || (flags & (FTS_PHYSICAL|FTS_LOGICAL)) == (FTS_PHYSICAL|FTS_LOGICAL)) {
+ update_ERRNO_int(EINVAL);
+ goto out;
+ }
+ if ((flags & FTS_NOSTAT) != 0) {
+ flags &= ~FTS_NOSTAT;
+ if (do_lint)
+ lintwarn(ext_id, _("fts: ignoring sneaky FTS_NOSTAT flag. nyah, nyah, nyah."));
+ }
+ flags &= mask; /* turn off anything else */
+
+ /* make pathvector */
+ count = path_array->count + 1;
+ emalloc(pathvector, char **, count * sizeof(char *), "do_fts");
+ memset(pathvector, 0, count * sizeof(char *));
- return make_number((AWKNUM) 0);
+ /* fill it in */
+ count--; /* ignore final NULL at end of vector */
+ for (i = 0; i < count; i++)
+ pathvector[i] = path_array->elements[i].value.str_value.str;
+
+
+ /* clear dest array */
+ if (! clear_array(dest.array_cookie)) {
+ warning(ext_id, _("fts: clear_array() failed\n"));
+ goto out;
+ }
+
+ /* let's do it! */
+ if ((heirarchy = fts_open(pathvector, flags, NULL)) != NULL) {
+ process(heirarchy, dest.array_cookie, (flags & FTS_SEEDOT) != 0);
+ fts_close(heirarchy);
+
+ if (fts_errors == 0)
+ ret = 0;
+ } else
+ update_ERRNO_int(errno);
+
+out:
+ if (pathvector != NULL)
+ gawk_free(pathvector);
+ if (path_array != NULL)
+ (void) release_flattened_array(pathlist.array_cookie, path_array);
+
+ return make_number(ret, result);
}
+#endif /* ! __MINGW32__ */
+
+static awk_ext_func_t func_table[] = {
+ { "chdir", do_chdir, 1 },
+ { "stat", do_stat, 2 },
+#ifndef __MINGW32__
+ { "fts", do_fts, 3 },
+#endif
+};
+
+
+/* define the dl_load function using the boilerplate macro */
+
+dl_load_func(func_table, filefuncs, "")
diff --git a/extension/fnmatch.3am b/extension/fnmatch.3am
new file mode 100644
index 00000000..e2e8391d
--- /dev/null
+++ b/extension/fnmatch.3am
@@ -0,0 +1,125 @@
+.TH FNMATCH 3am "Jan 15 2013" "Free Software Foundation" "GNU Awk Extension Modules"
+.SH NAME
+fnmatch \- compare a string against a filename wildcard
+.SH SYNOPSIS
+.ft CW
+@load "fnmatch"
+.sp
+result = fnmatch(pattern, string, flags)
+.ft R
+.SH DESCRIPTION
+The
+.I fnmatch
+extension provides an AWK interface to the
+.IR fnmatch (3)
+routine. It adds a single function named
+.BR fnmatch() ,
+one predefined variable
+.RB ( FNM_NOMATCH ),
+and an array of flag values named
+.BR FNM .
+.PP
+The first argument is the filename wildcard to match, the second
+is the filename string, and the third is either zero,
+or the bitwise OR of one or more of the flags in the
+.B FNM
+array.
+.PP
+The return value is zero on success,
+.B FNM_NOMATCH
+if the string did not match the pattern, or
+a different non-zero value if an error occurred.
+.PP
+The flags are follows:
+.TP
+\fBFNM["CASEFOLD"]\fP
+Corresponds to the
+.B FNM_CASEFOLD
+flag as defined in
+.IR fnmatch (3).
+.TP
+\fBFNM["FILE_NAME"]\fP
+Corresponds to the
+.B FNM_FILE_NAME
+flag as defined in
+.IR fnmatch (3).
+.TP
+\fBFNM["LEADING_DIR"]\fP
+Corresponds to the
+.B FNM_LEADING_DIR
+flag as defined in
+.IR fnmatch (3).
+.TP
+\fBFNM["NOESCAPE"]\fP
+Corresponds to the
+.B FNM_NOESCAPE
+flag as defined in
+.IR fnmatch (3).
+.TP
+\fBFNM["PATHNAME"]\fP
+Corresponds to the
+.B FNM_PATHNAME
+flag as defined in
+.IR fnmatch (3).
+.TP
+\fBFNM["PERIOD"]\fP
+Corresponds to the
+.B FNM_PERIOD
+flag as defined in
+.IR fnmatch (3).
+.PP
+.SH NOTES
+Nothing prevents AWK code from changing the predefined
+variabale
+.BR FNM_NOMATCH ,
+but doing so may cause strange results.
+... .SH BUGS
+.SH EXAMPLE
+.ft CW
+.nf
+@load "fnmatch"
+\&...
+flags = or(FNM["PERIOD"], FNM["NOESCAPE"])
+if (fnmatch("*.a", "foo.c", flags) == FNM_NOMATCH)
+ print "no match"
+.fi
+.ft R
+.SH "SEE ALSO"
+.IR "GAWK: Effective AWK Programming" ,
+.IR filefuncs (3am),
+.IR fork (3am),
+.IR inplace (3am),
+.IR ordchr (3am),
+.IR readdir (3am),
+.IR readfile (3am),
+.IR revoutput (3am),
+.IR rwarray (3am),
+.IR time (3am).
+.PP
+.IR fnmatch (3).
+.SH AUTHOR
+Arnold Robbins,
+.BR arnold@skeeve.com .
+.SH COPYING PERMISSIONS
+Copyright \(co 2012, 2013,
+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.
diff --git a/extension/fnmatch.c b/extension/fnmatch.c
new file mode 100644
index 00000000..a85bcc78
--- /dev/null
+++ b/extension/fnmatch.c
@@ -0,0 +1,207 @@
+/*
+ * fnmatch.c - Provide an interface to fnmatch(3) routine
+ *
+ * Arnold Robbins
+ * arnold@skeeve.com
+ * Written 7/2012
+ */
+
+/*
+ * Copyright (C) 2012, 2013 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 3 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 HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "gawkapi.h"
+
+#include "gettext.h"
+#define _(msgid) gettext(msgid)
+#define N_(msgid) msgid
+
+#ifdef __VMS
+#define __iswctype iswctype
+#define __btowc btowc
+#endif
+
+#define _GNU_SOURCE 1 /* use GNU extensions if they're there */
+#ifdef HAVE_FNMATCH_H
+#include <fnmatch.h>
+#else
+#ifdef __VMS
+#include "fnmatch.h" /* version that comes with gawk */
+#else
+#include "../missing_d/fnmatch.h" /* version that comes with gawk */
+#endif
+#define HAVE_FNMATCH_H
+#endif
+
+#ifndef HAVE_FNMATCH
+#ifdef __VMS
+#include "fnmatch.c" /* ditto */
+#else
+#include "../missing_d/fnmatch.c" /* ditto */
+#endif
+#define HAVE_FNMATCH
+#endif
+
+/* Provide GNU extensions as no-ops if not defined */
+#ifndef FNM_CASEFOLD
+#define FNM_CASEFOLD 0
+#endif
+#ifndef FNM_LEADING_DIR
+#define FNM_LEADING_DIR 0
+#endif
+#ifndef FNM_FILE_NAME
+#define FNM_FILE_NAME 0
+#endif
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+static const char *ext_version = "fnmatch extension: version 1.0";
+
+static awk_bool_t init_fnmatch(void);
+static awk_bool_t (*init_func)(void) = init_fnmatch;
+
+int plugin_is_GPL_compatible;
+
+
+/* do_fnmatch --- implement the fnmatch interface */
+
+static awk_value_t *
+do_fnmatch(int nargs, awk_value_t *result)
+{
+#ifdef HAVE_FNMATCH_H
+ static int flags_mask =
+ FNM_CASEFOLD | FNM_FILE_NAME |
+ FNM_LEADING_DIR | FNM_NOESCAPE |
+ FNM_PATHNAME | FNM_PERIOD ;
+#endif
+ awk_value_t pattern, string, flags;
+ int int_flags, retval;
+
+ make_number(-1.0, result); /* default return */
+#ifdef HAVE_FNMATCH
+ if (nargs < 3) {
+ warning(ext_id, _("fnmatch: called with less than three arguments"));
+ goto out;
+ } else if (do_lint && nargs > 3)
+ lintwarn(ext_id, _("fnmatch: called with more than three arguments"));
+
+ if (! get_argument(0, AWK_STRING, & pattern)) {
+ warning(ext_id, _("fnmatch: could not get first argument"));
+ goto out;
+ }
+
+ if (! get_argument(1, AWK_STRING, & string)) {
+ warning(ext_id, _("fnmatch: could not get second argument"));
+ goto out;
+ }
+
+ if (! get_argument(2, AWK_NUMBER, & flags)) {
+ warning(ext_id, _("fnmatch: could not get third argument"));
+ goto out;
+ }
+
+ int_flags = flags.num_value;
+ int_flags &= flags_mask;
+
+ retval = fnmatch(pattern.str_value.str,
+ string.str_value.str, int_flags);
+ make_number((double) retval, result);
+
+out:
+#else
+ fatal(ext_id, _("fnmatch is not implemented on this system\n"));
+#endif
+ return result;
+}
+
+#define ENTRY(x) { #x, FNM_##x }
+
+static struct fnmflags {
+ const char *name;
+ int value;
+} flagtable[] = {
+ ENTRY(CASEFOLD),
+ ENTRY(FILE_NAME),
+ ENTRY(LEADING_DIR),
+ ENTRY(NOESCAPE),
+ ENTRY(PATHNAME),
+ ENTRY(PERIOD),
+ { NULL, 0 }
+};
+
+/* init_fnmatch --- load array with flags */
+
+static awk_bool_t
+init_fnmatch(void)
+{
+ int errors = 0;
+#ifdef HAVE_FNMATCH
+ awk_value_t index, value, the_array;
+ awk_array_t new_array;
+ int i;
+
+ if (! sym_update("FNM_NOMATCH", make_number(FNM_NOMATCH, & value))) {
+ warning(ext_id, _("fnmatch init: could not add FNM_NOMATCH variable"));
+ errors++;
+ }
+
+ new_array = create_array();
+ for (i = 0; flagtable[i].name != NULL; i++) {
+ (void) make_const_string(flagtable[i].name,
+ strlen(flagtable[i].name), & index);
+ (void) make_number(flagtable[i].value, & value);
+ if (! set_array_element(new_array, & index, & value)) {
+ warning(ext_id, _("fnmatch init: could not set array element %s"),
+ flagtable[i].name);
+ errors++;
+ }
+ }
+
+ the_array.val_type = AWK_ARRAY;
+ the_array.array_cookie = new_array;
+
+ if (! sym_update("FNM", & the_array)) {
+ warning(ext_id, _("fnmatch init: could not install FNM array"));
+ errors++;
+ }
+
+#endif
+ return errors == 0;
+}
+
+static awk_ext_func_t func_table[] = {
+ { "fnmatch", do_fnmatch, 3 },
+};
+
+/* define the dl_load function using the boilerplate macro */
+
+dl_load_func(func_table, fnmatch, "")
diff --git a/extension/foo.awk b/extension/foo.awk
deleted file mode 100644
index 00a89e5b..00000000
--- a/extension/foo.awk
+++ /dev/null
@@ -1,9 +0,0 @@
-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
-}
diff --git a/extension/fork.3am b/extension/fork.3am
new file mode 100644
index 00000000..c87dada4
--- /dev/null
+++ b/extension/fork.3am
@@ -0,0 +1,98 @@
+.TH FORK 3am "Jan 15 2013" "Free Software Foundation" "GNU Awk Extension Modules"
+.SH NAME
+fork, wait, waitpid \- basic process management
+.SH SYNOPSIS
+.ft CW
+@load "fork"
+.sp
+pid = fork()
+.sp
+ret = waitpid(pid)
+.sp
+ret = wait();
+.ft R
+.SH DESCRIPTION
+The
+.I fork
+extension adds three functions, as follows.
+.TP
+.B fork()
+This function creates a new process. The return value is the zero
+in the child and the process-id number of the child in the parent,
+or \-1 upon error. In the latter case,
+.B ERRNO
+indicates the problem.
+In the child, \fBPROCINFO["pid"]\fP and \fBPROCINFO["ppid"]\fP
+are updated to reflect the correct values.
+.TP
+.B waitpid()
+This function takes a numeric argument, which is the process-id to
+wait for. The return value is that of the
+.IR waitpid (2)
+system call.
+.TP
+.B wait()
+This function waits for the first child to die.
+The return value is that of the
+.IR wait (2)
+system call.
+... .SH NOTES
+.SH BUGS
+There is no corresponding
+.B exec()
+function.
+.PP
+The interfaces could be enhanced to provide more facilities,
+including pulling out the various bits of the return status.
+.SH EXAMPLE
+.ft CW
+.nf
+@load "fork"
+\&...
+if ((pid = fork()) == 0)
+ print "hello from the child"
+else
+ print "hello from the parent"
+.fi
+.ft R
+.SH "SEE ALSO"
+.IR "GAWK: Effective AWK Programming" ,
+.IR filefuncs (3am),
+.IR fnmatch (3am),
+.IR inplace (3am),
+.IR ordchr (3am),
+.IR readdir (3am),
+.IR readfile (3am),
+.IR revoutput (3am),
+.IR rwarray (3am),
+.IR time (3am).
+.PP
+.IR fork (2),
+.IR wait (2),
+.IR waitpid (2).
+.SH AUTHOR
+Arnold Robbins,
+.BR arnold@skeeve.com .
+.SH COPYING PERMISSIONS
+Copyright \(co 2012, 2013,
+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.
diff --git a/extension/fork.c b/extension/fork.c
index 88353879..0ca0a0e0 100644
--- a/extension/fork.c
+++ b/extension/fork.c
@@ -2,10 +2,11 @@
* fork.c - Provide fork and waitpid functions for gawk.
*
* Revised 6/2004
+ * Revised 5/2012 for new extension API.
*/
/*
- * Copyright (C) 2001, 2004, 2011 the Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2004, 2011, 2012, 2013 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -25,80 +26,136 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "awk.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "gawkapi.h"
+
+#include "gettext.h"
+#define _(msgid) gettext(msgid)
+#define N_(msgid) msgid
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+static const char *ext_version = "fork extension: version 1.0";
+static awk_bool_t (*init_func)(void) = NULL;
int plugin_is_GPL_compatible;
+
+/* array_set --- set an array element */
+
+static void
+array_set_numeric(awk_array_t array, const char *sub, double num)
+{
+ awk_value_t index, value;
+
+ set_array_element(array,
+ make_const_string(sub, strlen(sub), & index),
+ make_number(num, & value));
+
+}
+
/* do_fork --- provide dynamically loaded fork() builtin for gawk */
-static NODE *
-do_fork(int nargs)
+static awk_value_t *
+do_fork(int nargs, awk_value_t *result)
{
int ret = -1;
- NODE **aptr;
- NODE *tmp;
- if (do_lint && nargs > 0)
- lintwarn("fork: called with too many arguments");
+ assert(result != NULL);
+
+ if (do_lint && nargs > 0)
+ lintwarn(ext_id, _("fork: called with too many arguments"));
ret = fork();
if (ret < 0)
- update_ERRNO();
+ update_ERRNO_int(errno);
else if (ret == 0) {
- /* update PROCINFO in the child */
-
- aptr = assoc_lookup(PROCINFO_node, tmp = make_string("pid", 3));
- (*aptr)->numbr = (AWKNUM) getpid();
- unref(tmp);
-
- aptr = assoc_lookup(PROCINFO_node, tmp = make_string("ppid", 4));
- (*aptr)->numbr = (AWKNUM) getppid();
- unref(tmp);
+ /* update PROCINFO in the child, if the array exists */
+ awk_value_t procinfo;
+
+ if (sym_lookup("PROCINFO", AWK_ARRAY, & procinfo)) {
+ if (procinfo.val_type != AWK_ARRAY) {
+ if (do_lint)
+ lintwarn(ext_id, _("fork: PROCINFO is not an array!"));
+ } else {
+ array_set_numeric(procinfo.array_cookie, "pid", getpid());
+ array_set_numeric(procinfo.array_cookie, "ppid", getppid());
+ }
+ }
}
/* Set the return value */
- return make_number((AWKNUM) ret);
+ return make_number(ret, result);
}
-
/* do_waitpid --- provide dynamically loaded waitpid() builtin for gawk */
-static NODE *
-do_waitpid(int nargs)
+static awk_value_t *
+do_waitpid(int nargs, awk_value_t *result)
{
- NODE *pidnode;
+ awk_value_t pid;
int ret = -1;
- double pidval;
- pid_t pid;
int options = 0;
- if (do_lint && nargs > 1)
- lintwarn("waitpid: called with too many arguments");
+ assert(result != NULL);
- pidnode = get_scalar_argument(0, FALSE);
- if (pidnode != NULL) {
- pidval = force_number(pidnode);
- pid = (int) pidval;
+ if (do_lint && nargs > 1)
+ lintwarn(ext_id, _("waitpid: called with too many arguments"));
+
+ if (get_argument(0, AWK_NUMBER, &pid)) {
options = WNOHANG|WUNTRACED;
- ret = waitpid(pid, NULL, options);
+ ret = waitpid(pid.num_value, NULL, options);
if (ret < 0)
- update_ERRNO();
+ update_ERRNO_int(errno);
} else if (do_lint)
- lintwarn("wait: called with no arguments");
+ lintwarn(ext_id, _("wait: called with no arguments"));
/* Set the return value */
- return make_number((AWKNUM) ret);
+ return make_number(ret, result);
}
-/* dlload --- load new builtins in this library */
-NODE *
-dlload(tree, dl)
-NODE *tree;
-void *dl;
+/* do_wait --- provide dynamically loaded wait() builtin for gawk */
+
+static awk_value_t *
+do_wait(int nargs, awk_value_t *result)
{
- make_builtin("fork", do_fork, 0);
- make_builtin("waitpid", do_waitpid, 1);
- return make_number((AWKNUM) 0);
+ int ret;
+
+ assert(result != NULL);
+
+ if (do_lint && nargs > 0)
+ lintwarn(ext_id, _("wait: called with too many arguments"));
+
+ ret = wait(NULL);
+ if (ret < 0)
+ update_ERRNO_int(errno);
+
+ /* Set the return value */
+ return make_number(ret, result);
}
+
+static awk_ext_func_t func_table[] = {
+ { "fork", do_fork, 0 },
+ { "waitpid", do_waitpid, 1 },
+ { "wait", do_wait, 0 },
+};
+
+/* define the dl_load function using the boilerplate macro */
+
+dl_load_func(func_table, fork, "")
diff --git a/extension/fts.3 b/extension/fts.3
new file mode 100644
index 00000000..9131d04f
--- /dev/null
+++ b/extension/fts.3
@@ -0,0 +1,773 @@
+.\" $NetBSD: fts.3,v 1.30 2011/03/30 16:29:26 jruoho Exp $
+.\"
+.\" Copyright (c) 1989, 1991, 1993, 1994
+.\" 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. 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.
+.\"
+.\" @(#)fts.3 8.5 (Berkeley) 4/16/94
+.\"
+.Dd March 30, 2011
+.Dt FTS 3
+.Os
+.Sh NAME
+.Nm fts ,
+.Nm fts_open ,
+.Nm fts_read ,
+.Nm fts_children ,
+.Nm fts_set ,
+.Nm fts_close
+.Nd traverse a file hierarchy
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/stat.h
+.In fts.h
+.Ft FTS *
+.Fo fts_open
+.Fa "char * const *path_argv"
+.Fa "int options"
+.Fa "int (*compar)(const FTSENT **, const FTSENT **)"
+.Fc
+.Ft FTSENT *
+.Fn fts_read "FTS *ftsp"
+.Ft FTSENT *
+.Fn fts_children "FTS *ftsp" "int options"
+.Ft int
+.Fn fts_set "FTS *ftsp" "FTSENT *f" "int options"
+.Ft int
+.Fn fts_close "FTS *ftsp"
+.Sh DESCRIPTION
+The
+.Nm
+functions are provided for traversing
+.Ux
+file hierarchies.
+A simple overview is that the
+.Fn fts_open
+function returns a
+.Dq handle
+on a file hierarchy, which is then supplied to
+the other
+.Nm
+functions.
+The function
+.Fn fts_read
+returns a pointer to a structure describing one of the files in the file
+hierarchy.
+The function
+.Fn fts_children
+returns a pointer to a linked list of structures, each of which describes
+one of the files contained in a directory in the hierarchy.
+In general, directories are visited two distinguishable times; in pre-order
+(before any of their descendants are visited) and in post-order (after all
+of their descendants have been visited).
+Files are visited once.
+It is possible to walk the hierarchy
+.Dq logically
+(ignoring symbolic links)
+or physically (visiting symbolic links), order the walk of the hierarchy or
+prune and/or re-visit portions of the hierarchy.
+.Pp
+Two structures are defined (and typedef'd) in the include file
+.In fts.h .
+The first is
+.Fa FTS ,
+the structure that represents the file hierarchy itself.
+The second is
+.Fa FTSENT ,
+the structure that represents a file in the file
+hierarchy.
+Normally, an
+.Fa FTSENT
+structure is returned for every file in the file
+hierarchy.
+In this manual page,
+.Dq file
+and
+.Dq Fa FTSENT No structure
+are generally
+interchangeable.
+The
+.Fa FTSENT
+structure contains at least the following fields, which are
+described in greater detail below:
+.Bd -literal -offset 2n
+typedef struct _ftsent {
+ u_short fts_info; /* flags for FTSENT structure */
+ char *fts_accpath; /* access path */
+ char *fts_path; /* root path */
+ short fts_pathlen; /* strlen(fts_path) */
+ char *fts_name; /* file name */
+ short fts_namelen; /* strlen(fts_name) */
+ short fts_level; /* depth (\-1 to N) */
+ int fts_errno; /* file errno */
+ long fts_number; /* local numeric value */
+ void *fts_pointer; /* local address value */
+ struct ftsent *fts_parent; /* parent directory */
+ struct ftsent *fts_link; /* next file structure */
+ struct ftsent *fts_cycle; /* cycle structure */
+ struct stat *fts_statp; /* stat(2) information */
+} FTSENT;
+.Ed
+.Pp
+These fields are defined as follows:
+.Bl -tag -width "fts_namelen"
+.It Fa fts_info
+One of the following flags describing the returned
+.Fa FTSENT
+structure and
+the file it represents.
+With the exception of directories without errors
+.Pq Dv FTS_D ,
+all of these
+entries are terminal, that is, they will not be revisited, nor will any
+of their descendants be visited.
+.Bl -tag -width FTS_DEFAULT
+.It Dv FTS_D
+A directory being visited in pre-order.
+.It Dv FTS_DC
+A directory that causes a cycle in the tree.
+(The
+.Fa fts_cycle
+field of the
+.Fa FTSENT
+structure will be filled in as well).
+.It Dv FTS_DEFAULT
+Any
+.Fa FTSENT
+structure that represents a file type not explicitly described
+by one of the other
+.Fa fts_info
+values.
+.It Dv FTS_DNR
+A directory which cannot be read.
+This is an error return, and the
+.Fa fts_errno
+field will be set to indicate what caused the error.
+.It Dv FTS_DOT
+A file named
+.Ql \&.
+or
+.Ql ..
+which was not specified as a file name to
+.Fn fts_open
+(see
+.Dv FTS_SEEDOT ) .
+.It Dv FTS_DP
+A directory being visited in post-order.
+The contents of the
+.Fa FTSENT
+structure will be unchanged from when
+it was returned in pre-order, i.e., with the
+.Fa fts_info
+field set to
+.Dv FTS_D .
+.It Dv FTS_ERR
+This is an error return, and the
+.Fa fts_errno
+field will be set to indicate what caused the error.
+.It Dv FTS_F
+A regular file.
+.It Dv FTS_NS
+A file for which no
+.Xr stat 2
+information was available.
+The contents of the
+.Fa fts_statp
+field are undefined.
+This is an error return, and the
+.Fa fts_errno
+field will be set to indicate what caused the error.
+.It Dv FTS_NSOK
+A file for which no
+.Xr stat 2
+information was requested.
+The contents of the
+.Fa fts_statp
+field are undefined.
+.It Dv FTS_SL
+A symbolic link.
+.It Dv FTS_SLNONE
+A symbolic link with a non-existent target.
+The contents of the
+.Fa fts_statp
+field reference the file characteristic information for the symbolic link
+itself.
+.It Dv FTS_W
+A whiteout object.
+.El
+.It Fa fts_accpath
+A path for accessing the file from the current directory.
+.It Fa fts_path
+The path for the file relative to the root of the traversal.
+This path contains the path specified to
+.Fn fts_open
+as a prefix.
+.It Fa fts_pathlen
+The length of the string referenced by
+.Fa fts_path .
+.It Fa fts_name
+The name of the file.
+.It Fa fts_namelen
+The length of the string referenced by
+.Fa fts_name .
+.It Fa fts_level
+The depth of the traversal, numbered from \-1 to N, where this file
+was found.
+The
+.Fa FTSENT
+structure representing the parent of the starting point (or root)
+of the traversal is numbered \-1, and the
+.Fa FTSENT
+structure for the root
+itself is numbered 0.
+.It Fa fts_errno
+Upon return of a
+.Fa FTSENT
+structure from the
+.Fn fts_children
+or
+.Fn fts_read
+functions, with its
+.Fa fts_info
+field set to
+.Dv FTS_DNR ,
+.Dv FTS_ERR
+or
+.Dv FTS_NS ,
+the
+.Fa fts_errno
+field contains the value of the external variable
+.Va errno
+specifying the cause of the error.
+Otherwise, the contents of the
+.Fa fts_errno
+field are undefined.
+.It Fa fts_number
+This field is provided for the use of the application program and is
+not modified by the
+.Nm
+functions.
+It is initialized to 0.
+.It Fa fts_pointer
+This field is provided for the use of the application program and is
+not modified by the
+.Nm
+functions.
+It is initialized to
+.Dv NULL .
+.It Fa fts_parent
+A pointer to the
+.Fa FTSENT
+structure referencing the file in the hierarchy
+immediately above the current file, i.e., the directory of which this
+file is a member.
+A parent structure for the initial entry point is provided as well,
+however, only the
+.Fa fts_level ,
+.Fa fts_number
+and
+.Fa fts_pointer
+fields are guaranteed to be initialized.
+.It Fa fts_link
+Upon return from the
+.Fn fts_children
+function, the
+.Fa fts_link
+field points to the next structure in the
+.Dv NULL Ns -terminated
+linked list of directory members.
+Otherwise, the contents of the
+.Fa fts_link
+field are undefined.
+.It Fa fts_cycle
+If a directory causes a cycle in the hierarchy (see
+.Dv FTS_DC ) ,
+either because
+of a hard link between two directories, or a symbolic link pointing to a
+directory, the
+.Fa fts_cycle
+field of the structure will point to the
+.Fa FTSENT
+structure in the hierarchy that references the same file as the current
+.Fa FTSENT
+structure.
+Otherwise, the contents of the
+.Fa fts_cycle
+field are undefined.
+.It Fa fts_statp
+A pointer to
+.Xr stat 2
+information for the file.
+.El
+.Pp
+A single buffer is used for all of the paths of all of the files in the
+file hierarchy.
+Therefore, the
+.Fa fts_path
+and
+.Fa fts_accpath
+fields are guaranteed to be
+.Dv NULL Ns -terminated
+.Em only
+for the file most recently returned by
+.Fn fts_read .
+To use these fields to reference any files represented by other
+.Fa FTSENT
+structures will require that the path buffer be modified using the
+information contained in that
+.Fa FTSENT
+structure's
+.Fa fts_pathlen
+field.
+Any such modifications should be undone before further calls to
+.Fn fts_read
+are attempted.
+The
+.Fa fts_name
+field is always
+.Dv NULL Ns -terminated .
+.Sh FTS_OPEN
+The
+.Fn fts_open
+function takes a pointer to an array of character pointers naming one
+or more paths which make up a logical file hierarchy to be traversed.
+The array must be terminated by a
+.Dv NULL
+pointer.
+.Pp
+There are
+a number of options, at least one of which (either
+.Dv FTS_LOGICAL
+or
+.Dv FTS_PHYSICAL )
+must be specified.
+The options are selected by
+.Em or Ns 'ing
+the following values:
+.Bl -tag -width "FTS_COMFOLLOW "
+.It Dv FTS_COMFOLLOW
+This option causes any symbolic link specified as a root path to be
+followed immediately whether or not
+.Dv FTS_LOGICAL
+is also specified.
+.It Dv FTS_LOGICAL
+This option causes the
+.Nm
+routines to return
+.Fa FTSENT
+structures for the targets of symbolic links
+instead of the symbolic links themselves.
+If this option is set, the only symbolic links for which
+.Fa FTSENT
+structures
+are returned to the application are those referencing non-existent files.
+Either
+.Dv FTS_LOGICAL
+or
+.Dv FTS_PHYSICAL
+.Em must
+be provided to the
+.Fn fts_open
+function.
+.It Dv FTS_NOCHDIR
+As a performance optimization, the
+.Nm
+functions change directories as they walk the file hierarchy.
+This has the side-effect that an application cannot rely on being
+in any particular directory during the traversal.
+The
+.Dv FTS_NOCHDIR
+option turns off this optimization, and the
+.Nm
+functions will not change the current directory.
+Note that applications should not themselves change their current directory
+and try to access files unless
+.Dv FTS_NOCHDIR
+is specified and absolute
+pathnames were provided as arguments to
+.Fn fts_open .
+.It Dv FTS_NOSTAT
+By default, returned
+.Fa FTSENT
+structures reference file characteristic information (the
+.Fa statp
+field) for each file visited.
+This option relaxes that requirement as a performance optimization,
+allowing the
+.Nm
+functions to set the
+.Fa fts_info
+field to
+.Dv FTS_NSOK
+and leave the contents of the
+.Fa statp
+field undefined.
+.It Dv FTS_PHYSICAL
+This option causes the
+.Nm
+routines to return
+.Fa FTSENT
+structures for symbolic links themselves instead
+of the target files they point to.
+If this option is set,
+.Fa FTSENT
+structures for all symbolic links in the
+hierarchy are returned to the application.
+Either
+.Dv FTS_LOGICAL
+or
+.Dv FTS_PHYSICAL
+.Em must
+be provided to the
+.Fn fts_open
+function.
+.It Dv FTS_SEEDOT
+By default, unless they are specified as path arguments to
+.Fn fts_open ,
+any files named
+.Ql \&.
+or
+.Ql ..
+encountered in the file hierarchy are ignored.
+This option causes the
+.Nm
+routines to return
+.Fa FTSENT
+structures for them.
+.It Dv FTS_WHITEOUT
+Return whiteout entries, which are normally hidden.
+.It Dv FTS_XDEV
+This option prevents
+.Nm
+from descending into directories that have a different device number
+than the file from which the descent began.
+.El
+.Pp
+The argument
+.Fn compar
+specifies a user-defined function which may be used to order the traversal
+of the hierarchy.
+It
+takes two pointers to pointers to
+.Fa FTSENT
+structures as arguments and
+should return a negative value, zero, or a positive value to indicate
+if the file referenced by its first argument comes before, in any order
+with respect to, or after, the file referenced by its second argument.
+The
+.Fa fts_accpath ,
+.Fa fts_path
+and
+.Fa fts_pathlen
+fields of the
+.Fa FTSENT
+structures may
+.Em never
+be used in this comparison.
+If the
+.Fa fts_info
+field is set to
+.Dv FTS_NS
+or
+.Dv FTS_NSOK ,
+the
+.Fa fts_statp
+field may not either.
+If the
+.Fn compar
+argument is
+.Dv NULL ,
+the directory traversal order is in the order listed in
+.Fa path_argv
+for the root paths, and in the order listed in the directory for
+everything else.
+.Sh FTS_READ
+The
+.Fn fts_read
+function returns a pointer to an
+.Fa FTSENT
+structure describing a file in
+the hierarchy.
+Directories (that are readable and do not cause cycles) are visited at
+least twice, once in pre-order and once in post-order.
+All other files are visited at least once.
+(Hard links between directories that do not cause cycles or symbolic
+links to symbolic links may cause files to be visited more than once,
+or directories more than twice.)
+.Pp
+If all the members of the hierarchy have been returned,
+.Fn fts_read
+returns
+.Dv NULL
+and sets the external variable
+.Va errno
+to 0.
+If an error unrelated to a file in the hierarchy occurs,
+.Fn fts_read
+returns
+.Dv NULL
+and sets
+.Va errno
+appropriately.
+If an error related to a returned file occurs, a pointer to an
+.Fa FTSENT
+structure is returned, and
+.Va errno
+may or may not have been set (see
+.Fa fts_info ) .
+.Pp
+The
+.Fa FTSENT
+structures returned by
+.Fn fts_read
+may be overwritten after a call to
+.Fn fts_close
+on the same file hierarchy stream, or, after a call to
+.Fn fts_read
+on the same file hierarchy stream unless they represent a file of type
+directory, in which case they will not be overwritten until after a call to
+.Fn fts_read
+after the
+.Fa FTSENT
+structure has been returned by the function
+.Fn fts_read
+in post-order.
+.Sh FTS_CHILDREN
+The
+.Fn fts_children
+function returns a pointer to an
+.Fa FTSENT
+structure describing the first entry in a
+.Dv NULL Ns -terminated
+linked list of the files in the directory represented by the
+.Fa FTSENT
+structure most recently returned by
+.Fn fts_read .
+The list is linked through the
+.Fa fts_link
+field of the
+.Fa FTSENT
+structure, and is ordered by the user-specified comparison function, if any.
+Repeated calls to
+.Fn fts_children
+will recreate this linked list.
+.Pp
+As a special case, if
+.Fn fts_read
+has not yet been called for a hierarchy,
+.Fn fts_children
+will return a pointer to the files in the logical directory specified to
+.Fn fts_open ,
+i.e., the arguments specified to
+.Fn fts_open .
+Otherwise, if the
+.Fa FTSENT
+structure most recently returned by
+.Fn fts_read
+is not a directory being visited in pre-order,
+or the directory does not contain any files,
+.Fn fts_children
+returns
+.Dv NULL
+and sets
+.Va errno
+to zero.
+If an error occurs,
+.Fn fts_children
+returns
+.Dv NULL
+and sets
+.Va errno
+appropriately.
+.Pp
+The
+.Fa FTSENT
+structures returned by
+.Fn fts_children
+may be overwritten after a call to
+.Fn fts_children ,
+.Fn fts_close
+or
+.Fn fts_read
+on the same file hierarchy stream.
+.Pp
+.Em Option
+may be set to the following value:
+.Bl -tag -width "FTS_COMFOLLOW "
+.It Dv FTS_NAMEONLY
+Only the names of the files are needed.
+The contents of all the fields in the returned linked list of structures
+are undefined with the exception of the
+.Fa fts_name
+and
+.Fa fts_namelen
+fields.
+.El
+.Sh FTS_SET
+The function
+.Fn fts_set
+allows the user application to determine further processing for the
+file
+.Fa f
+of the stream
+.Fa ftsp .
+The
+.Fn fts_set
+function
+returns 0 on success, and \-1 if an error occurs.
+.Em Option
+must be set to one of the following values:
+.Bl -tag -width "FTS_COMFOLLOW "
+.It Dv FTS_AGAIN
+Re-visit the file; any file type may be re-visited.
+The next call to
+.Fn fts_read
+will return the referenced file.
+The
+.Fa fts_stat
+and
+.Fa fts_info
+fields of the structure will be reinitialized at that time,
+but no other fields will have been changed.
+This option is meaningful only for the most recently returned
+file from
+.Fn fts_read .
+Normal use is for post-order directory visits, where it causes the
+directory to be re-visited (in both pre and post-order) as well as all
+of its descendants.
+.It Dv FTS_FOLLOW
+The referenced file must be a symbolic link.
+If the referenced file is the one most recently returned by
+.Fn fts_read ,
+the next call to
+.Fn fts_read
+returns the file with the
+.Fa fts_info
+and
+.Fa fts_statp
+fields reinitialized to reflect the target of the symbolic link instead
+of the symbolic link itself.
+If the file is one of those most recently returned by
+.Fn fts_children ,
+the
+.Fa fts_info
+and
+.Fa fts_statp
+fields of the structure, when returned by
+.Fn fts_read ,
+will reflect the target of the symbolic link instead of the symbolic link
+itself.
+In either case, if the target of the symbolic link does not exist the
+fields of the returned structure will be unchanged and the
+.Fa fts_info
+field will be set to
+.Dv FTS_SLNONE .
+.Pp
+If the target of the link is a directory, the pre-order return, followed
+by the return of all of its descendants, followed by a post-order return,
+is done.
+.It Dv FTS_SKIP
+No descendants of this file are visited.
+The file may be one of those most recently returned by either
+.Fn fts_children
+or
+.Fn fts_read .
+.El
+.Sh FTS_CLOSE
+The
+.Fn fts_close
+function closes a file hierarchy stream
+.Fa ftsp
+and restores the current directory to the directory from which
+.Fn fts_open
+was called to open
+.Fa ftsp .
+The
+.Fn fts_close
+function
+returns 0 on success, and \-1 if an error occurs.
+.Sh ERRORS
+The function
+.Fn fts_open
+may fail and set
+.Va errno
+for any of the errors specified for the library functions
+.Xr open 2
+and
+.Xr malloc 3 .
+.Pp
+The function
+.Fn fts_close
+may fail and set
+.Va errno
+for any of the errors specified for the library functions
+.Xr chdir 2
+and
+.Xr close 2 .
+.Pp
+The functions
+.Fn fts_read
+and
+.Fn fts_children
+may fail and set
+.Va errno
+for any of the errors specified for the library functions
+.Xr chdir 2 ,
+.Xr malloc 3 ,
+.Xr opendir 3 ,
+.Xr readdir 3
+and
+.Xr stat 2 .
+.Pp
+In addition,
+.Fn fts_children ,
+.Fn fts_open
+and
+.Fn fts_set
+may fail and set
+.Va errno
+as follows:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The options were invalid.
+.El
+.Sh SEE ALSO
+.Xr find 1 ,
+.Xr chdir 2 ,
+.Xr stat 2 ,
+.Xr qsort 3 ,
+.Xr symlink 7
+.Sh STANDARDS
+The
+.Nm
+utility was expected to be included in the
+.St -p1003.1-88
+revision.
+But twenty years later, it still was not included in the
+.St -p1003.1-2008
+revision.
diff --git a/extension/gawkdirfd.h b/extension/gawkdirfd.h
new file mode 100644
index 00000000..d1edf65f
--- /dev/null
+++ b/extension/gawkdirfd.h
@@ -0,0 +1,57 @@
+/* dirfd.c -- return the file descriptor associated with an open DIR*
+
+ Copyright (C) 2001, 2006, 2008-2013 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Jim Meyering. */
+
+/* Modified for gawk */
+
+#include <config.h>
+
+#ifndef ENOTSUP
+# define ENOTSUP ENOSYS
+#endif
+
+/*
+ * This is for fake directory file descriptors on systems that don't
+ * allow to open() a directory.
+ *
+ * Including a header from the main gawk source to share the definition
+ * of FAKE_FD_VALUE is the least of all evils that I can see.
+ *
+ * Unlike the main gawk code base, this include is NOT dependant
+ * upon MinGW or EMX.
+ */
+#ifndef __VMS
+#include "../nonposix.h"
+#else
+#include "nonposix.h"
+#endif
+
+#ifndef DIR_TO_FD
+# define DIR_TO_FD(d) (FAKE_FD_VALUE)
+#endif
+
+#if !defined(HAVE_DIRFD) && (!defined(HAVE_DECL_DIRFD) || HAVE_DECL_DIRFD == 0)
+int
+dirfd (DIR *dir_p)
+{
+ int fd = DIR_TO_FD (dir_p);
+ if (fd == -1)
+ errno = ENOTSUP;
+ return fd;
+}
+#endif /* HAVE_DIRFD */
diff --git a/extension/gawkfts.c b/extension/gawkfts.c
new file mode 100644
index 00000000..4a712153
--- /dev/null
+++ b/extension/gawkfts.c
@@ -0,0 +1,1263 @@
+/* $NetBSD: fts.c,v 1.44 2012/03/14 00:25:19 christos Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * 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. 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
+static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94";
+#else
+/* __RCSID("$NetBSD: fts.c,v 1.44 2012/03/14 00:25:19 christos Exp $"); */
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _BSD_SOURCE
+
+#include <limits.h>
+/* #include "namespace.h" */
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#else
+#include <stdio.h>
+#endif
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "gawkfts.h"
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "gawkdirfd.h"
+
+#if ! defined(S_ISREG) && defined(S_IFREG)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+
+/*
+#if ! HAVE_NBTOOL_CONFIG_H
+#define HAVE_STRUCT_DIRENT_D_NAMLEN
+#endif
+*/
+
+#ifndef MAX
+static int MAX(int x, int y)
+{
+ if (x > y)
+ return x;
+
+ return y;
+}
+#endif
+
+
+static FTSENT *fts_alloc(FTS *, const char *, size_t);
+static FTSENT *fts_build(FTS *, int);
+static void fts_free(FTSENT *);
+static void fts_lfree(FTSENT *);
+static void fts_load(FTS *, FTSENT *);
+static size_t fts_maxarglen(char * const *);
+static size_t fts_pow2(size_t);
+static int fts_palloc(FTS *, size_t);
+static void fts_padjust(FTS *, FTSENT *);
+static FTSENT *fts_sort(FTS *, FTSENT *, size_t);
+static unsigned short fts_stat(FTS *, FTSENT *, int);
+static int fts_safe_changedir(const FTS *, const FTSENT *, int,
+ const char *);
+
+#if defined(ALIGNBYTES) && defined(ALIGN)
+#define FTS_ALLOC_ALIGNED 1
+#else
+#undef FTS_ALLOC_ALIGNED
+#endif
+
+#ifndef ftsent_namelen_truncate
+#define ftsent_namelen_truncate(a) \
+ ((a) > UINT_MAX ? UINT_MAX : (unsigned int)(a))
+#endif
+#ifndef ftsent_pathlen_truncate
+#define ftsent_pathlen_truncate(a) \
+ ((a) > UINT_MAX ? UINT_MAX : (unsigned int)(a))
+#endif
+#ifndef fts_pathlen_truncate
+#define fts_pathlen_truncate(a) \
+ ((a) > UINT_MAX ? UINT_MAX : (unsigned int)(a))
+#endif
+#ifndef fts_nitems_truncate
+#define fts_nitems_truncate(a) \
+ ((a) > UINT_MAX ? UINT_MAX : (unsigned int)(a))
+#endif
+
+#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
+
+#define CLR(opt) (sp->fts_options &= ~(opt))
+#define ISSET(opt) (sp->fts_options & (opt))
+#define SET(opt) (sp->fts_options |= (opt))
+
+#define CHDIR(sp, path) (!ISSET(FTS_NOCHDIR) && chdir(path))
+#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
+
+/* fts_build flags */
+#define BCHILD 1 /* fts_children */
+#define BNAMES 2 /* fts_children, names only */
+#define BREAD 3 /* fts_read */
+
+#ifndef DTF_HIDEW
+#undef FTS_WHITEOUT
+#endif
+
+#define _DIAGASSERT(expression)
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024 /* a guess */
+#endif
+
+FTS *
+fts_open(char * const *argv, int options,
+ int (*compar)(const FTSENT **, const FTSENT **))
+{
+ FTS *sp;
+ FTSENT *p, *root;
+ size_t nitems;
+ FTSENT *parent, *tmp = NULL; /* pacify gcc */
+ size_t len;
+
+ _DIAGASSERT(argv != NULL);
+
+ /* Options check. */
+ if (options & ~FTS_OPTIONMASK) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ /* Allocate/initialize the stream */
+ if ((sp = malloc((unsigned int)sizeof(FTS))) == NULL)
+ return (NULL);
+ memset(sp, 0, sizeof(FTS));
+ sp->fts_compar = compar;
+ sp->fts_options = options;
+
+ /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
+ if (ISSET(FTS_LOGICAL))
+ SET(FTS_NOCHDIR);
+
+ /*
+ * Start out with 1K of path space, and enough, in any case,
+ * to hold the user's paths.
+ */
+ if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN)))
+ goto mem1;
+
+ /* Allocate/initialize root's parent. */
+ if ((parent = fts_alloc(sp, "", 0)) == NULL)
+ goto mem2;
+ parent->fts_level = FTS_ROOTPARENTLEVEL;
+
+ /* Allocate/initialize root(s). */
+ for (root = NULL, nitems = 0; *argv; ++argv, ++nitems) {
+ /* Don't allow zero-length paths. */
+ if ((len = strlen(*argv)) == 0) {
+ errno = ENOENT;
+ goto mem3;
+ }
+
+ if ((p = fts_alloc(sp, *argv, len)) == NULL)
+ goto mem3;
+ p->fts_level = FTS_ROOTLEVEL;
+ p->fts_parent = parent;
+ p->fts_accpath = p->fts_name;
+ p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW));
+
+ /* Command-line "." and ".." are real directories. */
+ if (p->fts_info == FTS_DOT)
+ p->fts_info = FTS_D;
+
+ /*
+ * If comparison routine supplied, traverse in sorted
+ * order; otherwise traverse in the order specified.
+ */
+ if (compar) {
+ p->fts_link = root;
+ root = p;
+ } else {
+ p->fts_link = NULL;
+ if (root == NULL)
+ tmp = root = p;
+ else {
+ tmp->fts_link = p;
+ tmp = p;
+ }
+ }
+ }
+ if (compar && nitems > 1)
+ root = fts_sort(sp, root, nitems);
+
+ /*
+ * Allocate a dummy pointer and make fts_read think that we've just
+ * finished the node before the root(s); set p->fts_info to FTS_INIT
+ * so that everything about the "current" node is ignored.
+ */
+ if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
+ goto mem3;
+ sp->fts_cur->fts_link = root;
+ sp->fts_cur->fts_info = FTS_INIT;
+
+ /*
+ * If using chdir(2), grab a file descriptor pointing to dot to insure
+ * that we can get back here; this could be avoided for some paths,
+ * but almost certainly not worth the effort. Slashes, symbolic links,
+ * and ".." are all fairly nasty problems. Note, if we can't get the
+ * descriptor we run anyway, just more slowly.
+ */
+#ifndef O_CLOEXEC
+#define O_CLOEXEC 0
+#endif
+ if (!ISSET(FTS_NOCHDIR)) {
+ if ((sp->fts_rfd = open(".", O_RDONLY | O_CLOEXEC, 0)) == -1)
+ SET(FTS_NOCHDIR);
+ }
+
+ if (nitems == 0)
+ fts_free(parent);
+
+ return (sp);
+
+mem3: fts_lfree(root);
+ fts_free(parent);
+mem2: free(sp->fts_path);
+mem1: free(sp);
+ return (NULL);
+}
+
+static void
+fts_load(FTS *sp, FTSENT *p)
+{
+ size_t len;
+ char *cp;
+
+ _DIAGASSERT(sp != NULL);
+ _DIAGASSERT(p != NULL);
+
+ /*
+ * Load the stream structure for the next traversal. Since we don't
+ * actually enter the directory until after the preorder visit, set
+ * the fts_accpath field specially so the chdir gets done to the right
+ * place and the user can access the first node. From fts_open it's
+ * known that the path will fit.
+ */
+ len = p->fts_pathlen = p->fts_namelen;
+ memmove(sp->fts_path, p->fts_name, len + 1);
+ if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) {
+ len = strlen(++cp);
+ memmove(p->fts_name, cp, len + 1);
+ p->fts_namelen = ftsent_namelen_truncate(len);
+ }
+ p->fts_accpath = p->fts_path = sp->fts_path;
+ sp->fts_dev = p->fts_dev;
+}
+
+int
+fts_close(FTS *sp)
+{
+ FTSENT *freep, *p;
+ int saved_errno = 0;
+
+ _DIAGASSERT(sp != NULL);
+
+ /*
+ * This still works if we haven't read anything -- the dummy structure
+ * points to the root list, so we step through to the end of the root
+ * list which has a valid parent pointer.
+ */
+ if (sp->fts_cur) {
+ if (sp->fts_cur->fts_flags & FTS_SYMFOLLOW)
+ (void)close(sp->fts_cur->fts_symfd);
+ for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
+ freep = p;
+ p = p->fts_link ? p->fts_link : p->fts_parent;
+ fts_free(freep);
+ }
+ fts_free(p);
+ }
+
+ /* Free up child linked list, sort array, path buffer. */
+ if (sp->fts_child)
+ fts_lfree(sp->fts_child);
+ if (sp->fts_array)
+ free(sp->fts_array);
+ free(sp->fts_path);
+
+ /* Return to original directory, save errno if necessary. */
+ if (!ISSET(FTS_NOCHDIR)) {
+ if (fchdir(sp->fts_rfd) == -1)
+ saved_errno = errno;
+ (void)close(sp->fts_rfd);
+ }
+
+ /* Free up the stream pointer. */
+ free(sp);
+ if (saved_errno) {
+ errno = saved_errno;
+ return -1;
+ }
+
+ return 0;
+}
+
+#if !defined(__FTS_COMPAT_TAILINGSLASH)
+
+/*
+ * Special case of "/" at the end of the path so that slashes aren't
+ * appended which would cause paths to be written as "....//foo".
+ */
+#define NAPPEND(p) \
+ (p->fts_path[p->fts_pathlen - 1] == '/' \
+ ? p->fts_pathlen - 1 : p->fts_pathlen)
+
+#else /* !defined(__FTS_COMPAT_TAILINGSLASH) */
+
+/*
+ * compatibility with the old behaviour.
+ *
+ * Special case a root of "/" so that slashes aren't appended which would
+ * cause paths to be written as "//foo".
+ */
+
+#define NAPPEND(p) \
+ (p->fts_level == FTS_ROOTLEVEL && p->fts_pathlen == 1 && \
+ p->fts_path[0] == '/' ? 0 : p->fts_pathlen)
+
+#endif /* !defined(__FTS_COMPAT_TAILINGSLASH) */
+
+FTSENT *
+fts_read(FTS *sp)
+{
+ FTSENT *p, *tmp;
+ int instr;
+ char *t;
+ int saved_errno;
+
+ _DIAGASSERT(sp != NULL);
+
+ /* If finished or unrecoverable error, return NULL. */
+ if (sp->fts_cur == NULL || ISSET(FTS_STOP))
+ return (NULL);
+
+ /* Set current node pointer. */
+ p = sp->fts_cur;
+
+ /* Save and zero out user instructions. */
+ instr = p->fts_instr;
+ p->fts_instr = FTS_NOINSTR;
+
+ /* Any type of file may be re-visited; re-stat and re-turn. */
+ if (instr == FTS_AGAIN) {
+ p->fts_info = fts_stat(sp, p, 0);
+ return (p);
+ }
+
+ /*
+ * Following a symlink -- SLNONE test allows application to see
+ * SLNONE and recover. If indirecting through a symlink, have
+ * keep a pointer to current location. If unable to get that
+ * pointer, follow fails.
+ */
+ if (instr == FTS_FOLLOW &&
+ (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
+ p->fts_info = fts_stat(sp, p, 1);
+ if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
+ if ((p->fts_symfd = open(".", O_RDONLY | O_CLOEXEC, 0))
+ == -1) {
+ p->fts_errno = errno;
+ p->fts_info = FTS_ERR;
+ } else
+ p->fts_flags |= FTS_SYMFOLLOW;
+ }
+ return (p);
+ }
+
+ /* Directory in pre-order. */
+ if (p->fts_info == FTS_D) {
+ /* If skipped or crossed mount point, do post-order visit. */
+ if (instr == FTS_SKIP ||
+ (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) {
+ if (p->fts_flags & FTS_SYMFOLLOW)
+ (void)close(p->fts_symfd);
+ if (sp->fts_child) {
+ fts_lfree(sp->fts_child);
+ sp->fts_child = NULL;
+ }
+ p->fts_info = FTS_DP;
+ return (p);
+ }
+
+ /* Rebuild if only read the names and now traversing. */
+ if (sp->fts_child && ISSET(FTS_NAMEONLY)) {
+ CLR(FTS_NAMEONLY);
+ fts_lfree(sp->fts_child);
+ sp->fts_child = NULL;
+ }
+
+ /*
+ * Cd to the subdirectory.
+ *
+ * If have already read and now fail to chdir, whack the list
+ * to make the names come out right, and set the parent errno
+ * so the application will eventually get an error condition.
+ * Set the FTS_DONTCHDIR flag so that when we logically change
+ * directories back to the parent we don't do a chdir.
+ *
+ * If haven't read do so. If the read fails, fts_build sets
+ * FTS_STOP or the fts_info field of the node.
+ */
+ if (sp->fts_child) {
+ if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
+ p->fts_errno = errno;
+ p->fts_flags |= FTS_DONTCHDIR;
+ for (p = sp->fts_child; p; p = p->fts_link)
+ p->fts_accpath =
+ p->fts_parent->fts_accpath;
+ }
+ } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) {
+ if (ISSET(FTS_STOP))
+ return (NULL);
+ return (p);
+ }
+ p = sp->fts_child;
+ sp->fts_child = NULL;
+ goto name;
+ }
+
+ /* Move to the next node on this level. */
+next: tmp = p;
+ if ((p = p->fts_link) != NULL) {
+ fts_free(tmp);
+
+ /*
+ * If reached the top, return to the original directory, and
+ * load the paths for the next root.
+ */
+ if (p->fts_level == FTS_ROOTLEVEL) {
+ if (FCHDIR(sp, sp->fts_rfd)) {
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ fts_load(sp, p);
+ return (sp->fts_cur = p);
+ }
+
+ /*
+ * User may have called fts_set on the node. If skipped,
+ * ignore. If followed, get a file descriptor so we can
+ * get back if necessary.
+ */
+ if (p->fts_instr == FTS_SKIP)
+ goto next;
+ if (p->fts_instr == FTS_FOLLOW) {
+ p->fts_info = fts_stat(sp, p, 1);
+ if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
+ if ((p->fts_symfd =
+ open(".", O_RDONLY | O_CLOEXEC, 0)) == -1) {
+ p->fts_errno = errno;
+ p->fts_info = FTS_ERR;
+ } else
+ p->fts_flags |= FTS_SYMFOLLOW;
+ }
+ p->fts_instr = FTS_NOINSTR;
+ }
+
+name: t = sp->fts_path + NAPPEND(p->fts_parent);
+ *t++ = '/';
+ memmove(t, p->fts_name, (size_t)(p->fts_namelen + 1));
+ return (sp->fts_cur = p);
+ }
+
+ /* Move up to the parent node. */
+ p = tmp->fts_parent;
+ fts_free(tmp);
+
+ if (p->fts_level == FTS_ROOTPARENTLEVEL) {
+ /*
+ * Done; free everything up and set errno to 0 so the user
+ * can distinguish between error and EOF.
+ */
+ fts_free(p);
+ errno = 0;
+ return (sp->fts_cur = NULL);
+ }
+
+ /* Nul terminate the pathname. */
+ sp->fts_path[p->fts_pathlen] = '\0';
+
+ /*
+ * Return to the parent directory. If at a root node or came through
+ * a symlink, go back through the file descriptor. Otherwise, cd up
+ * one directory.
+ */
+ if (p->fts_level == FTS_ROOTLEVEL) {
+ if (FCHDIR(sp, sp->fts_rfd)) {
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ } else if (p->fts_flags & FTS_SYMFOLLOW) {
+ if (FCHDIR(sp, p->fts_symfd)) {
+ saved_errno = errno;
+ (void)close(p->fts_symfd);
+ errno = saved_errno;
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ (void)close(p->fts_symfd);
+ } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
+ fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
+ return (sp->fts_cur = p);
+}
+
+/*
+ * Fts_set takes the stream as an argument although it's not used in this
+ * implementation; it would be necessary if anyone wanted to add global
+ * semantics to fts using fts_set. An error return is allowed for similar
+ * reasons.
+ */
+/* ARGSUSED */
+int
+fts_set(FTS *sp, FTSENT *p, int instr)
+{
+ (void) sp; /* silence warnings */
+ _DIAGASSERT(sp != NULL);
+ _DIAGASSERT(p != NULL);
+
+ if (instr && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
+ instr != FTS_NOINSTR && instr != FTS_SKIP) {
+ errno = EINVAL;
+ return (1);
+ }
+ p->fts_instr = instr;
+ return (0);
+}
+
+FTSENT *
+fts_children(FTS *sp, int instr)
+{
+ FTSENT *p;
+ int fd;
+
+ _DIAGASSERT(sp != NULL);
+
+ if (instr && instr != FTS_NAMEONLY) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ /* Set current node pointer. */
+ p = sp->fts_cur;
+
+ /*
+ * Errno set to 0 so user can distinguish empty directory from
+ * an error.
+ */
+ errno = 0;
+
+ /* Fatal errors stop here. */
+ if (ISSET(FTS_STOP))
+ return (NULL);
+
+ /* Return logical hierarchy of user's arguments. */
+ if (p->fts_info == FTS_INIT)
+ return (p->fts_link);
+
+ /*
+ * If not a directory being visited in pre-order, stop here. Could
+ * allow FTS_DNR, assuming the user has fixed the problem, but the
+ * same effect is available with FTS_AGAIN.
+ */
+ if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */)
+ return (NULL);
+
+ /* Free up any previous child list. */
+ if (sp->fts_child)
+ fts_lfree(sp->fts_child);
+
+ if (instr == FTS_NAMEONLY) {
+ SET(FTS_NAMEONLY);
+ instr = BNAMES;
+ } else
+ instr = BCHILD;
+
+ /*
+ * If using chdir on a relative path and called BEFORE fts_read does
+ * its chdir to the root of a traversal, we can lose -- we need to
+ * chdir into the subdirectory, and we don't know where the current
+ * directory is, so we can't get back so that the upcoming chdir by
+ * fts_read will work.
+ */
+ if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' ||
+ ISSET(FTS_NOCHDIR))
+ return (sp->fts_child = fts_build(sp, instr));
+
+ if ((fd = open(".", O_RDONLY, 0)) == -1)
+ return (sp->fts_child = NULL);
+ sp->fts_child = fts_build(sp, instr);
+ if (fchdir(fd)) {
+ (void)close(fd);
+ return (NULL);
+ }
+ (void)close(fd);
+ return (sp->fts_child);
+}
+
+/*
+ * This is the tricky part -- do not casually change *anything* in here. The
+ * idea is to build the linked list of entries that are used by fts_children
+ * and fts_read. There are lots of special cases.
+ *
+ * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is
+ * set and it's a physical walk (so that symbolic links can't be directories),
+ * we can do things quickly. First, if it's a 4.4BSD file system, the type
+ * of the file is in the directory entry. Otherwise, we assume that the number
+ * of subdirectories in a node is equal to the number of links to the parent.
+ * The former skips all stat calls. The latter skips stat calls in any leaf
+ * directories and for any files after the subdirectories in the directory have
+ * been found, cutting the stat calls by about 2/3.
+ */
+static FTSENT *
+fts_build(FTS *sp, int type)
+{
+ struct dirent *dp;
+ FTSENT *p, *head;
+ size_t nitems;
+ FTSENT *cur, *tail;
+ DIR *dirp;
+ void *oldaddr;
+ size_t dnamlen;
+ int cderrno, descend, level, nlinks, saved_errno, nostat, doadjust;
+ size_t len, maxlen;
+#ifdef FTS_WHITEOUT
+ int oflag;
+#endif
+ char *cp = NULL; /* pacify gcc */
+
+ _DIAGASSERT(sp != NULL);
+
+ /* Set current node pointer. */
+ cur = sp->fts_cur;
+
+ /*
+ * Open the directory for reading. If this fails, we're done.
+ * If being called from fts_read, set the fts_info field.
+ */
+#if 0 /* def FTS_WHITEOUT */
+ if (ISSET(FTS_WHITEOUT))
+ oflag = DTF_NODUP|DTF_REWIND;
+ else
+ oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND;
+#else
+#define __opendir2(path, flag) opendir(path)
+#endif
+ if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) {
+ if (type == BREAD) {
+ cur->fts_info = FTS_DNR;
+ cur->fts_errno = errno;
+ }
+ return (NULL);
+ }
+
+ /*
+ * Nlinks is the number of possible entries of type directory in the
+ * directory if we're cheating on stat calls, 0 if we're not doing
+ * any stat calls at all, -1 if we're doing stats on everything.
+ */
+ if (type == BNAMES) {
+ nlinks = 0;
+ nostat = 1;
+ } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
+ nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);
+ nostat = 1;
+ } else {
+ nlinks = -1;
+ nostat = 0;
+ }
+
+#ifdef notdef
+ (void)printf("nlinks == %d (cur: %d)\n", nlinks, cur->fts_nlink);
+ (void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n",
+ ISSET(FTS_NOSTAT), ISSET(FTS_PHYSICAL), ISSET(FTS_SEEDOT));
+#endif
+ /*
+ * If we're going to need to stat anything or we want to descend
+ * and stay in the directory, chdir. If this fails we keep going,
+ * but set a flag so we don't chdir after the post-order visit.
+ * We won't be able to stat anything, but we can still return the
+ * names themselves. Note, that since fts_read won't be able to
+ * chdir into the directory, it will have to return different path
+ * names than before, i.e. "a/b" instead of "b". Since the node
+ * has already been visited in pre-order, have to wait until the
+ * post-order visit to return the error. There is a special case
+ * here, if there was nothing to stat then it's not an error to
+ * not be able to stat. This is all fairly nasty. If a program
+ * needed sorted entries or stat information, they had better be
+ * checking FTS_NS on the returned nodes.
+ */
+ cderrno = 0;
+ if (nlinks || type == BREAD) {
+ if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
+ if (nlinks && type == BREAD)
+ cur->fts_errno = errno;
+ cur->fts_flags |= FTS_DONTCHDIR;
+ descend = 0;
+ cderrno = errno;
+ } else
+ descend = 1;
+ } else
+ descend = 0;
+
+ /*
+ * Figure out the max file name length that can be stored in the
+ * current path -- the inner loop allocates more path as necessary.
+ * We really wouldn't have to do the maxlen calculations here, we
+ * could do them in fts_read before returning the path, but it's a
+ * lot easier here since the length is part of the dirent structure.
+ *
+ * If not changing directories set a pointer so that can just append
+ * each new name into the path.
+ */
+ len = NAPPEND(cur);
+ if (ISSET(FTS_NOCHDIR)) {
+ cp = sp->fts_path + len;
+ *cp++ = '/';
+ }
+ len++;
+ maxlen = sp->fts_pathlen - len;
+
+#if defined(__FTS_COMPAT_LEVEL)
+ if (cur->fts_level == SHRT_MAX) {
+ (void)closedir(dirp);
+ cur->fts_info = FTS_ERR;
+ SET(FTS_STOP);
+ errno = ENAMETOOLONG;
+ return (NULL);
+ }
+#endif
+
+ level = cur->fts_level + 1;
+
+ /* Read the directory, attaching each entry to the `link' pointer. */
+ doadjust = 0;
+ for (head = tail = NULL, nitems = 0; (dp = readdir(dirp)) != NULL;) {
+
+ if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
+ continue;
+
+#if defined(HAVE_STRUCT_DIRENT_D_NAMLEN)
+ dnamlen = dp->d_namlen;
+#else
+ dnamlen = strlen(dp->d_name);
+#endif
+ if ((p = fts_alloc(sp, dp->d_name, dnamlen)) == NULL)
+ goto mem1;
+ if (dnamlen >= maxlen) { /* include space for NUL */
+ oldaddr = sp->fts_path;
+ if (fts_palloc(sp, dnamlen + len + 1)) {
+ /*
+ * No more memory for path or structures. Save
+ * errno, free up the current structure and the
+ * structures already allocated.
+ */
+mem1: saved_errno = errno;
+ if (p)
+ fts_free(p);
+ fts_lfree(head);
+ (void)closedir(dirp);
+ errno = saved_errno;
+ cur->fts_info = FTS_ERR;
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ /* Did realloc() change the pointer? */
+ if (oldaddr != sp->fts_path) {
+ doadjust = 1;
+ if (ISSET(FTS_NOCHDIR))
+ cp = sp->fts_path + len;
+ }
+ maxlen = sp->fts_pathlen - len;
+ }
+
+#if defined(__FTS_COMPAT_LENGTH)
+ if (len + dnamlen >= USHRT_MAX) {
+ /*
+ * In an FTSENT, fts_pathlen is an unsigned short
+ * so it is possible to wraparound here.
+ * If we do, free up the current structure and the
+ * structures already allocated, then error out
+ * with ENAMETOOLONG.
+ */
+ fts_free(p);
+ fts_lfree(head);
+ (void)closedir(dirp);
+ cur->fts_info = FTS_ERR;
+ SET(FTS_STOP);
+ errno = ENAMETOOLONG;
+ return (NULL);
+ }
+#endif
+ p->fts_level = level;
+ p->fts_pathlen = ftsent_pathlen_truncate(len + dnamlen);
+ p->fts_parent = sp->fts_cur;
+
+#ifdef FTS_WHITEOUT
+ if (dp->d_type == DT_WHT)
+ p->fts_flags |= FTS_ISW;
+#endif
+
+ if (cderrno) {
+ if (nlinks) {
+ p->fts_info = FTS_NS;
+ p->fts_errno = cderrno;
+ } else
+ p->fts_info = FTS_NSOK;
+ p->fts_accpath = cur->fts_accpath;
+ } else if (nlinks == 0
+#ifdef DT_DIR
+ || (nostat &&
+ dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
+#endif
+ ) {
+ p->fts_accpath =
+ ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
+ p->fts_info = FTS_NSOK;
+ } else {
+ /* Build a file name for fts_stat to stat. */
+ if (ISSET(FTS_NOCHDIR)) {
+ p->fts_accpath = p->fts_path;
+ memmove(cp, p->fts_name,
+ (size_t)(p->fts_namelen + 1));
+ } else
+ p->fts_accpath = p->fts_name;
+ /* Stat it. */
+ p->fts_info = fts_stat(sp, p, 0);
+
+ /* Decrement link count if applicable. */
+ if (nlinks > 0 && (p->fts_info == FTS_D ||
+ p->fts_info == FTS_DC || p->fts_info == FTS_DOT))
+ --nlinks;
+ }
+
+ /* We walk in directory order so "ls -f" doesn't get upset. */
+ p->fts_link = NULL;
+ if (head == NULL)
+ head = tail = p;
+ else {
+ tail->fts_link = p;
+ tail = p;
+ }
+ ++nitems;
+ }
+ (void)closedir(dirp);
+
+ /*
+ * If had to realloc the path, adjust the addresses for the rest
+ * of the tree.
+ */
+ if (doadjust)
+ fts_padjust(sp, head);
+
+ /*
+ * If not changing directories, reset the path back to original
+ * state.
+ */
+ if (ISSET(FTS_NOCHDIR)) {
+ if (len == sp->fts_pathlen || nitems == 0)
+ --cp;
+ *cp = '\0';
+ }
+
+ /*
+ * If descended after called from fts_children or after called from
+ * fts_read and nothing found, get back. At the root level we use
+ * the saved fd; if one of fts_open()'s arguments is a relative path
+ * to an empty directory, we wind up here with no other way back. If
+ * can't get back, we're done.
+ */
+ if (descend && (type == BCHILD || !nitems) &&
+ (cur->fts_level == FTS_ROOTLEVEL ?
+ FCHDIR(sp, sp->fts_rfd) :
+ fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
+ cur->fts_info = FTS_ERR;
+ SET(FTS_STOP);
+ return (NULL);
+ }
+
+ /* If didn't find anything, return NULL. */
+ if (!nitems) {
+ if (type == BREAD)
+ cur->fts_info = FTS_DP;
+ return (NULL);
+ }
+
+ /* Sort the entries. */
+ if (sp->fts_compar && nitems > 1)
+ head = fts_sort(sp, head, nitems);
+ return (head);
+}
+
+static unsigned short
+fts_stat(FTS *sp, FTSENT *p, int follow)
+{
+ FTSENT *t;
+ dev_t dev;
+ ino_t ino;
+ struct stat *sbp, sb;
+ int saved_errno;
+
+ _DIAGASSERT(sp != NULL);
+ _DIAGASSERT(p != NULL);
+
+ /* If user needs stat info, stat buffer already allocated. */
+ sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp;
+
+#ifdef FTS_WHITEOUT
+ /* check for whiteout */
+ if (p->fts_flags & FTS_ISW) {
+ if (sbp != &sb) {
+ memset(sbp, '\0', sizeof (*sbp));
+ sbp->st_mode = S_IFWHT;
+ }
+ return (FTS_W);
+ }
+#endif
+
+ /*
+ * If doing a logical walk, or application requested FTS_FOLLOW, do
+ * a stat(2). If that fails, check for a non-existent symlink. If
+ * fail, set the errno from the stat call.
+ */
+ if (ISSET(FTS_LOGICAL) || follow) {
+ if (stat(p->fts_accpath, sbp)) {
+ saved_errno = errno;
+ if (!lstat(p->fts_accpath, sbp)) {
+ errno = 0;
+ return (FTS_SLNONE);
+ }
+ p->fts_errno = saved_errno;
+ goto err;
+ }
+ } else if (lstat(p->fts_accpath, sbp)) {
+ p->fts_errno = errno;
+err: memset(sbp, 0, sizeof(*sbp));
+ return (FTS_NS);
+ }
+
+ if (S_ISDIR(sbp->st_mode)) {
+ /*
+ * Set the device/inode. Used to find cycles and check for
+ * crossing mount points. Also remember the link count, used
+ * in fts_build to limit the number of stat calls. It is
+ * understood that these fields are only referenced if fts_info
+ * is set to FTS_D.
+ */
+ dev = p->fts_dev = sbp->st_dev;
+ ino = p->fts_ino = sbp->st_ino;
+ p->fts_nlink = sbp->st_nlink;
+
+ if (ISDOT(p->fts_name))
+ return (FTS_DOT);
+
+ /*
+ * Cycle detection is done by brute force when the directory
+ * is first encountered. If the tree gets deep enough or the
+ * number of symbolic links to directories is high enough,
+ * something faster might be worthwhile.
+ */
+ for (t = p->fts_parent;
+ t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
+ if (ino == t->fts_ino && dev == t->fts_dev) {
+ p->fts_cycle = t;
+ return (FTS_DC);
+ }
+ return (FTS_D);
+ }
+ if (S_ISLNK(sbp->st_mode))
+ return (FTS_SL);
+ if (S_ISREG(sbp->st_mode))
+ return (FTS_F);
+ return (FTS_DEFAULT);
+}
+
+static FTSENT *
+fts_sort(FTS *sp, FTSENT *head, size_t nitems)
+{
+ FTSENT **ap, *p;
+
+ _DIAGASSERT(sp != NULL);
+ _DIAGASSERT(head != NULL);
+
+ /*
+ * Construct an array of pointers to the structures and call qsort(3).
+ * Reassemble the array in the order returned by qsort. If unable to
+ * sort for memory reasons, return the directory entries in their
+ * current order. Allocate enough space for the current needs plus
+ * 40 so don't realloc one entry at a time.
+ */
+ if (nitems > sp->fts_nitems) {
+ FTSENT **new;
+
+ new = realloc(sp->fts_array, sizeof(FTSENT *) * (nitems + 40));
+ if (new == 0)
+ return (head);
+ sp->fts_array = new;
+ sp->fts_nitems = fts_nitems_truncate(nitems + 40);
+ }
+ for (ap = sp->fts_array, p = head; p; p = p->fts_link)
+ *ap++ = p;
+ qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *),
+ (int (*)(const void *, const void *))sp->fts_compar);
+ for (head = *(ap = sp->fts_array); --nitems; ++ap)
+ ap[0]->fts_link = ap[1];
+ ap[0]->fts_link = NULL;
+ return (head);
+}
+
+static FTSENT *
+fts_alloc(FTS *sp, const char *name, size_t namelen)
+{
+ FTSENT *p;
+#if defined(FTS_ALLOC_ALIGNED)
+ size_t len;
+#endif
+
+ _DIAGASSERT(sp != NULL);
+ _DIAGASSERT(name != NULL);
+
+#if defined(FTS_ALLOC_ALIGNED)
+ /*
+ * The file name is a variable length array and no stat structure is
+ * necessary if the user has set the nostat bit. Allocate the FTSENT
+ * structure, the file name and the stat structure in one chunk, but
+ * be careful that the stat structure is reasonably aligned. Since the
+ * fts_name field is declared to be of size 1, the fts_name pointer is
+ * namelen + 2 before the first possible address of the stat structure.
+ */
+ len = sizeof(FTSENT) + namelen;
+ if (!ISSET(FTS_NOSTAT))
+ len += sizeof(*(p->fts_statp)) + ALIGNBYTES;
+ if ((p = malloc(len)) == NULL)
+ return (NULL);
+
+ if (!ISSET(FTS_NOSTAT))
+ p->fts_statp = (struct stat *)ALIGN(
+ (unsigned long)(p->fts_name + namelen + 2));
+#else
+ if ((p = malloc(sizeof(FTSENT) + namelen)) == NULL)
+ return (NULL);
+
+ if (!ISSET(FTS_NOSTAT))
+ if ((p->fts_statp = malloc(sizeof(*(p->fts_statp)))) == NULL) {
+ free(p);
+ return (NULL);
+ }
+#endif
+
+ if (ISSET(FTS_NOSTAT))
+ p->fts_statp = NULL;
+
+ /* Copy the name plus the trailing NULL. */
+ memmove(p->fts_name, name, namelen + 1);
+
+ p->fts_namelen = ftsent_namelen_truncate(namelen);
+ p->fts_path = sp->fts_path;
+ p->fts_errno = 0;
+ p->fts_flags = 0;
+ p->fts_instr = FTS_NOINSTR;
+ p->fts_number = 0;
+ p->fts_pointer = NULL;
+ return (p);
+}
+
+static void
+fts_free(FTSENT *p)
+{
+#if !defined(FTS_ALLOC_ALIGNED)
+ if (p->fts_statp)
+ free(p->fts_statp);
+#endif
+ free(p);
+}
+
+static void
+fts_lfree(FTSENT *head)
+{
+ FTSENT *p;
+
+ /* XXX: head may be NULL ? */
+
+ /* Free a linked list of structures. */
+ while ((p = head) != NULL) {
+ head = head->fts_link;
+ fts_free(p);
+ }
+}
+
+static size_t
+fts_pow2(size_t x)
+{
+
+ x--;
+ x |= x>>1;
+ x |= x>>2;
+ x |= x>>4;
+ x |= x>>8;
+ x |= x>>16;
+#if LONG_BIT > 32
+ x |= x>>32;
+#endif
+#if LONG_BIT > 64
+ x |= x>>64;
+#endif
+ x++;
+ return (x);
+}
+
+/*
+ * Allow essentially unlimited paths; find, rm, ls should all work on any tree.
+ * Most systems will allow creation of paths much longer than MAXPATHLEN, even
+ * though the kernel won't resolve them. Round up the new size to a power of 2,
+ * so we don't realloc the path 2 bytes at a time.
+ */
+static int
+fts_palloc(FTS *sp, size_t size)
+{
+ char *new;
+
+ _DIAGASSERT(sp != NULL);
+
+#ifdef __FTS_COMPAT_LENGTH
+ /* Protect against fts_pathlen overflow. */
+ if (size > USHRT_MAX + 1) {
+ errno = ENAMETOOLONG;
+ return (1);
+ }
+#endif
+ size = fts_pow2(size);
+ new = realloc(sp->fts_path, size);
+ if (new == 0)
+ return (1);
+ sp->fts_path = new;
+ sp->fts_pathlen = fts_pathlen_truncate(size);
+ return (0);
+}
+
+/*
+ * When the path is realloc'd, have to fix all of the pointers in structures
+ * already returned.
+ */
+static void
+fts_padjust(FTS *sp, FTSENT *head)
+{
+ FTSENT *p;
+ char *addr;
+
+ _DIAGASSERT(sp != NULL);
+
+#define ADJUST(p) do { \
+ if ((p)->fts_accpath != (p)->fts_name) \
+ (p)->fts_accpath = \
+ addr + ((p)->fts_accpath - (p)->fts_path); \
+ (p)->fts_path = addr; \
+} while (/*CONSTCOND*/0)
+
+ addr = sp->fts_path;
+
+ /* Adjust the current set of children. */
+ for (p = sp->fts_child; p; p = p->fts_link)
+ ADJUST(p);
+
+ /* Adjust the rest of the tree, including the current level. */
+ for (p = head; p->fts_level >= FTS_ROOTLEVEL;) {
+ ADJUST(p);
+ p = p->fts_link ? p->fts_link : p->fts_parent;
+ }
+}
+
+static size_t
+fts_maxarglen(char * const *argv)
+{
+ size_t len, max;
+
+ _DIAGASSERT(argv != NULL);
+
+ for (max = 0; *argv; ++argv)
+ if ((len = strlen(*argv)) > max)
+ max = len;
+ return (max + 1);
+}
+
+/*
+ * Change to dir specified by fd or p->fts_accpath without getting
+ * tricked by someone changing the world out from underneath us.
+ * Assumes p->fts_dev and p->fts_ino are filled in.
+ */
+static int
+fts_safe_changedir(const FTS *sp, const FTSENT *p, int fd, const char *path)
+{
+ int oldfd = fd, ret = -1;
+ struct stat sb;
+
+ if (ISSET(FTS_NOCHDIR))
+ return 0;
+
+ if (oldfd < 0 && (fd = open(path, O_RDONLY)) == -1)
+ return -1;
+
+ if (fstat(fd, &sb) == -1)
+ goto bail;
+
+ if (sb.st_ino != p->fts_ino || sb.st_dev != p->fts_dev) {
+ errno = ENOENT;
+ goto bail;
+ }
+
+ ret = fchdir(fd);
+
+bail:
+ if (oldfd < 0) {
+ int save_errno = errno;
+ (void)close(fd);
+ errno = save_errno;
+ }
+ return ret;
+}
diff --git a/extension/gawkfts.h b/extension/gawkfts.h
new file mode 100644
index 00000000..f1ca26f5
--- /dev/null
+++ b/extension/gawkfts.h
@@ -0,0 +1,157 @@
+/* $NetBSD: fts.h,v 1.19 2009/08/16 19:33:38 christos Exp $ */
+
+/*
+ * Copyright (c) 1989, 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. 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.
+ *
+ * @(#)fts.h 8.3 (Berkeley) 8/14/94
+ */
+
+#ifndef _FTS_H_
+#define _FTS_H_
+
+#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 ZOS_USS
+#include <limits.h>
+#define MAXPATHLEN FILENAME_MAX
+#endif
+
+typedef struct {
+ struct _ftsent *fts_cur; /* current node */
+ struct _ftsent *fts_child; /* linked list of children */
+ struct _ftsent **fts_array; /* sort array */
+ dev_t fts_dev; /* starting device # */
+ char *fts_path; /* path for this descent */
+ int fts_rfd; /* fd for root */
+ unsigned int fts_pathlen; /* sizeof(path) */
+ unsigned int fts_nitems; /* elements in the sort array */
+ int (*fts_compar) /* compare function */
+ (const struct _ftsent **, const struct _ftsent **);
+
+#define FTS_COMFOLLOW 0x001 /* follow command line symlinks */
+#define FTS_LOGICAL 0x002 /* logical walk */
+#define FTS_NOCHDIR 0x004 /* don't change directories */
+#define FTS_NOSTAT 0x008 /* don't get stat info */
+#define FTS_PHYSICAL 0x010 /* physical walk */
+#define FTS_SEEDOT 0x020 /* return dot and dot-dot */
+#define FTS_XDEV 0x040 /* don't cross devices */
+/* #define FTS_WHITEOUT 0x080 */ /* return whiteout information */
+#define FTS_OPTIONMASK 0x0ff /* valid user option mask */
+
+#define FTS_NAMEONLY 0x100 /* (private) child names only */
+#define FTS_STOP 0x200 /* (private) unrecoverable error */
+ int fts_options; /* fts_open options, global flags */
+} FTS;
+
+typedef struct _ftsent {
+ struct _ftsent *fts_cycle; /* cycle node */
+ struct _ftsent *fts_parent; /* parent directory */
+ struct _ftsent *fts_link; /* next file in directory */
+#ifdef ZOS_USS
+ long fts_number; /* local numeric value */
+#else
+ long long fts_number; /* local numeric value */
+#endif
+ void *fts_pointer; /* local address value */
+ char *fts_accpath; /* access path */
+ char *fts_path; /* root path */
+ int fts_errno; /* errno for this node */
+ int fts_symfd; /* fd for symlink */
+ unsigned int fts_pathlen; /* strlen(fts_path) */
+ unsigned int fts_namelen; /* strlen(fts_name) */
+
+ ino_t fts_ino; /* inode */
+ dev_t fts_dev; /* device */
+ unsigned int fts_nlink; /* link count */
+
+#define FTS_ROOTPARENTLEVEL -1
+#define FTS_ROOTLEVEL 0
+ int fts_level; /* depth (-1 to N) */
+
+#define FTS_D 1 /* preorder directory */
+#define FTS_DC 2 /* directory that causes cycles */
+#define FTS_DEFAULT 3 /* none of the above */
+#define FTS_DNR 4 /* unreadable directory */
+#define FTS_DOT 5 /* dot or dot-dot */
+#define FTS_DP 6 /* postorder directory */
+#define FTS_ERR 7 /* error; errno is set */
+#define FTS_F 8 /* regular file */
+#define FTS_INIT 9 /* initialized only */
+#define FTS_NS 10 /* stat(2) failed */
+#define FTS_NSOK 11 /* no stat(2) requested */
+#define FTS_SL 12 /* symbolic link */
+#define FTS_SLNONE 13 /* symbolic link without target */
+#define FTS_W 14 /* whiteout object */
+ unsigned short fts_info; /* user flags for FTSENT structure */
+
+#define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */
+#define FTS_SYMFOLLOW 0x02 /* followed a symlink to get here */
+#define FTS_ISW 0x04 /* this is a whiteout object */
+ unsigned short fts_flags; /* private flags for FTSENT structure */
+
+#define FTS_AGAIN 1 /* read node again */
+#define FTS_FOLLOW 2 /* follow symbolic link */
+#define FTS_NOINSTR 3 /* no instructions */
+#define FTS_SKIP 4 /* discard node */
+ unsigned short fts_instr; /* fts_set() instructions */
+
+ struct stat *fts_statp; /* stat(2) information */
+ char fts_name[1]; /* file name */
+} FTSENT;
+
+/*
+ * Due to the wonders of modern linkers, shared libraries,
+ * compilers and other deep, dark, black magic voodoo, we
+ * redefined the identifiers so our code will use our version
+ * of these routines. See README.fts for a little bit more
+ * information and a lot more ranting.
+ */
+
+#define fts_children gawk_fts_children
+#define fts_close gawk_fts_close
+#define fts_open gawk_fts_open
+#define fts_read gawk_fts_read
+#define fts_set gawk_fts_set
+
+FTSENT *fts_children (FTS *, int);
+int fts_close (FTS *);
+FTS *fts_open (char * const *, int,
+ int (*)(const FTSENT **, const FTSENT **));
+FTSENT *fts_read (FTS *);
+int fts_set (FTS *, FTSENT *, int) __THROW;
+
+#endif /* !_FTS_H_ */
diff --git a/extension/inplace.3am b/extension/inplace.3am
new file mode 100644
index 00000000..5ca04be2
--- /dev/null
+++ b/extension/inplace.3am
@@ -0,0 +1,92 @@
+.TH INPLACE 3am "Jan 15 2013" "Free Software Foundation" "GNU Awk Extension Modules"
+.SH NAME
+inplace \- emulate sed/perl/ruby in-place editing
+.SH SYNOPSIS
+.ft CW
+.nf
+@load "inplace"
+
+# Please set INPLACE_SUFFIX to make a backup copy. For example, you may
+# want to set INPLACE_SUFFIX to .bak on the command line or in a BEGIN rule.
+
+BEGINFILE {
+ inplace_begin(FILENAME, INPLACE_SUFFIX)
+}
+
+ENDFILE {
+ inplace_end(FILENAME, INPLACE_SUFFIX)
+}
+.fi
+.ft R
+.SH DESCRIPTION
+The
+.I inplace
+extension adds two functions named
+.B inplace_begin()
+and
+.BR inplace_end() .
+These functions are meant to be invoked from the
+.I inplace.awk
+wrapper (whose contents are displayed above)
+which is installed when
+.I gawk
+is.
+.PP
+By default, each named file on the command line is
+replaced with a new file of the same name whose contents
+are the results of running the AWK program.
+If the user supplies an AWK variable named
+.B INPLACE_SUFFIX
+in a
+.B BEGIN
+rule or on the command line, then the
+.I inplace
+extension concatenates that suffix onto the original
+filename and uses the result as a filename for renaming
+the original.
+... .SH NOTES
+... .SH BUGS
+.SH EXAMPLE
+.ft CW
+.nf
+gawk -i inplace '\f(CIscript\fP' files ...
+.br
+gawk -i inplace -f \f(CIscriptfile\fP files ...
+.fi
+.ft R
+.SH "SEE ALSO"
+.IR "GAWK: Effective AWK Programming" ,
+.IR filefuncs (3am),
+.IR fnmatch (3am),
+.IR fork (3am),
+.IR ordchr (3am),
+.IR readdir (3am),
+.IR readfile (3am),
+.IR revoutput (3am),
+.IR rwarray (3am).
+.SH AUTHOR
+Andrew Schorr,
+.BR schorr@telemetry-investments.com .
+.SH COPYING PERMISSIONS
+Copyright \(co 2012, 2013,
+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.
diff --git a/extension/inplace.c b/extension/inplace.c
new file mode 100644
index 00000000..0693ad92
--- /dev/null
+++ b/extension/inplace.c
@@ -0,0 +1,278 @@
+/*
+ * inplace.c - Provide support for in-place editing.
+ */
+
+/*
+ * Copyright (C) 2013, 2014 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 3 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 HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef _XOPEN_SOURCE
+# define _XOPEN_SOURCE
+#endif
+#ifndef _XOPEN_SOURCE_EXTENDED
+# define _XOPEN_SOURCE_EXTENDED 1
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "gawkapi.h"
+
+#include "gettext.h"
+#define _(msgid) gettext(msgid)
+#define N_(msgid) msgid
+
+#if ! defined(S_ISREG) && defined(S_IFREG)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+
+#ifdef __MINGW32__
+# define chown(x,y,z) (0)
+# define link(f1,f2) rename(f1,f2)
+int
+mkstemp (char *template)
+{
+ char *tmp_fname = _mktemp (template);
+
+ if (tmp_fname)
+ return _open (tmp_fname, O_RDWR | O_CREAT | O_EXCL, S_IREAD | S_IWRITE);
+ return -1;
+}
+#endif
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+static const char *ext_version = "inplace extension: version 1.0";
+
+int plugin_is_GPL_compatible;
+
+static struct {
+ char *tname;
+ int default_stdout;
+ int posrc; /* return code from fgetpos */
+ fpos_t pos;
+} state = { NULL, -1 };
+
+/*
+ * XXX Known problems:
+ * 1. Should copy ACL.
+ * 2. Not reentrant, so will not work if multiple files are open at
+ * the same time. I'm not sure this is a meaningful problem in practice.
+ */
+
+static void
+at_exit(void *data, int exit_status)
+{
+ (void) data; /* silence warnings */
+ (void) exit_status; /* silence warnings */
+ if (state.tname) {
+ unlink(state.tname);
+ gawk_free(state.tname);
+ state.tname = NULL;
+ }
+}
+
+/*
+ * N.B. Almost everything is a fatal error because this feature is typically
+ * used for one-liners where the user is not going to be worrying about
+ * checking errors. If anything unexpected occurs, we want to abort
+ * immediately!
+ */
+
+static int
+invalid_filename(const awk_string_t *filename)
+{
+ return filename->len == 0 ||
+ (filename->len == 1 && *filename->str == '-');
+}
+
+/* do_inplace_begin --- start in-place editing */
+
+static awk_value_t *
+do_inplace_begin(int nargs, awk_value_t *result)
+{
+ awk_value_t filename;
+ struct stat sbuf;
+ int fd;
+
+ assert(result != NULL);
+
+ if (state.tname)
+ fatal(ext_id, _("inplace_begin: in-place editing already active"));
+
+ if (nargs != 2)
+ fatal(ext_id, _("inplace_begin: expects 2 arguments but called with %d"), nargs);
+
+ if (! get_argument(0, AWK_STRING, &filename))
+ fatal(ext_id, _("inplace_begin: cannot retrieve 1st argument as a string filename"));
+
+ /*
+ * N.B. In the current implementation, the 2nd suffix arg is not used
+ * in this function. It is used only in the inplace_end function.
+ */
+
+ if (invalid_filename(&filename.str_value)) {
+ warning(ext_id, _("inplace_begin: disabling in-place editing for invalid FILENAME `%s'"),
+ filename.str_value.str);
+ unset_ERRNO();
+ return make_number(-1, result);
+ }
+
+ if (stat(filename.str_value.str, & sbuf) < 0) {
+ warning(ext_id, _("inplace_begin: Cannot stat `%s' (%s)"),
+ filename.str_value.str, strerror(errno));
+ update_ERRNO_int(errno);
+ return make_number(-1, result);
+ }
+
+ if (! S_ISREG(sbuf.st_mode)) {
+ warning(ext_id, _("inplace_begin: `%s' is not a regular file"),
+ filename.str_value.str);
+ unset_ERRNO();
+ return make_number(-1, result);
+ }
+
+ /* create a temporary file to which to redirect stdout */
+ emalloc(state.tname, char *, filename.str_value.len+14, "do_inplace_begin");
+ sprintf(state.tname, "%s.gawk.XXXXXX", filename.str_value.str);
+
+ if ((fd = mkstemp(state.tname)) < 0)
+ fatal(ext_id, _("inplace_begin: mkstemp(`%s') failed (%s)"),
+ state.tname, strerror(errno));
+
+ /* N.B. chown/chmod should be more portable than fchown/fchmod */
+ if (chown(state.tname, sbuf.st_uid, sbuf.st_gid) < 0) {
+ /* jumping through hoops to silence gcc. :-( */
+ int junk;
+ junk = chown(state.tname, -1, sbuf.st_gid);
+ junk = junk;
+ }
+
+ if (chmod(state.tname, sbuf.st_mode) < 0)
+ fatal(ext_id, _("inplace_begin: chmod failed (%s)"),
+ strerror(errno));
+
+ fflush(stdout);
+ /* N.B. fgetpos fails when stdout is a tty */
+ state.posrc = fgetpos(stdout, &state.pos);
+ if ((state.default_stdout = dup(STDOUT_FILENO)) < 0)
+ fatal(ext_id, _("inplace_begin: dup(stdout) failed (%s)"),
+ strerror(errno));
+ if (dup2(fd, STDOUT_FILENO) < 0)
+ fatal(ext_id, _("inplace_begin: dup2(%d, stdout) failed (%s)"),
+ fd, strerror(errno));
+ if (close(fd) < 0)
+ fatal(ext_id, _("inplace_begin: close(%d) failed (%s)"),
+ fd, strerror(errno));
+ rewind(stdout);
+ return make_number(0, result);
+}
+
+/* do_inplace_end --- finish in-place editing */
+
+static awk_value_t *
+do_inplace_end(int nargs, awk_value_t *result)
+{
+ awk_value_t filename, suffix;
+
+ assert(result != NULL);
+
+ if (nargs != 2)
+ fatal(ext_id, _("inplace_begin: expects 2 arguments but called with %d"), nargs);
+
+ if (! get_argument(0, AWK_STRING, &filename))
+ fatal(ext_id, _("inplace_end: cannot retrieve 1st argument as a string filename"));
+
+ if (! get_argument(1, AWK_STRING, &suffix))
+ suffix.str_value.str = NULL;
+
+ if (! state.tname) {
+ if (! invalid_filename(&filename.str_value))
+ warning(ext_id, _("inplace_end: in-place editing not active"));
+ return make_number(0, result);
+ }
+
+ fflush(stdout);
+ if (dup2(state.default_stdout, STDOUT_FILENO) < 0)
+ fatal(ext_id, _("inplace_end: dup2(%d, stdout) failed (%s)"),
+ state.default_stdout, strerror(errno));
+ if (close(state.default_stdout) < 0)
+ fatal(ext_id, _("inplace_end: close(%d) failed (%s)"),
+ state.default_stdout, strerror(errno));
+ state.default_stdout = -1;
+ if (state.posrc == 0 && fsetpos(stdout, &state.pos) < 0)
+ fatal(ext_id, _("inplace_end: fsetpos(stdout) failed (%s)"),
+ strerror(errno));
+
+ if (suffix.str_value.str && suffix.str_value.str[0]) {
+ /* backup requested */
+ char *bakname;
+
+ emalloc(bakname, char *, filename.str_value.len+suffix.str_value.len+1,
+ "do_inplace_end");
+ sprintf(bakname, "%s%s",
+ filename.str_value.str, suffix.str_value.str);
+ unlink(bakname); /* if backup file exists already, remove it */
+ if (link(filename.str_value.str, bakname) < 0)
+ fatal(ext_id, _("inplace_end: link(`%s', `%s') failed (%s)"),
+ filename.str_value.str, bakname, strerror(errno));
+ gawk_free(bakname);
+ }
+
+#ifdef __MINGW32__
+ unlink(filename.str_value.str);
+#endif
+
+ if (rename(state.tname, filename.str_value.str) < 0)
+ fatal(ext_id, _("inplace_end: rename(`%s', `%s') failed (%s)"),
+ state.tname, filename.str_value.str, strerror(errno));
+ gawk_free(state.tname);
+ state.tname = NULL;
+ return make_number(0, result);
+}
+
+static awk_ext_func_t func_table[] = {
+ { "inplace_begin", do_inplace_begin, 2 },
+ { "inplace_end", do_inplace_end, 2 },
+};
+
+static awk_bool_t init_inplace(void)
+{
+ awk_atexit(at_exit, NULL);
+ return awk_true;
+}
+
+static awk_bool_t (*init_func)(void) = init_inplace;
+
+/* define the dl_load function using the boilerplate macro */
+
+dl_load_func(func_table, inplace, "")
diff --git a/extension/m4/ChangeLog b/extension/m4/ChangeLog
new file mode 100644
index 00000000..349bbcc8
--- /dev/null
+++ b/extension/m4/ChangeLog
@@ -0,0 +1,30 @@
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.1: Release tar ball made.
+
+2013-12-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * libtool.m4, ltoptions.m4, ltversion.m4: Update to
+ libtool 2.4.2.418.
+
+2013-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.0: Release tar ball made.
+
+2013-01-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dirfd.m4: New file.
+
+2012-08-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * intlmacosx.m4: New file.
+
+2012-07-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gettext.m4, iconv.m4, lib-ld.m4, lib-link.m4, lib-prefix.m4,
+ nls.m4, po.m4, progtest.m4: New files for gettext support.
+
+2012-05-21 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * libtool.m4, ltoptions.m4, ltsugar.m4, ltversion.m4, lt~obsolete.m4:
+ New files to support libtool.
diff --git a/extension/m4/dirfd.m4 b/extension/m4/dirfd.m4
new file mode 100644
index 00000000..0b09a390
--- /dev/null
+++ b/extension/m4/dirfd.m4
@@ -0,0 +1,84 @@
+# serial 22 -*- Autoconf -*-
+
+dnl Find out how to get the file descriptor associated with an open DIR*.
+
+# Copyright (C) 2001-2006, 2008-2013 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.
+
+dnl From Jim Meyering
+dnl Simplified for gawk
+
+AC_DEFUN([GAWK_FUNC_DIRFD],
+[
+dnl AC_REQUIRE([gl_DIRENT_H_DEFAULTS])
+
+ dnl Persuade glibc <dirent.h> to declare dirfd().
+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+ AC_CHECK_FUNCS([dirfd])
+ AC_CHECK_DECLS([dirfd], , ,
+ [[#include <sys/types.h>
+ #include <dirent.h>]])
+ if test $ac_cv_have_decl_dirfd = no; then
+ HAVE_DECL_DIRFD=0
+ fi
+
+ AC_CACHE_CHECK([whether dirfd is a macro],
+ gl_cv_func_dirfd_macro,
+ [AC_EGREP_CPP([dirent_header_defines_dirfd], [
+#include <sys/types.h>
+#include <dirent.h>
+#ifdef dirfd
+ dirent_header_defines_dirfd
+#endif],
+ gl_cv_func_dirfd_macro=yes,
+ gl_cv_func_dirfd_macro=no)])
+
+ # Use the replacement only if we have no function or macro with that name.
+ if test $ac_cv_func_dirfd = no && test $gl_cv_func_dirfd_macro = no; then
+ if test $ac_cv_have_decl_dirfd = yes; then
+ # If the system declares dirfd already, let's declare rpl_dirfd instead.
+ REPLACE_DIRFD=1
+ fi
+ fi
+])
+
+dnl Prerequisites of lib/dirfd.c.
+AC_DEFUN([GAWK_PREREQ_DIRFD],
+[
+ AC_CACHE_CHECK([how to get the file descriptor associated with an open DIR*],
+ [gl_cv_sys_dir_fd_member_name],
+ [
+ dirfd_save_CFLAGS=$CFLAGS
+ for ac_expr in d_fd dd_fd; do
+
+ CFLAGS="$CFLAGS -DDIR_FD_MEMBER_NAME=$ac_expr"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ #include <sys/types.h>
+ #include <dirent.h>]],
+ [[DIR *dir_p = opendir("."); (void) dir_p->DIR_FD_MEMBER_NAME;]])],
+ [dir_fd_found=yes]
+ )
+ CFLAGS=$dirfd_save_CFLAGS
+ test "$dir_fd_found" = yes && break
+ done
+ test "$dir_fd_found" = yes || ac_expr=no_such_member
+
+ gl_cv_sys_dir_fd_member_name=$ac_expr
+ ]
+ )
+ if test $gl_cv_sys_dir_fd_member_name != no_such_member; then
+ AC_DEFINE_UNQUOTED([DIR_FD_MEMBER_NAME],
+ [$gl_cv_sys_dir_fd_member_name],
+ [the name of the file descriptor member of DIR])
+ fi
+ AH_VERBATIM([DIR_TO_FD],
+ [#ifdef DIR_FD_MEMBER_NAME
+# define DIR_TO_FD(Dir_p) ((Dir_p)->DIR_FD_MEMBER_NAME)
+#else
+# define DIR_TO_FD(Dir_p) -1
+#endif
+])
+])
diff --git a/extension/m4/gettext.m4 b/extension/m4/gettext.m4
new file mode 100644
index 00000000..f84e6a5d
--- /dev/null
+++ b/extension/m4/gettext.m4
@@ -0,0 +1,383 @@
+# gettext.m4 serial 63 (gettext-0.18)
+dnl Copyright (C) 1995-2010 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-2006, 2008-2010.
+
+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(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old],
+ [AC_DIAGNOSE([obsolete], [Use of AM_GNU_GETTEXT without [external] argument is deprecated.])])
+ 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],
+ ifdef([AM_GNU_GETTEXT_][INTL_SUBDIR], [yes], [no]),
+ [yes]))
+ define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], []))
+ gt_NEEDS_INIT
+ AM_GNU_GETTEXT_NEED([$2])
+
+ 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 { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "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.
+ AC_REQUIRE([AM_NLS])
+
+ ifelse(gt_included_intl, yes, [
+ BUILD_INCLUDED_LIBINTL=no
+ USE_INCLUDED_LIBINTL=no
+ ])
+ LIBINTL=
+ LTLIBINTL=
+ POSUB=
+
+ dnl Add a version number to the cache macros.
+ case " $gt_needs " in
+ *" need-formatstring-macros "*) gt_api_version=3 ;;
+ *" need-ngettext "*) gt_api_version=2 ;;
+ *) gt_api_version=1 ;;
+ esac
+ gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc"
+ gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl"
+
+ 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.
+
+ if test $gt_api_version -ge 3; then
+ gt_revision_test_code='
+#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
+'
+ else
+ gt_revision_test_code=
+ fi
+ if test $gt_api_version -ge 2; then
+ gt_expression_test_code=' + * ngettext ("", "", 0)'
+ else
+ gt_expression_test_code=
+ fi
+
+ AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc],
+ [AC_TRY_LINK([#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern int *_nl_domain_bindings;],
+ [bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings],
+ [eval "$gt_func_gnugettext_libc=yes"],
+ [eval "$gt_func_gnugettext_libc=no"])])
+
+ if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "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_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>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);],
+ [bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
+ [eval "$gt_func_gnugettext_libintl=yes"],
+ [eval "$gt_func_gnugettext_libintl=no"])
+ dnl Now see whether libintl exists and depends on libiconv.
+ if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then
+ LIBS="$LIBS $LIBICONV"
+ AC_TRY_LINK([#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);],
+ [bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
+ [LIBINTL="$LIBINTL $LIBICONV"
+ LTLIBINTL="$LTLIBINTL $LTLIBICONV"
+ eval "$gt_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 { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \
+ || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "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 $LIBTHREAD"
+ LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV $LTLIBTHREAD"
+ 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 { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "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 { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "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 gt_NEEDS_INIT ensures that the gt_needs variable is initialized.
+m4_define([gt_NEEDS_INIT],
+[
+ m4_divert_text([DEFAULTS], [gt_needs=])
+ m4_define([gt_NEEDS_INIT], [])
+])
+
+
+dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL])
+AC_DEFUN([AM_GNU_GETTEXT_NEED],
+[
+ m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"])
+])
+
+
+dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version])
+AC_DEFUN([AM_GNU_GETTEXT_VERSION], [])
diff --git a/extension/m4/iconv.m4 b/extension/m4/iconv.m4
new file mode 100644
index 00000000..e2041b9b
--- /dev/null
+++ b/extension/m4/iconv.m4
@@ -0,0 +1,214 @@
+# iconv.m4 serial 11 (gettext-0.18.1)
+dnl Copyright (C) 2000-2002, 2007-2010 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).
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+
+ 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_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [
+ dnl This tests against bugs in AIX 5.1, HP-UX 11.11, Solaris 10.
+ am_save_LIBS="$LIBS"
+ if test $am_cv_lib_iconv = yes; then
+ LIBS="$LIBS $LIBICONV"
+ fi
+ AC_TRY_RUN([
+#include <iconv.h>
+#include <string.h>
+int main ()
+{
+ /* Test against AIX 5.1 bug: Failures are not distinguishable from successful
+ returns. */
+ {
+ iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
+ if (cd_utf8_to_88591 != (iconv_t)(-1))
+ {
+ static const char input[] = "\342\202\254"; /* EURO SIGN */
+ char buf[10];
+ const char *inptr = input;
+ size_t inbytesleft = strlen (input);
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_utf8_to_88591,
+ (char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if (res == 0)
+ return 1;
+ }
+ }
+ /* Test against Solaris 10 bug: Failures are not distinguishable from
+ successful returns. */
+ {
+ iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
+ if (cd_ascii_to_88591 != (iconv_t)(-1))
+ {
+ static const char input[] = "\263";
+ char buf[10];
+ const char *inptr = input;
+ size_t inbytesleft = strlen (input);
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_ascii_to_88591,
+ (char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if (res == 0)
+ return 1;
+ }
+ }
+#if 0 /* This bug could be worked around by the caller. */
+ /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */
+ {
+ iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
+ if (cd_88591_to_utf8 != (iconv_t)(-1))
+ {
+ static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+ char buf[50];
+ const char *inptr = input;
+ size_t inbytesleft = strlen (input);
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_88591_to_utf8,
+ (char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if ((int)res > 0)
+ return 1;
+ }
+ }
+#endif
+ /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
+ provided. */
+ if (/* Try standardized names. */
+ iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
+ /* Try IRIX, OSF/1 names. */
+ && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
+ /* Try AIX names. */
+ && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
+ /* Try HP-UX names. */
+ && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
+ return 1;
+ return 0;
+}], [am_cv_func_iconv_works=yes], [am_cv_func_iconv_works=no],
+ [case "$host_os" in
+ aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
+ *) am_cv_func_iconv_works="guessing yes" ;;
+ esac])
+ LIBS="$am_save_LIBS"
+ ])
+ case "$am_cv_func_iconv_works" in
+ *no) am_func_iconv=no am_cv_lib_iconv=no ;;
+ *) am_func_iconv=yes ;;
+ esac
+ else
+ am_func_iconv=no am_cv_lib_iconv=no
+ fi
+ if test "$am_func_iconv" = yes; then
+ AC_DEFINE([HAVE_ICONV], [1],
+ [Define if you have the iconv() function and it works.])
+ 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])
+])
+
+dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to
+dnl avoid warnings like
+dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required".
+dnl This is tricky because of the way 'aclocal' is implemented:
+dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN.
+dnl Otherwise aclocal's initial scan pass would miss the macro definition.
+dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions.
+dnl Otherwise aclocal would emit many "Use of uninitialized value $1"
+dnl warnings.
+m4_define([gl_iconv_AC_DEFUN],
+ m4_version_prereq([2.64],
+ [[AC_DEFUN_ONCE(
+ [$1], [$2])]],
+ [[AC_DEFUN(
+ [$1], [$2])]]))
+gl_iconv_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([
+ $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
+])
diff --git a/extension/m4/intlmacosx.m4 b/extension/m4/intlmacosx.m4
new file mode 100644
index 00000000..dd910259
--- /dev/null
+++ b/extension/m4/intlmacosx.m4
@@ -0,0 +1,51 @@
+# intlmacosx.m4 serial 3 (gettext-0.18)
+dnl Copyright (C) 2004-2010 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 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_LIBS="$LIBS"
+ LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
+ AC_TRY_LINK([#include <CoreFoundation/CFPreferences.h>],
+ [CFPreferencesCopyAppValue(NULL, NULL)],
+ [gt_cv_func_CFPreferencesCopyAppValue=yes],
+ [gt_cv_func_CFPreferencesCopyAppValue=no])
+ 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_LIBS="$LIBS"
+ LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
+ AC_TRY_LINK([#include <CoreFoundation/CFLocale.h>], [CFLocaleCopyCurrent();],
+ [gt_cv_func_CFLocaleCopyCurrent=yes],
+ [gt_cv_func_CFLocaleCopyCurrent=no])
+ 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])
+])
diff --git a/extension/m4/lib-ld.m4 b/extension/m4/lib-ld.m4
new file mode 100644
index 00000000..ebb30528
--- /dev/null
+++ b/extension/m4/lib-ld.m4
@@ -0,0 +1,110 @@
+# lib-ld.m4 serial 4 (gettext-0.18)
+dnl Copyright (C) 1996-2003, 2009-2010 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
+])
diff --git a/extension/m4/lib-link.m4 b/extension/m4/lib-link.m4
new file mode 100644
index 00000000..c73bd8e3
--- /dev/null
+++ b/extension/m4/lib-link.m4
@@ -0,0 +1,774 @@
+# lib-link.m4 serial 21 (gettext-0.18)
+dnl Copyright (C) 2001-2010 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.54])
+
+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.
+dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
+dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
+AC_DEFUN([AC_LIB_LINKFLAGS],
+[
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+ pushdef([Name],[translit([$1],[./-], [___])])
+ pushdef([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"
+ ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX"
+ ])
+ LIB[]NAME="$ac_cv_lib[]Name[]_libs"
+ LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
+ INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
+ LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix"
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
+ AC_SUBST([LIB]NAME)
+ AC_SUBST([LTLIB]NAME)
+ AC_SUBST([LIB]NAME[_PREFIX])
+ 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
+ popdef([NAME])
+ popdef([Name])
+])
+
+dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message])
+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. The missing-message
+dnl defaults to 'no' and may contain additional hints for the user.
+dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME}
+dnl and 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.
+dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
+dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
+AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
+[
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+ pushdef([Name],[translit([$1],[./-], [___])])
+ pushdef([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"
+ dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS,
+ dnl because these -l options might require -L options that are present in
+ dnl LIBS. -l options benefit only from the -L options listed before it.
+ dnl Otherwise, add it to the front of LIBS, because it may be a static
+ dnl library that depends on another static library that is present in LIBS.
+ dnl Static libraries benefit only from the static libraries listed after
+ dnl it.
+ case " $LIB[]NAME" in
+ *" -l"*) LIBS="$LIBS $LIB[]NAME" ;;
+ *) LIBS="$LIB[]NAME $LIBS" ;;
+ esac
+ AC_TRY_LINK([$3], [$4],
+ [ac_cv_lib[]Name=yes],
+ [ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])'])
+ 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 lib][$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=
+ LIB[]NAME[]_PREFIX=
+ fi
+ AC_SUBST([HAVE_LIB]NAME)
+ AC_SUBST([LIB]NAME)
+ AC_SUBST([LTLIB]NAME)
+ AC_SUBST([LIB]NAME[_PREFIX])
+ popdef([NAME])
+ popdef([Name])
+])
+
+dnl Determine the platform dependent parameters needed to use rpath:
+dnl acl_libext,
+dnl acl_shlibext,
+dnl acl_hardcode_libdir_flag_spec,
+dnl acl_hardcode_libdir_separator,
+dnl acl_hardcode_direct,
+dnl acl_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"
+ acl_libext="$acl_cv_libext"
+ acl_shlibext="$acl_cv_shlibext"
+ acl_libname_spec="$acl_cv_libname_spec"
+ acl_library_names_spec="$acl_cv_library_names_spec"
+ acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
+ acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
+ acl_hardcode_direct="$acl_cv_hardcode_direct"
+ acl_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_FROMPACKAGE(name, package)
+dnl declares that libname comes from the given package. The configure file
+dnl will then not have a --with-libname-prefix option but a
+dnl --with-package-prefix option. Several libraries can come from the same
+dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar
+dnl macro call that searches for libname.
+AC_DEFUN([AC_LIB_FROMPACKAGE],
+[
+ pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ define([acl_frompackage_]NAME, [$2])
+ popdef([NAME])
+ pushdef([PACK],[$2])
+ pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ define([acl_libsinpackage_]PACKUP,
+ m4_ifdef([acl_libsinpackage_]PACKUP, [acl_libsinpackage_]PACKUP[[, ]],)[lib$1])
+ popdef([PACKUP])
+ popdef([PACK])
+])
+
+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.
+dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found
+dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
+AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
+[
+ AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+ pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])])
+ pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])])
+ dnl Autoconf >= 2.61 supports dots in --with options.
+ pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit(PACK,[.],[_])],PACK)])
+ 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_ARG_WITH(P_A_C_K[-prefix],
+[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib
+ --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ 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/$acl_libdirstem"
+ if test "$acl_libdirstem2" != "$acl_libdirstem" \
+ && ! test -d "$withval/$acl_libdirstem"; then
+ additional_libdir="$withval/$acl_libdirstem2"
+ fi
+ 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=
+ LIB[]NAME[]_PREFIX=
+ dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been
+ dnl computed. So it has to be reset here.
+ HAVE_LIB[]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=
+ eval libname=\"$acl_libname_spec\" # typically: libname=lib$name
+ if test -n "$acl_shlibext"; then
+ shrext=".$acl_shlibext" # typically: shrext=.so
+ else
+ shrext=
+ fi
+ if test $use_additional = yes; then
+ dir="$additional_libdir"
+ dnl The same code as in the loop below:
+ dnl First look for a shared library.
+ if test -n "$acl_shlibext"; then
+ if test -f "$dir/$libname$shrext"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext"
+ else
+ if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+ ver=`(cd "$dir" && \
+ for f in "$libname$shrext".*; do echo "$f"; done \
+ | sed -e "s,^$libname$shrext\\\\.,," \
+ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+ | sed 1q ) 2>/dev/null`
+ if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext.$ver"
+ fi
+ else
+ eval library_names=\"$acl_library_names_spec\"
+ for f in $library_names; do
+ if test -f "$dir/$f"; then
+ found_dir="$dir"
+ found_so="$dir/$f"
+ break
+ fi
+ done
+ fi
+ fi
+ fi
+ dnl Then look for a static library.
+ if test "X$found_dir" = "X"; then
+ if test -f "$dir/$libname.$acl_libext"; then
+ found_dir="$dir"
+ found_a="$dir/$libname.$acl_libext"
+ fi
+ fi
+ if test "X$found_dir" != "X"; then
+ if test -f "$dir/$libname.la"; then
+ found_la="$dir/$libname.la"
+ 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//'`
+ dnl First look for a shared library.
+ if test -n "$acl_shlibext"; then
+ if test -f "$dir/$libname$shrext"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext"
+ else
+ if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+ ver=`(cd "$dir" && \
+ for f in "$libname$shrext".*; do echo "$f"; done \
+ | sed -e "s,^$libname$shrext\\\\.,," \
+ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+ | sed 1q ) 2>/dev/null`
+ if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext.$ver"
+ fi
+ else
+ eval library_names=\"$acl_library_names_spec\"
+ for f in $library_names; do
+ if test -f "$dir/$f"; then
+ found_dir="$dir"
+ found_so="$dir/$f"
+ break
+ fi
+ done
+ fi
+ fi
+ fi
+ dnl Then look for a static library.
+ if test "X$found_dir" = "X"; then
+ if test -f "$dir/$libname.$acl_libext"; then
+ found_dir="$dir"
+ found_a="$dir/$libname.$acl_libext"
+ fi
+ fi
+ if test "X$found_dir" != "X"; then
+ if test -f "$dir/$libname.la"; then
+ found_la="$dir/$libname.la"
+ 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/$acl_libdirstem" \
+ || test "X$found_dir" = "X/usr/$acl_libdirstem2"; 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 "$acl_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 "$acl_hardcode_libdir_flag_spec" && test "$acl_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 "$acl_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 $acl_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
+ */$acl_libdirstem | */$acl_libdirstem/)
+ basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
+ if test "$name" = '$1'; then
+ LIB[]NAME[]_PREFIX="$basedir"
+ fi
+ additional_includedir="$basedir/include"
+ ;;
+ */$acl_libdirstem2 | */$acl_libdirstem2/)
+ basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'`
+ if test "$name" = '$1'; then
+ LIB[]NAME[]_PREFIX="$basedir"
+ fi
+ 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/$acl_libdirstem" \
+ && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
+ haveit=
+ if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
+ || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; 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 "$acl_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:+$acl_hardcode_libdir_separator}$found_dir"
+ done
+ dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl.
+ acl_save_libdir="$libdir"
+ libdir="$alldirs"
+ eval flag=\"$acl_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=\"$acl_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
+ popdef([P_A_C_K])
+ popdef([PACKLIBS])
+ popdef([PACKUP])
+ popdef([PACK])
+ popdef([NAME])
+])
+
+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
+])
+
+dnl For those cases where a variable contains several -L and -l options
+dnl referring to unknown libraries and directories, this macro determines the
+dnl necessary additional linker options for the runtime path.
+dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL])
+dnl sets LDADDVAR to linker options needed together with LIBSVALUE.
+dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed,
+dnl otherwise linking without libtool is assumed.
+AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
+[
+ AC_REQUIRE([AC_LIB_RPATH])
+ AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+ $1=
+ if test "$enable_rpath" != no; then
+ if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
+ dnl Use an explicit option to hardcode directories into the resulting
+ dnl binary.
+ rpathdirs=
+ next=
+ for opt in $2; do
+ if test -n "$next"; then
+ dir="$next"
+ dnl No need to hardcode the standard /usr/lib.
+ if test "X$dir" != "X/usr/$acl_libdirstem" \
+ && test "X$dir" != "X/usr/$acl_libdirstem2"; then
+ rpathdirs="$rpathdirs $dir"
+ fi
+ next=
+ else
+ case $opt in
+ -L) next=yes ;;
+ -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
+ dnl No need to hardcode the standard /usr/lib.
+ if test "X$dir" != "X/usr/$acl_libdirstem" \
+ && test "X$dir" != "X/usr/$acl_libdirstem2"; then
+ rpathdirs="$rpathdirs $dir"
+ fi
+ next= ;;
+ *) next= ;;
+ esac
+ fi
+ done
+ if test "X$rpathdirs" != "X"; then
+ if test -n ""$3""; then
+ dnl libtool is used for linking. Use -R options.
+ for dir in $rpathdirs; do
+ $1="${$1}${$1:+ }-R$dir"
+ done
+ else
+ dnl The linker is used for linking directly.
+ if test -n "$acl_hardcode_libdir_separator"; then
+ dnl Weird platform: only the last -rpath option counts, the user
+ dnl must pass all path elements in one option.
+ alldirs=
+ for dir in $rpathdirs; do
+ alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir"
+ done
+ acl_save_libdir="$libdir"
+ libdir="$alldirs"
+ eval flag=\"$acl_hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ $1="$flag"
+ else
+ dnl The -rpath options are cumulative.
+ for dir in $rpathdirs; do
+ acl_save_libdir="$libdir"
+ libdir="$dir"
+ eval flag=\"$acl_hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ $1="${$1}${$1:+ }$flag"
+ done
+ fi
+ fi
+ fi
+ fi
+ fi
+ AC_SUBST([$1])
+])
diff --git a/extension/m4/lib-prefix.m4 b/extension/m4/lib-prefix.m4
new file mode 100644
index 00000000..1601ceae
--- /dev/null
+++ b/extension/m4/lib-prefix.m4
@@ -0,0 +1,224 @@
+# lib-prefix.m4 serial 7 (gettext-0.18)
+dnl Copyright (C) 2001-2005, 2008-2010 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_MULTILIB])
+ 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/$acl_libdirstem"
+ 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/$acl_libdirstem"; 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/$acl_libdirstem"; 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"
+])
+
+dnl AC_LIB_PREPARE_MULTILIB creates
+dnl - a variable acl_libdirstem, containing the basename of the libdir, either
+dnl "lib" or "lib64" or "lib/64",
+dnl - a variable acl_libdirstem2, as a secondary possible value for
+dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or
+dnl "lib/amd64".
+AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
+[
+ dnl There is no formal standard regarding lib and lib64.
+ dnl On glibc systems, the current practice is that on a system supporting
+ dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
+ dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine
+ dnl the compiler's default mode by looking at the compiler's library search
+ dnl path. If at least one of its elements ends in /lib64 or points to a
+ dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI.
+ dnl Otherwise we use the default, namely "lib".
+ dnl On Solaris systems, the current practice is that on a system supporting
+ dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
+ dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or
+ dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib.
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ acl_libdirstem=lib
+ acl_libdirstem2=
+ case "$host_os" in
+ solaris*)
+ dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment
+ dnl <http://docs.sun.com/app/docs/doc/816-5138/dev-env?l=en&a=view>.
+ dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link."
+ dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the
+ dnl symlink is missing, so we set acl_libdirstem2 too.
+ AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit],
+ [AC_EGREP_CPP([sixtyfour bits], [
+#ifdef _LP64
+sixtyfour bits
+#endif
+ ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no])
+ ])
+ if test $gl_cv_solaris_64bit = yes; then
+ acl_libdirstem=lib/64
+ case "$host_cpu" in
+ sparc*) acl_libdirstem2=lib/sparcv9 ;;
+ i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
+ esac
+ fi
+ ;;
+ *)
+ searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
+ if test -n "$searchpath"; then
+ acl_save_IFS="${IFS= }"; IFS=":"
+ for searchdir in $searchpath; do
+ if test -d "$searchdir"; then
+ case "$searchdir" in
+ */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
+ */../ | */.. )
+ # Better ignore directories of this form. They are misleading.
+ ;;
+ *) searchdir=`cd "$searchdir" && pwd`
+ case "$searchdir" in
+ */lib64 ) acl_libdirstem=lib64 ;;
+ esac ;;
+ esac
+ fi
+ done
+ IFS="$acl_save_IFS"
+ fi
+ ;;
+ esac
+ test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
+])
diff --git a/extension/m4/libtool.m4 b/extension/m4/libtool.m4
new file mode 100644
index 00000000..068f0d8b
--- /dev/null
+++ b/extension/m4/libtool.m4
@@ -0,0 +1,8027 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+# Copyright (C) 1996-2001, 2003-2014 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 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.
+
+m4_define([_LT_COPYING], [dnl
+# Copyright (C) 2014 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.
+
+# GNU Libtool 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 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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, see <http://www.gnu.org/licenses/>.
+])
+
+# serial 58 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+ [m4_default([$3],
+ [m4_fatal([Libtool version $1 or higher is required],
+ 63)])],
+ [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+ *\ * | *\ *)
+ AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS=$ltmain
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+m4_defun([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+m4_require([_LT_CMD_TRUNCATE])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+old_CC=$CC
+old_CFLAGS=$CFLAGS
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ _LT_PATH_MAGIC
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from 'configure', and 'config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
+# 'config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain=$ac_aux_dir/ltmain.sh
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the 'libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+ [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME. Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+ [m4_ifval([$1], [$1], [$2])])
+ lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+ m4_ifval([$4],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+ lt_dict_add_subkey([lt_decl_dict], [$2],
+ [tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+ [0], [m4_fatal([$0: too few arguments: $#])],
+ [1], [m4_fatal([$0: too few arguments: $#: $1])],
+ [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+ [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+ [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+ m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_if([$2], [],
+ m4_quote(lt_decl_varnames),
+ m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+ lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to 'config.status' so that its
+# declaration there will have the same value as in 'configure'. VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly. In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+ [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags='_LT_TAGS'dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+# # Some comment about what VAR is for.
+# visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+ [description])))[]dnl
+m4_pushdef([_libtool_name],
+ m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+ [0], [_libtool_name=[$]$1],
+ [1], [_libtool_name=$lt_[]$1],
+ [2], [_libtool_name=$lt_[]$1],
+ [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool'
+# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+ m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into 'config.status', and then the shell code to quote escape them in
+# for loops in 'config.status'. Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+ dnl If the libtool generation code has been placed in $CONFIG_LT,
+ dnl instead of duplicating it all over again into config.status,
+ dnl then we will have config.status run $CONFIG_LT later, so it
+ dnl needs to know what name is stored there:
+ [AC_CONFIG_COMMANDS([libtool],
+ [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+ dnl If the libtool generation code is destined for config.status,
+ dnl expand the accumulated commands and init code now:
+ [AC_CONFIG_COMMANDS([libtool],
+ [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable. If COMMENT is supplied, it is inserted after the
+# '#!' sequence but before initialization text begins. After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script. The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test 0 = "$lt_write_fail" && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+ echo
+ AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+'$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+ -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
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test 0 != $[#]
+do
+ case $[1] in
+ --version | --v* | -V )
+ echo "$lt_cl_version"; exit 0 ;;
+ --help | --h* | -h )
+ echo "$lt_cl_help"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --quiet | --q* | --silent | --s* | -q )
+ lt_cl_silent=: ;;
+
+ -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try '$[0] --help' for more information.]) ;;
+
+ *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try '$[0] --help' for more information.]) ;;
+ esac
+ shift
+done
+
+if $lt_cl_silent; then
+ exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure. Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test yes = "$silent" &&
+ lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars. Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+ m4_if(_LT_TAG, [C], [
+ # See if we are running on zsh, and set the options that allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile=${ofile}T
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+ _LT_PROG_LTMAIN
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ RM='$RM'
+ ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+# autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+ [C], [_LT_LANG(C)],
+ [C++], [_LT_LANG(CXX)],
+ [Go], [_LT_LANG(GO)],
+ [Java], [_LT_LANG(GCJ)],
+ [Fortran 77], [_LT_LANG(F77)],
+ [Fortran], [_LT_LANG(FC)],
+ [Windows Resource], [_LT_LANG(RC)],
+ [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+ [_LT_LANG($1)],
+ [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+ [LT_SUPPORTED_TAG([$1])dnl
+ m4_append([_LT_TAGS], [$1 ])dnl
+ m4_define([_LT_LANG_]$1[_enabled], [])dnl
+ _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_GO. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC], [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+ if test -n "$ac_tool_prefix"; then
+ AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+ fi
+fi
+if test -z "$GOC"; then
+ AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [LT_LANG(CXX)],
+ [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [LT_LANG(F77)],
+ [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [LT_LANG(FC)],
+ [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [m4_ifdef([AC_PROG_GCJ],
+ [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([A][M_PROG_GCJ],
+ [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([LT_PROG_GCJ],
+ [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+ [LT_LANG(GO)],
+ [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+ [LT_LANG(RC)],
+ [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+ case $host_os in
+ rhapsody* | darwin*)
+ AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+ AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+ AC_CHECK_TOOL([LIPO], [lipo], [:])
+ AC_CHECK_TOOL([OTOOL], [otool], [:])
+ AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+ _LT_DECL([], [DSYMUTIL], [1],
+ [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+ _LT_DECL([], [NMEDIT], [1],
+ [Tool to change global to local symbols on Mac OS X])
+ _LT_DECL([], [LIPO], [1],
+ [Tool to manipulate fat objects and archives on Mac OS X])
+ _LT_DECL([], [OTOOL], [1],
+ [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+ _LT_DECL([], [OTOOL64], [1],
+ [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+ [lt_cv_apple_cc_single_mod=no
+ if test -z "$LT_MULTI_MODULE"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi])
+
+ AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+ [lt_cv_ld_exported_symbols_list],
+ [lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [lt_cv_ld_exported_symbols_list=yes],
+ [lt_cv_ld_exported_symbols_list=no])
+ LDFLAGS=$save_LDFLAGS
+ ])
+
+ AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+ [lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+ echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+ $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+ echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+ $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+ ])
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ 10.[[012]][[,.]]*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test yes = "$lt_cv_apple_cc_single_mod"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test yes = "$lt_cv_ld_exported_symbols_list"; then
+ _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+ fi
+ if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+ m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ if test yes = "$lt_cv_ld_force_load"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+ [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined
+ case $cc_basename in
+ ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test yes = "$_lt_dar_can_shared"; then
+ output_verbose_link_cmd=func_echo_all
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+ m4_if([$1], [CXX],
+[ if test yes != "$lt_cv_apple_cc_single_mod"; then
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+ fi
+],[])
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+ lt_aix_libpath_sed='[
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }]'
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi],[])
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib
+ fi
+ ])
+ aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script that will find a shell with a builtin
+# printf (that we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+case $ECHO in
+ printf*) AC_MSG_RESULT([printf]) ;;
+ print*) AC_MSG_RESULT([print -r]) ;;
+ *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test "X`printf %s $ECHO`" = "X$ECHO" \
+ || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
+ [Search for dependent libraries within DIR (or the compiler's sysroot
+ if not specified).])],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted. We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case $with_sysroot in #(
+ yes)
+ if test yes = "$GCC"; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ AC_MSG_RESULT([$with_sysroot])
+ AC_MSG_ERROR([The sysroot must be an absolute path.])
+ ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and where our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+ [AS_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out what ABI is being produced by ac_compile, and set mode
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE=32
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE=64
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+mips64*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ emul=elf
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ emul="${emul}32"
+ ;;
+ *64-bit*)
+ emul="${emul}64"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *MSB*)
+ emul="${emul}btsmip"
+ ;;
+ *LSB*)
+ emul="${emul}ltsmip"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *N32*)
+ emul="${emul}n32"
+ ;;
+ esac
+ LD="${LD-ld} -m $emul"
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly. Note that the listed cases only cover the
+ # situations where additional linker options are needed (such as when
+ # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+ # vice versa); the common cases where no linker options are needed do
+ # not appear in the list.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ powerpc64le-*linux*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ powerpcle-*linux*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS=$CFLAGS
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_PUSH(C)
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_POP])
+ if test yes != "$lt_cv_cc_needs_belf"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS=$SAVE_CFLAGS
+ fi
+ ;;
+*-*solaris*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*|x86_64-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD=${LD-ld}_sol2
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks=$enable_libtool_lock
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+ [lt_cv_ar_at_file=no
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+ [echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([lt_ar_try])
+ if test 0 -eq "$ac_status"; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ AC_TRY_EVAL([lt_ar_try])
+ if test 0 -ne "$ac_status"; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+ ])
+ ])
+
+if test no = "$lt_cv_ar_at_file"; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+ [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+ [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ bitrig* | openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+ [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+ [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ fi
+ $RM conftest*
+])
+
+if test yes = "[$]$2"; then
+ m4_if([$5], , :, [$5])
+else
+ m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS $3"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&AS_MESSAGE_LOG_FD
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ else
+ $2=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+])
+
+if test yes = "[$]$2"; then
+ m4_if([$4], , :, [$4])
+else
+ m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+ i=0
+ teststring=ABCD
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test 17 != "$i" # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+])
+if test -n "$lt_cv_sys_max_cmd_len"; then
+ AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+ AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+ [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test yes = "$cross_compiling"; then :
+ [$4]
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}]
+_LT_EOF
+ if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_dlunknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test yes != "$enable_dlopen"; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen=load_add_on
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen=LoadLibrary
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[
+ lt_cv_dlopen=dyld
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ])
+ ;;
+
+ tpf*)
+ # Don't try to run any link tests for TPF. We know it's impossible
+ # because TPF is a cross-compiler, and we know how we open DSOs.
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=no
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen=shl_load],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen=dlopen],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test no = "$lt_cv_dlopen"; then
+ enable_dlopen=no
+ else
+ enable_dlopen=yes
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS=$CPPFLAGS
+ test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS=$LDFLAGS
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS=$LIBS
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test yes = "$lt_cv_dlopen_self"; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS=$save_CPPFLAGS
+ LDFLAGS=$save_LDFLAGS
+ LIBS=$save_LIBS
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+ [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+ [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+ [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+ fi
+ fi
+ chmod u+w . 2>&AS_MESSAGE_LOG_FD
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+ [Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links=nottested
+if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test no = "$hard_links"; then
+ AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+ [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/",
+ [Define to the sub-directory where libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+ test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+ test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then
+
+ # We can hardcode non-existent directories.
+ if test no != "$_LT_TAGVAR(hardcode_direct, $1)" &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" &&
+ test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then
+ # Linking always hardcodes the temporary library directory.
+ _LT_TAGVAR(hardcode_action, $1)=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ _LT_TAGVAR(hardcode_action, $1)=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test relink = "$_LT_TAGVAR(hardcode_action, $1)" ||
+ test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+ test no = "$enable_shared"; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+ [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP"; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+ [], [
+if test yes = "$GCC"; then
+ case $host_os in
+ darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+ *) lt_awk_arg='/^libraries:/' ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
+ *) lt_sed_strip_eq='s|=/|/|g' ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary...
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ # ...but if some path component already ends with the multilib dir we assume
+ # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+ case "$lt_multi_os_dir; $lt_search_path_spec " in
+ "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+ lt_multi_os_dir=
+ ;;
+ esac
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+ elif test -n "$lt_multi_os_dir"; then
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS = " "; FS = "/|\n";} {
+ lt_foo = "";
+ lt_count = 0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo = "/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+ if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+
+aix[[4-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 supports IA64
+ library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line '#! .'. This would cause the generated library to
+ # depend on '.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test yes = "$aix_use_runtimelinking"; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='$libname$shared_ext'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[[45]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ library_names_spec='$libname.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec=$LIB
+ if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$major$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[[23]].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ if test 32 = "$HPUX_IA64_MODE"; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[[3-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+ sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+ [lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+ [lt_cv_shlibpath_overrides_runpath=yes])])
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+ ])
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd* | bitrig*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec=/usr/lib
+ need_lib_prefix=no
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ need_version=no
+ else
+ need_version=yes
+ fi
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=.dll
+ need_lib_prefix=no
+ library_names_spec='$libname$shared_ext $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test yes = "$with_gnu_ld"; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+ soname_spec='$libname$shared_ext.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test yes = "$with_gnu_ld"; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+ sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+ sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+ [Variables whose values should be saved in libtool wrapper scripts and
+ restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+ [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+ [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+ [[List of archive names. First name is the real one, the rest are links.
+ The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+ [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+ [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+ [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+ [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+ [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+ [[As "finish_cmds", except a single script fragment to be evaled but
+ not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+ [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+ [Compile-time system search path for libraries])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+ [Run-time system search path for libraries])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program that can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] | ?:[\\/]*])
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="m4_if([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$1"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac])
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+ [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program that can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+ [AS_HELP_STRING([--with-gnu-ld],
+ [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+ [test no = "$withval" || with_gnu_ld=yes],
+ [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test yes = "$GCC"; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by $CC])
+ 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.
+ [[\\/]]* | ?:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the pathname 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 yes = "$with_gnu_ld"; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD=$ac_dir/$ac_prog
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test no != "$with_gnu_ld" && break
+ ;;
+ *)
+ test yes != "$with_gnu_ld" && break
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+else
+ lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi])
+LD=$lt_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])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+ lt_cv_ld_reload_flag,
+ [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test yes != "$GCC"; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test yes = "$GCC"; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_PATH_DD
+# -----------
+# find a working dd
+m4_defun([_LT_PATH_DD],
+[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd],
+[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi])
+rm -f conftest.i conftest2.i conftest.out])
+])# _LT_PATH_DD
+
+
+# _LT_CMD_TRUNCATE
+# ----------------
+# find command to truncate a binary pipe
+m4_defun([_LT_CMD_TRUNCATE],
+[m4_require([_LT_PATH_DD])
+AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"])
+_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1],
+ [Command to truncate a binary pipe])
+])# _LT_CMD_TRUNCATE
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# 'unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[[45]]*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[[3-9]]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd* | bitrig*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+ [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+ [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+ [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+ [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM=$NM
+else
+ lt_nm_to_check=${ac_tool_prefix}nm
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/$lt_tmp_nm
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+ case $build_os in
+ mingw*) lt_bad_file=conftest.nm/nofile ;;
+ *) lt_bad_file=/dev/null ;;
+ esac
+ case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
+ *$lt_bad_file* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break 2
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break 2
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+ done
+ : ${lt_cv_path_NM=no}
+fi])
+if test no != "$lt_cv_path_NM"; then
+ NM=$lt_cv_path_NM
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+ case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols -headers"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+ AC_SUBST([DUMPBIN])
+ if test : != "$DUMPBIN"; then
+ NM=$DUMPBIN
+ fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+ [lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+ cat conftest.out >&AS_MESSAGE_LOG_FD
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh;
+ # decide which one to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd=$ECHO
+ ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+ [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+ [lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*])
+if test yes != "$lt_cv_path_mainfest_tool"; then
+ MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# _LT_DLL_DEF_P([FILE])
+# ---------------------
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with func_dll_def_p in the libtool script
+AC_DEFUN([_LT_DLL_DEF_P],
+[dnl
+ test DEF = "`$SED -n dnl
+ -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace
+ -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments
+ -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl
+ -e q dnl Only consider the first "real" line
+ $1`" dnl
+])# _LT_DLL_DEF_P
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw)
+ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, cos, LIBM=-lm)
+ ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test yes = "$GCC"; then
+ case $cc_basename in
+ nvcc*)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+ esac
+
+ _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+ lt_cv_prog_compiler_rtti_exceptions,
+ [-fno-rtti -fno-exceptions], [],
+ [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+ [Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*)
+ if test ia64 = "$host_cpu"; then
+ symcode='[[ABCDEGRST]]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[[BCDEGRST]]'
+ ;;
+osf*)
+ symcode='[[BCDEGQRST]]'
+ ;;
+solaris*)
+ symcode='[[BDRT]]'
+ ;;
+sco3.2v5*)
+ symcode='[[DT]]'
+ ;;
+sysv4.2uw2*)
+ symcode='[[DT]]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[[ABDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Gets list of data symbols to import.
+ lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+ # Adjust the below global symbol transforms to fixup imported variables.
+ lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+ lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
+ lt_c_name_lib_hook="\
+ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\
+ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'"
+else
+ # Disable hooks by default.
+ lt_cv_sys_global_symbol_to_import=
+ lt_cdecl_hook=
+ lt_c_name_hook=
+ lt_c_name_lib_hook=
+fi
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function,
+ # D for any global variable and I for any imported variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK ['"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx]"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT@&t@_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT@&t@_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS=conftstm.$ac_objext
+ CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+ if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test yes = "$pipe_works"; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+ [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+ [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1],
+ [Transform the output of nm into a list of symbols to manually relocate])
+_LT_DECL([global_symbol_to_c_name_address],
+ [lt_cv_sys_global_symbol_to_c_name_address], [1],
+ [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+ [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+ [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([nm_interface], [lt_cv_nm_interface], [1],
+ [The name lister interface])
+_LT_DECL([], [nm_file_list_spec], [1],
+ [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+m4_if([$1], [CXX], [
+ # C++ specific cases for pic, static, wl, etc.
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[[4-9]]*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ if test ia64 != "$host_cpu"; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ fi
+ ;;
+ aCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64, which still supported -KPIC.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+ # IBM XL 8.0, 9.0 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd*)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+],
+[
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+ if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ case $cc_basename in
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC (with -KPIC) is the default.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ # old Intel for x86_64, which still supported -KPIC.
+ ecc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ ccc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All Alpha code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ *Intel*\ [[CF]]*Compiler*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ *Portland\ Group*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All OSF/1 code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ rdos*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ unicos*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+])
+case $host_os in
+ # For platforms that do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+ ;;
+esac
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+ [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+ [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+ "" | " "*) ;;
+ *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+ esac],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+ [Additional compiler flags for building library objects])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+ [How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+ _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+ $lt_tmp_static_flag,
+ [],
+ [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+ [Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ case $host_os in
+ aix[[4-9]]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global defined
+ # symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
+ ;;
+ cygwin* | mingw* | cegcc*)
+ case $cc_basename in
+ cl*)
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+ ;;
+ esac
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+], [
+ runpath_var=
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(archive_cmds, $1)=
+ _LT_TAGVAR(archive_expsym_cmds, $1)=
+ _LT_TAGVAR(compiler_needs_object, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(hardcode_automatic, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ _LT_TAGVAR(hardcode_minus_L, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_TAGVAR(inherit_rpath, $1)=no
+ _LT_TAGVAR(link_all_deplibs, $1)=unknown
+ _LT_TAGVAR(module_cmds, $1)=
+ _LT_TAGVAR(module_expsym_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+ _LT_TAGVAR(thread_safe_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ _LT_TAGVAR(include_expsyms, $1)=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ' (' and ')$', so one must not match beginning or
+ # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+ # as well as any symbol that contains 'd'.
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # 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 yes != "$GCC"; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd* | bitrig*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test yes = "$with_gnu_ld"; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+ *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test yes = "$lt_use_gnu_ld_interface"; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='$wl'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[[3-9]]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test ia64 != "$host_cpu"; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test linux-dietlibc = "$host_os"; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test no = "$tmp_diet"
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ tmp_sharedflag='--shared' ;;
+ nagfor*) # NAGFOR 5.3
+ tmp_sharedflag='-Wl,-shared' ;;
+ xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+
+ if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+
+ if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then
+ runpath_var=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ 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]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+
+ if test yes = "$GCC"; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag="$shared_flag "'$wl-G'
+ fi
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test yes = "$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $wl-bnoentry $compiler_flags $wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[[45]]*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # 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.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ # FIXME: Should let the user specify the lib program.
+ _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ hpux9*)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ ;;
+
+ hpux10*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ m4_if($1, [], [
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ _LT_LINKER_OPTION([if $CC understands -b],
+ _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+ [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+ ;;
+ esac
+ fi
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+ [lt_cv_irix_exported_symbol],
+ [save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+ AC_LINK_IFELSE(
+ [AC_LANG_SOURCE(
+ [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+ [C++], [[int foo (void) { return 0; }]],
+ [Fortran 77], [[
+ subroutine foo
+ end]],
+ [Fortran], [[
+ subroutine foo
+ end]])])],
+ [lt_cv_irix_exported_symbol=yes],
+ [lt_cv_irix_exported_symbol=no])
+ LDFLAGS=$save_LDFLAGS])
+ if test yes = "$lt_cv_irix_exported_symbol"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+ fi
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ fi
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+ if test yes = "$GCC"; then
+ wlarc='$wl'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='$wl'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'. GCC discards it without '$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ sunos4*)
+ if test sequent = "$host_vendor"; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ ;;
+ motorola)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4.3*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ if test sni = "$host_vendor"; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+ [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+ # Assume -lc should be added
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+ if test yes,yes = "$GCC,$enable_shared"; then
+ case $_LT_TAGVAR(archive_cmds, $1) in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+ [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+ [$RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+ pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+ then
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ else
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ fi
+ _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ ])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+ [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+ [enable_shared_with_static_runtimes], [0],
+ [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+ [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+ [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+ [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+ [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+ [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+ [Commands used to build a loadable module if different from building
+ a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+ [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+ [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+ [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+ [Flag to hardcode $libdir into a binary during linking.
+ This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+ [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+ [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+ DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+ [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+ DIR into the resulting binary and the resulting library dependency is
+ "absolute", i.e impossible to change by setting $shlibpath_var if the
+ library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+ [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+ [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+ [Set to "yes" if building a shared library automatically hardcodes DIR
+ into the library and all subsequent libraries and executables linked
+ against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+ [Set to yes if linker adds runtime paths of dependent libraries
+ to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+ [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+ [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+ [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+ [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+ [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+ [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+ [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+ [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC=$CC
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+ LT_SYS_DLOPEN_SELF
+ _LT_CMD_STRIPLIB
+
+ # Report what library types will actually be built
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test ia64 != "$host_cpu" && test no = "$aix_use_runtimelinking"; then
+ test yes = "$enable_shared" && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC=$lt_save_CC
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test no != "$CXX" &&
+ ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
+ (test g++ != "$CXX"))); then
+ AC_PROG_CXXCPP
+else
+ _lt_caught_CXX_error=yes
+fi
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_caught_CXX_error"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_CFLAGS=$CFLAGS
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ CFLAGS=$CXXFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+ else
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+ fi
+
+ if test yes = "$GXX"; then
+ # Set up default GNU C++ configuration
+
+ LT_PATH_LD
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test yes = "$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='$wl'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aix[[4-9]]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ 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]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+
+ if test yes = "$GXX"; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag=$shared_flag' $wl-G'
+ fi
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test yes = "$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared
+ # libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $wl-bnoentry $compiler_flags $wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $GXX,$cc_basename in
+ ,cl* | no,cl*)
+ # Native MSVC
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # g++
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ freebsd2.*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ freebsd-elf*)
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ hpux9*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ if test no = "$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+ fi
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+ esac
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+ _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ $RANLIB $oldlib'
+ _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 6 and above use weak symbols
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+ ;;
+ xl* | mpixl* | bgxl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=func_echo_all
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
+ $RM $lib.exp'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes,no = "$GXX,$with_gnu_ld"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ case $host in
+ osf3*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test yes,no = "$GXX,$with_gnu_ld"; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require '-G' NOT '-shared' on this
+ # platform.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ fi
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+ '"$_LT_TAGVAR(old_archive_cmds, $1)"
+ _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+ '"$_LT_TAGVAR(reload_cmds, $1)"
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+ test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+
+ _LT_TAGVAR(GCC, $1)=$GXX
+ _LT_TAGVAR(LD, $1)=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test yes != "$_lt_caught_CXX_error"
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+ case @S|@2 in
+ .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;;
+ *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;;
+ esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library. It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer*4 a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+ private int a;
+ public void bar (void) {
+ a = 0;
+ }
+};
+_LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case $prev$p in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test x-L = "$p" ||
+ test x-R = "$p"; then
+ prev=$p
+ continue
+ fi
+
+ # Expand the sysroot to ease extracting the directories later.
+ if test -z "$prev"; then
+ case $p in
+ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+ esac
+ fi
+ case $p in
+ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+ esac
+ if test no = "$pre_test_object_deps_done"; then
+ case $prev in
+ -L | -R)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+ _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p
+ else
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+ _LT_TAGVAR(postdeps, $1)=$prev$p
+ else
+ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p"
+ fi
+ fi
+ prev=
+ ;;
+
+ *.lto.$objext) ;; # Ignore GCC LTO objects
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test no = "$pre_test_object_deps_done"; then
+ if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+ _LT_TAGVAR(predep_objects, $1)=$p
+ else
+ _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+ fi
+ else
+ if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+ _LT_TAGVAR(postdep_objects, $1)=$p
+ else
+ _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ _LT_TAGVAR(predep_objects,$1)=
+ _LT_TAGVAR(postdep_objects,$1)=
+ _LT_TAGVAR(postdeps,$1)=
+ ;;
+
+linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ if test yes != "$solaris_use_stlport4"; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ # Adding this requires a known-good setup of shared libraries for
+ # Sun compiler versions before 5.6, else PIC objects from an old
+ # archive will be linked into the output, leading to subtle bugs.
+ if test yes != "$solaris_use_stlport4"; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+ [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+ [Dependencies to place before and after the objects being linked to
+ create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+ [The library search path used internally by the compiler when linking
+ a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test no = "$F77"; then
+ _lt_disable_F77=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_disable_F77"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${F77-"f77"}
+ CFLAGS=$FFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+ GCC=$G77
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test ia64 != "$host_cpu" && test no = "$aix_use_runtimelinking"; then
+ test yes = "$enable_shared" && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)=$G77
+ _LT_TAGVAR(LD, $1)=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_F77"
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test no = "$FC"; then
+ _lt_disable_FC=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_disable_FC"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${FC-"f95"}
+ CFLAGS=$FCFLAGS
+ compiler=$CC
+ GCC=$ac_cv_fc_compiler_gnu
+
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test ia64 != "$host_cpu" && test no = "$aix_use_runtimelinking"; then
+ test yes = "$enable_shared" && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu
+ _LT_TAGVAR(LD, $1)=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_FC"
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)=$LD
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)=$LD
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code=$lt_simple_compile_test_code
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+ :
+ _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+ [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+ [AC_CHECK_TOOL(GCJ, gcj,)
+ test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible. Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+ [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_SED. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for lt_ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+ test ! -f "$lt_ac_sed" && continue
+ cat /dev/null > conftest.in
+ lt_ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+ # Check for GNU sed and select it if it is found.
+ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+ lt_cv_path_SED=$lt_ac_sed
+ break
+ fi
+ while true; do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >>conftest.nl
+ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+ cmp -s conftest.out conftest.nl || break
+ # 10000 chars as input seems more than enough
+ test 10 -lt "$lt_ac_count" && break
+ lt_ac_count=`expr $lt_ac_count + 1`
+ if test "$lt_ac_count" -gt "$lt_ac_max"; then
+ lt_ac_max=$lt_ac_count
+ lt_cv_path_SED=$lt_ac_sed
+ fi
+ done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine what file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path). These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+ [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+ [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
diff --git a/extension/m4/ltoptions.m4 b/extension/m4/ltoptions.m4
new file mode 100644
index 00000000..de6520ed
--- /dev/null
+++ b/extension/m4/ltoptions.m4
@@ -0,0 +1,382 @@
+# Helper functions for option handling. -*- Autoconf -*-
+#
+# Copyright (C) 2004-2005, 2007-2009, 2011-2014 Free Software
+# Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# 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 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it. Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+ _LT_MANGLE_DEFUN([$1], [$2]),
+ [m4_warning([Unknown $1 option '$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+ [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME. If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+ dnl
+ dnl Simply set some default values (i.e off) if boolean options were not
+ dnl specified:
+ _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+ ])
+ _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+ ])
+ dnl
+ dnl If no reference was made to various pairs of opposing options, then
+ dnl we run the default mode handler for the pair. For example, if neither
+ dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
+ dnl archives by default:
+ _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+ _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+ [_LT_ENABLE_FAST_INSTALL])
+ ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS], [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the 'shared' and
+# 'disable-shared' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+ [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+ [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+ _LT_DECL([build_libtool_libs], [enable_shared], [0],
+ [Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the 'static' and
+# 'disable-static' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+ [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+ [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+ _LT_DECL([build_old_libs], [enable_static], [0],
+ [Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the 'fast-install'
+# and 'disable-fast-install' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+ [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+ [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+ [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the 'fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the 'disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
+# LT_INIT options.
+# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+ [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
+ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+ [lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for lt_pkg in $withval; do
+ IFS=$lt_save_ifs
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [pic_mode=m4_default([$1], [default])])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+ [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+ [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+ [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+ [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+ [m4_define([_LTDL_TYPE], [convenience])])
diff --git a/extension/m4/ltsugar.m4 b/extension/m4/ltsugar.m4
new file mode 100644
index 00000000..da4ac6b3
--- /dev/null
+++ b/extension/m4/ltsugar.m4
@@ -0,0 +1,124 @@
+# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
+#
+# Copyright (C) 2004-2005, 2007-2008, 2011-2014 Free Software
+# Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# 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 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+ [$#], [2], [[$2]],
+ [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+ [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59, which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+ [$#], 1, [],
+ [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+ [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+ [m4_foreach([_Lt_suffix],
+ ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+ [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+ [lt_append([$1], [$2], [$3])$4],
+ [$5])],
+ [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+ m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+ m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+ [$5],
+ [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+ [lt_join(m4_quote(m4_default([$4], [[, ]])),
+ lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+ [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
diff --git a/extension/m4/ltversion.m4 b/extension/m4/ltversion.m4
new file mode 100644
index 00000000..3535ff40
--- /dev/null
+++ b/extension/m4/ltversion.m4
@@ -0,0 +1,23 @@
+# ltversion.m4 -- version numbers -*- Autoconf -*-
+#
+# Copyright (C) 2004, 2011-2014 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004
+#
+# 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.
+
+# @configure_input@
+
+# serial 4105 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.2.458.26-92994])
+m4_define([LT_PACKAGE_REVISION], [2.4.3])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.2.458.26-92994'
+macro_revision='2.4.3'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
diff --git a/extension/m4/lt~obsolete.m4 b/extension/m4/lt~obsolete.m4
new file mode 100644
index 00000000..6975098b
--- /dev/null
+++ b/extension/m4/lt~obsolete.m4
@@ -0,0 +1,99 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
+#
+# Copyright (C) 2004-2005, 2007, 2009, 2011-2014 Free Software
+# Foundation, Inc.
+# Written by Scott James Remnant, 2004.
+#
+# 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 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else. This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
diff --git a/extension/m4/nls.m4 b/extension/m4/nls.m4
new file mode 100644
index 00000000..003704c4
--- /dev/null
+++ b/extension/m4/nls.m4
@@ -0,0 +1,32 @@
+# nls.m4 serial 5 (gettext-0.18)
+dnl Copyright (C) 1995-2003, 2005-2006, 2008-2010 Free Software Foundation,
+dnl 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])
+])
diff --git a/extension/m4/po.m4 b/extension/m4/po.m4
new file mode 100644
index 00000000..3c9884ba
--- /dev/null
+++ b/extension/m4/po.m4
@@ -0,0 +1,449 @@
+# po.m4 serial 17 (gettext-0.18)
+dnl Copyright (C) 1995-2010 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([AC_PROG_MKDIR_P])dnl defined by automake
+ AC_REQUIRE([AM_NLS])dnl
+
+ dnl Release version of the gettext macros. This is used to ensure that
+ dnl the gettext macros and po/Makefile.in.in are in sync.
+ AC_SUBST([GETTEXT_MACRO_VERSION], [0.18])
+
+ 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 Test whether it is GNU msgfmt >= 0.15.
+changequote(,)dnl
+ case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;;
+ *) MSGFMT_015=$MSGFMT ;;
+ esac
+changequote([,])dnl
+ AC_SUBST([MSGFMT_015])
+changequote(,)dnl
+ case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;;
+ *) GMSGFMT_015=$GMSGFMT ;;
+ esac
+changequote([,])dnl
+ AC_SUBST([GMSGFMT_015])
+
+ 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 Test whether it is GNU xgettext >= 0.15.
+changequote(,)dnl
+ case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;;
+ *) XGETTEXT_015=$XGETTEXT ;;
+ esac
+changequote([,])dnl
+ AC_SUBST([XGETTEXT_015])
+
+ 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 Installation directories.
+ dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we
+ dnl have to define it here, so that it can be used in po/Makefile.
+ test -n "$localedir" || localedir='${datadir}/locale'
+ AC_SUBST([localedir])
+
+ dnl Support for AM_XGETTEXT_OPTION.
+ test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS=
+ AC_SUBST([XGETTEXT_EXTRA_OPTIONS])
+
+ AC_CONFIG_COMMANDS([po-directories], [[
+ 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 < 1.5.
+ eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
+ POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
+ else
+ # The set of available languages was given in configure.in.
+ # Hide the ALL_LINGUAS assigment from automake < 1.5.
+ 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 < 1.5.
+ 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 < 1.5.
+ 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"
+])
+
+dnl Initializes the accumulator used by AM_XGETTEXT_OPTION.
+AC_DEFUN([AM_XGETTEXT_OPTION_INIT],
+[
+ XGETTEXT_EXTRA_OPTIONS=
+])
+
+dnl Registers an option to be passed to xgettext in the po subdirectory.
+AC_DEFUN([AM_XGETTEXT_OPTION],
+[
+ AC_REQUIRE([AM_XGETTEXT_OPTION_INIT])
+ XGETTEXT_EXTRA_OPTIONS="$XGETTEXT_EXTRA_OPTIONS $1"
+])
diff --git a/extension/m4/progtest.m4 b/extension/m4/progtest.m4
new file mode 100644
index 00000000..2d804ac9
--- /dev/null
+++ b/extension/m4/progtest.m4
@@ -0,0 +1,92 @@
+# progtest.m4 serial 6 (gettext-0.18)
+dnl Copyright (C) 1996-2003, 2005, 2008-2010 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
+])
diff --git a/extension/ordchr.3am b/extension/ordchr.3am
new file mode 100644
index 00000000..a2b712ff
--- /dev/null
+++ b/extension/ordchr.3am
@@ -0,0 +1,78 @@
+.TH ORDCHR 3am "Jan 15 2013" "Free Software Foundation" "GNU Awk Extension Modules"
+.SH NAME
+ordchr \- convert characters to strings and vice versa
+.SH SYNOPSIS
+.ft CW
+@load "ordchr"
+.sp
+number = ord("A")
+.br
+string = chr(65)
+.ft R
+.SH DESCRIPTION
+The
+.I ordchr
+extension adds two functions named
+.BR ord() .
+and
+.BR chr() ,
+as follows.
+.TP
+.B ord()
+This function takes a string argument, and returns the
+numeric value of the first character in the string.
+.TP
+.B chr()
+This function takes a numeric argument and returns a string
+whose first character is that represented by the number.
+.PP
+These functions are inspired by the Pascal language functions
+of the same name.
+... .SH NOTES
+... .SH BUGS
+.SH EXAMPLE
+.ft CW
+.nf
+@load "ordchr"
+\&...
+printf("The numeric value of 'A' is %d\en", ord("A"))
+printf("The string value of 65 is %s\en", chr(65))
+.fi
+.ft R
+.SH "SEE ALSO"
+.IR "GAWK: Effective AWK Programming" ,
+.IR filefuncs (3am),
+.IR fnmatch (3am),
+.IR fork (3am),
+.IR inplace (3am),
+.IR readdir (3am),
+.IR readfile (3am),
+.IR revoutput (3am),
+.IR rwarray (3am),
+.IR time (3am).
+.SH AUTHOR
+Arnold Robbins,
+.BR arnold@skeeve.com .
+.SH COPYING PERMISSIONS
+Copyright \(co 2012, 2013,
+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.
diff --git a/extension/ordchr.c b/extension/ordchr.c
index 8926a949..8ec9de3f 100644
--- a/extension/ordchr.c
+++ b/extension/ordchr.c
@@ -5,10 +5,11 @@
* arnold@skeeve.com
* 8/2001
* Revised 6/2004
+ * Revised 5/2012
*/
/*
- * Copyright (C) 2001, 2004, 2011 the Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2004, 2011, 2012, 2013 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -28,71 +29,97 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "awk.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "gawkapi.h"
+
+#include "gettext.h"
+#define _(msgid) gettext(msgid)
+#define N_(msgid) msgid
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+static const char *ext_version = "ordchr extension: version 1.0";
+static awk_bool_t (*init_func)(void) = NULL;
int plugin_is_GPL_compatible;
/* do_ord --- return numeric value of first char of string */
-static NODE *
-do_ord(int nargs)
+static awk_value_t *
+do_ord(int nargs, awk_value_t *result)
{
- NODE *str;
- int ret = -1;
+ awk_value_t str;
+ double ret = -1;
- if (do_lint && nargs > 1)
- lintwarn("ord: called with too many arguments");
+ assert(result != NULL);
- str = get_scalar_argument(0, FALSE);
- if (str != NULL) {
- (void) force_string(str);
- ret = str->stptr[0];
- } else if (do_lint)
- lintwarn("ord: called with no arguments");
+ if (do_lint && nargs > 1)
+ lintwarn(ext_id, _("ord: called with too many arguments"));
+ if (get_argument(0, AWK_STRING, & str)) {
+ ret = str.str_value.str[0];
+ } else if (do_lint) {
+ if (nargs == 0)
+ lintwarn(ext_id, _("ord: called with no arguments"));
+ else
+ lintwarn(ext_id, _("ord: called with inappropriate argument(s)"));
+ }
/* Set the return value */
- return make_number((AWKNUM) ret);
+ return make_number(ret, result);
}
/* do_chr --- turn numeric value into a string */
-static NODE *
-do_chr(int nargs)
+static awk_value_t *
+do_chr(int nargs, awk_value_t *result)
{
- NODE *num;
+ awk_value_t num;
unsigned int ret = 0;
- AWKNUM val = 0.0;
+ double val = 0.0;
char str[2];
str[0] = str[1] = '\0';
- if (do_lint && nargs > 1)
- lintwarn("chr: called with too many arguments");
+ assert(result != NULL);
+
+ if (do_lint && nargs > 1)
+ lintwarn(ext_id, _("chr: called with too many arguments"));
- num = get_scalar_argument(0, FALSE);
- if (num != NULL) {
- val = force_number(num);
+ if (get_argument(0, AWK_NUMBER, & num)) {
+ val = num.num_value;
ret = val; /* convert to int */
ret &= 0xff;
str[0] = ret;
str[1] = '\0';
- } else if (do_lint)
- lintwarn("chr: called with no arguments");
+ } else if (do_lint) {
+ if (nargs == 0)
+ lintwarn(ext_id, _("chr: called with no arguments"));
+ else
+ lintwarn(ext_id, _("chr: called with inappropriate argument(s)"));
+ }
/* Set the return value */
- return make_string(str, 1);
+ return make_const_string(str, 1, result);
}
-/* dlload --- load new builtins in this library */
+static awk_ext_func_t func_table[] = {
+ { "ord", do_ord, 1 },
+ { "chr", do_chr, 1 },
+};
-NODE *
-dlload(tree, dl)
-NODE *tree;
-void *dl;
-{
- make_builtin("ord", do_ord, 1);
- make_builtin("chr", do_chr, 1);
+/* define the dl_load function using the boilerplate macro */
- return make_number((AWKNUM) 0);
-}
+dl_load_func(func_table, ord_chr, "")
diff --git a/extension/readdir.3am b/extension/readdir.3am
new file mode 100644
index 00000000..4ba5abc7
--- /dev/null
+++ b/extension/readdir.3am
@@ -0,0 +1,105 @@
+.TH READDIR 3am "Jan 15 2013" "Free Software Foundation" "GNU Awk Extension Modules"
+.SH NAME
+readdir \- directory input parser for gawk
+.SH SYNOPSIS
+.ft CW
+@load "readdir"
+.ft R
+.SH DESCRIPTION
+The
+.I readdir
+extension
+adds an input parser for directories.
+.PP
+When this extension is in use, instead of skipping directories named
+on the command line (or with
+.BR getline ),
+they are read, with each entry returned as a record.
+.PP
+The record consists of three fields. The first two are the inode number and the
+filename, separated by a forward slash character.
+On systems where the directory entry contains the file type, the record
+has a third field which is a single letter indicating the type of the
+file:
+.B f
+for file,
+.B d
+for directory,
+.B b
+for a block device,
+.B c
+for a character device,
+.B p
+for a FIFO,
+.B l
+for a symbolic link,
+.B s
+for a socket, and
+.B u
+(unknown) for anything else.
+.PP
+On systems without the file type information, the third field is always
+.BR u .
+.SH NOTES
+On GNU/Linux systems, there are filesystems that don't support the
+.B d_type
+entry (see
+.IR readdir (3)),
+and so the file type is always
+.BR u .
+You can use the
+.I filefuncs
+extension to call
+.I stat()
+in order to get correct type information.
+... .SH BUGS
+.SH EXAMPLE
+.ft CW
+.nf
+@load "readdir"
+\&...
+BEGIN { FS = "/" }
+{ print "file name is", $2 }
+.fi
+.ft R
+.SH "SEE ALSO"
+.IR "GAWK: Effective AWK Programming" ,
+.IR filefuncs (3am),
+.IR fnmatch (3am),
+.IR fork (3am),
+.IR inplace (3am),
+.IR ordchr (3am),
+.IR readfile (3am),
+.IR revoutput (3am),
+.IR rwarray (3am),
+.IR time (3am).
+.PP
+.IR opendir (3),
+.IR readdir (3),
+.IR stat (2).
+.SH AUTHOR
+Arnold Robbins,
+.BR arnold@skeeve.com .
+.SH COPYING PERMISSIONS
+Copyright \(co 2012, 2013,
+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.
diff --git a/extension/readdir.c b/extension/readdir.c
new file mode 100644
index 00000000..7bcabcb0
--- /dev/null
+++ b/extension/readdir.c
@@ -0,0 +1,334 @@
+/*
+ * readdir.c --- Provide an input parser to read directories
+ *
+ * Arnold Robbins
+ * arnold@skeeve.com
+ * Written 7/2012
+ *
+ * Andrew Schorr and Arnold Robbins: further fixes 8/2012.
+ * Simplified 11/2012.
+ */
+
+/*
+ * Copyright (C) 2012-2014 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 3 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 HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _BSD_SOURCE
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#else
+#error Cannot compile the dirent extension on this system!
+#endif
+
+#ifdef __MINGW32__
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+#include "gawkapi.h"
+
+#include "gawkdirfd.h"
+
+#include "gettext.h"
+#define _(msgid) gettext(msgid)
+#define N_(msgid) msgid
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024 /* a good guess */
+#endif
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+static const char *ext_version = "readdir extension: version 1.0";
+
+static awk_bool_t init_readdir(void);
+static awk_bool_t (*init_func)(void) = init_readdir;
+
+int plugin_is_GPL_compatible;
+
+/* data type for the opaque pointer: */
+
+typedef struct open_directory {
+ DIR *dp;
+ char *buf;
+} open_directory_t;
+
+/* ftype --- return type of file as a single character string */
+
+static const char *
+ftype(struct dirent *entry, const char *dirname)
+{
+#ifdef DT_BLK
+ (void) dirname; /* silence warnings */
+ switch (entry->d_type) {
+ case DT_BLK: return "b";
+ case DT_CHR: return "c";
+ case DT_DIR: return "d";
+ case DT_FIFO: return "p";
+ case DT_LNK: return "l";
+ case DT_REG: return "f";
+ case DT_SOCK: return "s";
+ default:
+ case DT_UNKNOWN: return "u";
+ }
+#else
+ char fname[PATH_MAX];
+ struct stat sbuf;
+
+ strcpy(fname, dirname);
+ strcat(fname, "/");
+ strcat(fname, entry->d_name);
+ if (stat(fname, &sbuf) == 0) {
+ if (S_ISBLK(sbuf.st_mode))
+ return "b";
+ if (S_ISCHR(sbuf.st_mode))
+ return "c";
+ if (S_ISDIR(sbuf.st_mode))
+ return "d";
+ if (S_ISFIFO(sbuf.st_mode))
+ return "p";
+ if (S_ISREG(sbuf.st_mode))
+ return "f";
+#ifdef S_ISLNK
+ if (S_ISLNK(sbuf.st_mode))
+ return "l";
+#endif
+#ifdef S_ISSOCK
+ if (S_ISSOCK(sbuf.st_mode))
+ return "s";
+#endif
+ }
+ return "u";
+#endif
+}
+
+/* get_inode --- get the inode of a file */
+#ifdef ZOS_USS
+static long
+#else
+static long long
+#endif
+get_inode(struct dirent *entry, const char *dirname)
+{
+#ifdef __MINGW32__
+ char fname[PATH_MAX];
+ HANDLE fh;
+ BY_HANDLE_FILE_INFORMATION info;
+
+ sprintf(fname, "%s\\%s", dirname, entry->d_name);
+ fh = CreateFile(fname, 0, 0, NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (fh == INVALID_HANDLE_VALUE)
+ return 0;
+ if (GetFileInformationByHandle(fh, &info)) {
+ long long inode = info.nFileIndexHigh;
+
+ inode <<= 32;
+ inode += info.nFileIndexLow;
+ return inode;
+ }
+ return 0;
+#else
+ (void) dirname; /* silence warnings */
+ return entry->d_ino;
+#endif
+}
+
+/* dir_get_record --- get one record at a time out of a directory */
+
+static int
+dir_get_record(char **out, awk_input_buf_t *iobuf, int *errcode,
+ char **rt_start, size_t *rt_len)
+{
+ DIR *dp;
+ struct dirent *dirent;
+ int len;
+ open_directory_t *the_dir;
+ const char *ftstr;
+#ifdef ZOS_USS
+ unsigned long ino;
+#else
+ unsigned long long ino;
+#endif
+
+ /*
+ * The caller sets *errcode to 0, so we should set it only if an
+ * error occurs.
+ */
+
+ if (out == NULL || iobuf == NULL || iobuf->opaque == NULL)
+ return EOF;
+
+ the_dir = (open_directory_t *) iobuf->opaque;
+ dp = the_dir->dp;
+
+ /*
+ * Initialize errno, since readdir does not set it to zero on EOF.
+ */
+ errno = 0;
+ dirent = readdir(dp);
+ if (dirent == NULL) {
+ *errcode = errno; /* in case there was an error */
+ return EOF;
+ }
+
+ ino = get_inode (dirent, iobuf->name);
+
+#if defined(ZOS_USS)
+ len = sprintf(the_dir->buf, "%lu/%s", ino, dirent->d_name);
+#elif __MINGW32__
+ len = sprintf(the_dir->buf, "%I64u/%s", ino, dirent->d_name);
+#else
+ len = sprintf(the_dir->buf, "%llu/%s", ino, dirent->d_name);
+#endif
+
+ ftstr = ftype(dirent, iobuf->name);
+ len += sprintf(the_dir->buf + len, "/%s", ftstr);
+
+ *out = the_dir->buf;
+
+ *rt_start = NULL;
+ *rt_len = 0; /* set RT to "" */
+ return len;
+}
+
+/* dir_close --- close up when done */
+
+static void
+dir_close(awk_input_buf_t *iobuf)
+{
+ open_directory_t *the_dir;
+
+ if (iobuf == NULL || iobuf->opaque == NULL)
+ return;
+
+ the_dir = (open_directory_t *) iobuf->opaque;
+
+ closedir(the_dir->dp);
+ gawk_free(the_dir->buf);
+ gawk_free(the_dir);
+
+ iobuf->fd = -1;
+}
+
+/* dir_can_take_file --- return true if we want the file */
+
+static awk_bool_t
+dir_can_take_file(const awk_input_buf_t *iobuf)
+{
+ if (iobuf == NULL)
+ return awk_false;
+
+ return (iobuf->fd != INVALID_HANDLE && S_ISDIR(iobuf->sbuf.st_mode));
+}
+
+/*
+ * dir_take_control_of --- set up input parser.
+ * We can assume that dir_can_take_file just returned true,
+ * and no state has changed since then.
+ */
+
+static awk_bool_t
+dir_take_control_of(awk_input_buf_t *iobuf)
+{
+ DIR *dp;
+ open_directory_t *the_dir;
+ size_t size;
+
+ errno = 0;
+#ifdef HAVE_FDOPENDIR
+ dp = fdopendir(iobuf->fd);
+#else
+ dp = opendir(iobuf->name);
+ if (dp != NULL)
+ iobuf->fd = dirfd(dp);
+#endif
+ if (dp == NULL) {
+ warning(ext_id, _("dir_take_control_of: opendir/fdopendir failed: %s"),
+ strerror(errno));
+ update_ERRNO_int(errno);
+ return awk_false;
+ }
+
+ emalloc(the_dir, open_directory_t *, sizeof(open_directory_t), "dir_take_control_of");
+ the_dir->dp = dp;
+ size = sizeof(struct dirent) + 21 /* max digits in inode */ + 2 /* slashes */;
+ emalloc(the_dir->buf, char *, size, "dir_take_control_of");
+
+ iobuf->opaque = the_dir;
+ iobuf->get_record = dir_get_record;
+ iobuf->close_func = dir_close;
+
+ return awk_true;
+}
+
+static awk_input_parser_t readdir_parser = {
+ "readdir",
+ dir_can_take_file,
+ dir_take_control_of,
+ NULL
+};
+
+#ifdef TEST_DUPLICATE
+static awk_input_parser_t readdir_parser2 = {
+ "readdir2",
+ dir_can_take_file,
+ dir_take_control_of,
+ NULL
+};
+#endif
+
+/* init_readdir --- set things ups */
+
+static awk_bool_t
+init_readdir()
+{
+ register_input_parser(& readdir_parser);
+#ifdef TEST_DUPLICATE
+ register_input_parser(& readdir_parser2);
+#endif
+
+ return awk_true;
+}
+
+static awk_ext_func_t func_table[] = {
+ { NULL, NULL, 0 }
+};
+
+/* define the dl_load function using the boilerplate macro */
+
+dl_load_func(func_table, readdir, "")
diff --git a/extension/readfile.3am b/extension/readfile.3am
new file mode 100644
index 00000000..0cb2eb5b
--- /dev/null
+++ b/extension/readfile.3am
@@ -0,0 +1,87 @@
+.TH READFILE 3am "Mar 24 2013" "Free Software Foundation" "GNU Awk Extension Modules"
+.SH NAME
+readfile \- return the entire contents of a file as a string
+.SH SYNOPSIS
+.ft CW
+@load "readfile"
+.sp
+result = readfile("/some/path")
+.sp
+.ft R
+For making whole files be single records:
+.sp
+.ft CW
+@load "readfile"
+.br
+BEGIN { PROCINFO["readfile"] = 1 }
+.ft R
+.SH DESCRIPTION
+The
+.I readfile
+extension adds a single function named
+.BR readfile() .
+The argument is the name of the file to read.
+The return value is a string containing the entire contents of
+the requested file.
+.PP
+Upon error, the function returns the empty string and sets
+.BR ERRNO .
+.PP
+In addition, it adds an input parser that is activated if
+.ft CW
+PROCINFO["readfile"]
+.ft R
+exists.
+When activated, each input file is returned in its entirety as \f(CW$0\fR.
+\f(CWRT\fP is set to the null string.
+... .SH NOTES
+... .SH BUGS
+.SH EXAMPLE
+.ft CW
+.nf
+@load "readfile"
+\&...
+contents = readfile("/path/to/file");
+if (contents == "" && ERRNO != "") {
+ print("problem reading file", ERRNO) > "/dev/stderr"
+ ...
+}
+.fi
+.ft R
+.SH "SEE ALSO"
+.IR "GAWK: Effective AWK Programming" ,
+.IR filefuncs (3am),
+.IR fnmatch (3am),
+.IR fork (3am),
+.IR inplace (3am),
+.IR ordchr (3am),
+.IR readdir (3am),
+.IR revoutput (3am),
+.IR rwarray (3am),
+.IR time (3am).
+.SH AUTHOR
+Arnold Robbins,
+.BR arnold@skeeve.com .
+.SH COPYING PERMISSIONS
+Copyright \(co 2012, 2013, 2014,
+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.
diff --git a/extension/readfile.c b/extension/readfile.c
index c9b1efc3..d4b4aef9 100644
--- a/extension/readfile.c
+++ b/extension/readfile.c
@@ -7,10 +7,13 @@
* Mon Jun 9 17:05:11 IDT 2003
* Revised for new dynamic function facilities
* Mon Jun 14 14:53:07 IDT 2004
+ * Revised for formal API May 2012
+ * Added input parser March 2014
*/
/*
- * Copyright (C) 2002, 2003, 2004, 2011 the Free Software Foundation, Inc.
+ * Copyright (C) 2002, 2003, 2004, 2011, 2012, 2013, 2014
+ * the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -30,80 +33,217 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "awk.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _BSD_SOURCE
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "gawkapi.h"
+
+#include "gettext.h"
+#define _(msgid) gettext(msgid)
+#define N_(msgid) msgid
#ifndef O_BINARY
#define O_BINARY 0
#endif
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+static const char *ext_version = "readfile extension: version 2.0";
+static awk_bool_t init_readfile();
+static awk_bool_t (*init_func)(void) = init_readfile;
+
int plugin_is_GPL_compatible;
+/* read_file_to_buffer --- handle the mechanics of reading the file */
+
+static char *
+read_file_to_buffer(int fd, const struct stat *sbuf)
+{
+ char *text = NULL;
+ int ret;
+
+ if ((sbuf->st_mode & S_IFMT) != S_IFREG) {
+ errno = EINVAL;
+ update_ERRNO_int(errno);
+ 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) {
+ update_ERRNO_int(errno);
+ gawk_free(text);
+ text = NULL;
+ /* fall through to return */
+ }
+done:
+ return text;
+}
+
/* do_readfile --- read a file into memory */
-NODE *
-do_readfile(int nargs)
+static awk_value_t *
+do_readfile(int nargs, awk_value_t *result)
{
- NODE *filename;
- int ret = -1;
+ awk_value_t filename;
+ int ret;
struct stat sbuf;
char *text;
int fd;
- if (do_lint && nargs > 1)
- lintwarn("readfile: called with too many arguments");
+ assert(result != NULL);
+ make_null_string(result); /* default return value */
+
+ if (do_lint && nargs > 1)
+ lintwarn(ext_id, _("readfile: called with too many arguments"));
- filename = get_scalar_argument(0, FALSE);
- if (filename != NULL) {
- (void) force_string(filename);
+ unset_ERRNO();
- ret = stat(filename->stptr, & sbuf);
+ if (get_argument(0, AWK_STRING, &filename)) {
+ ret = stat(filename.str_value.str, & sbuf);
if (ret < 0) {
- update_ERRNO();
- goto done;
- } else if ((sbuf.st_mode & S_IFMT) != S_IFREG) {
- errno = EINVAL;
- ret = -1;
- update_ERRNO();
+ update_ERRNO_int(errno);
goto done;
}
- if ((fd = open(filename->stptr, O_RDONLY|O_BINARY)) < 0) {
- ret = -1;
- update_ERRNO();
+ if ((fd = open(filename.str_value.str, O_RDONLY|O_BINARY)) < 0) {
+ update_ERRNO_int(errno);
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();
- goto done;
- }
+ text = read_file_to_buffer(fd, & sbuf);
+ if (text == NULL)
+ goto done; /* ERRNO already updated */
close(fd);
- return make_string(text, sbuf.st_size);
+ make_malloced_string(text, sbuf.st_size, result);
+ goto done;
} else if (do_lint)
- lintwarn("filename: called with no arguments");
-
+ lintwarn(ext_id, _("readfile: called with no arguments"));
done:
/* Set the return value */
- return make_number((AWKNUM) ret);
+ return result;
}
+/* readfile_get_record --- read the whole file as one record */
-/* dlload --- load new builtins in this library */
+static int
+readfile_get_record(char **out, awk_input_buf_t *iobuf, int *errcode,
+ char **rt_start, size_t *rt_len)
+{
+ char *text;
-NODE *
-dlload(tree, dl)
-NODE *tree;
-void *dl;
+ /*
+ * The caller sets *errcode to 0, so we should set it only if an
+ * error occurs.
+ */
+
+ if (out == NULL || iobuf == NULL)
+ return EOF;
+
+ if (iobuf->opaque != NULL) {
+ /*
+ * Already read the whole file,
+ * free up stuff and return EOF
+ */
+ gawk_free(iobuf->opaque);
+ iobuf->opaque = NULL;
+ return EOF;
+ }
+
+ /* read file */
+ text = read_file_to_buffer(iobuf->fd, & iobuf->sbuf);
+ if (text == NULL)
+ return EOF;
+
+ /* set up the iobuf for next time */
+ iobuf->opaque = text;
+
+ /* set return values */
+ *rt_start = NULL;
+ *rt_len = 0;
+ *out = text;
+
+ /* return count */
+ return iobuf->sbuf.st_size;
+}
+
+/* readfile_can_take_file --- return true if we want the file */
+
+static awk_bool_t
+readfile_can_take_file(const awk_input_buf_t *iobuf)
+{
+ awk_value_t array, index, value;
+
+ if (iobuf == NULL)
+ return awk_false;
+
+ /*
+ * This could fail if PROCINFO isn't referenced from
+ * the awk program. It's not a "can't happen" error.
+ */
+ if (! sym_lookup("PROCINFO", AWK_ARRAY, & array)) {
+ return awk_false;
+ }
+
+ (void) make_const_string("readfile", 8, & index);
+
+ if (! get_array_element(array.array_cookie, & index, AWK_UNDEFINED, & value)) {
+ return awk_false;
+ }
+
+ return awk_true;
+}
+
+/* readfile_take_control_of --- take over the file */
+
+static awk_bool_t
+readfile_take_control_of(awk_input_buf_t *iobuf)
+{
+ if (iobuf == NULL)
+ return awk_false;
+
+ iobuf->get_record = readfile_get_record;
+ return awk_true;
+}
+
+static awk_input_parser_t readfile_parser = {
+ "readfile",
+ readfile_can_take_file,
+ readfile_take_control_of,
+ NULL
+};
+
+/* init_readfile --- set things up */
+
+static awk_bool_t
+init_readfile()
{
- make_builtin("readfile", do_readfile, 1);
+ register_input_parser(& readfile_parser);
- return make_number((AWKNUM) 0);
+ return awk_true;
}
+
+static awk_ext_func_t func_table[] = {
+ { "readfile", do_readfile, 1 },
+};
+
+/* define the dl_load function using the boilerplate macro */
+
+dl_load_func(func_table, readfile, "")
diff --git a/extension/revoutput.3am b/extension/revoutput.3am
new file mode 100644
index 00000000..9c8f062f
--- /dev/null
+++ b/extension/revoutput.3am
@@ -0,0 +1,74 @@
+.TH REVOUTPUT 3am "Jan 15 2013" "Free Software Foundation" "GNU Awk Extension Modules"
+.SH NAME
+revoutput \- Reverse output strings sample extension
+.SH SYNOPSIS
+.ft CW
+@load "revoutput"
+.sp
+BEGIN { REVOUT = 1 } # Reverse all output strings
+.ft R
+.SH DESCRIPTION
+The
+.I revoutput
+extension
+adds a simple output wrapper that reverses the characters in each output
+line.
+It's main purpose is to show how to write an output wrapper, although
+it may be mildy amusing for the unwary.
+... .SH BUGS
+.SH EXAMPLE
+.ft CW
+.nf
+@load "revoutput"
+
+BEGIN {
+ REVOUT = 1
+ print "hello, world" > "/dev/stdout"
+}
+.fi
+.ft R
+.PP
+The output from this program is:
+.PP
+.ft CW
+.nf
+dlrow ,olleh
+.fi
+.ft R
+.SH "SEE ALSO"
+.IR "GAWK: Effective AWK Programming" ,
+.IR filefuncs (3am),
+.IR fnmatch (3am),
+.IR fork (3am),
+.IR inplace (3am),
+.IR ordchr (3am),
+.IR readdir (3am),
+.IR readfile (3am),
+.IR rwarray (3am),
+.IR time (3am).
+.SH AUTHOR
+Arnold Robbins,
+.BR arnold@skeeve.com .
+.SH COPYING PERMISSIONS
+Copyright \(co 2012, 2013,
+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.
diff --git a/extension/revoutput.c b/extension/revoutput.c
new file mode 100644
index 00000000..ae4b444a
--- /dev/null
+++ b/extension/revoutput.c
@@ -0,0 +1,139 @@
+/*
+ * revoutput.c --- Provide an output wrapper that reverses lines.
+ *
+ * Arnold Robbins
+ * arnold@skeeve.com
+ * Written 8/2012
+ */
+
+/*
+ * Copyright (C) 2012, 2013 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 3 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 HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "gawkapi.h"
+
+#include "gettext.h"
+#define _(msgid) gettext(msgid)
+#define N_(msgid) msgid
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+static const char *ext_version = "revoutput extension: version 1.0";
+
+static awk_bool_t init_revoutput(void);
+static awk_bool_t (*init_func)(void) = init_revoutput;
+
+int plugin_is_GPL_compatible;
+
+/* rev_fwrite --- write out characters in reverse order */
+
+static size_t
+rev_fwrite(const void *buf, size_t size, size_t count, FILE *fp, void *opaque)
+{
+ const char *cp = buf;
+ int nbytes = size * count;
+
+ (void) opaque;
+
+ for (; nbytes >= 1; nbytes--)
+ putc(cp[nbytes-1], fp);
+
+ return (size * count);
+}
+
+
+/* revoutput_can_take_file --- return true if we want the file */
+
+static awk_bool_t
+revoutput_can_take_file(const awk_output_buf_t *outbuf)
+{
+ awk_value_t value;
+
+ if (outbuf == NULL)
+ return awk_false;
+
+ if (! sym_lookup("REVOUT", AWK_NUMBER, & value))
+ return awk_false;
+
+ return (value.num_value != 0);
+}
+
+/*
+ * revoutput_take_control_of --- set up output wrapper.
+ * We can assume that revoutput_can_take_file just returned true,
+ * and no state has changed since then.
+ */
+
+static awk_bool_t
+revoutput_take_control_of(awk_output_buf_t *outbuf)
+{
+ if (outbuf == NULL)
+ return awk_false;
+
+ outbuf->gawk_fwrite = rev_fwrite;
+ outbuf->redirected = awk_true;
+ return awk_true;
+}
+
+static awk_output_wrapper_t output_wrapper = {
+ "revoutput",
+ revoutput_can_take_file,
+ revoutput_take_control_of,
+ NULL
+};
+
+/* init_revoutput --- set things ups */
+
+static awk_bool_t
+init_revoutput()
+{
+ awk_value_t value;
+
+ register_output_wrapper(& output_wrapper);
+
+ make_number(0.0, & value); /* init to false */
+ if (! sym_update("REVOUT", & value)) {
+ warning(ext_id, _("revoutput: could not initialize REVOUT variable"));
+
+ return awk_false;
+ }
+
+ return awk_true;
+}
+
+static awk_ext_func_t func_table[] = {
+ { NULL, NULL, 0 }
+};
+
+/* define the dl_load function using the boilerplate macro */
+
+dl_load_func(func_table, revoutput, "")
diff --git a/extension/revtwoway.3am b/extension/revtwoway.3am
new file mode 100644
index 00000000..3426971e
--- /dev/null
+++ b/extension/revtwoway.3am
@@ -0,0 +1,64 @@
+.TH REVTWOWAY 3am "Jan 15 2013" "Free Software Foundation" "GNU Awk Extension Modules"
+.SH NAME
+revtwoway \- Reverse strings sample two-way processor extension
+.SH SYNOPSIS
+.ft CW
+@load "revtwoway"
+.sp
+.nf
+BEGIN {
+ cmd = "/magic/mirror"
+ print "hello, world" |& cmd
+ cmd |& getline result
+ print result
+ close(cmd)
+}
+.fi
+.ft R
+.SH DESCRIPTION
+The
+.I revtwoway
+extension
+adds a simple two-way processor that reverses the characters
+in each line sent to it for reading back by the AWK program.
+It's main purpose is to show how to write a two-way extension, although
+it may also be mildy amusing.
+... .SH BUGS
+.SH "SEE ALSO"
+.IR "GAWK: Effective AWK Programming" ,
+.IR filefuncs (3am),
+.IR fnmatch (3am),
+.IR fork (3am),
+.IR inplace (3am),
+.IR ordchr (3am),
+.IR readdir (3am),
+.IR readfile (3am),
+.IR revoutput (3am),
+.IR rwarray (3am),
+.IR time (3am).
+.SH AUTHOR
+Arnold Robbins,
+.BR arnold@skeeve.com .
+.SH COPYING PERMISSIONS
+Copyright \(co 2012, 2013,
+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.
diff --git a/extension/revtwoway.c b/extension/revtwoway.c
new file mode 100644
index 00000000..c0d9381a
--- /dev/null
+++ b/extension/revtwoway.c
@@ -0,0 +1,342 @@
+/*
+ * revtwoway.c --- Provide a two-way processor that reverses lines.
+ *
+ * Arnold Robbins
+ * arnold@skeeve.com
+ * Written 8/2012
+ */
+
+/*
+ * Copyright (C) 2012-2014 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 3 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 HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _BSD_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "gawkapi.h"
+
+#include "gettext.h"
+#define _(msgid) gettext(msgid)
+#define N_(msgid) msgid
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+static const char *ext_version = "revtwoway extension: version 1.0";
+
+static awk_bool_t init_revtwoway(void);
+static awk_bool_t (*init_func)(void) = init_revtwoway;
+
+int plugin_is_GPL_compatible;
+
+/*
+ * Use this variable to provide a value != INVALID_HANDLE in the awk_input_buf_t
+ * and != NULL in the awk_output_buf_t. The idea is to have a value that
+ * is greater than the largest allowable file descriptor.
+ */
+static size_t max_fds;
+
+#ifndef HAVE_GETDTABLESIZE
+/* getdtablesize --- replacement version that should be good enough */
+
+static inline int
+getdtablesize()
+{
+ /*
+ * Algorithm for the GNULIB folks:
+ *
+ * Set up a bitmap of 2048 elements.
+ * Initialize it to zero.
+ * In a loop, do
+ * fd = open("/dev/null", O_RDONLY)
+ * set the bit corresponding to fd in the bit map
+ * until it fails.
+ * Get the highest value that succeeded and increment it by one
+ * --> that is how many descriptors we have.
+ * Loop over the bitmap to close all the file descriptors we opened.
+ *
+ * Do all this upon the first call and return static values upon
+ * subsequent calls.
+ */
+
+ /* In the meantime, this is good enough for us: */
+ return 1024;
+}
+#endif
+
+/*
+ * IMPORTANT NOTE: This is a NOT a true general purpose
+ * extension. It is intended to demonstrate how to set up
+ * all the "plumbing" and to work one record at a time, ONLY.
+ *
+ * While it would be possible to set up buffering and manage it,
+ * that would duplicate a large chunk of the code in gawk's
+ * get_a_record() function, and there's no real point in doing that.
+ */
+
+/* the data in the opaque pointer */
+typedef struct two_way_proc_data {
+ size_t size; /* size of allocated buffer */
+ size_t len; /* how much is actually in use */
+ char *data;
+ size_t in_use; /* use count, must hit zero to be freed */
+} two_way_proc_data_t;
+
+/* close_two_proc_data --- release the data */
+
+static void
+close_two_proc_data(two_way_proc_data_t *proc_data)
+{
+ if (proc_data->in_use > 1) {
+ proc_data->in_use--;
+ return;
+ }
+
+ gawk_free(proc_data->data);
+ gawk_free(proc_data);
+}
+
+/*
+ * Input side of the two-way processor (input TO gawk)
+ */
+
+/* rev2way_get_record --- get one record at a time out of a directory */
+
+static int
+rev2way_get_record(char **out, awk_input_buf_t *iobuf, int *errcode,
+ char **rt_start, size_t *rt_len)
+{
+ int len = 0; /* for now */
+ two_way_proc_data_t *proc_data;
+
+ /*
+ * The caller sets *errcode to 0, so we should set it only if an
+ * error occurs.
+ */
+
+ (void) errcode; /* silence warnings */
+ if (out == NULL || iobuf == NULL || iobuf->opaque == NULL)
+ return EOF;
+
+ proc_data = (two_way_proc_data_t *) iobuf->opaque;
+ if (proc_data->len == 0)
+ return 0;
+
+ *out = proc_data->data;
+
+ len = proc_data->len;
+ proc_data->len = 0;
+
+ *rt_len = 0; /* default: set RT to "" */
+ if (proc_data->data[len-1] == '\n') {
+ while (proc_data->data[len-1] == '\n') {
+ len--;
+ (*rt_len)++;
+ }
+ *rt_start = proc_data->data + len;
+ }
+
+ return len;
+}
+
+/* rev2way_close --- close up input side when done */
+
+static void
+rev2way_close(awk_input_buf_t *iobuf)
+{
+ two_way_proc_data_t *proc_data;
+
+ if (iobuf == NULL || iobuf->opaque == NULL)
+ return;
+
+ proc_data = (two_way_proc_data_t *) iobuf->opaque;
+ close_two_proc_data(proc_data);
+
+ iobuf->fd = INVALID_HANDLE;
+}
+
+
+/*
+ * Output side of the two-way processor (output FROM gawk)
+ */
+
+/* rev2way_fwrite --- write out characters in reverse order */
+
+static size_t
+rev2way_fwrite(const void *buf, size_t size, size_t count, FILE *fp, void *opaque)
+{
+ two_way_proc_data_t *proc_data;
+ size_t amount, char_count;
+ char *src, *dest;
+
+ (void) fp; /* silence warnings */
+ if (opaque == NULL)
+ return 0; /* error */
+
+ proc_data = (two_way_proc_data_t *) opaque;
+ amount = size * count;
+
+ /* do the dance */
+ if (amount > proc_data->size || proc_data->len > 0) {
+ if (proc_data->data == NULL)
+ emalloc(proc_data->data, char *, amount, "rev2way_fwrite");
+ else
+ erealloc(proc_data->data, char *, proc_data->size + amount, "rev2way_fwrite");
+ proc_data->size += amount;
+ }
+
+ src = (char *) buf + amount -1;
+ dest = proc_data->data + proc_data->len;
+ for (char_count = amount; char_count > 0; char_count--) {
+ /* copy in backwards */
+ *dest++ = *src--;
+ }
+ proc_data->len += amount;
+
+ return amount;
+}
+
+/* rev2way_fflush --- do nothing hook for fflush */
+
+static int
+rev2way_fflush(FILE *fp, void *opaque)
+{
+ (void) fp;
+ (void) opaque;
+
+ return 0;
+}
+
+/* rev2way_ferror --- do nothing hook for ferror */
+
+static int
+rev2way_ferror(FILE *fp, void *opaque)
+{
+ (void) fp;
+ (void) opaque;
+
+ return 0;
+}
+
+/* rev2way_fclose --- close output side of two-way processor */
+
+static int
+rev2way_fclose(FILE *fp, void *opaque)
+{
+ two_way_proc_data_t *proc_data;
+
+ if (opaque == NULL)
+ return EOF; /* error */
+
+ (void) fp;
+
+ proc_data = (two_way_proc_data_t *) opaque;
+ close_two_proc_data(proc_data);
+
+ return 0;
+}
+
+
+/* revtwoway_can_two_way --- return true if we want the file */
+
+static awk_bool_t
+revtwoway_can_take_two_way(const char *name)
+{
+ return (name != NULL && strcmp(name, "/magic/mirror") == 0);
+}
+
+/*
+ * revtwoway_take_control_of --- set up two way processor
+ * We can assume that revtwoway_can_take_two_way just returned true,
+ * and no state has changed since then.
+ */
+
+static awk_bool_t
+revtwoway_take_control_of(const char *name, awk_input_buf_t *inbuf, awk_output_buf_t *outbuf)
+{
+ two_way_proc_data_t *proc_data;
+
+ (void) name; /* silence warnings */
+ if (inbuf == NULL || outbuf == NULL)
+ return awk_false;
+
+ emalloc(proc_data, two_way_proc_data_t *, sizeof(two_way_proc_data_t), "revtwoway_take_control_of");
+ proc_data->in_use = 2;
+ proc_data->size = 0;
+ proc_data->len = 0;
+ proc_data->data = NULL;
+
+ if (max_fds + 1 == 0) /* wrapped. ha! */
+ max_fds = getdtablesize();
+
+ /* input side: */
+ inbuf->get_record = rev2way_get_record;
+ inbuf->close_func = rev2way_close;
+ inbuf->fd = max_fds;
+ inbuf->opaque = proc_data;
+
+ /* output side: */
+ outbuf->fp = (FILE *) max_fds++;
+ outbuf->opaque = proc_data;
+ outbuf->gawk_fwrite = rev2way_fwrite;
+ outbuf->gawk_fflush = rev2way_fflush;
+ outbuf->gawk_ferror = rev2way_ferror;
+ outbuf->gawk_fclose = rev2way_fclose;
+ outbuf->redirected = awk_true;
+
+ return awk_true;
+}
+
+static awk_two_way_processor_t two_way_processor = {
+ "revtwoway",
+ revtwoway_can_take_two_way,
+ revtwoway_take_control_of,
+ NULL
+};
+
+/* init_revtwoway --- set things ups */
+
+static awk_bool_t
+init_revtwoway()
+{
+ register_two_way_processor(& two_way_processor);
+
+ max_fds = getdtablesize();
+
+ return awk_true;
+}
+
+static awk_ext_func_t func_table[] = {
+ { NULL, NULL, 0 }
+};
+
+/* define the dl_load function using the boilerplate macro */
+
+dl_load_func(func_table, revtwoway, "")
diff --git a/extension/rwarray.3am b/extension/rwarray.3am
new file mode 100644
index 00000000..359d91cd
--- /dev/null
+++ b/extension/rwarray.3am
@@ -0,0 +1,103 @@
+.TH RWARRAY 3am "Jan 15 2013" "Free Software Foundation" "GNU Awk Extension Modules"
+.SH NAME
+writea, reada \- write and read gawk arrays to/from files
+.SH SYNOPSIS
+.ft CW
+@load "rwarray"
+.sp
+ret = writea(file, array)
+.br
+ret = reada(file, array)
+.ft R
+.SH DESCRIPTION
+The
+.I rwarray
+extension adds two functions named
+.BR writea() .
+and
+.BR reada() ,
+as follows.
+.TP
+.B writea()
+This function takes a string argument, which is the name of the
+file to which dump the array, and the array itself as the second
+argument.
+.B writea()
+understands multidimensional arrays.
+It returns one on success, or zero upon failure.
+.TP
+.B reada()
+is the inverse of
+.BR writea() ;
+it reads the file named as its first argument, filling in
+the array named as the second argument. It clears the array
+first.
+Here too, the return value is one on success and zero upon failure.
+.SH NOTES
+The array created by
+.B reada()
+is identical to that written by
+.B writea()
+in the sense that the contents are the same. However, due
+to implementation issues, the array traversal order of the recreated
+array will likely be different from that of the original array.
+As array traversal order in AWK is by default undefined, this is
+not (technically) a problem. If you need to guarantee a particular
+traversal order, use the array sorting features in
+.I gawk
+to do so.
+.PP
+The file contains binary data. All integral values are written
+in network byte order.
+However, double precision floating-point values are written as
+native binary data. Thus, arrays containing only string data
+can theoretically be dumped on systems with one byte order and
+restored on systems with a different one, but this has not been tried.
+... .SH BUGS
+.SH EXAMPLE
+.ft CW
+.nf
+@load "rwarray"
+\&...
+ret = writea("arraydump.bin", array)
+\&...
+ret = reada("arraydump.bin", array)
+.fi
+.ft R
+.SH "SEE ALSO"
+.IR "GAWK: Effective AWK Programming" ,
+.IR filefuncs (3am),
+.IR fnmatch (3am),
+.IR fork (3am),
+.IR inplace (3am),
+.IR ordchr (3am),
+.IR readdir (3am),
+.IR readfile (3am),
+.IR revoutput (3am),
+.IR time (3am).
+.SH AUTHOR
+Arnold Robbins,
+.BR arnold@skeeve.com .
+.SH COPYING PERMISSIONS
+Copyright \(co 2012, 2013,
+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.
diff --git a/extension/rwarray.awk b/extension/rwarray.awk
deleted file mode 100644
index 1057b396..00000000
--- a/extension/rwarray.awk
+++ /dev/null
@@ -1,28 +0,0 @@
-BEGIN {
- extension("./rwarray.so","dlload")
-
- while ((getline word < "/usr/share/dict/words") > 0)
- dict[word] = word word
-
- for (i in dict)
- printf("dict[%s] = %s\n", i, dict[i]) > "orig.out"
- close("orig.out");
-
- writea("orig.bin", dict)
-
- reada("orig.bin", dict)
-
- for (i in dict)
- printf("dict[%s] = %s\n", i, dict[i]) > "new.out"
- close("new.out");
-
- ret = system("cmp orig.out new.out")
-
- if (ret == 0)
- print "old and new are equal - GOOD"
- else
- print "old and new are not equal - BAD"
-
- if (ret == 0 && !("keepit" in ENVIRON))
- system("rm orig.bin orig.out new.out")
-}
diff --git a/extension/rwarray.c b/extension/rwarray.c
index 8175c7c0..aa05a0d5 100644
--- a/extension/rwarray.c
+++ b/extension/rwarray.c
@@ -3,10 +3,11 @@
*
* Arnold Robbins
* May 2009
+ * Redone June 2012
*/
/*
- * Copyright (C) 2009, 2010, 2011 the Free Software Foundation, Inc.
+ * Copyright (C) 2009-2014 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -26,437 +27,465 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "awk.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __MINGW32__
+#include <winsock2.h>
+#else
#include <arpa/inet.h>
+#endif
#include <sys/types.h>
#include <sys/stat.h>
-#include <fcntl.h>
+#include "gawkapi.h"
+
+#include "gettext.h"
+#define _(msgid) gettext(msgid)
+#define N_(msgid) msgid
+
+#if defined(ZOS_USS)
+#include <limits.h>
+#define INT32_MAX INT_MAX
+#define INT32_MIN INT_MIN
+#ifndef __uint32_t
+#define __uint32_t 1
+typedef unsigned long uint32_t;
+#endif
+typedef long int32_t;
+#endif /* ZOS_USS */
#define MAGIC "awkrulz\n"
-#define MAJOR 1
+#define MAJOR 3
#define MINOR 0
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+static const char *ext_version = "rwarray extension: version 1.0";
+static awk_bool_t (*init_func)(void) = NULL;
+
int plugin_is_GPL_compatible;
-static int write_array(int fd, NODE *array);
-static int write_elem(int fd, int index, NODE *item);
-static int write_chain(int fd, int index, NODE *item);
-static int write_value(int fd, NODE *val);
+static awk_bool_t write_array(FILE *fp, awk_array_t array);
+static awk_bool_t write_elem(FILE *fp, awk_element_t *element);
+static awk_bool_t write_value(FILE *fp, awk_value_t *val);
-static int read_array(int fd, NODE *array);
-static NODE *read_elem(int fd, int *index, NODE *array);
-static NODE *read_value(int fd);
+static awk_bool_t read_array(FILE *fp, awk_array_t array);
+static awk_bool_t read_elem(FILE *fp, awk_element_t *element);
+static awk_bool_t read_value(FILE *fp, awk_value_t *value);
/*
* Format of array info:
*
- * MAGIC 8 bytes
+ * MAGIC 8 bytes
* Major version 4 bytes - network order
* Minor version 4 bytes - network order
* Element count 4 bytes - network order
- * Array size 4 bytes - network order
* Elements
*
* For each element:
- * Bucket number: 4 bytes - network order
- * Hash of index val: 4 bytes - network order
* Length of index val: 4 bytes - network order
* Index val as characters (N bytes)
- * Value type 1 byte (0 = string, 1 = number, 2 = array)
+ * Value type 4 bytes (0 = string, 1 = number, 2 = array)
* IF string:
* Length of value 4 bytes
* Value as characters (N bytes)
- * ELSE
+ * ELSE IF number:
* 8 bytes as native double
+ * ELSE
+ * Element count
+ * Elements
+ * END IF
*/
/* do_writea --- write an array */
-static NODE *
-do_writea(int nargs)
+static awk_value_t *
+do_writea(int nargs, awk_value_t *result)
{
- NODE *file, *array;
- int ret;
- int fd;
+ awk_value_t filename, array;
+ FILE *fp = NULL;
uint32_t major = MAJOR;
uint32_t minor = MINOR;
+ assert(result != NULL);
+ make_number(0.0, result);
+
if (do_lint && nargs > 2)
- lintwarn("writea: called with too many arguments");
+ lintwarn(ext_id, _("writea: called with too many arguments"));
+
+ if (nargs < 2)
+ goto out;
/* directory is first arg, array to dump is second */
- file = get_scalar_argument(0, FALSE);
- array = get_array_argument(1, FALSE);
+ if (! get_argument(0, AWK_STRING, & filename)) {
+ fprintf(stderr, _("do_writea: argument 0 is not a string\n"));
+ errno = EINVAL;
+ goto done1;
+ }
- /* open the file, if error, set ERRNO and return */
- (void) force_string(file);
- fd = creat(file->stptr, 0600);
- if (fd < 0) {
+ if (! get_argument(1, AWK_ARRAY, & array)) {
+ fprintf(stderr, _("do_writea: argument 1 is not an array\n"));
+ errno = EINVAL;
goto done1;
}
- if (write(fd, MAGIC, strlen(MAGIC)) != strlen(MAGIC))
+ /* open the file, if error, set ERRNO and return */
+ fp = fopen(filename.str_value.str, "wb");
+ if (fp == NULL)
+ goto done1;
+
+ if (fwrite(MAGIC, 1, strlen(MAGIC), fp) != strlen(MAGIC))
goto done1;
major = htonl(major);
- if (write(fd, & major, sizeof(major)) != sizeof(major))
+ if (fwrite(& major, 1, sizeof(major), fp) != sizeof(major))
goto done1;
minor = htonl(minor);
- if (write(fd, & minor, sizeof(minor)) != sizeof(minor))
+ if (fwrite(& minor, 1, sizeof(minor), fp) != sizeof(minor))
goto done1;
- ret = write_array(fd, array);
- if (ret != 0)
- goto done1;
- ret = 0;
- goto done0;
+ if (write_array(fp, array.array_cookie)) {
+ make_number(1.0, result);
+ goto done0;
+ }
done1:
- ret = -1;
- update_ERRNO();
- unlink(file->stptr);
+ update_ERRNO_int(errno);
+ unlink(filename.str_value.str);
done0:
- close(fd);
-
- /* Set the return value */
- return make_number((AWKNUM) ret);
+ fclose(fp);
+out:
+ return result;
}
/* write_array --- write out an array or a sub-array */
-static int
-write_array(int fd, NODE *array)
+static awk_bool_t
+write_array(FILE *fp, awk_array_t array)
{
- int ret;
+ uint32_t i;
uint32_t count;
- uint32_t array_sz;
- int i;
-
- count = htonl(array->table_size);
- if (write(fd, & count, sizeof(count)) != sizeof(count))
- return -1;
+ awk_flat_array_t *flat_array;
- array_sz = htonl(array->array_size);
- if (write(fd, & array_sz, sizeof(array_sz)) != sizeof(array_sz))
- return -1;
-
- for (i = 0; i < array->array_size; i++) {
- ret = write_chain(fd, i, array->var_array[i]);
- if (ret != 0)
- return ret;
+ if (! flatten_array(array, & flat_array)) {
+ fprintf(stderr, _("write_array: could not flatten array\n"));
+ return awk_false;
}
- return 0;
-}
-
-
-/* write_chain --- write out a whole hash chain */
-
-/*
- * Write elements in the chain in reverse order so that
- * when we read the elements back in we can just push them
- * onto the front and thus recreate the array as it was.
- */
-static int
-write_chain(int fd, int index, NODE *bucket)
-{
- int ret;
+ count = htonl(flat_array->count);
+ if (fwrite(& count, 1, sizeof(count), fp) != sizeof(count))
+ return awk_false;
- if (bucket == NULL)
- return 0;
+ for (i = 0; i < flat_array->count; i++) {
+ if (! write_elem(fp, & flat_array->elements[i]))
+ return awk_false;
+ }
- ret = write_chain(fd, index, bucket->ahnext);
- if (ret != 0)
- return ret;
+ if (! release_flattened_array(array, flat_array)) {
+ fprintf(stderr, _("write_array: could not release flattened array\n"));
+ return awk_false;
+ }
- return write_elem(fd, index, bucket);
+ return awk_true;
}
/* write_elem --- write out a single element */
-static int
-write_elem(int fd, int index, NODE *item)
+static awk_bool_t
+write_elem(FILE *fp, awk_element_t *element)
{
- uint32_t hashval, indexval_len;
-
- index = htonl(index);
- if (write(fd, & index, sizeof(index)) != sizeof(index))
- return -1;
-
- hashval = htonl(item->ahcode);
- if (write(fd, & hashval, sizeof(hashval)) != sizeof(hashval))
- return -1;
-
- indexval_len = htonl(item->ahname_len);
- if (write(fd, & indexval_len, sizeof(indexval_len)) != sizeof(indexval_len))
- return -1;
-
- if (write(fd, item->ahname_str, item->ahname_len) != item->ahname_len)
- return -1;
+ uint32_t indexval_len;
+ ssize_t write_count;
+
+ indexval_len = htonl(element->index.str_value.len);
+ if (fwrite(& indexval_len, 1, sizeof(indexval_len), fp) != sizeof(indexval_len))
+ return awk_false;
+
+ if (element->index.str_value.len > 0) {
+ write_count = fwrite(element->index.str_value.str,
+ 1, element->index.str_value.len, fp);
+ if (write_count != (ssize_t) element->index.str_value.len)
+ return awk_false;
+ }
- return write_value(fd, item->ahvalue);
+ return write_value(fp, & element->value);
}
/* write_value --- write a number or a string or a array */
-static int
-write_value(int fd, NODE *val)
+static awk_bool_t
+write_value(FILE *fp, awk_value_t *val)
{
- int code, len;
+ uint32_t code, len;
- if (val->type == Node_var_array) {
+ if (val->val_type == AWK_ARRAY) {
code = htonl(2);
- if (write(fd, & code, sizeof(code)) != sizeof(code))
- return -1;
- return write_array(fd, val);
+ if (fwrite(& code, 1, sizeof(code), fp) != sizeof(code))
+ return awk_false;
+ return write_array(fp, val->array_cookie);
}
- if ((val->flags & NUMBER) != 0) {
+ if (val->val_type == AWK_NUMBER) {
code = htonl(1);
- if (write(fd, & code, sizeof(code)) != sizeof(code))
- return -1;
+ if (fwrite(& code, 1, sizeof(code), fp) != sizeof(code))
+ return awk_false;
- if (write(fd, & val->numbr, sizeof(val->numbr)) != sizeof(val->numbr))
- return -1;
+ if (fwrite(& val->num_value, 1, sizeof(val->num_value), fp) != sizeof(val->num_value))
+ return awk_false;
} else {
code = 0;
- if (write(fd, & code, sizeof(code)) != sizeof(code))
- return -1;
+ if (fwrite(& code, 1, sizeof(code), fp) != sizeof(code))
+ return awk_false;
- len = htonl(val->stlen);
- if (write(fd, & len, sizeof(len)) != sizeof(len))
- return -1;
+ len = htonl(val->str_value.len);
+ if (fwrite(& len, 1, sizeof(len), fp) != sizeof(len))
+ return awk_false;
- if (write(fd, val->stptr, val->stlen) != val->stlen)
- return -1;
+ if (fwrite(val->str_value.str, 1, val->str_value.len, fp)
+ != (ssize_t) val->str_value.len)
+ return awk_false;
}
- return 0;
+ return awk_true;
}
/* do_reada --- read an array */
-static NODE *
-do_reada(int nargs)
+static awk_value_t *
+do_reada(int nargs, awk_value_t *result)
{
- NODE *file, *array;
- int ret;
- int fd;
+ awk_value_t filename, array;
+ FILE *fp = NULL;
uint32_t major;
uint32_t minor;
char magic_buf[30];
+ assert(result != NULL);
+ make_number(0.0, result);
+
if (do_lint && nargs > 2)
- lintwarn("reada: called with too many arguments");
+ lintwarn(ext_id, _("reada: called with too many arguments"));
- /* directory is first arg, array to dump is second */
- file = get_scalar_argument(0, FALSE);
- array = get_array_argument(1, FALSE);
+ if (nargs < 2)
+ goto out;
+
+ /* directory is first arg, array to read is second */
+ if (! get_argument(0, AWK_STRING, & filename)) {
+ fprintf(stderr, _("do_reada: argument 0 is not a string\n"));
+ errno = EINVAL;
+ goto done1;
+ }
- (void) force_string(file);
- fd = open(file->stptr, O_RDONLY);
- if (fd < 0) {
+ if (! get_argument(1, AWK_ARRAY, & array)) {
+ fprintf(stderr, _("do_reada: argument 1 is not an array\n"));
+ errno = EINVAL;
goto done1;
}
+ fp = fopen(filename.str_value.str, "rb");
+ if (fp == NULL)
+ goto done1;
+
memset(magic_buf, '\0', sizeof(magic_buf));
- if (read(fd, magic_buf, strlen(MAGIC)) != strlen(MAGIC)) {
+ if (fread(magic_buf, 1, strlen(MAGIC), fp) != strlen(MAGIC)) {
+ errno = EBADF;
goto done1;
}
if (strcmp(magic_buf, MAGIC) != 0) {
+ errno = EBADF;
goto done1;
}
- if (read(fd, & major, sizeof(major)) != sizeof(major)) {
+ if (fread(& major, 1, sizeof(major), fp) != sizeof(major)) {
+ errno = EBADF;
goto done1;
}
major = ntohl(major);
if (major != MAJOR) {
+ errno = EBADF;
goto done1;
}
- if (read(fd, & minor, sizeof(minor)) != sizeof(minor)) {
+ if (fread(& minor, 1, sizeof(minor), fp) != sizeof(minor)) {
+ /* read() sets errno */
goto done1;
}
+
minor = ntohl(minor);
if (minor != MINOR) {
+ errno = EBADF;
goto done1;
}
- assoc_clear(array, NULL);
+ if (! clear_array(array.array_cookie)) {
+ errno = ENOMEM;
+ fprintf(stderr, _("do_reada: clear_array failed\n"));
+ goto done1;
+ }
- ret = read_array(fd, array);
- if (ret == 0)
+ if (read_array(fp, array.array_cookie)) {
+ make_number(1.0, result);
goto done0;
+ }
done1:
- ret = -1;
- update_ERRNO();
-
+ update_ERRNO_int(errno);
done0:
- close(fd);
-
- /* Set the return value */
- return make_number((AWKNUM) ret);
+ if (fp != NULL)
+ fclose(fp);
+out:
+ return result;
}
/* read_array --- read in an array or sub-array */
-static int
-read_array(int fd, NODE *array)
+static awk_bool_t
+read_array(FILE *fp, awk_array_t array)
{
- int i;
+ uint32_t i;
uint32_t count;
- uint32_t array_sz;
- int index;
- NODE *new_elem;
+ awk_element_t new_elem;
- if (read(fd, & count, sizeof(count)) != sizeof(count)) {
- return -1;
- }
- array->table_size = ntohl(count);
+ if (fread(& count, 1, sizeof(count), fp) != sizeof(count))
+ return awk_false;
- if (read(fd, & array_sz, sizeof(array_sz)) != sizeof(array_sz)) {
- return -1;
- }
- array->array_size = ntohl(array_sz);
+ count = ntohl(count);
- /* malloc var_array */
- array->var_array = (NODE **) malloc(array->array_size * sizeof(NODE *));
- memset(array->var_array, '\0', array->array_size * sizeof(NODE *));
-
- for (i = 0; i < array->table_size; i++) {
- if ((new_elem = read_elem(fd, & index, array)) != NULL) {
- new_elem->ahnext = array->var_array[index];
- array->var_array[index] = new_elem;
+ for (i = 0; i < count; i++) {
+ if (read_elem(fp, & new_elem)) {
+ /* add to array */
+ if (! set_array_element_by_elem(array, & new_elem)) {
+ fprintf(stderr, _("read_array: set_array_element failed\n"));
+ return awk_false;
+ }
} else
break;
}
- if (i != array->table_size)
- return -1;
- return 0;
-}
+ if (i != count)
+ return awk_false;
+
+ return awk_true;
+}
/* read_elem --- read in a single element */
-static NODE *
-read_elem(int fd, int *the_index, NODE *array)
+static awk_bool_t
+read_elem(FILE *fp, awk_element_t *element)
{
- uint32_t hashval, indexval_len, index;
- NODE *item;
- NODE *val;
- int ret;
+ uint32_t index_len;
+ static char *buffer;
+ static uint32_t buflen;
+ ssize_t ret;
- *the_index = 0;
-
- if ((ret = read(fd, & index, sizeof(index))) != sizeof(index)) {
- return NULL;
+ if ((ret = fread(& index_len, 1, sizeof(index_len), fp)) != sizeof(index_len)) {
+ return awk_false;
}
- *the_index = index = ntohl(index);
+ index_len = ntohl(index_len);
- getnode(item);
- memset(item, 0, sizeof(*item));
- item->type = Node_ahash;
- item->flags = MALLOC;
+ memset(element, 0, sizeof(*element));
- if (read(fd, & hashval, sizeof(hashval)) != sizeof(hashval)) {
- return NULL;
- }
+ if (index_len > 0) {
+ if (buffer == NULL) {
+ /* allocate buffer */
+ emalloc(buffer, char *, index_len, "read_elem");
+ buflen = index_len;
+ } else if (buflen < index_len) {
+ /* reallocate buffer */
+ char *cp = gawk_realloc(buffer, index_len);
- item->ahcode = ntohl(hashval);
+ if (cp == NULL)
+ return awk_false;
- if (read(fd, & indexval_len, sizeof(indexval_len)) != sizeof(indexval_len)) {
- return NULL;
- }
- item->ahname_len = ntohl(indexval_len);
+ buffer = cp;
+ buflen = index_len;
+ }
- item->ahname_str = malloc(item->ahname_len + 2);
- if (read(fd, item->ahname_str, item->ahname_len) != item->ahname_len) {
- return NULL;
+ if (fread(buffer, 1, index_len, fp) != (ssize_t) index_len) {
+ return awk_false;
+ }
+ make_const_string(buffer, index_len, & element->index);
+ } else {
+ make_null_string(& element->index);
}
- item->ahname_str[item->ahname_len] = '\0';
- item->ahname_ref = 1;
- item->ahvalue = val = read_value(fd);
- if (val == NULL) {
- return NULL;
- }
- if (val->type == Node_var_array) {
- char *aname;
- size_t aname_len;
-
- /* construct the sub-array name */
- aname_len = strlen(array->vname) + item->ahname_len + 4;
- emalloc(aname, char *, aname_len + 2, "read_elem");
- sprintf(aname, "%s[\"%.*s\"]", array->vname, (int) item->ahname_len, item->ahname_str);
- val->vname = aname;
- }
+ if (! read_value(fp, & element->value))
+ return awk_false;
- return item;
+ return awk_true;
}
/* read_value --- read a number or a string */
-static NODE *
-read_value(int fd)
+static awk_bool_t
+read_value(FILE *fp, awk_value_t *value)
{
- NODE *val;
- int code, len;
+ uint32_t code, len;
- getnode(val);
- memset(val, 0, sizeof(*val));
- val->type = Node_val;
+ if (fread(& code, 1, sizeof(code), fp) != sizeof(code))
+ return awk_false;
- if (read(fd, & code, sizeof(code)) != sizeof(code)) {
- return NULL;
- }
code = ntohl(code);
if (code == 2) {
- val->type = Node_var_array;
- if (read_array(fd, val) != 0)
- return NULL;
+ awk_array_t array = create_array();
+
+ if (! read_array(fp, array))
+ return awk_false;
+
+ /* hook into value */
+ value->val_type = AWK_ARRAY;
+ value->array_cookie = array;
} else if (code == 1) {
- if (read(fd, & val->numbr, sizeof(val->numbr)) != sizeof(val->numbr)) {
- return NULL;
- }
+ double d;
- val->flags = NUMBER|NUMCUR|MALLOC;
+ if (fread(& d, 1, sizeof(d), fp) != sizeof(d))
+ return awk_false;
+
+ /* hook into value */
+ value->val_type = AWK_NUMBER;
+ value->num_value = d;
} else {
- if (read(fd, & len, sizeof(len)) != sizeof(len)) {
- return NULL;
+ if (fread(& len, 1, sizeof(len), fp) != sizeof(len)) {
+ return awk_false;
}
- val->stlen = ntohl(len);
- val->stptr = malloc(val->stlen + 2);
- memset(val->stptr, '\0', val->stlen + 2);
-
- if (read(fd, val->stptr, val->stlen) != val->stlen) {
- return NULL;
+ len = ntohl(len);
+ value->val_type = AWK_STRING;
+ value->str_value.len = len;
+ value->str_value.str = gawk_malloc(len + 2);
+ memset(value->str_value.str, '\0', len + 2);
+
+ if (fread(value->str_value.str, 1, len, fp) != (ssize_t) len) {
+ gawk_free(value->str_value.str);
+ return awk_false;
}
-
- val->flags = STRING|STRCUR|MALLOC;
}
- return val;
+ return awk_true;
}
-/* dlload --- load new builtins in this library */
+static awk_ext_func_t func_table[] = {
+ { "writea", do_writea, 2 },
+ { "reada", do_reada, 2 },
+};
-NODE *
-dlload(tree, dl)
-NODE *tree;
-void *dl;
-{
- make_builtin("writea", do_writea, 2);
- make_builtin("reada", do_reada, 2);
- return make_number((AWKNUM) 0);
-}
+/* define the dl_load function using the boilerplate macro */
+
+dl_load_func(func_table, rwarray, "")
diff --git a/extension/rwarray0.c b/extension/rwarray0.c
new file mode 100644
index 00000000..e2de3cf5
--- /dev/null
+++ b/extension/rwarray0.c
@@ -0,0 +1,475 @@
+/*
+ * rwarray.c - Builtin functions to binary read / write arrays to a file.
+ *
+ * Arnold Robbins
+ * May 2009
+ * Redone June 2012
+ */
+
+/*
+ * Copyright (C) 2009, 2010, 2011, 2012, 2013 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 3 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 HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "gawkapi.h"
+
+#include "gettext.h"
+#define _(msgid) gettext(msgid)
+#define N_(msgid) msgid
+
+#define MAGIC "awkrulz\n"
+#define MAJOR 3
+#define MINOR 0
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+static const char *ext_version = "rwarray0 extension: version 1.0";
+static awk_bool_t (*init_func)(void) = NULL;
+
+int plugin_is_GPL_compatible;
+
+static awk_bool_t write_array(int fd, awk_array_t array);
+static awk_bool_t write_elem(int fd, awk_element_t *element);
+static awk_bool_t write_value(int fd, awk_value_t *val);
+
+static awk_bool_t read_array(int fd, awk_array_t array);
+static awk_bool_t read_elem(int fd, awk_element_t *element);
+static awk_bool_t read_value(int fd, awk_value_t *value);
+
+/*
+ * Format of array info:
+ *
+ * MAGIC 8 bytes
+ * Major version 4 bytes - network order
+ * Minor version 4 bytes - network order
+ * Element count 4 bytes - network order
+ * Elements
+ *
+ * For each element:
+ * Length of index val: 4 bytes - network order
+ * Index val as characters (N bytes)
+ * Value type 4 bytes (0 = string, 1 = number, 2 = array)
+ * IF string:
+ * Length of value 4 bytes
+ * Value as characters (N bytes)
+ * ELSE IF number:
+ * 8 bytes as native double
+ * ELSE
+ * Element count
+ * Elements
+ * END IF
+ */
+
+/* do_writea --- write an array */
+
+static awk_value_t *
+do_writea(int nargs, awk_value_t *result)
+{
+ awk_value_t filename, array;
+ int fd = -1;
+ uint32_t major = MAJOR;
+ uint32_t minor = MINOR;
+
+ assert(result != NULL);
+ make_number(0.0, result);
+
+ if (do_lint && nargs > 2)
+ lintwarn(ext_id, _("writea: called with too many arguments"));
+
+ if (nargs < 2)
+ goto out;
+
+ /* directory is first arg, array to dump is second */
+ if (! get_argument(0, AWK_STRING, & filename)) {
+ fprintf(stderr, _("do_writea: argument 0 is not a string\n"));
+ errno = EINVAL;
+ goto done1;
+ }
+
+ if (! get_argument(1, AWK_ARRAY, & array)) {
+ fprintf(stderr, _("do_writea: argument 1 is not an array\n"));
+ errno = EINVAL;
+ goto done1;
+ }
+
+ /* open the file, if error, set ERRNO and return */
+ fd = creat(filename.str_value.str, 0600);
+ if (fd < 0)
+ goto done1;
+
+ if (write(fd, MAGIC, strlen(MAGIC)) != strlen(MAGIC))
+ goto done1;
+
+ major = htonl(major);
+ if (write(fd, & major, sizeof(major)) != sizeof(major))
+ goto done1;
+
+ minor = htonl(minor);
+ if (write(fd, & minor, sizeof(minor)) != sizeof(minor))
+ goto done1;
+
+ if (write_array(fd, array.array_cookie)) {
+ make_number(1.0, result);
+ goto done0;
+ }
+
+done1:
+ update_ERRNO_int(errno);
+ unlink(filename.str_value.str);
+
+done0:
+ close(fd);
+out:
+ return result;
+}
+
+
+/* write_array --- write out an array or a sub-array */
+
+static awk_bool_t
+write_array(int fd, awk_array_t array)
+{
+ uint32_t i;
+ uint32_t count;
+ awk_flat_array_t *flat_array;
+
+ if (! flatten_array(array, & flat_array)) {
+ fprintf(stderr, _("write_array: could not flatten array\n"));
+ return awk_false;
+ }
+
+ count = htonl(flat_array->count);
+ if (write(fd, & count, sizeof(count)) != sizeof(count))
+ return awk_false;
+
+ for (i = 0; i < flat_array->count; i++) {
+ if (! write_elem(fd, & flat_array->elements[i]))
+ return awk_false;
+ }
+
+ if (! release_flattened_array(array, flat_array)) {
+ fprintf(stderr, _("write_array: could not release flattened array\n"));
+ return awk_false;
+ }
+
+ return awk_true;
+}
+
+/* write_elem --- write out a single element */
+
+static awk_bool_t
+write_elem(int fd, awk_element_t *element)
+{
+ uint32_t indexval_len;
+ ssize_t write_count;
+
+ indexval_len = htonl(element->index.str_value.len);
+ if (write(fd, & indexval_len, sizeof(indexval_len)) != sizeof(indexval_len))
+ return awk_false;
+
+ if (element->index.str_value.len > 0) {
+ write_count = write(fd, element->index.str_value.str,
+ element->index.str_value.len);
+ if (write_count != (ssize_t) element->index.str_value.len)
+ return awk_false;
+ }
+
+ return write_value(fd, & element->value);
+}
+
+/* write_value --- write a number or a string or a array */
+
+static awk_bool_t
+write_value(int fd, awk_value_t *val)
+{
+ uint32_t code, len;
+
+ if (val->val_type == AWK_ARRAY) {
+ code = htonl(2);
+ if (write(fd, & code, sizeof(code)) != sizeof(code))
+ return awk_false;
+ return write_array(fd, val->array_cookie);
+ }
+
+ if (val->val_type == AWK_NUMBER) {
+ code = htonl(1);
+ if (write(fd, & code, sizeof(code)) != sizeof(code))
+ return awk_false;
+
+ if (write(fd, & val->num_value, sizeof(val->num_value)) != sizeof(val->num_value))
+ return awk_false;
+ } else {
+ code = 0;
+ if (write(fd, & code, sizeof(code)) != sizeof(code))
+ return awk_false;
+
+ len = htonl(val->str_value.len);
+ if (write(fd, & len, sizeof(len)) != sizeof(len))
+ return awk_false;
+
+ if (write(fd, val->str_value.str, val->str_value.len)
+ != (ssize_t) val->str_value.len)
+ return awk_false;
+ }
+
+ return awk_true;
+}
+
+/* do_reada --- read an array */
+
+static awk_value_t *
+do_reada(int nargs, awk_value_t *result)
+{
+ awk_value_t filename, array;
+ int fd = -1;
+ uint32_t major;
+ uint32_t minor;
+ char magic_buf[30];
+
+ assert(result != NULL);
+ make_number(0.0, result);
+
+ if (do_lint && nargs > 2)
+ lintwarn(ext_id, _("reada: called with too many arguments"));
+
+ if (nargs < 2)
+ goto out;
+
+ /* directory is first arg, array to read is second */
+ if (! get_argument(0, AWK_STRING, & filename)) {
+ fprintf(stderr, _("do_reada: argument 0 is not a string\n"));
+ errno = EINVAL;
+ goto done1;
+ }
+
+ if (! get_argument(1, AWK_ARRAY, & array)) {
+ fprintf(stderr, _("do_reada: argument 1 is not an array\n"));
+ errno = EINVAL;
+ goto done1;
+ }
+
+ fd = open(filename.str_value.str, O_RDONLY);
+ if (fd < 0)
+ goto done1;
+
+ memset(magic_buf, '\0', sizeof(magic_buf));
+ if (read(fd, magic_buf, strlen(MAGIC)) != strlen(MAGIC)) {
+ errno = EBADF;
+ goto done1;
+ }
+
+ if (strcmp(magic_buf, MAGIC) != 0) {
+ errno = EBADF;
+ goto done1;
+ }
+
+ if (read(fd, & major, sizeof(major)) != sizeof(major)) {
+ errno = EBADF;
+ goto done1;
+ }
+ major = ntohl(major);
+
+ if (major != MAJOR) {
+ errno = EBADF;
+ goto done1;
+ }
+
+ if (read(fd, & minor, sizeof(minor)) != sizeof(minor)) {
+ /* read() sets errno */
+ goto done1;
+ }
+
+ minor = ntohl(minor);
+ if (minor != MINOR) {
+ errno = EBADF;
+ goto done1;
+ }
+
+ if (! clear_array(array.array_cookie)) {
+ errno = ENOMEM;
+ fprintf(stderr, _("do_reada: clear_array failed\n"));
+ goto done1;
+ }
+
+ if (read_array(fd, array.array_cookie)) {
+ make_number(1.0, result);
+ goto done0;
+ }
+
+done1:
+ update_ERRNO_int(errno);
+done0:
+ close(fd);
+out:
+ return result;
+}
+
+
+/* read_array --- read in an array or sub-array */
+
+static awk_bool_t
+read_array(int fd, awk_array_t array)
+{
+ uint32_t i;
+ uint32_t count;
+ awk_element_t new_elem;
+
+ if (read(fd, & count, sizeof(count)) != sizeof(count)) {
+ return awk_false;
+ }
+ count = ntohl(count);
+
+ for (i = 0; i < count; i++) {
+ if (read_elem(fd, & new_elem)) {
+ /* add to array */
+ if (! set_array_element_by_elem(array, & new_elem)) {
+ fprintf(stderr, _("read_array: set_array_element failed\n"));
+ return awk_false;
+ }
+ } else
+ break;
+ }
+
+ if (i != count)
+ return awk_false;
+
+ return awk_true;
+}
+
+/* read_elem --- read in a single element */
+
+static awk_bool_t
+read_elem(int fd, awk_element_t *element)
+{
+ uint32_t index_len;
+ static char *buffer;
+ static uint32_t buflen;
+ ssize_t ret;
+
+ if ((ret = read(fd, & index_len, sizeof(index_len))) != sizeof(index_len)) {
+ return awk_false;
+ }
+ index_len = ntohl(index_len);
+
+ memset(element, 0, sizeof(*element));
+
+ if (index_len > 0) {
+ if (buffer == NULL) {
+ // allocate buffer
+ emalloc(buffer, char *, index_len, "read_elem");
+ buflen = index_len;
+ } else if (buflen < index_len) {
+ // reallocate buffer
+ char *cp = realloc(buffer, index_len);
+
+ if (cp == NULL)
+ return awk_false;
+
+ buffer = cp;
+ buflen = index_len;
+ }
+
+ if (read(fd, buffer, index_len) != (ssize_t) index_len) {
+ return awk_false;
+ }
+ make_const_string(buffer, index_len, & element->index);
+ } else {
+ make_null_string(& element->index);
+ }
+
+ if (! read_value(fd, & element->value))
+ return awk_false;
+
+ return awk_true;
+}
+
+/* read_value --- read a number or a string */
+
+static awk_bool_t
+read_value(int fd, awk_value_t *value)
+{
+ uint32_t code, len;
+
+ if (read(fd, & code, sizeof(code)) != sizeof(code))
+ return awk_false;
+
+ code = ntohl(code);
+
+ if (code == 2) {
+ awk_array_t array = create_array();
+
+ if (read_array(fd, array) != 0)
+ return awk_false;
+
+ /* hook into value */
+ value->val_type = AWK_ARRAY;
+ value->array_cookie = array;
+ } else if (code == 1) {
+ double d;
+
+ if (read(fd, & d, sizeof(d)) != sizeof(d))
+ return awk_false;
+
+ /* hook into value */
+ value->val_type = AWK_NUMBER;
+ value->num_value = d;
+ } else {
+ if (read(fd, & len, sizeof(len)) != sizeof(len)) {
+ return awk_false;
+ }
+ len = ntohl(len);
+ value->val_type = AWK_STRING;
+ value->str_value.len = len;
+ value->str_value.str = malloc(len + 2);
+ memset(value->str_value.str, '\0', len + 2);
+
+ if (read(fd, value->str_value.str, len) != (ssize_t) len) {
+ free(value->str_value.str);
+ return awk_false;
+ }
+ }
+
+ return awk_true;
+}
+
+static awk_ext_func_t func_table[] = {
+ { "writea", do_writea, 2 },
+ { "reada", do_reada, 2 },
+};
+
+
+/* define the dl_load function using the boilerplate macro */
+
+dl_load_func(func_table, rwarray, "")
diff --git a/extension/stack.c b/extension/stack.c
new file mode 100644
index 00000000..6150442c
--- /dev/null
+++ b/extension/stack.c
@@ -0,0 +1,90 @@
+/*
+ * stack.c -- Implementation for stack functions for use by extensions.
+ */
+
+/*
+ * Copyright (C) 2012, 2013 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 3 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 <stdlib.h>
+
+#include "stack.h"
+
+#define INITIAL_STACK 20
+
+static size_t size;
+static void **stack;
+static int index = -1;
+
+/* stack_empty --- return true if stack is empty */
+
+int
+stack_empty()
+{
+ return index < 0;
+}
+
+/* stack_top --- return top object on the stack */
+
+void *
+stack_top()
+{
+ if (stack_empty() || stack == NULL)
+ return NULL;
+
+ return stack[index];
+}
+
+/* stack_pop --- pop top object and return it */
+
+void *
+stack_pop()
+{
+ if (stack_empty() || stack == NULL)
+ return NULL;
+
+ return stack[index--];
+}
+
+/* stack_push --- push an object onto the stack */
+
+int stack_push(void *object)
+{
+ void **new_stack;
+ size_t new_size = 2 * size;
+
+ if (stack == NULL) {
+ stack = (void **) malloc(INITIAL_STACK * sizeof(void *));
+ if (stack == NULL)
+ return 0;
+ size = INITIAL_STACK;
+ } else if (index + 1 >= size) {
+ if (new_size < size)
+ return 0;
+ new_stack = realloc(stack, new_size * sizeof(void *));
+ if (new_stack == NULL)
+ return 0;
+ size = new_size;
+ stack = new_stack;
+ }
+
+ stack[++index] = object;
+ return 1;
+}
diff --git a/extension/stack.h b/extension/stack.h
new file mode 100644
index 00000000..9643fb34
--- /dev/null
+++ b/extension/stack.h
@@ -0,0 +1,31 @@
+/*
+ * stack.h -- Definitions for stack functions for use by extensions.
+ */
+
+/*
+ * Copyright (C) 2012, 2013 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 3 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
+ */
+
+extern int stack_empty(); /* return true if stack is empty */
+extern void *stack_top(); /* return top object on the stack */
+extern void *stack_pop(); /* pop top object and return it */
+extern int stack_push(void *); /* push an object onto the stack,
+ * return 0 if failed, 1 if success
+ */
diff --git a/extension/steps b/extension/steps
deleted file mode 100755
index a6696ddc..00000000
--- a/extension/steps
+++ /dev/null
@@ -1,23 +0,0 @@
-# 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
-# Fri May 15 15:48:45 IDT 2009
-
-gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. dl.c
-gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. filefuncs.c
-gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. fork.c
-gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. ordchr.c
-gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. arrayparm.c
-gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. readfile.c
-gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. testarg.c
-gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. rwarray.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
-ld -o rwarray.so -shared rwarray.o
diff --git a/extension/testarg.awk b/extension/testarg.awk
deleted file mode 100644
index a91df1a9..00000000
--- a/extension/testarg.awk
+++ /dev/null
@@ -1,7 +0,0 @@
-BEGIN {
- extension("./testarg.so", "dlload")
- check_arg(x, a);
- check_arg(y, b, z);
- check_arg(u, v, u=1);
- check_arg(p, q, r, s);
-}
diff --git a/extension/testarg.c b/extension/testarg.c
deleted file mode 100644
index 4d012db5..00000000
--- a/extension/testarg.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "awk.h"
-
-int plugin_is_GPL_compatible;
-
-static NODE *
-do_check_arg(int nargs)
-{
- int ret = 0;
- NODE *arg1, *arg2, *arg3;
-
- printf("arg count: defined = 3, supplied = %d\n", nargs);
-
- arg1 = get_scalar_argument(0, FALSE);
- arg2 = get_array_argument(1, FALSE);
- arg3 = get_scalar_argument(2, TRUE); /* optional */
- if (nargs > 3) {
- /* try to use an extra arg */
- NODE *arg4;
- arg4 = get_array_argument(3, TRUE);
- printf("Shouldn't see this line\n");
- }
- if (arg3 != NULL) {
- printf("3rd arg present\n");
- if (arg3->type != Node_val)
- printf("3nd arg type = %s (*** NOT OK ***)\n", nodetype2str(arg3->type));
- } else
- printf("no 3rd arg\n");
-
- if (arg2 != NULL) {
- if (arg2->type != Node_var_array)
- printf("2nd arg type = %s (*** NOT OK ***)\n", nodetype2str(arg2->type));
- } else
- printf("2nd arg missing (NULL) (*** NOT OK ***)\n");
-
- if (arg1 != NULL) {
- if (arg1->type != Node_val)
- printf("1st arg type = %s (*** NOT OK ***)\n", nodetype2str(arg1->type));
- } else
- printf("1st arg missing (NULL) (*** NOT OK ***)\n");
- printf("\n");
-
- /* Set the return value */
- return make_number((AWKNUM) ret);
-}
-
-/* dlload --- load new builtins in this library */
-
-NODE *
-dlload(tree, dl)
-NODE *tree;
-void *dl;
-{
- make_builtin("check_arg", do_check_arg, 3);
- return make_number((AWKNUM) 0);
-}
diff --git a/extension/testarrayparm.awk b/extension/testarrayparm.awk
deleted file mode 100644
index 08178f3e..00000000
--- a/extension/testarrayparm.awk
+++ /dev/null
@@ -1,10 +0,0 @@
-#! /bin/awk -f
-
-BEGIN {
- extension("./arrayparm.so", "dlload")
-
- mkarray(newvar, "hi", "hello")
-
- for (i in newvar)
- printf ("newvar[\"%s\"] = \"%s\"\n", i, newvar[i])
-}
diff --git a/extension/testext.c b/extension/testext.c
new file mode 100644
index 00000000..4a1e7032
--- /dev/null
+++ b/extension/testext.c
@@ -0,0 +1,884 @@
+/*
+ * testext.c - tests for the extension API.
+ */
+
+/*
+ * Copyright (C) 2012, 2013, 2014, 2015
+ * 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 3 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 HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "gawkapi.h"
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+static const char *ext_version = "testext extension: version 1.0";
+
+int plugin_is_GPL_compatible;
+
+static void fill_in_array(awk_value_t *value);
+
+/* valrep2str --- turn a value into a string */
+
+static const char *
+valrep2str(const awk_value_t *value)
+{
+ static char buf[BUFSIZ];
+ int size = BUFSIZ - 3;
+
+ switch (value->val_type) {
+ case AWK_UNDEFINED:
+ strcpy(buf, "<undefined>");
+ break;
+ case AWK_ARRAY:
+ strcpy(buf, "<array>");
+ break;
+ case AWK_SCALAR:
+ strcpy(buf, "<scalar>");
+ break;
+ case AWK_VALUE_COOKIE:
+ strcpy(buf, "<value-cookie>");
+ break;
+ case AWK_STRING:
+ if (value->str_value.len < size)
+ size = value->str_value.len;
+ sprintf(buf, "\"%.*s\"",
+ size,
+ value->str_value.str);
+ break;
+ case AWK_NUMBER:
+ sprintf(buf, "%g", value->num_value);
+ break;
+ }
+ return buf;
+}
+
+/*
+ * The awk code for these tests is embedded in this file and then extracted
+ * dynamically to create the script that is run together with this extension.
+ * Extraction requires the format for awk code where test code is enclosed
+ * in a BEGIN block, with the BEGIN and close brace on lines by themselves
+ * and at the front of the lines.
+ */
+
+/*
+@load "testext"
+BEGIN {
+ n = split("blacky rusty sophie raincloud lucky", pets)
+ printf("pets has %d elements\n", length(pets))
+ ret = dump_array_and_delete("pets", "3")
+ printf("dump_array_and_delete(pets) returned %d\n", ret)
+ if ("3" in pets)
+ printf("dump_array_and_delete() did NOT remove index \"3\"!\n")
+ else
+ printf("dump_array_and_delete() did remove index \"3\"!\n")
+ print ""
+}
+*/
+static awk_value_t *
+dump_array_and_delete(int nargs, awk_value_t *result)
+{
+ awk_value_t value, value2, value3;
+ awk_flat_array_t *flat_array;
+ size_t count;
+ char *name;
+ int i;
+
+ assert(result != NULL);
+ make_number(0.0, result);
+
+ if (nargs != 2) {
+ printf("dump_array_and_delete: nargs not right (%d should be 2)\n", nargs);
+ goto out;
+ }
+
+ /* get argument named array as flat array and print it */
+ if (get_argument(0, AWK_STRING, & value)) {
+ name = value.str_value.str;
+ if (sym_lookup(name, AWK_ARRAY, & value2))
+ printf("dump_array_and_delete: sym_lookup of %s passed\n", name);
+ else {
+ printf("dump_array_and_delete: sym_lookup of %s failed\n", name);
+ goto out;
+ }
+ } else {
+ printf("dump_array_and_delete: get_argument(0) failed\n");
+ goto out;
+ }
+
+ if (! get_element_count(value2.array_cookie, & count)) {
+ printf("dump_array_and_delete: get_element_count failed\n");
+ goto out;
+ }
+
+ printf("dump_array_and_delete: incoming size is %lu\n", (unsigned long) count);
+
+ if (! flatten_array(value2.array_cookie, & flat_array)) {
+ printf("dump_array_and_delete: could not flatten array\n");
+ goto out;
+ }
+
+ if (flat_array->count != count) {
+ printf("dump_array_and_delete: flat_array->count (%lu) != count (%lu)\n",
+ (unsigned long) flat_array->count,
+ (unsigned long) count);
+ goto out;
+ }
+
+ if (! get_argument(1, AWK_STRING, & value3)) {
+ printf("dump_array_and_delete: get_argument(1) failed\n");
+ goto out;
+ }
+
+ for (i = 0; i < flat_array->count; i++) {
+ printf("\t%s[\"%.*s\"] = %s\n",
+ name,
+ (int) flat_array->elements[i].index.str_value.len,
+ flat_array->elements[i].index.str_value.str,
+ valrep2str(& flat_array->elements[i].value));
+
+ if (strcmp(value3.str_value.str, flat_array->elements[i].index.str_value.str) == 0) {
+ flat_array->elements[i].flags |= AWK_ELEMENT_DELETE;
+ printf("dump_array_and_delete: marking element \"%s\" for deletion\n",
+ flat_array->elements[i].index.str_value.str);
+ }
+ }
+
+ if (! release_flattened_array(value2.array_cookie, flat_array)) {
+ printf("dump_array_and_delete: could not release flattened array\n");
+ goto out;
+ }
+
+ make_number(1.0, result);
+out:
+ return result;
+}
+
+/*
+BEGIN {
+ ENVIRON["testext"]++
+ try_modify_environ()
+ if ("testext" in ENVIRON)
+ print "try_del_environ() could not delete element - pass"
+ else
+ print "try_del_environ() deleted element! - fail"
+ if ("testext2" in ENVIRON)
+ print "try_del_environ() added an element - fail"
+ else
+ print "try_del_environ() could not add an element - pass"
+}
+*/
+
+static awk_value_t *
+try_modify_environ(int nargs, awk_value_t *result)
+{
+ awk_value_t value, index, newvalue;
+ awk_flat_array_t *flat_array;
+ awk_array_t environ_array;
+ size_t count;
+ int i;
+
+ assert(result != NULL);
+ make_number(0.0, result);
+
+ if (nargs != 0) {
+ printf("try_modify_environ: nargs not right (%d should be 0)\n", nargs);
+ goto out;
+ }
+
+ /* get ENVIRON array */
+ if (sym_lookup("ENVIRON", AWK_ARRAY, & value))
+ printf("try_modify_environ: sym_lookup of ENVIRON passed\n");
+ else {
+ printf("try_modify_environ: sym_lookup of ENVIRON failed\n");
+ goto out;
+ }
+
+ environ_array = value.array_cookie;
+ if (! get_element_count(environ_array, & count)) {
+ printf("try_modify_environ: get_element_count failed\n");
+ goto out;
+ }
+
+ /* setting an array element should fail */
+ (void) make_const_string("testext2", 8, & index);
+ (void) make_const_string("a value", 7, & value);
+ if (set_array_element(environ_array, & index, & newvalue)) {
+ printf("try_modify_environ: set_array_element of ENVIRON passed\n");
+ } else {
+ printf("try_modify_environ: set_array_element of ENVIRON failed\n");
+ gawk_free(index.str_value.str);
+ gawk_free(value.str_value.str);
+ }
+
+ if (! flatten_array(environ_array, & flat_array)) {
+ printf("try_modify_environ: could not flatten array\n");
+ goto out;
+ }
+
+ if (flat_array->count != count) {
+ printf("try_modify_environ: flat_array->count (%lu) != count (%lu)\n",
+ (unsigned long) flat_array->count,
+ (unsigned long) count);
+ goto out;
+ }
+
+ for (i = 0; i < flat_array->count; i++) {
+ /* don't print */
+ /*
+ printf("\t%s[\"%.*s\"] = %s\n",
+ name,
+ (int) flat_array->elements[i].index.str_value.len,
+ flat_array->elements[i].index.str_value.str,
+ valrep2str(& flat_array->elements[i].value));
+ */
+ if (strcmp("testext", flat_array->elements[i].index.str_value.str) == 0) {
+ flat_array->elements[i].flags |= AWK_ELEMENT_DELETE;
+ printf("try_modify_environ: marking element \"%s\" for deletion\n",
+ flat_array->elements[i].index.str_value.str);
+ }
+ }
+
+ if (! release_flattened_array(environ_array, flat_array)) {
+ printf("try_modify_environ: could not release flattened array\n");
+ goto out;
+ }
+
+ make_number(1.0, result);
+out:
+ return result;
+}
+
+/*
+BEGIN {
+ testvar = "One Adam Twelve"
+ ret = var_test("testvar")
+ printf("var_test() returned %d, test_var = %s\n", ret, testvar)
+ print ""
+}
+*/
+
+static awk_value_t *
+var_test(int nargs, awk_value_t *result)
+{
+ awk_value_t value, value2;
+ awk_value_t *valp;
+
+ assert(result != NULL);
+ make_number(0.0, result);
+
+ if (nargs != 1) {
+ printf("var_test: nargs not right (%d should be 1)\n", nargs);
+ goto out;
+ }
+
+ /* look up PROCINFO - should succeed fail */
+ if (sym_lookup("PROCINFO", AWK_ARRAY, & value))
+ printf("var_test: sym_lookup of PROCINFO passed - got a value!\n");
+ else
+ printf("var_test: sym_lookup of PROCINFO failed - did not get a value\n");
+
+ /* look up a reserved variable - should pass */
+ if (sym_lookup("ARGC", AWK_NUMBER, & value))
+ printf("var_test: sym_lookup of ARGC passed - got a value!\n");
+ else
+ printf("var_test: sym_lookup of ARGC failed - did not get a value\n");
+
+ /* now try to set it - should fail */
+ value.num_value++;
+ if (sym_update("ARGC", & value))
+ printf("var_test: sym_update of ARGC passed and should not have!\n");
+ else
+ printf("var_test: sym_update of ARGC failed - correctly\n");
+
+ /* look up variable whose name is passed in, should pass */
+ if (get_argument(0, AWK_STRING, & value)) {
+ if (sym_lookup(value.str_value.str, AWK_STRING, & value2)) {
+ /* change the value, should be reflected in awk script */
+ valp = make_number(42.0, & value2);
+
+ if (sym_update(value.str_value.str, valp)) {
+ printf("var_test: sym_update(\"%s\") succeeded\n", value.str_value.str);
+ } else {
+ printf("var_test: sym_update(\"%s\") failed\n", value.str_value.str);
+ goto out;
+ }
+ } else {
+ printf("var_test: sym_lookup(\"%s\") failed\n", value.str_value.str);
+ goto out;
+ }
+ } else {
+ printf("var_test: get_argument() failed\n");
+ goto out;
+ }
+
+ make_number(1.0, result);
+out:
+ return result;
+}
+
+/*
+BEGIN {
+ ERRNO = ""
+ ret = test_errno()
+ printf("test_errno() returned %d, ERRNO = %s\n", ret, ERRNO)
+ print ""
+}
+*/
+static awk_value_t *
+test_errno(int nargs, awk_value_t *result)
+{
+ assert(result != NULL);
+ make_number(0.0, result);
+
+ if (nargs != 0) {
+ printf("test_errno: nargs not right (%d should be 0)\n", nargs);
+ goto out;
+ }
+
+ update_ERRNO_int(ECHILD);
+
+ make_number(1.0, result);
+out:
+ return result;
+}
+
+/*
+BEGIN {
+ for (i = 1; i <= 10; i++)
+ test_array[i] = i + 2
+
+ printf("length of test_array is %d, should be 10\n", length(test_array))
+ ret = test_array_size(test_array);
+ printf("test_array_size() returned %d, length is now %d\n", ret, length(test_array))
+ print ""
+}
+*/
+
+static awk_value_t *
+test_array_size(int nargs, awk_value_t *result)
+{
+ awk_value_t value;
+ size_t count = 0;
+
+ assert(result != NULL);
+ make_number(0.0, result);
+
+ if (nargs != 1) {
+ printf("test_array_size: nargs not right (%d should be 1)\n", nargs);
+ goto out;
+ }
+
+ /* get element count and print it; should match length(array) from awk script */
+ if (! get_argument(0, AWK_ARRAY, & value)) {
+ printf("test_array_size: get_argument failed\n");
+ goto out;
+ }
+
+ if (! get_element_count(value.array_cookie, & count)) {
+ printf("test_array_size: get_element_count failed\n");
+ goto out;
+ }
+
+ printf("test_array_size: incoming size is %lu\n", (unsigned long) count);
+
+ /* clear array - length(array) should then go to zero in script */
+ if (! clear_array(value.array_cookie)) {
+ printf("test_array_size: clear_array failed\n");
+ goto out;
+ }
+
+ make_number(1.0, result);
+
+out:
+ return result;
+}
+
+/*
+BEGIN {
+ n = split("one two three four five six", test_array2)
+ ret = test_array_elem(test_array2, "3")
+ printf("test_array_elem() returned %d, test_array2[3] = %g\n", ret, test_array2[3])
+ if ("5" in test_array2)
+ printf("error: test_array_elem() did not remove element \"5\"\n")
+ else
+ printf("test_array_elem() did remove element \"5\"\n")
+ if ("7" in test_array2)
+ printf("test_array_elem() added element \"7\" --> %s\n", test_array2[7])
+ else
+ printf("test_array_elem() did not add element \"7\"\n")
+ if ("subarray" in test_array2) {
+ if (isarray(test_array2["subarray"])) {
+ for (i in test_array2["subarray"])
+ printf("test_array2[\"subarray\"][\"%s\"] = %s\n",
+ i, test_array2["subarray"][i])
+ } else
+ printf("test_array_elem() added element \"subarray\" as scalar\n")
+ } else
+ printf("test_array_elem() did not add element \"subarray\"\n")
+ print ""
+}
+*/
+static awk_value_t *
+test_array_elem(int nargs, awk_value_t *result)
+{
+ awk_value_t array, index, index2, value;
+
+ make_number(0.0, result); /* default return until full success */
+
+ assert(result != NULL);
+
+ if (nargs != 2) {
+ printf("test_array_elem: nargs not right (%d should be 2)\n", nargs);
+ goto out;
+ }
+
+ /* look up an array element and print the value */
+ if (! get_argument(0, AWK_ARRAY, & array)) {
+ printf("test_array_elem: get_argument 0 (array) failed\n");
+ goto out;
+ }
+ if (! get_argument(1, AWK_STRING, & index)) {
+ printf("test_array_elem: get_argument 1 (index) failed\n");
+ goto out;
+ }
+ (void) make_const_string(index.str_value.str, index.str_value.len, & index2);
+ if (! get_array_element(array.array_cookie, & index2, AWK_UNDEFINED, & value)) {
+ printf("test_array_elem: get_array_element failed\n");
+ goto out;
+ }
+ printf("test_array_elem: a[\"%.*s\"] = %s\n",
+ (int) index.str_value.len,
+ index.str_value.str,
+ valrep2str(& value));
+
+ /* change the element - "3" */
+ (void) make_number(42.0, & value);
+ (void) make_const_string(index.str_value.str, index.str_value.len, & index2);
+ if (! set_array_element(array.array_cookie, & index2, & value)) {
+ printf("test_array_elem: set_array_element failed\n");
+ goto out;
+ }
+
+ /* delete another element - "5" */
+ (void) make_const_string("5", 1, & index);
+ if (! del_array_element(array.array_cookie, & index)) {
+ printf("test_array_elem: del_array_element failed\n");
+ goto out;
+ }
+
+ /* add a new element - "7" */
+ (void) make_const_string("7", 1, & index);
+ (void) make_const_string("seven", 5, & value);
+ if (! set_array_element(array.array_cookie, & index, & value)) {
+ printf("test_array_elem: set_array_element failed\n");
+ goto out;
+ }
+
+ /* add a subarray */
+ (void) make_const_string("subarray", 8, & index);
+ fill_in_array(& value);
+ if (! set_array_element(array.array_cookie, & index, & value)) {
+ printf("test_array_elem: set_array_element (subarray) failed\n");
+ goto out;
+ }
+
+ /* change and deletion should be reflected in awk script */
+ make_number(1.0, result);
+out:
+ return result;
+}
+
+/*
+BEGIN {
+ ret = test_array_param(a_new_array)
+ printf("test_array_param() returned %d\n", ret)
+ printf("isarray(a_new_array) = %d\n", isarray(a_new_array))
+ if (isarray(a_new_array))
+ for (i in a_new_array)
+ printf("a_new_array[\"%s\"] = %s\n",
+ i, a_new_array[i])
+
+ a_scalar = 42
+ ret = test_array_param(a_scalar)
+ printf("test_array_param() returned %d\n", ret)
+ printf("isarray(a_scalar) = %d\n", isarray(a_scalar))
+ print ""
+}
+*/
+
+static awk_value_t *
+test_array_param(int nargs, awk_value_t *result)
+{
+ awk_value_t new_array;
+ awk_value_t arg0;
+
+ (void) nargs; /* silence warnings */
+ make_number(0.0, result);
+
+ if (! get_argument(0, AWK_UNDEFINED, & arg0)) {
+ printf("test_array_param: could not get argument\n");
+ goto out;
+ }
+
+ if (arg0.val_type != AWK_UNDEFINED) {
+ printf("test_array_param: argument is not undefined (%d)\n",
+ arg0.val_type);
+ goto out;
+ }
+
+ fill_in_array(& new_array);
+ if (! set_argument(0, new_array.array_cookie)) {
+ printf("test_array_param: could not change type of argument\n");
+ goto out;
+ }
+
+ make_number(1.0, result);
+out:
+ return result; /* for now */
+}
+
+/*
+BEGIN {
+ printf("Initial value of LINT is %d\n", LINT)
+ ret = print_do_lint();
+ printf("print_do_lint() returned %d\n", ret)
+ LINT = ! LINT
+ printf("Changed value of LINT is %d\n", LINT)
+ ret = print_do_lint();
+ printf("print_do_lint() returned %d\n", ret)
+ print ""
+}
+*/
+static awk_value_t *
+print_do_lint(int nargs, awk_value_t *result)
+{
+ assert(result != NULL);
+ make_number(0.0, result);
+
+ if (nargs != 0) {
+ printf("print_do_lint: nargs not right (%d should be 0)\n", nargs);
+ goto out;
+ }
+
+ printf("print_do_lint: lint = %d\n", do_lint);
+
+ make_number(1.0, result);
+
+out:
+ return result;
+}
+
+/*
+BEGIN {
+ n = split("1 3 5 7 9 11", nums)
+ m = split("the quick brown fox jumps over the lazy dog", strings)
+ for (i in nums) {
+ ret = test_scalar(nums[i] + 0)
+ printf("test_scalar(%d) returned %d, the_scalar is %d\n", nums[i], ret, the_scalar)
+ }
+ for (i in strings) {
+ ret = test_scalar(strings[i])
+ printf("test_scalar(%s) returned %d, the_scalar is %s\n", strings[i], ret, the_scalar)
+ }
+}
+*/
+
+/* test_scalar --- test scalar cookie */
+
+static awk_value_t *
+test_scalar(int nargs, awk_value_t *result)
+{
+ awk_value_t new_value, new_value2;
+ awk_value_t the_scalar;
+
+ (void) nargs; /* silence warnings */
+ make_number(0.0, result);
+
+ if (! sym_lookup("the_scalar", AWK_SCALAR, & the_scalar)) {
+ printf("test_scalar: could not get scalar cookie\n");
+ goto out;
+ }
+
+ if (! get_argument(0, AWK_UNDEFINED, & new_value)) {
+ printf("test_scalar: could not get argument\n");
+ goto out;
+ } else if (new_value.val_type != AWK_STRING && new_value.val_type != AWK_NUMBER) {
+ printf("test_scalar: argument is not a scalar\n");
+ goto out;
+ }
+
+ if (new_value.val_type == AWK_STRING) {
+ make_const_string(new_value.str_value.str, new_value.str_value.len, & new_value2);
+ } else {
+ new_value2 = new_value;
+ }
+
+ if (! sym_update_scalar(the_scalar.scalar_cookie, & new_value2)) {
+ printf("test_scalar: could not update new_value2!\n");
+ goto out;
+ }
+
+ make_number(1.0, result);
+
+out:
+ return result;
+}
+
+/*
+BEGIN {
+ test_scalar_reserved()
+}
+*/
+
+/* test_scalar_reserved --- test scalar cookie on special variable */
+
+static awk_value_t *
+test_scalar_reserved(int nargs, awk_value_t *result)
+{
+ awk_value_t new_value;
+ awk_value_t the_scalar;
+
+ (void) nargs; /* silence warnings */
+ make_number(0.0, result);
+
+ /* look up a reserved variable - should pass */
+ if (sym_lookup("ARGC", AWK_SCALAR, & the_scalar)) {
+ printf("test_scalar_reserved: sym_lookup of ARGC passed - got a value!\n");
+ } else {
+ printf("test_scalar_reserved: sym_lookup of ARGC failed - did not get a value\n");
+ goto out;
+ }
+
+ /* updating it should fail */
+ make_number(42.0, & new_value);
+ if (! sym_update_scalar(the_scalar.scalar_cookie, & new_value)) {
+ printf("test_scalar_reserved: could not update new_value2 for ARGC - pass\n");
+ } else {
+ printf("test_scalar_reserved: was able to update new_value2 for ARGC - fail\n");
+ goto out;
+ }
+
+ make_number(1.0, result);
+
+out:
+ return result;
+}
+
+/*
+BEGIN {
+ print "line 1" > "testexttmp.txt"
+ print "line 2" > "testexttmp.txt"
+ print "line 3" > "testexttmp.txt"
+ close("testexttmp.txt")
+ ARGV[1] = "testexttmp.txt"
+ ARGC = 2
+ getline
+ getline
+ getline # now NR should be 3
+# system("rm testexttmp.txt")
+ ret = test_indirect_vars() # should get correct value of NR
+ printf("test_indirect_var() return %d\n", ret)
+ delete ARGV[1]
+}
+*/
+
+/* test_indirect_vars --- test that access to NR, NF, get correct vales */
+
+static awk_value_t *
+test_indirect_vars(int nargs, awk_value_t *result)
+{
+ awk_value_t value;
+ char *name = "NR";
+
+ (void) nargs; /* silence warnings */
+ assert(result != NULL);
+ make_number(0.0, result);
+
+ /* system("rm testexttmp.txt") */
+ (void) unlink("testexttmp.txt");
+
+ if (sym_lookup(name, AWK_NUMBER, & value))
+ printf("test_indirect_var: sym_lookup of %s passed\n", name);
+ else {
+ printf("test_indirect_var: sym_lookup of %s failed\n", name);
+ goto out;
+ }
+
+ printf("test_indirect_var: value of NR is %g\n", value.num_value);
+
+ make_number(1.0, result);
+out:
+ return result;
+}
+
+/* fill_in_array --- fill in a new array */
+
+static void
+fill_in_array(awk_value_t *new_array)
+{
+ awk_array_t a_cookie;
+ awk_value_t index, value;
+
+ a_cookie = create_array();
+
+ (void) make_const_string("hello", 5, & index);
+ (void) make_const_string("world", 5, & value);
+ if (! set_array_element(a_cookie, & index, & value)) {
+ printf("fill_in_array:%d: set_array_element failed\n", __LINE__);
+ return;
+ }
+
+ (void) make_const_string("answer", 6, & index);
+ (void) make_number(42.0, & value);
+ if (! set_array_element(a_cookie, & index, & value)) {
+ printf("fill_in_array:%d: set_array_element failed\n", __LINE__);
+ return;
+ }
+
+ new_array->val_type = AWK_ARRAY;
+ new_array->array_cookie = a_cookie;
+}
+
+/* create_new_array --- create a named array */
+
+static void
+create_new_array()
+{
+ awk_value_t value;
+
+ fill_in_array(& value);
+ if (! sym_update("new_array", & value))
+ printf("create_new_array: sym_update(\"new_array\") failed!\n");
+}
+
+/* at_exit0 --- first at_exit program, runs last */
+
+static void at_exit0(void *data, int exit_status)
+{
+ printf("at_exit0 called (should be third):");
+ if (data)
+ printf(" data = %p,", data);
+ else
+ printf(" data = NULL,");
+ printf(" exit_status = %d\n", exit_status);
+}
+
+/* at_exit1 --- second at_exit program, runs second */
+
+static int data_for_1 = 0xDeadBeef;
+static void at_exit1(void *data, int exit_status)
+{
+ int *data_p = (int *) data;
+
+ printf("at_exit1 called (should be second):");
+ if (data) {
+ if (data == & data_for_1)
+ printf(" (data is & data_for_1),");
+ else
+ printf(" (data is NOT & data_for_1),");
+ printf(" data value = %#x,", *data_p);
+ } else
+ printf(" data = NULL,");
+ printf(" exit_status = %d\n", exit_status);
+}
+
+/* at_exit2 --- third at_exit program, runs first */
+
+static void at_exit2(void *data, int exit_status)
+{
+ printf("at_exit2 called (should be first):");
+ if (data)
+ printf(" data = %p,", data);
+ else
+ printf(" data = NULL,");
+ printf(" exit_status = %d\n", exit_status);
+}
+
+static awk_ext_func_t func_table[] = {
+ { "dump_array_and_delete", dump_array_and_delete, 2 },
+ { "try_modify_environ", try_modify_environ, 0 },
+ { "var_test", var_test, 1 },
+ { "test_errno", test_errno, 0 },
+ { "test_array_size", test_array_size, 1 },
+ { "test_array_elem", test_array_elem, 2 },
+ { "test_array_param", test_array_param, 1 },
+ { "print_do_lint", print_do_lint, 0 },
+ { "test_scalar", test_scalar, 1 },
+ { "test_scalar_reserved", test_scalar_reserved, 0 },
+ { "test_indirect_vars", test_indirect_vars, 0 },
+};
+
+/* init_testext --- additional initialization function */
+
+static awk_bool_t init_testext(void)
+{
+ awk_value_t value;
+ static const char message[] = "hello, world"; /* of course */
+ static const char message2[] = "i am a scalar";
+
+ /* add at_exit functions */
+ awk_atexit(at_exit0, NULL);
+ awk_atexit(at_exit1, & data_for_1);
+ awk_atexit(at_exit2, NULL);
+
+/*
+BEGIN {
+ printf("answer_num = %g\n", answer_num);
+ printf("message_string = %s\n", message_string);
+ for (i in new_array)
+ printf("new_array[\"%s\"] = \"%s\"\n", i, new_array[i])
+ print ""
+}
+*/
+
+ /* install some variables */
+ if (! sym_update("answer_num", make_number(42, & value)))
+ printf("testext: sym_update(\"answer_num\") failed!\n");
+
+ if (! sym_update("message_string",
+ make_const_string(message, strlen(message), & value)))
+ printf("testext: sym_update(\"answer_num\") failed!\n");
+
+ if (! sym_update("the_scalar",
+ make_const_string(message2, strlen(message2), & value)))
+ printf("testext: sym_update(\"the_scalar\") failed!\n");
+
+ create_new_array();
+
+ return awk_true;
+}
+
+static awk_bool_t (*init_func)(void) = init_testext;
+
+dl_load_func(func_table, testext, "")
diff --git a/extension/testff.awk b/extension/testff.awk
deleted file mode 100644
index 0a0a9b2f..00000000
--- a/extension/testff.awk
+++ /dev/null
@@ -1,30 +0,0 @@
-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"])
-}
diff --git a/extension/testfork.awk b/extension/testfork.awk
deleted file mode 100644
index ca00dca8..00000000
--- a/extension/testfork.awk
+++ /dev/null
@@ -1,20 +0,0 @@
-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"]
- }
-}
diff --git a/extension/testordchr.awk b/extension/testordchr.awk
deleted file mode 100644
index 64e53d16..00000000
--- a/extension/testordchr.awk
+++ /dev/null
@@ -1,6 +0,0 @@
-BEGIN {
- extension("./ordchr.so", "dlload")
-
- print "ord(\"a\") is", ord("a")
- print "chr(65) is", chr(65)
-}
diff --git a/extension/time.3am b/extension/time.3am
new file mode 100644
index 00000000..aeb59199
--- /dev/null
+++ b/extension/time.3am
@@ -0,0 +1,89 @@
+.TH TIME 3am "Jan 15 2013" "Free Software Foundation" "GNU Awk Extension Modules"
+.SH NAME
+time \- time functions for gawk
+.SH SYNOPSIS
+.ft CW
+@load "time"
+.sp
+time = gettimeofday()
+.br
+ret = sleep(amount)
+.ft R
+.SH DESCRIPTION
+The
+.I time
+extension adds two functions named
+.B gettimeofday()
+and
+.BR sleep() ,
+as follows.
+.TP
+.B gettimeofday()
+This function returns the number of seconds since the Epoch
+as a floating-point value. It should have subsecond precision.
+It returns \-1 upon error and sets
+.B ERRNO
+to indicate the problem.
+.TP
+.BI sleep( seconds )
+This function attempts to sleep for the given amount of seconds, which
+may include a fractional portion.
+If
+.I seconds
+is negative, or the attempt to sleep fails,
+then it returns \-1 and sets
+.BR ERRNO .
+Otherwise, the function should return 0 after sleeping
+for the indicated amount of time.
+... .SH NOTES
+... .SH BUGS
+.SH EXAMPLE
+.ft CW
+.nf
+@load "time"
+\&...
+printf "It is now %g seconds since the Epoch\en", gettimeofday()
+printf "Pausing for a while... " ; sleep(2.5) ; print "done"
+.fi
+.ft R
+.SH "SEE ALSO"
+.IR "GAWK: Effective AWK Programming" ,
+.IR filefuncs (3am),
+.IR fnmatch (3am),
+.IR fork (3am),
+.IR inplace (3am),
+.IR ordchr (3am),
+.IR readdir (3am),
+.IR readfile (3am),
+.IR revoutput (3am),
+.IR rwarray (3am).
+.PP
+.IR gettimeofday (2),
+.IR nanosleep (2),
+.IR select (2).
+.SH AUTHOR
+Arnold Robbins,
+.BR arnold@skeeve.com .
+.SH COPYING PERMISSIONS
+Copyright \(co 2012, 2013,
+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.
diff --git a/extension/time.c b/extension/time.c
new file mode 100644
index 00000000..e6b2b39f
--- /dev/null
+++ b/extension/time.c
@@ -0,0 +1,221 @@
+/*
+ * time.c - Builtin functions that provide time-related functions.
+ */
+
+/*
+ * Copyright (C) 2012, 2013, 2014
+ * 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 3 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 HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef __VMS
+#define HAVE_NANOSLEEP
+#define HAVE_GETTIMEOFDAY
+#ifdef gettimeofday
+#undef gettimeofday
+#endif
+#ifdef __ia64__
+/* nanosleep not working correctly on IA64 */
+static int
+vms_fake_nanosleep(struct timespec *rqdly, struct timespec *rmdly)
+{
+ int result;
+ struct timespec mtime1, mtime2;
+
+ result = nanosleep(rqdly, &mtime1);
+ if (result == 0)
+ return 0;
+
+ /* On IA64 it returns 100 nanoseconds early with an error */
+ if ((mtime1.tv_sec == 0) && (mtime1.tv_nsec <= 100)) {
+ mtime1.tv_nsec += 100;
+ result = nanosleep(&mtime1, &mtime2);
+ if (result == 0)
+ return 0;
+ if ((mtime2.tv_sec == 0) && (mtime2.tv_nsec <= 100)) {
+ return 0;
+ }
+ }
+ return result;
+}
+#define nanosleep(x,y) vms_fake_nanosleep(x, y)
+#endif
+#endif
+
+#include "gawkapi.h"
+
+#include "gettext.h"
+#define _(msgid) gettext(msgid)
+#define N_(msgid) msgid
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+static const char *ext_version = "time extension: version 1.0";
+static awk_bool_t (*init_func)(void) = NULL;
+
+int plugin_is_GPL_compatible;
+
+#include <time.h>
+#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#endif
+#if defined(HAVE_SELECT) && defined(HAVE_SYS_SELECT_H)
+#include <sys/select.h>
+#endif
+#if defined(HAVE_GETSYSTEMTIMEASFILETIME)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+/*
+ * Returns time since 1/1/1970 UTC as a floating point value; should
+ * have sub-second precision, but the actual precision will vary based
+ * on the platform
+ */
+static awk_value_t *
+do_gettimeofday(int nargs, awk_value_t *result)
+{
+ double curtime;
+
+ assert(result != NULL);
+
+ if (do_lint && nargs > 0)
+ lintwarn(ext_id, _("gettimeofday: ignoring arguments"));
+
+#if defined(HAVE_GETTIMEOFDAY)
+ {
+ struct timeval tv;
+ gettimeofday(&tv,NULL);
+ curtime = tv.tv_sec+(tv.tv_usec/1000000.0);
+ }
+#elif defined(HAVE_GETSYSTEMTIMEASFILETIME)
+ /* based on perl win32/win32.c:win32_gettimeofday() implementation */
+ {
+ union {
+ unsigned __int64 ft_i64;
+ FILETIME ft_val;
+ } ft;
+
+ /* # of 100-nanosecond intervals since January 1, 1601 (UTC) */
+ GetSystemTimeAsFileTime(&ft.ft_val);
+#ifdef __GNUC__
+#define Const64(x) x##LL
+#else
+#define Const64(x) x##i64
+#endif
+/* Number of 100 nanosecond units from 1/1/1601 to 1/1/1970 */
+#define EPOCH_BIAS Const64(116444736000000000)
+ curtime = (ft.ft_i64 - EPOCH_BIAS)/10000000.0;
+#undef Const64
+ }
+#else
+ /* no way to retrieve system time on this platform */
+ curtime = -1;
+ update_ERRNO_string(_("gettimeofday: not supported on this platform"));
+#endif
+
+ return make_number(curtime, result);
+}
+
+/*
+ * Returns 0 if successful in sleeping the requested time;
+ * returns -1 if there is no platform support, or if the sleep request
+ * did not complete successfully (perhaps interrupted)
+ */
+static awk_value_t *
+do_sleep(int nargs, awk_value_t *result)
+{
+ awk_value_t num;
+ double secs;
+ int rc;
+
+ assert(result != NULL);
+
+ if (do_lint && nargs > 1)
+ lintwarn(ext_id, _("sleep: called with too many arguments"));
+
+ if (! get_argument(0, AWK_NUMBER, &num)) {
+ update_ERRNO_string(_("sleep: missing required numeric argument"));
+ return make_number(-1, result);
+ }
+ secs = num.num_value;
+
+ if (secs < 0) {
+ update_ERRNO_string(_("sleep: argument is negative"));
+ return make_number(-1, result);
+ }
+
+#if defined(HAVE_NANOSLEEP)
+ {
+ struct timespec req;
+
+ req.tv_sec = secs;
+ req.tv_nsec = (secs-(double)req.tv_sec)*1000000000.0;
+ if ((rc = nanosleep(&req,NULL)) < 0)
+ /* probably interrupted */
+ update_ERRNO_int(errno);
+ }
+#elif defined(HAVE_SELECT)
+ {
+ struct timeval timeout;
+
+ timeout.tv_sec = secs;
+ timeout.tv_usec = (secs-(double)timeout.tv_sec)*1000000.0;
+ if ((rc = select(0,NULL,NULL,NULL,&timeout)) < 0)
+ /* probably interrupted */
+ update_ERRNO_int(errno);
+ }
+#elif defined(HAVE_GETSYSTEMTIMEASFILETIME)
+ {
+ DWORD milliseconds = secs * 1000;
+
+ Sleep (milliseconds);
+ rc = 0;
+ }
+#else
+ /* no way to sleep on this platform */
+ rc = -1;
+ update_ERRNO_string(_("sleep: not supported on this platform"));
+#endif
+
+ return make_number(rc, result);
+}
+
+static awk_ext_func_t func_table[] = {
+ { "gettimeofday", do_gettimeofday, 0 },
+ { "sleep", do_sleep, 1 },
+};
+
+/* define the dl_load function using the boilerplate macro */
+
+dl_load_func(func_table, time, "")
diff --git a/extension/xreadlink.c b/extension/xreadlink.c
deleted file mode 100644
index 91e46d9d..00000000
--- a/extension/xreadlink.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* xreadlink.c -- readlink wrapper to return the link name in malloc'd storage
-
- Copyright (C) 2001, 2003, 2004, 2005, 2011 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"
-
-int plugin_is_GPL_compatible;
-
-/* 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 ();
- }
-}
diff --git a/extension/xreadlink.h b/extension/xreadlink.h
deleted file mode 100644
index 0c16610d..00000000
--- a/extension/xreadlink.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* readlink wrapper to return the link name in malloc'd storage
-
- Copyright (C) 2001, 2003, 2004, 2011 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);
diff --git a/extras/ChangeLog b/extras/ChangeLog
new file mode 100644
index 00000000..5f7d33ad
--- /dev/null
+++ b/extras/ChangeLog
@@ -0,0 +1,3 @@
+2014-10-29 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am, gawk.sh, gawk.csh: New files.
diff --git a/extras/Makefile.am b/extras/Makefile.am
new file mode 100644
index 00000000..6a33ae04
--- /dev/null
+++ b/extras/Makefile.am
@@ -0,0 +1,29 @@
+#
+# extras/Makefile.am --- automake input file for gawk
+#
+# Copyright (C) 2014 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 3 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.
+
+profiledir = $(sysconfdir)/profile.d
+profile_DATA = gawk.sh gawk.csh
+
+EXTRA_DIST = $(profile_DATA)
diff --git a/extras/Makefile.in b/extras/Makefile.in
new file mode 100644
index 00000000..f6416f56
--- /dev/null
+++ b/extras/Makefile.in
@@ -0,0 +1,516 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+
+#
+# extras/Makefile.am --- automake input file for gawk
+#
+# Copyright (C) 2014 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 3 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
+#
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+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 = extras
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/mkinstalldirs ChangeLog
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/arch.m4 \
+ $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/gettext.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/lcmessage.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libsigsegv.m4 \
+ $(top_srcdir)/m4/longlong.m4 $(top_srcdir)/m4/mpfr.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/noreturn.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/socket.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 =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(profiledir)"
+DATA = $(profile_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+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@
+GAWKLIBEXT = @GAWKLIBEXT@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+HAVE_LIBSIGSEGV = @HAVE_LIBSIGSEGV@
+INSTALL = @INSTALL@
+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@
+LIBMPFR = @LIBMPFR@
+LIBOBJS = @LIBOBJS@
+LIBREADLINE = @LIBREADLINE@
+LIBS = @LIBS@
+LIBSIGSEGV = @LIBSIGSEGV@
+LIBSIGSEGV_PREFIX = @LIBSIGSEGV_PREFIX@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LTLIBSIGSEGV = @LTLIBSIGSEGV@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POSUB = @POSUB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKET_LIBS = @SOCKET_LIBS@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+acl_shlibext = @acl_shlibext@
+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@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgextensiondir = @pkgextensiondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+profiledir = $(sysconfdir)/profile.d
+profile_DATA = gawk.sh gawk.csh
+EXTRA_DIST = $(profile_DATA)
+all: all-am
+
+.SUFFIXES:
+$(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 ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu extras/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu extras/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
+$(am__aclocal_m4_deps):
+install-profileDATA: $(profile_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(profile_DATA)'; test -n "$(profiledir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(profiledir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(profiledir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(profiledir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(profiledir)" || exit $$?; \
+ done
+
+uninstall-profileDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(profile_DATA)'; test -n "$(profiledir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(profiledir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$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 $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(profiledir)"; 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:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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 mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-profileDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+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-profileDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic cscopelist-am \
+ ctags-am distclean distclean-generic distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-profileDATA install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+ pdf-am ps ps-am tags-am uninstall uninstall-am \
+ uninstall-profileDATA
+
+
+# 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:
diff --git a/extras/gawk.csh b/extras/gawk.csh
new file mode 100644
index 00000000..583d5bcd
--- /dev/null
+++ b/extras/gawk.csh
@@ -0,0 +1,11 @@
+alias gawkpath_default 'unsetenv AWKPATH; setenv AWKPATH `gawk -v x=AWKPATH "BEGIN {print ENVIRON[x]}"`'
+
+alias gawkpath_prepend 'if (! $?AWKPATH) setenv AWKPATH ""; if ($AWKPATH == "") then; unsetenv AWKPATH; setenv AWKPATH `gawk -v x=AWKPATH "BEGIN {print ENVIRON[x]}"`; endif; setenv AWKPATH "\!*"":$AWKPATH"'
+
+alias gawkpath_append 'if (! $?AWKPATH) setenv AWKPATH ""; if ($AWKPATH == "") then; unsetenv AWKPATH; setenv AWKPATH `gawk -v x=AWKPATH "BEGIN {print ENVIRON[x]}"`; endif; setenv AWKPATH "$AWKPATH"":\!*"'
+
+alias gawklibpath_default 'unsetenv AWKLIBPATH; setenv AWKLIBPATH `gawk -v x=AWKLIBPATH "BEGIN {print ENVIRON[x]}"`'
+
+alias gawklibpath_prepend 'if (! $?AWKLIBPATH) setenv AWKLIBPATH ""; if ($AWKLIBPATH == "") then; unsetenv AWKLIBPATH; setenv AWKLIBPATH `gawk -v x=AWKLIBPATH "BEGIN {print ENVIRON[x]}"`; endif; setenv AWKLIBPATH "\!*"":$AWKLIBPATH"'
+
+alias gawklibpath_append 'if (! $?AWKLIBPATH) setenv AWKLIBPATH ""; if ($AWKLIBPATH == "") then; unsetenv AWKLIBPATH; setenv AWKLIBPATH `gawk -v x=AWKLIBPATH "BEGIN {print ENVIRON[x]}"`; endif; setenv AWKLIBPATH "$AWKLIBPATH"":\!*"'
diff --git a/extras/gawk.sh b/extras/gawk.sh
new file mode 100644
index 00000000..c35471fa
--- /dev/null
+++ b/extras/gawk.sh
@@ -0,0 +1,31 @@
+gawkpath_default () {
+ unset AWKPATH
+ export AWKPATH=`gawk 'BEGIN {print ENVIRON["AWKPATH"]}'`
+}
+
+gawkpath_prepend () {
+ [ -z "$AWKPATH" ] && AWKPATH=`gawk 'BEGIN {print ENVIRON["AWKPATH"]}'`
+ export AWKPATH="$*:$AWKPATH"
+}
+
+gawkpath_append () {
+ [ -z "$AWKPATH" ] && AWKPATH=`gawk 'BEGIN {print ENVIRON["AWKPATH"]}'`
+ export AWKPATH="$AWKPATH:$*"
+}
+
+gawklibpath_default () {
+ unset AWKLIBPATH
+ export AWKLIBPATH=`gawk 'BEGIN {print ENVIRON["AWKLIBPATH"]}'`
+}
+
+gawklibpath_prepend () {
+ [ -z "$AWKLIBPATH" ] && \
+ AWKLIBPATH=`gawk 'BEGIN {print ENVIRON["AWKLIBPATH"]}'`
+ export AWKLIBPATH="$*:$AWKLIBPATH"
+}
+
+gawklibpath_append () {
+ [ -z "$AWKLIBPATH" ] && \
+ AWKLIBPATH=`gawk 'BEGIN {print ENVIRON["AWKLIBPATH"]}'`
+ export AWKLIBPATH="$AWKLIBPATH:$*"
+}
diff --git a/field.c b/field.c
index 91789d2f..6a7c6b1d 100644
--- a/field.c
+++ b/field.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-2011 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-2014 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -39,22 +39,21 @@ is_blank(int c)
typedef void (* Setfunc)(long, char *, long, NODE *);
static long (*parse_field)(long, char **, int, NODE *,
- Regexp *, Setfunc, NODE *, NODE *, int);
-static void rebuild_record(void);
+ Regexp *, Setfunc, NODE *, NODE *, bool);
static long re_parse_field(long, char **, int, NODE *,
- Regexp *, Setfunc, NODE *, NODE *, int);
+ Regexp *, Setfunc, NODE *, NODE *, bool);
static long def_parse_field(long, char **, int, NODE *,
- Regexp *, Setfunc, NODE *, NODE *, int);
+ Regexp *, Setfunc, NODE *, NODE *, bool);
static long posix_def_parse_field(long, char **, int, NODE *,
- Regexp *, Setfunc, NODE *, NODE *, int);
+ Regexp *, Setfunc, NODE *, NODE *, bool);
static long null_parse_field(long, char **, int, NODE *,
- Regexp *, Setfunc, NODE *, NODE *, int);
+ Regexp *, Setfunc, NODE *, NODE *, bool);
static long sc_parse_field(long, char **, int, NODE *,
- Regexp *, Setfunc, NODE *, NODE *, int);
+ Regexp *, Setfunc, NODE *, NODE *, bool);
static long fw_parse_field(long, char **, int, NODE *,
- Regexp *, Setfunc, NODE *, NODE *, int);
+ Regexp *, Setfunc, NODE *, NODE *, bool);
static long fpat_parse_field(long, char **, int, NODE *,
- Regexp *, Setfunc, NODE *, NODE *, int);
+ Regexp *, Setfunc, NODE *, NODE *, bool);
static void set_element(long num, char * str, long len, NODE *arr);
static void grow_fields_arr(long num);
static void set_field(long num, char *str, long len, NODE *dummy);
@@ -62,15 +61,15 @@ static void set_field(long num, char *str, long len, NODE *dummy);
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 bool 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 == " " */
+bool 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;
@@ -85,14 +84,20 @@ void
init_fields()
{
emalloc(fields_arr, NODE **, sizeof(NODE *), "init_fields");
- fields_arr[0] = dupnode(Nnull_string);
+
+ getnode(fields_arr[0]);
+ *fields_arr[0] = *Nnull_string;
+ fields_arr[0]->flags |= NULL_FIELD;
+
parse_extent = fields_arr[0]->stptr;
save_FS = dupnode(FS_node->var_value);
+
getnode(Null_field);
*Null_field = *Nnull_string;
Null_field->valref = 1;
- Null_field->flags = (FIELD|STRCUR|STRING);
- field0_valid = TRUE;
+ Null_field->flags = (FIELD|STRCUR|STRING|NULL_FIELD);
+
+ field0_valid = true;
}
/* grow_fields --- acquire new fields as needed */
@@ -134,7 +139,7 @@ set_field(long num,
/* rebuild_record --- Someone assigned a value to $(something).
Fix up $0 to be right */
-static void
+void
rebuild_record()
{
/*
@@ -142,9 +147,7 @@ rebuild_record()
* a size_t isn't big enough.
*/
unsigned long tlen;
- unsigned long ofslen;
NODE *tmp;
- NODE *ofs;
char *ops;
char *cops;
long i;
@@ -152,14 +155,12 @@ rebuild_record()
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;
+ tlen += (NF - 1) * OFSlen;
if ((long) tlen < 0)
tlen = 0;
emalloc(ops, char *, tlen + 2, "rebuild_record");
@@ -177,11 +178,11 @@ rebuild_record()
}
/* copy OFS */
if (i != NF) {
- if (ofslen == 1)
- *cops++ = ofs->stptr[0];
- else if (ofslen != 0) {
- memcpy(cops, ofs->stptr, ofslen);
- cops += ofslen;
+ if (OFSlen == 1)
+ *cops++ = *OFS;
+ else if (OFSlen != 0) {
+ memcpy(cops, OFS, OFSlen);
+ cops += OFSlen;
}
}
}
@@ -194,34 +195,44 @@ rebuild_record()
* 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 *r = fields_arr[i];
+ if (r->stlen > 0) {
NODE *n;
getnode(n);
- if ((fields_arr[i]->flags & FIELD) == 0) {
+ if ((r->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;
+ n->stlen = r->stlen;
+ if ((r->flags & (NUMCUR|NUMBER)) != 0) {
+ n->flags |= (r->flags & (MPFN|MPZN|NUMCUR|NUMBER));
+#ifdef HAVE_MPFR
+ if (is_mpg_float(r)) {
+ mpfr_init(n->mpg_numbr);
+ mpfr_set(n->mpg_numbr, r->mpg_numbr, ROUND_MODE);
+ } else if (is_mpg_integer(r)) {
+ mpz_init(n->mpg_i);
+ mpz_set(n->mpg_i, r->mpg_i);
+ } else
+#endif
+ n->numbr = r->numbr;
}
} else {
- *n = *(fields_arr[i]);
+ *n = *r;
n->flags &= ~(MALLOC|STRING);
}
n->stptr = cops;
- unref(fields_arr[i]);
+ unref(r);
fields_arr[i] = n;
assert((n->flags & WSTRCUR) == 0);
}
- cops += fields_arr[i]->stlen + ofslen;
+ cops += fields_arr[i]->stlen + OFSlen;
}
unref(fields_arr[0]);
fields_arr[0] = tmp;
- field0_valid = TRUE;
+ field0_valid = true;
}
/*
@@ -266,6 +277,12 @@ set_record(const char *buf, int cnt)
/* copy the data */
memcpy(databuf, buf, cnt);
+ /*
+ * Add terminating '\0' so that C library routines
+ * will know when to stop.
+ */
+ databuf[cnt] = '\0';
+
/* manage field 0: */
unref(fields_arr[0]);
getnode(n);
@@ -304,12 +321,12 @@ reset_record()
* $0 = $0 should resplit using the current value of FS.
*/
if (resave_fs) {
- resave_fs = FALSE;
+ resave_fs = false;
unref(save_FS);
save_FS = dupnode(FS_node->var_value);
}
- field0_valid = TRUE;
+ field0_valid = true;
}
/* set_NF --- handle what happens to $0 and fields when NF is changed */
@@ -323,7 +340,8 @@ set_NF()
assert(NF != -1);
- nf = (long) force_number(NF_node->var_value);
+ (void) force_number(NF_node->var_value);
+ nf = get_number_si(NF_node->var_value);
if (nf < 0)
fatal(_("NF set to negative value"));
NF = nf;
@@ -337,6 +355,7 @@ set_NF()
*n = *Null_field;
fields_arr[i] = n;
}
+ parse_high_water = NF;
} else if (parse_high_water > 0) {
for (i = NF + 1; i >= 0 && i <= parse_high_water; i++) {
unref(fields_arr[i]);
@@ -346,7 +365,7 @@ set_NF()
}
parse_high_water = NF;
}
- field0_valid = FALSE;
+ field0_valid = false;
}
/*
@@ -365,7 +384,7 @@ re_parse_field(long up_to, /* parse only up to this field number */
Setfunc set, /* routine to set the value of the parsed field */
NODE *n,
NODE *sep_arr, /* array of field separators (maybe NULL) */
- int in_middle)
+ bool in_middle)
{
char *scan = *buf;
long nf = parse_high_water;
@@ -373,12 +392,10 @@ re_parse_field(long up_to, /* parse only up to this field number */
char *end = scan + len;
int regex_flags = RE_NEED_START;
char *sep;
-#if MBS_SUPPORT
size_t mbclen = 0;
mbstate_t mbs;
- if (gawk_mb_cur_max > 1)
- memset(&mbs, 0, sizeof(mbstate_t));
-#endif
+
+ memset(&mbs, 0, sizeof(mbstate_t));
if (in_middle)
regex_flags |= RE_NO_BOL;
@@ -405,7 +422,6 @@ re_parse_field(long up_to, /* parse only up to this field number */
&& nf < up_to) {
regex_flags |= RE_NO_BOL;
if (REEND(rp, scan) == RESTART(rp, scan)) { /* null match */
-#if MBS_SUPPORT
if (gawk_mb_cur_max > 1) {
mbclen = mbrlen(scan, end-scan, &mbs);
if ((mbclen == 1) || (mbclen == (size_t) -1)
@@ -415,8 +431,7 @@ re_parse_field(long up_to, /* parse only up to this field number */
}
scan += mbclen;
} else
-#endif
- scan++;
+ scan++;
if (scan == end) {
(*set)(++nf, field, (long)(scan - field), n);
up_to = nf;
@@ -459,7 +474,7 @@ def_parse_field(long up_to, /* parse only up to this field number */
Setfunc set, /* routine to set the value of the parsed field */
NODE *n,
NODE *sep_arr, /* array of field separators (maybe NULL) */
- int in_middle ATTRIBUTE_UNUSED)
+ bool in_middle ATTRIBUTE_UNUSED)
{
char *scan = *buf;
long nf = parse_high_water;
@@ -540,7 +555,7 @@ posix_def_parse_field(long up_to, /* parse only up to this field number */
Setfunc set, /* routine to set the value of the parsed field */
NODE *n,
NODE *dummy ATTRIBUTE_UNUSED, /* sep_arr not needed here: hence dummy */
- int in_middle ATTRIBUTE_UNUSED)
+ bool in_middle ATTRIBUTE_UNUSED)
{
char *scan = *buf;
long nf = parse_high_water;
@@ -606,7 +621,7 @@ null_parse_field(long up_to, /* parse only up to this field number */
Setfunc set, /* routine to set the value of the parsed field */
NODE *n,
NODE *sep_arr, /* array of field separators (maybe NULL) */
- int in_middle ATTRIBUTE_UNUSED)
+ bool in_middle ATTRIBUTE_UNUSED)
{
char *scan = *buf;
long nf = parse_high_water;
@@ -617,7 +632,6 @@ null_parse_field(long up_to, /* parse only up to this field number */
if (len == 0)
return nf;
-#if MBS_SUPPORT
if (gawk_mb_cur_max > 1) {
mbstate_t mbs;
memset(&mbs, 0, sizeof(mbstate_t));
@@ -633,12 +647,12 @@ null_parse_field(long up_to, /* parse only up to this field number */
(*set)(++nf, scan, mbclen, n);
scan += mbclen;
}
- } else
-#endif
- for (; nf < up_to && scan < end; scan++) {
- if (sep_arr != NULL && nf > 0)
- set_element(nf, scan, 0L, sep_arr);
- (*set)(++nf, scan, 1L, n);
+ } else {
+ for (; nf < up_to && scan < end; scan++) {
+ if (sep_arr != NULL && nf > 0)
+ set_element(nf, scan, 0L, sep_arr);
+ (*set)(++nf, scan, 1L, n);
+ }
}
*buf = scan;
@@ -661,7 +675,7 @@ sc_parse_field(long up_to, /* parse only up to this field number */
Setfunc set, /* routine to set the value of the parsed field */
NODE *n,
NODE *sep_arr, /* array of field separators (maybe NULL) */
- int in_middle ATTRIBUTE_UNUSED)
+ bool in_middle ATTRIBUTE_UNUSED)
{
char *scan = *buf;
char fschar;
@@ -669,12 +683,10 @@ sc_parse_field(long up_to, /* parse only up to this field number */
char *field;
char *end = scan + len;
char sav;
-#if MBS_SUPPORT
size_t mbclen = 0;
mbstate_t mbs;
- if (gawk_mb_cur_max > 1)
- memset(&mbs, 0, sizeof(mbstate_t));
-#endif
+
+ memset(&mbs, 0, sizeof(mbstate_t));
if (up_to == UNLIMITED)
nf = 0;
@@ -693,7 +705,6 @@ sc_parse_field(long up_to, /* parse only up to this field number */
for (; nf < up_to;) {
field = scan;
-#if MBS_SUPPORT
if (gawk_mb_cur_max > 1) {
while (*scan != fschar) {
mbclen = mbrlen(scan, end-scan, &mbs);
@@ -704,10 +715,10 @@ sc_parse_field(long up_to, /* parse only up to this field number */
}
scan += mbclen;
}
- } else
-#endif
- while (*scan != fschar)
- scan++;
+ } else {
+ while (*scan != fschar)
+ scan++;
+ }
(*set)(++nf, field, (long)(scan - field), n);
if (scan == end)
break;
@@ -742,12 +753,11 @@ fw_parse_field(long up_to, /* parse only up to this field number */
Setfunc set, /* routine to set the value of the parsed field */
NODE *n,
NODE *dummy ATTRIBUTE_UNUSED, /* sep_arr not needed here: hence dummy */
- int in_middle ATTRIBUTE_UNUSED)
+ bool in_middle ATTRIBUTE_UNUSED)
{
char *scan = *buf;
long nf = parse_high_water;
char *end = scan + len;
-#if MBS_SUPPORT
int nmbc;
size_t mbclen;
size_t mbslen;
@@ -756,14 +766,12 @@ fw_parse_field(long up_to, /* parse only up to this field number */
mbstate_t mbs;
memset(&mbs, 0, sizeof(mbstate_t));
-#endif
if (up_to == UNLIMITED)
nf = 0;
if (len == 0)
return nf;
for (; nf < up_to && (len = FIELDWIDTHS[nf+1]) != -1; ) {
-#if MBS_SUPPORT
if (gawk_mb_cur_max > 1) {
nmbc = 0;
mbslen = 0;
@@ -786,10 +794,7 @@ fw_parse_field(long up_to, /* parse only up to this field number */
}
(*set)(++nf, scan, (long) mbslen, n);
scan += mbslen;
- }
- else
-#endif
- {
+ } else {
if (len > end - scan)
len = end - scan;
(*set)(++nf, scan, (long) len, n);
@@ -808,7 +813,7 @@ fw_parse_field(long up_to, /* parse only up to this field number */
void
invalidate_field0()
{
- field0_valid = FALSE;
+ field0_valid = false;
}
/* get_field --- return a particular $n */
@@ -818,7 +823,7 @@ invalidate_field0()
NODE **
get_field(long requested, Func_ptr *assign)
{
- int in_middle = FALSE;
+ bool in_middle = false;
/*
* if requesting whole line but some other field has been altered,
* then the whole line must be rebuilt
@@ -847,7 +852,7 @@ get_field(long requested, Func_ptr *assign)
#if 0
if (assign != NULL)
- field0_valid = FALSE; /* $0 needs reconstruction */
+ field0_valid = false; /* $0 needs reconstruction */
#else
/*
* Keep things uniform. Also, mere intention of assigning something
@@ -872,7 +877,7 @@ get_field(long requested, Func_ptr *assign)
if (parse_high_water == 0) /* starting at the beginning */
parse_extent = fields_arr[0]->stptr;
else
- in_middle = TRUE;
+ in_middle = true;
parse_high_water = (*parse_field)(requested, &parse_extent,
fields_arr[0]->stlen - (parse_extent - fields_arr[0]->stptr),
save_FS, NULL, set_field, (NODE *) NULL, (NODE *) NULL, in_middle);
@@ -928,9 +933,11 @@ set_element(long num, char *s, long len, NODE *n)
it->flags |= MAYBE_NUM;
sub = make_number((AWKNUM) (num));
lhs = assoc_lookup(n, sub);
- unref(sub);
unref(*lhs);
*lhs = it;
+ if (n->astore != NULL)
+ (*n->astore)(n, sub);
+ unref(sub);
}
/* do_split --- implement split(), semantics are same as for field splitting */
@@ -941,11 +948,11 @@ do_split(int nargs)
NODE *src, *arr, *sep, *fs, *tmp, *sep_arr = NULL;
char *s;
long (*parseit)(long, char **, int, NODE *,
- Regexp *, Setfunc, NODE *, NODE *, int);
+ Regexp *, Setfunc, NODE *, NODE *, bool);
Regexp *rp = NULL;
if (nargs == 4) {
- static short warned1 = FALSE, warned2 = FALSE;
+ static bool warned1 = false, warned2 = false;
if (do_traditional || do_posix) {
fatal(_("split: fourth argument is a gawk extension"));
@@ -954,11 +961,11 @@ do_split(int nargs)
if (sep_arr->type != Node_var_array)
fatal(_("split: fourth argument is not an array"));
if (do_lint && ! warned1) {
- warned1 = TRUE;
+ warned1 = true;
lintwarn(_("split: fourth argument is a gawk extension"));
}
if (do_lint_old && ! warned2) {
- warned2 = TRUE;
+ warned2 = true;
warning(_("split: fourth argument is a gawk extension"));
}
}
@@ -993,7 +1000,9 @@ do_split(int nargs)
return make_number((AWKNUM) 0);
}
- if ((sep->re_flags & FS_DFLT) != 0 && current_field_sep() != Using_FIELDWIDTHS && ! RS_is_null) {
+ if ( (sep->re_flags & FS_DFLT) != 0
+ && current_field_sep() == Using_FS
+ && ! RS_is_null) {
parseit = parse_field;
fs = force_string(FS_node->var_value);
rp = FS_regexp;
@@ -1001,12 +1010,12 @@ do_split(int nargs)
fs = sep->re_exp;
if (fs->stlen == 0) {
- static short warned = FALSE;
+ static bool warned = false;
parseit = null_parse_field;
if (do_lint && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn(_("split: null string for third arg is a gawk extension"));
}
} else if (fs->stlen == 1 && (sep->re_flags & CONSTANT) == 0) {
@@ -1025,7 +1034,7 @@ do_split(int nargs)
s = src->stptr;
tmp = make_number((AWKNUM) (*parseit)(UNLIMITED, &s, (int) src->stlen,
- fs, rp, set_element, arr, sep_arr, FALSE));
+ fs, rp, set_element, arr, sep_arr, false));
src = POP_SCALAR(); /* really pop off stack */
DEREF(src);
@@ -1064,7 +1073,7 @@ do_patsplit(int nargs)
if (sep_arr == arr)
fatal(_("patsplit: cannot use the same array for second and fourth args"));
- /* This checks need to be done before clearing any of the arrays */
+ /* These checks need to be done before clearing any of the arrays */
for (tmp = sep_arr->parent_array; tmp != NULL; tmp = tmp->parent_array)
if (tmp == arr)
fatal(_("patsplit: cannot use a subarray of second arg for fourth arg"));
@@ -1085,7 +1094,7 @@ do_patsplit(int nargs)
s = src->stptr;
tmp = make_number((AWKNUM) fpat_parse_field(UNLIMITED, &s,
(int) src->stlen, fpat, rp,
- set_element, arr, sep_arr, FALSE));
+ set_element, arr, sep_arr, false));
}
src = POP_SCALAR(); /* really pop off stack */
@@ -1102,12 +1111,12 @@ set_FIELDWIDTHS()
char *end;
int i;
static int fw_alloc = 4;
- static short warned = FALSE;
- int fatal_error = FALSE;
+ static bool warned = false;
+ bool fatal_error = false;
NODE *tmp;
if (do_lint && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn(_("`FIELDWIDTHS' is a gawk extension"));
}
if (do_traditional) /* quick and dirty, does the trick */
@@ -1141,7 +1150,7 @@ set_FIELDWIDTHS()
++scan;
}
if (*scan == '-') {
- fatal_error = TRUE;
+ fatal_error = true;
break;
}
if (*scan == '\0')
@@ -1156,7 +1165,7 @@ set_FIELDWIDTHS()
|| (*end != '\0' && ! is_blank(*end))
|| !(0 < tmp && tmp <= INT_MAX)
) {
- fatal_error = TRUE;
+ fatal_error = true;
break;
}
FIELDWIDTHS[i] = tmp;
@@ -1185,7 +1194,7 @@ set_FS()
NODE *fs;
static NODE *save_fs = NULL;
static NODE *save_rs = NULL;
- int remake_re = TRUE;
+ bool remake_re = true;
/*
* If changing the way fields are split, obey least-surprise
@@ -1212,7 +1221,7 @@ set_FS()
if (current_field_sep() == Using_FS) {
return;
} else {
- remake_re = FALSE;
+ remake_re = false;
goto choose_fs_function;
}
}
@@ -1221,7 +1230,7 @@ set_FS()
save_fs = dupnode(FS_node->var_value);
unref(save_rs);
save_rs = dupnode(RS_node->var_value);
- resave_fs = TRUE;
+ resave_fs = true;
/* If FS_re_no_case assignment is fatal (make_regexp in remake_re)
* FS_regexp will be NULL with a non-null FS_re_yes_case.
@@ -1235,16 +1244,16 @@ set_FS()
choose_fs_function:
buf[0] = '\0';
- default_FS = FALSE;
+ default_FS = false;
fs = force_string(FS_node->var_value);
if (! do_traditional && fs->stlen == 0) {
- static short warned = FALSE;
+ static bool warned = false;
parse_field = null_parse_field;
if (do_lint && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn(_("null string for `FS' is a gawk extension"));
}
} else if (fs->stlen > 1) {
@@ -1256,7 +1265,7 @@ choose_fs_function:
parse_field = sc_parse_field;
if (fs->stlen == 1) {
if (fs->stptr[0] == ' ') {
- default_FS = TRUE;
+ default_FS = true;
strcpy(buf, "[ \t\n]+");
} else if (fs->stptr[0] == '\\') {
/* yet another special case */
@@ -1272,7 +1281,7 @@ choose_fs_function:
if (fs->stlen == 1) {
if (fs->stptr[0] == ' ')
- default_FS = TRUE;
+ default_FS = true;
else if (fs->stptr[0] == '\\')
/* same special case */
strcpy(buf, "[\\\\]");
@@ -1286,13 +1295,13 @@ choose_fs_function:
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, TRUE);
- FS_re_no_case = make_regexp(buf, strlen(buf), TRUE, TRUE, TRUE);
+ FS_re_yes_case = make_regexp(buf, strlen(buf), false, true, true);
+ FS_re_no_case = make_regexp(buf, strlen(buf), true, 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, TRUE);
- FS_re_no_case = make_regexp(fs->stptr, fs->stlen, TRUE, TRUE, TRUE);
+ FS_re_yes_case = make_regexp(fs->stptr, fs->stlen, false, true, true);
+ FS_re_no_case = make_regexp(fs->stptr, fs->stlen, true, 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;
@@ -1361,13 +1370,13 @@ update_PROCINFO_num(const char *subscript, AWKNUM val)
void
set_FPAT()
{
- static short warned = FALSE;
+ static bool warned = false;
static NODE *save_fpat = NULL;
- int remake_re = TRUE;
+ bool remake_re = true;
NODE *fpat;
if (do_lint && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn(_("`FPAT' is a gawk extension"));
}
if (do_traditional) /* quick and dirty, does the trick */
@@ -1395,7 +1404,7 @@ set_FPAT()
if (current_field_sep() == Using_FPAT) {
return;
} else {
- remake_re = FALSE;
+ remake_re = false;
goto set_fpat_function;
}
}
@@ -1415,8 +1424,8 @@ set_fpat_function:
refree(FPAT_re_no_case);
FPAT_re_yes_case = FPAT_re_no_case = FPAT_regexp = NULL;
- FPAT_re_yes_case = make_regexp(fpat->stptr, fpat->stlen, FALSE, TRUE, TRUE);
- FPAT_re_no_case = make_regexp(fpat->stptr, fpat->stlen, TRUE, TRUE, TRUE);
+ FPAT_re_yes_case = make_regexp(fpat->stptr, fpat->stlen, false, true, true);
+ FPAT_re_no_case = make_regexp(fpat->stptr, fpat->stlen, true, true, true);
FPAT_regexp = (IGNORECASE ? FPAT_re_no_case : FPAT_re_yes_case);
}
@@ -1428,13 +1437,8 @@ set_fpat_function:
* Implementation varies if doing MBS or not.
*/
-#if MBS_SUPPORT
#define increment_scan(scanp, len) incr_scan(scanp, len, & mbs)
-#else
-#define increment_scan(scanp, len) ((*scanp)++)
-#endif
-#if MBS_SUPPORT
/* incr_scan --- MBS version of increment_scan() */
static void
@@ -1455,7 +1459,6 @@ incr_scan(char **scanp, size_t len, mbstate_t *mbs)
} else
(*scanp)++;
}
-#endif
/*
* fpat_parse_field --- parse fields using a regexp.
@@ -1473,8 +1476,8 @@ incr_scan(char **scanp, size_t len, mbstate_t *mbs)
* by gsub.
*
* BEGIN {
- * FALSE = 0
- * TRUE = 1
+ * false = 0
+ * true = 1
*
* fpat[1] = "([^,]*)|(\"[^\"]+\")"
* fpat[2] = fpat[1]
@@ -1507,11 +1510,11 @@ incr_scan(char **scanp, size_t len, mbstate_t *mbs)
* if (length(string) == 0)
* return 0
*
- * eosflag = non_empty = FALSE
+ * eosflag = non_empty = false
* nf = 0
* while (match(string, pattern)) {
* if (RLENGTH > 0) { # easy case
- * non_empty = TRUE
+ * non_empty = true
* if (! (nf in seps)) {
* if (RSTART == 1) # match at front of string
* seps[nf] = ""
@@ -1526,7 +1529,7 @@ incr_scan(char **scanp, size_t len, mbstate_t *mbs)
* # last match was non-empty, and at the
* # current character we get a zero length match,
* # which we don't want, so skip over it
- * non_empty = FALSE
+ * non_empty = false
* seps[nf] = substr(string, 1, 1)
* string = substr(string, 2)
* } else {
@@ -1546,13 +1549,13 @@ incr_scan(char **scanp, size_t len, mbstate_t *mbs)
* } else {
* string = substr(string, RSTART + 1)
* }
- * non_empty = FALSE
+ * non_empty = false
* }
* if (length(string) == 0) {
* if (eosflag)
* break
* else
- * eosflag = TRUE
+ * eosflag = true
* }
* }
* if (length(string) > 0)
@@ -1570,22 +1573,19 @@ fpat_parse_field(long up_to, /* parse only up to this field number */
Setfunc set, /* routine to set the value of the parsed field */
NODE *n,
NODE *sep_arr, /* array of field separators (may be NULL) */
- int in_middle)
+ bool in_middle)
{
char *scan = *buf;
long nf = parse_high_water;
char *start;
char *end = scan + len;
int regex_flags = RE_NEED_START;
- int need_to_set_sep;
- int non_empty;
- int eosflag;
-#if MBS_SUPPORT
+ bool need_to_set_sep;
+ bool non_empty;
+ bool eosflag;
mbstate_t mbs;
- if (gawk_mb_cur_max > 1)
- memset(&mbs, 0, sizeof(mbstate_t));
-#endif
+ memset(&mbs, 0, sizeof(mbstate_t));
if (up_to == UNLIMITED)
nf = 0;
@@ -1600,16 +1600,16 @@ fpat_parse_field(long up_to, /* parse only up to this field number */
regex_flags |= RE_NO_BOL;
non_empty = rp->non_empty;
} else
- non_empty = FALSE;
+ non_empty = false;
- eosflag = FALSE;
- need_to_set_sep = TRUE;
+ eosflag = false;
+ need_to_set_sep = true;
start = scan;
while (research(rp, scan, 0, (end - scan), regex_flags) != -1
&& nf < up_to) {
if (REEND(rp, scan) > RESTART(rp, scan)) { /* if (RLENGTH > 0) */
- non_empty = TRUE;
+ non_empty = true;
if (sep_arr != NULL && need_to_set_sep) {
if (RESTART(rp, scan) == 0) /* match at front */
set_element(nf, start, 0L, sep_arr);
@@ -1628,16 +1628,16 @@ fpat_parse_field(long up_to, /* parse only up to this field number */
scan += REEND(rp, scan);
if (scan >= end)
break;
- need_to_set_sep = TRUE;
+ need_to_set_sep = true;
} else if (non_empty) { /* else if non_empty */
/*
* last match was non-empty, and at the
* current character we get a zero length match,
* which we don't want, so skip over it
*/
- non_empty = FALSE;
+ non_empty = false;
if (sep_arr != NULL) {
- need_to_set_sep = FALSE;
+ need_to_set_sep = false;
set_element(nf, start, 1L, sep_arr);
}
increment_scan(& scan, end - scan);
@@ -1651,12 +1651,12 @@ fpat_parse_field(long up_to, /* parse only up to this field number */
(long) RESTART(rp, scan),
sep_arr);
}
- need_to_set_sep = TRUE;
+ need_to_set_sep = true;
(*set)(++nf, scan, 0L, n);
if (! non_empty && ! eosflag) { /* prev was empty */
if (sep_arr != NULL) {
set_element(nf, start, 1L, sep_arr);
- need_to_set_sep = FALSE;
+ need_to_set_sep = false;
}
}
if (RESTART(rp, scan) == 0)
@@ -1664,13 +1664,13 @@ fpat_parse_field(long up_to, /* parse only up to this field number */
else {
scan += RESTART(rp, scan);
}
- non_empty = FALSE;
+ non_empty = false;
}
if (scan >= end) { /* length(string) == 0 */
if (eosflag)
break;
else
- eosflag = TRUE;
+ eosflag = true;
}
start = scan;
diff --git a/floatcomp.c b/floatcomp.c
index 9d24a67f..16a6d88e 100644
--- a/floatcomp.c
+++ b/floatcomp.c
@@ -26,6 +26,8 @@
#include "awk.h"
#include <math.h>
+#ifdef HAVE_UINTMAX_T
+
/* Assume IEEE-754 arithmetic on pre-C89 hosts. */
#ifndef FLT_RADIX
#define FLT_RADIX 2
@@ -69,28 +71,6 @@ Please port the following code to your weird host;
#define AWKNUM_FRACTION_BITS (AWKNUM_MANT_DIG * (FLT_RADIX == 2 ? 1 : 4))
#define DBL_FRACTION_BITS (DBL_MANT_DIG * (FLT_RADIX == 2 ? 1 : 4))
-/*
- * Floor and Ceil --- Work around a problem in conversion of
- * doubles to exact integers.
- */
-
-/* Floor --- do floor(), also for Cray */
-
-AWKNUM
-Floor(AWKNUM n)
-{
- return floor(n);
-}
-
-/* Ceil --- do ceil(), also for Cray */
-
-AWKNUM
-Ceil(AWKNUM n)
-{
- return ceil(n);
-}
-
-#ifdef HAVE_UINTMAX_T
/* adjust_uint --- fiddle with values, ask Paul Eggert to explain */
uintmax_t
diff --git a/gawkapi.c b/gawkapi.c
new file mode 100644
index 00000000..fc6e159a
--- /dev/null
+++ b/gawkapi.c
@@ -0,0 +1,1155 @@
+/*
+ * gawkapi.c -- Implement the functions defined for gawkapi.h
+ */
+
+/*
+ * Copyright (C) 2012-2014 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 3 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 awk_bool_t node_to_awk_value(NODE *node, awk_value_t *result, awk_valtype_t wanted);
+
+/*
+ * api_get_argument --- get the count'th paramater, zero-based.
+ *
+ * Returns false if count is out of range, or if actual paramater
+ * does not match what is specified in wanted. In the latter
+ * case, fills in result->val_type with the actual type.
+ */
+
+static awk_bool_t
+api_get_argument(awk_ext_id_t id, size_t count,
+ awk_valtype_t wanted, awk_value_t *result)
+{
+#ifdef DYNAMIC
+ NODE *arg;
+
+ if (result == NULL)
+ return awk_false;
+
+ (void) id;
+
+ /* set up default result */
+ memset(result, 0, sizeof(*result));
+ result->val_type = AWK_UNDEFINED;
+
+ /*
+ * Song and dance here. get_array_argument() and get_scalar_argument()
+ * will force a change in type of a parameter that is Node_var_new.
+ *
+ * Start by looking at the unadulterated argument as it was passed.
+ */
+ arg = get_argument(count);
+ if (arg == NULL)
+ return awk_false;
+
+ /* if type is undefined */
+ if (arg->type == Node_var_new) {
+ if (wanted == AWK_UNDEFINED)
+ return true;
+ else if (wanted == AWK_ARRAY) {
+ goto array;
+ } else {
+ goto scalar;
+ }
+ }
+
+ /* at this point, we have real type */
+ if (arg->type == Node_var_array || arg->type == Node_array_ref) {
+ if (wanted != AWK_ARRAY && wanted != AWK_UNDEFINED)
+ return false;
+ goto array;
+ } else
+ goto scalar;
+
+array:
+ /* get the array here */
+ arg = get_array_argument(count, false);
+ if (arg == NULL)
+ return awk_false;
+
+ return node_to_awk_value(arg, result, wanted);
+
+scalar:
+ /* at this point we have a real type that is not an array */
+ arg = get_scalar_argument(count, false);
+ if (arg == NULL)
+ return awk_false;
+
+ return node_to_awk_value(arg, result, wanted);
+#else
+ return awk_false;
+#endif
+}
+
+/* api_set_argument --- convert an argument to an array */
+
+static awk_bool_t
+api_set_argument(awk_ext_id_t id,
+ size_t count,
+ awk_array_t new_array)
+{
+#ifdef DYNAMIC
+ NODE *arg;
+ NODE *array = (NODE *) new_array;
+
+ (void) id;
+
+ if (array == NULL || array->type != Node_var_array)
+ return awk_false;
+
+ if ( (arg = get_argument(count)) == NULL
+ || arg->type != Node_var_new)
+ return awk_false;
+
+ arg = get_array_argument(count, false);
+ if (arg == NULL)
+ return awk_false;
+
+ array->vname = arg->vname;
+ *arg = *array;
+ freenode(array);
+
+ return awk_true;
+#else
+ return awk_false;
+#endif
+}
+
+/* awk_value_to_node --- convert a value into a NODE */
+
+NODE *
+awk_value_to_node(const awk_value_t *retval)
+{
+ NODE *ext_ret_val;
+ NODE *v;
+
+ if (retval == NULL)
+ fatal(_("awk_value_to_node: received null retval"));
+
+ switch (retval->val_type) {
+ case AWK_ARRAY:
+ ext_ret_val = (NODE *) retval->array_cookie;
+ break;
+ case AWK_UNDEFINED:
+ ext_ret_val = dupnode(Nnull_string);
+ break;
+ case AWK_NUMBER:
+ ext_ret_val = make_number(retval->num_value);
+ break;
+ case AWK_STRING:
+ ext_ret_val = make_str_node(retval->str_value.str,
+ retval->str_value.len, ALREADY_MALLOCED);
+ break;
+ case AWK_SCALAR:
+ v = (NODE *) retval->scalar_cookie;
+ if (v->type != Node_var)
+ ext_ret_val = NULL;
+ else
+ ext_ret_val = dupnode(v->var_value);
+ break;
+ case AWK_VALUE_COOKIE:
+ ext_ret_val = dupnode((NODE *)(retval->value_cookie));
+ break;
+ default: /* any invalid type */
+ ext_ret_val = NULL;
+ break;
+ }
+
+ return ext_ret_val;
+}
+
+/* Functions to print messages */
+
+/* api_fatal --- print a fatal message and exit */
+
+static void
+api_fatal(awk_ext_id_t id, const char *format, ...)
+{
+ va_list args;
+
+ (void) id;
+
+ va_start(args, format);
+ err(true, _("fatal: "), format, args);
+ va_end(args);
+}
+
+/* api_warning --- print a warning message and exit */
+
+static void
+api_warning(awk_ext_id_t id, const char *format, ...)
+{
+ va_list args;
+
+ (void) id;
+
+ va_start(args, format);
+ err(false, _("warning: "), format, args);
+ va_end(args);
+}
+
+/* api_lintwarn --- print a lint warning message and exit if appropriate */
+
+static void
+api_lintwarn(awk_ext_id_t id, const char *format, ...)
+{
+ va_list args;
+
+ (void) id;
+
+ va_start(args, format);
+ if (lintwarn == r_fatal) {
+ err(true, _("fatal: "), format, args);
+ va_end(args);
+ } else {
+ err(false, _("warning: "), format, args);
+ va_end(args);
+ }
+}
+
+/* api_register_input_parser --- register an input_parser; for opening files read-only */
+
+static void
+api_register_input_parser(awk_ext_id_t id, awk_input_parser_t *input_parser)
+{
+ (void) id;
+
+ if (input_parser == NULL)
+ return;
+
+ register_input_parser(input_parser);
+}
+
+/* api_register_output_wrapper --- egister an output wrapper, for writing files / two-way pipes */
+
+static void api_register_output_wrapper(awk_ext_id_t id,
+ awk_output_wrapper_t *output_wrapper)
+{
+ (void) id;
+
+ if (output_wrapper == NULL)
+ return;
+
+ register_output_wrapper(output_wrapper);
+}
+
+/* api_register_two_way_processor --- register a processor for two way I/O */
+
+static void
+api_register_two_way_processor(awk_ext_id_t id,
+ awk_two_way_processor_t *two_way_processor)
+{
+ (void) id;
+
+ if (two_way_processor == NULL)
+ return;
+
+ register_two_way_processor(two_way_processor);
+}
+
+/* Functions to update ERRNO */
+
+/* api_update_ERRNO_int --- update ERRNO with an integer value */
+
+static void
+api_update_ERRNO_int(awk_ext_id_t id, int errno_val)
+{
+ (void) id;
+
+ update_ERRNO_int(errno_val);
+}
+
+/* api_update_ERRNO_string --- update ERRNO with a string value */
+
+static void
+api_update_ERRNO_string(awk_ext_id_t id,
+ const char *string)
+{
+ (void) id;
+
+ if (string == NULL)
+ return;
+
+ update_ERRNO_string(string);
+}
+
+/* api_unset_ERRNO --- unset ERRNO */
+
+static void
+api_unset_ERRNO(awk_ext_id_t id)
+{
+ (void) id;
+
+ unset_ERRNO();
+}
+
+
+/* api_add_ext_func --- add a function to the interpreter, returns true upon success */
+
+static awk_bool_t
+api_add_ext_func(awk_ext_id_t id,
+ const char *namespace,
+ const awk_ext_func_t *func)
+{
+ (void) id;
+ (void) namespace;
+
+ if (func == NULL)
+ return awk_false;
+
+#ifdef DYNAMIC
+ return make_builtin(func);
+#else
+ return awk_false;
+#endif
+}
+
+/* Stuff for exit handler - do it as linked list */
+
+struct ext_exit_handler {
+ struct ext_exit_handler *next;
+ void (*funcp)(void *data, int exit_status);
+ void *arg0;
+};
+static struct ext_exit_handler *list_head = NULL;
+
+/* run_ext_exit_handlers --- run the extension exit handlers, LIFO order */
+
+void
+run_ext_exit_handlers(int exitval)
+{
+ struct ext_exit_handler *p, *next;
+
+ for (p = list_head; p != NULL; p = next) {
+ next = p->next;
+ p->funcp(p->arg0, exitval);
+ free(p);
+ }
+ list_head = NULL;
+}
+
+/* api_awk_atexit --- add an exit call back */
+
+static void
+api_awk_atexit(awk_ext_id_t id,
+ void (*funcp)(void *data, int exit_status),
+ void *arg0)
+{
+ struct ext_exit_handler *p;
+
+ (void) id;
+
+ if (funcp == NULL)
+ return;
+
+ /* allocate memory */
+ emalloc(p, struct ext_exit_handler *, sizeof(struct ext_exit_handler), "api_awk_atexit");
+
+ /* fill it in */
+ p->funcp = funcp;
+ p->arg0 = arg0;
+
+ /* add to linked list, LIFO order */
+ p->next = list_head;
+ list_head = p;
+}
+
+/* node_to_awk_value --- convert a node into a value for an extension */
+
+static awk_bool_t
+node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted)
+{
+ awk_bool_t ret = awk_false;
+
+ if (node == NULL)
+ fatal(_("node_to_awk_value: received null node"));
+
+ if (val == NULL)
+ fatal(_("node_to_awk_value: received null val"));
+
+ switch (node->type) {
+ case Node_var_new: /* undefined variable */
+ val->val_type = AWK_UNDEFINED;
+ if (wanted == AWK_UNDEFINED) {
+ ret = awk_true;
+ }
+ break;
+
+ case Node_var:
+ /* a scalar value */
+ if (wanted == AWK_SCALAR) {
+ val->val_type = AWK_SCALAR;
+ val->scalar_cookie = (void *) node;
+ ret = awk_true;
+ break;
+ }
+
+ node = node->var_value;
+ /* FALL THROUGH */
+ case Node_val:
+ /* a scalar value */
+ switch (wanted) {
+ case AWK_NUMBER:
+ val->val_type = AWK_NUMBER;
+
+ (void) force_number(node);
+ if ((node->flags & NUMCUR) != 0) {
+ val->num_value = get_number_d(node);
+ ret = awk_true;
+ }
+ break;
+
+ case AWK_STRING:
+ val->val_type = AWK_STRING;
+
+ (void) force_string(node);
+ if ((node->flags & STRCUR) != 0) {
+ val->str_value.str = node->stptr;
+ val->str_value.len = node->stlen;
+ ret = awk_true;
+ }
+ break;
+
+ case AWK_SCALAR:
+ if ((node->flags & NUMBER) != 0) {
+ val->val_type = AWK_NUMBER;
+ } else if ((node->flags & STRING) != 0) {
+ val->val_type = AWK_STRING;
+ } else
+ val->val_type = AWK_UNDEFINED;
+ ret = awk_false;
+ break;
+
+ case AWK_UNDEFINED:
+ /* return true and actual type for request of undefined */
+ if (node == Nnull_string) {
+ val->val_type = AWK_UNDEFINED;
+ ret = awk_true;
+ } else if ((node->flags & NUMBER) != 0) {
+ val->val_type = AWK_NUMBER;
+ val->num_value = get_number_d(node);
+ ret = awk_true;
+ } else if ((node->flags & STRING) != 0) {
+ val->val_type = AWK_STRING;
+ val->str_value.str = node->stptr;
+ val->str_value.len = node->stlen;
+ ret = awk_true;
+ } else
+ val->val_type = AWK_UNDEFINED;
+ break;
+
+ case AWK_ARRAY:
+ case AWK_VALUE_COOKIE:
+ break;
+ }
+ break;
+
+ case Node_var_array:
+ val->val_type = AWK_ARRAY;
+ if (wanted == AWK_ARRAY || wanted == AWK_UNDEFINED) {
+ val->array_cookie = node;
+ ret = awk_true;
+ } else
+ ret = awk_false;
+ break;
+
+ default:
+ val->val_type = AWK_UNDEFINED;
+ ret = awk_false;
+ break;
+ }
+
+ return ret;
+}
+
+/*
+ * Symbol table access:
+ * - No access to special variables (NF, etc.)
+ * - One special exception: PROCINFO.
+ * - Use sym_update() to change a value, including from UNDEFINED
+ * to scalar or array.
+ */
+/*
+ * Lookup a variable, fills in value. No messing with the value
+ * returned. Returns false if the variable doesn't exist
+ * or the wrong type was requested.
+ * In the latter case, fills in vaule->val_type with the real type.
+ * Built-in variables (except PROCINFO) may not be accessed by an extension.
+ */
+
+/* api_sym_lookup --- look up a symbol */
+
+static awk_bool_t
+api_sym_lookup(awk_ext_id_t id,
+ const char *name,
+ awk_valtype_t wanted,
+ awk_value_t *result)
+{
+ NODE *node;
+
+ update_global_values(); /* make sure stuff like NF, NR, are up to date */
+
+ if ( name == NULL
+ || *name == '\0'
+ || result == NULL
+ || (node = lookup(name)) == NULL)
+ return awk_false;
+
+ if (is_off_limits_var(name)) /* a built-in variable */
+ node->flags |= NO_EXT_SET;
+
+ return node_to_awk_value(node, result, wanted);
+}
+
+/* api_sym_lookup_scalar --- retrieve the current value of a scalar */
+
+static awk_bool_t
+api_sym_lookup_scalar(awk_ext_id_t id,
+ awk_scalar_t cookie,
+ awk_valtype_t wanted,
+ awk_value_t *result)
+{
+ NODE *node = (NODE *) cookie;
+
+ if (node == NULL
+ || result == NULL
+ || node->type != Node_var)
+ return awk_false;
+
+ update_global_values(); /* make sure stuff like NF, NR, are up to date */
+
+ return node_to_awk_value(node, result, wanted);
+}
+
+/* api_sym_update --- update a symbol's value, see gawkapi.h for semantics */
+
+static awk_bool_t
+api_sym_update(awk_ext_id_t id,
+ const char *name,
+ awk_value_t *value)
+{
+ NODE *node;
+ NODE *array_node;
+
+ if ( name == NULL
+ || *name == '\0'
+ || value == NULL)
+ return awk_false;
+
+ switch (value->val_type) {
+ case AWK_NUMBER:
+ case AWK_STRING:
+ case AWK_UNDEFINED:
+ case AWK_ARRAY:
+ case AWK_SCALAR:
+ case AWK_VALUE_COOKIE:
+ break;
+
+ default:
+ /* fatal(_("api_sym_update: invalid value for type of new value (%d)"), value->val_type); */
+ return awk_false;
+ }
+
+ node = lookup(name);
+
+ if (node == NULL) {
+ /* new value to be installed */
+ if (value->val_type == AWK_ARRAY) {
+ array_node = awk_value_to_node(value);
+ node = install_symbol(estrdup((char *) name, strlen(name)),
+ Node_var_array);
+ array_node->vname = node->vname;
+ *node = *array_node;
+ freenode(array_node);
+ value->array_cookie = node; /* pass new cookie back to extension */
+ } else {
+ /* regular variable */
+ node = install_symbol(estrdup((char *) name, strlen(name)),
+ Node_var);
+ node->var_value = awk_value_to_node(value);
+ }
+
+ return awk_true;
+ }
+
+ /*
+ * If we get here, then it exists already. Any valid type is
+ * OK except for AWK_ARRAY.
+ */
+ if ( (node->flags & NO_EXT_SET) != 0
+ || is_off_limits_var(name)) { /* most built-in vars not allowed */
+ node->flags |= NO_EXT_SET;
+ return awk_false;
+ }
+
+ if ( value->val_type != AWK_ARRAY
+ && (node->type == Node_var || node->type == Node_var_new)) {
+ unref(node->var_value);
+ node->var_value = awk_value_to_node(value);
+ if (node->type == Node_var_new && value->val_type != AWK_UNDEFINED)
+ node->type = Node_var;
+
+ return awk_true;
+ }
+
+ return awk_false;
+}
+
+/* api_sym_update_scalar --- update a scalar cookie */
+
+static awk_bool_t
+api_sym_update_scalar(awk_ext_id_t id,
+ awk_scalar_t cookie,
+ awk_value_t *value)
+{
+ NODE *node = (NODE *) cookie;
+
+ if (value == NULL
+ || node == NULL
+ || node->type != Node_var
+ || (node->flags & NO_EXT_SET) != 0)
+ return awk_false;
+
+ /*
+ * Optimization: if valref is 1, and the new value is a string or
+ * a number, we can avoid calling unref and then making a new node
+ * by simply installing the new value. First, we follow the same
+ * recipe used by node.c:r_unref to wipe the current values, and then
+ * we copy the logic from r_make_number or make_str_node to install
+ * the new value.
+ */
+ switch (value->val_type) {
+ case AWK_NUMBER:
+ if (node->var_value->valref == 1 && ! do_mpfr) {
+ NODE *r = node->var_value;
+
+ /* r_unref: */
+ if ((r->flags & (MALLOC|STRCUR)) == (MALLOC|STRCUR))
+ efree(r->stptr);
+ free_wstr(r);
+
+ /* r_make_number: */
+ r->numbr = value->num_value;
+ r->flags = MALLOC|NUMBER|NUMCUR;
+ r->stptr = NULL;
+ r->stlen = 0;
+ return awk_true;
+ }
+ break;
+ case AWK_STRING:
+ if (node->var_value->valref == 1) {
+ NODE *r = node->var_value;
+
+ /* r_unref: */
+ if ((r->flags & (MALLOC|STRCUR)) == (MALLOC|STRCUR))
+ efree(r->stptr);
+
+ mpfr_unset(r);
+ free_wstr(r);
+
+ /* make_str_node(s, l, ALREADY_MALLOCED): */
+ r->numbr = 0;
+ r->flags = (MALLOC|STRING|STRCUR);
+ r->stfmt = -1;
+ r->stptr = value->str_value.str;
+ r->stlen = value->str_value.len;
+ return awk_true;
+ }
+ break;
+ case AWK_UNDEFINED:
+ case AWK_SCALAR:
+ case AWK_VALUE_COOKIE:
+ break;
+
+ default: /* AWK_ARRAY or invalid type */
+ return awk_false;
+ }
+
+ /* do it the hard (slow) way */
+ unref(node->var_value);
+ node->var_value = awk_value_to_node(value);
+ return awk_true;
+}
+
+/*
+ * valid_subscript_type --- test if a type is allowed for an array subscript.
+ *
+ * Any scalar value is fine, so only AWK_ARRAY (or an invalid type) is illegal.
+ */
+
+static inline bool
+valid_subscript_type(awk_valtype_t valtype)
+{
+ switch (valtype) {
+ case AWK_UNDEFINED:
+ case AWK_NUMBER:
+ case AWK_STRING:
+ case AWK_SCALAR:
+ case AWK_VALUE_COOKIE:
+ return true;
+ default: /* AWK_ARRAY or an invalid type */
+ return false;
+ }
+}
+
+/* Array management */
+/*
+ * api_get_array_element --- teturn the value of an element - read only!
+ *
+ * Use set_array_element to change it.
+ */
+
+static awk_bool_t
+api_get_array_element(awk_ext_id_t id,
+ awk_array_t a_cookie,
+ const awk_value_t *const index,
+ awk_valtype_t wanted,
+ awk_value_t *result)
+{
+ NODE *array = (NODE *) a_cookie;
+ NODE *subscript;
+ NODE **aptr;
+
+ /* don't check for index len zero, null str is ok as index */
+ if ( array == NULL
+ || array->type != Node_var_array
+ || result == NULL
+ || index == NULL
+ || ! valid_subscript_type(index->val_type))
+ return awk_false;
+
+ subscript = awk_value_to_node(index);
+
+ /* if it doesn't exist, return false */
+ if (in_array(array, subscript) == NULL) {
+ unref(subscript);
+ return awk_false;
+ }
+
+ aptr = assoc_lookup(array, subscript);
+
+ if (aptr == NULL) { /* can't happen */
+ unref(subscript);
+ return awk_false;
+ }
+
+ unref(subscript);
+
+ return node_to_awk_value(*aptr, result, wanted);
+}
+
+/*
+ * api_set_array_element --- change (or create) element in existing array
+ * with element->index and element->value.
+ */
+
+static awk_bool_t
+api_set_array_element(awk_ext_id_t id, awk_array_t a_cookie,
+ const awk_value_t *const index,
+ const awk_value_t *const value)
+{
+ NODE *array = (NODE *)a_cookie;
+ NODE *tmp;
+ NODE *elem;
+ NODE **aptr;
+
+ /* don't check for index len zero, null str is ok as index */
+ if ( array == NULL
+ || array->type != Node_var_array
+ || (array->flags & NO_EXT_SET) != 0
+ || index == NULL
+ || value == NULL
+ || ! valid_subscript_type(index->val_type))
+ return awk_false;
+
+ tmp = awk_value_to_node(index);
+ aptr = assoc_lookup(array, tmp);
+ unref(tmp);
+ unref(*aptr);
+ elem = *aptr = awk_value_to_node(value);
+ if (elem->type == Node_var_array) {
+ elem->parent_array = array;
+ elem->vname = estrdup(index->str_value.str,
+ index->str_value.len);
+ }
+
+ return awk_true;
+}
+
+/*
+ * remove_element --- remove an array element
+ * common code used by multiple functions
+ */
+
+static void
+remove_element(NODE *array, NODE *subscript)
+{
+ NODE *val;
+
+ if (array == NULL)
+ fatal(_("remove_element: received null array"));
+
+ if (subscript == NULL)
+ fatal(_("remove_element: received null subscript"));
+
+ val = in_array(array, subscript);
+
+ if (val == NULL)
+ return;
+
+ if (val->type == Node_var_array) {
+ assoc_clear(val);
+ /* cleared a sub-array, free Node_var_array */
+ efree(val->vname);
+ freenode(val);
+ } else
+ unref(val);
+
+ (void) assoc_remove(array, subscript);
+}
+
+/*
+ * api_del_array_element --- remove the element with the given index.
+ * Return success if removed or if element did not exist.
+ */
+
+static awk_bool_t
+api_del_array_element(awk_ext_id_t id,
+ awk_array_t a_cookie, const awk_value_t* const index)
+{
+ NODE *array, *sub;
+
+ array = (NODE *) a_cookie;
+ if ( array == NULL
+ || array->type != Node_var_array
+ || (array->flags & NO_EXT_SET) != 0
+ || index == NULL
+ || ! valid_subscript_type(index->val_type))
+ return awk_false;
+
+ sub = awk_value_to_node(index);
+ remove_element(array, sub);
+ unref(sub);
+
+ return awk_true;
+}
+
+/*
+ * api_get_element_count --- retrieve total number of elements in array.
+ * Return false if some kind of error.
+ */
+
+static awk_bool_t
+api_get_element_count(awk_ext_id_t id,
+ awk_array_t a_cookie, size_t *count)
+{
+ NODE *node = (NODE *) a_cookie;
+
+ if (count == NULL || node == NULL || node->type != Node_var_array)
+ return awk_false;
+
+ *count = node->table_size;
+ return awk_true;
+}
+
+/* api_create_array --- create a new array cookie to which elements may be added */
+
+static awk_array_t
+api_create_array(awk_ext_id_t id)
+{
+ NODE *n;
+
+ getnode(n);
+ memset(n, 0, sizeof(NODE));
+ null_array(n);
+
+ return (awk_array_t) n;
+}
+
+/* api_clear_array --- clear out an array */
+
+static awk_bool_t
+api_clear_array(awk_ext_id_t id, awk_array_t a_cookie)
+{
+ NODE *node = (NODE *) a_cookie;
+
+ if ( node == NULL
+ || node->type != Node_var_array
+ || (node->flags & NO_EXT_SET) != 0)
+ return awk_false;
+
+ assoc_clear(node);
+ return awk_true;
+}
+
+/* api_flatten_array --- flatten out an array so that it can be looped over easily. */
+
+static awk_bool_t
+api_flatten_array(awk_ext_id_t id,
+ awk_array_t a_cookie,
+ awk_flat_array_t **data)
+{
+ NODE **list;
+ size_t i, j;
+ NODE *array = (NODE *) a_cookie;
+ size_t alloc_size;
+
+ if ( array == NULL
+ || array->type != Node_var_array
+ || array->table_size == 0
+ || data == NULL)
+ return awk_false;
+
+ alloc_size = sizeof(awk_flat_array_t) +
+ (array->table_size - 1) * sizeof(awk_element_t);
+
+ emalloc(*data, awk_flat_array_t *, alloc_size,
+ "api_flatten_array");
+ memset(*data, 0, alloc_size);
+
+ list = assoc_list(array, "@unsorted", ASORTI);
+
+ (*data)->opaque1 = array;
+ (*data)->opaque2 = list;
+ (*data)->count = array->table_size;
+
+ for (i = j = 0; i < 2 * array->table_size; i += 2, j++) {
+ NODE *index, *value;
+
+ index = list[i];
+ value = list[i + 1]; /* number or string or subarray */
+
+ /*
+ * Convert index and value to ext types. Force the
+ * index to be a string, since indices are always
+ * conceptually strings, regardless of internal optimizations
+ * to treat them as integers in some cases.
+ */
+ if (! node_to_awk_value(index,
+ & (*data)->elements[j].index, AWK_STRING)) {
+ fatal(_("api_flatten_array: could not convert index %d\n"),
+ (int) i);
+ }
+ if (! node_to_awk_value(value,
+ & (*data)->elements[j].value, AWK_UNDEFINED)) {
+ fatal(_("api_flatten_array: could not convert value %d\n"),
+ (int) i);
+ }
+ }
+ return awk_true;
+}
+
+/*
+ * api_release_flattened_array --- release array memory,
+ * delete any marked elements. Count must match what
+ * gawk thinks the size is.
+ */
+
+static awk_bool_t
+api_release_flattened_array(awk_ext_id_t id,
+ awk_array_t a_cookie,
+ awk_flat_array_t *data)
+{
+ NODE *array = a_cookie;
+ NODE **list;
+ size_t i, j, k;
+
+ if ( array == NULL
+ || array->type != Node_var_array
+ || data == NULL
+ || array != (NODE *) data->opaque1
+ || data->count != array->table_size
+ || data->opaque2 == NULL)
+ return awk_false;
+
+ list = (NODE **) data->opaque2;
+
+ /* free index nodes */
+ for (i = j = 0, k = 2 * array->table_size; i < k; i += 2, j++) {
+ /* Delete items flagged for delete. */
+ if ( (data->elements[j].flags & AWK_ELEMENT_DELETE) != 0
+ && (array->flags & NO_EXT_SET) == 0) {
+ remove_element(array, list[i]);
+ }
+ unref(list[i]);
+ }
+
+ efree(list);
+ efree(data);
+
+ return awk_true;
+}
+
+/* api_create_value --- create a cached value */
+
+static awk_bool_t
+api_create_value(awk_ext_id_t id, awk_value_t *value,
+ awk_value_cookie_t *result)
+{
+ if (value == NULL || result == NULL)
+ return awk_false;
+
+ switch (value->val_type) {
+ case AWK_NUMBER:
+ case AWK_STRING:
+ break;
+ default:
+ /* reject anything other than a simple scalar */
+ return awk_false;
+ }
+
+ return (awk_bool_t) ((*result = awk_value_to_node(value)) != NULL);
+}
+
+/* api_release_value --- release a cached value */
+
+static awk_bool_t
+api_release_value(awk_ext_id_t id, awk_value_cookie_t value)
+{
+ NODE *val = (NODE *) value;
+
+ if (val == NULL)
+ return awk_false;
+
+ unref(val);
+ return awk_true;
+}
+
+/*
+ * Register a version string for this extension with gawk.
+ */
+
+struct version_info {
+ const char *version;
+ struct version_info *next;
+};
+
+static struct version_info *vi_head;
+
+/* api_register_ext_version --- add an extension version string to the list */
+
+static void
+api_register_ext_version(awk_ext_id_t id, const char *version)
+{
+ struct version_info *info;
+
+ if (version == NULL)
+ return;
+
+ (void) id;
+
+ emalloc(info, struct version_info *, sizeof(struct version_info), "register_ext_version");
+ info->version = version;
+ info->next = vi_head;
+ vi_head = info;
+}
+
+/* the struct api */
+gawk_api_t api_impl = {
+ /* data */
+ GAWK_API_MAJOR_VERSION, /* major and minor versions */
+ GAWK_API_MINOR_VERSION,
+ { 0 }, /* do_flags */
+
+ /* registration functions */
+ api_add_ext_func,
+ api_register_input_parser,
+ api_register_output_wrapper,
+ api_register_two_way_processor,
+ api_awk_atexit,
+ api_register_ext_version,
+
+ /* message printing functions */
+ api_fatal,
+ api_warning,
+ api_lintwarn,
+
+ /* updating ERRNO */
+ api_update_ERRNO_int,
+ api_update_ERRNO_string,
+ api_unset_ERRNO,
+
+ /* Function arguments */
+ api_get_argument,
+ api_set_argument,
+
+ /* Accessing and installing variables and constants */
+ api_sym_lookup,
+ api_sym_update,
+
+ /* Accessing and modifying variables via scalar cookies */
+ api_sym_lookup_scalar,
+ api_sym_update_scalar,
+
+ /* Cached values */
+ api_create_value,
+ api_release_value,
+
+ /* Array management */
+ api_get_element_count,
+ api_get_array_element,
+ api_set_array_element,
+ api_del_array_element,
+ api_create_array,
+ api_clear_array,
+ api_flatten_array,
+ api_release_flattened_array,
+
+ /* Memory allocation */
+ malloc,
+ calloc,
+ realloc,
+ free,
+};
+
+/* init_ext_api --- init the extension API */
+
+void
+init_ext_api()
+{
+ /* force values to 1 / 0 */
+ api_impl.do_flags[0] = (do_lint ? 1 : 0);
+ api_impl.do_flags[1] = (do_traditional ? 1 : 0);
+ api_impl.do_flags[2] = (do_profile ? 1 : 0);
+ api_impl.do_flags[3] = (do_sandbox ? 1 : 0);
+ api_impl.do_flags[4] = (do_debug ? 1 : 0);
+ api_impl.do_flags[5] = (do_mpfr ? 1 : 0);
+}
+
+/* update_ext_api --- update the variables in the API that can change */
+
+void
+update_ext_api()
+{
+ api_impl.do_flags[0] = (do_lint ? 1 : 0);
+}
+
+/* print_ext_versions --- print the list */
+
+extern void
+print_ext_versions(void)
+{
+ struct version_info *p;
+
+ for (p = vi_head; p != NULL; p = p->next)
+ printf("%s\n", p->version);
+}
diff --git a/gawkapi.h b/gawkapi.h
new file mode 100644
index 00000000..d8215450
--- /dev/null
+++ b/gawkapi.h
@@ -0,0 +1,926 @@
+/*
+ * gawkapi.h -- Definitions for use by extension functions calling into gawk.
+ */
+
+/*
+ * Copyright (C) 2012-2014 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 3 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
+ */
+
+/*
+ * The following types and/or macros and/or functions are referenced
+ * in this file. For correct use, you must therefore include the
+ * corresponding standard header file BEFORE including this file.
+ *
+ * FILE - <stdio.h>
+ * NULL - <stddef.h>
+ * memset(), memcpy() - <string.h>
+ * size_t - <sys/types.h>
+ * struct stat - <sys/stat.h>
+ *
+ * Due to portability concerns, especially to systems that are not
+ * fully standards-compliant, it is your responsibility to include
+ * the correct files in the correct way. This requirement is necessary
+ * in order to keep this file clean, instead of becoming a portability
+ * hodge-podge as can be seen in the gawk source code.
+ *
+ * To pass reasonable integer values for ERRNO, you will also need to
+ * include <errno.h>.
+ */
+
+#ifndef _GAWK_API_H
+#define _GAWK_API_H
+
+/*
+ * General introduction:
+ *
+ * This API purposely restricts itself to ISO C 90 features. In particular, no
+ * bool, no // comments, no use of the restrict keyword, or anything else,
+ * in order to provide maximal portability.
+ *
+ * Exception: the "inline" keyword is used below in the "constructor"
+ * functions. If your compiler doesn't support it, you should either
+ * -Dinline='' on your command line, or use the autotools and include a
+ * config.h in your extensions.
+ *
+ * Additional important information:
+ *
+ * 1. ALL string values in awk_value_t objects need to come from api_malloc().
+ * Gawk will handle releasing the storage if necessary. This is slightly
+ * awkward, in that you can't take an awk_value_t that you got from gawk
+ * and reuse it directly, even for something that is conceptually pass
+ * by value.
+ *
+ * 2. Due to gawk internals, after using sym_update() to install an array
+ * into gawk, you have to retrieve the array cookie from the value
+ * passed in to sym_update(). Like so:
+ *
+ * new_array = create_array();
+ * val.val_type = AWK_ARRAY;
+ * val.array_cookie = new_array;
+ * sym_update("array", & val); // install array in the symbol table
+ *
+ * new_array = val.array_cookie; // MUST DO THIS
+ *
+ * // fill in new array with lots of subscripts and values
+ *
+ * Similarly, if installing a new array as a subarray of an existing
+ * array, you must add the new array to its parent before adding any
+ * elements to it.
+ *
+ * You must also retrieve the value of the array_cookie after the call
+ * to set_element().
+ *
+ * Thus, the correct way to build an array is to work "top down".
+ * Create the array, and immediately install it in gawk's symbol table
+ * using sym_update(), or install it as an element in a previously
+ * existing array using set_element().
+ *
+ * Thus the new array must ultimately be rooted in a global symbol. This is
+ * necessary before installing any subarrays in it, due to gawk's
+ * internal implementation. Strictly speaking, this is required only
+ * for arrays that will have subarrays as elements; however it is
+ * a good idea to always do this. This restriction may be relaxed
+ * in a subsequent revision of the API.
+ */
+
+/* Allow use in C++ code. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This is used to keep extensions from modifying certain fields in some structs. */
+#ifdef GAWK
+#define awk_const
+#else
+#define awk_const const
+#endif
+
+typedef enum awk_bool {
+ awk_false = 0,
+ awk_true
+} awk_bool_t; /* we don't use <stdbool.h> on purpose */
+
+/* The information about input files that input parsers need to know: */
+typedef struct awk_input {
+ const char *name; /* filename */
+ int fd; /* file descriptor */
+#define INVALID_HANDLE (-1)
+ void *opaque; /* private data for input parsers */
+ /*
+ * The get_record function is called to read the next record of data.
+ *
+ * It should return the length of the input record or EOF, and it
+ * should set *out to point to the contents of $0. The rt_start
+ * and rt_len arguments should be used to return RT to gawk.
+ * If EOF is not returned, the parser must set *rt_len (and
+ * *rt_start if *rt_len is non-zero).
+ *
+ * Note that gawk will make a copy of the record in *out, so the
+ * parser is responsible for managing its own memory buffer.
+ * Similarly, gawk will make its own copy of RT, so the parser
+ * is also responsible for managing this memory.
+ *
+ * It is guaranteed that errcode is a valid pointer, so there is
+ * no need to test for a NULL value. Gawk sets *errcode to 0,
+ * so there is no need to set it unless an error occurs.
+ *
+ * If an error does occur, the function should return EOF and set
+ * *errcode to a positive value. In that case, if *errcode is greater
+ * than zero, gawk will automatically update the ERRNO variable based
+ * on the value of *errcode (e.g., setting *errcode = errno should do
+ * the right thing).
+ */
+ int (*get_record)(char **out, struct awk_input *iobuf, int *errcode,
+ char **rt_start, size_t *rt_len);
+
+ /*
+ * No argument prototype on read_func to allow for older systems
+ * whose headers are not up to date.
+ */
+ ssize_t (*read_func)();
+
+ /*
+ * The close_func is called to allow the parser to free private data.
+ * Gawk itself will close the fd unless close_func first sets it to
+ * INVALID_HANDLE.
+ */
+ void (*close_func)(struct awk_input *iobuf);
+
+ /* put last, for alignment. bleah */
+ struct stat sbuf; /* stat buf */
+
+} awk_input_buf_t;
+
+typedef struct awk_input_parser {
+ const char *name; /* name of parser */
+
+ /*
+ * The can_take_file function should return non-zero if the parser
+ * would like to parse this file. It should not change any gawk
+ * state!
+ */
+ awk_bool_t (*can_take_file)(const awk_input_buf_t *iobuf);
+
+ /*
+ * If this parser is selected, then take_control_of will be called.
+ * It can assume that a previous call to can_take_file was successful,
+ * and no gawk state has changed since that call. It should populate
+ * the awk_input_buf_t's get_record, close_func, and opaque values as needed.
+ * It should return non-zero if successful.
+ */
+ awk_bool_t (*take_control_of)(awk_input_buf_t *iobuf);
+
+ awk_const struct awk_input_parser *awk_const next; /* for use by gawk */
+} awk_input_parser_t;
+
+/*
+ * Similar for output wrapper.
+ */
+
+/* First the data structure */
+typedef struct awk_output_buf {
+ const char *name; /* name of output file */
+ const char *mode; /* mode argument to fopen */
+ FILE *fp; /* stdio file pointer */
+ awk_bool_t redirected; /* true if a wrapper is active */
+ void *opaque; /* for use by output wrapper */
+
+ /*
+ * Replacement functions for I/O. Just like the regular
+ * versions but also take the opaque pointer argument.
+ */
+ size_t (*gawk_fwrite)(const void *buf, size_t size, size_t count,
+ FILE *fp, void *opaque);
+ int (*gawk_fflush)(FILE *fp, void *opaque);
+ int (*gawk_ferror)(FILE *fp, void *opaque);
+ int (*gawk_fclose)(FILE *fp, void *opaque);
+} awk_output_buf_t;
+
+/* Next the output wrapper registered with gawk */
+typedef struct awk_output_wrapper {
+ const char *name; /* name of the wrapper */
+
+ /*
+ * The can_take_file function should return non-zero if the wrapper
+ * would like to process this file. It should not change any gawk
+ * state!
+ */
+ awk_bool_t (*can_take_file)(const awk_output_buf_t *outbuf);
+
+ /*
+ * If this wrapper is selected, then take_control_of will be called.
+ * It can assume that a previous call to can_take_file was successful,
+ * and no gawk state has changed since that call. It should populate
+ * the awk_output_buf_t function pointers and opaque pointer as needed.
+ * It should return non-zero if successful.
+ */
+ awk_bool_t (*take_control_of)(awk_output_buf_t *outbuf);
+
+ awk_const struct awk_output_wrapper *awk_const next; /* for use by gawk */
+} awk_output_wrapper_t;
+
+/* A two-way processor combines an input parser and an output wrapper. */
+typedef struct awk_two_way_processor {
+ const char *name; /* name of the two-way processor */
+
+ /*
+ * The can_take_file function should return non-zero if the two-way
+ * processor would like to parse this file. It should not change
+ * any gawk state!
+ */
+ awk_bool_t (*can_take_two_way)(const char *name);
+
+ /*
+ * If this processor is selected, then take_control_of will be called.
+ * It can assume that a previous call to can_take_file was successful,
+ * and no gawk state has changed since that call. It should populate
+ * the awk_input_buf_t and awk_otuput_buf_t structures as needed.
+ * It should return non-zero if successful.
+ */
+ awk_bool_t (*take_control_of)(const char *name, awk_input_buf_t *inbuf,
+ awk_output_buf_t *outbuf);
+
+ awk_const struct awk_two_way_processor *awk_const next; /* for use by gawk */
+} awk_two_way_processor_t;
+
+/* Current version of the API. */
+enum {
+ GAWK_API_MAJOR_VERSION = 1,
+ GAWK_API_MINOR_VERSION = 1
+};
+
+/* A number of typedefs related to different types of values. */
+
+/*
+ * A mutable string. Gawk owns the memory pointed to if it supplied
+ * the value. Otherwise, it takes ownership of the memory pointed to.
+ *
+ * The API deals exclusively with regular chars; these strings may
+ * be multibyte encoded in the current locale's encoding and character
+ * set. Gawk will convert internally to wide characters if necessary.
+ */
+typedef struct awk_string {
+ char *str; /* data */
+ size_t len; /* length thereof, in chars */
+} awk_string_t;
+
+/* Arrays are represented as an opaque type. */
+typedef void *awk_array_t;
+
+/* Scalars can be represented as an opaque type. */
+typedef void *awk_scalar_t;
+
+/* Any value can be stored as a cookie. */
+typedef void *awk_value_cookie_t;
+
+/*
+ * This tag defines the type of a value.
+ *
+ * Values are associated with regular variables and with array elements.
+ * Since arrays can be multidimensional (as can regular variables)
+ * it's valid to have a "value" that is actually an array.
+ */
+typedef enum {
+ AWK_UNDEFINED,
+ AWK_NUMBER,
+ AWK_STRING,
+ AWK_ARRAY,
+ AWK_SCALAR, /* opaque access to a variable */
+ AWK_VALUE_COOKIE /* for updating a previously created value */
+} awk_valtype_t;
+
+/*
+ * An awk value. The val_type tag indicates what
+ * is in the union.
+ */
+typedef struct awk_value {
+ awk_valtype_t val_type;
+ union {
+ awk_string_t s;
+ double d;
+ awk_array_t a;
+ awk_scalar_t scl;
+ awk_value_cookie_t vc;
+ } u;
+#define str_value u.s
+#define num_value u.d
+#define array_cookie u.a
+#define scalar_cookie u.scl
+#define value_cookie u.vc
+} awk_value_t;
+
+/*
+ * A "flattened" array element. Gawk produces an array of these
+ * inside the awk_flat_array_t.
+ * ALL memory pointed to belongs to gawk. Individual elements may
+ * be marked for deletion. New elements must be added individually,
+ * one at a time, using the separate API for that purpose.
+ */
+
+typedef struct awk_element {
+ /* convenience linked list pointer, not used by gawk */
+ struct awk_element *next;
+ enum {
+ AWK_ELEMENT_DEFAULT = 0, /* set by gawk */
+ AWK_ELEMENT_DELETE = 1 /* set by extension if
+ should be deleted */
+ } flags;
+ awk_value_t index; /* guaranteed to be a string! */
+ awk_value_t value;
+} awk_element_t;
+
+/*
+ * A "flattened" array. See the description above for how
+ * to use the elements contained herein.
+ */
+typedef struct awk_flat_array {
+ awk_const void *awk_const opaque1; /* private data for use by gawk */
+ awk_const void *awk_const opaque2; /* private data for use by gawk */
+ awk_const size_t count; /* how many elements */
+ awk_element_t elements[1]; /* will be extended */
+} awk_flat_array_t;
+
+/*
+ * A record describing an extension function. Upon being
+ * loaded, the extension should pass in one of these to gawk for
+ * each C function.
+ *
+ * Each called function must fill in the result with either a number
+ * or string. Gawk takes ownership of any string memory.
+ *
+ * The called function must return the value of `result'.
+ * This is for the convenience of the calling code inside gawk.
+ *
+ * Each extension function may decide what to do if the number of
+ * arguments isn't what it expected. Following awk functions, it
+ * is likely OK to ignore extra arguments.
+ */
+typedef struct awk_ext_func {
+ const char *name;
+ awk_value_t *(*function)(int num_actual_args, awk_value_t *result);
+ size_t num_expected_args;
+} awk_ext_func_t;
+
+typedef void *awk_ext_id_t; /* opaque type for extension id */
+
+/*
+ * The API into gawk. Lots of functions here. We hope that they are
+ * logically organized.
+ */
+typedef struct gawk_api {
+ /* First, data fields. */
+
+ /* These are what gawk thinks the API version is. */
+ awk_const int major_version;
+ awk_const int minor_version;
+
+ /*
+ * These can change on the fly as things happen within gawk.
+ * Currently only do_lint is prone to change, but we reserve
+ * the right to allow the others to do so also.
+ */
+#define DO_FLAGS_SIZE 6
+ awk_const int do_flags[DO_FLAGS_SIZE];
+/* Use these as indices into do_flags[] array to check the values */
+#define gawk_do_lint 0
+#define gawk_do_traditional 1
+#define gawk_do_profile 2
+#define gawk_do_sandbox 3
+#define gawk_do_debug 4
+#define gawk_do_mpfr 5
+
+ /* Next, registration functions: */
+
+ /* Add a function to the interpreter, returns true upon success */
+ awk_bool_t (*api_add_ext_func)(awk_ext_id_t id, const char *namespace,
+ const awk_ext_func_t *func);
+
+ /* Register an input parser; for opening files read-only */
+ void (*api_register_input_parser)(awk_ext_id_t id,
+ awk_input_parser_t *input_parser);
+
+ /* Register an output wrapper, for writing files */
+ void (*api_register_output_wrapper)(awk_ext_id_t id,
+ awk_output_wrapper_t *output_wrapper);
+
+ /* Register a processor for two way I/O */
+ void (*api_register_two_way_processor)(awk_ext_id_t id,
+ awk_two_way_processor_t *two_way_processor);
+
+ /*
+ * Add an exit call back.
+ *
+ * arg0 is a private data pointer for use by the extension;
+ * gawk saves it and passes it into the function pointed
+ * to by funcp at exit.
+ *
+ * Exit callback functions are called in LIFO order.
+ */
+ void (*api_awk_atexit)(awk_ext_id_t id,
+ void (*funcp)(void *data, int exit_status),
+ void *arg0);
+
+ /* Register a version string for this extension with gawk. */
+ void (*api_register_ext_version)(awk_ext_id_t id, const char *version);
+
+ /* Functions to print messages */
+ void (*api_fatal)(awk_ext_id_t id, const char *format, ...);
+ void (*api_warning)(awk_ext_id_t id, const char *format, ...);
+ void (*api_lintwarn)(awk_ext_id_t id, const char *format, ...);
+
+ /* Functions to update ERRNO */
+ void (*api_update_ERRNO_int)(awk_ext_id_t id, int errno_val);
+ void (*api_update_ERRNO_string)(awk_ext_id_t id, const char *string);
+ void (*api_unset_ERRNO)(awk_ext_id_t id);
+
+ /*
+ * All of the functions that return a value from inside gawk
+ * (get a parameter, get a global variable, get an array element)
+ * behave in the same way.
+ *
+ * For a function parameter, the return is false if the argument
+ * count is out of range, or if actual paramater does not match
+ * what is specified in wanted. In that case, result->val_type
+ * will hold the actual type of what was passed.
+ *
+ * Similarly for symbol table access to variables and array elements,
+ * the return is false if the actual variable or array element does
+ * not match what was requested, and the result->val_type will hold
+ * the actual type.
+
+ Table entry is type returned:
+
+
+ +-------------------------------------------------+
+ | Type of Actual Value: |
+ +------------+------------+-----------+-----------+
+ | String | Number | Array | Undefined |
+ +-----------+-----------+------------+------------+-----------+-----------+
+ | | String | String | String | false | false |
+ | |-----------+------------+------------+-----------+-----------+
+ | | Number | Number if | Number | false | false |
+ | | | can be | | | |
+ | | | converted, | | | |
+ | | | else false | | | |
+ | |-----------+------------+------------+-----------+-----------+
+ | Type | Array | false | false | Array | false |
+ | Requested |-----------+------------+------------+-----------+-----------+
+ | | Scalar | Scalar | Scalar | false | false |
+ | |-----------+------------+------------+-----------+-----------+
+ | | Undefined | String | Number | Array | Undefined |
+ | |-----------+------------+------------+-----------+-----------+
+ | | Value | false | false | false | false |
+ | | Cookie | | | | |
+ +-----------+-----------+------------+------------+-----------+-----------+
+ */
+
+ /* Functions to handle parameters passed to the extension. */
+
+ /*
+ * Get the count'th paramater, zero-based.
+ * Returns false if count is out of range, or if actual paramater
+ * does not match what is specified in wanted. In that case,
+ * result->val_type is as described above.
+ */
+ awk_bool_t (*api_get_argument)(awk_ext_id_t id, size_t count,
+ awk_valtype_t wanted,
+ awk_value_t *result);
+
+ /*
+ * Convert a paramter that was undefined into an array
+ * (provide call-by-reference for arrays). Returns false
+ * if count is too big, or if the argument's type is
+ * not undefined.
+ */
+ awk_bool_t (*api_set_argument)(awk_ext_id_t id,
+ size_t count,
+ awk_array_t array);
+
+ /*
+ * Symbol table access:
+ * - Read-only access to special variables (NF, etc.)
+ * - One special exception: PROCINFO.
+ * - Use sym_update() to change a value, including from UNDEFINED
+ * to scalar or array.
+ */
+ /*
+ * Lookup a variable, fill in value. No messing with the value
+ * returned.
+ * Returns false if the variable doesn't exist* or if the wrong type
+ * was requested. In the latter case, vaule->val_type will have
+ * the real type, as described above.
+ *
+ * awk_value_t val;
+ * if (! api->sym_lookup(id, name, wanted, & val))
+ * error_code_here();
+ * else {
+ * // safe to use val
+ * }
+ */
+ awk_bool_t (*api_sym_lookup)(awk_ext_id_t id,
+ const char *name,
+ awk_valtype_t wanted,
+ awk_value_t *result);
+
+ /*
+ * Update a value. Adds it to the symbol table if not there.
+ * Changing types (scalar <--> array) is not allowed.
+ * In fact, using this to update an array is not allowed, either.
+ * Such an attempt returns false.
+ */
+ awk_bool_t (*api_sym_update)(awk_ext_id_t id,
+ const char *name,
+ awk_value_t *value);
+
+ /*
+ * A ``scalar cookie'' is an opaque handle that provide access
+ * to a global variable or array. It is an optimization that
+ * avoids looking up variables in gawk's symbol table every time
+ * access is needed.
+ *
+ * This function retrieves the current value of a scalar cookie.
+ * Once you have obtained a scalar_cookie using sym_lookup, you can
+ * use this function to get its value more efficiently.
+ *
+ * Return will be false if the value cannot be retrieved.
+ *
+ * Flow is thus
+ * awk_value_t val;
+ * awk_scalar_t cookie;
+ * api->sym_lookup(id, "variable", AWK_SCALAR, & val); // get the cookie
+ * cookie = val.scalar_cookie;
+ * ...
+ * api->sym_lookup_scalar(id, cookie, wanted, & val); // get the value
+ */
+ awk_bool_t (*api_sym_lookup_scalar)(awk_ext_id_t id,
+ awk_scalar_t cookie,
+ awk_valtype_t wanted,
+ awk_value_t *result);
+
+ /*
+ * Update the value associated with a scalar cookie.
+ * Flow is
+ * sym_lookup with wanted == AWK_SCALAR
+ * if returns false
+ * sym_update with real initial value to install it
+ * sym_lookup again with AWK_SCALAR
+ * else
+ * use the scalar cookie
+ *
+ * Return will be false if the new value is not one of
+ * AWK_STRING or AWK_NUMBER.
+ *
+ * Here too, the built-in variables may not be updated.
+ */
+ awk_bool_t (*api_sym_update_scalar)(awk_ext_id_t id,
+ awk_scalar_t cookie, awk_value_t *value);
+
+ /* Cached values */
+
+ /*
+ * Create a cached string or numeric value for efficient later
+ * assignment. This improves performance when you want to assign
+ * the same value to one or more variables repeatedly. Only
+ * AWK_NUMBER and AWK_STRING values are allowed. Any other type
+ * is rejected. We disallow AWK_UNDEFINED since that case would
+ * result in inferior performance.
+ */
+ awk_bool_t (*api_create_value)(awk_ext_id_t id, awk_value_t *value,
+ awk_value_cookie_t *result);
+
+ /*
+ * Release the memory associated with a cookie from api_create_value.
+ * Please call this to free memory when the value is no longer needed.
+ */
+ awk_bool_t (*api_release_value)(awk_ext_id_t id, awk_value_cookie_t vc);
+
+ /* Array management */
+
+ /*
+ * Retrieve total number of elements in array.
+ * Returns false if some kind of error.
+ */
+ awk_bool_t (*api_get_element_count)(awk_ext_id_t id,
+ awk_array_t a_cookie, size_t *count);
+
+ /*
+ * Return the value of an element - read only!
+ * Use set_array_element() to change it.
+ * Behavior for value and return is same as for api_get_argument
+ * and sym_lookup.
+ */
+ awk_bool_t (*api_get_array_element)(awk_ext_id_t id,
+ awk_array_t a_cookie,
+ const awk_value_t *const index,
+ awk_valtype_t wanted,
+ awk_value_t *result);
+
+ /*
+ * Change (or create) element in existing array with
+ * index and value.
+ *
+ * ARGV and ENVIRON may not be updated.
+ */
+ awk_bool_t (*api_set_array_element)(awk_ext_id_t id, awk_array_t a_cookie,
+ const awk_value_t *const index,
+ const awk_value_t *const value);
+
+ /*
+ * Remove the element with the given index.
+ * Returns success if removed or false if element did not exist.
+ */
+ awk_bool_t (*api_del_array_element)(awk_ext_id_t id,
+ awk_array_t a_cookie, const awk_value_t* const index);
+
+ /* Create a new array cookie to which elements may be added */
+ awk_array_t (*api_create_array)(awk_ext_id_t id);
+
+ /* Clear out an array */
+ awk_bool_t (*api_clear_array)(awk_ext_id_t id, awk_array_t a_cookie);
+
+ /* Flatten out an array so that it can be looped over easily. */
+ awk_bool_t (*api_flatten_array)(awk_ext_id_t id,
+ awk_array_t a_cookie,
+ awk_flat_array_t **data);
+
+ /* When done, delete any marked elements, release the memory. */
+ awk_bool_t (*api_release_flattened_array)(awk_ext_id_t id,
+ awk_array_t a_cookie,
+ awk_flat_array_t *data);
+
+ /*
+ * Hooks to provide access to gawk's memory allocation functions.
+ * This ensures that memory passed between gawk and the extension
+ * is allocated and released by the same library.
+ */
+ void *(*api_malloc)(size_t size);
+ void *(*api_calloc)(size_t nmemb, size_t size);
+ void *(*api_realloc)(void *ptr, size_t size);
+ void (*api_free)(void *ptr);
+} gawk_api_t;
+
+#ifndef GAWK /* these are not for the gawk code itself! */
+/*
+ * Use these if you want to define "global" variables named api
+ * and ext_id to make the code a little easier to read.
+ * See the sample boilerplate code, below.
+ */
+#define do_lint (api->do_flags[gawk_do_lint])
+#define do_traditional (api->do_flags[gawk_do_traditional])
+#define do_profile (api->do_flags[gawk_do_profile])
+#define do_sandbox (api->do_flags[gawk_do_sandbox])
+#define do_debug (api->do_flags[gawk_do_debug])
+#define do_mpfr (api->do_flags[gawk_do_mpfr])
+
+#define get_argument(count, wanted, result) \
+ (api->api_get_argument(ext_id, count, wanted, result))
+#define set_argument(count, new_array) \
+ (api->api_set_argument(ext_id, count, new_array))
+
+#define fatal api->api_fatal
+#define warning api->api_warning
+#define lintwarn api->api_lintwarn
+
+#define register_input_parser(parser) (api->api_register_input_parser(ext_id, parser))
+#define register_output_wrapper(wrapper) (api->api_register_output_wrapper(ext_id, wrapper))
+#define register_two_way_processor(processor) \
+ (api->api_register_two_way_processor(ext_id, processor))
+
+#define update_ERRNO_int(e) (api->api_update_ERRNO_int(ext_id, e))
+#define update_ERRNO_string(str) \
+ (api->api_update_ERRNO_string(ext_id, str))
+#define unset_ERRNO() (api->api_unset_ERRNO(ext_id))
+
+#define add_ext_func(ns, func) (api->api_add_ext_func(ext_id, ns, func))
+#define awk_atexit(funcp, arg0) (api->api_awk_atexit(ext_id, funcp, arg0))
+
+#define sym_lookup(name, wanted, result) \
+ (api->api_sym_lookup(ext_id, name, wanted, result))
+#define sym_lookup_scalar(scalar_cookie, wanted, result) \
+ (api->api_sym_lookup_scalar(ext_id, scalar_cookie, wanted, result))
+#define sym_update(name, value) \
+ (api->api_sym_update(ext_id, name, value))
+#define sym_update_scalar(scalar_cookie, value) \
+ (api->api_sym_update_scalar)(ext_id, scalar_cookie, value)
+
+#define get_array_element(array, index, wanted, result) \
+ (api->api_get_array_element(ext_id, array, index, wanted, result))
+
+#define set_array_element(array, index, value) \
+ (api->api_set_array_element(ext_id, array, index, value))
+
+#define set_array_element_by_elem(array, elem) \
+ (api->api_set_array_element(ext_id, array, & (elem)->index, & (elem)->value))
+
+#define del_array_element(array, index) \
+ (api->api_del_array_element(ext_id, array, index))
+
+#define get_element_count(array, count_p) \
+ (api->api_get_element_count(ext_id, array, count_p))
+
+#define create_array() (api->api_create_array(ext_id))
+
+#define clear_array(array) (api->api_clear_array(ext_id, array))
+
+#define flatten_array(array, data) \
+ (api->api_flatten_array(ext_id, array, data))
+
+#define release_flattened_array(array, data) \
+ (api->api_release_flattened_array(ext_id, array, data))
+
+#define gawk_malloc(size) (api->api_malloc(size))
+#define gawk_calloc(nmemb, size) (api->api_calloc(nmemb, size))
+#define gawk_realloc(ptr, size) (api->api_realloc(ptr, size))
+#define gawk_free(ptr) (api->api_free(ptr))
+
+#define create_value(value, result) \
+ (api->api_create_value(ext_id, value,result))
+
+#define release_value(value) \
+ (api->api_release_value(ext_id, value))
+
+#define register_ext_version(version) \
+ (api->api_register_ext_version(ext_id, version))
+
+#define emalloc(pointer, type, size, message) \
+ do { \
+ if ((pointer = (type) gawk_malloc(size)) == 0) \
+ fatal(ext_id, "%s: malloc of %d bytes failed\n", message, size); \
+ } while(0)
+
+#define erealloc(pointer, type, size, message) \
+ do { \
+ if ((pointer = (type) gawk_realloc(pointer, size)) == 0) \
+ fatal(ext_id, "%s: realloc of %d bytes failed\n", message, size); \
+ } while(0)
+
+/* Constructor functions */
+
+/* r_make_string --- make a string value in result from the passed-in string */
+
+static inline awk_value_t *
+r_make_string(const gawk_api_t *api, /* needed for emalloc */
+ awk_ext_id_t *ext_id, /* ditto */
+ const char *string,
+ size_t length,
+ awk_bool_t duplicate,
+ awk_value_t *result)
+{
+ char *cp = NULL;
+
+ memset(result, 0, sizeof(*result));
+
+ result->val_type = AWK_STRING;
+ result->str_value.len = length;
+
+ if (duplicate) {
+ emalloc(cp, char *, length + 2, "r_make_string");
+ memcpy(cp, string, length);
+ cp[length] = '\0';
+ result->str_value.str = cp;
+ } else {
+ result->str_value.str = (char *) string;
+ }
+
+ return result;
+}
+
+#define make_const_string(str, len, result) r_make_string(api, ext_id, str, len, 1, result)
+#define make_malloced_string(str, len, result) r_make_string(api, ext_id, str, len, 0, result)
+
+/* make_null_string --- make a null string value */
+
+static inline awk_value_t *
+make_null_string(awk_value_t *result)
+{
+ memset(result, 0, sizeof(*result));
+ result->val_type = AWK_UNDEFINED;
+
+ return result;
+}
+
+/* make_number --- make a number value in result */
+
+static inline awk_value_t *
+make_number(double num, awk_value_t *result)
+{
+ memset(result, 0, sizeof(*result));
+
+ result->val_type = AWK_NUMBER;
+ result->num_value = num;
+
+ return result;
+}
+
+/*
+ * Each extension must define a function with this prototype:
+ *
+ * int dl_load(gawk_api_t *api_p, awk_ext_id_t id)
+ *
+ * The return value should be zero on failure and non-zero on success.
+ *
+ * For the macros to work, the function should save api_p in a global
+ * variable named 'api' and save id in a global variable named 'ext_id'.
+ * In addition, a global function pointer named 'init_func' should be
+ * defined and set to either NULL or an initialization function that
+ * returns non-zero on success and zero upon failure.
+ */
+
+extern int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id);
+
+#if 0
+/* Boiler plate code: */
+int plugin_is_GPL_compatible;
+
+static gawk_api_t *const api;
+static awk_ext_id_t ext_id;
+static const char *ext_version = NULL; /* or ... = "some string" */
+
+static awk_ext_func_t func_table[] = {
+ { "name", do_name, 1 },
+ /* ... */
+};
+
+/* EITHER: */
+
+static awk_bool_t (*init_func)(void) = NULL;
+
+/* OR: */
+
+static awk_bool_t
+init_my_extension(void)
+{
+ ...
+}
+
+static awk_bool_t (*init_func)(void) = init_my_extension;
+
+dl_load_func(func_table, some_name, "name_space_in_quotes")
+#endif
+
+#define dl_load_func(func_table, extension, name_space) \
+int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) \
+{ \
+ size_t i, j; \
+ int errors = 0; \
+\
+ api = api_p; \
+ ext_id = id; \
+\
+ if (api->major_version != GAWK_API_MAJOR_VERSION \
+ || api->minor_version < GAWK_API_MINOR_VERSION) { \
+ fprintf(stderr, #extension ": version mismatch with gawk!\n"); \
+ fprintf(stderr, "\tmy version (%d, %d), gawk version (%d, %d)\n", \
+ GAWK_API_MAJOR_VERSION, GAWK_API_MINOR_VERSION, \
+ api->major_version, api->minor_version); \
+ exit(1); \
+ } \
+\
+ /* load functions */ \
+ for (i = 0, j = sizeof(func_table) / sizeof(func_table[0]); i < j; i++) { \
+ if (func_table[i].name == NULL) \
+ break; \
+ if (! add_ext_func(name_space, & func_table[i])) { \
+ warning(ext_id, #extension ": could not add %s\n", \
+ func_table[i].name); \
+ errors++; \
+ } \
+ } \
+\
+ if (init_func != NULL) { \
+ if (! init_func()) { \
+ warning(ext_id, #extension ": initialization function failed\n"); \
+ errors++; \
+ } \
+ } \
+\
+ if (ext_version != NULL) \
+ register_ext_version(ext_version); \
+\
+ return (errors == 0); \
+}
+
+#endif /* GAWK */
+
+#ifdef __cplusplus
+}
+#endif /* C++ */
+
+#endif /* _GAWK_API_H */
diff --git a/gawkmisc.c b/gawkmisc.c
index a729d88d..0172a810 100644
--- a/gawkmisc.c
+++ b/gawkmisc.c
@@ -52,6 +52,8 @@ pointer
xmalloc(size_t bytes)
{
pointer p;
+ if (bytes == 0)
+ bytes = 1; /* avoid dfa.c mishegos */
emalloc(p, pointer, bytes, "xmalloc");
return p;
}
diff --git a/getopt.c b/getopt.c
index 6521f48e..4de0b9a0 100644
--- a/getopt.c
+++ b/getopt.c
@@ -2,8 +2,7 @@
NOTE: getopt is 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-1996,1998-2004,2008,2009,2010
- Free Software Foundation, Inc.
+ Copyright (C) 1987-2015 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
@@ -17,9 +16,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
Ditto for AIX 3.2 and <stdlib.h>. */
@@ -49,14 +47,23 @@
# endif
#endif
+/* !@#$%^&*() !!!!!!!! */
+#ifdef GAWK
+#undef ELIDE_CODE
+#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. */
+#if defined (__GNU_LIBRARY__) || defined (__CYGWIN__) || defined(__DJGPP__) || defined(__APPLE__) || defined(__MINGW32__) || defined(__sun) /* Illumos */
+/* Don't include stdlib.h for
+ * non-GNU C libraries
+ * non-Cygwin
+ * non-DJGPP
+ * non-MinGW
+ * because some of them contain conflicting prototypes for getopt. */
# include <stdlib.h>
# include <unistd.h>
#endif /* GNU C library. */
@@ -74,7 +81,7 @@
# define _(msgid) gettext (msgid)
#endif
-#if defined _LIBC && defined USE_IN_LIBIO
+#if defined _LIBC
# include <wchar.h>
#endif
@@ -229,7 +236,7 @@ exchange (char **argv, struct _getopt_data *d)
{
/* Bottom segment is the short one. */
int len = middle - bottom;
- register int i;
+ int i;
/* Swap it with the top part of the top segment. */
for (i = 0; i < len; i++)
@@ -246,7 +253,7 @@ exchange (char **argv, struct _getopt_data *d)
{
/* Top segment is the short one. */
int len = top - middle;
- register int i;
+ int i;
/* Swap it with the bottom part of the bottom segment. */
for (i = 0; i < len; i++)
@@ -526,23 +533,29 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
|| !strchr (optstring, argv[d->optind][1])))))
{
char *nameend;
+ unsigned int namelen;
const struct option *p;
const struct option *pfound = NULL;
+ struct option_list
+ {
+ const struct option *p;
+ struct option_list *next;
+ int needs_free;
+ } *ambig_list = NULL;
int exact = 0;
- int ambig = 0;
int indfound = -1;
int option_index;
for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
/* Do nothing. */ ;
+ namelen = nameend - d->__nextchar;
/* 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 (!strncmp (p->name, d->__nextchar, namelen))
{
- if ((unsigned int) (nameend - d->__nextchar)
- == (unsigned int) strlen (p->name))
+ if (namelen == (unsigned int) strlen (p->name))
{
/* Exact match found. */
pfound = p;
@@ -560,35 +573,78 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
|| pfound->has_arg != p->has_arg
|| pfound->flag != p->flag
|| pfound->val != p->val)
- /* Second or later nonexact match found. */
- ambig = 1;
+ {
+ /* Second or later nonexact match found. */
+ struct option_list *newp = malloc (sizeof (*newp));
+ newp->p = p;
+ newp->needs_free = 1;
+ newp->next = ambig_list;
+ ambig_list = newp;
+ }
}
- if (ambig && !exact)
+ if (ambig_list != NULL && !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)
+ struct option_list first;
+ first.p = pfound;
+ first.next = ambig_list;
+ first.needs_free = 0;
+ ambig_list = &first;
+
+#if defined _LIBC
+ char *buf = NULL;
+ size_t buflen = 0;
+
+ FILE *fp = open_memstream (&buf, &buflen);
+ if (fp != NULL)
{
- _IO_flockfile (stderr);
+ fprintf (fp,
+ _("%s: option '%s' is ambiguous; possibilities:"),
+ argv[0], argv[d->optind]);
- int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
- ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+ do
+ {
+ fprintf (fp, " '--%s'", ambig_list->p->name);
+ ambig_list = ambig_list->next;
+ }
+ while (ambig_list != NULL);
- __fxprintf (NULL, "%s", buf);
+ fputc_unlocked ('\n', fp);
- ((_IO_FILE *) stderr)->_flags2 = old_flags2;
- _IO_funlockfile (stderr);
+ if (__glibc_likely (fclose (fp) != EOF))
+ {
+ _IO_flockfile (stderr);
- free (buf);
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+ __fxprintf (NULL, "%s", buf);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
}
#else
- fprintf (stderr, _("%s: option '%s' is ambiguous\n"),
+ fprintf (stderr,
+ _("%s: option '%s' is ambiguous; possibilities:"),
argv[0], argv[d->optind]);
+ do
+ {
+ struct option_list *tmp_next;
+
+ fprintf (stderr, " '--%s'", ambig_list->p->name);
+ tmp_next = ambig_list->next;
+ if (ambig_list->needs_free)
+ free(ambig_list);
+ ambig_list = tmp_next;
+ }
+ while (ambig_list != NULL);
+
+ fputc ('\n', stderr);
#endif
}
d->__nextchar += strlen (d->__nextchar);
@@ -611,7 +667,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
{
if (print_errors)
{
-#if defined _LIBC && defined USE_IN_LIBIO
+#if defined _LIBC
char *buf;
int n;
#endif
@@ -619,7 +675,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
if (argv[d->optind - 1][1] == '-')
{
/* --option */
-#if defined _LIBC && defined USE_IN_LIBIO
+#if defined _LIBC
n = __asprintf (&buf, _("\
%s: option '--%s' doesn't allow an argument\n"),
argv[0], pfound->name);
@@ -632,7 +688,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
else
{
/* +option or -option */
-#if defined _LIBC && defined USE_IN_LIBIO
+#if defined _LIBC
n = __asprintf (&buf, _("\
%s: option '%c%s' doesn't allow an argument\n"),
argv[0], argv[d->optind - 1][0],
@@ -645,7 +701,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
#endif
}
-#if defined _LIBC && defined USE_IN_LIBIO
+#if defined _LIBC
if (n >= 0)
{
_IO_flockfile (stderr);
@@ -678,7 +734,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
{
if (print_errors)
{
-#if defined _LIBC && defined USE_IN_LIBIO
+#if defined _LIBC
char *buf;
if (__asprintf (&buf, _("\
@@ -729,7 +785,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
{
if (print_errors)
{
-#if defined _LIBC && defined USE_IN_LIBIO
+#if defined _LIBC
char *buf;
int n;
#endif
@@ -737,7 +793,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
if (argv[d->optind][1] == '-')
{
/* --option */
-#if defined _LIBC && defined USE_IN_LIBIO
+#if defined _LIBC
n = __asprintf (&buf, _("%s: unrecognized option '--%s'\n"),
argv[0], d->__nextchar);
#else
@@ -748,7 +804,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
else
{
/* +option or -option */
-#if defined _LIBC && defined USE_IN_LIBIO
+#if defined _LIBC
n = __asprintf (&buf, _("%s: unrecognized option '%c%s'\n"),
argv[0], argv[d->optind][0], d->__nextchar);
#else
@@ -757,7 +813,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
#endif
}
-#if defined _LIBC && defined USE_IN_LIBIO
+#if defined _LIBC
if (n >= 0)
{
_IO_flockfile (stderr);
@@ -795,19 +851,19 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
{
if (print_errors)
{
-#if defined _LIBC && defined USE_IN_LIBIO
+#if defined _LIBC
char *buf;
int n;
#endif
-#if defined _LIBC && defined USE_IN_LIBIO
+#if defined _LIBC
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 defined _LIBC
if (n >= 0)
{
_IO_flockfile (stderr);
@@ -838,6 +894,9 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
int indfound = 0;
int option_index;
+ if (longopts == NULL)
+ goto no_longs;
+
/* This is an option that requires an argument. */
if (*d->__nextchar != '\0')
{
@@ -850,7 +909,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
{
if (print_errors)
{
-#if defined _LIBC && defined USE_IN_LIBIO
+#if defined _LIBC
char *buf;
if (__asprintf (&buf,
@@ -924,7 +983,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
{
if (print_errors)
{
-#if defined _LIBC && defined USE_IN_LIBIO
+#if defined _LIBC
char *buf;
if (__asprintf (&buf, _("%s: option '-W %s' is ambiguous\n"),
@@ -964,7 +1023,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
{
if (print_errors)
{
-#if defined _LIBC && defined USE_IN_LIBIO
+#if defined _LIBC
char *buf;
if (__asprintf (&buf, _("\
@@ -1003,7 +1062,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
{
if (print_errors)
{
-#if defined _LIBC && defined USE_IN_LIBIO
+#if defined _LIBC
char *buf;
if (__asprintf (&buf, _("\
@@ -1045,8 +1104,10 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
}
return pfound->val;
}
- d->__nextchar = NULL;
- return 'W'; /* Let the application handle it. */
+
+ no_longs:
+ d->__nextchar = NULL;
+ return 'W'; /* Let the application handle it. */
}
if (temp[1] == ':')
{
@@ -1076,7 +1137,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
{
if (print_errors)
{
-#if defined _LIBC && defined USE_IN_LIBIO
+#if defined _LIBC
char *buf;
if (__asprintf (&buf, _("\
diff --git a/getopt.h b/getopt.h
index b84953f7..75cd5e8d 100644
--- a/getopt.h
+++ b/getopt.h
@@ -1,6 +1,5 @@
/* Declarations for getopt.
- Copyright (C) 1989-1994,1996-1999,2001,2003,2004
- Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 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
@@ -14,9 +13,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _GETOPT_H
@@ -50,6 +48,21 @@
extern "C" {
#endif
+#ifdef __KLIBC__
+/* OS/2 kLIBC has already getopt(). So to avoid name clash, rename
+ them here. */
+
+# define optarg gawk_optarg
+# define optind gawk_optind
+# define opterr gawk_opterr
+# define optopt gawk_optopt
+
+# define getopt gawk_getopt
+# define getopt_long gawk_getopt_long
+# define getopt_long_only gawk_getopt_long_only
+#endif
+
+
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
@@ -158,9 +171,9 @@ extern int getopt (int ___argc, char *const *___argv, const char *__shortopts)
additional functionality can be disable at runtime. This redirection
helps to also do this at runtime. */
# ifdef __REDIRECT
- extern int __REDIRECT (getopt, (int ___argc, char *const *___argv,
- const char *__shortopts),
- __posix_getopt) __THROW;
+ extern int __REDIRECT_NTH (getopt, (int ___argc, char *const *___argv,
+ const char *__shortopts),
+ __posix_getopt);
# else
extern int __posix_getopt (int ___argc, char *const *___argv,
const char *__shortopts) __THROW;
diff --git a/getopt1.c b/getopt1.c
index 95f2fb35..b61041db 100644
--- a/getopt1.c
+++ b/getopt1.c
@@ -1,5 +1,5 @@
/* getopt_long and getopt_long_only entry points for GNU getopt.
- Copyright (C) 1987-1994,1996-1998,2004,2009 Free Software Foundation, Inc.
+ Copyright (C) 1987-2015 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
@@ -13,9 +13,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -46,6 +45,11 @@
#endif
#endif
+/* !@#$%^&*() !!!!!!!! */
+#ifdef GAWK
+#undef ELIDE_CODE
+#endif
+
#ifndef ELIDE_CODE
diff --git a/getopt_int.h b/getopt_int.h
index 6a32a514..03d62277 100644
--- a/getopt_int.h
+++ b/getopt_int.h
@@ -1,6 +1,5 @@
/* Internal declarations for getopt.
- Copyright (C) 1989-1994,1996-1999,2001,2003,2004,2009
- Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 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
@@ -14,9 +13,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _GETOPT_INT_H
#define _GETOPT_INT_H 1
diff --git a/gettext.h b/gettext.h
index 0c1a50e8..38b94c49 100644
--- a/gettext.h
+++ b/gettext.h
@@ -1,20 +1,18 @@
/* Convenience header for conditional use of GNU <libintl.h>.
- Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009 Free Software Foundation, Inc.
+ Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2013 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 3, or (at your option)
- any later version.
+ 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 3 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
- Library General Public License for more details.
+ 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. */
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef _LIBGETTEXT_H
#define _LIBGETTEXT_H 1
@@ -62,7 +60,7 @@
it now, to make later inclusions of <libintl.h> a NOP. */
#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
# include <cstdlib>
-# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
+# if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H
# include <libintl.h>
# endif
#endif
@@ -90,7 +88,7 @@
((void) (Domainname), ngettext (Msgid1, Msgid2, N))
# undef dcngettext
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
- ((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N))
+ ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N))
# undef textdomain
# define textdomain(Domainname) ((const char *) (Domainname))
# undef bindtextdomain
@@ -102,6 +100,12 @@
#endif
+/* Prefer gnulib's setlocale override over libintl's setlocale override. */
+#ifdef GNULIB_defined_setlocale
+# undef setlocale
+# define setlocale rpl_setlocale
+#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.
@@ -187,9 +191,12 @@ npgettext_aux (const char *domain,
#include <string.h>
-#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
- (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
- /* || __STDC_VERSION__ >= 199901L */ )
+#if (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \
+ /* || __STDC_VERSION__ >= 199901L */ )
+# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1
+#else
+# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0
+#endif
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
#include <stdlib.h>
diff --git a/helpers/ChangeLog b/helpers/ChangeLog
new file mode 100644
index 00000000..a5bbafb1
--- /dev/null
+++ b/helpers/ChangeLog
@@ -0,0 +1,41 @@
+2014-09-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * chlistref.awk: New file. Finds @ref{} to non-chapters.
+
+2014-06-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testdfa.c: Minor improvements.
+
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.1: Release tar ball made.
+
+2014-03-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * quoteconvert2.sh: Use .UTF-8 locales per request from
+ Michal Jaegermann.
+
+2014-03-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * quoteconvert2.sh, tryfmt.c, scanfmt.c: New files.
+
+2013-12-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testdfa.c: Fix some bugs and compiler warnings.
+
+2013-12-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * do.outline: New file.
+
+2013-06-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * ChangeLog: Created.
+ * testdfa.c: Add ifdef around xalloc.h, for use with grep dfa.
+
+2013-06-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testdfa.c: New file.
+
+2013-06-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testnet.awk, testnet.c, fixdump.awk: New files.
diff --git a/helpers/chlistref.awk b/helpers/chlistref.awk
new file mode 100644
index 00000000..49f63f59
--- /dev/null
+++ b/helpers/chlistref.awk
@@ -0,0 +1,31 @@
+BEGIN {
+ chapters["Getting Started"]++
+ chapters["Invoking Gawk"]++
+ chapters["Regexp"]++
+ chapters["Reading Files"]++
+ chapters["Printing"]++
+ chapters["Expressions"]++
+ chapters["Patterns and Actions"]++
+ chapters["Arrays"]++
+ chapters["Functions"]++
+ chapters["Library Functions"]++
+ chapters["Sample Programs"]++
+ chapters["Advanced Features"]++
+ chapters["Internationalization"]++
+ chapters["Debugger"]++
+ chapters["Arbitrary Precision Arithmetic"]++
+ chapters["Dynamic Extensions"]++
+ chapters["Language History"]++
+ chapters["Installation"]++
+ chapters["Notes"]++
+ chapters["Basic Concepts"]++
+
+ Pattern = ".*@ref\\{([^}]+)\\},.*"
+}
+
+$0 ~ Pattern {
+ ref = gensub(Pattern, "\\1", 1, $0)
+ if (! (ref in chapters))
+ printf("%s:%d: %s\n", FILENAME, FNR, $0)
+}
+
diff --git a/helpers/do.outline b/helpers/do.outline
new file mode 100755
index 00000000..203d27ad
--- /dev/null
+++ b/helpers/do.outline
@@ -0,0 +1,102 @@
+#! /usr/local/bin2/gawk -f
+
+# do.outline --- produce an outline of a texinfo document
+
+BEGIN {
+ # manifest constants
+ TRUE = 1
+ FALSE = 0
+
+ # Levels at which different nodes can be
+ Level["@top"] = 0
+ Level["@appendix"] = 1
+ Level["@chapter"] = 1
+ Level["@majorheading"] = 1
+ Level["@unnumbered"] = 1
+ Level["@preface"] = 1
+ Level["@appendixsec"] = 2
+ Level["@heading"] = 2
+ Level["@section"] = 2
+ Level["@unnumberedsec"] = 2
+ Level["@unnumberedsubsec"] = 3
+ Level["@appendixsubsec"] = 3
+ Level["@subheading"] = 3
+ Level["@subsection"] = 3
+ Level["@appendixsubsubsec"] = 4
+ Level["@subsubheading"] = 4
+ Level["@subsubsection"] = 4
+ Level["@unnumberedsubsubsec"] = 4
+
+ ah = bh = ch = 0
+
+ appendix = 0
+}
+
+/^@ignore/ && Pass == 1, /^@end[ \t]+ignore/ && Pass == 1 {
+ next
+}
+
+
+$1 in Level {
+ # save type
+ type = $1
+
+ lev = Level[$1]
+
+ if (lev == 1 && tolower($0) !~ /preface|foreword/) {
+ if ($1 == "@appendix") {
+ appendix = next_appendix(appendix)
+ ah = appendix
+ } else
+ ah++
+ bh = ch = dh = 0
+ } else if (lev == 2) {
+ bh++
+ ch = dh = 0
+ } else if (lev == 3) {
+ ch++
+ dh = 0
+ } else if (lev == 4)
+ dh++
+
+ Unnumbered = ($1 ~ /^@unnumbered/)
+
+ $1 = ""
+ $0 = preprocess($0)
+
+ for (i = 1; i < lev; i++)
+ printf "\t"
+
+ if (! Unnumbered) {
+ printf("%s.", ah)
+ if (bh)
+ printf("%d.", bh)
+ if (ch)
+ printf("%d.", ch)
+ if (dh)
+ printf("%d.", dh)
+ }
+
+ printf("%s\n", $0)
+}
+
+function preprocess(record)
+{
+ record = gensub(/@(code|command|samp|env)\{([^\}]+)\}/, "\\2", "g", record)
+ record = gensub(/@dots\{\}/, "...", "g", record)
+
+ return record
+}
+
+function next_appendix(cur, ind, letters)
+{
+ if (cur == 0)
+ return "A" # first time
+
+ letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ ind = index(letters, cur)
+ if (ind > 0 && ind <= 26)
+ return substr(letters, ++ind, 1)
+
+ return "Z"
+}
diff --git a/helpers/fixdump.awk b/helpers/fixdump.awk
new file mode 100644
index 00000000..b03f03f7
--- /dev/null
+++ b/helpers/fixdump.awk
@@ -0,0 +1,69 @@
+#! /usr/bin/gawk -f
+
+BEGIN {
+ address_re = "0x[[:xdigit:]]+"
+ bracketed_address = "\\[(([[:space:]]*[[:digit:]]*:)?|[[:alpha:]_]+ = )0x[[:xdigit:]]+\\]"
+}
+
+{
+ line[NR] = $0
+ extract_addresses($0, NR)
+}
+
+END {
+ for (i = 1; i <= NR; i++) {
+ if (line[i] !~ address_re) {
+ print line[i]
+ continue
+ }
+
+ translate(line[i])
+ }
+}
+
+# Global arrays
+#
+# Address[line] --- Address of instruction - first hex number
+# Target[address] = 1 --- Address is target of a jump
+# Newaddr[address] --- Replacement address, counting from 1
+
+function extract_addresses(line, num, data, i, n, seps, addr)
+{
+ if (line !~ address_re)
+ return
+
+ split(line, data, bracketed_address, seps)
+ n = length(seps)
+
+ for (i = 1; i <= n; i++) {
+ addr = gensub(".*(" address_re ").*", "\\1", 1, seps[i])
+ if (i == 1)
+ Address[num] = addr
+ else {
+ Target[addr]++
+ if (! (addr in Newaddr))
+ Newaddr[addr] = new_address()
+ }
+ }
+}
+
+function new_address()
+{
+ return sprintf("%8d", ++Address_seed)
+}
+
+function translate(line, n, data, seps, i, newline)
+{
+ split(line, data, address_re, seps)
+ n = length(seps)
+ newline = line
+ for (i = 1; i <= n; i++) {
+ if (! (seps[i] in Target)) {
+ gsub(seps[i], " ", newline)
+ continue
+ }
+ gsub(seps[i], Newaddr[seps[i]], newline)
+ }
+
+ print newline
+}
diff --git a/helpers/quoteconvert2.sh b/helpers/quoteconvert2.sh
new file mode 100755
index 00000000..63750a37
--- /dev/null
+++ b/helpers/quoteconvert2.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+# quoteconvert2.sh --- test locale dependent output of numbers
+# Michal Jaegermann, michal@harddata.com, 2014/Mar/1
+
+#AWK="../gawk"
+SCRIPT=`basename $0`
+
+if [ "$AWK" = "" ]
+then
+ echo $0: You must set AWK >&2
+ exit 1
+fi
+
+# The last entry on this list represents "a locale with a typo".
+
+llist="
+C
+en_US
+en_US.UTF-8
+de_DE
+de_DE.UTF-8
+fr_FR
+fr_FR.UTF-8
+pt_PT
+pt_PT.UTF-8
+pt_BR
+pt_BR.UTF-8
+ru_RU
+ru_RU.UTF-8
+pl_PX
+"
+
+error=0
+for lc in $llist ; do
+ wanted=`LC_ALL=$lc locale -c LC_NUMERIC 2>/dev/null | \
+ $AWK 'NR == 2 { decimal_point = $0 }
+ NR == 3 { thousands_sep = $0 }
+ END { printf("123%s456%s789%s15\n",
+ thousands_sep, thousands_sep, decimal_point)}'`
+ got=`LC_ALL=$lc $AWK "BEGIN {printf(\"%'.2f\n\",123456789.15)}"`
+ if [ "$wanted" != "$got" ] ; then
+ echo "$lc - unexpected output $got instead of $wanted"
+ error=1
+ fi
+done
+
+[ "$error" = 0 ] && echo ok || echo bummer
+exit $error
diff --git a/helpers/scanfmt.c b/helpers/scanfmt.c
new file mode 100644
index 00000000..2d7bd73a
--- /dev/null
+++ b/helpers/scanfmt.c
@@ -0,0 +1,22 @@
+/*
+ * Test out ' flag in different locales.
+ * Michal Jaegermann
+ * March, 2014
+ */
+
+#include <stdio.h>
+#include <locale.h>
+#include <stdlib.h>
+int
+main(int argc, char **argv)
+{
+ double t;
+
+ if (argc == 1)
+ return 1;
+
+ setlocale(LC_ALL, getenv("LC_ALL"));
+ sscanf(argv[1], "%lf", &t);
+ printf("%.2f\n", t);
+ return 0;
+}
diff --git a/helpers/testdfa.c b/helpers/testdfa.c
new file mode 100644
index 00000000..25a229a2
--- /dev/null
+++ b/helpers/testdfa.c
@@ -0,0 +1,1082 @@
+/*
+ * testdfa.c --- abstracted from gawk.
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991-2013 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 3 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 <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <locale.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <regex.h>
+#include <unistd.h>
+#include <wchar.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+
+#undef _Noreturn
+#define _Noreturn
+#define _GL_ATTRIBUTE_PURE
+#include "dfa.h"
+
+const char *regexflags2str(int flags);
+char *databuf(int fd);
+const char * reflags2str(int flagval);
+int parse_escape(const char **string_ptr);
+char *setup_pattern(const char *pattern, size_t *len);
+char casetable[];
+
+reg_syntax_t syn;
+
+struct flagtab {
+ int val;
+ const char *name;
+};
+
+/* usage --- print an error message and die */
+
+void usage(const char *myname)
+{
+ fprintf(stderr, "usage: %s [-ipt] 'awk-regex' < file\n", myname);
+ exit(EXIT_FAILURE);
+}
+
+/* main --- parse options, compile and run the regex */
+
+int main(int argc, char **argv)
+{
+ int c, ret, try_backref;
+ struct re_pattern_buffer pat;
+ struct re_registers regs;
+ struct dfa *dfareg;
+ size_t len;
+ const char *pattern;
+ const char *rerr;
+ char *data;
+ reg_syntax_t dfa_syn;
+ bool ignorecase = false;
+ char save;
+ size_t count = 0;
+ char *place;
+
+ if (argc < 2)
+ usage(argv[0]);
+
+ memset(& pat, 0, sizeof(pat));
+ memset(& regs, 0, sizeof(regs));
+
+ /* default syntax */
+ syn = RE_SYNTAX_GNU_AWK;
+
+ /* parse options, update syntax, ignorecase */
+ while ((c = getopt(argc, argv, "pit")) != -1) {
+ switch (c) {
+ case 'i':
+ ignorecase = true;
+ break;
+ case 'p':
+ syn = RE_SYNTAX_POSIX_AWK;
+ break;
+ case 't':
+ syn = RE_SYNTAX_AWK;
+ break;
+ case '?':
+ default:
+ usage(argv[0]);
+ break;
+ }
+ }
+
+ if (optind == argc)
+ usage(argv[0]);
+
+ pattern = argv[optind];
+ len = strlen(pattern);
+
+ setlocale(LC_CTYPE, "");
+ setlocale(LC_COLLATE, "");
+ setlocale(LC_MESSAGES, "");
+ setlocale(LC_NUMERIC, "");
+ setlocale(LC_TIME, "");
+
+ printf("Ignorecase: %s\nSyntax: %s\n",
+ (ignorecase ? "true" : "false"),
+ reflags2str(syn));
+ printf("Pattern: /%s/, len = %d\n", pattern, len);
+
+ pattern = setup_pattern(pattern, & len);
+ printf("After setup_pattern(), len = %d\n", len);
+
+ pat.fastmap = (char *) malloc(256);
+ if (pat.fastmap == NULL) {
+ perror("malloc");
+ exit(EXIT_FAILURE);
+ }
+
+ printf("MB_CUR_MAX = %d\n", (int) MB_CUR_MAX);
+
+ if (ignorecase) {
+ if (MB_CUR_MAX > 1) {
+ syn |= RE_ICASE;
+ pat.translate = NULL;
+ } else {
+ syn &= ~RE_ICASE;
+ pat.translate = (RE_TRANSLATE_TYPE) casetable;
+ }
+ } else {
+ pat.translate = NULL;
+ syn &= ~RE_ICASE;
+ }
+
+
+ dfa_syn = syn;
+ if (ignorecase)
+ dfa_syn |= RE_ICASE;
+ dfasyntax(dfa_syn, ignorecase, '\n');
+ re_set_syntax(syn);
+
+ if ((rerr = re_compile_pattern(pattern, len, & pat)) != NULL) {
+ fprintf(stderr, "%s: %s: cannot compile pattern '%s'\n",
+ argv[0], rerr, pattern);
+ exit(EXIT_FAILURE);
+ }
+
+ /* gack. this must be done *after* re_compile_pattern */
+ pat.newline_anchor = false; /* don't get \n in middle of string */
+
+ dfareg = dfaalloc();
+ printf("Calling dfacomp(%s, %d, %p, true)\n",
+ pattern, (int) len, dfareg);
+
+ dfacomp(pattern, len, dfareg, true);
+
+
+ data = databuf(STDIN_FILENO);
+
+ /* run the regex matcher */
+ ret = re_search(& pat, data, len, 0, len, NULL);
+ printf("re_search returned position %d (%s)\n", ret, (ret >= 0) ? "true" : "false");
+
+ /* run the dfa matcher */
+ /*
+ * dfa likes to stick a '\n' right after the matched
+ * text. So we just save and restore the character.
+ */
+ save = data[len];
+ place = dfaexec(dfareg, data, data+len, true,
+ &count, &try_backref);
+ data[len] = save;
+
+ if (place == NULL)
+ printf("dfaexec returned NULL\n");
+ else
+ printf("dfaexec returned %d (%.3s)\n", place - data, place);
+
+ /* release storage */
+ regfree(& pat);
+ if (regs.start)
+ free(regs.start);
+ if (regs.end)
+ free(regs.end);
+ dfafree(dfareg);
+ free(dfareg);
+
+ return 0;
+}
+
+/* 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) {
+ fprintf(stderr, "buffer overflow in genflags2str");
+ exit(EXIT_FAILURE);
+ }
+
+ if (sp != buffer) {
+ *sp++ = '|';
+ space_left--;
+ }
+ strcpy(sp, tab[i].name);
+ /* note ordering! */
+ space_left -= strlen(sp);
+ sp += strlen(sp);
+ }
+ }
+
+ *sp = '\0';
+ return buffer;
+}
+
+
+/* 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_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 },
+ };
+
+ if (flagval == RE_SYNTAX_EMACS) /* == 0 */
+ return "RE_SYNTAX_EMACS";
+
+ return genflags2str(flagval, values);
+}
+
+/*
+ * dfawarn() is called by the dfa routines whenever a regex is compiled
+ * must supply a dfawarn.
+ */
+
+void
+dfawarn(const char *dfa_warning)
+{
+ fprintf(stderr, "dfa warning: %s\n", dfa_warning);
+}
+
+/* dfaerror --- print an error message for the dfa routines */
+
+void
+dfaerror(const char *s)
+{
+ fprintf(stderr, "dfa-error: %s\n", s);
+ exit(EXIT_FAILURE);
+}
+
+/* databuf --- read the input file */
+
+char *
+databuf(int fd)
+{
+ char *buf;
+ struct stat sbuf;
+ ssize_t count;
+
+ if (fstat(fd, & sbuf) < 0)
+ return NULL;
+
+ buf = (char *) malloc(sbuf.st_size + 3);
+ if (buf == NULL)
+ return NULL;
+
+ if ((count = read(fd, buf, sbuf.st_size)) != sbuf.st_size) {
+ perror("read");
+ return NULL;
+ }
+ buf[sbuf.st_size] = '\0';
+
+ (void) close(fd);
+
+ return buf;
+}
+
+/* xmalloc --- for dfa.c */
+
+void *
+xmalloc(size_t bytes)
+{
+ void *p = malloc(bytes);
+
+ if (p == NULL) {
+ fprintf(stderr, "xmalloc: malloc failed: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ return p;
+}
+
+/* r_fatal --- print a fatal error message. also for dfa.c */
+
+void
+r_fatal(const char *mesg, ...)
+{
+ va_list args;
+ va_start(args, mesg);
+ fprintf(stderr, "fatal: ");
+ vfprintf(stderr, mesg, args);
+ va_end(args);
+
+ exit(EXIT_FAILURE);
+}
+
+/* setup_pattern --- do what gawk does with the pattern string */
+
+char *
+setup_pattern(const char *pattern, size_t *len)
+{
+ size_t is_multibyte = 0;
+ int c, c2;
+ size_t buflen = 0;
+ mbstate_t mbs;
+ bool has_anchor = false;
+ char *buf = NULL;
+ char *dest;
+ const char *src, *end;
+
+ memset(& mbs, 0, sizeof(mbs));
+
+ src = pattern;
+ end = pattern + *len;
+
+ /* Handle escaped characters first. */
+
+ /*
+ * Build a copy of the string (in buf) with the
+ * escaped characters translated, and generate the regex
+ * from that.
+ */
+ if (buf == NULL) {
+ buf = (char *) malloc(*len + 2);
+ if (buf == NULL) {
+ fprintf(stderr, "%s: malloc failed\n", __func__);
+ exit(EXIT_FAILURE);
+ }
+ buflen = *len;
+ } else if (*len > buflen) {
+ buf = (char *) realloc(buf, *len + 2);
+ if (buf == NULL) {
+ fprintf(stderr, "%s: realloc failed\n", __func__);
+ exit(EXIT_FAILURE);
+ }
+ buflen = *len;
+ }
+ dest = buf;
+
+ while (src < end) {
+ if (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 single-byte character. */
+ is_multibyte = 0;
+ }
+ }
+
+ /* We skip multibyte character, since it must not be a special
+ character. */
+ if ((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) {
+ fprintf(stderr, "%s: parse_escape failed\n", __func__);
+ exit(EXIT_FAILURE);
+ }
+ /*
+ * Unix awk treats octal (and hex?) chars
+ * literally in re's, so escape regexp
+ * metacharacters.
+ */
+ if (syn == RE_SYNTAX_AWK
+ && (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 (syn == RE_SYNTAX_GNU_AWK) {
+ *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 (MB_CUR_MAX > 1 && is_multibyte)
+ is_multibyte--;
+ } /* while */
+
+ *dest = '\0';
+ *len = dest - buf;
+
+ return buf;
+}
+
+/*
+ * 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)
+{
+ int c = *(*string_ptr)++;
+ int i;
+ int count;
+ int j;
+ const char *start;
+
+ switch (c) {
+ case 'a':
+ return '\a';
+ 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 (! isxdigit((unsigned char) (*string_ptr)[0])) {
+ return ('x');
+ }
+ i = j = 0;
+ start = *string_ptr;
+ for (;; j++) {
+ /* 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:
+ return c;
+ }
+}
+
+/* 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 independent
+ * 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'),
+};
+#elif 'a' == 0x81 /* it's EBCDIC */
+char casetable[] = {
+ /*00 NU SH SX EX PF HT LC DL */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ /*08 SM VT FF CR SO SI */
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ /*10 DE D1 D2 TM RS NL BS IL */
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ /*18 CN EM CC C1 FS GS RS US */
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+ /*20 DS SS FS BP LF EB EC */
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ /*28 SM C2 EQ AK BL */
+ 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
+ /*30 SY PN RS UC ET */
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ /*38 C3 D4 NK SU */
+ 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+ /*40 SP */
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ /*48 CENT . < ( + | */
+ 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+ /*50 & */
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ /*58 ! $ * ) ; ^ */
+ 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+ /*60 - / */
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ /*68 | , % _ > ? */
+ 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+ /*70 */
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ /*78 ` : # @ ' = " */
+ 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
+ /*80 a b c d e f g */
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ /*88 h i { */
+ 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
+ /*90 j k l m n o p */
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ /*98 q r } */
+ 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
+ /*A0 ~ s t u v w x */
+ 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
+ /*A8 y z [ */
+ 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+ /*B0 */
+ 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
+ /*B8 ] */
+ 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+ /*C0 { A B C D E F G */
+ 0xC0, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ /*C8 H I */
+ 0x88, 0x89, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+ /*D0 } J K L M N O P */
+ 0xD0, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ /*D8 Q R */
+ 0x98, 0x99, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
+ /*E0 \ S T U V W X */
+ 0xE0, 0xE1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
+ /*E8 Y Z */
+ 0xA8, 0xA9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
+ /*F0 0 1 2 3 4 5 6 7 */
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+ /*F8 8 9 */
+ 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
+};
+#else
+#include "You lose. You will need a translation table for your character set."
+#endif
+
+#undef C
+
+#ifdef GREP_DFA /* not needed for gawk */
+/* xalloc.h -- malloc with out-of-memory checking
+
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2003, 2004, 2006, 2007, 2008, 2009, 2010 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef XALLOC_H_
+# define XALLOC_H_
+
+# include <stddef.h>
+
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+
+# ifndef __attribute__
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
+# define __attribute__(x)
+# endif
+# endif
+
+# ifndef ATTRIBUTE_NORETURN
+# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
+# endif
+
+# ifndef ATTRIBUTE_MALLOC
+# if __GNUC__ >= 3
+# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
+# else
+# define ATTRIBUTE_MALLOC
+# endif
+# endif
+
+/* This function is always triggered when memory is exhausted.
+ It must be defined by the application, either explicitly
+ or by using gnulib's xalloc-die module. This is the
+ function to call when one wants the program to die because of a
+ memory allocation failure. */
+extern void xalloc_die (void);
+
+void *xmalloc (size_t s) ATTRIBUTE_MALLOC;
+void *xzalloc (size_t s) ATTRIBUTE_MALLOC;
+void *xcalloc (size_t n, size_t s) ATTRIBUTE_MALLOC;
+void *xrealloc (void *p, size_t s);
+void *x2realloc (void *p, size_t *pn);
+void *xmemdup (void const *p, size_t s) ATTRIBUTE_MALLOC;
+char *xstrdup (char const *str) ATTRIBUTE_MALLOC;
+
+/* Return 1 if an array of N objects, each of size S, cannot exist due
+ to size arithmetic overflow. S must be positive and N must be
+ nonnegative. This is a macro, not an inline function, so that it
+ works correctly even when SIZE_MAX < N.
+
+ By gnulib convention, SIZE_MAX represents overflow in size
+ calculations, so the conservative dividend to use here is
+ SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
+ However, malloc (SIZE_MAX) fails on all known hosts where
+ sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
+ exactly-SIZE_MAX allocations on such hosts; this avoids a test and
+ branch when S is known to be 1. */
+# define xalloc_oversized(n, s) \
+ ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
+
+
+/* In the following macros, T must be an elementary or structure/union or
+ typedef'ed type, or a pointer to such a type. To apply one of the
+ following macros to a function pointer or array type, you need to typedef
+ it first and use the typedef name. */
+
+/* Allocate an object of type T dynamically, with error checking. */
+/* extern t *XMALLOC (typename t); */
+# define XMALLOC(t) ((t *) xmalloc (sizeof (t)))
+
+/* Allocate memory for N elements of type T, with error checking. */
+/* extern t *XNMALLOC (size_t n, typename t); */
+# define XNMALLOC(n, t) \
+ ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t))))
+
+/* Allocate an object of type T dynamically, with error checking,
+ and zero it. */
+/* extern t *XZALLOC (typename t); */
+# define XZALLOC(t) ((t *) xzalloc (sizeof (t)))
+
+/* Allocate memory for N elements of type T, with error checking,
+ and zero it. */
+/* extern t *XCALLOC (size_t n, typename t); */
+# define XCALLOC(n, t) \
+ ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))
+
+/*
+ * Gawk uses this file only to keep dfa.c happy.
+ * We're therefore safe in manually defining HAVE_INLINE to
+ * make the !@#$%^&*() thing just work.
+ */
+#ifdef GAWK
+#define HAVE_INLINE 1 /* so there. nyah, nyah, nyah. */
+#endif
+
+# if HAVE_INLINE
+# define static_inline static inline
+# else
+void *xnmalloc (size_t n, size_t s) ATTRIBUTE_MALLOC;
+void *xnrealloc (void *p, size_t n, size_t s);
+void *x2nrealloc (void *p, size_t *pn, size_t s);
+char *xcharalloc (size_t n) ATTRIBUTE_MALLOC;
+# endif
+
+
+/* Allocate an array of N objects, each with S bytes of memory,
+ dynamically, with error checking. S must be nonzero. */
+
+void *
+xnmalloc (size_t n, size_t s)
+{
+ if (xalloc_oversized (n, s))
+ xalloc_die ();
+ return xmalloc (n * s);
+}
+
+/* Allocate an array of N objects, each with S bytes of memory,
+ dynamically, with error checking. S must be nonzero.
+ Clear the contents afterwards. */
+
+void *
+xcalloc(size_t nmemb, size_t size)
+{
+ void *p = xmalloc (nmemb * size);
+ memset(p, '\0', nmemb * size);
+ return p;
+}
+
+/* Reallocate a pointer to a new size, with error checking. */
+
+void *
+xrealloc(void *p, size_t size)
+{
+ void *new_p = realloc(p, size);
+ if (new_p == 0)
+ xalloc_die ();
+
+ return new_p;
+}
+
+/* xalloc_die --- fatal error message when malloc fails, needed by dfa.c */
+
+void
+xalloc_die (void)
+{
+ r_fatal("xalloc: malloc failed: %s"), strerror(errno);
+}
+
+/* Clone an object P of size S, with error checking. There's no need
+ for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any
+ need for an arithmetic overflow check. */
+
+void *
+xmemdup (void const *p, size_t s)
+{
+ return memcpy (xmalloc (s), p, s);
+}
+
+/* Change the size of an allocated block of memory P to an array of N
+ objects each of S bytes, with error checking. S must be nonzero. */
+
+void *
+xnrealloc (void *p, size_t n, size_t s)
+{
+ if (xalloc_oversized (n, s))
+ xalloc_die ();
+ return xrealloc (p, n * s);
+}
+
+/* If P is null, allocate a block of at least *PN such objects;
+ otherwise, reallocate P so that it contains more than *PN objects
+ each of S bytes. *PN must be nonzero unless P is null, and S must
+ be nonzero. Set *PN to the new number of objects, and return the
+ pointer to the new block. *PN is never set to zero, and the
+ returned pointer is never null.
+
+ Repeated reallocations are guaranteed to make progress, either by
+ allocating an initial block with a nonzero size, or by allocating a
+ larger block.
+
+ In the following implementation, nonzero sizes are increased by a
+ factor of approximately 1.5 so that repeated reallocations have
+ O(N) overall cost rather than O(N**2) cost, but the
+ specification for this function does not guarantee that rate.
+
+ Here is an example of use:
+
+ int *p = NULL;
+ size_t used = 0;
+ size_t allocated = 0;
+
+ void
+ append_int (int value)
+ {
+ if (used == allocated)
+ p = x2nrealloc (p, &allocated, sizeof *p);
+ p[used++] = value;
+ }
+
+ This causes x2nrealloc to allocate a block of some nonzero size the
+ first time it is called.
+
+ To have finer-grained control over the initial size, set *PN to a
+ nonzero value before calling this function with P == NULL. For
+ example:
+
+ int *p = NULL;
+ size_t used = 0;
+ size_t allocated = 0;
+ size_t allocated1 = 1000;
+
+ void
+ append_int (int value)
+ {
+ if (used == allocated)
+ {
+ p = x2nrealloc (p, &allocated1, sizeof *p);
+ allocated = allocated1;
+ }
+ p[used++] = value;
+ }
+
+ */
+
+void *
+x2nrealloc (void *p, size_t *pn, size_t s)
+{
+ size_t n = *pn;
+
+ if (! p)
+ {
+ if (! n)
+ {
+ /* The approximate size to use for initial small allocation
+ requests, when the invoking code specifies an old size of
+ zero. 64 bytes is the largest "small" request for the
+ GNU C library malloc. */
+ enum { DEFAULT_MXFAST = 64 };
+
+ n = DEFAULT_MXFAST / s;
+ n += !n;
+ }
+ }
+ else
+ {
+ /* Set N = ceil (1.5 * N) so that progress is made if N == 1.
+ Check for overflow, so that N * S stays in size_t range.
+ The check is slightly conservative, but an exact check isn't
+ worth the trouble. */
+ if ((size_t) -1 / 3 * 2 / s <= n)
+ xalloc_die ();
+ n += (n + 1) / 2;
+ }
+
+ *pn = n;
+ return xrealloc (p, n * s);
+}
+
+/* Return a pointer to a new buffer of N bytes. This is like xmalloc,
+ except it returns char *. */
+
+char *
+xcharalloc (size_t n)
+{
+ return XNMALLOC (n, char);
+}
+
+/* Allocate S bytes of zeroed memory dynamically, with error checking.
+ There's no need for xnzalloc (N, S), since it would be equivalent
+ to xcalloc (N, S). */
+
+void *
+xzalloc (size_t s)
+{
+ return memset (xmalloc (s), 0, s);
+}
+
+# endif
+
+# ifdef __cplusplus
+}
+
+/* C++ does not allow conversions from void * to other pointer types
+ without a cast. Use templates to work around the problem when
+ possible. */
+
+template <typename T> inline T *
+xrealloc (T *p, size_t s)
+{
+ return (T *) xrealloc ((void *) p, s);
+}
+
+template <typename T> inline T *
+xnrealloc (T *p, size_t n, size_t s)
+{
+ return (T *) xnrealloc ((void *) p, n, s);
+}
+
+template <typename T> inline T *
+x2realloc (T *p, size_t *pn)
+{
+ return (T *) x2realloc ((void *) p, pn);
+}
+
+template <typename T> inline T *
+x2nrealloc (T *p, size_t *pn, size_t s)
+{
+ return (T *) x2nrealloc ((void *) p, pn, s);
+}
+
+template <typename T> inline T *
+xmemdup (T const *p, size_t s)
+{
+ return (T *) xmemdup ((void const *) p, s);
+}
+
+
+
+#endif /* !XALLOC_H_ */
+#endif /* GREP_DFA */
diff --git a/helpers/testnet.awk b/helpers/testnet.awk
new file mode 100644
index 00000000..0200f312
--- /dev/null
+++ b/helpers/testnet.awk
@@ -0,0 +1,12 @@
+BEGIN {
+ URL = ARGV[1]; ARGV[1] = ""
+ if (Method == "") Method = "GET"
+ HttpService = "/inet/tcp/0/www.yahoo.com/80"
+ ORS = RS = "\r\n\r\n"
+ print Method " " URL "/index.html HTTP/1.0" |& HttpService
+ HttpService |& getline Header
+ print Header > "/dev/stderr"
+ while ((HttpService |& getline) > 0)
+ printf "%s", $0
+ close(HttpService)
+ }
diff --git a/helpers/testnet.c b/helpers/testnet.c
new file mode 100644
index 00000000..feda38b4
--- /dev/null
+++ b/helpers/testnet.c
@@ -0,0 +1,396 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <memory.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif /* O_BINARY */
+
+#ifndef AI_ADDRCONFIG /* not everyone has this symbol */
+#define AI_ADDRCONFIG 0
+#endif /* AI_ADDRCONFIG */
+
+#ifndef AF_UNSPEC
+#define AF_UNSPEC 0
+#endif
+#ifndef AF_INET
+#define AF_INET 2
+#endif
+#ifndef AF_INET6
+#define AF_INET6 10
+#endif
+
+#include <limits.h>
+
+#ifndef SHUT_RD
+#define SHUT_RD 0
+#endif
+
+#ifndef SHUT_WR
+#define SHUT_WR 1
+#endif
+
+#ifndef SHUT_RDWR
+#define SHUT_RDWR 2
+#endif
+
+#define _(str) str
+
+#define INVALID_HANDLE (-1)
+
+static int str2mode(const char *mode);
+
+
+/* socketopen --- open a socket and set it into connected state */
+
+static int
+socketopen(int family, int type, const char *localpname,
+ const char *remotepname, const char *remotehostname)
+{
+ struct addrinfo *lres, *lres0;
+ struct addrinfo lhints;
+ struct addrinfo *rres, *rres0;
+ struct addrinfo rhints;
+
+ int lerror, rerror;
+
+ int socket_fd = INVALID_HANDLE;
+ int any_remote_host = (strcmp(remotehostname, "0") == 0);
+
+ memset(& lhints, '\0', sizeof (lhints));
+ lhints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
+ lhints.ai_socktype = type;
+ lhints.ai_family = family;
+
+ lerror = getaddrinfo(NULL, localpname, & lhints, & lres);
+ if (lerror) {
+ if (strcmp(localpname, "0") != 0) {
+ fprintf(stderr, _("local port %s invalid in `/inet'"), localpname);
+ exit(1);
+ }
+ lres0 = NULL;
+ lres = & lhints;
+ } else
+ lres0 = lres;
+
+ while (lres != NULL) {
+ memset (& rhints, '\0', sizeof (rhints));
+ rhints.ai_flags = lhints.ai_flags;
+ rhints.ai_socktype = lhints.ai_socktype;
+ rhints.ai_family = lhints.ai_family;
+ rhints.ai_protocol = lhints.ai_protocol;
+
+ rerror = getaddrinfo(any_remote_host ? NULL : remotehostname,
+ remotepname, & rhints, & rres);
+ if (rerror) {
+ if (lres0 != NULL)
+ freeaddrinfo(lres0);
+ fprintf(stderr, _("remote host and port information (%s, %s) invalid"), remotehostname, remotepname);
+ exit(1);
+ }
+ rres0 = rres;
+ socket_fd = INVALID_HANDLE;
+ while (rres != NULL) {
+ socket_fd = socket(rres->ai_family,
+ rres->ai_socktype, rres->ai_protocol);
+ if (socket_fd < 0 || socket_fd == INVALID_HANDLE)
+ goto nextrres;
+
+ if (type == SOCK_STREAM) {
+ int on = 1;
+#ifdef SO_LINGER
+ struct linger linger;
+ memset(& linger, '\0', sizeof(linger));
+#endif
+ setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR,
+ (char *) & on, sizeof(on));
+#ifdef SO_LINGER
+ linger.l_onoff = 1;
+ /* linger for 30/100 second */
+ linger.l_linger = 30;
+ setsockopt(socket_fd, SOL_SOCKET, SO_LINGER,
+ (char *) & linger, sizeof(linger));
+#endif
+ }
+ if (bind(socket_fd, lres->ai_addr, lres->ai_addrlen) != 0)
+ goto nextrres;
+
+ if (! any_remote_host) { /* not ANY => create a client */
+ if (connect(socket_fd, rres->ai_addr, rres->ai_addrlen) == 0)
+ break;
+ } else { /* remote host is ANY => create a server */
+ if (type == SOCK_STREAM) {
+ int clientsocket_fd = INVALID_HANDLE;
+
+ struct sockaddr_storage remote_addr;
+ 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;
+ break;
+ }
+ } else if (type == SOCK_DGRAM) {
+#ifdef MSG_PEEK
+ char buf[10];
+ struct sockaddr_storage remote_addr;
+ socklen_t read_len;
+
+ if (recvfrom(socket_fd, buf, 1, MSG_PEEK,
+ (struct sockaddr *) & remote_addr,
+ & read_len) >= 0
+ && read_len
+ && connect(socket_fd,
+ (struct sockaddr *) & remote_addr,
+ read_len) == 0)
+ break;
+#endif
+ }
+ }
+
+nextrres:
+ if (socket_fd != INVALID_HANDLE)
+ close(socket_fd);
+ socket_fd = INVALID_HANDLE;
+ rres = rres->ai_next;
+ }
+ freeaddrinfo(rres0);
+ if (socket_fd != INVALID_HANDLE)
+ break;
+ lres = lres->ai_next;
+ }
+ if (lres0)
+ freeaddrinfo(lres0);
+
+ return socket_fd;
+}
+
+/* devopen --- handle /dev/std{in,out,err}, /dev/fd/N, regular files */
+
+/*
+ * 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;
+ int len;
+ int family;
+ int protocol;
+ char *hostname;
+ char *hostnameslastcharp;
+ char *localpname;
+ char *localpnamelastcharp;
+
+ flag = str2mode(mode);
+ openfd = INVALID_HANDLE;
+
+ /* /inet/protocol/localport/hostname/remoteport */
+ len = 6;
+
+ cp = (char *) name + len;
+ /* which protocol? */
+ if (strncmp(cp, "tcp/", 4) == 0)
+ protocol = SOCK_STREAM;
+ else if (strncmp(cp, "udp/", 4) == 0)
+ protocol = SOCK_DGRAM;
+ else {
+ protocol = SOCK_STREAM; /* shut up the compiler */
+ fprintf(stderr, _("no (known) protocol supplied in special filename `%s'"), name);
+ exit(1);
+ }
+ 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) {
+ fprintf(stderr, _("special file name `%s' is incomplete"), name);
+ exit(1);
+ }
+
+ /*
+ * 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';
+ localpnamelastcharp = cp;
+
+ /* which hostname? */
+ cp++;
+ hostname = cp;
+ while (*cp != '/' && *cp != '\0')
+ cp++;
+ if (*cp != '/' || cp == hostname) {
+ *localpnamelastcharp = '/';
+ fprintf(stderr, _("must supply a remote hostname to `/inet'"));
+ exit(1);
+ }
+ *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') {
+ *localpnamelastcharp = '/';
+ *hostnameslastcharp = '/';
+ fprintf(stderr, _("must supply a remote port to `/inet'"));
+ exit(1);
+ }
+
+ {
+#define DEFAULT_RETRIES 20
+ static unsigned long def_retries = DEFAULT_RETRIES;
+ static bool first_time = true;
+ unsigned long retries = 0;
+ static long msleep = 1000;
+
+ if (first_time) {
+ char *cp, *end;
+ unsigned long count = 0;
+ char *ms2;
+
+ first_time = false;
+ if ((cp = getenv("GAWK_SOCK_RETRIES")) != NULL) {
+ count = strtoul(cp, & end, 10);
+ if (end != cp && count > 0)
+ def_retries = count;
+ }
+
+ /*
+ * Env var is in milliseconds, paramter to usleep()
+ * is microseconds, make the conversion. Default is
+ * 1 millisecond.
+ */
+ if ((ms2 = getenv("GAWK_MSEC_SLEEP")) != NULL) {
+ msleep = strtol(ms2, & end, 10);
+ if (end == ms2 || msleep < 0)
+ msleep = 1000;
+ else
+ msleep *= 1000;
+ }
+ }
+ retries = def_retries;
+
+ do {
+ openfd = socketopen(family, protocol, localpname, cp, hostname);
+ retries--;
+ } while (openfd == INVALID_HANDLE && retries > 0 && usleep(msleep) == 0);
+ }
+
+ *localpnamelastcharp = '/';
+ *hostnameslastcharp = '/';
+
+ return openfd;
+}
+
+
+/* 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 */
+ fprintf(stderr, "bad mode passed to str2mode\n");
+ exit(1);
+ }
+ if (strchr(mode, 'b') != NULL)
+ ret |= O_BINARY;
+ return ret;
+}
+
+int main(int argc, char **argv)
+{
+ int ofd;
+ int ifd;
+ int n;
+ int nread;
+ int wrote;
+ char inbuf[BUFSIZ];
+ /* char outbuf[] = "GET www.yahoo.com/index.html HTTP/1.0\r\n\r\n"; */
+ char outbuf[] = "GET index.html HTTP/1.0\r\n\r\n";
+ char sockname[BUFSIZ];
+
+ strcpy(sockname, "/inet/tcp/0/www.yahoo.com/80");
+
+ ofd = devopen(sockname, "rw");
+ if (ofd < 0) {
+ perror("devopen");
+ exit(1);
+ }
+
+ if ((ifd = dup(ofd)) < 0) {
+ perror("dup");
+ exit(1);
+ }
+
+ n = strlen(outbuf);
+ if ((wrote = write(ofd, outbuf, n)) != n) {
+ perror("write");
+ exit(1);
+ }
+
+ while ((nread = read(ifd, inbuf, sizeof(inbuf))) > 0) {
+ write(1, inbuf, nread);
+ }
+
+ close(ifd);
+ close(ofd);
+
+ return 0;
+}
diff --git a/helpers/tryfmt.c b/helpers/tryfmt.c
new file mode 100644
index 00000000..8166d3f1
--- /dev/null
+++ b/helpers/tryfmt.c
@@ -0,0 +1,23 @@
+/*
+ * Test out ' flag in different locales.
+ * Michal Jaegermann
+ * March, 2014
+ */
+
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+int
+main(int argc, char **argv)
+{
+ const char *fmt;
+ if (argc == 1)
+ fmt = "%'.2f";
+ else
+ fmt = argv[1];
+
+ setlocale(LC_ALL, getenv("LC_ALL"));
+ printf(fmt, 12456789.01);
+ printf("\n");
+ return 0;
+}
diff --git a/install-sh b/install-sh
index 4fbbae7b..04367377 100755
--- a/install-sh
+++ b/install-sh
@@ -1,7 +1,7 @@
#!/bin/sh
# install - install a program, script, or datafile
-scriptversion=2006-10-14.15
+scriptversion=2013-10-30.23; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
@@ -35,57 +35,57 @@ scriptversion=2006-10-14.15
# 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
+# '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.
+tab=' '
nl='
'
-IFS=" "" $nl"
+IFS=" $tab$nl"
-# set DOITPROG to echo to test this script
+# Set DOITPROG to "echo" to test this script.
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-if test -z "$doit"; then
- doit_exec=exec
-else
- doit_exec=$doit
-fi
+doit=${DOITPROG-}
+doit_exec=${doit:-exec}
# Put in absolute file names if you don't have them in your path;
# or use environment 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}"
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
-posix_glob=
posix_mkdir=
# Desired mode of installed file.
mode=0755
+chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
-chgrpcmd=
-stripcmd=
+mvcmd=$mvprog
rmcmd="$rmprog -f"
-mvcmd="$mvprog"
+stripcmd=
+
src=
dst=
dir_arg=
-dstarg=
+dst_arg=
+
+copy_on_change=false
no_target_directory=
-usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
@@ -95,91 +95,89 @@ 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.
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -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.
Environment variables override the default commands:
- CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
- -c) shift
- continue;;
+ -c) ;;
+
+ -C) copy_on_change=true;;
- -d) dir_arg=true
- shift
- continue;;
+ -d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
- shift
- shift
- continue;;
+ shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
- shift
- shift
- case $mode in
- *' '* | *' '* | *'
-'* | *'*'* | *'?'* | *'['*)
- echo "$0: invalid mode: $mode" >&2
- exit 1;;
- esac
- continue;;
+ case $mode in
+ *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
-o) chowncmd="$chownprog $2"
- shift
- shift
- continue;;
+ shift;;
- -s) stripcmd=$stripprog
- shift
- continue;;
+ -s) stripcmd=$stripprog;;
- -t) dstarg=$2
- shift
- shift
- continue;;
+ -t) dst_arg=$2
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ shift;;
- -T) no_target_directory=true
- shift
- continue;;
+ -T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
- --) shift
- break;;
+ --) shift
+ break;;
- -*) echo "$0: invalid option: $1" >&2
- exit 1;;
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
*) break;;
esac
+ shift
done
-if test $# -ne 0 && test -z "$dir_arg$dstarg"; then
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
- if test -n "$dstarg"; then
+ if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
- set fnord "$@" "$dstarg"
+ set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
- dstarg=$arg
+ dst_arg=$arg
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
done
fi
@@ -188,13 +186,17 @@ if test $# -eq 0; then
echo "$0: no input file specified." >&2
exit 1
fi
- # It's OK to call `install-sh -d' without argument.
+ # It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
- trap '(exit $?); exit' 1 2 13 15
+ do_exit='(exit $ret); exit $ret'
+ trap "ret=129; $do_exit" 1
+ trap "ret=130; $do_exit" 2
+ trap "ret=141; $do_exit" 13
+ trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
@@ -205,16 +207,16 @@ if test -z "$dir_arg"; then
*[0-7])
if test -z "$stripcmd"; then
- u_plus_rw=
+ u_plus_rw=
else
- u_plus_rw='% 200'
+ u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
- u_plus_rw=
+ u_plus_rw=
else
- u_plus_rw=,u+rw
+ u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
@@ -222,9 +224,9 @@ fi
for src
do
- # Protect names starting with `-'.
+ # Protect names problematic for 'test' and other utilities.
case $src in
- -*) src=./$src ;;
+ -* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
@@ -242,55 +244,24 @@ do
exit 1
fi
- if test -z "$dstarg"; then
+ if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
-
- dst=$dstarg
- # Protect names starting with `-'.
- case $dst in
- -*) dst=./$dst ;;
- esac
+ dst=$dst_arg
# 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
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
- # Prefer dirname, but fall back on a substitute if dirname fails.
- dstdir=`
- (dirname "$dst") 2>/dev/null ||
- expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$dst" : 'X\(//\)[^/]' \| \
- X"$dst" : 'X\(//\)$' \| \
- X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
- echo X"$dst" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'
- `
-
+ dstdir=`dirname "$dst"`
test -d "$dstdir"
dstdir_status=$?
fi
@@ -301,74 +272,74 @@ do
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
- # Create intermediate dirs using mode 755 as modified by the umask.
- # This is like FreeBSD 'install' as of 1997-10-28.
- umask=`umask`
- case $stripcmd.$umask in
- # Optimize common cases.
- *[2367][2367]) mkdir_umask=$umask;;
- .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
- *[0-7])
- mkdir_umask=`expr $umask + 22 \
- - $umask % 100 % 40 + $umask % 20 \
- - $umask % 10 % 4 + $umask % 2
- `;;
- *) mkdir_umask=$umask,go-w;;
- esac
-
- # With -d, create the new directory with the user-specified mode.
- # Otherwise, rely on $mkdir_umask.
- if test -n "$dir_arg"; then
- mkdir_mode=-m$mode
- else
- mkdir_mode=
- fi
-
- posix_mkdir=false
- case $umask in
- *[123567][0-7][0-7])
- # POSIX mkdir -p sets u+wx bits regardless of umask, which
- # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
- ;;
- *)
- tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
- trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
-
- if (umask $mkdir_umask &&
- exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
- then
- if test -z "$dir_arg" || {
- # Check for POSIX incompatibilities with -m.
- # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
- # other-writeable bit of parent directory when it shouldn't.
- # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
- ls_ld_tmpdir=`ls -ld "$tmpdir"`
- case $ls_ld_tmpdir in
- d????-?r-*) different_mode=700;;
- d????-?--*) different_mode=755;;
- *) false;;
- esac &&
- $mkdirprog -m$different_mode -p -- "$tmpdir" && {
- ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
- test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
- }
- }
- then posix_mkdir=:
- fi
- rmdir "$tmpdir/d" "$tmpdir"
- else
- # Remove any dirs left behind by ancient mkdir implementations.
- rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
- fi
- trap '' 0;;
- esac;;
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
esac
if
$posix_mkdir && (
- umask $mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
@@ -378,60 +349,51 @@ do
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
- /*) prefix=/ ;;
- -*) prefix=./ ;;
- *) prefix= ;;
- esac
-
- case $posix_glob in
- '')
- if (set -f) 2>/dev/null; then
- posix_glob=true
- else
- posix_glob=false
- fi ;;
+ /*) prefix='/';;
+ [-=\(\)!]*) prefix='./';;
+ *) prefix='';;
esac
oIFS=$IFS
IFS=/
- $posix_glob && set -f
+ set -f
set fnord $dstdir
shift
- $posix_glob && set +f
+ set +f
IFS=$oIFS
prefixes=
for d
do
- test -z "$d" && continue
-
- prefix=$prefix$d
- if test -d "$prefix"; then
- prefixes=
- else
- if $posix_mkdir; then
- (umask=$mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
- # Don't fail if two instances are running concurrently.
- test -d "$prefix" || exit 1
- else
- case $prefix in
- *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
- *) qprefix=$prefix;;
- esac
- prefixes="$prefixes '$qprefix'"
- fi
- fi
- prefix=$prefix/
+ test X"$d" = X && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
done
if test -n "$prefixes"; then
- # Don't fail if two instances are running concurrently.
- (umask $mkdir_umask &&
- eval "\$doit_exec \$mkdirprog $prefixes") ||
- test -d "$dstdir" || exit 1
- obsolete_mkdir_used=true
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
fi
fi
fi
@@ -459,41 +421,51 @@ do
# 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 $mode "$dsttmp"; } &&
-
- # Now rename the file to the real destination.
- { $doit $mvcmd -f "$dsttmp" "$dst" 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 "$dst"; then
- $doit $rmcmd -f "$dst" 2>/dev/null \
- || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
- && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
- || {
- echo "$0: cannot unlink or rename $dst" >&2
- (exit 1); exit 1
- }
- else
- :
- fi
- } &&
-
- # Now rename the file to the real destination.
- $doit $mvcmd "$dsttmp" "$dst"
- }
- } || exit 1
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+ set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ set +f &&
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 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.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
trap '' 0
fi
@@ -503,5 +475,6 @@ done
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
# End:
diff --git a/int_array.c b/int_array.c
index fd58de26..c2bf37b5 100644
--- a/int_array.c
+++ b/int_array.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-2011 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-2013 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -40,18 +40,15 @@ static NODE **int_list(NODE *symbol, NODE *t);
static NODE **int_copy(NODE *symbol, NODE *newsymb);
static NODE **int_dump(NODE *symbol, NODE *ndump);
-#ifdef ARRAYDEBUG
-static NODE **int_option(NODE *opt, NODE *val);
-#endif
-
static uint32_t int_hash(uint32_t k, uint32_t hsize);
static inline NODE **int_find(NODE *symbol, long k, uint32_t hash1);
static NODE **int_insert(NODE *symbol, long k, uint32_t hash1);
static void grow_int_table(NODE *symbol);
-array_ptr int_array_func[] = {
+afunc_t int_array_func[] = {
int_array_init,
is_integer,
+ null_length,
int_lookup,
int_exists,
int_clear,
@@ -59,25 +56,27 @@ array_ptr int_array_func[] = {
int_list,
int_copy,
int_dump,
-#ifdef ARRAYDEBUG
- int_option,
-#endif
+ (afunc_t) 0,
};
-/* int_array_init --- check relevant environment variables */
+/* int_array_init --- array initialization routine */
static NODE **
-int_array_init(NODE *symbol ATTRIBUTE_UNUSED, NODE *subs ATTRIBUTE_UNUSED)
+int_array_init(NODE *symbol, NODE *subs ATTRIBUTE_UNUSED)
{
- long newval;
+ if (symbol == NULL) { /* first time */
+ long newval;
+
+ /* check relevant environment variables */
+ if ((newval = getenv_long("INT_CHAIN_MAX")) > 0)
+ INT_CHAIN_MAX = newval;
+ } else
+ null_array(symbol);
- if ((newval = getenv_long("INT_CHAIN_MAX")) > 0)
- INT_CHAIN_MAX = newval;
return (NODE **) ! NULL;
}
-
/* is_integer --- check if subscript is an integer */
NODE **
@@ -86,7 +85,7 @@ is_integer(NODE *symbol, NODE *subs)
long l;
AWKNUM d;
- if (subs == Nnull_string)
+ if (subs == Nnull_string || do_mpfr)
return NULL;
if ((subs->flags & NUMINT) != 0)
@@ -101,10 +100,10 @@ is_integer(NODE *symbol, NODE *subs)
return NULL;
}
- /* a[3]=1; print "3" in a -- TRUE
- * a[3]=1; print "+3" in a -- FALSE
- * a[3]=1; print "03" in a -- FALSE
- * a[-3]=1; print "-3" in a -- TRUE
+ /* a[3]=1; print "3" in a -- true
+ * a[3]=1; print "+3" in a -- false
+ * a[3]=1; print "03" in a -- false
+ * a[-3]=1; print "-3" in a -- true
*/
if ((subs->flags & (STRING|STRCUR)) != 0) {
@@ -154,7 +153,8 @@ is_integer(NODE *symbol, NODE *subs)
}
-/* int_lookup --- Find SYMBOL[SUBS] in the assoc array. Install it with value ""
+/*
+ * int_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.
*/
@@ -167,7 +167,8 @@ int_lookup(NODE *symbol, NODE *subs)
NODE **lhs;
NODE *xn;
- /* N.B: symbol->table_size is the total # of non-integers (symbol->xarray)
+ /*
+ * N.B: symbol->table_size is the total # of non-integers (symbol->xarray)
* and integer elements. Also, symbol->xarray must have at least one
* item in it, and can not exist if there are no integer elements.
* In that case, symbol->xarray is promoted to 'symbol' (See int_remove).
@@ -214,7 +215,8 @@ int_lookup(NODE *symbol, NODE *subs)
}
-/* int_exists --- test whether the array element symbol[subs] exists or not,
+/*
+ * int_exists --- test whether the array element symbol[subs] exists or not,
* return pointer to value if it does.
*/
@@ -273,8 +275,7 @@ int_clear(NODE *symbol, NODE *subs ATTRIBUTE_UNUSED)
}
if (symbol->buckets != NULL)
efree(symbol->buckets);
- init_array(symbol); /* re-initialize symbol */
- symbol->flags &= ~ARRAYMAXED;
+ symbol->ainit(symbol, NULL); /* re-initialize symbol */
return NULL;
}
@@ -290,7 +291,8 @@ int_remove(NODE *symbol, NODE *subs)
int i;
NODE *xn = symbol->xarray;
- assert(symbol->buckets != NULL);
+ if (symbol->table_size == 0 || symbol->buckets == NULL)
+ return NULL;
if (! is_integer(symbol, subs)) {
if (xn == NULL || xn->aremove(xn, subs) == NULL)
@@ -344,9 +346,7 @@ removed:
BUCKET *head = symbol->buckets[hash1];
assert(b->aicount == 1);
- /* move the last element from head
- * to bucket to make it full.
- */
+ /* move the last element from head to bucket to make it full. */
i = --head->aicount; /* head has one less element */
b->ainum[1] = head->ainum[i];
b->aivalue[1] = head->aivalue[i];
@@ -362,8 +362,7 @@ removed:
symbol->table_size--;
if (xn == NULL && symbol->table_size == 0) {
efree(symbol->buckets);
- init_array(symbol); /* re-initialize array 'symbol' */
- symbol->flags &= ~ARRAYMAXED;
+ symbol->ainit(symbol, NULL); /* re-initialize array 'symbol' */
} else if (xn != NULL && symbol->table_size == xn->table_size) {
/* promote xn (str_array) to symbol */
xn->flags &= ~XARRAY;
@@ -404,6 +403,7 @@ int_copy(NODE *symbol, NODE *newsymb)
) {
getbucket(newchain);
newchain->aicount = chain->aicount;
+ newchain->ainext = NULL;
for (j = 0; j < chain->aicount; j++) {
NODE *oldval;
@@ -426,6 +426,7 @@ int_copy(NODE *symbol, NODE *newsymb)
}
*pnew = newchain;
+ newchain->ainext = NULL;
pnew = & newchain->ainext;
}
}
@@ -461,14 +462,17 @@ int_list(NODE *symbol, NODE *t)
int j, elem_size = 1;
long num;
static char buf[100];
+ assoc_kind_t assoc_kind;
- assert(symbol->table_size > 0);
+ if (symbol->table_size == 0)
+ return NULL;
+ assoc_kind = (assoc_kind_t) t->flags;
num_elems = symbol->table_size;
- if ((t->flags & (AINDEX|AVALUE|ADELETE)) == (AINDEX|ADELETE))
+ if ((assoc_kind & (AINDEX|AVALUE|ADELETE)) == (AINDEX|ADELETE))
num_elems = 1;
- if ((t->flags & (AINDEX|AVALUE)) == (AINDEX|AVALUE))
+ if ((assoc_kind & (AINDEX|AVALUE)) == (AINDEX|AVALUE))
elem_size = 2;
list_size = elem_size * num_elems;
@@ -490,7 +494,7 @@ int_list(NODE *symbol, NODE *t)
for (j = 0; j < b->aicount; j++) {
/* index */
num = b->ainum[j];
- if (t->flags & AISTR) {
+ if ((assoc_kind & AISTR) != 0) {
sprintf(buf, "%ld", num);
subs = make_string(buf, strlen(buf));
subs->numbr = num;
@@ -502,12 +506,12 @@ int_list(NODE *symbol, NODE *t)
list[k++] = subs;
/* value */
- if (t->flags & AVALUE) {
+ if ((assoc_kind & AVALUE) != 0) {
r = b->aivalue[j];
if (r->type == Node_val) {
- if ((t->flags & AVNUM) != 0)
+ if ((assoc_kind & AVNUM) != 0)
(void) force_number(r);
- else if ((t->flags & AVSTR) != 0)
+ else if ((assoc_kind & AVSTR) != 0)
r = force_string(r);
}
list[k++] = r;
@@ -582,7 +586,7 @@ int_dump(NODE *symbol, NODE *ndump)
fprintf(output_fp, "flags: %s\n", flags2str(symbol->flags));
}
indent(indent_level);
- fprintf(output_fp, "INT_CHAIN_MAX: %lu\n", INT_CHAIN_MAX);
+ fprintf(output_fp, "INT_CHAIN_MAX: %lu\n", (unsigned long) INT_CHAIN_MAX);
indent(indent_level);
fprintf(output_fp, "array_size: %lu (int)\n", (unsigned long) symbol->array_size);
indent(indent_level);
@@ -663,14 +667,13 @@ static uint32_t
int_hash(uint32_t k, uint32_t hsize)
{
-/* Code snippet copied from:
+/*
+ * Code snippet copied from:
* Hash functions (http://www.azillionmonkeys.com/qed/hash.html).
* Copyright 2004-2008 by Paul Hsieh. Licenced under LGPL 2.1.
*/
- /* This is the final mixing function used by Paul Hsieh
- * in SuperFastHash.
- */
+ /* This is the final mixing function used by Paul Hsieh in SuperFastHash. */
k ^= k << 3;
k += k >> 5;
@@ -713,9 +716,7 @@ int_insert(NODE *symbol, long k, uint32_t hash1)
b = symbol->buckets[hash1];
- /* Only the first bucket in the chain can be partially full,
- * but is never empty.
- */
+ /* Only the first bucket in the chain can be partially full, but is never empty. */
if (b == NULL || (i = b->aicount) == 2) {
getbucket(b);
@@ -802,25 +803,3 @@ grow_int_table(NODE *symbol)
}
efree(old);
}
-
-
-#ifdef ARRAYDEBUG
-
-static NODE **
-int_option(NODE *opt, NODE *val)
-{
- int newval;
- NODE *tmp;
- NODE **ret = (NODE **) ! NULL;
-
- tmp = force_string(opt);
- (void) force_number(val);
- if (STREQ(tmp->stptr, "INT_CHAIN_MAX")) {
- newval = (int) val->numbr;
- if (newval > 0)
- INT_CHAIN_MAX = newval;
- } else
- ret = NULL;
- return ret;
-}
-#endif
diff --git a/interpret.h b/interpret.h
new file mode 100644
index 00000000..3a9cab37
--- /dev/null
+++ b/interpret.h
@@ -0,0 +1,1427 @@
+/*
+ * interpret.h --- run a list of instructions.
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991-2014 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 3 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 UNFIELD(l, r) \
+{ \
+ /* if was a field, turn it into a var */ \
+ if ((r->flags & FIELD) == 0) { \
+ l = r; \
+ } else if (r->valref == 1) { \
+ r->flags &= ~FIELD; \
+ l = r; \
+ } else { \
+ l = dupnode(r); \
+ DEREF(r); \
+ } \
+}
+int
+r_interpret(INSTRUCTION *code)
+{
+ INSTRUCTION *pc; /* current instruction */
+ OPCODE op; /* current opcode */
+ NODE *r = NULL;
+ NODE *m;
+ INSTRUCTION *ni;
+ NODE *t1, *t2;
+ NODE **lhs;
+ AWKNUM x, x2;
+ int di;
+ Regexp *rp;
+ NODE *set_array = NULL; /* array with a post-assignment routine */
+ NODE *set_idx = NULL; /* the index of the array element */
+
+
+/* array subscript */
+#define mk_sub(n) (n == 1 ? POP_SCALAR() : concat_exp(n, true))
+
+#ifdef EXEC_HOOK
+#define JUMPTO(x) do { if (post_execute) post_execute(pc); pc = (x); goto top; } while (false)
+#else
+#define JUMPTO(x) do { pc = (x); goto top; } while (false)
+#endif
+
+ pc = code;
+
+ /* N.B.: always use JUMPTO for next instruction, otherwise bad things
+ * may happen. DO NOT add a real loop (for/while) below to
+ * replace ' forever {'; this catches failure to use JUMPTO to execute
+ * next instruction (e.g. continue statement).
+ */
+
+ /* loop until hit Op_stop instruction */
+
+ /* forever { */
+top:
+ if (pc->source_line > 0)
+ sourceline = pc->source_line;
+
+#ifdef EXEC_HOOK
+ for (di = 0; di < num_exec_hook; di++) {
+ if (! pre_execute[di](& pc))
+ goto top;
+ }
+#endif
+
+ switch ((op = pc->opcode)) {
+ case Op_rule:
+ currule = pc->in_rule; /* for sole use in Op_K_next, Op_K_nextfile, Op_K_getline */
+ /* fall through */
+ case Op_func:
+ source = pc->source_file;
+ break;
+
+ case Op_atexit:
+ {
+ bool stdio_problem = false;
+
+ /* avoid false source indications */
+ source = NULL;
+ sourceline = 0;
+ (void) nextfile(& curfile, true); /* close input data file */
+ /*
+ * 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;
+
+ close_extensions();
+ }
+ break;
+
+ case Op_stop:
+ return 0;
+
+ case Op_push_i:
+ m = pc->memory;
+ if (! do_traditional && (m->flags & INTLSTR) != 0) {
+ char *orig, *trans, save;
+
+ save = m->stptr[m->stlen];
+ m->stptr[m->stlen] = '\0';
+ orig = m->stptr;
+ trans = dgettext(TEXTDOMAIN, orig);
+ m->stptr[m->stlen] = save;
+ m = make_string(trans, strlen(trans));
+ } else
+ UPREF(m);
+ PUSH(m);
+ break;
+
+ case Op_push:
+ case Op_push_arg:
+ {
+ NODE *save_symbol;
+ bool isparam = false;
+
+ save_symbol = m = pc->memory;
+ if (m->type == Node_param_list) {
+ isparam = true;
+ save_symbol = m = GET_PARAM(m->param_cnt);
+ if (m->type == Node_array_ref) {
+ if (m->orig_array->type == Node_var) {
+ /* gawk 'func f(x) { a = 10; print x; } BEGIN{ f(a) }' */
+ goto uninitialized_scalar;
+ }
+ m = m->orig_array;
+ }
+ }
+
+ switch (m->type) {
+ case Node_var:
+ if (do_lint && var_uninitialized(m))
+ lintwarn(isparam ?
+ _("reference to uninitialized argument `%s'") :
+ _("reference to uninitialized variable `%s'"),
+ save_symbol->vname);
+ m = m->var_value;
+ UPREF(m);
+ PUSH(m);
+ break;
+
+ case Node_var_new:
+uninitialized_scalar:
+ m->type = Node_var;
+ m->var_value = dupnode(Nnull_string);
+ if (do_lint)
+ lintwarn(isparam ?
+ _("reference to uninitialized argument `%s'") :
+ _("reference to uninitialized variable `%s'"),
+ save_symbol->vname);
+ m = dupnode(Nnull_string);
+ PUSH(m);
+ break;
+
+ case Node_var_array:
+ if (op == Op_push_arg)
+ PUSH(m);
+ else
+ fatal(_("attempt to use array `%s' in a scalar context"),
+ array_vname(save_symbol));
+ break;
+
+ default:
+ cant_happen();
+ }
+ }
+ break;
+
+ case Op_push_param: /* function argument */
+ m = pc->memory;
+ if (m->type == Node_param_list)
+ m = GET_PARAM(m->param_cnt);
+ if (m->type == Node_var) {
+ m = m->var_value;
+ UPREF(m);
+ PUSH(m);
+ break;
+ }
+ /* else
+ fall through */
+ case Op_push_array:
+ PUSH(pc->memory);
+ break;
+
+ case Op_push_lhs:
+ lhs = get_lhs(pc->memory, pc->do_reference);
+ PUSH_ADDRESS(lhs);
+ break;
+
+ case Op_subscript:
+ t2 = mk_sub(pc->sub_count);
+ t1 = POP_ARRAY();
+
+ if (do_lint && in_array(t1, t2) == NULL) {
+ t2 = force_string(t2);
+ lintwarn(_("reference to uninitialized element `%s[\"%.*s\"]'"),
+ array_vname(t1), (int) t2->stlen, t2->stptr);
+ if (t2->stlen == 0)
+ lintwarn(_("subscript of array `%s' is null string"), array_vname(t1));
+ }
+
+ /* for FUNCTAB, get the name as the element value */
+ if (t1 == func_table) {
+ static bool warned = false;
+
+ if (do_lint && ! warned) {
+ warned = true;
+ lintwarn(_("FUNCTAB is a gawk extension"));
+ }
+ r = t2;
+ } else {
+ /* make sure stuff like NF, NR, are up to date */
+ if (t1 == symbol_table)
+ update_global_values();
+
+ r = *assoc_lookup(t1, t2);
+ }
+ DEREF(t2);
+
+ /* for SYMTAB, step through to the actual variable */
+ if (t1 == symbol_table) {
+ static bool warned = false;
+
+ if (do_lint && ! warned) {
+ warned = true;
+ lintwarn(_("SYMTAB is a gawk extension"));
+ }
+ if (r->type == Node_var)
+ r = r->var_value;
+ }
+
+ if (r->type == Node_val)
+ UPREF(r);
+ PUSH(r);
+ break;
+
+ case Op_sub_array:
+ t2 = mk_sub(pc->sub_count);
+ t1 = POP_ARRAY();
+ r = in_array(t1, t2);
+ if (r == NULL) {
+ r = make_array();
+ r->parent_array = t1;
+ lhs = assoc_lookup(t1, t2);
+ unref(*lhs);
+ *lhs = r;
+ t2 = force_string(t2);
+ r->vname = estrdup(t2->stptr, t2->stlen); /* the subscript in parent array */
+
+ /* execute post-assignment routine if any */
+ if (t1->astore != NULL)
+ (*t1->astore)(t1, t2);
+ } else if (r->type != Node_var_array) {
+ t2 = force_string(t2);
+ fatal(_("attempt to use scalar `%s[\"%.*s\"]' as an array"),
+ array_vname(t1), (int) t2->stlen, t2->stptr);
+ }
+
+ DEREF(t2);
+ PUSH(r);
+ break;
+
+ case Op_subscript_lhs:
+ t2 = mk_sub(pc->sub_count);
+ t1 = POP_ARRAY();
+ if (do_lint && in_array(t1, t2) == NULL) {
+ t2 = force_string(t2);
+ if (pc->do_reference)
+ lintwarn(_("reference to uninitialized element `%s[\"%.*s\"]'"),
+ array_vname(t1), (int) t2->stlen, t2->stptr);
+ if (t2->stlen == 0)
+ lintwarn(_("subscript of array `%s' is null string"), array_vname(t1));
+ }
+
+ lhs = assoc_lookup(t1, t2);
+ if ((*lhs)->type == Node_var_array) {
+ t2 = force_string(t2);
+ fatal(_("attempt to use array `%s[\"%.*s\"]' in a scalar context"),
+ array_vname(t1), (int) t2->stlen, t2->stptr);
+ }
+
+ /*
+ * Changing something in FUNCTAB is not allowed.
+ *
+ * SYMTAB is a little more messy. Three kinds of values may
+ * be stored in SYMTAB:
+ * 1. Variables that don"t yet have a value (Node_var_new)
+ * 2. Variables that have a value (Node_var)
+ * 3. Values that awk code stuck into SYMTAB not related to variables (Node_value)
+ * For 1, since we are giving it a value, we have to change the type to Node_var.
+ * For 1 and 2, we have to step through the Node_var to get to the value.
+ * For 3, we just us the value we got from assoc_lookup(), above.
+ */
+ if (t1 == func_table)
+ fatal(_("cannot assign to elements of FUNCTAB"));
+ else if ( t1 == symbol_table
+ && ( (*lhs)->type == Node_var
+ || (*lhs)->type == Node_var_new)) {
+ update_global_values(); /* make sure stuff like NF, NR, are up to date */
+ (*lhs)->type = Node_var; /* in case was Node_var_new */
+ lhs = & ((*lhs)->var_value); /* extra level of indirection */
+ }
+
+ assert(set_idx == NULL);
+
+ if (t1->astore) {
+ /* array has post-assignment routine */
+ set_array = t1;
+ set_idx = t2;
+ } else
+ DEREF(t2);
+
+ PUSH_ADDRESS(lhs);
+ break;
+
+ case Op_field_spec:
+ t1 = TOP_SCALAR();
+ lhs = r_get_field(t1, (Func_ptr *) 0, true);
+ decr_sp();
+ DEREF(t1);
+ /* only for $0, up ref count */
+ if (*lhs == fields_arr[0]) {
+ r = *lhs;
+ UPREF(r);
+ } else
+ r = dupnode(*lhs);
+ PUSH(r);
+ break;
+
+ case Op_field_spec_lhs:
+ t1 = TOP_SCALAR();
+ lhs = r_get_field(t1, &pc->target_assign->field_assign, pc->do_reference);
+ decr_sp();
+ DEREF(t1);
+ PUSH_ADDRESS(lhs);
+ break;
+
+ case Op_lint:
+ if (do_lint) {
+ switch (pc->lint_type) {
+ case LINT_assign_in_cond:
+ lintwarn(_("assignment used in conditional context"));
+ break;
+
+ case LINT_no_effect:
+ lintwarn(_("statement has no effect"));
+ break;
+
+ default:
+ cant_happen();
+ }
+ }
+ break;
+
+ case Op_K_break:
+ case Op_K_continue:
+ case Op_jmp:
+ assert(pc->target_jmp != NULL);
+ JUMPTO(pc->target_jmp);
+
+ case Op_jmp_false:
+ r = POP_SCALAR();
+ di = eval_condition(r);
+ DEREF(r);
+ if (! di)
+ JUMPTO(pc->target_jmp);
+ break;
+
+ case Op_jmp_true:
+ r = POP_SCALAR();
+ di = eval_condition(r);
+ DEREF(r);
+ if (di)
+ JUMPTO(pc->target_jmp);
+ break;
+
+ case Op_and:
+ case Op_or:
+ t1 = POP_SCALAR();
+ di = eval_condition(t1);
+ DEREF(t1);
+ if ((op == Op_and && di) || (op == Op_or && ! di))
+ break;
+ r = node_Boolean[di];
+ UPREF(r);
+ PUSH(r);
+ ni = pc->target_jmp;
+ JUMPTO(ni->nexti);
+
+ case Op_and_final:
+ case Op_or_final:
+ t1 = TOP_SCALAR();
+ r = node_Boolean[eval_condition(t1)];
+ DEREF(t1);
+ UPREF(r);
+ REPLACE(r);
+ break;
+
+ case Op_not:
+ t1 = TOP_SCALAR();
+ r = node_Boolean[! eval_condition(t1)];
+ DEREF(t1);
+ UPREF(r);
+ REPLACE(r);
+ break;
+
+ case Op_equal:
+ r = node_Boolean[cmp_scalars() == 0];
+ UPREF(r);
+ REPLACE(r);
+ break;
+
+ case Op_notequal:
+ r = node_Boolean[cmp_scalars() != 0];
+ UPREF(r);
+ REPLACE(r);
+ break;
+
+ case Op_less:
+ r = node_Boolean[cmp_scalars() < 0];
+ UPREF(r);
+ REPLACE(r);
+ break;
+
+ case Op_greater:
+ r = node_Boolean[cmp_scalars() > 0];
+ UPREF(r);
+ REPLACE(r);
+ break;
+
+ case Op_leq:
+ r = node_Boolean[cmp_scalars() <= 0];
+ UPREF(r);
+ REPLACE(r);
+ break;
+
+ case Op_geq:
+ r = node_Boolean[cmp_scalars() >= 0];
+ UPREF(r);
+ REPLACE(r);
+ break;
+
+ case Op_plus_i:
+ x2 = force_number(pc->memory)->numbr;
+ goto plus;
+ case Op_plus:
+ t2 = POP_NUMBER();
+ x2 = t2->numbr;
+ DEREF(t2);
+plus:
+ t1 = TOP_NUMBER();
+ r = make_number(t1->numbr + x2);
+ DEREF(t1);
+ REPLACE(r);
+ break;
+
+ case Op_minus_i:
+ x2 = force_number(pc->memory)->numbr;
+ goto minus;
+ case Op_minus:
+ t2 = POP_NUMBER();
+ x2 = t2->numbr;
+ DEREF(t2);
+minus:
+ t1 = TOP_NUMBER();
+ r = make_number(t1->numbr - x2);
+ DEREF(t1);
+ REPLACE(r);
+ break;
+
+ case Op_times_i:
+ x2 = force_number(pc->memory)->numbr;
+ goto times;
+ case Op_times:
+ t2 = POP_NUMBER();
+ x2 = t2->numbr;
+ DEREF(t2);
+times:
+ t1 = TOP_NUMBER();
+ r = make_number(t1->numbr * x2);
+ DEREF(t1);
+ REPLACE(r);
+ break;
+
+ case Op_exp_i:
+ x2 = force_number(pc->memory)->numbr;
+ goto exp;
+ case Op_exp:
+ t2 = POP_NUMBER();
+ x2 = t2->numbr;
+ DEREF(t2);
+exp:
+ t1 = TOP_NUMBER();
+ r = make_number(calc_exp(t1->numbr, x2));
+ DEREF(t1);
+ REPLACE(r);
+ break;
+
+ case Op_quotient_i:
+ x2 = force_number(pc->memory)->numbr;
+ goto quotient;
+ case Op_quotient:
+ t2 = POP_NUMBER();
+ x2 = t2->numbr;
+ DEREF(t2);
+quotient:
+ t1 = TOP_NUMBER();
+ if (x2 == 0)
+ fatal(_("division by zero attempted"));
+ r = make_number(t1->numbr / x2);
+ DEREF(t1);
+ REPLACE(r);
+ break;
+
+ case Op_mod_i:
+ x2 = force_number(pc->memory)->numbr;
+ goto mod;
+ case Op_mod:
+ t2 = POP_NUMBER();
+ x2 = t2->numbr;
+ DEREF(t2);
+mod:
+ t1 = TOP_NUMBER();
+ if (x2 == 0)
+ fatal(_("division by zero attempted in `%%'"));
+#ifdef HAVE_FMOD
+ x = fmod(t1->numbr, x2);
+#else /* ! HAVE_FMOD */
+ (void) modf(t1->numbr / x2, &x);
+ x = t1->numbr - x * x2;
+#endif /* ! HAVE_FMOD */
+ r = make_number(x);
+
+ DEREF(t1);
+ REPLACE(r);
+ break;
+
+ case Op_preincrement:
+ case Op_predecrement:
+ x = op == Op_preincrement ? 1.0 : -1.0;
+ lhs = TOP_ADDRESS();
+ t1 = *lhs;
+ force_number(t1);
+ if (t1->valref == 1 && t1->flags == (MALLOC|NUMCUR|NUMBER)) {
+ /* optimization */
+ t1->numbr += x;
+ r = t1;
+ } else {
+ r = *lhs = make_number(t1->numbr + x);
+ unref(t1);
+ }
+ UPREF(r);
+ REPLACE(r);
+ break;
+
+ case Op_postincrement:
+ case Op_postdecrement:
+ x = op == Op_postincrement ? 1.0 : -1.0;
+ lhs = TOP_ADDRESS();
+ t1 = *lhs;
+ force_number(t1);
+ r = make_number(t1->numbr);
+ if (t1->valref == 1 && t1->flags == (MALLOC|NUMCUR|NUMBER)) {
+ /* optimization */
+ t1->numbr += x;
+ } else {
+ *lhs = make_number(t1->numbr + x);
+ unref(t1);
+ }
+ REPLACE(r);
+ break;
+
+ case Op_unary_minus:
+ t1 = TOP_NUMBER();
+ r = make_number(-t1->numbr);
+ DEREF(t1);
+ REPLACE(r);
+ break;
+
+ case Op_store_sub:
+ /*
+ * array[sub] assignment optimization,
+ * see awkgram.y (optimize_assignment)
+ */
+ t1 = force_array(pc->memory, true); /* array */
+ t2 = mk_sub(pc->expr_count); /* subscript */
+ lhs = assoc_lookup(t1, t2);
+ if ((*lhs)->type == Node_var_array) {
+ t2 = force_string(t2);
+ fatal(_("attempt to use array `%s[\"%.*s\"]' in a scalar context"),
+ array_vname(t1), (int) t2->stlen, t2->stptr);
+ }
+ DEREF(t2);
+
+ /*
+ * Changing something in FUNCTAB is not allowed.
+ *
+ * SYMTAB is a little more messy. Three kinds of values may
+ * be stored in SYMTAB:
+ * 1. Variables that don"t yet have a value (Node_var_new)
+ * 2. Variables that have a value (Node_var)
+ * 3. Values that awk code stuck into SYMTAB not related to variables (Node_value)
+ * For 1, since we are giving it a value, we have to change the type to Node_var.
+ * For 1 and 2, we have to step through the Node_var to get to the value.
+ * For 3, we just us the value we got from assoc_lookup(), above.
+ */
+ if (t1 == func_table)
+ fatal(_("cannot assign to elements of FUNCTAB"));
+ else if ( t1 == symbol_table
+ && ( (*lhs)->type == Node_var
+ || (*lhs)->type == Node_var_new)) {
+ (*lhs)->type = Node_var; /* in case was Node_var_new */
+ lhs = & ((*lhs)->var_value); /* extra level of indirection */
+ }
+
+ unref(*lhs);
+ r = POP_SCALAR();
+ UNFIELD(*lhs, r);
+
+ /* execute post-assignment routine if any */
+ if (t1->astore != NULL)
+ (*t1->astore)(t1, t2);
+
+ DEREF(t2);
+ break;
+
+ case Op_store_var:
+ /*
+ * simple variable assignment optimization,
+ * see awkgram.y (optimize_assignment)
+ */
+
+ lhs = get_lhs(pc->memory, false);
+ unref(*lhs);
+ r = pc->initval; /* constant initializer */
+ if (r != NULL) {
+ UPREF(r);
+ *lhs = r;
+ } else {
+ r = POP_SCALAR();
+ UNFIELD(*lhs, r);
+ }
+ break;
+
+ case Op_store_field:
+ {
+ /* field assignment optimization,
+ * see awkgram.y (optimize_assignment)
+ */
+
+ Func_ptr assign;
+ t1 = TOP_SCALAR();
+ lhs = r_get_field(t1, & assign, false);
+ decr_sp();
+ DEREF(t1);
+ unref(*lhs);
+ r = POP_SCALAR();
+ UNFIELD(*lhs, r);
+ assert(assign != NULL);
+ assign();
+ }
+ break;
+
+ case Op_assign_concat:
+ /* x = x ... string concatenation optimization */
+ lhs = get_lhs(pc->memory, false);
+ t1 = force_string(*lhs);
+ t2 = POP_STRING();
+
+ if (t1 != *lhs) {
+ unref(*lhs);
+ *lhs = dupnode(t1);
+ }
+
+ if (t1 != t2 && t1->valref == 1 && (t1->flags & MPFN) == 0) {
+ size_t nlen = t1->stlen + t2->stlen;
+
+ erealloc(t1->stptr, char *, nlen + 2, "r_interpret");
+ memcpy(t1->stptr + t1->stlen, t2->stptr, t2->stlen);
+ t1->stlen = nlen;
+ t1->stptr[nlen] = '\0';
+ t1->flags &= ~(NUMCUR|NUMBER|NUMINT);
+
+ if ((t1->flags & WSTRCUR) != 0 && (t2->flags & WSTRCUR) != 0) {
+ size_t wlen = t1->wstlen + t2->wstlen;
+
+ erealloc(t1->wstptr, wchar_t *,
+ sizeof(wchar_t) * (wlen + 2), "r_interpret");
+ memcpy(t1->wstptr + t1->wstlen, t2->wstptr, t2->wstlen);
+ t1->wstlen = wlen;
+ t1->wstptr[wlen] = L'\0';
+ t1->flags |= WSTRCUR;
+ } else
+ free_wstr(*lhs);
+ } else {
+ size_t nlen = t1->stlen + t2->stlen;
+ char *p;
+
+ emalloc(p, char *, nlen + 2, "r_interpret");
+ memcpy(p, t1->stptr, t1->stlen);
+ memcpy(p + t1->stlen, t2->stptr, t2->stlen);
+ unref(*lhs);
+ t1 = *lhs = make_str_node(p, nlen, ALREADY_MALLOCED);
+ }
+ DEREF(t2);
+ break;
+
+ case Op_assign:
+ lhs = POP_ADDRESS();
+ r = TOP_SCALAR();
+ unref(*lhs);
+ UPREF(r);
+ UNFIELD(*lhs, r);
+ REPLACE(r);
+ break;
+
+ case Op_subscript_assign:
+ /* conditionally execute post-assignment routine for an array element */
+
+ if (set_idx != NULL) {
+ di = true;
+ if (pc->assign_ctxt == Op_sub_builtin
+ && (r = TOP())
+ && get_number_si(r) == 0 /* no substitution performed */
+ )
+ di = false;
+ else if ((pc->assign_ctxt == Op_K_getline
+ || pc->assign_ctxt == Op_K_getline_redir)
+ && (r = TOP())
+ && get_number_si(r) <= 0 /* EOF or error */
+ )
+ di = false;
+
+ if (di)
+ (*set_array->astore)(set_array, set_idx);
+ unref(set_idx);
+ set_idx = NULL;
+ }
+ break;
+
+ /* numeric assignments */
+ case Op_assign_plus:
+ case Op_assign_minus:
+ case Op_assign_times:
+ case Op_assign_quotient:
+ case Op_assign_mod:
+ case Op_assign_exp:
+ op_assign(op);
+ break;
+
+ case Op_var_update: /* update value of NR, FNR or NF */
+ pc->update_var();
+ break;
+
+ case Op_var_assign:
+ case Op_field_assign:
+ r = TOP();
+ if (pc->assign_ctxt == Op_sub_builtin
+ && get_number_si(r) == 0 /* top of stack has a number == 0 */
+ ) {
+ /* There wasn't any substitutions. If the target is a FIELD,
+ * this means no field re-splitting or $0 reconstruction.
+ * Skip the set_FOO routine if the target is a special variable.
+ */
+
+ break;
+ } else if ((pc->assign_ctxt == Op_K_getline
+ || pc->assign_ctxt == Op_K_getline_redir)
+ && get_number_si(r) <= 0 /* top of stack has a number <= 0 */
+ ) {
+ /* getline returned EOF or error */
+
+ break;
+ }
+
+ if (op == Op_var_assign)
+ pc->assign_var();
+ else
+ pc->field_assign();
+ break;
+
+ case Op_concat:
+ r = concat_exp(pc->expr_count, pc->concat_flag & CSUBSEP);
+ PUSH(r);
+ break;
+
+ case Op_K_case:
+ if ((pc + 1)->match_exp) {
+ /* match a constant regex against switch expression instead of $0. */
+
+ m = POP(); /* regex */
+ t2 = TOP_SCALAR(); /* switch expression */
+ t2 = force_string(t2);
+ rp = re_update(m);
+ di = (research(rp, t2->stptr, 0, t2->stlen,
+ avoid_dfa(m, t2->stptr, t2->stlen)) >= 0);
+ } else {
+ t1 = POP_SCALAR(); /* case value */
+ t2 = TOP_SCALAR(); /* switch expression */
+ di = (cmp_nodes(t2, t1) == 0);
+ DEREF(t1);
+ }
+
+ if (di) {
+ /* match found */
+ t2 = POP_SCALAR();
+ DEREF(t2);
+ JUMPTO(pc->target_jmp);
+ }
+ break;
+
+ case Op_K_delete:
+ t1 = POP_ARRAY();
+ do_delete(t1, pc->expr_count);
+ stack_adj(-pc->expr_count);
+ break;
+
+ case Op_K_delete_loop:
+ t1 = POP_ARRAY();
+ lhs = POP_ADDRESS(); /* item */
+ do_delete_loop(t1, lhs);
+ break;
+
+ case Op_in_array:
+ t1 = POP_ARRAY();
+ t2 = mk_sub(pc->expr_count);
+ r = node_Boolean[(in_array(t1, t2) != NULL)];
+ DEREF(t2);
+ UPREF(r);
+ PUSH(r);
+ break;
+
+ case Op_arrayfor_init:
+ {
+ NODE **list = NULL;
+ NODE *array, *sort_str;
+ size_t num_elems = 0;
+ static NODE *sorted_in = NULL;
+ const char *how_to_sort = "@unsorted";
+
+ /* get the array */
+ array = POP_ARRAY();
+
+ /* sanity: check if empty */
+ num_elems = assoc_length(array);
+ if (num_elems == 0)
+ goto arrayfor;
+
+ if (sorted_in == NULL) /* do this once */
+ sorted_in = make_string("sorted_in", 9);
+
+ sort_str = NULL;
+ /*
+ * If posix, or if there's no PROCINFO[],
+ * there's no ["sorted_in"], so no sorting
+ */
+ if (! do_posix && PROCINFO_node != NULL)
+ sort_str = in_array(PROCINFO_node, sorted_in);
+
+ if (sort_str != NULL) {
+ sort_str = force_string(sort_str);
+ if (sort_str->stlen > 0)
+ how_to_sort = sort_str->stptr;
+ }
+
+ list = assoc_list(array, how_to_sort, SORTED_IN);
+
+arrayfor:
+ getnode(r);
+ r->type = Node_arrayfor;
+ r->for_list = list;
+ r->for_list_size = num_elems; /* # of elements in list */
+ r->cur_idx = -1; /* current index */
+ r->for_array = array; /* array */
+ PUSH(r);
+
+ if (num_elems == 0)
+ JUMPTO(pc->target_jmp); /* Op_arrayfor_final */
+ }
+ break;
+
+ case Op_arrayfor_incr:
+ r = TOP(); /* Node_arrayfor */
+ if (++r->cur_idx == r->for_list_size) {
+ NODE *array;
+ array = r->for_array; /* actual array */
+ if (do_lint && array->table_size != r->for_list_size)
+ lintwarn(_("for loop: array `%s' changed size from %ld to %ld during loop execution"),
+ array_vname(array), (long) r->for_list_size, (long) array->table_size);
+ JUMPTO(pc->target_jmp); /* Op_arrayfor_final */
+ }
+
+ t1 = r->for_list[r->cur_idx];
+ lhs = get_lhs(pc->array_var, false);
+ unref(*lhs);
+ *lhs = dupnode(t1);
+ break;
+
+ case Op_arrayfor_final:
+ r = POP();
+ assert(r->type == Node_arrayfor);
+ free_arrayfor(r);
+ break;
+
+ case Op_builtin:
+ r = pc->builtin(pc->expr_count);
+ PUSH(r);
+ break;
+
+ case Op_ext_builtin:
+ case Op_old_ext_builtin:
+ {
+ int arg_count = pc->expr_count;
+ awk_value_t result;
+
+ PUSH_CODE(pc);
+ if (op == Op_ext_builtin)
+ r = awk_value_to_node(pc->extfunc(arg_count, & result));
+ else
+ r = pc->builtin(arg_count);
+ (void) POP_CODE();
+ while (arg_count-- > 0) {
+ t1 = POP();
+ if (t1->type == Node_val)
+ DEREF(t1);
+ }
+ PUSH(r);
+ }
+ break;
+
+ case Op_sub_builtin: /* sub, gsub and gensub */
+ r = do_sub(pc->expr_count, pc->sub_flags);
+ PUSH(r);
+ break;
+
+ case Op_K_print:
+ do_print(pc->expr_count, pc->redir_type);
+ break;
+
+ case Op_K_printf:
+ do_printf(pc->expr_count, pc->redir_type);
+ break;
+
+ case Op_K_print_rec:
+ do_print_rec(pc->expr_count, pc->redir_type);
+ break;
+
+ case Op_push_re:
+ m = pc->memory;
+ if (m->type == Node_dynregex) {
+ r = POP_STRING();
+ unref(m->re_exp);
+ m->re_exp = r;
+ }
+ PUSH(m);
+ break;
+
+ case Op_match_rec:
+ m = pc->memory;
+ t1 = *get_field(0, (Func_ptr *) 0);
+match_re:
+ rp = re_update(m);
+ /*
+ * 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 Op_K_case.
+ *
+ * A new or improved dfa that distinguishes beginning/end of
+ * string from beginning/end of line will allow us to get rid of
+ * this hack.
+ *
+ * The avoid_dfa() function is in re.c; it is not very smart.
+ */
+
+ di = research(rp, t1->stptr, 0, t1->stlen,
+ avoid_dfa(m, t1->stptr, t1->stlen));
+ di = (di == -1) ^ (op != Op_nomatch);
+ if (op != Op_match_rec) {
+ decr_sp();
+ DEREF(t1);
+ }
+ r = node_Boolean[di];
+ UPREF(r);
+ PUSH(r);
+ break;
+
+ case Op_nomatch:
+ /* fall through */
+ case Op_match:
+ m = pc->memory;
+ t1 = TOP_STRING();
+ if (m->type == Node_dynregex) {
+ unref(m->re_exp);
+ m->re_exp = t1;
+ decr_sp();
+ t1 = TOP_STRING();
+ }
+ goto match_re;
+ break;
+
+ case Op_indirect_func_call:
+ {
+ NODE *f = NULL;
+ int arg_count;
+
+ arg_count = (pc + 1)->expr_count;
+ t1 = PEEK(arg_count); /* indirect var */
+
+ if (t1->type != Node_val) /* @a[1](p) not allowed in grammar */
+ fatal(_("indirect function call requires a simple scalar value"));
+
+ t1 = force_string(t1);
+ if (t1->stlen > 0) {
+ /* retrieve function definition node */
+ f = pc->func_body;
+ if (f != NULL && strcmp(f->vname, t1->stptr) == 0) {
+ /* indirect var hasn't been reassigned */
+
+ ni = setup_frame(pc);
+ JUMPTO(ni); /* Op_func */
+ }
+ f = lookup(t1->stptr);
+ }
+
+ if (f == NULL) {
+ fatal(_("`%s' is not a function, so it cannot be called indirectly"),
+ t1->stptr);
+ } else if (f->type == Node_builtin_func) {
+ int arg_count = (pc + 1)->expr_count;
+ builtin_func_t the_func = lookup_builtin(t1->stptr);
+
+ assert(the_func != NULL);
+
+ /* call it */
+ r = the_func(arg_count);
+ PUSH(r);
+ break;
+ } else if (f->type != Node_func) {
+ if ( f->type == Node_ext_func
+ || f->type == Node_old_ext_func) {
+ /* code copied from below, keep in sync */
+ INSTRUCTION *bc;
+ char *fname = pc->func_name;
+ int arg_count = (pc + 1)->expr_count;
+ static INSTRUCTION npc[2];
+
+ npc[0] = *pc;
+
+ bc = f->code_ptr;
+ assert(bc->opcode == Op_symbol);
+ if (f->type == Node_ext_func)
+ npc[0].opcode = Op_ext_builtin; /* self modifying code */
+ else
+ npc[0].opcode = Op_old_ext_builtin; /* self modifying code */
+ npc[0].extfunc = bc->extfunc;
+ npc[0].expr_count = arg_count; /* actual argument count */
+ npc[1] = pc[1];
+ npc[1].func_name = fname; /* name of the builtin */
+ npc[1].expr_count = bc->expr_count; /* defined max # of arguments */
+ ni = npc;
+ JUMPTO(ni);
+ } else
+ fatal(_("function called indirectly through `%s' does not exist"),
+ pc->func_name);
+ }
+ pc->func_body = f; /* save for next call */
+
+ ni = setup_frame(pc);
+ JUMPTO(ni); /* Op_func */
+ }
+
+ case Op_func_call:
+ {
+ NODE *f;
+
+ /* retrieve function definition node */
+ f = pc->func_body;
+ if (f == NULL) {
+ f = lookup(pc->func_name);
+ if (f == NULL || (f->type != Node_func && f->type != Node_ext_func && f->type != Node_old_ext_func))
+ fatal(_("function `%s' not defined"), pc->func_name);
+ pc->func_body = f; /* save for next call */
+ }
+
+ if (f->type == Node_ext_func || f->type == Node_old_ext_func) {
+ /* keep in sync with indirect call code */
+ INSTRUCTION *bc;
+ char *fname = pc->func_name;
+ int arg_count = (pc + 1)->expr_count;
+
+ bc = f->code_ptr;
+ assert(bc->opcode == Op_symbol);
+ if (f->type == Node_ext_func)
+ pc->opcode = Op_ext_builtin; /* self modifying code */
+ else
+ pc->opcode = Op_old_ext_builtin; /* self modifying code */
+ pc->extfunc = bc->extfunc;
+ pc->expr_count = arg_count; /* actual argument count */
+ (pc + 1)->func_name = fname; /* name of the builtin */
+ (pc + 1)->expr_count = bc->expr_count; /* defined max # of arguments */
+ ni = pc;
+ JUMPTO(ni);
+ }
+
+ ni = setup_frame(pc);
+ JUMPTO(ni); /* Op_func */
+ }
+
+ case Op_K_return:
+ m = POP_SCALAR(); /* return value */
+
+ ni = pop_fcall();
+
+ /* put the return value back on stack */
+ PUSH(m);
+
+ JUMPTO(ni);
+
+ case Op_K_getline_redir:
+ r = do_getline_redir(pc->into_var, pc->redir_type);
+ PUSH(r);
+ break;
+
+ case Op_K_getline: /* no redirection */
+ if (! currule || currule == BEGINFILE || currule == ENDFILE)
+ fatal(_("non-redirected `getline' invalid inside `%s' rule"),
+ ruletab[currule]);
+
+ do {
+ int ret;
+ ret = nextfile(& curfile, false);
+ if (ret <= 0)
+ r = do_getline(pc->into_var, curfile);
+ else {
+
+ /* Save execution state so that we can return to it
+ * from Op_after_beginfile or Op_after_endfile.
+ */
+
+ push_exec_state(pc, currule, source, stack_ptr);
+
+ if (curfile == NULL)
+ JUMPTO((pc + 1)->target_endfile);
+ else
+ JUMPTO((pc + 1)->target_beginfile);
+ }
+ } while (r == NULL); /* EOF */
+
+ PUSH(r);
+ break;
+
+ case Op_after_endfile:
+ /* Find the execution state to return to */
+ ni = pop_exec_state(& currule, & source, NULL);
+
+ assert(ni->opcode == Op_newfile || ni->opcode == Op_K_getline);
+ JUMPTO(ni);
+
+ case Op_after_beginfile:
+ after_beginfile(& curfile);
+
+ /* Find the execution state to return to */
+ ni = pop_exec_state(& currule, & source, NULL);
+
+ assert(ni->opcode == Op_newfile || ni->opcode == Op_K_getline);
+ if (ni->opcode == Op_K_getline
+ || curfile == NULL /* skipping directory argument */
+ )
+ JUMPTO(ni);
+
+ break; /* read a record, Op_get_record */
+
+ case Op_newfile:
+ {
+ int ret;
+
+ ret = nextfile(& curfile, false);
+
+ if (ret < 0) /* end of input */
+ JUMPTO(pc->target_jmp); /* end block or Op_atexit */
+
+ if (ret == 0) /* read a record */
+ JUMPTO((pc + 1)->target_get_record);
+
+ /* ret > 0 */
+ /* Save execution state for use in Op_after_beginfile or Op_after_endfile. */
+
+ push_exec_state(pc, currule, source, stack_ptr);
+
+ if (curfile == NULL) /* EOF */
+ JUMPTO(pc->target_endfile);
+ /* else
+ execute beginfile block */
+ }
+ break;
+
+ case Op_get_record:
+ {
+ int errcode = 0;
+
+ ni = pc->target_newfile;
+ if (curfile == NULL) {
+ /* from non-redirected getline, e.g.:
+ * {
+ * while (getline > 0) ;
+ * }
+ */
+
+ ni = ni->target_jmp; /* end_block or Op_atexit */
+ JUMPTO(ni);
+ }
+
+ if (! inrec(curfile, & errcode)) {
+ if (errcode > 0) {
+ update_ERRNO_int(errcode);
+ if (do_traditional || ! pc->has_endfile)
+ fatal(_("error reading input file `%s': %s"),
+ curfile->public.name, strerror(errcode));
+ }
+
+ JUMPTO(ni);
+ } /* else
+ prog (rule) block */
+ }
+ break;
+
+ case Op_K_nextfile:
+ {
+ int ret;
+
+ if (currule != Rule && currule != BEGINFILE)
+ fatal(_("`nextfile' cannot be called from a `%s' rule"),
+ ruletab[currule]);
+
+ ret = nextfile(& curfile, true); /* skip current file */
+
+ if (currule == BEGINFILE) {
+ long stack_size = 0;
+
+ ni = pop_exec_state(& currule, & source, & stack_size);
+
+ assert(ni->opcode == Op_K_getline || ni->opcode == Op_newfile);
+
+ /* pop stack returning to the state of Op_K_getline or Op_newfile. */
+ unwind_stack(stack_size);
+
+ if (ret == 0) {
+ /* There was an error opening the file;
+ * don't run ENDFILE block(s).
+ */
+
+ JUMPTO(ni);
+ } else {
+ /* do run ENDFILE block(s) first. */
+
+ /* Execution state to return to in Op_after_endfile. */
+ push_exec_state(ni, currule, source, stack_ptr);
+
+ JUMPTO(pc->target_endfile);
+ }
+ } /* else
+ Start over with the first rule. */
+
+ /* empty the run-time stack to avoid memory leak */
+ pop_stack();
+
+ /* Push an execution state for Op_after_endfile to return to */
+ push_exec_state(pc->target_newfile, currule, source, stack_ptr);
+
+ JUMPTO(pc->target_endfile);
+ }
+ break;
+
+ case Op_K_exit:
+ /* exit not allowed in user-defined comparison functions for "sorted_in";
+ * This is done so that END blocks aren't executed more than once.
+ */
+ if (! currule)
+ fatal(_("`exit' cannot be called in the current context"));
+
+ exiting = true;
+ t1 = POP_NUMBER();
+ exit_val = (int) get_number_si(t1);
+ DEREF(t1);
+#ifdef VMS
+ if (exit_val == 0)
+ exit_val = EXIT_SUCCESS;
+ else if (exit_val == 1)
+ exit_val = EXIT_FAILURE;
+ /* else
+ just pass anything else on through */
+#endif
+
+ if (currule == BEGINFILE || currule == ENDFILE) {
+
+ /* Find the rule of the saved execution state (Op_K_getline/Op_newfile).
+ * This is needed to prevent multiple execution of any END rules:
+ * gawk 'BEGINFILE { exit(1) } \
+ * END { while (getline > 0); }' in1 in2
+ */
+
+ (void) pop_exec_state(& currule, & source, NULL);
+ }
+
+ pop_stack(); /* empty stack, don't leak memory */
+
+ /* Jump to either the first END block instruction
+ * or to Op_atexit.
+ */
+
+ if (currule == END)
+ ni = pc->target_atexit;
+ else
+ ni = pc->target_end;
+ JUMPTO(ni);
+
+ case Op_K_next:
+ if (currule != Rule)
+ fatal(_("`next' cannot be called from a `%s' rule"), ruletab[currule]);
+
+ pop_stack();
+ JUMPTO(pc->target_jmp); /* Op_get_record, read next record */
+
+ case Op_pop:
+ r = POP_SCALAR();
+ DEREF(r);
+ break;
+
+ case Op_line_range:
+ if (pc->triggered) /* evaluate right expression */
+ JUMPTO(pc->target_jmp);
+ /* else
+ evaluate left expression */
+ break;
+
+ case Op_cond_pair:
+ {
+ int result;
+ INSTRUCTION *ip;
+
+ t1 = TOP_SCALAR(); /* from right hand side expression */
+ di = (eval_condition(t1) != 0);
+ DEREF(t1);
+
+ ip = pc->line_range; /* Op_line_range */
+
+ if (! ip->triggered && di) {
+ /* not already triggered and left expression is true */
+ decr_sp();
+ ip->triggered = true;
+ JUMPTO(ip->target_jmp); /* evaluate right expression */
+ }
+
+ result = ip->triggered || di;
+ ip->triggered ^= di; /* update triggered flag */
+ r = node_Boolean[result]; /* final value of condition pair */
+ UPREF(r);
+ REPLACE(r);
+ JUMPTO(pc->target_jmp);
+ }
+
+ case Op_exec_count:
+ if (do_profile)
+ pc->exec_count++;
+ break;
+
+ case Op_no_op:
+ case Op_K_do:
+ case Op_K_while:
+ case Op_K_for:
+ case Op_K_arrayfor:
+ case Op_K_switch:
+ case Op_K_default:
+ case Op_K_if:
+ case Op_K_else:
+ case Op_cond_exp:
+ case Op_comment:
+ break;
+
+ default:
+ fatal(_("Sorry, don't know how to interpret `%s'"), opcode2str(op));
+ }
+
+ JUMPTO(pc->nexti);
+
+/* } forever */
+
+ /* not reached */
+ return 0;
+
+#undef mk_sub
+#undef JUMPTO
+}
diff --git a/io.c b/io.c
index 4b7976f1..1d15d887 100644
--- a/io.c
+++ b/io.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-2011 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-2014 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -42,6 +42,10 @@
#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
#endif
+#if ! defined(S_ISREG) && defined(S_IFREG)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
@@ -76,7 +80,7 @@
#include "missing_d/getaddrinfo.h"
#endif
-#ifndef AI_ADDRCONFIG /* This is a recent symbol, not everyone has it */
+#ifndef AI_ADDRCONFIG /* not everyone has this symbol */
#define AI_ADDRCONFIG 0
#endif /* AI_ADDRCONFIG */
@@ -100,78 +104,154 @@
#include <limits.h>
#endif
+#if defined(HAVE_POPEN_H)
+#include "popen.h"
+#endif
+
#ifdef __EMX__
#include <process.h>
+
+#if !defined(_S_IFDIR) && defined(S_IFDIR)
+#define _S_IFDIR S_IFDIR
+#endif
+
+#if !defined(_S_IRWXU) && defined(S_IRWXU)
+#define _S_IRWXU S_IRWXU
+#endif
#endif
#ifndef ENFILE
#define ENFILE EMFILE
#endif
+#if defined(__DJGPP__)
+#define closemaybesocket(fd) close(fd)
+#endif
+
+#if defined(VMS)
+#include <ssdef.h>
+#ifndef SS$_EXBYTLM
+#define SS$_EXBYTLM 0x2a14 /* VMS 8.4 seen */
+#endif
+#include <rmsdef.h>
+#define closemaybesocket(fd) close(fd)
+#endif
+
#ifdef HAVE_SOCKETS
#ifndef SHUT_RD
-#define SHUT_RD 0
+# ifdef SD_RECEIVE
+# define SHUT_RD SD_RECEIVE
+# else
+# define SHUT_RD 0
+# endif
#endif
#ifndef SHUT_WR
-#define SHUT_WR 1
+# ifdef SD_SEND
+# define SHUT_WR SD_SEND
+# else
+# define SHUT_WR 1
+# endif
#endif
#ifndef SHUT_RDWR
-#define SHUT_RDWR 2
+# ifdef SD_BOTH
+# define SHUT_RDWR SD_BOTH
+# else
+# define SHUT_RDWR 2
+# endif
+#endif
+
+/* MinGW defines non-trivial macros on pc/socket.h. */
+#ifndef FD_TO_SOCKET
+# define FD_TO_SOCKET(fd) (fd)
+# define closemaybesocket(fd) close(fd)
+#endif
+
+#ifndef SOCKET_TO_FD
+# define SOCKET_TO_FD(s) (s)
+# define SOCKET int
+#endif
+
+#else /* HAVE_SOCKETS */
+
+#ifndef closemaybesocket
+# define closemaybesocket(fd) close(fd)
#endif
#endif /* HAVE_SOCKETS */
+#ifndef HAVE_SETSID
+#define setsid() /* nothing */
+#endif /* HAVE_SETSID */
+
#if defined(GAWK_AIX)
#undef TANDEM /* AIX defines this in one of its header files */
#endif
-#if defined(__DJGPP__) || defined(__MINGW32__)
+#ifdef __DJGPP__
#define PIPES_SIMULATED
#endif
+#ifdef __MINGW32__
+# ifndef PIPES_SIMULATED
+# define pipe(fds) _pipe(fds, 0, O_NOINHERIT)
+# endif
+#endif
+
+#ifdef HAVE_MPFR
+/* increment NR or FNR */
+#define INCREMENT_REC(X) (do_mpfr && X == (LONG_MAX - 1)) ? \
+ (mpz_add_ui(M##X, M##X, 1), X = 0) : X++
+#else
+#define INCREMENT_REC(X) X++
+#endif
+
typedef enum { CLOSE_ALL, CLOSE_TO, CLOSE_FROM } two_way_close_type;
-/* Several macros make the code a bit clearer: */
-/* */
-/* */
-/* <defines and enums>= */
+/* Several macros to make the code a bit clearer. */
#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>= */
+#define buffer_has_all_data(iop) ((iop)->dataend - (iop)->off == (iop)->public.sbuf.st_size)
+
+/*
+ * 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:
+ */
+
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 */
+ TERMNEAREND /* found terminator close to end of buffer, for when
+ the RE might be match more data further in
+ the file. */
} 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>= */
+
+/*
+ * 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.
+ */
+
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>= */
+
+/*
+ * When a record is seen (REC_OK or TERMATEND), the following
+ * structure is filled in.
+ */
+
struct recmatch {
char *start; /* record start */
size_t len; /* length of record */
@@ -183,17 +263,21 @@ struct recmatch {
static int iop_close(IOBUF *iop);
struct redirect *redirect(NODE *redir_exp, int redirtype, int *errflg);
static void close_one(void);
-static int close_redir(struct redirect *rp, int exitwarn, two_way_close_type how);
+static int close_redir(struct redirect *rp, bool exitwarn, two_way_close_type how);
#ifndef PIPES_SIMULATED
static int wait_any(int interesting);
#endif
static IOBUF *gawk_popen(const char *cmd, struct redirect *rp);
-static IOBUF *iop_alloc(int fd, const char *name, IOBUF *buf, int do_openhooks);
+static IOBUF *iop_alloc(int fd, const char *name, int errno_val);
+static IOBUF *iop_finish(IOBUF *iop);
static int gawk_pclose(struct redirect *rp);
static int str2mode(const char *mode);
static int two_way_open(const char *str, struct redirect *rp);
static int pty_vs_pipe(const char *command);
-static void find_open_hook(IOBUF *iop);
+static void find_input_parser(IOBUF *iop);
+static bool find_output_wrapper(awk_output_buf_t *outbuf);
+static void init_output_wrapper(awk_output_buf_t *outbuf);
+static bool find_two_way_processor(const char *name, struct redirect *rp);
static RECVALUE rs1scan(IOBUF *iop, struct recmatch *recm, SCANSTATE *state);
static RECVALUE rsnullscan(IOBUF *iop, struct recmatch *recm, SCANSTATE *state);
@@ -204,27 +288,76 @@ static RECVALUE (*matchrec)(IOBUF *iop, struct recmatch *recm, SCANSTATE *state)
static int get_a_record(char **out, IOBUF *iop, int *errcode);
static void free_rp(struct redirect *rp);
-static int inetfile(const char *str, int *length, int *family);
-#if defined(HAVE_POPEN_H)
-#include "popen.h"
-#endif
+struct inet_socket_info {
+ int family; /* AF_UNSPEC, AF_INET, or AF_INET6 */
+ int protocol; /* SOCK_STREAM or SOCK_DGRAM */
+ /*
+ * N.B. If we used 'char *' or 'const char *' pointers to the
+ * substrings, it would trigger compiler warnings about the casts
+ * in either inetfile() or devopen(). So we use offset/len to
+ * avoid that.
+ */
+ struct {
+ int offset;
+ int len;
+ } localport, remotehost, remoteport;
+};
+
+static bool inetfile(const char *str, struct inet_socket_info *isn);
+
+static NODE *in_PROCINFO(const char *pidx1, const char *pidx2, NODE **full_idx);
+static long get_read_timeout(IOBUF *iop);
+static ssize_t read_with_timeout(int fd, char *buf, size_t size);
+
+static bool read_can_timeout = false;
+static long read_timeout;
+static long read_default_timeout;
static struct redirect *red_head = NULL;
static NODE *RS = NULL;
-static Regexp *RS_re_yes_case;
-static Regexp *RS_re_no_case;
+static Regexp *RS_re_yes_case; /* regexp for RS when ignoring case */
+static Regexp *RS_re_no_case; /* regexp for RS when not ignoring case */
static Regexp *RS_regexp;
-int RS_is_null;
+bool 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;
+/* init_io --- set up timeout related variables */
+
+void
+init_io()
+{
+ long tmout;
+
+ /* Only MinGW has a non-trivial implementation of this. */
+ init_sockets();
+
+ /*
+ * N.B.: all these hacks are to minimize the effect
+ * on programs that do not care about timeout.
+ */
+
+ /* Parse the env. variable only once */
+ tmout = getenv_long("GAWK_READ_TIMEOUT");
+ if (tmout > 0) {
+ read_default_timeout = tmout;
+ read_can_timeout = true;
+ }
+
+ /*
+ * PROCINFO entries for timeout are dynamic;
+ * We can't be any more specific than this.
+ */
+ if (PROCINFO_node != NULL)
+ read_can_timeout = true;
+}
+
+
#if defined(__DJGPP__) || defined(__MINGW32__) || defined(__EMX__) || defined(__CYGWIN__)
/* binmode --- convert BINMODE to string for fopen */
@@ -233,12 +366,12 @@ binmode(const char *mode)
{
switch (mode[0]) {
case 'r':
- if ((BINMODE & 1) != 0)
+ if ((BINMODE & BINMODE_INPUT) != 0)
mode = "rb";
break;
case 'w':
case 'a':
- if ((BINMODE & 2) != 0)
+ if ((BINMODE & BINMODE_OUTPUT) != 0)
mode = (mode[0] == 'w' ? "wb" : "ab");
break;
}
@@ -257,6 +390,8 @@ static int vmsrtl_fileno(fp) FILE *fp; { return fileno(fp); }
#define fileno(FP) (((FP) && *(FP)) ? vmsrtl_fileno(FP) : -1)
#endif /* VMS */
+/* after_beginfile --- reset necessary state after BEGINFILE has run */
+
void
after_beginfile(IOBUF **curfile)
{
@@ -265,51 +400,56 @@ after_beginfile(IOBUF **curfile)
iop = *curfile;
assert(iop != NULL);
- if (iop->fd == INVALID_HANDLE) {
+ /*
+ * Input parsers could have been changed by BEGINFILE,
+ * so delay check until now.
+ */
+
+ find_input_parser(iop);
+
+ if (! iop->valid) {
const char *fname;
int errcode;
+ bool valid;
- fname = iop->name;
+ fname = iop->public.name;
errcode = iop->errcode;
- iop->errcode = 0;
+ valid = iop->valid;
errno = 0;
- update_ERRNO();
+ update_ERRNO_int(errcode);
iop_close(iop);
*curfile = NULL;
- if (errcode == EISDIR && ! do_traditional) {
+ if (! valid && errcode == EISDIR && ! do_traditional) {
warning(_("command line argument `%s' is a directory: skipped"), fname);
return; /* read next file */
}
fatal(_("cannot open file `%s' for reading (%s)"),
fname, strerror(errcode));
}
-
- /*
- * Open hooks could have been changed by BEGINFILE,
- * so delay check until now.
- */
-
- find_open_hook(iop);
}
/* nextfile --- move to the next input data file */
+/*
+ * Return value > 0 ----> run BEGINFILE block
+ * *curfile = NULL ----> hit EOF, run ENDFILE block
+ */
int
-nextfile(IOBUF **curfile, int skipping)
+nextfile(IOBUF **curfile, bool skipping)
{
static long i = 1;
- static int files = FALSE;
+ static bool files = false;
NODE *arg, *tmp;
- static IOBUF mybuf;
const char *fname;
int fd = INVALID_HANDLE;
- int errcode;
+ int errcode = 0;
IOBUF *iop = *curfile;
+ long argc;
if (skipping) { /* for 'nextfile' call */
errcode = 0;
if (iop != NULL) {
- errcode = iop->errcode;
+ errcode = iop->errcode;
(void) iop_close(iop);
}
*curfile = NULL;
@@ -318,7 +458,7 @@ nextfile(IOBUF **curfile, int skipping)
if (iop != NULL) {
if (at_eof(iop)) {
- assert(iop->fd != INVALID_HANDLE);
+ assert(iop->public.fd != INVALID_HANDLE);
(void) iop_close(iop);
*curfile = NULL;
return 1; /* run endfile block */
@@ -326,7 +466,9 @@ nextfile(IOBUF **curfile, int skipping)
return 0;
}
- for (; i < (long) (ARGC_node->lnode->numbr); i++) {
+ argc = get_number_si(ARGC_node->var_value);
+
+ for (; i < argc; i++) {
tmp = make_number((AWKNUM) i);
(void) force_string(tmp);
arg = in_array(ARGV_node, tmp);
@@ -340,46 +482,63 @@ nextfile(IOBUF **curfile, int skipping)
ARGIND_node->var_value = make_number((AWKNUM) i);
}
- if (! arg_assign(arg->stptr, FALSE)) {
- files = TRUE;
+ if (! arg_assign(arg->stptr, false)) {
+ files = true;
fname = arg->stptr;
- errno = 0;
- fd = devopen(fname, binmode("r"));
- errcode = errno;
- if (! do_traditional)
- update_ERRNO();
- /* This is a kludge. */
+ /* manage the awk variables: */
unref(FILENAME_node->var_value);
FILENAME_node->var_value = dupnode(arg);
+#ifdef HAVE_MPFR
+ if (is_mpg_number(FNR_node->var_value))
+ mpz_set_ui(MFNR, 0);
+#endif
FNR = 0;
- iop = *curfile = iop_alloc(fd, fname, &mybuf, FALSE);
- if (fd == INVALID_HANDLE)
+
+ /* IOBUF management: */
+ errno = 0;
+ fd = devopen(fname, binmode("r"));
+ if (fd == INVALID_HANDLE && errno == EMFILE) {
+ close_one();
+ close_one();
+ fd = devopen(fname, binmode("r"));
+ }
+ errcode = errno;
+ if (! do_traditional)
+ update_ERRNO_int(errno);
+ iop = iop_alloc(fd, fname, errcode);
+ *curfile = iop_finish(iop);
+ if (iop->public.fd == INVALID_HANDLE)
iop->errcode = errcode;
- else
+ else if (iop->valid)
iop->errcode = 0;
- iop->flag |= IOP_NOFREE_OBJ;
+
+ if (! do_traditional && iop->errcode != 0)
+ update_ERRNO_int(iop->errcode);
+
return ++i; /* run beginfile block */
}
}
- if (files == FALSE) {
- files = TRUE;
+ if (files == false) {
+ files = true;
/* no args. -- use stdin */
/* FNR is init'ed to 0 */
errno = 0;
if (! do_traditional)
- update_ERRNO();
+ update_ERRNO_int(errno);
+
unref(FILENAME_node->var_value);
FILENAME_node->var_value = make_string("-", 1);
FILENAME_node->var_value->flags |= MAYBE_NUM; /* be pedantic */
fname = "-";
- iop = *curfile = iop_alloc(fileno(stdin), fname, &mybuf, FALSE);
- iop->flag |= IOP_NOFREE_OBJ;
- if (iop->fd == INVALID_HANDLE) {
+ iop = iop_alloc(fileno(stdin), fname, 0);
+ *curfile = iop_finish(iop);
+
+ if (iop->public.fd == INVALID_HANDLE) {
errcode = errno;
errno = 0;
- update_ERRNO();
+ update_ERRNO_int(errno);
(void) iop_close(iop);
*curfile = NULL;
fatal(_("cannot open file `%s' for reading (%s)"),
@@ -396,7 +555,14 @@ nextfile(IOBUF **curfile, int skipping)
void
set_FNR()
{
- FNR = (long) FNR_node->var_value->numbr;
+ NODE *n = FNR_node->var_value;
+ (void) force_number(n);
+#ifdef HAVE_MPFR
+ if (is_mpg_number(n))
+ FNR = mpg_set_var(FNR_node);
+ else
+#endif
+ FNR = get_number_si(n);
}
/* set_NR --- update internal NR from awk variable */
@@ -404,33 +570,40 @@ set_FNR()
void
set_NR()
{
- NR = (long) NR_node->var_value->numbr;
+ NODE *n = NR_node->var_value;
+ (void) force_number(n);
+#ifdef HAVE_MPFR
+ if (is_mpg_number(n))
+ NR = mpg_set_var(NR_node);
+ else
+#endif
+ NR = get_number_si(n);
}
/* inrec --- This reads in a record from the input file */
-int
+bool
inrec(IOBUF *iop, int *errcode)
{
char *begin;
int cnt;
- int retval = 0;
+ bool retval = true;
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, errcode);
+ cnt = get_a_record(& begin, iop, errcode);
if (cnt == EOF) {
- retval = 1;
- if (*errcode > 0)
- update_ERRNO_saved(*errcode);
+ retval = false;
} else {
- NR += 1;
- FNR += 1;
+ INCREMENT_REC(NR);
+ INCREMENT_REC(FNR);
set_record(begin, cnt);
+ if (*errcode > 0)
+ retval = false;
}
return retval;
@@ -445,14 +618,14 @@ remap_std_file(int oldfd)
int ret = -1;
/*
- * Give OS-specific routines in gawkmisc.c chance to interpret
+ * Give OS-specific routines in gawkmisc.c a chance to interpret
* "/dev/null" as appropriate for their platforms.
*/
newfd = os_devopen("/dev/null", O_RDWR);
if (newfd == INVALID_HANDLE)
newfd = open("/dev/null", O_RDWR);
if (newfd >= 0) {
- /* dup2() will close oldfd for us first. */
+ /* if oldfd is open, dup2() will close oldfd for us first. */
ret = dup2(newfd, oldfd);
if (ret == 0)
close(newfd);
@@ -467,15 +640,10 @@ remap_std_file(int oldfd)
static int
iop_close(IOBUF *iop)
{
- int ret;
+ int ret = 0;
if (iop == NULL)
return 0;
- if (iop->fd == INVALID_HANDLE) { /* from nextfile(...) above */
- assert(iop->buf == NULL);
- assert((iop->flag & IOP_NOFREE_OBJ) != 0);
- return 0;
- }
errno = 0;
@@ -487,19 +655,21 @@ iop_close(IOBUF *iop)
* So we remap the standard file to /dev/null.
* Thanks to Jim Meyering for the suggestion.
*/
- if (iop->fd == fileno(stdin)
- || iop->fd == fileno(stdout)
- || iop->fd == fileno(stderr))
- ret = remap_std_file(iop->fd);
- else
- ret = close(iop->fd);
-
- if (iop->close_func != NULL)
- (*iop->close_func)(iop);
+ if (iop->public.close_func != NULL)
+ iop->public.close_func(&iop->public);
+
+ if (iop->public.fd != INVALID_HANDLE) {
+ if (iop->public.fd == fileno(stdin)
+ || iop->public.fd == fileno(stdout)
+ || iop->public.fd == fileno(stderr))
+ ret = remap_std_file(iop->public.fd);
+ else
+ ret = closemaybesocket(iop->public.fd);
+ }
if (ret == -1)
- warning(_("close of fd %d (`%s') failed (%s)"), iop->fd,
- iop->name, strerror(errno));
+ warning(_("close of fd %d (`%s') failed (%s)"), iop->public.fd,
+ iop->public.name, strerror(errno));
/*
* Be careful -- $0 may still reference the buffer even though
* an explicit close is being done; in the future, maybe we
@@ -515,7 +685,7 @@ iop_close(IOBUF *iop)
unref(fields_arr[0]);
fields_arr[0] = t;
/*
- * 1/27/2003: This used to be here:
+ * This used to be here:
*
* reset_record();
*
@@ -527,8 +697,7 @@ iop_close(IOBUF *iop)
efree(iop->buf);
iop->buf = NULL;
}
- if ((iop->flag & IOP_NOFREE_OBJ) == 0)
- efree(iop);
+ efree(iop);
return ret == -1 ? 1 : 0;
}
@@ -568,8 +737,10 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
const char *mode;
int fd;
const char *what = NULL;
- int new_rp = FALSE;
- int len; /* used with /inet */
+ bool new_rp = false;
+#ifdef HAVE_SOCKETS
+ struct inet_socket_info isi;
+#endif
static struct redirect *save_rp = NULL; /* hold onto rp that should
* be freed for reuse
*/
@@ -611,27 +782,26 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
if (do_lint && (redir_exp->flags & STRCUR) == 0)
lintwarn(_("expression in `%s' redirection only has numeric value"),
what);
- redir_exp= force_string(redir_exp);
+ redir_exp = force_string(redir_exp);
str = redir_exp->stptr;
if (str == NULL || *str == '\0')
fatal(_("expression for `%s' redirection has null string value"),
what);
- if (do_lint && (STREQN(str, "0", redir_exp->stlen)
- || STREQN(str, "1", redir_exp->stlen))
- )
+ if (do_lint && (strncmp(str, "0", redir_exp->stlen) == 0
+ || strncmp(str, "1", redir_exp->stlen) == 0))
lintwarn(_("filename `%s' for `%s' redirection may be result of logical expression"),
str, what);
+#ifdef HAVE_SOCKETS
/*
- * XXX: Use /inet4 and /inet6 with plain /inet being whatever
- * we get back from the system.
+ * Use /inet4 to force IPv4, /inet6 to force IPv6, and plain
+ * /inet will be whatever we get back from the system.
*/
-#ifdef HAVE_SOCKETS
- if (inetfile(str, & len, NULL)) {
+ if (inetfile(str, & isi)) {
tflag |= RED_SOCKET;
- if (STREQN(str + len, "tcp/", 4))
+ if (isi.protocol == SOCK_STREAM)
tflag |= RED_TCP; /* use shutdown when closing */
}
#endif /* HAVE_SOCKETS */
@@ -644,11 +814,16 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
* 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.
+ * a good bet that the child has died. So recover it.
*/
- if ((rp->flag & RED_EOF) && redirtype == redirect_pipein) {
+ if ((rp->flag & RED_EOF) != 0 && redirtype == redirect_pipein) {
if (rp->pid != -1)
+#ifdef __MINGW32__
+ /* MinGW cannot wait for any process. */
+ wait_any(rp->pid);
+#else
wait_any(0);
+#endif
}
#endif /* PIPES_SIMULATED */
@@ -672,7 +847,7 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
}
if (rp == NULL) {
- new_rp = TRUE;
+ new_rp = true;
if (save_rp != NULL) {
rp = save_rp;
efree(rp->value);
@@ -683,7 +858,8 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
str[redir_exp->stlen] = '\0';
rp->value = str;
rp->flag = tflag;
- rp->fp = NULL;
+ init_output_wrapper(& rp->output);
+ rp->output.name = str;
rp->iop = NULL;
rp->pid = -1;
rp->status = 0;
@@ -691,10 +867,10 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
str = rp->value; /* get \0 terminated string */
save_rp = rp;
- while (rp->fp == NULL && rp->iop == NULL) {
- if (! new_rp && rp->flag & RED_EOF) {
+ while (rp->output.fp == NULL && rp->iop == NULL) {
+ if (! new_rp && (rp->flag & RED_EOF) != 0) {
/*
- * encountered EOF on file or pipe -- must be cleared
+ * Encountered EOF on file or pipe -- must be cleared
* by explicit close() before reading more
*/
save_rp = NULL;
@@ -716,12 +892,12 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
(void) flush_io();
os_restore_mode(fileno(stdin));
- if ((rp->fp = popen(str, binmode("w"))) == NULL)
+ if ((rp->output.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");
+ os_close_on_exec(fileno(rp->output.fp), str, "pipe", "to");
rp->flag |= RED_NOBUF;
break;
case redirect_pipein:
@@ -738,13 +914,21 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
/* do not free rp, saving it for reuse (save_rp = rp) */
return NULL;
}
- rp->iop = iop_alloc(fd, str, NULL, TRUE);
+ rp->iop = iop_alloc(fd, str, errno);
+ find_input_parser(rp->iop);
+ iop_finish(rp->iop);
+ if (! rp->iop->valid) {
+ if (! do_traditional && rp->iop->errcode != 0)
+ update_ERRNO_int(rp->iop->errcode);
+ iop_close(rp->iop);
+ rp->iop = NULL;
+ }
break;
case redirect_twoway:
direction = "to/from";
if (! two_way_open(str, rp)) {
#ifdef HAVE_SOCKETS
- if (inetfile(str, NULL, NULL)) {
+ if (inetfile(str, NULL)) {
*errflg = errno;
/* do not free rp, saving it for reuse (save_rp = rp) */
return NULL;
@@ -760,15 +944,16 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
if (mode != NULL) {
errno = 0;
+ rp->output.mode = mode;
fd = devopen(str, mode);
if (fd > INVALID_HANDLE) {
if (fd == fileno(stdin))
- rp->fp = stdin;
+ rp->output.fp = stdin;
else if (fd == fileno(stdout))
- rp->fp = stdout;
+ rp->output.fp = stdout;
else if (fd == fileno(stderr))
- rp->fp = stderr;
+ rp->output.fp = stderr;
else {
const char *omode = mode;
#if defined(F_GETFL) && defined(O_APPEND)
@@ -779,13 +964,13 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
omode = binmode("a");
#endif
os_close_on_exec(fd, str, "file", "");
- rp->fp = fdopen(fd, (const char *) omode);
+ rp->output.fp = fdopen(fd, (const char *) omode);
rp->mode = (const char *) mode;
/* don't leak file descriptors */
- if (rp->fp == NULL)
+ if (rp->output.fp == NULL)
close(fd);
}
- if (rp->fp != NULL && os_isatty(fd))
+ if (rp->output.fp != NULL && os_isatty(fd))
rp->flag |= RED_NOBUF;
/* Move rp to the head of the list. */
@@ -798,21 +983,21 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
red_head = rp;
}
}
+ find_output_wrapper(& rp->output);
}
- if (rp->fp == NULL && rp->iop == NULL) {
+ if (rp->output.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
+ /* Alpha/VMS V7.1+ C RTL is returning these instead
of EMFILE (haven't tried other post-V6.2 systems) */
-#define SS$_EXQUOTA 0x001C
- else if (errno == EIO && vaxc$errno == SS$_EXQUOTA)
+ else if ((errno == EIO || errno == EVMSERR) &&
+ (vaxc$errno == SS$_EXQUOTA ||
+ vaxc$errno == SS$_EXBYTLM ||
+ vaxc$errno == RMS$_ACC ||
+ vaxc$errno == RMS$_SYN))
close_one();
#endif
else {
@@ -827,9 +1012,8 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
*/
if (errflg != NULL)
*errflg = errno;
- if (redirtype == redirect_output
- || redirtype == redirect_append
- ) {
+ if ( redirtype == redirect_output
+ || redirtype == redirect_append) {
/* multiple messages make life easier for translators */
if (*direction == 'f')
fatal(_("can't redirect from `%s' (%s)"),
@@ -882,10 +1066,10 @@ close_one()
struct redirect *rp;
struct redirect *rplast = NULL;
- static short warned = FALSE;
+ static bool warned = false;
if (do_lint && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn(_("reached system limit for open files: starting to multiplex file descriptors"));
}
@@ -895,16 +1079,16 @@ close_one()
/* 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)
+ if (rp->output.fp == NULL || rp->output.fp == stderr || rp->output.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)
+ if (rp->output.gawk_fclose(rp->output.fp, rp->output.opaque) != 0)
warning(_("close of `%s' failed (%s)."),
rp->value, strerror(errno));
- rp->fp = NULL;
+ rp->output.fp = NULL;
break;
}
}
@@ -955,8 +1139,7 @@ do_close(int nargs)
if (! do_traditional) {
/* 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));
+ update_ERRNO_string(cp);
}
DEREF(tmp);
@@ -964,7 +1147,7 @@ do_close(int nargs)
}
DEREF(tmp);
fflush(stdout); /* synchronize regular output */
- tmp = make_number((AWKNUM) close_redir(rp, FALSE, how));
+ tmp = make_number((AWKNUM) close_redir(rp, false, how));
rp = NULL;
/*
* POSIX says close() returns 0 on success, non-zero otherwise.
@@ -974,7 +1157,7 @@ do_close(int nargs)
*/
if (do_posix) {
unref(tmp);
- return make_number((AWKNUM) 0);
+ tmp = make_number((AWKNUM) 0);
}
return tmp;
}
@@ -989,18 +1172,18 @@ close_rp(struct redirect *rp, two_way_close_type how)
errno = 0;
if ((rp->flag & RED_TWOWAY) != 0) { /* two-way pipe */
/* write end: */
- if ((how == CLOSE_ALL || how == CLOSE_TO) && rp->fp != NULL) {
+ if ((how == CLOSE_ALL || how == CLOSE_TO) && rp->output.fp != NULL) {
#ifdef HAVE_SOCKETS
if ((rp->flag & RED_TCP) != 0)
- (void) shutdown(fileno(rp->fp), SHUT_WR);
+ (void) shutdown(fileno(rp->output.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);
+ rp->output.gawk_fwrite("\004\n", sizeof("\004\n") - 1, 1, rp->output.fp, rp->output.opaque);
+ rp->output.gawk_fflush(rp->output.fp, rp->output.opaque);
}
- status = fclose(rp->fp);
- rp->fp = NULL;
+ status = rp->output.gawk_fclose(rp->output.fp, rp->output.opaque);
+ rp->output.fp = NULL;
}
/* read end: */
@@ -1008,7 +1191,7 @@ close_rp(struct redirect *rp, two_way_close_type how)
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);
+ (void) shutdown(rp->iop->public.fd, SHUT_RD);
#endif /* HAVE_SOCKETS */
(void) iop_close(rp->iop);
} else
@@ -1016,15 +1199,16 @@ close_rp(struct redirect *rp, two_way_close_type how)
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)
+ } else if ((rp->flag & (RED_PIPE|RED_WRITE)) == (RED_PIPE|RED_WRITE)) {
+ /* write to pipe */
+ status = pclose(rp->output.fp);
+ if ((BINMODE & BINMODE_INPUT) != 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;
+ rp->output.fp = NULL;
+ } else if (rp->output.fp != NULL) { /* write to file */
+ status = rp->output.gawk_fclose(rp->output.fp, rp->output.opaque);
+ rp->output.fp = NULL;
} else if (rp->iop != NULL) { /* read from pipe/file */
if ((rp->flag & RED_PIPE) != 0) /* read from pipe */
status = gawk_pclose(rp);
@@ -1041,13 +1225,13 @@ close_rp(struct redirect *rp, two_way_close_type how)
/* close_redir --- close an open file or pipe */
static int
-close_redir(struct redirect *rp, int exitwarn, two_way_close_type how)
+close_redir(struct redirect *rp, bool exitwarn, two_way_close_type how)
{
int status = 0;
if (rp == NULL)
return 0;
- if (rp->fp == stdout || rp->fp == stderr)
+ if (rp->output.fp == stdout || rp->output.fp == stderr)
goto checkwarn; /* bypass closing, remove from list */
if (do_lint && (rp->flag & RED_TWOWAY) == 0 && how != CLOSE_ALL)
@@ -1056,14 +1240,15 @@ close_redir(struct redirect *rp, int exitwarn, two_way_close_type how)
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.
+ * BWK's awk, as far back as SVR4 (1989) would check
+ * and warn about the status of close. However, when
+ * we did this we got too many complaints, so we moved
+ * it to be under lint control.
*/
if (do_lint) {
if ((rp->flag & RED_PIPE) != 0)
@@ -1076,7 +1261,7 @@ close_redir(struct redirect *rp, int exitwarn, two_way_close_type how)
if (! do_traditional) {
/* set ERRNO too so that program can get at it */
- update_ERRNO_saved(save_errno);
+ update_ERRNO_int(save_errno);
}
}
@@ -1104,7 +1289,7 @@ checkwarn:
}
/* 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 (how == CLOSE_ALL || (rp->iop == NULL && rp->output.fp == NULL)) {
if (rp->next != NULL)
rp->next->prev = rp->prev;
if (rp->prev != NULL)
@@ -1126,22 +1311,25 @@ flush_io()
int status = 0;
errno = 0;
+ /* we don't warn about stdout/stderr if EPIPE, but we do error exit */
if (fflush(stdout)) {
- warning(_("error writing standard output (%s)"), strerror(errno));
+ if (errno != EPIPE)
+ warning(_("error writing standard output (%s)"), strerror(errno));
status++;
}
if (fflush(stderr)) {
- warning(_("error writing standard error (%s)"), strerror(errno));
+ if (errno != EPIPE)
+ 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)
+ if ((rp->flag & RED_WRITE) != 0 && rp->output.fp != NULL) {
+ if (rp->output.gawk_fflush(rp->output.fp, rp->output.opaque)) {
+ if ((rp->flag & RED_PIPE) != 0)
warning(_("pipe flush of `%s' failed (%s)."),
rp->value, strerror(errno));
- else if (rp->flag & RED_TWOWAY)
+ else if ((rp->flag & RED_TWOWAY) != 0)
warning(_("co-process flush of pipe to `%s' failed (%s)."),
rp->value, strerror(errno));
else
@@ -1158,7 +1346,7 @@ flush_io()
/* close_io --- close all open files, called when exiting */
int
-close_io(int *stdio_problem)
+close_io(bool *stdio_problem)
{
struct redirect *rp;
struct redirect *next;
@@ -1168,7 +1356,7 @@ close_io(int *stdio_problem)
for (rp = red_head; rp != NULL; rp = next) {
next = rp->next;
/*
- * close_redir() will print a message if needed
+ * 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))
@@ -1176,20 +1364,23 @@ close_io(int *stdio_problem)
rp = NULL;
}
/*
- * Some of the non-Unix os's have problems doing an fclose
+ * 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));
+ *stdio_problem = false;
+ /* we don't warn about stdout/stderr if EPIPE, but we do error exit */
+ if (fflush(stdout) != 0) {
+ if (errno != EPIPE)
+ warning(_("error writing standard output (%s)"), strerror(errno));
status++;
- *stdio_problem = TRUE;
+ *stdio_problem = true;
}
- if (fflush(stderr)) {
- warning(_("error writing standard error (%s)"), strerror(errno));
+ if (fflush(stderr) != 0) {
+ if (errno != EPIPE)
+ warning(_("error writing standard error (%s)"), strerror(errno));
status++;
- *stdio_problem = TRUE;
+ *stdio_problem = true;
}
return status;
}
@@ -1246,34 +1437,34 @@ socketopen(int family, int type, const char *localpname,
struct addrinfo *rres, *rres0;
struct addrinfo rhints;
- int lerror;
- int rerror;
+ int lerror, rerror;
int socket_fd = INVALID_HANDLE;
int any_remote_host = (strcmp(remotehostname, "0") == 0);
- memset (&lhints, '\0', sizeof (lhints));
+ memset(& lhints, '\0', sizeof (lhints));
lhints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
lhints.ai_socktype = type;
lhints.ai_family = family;
- lerror = getaddrinfo (NULL, localpname, &lhints, &lres);
+ lerror = getaddrinfo(NULL, localpname, & lhints, & lres);
if (lerror) {
if (strcmp(localpname, "0") != 0)
fatal(_("local port %s invalid in `/inet'"), localpname);
lres0 = NULL;
- lres = &lhints;
+ lres = & lhints;
} else
lres0 = lres;
while (lres != NULL) {
- memset (&rhints, '\0', sizeof (rhints));
+ memset (& rhints, '\0', sizeof (rhints));
rhints.ai_flags = lhints.ai_flags;
rhints.ai_socktype = lhints.ai_socktype;
rhints.ai_family = lhints.ai_family;
rhints.ai_protocol = lhints.ai_protocol;
- rerror = getaddrinfo (any_remote_host ? NULL : remotehostname, remotepname, &rhints, &rres);
+ rerror = getaddrinfo(any_remote_host ? NULL : remotehostname,
+ remotepname, & rhints, & rres);
if (rerror) {
if (lres0 != NULL)
freeaddrinfo(lres0);
@@ -1297,7 +1488,8 @@ socketopen(int family, int type, const char *localpname,
(char *) & on, sizeof(on));
#ifdef SO_LINGER
linger.l_onoff = 1;
- linger.l_linger = 30; /* linger for 30/100 second */
+ /* linger for 30/100 second */
+ linger.l_linger = 30;
setsockopt(socket_fd, SOL_SOCKET, SO_LINGER,
(char *) & linger, sizeof(linger));
#endif
@@ -1313,13 +1505,13 @@ socketopen(int family, int type, const char *localpname,
int clientsocket_fd = INVALID_HANDLE;
struct sockaddr_storage remote_addr;
- socklen_t namelen = sizeof (remote_addr);
+ 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);
+ (struct sockaddr *) & remote_addr,
+ & namelen)) >= 0) {
+ closemaybesocket(socket_fd);
socket_fd = clientsocket_fd;
break;
}
@@ -1327,15 +1519,15 @@ socketopen(int family, int type, const char *localpname,
#ifdef MSG_PEEK
char buf[10];
struct sockaddr_storage remote_addr;
- socklen_t readle;
+ socklen_t read_len = 0;
if (recvfrom(socket_fd, buf, 1, MSG_PEEK,
(struct sockaddr *) & remote_addr,
- & readle) >= 0
- && readle
+ & read_len) >= 0
+ && read_len
&& connect(socket_fd,
- (struct sockaddr *)& remote_addr,
- readle) == 0)
+ (struct sockaddr *) & remote_addr,
+ read_len) == 0)
break;
#endif
}
@@ -1343,7 +1535,7 @@ socketopen(int family, int type, const char *localpname,
nextrres:
if (socket_fd != INVALID_HANDLE)
- close(socket_fd);
+ closemaybesocket(socket_fd);
socket_fd = INVALID_HANDLE;
rres = rres->ai_next;
}
@@ -1366,6 +1558,17 @@ nextrres:
* change the string.
*/
+/*
+ * 9/2014: Flow here is a little messy.
+ *
+ * For do_posix, we don't allow any of the special filenames.
+ *
+ * For do_traditional, we allow /dev/{stdin,stdout,stderr} since BWK awk
+ * (and mawk) support them. But we don't allow /dev/fd/N or /inet.
+ *
+ * Note that for POSIX systems os_devopen() is a no-op.
+ */
+
int
devopen(const char *name, const char *mode)
{
@@ -1373,17 +1576,15 @@ devopen(const char *name, const char *mode)
char *cp;
char *ptr;
int flag = 0;
- int len;
- int family;
-
- flag = str2mode(mode);
+ struct inet_socket_info isi;
- if (STREQ(name, "-"))
+ if (strcmp(name, "-") == 0)
return fileno(stdin);
+ flag = str2mode(mode);
openfd = INVALID_HANDLE;
- if (do_traditional)
+ if (do_posix)
goto strictopen;
if ((openfd = os_devopen(name, flag)) != INVALID_HANDLE) {
@@ -1391,170 +1592,107 @@ devopen(const char *name, const char *mode)
return openfd;
}
- if (STREQN(name, "/dev/", 5)) {
+ if (strncmp(name, "/dev/", 5) == 0) {
cp = (char *) name + 5;
- if (STREQ(cp, "stdin") && (flag & O_ACCMODE) == O_RDONLY)
+ if (strcmp(cp, "stdin") == 0 && (flag & O_ACCMODE) == O_RDONLY)
openfd = fileno(stdin);
- else if (STREQ(cp, "stdout") && (flag & O_ACCMODE) == O_WRONLY)
+ else if (strcmp(cp, "stdout") == 0 && (flag & O_ACCMODE) == O_WRONLY)
openfd = fileno(stdout);
- else if (STREQ(cp, "stderr") && (flag & O_ACCMODE) == O_WRONLY)
+ else if (strcmp(cp, "stderr") == 0 && (flag & O_ACCMODE) == O_WRONLY)
openfd = fileno(stderr);
- else if (STREQN(cp, "fd/", 3)) {
+ else if (do_traditional)
+ goto strictopen;
+ else if (strncmp(cp, "fd/", 3) == 0) {
struct stat sbuf;
cp += 3;
- openfd = (int) strtoul(cp, &ptr, 10);
+ openfd = (int) strtoul(cp, & ptr, 10);
if (openfd <= INVALID_HANDLE || ptr == cp
- || fstat(openfd, &sbuf) < 0)
+ || fstat(openfd, & sbuf) < 0)
openfd = INVALID_HANDLE;
}
/* do not set close-on-exec for inherited fd's */
if (openfd != INVALID_HANDLE)
return openfd;
- } else if (inetfile(name, & len, & family)) {
+ } else if (do_traditional) {
+ goto strictopen;
+ } else if (inetfile(name, & isi)) {
#ifdef HAVE_SOCKETS
- /* /inet/protocol/localport/hostname/remoteport */
- int protocol;
- char *hostname;
- char *hostnameslastcharp;
- char *localpname;
- char *localpnamelastcharp;
-
- cp = (char *) name + len;
- /* which protocol? */
- if (STREQN(cp, "tcp/", 4))
- protocol = SOCK_STREAM;
- else if (STREQN(cp, "udp/", 4))
- protocol = SOCK_DGRAM;
- else {
- protocol = SOCK_STREAM; /* shut up the compiler */
- fatal(_("no (known) protocol supplied in special filename `%s'"),
- name);
- }
- 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);
+ cp = (char *) 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';
- localpnamelastcharp = cp;
-
- /* which hostname? */
- cp++;
- hostname = cp;
- while (*cp != '/' && *cp != '\0')
- cp++;
- if (*cp != '/' || cp == hostname) {
- *localpnamelastcharp = '/';
- 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') {
- *localpnamelastcharp = '/';
- *hostnameslastcharp = '/';
- fatal(_("must supply a remote port to `/inet'"));
- }
+ /* socketopen requires NUL-terminated strings */
+ cp[isi.localport.offset+isi.localport.len] = '\0';
+ cp[isi.remotehost.offset+isi.remotehost.len] = '\0';
+ /* remoteport comes last, so already NUL-terminated */
{
#define DEFAULT_RETRIES 20
- static unsigned long def_retries = DEFAULT_RETRIES;
- static int first_time = TRUE;
- unsigned long retries = 0;
- static long msleep = 1000;
-
- if (first_time) {
- char *cp, *end;
- unsigned long count = 0;
- char *ms2;
-
- first_time = FALSE;
- if ((cp = getenv("GAWK_SOCK_RETRIES")) != NULL) {
- count = strtoul(cp, &end, 10);
- if (end != cp && count > 0)
- def_retries = count;
- }
-
- /*
- * Env var is in milliseconds, paramter to usleep()
- * is microseconds, make the conversion. Default is
- * 1 millisecond.
- */
- if ((ms2 = getenv("GAWK_MSEC_SLEEP")) != NULL) {
- msleep = strtol(ms2, &end, 10);
- if (end == ms2 || msleep < 0)
- msleep = 1000;
- else
- msleep *= 1000;
- }
+ static unsigned long def_retries = DEFAULT_RETRIES;
+ static bool first_time = true;
+ unsigned long retries = 0;
+ static long msleep = 1000;
+
+ if (first_time) {
+ char *cp, *end;
+ unsigned long count = 0;
+ char *ms2;
+
+ first_time = false;
+ if ((cp = getenv("GAWK_SOCK_RETRIES")) != NULL) {
+ count = strtoul(cp, & end, 10);
+ if (end != cp && count > 0)
+ def_retries = count;
}
- retries = def_retries;
- do {
- openfd = socketopen(family, protocol, localpname, cp, hostname);
- retries--;
- } while (openfd == INVALID_HANDLE && retries > 0 && usleep(msleep) == 0);
+ /*
+ * Env var is in milliseconds, paramter to usleep()
+ * is microseconds, make the conversion. Default is
+ * 1 millisecond.
+ */
+ if ((ms2 = getenv("GAWK_MSEC_SLEEP")) != NULL) {
+ msleep = strtol(ms2, & end, 10);
+ if (end == ms2 || msleep < 0)
+ msleep = 1000;
+ else
+ msleep *= 1000;
+ }
}
+ retries = def_retries;
+
+ do {
+ openfd = socketopen(isi.family, isi.protocol, name+isi.localport.offset, name+isi.remoteport.offset, name+isi.remotehost.offset);
+ retries--;
+ } while (openfd == INVALID_HANDLE && retries > 0 && usleep(msleep) == 0);
+ }
- *localpnamelastcharp = '/';
- *hostnameslastcharp = '/';
+ /* restore original name string */
+ cp[isi.localport.offset+isi.localport.len] = '/';
+ cp[isi.remotehost.offset+isi.remotehost.len] = '/';
#else /* ! HAVE_SOCKETS */
- fatal(_("TCP/IP communications are not supported"));
+ fatal(_("TCP/IP communications are not supported"));
#endif /* HAVE_SOCKETS */
}
strictopen:
if (openfd == INVALID_HANDLE)
openfd = open(name, flag, 0666);
-#ifdef __EMX__
+#if defined(__EMX__) || defined(__MINGW32__)
if (openfd == INVALID_HANDLE && errno == EACCES) {
- /* on OS/2 directory access via open() is not permitted */
+ /* On OS/2 and Windows directory access via open() is
+ not permitted. */
struct stat buf;
- if (stat(name, &buf) == 0 && S_ISDIR(buf.st_mode))
- errno = EISDIR;
+ if (!inetfile(name, NULL)
+ && stat(name, & buf) == 0 && S_ISDIR(buf.st_mode))
+ errno = EISDIR;
}
#endif
if (openfd != INVALID_HANDLE) {
- if (os_isdir(openfd)) {
- (void) close(openfd); /* don't leak fds */
- /* Set useful error number. */
- errno = EISDIR;
- return INVALID_HANDLE;
- }
-
if (openfd > fileno(stderr))
os_close_on_exec(openfd, name, "file", "");
}
- /*
- * XXX: FIXME: if fd is INVALID_HANDLE, see if an open hook
- * can do something.
- */
+
return openfd;
}
@@ -1563,43 +1701,59 @@ strictopen:
static int
two_way_open(const char *str, struct redirect *rp)
{
- static int no_ptys = FALSE;
+ static bool no_ptys = false;
#ifdef HAVE_SOCKETS
/* case 1: socket */
- if (inetfile(str, NULL, NULL)) {
+ if (inetfile(str, NULL)) {
int fd, newfd;
fd = devopen(str, "rw");
if (fd == INVALID_HANDLE)
- return FALSE;
- rp->fp = fdopen(fd, "w");
- if (rp->fp == NULL) {
+ return false;
+ if ((BINMODE & BINMODE_OUTPUT) != 0)
+ os_setbinmode(fd, O_BINARY);
+ rp->output.fp = fdopen(fd, binmode("wb"));
+ if (rp->output.fp == NULL) {
close(fd);
- return FALSE;
+ return false;
}
newfd = dup(fd);
if (newfd < 0) {
- fclose(rp->fp);
- return FALSE;
+ rp->output.gawk_fclose(rp->output.fp, rp->output.opaque);
+ return false;
}
+ if ((BINMODE & BINMODE_INPUT) != 0)
+ os_setbinmode(newfd, O_BINARY);
+ os_close_on_exec(fd, str, "socket", "to/from");
os_close_on_exec(newfd, str, "socket", "to/from");
- rp->iop = iop_alloc(newfd, str, NULL, TRUE);
- if (rp->iop == NULL) {
- fclose(rp->fp);
- return FALSE;
+ rp->iop = iop_alloc(newfd, str, 0);
+ rp->output.name = str;
+ find_input_parser(rp->iop);
+ iop_finish(rp->iop);
+ if (! rp->iop->valid) {
+ if (! do_traditional && rp->iop->errcode != 0)
+ update_ERRNO_int(rp->iop->errcode);
+ iop_close(rp->iop);
+ rp->iop = NULL;
+ rp->output.gawk_fclose(rp->output.fp, rp->output.opaque);
+ return false;
}
rp->flag |= RED_SOCKET;
- return TRUE;
+ return true;
}
#endif /* HAVE_SOCKETS */
-#ifdef HAVE_TERMIOS_H
- /* case 2: use ptys for two-way communications to child */
+ /* case 2: see if an extension wants it */
+ if (find_two_way_processor(str, rp))
+ return true;
+
+#if defined(HAVE_TERMIOS_H) && ! defined(ZOS_USS)
+ /* case 3: use ptys for two-way communications to child */
if (! no_ptys && pty_vs_pipe(str)) {
- static int initialized = FALSE;
+ static bool initialized = false;
static char first_pty_letter;
-#ifdef HAVE_GRANTPT
+#if defined(HAVE_GRANTPT) && ! defined(HAVE_POSIX_OPENPT)
static int have_dev_ptmx;
#endif
char slavenam[32];
@@ -1610,20 +1764,20 @@ two_way_open(const char *str, struct redirect *rp)
pid_t pid;
struct stat statb;
struct termios st;
- /* Use array of chars to avoid ascii / ebcdic issues */
+ /* Use array of chars to avoid ASCII / EBCDIC issues */
static char pty_chars[] = "pqrstuvwxyzabcdefghijklmno";
int i;
if (! initialized) {
- initialized = TRUE;
-#ifdef HAVE_GRANTPT
- have_dev_ptmx = (stat("/dev/ptmx", &statb) >= 0);
+ initialized = true;
+#if defined(HAVE_GRANTPT) && ! defined(HAVE_POSIX_OPENPT)
+ have_dev_ptmx = (stat("/dev/ptmx", & statb) >= 0);
#endif
i = 0;
do {
c = pty_chars[i++];
sprintf(slavenam, "/dev/pty%c0", c);
- if (stat(slavenam, &statb) >= 0) {
+ if (stat(slavenam, & statb) >= 0) {
first_pty_letter = c;
break;
}
@@ -1631,8 +1785,13 @@ two_way_open(const char *str, struct redirect *rp)
}
#ifdef HAVE_GRANTPT
+#ifdef HAVE_POSIX_OPENPT
+ {
+ master = posix_openpt(O_RDWR|O_NOCTTY);
+#else
if (have_dev_ptmx) {
master = open("/dev/ptmx", O_RDWR);
+#endif
if (master >= 0) {
char *tem;
@@ -1651,8 +1810,9 @@ two_way_open(const char *str, struct redirect *rp)
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.
+ * 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;
@@ -1662,8 +1822,8 @@ two_way_open(const char *str, struct redirect *rp)
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 */
+ if (stat(slavenam, & statb) < 0) {
+ no_ptys = true; /* bypass all this next time */
goto use_pipes;
}
@@ -1683,7 +1843,7 @@ two_way_open(const char *str, struct redirect *rp)
c = *cp;
} while (c != first_pty_letter);
} else
- no_ptys = TRUE;
+ no_ptys = true;
/* Couldn't find a pty. Fall back to using pipes. */
goto use_pipes;
@@ -1704,7 +1864,7 @@ two_way_open(const char *str, struct redirect *rp)
ioctl(slave, I_PUSH, "ldterm");
#endif
- tcgetattr(slave, &st);
+ tcgetattr(slave, & st);
st.c_iflag &= ~(ISTRIP | IGNCR | INLCR | IXOFF);
st.c_iflag |= (ICRNL | IGNPAR | BRKINT | IXON);
st.c_oflag &= ~OPOST;
@@ -1712,10 +1872,6 @@ two_way_open(const char *str, struct redirect *rp)
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
@@ -1733,9 +1889,9 @@ two_way_open(const char *str, struct redirect *rp)
#ifdef VEOF
st.c_cc[VEOF] = '\004'; /* ^d */
#endif
- tcsetattr(slave, TCSANOW, &st);
+ tcsetattr(slave, TCSANOW, & st);
- switch (pid = fork ()) {
+ switch (pid = fork()) {
case 0:
/* Child process */
setsid();
@@ -1769,76 +1925,88 @@ two_way_open(const char *str, struct redirect *rp)
case -1:
save_errno = errno;
close(master);
+ close(slave);
errno = save_errno;
- return FALSE;
+ return false;
}
/* parent */
- if (close(slave)) {
+ if (close(slave) != 0) {
close(master);
- (void) kill(pid, SIGKILL); /* overkill? (pardon pun) */
+ (void) kill(pid, SIGKILL);
fatal(_("close of slave pty failed (%s)"), strerror(errno));
}
rp->pid = pid;
- rp->iop = iop_alloc(master, str, NULL, TRUE);
- if (rp->iop == NULL) {
- (void) close(master);
- (void) kill(pid, SIGKILL); /* overkill? (pardon pun) */
- return FALSE;
+ rp->iop = iop_alloc(master, str, 0);
+ find_input_parser(rp->iop);
+ iop_finish(rp->iop);
+ if (! rp->iop->valid) {
+ if (! do_traditional && rp->iop->errcode != 0)
+ update_ERRNO_int(rp->iop->errcode);
+ iop_close(rp->iop);
+ rp->iop = NULL;
+ (void) kill(pid, SIGKILL);
+ return false;
}
+ rp->output.name = str;
/*
* Force read and write ends of two-way connection to
* be different fd's so they can be closed independently.
*/
+ rp->output.mode = "w";
if ((dup_master = dup(master)) < 0
- || (rp->fp = fdopen(dup_master, "w")) == NULL) {
+ || (rp->output.fp = fdopen(dup_master, "w")) == NULL) {
iop_close(rp->iop);
rp->iop = NULL;
(void) close(master);
- (void) kill(pid, SIGKILL); /* overkill? (pardon pun) */
+ (void) kill(pid, SIGKILL);
if (dup_master > 0)
(void) close(dup_master);
- return FALSE;
- }
+ return false;
+ } else
+ find_output_wrapper(& rp->output);
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;
+ return true;
}
-#endif /* HAVE_TERMIOS_H */
+#endif /* defined(HAVE_TERMIOS_H) && ! defined(ZOS_USS) */
use_pipes:
#ifndef PIPES_SIMULATED /* real pipes */
- /* case 3: two way pipe to a child process */
+ /* case 4: two way pipe to a child process */
{
int ptoc[2], ctop[2];
int pid;
int save_errno;
-#ifdef __EMX__
+#if defined(__EMX__) || defined(__MINGW32__)
int save_stdout, save_stdin;
+#ifdef __MINGW32__
+ char *qcmd = NULL;
+#endif
#endif
if (pipe(ptoc) < 0)
- return FALSE; /* errno set, diagnostic from caller */
+ 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;
+ return false;
}
-#ifdef __EMX__
+#if defined(__EMX__) || defined(__MINGW32__)
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 */
+ /* if an error occurs close all open file handles */
save_errno = errno;
if (save_stdin != -1)
close(save_stdin);
@@ -1847,7 +2015,7 @@ use_pipes:
close(ptoc[0]); close(ptoc[1]);
close(ctop[0]); close(ctop[1]);
errno = save_errno;
- return FALSE;
+ return false;
}
/* connect pipes to stdin and stdout */
@@ -1876,7 +2044,13 @@ use_pipes:
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 */
+#ifdef __EMX__
pid = spawnl(P_NOWAIT, "/bin/sh", "sh", "-c", str, NULL);
+#else /* __MINGW32__ */
+ pid = spawnl(P_NOWAIT, getenv("ComSpec"), "cmd.exe", "/c",
+ qcmd = quote_cmd(str), NULL);
+ efree(qcmd);
+#endif
/* restore stdin and stdout */
close(1);
@@ -1901,16 +2075,16 @@ use_pipes:
close(ctop[0]);
errno = save_errno;
- return FALSE;
+ return false;
}
-#else /* NOT __EMX__ */
+#else /* NOT __EMX__, NOT __MINGW32__ */
if ((pid = fork()) < 0) {
save_errno = errno;
close(ptoc[0]); close(ptoc[1]);
close(ctop[0]); close(ctop[1]);
errno = save_errno;
- return FALSE;
+ return false;
}
if (pid == 0) { /* child */
@@ -1928,37 +2102,51 @@ use_pipes:
|| 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 */
+ signal(SIGPIPE, SIG_DFL);
execl("/bin/sh", "sh", "-c", str, NULL);
_exit(errno == ENOENT ? 127 : 126);
}
-#endif /* NOT __EMX__ */
+#endif /* NOT __EMX__, NOT __MINGW32__ */
/* parent */
+ if ((BINMODE & BINMODE_INPUT) != 0)
+ os_setbinmode(ctop[0], O_BINARY);
+ if ((BINMODE & BINMODE_OUTPUT) != 0)
+ os_setbinmode(ptoc[1], O_BINARY);
rp->pid = pid;
- rp->iop = iop_alloc(ctop[0], str, NULL, TRUE);
- if (rp->iop == NULL) {
- (void) close(ctop[0]);
+ rp->iop = iop_alloc(ctop[0], str, 0);
+ find_input_parser(rp->iop);
+ iop_finish(rp->iop);
+ if (! rp->iop->valid) {
+ if (! do_traditional && rp->iop->errcode != 0)
+ update_ERRNO_int(rp->iop->errcode);
+ iop_close(rp->iop);
+ rp->iop = NULL;
(void) close(ctop[1]);
(void) close(ptoc[0]);
(void) close(ptoc[1]);
- (void) kill(pid, SIGKILL); /* overkill? (pardon pun) */
+ (void) kill(pid, SIGKILL);
- return FALSE;
+ return false;
}
- rp->fp = fdopen(ptoc[1], "w");
- if (rp->fp == NULL) {
+ rp->output.fp = fdopen(ptoc[1], binmode("w"));
+ rp->output.mode = "w";
+ rp->output.name = str;
+ if (rp->output.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) */
+ (void) kill(pid, SIGKILL);
- return FALSE;
+ return false;
}
+ else
+ find_output_wrapper(& rp->output);
-#ifndef __EMX__
+#if !defined(__EMX__) && !defined(__MINGW32__)
os_close_on_exec(ctop[0], str, "pipe", "from");
os_close_on_exec(ptoc[1], str, "pipe", "from");
@@ -1966,14 +2154,14 @@ use_pipes:
(void) close(ctop[1]);
#endif
- return TRUE;
+ return true;
}
#else /*PIPES_SIMULATED*/
fatal(_("`|&' not supported"));
/*NOTREACHED*/
- return FALSE;
+ return false;
#endif
}
@@ -1990,15 +2178,31 @@ wait_any(int interesting) /* pid of interest, if any */
int status = 0;
struct redirect *redp;
- hstat = signal(SIGHUP, SIG_IGN);
istat = signal(SIGINT, SIG_IGN);
+#ifdef __MINGW32__
+ if (interesting < 0) {
+ status = -1;
+ pid = -1;
+ }
+ else
+ pid = _cwait(& status, interesting, 0);
+ if (pid == interesting && pid > 0) {
+ for (redp = red_head; redp != NULL; redp = redp->next)
+ if (interesting == redp->pid) {
+ redp->pid = -1;
+ redp->status = status;
+ break;
+ }
+ }
+#else
+ hstat = signal(SIGHUP, 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
+# ifdef HAVE_SYS_WAIT_H /* POSIX compatible sys/wait.h */
+ pid = wait(& status);
+# else
+ pid = wait((union wait *) & status);
+# endif
if (interesting && pid == interesting) {
break;
} else if (pid != -1) {
@@ -2013,8 +2217,9 @@ wait_any(int interesting) /* pid of interest, if any */
break;
}
signal(SIGHUP, hstat);
- signal(SIGINT, istat);
signal(SIGQUIT, qstat);
+#endif
+ signal(SIGINT, istat);
return status;
}
@@ -2025,32 +2230,39 @@ gawk_popen(const char *cmd, struct redirect *rp)
{
int p[2];
int pid;
-#ifdef __EMX__
+#if defined(__EMX__) || defined(__MINGW32__)
int save_stdout;
+#ifdef __MINGW32__
+ char *qcmd = NULL;
+#endif
#endif
/*
- * used to wait for any children to synchronize input and output,
+ * We 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 dependent)
+ * and thus has a child process feeding it input (shell dependent).
+ *
+ * (void) wait_any(0); // wait for outstanding processes
*/
- /*(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 */
+#if defined(__EMX__) || defined(__MINGW32__)
rp->iop = NULL;
+ save_stdout = dup(1); /* save stdout */
if (save_stdout == -1) {
- close(p[0]); close(p[1]);
- return rp->iop; /* failed */
+ close(p[0]);
+ close(p[1]);
+ return NULL; /* failed */
}
close(1); /* close stdout */
if (dup(p[1]) != 1) {
- close(p[0]); close(p[1]);
- fatal(_("moving pipe to stdout in child failed (dup: %s)"), strerror(errno));
+ close(p[0]);
+ close(p[1]);
+ fatal(_("moving pipe to stdout in child failed (dup: %s)"),
+ strerror(errno));
}
/* none of these handles must be inherited by the child process */
@@ -2058,8 +2270,14 @@ gawk_popen(const char *cmd, struct redirect *rp)
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 */
-
+
+#ifdef __EMX__
pid = spawnl(P_NOWAIT, "/bin/sh", "sh", "-c", cmd, NULL);
+#else /* __MINGW32__ */
+ pid = spawnl(P_NOWAIT, getenv("ComSpec"), "cmd.exe", "/c",
+ qcmd = quote_cmd(cmd), NULL);
+ efree(qcmd);
+#endif
/* restore stdout */
close(1);
@@ -2069,7 +2287,7 @@ gawk_popen(const char *cmd, struct redirect *rp)
}
close(save_stdout);
-#else /* NOT __EMX__ */
+#else /* NOT __EMX__, NOT __MINGW32__ */
if ((pid = fork()) == 0) {
if (close(1) == -1)
fatal(_("close of stdout in child failed (%s)"),
@@ -2078,26 +2296,35 @@ gawk_popen(const char *cmd, struct redirect *rp)
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));
+ signal(SIGPIPE, SIG_DFL);
execl("/bin/sh", "sh", "-c", cmd, NULL);
_exit(errno == ENOENT ? 127 : 126);
}
-#endif /* NOT __EMX__ */
+#endif /* NOT __EMX__, NOT __MINGW32__ */
if (pid == -1) {
close(p[0]); close(p[1]);
fatal(_("cannot create child process for `%s' (fork: %s)"), cmd, strerror(errno));
}
rp->pid = pid;
-#ifndef __EMX__
+#if !defined(__EMX__) && !defined(__MINGW32__)
if (close(p[1]) == -1) {
close(p[0]);
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, TRUE);
- if (rp->iop == NULL)
- (void) close(p[0]);
+ if ((BINMODE & BINMODE_INPUT) != 0)
+ os_setbinmode(p[0], O_BINARY);
+ rp->iop = iop_alloc(p[0], cmd, 0);
+ find_input_parser(rp->iop);
+ iop_finish(rp->iop);
+ if (! rp->iop->valid) {
+ if (! do_traditional && rp->iop->errcode != 0)
+ update_ERRNO_int(rp->iop->errcode);
+ iop_close(rp->iop);
+ rp->iop = NULL;
+ }
return rp->iop;
}
@@ -2135,14 +2362,21 @@ gawk_popen(const char *cmd, struct redirect *rp)
os_restore_mode(fileno(stdin));
current = popen(cmd, binmode("r"));
- if ((BINMODE & 1) != 0)
+ if ((BINMODE & BINMODE_INPUT) != 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, TRUE);
- if (rp->iop == NULL) {
+ rp->iop = iop_alloc(fileno(current), cmd, 0);
+ find_input_parser(rp->iop);
+ iop_finish(rp->iop);
+ if (! rp->iop->valid) {
+ if (! do_traditional && rp->iop->errcode != 0)
+ update_ERRNO_int(rp->iop->errcode);
(void) pclose(current);
+ rp->iop->public.fd = INVALID_HANDLE;
+ iop_close(rp->iop);
+ rp->iop = NULL;
current = NULL;
}
rp->ifp = current;
@@ -2154,10 +2388,10 @@ gawk_popen(const char *cmd, struct redirect *rp)
static int
gawk_pclose(struct redirect *rp)
{
- int rval, aval, fd = rp->iop->fd;
+ int rval, aval, fd = rp->iop->public.fd;
if (rp->iop != NULL) {
- rp->iop->fd = dup(fd); /* kludge to allow close() + pclose() */
+ rp->iop->public.fd = dup(fd); /* kludge to allow close() + pclose() */
rval = iop_close(rp->iop);
}
rp->iop = NULL;
@@ -2168,10 +2402,10 @@ gawk_pclose(struct redirect *rp)
#endif /* PIPES_SIMULATED */
-/* do_getline --- read in a line, into var and with redirection */
+/* do_getline_redir --- read in a line, into var and with redirection */
NODE *
-do_getline_redir(int intovar, int redirtype)
+do_getline_redir(int into_variable, enum redirval redirtype)
{
struct redirect *rp = NULL;
IOBUF *iop;
@@ -2182,18 +2416,18 @@ do_getline_redir(int intovar, int redirtype)
NODE **lhs = NULL;
int redir_error = 0;
- if (intovar)
+ if (into_variable)
lhs = POP_ADDRESS();
- assert(redirtype != 0);
+ assert(redirtype != redirect_none);
redir_exp = TOP();
- rp = redirect(redir_exp, redirtype, &redir_error);
+ rp = redirect(redir_exp, redirtype, & redir_error);
DEREF(redir_exp);
decr_sp();
if (rp == NULL) {
if (redir_error) { /* failed redirect */
if (! do_traditional)
- update_ERRNO_saved(redir_error);
+ update_ERRNO_int(redir_error);
}
return make_number((AWKNUM) -1.0);
}
@@ -2202,10 +2436,10 @@ do_getline_redir(int intovar, int redirtype)
return make_number((AWKNUM) 0.0);
errcode = 0;
- cnt = get_a_record(&s, iop, &errcode);
+ cnt = get_a_record(& s, iop, & errcode);
if (errcode != 0) {
if (! do_traditional && (errcode != -1))
- update_ERRNO_saved(errcode);
+ update_ERRNO_int(errcode);
return make_number((AWKNUM) -1.0);
}
@@ -2237,34 +2471,34 @@ do_getline_redir(int intovar, int redirtype)
/* do_getline --- read in a line, into var and without redirection */
NODE *
-do_getline(int intovar, IOBUF *iop)
+do_getline(int into_variable, IOBUF *iop)
{
int cnt = EOF;
char *s = NULL;
int errcode;
if (iop == NULL) { /* end of input */
- if (intovar)
+ if (into_variable)
(void) POP_ADDRESS();
return make_number((AWKNUM) 0.0);
}
errcode = 0;
- cnt = get_a_record(&s, iop, &errcode);
+ cnt = get_a_record(& s, iop, & errcode);
if (errcode != 0) {
if (! do_traditional && (errcode != -1))
- update_ERRNO_saved(errcode);
- if (intovar)
+ update_ERRNO_int(errcode);
+ if (into_variable)
(void) POP_ADDRESS();
return make_number((AWKNUM) -1.0);
}
if (cnt == EOF)
return NULL; /* try next file */
- NR++;
- FNR++;
+ INCREMENT_REC(NR);
+ INCREMENT_REC(FNR);
- if (! intovar) /* no optional var. */
+ if (! into_variable) /* no optional var. */
set_record(s, cnt);
else { /* assignment to variable */
NODE **lhs;
@@ -2276,35 +2510,42 @@ do_getline(int intovar, IOBUF *iop)
return make_number((AWKNUM) 1.0);
}
+typedef struct {
+ const char *envname;
+ char **dfltp; /* pointer to address of default path */
+ char **awkpath; /* array containing library search paths */
+ int max_pathlen; /* length of the longest item in awkpath */
+} path_info;
+
+static path_info pi_awkpath = {
+ /* envname */ "AWKPATH",
+ /* dfltp */ & defpath,
+};
-static char **awkpath = NULL; /* array containing library search paths */
-static int max_pathlen; /* length of the longest item in awkpath */
+static path_info pi_awklibpath = {
+ /* envname */ "AWKLIBPATH",
+ /* dfltp */ & deflibpath,
+};
/* init_awkpath --- split path(=$AWKPATH) into components */
static void
-init_awkpath(char *path)
+init_awkpath(path_info *pi)
{
+ char *path;
char *start, *end, *p;
int len, i;
- static int max_path = 0;
+ int max_path; /* (# of allocated paths)-1 */
#define INC_PATH 5
- max_pathlen = 0;
- if (path == NULL || *path == '\0')
- path = defpath;
-
- for (i = 0; i < max_path && awkpath[i]; i++) {
- efree(awkpath[i]);
- awkpath[i] = NULL;
- }
+ pi->max_pathlen = 0;
+ if ((path = getenv(pi->envname)) == NULL || *path == '\0')
+ path = pi->dfltp[0];
- if (max_path == 0) {
- max_path = INC_PATH;
- emalloc(awkpath, char **, (max_path + 1) * sizeof(char *), "init_awkpath");
- memset(awkpath, 0, (max_path + 1) * sizeof(char *));
- }
+ max_path = INC_PATH;
+ emalloc(pi->awkpath, char **, (max_path + 1) * sizeof(char *), "init_awkpath");
+ memset(pi->awkpath, 0, (max_path + 1) * sizeof(char *));
end = start = path;
i = 0;
@@ -2317,18 +2558,18 @@ init_awkpath(char *path)
memcpy(p, start, len);
/* add directory punctuation if necessary */
- if (! isdirpunct(*(end - 1)))
+ if (! isdirpunct(end[-1]))
p[len++] = '/';
p[len] = '\0';
if (i == max_path) {
max_path += INC_PATH;
- erealloc(awkpath, char **, (max_path + 1) * sizeof(char *), "init_awkpath");
- memset(awkpath + i, 0, (INC_PATH + 1) * sizeof(char *));
+ erealloc(pi->awkpath, char **, (max_path + 1) * sizeof(char *), "init_awkpath");
+ memset(pi->awkpath + i, 0, (INC_PATH + 1) * sizeof(char *));
}
- awkpath[i++] = p;
- if (len > max_pathlen)
- max_pathlen = len;
+ pi->awkpath[i++] = p;
+ if (len > pi->max_pathlen)
+ pi->max_pathlen = len;
}
/* skip one or more envsep char */
@@ -2336,7 +2577,7 @@ init_awkpath(char *path)
end++;
start = end;
}
- awkpath[i] = NULL;
+ pi->awkpath[i] = NULL;
#undef INC_PATH
}
@@ -2344,7 +2585,7 @@ init_awkpath(char *path)
/* do_find_source --- search $AWKPATH for file, return NULL if not found */
static char *
-do_find_source(const char *src, struct stat *stb, int *errcode)
+do_find_source(const char *src, struct stat *stb, int *errcode, path_info *pi)
{
char *path;
int i;
@@ -2362,22 +2603,15 @@ do_find_source(const char *src, struct stat *stb, int *errcode)
return NULL;
}
- /* try current directory before path search */
- if (stat(src, stb) == 0) {
- emalloc(path, char *, strlen(src) + 1, "do_find_source");
- strcpy(path, src);
- return path;
- }
-
- if (awkpath == NULL)
- init_awkpath(getenv("AWKPATH"));
+ if (pi->awkpath == NULL)
+ init_awkpath(pi);
- emalloc(path, char *, max_pathlen + strlen(src) + 1, "do_find_source");
- for (i = 0; awkpath[i] != NULL; i++) {
- if (STREQ(awkpath[i], "./") || STREQ(awkpath[i], ".")) {
+ emalloc(path, char *, pi->max_pathlen + strlen(src) + 1, "do_find_source");
+ for (i = 0; pi->awkpath[i] != NULL; i++) {
+ if (strcmp(pi->awkpath[i], "./") == 0 || strcmp(pi->awkpath[i], ".") == 0)
*path = '\0';
- } else
- strcpy(path, awkpath[i]);
+ else
+ strcpy(path, pi->awkpath[i]);
strcat(path, src);
if (stat(path, stb) == 0)
return path;
@@ -2392,19 +2626,54 @@ do_find_source(const char *src, struct stat *stb, int *errcode)
/* find_source --- find source file with default file extension handling */
char *
-find_source(const char *src, struct stat *stb, int *errcode)
+find_source(const char *src, struct stat *stb, int *errcode, int is_extlib)
{
char *path;
+ path_info *pi = (is_extlib ? & pi_awklibpath : & pi_awkpath);
*errcode = 0;
if (src == NULL || *src == '\0')
return NULL;
- path = do_find_source(src, stb, errcode);
+ path = do_find_source(src, stb, errcode, pi);
+
+ if (path == NULL && is_extlib) {
+ char *file_ext;
+ int save_errno;
+ size_t src_len;
+ size_t suffix_len;
+
+#define EXTLIB_SUFFIX "." SHLIBEXT
+ src_len = strlen(src);
+ suffix_len = strlen(EXTLIB_SUFFIX);
+
+ /* check if already has the SUFFIX */
+ if (src_len >= suffix_len && strcmp(& src[src_len - suffix_len], EXTLIB_SUFFIX) == 0)
+ return NULL;
+
+ /* append EXTLIB_SUFFIX and try again */
+ save_errno = errno;
+ emalloc(file_ext, char *, src_len + suffix_len + 1, "find_source");
+ sprintf(file_ext, "%s%s", src, EXTLIB_SUFFIX);
+ path = do_find_source(file_ext, stb, errcode, pi);
+ efree(file_ext);
+ if (path == NULL)
+ errno = save_errno;
+ return path;
+#undef EXTLIB_SUFFIX
+ }
+
+/*
+ * Try searching with .awk appended if the platform headers have not specified
+ * another suffix.
+ */
+#ifndef DEFAULT_FILETYPE
+#define DEFAULT_FILETYPE ".awk"
+#endif
#ifdef DEFAULT_FILETYPE
if (! do_traditional && path == NULL) {
char *file_awk;
- int save = errno;
+ int save_errno = errno;
#ifdef VMS
int vms_save = vaxc$errno;
#endif
@@ -2413,10 +2682,10 @@ find_source(const char *src, struct stat *stb, int *errcode)
emalloc(file_awk, char *, strlen(src) +
sizeof(DEFAULT_FILETYPE) + 1, "find_source");
sprintf(file_awk, "%s%s", src, DEFAULT_FILETYPE);
- path = do_find_source(file_awk, stb, errcode);
+ path = do_find_source(file_awk, stb, errcode, pi);
efree(file_awk);
if (path == NULL) {
- errno = save;
+ errno = save_errno;
#ifdef VMS
vaxc$errno = vms_save;
#endif
@@ -2427,105 +2696,324 @@ find_source(const char *src, struct stat *stb, int *errcode)
return path;
}
+
/* srcopen --- open source file */
int
srcopen(SRCFILE *s)
{
+ int fd = INVALID_HANDLE;
+
if (s->stype == SRC_STDIN)
- return (0);
- if (s->stype == SRC_FILE || s->stype == SRC_INC)
- return devopen(s->fullpath, "r");
- return INVALID_HANDLE;
+ fd = fileno(stdin);
+ else if (s->stype == SRC_FILE || s->stype == SRC_INC)
+ fd = devopen(s->fullpath, "r");
+
+ /* set binary mode so that debugger byte offset calculations will be right */
+ if (fd != INVALID_HANDLE)
+ os_setbinmode(fd, O_BINARY);
+
+ return fd;
}
-#ifdef TEST
-int bufsize = 8192;
+/* input parsers, mainly for use by extension functions */
+
+static awk_input_parser_t *ip_head, *ip_tail;
+
+/*
+ * register_input_parser --- add an input parser to the list, FIFO.
+ * The main reason to use FIFO is to provide the diagnostic
+ * with the correct information: input parser 2 conflicts
+ * with input parser 1. Otherwise LIFO would have been easier.
+ */
void
-fatal(const char *s)
+register_input_parser(awk_input_parser_t *input_parser)
{
- printf("%s\n", s);
- exit(EXIT_FAILURE);
+ if (input_parser == NULL)
+ fatal(_("register_input_parser: received NULL pointer"));
+
+ input_parser->next = NULL; /* force it */
+ if (ip_head == NULL) {
+ ip_head = ip_tail = input_parser;
+ } else {
+ ip_tail->next = input_parser;
+ ip_tail = ip_tail->next;
+ }
}
-#endif
-/* open hooks, mainly for use by extension functions */
+/* find_input_parser --- search the list of input parsers */
-static struct open_hook {
- struct open_hook *next;
- void *(*open_func)(IOBUF *);
-} *open_hooks;
+static void
+find_input_parser(IOBUF *iop)
+{
+ awk_input_parser_t *ip, *ip2;
-/* register_open_hook --- add an open hook to the list */
+ /* if already associated with an input parser, bail out early */
+ if (iop->public.get_record != NULL)
+ return;
+
+ ip = ip2 = NULL;
+ for (ip2 = ip_head; ip2 != NULL; ip2 = ip2->next) {
+ if (ip2->can_take_file(& iop->public)) {
+ if (ip == NULL)
+ ip = ip2; /* found first one */
+ else
+ fatal(_("input parser `%s' conflicts with previously installed input parser `%s'"),
+ ip2->name, ip->name);
+ }
+ }
+
+ if (ip != NULL) {
+ if (! ip->take_control_of(& iop->public))
+ warning(_("input parser `%s' failed to open `%s'"),
+ ip->name, iop->public.name);
+ else
+ iop->valid = true;
+ }
+}
+
+/* output wrappers --- for use by extensions */
+
+static awk_output_wrapper_t *op_head, *op_tail;
+
+/*
+ * register_output_wrapper --- add an output wrapper to the list.
+ * Same stuff here as for input parsers.
+ */
void
-register_open_hook(void *(*open_func)(IOBUF *))
+register_output_wrapper(awk_output_wrapper_t *wrapper)
{
- struct open_hook *oh;
+ if (wrapper == NULL)
+ fatal(_("register_output_wrapper: received NULL pointer"));
- emalloc(oh, struct open_hook *, sizeof(*oh), "register_open_hook");
- oh->open_func = open_func;
- oh->next = open_hooks;
- open_hooks = oh;
+ wrapper->next = NULL; /* force it */
+ if (op_head == NULL) {
+ op_head = op_tail = wrapper;
+ } else {
+ op_tail->next = wrapper;
+ op_tail = op_tail->next;
+ }
}
-/* find_open_hook --- search the list of open hooks */
+/* find_output_wrapper --- search the list of output wrappers */
-static void
-find_open_hook(IOBUF *iop)
+static bool
+find_output_wrapper(awk_output_buf_t *outbuf)
{
- struct open_hook *oh;
+ awk_output_wrapper_t *op, *op2;
- /* 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 already associated with an output wrapper, bail out early */
+ if (outbuf->redirected)
+ return false;
+
+ op = op2 = NULL;
+ for (op2 = op_head; op2 != NULL; op2 = op2->next) {
+ if (op2->can_take_file(outbuf)) {
+ if (op == NULL)
+ op = op2; /* found first one */
+ else
+ fatal(_("output wrapper `%s' conflicts with previously installed output wrapper `%s'"),
+ op2->name, op->name);
+ }
+ }
+
+ if (op != NULL) {
+ if (! op->take_control_of(outbuf)) {
+ warning(_("output wrapper `%s' failed to open `%s'"),
+ op->name, outbuf->name);
+ return false;
+ }
+ return true;
+ }
+
+ return false;
+}
+
+
+/* two way processors --- for use by extensions */
+
+static awk_two_way_processor_t *tw_head, *tw_tail;
+
+/* register_two_way_processor --- register a two-way I/O processor, for extensions */
+
+void
+register_two_way_processor(awk_two_way_processor_t *processor)
+{
+ if (processor == NULL)
+ fatal(_("register_output_processor: received NULL pointer"));
+
+ processor->next = NULL; /* force it */
+ if (tw_head == NULL) {
+ tw_head = tw_tail = processor;
+ } else {
+ tw_tail->next = processor;
+ tw_tail = tw_tail->next;
}
}
+/* find_two_way_processor --- search the list of two way processors */
+
+static bool
+find_two_way_processor(const char *name, struct redirect *rp)
+{
+ awk_two_way_processor_t *tw, *tw2;
+
+ /* if already associated with i/o, bail out early */
+ if ( (rp->iop != NULL && rp->iop->public.fd != INVALID_HANDLE)
+ || rp->output.fp != NULL)
+ return false;
+
+ tw = tw2 = NULL;
+ for (tw2 = tw_head; tw2 != NULL; tw2 = tw2->next) {
+ if (tw2->can_take_two_way(name)) {
+ if (tw == NULL)
+ tw = tw2; /* found first one */
+ else
+ fatal(_("two-way processor `%s' conflicts with previously installed two-way processor `%s'"),
+ tw2->name, tw->name);
+ }
+ }
+
+ if (tw != NULL) {
+ if (rp->iop == NULL)
+ rp->iop = iop_alloc(INVALID_HANDLE, name, 0);
+ if (! tw->take_control_of(name, & rp->iop->public, & rp->output)) {
+ warning(_("two way processor `%s' failed to open `%s'"),
+ tw->name, name);
+ return false;
+ }
+ iop_finish(rp->iop);
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * IOBUF management is somewhat complicated. In particular,
+ * it is possible and OK for an IOBUF to be allocated with
+ * a file descriptor that is either valid or not usable with
+ * read(2), in case an input parser will come along later and
+ * make it readable. Alternatively, an input parser can simply
+ * come along and take over reading on a valid readable descriptor.
+ *
+ * The first stage is simply to allocate the IOBUF. This is done
+ * during nextfile() for command line files and by redirect()
+ * and other routines for getline, input pipes, and the input
+ * side of a two-way pipe.
+ *
+ * The second stage is to check for input parsers. This is done
+ * for command line files in after_beginfile() and for the others
+ * as part of the full flow. At this point, either:
+ * - The fd is valid on a readable file
+ * - The input parser has taken over a valid fd and made
+ * it usable (e.g., directories)
+ * - Or the input parser has simply hijacked the reading
+ * (such as the gawkextlib XML extension)
+ * If none of those are true, the fd should be closed, reset
+ * to INVALID_HANDLE, and iop->errcode set to indicate the error
+ * (EISDIR for directories, EIO for anything else).
+ * iop->valid should be set to false in this case.
+ *
+ * Otherwise, after the second stage, iop->errcode should be
+ * zero, iop->valid should be true, and iop->public.fd should
+ * not be INVALID_HANDLE.
+ *
+ * The third stage is to set up the rest of the IOBUF for
+ * use by get_a_record(). In this case, iop->valid must
+ * be true already, and iop->public.fd cannot be INVALID_HANDLE.
+ *
+ * Checking for input parsers for command line files is delayed
+ * to after_beginfile() so that the BEGINFILE rule has an
+ * opportunity to look at FILENAME and ERRNO and attempt to
+ * recover with a custom input parser. The XML extension, in
+ * particular, relies strongly upon this ability.
+ */
+
/* iop_alloc --- allocate an IOBUF structure for an open fd */
static IOBUF *
-iop_alloc(int fd, const char *name, IOBUF *iop, int do_openhooks)
+iop_alloc(int fd, const char *name, int errno_val)
{
- struct stat sbuf;
- int iop_malloced = FALSE;
+ IOBUF *iop;
+
+ emalloc(iop, IOBUF *, sizeof(IOBUF), "iop_alloc");
- if (iop == NULL) {
- emalloc(iop, IOBUF *, sizeof(IOBUF), "iop_alloc");
- iop_malloced = TRUE;
- }
memset(iop, '\0', sizeof(IOBUF));
- iop->flag = 0;
- iop->fd = fd;
- iop->name = name;
+ iop->public.fd = fd;
+ iop->public.name = name;
+ iop->public.read_func = ( ssize_t(*)() ) read;
+ iop->valid = false;
+ iop->errcode = errno_val;
+
+ if (fd != INVALID_HANDLE)
+ fstat(fd, & iop->public.sbuf);
+#if defined(__EMX__) || defined(__MINGW32__)
+ else if (errno_val == EISDIR) {
+ iop->public.sbuf.st_mode = (_S_IFDIR | _S_IRWXU);
+ iop->public.fd = FAKE_FD_VALUE;
+ }
+#endif
- if (do_openhooks)
- find_open_hook(iop);
- else if (iop->fd == INVALID_HANDLE)
- return iop;
+ return iop;
+}
- /* test reached if tried to find open hook and could not */
- if (iop->fd == INVALID_HANDLE) {
- if (iop_malloced)
- efree(iop);
- return NULL;
+/* iop_finish --- finish setting up an IOBUF */
+
+static IOBUF *
+iop_finish(IOBUF *iop)
+{
+ bool isdir = false;
+
+ if (iop->public.fd != INVALID_HANDLE) {
+ if (os_isreadable(& iop->public, & isdir))
+ iop->valid = true;
+ else {
+ if (isdir)
+ iop->errcode = EISDIR;
+ else {
+ iop->errcode = EIO;
+ /*
+ * Extensions can supply values that are not
+ * INVALID_HANDLE but that are also not real
+ * file descriptors. So check the fd before
+ * trying to close it, which avoids errors
+ * on some operating systems.
+ *
+ * The fcntl call works for Windows, too.
+ */
+#if defined(F_GETFL)
+ if (fcntl(iop->public.fd, F_GETFL) >= 0)
+#endif
+ (void) close(iop->public.fd);
+ iop->public.fd = INVALID_HANDLE;
+ }
+ /*
+ * Don't close directories: after_beginfile(),
+ * special cases them.
+ */
+ }
}
- if (os_isatty(iop->fd))
+ if (! iop->valid || iop->public.fd == INVALID_HANDLE)
+ return iop;
+
+ if (os_isatty(iop->public.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->readsize = iop->size = optimal_bufsize(iop->public.fd, & iop->public.sbuf);
+ if (do_lint && S_ISREG(iop->public.sbuf.st_mode) && iop->public.sbuf.st_size == 0)
+ lintwarn(_("data file `%s' is empty"), iop->public.name);
+ iop->errcode = errno = 0;
iop->count = iop->scanoff = 0;
- emalloc(iop->buf, char *, iop->size += 2, "iop_alloc");
+ emalloc(iop->buf, char *, iop->size += 2, "iop_finish");
iop->off = iop->buf;
iop->dataend = NULL;
iop->end = iop->buf + iop->size;
iop->flag |= IOP_AT_START;
+
return iop;
}
@@ -2537,12 +3025,12 @@ iop_alloc(int fd, const char *name, IOBUF *iop, int do_openhooks)
(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 */
+/*
+ * grow_iop_buffer:
+ *
+ * grow must increase size of buffer, set end, make sure off and dataend
+ * point at the right spot.
+ */
static void
grow_iop_buffer(IOBUF *iop)
@@ -2576,10 +3064,8 @@ grow_iop_buffer(IOBUF *iop)
iop->end = iop->buf + iop->size;
}
-/* Here are the routines. */
-/* */
-/* */
-/* <rs1scan>= */
+/* Here are the routines. */
+
/* rs1scan --- scan for a single character record terminator */
static RECVALUE
@@ -2587,10 +3073,8 @@ rs1scan(IOBUF *iop, struct recmatch *recm, SCANSTATE *state)
{
char *bp;
char rs;
-#if MBS_SUPPORT
size_t mbclen = 0;
mbstate_t mbs;
-#endif
memset(recm, '\0', sizeof(struct recmatch));
rs = RS->stptr[0];
@@ -2601,7 +3085,6 @@ rs1scan(IOBUF *iop, struct recmatch *recm, SCANSTATE *state)
if (*state == INDATA) /* skip over data we've already seen */
bp += iop->scanoff;
-#if MBS_SUPPORT
/*
* From: Bruno Haible <bruno@clisp.org>
* To: Aharon Robbins <arnold@skeeve.com>, gnits@gnits.org
@@ -2660,19 +3143,19 @@ rs1scan(IOBUF *iop, struct recmatch *recm, SCANSTATE *state)
int len = iop->dataend - bp;
int found = 0;
- memset(&mbs, 0, sizeof(mbstate_t));
+ memset(& mbs, 0, sizeof(mbstate_t));
do {
if (*bp == rs)
found = 1;
if (is_valid_character(*bp))
mbclen = 1;
else
- 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 = mbrlen(bp, len, & mbs);
+ if ( mbclen == 1
+ || mbclen == (size_t) -1
+ || mbclen == (size_t) -2
+ || mbclen == 0) {
+ /* We treat it as a single-byte character. */
mbclen = 1;
}
len -= mbclen;
@@ -2682,8 +3165,8 @@ rs1scan(IOBUF *iop, struct recmatch *recm, SCANSTATE *state)
/* 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
+ * 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;
@@ -2698,7 +3181,7 @@ rs1scan(IOBUF *iop, struct recmatch *recm, SCANSTATE *state)
return NOTERM;
}
}
-#endif
+
while (*bp != rs)
bp++;
@@ -2717,7 +3200,6 @@ rs1scan(IOBUF *iop, struct recmatch *recm, SCANSTATE *state)
}
}
-/* <rsrescan>= */
/* rsrescan --- search for a regex match in the buffer */
static RECVALUE
@@ -2807,21 +3289,15 @@ again:
* 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
+ * The re->maybe_long member is true 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)) {
+ if (RSre->maybe_long) {
char *matchend = iop->off + reend;
if (iop->dataend - matchend < RS->stlen)
@@ -2831,7 +3307,6 @@ again:
return REC_OK;
}
-/* <rsnullscan>= */
/* rsnullscan --- handle RS = "" */
static RECVALUE
@@ -2908,8 +3383,11 @@ find_longest_terminator:
return REC_OK;
}
-/* <getarecord>= */
-/* get_a_record --- read a record from IOP into out, return length of EOF, set RT */
+/*
+ * get_a_record --- read a record from IOP into out,
+ * return length of EOF, set RT.
+ * Note that errcode is never NULL, and the caller initializes *errcode to 0.
+ */
static int
get_a_record(char **out, /* pointer to pointer to data */
@@ -2926,19 +3404,34 @@ get_a_record(char **out, /* pointer to pointer to data */
if (at_eof(iop) && no_data_left(iop))
return EOF;
- if (iop->get_record != NULL)
- return (*iop->get_record)(out, iop, errcode);
+ if (read_can_timeout)
+ read_timeout = get_read_timeout(iop);
- /* <fill initial buffer>= */
+ if (iop->public.get_record != NULL) {
+ char *rt_start;
+ size_t rt_len;
+ int rc = iop->public.get_record(out, &iop->public, errcode,
+ &rt_start, &rt_len);
+ if (rc == EOF)
+ iop->flag |= IOP_AT_EOF;
+ else {
+ if (rt_len != 0)
+ set_RT(rt_start, rt_len);
+ else
+ set_RT_to_null();
+ }
+ return rc;
+ }
+
+ /* fill initial buffer */
if (has_no_data(iop) || no_data_left(iop)) {
- iop->count = read(iop->fd, iop->buf, iop->readsize);
+ iop->count = iop->public.read_func(iop->public.fd, iop->buf, iop->readsize);
if (iop->count == 0) {
iop->flag |= IOP_AT_EOF;
return EOF;
} else if (iop->count == -1) {
iop->flag |= IOP_AT_EOF;
- if (errcode != NULL)
- *errcode = errno;
+ *errcode = errno;
return EOF;
} else {
iop->dataend = iop->buf + iop->count;
@@ -2946,75 +3439,90 @@ get_a_record(char **out, /* pointer to pointer to data */
}
}
- /* <loop through file to find a record>= */
+ /* loop through file to find a record */
state = NOSTATE;
for (;;) {
size_t dataend_off;
+ size_t room_left;
+ size_t amt_to_read;
ret = (*matchrec)(iop, & recm, & state);
iop->flag &= ~IOP_AT_START;
+ /* found the record, we're done, break the loop */
if (ret == REC_OK)
break;
+ /*
+ * Likely found the record; if there's no more data
+ * to be had (like from a tiny regular file), break the
+ * loop. Otherwise, see if we can read more.
+ */
+ if (ret == TERMNEAREND && buffer_has_all_data(iop))
+ break;
+
/* need to add more data to buffer */
- /* <shift data down in 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>= */
+ /* 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>= */
- {
-#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;
+ /* read more data, break if EOF */
+#ifndef MIN
+#define MIN(x, y) (x < y ? x : y)
+#endif
+ /* subtract one in read count to leave room for sentinel */
+ room_left = iop->end - iop->dataend - 1;
+ 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;
#ifdef SSIZE_MAX
- /*
- * POSIX limits read to SSIZE_MAX. There are (bizarre)
- * systems where this amount is small.
- */
- amt_to_read = min(amt_to_read, SSIZE_MAX);
+ /*
+ * POSIX limits read to SSIZE_MAX. There are (bizarre)
+ * systems where this amount is small.
+ */
+ amt_to_read = MIN(amt_to_read, SSIZE_MAX);
#endif
- iop->count = read(iop->fd, iop->dataend, amt_to_read);
- if (iop->count == -1) {
- *errcode = errno;
- iop->flag |= IOP_AT_EOF;
- break;
- } else if (iop->count == 0) {
- /*
- * hit EOF before matching RS, so end
- * the record and set RT to ""
- */
+ iop->count = iop->public.read_func(iop->public.fd, iop->dataend, amt_to_read);
+ if (iop->count == -1) {
+ *errcode = errno;
+ iop->flag |= IOP_AT_EOF;
+ break;
+ } else if (iop->count == 0) {
+ /*
+ * Hit EOF before being certain that we've matched
+ * the end of the record. If ret is TERMNEAREND,
+ * we need to pull out what we've got in the buffer.
+ * Eventually we'll come back here and see the EOF,
+ * end the record and set RT to "".
+ */
+ if (ret != TERMNEAREND)
iop->flag |= IOP_AT_EOF;
- break;
- } else
- iop->dataend += iop->count;
- }
+ break;
+ } else
+ iop->dataend += iop->count;
}
- /* <set record, RT, return right value>= */
+ /* set record, RT, return right value */
/*
* rtval is not a static pointer to avoid dangling pointer problems
@@ -3101,7 +3609,7 @@ set_RS()
}
unref(save_rs);
save_rs = dupnode(RS_node->var_value);
- RS_is_null = FALSE;
+ RS_is_null = false;
RS = force_string(RS_node->var_value);
/*
* used to be if (RS_regexp != NULL) { refree(..); refree(..); ...; }.
@@ -3113,20 +3621,20 @@ set_RS()
RS_re_yes_case = RS_re_no_case = RS_regexp = NULL;
if (RS->stlen == 0) {
- RS_is_null = TRUE;
+ RS_is_null = true;
matchrec = rsnullscan;
} else if (RS->stlen > 1) {
- static short warned = FALSE;
+ static bool warned = false;
- RS_re_yes_case = make_regexp(RS->stptr, RS->stlen, FALSE, TRUE, TRUE);
- RS_re_no_case = make_regexp(RS->stptr, RS->stlen, TRUE, TRUE, TRUE);
+ RS_re_yes_case = make_regexp(RS->stptr, RS->stlen, false, true, true);
+ RS_re_no_case = make_regexp(RS->stptr, RS->stlen, true, 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;
+ warned = true;
}
} else
matchrec = rs1scan;
@@ -3135,6 +3643,7 @@ set_FS:
set_FS();
}
+
/* pty_vs_pipe --- return true if should use pty instead of pipes for `|&' */
/*
@@ -3145,36 +3654,21 @@ static int
pty_vs_pipe(const char *command)
{
#ifdef HAVE_TERMIOS_H
- char *full_index;
- size_t full_len;
- NODE *val, *sub;
+ NODE *val;
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 = make_string(full_index, strlen(full_index));
- val = in_array(PROCINFO_node, sub);
- unref(sub);
- efree(full_index);
-
+ return false;
+ val = in_PROCINFO(command, "pty", NULL);
if (val) {
- if (val->flags & MAYBE_NUM)
+ if ((val->flags & MAYBE_NUM) != 0)
(void) force_number(val);
- if (val->flags & NUMBER)
- return (val->numbr != 0.0);
+ if ((val->flags & NUMBER) != 0)
+ return ! iszero(val);
else
return (val->stlen != 0);
}
#endif /* HAVE_TERMIOS_H */
- return FALSE;
+ return false;
}
/* iopflags2str --- make IOP flags printable */
@@ -3184,7 +3678,6 @@ iopflags2str(int flag)
{
static const struct flagtab values[] = {
{ IOP_IS_TTY, "IOP_IS_TTY" },
- { IOP_NOFREE_OBJ, "IOP_NOFREE_OBJ" },
{ IOP_AT_EOF, "IOP_AT_EOF" },
{ IOP_CLOSED, "IOP_CLOSED" },
{ IOP_AT_START, "IOP_AT_START" },
@@ -3205,33 +3698,290 @@ free_rp(struct redirect *rp)
/* inetfile --- return true for a /inet special file, set other values */
-static int
-inetfile(const char *str, int *length, int *family)
+static bool
+inetfile(const char *str, struct inet_socket_info *isi)
{
- int ret = FALSE;
-
- if (STREQN(str, "/inet/", 6)) {
- ret = TRUE;
- if (length != NULL)
- *length = 6;
- if (family != NULL)
- *family = AF_UNSPEC;
- } else if (STREQN(str, "/inet4/", 7)) {
- ret = TRUE;
- if (length != NULL)
- *length = 7;
- if (family != NULL)
- *family = AF_INET;
- } else if (STREQN(str, "/inet6/", 7)) {
- ret = TRUE;
- if (length != NULL)
- *length = 7;
- if (family != NULL)
- *family = AF_INET6;
+#ifndef HAVE_SOCKETS
+ return false;
+#else
+ const char *cp = str;
+ struct inet_socket_info buf;
+
+ /* syntax: /inet/protocol/localport/hostname/remoteport */
+ if (strncmp(cp, "/inet", 5) != 0)
+ /* quick exit */
+ return false;
+ if (! isi)
+ isi = & buf;
+ cp += 5;
+ switch (*cp) {
+ case '/':
+ isi->family = AF_UNSPEC;
+ break;
+ case '4':
+ if (*++cp != '/')
+ return false;
+ isi->family = AF_INET;
+ break;
+ case '6':
+ if (*++cp != '/')
+ return false;
+ isi->family = AF_INET6;
+ break;
+ default:
+ return false;
+ }
+ cp++; /* skip past '/' */
+
+ /* which protocol? */
+ if (strncmp(cp, "tcp/", 4) == 0)
+ isi->protocol = SOCK_STREAM;
+ else if (strncmp(cp, "udp/", 4) == 0)
+ isi->protocol = SOCK_DGRAM;
+ else
+ return false;
+ cp += 4;
+
+ /* which localport? */
+ isi->localport.offset = cp-str;
+ while (*cp != '/' && *cp != '\0')
+ cp++;
+ /*
+ * Require a port, let them explicitly put 0 if
+ * they don't care.
+ */
+ if (*cp != '/' || ((isi->localport.len = (cp-str)-isi->localport.offset) == 0))
+ return false;
+
+ /* which hostname? */
+ cp++;
+ isi->remotehost.offset = cp-str;
+ while (*cp != '/' && *cp != '\0')
+ cp++;
+ if (*cp != '/' || ((isi->remotehost.len = (cp-str)-isi->remotehost.offset) == 0))
+ return false;
+
+ /* 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.
+ */
+ isi->remoteport.offset = cp-str;
+ while (*cp != '/' && *cp != '\0')
+ cp++;
+ if (*cp != '\0' || ((isi->remoteport.len = (cp-str)-isi->remoteport.offset) == 0))
+ return false;
+
#ifndef HAVE_GETADDRINFO
+ /* final check for IPv6: */
+ if (isi->family == AF_INET6)
fatal(_("IPv6 communication is not supported"));
#endif
- }
+ return true;
+#endif /* HAVE_SOCKETS */
+}
- return ret;
+/*
+ * in_PROCINFO --- return value for a PROCINFO element with
+ * SUBSEP seperated indices.
+ */
+
+static NODE *
+in_PROCINFO(const char *pidx1, const char *pidx2, NODE **full_idx)
+{
+ char *str;
+ size_t str_len;
+ NODE *r, *sub = NULL;
+ NODE *subsep = SUBSEP_node->var_value;
+
+ /* full_idx is in+out parameter */
+
+ if (full_idx)
+ sub = *full_idx;
+
+ str_len = strlen(pidx1) + subsep->stlen + strlen(pidx2);
+ if (sub == NULL) {
+ emalloc(str, char *, str_len + 1, "in_PROCINFO");
+ sub = make_str_node(str, str_len, ALREADY_MALLOCED);
+ if (full_idx)
+ *full_idx = sub;
+ } else if (str_len != sub->stlen) {
+ /* *full_idx != NULL */
+
+ assert(sub->valref == 1);
+ erealloc(sub->stptr, char *, str_len + 1, "in_PROCINFO");
+ sub->stlen = str_len;
+ }
+
+ sprintf(sub->stptr, "%s%.*s%s", pidx1, (int)subsep->stlen,
+ subsep->stptr, pidx2);
+ r = in_array(PROCINFO_node, sub);
+ if (! full_idx)
+ unref(sub);
+ return r;
+}
+
+
+/* get_read_timeout --- get timeout in milliseconds for reading */
+
+static long
+get_read_timeout(IOBUF *iop)
+{
+ long tmout = 0;
+
+ if (PROCINFO_node != NULL) {
+ const char *name = iop->public.name;
+ NODE *val = NULL;
+ static NODE *full_idx = NULL;
+ static const char *last_name = NULL;
+
+ /*
+ * Do not re-construct the full index when last redirection
+ * string is the same as the current; "efficiency_hack++".
+ */
+ if (full_idx == NULL || strcmp(name, last_name) != 0) {
+ val = in_PROCINFO(name, "READ_TIMEOUT", & full_idx);
+ if (last_name != NULL)
+ efree((void *) last_name);
+ last_name = estrdup(name, strlen(name));
+ } else /* use cached full index */
+ val = in_array(PROCINFO_node, full_idx);
+
+ if (val != NULL) {
+ (void) force_number(val);
+ tmout = get_number_si(val);
+ }
+ } else
+ tmout = read_default_timeout; /* initialized from env. variable in init_io() */
+
+ /* overwrite read routine only if an extension has not done so */
+ if ((iop->public.read_func == ( ssize_t(*)() ) read) && tmout > 0)
+ iop->public.read_func = read_with_timeout;
+
+ return tmout;
+}
+
+/*
+ * read_with_timeout --- read with a timeout, return failure
+ * if no data is available within the timeout period.
+ */
+
+static ssize_t
+read_with_timeout(int fd, char *buf, size_t size)
+{
+#if ! defined(VMS)
+ fd_set readfds;
+ struct timeval tv;
+#ifdef __MINGW32__
+ /*
+ * Only sockets can be read with a timeout. Also, the FD_*
+ * macros work on SOCKET type, not on int file descriptors.
+ */
+ SOCKET s = valid_socket(fd);
+
+ if (!s)
+ return read(fd, buf, size);
+#else
+ int s = fd;
+#endif
+
+ tv.tv_sec = read_timeout / 1000;
+ tv.tv_usec = 1000 * (read_timeout - 1000 * tv.tv_sec);
+
+ FD_ZERO(& readfds);
+ FD_SET(s, & readfds);
+
+ errno = 0;
+ /*
+ * Note: the 1st arg of 'select' is ignored on MS-Windows, so
+ * it's not a mistake to pass fd+1 there, although we use
+ * sockets, not file descriptors.
+ */
+ if (select(fd + 1, & readfds, NULL, NULL, & tv) < 0)
+ return -1;
+
+ if (FD_ISSET(s, & readfds))
+ return read(fd, buf, size);
+ /* else
+ timed out */
+
+ /* Set a meaningful errno */
+#ifdef ETIMEDOUT
+ errno = ETIMEDOUT;
+#else
+ errno = EAGAIN;
+#endif
+ return -1;
+#else /* VMS */
+ return read(fd, buf, size);
+#endif /* VMS */
+}
+
+/*
+ * Dummy pass through functions for default output.
+ */
+
+/* gawk_fwrite --- like fwrite */
+
+static size_t
+gawk_fwrite(const void *buf, size_t size, size_t count, FILE *fp, void *opaque)
+{
+ (void) opaque;
+
+ return fwrite(buf, size, count, fp);
+}
+
+static int
+gawk_fflush(FILE *fp, void *opaque)
+{
+ (void) opaque;
+
+ return fflush(fp);
+}
+
+static int
+gawk_ferror(FILE *fp, void *opaque)
+{
+ (void) opaque;
+
+ return ferror(fp);
+}
+
+static int
+gawk_fclose(FILE *fp, void *opaque)
+{
+ int result;
+#ifdef __MINGW32__
+ SOCKET s = valid_socket (fileno(fp));
+#endif
+ (void) opaque;
+
+ result = fclose(fp);
+#ifdef __MINGW32__
+ if (s && closesocket(s) == SOCKET_ERROR)
+ result = -1;
+#endif
+ return result;
+}
+
+
+/* init_output_wrapper --- initialize the output wrapper */
+
+static void
+init_output_wrapper(awk_output_buf_t *outbuf)
+{
+ outbuf->name = NULL;
+ outbuf->mode = NULL;
+ outbuf->fp = NULL;
+ outbuf->opaque = NULL;
+ outbuf->redirected = awk_false;
+ outbuf->gawk_fwrite = gawk_fwrite;
+ outbuf->gawk_fflush = gawk_fflush;
+ outbuf->gawk_ferror = gawk_ferror;
+ outbuf->gawk_fclose = gawk_fclose;
}
diff --git a/m4/ChangeLog b/m4/ChangeLog
index 8aaeb418..9ef76c4f 100644
--- a/m4/ChangeLog
+++ b/m4/ChangeLog
@@ -1,3 +1,94 @@
+2014-11-19 gettextize <bug-gnu-gettext@gnu.org>
+
+ * gettext.m4: Upgrade to gettext-0.19.3.
+ * iconv.m4: Upgrade to gettext-0.19.3.
+ * lib-ld.m4: Upgrade to gettext-0.19.3.
+ * lib-link.m4: Upgrade to gettext-0.19.3.
+ * lib-prefix.m4: Upgrade to gettext-0.19.3.
+ * nls.m4: Upgrade to gettext-0.19.3.
+ * po.m4: Upgrade to gettext-0.19.3.
+ * progtest.m4: Upgrade to gettext-0.19.3.
+
+2014-10-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * readline.m4: Enable cross compiling. Thanks to
+ Christer Solskogen <christer.solskogen@gmail.com> for
+ motivating and testing.
+
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.1: Release tar ball made.
+
+2014-03-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * readline.m4: Add manual check for *bsd* OS and add -ltermcap
+ if so. Hack, slash. Can you say "quick and dirty" boys and girls?
+ I knew you could.
+
+2013-10-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * readline.m4: Add check for NULL return from readline() in
+ call to printf() for results. Thanks to Dagobert Michelsen
+ <dam@opencsw.org> for the report.
+
+2013-08-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * readline.m4: Add additional code to check for history_list()
+ function. Patterned after checks in:
+ http://ftp.samba.org/pub/unpacked/samba_3_current/source4/lib/smbreadline/readline.m4
+ Thanks to Larry Baker (larry.baker@stanfordalumni.org) for the
+ pointer.
+
+2013-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.0: Release tar ball made.
+
+2013-01-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * readline.m4: Add cross-compiling action.
+
+2013-01-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * readline.m4 (GAWK_CHECK_READLINE): Renamed from GNUPG_CHECK_READLINE.
+ Test program changed and test changed to try to run the built program
+ since some systems don't notice a link dependency between libreadline
+ and other libs until runtime. Isn't that fun?
+
+2012-12-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.2: Release tar ball made.
+
+2012-10-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * po.m4, intl.m4: Fix droppings left over from a git merge.
+
+2012-05-21 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * libtool.m4, ltoptions.m4, ltsugar.m4, ltversion.m4, lt~obsolete.m4:
+ Remove files related to libtool support. Libtool usage has been
+ pushed down into the extension directory.
+
+2012-04-01 John Haque <j.eh@mchsi.com>
+
+ * mpfr.m4: New file.
+
+2012-04-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ Update to autoconf 2.69, automake 1.12.
+
+ * codeset.m4, glibc2.m4, glibc21.m4, intdiv0.m4, intl.m4, intldir.m4,
+ intlmacosx.m4, intmax.m4, inttypes-pri.m4, inttypes_h.m4, lcmessage.m4,
+ lock.m4, longlong.m4, printf-posix.m4, size_max.m4, stdint_h.m4,
+ uintmax_t.m4, visibility.m4, wchar_t.m4, wint_t.m4, xsize.m4: Updated.
+
+2012-03-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * noreturn.m4: New file.
+
+2012-03-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.1: Release tar ball made.
+
2011-06-23 Arnold D. Robbins <arnold@skeeve.com>
* ChangeLog.0: Rotated ChangeLog into this file.
diff --git a/m4/codeset.m4 b/m4/codeset.m4
index 223955b4..a53c0426 100644
--- a/m4/codeset.m4
+++ b/m4/codeset.m4
@@ -1,5 +1,5 @@
-# codeset.m4 serial 2 (gettext-0.16)
-dnl Copyright (C) 2000-2002, 2006 Free Software Foundation, Inc.
+# codeset.m4 serial 4 (gettext-0.18)
+dnl Copyright (C) 2000-2002, 2006, 2008-2010 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.
@@ -8,14 +8,14 @@ dnl From Bruno Haible.
AC_DEFUN([AM_LANGINFO_CODESET],
[
- AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_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); return !cs;],
- am_cv_langinfo_codeset=yes,
- am_cv_langinfo_codeset=no)
+ [am_cv_langinfo_codeset=yes],
+ [am_cv_langinfo_codeset=no])
])
if test $am_cv_langinfo_codeset = yes; then
- AC_DEFINE(HAVE_LANGINFO_CODESET, 1,
+ AC_DEFINE([HAVE_LANGINFO_CODESET], [1],
[Define if you have <langinfo.h> and nl_langinfo(CODESET).])
fi
])
diff --git a/m4/gettext.m4 b/m4/gettext.m4
index f84e6a5d..be247bf7 100644
--- a/m4/gettext.m4
+++ b/m4/gettext.m4
@@ -1,5 +1,5 @@
-# gettext.m4 serial 63 (gettext-0.18)
-dnl Copyright (C) 1995-2010 Free Software Foundation, Inc.
+# gettext.m4 serial 66 (gettext-0.18.2)
+dnl Copyright (C) 1995-2014 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.
@@ -35,7 +35,7 @@ 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 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
@@ -97,7 +97,7 @@ AC_DEFUN([AM_GNU_GETTEXT],
AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
])
- dnl Sometimes, on MacOS X, libintl requires linking with CoreFoundation.
+ dnl Sometimes, on Mac OS X, libintl requires linking with CoreFoundation.
gt_INTL_MACOSX
dnl Set USE_NLS.
@@ -157,12 +157,18 @@ changequote([,])dnl
fi
AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc],
- [AC_TRY_LINK([#include <libintl.h>
+ [AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#include <libintl.h>
$gt_revision_test_code
extern int _nl_msg_cat_cntr;
-extern int *_nl_domain_bindings;],
- [bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings],
+extern int *_nl_domain_bindings;
+ ]],
+ [[
+bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings
+ ]])],
[eval "$gt_func_gnugettext_libc=yes"],
[eval "$gt_func_gnugettext_libc=no"])])
@@ -183,35 +189,47 @@ return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_b
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>
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#include <libintl.h>
$gt_revision_test_code
extern int _nl_msg_cat_cntr;
extern
#ifdef __cplusplus
"C"
#endif
-const char *_nl_expand_alias (const char *);],
- [bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
+const char *_nl_expand_alias (const char *);
+ ]],
+ [[
+bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")
+ ]])],
[eval "$gt_func_gnugettext_libintl=yes"],
[eval "$gt_func_gnugettext_libintl=no"])
dnl Now see whether libintl exists and depends on libiconv.
if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then
LIBS="$LIBS $LIBICONV"
- AC_TRY_LINK([#include <libintl.h>
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#include <libintl.h>
$gt_revision_test_code
extern int _nl_msg_cat_cntr;
extern
#ifdef __cplusplus
"C"
#endif
-const char *_nl_expand_alias (const char *);],
- [bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
- [LIBINTL="$LIBINTL $LIBICONV"
- LTLIBINTL="$LTLIBINTL $LTLIBICONV"
- eval "$gt_func_gnugettext_libintl=yes"
- ])
+const char *_nl_expand_alias (const char *);
+ ]],
+ [[
+bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")
+ ]])],
+ [LIBINTL="$LIBINTL $LIBICONV"
+ LTLIBINTL="$LTLIBINTL $LTLIBICONV"
+ eval "$gt_func_gnugettext_libintl=yes"
+ ])
fi
CPPFLAGS="$gt_save_CPPFLAGS"
LIBS="$gt_save_LIBS"])
diff --git a/m4/glibc2.m4 b/m4/glibc2.m4
index e8f5bfe6..f148c12c 100644
--- a/m4/glibc2.m4
+++ b/m4/glibc2.m4
@@ -1,5 +1,5 @@
-# glibc2.m4 serial 1
-dnl Copyright (C) 2000-2002, 2004 Free Software Foundation, Inc.
+# glibc2.m4 serial 2
+dnl Copyright (C) 2000-2002, 2004, 2008-2010 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.
@@ -9,22 +9,22 @@ dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gt_GLIBC2],
[
- AC_CACHE_CHECK(whether we are using the GNU C Library 2 or newer,
- ac_cv_gnu_library_2,
+ 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_cv_gnu_library_2=yes],
+ [ac_cv_gnu_library_2=no])
]
)
- AC_SUBST(GLIBC2)
+ AC_SUBST([GLIBC2])
GLIBC2="$ac_cv_gnu_library_2"
]
)
diff --git a/m4/glibc21.m4 b/m4/glibc21.m4
index d95fd986..68ada9d4 100644
--- a/m4/glibc21.m4
+++ b/m4/glibc21.m4
@@ -1,5 +1,5 @@
-# glibc21.m4 serial 3
-dnl Copyright (C) 2000-2002, 2004 Free Software Foundation, Inc.
+# glibc21.m4 serial 4
+dnl Copyright (C) 2000-2002, 2004, 2008-2010 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.
@@ -9,22 +9,22 @@ dnl with or without modifications, as long as this notice is preserved.
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_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_cv_gnu_library_2_1=yes],
+ [ac_cv_gnu_library_2_1=no])
]
)
- AC_SUBST(GLIBC21)
+ AC_SUBST([GLIBC21])
GLIBC21="$ac_cv_gnu_library_2_1"
]
)
diff --git a/m4/iconv.m4 b/m4/iconv.m4
index e2041b9b..4b29c5f2 100644
--- a/m4/iconv.m4
+++ b/m4/iconv.m4
@@ -1,5 +1,5 @@
-# iconv.m4 serial 11 (gettext-0.18.1)
-dnl Copyright (C) 2000-2002, 2007-2010 Free Software Foundation, Inc.
+# iconv.m4 serial 18 (gettext-0.18.2)
+dnl Copyright (C) 2000-2002, 2007-2014 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.
@@ -30,27 +30,35 @@ AC_DEFUN([AM_ICONV_LINK],
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.
+ dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE 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);],
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#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);],
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#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"
@@ -58,16 +66,19 @@ AC_DEFUN([AM_ICONV_LINK],
])
if test "$am_cv_func_iconv" = yes; then
AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [
- dnl This tests against bugs in AIX 5.1, HP-UX 11.11, Solaris 10.
+ dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11,
+ dnl Solaris 10.
am_save_LIBS="$LIBS"
if test $am_cv_lib_iconv = yes; then
LIBS="$LIBS $LIBICONV"
fi
- AC_TRY_RUN([
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
#include <iconv.h>
#include <string.h>
int main ()
{
+ int result = 0;
/* Test against AIX 5.1 bug: Failures are not distinguishable from successful
returns. */
{
@@ -84,7 +95,8 @@ int main ()
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res == 0)
- return 1;
+ result |= 1;
+ iconv_close (cd_utf8_to_88591);
}
}
/* Test against Solaris 10 bug: Failures are not distinguishable from
@@ -103,7 +115,27 @@ int main ()
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res == 0)
- return 1;
+ result |= 2;
+ iconv_close (cd_ascii_to_88591);
+ }
+ }
+ /* Test against AIX 6.1..7.1 bug: Buffer overrun. */
+ {
+ iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
+ if (cd_88591_to_utf8 != (iconv_t)(-1))
+ {
+ static const char input[] = "\304";
+ static char buf[2] = { (char)0xDE, (char)0xAD };
+ const char *inptr = input;
+ size_t inbytesleft = 1;
+ char *outptr = buf;
+ size_t outbytesleft = 1;
+ size_t res = iconv (cd_88591_to_utf8,
+ (char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD)
+ result |= 4;
+ iconv_close (cd_88591_to_utf8);
}
}
#if 0 /* This bug could be worked around by the caller. */
@@ -122,7 +154,8 @@ int main ()
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
if ((int)res > 0)
- return 1;
+ result |= 8;
+ iconv_close (cd_88591_to_utf8);
}
}
#endif
@@ -136,13 +169,19 @@ int main ()
&& iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
/* Try HP-UX names. */
&& iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
- return 1;
- return 0;
-}], [am_cv_func_iconv_works=yes], [am_cv_func_iconv_works=no],
- [case "$host_os" in
+ result |= 16;
+ return result;
+}]])],
+ [am_cv_func_iconv_works=yes],
+ [am_cv_func_iconv_works=no],
+ [
+changequote(,)dnl
+ case "$host_os" in
aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
*) am_cv_func_iconv_works="guessing yes" ;;
- esac])
+ esac
+changequote([,])dnl
+ ])
LIBS="$am_save_LIBS"
])
case "$am_cv_func_iconv_works" in
@@ -183,32 +222,47 @@ m4_define([gl_iconv_AC_DEFUN],
m4_version_prereq([2.64],
[[AC_DEFUN_ONCE(
[$1], [$2])]],
- [[AC_DEFUN(
- [$1], [$2])]]))
+ [m4_ifdef([gl_00GNULIB],
+ [[AC_DEFUN_ONCE(
+ [$1], [$2])]],
+ [[AC_DEFUN(
+ [$1], [$2])]])]))
gl_iconv_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([
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
#include <stdlib.h>
#include <iconv.h>
extern
#ifdef __cplusplus
"C"
#endif
-#if defined(__STDC__) || defined(__cplusplus)
+#if defined(__STDC__) || defined(_MSC_VER) || 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_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([
$am_cv_proto_iconv])
AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
[Define as const if the declaration of iconv() needs const.])
+ dnl Also substitute ICONV_CONST in the gnulib generated <iconv.h>.
+ m4_ifdef([gl_ICONV_H_DEFAULTS],
+ [AC_REQUIRE([gl_ICONV_H_DEFAULTS])
+ if test -n "$am_cv_proto_iconv_arg1"; then
+ ICONV_CONST="const"
+ fi
+ ])
fi
])
diff --git a/m4/intdiv0.m4 b/m4/intdiv0.m4
index b8d78176..289c4df5 100644
--- a/m4/intdiv0.m4
+++ b/m4/intdiv0.m4
@@ -1,5 +1,5 @@
-# intdiv0.m4 serial 1 (gettext-0.11.3)
-dnl Copyright (C) 2002 Free Software Foundation, Inc.
+# intdiv0.m4 serial 3 (gettext-0.18)
+dnl Copyright (C) 2002, 2007-2010 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.
@@ -14,16 +14,27 @@ AC_DEFUN([gt_INTDIV0],
AC_CACHE_CHECK([whether integer division by zero raises SIGFPE],
gt_cv_int_divbyzero_sigfpe,
[
- AC_TRY_RUN([
+ gt_cv_int_divbyzero_sigfpe=
+changequote(,)dnl
+ case "$host_os" in
+ macos* | darwin[6-9]* | darwin[1-9][0-9]*)
+ # On MacOS X 10.2 or newer, just assume the same as when cross-
+ # compiling. If we were to perform the real test, 1 Crash Report
+ # dialog window would pop up.
+ case "$host_cpu" in
+ i[34567]86 | x86_64)
+ gt_cv_int_divbyzero_sigfpe="guessing yes" ;;
+ esac
+ ;;
+ esac
+changequote([,])dnl
+ if test -z "$gt_cv_int_divbyzero_sigfpe"; then
+ 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);
@@ -50,21 +61,24 @@ int main ()
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
- ])
+], [gt_cv_int_divbyzero_sigfpe=yes], [gt_cv_int_divbyzero_sigfpe=no],
+ [
+ # Guess based on the CPU.
+changequote(,)dnl
+ case "$host_cpu" in
+ alpha* | i[34567]86 | x86_64 | m68k | s390*)
+ gt_cv_int_divbyzero_sigfpe="guessing yes";;
+ *)
+ gt_cv_int_divbyzero_sigfpe="guessing no";;
+ esac
+changequote([,])dnl
+ ])
+ fi
])
case "$gt_cv_int_divbyzero_sigfpe" in
*yes) value=1;;
*) value=0;;
esac
- AC_DEFINE_UNQUOTED(INTDIV0_RAISES_SIGFPE, $value,
+ AC_DEFINE_UNQUOTED([INTDIV0_RAISES_SIGFPE], [$value],
[Define if integer division by zero raises signal SIGFPE.])
])
diff --git a/m4/intl.m4 b/m4/intl.m4
index dcefb118..d18cc01f 100644
--- a/m4/intl.m4
+++ b/m4/intl.m4
@@ -1,5 +1,5 @@
-# intl.m4 serial 3 (gettext-0.16)
-dnl Copyright (C) 1995-2006 Free Software Foundation, Inc.
+# intl.m4 serial 17 (gettext-0.18)
+dnl Copyright (C) 1995-2009 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.
@@ -15,9 +15,9 @@ 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-2006.
+dnl Bruno Haible <haible@clisp.cons.org>, 2000-2009.
-AC_PREREQ(2.52)
+AC_PREREQ([2.52])
dnl Checks for all prerequisites of the intl subdirectory,
dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS,
@@ -25,7 +25,7 @@ dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL.
AC_DEFUN([AM_INTL_SUBDIR],
[
AC_REQUIRE([AC_PROG_INSTALL])dnl
- AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake
+ AC_REQUIRE([AC_PROG_MKDIR_P])dnl
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_REQUIRE([gt_GLIBC2])dnl
@@ -33,7 +33,6 @@ AC_DEFUN([AM_INTL_SUBDIR],
AC_REQUIRE([gl_VISIBILITY])dnl
AC_REQUIRE([gt_INTL_SUBDIR_CORE])dnl
AC_REQUIRE([AC_TYPE_LONG_LONG_INT])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])
@@ -41,14 +40,24 @@ AC_DEFUN([AM_INTL_SUBDIR],
AC_REQUIRE([gt_PRINTF_POSIX])
AC_REQUIRE([gl_GLIBC21])dnl
AC_REQUIRE([gl_XSIZE])dnl
+ AC_REQUIRE([gl_FCNTL_O_FLAGS])dnl
AC_REQUIRE([gt_INTL_MACOSX])dnl
+ dnl Support for automake's --enable-silent-rules.
+ case "$enable_silent_rules" in
+ yes) INTL_DEFAULT_VERBOSITY=0;;
+ no) INTL_DEFAULT_VERBOSITY=1;;
+ *) INTL_DEFAULT_VERBOSITY=1;;
+ esac
+ AC_SUBST([INTL_DEFAULT_VERBOSITY])
+
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([stddef.h stdlib.h string.h])
- AC_CHECK_FUNCS([asprintf fwprintf putenv setenv setlocale snprintf wcslen])
+ AC_CHECK_FUNCS([asprintf fwprintf newlocale putenv setenv setlocale \
+ snprintf strnlen wcslen wcsnlen mbrtowc wcrtomb])
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).
@@ -79,6 +88,12 @@ AC_DEFUN([AM_INTL_SUBDIR],
HAVE_SNPRINTF=0
fi
AC_SUBST([HAVE_SNPRINTF])
+ if test "$ac_cv_func_newlocale" = yes; then
+ HAVE_NEWLOCALE=1
+ else
+ HAVE_NEWLOCALE=0
+ fi
+ AC_SUBST([HAVE_NEWLOCALE])
if test "$ac_cv_func_wprintf" = yes; then
HAVE_WPRINTF=1
else
@@ -98,7 +113,7 @@ AC_DEFUN([AM_INTL_SUBDIR],
dnl exported variables _also_ in the static library.
if test "$enable_shared" = yes; then
case "$host_os" in
- cygwin*) is_woe32dll=yes ;;
+ mingw* | cygwin*) is_woe32dll=yes ;;
*) is_woe32dll=no ;;
esac
else
@@ -107,6 +122,31 @@ AC_DEFUN([AM_INTL_SUBDIR],
WOE32DLL=$is_woe32dll
AC_SUBST([WOE32DLL])
+ dnl On mingw and Cygwin, we can activate special Makefile rules which add
+ dnl version information to the shared libraries and executables.
+ case "$host_os" in
+ mingw* | cygwin*) is_woe32=yes ;;
+ *) is_woe32=no ;;
+ esac
+ WOE32=$is_woe32
+ AC_SUBST([WOE32])
+ if test $WOE32 = yes; then
+ dnl Check for a program that compiles Windows resource files.
+ AC_CHECK_TOOL([WINDRES], [windres])
+ fi
+
+ dnl Determine whether when creating a library, "-lc" should be passed to
+ dnl libtool or not. On many platforms, it is required for the libtool option
+ dnl -no-undefined to work. On HP-UX, however, the -lc - stored by libtool
+ dnl in the *.la files - makes it impossible to create multithreaded programs,
+ dnl because libtool also reorders the -lc to come before the -pthread, and
+ dnl this disables pthread_create() <http://docs.hp.com/en/1896/pthreads.html>.
+ case "$host_os" in
+ hpux*) LTLIBC="" ;;
+ *) LTLIBC="-lc" ;;
+ esac
+ AC_SUBST([LTLIBC])
+
dnl Rename some macros and functions used for locking.
AH_BOTTOM([
#define __libc_lock_t gl_lock_t
@@ -122,22 +162,31 @@ AC_DEFUN([AM_INTL_SUBDIR],
#define __libc_lock_lock_recursive gl_recursive_lock_lock
#define __libc_lock_unlock_recursive gl_recursive_lock_unlock
#define glthread_in_use libintl_thread_in_use
-#define glthread_lock_init libintl_lock_init
-#define glthread_lock_lock libintl_lock_lock
-#define glthread_lock_unlock libintl_lock_unlock
-#define glthread_lock_destroy libintl_lock_destroy
-#define glthread_rwlock_init libintl_rwlock_init
-#define glthread_rwlock_rdlock libintl_rwlock_rdlock
-#define glthread_rwlock_wrlock libintl_rwlock_wrlock
-#define glthread_rwlock_unlock libintl_rwlock_unlock
-#define glthread_rwlock_destroy libintl_rwlock_destroy
-#define glthread_recursive_lock_init libintl_recursive_lock_init
-#define glthread_recursive_lock_lock libintl_recursive_lock_lock
-#define glthread_recursive_lock_unlock libintl_recursive_lock_unlock
-#define glthread_recursive_lock_destroy libintl_recursive_lock_destroy
-#define glthread_once libintl_once
-#define glthread_once_call libintl_once_call
+#define glthread_lock_init_func libintl_lock_init_func
+#define glthread_lock_lock_func libintl_lock_lock_func
+#define glthread_lock_unlock_func libintl_lock_unlock_func
+#define glthread_lock_destroy_func libintl_lock_destroy_func
+#define glthread_rwlock_init_multithreaded libintl_rwlock_init_multithreaded
+#define glthread_rwlock_init_func libintl_rwlock_init_func
+#define glthread_rwlock_rdlock_multithreaded libintl_rwlock_rdlock_multithreaded
+#define glthread_rwlock_rdlock_func libintl_rwlock_rdlock_func
+#define glthread_rwlock_wrlock_multithreaded libintl_rwlock_wrlock_multithreaded
+#define glthread_rwlock_wrlock_func libintl_rwlock_wrlock_func
+#define glthread_rwlock_unlock_multithreaded libintl_rwlock_unlock_multithreaded
+#define glthread_rwlock_unlock_func libintl_rwlock_unlock_func
+#define glthread_rwlock_destroy_multithreaded libintl_rwlock_destroy_multithreaded
+#define glthread_rwlock_destroy_func libintl_rwlock_destroy_func
+#define glthread_recursive_lock_init_multithreaded libintl_recursive_lock_init_multithreaded
+#define glthread_recursive_lock_init_func libintl_recursive_lock_init_func
+#define glthread_recursive_lock_lock_multithreaded libintl_recursive_lock_lock_multithreaded
+#define glthread_recursive_lock_lock_func libintl_recursive_lock_lock_func
+#define glthread_recursive_lock_unlock_multithreaded libintl_recursive_lock_unlock_multithreaded
+#define glthread_recursive_lock_unlock_func libintl_recursive_lock_unlock_func
+#define glthread_recursive_lock_destroy_multithreaded libintl_recursive_lock_destroy_multithreaded
+#define glthread_recursive_lock_destroy_func libintl_recursive_lock_destroy_func
+#define glthread_once_func libintl_once_func
#define glthread_once_singlethreaded libintl_once_singlethreaded
+#define glthread_once_multithreaded libintl_once_multithreaded
])
])
@@ -174,38 +223,24 @@ AC_DEFUN([gt_INTL_SUBDIR_CORE],
AC_TRY_LINK(
[int foo (int a) { a = __builtin_expect (a, 10); return a == 10 ? 0 : 1; }],
[],
- [AC_DEFINE([HAVE_BUILTIN_EXPECT], 1,
+ [AC_DEFINE([HAVE_BUILTIN_EXPECT], [1],
[Define to 1 if the compiler understands __builtin_expect.])])
AC_CHECK_HEADERS([argz.h inttypes.h limits.h unistd.h sys/param.h])
AC_CHECK_FUNCS([getcwd getegid geteuid getgid getuid mempcpy munmap \
- stpcpy strcasecmp strdup strtoul tsearch argz_count argz_stringify \
- argz_next __fsetlocking])
+ stpcpy strcasecmp strdup strtoul tsearch uselocale argz_count \
+ argz_stringify argz_next __fsetlocking])
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([feof_unlocked], [#include <stdio.h>])
+ gt_CHECK_DECL([fgets_unlocked], [#include <stdio.h>])
AM_ICONV
- dnl glibc >= 2.4 has a NL_LOCALE_NAME macro when _GNU_SOURCE is defined,
- dnl and a _NL_LOCALE_NAME macro always.
- AC_CACHE_CHECK([for NL_LOCALE_NAME macro], gt_cv_nl_locale_name,
- [AC_TRY_LINK([#include <langinfo.h>
-#include <locale.h>],
- [char* cs = nl_langinfo(_NL_LOCALE_NAME(LC_MESSAGES));],
- gt_cv_nl_locale_name=yes,
- gt_cv_nl_locale_name=no)
- ])
- if test $gt_cv_nl_locale_name = yes; then
- AC_DEFINE(HAVE_NL_LOCALE_NAME, 1,
- [Define if you have <langinfo.h> and it defines the NL_LOCALE_NAME macro if _GNU_SOURCE is defined.])
- 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
@@ -243,7 +278,7 @@ 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_CACHE_CHECK([whether $1 is declared], [ac_cv_have_decl_$1],
[AC_TRY_COMPILE([$2], [
#ifndef $1
char *p = (char *) $1;
diff --git a/m4/intldir.m4 b/m4/intldir.m4
index 7a28843f..ebae76d3 100644
--- a/m4/intldir.m4
+++ b/m4/intldir.m4
@@ -1,5 +1,5 @@
-# intldir.m4 serial 1 (gettext-0.16)
-dnl Copyright (C) 2006 Free Software Foundation, Inc.
+# intldir.m4 serial 2 (gettext-0.18)
+dnl Copyright (C) 2006, 2009-2010 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.
@@ -13,7 +13,7 @@ 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.
-AC_PREREQ(2.52)
+AC_PREREQ([2.52])
dnl Tells the AM_GNU_GETTEXT macro to consider an intl/ directory.
AC_DEFUN([AM_GNU_GETTEXT_INTL_SUBDIR], [])
diff --git a/m4/intlmacosx.m4 b/m4/intlmacosx.m4
index d3f0d904..dd910259 100644
--- a/m4/intlmacosx.m4
+++ b/m4/intlmacosx.m4
@@ -1,5 +1,5 @@
-# intlmacosx.m4 serial 1 (gettext-0.17)
-dnl Copyright (C) 2004-2007 Free Software Foundation, Inc.
+# intlmacosx.m4 serial 3 (gettext-0.18)
+dnl Copyright (C) 2004-2010 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.
@@ -19,7 +19,7 @@ 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_cv_func_CFPreferencesCopyAppValue],
[gt_save_LIBS="$LIBS"
LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
AC_TRY_LINK([#include <CoreFoundation/CFPreferences.h>],
@@ -28,11 +28,11 @@ AC_DEFUN([gt_INTL_MACOSX],
[gt_cv_func_CFPreferencesCopyAppValue=no])
LIBS="$gt_save_LIBS"])
if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then
- AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], 1,
+ 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,
+ AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent],
[gt_save_LIBS="$LIBS"
LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
AC_TRY_LINK([#include <CoreFoundation/CFLocale.h>], [CFLocaleCopyCurrent();],
@@ -40,7 +40,7 @@ AC_DEFUN([gt_INTL_MACOSX],
[gt_cv_func_CFLocaleCopyCurrent=no])
LIBS="$gt_save_LIBS"])
if test $gt_cv_func_CFLocaleCopyCurrent = yes; then
- AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], 1,
+ AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1],
[Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the CoreFoundation framework.])
fi
INTL_MACOSX_LIBS=
diff --git a/m4/intmax.m4 b/m4/intmax.m4
index ce7a8a49..74aaaf5e 100644
--- a/m4/intmax.m4
+++ b/m4/intmax.m4
@@ -1,5 +1,5 @@
-# intmax.m4 serial 3 (gettext-0.16)
-dnl Copyright (C) 2002-2005 Free Software Foundation, Inc.
+# intmax.m4 serial 5 (gettext-0.18)
+dnl Copyright (C) 2002-2005, 2008-2010 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.
@@ -12,7 +12,7 @@ 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_CACHE_CHECK([for intmax_t], [gt_cv_c_intmax_t],
[AC_TRY_COMPILE([
#include <stddef.h>
#include <stdlib.h>
@@ -24,10 +24,10 @@ AC_DEFUN([gt_TYPE_INTMAX_T],
#endif
], [intmax_t x = -1;
return !x;],
- gt_cv_c_intmax_t=yes,
- gt_cv_c_intmax_t=no)])
+ [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,
+ AC_DEFINE([HAVE_INTMAX_T], [1],
[Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>.])
fi
])
diff --git a/m4/inttypes-pri.m4 b/m4/inttypes-pri.m4
index 7c7f8940..718a4f4e 100644
--- a/m4/inttypes-pri.m4
+++ b/m4/inttypes-pri.m4
@@ -1,12 +1,12 @@
-# inttypes-pri.m4 serial 4 (gettext-0.16)
-dnl Copyright (C) 1997-2002, 2006 Free Software Foundation, Inc.
+# inttypes-pri.m4 serial 6 (gettext-0.18)
+dnl Copyright (C) 1997-2002, 2006, 2008-2010 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.52)
+AC_PREREQ([2.52])
# 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.
@@ -16,17 +16,17 @@ AC_DEFUN([gt_INTTYPES_PRI],
AC_CHECK_HEADERS([inttypes.h])
if test $ac_cv_header_inttypes_h = yes; then
AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken],
- gt_cv_inttypes_pri_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)
+], [], [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,
+ AC_DEFINE_UNQUOTED([PRI_MACROS_BROKEN], [1],
[Define if <inttypes.h> exists and defines unusable PRI* macros.])
PRI_MACROS_BROKEN=1
else
diff --git a/m4/inttypes_h.m4 b/m4/inttypes_h.m4
index 76171888..782d77ed 100644
--- a/m4/inttypes_h.m4
+++ b/m4/inttypes_h.m4
@@ -1,5 +1,5 @@
-# inttypes_h.m4 serial 7
-dnl Copyright (C) 1997-2004, 2006 Free Software Foundation, Inc.
+# inttypes_h.m4 serial 9
+dnl Copyright (C) 1997-2004, 2006, 2008-2010 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.
@@ -11,21 +11,16 @@ dnl From Paul Eggert.
AC_DEFUN([gl_AC_HEADER_INTTYPES_H],
[
- if test "OS/390" = "`uname`"
- then
- gl_cv_header_inttypes_h=no
- else
- AC_CACHE_CHECK([for inttypes.h], gl_cv_header_inttypes_h,
- [AC_TRY_COMPILE(
- [#include <sys/types.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; return !i;],
- 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
+ [uintmax_t i = (uintmax_t) -1; return !i;],
+ [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
])
diff --git a/m4/lcmessage.m4 b/m4/lcmessage.m4
index 19aa77e4..1a705431 100644
--- a/m4/lcmessage.m4
+++ b/m4/lcmessage.m4
@@ -1,5 +1,6 @@
-# lcmessage.m4 serial 4 (gettext-0.14.2)
-dnl Copyright (C) 1995-2002, 2004-2005 Free Software Foundation, Inc.
+# lcmessage.m4 serial 6 (gettext-0.18)
+dnl Copyright (C) 1995-2002, 2004-2005, 2008-2010 Free Software Foundation,
+dnl 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.
@@ -20,11 +21,11 @@ dnl Ulrich Drepper <drepper@cygnus.com>, 1995.
AC_DEFUN([gt_LC_MESSAGES],
[
- AC_CACHE_CHECK([for LC_MESSAGES], gt_cv_val_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)])
+ [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,
+ AC_DEFINE([HAVE_LC_MESSAGES], [1],
[Define if your <locale.h> file defines LC_MESSAGES.])
fi
])
diff --git a/m4/lib-ld.m4 b/m4/lib-ld.m4
index ebb30528..ddc569f7 100644
--- a/m4/lib-ld.m4
+++ b/m4/lib-ld.m4
@@ -1,50 +1,56 @@
-# lib-ld.m4 serial 4 (gettext-0.18)
-dnl Copyright (C) 1996-2003, 2009-2010 Free Software Foundation, Inc.
+# lib-ld.m4 serial 6
+dnl Copyright (C) 1996-2003, 2009-2014 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 with replacements s/_*LT_PATH/AC_LIB_PROG/ and s/lt_/acl_/ to avoid
+dnl collision with libtool.m4.
-dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
+dnl From libtool-2.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.
+[# I'd rather use --version here, but apparently some GNU lds 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=yes
+ ;;
*)
- acl_cv_prog_gnu_ld=no ;;
+ acl_cv_prog_gnu_ld=no
+ ;;
esac])
with_gnu_ld=$acl_cv_prog_gnu_ld
])
-dnl From libtool-1.4. Sets the variable LD.
+dnl From libtool-2.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_PROG_CC])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl
+
+AC_ARG_WITH([gnu-ld],
+ [AS_HELP_STRING([--with-gnu-ld],
+ [assume the C compiler uses GNU ld [default=no]])],
+ [test "$withval" = no || with_gnu_ld=yes],
+ [with_gnu_ld=no])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
+ # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which
+ # contains only /bin. Note that ksh looks also at the FPATH variable,
+ # so we have to set that as well for the test.
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
+ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
+ || PATH_SEPARATOR=';'
+ }
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])
+ AC_MSG_CHECKING([for ld used by $CC])
case $host in
*-*-mingw*)
# gcc leaves a trailing carriage return which upsets mingw
@@ -54,11 +60,11 @@ if test "$GCC" = yes; then
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
+ [[\\/]]* | ?:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the pathname 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"
@@ -79,23 +85,26 @@ else
fi
AC_CACHE_VAL([acl_cv_path_LD],
[if test -z "$LD"; then
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
for ac_dir in $PATH; do
+ IFS="$acl_save_ifs"
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.
+ # but apparently some variants of GNU ld 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
+ case `"$acl_cv_path_LD" -v 2>&1 </dev/null` in
*GNU* | *'with BFD'*)
- test "$with_gnu_ld" != no && break ;;
+ test "$with_gnu_ld" != no && break
+ ;;
*)
- test "$with_gnu_ld" != yes && break ;;
+ test "$with_gnu_ld" != yes && break
+ ;;
esac
fi
done
- IFS="$ac_save_ifs"
+ IFS="$acl_save_ifs"
else
acl_cv_path_LD="$LD" # Let the user override the test with a path.
fi])
diff --git a/m4/lib-link.m4 b/m4/lib-link.m4
index c73bd8e3..3522d994 100644
--- a/m4/lib-link.m4
+++ b/m4/lib-link.m4
@@ -1,5 +1,5 @@
-# lib-link.m4 serial 21 (gettext-0.18)
-dnl Copyright (C) 2001-2010 Free Software Foundation, Inc.
+# lib-link.m4 serial 26 (gettext-0.18.2)
+dnl Copyright (C) 2001-2014 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.
@@ -18,9 +18,9 @@ AC_DEFUN([AC_LIB_LINKFLAGS],
[
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
AC_REQUIRE([AC_LIB_RPATH])
- pushdef([Name],[translit([$1],[./-], [___])])
- pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ pushdef([Name],[m4_translit([$1],[./+-], [____])])
+ pushdef([NAME],[m4_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"
@@ -58,9 +58,9 @@ AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
[
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
AC_REQUIRE([AC_LIB_RPATH])
- pushdef([Name],[translit([$1],[./-], [___])])
- pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ pushdef([Name],[m4_translit([$1],[./+-], [____])])
+ pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
dnl accordingly.
@@ -85,7 +85,8 @@ AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
*" -l"*) LIBS="$LIBS $LIB[]NAME" ;;
*) LIBS="$LIB[]NAME $LIBS" ;;
esac
- AC_TRY_LINK([$3], [$4],
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([[$3]], [[$4]])],
[ac_cv_lib[]Name=yes],
[ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])'])
LIBS="$ac_save_LIBS"
@@ -115,6 +116,8 @@ AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
dnl Determine the platform dependent parameters needed to use rpath:
dnl acl_libext,
dnl acl_shlibext,
+dnl acl_libname_spec,
+dnl acl_library_names_spec,
dnl acl_hardcode_libdir_flag_spec,
dnl acl_hardcode_libdir_separator,
dnl acl_hardcode_direct,
@@ -157,15 +160,15 @@ dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar
dnl macro call that searches for libname.
AC_DEFUN([AC_LIB_FROMPACKAGE],
[
- pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
define([acl_frompackage_]NAME, [$2])
popdef([NAME])
pushdef([PACK],[$2])
- pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
define([acl_libsinpackage_]PACKUP,
- m4_ifdef([acl_libsinpackage_]PACKUP, [acl_libsinpackage_]PACKUP[[, ]],)[lib$1])
+ m4_ifdef([acl_libsinpackage_]PACKUP, [m4_defn([acl_libsinpackage_]PACKUP)[, ]],)[lib$1])
popdef([PACKUP])
popdef([PACK])
])
@@ -178,14 +181,14 @@ dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
[
AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
- pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])])
- pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])])
dnl Autoconf >= 2.61 supports dots in --with options.
- pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit(PACK,[.],[_])],PACK)])
+ pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)])
dnl By default, look in $includedir and $libdir.
use_additional=yes
AC_LIB_WITH_FINAL_PREFIX([
@@ -242,7 +245,7 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
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___|'`
+ uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'`
eval value=\"\$HAVE_LIB$uppername\"
if test -n "$value"; then
if test "$value" = yes; then
diff --git a/m4/lib-prefix.m4 b/m4/lib-prefix.m4
index 1601ceae..31f49e40 100644
--- a/m4/lib-prefix.m4
+++ b/m4/lib-prefix.m4
@@ -1,5 +1,5 @@
# lib-prefix.m4 serial 7 (gettext-0.18)
-dnl Copyright (C) 2001-2005, 2008-2010 Free Software Foundation, Inc.
+dnl Copyright (C) 2001-2005, 2008-2014 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.
diff --git a/m4/lock.m4 b/m4/lock.m4
index 0224f2ff..9da8465e 100644
--- a/m4/lock.m4
+++ b/m4/lock.m4
@@ -1,254 +1,33 @@
-# lock.m4 serial 6 (gettext-0.16)
-dnl Copyright (C) 2005-2006 Free Software Foundation, Inc.
+# lock.m4 serial 10 (gettext-0.18)
+dnl Copyright (C) 2005-2010 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 Tests for a multithreading library to be used.
-dnl Defines at most one of the macros USE_POSIX_THREADS, USE_SOLARIS_THREADS,
-dnl USE_PTH_THREADS, USE_WIN32_THREADS
-dnl Sets the variables LIBTHREAD and LTLIBTHREAD to the linker options for use
-dnl in a Makefile (LIBTHREAD for use without libtool, LTLIBTHREAD for use with
-dnl libtool).
-dnl Sets the variables LIBMULTITHREAD and LTLIBMULTITHREAD similarly, for
-dnl programs that really need multithread functionality. The difference
-dnl between LIBTHREAD and LIBMULTITHREAD is that on platforms supporting weak
-dnl symbols, typically LIBTHREAD="" whereas LIBMULTITHREAD="-lpthread".
-dnl Adds to CPPFLAGS the flag -D_REENTRANT or -D_THREAD_SAFE if needed for
-dnl multithread-safe programs.
-
-AC_DEFUN([gl_LOCK_EARLY],
-[
- AC_REQUIRE([gl_LOCK_EARLY_BODY])
-])
-
-dnl The guts of gl_LOCK_EARLY. Needs to be expanded only once.
-
-AC_DEFUN([gl_LOCK_EARLY_BODY],
-[
- dnl Ordering constraints: This macro modifies CPPFLAGS in a way that
- dnl influences the result of the autoconf tests that test for *_unlocked
- dnl declarations, on AIX 5 at least. Therefore it must come early.
- AC_BEFORE([$0], [gl_FUNC_GLIBC_UNLOCKED_IO])dnl
- AC_BEFORE([$0], [gl_ARGP])dnl
-
- AC_REQUIRE([AC_CANONICAL_HOST])
- AC_REQUIRE([AC_GNU_SOURCE]) dnl needed for pthread_rwlock_t on glibc systems
- dnl Check for multithreading.
- AC_ARG_ENABLE(threads,
-AC_HELP_STRING([--enable-threads={posix|solaris|pth|win32}], [specify multithreading API])
-AC_HELP_STRING([--disable-threads], [build without multithread safety]),
- [gl_use_threads=$enableval],
- [case "$host_os" in
- dnl Disable multithreading by default on OSF/1, because it interferes
- dnl with fork()/exec(): When msgexec is linked with -lpthread, its child
- dnl process gets an endless segmentation fault inside execvp().
- osf*) gl_use_threads=no ;;
- *) gl_use_threads=yes ;;
- esac
- ])
- if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
- # For using <pthread.h>:
- case "$host_os" in
- osf*)
- # On OSF/1, the compiler needs the flag -D_REENTRANT so that it
- # groks <pthread.h>. cc also understands the flag -pthread, but
- # we don't use it because 1. gcc-2.95 doesn't understand -pthread,
- # 2. putting a flag into CPPFLAGS that has an effect on the linker
- # causes the AC_TRY_LINK test below to succeed unexpectedly,
- # leading to wrong values of LIBTHREAD and LTLIBTHREAD.
- CPPFLAGS="$CPPFLAGS -D_REENTRANT"
- ;;
- esac
- # Some systems optimize for single-threaded programs by default, and
- # need special flags to disable these optimizations. For example, the
- # definition of 'errno' in <errno.h>.
- case "$host_os" in
- aix* | freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;;
- solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;;
- esac
- fi
-])
-
-dnl The guts of gl_LOCK. Needs to be expanded only once.
-
-AC_DEFUN([gl_LOCK_BODY],
+AC_DEFUN([gl_LOCK],
[
- AC_REQUIRE([gl_LOCK_EARLY_BODY])
- gl_threads_api=none
- LIBTHREAD=
- LTLIBTHREAD=
- LIBMULTITHREAD=
- LTLIBMULTITHREAD=
- if test "$gl_use_threads" != no; then
- dnl Check whether the compiler and linker support weak declarations.
- AC_MSG_CHECKING([whether imported symbols can be declared weak])
- gl_have_weak=no
- AC_TRY_LINK([extern void xyzzy ();
-#pragma weak xyzzy], [xyzzy();], [gl_have_weak=yes])
- AC_MSG_RESULT([$gl_have_weak])
- if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
- # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that
- # it groks <pthread.h>. It's added above, in gl_LOCK_EARLY_BODY.
- AC_CHECK_HEADER(pthread.h, gl_have_pthread_h=yes, gl_have_pthread_h=no)
- if test "$gl_have_pthread_h" = yes; then
- # Other possible tests:
- # -lpthreads (FSU threads, PCthreads)
- # -lgthreads
- gl_have_pthread=
- # Test whether both pthread_mutex_lock and pthread_mutexattr_init exist
- # in libc. IRIX 6.5 has the first one in both libc and libpthread, but
- # the second one only in libpthread, and lock.c needs it.
- AC_TRY_LINK([#include <pthread.h>],
- [pthread_mutex_lock((pthread_mutex_t*)0);
- pthread_mutexattr_init((pthread_mutexattr_t*)0);],
- [gl_have_pthread=yes])
- # Test for libpthread by looking for pthread_kill. (Not pthread_self,
- # since it is defined as a macro on OSF/1.)
- if test -n "$gl_have_pthread"; then
- # The program links fine without libpthread. But it may actually
- # need to link with libpthread in order to create multiple threads.
- AC_CHECK_LIB(pthread, pthread_kill,
- [LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread
- # On Solaris and HP-UX, most pthread functions exist also in libc.
- # Therefore pthread_in_use() needs to actually try to create a
- # thread: pthread_create from libc will fail, whereas
- # pthread_create will actually create a thread.
- case "$host_os" in
- solaris* | hpux*)
- AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], 1,
- [Define if the pthread_in_use() detection is hard.])
- esac
- ])
- else
- # Some library is needed. Try libpthread and libc_r.
- AC_CHECK_LIB(pthread, pthread_kill,
- [gl_have_pthread=yes
- LIBTHREAD=-lpthread LTLIBTHREAD=-lpthread
- LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread])
- if test -z "$gl_have_pthread"; then
- # For FreeBSD 4.
- AC_CHECK_LIB(c_r, pthread_kill,
- [gl_have_pthread=yes
- LIBTHREAD=-lc_r LTLIBTHREAD=-lc_r
- LIBMULTITHREAD=-lc_r LTLIBMULTITHREAD=-lc_r])
- fi
- fi
- if test -n "$gl_have_pthread"; then
- gl_threads_api=posix
- AC_DEFINE([USE_POSIX_THREADS], 1,
- [Define if the POSIX multithreading library can be used.])
- if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then
- if test $gl_have_weak = yes; then
- AC_DEFINE([USE_POSIX_THREADS_WEAK], 1,
- [Define if references to the POSIX multithreading library should be made weak.])
- LIBTHREAD=
- LTLIBTHREAD=
- fi
- fi
- # OSF/1 4.0 and MacOS X 10.1 lack the pthread_rwlock_t type and the
- # pthread_rwlock_* functions.
- AC_CHECK_TYPE([pthread_rwlock_t],
- [AC_DEFINE([HAVE_PTHREAD_RWLOCK], 1,
- [Define if the POSIX multithreading library has read/write locks.])],
- [],
- [#include <pthread.h>])
- # glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro.
- AC_TRY_COMPILE([#include <pthread.h>],
- [#if __FreeBSD__ == 4
+ AC_REQUIRE([gl_THREADLIB])
+ if test "$gl_threads_api" = posix; then
+ # OSF/1 4.0 and MacOS X 10.1 lack the pthread_rwlock_t type and the
+ # pthread_rwlock_* functions.
+ AC_CHECK_TYPE([pthread_rwlock_t],
+ [AC_DEFINE([HAVE_PTHREAD_RWLOCK], [1],
+ [Define if the POSIX multithreading library has read/write locks.])],
+ [],
+ [#include <pthread.h>])
+ # glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro.
+ AC_TRY_COMPILE([#include <pthread.h>],
+ [#if __FreeBSD__ == 4
error "No, in FreeBSD 4.0 recursive mutexes actually don't work."
#else
int x = (int)PTHREAD_MUTEX_RECURSIVE;
return !x;
#endif],
- [AC_DEFINE([HAVE_PTHREAD_MUTEX_RECURSIVE], 1,
- [Define if the <pthread.h> defines PTHREAD_MUTEX_RECURSIVE.])])
- fi
- fi
- fi
- if test -z "$gl_have_pthread"; then
- if test "$gl_use_threads" = yes || test "$gl_use_threads" = solaris; then
- gl_have_solaristhread=
- gl_save_LIBS="$LIBS"
- LIBS="$LIBS -lthread"
- AC_TRY_LINK([#include <thread.h>
-#include <synch.h>],
- [thr_self();],
- [gl_have_solaristhread=yes])
- LIBS="$gl_save_LIBS"
- if test -n "$gl_have_solaristhread"; then
- gl_threads_api=solaris
- LIBTHREAD=-lthread
- LTLIBTHREAD=-lthread
- LIBMULTITHREAD="$LIBTHREAD"
- LTLIBMULTITHREAD="$LTLIBTHREAD"
- AC_DEFINE([USE_SOLARIS_THREADS], 1,
- [Define if the old Solaris multithreading library can be used.])
- if test $gl_have_weak = yes; then
- AC_DEFINE([USE_SOLARIS_THREADS_WEAK], 1,
- [Define if references to the old Solaris multithreading library should be made weak.])
- LIBTHREAD=
- LTLIBTHREAD=
- fi
- fi
- fi
- fi
- if test "$gl_use_threads" = pth; then
- gl_save_CPPFLAGS="$CPPFLAGS"
- AC_LIB_LINKFLAGS(pth)
- gl_have_pth=
- gl_save_LIBS="$LIBS"
- LIBS="$LIBS -lpth"
- AC_TRY_LINK([#include <pth.h>], [pth_self();], gl_have_pth=yes)
- LIBS="$gl_save_LIBS"
- if test -n "$gl_have_pth"; then
- gl_threads_api=pth
- LIBTHREAD="$LIBPTH"
- LTLIBTHREAD="$LTLIBPTH"
- LIBMULTITHREAD="$LIBTHREAD"
- LTLIBMULTITHREAD="$LTLIBTHREAD"
- AC_DEFINE([USE_PTH_THREADS], 1,
- [Define if the GNU Pth multithreading library can be used.])
- if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then
- if test $gl_have_weak = yes; then
- AC_DEFINE([USE_PTH_THREADS_WEAK], 1,
- [Define if references to the GNU Pth multithreading library should be made weak.])
- LIBTHREAD=
- LTLIBTHREAD=
- fi
- fi
- else
- CPPFLAGS="$gl_save_CPPFLAGS"
- fi
- fi
- if test -z "$gl_have_pthread"; then
- if test "$gl_use_threads" = yes || test "$gl_use_threads" = win32; then
- if { case "$host_os" in
- mingw*) true;;
- *) false;;
- esac
- }; then
- gl_threads_api=win32
- AC_DEFINE([USE_WIN32_THREADS], 1,
- [Define if the Win32 multithreading API can be used.])
- fi
- fi
- fi
+ [AC_DEFINE([HAVE_PTHREAD_MUTEX_RECURSIVE], [1],
+ [Define if the <pthread.h> defines PTHREAD_MUTEX_RECURSIVE.])])
fi
- AC_MSG_CHECKING([for multithread API to use])
- AC_MSG_RESULT([$gl_threads_api])
- AC_SUBST(LIBTHREAD)
- AC_SUBST(LTLIBTHREAD)
- AC_SUBST(LIBMULTITHREAD)
- AC_SUBST(LTLIBMULTITHREAD)
-])
-
-AC_DEFUN([gl_LOCK],
-[
- AC_REQUIRE([gl_LOCK_EARLY])
- AC_REQUIRE([gl_LOCK_BODY])
gl_PREREQ_LOCK
])
@@ -256,56 +35,3 @@ AC_DEFUN([gl_LOCK],
AC_DEFUN([gl_PREREQ_LOCK], [
AC_REQUIRE([AC_C_INLINE])
])
-
-dnl Survey of platforms:
-dnl
-dnl Platform Available Compiler Supports test-lock
-dnl flavours option weak result
-dnl --------------- --------- --------- -------- ---------
-dnl Linux 2.4/glibc posix -lpthread Y OK
-dnl
-dnl GNU Hurd/glibc posix
-dnl
-dnl FreeBSD 5.3 posix -lc_r Y
-dnl posix -lkse ? Y
-dnl posix -lpthread ? Y
-dnl posix -lthr Y
-dnl
-dnl FreeBSD 5.2 posix -lc_r Y
-dnl posix -lkse Y
-dnl posix -lthr Y
-dnl
-dnl FreeBSD 4.0,4.10 posix -lc_r Y OK
-dnl
-dnl NetBSD 1.6 --
-dnl
-dnl OpenBSD 3.4 posix -lpthread Y OK
-dnl
-dnl MacOS X 10.[123] posix -lpthread Y OK
-dnl
-dnl Solaris 7,8,9 posix -lpthread Y Sol 7,8: 0.0; Sol 9: OK
-dnl solaris -lthread Y Sol 7,8: 0.0; Sol 9: OK
-dnl
-dnl HP-UX 11 posix -lpthread N (cc) OK
-dnl Y (gcc)
-dnl
-dnl IRIX 6.5 posix -lpthread Y 0.5
-dnl
-dnl AIX 4.3,5.1 posix -lpthread N AIX 4: 0.5; AIX 5: OK
-dnl
-dnl OSF/1 4.0,5.1 posix -pthread (cc) N OK
-dnl -lpthread (gcc) Y
-dnl
-dnl Cygwin posix -lpthread Y OK
-dnl
-dnl Any of the above pth -lpth 0.0
-dnl
-dnl Mingw win32 N OK
-dnl
-dnl BeOS 5 --
-dnl
-dnl The test-lock result shows what happens if in test-lock.c EXPLICIT_YIELD is
-dnl turned off:
-dnl OK if all three tests terminate OK,
-dnl 0.5 if the first test terminates OK but the second one loops endlessly,
-dnl 0.0 if the first test already loops endlessly.
diff --git a/m4/longlong.m4 b/m4/longlong.m4
index 3716c09f..cca3c1a9 100644
--- a/m4/longlong.m4
+++ b/m4/longlong.m4
@@ -1,5 +1,5 @@
-# longlong.m4 serial 8
-dnl Copyright (C) 1999-2006 Free Software Foundation, Inc.
+# longlong.m4 serial 14
+dnl Copyright (C) 1999-2007, 2009-2010 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.
@@ -7,42 +7,100 @@ dnl with or without modifications, as long as this notice is preserved.
dnl From Paul Eggert.
# Define HAVE_LONG_LONG_INT if 'long long int' works.
-# This fixes a bug in Autoconf 2.60, but can be removed once we
-# assume 2.61 everywhere.
+# This fixes a bug in Autoconf 2.61, but can be removed once we
+# assume 2.62 everywhere.
# Note: If the type 'long long int' exists but is only 32 bits large
-# (as on some very old compilers), AC_TYPE_LONG_LONG_INT will not be
+# (as on some very old compilers), HAVE_LONG_LONG_INT will not be
# defined. In this case you can treat 'long long int' like 'long int'.
AC_DEFUN([AC_TYPE_LONG_LONG_INT],
[
AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int],
[AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
- [[long long int ll = 9223372036854775807ll;
- long long int nll = -9223372036854775807LL;
- typedef int a[((-9223372036854775807LL < 0
- && 0 < 9223372036854775807ll)
- ? 1 : -1)];
- int i = 63;]],
- [[long long int llmax = 9223372036854775807ll;
- return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
- | (llmax / ll) | (llmax % ll));]])],
- [ac_cv_type_long_long_int=yes],
+ [_AC_TYPE_LONG_LONG_SNIPPET],
+ [dnl This catches a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004.
+ dnl If cross compiling, assume the bug isn't important, since
+ dnl nobody cross compiles for this platform as far as we know.
+ AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[@%:@include <limits.h>
+ @%:@ifndef LLONG_MAX
+ @%:@ define HALF \
+ (1LL << (sizeof (long long int) * CHAR_BIT - 2))
+ @%:@ define LLONG_MAX (HALF - 1 + HALF)
+ @%:@endif]],
+ [[long long int n = 1;
+ int i;
+ for (i = 0; ; i++)
+ {
+ long long int m = n << i;
+ if (m >> i != n)
+ return 1;
+ if (LLONG_MAX / 2 < m)
+ break;
+ }
+ return 0;]])],
+ [ac_cv_type_long_long_int=yes],
+ [ac_cv_type_long_long_int=no],
+ [ac_cv_type_long_long_int=yes])],
[ac_cv_type_long_long_int=no])])
if test $ac_cv_type_long_long_int = yes; then
- AC_DEFINE([HAVE_LONG_LONG_INT], 1,
+ AC_DEFINE([HAVE_LONG_LONG_INT], [1],
[Define to 1 if the system has the type `long long int'.])
fi
])
-# This macro is obsolescent and should go away soon.
-AC_DEFUN([gl_AC_TYPE_LONG_LONG],
+# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works.
+# This fixes a bug in Autoconf 2.61, but can be removed once we
+# assume 2.62 everywhere.
+
+# Note: If the type 'unsigned long long int' exists but is only 32 bits
+# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT
+# will not be defined. In this case you can treat 'unsigned long long int'
+# like 'unsigned long int'.
+
+AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT],
[
- AC_REQUIRE([AC_TYPE_LONG_LONG_INT])
- ac_cv_type_long_long=$ac_cv_type_long_long_int
- if test $ac_cv_type_long_long = yes; then
- AC_DEFINE(HAVE_LONG_LONG, 1,
- [Define if you have the 'long long' type.])
+ AC_CACHE_CHECK([for unsigned long long int],
+ [ac_cv_type_unsigned_long_long_int],
+ [AC_LINK_IFELSE(
+ [_AC_TYPE_LONG_LONG_SNIPPET],
+ [ac_cv_type_unsigned_long_long_int=yes],
+ [ac_cv_type_unsigned_long_long_int=no])])
+ if test $ac_cv_type_unsigned_long_long_int = yes; then
+ AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], [1],
+ [Define to 1 if the system has the type `unsigned long long int'.])
fi
])
+
+# Expands to a C program that can be used to test for simultaneous support
+# of 'long long' and 'unsigned long long'. We don't want to say that
+# 'long long' is available if 'unsigned long long' is not, or vice versa,
+# because too many programs rely on the symmetry between signed and unsigned
+# integer types (excluding 'bool').
+AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET],
+[
+ AC_LANG_PROGRAM(
+ [[/* For now, do not test the preprocessor; as of 2007 there are too many
+ implementations with broken preprocessors. Perhaps this can
+ be revisited in 2012. In the meantime, code should not expect
+ #if to work with literals wider than 32 bits. */
+ /* Test literals. */
+ long long int ll = 9223372036854775807ll;
+ long long int nll = -9223372036854775807LL;
+ unsigned long long int ull = 18446744073709551615ULL;
+ /* Test constant expressions. */
+ typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
+ ? 1 : -1)];
+ typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
+ ? 1 : -1)];
+ int i = 63;]],
+ [[/* Test availability of runtime routines for shift and division. */
+ long long int llmax = 9223372036854775807ll;
+ unsigned long long int ullmax = 18446744073709551615ull;
+ return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
+ | (llmax / ll) | (llmax % ll)
+ | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
+ | (ullmax / ull) | (ullmax % ull));]])
+])
diff --git a/m4/mpfr.m4 b/m4/mpfr.m4
new file mode 100644
index 00000000..7d9e678b
--- /dev/null
+++ b/m4/mpfr.m4
@@ -0,0 +1,62 @@
+dnl Check for MPFR and dependencies
+dnl Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+dnl
+dnl This file is free software, distributed under the terms of the GNU
+dnl General Public License. As a special exception to the GNU General
+dnl Public License, this file may be distributed as part of a program
+dnl that contains a configuration script generated by Autoconf, under
+dnl the same distribution terms as the rest of that program.
+dnl
+dnl Defines HAVE_MPFR to 1 if a working MPFR/GMP setup is
+dnl found, and sets @LIBMPFR@ to the necessary libraries.
+
+AC_DEFUN([GNUPG_CHECK_MPFR],
+[
+ AC_ARG_WITH([mpfr],
+ AC_HELP_STRING([--with-mpfr=DIR],
+ [look for the mpfr and gmp libraries in DIR]),
+ [_do_mpfr=$withval],[_do_mpfr=yes])
+
+ if test "$_do_mpfr" != "no" ; then
+ if test -d "$withval" ; then
+ CPPFLAGS="${CPPFLAGS} -I$withval/include"
+ LDFLAGS="${LDFLAGS} -L$withval/lib"
+ fi
+
+ _mpfr_save_libs=$LIBS
+ _combo="-lmpfr -lgmp"
+ LIBS="$LIBS $_combo"
+
+ AC_MSG_CHECKING([whether mpfr via \"$_combo\" is present and usable])
+
+ AC_LINK_IFELSE([
+ AC_LANG_PROGRAM([
+#include <stdio.h>
+#include <mpfr.h>
+#include <gmp.h>
+],[
+mpfr_t p;
+mpz_t z;
+mpfr_init(p);
+mpz_init(z);
+mpfr_printf("%Rf%Zd", p, z);
+mpfr_clear(p);
+mpz_clear(z);
+])],_found_mpfr=yes,_found_mpfr=no)
+
+ AC_MSG_RESULT([$_found_mpfr])
+
+ LIBS=$_mpfr_save_libs
+
+ if test $_found_mpfr = yes ; then
+ AC_DEFINE(HAVE_MPFR,1,
+ [Define to 1 if you have fully functional mpfr and gmp libraries.])
+ AC_SUBST(LIBMPFR,$_combo)
+ break
+ fi
+
+ unset _mpfr_save_libs
+ unset _combo
+ unset _found_mpfr
+ fi
+])dnl
diff --git a/m4/nls.m4 b/m4/nls.m4
index 003704c4..53cdc8be 100644
--- a/m4/nls.m4
+++ b/m4/nls.m4
@@ -1,5 +1,5 @@
# nls.m4 serial 5 (gettext-0.18)
-dnl Copyright (C) 1995-2003, 2005-2006, 2008-2010 Free Software Foundation,
+dnl Copyright (C) 1995-2003, 2005-2006, 2008-2014 Free Software Foundation,
dnl Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
diff --git a/m4/noreturn.m4 b/m4/noreturn.m4
new file mode 100644
index 00000000..7fa7d377
--- /dev/null
+++ b/m4/noreturn.m4
@@ -0,0 +1,38 @@
+dnl Date: Sun, 26 Feb 2012 11:31:50 -0800
+dnl From: Paul Eggert <eggert@cs.ucla.edu>
+dnl To: arnold@skeeve.com
+dnl CC: bug-grep@gnu.org
+dnl Subject: Re: avoid gcc 4.6.2 'may be used before set' warnings in dfa.c
+dnl
+dnl On 02/26/2012 01:18 AM, arnold@skeeve.com wrote:
+dnl > It looks like I can just use the code as it is now in grep. I have asked
+dnl > for compile failures and haven't gotten any.
+dnl
+dnl Sure, but the gnulib support for this is better
+dnl than what's in the dfa code. It could be that
+dnl your correspondents aren't using the less-common hosts
+dnl or compiler warning options that gnulib is ported to.
+dnl
+dnl In the long run stdnoreturn.h or _Noreturn is the way to go,
+dnl since they're part of the C standard.
+dnl
+dnl If you'd rather not create a separate file, how about if
+dnl we change the dfa code to use _Noreturn instead of
+dnl <stdnoreturn.h> and noreturn, and you can put the
+dnl following into your configure.ac so that config.h
+dnl defines _Noreturn the same way gnulib does:
+
+AC_DEFUN([GAWK_AC_NORETURN],[
+AH_VERBATIM([_Noreturn],
+[/* The _Noreturn keyword of C11. */
+#ifndef _Noreturn
+# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \
+ || 0x5110 <= __SUNPRO_C)
+# define _Noreturn __attribute__ ((__noreturn__))
+# elif defined _MSC_VER && 1200 <= _MSC_VER
+# define _Noreturn __declspec (noreturn)
+# else
+# define _Noreturn
+# endif
+#endif
+])])
diff --git a/m4/po.m4 b/m4/po.m4
index 47f36a41..84659ea5 100644
--- a/m4/po.m4
+++ b/m4/po.m4
@@ -1,5 +1,5 @@
-# po.m4 serial 17 (gettext-0.18)
-dnl Copyright (C) 1995-2010 Free Software Foundation, Inc.
+# po.m4 serial 22 (gettext-0.19)
+dnl Copyright (C) 1995-2014 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.
@@ -17,19 +17,20 @@ dnl Authors:
dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003.
-AC_PREREQ([2.50])
+AC_PREREQ([2.60])
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_PROG_MKDIR_P])dnl defined by automake
+ AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+ AC_REQUIRE([AC_PROG_SED])dnl
AC_REQUIRE([AM_NLS])dnl
dnl Release version of the gettext macros. This is used to ensure that
dnl the gettext macros and po/Makefile.in.in are in sync.
- AC_SUBST([GETTEXT_MACRO_VERSION], [0.18])
+ AC_SUBST([GETTEXT_MACRO_VERSION], [0.19])
dnl Perform the following tests also if --disable-nls has been given,
dnl because they are needed for "make dist" to work.
@@ -102,7 +103,7 @@ changequote([,])dnl
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_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.
@@ -118,7 +119,8 @@ changequote([,])dnl
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"
+ gt_tab=`printf '\t'`
+ cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/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
@@ -129,12 +131,12 @@ changequote([,])dnl
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 < 1.5.
+ # Hide the ALL_LINGUAS assignment from automake < 1.5.
eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
else
# The set of available languages was given in configure.in.
- # Hide the ALL_LINGUAS assigment from automake < 1.5.
+ # Hide the ALL_LINGUAS assignment from automake < 1.5.
eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
fi
# Compute POFILES
@@ -226,7 +228,7 @@ AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE],
changequote(,)dnl
# Adjust a relative srcdir.
ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
- ac_dir_suffix="/`echo "$ac_dir"|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.
@@ -254,6 +256,7 @@ EOT
fi
# A sed script that extracts the value of VARIABLE from a Makefile.
+ tab=`printf '\t'`
sed_x_variable='
# Test if the hold space is empty.
x
@@ -261,9 +264,9 @@ s/P/P/
x
ta
# Yes it was empty. Look if we have the expected variable definition.
-/^[ ]*VARIABLE[ ]*=/{
+/^['"${tab}"' ]*VARIABLE['"${tab}"' ]*=/{
# Seen the first line of the variable definition.
- s/^[ ]*VARIABLE[ ]*=//
+ s/^['"${tab}"' ]*VARIABLE['"${tab}"' ]*=//
ba
}
bd
@@ -315,7 +318,7 @@ changequote([,])dnl
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 < 1.5.
+ # Hide the ALL_LINGUAS assignment from automake < 1.5.
eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
# Compute POFILES
# as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
@@ -405,14 +408,15 @@ changequote([,])dnl
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"
+ tab=`printf '\t'`
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; }
+${tab}@echo "\$(MSGFMT) -c --tcl -d \$(srcdir) -l $lang $srcdirpre$lang.po"; \
+${tab}\$(MSGFMT) -c --tcl -d "\$(srcdir)" -l $lang $srcdirpre$lang.po || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
EOF
done
fi
@@ -422,8 +426,8 @@ EOF
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; }
+${tab}@echo "\$(MSGFMT) -c --csharp -d \$(srcdir) -l $lang $srcdirpre$lang.po -r \$(DOMAIN)"; \
+${tab}\$(MSGFMT) -c --csharp -d "\$(srcdir)" -l $lang $srcdirpre$lang.po -r "\$(DOMAIN)" || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
EOF
done
fi
diff --git a/m4/printf-posix.m4 b/m4/printf-posix.m4
index af10170a..1eacf95a 100644
--- a/m4/printf-posix.m4
+++ b/m4/printf-posix.m4
@@ -1,5 +1,5 @@
-# printf-posix.m4 serial 2 (gettext-0.13.1)
-dnl Copyright (C) 2003 Free Software Foundation, Inc.
+# printf-posix.m4 serial 5 (gettext-0.18)
+dnl Copyright (C) 2003, 2007, 2009-2010 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.
@@ -27,17 +27,18 @@ int main ()
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__
+ AC_EGREP_CPP([notposix], [
+#if defined __NetBSD__ || defined __BEOS__ || defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__
notposix
#endif
- ], gt_cv_func_printf_posix="guessing no",
- gt_cv_func_printf_posix="guessing yes")
+ ],
+ [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,
+ AC_DEFINE([HAVE_POSIX_PRINTF], [1],
[Define if your printf() function supports format strings with positions.])
;;
esac
diff --git a/m4/progtest.m4 b/m4/progtest.m4
index 2d804ac9..b499f79c 100644
--- a/m4/progtest.m4
+++ b/m4/progtest.m4
@@ -1,5 +1,5 @@
-# progtest.m4 serial 6 (gettext-0.18)
-dnl Copyright (C) 1996-2003, 2005, 2008-2010 Free Software Foundation, Inc.
+# progtest.m4 serial 7 (gettext-0.18.2)
+dnl Copyright (C) 1996-2003, 2005, 2008-2014 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.
@@ -27,15 +27,14 @@ 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
+ # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which
+ # contains only /bin. Note that ksh looks also at the FPATH variable,
+ # so we have to set that as well for the test.
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
+ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
+ || PATH_SEPARATOR=';'
+ }
fi
# Find out how to test for executable files. Don't use a zero-byte file,
diff --git a/m4/readline.m4 b/m4/readline.m4
index 73bbf2a9..740b9c7b 100644
--- a/m4/readline.m4
+++ b/m4/readline.m4
@@ -1,5 +1,5 @@
dnl Check for readline and dependencies
-dnl Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+dnl Copyright (C) 2004, 2005, 2013, 2014 Free Software Foundation, Inc.
dnl
dnl This file is free software, distributed under the terms of the GNU
dnl General Public License. As a special exception to the GNU General
@@ -9,8 +9,14 @@ dnl the same distribution terms as the rest of that program.
dnl
dnl Defines HAVE_LIBREADLINE to 1 if a working readline setup is
dnl found, and sets @LIBREADLINE@ to the necessary libraries.
+dnl
+dnl Based upon GNUPG_CHECK_READLINE. Many more years into the
+dnl twenty-first century, it is not enough to link a test program
+dnl with the readline library. On several systems, if readline is
+dnl not linked with the curses / termcap / whatever libraries, the
+dnl problem is only discovered at run time. Isn't that special?
-AC_DEFUN([GNUPG_CHECK_READLINE],
+AC_DEFUN([GAWK_CHECK_READLINE],
[
AC_ARG_WITH([readline],
AC_HELP_STRING([--with-readline=DIR],
@@ -30,28 +36,74 @@ AC_DEFUN([GNUPG_CHECK_READLINE],
AC_MSG_CHECKING([whether readline via \"$_combo\" is present and sane])
- AC_LINK_IFELSE([
- AC_LANG_PROGRAM([
-#include <stdio.h>
+ AC_TRY_RUN(
+dnl source program:
+AC_LANG_SOURCE([[#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
-],[
-rl_completion_func_t *completer;
-add_history("foobar");
-rl_catch_signals=0;
-rl_inhibit_completion=0;
-rl_attempted_completion_function=NULL;
-rl_completion_matches(NULL,NULL);
-])],_found_readline=yes,_found_readline=no)
+
+int main(int argc, char **argv)
+{
+ int fd;
+ char *line;
+
+ close(0);
+ close(1);
+ fd = open("/dev/null", 2); /* should get fd 0 */
+ dup(fd);
+ line = readline("giveittome> ");
+
+ /* some printfs don't handle NULL for %s */
+ printf("got <%s>\n", line ? line : "(NULL)");
+ return 0;
+}]]),
+dnl action if true:
+ [_found_readline=yes],
+dnl action if false:
+ [_found_readline=no],
+dnl action if cross compiling:
+ AC_TRY_LINK([#include <stdio.h>
+#include <readline/readline.h>
+#include <readline/history.h>], dnl includes
+ dnl function body
+ [
+ int fd;
+ char *line;
+
+ close(0);
+ close(1);
+ fd = open("/dev/null", 2); /* should get fd 0 */
+ dup(fd);
+ line = readline("giveittome> ");
+
+ /* some printfs don't handle NULL for %s */
+ printf("got <%s>\n", line ? line : "(NULL)");
+],
+dnl action if found:
+ [_found_readline=yes],
+dnl action if not found:
+ [_found_readline=no]
+ )
+ )
AC_MSG_RESULT([$_found_readline])
LIBS=$_readline_save_libs
if test $_found_readline = yes ; then
+ case $host_os in
+ *bsd* ) _combo="$_combo -ltermcap"
+ ;;
+ esac
AC_DEFINE(HAVE_LIBREADLINE,1,
[Define to 1 if you have a fully functional readline library.])
AC_SUBST(LIBREADLINE,$_combo)
+
+ AC_CHECK_LIB(readline, history_list,
+ [AC_DEFINE(HAVE_HISTORY_LIST, 1, [Do we have history_list?])],
+ [],
+ [$_combo])
+
break
fi
done
diff --git a/m4/size_max.m4 b/m4/size_max.m4
index bfba811e..ce992db1 100644
--- a/m4/size_max.m4
+++ b/m4/size_max.m4
@@ -1,5 +1,5 @@
-# size_max.m4 serial 5
-dnl Copyright (C) 2003, 2005-2006 Free Software Foundation, Inc.
+# size_max.m4 serial 9
+dnl Copyright (C) 2003, 2005-2006, 2008-2010 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.
@@ -8,10 +8,9 @@ dnl From Bruno Haible.
AC_DEFUN([gl_SIZE_MAX],
[
- AC_CHECK_HEADERS(stdint.h)
+ AC_CHECK_HEADERS([stdint.h])
dnl First test whether the system already has SIZE_MAX.
- AC_MSG_CHECKING([for SIZE_MAX])
- AC_CACHE_VAL([gl_cv_size_max], [
+ AC_CACHE_CHECK([for SIZE_MAX], [gl_cv_size_max], [
gl_cv_size_max=
AC_EGREP_CPP([Found it], [
#include <limits.h>
@@ -21,16 +20,16 @@ AC_DEFUN([gl_SIZE_MAX],
#ifdef SIZE_MAX
Found it
#endif
-], gl_cv_size_max=yes)
+], [gl_cv_size_max=yes])
if test -z "$gl_cv_size_max"; then
dnl Define it ourselves. Here we assume that the type 'size_t' is not wider
dnl than the type 'unsigned long'. Try hard to find a definition that can
dnl be used in a preprocessor #if, i.e. doesn't contain a cast.
- _AC_COMPUTE_INT([sizeof (size_t) * CHAR_BIT - 1], size_t_bits_minus_1,
+ AC_COMPUTE_INT([size_t_bits_minus_1], [sizeof (size_t) * CHAR_BIT - 1],
[#include <stddef.h>
-#include <limits.h>], size_t_bits_minus_1=)
- _AC_COMPUTE_INT([sizeof (size_t) <= sizeof (unsigned int)], fits_in_uint,
- [#include <stddef.h>], fits_in_uint=)
+#include <limits.h>], [size_t_bits_minus_1=])
+ AC_COMPUTE_INT([fits_in_uint], [sizeof (size_t) <= sizeof (unsigned int)],
+ [#include <stddef.h>], [fits_in_uint=])
if test -n "$size_t_bits_minus_1" && test -n "$fits_in_uint"; then
if test $fits_in_uint = 1; then
dnl Even though SIZE_MAX fits in an unsigned int, it must be of type
@@ -38,7 +37,7 @@ Found it
AC_TRY_COMPILE([#include <stddef.h>
extern size_t foo;
extern unsigned long foo;
- ], [], fits_in_uint=0)
+ ], [], [fits_in_uint=0])
fi
dnl We cannot use 'expr' to simplify this expression, because 'expr'
dnl works only with 'long' integers in the host environment, while we
@@ -54,9 +53,23 @@ Found it
fi
fi
])
- AC_MSG_RESULT([$gl_cv_size_max])
if test "$gl_cv_size_max" != yes; then
AC_DEFINE_UNQUOTED([SIZE_MAX], [$gl_cv_size_max],
[Define as the maximum value of type 'size_t', if the system doesn't define it.])
fi
+ dnl Don't redefine SIZE_MAX in config.h if config.h is re-included after
+ dnl <stdint.h>. Remember that the #undef in AH_VERBATIM gets replaced with
+ dnl #define by AC_DEFINE_UNQUOTED.
+ AH_VERBATIM([SIZE_MAX],
+[/* Define as the maximum value of type 'size_t', if the system doesn't define
+ it. */
+#ifndef SIZE_MAX
+# undef SIZE_MAX
+#endif])
+])
+
+dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in.
+dnl Remove this when we can assume autoconf >= 2.61.
+m4_ifdef([AC_COMPUTE_INT], [], [
+ AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])])
])
diff --git a/m4/stdint_h.m4 b/m4/stdint_h.m4
index 86da6d78..b8e3c6cc 100644
--- a/m4/stdint_h.m4
+++ b/m4/stdint_h.m4
@@ -1,5 +1,5 @@
-# stdint_h.m4 serial 6
-dnl Copyright (C) 1997-2004, 2006 Free Software Foundation, Inc.
+# stdint_h.m4 serial 8
+dnl Copyright (C) 1997-2004, 2006, 2008-2010 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.
@@ -11,21 +11,16 @@ dnl From Paul Eggert.
AC_DEFUN([gl_AC_HEADER_STDINT_H],
[
- if test "OS/390" = "`uname`"
- then
- gl_cv_header_stdint_h=no
- else
- AC_CACHE_CHECK([for stdint.h], gl_cv_header_stdint_h,
- [AC_TRY_COMPILE(
- [#include <sys/types.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; return !i;],
- 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
+ [uintmax_t i = (uintmax_t) -1; return !i;],
+ [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
])
diff --git a/m4/uintmax_t.m4 b/m4/uintmax_t.m4
index bf83ed74..03b51bcf 100644
--- a/m4/uintmax_t.m4
+++ b/m4/uintmax_t.m4
@@ -1,12 +1,12 @@
-# uintmax_t.m4 serial 9
-dnl Copyright (C) 1997-2004 Free Software Foundation, Inc.
+# uintmax_t.m4 serial 12
+dnl Copyright (C) 1997-2004, 2007-2010 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)
+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>.
@@ -16,15 +16,15 @@ 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_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT])
+ test $ac_cv_type_unsigned_long_long_int = yes \
&& ac_type='unsigned long long' \
|| ac_type='unsigned long'
- AC_DEFINE_UNQUOTED(uintmax_t, $ac_type,
+ 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,
+ AC_DEFINE([HAVE_UINTMAX_T], [1],
[Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>.])
fi
])
diff --git a/m4/visibility.m4 b/m4/visibility.m4
index 2ff6330a..077c4765 100644
--- a/m4/visibility.m4
+++ b/m4/visibility.m4
@@ -1,5 +1,5 @@
-# visibility.m4 serial 1 (gettext-0.15)
-dnl Copyright (C) 2005 Free Software Foundation, Inc.
+# visibility.m4 serial 3 (gettext-0.18)
+dnl Copyright (C) 2005, 2008-2010 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.
@@ -26,18 +26,40 @@ AC_DEFUN([gl_VISIBILITY],
CFLAG_VISIBILITY=
HAVE_VISIBILITY=0
if test -n "$GCC"; then
+ dnl First, check whether -Werror can be added to the command line, or
+ dnl whether it leads to an error because of some other option that the
+ dnl user has put into $CC $CFLAGS $CPPFLAGS.
+ AC_MSG_CHECKING([whether the -Werror option is usable])
+ AC_CACHE_VAL([gl_cv_cc_vis_werror], [
+ gl_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Werror"
+ AC_TRY_COMPILE([], [],
+ [gl_cv_cc_vis_werror=yes],
+ [gl_cv_cc_vis_werror=no])
+ CFLAGS="$gl_save_CFLAGS"])
+ AC_MSG_RESULT([$gl_cv_cc_vis_werror])
+ dnl Now check whether visibility declarations are supported.
AC_MSG_CHECKING([for simple visibility declarations])
- AC_CACHE_VAL(gl_cv_cc_visibility, [
+ AC_CACHE_VAL([gl_cv_cc_visibility], [
gl_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -fvisibility=hidden"
+ dnl We use the option -Werror and a function dummyfunc, because on some
+ dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning
+ dnl "visibility attribute not supported in this configuration; ignored"
+ dnl at the first function definition in every compilation unit, and we
+ dnl don't want to use the option in this case.
+ if test $gl_cv_cc_vis_werror = yes; then
+ CFLAGS="$CFLAGS -Werror"
+ fi
AC_TRY_COMPILE(
[extern __attribute__((__visibility__("hidden"))) int hiddenvar;
extern __attribute__((__visibility__("default"))) int exportedvar;
extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void);
- extern __attribute__((__visibility__("default"))) int exportedfunc (void);],
+ extern __attribute__((__visibility__("default"))) int exportedfunc (void);
+ void dummyfunc (void) {}],
[],
- gl_cv_cc_visibility=yes,
- gl_cv_cc_visibility=no)
+ [gl_cv_cc_visibility=yes],
+ [gl_cv_cc_visibility=no])
CFLAGS="$gl_save_CFLAGS"])
AC_MSG_RESULT([$gl_cv_cc_visibility])
if test $gl_cv_cc_visibility = yes; then
diff --git a/m4/wchar_t.m4 b/m4/wchar_t.m4
index cde2129a..ed804e66 100644
--- a/m4/wchar_t.m4
+++ b/m4/wchar_t.m4
@@ -1,5 +1,5 @@
-# wchar_t.m4 serial 1 (gettext-0.12)
-dnl Copyright (C) 2002-2003 Free Software Foundation, Inc.
+# wchar_t.m4 serial 3 (gettext-0.18)
+dnl Copyright (C) 2002-2003, 2008-2010 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.
@@ -10,11 +10,11 @@ dnl Prerequisite: AC_PROG_CC
AC_DEFUN([gt_TYPE_WCHAR_T],
[
- AC_CACHE_CHECK([for wchar_t], gt_cv_c_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)])
+ [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.])
+ AC_DEFINE([HAVE_WCHAR_T], [1], [Define if you have the 'wchar_t' type.])
fi
])
diff --git a/m4/wint_t.m4 b/m4/wint_t.m4
index b8fff9c8..a6c7d15c 100644
--- a/m4/wint_t.m4
+++ b/m4/wint_t.m4
@@ -1,5 +1,5 @@
-# wint_t.m4 serial 1 (gettext-0.12)
-dnl Copyright (C) 2003 Free Software Foundation, Inc.
+# wint_t.m4 serial 4 (gettext-0.18)
+dnl Copyright (C) 2003, 2007-2010 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.
@@ -10,11 +10,19 @@ 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>
+ AC_CACHE_CHECK([for wint_t], [gt_cv_c_wint_t],
+ [AC_TRY_COMPILE([
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+ <wchar.h>.
+ BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be included
+ before <wchar.h>. */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
wint_t foo = (wchar_t)'\0';], ,
- gt_cv_c_wint_t=yes, gt_cv_c_wint_t=no)])
+ [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.])
+ AC_DEFINE([HAVE_WINT_T], [1], [Define if you have the 'wint_t' type.])
fi
])
diff --git a/m4/xsize.m4 b/m4/xsize.m4
index 85bb721e..b653693a 100644
--- a/m4/xsize.m4
+++ b/m4/xsize.m4
@@ -1,5 +1,5 @@
-# xsize.m4 serial 3
-dnl Copyright (C) 2003-2004 Free Software Foundation, Inc.
+# xsize.m4 serial 4
+dnl Copyright (C) 2003-2004, 2008-2010 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.
@@ -9,5 +9,5 @@ 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)
+ AC_CHECK_HEADERS([stdint.h])
])
diff --git a/main.c b/main.c
index 6b24a80b..f2bea917 100644
--- a/main.c
+++ b/main.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-2011 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-2014 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -24,7 +24,7 @@
*/
/* FIX THIS BEFORE EVERY RELEASE: */
-#define UPDATE_YEAR 2011
+#define UPDATE_YEAR 2014
#include "awk.h"
#include "getopt.h"
@@ -33,8 +33,20 @@
#include <mcheck.h>
#endif
+#ifdef HAVE_LIBSIGSEGV
+#include <sigsegv.h>
+#else
+typedef void *stackoverflow_context_t;
+/* the argument to this macro is purposely not used */
+#define sigsegv_install_handler(catchsegv) signal(SIGSEGV, catchsig)
+/* define as 0 rather than empty so that (void) cast on it works */
+#define stackoverflow_install_handler(catchstackoverflow, extra_stack, STACK_SIZE) 0
+#endif
+
#define DEFAULT_PROFILE "awkprof.out" /* where to put profile */
#define DEFAULT_VARFILE "awkvars.out" /* where to put vars */
+#define DEFAULT_PREC 53
+#define DEFAULT_ROUNDMODE "N" /* round to nearest */
static const char *varfile = DEFAULT_VARFILE;
const char *command_file = NULL; /* debugger commands */
@@ -55,19 +67,20 @@ static void nostalgia(void) ATTRIBUTE_NORETURN;
static void version(void) ATTRIBUTE_NORETURN;
static void init_fds(void);
static void init_groupset(void);
-
static void save_argv(int, char **);
+extern int debug_prog(INSTRUCTION *pc); /* debug.c */
+extern int init_debug(); /* debug.c */
+
/* 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;
NODE *FNR_node, *FPAT_node, *FS_node, *IGNORECASE_node, *LINT_node;
NODE *NF_node, *NR_node, *OFMT_node, *OFS_node, *ORS_node, *PROCINFO_node;
NODE *RLENGTH_node, *RSTART_node, *RS_node, *RT_node, *SUBSEP_node;
+NODE *PREC_node, *ROUNDMODE_node;
NODE *TEXTDOMAIN_node;
-NODE *_r; /* used as temporary in stack macros */
-
long NF;
long NR;
long FNR;
@@ -81,7 +94,7 @@ char *TEXTDOMAIN;
/*
* 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
+ * set_CONVFMT -> fmt_index -> force_string: gets NULL CONVFMT
* Fun, fun, fun, fun.
*/
char *CONVFMT = "%.6g";
@@ -125,23 +138,27 @@ struct pre_assign {
static struct pre_assign *preassigns = NULL; /* requested via -v or -F */
static long numassigns = -1; /* how many of them */
-static int disallow_var_assigns = FALSE; /* true for --exec */
+static bool disallow_var_assigns = false; /* true for --exec */
static void add_preassign(enum assign_type type, char *val);
-int do_flags = FALSE;
-int do_optimize = TRUE; /* apply default optimizations */
-static int do_nostalgia = FALSE; /* provide a blast from the past */
-static int do_binary = FALSE; /* hands off my data! */
+static void parse_args(int argc, char **argv);
+static void set_locale_stuff(void);
+static bool stopped_early = false;
+
+int do_flags = false;
+bool do_optimize = false; /* apply default optimizations */
+static int do_nostalgia = false; /* provide a blast from the past */
+static int do_binary = false; /* hands off my data! */
+static int do_version = false; /* print version info */
+static const char *locale = ""; /* default value to setlocale */
-int use_lc_numeric = FALSE; /* obey locale for decimal point */
+int use_lc_numeric = false; /* obey locale for decimal point */
-#if MBS_SUPPORT
int gawk_mb_cur_max; /* MB_CUR_MAX value, see comment in main() */
-#endif
-FILE *output_fp; /* default output for debugger */
-int output_is_tty = FALSE; /* control flushing of output */
+FILE *output_fp; /* default gawk output, can be redirected in the debugger */
+bool output_is_tty = false; /* control flushing of output */
/* default format for strftime(), available via PROCINFO */
const char def_strftime_format[] = "%a %b %e %H:%M:%S %Z %Y";
@@ -153,60 +170,55 @@ GETGROUPS_T *groupset; /* current group set */
int ngroups; /* size of said set */
#endif
-void (*lintfunc)(const char *mesg, ...) = warning;
+void (*lintfunc)(const char *mesg, ...) = r_warning;
-/*
- * Note: reserve -D for future use, to merge dgawk into gawk.
- * Note: reserve -l for future use, for xgawk's -l option.
- */
+/* Sorted by long option name! */
static const struct option optab[] = {
- { "traditional", no_argument, NULL, 'c' },
- { "lint", optional_argument, NULL, 'L' },
+ { "assign", required_argument, NULL, 'v' },
+ { "bignum", no_argument, NULL, 'M' },
+ { "characters-as-bytes", no_argument, & do_binary, 'b' },
+ { "copyright", no_argument, NULL, 'C' },
+ { "debug", optional_argument, NULL, 'D' },
+ { "dump-variables", optional_argument, NULL, 'd' },
+ { "exec", required_argument, NULL, 'E' },
+ { "field-separator", required_argument, NULL, 'F' },
+ { "file", required_argument, NULL, 'f' },
+ { "gen-pot", no_argument, NULL, 'g' },
+ { "help", no_argument, NULL, 'h' },
+ { "include", required_argument, NULL, 'i' },
+ { "lint", optional_argument, NULL, 'L' },
{ "lint-old", no_argument, NULL, 't' },
+ { "load", required_argument, NULL, 'l' },
+#if defined(LOCALEDEBUG)
+ { "locale", required_argument, NULL, 'Z' },
+#endif
+ { "non-decimal-data", no_argument, NULL, 'n' },
+ { "nostalgia", no_argument, & do_nostalgia, 1 },
{ "optimize", no_argument, NULL, 'O' },
+#if defined(YYDEBUG) || defined(GAWKDEBUG)
+ { "parsedebug", no_argument, NULL, 'Y' },
+#endif
{ "posix", no_argument, NULL, 'P' },
- { "command", required_argument, NULL, 'R' },
- { "nostalgia", no_argument, & do_nostalgia, 1 },
- { "gen-pot", no_argument, NULL, 'g' },
- { "non-decimal-data", no_argument, NULL, 'n' },
- { "profile", optional_argument, NULL, 'p' },
- { "copyright", no_argument, NULL, 'C' },
- { "field-separator", required_argument, NULL, 'F' },
- { "file", required_argument, NULL, 'f' },
+ { "pretty-print", optional_argument, NULL, 'o' },
+ { "profile", optional_argument, NULL, 'p' },
{ "re-interval", no_argument, NULL, 'r' },
- { "source", required_argument, NULL, 'e' },
- { "dump-variables", optional_argument, NULL, 'd' },
- { "assign", required_argument, NULL, 'v' },
- { "version", no_argument, NULL, 'V' },
- { "help", no_argument, NULL, 'h' },
- { "exec", required_argument, NULL, 'E' },
- { "use-lc-numeric", no_argument, & use_lc_numeric, 1 },
- { "characters-as-bytes", no_argument, & do_binary, 'b' },
{ "sandbox", no_argument, NULL, 'S' },
-#if defined(YYDEBUG) || defined(GAWKDEBUG)
- { "parsedebug", no_argument, NULL, 'Y' },
-#endif
+ { "source", required_argument, NULL, 'e' },
+ { "traditional", no_argument, NULL, 'c' },
+ { "use-lc-numeric", no_argument, & use_lc_numeric, 1 },
+ { "version", no_argument, & do_version, 'V' },
{ NULL, 0, NULL, '\0' }
};
-
/* main --- process args, parse program, run it, clean up */
int
main(int argc, char **argv)
{
- /*
- * The + on the front tells GNU getopt not to rearrange argv.
- * Note: reserve -D for future use, to merge dgawk into gawk.
- * Note: reserve -l for future use, for xgawk's -l option.
- */
- const char *optlist = "+F:f:v:W;m:bcCd::e:E:gh:L:nNOp::PrR:StVY";
- int stopped_early = FALSE;
- int old_optind;
int i;
- int c;
- char *scan, *src;
char *extra_stack;
+ int have_srcfile = 0;
+ SRCFILE *s;
/* do these checks early */
if (getenv("TIDYMEM") != NULL)
@@ -219,49 +231,11 @@ main(int argc, char **argv)
#endif /* HAVE_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) && defined(HAVE_LOCALE_H)
- /*
- * 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.
- *
- * 10/2005 --- see below also; we now only use the locale's
- * decimal point if do_posix in effect.
- *
- * 9/2007:
- * This is a mess. We need to get the locale's numeric info for
- * the thousands separator for the %'d flag.
- */
- setlocale(LC_NUMERIC, "");
- init_locale(& loc);
- setlocale(LC_NUMERIC, "C");
-#endif
-#if defined(LC_TIME)
- setlocale(LC_TIME, "");
-#endif
-
-#if 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. */
+ myname = gawk_name(argv[0]);
+ os_arg_fixup(&argc, &argv); /* emulate redirection, expand wildcards */
- /* init the cache for checking bytes if they're characters */
- init_btowc_cache();
-#endif
+ if (argc < 2)
+ usage(EXIT_FAILURE, stderr);
(void) bindtextdomain(PACKAGE, LOCALEDIR);
(void) textdomain(PACKAGE);
@@ -270,6 +244,22 @@ main(int argc, char **argv)
#ifdef SIGBUS
(void) signal(SIGBUS, catchsig);
#endif
+#ifdef SIGPIPE
+ /*
+ * Ignore SIGPIPE so that writes to pipes that fail don't
+ * kill the process but instead return -1 and set errno.
+ * That lets us print a fatal message instead of dieing suddenly.
+ *
+ * Note that this requires ignoring EPIPE when writing and
+ * flushing stdout/stderr in other parts of the program. E.g.,
+ *
+ * gawk 'BEGIN { print "hi" }' | exit
+ *
+ * should not give us "broken pipe" messages --- mainly because
+ * it did not do so in the past and people would complain.
+ */
+ signal(SIGPIPE, SIG_IGN);
+#endif
(void) sigsegv_install_handler(catchsegv);
#define STACK_SIZE (16*1024)
@@ -277,11 +267,8 @@ main(int argc, char **argv)
(void) stackoverflow_install_handler(catchstackoverflow, extra_stack, STACK_SIZE);
#undef STACK_SIZE
- myname = gawk_name(argv[0]);
- os_arg_fixup(&argc, &argv); /* emulate redirection, expand wildcards */
-
- if (argc < 2)
- usage(EXIT_FAILURE, stderr);
+ /* initialize the null string */
+ Nnull_string = make_string("", 0);
/* Robustness: check that file descriptors 0, 1, 2 are open */
init_fds();
@@ -289,226 +276,27 @@ main(int argc, char **argv)
/* init array handling. */
array_init();
- /* we do error messages ourselves on invalid options */
- opterr = FALSE;
+ /* init the symbol tables */
+ init_symbol_table();
- /* copy argv before getopt gets to it; used to restart the debugger */
- save_argv(argc, argv);
+ output_fp = stdout;
/* initialize global (main) execution context */
push_context(new_context());
- /* 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':
- add_preassign(PRE_ASSIGN_FS, optarg);
- break;
-
- case 'E':
- disallow_var_assigns = TRUE;
- /* fall through */
- case 'f':
- /*
- * 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((unsigned char) *scan))
- scan++;
- src = (*scan == '\0' ? argv[optind++] : optarg);
- (void) add_srcfile((src && src[0] == '-' && src[1] == '\0') ?
- SRC_STDIN : SRC_FILE,
- src, srcfiles, NULL, NULL);
-
- break;
-
- case 'v':
- add_preassign(PRE_ASSIGN, optarg);
- break;
-
- case 'm':
- /*
- * BWK awk extension.
- * -mf nnn set # fields, gawk ignores
- * -mr nnn set record length, ditto
- *
- * As of at least 10/2007, BWK awk also ignores it.
- */
- if (do_lint)
- lintwarn(_("`-m[fr]' option irrelevant in gawk"));
- if (optarg[0] != 'r' && optarg[0] != 'f')
- warning(_("-m option usage: `-m[fr] nnn'"));
- break;
-
- case 'b':
- do_binary = TRUE;
- break;
-
- case 'c':
- do_flags |= DO_TRADITIONAL;
- break;
-
- case 'C':
- copyleft();
- break;
+ parse_args(argc, argv);
- case 'd':
- do_flags |= DO_DUMP_VARS;
- if (optarg != NULL && optarg[0] != '\0')
- varfile = optarg;
- break;
-
- case 'e':
- if (optarg[0] == '\0')
- warning(_("empty argument to `-e/--source' ignored"));
- else
- (void) add_srcfile(SRC_CMDLINE, optarg, srcfiles, NULL, NULL);
- break;
+ set_locale_stuff();
- case 'g':
- do_flags |= DO_INTL;
- break;
-
- case 'h':
- /* write usage to stdout, per GNU coding stds */
- usage(EXIT_SUCCESS, stdout);
- break;
-
- case 'L':
-#ifndef NO_LINT
- do_flags |= DO_LINT_ALL;
- if (optarg != NULL) {
- if (strcmp(optarg, "fatal") == 0)
- lintfunc = r_fatal;
- else if (strcmp(optarg, "invalid") == 0) {
- do_flags &= ~DO_LINT_ALL;
- do_flags |= DO_LINT_INVALID;
- }
- }
- break;
-
- case 't':
- do_flags |= DO_LINT_OLD;
- break;
-#else
- case 'L':
- case 't':
- break;
-#endif
-
- case 'n':
- do_flags |= DO_NON_DEC_DATA;
- break;
-
- case 'N':
- use_lc_numeric = TRUE;
- break;
-
- case 'O':
- do_optimize++;
- break;
-
- case 'p':
- do_flags |= DO_PROFILING;
- if (optarg != NULL)
- set_prof_file(optarg);
- else
- set_prof_file(DEFAULT_PROFILE);
- break;
-
- case 'P':
- do_flags |= DO_POSIX;
- break;
-
- case 'r':
- do_flags |= DO_INTERVALS;
- break;
-
- case 'S':
- do_flags |= DO_SANDBOX;
- break;
-
- case 'V':
- version();
- break;
-
- case 'W': /* gawk specific options - now in getopt_long */
- fprintf(stderr, _("%s: option `-W %s' unrecognized, ignored\n"),
- argv[0], optarg);
- 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 'Y':
- case 'R':
-#if defined(YYDEBUG) || defined(GAWKDEBUG)
- if (c == 'Y') {
- yydebug = 2;
- break;
- }
-#endif
- if (c == 'R' && which_gawk == exe_debugging) {
- if (optarg[0] != '\0')
- command_file = optarg;
- break;
- }
- /* if not debugging or dgawk, fall through */
+ /*
+ * 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;
- case '?':
- default:
- /*
- * 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 POSIX required message format */
- fprintf(stderr,
- _("%s: option requires an argument -- %c\n"),
- myname, optopt);
- usage(EXIT_FAILURE, stderr);
- }
- /* else
- let getopt print error message for us */
- break;
- }
- if (c == 'E') /* --exec ends option processing */
- break;
- }
-out:
+ /* init the cache for checking bytes if they're characters */
+ init_btowc_cache();
if (do_nostalgia)
nostalgia();
@@ -522,7 +310,7 @@ out:
}
if (do_posix) {
- use_lc_numeric = TRUE;
+ use_lc_numeric = true;
if (do_traditional) /* both on command line */
warning(_("`--posix' overrides `--traditional'"));
else
@@ -541,29 +329,38 @@ out:
if (do_lint && os_is_setuid())
warning(_("running %s setuid root may be a security problem"), myname);
-#if MBS_SUPPORT
if (do_binary) {
if (do_posix)
- warning(_("`--posix' overrides `--binary'"));
+ warning(_("`--posix' overrides `--characters-as-bytes'"));
else
gawk_mb_cur_max = 1; /* hands off my data! */
- }
+#if defined(LC_ALL)
+ setlocale(LC_ALL, "C");
#endif
+ }
- /*
- * Force profiling if this is pgawk.
- * Don't bother if the command line already set profiling up.
- */
- if (! do_profiling)
- init_profiling(& do_flags, DEFAULT_PROFILE);
+ if (do_debug) /* Need to register the debugger pre-exec hook before any other */
+ init_debug();
+
+#ifdef HAVE_MPFR
+ /* Set up MPFR defaults, and register pre-exec hook to process arithmetic opcodes */
+ if (do_mpfr)
+ init_mpfr(DEFAULT_PREC, DEFAULT_ROUNDMODE);
+#endif
/* load group set */
init_groupset();
- /* initialize the null string */
- Nnull_string = make_string("", 0);
- Nnull_string->numbr = 0.0;
- Nnull_string->flags = (MALLOC|STRCUR|STRING|NUMCUR|NUMBER);
+#ifdef HAVE_MPFR
+ if (do_mpfr) {
+ mpz_init(Nnull_string->mpg_i);
+ Nnull_string->flags = (MALLOC|STRCUR|STRING|MPZN|NUMCUR|NUMBER);
+ } else
+#endif
+ {
+ Nnull_string->numbr = 0.0;
+ Nnull_string->flags = (MALLOC|STRCUR|STRING|NUMCUR|NUMBER);
+ }
/*
* Tell the regex routines how they should work.
@@ -572,8 +369,6 @@ out:
*/
resetup();
- (void) grow_stack();
-
/* Set up the special variables */
init_vars();
@@ -583,7 +378,7 @@ out:
/* Now process the pre-assignments */
for (i = 0; i <= numassigns; i++) {
if (preassigns[i].type == PRE_ASSIGN)
- (void) arg_assign(preassigns[i].val, TRUE);
+ (void) arg_assign(preassigns[i].val, true);
else /* PRE_ASSIGN_FS */
cmdline_fs(preassigns[i].val);
efree(preassigns[i].val);
@@ -592,10 +387,10 @@ out:
if (preassigns != NULL)
efree(preassigns);
- if ((BINMODE & 1) != 0)
+ if ((BINMODE & BINMODE_INPUT) != 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 ((BINMODE & BINMODE_OUTPUT) != 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)
@@ -606,15 +401,34 @@ out:
setbuf(stdout, (char *) NULL); /* make debugging easier */
#endif
if (os_isatty(fileno(stdout)))
- output_is_tty = TRUE;
+ output_is_tty = true;
+
+ /* initialize API before loading extension libraries */
+ init_ext_api();
+
+ /* load extension libs */
+ for (s = srcfiles->next; s != srcfiles; s = s->next) {
+ if (s->stype == SRC_EXTLIB)
+ load_ext(s->fullpath);
+ else if (s->stype != SRC_INC)
+ have_srcfile++;
+ }
+
+ /* do version check after extensions are loaded to get extension info */
+ if (do_version)
+ version();
+
/* No -f or --source options, use next arg */
- if (srcfiles->next == srcfiles) {
+ if (! have_srcfile) {
if (optind > argc - 1 || stopped_early) /* no args left or no program */
usage(EXIT_FAILURE, stderr);
(void) add_srcfile(SRC_CMDLINE, argv[optind], srcfiles, NULL, NULL);
optind++;
}
+ /* Select the interpreter routine */
+ init_interpret();
+
init_args(optind, argc,
do_posix ? argv[0] : myname,
argv);
@@ -628,19 +442,24 @@ out:
setlocale(LC_NUMERIC, "C");
#endif
/* Read in the program */
- if (parse_program(&code_block) != 0)
+ if (parse_program(& code_block) != 0)
exit(EXIT_FAILURE);
if (do_intl)
exit(EXIT_SUCCESS);
+ install_builtins();
+
if (do_lint)
shadow_funcs();
if (do_lint && code_block->nexti->opcode == Op_atexit)
lintwarn(_("no program text at all!"));
- init_profiling_signals();
+ load_symbols();
+
+ if (do_profile)
+ init_profiling_signals();
#if defined(LC_NUMERIC)
/*
@@ -659,13 +478,20 @@ out:
* data using the local decimal point.
*/
if (use_lc_numeric)
- setlocale(LC_NUMERIC, "");
+ setlocale(LC_NUMERIC, locale);
#endif
+ init_io();
output_fp = stdout;
- interpret(code_block);
- if (do_profiling) {
+ if (do_debug)
+ debug_prog(code_block);
+ else if (do_pretty_print && ! do_profile)
+ ; /* run pretty printer only. */
+ else
+ interpret(code_block);
+
+ if (do_pretty_print) {
dump_prog(code_block);
dump_funcs();
}
@@ -673,6 +499,11 @@ out:
if (do_dump_vars)
dump_vars(varfile);
+#ifdef HAVE_MPFR
+ if (do_mpfr)
+ cleanup_mpfr();
+#endif
+
if (do_tidy_mem)
release_all_vars();
@@ -680,7 +511,7 @@ out:
if (extra_stack)
efree(extra_stack);
- exit(exit_val); /* more portable */
+ final_exit(exit_val);
return exit_val; /* to suppress warnings */
}
@@ -718,8 +549,7 @@ 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);
- if (which_gawk != exe_debugging)
- fprintf(fp, _("Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"),
+ 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. */
@@ -733,19 +563,22 @@ usage(int exitval, FILE *fp)
fputs(_("\t-c\t\t\t--traditional\n"), fp);
fputs(_("\t-C\t\t\t--copyright\n"), fp);
fputs(_("\t-d[file]\t\t--dump-variables[=file]\n"), fp);
+ fputs(_("\t-D[file]\t\t--debug[=file]\n"), fp);
fputs(_("\t-e 'program-text'\t--source='program-text'\n"), fp);
fputs(_("\t-E file\t\t\t--exec=file\n"), fp);
fputs(_("\t-g\t\t\t--gen-pot\n"), fp);
fputs(_("\t-h\t\t\t--help\n"), fp);
- fputs(_("\t-L [fatal]\t\t--lint[=fatal]\n"), fp);
- fputs(_("\t-n\t\t\t--non-decimal-data\n"), fp);
+ fputs(_("\t-i includefile\t\t--include=includefile\n"), fp);
+ fputs(_("\t-l library\t\t--load=library\n"), fp);
+ fputs(_("\t-L[fatal|invalid]\t--lint[=fatal|invalid]\n"), fp);
+ fputs(_("\t-M\t\t\t--bignum\n"), fp);
fputs(_("\t-N\t\t\t--use-lc-numeric\n"), fp);
+ fputs(_("\t-n\t\t\t--non-decimal-data\n"), fp);
+ fputs(_("\t-o[file]\t\t--pretty-print[=file]\n"), fp);
fputs(_("\t-O\t\t\t--optimize\n"), fp);
fputs(_("\t-p[file]\t\t--profile[=file]\n"), fp);
fputs(_("\t-P\t\t\t--posix\n"), fp);
fputs(_("\t-r\t\t\t--re-interval\n"), fp);
- if (which_gawk == exe_debugging)
- fputs(_("\t-R file\t\t\t--command=file\n"), fp);
fputs(_("\t-S\t\t\t--sandbox\n"), fp);
fputs(_("\t-t\t\t\t--lint-old\n"), fp);
fputs(_("\t-V\t\t\t--version\n"), fp);
@@ -776,8 +609,13 @@ By default it reads standard input and writes standard output.\n\n"), fp);
fflush(fp);
if (ferror(fp)) {
- if (fp == stdout)
- warning(_("error writing standard output (%s)"), strerror(errno));
+ /* don't warn about stdout/stderr if EPIPE, but do error exit */
+ if (errno != EPIPE) {
+ if (fp == stdout)
+ warning(_("error writing standard output (%s)"), strerror(errno));
+ else if (fp == stderr)
+ warning(_("error writing standard error (%s)"), strerror(errno));
+ }
exit(EXIT_FAILURE);
}
@@ -814,7 +652,9 @@ along with this program. If not, see http://www.gnu.org/licenses/.\n");
fflush(stdout);
if (ferror(stdout)) {
- warning(_("error writing standard output (%s)"), strerror(errno));
+ /* don't warn about stdout if EPIPE, but do error exit */
+ if (errno != EPIPE)
+ warning(_("error writing standard output (%s)"), strerror(errno));
exit(EXIT_FAILURE);
}
@@ -893,40 +733,43 @@ struct varinit {
AWKNUM numval;
Func_ptr update;
Func_ptr assign;
- int do_assign;
+ bool do_assign;
int flags;
#define NO_INSTALL 0x01
#define NON_STANDARD 0x02
+#define NOT_OFF_LIMITS 0x04 /* may be accessed by extension function */
};
static const struct varinit varinit[] = {
-{NULL, "ARGC", NULL, 0, NULL, NULL, FALSE, NO_INSTALL },
-{&ARGIND_node, "ARGIND", NULL, 0, NULL, NULL, FALSE, NON_STANDARD },
-{NULL, "ARGV", NULL, 0, NULL, NULL, FALSE, NO_INSTALL },
-{&BINMODE_node, "BINMODE", NULL, 0, NULL, set_BINMODE, FALSE, NON_STANDARD },
-{&CONVFMT_node, "CONVFMT", "%.6g", 0, NULL, set_CONVFMT,TRUE, 0 },
-{NULL, "ENVIRON", NULL, 0, NULL, NULL, FALSE, NO_INSTALL },
-{&ERRNO_node, "ERRNO", "", 0, NULL, NULL, FALSE, NON_STANDARD },
-{&FIELDWIDTHS_node, "FIELDWIDTHS", "", 0, NULL, set_FIELDWIDTHS, FALSE, NON_STANDARD },
-{&FILENAME_node, "FILENAME", "", 0, NULL, NULL, FALSE, 0 },
-{&FNR_node, "FNR", NULL, 0, update_FNR, set_FNR, TRUE, 0 },
-{&FS_node, "FS", " ", 0, NULL, set_FS, FALSE, 0 },
-{&FPAT_node, "FPAT", "[^[:space:]]+", 0, NULL, set_FPAT, FALSE, NON_STANDARD },
-{&IGNORECASE_node, "IGNORECASE", NULL, 0, NULL, set_IGNORECASE, FALSE, NON_STANDARD },
-{&LINT_node, "LINT", NULL, 0, NULL, set_LINT, FALSE, NON_STANDARD },
-{&NF_node, "NF", NULL, -1, update_NF, set_NF, FALSE, 0 },
-{&NR_node, "NR", NULL, 0, update_NR, set_NR, TRUE, 0 },
-{&OFMT_node, "OFMT", "%.6g", 0, NULL, set_OFMT, TRUE, 0 },
-{&OFS_node, "OFS", " ", 0, NULL, set_OFS, TRUE, 0 },
-{&ORS_node, "ORS", "\n", 0, NULL, set_ORS, TRUE, 0 },
-{NULL, "PROCINFO", NULL, 0, NULL, NULL, FALSE, NO_INSTALL | NON_STANDARD },
-{&RLENGTH_node, "RLENGTH", NULL, 0, NULL, NULL, FALSE, 0 },
-{&RS_node, "RS", "\n", 0, NULL, set_RS, TRUE, 0 },
-{&RSTART_node, "RSTART", NULL, 0, NULL, NULL, FALSE, 0 },
-{&RT_node, "RT", "", 0, NULL, NULL, FALSE, NON_STANDARD },
-{&SUBSEP_node, "SUBSEP", "\034", 0, NULL, set_SUBSEP, TRUE, 0 },
-{&TEXTDOMAIN_node, "TEXTDOMAIN", "messages", 0, NULL, set_TEXTDOMAIN, TRUE, NON_STANDARD },
-{0, NULL, NULL, 0, NULL, NULL, FALSE, 0 },
+{NULL, "ARGC", NULL, 0, NULL, NULL, false, NO_INSTALL },
+{&ARGIND_node, "ARGIND", NULL, 0, NULL, NULL, false, NON_STANDARD },
+{NULL, "ARGV", NULL, 0, NULL, NULL, false, NO_INSTALL },
+{&BINMODE_node, "BINMODE", NULL, 0, NULL, set_BINMODE, false, NON_STANDARD },
+{&CONVFMT_node, "CONVFMT", "%.6g", 0, NULL, set_CONVFMT,true, 0 },
+{NULL, "ENVIRON", NULL, 0, NULL, NULL, false, NO_INSTALL },
+{&ERRNO_node, "ERRNO", "", 0, NULL, NULL, false, NON_STANDARD },
+{&FIELDWIDTHS_node, "FIELDWIDTHS", "", 0, NULL, set_FIELDWIDTHS, false, NON_STANDARD },
+{&FILENAME_node, "FILENAME", "", 0, NULL, NULL, false, 0 },
+{&FNR_node, "FNR", NULL, 0, update_FNR, set_FNR, true, 0 },
+{&FS_node, "FS", " ", 0, NULL, set_FS, false, 0 },
+{&FPAT_node, "FPAT", "[^[:space:]]+", 0, NULL, set_FPAT, false, NON_STANDARD },
+{&IGNORECASE_node, "IGNORECASE", NULL, 0, NULL, set_IGNORECASE, false, NON_STANDARD },
+{&LINT_node, "LINT", NULL, 0, NULL, set_LINT, false, NON_STANDARD },
+{&PREC_node, "PREC", NULL, DEFAULT_PREC, NULL, set_PREC, false, NON_STANDARD},
+{&NF_node, "NF", NULL, -1, update_NF, set_NF, false, 0 },
+{&NR_node, "NR", NULL, 0, update_NR, set_NR, true, 0 },
+{&OFMT_node, "OFMT", "%.6g", 0, NULL, set_OFMT, true, 0 },
+{&OFS_node, "OFS", " ", 0, NULL, set_OFS, true, 0 },
+{&ORS_node, "ORS", "\n", 0, NULL, set_ORS, true, 0 },
+{NULL, "PROCINFO", NULL, 0, NULL, NULL, false, NO_INSTALL | NON_STANDARD | NOT_OFF_LIMITS },
+{&RLENGTH_node, "RLENGTH", NULL, 0, NULL, NULL, false, 0 },
+{&ROUNDMODE_node, "ROUNDMODE", DEFAULT_ROUNDMODE, 0, NULL, set_ROUNDMODE, false, NON_STANDARD },
+{&RS_node, "RS", "\n", 0, NULL, set_RS, true, 0 },
+{&RSTART_node, "RSTART", NULL, 0, NULL, NULL, false, 0 },
+{&RT_node, "RT", "", 0, NULL, NULL, false, NON_STANDARD },
+{&SUBSEP_node, "SUBSEP", "\034", 0, NULL, set_SUBSEP, true, 0 },
+{&TEXTDOMAIN_node, "TEXTDOMAIN", "messages", 0, NULL, set_TEXTDOMAIN, true, NON_STANDARD },
+{0, NULL, NULL, 0, NULL, NULL, false, 0 },
};
/* init_vars --- actually initialize everything in the symbol table */
@@ -941,18 +784,50 @@ init_vars()
if ((vp->flags & NO_INSTALL) != 0)
continue;
n = *(vp->spec) = install_symbol(estrdup(vp->name, strlen(vp->name)), Node_var);
- n->var_value = vp->strval == NULL ? make_number(vp->numval)
- : make_string(vp->strval, strlen(vp->strval));
+ if (vp->strval != NULL)
+ n->var_value = make_string(vp->strval, strlen(vp->strval));
+ else
+ n->var_value = make_number(vp->numval);
n->var_assign = (Func_ptr) vp->assign;
n->var_update = (Func_ptr) vp->update;
if (vp->do_assign)
(*(vp->assign))();
}
- /* Set up deferred variables (loaded only when accessed). */
+ /* Load PROCINFO and ENVIRON */
if (! do_traditional)
- register_deferred_variable("PROCINFO", load_procinfo);
- register_deferred_variable("ENVIRON", load_environ);
+ load_procinfo();
+ load_environ();
+}
+
+/* path_environ --- put path variable into environment if not already there */
+
+static void
+path_environ(const char *pname, const char *dflt)
+{
+ const char *val;
+ NODE **aptr;
+ NODE *tmp;
+
+ tmp = make_string(pname, strlen(pname));
+ /*
+ * On VMS, environ[] only holds a subset of what getenv() can
+ * find, so look AWKPATH up before resorting to default path.
+ */
+ val = getenv(pname);
+ if (val == NULL || *val == '\0')
+ val = dflt;
+ aptr = assoc_lookup(ENVIRON_node, tmp);
+ /*
+ * If original value was the empty string, set it to
+ * the default value.
+ */
+ if ((*aptr)->stlen == 0) {
+ unref(*aptr);
+ *aptr = make_string(val, strlen(val));
+ }
+
+ unref(tmp);
}
/* load_environ --- populate the ENVIRON array */
@@ -967,6 +842,12 @@ load_environ()
NODE **aptr;
int i;
NODE *tmp;
+ static bool been_here = false;
+
+ if (been_here)
+ return ENVIRON_node;
+
+ been_here = true;
ENVIRON_node = install_symbol(estrdup("ENVIRON", 7), Node_var_array);
for (i = 0; environ[i] != NULL; i++) {
@@ -990,23 +871,20 @@ load_environ()
*--val = '=';
}
/*
- * Put AWKPATH into ENVIRON if it's not there.
+ * Put AWKPATH and AWKLIBPATH into ENVIRON if not already there.
* This allows querying it from within awk programs.
+ *
+ * October 2014:
+ * If their values are "", override with the default values;
+ * since 2.10 AWKPATH used default value if environment's
+ * value was "".
*/
- tmp = make_string("AWKPATH", 7);
- if (! in_array(ENVIRON_node, tmp)) {
- /*
- * On VMS, environ[] only holds a subset of what getenv() can
- * find, so look AWKPATH up before resorting to default path.
- */
- val = getenv("AWKPATH");
- if (val == NULL)
- val = defpath;
- aptr = assoc_lookup(ENVIRON_node, tmp);
- unref(*aptr);
- *aptr = make_string(val, strlen(val));
- }
- unref(tmp);
+ path_environ("AWKPATH", defpath);
+ path_environ("AWKLIBPATH", deflibpath);
+
+ /* set up array functions */
+ init_env_array(ENVIRON_node);
+
return ENVIRON_node;
}
@@ -1017,15 +895,37 @@ load_procinfo()
{
#if defined (HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
int i;
+#endif
+#if (defined (HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0) || defined(HAVE_MPFR)
char name[100];
#endif
AWKNUM value;
+ static bool been_here = false;
+
+ if (been_here)
+ return PROCINFO_node;
+
+ been_here = true;
PROCINFO_node = install_symbol(estrdup("PROCINFO", 8), Node_var_array);
update_PROCINFO_str("version", VERSION);
update_PROCINFO_str("strftime", def_strftime_format);
+#ifdef HAVE_MPFR
+ sprintf(name, "GNU MPFR %s", mpfr_get_version());
+ update_PROCINFO_str("mpfr_version", name);
+ sprintf(name, "GNU MP %s", gmp_version);
+ update_PROCINFO_str("gmp_version", name);
+ update_PROCINFO_num("prec_max", MPFR_PREC_MAX);
+ update_PROCINFO_num("prec_min", MPFR_PREC_MIN);
+#endif
+
+#ifdef DYNAMIC
+ update_PROCINFO_num("api_major", GAWK_API_MAJOR_VERSION);
+ update_PROCINFO_num("api_minor", GAWK_API_MINOR_VERSION);
+#endif
+
#ifdef GETPGRP_VOID
#define getpgrp_arg() /* nothing */
#else
@@ -1100,15 +1000,32 @@ is_std_var(const char *var)
for (vp = varinit; vp->name != NULL; vp++) {
if (strcmp(vp->name, var) == 0) {
if ((do_traditional || do_posix) && (vp->flags & NON_STANDARD) != 0)
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
+/*
+ * is_off_limits_var --- return true if a variable is off limits
+ * to extension functions
+ */
+
+int
+is_off_limits_var(const char *var)
+{
+ const struct varinit *vp;
+
+ for (vp = varinit; vp->name != NULL; vp++) {
+ if (strcmp(vp->name, var) == 0)
+ return ((vp->flags & NOT_OFF_LIMITS) == 0);
+ }
+
+ return false;
+}
/* get_spec_varname --- return the name of a special variable
with the given assign or update routine.
@@ -1132,23 +1049,23 @@ get_spec_varname(Func_ptr fptr)
/* arg_assign --- process a command-line assignment */
int
-arg_assign(char *arg, int initing)
+arg_assign(char *arg, bool initing)
{
char *cp, *cp2;
- int badvar;
+ bool badvar;
NODE *var;
NODE *it;
NODE **lhs;
long save_FNR;
if (! initing && disallow_var_assigns)
- return FALSE; /* --exec */
+ return false; /* --exec */
cp = strchr(arg, '=');
if (cp == NULL) {
if (! initing)
- return FALSE; /* This is file name, not assignment. */
+ return false; /* This is file name, not assignment. */
fprintf(stderr,
_("%s: `%s' argument to `-v' not in `var=value' form\n\n"),
@@ -1165,13 +1082,13 @@ arg_assign(char *arg, int initing)
FNR = 0;
/* first check that the variable name has valid syntax */
- badvar = FALSE;
- if (! isalpha((unsigned char) arg[0]) && arg[0] != '_')
- badvar = TRUE;
+ badvar = false;
+ if (! is_alpha((unsigned char) arg[0]) && arg[0] != '_')
+ badvar = true;
else
for (cp2 = arg+1; *cp2; cp2++)
- if (! isalnum((unsigned char) *cp2) && *cp2 != '_') {
- badvar = TRUE;
+ if (! is_identchar((unsigned char) *cp2)) {
+ badvar = true;
break;
}
@@ -1206,7 +1123,7 @@ arg_assign(char *arg, int initing)
setlocale(LC_NUMERIC, "C");
(void) force_number(it);
if (do_posix)
- setlocale(LC_NUMERIC, "");
+ setlocale(LC_NUMERIC, locale);
#endif /* LC_NUMERIC */
/*
@@ -1219,10 +1136,10 @@ arg_assign(char *arg, int initing)
var = variable(0, cp2, Node_var);
if (var == NULL) /* error */
- exit(EXIT_FATAL);
+ final_exit(EXIT_FATAL);
if (var->type == Node_var && var->var_update)
var->var_update();
- lhs = get_lhs(var, FALSE);
+ lhs = get_lhs(var, false);
unref(*lhs);
*lhs = it;
/* check for set_FOO() routine */
@@ -1302,7 +1219,16 @@ nostalgia()
static void
version()
{
- printf("%s\n", version_string);
+ printf("%s", version_string);
+#ifdef DYNAMIC
+ printf(", API: %d.%d", GAWK_API_MAJOR_VERSION, GAWK_API_MINOR_VERSION);
+#endif
+#ifdef HAVE_MPFR
+ printf(" (GNU MPFR %s, GNU MP %s)", mpfr_get_version(), gmp_version);
+#endif
+ printf("\n");
+ print_ext_versions();
+
/*
* Per GNU coding standards, print copyright info,
* then exit successfully, do nothing else.
@@ -1355,17 +1281,20 @@ init_groupset()
*/
ngroups = getgroups(0, NULL);
#endif
- if (ngroups == -1)
- fatal(_("could not find groups: %s"), strerror(errno));
- else if (ngroups == 0)
+ /* If an error or no groups, just give up and get on with life. */
+ 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));
+ /* same thing here, give up but keep going */
+ if (ngroups == -1) {
+ efree(groupset);
+ ngroups = 0;
+ groupset = NULL;
+ }
#endif
}
@@ -1429,6 +1358,8 @@ save_argv(int argc, char **argv)
/*
* update_global_values --- make sure the symbol table has correct values.
* Called from the grammar before dumping values.
+ *
+ * Also called when accessing through SYMTAB, and from api_sym_lookup().
*/
void
@@ -1456,3 +1387,285 @@ getenv_long(const char *name)
}
return -1;
}
+
+/* parse_args --- do the getopt_long thing */
+
+static void
+parse_args(int argc, char **argv)
+{
+ /*
+ * The + on the front tells GNU getopt not to rearrange argv.
+ */
+ const char *optlist = "+F:f:v:W;bcCd::D::e:E:ghi:l:L:nNo::Op::MPrStVYZ:";
+ int old_optind;
+ int c;
+ char *scan;
+ char *src;
+
+ /* we do error messages ourselves on invalid options */
+ opterr = false;
+
+ /* copy argv before getopt gets to it; used to restart the debugger */
+ save_argv(argc, argv);
+
+ /* 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':
+ add_preassign(PRE_ASSIGN_FS, optarg);
+ break;
+
+ case 'E':
+ disallow_var_assigns = true;
+ /* fall through */
+ case 'f':
+ /*
+ * 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((unsigned char) *scan))
+ scan++;
+ src = (*scan == '\0' ? argv[optind++] : optarg);
+ (void) add_srcfile((src && src[0] == '-' && src[1] == '\0') ?
+ SRC_STDIN : SRC_FILE,
+ src, srcfiles, NULL, NULL);
+
+ break;
+
+ case 'v':
+ add_preassign(PRE_ASSIGN, optarg);
+ break;
+
+ case 'b':
+ do_binary = true;
+ break;
+
+ case 'c':
+ do_flags |= DO_TRADITIONAL;
+ break;
+
+ case 'C':
+ copyleft();
+ break;
+
+ case 'd':
+ do_flags |= DO_DUMP_VARS;
+ if (optarg != NULL && optarg[0] != '\0')
+ varfile = optarg;
+ break;
+
+ case 'D':
+ do_flags |= DO_DEBUG;
+ if (optarg != NULL && optarg[0] != '\0')
+ command_file = optarg;
+ break;
+
+ case 'e':
+ if (optarg[0] == '\0')
+ warning(_("empty argument to `-e/--source' ignored"));
+ else
+ (void) add_srcfile(SRC_CMDLINE, optarg, srcfiles, NULL, NULL);
+ break;
+
+ case 'g':
+ do_flags |= DO_INTL;
+ break;
+
+ case 'h':
+ /* write usage to stdout, per GNU coding stds */
+ usage(EXIT_SUCCESS, stdout);
+ break;
+
+ case 'i':
+ (void) add_srcfile(SRC_INC, optarg, srcfiles, NULL, NULL);
+ break;
+
+ case 'l':
+ (void) add_srcfile(SRC_EXTLIB, optarg, srcfiles, NULL, NULL);
+ break;
+
+#ifndef NO_LINT
+ case 'L':
+ do_flags |= DO_LINT_ALL;
+ if (optarg != NULL) {
+ if (strcmp(optarg, "fatal") == 0)
+ lintfunc = r_fatal;
+ else if (strcmp(optarg, "invalid") == 0) {
+ do_flags &= ~DO_LINT_ALL;
+ do_flags |= DO_LINT_INVALID;
+ }
+ }
+ break;
+
+ case 't':
+ do_flags |= DO_LINT_OLD;
+ break;
+#else
+ case 'L':
+ case 't':
+ break;
+#endif
+
+ case 'n':
+ do_flags |= DO_NON_DEC_DATA;
+ break;
+
+ case 'N':
+ use_lc_numeric = true;
+ break;
+
+ case 'O':
+ do_optimize = true;
+ break;
+
+ case 'p':
+ do_flags |= DO_PROFILE;
+ /* fall through */
+ case 'o':
+ do_flags |= DO_PRETTY_PRINT;
+ if (optarg != NULL)
+ set_prof_file(optarg);
+ else
+ set_prof_file(DEFAULT_PROFILE);
+ break;
+
+ case 'M':
+#ifdef HAVE_MPFR
+ do_flags |= DO_MPFR;
+#else
+ warning(_("-M ignored: MPFR/GMP support not compiled in"));
+#endif
+ break;
+
+ case 'P':
+ do_flags |= DO_POSIX;
+ break;
+
+ case 'r':
+ do_flags |= DO_INTERVALS;
+ break;
+
+ case 'S':
+ do_flags |= DO_SANDBOX;
+ break;
+
+ case 'V':
+ do_version = true;
+ break;
+
+ case 'W': /* gawk specific options - now in getopt_long */
+ fprintf(stderr, _("%s: option `-W %s' unrecognized, ignored\n"),
+ argv[0], optarg);
+ 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 'Y':
+ case 'Z':
+#if defined(YYDEBUG) || defined(GAWKDEBUG)
+ if (c == 'Y') {
+ yydebug = 2;
+ break;
+ }
+#endif
+#if defined(LOCALEDEBUG)
+ if (c == 'Z') {
+ locale = optarg;
+ break;
+ }
+#endif
+ /* if not debugging, fall through */
+ case '?':
+ default:
+ /*
+ * 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 POSIX required message format */
+ fprintf(stderr,
+ _("%s: option requires an argument -- %c\n"),
+ myname, optopt);
+ usage(EXIT_FAILURE, stderr);
+ }
+ /* else
+ let getopt print error message for us */
+ break;
+ }
+ if (c == 'E') /* --exec ends option processing */
+ break;
+ }
+out:
+ return;
+}
+
+/* set_locale_stuff --- setup the locale stuff */
+
+static void
+set_locale_stuff(void)
+{
+#if defined(LC_CTYPE)
+ setlocale(LC_CTYPE, locale);
+#endif
+#if defined(LC_COLLATE)
+ setlocale(LC_COLLATE, locale);
+#endif
+#if defined(LC_MESSAGES)
+ setlocale(LC_MESSAGES, locale);
+#endif
+#if defined(LC_NUMERIC) && defined(HAVE_LOCALE_H)
+ /*
+ * 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.
+ *
+ * 10/2005 --- see below also; we now only use the locale's
+ * decimal point if do_posix in effect.
+ *
+ * 9/2007:
+ * This is a mess. We need to get the locale's numeric info for
+ * the thousands separator for the %'d flag.
+ */
+ setlocale(LC_NUMERIC, locale);
+ init_locale(& loc);
+ setlocale(LC_NUMERIC, "C");
+#endif
+#if defined(LC_TIME)
+ setlocale(LC_TIME, locale);
+#endif
+}
diff --git a/mbsupport.h b/mbsupport.h
index 6008da77..f4e1a821 100644
--- a/mbsupport.h
+++ b/mbsupport.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2004, 2005, 2011 the Free Software Foundation, Inc.
+ * Copyright (C) 2004, 2005, 2011, 2012 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -23,48 +23,27 @@
* 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
+#ifdef __DJGPP__
+# undef MB_CUR_MAX
+# define MB_CUR_MAX 1
-#ifndef NO_MBSUPPORT
+/* All this glop is for DGJPP */
-#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
-# define MBS_SUPPORT 0
-#endif
+#define towupper toupper
+#define towlower tolower
+#define iswalnum isalnum
+#define iswalpha isalpha
+#define iswupper isupper
+#define iswlower islower
-#else /* NO_MBSUPPORT is defined */
-# define MBS_SUPPORT 0
-#endif
+#define mbrtowc(wcp, s, e, mbs) (-1)
+#define mbrlen(s, e, mbs) strlen(s)
+#define wcrtomb(wc, b, mbs) (-1)
+#define wcslen strlen
+#define wctob(wc) (EOF)
-#if ! MBS_SUPPORT
-# undef MB_CUR_MAX
-# define MB_CUR_MAX 1
+extern wctype_t wctype(const char *name);
+extern int iswctype(wint_t wc, wctype_t desc);
+extern int wcscoll(const wchar_t *ws1, const wchar_t *ws2);
#endif
diff --git a/missing b/missing
index 1c8ff704..cdea5149 100755
--- a/missing
+++ b/missing
@@ -1,11 +1,10 @@
#! /bin/sh
-# Common stub for a few missing GNU programs while installing.
+# Common wrapper for a few potentially missing GNU programs.
-scriptversion=2006-05-10.23
+scriptversion=2012-06-26.16; # UTC
-# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006
-# Free Software Foundation, Inc.
-# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Originally written 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
@@ -18,9 +17,7 @@ scriptversion=2006-05-10.23
# 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.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -28,66 +25,40 @@ scriptversion=2006-05-10.23
# 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"
+ echo 1>&2 "Try '$0 --help' for more information"
exit 1
fi
-run=:
-sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
-sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
-
-# 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
+case $1 in
-msg="missing on your system"
+ --is-lightweight)
+ # Used by our autoconf macros to check whether the available missing
+ # script is modern enough.
+ exit 0
+ ;;
-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
- ;;
+ --run)
+ # Back-compat with the calling convention used by older automake.
+ shift
+ ;;
-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.
+Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
+to PROGRAM being missing or too old.
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'
- autom4te touch the output file, or create a stub one
- 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]
+ aclocal autoconf autoheader autom4te automake makeinfo
+ bison yacc flex lex help2man
+
+Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
+'g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
@@ -99,269 +70,146 @@ Send bug reports to <bug-automake@gnu.org>."
;;
-*)
- echo 1>&2 "$0: Unknown \`$1' option"
- echo 1>&2 "Try \`$0 --help' for more information"
+ 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 "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- 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 test $# -ne 1; then
- eval LASTARG="\${$#}"
- case $LASTARG in
- *.y)
- SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
- if test -f "$SRCFILE"; then
- cp "$SRCFILE" y.tab.c
- fi
- SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
- if test -f "$SRCFILE"; then
- cp "$SRCFILE" y.tab.h
- fi
- ;;
- esac
- fi
- if test ! -f y.tab.h; then
- echo >y.tab.h
- fi
- if test ! -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 test $# -ne 1; then
- eval LASTARG="\${$#}"
- case $LASTARG in
- *.l)
- SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
- if test -f "$SRCFILE"; then
- cp "$SRCFILE" lex.yy.c
- fi
- ;;
- esac
- fi
- if test ! -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 "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- if test -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 "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- 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
- # If the file does not exist, the user really needs makeinfo;
- # let's fail without touching anything.
- test -f $file || exit 1
- 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
+# Run the given program, remember its exit status.
+"$@"; st=$?
+
+# If it succeeded, we are done.
+test $st -eq 0 && exit 0
+
+# Also exit now if we it failed (or wasn't found), and '--version' was
+# passed; such an option is passed most likely to detect whether the
+# program is present and works.
+case $2 in --version|--help) exit $st;; esac
+
+# Exit code 63 means version mismatch. This often happens when the user
+# tries to use an ancient version of a tool on a file that requires a
+# minimum version.
+if test $st -eq 63; then
+ msg="probably too old"
+elif test $st -eq 127; then
+ # Program was missing.
+ msg="missing on your system"
+else
+ # Program was found and executed, but failed. Give up.
+ exit $st
+fi
-exit 0
+perl_URL=http://www.perl.org/
+flex_URL=http://flex.sourceforge.net/
+gnu_software_URL=http://www.gnu.org/software
+
+program_details ()
+{
+ case $1 in
+ aclocal|automake)
+ echo "The '$1' program is part of the GNU Automake package:"
+ echo "<$gnu_software_URL/automake>"
+ echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/autoconf>"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ autoconf|autom4te|autoheader)
+ echo "The '$1' program is part of the GNU Autoconf package:"
+ echo "<$gnu_software_URL/autoconf/>"
+ echo "It also requires GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ esac
+}
+
+give_advice ()
+{
+ # Normalize program name to check for.
+ normalized_program=`echo "$1" | sed '
+ s/^gnu-//; t
+ s/^gnu//; t
+ s/^g//; t'`
+
+ printf '%s\n' "'$1' is $msg."
+
+ configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
+ case $normalized_program in
+ autoconf*)
+ echo "You should only need it if you modified 'configure.ac',"
+ echo "or m4 files included by it."
+ program_details 'autoconf'
+ ;;
+ autoheader*)
+ echo "You should only need it if you modified 'acconfig.h' or"
+ echo "$configure_deps."
+ program_details 'autoheader'
+ ;;
+ automake*)
+ echo "You should only need it if you modified 'Makefile.am' or"
+ echo "$configure_deps."
+ program_details 'automake'
+ ;;
+ aclocal*)
+ echo "You should only need it if you modified 'acinclude.m4' or"
+ echo "$configure_deps."
+ program_details 'aclocal'
+ ;;
+ autom4te*)
+ echo "You might have modified some maintainer files that require"
+ echo "the 'automa4te' program to be rebuilt."
+ program_details 'autom4te'
+ ;;
+ bison*|yacc*)
+ echo "You should only need it if you modified a '.y' file."
+ echo "You may want to install the GNU Bison package:"
+ echo "<$gnu_software_URL/bison/>"
+ ;;
+ lex*|flex*)
+ echo "You should only need it if you modified a '.l' file."
+ echo "You may want to install the Fast Lexical Analyzer package:"
+ echo "<$flex_URL>"
+ ;;
+ help2man*)
+ echo "You should only need it if you modified a dependency" \
+ "of a man page."
+ echo "You may want to install the GNU Help2man package:"
+ echo "<$gnu_software_URL/help2man/>"
+ ;;
+ makeinfo*)
+ echo "You should only need it if you modified a '.texi' file, or"
+ echo "any other file indirectly affecting the aspect of the manual."
+ echo "You might want to install the Texinfo package:"
+ echo "<$gnu_software_URL/texinfo/>"
+ echo "The spurious makeinfo call might also be the consequence of"
+ echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
+ echo "want to install GNU make:"
+ echo "<$gnu_software_URL/make/>"
+ ;;
+ *)
+ echo "You might have modified some files without having the proper"
+ echo "tools for further handling them. Check the 'README' file, it"
+ echo "often tells you about the needed prerequisites for installing"
+ echo "this package. You may also peek at any GNU archive site, in"
+ echo "case some other package contains this missing '$1' program."
+ ;;
+ esac
+}
+
+give_advice "$1" | sed -e '1s/^/WARNING: /' \
+ -e '2,$s/^/ /' >&2
+
+# Propagate the correct exit status (expected to be 127 for a program
+# not found, 63 for a program that failed due to version mismatch).
+exit $st
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
# End:
diff --git a/missing_d/ChangeLog b/missing_d/ChangeLog
index 8aaeb418..70fbde64 100644
--- a/missing_d/ChangeLog
+++ b/missing_d/ChangeLog
@@ -1,3 +1,39 @@
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.1: Release tar ball made.
+
+2013-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.0: Release tar ball made.
+
+2013-02-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * fnmatch.h, fnmatch.c: New files, from GNU Make.
+
+2012-12-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.2: Release tar ball made.
+
+2012-09-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * snprintf.c, strtoul.c: Remove TRUE/FALSE in favor of true/false.
+
+2012-05-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * snprintf.c [DJGPP]: Change to __DJGPP__.
+
+2012-03-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.1: Release tar ball made.
+
+2011-11-02 Pat Rankin <r.pat.rankin@gmail.com>
+
+ * wcmisc.c: Make code be conditional upon corresponding !HAVE_WCxxx.
+
+2011-11-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ * wcmisc.c: New file.
+
2011-06-23 Arnold D. Robbins <arnold@skeeve.com>
* ChangeLog.0: Rotated ChangeLog into this file.
diff --git a/missing_d/fnmatch.c b/missing_d/fnmatch.c
new file mode 100644
index 00000000..4da8c5fb
--- /dev/null
+++ b/missing_d/fnmatch.c
@@ -0,0 +1,489 @@
+/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999 Free Software
+Foundation, Inc.
+This file is part of the GNU C Library.
+
+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; see the file COPYING.LIB. If not, write to the Free
+Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Enable GNU extensions in fnmatch.h. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+
+#include <errno.h>
+#include <fnmatch.h>
+#include <ctype.h>
+
+#if HAVE_STRING_H || defined _LIBC
+# include <string.h>
+#else
+# include <strings.h>
+#endif
+
+#if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+#endif
+
+/* For platform which support the ISO C amendement 1 functionality we
+ support user defined character classes. */
+#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
+/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
+# include <wchar.h>
+# include <wctype.h>
+#endif
+
+/* 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. */
+
+#if defined _LIBC || !defined __GNU_LIBRARY__
+
+
+# if defined STDC_HEADERS || !defined isascii
+# define ISASCII(c) 1
+# else
+# define ISASCII(c) isascii(c)
+# endif
+
+# ifdef isblank
+# define ISBLANK(c) (ISASCII (c) && isblank (c))
+# else
+# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
+# endif
+# ifdef isgraph
+# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
+# else
+# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
+# endif
+
+# define ISPRINT(c) (ISASCII (c) && isprint (c))
+# define ISDIGIT(c) (ISASCII (c) && isdigit (c))
+# define ISALNUM(c) (ISASCII (c) && isalnum (c))
+# define ISALPHA(c) (ISASCII (c) && isalpha (c))
+# define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
+# define ISLOWER(c) (ISASCII (c) && islower (c))
+# define ISPUNCT(c) (ISASCII (c) && ispunct (c))
+# define ISSPACE(c) (ISASCII (c) && isspace (c))
+# define ISUPPER(c) (ISASCII (c) && isupper (c))
+# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
+
+# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
+
+# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
+/* The GNU C library provides support for user-defined character classes
+ and the functions from ISO C amendement 1. */
+# ifdef CHARCLASS_NAME_MAX
+# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
+# else
+/* This shouldn't happen but some implementation might still have this
+ problem. Use a reasonable default value. */
+# define CHAR_CLASS_MAX_LENGTH 256
+# endif
+
+# ifdef _LIBC
+# define IS_CHAR_CLASS(string) __wctype (string)
+# else
+# define IS_CHAR_CLASS(string) wctype (string)
+# endif
+# else
+# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
+
+# define IS_CHAR_CLASS(string) \
+ (STREQ (string, "alpha") || STREQ (string, "upper") \
+ || STREQ (string, "lower") || STREQ (string, "digit") \
+ || STREQ (string, "alnum") || STREQ (string, "xdigit") \
+ || STREQ (string, "space") || STREQ (string, "print") \
+ || STREQ (string, "punct") || STREQ (string, "graph") \
+ || STREQ (string, "cntrl") || STREQ (string, "blank"))
+# endif
+
+/* Avoid depending on library functions or files
+ whose names are inconsistent. */
+
+# if !defined _LIBC && !defined getenv
+extern char *getenv ();
+# endif
+
+# ifndef errno
+extern int errno;
+# endif
+
+/* This function doesn't exist on most systems. */
+
+# if !defined HAVE___STRCHRNUL && !defined _LIBC
+static char *
+__strchrnul (s, c)
+ const char *s;
+ int c;
+{
+ char *result = strchr (s, c);
+ if (result == NULL)
+ result = strchr (s, '\0');
+ return result;
+}
+# endif
+
+# ifndef internal_function
+/* Inside GNU libc we mark some function in a special way. In other
+ environments simply ignore the marking. */
+# define internal_function
+# endif
+
+/* Match STRING against the filename pattern PATTERN, returning zero if
+ it matches, nonzero if not. */
+static int internal_fnmatch __P ((const char *pattern, const char *string,
+ int no_leading_period, int flags))
+ internal_function;
+static int
+internal_function
+internal_fnmatch (pattern, string, no_leading_period, flags)
+ const char *pattern;
+ const char *string;
+ int no_leading_period;
+ int flags;
+{
+ register const char *p = pattern, *n = string;
+ register unsigned char c;
+
+/* Note that this evaluates C many times. */
+# ifdef _LIBC
+# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
+# else
+# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
+# endif
+
+ while ((c = *p++) != '\0')
+ {
+ c = FOLD (c);
+
+ switch (c)
+ {
+ case '?':
+ if (*n == '\0')
+ return FNM_NOMATCH;
+ else if (*n == '/' && (flags & FNM_FILE_NAME))
+ return FNM_NOMATCH;
+ else if (*n == '.' && no_leading_period
+ && (n == string
+ || (n[-1] == '/' && (flags & FNM_FILE_NAME))))
+ return FNM_NOMATCH;
+ break;
+
+ case '\\':
+ if (!(flags & FNM_NOESCAPE))
+ {
+ c = *p++;
+ if (c == '\0')
+ /* Trailing \ loses. */
+ return FNM_NOMATCH;
+ c = FOLD (c);
+ }
+ if (FOLD ((unsigned char) *n) != c)
+ return FNM_NOMATCH;
+ break;
+
+ case '*':
+ if (*n == '.' && no_leading_period
+ && (n == string
+ || (n[-1] == '/' && (flags & FNM_FILE_NAME))))
+ return FNM_NOMATCH;
+
+ for (c = *p++; c == '?' || c == '*'; c = *p++)
+ {
+ if (*n == '/' && (flags & FNM_FILE_NAME))
+ /* A slash does not match a wildcard under FNM_FILE_NAME. */
+ return FNM_NOMATCH;
+ else if (c == '?')
+ {
+ /* A ? needs to match one character. */
+ if (*n == '\0')
+ /* There isn't another character; no match. */
+ return FNM_NOMATCH;
+ else
+ /* One character of the string is consumed in matching
+ this ? wildcard, so *??? won't match if there are
+ less than three characters. */
+ ++n;
+ }
+ }
+
+ if (c == '\0')
+ /* The wildcard(s) is/are the last element of the pattern.
+ If the name is a file name and contains another slash
+ this does mean it cannot match. */
+ return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL
+ ? FNM_NOMATCH : 0);
+ else
+ {
+ const char *endp;
+
+ endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
+
+ if (c == '[')
+ {
+ int flags2 = ((flags & FNM_FILE_NAME)
+ ? flags : (flags & ~FNM_PERIOD));
+
+ for (--p; n < endp; ++n)
+ if (internal_fnmatch (p, n,
+ (no_leading_period
+ && (n == string
+ || (n[-1] == '/'
+ && (flags
+ & FNM_FILE_NAME)))),
+ flags2)
+ == 0)
+ return 0;
+ }
+ else if (c == '/' && (flags & FNM_FILE_NAME))
+ {
+ while (*n != '\0' && *n != '/')
+ ++n;
+ if (*n == '/'
+ && (internal_fnmatch (p, n + 1, flags & FNM_PERIOD,
+ flags) == 0))
+ return 0;
+ }
+ else
+ {
+ int flags2 = ((flags & FNM_FILE_NAME)
+ ? flags : (flags & ~FNM_PERIOD));
+
+ if (c == '\\' && !(flags & FNM_NOESCAPE))
+ c = *p;
+ c = FOLD (c);
+ for (--p; n < endp; ++n)
+ if (FOLD ((unsigned char) *n) == c
+ && (internal_fnmatch (p, n,
+ (no_leading_period
+ && (n == string
+ || (n[-1] == '/'
+ && (flags
+ & FNM_FILE_NAME)))),
+ flags2) == 0))
+ return 0;
+ }
+ }
+
+ /* If we come here no match is possible with the wildcard. */
+ return FNM_NOMATCH;
+
+ case '[':
+ {
+ /* Nonzero if the sense of the character class is inverted. */
+ static int posixly_correct;
+ register int not;
+ char cold;
+
+ if (posixly_correct == 0)
+ posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
+
+ if (*n == '\0')
+ return FNM_NOMATCH;
+
+ if (*n == '.' && no_leading_period && (n == string
+ || (n[-1] == '/'
+ && (flags
+ & FNM_FILE_NAME))))
+ return FNM_NOMATCH;
+
+ if (*n == '/' && (flags & FNM_FILE_NAME))
+ /* `/' cannot be matched. */
+ return FNM_NOMATCH;
+
+ not = (*p == '!' || (posixly_correct < 0 && *p == '^'));
+ if (not)
+ ++p;
+
+ c = *p++;
+ for (;;)
+ {
+ unsigned char fn = FOLD ((unsigned char) *n);
+
+ if (!(flags & FNM_NOESCAPE) && c == '\\')
+ {
+ if (*p == '\0')
+ return FNM_NOMATCH;
+ c = FOLD ((unsigned char) *p);
+ ++p;
+
+ if (c == fn)
+ goto matched;
+ }
+ else if (c == '[' && *p == ':')
+ {
+ /* Leave room for the null. */
+ char str[CHAR_CLASS_MAX_LENGTH + 1];
+ size_t c1 = 0;
+# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
+ wctype_t wt;
+# endif
+ const char *startp = p;
+
+ for (;;)
+ {
+ if (c1 == CHAR_CLASS_MAX_LENGTH)
+ /* The name is too long and therefore the pattern
+ is ill-formed. */
+ return FNM_NOMATCH;
+
+ c = *++p;
+ if (c == ':' && p[1] == ']')
+ {
+ p += 2;
+ break;
+ }
+ if (c < 'a' || c >= 'z')
+ {
+ /* This cannot possibly be a character class name.
+ Match it as a normal range. */
+ p = startp;
+ c = '[';
+ goto normal_bracket;
+ }
+ str[c1++] = c;
+ }
+ str[c1] = '\0';
+
+# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
+ wt = IS_CHAR_CLASS (str);
+ if (wt == 0)
+ /* Invalid character class name. */
+ return FNM_NOMATCH;
+
+ if (__iswctype (__btowc ((unsigned char) *n), wt))
+ goto matched;
+# else
+ if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n))
+ || (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n))
+ || (STREQ (str, "blank") && ISBLANK ((unsigned char) *n))
+ || (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n))
+ || (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n))
+ || (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n))
+ || (STREQ (str, "lower") && ISLOWER ((unsigned char) *n))
+ || (STREQ (str, "print") && ISPRINT ((unsigned char) *n))
+ || (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n))
+ || (STREQ (str, "space") && ISSPACE ((unsigned char) *n))
+ || (STREQ (str, "upper") && ISUPPER ((unsigned char) *n))
+ || (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n)))
+ goto matched;
+# endif
+ }
+ else if (c == '\0')
+ /* [ (unterminated) loses. */
+ return FNM_NOMATCH;
+ else
+ {
+ normal_bracket:
+ if (FOLD (c) == fn)
+ goto matched;
+
+ cold = c;
+ c = *p++;
+
+ if (c == '-' && *p != ']')
+ {
+ /* It is a range. */
+ unsigned char cend = *p++;
+ if (!(flags & FNM_NOESCAPE) && cend == '\\')
+ cend = *p++;
+ if (cend == '\0')
+ return FNM_NOMATCH;
+
+ if (cold <= fn && fn <= FOLD (cend))
+ goto matched;
+
+ c = *p++;
+ }
+ }
+
+ if (c == ']')
+ break;
+ }
+
+ if (!not)
+ return FNM_NOMATCH;
+ break;
+
+ matched:
+ /* Skip the rest of the [...] that already matched. */
+ while (c != ']')
+ {
+ if (c == '\0')
+ /* [... (unterminated) loses. */
+ return FNM_NOMATCH;
+
+ c = *p++;
+ if (!(flags & FNM_NOESCAPE) && c == '\\')
+ {
+ if (*p == '\0')
+ return FNM_NOMATCH;
+ /* XXX 1003.2d11 is unclear if this is right. */
+ ++p;
+ }
+ else if (c == '[' && *p == ':')
+ {
+ do
+ if (*++p == '\0')
+ return FNM_NOMATCH;
+ while (*p != ':' || p[1] == ']');
+ p += 2;
+ c = *p;
+ }
+ }
+ if (not)
+ return FNM_NOMATCH;
+ }
+ break;
+
+ default:
+ if (c != FOLD ((unsigned char) *n))
+ return FNM_NOMATCH;
+ }
+
+ ++n;
+ }
+
+ if (*n == '\0')
+ return 0;
+
+ if ((flags & FNM_LEADING_DIR) && *n == '/')
+ /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
+ return 0;
+
+ return FNM_NOMATCH;
+
+# undef FOLD
+}
+
+
+int
+fnmatch (pattern, string, flags)
+ const char *pattern;
+ const char *string;
+ int flags;
+{
+ return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags);
+}
+
+#endif /* _LIBC or not __GNU_LIBRARY__. */
diff --git a/missing_d/fnmatch.h b/missing_d/fnmatch.h
new file mode 100644
index 00000000..a788c8e1
--- /dev/null
+++ b/missing_d/fnmatch.h
@@ -0,0 +1,85 @@
+/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999 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 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 this library; see the file COPYING.LIB. If not, write to the Free
+Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA. */
+
+#ifndef _FNMATCH_H
+#define _FNMATCH_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
+# if !defined __GLIBC__
+# undef __P
+# define __P(protos) protos
+# endif
+#else /* Not C++ or ANSI C. */
+# undef __P
+# define __P(protos) ()
+/* We can get away without defining `const' here only because in this file
+ it is used only inside the prototype for `fnmatch', which is elided in
+ non-ANSI C where `const' is problematical. */
+#endif /* C++ or ANSI C. */
+
+#ifndef const
+# if (defined __STDC__ && __STDC__) || defined __cplusplus || defined WINDOWS32
+# define __const const
+# else
+# define __const
+# endif
+#endif
+
+/* We #undef these before defining them because some losing systems
+ (HP-UX A.08.07 for example) define these in <unistd.h>. */
+#undef FNM_PATHNAME
+#undef FNM_NOESCAPE
+#undef FNM_PERIOD
+
+/* Bits set in the FLAGS argument to `fnmatch'. */
+#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
+#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
+#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
+
+#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE
+# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
+# define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
+# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
+#endif
+
+/* Value returned by `fnmatch' if STRING does not match PATTERN. */
+#define FNM_NOMATCH 1
+
+/* This value is returned if the implementation does not support
+ `fnmatch'. Since this is not the case here it will never be
+ returned but the conformance test suites still require the symbol
+ to be defined. */
+#ifdef _XOPEN_SOURCE
+# define FNM_NOSYS (-1)
+#endif
+
+/* Match NAME against the filename pattern PATTERN,
+ returning zero if it matches, FNM_NOMATCH if not. */
+extern int fnmatch __P ((__const char *__pattern, __const char *__name,
+ int __flags));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* fnmatch.h */
diff --git a/eval_d.c b/missing_d/gawkbool.h
index 64a8e55a..c75a5a10 100644
--- a/eval_d.c
+++ b/missing_d/gawkbool.h
@@ -1,16 +1,16 @@
/*
- * eval_p.c - compile eval.c with debugging turned on.
+ * gawkbool.h -- replacement definitions for bool.
*/
/*
- * Copyright (C) 2001 the Free Software Foundation, Inc.
+ * Copyright (C) 2012 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
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* GAWK is distributed in the hope that it will be useful,
@@ -20,8 +20,21 @@
*
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#define DEBUGGING 1
-#include "eval.c"
+/* This stuff largely taken from the Autoconf doc. */
+
+#ifndef __bool_true_false_are_defined
+# ifndef HAVE__BOOL
+# ifdef __cplusplus
+typedef bool _Bool;
+# else
+# define _Bool signed char
+# endif
+# endif
+# define bool _Bool
+# define false 0
+# define true 1
+# define __bool_true_false_are_defined 1
+#endif
diff --git a/missing_d/snprintf.c b/missing_d/snprintf.c
index 254a8e0b..6cee2bed 100644
--- a/missing_d/snprintf.c
+++ b/missing_d/snprintf.c
@@ -53,14 +53,14 @@ static void close_safe_f()
static FILE *
safe_tmpfile (void)
{
- static short first = TRUE;
+ static bool first = true;
static const char template[] = "snprintfXXXXXX";
int fd;
static char *tmpdir = NULL;
static int len = 0;
if (first) {
- first = FALSE;
+ first = false;
/*
* First try Unix stanadard env var, then Windows var,
* then fall back to /tmp.
@@ -86,10 +86,10 @@ safe_tmpfile (void)
if ((fd = mkstemp (tmpfilename)) < 0)
return NULL;
-#if ! defined(DJGPP) && ! defined(MSDOS) && ! defined(_MSC_VER) \
+#if ! defined(__DJGPP__) && ! defined(MSDOS) && ! defined(_MSC_VER) \
&& ! defined(_WIN32) && ! defined(__CRTRSXNT__) && ! defined(__EMX__) \
&& ! defined(__MINGW32__) && ! defined(__WIN32__)
- /* If not MS, unlink after opening. */
+ /* If not MS or OS/2, unlink after opening. */
unlink (tmpfilename);
free(tmpfilename);
tmpfilename = NULL;
diff --git a/missing_d/strtoul.c b/missing_d/strtoul.c
index d2655750..cdd7cf14 100644
--- a/missing_d/strtoul.c
+++ b/missing_d/strtoul.c
@@ -14,8 +14,6 @@
#include <string.h>
#include <errno.h>
#include <limits.h>
-#define TRUE 1
-#define FALSE 0
#define strtoul mystrtoul
#endif
@@ -33,10 +31,10 @@ int base;
unsigned long result = 0UL;
char *nptr_orig = (char *) nptr;
- int neg = FALSE;
+ bool neg = false;
char *cp, c;
int val;
- int sawdigs = FALSE;
+ bool sawdigs = false;
/*
* The strtoul() function converts the initial part of the
@@ -64,7 +62,7 @@ int base;
nptr++;
else if (*nptr == '-') {
nptr++;
- neg = TRUE;
+ neg = true;
}
/*
@@ -110,7 +108,7 @@ int base;
goto out;
result *= base;
result += val;
- sawdigs = TRUE;
+ sawdigs = true;
break;
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
@@ -133,7 +131,7 @@ int base;
goto out;
result *= base;
result += val;
- sawdigs = TRUE;
+ sawdigs = true;
break;
default:
goto out;
diff --git a/missing_d/wcmisc.c b/missing_d/wcmisc.c
new file mode 100644
index 00000000..d2b7aa08
--- /dev/null
+++ b/missing_d/wcmisc.c
@@ -0,0 +1,100 @@
+/* wcmisc.c - replace wcXXXX routines
+ Copyright (C) 2011 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 3, 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 !defined(HAVE_WCTYPE) || !defined(HAVE_ISWCTYPE)
+static const char *classes[] = {
+ "<dummy>",
+ "alnum",
+ "alpha",
+ "blank",
+ "cntrl",
+ "digit",
+ "graph",
+ "lower",
+ "print",
+ "punct",
+ "space",
+ "upper",
+ "xdigit",
+ NULL
+};
+#endif
+
+#ifndef HAVE_ISWCTYPE
+static int is_blank (int c)
+{
+ return (c == ' ' || c == '\t');
+}
+#endif
+
+#ifndef HAVE_WCTYPE
+wctype_t wctype(const char *name)
+{
+ int i;
+
+ for (i = 1; classes[i] != NULL; i++)
+ if (strcmp(name, classes[i]) == 0)
+ return i;
+
+ return 0;
+}
+#endif
+
+#ifndef HAVE_ISWCTYPE
+int iswctype(wint_t wc, wctype_t desc)
+{
+ int j = sizeof(classes) / sizeof(classes[0]);
+
+ if (desc >= j || desc == 0)
+ return 0;
+
+ switch (desc) {
+ case 1: return isalnum(wc);
+ case 2: return isalpha(wc);
+ case 3: return is_blank(wc);
+ case 4: return iscntrl(wc);
+ case 5: return isdigit(wc);
+ case 6: return isgraph(wc);
+ case 7: return islower(wc);
+ case 8: return isprint(wc);
+ case 9: return ispunct(wc);
+ case 10: return isspace(wc);
+ case 11: return isupper(wc);
+ case 12: return isxdigit(wc);
+ default: return 0;
+ }
+}
+#endif
+
+#ifndef HAVE_WCSCOLL
+int wcscoll(const wchar_t *ws1, const wchar_t *ws2)
+{
+ size_t i;
+
+ for (i = 0; ws1[i] != 0 && ws2[i] != 0; i++) {
+ if (ws1[i] < ws2[i])
+ return -1;
+ else if (ws1[i] > ws2[i])
+ return 1;
+ }
+
+ return (ws1[i] - ws2[i]);
+}
+#endif
+
+/*wcmisc.c*/
diff --git a/mkinstalldirs b/mkinstalldirs
index ef7e16fd..55d537f8 100755
--- a/mkinstalldirs
+++ b/mkinstalldirs
@@ -1,7 +1,7 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
-scriptversion=2006-05-11.19
+scriptversion=2009-04-28.21; # UTC
# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
@@ -81,9 +81,9 @@ case $dirmode in
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
else
- # On NextStep and OpenStep, the `mkdir' command does not
+ # 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
+ # directories to create, and then abort because '.' already
# exists.
test -d ./-p && rmdir ./-p
test -d ./--version && rmdir ./--version
@@ -157,5 +157,6 @@ exit $errstatus
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
# End:
diff --git a/mpfr.c b/mpfr.c
new file mode 100644
index 00000000..571b334b
--- /dev/null
+++ b/mpfr.c
@@ -0,0 +1,1783 @@
+/*
+ * mpfr.c - routines for arbitrary-precision number support in gawk.
+ */
+
+/*
+ * Copyright (C) 2012, 2013 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 3 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_MPFR
+
+#if !defined(MPFR_VERSION_MAJOR) || MPFR_VERSION_MAJOR < 3
+typedef mp_exp_t mpfr_exp_t;
+#endif
+
+extern NODE **fmt_list; /* declared in eval.c */
+
+mpz_t mpzval; /* GMP integer type, used as temporary in few places */
+mpz_t MNR;
+mpz_t MFNR;
+bool do_ieee_fmt; /* IEEE-754 floating-point emulation */
+mpfr_rnd_t ROUND_MODE;
+
+static mpfr_rnd_t get_rnd_mode(const char rmode);
+static NODE *mpg_force_number(NODE *n);
+static NODE *mpg_make_number(double);
+static NODE *mpg_format_val(const char *format, int index, NODE *s);
+static int mpg_interpret(INSTRUCTION **cp);
+
+static mpfr_exp_t min_exp = MPFR_EMIN_DEFAULT;
+static mpfr_exp_t max_exp = MPFR_EMAX_DEFAULT;
+
+/* temporary MPFR floats used to hold converted GMP integer operands */
+static mpfr_t _mpf_t1;
+static mpfr_t _mpf_t2;
+
+/*
+ * PRECISION_MIN is the precision used to initialize _mpf_t1 and _mpf_t2.
+ * 64 bits should be enough for exact conversion of most integers to floats.
+ */
+
+#define PRECISION_MIN 64
+
+/* mf = { _mpf_t1, _mpf_t2 } */
+static inline mpfr_ptr mpg_tofloat(mpfr_ptr mf, mpz_ptr mz);
+/* T = {t1, t2} */
+#define MP_FLOAT(T) is_mpg_integer(T) ? mpg_tofloat(_mpf_##T, (T)->mpg_i) : (T)->mpg_numbr
+
+
+/* init_mpfr --- set up MPFR related variables */
+
+void
+init_mpfr(mpfr_prec_t prec, const char *rmode)
+{
+ mpfr_set_default_prec(prec);
+ ROUND_MODE = get_rnd_mode(rmode[0]);
+ mpfr_set_default_rounding_mode(ROUND_MODE);
+ make_number = mpg_make_number;
+ str2number = mpg_force_number;
+ format_val = mpg_format_val;
+ cmp_numbers = mpg_cmp;
+
+ mpz_init(MNR);
+ mpz_init(MFNR);
+ do_ieee_fmt = false;
+
+ mpfr_init2(_mpf_t1, PRECISION_MIN);
+ mpfr_init2(_mpf_t2, PRECISION_MIN);
+ mpz_init(mpzval);
+
+ register_exec_hook(mpg_interpret, 0);
+}
+
+/* cleanup_mpfr --- clean stuff up, mainly for valgrind */
+
+void
+cleanup_mpfr(void)
+{
+ mpfr_clear(_mpf_t1);
+ mpfr_clear(_mpf_t2);
+}
+
+/* mpg_node --- allocate a node to store MPFR float or GMP integer */
+
+NODE *
+mpg_node(unsigned int tp)
+{
+ NODE *r;
+ getnode(r);
+ r->type = Node_val;
+
+ if (tp == MPFN) {
+ /* Initialize, set precision to the default precision, and value to NaN */
+ mpfr_init(r->mpg_numbr);
+ r->flags = MPFN;
+ } else {
+ /* Initialize and set value to 0 */
+ mpz_init(r->mpg_i);
+ r->flags = MPZN;
+ }
+
+ r->valref = 1;
+ r->flags |= MALLOC|NUMBER|NUMCUR;
+ r->stptr = NULL;
+ r->stlen = 0;
+ r->wstptr = NULL;
+ r->wstlen = 0;
+ return r;
+}
+
+/*
+ * mpg_make_number --- make a arbitrary-precision number node
+ * and initialize with a C double
+ */
+
+static NODE *
+mpg_make_number(double x)
+{
+ NODE *r;
+ double ival;
+
+ if ((ival = double_to_int(x)) != x) {
+ int tval;
+ r = mpg_float();
+ tval = mpfr_set_d(r->mpg_numbr, x, ROUND_MODE);
+ IEEE_FMT(r->mpg_numbr, tval);
+ } else {
+ r = mpg_integer();
+ mpz_set_d(r->mpg_i, ival);
+ }
+ return r;
+}
+
+/* mpg_strtoui --- assign arbitrary-precision integral value from a string */
+
+int
+mpg_strtoui(mpz_ptr zi, char *str, size_t len, char **end, int base)
+{
+ char *s = str;
+ char *start;
+ int ret = -1;
+
+ /*
+ * mpz_set_str does not like leading 0x or 0X for hex (or 0 for octal)
+ * with a non-zero base argument.
+ */
+ if (base == 16 && len >= 2 && *s == '0' && (s[1] == 'x' || s[1] == 'X')) {
+ s += 2; len -= 2;
+ } else if (base == 8 && len >= 1 && *s == '0') {
+ s++; len--;
+ }
+ start = s;
+
+ while (len > 0) {
+ switch (*s) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ break;
+ case '8':
+ case '9':
+ if (base == 8)
+ goto done;
+ break;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ if (base == 16)
+ break;
+ default:
+ goto done;
+ }
+ s++; len--;
+ }
+done:
+ if (s > start) {
+ char save = *s;
+ *s = '\0';
+ ret = mpz_set_str(zi, start, base);
+ *s = save;
+ }
+ if (end != NULL)
+ *end = s;
+ return ret;
+}
+
+
+/* mpg_maybe_float --- test if a string may contain arbitrary-precision float */
+
+static int
+mpg_maybe_float(const char *str, int use_locale)
+{
+ int dec_point = '.';
+ const char *s = str;
+
+#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 (strlen(s) >= 3
+ && ( ( (s[0] == 'i' || s[0] == 'I')
+ && (s[1] == 'n' || s[1] == 'N')
+ && (s[2] == 'f' || s[2] == 'F'))
+ || ( (s[0] == 'n' || s[0] == 'N')
+ && (s[1] == 'a' || s[1] == 'A')
+ && (s[2] == 'n' || s[2] == 'N'))))
+ return true;
+
+ for (; *s != '\0'; s++) {
+ if (*s == dec_point || *s == 'e' || *s == 'E')
+ return true;
+ }
+
+ return false;
+}
+
+
+/* mpg_zero --- initialize with arbitrary-precision integer(GMP) and set value to zero */
+
+static inline void
+mpg_zero(NODE *n)
+{
+ if (is_mpg_float(n)) {
+ mpfr_clear(n->mpg_numbr);
+ n->flags &= ~MPFN;
+ }
+ if (! is_mpg_integer(n)) {
+ mpz_init(n->mpg_i); /* this also sets its value to 0 */
+ n->flags |= MPZN;
+ } else
+ mpz_set_si(n->mpg_i, 0);
+}
+
+
+/* force_mpnum --- force a value to be a GMP integer or MPFR float */
+
+static int
+force_mpnum(NODE *n, int do_nondec, int use_locale)
+{
+ char *cp, *cpend, *ptr, *cp1;
+ char save;
+ int tval, base = 10;
+
+ if (n->stlen == 0) {
+ mpg_zero(n);
+ return false;
+ }
+
+ cp = n->stptr;
+ cpend = n->stptr + n->stlen;
+ while (cp < cpend && isspace((unsigned char) *cp))
+ cp++;
+ if (cp == cpend) { /* only spaces */
+ mpg_zero(n);
+ return false;
+ }
+
+ save = *cpend;
+ *cpend = '\0';
+
+ if (*cp == '+' || *cp == '-')
+ cp1 = cp + 1;
+ else
+ cp1 = cp;
+
+ if (do_nondec)
+ base = get_numbase(cp1, use_locale);
+
+ if (! mpg_maybe_float(cp1, use_locale)) {
+ mpg_zero(n);
+ errno = 0;
+ mpg_strtoui(n->mpg_i, cp1, cpend - cp1, & ptr, base);
+ if (*cp == '-')
+ mpz_neg(n->mpg_i, n->mpg_i);
+ goto done;
+ }
+
+ if (is_mpg_integer(n)) {
+ mpz_clear(n->mpg_i);
+ n->flags &= ~MPZN;
+ }
+
+ if (! is_mpg_float(n)) {
+ mpfr_init(n->mpg_numbr);
+ n->flags |= MPFN;
+ }
+
+ errno = 0;
+ tval = mpfr_strtofr(n->mpg_numbr, cp, & ptr, base, ROUND_MODE);
+ IEEE_FMT(n->mpg_numbr, tval);
+done:
+ /* trailing space is OK for NUMBER */
+ while (isspace((unsigned char) *ptr))
+ ptr++;
+ *cpend = save;
+ if (errno == 0 && ptr == cpend)
+ return true;
+ errno = 0;
+ return false;
+}
+
+/* mpg_force_number --- force a value to be a multiple-precision number */
+
+static NODE *
+mpg_force_number(NODE *n)
+{
+ unsigned int newflags = 0;
+
+ if (is_mpg_number(n) && (n->flags & NUMCUR) != 0)
+ return n;
+
+ if ((n->flags & MAYBE_NUM) != 0) {
+ n->flags &= ~MAYBE_NUM;
+ newflags = NUMBER;
+ }
+
+ if (force_mpnum(n, (do_non_decimal_data && ! do_traditional), true)) {
+ n->flags |= newflags;
+ n->flags |= NUMCUR;
+ }
+ return n;
+}
+
+/* mpg_format_val --- format a numeric value based on format */
+
+static NODE *
+mpg_format_val(const char *format, int index, NODE *s)
+{
+ NODE *dummy[2], *r;
+ unsigned int oflags;
+
+ /* create dummy node for a sole use of format_tree */
+ dummy[1] = s;
+ oflags = s->flags;
+
+ if (is_mpg_integer(s) || mpfr_integer_p(s->mpg_numbr)) {
+ /* integral value, use %d */
+ r = format_tree("%d", 2, dummy, 2);
+ s->stfmt = -1;
+ } else {
+ r = format_tree(format, fmt_list[index]->stlen, dummy, 2);
+ assert(r != NULL);
+ s->stfmt = (char) index;
+ }
+ s->flags = oflags;
+ s->stlen = r->stlen;
+ if ((s->flags & STRCUR) != 0)
+ efree(s->stptr);
+ s->stptr = r->stptr;
+ freenode(r); /* Do not unref(r)! We want to keep s->stptr == r->stpr. */
+
+ s->flags |= STRCUR;
+ free_wstr(s);
+ return s;
+}
+
+/* mpg_cmp --- compare two numbers */
+
+int
+mpg_cmp(const NODE *t1, const NODE *t2)
+{
+ /*
+ * For the purposes of sorting, NaN is considered greater than
+ * any other value, and all NaN values are considered equivalent and equal.
+ */
+
+ if (is_mpg_float(t1)) {
+ if (is_mpg_float(t2)) {
+ if (mpfr_nan_p(t1->mpg_numbr))
+ return ! mpfr_nan_p(t2->mpg_numbr);
+ if (mpfr_nan_p(t2->mpg_numbr))
+ return -1;
+ return mpfr_cmp(t1->mpg_numbr, t2->mpg_numbr);
+ }
+ if (mpfr_nan_p(t1->mpg_numbr))
+ return 1;
+ return mpfr_cmp_z(t1->mpg_numbr, t2->mpg_i);
+ } else if (is_mpg_float(t2)) {
+ int ret;
+ if (mpfr_nan_p(t2->mpg_numbr))
+ return -1;
+ ret = mpfr_cmp_z(t2->mpg_numbr, t1->mpg_i);
+ return ret > 0 ? -1 : (ret < 0);
+ } else if (is_mpg_integer(t1)) {
+ return mpz_cmp(t1->mpg_i, t2->mpg_i);
+ }
+
+ /* t1 and t2 are AWKNUMs */
+ return cmp_awknums(t1, t2);
+}
+
+
+/*
+ * mpg_update_var --- update NR or FNR.
+ * NR_node->var_value(mpz_t) = MNR(mpz_t) * LONG_MAX + NR(long)
+ */
+
+NODE *
+mpg_update_var(NODE *n)
+{
+ NODE *val = n->var_value;
+ long nr = 0;
+ mpz_ptr nq = 0;
+
+ if (n == NR_node) {
+ nr = NR;
+ nq = MNR;
+ } else if (n == FNR_node) {
+ nr = FNR;
+ nq = MFNR;
+ } else
+ cant_happen();
+
+ if (mpz_sgn(nq) == 0) {
+ /* Efficiency hack similar to that for AWKNUM */
+ if (is_mpg_float(val) || mpz_get_si(val->mpg_i) != nr) {
+ unref(n->var_value);
+ val = n->var_value = mpg_integer();
+ mpz_set_si(val->mpg_i, nr);
+ }
+ } else {
+ unref(n->var_value);
+ val = n->var_value = mpg_integer();
+ mpz_set_si(val->mpg_i, nr);
+ mpz_addmul_ui(val->mpg_i, nq, LONG_MAX); /* val->mpg_i += nq * LONG_MAX */
+ }
+ return val;
+}
+
+/* mpg_set_var --- set NR or FNR */
+
+long
+mpg_set_var(NODE *n)
+{
+ long nr = 0;
+ mpz_ptr nq = 0, r;
+ NODE *val = n->var_value;
+
+ if (n == NR_node)
+ nq = MNR;
+ else if (n == FNR_node)
+ nq = MFNR;
+ else
+ cant_happen();
+
+ if (is_mpg_integer(val))
+ r = val->mpg_i;
+ else {
+ /* convert float to integer */
+ mpfr_get_z(mpzval, val->mpg_numbr, MPFR_RNDZ);
+ r = mpzval;
+ }
+ nr = mpz_fdiv_q_ui(nq, r, LONG_MAX); /* nq (MNR or MFNR) is quotient */
+ return nr; /* remainder (NR or FNR) */
+}
+
+/* set_PREC --- update MPFR PRECISION related variables when PREC assigned to */
+
+void
+set_PREC()
+{
+ long prec = 0;
+ NODE *val;
+ static const struct ieee_fmt {
+ const char *name;
+ mpfr_prec_t precision;
+ mpfr_exp_t emax;
+ mpfr_exp_t emin;
+ } ieee_fmts[] = {
+{ "half", 11, 16, -23 }, /* binary16 */
+{ "single", 24, 128, -148 }, /* binary32 */
+{ "double", 53, 1024, -1073 }, /* binary64 */
+{ "quad", 113, 16384, -16493 }, /* binary128 */
+{ "oct", 237, 262144, -262377 }, /* binary256, not in the IEEE 754-2008 standard */
+
+ /*
+ * For any bitwidth = 32 * k ( k >= 4),
+ * precision = 13 + bitwidth - int(4 * log2(bitwidth))
+ * emax = 1 << bitwidth - precision - 1
+ * emin = 4 - emax - precision
+ */
+ };
+
+ if (! do_mpfr)
+ return;
+
+ val = PREC_node->var_value;
+ if ((val->flags & MAYBE_NUM) != 0)
+ force_number(val);
+
+ if ((val->flags & (STRING|NUMBER)) == STRING) {
+ int i, j;
+
+ /* emulate IEEE-754 binary format */
+
+ for (i = 0, j = sizeof(ieee_fmts)/sizeof(ieee_fmts[0]); i < j; i++) {
+ if (strcasecmp(ieee_fmts[i].name, val->stptr) == 0)
+ break;
+ }
+
+ if (i < j) {
+ prec = ieee_fmts[i].precision;
+
+ /*
+ * We *DO NOT* change the MPFR exponent range using
+ * mpfr_set_{emin, emax} here. See format_ieee() for details.
+ */
+ max_exp = ieee_fmts[i].emax;
+ min_exp = ieee_fmts[i].emin;
+
+ do_ieee_fmt = true;
+ }
+ }
+
+ if (prec <= 0) {
+ force_number(val);
+ prec = get_number_si(val);
+ if (prec < MPFR_PREC_MIN || prec > MPFR_PREC_MAX) {
+ force_string(val);
+ warning(_("PREC value `%.*s' is invalid"), (int) val->stlen, val->stptr);
+ prec = 0;
+ } else
+ do_ieee_fmt = false;
+ }
+
+ if (prec > 0)
+ mpfr_set_default_prec(prec);
+}
+
+
+/* get_rnd_mode --- convert string to MPFR rounding mode */
+
+static mpfr_rnd_t
+get_rnd_mode(const char rmode)
+{
+ switch (rmode) {
+ case 'N':
+ case 'n':
+ return MPFR_RNDN; /* round to nearest (IEEE-754 roundTiesToEven) */
+ case 'Z':
+ case 'z':
+ return MPFR_RNDZ; /* round toward zero (IEEE-754 roundTowardZero) */
+ case 'U':
+ case 'u':
+ return MPFR_RNDU; /* round toward plus infinity (IEEE-754 roundTowardPositive) */
+ case 'D':
+ case 'd':
+ return MPFR_RNDD; /* round toward minus infinity (IEEE-754 roundTowardNegative) */
+#if defined(MPFR_VERSION_MAJOR) && MPFR_VERSION_MAJOR > 2
+ case 'A':
+ case 'a':
+ return MPFR_RNDA; /* round away from zero (IEEE-754 roundTiesToAway) */
+#endif
+ default:
+ break;
+ }
+ return -1;
+}
+
+/*
+ * set_ROUNDMODE --- update MPFR rounding mode related variables
+ * when ROUNDMODE assigned to
+ */
+
+void
+set_ROUNDMODE()
+{
+ if (do_mpfr) {
+ mpfr_rnd_t rndm = -1;
+ NODE *n;
+ n = force_string(ROUNDMODE_node->var_value);
+ if (n->stlen == 1)
+ rndm = get_rnd_mode(n->stptr[0]);
+ if (rndm != -1) {
+ mpfr_set_default_rounding_mode(rndm);
+ ROUND_MODE = rndm;
+ } else
+ warning(_("RNDMODE value `%.*s' is invalid"), (int) n->stlen, n->stptr);
+ }
+}
+
+
+/* format_ieee --- make sure a number follows IEEE-754 floating-point standard */
+
+int
+format_ieee(mpfr_ptr x, int tval)
+{
+ /*
+ * The MPFR doc says that it's our responsibility to make sure all numbers
+ * including those previously created are in range after we've changed the
+ * exponent range. Most MPFR operations and functions require
+ * the input arguments to have exponents within the current exponent range.
+ * Any argument outside the range results in a MPFR assertion failure
+ * like this:
+ *
+ * $ gawk -M 'BEGIN { x=1.0e-10000; print x+0; PREC="double"; print x+0}'
+ * 1e-10000
+ * init2.c:52: MPFR assertion failed ....
+ *
+ * A "naive" approach would be to keep track of the ternary state and
+ * the rounding mode for each number, and make sure it is in the current
+ * exponent range (using mpfr_check_range) before using it in an
+ * operation or function. Instead, we adopt the following strategy.
+ *
+ * When gawk starts, the exponent range is the MPFR default
+ * [MPFR_EMIN_DEFAULT, MPFR_EMAX_DEFAULT]. Any number that gawk
+ * creates must have exponent in this range (excluding infinities, NaNs and zeros).
+ * Each MPFR operation or function is performed with this default exponent
+ * range.
+ *
+ * When emulating IEEE-754 format, the exponents are *temporarily* changed,
+ * mpfr_check_range is called to make sure the number is in the new range,
+ * and mpfr_subnormalize is used to round following the rules of subnormal
+ * arithmetic. The exponent range is then *restored* to the original value
+ * [MPFR_EMIN_DEFAULT, MPFR_EMAX_DEFAULT].
+ */
+
+ (void) mpfr_set_emin(min_exp);
+ (void) mpfr_set_emax(max_exp);
+ tval = mpfr_check_range(x, tval, ROUND_MODE);
+ tval = mpfr_subnormalize(x, tval, ROUND_MODE);
+ (void) mpfr_set_emin(MPFR_EMIN_DEFAULT);
+ (void) mpfr_set_emax(MPFR_EMAX_DEFAULT);
+ return tval;
+}
+
+
+/* do_mpfr_atan2 --- do the atan2 function */
+
+NODE *
+do_mpfr_atan2(int nargs)
+{
+ NODE *t1, *t2, *res;
+ mpfr_ptr p1, p2;
+ int tval;
+
+ t2 = POP_SCALAR();
+ t1 = POP_SCALAR();
+
+ 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"));
+ }
+ force_number(t1);
+ force_number(t2);
+
+ p1 = MP_FLOAT(t1);
+ p2 = MP_FLOAT(t2);
+ res = mpg_float();
+ /* See MPFR documentation for handling of special values like +inf as an argument */
+ tval = mpfr_atan2(res->mpg_numbr, p1, p2, ROUND_MODE);
+ IEEE_FMT(res->mpg_numbr, tval);
+
+ DEREF(t1);
+ DEREF(t2);
+ return res;
+}
+
+/* do_mpfr_func --- run an MPFR function - not inline, for debugging */
+
+static inline NODE *
+do_mpfr_func(const char *name,
+ int (*mpfr_func)(), /* putting argument types just gets the compiler confused */
+ int nargs)
+{
+ NODE *t1, *res;
+ mpfr_ptr p1;
+ int tval;
+
+ t1 = POP_SCALAR();
+ if (do_lint && (t1->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("%s: received non-numeric argument"), name);
+
+ force_number(t1);
+ p1 = MP_FLOAT(t1);
+ res = mpg_float();
+ mpfr_set_prec(res->mpg_numbr, mpfr_get_prec(p1)); /* needed at least for sqrt() */
+ tval = mpfr_func(res->mpg_numbr, p1, ROUND_MODE);
+ IEEE_FMT(res->mpg_numbr, tval);
+ DEREF(t1);
+ return res;
+}
+
+#define SPEC_MATH(X) \
+NODE *result; \
+result = do_mpfr_func(#X, mpfr_##X, nargs); \
+return result
+
+/* do_mpfr_sin --- do the sin function */
+
+NODE *
+do_mpfr_sin(int nargs)
+{
+ SPEC_MATH(sin);
+}
+
+/* do_mpfr_cos --- do the cos function */
+
+NODE *
+do_mpfr_cos(int nargs)
+{
+ SPEC_MATH(cos);
+}
+
+/* do_mpfr_exp --- exponential function */
+
+NODE *
+do_mpfr_exp(int nargs)
+{
+ SPEC_MATH(exp);
+}
+
+/* do_mpfr_log --- the log function */
+
+NODE *
+do_mpfr_log(int nargs)
+{
+ SPEC_MATH(log);
+}
+
+/* do_mpfr_sqrt --- do the sqrt function */
+
+NODE *
+do_mpfr_sqrt(int nargs)
+{
+ SPEC_MATH(sqrt);
+}
+
+/* do_mpfr_int --- convert double to int for awk */
+
+NODE *
+do_mpfr_int(int nargs)
+{
+ NODE *tmp, *r;
+
+ tmp = POP_SCALAR();
+ if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("int: received non-numeric argument"));
+ force_number(tmp);
+
+ if (is_mpg_integer(tmp)) {
+ r = mpg_integer();
+ mpz_set(r->mpg_i, tmp->mpg_i);
+ } else {
+ if (! mpfr_number_p(tmp->mpg_numbr)) {
+ /* [+-]inf or NaN */
+ return tmp;
+ }
+
+ r = mpg_integer();
+ mpfr_get_z(r->mpg_i, tmp->mpg_numbr, MPFR_RNDZ);
+ }
+
+ DEREF(tmp);
+ return r;
+}
+
+/* do_mpfr_compl --- perform a ~ operation */
+
+NODE *
+do_mpfr_compl(int nargs)
+{
+ NODE *tmp, *r;
+ mpz_ptr zptr;
+
+ tmp = POP_SCALAR();
+ if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("compl: received non-numeric argument"));
+
+ force_number(tmp);
+ if (is_mpg_float(tmp)) {
+ mpfr_ptr p = tmp->mpg_numbr;
+
+ if (! mpfr_number_p(p)) {
+ /* [+-]inf or NaN */
+ return tmp;
+ }
+ if (do_lint) {
+ if (mpfr_sgn(p) < 0)
+ lintwarn("%s",
+ mpg_fmt(_("compl(%Rg): negative value will give strange results"), p)
+ );
+ if (! mpfr_integer_p(p))
+ lintwarn("%s",
+ mpg_fmt(_("comp(%Rg): fractional value will be truncated"), p)
+ );
+ }
+
+ mpfr_get_z(mpzval, p, MPFR_RNDZ); /* float to integer conversion */
+ zptr = mpzval;
+ } else {
+ /* (tmp->flags & MPZN) != 0 */
+ zptr = tmp->mpg_i;
+ if (do_lint) {
+ if (mpz_sgn(zptr) < 0)
+ lintwarn("%s",
+ mpg_fmt(_("cmpl(%Zd): negative values will give strange results"), zptr)
+ );
+ }
+ }
+
+ r = mpg_integer();
+ mpz_com(r->mpg_i, zptr);
+ DEREF(tmp);
+ return r;
+}
+
+/* get_intval --- get the (converted) integral operand of a binary function. */
+
+static mpz_ptr
+get_intval(NODE *t1, int argnum, const char *op)
+{
+ mpz_ptr pz;
+
+ if (do_lint && (t1->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("%s: received non-numeric argument #%d"), op, argnum);
+
+ (void) force_number(t1);
+
+ if (is_mpg_float(t1)) {
+ mpfr_ptr left = t1->mpg_numbr;
+ if (! mpfr_number_p(left)) {
+ /* inf or NaN */
+ if (do_lint)
+ lintwarn("%s",
+ mpg_fmt(_("%s: argument #%d has invalid value %Rg, using 0"),
+ op, argnum, left)
+ );
+
+ emalloc(pz, mpz_ptr, sizeof (mpz_t), "get_intval");
+ mpz_init(pz);
+ return pz; /* should be freed */
+ }
+
+ if (do_lint) {
+ if (mpfr_sgn(left) < 0)
+ lintwarn("%s",
+ mpg_fmt(_("%s: argument #%d negative value %Rg will give strange results"),
+ op, argnum, left)
+ );
+
+ if (! mpfr_integer_p(left))
+ lintwarn("%s",
+ mpg_fmt(_("%s: argument #%d fractional value %Rg will be truncated"),
+ op, argnum, left)
+ );
+ }
+
+ emalloc(pz, mpz_ptr, sizeof (mpz_t), "get_intval");
+ mpz_init(pz);
+ mpfr_get_z(pz, left, MPFR_RNDZ); /* float to integer conversion */
+ return pz; /* should be freed */
+ }
+ /* (t1->flags & MPZN) != 0 */
+ pz = t1->mpg_i;
+ if (do_lint) {
+ if (mpz_sgn(pz) < 0)
+ lintwarn("%s",
+ mpg_fmt(_("%s: argument #%d negative value %Zd will give strange results"),
+ op, argnum, pz)
+ );
+ }
+ return pz; /* must not be freed */
+}
+
+
+/* free_intval --- free the converted integer value returned by get_intval() */
+
+static inline void
+free_intval(NODE *t, mpz_ptr pz)
+{
+ if ((t->flags & MPZN) == 0) {
+ mpz_clear(pz);
+ efree(pz);
+ }
+}
+
+
+/* do_mpfr_lshift --- perform a << operation */
+
+NODE *
+do_mpfr_lshift(int nargs)
+{
+ NODE *t1, *t2, *res;
+ unsigned long shift;
+ mpz_ptr pz1, pz2;
+
+ t2 = POP_SCALAR();
+ t1 = POP_SCALAR();
+
+ pz1 = get_intval(t1, 1, "lshift");
+ pz2 = get_intval(t2, 2, "lshift");
+
+ /*
+ * mpz_get_ui: If op is too big to fit an unsigned long then just
+ * the least significant bits that do fit are returned.
+ * The sign of op is ignored, only the absolute value is used.
+ */
+
+ shift = mpz_get_ui(pz2); /* GMP integer => unsigned long conversion */
+ res = mpg_integer();
+ mpz_mul_2exp(res->mpg_i, pz1, shift); /* res = pz1 * 2^shift */
+
+ free_intval(t1, pz1);
+ free_intval(t2, pz2);
+ DEREF(t2);
+ DEREF(t1);
+ return res;
+}
+
+/* do_mpfr_rshift --- perform a >> operation */
+
+NODE *
+do_mpfr_rshift(int nargs)
+{
+ NODE *t1, *t2, *res;
+ unsigned long shift;
+ mpz_ptr pz1, pz2;
+
+ t2 = POP_SCALAR();
+ t1 = POP_SCALAR();
+
+ pz1 = get_intval(t1, 1, "rshift");
+ pz2 = get_intval(t2, 2, "rshift");
+
+ /* N.B: See do_mpfp_lshift. */
+ shift = mpz_get_ui(pz2); /* GMP integer => unsigned long conversion */
+ res = mpg_integer();
+ mpz_fdiv_q_2exp(res->mpg_i, pz1, shift); /* res = pz1 / 2^shift, round towards −inf */
+
+ free_intval(t1, pz1);
+ free_intval(t2, pz2);
+ DEREF(t2);
+ DEREF(t1);
+ return res;
+}
+
+
+/* do_mpfr_and --- perform an & operation */
+
+NODE *
+do_mpfr_and(int nargs)
+{
+ NODE *t1, *t2, *res;
+ mpz_ptr pz1, pz2;
+ int i;
+
+ if (nargs < 2)
+ fatal(_("and: called with less than two arguments"));
+
+ t2 = POP_SCALAR();
+ pz2 = get_intval(t2, nargs, "and");
+
+ res = mpg_integer();
+ for (i = 1; i < nargs; i++) {
+ t1 = POP_SCALAR();
+ pz1 = get_intval(t1, nargs - i, "and");
+ mpz_and(res->mpg_i, pz1, pz2);
+ free_intval(t1, pz1);
+ DEREF(t1);
+ if (i == 1) {
+ free_intval(t2, pz2);
+ DEREF(t2);
+ }
+ pz2 = res->mpg_i;
+ }
+ return res;
+}
+
+
+/* do_mpfr_or --- perform an | operation */
+
+NODE *
+do_mpfr_or(int nargs)
+{
+ NODE *t1, *t2, *res;
+ mpz_ptr pz1, pz2;
+ int i;
+
+ if (nargs < 2)
+ fatal(_("or: called with less than two arguments"));
+
+ t2 = POP_SCALAR();
+ pz2 = get_intval(t2, nargs, "or");
+
+ res = mpg_integer();
+ for (i = 1; i < nargs; i++) {
+ t1 = POP_SCALAR();
+ pz1 = get_intval(t1, nargs - i, "or");
+ mpz_ior(res->mpg_i, pz1, pz2);
+ free_intval(t1, pz1);
+ DEREF(t1);
+ if (i == 1) {
+ free_intval(t2, pz2);
+ DEREF(t2);
+ }
+ pz2 = res->mpg_i;
+ }
+ return res;
+}
+
+/* do_mpfr_xor --- perform an ^ operation */
+
+NODE *
+do_mpfr_xor(int nargs)
+{
+ NODE *t1, *t2, *res;
+ mpz_ptr pz1, pz2;
+ int i;
+
+ if (nargs < 2)
+ fatal(_("xor: called with less than two arguments"));
+
+ t2 = POP_SCALAR();
+ pz2 = get_intval(t2, nargs, "xor");
+
+ res = mpg_integer();
+ for (i = 1; i < nargs; i++) {
+ t1 = POP_SCALAR();
+ pz1 = get_intval(t1, nargs - i, "xor");
+ mpz_xor(res->mpg_i, pz1, pz2);
+ free_intval(t1, pz1);
+ DEREF(t1);
+ if (i == 1) {
+ free_intval(t2, pz2);
+ DEREF(t2);
+ }
+ pz2 = res->mpg_i;
+ }
+ return res;
+}
+
+/* do_mpfr_strtonum --- the strtonum function */
+
+NODE *
+do_mpfr_strtonum(int nargs)
+{
+ NODE *tmp, *r;
+
+ tmp = POP_SCALAR();
+ if ((tmp->flags & (NUMBER|NUMCUR)) == 0) {
+ r = mpg_integer(); /* will be changed to MPFR float if necessary in force_mpnum() */
+ r->stptr = tmp->stptr;
+ r->stlen = tmp->stlen;
+ force_mpnum(r, true, use_lc_numeric);
+ r->stptr = NULL;
+ r->stlen = 0;
+ } else {
+ (void) force_number(tmp);
+ if (is_mpg_float(tmp)) {
+ int tval;
+ r = mpg_float();
+ tval = mpfr_set(r->mpg_numbr, tmp->mpg_numbr, ROUND_MODE);
+ IEEE_FMT(r->mpg_numbr, tval);
+ } else {
+ r = mpg_integer();
+ mpz_set(r->mpg_i, tmp->mpg_i);
+ }
+ }
+
+ DEREF(tmp);
+ return r;
+}
+
+
+static bool firstrand = true;
+static gmp_randstate_t state;
+static mpz_t seed; /* current seed */
+
+/* do_mpfr_rand --- do the rand function */
+
+NODE *
+do_mpfr_rand(int nargs ATTRIBUTE_UNUSED)
+{
+ NODE *res;
+ int tval;
+
+ if (firstrand) {
+#if 0
+ /* Choose the default algorithm */
+ gmp_randinit_default(state);
+#endif
+ /*
+ * Choose a specific (Mersenne Twister) algorithm in case the default
+ * changes in the future.
+ */
+
+ gmp_randinit_mt(state);
+
+ mpz_init(seed);
+ mpz_set_ui(seed, 1);
+ /* seed state */
+ gmp_randseed(state, seed);
+ firstrand = false;
+ }
+ res = mpg_float();
+ tval = mpfr_urandomb(res->mpg_numbr, state);
+ IEEE_FMT(res->mpg_numbr, tval);
+ return res;
+}
+
+
+/* do_mpfr_srand --- seed the random number generator */
+
+NODE *
+do_mpfr_srand(int nargs)
+{
+ NODE *res;
+
+ if (firstrand) {
+#if 0
+ /* Choose the default algorithm */
+ gmp_randinit_default(state);
+#endif
+ /*
+ * Choose a specific algorithm (Mersenne Twister) in case default
+ * changes in the future.
+ */
+
+ gmp_randinit_mt(state);
+
+ mpz_init(seed);
+ mpz_set_ui(seed, 1);
+ /* No need to seed state, will change it below */
+ firstrand = false;
+ }
+
+ res = mpg_integer();
+ mpz_set(res->mpg_i, seed); /* previous seed */
+
+ if (nargs == 0)
+ mpz_set_ui(seed, (unsigned long) time((time_t *) 0));
+ else {
+ NODE *tmp;
+ tmp = POP_SCALAR();
+ if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("srand: received non-numeric argument"));
+ force_number(tmp);
+ if (is_mpg_float(tmp))
+ mpfr_get_z(seed, tmp->mpg_numbr, MPFR_RNDZ);
+ else /* MP integer */
+ mpz_set(seed, tmp->mpg_i);
+ DEREF(tmp);
+ }
+
+ gmp_randseed(state, seed);
+ return res;
+}
+
+/* do_mpfr_div --- do integer division, return quotient and remainder in dest array */
+
+/*
+ * We define the semantics as:
+ * numerator = int(numerator)
+ * denominator = int(denonmator)
+ * quotient = int(numerator / denomator)
+ * remainder = int(numerator % denomator)
+ */
+
+NODE *
+do_mpfr_div(int nargs)
+{
+ NODE *numerator, *denominator, *result;
+ NODE *num, *denom;
+ NODE *quotient, *remainder;
+ NODE *sub, **lhs;
+
+ result = POP_PARAM();
+ if (result->type != Node_var_array)
+ fatal(_("div: third argument is not an array"));
+ assoc_clear(result);
+
+ denominator = POP_SCALAR();
+ numerator = POP_SCALAR();
+
+ if (do_lint) {
+ if ((numerator->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("div: received non-numeric first argument"));
+ if ((denominator->flags & (NUMCUR|NUMBER)) == 0)
+ lintwarn(_("div: received non-numeric second argument"));
+ }
+
+ (void) force_number(numerator);
+ (void) force_number(denominator);
+
+ /* convert numerator and denominator to integer */
+ if (is_mpg_integer(numerator)) {
+ num = mpg_integer();
+ mpz_set(num->mpg_i, numerator->mpg_i);
+ } else {
+ if (! mpfr_number_p(numerator->mpg_numbr)) {
+ /* [+-]inf or NaN */
+ return numerator;
+ }
+
+ num = mpg_integer();
+ mpfr_get_z(num->mpg_i, numerator->mpg_numbr, MPFR_RNDZ);
+ }
+
+ if (is_mpg_integer(denominator)) {
+ denom = mpg_integer();
+ mpz_set(denom->mpg_i, denominator->mpg_i);
+ } else {
+ if (! mpfr_number_p(denominator->mpg_numbr)) {
+ /* [+-]inf or NaN */
+ return denominator;
+ }
+
+ denom = mpg_integer();
+ mpfr_get_z(denom->mpg_i, denominator->mpg_numbr, MPFR_RNDZ);
+ }
+
+ if (mpz_sgn(denom->mpg_i) == 0)
+ fatal(_("div: division by zero attempted"));
+
+ quotient = mpg_integer();
+ remainder = mpg_integer();
+
+ /* do the division */
+ mpz_tdiv_qr(quotient->mpg_i, remainder->mpg_i, num->mpg_i, denom->mpg_i);
+ unref(num);
+ unref(denom);
+ unref(numerator);
+ unref(denominator);
+
+ sub = make_string("quotient", 8);
+ lhs = assoc_lookup(result, sub);
+ unref(*lhs);
+ *lhs = quotient;
+
+ sub = make_string("remainder", 9);
+ lhs = assoc_lookup(result, sub);
+ unref(*lhs);
+ *lhs = remainder;
+
+ return make_number((AWKNUM) 0.0);
+}
+
+/*
+ * mpg_tofloat --- convert an arbitrary-precision integer operand to
+ * a float without loss of precision. It is assumed that the
+ * MPFR variable has already been initialized.
+ */
+
+static inline mpfr_ptr
+mpg_tofloat(mpfr_ptr mf, mpz_ptr mz)
+{
+ size_t prec;
+
+ /*
+ * When implicitely converting a GMP integer operand to a MPFR float, use
+ * a precision sufficiently large to hold the converted value exactly.
+ *
+ * $ ./gawk -M 'BEGIN { print 13 % 2 }'
+ * 1
+ * If the user-specified precision is used to convert the integer 13 to a
+ * float, one will get:
+ * $ ./gawk -M 'BEGIN { PREC=2; print 13 % 2.0 }'
+ * 0
+ */
+
+ prec = mpz_sizeinbase(mz, 2); /* most significant 1 bit position starting at 1 */
+ if (prec > PRECISION_MIN) {
+ prec -= (size_t) mpz_scan1(mz, 0); /* least significant 1 bit index starting at 0 */
+ if (prec > MPFR_PREC_MAX)
+ prec = MPFR_PREC_MAX;
+ if (prec > PRECISION_MIN)
+ mpfr_set_prec(mf, prec);
+ }
+
+ mpfr_set_z(mf, mz, ROUND_MODE);
+ return mf;
+}
+
+
+/* mpg_add --- add arbitrary-precision numbers */
+
+static NODE *
+mpg_add(NODE *t1, NODE *t2)
+{
+ NODE *r;
+ int tval;
+
+ if (is_mpg_integer(t1) && is_mpg_integer(t2)) {
+ r = mpg_integer();
+ mpz_add(r->mpg_i, t1->mpg_i, t2->mpg_i);
+ } else {
+ r = mpg_float();
+ if (is_mpg_integer(t2))
+ tval = mpfr_add_z(r->mpg_numbr, t1->mpg_numbr, t2->mpg_i, ROUND_MODE);
+ else if (is_mpg_integer(t1))
+ tval = mpfr_add_z(r->mpg_numbr, t2->mpg_numbr, t1->mpg_i, ROUND_MODE);
+ else
+ tval = mpfr_add(r->mpg_numbr, t1->mpg_numbr, t2->mpg_numbr, ROUND_MODE);
+ IEEE_FMT(r->mpg_numbr, tval);
+ }
+ return r;
+}
+
+/* mpg_sub --- subtract arbitrary-precision numbers */
+
+static NODE *
+mpg_sub(NODE *t1, NODE *t2)
+{
+ NODE *r;
+ int tval;
+
+ if (is_mpg_integer(t1) && is_mpg_integer(t2)) {
+ r = mpg_integer();
+ mpz_sub(r->mpg_i, t1->mpg_i, t2->mpg_i);
+ } else {
+ r = mpg_float();
+ if (is_mpg_integer(t2))
+ tval = mpfr_sub_z(r->mpg_numbr, t1->mpg_numbr, t2->mpg_i, ROUND_MODE);
+ else if (is_mpg_integer(t1)) {
+#if (!defined(MPFR_VERSION) || (MPFR_VERSION < MPFR_VERSION_NUM(3,1,0)))
+ NODE *tmp = t1;
+ t1 = t2;
+ t2 = tmp;
+ tval = mpfr_sub_z(r->mpg_numbr, t1->mpg_numbr, t2->mpg_i, ROUND_MODE);
+ tval = mpfr_neg(r->mpg_numbr, r->mpg_numbr, ROUND_MODE);
+ t2 = t1;
+ t1 = tmp;
+#else
+ tval = mpfr_z_sub(r->mpg_numbr, t1->mpg_i, t2->mpg_numbr, ROUND_MODE);
+#endif
+ } else
+ tval = mpfr_sub(r->mpg_numbr, t1->mpg_numbr, t2->mpg_numbr, ROUND_MODE);
+ IEEE_FMT(r->mpg_numbr, tval);
+ }
+ return r;
+}
+
+/* mpg_mul --- multiply arbitrary-precision numbers */
+
+static NODE *
+mpg_mul(NODE *t1, NODE *t2)
+{
+ NODE *r;
+ int tval;
+
+ if (is_mpg_integer(t1) && is_mpg_integer(t2)) {
+ r = mpg_integer();
+ mpz_mul(r->mpg_i, t1->mpg_i, t2->mpg_i);
+ } else {
+ r = mpg_float();
+ if (is_mpg_integer(t2))
+ tval = mpfr_mul_z(r->mpg_numbr, t1->mpg_numbr, t2->mpg_i, ROUND_MODE);
+ else if (is_mpg_integer(t1))
+ tval = mpfr_mul_z(r->mpg_numbr, t2->mpg_numbr, t1->mpg_i, ROUND_MODE);
+ else
+ tval = mpfr_mul(r->mpg_numbr, t1->mpg_numbr, t2->mpg_numbr, ROUND_MODE);
+ IEEE_FMT(r->mpg_numbr, tval);
+ }
+ return r;
+}
+
+
+/* mpg_pow --- exponentiation involving arbitrary-precision numbers */
+
+static NODE *
+mpg_pow(NODE *t1, NODE *t2)
+{
+ NODE *r;
+ int tval;
+
+ if (is_mpg_integer(t1) && is_mpg_integer(t2)) {
+ if (mpz_sgn(t2->mpg_i) >= 0 && mpz_fits_ulong_p(t2->mpg_i)) {
+ r = mpg_integer();
+ mpz_pow_ui(r->mpg_i, t1->mpg_i, mpz_get_ui(t2->mpg_i));
+ } else {
+ mpfr_ptr p1, p2;
+ p1 = MP_FLOAT(t1);
+ p2 = MP_FLOAT(t2);
+ r = mpg_float();
+ tval = mpfr_pow(r->mpg_numbr, p1, p2, ROUND_MODE);
+ IEEE_FMT(r->mpg_numbr, tval);
+ }
+ } else {
+ r = mpg_float();
+ if (is_mpg_integer(t2))
+ tval = mpfr_pow_z(r->mpg_numbr, t1->mpg_numbr, t2->mpg_i, ROUND_MODE);
+ else {
+ mpfr_ptr p1;
+ p1 = MP_FLOAT(t1);
+ tval = mpfr_pow(r->mpg_numbr, p1, t2->mpg_numbr, ROUND_MODE);
+ }
+ IEEE_FMT(r->mpg_numbr, tval);
+ }
+ return r;
+}
+
+/* mpg_div --- arbitrary-precision division */
+
+static NODE *
+mpg_div(NODE *t1, NODE *t2)
+{
+ NODE *r;
+ int tval;
+
+ if (is_mpg_integer(t1) && is_mpg_integer(t2)
+ && (mpz_sgn(t2->mpg_i) != 0) /* not dividing by 0 */
+ && mpz_divisible_p(t1->mpg_i, t2->mpg_i)
+ ) {
+ r = mpg_integer();
+ mpz_divexact(r->mpg_i, t1->mpg_i, t2->mpg_i);
+ } else {
+ mpfr_ptr p1, p2;
+ p1 = MP_FLOAT(t1);
+ p2 = MP_FLOAT(t2);
+ r = mpg_float();
+ tval = mpfr_div(r->mpg_numbr, p1, p2, ROUND_MODE);
+ IEEE_FMT(r->mpg_numbr, tval);
+ }
+ return r;
+}
+
+/* mpg_mod --- modulus operation with arbitrary-precision numbers */
+
+static NODE *
+mpg_mod(NODE *t1, NODE *t2)
+{
+ NODE *r;
+ int tval;
+
+ if (is_mpg_integer(t1) && is_mpg_integer(t2)) {
+ /*
+ * 8/2014: Originally, this was just
+ *
+ * r = mpg_integer();
+ * mpz_mod(r->mpg_i, t1->mpg_i, t2->mpg_i);
+ *
+ * But that gave very strange results with negative numerator:
+ *
+ * $ ./gawk -M 'BEGIN { print -15 % 7 }'
+ * 6
+ *
+ * So instead we use mpz_tdiv_qr() to get the correct result
+ * and just throw away the quotient. We could not find any
+ * reason why mpz_mod() wasn't working correctly.
+ */
+ NODE *dummy_quotient;
+
+ r = mpg_integer();
+ dummy_quotient = mpg_integer();
+ mpz_tdiv_qr(dummy_quotient->mpg_i, r->mpg_i, t1->mpg_i, t2->mpg_i);
+ unref(dummy_quotient);
+ } else {
+ mpfr_ptr p1, p2;
+ p1 = MP_FLOAT(t1);
+ p2 = MP_FLOAT(t2);
+ r = mpg_float();
+ tval = mpfr_fmod(r->mpg_numbr, p1, p2, ROUND_MODE);
+ IEEE_FMT(r->mpg_numbr, tval);
+ }
+ return r;
+}
+
+/*
+ * mpg_interpret --- pre-exec hook in the interpreter. Handles
+ * arithmetic operations with MPFR/GMP numbers.
+ */
+
+static int
+mpg_interpret(INSTRUCTION **cp)
+{
+ INSTRUCTION *pc = *cp; /* current instruction */
+ OPCODE op; /* current opcode */
+ NODE *r = NULL;
+ NODE *t1, *t2;
+ NODE **lhs;
+ int tval; /* the ternary value returned by a MPFR function */
+
+ switch ((op = pc->opcode)) {
+ case Op_plus_i:
+ t2 = force_number(pc->memory);
+ goto plus;
+ case Op_plus:
+ t2 = POP_NUMBER();
+plus:
+ t1 = TOP_NUMBER();
+ r = mpg_add(t1, t2);
+ DEREF(t1);
+ if (op == Op_plus)
+ DEREF(t2);
+ REPLACE(r);
+ break;
+
+ case Op_minus_i:
+ t2 = force_number(pc->memory);
+ goto minus;
+ case Op_minus:
+ t2 = POP_NUMBER();
+minus:
+ t1 = TOP_NUMBER();
+ r = mpg_sub(t1, t2);
+ DEREF(t1);
+ if (op == Op_minus)
+ DEREF(t2);
+ REPLACE(r);
+ break;
+
+ case Op_times_i:
+ t2 = force_number(pc->memory);
+ goto times;
+ case Op_times:
+ t2 = POP_NUMBER();
+times:
+ t1 = TOP_NUMBER();
+ r = mpg_mul(t1, t2);
+ DEREF(t1);
+ if (op == Op_times)
+ DEREF(t2);
+ REPLACE(r);
+ break;
+
+ case Op_exp_i:
+ t2 = force_number(pc->memory);
+ goto exp;
+ case Op_exp:
+ t2 = POP_NUMBER();
+exp:
+ t1 = TOP_NUMBER();
+ r = mpg_pow(t1, t2);
+ DEREF(t1);
+ if (op == Op_exp)
+ DEREF(t2);
+ REPLACE(r);
+ break;
+
+ case Op_quotient_i:
+ t2 = force_number(pc->memory);
+ goto quotient;
+ case Op_quotient:
+ t2 = POP_NUMBER();
+quotient:
+ t1 = TOP_NUMBER();
+ r = mpg_div(t1, t2);
+ DEREF(t1);
+ if (op == Op_quotient)
+ DEREF(t2);
+ REPLACE(r);
+ break;
+
+ case Op_mod_i:
+ t2 = force_number(pc->memory);
+ goto mod;
+ case Op_mod:
+ t2 = POP_NUMBER();
+mod:
+ t1 = TOP_NUMBER();
+ r = mpg_mod(t1, t2);
+ DEREF(t1);
+ if (op == Op_mod)
+ DEREF(t2);
+ REPLACE(r);
+ break;
+
+ case Op_preincrement:
+ case Op_predecrement:
+ lhs = TOP_ADDRESS();
+ t1 = *lhs;
+ force_number(t1);
+
+ if (is_mpg_integer(t1)) {
+ if (t1->valref == 1 && t1->flags == (MALLOC|MPZN|NUMCUR|NUMBER))
+ /* Efficiency hack. Big speed-up (> 30%) in a tight loop */
+ r = t1;
+ else
+ r = *lhs = mpg_integer();
+ if (op == Op_preincrement)
+ mpz_add_ui(r->mpg_i, t1->mpg_i, 1);
+ else
+ mpz_sub_ui(r->mpg_i, t1->mpg_i, 1);
+ } else {
+
+ /*
+ * An optimization like the one above is not going to work
+ * for a floating-point number. With it,
+ * gawk -M 'BEGIN { PREC=53; i=2^53+0.0; PREC=113; ++i; print i}'
+ * will output 2^53 instead of 2^53+1.
+ */
+
+ r = *lhs = mpg_float();
+ tval = mpfr_add_si(r->mpg_numbr, t1->mpg_numbr,
+ op == Op_preincrement ? 1 : -1,
+ ROUND_MODE);
+ IEEE_FMT(r->mpg_numbr, tval);
+ }
+ if (r != t1)
+ unref(t1);
+ UPREF(r);
+ REPLACE(r);
+ break;
+
+ case Op_postincrement:
+ case Op_postdecrement:
+ lhs = TOP_ADDRESS();
+ t1 = *lhs;
+ force_number(t1);
+
+ if (is_mpg_integer(t1)) {
+ r = mpg_integer();
+ mpz_set(r->mpg_i, t1->mpg_i);
+ if (t1->valref == 1 && t1->flags == (MALLOC|MPZN|NUMCUR|NUMBER))
+ /* Efficiency hack. Big speed-up (> 30%) in a tight loop */
+ t2 = t1;
+ else
+ t2 = *lhs = mpg_integer();
+ if (op == Op_postincrement)
+ mpz_add_ui(t2->mpg_i, t1->mpg_i, 1);
+ else
+ mpz_sub_ui(t2->mpg_i, t1->mpg_i, 1);
+ } else {
+ r = mpg_float();
+ tval = mpfr_set(r->mpg_numbr, t1->mpg_numbr, ROUND_MODE);
+ IEEE_FMT(r->mpg_numbr, tval);
+ t2 = *lhs = mpg_float();
+ tval = mpfr_add_si(t2->mpg_numbr, t1->mpg_numbr,
+ op == Op_postincrement ? 1 : -1,
+ ROUND_MODE);
+ IEEE_FMT(t2->mpg_numbr, tval);
+ }
+ if (t2 != t1)
+ unref(t1);
+ REPLACE(r);
+ break;
+
+ case Op_unary_minus:
+ t1 = TOP_NUMBER();
+ if (is_mpg_float(t1)) {
+ r = mpg_float();
+ tval = mpfr_neg(r->mpg_numbr, t1->mpg_numbr, ROUND_MODE);
+ IEEE_FMT(r->mpg_numbr, tval);
+ } else {
+ r = mpg_integer();
+ mpz_neg(r->mpg_i, t1->mpg_i);
+ }
+ DEREF(t1);
+ REPLACE(r);
+ break;
+
+ case Op_assign_plus:
+ case Op_assign_minus:
+ case Op_assign_times:
+ case Op_assign_quotient:
+ case Op_assign_mod:
+ case Op_assign_exp:
+ lhs = POP_ADDRESS();
+ t1 = *lhs;
+ force_number(t1);
+ t2 = TOP_NUMBER();
+
+ switch (op) {
+ case Op_assign_plus:
+ r = mpg_add(t1, t2);
+ break;
+ case Op_assign_minus:
+ r = mpg_sub(t1, t2);
+ break;
+ case Op_assign_times:
+ r = mpg_mul(t1, t2);
+ break;
+ case Op_assign_quotient:
+ r = mpg_div(t1, t2);
+ break;
+ case Op_assign_mod:
+ r = mpg_mod(t1, t2);
+ break;
+ case Op_assign_exp:
+ r = mpg_pow(t1, t2);
+ break;
+ default:
+ cant_happen();
+ }
+
+ DEREF(t2);
+ unref(*lhs);
+ *lhs = r;
+ UPREF(r);
+ REPLACE(r);
+ break;
+
+ default:
+ return true; /* unhandled */
+ }
+
+ *cp = pc->nexti; /* next instruction to execute */
+ return false;
+}
+
+
+/* mpg_fmt --- output formatted string with special MPFR/GMP conversion specifiers */
+
+const char *
+mpg_fmt(const char *mesg, ...)
+{
+ static char *tmp = NULL;
+ int ret;
+ va_list args;
+
+ if (tmp != NULL) {
+ mpfr_free_str(tmp);
+ tmp = NULL;
+ }
+ va_start(args, mesg);
+ ret = mpfr_vasprintf(& tmp, mesg, args);
+ va_end(args);
+ if (ret >= 0 && tmp != NULL)
+ return tmp;
+ return mesg;
+}
+
+/* mpfr_unset --- clear out the MPFR values */
+
+void
+mpfr_unset(NODE *n)
+{
+ if (is_mpg_float(n))
+ mpfr_clear(n->mpg_numbr);
+ else if (is_mpg_integer(n))
+ mpz_clear(n->mpg_i);
+}
+
+#else
+
+void
+set_PREC()
+{
+ /* dummy function */
+}
+
+void
+set_ROUNDMODE()
+{
+ /* dummy function */
+}
+
+void
+mpfr_unset(NODE *n)
+{
+ /* dummy function */
+}
+#endif
diff --git a/msg.c b/msg.c
index 84a4e5cd..16fef73a 100644
--- a/msg.c
+++ b/msg.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-2001, 2003, 2010
+ * Copyright (C) 1986, 1988, 1989, 1991-2001, 2003, 2010-2013
* the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
@@ -33,28 +33,33 @@ static const char *srcfile = NULL;
static int srcline;
jmp_buf fatal_tag;
-int fatal_tag_valid = FALSE;
+bool fatal_tag_valid = false;
/* err --- print an error message with source line and file and record */
/* VARARGS2 */
void
-err(const char *s, const char *emsg, va_list argp)
+err(bool isfatal, const char *s, const char *emsg, va_list argp)
{
char *file;
const char *me;
+ static bool first = true;
+ static bool add_src_info = false;
+
+ if (first) {
+ first = false;
+ add_src_info = (getenv("GAWK_MSG_SRC") != NULL);
+ }
+
(void) fflush(output_fp);
me = myname;
- if (STREQN(me, "dgawk", 5))
- me = &myname[1];
(void) fprintf(stderr, "%s: ", me);
-#ifdef GAWKDEBUG
- if (srcfile != NULL) {
+
+ if (srcfile != NULL && add_src_info) {
fprintf(stderr, "%s:%d:", srcfile, srcline);
srcfile = NULL;
}
-#endif /* GAWKDEBUG */
if (sourceline > 0) {
if (source != NULL)
@@ -64,6 +69,21 @@ err(const char *s, const char *emsg, va_list argp)
(void) fprintf(stderr, "%d: ", sourceline);
}
+
+#ifdef HAVE_MPFR
+ if (FNR_node && is_mpg_number(FNR_node->var_value)) {
+ NODE *val;
+ val = mpg_update_var(FNR_node);
+ assert((val->flags & MPZN) != 0);
+ if (mpz_sgn(val->mpg_i) > 0) {
+ file = FILENAME_node->var_value->stptr;
+ (void) putc('(', stderr);
+ if (file)
+ (void) fprintf(stderr, "FILENAME=%s ", file);
+ (void) mpfr_fprintf(stderr, "FNR=%Zd) ", val->mpg_i);
+ }
+ } else
+#endif
if (FNR > 0) {
file = FILENAME_node->var_value->stptr;
(void) putc('(', stderr);
@@ -71,10 +91,18 @@ err(const char *s, const char *emsg, va_list argp)
(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);
+
+ if (isfatal) {
+#ifdef GAWKDEBUG
+ abort();
+#endif
+ gawk_exit(EXIT_FATAL);
+ }
}
/* msg --- take a varargs error message and print it */
@@ -84,18 +112,18 @@ msg(const char *mesg, ...)
{
va_list args;
va_start(args, mesg);
- err("", mesg, args);
+ err(false, "", mesg, args);
va_end(args);
}
-/* warning --- print a warning message */
+/* r_warning --- print a warning message */
void
-warning(const char *mesg, ...)
+r_warning(const char *mesg, ...)
{
va_list args;
va_start(args, mesg);
- err(_("warning: "), mesg, args);
+ err(false, _("warning: "), mesg, args);
va_end(args);
}
@@ -104,7 +132,7 @@ error(const char *mesg, ...)
{
va_list args;
va_start(args, mesg);
- err(_("error: "), mesg, args);
+ err(false, _("error: "), mesg, args);
va_end(args);
}
@@ -127,12 +155,8 @@ r_fatal(const char *mesg, ...)
{
va_list args;
va_start(args, mesg);
- err(_("fatal: "), mesg, args);
+ err(true, _("fatal: "), mesg, args);
va_end(args);
-#ifdef GAWKDEBUG
- abort();
-#endif
- gawk_exit(EXIT_FATAL);
}
/* gawk_exit --- longjmp out if necessary */
@@ -144,5 +168,20 @@ gawk_exit(int status)
exit_val = status;
longjmp(fatal_tag, 1);
}
+
+ final_exit(status);
+}
+
+/* final_exit --- run extension exit handlers and exit */
+
+void
+final_exit(int status)
+{
+ /* run any extension exit handlers */
+ run_ext_exit_handlers(status);
+
+ /* we could close_io() here */
+ close_extensions();
+
exit(status);
}
diff --git a/node.c b/node.c
index 73d3ec41..507d0650 100644
--- a/node.c
+++ b/node.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-2001, 2003-2011,
+ * Copyright (C) 1986, 1988, 1989, 1991-2001, 2003-2013,
* the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
@@ -26,15 +26,21 @@
#include "awk.h"
#include "math.h"
+#include "floatmagic.h" /* definition of isnan */
static int is_ieee_magic_val(const char *val);
+static NODE *r_make_number(double x);
static AWKNUM get_ieee_magic_val(const char *val);
extern NODE **fmt_list; /* declared in eval.c */
+NODE *(*make_number)(double) = r_make_number;
+NODE *(*str2number)(NODE *) = r_force_number;
+NODE *(*format_val)(const char *, int, NODE *) = r_format_val;
+int (*cmp_numbers)(const NODE *, const NODE *) = cmp_awknums;
/* force_number --- force a value to be numeric */
-AWKNUM
+NODE *
r_force_number(NODE *n)
{
char *cp;
@@ -44,8 +50,8 @@ r_force_number(NODE *n)
unsigned int newflags;
extern double strtod();
- if (n->flags & NUMCUR)
- return n->numbr;
+ if ((n->flags & NUMCUR) != 0)
+ return n;
/* all the conditionals are an attempt to avoid the expensive strtod */
@@ -54,7 +60,7 @@ r_force_number(NODE *n)
n->numbr = 0.0;
if (n->stlen == 0) {
- return 0.0;
+ return n;
}
cp = n->stptr;
@@ -66,15 +72,15 @@ r_force_number(NODE *n)
* This also allows hexadecimal floating point. Ugh.
*/
if (! do_posix) {
- if (isalpha((unsigned char) *cp)) {
- return 0.0;
+ if (is_alpha((unsigned char) *cp)) {
+ return n;
} else if (n->stlen == 4 && is_ieee_magic_val(n->stptr)) {
- if (n->flags & MAYBE_NUM)
+ if ((n->flags & MAYBE_NUM) != 0)
n->flags &= ~MAYBE_NUM;
n->flags |= NUMBER|NUMCUR;
n->numbr = get_ieee_magic_val(n->stptr);
- return n->numbr;
+ return n;
}
/* else
fall through */
@@ -88,14 +94,14 @@ r_force_number(NODE *n)
if ( cp == cpend /* only spaces, or */
|| (! do_posix /* not POSIXLY paranoid and */
- && (isalpha((unsigned char) *cp) /* letter, or */
+ && (is_alpha((unsigned char) *cp) /* letter, or */
/* CANNOT do non-decimal and saw 0x */
|| (! do_non_decimal_data && cp[0] == '0'
&& (cp[1] == 'x' || cp[1] == 'X'))))) {
- return 0.0;
+ return n;
}
- if (n->flags & MAYBE_NUM) {
+ if ((n->flags & MAYBE_NUM) != 0) {
newflags = NUMBER;
n->flags &= ~MAYBE_NUM;
} else
@@ -109,12 +115,12 @@ r_force_number(NODE *n)
if (cp == n->stptr) /* no leading spaces */
n->flags |= NUMINT;
}
- return n->numbr;
+ return n;
}
if (do_non_decimal_data) { /* main.c assures false if do_posix */
errno = 0;
- if (! do_traditional && isnondecimal(cp, TRUE)) {
+ if (! do_traditional && get_numbase(cp, true) != 10) {
n->numbr = nondec2awknum(cp, cpend - cp);
n->flags |= NUMCUR;
ptr = cpend;
@@ -139,7 +145,7 @@ finish:
errno = 0;
}
- return n->numbr;
+ return n;
}
@@ -162,10 +168,10 @@ static const char *values[] = {
};
#define NVAL (sizeof(values)/sizeof(values[0]))
-/* format_val --- format a numeric value based on format */
+/* r_format_val --- format a numeric value based on format */
NODE *
-format_val(const char *format, int index, NODE *s)
+r_format_val(const char *format, int index, NODE *s)
{
char buf[BUFSIZ];
char *sp = buf;
@@ -190,7 +196,8 @@ format_val(const char *format, int index, NODE *s)
/* not an integral value, or out of range */
if ((val = double_to_int(s->numbr)) != s->numbr
- || val <= LONG_MIN || val >= LONG_MAX) {
+ || val <= LONG_MIN || val >= LONG_MAX
+ ) {
/*
* Once upon a time, we just blindly did this:
* sprintf(sp, format, s->numbr);
@@ -201,11 +208,12 @@ format_val(const char *format, int index, NODE *s)
*/
NODE *dummy[2], *r;
- unsigned short oflags;
+ unsigned int oflags;
/* create dummy node for a sole use of format_tree */
dummy[1] = s;
oflags = s->flags;
+
if (val == s->numbr) {
/* integral value, but outside range of %ld, use %.0f */
r = format_tree("%.0f", 4, dummy, 2);
@@ -237,7 +245,7 @@ format_val(const char *format, int index, NODE *s)
s->stlen = strlen(sp);
}
s->stfmt = -1;
- if (s->flags & INTIND) {
+ if ((s->flags & INTIND) != 0) {
s->flags &= ~(INTIND|NUMBER);
s->flags |= STRING;
}
@@ -252,21 +260,6 @@ no_malloc:
return s;
}
-
-/* r_force_string --- force a value to be a string */
-
-#ifdef GAWKDEBUG
-NODE *
-r_force_string(NODE *s)
-{
- if ((s->flags & STRCUR) != 0
- && (s->stfmt == -1 || s->stfmt == CONVFMTidx)
- )
- return s;
- return format_val(CONVFMT, CONVFMTidx, s);
-}
-#endif
-
/* r_dupnode --- duplicate a node */
NODE *
@@ -288,7 +281,6 @@ r_dupnode(NODE *n)
r->flags &= ~FIELD;
r->flags |= MALLOC;
r->valref = 1;
-#if MBS_SUPPORT
/*
* DON'T call free_wstr(r) here!
* r->wstptr still points at n->wstptr's value, and we
@@ -296,13 +288,11 @@ r_dupnode(NODE *n)
*/
r->wstptr = NULL;
r->wstlen = 0;
-#endif /* MBS_SUPPORT */
if ((n->flags & STRCUR) != 0) {
emalloc(r->stptr, char *, n->stlen + 2, "r_dupnode");
memcpy(r->stptr, n->stptr, n->stlen);
r->stptr[n->stlen] = '\0';
-#if MBS_SUPPORT
if ((n->flags & WSTRCUR) != 0) {
r->wstlen = n->wstlen;
emalloc(r->wstptr, wchar_t *, sizeof(wchar_t) * (n->wstlen + 2), "r_dupnode");
@@ -310,37 +300,60 @@ r_dupnode(NODE *n)
r->wstptr[n->wstlen] = L'\0';
r->flags |= WSTRCUR;
}
-#endif /* MBS_SUPPORT */
}
return r;
}
-/* make_number --- allocate a node with defined number */
+/* r_make_number --- allocate a node with defined number */
-NODE *
-make_number(AWKNUM x)
+static NODE *
+r_make_number(double x)
{
NODE *r;
getnode(r);
r->type = Node_val;
r->numbr = x;
- r->valref = 1;
r->flags = MALLOC|NUMBER|NUMCUR;
+ r->valref = 1;
r->stptr = NULL;
r->stlen = 0;
-#if MBS_SUPPORT
r->wstptr = NULL;
r->wstlen = 0;
-#endif /* defined MBS_SUPPORT */
return r;
}
+/* cmp_awknums --- compare two AWKNUMs */
+
+int
+cmp_awknums(const NODE *t1, const NODE *t2)
+{
+ /*
+ * This routine is also used to sort numeric array indices or values.
+ * For the purposes of sorting, NaN is considered greater than
+ * any other value, and all NaN values are considered equivalent and equal.
+ * This isn't in compliance with IEEE standard, but compliance w.r.t. NaN
+ * comparison at the awk level is a different issue, and needs to be dealt
+ * with in the interpreter for each opcode seperately.
+ */
+
+ if (isnan(t1->numbr))
+ return ! isnan(t2->numbr);
+ if (isnan(t2->numbr))
+ return -1;
+ /* don't subtract, in case one or both are infinite */
+ if (t1->numbr == t2->numbr)
+ return 0;
+ if (t1->numbr < t2->numbr)
+ return -1;
+ return 1;
+}
-/* r_make_str_node --- make a string node */
+
+/* make_str_node --- make a string node */
NODE *
-r_make_str_node(const char *s, size_t len, int flags)
+make_str_node(const char *s, size_t len, int flags)
{
NODE *r;
getnode(r);
@@ -349,16 +362,13 @@ r_make_str_node(const char *s, size_t len, int flags)
r->flags = (MALLOC|STRING|STRCUR);
r->valref = 1;
r->stfmt = -1;
-
-#if MBS_SUPPORT
r->wstptr = NULL;
r->wstlen = 0;
-#endif /* MBS_SUPPORT */
- if (flags & ALREADY_MALLOCED)
+ if ((flags & ALREADY_MALLOCED) != 0)
r->stptr = (char *) s;
else {
- emalloc(r->stptr, char *, len + 2, "r_make_str_node");
+ emalloc(r->stptr, char *, len + 2, "make_str_node");
memcpy(r->stptr, s, len);
}
r->stptr[len] = '\0';
@@ -368,15 +378,12 @@ r_make_str_node(const char *s, size_t len, int flags)
char *ptm;
int c;
const char *end;
-#if 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;) {
-#if MBS_SUPPORT
/*
* Keep multibyte characters together. This avoids
* problems if a subsequent byte of a multibyte
@@ -393,7 +400,7 @@ r_make_str_node(const char *s, size_t len, int flags)
continue;
}
}
-#endif
+
c = *pf++;
if (c == '\\') {
c = parse_escape(&pf);
@@ -407,7 +414,7 @@ r_make_str_node(const char *s, size_t len, int flags)
*ptm++ = c;
}
len = ptm - r->stptr;
- erealloc(r->stptr, char *, len + 1, "r_make_str_node");
+ erealloc(r->stptr, char *, len + 1, "make_str_node");
r->stptr[len] = '\0';
}
r->stlen = len;
@@ -429,7 +436,7 @@ r_unref(NODE *tmp)
tmp->valref--;
return;
}
- if (tmp->flags & STRCUR)
+ if ((tmp->flags & STRCUR) != 0)
efree(tmp->stptr);
}
#else
@@ -437,6 +444,8 @@ r_unref(NODE *tmp)
efree(tmp->stptr);
#endif
+ mpfr_unset(tmp);
+
free_wstr(tmp);
freenode(tmp);
}
@@ -523,10 +532,10 @@ parse_escape(const char **string_ptr)
return i;
case 'x':
if (do_lint) {
- static short warned = FALSE;
+ static bool warned = false;
if (! warned) {
- warned = TRUE;
+ warned = true;
lintwarn(_("POSIX does not allow `\\x' escapes"));
}
}
@@ -536,9 +545,8 @@ parse_escape(const char **string_ptr)
warning(_("no hex digits in `\\x' escape sequence"));
return ('x');
}
- i = j = 0;
start = *string_ptr;
- for (;; j++) {
+ for (i = j = 0; j < 2; j++) {
/* do outside test to avoid multiple side effects */
c = *(*string_ptr)++;
if (isxdigit(c)) {
@@ -562,13 +570,13 @@ parse_escape(const char **string_ptr)
return c;
default:
{
- static short warned[256];
+ static bool 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;
+ warned[uc] = true;
warning(_("escape sequence `\\%c' treated as plain `%c'"), uc, uc);
}
@@ -577,12 +585,14 @@ parse_escape(const char **string_ptr)
}
}
-/* isnondecimal --- return true if number is not a decimal number */
+/* get_numbase --- return the base to use for the number in 's' */
int
-isnondecimal(const char *str, int use_locale)
+get_numbase(const char *s, bool use_locale)
{
int dec_point = '.';
+ const char *str = s;
+
#if defined(HAVE_LOCALE_H)
/*
* loc.decimal_point may not have been initialized yet,
@@ -593,11 +603,11 @@ isnondecimal(const char *str, int use_locale)
#endif
if (str[0] != '0')
- return FALSE;
+ return 10;
/* leading 0x or 0X */
if (str[1] == 'x' || str[1] == 'X')
- return TRUE;
+ return 16;
/*
* Numbers with '.', 'e', or 'E' are decimal.
@@ -607,15 +617,18 @@ isnondecimal(const char *str, int use_locale)
*/
for (; *str != '\0'; str++) {
if (*str == 'e' || *str == 'E' || *str == dec_point)
- return FALSE;
+ return 10;
else if (! isdigit((unsigned char) *str))
break;
}
- return TRUE;
+ if (! isdigit((unsigned char) s[1])
+ || s[1] == '8' || s[1] == '9'
+ )
+ return 10;
+ return 8;
}
-#if MBS_SUPPORT
/* str2wstr --- convert a multibyte string to a wide string */
NODE *
@@ -625,7 +638,7 @@ str2wstr(NODE *n, size_t **ptr)
char *sp;
mbstate_t mbs;
wchar_t wc, *wsp;
- static short warned = FALSE;
+ static bool warned = false;
assert((n->flags & (STRING|STRCUR)) != 0);
@@ -708,7 +721,7 @@ str2wstr(NODE *n, size_t **ptr)
memset(& mbs, 0, sizeof(mbs));
/* And warn the user something's wrong */
if (do_lint && ! warned) {
- warned = TRUE;
+ warned = true;
lintwarn(_("Invalid multibyte data detected. There may be a mismatch between your data and your locale."));
}
break;
@@ -782,7 +795,7 @@ wstr2str(NODE *n)
/* free_wstr --- release the wide string part of a node */
void
-free_wstr(NODE *n)
+r_free_wstr(NODE *n)
{
assert(n->type == Node_val);
@@ -864,7 +877,6 @@ out: ;
return NULL;
}
-#endif /* MBS_SUPPORT */
/* is_ieee_magic_val --- return true for +inf, -inf, +nan, -nan */
@@ -889,7 +901,7 @@ is_ieee_magic_val(const char *val)
static AWKNUM
get_ieee_magic_val(const char *val)
{
- static short first = TRUE;
+ static bool first = true;
static AWKNUM inf;
static AWKNUM nan;
@@ -898,7 +910,7 @@ get_ieee_magic_val(const char *val)
if (val == ptr) { /* Older strtod implementations don't support inf or nan. */
if (first) {
- first = FALSE;
+ first = false;
nan = sqrt(-1.0);
inf = -log(0.0);
}
@@ -911,7 +923,6 @@ get_ieee_magic_val(const char *val)
return v;
}
-#if MBS_SUPPORT
wint_t btowc_cache[256];
/* init_btowc_cache --- initialize the cache */
@@ -924,7 +935,6 @@ void init_btowc_cache()
btowc_cache[i] = btowc(i);
}
}
-#endif
#define BLOCKCHUNK 100
diff --git a/eval_p.c b/nonposix.h
index c8afe666..88fd9e69 100644
--- a/eval_p.c
+++ b/nonposix.h
@@ -1,9 +1,9 @@
/*
- * eval_p.c - compile eval.c with profiling turned on.
+ * nonposix.h --- definitions needed on non-POSIX systems.
*/
/*
- * Copyright (C) 2001 the Free Software Foundation, Inc.
+ * Copyright (C) 2012, 2013 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -23,5 +23,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#define PROFILING 1
-#include "eval.c"
+/*
+ * This is for fake directory file descriptors on systems that don't
+ * allow to open() a directory.
+ */
+
+#define FAKE_FD_VALUE 42
diff --git a/old-extension/ChangeLog b/old-extension/ChangeLog
new file mode 100644
index 00000000..55c8d31d
--- /dev/null
+++ b/old-extension/ChangeLog
@@ -0,0 +1,13 @@
+2014-01-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * dbarray.awk: Use full name for lib to load in extenstion() call.
+ * record.awk: Ditto.
+ * testsparr.awk: Ditto.
+ * spec_array.c [SUPER]: Fix so that it will compile.
+
+2013-01-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * bindarr.c, dbarray.awk, fileop.c, record.awk, sparr.c,
+ spec_array.c, spec_array.h, steps, testdbarray.awk, testrecord.sh,
+ testsparr.awk: Moved here from extension directory, since they
+ use the old mechanism.
diff --git a/old-extension/bindarr.c b/old-extension/bindarr.c
new file mode 100644
index 00000000..60959903
--- /dev/null
+++ b/old-extension/bindarr.c
@@ -0,0 +1,347 @@
+/*
+ * bindarr.c - routines for binding (attaching) user-defined functions
+ * to array and array elements.
+ */
+
+/*
+ * Copyright (C) 1986, 1988, 1989, 1991-2011 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 3 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"
+
+/*
+ * Binding an array is basically the binding of functions to the internal
+ * triggers for reading and writing that array or an element of that array.
+ * This allows the user to define the set of behaviors for gawk arrays
+ * using gawk functions. With arrays you can assign and read values of
+ * specific elements, provide list of indices and values, and tell if a
+ * certain index exists or not. A variable can be "tied" by including
+ * code which overrides any or all of the standard behaviors of awk arrays.
+ *
+ * See dbarray.awk and testdbarray.awk to learn how to bind an array
+ * to an external database for persistent storage.
+ */
+
+int plugin_is_GPL_compatible;
+
+static NODE **bind_array_lookup(NODE *, NODE *);
+static NODE **bind_array_exists(NODE *, NODE *);
+static NODE **bind_array_clear(NODE *, NODE *);
+static NODE **bind_array_remove(NODE *, NODE *);
+static NODE **bind_array_list(NODE *, NODE *);
+static NODE **bind_array_store(NODE *, NODE *);
+static NODE **bind_array_length(NODE *, NODE *);
+
+static afunc_t bind_array_func[] = {
+ (afunc_t) 0,
+ (afunc_t) 0,
+ bind_array_length,
+ bind_array_lookup,
+ bind_array_exists,
+ bind_array_clear,
+ bind_array_remove,
+ bind_array_list,
+ null_afunc, /* copy */
+ null_afunc, /* dump */
+ bind_array_store,
+};
+
+enum { INIT, FINI, COUNT, EXISTS, LOOKUP,
+ STORE, DELETE, CLEAR, FETCHALL
+};
+
+static const char *const bfn[] = {
+ "init", "fini", "count", "exists", "lookup",
+ "store", "delete", "clear", "fetchall",
+};
+
+typedef struct {
+ NODE *func[sizeof(bfn)/sizeof(char *)];
+ NODE *arg0;
+} array_t;
+
+static NODE *call_func(NODE *func, NODE **arg, int arg_count);
+static long array_func_call(NODE *, NODE *, int);
+
+
+/* bind_array_length -- find the number of elements in the array */
+
+static NODE **
+bind_array_length(NODE *symbol, NODE *subs ATTRIBUTE_UNUSED)
+{
+ static NODE *length_node;
+
+ symbol->table_size = array_func_call(symbol, NULL, COUNT);
+ length_node = symbol;
+ return & length_node;
+}
+
+/* bind_array_lookup --- find element in the array; return a pointer to value. */
+
+static NODE **
+bind_array_lookup(NODE *symbol, NODE *subs)
+{
+ NODE *xn = symbol->xarray;
+ (void) array_func_call(symbol, subs, LOOKUP);
+ return xn->alookup(xn, subs);
+}
+
+/*
+ * bind_array_exists --- test whether the array element symbol[subs] exists or not,
+ * return pointer to value if it does.
+ */
+
+static NODE **
+bind_array_exists(NODE *symbol, NODE *subs)
+{
+ NODE *xn = symbol->xarray;
+ (void) array_func_call(symbol, subs, EXISTS);
+ return xn->aexists(xn, subs);
+}
+
+/* bind_array_clear --- flush all the values in symbol[] */
+
+static NODE **
+bind_array_clear(NODE *symbol, NODE *subs ATTRIBUTE_UNUSED)
+{
+ NODE *xn = symbol->xarray;
+ (void) xn->aclear(xn, NULL);
+ (void) array_func_call(symbol, NULL, CLEAR);
+ return NULL;
+}
+
+/* bind_array_remove --- if subs is already in the table, remove it. */
+
+static NODE **
+bind_array_remove(NODE *symbol, NODE *subs)
+{
+ NODE *xn = symbol->xarray;
+ (void) xn->aremove(xn, subs);
+ (void) array_func_call(symbol, subs, DELETE);
+ return NULL;
+}
+
+/* bind_array_store --- update the value for the SUBS */
+
+static NODE **
+bind_array_store(NODE *symbol, NODE *subs)
+{
+ (void) array_func_call(symbol, subs, STORE);
+ return NULL;
+}
+
+/* bind_array_list --- return a list of array items */
+
+static NODE**
+bind_array_list(NODE *symbol, NODE *akind)
+{
+ NODE *xn = symbol->xarray;
+ (void) array_func_call(symbol, NULL, FETCHALL);
+ return xn->alist(xn, akind);
+}
+
+
+/* array_func_call --- call user-defined array routine */
+
+static long
+array_func_call(NODE *symbol, NODE *arg1, int fi)
+{
+ NODE *argp[3];
+ NODE *retval;
+ long ret;
+ int i = 0;
+ array_t *aq;
+
+ aq = symbol->a_opaque;
+ if (! aq) /* an array routine invoked from the same or another routine */
+ fatal(_("bind_array: cannot access bound array, operation not allowed"));
+ symbol->a_opaque = NULL; /* avoid infinite recursion */
+
+ argp[i++] = symbol->xarray;
+ argp[i++] = aq->arg0;
+ if (arg1 != NULL)
+ argp[i++] = arg1;
+
+ retval = call_func(aq->func[fi], argp, i);
+ symbol->a_opaque = aq;
+ force_number(retval);
+ ret = get_number_si(retval);
+ unref(retval);
+ if (ret < 0) {
+ if (ERRNO_node->var_value->stlen > 0)
+ fatal(_("%s"), ERRNO_node->var_value->stptr);
+ else
+ fatal(_("unknown reason"));
+ }
+ return ret;
+}
+
+/* do_bind_array --- bind an array to user-defined functions */
+
+static NODE *
+do_bind_array(int nargs)
+{
+ NODE *symbol, *xn, *t, *td;
+ int i;
+ array_t *aq;
+ char *aname;
+
+ symbol = get_array_argument(0, false);
+ if (symbol->array_funcs == bind_array_func)
+ fatal(_("bind_array: array `%s' already bound"), array_vname(symbol));
+
+ assoc_clear(symbol);
+
+ emalloc(aq, array_t *, sizeof(array_t), "do_bind_array");
+ memset(aq, '\0', sizeof(array_t));
+
+ t = get_array_argument(1, false);
+
+ for (i = 0; i < sizeof(bfn)/sizeof(char *); i++) {
+ NODE *subs, *val, *f;
+
+ subs = make_string(bfn[i], strlen(bfn[i]));
+ val = in_array(t, subs);
+ unref(subs);
+ if (val == NULL) {
+ if (i != INIT && i != FINI)
+ fatal(_("bind_array: array element `%s[\"%s\"]' not defined"),
+ t->vname, bfn[i]);
+ continue;
+ }
+
+ force_string(val);
+ f = lookup(val->stptr);
+ if (f == NULL || f->type != Node_func)
+ fatal(_("bind_array: function `%s' is not defined"), val->stptr);
+ aq->func[i] = f;
+ }
+
+ /* copy the array -- this is passed as the second argument to the functions */
+ emalloc(aname, char *, strlen(t->vname) + 2, "do_bind_array");
+ aname[0] = '~'; /* any illegal character */
+ strcpy(& aname[1], symbol->vname);
+ td = make_array();
+ td->vname = aname;
+ assoc_copy(t, td);
+ aq->arg0 = td;
+
+ /* internal array for the actual storage */
+ xn = make_array();
+ xn->vname = symbol->vname; /* shallow copy */
+ xn->flags |= XARRAY;
+ symbol->a_opaque = aq;
+ symbol->array_funcs = bind_array_func;
+ symbol->xarray = xn;
+
+ if (aq->func[INIT] != NULL)
+ (void) array_func_call(symbol, NULL, INIT);
+
+ return make_number(0);
+}
+
+/* do_unbind_array --- unbind an array */
+
+static NODE *
+do_unbind_array(int nargs)
+{
+ NODE *symbol, *xn, *td;
+ array_t *aq;
+
+ symbol = get_array_argument(0, false);
+ if (symbol->array_funcs != bind_array_func)
+ fatal(_("unbind_array: `%s' is not a bound array"), array_vname(symbol));
+
+ aq = symbol->a_opaque;
+ if (aq->func[FINI] != NULL)
+ (void) array_func_call(symbol, NULL, FINI);
+
+ td = aq->arg0;
+ assoc_clear(td);
+ efree(td->vname);
+ freenode(td);
+ efree(aq);
+
+ /* promote xarray to symbol */
+ xn = symbol->xarray;
+ xn->flags &= ~XARRAY;
+ xn->parent_array = symbol->parent_array;
+ *symbol = *xn;
+ freenode(xn);
+
+ return make_number(0);
+}
+
+
+/* call_func --- call a user-defined gawk function */
+
+static NODE *
+call_func(NODE *func, NODE **arg, int arg_count)
+{
+ NODE *ret;
+ INSTRUCTION *code;
+ extern int currule;
+ int i, save_rule = 0;
+
+ if (arg_count > func->param_cnt)
+ fatal(_("function `%s' called with too many parameters"), func->vname);
+
+ /* make function call instructions */
+ code = bcalloc(Op_func_call, 2, 0);
+ code->func_body = func;
+ code->func_name = NULL; /* not needed, func_body already assigned */
+ (code + 1)->expr_count = arg_count;
+ code->nexti = bcalloc(Op_stop, 1, 0);
+
+ save_rule = currule; /* save current rule */
+ currule = 0;
+
+ /* push arguments onto stack */
+ for (i = 0; i < arg_count; i++) {
+ if (arg[i]->type == Node_val)
+ UPREF(arg[i]);
+ PUSH(arg[i]);
+ }
+
+ /* execute the function */
+ (void) interpret(code);
+
+ ret = POP_SCALAR(); /* the return value of the function */
+
+ /* restore current rule */
+ currule = save_rule;
+
+ /* free code */
+ bcfree(code->nexti);
+ bcfree(code);
+
+ return ret;
+}
+
+
+/* dlload --- load this library */
+
+NODE *
+dlload(NODE *obj, void *dl)
+{
+ make_old_builtin("bind_array", do_bind_array, 2);
+ make_old_builtin("unbind_array", do_unbind_array, 1);
+ return make_number((AWKNUM) 0);
+}
diff --git a/old-extension/dbarray.awk b/old-extension/dbarray.awk
new file mode 100644
index 00000000..1e31f58f
--- /dev/null
+++ b/old-extension/dbarray.awk
@@ -0,0 +1,222 @@
+# dbarray.awk -- persistent array with sqlite database backend
+
+# @load "bindarr"
+
+BEGIN {
+ extension("./bindarr.so")
+}
+
+function _db_count(symbol, sq,
+ sth, ret, count)
+{
+ sth = sq["sqlc"]
+ printf "SELECT count(col1) FROM %s;\n", sq["table"] |& sth
+ close(sth, "to")
+ ret = (sth |& getline count)
+ if (close(sth) != 0 || ret <= 0)
+ return -1
+ return count
+}
+
+function _db_exists(symbol, sq, subs,
+ sth, ret, row, qsubs)
+{
+ if (! (subs in symbol)) {
+ sth = sq["sqlc"]
+
+ # double up single quotes
+ qsubs = gensub(/'/, "''", "g", subs)
+
+ printf "SELECT col2 FROM %s WHERE col1='%s';\n", sq["table"], qsubs |& sth
+ close(sth, "to")
+ ret = (sth |& getline row)
+ if (close(sth) != 0 || ret < 0)
+ return -1
+ if (ret == 0) # non-existent row
+ return 0
+ if (row == sq["null"])
+ symbol[subs] # install null string as value
+ else
+ symbol[subs] = row
+ }
+ return 0
+}
+
+function _db_lookup(symbol, sq, subs,
+ sth, ret, row, qsubs)
+{
+ if (! (subs in symbol)) {
+ sth = sq["sqlc"]
+
+ # double up single quotes
+ qsubs = gensub(/'/, "''", "g", subs)
+
+ printf "SELECT col2 FROM %s WHERE col1='%s';\n", sq["table"], qsubs |& sth
+ close(sth, "to")
+ ret = (sth |& getline row)
+ if (close(sth) != 0 || ret < 0)
+ return -1
+
+ if (ret > 0) {
+ if (row == sq["null"])
+ symbol[subs] # install null string as value
+ else
+ symbol[subs] = row
+ } else {
+ # Not there, install it with NULL as value
+ printf "INSERT INTO %s (col1) VALUES('%s');\n", sq["table"], qsubs |& sth
+ close(sth, "to")
+ ret = (sth |& getline)
+ if (close(sth) != 0 || ret < 0)
+ return -1
+ }
+ }
+ return 0
+}
+
+function _db_clear(symbol, sq,
+ sth, ret)
+{
+ sth = sq["sqlc"]
+ printf "DELETE FROM %s;\n", sq["table"] |& sth
+ close(sth, "to")
+ ret = (sth |& getline)
+ if (close(sth) != 0 || ret < 0)
+ return -1
+ return 0
+}
+
+function _db_delete(symbol, sq, subs,
+ sth, ret, qsubs)
+{
+ sth = sq["sqlc"]
+ qsubs = gensub(/'/, "''", "g", subs)
+ printf "DELETE FROM %s WHERE col1='%s';\n", sq["table"], qsubs |& sth
+ close(sth, "to")
+ ret = (sth |& getline)
+ if (close(sth) != 0 || ret < 0)
+ return -1
+ return 0
+}
+
+function _db_store(symbol, sq, subs,
+ sth, ret, qsubs, qval)
+{
+ sth = sq["sqlc"]
+
+ qval = gensub(/'/, "''", "g", symbol[subs])
+ qsubs = gensub(/'/, "''", "g", subs)
+ printf "UPDATE %s SET col2='%s' WHERE col1='%s';\n", \
+ sq["table"], qval, qsubs |& sth
+ close(sth, "to")
+ ret = (sth |& getline)
+ if (close(sth) != 0 || ret < 0)
+ return -1
+ return 0
+}
+
+function _db_fetchall(symbol, sq,
+ sth, ret, save_RS, save_FS)
+{
+ sth = sq["sqlc2"]
+
+ if (! sq["loaded"]) {
+ printf "SELECT col1, col2 FROM %s;\n", sq["table"] |& sth
+ close(sth, "to")
+ save_RS = RS
+ save_FS = FS
+ RS = "\n\n"
+ FS = "\n"
+ while ((ret = (sth |& getline)) > 0) {
+ sub(/^ *col1 = /, "", $1)
+ sub(/^ *col2 = /, "", $2)
+ if ($2 == sq["null"])
+ symbol[$1] # install null string as value
+ else
+ symbol[$1] = $2
+ }
+ RS = save_RS
+ FS = save_FS
+ if (ret < 0 || close(sth) != 0)
+ return -1
+ sq["loaded"] = 1
+ }
+}
+
+
+function _db_init(symbol, sq,
+ sth, table, ret)
+{
+ sth = sq["sqlc"]
+ table = sq["table"]
+
+ # check if table exists
+ printf ".tables %s\n", table |& sth
+ close(sth, "to")
+ ret = (sth |& getline)
+ if (close(sth) != 0 || ret < 0)
+ return -1
+ if (ret > 0 && $0 == table) {
+ # verify schema
+ printf ".schema %s\n", table |& sth
+ close(sth, "to")
+ ret = (sth |& getline)
+ if (close(sth) != 0 || ret <= 0)
+ return -1
+ if ($0 !~ /\(col1 TEXT PRIMARY KEY, col2 TEXT\)/) {
+ printf "table %s: Invalid column name or type(s)\n", table > "/dev/stderr"
+ return -1
+ }
+ } else {
+ # table does not exist, create it.
+ printf "CREATE TABLE %s (col1 TEXT PRIMARY KEY, col2 TEXT);\n", table |& sth
+ close(sth, "to")
+ ret = (sth |& getline)
+ if (close(sth) != 0 || ret < 0)
+ return -1
+ }
+ return 0
+}
+
+#function _db_fini(tie, a, subs) {}
+
+function db_bind(arr, database, table, sq)
+{
+ if (! database) {
+ print "db_bind: must specify a database name" > "/dev/stderr"
+ exit(1)
+ }
+
+ if (! table) {
+ print "db_bind: must specify a table name" > "/dev/stderr"
+ exit(1)
+ }
+
+ # string used by the sqlite3 client to represent NULL
+ sq["null"] = "(null)"
+
+ sq["sqlc"] = sprintf("sqlite3 -nullvalue '%s' %s", sq["null"], database)
+ # sqlite command used in _db_fetchall
+ sq["sqlc2"] = sprintf("sqlite3 -line -nullvalue '%s' %s", sq["null"], database)
+
+ sq["table"] = table
+
+ # register our array routines
+ sq["init"] = "_db_init"
+ sq["count"] = "_db_count"
+ sq["exists"] = "_db_exists"
+ sq["lookup"] = "_db_lookup"
+ sq["delete"] = "_db_delete"
+ sq["store"] = "_db_store"
+ sq["clear"] = "_db_clear"
+ sq["fetchall"] = "_db_fetchall"
+
+# sq["fini"] = "_db_fini";
+
+ bind_array(arr, sq)
+}
+
+function db_unbind(arr)
+{
+ unbind_array(arr)
+}
diff --git a/old-extension/fileop.c b/old-extension/fileop.c
new file mode 100644
index 00000000..86f62576
--- /dev/null
+++ b/old-extension/fileop.c
@@ -0,0 +1,394 @@
+/*
+ * fileop.c -- Builtin functions for binary I/O and other interfaces to
+ * the filesystem.
+ */
+
+/*
+ * Copyright (C) 2012 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 3 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"
+
+int plugin_is_GPL_compatible;
+
+typedef struct file_struct {
+ struct file_struct *next;
+ FILE *fp;
+ int flags;
+ char path[1];
+} file_t;
+
+static file_t *files;
+static file_t *file_open(const char *builtin_name, int nargs, int do_open);
+static int mode2flags(const char *mode);
+
+/* do_fread --- read from file */
+
+static NODE *
+do_fread(int nargs)
+{
+ NODE *arg;
+ size_t rlen, count;
+ file_t *f;
+ char *rbuf;
+
+ f = file_open("fread", nargs, true);
+
+ arg = get_scalar_argument(2, false);
+ force_number(arg);
+ rlen = get_number_ui(arg);
+
+ emalloc(rbuf, char *, rlen + 2, "do_fread");
+ if ((count = fread(rbuf, 1, rlen, f->fp)) < rlen) {
+ if (! feof(f->fp))
+ update_ERRNO_int(errno);
+ }
+ return make_str_node(rbuf, count, ALREADY_MALLOCED);
+}
+
+/* do_fwrite --- write to file */
+
+static NODE *
+do_fwrite(int nargs)
+{
+ NODE *arg;
+ file_t *f;
+ size_t count = 0;
+
+ f = file_open("fwrite", nargs, true);
+
+ arg = get_scalar_argument(2, false);
+ force_string(arg);
+ if (arg->stlen > 0) {
+ count = fwrite(arg->stptr, 1, arg->stlen, f->fp);
+ if (count < arg->stlen)
+ update_ERRNO_int(errno);
+ }
+ return make_number(count);
+}
+
+/* do_fseek --- set the file position indicator */
+
+static NODE *
+do_fseek(int nargs)
+{
+ NODE *arg;
+ long offset;
+ file_t *f;
+ int whence = 0, ret = 0;
+
+ f = file_open("fseek", nargs, true);
+
+ arg = get_scalar_argument(2, false);
+ force_number(arg);
+ offset = get_number_si(arg);
+
+ arg = get_scalar_argument(3, false);
+ force_string(arg);
+ if (strcasecmp(arg->stptr, "SEEK_SET") == 0)
+ whence = SEEK_SET;
+ else if (strcasecmp(arg->stptr, "SEEK_CUR") == 0)
+ whence = SEEK_CUR;
+ else if (strcasecmp(arg->stptr, "SEEK_END") == 0)
+ whence = SEEK_END;
+ else
+ fatal(_("fseek: `%.*s' is not a valid 4th argument"),
+ (int) arg->stlen, arg->stptr);
+
+ if (fseek(f->fp, offset, whence) < 0) {
+ update_ERRNO_int(errno);
+ ret = -1;
+ }
+ return make_number(ret);
+}
+
+/* do_ftruncate --- truncate the file to a specified length */
+
+static NODE *
+do_ftruncate(int nargs)
+{
+ NODE *arg;
+ file_t *f;
+ off_t len;
+ int ret = 0;
+
+ f = file_open("ftruncate", nargs, true);
+ arg = get_scalar_argument(2, false);
+ force_number(arg);
+ len = (off_t) get_number_si(arg);
+ if (ftruncate(fileno(f->fp), len) < 0) {
+ update_ERRNO_int(errno);
+ ret = -1;
+ }
+ return make_number(ret);
+}
+
+/* do_unlink --- delete the name from the filesystem */
+
+static NODE *
+do_unlink(int nargs)
+{
+ NODE *file;
+ int ret = 0;
+
+ file = get_scalar_argument(0, false);
+ force_string(file);
+ if (file->stlen == 0)
+ fatal(_("unlink: filename has empty string value"));
+ if (unlink(file->stptr) < 0) {
+ update_ERRNO_int(errno);
+ ret = -1;
+ }
+ return make_number(ret);
+}
+
+/* do_flush --- flush buffered data to file */
+
+static NODE *
+do_flush(int nargs)
+{
+ file_t *f;
+ int status = -1;
+
+ f = file_open("flush", nargs, false);
+ if (f != NULL) {
+ status = fflush(f->fp);
+ if (status != 0)
+ update_ERRNO_int(errno);
+ }
+ return make_number(status);
+}
+
+/* do_fclose --- close an open file */
+
+static NODE *
+do_fclose(int nargs)
+{
+ file_t *f;
+ int status = -1;
+
+ f = file_open("fclose", nargs, false);
+ if (f != NULL) {
+ status = fclose(f->fp);
+ if (status != 0)
+ update_ERRNO_int(errno);
+ assert(files == f);
+ files = f->next;
+ efree(f);
+ }
+ return make_number(status);
+}
+
+/* do_filesize --- return the size of the file */
+
+static NODE *
+do_filesize(int nargs)
+{
+ NODE *file;
+ struct stat sbuf;
+ AWKNUM d = -1.0;
+
+ file = get_scalar_argument(0, false);
+ force_string(file);
+ if (file->stlen == 0)
+ fatal(_("filesize: filename has empty string value"));
+
+ if (stat(file->stptr, & sbuf) < 0) {
+ update_ERRNO_int(errno);
+ goto ferror;
+ }
+ if ((sbuf.st_mode & S_IFMT) != S_IFREG) {
+ errno = EINVAL;
+ update_ERRNO_int(errno);
+ goto ferror;
+ }
+ d = sbuf.st_size;
+
+ferror:
+ return make_number(d);
+}
+
+/* do_file_exists --- check if path exists in the filesystem */
+
+static NODE *
+do_file_exists(int nargs)
+{
+ NODE *file;
+ struct stat sbuf;
+ int ret = 1;
+
+ file = get_scalar_argument(0, false);
+ force_string(file);
+ if (file->stlen == 0)
+ fatal(_("file_exists: filename has empty string value"));
+
+ if (stat(file->stptr, & sbuf) < 0) {
+ if (errno != ENOENT)
+ update_ERRNO_int(errno);
+ ret = 0;
+ }
+ return make_number(ret);
+}
+
+
+/* file_open --- open a file or find an already opened file */
+
+static file_t *
+file_open(const char *builtin_name, int nargs, int do_open)
+{
+ NODE *file, *mode;
+ file_t *f, *prev;
+ FILE *fp;
+ int flags;
+ char *path;
+
+ if (nargs < 2)
+ cant_happen();
+
+ file = get_scalar_argument(0, false);
+ force_string(file);
+ mode = get_scalar_argument(1, true);
+ force_string(mode);
+
+ if (file->stlen == 0)
+ fatal(_("%s: filename has empty string value"), builtin_name);
+ if (mode->stlen == 0)
+ fatal(_("%s: mode has empty string value"), builtin_name);
+
+ flags = mode2flags(mode->stptr);
+ if (flags < 0)
+ fatal(_("%s: invalid mode `%.*s'"), builtin_name,
+ (int) mode->stlen, mode->stptr);
+
+ path = file->stptr;
+ for (prev = NULL, f = files; f != NULL; prev = f, f = f->next) {
+ if (strcmp(f->path, path) == 0 && f->flags == flags) {
+ /* Move to the head of the list */
+ if (prev != NULL) {
+ prev->next = f->next;
+ f->next = files;
+ files = f;
+ }
+ return f;
+ }
+ }
+
+ if (! do_open) {
+ if (do_lint)
+ lintwarn(_("%s: `%.*s' is not an open file"),
+ builtin_name, (int) file->stlen, file->stptr);
+ return NULL;
+ }
+
+ fp = fopen(path, mode->stptr);
+ if (fp == NULL)
+ fatal(_("%s: cannot open file `%.*s'"),
+ builtin_name, (int) file->stlen, file->stptr);
+
+ os_close_on_exec(fileno(fp), path, "", "");
+
+ emalloc(f, file_t *, sizeof(file_t) + file->stlen + 1, "file_open");
+ memcpy(f->path, path, file->stlen + 1);
+ f->fp = fp;
+ f->flags = flags;
+ f->next = files;
+ files = f;
+ return f;
+}
+
+
+/*
+ * mode2flags --- convert a string mode to an integer flag;
+ * modified from str2mode in io.c.
+ */
+
+static int
+mode2flags(const char *mode)
+{
+ int ret = -1;
+ const char *second;
+
+ if (mode == NULL || mode[0] == '\0')
+ return -1;
+
+ 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 = -1;
+ }
+ if (ret != -1 && strchr(mode, 'b') != NULL)
+ ret |= O_BINARY;
+ return ret;
+}
+
+
+/* dlload --- load new builtins in this library */
+
+NODE *
+dlload(NODE *tree, void *dl)
+{
+ make_old_builtin("fseek", do_fseek, 4);
+ make_old_builtin("fread", do_fread, 3);
+ make_old_builtin("fwrite", do_fwrite, 3);
+ make_old_builtin("flush", do_flush, 2);
+ make_old_builtin("filesize", do_filesize, 1);
+ make_old_builtin("file_exists", do_file_exists, 1);
+ make_old_builtin("fclose", do_fclose, 2);
+ make_old_builtin("ftruncate", do_ftruncate, 3);
+ make_old_builtin("unlink", do_unlink, 1);
+ return make_number((AWKNUM) 0);
+}
+
+
+/* dlunload --- routine called when exiting */
+
+void
+dlunload()
+{
+ file_t *f;
+ for (f = files; f != NULL; f = f->next) {
+ if (f->fp != NULL) {
+ fclose(f->fp);
+ f->fp = NULL;
+ }
+ }
+}
diff --git a/old-extension/record.awk b/old-extension/record.awk
new file mode 100644
index 00000000..ff89110d
--- /dev/null
+++ b/old-extension/record.awk
@@ -0,0 +1,252 @@
+# record.awk -- represent fixed-length records in a file as an array.
+# Each element in the array corresponds to a record in the file.
+# The records are numbered starting from 1, and each record read in
+# from the file is cached. If opened using mode "r+",
+# changes to the array are reflected in the file immediately i.e.
+# writing to an element writes the data into the file.
+#
+# Usage:
+# record(r, path [, reclen [, mode]])
+# r -- array to bind
+# path -- filename
+# reclen -- length of each record
+# mode -- "r" for reading (default), "r+" for reading and writing
+#
+# With reclen <= 0, entire file is treated as one record #1.
+#
+# record(r, "data.in", 80, "r+")
+# r[10] = r[1]
+# for (i = 1; i in r; i++)
+# print r[i]
+# delete r[1]
+#
+# See Also: testrecord.sh
+#
+#
+# TODO:
+# * implement deferred writing
+# * limit memory usage for read cache
+# * use fixed size buffer when deleting a record
+#
+
+BEGIN {
+ extension("./fileop.so")
+ extension("./bindarr.so")
+}
+
+# _record_count --- return the number of records in file
+
+function _record_count(symbol, rd)
+{
+ if (! ("rectot" in rd))
+ rd["rectot"] = ("reclen" in rd) ?
+ int(filesize(rd["path"]) / rd["reclen"]) : 1
+ return rd["rectot"]
+}
+
+# _record_exists --- check if record exists
+
+function _record_exists(symbol, rd, recnum,
+ path, mode, reclen, rectot)
+{
+ path = rd["path"]
+ reclen = ("reclen" in rd) ? rd["reclen"] : filesize(path)
+ mode = rd["mode"]
+ rectot = _record_count(symbol, rd)
+
+ recnum = int(recnum)
+ if (recnum <= 0 || recnum > rectot)
+ return 0
+
+ if (! (recnum in symbol)) {
+ fseek(path, mode, (recnum - 1) * reclen, "SEEK_SET")
+ symbol[recnum] = fread(path, mode, reclen)
+ }
+ return 0
+}
+
+# _record_lookup --- lookup a record
+
+function _record_lookup(symbol, rd, recnum,
+ path, mode, reclen, rectot)
+{
+ path = rd["path"]
+ reclen = ("reclen" in rd) ? rd["reclen"] : filesize(path)
+ mode = rd["mode"]
+ rectot = _record_count(symbol, rd)
+
+ recnum = int(recnum)
+ if (recnum <= 0 || recnum > rectot) {
+ ERRNO = sprintf("record: %s: reference to non-existent record #%d", path, recnum)
+ return -1
+ }
+
+ if (! (recnum in symbol)) {
+ fseek(path, mode, (recnum - 1) * reclen, "SEEK_SET")
+ symbol[recnum] = fread(path, mode, reclen)
+ }
+ return 0
+}
+
+# _record_clear --- remove all records
+
+function _record_clear(symbol, rd,
+ path, mode)
+{
+ path = rd["path"]
+ mode = rd["mode"]
+ if (mode == "r") {
+ ERRNO = sprintf("record: cannot delete record from file `%s' opened only for reading", path)
+ return -1
+ }
+ ftruncate(path, mode, 0)
+ delete rd["reclen"]
+ return 0
+}
+
+# _record_delete --- delete a record from the file
+
+function _record_delete(symbol, rd, recnum,
+ path, mode, reclen, rectot)
+{
+ path = rd["path"]
+ reclen = ("reclen" in rd) ? rd["reclen"] : filesize(path)
+ mode = rd["mode"]
+
+ if (mode == "r") {
+ ERRNO = sprintf("record: cannot delete record from file `%s' opened only for reading", path)
+ return -1
+ }
+
+ recnum = int(recnum)
+ if (! ("reclen" in rd)) {
+ # entire file is record #1
+ ftruncate(path, mode, 0)
+ delete rd["reclen"]
+ return 0
+ }
+
+ sz = filesize(path)
+ rectot = int(sz / reclen)
+
+ recstart = (recnum - 1) * reclen
+ off = sz - (recstart + reclen)
+
+ fseek(path, mode, -off, "SEEK_END")
+ tmp = fread(path, mode, off)
+ fseek(path, mode, recstart, "SEEK_SET")
+ if (fwrite(path, mode, tmp) != length(tmp))
+ return -1
+ flush(path, mode)
+ ftruncate(path, mode, sz - reclen)
+
+ rd["rectot"] = rectot - 1
+ for (i = recnum + 1; i <= rectot; i++) {
+ if (i in symbol) {
+ symbol[i - 1] = symbol[i]
+ delete symbol[i]
+ }
+ }
+ return 0
+}
+
+# _record_store --- write a record to file
+
+function _record_store(symbol, rd, recnum,
+ path, mode, reclen, val)
+{
+ path = rd["path"]
+ reclen = ("reclen" in rd) ? rd["reclen"] : filesize(path)
+ mode = rd["mode"]
+
+ if (mode == "r") {
+ ERRNO = sprintf("record: cannot write to file `%s' opened only for reading", path)
+ return -1
+ }
+
+ recnum = int(recnum)
+ val = symbol[recnum]
+ if (! ("reclen" in rd)) {
+ # the entire file is record #1
+ if (reclen != 0)
+ ftruncate(path, mode, 0)
+ } else if (length(val) != reclen) {
+ ERRNO = sprintf("record: %s: invalid length for record #%d", path, recnum)
+ return -1
+ }
+
+ fseek(path, mode, (recnum - 1) * reclen, "SEEK_SET")
+ if (fwrite(path, mode, val) != length(val))
+ return -1
+ flush(path, mode)
+ return 0
+}
+
+# _record_fetchall --- retrieve all the records
+
+function _record_fetchall(symbol, rd,
+ path, mode, reclen, rectot, recnum)
+{
+ path = rd["path"]
+ reclen = ("reclen" in rd) ? rd["reclen"] : filesize(path)
+ mode = rd["mode"]
+ rectot = _record_count(symbol, rd)
+
+ if (rd["loaded"])
+ return 0
+ for (recnum = 1; recnum <= rectot; recnum++) {
+ if (! (recnum in symbol)) {
+ fseek(path, mode, (recnum - 1) * reclen, "SEEK_SET")
+ symbol[recnum] = fread(path, mode, reclen)
+ }
+ }
+ rd["loaded"] = 1
+ return 0
+}
+
+# _record_init --- initialization routine
+
+function _record_init(symbol, rd)
+{
+ if (! file_exists(rd["path"])) {
+ ERRNO = sprintf("record: cannot open file `%s' for reading", rd["path"])
+ return -1
+ }
+ return 0
+}
+
+# _record_fini --- cleanup routine
+
+function _record_fini(symbol, rd)
+{
+ fclose(rd["path"], rd["mode"])
+}
+
+# record --- bind an array to a file with fixed-length records
+
+function record(array, path, reclen, mode, rd)
+{
+ if (path == "") {
+ print "fatal: record: empty string value for filename" > "/dev/stderr"
+ exit(1)
+ }
+
+ # register our array routines
+ rd["init"] = "_record_init"
+ rd["fini"] = "_record_fini"
+ rd["count"] = "_record_count"
+ rd["exists"] = "_record_exists"
+ rd["lookup"] = "_record_lookup"
+ rd["delete"] = "_record_delete"
+ rd["store"] = "_record_store"
+ rd["clear"] = "_record_clear"
+ rd["fetchall"] = "_record_fetchall"
+
+ rd["path"] = path
+ if (reclen > 0)
+ rd["reclen"] = reclen
+ rd["mode"] = mode == "r+" ? "r+" : "r"
+
+ delete array
+ bind_array(array, rd)
+}
diff --git a/old-extension/sparr.c b/old-extension/sparr.c
new file mode 100644
index 00000000..a3d06e66
--- /dev/null
+++ b/old-extension/sparr.c
@@ -0,0 +1,163 @@
+/*
+ * sparr.c - Example of changing behavior of arrays in gawk.
+ * See testsparr.awk for usage.
+ */
+
+/*
+ * Copyright (C) 2012 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 3 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 "spec_array.h"
+
+int plugin_is_GPL_compatible;
+
+typedef struct {
+ int load_file;
+ NODE *filename;
+} sdata_t;
+
+/* install_array --- install an array in the symbol table */
+
+static NODE *
+install_array(const char *name)
+{
+ NODE *r;
+
+ r = lookup(name);
+ if (r == NULL)
+ r = install_symbol(estrdup(name, strlen(name)), Node_var_array);
+ switch (r->type) {
+ case Node_var_new:
+ r = force_array(r, false);
+ /* fall through */
+ case Node_var_array:
+ assoc_clear(r);
+ break;
+ default:
+ fatal(_("`%s' is not an array"), name);
+ }
+ return r;
+}
+
+/* fetch_SYS --- fetch routine for the array `SYS' */
+
+static NODE *
+fetch_SYS(NODE *symbol, NODE *subs, void *data)
+{
+ force_string(subs);
+ if (strcmp(subs->stptr, "time") == 0)
+ return do_strftime(0);
+ return NULL;
+}
+
+/* store_SYS --- store routine for the array `SYS' */
+
+static void
+store_SYS(NODE *symbol, NODE *subs, NODE *val, void *data)
+{
+ sdata_t *sd = (sdata_t *) data;
+
+ if (subs != NULL && val != NULL && val->type == Node_val) {
+ force_string(subs);
+ if (strcmp(subs->stptr, "readline") == 0) {
+ sd->load_file = true;
+ unref(sd->filename);
+ sd->filename = dupnode(val);
+ }
+ }
+}
+
+/* load_READLINE --- load routine for the array `READLINE' */
+
+static void
+load_READLINE(NODE *symbol, void *data)
+{
+ sdata_t *sd = (sdata_t *) data;
+ NODE *file, *tmp;
+ FILE *fp;
+ static char linebuf[BUFSIZ];
+ int i;
+ bool long_line = false;
+
+ if (! sd->load_file) /* non-existent SYS["readline"] or already loaded */
+ return;
+
+ file = sd->filename;
+ force_string(file);
+
+ if (file->stlen == 0)
+ return;
+
+ assoc_clear(symbol);
+
+ if ((fp = fopen(file->stptr, "r" )) == NULL) {
+ warning(_("READLINE (%s): %s"), file->stptr, strerror(errno));
+ return;
+ }
+
+ for (i = 1; fgets(linebuf, sizeof(linebuf), fp ) != NULL; i++) {
+ NODE **lhs;
+ size_t sz;
+
+ sz = strlen(linebuf);
+ if (sz > 0 && linebuf[sz - 1] == '\n') {
+ linebuf[sz - 1] = '\0';
+ sz--;
+ if (long_line) {
+ long_line = false;
+ i--;
+ continue;
+ }
+ } else if (long_line) {
+ i--;
+ continue;
+ } else {
+ if (do_lint)
+ lintwarn(_("file `%s' does not end in newline or line # `%d' is too long"),
+ file->stptr, i);
+ long_line = true;
+ }
+
+ tmp = make_number(i);
+ lhs = assoc_lookup(symbol, tmp);
+ unref(tmp);
+ unref(*lhs);
+ *lhs = make_string(linebuf, sz);
+ }
+ fclose(fp);
+ sd->load_file = false; /* don't load this file again */
+}
+
+/* dlload --- load this library */
+
+NODE *
+dlload(NODE *obj, void *dl)
+{
+ NODE *a1, *a2;
+ static sdata_t data;
+
+ a1 = install_array("SYS");
+ register_dyn_array(a1, fetch_SYS, store_SYS, & data);
+ a2 = install_array("READLINE");
+ register_deferred_array(a2, load_READLINE, & data);
+ return make_number((AWKNUM) 0);
+}
diff --git a/old-extension/spec_array.c b/old-extension/spec_array.c
new file mode 100644
index 00000000..34d15fc5
--- /dev/null
+++ b/old-extension/spec_array.c
@@ -0,0 +1,416 @@
+/*
+ * spec_array.c - Support for specialized associative arrays.
+ */
+
+/*
+ * Copyright (C) 2012, 2014 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 3 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 "spec_array.h"
+
+typedef struct spec_array {
+ Fetch_func_t fetch_func;
+ Store_func_t store_func;
+ Load_func_t load_func;
+ void *data;
+} array_t;
+
+/*
+ * The array_t structure is attached to the array itself without
+ * the necessity to maintain a list of symbols; this works only
+ * because there is just enough free space in the NODE strcture when
+ * the base array is str_array.
+ */
+
+#define SUPER(F) (*str_array_func[F ## _ind])
+
+
+/*
+ * deferred_array --- Deferred loading of array at run-time.
+ *
+ * The load routine takes two arguments, the array and
+ * a void * data:
+ *
+ * void load_func(NODE *array, void *data)
+ *
+ * Use register_deferred_array(array, load_func, void *data) to
+ * bind an array to the load routine.
+ */
+
+static NODE **deferred_array_init(NODE *, NODE *);
+static NODE **deferred_array_lookup(NODE *, NODE *);
+static NODE **deferred_array_exists(NODE *, NODE *);
+static NODE **deferred_array_remove(NODE *, NODE *);
+static NODE **deferred_array_clear(NODE *, NODE *);
+static NODE **deferred_array_list(NODE *, NODE *);
+static NODE **deferred_array_copy(NODE *, NODE *);
+static NODE **deferred_array_length(NODE *, NODE *);
+
+static afunc_t deferred_array_func[] = {
+ deferred_array_init,
+ (afunc_t) 0, /* typeof */
+ deferred_array_length,
+ deferred_array_lookup,
+ deferred_array_exists,
+ deferred_array_clear,
+ deferred_array_remove,
+ deferred_array_list,
+ deferred_array_copy,
+ null_afunc, /* dump */
+ (afunc_t) 0, /* store */
+};
+
+
+/* deferred_array_init --- called when array becomes empty, e.g: delete BOUND_ARRAY */
+
+static NODE **
+deferred_array_init(NODE *symbol, NODE *subs)
+{
+ if (symbol != NULL) {
+ array_t *av = (array_t *) symbol->xarray;
+ symbol->xarray = NULL; /* this is to avoid an assertion failure in null_array */
+ null_array(symbol); /* typeless empty array */
+ if (symbol->parent_array == NULL) {
+ /* main array */
+ symbol->array_funcs = deferred_array_func; /* restore type */
+ symbol->xarray = (NODE *) av;
+ } else if (av) /* sub-array */
+ efree(av);
+ }
+ return NULL;
+}
+
+/* deferred_array_length --- get the length of the array */
+
+static NODE **
+deferred_array_length(NODE *symbol, NODE *subs)
+{
+ static NODE *length_node;
+ array_t *av = (array_t *) symbol->xarray;
+ if (av) {
+ symbol->xarray = NULL;
+ (*av->load_func)(symbol, av->data);
+ symbol->xarray = (NODE *) av;
+ }
+ length_node = symbol;
+ return & length_node;
+}
+
+#define DEF_ARR(F) static NODE ** \
+deferred_array_##F(NODE *symbol, NODE *subs) \
+{ \
+ array_t *av = (array_t *) symbol->xarray; \
+ if (av) { \
+ symbol->xarray = NULL; \
+ (*av->load_func)(symbol, av->data); \
+ symbol->xarray = (NODE *) av; \
+ } \
+ return SUPER(a##F)(symbol, subs); \
+}
+
+/* the rest of the routines */
+
+DEF_ARR(exists)
+DEF_ARR(lookup)
+DEF_ARR(list)
+DEF_ARR(copy)
+
+#undef DEF_ARR
+
+/* deferred_array_remove --- remove the index from the array */
+
+static NODE **
+deferred_array_remove(NODE *symbol, NODE *subs)
+{
+ array_t *av = (array_t *) symbol->xarray;
+
+ (void) SUPER(aremove)(symbol, subs);
+ if (av) {
+ symbol->xarray = NULL;
+ (*av->load_func)(symbol, av->data);
+ symbol->xarray = (NODE *) av;
+ }
+ return NULL;
+}
+
+/* deferred_array_clear --- flush all the values in symbol[] */
+
+static NODE **
+deferred_array_clear(NODE *symbol, NODE *subs)
+{
+ array_t *av = (array_t *) symbol->xarray;
+
+ (void) SUPER(aclear)(symbol, subs);
+ if (av) {
+ symbol->xarray = NULL;
+ (*av->load_func)(symbol, av->data);
+ symbol->xarray = (NODE *) av;
+ }
+ return NULL;
+}
+
+
+/*
+ * dyn_array --- array with triggers for reading and writing
+ * an element.
+ *
+ * The fetch routine should expect three arguments, the array,
+ * the subscript and optional void * data. It should return the value
+ * if it exists or NULL otherwise.
+ *
+ * NODE *fetch_func(NODE *array, NODE *subs, void *data)
+ *
+ * The store routine must take an additional argument for the
+ * value. The value can be NULL if the specific element is
+ * removed from the array. The subscript (and the value) is NULL
+ * when the entire array is deleted.
+ *
+ * void store_func(NODE *array, NODE *subs, NODE *value, void *data)
+ *
+ * Use register_dyn_array(array, fetch_func, store_func, void *data) to
+ * bind an array to the fetch/store routine.
+ */
+
+
+static NODE **dyn_array_init(NODE *, NODE *);
+static NODE **dyn_array_lookup(NODE *, NODE *);
+static NODE **dyn_array_exists(NODE *, NODE *);
+static NODE **dyn_array_remove(NODE *, NODE *);
+static NODE **dyn_array_clear(NODE *, NODE *);
+static NODE **dyn_array_list(NODE *, NODE *);
+static NODE **dyn_array_copy(NODE *, NODE *);
+static NODE **dyn_array_store(NODE *, NODE *);
+
+static afunc_t dyn_array_func[] = {
+ dyn_array_init,
+ (afunc_t) 0, /* typeof */
+ null_length, /* length */
+ dyn_array_lookup,
+ dyn_array_exists,
+ dyn_array_clear,
+ dyn_array_remove,
+ dyn_array_list,
+ dyn_array_copy,
+ null_afunc, /* dump */
+ dyn_array_store,
+};
+
+/* dyn_array_init --- called when array becomes empty */
+
+static NODE **
+dyn_array_init(NODE *symbol, NODE *subs)
+{
+ if (symbol != NULL) {
+ array_t *av = (array_t *) symbol->xarray;
+ symbol->xarray = NULL;
+ null_array(symbol); /* typeless empty array */
+ if (symbol->parent_array == NULL) {
+ /* main array */
+ symbol->array_funcs = dyn_array_func; /* restore type */
+ symbol->xarray = (NODE *) av;
+ } else if (av) /* sub-array */
+ efree(av);
+ }
+ return NULL;
+}
+
+/* dyn_array_exists --- check if the SUBS exists */
+
+static NODE **
+dyn_array_exists(NODE *symbol, NODE *subs)
+{
+ NODE *r;
+ array_t *av = (array_t *) symbol->xarray;
+
+ if (av && av->fetch_func) {
+ symbol->xarray = NULL;
+ r = (*av->fetch_func)(symbol, subs, av->data);
+ symbol->xarray = (NODE *) av;
+ if (r != NULL) {
+ NODE **lhs;
+ lhs = SUPER(alookup)(symbol, subs);
+ unref(*lhs);
+ *lhs = r;
+ return lhs;
+ }
+ }
+
+ return SUPER(aexists)(symbol, subs);
+}
+
+/* dyn_array_lookup --- lookup SUBS and return a pointer to store its value */
+
+static NODE **
+dyn_array_lookup(NODE *symbol, NODE *subs)
+{
+ NODE **lhs;
+ NODE *r;
+ array_t *av = (array_t *) symbol->xarray;
+
+ lhs = SUPER(alookup)(symbol, subs);
+ if (av && av->fetch_func) {
+ symbol->xarray = NULL;
+ r = (*av->fetch_func)(symbol, subs, av->data);
+ symbol->xarray = (NODE *) av;
+ if (r != NULL) {
+ unref(*lhs);
+ *lhs = r;
+ }
+ }
+ return lhs;
+}
+
+/* dyn_array_store --- call the store routine after an assignment */
+
+static NODE **
+dyn_array_store(NODE *symbol, NODE *subs)
+{
+ array_t *av = (array_t *) symbol->xarray;
+
+ if (av && av->store_func) {
+ NODE **lhs;
+ lhs = SUPER(aexists)(symbol, subs);
+ symbol->xarray = NULL;
+ (*av->store_func)(symbol, subs, *lhs, av->data);
+ symbol->xarray = (NODE *) av;
+ }
+ return NULL;
+}
+
+/* dyn_array_remove --- remove the index from the array */
+
+static NODE **
+dyn_array_remove(NODE *symbol, NODE *subs)
+{
+ array_t *av = (array_t *) symbol->xarray;
+
+ (void) SUPER(aremove)(symbol, subs);
+ if (av && av->store_func) {
+ symbol->xarray = NULL;
+ (*av->store_func)(symbol, subs, NULL, av->data);
+ symbol->xarray = (NODE *) av;
+ }
+ return NULL;
+}
+
+/* dyn_array_clear --- flush all the values in symbol[] */
+
+static NODE **
+dyn_array_clear(NODE *symbol, NODE *subs)
+{
+ array_t *av = (array_t *) symbol->xarray;
+
+ (void) SUPER(aclear)(symbol, subs);
+ if (av && av->store_func) {
+ symbol->xarray = NULL;
+ (*av->store_func)(symbol, NULL, NULL, av->data);
+ symbol->xarray = (NODE *) av;
+ }
+ return NULL;
+}
+
+/* dyn_array_list --- return a list of items in symbol[] */
+
+static NODE **
+dyn_array_list(NODE *symbol, NODE *subs)
+{
+ return SUPER(alist)(symbol, subs);
+}
+
+/* dyn_array_copy --- duplicate the array */
+
+static NODE **
+dyn_array_copy(NODE *symbol, NODE *subs)
+{
+ return SUPER(acopy)(symbol, subs);
+}
+
+/* register_array_s --- attach the specified routine(s) to an array */
+
+static void
+register_array_s(NODE *symbol, Fetch_func_t fetch_func,
+ Store_func_t store_func, Load_func_t load_func, void *data)
+{
+ array_t *av;
+
+ if (symbol->type != Node_var_array)
+ fatal(_("register_array_s: argument is not an array"));
+
+ if (symbol->array_funcs == deferred_array_func
+ || symbol->array_funcs == dyn_array_func)
+ fatal(_("register_array_s: `%s' already is a deferred/dyn array"),
+ array_vname(symbol));
+
+ assoc_clear(symbol);
+ assert(symbol->xarray == NULL);
+ emalloc(av, array_t *, sizeof (array_t), "register_spec_array");
+ av->fetch_func = fetch_func;
+ av->store_func = store_func;
+ av->load_func = load_func;
+ av->data = data;
+ symbol->xarray = (NODE *) av;
+}
+
+/* register_deferred_array --- make the array to be loaded at run-time */
+
+void
+register_deferred_array(NODE *symbol, Load_func_t load_func, void *dq)
+{
+ if (! load_func)
+ fatal(_("register_deferred_array: null load function"));
+ register_array_s(symbol, 0, 0, load_func, dq);
+ symbol->array_funcs = deferred_array_func;
+}
+
+/* register_dyn_array --- attach read and write triggers to an array */
+
+void
+register_dyn_array(NODE *symbol, Fetch_func_t fetch_func,
+ Store_func_t store_func, void *dq)
+{
+ register_array_s(symbol, fetch_func, store_func, 0, dq);
+ symbol->array_funcs = dyn_array_func;
+}
+
+/* unregister_array_s --- un-special the array */
+
+void *
+unregister_array_s(NODE *symbol)
+{
+ void *data = NULL;
+ if (symbol->type != Node_var_array)
+ fatal(_("unregister_array_s: argument is not an array"));
+
+ if (symbol->array_funcs == dyn_array_func
+ || symbol->array_funcs == deferred_array_func
+ ) {
+ array_t *av;
+
+ av = (array_t *) symbol->xarray;
+ assert(av != NULL);
+ data = av->data;
+ efree(av);
+ symbol->array_funcs = str_array_func;
+ symbol->xarray = NULL;
+ /* FIXME: do we assoc_clear the array ? */
+ }
+ return data;
+}
diff --git a/profile_p.c b/old-extension/spec_array.h
index 97edd367..f75fc7ce 100644
--- a/profile_p.c
+++ b/old-extension/spec_array.h
@@ -1,9 +1,5 @@
/*
- * profile_p.c - compile profile.c with profiling turned on.
- */
-
-/*
- * Copyright (C) 2001 the Free Software Foundation, Inc.
+ * Copyright (C) 2012 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -23,5 +19,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#define PROFILING 1
-#include "profile.c"
+
+typedef NODE *(*Fetch_func_t)(NODE *, NODE *, void *);
+typedef void(*Store_func_t)(NODE *, NODE *, NODE *, void *);
+typedef void(*Load_func_t)(NODE *, void *);
+extern void register_dyn_array(NODE *, Fetch_func_t, Store_func_t, void *);
+extern void register_deferred_array(NODE *, Load_func_t, void *);
+extern void *unregister_array_s(NODE *);
diff --git a/old-extension/steps b/old-extension/steps
new file mode 100755
index 00000000..3e8070d6
--- /dev/null
+++ b/old-extension/steps
@@ -0,0 +1,10 @@
+# what to do under linux to make dl.so
+# Sun Nov 25 21:40:49 IST 2012
+
+gcc -fPIC -shared -Wall -DGAWK -DHAVE_CONFIG_H -c -O -g -I.. spec_array.c
+gcc -fPIC -shared -Wall -DGAWK -DHAVE_CONFIG_H -c -O -g -I.. sparr.c
+gcc -fPIC -shared -Wall -DGAWK -DHAVE_CONFIG_H -c -O -g -I.. bindarr.c
+gcc -fPIC -shared -Wall -DGAWK -DHAVE_CONFIG_H -c -O -g -I.. fileop.c
+gcc -o sparr.so -shared sparr.o spec_array.o
+gcc -o bindarr.so -shared bindarr.o
+gcc -o fileop.so -shared fileop.o
diff --git a/old-extension/testdbarray.awk b/old-extension/testdbarray.awk
new file mode 100644
index 00000000..fd7fd595
--- /dev/null
+++ b/old-extension/testdbarray.awk
@@ -0,0 +1,21 @@
+@include "dbarray.awk"
+
+# $ ../gawk -f testdbarray.awk
+# $ ../gawk -f testdbarray.awk
+# ...
+# $ ../gawk -vINIT=1 -f testdbarray.awk
+
+
+BEGIN {
+ # bind array 'A' to the table 'table_A' in sqlite3 database 'testdb'
+ db_bind(A, "testdb", "table_A")
+
+ if (INIT) # detele table and start over
+ delete A
+
+ lenA = length(A)
+ A[++lenA] = strftime()
+ PROCINFO["sorted_in"] = "@ind_num_asc"
+ for (item in A)
+ print item, ":", A[item]
+}
diff --git a/old-extension/testrecord.sh b/old-extension/testrecord.sh
new file mode 100755
index 00000000..61d1ba76
--- /dev/null
+++ b/old-extension/testrecord.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+AWK=../gawk
+$AWK 'BEGIN { OFS = ORS = ""; for (j = 1; j <= 4; j++) for (i = 1; i <= 16; i++) print j}' > _rec.in
+for i in 1 2 3 4 5
+do
+$AWK -f record.awk -vinfile='_rec.in' -e 'BEGIN {
+reclen = 16
+record(r, infile, reclen, "r+")
+FIELDWIDTHS="8 4 4"
+for (i = 1; i in r; i++) {
+ $0 = r[i]
+ print $1
+}
+delete r[1]
+unbind_array(r)
+print "--" }'
+done
+rm -f _rec.in
diff --git a/old-extension/testsparr.awk b/old-extension/testsparr.awk
new file mode 100644
index 00000000..a9e3119d
--- /dev/null
+++ b/old-extension/testsparr.awk
@@ -0,0 +1,18 @@
+# ../gawk -lsparr -f testsparr.awk
+BEGIN {
+ extension("./sparr.so")
+ print SYS["time"]
+ SYS["readline"] = "sparr.c";
+ printf("File %s has %d lines\n", SYS["readline"], length(READLINE))
+ SYS["readline"] = "testsparr.awk";
+ printf("File %s has %d lines\n", SYS["readline"], length(READLINE))
+ for (i = 1; i in READLINE; i++)
+ print READLINE[i]
+
+ system("sleep 1")
+
+# PROCINFO["/dev/stdin", "READ_TIMEOUT"] = 1000
+# getline < "/dev/stdin"
+
+ print SYS["time"]
+}
diff --git a/pc/ChangeLog b/pc/ChangeLog
index 9f56a20d..218621eb 100644
--- a/pc/ChangeLog
+++ b/pc/ChangeLog
@@ -1,4 +1,407 @@
-2011-10-27 Scott Deifik <scottd.mail@sbcglobal.net>
+2014-11-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.tst (id): Add an 'expect to fail for DJGPP' message.
+
+2014-11-13 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * Makefile.tst: Sync with mainline.
+
+2014-10-12 KO Myung-Hun <komh78@gmail.com>
+
+ Fixes for OS/2:
+
+ * gawkmisc.pc (init_sockets): Add additional checks for __EMX__.
+
+2014-09-23 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * Makefile.tst: Sync with mainline.
+
+2014-04-17 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * Makefile.tst: Add readfile2 test.
+
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.1: Release tar ball made.
+
+2014-02-03 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * Makefile.tst: Include original test/Makefile.in lines as
+ comments.
+
+2014-01-28 Eli Zaretskii <eliz@gnu.org>
+
+ * Makefile.tst (strftime): Pass the value of 'date' command
+ through the DATECMD variable.
+ (readdir): Adapt to changes in test/readdir0.awk.
+
+2014-01-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.tst (mbprintf4, backbigs1, backsmalls1): Add warning
+ that the tests are expected to fail with DJGPP.
+
+2014-01-24 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * Makefile.tst: Sync with mainline.
+
+2014-01-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.tst (split_after_fpat, mpfrnegzero): Added, to
+ sync with main test Makefile.
+
+2014-01-15 Eli Zaretskii <eliz@gnu.org>
+
+ * Makefile.tst (mbprintf4, profile5, backbigs1, backsmalls1):
+ Announce expected failures.
+ (fts): Fail gracefully, to avoid bailing out of the test suite too
+ early.
+
+ * popen.c (os_system): Use spawnl, and quote the command line, to
+ be consistent with what gawk_popen does.
+ (os_popen) [__MINGW32__]: Don't scriptify the command, to be
+ consistent with gawk_popen.
+ (os_pclose) [__MINGW32__]: Update to match os_open: no need to
+ unlink the script file.
+
+2013-12-10 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * gawkmisc.c (init_sockets): Move into the right part of the
+ file so that it will be compiled for DJGPP also.
+ * Makefile.tst: Sync with mainline.
+
+2013-06-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.c (init_sockets): Rearrange ifdefs.
+
+2013-06-01 Eli Zaretskii <eliz@gnu.org>
+
+ * popen.h (SIGKILL) [__MINGW32__]: Define.
+ (kill, quote_cmd): New prototypes.
+
+ * popen.c: Include popen.h and errno.h.
+ (popen, pclose, system): Undefine macros.
+ (WIN32_LEAN_AND_MEAN) [__MINGW32__]: Define and include windows.h.
+ (kill, quote_cmd) [!PIPES_SIMULATED]: New functions.
+ (os_popen): Make the function definition match its prototype
+ exactly.
+
+ * gawkmisc.pc [HAVE_SOCKETS]: Include socket.h and windows.h.
+ (socket, setsockopt, bind, connect, listen, accept, recvfrom)
+ (shutdown): Undefine macros.
+ (os_close_on_exec) [__MINGW32__]: Non-trivial implementation.
+ (init_sockets, socket_to_fd, w32_socket, w32_setsockopt)
+ (w32_bind, w32_connect, w32_listen, w32_accept, valid_socket)
+ (w32_closesocket, w32_recvfrom, w32_shutdown) [HAVE_SOCKETS]: New
+ functions for MinGW, emulate Posix sockets specified by file
+ descriptors.
+
+ * config.h (HAVE_GETADDRINFO, HAVE_SOCKADDR_STORAGE)
+ (HAVE_SOCKETS) [__MINGW32__]: Define.
+
+ * config.sed (HAVE_GETADDRINFO, HAVE_SOCKADDR_STORAGE)
+ (HAVE_SOCKETS) [__MINGW32__]: Define.
+
+ * Makefile.tst (fmtspcl): Announce expected failure only if not
+ built with MPFR.
+ (inetecht, inetdayt): For MinGW, warn about time-outs.
+ (beginfile1, clos1way, getlndir): Announce expected failure only
+ with DJGPP.
+ (exit): Describe the failure on MinGW.
+ (readdir): Explain why test might fail with bad ls.exe.
+
+ * Makefile (mingw32, mingw32-readline, mingw32-mpfr)
+ (mingw32-readline-mpfr): Add -lws2_32 to the link flags.
+ (gawkmisc$O): Depend on socket.h.
+ (io$O): Depend on socket.h and in.h.
+ (popen$O): New dependency.
+
+2013-05-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * config.h: Remove obsolete HAVE_ST_BLKSIZE.
+
+2013-05-14 Eli Zaretskii <eliz@gnu.org>
+
+ * Makefile.tst (AWK): Set AWKLIBPATH so extensions could be found.
+ (LS): New variable.
+ (check): Add back shlib-tests and shlib-msg-end.
+ (readdir): Add a warning regarding inode reporting by ls.exe.
+ (fts, fork, fork2): Add message about expected failure on MinGW.
+
+ * Makefile (install): Install the extensions.
+ (install-strip): Likewise.
+
+ * Makefile.ext: New file.
+
+2013-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.0: Release tar ball made.
+
+2013-05-09 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * Makefile.tst: Sync with mainline.
+
+2013-05-05 Eli Zaretskii <eliz@gnu.org>
+
+ * config.sed (HAVE_MPFR): Don't #undef; it will be defined by
+ pc/Makefile as needed.
+
+2013-05-04 Eli Zaretskii <eliz@gnu.org>
+
+ * config.h (HAVE_MPFR): Don't #undef; it will be defined by
+ pc/Makefile as needed.
+
+2013-05-02 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * Makefile.tst: Sync with mainline.
+
+2013-04-29 Eli Zaretskii <eliz@gnu.org>
+
+ * Makefile.tst (mpfr-tests, shlib-tests, rsnulbig, rsnulbig2):
+ Insert a space between ' and the following / to prevent MSYS Bash
+ from interpreting that as a Unix-style file name.
+
+2013-04-28 Eli Zaretskii <eliz@gnu.org>
+
+ * Makefile.tst (top_srcdir): Define. This avoids failure in a few
+ tests that use this variable.
+ (testext): Prepend a space before the /regexp/ argument, to
+ prevent MSYS Bash mistaking this for an absolute file name that
+ needs to be converted to the Windows D:/foo/bar form, which fails
+ the test.
+ (check): Remove the shlib tests from 'check', so that they are not
+ run by default, because the extensions are not yet built
+ automatically.
+
+2013-04-22 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * Makefile.tst: Sync with mainline.
+
+2013-04-14 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * Makefile.tst: Sync with mainline.
+
+2013-03-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * config.h: Update by manually running make-config.bat steps.
+
+2013-03-10 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * Makefile: Sync with mainline.
+
+2013-03-04 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * Makefile: Build additional C source files.
+
+2013-03-04 Eli Zaretskii <eliz@gnu.org>
+
+ * config.sed: Fixes to build on DJGPP.
+
+2013-02-09 Eli Zaretskii <eliz@gnu.org>
+
+ * gawkmisc.pc (dlopen, dlerror, dlclose, dlsym) [DYNAMIC]: New
+ functions for _WIN32 build.
+
+ * dlfcn.h: New file.
+
+ * Makefile (pkgextensiondir, DEFLIBPATH, SHLIBEXT): New variables.
+ (AWKOBJS4): New sub-list of object files; add gawkapi$O.
+ (ALLOBJS): Include AWKOBJS4.
+ (CFLAGS): Add -DDEFLIBPATH=$(DEFLIBPATH) -DSHLIBEXT=$(SHLIBEXT).
+
+ * config.sed (DYNAMIC): Define for _WIN32 build.
+
+2013-02-07 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * Makefile.tst: Sync with mainline.
+
+2013-01-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * config.h: Version bumped.
+
+2012-12-28 Eli Zaretskii <eliz@gnu.org>
+
+ * Makefile (install1): Don't require a Unixy shell and Sed. Don't
+ edit igawk.bat to point to the igawk script in $(prefix)/bin, as
+ that directory should be on PATH when Gawk is installed. Create
+ $(prefix)/bin/awk.exe, to emulate a symlink created on Unix.
+ Install documentation in $(prefix)/share. Install gawkinet.info.
+ (install-strip): New target.
+
+ * install.awk: Install documentation in $prefix/share.
+
+2012-12-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.2: Release tar ball made.
+
+2012-12-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.tst (paramuninitglobal): New test.
+
+2012-11-22 Eli Zaretskii <eliz@gnu.org>
+
+ * Makefile.tst (jarebug): Update.
+ (GREP_OPTIONS): Add.
+
+2012-11-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.pc (os_isreadable): Use correct type for first parameter.
+
+2012-11-04 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * Makefile.tst (jarebug, charasbytes): Update.
+
+2012-10-28 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * Makefile.tst: Sync with mainline version.
+
+2012-10-28 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.pc (messages): Adjust to use standard failure test for
+ make diffout.
+
+2012-08-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.pc (os_isreadable): Take IOBUF_PUBLIC instead of fd and
+ use passed in info.
+
+2012-07-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.pc (os_isreadable): Add isdir pointer parameter to be
+ set to true if fd is for a directory.
+
+2012-07-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.pc (os_isreadable): New function.
+
+2012-05-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile: Remove second mingw32-readline target. Bad
+ result from branch merging.
+
+2012-05-06 Eli Zaretskii <eliz@gnu.org>
+
+ * config.sed: Update DJGPP -> __DJGPP__.
+
+2012-04-16 Eli Zaretskii <eliz@gnu.org>
+
+ * Makefile.tst (PGAWK): Redefine as "../gawk.exe -p".
+ (MPFR_TESTS): New variable, a list of MPFR-related tests.
+ (mpfr-tests): A new target.
+ (badargs): Reset GREP_OPTIONS to empty, to avoid gratuitous
+ failures when the user has something like -nH there.
+ (mpfrieee, mpfrexprange, mpfrrnd, mpfrnr, mpfrsort, mpfrbigint):
+ New tests.
+
+ * Makefile (default): Add descriptions of mingw32-mpfr and
+ mingw32-libreadline-mpfr targets.
+ (PRSPFILE, DRSPFILE, PRSP, DRSP, PLDRSP, DLDRSP, DO_PLNK)
+ (DO_PBIND, DO_DLNK, DO_DBIND, PLDJG, DLDJG, PLMINGW32)
+ (DLMINGW32, PAWKOBJS1, PAWKOBJS2, DAWKOBJS2, PGAWKOBJS)
+ (DGAWKOBJS): Remove unused variables.
+ (djgpp, djgpp-debug, mingw32): Don't use them.
+ (mingw32): Add -D__USE_MINGW_ANSI_STDIO to compilation flags.
+ (mingw32-readline, mingw32-mpfr, mingw32-readline-mpfr): New targets.
+ (CFLAGS, AWKOBJS2): Don't reference obsolete DYN_FLAGS and DYN_OBJ
+ variables.
+ (AWKOBJS2): Add symbol$O.
+ (AWKOBJS3): New variable, lists MPFR-related object files.
+ (AWKOBJS): Add $(AWKOBJS3).
+ (all): Remove pgawk.exe and dgawk.exe.
+ (pgawk.exe, dgawk.exe, $(PRSPFILE) $(DRSPFILE), eval_p$O)
+ (profile_p$O): Remove targets.
+ (random$O, debug$O): Don't depend on floatmagic.h
+ (eval$O): Depend on interpret.h.
+ (clean): Prepend '-' to command line, to ignore errors due to
+ non-existent files.
+
+ * config.h: Comment out "#undef HAVE_LIBREADLINE" (again).
+
+2012-03-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * config.h: Add definition for _Noreturn.
+
+2012-03-20 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkmisc.pc (deflibpath): New global variable.
+
+2012-03-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.1: Release tar ball made.
+
+2012-03-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.tst (printfbad3): New test.
+
+2012-03-14 Eli Zaretskii <eliz@gnu.org>
+
+ * gawkmisc.pc (btowc): New version for DJGPP.
+
+2012-03-01 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * Makefile.tst: Sync with mainline version.
+
+2012-03-01 Eli Zaretskii <eliz@gnu.org>
+
+ * Makefile: Quiet confusing info messages from the linker when
+ gawk is linked against readline as a shared library.
+
+2012-02-22 Eli Zaretskii <eliz@gnu.org>
+
+ * Makefile.tst: Update CMP and CP definitions, add "Expect xxxx to
+ fail with MinGW" messages as needed.
+
+2012-02-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.pc (execvp): Modify signature, return -1
+ on error.
+
+2012-02-11 Eli Zaretskii <eliz@gnu.org>
+
+ Fix dependencies in pc/Makefile.
+ * Makefile ($(ALLOBJS) $(LIBOBJS) eval_p$O profile_p$O): Add eval_d$O,
+ debug$O, and command$O.
+
+ Support MinGW build with the readline library.
+ * Makefile (default): Add a line for the mingw32-readline target.
+ (mingw32-readline): New target, passes -DHAVE_LIBREADLINE to the
+ compiler and adds -lreadline to the linker command line.
+
+ * config.sed: Comment out "#undef HAVE_LIBREADLINE", so that it
+ could be #define'd on the compiler command line.
+
+2012-02-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.pc (execvp): New function based on code from Eli
+ Zaretskii to make dgawk's restarting the debugger work.
+
+2012-01-27 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * Makefile.tst: Sync with mainline version.
+
+2011-12-12 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * Makefile.tst: Sync with mainline version.
+
+2011-12-06 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * Makefile.tst: Sync with mainline version.
+ Use testoutcmp.awk script.
+
+2011-12-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testoutcmp.awk: Script to replace cmd for DJGPP.
+
+2011-11-01 Scott Deifik <scottd.mail@sbcglobal.net>
+
+ * config.sed: Additional update.
+
+2011-10-29 Eli Zaretskii <eliz@gnu.org>
+
+ * config.sed: Fix some edits, to be consistent with the old
+ config.h file. Make regexps match #undef lines with whitespace
+ at the end of the line. Add forgotten EMX #defines.
+
+2011-10-27 Scott Deifik <scottd.mail@sbcglobal.net>
* Makefile.tst: Sync with mainline version.
diff --git a/pc/Makefile b/pc/Makefile
index 6156ce96..d1c08069 100644
--- a/pc/Makefile
+++ b/pc/Makefile
@@ -6,6 +6,17 @@
# Tested with GNU make on Windows, OS/2 and DOS.
+# Copyright (C) 1989-2014 Free Software Foundation, Inc.
+
+# This Makefile 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.
+
default:
@echo "Enter $(MAK) target "
@echo " where 'target' is chosen from "
@@ -14,6 +25,11 @@ default:
@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 " mingw32-readline . Like mingw32, but with readline "
+ @echo " [You will need to have GNU readline library installed.] "
+ @echo " mingw32-mpfr . Like mingw32, but with MPFR "
+ @echo " [You will need to have GNU MPFR library installed.] "
+ @echo " mingw32-readline-mpfr . mingw32 with readline and MPFR "
@echo " ----------------------------------------------------- "
@echo " test .... Perform tests (see README_d/README.pc) "
@echo " install . Install gawk under $(prefix)/ "
@@ -37,8 +53,6 @@ default:
#======================= Configuration ==================================
RSPFILE = gawk.rsp
-PRSPFILE = pgawk.rsp
-DRSPFILE = dgawk.rsp
#
# Choose method for passing arguments to the linker.
#
@@ -48,11 +62,7 @@ DRSPFILE = dgawk.rsp
#
# else use brain-dead approach (emxbnd will need 'tr').
RSP = $(RSPFILE)
-PRSP = $(PRSPFILE)
-DRSP = $(DRSPFILE)
LDRSP = @$(RSP)
-PLDRSP = @$(PRSP)
-DLDRSP = @$(DRSP)
LNKRSP = $(LDRSP)
#------------------------------------------------------------------------
# Some makes do not define MAKE (and ndmake does not allow a define).
@@ -69,19 +79,18 @@ MAK = $(MAKE) $(MAKEFILE)
#prefix =
prefix = c:/gnu
pkgdatadir = $(prefix)/lib/awk
+pkgextensiondir = $(prefix)/lib/gawk
+DEFLIBPATH = "\"$(pkgextensiondir)\""
+SHLIBEXT = "\"dll\""
#
-# Define the install method. Method 1 is Unix-like (and requires cat,
-# cp, mkdir, sed, and sh); method 2 uses gawk and batch files.
+# Define the install method. Method 1 is Unix-like (and requires cat
+# and cp); method 2 uses gawk and batch files.
install = 1
#------------------------------------------------------------------------
# To work around command-line length problems, this makefile assumes
# that $($X) can be expanded.
DO_LNK = $($(LNK))
DO_BIND= $($(BIND))
-DO_PLNK = $($(PLNK))
-DO_PBIND= $($(PBIND))
-DO_DLNK = $($(DLNK))
-DO_DBIND= $($(DBIND))
#========================================================================
# End of general configuration. Some platform-specific configuration
# notes appear below.
@@ -95,21 +104,19 @@ prefix = $(DJDIR)
pkgdatadir = $(prefix)/share/awk
endif
LDJG = $(CC) $(LF) -o gawk.exe $(LDRSP) $(LF2)
-PLDJG = $(CC) $(LF) -o pgawk.exe $(PLDRSP) $(LF2)
-DLDJG = $(CC) $(LF) -o dgawk.exe $(DLDRSP) $(LF2)
BDJG = stubify -g awk.exe | stubedit awk.exe runfile=gawk
djgpp:
$(MAK) all \
CC=gcc O=.o CF=-O2 \
- LNK=LDJG PLNK=PLDJG DLNK=DLDJG LF=-s LF2=-lm \
- BIND=BDJG PBIND='' DBIND=''
+ LNK=LDJG LF=-s LF2=-lm \
+ BIND=BDJG
djgpp-debug:
$(MAK) all \
CC=gcc O=.o CF='-O2 -g' \
- LNK=LDJG PLNK=PLDJG DLNK=DLDJG LF2=-lm \
- BIND=BDJG PBIND='' DBIND=''
+ LNK=LDJG LF2=-lm \
+ BIND=BDJG
#========================================================================
#========================== EMX =========================================
@@ -156,34 +163,49 @@ emxbnd-debug:
#========================================================================
LMINGW32 = $(CC) $(LF) -o $@ $(GAWKOBJS) $(LF2)
-PLMINGW32 = $(CC) $(LF) -o $@ $(PGAWKOBJS) $(LF2)
-DLMINGW32 = $(CC) $(LF) -o $@ $(DGAWKOBJS) $(LF2)
# The following might work around command-line length limitations:
#LMINGW32 = $(CC) $(LF) -o $@ *.o $(LF2)
mingw32:
$(MAK) all \
- CC=gcc O=.o CF="-O2 -gdwarf-2 -g3" OBJ=popen.o \
- LNK=LMINGW32 PLNK=PLMINGW32 DLNK=DLMINGW32 \
- LF="-gdwarf-2 -g3" LF2=-lmsvcp60 RSP=
+ CC=gcc O=.o CF="-D__USE_MINGW_ANSI_STDIO -O2 -gdwarf-2 -g3" \
+ OBJ=popen.o LNK=LMINGW32 LF="-gdwarf-2 -g3" \
+ LF2="-lws2_32 -lmsvcp60" RSP=
+
+mingw32-readline:
+ $(MAK) all \
+ CC=gcc O=.o \
+ CF="-D__USE_MINGW_ANSI_STDIO -DHAVE_LIBREADLINE -O2 -gdwarf-2 -g3" \
+ OBJ=popen.o LNK=LMINGW32 LF="-gdwarf-2 -g3" \
+ LF2="-lreadline -lws2_32 -lmsvcp60 -Wl,--enable-auto-import" RSP=
+
+mingw32-mpfr:
+ $(MAK) all \
+ CC=gcc O=.o \
+ CF="-D__USE_MINGW_ANSI_STDIO -DHAVE_MPFR -O2 -gdwarf-2 -g3" \
+ OBJ=popen.o LNK=LMINGW32 LF="-gdwarf-2 -g3" \
+ LF2="-lmpfr -lgmp -lws2_32 -lmsvcp60 -Wl,--enable-auto-import" RSP=
+
+mingw32-readline-mpfr:
+ $(MAK) all \
+ CC=gcc O=.o \
+ CF="-D__USE_MINGW_ANSI_STDIO -DHAVE_LIBREADLINE -DHAVE_MPFR -O2 -gdwarf-2 -g3" \
+ OBJ=popen.o LNK=LMINGW32 LF="-gdwarf-2 -g3" \
+ LF2="-lmpfr -lgmp -lreadline -lws2_32 -lmsvcp60 -Wl,--enable-auto-import" RSP=
# 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)
+CFLAGS = $(CF) -DGAWK -I. -DHAVE_CONFIG_H -DDEFLIBPATH=$(DEFLIBPATH) -DSHLIBEXT=$(SHLIBEXT)
# object files
AWKOBJS1 = array$O builtin$O eval$O field$O floatcomp$O gawkmisc$O io$O main$O
-AWKOBJS2 = ext$O msg$O node$O profile$O re$O replace$O version$O $(DYN_OBJ)
-PAWKOBJS1 = array$O builtin$O eval_p$O field$O floatcomp$O gawkmisc$O io$O main$O
-PAWKOBJS2 = ext$O msg$O node$O profile_p$O re$O replace$O version$O $(DYN_OBJ)
-DAWKOBJS1 = array$O builtin$O debug$O eval_d$O field$O floatcomp$O gawkmisc$O io$O main$O
-DAWKOBJS2 = ext$O msg$O node$O profile$O re$O replace$O version$O command$O $(DYN_OBJ)
-AWKOBJS = $(AWKOBJS1) $(AWKOBJS2)
+AWKOBJS2 = ext$O msg$O node$O profile$O re$O replace$O version$O symbol$O
+AWKOBJS3 = debug$O cint_array$O int_array$O mpfr$O str_array$O command$O
+AWKOBJS4 = gawkapi$O
+AWKOBJS = $(AWKOBJS1) $(AWKOBJS2) $(AWKOBJS3) $(AWKOBJS4)
ALLOBJS = $(AWKOBJS) awkgram$O getid$O $(OBJ)
@@ -192,8 +214,6 @@ ALLOBJS = $(AWKOBJS) awkgram$O getid$O $(OBJ)
LIBOBJS= getopt$O getopt1$O dfa$O regex$O random$O
GAWKOBJS = $(ALLOBJS) $(LIBOBJS)
-PGAWKOBJS = $(PAWKOBJS1) $(PAWKOBJS2) $(LIBOBJS) awkgram$O getid$O $(OBJ)
-DGAWKOBJS = $(DAWKOBJS1) $(DAWKOBJS2) $(LIBOBJS) awkgram$O getid$O $(OBJ)
# clear out suffixes list
# .SUFFIXES:
@@ -203,33 +223,17 @@ DGAWKOBJS = $(DAWKOBJS1) $(DAWKOBJS2) $(LIBOBJS) awkgram$O getid$O $(OBJ)
$(CC) -c $(CFLAGS) $<
# rules to build gawk
-all : gawk.exe pgawk.exe dgawk.exe
+all : gawk.exe
gawk.exe:: $(GAWKOBJS) $(RSP)
$(DO_LNK)
$(DO_BIND)
-pgawk.exe:: $(PGAWKOBJS) $(PRSP)
- $(DO_PLNK)
- $(DO_PBIND)
-
-dgawk.exe:: $(DGAWKOBJS) $(DRSP)
- $(DO_DLNK)
- $(DO_DBIND)
-
$(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 >> $@
-
-$(DRSPFILE) : $(DGAWKOBJS)
- echo $(DAWKOBJS1)$P > $@
- echo $(DAWKOBJS2)$P >> $@
+ echo $(AWKOBJS3)$P >> $@
+ echo $(AWKOBJS4)$P >> $@
echo awkgram$O getid$O $(OBJ) $(LIBOBJS)$P >> $@
# Notes to dependencies:
@@ -237,30 +241,28 @@ $(DRSPFILE) : $(DGAWKOBJS)
# and we have -I. on the compiler command line. unistd.h is
# included by awk.h.
# 2. custom.h is not mentioned because pc ports don't use it.
-$(ALLOBJS) $(LIBOBJS) eval_p$O profile_p$O: \
+$(ALLOBJS) $(LIBOBJS): \
awk.h regex.h config.h gettext.h mbsupport.h protos.h dfa.h getopt.h
builtin$O: floatmagic.h random.h popen.h
-random$O: floatmagic.h random.h
+random$O: random.h
-debug$O: floatmagic.h
+node$O: floatmagic.h
command$O debug$O: cmd.h
-dfa$O: xalloc.h
+dfa$O: xalloc.h
-gawkmisc$O: pc/gawkmisc.pc
+gawkmisc$O: pc/gawkmisc.pc socket.h
getopt$O getopt1$O : getopt_int.h
-io$O: popen.h
+io$O: popen.h socket.h in.h
regex$O: regcomp.c regexec.c regex_internal.h
-eval_p$O: eval.c
-
-profile_p$O: profile.c
+eval$O: interpret.h
# A bug in ndmake requires the following rule
awkgram$O: awk.h awkgram.c
@@ -271,27 +273,37 @@ awkgram.c: awkgram.y
alloca$O: alloca.c
+popen$O: popen.h
install: install$(install)
+ -$(MAKE) -C extension install-extensions
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 $(pkgdatadir) $(prefix)/man/man1 $(prefix)/info
+ cat pc/awklib/igawk.bat > igawk.bat
+ -mkdir "$(prefix)"
+ -mkdir "$(prefix)/bin"
+ -mkdir "$(prefix)/share"
+ -mkdir "$(prefix)/share/man"
+ -mkdir "$(pkgdatadir)" "$(prefix)/share/man/man1" "$(prefix)/share/info"
cp *awk.exe igawk.bat igawk.cmd pc/awklib/igawk $(prefix)/bin
+ cp gawk.exe $(prefix)/bin/awk.exe
cp awklib/eg/lib/* pc/awklib/igawk.awk $(pkgdatadir)
- cp doc/*.1 $(prefix)/man/man1
- cp doc/gawk.info $(prefix)/info
+ cp doc/*.1 $(prefix)/share/man/man1
+ cp doc/*.info $(prefix)/share/info
# install2 is equivalent to install1, but doesn't require cp, sed, etc.
install2:
gawk -v prefix=$(prefix) -f install.awk
+install-strip: install$(install)
+ strip "$(prefix)/bin"/*.exe
+ -$(MAKE) -C extension $@
+
clean:
- rm -rf gawk pgawk dgawk *.exe gawk.map *.o *.obj core a.out $(RSPFILE) $(PRSPFILE) $(DRSPFILE) $(DYN_EXP)
+ -rm -rf gawk *.exe gawk.map *.o *.obj core a.out $(RSPFILE) $(PRSPFILE) $(DRSPFILE) $(DYN_EXP)
# cd doc && $(MAKE) clean
# cd test && $(MAKE) clean
# cd awklib && $(MAKE) clean
diff --git a/pc/Makefile.ext b/pc/Makefile.ext
new file mode 100644
index 00000000..8971014b
--- /dev/null
+++ b/pc/Makefile.ext
@@ -0,0 +1,75 @@
+# extension/Makefile for the MinGW build
+#
+# Copyright (C) 2013 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.
+
+prefix = c:/gnu
+pkgdatadir = $(prefix)/lib/awk
+pkgextensiondir = $(prefix)/lib/gawk
+includedir = $(prefix)/include
+libdir = $(prefix)/lib
+datadir = $(prefix)/share
+pkgdatadir = $(datadir)/gawk-extensions
+pkgincludedir = $(includedir)/gawk-extensions
+pkglibdir = $(libdir)/gawk-extensions
+pkglibexecdir = $(libexecdir)/gawk-extensions
+
+SOEXT = dll
+SIMPLE_EXTENSIONS = inplace.$(SOEXT) ordchr.$(SOEXT) readfile.$(SOEXT)\
+ revoutput.$(SOEXT) revtwoway.$(SOEXT) testext.$(SOEXT)
+ALL_EXTENSIONS = filefuncs.$(SOEXT) fnmatch.$(SOEXT) inplace.$(SOEXT)\
+ ordchr.$(SOEXT) readdir.$(SOEXT) readfile.$(SOEXT) revoutput.$(SOEXT)\
+ revtwoway.$(SOEXT) rwarray.$(SOEXT) testext.$(SOEXT) time.$(SOEXT)
+
+extensions: $(ALL_EXTENSIONS)
+
+fnmatch.$(SOEXT): fnmatch.c
+ gcc -I.. -I../missing_d -DHAVE_FNMATCH_H -shared -gdwarf-2 -g3 -o $@ fnmatch.c
+
+readdir.$(SOEXT): readdir.c gawkdirfd.h
+ gcc -I.. -DHAVE_DIRENT_H -shared -gdwarf-2 -g3 -o $@ readdir.c
+
+rwarray.$(SOEXT): rwarray.c
+ gcc -I.. -shared -gdwarf-2 -g3 -o $@ rwarray.c -lws2_32
+
+filefuncs.$(SOEXT): filefuncs.c stack.c stack.h gawkfts.h
+ gcc -I.. -shared -gdwarf-2 -g3 -o $@ filefuncs.c stack.c
+
+time.$(SOEXT): time.c
+ gcc -DHAVE_GETSYSTEMTIMEASFILETIME -I.. -shared -gdwarf-2 -g3 -o $@ time.c
+
+$(SIMPLE_EXTENSIONS):
+ gcc -I.. -shared -gdwarf-2 -g3 -o $@ $(@:.$(SOEXT)=.c)
+
+$(ALL_EXTENSIONS): ../gawkapi.h ../gettext.h
+
+inplace.$(SOEXT): inplace.c
+ordchr.$(SOEXT): ordchr.c
+readfile.$(SOEXT): readfile.c
+revoutput.$(SOEXT): revoutput.c
+rwarray.$(SOEXT): rwarray.c
+testext.$(SOEXT): testext.c
+time.$(SOEXT): time.c
+
+# This must not be called 'install' because there's a file INSTALL,
+# and case-insensitive filesystems will gladly accept it.
+install-extensions:
+ -mkdir "$(pkgextensiondir)"
+ cp *.$(SOEXT) "$(pkgextensiondir)"
+ -mkdir "$(prefix)/share/man/man3"
+ cp *.3am "$(prefix)/share/man/man3"
+
+install-strip: install-extensions
+ strip --strip-unneeded "$(pkgextensiondir)"/*.$(SOEXT)
+
+clean:
+ -rm -f *.$(SOEXT)
+
diff --git a/pc/Makefile.tst b/pc/Makefile.tst
index e63b8eb5..79d01ad9 100644
--- a/pc/Makefile.tst
+++ b/pc/Makefile.tst
@@ -1,6 +1,6 @@
# Makefile for GNU Awk test suite.
#
-# Copyright (C) 1988-2011 the Free Software Foundation, Inc.
+# Copyright (C) 1988-2014 the Free Software Foundation, Inc.
#
# This file is part of GAWK, the GNU implementation of the
# AWK Programming Language.
@@ -60,14 +60,19 @@
SHELL = /bin/sh
# Point to gawk
-AWK = ../gawk.exe
+AWK = AWKLIBPATH=../extension $(AWKPROG)
# 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
+# Point $(LS) to a version of ls.exe that reports true Windows file
+# index numbers, because this is what the readdir test expects.
+# Otherwise, the readdir test will fail. (The MSYS ls.exe doesn't
+# report full index values.)
+LS = ls.exe
# Define PGAWK
-PGAWK = ../pgawk.exe
+PGAWK = ../gawk.exe -p
# 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).
@@ -86,17 +91,22 @@ PGAWK = ../pgawk.exe
#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 = diff
+CMP = diff -u
#CMP = gcmp
+# cmp replacement program for PC where the error messages aren't
+# exactly the same. Should run even on old awk.
+TESTOUTCMP = $(AWK) -f ../testoutcmp.awk
+
# Set your "cp," "mv," and "mkdir" commands here. Note: DOS's copy must take
# forward slashes.
-#CP = cp
+CP = cp
#CP = : && command -c copy
-CP = command.com /c copy
+#CP = command.com /c copy
MV = cmd.exe /c ren
+#MV = mv
#MKDIR = mkdir
#MKDIR = gmkdir
@@ -110,73 +120,98 @@ DATE = gdate
# MS-DOS and OS/2 use ; as a PATH delimiter
PATH_SEPARATOR = ;
+# Non-default GREP_OPTIONS might fail the badargs test
+export GREP_OPTIONS=
+
# ============================================================================
# You shouldn't need to modify anything below this line.
# ============================================================================
srcdir = .
+abs_srcdir = .
+abs_builddir = .
+top_srcdir = "$(srcdir)"/..
# Get rid of core files when cleaning and generated .ok file
CLEANFILES = core core.* fmtspcl.ok
-# try to keep these sorted
+# try to keep these sorted. each letter starts a new line
BASIC_TESTS = \
addcomma anchgsub argarray arrayparm arrayprm2 arrayprm3 \
arrayref arrymem1 arryref2 arryref3 arryref4 arryref5 arynasty \
arynocls aryprm1 aryprm2 aryprm3 aryprm4 aryprm5 aryprm6 aryprm7 \
- aryprm8 arysubnm asgext awkpath back89 backgsub childin clobber \
- closebad clsflnam compare compare2 concat1 concat2 concat3 \
- concat4 convfmt datanonl defref delargv delarpm2 delarprm delfunc \
- dfastress dynlj eofsplit exitval1 exitval2 fcall_exit fcall_exit2 \
- fldchg fldchgnf fnamedat fnarray fnarray2 fnaryscl fnasgnm fnmisc \
- fordel forref forsimp fsbs fsrs fsspcoln fstabplus funsemnl funsmnam \
- funstack getline getline2 getline3 getline4 \
- getlnbuf getnr2tb getnr2tm \
+ aryprm8 arysubnm asgext awkpath \
+ back89 backgsub badassign1 \
+ childin clobber closebad clsflnam compare compare2 concat1 concat2 \
+ concat3 concat4 convfmt \
+ datanonl defref delargv delarpm2 delarprm delfunc dfamb1 dfastress dynlj \
+ eofsplit exit2 exitval1 exitval2 \
+ fcall_exit fcall_exit2 fldchg fldchgnf fnamedat fnarray fnarray2 \
+ fnaryscl fnasgnm fnmisc fordel forref forsimp fsbs fsrs fsspcoln \
+ fstabplus funsemnl funsmnam funstack \
+ getline getline2 getline3 getline4 getline5 getlnbuf getnr2tb getnr2tm \
gsubasgn gsubtest gsubtst2 gsubtst3 gsubtst4 gsubtst5 gsubtst6 \
gsubtst7 gsubtst8 \
- hex hsprint inputred intest intprec iobug1 leaddig leadnl litoct \
- longsub longwrds manglprm math membug1 messages minusstr mmap8k \
- mtchi18n nasty nasty2 negexp negrange nested nfldstr nfneg \
- nfset nlfldsep nlinstr nlstrina noeffect nofile nofmtch noloop1 \
- noloop2 nonl noparms nors nulrsend numindex numsubstr octsub ofmt \
- ofmta ofmtbig ofmtfidl ofmts onlynl opasnidx opasnslf paramdup \
- paramres paramtyp parse1 parsefld parseme pcntplus posix2008sub \
- prdupval prec printf0 printf1 prmarscl prmreuse prt1eval prtoeval \
- rand range1 rebt8b1 redfilnm regeq regrange reindops reparse resplit \
- rs rsnul1nl rsnulbig rsnulbig2 rstest1 rstest2 rstest3 rstest4 \
- rstest5 rswhite scalar sclforin sclifin sortempty splitargv \
- splitarr splitdef splitvar splitwht strcat1 strnum1 strtod subamp \
- subi18n subsepnm subslash substr swaplns synerr1 synerr2 tradanch \
- tweakfld uninit2 uninit3 uninit4 uninit5 uninitialized unterm \
- uparrfs wideidx wideidx2 widesub widesub2 widesub3 widesub4 \
- wjposer1 zero2 zeroe0 zeroflag
+ hex hsprint \
+ inputred intest intprec iobug1 \
+ leaddig leadnl litoct longsub longwrds \
+ manglprm math membug1 messages minusstr mmap8k mtchi18n \
+ nasty nasty2 negexp negrange nested nfldstr nfloop nfneg nfset nlfldsep \
+ nlinstr nlstrina noeffect nofile nofmtch noloop1 noloop2 nonl \
+ noparms nors nulrsend numindex numsubstr \
+ octsub ofmt ofmta ofmtbig ofmtfidl ofmts ofs1 onlynl opasnidx opasnslf \
+ paramdup paramres paramtyp paramuninitglobal parse1 parsefld parseme \
+ pcntplus posix2008sub prdupval prec printf0 printf1 prmarscl prmreuse \
+ prt1eval prtoeval \
+ rand range1 rebt8b1 redfilnm regeq regexprange regrange reindops \
+ reparse resplit rri1 rs rsnul1nl rsnulbig rsnulbig2 rstest1 rstest2 \
+ rstest3 rstest4 rstest5 rswhite \
+ scalar sclforin sclifin sortempty splitargv splitarr splitdef \
+ splitvar splitwht strcat1 strnum1 strtod subamp subi18n \
+ subsepnm subslash substr swaplns synerr1 synerr2 tradanch tweakfld \
+ uninit2 uninit3 uninit4 uninit5 uninitialized unterm uparrfs \
+ wideidx wideidx2 widesub widesub2 widesub3 widesub4 wjposer1 \
+ zero2 zeroe0 zeroflag
UNIX_TESTS = \
- fflush getlnhd localenl pid pipeio1 pipeio2 poundbang rtlen rtlen01 \
- space strftlng
+ fflush getlnhd localenl pid pipeio1 pipeio2 poundbang \
+ rtlen rtlen01 space strftlng
GAWK_EXT_TESTS = \
aadelete1 aadelete2 aarray1 aasort aasorti argtest arraysort \
- backw badargs beginfile1 beginfile2 \
- binmode1 clos1way delsub devfd devfd1 \
- devfd2 dumpvars exit fieldwdth fpat1 fpat2 fpat3 \
- fpatnull fsfwfs funlen \
- fwtest fwtest2 fwtest3 \
- gensub gensub2 getlndir gnuops2 gnuops3 gnureops \
- icasefs icasers igncdym igncfs ignrcas2 ignrcase indirectcall lint \
- lintold lintwarn manyfiles match1 match2 match3 mbstr1 nastyparm \
- next nondec nondec2 patsplit posix printfbad1 printfbad2 procinfs \
- profile1 profile2 profile3 pty1 \
- rebuf regx8bit reint reint2 rsstart1 \
- rsstart2 rsstart3 rstest6 shadow sortfor sortu splitarg4 strftime \
- strtonum switch2
+ backw badargs beginfile1 beginfile2 binmode1 charasbytes \
+ colonwarn clos1way dbugeval delsub devfd devfd1 devfd2 dumpvars exit \
+ fieldwdth fpat1 fpat2 fpat3 fpatnull fsfwfs funlen \
+ functab1 functab2 functab3 fwtest fwtest2 fwtest3 \
+ genpot gensub gensub2 getlndir gnuops2 gnuops3 gnureops \
+ icasefs icasers id igncdym igncfs ignrcas2 ignrcase \
+ incdupe incdupe2 incdupe3 incdupe4 incdupe5 incdupe6 incdupe7 \
+ include include2 indirectcall indirectcall2 \
+ lint lintold lintwarn \
+ manyfiles match1 match2 match3 mbstr1 \
+ nastyparm next nondec nondec2 \
+ patsplit posix printfbad1 printfbad2 printfbad3 printhuge procinfs \
+ profile1 profile2 profile3 profile4 profile5 profile6 profile7 pty1 \
+ rebuf regnul1 regnul2 regx8bit reginttrad reint reint2 rsgetline rsglstdin rsstart1 \
+ rsstart2 rsstart3 rstest6 shadow sortfor sortu split_after_fpat \
+ splitarg4 strftime \
+ strtonum switch2 symtab1 symtab2 symtab3 symtab4 symtab5 symtab6 \
+ symtab7 symtab8 symtab9
EXTRA_TESTS = inftest regtest
INET_TESTS = inetdayu inetdayt inetechu inetecht
MACHINE_TESTS = double1 double2 fmtspcl intformat
+MPFR_TESTS = mpfrnr mpfrnegzero mpfrrem mpfrrnd mpfrieee mpfrexprange \
+ mpfrsort mpfrsqrt mpfrbigint
+
LOCALE_CHARSET_TESTS = \
- asort asorti fmttest fnarydel fnparydl lc_num1 mbfw1 \
- mbprintf1 mbprintf2 mbprintf3 rebt8b2 rtlenmb sort1 sprintfc
+ asort asorti backbigs1 backsmalls1 backsmalls2 \
+ fmttest fnarydel fnparydl jarebug lc_num1 mbfw1 \
+ mbprintf1 mbprintf2 mbprintf3 mbprintf4 rebt8b2 rtlenmb sort1 sprintfc
+
+SHLIB_TESTS = \
+ fnmatch filefuncs fork fork2 fts functab4 inplace1 inplace2 inplace3 \
+ ordchr ordchr2 readdir readfile readfile2 revout revtwoway rwarray testext time
# List of the tests which should be run with --lint option:
NEED_LINT = \
@@ -192,8 +227,15 @@ FAIL_CODE1 = \
fnarray2 fnmisc gsubasgn mixed1 noparms paramdup synerr1 synerr2 unterm
+# List of files which have .ok versions for MPFR
+CHECK_MPFR = \
+ rand fnarydel fnparydl
+
+
# List of the files that appear in manual tests or are for reserve testing:
-GENTESTS_UNUSED = Makefile.in gtlnbufv.awk printfloat.awk
+GENTESTS_UNUSED = Makefile.in dtdgport.awk gtlnbufv.awk hello.awk \
+ inchello.awk inclib.awk inplace.1.in inplace.2.in inplace.in \
+ longdbl.awk longdbl.in printfloat.awk readdir0.awk xref.awk
# Message stuff is to make it a little easier to follow.
# Make the pass-fail last and dependent on others to avoid
@@ -205,6 +247,8 @@ check: msg \
extend-msg-start gawk-extensions extend-msg-end \
machine-msg-start machine-tests machine-msg-end \
charset-msg-start charset-tests charset-msg-end \
+ shlib-msg-start shlib-tests shlib-msg-end \
+ mpfr-msg-start mpfr-tests mpfr-msg-end \
pass-fail
basic: $(BASIC_TESTS)
@@ -221,6 +265,24 @@ inet: inetmesg $(INET_TESTS)
machine-tests: $(MACHINE_TESTS)
+# The blank between ' and /MPFR/ is for running tests on Windows under
+# MSYS, which thinks /MPFR is a Unix-style file name and converts it
+# to Windows format, butchering it in the process. Likewise for /API/
+# in the next shlib-tests.
+mpfr-tests:
+ @if $(AWK) --version | $(AWK) ' /MPFR/ { exit 1 }' ; then \
+ echo MPFR tests not supported on this system ; \
+ else $(MAKE) $(MPFR_TESTS) ; \
+ fi
+
+shlib-tests:
+ @if $(AWK) --version | $(AWK) ' /API/ { exit 1 }' ; then \
+ echo shlib tests not supported on this system ; \
+ else $(MAKE) shlib-real-tests ; \
+ fi
+
+shlib-real-tests: $(SHLIB_TESTS)
+
msg::
@echo ""
@echo "Any output from $(CMP) is bad news, although some differences"
@@ -229,7 +291,7 @@ msg::
@echo "precision may lead to slightly different output in a few cases."
printlang::
- @$(AWK) -f $(srcdir)/printlang.awk
+ @$(AWK) -f "$(srcdir)"/printlang.awk
basic-msg-start:
@echo "======== Starting basic tests ========"
@@ -257,15 +319,33 @@ machine-msg-end:
charset-msg-start:
@echo "======== Starting tests that can vary based on character set or locale support ========"
+ @echo "************************************************"
+ @echo "** Some or all of these tests may fail if you **"
+ @echo "** have inadequate or missing locale support **"
+ @echo "** At least en_US.UTF-8, ru_RU.UTF-8 and **"
+ @echo "** ja_JP.UTF-8 are needed. **"
+ @echo "************************************************"
charset-msg-end:
@echo "======== Done with tests that can vary based on character set or locale support ========"
+shlib-msg-start:
+ @echo "======== Starting shared library tests ========"
+
+shlib-msg-end:
+ @echo "======== Done with shared library tests ========"
+
+mpfr-msg-start:
+ @echo "======== Starting MPFR tests ========"
+
+mpfr-msg-end:
+ @echo "======== Done with MPFR tests ========"
+
lc_num1:
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
# This test is a PITA because increasingly, /tmp is getting
# mounted noexec. So, we'll test it locally. Sigh.
@@ -274,193 +354,205 @@ lc_num1:
# so this can still fail
poundbang::
@echo $@
- @sed "s;/tmp/gawk;`pwd`/$(AWKPROG);" < $(srcdir)/poundbang.awk > ./_pbd.awk
+ @sed "s;/tmp/gawk;`pwd`/$(AWKPROG);" < "$(srcdir)"/poundbang.awk > ./_pbd.awk
@chmod +x ./_pbd.awk
- @if ./_pbd.awk $(srcdir)/poundbang.awk > _`basename $@` ; \
+ @if ./_pbd.awk "$(srcdir)"/poundbang.awk > _`basename $@` ; \
then : ; \
else \
- sed "s;/tmp/gawk;../$(AWKPROG);" < $(srcdir)/poundbang.awk > ./_pbd.awk ; \
+ 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 $@`; \
+ LC_ALL=$${GAWKLOCALE:-C} LANG=$${GAWKLOCALE:-C} ./_pbd.awk "$(srcdir)"/poundbang.awk > _`basename $@`; \
fi
- @-$(CMP) $(srcdir)/poundbang.awk _`basename $@` && rm -f _`basename $@` _pbd.awk
+ @-$(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
+ @$(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 \
+ @case "$(srcdir)" in \
.) : ;; \
- *) cp $(srcdir)/argarray.in . ;; \
+ *) cp "$(srcdir)"/argarray.in . ;; \
esac
- @TEST=test echo just a test | $(AWK) -f $(srcdir)/argarray.awk ./argarray.in - >_$@
- @case $(srcdir) in \
+ @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 _$@
+ @-$(CMP) "$(srcdir)"/$@.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=$(AWKPROG) $(srcdir)/regtest.sh
+ AWK=$(AWKPROG) "$(srcdir)"/regtest.sh
manyfiles::
@echo manyfiles
@rm -rf junk
@mkdir junk
@$(AWK) 'BEGIN { for (i = 1; i <= 1030; i++) print i, i}' >_$@
- @$(AWK) -f $(srcdir)/manyfiles.awk _$@ _$@
+ @$(AWK) -f "$(srcdir)"/manyfiles.awk _$@ _$@
@wc -l junk/* | $(AWK) '$$1 != 2' | wc -l | sed "s/ *//g" > _$@
- @rm -rf junk ; $(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @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 _$@
+ @$(AWK) -f "$(srcdir)"/compare.awk 0 1 "$(srcdir)"/compare.in >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
inftest::
@echo $@
@echo This test is very machine specific...
@echo Expect inftest to fail with DJGPP.
- @$(AWK) -f $(srcdir)/inftest.awk | sed "s/inf/Inf/g" >_$@
- @-$(CMP) $(srcdir)/inftest.ok _$@ && rm -f _$@
+ @$(AWK) -f "$(srcdir)"/inftest.awk | sed "s/inf/Inf/g" >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
getline2::
@echo $@
- @$(AWK) -f $(srcdir)/getline2.awk $(srcdir)/getline2.awk $(srcdir)/getline2.awk >_$@
- @-$(CMP) $(srcdir)/getline2.ok _$@ && rm -f _$@
+ @$(AWK) -f "$(srcdir)"/getline2.awk "$(srcdir)"/getline2.awk "$(srcdir)"/getline2.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
awkpath::
@echo $@
@AWKPATH="$(srcdir)$(PATH_SEPARATOR)$(srcdir)/lib" $(AWK) -f awkpath.awk >_$@
- @-$(CMP) $(srcdir)/awkpath.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
argtest::
@echo $@
- @$(AWK) -f $(srcdir)/argtest.awk -x -y abc >_$@
- @-$(CMP) $(srcdir)/argtest.ok _$@ && rm -f _$@
+ @$(AWK) -f "$(srcdir)"/argtest.awk -x -y abc >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
badargs::
@echo $@
@-$(AWK) -f 2>&1 | grep -v patchlevel >_$@
- @-$(CMP) $(srcdir)/badargs.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
nonl::
@echo $@
- @-AWKPATH=$(srcdir) $(AWK) --lint -f nonl.awk /dev/null >_$@ 2>&1
- @-$(CMP) $(srcdir)/nonl.ok _$@ && rm -f _$@
+ @-AWKPATH="$(srcdir)" $(AWK) --lint -f nonl.awk /dev/null >_$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.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
+# $(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
+ $(AWK) -v OUTPUT=_$@ -v DATECMD="$(DATE)" -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 _$@
+ @echo ab | $(AWK) --traditional -f "$(srcdir)"/litoct.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
devfd::
@echo $@
@echo Expect devfd to fail in MinGW
- @$(AWK) 1 /dev/fd/4 /dev/fd/5 4<$(srcdir)/devfd.in4 5<$(srcdir)/devfd.in5 >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(AWK) 1 /dev/fd/4 /dev/fd/5 4<"$(srcdir)"/devfd.in4 5<"$(srcdir)"/devfd.in5 >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fflush::
@echo $@
- @$(srcdir)/fflush.sh >_$@
- @-$(CMP) $(srcdir)/fflush.ok _$@ && rm -f _$@
+ @"$(srcdir)"/fflush.sh >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
tweakfld::
@echo $@
- @$(AWK) -f $(srcdir)/tweakfld.awk $(srcdir)/tweakfld.in >_$@
+ @$(AWK) -f "$(srcdir)"/tweakfld.awk "$(srcdir)"/tweakfld.in >_$@
@rm -f errors.cleanup
- @-$(CMP) $(srcdir)/tweakfld.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mmap8k::
@echo $@
- @$(AWK) '{ print }' $(srcdir)/mmap8k.in >_$@
- @-$(CMP) $(srcdir)/mmap8k.in _$@ && rm -f _$@
+ @$(AWK) '{ print }' "$(srcdir)"/mmap8k.in >_$@
+ @-$(CMP) "$(srcdir)"/mmap8k.in _$@ && rm -f _$@ || cp "$(srcdir)"/$@.in $@.ok
tradanch::
@echo $@
- @$(AWK) --traditional -f $(srcdir)/tradanch.awk $(srcdir)/tradanch.in >_$@
- @-$(CMP) $(srcdir)/tradanch.ok _$@ && rm -f _$@
+ @$(AWK) --traditional -f "$(srcdir)"/tradanch.awk "$(srcdir)"/tradanch.in >_$@
+ @-$(CMP) "$(srcdir)"/$@.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 and MinGW.
- @AWKPATH=$(srcdir) AWK=$(AWKPROG) $(SHELL) $(srcdir)/pid.sh $$$$ > _`basename $@` ; :
- @-$(CMP) $(srcdir)/pid.ok _`basename $@` && rm -f _`basename $@`
+ @AWKPATH="$(srcdir)" AWK=$(AWKPROG) $(SHELL) "$(srcdir)"/pid.sh $$$$ > _`basename $@` ; :
+ @-$(CMP) "$(srcdir)"/pid.ok _`basename $@` && rm -f _`basename $@`
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 >_$@ ; \
+ @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 _$@
+ @-$(CMP) "$(srcdir)"/$@.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 _$@
+ @echo A B C D E | tr -d '\12\15' | $(AWK) '{ print $$NF }' - "$(srcdir)"/nors.in > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fmtspcl.ok: fmtspcl.tok
- @$(AWK) -v "sd=$(srcdir)" 'BEGIN {pnan = sprintf("%g",sqrt(-1)); nnan = sprintf("%g",-sqrt(-1)); pinf = sprintf("%g",-log(0)); ninf = sprintf("%g",log(0))} {sub(/positive_nan/,pnan); sub(/negative_nan/,nnan); sub(/positive_infinity/,pinf); sub(/negative_infinity/,ninf); sub(/fmtspcl/,(sd"/fmtspcl")); print}' < $(srcdir)/fmtspcl.tok > $@ 2>/dev/null
+ @$(AWK) -v "sd=$(srcdir)" 'BEGIN {pnan = sprintf("%g",sqrt(-1)); nnan = sprintf("%g",-sqrt(-1)); pinf = sprintf("%g",-log(0)); ninf = sprintf("%g",log(0))} {sub(/positive_nan/,pnan); sub(/negative_nan/,nnan); sub(/positive_infinity/,pinf); sub(/negative_infinity/,ninf); sub(/fmtspcl/,(sd"/fmtspcl")); print}' < "$(srcdir)"/fmtspcl.tok > $@ 2>/dev/null
fmtspcl: fmtspcl.ok
- @echo fmtspcl
- @echo Expect $@ to fail with MinGW
- @$(AWK) -f $(srcdir)/fmtspcl.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $@.ok _$@ && rm -f _$@
+ @echo $@
+ @echo Expect $@ to fail on MinGW if not built with MPFR
+ @$(AWK) $(AWKFLAGS) -f "$(srcdir)"/fmtspcl.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-if test -z "$$AWKFLAGS" ; then $(CMP) $@.ok _$@ && rm -f _$@ ; else \
+ $(CMP) "$(srcdir)"/$@-mpfr.ok _$@ && rm -f _$@ ; \
+ fi
+
+rebuf::
+ @echo $@
+ @AWKBUFSIZE=4096 AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+rsglstdin::
+ @echo $@
+ @cat "$(srcdir)"/rsgetline.in | AWKPATH="$(srcdir)" $(AWK) -f rsgetline.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
reint::
@echo $@
- @$(AWK) --re-interval -f $(srcdir)/reint.awk $(srcdir)/reint.in >_$@
- @-$(CMP) $(srcdir)/reint.ok _$@ && rm -f _$@
+ @$(AWK) --re-interval -f "$(srcdir)"/reint.awk "$(srcdir)"/reint.in >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
pipeio1::
@echo $@
- @$(AWK) -f $(srcdir)/pipeio1.awk >_$@
+ @$(AWK) -f "$(srcdir)"/pipeio1.awk >_$@
@rm -f test1 test2
- @-$(CMP) $(srcdir)/pipeio1.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
pipeio2::
@echo $@
- @$(AWK) -v SRCDIR=$(srcdir) -f $(srcdir)/pipeio2.awk >_$@
- @-$(CMP) $(srcdir)/pipeio2.ok _$@ && rm -f _$@
+ @echo Expect pipeio2 to fail with MinGW
+ @$(AWK) -v SRCDIR="$(srcdir)" -f "$(srcdir)"/pipeio2.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
clobber::
@echo $@
- @$(AWK) -f $(srcdir)/clobber.awk >_$@
- @-$(CMP) $(srcdir)/clobber.ok seq && $(CMP) $(srcdir)/clobber.ok _$@ && rm -f _$@
+ @$(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 _$@
+ @-AWKPATH="$(srcdir)" $(AWK) -v INPUT="$(srcdir)"/arynocls.in -f arynocls.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.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$@
+ @-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
@@ -475,6 +567,7 @@ inetechu::
inetecht::
@echo Expect inetecht to fail with DJGPP.
+ @echo Expect inetecht to time out with MinGW after 20 sec.
@echo This test is for establishing TCP connections
# @$(AWK) 'BEGIN {print "" |& "/inet/tcp/0/127.0.0.1/9"}'
@-$(AWK) 'BEGIN {print "" |& "/inet/tcp/0/127.0.0.1/9"}'
@@ -489,6 +582,7 @@ inetdayu::
inetdayt::
@echo Expect inetdayt to fail with DJGPP.
+ @echo Expect inetdayt to time out with MinGW after 41 sec.
@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}'
@@ -497,1487 +591,1977 @@ inetdayt::
redfilnm::
@echo $@
- @$(AWK) -f $(srcdir)/redfilnm.awk srcdir=$(srcdir) $(srcdir)/redfilnm.in >_$@
- @-$(CMP) $(srcdir)/redfilnm.ok _$@ && rm -f _$@
+ @$(AWK) -f "$(srcdir)"/redfilnm.awk srcdir="$(srcdir)" "$(srcdir)"/redfilnm.in >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
leaddig::
@echo $@
- @$(AWK) -v x=2E -f $(srcdir)/leaddig.awk >_$@
- @-$(CMP) $(srcdir)/leaddig.ok _$@ && rm -f _$@
+ @$(AWK) -v x=2E -f "$(srcdir)"/leaddig.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
gsubtst3::
@echo $@
- @$(AWK) --re-interval -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(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 _$@
+ @$(AWK) -f ' ' "$(srcdir)"/space.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+# @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+ @-$(TESTOUTCMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
printf0::
@echo $@
- @$(AWK) --posix -f $(srcdir)/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(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: $$? >>_$@
@$(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 _$@
+ $(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: $$? >>_$@
@$(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 _$@
+ $(AWK) ' /^[^a]/; END { print NR }' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
wideidx::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
wideidx2::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
widesub::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
widesub2::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
widesub3::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
widesub4::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(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 _$@
+ @GAWKLOCALE=en_US.UTF-8 ; 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 _$@
+ $(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 _$@
+ @$(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 _$@
+ @$(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 _$@
+ @$(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 _$@
+ @$(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 _$@
+ @head "$(srcdir)"/rsstart1.in | $(AWK) -f "$(srcdir)"/rsstart2.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
rtlen::
@echo $@
- @$(srcdir)/$@.sh >_$@ || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @"$(srcdir)"/$@.sh >_$@ || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
rtlen01::
@echo $@
- @$(srcdir)/$@.sh >_$@ || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @"$(srcdir)"/$@.sh >_$@ || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
rtlenmb::
@echo $@
@GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
- $(srcdir)/rtlen.sh >_$@ || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/rtlen.ok _$@ && rm -f _$@
+ "$(srcdir)"/rtlen.sh >_$@ || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
nondec2::
@echo $@
- @$(AWK) --non-decimal-data -v a=0x1 -f $(srcdir)/$@.awk >_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(AWK) --non-decimal-data -v a=0x1 -f "$(srcdir)"/$@.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
nofile::
@echo $@
@$(AWK) '{}' no/such/file >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@sed "s/ (ENOENT)//" _$@ > _$@.2
@rm -f _$@
-# @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
- @-$(CMP) $(srcdir)/$@.ok _$@.2 && rm -f _$@.2
+# @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@.2 && rm -f _$@.2
binmode1::
@echo $@
@$(AWK) -v BINMODE=3 'BEGIN { print BINMODE }' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
subi18n::
@echo $@
- @GAWKLOCALE=en_US.UTF-8 ; $(AWK) -f $(srcdir)/$@.awk > _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @GAWKLOCALE=en_US.UTF-8 ; $(AWK) -f "$(srcdir)"/$@.awk > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
concat4::
@echo $@
- @GAWKLOCALE=en_US.UTF-8 ; $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in > _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @GAWKLOCALE=en_US.UTF-8 ; $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
devfd1::
@echo $@
@echo Expect devfd1 to fail in MinGW
- @$(AWK) -f $(srcdir)/$@.awk 4< $(srcdir)/devfd.in1 5< $(srcdir)/devfd.in2 >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(AWK) -f "$(srcdir)"/$@.awk 4< "$(srcdir)"/devfd.in1 5< "$(srcdir)"/devfd.in2 >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
# The program text is the '1' which will print each record. How compact can you get?
devfd2::
@echo $@
- @$(AWK) 1 /dev/fd/4 /dev/fd/5 4< $(srcdir)/devfd.in1 5< $(srcdir)/devfd.in2 >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo Expect devfd2 to fail in MinGW
+ @$(AWK) 1 /dev/fd/4 /dev/fd/5 4< "$(srcdir)"/devfd.in1 5< "$(srcdir)"/devfd.in2 >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mixed1::
@echo $@
@$(AWK) -f /dev/null --source 'BEGIN {return junk}' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mtchi18n::
@echo $@
@GAWKLOCALE=ru_RU.UTF-8 ; export GAWKLOCALE ; \
- $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
reint2::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) --re-interval -f $@.awk $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) --re-interval -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
localenl::
@echo $@
- @$(srcdir)/$@.sh >_$@ 2>/dev/null
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @"$(srcdir)"/$@.sh >_$@ 2>/dev/null
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbprintf1::
@echo $@
- @echo Expect mbprintf1 to fail with DJGPP.
+ @echo Expect mbprintf1 to fail with DJGPP and MinGW.
@GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
- $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbprintf2::
@echo $@
@GAWKLOCALE=ja_JP.UTF-8 ; export GAWKLOCALE ; \
- $(AWK) -f $(srcdir)/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ $(AWK) -f "$(srcdir)"/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbprintf3::
@echo $@
@GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
- $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mbprintf4::
+ @echo $@
+ @echo Expect mbprintf4 to fail with MinGW and DJGPP
+ @GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
+ $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbfw1::
@echo $@
- @echo Expect mbfw1 to fail with DJGPP.
+ @echo Expect mbfw1 to fail with DJGPP and MinGW.
@GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
- $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
gsubtst6::
@echo $@
- @GAWKLOCALE=C ; $(AWK) -f $(srcdir)/$@.awk > _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @GAWKLOCALE=C ; $(AWK) -f "$(srcdir)"/$@.awk > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbstr1::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
printfbad2: printfbad2.ok
@echo $@
- @$(AWK) --lint -f $(srcdir)/$@.awk $(srcdir)/$@.in 2>&1 | sed 's;\$(srcdir)/;;g' >_$@ || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(AWK) --lint -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in 2>&1 | sed 's;$(srcdir)/;;g' >_$@ || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
beginfile1::
@echo $@
@echo Expect beginfile1 to fail with DJGPP
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk $(srcdir)/$@.awk . ./no/such/file Makefile >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.awk . ./no/such/file Makefile >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
beginfile2:
@echo $@
- @-( cd $(srcdir) && AWK="$(abs_builddir)/$(AWKPROG)" $(srcdir)/$@.sh $(srcdir)/$@.in ) > _$@ 2>&1
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-( cd "$(srcdir)" && LC_ALL=C AWK="$(abs_builddir)/$(AWKPROG)" $(abs_srcdir)/$@.sh $(abs_srcdir)/$@.in ) > _$@ 2>&1
+# @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+ @-$(TESTOUTCMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
dumpvars::
@echo $@
- @AWKPATH=$(srcdir) $(AWK) --dump-variables 1 < $(srcdir)/$@.in >/dev/null 2>&1 || echo EXIT CODE: $$? >>_$@
+ @AWKPATH="$(srcdir)" $(AWK) --dump-variables 1 < "$(srcdir)"/$@.in >/dev/null 2>&1 || echo EXIT CODE: $$? >>_$@
# @mv awkvars.out _$@
@$(MV) awkvars.out _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
profile1:
@echo $@
- @$(AWK) --profile=ap-$@.out -f $(srcdir)/xref.awk $(srcdir)/dtdgport.awk > _$@.out1
- @$(AWK) -f ap-$@.out $(srcdir)/dtdgport.awk > _$@.out2 ; rm ap-$@.out
- @cmp _$@.out1 _$@.out2 && rm _$@.out[12] || echo EXIT CODE: $$? >>_$@
+ @$(AWK) --pretty-print=ap-$@.out -f "$(srcdir)"/xref.awk "$(srcdir)"/dtdgport.awk > _$@.out1
+ @$(AWK) -f ./ap-$@.out "$(srcdir)"/dtdgport.awk > _$@.out2 ; rm ap-$@.out
+ @$(CMP) _$@.out1 _$@.out2 && rm _$@.out[12] || { echo EXIT CODE: $$? >>_$@ ; \
+ cp "$(srcdir)"/dtdgport.awk > $@.ok ; }
profile2:
@echo $@
- @$(PGAWK) --profile=ap-$@.out -v sortcmd=sort -f $(srcdir)/xref.awk $(srcdir)/dtdgport.awk > /dev/null
+ @$(AWK) --profile=ap-$@.out -v sortcmd=sort -f "$(srcdir)"/xref.awk "$(srcdir)"/dtdgport.awk > /dev/null
@sed 1,2d < ap-$@.out > _$@; rm ap-$@.out
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
profile3:
@echo $@
- @$(PGAWK) --profile=ap-$@.out -f $(srcdir)/$@.awk > /dev/null
+ @$(AWK) --profile=ap-$@.out -f "$(srcdir)"/$@.awk > /dev/null
@sed 1,2d < ap-$@.out > _$@; rm ap-$@.out
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+profile4:
+ @echo $@
+ @GAWK_NO_PP_RUN=1 $(AWK) --profile=ap-$@.out -f "$(srcdir)"/$@.awk > /dev/null
+ @sed 1,2d < ap-$@.out > _$@; rm ap-$@.out
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+profile5:
+ @echo $@
+ @echo Expect profile5 to fail with MinGW due to 3 digits in %e output
+ @GAWK_NO_PP_RUN=1 $(AWK) --profile=ap-$@.out -f "$(srcdir)"/$@.awk > /dev/null
+ @sed 1,2d < ap-$@.out > _$@; rm ap-$@.out
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+profile6:
+ @echo $@
+ @$(AWK) --profile=ap-$@.out -f "$(srcdir)"/$@.awk > /dev/null
+ @sed 1,2d < ap-$@.out > _$@; rm ap-$@.out
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+profile7:
+ @echo $@
+ @$(AWK) --profile=ap-$@.out -f "$(srcdir)"/$@.awk > /dev/null
+ @sed 1,2d < ap-$@.out > _$@; rm ap-$@.out
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
posix2008sub:
@echo $@
- @$(AWK) --posix -f $(srcdir)/$@.awk > _$@ 2>&1
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(AWK) --posix -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
next:
@echo $@
- @-AWK="$(AWKPROG)" $(srcdir)/$@.sh > _$@ 2>&1
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-$(LOCALES) AWK="$(AWKPROG)" "$(srcdir)"/$@.sh > _$@ 2>&1
+ @-LC_ALL=C $(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
exit:
@echo $@
- @-AWK="$(AWKPROG)" $(srcdir)/$@.sh > _$@ 2>&1
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo Expect exit to fail with MinGW due to null vs nul difference
+ @-AWK="$(AWKPROG)" "$(srcdir)"/$@.sh > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+rri1::
+ @echo $@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrieee:
+ @echo $@
+ @$(AWK) -M -vPREC=double -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrexprange:
+ @echo $@
+ @$(AWK) -M -vPREC=53 -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrrnd:
+ @echo $@
+ @$(AWK) -M -vPREC=53 -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrnegzero:
+ @echo $@
+ @$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrnr:
+ @echo $@
+ @$(AWK) -M -vPREC=113 -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrsort:
+ @echo $@
+ @$(AWK) -M -vPREC=53 -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrbigint:
+ @echo $@
+ @$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrsqrt:
+ @echo $@
+ @$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrrem:
+ @echo $@
+ @$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+jarebug::
+ @echo $@
+ @echo Expect jarebug to fail with DJGPP and MinGW.
+ @"$(srcdir)"/$@.sh "$(AWKPROG)" "$(srcdir)"/$@.awk "$(srcdir)"/$@.in "_$@"
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+ordchr2::
+ @echo $@
+ @$(AWK) --load ordchr 'BEGIN {print chr(ord("z"))}' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+# N.B. If the test fails, create readfile.ok so that "make diffout" will work
+readfile::
+ @echo $@
+ @$(AWK) -l readfile 'BEGIN {printf "%s", readfile("Makefile")}' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) Makefile _$@ && rm -f _$@ || cp -p Makefile $@.ok
+
+readfile2::
+ @echo $@
+ @$(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.awk "$(srcdir)"/readdir.awk > _$@ || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+include2::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --include inclib 'BEGIN {print sandwich("a", "b", "c")}' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -i inclib -i inclib.awk 'BEGIN {print sandwich("a", "b", "c")}' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe2::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -f inclib -f inclib.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe3::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -f hello -f hello.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe4::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -f hello -i hello.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe5::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -i hello -f hello.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe6::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -i inchello -f hello.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe7::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -f hello -i inchello >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+inplace1::
+ @echo $@
+ @cp "$(srcdir)"/inplace.1.in _$@.1
+ @cp "$(srcdir)"/inplace.2.in _$@.2
+ @AWKPATH="$(srcdir)"/../awklib/eg/lib $(AWK) -i inplace 'BEGIN {print "before"} {gsub(/foo/, "bar"); print} END {print "after"}' _$@.1 - _$@.2 < "$(srcdir)"/inplace.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.1.ok _$@.1 && rm -f _$@.1
+ @-$(CMP) "$(srcdir)"/$@.2.ok _$@.2 && rm -f _$@.2
+
+inplace2::
+ @echo $@
+ @cp "$(srcdir)"/inplace.1.in _$@.1
+ @cp "$(srcdir)"/inplace.2.in _$@.2
+ @AWKPATH="$(srcdir)"/../awklib/eg/lib $(AWK) -i inplace -v INPLACE_SUFFIX=.bak 'BEGIN {print "before"} {gsub(/foo/, "bar"); print} END {print "after"}' _$@.1 - _$@.2 < "$(srcdir)"/inplace.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.1.ok _$@.1 && rm -f _$@.1
+ @-$(CMP) "$(srcdir)"/$@.1.bak.ok _$@.1.bak && rm -f _$@.1.bak
+ @-$(CMP) "$(srcdir)"/$@.2.ok _$@.2 && rm -f _$@.2
+ @-$(CMP) "$(srcdir)"/$@.2.bak.ok _$@.2.bak && rm -f _$@.2.bak
+
+inplace3::
+ @echo $@
+ @cp "$(srcdir)"/inplace.1.in _$@.1
+ @cp "$(srcdir)"/inplace.2.in _$@.2
+ @AWKPATH="$(srcdir)"/../awklib/eg/lib $(AWK) -i inplace -v INPLACE_SUFFIX=.bak 'BEGIN {print "before"} {gsub(/foo/, "bar"); print} END {print "after"}' _$@.1 - _$@.2 < "$(srcdir)"/inplace.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @AWKPATH="$(srcdir)"/../awklib/eg/lib $(AWK) -i inplace -v INPLACE_SUFFIX=.bak 'BEGIN {print "Before"} {gsub(/bar/, "foo"); print} END {print "After"}' _$@.1 - _$@.2 < "$(srcdir)"/inplace.in >>_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.1.ok _$@.1 && rm -f _$@.1
+ @-$(CMP) "$(srcdir)"/$@.1.bak.ok _$@.1.bak && rm -f _$@.1.bak
+ @-$(CMP) "$(srcdir)"/$@.2.ok _$@.2 && rm -f _$@.2
+ @-$(CMP) "$(srcdir)"/$@.2.bak.ok _$@.2.bak && rm -f _$@.2.bak
+
+testext::
+ @echo $@
+# @$(AWK) '/^(@load|BEGIN)/,/^}/' "$(top_srcdir)"/extension/testext.c > testext.awk
+ @$(AWK) ' /^(@load|BEGIN)/,/^}/' "$(top_srcdir)"/extension/testext.c > testext.awk
+ @$(AWK) -f ./testext.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ testext.awk
+
+readdir:
+ @if [ "`uname`" = Linux ] && [ "`stat -f . 2>/dev/null | awk 'NR == 2 { print $$NF }'`" = nfs ]; then \
+ echo This test may fail on GNU/Linux systems when run on an NFS filesystem.; \
+ echo If it does, try rerunning on an ext'[234]' filesystem. ; \
+ fi
+ @echo $@
+ @echo This test may fail on MinGW if $(LS) does not report full Windows file index as the inode
+ @$(AWK) -f "$(srcdir)"/readdir.awk "$(top_srcdir)" > _$@
+# @ls -afi "$(top_srcdir)" > _dirlist
+ @$(LS) -afi "$(top_srcdir)" > _dirlist
+# @ls -lna "$(top_srcdir)" | sed 1d > _longlist
+ @$(LS) -lna "$(top_srcdir)" | sed 1d > _longlist
+ @$(AWK) -f "$(srcdir)"/readdir0.awk -v extout=_$@ \
+ -v dirlist=_dirlist -v longlist=_longlist > $@.ok
+ @-$(CMP) $@.ok _$@ && rm -f $@.ok _$@ _dirlist _longlist
+
+fts:
+ @case `uname` in \
+ IRIX) \
+ echo This test may fail on IRIX systems when run on an NFS filesystem.; \
+ echo If it does, try rerunning on an xfs filesystem. ;; \
+ CYGWIN*) \
+ echo This test may fail on CYGWIN systems when run on an NFS filesystem.; \
+ echo If it does, try rerunning on an ntfs filesystem. ;; \
+ esac
+ @echo $@
+ @echo Expect $@ to fail with MinGW because function 'fts' is not defined.
+# @$(AWK) -f "$(srcdir)"/fts.awk
+ @$(AWK) -f "$(srcdir)"/fts.awk || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $@.ok _$@ && rm -f $@.ok _$@
+
+charasbytes:
+ @echo $@
+# @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+# AWKPATH="$(srcdir)" $(AWK) -b -f $@.awk "$(srcdir)"/$@.in | \
+# od -c -t x1 | tr ' ' ' ' | sed -e 's/ */ /g' -e 's/ *$$//' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -b -v BINMODE=2 -f $@.awk "$(srcdir)"/$@.in | \
+ od -c -t x1 | tr ' ' ' ' | sed -e 's/ */ /g' -e 's/ *$$//' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab6:
+ @echo $@
+ @$(AWK) -d__$@ -f "$(srcdir)"/$@.awk
+ @grep -v '^ENVIRON' __$@ | grep -v '^PROCINFO' > _$@ ; rm __$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab8:
+ @echo $@
+ @$(AWK) -d__$@ -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@
+ @grep -v '^ENVIRON' __$@ | grep -v '^PROCINFO' | grep -v '^FILENAME' >> _$@ ; rm __$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab9:
+ @echo $@
+ @$(AWK) -f "$(srcdir)"/$@.awk >_$@
+ @rm -f testit.txt
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+reginttrad:
+ @echo $@
+ @$(AWK) --traditional -r -f "$(srcdir)"/$@.awk > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+colonwarn:
+ @echo $@
+ @for i in 1 2 3 ; \
+ do $(AWK) -f "$(srcdir)"/$@.awk $$i < "$(srcdir)"/$@.in ; \
+ done > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+clos1way:
+ @echo $@
+ @echo Expect clos1way to fail with DJGPP.
+ @AWKPATH="$(srcdir)" LC_ALL=C $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+dfamb1:
+ @echo $@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+backbigs1:
+ @echo $@
+ @echo Expect backbigs1 to fail with MinGW and DJGPP
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+backsmalls1:
+ @echo $@
+ @echo Expect backsmalls1 to fail with MinGW and DJGPP
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+backsmalls2:
+ @echo $@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+dbugeval::
+ @echo $@
+ @$(AWK) --debug -f /dev/null < "$(srcdir)"/$@.in > _$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+printhuge::
+ @echo $@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+filefuncs:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk -v builddir="$(abs_top_builddir)" >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+genpot:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --gen-pot >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+badassign1:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
closebad:
- @echo closebad
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
delargv:
- @echo delargv
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
dfastress:
- @echo dfastress
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+exit2:
+ @echo $@
+ @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 _$@
+ @echo $@
+ @echo Expect exitval2 to fail with MinGW
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fcall_exit:
- @echo fcall_exit
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fcall_exit2:
- @echo fcall_exit2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
forref:
- @echo forref
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
getline4:
- @echo getline4
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+getline5:
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
gsubtst7:
- @echo gsubtst7
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
gsubtst8:
- @echo gsubtst8
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @echo Expect hsprint to fail with MinGW due to 3 digits in %e output
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 SORT=sort < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
-# @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk SORT=sort < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+# @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
negrange:
- @echo negrange
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+nfloop:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
ofmta:
- @echo ofmta
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+ofs1:
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
paramres:
- @echo paramres
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+paramuninitglobal:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
parse1:
- @echo parse1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
parsefld:
- @echo parsefld
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) $(AWKFLAGS) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-if test -z "$$AWKFLAGS" ; then $(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ ; else \
+ $(CMP) "$(srcdir)"/$@-mpfr.ok _$@ && rm -f _$@ ; \
+ fi
range1:
- @echo range1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+regexprange:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
regrange:
- @echo regrange
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @echo Expect rstest4 to fail with MinGW
+ @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 _$@
+ @echo $@
+ @echo Expect rstest5 to fail with MinGW
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
strnum1:
- @echo strnum1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
strtod:
- @echo strtod
+ @echo $@
@echo Expect strtod to fail with DJGPP.
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
synerr2:
- @echo synerr2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
uninit5:
- @echo uninit5
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
uparrfs:
- @echo uparrfs
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
zero2:
- @echo zero2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
getlnhd:
- @echo getlnhd
+ @echo $@
@echo Expect getlnhd to fail if pipe does not use a Unixy shell
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
aadelete1:
- @echo aadelete1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
aadelete2:
- @echo aadelete2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
aarray1:
- @echo aarray1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
aasort:
- @echo aasort
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
aasorti:
- @echo aasorti
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
arraysort:
- @echo arraysort
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 and MinGW.
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
delsub:
- @echo delsub
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fpat1:
- @echo fpat1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fpat2:
- @echo fpat2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fpat3:
- @echo fpat3
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fpatnull:
- @echo fpatnull
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
funlen:
- @echo funlen
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+functab1:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+functab2:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+functab3:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fwtest:
- @echo fwtest
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fwtest2:
- @echo fwtest2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fwtest3:
- @echo fwtest3
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
getlndir:
- @echo getlndir
+ @echo $@
@echo Expect getlndir to fail with DJGPP.
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+id:
+ @echo $@
+ @echo Expect id to fail with DJGPP.
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+include:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
indirectcall:
- @echo indirectcall
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+indirectcall2:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
lintold:
- @echo lintold
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint-old < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint-old < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
lintwarn:
- @echo lintwarn
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
match3:
- @echo match3
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
nastyparm:
- @echo nastyparm
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
patsplit:
- @echo patsplit
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @echo Expect posix to fail with MinGW due to 3 digits in e+NNN exponent
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+printfbad3:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
pty1:
- @echo pty1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @echo Expect pty1 to fail with DJGPP and MinGW.
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+regnul1:
+ @echo $@
+ @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 _$@
+regnul2:
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+rsgetline:
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
sortfor:
- @echo sortfor
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
sortu:
- @echo sortu
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+split_after_fpat:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
splitarg4:
- @echo splitarg4
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
switch2:
- @echo switch2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab1:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab2:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab3:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab4:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab5:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab7:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
double1:
- @echo double1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
double2:
- @echo double2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @echo Expect double2 to fail with MinGW due to 3 digits in e+NNN exponents
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
intformat:
- @echo intformat
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @echo Expect fmttest to fail with MinGW due to 3 digits in e+NNN exponents
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) $(AWKFLAGS) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-if test -z "$$AWKFLAGS" ; then $(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ ; else \
+ $(CMP) "$(srcdir)"/$@-mpfr.ok _$@ && rm -f _$@ ; \
+ fi
fnparydl:
- @echo fnparydl
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) $(AWKFLAGS) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-if test -z "$$AWKFLAGS" ; then $(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ ; else \
+ $(CMP) "$(srcdir)"/$@-mpfr.ok _$@ && rm -f _$@ ; \
+ fi
rebt8b2:
- @echo rebt8b2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+fnmatch:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+fork:
+ @echo $@
+ @echo Expect $@ to fail with MinGW because fork.dll is not available
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+fork2:
+ @echo $@
+ @echo Expect $@ to fail with MinGW because fork.dll is not available
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+functab4:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+ordchr:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+revout:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+revtwoway:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+rwarray:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+time:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
# end of file Maketests
@@ -1985,17 +2569,19 @@ sprintfc:
$(srcdir)/Maketests: $(srcdir)/Makefile.am $(srcdir)/Gentests
files=`cd "$(srcdir)" && echo *.awk *.in`; \
- $(AWK) -f $(srcdir)/Gentests "$(srcdir)/Makefile.am" $$files > $(srcdir)/Maketests
+ $(AWK) -f "$(srcdir)"/Gentests "$(srcdir)"/Makefile.am $$files > "$(srcdir)"/Maketests
clean:
- rm -fr _* core core.* fmtspcl.ok junk out1 out2 out3 strftime.ok test1 test2 seq *~
+ rm -fr _* core core.* fmtspcl.ok junk strftime.ok test1 test2 \
+ seq *~ readfile.ok fork.tmp.* testext.awk fts.ok readdir.ok \
+ mmap8k.ok profile1.ok
# 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 ; \
+ else echo $$COUNT TESTS FAILED ; exit 1; \
fi
# This target for my convenience to look at all the results
@@ -2004,10 +2590,11 @@ diffout:
do \
if [ "$$i" != "_*" ]; then \
echo ============== $$i ============= ; \
- if [ -r $${i#_}.ok ]; then \
- diff -c $${i#_}.ok $$i ; \
+ base=`echo $$i | sed 's/^_//'` ; \
+ if [ -r $${base}.ok ]; then \
+ diff -c $${base}.ok $$i ; \
else \
- diff -c $(srcdir)/$${i#_}.ok $$i ; \
+ diff -c "$(srcdir)"/$${base}.ok $$i ; \
fi ; \
fi ; \
done | more
@@ -2019,8 +2606,8 @@ valgrind-scan:
function show() {if (cmd) {printf "%s: %s\n",FILENAME,cmd; cmd = ""}; \
printf "\t%s\n",$$0}; \
{$$1 = ""}; \
- /Prog and args are:/ {incmd = 1; cmd = ""; next}; \
- incmd {if (NF == 1) incmd = 0; else {cmd = (cmd $$0); next}}; \
+ $$2 == "Command:" {incmd = 1; $$2 = ""; cmd = $$0; next}; \
+ incmd {if (/Parent PID:/) incmd = 0; else {cmd = (cmd $$0); next}}; \
/ERROR SUMMARY:/ && !/: 0 errors from 0 contexts/ {show()}; \
/definitely lost:/ && !/: 0 bytes in 0 blocks/ {show()}; \
/possibly lost:/ && !/: 0 bytes in 0 blocks/ {show()}; \
diff --git a/pc/config.h b/pc/config.h
index 41fd895a..a6b2d4c4 100644
--- a/pc/config.h
+++ b/pc/config.h
@@ -2,7 +2,9 @@
/* pc/config.h. Generated automatically by pc/config.sed. */
/* dynamic loading is possible */
-#undef DYNAMIC
+#ifdef _WIN32
+#define DYNAMIC 1
+#endif
/* Define to 1 if translation of program messages to the user's native
language is requested. */
@@ -13,7 +15,7 @@
#define GETGROUPS_T gid_t
/* Define to 1 if the `getpgrp' function requires zero arguments. */
-#undef GETPGRP_VOID
+#define GETPGRP_VOID 1
/* Define to 1 if you have the `alarm' function. */
#define HAVE_ALARM 1
@@ -47,19 +49,16 @@
#define HAVE_DECL_TZNAME 1
#endif
-/* 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. */
-#ifdef __MINGW32__
#define HAVE_FCNTL_H 1
-#endif
/* Define to 1 if you have the `fmod' function. */
#define HAVE_FMOD 1
/* have getaddrinfo */
-#undef HAVE_GETADDRINFO
+#ifdef __MINGW32__
+#define HAVE_GETADDRINFO 1
+#endif
/* Define to 1 if you have the `getgrent' function. */
#undef HAVE_GETGRENT
@@ -73,10 +72,13 @@
/* Define to 1 if you have the `grantpt' function. */
#undef HAVE_GRANTPT
+/* Do we have history_list? */
+#undef HAVE_HISTORY_LIST
+
/* Define if you have the iconv() function and it works. */
#undef HAVE_ICONV
-/* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */
+/* Define to 1 if the system has the type `intmax_t'. */
#ifdef __MINGW32__
#define HAVE_INTMAX_T 1
#endif
@@ -86,12 +88,6 @@
#define HAVE_INTTYPES_H 1
#endif
-/* Define if <inttypes.h> exists, doesn't clash with <sys/types.h>, and
- declares uintmax_t. */
-#ifdef __MINGW32__
-#define HAVE_INTTYPES_H_WITH_UINTMAX 1
-#endif
-
/* Define to 1 if you have the `isascii' function. */
#ifdef __MINGW32__
#define HAVE_ISASCII 1
@@ -125,26 +121,19 @@
#define HAVE_LIBM 1
/* Define to 1 if you have a fully functional readline library. */
-#undef HAVE_LIBREADLINE
+/* #undef HAVE_LIBREADLINE */
/* Define if you have the libsigsegv library. */
#undef HAVE_LIBSIGSEGV
/* Define to 1 if you have the <limits.h> header file. */
-#if defined(DJGPP) || defined(__MINGW32__)
#define HAVE_LIMITS_H 1
-#endif
/* Define to 1 if you have the <locale.h> header file. */
#ifdef __MINGW32__
#define HAVE_LOCALE_H 1
#endif
-/* Define if you have the 'long long' type. */
-#ifdef __MINGW32__
-#define HAVE_LONG_LONG 1
-#endif
-
/* Define to 1 if the system has the type `long long int'. */
#undef HAVE_LONG_LONG_INT
@@ -185,19 +174,25 @@
#undef HAVE_MEMSET_ULONG
/* Define to 1 if you have the `mkstemp' function. */
-#ifdef DJGPP
+#ifdef __DJGPP__
#define HAVE_MKSTEMP 1
#endif
/* we have the mktime function */
#define HAVE_MKTIME 1
+/* Define to 1 if you have fully functional mpfr and gmp libraries. */
+/* #undef HAVE_MPFR */
+
/* 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 `posix_openpt' function. */
+#undef HAVE_POSIX_OPENPT
+
/* Define to 1 if you have the `setenv' function. */
#if defined(__MINGW32__) || defined(__DJGPP__)
#define HAVE_SETENV 1
@@ -217,14 +212,21 @@
#endif
/* newer systems define this type here */
-#undef HAVE_SOCKADDR_STORAGE
+#ifdef __MINGW32__
+#define HAVE_SOCKADDR_STORAGE 1
+#endif
/* we have sockets on this system */
-#undef HAVE_SOCKETS
+#ifdef __MINGW32__
+#define HAVE_SOCKETS 1
+#endif
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
+/* Define to 1 if stdbool.h conforms to C99. */
+#undef HAVE_STDBOOL_H
+
/* Define to 1 if you have the <stddef.h> header file. */
#ifdef __GNUC__
#define HAVE_STDDEF_H 1
@@ -235,15 +237,14 @@
#define HAVE_STDINT_H 1
#endif
-/* 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. */
#ifdef __MINGW32__
#define HAVE_STDLIB_H 1
#endif
+/* 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
@@ -293,14 +294,8 @@
/* Define to 1 if `tm_zone' is a 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. */
-#ifdef __MINGW32__
#define HAVE_SYSTEM 1
-#endif
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
@@ -319,7 +314,7 @@
#endif
/* Define to 1 if you have the <sys/time.h> header file. */
-#if defined(DJGPP) || defined(__MINGW32__)
+#if defined(__DJGPP__) || defined(__MINGW32__)
#define HAVE_SYS_TIME_H 1
#endif
@@ -354,37 +349,29 @@
#define HAVE_TZNAME 1
/* Define to 1 if you have the `tzset' function. */
-#ifdef __MINGW32__
#define HAVE_TZSET 1
-#endif
-/* Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>. */
-#if defined(DJGPP) || defined(__MINGW32__)
+/* Define to 1 if the system has the type `uintmax_t'. */
+#if defined(__DJGPP__) || defined(__MINGW32__)
#define HAVE_UINTMAX_T 1
-#ifdef DJGPP
+#ifdef __DJGPP__
#define uintmax_t unsigned long long
#endif
#endif
/* Define to 1 if you have the <unistd.h> header file. */
-#if defined(DJGPP) || defined(__MINGW32__)
+#if defined(__DJGPP__) || defined(__MINGW32__)
#define HAVE_UNISTD_H 1
#endif
-/* Define if you have the 'unsigned long long' type. */
-#define HAVE_UNSIGNED_LONG_LONG 1
-
/* Define to 1 if the system has the type `unsigned long long int'. */
#undef HAVE_UNSIGNED_LONG_LONG_INT
/* Define to 1 if you have the `usleep' function. */
-#if defined(DJGPP) || defined(__MINGW32__)
+#if defined(__DJGPP__) || defined(__MINGW32__)
#define HAVE_USLEEP 1
#endif
-/* Define to 1 if you have the `vprintf' function. */
-#define HAVE_VPRINTF 1
-
/* Define to 1 if you have the <wchar.h> header file. */
#ifdef __MINGW32__
#define HAVE_WCHAR_H 1
@@ -420,6 +407,15 @@
#define HAVE_WINT_T 1
#endif
+/* Define to 1 if the system has the type `_Bool'. */
+#undef HAVE__BOOL
+
+/* enable severe portability problems */
+#undef I_DONT_KNOW_WHAT_IM_DOING
+
+/* libc is broken for regex handling */
+#undef LIBC_IS_BORKED
+
/* disable lint checks */
#undef NO_LINT
@@ -433,7 +429,7 @@
#define PACKAGE_NAME "GNU Awk"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "GNU Awk 4.0.0c"
+#define PACKAGE_STRING "GNU Awk 4.1.60"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "gawk"
@@ -442,7 +438,7 @@
#define PACKAGE_URL "http://www.gnu.org/software/gawk/"
/* Define to the version of this package. */
-#define PACKAGE_VERSION "4.0.0c"
+#define PACKAGE_VERSION "4.1.60"
/* Define to 1 if *printf supports %F format */
#undef PRINTF_HAS_F_FORMAT
@@ -450,7 +446,7 @@
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void
-#if defined(DJGPP) || defined(__MINGW32__)
+#if defined(__DJGPP__) || defined(__MINGW32__)
#include <limits.h>
#endif
@@ -504,7 +500,12 @@
/* Version number of package */
-#define VERSION "4.0.0c"
+#define VERSION "4.1.60"
+
+/* Enable large inode numbers on Mac OS X 10.5. */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
@@ -515,6 +516,19 @@
/* Define to 1 if on MINIX. */
#undef _MINIX
+/* The _Noreturn keyword of C11. */
+#ifndef _Noreturn
+# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \
+ || 0x5110 <= __SUNPRO_C)
+# define _Noreturn __attribute__ ((__noreturn__))
+# elif defined _MSC_VER && 1200 <= _MSC_VER
+# define _Noreturn __declspec (noreturn)
+# else
+# define _Noreturn
+# endif
+#endif
+
+
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
#undef _POSIX_1_SOURCE
@@ -541,8 +555,9 @@
#endif
#endif
-/* Define to long or long long if <inttypes.h> and <stdint.h> don't define. */
-#ifdef DJGPP
+/* Define to the widest signed integer type if <stdint.h> and <inttypes.h> do
+ not define. */
+#ifdef __DJGPP__
#define intmax_t long long
#endif
@@ -552,7 +567,7 @@
/* Define to the equivalent of the C99 'restrict' keyword, or to
nothing if this is not supported. Do not define if restrict is
supported directly. */
-#ifdef DJGPP
+#ifdef __DJGPP__
#define restrict
#endif
/* Work around a bug in Sun C++: it does not support _Restrict or
@@ -577,9 +592,9 @@
/* 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. */
-#ifdef DJGPP
+/* Define to the widest unsigned integer type if <stdint.h> and <inttypes.h>
+ do not define. */
+#ifdef __DJGPP__
#define uintmax_t unsigned long long
#endif
@@ -591,10 +606,22 @@
# define DEFPATH ".;c:/lib/awk;c:/gnu/lib/awk"
#endif
-#ifndef DJGPP
+#ifndef __DJGPP__
#define HAVE_POPEN_H 1
#endif
+#if defined(__DJGPP__)
+typedef unsigned int uint32_t;
+typedef int int32_t;
+#define INT32_MAX INT_MAX
+#define INT32_MIN INT_MIN
+#endif
+
+#if defined(__EMX__)
+#define strcasecmp stricmp
+#define strncasecmp strnicmp
+#endif
+
#if defined(__MINGW32__)
# define WEXITSTATUS(stat_val) ((stat_val) & ~0xC0000000)
#endif
diff --git a/pc/config.sed b/pc/config.sed
index c0fa766a..e18a6e68 100644
--- a/pc/config.sed
+++ b/pc/config.sed
@@ -26,111 +26,130 @@
/configh\.in/a\
/* pc/config.h. Generated automatically by pc/config.sed. */
+/^#undef DYNAMIC$/c\
+#ifdef _WIN32\
+#define DYNAMIC 1\
+#endif
+s/^#undef GETPGRP_VOID *$/#define GETPGRP_VOID 1/
s/^#undef GETGROUPS_T *$/#define GETGROUPS_T gid_t/
+/^#undef GETPGRP_VOID$/c\
+#ifdef __DJGPP__\
+#define GETPGRP_VOID 1\
+#endif
s/^#undef HAVE_ALARM *$/#define HAVE_ALARM 1/
s/^#undef HAVE_ATEXIT *$/#define HAVE_ATEXIT 1/
-/^#undef HAVE_BTOWC$/c\
+/^#undef HAVE_BTOWC *$/c\
#ifdef _WIN32\
#define HAVE_BTOWC 1\
#endif
-/^#undef HAVE_DECL_TZNAME$/c\
+/^#undef HAVE_DECL_TZNAME *$/c\
#ifdef __MINGW32__\
#define HAVE_DECL_TZNAME 1\
#endif
-/^#undef HAVE_FCNTL_H$/c\
+s/^#undef HAVE_FCNTL_H *$/#define HAVE_FCNTL_H 1/
+s/^#undef HAVE_FMOD *$/#define HAVE_FMOD 1/
+/^#undef HAVE_GETADDRINFO *$/c\
#ifdef __MINGW32__\
-#define HAVE_FCNTL_H 1\
+#define HAVE_GETADDRINFO 1\
#endif
-s/^#undef HAVE_FMOD *$/#define HAVE_FMOD 1/
-/^#undef HAVE_INTMAX_T$/c\
+/^#undef HAVE_INTMAX_T *$/c\
#ifdef __MINGW32__\
#define HAVE_INTMAX_T 1\
#endif
-/^#undef HAVE_INTTYPES_H$/c\
+/^#undef HAVE_INTTYPES_H *$/c\
#ifdef __MINGW32__\
#define HAVE_INTTYPES_H 1\
#endif
-/^#undef HAVE_INTTYPES_H_WITH_UINTMAX$/c\
+/^#undef HAVE_INTTYPES_H_WITH_UINTMAX *$/c\
#ifdef __MINGW32__\
#define HAVE_INTTYPES_H_WITH_UINTMAX 1\
#endif
-/^#undef HAVE_ISASCII$/c\
+/^#undef HAVE_ISASCII *$/c\
#ifdef __MINGW32__\
#define HAVE_ISASCII 1\
#endif
-/^#undef HAVE_ISWCTYPE$/c\
+/^#undef HAVE_ISWCTYPE *$/c\
#ifdef __MINGW32__\
#define HAVE_ISWCTYPE 1\
#endif
-/^#undef HAVE_ISWLOWER$/c\
+/^#undef HAVE_ISWLOWER *$/c\
#ifdef __MINGW32__\
#define HAVE_ISWLOWER 1\
#endif
-/^#undef HAVE_ISWUPPER$/c\
+/^#undef HAVE_ISWUPPER *$/c\
#ifdef __MINGW32__\
#define HAVE_ISWUPPER 1\
#endif
s/^#undef HAVE_LIBM *$/#define HAVE_LIBM 1/
-/^#undef HAVE_LIMITS_H$/c\
-#if defined(DJGPP) || defined(__MINGW32__)\
-#define HAVE_LIMITS_H 1\
-#endif
-/^#undef HAVE_LOCALE_H$/c\
+/^#undef HAVE_LIBREADLINE *$/c\
+/* #undef HAVE_LIBREADLINE */
+s/^#undef HAVE_LIMITS_H *$/#define HAVE_LIMITS_H 1/
+/^#undef HAVE_LOCALE_H *$/c\
#ifdef __MINGW32__\
#define HAVE_LOCALE_H 1\
#endif
-/^#undef HAVE_LONG_LONG$/c\
+/^#undef HAVE_LONG_LONG *$/c\
#ifdef __MINGW32__\
#define HAVE_LONG_LONG 1\
#endif
-/^#undef HAVE_MBRLEN$/c\
+/^#undef HAVE_MBRLEN *$/c\
#ifdef __MINGW32__\
#define HAVE_MBRLEN 1\
#endif
-/^#undef HAVE_MBRTOWC$/c\
+/^#undef HAVE_MBRTOWC *$/c\
#ifdef __MINGW32__\
#define HAVE_MBRTOWC 1\
#endif
s/^#undef HAVE_MEMCMP *$/#define HAVE_MEMCMP 1/
s/^#undef HAVE_MEMCPY *$/#define HAVE_MEMCPY 1/
-/^#undef HAVE_MEMMOVE$/c\
+/^#undef HAVE_MEMMOVE *$/c\
#ifdef __MINGW32__\
#define HAVE_MEMMOVE 1\
#endif
s/^#undef HAVE_MEMSET *$/#define HAVE_MEMSET 1/
-/^#undef HAVE_MKSTEMP$/c\
-#ifdef DJGPP\
+/^#undef HAVE_MKSTEMP *$/c\
+#ifdef __DJGPP__\
#define HAVE_MKSTEMP 1\
#endif
s/^#undef HAVE_MKTIME *$/#define HAVE_MKTIME 1/
-/^#undef HAVE_SETENV$/c\
+/^#undef HAVE_MPFR *$/c\
+/* #undef HAVE_MPFR */
+/^#undef HAVE_SETENV *$/c\
#if defined(__MINGW32__) || defined(__DJGPP__)\
#define HAVE_SETENV 1\
#endif
-/^#undef HAVE_SETLOCALE$/c\
+/^#undef HAVE_SETLOCALE *$/c\
#ifdef __MINGW32__\
#define HAVE_SETLOCALE 1\
#endif
-/^#undef HAVE_SNPRINTF$/c\
+/^#undef HAVE_SNPRINTF *$/c\
#ifdef __MINGW32__\
#define HAVE_SNPRINTF 1\
#endif
+/^#undef HAVE_SOCKADDR_STORAGE *$/c\
+#ifdef __MINGW32__\
+#define HAVE_SOCKADDR_STORAGE 1\
+#endif
+/^#undef HAVE_SOCKETS *$/c\
+#ifdef __MINGW32__\
+#define HAVE_SOCKETS 1\
+#endif
s/^#undef HAVE_STDARG_H *$/#define HAVE_STDARG_H 1/
-/^#undef HAVE_STDDEF_H$/c\
+/^#undef HAVE_STDDEF_H *$/c\
#ifdef __GNUC__\
#define HAVE_STDDEF_H 1\
#endif
-/^#undef HAVE_STDINT_H$/c\
+/^#undef HAVE_STDINT_H *$/c\
#ifdef __MINGW32__\
#define HAVE_STDINT_H 1\
#endif
-/^#undef HAVE_STDLIB_H$/c\
+/^#undef HAVE_STDLIB_H *$/c\
#ifdef __MINGW32__\
#define HAVE_STDLIB_H 1\
#endif
s/^#undef HAVE_STRCHR *$/#define HAVE_STRCHR 1/
s/^#undef HAVE_STRERROR *$/#define HAVE_STRERROR 1/
-/^#undef HAVE_STRFTIME$/c\
+/^#undef HAVE_STRFTIME *$/c\
#ifdef __MINGW32__\
/* MinGW uses the replacement from missing_d, to support the %e specifier. */\
#define strftime rpl_strftime\
@@ -139,88 +158,82 @@ s/^#undef HAVE_STRERROR *$/#define HAVE_STRERROR 1/
#endif
s/^#undef HAVE_STRINGIZE *$/#define HAVE_STRINGIZE 1/
s/^#undef HAVE_STRING_H *$/#define HAVE_STRING_H 1/
-/^#undef HAVE_STRNCASECMP$/c\
+/^#undef HAVE_STRNCASECMP *$/c\
#define HAVE_STRNCASECMP 1\
#ifdef __EMX__\
#define strncasecmp strnicmp\
#endif
s/^#undef HAVE_STRTOD *$/#define HAVE_STRTOD 1/
-/^#undef HAVE_STRTOUL$/c\
+/^#undef HAVE_STRTOUL *$/c\
#ifdef __MINGW32__\
#define HAVE_STRTOUL 1\
#endif
-/^#undef HAVE_SYSTEM$/c\
-#ifdef __MINGW32__\
-#define HAVE_SYSTEM 1\
-#endif
-/^#undef HAVE_SYS_PARAM_H$/c\
+s/^#undef HAVE_SYSTEM *$/#define HAVE_SYSTEM 1/
+/^#undef HAVE_SYS_PARAM_H *$/c\
#ifndef __MINGW32__\
#define HAVE_SYS_PARAM_H 1\
#endif
-/^#undef HAVE_SYS_STAT_H$/c\
+/^#undef HAVE_SYS_STAT_H *$/c\
#ifdef __MINGW32__\
#define HAVE_SYS_STAT_H 1\
#endif
-/^#undef HAVE_SYS_TIME_H$/c\
-#if defined(DJGPP) || defined(__MINGW32__)\
+/^#undef HAVE_SYS_TIME_H *$/c\
+#if defined(__DJGPP__) || defined(__MINGW32__)\
#define HAVE_SYS_TIME_H 1\
#endif
s/^#undef HAVE_SYS_TYPES_H *$/#define HAVE_SYS_TYPES_H 1/
-/^#undef HAVE_TOWLOWER$/c\
+/^#undef HAVE_TOWLOWER *$/c\
#ifdef __MINGW32__\
#define HAVE_TOWLOWER 1\
#endif
-/^#undef HAVE_TOWUPPER$/c\
+/^#undef HAVE_TOWUPPER *$/c\
#ifdef __MINGW32__\
#define HAVE_TOWUPPER 1\
#endif
s/^#undef HAVE_TZNAME *$/#define HAVE_TZNAME 1/
-/^#undef HAVE_TZSET$/c\
-#ifdef __MINGW32__\
-#define HAVE_TZSET 1\
-#endif
-/^#undef HAVE_UINTMAX_T$/c\
-#if defined(DJGPP) || defined(__MINGW32__)\
+s/^#undef HAVE_TZSET *$/#define HAVE_TZSET 1/
+/^#undef HAVE_UINTMAX_T *$/c\
+#if defined(__DJGPP__) || defined(__MINGW32__)\
#define HAVE_UINTMAX_T 1\
-#ifdef DJGPP\
+#ifdef __DJGPP__\
#define uintmax_t unsigned long long\
#endif\
#endif
-/^#undef HAVE_UNISTD_H$/c\
-#if defined(DJGPP) || defined(__MINGW32__)\
+/^#undef HAVE_UNISTD_H *$/c\
+#if defined(__DJGPP__) || defined(__MINGW32__)\
#define HAVE_UNISTD_H 1\
#endif
s/^#undef HAVE_UNSIGNED_LONG_LONG *$/#define HAVE_UNSIGNED_LONG_LONG 1/
-/^#undef HAVE_USLEEP$/c\
-#if defined(DJGPP) || defined(__MINGW32__)\
+/^#undef HAVE_USLEEP *$/c\
+#if defined(__DJGPP__) || defined(__MINGW32__)\
#define HAVE_USLEEP 1\
#endif
s/^#undef HAVE_VPRINTF *$/#define HAVE_VPRINTF 1/
-/^#undef HAVE_WCHAR_H$/c\
+/^#undef HAVE_WCHAR_H *$/c\
#ifdef __MINGW32__\
#define HAVE_WCHAR_H 1\
#endif
-/^#undef HAVE_WCRTOMB$/c\
+/^#undef HAVE_WCRTOMB *$/c\
#ifdef __MINGW32__\
#define HAVE_WCRTOMB 1\
#endif
-/^#undef HAVE_WCSCOLL$/c\
+/^#undef HAVE_WCSCOLL *$/c\
#ifdef __MINGW32__\
#define HAVE_WCSCOLL 1\
#endif
-/^#undef HAVE_WCTYPE$/c\
+/^#undef HAVE_WCTYPE *$/c\
#ifdef __MINGW32__\
#define HAVE_WCTYPE 1\
#endif
-/^#undef HAVE_WCTYPE_H$/c\
+/^#undef HAVE_WCTYPE_H *$/c\
#ifdef __MINGW32__\
#define HAVE_WCTYPE_H 1\
#endif
-/^#undef HAVE_WCTYPE_T$/c\
+/^#undef HAVE_WCTYPE_T *$/c\
#ifdef __MINGW32__\
#define HAVE_WCTYPE_T 1\
#endif
-/^#undef HAVE_WINT_T$/c\
+/^#undef HAVE_WINT_T *$/c\
#ifdef __MINGW32__\
#define HAVE_WINT_T 1\
#endif
@@ -228,35 +241,35 @@ s/^#undef PROTOTYPES *$/#define PROTOTYPES 1/
s/^#undef RETSIGTYPE *$/#define RETSIGTYPE void/
/^#.*RETSIGTYPE /a\
\
-#if defined(DJGPP) || defined(__MINGW32__)\
+#if defined(__DJGPP__) || defined(__MINGW32__)\
#include <limits.h>\
#endif
-/^#undef SIZEOF_UNSIGNED_INT$/c\
+/^#undef SIZEOF_UNSIGNED_INT *$/c\
#if UINT_MAX == 65536\
#define SIZEOF_UNSIGNED_INT 2\
#elif UINT_MAX == 4294967295U\
#define SIZEOF_UNSIGNED_INT 4\
#endif
-/^#undef SIZEOF_UNSIGNED_LONG$/c\
+/^#undef SIZEOF_UNSIGNED_LONG *$/c\
#if ULONG_MAX == 4294967295UL\
#define SIZEOF_UNSIGNED_LONG 4\
#endif
s/^#undef STDC_HEADERS *$/#define STDC_HEADERS 1/
s/^#undef TIME_WITH_SYS_TIME *$/#define TIME_WITH_SYS_TIME 1/
-/^#undef inline$/c\
+/^#undef inline *$/c\
#ifdef __GNUC__\
#define inline __inline__\
#endif
-/^#undef intmax_t$/c\
-#ifdef DJGPP\
+/^#undef intmax_t *$/c\
+#ifdef __DJGPP__\
#define intmax_t long long\
#endif
-/^#undef restrict$/c\
-#ifdef DJGPP\
+/^#undef restrict *$/c\
+#ifdef __DJGPP__\
#define restrict\
#endif
-/^#undef uintmax_t$/c\
-#ifdef DJGPP\
+/^#undef uintmax_t *$/c\
+#ifdef __DJGPP__\
#define uintmax_t unsigned long long\
#endif
@@ -270,10 +283,22 @@ $a\
# define DEFPATH ".;c:/lib/awk;c:/gnu/lib/awk"\
#endif\
\
-#ifndef DJGPP\
+#ifndef __DJGPP__\
#define HAVE_POPEN_H 1\
#endif\
\
+#if defined(__DJGPP__)\
+typedef unsigned int uint32_t;\
+typedef int int32_t;\
+#define INT32_MAX INT_MAX\
+#define INT32_MIN INT_MIN\
+#endif\
+\
+#if defined(__EMX__)\
+#define strcasecmp stricmp\
+#define strncasecmp strnicmp\
+#endif\
+\
#if defined(__MINGW32__)\
# define WEXITSTATUS(stat_val) ((stat_val) & ~0xC0000000)\
#endif
diff --git a/pc/dlfcn.h b/pc/dlfcn.h
new file mode 100644
index 00000000..64ef4bc5
--- /dev/null
+++ b/pc/dlfcn.h
@@ -0,0 +1,12 @@
+/* dlfcn.h replacement for MS-Windows build. */
+#ifndef DLFCN_H
+#define DLFCN_H
+
+#define RTLD_LAZY 1
+
+extern void *dlopen (const char *, int);
+extern int dlclose (void *);
+extern void *dlsym (void *, const char *);
+extern char *dlerror (void);
+
+#endif /* DLFCN_H */
diff --git a/pc/gawkmisc.pc b/pc/gawkmisc.pc
index 64b42396..fdd32e7e 100644
--- a/pc/gawkmisc.pc
+++ b/pc/gawkmisc.pc
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991 - 2003 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991 - 2003, 2012 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Progamming Language.
@@ -31,6 +31,8 @@ char *defpath = DEFPATH;
# else
char *defpath = ".;c:\\lib\\awk;c:\\gnu\\lib\\awk";
# endif
+/* the Makefile should define DEFLIBPATH */
+char *deflibpath = DEFLIBPATH;
#ifdef __EMX__
#include<io.h>
@@ -40,6 +42,24 @@ static char* _os2_unixroot(const char *path);
static const char* _os2_unixroot_path(const char *path);
#endif
+#ifdef __MINGW32__
+#ifdef HAVE_SOCKETS
+#include <socket.h>
+
+#undef socket
+#undef setsockopt
+#undef bind
+#undef connect
+#undef listen
+#undef accept
+#undef recvfrom
+#undef shutdown
+#endif
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
/* gawk_name --- pull out the "gawk" part from how the OS called us */
char *
@@ -203,15 +223,19 @@ 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 (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
+#ifdef __MINGW32__
+ HANDLE fh = (HANDLE)_get_osfhandle(fd);
+
+ if (fh && fh != INVALID_HANDLE_VALUE)
+ SetHandleInformation(fh, HANDLE_FLAG_INHERIT, 0);
#endif
}
@@ -230,6 +254,31 @@ int fd;
return (fstat(fd, &sbuf) == 0 && S_ISDIR(sbuf.st_mode));
}
+/* os_isreadable --- fd can be read from */
+
+int
+os_isreadable(const awk_input_buf_t *iobuf, bool *isdir)
+{
+ *isdir = false;
+
+ switch (iobuf->sbuf.st_mode & S_IFMT) {
+ case S_IFREG:
+ case S_IFCHR: /* ttys, /dev/null, .. */
+#ifdef S_IFSOCK
+ case S_IFSOCK:
+#endif
+#ifdef S_IFIFO
+ case S_IFIFO:
+#endif
+ return true;
+ case S_IFDIR:
+ *isdir = true;
+ /* fall through */
+ default:
+ return false;
+ }
+}
+
/* os_is_setuid --- true if running setuid root */
int
@@ -535,8 +584,6 @@ unsetenv (const char *name)
return setenv (name, "", 1);
}
-#include <windows.h>
-
int
usleep(unsigned int usec)
{
@@ -569,8 +616,257 @@ wctob (wint_t wc)
return EOF;
}
+/*
+ * On MS-Windows with MinGW, execvp causes the shell and the re-exec'ed
+ * dgawk to compete for the keyboard input.
+ *
+ * This will need work if we ever need a real version of execvp.
+ */
+int execvp(const char *file, const char *const *argv)
+{
+ if (_spawnvp(_P_WAIT, file, (const char * const *)argv) != -1)
+ exit(EXIT_SUCCESS);
+
+ return -1;
+}
+
+#ifdef DYNAMIC
+
+#include <dlfcn.h>
+
+static DWORD last_err;
+
+void *
+dlopen (const char *file, int mode)
+{
+ char dllfn[MAX_PATH], *p;
+ HANDLE dllhandle;
+
+ if (mode != RTLD_LAZY)
+ {
+ errno = EINVAL;
+ last_err = ERROR_INVALID_PARAMETER;
+ return NULL;
+ }
+
+ /* MSDN says to be sure to use backslashes in the DLL file name. */
+ strcpy (dllfn, file);
+ for (p = dllfn; *p; p++)
+ if (*p == '/')
+ *p = '\\';
+
+ dllhandle = LoadLibrary (dllfn);
+ if (!dllhandle)
+ last_err = GetLastError ();
+
+ return dllhandle;
+}
+
+char *
+dlerror (void)
+{
+ static char errbuf[1024];
+ DWORD ret;
+
+ if (!last_err)
+ return NULL;
+
+ ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, last_err, 0, errbuf, sizeof (errbuf), NULL);
+ while (ret > 0 && (errbuf[ret - 1] == '\n' || errbuf[ret - 1] == '\r'))
+ --ret;
+
+ errbuf[ret] = '\0';
+ if (!ret)
+ sprintf (errbuf, "Error code %lu", last_err);
+
+ last_err = 0;
+ return errbuf;
+}
+
+int
+dlclose (void *handle)
+{
+ if (!handle || handle == INVALID_HANDLE_VALUE)
+ return -1;
+ if (!FreeLibrary (handle))
+ return -1;
+
+ return 0;
+}
+
+void *
+dlsym (void *handle, const char *name)
+{
+ FARPROC addr = NULL;
+
+ if (!handle || handle == INVALID_HANDLE_VALUE)
+ {
+ last_err = ERROR_INVALID_PARAMETER;
+ return NULL;
+ }
+
+ addr = GetProcAddress (handle, name);
+ if (!addr)
+ last_err = GetLastError ();
+
+ return (void *)addr;
+}
+#endif /* DYNAMIC */
+
+#ifdef HAVE_SOCKETS
+int
+socket_to_fd(SOCKET s)
+{
+ return (s == INVALID_SOCKET
+ ? INVALID_HANDLE
+ : _open_osfhandle (s, O_BINARY | O_NOINHERIT));
+}
+
+int
+w32_socket(int family, int type, int protocol)
+{
+ /* We need to use WSASocket rather than socket, since the latter
+ creates overlapped sockets that cannot be used in file I/O
+ APIs. */
+ SOCKET s = WSASocket (family, type, protocol, NULL, 0, 0);
+
+ if (s == INVALID_SOCKET)
+ {
+ switch (WSAGetLastError ())
+ {
+ case WSAEMFILE:
+ errno = EMFILE;
+ break;
+ case WSANOTINITIALISED:
+ case WSAENETDOWN:
+ errno = EACCES;
+ break;
+ case WSAENOBUFS:
+ errno = ENOMEM;
+ break;
+ case WSAEFAULT:
+ errno = EFAULT;
+ break;
+ default:
+ errno = EINVAL;
+ break;
+ }
+ }
+
+ return socket_to_fd (s);
+}
+
+int
+w32_setsockopt (int fd, int level, int optname, const char *optval, int optlen)
+{
+ SOCKET s = FD_TO_SOCKET (fd);
+
+ return setsockopt (s, level, optname, optval, optlen);
+}
+
+int
+w32_bind (int fd, const struct sockaddr *name, int namelen)
+{
+ SOCKET s = FD_TO_SOCKET (fd);
+
+ return bind (s, name, namelen);
+}
+
+int
+w32_connect (int fd, const struct sockaddr *name, int namelen)
+{
+ SOCKET s = FD_TO_SOCKET (fd);
+
+ return connect (s, name, namelen);
+}
+
+int
+w32_listen (int fd, int backlog)
+{
+ SOCKET s = FD_TO_SOCKET (fd);
+
+ return listen (s, backlog);
+}
+
+int
+w32_accept (int fd, struct sockaddr *addr, int *addrlen)
+{
+ SOCKET s = FD_TO_SOCKET (fd);
+
+ return socket_to_fd (accept (s, addr, addrlen));
+}
+
+SOCKET
+valid_socket (int fd)
+{
+ SOCKET s = FD_TO_SOCKET (fd);
+ int ov, ol = 4;
+
+ if (s == INVALID_SOCKET
+ || (getsockopt (s, SOL_SOCKET, SO_TYPE, (char *)&ov, &ol) == SOCKET_ERROR
+ && WSAGetLastError() == WSAENOTSOCK))
+ return (SOCKET)0;
+ return s;
+}
+
+int
+w32_closesocket (int fd)
+{
+ SOCKET s = valid_socket (fd);
+ int res1, res2 = 0;
+
+ if (!s && fd == FAKE_FD_VALUE)
+ return 0;
+
+ res1 = close (fd);
+ if (s)
+ res2 = closesocket (s);
+
+ if (res1 == -1 || res2 == SOCKET_ERROR)
+ return -1;
+ return 0;
+}
+
+int
+w32_recvfrom (int fd, char *buf, int len, int flags,
+ struct sockaddr *from, int *fromlen)
+{
+ SOCKET s = FD_TO_SOCKET (fd);
+
+ return recvfrom (s, buf, len, flags, from, fromlen);
+}
+
+int
+w32_shutdown (int fd, int how)
+{
+ SOCKET s = FD_TO_SOCKET (fd);
+
+ return shutdown (s, how);
+}
+
+#endif /* HAVE_SOCKETS */
+
#endif /* __MINGW32__ */
+#if defined(__DJGPP__) || defined(__MINGW32__) || defined(__EMX__)
+
+void
+init_sockets(void)
+{
+#if defined(HAVE_SOCKETS) && !defined(__EMX__)
+ WSADATA winsockData;
+ int errcode;
+
+ if ((errcode = WSAStartup (0x101, &winsockData)) != 0
+ || winsockData.wVersion != 0x101)
+ fatal(_("cannot start Winsock (%d)"), errcode);
+#endif
+}
+
+#endif /* __DJGPP__ || __MINGW32__ */
+
#ifdef __DJGPP__
int
@@ -582,4 +878,12 @@ unsetenv (const char *name)
return putenv (name);
}
+/* This is needed to defeat too-clever GCC warnings in dfa.c about
+ comparison being always false due to limited range of data type. */
+wint_t
+btowc (int c)
+{
+ return c;
+}
+
#endif /* __DJGPP__ */
diff --git a/pc/in.h b/pc/in.h
new file mode 100644
index 00000000..d0833805
--- /dev/null
+++ b/pc/in.h
@@ -0,0 +1 @@
+/* A dummy in.h for pc/ systems. */
diff --git a/pc/install.awk b/pc/install.awk
index 367e8b98..7b8e1c90 100644
--- a/pc/install.awk
+++ b/pc/install.awk
@@ -50,13 +50,13 @@ 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
+printf("@sh 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")
+mkinstalldirs(prefix "/lib/awk " prefix "/share/man/man1 " prefix "/share/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");
+cp("doc/*.1 " prefix "/share/man/man1");
+cp("doc/gawk.info " prefix "/share/info");
+cp("doc/gawkinet.info " prefix "/share/info");
}
diff --git a/pc/popen.c b/pc/popen.c
index 97ff2645..73770d98 100644
--- a/pc/popen.c
+++ b/pc/popen.c
@@ -3,12 +3,16 @@
#include <io.h>
#include <string.h>
#include <process.h>
+#include <errno.h>
+#include "popen.h"
+#undef popen
+#undef pclose
+#undef system
#ifndef _NFILE
#define _NFILE 40
#endif
-static char template[] = "piXXXXXX";
static struct {
char *command;
char *name;
@@ -26,6 +30,10 @@ static struct {
#if defined(__MINGW32__)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#if 0
static int
unixshell(char *p)
{
@@ -111,47 +119,101 @@ unlink_and_free(char *cmd)
s = cmd;
unlink(s); free(cmd);
}
+#endif
int
os_system(const char *cmd)
{
- char *s;
- int i;
- char *cmd1;
+ char *cmdexe = getenv("ComSpec");
+ char *cmd1 = quote_cmd(cmd);
+ int i = spawnl(P_WAIT, cmdexe, "cmd.exe", "/c", cmd1, NULL);
- if ((cmd1 = scriptify(cmd)) == NULL) return(1);
- if (s = getenv("SHELL"))
- i = spawnlp(P_WAIT, s, s, cmd1 + strlen(s), NULL);
- else
- i = system(cmd1);
- unlink_and_free(cmd1);
+ free(cmd1);
return(i);
}
+
+#ifndef PIPES_SIMULATED
+int
+kill (int pid, int sig)
+{
+ HANDLE ph;
+ int retval = 0;
+
+ /* We only support SIGKILL. */
+ if (sig != SIGKILL)
+ {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ ph = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
+ if (ph)
+ {
+ BOOL status = TerminateProcess(ph, -1);
+
+ if (!status)
+ {
+ errno = EPERM;
+ retval = -1;
+ }
+ }
+ else
+ {
+ /* If we cannot open the process, it means we eaither aren't
+ allowed to (e.g., a process of another user), or such a
+ process doesn't exist. */
+ switch (GetLastError ())
+ {
+ case ERROR_ACCESS_DENIED:
+ errno = EPERM;
+ break;
+ default:
+ errno = ESRCH;
+ break;
+ }
+ retval = -1;
+ }
+ CloseHandle (ph);
+ return retval;
+}
+
+char *
+quote_cmd(const char *cmd)
+{
+ char *quoted;
+
+ /* The command will be invoked via cmd.exe, whose behavior wrt
+ quoted commands is to remove the first and the last quote
+ characters, and leave the rest (including any quote characters
+ inside the outer pair) intact. */
+ quoted = malloc(strlen (cmd) + 2 + 1);
+ sprintf(quoted, "\"%s\"", cmd);
+
+ return quoted;
+}
+#endif
+
#else /* !__MINGW32__ */
#define os_system(cmd) system(cmd)
#endif
FILE *
-os_popen(const char *command, char *mode )
+os_popen(const char *command, const char *mode )
{
FILE *current;
char *name;
int cur;
char curmode[4];
-#if defined(__MINGW32__)
- char *cmd;
-#endif
if (*mode != 'r' && *mode != 'w')
return NULL;
strncpy(curmode, mode, 3); curmode[3] = '\0';
#if defined(__MINGW32__)
- current = popen(cmd = scriptify(command), mode);
+ current = popen(command, mode);
cur = fileno(current);
strcpy(pipes[cur].pmode, curmode);
- pipes[cur].command = cmd;
return(current);
#endif
@@ -198,7 +260,6 @@ os_pclose( FILE * current)
#if defined(__MINGW32__)
rval = pclose(current);
*pipes[cur].pmode = '\0';
- unlink_and_free(pipes[cur].command);
return rval;
#endif
diff --git a/pc/popen.h b/pc/popen.h
index 9a04299c..b86c00f0 100644
--- a/pc/popen.h
+++ b/pc/popen.h
@@ -12,6 +12,9 @@
extern int os_pclose( FILE * );
# ifdef __MINGW32__
# define system(c) os_system(c)
- extern int os_system( const char * );
+ extern int os_system( const char * );
+# define SIGKILL 9
+ extern int kill( int, int );
+ extern char *quote_cmd( const char * );
# endif /* __MINGW32__ */
#endif /* !__DJGPP__ */
diff --git a/pc/socket.h b/pc/socket.h
new file mode 100644
index 00000000..41dd23cf
--- /dev/null
+++ b/pc/socket.h
@@ -0,0 +1,42 @@
+/* An emulation for socket.h header for pc/ systems. */
+
+#ifndef GAWK_SOCKET_H
+#define GAWK_SOCKET_H
+
+#ifdef __MINGW32__
+
+#include <io.h>
+
+#define _WIN32_WINNT 0x501
+#include <winsock2.h>
+#include <ws2tcpip.h>
+
+#define socket(f,t,p) w32_socket(f,t,p)
+#define setsockopt(f,l,o,v,s) w32_setsockopt(f,l,o,v,s)
+#define bind(f,a,l) w32_bind(f,a,l)
+#define connect(f,a,l) w32_connect(f,a,l)
+#define listen(f,b) w32_listen(f,b)
+#define accept(f,a,l) w32_accept(f,a,l)
+#define closemaybesocket(f) w32_closesocket(f)
+#define recvfrom(f,b,l,fl,fr,ln) w32_recvfrom(f,b,l,fl,fr,ln)
+#define shutdown(f,h) w32_shutdown(f,h)
+
+#define SOCKET_TO_FD(s) socket_to_fd(s)
+#define FD_TO_SOCKET(fd) \
+ ((fd) == INVALID_HANDLE ? INVALID_SOCKET : _get_osfhandle(fd))
+
+int w32_socket (int, int, int);
+int w32_setsockopt (int, int, int, const char *, int);
+int w32_bind (int, const struct sockaddr *, int);
+int w32_connect (int, const struct sockaddr *, int);
+int w32_listen (int, int);
+int w32_accept (int, struct sockaddr *, int *);
+int w32_closesocket (int);
+int w32_recvfrom (int, char *, int, int, struct sockaddr *, int *);
+int w32_shutdown (int, int);
+int socket_to_fd (SOCKET);
+SOCKET valid_socket (int);
+
+#endif /* __MINGW32__ */
+
+#endif /* GAWK_SOCKET_H */
diff --git a/pc/testoutcmp.awk b/pc/testoutcmp.awk
new file mode 100644
index 00000000..33dcaa3f
--- /dev/null
+++ b/pc/testoutcmp.awk
@@ -0,0 +1,57 @@
+# cmp replacement program for PC where the error messages aren't
+# exactly the same. should run even on old awk
+#
+# Copyright (C) 2011 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 3 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 (FNR == NR)
+ file = 0
+ else
+ file = 1
+ gsub(/\r/, "", $0)
+ lines[file, FNR] = $0
+}
+
+END {
+ if (NR/2 != FNR) {
+ printf("testoutcmp: warning: files are not of equal length!\n") > "/dev/stderr"
+ exit 1
+ }
+
+ for (i = 1; i <= FNR; i++) {
+ good = lines[0, i]
+ actual = lines[1, i]
+ if (good == actual)
+ continue
+
+ l = length(good)
+ if (substr(good, l, 1) == ")")
+ l--
+ if (substr(good, 1, l) == substr(actual, 1, l))
+ continue
+ else {
+ printf("%s and %s are not equal\n", ARGV[1],
+ ARGV[2]) > "/dev/stderr"
+ exit 1
+ }
+ }
+
+ exit 0
+}
diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt
new file mode 100644
index 00000000..cd930077
--- /dev/null
+++ b/po/CMakeLists.txt
@@ -0,0 +1,133 @@
+# Most of this copied from the repository of Stellarium
+# http://sourceforge.net/projects/stellarium/
+
+# Special targets for translations:
+#
+# translations
+# Converts all PO files to GMO files. Note that it does *not* update
+# the PO files or the PO templates -- in fact, these files are never
+# updated automatically.
+#
+# generate-pot
+# Re-creates all POT files unconditionally.
+#
+# update-po
+# Updates all PO files unconditionally. Note that it takes care of
+# updating the POT files.
+#
+# translations-<DOMAIN>
+# generate-pot-<DOMAIN>
+# update-po-<DOMAIN>
+# Same as above, but only affect the files in the corresponding
+# po/<DOMAIN> directory. (DOMAIN is actually the base name of the POT
+# file in the subdirectory, but that should match the directory name
+# anyway.)
+
+ADD_CUSTOM_TARGET(translations)
+ADD_CUSTOM_TARGET(generate-pot)
+ADD_CUSTOM_TARGET(update-po)
+
+# GETTEXT_CREATE_TRANSLATIONS(domain [DEFAULT_TARGET] lang1 ... langN)
+#
+# Creates custom build rules to create and install (G)MO files for the
+# specified languages. If the DEFAULT_TARGET option is used, the
+# translations will also be created when building the default target.
+#
+# "domain" is the translation domain, eg. "gawk". A POT file
+# with the name ${domain}.pot must exist in the directory of the
+# CMakeLists.txt file invoking the macro.
+#
+# This macro also creates the "translations-${domain}" and
+# "update-po-${domain}" targets (see above for an explanation).
+#
+MACRO(GETTEXT_CREATE_TRANSLATIONS _domain _firstLang)
+
+ SET(_gmoFiles)
+ GET_FILENAME_COMPONENT(_absPotFile ${_domain}.pot ABSOLUTE)
+
+ # Update these PO files when building the "update-po-<DOMAIN>" and
+ # "update-po" targets.
+ ADD_CUSTOM_TARGET(update-po-${_domain})
+ ADD_DEPENDENCIES(update-po update-po-${_domain})
+
+ # Make sure the POT file is updated before updating the PO files.
+ ADD_DEPENDENCIES(update-po-${_domain} generate-pot-${_domain})
+
+ SET(_addToAll)
+ IF(${_firstLang} STREQUAL "DEFAULT_TARGET")
+ SET(_addToAll "ALL")
+ SET(_firstLang)
+ ENDIF(${_firstLang} STREQUAL "DEFAULT_TARGET")
+
+ FOREACH (_lang ${ARGN})
+ GET_FILENAME_COMPONENT(_absFile ${_lang}.po ABSOLUTE)
+ FILE(RELATIVE_PATH _relFile ${PROJECT_SOURCE_DIR} ${_absFile})
+ SET(_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_lang}.gmo)
+
+ # Convert a PO file into a GMO file.
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${_gmoFile}
+ COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${_gmoFile} ${_absFile}
+ DEPENDS ${_absFile}
+ )
+
+ # Update the PO file unconditionally when building the
+ # "update-po-<DOMAIN>" target. Note that to see the file being
+ # processed, we have to run "cmake -E echo", because the
+ # COMMENT is not displayed by cmake...
+ ADD_CUSTOM_COMMAND(
+ TARGET update-po-${_domain}
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E echo "** Updating ${_relFile}"
+ COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE}
+ --quiet --update -m --backup=none -s
+ ${_absFile} ${_absPotFile}
+ VERBATIM
+ )
+
+ INSTALL(FILES ${_gmoFile} DESTINATION share/locale/${_lang}/LC_MESSAGES RENAME ${_domain}.mo)
+ SET(_gmoFiles ${_gmoFiles} ${_gmoFile})
+
+ ENDFOREACH (_lang)
+
+ # Create the GMO files when building the "translations-<DOMAIN>" and
+ # "translations" targets.
+ ADD_CUSTOM_TARGET(translations-${_domain} ${_addToAll} DEPENDS ${_gmoFiles})
+ ADD_DEPENDENCIES(translations translations-${_domain})
+
+ENDMACRO(GETTEXT_CREATE_TRANSLATIONS )
+
+SET(gawk_DOMAIN gawk)
+SET(gawk_POT ${gawk_DOMAIN}.pot)
+
+file(READ LINGUAS linguas)
+string(REGEX REPLACE "\n" ";" linguas ${linguas})
+GETTEXT_CREATE_TRANSLATIONS(${gawk_DOMAIN} DEFAULT_TARGET ${linguas})
+
+ADD_CUSTOM_TARGET(
+ generate-pot-${gawk_DOMAIN}
+ ${GETTEXT_XGETTEXT_EXECUTABLE}
+ -o ${CMAKE_CURRENT_SOURCE_DIR}/${gawk_POT}
+ -C
+ --keyword=_
+ --keyword=N_
+ --keyword=q_
+ --keyword=translate:2
+ --add-comments=TRANSLATORS:
+ --directory=${CMAKE_BINARY_DIR}
+ --directory=${CMAKE_SOURCE_DIR}
+ --output-dir=${CMAKE_BINARY_DIR}
+ --files-from=${CMAKE_CURRENT_SOURCE_DIR}/POTFILES.in
+ --copyright-holder=FSF
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ COMMENT "Generating ${gawk_POT}"
+ VERBATIM
+)
+# TODO: It would be nice to just depend on the exact files in POTFILES.in
+#file(READ ${CMAKE_CURRENT_SOURCE_DIR}/${gawk_POT} UiHeaders)
+#ADD_DEPENDENCIES(generate-pot-${gawk_DOMAIN} UiHeaders)
+#ADD_DEPENDENCIES(generate-pot-${gawk_DOMAIN} gawk_UIS_H)
+# Make sure the UI headers are created first.
+ADD_DEPENDENCIES(generate-pot-${gawk_DOMAIN} StelGuiLib) # ??? FIXME
+# Generate this POT file when building the "generate-pot" target.
+ADD_DEPENDENCIES(generate-pot generate-pot-${gawk_DOMAIN})
diff --git a/po/ChangeLog b/po/ChangeLog
index ff5d3695..022e5326 100644
--- a/po/ChangeLog
+++ b/po/ChangeLog
@@ -1,3 +1,32 @@
+2014-11-19 gettextize <bug-gnu-gettext@gnu.org>
+
+ * Makefile.in.in: Upgrade to gettext-0.19.3.
+ * Rules-quot: Upgrade to gettext-0.19.3.
+
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.1: Release tar ball made.
+
+2013-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.0: Release tar ball made.
+
+2013-04-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * POTFILES.in: Brought up to date.
+
+2012-12-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.2: Release tar ball made.
+
+2012-07-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * POTFILES.in: Brought up to date.
+
+2012-03-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.1: Release tar ball made.
+
2011-07-17 Arnold D. Robbins <arnold@skeeve.com>
* Makefile.in.in (dist2): Remove README from list of files checked for
diff --git a/po/LINGUAS b/po/LINGUAS
index 1e55e059..d00794ef 100644
--- a/po/LINGUAS
+++ b/po/LINGUAS
@@ -1,3 +1,4 @@
+ca
da
de
es
@@ -5,6 +6,8 @@ fi
fr
it
ja
+ms
nl
pl
sv
+vi
diff --git a/po/Makefile.in.in b/po/Makefile.in.in
index 83d8838a..65184f65 100644
--- a/po/Makefile.in.in
+++ b/po/Makefile.in.in
@@ -8,13 +8,14 @@
# 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.18
-GETTEXT_MACRO_VERSION = 0.18
+# Origin: gettext-0.19
+GETTEXT_MACRO_VERSION = 0.19
PACKAGE = @PACKAGE@
VERSION = @VERSION@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+SED = @SED@
SHELL = /bin/sh
@SET_MAKE@
@@ -76,6 +77,16 @@ POTFILES = \
CATALOGS = @CATALOGS@
+POFILESDEPS_ = $(srcdir)/$(DOMAIN).pot
+POFILESDEPS_yes = $(POFILESDEPS_)
+POFILESDEPS_no =
+POFILESDEPS = $(POFILESDEPS_$(PO_DEPENDS_ON_POT))
+
+DISTFILESDEPS_ = update-po
+DISTFILESDEPS_yes = $(DISTFILESDEPS_)
+DISTFILESDEPS_no =
+DISTFILESDEPS = $(DISTFILESDEPS_$(DIST_DEPENDS_ON_UPDATE_PO))
+
# Makevars gets inserted here. (Don't remove this line!)
.SUFFIXES:
@@ -96,14 +107,14 @@ CATALOGS = @CATALOGS@
mv t-$@ $@
-all: check-macro-version all-@USE_NLS@
+all: all-@USE_NLS@
all-yes: stamp-po
all-no:
# Ensure that the gettext macros and this Makefile.in.in are in sync.
-check-macro-version:
- @test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \
+CHECK_MACRO_VERSION = \
+ test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \
|| { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \
exit 1; \
}
@@ -123,6 +134,7 @@ check-macro-version:
# $(POFILES) has been designed to not touch files that don't need to be
# changed.
stamp-po: $(srcdir)/$(DOMAIN).pot
+ @$(CHECK_MACRO_VERSION)
test ! -f $(srcdir)/$(DOMAIN).pot || \
test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES)
@test ! -f $(srcdir)/$(DOMAIN).pot || { \
@@ -137,11 +149,29 @@ stamp-po: $(srcdir)/$(DOMAIN).pot
# 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.
+# The determination of whether the package xyz is a GNU one is based on the
+# heuristic whether some file in the top level directory mentions "GNU xyz".
+# If GNU 'find' is available, we avoid grepping through monster files.
$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed
- if LC_ALL=C grep 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null | grep -v 'libtool:' >/dev/null; then \
- package_gnu='GNU '; \
+ package_gnu="$(PACKAGE_GNU)"; \
+ test -n "$$package_gnu" || { \
+ if { if (LC_ALL=C find --version) 2>/dev/null | grep GNU >/dev/null; then \
+ LC_ALL=C find -L $(top_srcdir) -maxdepth 1 -type f \
+ -size -10000000c -exec grep 'GNU @PACKAGE@' \
+ /dev/null '{}' ';' 2>/dev/null; \
+ else \
+ LC_ALL=C grep 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null; \
+ fi; \
+ } | grep -v 'libtool:' >/dev/null; then \
+ package_gnu=yes; \
+ else \
+ package_gnu=no; \
+ fi; \
+ }; \
+ if test "$$package_gnu" = "yes"; then \
+ package_prefix='GNU '; \
else \
- package_gnu=''; \
+ package_prefix=''; \
fi; \
if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \
msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \
@@ -161,7 +191,7 @@ $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed
--add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \
--files-from=$(srcdir)/POTFILES.in \
--copyright-holder='$(COPYRIGHT_HOLDER)' \
- --package-name="$${package_gnu}@PACKAGE@" \
+ --package-name="$${package_prefix}@PACKAGE@" \
--package-version='@VERSION@' \
--msgid-bugs-address="$$msgid_bugs_address" \
;; \
@@ -189,9 +219,10 @@ $(srcdir)/$(DOMAIN).pot:
# 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
+$(POFILES): $(POFILESDEPS)
@lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \
if test -f "$(srcdir)/$${lang}.po"; then \
+ test -f $(srcdir)/$(DOMAIN).pot || $(MAKE) $(srcdir)/$(DOMAIN).pot; \
test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \
cd $(srcdir) \
@@ -352,7 +383,7 @@ maintainer-clean: distclean
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
dist distdir:
- $(MAKE) update-po
+ test -z "$(DISTFILESDEPS)" || $(MAKE) $(DISTFILESDEPS)
@$(MAKE) dist2
# This is a separate target because 'update-po' must be executed before.
dist2: stamp-po $(DISTFILES)
diff --git a/po/Makevars b/po/Makevars
index c5a271db..4293de4e 100644
--- a/po/Makevars
+++ b/po/Makevars
@@ -20,6 +20,13 @@ XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
# their copyright.
COPYRIGHT_HOLDER = Free Software Foundation, Inc.
+# This tells whether or not to prepend "GNU " prefix to the package
+# name that gets inserted into the header of the $(DOMAIN).pot file.
+# Possible values are "yes", "no", or empty. If it is empty, try to
+# detect it automatically by scanning the files in $(top_srcdir) for
+# "GNU packagename" string.
+PACKAGE_GNU =
+
# 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
@@ -34,8 +41,38 @@ COPYRIGHT_HOLDER = Free Software Foundation, Inc.
# 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
+MSGID_BUGS_ADDRESS = bug-gawk@gnu.org
# 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 =
+
+# This tells whether the $(DOMAIN).pot file contains messages with an 'msgctxt'
+# context. Possible values are "yes" and "no". Set this to yes if the
+# package uses functions taking also a message context, like pgettext(), or
+# if in $(XGETTEXT_OPTIONS) you define keywords with a context argument.
+USE_MSGCTXT = no
+
+# These options get passed to msgmerge.
+# Useful options are in particular:
+# --previous to keep previous msgids of translated messages,
+# --quiet to reduce the verbosity.
+MSGMERGE_OPTIONS =
+
+# These options get passed to msginit.
+# If you want to disable line wrapping when writing PO files, add
+# --no-wrap to MSGMERGE_OPTIONS, XGETTEXT_OPTIONS, and
+# MSGINIT_OPTIONS.
+MSGINIT_OPTIONS =
+
+# This tells whether or not to regenerate a PO file when $(DOMAIN).pot
+# has changed. Possible values are "yes" and "no". Set this to no if
+# the POT file is checked in the repository and the version control
+# program ignores timestamps.
+PO_DEPENDS_ON_POT = yes
+
+# This tells whether or not to forcibly update $(DOMAIN).pot and
+# regenerate PO files on "make dist". Possible values are "yes" and
+# "no". Set this to no if the POT file and PO files are maintained
+# externally.
+DIST_DEPENDS_ON_UPDATE_PO = yes
diff --git a/po/Makevars.template b/po/Makevars.template
index 32692ab4..0648ec75 100644
--- a/po/Makevars.template
+++ b/po/Makevars.template
@@ -20,6 +20,13 @@ XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
# their copyright.
COPYRIGHT_HOLDER = Free Software Foundation, Inc.
+# This tells whether or not to prepend "GNU " prefix to the package
+# name that gets inserted into the header of the $(DOMAIN).pot file.
+# Possible values are "yes", "no", or empty. If it is empty, try to
+# detect it automatically by scanning the files in $(top_srcdir) for
+# "GNU packagename" string.
+PACKAGE_GNU =
+
# 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
@@ -39,3 +46,33 @@ MSGID_BUGS_ADDRESS =
# 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 =
+
+# This tells whether the $(DOMAIN).pot file contains messages with an 'msgctxt'
+# context. Possible values are "yes" and "no". Set this to yes if the
+# package uses functions taking also a message context, like pgettext(), or
+# if in $(XGETTEXT_OPTIONS) you define keywords with a context argument.
+USE_MSGCTXT = no
+
+# These options get passed to msgmerge.
+# Useful options are in particular:
+# --previous to keep previous msgids of translated messages,
+# --quiet to reduce the verbosity.
+MSGMERGE_OPTIONS =
+
+# These options get passed to msginit.
+# If you want to disable line wrapping when writing PO files, add
+# --no-wrap to MSGMERGE_OPTIONS, XGETTEXT_OPTIONS, and
+# MSGINIT_OPTIONS.
+MSGINIT_OPTIONS =
+
+# This tells whether or not to regenerate a PO file when $(DOMAIN).pot
+# has changed. Possible values are "yes" and "no". Set this to no if
+# the POT file is checked in the repository and the version control
+# program ignores timestamps.
+PO_DEPENDS_ON_POT = yes
+
+# This tells whether or not to forcibly update $(DOMAIN).pot and
+# regenerate PO files on "make dist". Possible values are "yes" and
+# "no". Set this to no if the POT file and PO files are maintained
+# externally.
+DIST_DEPENDS_ON_UPDATE_PO = yes
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 807df336..63461e76 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,17 +1,34 @@
# List of source files containing translatable strings.
-# Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+# Copyright (C) 1999, 2002, 2012 Free Software Foundation, Inc.
array.c
awkgram.c
builtin.c
+cint_array.c
+command.c
+debug.c
+dfa.c
eval.c
ext.c
+extension/filefuncs.c
+extension/fnmatch.c
+extension/fork.c
+extension/inplace.c
+extension/ordchr.c
+extension/readdir.c
+extension/readfile.c
+extension/rwarray.c
+extension/time.c
field.c
+floatcomp.c
+gawkapi.c
gawkmisc.c
getopt.c
getopt1.c
+int_array.c
io.c
main.c
+mpfr.c
msg.c
node.c
posix/gawkmisc.c
@@ -19,6 +36,10 @@ profile.c
random.c
re.c
regcomp.c
+regex.c
regex_internal.c
regexec.c
replace.c
+str_array.c
+symbol.c
+version.c
diff --git a/po/Rules-quot b/po/Rules-quot
index af524879..9dc96307 100644
--- a/po/Rules-quot
+++ b/po/Rules-quot
@@ -1,3 +1,4 @@
+# This file, Rules-quot, can be copied and used freely without restrictions.
# 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
@@ -14,13 +15,23 @@ 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; \
+ if test "$(PACKAGE)" = "gettext-tools"; 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 $$lang -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 $(MSGINIT) $(MSGINIT_OPTIONS) -i $(DOMAIN).pot --no-translator -l $$lang -o - 2>/dev/null \
+ | $(SED) -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | \
+ { case `$(MSGFILTER) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-8] | 0.1[0-8].*) \
+ $(MSGFILTER) $(SED) -f `echo $$lang | sed -e 's/.*@//'`.sed \
+ ;; \
+ *) \
+ $(MSGFILTER) `echo $$lang | sed -e 's/.*@//'` \
+ ;; \
+ esac } 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 \
diff --git a/po/ast.gmo b/po/ast.gmo
deleted file mode 100644
index 7c2ac4e2..00000000
--- a/po/ast.gmo
+++ /dev/null
Binary files differ
diff --git a/po/ca.gmo b/po/ca.gmo
index 426541dc..465f05a5 100644
--- a/po/ca.gmo
+++ b/po/ca.gmo
Binary files differ
diff --git a/po/ca.po b/po/ca.po
index d7b6e552..444f09c4 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -1,14 +1,15 @@
# translation of gawk.po to Catalan
# Copyright (C) 2003 Free Software Foundation, Inc.
+# This file is distributed under the same license as the gawk package.
# Antoni Bella Perez <bella5@teleline.es>, 2003.
-#
+# Walter Garcia-Fontes <walter.garcia@upf.edu>, 2014.
msgid ""
msgstr ""
-"Project-Id-Version: gawk 3.1.31\n"
+"Project-Id-Version: gawk 4.1.0b\n"
"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
-"POT-Creation-Date: 2011-03-18 12:00+0200\n"
-"PO-Revision-Date: 2003-05-07 21:13+0100\n"
-"Last-Translator: Antoni Bella Perez <bella5@teleline.es>\n"
+"POT-Creation-Date: 2014-04-08 19:23+0300\n"
+"PO-Revision-Date: 2014-02-26 20:18+0100\n"
+"Last-Translator: Walter Garcia-Fontes <walter.garcia@upf.edu>\n"
"Language-Team: Catalan <ca@dodds.net>\n"
"Language: ca\n"
"MIME-Version: 1.0\n"
@@ -16,880 +17,1897 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.0.1\n"
-#: array.c:103
-#, fuzzy, c-format
+#: array.c:256
+#, c-format
msgid "from %s"
-msgstr "%s (de %s)"
+msgstr "de %s"
-#: array.c:267
-#, fuzzy
+#: array.c:357
msgid "attempt to use a scalar value as array"
-msgstr "s'ha intentat usar la dada escalar «%s» com a una matriu"
-
-#: array.c:270
-#, fuzzy, c-format
-msgid "attempt to use function `%s' as an array"
-msgstr "s'ha intentat usar la funció «%s» com a una matriu"
+msgstr "s'ha intentat usar un valor escalar com a una matriu"
-#: array.c:273
+#: array.c:359
#, 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"
+msgstr "s'ha intentat usar un paràmetre escalar `%s' com a una matriu"
-#: array.c:276 eval.c:2013
-#, fuzzy, c-format
+#: array.c:362
+#, c-format
msgid "attempt to use scalar `%s' as an array"
-msgstr "s'ha intentat usar la dada escalar «%s» com a una matriu"
+msgstr "s'ha intentat usar la dada escalar `%s' com a una matriu"
-#: array.c:321 array.c:648 builtin.c:75 builtin.c:555 builtin.c:597
-#: builtin.c:610 builtin.c:1016 builtin.c:1028 eval.c:1381 eval.c:1385
-#: eval.c:1710 eval.c:1958 eval.c:2026 eval.c:2274
+#: array.c:409 array.c:576 builtin.c:85 builtin.c:1615 builtin.c:1661
+#: builtin.c:1674 builtin.c:2102 builtin.c:2116 eval.c:1122 eval.c:1126
+#: eval.c:1531
#, c-format
msgid "attempt to use array `%s' in a scalar context"
-msgstr "s'ha intentat usar la matriu «%s» en un context escalar"
-
-#: array.c:570
-#, fuzzy, c-format
-msgid "reference to uninitialized element `%s[\"%.*s\"]'"
-msgstr "referència a un element sense valor inicial «%s[\"%s\"]»"
+msgstr "s'ha intentat usar la matriu `%s' en un context escalar"
-#: array.c:576
-#, c-format
-msgid "subscript of array `%s' is null string"
-msgstr "el subscript de la matriu «%s» és una cadena nul·la"
-
-#: array.c:684
+#: array.c:583
#, c-format
msgid "delete: index `%s' not in array `%s'"
-msgstr "delete: l'índex «%s» no està en la matriu «%s»"
-
-#: array.c:708
-#, fuzzy, c-format
-msgid "attempt to use scalar `%s[\"%.*s\"]' as an array"
-msgstr "s'ha intentat usar la dada escalar «%s» com a una matriu"
+msgstr "delete: l'índex `%s' no està en la matriu `%s'"
-#: array.c:871
+#: array.c:597
#, c-format
-msgid "%s: empty (null)\n"
-msgstr "%s: buit (nul)\n"
-
-#: array.c:876
-#, c-format
-msgid "%s: empty (zero)\n"
-msgstr "%s: buit (zero)\n"
-
-#: array.c:880
-#, c-format
-msgid "%s: table_size = %d, array_size = %d\n"
-msgstr "%s: mida_taula = %d, mida_matriu = %d\n"
-
-#: array.c:915
-#, fuzzy, c-format
-msgid "%s: is parameter\n"
-msgstr "%s: és un paràmetre\n"
-
-#: array.c:919
-#, c-format
-msgid "%s: array_ref to %s\n"
-msgstr "%s: ref_matriu a %s\n"
-
-#: array.c:924
-#, fuzzy
-msgid "adump: argument not an array"
-msgstr "asort: el primer argument no és una matriu"
+msgid "attempt to use scalar `%s[\"%.*s\"]' as an array"
+msgstr "s'ha intentat usar la dada escalar `%s[\"%.*s\"]' com a una matriu"
-#: array.c:1142
-#, fuzzy
-msgid "attempt to use array in a scalar context"
-msgstr "s'ha intentat usar la matriu «%s» en un context escalar"
+#: array.c:776
+msgid "adump: first argument not an array"
+msgstr "adump: el primer argument no és una matriu"
-#: array.c:1239
-#, fuzzy
+#: array.c:815
msgid "asort: second argument not an array"
msgstr "asort: el segon argument no és una matriu"
-#: array.c:1240
-#, fuzzy
+#: array.c:816
msgid "asorti: second argument not an array"
-msgstr "asort: el segon argument no és una matriu"
+msgstr "asorti: el segon argument no és una matriu"
-#: array.c:1247
-#, fuzzy
+#: array.c:823
msgid "asort: first argument not an array"
msgstr "asort: el primer argument no és una matriu"
-#: array.c:1248
-#, fuzzy
+#: array.c:824
msgid "asorti: first argument not an array"
msgstr "asort: el primer argument no és una matriu"
-#: awkgram.y:249
-#, fuzzy, c-format
+#: array.c:831
+msgid "asort: cannot use a subarray of first arg for second arg"
+msgstr ""
+"asort: no es pot usar una submatriu com a primer argument per al segon "
+"argument"
+
+#: array.c:832
+msgid "asorti: cannot use a subarray of first arg for second arg"
+msgstr ""
+"asorti: no es pot usar una submatriu com a primer argument per al segon "
+"argument"
+
+#: array.c:837
+msgid "asort: cannot use a subarray of second arg for first arg"
+msgstr ""
+"asort: no es pot usar una submatriu com a segon argument per al primer "
+"argument"
+
+#: array.c:838
+msgid "asorti: cannot use a subarray of second arg for first arg"
+msgstr ""
+"asorti: no es pot usar una submatriu com a segon argument per al primer "
+"argument"
+
+#: array.c:1314
+#, c-format
+msgid "`%s' is invalid as a function name"
+msgstr "`%s' no és vàlid com a nom de funció"
+
+#: array.c:1318
+#, c-format
+msgid "sort comparison function `%s' is not defined"
+msgstr "la funció de comparació d'ordenació `%s' no està definida"
+
+#: awkgram.y:233
+#, c-format
msgid "%s blocks must have an action part"
-msgstr "Els blocs FINAL han de tindre una part d'acció"
+msgstr "%s blocs han de tenir una part d'acció"
-#: awkgram.y:252
-#, fuzzy
+#: awkgram.y:236
msgid "each rule must have a pattern or an action part"
-msgstr "Els blocs FINAL han de tindre una part d'acció"
+msgstr "cada regla ha de tenir un patró o una part d'acció"
-#: awkgram.y:323 awkgram.y:334
-#, fuzzy
+#: awkgram.y:325 awkgram.y:336
msgid "old awk does not support multiple `BEGIN' or `END' rules"
-msgstr "l'antic awk no suporta l'operador «**=»"
+msgstr "l'antic awk no suporta múltiples regles `BEGIN' i `END'"
-#: awkgram.y:371
+#: awkgram.y:373
#, c-format
msgid "`%s' is a built-in function, it cannot be redefined"
-msgstr "«%s» és una funció interna, no pot ser redefinida"
+msgstr "`%s' és una funció interna, no pot ser redefinida"
-#: awkgram.y:432
-#, fuzzy
+#: awkgram.y:419
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 "
+"la constant d'expressió regular `//' sembla un comentari en C++, però no ho "
"és"
-#: awkgram.y:436
+#: awkgram.y:423
#, 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 "
+"la constant d'expressió regular `/%s/' sembla un comentari en C, però no ho "
"és"
-#: awkgram.y:528
+#: awkgram.y:515
#, c-format
msgid "duplicate case values in switch body: %s"
-msgstr ""
+msgstr "valors duplicats de casos al cos de l'expressió switch: %s"
-#: awkgram.y:549
+#: awkgram.y:536
msgid "duplicate `default' detected in switch body"
msgstr ""
+"s'ha detectat el cas predeterminat `default' duplicat a l'expressió switch "
-#: awkgram.y:811
-#, fuzzy
+#: awkgram.y:796 awkgram.y:3723
msgid "`break' is not allowed outside a loop or switch"
-msgstr "no es permet «break» a fora d'un bucle"
+msgstr "no es permet `break' a fora d'un bucle o bifurcació"
-#: awkgram.y:820
-#, fuzzy
+#: awkgram.y:805 awkgram.y:3715
msgid "`continue' is not allowed outside a loop"
-msgstr "no es permet «continue» a fora d'un bucle"
+msgstr "no es permet `continue' a fora d'un bucle"
-#: awkgram.y:829
-#, fuzzy, c-format
+#: awkgram.y:815
+#, c-format
msgid "`next' used in %s action"
-msgstr "«next» és usat dintre de l'acció BEGIN o END"
-
-#: awkgram.y:837
-msgid "`nextfile' is a gawk extension"
-msgstr "«nextfile» és una extensió de gawk"
+msgstr "`next' usat a l'acció %s"
-#: awkgram.y:840
-#, fuzzy, c-format
+#: awkgram.y:824
+#, c-format
msgid "`nextfile' used in %s action"
-msgstr "«next» és usat dintre de l'acció BEGIN o END"
+msgstr "`nextfile' usat a l'acció %s"
-#: awkgram.y:863
+#: awkgram.y:848
msgid "`return' used outside function context"
-msgstr "«return» és usat fora del context d'una funció"
+msgstr "`return' és usat fora del context d'una funció"
-#: awkgram.y:923
+#: awkgram.y:922
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 \"\"»"
+"el `print'» simple en la regla BEGIN o END probablement ha de ser `print "
+"\"\"'"
+
+#: awkgram.y:988 awkgram.y:1037
+msgid "`delete' is not allowed with SYMTAB"
+msgstr "no es permet `delete' amb SYMTAB"
-#: awkgram.y:993 awkgram.y:997 awkgram.y:1021
-msgid "`delete array' is a gawk extension"
-msgstr "«delete array» és una extensió de gawk"
+#: awkgram.y:990 awkgram.y:1039
+msgid "`delete' is not allowed with FUNCTAB"
+msgstr "no es permet `delete' a FUNCTAB"
-#: awkgram.y:1017
-#, fuzzy
+#: awkgram.y:1024 awkgram.y:1028
msgid "`delete(array)' is a non-portable tawk extension"
-msgstr "«delete array» és una extensió de gawk"
+msgstr "`delete(array)' és una extensió tawk no portable"
-#: awkgram.y:1133
+#: awkgram.y:1149
msgid "multistage two-way pipelines don't work"
msgstr "les canonades bidireccionals multi-etapes no funcionen"
-#: awkgram.y:1236
+#: awkgram.y:1264
msgid "regular expression on right of assignment"
msgstr "expressió regular a la dreta d'una assignació"
-#: awkgram.y:1247
+#: awkgram.y:1275
msgid "regular expression on left of `~' or `!~' operator"
-msgstr "expressió regular a l'esquerra de l'operador «~» o «!~»"
+msgstr "expressió regular a l'esquerra de l'operador `~' o `!~'"
-#: awkgram.y:1263 awkgram.y:1417
-#, fuzzy
+#: awkgram.y:1291 awkgram.y:1442
msgid "old awk does not support the keyword `in' except after `for'"
-msgstr "l'antic awk no suporta l'operador «**=»"
+msgstr ""
+"l'antic awk no dóna suport a la paraula clau `in' excepte després de `for'"
-#: awkgram.y:1273
+#: awkgram.y:1301
msgid "regular expression on right of comparison"
-msgstr "expressió regular a la derta de la comparació"
+msgstr "expressió regular a la dreta de la comparació"
-#: awkgram.y:1392
-#, fuzzy, c-format
+#: awkgram.y:1417
+#, c-format
msgid "`getline var' invalid inside `%s' rule"
-msgstr "port remot no vàlid en «%s»"
+msgstr "`getline var' no és vàlid a dins de la regla `%s'"
-#: awkgram.y:1395 eval.c:2649
-#, fuzzy, c-format
+#: awkgram.y:1420
+#, c-format
msgid "`getline' invalid inside `%s' rule"
-msgstr "port remot no vàlid en «%s»"
+msgstr "`getline' no és vàlid a dins de la regla `%s'"
-#: awkgram.y:1400
+#: awkgram.y:1425
msgid "non-redirected `getline' undefined inside END action"
-msgstr "«getline» no redirigit sense definir dintre de l'acció FINAL"
+msgstr "`getline' no redirigit sense definir dintre de l'acció FINAL"
-#: awkgram.y:1419
-#, fuzzy
+#: awkgram.y:1444
msgid "old awk does not support multidimensional arrays"
-msgstr "l'antic awk no suporta l'operador «**=»"
+msgstr "l'antic awk no suporta matrius multidimensionals"
-#: awkgram.y:1515
+#: awkgram.y:1541
msgid "call of `length' without parentheses is not portable"
-msgstr "la crida de «length» sense parèntesis no és portable"
+msgstr "la crida de `length' sense parèntesis no és portable"
-#: awkgram.y:1578
-#, fuzzy
+#: awkgram.y:1607
msgid "indirect function calls are a gawk extension"
-msgstr "«nextfile» és una extensió de gawk"
+msgstr "les crides a funcions indirectes són una extensió gawk"
-#: awkgram.y:1591
-#, fuzzy, c-format
+#: awkgram.y:1620
+#, c-format
msgid "can not use special variable `%s' for indirect function call"
-msgstr "funció «%s»: no pot usar el nom de la funció com a paràmetre"
+msgstr ""
+"no es pot usar la variable especial `%s' per a una crida indirecta de funció"
-#: awkgram.y:1669
+#: awkgram.y:1698
msgid "invalid subscript expression"
-msgstr "expressió de subscript no vàlida"
+msgstr "expressió de subíndex no vàlida"
-#: awkgram.y:1709
-msgid "use of non-array as array"
-msgstr ""
-
-#: awkgram.y:1973 awkgram.y:1993 msg.c:98
+#: awkgram.y:2048 awkgram.y:2068 gawkapi.c:206 gawkapi.c:224 msg.c:126
msgid "warning: "
-msgstr "ADVERTIMENT: "
+msgstr "advertiment: "
-#: awkgram.y:1991 msg.c:130
+#: awkgram.y:2066 gawkapi.c:192 gawkapi.c:221 msg.c:158
msgid "fatal: "
-msgstr "Fatal: "
+msgstr "fatal: "
-#: awkgram.y:2041
-#, fuzzy
+#: awkgram.y:2116
msgid "unexpected newline or end of string"
-msgstr "nova línia inesperada"
+msgstr "nova línia inesperada o final d'una cadena de caràcters"
-#: awkgram.y:2297 awkgram.y:2355 awkgram.y:2539
+#: awkgram.y:2383 awkgram.y:2459 awkgram.y:2682 debug.c:523 debug.c:539
+#: debug.c:2812 debug.c:5055
#, 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)"
+msgstr "no es pot obrir el fitxer font `%s' per a lectura (%s)"
+
+#: awkgram.y:2384 awkgram.y:2509
+#, c-format
+msgid "can't open shared library `%s' for reading (%s)"
+msgstr "no es pot obrir la llibreria compartida `%s' per a lectura (%s)"
-#: awkgram.y:2298 awkgram.y:2356 builtin.c:119
+#: awkgram.y:2386 awkgram.y:2460 awkgram.y:2510 builtin.c:135 debug.c:5206
msgid "reason unknown"
msgstr "motiu desconegut"
-#: awkgram.y:2314
-#, fuzzy, c-format
+#: awkgram.y:2395 awkgram.y:2419
+#, c-format
+msgid "can't include `%s' and use it as a program file"
+msgstr "no es pot incloure `%s' i usar-lo com un fitxer de programa"
+
+#: awkgram.y:2408
+#, c-format
msgid "already included source file `%s'"
-msgstr "no es pot llegir el fitxer font «%s» (%s)"
+msgstr "ja s'ha inclòs el fitxer font `%s'"
+
+#: awkgram.y:2409
+#, c-format
+msgid "already loaded shared library `%s'"
+msgstr "ja s'ha carregat la biblioteca compartida `%s'"
-#: awkgram.y:2340
-#, fuzzy
+#: awkgram.y:2444
msgid "@include is a gawk extension"
-msgstr "«nextfile» és una extensió de gawk"
+msgstr "@include és una extensió de gawk"
-#: awkgram.y:2346
+#: awkgram.y:2450
msgid "empty filename after @include"
-msgstr ""
+msgstr "nom de fitxer buit després de @include"
+
+#: awkgram.y:2494
+msgid "@load is a gawk extension"
+msgstr "@load és una extensió de gawk"
+
+#: awkgram.y:2500
+msgid "empty filename after @load"
+msgstr "fitxer buit després de @load"
-#: awkgram.y:2491
+#: awkgram.y:2634
msgid "empty program text on command line"
msgstr "el text del programa en la línia de comandaments està buit"
-#: awkgram.y:2606
+#: awkgram.y:2749
#, c-format
msgid "can't read sourcefile `%s' (%s)"
-msgstr "no es pot llegir el fitxer font «%s» (%s)"
+msgstr "no es pot llegir el fitxer font `%s' (%s)"
-#: awkgram.y:2617
+#: awkgram.y:2760
#, c-format
msgid "source file `%s' is empty"
-msgstr "el fitxer font «%s» està buit"
+msgstr "el fitxer font `%s' està buit"
-#: awkgram.y:2802
+#: awkgram.y:2937
msgid "source file does not end in newline"
msgstr "el fitxer font no finalitza amb un retorn de carro"
-#: awkgram.y:2879
+#: awkgram.y:3042
msgid "unterminated regexp ends with `\\' at end of file"
-msgstr "expressió regular sense finalitzar acaba amb «\\» al final del fitxer"
+msgstr "expressió regular sense finalitzar acaba amb `\\' al final del fitxer"
-#: awkgram.y:2903
+#: awkgram.y:3066
#, c-format
msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
-msgstr ""
+msgstr "%s: %d: el modificador regex tawk `/.../%c' no funciona a gawk"
-#: awkgram.y:2907
+#: awkgram.y:3070
#, c-format
msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
-msgstr ""
+msgstr "el modificador regex tawk `/.../%c' no funciona a gawk"
-#: awkgram.y:2914
+#: awkgram.y:3077
msgid "unterminated regexp"
msgstr "expressió regular sense finalitzar"
-#: awkgram.y:2918
+#: awkgram.y:3081
msgid "unterminated regexp at end of file"
msgstr "expressió regular sense finalitzar al final del fitxer"
-#: awkgram.y:2977
+#: awkgram.y:3140
msgid "use of `\\ #...' line continuation is not portable"
-msgstr "l'ús de «\\ #...» com a continuació de línia no és portable"
+msgstr "l'ús de `\\ #...' com a continuació de línia no és portable"
-#: awkgram.y:2993
+#: awkgram.y:3156
msgid "backslash not last character on line"
msgstr "la barra invertida no és l'últim caràcter en la línia"
-#: awkgram.y:3054
+#: awkgram.y:3217
msgid "POSIX does not allow operator `**='"
-msgstr "POSIX no permet l'operador «**=»"
+msgstr "POSIX no permet l'operador `**='"
-#: awkgram.y:3056
+#: awkgram.y:3219
msgid "old awk does not support operator `**='"
-msgstr "l'antic awk no suporta l'operador «**=»"
+msgstr "l'antic awk no suporta l'operador `**='"
-#: awkgram.y:3065
+#: awkgram.y:3228
msgid "POSIX does not allow operator `**'"
-msgstr "POSIX no permet l'operador «**»"
+msgstr "POSIX no permet l'operador `**'"
-#: awkgram.y:3067
+#: awkgram.y:3230
msgid "old awk does not support operator `**'"
-msgstr "l'antic awk no suporta l'operador «**=»"
+msgstr "l'antic awk no suporta l'operador `**='"
-#: awkgram.y:3102
+#: awkgram.y:3265
msgid "operator `^=' is not supported in old awk"
-msgstr "l'operador «^=» no està suportat en l'antic awk"
+msgstr "l'operador `^=' no està suportat en l'antic awk"
-#: awkgram.y:3110
+#: awkgram.y:3273
msgid "operator `^' is not supported in old awk"
-msgstr "l'operador «^» no està suportat en l'antic awk"
+msgstr "l'operador `^' no està suportat en l'antic awk"
-#: awkgram.y:3203 awkgram.y:3219
+#: awkgram.y:3366 awkgram.y:3382 command.y:1178
msgid "unterminated string"
msgstr "cadena sense finalitzar"
-#: awkgram.y:3415
+#: awkgram.y:3603
#, c-format
msgid "invalid char '%c' in expression"
-msgstr "caràcter «%c» no vàlid en l'expressió"
+msgstr "caràcter `%c' no vàlid en l'expressió"
-#: awkgram.y:3462
+#: awkgram.y:3650
#, c-format
msgid "`%s' is a gawk extension"
-msgstr "«%s» és una extensió de gawk"
-
-#: awkgram.y:3467
-#, c-format
-msgid "`%s' is a Bell Labs extension"
-msgstr "«%s» és una extensió de Bell Labs"
+msgstr "`%s' és una extensió de gawk"
-#: awkgram.y:3472
+#: awkgram.y:3655
#, c-format
msgid "POSIX does not allow `%s'"
msgstr "POSIX no permet «%s»"
-#: awkgram.y:3480
+#: awkgram.y:3663
#, c-format
msgid "`%s' is not supported in old awk"
-msgstr "«%s» no està suportat en l'antic awk"
+msgstr "`%s' no està suportat en l'antic awk"
-#: awkgram.y:3550
+#: awkgram.y:3753
msgid "`goto' considered harmful!\n"
-msgstr "«goto» se considera nefast!\n"
+msgstr "`goto' es considera perjudicial!\n"
-#: awkgram.y:3602
+#: awkgram.y:3787
#, 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:3637 awkgram.y:3640
-msgid "match: third argument is a gawk extension"
-msgstr "match: el tercer argument és una extensió de gawk"
-
-#: awkgram.y:3668
+#: awkgram.y:3822
#, 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:3673
-#, fuzzy, c-format
+#: awkgram.y:3827
+#, c-format
msgid "%s third parameter is not a changeable object"
-msgstr "sub: el tercer argument no és un objecte intercanviable"
+msgstr "%s el tercer paràmetre no és un objecte intercanviable"
+
+#: awkgram.y:3910 awkgram.y:3913
+msgid "match: third argument is a gawk extension"
+msgstr "match: el tercer argument és una extensió de gawk"
-#: awkgram.y:3759 awkgram.y:3762
+#: awkgram.y:3967 awkgram.y:3970
msgid "close: second argument is a gawk extension"
msgstr "close: el segon argument és una extensió de gawk"
-#: awkgram.y:3774
+#: awkgram.y:3982
msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
msgstr ""
"l'ús de dcgettext(_\"...\") no és correcte: elimineu el guió baix inicial"
-#: awkgram.y:3789
-#, fuzzy
+#: awkgram.y:3997
msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
msgstr ""
"l'ús de dcgettext(_\"...\") no és correcte: elimineu el guió baix inicial"
-#: awkgram.y:3881
-#, 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:4016
+msgid "index: regexp constant as second argument is not allowed"
+msgstr "índex: no es permet una constant regexp com a segon argument"
-#: awkgram.y:3923
+#: awkgram.y:4069
#, c-format
msgid "function `%s': parameter `%s' shadows global variable"
-msgstr "funció «%s»: paràmetre «%s» ofusca la variable global"
+msgstr "funció `%s': paràmetre `%s' ofusca la variable global"
-#: awkgram.y:4081
+#: awkgram.y:4126 debug.c:4041 debug.c:4084 debug.c:5204
#, c-format
msgid "could not open `%s' for writing (%s)"
-msgstr "no es pot obrir «%s» per a escriptura (%s)"
+msgstr "no es pot obrir `%s' per a escriptura (%s)"
-#: awkgram.y:4082 profile.c:85
-msgid "sending profile to standard error"
-msgstr "enviant el perfil a l'eixida d'error estàndard"
+#: awkgram.y:4127
+msgid "sending variable list to standard error"
+msgstr "s'està enviant la llista de variables a l'eixida d'error estàndard"
-#: awkgram.y:4088
+#: awkgram.y:4135
#, c-format
msgid "%s: close failed (%s)"
msgstr "%s: tancament erroni (%s)"
-#: awkgram.y:4140
+#: awkgram.y:4160
msgid "shadow_funcs() called twice!"
-msgstr "shadow_funcs() crida dos vegades!"
+msgstr "shadow_funcs() s'ha cridat dues vegades!"
-#: awkgram.y:4146
+#: awkgram.y:4168
msgid "there were shadowed variables."
-msgstr ""
+msgstr "hi ha hagut variables a l'ombra"
+
+#: awkgram.y:4239
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "nom de la funció `%s' definida prèviament"
-#: awkgram.y:4176
+#: awkgram.y:4285
#, 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"
+msgstr "funció `%s»: no pot usar el nom de la funció com a paràmetre"
-#: awkgram.y:4180
-#, fuzzy, c-format
+#: awkgram.y:4288
+#, c-format
msgid "function `%s': can't use special variable `%s' as a function parameter"
-msgstr "funció «%s»: no pot usar el nom de la funció com a paràmetre"
+msgstr ""
+"funció `%s': no es pot usar la variable especial `%s' com a un paràmetre de "
+"funció"
-#: awkgram.y:4196
+#: awkgram.y:4296
#, c-format
-msgid "function name `%s' previously defined"
-msgstr "nom de la funció «%s» definida prèviament"
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "funció `%s': paràmetre #%d, `%s', duplica al paràmetre #%d"
-#: awkgram.y:4364 awkgram.y:4370
+#: awkgram.y:4383 awkgram.y:4389
#, c-format
msgid "function `%s' called but never defined"
-msgstr "es crida a la funció «%s» però no s'ha definit"
+msgstr "es crida a la funció `%s' però no s'ha definit"
-#: awkgram.y:4373
-#, fuzzy, c-format
+#: awkgram.y:4393
+#, c-format
msgid "function `%s' defined but never called directly"
-msgstr "es defineix la funció «%s» però no s'ha cridat mai"
+msgstr "la funció `%s' està definida però no s'ha cridat mai directament"
-#: awkgram.y:4405
+#: awkgram.y:4425
#, 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:4514
-#, fuzzy, c-format
+#: awkgram.y:4484
+#, 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"
+"s'ha cridat a la funció `%s' amb espai entre el nom i el '(',\n"
+"o s'ha usat com a variable o matriu"
-#: awkgram.y:4761 eval.c:2206
+#: awkgram.y:4720
msgid "division by zero attempted"
msgstr "s'ha intentat una divisió per zero"
-#: awkgram.y:4770 eval.c:2222
+#: awkgram.y:4729
#, c-format
msgid "division by zero attempted in `%%'"
-msgstr "s'ha intentat una divisió per zero en «%%»"
+msgstr "s'ha intentat una divisió per zero en `%%'"
+
+#: awkgram.y:5049
+msgid ""
+"cannot assign a value to the result of a field post-increment expression"
+msgstr ""
+"no es pot assignar un valor al resultat d'una expressió post-increment de "
+"camp"
+
+#: awkgram.y:5052
+#, c-format
+msgid "invalid target of assignment (opcode %s)"
+msgstr "destí no vàlid d'assignació (opcode %s)"
-#: builtin.c:117
+#: builtin.c:133
#, c-format
msgid "%s to \"%s\" failed (%s)"
msgstr "%s a \"%s\" ha fallat (%s)"
-#: builtin.c:118
+#: builtin.c:134
msgid "standard output"
-msgstr "eixida estàndard"
+msgstr "sortida estàndard"
-#: builtin.c:132
+#: builtin.c:148
msgid "exp: received non-numeric argument"
msgstr "exp: s'ha rebut un argument que no és un número"
-#: builtin.c:138
+#: builtin.c:154
#, c-format
msgid "exp: argument %g is out of range"
msgstr "exp: l'argument %g està fora de rang"
-#: builtin.c:197
+#: builtin.c:229
#, 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 "
+"fflush: no es pot netejar: la canonada `%s' s'ha obert per a lectura, no per "
"a escriptura"
-#: builtin.c:200
+#: builtin.c:232
#, 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 "
+"fflush: no es pot netejar: el fitxer `%s' s'ha obert per a lectura, no per a "
"escriptura"
-#: builtin.c:212
+#: builtin.c:244
#, 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"
+msgstr "fflush: `%s' no és un fitxer obert, canonada o co-procés"
-#: builtin.c:330
+#: builtin.c:362
msgid "index: received non-string first argument"
msgstr "índex: el primer argument rebut no és una cadena"
-#: builtin.c:332
+#: builtin.c:364
msgid "index: received non-string second argument"
msgstr "índex: el segon argument rebut no és una cadena"
-#: builtin.c:454
+#: builtin.c:488 mpfr.c:757
msgid "int: received non-numeric argument"
msgstr "int: s'ha rebut un argument no numèric"
-#: builtin.c:490
-#, fuzzy
+#: builtin.c:525
msgid "length: received array argument"
-msgstr "length: s'ha rebut un argument que no és una cadena"
+msgstr "length: s'ha rebut un argument de matriu"
-#: builtin.c:493
-#, fuzzy
+#: builtin.c:528
msgid "`length(array)' is a gawk extension"
-msgstr "«delete array» és una extensió de gawk"
+msgstr "`length(array)' és una extensió de gawk"
-#: builtin.c:501
+#: builtin.c:544
msgid "length: received non-string argument"
msgstr "length: s'ha rebut un argument que no és una cadena"
-#: builtin.c:532
+#: builtin.c:575
msgid "log: received non-numeric argument"
msgstr "log: s'ha rebut un argument no numèric"
-#: builtin.c:535
+#: builtin.c:578
#, c-format
msgid "log: received negative argument %g"
msgstr "log: s'ha rebut l'argument negatiu %g"
-#: builtin.c:593 builtin.c:604
+#: builtin.c:776 builtin.c:781
+msgid "fatal: must use `count$' on all formats or none"
+msgstr "fatal: s'ha d'usar `count$' a tots els format o a cap"
+
+#: builtin.c:851
+#, c-format
+msgid "field width is ignored for `%%' specifier"
+msgstr "l'amplada de camp s'ignorarà per a l'especificador `%%'"
+
+#: builtin.c:853
+#, c-format
+msgid "precision is ignored for `%%' specifier"
+msgstr "la precisió s'ignorarà per a l'especificador `%%'"
+
+#: builtin.c:855
+#, c-format
+msgid "field width and precision are ignored for `%%' specifier"
+msgstr "l'amplada de camp i la precisió s'ignoraran per a l'especificador `%%'"
+
+#: builtin.c:906
+msgid "fatal: `$' is not permitted in awk formats"
+msgstr "fatal: no es permeten `$' en els formats awk"
+
+#: builtin.c:915
+msgid "fatal: arg count with `$' must be > 0"
+msgstr "fatal: el recompte d'arguments amb `$' ha de ser > 0"
+
+#: builtin.c:919
+#, c-format
+msgid "fatal: arg count %ld greater than total number of supplied arguments"
+msgstr ""
+"fatal: el recompte d'arguments %ld és major que el nombre total d'arguments "
+"proporcionats"
+
+#: builtin.c:923
+msgid "fatal: `$' not permitted after period in format"
+msgstr "fatal: no es permet `$' després d'un punt en el format"
+
+#: builtin.c:939
+msgid "fatal: no `$' supplied for positional field width or precision"
+msgstr ""
+"fatal: no es proporciona `$' per a l'ample o precisió del camp de posició"
+
+#: builtin.c:1009
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "`l' manca de significat en els formats awk; serà ignorat"
+
+#: builtin.c:1013
+msgid "fatal: `l' is not permitted in POSIX awk formats"
+msgstr "fatal: `l' no està permès en els formats POSIX de awk"
+
+#: builtin.c:1026
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "`L' manca de significat en els formats awk; serà ignorat"
+
+#: builtin.c:1030
+msgid "fatal: `L' is not permitted in POSIX awk formats"
+msgstr "fatal: `L' no està permès en els formats POSIX de awk"
+
+#: builtin.c:1043
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "`h' manca de significat en els formats awk; serà ignorat"
+
+#: builtin.c:1047
+msgid "fatal: `h' is not permitted in POSIX awk formats"
+msgstr "fatal: `h' no està permès en els formats POSIX de awk"
+
+#: builtin.c:1463
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr "[s]printf: el valor %g està fora de rang per al format `%%%c'"
+
+#: builtin.c:1561
+#, c-format
+msgid "ignoring unknown format specifier character `%c': no argument converted"
+msgstr ""
+"s'ignorarà el caràcter especificador de format `%c': no s'ha convertit cap "
+"argument"
+
+#: builtin.c:1566
+msgid "fatal: not enough arguments to satisfy format string"
+msgstr "fatal: no hi ha prou arguments per a satisfer el format d'una cadena"
+
+#: builtin.c:1568
+msgid "^ ran out for this one"
+msgstr "^ desbordament per a aquest"
+
+#: builtin.c:1575
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "[s]printf: l'especificador de format no conté lletra de control"
+
+#: builtin.c:1578
+msgid "too many arguments supplied for format string"
+msgstr "s'han proporcionat masses arguments per a la cadena de format"
+
+#: builtin.c:1634
+msgid "sprintf: no arguments"
+msgstr "sprintf: sense arguments"
+
+#: builtin.c:1657 builtin.c:1668
msgid "printf: no arguments"
msgstr "printf: sense arguments"
-#: builtin.c:645
+#: builtin.c:1711
msgid "sqrt: received non-numeric argument"
msgstr "sqrt: s'ha rebut un argument no numèric"
-#: builtin.c:649
+#: builtin.c:1715
#, c-format
msgid "sqrt: called with negative argument %g"
msgstr "sqrt: cridat amb l'argument negatiu %g"
-#: builtin.c:673
-#, fuzzy, c-format
+#: builtin.c:1746
+#, c-format
msgid "substr: length %g is not >= 1"
-msgstr "substr: la longitud %g és <= 0"
+msgstr "substr: la longitud %g no és >= 1"
-#: builtin.c:675
-#, fuzzy, c-format
+#: builtin.c:1748
+#, c-format
msgid "substr: length %g is not >= 0"
-msgstr "substr: la longitud %g és <= 0"
+msgstr "substr: la longitud %g no és >= 0"
-#: builtin.c:682
+#: builtin.c:1755
#, 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:687
+#: builtin.c:1760
#, c-format
msgid "substr: length %g too big for string indexing, truncating to %g"
msgstr ""
+"substr: la llargada %g és massa gran per a la indexació de cadenes de "
+"caràcters, es truncarà a %g"
-#: builtin.c:699
+#: builtin.c:1772
#, 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:704
+#: builtin.c:1777
#, 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:729
+#: builtin.c:1802
msgid "substr: source string is zero length"
msgstr "substr: la cadena font és de longitud zero"
-#: builtin.c:745
-#, fuzzy, c-format
+#: builtin.c:1818
+#, 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"
+msgstr "substr: l'índex d'inici %g sobrepassa l'acabament de la cadena"
-#: builtin.c:753
-#, fuzzy, c-format
+#: builtin.c:1826
+#, 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)"
+"substr: la longitud %g a l'índex d'inici %g excedeix la longitud del primer "
+"argument (%lu)"
-#: builtin.c:826
+#: builtin.c:1900
msgid "strftime: format value in PROCINFO[\"strftime\"] has numeric type"
-msgstr ""
+msgstr "strftime: el valor de format a PROCINFO[\"strftime\"] té tipus numèric"
-#: builtin.c:840
-#, fuzzy
+#: builtin.c:1923
msgid "strftime: received non-numeric second argument"
-msgstr "strftime: el segon argument rebut no és numèric"
+msgstr "strftime: s'ha rebut un segon argument no numèric"
+
+#: builtin.c:1927
+msgid "strftime: second argument less than 0 or too big for time_t"
+msgstr ""
+"strftime: el segon argument és més petit que 0 o massa gran per a time_t"
-#: builtin.c:847
-#, fuzzy
+#: builtin.c:1934
msgid "strftime: received non-string first argument"
msgstr "strftime: el primer argument rebut no és una cadena"
-#: builtin.c:853
+#: builtin.c:1941
msgid "strftime: received empty format string"
msgstr "strftime: s'ha rebut una cadena de format buida"
-#: builtin.c:919
+#: builtin.c:2007
msgid "mktime: received non-string argument"
msgstr "mktime: s'ha rebut un argument que no és una cadena"
-#: builtin.c:936
+#: builtin.c:2024
msgid "mktime: at least one of the values is out of the default range"
-msgstr ""
+msgstr "mktime: almenys un dels valors està forra del rang predeterminat"
-#: builtin.c:971
+#: builtin.c:2059
msgid "'system' function not allowed in sandbox mode"
-msgstr ""
+msgstr "la funció 'system' no es permet fora del mode entorn de proves"
-#: builtin.c:976
-#, fuzzy
+#: builtin.c:2064
msgid "system: received non-string argument"
msgstr "system: s'ha rebut un argument que no és una cadena"
-#: builtin.c:1031 eval.c:1411 eval.c:1936 eval.c:1949
+#: builtin.c:2184
#, c-format
-msgid "reference to uninitialized variable `%s'"
-msgstr "referència a una variable sense inicialitzar «%s»"
-
-#: builtin.c:1098
-#, fuzzy, c-format
msgid "reference to uninitialized field `$%d'"
-msgstr "referència a una variable sense inicialitzar «%s»"
+msgstr "referència a una variable sense inicialitzar `$%d'"
-#: builtin.c:1185
-#, fuzzy
+#: builtin.c:2271
msgid "tolower: received non-string argument"
msgstr "tolower: s'ha rebut un argument que no és una cadena"
-#: builtin.c:1219
-#, fuzzy
+#: builtin.c:2305
msgid "toupper: received non-string argument"
msgstr "toupper: s'ha rebut un argument que no és una cadena"
-#: builtin.c:1255
+#: builtin.c:2341 mpfr.c:672
msgid "atan2: received non-numeric first argument"
msgstr "atan2: el primer argument rebut no és numèric"
-#: builtin.c:1257
+#: builtin.c:2343 mpfr.c:674
msgid "atan2: received non-numeric second argument"
msgstr "atan2: el segon argument rebut no és numèric"
-#: builtin.c:1276
+#: builtin.c:2362
msgid "sin: received non-numeric argument"
msgstr "sin: s'ha rebut un argument que no és numèric"
-#: builtin.c:1292
+#: builtin.c:2378
msgid "cos: received non-numeric argument"
msgstr "cos: s'ha rebut un argument que no és numèric"
-#: builtin.c:1345
+#: builtin.c:2431 mpfr.c:1156
msgid "srand: received non-numeric argument"
msgstr "srand: s'ha rebut un argument que no és numèric"
-#: builtin.c:1376
+#: builtin.c:2462
msgid "match: third argument is not an array"
msgstr "match: el tercer argument no és una matriu"
-#: builtin.c:1883
-#, fuzzy
+#: builtin.c:2734
msgid "gensub: third argument of 0 treated as 1"
msgstr "gensub: el tercer argument de 0 és tractat com a 1"
-#: builtin.c:1923
+#: builtin.c:3030
msgid "lshift: received non-numeric first argument"
msgstr "lshift: el primer argument rebut no és numèric"
-#: builtin.c:1925
-#, fuzzy
+#: builtin.c:3032
msgid "lshift: received non-numeric second argument"
-msgstr "atan2: el segon argument rebut no és numèric"
+msgstr "lshift: el segon argument rebut no és numèric"
-#: builtin.c:1931
+#: builtin.c:3038
#, c-format
-msgid "lshift(%lf, %lf): negative values will give strange results"
-msgstr "lshift(%lf, %lf): els valors negatius donaran resultats estranys"
+msgid "lshift(%f, %f): negative values will give strange results"
+msgstr "lshift(%f, %f): els valors negatius donaran resultats estranys"
-#: builtin.c:1933
+#: builtin.c:3040
#, c-format
-msgid "lshift(%lf, %lf): fractional values will be truncated"
-msgstr "lshift(%lf, %lf): els valors fraccionaris sernn truncats"
+msgid "lshift(%f, %f): fractional values will be truncated"
+msgstr "lshift(%f, %f): els valors fraccionaris sernn truncats"
-#: builtin.c:1935
+#: builtin.c:3042
#, c-format
-msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgid "lshift(%f, %f): too large shift value will give strange results"
msgstr ""
-"lshift(%lf, %lf): un valor de desplaçament massa gran donarà resultats "
-"estranys"
+"lshift(%f, %f): un valor de desplaçament massa gran donarà resultats estranys"
-#: builtin.c:1960
+#: builtin.c:3067
msgid "rshift: received non-numeric first argument"
msgstr "rshift: el primer argument rebut no és numèric"
-#: builtin.c:1962
-#, fuzzy
+#: builtin.c:3069
msgid "rshift: received non-numeric second argument"
-msgstr "atan2: el segon argument rebut no és numèric"
+msgstr "rshift: el segon argument rebut no és numèric"
-#: builtin.c:1968
+#: builtin.c:3075
#, c-format
-msgid "rshift(%lf, %lf): negative values will give strange results"
-msgstr "rshift(%lf, %lf): els valors negatius donaran resultats estranys"
+msgid "rshift(%f, %f): negative values will give strange results"
+msgstr "rshift(%f, %f): els valors negatius donaran resultats estranys"
-#: builtin.c:1970
+#: builtin.c:3077
#, c-format
-msgid "rshift(%lf, %lf): fractional values will be truncated"
-msgstr "rshift(%lf, %lf): els valors fraccionaris seran truncats"
+msgid "rshift(%f, %f): fractional values will be truncated"
+msgstr "rshift(%f, %f): els valors fraccionaris seran truncats"
-#: builtin.c:1972
+#: builtin.c:3079
#, c-format
-msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgid "rshift(%f, %f): too large shift value will give strange results"
msgstr ""
-"rshift(%lf, %lf): un valor de desplaçament massa gran donarà resultats "
-"estranys"
+"rshift(%f, %f): un valor de desplaçament massa gran donarà resultats estranys"
-#: builtin.c:1997
-msgid "and: received non-numeric first argument"
-msgstr "and: el primer argument rebut no és numèric"
-
-#: builtin.c:1999
-#, fuzzy
-msgid "and: received non-numeric second argument"
-msgstr "atan2: el segon argument rebut no és numèric"
+#: builtin.c:3104 mpfr.c:968
+msgid "and: called with less than two arguments"
+msgstr "and: cridat amb menys de dos arguments"
-#: builtin.c:2005
+#: builtin.c:3109
#, c-format
-msgid "and(%lf, %lf): negative values will give strange results"
-msgstr "and(%lf, %lf): els valors negatius donaran resultats estranys"
+msgid "and: argument %d is non-numeric"
+msgstr "exp: l'argument %d no és numèric"
-#: builtin.c:2007
+#: builtin.c:3113
#, c-format
-msgid "and(%lf, %lf): fractional values will be truncated"
-msgstr "and(%lf, %lf): els valors fraccionaris seran truncats"
-
-#: builtin.c:2032
-msgid "or: received non-numeric first argument"
-msgstr "or: el primer argument rebut no és numèric"
+msgid "and: argument %d negative value %g will give strange results"
+msgstr "and: l'argument %d amb valor negatiu %g donarà resultats estranys"
-#: builtin.c:2034
-#, fuzzy
-msgid "or: received non-numeric second argument"
-msgstr "atan2: el segon argument rebut no és numèric"
+#: builtin.c:3136 mpfr.c:1000
+msgid "or: called with less than two arguments"
+msgstr "or: cridat amb menys de dos arguments"
-#: builtin.c:2040
+#: builtin.c:3141
#, c-format
-msgid "or(%lf, %lf): negative values will give strange results"
-msgstr "or(%lf, %lf): els valors negatius donaran resultats estranys"
+msgid "or: argument %d is non-numeric"
+msgstr "or: l'argument %d no és numèric"
-#: builtin.c:2042
+#: builtin.c:3145
#, c-format
-msgid "or(%lf, %lf): fractional values will be truncated"
-msgstr "or(%lf, %lf): els valors fraccionaris seran truncats"
-
-#: builtin.c:2070
-msgid "xor: received non-numeric first argument"
-msgstr "xor: el primer argument rebut no és numèric"
+msgid "or: argument %d negative value %g will give strange results"
+msgstr "or: l'argument %d amb valor negatiu %g donarà resultats estranys"
-#: builtin.c:2072
-#, fuzzy
-msgid "xor: received non-numeric second argument"
-msgstr "atan2: el segon argument rebut no és numèric"
+#: builtin.c:3167 mpfr.c:1031
+msgid "xor: called with less than two arguments"
+msgstr "xort: cridat amb menys de dos arguments"
-#: builtin.c:2078
+#: builtin.c:3173
#, c-format
-msgid "xor(%lf, %lf): negative values will give strange results"
-msgstr "xor(%lf, %lf): els valors negatius donaran resultats estranys"
+msgid "xor: argument %d is non-numeric"
+msgstr "xor: l'argument %d no és numèric"
-#: builtin.c:2080
+#: builtin.c:3177
#, c-format
-msgid "xor(%lf, %lf): fractional values will be truncated"
-msgstr "xor(%lf, %lf): els valors fraccionaris seran truncats"
+msgid "xor: argument %d negative value %g will give strange results"
+msgstr "xor: l'argument %d del valor negatiu %g donarà resultats estranys"
-#: builtin.c:2104 builtin.c:2110
+#: builtin.c:3202 mpfr.c:787
msgid "compl: received non-numeric argument"
msgstr "compl: s'ha rebut un argument que no és numèric"
-#: builtin.c:2112
+#: builtin.c:3208
#, c-format
-msgid "compl(%lf): negative value will give strange results"
-msgstr "compl(%lf): el valor negatiu donarà resultats estranys"
+msgid "compl(%f): negative value will give strange results"
+msgstr "compl(%f): el valor negatiu donarà resultats estranys"
-#: builtin.c:2114
+#: builtin.c:3210
#, c-format
-msgid "compl(%lf): fractional value will be truncated"
-msgstr "compl(%lf): el valor fraccionari serà truncat"
+msgid "compl(%f): fractional value will be truncated"
+msgstr "compl(%f): el valor fraccionari serà truncat"
-#: builtin.c:2283
+#: builtin.c:3379
#, c-format
msgid "dcgettext: `%s' is not a valid locale category"
-msgstr "dcgettext: «%s» no és una categoria local vàlida"
+msgstr "dcgettext: `%s' no és una categoria local vàlida"
+
+#: command.y:225
+#, c-format
+msgid "Type (g)awk statement(s). End with the command \"end\"\n"
+msgstr "Escriviu proposició(ns) g(awk). Termineu amb la instrucció \"end\"\n"
+
+#: command.y:289
+#, c-format
+msgid "invalid frame number: %d"
+msgstr "número invàlid de marc: %d"
+
+#: command.y:295
+#, c-format
+msgid "info: invalid option - \"%s\""
+msgstr "info: opció no vàlida - \"%s\""
+
+#: command.y:321
+#, c-format
+msgid "source \"%s\": already sourced."
+msgstr "source \"%s\": ja s'ha utilitzat."
+
+#: command.y:326
+#, c-format
+msgid "save \"%s\": command not permitted."
+msgstr "save \"%s\": ordre no permesa."
+
+#: command.y:339
+msgid "Can't use command `commands' for breakpoint/watchpoint commands"
+msgstr ""
+"No es pot usar l'ordre `commands' per a ordres de punt d'interrupció/"
+"inspecció"
+
+#: command.y:341
+msgid "no breakpoint/watchpoint has been set yet"
+msgstr "no s'ha establert encara cap punt d'interrupció/verificació"
+
+#: command.y:343
+msgid "invalid breakpoint/watchpoint number"
+msgstr "número de punt d'interrupció/inspecció no vàlid"
+
+#: command.y:348
+#, c-format
+msgid "Type commands for when %s %d is hit, one per line.\n"
+msgstr "Escriviu les ordres per a quan s'assoleix %s %d, una per línia.\n"
+
+#: command.y:350
+#, c-format
+msgid "End with the command \"end\"\n"
+msgstr "Termineu amb l'ordre \"end\"\n"
+
+#: command.y:357
+msgid "`end' valid only in command `commands' or `eval'"
+msgstr "`end' és vàlid sols a les ordres `commands' o `eval'"
+
+#: command.y:367
+msgid "`silent' valid only in command `commands'"
+msgstr "`silent' és vàlid sols a l'ordre `commands'"
+
+#: command.y:373
+#, c-format
+msgid "trace: invalid option - \"%s\""
+msgstr "traç: opció no vàlida - \"%s\""
+
+#: command.y:387
+msgid "condition: invalid breakpoint/watchpoint number"
+msgstr "condició: número de punt d'interrupció/inspecció no vàlid"
+
+#: command.y:449
+msgid "argument not a string"
+msgstr "l'argument no és una cadena de caràcters"
+
+#: command.y:459 command.y:464
+#, c-format
+msgid "option: invalid parameter - \"%s\""
+msgstr "opció: paràmetre no vàlid - \"%s\""
+
+#: command.y:474
+#, c-format
+msgid "no such function - \"%s\""
+msgstr "no existeix aquesta funció - \"%s\""
+
+#: command.y:531
+#, c-format
+msgid "enable: invalid option - \"%s\""
+msgstr "enable: opció no vàlida - \"%s\""
+
+#: command.y:597
+#, c-format
+msgid "invalid range specification: %d - %d"
+msgstr "especificació no vàlida de rang: %d - %d"
+
+#: command.y:659
+msgid "non-numeric value for field number"
+msgstr "valor no numèric per al número de camp"
+
+#: command.y:680 command.y:687
+msgid "non-numeric value found, numeric expected"
+msgstr "s'ha trobat un valor no numèric, s'esperava un valor numèric"
+
+#: command.y:712 command.y:718
+msgid "non-zero integer value"
+msgstr "valor enter no zero"
+
+#: command.y:817
+msgid ""
+"backtrace [N] - print trace of all or N innermost (outermost if N < 0) "
+"frames."
+msgstr ""
+"backtrace [N] - imprimeix la traça de tot els N marcs interiors (exteriors "
+"si N < 0)."
+
+#: command.y:819
+msgid ""
+"break [[filename:]N|function] - set breakpoint at the specified location."
+msgstr ""
+"break [[fitxer:]N|funció] - estableix el punt d'interrupció a la ubicació "
+"especificada."
+
+#: command.y:821
+msgid "clear [[filename:]N|function] - delete breakpoints previously set."
+msgstr ""
+"clear [[fitxer:]N|funció] - suprimeix els punts establerts prèviament."
+
+#: command.y:823
+msgid ""
+"commands [num] - starts a list of commands to be executed at a "
+"breakpoint(watchpoint) hit."
+msgstr ""
+"commands [num] - inicia una llista d'ordres a executar quan s'arribi a un "
+"punt d'interrupció/inspecció."
+
+#: command.y:825
+msgid "condition num [expr] - set or clear breakpoint or watchpoint condition."
+msgstr ""
+"condition num [expr] - estableix o neteja una condició de punt d'interrupció "
+"o d'inspecció."
+
+#: command.y:827
+msgid "continue [COUNT] - continue program being debugged."
+msgstr "continue [RECOMPTE] - continua el programa que s'està depurant."
+
+#: command.y:829
+msgid "delete [breakpoints] [range] - delete specified breakpoints."
+msgstr ""
+"delete [punts d'interrupció] [rang] - esborra els punts d'interrupció "
+"especificats."
+
+#: command.y:831
+msgid "disable [breakpoints] [range] - disable specified breakpoints."
+msgstr ""
+"disable [punts d'interrupció] [rang] - deshabilita els punts d'interrupció "
+"especificats."
+
+#: command.y:833
+msgid "display [var] - print value of variable each time the program stops."
+msgstr ""
+"display [var] - imprimeix el valor de la variable cada cop que el programa "
+"s'atura"
+
+#: command.y:835
+msgid "down [N] - move N frames down the stack."
+msgstr "down [N] - mou N marcs cap a baix a la pila."
+
+#: command.y:837
+msgid "dump [filename] - dump instructions to file or stdout."
+msgstr ""
+"dump [filename] - aboca les instruccions a un fitxer o a la sortida "
+"estàndard."
+
+#: command.y:839
+msgid "enable [once|del] [breakpoints] [range] - enable specified breakpoints."
+msgstr ""
+"enable [once|del] [punts d'interrupció] [rang] - habilita els punts "
+"d'interrupció especificats."
+
+#: command.y:841
+msgid "end - end a list of commands or awk statements."
+msgstr "end - finalitza una llista de ordres o declaracions awk."
+
+#: command.y:843
+msgid "eval stmt|[p1, p2, ...] - evaluate awk statement(s)."
+msgstr "eval stmt|[p1, p2, ...] - avalua la(es) declaració(ns) awk."
+
+#: command.y:845
+msgid "finish - execute until selected stack frame returns."
+msgstr ""
+"finish - executa fins que hi hagi un retorn del marc de pila seleccionat."
+
+#: command.y:847
+msgid "frame [N] - select and print stack frame number N."
+msgstr "frame [N] - selecciona i imprimeix el marc de pila amb número N."
+
+#: command.y:849
+msgid "help [command] - print list of commands or explanation of command."
+msgstr "help [ordre] - imprimeix una llista d'ordres o una explica de l'ordre."
+
+#: command.y:851
+msgid "ignore N COUNT - set ignore-count of breakpoint number N to COUNT."
+msgstr ""
+"ignore N RECOMPTE - estableix ignore-count del punt d'interrupció número N "
+"fins RECOMPTE."
+
+#: command.y:853
+msgid ""
+"info topic - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch."
+msgstr ""
+"info topic - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch."
+
+#: command.y:855
+msgid "list [-|+|[filename:]lineno|function|range] - list specified line(s)."
+msgstr ""
+"list [-|+|[fitxer:]número-de-línia|funció|rang] - fes una llista la(es) "
+"línia(es) especificada(es)."
+
+#: command.y:857
+msgid "next [COUNT] - step program, proceeding through subroutine calls."
+msgstr ""
+"next [RECOMPTE] - avança el programa pas per pas, tot procedint a través de "
+"les crides de subrutines."
+
+#: command.y:859
+msgid ""
+"nexti [COUNT] - step one instruction, but proceed through subroutine calls."
+msgstr ""
+"nexti [RECOMPTE] - avança una instrucció, però procedeix a través de crides "
+"de subrutines."
+
+#: command.y:861
+msgid "option [name[=value]] - set or display debugger option(s)."
+msgstr ""
+"option [nom[=valor]] - estableix o mostra la(es) opció(ns) del depurador."
+
+#: command.y:863
+msgid "print var [var] - print value of a variable or array."
+msgstr "print var [var] - imprimeix el valor de la variable o matriu."
+
+#: command.y:865
+msgid "printf format, [arg], ... - formatted output."
+msgstr "printf format, [arg], ... - sortida amb format."
+
+#: command.y:867
+msgid "quit - exit debugger."
+msgstr "quit - surt del depurador."
+
+#: command.y:869
+msgid "return [value] - make selected stack frame return to its caller."
+msgstr ""
+"return [valor] - fes que el marc seleccionat de pila retorni a l'element que "
+"l'ha cridat."
+
+#: command.y:871
+msgid "run - start or restart executing program."
+msgstr "run - inicia o reinicia el programa que s'està executant."
+
+#: command.y:874
+msgid "save filename - save commands from the session to file."
+msgstr "save filename - desa les ordres de la sessió a un fitxer."
+
+#: command.y:877
+msgid "set var = value - assign value to a scalar variable."
+msgstr "set var = valor - assigna un valor a una variable escalar."
+
+#: command.y:879
+msgid ""
+"silent - suspends usual message when stopped at a breakpoint/watchpoint."
+msgstr ""
+"silent - suspèn els missatges habituals quan s'autra a un punt d'interrupció/"
+"inspecció."
+
+#: command.y:881
+msgid "source file - execute commands from file."
+msgstr "source file - executa una ordre des d'un fitxer."
+
+#: command.y:883
+msgid "step [COUNT] - step program until it reaches a different source line."
+msgstr ""
+"step [RECOMPTE] - avança pas per pas pel programa fins que arribi a una "
+"línia diferent de la font."
+
+#: command.y:885
+msgid "stepi [COUNT] - step one instruction exactly."
+msgstr "stepi [RECOMPTE] - avança exactament una instrucció."
+
+#: command.y:887
+msgid "tbreak [[filename:]N|function] - set a temporary breakpoint."
+msgstr ""
+"tbreak [[fitxer:]N|funció] - estableix un punt temporari d'interrupció."
+
+#: command.y:889
+msgid "trace on|off - print instruction before executing."
+msgstr "trace on|off - imprimeix la instrucció abans d'executar-la."
+
+#: command.y:891
+msgid "undisplay [N] - remove variable(s) from automatic display list."
+msgstr ""
+"undisplay [N] - remou la(es) variable(s) de la llista automàtica "
+"visualització."
+
+#: command.y:893
+msgid ""
+"until [[filename:]N|function] - execute until program reaches a different "
+"line or line N within current frame."
+msgstr ""
+"until [[fitxer:]N|funció] - executa fins que el programa arribi a una línia "
+"diferent a la línia N dins del marc actual."
+
+#: command.y:895
+msgid "unwatch [N] - remove variable(s) from watch list."
+msgstr "unwatch [N] - remou la(es) variable(s) de la llista d'inspecció."
+
+#: command.y:897
+msgid "up [N] - move N frames up the stack."
+msgstr "up [N] - mou-te N marcs cap a dalt de la pila."
+
+#: command.y:899
+msgid "watch var - set a watchpoint for a variable."
+msgstr "watch var - estableix un punt d'inspecció per a una variable."
+
+#: command.y:1011 debug.c:401 msg.c:135
+#, c-format
+msgid "error: "
+msgstr "error: "
+
+#: command.y:1051
+#, c-format
+msgid "can't read command (%s)\n"
+msgstr "no es pot llegir l'ordre (%s)\n"
+
+#: command.y:1065
+#, c-format
+msgid "can't read command (%s)"
+msgstr "no es pot llegir l'ordre (%s)"
+
+#: command.y:1116
+msgid "invalid character in command"
+msgstr "caràcter no vàlida en la instucció"
+
+#: command.y:1152
+#, c-format
+msgid "unknown command - \"%.*s\", try help"
+msgstr "ordre desconeguda - \"%.*s\", prova l'ajuda"
+
+#: command.y:1222
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: command.y:1284
+msgid "invalid character"
+msgstr "caràcter no vàlid"
+
+#: command.y:1455
+#, c-format
+msgid "undefined command: %s\n"
+msgstr "ordre no definida: %s\n"
+
+#: debug.c:252
+msgid "set or show the number of lines to keep in history file."
+msgstr ""
+"estableix o mostra el número de línies a mantenir al fitxer d'història."
+
+#: debug.c:254
+msgid "set or show the list command window size."
+msgstr "estableix o mostra la mida de la finestra de llista d'ordres."
+
+#: debug.c:256
+msgid "set or show gawk output file."
+msgstr "estableix o mostra el fitxer de sortida gawk."
+
+#: debug.c:258
+msgid "set or show debugger prompt."
+msgstr "estableix o mostra l'indicador del depurador."
+
+#: debug.c:260
+msgid "(un)set or show saving of command history (value=on|off)."
+msgstr ""
+"estableix(anul·la) o mostra el desament de la història d'ordres (valor=on|"
+"off)."
+
+#: debug.c:262
+msgid "(un)set or show saving of options (value=on|off)."
+msgstr "estableix(anul·la) o mostra el desament d'opcions (valor=on|off)."
+
+#: debug.c:264
+msgid "(un)set or show instruction tracing (value=on|off)."
+msgstr ""
+"estableix(anul·la) o mostra el seguiment d'instruccions (valor=on|off)."
+
+#: debug.c:345
+msgid "program not running."
+msgstr "el programa no s'està executant."
+
+#: debug.c:448 debug.c:606
+#, c-format
+msgid "can't read source file `%s' (%s)"
+msgstr "no es pot llegir el fitxer font `%s' (%s)"
+
+#: debug.c:453
+#, c-format
+msgid "source file `%s' is empty.\n"
+msgstr "el fitxer font `%s' està buit\n"
+
+#: debug.c:480
+msgid "no current source file."
+msgstr "no hi ha un fitxer font."
+
+#: debug.c:505
+#, c-format
+msgid "cannot find source file named `%s' (%s)"
+msgstr "no es pot trobar el fitxer font `%s' (%s)"
+
+#: debug.c:529
+#, c-format
+msgid "WARNING: source file `%s' modified since program compilation.\n"
+msgstr ""
+"ADVERTIMENT: el fitxer font `%s' s'ha modificat des de la compilació del "
+"programa.\n"
+
+#: debug.c:551
+#, c-format
+msgid "line number %d out of range; `%s' has %d lines"
+msgstr "línia número %d fora de rang; `%s' té %d línies"
+
+#: debug.c:611
+#, c-format
+msgid "unexpected eof while reading file `%s', line %d"
+msgstr ""
+"final de fitxer no esperat quan s'estava llegint el fitxer `%s', línia %d"
+
+#: debug.c:620
+#, c-format
+msgid "source file `%s' modified since start of program execution"
+msgstr ""
+"el fitxer font `%s' s'ha modificat des de l'inici de l'execució del programa"
+
+#: debug.c:732
+#, c-format
+msgid "Current source file: %s\n"
+msgstr "Fitxer font actual: %s\n"
+
+#: debug.c:733
+#, c-format
+msgid "Number of lines: %d\n"
+msgstr "Nombre de línies: %d\n"
+
+#: debug.c:740
+#, c-format
+msgid "Source file (lines): %s (%d)\n"
+msgstr "Fitxer font (línies): %s (%d)\n"
+
+#: debug.c:754
+msgid ""
+"Number Disp Enabled Location\n"
+"\n"
+msgstr ""
+"Ubicació habilitada per número disp\n"
+"\n"
+
+#: debug.c:765
+#, c-format
+msgid "\tno of hits = %ld\n"
+msgstr "\tnúmero de accessos = %ld\n"
+
+#: debug.c:767
+#, c-format
+msgid "\tignore next %ld hit(s)\n"
+msgstr "\tignora el(s) pròxim(s) %ld accés(sos)\n"
+
+#: debug.c:769 debug.c:909
+#, c-format
+msgid "\tstop condition: %s\n"
+msgstr "\tcondició d'aturada: %s\n"
+
+#: debug.c:771 debug.c:911
+msgid "\tcommands:\n"
+msgstr "\tordres:\n"
+
+#: debug.c:793
+#, c-format
+msgid "Current frame: "
+msgstr "Marc actual: "
+
+#: debug.c:796
+#, c-format
+msgid "Called by frame: "
+msgstr "Cridat per marc: "
+
+#: debug.c:800
+#, c-format
+msgid "Caller of frame: "
+msgstr "Cridador de marc: "
+
+#: debug.c:818
+#, c-format
+msgid "None in main().\n"
+msgstr "Cap a main().\n"
+
+#: debug.c:848
+msgid "No arguments.\n"
+msgstr "Sense arguments.\n"
+
+#: debug.c:849
+msgid "No locals.\n"
+msgstr "No hi ha locals.\n"
+
+#: debug.c:857
+msgid ""
+"All defined variables:\n"
+"\n"
+msgstr ""
+"Totes les variables definides:\n"
+"\n"
+
+#: debug.c:867
+msgid ""
+"All defined functions:\n"
+"\n"
+msgstr ""
+"Totes les funcions definides:\n"
+"\n"
+
+#: debug.c:886
+msgid ""
+"Auto-display variables:\n"
+"\n"
+msgstr ""
+"Mostra automàticament les variables:\n"
+"\n"
+
+#: debug.c:889
+msgid ""
+"Watch variables:\n"
+"\n"
+msgstr ""
+"Inspecciona les variables:\n"
+"\n"
+
+#: debug.c:1029
+#, c-format
+msgid "no symbol `%s' in current context\n"
+msgstr "no hi ha el símbol `%s' al context actual\n"
+
+#: debug.c:1041 debug.c:1427
+#, c-format
+msgid "`%s' is not an array\n"
+msgstr "`%s' no és una matriu\n"
+
+#: debug.c:1055
+#, c-format
+msgid "$%ld = uninitialized field\n"
+msgstr "$%ld = camp sense inicialitzar\n"
+
+#: debug.c:1076
+#, c-format
+msgid "array `%s' is empty\n"
+msgstr "la matriu `%s' està buida\n"
+
+#: debug.c:1119 debug.c:1171
+#, c-format
+msgid "[\"%s\"] not in array `%s'\n"
+msgstr "[\"%s\"] no està a la matriu `%s'\n"
+
+#: debug.c:1175
+#, c-format
+msgid "`%s[\"%s\"]' is not an array\n"
+msgstr "`%s[\"%s\"]' no és una matriu\n"
+
+#: debug.c:1236 debug.c:4964
+#, c-format
+msgid "`%s' is not a scalar variable"
+msgstr "`%s' no és una variable escalar"
+
+#: debug.c:1258 debug.c:4994
+#, c-format
+msgid "attempt to use array `%s[\"%s\"]' in a scalar context"
+msgstr "s'ha intentat usar la matriu `%s[\"%s\"]' en un context escalar"
+
+#: debug.c:1280 debug.c:5005
+#, c-format
+msgid "attempt to use scalar `%s[\"%s\"]' as array"
+msgstr "s'ha intentat usar la dada escalar `%s[\"%s\"]' com a una matriu"
+
+#: debug.c:1423
+#, c-format
+msgid "`%s' is a function"
+msgstr "`%s' és una funció"
+
+#: debug.c:1465
+#, c-format
+msgid "watchpoint %d is unconditional\n"
+msgstr "el punt d'inspecció %d és incondicional\n"
+
+#: debug.c:1499
+#, c-format
+msgid "No display item numbered %ld"
+msgstr "No hi ha un element de visualització numerat %ld"
+
+#: debug.c:1502
+#, c-format
+msgid "No watch item numbered %ld"
+msgstr "No hi ha un element d'inspecció numerat %ld"
+
+#: debug.c:1528
+#, c-format
+msgid "%d: [\"%s\"] not in array `%s'\n"
+msgstr "%d: [\"%s\"] no està a la matriu `%s'\n"
+
+#: debug.c:1767
+msgid "attempt to use scalar value as array"
+msgstr "s'ha intentat usar una dada escalar com a una matriu"
+
+#: debug.c:1856
+#, c-format
+msgid "Watchpoint %d deleted because parameter is out of scope.\n"
+msgstr ""
+"El punt d'inspecció %d s'ha esborrat perquè el paràmetre està fora d'abast.\n"
+
+#: debug.c:1867
+#, c-format
+msgid "Display %d deleted because parameter is out of scope.\n"
+msgstr "La vista %d s'ha suprimit perquè el paràmetre està fora de l'abast.\n"
+
+#: debug.c:1900
+#, c-format
+msgid " in file `%s', line %d\n"
+msgstr "al fitxer `%s', línia %d\n"
+
+#: debug.c:1921
+#, c-format
+msgid " at `%s':%d"
+msgstr " a `%s':%d"
+
+#: debug.c:1937 debug.c:2000
+#, c-format
+msgid "#%ld\tin "
+msgstr "#%ld\ten "
+
+#: debug.c:1974
+#, c-format
+msgid "More stack frames follow ...\n"
+msgstr "Segueixen més marcs de pila ...\n"
+
+#: debug.c:2017
+msgid "invalid frame number"
+msgstr "número no vàlid de rang"
+
+#: debug.c:2200
+#, c-format
+msgid "Note: breakpoint %d (enabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+"Nota: el punt d'interrupció %d (habilitat, ignora els %ld accessos "
+"següents), també s'ha establert a %s:%d"
+
+#: debug.c:2207
+#, c-format
+msgid "Note: breakpoint %d (enabled), also set at %s:%d"
+msgstr ""
+"Nota: el punt d'interrupció %d (habilitat), també s'ha establert a %s:%d"
+
+#: debug.c:2214
+#, c-format
+msgid "Note: breakpoint %d (disabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+"Nota: el punt d'interrupció %d (deshabilitat, ignora els %ld accessos "
+"següents), també s'ha establert a %s:%d"
+
+#: debug.c:2221
+#, c-format
+msgid "Note: breakpoint %d (disabled), also set at %s:%d"
+msgstr ""
+"Nota: el punt d'interrupció %d (deshabilitat), també s'ha establert a %s:%d"
+
+#: debug.c:2238
+#, c-format
+msgid "Breakpoint %d set at file `%s', line %d\n"
+msgstr "Punt d'interrupció %d establert al fitxer `%s', línia %d\n"
+
+#: debug.c:2340
+#, c-format
+msgid "Can't set breakpoint in file `%s'\n"
+msgstr "No es pot establir el punt d'interrupció al fitxer `%s'\n"
+
+#: debug.c:2369 debug.c:2492 debug.c:3350
+#, c-format
+msgid "line number %d in file `%s' out of range"
+msgstr "el número de línia %d al fitxer `%s' està fora de rang"
+
+#: debug.c:2373
+#, c-format
+msgid "Can't find rule!!!\n"
+msgstr "No es pot trobar la regla!!!\n"
+
+#: debug.c:2375
+#, c-format
+msgid "Can't set breakpoint at `%s':%d\n"
+msgstr "No es pot establir el punt d'interrupció a `%s':%d\n"
+
+#: debug.c:2387
+#, c-format
+msgid "Can't set breakpoint in function `%s'\n"
+msgstr "No est pot establir el punt d'interrupció a la funció `%s'\n"
+
+#: debug.c:2403
+#, c-format
+msgid "breakpoint %d set at file `%s', line %d is unconditional\n"
+msgstr ""
+"el punt d'interrupció %d establert al fitxer `%s', línia %d és "
+"incondicional\n"
+
+#: debug.c:2508 debug.c:2530
+#, c-format
+msgid "Deleted breakpoint %d"
+msgstr "Punt interrupció suprimit %d"
+
+#: debug.c:2514
+#, c-format
+msgid "No breakpoint(s) at entry to function `%s'\n"
+msgstr "No hi ha punt(s) d'interrupció a l'entrada a la funció `%s'\n"
+
+#: debug.c:2541
+#, c-format
+msgid "No breakpoint at file `%s', line #%d\n"
+msgstr "No hi ha un punt d'interrupció al fitxer `%s', línia #%d\n"
+
+#: debug.c:2596 debug.c:2637 debug.c:2657 debug.c:2700
+msgid "invalid breakpoint number"
+msgstr "número no vàlid de punt d'interrupció"
+
+#: debug.c:2612
+msgid "Delete all breakpoints? (y or n) "
+msgstr "Suprimir tots els punts d'interrupció (s o n) "
+
+#: debug.c:2613 debug.c:2923 debug.c:2976
+msgid "y"
+msgstr "s"
+
+#: debug.c:2662
+#, c-format
+msgid "Will ignore next %ld crossing(s) of breakpoint %d.\n"
+msgstr ""
+"S'ignoraran el(s) %ld creuament(s) següent(s) del punt d'interrupció %d.\n"
+
+#: debug.c:2666
+#, c-format
+msgid "Will stop next time breakpoint %d is reached.\n"
+msgstr ""
+"S'aturarà la pròxima vegada que s'assoleixi el punt d'interrupció %d.\n"
+
+#: debug.c:2783
+#, c-format
+msgid "Can only debug programs provided with the `-f' option.\n"
+msgstr "Sols es poden depurar programes que tenen l'opció `-f'.\n"
+
+#: debug.c:2908
+#, c-format
+msgid "Failed to restart debugger"
+msgstr "No s'ha pogut reiniciar el depurador."
+
+#: debug.c:2922
+msgid "Program already running. Restart from beginning (y/n)? "
+msgstr "El programa ja està corrent. S'ha de reiniciar des del principi (s/n)?"
+
+#: debug.c:2926
+#, c-format
+msgid "Program not restarted\n"
+msgstr "No s'ha reiniciat el programa\n"
+
+#: debug.c:2936
+#, c-format
+msgid "error: cannot restart, operation not allowed\n"
+msgstr "error: no es pot reiniciar, l'operació no està permesa\n"
+
+#: debug.c:2942
+#, c-format
+msgid "error (%s): cannot restart, ignoring rest of the commands\n"
+msgstr "error (%s): no es pot reiniciar, s'ignoraran la resta de les ordres\n"
+
+#: debug.c:2950
+#, c-format
+msgid "Starting program: \n"
+msgstr "S'està iniciant el programa: \n"
+
+#: debug.c:2959
+#, c-format
+msgid "Program exited %s with exit value: %d\n"
+msgstr "El programa ha tingut la sortida %s amb el valor de sortida: %d\n"
+
+#: debug.c:2975
+msgid "The program is running. Exit anyway (y/n)? "
+msgstr "El programa s'està executant. Voleu sortir tot i això (s/n)? "
+
+#: debug.c:3010
+#, c-format
+msgid "Not stopped at any breakpoint; argument ignored.\n"
+msgstr "No s'ha detingut a cap punt d'interrupció; s'ignorarà l'argument.\n"
+
+#: debug.c:3015
+#, c-format
+msgid "invalid breakpoint number %d."
+msgstr "número no vàlid de punt d'interrupció %d."
+
+#: debug.c:3020
+#, c-format
+msgid "Will ignore next %ld crossings of breakpoint %d.\n"
+msgstr "S'ignoraran els pròxims %ld creuaments de punt d'interrupció %d.\n"
+
+#: debug.c:3207
+#, c-format
+msgid "'finish' not meaningful in the outermost frame main()\n"
+msgstr "'finish' no té significat al marc més extern main()\n"
+
+#: debug.c:3212
+#, c-format
+msgid "Run till return from "
+msgstr "Executa fins retornar de "
+
+#: debug.c:3255
+#, c-format
+msgid "'return' not meaningful in the outermost frame main()\n"
+msgstr "'return' no té significat al marc més extern main()\n"
+
+#: debug.c:3369
+#, c-format
+msgid "Can't find specified location in function `%s'\n"
+msgstr "No es pot trobar la ubicació especificada a la funció `%s'\n"
+
+#: debug.c:3377
+#, c-format
+msgid "invalid source line %d in file `%s'"
+msgstr "línia %d no vàlida de font al fitxer `%s'"
+
+#: debug.c:3392
+#, c-format
+msgid "Can't find specified location %d in file `%s'\n"
+msgstr "No es pot trobar la ubicació especificada %d al fitxer `%s'\n"
+
+#: debug.c:3424
+#, c-format
+msgid "element not in array\n"
+msgstr "l'element no està a la matriu\n"
+
+#: debug.c:3424
+#, c-format
+msgid "untyped variable\n"
+msgstr "variable sense tipus\n"
+
+#: debug.c:3466
+#, c-format
+msgid "Stopping in %s ...\n"
+msgstr "S'està aturant a %s ...\n"
+
+#: debug.c:3543
+#, c-format
+msgid "'finish' not meaningful with non-local jump '%s'\n"
+msgstr "'finish' no té significat amb salt no local '%s'\n"
+
+#: debug.c:3550
+#, c-format
+msgid "'until' not meaningful with non-local jump '%s'\n"
+msgstr "'until' no té significat amb salt no local '%s'\n"
+
+#: debug.c:4185
+msgid "\t------[Enter] to continue or q [Enter] to quit------"
+msgstr "\t------[Intro] per continuar o q [Intro] per sortir------"
+
+#: debug.c:4186
+msgid "q"
+msgstr "q"
+
+#: debug.c:5001
+#, c-format
+msgid "[\"%s\"] not in array `%s'"
+msgstr "[\"%s\"] no està a la matriu `%s'"
+
+#: debug.c:5207
+#, c-format
+msgid "sending output to stdout\n"
+msgstr "s'està enviant la sortida a la sortida estàndard\n"
+
+#: debug.c:5247
+msgid "invalid number"
+msgstr "número no vàlid"
+
+#: debug.c:5381
+#, c-format
+msgid "`%s' not allowed in current context; statement ignored"
+msgstr "`%s' no està permès al context actual; s'ignorarà la declaració"
+
+#: debug.c:5389
+msgid "`return' not allowed in current context; statement ignored"
+msgstr "`return' no està permès al context actual; s'ignorarà la declaració"
+
+#: debug.c:5590
+#, c-format
+msgid "No symbol `%s' in current context"
+msgstr "No hi ha un símbol `%s' al context actual"
+
+#: dfa.c:1118 dfa.c:1121 dfa.c:1142 dfa.c:1150 dfa.c:1162 dfa.c:1197
+#: dfa.c:1206 dfa.c:1209 dfa.c:1214 dfa.c:1228 dfa.c:1275
+msgid "unbalanced ["
+msgstr "[ sense aparellar"
+
+#: dfa.c:1174
+msgid "invalid character class"
+msgstr "classe no vàlida de caràcters"
+
+#: dfa.c:1316
+msgid "character class syntax is [[:space:]], not [:space:]"
+msgstr "la sintaxi de la classe de caràcters és [[:espai:]], no [:espai:]"
-#: eval.c:410
+#: dfa.c:1366
+msgid "unfinished \\ escape"
+msgstr "seqüència d'escapada \\ sense finalitzar"
+
+#: dfa.c:1513 regcomp.c:161
+msgid "Invalid content of \\{\\}"
+msgstr "Contingut no vàlid de \\{\\}"
+
+#: dfa.c:1516 regcomp.c:176
+msgid "Regular expression too big"
+msgstr "L'expressió regular és massa gran"
+
+#: dfa.c:1936
+msgid "unbalanced ("
+msgstr "( sense aparellar"
+
+#: dfa.c:2062
+msgid "no syntax specified"
+msgstr "no s'ha especificat una sintaxi"
+
+#: dfa.c:2070
+msgid "unbalanced )"
+msgstr ") sense aparellar"
+
+#: eval.c:394
#, c-format
msgid "unknown nodetype %d"
-msgstr "tipo de node %d desconegut"
+msgstr "tipus de node %d desconegut"
-#: eval.c:421 eval.c:435
-#, fuzzy, c-format
+#: eval.c:405 eval.c:419
+#, c-format
msgid "unknown opcode %d"
-msgstr "tipo de node %d desconegut"
+msgstr "opcode %d desconegut"
-#: eval.c:432
+#: eval.c:416
#, c-format
msgid "opcode %s not an operator or keyword"
-msgstr ""
+msgstr "l'opcode %s no és un operador o una paraula clau"
-#: eval.c:485
+#: eval.c:472
msgid "buffer overflow in genflags2str"
msgstr "desbordament del cau temporal en genflags2str"
-#: eval.c:696
+#: eval.c:675
#, c-format
msgid ""
"\n"
@@ -897,870 +1915,1292 @@ msgid ""
"\n"
msgstr ""
"\n"
-"\t# Pila de Crides a les Funcions:\n"
+"\t# Pila de crida a les funcions:\n"
"\n"
-#: eval.c:723
+#: eval.c:704
msgid "`IGNORECASE' is a gawk extension"
-msgstr "«IGNORECASE» és una extensió de gawk"
+msgstr "`IGNORECASE' és una extensió de gawk"
-#: eval.c:752
+#: eval.c:736
msgid "`BINMODE' is a gawk extension"
-msgstr "«BINMODE» és una extensió de gawk"
+msgstr "`BINMODE' és una extensió de gawk"
-#: eval.c:810
+#: eval.c:794
#, c-format
msgid "BINMODE value `%s' is invalid, treated as 3"
-msgstr ""
+msgstr "El valor BINMODE `%s' no és vàlid, es tractarà com 3"
-#: eval.c:900
+#: eval.c:885
#, c-format
msgid "bad `%sFMT' specification `%s'"
-msgstr "«%sFMT» especificació errònia «%s»"
+msgstr "`%sFMT' especificació errònia `%s'"
-#: eval.c:978
+#: eval.c:969
msgid "turning off `--lint' due to assignment to `LINT'"
-msgstr "desactivant «--lint» degut a una assignació a «LINT»"
-
-#: eval.c:1247
-#, fuzzy
-msgid "sorted array traversal is a gawk extension"
-msgstr "«delete array» és una extensió de gawk"
-
-#: eval.c:1291
-msgid "`PROCINFO[\"sorted_in\"]' value is not recognized"
-msgstr ""
+msgstr "desactivant `--lint' degut a una assignació a `LINT'"
-#: eval.c:1373 eval.c:1923
+#: eval.c:1147
#, 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:1401
-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"
+msgid "reference to uninitialized argument `%s'"
+msgstr "referència a un argument sense inicialitzar `%s'"
-#: eval.c:1410 eval.c:1935 eval.c:1948
+#: eval.c:1148
#, c-format
-msgid "reference to uninitialized argument `%s'"
-msgstr "referència a un argument sense inicialitzar «%s»"
+msgid "reference to uninitialized variable `%s'"
+msgstr "referència a una variable sense inicialitzar `%s'"
-#: eval.c:1429
+#: eval.c:1166
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:1431
-#, fuzzy
+#: eval.c:1168
msgid "attempt to field reference from null string"
-msgstr "s'ha intentat una referència a partir d'una cadena nul·la"
+msgstr "s'ha intentat entrar una referència a partir d'una cadena nul·la"
-#: eval.c:1437
-#, fuzzy, c-format
+#: eval.c:1176
+#, c-format
msgid "attempt to access field %ld"
-msgstr "s'ha intentat accedir al camp %d"
+msgstr "s'ha intentat accedir al camp %ld"
-#: eval.c:1446
-#, fuzzy, c-format
+#: eval.c:1185
+#, c-format
msgid "reference to uninitialized field `$%ld'"
-msgstr "referència a una variable sense inicialitzar «%s»"
+msgstr "referència a una variable sense inicialitzar `$%ld'"
-#: eval.c:1508
+#: eval.c:1272
#, 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"
+msgstr "s'ha cridat a la funció `%s' amb més arguments dels declarats"
-#: eval.c:1663
+#: eval.c:1473
#, c-format
msgid "unwind_stack: unexpected type `%s'"
-msgstr ""
+msgstr "unwind_stack: tipus no esperat `%s'"
-#: eval.c:1747
+#: eval.c:1569
msgid "division by zero attempted in `/='"
-msgstr "s'ha intentat una divisió per zero en «/=»"
+msgstr "s'ha intentat una divisió per zero en `/='"
-#: eval.c:1754
+#: eval.c:1576
#, c-format
msgid "division by zero attempted in `%%='"
-msgstr "s'ha intentat una divisió per zero en «%%=»"
+msgstr "s'ha intentat una divisió per zero en `%%='"
-#: eval.c:2057
-msgid "assignment used in conditional context"
-msgstr "assignació usada en un context condicional"
+#: ext.c:89 ext.c:171
+msgid "extensions are not allowed in sandbox mode"
+msgstr "les extensions no estan permeses en mode de proves"
-#: eval.c:2061
-msgid "statement has no effect"
-msgstr "la sentència no té efecte"
+#: ext.c:92
+msgid "-l / @load are gawk extensions"
+msgstr "-l / @load són extensions gawk"
-#: eval.c:2473
-#, 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"
+#: ext.c:95
+msgid "load_ext: received NULL lib_name"
+msgstr "load_ext: s'ha rebut lib_name nul"
+
+#: ext.c:98
+#, c-format
+msgid "load_ext: cannot open library `%s' (%s)\n"
+msgstr "load_ext: no es pot obrir la llibreria `%s' (%s)\n"
-#: eval.c:2583
+#: ext.c:104
#, c-format
-msgid "function called indirectly through `%s' does not exist"
+msgid ""
+"load_ext: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"
msgstr ""
+"load_ext: biblioteca `%s': no defineix `plugin_is_GPL_compatible' (%s)\n"
-#: eval.c:2595
+#: ext.c:110
#, c-format
-msgid "function `%s' not defined"
-msgstr "la funció «%s» no està definida"
+msgid "load_ext: library `%s': cannot call function `%s' (%s)\n"
+msgstr "load_ext: biblioteca `%s': no es pot cridar a la funció `%s' (%s)\n"
-#: eval.c:2656
-#, fuzzy, c-format
-msgid "non-redirected `getline' invalid inside `%s' rule"
-msgstr "port remot no vàlid en «%s»"
+#: ext.c:114
+#, c-format
+msgid "load_ext: library `%s' initialization routine `%s' failed\n"
+msgstr ""
+"load_ext: la biblioteca `%s' amb rutina d'inicialització `%s' ha fallat\n"
-#: eval.c:2717
-#, fuzzy, c-format
-msgid "`nextfile' cannot be called from a `%s' rule"
-msgstr "«nextfile» no es pot cridar des d'una regla FINAL"
+#: ext.c:174
+msgid "`extension' is a gawk extension"
+msgstr "`extension' és una extensió gawk"
-#: eval.c:2767
-#, fuzzy, c-format
-msgid "`next' cannot be called from a `%s' rule"
-msgstr "«next» no es pot cridar des d'una regla FINAL"
+#: ext.c:177
+msgid "extension: received NULL lib_name"
+msgstr "extension: s'ha rebut lib_name nul"
-#: eval.c:2834
+#: ext.c:180
#, c-format
-msgid "Sorry, don't know how to interpret `%s'"
-msgstr ""
+msgid "extension: cannot open library `%s' (%s)"
+msgstr "extension: no es pot obrir la biblioteca `%s' (%s)"
-#: ext.c:64
-msgid "extensions are not allowed in sandbox mode"
+#: ext.c:186
+#, c-format
+msgid ""
+"extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)"
msgstr ""
+"extension: biblioteca `%s': no defineix `plugin_is_GPL_compatible' (%s)"
-#: ext.c:70 ext.c:75
-msgid "`extension' is a gawk extension"
-msgstr "«extension» és una extensió gawk"
+#: ext.c:190
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)"
+msgstr "extension: biblioteca `%s': no es pot cridar a la funció `%s' (%s)"
-#: ext.c:85
-#, fuzzy, c-format
-msgid "fatal: extension: cannot open `%s' (%s)\n"
-msgstr "extension: no es pot obrir «%s» (%s)\n"
+#: ext.c:221
+msgid "make_builtin: missing function name"
+msgstr "make_builtin: nom absent de funció"
-#: ext.c:94
-#, fuzzy, c-format
-msgid ""
-"fatal: extension: library `%s': does not define "
-"`plugin_is_GPL_compatible' (%s)\n"
-msgstr "extension: biblioteca «%s»: no es pot cridar a la funció «%s» (%s)\n"
+#: ext.c:236
+#, c-format
+msgid "make_builtin: can't redefine function `%s'"
+msgstr "make_builtin: no es pot redefinir la funció `%s'"
+
+#: ext.c:240
+#, c-format
+msgid "make_builtin: function `%s' already defined"
+msgstr "make_builtin: la funció `%s' ja està definida"
+
+#: ext.c:244
+#, c-format
+msgid "make_builtin: function name `%s' previously defined"
+msgstr "make_builtin: nom de la funció `%s' definida prèviament"
+
+#: ext.c:246
+#, c-format
+msgid "make_builtin: can't use gawk built-in `%s' as function name"
+msgstr "make_builtin: no es pot usar el nom intern `%s' com a nom de funció"
-#: ext.c:103
-#, fuzzy, c-format
-msgid "fatal: 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:249 ext.c:304
+#, c-format
+msgid "make_builtin: negative argument count for function `%s'"
+msgstr "make_builtin: recompte negatiu d'arguments per a la funció `%s'"
-#: ext.c:137
+#: ext.c:276
msgid "extension: missing function name"
-msgstr ""
+msgstr "extension: nom absent de funció"
-#: ext.c:142
-#, fuzzy, c-format
+#: ext.c:279 ext.c:283
+#, 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"
+msgstr "extension: caràcter `%c' il·legal al nom de funció `%s'"
-#: ext.c:151
-#, fuzzy, c-format
+#: ext.c:291
+#, c-format
msgid "extension: can't redefine function `%s'"
-msgstr "extension: no es pot obrir «%s» (%s)\n"
+msgstr "extension: no es pot redefinir la funció `%s'"
-#: ext.c:155
-#, fuzzy, c-format
+#: ext.c:295
+#, c-format
msgid "extension: function `%s' already defined"
-msgstr "la funció «%s» no està definida"
+msgstr "extension: la funció `%s' ja està definida"
-#: ext.c:160
-#, fuzzy, c-format
+#: ext.c:299
+#, c-format
msgid "extension: function name `%s' previously defined"
-msgstr "nom de la funció «%s» definida prèviament"
+msgstr "extension: nom de la funció `%s' definida prèviament"
-#: ext.c:162
-#, fuzzy, c-format
+#: ext.c:301
+#, c-format
msgid "extension: can't use gawk built-in `%s' as function name"
-msgstr "funció «%s»: no pot usar el nom de la funció com a paràmetre"
+msgstr "extension: no es pot usar el nom intern `%s' com a nom de funció"
-#: ext.c:166
+#: ext.c:375
#, c-format
-msgid "make_builtin: negative argument count for function `%s'"
-msgstr ""
-
-#: ext.c:269
-#, 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"
+msgstr "la funció `%s' està definida per agafar no més de %d argument(s)"
-#: ext.c:272
-#, fuzzy, c-format
+#: ext.c:378
+#, c-format
msgid "function `%s': missing argument #%d"
-msgstr "la funció «%s» no està definida"
+msgstr "funció `%s': falta l'argument #%d"
-#: ext.c:282
-#, fuzzy, c-format
+#: ext.c:395
+#, 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"
+msgstr ""
+"funció `%s': argument #%d: s'ha intentat usar una dada escalar com a una "
+"matriu"
-#: ext.c:286
+#: ext.c:399
#, c-format
msgid "function `%s': argument #%d: attempt to use array as a scalar"
msgstr ""
+"funció `%s': argument #%d: s'ha intentat usar una matriu com a un escalar"
-#: ext.c:299
-msgid "Operation Not Supported"
-msgstr "Operació No Suportada"
+#: ext.c:413
+msgid "dynamic loading of library not supported"
+msgstr "no està suportada la càrrega dinàmica de la biblioteca"
+
+#: extension/filefuncs.c:159
+msgid "chdir: called with incorrect number of arguments, expecting 1"
+msgstr "chdir: cridat amb un nombre incorrecte d'arguments, s'esperava 1"
+
+#: extension/filefuncs.c:439
+#, c-format
+msgid "stat: unable to read symbolic link `%s'"
+msgstr "stat: no s'ha pogut llegir l'enllaç simbòlic `%s'"
+
+#: extension/filefuncs.c:472
+msgid "stat: called with wrong number of arguments"
+msgstr "stat: cridat amb un nombre incorrecte d'arguments"
+
+#: extension/filefuncs.c:479
+msgid "stat: bad parameters"
+msgstr "stata: arguments dolents"
+
+#: extension/filefuncs.c:533
+#, c-format
+msgid "fts init: could not create variable %s"
+msgstr "fts init: no s'ha pogut crear la variable %s"
+
+#: extension/filefuncs.c:554
+msgid "fts is not supported on this system"
+msgstr "fts no està suportat en aquest sistema"
+
+#: extension/filefuncs.c:573
+msgid "fill_stat_element: could not create array"
+msgstr "fill_stat_element: no s'ha pogut crear la matriu"
+
+#: extension/filefuncs.c:582
+msgid "fill_stat_element: could not set element"
+msgstr "fill_stat_element: no s'ha pogut establir l'element"
+
+#: extension/filefuncs.c:597
+msgid "fill_path_element: could not set element"
+msgstr "fill_path_element: no s'ha pogut establir l'element"
+
+#: extension/filefuncs.c:613
+msgid "fill_error_element: could not set element"
+msgstr "fill_error_element: no s'ha pogut establir l'element"
+
+#: extension/filefuncs.c:660 extension/filefuncs.c:707
+msgid "fts-process: could not create array"
+msgstr "fts-process: no s'ha pogut crear la matriu"
+
+#: extension/filefuncs.c:670 extension/filefuncs.c:717
+#: extension/filefuncs.c:735
+msgid "fts-process: could not set element"
+msgstr "fts-process: no s'ha pogut establir l'element"
+
+#: extension/filefuncs.c:784
+msgid "fts: called with incorrect number of arguments, expecting 3"
+msgstr "fts: cridat amb un nombre incorrecte d'arguments, s'esperaven 3"
+
+#: extension/filefuncs.c:787
+msgid "fts: bad first parameter"
+msgstr "fts: el segon argument és dolent"
+
+#: extension/filefuncs.c:793
+msgid "fts: bad second parameter"
+msgstr "fts: el segon argument és dolent"
+
+#: extension/filefuncs.c:799
+msgid "fts: bad third parameter"
+msgstr "fts: el tercer paràmeter es dolent"
+
+#: extension/filefuncs.c:806
+msgid "fts: could not flatten array\n"
+msgstr "fts: no s'ha pogut aplanar la matriu\n"
+
+#: extension/filefuncs.c:824
+msgid "fts: ignoring sneaky FTS_NOSTAT flag. nyah, nyah, nyah."
+msgstr "fts: s'ignorarà l'indicador FTS_NOSTAT furtiu. T'he enxampat!"
+
+#: extension/filefuncs.c:841
+msgid "fts: clear_array() failed\n"
+msgstr "fts: clear_array() ha fallat\n"
+
+#: extension/fnmatch.c:112
+msgid "fnmatch: called with less than three arguments"
+msgstr "fnmatch: s'ha cridat amb menys de tres arguments"
+
+#: extension/fnmatch.c:115
+msgid "fnmatch: called with more than three arguments"
+msgstr "fnmatch: s'ha cridat amb més de tres arguments"
+
+#: extension/fnmatch.c:118
+msgid "fnmatch: could not get first argument"
+msgstr "fnmatch: no s'ha pogut obtenir el segon argument"
+
+#: extension/fnmatch.c:123
+msgid "fnmatch: could not get second argument"
+msgstr "fnmatch: no s'ha pogut obtenir el segon argument"
+
+#: extension/fnmatch.c:128
+msgid "fnmatch: could not get third argument"
+msgstr "fnmatch: no s'ha pogut obtenir el tercer argument"
+
+#: extension/fnmatch.c:141
+msgid "fnmatch is not implemented on this system\n"
+msgstr "fnmatch no està implementat en aquest sistema\n"
+
+#: extension/fnmatch.c:173
+msgid "fnmatch init: could not add FNM_NOMATCH variable"
+msgstr "fnmatch init: no s'ha pogut afegir la variable FNM_NOMATCH"
+
+#: extension/fnmatch.c:183
+#, c-format
+msgid "fnmatch init: could not set array element %s"
+msgstr "fnmatch init: no s'ha pogut establir l'element de matriu %s"
+
+#: extension/fnmatch.c:193
+msgid "fnmatch init: could not install FNM array"
+msgstr "fnmatch init: no s'ha pogut instal·lar la matriu FNM"
+
+#: extension/fork.c:81
+msgid "fork: called with too many arguments"
+msgstr "fork: s'ha cridat amb massa arguments"
+
+#: extension/fork.c:94
+msgid "fork: PROCINFO is not an array!"
+msgstr "fork: PROCINFO no és una matriu!"
+
+#: extension/fork.c:118
+msgid "waitpid: called with too many arguments"
+msgstr "waitpid: s'ha cridat amb massa arguments"
+
+#: extension/fork.c:126
+msgid "wait: called with no arguments"
+msgstr "wait: s'ha cridat amb cap argument"
+
+#: extension/fork.c:143
+msgid "wait: called with too many arguments"
+msgstr "wait: s'ha cridat amb massa arguments"
+
+#: extension/inplace.c:130
+msgid "inplace_begin: in-place editing already active"
+msgstr "inplace_begin: l'edició in situ ja està activa"
+
+#: extension/inplace.c:133 extension/inplace.c:207
+#, c-format
+msgid "inplace_begin: expects 2 arguments but called with %d"
+msgstr "inplace_begin: s'esperaven 2 arguments però s'ha cridat amb %d"
+
+#: extension/inplace.c:136
+msgid "inplace_begin: cannot retrieve 1st argument as a string filename"
+msgstr ""
+"inplace_begin: no es pot obtenir el primer argument com nom de fitxer cadena "
+"de caràcters"
+
+#: extension/inplace.c:144
+#, c-format
+msgid "inplace_begin: disabling in-place editing for invalid FILENAME `%s'"
+msgstr ""
+"inplace_begin: s'està deshabilitant l'edició in situ per al nom de fitxer no "
+"vàlid `%s'"
+
+#: extension/inplace.c:151
+#, c-format
+msgid "inplace_begin: Cannot stat `%s' (%s)"
+msgstr "implace_begin: No es pot obrir `%s' (%s)"
+
+#: extension/inplace.c:158
+#, c-format
+msgid "inplace_begin: `%s' is not a regular file"
+msgstr "inplace_begin: `%s' no és un fitxer regular"
+
+#: extension/inplace.c:169
+#, c-format
+msgid "inplace_begin: mkstemp(`%s') failed (%s)"
+msgstr "inplace_begin: mkstemp(`%s') ha fallat (%s)"
+
+#: extension/inplace.c:178
+#, c-format
+msgid "inplace_begin: chmod failed (%s)"
+msgstr "inplace_begin: ha fallat chmod (%s)"
+
+#: extension/inplace.c:185
+#, c-format
+msgid "inplace_begin: dup(stdout) failed (%s)"
+msgstr "inplace_begin: dup(stdout) ha fallat(%s)"
+
+#: extension/inplace.c:188
+#, c-format
+msgid "inplace_begin: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_begin: dup2(%d, stdout) ha fallat (%s)"
+
+#: extension/inplace.c:191
+#, c-format
+msgid "inplace_begin: close(%d) failed (%s)"
+msgstr "inplace begin: close(%d) ha fallat (%s)"
+
+#: extension/inplace.c:210
+msgid "inplace_end: cannot retrieve 1st argument as a string filename"
+msgstr ""
+"inplace_end: no es pot obtenir el primer argument com un nom de fitxer "
+"cadena de caràcters"
-#: field.c:328
+#: extension/inplace.c:217
+msgid "inplace_end: in-place editing not active"
+msgstr "inplace_end: no està activa l'edició in situ"
+
+#: extension/inplace.c:223
+#, c-format
+msgid "inplace_end: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_end: dup2(%d, stdout) ha fallat (%s)"
+
+#: extension/inplace.c:226
+#, c-format
+msgid "inplace_end: close(%d) failed (%s)"
+msgstr "inplace_end: close(%d) ha fallat (%s)"
+
+#: extension/inplace.c:230
+#, c-format
+msgid "inplace_end: fsetpos(stdout) failed (%s)"
+msgstr "inplace_end: fsetpos(stdout) ha fallat (%s)"
+
+#: extension/inplace.c:243
+#, c-format
+msgid "inplace_end: link(`%s', `%s') failed (%s)"
+msgstr "inplace_end: link(`%s', `%s') ha fallat (%s)"
+
+#: extension/inplace.c:253
+#, c-format
+msgid "inplace_end: rename(`%s', `%s') failed (%s)"
+msgstr "inplace_end: rename(`%s', `%s') ha fallat (%s)"
+
+#: extension/ordchr.c:69
+msgid "ord: called with too many arguments"
+msgstr "ord: s'ha cridat amb massa arguments"
+
+#: extension/ordchr.c:75
+msgid "ord: called with no arguments"
+msgstr "ord: s'ha cridat amb cap argument"
+
+#: extension/ordchr.c:77
+msgid "ord: called with inappropriate argument(s)"
+msgstr "ord: s'ha cridat amb argument(s) no apropiat(s)"
+
+#: extension/ordchr.c:99
+msgid "chr: called with too many arguments"
+msgstr "chr: s'ha cridat amb massa arguments"
+
+#: extension/ordchr.c:109
+msgid "chr: called with no arguments"
+msgstr "chr: s'ha cridat amb cap argument"
+
+#: extension/ordchr.c:111
+msgid "chr: called with inappropriate argument(s)"
+msgstr "chr: s'ha cridat amb argument(s) no apropiat(s)"
+
+#: extension/readdir.c:281
+#, c-format
+msgid "dir_take_control_of: opendir/fdopendir failed: %s"
+msgstr "dir_take_control_of: opendir/fdopendir ha fallat: %s"
+
+#: extension/readfile.c:113
+msgid "readfile: called with too many arguments"
+msgstr "readfile: s'ha cridat amb massa arguments"
+
+#: extension/readfile.c:137
+msgid "readfile: called with no arguments"
+msgstr "readfile: s'ha cridat amb cap argument"
+
+#: extension/rwarray.c:124
+msgid "writea: called with too many arguments"
+msgstr "writea: s'ha cridat amb massa arguments"
+
+#: extension/rwarray.c:131
+#, c-format
+msgid "do_writea: argument 0 is not a string\n"
+msgstr "do_writea: l'argument 0 no és una cadena de caràcters\n"
+
+#: extension/rwarray.c:137
+#, c-format
+msgid "do_writea: argument 1 is not an array\n"
+msgstr "do_writea: l'argument 1 no és una matriu\n"
+
+#: extension/rwarray.c:184
+#, c-format
+msgid "write_array: could not flatten array\n"
+msgstr "write_array: no s'ha pogut aplanar la matriu\n"
+
+#: extension/rwarray.c:198
+#, c-format
+msgid "write_array: could not release flattened array\n"
+msgstr "write_array: no s'ha pogut alliberar la matriu aplanada\n"
+
+#: extension/rwarray.c:280
+msgid "reada: called with too many arguments"
+msgstr "reada: s'ha cridat amb massa arguments"
+
+#: extension/rwarray.c:287
+#, c-format
+msgid "do_reada: argument 0 is not a string\n"
+msgstr "do_reada: l'argument 0 no és una cadena de caràcters\n"
+
+#: extension/rwarray.c:293
+#, c-format
+msgid "do_reada: argument 1 is not an array\n"
+msgstr "do_reada: l'argument 1 no és una matriu\n"
+
+#: extension/rwarray.c:337
+#, c-format
+msgid "do_reada: clear_array failed\n"
+msgstr "do_reada: clear_array ha fallat\n"
+
+#: extension/rwarray.c:374
+#, c-format
+msgid "read_array: set_array_element failed\n"
+msgstr "read_array: set_array_element ha fallat\n"
+
+#: extension/time.c:113
+msgid "gettimeofday: ignoring arguments"
+msgstr "gettimeofday: s'estan ignorant els arguments"
+
+#: extension/time.c:144
+msgid "gettimeofday: not supported on this platform"
+msgstr "gettimeofday: no està suportat en aquesta plataforma"
+
+#: extension/time.c:165
+msgid "sleep: called with too many arguments"
+msgstr "sleep: s'ha cridat amb massa arguments"
+
+#: extension/time.c:168
+msgid "sleep: missing required numeric argument"
+msgstr "sleep: no hi ha un argument numèric requerit"
+
+#: extension/time.c:174
+msgid "sleep: argument is negative"
+msgstr "sleep: l'argument és negatiu"
+
+#: extension/time.c:208
+msgid "sleep: not supported on this platform"
+msgstr "sleep: no està suportat en aquesta plataforma"
+
+#: field.c:345
msgid "NF set to negative value"
msgstr "NF s'inicialitza sobre un valor negatiu"
-#: field.c:939 field.c:946 field.c:950
-#, fuzzy
+#: field.c:971 field.c:978 field.c:982
msgid "split: fourth argument is a gawk extension"
-msgstr "match: el tercer argument és una extensió de gawk"
+msgstr "split: el quart argument és una extensió gawk"
-#: field.c:943
-#, fuzzy
+#: field.c:975
msgid "split: fourth argument is not an array"
-msgstr "split: el segon argument no és una matriu"
+msgstr "split: el quart argument no és una matriu"
-#: field.c:957
+#: field.c:989
msgid "split: second argument is not an array"
msgstr "split: el segon argument no és una matriu"
-#: field.c:962
-msgid "split: can not use the same array for second and fourth args"
+#: field.c:993
+msgid "split: cannot use the same array for second and fourth args"
+msgstr ""
+"split: no es pot usar una submatriu de segon argument per a quart argument"
+
+#: field.c:998
+msgid "split: cannot use a subarray of second arg for fourth arg"
+msgstr ""
+"split: no es pot usar una submatriu de segon argument per a quart argument"
+
+#: field.c:1001
+msgid "split: cannot use a subarray of fourth arg for second arg"
msgstr ""
+"split: no est pot usar una submatriu de quart argument per a segon argument"
-#: field.c:990
+#: field.c:1032
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:1031
-#, fuzzy
+#: field.c:1072
msgid "patsplit: fourth argument is not an array"
-msgstr "split: el segon argument no és una matriu"
+msgstr "patsplit: el quart argument no és una matriu"
-#: field.c:1036
-#, fuzzy
+#: field.c:1077
msgid "patsplit: second argument is not an array"
-msgstr "split: el segon argument no és una matriu"
+msgstr "patsplit: el tercer argument no és una matriu"
-#: field.c:1054
-#, fuzzy
+#: field.c:1083
msgid "patsplit: third argument must be non-null"
-msgstr "match: el tercer argument no és una matriu"
+msgstr "patsplit: el segon argument no és una matriu"
-#: field.c:1059
-msgid "patsplit: can not use the same array for second and fourth args"
+#: field.c:1087
+msgid "patsplit: cannot use the same array for second and fourth args"
msgstr ""
+"patsplit: no es pot usar la mateixa matriu per a segon i quart argument"
-#: field.c:1089
+#: field.c:1092
+msgid "patsplit: cannot use a subarray of second arg for fourth arg"
+msgstr ""
+"patsplit: no es pot usar una submatriu de segon argument per a quart argument"
+
+#: field.c:1095
+msgid "patsplit: cannot use a subarray of fourth arg for second arg"
+msgstr ""
+"patsplit: no es pot usar una submatriu de quart argument per a segon argument"
+
+#: field.c:1133
msgid "`FIELDWIDTHS' is a gawk extension"
-msgstr "«FIELDWIDTHS» és una extensió de gawk"
+msgstr "`FIELDWIDTHS' és una extensió de gawk"
-#: field.c:1152
+#: field.c:1197
#, c-format
msgid "invalid FIELDWIDTHS value, near `%s'"
-msgstr ""
+msgstr "valor FIELDWIDTHS no vàlid, a prop de `%s'"
-#: field.c:1225
+#: field.c:1270
msgid "null string for `FS' is a gawk extension"
-msgstr "la cadena nul·la per a «FS» és una extensió de gawk"
+msgstr "la cadena nul·la per a `FS' és una extensió de gawk"
-#: field.c:1229
-#, fuzzy
+#: field.c:1274
msgid "old awk does not support regexps as value of `FS'"
-msgstr "l'antic awk no suporta l'operador «**=»"
+msgstr "l'antic awk no suporta expressions regulars com a valor de `FS'"
-#: field.c:1348
-#, fuzzy
+#: field.c:1393
msgid "`FPAT' is a gawk extension"
-msgstr "«%s» és una extensió de gawk"
+msgstr "`FPAT' és una extensió gawk"
+
+#: gawkapi.c:146
+msgid "awk_value_to_node: received null retval"
+msgstr "awk_value_to_node: s'ha rebut retval nul"
+
+#: gawkapi.c:384
+msgid "node_to_awk_value: received null node"
+msgstr "node_to_awk_value: s'ha rebut un node nul"
-#: getopt.c:574 getopt.c:590
-#, fuzzy, c-format
-msgid "%s: option '%s' is ambiguous\n"
-msgstr "%s: l'opció «%s» és ambigua\n"
+#: gawkapi.c:387
+msgid "node_to_awk_value: received null val"
+msgstr "node_to_awk_value: s'ha rebut un valor nul"
-#: getopt.c:623 getopt.c:627
-#, fuzzy, c-format
+#: gawkapi.c:807
+msgid "remove_element: received null array"
+msgstr "remove_element: s'ha rebut una matriu nul·la"
+
+#: gawkapi.c:810
+msgid "remove_element: received null subscript"
+msgstr "remove_element: s'ha rebut un subíndex nul"
+
+#: gawkapi.c:947
+#, c-format
+msgid "api_flatten_array: could not convert index %d\n"
+msgstr "api_flatten_array: no s'ha pogut convertir l'índex %d\n"
+
+#: gawkapi.c:952
+#, c-format
+msgid "api_flatten_array: could not convert value %d\n"
+msgstr "api_flatten_array: no s'ha pogut convertir el valor %d\n"
+
+#: getopt.c:604 getopt.c:633
+#, c-format
+msgid "%s: option '%s' is ambiguous; possibilities:"
+msgstr "%s: l'opció `%s' és ambigua<b: possibilitats:"
+
+#: getopt.c:679 getopt.c:683
+#, c-format
msgid "%s: option '--%s' doesn't allow an argument\n"
-msgstr "%s: l'opció «--%s» no admet cap argument\n"
+msgstr "%s: l'opció `--%s' no admet cap argument\n"
-#: getopt.c:636 getopt.c:641
-#, fuzzy, c-format
+#: getopt.c:692 getopt.c:697
+#, c-format
msgid "%s: option '%c%s' doesn't allow an argument\n"
-msgstr "%s: l'opció «%c%s» no admet cap argument\n"
+msgstr "%s: l'opció `%c%s' no admet cap argument\n"
-#: getopt.c:684 getopt.c:703
-#, fuzzy, c-format
+#: getopt.c:740 getopt.c:759
+#, c-format
msgid "%s: option '--%s' requires an argument\n"
-msgstr "%s: l'opció «%s» requereix un argument\n"
+msgstr "%s: l'opció `--%s' requereix un argument\n"
-#: getopt.c:741 getopt.c:744
-#, fuzzy, c-format
+#: getopt.c:797 getopt.c:800
+#, c-format
msgid "%s: unrecognized option '--%s'\n"
-msgstr "%s: no es reconeix l'opció «--%s»\n"
+msgstr "%s: no es reconeix l'opció `--%s'\n"
-#: getopt.c:752 getopt.c:755
-#, fuzzy, c-format
+#: getopt.c:808 getopt.c:811
+#, c-format
msgid "%s: unrecognized option '%c%s'\n"
-msgstr "%s: no es reconeix l'opció «%c%s»\n"
+msgstr "%s: no es reconeix l'opció `%c%s'\n"
-#: getopt.c:804 getopt.c:807
-#, fuzzy, c-format
+#: getopt.c:860 getopt.c:863
+#, c-format
msgid "%s: invalid option -- '%c'\n"
-msgstr "%s: opció no vàlida -- %c\n"
+msgstr "%s: opció no vàlida -- '%c'\n"
-#: getopt.c:857 getopt.c:874 getopt.c:1082 getopt.c:1100
-#, fuzzy, c-format
+#: getopt.c:916 getopt.c:933 getopt.c:1143 getopt.c:1161
+#, c-format
msgid "%s: option requires an argument -- '%c'\n"
-msgstr "%s: l'opció requereix un argument -- %c\n"
+msgstr "%s: l'opció requereix un argument -- '%c'\n"
-#: getopt.c:930 getopt.c:946
-#, fuzzy, c-format
+#: getopt.c:989 getopt.c:1005
+#, c-format
msgid "%s: option '-W %s' is ambiguous\n"
-msgstr "%s: l'opció «-W %s» és ambigua\n"
+msgstr "%s: l'opció `-W %s' és ambigua\n"
-#: getopt.c:970 getopt.c:988
-#, fuzzy, c-format
+#: getopt.c:1029 getopt.c:1047
+#, c-format
msgid "%s: option '-W %s' doesn't allow an argument\n"
-msgstr "%s: l'opció «-W %s» no admet cap argument\n"
+msgstr "%s: l'opció `-W %s' no admet cap argument\n"
-#: getopt.c:1009 getopt.c:1027
-#, fuzzy, c-format
+#: getopt.c:1068 getopt.c:1086
+#, c-format
msgid "%s: option '-W %s' requires an argument\n"
-msgstr "%s: l'opció «%s» requereix un argument\n"
+msgstr "%s: l'opció `-W %s' requereix un argument\n"
-#: io.c:282
+#: io.c:392
#, c-format
msgid "command line argument `%s' is a directory: skipped"
-msgstr ""
+msgstr "l'argument `%s' de línia d'ordres és un directori: s'ignorarà"
-#: io.c:285 io.c:382
+#: io.c:395 io.c:513
#, c-format
msgid "cannot open file `%s' for reading (%s)"
-msgstr "no es pot obrir el fitxer «%s» per a lectura (%s)"
-
-#: io.c:429
-#, c-format
-msgid "error reading input file `%s': %s"
-msgstr "error en llegir el fitxer d'entrada «%s»: %s"
+msgstr "no es pot obrir el fitxer `%s' per a lectura (%s)"
-#: io.c:498
+#: io.c:640
#, c-format
msgid "close of fd %d (`%s') failed (%s)"
-msgstr "la finalització del descriptor fd %d («%s») ha fallat (%s)"
+msgstr "la finalització del descriptor fd %d (`%s') ha fallat (%s)"
-#: io.c:575
+#: io.c:716
msgid "redirection not allowed in sandbox mode"
-msgstr ""
+msgstr "no est permeten redireccions en mode de proves"
-#: io.c:609
+#: io.c:750
#, c-format
msgid "expression in `%s' redirection only has numeric value"
-msgstr "l'expressió en la redirecció «%s» solt té un valor numèric"
+msgstr "l'expressió en la redirecció `%s' solt té un valor numèric"
-#: io.c:615
+#: io.c:756
#, 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"
+msgstr "l'expressió per a la redirecció `%s' té un valor de cadena nul·la"
-#: io.c:621
+#: io.c:761
#, 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ó "
+"el fitxer `%s' per a la redirecció `%s' pot ser resultat d'una expressió "
"lògica"
-#: io.c:664
+#: io.c:809
#, c-format
msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
-msgstr "mescla innecessària de «>» i «>>» per al fitxer «%.*s»"
+msgstr "mescla innecessària de `>' i `>>' per al fitxer `%.*s'"
-#: io.c:717
+#: io.c:863
#, c-format
msgid "can't open pipe `%s' for output (%s)"
-msgstr "no es pot obrir la canonada «%s» per a l'eixida (%s)"
+msgstr "no es pot obrir la canonada `%s' per a l'eixida (%s)"
-#: io.c:727
+#: io.c:873
#, c-format
msgid "can't open pipe `%s' for input (%s)"
-msgstr "no es pot obrir la canonada «%s» per a l'entrada (%s)"
+msgstr "no es pot obrir la canonada `%s' per a l'entrada (%s)"
-#: io.c:749
+#: io.c:904
#, 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 "
+"no es pot obrir una canonada bidireccional `%s' per a les entrades/eixides "
"(%s)"
-#: io.c:831
+#: io.c:986
#, c-format
msgid "can't redirect from `%s' (%s)"
-msgstr "no es pot redirigir des de «%s» (%s)"
+msgstr "no es pot redirigir des de `%s' (%s)"
-#: io.c:834
+#: io.c:989
#, c-format
msgid "can't redirect to `%s' (%s)"
-msgstr "no es pot redirigir cap a «%s» (%s)"
+msgstr "no es pot redirigir cap a `%s' (%s)"
-#: io.c:883
+#: io.c:1040
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:899
+#: io.c:1056
#, c-format
msgid "close of `%s' failed (%s)."
-msgstr "la finalització de «%s» ha fallat (%s)"
+msgstr "la finalització de `%s' ha fallat (%s)"
-#: io.c:907
+#: io.c:1064
msgid "too many pipes or input files open"
msgstr "masses canonades o fitxers d'entrada oberts"
-#: io.c:929
+#: io.c:1086
msgid "close: second argument must be `to' or `from'"
-msgstr "close: el segon argument hauria de ser «to» o «from»"
+msgstr "close: el segon argument hauria de ser `to' o `from'"
-#: io.c:946
+#: io.c:1103
#, 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"
+msgstr "close: `%.*s' no és un fitxer obert, canonada o co-procés"
-#: io.c:951
+#: io.c:1108
msgid "close of redirection that was never opened"
msgstr "finalització d'una redirecció que no s'ha obert"
-#: io.c:1048
+#: io.c:1205
#, 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"
+"close: la redirecció `%s' no s'obre amb `|&', s'ignora el segon argument"
-#: io.c:1064
+#: io.c:1222
#, 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)"
+msgstr "estat de fallada (%d) en la finalització de la canonada `%s' (%s)"
-#: io.c:1067
+#: io.c:1225
#, c-format
msgid "failure status (%d) on file close of `%s' (%s)"
-msgstr "estatus de falla (%d) en la finalització del fitxer «%s» (%s)"
+msgstr "estat de falla (%d) en la finalització del fitxer `%s' (%s)"
-#: io.c:1087
+#: io.c:1245
#, c-format
msgid "no explicit close of socket `%s' provided"
-msgstr "no s'aporta la finalització explícita del socket «%s»"
+msgstr "no s'aporta la finalització explícita del socket `%s'"
-#: io.c:1090
+#: io.c:1248
#, c-format
msgid "no explicit close of co-process `%s' provided"
-msgstr "no s'aporta la finalització explícita del co-procés «%s»"
+msgstr "no s'aporta la finalització explícita del co-procés `%s'"
-#: io.c:1093
+#: io.c:1251
#, c-format
msgid "no explicit close of pipe `%s' provided"
-msgstr "no s'aporta la finalització explícita de la canonada «%s»"
+msgstr "no s'aporta la finalització explícita de la canonada `%s'"
-#: io.c:1096
+#: io.c:1254
#, c-format
msgid "no explicit close of file `%s' provided"
-msgstr "no s'aporta la finalització explícita del fitxer «%s»"
+msgstr "no s'aporta la finalització explícita del fitxer `%s'"
-#: io.c:1124 io.c:1179 main.c:809 main.c:851
+#: io.c:1284 io.c:1342 main.c:864 main.c:906
#, c-format
msgid "error writing standard output (%s)"
-msgstr "error a l'escriure en l'eixida estàndard (%s)"
+msgstr "error en escriure a la sortida estàndard (%s)"
-#: io.c:1128 io.c:1184
+#: io.c:1289 io.c:1348 main.c:866
#, c-format
msgid "error writing standard error (%s)"
-msgstr "error a l'escriure en l'eixida d'error estàndard (%s)"
+msgstr "error en escriure a la sortida d'error estàndard (%s)"
-#: io.c:1136
+#: io.c:1297
#, c-format
msgid "pipe flush of `%s' failed (%s)."
-msgstr "la neteja de la canonada de «%sx» ha fallat (%s)."
+msgstr "la neteja de la canonada de `%sx' ha fallat (%s)."
-#: io.c:1139
+#: io.c:1300
#, 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)."
+msgstr "la neteja de la canonada per al co-procés de `%sx' ha fallat (%s)."
-#: io.c:1142
+#: io.c:1303
#, c-format
msgid "file flush of `%s' failed (%s)."
-msgstr "la neteja del fitxer «%sx» ha fallat (%s)."
+msgstr "la neteja del fitxer `%s' ha fallat (%s)."
-#: io.c:1257
-#, fuzzy, c-format
+#: io.c:1420
+#, c-format
msgid "local port %s invalid in `/inet'"
-msgstr "port local no vàlid en «%s»"
+msgstr "port local %s no vàlid a `/inet'"
-#: io.c:1274
+#: io.c:1438
#, c-format
msgid "remote host and port information (%s, %s) invalid"
-msgstr ""
+msgstr "amfitrió remot i informació de port (%s, %s) no vàlids"
-#: io.c:1426
+#: io.c:1590
#, 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»"
+msgstr "no s'aporta cap protocol (conegut) en el nom del fitxer especial `%s'"
-#: io.c:1440
+#: io.c:1604
#, c-format
msgid "special file name `%s' is incomplete"
-msgstr "el nom del fitxer especial «%s» està incomplet"
+msgstr "el nom del fitxer especial `%s' està incomplet"
-#: io.c:1457
+#: io.c:1621
msgid "must supply a remote hostname to `/inet'"
-msgstr "s'ha de subministrar un nom de sistema remot a «/inet»"
+msgstr "s'ha de subministrar un nom de sistema remot a `/inet'"
-#: io.c:1475
+#: io.c:1639
msgid "must supply a remote port to `/inet'"
-msgstr "s'ha de subministrar un port remot a «/inet»"
+msgstr "s'ha de subministrar un port remot a `/inet'"
-#: io.c:1521
+#: io.c:1685
msgid "TCP/IP communications are not supported"
msgstr "les comunicacions TCP/IP no estan suportades"
-#: io.c:1688
+#: io.c:1867
#, c-format
msgid "could not open `%s', mode `%s'"
-msgstr "no es pot obrir «%s», mode «%s»"
+msgstr "no es pot obrir `%s', mode `%s'"
-#: io.c:1739
-#, fuzzy, c-format
+#: io.c:1917
+#, c-format
msgid "close of master pty failed (%s)"
-msgstr "ha fallat la finalització de la canonada (%s)"
+msgstr "ha fallat el tancament del pty mestre (%s)"
-#: io.c:1741 io.c:1909 io.c:2066
+#: io.c:1919 io.c:2105 io.c:2305
#, 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)"
+"ha fallat la finalització de la sortida estàndard en els processos fills (%s)"
-#: io.c:1744
-#, fuzzy, c-format
+#: io.c:1922
+#, 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)"
+"ha fallat el trasllat del pty esclau cap a l'eixida estàndard dels processos "
+"fills (dup: %s)"
-#: io.c:1746 io.c:1914
+#: io.c:1924 io.c:2110
#, 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:1749
-#, fuzzy, c-format
+#: io.c:1927
+#, 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)"
+"ha fallat el trasllat del pty esclau cap a l'entrada estàndard dels "
+"processos fills (dup: %s)"
-#: io.c:1751 io.c:1772
-#, fuzzy, c-format
+#: io.c:1929 io.c:1951
+#, c-format
msgid "close of slave pty failed (%s)"
-msgstr "ha fallat la finalització de la canonada (%s)"
+msgstr "ha fallat el tancament del pty esclau (%s)"
-#: io.c:1850 io.c:1912 io.c:2044 io.c:2069
+#: io.c:2040 io.c:2108 io.c:2276 io.c:2308
#, 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:1857 io.c:1917
+#: io.c:2047 io.c:2113
#, 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:1877 io.c:2059
+#: io.c:2073 io.c:2298
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:1885
+#: io.c:2081
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:1920 io.c:2071 io.c:2085
+#: io.c:2116 io.c:2310 io.c:2324
#, c-format
msgid "close of pipe failed (%s)"
msgstr "ha fallat la finalització de la canonada (%s)"
-#: io.c:1965
+#: io.c:2174
msgid "`|&' not supported"
-msgstr "«|&» no està suportat"
+msgstr "`|&' no està suportat"
-#: io.c:2031
+#: io.c:2261
#, c-format
msgid "cannot open pipe `%s' (%s)"
-msgstr "no es pot obrir la canonada «%s» (%s)"
+msgstr "no es pot obrir la canonada `%s' (%s)"
-#: io.c:2079
+#: io.c:2318
#, 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)"
+msgstr "no es pot crear el procés fill per a `%s' (fork: %s)"
+
+#: io.c:2790
+msgid "register_input_parser: received NULL pointer"
+msgstr "register_input_parser: s'ha rebut un punter nul"
-#: io.c:2569
+#: io.c:2818
#, c-format
-msgid "data file `%s' is empty"
-msgstr "el fitxer de dades «%s» està buit"
+msgid "input parser `%s' conflicts with previously installed input parser `%s'"
+msgstr ""
+"l'analitzador d'entrades `%s' està en conflicte amb analitzador d'entrades `"
+"%s' instal·lat prèviament"
-#: io.c:2610 io.c:2618
-msgid "could not allocate more input memory"
+#: io.c:2825
+#, c-format
+msgid "input parser `%s' failed to open `%s'"
+msgstr "l'analitzador d'entrada `%s' no ha pogut obrir `%s'"
+
+#: io.c:2845
+msgid "register_output_wrapper: received NULL pointer"
+msgstr "register_output_wrapper: s'ha rebut un punter nul"
+
+#: io.c:2873
+#, c-format
+msgid ""
+"output wrapper `%s' conflicts with previously installed output wrapper `%s'"
msgstr ""
+"l'embolcall de sortida `%s' està en conflicte amb l'embolcall de sortida `"
+"%s' instal·lat prèviament"
-#: io.c:3171
-msgid "multicharacter value of `RS' is a gawk extension"
-msgstr "el valor multicaràcter de «RS» és una extensió de gawk"
+#: io.c:2880
+#, c-format
+msgid "output wrapper `%s' failed to open `%s'"
+msgstr "l'embolcall de sortida `%s' no ha pogut obrir `%s'"
-#: io.c:3276
-#, fuzzy
-msgid "IPv6 communication is not supported"
-msgstr "les comunicacions TCP/IP no estan suportades"
+#: io.c:2901
+msgid "register_output_processor: received NULL pointer"
+msgstr "register_output_processor: s'ha rebut un punter nul"
-#: main.c:307
-msgid "out of memory"
-msgstr "memòria esgotada"
+#: io.c:2930
+#, c-format
+msgid ""
+"two-way processor `%s' conflicts with previously installed two-way processor "
+"`%s'"
+msgstr ""
+"el processsador de dues vies `%s' està en conflicte amb el processador de "
+"dues vies `%s' instal·lat prèviament"
-#: main.c:384
-msgid "`-m[fr]' option irrelevant in gawk"
-msgstr "l'opción «-m[fr]» és irrellevant en gawk"
+#: io.c:2939
+#, c-format
+msgid "two way processor `%s' failed to open `%s'"
+msgstr "el processador de dues vies `%s' no ha pogut obrir `%s'"
+
+#: io.c:3064
+#, c-format
+msgid "data file `%s' is empty"
+msgstr "el fitxer de dades `%s' està buit"
-#: main.c:386
-msgid "-m option usage: `-m[fr] nnn'"
-msgstr "ús de l'opció -m: «-m[fr] nnn»"
+#: io.c:3106 io.c:3114
+msgid "could not allocate more input memory"
+msgstr "no s'ha pogut assignar més memòria d'entrada"
+
+#: io.c:3682
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr "el valor multicaràcter de `RS' és una extensió de gawk"
-#: main.c:409
-#, fuzzy
+#: io.c:3771
+msgid "IPv6 communication is not supported"
+msgstr "la comunicació IPv6 no està suportada"
+
+#: main.c:405
msgid "empty argument to `-e/--source' ignored"
-msgstr "s'igonarà l'argument buit per a l'opció «--source»"
+msgstr "s'ignonarà l'argument buit de `-e/--source'"
-#: main.c:475
+#: main.c:495
#, c-format
msgid "%s: option `-W %s' unrecognized, ignored\n"
-msgstr "%s: no es reconeix l'opció «-W %s», serà ignorada\n"
+msgstr "%s: no es reconeix l'opció `-W %s', serà ignorada\n"
-#: main.c:528
+#: main.c:541
#, c-format
msgid "%s: option requires an argument -- %c\n"
msgstr "%s: l'opció requereix un argument -- %c\n"
-#: main.c:549
+#: main.c:562
msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
msgstr ""
-"la variable d'entorn «POSIXLY_CORRECT» està establerta: usant «--posix»"
+"la variable d'entorn `POSIXLY_CORRECT' està establerta: usant `--posix'"
-#: main.c:555
+#: main.c:568
msgid "`--posix' overrides `--traditional'"
-msgstr "«--posix» solapa a «--traditional»"
+msgstr "`--posix' solapa a `--traditional'"
-#: main.c:566
+#: main.c:579
msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
-msgstr "«--posix» i «--traditional» solapen a «--non-decimal-data»"
+msgstr "`--posix' i `--traditional' solapen a `--non-decimal-data'"
-#: main.c:570
-#, fuzzy, c-format
+#: main.c:583
+#, 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:575
-#, fuzzy
-msgid "`--posix' overrides `--binary'"
-msgstr "«--posix» solapa a «--traditional»"
+#: main.c:588
+msgid "`--posix' overrides `--characters-as-bytes'"
+msgstr "`--posix' anul·la a `--characters-as-bytes'"
-#: main.c:626
-#, fuzzy, c-format
+#: main.c:647
+#, c-format
msgid "can't set binary mode on stdin (%s)"
-msgstr "no es pot establir el mode en l'entrada estàndard (%s)"
+msgstr "no es pot establir el mode binari en l'entrada estàndard (%s)"
-#: main.c:629
-#, fuzzy, c-format
+#: main.c:650
+#, 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:631
-#, fuzzy, c-format
+#: main.c:652
+#, 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:670
+#: main.c:710
msgid "no program text at all!"
msgstr "no hi ha cap text per al programa!"
-#: main.c:749
+#: main.c:799
#, 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:751
+#: main.c:801
#, 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:756
-#, fuzzy
+#: main.c:806
msgid "POSIX options:\t\tGNU long options: (standard)\n"
-msgstr "Opcions POSIX:\t\tOpcions llargues GNU:\n"
+msgstr "Opcions POSIX:\t\tOpcions llargues GNU: (estàndard)\n"
-#: main.c:757
+#: main.c:807
msgid "\t-f progfile\t\t--file=progfile\n"
msgstr "\t-f fitx_prog\t\t--file=fitx_prog\n"
-#: main.c:758
+#: main.c:808
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:759
+#: main.c:809
msgid "\t-v var=val\t\t--assign=var=val\n"
msgstr "\t-v var=valor\t\t--assign=var=valor\n"
-#: main.c:760
-#, fuzzy
+#: main.c:810
msgid "Short options:\t\tGNU long options: (extensions)\n"
-msgstr "Opcions POSIX:\t\tOpcions llargues GNU:\n"
+msgstr "Opcions curtes:\t\tOpcions llargues GNU: (extensions)\n"
-#: main.c:761
+#: main.c:811
msgid "\t-b\t\t\t--characters-as-bytes\n"
-msgstr ""
+msgstr "\t-b\t\t\t--characters-as-bytes\n"
-#: main.c:762
-#, fuzzy
+#: main.c:812
msgid "\t-c\t\t\t--traditional\n"
-msgstr "\t-W traditional\t\t--traditional\n"
+msgstr "\t-c\t\t\t--traditional\n"
-#: main.c:763
-#, fuzzy
+#: main.c:813
msgid "\t-C\t\t\t--copyright\n"
-msgstr "\t-W copyright\t\t--copyright\n"
+msgstr "\t-C\t\t\t--copyright\n"
+
+#: main.c:814
+msgid "\t-d[file]\t\t--dump-variables[=file]\n"
+msgstr "\t-d[file]\t\t--dump-variables[=file]\n"
-#: main.c:764
-#, fuzzy
-msgid "\t-d [file]\t\t--dump-variables[=file]\n"
-msgstr "\t-W dump-variables[=fitxer] --dump-variables[=fitxer]\n"
+#: main.c:815
+msgid "\t-D[file]\t\t--debug[=file]\n"
+msgstr "\t-D[file]\t\t--debug[=file]\n"
-#: main.c:765
-#, fuzzy
+#: main.c:816
msgid "\t-e 'program-text'\t--source='program-text'\n"
-msgstr "\t-W source=text_prog\t--source=text_prog\n"
+msgstr "\t-e 'program-text'\t--source='program-text'\n"
-#: main.c:766
-#, fuzzy
+#: main.c:817
msgid "\t-E file\t\t\t--exec=file\n"
-msgstr "\t-W profile[=fitxer]\t--profile[=fitxer]\n"
+msgstr "\t-E file\t\t\t--exec=file\n"
-#: main.c:767
-#, fuzzy
+#: main.c:818
msgid "\t-g\t\t\t--gen-pot\n"
-msgstr "\t-W gen-po\t\t--gen-po\n"
+msgstr "\t-g\t\t\t--gen-pot\n"
-#: main.c:768
-#, fuzzy
+#: main.c:819
msgid "\t-h\t\t\t--help\n"
-msgstr "\t-W help\t\t\t--help\n"
+msgstr "\t-h\t\t\t--help\n"
-#: main.c:769
-#, fuzzy
+#: main.c:820
+msgid "\t-i includefile\t\t--include=includefile\n"
+msgstr "\t-i includefile\t\t--include=fitxer a incloure\n"
+
+#: main.c:821
+msgid "\t-l library\t\t--load=library\n"
+msgstr "\t-l library\t\t--load=biblioteca\n"
+
+#: main.c:822
msgid "\t-L [fatal]\t\t--lint[=fatal]\n"
-msgstr "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr "\t-L [fatal]\t\t--lint[=fatal]\n"
-#: main.c:770
-#, fuzzy
+#: main.c:823
msgid "\t-n\t\t\t--non-decimal-data\n"
-msgstr "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr "\t-n\t\t\t--non-decimal-data\n"
+
+#: main.c:824
+msgid "\t-M\t\t\t--bignum\n"
+msgstr "\t-M\t\t\t--bignum\n"
-#: main.c:771
+#: main.c:825
msgid "\t-N\t\t\t--use-lc-numeric\n"
-msgstr ""
+msgstr "\t-N\t\t\t--use-lc-numeric\n"
+
+#: main.c:826
+msgid "\t-o[file]\t\t--pretty-print[=file]\n"
+msgstr "\t-o[file]\t\t--pretty-print[=file]\n"
-#: main.c:772
+#: main.c:827
msgid "\t-O\t\t\t--optimize\n"
-msgstr ""
+msgstr "\t-O\t\t\t--optimize\n"
-#: main.c:773
-#, fuzzy
-msgid "\t-p [file]\t\t--profile[=file]\n"
-msgstr "\t-W profile[=fitxer]\t--profile[=fitxer]\n"
+#: main.c:828
+msgid "\t-p[file]\t\t--profile[=file]\n"
+msgstr "\t-p[file]\t\t--profile[=file]\n"
-#: main.c:774
-#, fuzzy
+#: main.c:829
msgid "\t-P\t\t\t--posix\n"
-msgstr "\t-W posix\t\t--posix\n"
+msgstr "\t-P\t\t\t--posix\n"
-#: main.c:775
-#, fuzzy
+#: main.c:830
msgid "\t-r\t\t\t--re-interval\n"
-msgstr "\t-W re-interval\t\t--re-interval\n"
+msgstr "\t-r\t\t\t--re-interval\n"
-#: main.c:777
-#, fuzzy
-msgid "\t-R file\t\t\t--command=file\n"
-msgstr "\t-W profile[=fitxer]\t--profile[=fitxer]\n"
-
-#: main.c:778
+#: main.c:831
msgid "\t-S\t\t\t--sandbox\n"
-msgstr ""
+msgstr "\t-S\t\t\t--sandbox\n"
-#: main.c:779
-#, fuzzy
+#: main.c:832
msgid "\t-t\t\t\t--lint-old\n"
-msgstr "\t-W lint-old\t\t--lint-old\n"
+msgstr "\t-t\t\t\t--lint-old\n"
-#: main.c:780
-#, fuzzy
+#: main.c:833
msgid "\t-V\t\t\t--version\n"
-msgstr "\t-W version\t\t--version\n"
+msgstr "\t-V\t\t\t--version\n"
-#: main.c:782
+#: main.c:835
msgid "\t-W nostalgia\t\t--nostalgia\n"
msgstr "\t-W nostalgia\t\t--nostalgia\n"
-#: main.c:785
-#, fuzzy
+#: main.c:838
msgid "\t-Y\t\t--parsedebug\n"
-msgstr "\t-W parsedebug\t\t--parsedebug\n"
+msgstr "\t-Y\t\t--parsedebug\n"
#. TRANSLATORS: --help output 5 (end)
#. TRANSLATORS: the placeholder indicates the bug-reporting address
#. for this application. Please add _another line_ with the
#. address for translation bugs.
#. no-wrap
-#: main.c:794
-#, fuzzy
+#: main.c:847
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"
+msgstr ""
+"\n"
+"Per informar d'errors, vegeu el node `Bugs' a `gawk.info', que\n"
+"és la secció `Informant sobre problemes i errors' a la versió impresa.\n"
+"Informeu dels errors de traducció a <ca@li.org>\n"
-#: main.c:798
+#: main.c:851
msgid ""
"gawk is a pattern scanning and processing language.\n"
"By default it reads standard input and writes standard output.\n"
"\n"
msgstr ""
+"gawk és un llenguatge d'anàlisi i processament de patrons.\n"
+"De forma predeterminada llegeix l'entrada estàndard i escriu a la sortida "
+"estàndar.\n"
-#: main.c:802
+#: main.c:855
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 }' fitxer\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
-#: main.c:822
-#, fuzzy, c-format
+#: main.c:880
+#, c-format
msgid ""
"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
"\n"
@@ -1774,11 +3214,11 @@ msgstr ""
"\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"
+"publicada per la Free Software Foundation; ja siga en la versió 3 de la\n"
"Llicència, o (a la vostra elecció) qualsevol versió posterior.\n"
"\n"
-#: main.c:830
+#: main.c:888
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"
@@ -1792,145 +3232,204 @@ msgstr ""
"Per a més detalls consulteu la Llicència Pública General de GNU.\n"
"\n"
-#: main.c:841
-#, fuzzy
+#: main.c:894
msgid ""
"You should have received a copy of the GNU General Public License\n"
"along with this program. If not, see http://www.gnu.org/licenses/.\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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n"
+"Junt amb aquest programa hauríeu d'haver rebut una còpia de la Llicència\n"
+"Pública General de GNU; si no és així, vegeu http://www.gnu.org/licenses/.\n"
-#: main.c:876
+#: main.c:931
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:1110
+#: main.c:1208
#, c-format
msgid "unknown value for field spec: %d\n"
-msgstr ""
+msgstr "valor desconegut per a l'especificació de camp: %d\n"
-#: main.c:1170
+#: main.c:1306
#, c-format
msgid ""
"%s: `%s' argument to `-v' not in `var=value' form\n"
"\n"
msgstr ""
+"%s: `%s' l'argument per a `-v' no està en forma `var=valor'\n"
+"\n"
-#: main.c:1190
+#: main.c:1332
#, c-format
msgid "`%s' is not a legal variable name"
-msgstr ""
+msgstr "`%s' no és nom legal de variable"
-#: main.c:1193
+#: main.c:1335
#, c-format
msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr "`%s' no és un valor de variable, s'esperava fitxer `%s=%s'"
+
+#: main.c:1339
+#, c-format
+msgid "cannot use gawk builtin `%s' as variable name"
msgstr ""
+"no es pot usar el nom de la funció integrada `%s' com a nom de variable"
+
+#: main.c:1344
+#, c-format
+msgid "cannot use function `%s' as variable name"
+msgstr "no es pot usar el nom de la funció interna `%s' com nom de variable"
-#: main.c:1246
+#: main.c:1397
msgid "floating point exception"
msgstr "excepció de coma flotant"
-#: main.c:1253
+#: main.c:1404
msgid "fatal error: internal error"
msgstr "error fatal: error intern"
-#: main.c:1268
-#, fuzzy
+#: main.c:1419
msgid "fatal error: internal error: segfault"
-msgstr "error fatal: error intern"
+msgstr "error fatal: error intern: segfault"
-#: main.c:1280
-#, fuzzy
+#: main.c:1431
msgid "fatal error: internal error: stack overflow"
-msgstr "error fatal: error intern"
+msgstr "error fatal: error intern: sobreeiximent de pila"
-#: main.c:1330
+#: main.c:1490
#, c-format
msgid "no pre-opened fd %d"
msgstr "no s'ha pre-obert el descriptor fd per a %d"
-#: main.c:1337
+#: main.c:1497
#, 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:1360 main.c:1369
+#: mpfr.c:550
+#, c-format
+msgid "PREC value `%.*s' is invalid"
+msgstr "Valor PREC `%.*s' no és vàlid"
+
+#: mpfr.c:608
+#, c-format
+msgid "RNDMODE value `%.*s' is invalid"
+msgstr "Valor RNDMODE `%.*s' no és vàlid"
+
+#: mpfr.c:698
+#, c-format
+msgid "%s: received non-numeric argument"
+msgstr "%s: s'ha rebut un argument que no és numèric"
+
+#: mpfr.c:800
+msgid "compl(%Rg): negative value will give strange results"
+msgstr "compl(%Rg): el valor negatiu donarà resultats estranys"
+
+#: mpfr.c:804
+msgid "comp(%Rg): fractional value will be truncated"
+msgstr "compl(%Rg): el valor fraccionari serà truncat"
+
+#: mpfr.c:816
+#, c-format
+msgid "cmpl(%Zd): negative values will give strange results"
+msgstr "cmpl(%Zd): els valors negatius donaran resultats estranys"
+
+#: mpfr.c:835
+#, c-format
+msgid "%s: received non-numeric argument #%d"
+msgstr "%s: s'ha rebut un argument no numèric #%d"
+
+#: mpfr.c:845
+msgid "%s: argument #%d has invalid value %Rg, using 0"
+msgstr "%s: l'argument #%d té valor no vàlid %Rg, s'usarà 0"
+
+#: mpfr.c:857
+msgid "%s: argument #%d negative value %Rg will give strange results"
+msgstr "%s: l'argument #%d amb valor negatiu %Rg donarà resultats estranys"
+
+#: mpfr.c:863
+msgid "%s: argument #%d fractional value %Rg will be truncated"
+msgstr "%s: l'argument #%d amb valor fraccional %Rg serà truncat"
+
+#: mpfr.c:878
#, c-format
-msgid "could not find groups: %s"
-msgstr "no es poden trobar els grups: %s"
+msgid "%s: argument #%d negative value %Zd will give strange results"
+msgstr "%s: l'argument #%d amb valor negatiu %Zd donarà resultats estranys"
-#: msg.c:63
+#: msg.c:68
#, c-format
msgid "cmd. line:"
msgstr "línia cmd.:"
-#: msg.c:107
-msgid "error: "
-msgstr "Error: "
-
-#: node.c:401
+#: node.c:421
msgid "backslash at end of string"
msgstr "barra invertida al final de la cadena"
-#: node.c:502
-#, fuzzy, c-format
+#: node.c:500
+#, c-format
msgid "old awk does not support the `\\%c' escape sequence"
-msgstr "l'antic awk no suporta l'operador «**=»"
+msgstr "l'antic awk no dóna suport a la seqüencia d'escapada `\\%c'"
-#: node.c:553
+#: node.c:551
msgid "POSIX does not allow `\\x' escapes"
-msgstr "POSIX no permet seqüències d'escapada «\\x»"
+msgstr "POSIX no permet seqüències d'escapada `\\x'"
-#: node.c:559
+#: node.c:557
msgid "no hex digits in `\\x' escape sequence"
-msgstr "no hi ha dígits hexadecimals en la seqüència d'escapada «\\x»"
+msgstr "no hi ha dígits hexadecimals en la seqüència d'escapada `\\x'"
-#: node.c:581
+#: node.c:579
#, c-format
msgid ""
"hex escape \\x%.*s of %d characters probably not interpreted the way you "
"expect"
msgstr ""
+"probablement no s'han interpretat els caràcters hex escape \\x%.*s of %d de "
+"la manera que esperàveu"
-#: node.c:596
+#: node.c:594
#, c-format
msgid "escape sequence `\\%c' treated as plain `%c'"
-msgstr "la seqüència d'escapada «\\%c» és tractada com a una simple «%c»"
+msgstr "la seqüència d'escapada `\\%c' és tractada com a una simple `%c'"
-#: node.c:735
+#: node.c:739
msgid ""
"Invalid multibyte data detected. There may be a mismatch between your data "
"and your locale."
msgstr ""
+"S'han detectat dades multibyte no vàlides. Pot haver-hi una discordança "
+"entre les vostres dades i la vostra configuració local"
-#: posix/gawkmisc.c:175
-#, fuzzy, c-format
+#: posix/gawkmisc.c:177
+#, c-format
msgid "%s %s `%s': could not get fd flags: (fcntl F_GETFD: %s)"
-msgstr "%s %s «%s»: no es pot inicialitzar close-on-exec: (fcntl: %s)"
+msgstr ""
+"%s %s `%s': no s'han pogut obtenir els indicadors fd: (fcntl F_GETFD: %s)"
-#: posix/gawkmisc.c:187
-#, fuzzy, c-format
+#: posix/gawkmisc.c:189
+#, c-format
msgid "%s %s `%s': could not set close-on-exec: (fcntl F_SETFD: %s)"
-msgstr "%s %s «%s»: no es pot inicialitzar close-on-exec: (fcntl: %s)"
+msgstr "%s %s `%s': no s'ha pogut establir close-on-exec: (fcntl F_SETFD: %s)"
-#: profile.c:83
+#: profile.c:71
#, c-format
msgid "could not open `%s' for writing: %s"
-msgstr "no es pot obrir «%s» per a escriptura: %s"
+msgstr "no es pot obrir `%s' per a escriptura: %s"
-#: profile.c:203
-#, fuzzy, c-format
+#: profile.c:73
+msgid "sending profile to standard error"
+msgstr "enviant el perfil a l'eixida d'error estàndard"
+
+#: profile.c:193
+#, c-format
msgid ""
"\t# %s block(s)\n"
"\n"
msgstr ""
-"\t# Bloc(s) FINAL\n"
+"\t# %s bloc(s)\n"
"\n"
-#: profile.c:208
-#, fuzzy, c-format
+#: profile.c:198
+#, c-format
msgid ""
"\t# Rule(s)\n"
"\n"
@@ -1938,17 +3437,30 @@ msgstr ""
"\t# Regla(es)\n"
"\n"
-#: profile.c:279
-#, fuzzy, c-format
+#: profile.c:272
+#, c-format
msgid "internal error: %s with null vname"
-msgstr "error intern: Node_var amb vname nul"
+msgstr "error intern: %s amb vname nul"
+
+#: profile.c:537
+msgid "internal error: builtin with null fname"
+msgstr "error intern: funció integrada amb fname nul"
-#: profile.c:938
+#: profile.c:949
+#, c-format
+msgid ""
+"\t# Loaded extensions (-l and/or @load)\n"
+"\n"
+msgstr ""
+"\t# Extensions carregades (-l i/o @load)\n"
+"\n"
+
+#: profile.c:972
#, c-format
msgid "\t# gawk profile, created %s\n"
msgstr "\t# perfil gawk, creat %s\n"
-#: profile.c:1317
+#: profile.c:1475
#, c-format
msgid ""
"\n"
@@ -1957,152 +3469,137 @@ msgstr ""
"\n"
"\t# Funcions, llistades alfabèticament\n"
-#: profile.c:1356
+#: profile.c:1513
#, c-format
msgid "redir2str: unknown redirection type %d"
-msgstr ""
+msgstr "redir2str: tipus desconegut de redireccionament %d"
-#: re.c:589
-#, c-format
-msgid "range of the form `[%c-%c]' is locale dependant"
-msgstr ""
-
-#: re.c:611
+#: re.c:607
#, c-format
msgid "regexp component `%.*s' should probably be `[%.*s]'"
-msgstr ""
+msgstr "el component regexp `%.*s' probablement hauria de ser `[%.*s]'"
-#: regcomp.c:132
+#: regcomp.c:131
msgid "Success"
msgstr "Èxit"
-#: regcomp.c:135
+#: regcomp.c:134
msgid "No match"
msgstr "No hi ha concordança"
-#: regcomp.c:138
+#: regcomp.c:137
msgid "Invalid regular expression"
msgstr "Expressió regular no vàlida"
-#: regcomp.c:141
+#: regcomp.c:140
msgid "Invalid collation character"
msgstr "Caràcter de comparació no vàlid"
-#: regcomp.c:144
+#: regcomp.c:143
msgid "Invalid character class name"
msgstr "Nom de classe de caràcters no vàlid"
-#: regcomp.c:147
+#: regcomp.c:146
msgid "Trailing backslash"
msgstr "Barra invertida extra al final"
-#: regcomp.c:150
+#: regcomp.c:149
msgid "Invalid back reference"
-msgstr "Referència cap enradera no vàlida"
+msgstr "Referència cap endarrere no vàlida"
-#: regcomp.c:153
+#: regcomp.c:152
msgid "Unmatched [ or [^"
msgstr "[ o [^ desemparellats"
-#: regcomp.c:156
+#: regcomp.c:155
msgid "Unmatched ( or \\("
msgstr "( o \\( desemparellats"
-#: regcomp.c:159
+#: regcomp.c:158
msgid "Unmatched \\{"
msgstr "\\{ desemparellat"
-#: regcomp.c:162
-msgid "Invalid content of \\{\\}"
-msgstr "Contingut no vàlid de \\{\\}"
-
-#: regcomp.c:165
+#: regcomp.c:164
msgid "Invalid range end"
msgstr "Final de rang no vàlid"
-#: regcomp.c:168
+#: regcomp.c:167
msgid "Memory exhausted"
msgstr "Memòria exhaurida"
-#: regcomp.c:171
+#: regcomp.c:170
msgid "Invalid preceding regular expression"
msgstr "Expressió regular precedent no vàlida"
-#: regcomp.c:174
+#: regcomp.c:173
msgid "Premature end of regular expression"
msgstr "Fí prematura de l'expressió regular"
-#: regcomp.c:177
-msgid "Regular expression too big"
-msgstr "L'expressió regular és massa gran"
-
-#: regcomp.c:180
+#: regcomp.c:179
msgid "Unmatched ) or \\)"
msgstr ") o \\) desemparellats"
-#: regcomp.c:701
+#: regcomp.c:704
msgid "No previous regular expression"
msgstr "No hi ha una expressió regular prèvia"
-#~ msgid "statement may have no effect"
-#~ msgstr "la declaració podria no tindre efecte"
+#: symbol.c:741
+msgid "can not pop main context"
+msgstr "no es pot mostrar el context principal"
-#~ msgid "attempt to use scalar `%s' as array"
-#~ msgstr "s'ha intentat usar la dada escalar «%s» com a una matriu"
+#~ msgid "reference to uninitialized element `%s[\"%s\"]'"
+#~ msgstr "referència a un element sense valor inicial `%s[\"%s\"]'"
-#, fuzzy
-#~ msgid "attempt to use array `%s' in scalar context"
-#~ msgstr "s'ha intentat usar la matriu «%s» en un context escalar"
+#~ msgid "subscript of array `%s' is null string"
+#~ msgstr "el subscript de la matriu `%s' és una cadena nul·la"
-#~ msgid "`continue' outside a loop is not allowed"
-#~ msgstr "no es permet «continue» a fora d'un bucle"
+#~ msgid "delete: illegal use of variable `%s' as array"
+#~ msgstr "delete: ús il·legal de la variable `%s' com a una matriu"
-#, fuzzy
-#~ msgid "`break' outside a loop is not allowed"
-#~ msgstr "no es permet «break» a fora d'un bucle"
+#~ msgid "%s: empty (null)\n"
+#~ msgstr "%s: buit (nul)\n"
-#~ msgid "/inet/raw client not ready yet, sorry"
-#~ msgstr "el client /inet/raw encara no està a punt, ho sento"
+#~ msgid "%s: empty (zero)\n"
+#~ msgstr "%s: buit (zero)\n"
-#~ msgid "only root may use `/inet/raw'."
-#~ msgstr "sols el root pot usar «/inet/raw»."
+#~ msgid "%s: table_size = %d, array_size = %d\n"
+#~ msgstr "%s: mida_taula = %d, mida_matriu = %d\n"
-#~ msgid "/inet/raw server not ready yet, sorry"
-#~ msgstr "el servidor /inet/raw encara no està a punt, ho sento"
+#~ msgid "%s: array_ref to %s\n"
+#~ msgstr "%s: ref_matriu a %s\n"
-#~ msgid "\t-m[fr] val\n"
-#~ msgstr "\t-m[fr] valor\n"
+#~ msgid "and: received non-numeric first argument"
+#~ msgstr "and: el primer argument rebut no és numèric"
-#~ msgid "call of `length' without parentheses is deprecated by POSIX"
-#~ msgstr "la crida de «length» sense parèntesis està desaprovada per POSIX"
+#~ msgid "or: received non-numeric first argument"
+#~ msgstr "or: el primer argument rebut no és numèric"
-#, fuzzy
-#~ msgid "reference to uninitialized field `$%s'"
-#~ msgstr "referència a una variable sense inicialitzar «%s»"
+#~ msgid "or(%lf, %lf): negative values will give strange results"
+#~ msgstr "or(%lf, %lf): els valors negatius donaran resultats estranys"
-#~ msgid "can't convert string to float"
-#~ msgstr "no es pot convertir la cadena a coma flotant"
+#~ msgid "or(%lf, %lf): fractional values will be truncated"
+#~ msgstr "or(%lf, %lf): els valors fraccionaris seran truncats"
-#~ msgid "`continue' outside a loop is not portable"
-#~ msgstr "«continue» fora d'un bucle no és portable"
+#~ msgid "xor: received non-numeric first argument"
+#~ msgstr "xor: el primer argument rebut no és numèric"
-#~ msgid "`break' outside a loop is not portable"
-#~ msgstr "«break» a fora d'un bucle no és portable"
+#~ msgid "xor(%lf, %lf): fractional values will be truncated"
+#~ msgstr "xor(%lf, %lf): els valors fraccionaris seran truncats"
-#~ msgid "`nextfile' cannot be called from a BEGIN rule"
-#~ msgstr "«nextfile» no es pot cridar des d'una regla BEGIN"
+#~ msgid "Operation Not Supported"
+#~ msgstr "Operació No Suportada"
-#~ msgid "`next' cannot be called from a BEGIN rule"
-#~ msgstr "«next» no es pot cridar des d'una regla BEGIN"
+#~ msgid "%s: illegal option -- %c\n"
+#~ msgstr "%s: opció il·legal -- %c\n"
-#~ msgid "file `%s' is a directory"
-#~ msgstr "el fitxer «%s» és un directori"
+#~ msgid "`-m[fr]' option irrelevant in gawk"
+#~ msgstr "l'opción `-m[fr]' és irrellevant en gawk"
-#~ msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
-#~ msgstr "useu «PROCINFO[\"%s\"]» en comptes de «%s»"
+#~ msgid "-m option usage: `-m[fr] nnn'"
+#~ msgstr "ús de l'opció -m: `-m[fr] nnn'"
-#~ msgid "use `PROCINFO[...]' instead of `/dev/user'"
-#~ msgstr "useu «PROCINFO[...]» en comptes de «/dev/user»"
+#~ msgid "\t-m[fr] val\n"
+#~ msgstr "\t-m[fr] valor\n"
#~ msgid "\t-W compat\t\t--compat\n"
#~ msgstr "\t-W compat\t\t--compat\n"
@@ -2114,159 +3611,152 @@ msgstr "No hi ha una expressió regular prèvia"
#~ msgstr "\t-W usage\t\t--usage\n"
#~ msgid ""
-#~ "\t# BEGIN block(s)\n"
#~ "\n"
+#~ "To report bugs, see node `Bugs' in `gawk.info', which is\n"
#~ msgstr ""
-#~ "\t# Bloc(s) INICI\n"
#~ "\n"
+#~ "Per a informar d'errors, consulteu el node «Bugs' en «gawk.info', que "
+#~ "està\n"
-#~ msgid "`$' is not permitted in awk formats"
-#~ msgstr "no es permeten «$» en els formats awk"
-
-#~ msgid "arg count with `$' must be > 0"
-#~ msgstr "el compte d'arguments amb «$» ha de ser > 0"
-
-#, fuzzy
-#~ 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"
-
-#~ msgid "`$' not permitted after period in format"
-#~ msgstr "no es permet «$» després d'un punt en el format"
-
-#~ msgid "no `$' supplied for positional field width or precision"
-#~ msgstr "no es proporciona «$» per a l'ample o precisió del camp de posició"
-
-#~ msgid "`l' is meaningless in awk formats; ignored"
-#~ msgstr "«l» manca de significat en els formats awk; serà ignorat"
-
-#~ msgid "`l' is not permitted in POSIX awk formats"
-#~ msgstr "«l» no està permés en els formats POSIX de awk"
-
-#~ msgid "`L' is meaningless in awk formats; ignored"
-#~ msgstr "«L» manca de significat en els formats awk; serà ignorat"
-
-#~ msgid "`L' is not permitted in POSIX awk formats"
-#~ msgstr "«L» no està permés en els formats POSIX de awk"
-
-#~ msgid "`h' is meaningless in awk formats; ignored"
-#~ msgstr "«h» manca de significat en els formats awk; serà ignorat"
-
-#~ msgid "`h' is not permitted in POSIX awk formats"
-#~ msgstr "«h» no està permés en els formats POSIX de awk"
-
-#~ msgid "not enough arguments to satisfy format string"
-#~ msgstr "no hi ha prou arguments per a satisfer el format d'una cadena"
-
-#~ msgid "^ ran out for this one"
-#~ msgstr "^ desbordament per a aquest"
-
-#~ msgid "[s]printf: format specifier does not have control letter"
-#~ msgstr "[s]printf: l'especificador de format no conté lletra de control"
-
-#~ msgid "too many arguments supplied for format string"
-#~ msgstr "s'han proporcionat masses arguments per a la cadena de format"
-
-#, fuzzy
-#~ msgid "attempt to use array parameter `%s' in a scalar context"
-#~ msgstr "s'ha intentat usar la matriu «%s» en un context escalar"
+#~ 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 "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)"
+#~ msgid "could not find groups: %s"
+#~ msgstr "no es poden trobar els grups: %s"
-#~ msgid "%s: illegal option -- %c\n"
-#~ msgstr "%s: opció il·legal -- %c\n"
+#~ msgid "internal error: Node_var_array with null vname"
+#~ msgstr "error intern: Node_var_array amb vname nul"
-#~ 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!"
+#~ msgid "or used in other expression context"
+#~ msgstr "o s'ha emprat en un altre context de l'expressió"
#~ msgid "illegal type (%s) in tree_eval"
#~ msgstr "tipus il·legal (%s) en tree_eval"
-#~ msgid "\t# -- main --\n"
-#~ msgstr "\t# -- principal --\n"
+#~ msgid "attempt to use function `%s' as array"
+#~ msgstr "s'ha intentat usar la funció «%s» com a una matriu"
-#~ msgid "invalid tree type %s in redirect()"
-#~ msgstr "tipus d'arbre %s no vàlid dintre de redirect()"
-
-#~ msgid "unexpected type %s in prec_level"
-#~ msgstr "tipus %s inesperat en prec_level"
-
-#, fuzzy
-#~ msgid "Unknown node type %s in pp_var"
-#~ msgstr "tipo de node %d desconegut"
+#~ msgid "`%s' is a function, assignment is not allowed"
+#~ msgstr "«%s» és una funció, l'assignació no és permesa"
-#~ msgid "delete: illegal use of variable `%s' as array"
-#~ msgstr "delete: ús il·legal de la variable «%s» com a una matriu"
+#~ 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"
#~ msgid ""
+#~ "\t# BEGIN block(s)\n"
#~ "\n"
-#~ "To report bugs, see node `Bugs' in `gawk.info', which is\n"
#~ msgstr ""
+#~ "\t# Bloc(s) INICI\n"
#~ "\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 "internal error: Node_var_array with null vname"
-#~ msgstr "error intern: Node_var_array amb vname nul"
-
-#~ 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 "unexpected type %s in prec_level"
+#~ msgstr "tipus %s inesperat en prec_level"
#~ 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 "statement may have no effect"
+#~ msgstr "la declaració podria no tindre efecte"
#~ msgid "non-redirected `getline' undefined inside BEGIN or END action"
#~ msgstr "«getline» no redirigit sense definir dintre de l'acció BEGIN o END"
+#~ msgid "call of `length' without parentheses is deprecated by POSIX"
+#~ msgstr "la crida de «length» sense parèntesis està desaprovada per POSIX"
+
#~ msgid "fptr %x not in tokentab\n"
#~ msgstr "fptr %x no està en la taula de referència\n"
+#~ msgid "`%s' is a Bell Labs extension"
+#~ msgstr "«%s» és una extensió de Bell Labs"
+
#~ 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 "out of memory"
+#~ msgstr "memòria esgotada"
-#~ msgid "Unbalanced ("
-#~ msgstr "( sense aparellar"
+#~ msgid "field %d in FIELDWIDTHS, must be > 0"
+#~ msgstr "el camp %d en FIELDWIDTHS, hauria de ser > 0"
-#~ msgid "No regexp syntax bits specified"
-#~ msgstr "No s'especifiquen els bits de sintaxi de l'expressió regular"
+#~ msgid ""
+#~ "for loop: array `%s' changed size from %d to %d during loop execution"
+#~ msgstr ""
+#~ "bucle for: la matriu «%s» ha canviat de mida de %d a %d durant l'execució "
+#~ "del bucle"
-#~ msgid "Unbalanced )"
-#~ msgstr ") sense aparellar"
+#~ msgid "`break' outside a loop is not portable"
+#~ msgstr "«break» a fora d'un bucle no és portable"
-#~ msgid "field %d in FIELDWIDTHS, must be > 0"
-#~ msgstr "el camp %d en FIELDWIDTHS, hauria de ser > 0"
+#~ msgid "`continue' outside a loop is not portable"
+#~ msgstr "«continue» fora d'un bucle no és portable"
+
+#~ msgid "`next' cannot be called from a BEGIN rule"
+#~ msgstr "«next» no es pot cridar des d'una regla BEGIN"
+
+#~ msgid "`next' cannot be called from an END rule"
+#~ msgstr "«next» no es pot cridar des d'una regla FINAL"
+
+#~ msgid "`nextfile' cannot be called from a BEGIN rule"
+#~ msgstr "«nextfile» no es pot cridar des d'una regla BEGIN"
+
+#~ msgid "`nextfile' cannot be called from an END rule"
+#~ msgstr "«nextfile» no es pot cridar des d'una regla FINAL"
+
+#~ msgid "statement has no effect"
+#~ msgstr "la sentència no té efecte"
+
+#~ msgid "assignment used in conditional context"
+#~ msgstr "assignació usada en un context condicional"
+
+#~ 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!"
#~ msgid "function %s called\n"
#~ msgstr "s'ha cridat a la funció %s\n"
-#~ msgid "internal error: file `%s', line %d\n"
-#~ msgstr "error intern: fitxer «%s», línia %d\n"
+#~ msgid "\t# -- main --\n"
+#~ msgstr "\t# -- principal --\n"
+
+#~ msgid "invalid tree type %s in redirect()"
+#~ msgstr "tipus d'arbre %s no vàlid dintre de redirect()"
+
+#~ 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)"
+
+#~ msgid "/inet/raw client not ready yet, sorry"
+#~ msgstr "el client /inet/raw encara no està a punt, ho sento"
+
+#~ msgid "only root may use `/inet/raw'."
+#~ msgstr "sols el root pot usar «/inet/raw»."
+
+#~ msgid "/inet/raw server not ready yet, sorry"
+#~ msgstr "el servidor /inet/raw encara no està a punt, ho sento"
+
+#~ msgid "file `%s' is a directory"
+#~ msgstr "el fitxer «%s» és un directori"
+
+#~ msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+#~ msgstr "useu «PROCINFO[\"%s\"]» en comptes de «%s»"
+
+#~ msgid "use `PROCINFO[...]' instead of `/dev/user'"
+#~ msgstr "useu «PROCINFO[...]» en comptes de «/dev/user»"
+
+#~ msgid "error reading input file `%s': %s"
+#~ msgstr "error en llegir el fitxer d'entrada «%s»: %s"
+
+#~ msgid "can't convert string to float"
+#~ msgstr "no es pot convertir la cadena a coma flotant"
diff --git a/po/da.gmo b/po/da.gmo
index 6685bdb7..0ba7ffc0 100644
--- a/po/da.gmo
+++ b/po/da.gmo
Binary files differ
diff --git a/po/da.po b/po/da.po
index 33c60c39..f3840840 100644
--- a/po/da.po
+++ b/po/da.po
@@ -1,529 +1,512 @@
# Danish translation of gawk
# Copyright (C) 2001 Free Software Foundation, Inc.
# This file is distributed under the same license as the gawk package.
-# Martin Sjögren <md9ms@mdstud.chalmers.se>, 2001-2002.
+# Martin Sjögren <md9ms@mdstud.chalmers.se>, 2001-2002.
# Christer Andersson <klamm@comhem.se>, 2007.
-# Keld Simonsen <keld@keldix.com>, 2002,2011.
-# Review by Torben Grøn Helligsø <torben-dansk@thel.dk>, 2011.
+# Keld Simonsen <keld@keldix.com>, 2002,2011,2012.
+# Review by Torben Grøn Helligsø <torben-dansk@thel.dk>, 2011.
# Review by Ask Hjorth Larsen <asklarsen@gmail.com>, 2011.
msgid ""
msgstr ""
-"Project-Id-Version: gawk 3.1.83\n"
+"Project-Id-Version: gawk 4.0.0h\n"
"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
-"POT-Creation-Date: 2011-10-24 05:57+0200\n"
-"PO-Revision-Date: 2011-05-22 10:37+0200\n"
+"POT-Creation-Date: 2014-04-08 19:23+0300\n"
+"PO-Revision-Date: 2012-02-06 10:37+0100\n"
"Last-Translator: Keld Simonsen <keld@keldix.com>\n"
"Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
"Language: da\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Lokalize 1.0\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: array.c:140
+#: array.c:256
#, c-format
msgid "from %s"
msgstr "fra %s"
-#: array.c:248
+#: array.c:357
msgid "attempt to use a scalar value as array"
-msgstr "forsøg på at bruge en skalar som array"
+msgstr "forsøg på at bruge en skalar som array"
-#: array.c:251
-#, c-format
-msgid "attempt to use function `%s' as an array"
-msgstr "forsøg på at bruge funktionen '%s' som et array"
-
-#: array.c:254
+#: array.c:359
#, c-format
msgid "attempt to use scalar parameter `%s' as an array"
-msgstr "forsøg på at bruge skalarparameteren '%s' som et array"
+msgstr "forsøg på at bruge skalarparameteren '%s' som et array"
-#: array.c:257
+#: array.c:362
#, c-format
msgid "attempt to use scalar `%s' as an array"
-msgstr "forsøg på at bruge skalar '%s' som et array"
+msgstr "forsøg på at bruge skalar '%s' som et array"
-#: array.c:302 array.c:707 builtin.c:84 builtin.c:1384 builtin.c:1426
-#: builtin.c:1439 builtin.c:1856 builtin.c:1868 eval.c:1135 eval.c:1139
-#: eval.c:1495 eval.c:1812
+#: array.c:409 array.c:576 builtin.c:85 builtin.c:1615 builtin.c:1661
+#: builtin.c:1674 builtin.c:2102 builtin.c:2116 eval.c:1122 eval.c:1126
+#: eval.c:1531
#, c-format
msgid "attempt to use array `%s' in a scalar context"
-msgstr "forsøg på at bruge array '%s' i skalarsammenhæng"
-
-#: array.c:513
-#, c-format
-msgid "reference to uninitialized element `%s[\"%.*s\"]'"
-msgstr "reference til ikke-initieret element '%s[\"%.*s\"]'"
+msgstr "forsøg på at bruge array '%s' i skalarsammenhæng"
-#: array.c:519
-#, c-format
-msgid "subscript of array `%s' is null string"
-msgstr "indeks i array '%s' er en tom streng"
-
-#: array.c:723
+#: array.c:583
#, c-format
msgid "delete: index `%s' not in array `%s'"
msgstr "delete: indeks '%s' findes ikke i array '%s'"
-#: array.c:734 eval.c:1865
+#: array.c:597
#, c-format
msgid "attempt to use scalar `%s[\"%.*s\"]' as an array"
-msgstr "forsøg på at bruge skalaren '%s[\"%.*s\"]' som array"
-
-#: array.c:910
-#, c-format
-msgid "%s: empty (null)\n"
-msgstr "%s: tom (null)\n"
-
-#: array.c:915
-#, c-format
-msgid "%s: empty (zero)\n"
-msgstr "%s: tom (nul)\n"
-
-#: array.c:919
-#, c-format
-msgid "%s: table_size = %d, array_size = %d\n"
-msgstr "%s: tabelstørrelse = %d, arraystørrelse = %d\n"
-
-#: array.c:954
-#, c-format
-msgid "%s: is parameter\n"
-msgstr "%s: er parameter\n"
+msgstr "forsøg på at bruge skalaren '%s[\"%.*s\"]' som array"
-#: array.c:958
-#, c-format
-msgid "%s: array_ref to %s\n"
-msgstr "%s: arrayreference til %s\n"
-
-#: array.c:963
-msgid "adump: argument not an array"
+#: array.c:776
+#, fuzzy
+msgid "adump: first argument not an array"
msgstr "adump: argument er ikke et array"
-#: array.c:1086
+#: array.c:815
msgid "asort: second argument not an array"
msgstr "asort: andet argument er ikke et array"
-#: array.c:1087
+#: array.c:816
msgid "asorti: second argument not an array"
msgstr "asorti: andet argument er ikke et array"
-#: array.c:1094
+#: array.c:823
msgid "asort: first argument not an array"
-msgstr "asort: første argument er ikke et array"
+msgstr "asort: første argument er ikke et array"
-#: array.c:1095
+#: array.c:824
msgid "asorti: first argument not an array"
-msgstr "asorti: første argument er ikke et array"
+msgstr "asorti: første argument er ikke et array"
-#: array.c:1102
+#: array.c:831
msgid "asort: cannot use a subarray of first arg for second arg"
msgstr ""
-"asort: kan ikke bruge et underarray af første argument for andet argument"
+"asort: kan ikke bruge et underarray af første argument for andet argument"
-#: array.c:1103
+#: array.c:832
msgid "asorti: cannot use a subarray of first arg for second arg"
msgstr ""
-"asorti: kan ikke bruge et underarray af første argument for andet argument"
+"asorti: kan ikke bruge et underarray af første argument for andet argument"
-#: array.c:1108
+#: array.c:837
msgid "asort: cannot use a subarray of second arg for first arg"
msgstr ""
-"asort: kan ikke bruge et underarray af andet argument for første argument"
+"asort: kan ikke bruge et underarray af andet argument for første argument"
-#: array.c:1109
+#: array.c:838
msgid "asorti: cannot use a subarray of second arg for first arg"
msgstr ""
-"asorti: kan ikke bruge et underarray af andet argument for første argument"
+"asorti: kan ikke bruge et underarray af andet argument for første argument"
-#: array.c:1659
+#: array.c:1314
#, c-format
msgid "`%s' is invalid as a function name"
msgstr "'%s' er ugyldigt som funktionsnavn"
-#: array.c:1663
+#: array.c:1318
#, c-format
msgid "sort comparison function `%s' is not defined"
msgstr "funktionen for sorteringssammenligning '%s' er ikke defineret"
-#: awkgram.y:249
+#: awkgram.y:233
#, c-format
msgid "%s blocks must have an action part"
msgstr "%s-blokke skal have en handlingsdel"
-#: awkgram.y:252
+#: awkgram.y:236
msgid "each rule must have a pattern or an action part"
-msgstr "hver regel skal have et mønster eller en handlingsdel"
+msgstr "hver regel skal have et mønster eller en handlingsdel"
-#: awkgram.y:323 awkgram.y:334
+#: awkgram.y:325 awkgram.y:336
msgid "old awk does not support multiple `BEGIN' or `END' rules"
msgstr ""
-"gamle versioner af awk understøtter ikke flere 'BEGIN'- eller 'END'-regler"
+"gamle versioner af awk understøtter ikke flere 'BEGIN'- eller 'END'-regler"
-#: awkgram.y:371
+#: awkgram.y:373
#, 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:432
+#: awkgram.y:419
msgid "regexp constant `//' looks like a C++ comment, but is not"
msgstr "regexp-konstanten '//' ser ud som en C++-kommentar, men er det ikke"
-#: awkgram.y:436
+#: awkgram.y:423
#, 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:528
+#: awkgram.y:515
#, c-format
msgid "duplicate case values in switch body: %s"
-msgstr "dublet case-værdier i switch-krop %s"
+msgstr "dublet case-værdier i switch-krop %s"
-#: awkgram.y:549
+#: awkgram.y:536
msgid "duplicate `default' detected in switch body"
msgstr "dublet 'default' opdaget i switch-krop"
-#: awkgram.y:809
+#: awkgram.y:796 awkgram.y:3723
msgid "`break' is not allowed outside a loop or switch"
-msgstr "'break' uden for en løkke eller switch er ikke tilladt"
+msgstr "'break' uden for en løkke eller switch er ikke tilladt"
-#: awkgram.y:818
+#: awkgram.y:805 awkgram.y:3715
msgid "`continue' is not allowed outside a loop"
-msgstr "'continue' uden for en løkke er ikke tilladt"
+msgstr "'continue' uden for en løkke er ikke tilladt"
-#: awkgram.y:828
+#: awkgram.y:815
#, c-format
msgid "`next' used in %s action"
msgstr "'next' brugt i %s-handling"
-#: awkgram.y:836
-msgid "`nextfile' is a gawk extension"
-msgstr "'nextfile' er en gawk-udvidelse"
-
-#: awkgram.y:841
+#: awkgram.y:824
#, c-format
msgid "`nextfile' used in %s action"
msgstr "'nextfile' brugt i %s-handling"
-#: awkgram.y:865
+#: awkgram.y:848
msgid "`return' used outside function context"
msgstr "'return' brugt uden for funktion"
-#: awkgram.y:925
+#: awkgram.y:922
msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
msgstr ""
-"alenestående 'print' i BEGIN eller END-regel skulle muligvis være 'print "
+"alenestående 'print' i BEGIN eller END-regel skulle muligvis være 'print "
"\"\"'"
-#: awkgram.y:995 awkgram.y:999 awkgram.y:1023
-msgid "`delete array' is a gawk extension"
-msgstr "'delete array' er en gawk-udvidelse"
+#: awkgram.y:988 awkgram.y:1037
+msgid "`delete' is not allowed with SYMTAB"
+msgstr ""
+
+#: awkgram.y:990 awkgram.y:1039
+msgid "`delete' is not allowed with FUNCTAB"
+msgstr ""
-#: awkgram.y:1019
+#: awkgram.y:1024 awkgram.y:1028
msgid "`delete(array)' is a non-portable tawk extension"
msgstr "'delete array' er en ikke-portabel udvidelse fra tawk"
-#: awkgram.y:1135
+#: awkgram.y:1149
msgid "multistage two-way pipelines don't work"
msgstr "flertrins dobbeltrettede datakanaler fungerer ikke"
-#: awkgram.y:1238
+#: awkgram.y:1264
msgid "regular expression on right of assignment"
-msgstr "regulært udtryk i højreleddet af en tildeling"
+msgstr "regulært udtryk i højreleddet af en tildeling"
-#: awkgram.y:1249
+#: awkgram.y:1275
msgid "regular expression on left of `~' or `!~' operator"
-msgstr "regulært udtryk på venstre side af en '~'- eller '!~'-operator"
+msgstr "regulært udtryk på venstre side af en '~'- eller '!~'-operator"
-#: awkgram.y:1265 awkgram.y:1419
+#: awkgram.y:1291 awkgram.y:1442
msgid "old awk does not support the keyword `in' except after `for'"
msgstr ""
-"gamle versioner af awk understøtter ikke nøgleordet 'in' undtagen efter 'for'"
+"gamle versioner af awk understøtter ikke nøgleordet 'in' undtagen efter 'for'"
-#: awkgram.y:1275
+#: awkgram.y:1301
msgid "regular expression on right of comparison"
-msgstr "regulært udtryk i højreleddet af en sammenligning"
+msgstr "regulært udtryk i højreleddet af en sammenligning"
-#: awkgram.y:1394
+#: awkgram.y:1417
#, c-format
msgid "`getline var' invalid inside `%s' rule"
msgstr "'getline var' ugyldig inden i '%s' regel"
-#: awkgram.y:1397 eval.c:2504
+#: awkgram.y:1420
#, c-format
msgid "`getline' invalid inside `%s' rule"
msgstr "'getline' ugyldig inden i '%s' regel"
-#: awkgram.y:1402
+#: awkgram.y:1425
msgid "non-redirected `getline' undefined inside END action"
msgstr "ikke-omdirigeret 'getline' udefineret inden i END-handling"
-#: awkgram.y:1421
+#: awkgram.y:1444
msgid "old awk does not support multidimensional arrays"
-msgstr "gamle versioner af awk understøtter ikke flerdimensionale array"
+msgstr "gamle versioner af awk understøtter ikke flerdimensionale array"
-#: awkgram.y:1517
+#: awkgram.y:1541
msgid "call of `length' without parentheses is not portable"
msgstr "kald af 'length' uden parenteser er ikke portabelt"
-#: awkgram.y:1580
+#: awkgram.y:1607
msgid "indirect function calls are a gawk extension"
msgstr "indirekte funktionskald er en gawk-udvidelse"
-#: awkgram.y:1593
+#: awkgram.y:1620
#, c-format
msgid "can not use special variable `%s' for indirect function call"
msgstr "kan ikke bruge specialvariabel '%s' til indirekte funktionskald"
-#: awkgram.y:1671
+#: awkgram.y:1698
msgid "invalid subscript expression"
msgstr "ugyldigt indeksudtryk"
-#: awkgram.y:1711
-msgid "use of non-array as array"
-msgstr "brug af ikke-array som array"
-
-#: awkgram.y:1975 awkgram.y:1995 msg.c:98
+#: awkgram.y:2048 awkgram.y:2068 gawkapi.c:206 gawkapi.c:224 msg.c:126
msgid "warning: "
msgstr "advarsel: "
-#: awkgram.y:1993 msg.c:130
+#: awkgram.y:2066 gawkapi.c:192 gawkapi.c:221 msg.c:158
msgid "fatal: "
msgstr "fatal: "
-#: awkgram.y:2043
+#: awkgram.y:2116
msgid "unexpected newline or end of string"
msgstr "uventet nylinjetegn eller strengafslutning"
-#: awkgram.y:2300 awkgram.y:2358 awkgram.y:2542
+#: awkgram.y:2383 awkgram.y:2459 awkgram.y:2682 debug.c:523 debug.c:539
+#: debug.c:2812 debug.c:5055
#, c-format
msgid "can't open source file `%s' for reading (%s)"
-msgstr "kan ikke åbne kildefilen '%s' for læsning (%s)"
+msgstr "kan ikke åbne kildefilen '%s' for læsning (%s)"
+
+#: awkgram.y:2384 awkgram.y:2509
+#, fuzzy, c-format
+msgid "can't open shared library `%s' for reading (%s)"
+msgstr "kan ikke åbne kildefilen '%s' for læsning (%s)"
-#: awkgram.y:2301 awkgram.y:2359 builtin.c:122
+#: awkgram.y:2386 awkgram.y:2460 awkgram.y:2510 builtin.c:135 debug.c:5206
msgid "reason unknown"
-msgstr "ukendt årsag"
+msgstr "ukendt årsag"
-#: awkgram.y:2317
+#: awkgram.y:2395 awkgram.y:2419
+#, c-format
+msgid "can't include `%s' and use it as a program file"
+msgstr ""
+
+#: awkgram.y:2408
#, c-format
msgid "already included source file `%s'"
msgstr "allerede inkluderet kildefil '%s'"
-#: awkgram.y:2343
+#: awkgram.y:2409
+#, fuzzy, c-format
+msgid "already loaded shared library `%s'"
+msgstr "allerede inkluderet kildefil '%s'"
+
+#: awkgram.y:2444
msgid "@include is a gawk extension"
msgstr "@include er en gawk-udvidelse"
-#: awkgram.y:2349
+#: awkgram.y:2450
msgid "empty filename after @include"
msgstr "tomt filnavn efter @include"
#: awkgram.y:2494
+#, fuzzy
+msgid "@load is a gawk extension"
+msgstr "@include er en gawk-udvidelse"
+
+#: awkgram.y:2500
+#, fuzzy
+msgid "empty filename after @load"
+msgstr "tomt filnavn efter @include"
+
+#: awkgram.y:2634
msgid "empty program text on command line"
-msgstr "tom programtekst på kommandolinjen"
+msgstr "tom programtekst på kommandolinjen"
-#: awkgram.y:2609
+#: awkgram.y:2749
#, c-format
msgid "can't read sourcefile `%s' (%s)"
-msgstr "kan ikke læse kildefilen '%s' (%s)"
+msgstr "kan ikke læse kildefilen '%s' (%s)"
-#: awkgram.y:2620
+#: awkgram.y:2760
#, c-format
msgid "source file `%s' is empty"
msgstr "kildefilen '%s' er tom"
-#: awkgram.y:2805
+#: awkgram.y:2937
msgid "source file does not end in newline"
msgstr "kildefilen slutter ikke med en ny linje"
-#: awkgram.y:2882
+#: awkgram.y:3042
msgid "unterminated regexp ends with `\\' at end of file"
-msgstr "uafsluttet regulært udtryk slutter med '\\' i slutningen af filen"
+msgstr "uafsluttet regulært udtryk slutter med '\\' i slutningen af filen"
-#: awkgram.y:2906
+#: awkgram.y:3066
#, c-format
msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
-msgstr "%s: %d: regex-ændringstegn '/.../%c' fra tawk virker ikke i gawk"
+msgstr "%s: %d: regex-ændringstegn '/.../%c' fra tawk virker ikke i gawk"
-#: awkgram.y:2910
+#: awkgram.y:3070
#, c-format
msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
-msgstr "regex-ændringstegn '/.../%c' fra tawk virker ikke i gawk"
+msgstr "regex-ændringstegn '/.../%c' fra tawk virker ikke i gawk"
-#: awkgram.y:2917
+#: awkgram.y:3077
msgid "unterminated regexp"
-msgstr "uafsluttet regulært udtryk"
+msgstr "uafsluttet regulært udtryk"
-#: awkgram.y:2921
+#: awkgram.y:3081
msgid "unterminated regexp at end of file"
-msgstr "uafsluttet regulært udtryk i slutningen af filen"
+msgstr "uafsluttet regulært udtryk i slutningen af filen"
-#: awkgram.y:2980
+#: awkgram.y:3140
msgid "use of `\\ #...' line continuation is not portable"
-msgstr "brug af '\\ #...' for linjefortsættelse er ikke portabelt"
+msgstr "brug af '\\ #...' for linjefortsættelse er ikke portabelt"
-#: awkgram.y:2996
+#: awkgram.y:3156
msgid "backslash not last character on line"
-msgstr "sidste tegn på linjen er ikke en omvendt skråstreg"
+msgstr "sidste tegn på linjen er ikke en omvendt skråstreg"
-#: awkgram.y:3057
+#: awkgram.y:3217
msgid "POSIX does not allow operator `**='"
msgstr "POSIX tillader ikke operatoren '**='"
-#: awkgram.y:3059
+#: awkgram.y:3219
msgid "old awk does not support operator `**='"
-msgstr "gamle versioner af awk understøtter ikke operatoren '**='"
+msgstr "gamle versioner af awk understøtter ikke operatoren '**='"
-#: awkgram.y:3068
+#: awkgram.y:3228
msgid "POSIX does not allow operator `**'"
msgstr "POSIX tillader ikke operatoren '**'"
-#: awkgram.y:3070
+#: awkgram.y:3230
msgid "old awk does not support operator `**'"
-msgstr "gamle versioner af awk understøtter ikke operatoren '**'"
+msgstr "gamle versioner af awk understøtter ikke operatoren '**'"
-#: awkgram.y:3105
+#: awkgram.y:3265
msgid "operator `^=' is not supported in old awk"
-msgstr "operatoren '^=' understøttes ikke i gamle versioner af awk"
+msgstr "operatoren '^=' understøttes ikke i gamle versioner af awk"
-#: awkgram.y:3113
+#: awkgram.y:3273
msgid "operator `^' is not supported in old awk"
-msgstr "operatoren '^' understøttes ikke i gamle versioner af awk"
+msgstr "operatoren '^' understøttes ikke i gamle versioner af awk"
-#: awkgram.y:3206 awkgram.y:3222
+#: awkgram.y:3366 awkgram.y:3382 command.y:1178
msgid "unterminated string"
msgstr "uafsluttet streng"
-#: awkgram.y:3418
+#: awkgram.y:3603
#, c-format
msgid "invalid char '%c' in expression"
msgstr "ugyldigt tegn '%c' i udtryk"
-#: awkgram.y:3465
+#: awkgram.y:3650
#, c-format
msgid "`%s' is a gawk extension"
msgstr "'%s' er en gawk-udvidelse"
-#: awkgram.y:3470
-#, c-format
-msgid "`%s' is a Bell Labs extension"
-msgstr "'%s' er en Bell Labs-udvidelse"
-
-#: awkgram.y:3475
+#: awkgram.y:3655
#, c-format
msgid "POSIX does not allow `%s'"
msgstr "POSIX tillader ikke '%s'"
-#: awkgram.y:3483
+#: awkgram.y:3663
#, c-format
msgid "`%s' is not supported in old awk"
-msgstr "'%s' understøttes ikke i gamle versioner af awk"
+msgstr "'%s' understøttes ikke i gamle versioner af awk"
-#: awkgram.y:3550
+#: awkgram.y:3753
msgid "`goto' considered harmful!\n"
msgstr "'goto' anses for skadelig!\n"
-#: awkgram.y:3601
+#: awkgram.y:3787
#, c-format
msgid "%d is invalid as number of arguments for %s"
msgstr "%d er et ugyldigt antal argumenter for %s"
-#: awkgram.y:3636
+#: awkgram.y:3822
#, 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:3641
+#: awkgram.y:3827
#, c-format
msgid "%s third parameter is not a changeable object"
-msgstr "%s: tredje argument er ikke et ændringsbart objekt"
+msgstr "%s: tredje argument er ikke et ændringsbart objekt"
-#: awkgram.y:3714 awkgram.y:3717
+#: awkgram.y:3910 awkgram.y:3913
msgid "match: third argument is a gawk extension"
msgstr "match: tredje argument er en gawk-udvidelse"
-#: awkgram.y:3771 awkgram.y:3774
+#: awkgram.y:3967 awkgram.y:3970
msgid "close: second argument is a gawk extension"
msgstr "close: andet argument er en gawk-udvidelse"
-#: awkgram.y:3786
+#: awkgram.y:3982
msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
msgstr ""
"brug af dcgettext(_\"...\") er forkert: fjern det indledende "
"understregningstegn"
-#: awkgram.y:3801
+#: awkgram.y:3997
msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
msgstr ""
"brug af dcgettext(_\"...\") er forkert: fjern det indledende "
"understregningstegn"
-#: awkgram.y:3893
-#, c-format
-msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
-msgstr "funktionen '%s': parameter %d, '%s', er samme som parameter %d"
+#: awkgram.y:4016
+#, fuzzy
+msgid "index: regexp constant as second argument is not allowed"
+msgstr "indeks: andet argument er ikke en streng"
-#: awkgram.y:3935
+#: awkgram.y:4069
#, c-format
msgid "function `%s': parameter `%s' shadows global variable"
msgstr "funktionen '%s': parameteren '%s' overskygger en global variabel"
-#: awkgram.y:4093
+#: awkgram.y:4126 debug.c:4041 debug.c:4084 debug.c:5204
#, c-format
msgid "could not open `%s' for writing (%s)"
-msgstr "kunne ikke åbne '%s' for skrivning (%s)"
+msgstr "kunne ikke åbne '%s' for skrivning (%s)"
-#: awkgram.y:4094
+#: awkgram.y:4127
msgid "sending variable list to standard error"
msgstr "sender variabelliste til standard fejl"
-#: awkgram.y:4100
+#: awkgram.y:4135
#, c-format
msgid "%s: close failed (%s)"
msgstr "%s: lukning mislykkedes (%s)"
-#: awkgram.y:4152
+#: awkgram.y:4160
msgid "shadow_funcs() called twice!"
msgstr "shadow_funcs() kaldt to gange!"
-#: awkgram.y:4158
+#: awkgram.y:4168
msgid "there were shadowed variables."
msgstr "der var skyggede variable."
-#: awkgram.y:4188
+#: awkgram.y:4239
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "funktionsnavnet '%s' er allerede defineret"
+
+#: awkgram.y:4285
#, c-format
msgid "function `%s': can't use function name as parameter name"
msgstr "funktionen '%s': kan ikke bruge funktionsnavn som parameternavn"
-#: awkgram.y:4192
+#: awkgram.y:4288
#, c-format
msgid "function `%s': can't use special variable `%s' as a function parameter"
msgstr ""
"funktionen '%s': kan ikke bruge specialvariabel '%s' som en "
"funktionsparameter"
-#: awkgram.y:4208
+#: awkgram.y:4296
#, c-format
-msgid "function name `%s' previously defined"
-msgstr "funktionsnavnet '%s' er allerede defineret"
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "funktionen '%s': parameter %d, '%s', er samme som parameter %d"
-#: awkgram.y:4376 awkgram.y:4382
+#: awkgram.y:4383 awkgram.y:4389
#, c-format
msgid "function `%s' called but never defined"
msgstr "funktionen '%s' kaldt, men aldrig defineret"
-#: awkgram.y:4385
+#: awkgram.y:4393
#, c-format
msgid "function `%s' defined but never called directly"
msgstr "funktionen '%s' defineret, men aldrig kaldt direkte"
-#: awkgram.y:4417
+#: awkgram.y:4425
#, c-format
msgid "regexp constant for parameter #%d yields boolean value"
-msgstr "konstant regulært udtryk for parameter %d giver en boolesk værdi"
+msgstr "konstant regulært udtryk for parameter %d giver en boolesk værdi"
-#: awkgram.y:4526
+#: awkgram.y:4484
#, c-format
msgid ""
"function `%s' called with space between name and `(',\n"
@@ -532,457 +515,1329 @@ msgstr ""
"funktionen '%s' kaldt med blanktegn mellem navnet og '(',\n"
"eller brugt som en variabel eller et array"
-#: awkgram.y:4773 eval.c:2056
+#: awkgram.y:4720
msgid "division by zero attempted"
-msgstr "forsøgte at dividere med nul"
+msgstr "forsøgte at dividere med nul"
-#: awkgram.y:4782 eval.c:2072
+#: awkgram.y:4729
#, c-format
msgid "division by zero attempted in `%%'"
-msgstr "forsøgte at dividere med nul i '%%'"
+msgstr "forsøgte at dividere med nul i '%%'"
-#: builtin.c:120
+#: awkgram.y:5049
+msgid ""
+"cannot assign a value to the result of a field post-increment expression"
+msgstr ""
+
+#: awkgram.y:5052
+#, fuzzy, c-format
+msgid "invalid target of assignment (opcode %s)"
+msgstr "%d er et ugyldigt antal argumenter for %s"
+
+#: builtin.c:133
#, c-format
msgid "%s to \"%s\" failed (%s)"
msgstr "%s til '%s' mislykkedes (%s)"
-#: builtin.c:121
+#: builtin.c:134
msgid "standard output"
msgstr "standard ud"
-#: builtin.c:135
+#: builtin.c:148
msgid "exp: received non-numeric argument"
msgstr "exp: fik et ikke-numerisk argument"
-#: builtin.c:141
+#: builtin.c:154
#, c-format
msgid "exp: argument %g is out of range"
-msgstr "exp: argumentet %g er uden for det tilladte område"
+msgstr "exp: argumentet %g er uden for det tilladte område"
-#: builtin.c:200
+#: builtin.c:229
#, c-format
msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
msgstr ""
-"fflush: kan ikke rense: datakanalen '%s' åbnet for læsning, ikke skrivning"
+"fflush: kan ikke rense: datakanalen '%s' åbnet for læsning, ikke skrivning"
-#: builtin.c:203
+#: builtin.c:232
#, c-format
msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
-msgstr "fflush: kan ikke rense: filen '%s' åbnet for læsning, ikke skrivning"
+msgstr "fflush: kan ikke rense: filen '%s' åbnet for læsning, ikke skrivning"
-#: builtin.c:215
+#: builtin.c:244
#, 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"
+msgstr "fflush: '%s' er ikke en åben fil, datakanal eller ko-proces"
-#: builtin.c:333
+#: builtin.c:362
msgid "index: received non-string first argument"
-msgstr "indeks: første argument er ikke en streng"
+msgstr "indeks: første argument er ikke en streng"
-#: builtin.c:335
+#: builtin.c:364
msgid "index: received non-string second argument"
msgstr "indeks: andet argument er ikke en streng"
-#: builtin.c:457
+#: builtin.c:488 mpfr.c:757
msgid "int: received non-numeric argument"
msgstr "int: fik et ikke-numerisk argument"
-#: builtin.c:493
+#: builtin.c:525
msgid "length: received array argument"
msgstr "length: fik et array-argument"
-#: builtin.c:496
+#: builtin.c:528
msgid "`length(array)' is a gawk extension"
msgstr "'length(array)' er en gawk-udvidelse"
-#: builtin.c:504
+#: builtin.c:544
msgid "length: received non-string argument"
msgstr "length: fik et argument som ikke er en streng"
-#: builtin.c:535
+#: builtin.c:575
msgid "log: received non-numeric argument"
msgstr "log: fik et ikke-numerisk argument"
-#: builtin.c:538
+#: builtin.c:578
#, c-format
msgid "log: received negative argument %g"
msgstr "log: fik et negativt argument %g"
-#: builtin.c:694 builtin.c:699
+#: builtin.c:776 builtin.c:781
msgid "fatal: must use `count$' on all formats or none"
-msgstr "fatal: skal bruge 'count$' på alle formater eller ikke nogen"
+msgstr "fatal: skal bruge 'count$' på alle formater eller ikke nogen"
-#: builtin.c:761
+#: builtin.c:851
#, c-format
msgid "field width is ignored for `%%' specifier"
msgstr "feltbredde ignoreret for '%%'-angivelse"
-#: builtin.c:763
+#: builtin.c:853
#, c-format
msgid "precision is ignored for `%%' specifier"
-msgstr "præcision ignoreret for '%%'-angivelse"
+msgstr "præcision ignoreret for '%%'-angivelse"
-#: builtin.c:765
+#: builtin.c:855
#, c-format
msgid "field width and precision are ignored for `%%' specifier"
-msgstr "feltbredde og præcision ignoreret for '%%'-angivelse"
+msgstr "feltbredde og præcision ignoreret for '%%'-angivelse"
-#: builtin.c:816
+#: builtin.c:906
msgid "fatal: `$' is not permitted in awk formats"
msgstr "fatal: '$' tillades ikke i awk-formater"
-#: builtin.c:825
+#: builtin.c:915
msgid "fatal: arg count with `$' must be > 0"
-msgstr "fatal: argumentantallet med '$' skal være > 0"
+msgstr "fatal: argumentantallet med '$' skal være > 0"
-#: builtin.c:829
+#: builtin.c:919
#, c-format
msgid "fatal: arg count %ld greater than total number of supplied arguments"
-msgstr "fatal: argumentantallet %ld er større end antal givne argumenter"
+msgstr "fatal: argumentantallet %ld er større end antal givne argumenter"
-#: builtin.c:833
+#: builtin.c:923
msgid "fatal: `$' not permitted after period in format"
msgstr "fatal: '$' tillades ikke efter et punktum i formatet"
-#: builtin.c:849
+#: builtin.c:939
msgid "fatal: no `$' supplied for positional field width or precision"
msgstr ""
-"fatal: intet '$' angivet for bredde eller præcision af positionsangivet felt"
+"fatal: intet '$' angivet for bredde eller præcision af positionsangivet felt"
-#: builtin.c:920
+#: builtin.c:1009
msgid "`l' is meaningless in awk formats; ignored"
-msgstr "'l' er meningsløst i awk-formater, ignoreret"
+msgstr "'l' er meningsløst i awk-formater, ignoreret"
-#: builtin.c:924
+#: builtin.c:1013
msgid "fatal: `l' is not permitted in POSIX awk formats"
msgstr "fatal: 'l' tillades ikke i POSIX awk-formater"
-#: builtin.c:937
+#: builtin.c:1026
msgid "`L' is meaningless in awk formats; ignored"
-msgstr "'L' er meningsløst i awk-formater, ignoreret"
+msgstr "'L' er meningsløst i awk-formater, ignoreret"
-#: builtin.c:941
+#: builtin.c:1030
msgid "fatal: `L' is not permitted in POSIX awk formats"
msgstr "fatal: 'L' tillades ikke i POSIX awk-formater"
-#: builtin.c:954
+#: builtin.c:1043
msgid "`h' is meaningless in awk formats; ignored"
-msgstr "'h' er meningsløst i awk-formater, ignoreret"
+msgstr "'h' er meningsløst i awk-formater, ignoreret"
-#: builtin.c:958
+#: builtin.c:1047
msgid "fatal: `h' is not permitted in POSIX awk formats"
msgstr "fatal: 'h' tillades ikke i POSIX awk-formater"
-#: builtin.c:1271
+#: builtin.c:1463
#, c-format
msgid "[s]printf: value %g is out of range for `%%%c' format"
-msgstr "[s]printf: værdi %g er uden for område for '%%%c'-format"
+msgstr "[s]printf: værdi %g er uden for område for '%%%c'-format"
-#: builtin.c:1331
+#: builtin.c:1561
#, c-format
msgid "ignoring unknown format specifier character `%c': no argument converted"
msgstr ""
"ignorerer ukendt formatspecificeringstegn '%c': intet argument konverteret"
-#: builtin.c:1336
+#: builtin.c:1566
msgid "fatal: not enough arguments to satisfy format string"
-msgstr "fatal: for få argumenter til formatstrengen"
+msgstr "fatal: for få argumenter til formatstrengen"
-#: builtin.c:1338
+#: builtin.c:1568
msgid "^ ran out for this one"
msgstr "^ sluttede her"
-#: builtin.c:1345
+#: builtin.c:1575
msgid "[s]printf: format specifier does not have control letter"
msgstr "[s]printf: formatspecifikation har intet kommandobogstav"
-#: builtin.c:1348
+#: builtin.c:1578
msgid "too many arguments supplied for format string"
msgstr "for mange argumenter til formatstrengen"
-#: builtin.c:1422 builtin.c:1433
+#: builtin.c:1634
+#, fuzzy
+msgid "sprintf: no arguments"
+msgstr "printf: ingen argumenter"
+
+#: builtin.c:1657 builtin.c:1668
msgid "printf: no arguments"
msgstr "printf: ingen argumenter"
-#: builtin.c:1474
+#: builtin.c:1711
msgid "sqrt: received non-numeric argument"
msgstr "sqrt: fik ikke-numerisk argument"
-#: builtin.c:1478
+#: builtin.c:1715
#, c-format
msgid "sqrt: called with negative argument %g"
msgstr "sqrt: kaldt med negativt argument %g"
-#: builtin.c:1502
+#: builtin.c:1746
#, c-format
msgid "substr: length %g is not >= 1"
-msgstr "substr: længden %g er ikke >= 1"
+msgstr "substr: længden %g er ikke >= 1"
-#: builtin.c:1504
+#: builtin.c:1748
#, c-format
msgid "substr: length %g is not >= 0"
-msgstr "substr: længden %g er ikke >= 0"
+msgstr "substr: længden %g er ikke >= 0"
-#: builtin.c:1511
+#: builtin.c:1755
#, c-format
msgid "substr: non-integer length %g will be truncated"
-msgstr "substr: længden %g som ikke er et heltal vil blive trunkeret"
+msgstr "substr: længden %g som ikke er et heltal vil blive trunkeret"
-#: builtin.c:1516
+#: builtin.c:1760
#, c-format
msgid "substr: length %g too big for string indexing, truncating to %g"
-msgstr "substr: længden %g for stor til strengindeksering, trunkerer til %g"
+msgstr "substr: længden %g for stor til strengindeksering, trunkerer til %g"
-#: builtin.c:1528
+#: builtin.c:1772
#, c-format
msgid "substr: start index %g is invalid, using 1"
msgstr "substr: startindeks %g er ugyldigt, bruger 1"
-#: builtin.c:1533
+#: builtin.c:1777
#, c-format
msgid "substr: non-integer start index %g will be truncated"
msgstr "substr: startindeks %g som ikke er et heltal vil blive trunkeret"
-#: builtin.c:1558
+#: builtin.c:1802
msgid "substr: source string is zero length"
msgstr "substr: kildestrengen er tom"
-#: builtin.c:1574
+#: builtin.c:1818
#, c-format
msgid "substr: start index %g is past end of string"
-msgstr "substr: startindeks %g er forbi slutningen på strengen"
+msgstr "substr: startindeks %g er forbi slutningen på strengen"
-#: builtin.c:1582
+#: builtin.c:1826
#, c-format
msgid ""
"substr: length %g at start index %g exceeds length of first argument (%lu)"
msgstr ""
-"substr: længden %g ved startindeks %g overskrider længden af første argument "
+"substr: længden %g ved startindeks %g overskrider længden af første argument "
"(%lu)"
-#: builtin.c:1655
+#: builtin.c:1900
msgid "strftime: format value in PROCINFO[\"strftime\"] has numeric type"
-msgstr "strftime: formatværdi i PROCINFO[\"strftime\"] har numerisk type"
+msgstr "strftime: formatværdi i PROCINFO[\"strftime\"] har numerisk type"
-#: builtin.c:1678
+#: builtin.c:1923
msgid "strftime: received non-numeric second argument"
msgstr "strftime: fik et ikke-numerisk andet argument"
-#: builtin.c:1681
+#: builtin.c:1927
msgid "strftime: second argument less than 0 or too big for time_t"
-msgstr ""
+msgstr "strftime: andet argument mindre end 0 eller for stort til time_t"
-#: builtin.c:1687
+#: builtin.c:1934
msgid "strftime: received non-string first argument"
-msgstr "strftime: fik et første argument som ikke er en streng"
+msgstr "strftime: fik et første argument som ikke er en streng"
-#: builtin.c:1693
+#: builtin.c:1941
msgid "strftime: received empty format string"
msgstr "strftime: fik en tom formatstreng"
-#: builtin.c:1759
+#: builtin.c:2007
msgid "mktime: received non-string argument"
msgstr "mktime: fik et argument som ikke er en streng"
-#: builtin.c:1776
+#: builtin.c:2024
msgid "mktime: at least one of the values is out of the default range"
-msgstr "mktime: mindst én af værdierne er udenfor standardområdet"
+msgstr "mktime: mindst én af værdierne er udenfor standardområdet"
-#: builtin.c:1811
+#: builtin.c:2059
msgid "'system' function not allowed in sandbox mode"
msgstr "'system'-funktion ikke tilladt i sandkasse-tilstand"
-#: builtin.c:1816
+#: builtin.c:2064
msgid "system: received non-string argument"
msgstr "system: fik et argument som ikke er en streng"
-#: builtin.c:1871 eval.c:1159 eval.c:1790 eval.c:1803
-#, c-format
-msgid "reference to uninitialized variable `%s'"
-msgstr "reference til ikke-initieret variabel '%s'"
-
-#: builtin.c:1938
+#: builtin.c:2184
#, c-format
msgid "reference to uninitialized field `$%d'"
msgstr "reference til ikke-initieret felt '$%d'"
-#: builtin.c:2025
+#: builtin.c:2271
msgid "tolower: received non-string argument"
msgstr "tolower: fik et argument som ikke er en streng"
-#: builtin.c:2059
+#: builtin.c:2305
msgid "toupper: received non-string argument"
msgstr "toupper: fik et argument som ikke er en streng"
-#: builtin.c:2095
+#: builtin.c:2341 mpfr.c:672
msgid "atan2: received non-numeric first argument"
-msgstr "atan2: fik et ikke-numerisk første argument"
+msgstr "atan2: fik et ikke-numerisk første argument"
-#: builtin.c:2097
+#: builtin.c:2343 mpfr.c:674
msgid "atan2: received non-numeric second argument"
msgstr "atan2: fik et ikke-numerisk andet argument"
-#: builtin.c:2116
+#: builtin.c:2362
msgid "sin: received non-numeric argument"
msgstr "sin: fik et ikke-numerisk argument"
-#: builtin.c:2132
+#: builtin.c:2378
msgid "cos: received non-numeric argument"
msgstr "cos: fik et ikke-numerisk argument"
-#: builtin.c:2185
+#: builtin.c:2431 mpfr.c:1156
msgid "srand: received non-numeric argument"
msgstr "srand: fik et ikke-numerisk argument"
-#: builtin.c:2216
+#: builtin.c:2462
msgid "match: third argument is not an array"
msgstr "match: tredje argument er ikke et array"
-#: builtin.c:2480
+#: builtin.c:2734
msgid "gensub: third argument of 0 treated as 1"
msgstr "gensub: 0 i tredje argument behandlet som 1"
-#: builtin.c:2773
+#: builtin.c:3030
msgid "lshift: received non-numeric first argument"
-msgstr "lshift: fik et ikke-numerisk første argument"
+msgstr "lshift: fik et ikke-numerisk første argument"
-#: builtin.c:2775
+#: builtin.c:3032
msgid "lshift: received non-numeric second argument"
msgstr "lshift: fik et ikke-numerisk andet argument"
-#: builtin.c:2781
-#, 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:3038
+#, fuzzy, c-format
+msgid "lshift(%f, %f): negative values will give strange results"
+msgstr "lshift(%lf, %lf): negative værdier vil give mærkelige resultater"
-#: builtin.c:2783
-#, c-format
-msgid "lshift(%lf, %lf): fractional values will be truncated"
-msgstr "lshift(%lf, %lf): kommatalsværdier vil blive trunkeret"
+#: builtin.c:3040
+#, fuzzy, c-format
+msgid "lshift(%f, %f): fractional values will be truncated"
+msgstr "lshift(%lf, %lf): kommatalsværdier vil blive trunkeret"
-#: builtin.c:2785
-#, c-format
-msgid "lshift(%lf, %lf): too large shift value will give strange results"
+#: builtin.c:3042
+#, fuzzy, c-format
+msgid "lshift(%f, %f): too large shift value will give strange results"
msgstr ""
-"lshift(%lf, %lf): for store skifteværdier vil give mærkelige resultater"
+"lshift(%lf, %lf): for store skifteværdier vil give mærkelige resultater"
-#: builtin.c:2810
+#: builtin.c:3067
msgid "rshift: received non-numeric first argument"
-msgstr "rshift: fik et ikke-numerisk første argument"
+msgstr "rshift: fik et ikke-numerisk første argument"
-#: builtin.c:2812
+#: builtin.c:3069
msgid "rshift: received non-numeric second argument"
msgstr "rshift: fik et ikke-numerisk andet argument"
-#: builtin.c:2818
+#: builtin.c:3075
+#, fuzzy, c-format
+msgid "rshift(%f, %f): negative values will give strange results"
+msgstr "rshift(%lf, %lf): negative værdier vil give mærkelige resultater"
+
+#: builtin.c:3077
+#, fuzzy, c-format
+msgid "rshift(%f, %f): fractional values will be truncated"
+msgstr "rshift(%lf, %lf): kommatalsværdier vil blive trunkeret"
+
+#: builtin.c:3079
+#, fuzzy, c-format
+msgid "rshift(%f, %f): too large shift value will give strange results"
+msgstr ""
+"rshift(%lf, %lf): for store skifteværdier vil give mærkelige resultater"
+
+#: builtin.c:3104 mpfr.c:968
+#, fuzzy
+msgid "and: called with less than two arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: builtin.c:3109
+#, fuzzy, c-format
+msgid "and: argument %d is non-numeric"
+msgstr "exp: argumentet %g er uden for det tilladte område"
+
+#: builtin.c:3113
+#, fuzzy, c-format
+msgid "and: argument %d negative value %g will give strange results"
+msgstr "and(%lf, %lf): negative værdier vil give mærkelige resultater"
+
+#: builtin.c:3136 mpfr.c:1000
+#, fuzzy
+msgid "or: called with less than two arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: builtin.c:3141
+#, fuzzy, c-format
+msgid "or: argument %d is non-numeric"
+msgstr "exp: argumentet %g er uden for det tilladte område"
+
+#: builtin.c:3145
+#, fuzzy, c-format
+msgid "or: argument %d negative value %g will give strange results"
+msgstr "compl(%lf): negative værdier vil give mærkelige resultater"
+
+#: builtin.c:3167 mpfr.c:1031
+#, fuzzy
+msgid "xor: called with less than two arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: builtin.c:3173
+#, fuzzy, c-format
+msgid "xor: argument %d is non-numeric"
+msgstr "exp: argumentet %g er uden for det tilladte område"
+
+#: builtin.c:3177
+#, fuzzy, c-format
+msgid "xor: argument %d negative value %g will give strange results"
+msgstr "xor(%lf, %lf): negative værdier vil give mærkelige resultater"
+
+#: builtin.c:3202 mpfr.c:787
+msgid "compl: received non-numeric argument"
+msgstr "compl: fik et ikke-numerisk argument"
+
+#: builtin.c:3208
+#, fuzzy, c-format
+msgid "compl(%f): negative value will give strange results"
+msgstr "compl(%lf): negative værdier vil give mærkelige resultater"
+
+#: builtin.c:3210
+#, fuzzy, c-format
+msgid "compl(%f): fractional value will be truncated"
+msgstr "compl(%lf): kommatalsværdier vil blive trunkeret"
+
+#: builtin.c:3379
#, c-format
-msgid "rshift(%lf, %lf): negative values will give strange results"
-msgstr "rshift(%lf, %lf): negative værdier vil give mærkelige resultater"
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: '%s' er ikke en gyldig lokalitetskategori"
-#: builtin.c:2820
+#: command.y:225
#, c-format
-msgid "rshift(%lf, %lf): fractional values will be truncated"
-msgstr "rshift(%lf, %lf): kommatalsværdier vil blive trunkeret"
+msgid "Type (g)awk statement(s). End with the command \"end\"\n"
+msgstr ""
+
+#: command.y:289
+#, fuzzy, c-format
+msgid "invalid frame number: %d"
+msgstr "Ugyldig intervalslutning"
-#: builtin.c:2822
+#: command.y:295
+#, fuzzy, c-format
+msgid "info: invalid option - \"%s\""
+msgstr "%s: ugyldigt flag - '%c'\n"
+
+#: command.y:321
+#, c-format
+msgid "source \"%s\": already sourced."
+msgstr ""
+
+#: command.y:326
#, c-format
-msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgid "save \"%s\": command not permitted."
msgstr ""
-"rshift(%lf, %lf): for store skifteværdier vil give mærkelige resultater"
-#: builtin.c:2847
-msgid "and: received non-numeric first argument"
-msgstr "and: fik et ikke-numerisk første argument"
+#: command.y:339
+msgid "Can't use command `commands' for breakpoint/watchpoint commands"
+msgstr ""
+
+#: command.y:341
+msgid "no breakpoint/watchpoint has been set yet"
+msgstr ""
-#: builtin.c:2849
-msgid "and: received non-numeric second argument"
-msgstr "and: fik et ikke-numerisk andet argument"
+#: command.y:343
+msgid "invalid breakpoint/watchpoint number"
+msgstr ""
-#: builtin.c:2855
+#: command.y:348
#, c-format
-msgid "and(%lf, %lf): negative values will give strange results"
-msgstr "and(%lf, %lf): negative værdier vil give mærkelige resultater"
+msgid "Type commands for when %s %d is hit, one per line.\n"
+msgstr ""
-#: builtin.c:2857
+#: command.y:350
#, c-format
-msgid "and(%lf, %lf): fractional values will be truncated"
-msgstr "and(%lf, %lf): kommatalsværdier vil blive trunkeret"
+msgid "End with the command \"end\"\n"
+msgstr ""
+
+#: command.y:357
+msgid "`end' valid only in command `commands' or `eval'"
+msgstr ""
-#: builtin.c:2882
-msgid "or: received non-numeric first argument"
-msgstr "or: fik et ikke-numerisk første argument"
+#: command.y:367
+msgid "`silent' valid only in command `commands'"
+msgstr ""
-#: builtin.c:2884
-msgid "or: received non-numeric second argument"
-msgstr "or: fik et ikke-numerisk andet argument"
+#: command.y:373
+#, fuzzy, c-format
+msgid "trace: invalid option - \"%s\""
+msgstr "%s: ugyldigt flag - '%c'\n"
-#: builtin.c:2890
+#: command.y:387
+msgid "condition: invalid breakpoint/watchpoint number"
+msgstr ""
+
+#: command.y:449
+#, fuzzy
+msgid "argument not a string"
+msgstr "exp: argumentet %g er uden for det tilladte område"
+
+#: command.y:459 command.y:464
#, c-format
-msgid "or(%lf, %lf): negative values will give strange results"
-msgstr "or(%lf, %lf): negative værdier vil give mærkelige resultater"
+msgid "option: invalid parameter - \"%s\""
+msgstr ""
-#: builtin.c:2892
+#: command.y:474
#, c-format
-msgid "or(%lf, %lf): fractional values will be truncated"
-msgstr "or(%lf, %lf): kommatalsværdier vil blive trunkeret"
+msgid "no such function - \"%s\""
+msgstr ""
+
+#: command.y:531
+#, fuzzy, c-format
+msgid "enable: invalid option - \"%s\""
+msgstr "%s: ugyldigt flag - '%c'\n"
+
+#: command.y:597
+#, fuzzy, c-format
+msgid "invalid range specification: %d - %d"
+msgstr "Ugyldig intervalslutning"
+
+#: command.y:659
+#, fuzzy
+msgid "non-numeric value for field number"
+msgstr "ukendt værdi for felt-spec: %d\n"
+
+#: command.y:680 command.y:687
+msgid "non-numeric value found, numeric expected"
+msgstr ""
+
+#: command.y:712 command.y:718
+msgid "non-zero integer value"
+msgstr ""
+
+#: command.y:817
+msgid ""
+"backtrace [N] - print trace of all or N innermost (outermost if N < 0) "
+"frames."
+msgstr ""
+
+#: command.y:819
+msgid ""
+"break [[filename:]N|function] - set breakpoint at the specified location."
+msgstr ""
+
+#: command.y:821
+msgid "clear [[filename:]N|function] - delete breakpoints previously set."
+msgstr ""
+
+#: command.y:823
+msgid ""
+"commands [num] - starts a list of commands to be executed at a "
+"breakpoint(watchpoint) hit."
+msgstr ""
+
+#: command.y:825
+msgid "condition num [expr] - set or clear breakpoint or watchpoint condition."
+msgstr ""
+
+#: command.y:827
+msgid "continue [COUNT] - continue program being debugged."
+msgstr ""
+
+#: command.y:829
+msgid "delete [breakpoints] [range] - delete specified breakpoints."
+msgstr ""
+
+#: command.y:831
+msgid "disable [breakpoints] [range] - disable specified breakpoints."
+msgstr ""
+
+#: command.y:833
+msgid "display [var] - print value of variable each time the program stops."
+msgstr ""
+
+#: command.y:835
+msgid "down [N] - move N frames down the stack."
+msgstr ""
+
+#: command.y:837
+msgid "dump [filename] - dump instructions to file or stdout."
+msgstr ""
+
+#: command.y:839
+msgid "enable [once|del] [breakpoints] [range] - enable specified breakpoints."
+msgstr ""
+
+#: command.y:841
+msgid "end - end a list of commands or awk statements."
+msgstr ""
+
+#: command.y:843
+msgid "eval stmt|[p1, p2, ...] - evaluate awk statement(s)."
+msgstr ""
+
+#: command.y:845
+msgid "finish - execute until selected stack frame returns."
+msgstr ""
+
+#: command.y:847
+msgid "frame [N] - select and print stack frame number N."
+msgstr ""
+
+#: command.y:849
+msgid "help [command] - print list of commands or explanation of command."
+msgstr ""
+
+#: command.y:851
+msgid "ignore N COUNT - set ignore-count of breakpoint number N to COUNT."
+msgstr ""
+
+#: command.y:853
+msgid ""
+"info topic - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch."
+msgstr ""
+
+#: command.y:855
+msgid "list [-|+|[filename:]lineno|function|range] - list specified line(s)."
+msgstr ""
+
+#: command.y:857
+msgid "next [COUNT] - step program, proceeding through subroutine calls."
+msgstr ""
+
+#: command.y:859
+msgid ""
+"nexti [COUNT] - step one instruction, but proceed through subroutine calls."
+msgstr ""
+
+#: command.y:861
+msgid "option [name[=value]] - set or display debugger option(s)."
+msgstr ""
+
+#: command.y:863
+msgid "print var [var] - print value of a variable or array."
+msgstr ""
+
+#: command.y:865
+msgid "printf format, [arg], ... - formatted output."
+msgstr ""
+
+#: command.y:867
+msgid "quit - exit debugger."
+msgstr ""
+
+#: command.y:869
+msgid "return [value] - make selected stack frame return to its caller."
+msgstr ""
+
+#: command.y:871
+msgid "run - start or restart executing program."
+msgstr ""
+
+#: command.y:874
+msgid "save filename - save commands from the session to file."
+msgstr ""
+
+#: command.y:877
+msgid "set var = value - assign value to a scalar variable."
+msgstr ""
+
+#: command.y:879
+msgid ""
+"silent - suspends usual message when stopped at a breakpoint/watchpoint."
+msgstr ""
+
+#: command.y:881
+msgid "source file - execute commands from file."
+msgstr ""
+
+#: command.y:883
+msgid "step [COUNT] - step program until it reaches a different source line."
+msgstr ""
+
+#: command.y:885
+msgid "stepi [COUNT] - step one instruction exactly."
+msgstr ""
+
+#: command.y:887
+msgid "tbreak [[filename:]N|function] - set a temporary breakpoint."
+msgstr ""
+
+#: command.y:889
+msgid "trace on|off - print instruction before executing."
+msgstr ""
+
+#: command.y:891
+msgid "undisplay [N] - remove variable(s) from automatic display list."
+msgstr ""
+
+#: command.y:893
+msgid ""
+"until [[filename:]N|function] - execute until program reaches a different "
+"line or line N within current frame."
+msgstr ""
+
+#: command.y:895
+msgid "unwatch [N] - remove variable(s) from watch list."
+msgstr ""
-#: builtin.c:2920
-msgid "xor: received non-numeric first argument"
-msgstr "xor: fik et ikke-numerisk første argument"
+#: command.y:897
+msgid "up [N] - move N frames up the stack."
+msgstr ""
-#: builtin.c:2922
-msgid "xor: received non-numeric second argument"
-msgstr "xor: fik et ikke-numerisk andet argument"
+#: command.y:899
+msgid "watch var - set a watchpoint for a variable."
+msgstr ""
-#: builtin.c:2928
+#: command.y:1011 debug.c:401 msg.c:135
#, c-format
-msgid "xor(%lf, %lf): negative values will give strange results"
-msgstr "xor(%lf, %lf): negative værdier vil give mærkelige resultater"
+msgid "error: "
+msgstr "fejl: "
-#: builtin.c:2930
+#: command.y:1051
+#, fuzzy, c-format
+msgid "can't read command (%s)\n"
+msgstr "kan ikke omdirigere fra '%s' (%s)"
+
+#: command.y:1065
+#, fuzzy, c-format
+msgid "can't read command (%s)"
+msgstr "kan ikke omdirigere fra '%s' (%s)"
+
+#: command.y:1116
+#, fuzzy
+msgid "invalid character in command"
+msgstr "Ugyldigt tegnklassenavn"
+
+#: command.y:1152
#, c-format
-msgid "xor(%lf, %lf): fractional values will be truncated"
-msgstr "xor(%lf, %lf): kommatalsværdier vil blive trunkeret"
+msgid "unknown command - \"%.*s\", try help"
+msgstr ""
-#: builtin.c:2954 builtin.c:2960
-msgid "compl: received non-numeric argument"
-msgstr "compl: fik et ikke-numerisk argument"
+#: command.y:1222
+#, c-format
+msgid "%s"
+msgstr ""
+
+#: command.y:1284
+#, fuzzy
+msgid "invalid character"
+msgstr "Ugyldigt sorteringstegn"
+
+#: command.y:1455
+#, c-format
+msgid "undefined command: %s\n"
+msgstr ""
+
+#: debug.c:252
+msgid "set or show the number of lines to keep in history file."
+msgstr ""
+
+#: debug.c:254
+msgid "set or show the list command window size."
+msgstr ""
+
+#: debug.c:256
+msgid "set or show gawk output file."
+msgstr ""
+
+#: debug.c:258
+msgid "set or show debugger prompt."
+msgstr ""
+
+#: debug.c:260
+msgid "(un)set or show saving of command history (value=on|off)."
+msgstr ""
+
+#: debug.c:262
+msgid "(un)set or show saving of options (value=on|off)."
+msgstr ""
+
+#: debug.c:264
+msgid "(un)set or show instruction tracing (value=on|off)."
+msgstr ""
+
+#: debug.c:345
+msgid "program not running."
+msgstr ""
+
+#: debug.c:448 debug.c:606
+#, fuzzy, c-format
+msgid "can't read source file `%s' (%s)"
+msgstr "kan ikke læse kildefilen '%s' (%s)"
+
+#: debug.c:453
+#, fuzzy, c-format
+msgid "source file `%s' is empty.\n"
+msgstr "kildefilen '%s' er tom"
+
+#: debug.c:480
+msgid "no current source file."
+msgstr ""
-#: builtin.c:2962
+#: debug.c:505
+#, fuzzy, c-format
+msgid "cannot find source file named `%s' (%s)"
+msgstr "kan ikke læse kildefilen '%s' (%s)"
+
+#: debug.c:529
#, c-format
-msgid "compl(%lf): negative value will give strange results"
-msgstr "compl(%lf): negative værdier vil give mærkelige resultater"
+msgid "WARNING: source file `%s' modified since program compilation.\n"
+msgstr ""
-#: builtin.c:2964
+#: debug.c:551
#, c-format
-msgid "compl(%lf): fractional value will be truncated"
-msgstr "compl(%lf): kommatalsværdier vil blive trunkeret"
+msgid "line number %d out of range; `%s' has %d lines"
+msgstr ""
-#: builtin.c:3133
+#: debug.c:611
+#, fuzzy, c-format
+msgid "unexpected eof while reading file `%s', line %d"
+msgstr "uventet nylinjetegn eller strengafslutning"
+
+#: debug.c:620
#, c-format
-msgid "dcgettext: `%s' is not a valid locale category"
-msgstr "dcgettext: '%s' er ikke en gyldig lokalitetskategori"
+msgid "source file `%s' modified since start of program execution"
+msgstr ""
+
+#: debug.c:732
+#, fuzzy, c-format
+msgid "Current source file: %s\n"
+msgstr "allerede inkluderet kildefil '%s'"
+
+#: debug.c:733
+#, c-format
+msgid "Number of lines: %d\n"
+msgstr ""
+
+#: debug.c:740
+#, c-format
+msgid "Source file (lines): %s (%d)\n"
+msgstr ""
+
+#: debug.c:754
+msgid ""
+"Number Disp Enabled Location\n"
+"\n"
+msgstr ""
+
+#: debug.c:765
+#, c-format
+msgid "\tno of hits = %ld\n"
+msgstr ""
+
+#: debug.c:767
+#, c-format
+msgid "\tignore next %ld hit(s)\n"
+msgstr ""
+
+#: debug.c:769 debug.c:909
+#, c-format
+msgid "\tstop condition: %s\n"
+msgstr ""
+
+#: debug.c:771 debug.c:911
+msgid "\tcommands:\n"
+msgstr ""
+
+#: debug.c:793
+#, c-format
+msgid "Current frame: "
+msgstr ""
+
+#: debug.c:796
+#, c-format
+msgid "Called by frame: "
+msgstr ""
+
+#: debug.c:800
+#, c-format
+msgid "Caller of frame: "
+msgstr ""
+
+#: debug.c:818
+#, c-format
+msgid "None in main().\n"
+msgstr ""
+
+#: debug.c:848
+#, fuzzy
+msgid "No arguments.\n"
+msgstr "printf: ingen argumenter"
+
+#: debug.c:849
+msgid "No locals.\n"
+msgstr ""
+
+#: debug.c:857
+msgid ""
+"All defined variables:\n"
+"\n"
+msgstr ""
+
+#: debug.c:867
+msgid ""
+"All defined functions:\n"
+"\n"
+msgstr ""
+
+#: debug.c:886
+msgid ""
+"Auto-display variables:\n"
+"\n"
+msgstr ""
+
+#: debug.c:889
+msgid ""
+"Watch variables:\n"
+"\n"
+msgstr ""
+
+#: debug.c:1029
+#, fuzzy, c-format
+msgid "no symbol `%s' in current context\n"
+msgstr "'exit' kan ikke kaldes i den aktuelle kontekst"
+
+#: debug.c:1041 debug.c:1427
+#, fuzzy, c-format
+msgid "`%s' is not an array\n"
+msgstr "'%s' er ikke et gyldigt variabelnavn"
+
+#: debug.c:1055
+#, fuzzy, c-format
+msgid "$%ld = uninitialized field\n"
+msgstr "reference til ikke-initieret felt '$%d'"
+
+#: debug.c:1076
+#, fuzzy, c-format
+msgid "array `%s' is empty\n"
+msgstr "datafilen '%s' er tom"
+
+#: debug.c:1119 debug.c:1171
+#, fuzzy, c-format
+msgid "[\"%s\"] not in array `%s'\n"
+msgstr "delete: indeks '%s' findes ikke i array '%s'"
+
+#: debug.c:1175
+#, c-format
+msgid "`%s[\"%s\"]' is not an array\n"
+msgstr ""
+
+#: debug.c:1236 debug.c:4964
+#, fuzzy, c-format
+msgid "`%s' is not a scalar variable"
+msgstr "'%s' er ikke et gyldigt variabelnavn"
+
+#: debug.c:1258 debug.c:4994
+#, fuzzy, c-format
+msgid "attempt to use array `%s[\"%s\"]' in a scalar context"
+msgstr "forsøg på at bruge array '%s[\"%.*s\"]' i skalarsammenhæng"
+
+#: debug.c:1280 debug.c:5005
+#, fuzzy, c-format
+msgid "attempt to use scalar `%s[\"%s\"]' as array"
+msgstr "forsøg på at bruge skalaren '%s[\"%.*s\"]' som array"
+
+#: debug.c:1423
+#, fuzzy, c-format
+msgid "`%s' is a function"
+msgstr "'%s' er ugyldigt som funktionsnavn"
+
+#: debug.c:1465
+#, c-format
+msgid "watchpoint %d is unconditional\n"
+msgstr ""
+
+#: debug.c:1499
+#, c-format
+msgid "No display item numbered %ld"
+msgstr ""
+
+#: debug.c:1502
+#, c-format
+msgid "No watch item numbered %ld"
+msgstr ""
+
+#: debug.c:1528
+#, fuzzy, c-format
+msgid "%d: [\"%s\"] not in array `%s'\n"
+msgstr "delete: indeks '%s' findes ikke i array '%s'"
+
+#: debug.c:1767
+#, fuzzy
+msgid "attempt to use scalar value as array"
+msgstr "forsøg på at bruge en skalar som array"
+
+#: debug.c:1856
+#, c-format
+msgid "Watchpoint %d deleted because parameter is out of scope.\n"
+msgstr ""
+
+#: debug.c:1867
+#, c-format
+msgid "Display %d deleted because parameter is out of scope.\n"
+msgstr ""
+
+#: debug.c:1900
+#, c-format
+msgid " in file `%s', line %d\n"
+msgstr ""
+
+#: debug.c:1921
+#, c-format
+msgid " at `%s':%d"
+msgstr ""
+
+#: debug.c:1937 debug.c:2000
+#, c-format
+msgid "#%ld\tin "
+msgstr ""
+
+#: debug.c:1974
+#, c-format
+msgid "More stack frames follow ...\n"
+msgstr ""
+
+#: debug.c:2017
+#, fuzzy
+msgid "invalid frame number"
+msgstr "Ugyldig intervalslutning"
+
+#: debug.c:2200
+#, c-format
+msgid "Note: breakpoint %d (enabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2207
+#, c-format
+msgid "Note: breakpoint %d (enabled), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2214
+#, c-format
+msgid "Note: breakpoint %d (disabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2221
+#, c-format
+msgid "Note: breakpoint %d (disabled), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2238
+#, c-format
+msgid "Breakpoint %d set at file `%s', line %d\n"
+msgstr ""
+
+#: debug.c:2340
+#, c-format
+msgid "Can't set breakpoint in file `%s'\n"
+msgstr ""
+
+#: debug.c:2369 debug.c:2492 debug.c:3350
+#, fuzzy, c-format
+msgid "line number %d in file `%s' out of range"
+msgstr "exp: argumentet %g er uden for det tilladte område"
+
+#: debug.c:2373
+#, c-format
+msgid "Can't find rule!!!\n"
+msgstr ""
+
+#: debug.c:2375
+#, c-format
+msgid "Can't set breakpoint at `%s':%d\n"
+msgstr ""
+
+#: debug.c:2387
+#, c-format
+msgid "Can't set breakpoint in function `%s'\n"
+msgstr ""
+
+#: debug.c:2403
+#, c-format
+msgid "breakpoint %d set at file `%s', line %d is unconditional\n"
+msgstr ""
+
+#: debug.c:2508 debug.c:2530
+#, c-format
+msgid "Deleted breakpoint %d"
+msgstr ""
+
+#: debug.c:2514
+#, c-format
+msgid "No breakpoint(s) at entry to function `%s'\n"
+msgstr ""
+
+#: debug.c:2541
+#, fuzzy, c-format
+msgid "No breakpoint at file `%s', line #%d\n"
+msgstr "fejl ved læsning af inddatafilen '%s': %s"
+
+#: debug.c:2596 debug.c:2637 debug.c:2657 debug.c:2700
+msgid "invalid breakpoint number"
+msgstr ""
+
+#: debug.c:2612
+msgid "Delete all breakpoints? (y or n) "
+msgstr ""
+
+#: debug.c:2613 debug.c:2923 debug.c:2976
+msgid "y"
+msgstr ""
+
+#: debug.c:2662
+#, c-format
+msgid "Will ignore next %ld crossing(s) of breakpoint %d.\n"
+msgstr ""
+
+#: debug.c:2666
+#, c-format
+msgid "Will stop next time breakpoint %d is reached.\n"
+msgstr ""
+
+#: debug.c:2783
+#, c-format
+msgid "Can only debug programs provided with the `-f' option.\n"
+msgstr ""
+
+#: debug.c:2908
+#, c-format
+msgid "Failed to restart debugger"
+msgstr ""
+
+#: debug.c:2922
+msgid "Program already running. Restart from beginning (y/n)? "
+msgstr ""
+
+#: debug.c:2926
+#, c-format
+msgid "Program not restarted\n"
+msgstr ""
+
+#: debug.c:2936
+#, c-format
+msgid "error: cannot restart, operation not allowed\n"
+msgstr ""
+
+#: debug.c:2942
+#, c-format
+msgid "error (%s): cannot restart, ignoring rest of the commands\n"
+msgstr ""
+
+#: debug.c:2950
+#, c-format
+msgid "Starting program: \n"
+msgstr ""
+
+#: debug.c:2959
+#, c-format
+msgid "Program exited %s with exit value: %d\n"
+msgstr ""
+
+#: debug.c:2975
+msgid "The program is running. Exit anyway (y/n)? "
+msgstr ""
+
+#: debug.c:3010
+#, c-format
+msgid "Not stopped at any breakpoint; argument ignored.\n"
+msgstr ""
+
+#: debug.c:3015
+#, c-format
+msgid "invalid breakpoint number %d."
+msgstr ""
+
+#: debug.c:3020
+#, c-format
+msgid "Will ignore next %ld crossings of breakpoint %d.\n"
+msgstr ""
+
+#: debug.c:3207
+#, c-format
+msgid "'finish' not meaningful in the outermost frame main()\n"
+msgstr ""
+
+#: debug.c:3212
+#, c-format
+msgid "Run till return from "
+msgstr ""
+
+#: debug.c:3255
+#, c-format
+msgid "'return' not meaningful in the outermost frame main()\n"
+msgstr ""
+
+#: debug.c:3369
+#, c-format
+msgid "Can't find specified location in function `%s'\n"
+msgstr ""
+
+#: debug.c:3377
+#, fuzzy, c-format
+msgid "invalid source line %d in file `%s'"
+msgstr "allerede inkluderet kildefil '%s'"
+
+#: debug.c:3392
+#, c-format
+msgid "Can't find specified location %d in file `%s'\n"
+msgstr ""
+
+#: debug.c:3424
+#, fuzzy, c-format
+msgid "element not in array\n"
+msgstr "delete: indeks '%s' findes ikke i array '%s'"
+
+#: debug.c:3424
+#, c-format
+msgid "untyped variable\n"
+msgstr ""
+
+#: debug.c:3466
+#, c-format
+msgid "Stopping in %s ...\n"
+msgstr ""
+
+#: debug.c:3543
+#, c-format
+msgid "'finish' not meaningful with non-local jump '%s'\n"
+msgstr ""
+
+#: debug.c:3550
+#, c-format
+msgid "'until' not meaningful with non-local jump '%s'\n"
+msgstr ""
+
+#: debug.c:4185
+msgid "\t------[Enter] to continue or q [Enter] to quit------"
+msgstr ""
+
+#: debug.c:4186
+msgid "q"
+msgstr ""
+
+#: debug.c:5001
+#, fuzzy, c-format
+msgid "[\"%s\"] not in array `%s'"
+msgstr "delete: indeks '%s' findes ikke i array '%s'"
+
+#: debug.c:5207
+#, c-format
+msgid "sending output to stdout\n"
+msgstr ""
+
+#: debug.c:5247
+msgid "invalid number"
+msgstr ""
+
+#: debug.c:5381
+#, fuzzy, c-format
+msgid "`%s' not allowed in current context; statement ignored"
+msgstr "'exit' kan ikke kaldes i den aktuelle kontekst"
+
+#: debug.c:5389
+#, fuzzy
+msgid "`return' not allowed in current context; statement ignored"
+msgstr "'exit' kan ikke kaldes i den aktuelle kontekst"
+
+#: debug.c:5590
+#, fuzzy, c-format
+msgid "No symbol `%s' in current context"
+msgstr "forsøg på at bruge array '%s' i skalarsammenhæng"
+
+#: dfa.c:1118 dfa.c:1121 dfa.c:1142 dfa.c:1150 dfa.c:1162 dfa.c:1197
+#: dfa.c:1206 dfa.c:1209 dfa.c:1214 dfa.c:1228 dfa.c:1275
+msgid "unbalanced ["
+msgstr ""
+
+#: dfa.c:1174
+#, fuzzy
+msgid "invalid character class"
+msgstr "Ugyldigt tegnklassenavn"
+
+#: dfa.c:1316
+msgid "character class syntax is [[:space:]], not [:space:]"
+msgstr ""
+
+#: dfa.c:1366
+msgid "unfinished \\ escape"
+msgstr ""
+
+#: dfa.c:1513 regcomp.c:161
+msgid "Invalid content of \\{\\}"
+msgstr "Ugyldigt indhold i \\{\\}"
+
+#: dfa.c:1516 regcomp.c:176
+msgid "Regular expression too big"
+msgstr "Regulært udtryk for stort"
+
+#: dfa.c:1936
+msgid "unbalanced ("
+msgstr ""
+
+#: dfa.c:2062
+msgid "no syntax specified"
+msgstr ""
+
+#: dfa.c:2070
+msgid "unbalanced )"
+msgstr ""
-#: eval.c:412
+#: eval.c:394
#, c-format
msgid "unknown nodetype %d"
msgstr "ukendt nodetype %d"
-#: eval.c:423 eval.c:437
+#: eval.c:405 eval.c:419
#, c-format
msgid "unknown opcode %d"
msgstr "ukendt opkode %d"
-#: eval.c:434
+#: eval.c:416
#, c-format
msgid "opcode %s not an operator or keyword"
-msgstr "opkode %s er ikke en operator eller et nøgleord"
+msgstr "opkode %s er ikke en operator eller et nøgleord"
-#: eval.c:488
+#: eval.c:472
msgid "buffer overflow in genflags2str"
-msgstr "bufferoverløb i genflags2str"
+msgstr "bufferoverløb i genflags2str"
-#: eval.c:698
+#: eval.c:675
#, c-format
msgid ""
"\n"
@@ -993,807 +1848,1266 @@ msgstr ""
"\t# Funktionskaldsstak:\n"
"\n"
-#: eval.c:725
+#: eval.c:704
msgid "`IGNORECASE' is a gawk extension"
msgstr "'IGNORECASE' er en gawk-udvidelse"
-#: eval.c:754
+#: eval.c:736
msgid "`BINMODE' is a gawk extension"
msgstr "'BINMODE' er en gawk-udvidelse"
-#: eval.c:812
+#: eval.c:794
#, c-format
msgid "BINMODE value `%s' is invalid, treated as 3"
-msgstr "BINMODE værdi '%s' er ugyldig, behandles som 3"
+msgstr "BINMODE værdi '%s' er ugyldig, behandles som 3"
-#: eval.c:902
+#: eval.c:885
#, c-format
msgid "bad `%sFMT' specification `%s'"
msgstr "forkert '%sFMT'-specifikation '%s'"
-#: eval.c:980
+#: eval.c:969
msgid "turning off `--lint' due to assignment to `LINT'"
-msgstr "deaktiverer '--lint' på grund af en tildeling til 'LINT'"
-
-#: eval.c:1127 eval.c:1777
-#, c-format
-msgid "can't use function name `%s' as variable or array"
-msgstr "kan ikke bruge funktionsnavnet '%s' som variabel eller array"
+msgstr "deaktiverer '--lint' på grund af en tildeling til 'LINT'"
-#: eval.c:1158 eval.c:1789 eval.c:1802
+#: eval.c:1147
#, c-format
msgid "reference to uninitialized argument `%s'"
msgstr "reference til ikke-initieret argument '%s'"
-#: eval.c:1177
+#: eval.c:1148
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "reference til ikke-initieret variabel '%s'"
+
+#: eval.c:1166
msgid "attempt to field reference from non-numeric value"
-msgstr "forsøg på at referere til et felt fra ikke-numerisk værdi"
+msgstr "forsøg på at referere til et felt fra ikke-numerisk værdi"
-#: eval.c:1179
+#: eval.c:1168
msgid "attempt to field reference from null string"
-msgstr "forsøg på at referere til et felt fra tom streng"
+msgstr "forsøg på at referere til et felt fra tom streng"
-#: eval.c:1185
+#: eval.c:1176
#, c-format
msgid "attempt to access field %ld"
-msgstr "forsøg på at få adgang til felt %ld"
+msgstr "forsøg på at få adgang til felt %ld"
-#: eval.c:1194
+#: eval.c:1185
#, c-format
msgid "reference to uninitialized field `$%ld'"
msgstr "reference til ikke-initieret felt '$%ld'"
-#: eval.c:1256
+#: eval.c:1272
#, c-format
msgid "function `%s' called with more arguments than declared"
msgstr "funktionen '%s' kaldt med flere argumenter end deklareret"
-#: eval.c:1437
+#: eval.c:1473
#, c-format
msgid "unwind_stack: unexpected type `%s'"
msgstr "unwind_stack: uventet type `%s'"
-#: eval.c:1532
+#: eval.c:1569
msgid "division by zero attempted in `/='"
-msgstr "forsøgte at dividere med nul i '/='"
+msgstr "forsøgte at dividere med nul i '/='"
-#: eval.c:1539
+#: eval.c:1576
#, c-format
msgid "division by zero attempted in `%%='"
-msgstr "forsøgte at dividere med nul i '%%='"
-
-#: eval.c:1876 eval.c:2122
-#, c-format
-msgid "attempt to use array `%s[\"%.*s\"]' in a scalar context"
-msgstr "forsøg på at bruge array '%s[\"%.*s\"]' i skalarsammenhæng"
+msgstr "forsøgte at dividere med nul i '%%='"
-#: eval.c:1907
-msgid "assignment used in conditional context"
-msgstr "tildeling brugt i sammenligningsammenhæng"
+#: ext.c:89 ext.c:171
+msgid "extensions are not allowed in sandbox mode"
+msgstr "udvidelser er ikke tilladt i sandkasse-tilstand"
-#: eval.c:1911
-msgid "statement has no effect"
-msgstr "kommandoen har ingen effekt"
+#: ext.c:92
+#, fuzzy
+msgid "-l / @load are gawk extensions"
+msgstr "@include er en gawk-udvidelse"
-#: eval.c:2343
-#, c-format
-msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+#: ext.c:95
+msgid "load_ext: received NULL lib_name"
msgstr ""
-"for-løkke: array '%s' ændrede størrelse fra %ld til %ld under udførelse af "
-"løkken"
-#: eval.c:2458
-#, c-format
-msgid "function called indirectly through `%s' does not exist"
-msgstr "funktion kaldt indirekte via '%s' eksisterer ikke"
-
-#: eval.c:2470
-#, c-format
-msgid "function `%s' not defined"
-msgstr "funktionen '%s' er ikke defineret"
-
-#: eval.c:2511
-#, c-format
-msgid "non-redirected `getline' invalid inside `%s' rule"
-msgstr "ikke-omdirigeret 'getline' ugyldig inden i '%s'-regel"
-
-#: eval.c:2600
-#, c-format
-msgid "error reading input file `%s': %s"
-msgstr "fejl ved læsning af inddatafilen '%s': %s"
+#: ext.c:98
+#, fuzzy, c-format
+msgid "load_ext: cannot open library `%s' (%s)\n"
+msgstr "atalt: extension: kan ikke åbne '%s' (%s)\n"
-#: eval.c:2614
-#, c-format
-msgid "`nextfile' cannot be called from a `%s' rule"
-msgstr "'nextfile' kan ikke kaldes fra en '%s'-regel"
+#: ext.c:104
+#, fuzzy, c-format
+msgid ""
+"load_ext: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"
+msgstr ""
+"fatalt: extension: bibliotek '%s': definer ikke "
+"'plugin_is_GPL_compatible' (%s)\n"
-#: eval.c:2694
-#, c-format
-msgid "`next' cannot be called from a `%s' rule"
-msgstr "'next' kan ikke kaldes fra en '%s'-regel"
+#: ext.c:110
+#, fuzzy, c-format
+msgid "load_ext: library `%s': cannot call function `%s' (%s)\n"
+msgstr ""
+"fatalt: extension: bibliotek '%s': kan ikke kalde funktionen '%s' (%s)\n"
-#: eval.c:2760
+#: ext.c:114
#, c-format
-msgid "Sorry, don't know how to interpret `%s'"
-msgstr "Véd desværre ikke hvordan '%s' skal fortolkes"
-
-#: ext.c:64
-msgid "extensions are not allowed in sandbox mode"
-msgstr "udvidelser er ikke tilladt i sandkasse-tilstand"
+msgid "load_ext: library `%s' initialization routine `%s' failed\n"
+msgstr ""
-#: ext.c:70 ext.c:75
+#: ext.c:174
msgid "`extension' is a gawk extension"
msgstr "'extension' er en gawk-udvidelse"
-#: ext.c:85
-#, c-format
-msgid "fatal: extension: cannot open `%s' (%s)\n"
-msgstr "atalt: extension: kan ikke åbne '%s' (%s)\n"
+#: ext.c:177
+msgid "extension: received NULL lib_name"
+msgstr ""
-#: ext.c:94
-#, c-format
+#: ext.c:180
+#, fuzzy, c-format
+msgid "extension: cannot open library `%s' (%s)"
+msgstr "atalt: extension: kan ikke åbne '%s' (%s)\n"
+
+#: ext.c:186
+#, fuzzy, c-format
msgid ""
-"fatal: extension: library `%s': does not define "
-"`plugin_is_GPL_compatible' (%s)\n"
+"extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)"
msgstr ""
"fatalt: extension: bibliotek '%s': definer ikke "
"'plugin_is_GPL_compatible' (%s)\n"
-#: ext.c:103
-#, c-format
-msgid "fatal: extension: library `%s': cannot call function `%s' (%s)\n"
+#: ext.c:190
+#, fuzzy, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)"
msgstr ""
"fatalt: extension: bibliotek '%s': kan ikke kalde funktionen '%s' (%s)\n"
-#: ext.c:137
-msgid "extension: missing function name"
+#: ext.c:221
+#, fuzzy
+msgid "make_builtin: missing function name"
msgstr "extension: mangler funktionsnavn"
-#: ext.c:142
+#: ext.c:236
+#, fuzzy, c-format
+msgid "make_builtin: can't redefine function `%s'"
+msgstr "extension: kan ikke omdefinere funktion '%s'"
+
+#: ext.c:240
+#, fuzzy, c-format
+msgid "make_builtin: function `%s' already defined"
+msgstr "extension: funktionen '%s' er allerede defineret"
+
+#: ext.c:244
+#, fuzzy, c-format
+msgid "make_builtin: function name `%s' previously defined"
+msgstr "extension: funktionsnavnet '%s' er defineret tidligere"
+
+#: ext.c:246
+#, fuzzy, c-format
+msgid "make_builtin: can't use gawk built-in `%s' as function name"
+msgstr "extension: kan ikke bruge gawk's indbyggede '%s' som funktionsnavn"
+
+#: ext.c:249 ext.c:304
#, c-format
+msgid "make_builtin: negative argument count for function `%s'"
+msgstr "make_builtin: negativt argumentantal for funktion '%s'"
+
+#: ext.c:276
+#, fuzzy
+msgid "extension: missing function name"
+msgstr "extension: mangler funktionsnavn"
+
+#: ext.c:279 ext.c:283
+#, fuzzy, c-format
msgid "extension: illegal character `%c' in function name `%s'"
msgstr "extension: ugyldigt tegn '%c' i funktionsnavn '%s'"
-#: ext.c:151
-#, c-format
+#: ext.c:291
+#, fuzzy, c-format
msgid "extension: can't redefine function `%s'"
msgstr "extension: kan ikke omdefinere funktion '%s'"
-#: ext.c:155
-#, c-format
+#: ext.c:295
+#, fuzzy, c-format
msgid "extension: function `%s' already defined"
msgstr "extension: funktionen '%s' er allerede defineret"
-#: ext.c:160
-#, c-format
+#: ext.c:299
+#, fuzzy, c-format
msgid "extension: function name `%s' previously defined"
-msgstr "extension: funktionsnavnet '%s' er defineret tidligere"
+msgstr "funktionsnavnet '%s' er allerede defineret"
-#: ext.c:162
-#, c-format
+#: ext.c:301
+#, fuzzy, c-format
msgid "extension: can't use gawk built-in `%s' as function name"
msgstr "extension: kan ikke bruge gawk's indbyggede '%s' som funktionsnavn"
-#: ext.c:166
-#, c-format
-msgid "make_builtin: negative argument count for function `%s'"
-msgstr "make_builtin: negativt argumentantal for funktion '%s'"
-
-#: ext.c:269
+#: ext.c:375
#, c-format
msgid "function `%s' defined to take no more than %d argument(s)"
msgstr "funktionen '%s' defineret til at tage ikke mere end %d argumenter"
-#: ext.c:272
+#: ext.c:378
#, c-format
msgid "function `%s': missing argument #%d"
msgstr "funktion '%s': mangler argument nummer %d"
-#: ext.c:289
+#: ext.c:395
#, c-format
msgid "function `%s': argument #%d: attempt to use scalar as an array"
msgstr ""
-"funktion '%s': argument nummer %d: forsøg på at bruge skalar som et array"
+"funktion '%s': argument nummer %d: forsøg på at bruge skalar som et array"
-#: ext.c:293
+#: ext.c:399
#, c-format
msgid "function `%s': argument #%d: attempt to use array as a scalar"
msgstr ""
-"funktion '%s': argument nummer %d: forsøg på at bruge array som en skalar"
+"funktion '%s': argument nummer %d: forsøg på at bruge array som en skalar"
+
+#: ext.c:413
+msgid "dynamic loading of library not supported"
+msgstr ""
+
+#: extension/filefuncs.c:159
+#, fuzzy
+msgid "chdir: called with incorrect number of arguments, expecting 1"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/filefuncs.c:439
+#, c-format
+msgid "stat: unable to read symbolic link `%s'"
+msgstr ""
+
+#: extension/filefuncs.c:472
+#, fuzzy
+msgid "stat: called with wrong number of arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/filefuncs.c:479
+#, fuzzy
+msgid "stat: bad parameters"
+msgstr "%s: er parameter\n"
+
+#: extension/filefuncs.c:533
+#, fuzzy, c-format
+msgid "fts init: could not create variable %s"
+msgstr "indeks: andet argument er ikke en streng"
+
+#: extension/filefuncs.c:554
+#, fuzzy
+msgid "fts is not supported on this system"
+msgstr "'%s' understøttes ikke i gamle versioner af awk"
+
+#: extension/filefuncs.c:573
+msgid "fill_stat_element: could not create array"
+msgstr ""
+
+#: extension/filefuncs.c:582
+msgid "fill_stat_element: could not set element"
+msgstr ""
+
+#: extension/filefuncs.c:597
+#, fuzzy
+msgid "fill_path_element: could not set element"
+msgstr "indeks: andet argument er ikke en streng"
+
+#: extension/filefuncs.c:613
+msgid "fill_error_element: could not set element"
+msgstr ""
+
+#: extension/filefuncs.c:660 extension/filefuncs.c:707
+msgid "fts-process: could not create array"
+msgstr ""
+
+#: extension/filefuncs.c:670 extension/filefuncs.c:717
+#: extension/filefuncs.c:735
+#, fuzzy
+msgid "fts-process: could not set element"
+msgstr "indeks: andet argument er ikke en streng"
+
+#: extension/filefuncs.c:784
+#, fuzzy
+msgid "fts: called with incorrect number of arguments, expecting 3"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/filefuncs.c:787
+#, fuzzy
+msgid "fts: bad first parameter"
+msgstr "%s: er parameter\n"
+
+#: extension/filefuncs.c:793
+#, fuzzy
+msgid "fts: bad second parameter"
+msgstr "%s: er parameter\n"
+
+#: extension/filefuncs.c:799
+#, fuzzy
+msgid "fts: bad third parameter"
+msgstr "%s: er parameter\n"
+
+#: extension/filefuncs.c:806
+#, fuzzy
+msgid "fts: could not flatten array\n"
+msgstr "'%s' er ikke et gyldigt variabelnavn"
+
+#: extension/filefuncs.c:824
+msgid "fts: ignoring sneaky FTS_NOSTAT flag. nyah, nyah, nyah."
+msgstr ""
+
+#: extension/filefuncs.c:841
+msgid "fts: clear_array() failed\n"
+msgstr ""
+
+#: extension/fnmatch.c:112
+#, fuzzy
+msgid "fnmatch: called with less than three arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/fnmatch.c:115
+#, fuzzy
+msgid "fnmatch: called with more than three arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/fnmatch.c:118
+#, fuzzy
+msgid "fnmatch: could not get first argument"
+msgstr "strftime: fik et første argument som ikke er en streng"
+
+#: extension/fnmatch.c:123
+#, fuzzy
+msgid "fnmatch: could not get second argument"
+msgstr "indeks: andet argument er ikke en streng"
+
+#: extension/fnmatch.c:128
+msgid "fnmatch: could not get third argument"
+msgstr ""
+
+#: extension/fnmatch.c:141
+msgid "fnmatch is not implemented on this system\n"
+msgstr ""
+
+#: extension/fnmatch.c:173
+msgid "fnmatch init: could not add FNM_NOMATCH variable"
+msgstr ""
+
+#: extension/fnmatch.c:183
+#, c-format
+msgid "fnmatch init: could not set array element %s"
+msgstr ""
+
+#: extension/fnmatch.c:193
+msgid "fnmatch init: could not install FNM array"
+msgstr ""
+
+#: extension/fork.c:81
+#, fuzzy
+msgid "fork: called with too many arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/fork.c:94
+msgid "fork: PROCINFO is not an array!"
+msgstr ""
+
+#: extension/fork.c:118
+#, fuzzy
+msgid "waitpid: called with too many arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/fork.c:126
+#, fuzzy
+msgid "wait: called with no arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/fork.c:143
+#, fuzzy
+msgid "wait: called with too many arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/inplace.c:130
+msgid "inplace_begin: in-place editing already active"
+msgstr ""
-#: ext.c:306
-msgid "Operation Not Supported"
-msgstr "Operationen understøttes ikke"
+#: extension/inplace.c:133 extension/inplace.c:207
+#, c-format
+msgid "inplace_begin: expects 2 arguments but called with %d"
+msgstr ""
+
+#: extension/inplace.c:136
+msgid "inplace_begin: cannot retrieve 1st argument as a string filename"
+msgstr ""
+
+#: extension/inplace.c:144
+#, c-format
+msgid "inplace_begin: disabling in-place editing for invalid FILENAME `%s'"
+msgstr ""
+
+#: extension/inplace.c:151
+#, fuzzy, c-format
+msgid "inplace_begin: Cannot stat `%s' (%s)"
+msgstr "atalt: extension: kan ikke åbne '%s' (%s)\n"
+
+#: extension/inplace.c:158
+#, fuzzy, c-format
+msgid "inplace_begin: `%s' is not a regular file"
+msgstr "'%s' er ikke et gyldigt variabelnavn"
+
+#: extension/inplace.c:169
+#, c-format
+msgid "inplace_begin: mkstemp(`%s') failed (%s)"
+msgstr ""
-#: field.c:328
+#: extension/inplace.c:178
+#, fuzzy, c-format
+msgid "inplace_begin: chmod failed (%s)"
+msgstr "%s: lukning mislykkedes (%s)"
+
+#: extension/inplace.c:185
+#, c-format
+msgid "inplace_begin: dup(stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:188
+#, c-format
+msgid "inplace_begin: dup2(%d, stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:191
+#, fuzzy, c-format
+msgid "inplace_begin: close(%d) failed (%s)"
+msgstr "%s: lukning mislykkedes (%s)"
+
+#: extension/inplace.c:210
+msgid "inplace_end: cannot retrieve 1st argument as a string filename"
+msgstr ""
+
+#: extension/inplace.c:217
+msgid "inplace_end: in-place editing not active"
+msgstr ""
+
+#: extension/inplace.c:223
+#, c-format
+msgid "inplace_end: dup2(%d, stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:226
+#, fuzzy, c-format
+msgid "inplace_end: close(%d) failed (%s)"
+msgstr "%s: lukning mislykkedes (%s)"
+
+#: extension/inplace.c:230
+#, c-format
+msgid "inplace_end: fsetpos(stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:243
+#, fuzzy, c-format
+msgid "inplace_end: link(`%s', `%s') failed (%s)"
+msgstr "datakanalsrensning af '%s' mislykkedes (%s)."
+
+#: extension/inplace.c:253
+#, fuzzy, c-format
+msgid "inplace_end: rename(`%s', `%s') failed (%s)"
+msgstr "lukning af fd %d ('%s') mislykkedes (%s)"
+
+#: extension/ordchr.c:69
+#, fuzzy
+msgid "ord: called with too many arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/ordchr.c:75
+#, fuzzy
+msgid "ord: called with no arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/ordchr.c:77
+#, fuzzy
+msgid "ord: called with inappropriate argument(s)"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/ordchr.c:99
+#, fuzzy
+msgid "chr: called with too many arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/ordchr.c:109
+#, fuzzy
+msgid "chr: called with no arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/ordchr.c:111
+#, fuzzy
+msgid "chr: called with inappropriate argument(s)"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/readdir.c:281
+#, c-format
+msgid "dir_take_control_of: opendir/fdopendir failed: %s"
+msgstr ""
+
+#: extension/readfile.c:113
+#, fuzzy
+msgid "readfile: called with too many arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/readfile.c:137
+#, fuzzy
+msgid "readfile: called with no arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/rwarray.c:124
+#, fuzzy
+msgid "writea: called with too many arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/rwarray.c:131
+#, fuzzy, c-format
+msgid "do_writea: argument 0 is not a string\n"
+msgstr "exp: argumentet %g er uden for det tilladte område\n"
+
+#: extension/rwarray.c:137
+#, fuzzy, c-format
+msgid "do_writea: argument 1 is not an array\n"
+msgstr "split: fjerde argument er ikke et array\n"
+
+#: extension/rwarray.c:184
+#, c-format
+msgid "write_array: could not flatten array\n"
+msgstr ""
+
+#: extension/rwarray.c:198
+#, c-format
+msgid "write_array: could not release flattened array\n"
+msgstr ""
+
+#: extension/rwarray.c:280
+#, fuzzy
+msgid "reada: called with too many arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/rwarray.c:287
+#, fuzzy, c-format
+msgid "do_reada: argument 0 is not a string\n"
+msgstr "exp: argumentet %g er uden for det tilladte område"
+
+#: extension/rwarray.c:293
+#, fuzzy, c-format
+msgid "do_reada: argument 1 is not an array\n"
+msgstr "match: tredje argument er ikke et array"
+
+#: extension/rwarray.c:337
+#, c-format
+msgid "do_reada: clear_array failed\n"
+msgstr ""
+
+#: extension/rwarray.c:374
+#, c-format
+msgid "read_array: set_array_element failed\n"
+msgstr ""
+
+#: extension/time.c:113
+#, fuzzy
+msgid "gettimeofday: ignoring arguments"
+msgstr "mktime: fik et argument som ikke er en streng"
+
+#: extension/time.c:144
+msgid "gettimeofday: not supported on this platform"
+msgstr ""
+
+#: extension/time.c:165
+#, fuzzy
+msgid "sleep: called with too many arguments"
+msgstr "sqrt: kaldt med negativt argument %g"
+
+#: extension/time.c:168
+#, fuzzy
+msgid "sleep: missing required numeric argument"
+msgstr "exp: fik et ikke-numerisk argument"
+
+#: extension/time.c:174
+#, fuzzy
+msgid "sleep: argument is negative"
+msgstr "exp: argumentet %g er uden for det tilladte område"
+
+#: extension/time.c:208
+msgid "sleep: not supported on this platform"
+msgstr ""
+
+#: field.c:345
msgid "NF set to negative value"
-msgstr "NF sat til en negativ værdi"
+msgstr "NF sat til en negativ værdi"
-#: field.c:951 field.c:958 field.c:962
+#: field.c:971 field.c:978 field.c:982
msgid "split: fourth argument is a gawk extension"
msgstr "split: fjerde argument er en gawk-udvidelse"
-#: field.c:955
+#: field.c:975
msgid "split: fourth argument is not an array"
msgstr "split: fjerde argument er ikke et array"
-#: field.c:969
+#: field.c:989
msgid "split: second argument is not an array"
msgstr "split: andet argument er ikke et array"
-#: field.c:973
+#: field.c:993
msgid "split: cannot use the same array for second and fourth args"
msgstr "split: kan ikke bruge det samme array som andet og fjerde argument"
-#: field.c:978
+#: field.c:998
msgid "split: cannot use a subarray of second arg for fourth arg"
msgstr ""
"split: kan ikke bruge et underarray af andet argument som fjerde argument"
-#: field.c:981
+#: field.c:1001
msgid "split: cannot use a subarray of fourth arg for second arg"
msgstr ""
"split: kan ikke bruge et underarray af fjerde argument som andet argument"
-#: field.c:1010
+#: field.c:1032
msgid "split: null string for third arg is a gawk extension"
msgstr "split: tom streng som tredje argument er en gawk-udvidelse"
-#: field.c:1050
+#: field.c:1072
msgid "patsplit: fourth argument is not an array"
msgstr "patsplit: fjerde argument er ikke et array"
-#: field.c:1055
+#: field.c:1077
msgid "patsplit: second argument is not an array"
msgstr "patsplit: andet argument er ikke et array"
-#: field.c:1061
+#: field.c:1083
msgid "patsplit: third argument must be non-null"
msgstr "patmatch: tredje argument er ikke et array"
-#: field.c:1065
+#: field.c:1087
msgid "patsplit: cannot use the same array for second and fourth args"
msgstr "patsplit: kan ikke bruge det samme array som andet og fjerde argument"
-#: field.c:1070
+#: field.c:1092
msgid "patsplit: cannot use a subarray of second arg for fourth arg"
msgstr ""
"patsplit: kan ikke bruge et underarray af andet argument som fjerde argument"
-#: field.c:1073
+#: field.c:1095
msgid "patsplit: cannot use a subarray of fourth arg for second arg"
msgstr ""
"patsplit: kan ikke bruge et underarray af fjerde argument som andet argument"
-#: field.c:1110
+#: field.c:1133
msgid "`FIELDWIDTHS' is a gawk extension"
msgstr "'FIELDWIDTHS' er en gawk-udvidelse"
-#: field.c:1173
+#: field.c:1197
#, c-format
msgid "invalid FIELDWIDTHS value, near `%s'"
-msgstr "ugyldig FIELDWIDTHS værdi, nær '%s"
+msgstr "ugyldig FIELDWIDTHS værdi, nær '%s"
-#: field.c:1246
+#: field.c:1270
msgid "null string for `FS' is a gawk extension"
msgstr "tom streng som 'FS' er en gawk-udvidelse"
-#: field.c:1250
+#: field.c:1274
msgid "old awk does not support regexps as value of `FS'"
-msgstr "gamle versioner af awk understøtter ikke regexp'er som værdi for 'FS'"
+msgstr "gamle versioner af awk understøtter ikke regexp'er som værdi for 'FS'"
-#: field.c:1369
+#: field.c:1393
msgid "`FPAT' is a gawk extension"
msgstr "'FPAT' er en gawk-udvidelse"
-#: getopt.c:574 getopt.c:590
+#: gawkapi.c:146
+msgid "awk_value_to_node: received null retval"
+msgstr ""
+
+#: gawkapi.c:384
+msgid "node_to_awk_value: received null node"
+msgstr ""
+
+#: gawkapi.c:387
+msgid "node_to_awk_value: received null val"
+msgstr ""
+
+#: gawkapi.c:807
+#, fuzzy
+msgid "remove_element: received null array"
+msgstr "length: fik et array-argument"
+
+#: gawkapi.c:810
+msgid "remove_element: received null subscript"
+msgstr ""
+
+#: gawkapi.c:947
#, c-format
-msgid "%s: option '%s' is ambiguous\n"
+msgid "api_flatten_array: could not convert index %d\n"
+msgstr ""
+
+#: gawkapi.c:952
+#, c-format
+msgid "api_flatten_array: could not convert value %d\n"
+msgstr ""
+
+#: getopt.c:604 getopt.c:633
+#, fuzzy, c-format
+msgid "%s: option '%s' is ambiguous; possibilities:"
msgstr "%s: flaget '%s' er flertydigt\n"
-#: getopt.c:623 getopt.c:627
+#: getopt.c:679 getopt.c:683
#, 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
+#: getopt.c:692 getopt.c:697
#, 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:684 getopt.c:703
+#: getopt.c:740 getopt.c:759
#, c-format
msgid "%s: option '--%s' requires an argument\n"
-msgstr "%s: flaget '--%s' kræver et argument\n"
+msgstr "%s: flaget '--%s' kræver et argument\n"
-#: getopt.c:741 getopt.c:744
+#: getopt.c:797 getopt.c:800
#, c-format
msgid "%s: unrecognized option '--%s'\n"
msgstr "%s: ukendt flag '--%s'\n"
-#: getopt.c:752 getopt.c:755
+#: getopt.c:808 getopt.c:811
#, c-format
msgid "%s: unrecognized option '%c%s'\n"
msgstr "%s: ukendt flag '%c%s'\n"
-#: getopt.c:804 getopt.c:807
+#: getopt.c:860 getopt.c:863
#, c-format
msgid "%s: invalid option -- '%c'\n"
msgstr "%s: ugyldigt flag - '%c'\n"
-#: getopt.c:857 getopt.c:874 getopt.c:1082 getopt.c:1100
+#: getopt.c:916 getopt.c:933 getopt.c:1143 getopt.c:1161
#, c-format
msgid "%s: option requires an argument -- '%c'\n"
-msgstr "%s: flaget kræver et argument - '%c'\n"
+msgstr "%s: flaget kræver et argument - '%c'\n"
-#: getopt.c:930 getopt.c:946
+#: getopt.c:989 getopt.c:1005
#, c-format
msgid "%s: option '-W %s' is ambiguous\n"
msgstr "%s: flaget '-W %s' er flertydigt\n"
-#: getopt.c:970 getopt.c:988
+#: getopt.c:1029 getopt.c:1047
#, c-format
msgid "%s: option '-W %s' doesn't allow an argument\n"
msgstr "%s: flaget '-W %s' tillader ikke noget argument\n"
-#: getopt.c:1009 getopt.c:1027
+#: getopt.c:1068 getopt.c:1086
#, c-format
msgid "%s: option '-W %s' requires an argument\n"
-msgstr "%s: flaget '-W %s' kræver et argument\n"
+msgstr "%s: flaget '-W %s' kræver et argument\n"
-#: io.c:280
+#: io.c:392
#, c-format
msgid "command line argument `%s' is a directory: skipped"
msgstr "kommandolinjeargument '%s' er et katalog, oversprunget"
-#: io.c:283 io.c:385
+#: io.c:395 io.c:513
#, c-format
msgid "cannot open file `%s' for reading (%s)"
-msgstr "kan ikke åbne filen '%s' for læsning (%s)"
+msgstr "kan ikke åbne filen '%s' for læsning (%s)"
-#: io.c:501
+#: io.c:640
#, c-format
msgid "close of fd %d (`%s') failed (%s)"
msgstr "lukning af fd %d ('%s') mislykkedes (%s)"
-#: io.c:578
+#: io.c:716
msgid "redirection not allowed in sandbox mode"
msgstr "omdirigering ikke tilladt i sandkasse-tilstand"
-#: io.c:612
+#: io.c:750
#, c-format
msgid "expression in `%s' redirection only has numeric value"
-msgstr "udtrykket i '%s'-omdirigering har kun numerisk værdi"
+msgstr "udtrykket i '%s'-omdirigering har kun numerisk værdi"
-#: io.c:618
+#: io.c:756
#, c-format
msgid "expression for `%s' redirection has null string value"
-msgstr "udtrykket for '%s'-omdirigering har en tom streng som værdi"
+msgstr "udtrykket for '%s'-omdirigering har en tom streng som værdi"
-#: io.c:624
+#: io.c:761
#, 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"
+"filnavnet '%s' for '%s'-omdirigering kan være resultatet af et logisk udtryk"
-#: io.c:667
+#: io.c:809
#, c-format
msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
-msgstr "unødig blanding af '>' og '>>' for filen '%.*s'"
+msgstr "unødig blanding af '>' og '>>' for filen '%.*s'"
-#: io.c:720
+#: io.c:863
#, c-format
msgid "can't open pipe `%s' for output (%s)"
-msgstr "kan ikke åbne datakanalen '%s' for udskrivning (%s)"
+msgstr "kan ikke åbne datakanalen '%s' for udskrivning (%s)"
-#: io.c:730
+#: io.c:873
#, c-format
msgid "can't open pipe `%s' for input (%s)"
-msgstr "kan ikke åbne datakanalen '%s' for indtastning (%s)"
+msgstr "kan ikke åbne datakanalen '%s' for indtastning (%s)"
-#: io.c:753
+#: io.c:904
#, c-format
msgid "can't open two way pipe `%s' for input/output (%s)"
-msgstr "kan ikke åbne tovejsdatakanalen '%s' for ind-/uddata (%s)"
+msgstr "kan ikke åbne tovejsdatakanalen '%s' for ind-/uddata (%s)"
-#: io.c:835
+#: io.c:986
#, c-format
msgid "can't redirect from `%s' (%s)"
msgstr "kan ikke omdirigere fra '%s' (%s)"
-#: io.c:838
+#: io.c:989
#, c-format
msgid "can't redirect to `%s' (%s)"
msgstr "kan ikke omdirigere til '%s' (%s)"
-#: io.c:889
+#: io.c:1040
msgid ""
"reached system limit for open files: starting to multiplex file descriptors"
msgstr ""
-"nåede systembegrænsningen for åbne filer: begynder at multiplekse "
+"nåede systembegrænsningen for åbne filer: begynder at multiplekse "
"fildeskriptorer"
-#: io.c:905
+#: io.c:1056
#, c-format
msgid "close of `%s' failed (%s)."
msgstr "lukning af '%s' mislykkedes (%s)."
-#: io.c:913
+#: io.c:1064
msgid "too many pipes or input files open"
-msgstr "for mange datakanaler eller inddatafiler åbne"
+msgstr "for mange datakanaler eller inddatafiler åbne"
-#: io.c:935
+#: io.c:1086
msgid "close: second argument must be `to' or `from'"
-msgstr "close: andet argument skal være 'to' eller 'from'"
+msgstr "close: andet argument skal være 'to' eller 'from'"
-#: io.c:952
+#: io.c:1103
#, 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"
+msgstr "close: '%.*s' er ikke en åben fil, datakanal eller ko-proces"
-#: io.c:957
+#: io.c:1108
msgid "close of redirection that was never opened"
-msgstr "lukning af omdirigering som aldrig blev åbnet"
+msgstr "lukning af omdirigering som aldrig blev åbnet"
-#: io.c:1054
+#: io.c:1205
#, c-format
msgid "close: redirection `%s' not opened with `|&', second argument ignored"
msgstr ""
-"close: omdirigeringen '%s' blev ikke åbnet med '|&', andet argument ignoreret"
+"close: omdirigeringen '%s' blev ikke åbnet med '|&', andet argument ignoreret"
-#: io.c:1070
+#: io.c:1222
#, c-format
msgid "failure status (%d) on pipe close of `%s' (%s)"
msgstr "fejlstatus (%d) fra lukning af datakanalen '%s' (%s)"
-#: io.c:1073
+#: io.c:1225
#, c-format
msgid "failure status (%d) on file close of `%s' (%s)"
msgstr "fejlstatus (%d) fra fillukning af '%s' (%s)"
-#: io.c:1093
+#: io.c:1245
#, c-format
msgid "no explicit close of socket `%s' provided"
msgstr "ingen eksplicit lukning af soklen '%s' angivet"
-#: io.c:1096
+#: io.c:1248
#, c-format
msgid "no explicit close of co-process `%s' provided"
msgstr "ingen eksplicit lukning af ko-processen '%s' angivet"
-#: io.c:1099
+#: io.c:1251
#, c-format
msgid "no explicit close of pipe `%s' provided"
msgstr "ingen eksplicit lukning af datakanalen '%s' angivet"
-#: io.c:1102
+#: io.c:1254
#, c-format
msgid "no explicit close of file `%s' provided"
msgstr "ingen eksplicit lukning af filen '%s' angivet"
-#: io.c:1130 io.c:1185 main.c:793 main.c:830
+#: io.c:1284 io.c:1342 main.c:864 main.c:906
#, c-format
msgid "error writing standard output (%s)"
msgstr "fejl ved skrivning til standard ud (%s)"
-#: io.c:1134 io.c:1190
+#: io.c:1289 io.c:1348 main.c:866
#, c-format
msgid "error writing standard error (%s)"
msgstr "fejl ved skrivning til standard fejl (%s)"
-#: io.c:1142
+#: io.c:1297
#, c-format
msgid "pipe flush of `%s' failed (%s)."
msgstr "datakanalsrensning af '%s' mislykkedes (%s)."
-#: io.c:1145
+#: io.c:1300
#, c-format
msgid "co-process flush of pipe to `%s' failed (%s)."
msgstr "ko-procesrensning af datakanalen til '%s' mislykkedes (%s)."
-#: io.c:1148
+#: io.c:1303
#, c-format
msgid "file flush of `%s' failed (%s)."
msgstr "filrensning af '%s' mislykkedes (%s)."
-#: io.c:1263
+#: io.c:1420
#, c-format
msgid "local port %s invalid in `/inet'"
msgstr "lokal port %s ugyldig i '/inet'"
-#: io.c:1280
+#: io.c:1438
#, c-format
msgid "remote host and port information (%s, %s) invalid"
-msgstr "fjernvært og portinformation (%s, %s) ugyldige"
+msgstr "fjernvært og portinformation (%s, %s) ugyldige"
-#: io.c:1432
+#: io.c:1590
#, c-format
msgid "no (known) protocol supplied in special filename `%s'"
msgstr "ingen (kendt) protokol opgivet i special-filnavn '%s'"
-#: io.c:1446
+#: io.c:1604
#, c-format
msgid "special file name `%s' is incomplete"
-msgstr "special-filnavn '%s' er ufuldstændigt"
+msgstr "special-filnavn '%s' er ufuldstændigt"
-#: io.c:1463
+#: io.c:1621
msgid "must supply a remote hostname to `/inet'"
msgstr "fjernmaskinenavn til '/inet' skal angives"
-#: io.c:1481
+#: io.c:1639
msgid "must supply a remote port to `/inet'"
msgstr "fjernport til '/inet' skal angives"
-#: io.c:1527
+#: io.c:1685
msgid "TCP/IP communications are not supported"
-msgstr "TCP/IP-kommunikation understøttes ikke"
+msgstr "TCP/IP-kommunikation understøttes ikke"
-#: io.c:1694
+#: io.c:1867
#, c-format
msgid "could not open `%s', mode `%s'"
-msgstr "kunne ikke åbne '%s', tilstand '%s'"
+msgstr "kunne ikke åbne '%s', tilstand '%s'"
-#: io.c:1748
+#: io.c:1917
#, c-format
msgid "close of master pty failed (%s)"
msgstr "lukning af master-pty mislykkedes (%s)"
-#: io.c:1750 io.c:1918 io.c:2075
+#: io.c:1919 io.c:2105 io.c:2305
#, c-format
msgid "close of stdout in child failed (%s)"
msgstr "lukning af standard ud i underproces mislykkedes (%s)"
-#: io.c:1753
+#: io.c:1922
#, c-format
msgid "moving slave pty to stdout in child failed (dup: %s)"
msgstr ""
"flytning af slave-pty til standard ud i underproces mislykkedes (dup: %s)"
-#: io.c:1755 io.c:1923
+#: io.c:1924 io.c:2110
#, c-format
msgid "close of stdin in child failed (%s)"
msgstr "lukning af standard ind i underproces mislykkedes (%s)"
-#: io.c:1758
+#: io.c:1927
#, c-format
msgid "moving slave pty to stdin in child failed (dup: %s)"
msgstr ""
"flytning af slave-pty til standard ind i underproces mislykkedes (dup: %s)"
-#: io.c:1760 io.c:1781
+#: io.c:1929 io.c:1951
#, c-format
msgid "close of slave pty failed (%s)"
msgstr "lukning af slave-pty mislykkedes (%s)"
-#: io.c:1859 io.c:1921 io.c:2053 io.c:2078
+#: io.c:2040 io.c:2108 io.c:2276 io.c:2308
#, c-format
msgid "moving pipe to stdout in child failed (dup: %s)"
msgstr ""
"flytning af datakanal til standard ud i underproces mislykkedes (dup: %s)"
-#: io.c:1866 io.c:1926
+#: io.c:2047 io.c:2113
#, c-format
msgid "moving pipe to stdin in child failed (dup: %s)"
msgstr ""
"flytning af datakanalen til standard ind i underproces mislykkedes (dup: %s)"
-#: io.c:1886 io.c:2068
+#: io.c:2073 io.c:2298
msgid "restoring stdout in parent process failed\n"
-msgstr "genskabelse af standard ud i forælderprocessen mislykkedes\n"
+msgstr "genskabelse af standard ud i forælderprocessen mislykkedes\n"
-#: io.c:1894
+#: io.c:2081
msgid "restoring stdin in parent process failed\n"
-msgstr "genskabelse af standard ind i forælderprocessen mislykkedes\n"
+msgstr "genskabelse af standard ind i forælderprocessen mislykkedes\n"
-#: io.c:1929 io.c:2080 io.c:2094
+#: io.c:2116 io.c:2310 io.c:2324
#, c-format
msgid "close of pipe failed (%s)"
msgstr "lukning af datakanalen mislykkedes (%s)"
-#: io.c:1974
+#: io.c:2174
msgid "`|&' not supported"
-msgstr "'|&' understøttes ikke"
+msgstr "'|&' understøttes ikke"
-#: io.c:2040
+#: io.c:2261
#, c-format
msgid "cannot open pipe `%s' (%s)"
-msgstr "kan ikke åbne datakanalen '%s' (%s)"
+msgstr "kan ikke åbne datakanalen '%s' (%s)"
-#: io.c:2088
+#: io.c:2318
#, c-format
msgid "cannot create child process for `%s' (fork: %s)"
msgstr "kan ikke oprette barneproces for '%s' (fork: %s)"
-#: io.c:2521
+#: io.c:2790
+msgid "register_input_parser: received NULL pointer"
+msgstr ""
+
+#: io.c:2818
+#, c-format
+msgid "input parser `%s' conflicts with previously installed input parser `%s'"
+msgstr ""
+
+#: io.c:2825
+#, c-format
+msgid "input parser `%s' failed to open `%s'"
+msgstr ""
+
+#: io.c:2845
+msgid "register_output_wrapper: received NULL pointer"
+msgstr ""
+
+#: io.c:2873
+#, c-format
+msgid ""
+"output wrapper `%s' conflicts with previously installed output wrapper `%s'"
+msgstr ""
+
+#: io.c:2880
+#, c-format
+msgid "output wrapper `%s' failed to open `%s'"
+msgstr ""
+
+#: io.c:2901
+msgid "register_output_processor: received NULL pointer"
+msgstr ""
+
+#: io.c:2930
+#, c-format
+msgid ""
+"two-way processor `%s' conflicts with previously installed two-way processor "
+"`%s'"
+msgstr ""
+
+#: io.c:2939
+#, c-format
+msgid "two way processor `%s' failed to open `%s'"
+msgstr ""
+
+#: io.c:3064
#, c-format
msgid "data file `%s' is empty"
msgstr "datafilen '%s' er tom"
-#: io.c:2562 io.c:2570
+#: io.c:3106 io.c:3114
msgid "could not allocate more input memory"
msgstr "kunne ikke allokere mere hukommelse til inddata"
-#: io.c:3128
+#: io.c:3682
msgid "multicharacter value of `RS' is a gawk extension"
-msgstr "'RS' som flertegnsværdi er en gawk-udvidelse"
+msgstr "'RS' som flertegnsværdi er en gawk-udvidelse"
-#: io.c:3233
+#: io.c:3771
msgid "IPv6 communication is not supported"
-msgstr "IPv6-kommunikation understøttes ikke"
+msgstr "IPv6-kommunikation understøttes ikke"
-#: main.c:364
-msgid "`-m[fr]' option irrelevant in gawk"
-msgstr "'-m[fr]'-flaget er irrelevant i gawk"
-
-#: main.c:366
-msgid "-m option usage: `-m[fr] nnn'"
-msgstr "brug af flaget -m: '-m[fr] nnn'"
-
-#: main.c:389
+#: main.c:405
msgid "empty argument to `-e/--source' ignored"
msgstr "tomt argument til '-e/--source' ignoreret"
-#: main.c:460
+#: main.c:495
#, c-format
msgid "%s: option `-W %s' unrecognized, ignored\n"
msgstr "%s: flaget '-W %s' ukendt, ignoreret\n"
-#: main.c:513
+#: main.c:541
#, c-format
msgid "%s: option requires an argument -- %c\n"
-msgstr "%s: flaget kræver et argument -- %c\n"
+msgstr "%s: flaget kræver et argument -- %c\n"
-#: main.c:534
+#: main.c:562
msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
-msgstr "miljøvariablen 'POSIXLY_CORRECT' sat: aktiverer '--posix'"
+msgstr "miljøvariablen 'POSIXLY_CORRECT' sat: aktiverer '--posix'"
-#: main.c:540
+#: main.c:568
msgid "`--posix' overrides `--traditional'"
-msgstr "'--posix' tilsidesætter '--traditional'"
+msgstr "'--posix' tilsidesætter '--traditional'"
-#: main.c:551
+#: main.c:579
msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
-msgstr "'--posix'/'--traditional' tilsidesætter '--non-decimal-data'"
+msgstr "'--posix'/'--traditional' tilsidesætter '--non-decimal-data'"
-#: main.c:555
+#: main.c:583
#, c-format
msgid "running %s setuid root may be a security problem"
-msgstr "at køre %s setuid root kan være et sikkerhedsproblem"
+msgstr "at køre %s setuid root kan være et sikkerhedsproblem"
-#: main.c:560
-msgid "`--posix' overrides `--binary'"
-msgstr "'--posix' tilsidesætter '--binary'"
+#: main.c:588
+#, fuzzy
+msgid "`--posix' overrides `--characters-as-bytes'"
+msgstr "'--posix' tilsidesætter '--binary'"
-#: main.c:611
+#: main.c:647
#, c-format
msgid "can't set binary mode on stdin (%s)"
-msgstr "kan ikke sætte binær tilstand på standard ind (%s)"
+msgstr "kan ikke sætte binær tilstand på standard ind (%s)"
-#: main.c:614
+#: main.c:650
#, c-format
msgid "can't set binary mode on stdout (%s)"
-msgstr "kan ikke sætte binær tilstand på standard ud (%s)"
+msgstr "kan ikke sætte binær tilstand på standard ud (%s)"
-#: main.c:616
+#: main.c:652
#, c-format
msgid "can't set binary mode on stderr (%s)"
-msgstr "kan ikke sætte binær tilstand på standard fejl (%s)"
+msgstr "kan ikke sætte binær tilstand på standard fejl (%s)"
-#: main.c:655
+#: main.c:710
msgid "no program text at all!"
msgstr "ingen programtekst overhovedet!"
-#: main.c:733
+#: main.c:799
#, c-format
msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
msgstr "Brug: %s [flag i POSIX- eller GNU-stil] -f progfil [--] fil ...\n"
-#: main.c:735
+#: main.c:801
#, c-format
msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
msgstr "Brug: %s [flag i POSIX- eller GNU-stil] %cprogram%c fil ...\n"
-#: main.c:740
+#: main.c:806
msgid "POSIX options:\t\tGNU long options: (standard)\n"
msgstr "POSIX-flag:\t\tlange GNU-flag: (standard)\n"
-#: main.c:741
+#: main.c:807
msgid "\t-f progfile\t\t--file=progfile\n"
msgstr "\t-f progfil\t\t--file=progfil\n"
-#: main.c:742
+#: main.c:808
msgid "\t-F fs\t\t\t--field-separator=fs\n"
msgstr "\t-F fs\t\t\t--field-separator=fs\n"
-#: main.c:743
+#: main.c:809
msgid "\t-v var=val\t\t--assign=var=val\n"
-msgstr "\t-v var=værdi\t\t--assign=var=værdi\n"
+msgstr "\t-v var=værdi\t\t--assign=var=værdi\n"
-#: main.c:744
+#: main.c:810
msgid "Short options:\t\tGNU long options: (extensions)\n"
msgstr "POSIX-flag:\t\tlange GNU-flag: (udvidelser)\n"
-#: main.c:745
+#: main.c:811
msgid "\t-b\t\t\t--characters-as-bytes\n"
msgstr "\t-b\t\t\t--characters-as-bytes\n"
-#: main.c:746
+#: main.c:812
msgid "\t-c\t\t\t--traditional\n"
msgstr "\t-c\t\t\t--traditional\n"
-#: main.c:747
+#: main.c:813
msgid "\t-C\t\t\t--copyright\n"
msgstr "\t-C\t\t\t--copyright\n"
-#: main.c:748
+#: main.c:814
msgid "\t-d[file]\t\t--dump-variables[=file]\n"
msgstr "\t-d[fil]\t\t--dump-variables[=fil]\n"
-#: main.c:749
+#: main.c:815
+#, fuzzy
+msgid "\t-D[file]\t\t--debug[=file]\n"
+msgstr "\t-p[fil]\t\t--profile[=fil]\n"
+
+#: main.c:816
msgid "\t-e 'program-text'\t--source='program-text'\n"
msgstr "\t-e 'programtekst'\t--source='programtekst'\n"
-#: main.c:750
+#: main.c:817
msgid "\t-E file\t\t\t--exec=file\n"
msgstr "\t-E fil\t\t\t--exec=fil\n"
-#: main.c:751
+#: main.c:818
msgid "\t-g\t\t\t--gen-pot\n"
msgstr "\t-g\t\t\t--gen-pot\n"
-#: main.c:752
+#: main.c:819
msgid "\t-h\t\t\t--help\n"
msgstr "\t-h\t\t\t--help\n"
-#: main.c:753
+#: main.c:820
+msgid "\t-i includefile\t\t--include=includefile\n"
+msgstr ""
+
+#: main.c:821
+msgid "\t-l library\t\t--load=library\n"
+msgstr ""
+
+#: main.c:822
msgid "\t-L [fatal]\t\t--lint[=fatal]\n"
msgstr "\t-L [fatal]\t\t--lint[=fatal]\n"
-#: main.c:754
+#: main.c:823
msgid "\t-n\t\t\t--non-decimal-data\n"
msgstr "\t-n\t\t\t--non-decimal-data\n"
-#: main.c:755
+#: main.c:824
+#, fuzzy
+msgid "\t-M\t\t\t--bignum\n"
+msgstr "\t-g\t\t\t--gen-pot\n"
+
+#: main.c:825
msgid "\t-N\t\t\t--use-lc-numeric\n"
msgstr "\t-N\t\t\t--use-lc-numeric\n"
-#: main.c:756
+#: main.c:826
+#, fuzzy
+msgid "\t-o[file]\t\t--pretty-print[=file]\n"
+msgstr "\t-p[fil]\t\t--profile[=fil]\n"
+
+#: main.c:827
msgid "\t-O\t\t\t--optimize\n"
msgstr "\t-O\t\t\t--optimize\n"
-#: main.c:757
+#: main.c:828
msgid "\t-p[file]\t\t--profile[=file]\n"
msgstr "\t-p[fil]\t\t--profile[=fil]\n"
-#: main.c:758
+#: main.c:829
msgid "\t-P\t\t\t--posix\n"
msgstr "\t-P\t\t\t--posix\n"
-#: main.c:759
+#: main.c:830
msgid "\t-r\t\t\t--re-interval\n"
msgstr "\t-r\t\t\t--re-interval\n"
-#: main.c:761
-msgid "\t-R file\t\t\t--command=file\n"
-msgstr "\t-R file\t\t\t--command=fil\n"
-
-#: main.c:762
+#: main.c:831
msgid "\t-S\t\t\t--sandbox\n"
msgstr "\t-S\t\t\t--sandbox\n"
-#: main.c:763
+#: main.c:832
msgid "\t-t\t\t\t--lint-old\n"
msgstr "\t-t\t\t\t--lint-old\n"
-#: main.c:764
+#: main.c:833
msgid "\t-V\t\t\t--version\n"
msgstr "\t-V\t\t\t--version\n"
-#: main.c:766
+#: main.c:835
msgid "\t-W nostalgia\t\t--nostalgia\n"
msgstr "\t-W nostalgia\t\t--nostalgia\n"
-#: main.c:769
+#: main.c:838
msgid "\t-Y\t\t--parsedebug\n"
msgstr "\t-Y\t\t--parsedebug\n"
@@ -1802,7 +3116,7 @@ msgstr "\t-Y\t\t--parsedebug\n"
#. for this application. Please add _another line_ with the
#. address for translation bugs.
#. no-wrap
-#: main.c:778
+#: main.c:847
msgid ""
"\n"
"To report bugs, see node `Bugs' in `gawk.info', which is\n"
@@ -1813,19 +3127,19 @@ msgstr ""
"For at rapportere fejl kan du se punktet 'Bugs' i 'gawk.info', som er\n"
"sektionen 'Reporting Problems and Bugs' i den trykte version.\n"
"\n"
-"Rapportér kommentarer til oversættelsen til <dansk@dansk-gruppen.dk>.\n"
+"Rapportér kommentarer til oversættelsen til <dansk@dansk-gruppen.dk>.\n"
-#: main.c:782
+#: main.c:851
msgid ""
"gawk is a pattern scanning and processing language.\n"
"By default it reads standard input and writes standard output.\n"
"\n"
msgstr ""
-"gawk er et sprog til mønster-genkendelse og -behandling.\n"
-"Almindeligvis læser gawk fra standard ind og skriver til standard ud.\n"
+"gawk er et sprog til mønster-genkendelse og -behandling.\n"
+"Almindeligvis læser gawk fra standard ind og skriver til standard ud.\n"
"\n"
-#: main.c:786
+#: main.c:855
msgid ""
"Examples:\n"
"\tgawk '{ sum += $1 }; END { print sum }' file\n"
@@ -1835,7 +3149,7 @@ msgstr ""
"\tgawk '{ sum += $1 }; END { print sum }' fil\n"
"\tgawk -F: '{ print $1 }' /etc/passwd\n"
-#: main.c:806
+#: main.c:880
#, c-format
msgid ""
"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
@@ -1846,16 +3160,16 @@ msgid ""
"(at your option) any later version.\n"
"\n"
msgstr ""
-"Copyright © 1989, 1991-%d Free Software Foundation.\n"
+"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"
+"ændre det under betingelserne i GNU General Public License, offentliggjort\n"
"af Free Software Foundation, enten version 3 af licensen, eller (hvis du "
"vil)\n"
"enhver senere version.\n"
"\n"
-#: main.c:814
+#: main.c:888
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"
@@ -1863,157 +3177,202 @@ msgid ""
"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"
+"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:820
+#: main.c:894
msgid ""
"You should have received a copy of the GNU General Public License\n"
"along with this program. If not, see http://www.gnu.org/licenses/.\n"
msgstr ""
-"Du bør have fået en kopi af GNU General Public License sammen\n"
-"med dette program. Hvis ikke, så se http://www.gnu.org/licenses/.\n"
+"Du bør have fået en kopi af GNU General Public License sammen\n"
+"med dette program. Hvis ikke, så se http://www.gnu.org/licenses/.\n"
-#: main.c:855
+#: main.c:931
msgid "-Ft does not set FS to tab in POSIX awk"
-msgstr "-Ft sætter ikke FS til tab i POSIX-awk"
+msgstr "-Ft sætter ikke FS til tab i POSIX-awk"
-#: main.c:1089
+#: main.c:1208
#, c-format
msgid "unknown value for field spec: %d\n"
-msgstr "ukendt værdi for felt-spec: %d\n"
+msgstr "ukendt værdi for felt-spec: %d\n"
-#: main.c:1170
+#: main.c:1306
#, c-format
msgid ""
"%s: `%s' argument to `-v' not in `var=value' form\n"
"\n"
msgstr ""
-"%s: '%s' argument til '-v' ikke på formen 'var=værdi'\n"
+"%s: '%s' argument til '-v' ikke på formen 'var=værdi'\n"
"\n"
-#: main.c:1196
+#: main.c:1332
#, c-format
msgid "`%s' is not a legal variable name"
msgstr "'%s' er ikke et gyldigt variabelnavn"
-#: main.c:1199
+#: main.c:1335
#, c-format
msgid "`%s' is not a variable name, looking for file `%s=%s'"
msgstr "'%s' er ikke et variabelnavn, leder efter fil '%s=%s'"
-#: main.c:1203
-#, fuzzy, c-format
+#: main.c:1339
+#, c-format
msgid "cannot use gawk builtin `%s' as variable name"
-msgstr "extension: kan ikke bruge gawk's indbyggede '%s' som funktionsnavn"
+msgstr "kan ikke bruge gawk's indbyggede '%s' som variabelnavn"
-#: main.c:1208
-#, fuzzy, c-format
+#: main.c:1344
+#, c-format
msgid "cannot use function `%s' as variable name"
-msgstr "kan ikke bruge funktionsnavnet '%s' som variabel eller array"
+msgstr "kan ikke bruge funktion '%s' som variabelnavn"
-#: main.c:1261
+#: main.c:1397
msgid "floating point exception"
msgstr "flydendetalsundtagelse"
-#: main.c:1268
+#: main.c:1404
msgid "fatal error: internal error"
msgstr "fatal fejl: intern fejl"
-#: main.c:1283
+#: main.c:1419
msgid "fatal error: internal error: segfault"
msgstr "fatal fejl: intern fejl: segmentfejl"
-#: main.c:1295
+#: main.c:1431
msgid "fatal error: internal error: stack overflow"
-msgstr "fatal fejl: intern fejl: stakoverløb"
+msgstr "fatal fejl: intern fejl: stakoverløb"
-#: main.c:1345
+#: main.c:1490
#, c-format
msgid "no pre-opened fd %d"
-msgstr "ingen fd %d åbnet i forvejen"
+msgstr "ingen fd %d åbnet i forvejen"
-#: main.c:1352
+#: main.c:1497
#, c-format
msgid "could not pre-open /dev/null for fd %d"
-msgstr "kunne ikke i forvejen åbne /dev/null for fd %d"
+msgstr "kunne ikke i forvejen åbne /dev/null for fd %d"
-#: main.c:1375 main.c:1384
-#, c-format
-msgid "could not find groups: %s"
-msgstr "kunne ikke finde grupper: %s"
+#: mpfr.c:550
+#, fuzzy, c-format
+msgid "PREC value `%.*s' is invalid"
+msgstr "BINMODE værdi '%s' er ugyldig, behandles som 3"
+
+#: mpfr.c:608
+#, fuzzy, c-format
+msgid "RNDMODE value `%.*s' is invalid"
+msgstr "BINMODE værdi '%s' er ugyldig, behandles som 3"
+
+#: mpfr.c:698
+#, fuzzy, c-format
+msgid "%s: received non-numeric argument"
+msgstr "cos: fik et ikke-numerisk argument"
+
+#: mpfr.c:800
+#, fuzzy
+msgid "compl(%Rg): negative value will give strange results"
+msgstr "compl(%lf): negative værdier vil give mærkelige resultater"
+
+#: mpfr.c:804
+#, fuzzy
+msgid "comp(%Rg): fractional value will be truncated"
+msgstr "compl(%lf): kommatalsværdier vil blive trunkeret"
-#: msg.c:63
+#: mpfr.c:816
+#, fuzzy, c-format
+msgid "cmpl(%Zd): negative values will give strange results"
+msgstr "compl(%lf): negative værdier vil give mærkelige resultater"
+
+#: mpfr.c:835
+#, fuzzy, c-format
+msgid "%s: received non-numeric argument #%d"
+msgstr "cos: fik et ikke-numerisk argument"
+
+#: mpfr.c:845
+msgid "%s: argument #%d has invalid value %Rg, using 0"
+msgstr ""
+
+#: mpfr.c:857
+#, fuzzy
+msgid "%s: argument #%d negative value %Rg will give strange results"
+msgstr "compl(%lf): negative værdier vil give mærkelige resultater"
+
+#: mpfr.c:863
+#, fuzzy
+msgid "%s: argument #%d fractional value %Rg will be truncated"
+msgstr "or(%lf, %lf): kommatalsværdier vil blive trunkeret"
+
+#: mpfr.c:878
+#, fuzzy, c-format
+msgid "%s: argument #%d negative value %Zd will give strange results"
+msgstr "compl(%lf): negative værdier vil give mærkelige resultater"
+
+#: msg.c:68
#, c-format
msgid "cmd. line:"
msgstr "kommandolinje:"
-#: msg.c:107
-msgid "error: "
-msgstr "fejl: "
-
-#: node.c:406
+#: node.c:421
msgid "backslash at end of string"
-msgstr "omvendt skråstreg i slutningen af strengen"
+msgstr "omvendt skråstreg i slutningen af strengen"
-#: node.c:517
+#: node.c:500
#, c-format
msgid "old awk does not support the `\\%c' escape sequence"
-msgstr "gamle versioner af awk understøtter ikke '\\%c' undvigesekvens"
+msgstr "gamle versioner af awk understøtter ikke '\\%c' undvigesekvens"
-#: node.c:568
+#: node.c:551
msgid "POSIX does not allow `\\x' escapes"
msgstr "POSIX tillader ikke '\\x'-kontrolsekvenser"
-#: node.c:574
+#: node.c:557
msgid "no hex digits in `\\x' escape sequence"
msgstr "ingen heksadecimale cifre i '\\x'-kontrolsekvenser"
-#: node.c:596
+#: node.c:579
#, c-format
msgid ""
"hex escape \\x%.*s of %d characters probably not interpreted the way you "
"expect"
msgstr ""
-"den heksadecimale sekvens \\x%.*s på %d tegn nok ikke forstået som du "
+"den heksadecimale sekvens \\x%.*s på %d tegn nok ikke forstået som du "
"forventer det"
-#: node.c:611
+#: node.c:594
#, c-format
msgid "escape sequence `\\%c' treated as plain `%c'"
msgstr "kontrolsekvensen '\\%c' behandlet som kun '%c'"
-#: node.c:750
+#: node.c:739
msgid ""
"Invalid multibyte data detected. There may be a mismatch between your data "
"and your locale."
msgstr ""
-"Ugyldigt multibyte data fundet. MÃ¥ske er der uoverensstemmelse mellem dine "
+"Ugyldigt multibyte data fundet. Måske er der uoverensstemmelse mellem dine "
"data og dit locale."
-#: posix/gawkmisc.c:176
+#: posix/gawkmisc.c:177
#, c-format
msgid "%s %s `%s': could not get fd flags: (fcntl F_GETFD: %s)"
-msgstr "%s %s '%s': kunne ikke få fat på fd flag: (fcntl F_GETFD: %s)"
+msgstr "%s %s '%s': kunne ikke få fat på fd flag: (fcntl F_GETFD: %s)"
-#: posix/gawkmisc.c:188
+#: posix/gawkmisc.c:189
#, c-format
msgid "%s %s `%s': could not set close-on-exec: (fcntl F_SETFD: %s)"
-msgstr "%s %s '%s': kunne ikke sætte luk-ved-exec (fcntl F_SETFD: %s)"
+msgstr "%s %s '%s': kunne ikke sætte luk-ved-exec (fcntl F_SETFD: %s)"
-#: profile.c:83
+#: profile.c:71
#, c-format
msgid "could not open `%s' for writing: %s"
-msgstr "kunne ikke åbne '%s' for skrivning: %s"
+msgstr "kunne ikke åbne '%s' for skrivning: %s"
-#: profile.c:85
+#: profile.c:73
msgid "sending profile to standard error"
msgstr "sender profilen til standard fejl"
-#: profile.c:203
+#: profile.c:193
#, c-format
msgid ""
"\t# %s block(s)\n"
@@ -2022,7 +3381,7 @@ msgstr ""
"\t# %s blokke\n"
"\n"
-#: profile.c:208
+#: profile.c:198
#, c-format
msgid ""
"\t# Rule(s)\n"
@@ -2031,17 +3390,29 @@ msgstr ""
"\t# Regler\n"
"\n"
-#: profile.c:279
+#: profile.c:272
#, c-format
msgid "internal error: %s with null vname"
msgstr "intern fejl: %s med null vname"
-#: profile.c:952
+#: profile.c:537
+#, fuzzy
+msgid "internal error: builtin with null fname"
+msgstr "intern fejl: %s med null vname"
+
+#: profile.c:949
+#, c-format
+msgid ""
+"\t# Loaded extensions (-l and/or @load)\n"
+"\n"
+msgstr ""
+
+#: profile.c:972
#, c-format
msgid "\t# gawk profile, created %s\n"
msgstr "\t# profil til gawk oprettet %s\n"
-#: profile.c:1331
+#: profile.c:1475
#, c-format
msgid ""
"\n"
@@ -2050,116 +3421,238 @@ msgstr ""
"\n"
"\t# Funktioner, listede alfabetisk\n"
-#: profile.c:1370
+#: profile.c:1513
#, c-format
msgid "redir2str: unknown redirection type %d"
msgstr "redir2str: uykendt omdirigeringstype %d"
-#: re.c:572
-#, fuzzy, c-format
-msgid "range of the form `[%c-%c]' is locale dependent"
-msgstr "område på formen `[%c-%c]' er locale-afhængig"
-
-#: re.c:599
+#: re.c:607
#, c-format
msgid "regexp component `%.*s' should probably be `[%.*s]'"
-msgstr "regexp-komponent `%.*s' skulle nok være `[%.*s]'"
+msgstr "regexp-komponent `%.*s' skulle nok være `[%.*s]'"
-#: regcomp.c:132
+#: regcomp.c:131
msgid "Success"
msgstr "Lykkedes"
-#: regcomp.c:135
+#: regcomp.c:134
msgid "No match"
msgstr "Mislykkedes"
-#: regcomp.c:138
+#: regcomp.c:137
msgid "Invalid regular expression"
-msgstr "Ugyldigt regulært udtryk"
+msgstr "Ugyldigt regulært udtryk"
-#: regcomp.c:141
+#: regcomp.c:140
msgid "Invalid collation character"
msgstr "Ugyldigt sorteringstegn"
-#: regcomp.c:144
+#: regcomp.c:143
msgid "Invalid character class name"
msgstr "Ugyldigt tegnklassenavn"
-#: regcomp.c:147
+#: regcomp.c:146
msgid "Trailing backslash"
-msgstr "Efterfølgende omvendt skråstreg"
+msgstr "Efterfølgende omvendt skråstreg"
-#: regcomp.c:150
+#: regcomp.c:149
msgid "Invalid back reference"
msgstr "Ugyldig bagudreference"
-#: regcomp.c:153
+#: regcomp.c:152
msgid "Unmatched [ or [^"
msgstr "Ubalanceret [ eller [^"
-#: regcomp.c:156
+#: regcomp.c:155
msgid "Unmatched ( or \\("
msgstr "Ubalanceret ( eller \\("
-#: regcomp.c:159
+#: regcomp.c:158
msgid "Unmatched \\{"
msgstr "Ubalanceret \\{"
-#: regcomp.c:162
-msgid "Invalid content of \\{\\}"
-msgstr "Ugyldigt indhold i \\{\\}"
-
-#: regcomp.c:165
+#: regcomp.c:164
msgid "Invalid range end"
msgstr "Ugyldig intervalslutning"
-#: regcomp.c:168
+#: regcomp.c:167
msgid "Memory exhausted"
msgstr "Hukommelsen opbrugt"
-#: regcomp.c:171
+#: regcomp.c:170
msgid "Invalid preceding regular expression"
-msgstr "Ugyldigt foregående regulært udtryk"
+msgstr "Ugyldigt foregående regulært udtryk"
-#: regcomp.c:174
+#: regcomp.c:173
msgid "Premature end of regular expression"
-msgstr "For tidligt slut på regulært udtryk"
+msgstr "For tidligt slut på regulært udtryk"
-#: regcomp.c:177
-msgid "Regular expression too big"
-msgstr "Regulært udtryk for stort"
-
-#: regcomp.c:180
+#: regcomp.c:179
msgid "Unmatched ) or \\)"
msgstr "Ubalanceret ) eller \\)"
-#: regcomp.c:701
+#: regcomp.c:704
msgid "No previous regular expression"
-msgstr "Intet foregående regulært udtryk"
+msgstr "Intet foregående regulært udtryk"
+
+#: symbol.c:741
+msgid "can not pop main context"
+msgstr ""
+
+#~ msgid "range of the form `[%c-%c]' is locale dependent"
+#~ msgstr "område på formen `[%c-%c]' er locale-afhængig"
+
+#, fuzzy
+#~ msgid "[s]printf called with no arguments"
+#~ msgstr "sqrt: kaldt med negativt argument %g"
+
+#~ msgid "`-m[fr]' option irrelevant in gawk"
+#~ msgstr "'-m[fr]'-flaget er irrelevant i gawk"
+
+#~ msgid "-m option usage: `-m[fr] nnn'"
+#~ msgstr "brug af flaget -m: '-m[fr] nnn'"
+
+#, fuzzy
+#~ msgid "%s: received non-numeric first argument"
+#~ msgstr "or: fik et ikke-numerisk første argument"
+
+#, fuzzy
+#~ msgid "%s: received non-numeric second argument"
+#~ msgstr "or: fik et ikke-numerisk andet argument"
+
+#, fuzzy
+#~ msgid "%s(%Rg, ..): negative values will give strange results"
+#~ msgstr "or(%lf, %lf): negative værdier vil give mærkelige resultater"
+
+#, fuzzy
+#~ msgid "%s(%Rg, ..): fractional values will be truncated"
+#~ msgstr "or(%lf, %lf): kommatalsværdier vil blive trunkeret"
+
+#, fuzzy
+#~ msgid "%s(%Zd, ..): negative values will give strange results"
+#~ msgstr "or(%lf, %lf): negative værdier vil give mærkelige resultater"
+
+#, fuzzy
+#~ msgid "%s(.., %Rg): negative values will give strange results"
+#~ msgstr "or(%lf, %lf): negative værdier vil give mærkelige resultater"
+
+#, fuzzy
+#~ msgid "%s(.., %Zd): negative values will give strange results"
+#~ msgstr "or(%lf, %lf): negative værdier vil give mærkelige resultater"
+
+#~ msgid "`%s' is a Bell Labs extension"
+#~ msgstr "'%s' er en Bell Labs-udvidelse"
+
+#~ msgid "`nextfile' is a gawk extension"
+#~ msgstr "'nextfile' er en gawk-udvidelse"
+
+#~ msgid "`delete array' is a gawk extension"
+#~ msgstr "'delete array' er en gawk-udvidelse"
+
+#~ msgid "and: received non-numeric first argument"
+#~ msgstr "and: fik et ikke-numerisk første argument"
+
+#~ msgid "and: received non-numeric second argument"
+#~ msgstr "and: fik et ikke-numerisk andet argument"
+
+#~ msgid "and(%lf, %lf): fractional values will be truncated"
+#~ msgstr "and(%lf, %lf): kommatalsværdier vil blive trunkeret"
+
+#~ msgid "xor: received non-numeric first argument"
+#~ msgstr "xor: fik et ikke-numerisk første argument"
+
+#~ msgid "xor: received non-numeric second argument"
+#~ msgstr "xor: fik et ikke-numerisk andet argument"
+
+#~ msgid "xor(%lf, %lf): fractional values will be truncated"
+#~ msgstr "xor(%lf, %lf): kommatalsværdier vil blive trunkeret"
+
+#~ msgid "Operation Not Supported"
+#~ msgstr "Operationen understøttes ikke"
+
+#~ msgid "attempt to use function `%s' as an array"
+#~ msgstr "forsøg på at bruge funktionen '%s' som et array"
+
+#~ msgid "reference to uninitialized element `%s[\"%.*s\"]'"
+#~ msgstr "reference til ikke-initieret element '%s[\"%.*s\"]'"
+
+#~ msgid "subscript of array `%s' is null string"
+#~ msgstr "indeks i array '%s' er en tom streng"
+
+#~ msgid "%s: empty (null)\n"
+#~ msgstr "%s: tom (null)\n"
+
+#~ msgid "%s: empty (zero)\n"
+#~ msgstr "%s: tom (nul)\n"
+
+#~ msgid "%s: table_size = %d, array_size = %d\n"
+#~ msgstr "%s: tabelstørrelse = %d, arraystørrelse = %d\n"
+
+#~ msgid "%s: array_ref to %s\n"
+#~ msgstr "%s: arrayreference til %s\n"
+
+#~ msgid "use of non-array as array"
+#~ msgstr "brug af ikke-array som array"
+
+#~ msgid "can't use function name `%s' as variable or array"
+#~ msgstr "kan ikke bruge funktionsnavnet '%s' som variabel eller array"
+
+#~ msgid "assignment used in conditional context"
+#~ msgstr "tildeling brugt i sammenligningsammenhæng"
+
+#~ msgid "statement has no effect"
+#~ msgstr "kommandoen har ingen effekt"
+
+#~ msgid ""
+#~ "for loop: array `%s' changed size from %ld to %ld during loop execution"
+#~ msgstr ""
+#~ "for-løkke: array '%s' ændrede størrelse fra %ld til %ld under udførelse "
+#~ "af løkken"
+
+#~ msgid "function called indirectly through `%s' does not exist"
+#~ msgstr "funktion kaldt indirekte via '%s' eksisterer ikke"
+
+#~ msgid "function `%s' not defined"
+#~ msgstr "funktionen '%s' er ikke defineret"
+
+#~ msgid "non-redirected `getline' invalid inside `%s' rule"
+#~ msgstr "ikke-omdirigeret 'getline' ugyldig inden i '%s'-regel"
+
+#~ msgid "`nextfile' cannot be called from a `%s' rule"
+#~ msgstr "'nextfile' kan ikke kaldes fra en '%s'-regel"
+
+#~ msgid "`next' cannot be called from a `%s' rule"
+#~ msgstr "'next' kan ikke kaldes fra en '%s'-regel"
+
+#~ msgid "Sorry, don't know how to interpret `%s'"
+#~ msgstr "Véd desværre ikke hvordan '%s' skal fortolkes"
+
+#~ msgid "\t-R file\t\t\t--command=file\n"
+#~ msgstr "\t-R file\t\t\t--command=fil\n"
+
+#~ msgid "could not find groups: %s"
+#~ msgstr "kunne ikke finde grupper: %s"
#~ msgid "assignment is not allowed to result of builtin function"
#~ msgstr "tildeling er ikke tilladt til resultatet fra en indbygget funktion"
#~ msgid "attempt to use array in a scalar context"
-#~ msgstr "forsøg på at bruge array i skalarsammenhæng"
+#~ msgstr "forsøg på at bruge array i skalarsammenhæng"
#~ msgid "statement may have no effect"
-#~ msgstr "kommandoen har måske ikke nogen effekt"
+#~ msgstr "kommandoen har måske ikke nogen effekt"
#~ msgid "out of memory"
-#~ msgstr "slut på hukommelsen"
+#~ msgstr "slut på hukommelsen"
#~ msgid "attempt to use scalar `%s' as array"
-#~ msgstr "forsøg på at bruge skalaren '%s' som array"
-
-#~ msgid "attempt to use array `%s' in scalar context"
-#~ msgstr "forsøg på at bruge array '%s' i skalarsammenhæng"
+#~ msgstr "forsøg på at bruge skalaren '%s' som array"
#~ msgid "call of `length' without parentheses is deprecated by POSIX"
-#~ msgstr "kald af 'length' uden parenteser er forældet ifølge POSIX"
+#~ msgstr "kald af 'length' uden parenteser er forældet ifølge POSIX"
#~ msgid "division by zero attempted in `/'"
-#~ msgstr "forsøgte at dividere med nul i '/'"
+#~ msgstr "forsøgte at dividere med nul i '/'"
#~ msgid "length: untyped parameter argument will be forced to scalar"
#~ msgstr "length: parameter uden type vil blive brugt som skalar"
@@ -2168,10 +3661,10 @@ msgstr "Intet foregående regulært udtryk"
#~ msgstr "length: argument uden type vil blive brugt som skalar"
#~ msgid "`break' outside a loop is not portable"
-#~ msgstr "'break' uden for en løkke er ikke portabelt"
+#~ msgstr "'break' uden for en løkke er ikke portabelt"
#~ msgid "`continue' outside a loop is not portable"
-#~ msgstr "'continue' uden for en løkke er ikke portabelt"
+#~ msgstr "'continue' uden for en løkke er ikke portabelt"
#~ msgid "`next' cannot be called from a BEGIN rule"
#~ msgstr "'next' kan ikke kaldes fra en BEGIN-regel"
@@ -2183,7 +3676,7 @@ msgstr "Intet foregående regulært udtryk"
#~ "concatenation: side effects in one expression have changed the length of "
#~ "another!"
#~ msgstr ""
-#~ "konkatenering: sideeffekter i et udtryk har ændret længden af et andet!"
+#~ "konkatenering: sideeffekter i et udtryk har ændret længden af et andet!"
#~ msgid "illegal type (%s) in tree_eval"
#~ msgstr "ugyldig type (%s) i tree_eval"
@@ -2192,16 +3685,16 @@ msgstr "Intet foregående regulært udtryk"
#~ msgstr "\t# -- main --\n"
#~ msgid "invalid tree type %s in redirect()"
-#~ msgstr "ugyldig trætype %s i redirect()"
+#~ msgstr "ugyldig trætype %s i redirect()"
#~ msgid "/inet/raw client not ready yet, sorry"
-#~ msgstr "/inet/raw-klient er desværre ikke klar endnu"
+#~ msgstr "/inet/raw-klient er desværre ikke klar endnu"
#~ msgid "only root may use `/inet/raw'."
#~ msgstr "kun root kan bruge '/inet/raw'."
#~ msgid "/inet/raw server not ready yet, sorry"
-#~ msgstr "/inet/raw-server er desværre ikke klar endnu"
+#~ msgstr "/inet/raw-server er desværre ikke klar endnu"
#~ msgid "file `%s' is a directory"
#~ msgstr "filen '%s' er et katalog"
@@ -2213,7 +3706,7 @@ msgstr "Intet foregående regulært udtryk"
#~ msgstr "brug 'PROCINFO[...]' i stedet for '/dev/user'"
#~ msgid "\t-m[fr] val\n"
-#~ msgstr "\t-m[fr] værdi\n"
+#~ msgstr "\t-m[fr] værdi\n"
#~ msgid "\t-W compat\t\t--compat\n"
#~ msgstr "\t-W compat\t\t--compat\n"
@@ -2231,7 +3724,7 @@ msgstr "Intet foregående regulært udtryk"
#~ msgstr "# behandlet internt som 'delete'"
#~ msgid "# this is a dynamically loaded extension function"
-#~ msgstr "# dette er en dynamisk indlæst udvidelsesfunktion"
+#~ msgstr "# dette er en dynamisk indlæst udvidelsesfunktion"
#~ msgid ""
#~ "\t# BEGIN block(s)\n"
diff --git a/po/de.gmo b/po/de.gmo
index f95537b8..e46946bb 100644
--- a/po/de.gmo
+++ b/po/de.gmo
Binary files differ
diff --git a/po/de.po b/po/de.po
index 3500bf2d..ca6d5475 100644
--- a/po/de.po
+++ b/po/de.po
@@ -2,14 +2,14 @@
# Copyright (C) 2000 Free Software Foundation, Inc.
# This file is distributed under the same license as the gawk package.
#
-# Philipp Thomas <pth@suse.de>, 2011
+# Philipp Thomas <pth@suse.de>, 2011, 2012, 2014
#
msgid ""
msgstr ""
-"Project-Id-Version: gawk 4.0.0\n"
+"Project-Id-Version: gawk 4.1.0b\n"
"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
-"POT-Creation-Date: 2011-10-24 05:57+0200\n"
-"PO-Revision-Date: 2011-09-27 16:38+0200\n"
+"POT-Creation-Date: 2014-01-14 22:23+0200\n"
+"PO-Revision-Date: 2014-10-23 17:31+0200\n"
"Last-Translator: Philipp Thomas <pth@suse.de>\n"
"Language-Team: German <translation-team-de@lists.sourceforge.net>\n"
"Language: de\n"
@@ -17,525 +17,479 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: array.c:140
+#: array.c:256
#, c-format
msgid "from %s"
msgstr "von %s"
-#: array.c:248
+#: array.c:357
msgid "attempt to use a scalar value as array"
msgstr "Es wird versucht, einen Skalar als Feld zu verwenden"
-#: array.c:251
-#, c-format
-msgid "attempt to use function `%s' as an array"
-msgstr "Es wird versucht, die Funktion »%s« als Feld zu verwenden"
-
-#: array.c:254
+#: array.c:359
#, c-format
msgid "attempt to use scalar parameter `%s' as an array"
msgstr "Es wird versucht, den skalaren Parameter »%s« als Feld zu verwenden"
-#: array.c:257
+#: array.c:362
#, c-format
msgid "attempt to use scalar `%s' as an array"
msgstr "Es wird versucht, den Skalar »%s« als Array zu verwenden"
-#: array.c:302 array.c:707 builtin.c:84 builtin.c:1384 builtin.c:1426
-#: builtin.c:1439 builtin.c:1856 builtin.c:1868 eval.c:1135 eval.c:1139
-#: eval.c:1495 eval.c:1812
+#: array.c:409 array.c:576 builtin.c:85 builtin.c:1599 builtin.c:1645
+#: builtin.c:1658 builtin.c:2086 builtin.c:2100 eval.c:1122 eval.c:1126
+#: eval.c:1531
#, c-format
msgid "attempt to use array `%s' in a scalar context"
msgstr "Es wird versucht, das Feld »%s« in einem Skalarkontext zu verwenden"
-#: array.c:513
-#, c-format
-msgid "reference to uninitialized element `%s[\"%.*s\"]'"
-msgstr "Bezug auf ein nicht initialisiertes Element »%s[\"%.*s\"]«"
-
-#: array.c:519
-#, c-format
-msgid "subscript of array `%s' is null string"
-msgstr "Der Index von Feld »%s« ist ein Nullstring"
-
-#: array.c:723
+#: array.c:583
#, c-format
msgid "delete: index `%s' not in array `%s'"
msgstr "delete: Index »%s« ist in Feld »%s« nicht vorhanden"
-#: array.c:734 eval.c:1865
+#: array.c:597
#, c-format
msgid "attempt to use scalar `%s[\"%.*s\"]' as an array"
msgstr "Es wird versucht, den Skalar »%s[\"%.*s\"]« als Feld zu verwenden"
-#: array.c:910
-#, c-format
-msgid "%s: empty (null)\n"
-msgstr "%s: leer (Null)\n"
-
-#: array.c:915
-#, c-format
-msgid "%s: empty (zero)\n"
-msgstr "%s: leer (0)\n"
-
-#: array.c:919
-#, c-format
-msgid "%s: table_size = %d, array_size = %d\n"
-msgstr "%s: Tabellengröße = %d, Feldgröße = %d\n"
-
-#: array.c:954
-#, c-format
-msgid "%s: is parameter\n"
-msgstr "%s: ist ein Parameter\n"
-
-#: array.c:958
-#, c-format
-msgid "%s: array_ref to %s\n"
-msgstr "%s: Feld-Referenz auf %s\n"
+#: array.c:776
+msgid "adump: first argument not an array"
+msgstr "adump: Das erste Argument ist kein Feld"
-#: array.c:963
-msgid "adump: argument not an array"
-msgstr "adump: Das Argument ist kein Feld"
-
-#: array.c:1086
+#: array.c:815
msgid "asort: second argument not an array"
msgstr "asort: Das zweite Argument ist kein Feld"
-#: array.c:1087
+#: array.c:816
msgid "asorti: second argument not an array"
msgstr "asorti: Das zweite Argument ist kein Feld"
-#: array.c:1094
+#: array.c:823
msgid "asort: first argument not an array"
msgstr "asort: Das erste Argument ist kein Feld"
-#: array.c:1095
+#: array.c:824
msgid "asorti: first argument not an array"
msgstr "asorti: Das erste Argument ist kein Feld"
-#: array.c:1102
+#: array.c:831
msgid "asort: cannot use a subarray of first arg for second arg"
-msgstr ""
-"asort: ein untergeordnetes Feld des ersten Arguments kann nicht als zweites "
-"Argument verwendet werden"
+msgstr "asort: ein untergeordnetes Feld des ersten Arguments kann nicht als zweites Argument verwendet werden"
-#: array.c:1103
+#: array.c:832
msgid "asorti: cannot use a subarray of first arg for second arg"
-msgstr ""
-"asorti: ein untergeordnetes Feld des ersten Arguments kann nicht als zweites "
-"Argument verwendet werden"
+msgstr "asorti: ein untergeordnetes Feld des ersten Arguments kann nicht als zweites Argument verwendet werden"
-#: array.c:1108
+#: array.c:837
msgid "asort: cannot use a subarray of second arg for first arg"
-msgstr ""
-"asort: ein untergeordnetes Feld des zweiten Arguments kann nicht als erstes "
-"Argument verwendet werden"
+msgstr "asort: ein untergeordnetes Feld des zweiten Arguments kann nicht als erstes Argument verwendet werden"
-#: array.c:1109
+#: array.c:838
msgid "asorti: cannot use a subarray of second arg for first arg"
-msgstr ""
-"asorti: ein untergeordnetes Feld des zweiten Arguments kann nicht als erstes "
-"Argument verwendet werden"
+msgstr "asorti: ein untergeordnetes Feld des zweiten Arguments kann nicht als erstes Argument verwendet werden"
-#: array.c:1659
+#: array.c:1314
#, c-format
msgid "`%s' is invalid as a function name"
msgstr "»%s« ist ein unzulässiger Funktionsname"
-#: array.c:1663
+#: array.c:1318
#, c-format
msgid "sort comparison function `%s' is not defined"
msgstr "Die Vergleichsfunktion »%s« für das Sortieren ist nicht definiert"
-#: awkgram.y:249
+#: awkgram.y:233
#, c-format
msgid "%s blocks must have an action part"
msgstr "%s-Blöcke müssen einen Aktionsteil haben"
-#: awkgram.y:252
+#: awkgram.y:236
msgid "each rule must have a pattern or an action part"
msgstr "Jede Regel muss entweder ein Muster oder einen Aktionsteil haben"
-#: awkgram.y:323 awkgram.y:334
+#: awkgram.y:325 awkgram.y:336
msgid "old awk does not support multiple `BEGIN' or `END' rules"
msgstr "Das alte awk erlaubt keine mehrfachen »BEGIN«- oder »END«-Regeln"
-#: awkgram.y:371
+#: awkgram.y:373
#, 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:432
+#: awkgram.y:419
msgid "regexp constant `//' looks like a C++ comment, but is not"
-msgstr ""
-"Die Regulärer-Ausdruck-Konstante »//« sieht wie ein C-Kommentar aus, ist "
-"aber keiner"
+msgstr "Die Regulärer-Ausdruck-Konstante »//« sieht wie ein C-Kommentar aus, ist aber keiner"
-#: awkgram.y:436
+#: awkgram.y:423
#, c-format
msgid "regexp constant `/%s/' looks like a C comment, but is not"
-msgstr ""
-"Die Regulärer-Ausdruck-Konstante »/%s/« sieht wie ein C-Kommentar aus, ist "
-"aber keiner"
+msgstr "Die Regulärer-Ausdruck-Konstante »/%s/« sieht wie ein C-Kommentar aus, ist aber keiner"
-#: awkgram.y:528
+#: awkgram.y:515
#, c-format
msgid "duplicate case values in switch body: %s"
msgstr "doppelte Case-Werte im Switch-Block: %s"
-#: awkgram.y:549
+#: awkgram.y:536
msgid "duplicate `default' detected in switch body"
msgstr "doppeltes »default« im Switch-Block gefunden"
-#: awkgram.y:809
+#: awkgram.y:796 awkgram.y:3699
msgid "`break' is not allowed outside a loop or switch"
-msgstr ""
-"»break« ist außerhalb einer Schleife oder eines Switch-Blocks nicht zulässig"
+msgstr "»break« ist außerhalb einer Schleife oder eines Switch-Blocks nicht zulässig"
-#: awkgram.y:818
+#: awkgram.y:805 awkgram.y:3691
msgid "`continue' is not allowed outside a loop"
msgstr "»continue« ist außerhalb einer Schleife nicht zulässig"
-#: awkgram.y:828
+#: awkgram.y:815
#, c-format
msgid "`next' used in %s action"
msgstr "»next« wird in %s-Aktion verwendet"
-#: awkgram.y:836
-msgid "`nextfile' is a gawk extension"
-msgstr "»nextfile« ist eine gawk-Erweiterung"
-
-#: awkgram.y:841
+#: awkgram.y:824
#, c-format
msgid "`nextfile' used in %s action"
msgstr "»nextfile« wird in %s-Aktion verwendet"
-#: awkgram.y:865
+#: awkgram.y:848
msgid "`return' used outside function context"
msgstr "»return« wird außerhalb einer Funktion verwendet"
-#: awkgram.y:925
+#: awkgram.y:922
msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
-msgstr ""
-"Einfaches »print« in BEGIN- oder END-Regel soll vermutlich »print \"\"« sein"
+msgstr "Einfaches »print« in BEGIN- oder END-Regel soll vermutlich »print \"\"« sein"
-#: awkgram.y:995 awkgram.y:999 awkgram.y:1023
-msgid "`delete array' is a gawk extension"
-msgstr "»delete array« ist eine gawk-Erweiterung"
+#: awkgram.y:988 awkgram.y:1037
+msgid "`delete' is not allowed with SYMTAB"
+msgstr "»delete« ist in Zusammenhang mit SYMTAB nicht zulässig"
-#: awkgram.y:1019
+#: awkgram.y:990 awkgram.y:1039
+msgid "`delete' is not allowed with FUNCTAB"
+msgstr "»delete« ist in Zusammenhang mit FUNCTAB nicht zulässig"
+
+#: awkgram.y:1024 awkgram.y:1028
msgid "`delete(array)' is a non-portable tawk extension"
msgstr "»delete(array)« ist eine gawk-Erweiterung"
-#: awkgram.y:1135
+#: awkgram.y:1149
msgid "multistage two-way pipelines don't work"
msgstr "mehrstufige Zweiwege-Pipes funktionieren nicht"
-#: awkgram.y:1238
+#: awkgram.y:1264
msgid "regular expression on right of assignment"
msgstr "Regulärer Ausdruck auf der rechten Seite einer Zuweisung"
-#: awkgram.y:1249
+#: awkgram.y:1275
msgid "regular expression on left of `~' or `!~' operator"
msgstr "Regulärer Ausdruck links vom »~«- oder »!~«-Operator"
-#: awkgram.y:1265 awkgram.y:1419
+#: awkgram.y:1291 awkgram.y:1442
msgid "old awk does not support the keyword `in' except after `for'"
msgstr "Das alte awk unterstützt das Schlüsselwort »in« nur nach »for«"
-#: awkgram.y:1275
+#: awkgram.y:1301
msgid "regular expression on right of comparison"
msgstr "Regulärer Ausdruck rechts von einem Vergleich"
-#: awkgram.y:1394
+#: awkgram.y:1417
#, c-format
msgid "`getline var' invalid inside `%s' rule"
msgstr "»getline var« ist ungültig innerhalb der »%s«-Regel"
-#: awkgram.y:1397 eval.c:2504
+#: awkgram.y:1420
#, c-format
msgid "`getline' invalid inside `%s' rule"
msgstr "»getline« ist ungültig innerhalb der »%s«-Regel"
-#: awkgram.y:1402
+#: awkgram.y:1425
msgid "non-redirected `getline' undefined inside END action"
-msgstr ""
-"Nicht-umgelenktes »getline« ist innerhalb der END-Aktion nicht definiert"
+msgstr "Nicht-umgelenktes »getline« ist innerhalb der END-Aktion nicht definiert"
-#: awkgram.y:1421
+#: awkgram.y:1444
msgid "old awk does not support multidimensional arrays"
msgstr "Das alte awk unterstützt keine mehrdimensionalen Felder"
-#: awkgram.y:1517
+#: awkgram.y:1541
msgid "call of `length' without parentheses is not portable"
msgstr "Aufruf von »length« ohne Klammern ist nicht portabel"
-#: awkgram.y:1580
+#: awkgram.y:1607
msgid "indirect function calls are a gawk extension"
msgstr "indirekte Funktionsaufrufe sind eine gawk-Erweiterung"
-#: awkgram.y:1593
+#: awkgram.y:1620
#, c-format
msgid "can not use special variable `%s' for indirect function call"
-msgstr ""
-"die besondere Variable »%s« kann nicht für den indirekten Funktionsaufruf "
-"verwendet werden"
+msgstr "die besondere Variable »%s« kann nicht für den indirekten Funktionsaufruf verwendet werden"
-#: awkgram.y:1671
+#: awkgram.y:1698
msgid "invalid subscript expression"
msgstr "Ungültiger Index-Ausdruck"
-#: awkgram.y:1711
-msgid "use of non-array as array"
-msgstr "Verwendung eines Nicht-Feldes als Feld"
-
-#: awkgram.y:1975 awkgram.y:1995 msg.c:98
+#: awkgram.y:2024 awkgram.y:2044 gawkapi.c:206 gawkapi.c:224 msg.c:126
msgid "warning: "
msgstr "Warnung: "
-#: awkgram.y:1993 msg.c:130
+#: awkgram.y:2042 gawkapi.c:192 gawkapi.c:221 msg.c:158
msgid "fatal: "
msgstr "Fatal: "
-#: awkgram.y:2043
+#: awkgram.y:2092
msgid "unexpected newline or end of string"
msgstr "Unerwarteter Zeilenumbruch oder Ende der Zeichenkette"
-#: awkgram.y:2300 awkgram.y:2358 awkgram.y:2542
+#: awkgram.y:2359 awkgram.y:2435 awkgram.y:2658 debug.c:523 debug.c:539
+#: debug.c:2812 debug.c:5055
#, c-format
msgid "can't open source file `%s' for reading (%s)"
msgstr "Quelldatei »%s« kann nicht zum Lesen geöffnet werden (%s)"
-#: awkgram.y:2301 awkgram.y:2359 builtin.c:122
+#: awkgram.y:2360 awkgram.y:2485
+#, c-format
+msgid "can't open shared library `%s' for reading (%s)"
+msgstr "Die dynamische Bibliothek »%s« kann nicht zum Lesen geöffnet werden (%s)"
+
+#: awkgram.y:2362 awkgram.y:2436 awkgram.y:2486 builtin.c:135 debug.c:5206
msgid "reason unknown"
msgstr "Unbekannte Ursache"
-#: awkgram.y:2317
+#: awkgram.y:2371 awkgram.y:2395
+#, c-format
+msgid "can't include `%s' and use it as a program file"
+msgstr "»%s« kann nicht eingebunden und als Programmdatei verwendet werden"
+
+#: awkgram.y:2384
#, c-format
msgid "already included source file `%s'"
msgstr "Quelldatei »%s« wurde bereits eingebunden"
-#: awkgram.y:2343
+#: awkgram.y:2385
+#, c-format
+msgid "already loaded shared library `%s'"
+msgstr "Die dynamische Bibliothek »%s« wurde bereits eingebunden"
+
+#: awkgram.y:2420
msgid "@include is a gawk extension"
msgstr "»@include« ist eine gawk-Erweiterung"
-#: awkgram.y:2349
+#: awkgram.y:2426
msgid "empty filename after @include"
msgstr "leerer Dateiname nach @include"
-#: awkgram.y:2494
+#: awkgram.y:2470
+msgid "@load is a gawk extension"
+msgstr "»@load« ist eine Gawk-Erweiterung"
+
+#: awkgram.y:2476
+msgid "empty filename after @load"
+msgstr "leerer Dateiname nach @load"
+
+#: awkgram.y:2610
msgid "empty program text on command line"
msgstr "Kein Programmtext auf der Kommandozeile"
-#: awkgram.y:2609
+#: awkgram.y:2725
#, c-format
msgid "can't read sourcefile `%s' (%s)"
msgstr "Die Quelldatei »%s« kann nicht gelesen werden (%s)"
-#: awkgram.y:2620
+#: awkgram.y:2736
#, c-format
msgid "source file `%s' is empty"
msgstr "Die Quelldatei »%s« ist leer"
-#: awkgram.y:2805
+#: awkgram.y:2913
msgid "source file does not end in newline"
msgstr "Die Quelldatei hört nicht mit einem Zeilenende auf"
-#: awkgram.y:2882
+#: awkgram.y:3018
msgid "unterminated regexp ends with `\\' at end of file"
-msgstr ""
-"Nicht beendeter regulärer Ausdruck (hört mit '\\' auf) am Ende der Datei"
+msgstr "Nicht beendeter regulärer Ausdruck (hört mit '\\' auf) am Ende der Datei"
-#: awkgram.y:2906
+#: awkgram.y:3042
#, c-format
msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
-msgstr ""
-"%s: %d: der tawk-Modifizierer für reguläre Ausdrücke »/.../%c« funktioniert "
-"nicht in gawk"
+msgstr "%s: %d: der tawk-Modifizierer für reguläre Ausdrücke »/.../%c« funktioniert nicht in gawk"
-#: awkgram.y:2910
+#: awkgram.y:3046
#, c-format
msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
-msgstr ""
-"Der tawk-Modifizierer für reguläre Ausdrücke »/.../%c« funktioniert nicht in "
-"gawk"
+msgstr "Der tawk-Modifizierer für reguläre Ausdrücke »/.../%c« funktioniert nicht in gawk"
-#: awkgram.y:2917
+#: awkgram.y:3053
msgid "unterminated regexp"
msgstr "Nicht beendeter regulärer Ausdruck"
-#: awkgram.y:2921
+#: awkgram.y:3057
msgid "unterminated regexp at end of file"
msgstr "Nicht beendeter regulärer Ausdruck am Dateiende"
-#: awkgram.y:2980
+#: awkgram.y:3116
msgid "use of `\\ #...' line continuation is not portable"
-msgstr ""
-"Die Verwendung von »\\#...« zur Fortsetzung von Zeilen ist nicht portabel"
+msgstr "Die Verwendung von »\\#...« zur Fortsetzung von Zeilen ist nicht portabel"
-#: awkgram.y:2996
+#: awkgram.y:3132
msgid "backslash not last character on line"
msgstr "das letzte Zeichen auf der Zeile ist kein Backslash (»\\«)"
-#: awkgram.y:3057
+#: awkgram.y:3193
msgid "POSIX does not allow operator `**='"
msgstr "POSIX erlaubt den Operator »**=« nicht"
-#: awkgram.y:3059
+#: awkgram.y:3195
msgid "old awk does not support operator `**='"
msgstr "Das alte awk unterstützt den Operator »**=« nicht"
-#: awkgram.y:3068
+#: awkgram.y:3204
msgid "POSIX does not allow operator `**'"
msgstr "POSIX erlaubt den Operator »**« nicht"
-#: awkgram.y:3070
+#: awkgram.y:3206
msgid "old awk does not support operator `**'"
msgstr "Das alte awk unterstützt den Operator »**« nicht"
-#: awkgram.y:3105
+#: awkgram.y:3241
msgid "operator `^=' is not supported in old awk"
msgstr "Das alte awk unterstützt den Operator »^=« nicht"
-#: awkgram.y:3113
+#: awkgram.y:3249
msgid "operator `^' is not supported in old awk"
msgstr "Das alte awk unterstützt den Operator »^« nicht"
-#: awkgram.y:3206 awkgram.y:3222
+#: awkgram.y:3342 awkgram.y:3358 command.y:1178
msgid "unterminated string"
msgstr "Nicht beendete Zeichenkette"
-#: awkgram.y:3418
+#: awkgram.y:3579
#, c-format
msgid "invalid char '%c' in expression"
msgstr "Ungültiges Zeichen »%c« in einem Ausdruck"
-#: awkgram.y:3465
+#: awkgram.y:3626
#, c-format
msgid "`%s' is a gawk extension"
msgstr "»%s« ist eine gawk-Erweiterung"
-#: awkgram.y:3470
-#, c-format
-msgid "`%s' is a Bell Labs extension"
-msgstr "»%s« ist eine Erweiterung der Bell Labs"
-
-#: awkgram.y:3475
+#: awkgram.y:3631
#, c-format
msgid "POSIX does not allow `%s'"
msgstr "POSIX erlaubt »%s« nicht"
-#: awkgram.y:3483
+#: awkgram.y:3639
#, c-format
msgid "`%s' is not supported in old awk"
msgstr "»%s« wird im alten awk nicht unterstützt"
-#: awkgram.y:3550
+#: awkgram.y:3729
msgid "`goto' considered harmful!\n"
msgstr "»goto« gilt als schlechter Stil!\n"
-#: awkgram.y:3601
+#: awkgram.y:3763
#, c-format
msgid "%d is invalid as number of arguments for %s"
msgstr "Unzulässige Argumentzahl %d für %s"
-#: awkgram.y:3636
+#: awkgram.y:3798
#, 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:3641
+#: awkgram.y:3803
#, c-format
msgid "%s third parameter is not a changeable object"
msgstr "Der dritte Parameter von %s ist ein unveränderliches Objekt"
-#: awkgram.y:3714 awkgram.y:3717
+#: awkgram.y:3886 awkgram.y:3889
msgid "match: third argument is a gawk extension"
msgstr "match: Das dritte Argument ist eine gawk-Erweiterung"
-#: awkgram.y:3771 awkgram.y:3774
+#: awkgram.y:3943 awkgram.y:3946
msgid "close: second argument is a gawk extension"
msgstr "close: Das zweite Argument ist eine gawk-Erweiterung"
-#: awkgram.y:3786
+#: awkgram.y:3958
msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
msgstr ""
"Fehlerhafte Verwendung von dcgettext(_\"...\"): \n"
"Entfernen Sie den führenden Unterstrich"
-#: awkgram.y:3801
+#: awkgram.y:3973
msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
msgstr ""
"Fehlerhafte Verwendung von dcngettext(_\"...\"): \n"
"Entfernen Sie den führenden Unterstrich"
-#: awkgram.y:3893
-#, c-format
-msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
-msgstr "Funktion »%s«: Parameter #%d, »%s« wiederholt Parameter #%d"
+#: awkgram.y:3992
+msgid "index: regexp constant as second argument is not allowed"
+msgstr "index: eine Regexp-Konstante als zweites Argument ist unzulässig"
-#: awkgram.y:3935
+#: awkgram.y:4045
#, c-format
msgid "function `%s': parameter `%s' shadows global variable"
msgstr "Funktion »%s«: Parameter »%s« verdeckt eine globale Variable"
-#: awkgram.y:4093
+#: awkgram.y:4102 debug.c:4041 debug.c:4084 debug.c:5204
#, c-format
msgid "could not open `%s' for writing (%s)"
msgstr "»%s« kann nicht zum Schreiben geöffne werden(%s)"
-#: awkgram.y:4094
+#: awkgram.y:4103
msgid "sending variable list to standard error"
msgstr "Die Liste der Variablen wird auf der Standardfehlerausgabe ausgegeben"
-#: awkgram.y:4100
+#: awkgram.y:4111
#, c-format
msgid "%s: close failed (%s)"
msgstr "%s: close ist gescheitert (%s)"
-#: awkgram.y:4152
+#: awkgram.y:4136
msgid "shadow_funcs() called twice!"
msgstr "shadow_funcs() zweimal aufgerufen!"
-#: awkgram.y:4158
+#: awkgram.y:4144
msgid "there were shadowed variables."
msgstr "es sind verdeckte Variablen vorhanden"
-#: awkgram.y:4188
+#: awkgram.y:4215
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "Funktion »%s« wurde bereits definiert"
+
+#: awkgram.y:4261
#, c-format
msgid "function `%s': can't use function name as parameter name"
msgstr "Funktion »%s«: Funktionsnamen können nicht als Parameternamen benutzen"
-#: awkgram.y:4192
+#: awkgram.y:4264
#, c-format
msgid "function `%s': can't use special variable `%s' as a function parameter"
-msgstr ""
-"Funktion »%s«: die spezielle Variable »%s« kann nicht als Parameter "
-"verwendet werden"
+msgstr "Funktion »%s«: die spezielle Variable »%s« kann nicht als Parameter verwendet werden"
-#: awkgram.y:4208
+#: awkgram.y:4272
#, c-format
-msgid "function name `%s' previously defined"
-msgstr "Funktion »%s« wurde bereits definiert"
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "Funktion »%s«: Parameter #%d, »%s« wiederholt Parameter #%d"
-#: awkgram.y:4376 awkgram.y:4382
+#: awkgram.y:4359 awkgram.y:4365
#, c-format
msgid "function `%s' called but never defined"
msgstr "Aufgerufene Funktion »%s« ist nirgends definiert"
-#: awkgram.y:4385
+#: awkgram.y:4369
#, c-format
msgid "function `%s' defined but never called directly"
msgstr "Funktion »%s« wurde definiert aber nirgends aufgerufen"
-#: awkgram.y:4417
+#: awkgram.y:4401
#, c-format
msgid "regexp constant for parameter #%d yields boolean value"
msgstr ""
"Regulärer-Ausdruck-Konstante für Parameter #%d ergibt einen \n"
"logischen Wert"
-#: awkgram.y:4526
+#: awkgram.y:4460
#, c-format
msgid ""
"function `%s' called with space between name and `(',\n"
@@ -544,468 +498,1307 @@ msgstr ""
"Funktion »%s« wird mit Leerzeichen zwischen Name und »(« aufgerufen, \n"
"oder als Variable oder Feld verwendet"
-#: awkgram.y:4773 eval.c:2056
+#: awkgram.y:4696
msgid "division by zero attempted"
msgstr "Division durch Null wurde versucht"
-#: awkgram.y:4782 eval.c:2072
+#: awkgram.y:4705
#, c-format
msgid "division by zero attempted in `%%'"
msgstr "Division durch Null versucht in »%%«"
-#: builtin.c:120
+#: awkgram.y:5025
+msgid "cannot assign a value to the result of a field post-increment expression"
+msgstr "dem Ergebnis eines Feld-Postinkrementausdruck kann kein Wert zugewiesen werden"
+
+#: awkgram.y:5028
+#, c-format
+msgid "invalid target of assignment (opcode %s)"
+msgstr "Unzulässiges Ziel für eine Zuweisung (Opcode %s)"
+
+#: builtin.c:133
#, c-format
msgid "%s to \"%s\" failed (%s)"
msgstr "%s to \"%s\" fehlgeschlagen (%s)"
-#: builtin.c:121
+#: builtin.c:134
msgid "standard output"
msgstr "Standardausgabe"
-#: builtin.c:135
+#: builtin.c:148
msgid "exp: received non-numeric argument"
msgstr "exp: das Argument ist keine Zahl"
-#: builtin.c:141
+#: builtin.c:154
#, c-format
msgid "exp: argument %g is out of range"
msgstr "exp: das Argument %g liegt außerhalb des gültigen Bereichs"
-#: builtin.c:200
+#: builtin.c:229
#, 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"
+msgstr "fflush: Leeren der Puffer nicht möglich, Pipe »%s« ist nur zum Lesen geöffnet"
-#: builtin.c:203
+#: builtin.c:232
#, 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"
+msgstr "fflush: Leeren der Puffer nicht möglich, Datei »%s« ist nur zum Lesen geöffnet"
-#: builtin.c:215
+#: builtin.c:244
#, 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:333
+#: builtin.c:362
msgid "index: received non-string first argument"
msgstr "index: Erstes Argument ist kein String"
-#: builtin.c:335
+#: builtin.c:364
msgid "index: received non-string second argument"
msgstr "index: Zweites Argument ist kein string"
-#: builtin.c:457
+#: builtin.c:488 mpfr.c:757
msgid "int: received non-numeric argument"
msgstr "Argument ist keine Zahl"
-#: builtin.c:493
+#: builtin.c:525
msgid "length: received array argument"
msgstr "length: Argument ist ein Feld"
-#: builtin.c:496
+#: builtin.c:528
msgid "`length(array)' is a gawk extension"
msgstr "»length(array)« ist eine gawk-Erweiterung"
-#: builtin.c:504
+#: builtin.c:544
msgid "length: received non-string argument"
msgstr "length: Argument ist kein String"
-#: builtin.c:535
+#: builtin.c:575
msgid "log: received non-numeric argument"
msgstr "log: Argument ist keine Zahl"
-#: builtin.c:538
+#: builtin.c:578
#, c-format
msgid "log: received negative argument %g"
msgstr "log: Negatives Argument %g"
-#: builtin.c:694 builtin.c:699
+#: builtin.c:776 builtin.c:781
msgid "fatal: must use `count$' on all formats or none"
msgstr "Fatal: »count$« muss auf alle Formate angewandt werden oder auf keines"
-#: builtin.c:761
+#: builtin.c:851
#, c-format
msgid "field width is ignored for `%%' specifier"
msgstr "Feldbreite wird für die »%%«-Angabe ignoriert"
-#: builtin.c:763
+#: builtin.c:853
#, c-format
msgid "precision is ignored for `%%' specifier"
msgstr "Genauigkeit wird für die »%%«-Angabe ignoriert"
-#: builtin.c:765
+#: builtin.c:855
#, c-format
msgid "field width and precision are ignored for `%%' specifier"
msgstr "Feldbreite und Genauigkeit werden für die »%%«-Angabe ignoriert"
-#: builtin.c:816
+#: builtin.c:906
msgid "fatal: `$' is not permitted in awk formats"
msgstr "Fatal: »$« ist in awk-Formaten nicht zulässig"
-#: builtin.c:825
+#: builtin.c:915
msgid "fatal: arg count with `$' must be > 0"
msgstr "Fatal: die Anzahl der Argumen bei »$« muss > 0 sein"
-#: builtin.c:829
+#: builtin.c:919
#, c-format
msgid "fatal: arg count %ld greater than total number of supplied arguments"
-msgstr ""
-"Fatal: Argumentenanzahl %ld ist größer als die Gesamtzahl angegebener "
-"Argumente"
+msgstr "Fatal: Argumentenanzahl %ld ist größer als die Gesamtzahl angegebener Argumente"
-#: builtin.c:833
+#: builtin.c:923
msgid "fatal: `$' not permitted after period in format"
msgstr "Fatal: »$« nach Punkt in Formatangabe nicht zulässig"
-#: builtin.c:849
+#: builtin.c:939
msgid "fatal: no `$' supplied for positional field width or precision"
msgstr "Fatal: »$« fehlt in positionsabhängiger Feldbreite oder Genauigkeit"
#
-#: builtin.c:920
+#: builtin.c:1011
msgid "`l' is meaningless in awk formats; ignored"
msgstr "»l« ist in awk-Formaten bedeutungslos, ignoriert"
-#: builtin.c:924
+#: builtin.c:1015
msgid "fatal: `l' is not permitted in POSIX awk formats"
msgstr "Fatal: »l« ist in POSIX-awk-Formaten nicht zulässig"
-#: builtin.c:937
+#: builtin.c:1028
msgid "`L' is meaningless in awk formats; ignored"
msgstr "»L« ist in awk-Formaten bedeutungslos, ignoriert"
-#: builtin.c:941
+#: builtin.c:1032
msgid "fatal: `L' is not permitted in POSIX awk formats"
msgstr "Fatal: »L« ist in POSIX-awk-Formaten nicht zulässig"
-#: builtin.c:954
+#: builtin.c:1045
msgid "`h' is meaningless in awk formats; ignored"
msgstr "»h« ist in awk-Formaten bedeutungslos, ignoriert"
-#: builtin.c:958
+#: builtin.c:1049
msgid "fatal: `h' is not permitted in POSIX awk formats"
msgstr "Fatal: »h« ist in POSIX-awk-Formaten nicht zulässig"
-#: builtin.c:1271
+#: builtin.c:1447
#, c-format
msgid "[s]printf: value %g is out of range for `%%%c' format"
msgstr "[s]printf: Wert %g ist außerhalb des Bereichs für Format »%%%c«"
-#: builtin.c:1331
+#: builtin.c:1545
#, c-format
msgid "ignoring unknown format specifier character `%c': no argument converted"
-msgstr ""
-"das unbekannte Zeichen »%c« in der Formatspezifikation wird ignoriert: keine "
-"Argumente umgewandelt"
+msgstr "das unbekannte Zeichen »%c« in der Formatspezifikation wird ignoriert: keine Argumente umgewandelt"
-#: builtin.c:1336
+#: builtin.c:1550
msgid "fatal: not enough arguments to satisfy format string"
msgstr "Fatal: Nicht genügend Argumente für die Formatangabe"
-#: builtin.c:1338
+#: builtin.c:1552
msgid "^ ran out for this one"
msgstr "^ hierfür fehlte es"
-#: builtin.c:1345
+#: builtin.c:1559
msgid "[s]printf: format specifier does not have control letter"
msgstr "[s]printf: Format-Spezifikation hat keinen Controlcode"
-#: builtin.c:1348
+#: builtin.c:1562
msgid "too many arguments supplied for format string"
msgstr "Zu viele Argumente für den Formatstring"
-#: builtin.c:1422 builtin.c:1433
+#: builtin.c:1618
+msgid "sprintf: no arguments"
+msgstr "sprintf: Keine Argumente"
+
+#: builtin.c:1641 builtin.c:1652
msgid "printf: no arguments"
msgstr "printf: Keine Argumente"
-#: builtin.c:1474
+#: builtin.c:1695
msgid "sqrt: received non-numeric argument"
msgstr "sqrt: das Argument ist keine Zahl"
-#: builtin.c:1478
+#: builtin.c:1699
#, c-format
msgid "sqrt: called with negative argument %g"
msgstr "sqrt: das Argument %g ist negativ"
-#: builtin.c:1502
+#: builtin.c:1730
#, c-format
msgid "substr: length %g is not >= 1"
msgstr "substr: Länge %g ist nicht >= 1"
-#: builtin.c:1504
+#: builtin.c:1732
#, c-format
msgid "substr: length %g is not >= 0"
msgstr "substr: Länge %g ist nicht >= 0"
-#: builtin.c:1511
+#: builtin.c:1739
#, c-format
msgid "substr: non-integer length %g will be truncated"
msgstr "substr: Nicht ganzzahlige Länge %g wird abgeschnitten"
-#: builtin.c:1516
+#: builtin.c:1744
#, c-format
msgid "substr: length %g too big for string indexing, truncating to %g"
-msgstr ""
-"substr: Länge %g ist zu groß für Stringindizierung, wird auf %g gekürzt"
+msgstr "substr: Länge %g ist zu groß für Stringindizierung, wird auf %g gekürzt"
-#: builtin.c:1528
+#: builtin.c:1756
#, c-format
msgid "substr: start index %g is invalid, using 1"
msgstr "substr: Start-Index %g ist ungültig, 1 wird verwendet"
-#: builtin.c:1533
+#: builtin.c:1761
#, c-format
msgid "substr: non-integer start index %g will be truncated"
msgstr "substr: Nicht ganzzahliger Start-Wert %g wird abgeschnitten"
-#: builtin.c:1558
+#: builtin.c:1786
msgid "substr: source string is zero length"
msgstr "substr: Quellstring ist leer"
-#: builtin.c:1574
+#: builtin.c:1802
#, c-format
msgid "substr: start index %g is past end of string"
msgstr "substr: Start-Wert %g liegt hinter dem Ende des Strings"
-#: builtin.c:1582
+#: builtin.c:1810
#, c-format
-msgid ""
-"substr: length %g at start index %g exceeds length of first argument (%lu)"
-msgstr ""
-"substr: Länge %g am Start-Wert %g überschreitet die Länge des ersten "
-"Arguments (%lu)"
+msgid "substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr "substr: Länge %g am Start-Wert %g überschreitet die Länge des ersten Arguments (%lu)"
-#: builtin.c:1655
+#: builtin.c:1884
msgid "strftime: format value in PROCINFO[\"strftime\"] has numeric type"
msgstr "strftime: Formatwert in PROCINFO[\"strftime\"] ist numerischen Typs"
-#: builtin.c:1678
+#: builtin.c:1907
msgid "strftime: received non-numeric second argument"
msgstr "strftime: Das zweite Argument ist keine Zahl"
-#: builtin.c:1681
+#: builtin.c:1911
msgid "strftime: second argument less than 0 or too big for time_t"
-msgstr ""
+msgstr "strftime: das zweite Argument ist kleiner als 0 oder zu groß für time_t"
-#: builtin.c:1687
+#: builtin.c:1918
msgid "strftime: received non-string first argument"
msgstr "strftime: Das erste Argument ist kein String"
-#: builtin.c:1693
+#: builtin.c:1925
msgid "strftime: received empty format string"
msgstr "strftime: Der Format-String ist leer"
-#: builtin.c:1759
+#: builtin.c:1991
msgid "mktime: received non-string argument"
msgstr "mktime: Das Argument ist kein String"
-#: builtin.c:1776
+#: builtin.c:2008
msgid "mktime: at least one of the values is out of the default range"
msgstr "mktime: mindestens einer der Werte ist außerhalb des normalen Bereichs"
-#: builtin.c:1811
+#: builtin.c:2043
msgid "'system' function not allowed in sandbox mode"
msgstr "Die Funktion »system« ist im Sandbox-Modus nicht erlaubt"
-#: builtin.c:1816
+#: builtin.c:2048
msgid "system: received non-string argument"
msgstr "system: Das Argument ist kein String"
-#: builtin.c:1871 eval.c:1159 eval.c:1790 eval.c:1803
-#, c-format
-msgid "reference to uninitialized variable `%s'"
-msgstr "Referenz auf die nicht initialisierte Variable »%s«"
-
-#: builtin.c:1938
+#: builtin.c:2168
#, c-format
msgid "reference to uninitialized field `$%d'"
msgstr "Referenz auf das nicht initialisierte Feld »$%d«"
-#: builtin.c:2025
+#: builtin.c:2255
msgid "tolower: received non-string argument"
msgstr "tolower: das Argument ist kein String"
-#: builtin.c:2059
+#: builtin.c:2289
msgid "toupper: received non-string argument"
msgstr "toupper: das Argument ist kein String"
-#: builtin.c:2095
+#: builtin.c:2325 mpfr.c:672
msgid "atan2: received non-numeric first argument"
msgstr "atan2: das erste Argument ist keine Zahl"
-#: builtin.c:2097
+#: builtin.c:2327 mpfr.c:674
msgid "atan2: received non-numeric second argument"
msgstr "atan2: das zweite Argument ist keine Zahl"
-#: builtin.c:2116
+#: builtin.c:2346
msgid "sin: received non-numeric argument"
msgstr "sin: das Argument ist keine Zahl"
-#: builtin.c:2132
+#: builtin.c:2362
msgid "cos: received non-numeric argument"
msgstr "cos: das Argument ist keine Zahl"
-#: builtin.c:2185
+#: builtin.c:2415 mpfr.c:1156
msgid "srand: received non-numeric argument"
msgstr "srand: das Argument ist keine Zahl"
-#: builtin.c:2216
+#: builtin.c:2446
msgid "match: third argument is not an array"
msgstr "match: das dritte Argument ist kein Array"
-#: builtin.c:2480
+#: builtin.c:2718
msgid "gensub: third argument of 0 treated as 1"
msgstr "gensub: 0 als drittes Argument wird als 1 interpretiert"
-#: builtin.c:2773
+#: builtin.c:3014
msgid "lshift: received non-numeric first argument"
msgstr "lshift: das erste Argument ist keine Zahl"
-#: builtin.c:2775
+#: builtin.c:3016
msgid "lshift: received non-numeric second argument"
msgstr "lshift: das zweite Argument ist keine Zahl"
-#: builtin.c:2781
+#: builtin.c:3022
#, c-format
-msgid "lshift(%lf, %lf): negative values will give strange results"
-msgstr ""
-"lshift(%lf, %lf): Negative Werte werden zu merkwürdigen Ergebnissen führen"
+msgid "lshift(%f, %f): negative values will give strange results"
+msgstr "lshift(%f, %f): Negative Werte werden zu merkwürdigen Ergebnissen führen"
-#: builtin.c:2783
+#: builtin.c:3024
#, c-format
-msgid "lshift(%lf, %lf): fractional values will be truncated"
-msgstr "lshift(%lf, %lf): Dezimalteil wird abgeschnitten"
+msgid "lshift(%f, %f): fractional values will be truncated"
+msgstr "lshift(%f, %f): Dezimalteil wird abgeschnitten"
-#: builtin.c:2785
+#: builtin.c:3026
#, c-format
-msgid "lshift(%lf, %lf): too large shift value will give strange results"
-msgstr ""
-"lshift(%lf, %lf): Zu große Shift-Werte werden zu merkwürdigen Ergebnissen "
-"führen"
+msgid "lshift(%f, %f): too large shift value will give strange results"
+msgstr "lshift(%f, %f): Zu große Shift-Werte werden zu merkwürdigen Ergebnissen führen"
-#: builtin.c:2810
+#: builtin.c:3051
msgid "rshift: received non-numeric first argument"
msgstr "rshift: das erste Argument ist keine Zahl"
-#: builtin.c:2812
+#: builtin.c:3053
msgid "rshift: received non-numeric second argument"
msgstr "rshift: das zweite Argument ist keine Zahl"
-#: builtin.c:2818
+#: builtin.c:3059
#, c-format
-msgid "rshift(%lf, %lf): negative values will give strange results"
-msgstr ""
-"rshift (%lf, %lf): Negative Werte werden zu merkwürdigen Ergebnissen führen"
+msgid "rshift(%f, %f): negative values will give strange results"
+msgstr "rshift (%f, %f): Negative Werte werden zu merkwürdigen Ergebnissen führen"
+
+#: builtin.c:3061
+#, c-format
+msgid "rshift(%f, %f): fractional values will be truncated"
+msgstr "rshift(%f, %f): Dezimalteil wird abgeschnitten"
+
+#: builtin.c:3063
+#, c-format
+msgid "rshift(%f, %f): too large shift value will give strange results"
+msgstr "rshift(%f, %f): Zu große Shift-Werte werden zu merkwürdigen Ergebnissen führen"
+
+#: builtin.c:3088 mpfr.c:968
+msgid "and: called with less than two arguments"
+msgstr "and: wird mit weniger als zwei Argumenten aufgerufen"
+
+#: builtin.c:3093
+#, c-format
+msgid "and: argument %d is non-numeric"
+msgstr "and: das Argument %d ist nicht numerisch"
+
+#: builtin.c:3097
+#, c-format
+msgid "and: argument %d negative value %g will give strange results"
+msgstr "and: der negative Wert %2$g von Argument %1$d wird zu merkwürdigen Ergebnissen führen"
+
+#: builtin.c:3120 mpfr.c:1000
+msgid "or: called with less than two arguments"
+msgstr "or: wird mit weniger als zwei Argumenten aufgerufen"
+
+#: builtin.c:3125
+#, c-format
+msgid "or: argument %d is non-numeric"
+msgstr "or: das Argument %d ist nicht numerisch"
+
+#: builtin.c:3129
+#, c-format
+msgid "or: argument %d negative value %g will give strange results"
+msgstr "or: der negative Wert %2$g von Argument %1$d wird zu merkwürdigen Ergebnissen führen"
+
+#: builtin.c:3151 mpfr.c:1031
+msgid "xor: called with less than two arguments"
+msgstr "xor: wird mit weniger als zwei Argumenten aufgerufen"
+
+#: builtin.c:3157
+#, c-format
+msgid "xor: argument %d is non-numeric"
+msgstr "xor: das Argument %d ist nicht numerisch"
+
+#: builtin.c:3161
+#, c-format
+msgid "xor: argument %d negative value %g will give strange results"
+msgstr "xor: der negative Wert %2$g von Argument %1$d wird zu merkwürdigen Ergebnissen führen"
+
+#: builtin.c:3186 mpfr.c:787
+msgid "compl: received non-numeric argument"
+msgstr "compl: das erste Argument ist keine Zahl"
+
+#: builtin.c:3192
+#, c-format
+msgid "compl(%f): negative value will give strange results"
+msgstr "compl(%f): Der negative Wert wird zu merkwürdigen Ergebnissen führen"
+
+#: builtin.c:3194
+#, c-format
+msgid "compl(%f): fractional value will be truncated"
+msgstr "compl(%f): der Dezimalteil wird abgeschnitten"
+
+#: builtin.c:3363
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: »%s« ist keine gültige Locale-Kategorie"
+
+#: command.y:225
+#, c-format
+msgid "Type (g)awk statement(s). End with the command \"end\"\n"
+msgstr "Geben Sie »(g)awk Ausdrücke« und zum Abschluss \"end\" ein\n"
+
+#: command.y:289
+#, c-format
+msgid "invalid frame number: %d"
+msgstr "Ungültige Frame-Nummer: %d"
+
+#: command.y:295
+#, c-format
+msgid "info: invalid option - \"%s\""
+msgstr "info: Ungültige Option - »%s«"
+
+#: command.y:321
+#, c-format
+msgid "source \"%s\": already sourced."
+msgstr "Quelle »%s«: wurde bereits eingelesen."
+
+#: command.y:326
+#, c-format
+msgid "save \"%s\": command not permitted."
+msgstr "save »%s«: Der Befehl ist nicht zulässig."
+
+#: command.y:339
+msgid "Can't use command `commands' for breakpoint/watchpoint commands"
+msgstr "Der Befehl »commands« kann nicht für Break- bzw. Watchpoints verwendet werden"
+
+#: command.y:341
+msgid "no breakpoint/watchpoint has been set yet"
+msgstr "es wurden noch keine Break-/Watchpoints gesetzt"
+
+#: command.y:343
+msgid "invalid breakpoint/watchpoint number"
+msgstr "ungültige Break-/Watchpoint/Nummer"
+
+#: command.y:348
+#, c-format
+msgid "Type commands for when %s %d is hit, one per line.\n"
+msgstr "Befehle eingeben, die bei Erreichen von %s %d ausgeführt werden sollen, einer pro Zeile.\n"
+
+#: command.y:350
+#, c-format
+msgid "End with the command \"end\"\n"
+msgstr "Abschließen mit dem Befehl »end«\n"
+
+#: command.y:357
+msgid "`end' valid only in command `commands' or `eval'"
+msgstr "»end« ist nur innerhalb der Befehle »commands« oder »eval« zulässig"
+
+#: command.y:367
+msgid "`silent' valid only in command `commands'"
+msgstr "»silent« ist nur innerhalb des Befehls »commands« zuzlässig"
+
+#: command.y:373
+#, c-format
+msgid "trace: invalid option - \"%s\""
+msgstr "trace: Ungültige Option - »%s«"
+
+#: command.y:387
+msgid "condition: invalid breakpoint/watchpoint number"
+msgstr "condition: Unzulässige Break-/Watchpoint-Nummer"
+
+#: command.y:449
+msgid "argument not a string"
+msgstr "Das Argument ist keine Zeichenkette"
+
+#: command.y:459 command.y:464
+#, c-format
+msgid "option: invalid parameter - \"%s\""
+msgstr "option: ungültiger Parameter - »%s«"
+
+#: command.y:474
+#, c-format
+msgid "no such function - \"%s\""
+msgstr "Unbekannte Funktion - »%s«"
+
+#: command.y:531
+#, c-format
+msgid "enable: invalid option - \"%s\""
+msgstr "enable: Ungültige Option - »%s«"
+
+#: command.y:597
+#, c-format
+msgid "invalid range specification: %d - %d"
+msgstr "Ungültige Bereichsangabe: %d - %d"
+
+#: command.y:659
+msgid "non-numeric value for field number"
+msgstr "nichtnumerischer Wert als Feldnummer"
+
+#: command.y:680 command.y:687
+msgid "non-numeric value found, numeric expected"
+msgstr "nichtnumerischer Wert wo ein numerischer erwartet wurde"
+
+#: command.y:712 command.y:718
+msgid "non-zero integer value"
+msgstr "ganyzahliger Wert ungleich Null"
+
+#: command.y:817
+msgid "backtrace [N] - print trace of all or N innermost (outermost if N < 0) frames."
+msgstr "backtrace [N] - log von allen oder den N innersten (äußersten wenn N < 0) Rahmen."
+
+#: command.y:819
+msgid "break [[filename:]N|function] - set breakpoint at the specified location."
+msgstr "break [[Dateiname:]N|funktion - Breakpoint an der angegebenen Stelle setzen.]"
+
+#: command.y:821
+msgid "clear [[filename:]N|function] - delete breakpoints previously set."
+msgstr "clear [[Dateiname:]N|Funktion - zuvor gesetzte Breakpoints löschen."
+
+#: command.y:823
+msgid "commands [num] - starts a list of commands to be executed at a breakpoint(watchpoint) hit."
+msgstr "commands [Nr] - startet eine Liste von Befehlen, die bei Erreichen eines Break- bzw. Watchpoints ausgeführt werden."
+
+#: command.y:825
+msgid "condition num [expr] - set or clear breakpoint or watchpoint condition."
+msgstr "condition Nr [Ausdruck] - Bedingungen für einen Break-/Watchpoint setzen oder löschen."
+
+#: command.y:827
+msgid "continue [COUNT] - continue program being debugged."
+msgstr "continue [ANZAHL] - zu debuggendes Programm fortsetzen."
+
+#: command.y:829
+msgid "delete [breakpoints] [range] - delete specified breakpoints."
+msgstr "delete [Breakpoints] [Bereich] - angegebene Breakpoints entfernen."
+
+#: command.y:831
+msgid "disable [breakpoints] [range] - disable specified breakpoints."
+msgstr "disable [Breakpoints] [Bereich] - angegebene Breakpoints deaktivieren."
+
+#: command.y:833
+msgid "display [var] - print value of variable each time the program stops."
+msgstr "display [Var] - den Wert der Variablen bei jedem Programmstop ausgeben."
+
+#: command.y:835
+msgid "down [N] - move N frames down the stack."
+msgstr "down [N] - N Rahmen nach unten im Stack gehen."
+
+#: command.y:837
+msgid "dump [filename] - dump instructions to file or stdout."
+msgstr "dump [Dateiname] - Befehle in eine Datei oder auf der Standardausgabe ausgeben"
+
+#: command.y:839
+msgid "enable [once|del] [breakpoints] [range] - enable specified breakpoints."
+msgstr "enable [once|del] [Breakpoints] [Bereich] - die angegebenen Breakpoints aktivieren."
+
+#: command.y:841
+msgid "end - end a list of commands or awk statements."
+msgstr "end - beendet eine Liste von Befehlen oder AWK/Ausdrücken."
+
+#: command.y:843
+msgid "eval stmt|[p1, p2, ...] - evaluate awk statement(s)."
+msgstr "eval stmt[p1, p2, ...] - Awk-Ausdrücke auswerten."
+
+#: command.y:845
+msgid "finish - execute until selected stack frame returns."
+msgstr "finish - mit Ausführung fortfahren bis auisgewählter Rahmen verlassen wird."
+
+#: command.y:847
+msgid "frame [N] - select and print stack frame number N."
+msgstr "frame [N] - den Stackrahmen Nummer N auswählen und ausgeben."
+
+#: command.y:849
+msgid "help [command] - print list of commands or explanation of command."
+msgstr "help [Befehl] - gibt eine Liste der Befehle oder die Beschreibung eines einzelnen Befehls aus."
+
+#: command.y:851
+msgid "ignore N COUNT - set ignore-count of breakpoint number N to COUNT."
+msgstr "ignore N ZÄHLER - setzt den Ignorieren-Zähler von Breakpoint N auf ZÄHLER"
-#: builtin.c:2820
+#: command.y:853
+msgid "info topic - source|sources|variables|functions|break|frame|args|locals|display|watch."
+msgstr "info Thema - source|sources|variables|functions|break|frame|args|locals|display|watch."
+
+#: command.y:855
+msgid "list [-|+|[filename:]lineno|function|range] - list specified line(s)."
+msgstr "list [-|+|[Dateiname:]Zeilennr|Funktion|Breich] - die angegebenen Zeilen ausgeben"
+
+#: command.y:857
+msgid "next [COUNT] - step program, proceeding through subroutine calls."
+msgstr "next [ZÄHLER] - Programm schrittweise ausführen aber Subroutinen in einem Rutsch ausführen"
+
+#: command.y:859
+msgid "nexti [COUNT] - step one instruction, but proceed through subroutine calls."
+msgstr "nexti [ZÄHLER] - einen Befehl abarbeiten. aber Subroutinen in einem Rutsch ausführen"
+
+#: command.y:861
+msgid "option [name[=value]] - set or display debugger option(s)."
+msgstr "option [Name[=Wer]] - Debuggeroptionen setzen oder anzeigen."
+
+#: command.y:863
+msgid "print var [var] - print value of a variable or array."
+msgstr "print Var [Var] - den Wert einer Variablen oder eines Feldes ausgeben."
+
+#: command.y:865
+msgid "printf format, [arg], ... - formatted output."
+msgstr "printf Format, [Arg], ... - formatierte Ausgabe."
+
+#: command.y:867
+msgid "quit - exit debugger."
+msgstr "quit - Debugger verlassen"
+
+#: command.y:869
+msgid "return [value] - make selected stack frame return to its caller."
+msgstr "return [Wert] - den ausgewählten Stapelrahmen yu seinem Aufrufer zurück kehren lassen"
+
+#: command.y:871
+msgid "run - start or restart executing program."
+msgstr "run - startet die (erneute) Ausführung des Programms."
+
+#: command.y:874
+msgid "save filename - save commands from the session to file."
+msgstr "save Dateineme - sichert die Befehle der Sitzung in einer Datei."
+
+#: command.y:877
+msgid "set var = value - assign value to a scalar variable."
+msgstr "set Var = Wert - einer skalaren Variablen einen Wert zuweisen"
+
+#: command.y:879
+msgid "silent - suspends usual message when stopped at a breakpoint/watchpoint."
+msgstr "silent - unterdrückt die übliche Nachricht, wenn ein Break- bzw. Watchpoint erreicht wird."
+
+#: command.y:881
+msgid "source file - execute commands from file."
+msgstr "source Datei - die Befehle in Datei ausführen"
+
+#: command.y:883
+msgid "step [COUNT] - step program until it reaches a different source line."
+msgstr "step [ZÄHLER - Programm schrittweise ausführen bis es eine andere Quellzeile erricht."
+
+#: command.y:885
+msgid "stepi [COUNT] - step one instruction exactly."
+msgstr "stepi [ZÄHLER - genau eine Instruktion ausführen"
+
+#: command.y:887
+msgid "tbreak [[filename:]N|function] - set a temporary breakpoint."
+msgstr "tbreak [[Dateinem:]N|Funktion] - einen temporären Breakpoint setzen."
+
+#: command.y:889
+msgid "trace on|off - print instruction before executing."
+msgstr "trace on|off - Instruktionen vor der Ausführung ausgeben."
+
+#: command.y:891
+msgid "undisplay [N] - remove variable(s) from automatic display list."
+msgstr "undisplay [N] - Variablen von der Liste der automatisch Anzuzeigenden entfernen."
+
+#: command.y:893
+msgid "until [[filename:]N|function] - execute until program reaches a different line or line N within current frame."
+msgstr "until [[Dateiname:]N|Funktion - Ausführen bis das Programm eine andere Zeile erreicht oder N Zeilen im aktuellen Rahmen."
+
+#: command.y:895
+msgid "unwatch [N] - remove variable(s) from watch list."
+msgstr "unwatch [N} - Variablen von der Beobachtungsliste löschen"
+
+#: command.y:897
+msgid "up [N] - move N frames up the stack."
+msgstr "up [N] - N Rahmen im Kellerspeicher nach oben gehen."
+
+#: command.y:899
+msgid "watch var - set a watchpoint for a variable."
+msgstr "watch Var - einen Watchpoint für eine Variable setzen."
+
+#: command.y:1011 debug.c:401 msg.c:135
+#, c-format
+msgid "error: "
+msgstr "Fehler: "
+
+#: command.y:1051
+#, c-format
+msgid "can't read command (%s)\n"
+msgstr "der Befehl kann nicht gelesen werden (»%s«)\n"
+
+#: command.y:1065
+#, c-format
+msgid "can't read command (%s)"
+msgstr "der Befehl kann nicht gelesen werden (»%s«)"
+
+#: command.y:1116
+msgid "invalid character in command"
+msgstr "Ungültiges Zeichen im Befehl"
+
+#: command.y:1152
+#, c-format
+msgid "unknown command - \"%.*s\", try help"
+msgstr "unbekannter Befehl - »%.*s«, versuchen Sie es mit help"
+
+#: command.y:1222
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: command.y:1284
+msgid "invalid character"
+msgstr "Ungültiges Zeichen"
+
+#: command.y:1455
+#, c-format
+msgid "undefined command: %s\n"
+msgstr "undefinierter Befehl: %s\n"
+
+#: debug.c:252
+msgid "set or show the number of lines to keep in history file."
+msgstr "die Anzahl von Zeilen setzen oder anzeigen, die in der Historydatei gespeichert werden sollen."
+
+#: debug.c:254
+msgid "set or show the list command window size."
+msgstr "die Größe des Fensters für den Befehl list setzen oder anzeigen."
+
+#: debug.c:256
+msgid "set or show gawk output file."
+msgstr "die gawk Ausgabedatei setzen oder anzeigen."
+
+#: debug.c:258
+msgid "set or show debugger prompt."
+msgstr "das Debugger-Prompt setzen oder anzeigen."
+
+#: debug.c:260
+msgid "(un)set or show saving of command history (value=on|off)."
+msgstr "(rück)setzen des Sicherns der Befehlshistorie (on oder off)."
+
+#: debug.c:262
+msgid "(un)set or show saving of options (value=on|off)."
+msgstr "(rück)setzen des Sicherns von Optionen (on oder off)."
+
+#: debug.c:264
+msgid "(un)set or show instruction tracing (value=on|off)."
+msgstr "(rück)setzen des Verfolgens von Instruktionen (on oder off)."
+
+#: debug.c:345
+msgid "program not running."
+msgstr "Das Programm läuft nicht."
+
+#: debug.c:448 debug.c:606
+#, c-format
+msgid "can't read source file `%s' (%s)"
+msgstr "Die Quelldatei »%s« kann nicht gelesen werden (%s)"
+
+#: debug.c:453
+#, c-format
+msgid "source file `%s' is empty.\n"
+msgstr "Die Quelldatei »%s« ist leer.\n"
+
+#: debug.c:480
+msgid "no current source file."
+msgstr "keine aktuelle Quelldatei"
+
+#: debug.c:505
+#, c-format
+msgid "cannot find source file named `%s' (%s)"
+msgstr "Die Quelldatei »%s« kann nicht gefunden werden (%s)"
+
+#: debug.c:529
+#, c-format
+msgid "WARNING: source file `%s' modified since program compilation.\n"
+msgstr "WARNUNG: Quelldatei »%s« wurde seit der Programmübersetzung verändert.\n"
+
+#: debug.c:551
+#, c-format
+msgid "line number %d out of range; `%s' has %d lines"
+msgstr "die Zeilennummer %d ist außerhalb des gültigen Bereichs: »%s« hat %d Zeilen"
+
+#: debug.c:611
#, c-format
-msgid "rshift(%lf, %lf): fractional values will be truncated"
-msgstr "rshift(%lf, %lf): Dezimalteil wird abgeschnitten"
+msgid "unexpected eof while reading file `%s', line %d"
+msgstr "Unerwartetes Dateiende beim Lesen von Datei »%s<<, Zeile %d"
-#: builtin.c:2822
+#: debug.c:620
#, c-format
-msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgid "source file `%s' modified since start of program execution"
+msgstr "Quelldatei »%s« wurde seit dem Start des Programmes verändert"
+
+#: debug.c:732
+#, c-format
+msgid "Current source file: %s\n"
+msgstr "Derzeitige Quelldatei: %s\n"
+
+#: debug.c:733
+#, c-format
+msgid "Number of lines: %d\n"
+msgstr "Anzahl von Zeilen: %d\n"
+
+#: debug.c:740
+#, c-format
+msgid "Source file (lines): %s (%d)\n"
+msgstr "Quelldatei (Zeilen): %s (%d)\n"
+
+#: debug.c:754
+msgid ""
+"Number Disp Enabled Location\n"
+"\n"
msgstr ""
-"rshift(%lf, %lf): Zu große Shift-Werte werden zu merkwürdigen Ergebnissen "
-"führen"
+"Nummer Anz. Aktiv Ort\n"
+"\n"
-#: builtin.c:2847
-msgid "and: received non-numeric first argument"
-msgstr "and: das erste Argument ist keine Zahl"
+#: debug.c:765
+#, c-format
+msgid "\tno of hits = %ld\n"
+msgstr "\tAnzahl Treffer = %ld\n"
+
+#: debug.c:767
+#, c-format
+msgid "\tignore next %ld hit(s)\n"
+msgstr "\tdie nächsten %ld Treffer\n"
+
+#: debug.c:769 debug.c:909
+#, c-format
+msgid "\tstop condition: %s\n"
+msgstr "\tStopbedingung: %s\n"
+
+#: debug.c:771 debug.c:911
+msgid "\tcommands:\n"
+msgstr "\tBefehle:\n"
+
+#: debug.c:793
+#, c-format
+msgid "Current frame: "
+msgstr "Derzeitiger Stapelrahmen"
+
+#: debug.c:796
+#, c-format
+msgid "Called by frame: "
+msgstr "Aufgerufen aus Rahmen: "
-#: builtin.c:2849
-msgid "and: received non-numeric second argument"
-msgstr "and: das zweite Argument ist keine Zahl"
+#: debug.c:800
+#, c-format
+msgid "Caller of frame: "
+msgstr "Aufrufer des Rahmens: "
-#: builtin.c:2855
+#: debug.c:818
#, c-format
-msgid "and(%lf, %lf): negative values will give strange results"
+msgid "None in main().\n"
+msgstr "Keine in main().\n"
+
+#: debug.c:848
+msgid "No arguments.\n"
+msgstr "Keine Argumente.\n"
+
+#: debug.c:849
+msgid "No locals.\n"
+msgstr "Keine lokalen.\n"
+
+#: debug.c:857
+msgid ""
+"All defined variables:\n"
+"\n"
+msgstr ""
+"Alle definierten Variablen:\n"
+"\n"
+
+#: debug.c:867
+msgid ""
+"All defined functions:\n"
+"\n"
+msgstr ""
+"Alle definierten Funktionen:\n"
+"\n"
+
+#: debug.c:886
+msgid ""
+"Auto-display variables:\n"
+"\n"
+msgstr ""
+"Auto-display-Variablen:\n"
+"\n"
+
+#: debug.c:889
+msgid ""
+"Watch variables:\n"
+"\n"
msgstr ""
-"and(%lf, %lf): Negative Werte werden zu merkwürdigen Ergebnissen führen"
+"Yu überwachende Variablen:\n"
+"\n"
-#: builtin.c:2857
+#: debug.c:1029
#, c-format
-msgid "and(%lf, %lf): fractional values will be truncated"
-msgstr "and(%lf, %lf): Dezimalteil wird abgeschnitten"
+msgid "no symbol `%s' in current context\n"
+msgstr "im aktuellen Kontext gibt es kein Symbol mit Namen »%s«\n"
-#: builtin.c:2882
-msgid "or: received non-numeric first argument"
-msgstr "or: das erste Argument ist keine Zahl"
+#: debug.c:1041 debug.c:1427
+#, c-format
+msgid "`%s' is not an array\n"
+msgstr "»%s« ist kein Feld\n"
-#: builtin.c:2884
-msgid "or: received non-numeric second argument"
-msgstr "or: das zweite Argument ist keine Zahl"
+#: debug.c:1055
+#, c-format
+msgid "$%ld = uninitialized field\n"
+msgstr "$%ld = nicht initialisiertes Feld\n"
-#: builtin.c:2890
+#: debug.c:1076
#, c-format
-msgid "or(%lf, %lf): negative values will give strange results"
-msgstr "or(%lf, %lf): Negative Werte werden zu merkwürdigen Ergebnissen führen"
+msgid "array `%s' is empty\n"
+msgstr "Das Feld »%s« ist leer\n"
-#: builtin.c:2892
+#: debug.c:1119 debug.c:1171
#, c-format
-msgid "or(%lf, %lf): fractional values will be truncated"
-msgstr "or(%lf, %lf): Dezimalteil wird abgeschnitten"
+msgid "[\"%s\"] not in array `%s'\n"
+msgstr "[\"%s\"] ist in Feld »%s« nicht vorhanden\n"
-#: builtin.c:2920
-msgid "xor: received non-numeric first argument"
-msgstr "xor: das erste Argument ist keine Zahl"
+#: debug.c:1175
+#, c-format
+msgid "`%s[\"%s\"]' is not an array\n"
+msgstr "»%s[\"%s\"]« ist kein Feld\n"
-#: builtin.c:2922
-msgid "xor: received non-numeric second argument"
-msgstr "xor: das zweite Argument ist keine Zahl"
+#: debug.c:1236 debug.c:4964
+#, c-format
+msgid "`%s' is not a scalar variable"
+msgstr "»%s« ist keine skalare Variable"
-#: builtin.c:2928
+#: debug.c:1258 debug.c:4994
#, c-format
-msgid "xor(%lf, %lf): negative values will give strange results"
-msgstr "xor(%lf, %lf: Negative Werte werden zu merkwürdigen Ergebnissen führen"
+msgid "attempt to use array `%s[\"%s\"]' in a scalar context"
+msgstr "Es wird versucht, das Feld »%s[\"%s\"]« in einem Skalarkontext zu verwenden"
-#: builtin.c:2930
+#: debug.c:1280 debug.c:5005
#, c-format
-msgid "xor(%lf, %lf): fractional values will be truncated"
-msgstr "xor(%lf, %lf): Dezimalteil wird abgeschnitten"
+msgid "attempt to use scalar `%s[\"%s\"]' as array"
+msgstr "Es wird versucht, den Skalar »%s[\"%s\"]« als Feld zu verwenden"
-#: builtin.c:2954 builtin.c:2960
-msgid "compl: received non-numeric argument"
-msgstr "compl: das erste Argument ist keine Zahl"
+#: debug.c:1423
+#, c-format
+msgid "`%s' is a function"
+msgstr "»%s« ist eine Funktion"
-#: builtin.c:2962
+#: debug.c:1465
#, c-format
-msgid "compl(%lf): negative value will give strange results"
-msgstr "compl(%lf): Negativer Wert wird zu merkwürdigen Ergebnissen führen"
+msgid "watchpoint %d is unconditional\n"
+msgstr "Watchpoint %d ist bedingungslos\n"
-#: builtin.c:2964
+#: debug.c:1499
#, c-format
-msgid "compl(%lf): fractional value will be truncated"
-msgstr "compl(%lf): Dezimalteil wird abgeschnitten"
+msgid "No display item numbered %ld"
+msgstr "Kein anzuzeigendes Element mit Nummer %ld"
-#: builtin.c:3133
+#: debug.c:1502
#, c-format
-msgid "dcgettext: `%s' is not a valid locale category"
-msgstr "dcgettext: »%s« ist keine gültige Locale-Kategorie"
+msgid "No watch item numbered %ld"
+msgstr "Kein zu beobachtendes Element mit Nummer %ld"
+
+#: debug.c:1528
+#, c-format
+msgid "%d: [\"%s\"] not in array `%s'\n"
+msgstr "%d: [\"%s\"] ist in Feld »%s« nicht vorhanden\n"
+
+#: debug.c:1767
+msgid "attempt to use scalar value as array"
+msgstr "Es wird versucht, einen Skalar als Feld zu verwenden"
+
+#: debug.c:1856
+#, c-format
+msgid "Watchpoint %d deleted because parameter is out of scope.\n"
+msgstr "Watchpoint %d wurde gelöscht, weil der Parameter außerhalb des Gültigkeitsbereichs ist.\n"
+
+#: debug.c:1867
+#, c-format
+msgid "Display %d deleted because parameter is out of scope.\n"
+msgstr "Anzuzeigendes Element %d wurde gelöscht, weil der Parameter außerhalb des Gültigkeitsbereichs ist.\n"
+
+#: debug.c:1900
+#, c-format
+msgid " in file `%s', line %d\n"
+msgstr " in Datei »%s«, Zeile %d\n"
+
+#: debug.c:1921
+#, c-format
+msgid " at `%s':%d"
+msgstr " bei »%s«:%d"
+
+#: debug.c:1937 debug.c:2000
+#, c-format
+msgid "#%ld\tin "
+msgstr "#%ld\tin "
+
+#: debug.c:1974
+#, c-format
+msgid "More stack frames follow ...\n"
+msgstr "Weitere Stapelrahmen folgen ...\n"
+
+#: debug.c:2017
+msgid "invalid frame number"
+msgstr "Ungültige Rahmennummer"
+
+#: debug.c:2200
+#, c-format
+msgid "Note: breakpoint %d (enabled, ignore next %ld hits), also set at %s:%d"
+msgstr "Hinweis: Breakpont %d (aktiv, ignoriert für die nächsten %ld Treffer) wird auch an %s:%d gesetzt"
+
+#: debug.c:2207
+#, c-format
+msgid "Note: breakpoint %d (enabled), also set at %s:%d"
+msgstr "Hinweis: Breakpont %d (aktiv) wird auch an %s:%d gesetzt"
+
+#: debug.c:2214
+#, c-format
+msgid "Note: breakpoint %d (disabled, ignore next %ld hits), also set at %s:%d"
+msgstr "Hinweis: Breakpont %d (inaktiv, ignoriert für die nächsten %ld Treffer) wird auch von %s:%d gesetzt"
+
+#: debug.c:2221
+#, c-format
+msgid "Note: breakpoint %d (disabled), also set at %s:%d"
+msgstr "Hinweis: Breakpont %d (inaktiv) wird auch an %s:%d gesetzt"
+
+#: debug.c:2238
+#, c-format
+msgid "Breakpoint %d set at file `%s', line %d\n"
+msgstr "Breakpont %d wird auf Datei %s, Zeile %d gesetzt\n"
+
+#: debug.c:2340
+#, c-format
+msgid "Can't set breakpoint in file `%s'\n"
+msgstr "In Datei »%s« kann kein Breakpoint gesetzt werden\n"
-#: eval.c:412
+#: debug.c:2369 debug.c:2492 debug.c:3350
+#, c-format
+msgid "line number %d in file `%s' out of range"
+msgstr "Zeile Nummer %d in Datei »%s« liegt außerhalb des gültigen Bereichs"
+
+#: debug.c:2373
+#, c-format
+msgid "Can't find rule!!!\n"
+msgstr "Die Regel kann nicht gefunden werden!!!\n"
+
+#: debug.c:2375
+#, c-format
+msgid "Can't set breakpoint at `%s':%d\n"
+msgstr "In »%s«:%d kann kein Breakpoint gesetzt werden\n"
+
+#: debug.c:2387
+#, c-format
+msgid "Can't set breakpoint in function `%s'\n"
+msgstr "In Funktion »%s« kann kein Breakpoint gesetzt werden\n"
+
+#: debug.c:2403
+#, c-format
+msgid "breakpoint %d set at file `%s', line %d is unconditional\n"
+msgstr "Breakpoint %d gestzt auf Datei »%s« Zeile %d ist bedingungslos\n"
+
+#: debug.c:2508 debug.c:2530
+#, c-format
+msgid "Deleted breakpoint %d"
+msgstr "Breakpoint %d wurde gelöscht"
+
+#: debug.c:2514
+#, c-format
+msgid "No breakpoint(s) at entry to function `%s'\n"
+msgstr "Am Beginn von Funktion »%s« gibt es keine Breakpoints\n"
+
+#: debug.c:2541
+#, c-format
+msgid "No breakpoint at file `%s', line #%d\n"
+msgstr "Bei Datei »%s« Zeile %d gibt es keine Breakpoints\n"
+
+#: debug.c:2596 debug.c:2637 debug.c:2657 debug.c:2700
+msgid "invalid breakpoint number"
+msgstr "Ungtige Breakpoint/Nummer"
+
+#: debug.c:2612
+msgid "Delete all breakpoints? (y or n) "
+msgstr "Alle Breakpoints löschen? (j oder n) "
+
+#: debug.c:2613 debug.c:2923 debug.c:2976
+msgid "y"
+msgstr "j"
+
+#: debug.c:2662
+#, c-format
+msgid "Will ignore next %ld crossing(s) of breakpoint %d.\n"
+msgstr "die nächsten %ld Überschreitungen von Breakpoint %d werden ignoriert.\n"
+
+#: debug.c:2666
+#, c-format
+msgid "Will stop next time breakpoint %d is reached.\n"
+msgstr "wenn Breakpoint %d das nächste mal erreicht wird, wird angehalten\n"
+
+#: debug.c:2783
+#, c-format
+msgid "Can only debug programs provided with the `-f' option.\n"
+msgstr "Es können nur Programme untersucht werden, die mittels der Option »-f« übergeben wurden.\n"
+
+#: debug.c:2908
+#, c-format
+msgid "Failed to restart debugger"
+msgstr "Der Debugger konnte nicht neu gestartet werden"
+
+#: debug.c:2922
+msgid "Program already running. Restart from beginning (y/n)? "
+msgstr "das Programm läfut bereits. Neu starten (j/n}? "
+
+#: debug.c:2926
+#, c-format
+msgid "Program not restarted\n"
+msgstr "Das Programm wurde nicht neu gestartet\n"
+
+#: debug.c:2936
+#, c-format
+msgid "error: cannot restart, operation not allowed\n"
+msgstr "Fehler: Neustart nicht möglich da die Operation verboten ist\n"
+
+#: debug.c:2942
+#, c-format
+msgid "error (%s): cannot restart, ignoring rest of the commands\n"
+msgstr "Fehler (%s): Neustart nicht möglich, der Rest der Befehle wird ignoriert\n"
+
+#: debug.c:2950
+#, c-format
+msgid "Starting program: \n"
+msgstr "Das Programm wird gestartet: \n"
+
+#: debug.c:2959
+#, c-format
+msgid "Program exited %s with exit value: %d\n"
+msgstr "Das Programm verließ %s mit einem Rückgabewert: %d\n"
+
+#: debug.c:2975
+msgid "The program is running. Exit anyway (y/n)? "
+msgstr "Das Prgramm läuft. Trotzdem beenden (j/n) "
+
+#: debug.c:3010
+#, c-format
+msgid "Not stopped at any breakpoint; argument ignored.\n"
+msgstr "Es wird an keinem Breakpoint gestoppt; das Argument wird ignoriert.\n"
+
+#: debug.c:3015
+#, c-format
+msgid "invalid breakpoint number %d."
+msgstr "ungültige Breakpointnummer %d."
+
+#: debug.c:3020
+#, c-format
+msgid "Will ignore next %ld crossings of breakpoint %d.\n"
+msgstr "Die nächsten %ld Überschreitungen von Breakpoint %d werden ignoriert.\n"
+
+#: debug.c:3207
+#, c-format
+msgid "'finish' not meaningful in the outermost frame main()\n"
+msgstr "»finish« hat in main() des äußersten Rahmens keine Bedeutung\n"
+
+#: debug.c:3212
+#, c-format
+msgid "Run till return from "
+msgstr "Laufen bis zur Rückkehr von "
+
+#: debug.c:3255
+#, c-format
+msgid "'return' not meaningful in the outermost frame main()\n"
+msgstr "»return« hat in main() des äußersten Rahmens keine Bedeutung\n"
+
+#: debug.c:3369
+#, c-format
+msgid "Can't find specified location in function `%s'\n"
+msgstr "Die angegebene Position in Funktion »%s« kann nicht gefunden werden\n"
+
+#: debug.c:3377
+#, c-format
+msgid "invalid source line %d in file `%s'"
+msgstr "ungültige Quellzeilennummer %d in Datei »%s«"
+
+#: debug.c:3392
+#, c-format
+msgid "Can't find specified location %d in file `%s'\n"
+msgstr "Der Zielpunkt %d in Datei »%s« ist nicht auffindbar\n"
+
+#: debug.c:3424
+#, c-format
+msgid "element not in array\n"
+msgstr "Das Element ist kein Feld\n"
+
+#: debug.c:3424
+#, c-format
+msgid "untyped variable\n"
+msgstr "untypisierte Variable\n"
+
+#: debug.c:3466
+#, c-format
+msgid "Stopping in %s ...\n"
+msgstr "Stopp in %s ...\n"
+
+#: debug.c:3543
+#, c-format
+msgid "'finish' not meaningful with non-local jump '%s'\n"
+msgstr "»finish« hat bei dem nichtlokalen Sprung »%s« keine Bedeutung\n"
+
+#: debug.c:3550
+#, c-format
+msgid "'until' not meaningful with non-local jump '%s'\n"
+msgstr "»finish« hat bei dem nichtlokalen Sprung »%s« keine Bedeutung\n"
+
+#: debug.c:4185
+msgid "\t------[Enter] to continue or q [Enter] to quit------"
+msgstr "\t-[Eingabe] um fort zu fahren oder b [Eingabe] für geenden -"
+
+#: debug.c:4186
+msgid "q"
+msgstr "b"
+
+#: debug.c:5001
+#, c-format
+msgid "[\"%s\"] not in array `%s'"
+msgstr "[\"%s\"] ist in Feld »%s« nicht vorhanden"
+
+#: debug.c:5207
+#, c-format
+msgid "sending output to stdout\n"
+msgstr "Ausgabe wird an die Standardausgabe geschickt\n"
+
+#: debug.c:5247
+msgid "invalid number"
+msgstr "ungültige Zahl"
+
+#: debug.c:5381
+#, c-format
+msgid "`%s' not allowed in current context; statement ignored"
+msgstr "»%s« ist im aktuellen Kontext nicht zulässig; der Ausdruck wird ignoriert"
+
+#: debug.c:5389
+msgid "`return' not allowed in current context; statement ignored"
+msgstr "»reeturn« ist im aktuellen Kontext nicht zulässig; der Ausdruck wird ignoriert"
+
+#: debug.c:5590
+#, c-format
+msgid "No symbol `%s' in current context"
+msgstr "Im aktuelln Kontext gibt es kein Symbol »%s«"
+
+#: dfa.c:998 dfa.c:1001 dfa.c:1021 dfa.c:1031 dfa.c:1043 dfa.c:1094 dfa.c:1103
+#: dfa.c:1106 dfa.c:1111 dfa.c:1124 dfa.c:1191
+msgid "unbalanced ["
+msgstr "nicht geschlossene ["
+
+#: dfa.c:1052
+msgid "invalid character class"
+msgstr "ungültige Zeichenklasse"
+
+#: dfa.c:1228
+msgid "character class syntax is [[:space:]], not [:space:]"
+msgstr "Die Syntax für Zeichenklassen ist [[:space:]], nicht [:space:]"
+
+#: dfa.c:1280
+msgid "unfinished \\ escape"
+msgstr "nicht beendetes \\ Escape"
+
+#: dfa.c:1427 regcomp.c:161
+msgid "Invalid content of \\{\\}"
+msgstr "Ungültiger Inhalt von \\{\\}"
+
+#: dfa.c:1430 regcomp.c:176
+msgid "Regular expression too big"
+msgstr "Regulärer Ausdruck ist zu groß"
+
+#: dfa.c:1847
+msgid "unbalanced ("
+msgstr "nicht geschlossene ("
+
+#: dfa.c:1973
+msgid "no syntax specified"
+msgstr "keine Syntax angegeben"
+
+#: dfa.c:1981
+msgid "unbalanced )"
+msgstr "nicht geöffnete )"
+
+#: eval.c:394
#, c-format
msgid "unknown nodetype %d"
msgstr "Unbekannter Knotentyp %d"
-#: eval.c:423 eval.c:437
+#: eval.c:405 eval.c:419
#, c-format
msgid "unknown opcode %d"
msgstr "Unbekannter Opcode %d"
-#: eval.c:434
+#: eval.c:416
#, c-format
msgid "opcode %s not an operator or keyword"
msgstr "Opcode %s ist weder ein Operator noch ein Schlüsselwort"
-#: eval.c:488
+#: eval.c:472
msgid "buffer overflow in genflags2str"
msgstr "Pufferüberlauf in genflags2str"
-#: eval.c:698
+#: eval.c:675
#, c-format
msgid ""
"\n"
@@ -1016,843 +1809,1199 @@ msgstr ""
"\t# Funktions-Aufruf-Stack\n"
"\n"
-#: eval.c:725
+#: eval.c:704
msgid "`IGNORECASE' is a gawk extension"
msgstr "»IGNORECASE« ist eine gawk-Erweiterung"
-#: eval.c:754
+#: eval.c:736
msgid "`BINMODE' is a gawk extension"
msgstr "»BINMODE« ist eine gawk-Erweiterung"
-#: eval.c:812
+#: eval.c:794
#, c-format
msgid "BINMODE value `%s' is invalid, treated as 3"
msgstr "BINMODE Wert »%s« ist ungültig und wird als 3 behandelt"
-#: eval.c:902
+#: eval.c:885
#, c-format
msgid "bad `%sFMT' specification `%s'"
msgstr "Falsche »%sFMT«-Angabe »%s«"
-#: eval.c:980
+#: eval.c:969
msgid "turning off `--lint' due to assignment to `LINT'"
msgstr "»--lint« wird abgeschaltet, da an »LINT« zugewiesen wird"
-#: eval.c:1127 eval.c:1777
-#, c-format
-msgid "can't use function name `%s' as variable or array"
-msgstr "Funktion »%s« kann nicht als Variable oder Feld verwendet werden"
-
-#: eval.c:1158 eval.c:1789 eval.c:1802
+#: eval.c:1147
#, c-format
msgid "reference to uninitialized argument `%s'"
msgstr "Referenz auf nicht initialisiertes Argument »%s«"
-#: eval.c:1177
+#: eval.c:1148
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "Referenz auf die nicht initialisierte Variable »%s«"
+
+#: eval.c:1166
msgid "attempt to field reference from non-numeric value"
msgstr "Nicht numerischer Wert für Feldreferenz verwendet"
-#: eval.c:1179
+#: eval.c:1168
msgid "attempt to field reference from null string"
msgstr "Referenz auf ein Feld von einem Null-String"
-#: eval.c:1185
+#: eval.c:1176
#, c-format
msgid "attempt to access field %ld"
msgstr "Versuch des Zugriffs auf Feld %ld"
-#: eval.c:1194
+#: eval.c:1185
#, c-format
msgid "reference to uninitialized field `$%ld'"
msgstr "Referenz auf das nicht initialisierte Feld »$%ld«"
-#: eval.c:1256
+#: eval.c:1272
#, c-format
msgid "function `%s' called with more arguments than declared"
msgstr "Funktion »%s« mit zu vielen Argumenten aufgerufen"
-#: eval.c:1437
+#: eval.c:1473
#, c-format
msgid "unwind_stack: unexpected type `%s'"
msgstr "unwind_stack: unerwarteter Typ »%s«"
-#: eval.c:1532
+#: eval.c:1569
msgid "division by zero attempted in `/='"
msgstr "Division durch Null versucht in »/=«"
-#: eval.c:1539
+#: eval.c:1576
#, c-format
msgid "division by zero attempted in `%%='"
msgstr "Division durch Null versucht in »%%=«"
-#: eval.c:1876 eval.c:2122
-#, c-format
-msgid "attempt to use array `%s[\"%.*s\"]' in a scalar context"
-msgstr ""
-"Es wird versucht, das Feld »%s[\"%.*s\"]« in einem Skalarkontext zu verwenden"
+#: ext.c:89 ext.c:171
+msgid "extensions are not allowed in sandbox mode"
+msgstr "Erweiterungen sind im Sandbox-Modus nicht erlaubt"
-#: eval.c:1907
-msgid "assignment used in conditional context"
-msgstr "Zuweisung in einer Bedingung"
+#: ext.c:92
+msgid "-l / @load are gawk extensions"
+msgstr "-l / @load sind gawk-Erweiterungen"
-#: eval.c:1911
-msgid "statement has no effect"
-msgstr "Anweisung hat keinen Effekt"
+#: ext.c:95
+msgid "load_ext: received NULL lib_name"
+msgstr "load_ext: NULL lib_name erhalten"
-#: eval.c:2343
+#: ext.c:98
#, c-format
-msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
-msgstr ""
-"for-Schleife: Feld »%s« ändert seine Größe von %ld innerhalb der Schleife zu "
-"%ld"
+msgid "load_ext: cannot open library `%s' (%s)\n"
+msgstr "load_ext: Bibliothek »%s« kann nicht geöffnet werden (%s)\n"
-#: eval.c:2458
+#: ext.c:104
#, c-format
-msgid "function called indirectly through `%s' does not exist"
-msgstr "die durch »%s« indirekt aufgerufene Funktion existiert nicht"
+msgid "load_ext: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"
+msgstr "load_ext: Bibliothek »%s«: definiert »plugin_is_GPL_compatible« nicht (%s)\n"
-#: eval.c:2470
+#: ext.c:110
#, c-format
-msgid "function `%s' not defined"
-msgstr "Funktion »%s« ist nicht definiert"
+msgid "load_ext: library `%s': cannot call function `%s' (%s)\n"
+msgstr "load_ext: Bibliothek »%s«: Funktion »%s« kann nicht aufgerufen werden (%s)\n"
-#: eval.c:2511
+#: ext.c:114
#, c-format
-msgid "non-redirected `getline' invalid inside `%s' rule"
-msgstr "Nicht umgelenktes »getline« ist innerhalb der »%s«-Aktion unzuässig"
+msgid "load_ext: library `%s' initialization routine `%s' failed\n"
+msgstr "load_ext: die Initialisierungsroutine %2$s von Bibliothek »%1$s« ist gescheitert\n"
-#: eval.c:2600
-#, c-format
-msgid "error reading input file `%s': %s"
-msgstr "Fehler beim Lesen der Eingabedatei »%s«: %s"
+#: ext.c:174
+msgid "`extension' is a gawk extension"
+msgstr "»extension« ist eine gawk-Erweiterung"
-#: eval.c:2614
+#: ext.c:177
+msgid "extension: received NULL lib_name"
+msgstr "extension: NULL lib_name erhalten"
+
+#: ext.c:180
#, c-format
-msgid "`nextfile' cannot be called from a `%s' rule"
-msgstr "»nextfile« kann nicht aus einer »«%s-Regel aufgerufen werden"
+msgid "extension: cannot open library `%s' (%s)"
+msgstr "extension: Bibliothek »%s« kann nicht geöffnet werden (%s)"
-#: eval.c:2694
+#: ext.c:186
#, c-format
-msgid "`next' cannot be called from a `%s' rule"
-msgstr "»next« kann nicht in einer »%s«-Regel verwendet werden"
+msgid "extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)"
+msgstr "extension: Bibliothek »%s«: definiert »plugin_is_GPL_compatible« nicht (%s)"
-#: eval.c:2760
+#: ext.c:190
#, c-format
-msgid "Sorry, don't know how to interpret `%s'"
-msgstr "Entschuldigung, aber es ist unbekannt, wie »%s« zu interpretieren ist"
+msgid "extension: library `%s': cannot call function `%s' (%s)"
+msgstr "extension: Bibliothek »%s«: Funktion »%s« kann nicht aufgerufen werden (%s)"
-#: ext.c:64
-msgid "extensions are not allowed in sandbox mode"
-msgstr "Erweiterungen sind im Sandbox-Modus nicht erlaubt"
+#: ext.c:221
+msgid "make_builtin: missing function name"
+msgstr "make_builtin: Funktionsname fehlt"
-#: ext.c:70 ext.c:75
-msgid "`extension' is a gawk extension"
-msgstr "»extension« ist eine gawk-Erweiterung"
+#: ext.c:236
+#, c-format
+msgid "make_builtin: can't redefine function `%s'"
+msgstr "make_builtin: Funktion »%s« kann nicht neu definiert werden"
-#: ext.c:85
+#: ext.c:240
#, c-format
-msgid "fatal: extension: cannot open `%s' (%s)\n"
-msgstr "Fatal: extension: »%s« kann nicht geöffnet werden (%s)\n"
+msgid "make_builtin: function `%s' already defined"
+msgstr "make_builtin: Funktion »%s« wurde bereits definiert"
-#: ext.c:94
+#: ext.c:244
#, c-format
-msgid ""
-"fatal: extension: library `%s': does not define "
-"`plugin_is_GPL_compatible' (%s)\n"
-msgstr ""
-"Fatal: Erweiterung: Bibliothek »%s«: definiert »plugin_is_GPL_compatible« "
-"nicht (%s)\n"
+msgid "make_builtin: function name `%s' previously defined"
+msgstr "make_builtin: Funktion »%s« wurde bereits vorher definiert"
-#: ext.c:103
+#: ext.c:246
#, c-format
-msgid "fatal: extension: library `%s': cannot call function `%s' (%s)\n"
-msgstr ""
-"Fatal: Erweiterung: Bibliothek »%s«: Funktion »%s« kann nicht aufgerufen "
-"werden (%s)\n"
+msgid "make_builtin: can't use gawk built-in `%s' as function name"
+msgstr "make_builtin: die in gawk eingebaute Funktion »%s« kann nicht als Funktionsname verwendet werden"
+
+#: ext.c:249 ext.c:304
+#, c-format
+msgid "make_builtin: negative argument count for function `%s'"
+msgstr "make_builtin: negative Anzahl von Argumenten für Funktion »%s«"
-#: ext.c:137
+#: ext.c:276
msgid "extension: missing function name"
msgstr "Erweiterung: Funktionsname fehlt"
-#: ext.c:142
+#: ext.c:279 ext.c:283
#, c-format
msgid "extension: illegal character `%c' in function name `%s'"
-msgstr "Erweiterung: unzulässiges Zeichen »%c« in Funktionsname »%s«"
+msgstr "extension: unzulässiges Zeichen »%c« in Funktionsname »%s«"
-#: ext.c:151
+#: ext.c:291
#, c-format
msgid "extension: can't redefine function `%s'"
-msgstr "Erweiterung: Funktion »%s« kann nicht neu definiert werden"
+msgstr "extension: Funktion »%s« kann nicht neu definiert werden"
-#: ext.c:155
+#: ext.c:295
#, c-format
msgid "extension: function `%s' already defined"
-msgstr "Erweiterung: Funktion »%s« wurde bereits definiert"
+msgstr "extension: Funktion »%s« wurde bereits definiert"
-#: ext.c:160
+#: ext.c:299
#, c-format
msgid "extension: function name `%s' previously defined"
-msgstr "Erweiterung: Funktion »%s« wurde bereits vorher definiert"
+msgstr "extension: Funktion »%s« wurde bereits vorher definiert"
-#: ext.c:162
+#: ext.c:301
#, c-format
msgid "extension: can't use gawk built-in `%s' as function name"
-msgstr ""
-"Erweiterung: die eingebaute Funktion »%s« kann nicht als Funktionsname "
-"verwendet werden"
-
-#: ext.c:166
-#, c-format
-msgid "make_builtin: negative argument count for function `%s'"
-msgstr "make_builtin: negative Anzahl von Argumenten für Funktion »%s«"
+msgstr "extension: die eingebaute Funktion »%s« kann nicht als Funktionsname verwendet werden"
-#: ext.c:269
+#: ext.c:375
#, c-format
msgid "function `%s' defined to take no more than %d argument(s)"
-msgstr ""
-"Funktion »%s« wird als Funktion definiert, die nie mehr als %d Argument(e) "
-"akzeptiert"
+msgstr "Funktion »%s« wird als Funktion definiert, die nie mehr als %d Argument(e) akzeptiert"
-#: ext.c:272
+#: ext.c:378
#, c-format
msgid "function `%s': missing argument #%d"
msgstr "Funktion »%s«: fehlendes Argument #%d"
-#: ext.c:289
+#: ext.c:395
#, c-format
msgid "function `%s': argument #%d: attempt to use scalar as an array"
-msgstr ""
-"Funktion »%s«: Argument #%d: Es wird versucht, einen Skalar als Feld zu "
-"verwenden"
+msgstr "Funktion »%s«: Argument #%d: Es wird versucht, einen Skalar als Feld zu verwenden"
-#: ext.c:293
+#: ext.c:399
#, c-format
msgid "function `%s': argument #%d: attempt to use array as a scalar"
-msgstr ""
-"Funktion »%s«: Argument #%d: Es wird versucht, ein Feld als Skalar zu "
-"verwenden"
+msgstr "Funktion »%s«: Argument #%d: Es wird versucht, ein Feld als Skalar zu verwenden"
+
+#: ext.c:413
+msgid "dynamic loading of library not supported"
+msgstr "das dynamische Laden von Bibliotheken wird nicht unterstützt"
+
+#: extension/filefuncs.c:159
+msgid "chdir: called with incorrect number of arguments, expecting 1"
+msgstr "chdir: Aufgruf mit einer ungültigen Anzahl von Argumenten, 1 wird erwartet"
+
+#: extension/filefuncs.c:439
+#, c-format
+msgid "stat: unable to read symbolic link `%s'"
+msgstr "stst: die symbolische Verknüpfung »%s« kann nicht gelesenb werden"
+
+#: extension/filefuncs.c:472
+msgid "stat: called with wrong number of arguments"
+msgstr "stat: Aufruf mit falscher Anzahl Argumenten"
+
+#: extension/filefuncs.c:479
+msgid "stat: bad parameters"
+msgstr "stat: ungültige Parameter"
+
+#: extension/filefuncs.c:533
+#, c-format
+msgid "fts init: could not create variable %s"
+msgstr "fts_init: Variable %s konnte nicht angelegt werden"
+
+#: extension/filefuncs.c:554
+msgid "fts is not supported on this system"
+msgstr "fts wird auf diesem System nicht unterstützt"
+
+#: extension/filefuncs.c:573
+msgid "fill_stat_element: could not create array"
+msgstr "fill_stat_element: das Feld konnte nicht angelegt werden"
+
+#: extension/filefuncs.c:582
+msgid "fill_stat_element: could not set element"
+msgstr "fill_stat_element: das Element konnte nicht gesetzt werden"
-#: ext.c:306
-msgid "Operation Not Supported"
-msgstr "Die Operation wird nicht unterstützt"
+#: extension/filefuncs.c:597
+msgid "fill_path_element: could not set element"
+msgstr "fill_path_element: das Element konnte nicht gesetzt werden"
-#: field.c:328
+#: extension/filefuncs.c:613
+msgid "fill_error_element: could not set element"
+msgstr "fill_error_element: das Element konnte nicht gesetzt werden"
+
+#: extension/filefuncs.c:660 extension/filefuncs.c:707
+msgid "fts-process: could not create array"
+msgstr "fts-process: das Feld konnte nicht anglegt werden"
+
+#: extension/filefuncs.c:670 extension/filefuncs.c:717
+#: extension/filefuncs.c:735
+msgid "fts-process: could not set element"
+msgstr "fts-process: das Element konnte nicht gesetzt werden"
+
+#: extension/filefuncs.c:784
+msgid "fts: called with incorrect number of arguments, expecting 3"
+msgstr "fts: Aufruf mit falscher Anzahl an Argumenten, es werden 3 erwartet"
+
+#: extension/filefuncs.c:787
+msgid "fts: bad first parameter"
+msgstr "fts: ungültiger Parameter"
+
+#: extension/filefuncs.c:793
+msgid "fts: bad second parameter"
+msgstr "fts: ungültiger zweiter Parameter"
+
+#: extension/filefuncs.c:799
+msgid "fts: bad third parameter"
+msgstr "%s: ist ein Parameter"
+
+#: extension/filefuncs.c:806
+msgid "fts: could not flatten array\n"
+msgstr "fts: ungültiger dritter Parameter\n"
+
+#: extension/filefuncs.c:824
+msgid "fts: ignoring sneaky FTS_NOSTAT flag. nyah, nyah, nyah."
+msgstr "fts: die heimtückische Kennung FTS_NOSTAT wird ignoriert, ätsch bätsch."
+
+#: extension/filefuncs.c:841
+msgid "fts: clear_array() failed\n"
+msgstr "fts: clear_array() ist gescheitert\n"
+
+#: extension/fnmatch.c:112
+msgid "fnmatch: called with less than three arguments"
+msgstr "fnmatch: Aufruf mit weniger als drei Argumenten"
+
+#: extension/fnmatch.c:115
+msgid "fnmatch: called with more than three arguments"
+msgstr "fnmatch: Aufruf mit mehr als drei Argumenten"
+
+#: extension/fnmatch.c:118
+msgid "fnmatch: could not get first argument"
+msgstr "fnmatch: Das erste Argument konnte nicht gelesen werden"
+
+#: extension/fnmatch.c:123
+msgid "fnmatch: could not get second argument"
+msgstr "fnmatch: Das zweite Argument konnte nicht gelesen werden"
+
+#: extension/fnmatch.c:128
+msgid "fnmatch: could not get third argument"
+msgstr "fnmatch: Das dritte Argument konnte nicht gelesen werden"
+
+#: extension/fnmatch.c:141
+msgid "fnmatch is not implemented on this system\n"
+msgstr "fnmatch ist auf diesem System nicht implementiert\n"
+
+#: extension/fnmatch.c:173
+msgid "fnmatch init: could not add FNM_NOMATCH variable"
+msgstr "fnmatch_init: eine FNM_NOMATCH-Variable konnte nicht hinzu gefügt werden"
+
+#: extension/fnmatch.c:183
+#, c-format
+msgid "fnmatch init: could not set array element %s"
+msgstr "fnmatch_init: das Feldelement %s konnte nicht initialisiert werden"
+
+#: extension/fnmatch.c:193
+msgid "fnmatch init: could not install FNM array"
+msgstr "fnmatch_init: das FNM-Feld konnte nicht gesetzt werden."
+
+#: extension/fork.c:81
+msgid "fork: called with too many arguments"
+msgstr "fork: Aufruf mit zu vielen Argumenten"
+
+#: extension/fork.c:94
+msgid "fork: PROCINFO is not an array!"
+msgstr "fork: PROCINFO ist kein Feld!"
+
+#: extension/fork.c:118
+msgid "waitpid: called with too many arguments"
+msgstr "waitpid: Aufruf mit zu vielen Argumenten"
+
+#: extension/fork.c:126
+msgid "wait: called with no arguments"
+msgstr "wait: Aufruf ohne Argumente"
+
+#: extension/fork.c:143
+msgid "wait: called with too many arguments"
+msgstr "wait: Aufruf mit zu vielen Argumenten"
+
+#: extension/inplace.c:130
+msgid "inplace_begin: in-place editing already active"
+msgstr "inplace_begin: direktes Editieren ist bereits aktiv"
+
+#: extension/inplace.c:133 extension/inplace.c:207
+#, c-format
+msgid "inplace_begin: expects 2 arguments but called with %d"
+msgstr "inplace_begin: erwartet 2 Argumente aber wurde aufgerufen mit %d"
+
+#: extension/inplace.c:136
+msgid "inplace_begin: cannot retrieve 1st argument as a string filename"
+msgstr "inplace_begin: das erste Argument ist kein Dateiname"
+
+#: extension/inplace.c:144
+#, c-format
+msgid "inplace_begin: disabling in-place editing for invalid FILENAME `%s'"
+msgstr "inplace_begin: direktes Editieren wird deaktiviert wegen des ungültigen Dateinamens »%s«"
+
+#: extension/inplace.c:151
+#, c-format
+msgid "inplace_begin: Cannot stat `%s' (%s)"
+msgstr "inplace_begin: Status von »%s« kann nicht ermittelt werden (%s)"
+
+#: extension/inplace.c:158
+#, c-format
+msgid "inplace_begin: `%s' is not a regular file"
+msgstr "inplace_begin: »%s« ist keine reguläre Datei"
+
+#: extension/inplace.c:169
+#, c-format
+msgid "inplace_begin: mkstemp(`%s') failed (%s)"
+msgstr "inplace_begin: mkstemp(»%s«) ist gescheitert (%s)"
+
+#: extension/inplace.c:178
+#, c-format
+msgid "inplace_begin: chmod failed (%s)"
+msgstr "inplace_begin:: chmod ist gescheitert (%s)"
+
+#: extension/inplace.c:185
+#, c-format
+msgid "inplace_begin: dup(stdout) failed (%s)"
+msgstr "inplace_begin: dup(stdout) ist gescheitert (%s)"
+
+#: extension/inplace.c:188
+#, c-format
+msgid "inplace_begin: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_begin: dup2(%d, stdout) ist gescheitert (%s)"
+
+#: extension/inplace.c:191
+#, c-format
+msgid "inplace_begin: close(%d) failed (%s)"
+msgstr "inplace_begin: close(%d) ist gescheitert (%s)"
+
+#: extension/inplace.c:210
+msgid "inplace_end: cannot retrieve 1st argument as a string filename"
+msgstr "inplace_end: das erste Argument ist kein Dateiname"
+
+#: extension/inplace.c:217
+msgid "inplace_end: in-place editing not active"
+msgstr "inplace_end: direktes Editieren ist nicht aktiv"
+
+#: extension/inplace.c:223
+#, c-format
+msgid "inplace_end: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_end: dup2(%d, stdout) ist gescheitert (%s)"
+
+#: extension/inplace.c:226
+#, c-format
+msgid "inplace_end: close(%d) failed (%s)"
+msgstr "inplace_end: close(%d) ist gescheitert (%s)"
+
+#: extension/inplace.c:230
+#, c-format
+msgid "inplace_end: fsetpos(stdout) failed (%s)"
+msgstr "inplace_end: fsetpos(stdout) ist gescheitert (%s)"
+
+#: extension/inplace.c:243
+#, c-format
+msgid "inplace_end: link(`%s', `%s') failed (%s)"
+msgstr "inplace_end: link(»%s«, »%s«) ist gescheitert (%s)"
+
+#: extension/inplace.c:253
+#, c-format
+msgid "inplace_end: rename(`%s', `%s') failed (%s)"
+msgstr "inplace_end: rename(»%s«, »%s«) ist gescheitert (%s)"
+
+#: extension/ordchr.c:69
+msgid "ord: called with too many arguments"
+msgstr "ord: Aufruf mit yu vielen Argumenten"
+
+#: extension/ordchr.c:75
+msgid "ord: called with no arguments"
+msgstr "ord: Aufruf ohne Argumente"
+
+#: extension/ordchr.c:77
+msgid "ord: called with inappropriate argument(s)"
+msgstr "ord: Aufruf mit ungeeigneten Argumenten"
+
+#: extension/ordchr.c:99
+msgid "chr: called with too many arguments"
+msgstr "chr: Aufruf mit zu vielen Argumenten"
+
+#: extension/ordchr.c:109
+msgid "chr: called with no arguments"
+msgstr "chr: Aufruf ohne Argumente"
+
+#: extension/ordchr.c:111
+msgid "chr: called with inappropriate argument(s)"
+msgstr "chr: Aufruf mit ungeeigneten Argumenten"
+
+#: extension/readdir.c:277
+#, c-format
+msgid "dir_take_control_of: opendir/fdopendir failed: %s"
+msgstr "dir_take_control_of: opendir/fdopendir ist gescheitert: %s"
+
+#: extension/readfile.c:84
+msgid "readfile: called with too many arguments"
+msgstr "readfile: Aufruf mit zu vielen Argumenten"
+
+#: extension/readfile.c:118
+msgid "readfile: called with no arguments"
+msgstr "readfile: Aufruf ohen Argumente"
+
+#: extension/rwarray.c:124
+msgid "writea: called with too many arguments"
+msgstr "writea: Aufruf mit zu vielen Argumenten"
+
+#: extension/rwarray.c:131
+#, c-format
+msgid "do_writea: argument 0 is not a string\n"
+msgstr "do_writea: das Argument 0 ist keine Zeichenkette\n"
+
+#: extension/rwarray.c:137
+#, c-format
+msgid "do_writea: argument 1 is not an array\n"
+msgstr "do_writea: das Argument 1 ist kein Feld\n"
+
+#: extension/rwarray.c:184
+#, c-format
+msgid "write_array: could not flatten array\n"
+msgstr "write_array: das Feld konnte nicht niveliert werden\n"
+
+#: extension/rwarray.c:198
+#, c-format
+msgid "write_array: could not release flattened array\n"
+msgstr "write_array: das nivelierte Feld konnte nicht frei gegeben werden\n"
+
+#: extension/rwarray.c:280
+msgid "reada: called with too many arguments"
+msgstr "reada: Aufruf mit zu vielen Argumenten"
+
+#: extension/rwarray.c:287
+#, c-format
+msgid "do_reada: argument 0 is not a string\n"
+msgstr "do_reada: Argument 0 ist keine Zeichenkette\n"
+
+#: extension/rwarray.c:293
+#, c-format
+msgid "do_reada: argument 1 is not an array\n"
+msgstr "do_reada: Argument 1 ist kein Feld\n"
+
+#: extension/rwarray.c:337
+#, c-format
+msgid "do_reada: clear_array failed\n"
+msgstr "do_reada: clear_array ist gescheitert\n"
+
+#: extension/rwarray.c:374
+#, c-format
+msgid "read_array: set_array_element failed\n"
+msgstr "read_array: set_array_element ist gescheitert\n"
+
+#: extension/time.c:106
+msgid "gettimeofday: ignoring arguments"
+msgstr "gettimeofday: die Argumente werden ignoriert"
+
+#: extension/time.c:137
+msgid "gettimeofday: not supported on this platform"
+msgstr "gettimeofday: wird auf dieser Plattform nicht unterstützt"
+
+#: extension/time.c:158
+msgid "sleep: called with too many arguments"
+msgstr "sleep: Aufruf mit zu vielen Argumenten"
+
+#: extension/time.c:161
+msgid "sleep: missing required numeric argument"
+msgstr "sleep: das erforderliche numerische Argument fehlt"
+
+#: extension/time.c:167
+msgid "sleep: argument is negative"
+msgstr "sleep: das Argument ist negativ"
+
+#: extension/time.c:201
+msgid "sleep: not supported on this platform"
+msgstr "sleep: wird auf dieser Plattform nicht unterstützt"
+
+#: field.c:345
msgid "NF set to negative value"
msgstr "NF wird ein negativer Wert zugewiesen"
-#: field.c:951 field.c:958 field.c:962
+#: field.c:971 field.c:978 field.c:982
msgid "split: fourth argument is a gawk extension"
msgstr "split: das vierte Argument ist eine gawk-Erweiterung"
-#: field.c:955
+#: field.c:975
msgid "split: fourth argument is not an array"
msgstr "split: das vierte Argument ist kein Feld"
-#: field.c:969
+#: field.c:989
msgid "split: second argument is not an array"
msgstr "split: das zweite Argument ist kein Feld"
-#: field.c:973
+#: field.c:993
msgid "split: cannot use the same array for second and fourth args"
-msgstr ""
-"split: als zweites und viertes Argument kann nicht das gleiche Feld "
-"verwendet werden"
+msgstr "split: als zweites und viertes Argument kann nicht das gleiche Feld verwendet werden"
-#: field.c:978
+#: field.c:998
msgid "split: cannot use a subarray of second arg for fourth arg"
-msgstr ""
-"split: Ein untergeordnetes Feld des zweiten Arguments kann nicht als viertes "
-"Argument verwendet werden"
+msgstr "split: Ein untergeordnetes Feld des zweiten Arguments kann nicht als viertes Argument verwendet werden"
-#: field.c:981
+#: field.c:1001
msgid "split: cannot use a subarray of fourth arg for second arg"
-msgstr ""
-"split: Ein untergeordnetes Feld des vierten Arguments kann nicht als zweites "
-"Argument verwendet werden"
+msgstr "split: Ein untergeordnetes Feld des vierten Arguments kann nicht als zweites Argument verwendet werden"
-#: field.c:1010
+#: field.c:1032
msgid "split: null string for third arg is a gawk extension"
msgstr "split: Null-String als drittes Argument ist eine gawk-Erweiterung"
-#: field.c:1050
+#: field.c:1072
msgid "patsplit: fourth argument is not an array"
msgstr "patsplit: Das vierte Argument ist kein Feld"
-#: field.c:1055
+#: field.c:1077
msgid "patsplit: second argument is not an array"
msgstr "patsplit: Das zweite Argument ist kein Feld"
-#: field.c:1061
+#: field.c:1083
msgid "patsplit: third argument must be non-null"
msgstr "patsplit: Das dritte Argument darf nicht Null sein"
-#: field.c:1065
+#: field.c:1087
msgid "patsplit: cannot use the same array for second and fourth args"
-msgstr ""
-"patsplit: als zweites und viertes Argument kann nicht das gleiche Feld "
-"verwendet werden"
+msgstr "patsplit: als zweites und viertes Argument kann nicht das gleiche Feld verwendet werden"
-#: field.c:1070
+#: field.c:1092
msgid "patsplit: cannot use a subarray of second arg for fourth arg"
-msgstr ""
-"patsplit: Ein untergeordnetes Feld des zweiten Arguments kann nicht als "
-"viertes Argument verwendet werden"
+msgstr "patsplit: Ein untergeordnetes Feld des zweiten Arguments kann nicht als viertes Argument verwendet werden"
-#: field.c:1073
+#: field.c:1095
msgid "patsplit: cannot use a subarray of fourth arg for second arg"
-msgstr ""
-"patsplit: Ein untergeordnetes Feld des vierten Arguments kann nicht als "
-"zweites Argument verwendet werden"
+msgstr "patsplit: Ein untergeordnetes Feld des vierten Arguments kann nicht als zweites Argument verwendet werden"
-#: field.c:1110
+#: field.c:1133
msgid "`FIELDWIDTHS' is a gawk extension"
msgstr "»FIELDWIDTHS« ist eine gawk-Erweiterung"
-#: field.c:1173
+#: field.c:1197
#, c-format
msgid "invalid FIELDWIDTHS value, near `%s'"
msgstr "ungültiger FIELDWIDTHS-Wert nah bei »%s«"
-#: field.c:1246
+#: field.c:1270
msgid "null string for `FS' is a gawk extension"
msgstr "Null-String für »FS« ist eine gawk-Erweiterung"
-#: field.c:1250
+#: field.c:1274
msgid "old awk does not support regexps as value of `FS'"
msgstr "Das alte awk unterstützt keine regulären Ausdrücke als Wert von »FS«"
-#: field.c:1369
+#: field.c:1393
msgid "`FPAT' is a gawk extension"
msgstr "»FPAT« ist eine gawk-Erweiterung"
-#: getopt.c:574 getopt.c:590
+#: gawkapi.c:146
+msgid "awk_value_to_node: received null retval"
+msgstr "awk_value_to_node: Rückgabewert Null erhalten"
+
+#: gawkapi.c:384
+msgid "node_to_awk_value: received null node"
+msgstr "node_to_awk_value: Null-Knoten erhalten"
+
+#: gawkapi.c:387
+msgid "node_to_awk_value: received null val"
+msgstr "node_to_awk_value: Null-Wert erhalten"
+
+#: gawkapi.c:808
+msgid "remove_element: received null array"
+msgstr "remove_element: Null-Feld erhalten"
+
+#: gawkapi.c:811
+msgid "remove_element: received null subscript"
+msgstr "remove_element: Null-Index erhalten"
+
+#: gawkapi.c:948
+#, c-format
+msgid "api_flatten_array: could not convert index %d\n"
+msgstr "api_flatten_array: Index %d konnte nicht umgewandelt werden\n"
+
+#: gawkapi.c:953
+#, c-format
+msgid "api_flatten_array: could not convert value %d\n"
+msgstr "api_flatten_array: Wert %d konnte nicht umgewandelt werden\n"
+
+#: getopt.c:604 getopt.c:633
#, c-format
-msgid "%s: option '%s' is ambiguous\n"
-msgstr "%s: Option »%s« ist mehrdeutig\n"
+msgid "%s: option '%s' is ambiguous; possibilities:"
+msgstr "%s: Option »%s« ist mehrdeutig; Mögliche Bedautung:"
-#: getopt.c:623 getopt.c:627
+#: getopt.c:679 getopt.c:683
#, c-format
msgid "%s: option '--%s' doesn't allow an argument\n"
msgstr "%s: Die Option »--%s« hat keine Argumente\n"
-#: getopt.c:636 getopt.c:641
+#: getopt.c:692 getopt.c:697
#, c-format
msgid "%s: option '%c%s' doesn't allow an argument\n"
msgstr "%s: Die Option »%c%s« hat keine Argument\n"
-#: getopt.c:684 getopt.c:703
+#: getopt.c:740 getopt.c:759
#, c-format
msgid "%s: option '--%s' requires an argument\n"
msgstr "%s: Die Option »%s« erfordert ein Argument\n"
-#: getopt.c:741 getopt.c:744
+#: getopt.c:797 getopt.c:800
#, c-format
msgid "%s: unrecognized option '--%s'\n"
msgstr "%s: Die Option »--%s« ist unbekannt\n"
-#: getopt.c:752 getopt.c:755
+#: getopt.c:808 getopt.c:811
#, c-format
msgid "%s: unrecognized option '%c%s'\n"
msgstr "%s: Die Option »%c%s« ist unbekannt\n"
-#: getopt.c:804 getopt.c:807
+#: getopt.c:860 getopt.c:863
#, c-format
msgid "%s: invalid option -- '%c'\n"
msgstr "%s: Ungültige Option -- »%c«\n"
-#: getopt.c:857 getopt.c:874 getopt.c:1082 getopt.c:1100
+#: getopt.c:916 getopt.c:933 getopt.c:1143 getopt.c:1161
#, c-format
msgid "%s: option requires an argument -- '%c'\n"
msgstr "%s Die Option »%c« erfordert ein Argument\n"
-#: getopt.c:930 getopt.c:946
+#: getopt.c:989 getopt.c:1005
#, c-format
msgid "%s: option '-W %s' is ambiguous\n"
msgstr "%s: Die Option »-W %s« ist mehrdeutig\n"
-#: getopt.c:970 getopt.c:988
+#: getopt.c:1029 getopt.c:1047
#, c-format
msgid "%s: option '-W %s' doesn't allow an argument\n"
msgstr "%s: Die Option »-W %s« hat keine Argumente\n"
-#: getopt.c:1009 getopt.c:1027
+#: getopt.c:1068 getopt.c:1086
#, c-format
msgid "%s: option '-W %s' requires an argument\n"
msgstr "%s: Die Option »-W %s« erfordert ein Argument\n"
-#: io.c:280
+#: io.c:392
#, c-format
msgid "command line argument `%s' is a directory: skipped"
-msgstr ""
-"das Kommandozeilen-Argument »%s« ist ein Verzeichnis: wird übersprungen"
+msgstr "das Kommandozeilen-Argument »%s« ist ein Verzeichnis: wird übersprungen"
-#: io.c:283 io.c:385
+#: io.c:395 io.c:513
#, c-format
msgid "cannot open file `%s' for reading (%s)"
msgstr "Die Datei »%s« kann nicht zum Lesen geöffnet werden (%s)"
-#: io.c:501
+#: io.c:640
#, c-format
msgid "close of fd %d (`%s') failed (%s)"
msgstr "Das Schließen des Dateideskriptors %d (»%s«) ist gescheitert (%s)"
-#: io.c:578
+#: io.c:716
msgid "redirection not allowed in sandbox mode"
msgstr "Umlenkungen sind im Sandbox-Modus nicht erlaubt"
-#: io.c:612
+#: io.c:750
#, c-format
msgid "expression in `%s' redirection only has numeric value"
-msgstr ""
-"Der Ausdruck in einer Umlenkung mittels »%s« hat nur einen numerischen Wert"
+msgstr "Der Ausdruck in einer Umlenkung mittels »%s« hat nur einen numerischen Wert"
-#: io.c:618
+#: io.c:756
#, c-format
msgid "expression for `%s' redirection has null string value"
msgstr "Der Ausdruck für eine Umlenkung mittels »%s« ist ein leerer String"
-#: io.c:624
+#: io.c:761
#, c-format
msgid "filename `%s' for `%s' redirection may be result of logical expression"
-msgstr ""
-"Der Dateiname »%s« für eine Umlenkung mittels »%s« kann das Ergebnis eines "
-"logischen Ausdrucks sein"
+msgstr "Der Dateiname »%s« für eine Umlenkung mittels »%s« kann das Ergebnis eines logischen Ausdrucks sein"
-#: io.c:667
+#: io.c:809
#, c-format
msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
msgstr "Unnötige Kombination von »>« und »>>« für Datei »%.*s«"
-#: io.c:720
+#: io.c:863
#, c-format
msgid "can't open pipe `%s' for output (%s)"
msgstr "Die Pipe »%s« kann nicht für die Ausgabe geöffnet werden (%s)"
-#: io.c:730
+#: io.c:873
#, c-format
msgid "can't open pipe `%s' for input (%s)"
msgstr "Die Pipe »%s« kann nicht für die Eingabe geöffnet werden (%s)"
-#: io.c:753
+#: io.c:904
#, c-format
msgid "can't open two way pipe `%s' for input/output (%s)"
-msgstr ""
-"Die bidirektionale Pipe »%s« kann nicht für die Ein-/Ausgabe geöffnet werden "
-"(%s)"
+msgstr "Die bidirektionale Pipe »%s« kann nicht für die Ein-/Ausgabe geöffnet werden (%s)"
-#: io.c:835
+#: io.c:986
#, c-format
msgid "can't redirect from `%s' (%s)"
msgstr "Von »%s« kann nicht umgelenkt werden (%s)"
-#: io.c:838
+#: io.c:989
#, c-format
msgid "can't redirect to `%s' (%s)"
msgstr "Zu »%s« kann nicht umgelenkt werden (%s)"
-#: io.c:889
-msgid ""
-"reached system limit for open files: starting to multiplex file descriptors"
-msgstr ""
-"Die Systemgrenze offener Dateien ist erreicht, daher werden nun "
-"Dateideskriptoren mehrfach verwendet"
+#: io.c:1040
+msgid "reached system limit for open files: starting to multiplex file descriptors"
+msgstr "Die Systemgrenze offener Dateien ist erreicht, daher werden nun Dateideskriptoren mehrfach verwendet"
-#: io.c:905
+#: io.c:1056
#, c-format
msgid "close of `%s' failed (%s)."
msgstr "Das Schließen von »%s« ist gescheitert (%s)."
-#: io.c:913
+#: io.c:1064
msgid "too many pipes or input files open"
msgstr "Zu viele Pipes oder Eingabedateien offen"
-#: io.c:935
+#: io.c:1086
msgid "close: second argument must be `to' or `from'"
msgstr "close: Das zweite Argument muss »to« oder »from« sein"
-#: io.c:952
+#: io.c:1103
#, c-format
msgid "close: `%.*s' is not an open file, pipe or co-process"
msgstr "close: »%.*s« ist weder offene Datei, noch Pipe oder Ko-Prozess"
-#: io.c:957
+#: io.c:1108
msgid "close of redirection that was never opened"
msgstr "»close« für eine Umlenkung, die nie geöffnet wurde"
-#: io.c:1054
+#: io.c:1205
#, c-format
msgid "close: redirection `%s' not opened with `|&', second argument ignored"
-msgstr ""
-"close: Umlenkung »%s« wurde nicht mit »[&« geöffnet, das zweite Argument "
-"wird ignoriert"
+msgstr "close: Umlenkung »%s« wurde nicht mit »[&« geöffnet, das zweite Argument wird ignoriert"
-#: io.c:1070
+#: io.c:1222
#, c-format
msgid "failure status (%d) on pipe close of `%s' (%s)"
msgstr "Fehlerstatus (%d) beim Schließen der Pipe »%s« (%s)"
-#: io.c:1073
+#: io.c:1225
#, c-format
msgid "failure status (%d) on file close of `%s' (%s)"
msgstr "Fehlerstatus (%d) beim Schließen der Datei »%s« (%s)"
-#: io.c:1093
+#: io.c:1245
#, c-format
msgid "no explicit close of socket `%s' provided"
msgstr "Das explizite Schließen des Sockets »%s« fehlt"
-#: io.c:1096
+#: io.c:1248
#, c-format
msgid "no explicit close of co-process `%s' provided"
msgstr "Das explizite Schließen des Ko-Prozesses »%s« fehlt"
-#: io.c:1099
+#: io.c:1251
#, c-format
msgid "no explicit close of pipe `%s' provided"
msgstr "Das explizite Schließen der Pipe »%s« fehlt"
-#: io.c:1102
+#: io.c:1254
#, c-format
msgid "no explicit close of file `%s' provided"
msgstr "Das explizite Schließen der Datei »%s« fehlt"
-#: io.c:1130 io.c:1185 main.c:793 main.c:830
+#: io.c:1284 io.c:1342 main.c:864 main.c:906
#, c-format
msgid "error writing standard output (%s)"
msgstr "Fehler beim Schreiben auf die Standardausgabe (%s)"
-#: io.c:1134 io.c:1190
+#: io.c:1289 io.c:1348 main.c:866
#, c-format
msgid "error writing standard error (%s)"
msgstr "Fehler beim Schreiben auf die Standardfehlerausgabe (%s)"
-#: io.c:1142
+#: io.c:1297
#, c-format
msgid "pipe flush of `%s' failed (%s)."
msgstr "Das Leeren der Pipe »%s« ist gescheitert (%s)"
-#: io.c:1145
+#: io.c:1300
#, c-format
msgid "co-process flush of pipe to `%s' failed (%s)."
msgstr "Ko-Prozess: Das Leeren der Pipe zu »%s« ist gescheitert (%s)"
-#: io.c:1148
+#: io.c:1303
#, c-format
msgid "file flush of `%s' failed (%s)."
msgstr "Das Leeren der Datei »%s« ist gescheitert (%s)"
-#: io.c:1263
+#: io.c:1420
#, c-format
msgid "local port %s invalid in `/inet'"
msgstr "Der lokale Port »%s« ist ungültig in »/inet«"
-#: io.c:1280
+#: io.c:1438
#, c-format
msgid "remote host and port information (%s, %s) invalid"
msgstr "Die Angaben zu entferntem Host und Port (%s, %s) sind ungültig"
-#: io.c:1432
+#: io.c:1590
#, c-format
msgid "no (known) protocol supplied in special filename `%s'"
msgstr "Es wurde kein (bekanntes) Protokoll im Dateinamen »%s« angegeben"
-#: io.c:1446
+#: io.c:1604
#, c-format
msgid "special file name `%s' is incomplete"
msgstr "Der Dateiname »%s« ist unvollständig"
-#: io.c:1463
+#: io.c:1621
msgid "must supply a remote hostname to `/inet'"
msgstr "Sie müssen in /inet einen Rechnernamen angeben"
-#: io.c:1481
+#: io.c:1639
msgid "must supply a remote port to `/inet'"
msgstr "Sie müssen in »/inet« einen Port angeben"
-#: io.c:1527
+#: io.c:1685
msgid "TCP/IP communications are not supported"
msgstr "TCP/IP-Verbindungen werden nicht unterstützt"
-#: io.c:1694
+#: io.c:1867
#, c-format
msgid "could not open `%s', mode `%s'"
msgstr "»%s« konnte nicht geöffnet werden, Modus »%s«"
-#: io.c:1748
+#: io.c:1917
#, c-format
msgid "close of master pty failed (%s)"
-msgstr ""
-"Das Schließen der übergeordneten Terminal-Gerätedatei ist gescheitert (%s)"
+msgstr "Das Schließen der übergeordneten Terminal-Gerätedatei ist gescheitert (%s)"
-#: io.c:1750 io.c:1918 io.c:2075
+#: io.c:1919 io.c:2105 io.c:2305
#, c-format
msgid "close of stdout in child failed (%s)"
msgstr "Das Schließen der Standardausgabe im Kindprozess ist gescheitert (%s)"
-#: io.c:1753
+#: io.c:1922
#, c-format
msgid "moving slave pty to stdout in child failed (dup: %s)"
-msgstr ""
-"Das Verschieben der untergeordneten Terminal-Gerätedatei zur Standardausgabe "
-"im Kindprozess ist gescheitert (dup: %s)"
+msgstr "Das Verschieben der untergeordneten Terminal-Gerätedatei zur Standardausgabe im Kindprozess ist gescheitert (dup: %s)"
-#: io.c:1755 io.c:1923
+#: io.c:1924 io.c:2110
#, c-format
msgid "close of stdin in child failed (%s)"
msgstr "Schließen von stdin im Kindprozess gescheitert (%s)"
-#: io.c:1758
+#: io.c:1927
#, c-format
msgid "moving slave pty to stdin in child failed (dup: %s)"
-msgstr ""
-"Das Verschieben der untergeordneten Terminal-Gerätedatei zur Standardeingabe "
-"im Kindprozess ist gescheitert (dup: %s)"
+msgstr "Das Verschieben der untergeordneten Terminal-Gerätedatei zur Standardeingabe im Kindprozess ist gescheitert (dup: %s)"
-#: io.c:1760 io.c:1781
+#: io.c:1929 io.c:1951
#, c-format
msgid "close of slave pty failed (%s)"
-msgstr ""
-"Das Schließen der untergeordneten Terminal-Gerätedatei ist gescheitert (%s)"
+msgstr "Das Schließen der untergeordneten Terminal-Gerätedatei ist gescheitert (%s)"
-#: io.c:1859 io.c:1921 io.c:2053 io.c:2078
+#: io.c:2040 io.c:2108 io.c:2276 io.c:2308
#, c-format
msgid "moving pipe to stdout in child failed (dup: %s)"
-msgstr ""
-"Das Verschieben der Pipe zur Standardausgabe im Kindprozess ist gescheitert "
-"(dup: %s)"
+msgstr "Das Verschieben der Pipe zur Standardausgabe im Kindprozess ist gescheitert (dup: %s)"
-#: io.c:1866 io.c:1926
+#: io.c:2047 io.c:2113
#, c-format
msgid "moving pipe to stdin in child failed (dup: %s)"
-msgstr ""
-"Das Verschieben der Pipe zur Standardeingabe im Kindprozess ist gescheitert "
-"(dup: %s)"
+msgstr "Das Verschieben der Pipe zur Standardeingabe im Kindprozess ist gescheitert (dup: %s)"
-#: io.c:1886 io.c:2068
+#: io.c:2073 io.c:2298
msgid "restoring stdout in parent process failed\n"
-msgstr ""
-"Das Wiederherstellen der Standardausgabe im Elternprozess ist gescheitert\n"
+msgstr "Das Wiederherstellen der Standardausgabe im Elternprozess ist gescheitert\n"
-#: io.c:1894
+#: io.c:2081
msgid "restoring stdin in parent process failed\n"
-msgstr ""
-"Das Wiederherstellen der Standardeingabe im Elternprozess ist gescheitert\n"
+msgstr "Das Wiederherstellen der Standardeingabe im Elternprozess ist gescheitert\n"
-#: io.c:1929 io.c:2080 io.c:2094
+#: io.c:2116 io.c:2310 io.c:2324
#, c-format
msgid "close of pipe failed (%s)"
msgstr "Das Schließen der Pipe ist gescheitert (%s)"
-#: io.c:1974
+#: io.c:2174
msgid "`|&' not supported"
msgstr "»|&« wird nicht unterstützt"
-#: io.c:2040
+#: io.c:2261
#, c-format
msgid "cannot open pipe `%s' (%s)"
msgstr "Pipe »%s« kann nicht geöffnet werden (%s)"
-#: io.c:2088
+#: io.c:2318
#, c-format
msgid "cannot create child process for `%s' (fork: %s)"
msgstr "Kindprozess für »%s« kann nicht erzeugt werden (fork: %s)"
-#: io.c:2521
+#: io.c:2790
+msgid "register_input_parser: received NULL pointer"
+msgstr "register_input_parser: NULL-Zeiger erhalten"
+
+#: io.c:2818
+#, c-format
+msgid "input parser `%s' conflicts with previously installed input parser `%s'"
+msgstr "Eingabeparser »%s« steht im Konflikt mit dem vorher installierten Eingabeparser »%s«"
+
+#: io.c:2825
+#, c-format
+msgid "input parser `%s' failed to open `%s'"
+msgstr "Eingabeparser »%s« konnte »%s« nicht öffnen"
+
+#: io.c:2845
+msgid "register_output_wrapper: received NULL pointer"
+msgstr "register_output_wrapper: NULL-Zeiger erhalten"
+
+#: io.c:2873
+#, c-format
+msgid "output wrapper `%s' conflicts with previously installed output wrapper `%s'"
+msgstr "Ausgabeverpackung »%s« steht im Konflikt mit Ausgabeverpackung »%s«"
+
+#: io.c:2880
+#, c-format
+msgid "output wrapper `%s' failed to open `%s'"
+msgstr "Ausgabeverpackung »%s« konnte »%s« nicht öffnen"
+
+#: io.c:2901
+msgid "register_output_processor: received NULL pointer"
+msgstr "register_output_processor: NULL-Zeiger erhalten"
+
+#: io.c:2930
+#, c-format
+msgid "two-way processor `%s' conflicts with previously installed two-way processor `%s'"
+msgstr "Zweiwegeprozessor »%s« steht im Konflikt mit Zweiwegeprozessor »%s«"
+
+#: io.c:2939
+#, c-format
+msgid "two way processor `%s' failed to open `%s'"
+msgstr "Zweiwegeprozessor »%s« konnte »%s« nicht öffnen"
+
+#: io.c:3064
#, c-format
msgid "data file `%s' is empty"
msgstr "Die Datei »%s« ist leer"
-#: io.c:2562 io.c:2570
+#: io.c:3106 io.c:3114
msgid "could not allocate more input memory"
msgstr "Es konnte kein weiterer Speicher für die Eingabe beschafft werden"
-#: io.c:3128
+#: io.c:3682
msgid "multicharacter value of `RS' is a gawk extension"
msgstr "Multicharacter-Wert von »RS« ist eine gawk-Erweiterung"
-#: io.c:3233
+#: io.c:3771
msgid "IPv6 communication is not supported"
msgstr "IPv6-Verbindungen werden nicht unterstützt"
-#: main.c:364
-msgid "`-m[fr]' option irrelevant in gawk"
-msgstr "Die Option »-m[fr]« ist in gawk bedeutungslos"
-
-#: main.c:366
-msgid "-m option usage: `-m[fr] nnn'"
-msgstr "Anwendung der Option -m: »-m[fr] nnn«"
-
-#: main.c:389
+#: main.c:405
msgid "empty argument to `-e/--source' ignored"
msgstr "Das leere Argument für »--source« wird ignoriert"
-#: main.c:460
+#: main.c:495
#, c-format
msgid "%s: option `-W %s' unrecognized, ignored\n"
msgstr "%s: Die Option »-W %s« ist unbekannt und wird ignoriert\n"
-#: main.c:513
+#: main.c:541
#, c-format
msgid "%s: option requires an argument -- %c\n"
msgstr "%s: Die Option %c erfordert ein Argument\n"
-#: main.c:534
+#: main.c:562
msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
-msgstr ""
-"Die Umgebungsvariable »POSIXLY_CORRECT« ist gesetzt: »--posix« wird "
-"eingeschaltet"
+msgstr "Die Umgebungsvariable »POSIXLY_CORRECT« ist gesetzt: »--posix« wird eingeschaltet"
-#: main.c:540
+#: main.c:568
msgid "`--posix' overrides `--traditional'"
msgstr "»--posix« hat Vorrang vor »--traditional«"
-#: main.c:551
+#: main.c:579
msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
msgstr "»--posix« /»--traditional« hat Vorrang vor »--non-decimal-data«"
-#: main.c:555
+#: main.c:583
#, 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:560
-msgid "`--posix' overrides `--binary'"
-msgstr "»--posix« hat Vorrang vor »--binary«"
+#: main.c:588
+msgid "`--posix' overrides `--characters-as-bytes'"
+msgstr "»--posix« hat Vorrang vor »--characters-as-bytes«"
-#: main.c:611
+#: main.c:647
#, c-format
msgid "can't set binary mode on stdin (%s)"
-msgstr ""
-"Das Setzen des Binärermodus für die Standardeingabe ist nicht möglich (%s)"
+msgstr "Das Setzen des Binärermodus für die Standardeingabe ist nicht möglich (%s)"
-#: main.c:614
+#: main.c:650
#, c-format
msgid "can't set binary mode on stdout (%s)"
-msgstr ""
-"Das Setzen des Binärermodus für die Standardausgabe ist nicht möglich (%s)"
+msgstr "Das Setzen des Binärermodus für die Standardausgabe ist nicht möglich (%s)"
-#: main.c:616
+#: main.c:652
#, c-format
msgid "can't set binary mode on stderr (%s)"
-msgstr ""
-"Das Setzen des Binärermodus für die Standardfehlerausgabe ist nicht möglich "
-"(%s)"
+msgstr "Das Setzen des Binärermodus für die Standardfehlerausgabe ist nicht möglich (%s)"
-#: main.c:655
+#: main.c:710
msgid "no program text at all!"
msgstr "Es wurde überhaupt kein Programmtext angegeben!"
-#: main.c:733
+#: main.c:799
#, c-format
msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
msgstr "Aufruf: %s [POSIX- oder GNU-Optionen] -f PROGRAMM [--] Datei ...\n"
-#: main.c:735
+#: main.c:801
#, c-format
msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
msgstr "Aufruf: %s [POSIX- oder GNU-Optionen] -- %cPROGRAMM%c Datei ...\n"
-#: main.c:740
+#: main.c:806
msgid "POSIX options:\t\tGNU long options: (standard)\n"
msgstr "POSIX-Optionen\t\tlange GNU-Optionen: (standard)\n"
-#: main.c:741
+#: main.c:807
msgid "\t-f progfile\t\t--file=progfile\n"
msgstr "\t-f PROGRAMM\t\t--file=PROGRAMM\n"
-#: main.c:742
+#: main.c:808
msgid "\t-F fs\t\t\t--field-separator=fs\n"
msgstr "\t-F Feldtrenner\t\t\t--field-separator=Feldtrenner\n"
-#: main.c:743
+#: main.c:809
msgid "\t-v var=val\t\t--assign=var=val\n"
msgstr "\t-v var=Wert\t\t--assign=var=Wert\n"
-#: main.c:744
+#: main.c:810
msgid "Short options:\t\tGNU long options: (extensions)\n"
msgstr "POSIX-Optionen\t\tGNU-Optionen (lang): (Erweiterungen)\n"
-#: main.c:745
+#: main.c:811
msgid "\t-b\t\t\t--characters-as-bytes\n"
msgstr "\t-b\t\t\t--characters-as-bytes\n"
-#: main.c:746
+#: main.c:812
msgid "\t-c\t\t\t--traditional\n"
msgstr "\t-c\t\t\t--traditional\n"
-#: main.c:747
+#: main.c:813
msgid "\t-C\t\t\t--copyright\n"
msgstr "\t-C\t\t\t--copyright\n"
-#: main.c:748
+#: main.c:814
msgid "\t-d[file]\t\t--dump-variables[=file]\n"
msgstr "\t-d [Datei]\t\t--dump-variables[=Datei]\n"
-#: main.c:749
+#: main.c:815
+msgid "\t-D[file]\t\t--debug[=file]\n"
+msgstr "\t-D[Datei]\t\t--debug[=Datei]\n"
+
+#: main.c:816
msgid "\t-e 'program-text'\t--source='program-text'\n"
msgstr "\t-e 'Programmtext'\t--source=Programmtext\n"
-#: main.c:750
+#: main.c:817
msgid "\t-E file\t\t\t--exec=file\n"
msgstr "\t-E Datei\t\t\t--exec=Datei\n"
-#: main.c:751
+#: main.c:818
msgid "\t-g\t\t\t--gen-pot\n"
msgstr "\t-g\t\t\t--gen-pot\n"
-#: main.c:752
+#: main.c:819
msgid "\t-h\t\t\t--help\n"
msgstr "\t-h\t\t\t--help\n"
-#: main.c:753
+#: main.c:820
+msgid "\t-i includefile\t\t--include=includefile\n"
+msgstr "\t-i einzubindende_datei\t\t--include=einzubindende_datei\n"
+
+#: main.c:821
+msgid "\t-l library\t\t--load=library\n"
+msgstr "\t-l Bibliothek\t\t--load=Bibliothek\n"
+
+#: main.c:822
msgid "\t-L [fatal]\t\t--lint[=fatal]\n"
msgstr "\t-L [fatal]\t\t--lint[=fatal]\n"
-#: main.c:754
+#: main.c:823
msgid "\t-n\t\t\t--non-decimal-data\n"
msgstr "\t-n\t\t\t--non-decimal-data\n"
-#: main.c:755
+#: main.c:824
+msgid "\t-M\t\t\t--bignum\n"
+msgstr "\t-M\t\t\t--bignum\n"
+
+#: main.c:825
msgid "\t-N\t\t\t--use-lc-numeric\n"
msgstr "\t-N\t\t\t--use-lc-numeric\n"
-#: main.c:756
+#: main.c:826
+msgid "\t-o[file]\t\t--pretty-print[=file]\n"
+msgstr "\t-o[Datei]\t\t--pretty-print[=Datei]\n"
+
+#: main.c:827
msgid "\t-O\t\t\t--optimize\n"
msgstr "\t-O\t\t\t--optimize\n"
-#: main.c:757
+#: main.c:828
msgid "\t-p[file]\t\t--profile[=file]\n"
msgstr "\t-p [Datei]\t\t--profile[=Datei]\n"
-#: main.c:758
+#: main.c:829
msgid "\t-P\t\t\t--posix\n"
msgstr "\t-P\t\t\t--posix\n"
-#: main.c:759
+#: main.c:830
msgid "\t-r\t\t\t--re-interval\n"
msgstr "\t-r\t\t\t--re-interval\n"
-#: main.c:761
-msgid "\t-R file\t\t\t--command=file\n"
-msgstr "\t-R Datei\t\t\t--command=Datei\n"
-
-#: main.c:762
+#: main.c:831
msgid "\t-S\t\t\t--sandbox\n"
msgstr "\t-S\t\t\t--sandbox\n"
-#: main.c:763
+#: main.c:832
msgid "\t-t\t\t\t--lint-old\n"
msgstr "\t-t\t\t\t--lint-old\n"
-#: main.c:764
+#: main.c:833
msgid "\t-V\t\t\t--version\n"
msgstr "\t-V\t\t\t--version\n"
-#: main.c:766
+#: main.c:835
msgid "\t-W nostalgia\t\t--nostalgia\n"
msgstr "\t-W nostalgia\t\t--nostalgia\n"
-#: main.c:769
+#: main.c:838
msgid "\t-Y\t\t--parsedebug\n"
msgstr "\t-Y\t\t--parsedebug\n"
@@ -1861,7 +3010,7 @@ msgstr "\t-Y\t\t--parsedebug\n"
#. for this application. Please add _another line_ with the
#. address for translation bugs.
#. no-wrap
-#: main.c:778
+#: main.c:847
msgid ""
"\n"
"To report bugs, see node `Bugs' in `gawk.info', which is\n"
@@ -1873,11 +3022,11 @@ msgstr ""
"in »gawk.info«, den Sie als Kapitel »Reporting Problems and Bugs«\n"
"in der gedruckten Version finden.\n"
"\n"
-"Fehler in der Ãœbersetzuung senden Sie bitte als E-Mail an\n"
-"an translation-team-de@lists.sourceforge.net\n"
+"Fehler in der Ãœbersetzung senden Sie bitte als E-Mail an\n"
+"translation-team-de@lists.sourceforge.net\n"
"\n"
-#: main.c:782
+#: main.c:851
msgid ""
"gawk is a pattern scanning and processing language.\n"
"By default it reads standard input and writes standard output.\n"
@@ -1888,7 +3037,7 @@ msgstr ""
"auf der Standardausgabe aus.\n"
"\n"
-#: main.c:786
+#: main.c:855
msgid ""
"Examples:\n"
"\tgawk '{ sum += $1 }; END { print sum }' file\n"
@@ -1898,7 +3047,7 @@ msgstr ""
"\tgawk '{ sum += $1 }; END { print sum }' file\n"
"\tgawk -F: '{ print $1 }' /etc/passwd\n"
-#: main.c:806
+#: main.c:880
#, c-format
msgid ""
"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
@@ -1918,7 +3067,7 @@ msgstr ""
"spätere Version.\n"
"\n"
-#: main.c:814
+#: main.c:888
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"
@@ -1931,7 +3080,7 @@ msgstr ""
"leistung einer HANDELBARKEIT oder der EIGNUNG FÃœR EINEN BESTIMMTEN ZWECK.\n"
"Sehen Sie bitte die GNU General Public License für weitere Details.\n"
-#: main.c:820
+#: main.c:894
msgid ""
"You should have received a copy of the GNU General Public License\n"
"along with this program. If not, see http://www.gnu.org/licenses/.\n"
@@ -1940,16 +3089,16 @@ msgstr ""
"diesem Programm erhalten haben. Wenn nicht, lesen Sie bitte\n"
"http://www.gnu.org/licenses/.\n"
-#: main.c:855
+#: main.c:931
msgid "-Ft does not set FS to tab in POSIX awk"
msgstr "-Ft setzt FS im POSIX-awk nicht auf Tab"
-#: main.c:1089
+#: main.c:1208
#, c-format
msgid "unknown value for field spec: %d\n"
msgstr "unbekannter Wert für eine Feldangabe: %d\n"
-#: main.c:1170
+#: main.c:1306
#, c-format
msgid ""
"%s: `%s' argument to `-v' not in `var=value' form\n"
@@ -1958,130 +3107,159 @@ msgstr ""
"%s: Argument »%s« von »-v« ist nicht in der Form »Variable=Wert«\n"
"\n"
-#: main.c:1196
+#: main.c:1332
#, c-format
msgid "`%s' is not a legal variable name"
msgstr "»%s« ist kein gültiger Variablenname"
-#: main.c:1199
+#: main.c:1335
#, c-format
msgid "`%s' is not a variable name, looking for file `%s=%s'"
msgstr "»%s« ist kein Variablenname, es wird nach der Datei »%s=%s« gesucht"
-#: main.c:1203
+#: main.c:1339
#, c-format
msgid "cannot use gawk builtin `%s' as variable name"
-msgstr ""
-"die eingebaute Funktion »%s« kann nicht als Variablenname verwendet werden"
+msgstr "die eingebaute Funktion »%s« kann nicht als Variablenname verwendet werden"
# c-format
-#: main.c:1208
+#: main.c:1344
#, c-format
msgid "cannot use function `%s' as variable name"
msgstr "Funktion »%s« kann nicht als Name einer Variablen verwendet werden"
-#: main.c:1261
+#: main.c:1397
msgid "floating point exception"
msgstr "Fließkomma-Ausnahme"
-#: main.c:1268
+#: main.c:1404
msgid "fatal error: internal error"
msgstr "Fataler Fehler: interner Fehler"
-#: main.c:1283
+#: main.c:1419
msgid "fatal error: internal error: segfault"
msgstr "Fataler Fehler: interner Fehler: Speicherbegrenzungsfehler"
-#: main.c:1295
+#: main.c:1431
msgid "fatal error: internal error: stack overflow"
msgstr "Fataler Fehler: interner Fehler: Stapelüberlauf"
-#: main.c:1345
+#: main.c:1490
#, c-format
msgid "no pre-opened fd %d"
msgstr "Kein bereits geöffneter Dateideskriptor %d"
-#: main.c:1352
+#: main.c:1497
#, c-format
msgid "could not pre-open /dev/null for fd %d"
msgstr "/dev/null konnte nicht für Dateideskriptor %d geöffnet werden"
-#: main.c:1375 main.c:1384
+#: mpfr.c:550
#, c-format
-msgid "could not find groups: %s"
-msgstr "Die Gruppen konnten nicht gefunden werden: %s"
+msgid "PREC value `%.*s' is invalid"
+msgstr "PREC Wert »%.*s« ist ungültig"
-#: msg.c:63
+#: mpfr.c:608
+#, c-format
+msgid "RNDMODE value `%.*s' is invalid"
+msgstr "BINMODE Wert »%.*s« ist ungültig"
+
+#: mpfr.c:698
+#, c-format
+msgid "%s: received non-numeric argument"
+msgstr "%s: das Argument ist keine Zahl"
+
+#: mpfr.c:800
+msgid "compl(%Rg): negative value will give strange results"
+msgstr "compl(%Rg): ein negativer Wert wird zu merkwürdigen Ergebnissen führen"
+
+#: mpfr.c:804
+msgid "comp(%Rg): fractional value will be truncated"
+msgstr "compl(%Rg): Dezimalteil wird abgeschnitten"
+
+#: mpfr.c:816
+#, c-format
+msgid "cmpl(%Zd): negative values will give strange results"
+msgstr "cmpl(%Zd): Negative Werte führen zu merkwürdigen Ergebnissen"
+
+#: mpfr.c:835
+#, c-format
+msgid "%s: received non-numeric argument #%d"
+msgstr "%s: das Argument Nr. %d ist keine Zahl"
+
+#: mpfr.c:845
+msgid "%s: argument #%d has invalid value %Rg, using 0"
+msgstr "%s: Argument Nr. %d hat den ungültigen Wert %Rg, es wird stattdessen 0 verwendet"
+
+#: mpfr.c:857
+msgid "%s: argument #%d negative value %Rg will give strange results"
+msgstr "%s: der negative Wert %2$Rg in Argument Nr. %1$d wird zu merkwürdigen Ergebnissen führen"
+
+#: mpfr.c:863
+msgid "%s: argument #%d fractional value %Rg will be truncated"
+msgstr "%s: der Nachkommateil %2$Rg in Argument Nr. %1$d wird abgeschnitten"
+
+#: mpfr.c:878
+#, c-format
+msgid "%s: argument #%d negative value %Zd will give strange results"
+msgstr "%1$s: der negative Wert %3$Zd in Argument Nr. %2$d wird zu merkwürdigen Ergebnissen führen"
+
+#: msg.c:68
#, c-format
msgid "cmd. line:"
msgstr "Kommandozeile:"
-#: msg.c:107
-msgid "error: "
-msgstr "Fehler: "
-
-#: node.c:406
+#: node.c:421
msgid "backslash at end of string"
msgstr "Backslash am Ende der Zeichenkette"
-#: node.c:517
+#: node.c:500
#, c-format
msgid "old awk does not support the `\\%c' escape sequence"
-msgstr "Das alte awk unterstützt die Fluchsequenz »\\%c« nicht"
+msgstr "Das alte awk unterstützt die Escapesequenz »\\%c« nicht"
-#: node.c:568
+#: node.c:551
msgid "POSIX does not allow `\\x' escapes"
msgstr "POSIX erlaubt keine »\\x«-Escapes"
-#: node.c:574
+#: node.c:557
msgid "no hex digits in `\\x' escape sequence"
msgstr "In der »\\x«-Fluchtsequenz sind keine hexadezimalen Zahlen"
-#: node.c:596
+#: node.c:579
#, c-format
-msgid ""
-"hex escape \\x%.*s of %d characters probably not interpreted the way you "
-"expect"
-msgstr ""
-"Die Hex-Sequenz \\x%.*s aus %d Zeichen wird wahrscheinlich nicht wie "
-"gewünscht interpretiert"
+msgid "hex escape \\x%.*s of %d characters probably not interpreted the way you expect"
+msgstr "Die Hex-Sequenz \\x%.*s aus %d Zeichen wird wahrscheinlich nicht wie gewünscht interpretiert"
-#: node.c:611
+#: node.c:594
#, c-format
msgid "escape sequence `\\%c' treated as plain `%c'"
msgstr "Fluchtsequenz »\\%c« wird wie ein normales »%c« behandelt"
-#: node.c:750
-msgid ""
-"Invalid multibyte data detected. There may be a mismatch between your data "
-"and your locale."
-msgstr ""
-"Es wurden unbekannte Multibyte-Daten gefunden. Ihre Daten entsprechen "
-"neventuell nicht der gesetzten Locale"
+#: node.c:739
+msgid "Invalid multibyte data detected. There may be a mismatch between your data and your locale."
+msgstr "Es wurden unbekannte Multibyte-Daten gefunden. Ihre Daten entsprechen neventuell nicht der gesetzten Locale"
-#: posix/gawkmisc.c:176
+#: posix/gawkmisc.c:177
#, c-format
msgid "%s %s `%s': could not get fd flags: (fcntl F_GETFD: %s)"
-msgstr ""
-"%s %s »%s«: Die Kennungen des Dateideskriptors konnten nicht abgefragt "
-"werden: (fcntl F_GETFD: %s)"
+msgstr "%s %s »%s«: Die Kennungen des Dateideskriptors konnten nicht abgefragt werden: (fcntl F_GETFD: %s)"
-#: posix/gawkmisc.c:188
+#: posix/gawkmisc.c:189
#, c-format
msgid "%s %s `%s': could not set close-on-exec: (fcntl F_SETFD: %s)"
-msgstr ""
-"%s %s »%s«: close-on-exec konnte nicht gesetzt werden: (fcntl F_SETFD: %s)"
+msgstr "%s %s »%s«: close-on-exec konnte nicht gesetzt werden: (fcntl F_SETFD: %s)"
-#: profile.c:83
+#: profile.c:71
#, c-format
msgid "could not open `%s' for writing: %s"
msgstr "»%s« konnte nicht zum Schreiben geöffnet werden: %s"
-#: profile.c:85
+#: profile.c:73
msgid "sending profile to standard error"
msgstr "Das Profil wird auf der Standardfehlerausgabe ausgegeben"
-#: profile.c:203
+#: profile.c:193
#, c-format
msgid ""
"\t# %s block(s)\n"
@@ -2090,7 +3268,7 @@ msgstr ""
"\t# %s Blöcke\n"
"\n"
-#: profile.c:208
+#: profile.c:198
#, c-format
msgid ""
"\t# Rule(s)\n"
@@ -2099,17 +3277,30 @@ msgstr ""
"\t# Regeln(s)\n"
"\n"
-#: profile.c:279
+#: profile.c:272
#, c-format
msgid "internal error: %s with null vname"
msgstr "Interner Fehler: %s mit null vname"
-#: profile.c:952
+#: profile.c:537
+msgid "internal error: builtin with null fname"
+msgstr "Interner Fehler: eingebaute Fuktion mit leerem fname"
+
+#: profile.c:949
+#, c-format
+msgid ""
+"\t# Loaded extensions (-l and/or @load)\n"
+"\n"
+msgstr ""
+"\t# Erweiterungen geladen (-l und/oder @load)\n"
+"\n"
+
+#: profile.c:972
#, c-format
msgid "\t# gawk profile, created %s\n"
msgstr "\t# gawk-Profil, erzeugt %s\n"
-#: profile.c:1331
+#: profile.c:1475
#, c-format
msgid ""
"\n"
@@ -2118,95 +3309,80 @@ msgstr ""
"\n"
"\t# Funktionen in alphabetischer Reihenfolge\n"
-#: profile.c:1370
+#: profile.c:1513
#, c-format
msgid "redir2str: unknown redirection type %d"
msgstr "redir2str: unbekannter Umlenkungstyp %d"
-#: re.c:572
-#, fuzzy, c-format
-msgid "range of the form `[%c-%c]' is locale dependent"
-msgstr ""
-"Ein Bereich in der Form »[%c-%c]« ist abhängig von der gesetzten Locale"
-
-#: re.c:599
+#: re.c:607
#, c-format
msgid "regexp component `%.*s' should probably be `[%.*s]'"
-msgstr ""
-"Regulärer-Ausdruck-Komponente »%.*s« sollte wahrscheinlich »[%.*s]« sein"
+msgstr "Regulärer-Ausdruck-Komponente »%.*s« sollte wahrscheinlich »[%.*s]« sein"
-#: regcomp.c:132
+#: regcomp.c:131
msgid "Success"
msgstr "Erfolg"
-#: regcomp.c:135
+#: regcomp.c:134
msgid "No match"
msgstr "Kein Treffer"
-#: regcomp.c:138
+#: regcomp.c:137
msgid "Invalid regular expression"
msgstr "Ungültiger Regulärer Ausdruck"
-#: regcomp.c:141
+#: regcomp.c:140
msgid "Invalid collation character"
msgstr "Ungültiges Zeichen"
-#: regcomp.c:144
+#: regcomp.c:143
msgid "Invalid character class name"
msgstr "Ungültiger Name für eine Zeichenklasse"
-#: regcomp.c:147
+#: regcomp.c:146
msgid "Trailing backslash"
msgstr "Angehängter Backslash"
-#: regcomp.c:150
+#: regcomp.c:149
msgid "Invalid back reference"
msgstr "Ungültige Rück-Referenz"
-#: regcomp.c:153
+#: regcomp.c:152
msgid "Unmatched [ or [^"
msgstr "[ oder [^ werden nicht geschlossen"
-#: regcomp.c:156
+#: regcomp.c:155
msgid "Unmatched ( or \\("
msgstr "( oder \\( werden nicht geschlossen"
-#: regcomp.c:159
+#: regcomp.c:158
msgid "Unmatched \\{"
msgstr "\\{ wird nicht geschlossen"
-#: regcomp.c:162
-msgid "Invalid content of \\{\\}"
-msgstr "Ungültiger Inhalt von \\{\\}"
-
-#: regcomp.c:165
+#: regcomp.c:164
msgid "Invalid range end"
msgstr "Ungültiges Bereichsende"
-#: regcomp.c:168
+#: regcomp.c:167
msgid "Memory exhausted"
msgstr "Kein freier Speicher mehr vorhanden"
-#: regcomp.c:171
+#: regcomp.c:170
msgid "Invalid preceding regular expression"
msgstr "Vorangehender regulärer Ausdruck ist ungültig"
-#: regcomp.c:174
+#: regcomp.c:173
msgid "Premature end of regular expression"
msgstr "Vorzeitiges Ende des regulären Ausdrucks"
-#: regcomp.c:177
-msgid "Regular expression too big"
-msgstr "Regulärer Ausdruck ist zu groß"
-
-#: regcomp.c:180
+#: regcomp.c:179
msgid "Unmatched ) or \\)"
msgstr ") oder \\) werden nicht geöffnet"
-#: regcomp.c:701
+#: regcomp.c:704
msgid "No previous regular expression"
msgstr "Kein vorangehender regulärer Ausdruck"
-#~ msgid "assignment is not allowed to result of builtin function"
-#~ msgstr ""
-#~ "Zuweisungen an das Ergebnis einer eingebauten Funktion sind nicht erlaubt"
+#: symbol.c:741
+msgid "can not pop main context"
+msgstr "der Hauptkontext kann nicht entfernt werden"
diff --git a/po/es.gmo b/po/es.gmo
index e395377a..0bfebbae 100644
--- a/po/es.gmo
+++ b/po/es.gmo
Binary files differ
diff --git a/po/es.po b/po/es.po
index 676e7a8b..d16109a9 100644
--- a/po/es.po
+++ b/po/es.po
@@ -1,14 +1,14 @@
-# Mensajes en español para gawk-4.0.0.
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+# Mensajes en español para gawk-4.0.0h.
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
# This file is distributed under the same license as the gawk package.
-# Cristian Othón Martínez Vera <cfuga@cfuga.mx>, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011.
+# Cristian Othón Martínez Vera <cfuga@cfuga.mx>, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012.
#
msgid ""
msgstr ""
-"Project-Id-Version: gawk 4.0.0\n"
+"Project-Id-Version: gawk 4.0.0h\n"
"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
-"POT-Creation-Date: 2011-10-24 05:57+0200\n"
-"PO-Revision-Date: 2011-08-14 12:02-0500\n"
+"POT-Creation-Date: 2014-04-08 19:23+0300\n"
+"PO-Revision-Date: 2012-01-30 07:42-0600\n"
"Last-Translator: Cristian Othón Martínez Vera <cfuga@cfuga.mx>\n"
"Language-Team: Spanish <es@li.org>\n"
"Language: es\n"
@@ -16,519 +16,502 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: array.c:140
+#: array.c:256
#, c-format
msgid "from %s"
msgstr "desde %s"
-#: array.c:248
+#: array.c:357
msgid "attempt to use a scalar value as array"
msgstr "se intentó usar un valor escalar como una matriz"
-#: array.c:251
-#, c-format
-msgid "attempt to use function `%s' as an array"
-msgstr "se intentó usar la función `%s' como una matriz"
-
-#: array.c:254
+#: array.c:359
#, 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:257
+#: array.c:362
#, c-format
msgid "attempt to use scalar `%s' as an array"
msgstr "se intentó usar el escalar `%s' como una matriz"
-#: array.c:302 array.c:707 builtin.c:84 builtin.c:1384 builtin.c:1426
-#: builtin.c:1439 builtin.c:1856 builtin.c:1868 eval.c:1135 eval.c:1139
-#: eval.c:1495 eval.c:1812
+#: array.c:409 array.c:576 builtin.c:85 builtin.c:1615 builtin.c:1661
+#: builtin.c:1674 builtin.c:2102 builtin.c:2116 eval.c:1122 eval.c:1126
+#: eval.c:1531
#, c-format
msgid "attempt to use array `%s' in a scalar context"
msgstr "se intentó usar la matriz `%s' en un contexto escalar"
-#: array.c:513
-#, c-format
-msgid "reference to uninitialized element `%s[\"%.*s\"]'"
-msgstr "referencia al elemento sin inicializar `%s[\"%.*s\"]'"
-
-#: array.c:519
-#, c-format
-msgid "subscript of array `%s' is null string"
-msgstr "el subíndice de la matriz `%s' es la cadena nula"
-
-#: array.c:723
+#: array.c:583
#, c-format
msgid "delete: index `%s' not in array `%s'"
msgstr "delete: el índice `%s' no está en la matriz `%s'"
-#: array.c:734 eval.c:1865
+#: array.c:597
#, c-format
msgid "attempt to use scalar `%s[\"%.*s\"]' as an array"
msgstr "se intentó usar el dato escalar `%s[\"%.*s\"]' como una matriz"
-#: array.c:910
-#, c-format
-msgid "%s: empty (null)\n"
-msgstr "%s: vacío (nulo)\n"
-
-#: array.c:915
-#, c-format
-msgid "%s: empty (zero)\n"
-msgstr "%s: vacío (cero)\n"
-
-#: array.c:919
-#, c-format
-msgid "%s: table_size = %d, array_size = %d\n"
-msgstr "%s: tamaño_tabla = %d, tamaño_matriz = %d\n"
-
-#: array.c:954
-#, c-format
-msgid "%s: is parameter\n"
-msgstr "%s: es un parámetro\n"
-
-#: array.c:958
-#, c-format
-msgid "%s: array_ref to %s\n"
-msgstr "%s: array_ref a %s\n"
-
-#: array.c:963
-msgid "adump: argument not an array"
+#: array.c:776
+#, fuzzy
+msgid "adump: first argument not an array"
msgstr "adump: el argumento no es una matriz"
-#: array.c:1086
+#: array.c:815
msgid "asort: second argument not an array"
msgstr "asort: el segundo argumento no es una matriz"
-#: array.c:1087
+#: array.c:816
msgid "asorti: second argument not an array"
msgstr "asorti: el segundo argumento no es una matriz"
-#: array.c:1094
+#: array.c:823
msgid "asort: first argument not an array"
msgstr "asort: el primer argumento no es una matriz"
-#: array.c:1095
+#: array.c:824
msgid "asorti: first argument not an array"
msgstr "asorti: el primer argumento no es una matriz"
-#: array.c:1102
+#: array.c:831
msgid "asort: cannot use a subarray of first arg for second arg"
msgstr ""
"asort: no se puede usar una submatriz del primer argumento para el segundo "
"argumento"
-#: array.c:1103
+#: array.c:832
msgid "asorti: cannot use a subarray of first arg for second arg"
msgstr ""
"asorti: no se puede usar una submatriz del primer argumento para el segundo "
"argumento"
-#: array.c:1108
+#: array.c:837
msgid "asort: cannot use a subarray of second arg for first arg"
msgstr ""
"asort: no se puede usar una submatriz del segundo argumento para el primer "
"argumento"
-#: array.c:1109
+#: array.c:838
msgid "asorti: cannot use a subarray of second arg for first arg"
msgstr ""
"asorti: no se puede usar una submatriz del segundo argumento para el primer "
"argumento"
-#: array.c:1659
+#: array.c:1314
#, c-format
msgid "`%s' is invalid as a function name"
msgstr "`%s' es inválido como un nombre de función"
-#: array.c:1663
+#: array.c:1318
#, c-format
msgid "sort comparison function `%s' is not defined"
msgstr "la función de comparación de ordenamiento `%s' no está definida"
-#: awkgram.y:249
+#: awkgram.y:233
#, c-format
msgid "%s blocks must have an action part"
msgstr "los bloques %s deben tener una parte de acción"
-#: awkgram.y:252
+#: awkgram.y:236
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:323 awkgram.y:334
+#: awkgram.y:325 awkgram.y:336
msgid "old awk does not support multiple `BEGIN' or `END' rules"
msgstr "el awk antiguo no admite múltiples reglas `BEGIN' o `END'"
-#: awkgram.y:371
+#: awkgram.y:373
#, 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:432
+#: awkgram.y:419
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:436
+#: awkgram.y:423
#, 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:528
+#: awkgram.y:515
#, c-format
msgid "duplicate case values in switch body: %s"
msgstr "valores case duplicados en el cuerpo de un switch: %s"
-#: awkgram.y:549
+#: awkgram.y:536
msgid "duplicate `default' detected in switch body"
msgstr "se detectó un `default' duplicado en el cuerpo de un switch"
-#: awkgram.y:809
+#: awkgram.y:796 awkgram.y:3723
msgid "`break' is not allowed outside a loop or switch"
msgstr "no se permite `break' fuera de un bucle o switch"
-#: awkgram.y:818
+#: awkgram.y:805 awkgram.y:3715
msgid "`continue' is not allowed outside a loop"
msgstr "no se permite `continue' fuera de un bucle"
-#: awkgram.y:828
+#: awkgram.y:815
#, c-format
msgid "`next' used in %s action"
msgstr "se usó `next' en la acción %s"
-#: awkgram.y:836
-msgid "`nextfile' is a gawk extension"
-msgstr "`nextfile' es una extensión de gawk"
-
-#: awkgram.y:841
+#: awkgram.y:824
#, c-format
msgid "`nextfile' used in %s action"
msgstr "se usó `nextfile' en la acción %s"
-#: awkgram.y:865
+#: awkgram.y:848
msgid "`return' used outside function context"
msgstr "se usó `return' fuera del contexto de la función"
-#: awkgram.y:925
+#: awkgram.y:922
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:995 awkgram.y:999 awkgram.y:1023
-msgid "`delete array' is a gawk extension"
-msgstr "`delete array' es una extensión de gawk"
+#: awkgram.y:988 awkgram.y:1037
+msgid "`delete' is not allowed with SYMTAB"
+msgstr ""
+
+#: awkgram.y:990 awkgram.y:1039
+msgid "`delete' is not allowed with FUNCTAB"
+msgstr ""
-#: awkgram.y:1019
+#: awkgram.y:1024 awkgram.y:1028
msgid "`delete(array)' is a non-portable tawk extension"
msgstr "`delete(array)' es una extensión de tawk que no es transportable"
-#: awkgram.y:1135
+#: awkgram.y:1149
msgid "multistage two-way pipelines don't work"
msgstr "las líneas de trabajo de dos vías multiestado no funcionan"
-#: awkgram.y:1238
+#: awkgram.y:1264
msgid "regular expression on right of assignment"
msgstr "expresión regular del lado derecho de una asignación"
-#: awkgram.y:1249
+#: awkgram.y:1275
msgid "regular expression on left of `~' or `!~' operator"
msgstr "expresión regular a la izquierda del operador `~' o `!~'"
-#: awkgram.y:1265 awkgram.y:1419
+#: awkgram.y:1291 awkgram.y:1442
msgid "old awk does not support the keyword `in' except after `for'"
msgstr ""
"el awk antiguo no admite la palabra clave `in' excepto después de `for'"
-#: awkgram.y:1275
+#: awkgram.y:1301
msgid "regular expression on right of comparison"
msgstr "expresión regular a la derecha de una comparación"
-#: awkgram.y:1394
+#: awkgram.y:1417
#, c-format
msgid "`getline var' invalid inside `%s' rule"
msgstr "`getline var' inválido dentro de la regla `%s'"
-#: awkgram.y:1397 eval.c:2504
+#: awkgram.y:1420
#, c-format
msgid "`getline' invalid inside `%s' rule"
msgstr "`getline' inválido dentro de la regla `%s'"
-#: awkgram.y:1402
+#: awkgram.y:1425
msgid "non-redirected `getline' undefined inside END action"
msgstr "`getline' no redirigido indefinido dentro de la acción de END"
-#: awkgram.y:1421
+#: awkgram.y:1444
msgid "old awk does not support multidimensional arrays"
msgstr "el awk antiguo no admite matrices multidimensionales"
-#: awkgram.y:1517
+#: awkgram.y:1541
msgid "call of `length' without parentheses is not portable"
msgstr "la llamada de `length' sin paréntesis no es transportable"
-#: awkgram.y:1580
+#: awkgram.y:1607
msgid "indirect function calls are a gawk extension"
msgstr "las llamadas indirectas a función son una extensión de gawk"
-#: awkgram.y:1593
+#: awkgram.y:1620
#, c-format
msgid "can not use special variable `%s' for indirect function call"
msgstr ""
"no se puede usar la variable especial `%s' como llamada indirecta a función"
-#: awkgram.y:1671
+#: awkgram.y:1698
msgid "invalid subscript expression"
msgstr "expresión de subíndice inválida"
-#: awkgram.y:1711
-msgid "use of non-array as array"
-msgstr "uso de una matriz que no es matriz"
-
-#: awkgram.y:1975 awkgram.y:1995 msg.c:98
+#: awkgram.y:2048 awkgram.y:2068 gawkapi.c:206 gawkapi.c:224 msg.c:126
msgid "warning: "
msgstr "aviso: "
-#: awkgram.y:1993 msg.c:130
+#: awkgram.y:2066 gawkapi.c:192 gawkapi.c:221 msg.c:158
msgid "fatal: "
msgstr "fatal: "
-#: awkgram.y:2043
+#: awkgram.y:2116
msgid "unexpected newline or end of string"
msgstr "nueva línea o fin de la cadena inesperados"
-#: awkgram.y:2300 awkgram.y:2358 awkgram.y:2542
+#: awkgram.y:2383 awkgram.y:2459 awkgram.y:2682 debug.c:523 debug.c:539
+#: debug.c:2812 debug.c:5055
#, 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:2301 awkgram.y:2359 builtin.c:122
+#: awkgram.y:2384 awkgram.y:2509
+#, fuzzy, c-format
+msgid "can't open shared library `%s' for reading (%s)"
+msgstr "no se puede abrir el fichero fuente `%s' para lectura (%s)"
+
+#: awkgram.y:2386 awkgram.y:2460 awkgram.y:2510 builtin.c:135 debug.c:5206
msgid "reason unknown"
msgstr "razón desconocida"
-#: awkgram.y:2317
+#: awkgram.y:2395 awkgram.y:2419
+#, c-format
+msgid "can't include `%s' and use it as a program file"
+msgstr ""
+
+#: awkgram.y:2408
#, c-format
msgid "already included source file `%s'"
msgstr "ya se incluyó el fichero fuente `%s'"
-#: awkgram.y:2343
+#: awkgram.y:2409
+#, fuzzy, c-format
+msgid "already loaded shared library `%s'"
+msgstr "ya se incluyó el fichero fuente `%s'"
+
+#: awkgram.y:2444
msgid "@include is a gawk extension"
msgstr "@include es una extensión de gawk"
-#: awkgram.y:2349
+#: awkgram.y:2450
msgid "empty filename after @include"
msgstr "nombre de fichero vacío después de @include"
#: awkgram.y:2494
+#, fuzzy
+msgid "@load is a gawk extension"
+msgstr "@include es una extensión de gawk"
+
+#: awkgram.y:2500
+#, fuzzy
+msgid "empty filename after @load"
+msgstr "nombre de fichero vacío después de @include"
+
+#: awkgram.y:2634
msgid "empty program text on command line"
msgstr "texto de programa vacío en la linea de órdenes"
-#: awkgram.y:2609
+#: awkgram.y:2749
#, c-format
msgid "can't read sourcefile `%s' (%s)"
msgstr "no se puede leer el fichero fuente `%s' (%s)"
-#: awkgram.y:2620
+#: awkgram.y:2760
#, c-format
msgid "source file `%s' is empty"
msgstr "el fichero fuente `%s' está vacío"
-#: awkgram.y:2805
+#: awkgram.y:2937
msgid "source file does not end in newline"
msgstr "el fichero fuente no termina con línea nueva"
-#: awkgram.y:2882
+#: awkgram.y:3042
msgid "unterminated regexp ends with `\\' at end of file"
msgstr "expresión regular sin terminar termina con `\\` al final del fichero"
-#: awkgram.y:2906
+#: awkgram.y:3066
#, 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:2910
+#: awkgram.y:3070
#, 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:2917
+#: awkgram.y:3077
msgid "unterminated regexp"
msgstr "expresión regular sin terminar"
-#: awkgram.y:2921
+#: awkgram.y:3081
msgid "unterminated regexp at end of file"
msgstr "expresión regular sin terminar al final del fichero"
-#: awkgram.y:2980
+#: awkgram.y:3140
msgid "use of `\\ #...' line continuation is not portable"
msgstr "el uso de la continuación de línea `\\ #...' no es transportable"
-#: awkgram.y:2996
+#: awkgram.y:3156
msgid "backslash not last character on line"
msgstr "la barra invertida no es el último caracter en la línea"
-#: awkgram.y:3057
+#: awkgram.y:3217
msgid "POSIX does not allow operator `**='"
msgstr "POSIX no permite el operador `**='"
-#: awkgram.y:3059
+#: awkgram.y:3219
msgid "old awk does not support operator `**='"
msgstr "el awk antiguo no admite el operador `**='"
-#: awkgram.y:3068
+#: awkgram.y:3228
msgid "POSIX does not allow operator `**'"
msgstr "POSIX no permite el operador `**'"
-#: awkgram.y:3070
+#: awkgram.y:3230
msgid "old awk does not support operator `**'"
msgstr "el awk antiguo no admite el operador `**='"
-#: awkgram.y:3105
+#: awkgram.y:3265
msgid "operator `^=' is not supported in old awk"
msgstr "el operador `^=' no se admite en el awk antiguo"
-#: awkgram.y:3113
+#: awkgram.y:3273
msgid "operator `^' is not supported in old awk"
msgstr "el operador `^' no se admite en el awk antiguo"
-#: awkgram.y:3206 awkgram.y:3222
+#: awkgram.y:3366 awkgram.y:3382 command.y:1178
msgid "unterminated string"
msgstr "cadena sin terminar"
-#: awkgram.y:3418
+#: awkgram.y:3603
#, c-format
msgid "invalid char '%c' in expression"
msgstr "caracter '%c' inválido en la expresión"
-#: awkgram.y:3465
+#: awkgram.y:3650
#, c-format
msgid "`%s' is a gawk extension"
msgstr "`%s' es una extensión de gawk"
-#: awkgram.y:3470
-#, c-format
-msgid "`%s' is a Bell Labs extension"
-msgstr "`%s' es una extensión de Bell Labs"
-
-#: awkgram.y:3475
+#: awkgram.y:3655
#, c-format
msgid "POSIX does not allow `%s'"
msgstr "POSIX no permite `%s'"
-#: awkgram.y:3483
+#: awkgram.y:3663
#, c-format
msgid "`%s' is not supported in old awk"
msgstr "`%s' no se admite en el awk antiguo"
-#: awkgram.y:3550
+#: awkgram.y:3753
msgid "`goto' considered harmful!\n"
msgstr "¡`goto' se considera dañino!\n"
-#: awkgram.y:3601
+#: awkgram.y:3787
#, 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:3636
+#: awkgram.y:3822
#, 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:3641
+#: awkgram.y:3827
#, c-format
msgid "%s third parameter is not a changeable object"
msgstr "el tercer argumento de %s no es un objecto modificable"
-#: awkgram.y:3714 awkgram.y:3717
+#: awkgram.y:3910 awkgram.y:3913
msgid "match: third argument is a gawk extension"
msgstr "match: el tercer argumento es una extensión de gawk"
-#: awkgram.y:3771 awkgram.y:3774
+#: awkgram.y:3967 awkgram.y:3970
msgid "close: second argument is a gawk extension"
msgstr "close: el segundo argumento es una extensión de gawk"
-#: awkgram.y:3786
+#: awkgram.y:3982
msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
msgstr ""
"el uso de dcgettext(_\"...\") es incorrecto: quite el subrayado inicial"
-#: awkgram.y:3801
+#: awkgram.y:3997
msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
msgstr ""
"el uso de dcngettext(_\"...\") es incorrecto: quite el subrayado inicial"
-#: awkgram.y:3893
-#, 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:4016
+#, fuzzy
+msgid "index: regexp constant as second argument is not allowed"
+msgstr "index: el segundo argumento recibido no es una cadena"
-#: awkgram.y:3935
+#: awkgram.y:4069
#, c-format
msgid "function `%s': parameter `%s' shadows global variable"
msgstr "función `%s': parámetro `%s' oscurece la variable global"
-#: awkgram.y:4093
+#: awkgram.y:4126 debug.c:4041 debug.c:4084 debug.c:5204
#, c-format
msgid "could not open `%s' for writing (%s)"
msgstr "no se puede abrir `%s' para escritura (%s)"
-#: awkgram.y:4094
+#: awkgram.y:4127
msgid "sending variable list to standard error"
msgstr "se envía la lista de variables a la salida estándar de error"
-#: awkgram.y:4100
+#: awkgram.y:4135
#, c-format
msgid "%s: close failed (%s)"
msgstr "%s: falló close (%s)"
-#: awkgram.y:4152
+#: awkgram.y:4160
msgid "shadow_funcs() called twice!"
msgstr "¡se llamó shadow_funcs() dos veces!"
-#: awkgram.y:4158
+#: awkgram.y:4168
msgid "there were shadowed variables."
msgstr "hay variables opacadas."
-#: awkgram.y:4188
+#: awkgram.y:4239
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "el nombre de función `%s' se definió previamente"
+
+#: awkgram.y:4285
#, 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:4192
+#: awkgram.y:4288
#, c-format
msgid "function `%s': can't use special variable `%s' as a function parameter"
msgstr ""
"función `%s': no se puede usar la variable especial `%s' como un parámetro "
"de función"
-#: awkgram.y:4208
+#: awkgram.y:4296
#, c-format
-msgid "function name `%s' previously defined"
-msgstr "el nombre de función `%s' se definió previamente"
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "función `%s': parámetro #%d, `%s', duplica el parámetro #%d"
-#: awkgram.y:4376 awkgram.y:4382
+#: awkgram.y:4383 awkgram.y:4389
#, c-format
msgid "function `%s' called but never defined"
msgstr "se llamó a la función `%s' pero nunca se definió"
-#: awkgram.y:4385
+#: awkgram.y:4393
#, c-format
msgid "function `%s' defined but never called directly"
msgstr "se definió la función `%s' pero nunca se llamó directamente"
-#: awkgram.y:4417
+#: awkgram.y:4425
#, 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:4526
+#: awkgram.y:4484
#, c-format
msgid ""
"function `%s' called with space between name and `(',\n"
@@ -537,238 +520,253 @@ msgstr ""
"se llamó la función `%s' con espacio entre el nombre y el `(',\n"
"o se usó como una variable o una matriz"
-#: awkgram.y:4773 eval.c:2056
+#: awkgram.y:4720
msgid "division by zero attempted"
msgstr "se intentó una división por cero"
-#: awkgram.y:4782 eval.c:2072
+#: awkgram.y:4729
#, c-format
msgid "division by zero attempted in `%%'"
msgstr "se intentó una división por cero en `%%'"
-#: builtin.c:120
+#: awkgram.y:5049
+msgid ""
+"cannot assign a value to the result of a field post-increment expression"
+msgstr ""
+
+#: awkgram.y:5052
+#, fuzzy, c-format
+msgid "invalid target of assignment (opcode %s)"
+msgstr "%d es inválido como número de argumentos para %s"
+
+#: builtin.c:133
#, c-format
msgid "%s to \"%s\" failed (%s)"
msgstr "falló %s a \"%s\" (%s)"
-#: builtin.c:121
+#: builtin.c:134
msgid "standard output"
msgstr "salida estándar"
-#: builtin.c:135
+#: builtin.c:148
msgid "exp: received non-numeric argument"
msgstr "exp: se recibió un argumento que no es númerico"
-#: builtin.c:141
+#: builtin.c:154
#, c-format
msgid "exp: argument %g is out of range"
msgstr "exp: el argumento %g está fuera de rango"
-#: builtin.c:200
+#: builtin.c:229
#, 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:203
+#: builtin.c:232
#, 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:215
+#: builtin.c:244
#, 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:333
+#: builtin.c:362
msgid "index: received non-string first argument"
msgstr "index: el primer argumento recibido no es una cadena"
-#: builtin.c:335
+#: builtin.c:364
msgid "index: received non-string second argument"
msgstr "index: el segundo argumento recibido no es una cadena"
-#: builtin.c:457
+#: builtin.c:488 mpfr.c:757
msgid "int: received non-numeric argument"
msgstr "int: se recibió un argumento que no es númerico"
-#: builtin.c:493
+#: builtin.c:525
msgid "length: received array argument"
msgstr "length: se recibió un argumento de matriz"
-#: builtin.c:496
+#: builtin.c:528
msgid "`length(array)' is a gawk extension"
msgstr "`length(array)' es una extensión de gawk"
-#: builtin.c:504
+#: builtin.c:544
msgid "length: received non-string argument"
msgstr "length: se recibió un argumento que no es una cadena"
-#: builtin.c:535
+#: builtin.c:575
msgid "log: received non-numeric argument"
msgstr "log: se recibió un argumento que no es númerico"
-#: builtin.c:538
+#: builtin.c:578
#, c-format
msgid "log: received negative argument %g"
msgstr "log: se recibió el argumento negativo %g"
-#: builtin.c:694 builtin.c:699
+#: builtin.c:776 builtin.c:781
msgid "fatal: must use `count$' on all formats or none"
msgstr "fatal: se debe utilizar `count$' en todos los formatos o en ninguno"
-#: builtin.c:761
+#: builtin.c:851
#, c-format
msgid "field width is ignored for `%%' specifier"
msgstr "se descarta la anchura del campo para el especificador `%%'"
-#: builtin.c:763
+#: builtin.c:853
#, c-format
msgid "precision is ignored for `%%' specifier"
msgstr "se descarta la precisión para el especificador `%%'"
-#: builtin.c:765
+#: builtin.c:855
#, c-format
msgid "field width and precision are ignored for `%%' specifier"
msgstr ""
"se descartan la anchura del campo y la precisión para el especificador `%%'"
-#: builtin.c:816
+#: builtin.c:906
msgid "fatal: `$' is not permitted in awk formats"
msgstr "fatal: no se permite `$' en los formatos de awk"
-#: builtin.c:825
+#: builtin.c:915
msgid "fatal: arg count with `$' must be > 0"
msgstr "fatal: la cuenta de argumentos con `$' debe ser > 0"
-#: builtin.c:829
+#: builtin.c:919
#, c-format
msgid "fatal: arg count %ld greater than total number of supplied arguments"
msgstr ""
"fatal: la cuenta de argumentos %ld es mayor que el número total de "
"argumentos proporcionados"
-#: builtin.c:833
+#: builtin.c:923
msgid "fatal: `$' not permitted after period in format"
msgstr "fatal: no se permite `$' después de un punto en el formato"
-#: builtin.c:849
+#: builtin.c:939
msgid "fatal: no `$' supplied for positional field width or precision"
msgstr ""
"fatal: no se proporciona `$' para la anchura o la precisión del campo "
"posicional"
-#: builtin.c:920
+#: builtin.c:1009
msgid "`l' is meaningless in awk formats; ignored"
msgstr "`l' no tiene significado en los formatos de awk; se descarta"
-#: builtin.c:924
+#: builtin.c:1013
msgid "fatal: `l' is not permitted in POSIX awk formats"
msgstr "fatal: no se permite `l' en los formatos POSIX de awk"
-#: builtin.c:937
+#: builtin.c:1026
msgid "`L' is meaningless in awk formats; ignored"
msgstr "`L' no tiene significado en los formatos de awk; se descarta"
-#: builtin.c:941
+#: builtin.c:1030
msgid "fatal: `L' is not permitted in POSIX awk formats"
msgstr "fatal: no se permite `L' en los formatos POSIX de awk"
-#: builtin.c:954
+#: builtin.c:1043
msgid "`h' is meaningless in awk formats; ignored"
msgstr "`h' no tiene significado en los formatos de awk; se descarta"
-#: builtin.c:958
+#: builtin.c:1047
msgid "fatal: `h' is not permitted in POSIX awk formats"
msgstr "fatal: no se permite `h' en los formatos POSIX de awk"
-#: builtin.c:1271
+#: builtin.c:1463
#, c-format
msgid "[s]printf: value %g is out of range for `%%%c' format"
msgstr "[s]printf: el valor %g está fuera del rango para el formato `%%%c'"
-#: builtin.c:1331
+#: builtin.c:1561
#, c-format
msgid "ignoring unknown format specifier character `%c': no argument converted"
msgstr ""
"se descarta el carácter especificador de formato `%c' desconocido: no se "
"convirtió ningún argumento"
-#: builtin.c:1336
+#: builtin.c:1566
msgid "fatal: not enough arguments to satisfy format string"
msgstr ""
"fatal: no hay suficientes argumentos para satisfacer a la cadena de formato"
-#: builtin.c:1338
+#: builtin.c:1568
msgid "^ ran out for this one"
msgstr "se acabó ^ para éste"
-#: builtin.c:1345
+#: builtin.c:1575
msgid "[s]printf: format specifier does not have control letter"
msgstr "[s]printf: el especificador de formato no tiene letras de control"
-#: builtin.c:1348
+#: builtin.c:1578
msgid "too many arguments supplied for format string"
msgstr "se proporcionaron demasiados argumentos para la cadena de formato"
-#: builtin.c:1422 builtin.c:1433
+#: builtin.c:1634
+#, fuzzy
+msgid "sprintf: no arguments"
+msgstr "printf: sin argumentos"
+
+#: builtin.c:1657 builtin.c:1668
msgid "printf: no arguments"
msgstr "printf: sin argumentos"
-#: builtin.c:1474
+#: builtin.c:1711
msgid "sqrt: received non-numeric argument"
msgstr "sqrt: se recibió un argumento que no es un númerico"
-#: builtin.c:1478
+#: builtin.c:1715
#, c-format
msgid "sqrt: called with negative argument %g"
msgstr "sqrt: se llamó con el argumento negativo %g"
-#: builtin.c:1502
+#: builtin.c:1746
#, c-format
msgid "substr: length %g is not >= 1"
msgstr "substr: la longitud %g no es >= 1"
-#: builtin.c:1504
+#: builtin.c:1748
#, c-format
msgid "substr: length %g is not >= 0"
msgstr "substr: la longitud %g no es >= 0"
-#: builtin.c:1511
+#: builtin.c:1755
#, c-format
msgid "substr: non-integer length %g will be truncated"
msgstr "substr: se truncará la longitud no entera %g"
-#: builtin.c:1516
+#: builtin.c:1760
#, 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:1528
+#: builtin.c:1772
#, c-format
msgid "substr: start index %g is invalid, using 1"
msgstr "substr: el índice de inicio %g es inválido, se usa 1"
-#: builtin.c:1533
+#: builtin.c:1777
#, c-format
msgid "substr: non-integer start index %g will be truncated"
msgstr "substr: se truncará el índice de inicio no entero %g"
-#: builtin.c:1558
+#: builtin.c:1802
msgid "substr: source string is zero length"
msgstr "substr: la cadena de origen es de longitud cero"
-#: builtin.c:1574
+#: builtin.c:1818
#, 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:1582
+#: builtin.c:1826
#, c-format
msgid ""
"substr: length %g at start index %g exceeds length of first argument (%lu)"
@@ -776,233 +774,1096 @@ msgstr ""
"substr: la cadena %g en el índice de inicio %g excede la longitud del primer "
"argumento (%lu)"
-#: builtin.c:1655
+#: builtin.c:1900
msgid "strftime: format value in PROCINFO[\"strftime\"] has numeric type"
msgstr ""
"strftime: el valor de formato en PROCINFO[\"strftime\"] tiene tipo numérico"
-#: builtin.c:1678
+#: builtin.c:1923
msgid "strftime: received non-numeric second argument"
msgstr "strftime: el segundo argumento recibido no es númerico"
-#: builtin.c:1681
+#: builtin.c:1927
msgid "strftime: second argument less than 0 or too big for time_t"
msgstr ""
+"strftime: el segundo argumento es menor que 0 o demasiado grande para time_t"
-#: builtin.c:1687
+#: builtin.c:1934
msgid "strftime: received non-string first argument"
msgstr "strftime: el primer argumento recibido no es una cadena"
-#: builtin.c:1693
+#: builtin.c:1941
msgid "strftime: received empty format string"
msgstr "strftime: se recibió una cadena de formato vacía"
-#: builtin.c:1759
+#: builtin.c:2007
msgid "mktime: received non-string argument"
msgstr "mktime: se recibió un argumento que no es una cadena"
-#: builtin.c:1776
+#: builtin.c:2024
msgid "mktime: at least one of the values is out of the default range"
msgstr ""
"mktime: por lo menos uno de los valores está fuera del rango por defecto"
-#: builtin.c:1811
+#: builtin.c:2059
msgid "'system' function not allowed in sandbox mode"
msgstr "no se permite la función 'system' en modo sandbox"
-#: builtin.c:1816
+#: builtin.c:2064
msgid "system: received non-string argument"
msgstr "system: se recibió un argumento que no es una cadena"
-#: builtin.c:1871 eval.c:1159 eval.c:1790 eval.c:1803
-#, c-format
-msgid "reference to uninitialized variable `%s'"
-msgstr "referencia a la variable sin inicializar `%s'"
-
-#: builtin.c:1938
+#: builtin.c:2184
#, c-format
msgid "reference to uninitialized field `$%d'"
msgstr "referencia al campo sin inicializar `$%d'"
-#: builtin.c:2025
+#: builtin.c:2271
msgid "tolower: received non-string argument"
msgstr "tolower: se recibió un argumento que no es una cadena"
-#: builtin.c:2059
+#: builtin.c:2305
msgid "toupper: received non-string argument"
msgstr "toupper: se recibió un argumento que no es una cadena"
-#: builtin.c:2095
+#: builtin.c:2341 mpfr.c:672
msgid "atan2: received non-numeric first argument"
msgstr "atan2: el primer argumento recibido no es númerico"
-#: builtin.c:2097
+#: builtin.c:2343 mpfr.c:674
msgid "atan2: received non-numeric second argument"
msgstr "atan2: el segundo argumento recibido no es númerico"
-#: builtin.c:2116
+#: builtin.c:2362
msgid "sin: received non-numeric argument"
msgstr "sin: se recibió un argumento que no es númerico"
-#: builtin.c:2132
+#: builtin.c:2378
msgid "cos: received non-numeric argument"
msgstr "cos: se recibió un argumento que no es númerico"
-#: builtin.c:2185
+#: builtin.c:2431 mpfr.c:1156
msgid "srand: received non-numeric argument"
msgstr "srand: se recibió un argumento que no es númerico"
-#: builtin.c:2216
+#: builtin.c:2462
msgid "match: third argument is not an array"
msgstr "match: el tercer argumento no es una matriz"
-#: builtin.c:2480
+#: builtin.c:2734
msgid "gensub: third argument of 0 treated as 1"
msgstr "gensub: el tercer argumento de 0 se trata como 1"
-#: builtin.c:2773
+#: builtin.c:3030
msgid "lshift: received non-numeric first argument"
msgstr "lshift: el primer argumento recibido no es númerico"
-#: builtin.c:2775
+#: builtin.c:3032
msgid "lshift: received non-numeric second argument"
msgstr "lshift: el segundo argumento recibido no es númerico"
-#: builtin.c:2781
-#, c-format
-msgid "lshift(%lf, %lf): negative values will give strange results"
+#: builtin.c:3038
+#, fuzzy, c-format
+msgid "lshift(%f, %f): negative values will give strange results"
msgstr "lshift(%lf, %lf): los valores negativos darán resultados extraños"
-#: builtin.c:2783
-#, c-format
-msgid "lshift(%lf, %lf): fractional values will be truncated"
+#: builtin.c:3040
+#, fuzzy, c-format
+msgid "lshift(%f, %f): fractional values will be truncated"
msgstr "lshift(%lf, %lf): los valores fraccionarios se truncarán"
-#: builtin.c:2785
-#, c-format
-msgid "lshift(%lf, %lf): too large shift value will give strange results"
+#: builtin.c:3042
+#, fuzzy, c-format
+msgid "lshift(%f, %f): too large shift value will give strange results"
msgstr ""
"lshift(%lf, %lf): un valor de desplazamiento muy grande dará resultados "
"extraños"
-#: builtin.c:2810
+#: builtin.c:3067
msgid "rshift: received non-numeric first argument"
msgstr "rshift: el primer argumento recibido no es númerico"
-#: builtin.c:2812
+#: builtin.c:3069
msgid "rshift: received non-numeric second argument"
msgstr "rshift: el segundo argumento recibido no es númerico"
-#: builtin.c:2818
-#, c-format
-msgid "rshift(%lf, %lf): negative values will give strange results"
+#: builtin.c:3075
+#, fuzzy, c-format
+msgid "rshift(%f, %f): negative values will give strange results"
msgstr "rshift(%lf, %lf): los valores negativos darán resultados extraños"
-#: builtin.c:2820
-#, c-format
-msgid "rshift(%lf, %lf): fractional values will be truncated"
+#: builtin.c:3077
+#, fuzzy, c-format
+msgid "rshift(%f, %f): fractional values will be truncated"
msgstr "rshift(%lf, %lf): los valores fraccionarios serán truncados"
-#: builtin.c:2822
-#, c-format
-msgid "rshift(%lf, %lf): too large shift value will give strange results"
+#: builtin.c:3079
+#, fuzzy, c-format
+msgid "rshift(%f, %f): too large shift value will give strange results"
msgstr ""
"rshift(%lf, %lf): un valor de desplazamiento muy grande dará resultados "
"extraños"
-#: builtin.c:2847
-msgid "and: received non-numeric first argument"
-msgstr "and: el primer argumento recibido no es númerico"
+#: builtin.c:3104 mpfr.c:968
+#, fuzzy
+msgid "and: called with less than two arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
-#: builtin.c:2849
-msgid "and: received non-numeric second argument"
-msgstr "and: el segundo argumento recibido no es númerico"
+#: builtin.c:3109
+#, fuzzy, c-format
+msgid "and: argument %d is non-numeric"
+msgstr "exp: el argumento %g está fuera de rango"
-#: builtin.c:2855
-#, c-format
-msgid "and(%lf, %lf): negative values will give strange results"
+#: builtin.c:3113
+#, fuzzy, c-format
+msgid "and: argument %d negative value %g will give strange results"
msgstr "and(%lf, %lf): los valores negativos darán resultados extraños"
-#: builtin.c:2857
+#: builtin.c:3136 mpfr.c:1000
+#, fuzzy
+msgid "or: called with less than two arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: builtin.c:3141
+#, fuzzy, c-format
+msgid "or: argument %d is non-numeric"
+msgstr "exp: el argumento %g está fuera de rango"
+
+#: builtin.c:3145
+#, fuzzy, c-format
+msgid "or: argument %d negative value %g will give strange results"
+msgstr "compl(%lf): el valor negativo dará resultados extraños"
+
+#: builtin.c:3167 mpfr.c:1031
+#, fuzzy
+msgid "xor: called with less than two arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: builtin.c:3173
+#, fuzzy, c-format
+msgid "xor: argument %d is non-numeric"
+msgstr "exp: el argumento %g está fuera de rango"
+
+#: builtin.c:3177
+#, fuzzy, c-format
+msgid "xor: argument %d negative value %g will give strange results"
+msgstr "xor(%lf, %lf): los valores negativos darán resultados extraños"
+
+#: builtin.c:3202 mpfr.c:787
+msgid "compl: received non-numeric argument"
+msgstr "compl: se recibió un argumento que no es númerico"
+
+#: builtin.c:3208
+#, fuzzy, c-format
+msgid "compl(%f): negative value will give strange results"
+msgstr "compl(%lf): el valor negativo dará resultados extraños"
+
+#: builtin.c:3210
+#, fuzzy, c-format
+msgid "compl(%f): fractional value will be truncated"
+msgstr "compl(%lf): el valor fraccionario se truncará"
+
+#: builtin.c:3379
#, c-format
-msgid "and(%lf, %lf): fractional values will be truncated"
-msgstr "and(%lf, %lf): los valores fraccionarios serán truncados"
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: `%s' no es una categoría local válida"
-#: builtin.c:2882
-msgid "or: received non-numeric first argument"
-msgstr "or: el primer argumento recibido no es númerico"
+#: command.y:225
+#, c-format
+msgid "Type (g)awk statement(s). End with the command \"end\"\n"
+msgstr ""
+
+#: command.y:289
+#, fuzzy, c-format
+msgid "invalid frame number: %d"
+msgstr "Final de rango inválido"
-#: builtin.c:2884
-msgid "or: received non-numeric second argument"
-msgstr "or: el segundo argumento recibido no es númerico"
+#: command.y:295
+#, fuzzy, c-format
+msgid "info: invalid option - \"%s\""
+msgstr "%s: opción inválida -- '%c'\n"
-#: builtin.c:2890
+#: command.y:321
#, c-format
-msgid "or(%lf, %lf): negative values will give strange results"
-msgstr "or(%lf, %lf): los valores negativos darán resultados extraños"
+msgid "source \"%s\": already sourced."
+msgstr ""
-#: builtin.c:2892
+#: command.y:326
#, c-format
-msgid "or(%lf, %lf): fractional values will be truncated"
-msgstr "or(%lf, %lf): los valores fraccionarios serán truncados"
+msgid "save \"%s\": command not permitted."
+msgstr ""
-#: builtin.c:2920
-msgid "xor: received non-numeric first argument"
-msgstr "xor: el primer argumento recibido no es númerico"
+#: command.y:339
+msgid "Can't use command `commands' for breakpoint/watchpoint commands"
+msgstr ""
-#: builtin.c:2922
-msgid "xor: received non-numeric second argument"
-msgstr "xor: el segundo argumento recibido no es númerico"
+#: command.y:341
+msgid "no breakpoint/watchpoint has been set yet"
+msgstr ""
-#: builtin.c:2928
+#: command.y:343
+msgid "invalid breakpoint/watchpoint number"
+msgstr ""
+
+#: command.y:348
#, c-format
-msgid "xor(%lf, %lf): negative values will give strange results"
-msgstr "xor(%lf, %lf): los valores negativos darán resultados extraños"
+msgid "Type commands for when %s %d is hit, one per line.\n"
+msgstr ""
-#: builtin.c:2930
+#: command.y:350
#, c-format
-msgid "xor(%lf, %lf): fractional values will be truncated"
-msgstr "xor(%lf, %lf): los valores fraccionarios se truncarán"
+msgid "End with the command \"end\"\n"
+msgstr ""
-#: builtin.c:2954 builtin.c:2960
-msgid "compl: received non-numeric argument"
-msgstr "compl: se recibió un argumento que no es númerico"
+#: command.y:357
+msgid "`end' valid only in command `commands' or `eval'"
+msgstr ""
+
+#: command.y:367
+msgid "`silent' valid only in command `commands'"
+msgstr ""
+
+#: command.y:373
+#, fuzzy, c-format
+msgid "trace: invalid option - \"%s\""
+msgstr "%s: opción inválida -- '%c'\n"
+
+#: command.y:387
+msgid "condition: invalid breakpoint/watchpoint number"
+msgstr ""
-#: builtin.c:2962
+#: command.y:449
+#, fuzzy
+msgid "argument not a string"
+msgstr "exp: el argumento %g está fuera de rango"
+
+#: command.y:459 command.y:464
#, c-format
-msgid "compl(%lf): negative value will give strange results"
-msgstr "compl(%lf): el valor negativo dará resultados extraños"
+msgid "option: invalid parameter - \"%s\""
+msgstr ""
-#: builtin.c:2964
+#: command.y:474
#, c-format
-msgid "compl(%lf): fractional value will be truncated"
-msgstr "compl(%lf): el valor fraccionario se truncará"
+msgid "no such function - \"%s\""
+msgstr ""
+
+#: command.y:531
+#, fuzzy, c-format
+msgid "enable: invalid option - \"%s\""
+msgstr "%s: opción inválida -- '%c'\n"
+
+#: command.y:597
+#, fuzzy, c-format
+msgid "invalid range specification: %d - %d"
+msgstr "Final de rango inválido"
+
+#: command.y:659
+#, fuzzy
+msgid "non-numeric value for field number"
+msgstr "valor desconocido para la especificación de campo: %d\n"
+
+#: command.y:680 command.y:687
+msgid "non-numeric value found, numeric expected"
+msgstr ""
+
+#: command.y:712 command.y:718
+msgid "non-zero integer value"
+msgstr ""
+
+#: command.y:817
+msgid ""
+"backtrace [N] - print trace of all or N innermost (outermost if N < 0) "
+"frames."
+msgstr ""
+
+#: command.y:819
+msgid ""
+"break [[filename:]N|function] - set breakpoint at the specified location."
+msgstr ""
+
+#: command.y:821
+msgid "clear [[filename:]N|function] - delete breakpoints previously set."
+msgstr ""
+
+#: command.y:823
+msgid ""
+"commands [num] - starts a list of commands to be executed at a "
+"breakpoint(watchpoint) hit."
+msgstr ""
+
+#: command.y:825
+msgid "condition num [expr] - set or clear breakpoint or watchpoint condition."
+msgstr ""
+
+#: command.y:827
+msgid "continue [COUNT] - continue program being debugged."
+msgstr ""
+
+#: command.y:829
+msgid "delete [breakpoints] [range] - delete specified breakpoints."
+msgstr ""
+
+#: command.y:831
+msgid "disable [breakpoints] [range] - disable specified breakpoints."
+msgstr ""
+
+#: command.y:833
+msgid "display [var] - print value of variable each time the program stops."
+msgstr ""
+
+#: command.y:835
+msgid "down [N] - move N frames down the stack."
+msgstr ""
+
+#: command.y:837
+msgid "dump [filename] - dump instructions to file or stdout."
+msgstr ""
+
+#: command.y:839
+msgid "enable [once|del] [breakpoints] [range] - enable specified breakpoints."
+msgstr ""
+
+#: command.y:841
+msgid "end - end a list of commands or awk statements."
+msgstr ""
+
+#: command.y:843
+msgid "eval stmt|[p1, p2, ...] - evaluate awk statement(s)."
+msgstr ""
+
+#: command.y:845
+msgid "finish - execute until selected stack frame returns."
+msgstr ""
-#: builtin.c:3133
+#: command.y:847
+msgid "frame [N] - select and print stack frame number N."
+msgstr ""
+
+#: command.y:849
+msgid "help [command] - print list of commands or explanation of command."
+msgstr ""
+
+#: command.y:851
+msgid "ignore N COUNT - set ignore-count of breakpoint number N to COUNT."
+msgstr ""
+
+#: command.y:853
+msgid ""
+"info topic - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch."
+msgstr ""
+
+#: command.y:855
+msgid "list [-|+|[filename:]lineno|function|range] - list specified line(s)."
+msgstr ""
+
+#: command.y:857
+msgid "next [COUNT] - step program, proceeding through subroutine calls."
+msgstr ""
+
+#: command.y:859
+msgid ""
+"nexti [COUNT] - step one instruction, but proceed through subroutine calls."
+msgstr ""
+
+#: command.y:861
+msgid "option [name[=value]] - set or display debugger option(s)."
+msgstr ""
+
+#: command.y:863
+msgid "print var [var] - print value of a variable or array."
+msgstr ""
+
+#: command.y:865
+msgid "printf format, [arg], ... - formatted output."
+msgstr ""
+
+#: command.y:867
+msgid "quit - exit debugger."
+msgstr ""
+
+#: command.y:869
+msgid "return [value] - make selected stack frame return to its caller."
+msgstr ""
+
+#: command.y:871
+msgid "run - start or restart executing program."
+msgstr ""
+
+#: command.y:874
+msgid "save filename - save commands from the session to file."
+msgstr ""
+
+#: command.y:877
+msgid "set var = value - assign value to a scalar variable."
+msgstr ""
+
+#: command.y:879
+msgid ""
+"silent - suspends usual message when stopped at a breakpoint/watchpoint."
+msgstr ""
+
+#: command.y:881
+msgid "source file - execute commands from file."
+msgstr ""
+
+#: command.y:883
+msgid "step [COUNT] - step program until it reaches a different source line."
+msgstr ""
+
+#: command.y:885
+msgid "stepi [COUNT] - step one instruction exactly."
+msgstr ""
+
+#: command.y:887
+msgid "tbreak [[filename:]N|function] - set a temporary breakpoint."
+msgstr ""
+
+#: command.y:889
+msgid "trace on|off - print instruction before executing."
+msgstr ""
+
+#: command.y:891
+msgid "undisplay [N] - remove variable(s) from automatic display list."
+msgstr ""
+
+#: command.y:893
+msgid ""
+"until [[filename:]N|function] - execute until program reaches a different "
+"line or line N within current frame."
+msgstr ""
+
+#: command.y:895
+msgid "unwatch [N] - remove variable(s) from watch list."
+msgstr ""
+
+#: command.y:897
+msgid "up [N] - move N frames up the stack."
+msgstr ""
+
+#: command.y:899
+msgid "watch var - set a watchpoint for a variable."
+msgstr ""
+
+#: command.y:1011 debug.c:401 msg.c:135
#, c-format
-msgid "dcgettext: `%s' is not a valid locale category"
-msgstr "dcgettext: `%s' no es una categoría local válida"
+msgid "error: "
+msgstr "error: "
+
+#: command.y:1051
+#, fuzzy, c-format
+msgid "can't read command (%s)\n"
+msgstr "no se puede redirigir desde `%s' (%s)"
+
+#: command.y:1065
+#, fuzzy, c-format
+msgid "can't read command (%s)"
+msgstr "no se puede redirigir desde `%s' (%s)"
+
+#: command.y:1116
+#, fuzzy
+msgid "invalid character in command"
+msgstr "Nombre de clase de caracter inválido"
+
+#: command.y:1152
+#, c-format
+msgid "unknown command - \"%.*s\", try help"
+msgstr ""
+
+#: command.y:1222
+#, c-format
+msgid "%s"
+msgstr ""
+
+#: command.y:1284
+#, fuzzy
+msgid "invalid character"
+msgstr "Caracter de ordenación inválido"
+
+#: command.y:1455
+#, c-format
+msgid "undefined command: %s\n"
+msgstr ""
+
+#: debug.c:252
+msgid "set or show the number of lines to keep in history file."
+msgstr ""
+
+#: debug.c:254
+msgid "set or show the list command window size."
+msgstr ""
+
+#: debug.c:256
+msgid "set or show gawk output file."
+msgstr ""
+
+#: debug.c:258
+msgid "set or show debugger prompt."
+msgstr ""
+
+#: debug.c:260
+msgid "(un)set or show saving of command history (value=on|off)."
+msgstr ""
+
+#: debug.c:262
+msgid "(un)set or show saving of options (value=on|off)."
+msgstr ""
+
+#: debug.c:264
+msgid "(un)set or show instruction tracing (value=on|off)."
+msgstr ""
+
+#: debug.c:345
+msgid "program not running."
+msgstr ""
+
+#: debug.c:448 debug.c:606
+#, fuzzy, c-format
+msgid "can't read source file `%s' (%s)"
+msgstr "no se puede leer el fichero fuente `%s' (%s)"
+
+#: debug.c:453
+#, fuzzy, c-format
+msgid "source file `%s' is empty.\n"
+msgstr "el fichero fuente `%s' está vacío"
+
+#: debug.c:480
+msgid "no current source file."
+msgstr ""
+
+#: debug.c:505
+#, fuzzy, c-format
+msgid "cannot find source file named `%s' (%s)"
+msgstr "no se puede leer el fichero fuente `%s' (%s)"
+
+#: debug.c:529
+#, c-format
+msgid "WARNING: source file `%s' modified since program compilation.\n"
+msgstr ""
+
+#: debug.c:551
+#, c-format
+msgid "line number %d out of range; `%s' has %d lines"
+msgstr ""
+
+#: debug.c:611
+#, fuzzy, c-format
+msgid "unexpected eof while reading file `%s', line %d"
+msgstr "error interno: fichero `%s', línea %d\n"
+
+#: debug.c:620
+#, c-format
+msgid "source file `%s' modified since start of program execution"
+msgstr ""
+
+#: debug.c:732
+#, fuzzy, c-format
+msgid "Current source file: %s\n"
+msgstr "ya se incluyó el fichero fuente `%s'"
+
+#: debug.c:733
+#, c-format
+msgid "Number of lines: %d\n"
+msgstr ""
+
+#: debug.c:740
+#, c-format
+msgid "Source file (lines): %s (%d)\n"
+msgstr ""
+
+#: debug.c:754
+msgid ""
+"Number Disp Enabled Location\n"
+"\n"
+msgstr ""
+
+#: debug.c:765
+#, c-format
+msgid "\tno of hits = %ld\n"
+msgstr ""
+
+#: debug.c:767
+#, c-format
+msgid "\tignore next %ld hit(s)\n"
+msgstr ""
+
+#: debug.c:769 debug.c:909
+#, c-format
+msgid "\tstop condition: %s\n"
+msgstr ""
+
+#: debug.c:771 debug.c:911
+msgid "\tcommands:\n"
+msgstr ""
+
+#: debug.c:793
+#, c-format
+msgid "Current frame: "
+msgstr ""
+
+#: debug.c:796
+#, c-format
+msgid "Called by frame: "
+msgstr ""
+
+#: debug.c:800
+#, c-format
+msgid "Caller of frame: "
+msgstr ""
+
+#: debug.c:818
+#, c-format
+msgid "None in main().\n"
+msgstr ""
+
+#: debug.c:848
+#, fuzzy
+msgid "No arguments.\n"
+msgstr "printf: sin argumentos"
+
+#: debug.c:849
+msgid "No locals.\n"
+msgstr ""
+
+#: debug.c:857
+msgid ""
+"All defined variables:\n"
+"\n"
+msgstr ""
+
+#: debug.c:867
+msgid ""
+"All defined functions:\n"
+"\n"
+msgstr ""
+
+#: debug.c:886
+msgid ""
+"Auto-display variables:\n"
+"\n"
+msgstr ""
+
+#: debug.c:889
+msgid ""
+"Watch variables:\n"
+"\n"
+msgstr ""
+
+#: debug.c:1029
+#, fuzzy, c-format
+msgid "no symbol `%s' in current context\n"
+msgstr "`exit' no se puede llamar en el contexto actual"
+
+#: debug.c:1041 debug.c:1427
+#, fuzzy, c-format
+msgid "`%s' is not an array\n"
+msgstr "`%s' no es un nombre de variable legal"
+
+#: debug.c:1055
+#, fuzzy, c-format
+msgid "$%ld = uninitialized field\n"
+msgstr "referencia al campo sin inicializar `$%d'"
+
+#: debug.c:1076
+#, fuzzy, c-format
+msgid "array `%s' is empty\n"
+msgstr "el fichero de datos `%s' está vacío"
+
+#: debug.c:1119 debug.c:1171
+#, fuzzy, c-format
+msgid "[\"%s\"] not in array `%s'\n"
+msgstr "delete: el índice `%s' no está en la matriz `%s'"
+
+#: debug.c:1175
+#, c-format
+msgid "`%s[\"%s\"]' is not an array\n"
+msgstr ""
+
+#: debug.c:1236 debug.c:4964
+#, fuzzy, c-format
+msgid "`%s' is not a scalar variable"
+msgstr "`%s' no es un nombre de variable legal"
+
+#: debug.c:1258 debug.c:4994
+#, fuzzy, c-format
+msgid "attempt to use array `%s[\"%s\"]' in a scalar context"
+msgstr "se intentó usar la matriz `%s[\"%.*s\"]' en un contexto escalar"
+
+#: debug.c:1280 debug.c:5005
+#, fuzzy, c-format
+msgid "attempt to use scalar `%s[\"%s\"]' as array"
+msgstr "se intentó usar el dato escalar `%s[\"%.*s\"]' como una matriz"
+
+#: debug.c:1423
+#, fuzzy, c-format
+msgid "`%s' is a function"
+msgstr "`%s' es inválido como un nombre de función"
+
+#: debug.c:1465
+#, c-format
+msgid "watchpoint %d is unconditional\n"
+msgstr ""
+
+#: debug.c:1499
+#, c-format
+msgid "No display item numbered %ld"
+msgstr ""
+
+#: debug.c:1502
+#, c-format
+msgid "No watch item numbered %ld"
+msgstr ""
+
+#: debug.c:1528
+#, fuzzy, c-format
+msgid "%d: [\"%s\"] not in array `%s'\n"
+msgstr "delete: el índice `%s' no está en la matriz `%s'"
+
+#: debug.c:1767
+#, fuzzy
+msgid "attempt to use scalar value as array"
+msgstr "se intentó usar un valor escalar como una matriz"
+
+#: debug.c:1856
+#, c-format
+msgid "Watchpoint %d deleted because parameter is out of scope.\n"
+msgstr ""
+
+#: debug.c:1867
+#, c-format
+msgid "Display %d deleted because parameter is out of scope.\n"
+msgstr ""
+
+#: debug.c:1900
+#, fuzzy, c-format
+msgid " in file `%s', line %d\n"
+msgstr "error interno: fichero `%s', línea %d\n"
+
+#: debug.c:1921
+#, c-format
+msgid " at `%s':%d"
+msgstr ""
+
+#: debug.c:1937 debug.c:2000
+#, c-format
+msgid "#%ld\tin "
+msgstr ""
+
+#: debug.c:1974
+#, c-format
+msgid "More stack frames follow ...\n"
+msgstr ""
+
+#: debug.c:2017
+#, fuzzy
+msgid "invalid frame number"
+msgstr "Final de rango inválido"
+
+#: debug.c:2200
+#, c-format
+msgid "Note: breakpoint %d (enabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2207
+#, c-format
+msgid "Note: breakpoint %d (enabled), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2214
+#, c-format
+msgid "Note: breakpoint %d (disabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2221
+#, c-format
+msgid "Note: breakpoint %d (disabled), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2238
+#, fuzzy, c-format
+msgid "Breakpoint %d set at file `%s', line %d\n"
+msgstr "error interno: fichero `%s', línea %d\n"
+
+#: debug.c:2340
+#, c-format
+msgid "Can't set breakpoint in file `%s'\n"
+msgstr ""
+
+#: debug.c:2369 debug.c:2492 debug.c:3350
+#, fuzzy, c-format
+msgid "line number %d in file `%s' out of range"
+msgstr "exp: el argumento %g está fuera de rango"
+
+#: debug.c:2373
+#, c-format
+msgid "Can't find rule!!!\n"
+msgstr ""
+
+#: debug.c:2375
+#, c-format
+msgid "Can't set breakpoint at `%s':%d\n"
+msgstr ""
+
+#: debug.c:2387
+#, c-format
+msgid "Can't set breakpoint in function `%s'\n"
+msgstr ""
+
+#: debug.c:2403
+#, c-format
+msgid "breakpoint %d set at file `%s', line %d is unconditional\n"
+msgstr ""
+
+#: debug.c:2508 debug.c:2530
+#, c-format
+msgid "Deleted breakpoint %d"
+msgstr ""
+
+#: debug.c:2514
+#, c-format
+msgid "No breakpoint(s) at entry to function `%s'\n"
+msgstr ""
+
+#: debug.c:2541
+#, fuzzy, c-format
+msgid "No breakpoint at file `%s', line #%d\n"
+msgstr "error interno: fichero `%s', línea %d\n"
+
+#: debug.c:2596 debug.c:2637 debug.c:2657 debug.c:2700
+msgid "invalid breakpoint number"
+msgstr ""
+
+#: debug.c:2612
+msgid "Delete all breakpoints? (y or n) "
+msgstr ""
+
+#: debug.c:2613 debug.c:2923 debug.c:2976
+msgid "y"
+msgstr ""
+
+#: debug.c:2662
+#, c-format
+msgid "Will ignore next %ld crossing(s) of breakpoint %d.\n"
+msgstr ""
+
+#: debug.c:2666
+#, c-format
+msgid "Will stop next time breakpoint %d is reached.\n"
+msgstr ""
+
+#: debug.c:2783
+#, c-format
+msgid "Can only debug programs provided with the `-f' option.\n"
+msgstr ""
+
+#: debug.c:2908
+#, c-format
+msgid "Failed to restart debugger"
+msgstr ""
+
+#: debug.c:2922
+msgid "Program already running. Restart from beginning (y/n)? "
+msgstr ""
+
+#: debug.c:2926
+#, c-format
+msgid "Program not restarted\n"
+msgstr ""
+
+#: debug.c:2936
+#, c-format
+msgid "error: cannot restart, operation not allowed\n"
+msgstr ""
+
+#: debug.c:2942
+#, c-format
+msgid "error (%s): cannot restart, ignoring rest of the commands\n"
+msgstr ""
+
+#: debug.c:2950
+#, c-format
+msgid "Starting program: \n"
+msgstr ""
+
+#: debug.c:2959
+#, c-format
+msgid "Program exited %s with exit value: %d\n"
+msgstr ""
+
+#: debug.c:2975
+msgid "The program is running. Exit anyway (y/n)? "
+msgstr ""
+
+#: debug.c:3010
+#, c-format
+msgid "Not stopped at any breakpoint; argument ignored.\n"
+msgstr ""
+
+#: debug.c:3015
+#, c-format
+msgid "invalid breakpoint number %d."
+msgstr ""
+
+#: debug.c:3020
+#, c-format
+msgid "Will ignore next %ld crossings of breakpoint %d.\n"
+msgstr ""
+
+#: debug.c:3207
+#, c-format
+msgid "'finish' not meaningful in the outermost frame main()\n"
+msgstr ""
+
+#: debug.c:3212
+#, c-format
+msgid "Run till return from "
+msgstr ""
+
+#: debug.c:3255
+#, c-format
+msgid "'return' not meaningful in the outermost frame main()\n"
+msgstr ""
+
+#: debug.c:3369
+#, c-format
+msgid "Can't find specified location in function `%s'\n"
+msgstr ""
+
+#: debug.c:3377
+#, fuzzy, c-format
+msgid "invalid source line %d in file `%s'"
+msgstr "ya se incluyó el fichero fuente `%s'"
+
+#: debug.c:3392
+#, c-format
+msgid "Can't find specified location %d in file `%s'\n"
+msgstr ""
+
+#: debug.c:3424
+#, fuzzy, c-format
+msgid "element not in array\n"
+msgstr "delete: el índice `%s' no está en la matriz `%s'"
+
+#: debug.c:3424
+#, c-format
+msgid "untyped variable\n"
+msgstr ""
+
+#: debug.c:3466
+#, c-format
+msgid "Stopping in %s ...\n"
+msgstr ""
+
+#: debug.c:3543
+#, c-format
+msgid "'finish' not meaningful with non-local jump '%s'\n"
+msgstr ""
+
+#: debug.c:3550
+#, c-format
+msgid "'until' not meaningful with non-local jump '%s'\n"
+msgstr ""
+
+#: debug.c:4185
+msgid "\t------[Enter] to continue or q [Enter] to quit------"
+msgstr ""
+
+#: debug.c:4186
+msgid "q"
+msgstr ""
+
+#: debug.c:5001
+#, fuzzy, c-format
+msgid "[\"%s\"] not in array `%s'"
+msgstr "delete: el índice `%s' no está en la matriz `%s'"
+
+#: debug.c:5207
+#, c-format
+msgid "sending output to stdout\n"
+msgstr ""
+
+#: debug.c:5247
+msgid "invalid number"
+msgstr ""
+
+#: debug.c:5381
+#, fuzzy, c-format
+msgid "`%s' not allowed in current context; statement ignored"
+msgstr "`exit' no se puede llamar en el contexto actual"
+
+#: debug.c:5389
+#, fuzzy
+msgid "`return' not allowed in current context; statement ignored"
+msgstr "`exit' no se puede llamar en el contexto actual"
+
+#: debug.c:5590
+#, fuzzy, c-format
+msgid "No symbol `%s' in current context"
+msgstr "se intentó usar la matriz `%s' en un contexto escalar"
+
+#: dfa.c:1118 dfa.c:1121 dfa.c:1142 dfa.c:1150 dfa.c:1162 dfa.c:1197
+#: dfa.c:1206 dfa.c:1209 dfa.c:1214 dfa.c:1228 dfa.c:1275
+#, fuzzy
+msgid "unbalanced ["
+msgstr "[ desbalanceado"
+
+#: dfa.c:1174
+#, fuzzy
+msgid "invalid character class"
+msgstr "Nombre de clase de caracter inválido"
+
+#: dfa.c:1316
+msgid "character class syntax is [[:space:]], not [:space:]"
+msgstr ""
+
+#: dfa.c:1366
+#, fuzzy
+msgid "unfinished \\ escape"
+msgstr "Escape \\ sin terminar"
+
+#: dfa.c:1513 regcomp.c:161
+msgid "Invalid content of \\{\\}"
+msgstr "Contenido inválido de \\{\\}"
+
+#: dfa.c:1516 regcomp.c:176
+msgid "Regular expression too big"
+msgstr "La expresión regular es demasiado grande"
-#: eval.c:412
+#: dfa.c:1936
+#, fuzzy
+msgid "unbalanced ("
+msgstr "( desbalanceado"
+
+#: dfa.c:2062
+#, fuzzy
+msgid "no syntax specified"
+msgstr "No se especifican los bits de sintaxis de la expresión regular"
+
+#: dfa.c:2070
+#, fuzzy
+msgid "unbalanced )"
+msgstr ") desbalanceado"
+
+#: eval.c:394
#, c-format
msgid "unknown nodetype %d"
msgstr "tipo de nodo %d desconocido"
-#: eval.c:423 eval.c:437
+#: eval.c:405 eval.c:419
#, c-format
msgid "unknown opcode %d"
msgstr "código de operación %d desconocido"
-#: eval.c:434
+#: eval.c:416
#, c-format
msgid "opcode %s not an operator or keyword"
msgstr "el código de operación %s no es un operador o una palabra clave"
-#: eval.c:488
+#: eval.c:472
msgid "buffer overflow in genflags2str"
msgstr "desbordamiento de almacenamiento temporal en genflags2str"
-#: eval.c:698
+#: eval.c:675
#, c-format
msgid ""
"\n"
@@ -1013,830 +1874,1292 @@ msgstr ""
"\t# Pila de Llamadas de Funciones:\n"
"\n"
-#: eval.c:725
+#: eval.c:704
msgid "`IGNORECASE' is a gawk extension"
msgstr "`IGNORECASE' es una extensión de gawk"
-#: eval.c:754
+#: eval.c:736
msgid "`BINMODE' is a gawk extension"
msgstr "`BINMODE' es una extensión de gawk"
-#: eval.c:812
+#: eval.c:794
#, c-format
msgid "BINMODE value `%s' is invalid, treated as 3"
msgstr "el valor BINMODE `%s' es inválido; se trata como 3"
-#: eval.c:902
+#: eval.c:885
#, c-format
msgid "bad `%sFMT' specification `%s'"
msgstr "especificación `%sFMT' `%s' errónea"
-#: eval.c:980
+#: eval.c:969
msgid "turning off `--lint' due to assignment to `LINT'"
msgstr "se desactiva `--lint' debido a una asignación a `LINT'"
-#: eval.c:1127 eval.c:1777
-#, 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:1158 eval.c:1789 eval.c:1802
+#: eval.c:1147
#, c-format
msgid "reference to uninitialized argument `%s'"
msgstr "referencia al argumento sin inicializar `%s'"
-#: eval.c:1177
+#: eval.c:1148
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "referencia a la variable sin inicializar `%s'"
+
+#: eval.c:1166
msgid "attempt to field reference from non-numeric value"
msgstr "se intentó una referencia de campo desde un valor que no es númerico"
-#: eval.c:1179
+#: eval.c:1168
msgid "attempt to field reference from null string"
msgstr "se intentó una referencia de campo desde una cadena nula"
-#: eval.c:1185
+#: eval.c:1176
#, c-format
msgid "attempt to access field %ld"
msgstr "se intentó acceder al campo %ld"
-#: eval.c:1194
+#: eval.c:1185
#, c-format
msgid "reference to uninitialized field `$%ld'"
msgstr "referencia al campo sin inicializar `$%ld'"
-#: eval.c:1256
+#: eval.c:1272
#, 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:1437
+#: eval.c:1473
#, c-format
msgid "unwind_stack: unexpected type `%s'"
msgstr "unwind_stack: tipo `%s' inesperado"
-#: eval.c:1532
+#: eval.c:1569
msgid "division by zero attempted in `/='"
msgstr "se intentó una división por cero en `/='"
-#: eval.c:1539
+#: eval.c:1576
#, c-format
msgid "division by zero attempted in `%%='"
msgstr "se intentó una división por cero en `%%='"
-#: eval.c:1876 eval.c:2122
-#, c-format
-msgid "attempt to use array `%s[\"%.*s\"]' in a scalar context"
-msgstr "se intentó usar la matriz `%s[\"%.*s\"]' en un contexto escalar"
-
-#: eval.c:1907
-msgid "assignment used in conditional context"
-msgstr "se usó una asignación en un contexto condicional"
+#: ext.c:89 ext.c:171
+msgid "extensions are not allowed in sandbox mode"
+msgstr "no se permiten las extensiones en modo sandbox"
-#: eval.c:1911
-msgid "statement has no effect"
-msgstr "la declaración no tiene efecto"
+#: ext.c:92
+#, fuzzy
+msgid "-l / @load are gawk extensions"
+msgstr "@include es una extensión de gawk"
-#: eval.c:2343
-#, c-format
-msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+#: ext.c:95
+msgid "load_ext: received NULL lib_name"
msgstr ""
-"bucle for: la matriz `%s' cambió de tamaño de %ld a %ld durante la ejecución "
-"del bucle"
-
-#: eval.c:2458
-#, c-format
-msgid "function called indirectly through `%s' does not exist"
-msgstr "no existe la función llamada indirectamente a través de `%s'"
-
-#: eval.c:2470
-#, c-format
-msgid "function `%s' not defined"
-msgstr "la función `%s' no está definida"
-
-#: eval.c:2511
-#, c-format
-msgid "non-redirected `getline' invalid inside `%s' rule"
-msgstr "`getline' no redirigido es inválido dentro de la regla `%s'"
-#: eval.c:2600
-#, c-format
-msgid "error reading input file `%s': %s"
-msgstr "error al leer el fichero de entrada `%s': %s"
+#: ext.c:98
+#, fuzzy, c-format
+msgid "load_ext: cannot open library `%s' (%s)\n"
+msgstr "fatal: extension: no se puede abrir `%s' (%s)\n"
-#: eval.c:2614
-#, c-format
-msgid "`nextfile' cannot be called from a `%s' rule"
-msgstr "`nextfile' no se puede llamar desde una regla `%s'"
+#: ext.c:104
+#, fuzzy, c-format
+msgid ""
+"load_ext: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"
+msgstr ""
+"fatal: extension: la biblioteca `%s': no define "
+"`plugin_is_GPL_compatible' (%s)\n"
-#: eval.c:2694
-#, c-format
-msgid "`next' cannot be called from a `%s' rule"
-msgstr "`next' no se puede llamar desde una regla `%s'"
+#: ext.c:110
+#, fuzzy, c-format
+msgid "load_ext: library `%s': cannot call function `%s' (%s)\n"
+msgstr ""
+"fatal: extension: la biblioteca `%s': no puede llamar a la función `"
+"%s' (%s)\n"
-#: eval.c:2760
+#: ext.c:114
#, c-format
-msgid "Sorry, don't know how to interpret `%s'"
-msgstr "Perdón, no se cómo interpretar `%s'"
-
-#: ext.c:64
-msgid "extensions are not allowed in sandbox mode"
-msgstr "no se permiten las extensiones en modo sandbox"
+msgid "load_ext: library `%s' initialization routine `%s' failed\n"
+msgstr ""
-#: ext.c:70 ext.c:75
+#: ext.c:174
msgid "`extension' is a gawk extension"
msgstr "`extension' es una extensión de gawk"
-#: ext.c:85
-#, c-format
-msgid "fatal: extension: cannot open `%s' (%s)\n"
+#: ext.c:177
+msgid "extension: received NULL lib_name"
+msgstr ""
+
+#: ext.c:180
+#, fuzzy, c-format
+msgid "extension: cannot open library `%s' (%s)"
msgstr "fatal: extension: no se puede abrir `%s' (%s)\n"
-#: ext.c:94
-#, c-format
+#: ext.c:186
+#, fuzzy, c-format
msgid ""
-"fatal: extension: library `%s': does not define "
-"`plugin_is_GPL_compatible' (%s)\n"
+"extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)"
msgstr ""
"fatal: extension: la biblioteca `%s': no define "
"`plugin_is_GPL_compatible' (%s)\n"
-#: ext.c:103
-#, c-format
-msgid "fatal: extension: library `%s': cannot call function `%s' (%s)\n"
+#: ext.c:190
+#, fuzzy, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)"
msgstr ""
"fatal: extension: la biblioteca `%s': no puede llamar a la función `"
"%s' (%s)\n"
-#: ext.c:137
-msgid "extension: missing function name"
+#: ext.c:221
+#, fuzzy
+msgid "make_builtin: missing function name"
msgstr "extension: falta el nombre de la función"
-#: ext.c:142
+#: ext.c:236
+#, fuzzy, c-format
+msgid "make_builtin: can't redefine function `%s'"
+msgstr "extension: no se puede redefinir la función `%s'"
+
+#: ext.c:240
+#, fuzzy, c-format
+msgid "make_builtin: function `%s' already defined"
+msgstr "extension: la función `%s' ya está definida"
+
+#: ext.c:244
+#, fuzzy, c-format
+msgid "make_builtin: function name `%s' previously defined"
+msgstr "extension: el nombre de función `%s' se definió previamente"
+
+#: ext.c:246
+#, fuzzy, c-format
+msgid "make_builtin: 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:249 ext.c:304
#, c-format
+msgid "make_builtin: negative argument count for function `%s'"
+msgstr "make_builtin: cuenta de argumento negativa para la función `%s'"
+
+#: ext.c:276
+#, fuzzy
+msgid "extension: missing function name"
+msgstr "extension: falta el nombre de la función"
+
+#: ext.c:279 ext.c:283
+#, fuzzy, 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:151
-#, c-format
+#: ext.c:291
+#, fuzzy, c-format
msgid "extension: can't redefine function `%s'"
msgstr "extension: no se puede redefinir la función `%s'"
-#: ext.c:155
-#, c-format
+#: ext.c:295
+#, fuzzy, c-format
msgid "extension: function `%s' already defined"
msgstr "extension: la función `%s' ya está definida"
-#: ext.c:160
-#, c-format
+#: ext.c:299
+#, fuzzy, c-format
msgid "extension: function name `%s' previously defined"
-msgstr "extension: el nombre de función `%s' se definió previamente"
+msgstr "el nombre de función `%s' se definió previamente"
-#: ext.c:162
-#, c-format
+#: ext.c:301
+#, fuzzy, 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:166
-#, c-format
-msgid "make_builtin: negative argument count for function `%s'"
-msgstr "make_builtin: cuenta de argumento negativa para la función `%s'"
-
-#: ext.c:269
+#: ext.c:375
#, c-format
msgid "function `%s' defined to take no more than %d argument(s)"
msgstr "la función `%s' se definió para tomar no más de %d argumento(s)"
-#: ext.c:272
+#: ext.c:378
#, c-format
msgid "function `%s': missing argument #%d"
msgstr "función `%s': falta el argumento #%d"
-#: ext.c:289
+#: ext.c:395
#, 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:293
+#: ext.c:399
#, 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:306
-msgid "Operation Not Supported"
-msgstr "No Se Admite La Operación"
+#: ext.c:413
+msgid "dynamic loading of library not supported"
+msgstr ""
+
+#: extension/filefuncs.c:159
+#, fuzzy
+msgid "chdir: called with incorrect number of arguments, expecting 1"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/filefuncs.c:439
+#, c-format
+msgid "stat: unable to read symbolic link `%s'"
+msgstr ""
+
+#: extension/filefuncs.c:472
+#, fuzzy
+msgid "stat: called with wrong number of arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/filefuncs.c:479
+#, fuzzy
+msgid "stat: bad parameters"
+msgstr "%s: es un parámetro\n"
+
+#: extension/filefuncs.c:533
+#, fuzzy, c-format
+msgid "fts init: could not create variable %s"
+msgstr "index: el segundo argumento recibido no es una cadena"
+
+#: extension/filefuncs.c:554
+#, fuzzy
+msgid "fts is not supported on this system"
+msgstr "`%s' no se admite en el awk antiguo"
+
+#: extension/filefuncs.c:573
+msgid "fill_stat_element: could not create array"
+msgstr ""
+
+#: extension/filefuncs.c:582
+msgid "fill_stat_element: could not set element"
+msgstr ""
+
+#: extension/filefuncs.c:597
+#, fuzzy
+msgid "fill_path_element: could not set element"
+msgstr "index: el segundo argumento recibido no es una cadena"
+
+#: extension/filefuncs.c:613
+msgid "fill_error_element: could not set element"
+msgstr ""
+
+#: extension/filefuncs.c:660 extension/filefuncs.c:707
+msgid "fts-process: could not create array"
+msgstr ""
+
+#: extension/filefuncs.c:670 extension/filefuncs.c:717
+#: extension/filefuncs.c:735
+#, fuzzy
+msgid "fts-process: could not set element"
+msgstr "index: el segundo argumento recibido no es una cadena"
+
+#: extension/filefuncs.c:784
+#, fuzzy
+msgid "fts: called with incorrect number of arguments, expecting 3"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/filefuncs.c:787
+#, fuzzy
+msgid "fts: bad first parameter"
+msgstr "%s: es un parámetro\n"
+
+#: extension/filefuncs.c:793
+#, fuzzy
+msgid "fts: bad second parameter"
+msgstr "%s: es un parámetro\n"
+
+#: extension/filefuncs.c:799
+#, fuzzy
+msgid "fts: bad third parameter"
+msgstr "%s: es un parámetro\n"
+
+#: extension/filefuncs.c:806
+#, fuzzy
+msgid "fts: could not flatten array\n"
+msgstr "`%s' no es un nombre de variable legal"
+
+#: extension/filefuncs.c:824
+msgid "fts: ignoring sneaky FTS_NOSTAT flag. nyah, nyah, nyah."
+msgstr ""
+
+#: extension/filefuncs.c:841
+msgid "fts: clear_array() failed\n"
+msgstr ""
+
+#: extension/fnmatch.c:112
+#, fuzzy
+msgid "fnmatch: called with less than three arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/fnmatch.c:115
+#, fuzzy
+msgid "fnmatch: called with more than three arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/fnmatch.c:118
+#, fuzzy
+msgid "fnmatch: could not get first argument"
+msgstr "strftime: el primer argumento recibido no es una cadena"
+
+#: extension/fnmatch.c:123
+#, fuzzy
+msgid "fnmatch: could not get second argument"
+msgstr "index: el segundo argumento recibido no es una cadena"
+
+#: extension/fnmatch.c:128
+msgid "fnmatch: could not get third argument"
+msgstr ""
+
+#: extension/fnmatch.c:141
+msgid "fnmatch is not implemented on this system\n"
+msgstr ""
+
+#: extension/fnmatch.c:173
+msgid "fnmatch init: could not add FNM_NOMATCH variable"
+msgstr ""
+
+#: extension/fnmatch.c:183
+#, c-format
+msgid "fnmatch init: could not set array element %s"
+msgstr ""
+
+#: extension/fnmatch.c:193
+msgid "fnmatch init: could not install FNM array"
+msgstr ""
+
+#: extension/fork.c:81
+#, fuzzy
+msgid "fork: called with too many arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/fork.c:94
+msgid "fork: PROCINFO is not an array!"
+msgstr ""
+
+#: extension/fork.c:118
+#, fuzzy
+msgid "waitpid: called with too many arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/fork.c:126
+#, fuzzy
+msgid "wait: called with no arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/fork.c:143
+#, fuzzy
+msgid "wait: called with too many arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/inplace.c:130
+msgid "inplace_begin: in-place editing already active"
+msgstr ""
+
+#: extension/inplace.c:133 extension/inplace.c:207
+#, c-format
+msgid "inplace_begin: expects 2 arguments but called with %d"
+msgstr ""
+
+#: extension/inplace.c:136
+msgid "inplace_begin: cannot retrieve 1st argument as a string filename"
+msgstr ""
+
+#: extension/inplace.c:144
+#, c-format
+msgid "inplace_begin: disabling in-place editing for invalid FILENAME `%s'"
+msgstr ""
+
+#: extension/inplace.c:151
+#, fuzzy, c-format
+msgid "inplace_begin: Cannot stat `%s' (%s)"
+msgstr "fatal: extension: no se puede abrir `%s' (%s)\n"
+
+#: extension/inplace.c:158
+#, fuzzy, c-format
+msgid "inplace_begin: `%s' is not a regular file"
+msgstr "`%s' no es un nombre de variable legal"
+
+#: extension/inplace.c:169
+#, c-format
+msgid "inplace_begin: mkstemp(`%s') failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:178
+#, fuzzy, c-format
+msgid "inplace_begin: chmod failed (%s)"
+msgstr "%s: falló close (%s)"
+
+#: extension/inplace.c:185
+#, c-format
+msgid "inplace_begin: dup(stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:188
+#, c-format
+msgid "inplace_begin: dup2(%d, stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:191
+#, fuzzy, c-format
+msgid "inplace_begin: close(%d) failed (%s)"
+msgstr "%s: falló close (%s)"
+
+#: extension/inplace.c:210
+msgid "inplace_end: cannot retrieve 1st argument as a string filename"
+msgstr ""
+
+#: extension/inplace.c:217
+msgid "inplace_end: in-place editing not active"
+msgstr ""
+
+#: extension/inplace.c:223
+#, c-format
+msgid "inplace_end: dup2(%d, stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:226
+#, fuzzy, c-format
+msgid "inplace_end: close(%d) failed (%s)"
+msgstr "%s: falló close (%s)"
+
+#: extension/inplace.c:230
+#, c-format
+msgid "inplace_end: fsetpos(stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:243
+#, fuzzy, c-format
+msgid "inplace_end: link(`%s', `%s') failed (%s)"
+msgstr "falló la limpieza de la tubería de `%s' (%s)."
+
+#: extension/inplace.c:253
+#, fuzzy, c-format
+msgid "inplace_end: rename(`%s', `%s') failed (%s)"
+msgstr "falló al cerrar el df %d (`%s') (%s)"
+
+#: extension/ordchr.c:69
+#, fuzzy
+msgid "ord: called with too many arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/ordchr.c:75
+#, fuzzy
+msgid "ord: called with no arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/ordchr.c:77
+#, fuzzy
+msgid "ord: called with inappropriate argument(s)"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/ordchr.c:99
+#, fuzzy
+msgid "chr: called with too many arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/ordchr.c:109
+#, fuzzy
+msgid "chr: called with no arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/ordchr.c:111
+#, fuzzy
+msgid "chr: called with inappropriate argument(s)"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/readdir.c:281
+#, c-format
+msgid "dir_take_control_of: opendir/fdopendir failed: %s"
+msgstr ""
+
+#: extension/readfile.c:113
+#, fuzzy
+msgid "readfile: called with too many arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/readfile.c:137
+#, fuzzy
+msgid "readfile: called with no arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/rwarray.c:124
+#, fuzzy
+msgid "writea: called with too many arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/rwarray.c:131
+#, fuzzy, c-format
+msgid "do_writea: argument 0 is not a string\n"
+msgstr "exp: el argumento %g está fuera de rango"
+
+#: extension/rwarray.c:137
+#, fuzzy, c-format
+msgid "do_writea: argument 1 is not an array\n"
+msgstr "split: el cuarto argumento no es una matriz"
+
+#: extension/rwarray.c:184
+#, c-format
+msgid "write_array: could not flatten array\n"
+msgstr ""
+
+#: extension/rwarray.c:198
+#, c-format
+msgid "write_array: could not release flattened array\n"
+msgstr ""
+
+#: extension/rwarray.c:280
+#, fuzzy
+msgid "reada: called with too many arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/rwarray.c:287
+#, fuzzy, c-format
+msgid "do_reada: argument 0 is not a string\n"
+msgstr "exp: el argumento %g está fuera de rango"
+
+#: extension/rwarray.c:293
+#, fuzzy, c-format
+msgid "do_reada: argument 1 is not an array\n"
+msgstr "match: el tercer argumento no es una matriz"
+
+#: extension/rwarray.c:337
+#, c-format
+msgid "do_reada: clear_array failed\n"
+msgstr ""
+
+#: extension/rwarray.c:374
+#, c-format
+msgid "read_array: set_array_element failed\n"
+msgstr ""
+
+#: extension/time.c:113
+#, fuzzy
+msgid "gettimeofday: ignoring arguments"
+msgstr "mktime: se recibió un argumento que no es una cadena"
+
+#: extension/time.c:144
+msgid "gettimeofday: not supported on this platform"
+msgstr ""
+
+#: extension/time.c:165
+#, fuzzy
+msgid "sleep: called with too many arguments"
+msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#: extension/time.c:168
+#, fuzzy
+msgid "sleep: missing required numeric argument"
+msgstr "exp: se recibió un argumento que no es númerico"
+
+#: extension/time.c:174
+#, fuzzy
+msgid "sleep: argument is negative"
+msgstr "exp: el argumento %g está fuera de rango"
+
+#: extension/time.c:208
+msgid "sleep: not supported on this platform"
+msgstr ""
-#: field.c:328
+#: field.c:345
msgid "NF set to negative value"
msgstr "se definió NF con un valor negativo"
-#: field.c:951 field.c:958 field.c:962
+#: field.c:971 field.c:978 field.c:982
msgid "split: fourth argument is a gawk extension"
msgstr "split: el cuarto argumento es una extensión de gawk"
-#: field.c:955
+#: field.c:975
msgid "split: fourth argument is not an array"
msgstr "split: el cuarto argumento no es una matriz"
-#: field.c:969
+#: field.c:989
msgid "split: second argument is not an array"
msgstr "split: el segundo argumento no es una matriz"
-#: field.c:973
+#: field.c:993
msgid "split: cannot use the same array for second and fourth args"
msgstr ""
"split: no se puede usar la misma matriz para el segundo y cuarto argumentos"
-#: field.c:978
+#: field.c:998
msgid "split: cannot use a subarray of second arg for fourth arg"
msgstr ""
"split: no se puede usar una submatriz del segundo argumento para el cuarto "
"argumento"
-#: field.c:981
+#: field.c:1001
msgid "split: cannot use a subarray of fourth arg for second arg"
msgstr ""
"split: no se puede usar una submatriz del cuarto argumento para el segundo "
"argumento"
-#: field.c:1010
+#: field.c:1032
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:1050
+#: field.c:1072
msgid "patsplit: fourth argument is not an array"
msgstr "patsplit: el cuarto argumento no es una matriz"
-#: field.c:1055
+#: field.c:1077
msgid "patsplit: second argument is not an array"
msgstr "patsplit: el segundo argumento no es una matriz"
-#: field.c:1061
+#: field.c:1083
msgid "patsplit: third argument must be non-null"
msgstr "patsplit: el tercer argumento no debe ser nulo"
-#: field.c:1065
+#: field.c:1087
msgid "patsplit: cannot use the same array for second and fourth args"
msgstr ""
"patsplit: no se puede usar la misma matriz para el segundo y cuarto "
"argumentos"
-#: field.c:1070
+#: field.c:1092
msgid "patsplit: cannot use a subarray of second arg for fourth arg"
msgstr ""
"patsplit: no se puede usar una submatriz del segundo argumento para el "
"cuarto argumento"
-#: field.c:1073
+#: field.c:1095
msgid "patsplit: cannot use a subarray of fourth arg for second arg"
msgstr ""
"patsplit: no se puede usar una submatriz del cuarto argumento para el "
"segundo argumento"
-#: field.c:1110
+#: field.c:1133
msgid "`FIELDWIDTHS' is a gawk extension"
msgstr "`FIELDWIDTHS' es una extensión gawk"
-#: field.c:1173
+#: field.c:1197
#, c-format
msgid "invalid FIELDWIDTHS value, near `%s'"
msgstr "valor de FIELDWIDTHS inválido, cerca de `%s'"
-#: field.c:1246
+#: field.c:1270
msgid "null string for `FS' is a gawk extension"
msgstr "la cadena nula para `FS' es una extensión de gawk"
-#: field.c:1250
+#: field.c:1274
msgid "old awk does not support regexps as value of `FS'"
msgstr "el awk antiguo no admite expresiones regulares como valor de `FS'"
-#: field.c:1369
+#: field.c:1393
msgid "`FPAT' is a gawk extension"
msgstr "`FPAT' es una extensión de gawk"
-#: getopt.c:574 getopt.c:590
+#: gawkapi.c:146
+msgid "awk_value_to_node: received null retval"
+msgstr ""
+
+#: gawkapi.c:384
+msgid "node_to_awk_value: received null node"
+msgstr ""
+
+#: gawkapi.c:387
+msgid "node_to_awk_value: received null val"
+msgstr ""
+
+#: gawkapi.c:807
+#, fuzzy
+msgid "remove_element: received null array"
+msgstr "length: se recibió un argumento de matriz"
+
+#: gawkapi.c:810
+msgid "remove_element: received null subscript"
+msgstr ""
+
+#: gawkapi.c:947
+#, c-format
+msgid "api_flatten_array: could not convert index %d\n"
+msgstr ""
+
+#: gawkapi.c:952
#, c-format
-msgid "%s: option '%s' is ambiguous\n"
+msgid "api_flatten_array: could not convert value %d\n"
+msgstr ""
+
+#: getopt.c:604 getopt.c:633
+#, fuzzy, c-format
+msgid "%s: option '%s' is ambiguous; possibilities:"
msgstr "%s: la opción '%s' es ambigua\n"
-#: getopt.c:623 getopt.c:627
+#: getopt.c:679 getopt.c:683
#, 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
+#: getopt.c:692 getopt.c:697
#, 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:684 getopt.c:703
+#: getopt.c:740 getopt.c:759
#, c-format
msgid "%s: option '--%s' requires an argument\n"
msgstr "%s: la opción '--%s' requiere un argumento\n"
-#: getopt.c:741 getopt.c:744
+#: getopt.c:797 getopt.c:800
#, c-format
msgid "%s: unrecognized option '--%s'\n"
msgstr "%s: no se reconoce la opción '--%s'\n"
-#: getopt.c:752 getopt.c:755
+#: getopt.c:808 getopt.c:811
#, c-format
msgid "%s: unrecognized option '%c%s'\n"
msgstr "%s: no se reconoce la opción '%c%s'\n"
-#: getopt.c:804 getopt.c:807
+#: getopt.c:860 getopt.c:863
#, c-format
msgid "%s: invalid option -- '%c'\n"
msgstr "%s: opción inválida -- '%c'\n"
-#: getopt.c:857 getopt.c:874 getopt.c:1082 getopt.c:1100
+#: getopt.c:916 getopt.c:933 getopt.c:1143 getopt.c:1161
#, c-format
msgid "%s: option requires an argument -- '%c'\n"
msgstr "%s: la opción requiere un argumento -- '%c'\n"
-#: getopt.c:930 getopt.c:946
+#: getopt.c:989 getopt.c:1005
#, c-format
msgid "%s: option '-W %s' is ambiguous\n"
msgstr "%s: la opción '-W %s' es ambigua\n"
-#: getopt.c:970 getopt.c:988
+#: getopt.c:1029 getopt.c:1047
#, 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"
-#: getopt.c:1009 getopt.c:1027
+#: getopt.c:1068 getopt.c:1086
#, c-format
msgid "%s: option '-W %s' requires an argument\n"
msgstr "%s: la opción '-W %s' requiere un argumento\n"
-#: io.c:280
+#: io.c:392
#, c-format
msgid "command line argument `%s' is a directory: skipped"
msgstr "el argumento de la línea de órdenes `%s' es un directorio: se salta"
-#: io.c:283 io.c:385
+#: io.c:395 io.c:513
#, c-format
msgid "cannot open file `%s' for reading (%s)"
msgstr "no se puede abrir el fichero `%s' para lectura (%s)"
-#: io.c:501
+#: io.c:640
#, c-format
msgid "close of fd %d (`%s') failed (%s)"
msgstr "falló al cerrar el df %d (`%s') (%s)"
-#: io.c:578
+#: io.c:716
msgid "redirection not allowed in sandbox mode"
msgstr "no se permite la redirección en modo sandbox"
-#: io.c:612
+#: io.c:750
#, c-format
msgid "expression in `%s' redirection only has numeric value"
msgstr "la expresión en la redirección `%s' sólo tiene valor numérico"
-#: io.c:618
+#: io.c:756
#, 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:624
+#: io.c:761
#, 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:667
+#: io.c:809
#, c-format
msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
msgstr "mezcla innecesaria de `>' y `>>' para el fichero `%.*s'"
-#: io.c:720
+#: io.c:863
#, 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:730
+#: io.c:873
#, 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:753
+#: io.c:904
#, 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:835
+#: io.c:986
#, c-format
msgid "can't redirect from `%s' (%s)"
msgstr "no se puede redirigir desde `%s' (%s)"
-#: io.c:838
+#: io.c:989
#, c-format
msgid "can't redirect to `%s' (%s)"
msgstr "no se puede redirigir a `%s' (%s)"
-#: io.c:889
+#: io.c:1040
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:905
+#: io.c:1056
#, c-format
msgid "close of `%s' failed (%s)."
msgstr "falló al cerrar `%s' (%s)."
-#: io.c:913
+#: io.c:1064
msgid "too many pipes or input files open"
msgstr "demasiadas tuberías o ficheros de entrada abiertos"
-#: io.c:935
+#: io.c:1086
msgid "close: second argument must be `to' or `from'"
msgstr "close: el segundo argumento debe ser `to' o `from'"
-#: io.c:952
+#: io.c:1103
#, 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:957
+#: io.c:1108
msgid "close of redirection that was never opened"
msgstr "se cerró una redirección que nunca se abrió"
-#: io.c:1054
+#: io.c:1205
#, c-format
msgid "close: redirection `%s' not opened with `|&', second argument ignored"
msgstr ""
"close: la redirección `%s' no se abrió con `|&', se descarta el segundo "
"argumento"
-#: io.c:1070
+#: io.c:1222
#, 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:1073
+#: io.c:1225
#, 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:1093
+#: io.c:1245
#, c-format
msgid "no explicit close of socket `%s' provided"
msgstr "no se provee el cerrado explícito del `socket' `%s'"
-#: io.c:1096
+#: io.c:1248
#, 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:1099
+#: io.c:1251
#, 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:1102
+#: io.c:1254
#, c-format
msgid "no explicit close of file `%s' provided"
msgstr "no se provee el cerrado explícito del fichero `%s'"
-#: io.c:1130 io.c:1185 main.c:793 main.c:830
+#: io.c:1284 io.c:1342 main.c:864 main.c:906
#, c-format
msgid "error writing standard output (%s)"
msgstr "error al escribir en la salida estándar (%s)"
-#: io.c:1134 io.c:1190
+#: io.c:1289 io.c:1348 main.c:866
#, c-format
msgid "error writing standard error (%s)"
msgstr "error al escribir en la salida estándar de error (%s)"
-#: io.c:1142
+#: io.c:1297
#, c-format
msgid "pipe flush of `%s' failed (%s)."
msgstr "falló la limpieza de la tubería de `%s' (%s)."
-#: io.c:1145
+#: io.c:1300
#, 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:1148
+#: io.c:1303
#, c-format
msgid "file flush of `%s' failed (%s)."
msgstr "falló la limpieza del fichero de `%s' (%s)."
-#: io.c:1263
+#: io.c:1420
#, c-format
msgid "local port %s invalid in `/inet'"
msgstr "puerto local %s inválido en `/inet'"
-#: io.c:1280
+#: io.c:1438
#, c-format
msgid "remote host and port information (%s, %s) invalid"
msgstr "anfitrión remoto e información de puerto (%s, %s) inválidos"
-#: io.c:1432
+#: io.c:1590
#, 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:1446
+#: io.c:1604
#, c-format
msgid "special file name `%s' is incomplete"
msgstr "el nombre de fichero especial `%s' está incompleto"
-#: io.c:1463
+#: io.c:1621
msgid "must supply a remote hostname to `/inet'"
msgstr "se debe proporcionar a `/inet' un nombre de anfitrión remoto"
-#: io.c:1481
+#: io.c:1639
msgid "must supply a remote port to `/inet'"
msgstr "se debe proporcionar a `/inet' un puerto remoto"
-#: io.c:1527
+#: io.c:1685
msgid "TCP/IP communications are not supported"
msgstr "no se admiten las comunicaciones TCP/IP"
-#: io.c:1694
+#: io.c:1867
#, c-format
msgid "could not open `%s', mode `%s'"
msgstr "no se puede abrir `%s', modo `%s'"
-#: io.c:1748
+#: io.c:1917
#, c-format
msgid "close of master pty failed (%s)"
msgstr "falló al cerrar el pty maestro (%s)"
-#: io.c:1750 io.c:1918 io.c:2075
+#: io.c:1919 io.c:2105 io.c:2305
#, c-format
msgid "close of stdout in child failed (%s)"
msgstr "falló al cerrar la salida estándar en el hijo (%s)"
-#: io.c:1753
+#: io.c:1922
#, 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:1755 io.c:1923
+#: io.c:1924 io.c:2110
#, c-format
msgid "close of stdin in child failed (%s)"
msgstr "falló al cerrar la entrada estándar en el hijo (%s)"
-#: io.c:1758
+#: io.c:1927
#, 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:1760 io.c:1781
+#: io.c:1929 io.c:1951
#, c-format
msgid "close of slave pty failed (%s)"
msgstr "falló al cerrar el pty esclavo (%s)"
-#: io.c:1859 io.c:1921 io.c:2053 io.c:2078
+#: io.c:2040 io.c:2108 io.c:2276 io.c:2308
#, 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:1866 io.c:1926
+#: io.c:2047 io.c:2113
#, 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:1886 io.c:2068
+#: io.c:2073 io.c:2298
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:1894
+#: io.c:2081
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:1929 io.c:2080 io.c:2094
+#: io.c:2116 io.c:2310 io.c:2324
#, c-format
msgid "close of pipe failed (%s)"
msgstr "falló al cerrar la tubería (%s)"
-#: io.c:1974
+#: io.c:2174
msgid "`|&' not supported"
msgstr "no se admite `|&'"
-#: io.c:2040
+#: io.c:2261
#, c-format
msgid "cannot open pipe `%s' (%s)"
msgstr "no se puede abrir la tubería `%s' (%s)"
-#: io.c:2088
+#: io.c:2318
#, 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:2521
+#: io.c:2790
+msgid "register_input_parser: received NULL pointer"
+msgstr ""
+
+#: io.c:2818
+#, c-format
+msgid "input parser `%s' conflicts with previously installed input parser `%s'"
+msgstr ""
+
+#: io.c:2825
+#, c-format
+msgid "input parser `%s' failed to open `%s'"
+msgstr ""
+
+#: io.c:2845
+msgid "register_output_wrapper: received NULL pointer"
+msgstr ""
+
+#: io.c:2873
+#, c-format
+msgid ""
+"output wrapper `%s' conflicts with previously installed output wrapper `%s'"
+msgstr ""
+
+#: io.c:2880
+#, c-format
+msgid "output wrapper `%s' failed to open `%s'"
+msgstr ""
+
+#: io.c:2901
+msgid "register_output_processor: received NULL pointer"
+msgstr ""
+
+#: io.c:2930
+#, c-format
+msgid ""
+"two-way processor `%s' conflicts with previously installed two-way processor "
+"`%s'"
+msgstr ""
+
+#: io.c:2939
+#, c-format
+msgid "two way processor `%s' failed to open `%s'"
+msgstr ""
+
+#: io.c:3064
#, c-format
msgid "data file `%s' is empty"
msgstr "el fichero de datos `%s' está vacío"
-#: io.c:2562 io.c:2570
+#: io.c:3106 io.c:3114
msgid "could not allocate more input memory"
msgstr "no se puede reservar más memoria de entrada"
-#: io.c:3128
+#: io.c:3682
msgid "multicharacter value of `RS' is a gawk extension"
msgstr "el valor multicaracter de `RS' es una extensión de gawk"
-#: io.c:3233
+#: io.c:3771
msgid "IPv6 communication is not supported"
msgstr "no se admite la comunicación IPv6"
-#: main.c:364
-msgid "`-m[fr]' option irrelevant in gawk"
-msgstr "la opción -m[fr] es irrelevante en gawk"
-
-#: main.c:366
-msgid "-m option usage: `-m[fr] nnn'"
-msgstr "uso de la opción -m: `-m[fr]' nnn"
-
-#: main.c:389
+#: main.c:405
msgid "empty argument to `-e/--source' ignored"
msgstr "se descarta el argumento vacío para `-e/--source'"
-#: main.c:460
+#: main.c:495
#, c-format
msgid "%s: option `-W %s' unrecognized, ignored\n"
msgstr "%s: no se reconoce la opción `-W %s', se descarta\n"
-#: main.c:513
+#: main.c:541
#, c-format
msgid "%s: option requires an argument -- %c\n"
msgstr "%s: la opción requiere un argumento -- %c\n"
-#: main.c:534
+#: main.c:562
msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
msgstr ""
"la variable de ambiente `POSIXLY_CORRECT' está definida: se activa `--posix'"
-#: main.c:540
+#: main.c:568
msgid "`--posix' overrides `--traditional'"
msgstr "`--posix' se impone a `--traditional'"
-#: main.c:551
+#: main.c:579
msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
msgstr "`--posix'/`--traditional' se imponen a `--non-decimal-data'"
-#: main.c:555
+#: main.c:583
#, 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:560
-msgid "`--posix' overrides `--binary'"
+#: main.c:588
+#, fuzzy
+msgid "`--posix' overrides `--characters-as-bytes'"
msgstr "`--posix' se impone a `--binary'"
-#: main.c:611
+#: main.c:647
#, 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:614
+#: main.c:650
#, 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:616
+#: main.c:652
#, 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:655
+#: main.c:710
msgid "no program text at all!"
msgstr "¡No hay ningún programa de texto!"
-#: main.c:733
+#: main.c:799
#, 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:735
+#: main.c:801
#, 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:740
+#: main.c:806
msgid "POSIX options:\t\tGNU long options: (standard)\n"
msgstr "Opciones POSIX:\t\tOpciones largas GNU: (estándar)\n"
-#: main.c:741
+#: main.c:807
msgid "\t-f progfile\t\t--file=progfile\n"
msgstr "\t-f fichprog\t\t--file=fichprog\n"
-#: main.c:742
+#: main.c:808
msgid "\t-F fs\t\t\t--field-separator=fs\n"
msgstr "\t-F sc\t\t\t--field-separator=sc\n"
-#: main.c:743
+#: main.c:809
msgid "\t-v var=val\t\t--assign=var=val\n"
msgstr "\t-v var=valor\t\t--assign=var=valor\n"
-#: main.c:744
+#: main.c:810
msgid "Short options:\t\tGNU long options: (extensions)\n"
msgstr "Opciones cortas:\t\tOpciones largas GNU: (extensiones)\n"
-#: main.c:745
+#: main.c:811
msgid "\t-b\t\t\t--characters-as-bytes\n"
msgstr "\t-b\t\t\t--characters-as-bytes\n"
-#: main.c:746
+#: main.c:812
msgid "\t-c\t\t\t--traditional\n"
msgstr "\t-c\t\t\t--traditional\n"
-#: main.c:747
+#: main.c:813
msgid "\t-C\t\t\t--copyright\n"
msgstr "\t-C\t\t\t--copyright\n"
-#: main.c:748
+#: main.c:814
msgid "\t-d[file]\t\t--dump-variables[=file]\n"
msgstr "\t-d[fichero]\t\t--dump-variables[=fichero]\n"
+#: main.c:815
+#, fuzzy
+msgid "\t-D[file]\t\t--debug[=file]\n"
+msgstr "\t-p[fichero]\t\t--profile[=fichero]\n"
+
# Esta es la línea más larga de la lista de argumentos.
# Probar con gawk para revisar tabuladores. cfuga
-#: main.c:749
+#: main.c:816
msgid "\t-e 'program-text'\t--source='program-text'\n"
msgstr "\t-e 'texto-prog'\t--source='texto-prog'\n"
-#: main.c:750
+#: main.c:817
msgid "\t-E file\t\t\t--exec=file\n"
msgstr "\t-E fichero\t\t--exec=fichero\n"
-#: main.c:751
+#: main.c:818
msgid "\t-g\t\t\t--gen-pot\n"
msgstr "\t-g\t\t\t--gen-pot\n"
-#: main.c:752
+#: main.c:819
msgid "\t-h\t\t\t--help\n"
msgstr "\t-h\t\t\t--help\n"
-#: main.c:753
+#: main.c:820
+msgid "\t-i includefile\t\t--include=includefile\n"
+msgstr ""
+
+#: main.c:821
+msgid "\t-l library\t\t--load=library\n"
+msgstr ""
+
+#: main.c:822
msgid "\t-L [fatal]\t\t--lint[=fatal]\n"
msgstr "\t-L [fatal]\t\t--lint[=fatal]\n"
-#: main.c:754
+#: main.c:823
msgid "\t-n\t\t\t--non-decimal-data\n"
msgstr "\t-n\t\t\t--non-decimal-data\n"
-#: main.c:755
+#: main.c:824
+#, fuzzy
+msgid "\t-M\t\t\t--bignum\n"
+msgstr "\t-g\t\t\t--gen-pot\n"
+
+#: main.c:825
msgid "\t-N\t\t\t--use-lc-numeric\n"
msgstr "\t-N\t\t\t--use-lc-numeric\n"
-#: main.c:756
+#: main.c:826
+#, fuzzy
+msgid "\t-o[file]\t\t--pretty-print[=file]\n"
+msgstr "\t-p[fichero]\t\t--profile[=fichero]\n"
+
+#: main.c:827
msgid "\t-O\t\t\t--optimize\n"
msgstr "\t-O\t\t\t--optimize\n"
-#: main.c:757
+#: main.c:828
msgid "\t-p[file]\t\t--profile[=file]\n"
msgstr "\t-p[fichero]\t\t--profile[=fichero]\n"
-#: main.c:758
+#: main.c:829
msgid "\t-P\t\t\t--posix\n"
msgstr "\t-P\t\t\t--posix\n"
-#: main.c:759
+#: main.c:830
msgid "\t-r\t\t\t--re-interval\n"
msgstr "\t-r\t\t\t--re-interval\n"
-#: main.c:761
-msgid "\t-R file\t\t\t--command=file\n"
-msgstr "\t-R fichero\t\t\t--command=fichero\n"
-
-#: main.c:762
+#: main.c:831
msgid "\t-S\t\t\t--sandbox\n"
msgstr "\t-S\t\t\t--sandbox\n"
-#: main.c:763
+#: main.c:832
msgid "\t-t\t\t\t--lint-old\n"
msgstr "\t-t\t\t\t--lint-old\n"
-#: main.c:764
+#: main.c:833
msgid "\t-V\t\t\t--version\n"
msgstr "\t-V\t\t\t--version\n"
-#: main.c:766
+#: main.c:835
msgid "\t-W nostalgia\t\t--nostalgia\n"
msgstr "\t-W nostalgia\t\t--nostalgia\n"
-#: main.c:769
+#: main.c:838
msgid "\t-Y\t\t--parsedebug\n"
msgstr "\t-Y\t\t--parsedebug\n"
@@ -1845,7 +3168,7 @@ msgstr "\t-Y\t\t--parsedebug\n"
#. for this application. Please add _another line_ with the
#. address for translation bugs.
#. no-wrap
-#: main.c:778
+#: main.c:847
msgid ""
"\n"
"To report bugs, see node `Bugs' in `gawk.info', which is\n"
@@ -1859,7 +3182,7 @@ msgstr ""
"Reporte los errores de los mensajes en español a <es@li.org>.\n"
"\n"
-#: main.c:782
+#: main.c:851
msgid ""
"gawk is a pattern scanning and processing language.\n"
"By default it reads standard input and writes standard output.\n"
@@ -1869,7 +3192,7 @@ msgstr ""
"Por defecto lee la entrada estándar y escribe en la salida estándar.\n"
"\n"
-#: main.c:786
+#: main.c:855
msgid ""
"Examples:\n"
"\tgawk '{ sum += $1 }; END { print sum }' file\n"
@@ -1879,7 +3202,7 @@ msgstr ""
"\tgawk '{ sum += $1 }; END { print sum }' fichero\n"
"\tgawk -F: '{ print $1 }' /etc/passwd\n"
-#: main.c:806
+#: main.c:880
#, c-format
msgid ""
"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
@@ -1899,7 +3222,7 @@ msgstr ""
"(a su elección) cualquier versión posterior.\n"
"\n"
-#: main.c:814
+#: main.c:888
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"
@@ -1913,7 +3236,7 @@ msgstr ""
"Licencia Pública General de GNU para más detalles.\n"
"\n"
-#: main.c:820
+#: main.c:894
msgid ""
"You should have received a copy of the GNU General Public License\n"
"along with this program. If not, see http://www.gnu.org/licenses/.\n"
@@ -1922,16 +3245,16 @@ msgstr ""
"junto con este programa. Si no es así, consulte\n"
"http://www.gnu.org/licenses/.\n"
-#: main.c:855
+#: main.c:931
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:1089
+#: main.c:1208
#, c-format
msgid "unknown value for field spec: %d\n"
msgstr "valor desconocido para la especificación de campo: %d\n"
-#: main.c:1170
+#: main.c:1306
#, c-format
msgid ""
"%s: `%s' argument to `-v' not in `var=value' form\n"
@@ -1940,85 +3263,130 @@ msgstr ""
"%s: el argumento `%s' para `-v' no es de la forma `var=valor'\n"
"\n"
-#: main.c:1196
+#: main.c:1332
#, c-format
msgid "`%s' is not a legal variable name"
msgstr "`%s' no es un nombre de variable legal"
-#: main.c:1199
+#: main.c:1335
#, 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:1203
+#: main.c:1339
#, c-format
msgid "cannot use gawk builtin `%s' as variable name"
msgstr ""
"no se puede utilizar la orden interna de gawk `%s' como nombre de variable"
-#: main.c:1208
+#: main.c:1344
#, c-format
msgid "cannot use function `%s' as variable name"
msgstr "no se puede usar la función `%s' como nombre de variable"
-#: main.c:1261
+#: main.c:1397
msgid "floating point exception"
msgstr "excepción de coma flotante"
-#: main.c:1268
+#: main.c:1404
msgid "fatal error: internal error"
msgstr "error fatal: error interno"
-#: main.c:1283
+#: main.c:1419
msgid "fatal error: internal error: segfault"
msgstr "error fatal: error interno: falla de segmentación"
-#: main.c:1295
+#: main.c:1431
msgid "fatal error: internal error: stack overflow"
msgstr "error fatal: error interno: desbordamiento de pila"
-#: main.c:1345
+#: main.c:1490
#, c-format
msgid "no pre-opened fd %d"
msgstr "no existe el df %d abierto previamente"
-#: main.c:1352
+#: main.c:1497
#, 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:1375 main.c:1384
-#, c-format
-msgid "could not find groups: %s"
-msgstr "no se pueden encontrar los grupos: %s"
+#: mpfr.c:550
+#, fuzzy, c-format
+msgid "PREC value `%.*s' is invalid"
+msgstr "el valor BINMODE `%s' es inválido; se trata como 3"
-#: msg.c:63
+#: mpfr.c:608
+#, fuzzy, c-format
+msgid "RNDMODE value `%.*s' is invalid"
+msgstr "el valor BINMODE `%s' es inválido; se trata como 3"
+
+#: mpfr.c:698
+#, fuzzy, c-format
+msgid "%s: received non-numeric argument"
+msgstr "cos: se recibió un argumento que no es númerico"
+
+#: mpfr.c:800
+#, fuzzy
+msgid "compl(%Rg): negative value will give strange results"
+msgstr "compl(%lf): el valor negativo dará resultados extraños"
+
+#: mpfr.c:804
+#, fuzzy
+msgid "comp(%Rg): fractional value will be truncated"
+msgstr "compl(%lf): el valor fraccionario se truncará"
+
+#: mpfr.c:816
+#, fuzzy, c-format
+msgid "cmpl(%Zd): negative values will give strange results"
+msgstr "compl(%lf): el valor negativo dará resultados extraños"
+
+#: mpfr.c:835
+#, fuzzy, c-format
+msgid "%s: received non-numeric argument #%d"
+msgstr "cos: se recibió un argumento que no es númerico"
+
+#: mpfr.c:845
+msgid "%s: argument #%d has invalid value %Rg, using 0"
+msgstr ""
+
+#: mpfr.c:857
+#, fuzzy
+msgid "%s: argument #%d negative value %Rg will give strange results"
+msgstr "compl(%lf): el valor negativo dará resultados extraños"
+
+#: mpfr.c:863
+#, fuzzy
+msgid "%s: argument #%d fractional value %Rg will be truncated"
+msgstr "or(%lf, %lf): los valores fraccionarios serán truncados"
+
+#: mpfr.c:878
+#, fuzzy, c-format
+msgid "%s: argument #%d negative value %Zd will give strange results"
+msgstr "compl(%lf): el valor negativo dará resultados extraños"
+
+#: msg.c:68
#, c-format
msgid "cmd. line:"
msgstr "línea ord.:"
-#: msg.c:107
-msgid "error: "
-msgstr "error: "
-
-#: node.c:406
+#: node.c:421
msgid "backslash at end of string"
msgstr "barra invertida al final de la cadena"
-#: node.c:517
+#: node.c:500
#, c-format
msgid "old awk does not support the `\\%c' escape sequence"
msgstr "el awk antiguo no admite la secuencia de escape `\\%c'"
-#: node.c:568
+#: node.c:551
msgid "POSIX does not allow `\\x' escapes"
msgstr "POSIX no permite escapes `\\x'"
-#: node.c:574
+#: node.c:557
msgid "no hex digits in `\\x' escape sequence"
msgstr "no hay dígitos hexadecimales en la secuencia de escape `\\x'"
-#: node.c:596
+#: node.c:579
#, c-format
msgid ""
"hex escape \\x%.*s of %d characters probably not interpreted the way you "
@@ -2027,12 +3395,12 @@ msgstr ""
"el escape hexadecimal \\x%.*s de %d caracteres tal vez no se interprete de "
"la forma esperada"
-#: node.c:611
+#: node.c:594
#, c-format
msgid "escape sequence `\\%c' treated as plain `%c'"
msgstr "la secuencia de escape `\\%c' se trata como una simple `%c'"
-#: node.c:750
+#: node.c:739
msgid ""
"Invalid multibyte data detected. There may be a mismatch between your data "
"and your locale."
@@ -2040,27 +3408,27 @@ msgstr ""
"Se detectaron datos multibyte inválidos. Puede ser que no coincidan sus "
"datos con su local."
-#: posix/gawkmisc.c:176
+#: posix/gawkmisc.c:177
#, c-format
msgid "%s %s `%s': could not get fd flags: (fcntl F_GETFD: %s)"
msgstr ""
"%s %s `%s': no se pueden obtener las opciones del fd: (fcntl F_GETFD: %s)"
-#: posix/gawkmisc.c:188
+#: posix/gawkmisc.c:189
#, c-format
msgid "%s %s `%s': could not set close-on-exec: (fcntl F_SETFD: %s)"
msgstr "%s %s `%s': no se puede establecer close-on-exec: (fcntl F_SETFD: %s)"
-#: profile.c:83
+#: profile.c:71
#, c-format
msgid "could not open `%s' for writing: %s"
msgstr "no se puede abrir `%s' para escritura: %s"
-#: profile.c:85
+#: profile.c:73
msgid "sending profile to standard error"
msgstr "se envía el perfil a la salida estándar de error"
-#: profile.c:203
+#: profile.c:193
#, c-format
msgid ""
"\t# %s block(s)\n"
@@ -2069,7 +3437,7 @@ msgstr ""
"\t# bloque(s) %s\n"
"\n"
-#: profile.c:208
+#: profile.c:198
#, c-format
msgid ""
"\t# Rule(s)\n"
@@ -2078,17 +3446,29 @@ msgstr ""
"\t# Regla(s)\n"
"\n"
-#: profile.c:279
+#: profile.c:272
#, c-format
msgid "internal error: %s with null vname"
msgstr "error interno: %s con vname nulo"
-#: profile.c:952
+#: profile.c:537
+#, fuzzy
+msgid "internal error: builtin with null fname"
+msgstr "error interno: %s con vname nulo"
+
+#: profile.c:949
+#, c-format
+msgid ""
+"\t# Loaded extensions (-l and/or @load)\n"
+"\n"
+msgstr ""
+
+#: profile.c:972
#, c-format
msgid "\t# gawk profile, created %s\n"
msgstr "\t# perfil de gawk, creado %s\n"
-#: profile.c:1331
+#: profile.c:1475
#, c-format
msgid ""
"\n"
@@ -2097,94 +3477,223 @@ msgstr ""
"\n"
"\t# Funciones, enumeradas alfabéticamente\n"
-#: profile.c:1370
+#: profile.c:1513
#, c-format
msgid "redir2str: unknown redirection type %d"
msgstr "redir2str: tipo de redirección %d desconocida"
-#: re.c:572
-#, fuzzy, c-format
-msgid "range of the form `[%c-%c]' is locale dependent"
-msgstr "el rango de la forma [%c-%c] depende del local"
-
-#: re.c:599
+#: re.c:607
#, c-format
msgid "regexp component `%.*s' should probably be `[%.*s]'"
msgstr ""
"el componente de expresión regular `%.*s' probablemente debe ser `[%.*s]'"
-#: regcomp.c:132
+#: regcomp.c:131
msgid "Success"
msgstr "Éxito"
-#: regcomp.c:135
+#: regcomp.c:134
msgid "No match"
msgstr "No hay coincidencia"
-#: regcomp.c:138
+#: regcomp.c:137
msgid "Invalid regular expression"
msgstr "Expresión regular inválida"
-#: regcomp.c:141
+#: regcomp.c:140
msgid "Invalid collation character"
msgstr "Caracter de ordenación inválido"
-#: regcomp.c:144
+#: regcomp.c:143
msgid "Invalid character class name"
msgstr "Nombre de clase de caracter inválido"
-#: regcomp.c:147
+#: regcomp.c:146
msgid "Trailing backslash"
msgstr "Barra invertida extra al final"
-#: regcomp.c:150
+#: regcomp.c:149
msgid "Invalid back reference"
msgstr "Referencia hacia atrás inválida"
-#: regcomp.c:153
+#: regcomp.c:152
msgid "Unmatched [ or [^"
msgstr "[ o [^ desemparejados"
-#: regcomp.c:156
+#: regcomp.c:155
msgid "Unmatched ( or \\("
msgstr "( o \\( desemparejados"
-#: regcomp.c:159
+#: regcomp.c:158
msgid "Unmatched \\{"
msgstr "\\{ desemparejado"
-#: regcomp.c:162
-msgid "Invalid content of \\{\\}"
-msgstr "Contenido inválido de \\{\\}"
-
-#: regcomp.c:165
+#: regcomp.c:164
msgid "Invalid range end"
msgstr "Final de rango inválido"
-#: regcomp.c:168
+#: regcomp.c:167
msgid "Memory exhausted"
msgstr "Memoria agotada"
-#: regcomp.c:171
+#: regcomp.c:170
msgid "Invalid preceding regular expression"
msgstr "Expresión regular precedente inválida"
-#: regcomp.c:174
+#: regcomp.c:173
msgid "Premature end of regular expression"
msgstr "Fin prematuro de la expresión regular"
-#: regcomp.c:177
-msgid "Regular expression too big"
-msgstr "La expresión regular es demasiado grande"
-
-#: regcomp.c:180
+#: regcomp.c:179
msgid "Unmatched ) or \\)"
msgstr ") o \\) desemparejados"
-#: regcomp.c:701
+#: regcomp.c:704
msgid "No previous regular expression"
msgstr "No hay una expresión regular previa"
+#: symbol.c:741
+msgid "can not pop main context"
+msgstr ""
+
+#~ msgid "range of the form `[%c-%c]' is locale dependent"
+#~ msgstr "el rango de la forma `[%c-%c]' depende del local"
+
+#, fuzzy
+#~ msgid "[s]printf called with no arguments"
+#~ msgstr "sqrt: se llamó con el argumento negativo %g"
+
+#~ msgid "`-m[fr]' option irrelevant in gawk"
+#~ msgstr "la opción -m[fr] es irrelevante en gawk"
+
+#~ msgid "-m option usage: `-m[fr] nnn'"
+#~ msgstr "uso de la opción -m: `-m[fr]' nnn"
+
+#, fuzzy
+#~ msgid "%s: received non-numeric first argument"
+#~ msgstr "or: el primer argumento recibido no es númerico"
+
+#, fuzzy
+#~ msgid "%s: received non-numeric second argument"
+#~ msgstr "or: el segundo argumento recibido no es númerico"
+
+#, fuzzy
+#~ msgid "%s(%Rg, ..): negative values will give strange results"
+#~ msgstr "or(%lf, %lf): los valores negativos darán resultados extraños"
+
+#, fuzzy
+#~ msgid "%s(%Rg, ..): fractional values will be truncated"
+#~ msgstr "or(%lf, %lf): los valores fraccionarios serán truncados"
+
+#, fuzzy
+#~ msgid "%s(%Zd, ..): negative values will give strange results"
+#~ msgstr "or(%lf, %lf): los valores negativos darán resultados extraños"
+
+#, fuzzy
+#~ msgid "%s(.., %Rg): negative values will give strange results"
+#~ msgstr "or(%lf, %lf): los valores negativos darán resultados extraños"
+
+#, fuzzy
+#~ msgid "%s(.., %Zd): negative values will give strange results"
+#~ msgstr "or(%lf, %lf): los valores negativos darán resultados extraños"
+
+#~ msgid "`%s' is a Bell Labs extension"
+#~ msgstr "`%s' es una extensión de Bell Labs"
+
+#~ msgid "`nextfile' is a gawk extension"
+#~ msgstr "`nextfile' es una extensión de gawk"
+
+#~ msgid "`delete array' is a gawk extension"
+#~ msgstr "`delete array' es una extensión de gawk"
+
+#~ msgid "and: received non-numeric first argument"
+#~ msgstr "and: el primer argumento recibido no es númerico"
+
+#~ msgid "and: received non-numeric second argument"
+#~ msgstr "and: el segundo argumento recibido no es númerico"
+
+#~ msgid "and(%lf, %lf): fractional values will be truncated"
+#~ msgstr "and(%lf, %lf): los valores fraccionarios serán truncados"
+
+#~ msgid "xor: received non-numeric first argument"
+#~ msgstr "xor: el primer argumento recibido no es númerico"
+
+#~ msgid "xor: received non-numeric second argument"
+#~ msgstr "xor: el segundo argumento recibido no es númerico"
+
+#~ msgid "xor(%lf, %lf): fractional values will be truncated"
+#~ msgstr "xor(%lf, %lf): los valores fraccionarios se truncarán"
+
+#~ msgid "Operation Not Supported"
+#~ msgstr "No Se Admite La Operación"
+
+#~ msgid "attempt to use function `%s' as an array"
+#~ msgstr "se intentó usar la función `%s' como una matriz"
+
+#~ msgid "reference to uninitialized element `%s[\"%.*s\"]'"
+#~ msgstr "referencia al elemento sin inicializar `%s[\"%.*s\"]'"
+
+#~ msgid "subscript of array `%s' is null string"
+#~ msgstr "el subíndice de la matriz `%s' es la cadena nula"
+
+#~ msgid "%s: empty (null)\n"
+#~ msgstr "%s: vacío (nulo)\n"
+
+#~ msgid "%s: empty (zero)\n"
+#~ msgstr "%s: vacío (cero)\n"
+
+#~ msgid "%s: table_size = %d, array_size = %d\n"
+#~ msgstr "%s: tamaño_tabla = %d, tamaño_matriz = %d\n"
+
+#~ msgid "%s: array_ref to %s\n"
+#~ msgstr "%s: array_ref a %s\n"
+
+#~ msgid "use of non-array as array"
+#~ msgstr "uso de una matriz que no es matriz"
+
+#~ 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"
+
+#~ msgid "assignment used in conditional context"
+#~ msgstr "se usó una asignación en un contexto condicional"
+
+#~ msgid "statement has no effect"
+#~ msgstr "la declaración no tiene efecto"
+
+#~ msgid ""
+#~ "for loop: array `%s' changed size from %ld to %ld during loop execution"
+#~ msgstr ""
+#~ "bucle for: la matriz `%s' cambió de tamaño de %ld a %ld durante la "
+#~ "ejecución del bucle"
+
+#~ msgid "function called indirectly through `%s' does not exist"
+#~ msgstr "no existe la función llamada indirectamente a través de `%s'"
+
+#~ msgid "function `%s' not defined"
+#~ msgstr "la función `%s' no está definida"
+
+#~ msgid "non-redirected `getline' invalid inside `%s' rule"
+#~ msgstr "`getline' no redirigido es inválido dentro de la regla `%s'"
+
+#~ msgid "error reading input file `%s': %s"
+#~ msgstr "error al leer el fichero de entrada `%s': %s"
+
+#~ msgid "`nextfile' cannot be called from a `%s' rule"
+#~ msgstr "`nextfile' no se puede llamar desde una regla `%s'"
+
+#~ msgid "`next' cannot be called from a `%s' rule"
+#~ msgstr "`next' no se puede llamar desde una regla `%s'"
+
+#~ msgid "Sorry, don't know how to interpret `%s'"
+#~ msgstr "Perdón, no se cómo interpretar `%s'"
+
+#~ msgid "\t-R file\t\t\t--command=file\n"
+#~ msgstr "\t-R fichero\t\t\t--command=fichero\n"
+
+#~ msgid "could not find groups: %s"
+#~ msgstr "no se pueden encontrar los grupos: %s"
+
#~ msgid "assignment is not allowed to result of builtin function"
#~ msgstr "no se permite la asignación como resultado de una función interna"
@@ -2200,9 +3709,6 @@ msgstr "No hay una expresión regular previa"
#~ msgid "attempt to use scalar `%s' as array"
#~ msgstr "se intentó usar el dato escalar `%s' como una matriz"
-#~ msgid "attempt to use array `%s' in scalar context"
-#~ msgstr "se intentó usar la matriz `%s' en un contexto escalar"
-
#~ msgid "call of `length' without parentheses is deprecated by POSIX"
#~ msgstr "la llamada de `length' sin paréntesis está obsoleta por POSIX"
@@ -2351,30 +3857,12 @@ msgstr "No hay una expresión regular previa"
#~ 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 "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"
diff --git a/po/fi.gmo b/po/fi.gmo
index df538bcf..478aa070 100644
--- a/po/fi.gmo
+++ b/po/fi.gmo
Binary files differ
diff --git a/po/fi.po b/po/fi.po
index 442a7322..49014233 100644
--- a/po/fi.po
+++ b/po/fi.po
@@ -1,14 +1,14 @@
# Finnish messages for gawk.
-# Copyright © 2010, 2011 Free Software Foundation, Inc.
+# Copyright © 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
# This file is distributed under the same license as the gawk package.
-# Jorma Karvonen <karvonen.jorma@gmail.com>, 2010-2011.
+# Jorma Karvonen <karvonen.jorma@gmail.com>, 2010-2014.
#
msgid ""
msgstr ""
-"Project-Id-Version: gawk 4.0.0\n"
+"Project-Id-Version: gawk 4.1.0b\n"
"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
-"POT-Creation-Date: 2011-10-24 05:57+0200\n"
-"PO-Revision-Date: 2011-09-12 12:14+0200\n"
+"POT-Creation-Date: 2014-04-08 19:23+0300\n"
+"PO-Revision-Date: 2014-01-16 13:32+0200\n"
"Last-Translator: Jorma Karvonen <karvonen.jorma@gmail.com>\n"
"Language-Team: Finnish <translation-team-fi@lists.sourceforge.net>\n"
"Language: fi\n"
@@ -16,509 +16,490 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 1.5.4\n"
-#: array.c:140
+#: array.c:256
#, c-format
msgid "from %s"
msgstr "taulukosta %s"
-#: array.c:248
+#: array.c:357
msgid "attempt to use a scalar value as array"
msgstr "yritettiin käyttää skalaariarvoa taulukkona"
-#: array.c:251
-#, c-format
-msgid "attempt to use function `%s' as an array"
-msgstr "yritettiin käyttää funktiota â€%s†taulukkona"
-
-#: array.c:254
+#: array.c:359
#, c-format
msgid "attempt to use scalar parameter `%s' as an array"
msgstr "yritettiin käyttää skalaariparametria â€%s†taulukkona"
-#: array.c:257
+#: array.c:362
#, c-format
msgid "attempt to use scalar `%s' as an array"
msgstr "yritettiin käyttää skalaaria â€%s†taulukkona"
-#: array.c:302 array.c:707 builtin.c:84 builtin.c:1384 builtin.c:1426
-#: builtin.c:1439 builtin.c:1856 builtin.c:1868 eval.c:1135 eval.c:1139
-#: eval.c:1495 eval.c:1812
+#: array.c:409 array.c:576 builtin.c:85 builtin.c:1615 builtin.c:1661
+#: builtin.c:1674 builtin.c:2102 builtin.c:2116 eval.c:1122 eval.c:1126
+#: eval.c:1531
#, c-format
msgid "attempt to use array `%s' in a scalar context"
msgstr "yritettiin käyttää taulukkoa â€%s†skalaarikontekstissa"
-#: array.c:513
-#, c-format
-msgid "reference to uninitialized element `%s[\"%.*s\"]'"
-msgstr "viite alustamattomaan elementtiin â€%s[\"%.*s\"]â€"
-
-#: array.c:519
-#, c-format
-msgid "subscript of array `%s' is null string"
-msgstr "taulukon alaindeksi â€%s†on null-merkkijono"
-
-#: array.c:723
+#: array.c:583
#, c-format
msgid "delete: index `%s' not in array `%s'"
msgstr "delete: indeksi â€%s†ei ole taulukossa â€%sâ€"
-#: array.c:734 eval.c:1865
+#: array.c:597
#, c-format
msgid "attempt to use scalar `%s[\"%.*s\"]' as an array"
msgstr "yritettiin käyttää skalaaria â€%s[\"%.*s\"]†taulukkona"
-#: array.c:910
-#, c-format
-msgid "%s: empty (null)\n"
-msgstr "%s: tyhjä (null)\n"
-
-#: array.c:915
-#, c-format
-msgid "%s: empty (zero)\n"
-msgstr "%s: tyhjä (nolla)\n"
-
-#: array.c:919
-#, c-format
-msgid "%s: table_size = %d, array_size = %d\n"
-msgstr "%s: table_size = %d, array_size = %d\n"
+#: array.c:776
+msgid "adump: first argument not an array"
+msgstr "adump: ensimmäinen argumentti ei ole taulukko"
-#: array.c:954
-#, c-format
-msgid "%s: is parameter\n"
-msgstr "%s: on parametri\n"
-
-#: array.c:958
-#, c-format
-msgid "%s: array_ref to %s\n"
-msgstr "%s: array_ref-viite taulukkoon %s\n"
-
-#: array.c:963
-msgid "adump: argument not an array"
-msgstr "adump: argumentti ei ole taulukko"
-
-#: array.c:1086
+#: array.c:815
msgid "asort: second argument not an array"
msgstr "asort: toinen argumentti ei ole taulukko"
-#: array.c:1087
+#: array.c:816
msgid "asorti: second argument not an array"
msgstr "asorti: toinen argumentti ei ole taulukko"
-#: array.c:1094
+#: array.c:823
msgid "asort: first argument not an array"
msgstr "asort: ensimmäinen argumentti ei ole taulukko"
-#: array.c:1095
+#: array.c:824
msgid "asorti: first argument not an array"
msgstr "asorti: ensimmäinen argumentti ei ole taulukko"
-#: array.c:1102
+#: array.c:831
msgid "asort: cannot use a subarray of first arg for second arg"
msgstr ""
-"asort: ei voida käyttää ensimmäisen argumentin alitaulukkoa toiselle "
-"argumentille"
+"asort: ensimmäisen argumentin alitaulukon käyttö toiselle argumentille "
+"epäonnistui"
-#: array.c:1103
+#: array.c:832
msgid "asorti: cannot use a subarray of first arg for second arg"
msgstr ""
-"asorti: ei voida käyttää ensimmäisen argumentin alitaulukkoa toiselle "
-"argumentille"
+"asorti: ensimmäisen argumentin alitaulukon käyttö toiselle argumentille "
+"epäonnistui"
-#: array.c:1108
+#: array.c:837
msgid "asort: cannot use a subarray of second arg for first arg"
msgstr ""
-"asort: ei voida käyttää toisen argumentin alitaulukkoa ensimmäiselle "
-"argumentille"
+"asort: toisen argumentin alitaulukon käyttö ensimmäiselle argumentille "
+"epäonnistui"
-#: array.c:1109
+#: array.c:838
msgid "asorti: cannot use a subarray of second arg for first arg"
msgstr ""
-"asorti: ei voida käyttää toisen argumentin alitaulukkoa ensimmäiselle "
-"argumentille"
+"asorti: toisen argumentin alitaulukon käyttö ensimmäiselle argumentille "
+"epäonnistui"
-#: array.c:1659
+#: array.c:1314
#, c-format
msgid "`%s' is invalid as a function name"
msgstr "â€%s†on virheellinen funktionimenä"
-#: array.c:1663
+#: array.c:1318
#, c-format
msgid "sort comparison function `%s' is not defined"
msgstr "lajitteluvertailufunktiota â€%s†ei ole määritelty"
-#: awkgram.y:249
+#: awkgram.y:233
#, c-format
msgid "%s blocks must have an action part"
msgstr "%s lohkoilla on oltava toiminto-osa"
-#: awkgram.y:252
+#: awkgram.y:236
msgid "each rule must have a pattern or an action part"
msgstr "jokaisella säännöllä on oltava malli tai toiminto-osa"
-#: awkgram.y:323 awkgram.y:334
+#: awkgram.y:325 awkgram.y:336
msgid "old awk does not support multiple `BEGIN' or `END' rules"
msgstr "vanha awk ei tue useita â€BEGINâ€- tai â€ENDâ€-sääntöjä"
-#: awkgram.y:371
+#: awkgram.y:373
#, c-format
msgid "`%s' is a built-in function, it cannot be redefined"
msgstr "â€%s†on sisäänrakennettu funktio. Sitä ei voi määritellä uudelleen"
-#: awkgram.y:432
+#: awkgram.y:419
msgid "regexp constant `//' looks like a C++ comment, but is not"
msgstr ""
"säännöllisen lausekkeen vakio â€//†näyttää C++-kommentilta, mutta ei ole"
-#: awkgram.y:436
+#: awkgram.y:423
#, c-format
msgid "regexp constant `/%s/' looks like a C comment, but is not"
msgstr ""
"säännöllisen lausekkeen vakio â€/%s/†näyttää C-kommentilta, mutta ei ole"
-#: awkgram.y:528
+#: awkgram.y:515
#, c-format
msgid "duplicate case values in switch body: %s"
msgstr "kaksi samanlaista case-arvoa switch-rakenteen rungossa: %s"
-#: awkgram.y:549
+#: awkgram.y:536
msgid "duplicate `default' detected in switch body"
msgstr "kaksoiskappale â€default†havaittu switch-rungossa"
-#: awkgram.y:809
+#: awkgram.y:796 awkgram.y:3723
msgid "`break' is not allowed outside a loop or switch"
msgstr "â€break†ei ole sallittu silmukan tai switch-lauseen ulkopuolella"
-#: awkgram.y:818
+#: awkgram.y:805 awkgram.y:3715
msgid "`continue' is not allowed outside a loop"
msgstr "â€continue†ei ole sallittu silmukan ulkopuolella"
-#: awkgram.y:828
+#: awkgram.y:815
#, c-format
msgid "`next' used in %s action"
msgstr "â€next†käytetty %s-toiminnossa"
-#: awkgram.y:836
-msgid "`nextfile' is a gawk extension"
-msgstr "â€nextfile†on gawk-laajennus"
-
-#: awkgram.y:841
+#: awkgram.y:824
#, c-format
msgid "`nextfile' used in %s action"
msgstr "â€nextfile†käytetty %s-toiminnossa"
-#: awkgram.y:865
+#: awkgram.y:848
msgid "`return' used outside function context"
msgstr "â€return†käytetty funktiokontekstin ulkopuolella"
-#: awkgram.y:925
+#: awkgram.y:922
msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
msgstr ""
"pelkkä â€print†BEGIN- tai END-säännössä pitäisi luultavasti olla â€print \"\"â€"
-#: awkgram.y:995 awkgram.y:999 awkgram.y:1023
-msgid "`delete array' is a gawk extension"
-msgstr "â€delete array†on gawk-laajennus"
+#: awkgram.y:988 awkgram.y:1037
+msgid "`delete' is not allowed with SYMTAB"
+msgstr "â€delete†ei ole sallittu kohteessa SYMTAB"
+
+#: awkgram.y:990 awkgram.y:1039
+msgid "`delete' is not allowed with FUNCTAB"
+msgstr "â€delete†ei ole sallittu kohteessa FUNCTAB"
-#: awkgram.y:1019
+#: awkgram.y:1024 awkgram.y:1028
msgid "`delete(array)' is a non-portable tawk extension"
msgstr "â€delete(array)†ei ole siirrettävä tawk-laajennus"
-#: awkgram.y:1135
+#: awkgram.y:1149
msgid "multistage two-way pipelines don't work"
msgstr "monivaiheiset kaksisuuntaiset putket eivät toimi"
-#: awkgram.y:1238
+#: awkgram.y:1264
msgid "regular expression on right of assignment"
msgstr "säännöllinen lauseke sijoituksen oikealla puolella"
-#: awkgram.y:1249
+#: awkgram.y:1275
msgid "regular expression on left of `~' or `!~' operator"
msgstr "säännöllinen lauseke â€~â€- tai â€!~â€-operaattorin vasemmalla puolella"
-#: awkgram.y:1265 awkgram.y:1419
+#: awkgram.y:1291 awkgram.y:1442
msgid "old awk does not support the keyword `in' except after `for'"
msgstr "vanha awk ei tue avainsanaa â€in†paitsi â€forâ€-sanan jälkeen"
-#: awkgram.y:1275
+#: awkgram.y:1301
msgid "regular expression on right of comparison"
msgstr "säännöllinen lauseke vertailun oikealla puolella"
-#: awkgram.y:1394
+#: awkgram.y:1417
#, c-format
msgid "`getline var' invalid inside `%s' rule"
msgstr "â€getline var†virheellinen säännön â€%s†sisällä"
-#: awkgram.y:1397 eval.c:2504
+#: awkgram.y:1420
#, c-format
msgid "`getline' invalid inside `%s' rule"
msgstr "â€getline†virheellinen säännön â€%s†sisällä"
-#: awkgram.y:1402
+#: awkgram.y:1425
msgid "non-redirected `getline' undefined inside END action"
msgstr "edelleenohjaamaton â€getline†määrittelemätön END-toiminnon sisällä"
-#: awkgram.y:1421
+#: awkgram.y:1444
msgid "old awk does not support multidimensional arrays"
msgstr "vanha awk ei tue moniulotteisia taulukkoja"
-#: awkgram.y:1517
+#: awkgram.y:1541
msgid "call of `length' without parentheses is not portable"
msgstr "â€lengthâ€-kutsu ilman sulkumerkkejä ei ole siirrettävä"
-#: awkgram.y:1580
+#: awkgram.y:1607
msgid "indirect function calls are a gawk extension"
msgstr "epäsuorat funktiokutsut ovat gawk-laajennus"
-#: awkgram.y:1593
+#: awkgram.y:1620
#, c-format
msgid "can not use special variable `%s' for indirect function call"
-msgstr "ei voi käyttää erikoismuuttujaa â€%s†epäsuoralle funktiokutsulle"
+msgstr "erikoismuuttujan â€%s†käyttö epäsuoralle funktiokutsulle epäonnistui"
-#: awkgram.y:1671
+#: awkgram.y:1698
msgid "invalid subscript expression"
msgstr "virheellinen indeksointilauseke"
-#: awkgram.y:1711
-msgid "use of non-array as array"
-msgstr "ei-taulukon käyttö taulukkona"
-
-#: awkgram.y:1975 awkgram.y:1995 msg.c:98
+#: awkgram.y:2048 awkgram.y:2068 gawkapi.c:206 gawkapi.c:224 msg.c:126
msgid "warning: "
-msgstr "varoitus:"
+msgstr "varoitus: "
-#: awkgram.y:1993 msg.c:130
+#: awkgram.y:2066 gawkapi.c:192 gawkapi.c:221 msg.c:158
msgid "fatal: "
-msgstr "tuhoisa:"
+msgstr "tuhoisa: "
-#: awkgram.y:2043
+#: awkgram.y:2116
msgid "unexpected newline or end of string"
msgstr "odottamaton rivinvaihto tai merkkijonon loppu"
-#: awkgram.y:2300 awkgram.y:2358 awkgram.y:2542
+#: awkgram.y:2383 awkgram.y:2459 awkgram.y:2682 debug.c:523 debug.c:539
+#: debug.c:2812 debug.c:5055
#, c-format
msgid "can't open source file `%s' for reading (%s)"
-msgstr "ei voi avata lähdetiedostoa â€%s†lukemista varten (%s)"
+msgstr "lähdetiedoston â€%s†avaaminen lukemista varten (%s) epäonnistui"
-#: awkgram.y:2301 awkgram.y:2359 builtin.c:122
+#: awkgram.y:2384 awkgram.y:2509
+#, c-format
+msgid "can't open shared library `%s' for reading (%s)"
+msgstr "jaetun kirjaston â€%s†avaaminen lukemista varten (%s) epäonnistui"
+
+#: awkgram.y:2386 awkgram.y:2460 awkgram.y:2510 builtin.c:135 debug.c:5206
msgid "reason unknown"
msgstr "syy tuntematon"
-#: awkgram.y:2317
+#: awkgram.y:2395 awkgram.y:2419
+#, c-format
+msgid "can't include `%s' and use it as a program file"
+msgstr "kohteen â€%s†sisällyttäminen ja käyttö ohjelmatiedostona epäonnistui"
+
+#: awkgram.y:2408
#, c-format
msgid "already included source file `%s'"
msgstr "on jo sisällytetty lähdetiedostoon â€%sâ€"
-#: awkgram.y:2343
+#: awkgram.y:2409
+#, c-format
+msgid "already loaded shared library `%s'"
+msgstr "jaettu kirjasto â€%s†on jo ladattu"
+
+#: awkgram.y:2444
msgid "@include is a gawk extension"
msgstr "@include on gawk-laajennus"
-#: awkgram.y:2349
+#: awkgram.y:2450
msgid "empty filename after @include"
msgstr "tyhjä tiedostonimi @include:n jälkeen"
#: awkgram.y:2494
+msgid "@load is a gawk extension"
+msgstr "@load on gawk-laajennus"
+
+#: awkgram.y:2500
+msgid "empty filename after @load"
+msgstr "tyhjä tiedostonimi @load:n jälkeen"
+
+#: awkgram.y:2634
msgid "empty program text on command line"
msgstr "tyhjä ohjelmateksti komentorivillä"
-#: awkgram.y:2609
+#: awkgram.y:2749
#, c-format
msgid "can't read sourcefile `%s' (%s)"
-msgstr "ei voi lukea lähdetiedostoa â€%s†(%s)"
+msgstr "lähdetiedoston â€%s†(%s) lukeminen epäonnistui"
-#: awkgram.y:2620
+#: awkgram.y:2760
#, c-format
msgid "source file `%s' is empty"
msgstr "lähdetiedosto â€%s†on tyhjä"
-#: awkgram.y:2805
+#: awkgram.y:2937
msgid "source file does not end in newline"
msgstr "lähdetiedoston lopussa ei ole rivinvaihtoa"
-#: awkgram.y:2882
+#: awkgram.y:3042
msgid "unterminated regexp ends with `\\' at end of file"
msgstr ""
"päättämätön säännöllinen lauseke loppuu â€\\â€-merkkeihin tiedoston lopussa"
-#: awkgram.y:2906
+#: awkgram.y:3066
#, c-format
msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
msgstr "%s: %d: tawk:n regex-määre â€/.../%c†ei toimi gawk:ssa"
-#: awkgram.y:2910
+#: awkgram.y:3070
#, c-format
msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
msgstr "tawkin regex-määre â€/.../%c†ei toimi gawkissa"
-#: awkgram.y:2917
+#: awkgram.y:3077
msgid "unterminated regexp"
msgstr "päättämätön säännöllinen lauseke"
-#: awkgram.y:2921
+#: awkgram.y:3081
msgid "unterminated regexp at end of file"
msgstr "päättämätön säännöllinen lauseke tiedoston lopussa"
-#: awkgram.y:2980
+#: awkgram.y:3140
msgid "use of `\\ #...' line continuation is not portable"
msgstr "â€\\ #...â€-rivijatkamisen käyttö ei ole siirrettävä"
-#: awkgram.y:2996
+#: awkgram.y:3156
msgid "backslash not last character on line"
msgstr "kenoviiva ei ole rivin viimeinen merkki"
-#: awkgram.y:3057
+#: awkgram.y:3217
msgid "POSIX does not allow operator `**='"
msgstr "POSIX ei salli operaattoria â€**=â€"
-#: awkgram.y:3059
+#: awkgram.y:3219
msgid "old awk does not support operator `**='"
msgstr "vanha awk ei tue operaattoria â€**=â€"
-#: awkgram.y:3068
+#: awkgram.y:3228
msgid "POSIX does not allow operator `**'"
msgstr "POSIX ei salli operaattoria â€**â€"
-#: awkgram.y:3070
+#: awkgram.y:3230
msgid "old awk does not support operator `**'"
msgstr "vanha awk ei tue operaattoria â€**â€"
-#: awkgram.y:3105
+#: awkgram.y:3265
msgid "operator `^=' is not supported in old awk"
msgstr "operaattoria â€^=†ei tueta vanhassa awk:ssa"
-#: awkgram.y:3113
+#: awkgram.y:3273
msgid "operator `^' is not supported in old awk"
msgstr "operaattoria â€^†ei tueta vanhassa awk:ssa"
-#: awkgram.y:3206 awkgram.y:3222
+#: awkgram.y:3366 awkgram.y:3382 command.y:1178
msgid "unterminated string"
msgstr "päättämätön merkkijono"
-#: awkgram.y:3418
+#: awkgram.y:3603
#, c-format
msgid "invalid char '%c' in expression"
msgstr "virheellinen merkki ’%c’ lausekkeessa"
-#: awkgram.y:3465
+#: awkgram.y:3650
#, c-format
msgid "`%s' is a gawk extension"
msgstr "â€%s†on gawk-laajennus"
-#: awkgram.y:3470
-#, c-format
-msgid "`%s' is a Bell Labs extension"
-msgstr "â€%s†on Bell Labs -laajennus"
-
-#: awkgram.y:3475
+#: awkgram.y:3655
#, c-format
msgid "POSIX does not allow `%s'"
-msgstr "POSIX ei salli operaattori â€%sâ€"
+msgstr "POSIX ei salli operaattoria â€%sâ€"
-#: awkgram.y:3483
+#: awkgram.y:3663
#, c-format
msgid "`%s' is not supported in old awk"
msgstr "â€%s†ei ole tuettu vanhassa awk-ohjelmassa"
-#: awkgram.y:3550
+#: awkgram.y:3753
msgid "`goto' considered harmful!\n"
msgstr "â€gotoâ€-käskyä pidetään haitallisena!\n"
-#: awkgram.y:3601
+#: awkgram.y:3787
#, c-format
msgid "%d is invalid as number of arguments for %s"
msgstr "%d on virheellinen argumenttilukumäärä operaattorille %s"
-#: awkgram.y:3636
+#: awkgram.y:3822
#, c-format
msgid "%s: string literal as last arg of substitute has no effect"
msgstr ""
"%s: merkkijonoliteraalilla ei ole vaikutusta korvauksen viimeisenä "
"argumenttina"
-#: awkgram.y:3641
+#: awkgram.y:3827
#, c-format
msgid "%s third parameter is not a changeable object"
msgstr "%s kolmas parametri ei ole vaihdettava objekti"
-#: awkgram.y:3714 awkgram.y:3717
+#: awkgram.y:3910 awkgram.y:3913
msgid "match: third argument is a gawk extension"
msgstr "match: kolmas argumentti on gawk-laajennus"
-#: awkgram.y:3771 awkgram.y:3774
+#: awkgram.y:3967 awkgram.y:3970
msgid "close: second argument is a gawk extension"
msgstr "close: toinen argumentti on gawk-laajennus"
-#: awkgram.y:3786
+#: awkgram.y:3982
msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
msgstr "dcgettext(_\"...\")-käyttö on virheellinen: poista alaviiva alusta"
-#: awkgram.y:3801
+#: awkgram.y:3997
msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
msgstr "dcngettext(_\"...\")-käyttö on virheellinen: poista alaviiva alusta"
-#: awkgram.y:3893
-#, c-format
-msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
-msgstr "funktio â€%sâ€: parametri #%d, â€%sâ€, samanlainen parametri #%d"
+#: awkgram.y:4016
+msgid "index: regexp constant as second argument is not allowed"
+msgstr "index: regexp-vakio toisena argumenttina ei ole sallittu"
-#: awkgram.y:3935
+#: awkgram.y:4069
#, c-format
msgid "function `%s': parameter `%s' shadows global variable"
msgstr "funktio â€%sâ€: parametri â€%s†varjostaa yleismuuttujaa"
-#: awkgram.y:4093
+#: awkgram.y:4126 debug.c:4041 debug.c:4084 debug.c:5204
#, c-format
msgid "could not open `%s' for writing (%s)"
-msgstr "ei voitu avata tiedostoa â€%s†kirjoittamista varten (%s)"
+msgstr "tiedoston â€%s†avaaminen kirjoittamista varten (%s) epäonnistui"
-#: awkgram.y:4094
+#: awkgram.y:4127
msgid "sending variable list to standard error"
msgstr "lähetetään muuttujaluettelo vakiovirheeseen"
-#: awkgram.y:4100
+#: awkgram.y:4135
#, c-format
msgid "%s: close failed (%s)"
msgstr "%s: sulkeminen epäonnistui (%s)"
-#: awkgram.y:4152
+#: awkgram.y:4160
msgid "shadow_funcs() called twice!"
msgstr "shadow_funcs() kutsuttu kahdesti!"
-#: awkgram.y:4158
+#: awkgram.y:4168
msgid "there were shadowed variables."
msgstr "siellä oli varjostettuja muuttujia."
-#: awkgram.y:4188
+#: awkgram.y:4239
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "funktionimi â€%s†on jo aikaisemmin määritelty"
+
+#: awkgram.y:4285
#, c-format
msgid "function `%s': can't use function name as parameter name"
-msgstr "funktio â€%sâ€: ei voi käyttää funktionimeä parametrinimenä"
+msgstr "funktio â€%sâ€: funktionimen käyttö parametrinimenä epäonnistui"
-#: awkgram.y:4192
+#: awkgram.y:4288
#, c-format
msgid "function `%s': can't use special variable `%s' as a function parameter"
-msgstr "funktio â€%sâ€: ei voi käyttää erikoismuuttujaa â€%s†funktioparametrina"
+msgstr ""
+"funktio â€%sâ€: erikoismuuttujan â€%s†käyttö funktioparametrina epäonnistui"
-#: awkgram.y:4208
+#: awkgram.y:4296
#, c-format
-msgid "function name `%s' previously defined"
-msgstr "funktionimi â€%s†on jo aikaisemmin määritelty"
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "funktio â€%sâ€: parametri #%d, â€%sâ€, samanlainen parametri #%d"
-#: awkgram.y:4376 awkgram.y:4382
+#: awkgram.y:4383 awkgram.y:4389
#, c-format
msgid "function `%s' called but never defined"
msgstr "funktiota â€%s†kutsuttiin, mutta sitä ei ole koskaan määritelty"
-#: awkgram.y:4385
+#: awkgram.y:4393
#, c-format
msgid "function `%s' defined but never called directly"
msgstr "funktio â€%s†määriteltiin, mutta sitä ei ole koskaan kutsuttu suoraan"
-#: awkgram.y:4417
+#: awkgram.y:4425
#, c-format
msgid "regexp constant for parameter #%d yields boolean value"
msgstr "säännöllisen lausekkeen vakio parametrille #%d antaa boolean-arvon"
-#: awkgram.y:4526
+#: awkgram.y:4484
#, c-format
msgid ""
"function `%s' called with space between name and `(',\n"
@@ -527,235 +508,249 @@ msgstr ""
"funktio â€%s†kutsuttu välilyönnillä nimen ja â€(â€-merkin\n"
"välillä, tai käytetty muuttujana tai taulukkona"
-#: awkgram.y:4773 eval.c:2056
+#: awkgram.y:4720
msgid "division by zero attempted"
msgstr "nollalla jakoa yritettiin"
-#: awkgram.y:4782 eval.c:2072
+#: awkgram.y:4729
#, c-format
msgid "division by zero attempted in `%%'"
msgstr "jakoa nollalla yritettiin operaattorissa â€%%â€"
+#: awkgram.y:5049
+msgid ""
+"cannot assign a value to the result of a field post-increment expression"
+msgstr "arvon liittäminen kenttäjälkiaskelkasvatuslausekkeeseen epäonnistui"
+
+#: awkgram.y:5052
+#, c-format
+msgid "invalid target of assignment (opcode %s)"
+msgstr "virheellinen liittämiskohde (käskykoodi %s)"
+
# kohteena voi olla vakiotuloste tai joku muu
-#: builtin.c:120
+#: builtin.c:133
#, c-format
msgid "%s to \"%s\" failed (%s)"
msgstr "%s kohteeseen â€%s†epäonnistui (%s)"
-#: builtin.c:121
+#: builtin.c:134
msgid "standard output"
msgstr "vakiotuloste"
-#: builtin.c:135
+#: builtin.c:148
msgid "exp: received non-numeric argument"
msgstr "exp: vastaanotettu argumentti ei ole numeerinen"
-#: builtin.c:141
+#: builtin.c:154
#, c-format
msgid "exp: argument %g is out of range"
msgstr "exp: argumentti %g on lukualueen ulkopuolella"
-#: builtin.c:200
+#: builtin.c:229
#, c-format
msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
msgstr ""
-"fflush: ei voi tyhjentää: putki â€%s†avattu lukemista varten, ei "
+"fflush: tyhjentäminen epäonnistui: putki â€%s†avattu lukemista varten, ei "
"kirjoittamiseen"
-#: builtin.c:203
+#: builtin.c:232
#, c-format
msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
msgstr ""
-"fflush: ei voi tyhjentää: tiedosto â€%s†avattu lukemista varten, ei "
+"fflush: tyhjentäminen epäonnistui: tiedosto â€%s†avattu lukemista varten, ei "
"kirjoittamiseen"
-#: builtin.c:215
+#: builtin.c:244
#, c-format
msgid "fflush: `%s' is not an open file, pipe or co-process"
msgstr "fflush: â€%s†ei ole avoin tiedosto, putki tai apuprosessi"
-#: builtin.c:333
+#: builtin.c:362
msgid "index: received non-string first argument"
msgstr "index: ensimmäinen vastaanotettu argumentti ei ole merkkijono"
-#: builtin.c:335
+#: builtin.c:364
msgid "index: received non-string second argument"
msgstr "index: toinen vastaanotettu argumentti ei ole merkkijono"
-#: builtin.c:457
+#: builtin.c:488 mpfr.c:757
msgid "int: received non-numeric argument"
msgstr "int: vastaanotettu argumentti ei ole numeerinen"
-#: builtin.c:493
+#: builtin.c:525
msgid "length: received array argument"
msgstr "length: vastaanotettu taulukkoargumentti"
-#: builtin.c:496
+#: builtin.c:528
msgid "`length(array)' is a gawk extension"
msgstr "â€length(array)†on gawk-laajennus"
-#: builtin.c:504
+#: builtin.c:544
msgid "length: received non-string argument"
msgstr "length: vastaanotettu argumentti ei ole merkkijono"
-#: builtin.c:535
+#: builtin.c:575
msgid "log: received non-numeric argument"
msgstr "log: vastaanotettu argumentti ei ole numeerinen"
-#: builtin.c:538
+#: builtin.c:578
#, c-format
msgid "log: received negative argument %g"
msgstr "log: vastaanotettu negatiivinen argumentti %g"
-#: builtin.c:694 builtin.c:699
+#: builtin.c:776 builtin.c:781
msgid "fatal: must use `count$' on all formats or none"
msgstr "kohtalokas: on käytettävä â€count$†kaikilla muodoilla tai ei missään"
-#: builtin.c:761
+#: builtin.c:851
#, c-format
msgid "field width is ignored for `%%' specifier"
msgstr "kenttäleveys ohitetaan â€%%%%â€-määritteelle"
-#: builtin.c:763
+#: builtin.c:853
#, c-format
msgid "precision is ignored for `%%' specifier"
msgstr "tarkkuus ohitetaan â€%%%%â€-määritteelle"
-#: builtin.c:765
+#: builtin.c:855
#, c-format
msgid "field width and precision are ignored for `%%' specifier"
msgstr "kenttäleveys ja tarkkuus ohitetaan â€%%%%â€-määritteelle"
-#: builtin.c:816
+#: builtin.c:906
msgid "fatal: `$' is not permitted in awk formats"
msgstr "kohtalokas: â€$â€-argumentti ei ole sallittu awk-muodoissa"
-#: builtin.c:825
+#: builtin.c:915
msgid "fatal: arg count with `$' must be > 0"
msgstr "kohtalokas: argumenttilukumäärän argumentilla â€$†on oltava > 0"
-#: builtin.c:829
+#: builtin.c:919
#, c-format
msgid "fatal: arg count %ld greater than total number of supplied arguments"
msgstr ""
"kohtalokas: argumenttilukumäärä %ld on suurempi kuin toimitettujen "
"argumenttien lukumäärä"
-#: builtin.c:833
+#: builtin.c:923
msgid "fatal: `$' not permitted after period in format"
msgstr "kohtalokas: â€$â€-argumentti ei ole sallittu pisteen jälkeen muodossa"
-#: builtin.c:849
+#: builtin.c:939
msgid "fatal: no `$' supplied for positional field width or precision"
msgstr ""
"kohtalokas: ei â€$â€-argumenttia tarjottu sijantikenttäleveydelle tai "
"tarkkuudelle"
-#: builtin.c:920
+#: builtin.c:1009
msgid "`l' is meaningless in awk formats; ignored"
msgstr "â€l†on merkityksetön awk-muodoissa; ohitetaan"
-#: builtin.c:924
+#: builtin.c:1013
msgid "fatal: `l' is not permitted in POSIX awk formats"
msgstr "kohtalokas: â€l†ei ole sallittu POSIX awk -muodoissa"
-#: builtin.c:937
+#: builtin.c:1026
msgid "`L' is meaningless in awk formats; ignored"
msgstr "â€L†on merkityksetön awk-muodoissa; ohitetaan"
-#: builtin.c:941
+#: builtin.c:1030
msgid "fatal: `L' is not permitted in POSIX awk formats"
msgstr "kohtalokas: â€L†ei ole sallittu POSIX awk -muodoissa"
-#: builtin.c:954
+#: builtin.c:1043
msgid "`h' is meaningless in awk formats; ignored"
msgstr "â€h†on merkityksetön awk-muodoissa; ohitetaan"
-#: builtin.c:958
+#: builtin.c:1047
msgid "fatal: `h' is not permitted in POSIX awk formats"
msgstr "kohtalokas: â€h†ei ole sallittu POSIX awk -muodoissa"
-#: builtin.c:1271
+#: builtin.c:1463
#, c-format
msgid "[s]printf: value %g is out of range for `%%%c' format"
msgstr "[s]printf: arvo %g on lukualueen ulkopuolella â€%%%câ€-muodolle"
-#: builtin.c:1331
+#: builtin.c:1561
#, c-format
msgid "ignoring unknown format specifier character `%c': no argument converted"
msgstr ""
"ohitetaan tuntematon muotoargumenttimerkki â€%câ€: ei muunnettu argumenttia"
-#: builtin.c:1336
+#: builtin.c:1566
msgid "fatal: not enough arguments to satisfy format string"
msgstr "kohtalokas: ei kylliksi argumentteja muotomerkkijonon tyydyttämiseksi"
-#: builtin.c:1338
+#: builtin.c:1568
msgid "^ ran out for this one"
msgstr "^ tällainen loppui kesken"
-#: builtin.c:1345
+#: builtin.c:1575
msgid "[s]printf: format specifier does not have control letter"
msgstr "[s]printf: muotoargumentilla ei ole ohjauskirjainta"
-#: builtin.c:1348
+#: builtin.c:1578
msgid "too many arguments supplied for format string"
msgstr "muotomerkkijonoon toimitettu liian monta argumenttia"
-#: builtin.c:1422 builtin.c:1433
+#: builtin.c:1634
+msgid "sprintf: no arguments"
+msgstr "sprintf: ei argumentteja"
+
+#: builtin.c:1657 builtin.c:1668
msgid "printf: no arguments"
msgstr "printf: ei argumentteja"
-#: builtin.c:1474
+#: builtin.c:1711
msgid "sqrt: received non-numeric argument"
msgstr "sqrt: vastaanotettu argumentti ei ole numeerinen"
-#: builtin.c:1478
+#: builtin.c:1715
#, c-format
msgid "sqrt: called with negative argument %g"
msgstr "sqrt: kutsuttu negatiivisella argumentilla %g"
-#: builtin.c:1502
+#: builtin.c:1746
#, c-format
msgid "substr: length %g is not >= 1"
msgstr "substr: pituus %g ei ole >= 1"
-#: builtin.c:1504
+#: builtin.c:1748
#, c-format
msgid "substr: length %g is not >= 0"
msgstr "substr: pituus %g ei ole >= 0"
-#: builtin.c:1511
+#: builtin.c:1755
#, c-format
msgid "substr: non-integer length %g will be truncated"
msgstr "substr: typistetään pituus %g, joka ei ole kokonaisluku"
-#: builtin.c:1516
+#: builtin.c:1760
#, c-format
msgid "substr: length %g too big for string indexing, truncating to %g"
msgstr ""
"substr: pituus %g liian suuri merkkijononindeksointiin, typistetään arvoon %g"
-#: builtin.c:1528
+#: builtin.c:1772
#, c-format
msgid "substr: start index %g is invalid, using 1"
msgstr "substr: aloitusindeksi %g on virheellinen, käytetään 1:tä"
-#: builtin.c:1533
+#: builtin.c:1777
#, c-format
msgid "substr: non-integer start index %g will be truncated"
msgstr "substr: typistetään aloitusindeksi %g, joka ei ole kokonaisluku"
-#: builtin.c:1558
+#: builtin.c:1802
msgid "substr: source string is zero length"
msgstr "substr: lähdemerkkijono on nollapituinen"
-#: builtin.c:1574
+#: builtin.c:1818
#, c-format
msgid "substr: start index %g is past end of string"
msgstr "substr: aloitusindeksi %g on merkkijonon lopun jälkeen"
-#: builtin.c:1582
+#: builtin.c:1826
#, c-format
msgid ""
"substr: length %g at start index %g exceeds length of first argument (%lu)"
@@ -763,228 +758,1127 @@ msgstr ""
"substr: pituus %g alkuindeksissä %g ylittää ensimmäisen argumentin pituuden "
"(%lu)"
-#: builtin.c:1655
+#: builtin.c:1900
msgid "strftime: format value in PROCINFO[\"strftime\"] has numeric type"
msgstr ""
"strftime: muotoarvolla kohteessa PROCINFO[\"strftime\"] on numerotyyppi"
-#: builtin.c:1678
+#: builtin.c:1923
msgid "strftime: received non-numeric second argument"
msgstr "strftime: toinen vastaanotettu argumentti ei ole numeerinen"
-#: builtin.c:1681
+#: builtin.c:1927
msgid "strftime: second argument less than 0 or too big for time_t"
msgstr ""
+"strftime: toinen argumentti on pienempi kuin 0 tai liian suuri time_t-"
+"rakenteeseen"
-#: builtin.c:1687
+#: builtin.c:1934
msgid "strftime: received non-string first argument"
msgstr "strftime: ensimmäinen vastaanotettu argumentti ei ole merkkijono"
-#: builtin.c:1693
+#: builtin.c:1941
msgid "strftime: received empty format string"
msgstr "strftime: vastaanotettu tyhjä muotomerkkijono"
-#: builtin.c:1759
+#: builtin.c:2007
msgid "mktime: received non-string argument"
msgstr "mktime: vastaanotettu argumentti ei ole merkkijono"
-#: builtin.c:1776
+#: builtin.c:2024
msgid "mktime: at least one of the values is out of the default range"
msgstr "mktime: vähintään yksi arvoista on oletuslukualueen ulkopuolella"
-#: builtin.c:1811
+#: builtin.c:2059
msgid "'system' function not allowed in sandbox mode"
-msgstr "â€systemâ€-funktio ei ole sallittu hiekkalaatikkotilassa"
+msgstr "’system’-funktio ei ole sallittu hiekkalaatikkotilassa"
-#: builtin.c:1816
+#: builtin.c:2064
msgid "system: received non-string argument"
msgstr "system: vastaanotettu argumentti ei ole merkkijono"
-#: builtin.c:1871 eval.c:1159 eval.c:1790 eval.c:1803
-#, c-format
-msgid "reference to uninitialized variable `%s'"
-msgstr "viite alustamattomaan muuttujaan â€%sâ€"
-
-#: builtin.c:1938
+#: builtin.c:2184
#, c-format
msgid "reference to uninitialized field `$%d'"
msgstr "viite alustamattomaan kenttään â€$%dâ€"
-#: builtin.c:2025
+#: builtin.c:2271
msgid "tolower: received non-string argument"
msgstr "tolower: vastaanotettu argumentti ei ole merkkijono"
-#: builtin.c:2059
+#: builtin.c:2305
msgid "toupper: received non-string argument"
msgstr "toupper: vastaanotettu argumentti ei ole merkkijono"
-#: builtin.c:2095
+#: builtin.c:2341 mpfr.c:672
msgid "atan2: received non-numeric first argument"
msgstr "atan2: ensimmäinen vastaanotettu argumentti ei ole numeerinen"
-#: builtin.c:2097
+#: builtin.c:2343 mpfr.c:674
msgid "atan2: received non-numeric second argument"
msgstr "atan2: toinen vastaanotettu argumentti ei ole numeerinen"
-#: builtin.c:2116
+#: builtin.c:2362
msgid "sin: received non-numeric argument"
msgstr "sin: vastaanotettu argumentti ei ole numeerinen"
-#: builtin.c:2132
+#: builtin.c:2378
msgid "cos: received non-numeric argument"
msgstr "cos: vastaanotettu argumentti ei ole numeerinen"
-#: builtin.c:2185
+#: builtin.c:2431 mpfr.c:1156
msgid "srand: received non-numeric argument"
msgstr "srand: vastaanotettu argumentti ei ole numeerinen"
-#: builtin.c:2216
+#: builtin.c:2462
msgid "match: third argument is not an array"
msgstr "match: kolmas argumentti ei ole taulukko"
-#: builtin.c:2480
+#: builtin.c:2734
msgid "gensub: third argument of 0 treated as 1"
msgstr "gensub: 0-arvoinen kolmas argumentti käsitellään kuin 1"
-#: builtin.c:2773
+#: builtin.c:3030
msgid "lshift: received non-numeric first argument"
msgstr "lshift: ensimmäinen vastaanotettu argumentti ei ole numeerinen"
-#: builtin.c:2775
+#: builtin.c:3032
msgid "lshift: received non-numeric second argument"
msgstr "lshift: toinen vastaanotettu argumentti ei ole numeerinen"
-#: builtin.c:2781
+#: builtin.c:3038
#, c-format
-msgid "lshift(%lf, %lf): negative values will give strange results"
-msgstr "lshift(%lf, %lf): negatiiviset arvot antavat outoja tuloksia"
+msgid "lshift(%f, %f): negative values will give strange results"
+msgstr "lshift(%f, %f): negatiiviset arvot antavat outoja tuloksia"
-#: builtin.c:2783
+#: builtin.c:3040
#, c-format
-msgid "lshift(%lf, %lf): fractional values will be truncated"
-msgstr "lshift(%lf, %lf): jaosarvot typistetään"
+msgid "lshift(%f, %f): fractional values will be truncated"
+msgstr "lshift(%f, %f): jaosarvot typistetään"
-#: builtin.c:2785
+#: builtin.c:3042
#, c-format
-msgid "lshift(%lf, %lf): too large shift value will give strange results"
-msgstr "lshift(%lf, %lf): liian suuri siirrosarvo antaa outoja tuloksia"
+msgid "lshift(%f, %f): too large shift value will give strange results"
+msgstr "lshift(%f, %f): liian suuri siirrosarvo antaa outoja tuloksia"
-#: builtin.c:2810
+#: builtin.c:3067
msgid "rshift: received non-numeric first argument"
msgstr "rshift: ensimmäinen vastaanotettu argumentti ei ole numeerinen"
-#: builtin.c:2812
+#: builtin.c:3069
msgid "rshift: received non-numeric second argument"
msgstr "rshift: toinen vastaanotettu argumentti ei ole numeerinen"
-#: builtin.c:2818
+#: builtin.c:3075
#, c-format
-msgid "rshift(%lf, %lf): negative values will give strange results"
-msgstr "rshift(%lf, %lf): negatiiviset arvot antavat outoja tuloksia"
+msgid "rshift(%f, %f): negative values will give strange results"
+msgstr "rshift(%f, %f): negatiiviset arvot antavat outoja tuloksia"
-#: builtin.c:2820
+#: builtin.c:3077
#, c-format
-msgid "rshift(%lf, %lf): fractional values will be truncated"
-msgstr "rshift(%lf, %lf): jaosarvot typistetään"
+msgid "rshift(%f, %f): fractional values will be truncated"
+msgstr "rshift(%f, %f): jaosarvot typistetään"
-#: builtin.c:2822
+#: builtin.c:3079
#, c-format
-msgid "rshift(%lf, %lf): too large shift value will give strange results"
-msgstr "rshift(%lf, %lf): liian suuri siirrosarvo antaa outoja tuloksia"
+msgid "rshift(%f, %f): too large shift value will give strange results"
+msgstr "rshift(%f, %f): liian suuri siirrosarvo antaa outoja tuloksia"
-#: builtin.c:2847
-msgid "and: received non-numeric first argument"
-msgstr "and: ensimmäinen vastaanotettu argumentti ei ole numeerinen"
+#: builtin.c:3104 mpfr.c:968
+msgid "and: called with less than two arguments"
+msgstr "and: kutsuttu vähemmällä kuin kahdella argumentilla"
-#: builtin.c:2849
-msgid "and: received non-numeric second argument"
-msgstr "and: toinen vastaanotettu argumentti ei ole numeerinen"
-
-#: builtin.c:2855
+#: builtin.c:3109
#, c-format
-msgid "and(%lf, %lf): negative values will give strange results"
-msgstr "and(%lf, %lf): negatiiviset arvot antavat outoja tuloksia"
+msgid "and: argument %d is non-numeric"
+msgstr "and: argumentti %d ei ole numeeraaliargumentti"
-#: builtin.c:2857
+#: builtin.c:3113
#, c-format
-msgid "and(%lf, %lf): fractional values will be truncated"
-msgstr "and(%lf, %lf): jaosarvot typistetään"
-
-#: builtin.c:2882
-msgid "or: received non-numeric first argument"
-msgstr "or: ensimmäinen vastaanotettu argumentti ei ole numeerinen"
+msgid "and: argument %d negative value %g will give strange results"
+msgstr "and: argumentin %d negatiivinen arvo %g antaa outoja tuloksia"
-#: builtin.c:2884
-msgid "or: received non-numeric second argument"
-msgstr "or: toinen vastaanotettu argumentti ei ole numeerinen"
+#: builtin.c:3136 mpfr.c:1000
+msgid "or: called with less than two arguments"
+msgstr "or: kutsuttu vähemmällä kuin kahdella argumentilla"
-#: builtin.c:2890
+#: builtin.c:3141
#, c-format
-msgid "or(%lf, %lf): negative values will give strange results"
-msgstr "or(%lf, %lf): negatiiviset arvot antavat outoja tuloksia"
+msgid "or: argument %d is non-numeric"
+msgstr "or: argumentti %d ei ole numeraaliargumentti"
-#: builtin.c:2892
+#: builtin.c:3145
#, c-format
-msgid "or(%lf, %lf): fractional values will be truncated"
-msgstr "or(%lf, %lf): jaosarvot typistetään"
+msgid "or: argument %d negative value %g will give strange results"
+msgstr "or: argumentin %d negatiivinen arvo %g antaa outoja tuloksia"
-#: builtin.c:2920
-msgid "xor: received non-numeric first argument"
-msgstr "xor: ensimmäinen vastaanotettu argumentti ei ole numeerinen"
+#: builtin.c:3167 mpfr.c:1031
+msgid "xor: called with less than two arguments"
+msgstr "xor: kutsuttu vähemmällä kuin kahdella argumentilla"
-#: builtin.c:2922
-msgid "xor: received non-numeric second argument"
-msgstr "xor: toinen vastaanotettu argumentti ei ole numeerinen"
-
-#: builtin.c:2928
+#: builtin.c:3173
#, c-format
-msgid "xor(%lf, %lf): negative values will give strange results"
-msgstr "xor(%lf, %lf): negatiiviset arvot antavat outoja tuloksia"
+msgid "xor: argument %d is non-numeric"
+msgstr "xor: argumentti %d ei ole numeraaliargumentti"
-#: builtin.c:2930
+#: builtin.c:3177
#, c-format
-msgid "xor(%lf, %lf): fractional values will be truncated"
-msgstr "xor(%lf, %lf): jaosarvot typistetään"
+msgid "xor: argument %d negative value %g will give strange results"
+msgstr "xor: argumentin %d negatiivinen arvo %g antaa outoja tuloksia"
-#: builtin.c:2954 builtin.c:2960
+#: builtin.c:3202 mpfr.c:787
msgid "compl: received non-numeric argument"
msgstr "compl: vastaanotettu argumentti ei ole numeerinen"
-#: builtin.c:2962
+#: builtin.c:3208
#, c-format
-msgid "compl(%lf): negative value will give strange results"
-msgstr "compl(%lf): negatiiviset arvot antavat outoja tuloksia"
+msgid "compl(%f): negative value will give strange results"
+msgstr "compl(%f): negatiivinen arvo antaa outoja tuloksia"
-#: builtin.c:2964
+#: builtin.c:3210
#, c-format
-msgid "compl(%lf): fractional value will be truncated"
-msgstr "compl(%lf): jaosarvo typistetään"
+msgid "compl(%f): fractional value will be truncated"
+msgstr "compl(%f): jaosarvo typistetään"
-#: builtin.c:3133
+#: builtin.c:3379
#, c-format
msgid "dcgettext: `%s' is not a valid locale category"
msgstr "dcgettext: â€%s†ei ole kelvollinen paikallinen kategoria"
-#: eval.c:412
+#: command.y:225
+#, c-format
+msgid "Type (g)awk statement(s). End with the command \"end\"\n"
+msgstr "Kirjoita (g)awk-lause(et). Lopeta komennolla \"end\"\n"
+
+#: command.y:289
+#, c-format
+msgid "invalid frame number: %d"
+msgstr "virheellinen kehysnumero: %d"
+
+#: command.y:295
+#, c-format
+msgid "info: invalid option - \"%s\""
+msgstr "info: virheellinen valitsin -- â€%sâ€"
+
+#: command.y:321
+#, c-format
+msgid "source \"%s\": already sourced."
+msgstr "source â€%sâ€: on jo merkitty lähteeksi."
+
+#: command.y:326
+#, c-format
+msgid "save \"%s\": command not permitted."
+msgstr "save â€%sâ€: komento ei ole sallittu."
+
+#: command.y:339
+msgid "Can't use command `commands' for breakpoint/watchpoint commands"
+msgstr ""
+"Komennon â€commands†käyttö breakpoint/watchpoint-komentoja varten epäonnistui"
+
+#: command.y:341
+msgid "no breakpoint/watchpoint has been set yet"
+msgstr "yhtään breakpoint/watchpoint -kohdetta ei ole vielä asetettu"
+
+#: command.y:343
+msgid "invalid breakpoint/watchpoint number"
+msgstr "virheellinen breakpoint/watchpoint-numero"
+
+#: command.y:348
+#, c-format
+msgid "Type commands for when %s %d is hit, one per line.\n"
+msgstr "Kirjoita komennot, kun %s %d osui, yksi per rivi.\n"
+
+#: command.y:350
+#, c-format
+msgid "End with the command \"end\"\n"
+msgstr "Lopeta komennolla â€endâ€\n"
+
+#: command.y:357
+msgid "`end' valid only in command `commands' or `eval'"
+msgstr "â€end†on kelvollinen vain komennoissa â€commands†tai â€evalâ€"
+
+#: command.y:367
+msgid "`silent' valid only in command `commands'"
+msgstr "â€silent†on kelvollinen vain komennossa â€commandsâ€"
+
+#: command.y:373
+#, c-format
+msgid "trace: invalid option - \"%s\""
+msgstr "trace: virheellinen valitsin -- â€%sâ€"
+
+#: command.y:387
+msgid "condition: invalid breakpoint/watchpoint number"
+msgstr "condition: virheellinen breakpoint/watchpoint-numero"
+
+#: command.y:449
+msgid "argument not a string"
+msgstr "argumentti ei ole merkkijono"
+
+#: command.y:459 command.y:464
+#, c-format
+msgid "option: invalid parameter - \"%s\""
+msgstr "option: virheellinen parametri - â€%sâ€"
+
+#: command.y:474
+#, c-format
+msgid "no such function - \"%s\""
+msgstr "tuntematon funktio - â€%sâ€"
+
+#: command.y:531
+#, c-format
+msgid "enable: invalid option - \"%s\""
+msgstr "enable: virheellinen valitsin -- â€%sâ€"
+
+#: command.y:597
+#, c-format
+msgid "invalid range specification: %d - %d"
+msgstr "virheellinen lukualuemäärittely: %d - %d"
+
+#: command.y:659
+msgid "non-numeric value for field number"
+msgstr "ei-numeerinen arvo kenttänumerolle"
+
+#: command.y:680 command.y:687
+msgid "non-numeric value found, numeric expected"
+msgstr "löytyi ei-numeerinen arvo, odotettiin numeraalia"
+
+#: command.y:712 command.y:718
+msgid "non-zero integer value"
+msgstr "nollasta poikkeava kokonaislukuarvo"
+
+#: command.y:817
+msgid ""
+"backtrace [N] - print trace of all or N innermost (outermost if N < 0) "
+"frames."
+msgstr ""
+"backtrace [N] - tulosta kaikkien tai N:n sisimmäisen (ulommaisin, jos N < 0) "
+"kehyksen jäljet."
+
+#: command.y:819
+msgid ""
+"break [[filename:]N|function] - set breakpoint at the specified location."
+msgstr ""
+"break [[filename:]N|function] - aseta breakpoint määriteltyyn sijaintiin."
+
+#: command.y:821
+msgid "clear [[filename:]N|function] - delete breakpoints previously set."
+msgstr ""
+"clear [[filename:]N|function] - poista aiemmin asetetut breakpoint-kohdat."
+
+#: command.y:823
+msgid ""
+"commands [num] - starts a list of commands to be executed at a "
+"breakpoint(watchpoint) hit."
+msgstr ""
+"commands [num] - aloittaa komentojen luettelon, joka suoritetaan "
+"keskeytyskohta(watchpoint)osumassa."
+
+#: command.y:825
+msgid "condition num [expr] - set or clear breakpoint or watchpoint condition."
+msgstr ""
+"condition num [expr] - aseta tai nollaa keskeytyskohta- tai vahtikohtaehdot."
+
+#: command.y:827
+msgid "continue [COUNT] - continue program being debugged."
+msgstr "continue [COUNT] - continue program being debugged."
+
+#: command.y:829
+msgid "delete [breakpoints] [range] - delete specified breakpoints."
+msgstr ""
+"delete [keskeytyskohdat] [lukualue] - poista määritellyt keskeytyskohdat."
+
+#: command.y:831
+msgid "disable [breakpoints] [range] - disable specified breakpoints."
+msgstr ""
+"disable [keskeytyskohdat] [lukualue] - ota pois käytöstä määritellyt "
+"keskeytyskohdat."
+
+#: command.y:833
+msgid "display [var] - print value of variable each time the program stops."
+msgstr ""
+"display [muuttuja] - tulosta muuttujan arvo joka kerta kun ohjelma pysähtyy."
+
+#: command.y:835
+msgid "down [N] - move N frames down the stack."
+msgstr "down [N] - siirrä N kehystä alaspäin pinossa."
+
+#: command.y:837
+msgid "dump [filename] - dump instructions to file or stdout."
+msgstr "dump [tiedostonimi] - vedosta käskyt tiedostoon tai vakiotulosteeseen."
+
+#: command.y:839
+msgid "enable [once|del] [breakpoints] [range] - enable specified breakpoints."
+msgstr ""
+"enable [once|del] [keskeytyskohdat] [lukualue] - ota käyttöön määritellyt "
+"keskeytyskohdat."
+
+#: command.y:841
+msgid "end - end a list of commands or awk statements."
+msgstr "end - lopeta komentojen tai awk-lauseiden luottelo."
+
+#: command.y:843
+msgid "eval stmt|[p1, p2, ...] - evaluate awk statement(s)."
+msgstr "eval stmt|[p1, p2, ...] - evaloi awk-lauseet."
+
+#: command.y:845
+msgid "finish - execute until selected stack frame returns."
+msgstr "finish - suorita kunnes palautetaan valittu pinokehys."
+
+#: command.y:847
+msgid "frame [N] - select and print stack frame number N."
+msgstr "frame [N] - valitse ja tulosta pinokehys numero N."
+
+#: command.y:849
+msgid "help [command] - print list of commands or explanation of command."
+msgstr "help [komento] - tulosta komentoluettelo tai komennon selitys."
+
+#: command.y:851
+msgid "ignore N COUNT - set ignore-count of breakpoint number N to COUNT."
+msgstr ""
+"ignore N COUNT - aseta keskeytyskohdan ignore-count numero N arvoon COUNT."
+
+#: command.y:853
+msgid ""
+"info topic - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch."
+msgstr ""
+"info aihe - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch."
+
+#: command.y:855
+msgid "list [-|+|[filename:]lineno|function|range] - list specified line(s)."
+msgstr ""
+"list [-|+|[tiedostonimi:]rivinumero|funktio|lukualue] - luettele määritellyt "
+"rivit."
+
+#: command.y:857
+msgid "next [COUNT] - step program, proceeding through subroutine calls."
+msgstr "next [COUNT] - askella ohjelmaa, etene alirutiinikutsujen kautta."
+
+#: command.y:859
+msgid ""
+"nexti [COUNT] - step one instruction, but proceed through subroutine calls."
+msgstr ""
+"nexti [COUNT] - askella yksi käsky, mutta etene alirutiinikutsujen kautta."
+
+#: command.y:861
+msgid "option [name[=value]] - set or display debugger option(s)."
+msgstr "option [nimi[=arvo]] - aseta tai näytä vianjäljittäjävalitsimet."
+
+#: command.y:863
+msgid "print var [var] - print value of a variable or array."
+msgstr "print var [muuttuja] - tulosta muutujan tai taulukon arvo."
+
+#: command.y:865
+msgid "printf format, [arg], ... - formatted output."
+msgstr "printf muoto, [argumentti], ... - muotoiltu tuloste."
+
+#: command.y:867
+msgid "quit - exit debugger."
+msgstr "quit - poistu vianjäljittäjästä."
+
+#: command.y:869
+msgid "return [value] - make selected stack frame return to its caller."
+msgstr "return [arvo] - tekee valitun pinokehyksen paluun sen kutsujalle."
+
+#: command.y:871
+msgid "run - start or restart executing program."
+msgstr "run - käynnistä tai uudelleenkäynnistä ohjelman suoritus."
+
+#: command.y:874
+msgid "save filename - save commands from the session to file."
+msgstr "save tiedostonimi - tallenna komennot istunnosta tiedostoon."
+
+#: command.y:877
+msgid "set var = value - assign value to a scalar variable."
+msgstr "set var = arvo - liitä arvo skalaarimuuttujaan."
+
+#: command.y:879
+msgid ""
+"silent - suspends usual message when stopped at a breakpoint/watchpoint."
+msgstr ""
+"silent - pysäyttää tavallisen viestin kun pysähdytään katkaisukohdassa/"
+"vahtipisteessä."
+
+#: command.y:881
+msgid "source file - execute commands from file."
+msgstr "source file - suorita komennot tiedostosta."
+
+#: command.y:883
+msgid "step [COUNT] - step program until it reaches a different source line."
+msgstr ""
+"step [COUNT] - askella ohjelmaa, kunnes se saavuttaa eri lähdekoodirivin."
+
+#: command.y:885
+msgid "stepi [COUNT] - step one instruction exactly."
+msgstr "stepi [COUNT] - askella tarkalleen yksi käsky."
+
+#: command.y:887
+msgid "tbreak [[filename:]N|function] - set a temporary breakpoint."
+msgstr "tbreak [[tiedostonimi:]N|funktio] - aseta tilapäinen keskeytyskohta."
+
+#: command.y:889
+msgid "trace on|off - print instruction before executing."
+msgstr "trace on|off - tulosta käsky ennen suoritusta."
+
+#: command.y:891
+msgid "undisplay [N] - remove variable(s) from automatic display list."
+msgstr "undisplay [N] - poista muuttuja(t) automaattisesta näyttöluettelosta."
+
+#: command.y:893
+msgid ""
+"until [[filename:]N|function] - execute until program reaches a different "
+"line or line N within current frame."
+msgstr ""
+"until [[tiedostonimi:]N|funktio] - suorita kunnes ohjelma tavoittaa eri "
+"rivin tai rivin N nykyisen kehyksen sisällä."
+
+#: command.y:895
+msgid "unwatch [N] - remove variable(s) from watch list."
+msgstr "unwatch [N] - poista muuttuja(t) vahtiluettelosta."
+
+#: command.y:897
+msgid "up [N] - move N frames up the stack."
+msgstr "up [N] - siirrä N kehystä ylöspäin pinossa."
+
+#: command.y:899
+msgid "watch var - set a watchpoint for a variable."
+msgstr "watch muuttuja - aseta vahtikohta muuttujalle."
+
+#: command.y:1011 debug.c:401 msg.c:135
+#, c-format
+msgid "error: "
+msgstr "virhe: "
+
+#: command.y:1051
+#, c-format
+msgid "can't read command (%s)\n"
+msgstr "komennon (%s) lukeminen epäonnistui\n"
+
+#: command.y:1065
+#, c-format
+msgid "can't read command (%s)"
+msgstr "komennon (%s) lukeminen epäonnistui"
+
+#: command.y:1116
+msgid "invalid character in command"
+msgstr "virheellinen merkki komennossa"
+
+#: command.y:1152
+#, c-format
+msgid "unknown command - \"%.*s\", try help"
+msgstr "tuntematon komento - \"%.*s\", kokeile käskyä help"
+
+#: command.y:1222
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: command.y:1284
+msgid "invalid character"
+msgstr "virheellinen merkki"
+
+#: command.y:1455
+#, c-format
+msgid "undefined command: %s\n"
+msgstr "määrittelemätön komento: %s\n"
+
+#: debug.c:252
+msgid "set or show the number of lines to keep in history file."
+msgstr "aseta tai näytä historiatiedostossa säilytettävien rivien lukumäärä."
+
+#: debug.c:254
+msgid "set or show the list command window size."
+msgstr "aseta tai näytä luettelokomentoikkunan koko."
+
+#: debug.c:256
+msgid "set or show gawk output file."
+msgstr "aseta tai näytä gawk-tulostetiedosto."
+
+#: debug.c:258
+msgid "set or show debugger prompt."
+msgstr "aseta tai näytä vianjäljittäjäkehote."
+
+#: debug.c:260
+msgid "(un)set or show saving of command history (value=on|off)."
+msgstr ""
+"aseta, poista asetus tai näytä komentohistoriatallennus (value=on|off)."
+
+#: debug.c:262
+msgid "(un)set or show saving of options (value=on|off)."
+msgstr "aseta, poista asetus tai näytä valitsintallennus (value=on|off)."
+
+#: debug.c:264
+msgid "(un)set or show instruction tracing (value=on|off)."
+msgstr "aseta, poista asetus tai näytä käskyjäljitys (value=on|off)."
+
+#: debug.c:345
+msgid "program not running."
+msgstr "ohjelma ei ole käynnissä."
+
+#: debug.c:448 debug.c:606
+#, c-format
+msgid "can't read source file `%s' (%s)"
+msgstr "lähdetiedoston â€%s†(%s) lukeminen epäonnistui"
+
+#: debug.c:453
+#, c-format
+msgid "source file `%s' is empty.\n"
+msgstr "lähdetiedosto â€%s†on tyhjä.\n"
+
+#: debug.c:480
+msgid "no current source file."
+msgstr "ei nykyistä lähdekooditiedostoa."
+
+#: debug.c:505
+#, c-format
+msgid "cannot find source file named `%s' (%s)"
+msgstr "lähdetiedostoa nimeltä â€%s†(%s) ei kyetä lukemaan"
+
+#: debug.c:529
+#, c-format
+msgid "WARNING: source file `%s' modified since program compilation.\n"
+msgstr ""
+"VAROITUS: lähdekooditiedostoa â€%s†on muokattu ohjelman kääntämisen "
+"jälkeen.\n"
+
+#: debug.c:551
+#, c-format
+msgid "line number %d out of range; `%s' has %d lines"
+msgstr "rivinumero %d lukualueen ulkopuolella; kohteessa â€%s†on %d riviä"
+
+#: debug.c:611
+#, c-format
+msgid "unexpected eof while reading file `%s', line %d"
+msgstr ""
+"odottamaton eof-tiedostonloppumerkki luettaessa tiedostoa â€%sâ€, rivi %d"
+
+#: debug.c:620
+#, c-format
+msgid "source file `%s' modified since start of program execution"
+msgstr ""
+"lähdekooditiedostoa â€%s†on muokattu ohjelman suorituksen aloituksen jälkeen"
+
+#: debug.c:732
+#, c-format
+msgid "Current source file: %s\n"
+msgstr "Nykyinen lähdetiedosto: %s\n"
+
+#: debug.c:733
+#, c-format
+msgid "Number of lines: %d\n"
+msgstr "Rivien lukumäärä: %d\n"
+
+#: debug.c:740
+#, c-format
+msgid "Source file (lines): %s (%d)\n"
+msgstr "Lähdetiedosto (riviä): %s (%d)\n"
+
+#: debug.c:754
+msgid ""
+"Number Disp Enabled Location\n"
+"\n"
+msgstr ""
+"Numero Disp Käytössä Sijainti\n"
+"\n"
+
+#: debug.c:765
+#, c-format
+msgid "\tno of hits = %ld\n"
+msgstr "\tosumien lukumäärä = %ld\n"
+
+#: debug.c:767
+#, c-format
+msgid "\tignore next %ld hit(s)\n"
+msgstr "\tohita seuraavat %ld osumaa\n"
+
+#: debug.c:769 debug.c:909
+#, c-format
+msgid "\tstop condition: %s\n"
+msgstr "\tpysähtymisehto: %s\n"
+
+#: debug.c:771 debug.c:911
+msgid "\tcommands:\n"
+msgstr "\tkomennot:\n"
+
+#: debug.c:793
+#, c-format
+msgid "Current frame: "
+msgstr "Nykyinen kehys: "
+
+#: debug.c:796
+#, c-format
+msgid "Called by frame: "
+msgstr "Kehyksen kutsuma: "
+
+#: debug.c:800
+#, c-format
+msgid "Caller of frame: "
+msgstr "Kehyksen kutsuja: "
+
+#: debug.c:818
+#, c-format
+msgid "None in main().\n"
+msgstr "Funktiossa main() ei ole mitään.\n"
+
+#: debug.c:848
+msgid "No arguments.\n"
+msgstr "Ei argumentteja.\n"
+
+#: debug.c:849
+msgid "No locals.\n"
+msgstr "Ei paikallisia muuttujia.\n"
+
+#: debug.c:857
+msgid ""
+"All defined variables:\n"
+"\n"
+msgstr ""
+"Kaikki määritellyt muuttujat:\n"
+"\n"
+
+#: debug.c:867
+msgid ""
+"All defined functions:\n"
+"\n"
+msgstr ""
+"Kaikki määritellyt funktiot.\n"
+"\n"
+
+#: debug.c:886
+msgid ""
+"Auto-display variables:\n"
+"\n"
+msgstr ""
+"Automaattisesti näytettävät muuttujat:\n"
+"\n"
+
+#: debug.c:889
+msgid ""
+"Watch variables:\n"
+"\n"
+msgstr ""
+"Vahtimuuttujia:\n"
+"\n"
+
+#: debug.c:1029
+#, c-format
+msgid "no symbol `%s' in current context\n"
+msgstr "symbolia â€%s†ei löydy nykyisestä asiayhteydestä\n"
+
+#: debug.c:1041 debug.c:1427
+#, c-format
+msgid "`%s' is not an array\n"
+msgstr "â€%s†ei ole taulukko\n"
+
+#: debug.c:1055
+#, c-format
+msgid "$%ld = uninitialized field\n"
+msgstr "$%ld = alustamaton kenttä\n"
+
+#: debug.c:1076
+#, c-format
+msgid "array `%s' is empty\n"
+msgstr "taulukko â€%s†on tyhjä\n"
+
+#: debug.c:1119 debug.c:1171
+#, c-format
+msgid "[\"%s\"] not in array `%s'\n"
+msgstr "[â€%sâ€] ei ole taulukossa â€%sâ€\n"
+
+#: debug.c:1175
+#, c-format
+msgid "`%s[\"%s\"]' is not an array\n"
+msgstr "â€%s[\"%s\"]†ei ole taulukko\n"
+
+#: debug.c:1236 debug.c:4964
+#, c-format
+msgid "`%s' is not a scalar variable"
+msgstr "â€%s†ei ole skalaarimuuttuja"
+
+#: debug.c:1258 debug.c:4994
+#, c-format
+msgid "attempt to use array `%s[\"%s\"]' in a scalar context"
+msgstr "yritettiin käyttää taulukkoa â€%s[\"%s\"]†skalaarikontekstissa"
+
+#: debug.c:1280 debug.c:5005
+#, c-format
+msgid "attempt to use scalar `%s[\"%s\"]' as array"
+msgstr "yritettiin käyttää skalaaria â€%s[\"%s\"]†taulukkona"
+
+#: debug.c:1423
+#, c-format
+msgid "`%s' is a function"
+msgstr "â€%s†on funktio"
+
+#: debug.c:1465
+#, c-format
+msgid "watchpoint %d is unconditional\n"
+msgstr "watchpoint %d ei ole ehdollinen\n"
+
+#: debug.c:1499
+#, c-format
+msgid "No display item numbered %ld"
+msgstr "Yksikään näyttörivi ei ole numeroitu %ld"
+
+#: debug.c:1502
+#, c-format
+msgid "No watch item numbered %ld"
+msgstr "Yksikään vahtirivi ei ole numeroitu %ld"
+
+#: debug.c:1528
+#, c-format
+msgid "%d: [\"%s\"] not in array `%s'\n"
+msgstr "%d: [â€%sâ€] ei ole taulukossa â€%sâ€\n"
+
+#: debug.c:1767
+msgid "attempt to use scalar value as array"
+msgstr "yritettiin käyttää skalaariarvoa taulukkona"
+
+#: debug.c:1856
+#, c-format
+msgid "Watchpoint %d deleted because parameter is out of scope.\n"
+msgstr ""
+"Watchpoint %d poistettiin, koska parametri on lukualueen ulkopuolella.\n"
+
+#: debug.c:1867
+#, c-format
+msgid "Display %d deleted because parameter is out of scope.\n"
+msgstr "Display %d poistettiin, koska parametri on lukualueen ulkopuolella.\n"
+
+#: debug.c:1900
+#, c-format
+msgid " in file `%s', line %d\n"
+msgstr " tiedostossa â€%sâ€, rivi %d\n"
+
+#: debug.c:1921
+#, c-format
+msgid " at `%s':%d"
+msgstr " osoitteessa â€%sâ€:%d"
+
+#: debug.c:1937 debug.c:2000
+#, c-format
+msgid "#%ld\tin "
+msgstr "#%ld\tkohteessa "
+
+#: debug.c:1974
+#, c-format
+msgid "More stack frames follow ...\n"
+msgstr "Lisää pinokehyksiä seuraa ...\n"
+
+#: debug.c:2017
+msgid "invalid frame number"
+msgstr "virheellinen kehysnumero"
+
+#: debug.c:2200
+#, c-format
+msgid "Note: breakpoint %d (enabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+"Huomaa: keskeytyskohta %d (otettu käyttöön, ohita seuraavat %ld osumaa), "
+"asetettu myös osoitteessa %s:%d"
+
+#: debug.c:2207
+#, c-format
+msgid "Note: breakpoint %d (enabled), also set at %s:%d"
+msgstr ""
+"Huomaa: keskeytyskohta %d (otettu käyttöön), asetettu myös kohdassa %s:%d"
+
+#: debug.c:2214
+#, c-format
+msgid "Note: breakpoint %d (disabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+"Huomaa: keskeytyskohta %d (otettu pois käytöstä, ohita seuraavat %ld "
+"osumaa), asetettu myös kohdassa %s:%d"
+
+#: debug.c:2221
+#, c-format
+msgid "Note: breakpoint %d (disabled), also set at %s:%d"
+msgstr ""
+"Huomaa: keskeytyskohta %d (otettu pois käytöstä), asetettu myös kohdassa %s:"
+"%d"
+
+#: debug.c:2238
+#, c-format
+msgid "Breakpoint %d set at file `%s', line %d\n"
+msgstr "Keskeytyskohta %d asetettu tiedostossa â€%sâ€, rivi %d\n"
+
+#: debug.c:2340
+#, c-format
+msgid "Can't set breakpoint in file `%s'\n"
+msgstr "Keskeytyskohdan asetaminen tiedostossa â€%s†epäonnistui\n"
+
+#: debug.c:2369 debug.c:2492 debug.c:3350
+#, c-format
+msgid "line number %d in file `%s' out of range"
+msgstr "rivinumero %d tiedostossa â€%s†on lukualueen ulkopuolella"
+
+#: debug.c:2373
+#, c-format
+msgid "Can't find rule!!!\n"
+msgstr "Säännön löytäminen epäonnistui!!!\n"
+
+#: debug.c:2375
+#, c-format
+msgid "Can't set breakpoint at `%s':%d\n"
+msgstr "Keskeytykohdan asettaminen kohdassa â€%sâ€:%d epäonnistui\n"
+
+#: debug.c:2387
+#, c-format
+msgid "Can't set breakpoint in function `%s'\n"
+msgstr "Keskeytyskohdan asettaminen funktiossa â€%s†epäonnistui\n"
+
+#: debug.c:2403
+#, c-format
+msgid "breakpoint %d set at file `%s', line %d is unconditional\n"
+msgstr "keskeytyskohta %d asetettu tiedostossa â€%sâ€, rivi %d on ehdoton\n"
+
+#: debug.c:2508 debug.c:2530
+#, c-format
+msgid "Deleted breakpoint %d"
+msgstr "Poistettu keskeytyskohta %d"
+
+#: debug.c:2514
+#, c-format
+msgid "No breakpoint(s) at entry to function `%s'\n"
+msgstr "Ei keskeytyskohtaa funktion â€%s†sisääntulossa\n"
+
+#: debug.c:2541
+#, c-format
+msgid "No breakpoint at file `%s', line #%d\n"
+msgstr "Tiedostossa â€%s†ei ole keskeytyskohtaa, rivi #%d\n"
+
+#: debug.c:2596 debug.c:2637 debug.c:2657 debug.c:2700
+msgid "invalid breakpoint number"
+msgstr "virheellinen keskeytyskohtanumero"
+
+#: debug.c:2612
+msgid "Delete all breakpoints? (y or n) "
+msgstr "Poistetaanko kaikki keskeytyskohdata? (y tai n) "
+
+#: debug.c:2613 debug.c:2923 debug.c:2976
+msgid "y"
+msgstr "k"
+
+#: debug.c:2662
+#, c-format
+msgid "Will ignore next %ld crossing(s) of breakpoint %d.\n"
+msgstr "Keskeytyskohta %2$d:n seuraavat %1$ld risteystä ohitetaan.\n"
+
+#: debug.c:2666
+#, c-format
+msgid "Will stop next time breakpoint %d is reached.\n"
+msgstr "Pysähtyy seuraavalla kerralla kun keskeytyskohta %d saavutetaan.\n"
+
+#: debug.c:2783
+#, c-format
+msgid "Can only debug programs provided with the `-f' option.\n"
+msgstr ""
+"Vain ohjelmia, jotka tarjoavat valitsimen â€-fâ€, voidaan vikajäljittää.\n"
+
+#: debug.c:2908
+#, c-format
+msgid "Failed to restart debugger"
+msgstr "Vianjäljittäjän uudelleenkäynnistys epäonnistui"
+
+#: debug.c:2922
+msgid "Program already running. Restart from beginning (y/n)? "
+msgstr "Ohjelma on jo käynnissä. Käynnistetäänkö uudelleen alusta (y/n)? "
+
+#: debug.c:2926
+#, c-format
+msgid "Program not restarted\n"
+msgstr "Ohjelma ei käynnistynyt uudelleen\n"
+
+#: debug.c:2936
+#, c-format
+msgid "error: cannot restart, operation not allowed\n"
+msgstr "virhe: uudelleenkäynnistys epäonnistui, toiminto ei ole sallittu\n"
+
+#: debug.c:2942
+#, c-format
+msgid "error (%s): cannot restart, ignoring rest of the commands\n"
+msgstr ""
+"virhe (%s): uudelleenkäynnistys epäonnistui, loput komennot ohitetaan\n"
+
+#: debug.c:2950
+#, c-format
+msgid "Starting program: \n"
+msgstr "Käynnistetään ohjelma: \n"
+
+#: debug.c:2959
+#, c-format
+msgid "Program exited %s with exit value: %d\n"
+msgstr "Ohjelma päättyi %s päättymisarvolla: %d\n"
+
+#: debug.c:2975
+msgid "The program is running. Exit anyway (y/n)? "
+msgstr "Ohjelma on käynnissä. Poistutaanko silti (y/n)? "
+
+#: debug.c:3010
+#, c-format
+msgid "Not stopped at any breakpoint; argument ignored.\n"
+msgstr "Ei pysäytetty yhdessäkään keskeytyskohdassa; argumentti ohitetaan.\n"
+
+#: debug.c:3015
+#, c-format
+msgid "invalid breakpoint number %d."
+msgstr "virheellinen keskeytyskohtanumero %d."
+
+#: debug.c:3020
+#, c-format
+msgid "Will ignore next %ld crossings of breakpoint %d.\n"
+msgstr "Ohittaa seuraavat %ld keskeytyskohdan %d ylitystä.\n"
+
+#: debug.c:3207
+#, c-format
+msgid "'finish' not meaningful in the outermost frame main()\n"
+msgstr ""
+"’finish’ ei ole merkityksellinen ulommaisen kehyksen main()-funktiossa\n"
+
+#: debug.c:3212
+#, c-format
+msgid "Run till return from "
+msgstr "Suorita kunnes paluu kohteesta "
+
+#: debug.c:3255
+#, c-format
+msgid "'return' not meaningful in the outermost frame main()\n"
+msgstr ""
+"’return’ ei ole merkityksellinen ulommaisen kehyksen main()-funktiossa\n"
+
+#: debug.c:3369
+#, c-format
+msgid "Can't find specified location in function `%s'\n"
+msgstr "Määritellyn sijainnin löytyminen funktiossa â€%s†epäonnistui\n"
+
+#: debug.c:3377
+#, c-format
+msgid "invalid source line %d in file `%s'"
+msgstr "virheellinen lähdekoodirivi %d tiedostossa â€%sâ€"
+
+#: debug.c:3392
+#, c-format
+msgid "Can't find specified location %d in file `%s'\n"
+msgstr "Määritellyn sijainnin %d löytyminen tiedostossa â€%s†epäonnistui\n"
+
+#: debug.c:3424
+#, c-format
+msgid "element not in array\n"
+msgstr "elementti ei ole taulukossa\n"
+
+#: debug.c:3424
+#, c-format
+msgid "untyped variable\n"
+msgstr "tyypitön muuttuja\n"
+
+#: debug.c:3466
+#, c-format
+msgid "Stopping in %s ...\n"
+msgstr "Pysäytetään kohdassa %s ...\n"
+
+#: debug.c:3543
+#, c-format
+msgid "'finish' not meaningful with non-local jump '%s'\n"
+msgstr "’finish’ ei ole merkityksellinen ei-paikallisessa hypyssä ’%s’\n"
+
+#: debug.c:3550
+#, c-format
+msgid "'until' not meaningful with non-local jump '%s'\n"
+msgstr "’until’ ei ole merkityksellinen ei-paikallisessa hypyssä ’%s’\n"
+
+#: debug.c:4185
+msgid "\t------[Enter] to continue or q [Enter] to quit------"
+msgstr "\t------Jatka painamalla [Enter] tai poistu painamalla q [Enter]------"
+
+#: debug.c:4186
+msgid "q"
+msgstr "q"
+
+#: debug.c:5001
+#, c-format
+msgid "[\"%s\"] not in array `%s'"
+msgstr "[â€%sâ€] ei ole taulukossa â€%sâ€"
+
+#: debug.c:5207
+#, c-format
+msgid "sending output to stdout\n"
+msgstr "lähetetään tuloste vakiotulosteeseen\n"
+
+#: debug.c:5247
+msgid "invalid number"
+msgstr "virheellinen numero"
+
+#: debug.c:5381
+#, c-format
+msgid "`%s' not allowed in current context; statement ignored"
+msgstr "â€%s†ei ole sallittu nykyisessä asiayhteydessä; lause ohitetaan"
+
+#: debug.c:5389
+msgid "`return' not allowed in current context; statement ignored"
+msgstr "â€return†ei ole sallittu nykyisessä asiayhteydessä; lause ohitetaan"
+
+#: debug.c:5590
+#, c-format
+msgid "No symbol `%s' in current context"
+msgstr "Symbolia â€%s†ei ole nykyisesssä asiayhteydessä"
+
+#: dfa.c:1118 dfa.c:1121 dfa.c:1142 dfa.c:1150 dfa.c:1162 dfa.c:1197
+#: dfa.c:1206 dfa.c:1209 dfa.c:1214 dfa.c:1228 dfa.c:1275
+msgid "unbalanced ["
+msgstr "pariton ["
+
+#: dfa.c:1174
+msgid "invalid character class"
+msgstr "virheellinen merkkiluokka"
+
+#: dfa.c:1316
+msgid "character class syntax is [[:space:]], not [:space:]"
+msgstr "merkkiluokkasyntaksi on [[:space:]], ei [:space:]"
+
+#: dfa.c:1366
+msgid "unfinished \\ escape"
+msgstr "päättymätön \\-koodinvaihtomerkki"
+
+#: dfa.c:1513 regcomp.c:161
+msgid "Invalid content of \\{\\}"
+msgstr "Virheellinen \\{\\}-sisältö"
+
+#: dfa.c:1516 regcomp.c:176
+msgid "Regular expression too big"
+msgstr "Säännöllinen lauseke on liian iso"
+
+#: dfa.c:1936
+msgid "unbalanced ("
+msgstr "pariton ("
+
+#: dfa.c:2062
+msgid "no syntax specified"
+msgstr "syntaksi ei ole määritelty"
+
+#: dfa.c:2070
+msgid "unbalanced )"
+msgstr "pariton )"
+
+#: eval.c:394
#, c-format
msgid "unknown nodetype %d"
msgstr "tuntematon solmutyyppi %d"
-#: eval.c:423 eval.c:437
+#: eval.c:405 eval.c:419
#, c-format
msgid "unknown opcode %d"
msgstr "tuntematon käskykoodi %d"
-#: eval.c:434
+#: eval.c:416
#, c-format
msgid "opcode %s not an operator or keyword"
msgstr "käskykoodi %s ei ole operaattori tai avainsana"
-#: eval.c:488
+#: eval.c:472
msgid "buffer overflow in genflags2str"
msgstr "puskurin ylivuoto funktiossa genflags2str"
-#: eval.c:698
+#: eval.c:675
#, c-format
msgid ""
"\n"
@@ -995,824 +1889,1255 @@ msgstr ""
"\t# Funktiokutsupino:\n"
"\n"
-#: eval.c:725
+#: eval.c:704
msgid "`IGNORECASE' is a gawk extension"
msgstr "â€IGNORECASE†on gawk-laajennus"
-#: eval.c:754
+#: eval.c:736
msgid "`BINMODE' is a gawk extension"
msgstr "â€BINMODE†on gawk-laajennus"
-#: eval.c:812
+#: eval.c:794
#, c-format
msgid "BINMODE value `%s' is invalid, treated as 3"
msgstr "BINMODE-arvo â€%s†on virheellinen, käsiteltiin arvona 3"
-#: eval.c:902
+#: eval.c:885
#, c-format
msgid "bad `%sFMT' specification `%s'"
msgstr "väärä â€%sFMTâ€-määritys â€%sâ€"
-#: eval.c:980
+#: eval.c:969
msgid "turning off `--lint' due to assignment to `LINT'"
msgstr "käännetään pois â€--lintâ€-valitsin â€LINTâ€-sijoituksen vuoksi"
-#: eval.c:1127 eval.c:1777
-#, c-format
-msgid "can't use function name `%s' as variable or array"
-msgstr "funktionimeä â€%s†ei voi käyttää muuttujana tai taulukkona"
-
-#: eval.c:1158 eval.c:1789 eval.c:1802
+#: eval.c:1147
#, c-format
msgid "reference to uninitialized argument `%s'"
msgstr "viite alustamattomaan argumenttiin â€%sâ€"
-#: eval.c:1177
+#: eval.c:1148
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "viite alustamattomaan muuttujaan â€%sâ€"
+
+#: eval.c:1166
msgid "attempt to field reference from non-numeric value"
msgstr "yritettiin kenttäviitettä arvosta, joka ei ole numeerinen"
-#: eval.c:1179
+#: eval.c:1168
msgid "attempt to field reference from null string"
msgstr "yritettiin kenttäviitettä null-merkkijonosta"
-#: eval.c:1185
+#: eval.c:1176
#, c-format
msgid "attempt to access field %ld"
msgstr "yritettiin saantia kenttään %ld"
-#: eval.c:1194
+#: eval.c:1185
#, c-format
msgid "reference to uninitialized field `$%ld'"
msgstr "viite alustamattomaan kenttään â€$%ldâ€"
-#: eval.c:1256
+#: eval.c:1272
#, c-format
msgid "function `%s' called with more arguments than declared"
msgstr "funktio â€%s†kutsuttiin useammalla argumentilla kuin esiteltiin"
-#: eval.c:1437
+#: eval.c:1473
#, c-format
msgid "unwind_stack: unexpected type `%s'"
msgstr "unwind_stack: odottamaton tyyppi â€%sâ€"
-#: eval.c:1532
+#: eval.c:1569
msgid "division by zero attempted in `/='"
msgstr "jakoa nollalla yritettiin operaatiossa â€/=â€"
-#: eval.c:1539
+#: eval.c:1576
#, c-format
msgid "division by zero attempted in `%%='"
msgstr "jakoa nollalla yritettiin operaatiossa â€%%=â€"
-#: eval.c:1876 eval.c:2122
-#, c-format
-msgid "attempt to use array `%s[\"%.*s\"]' in a scalar context"
-msgstr "yritettiin käyttää taulukkoa â€%s[\"%.*s\"]†skalaarikontekstissa"
+#: ext.c:89 ext.c:171
+msgid "extensions are not allowed in sandbox mode"
+msgstr "laajennuksia ei sallita hiekkalaatikkotilassa"
-#: eval.c:1907
-msgid "assignment used in conditional context"
-msgstr "sijoitusta käytetty ehdollisessa kontekstissa"
+#: ext.c:92
+msgid "-l / @load are gawk extensions"
+msgstr "-l / @load ovat gawk-laajennuksia"
-#: eval.c:1911
-msgid "statement has no effect"
-msgstr "käskyllä ei ole vaikutusta"
+#: ext.c:95
+msgid "load_ext: received NULL lib_name"
+msgstr "load_ext: vastaanotettiin NULL lib_name"
-#: eval.c:2343
+#: ext.c:98
#, c-format
-msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
-msgstr ""
-"for-silmukka: taulukon â€%s†koko muuttui arvosta %ld arvoon %ld silmukan "
-"suorituksen aikana"
+msgid "load_ext: cannot open library `%s' (%s)\n"
+msgstr "load_ext: kirjaston â€%s†(%s) avaus epäonnistui\n"
-#: eval.c:2458
+#: ext.c:104
#, c-format
-msgid "function called indirectly through `%s' does not exist"
-msgstr "kohteen â€%s†kautta epäsuorasti kutsuttu funktio ei ole olemassa"
+msgid ""
+"load_ext: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"
+msgstr ""
+"load_ext: kirjasto â€%sâ€: ei määrittele â€plugin_is_GPL_compatible†(%s)\n"
-#: eval.c:2470
+#: ext.c:110
#, c-format
-msgid "function `%s' not defined"
-msgstr "funktio â€%s†ei ole määritelty"
+msgid "load_ext: library `%s': cannot call function `%s' (%s)\n"
+msgstr "load_ext: kirjasto â€%sâ€: funktion â€%s†(%s) kutsu epäonnistui\n"
-#: eval.c:2511
+#: ext.c:114
#, c-format
-msgid "non-redirected `getline' invalid inside `%s' rule"
-msgstr "edelleenohjaamaton â€getline†virheellinen â€%sâ€-säännön sisällä"
+msgid "load_ext: library `%s' initialization routine `%s' failed\n"
+msgstr "load_ext: kirjaston â€%s†alustusrutiini â€%s†epäonnistui\n"
-#: eval.c:2600
-#, c-format
-msgid "error reading input file `%s': %s"
-msgstr "virhe luettaessa syötetiedostoa â€%sâ€: %s"
+#: ext.c:174
+msgid "`extension' is a gawk extension"
+msgstr "â€extension†on gawk-laajennus"
+
+#: ext.c:177
+msgid "extension: received NULL lib_name"
+msgstr "extension: vastaanotettiin NULL lib_name"
-#: eval.c:2614
+#: ext.c:180
#, c-format
-msgid "`nextfile' cannot be called from a `%s' rule"
-msgstr "â€nextfile†ei voida kutsua â€%sâ€-säännöstä"
+msgid "extension: cannot open library `%s' (%s)"
+msgstr "extension: kirjaston â€%s†(%s) avaus epäonnistui"
-#: eval.c:2694
+#: ext.c:186
#, c-format
-msgid "`next' cannot be called from a `%s' rule"
-msgstr "â€next†ei voida kutsua â€%sâ€-säännöstä"
+msgid ""
+"extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)"
+msgstr ""
+"extension: kirjasto â€%sâ€: ei määrittele â€plugin_is_GPL_compatible†(%s)"
-#: eval.c:2760
+#: ext.c:190
#, c-format
-msgid "Sorry, don't know how to interpret `%s'"
-msgstr "Ei osata tulkita kohdetta â€%sâ€"
+msgid "extension: library `%s': cannot call function `%s' (%s)"
+msgstr "extension: kirjasto â€%sâ€: funktion â€%s†(%s) kutsu epäonnistui"
-#: ext.c:64
-msgid "extensions are not allowed in sandbox mode"
-msgstr "laajennuksia ei sallita hiekkalaatikkotilassa"
+#: ext.c:221
+msgid "make_builtin: missing function name"
+msgstr "make_builtin: puuttuva funktionimi"
-#: ext.c:70 ext.c:75
-msgid "`extension' is a gawk extension"
-msgstr "â€extension†on gawk-laajennus"
+#: ext.c:236
+#, c-format
+msgid "make_builtin: can't redefine function `%s'"
+msgstr "make_builtin: funktion â€%s†uudelleenmäärittely epäonnistui"
-#: ext.c:85
+#: ext.c:240
#, c-format
-msgid "fatal: extension: cannot open `%s' (%s)\n"
-msgstr "tuhoisa: extension: ei voi avata solmua â€%s†(%s)\n"
+msgid "make_builtin: function `%s' already defined"
+msgstr "make_builtin: funktio â€%s†on jo määritelty"
-#: ext.c:94
+#: ext.c:244
#, c-format
-msgid ""
-"fatal: extension: library `%s': does not define "
-"`plugin_is_GPL_compatible' (%s)\n"
+msgid "make_builtin: function name `%s' previously defined"
+msgstr "make_builtin: funktionimi â€%s†on määritelty jo aiemmin"
+
+#: ext.c:246
+#, c-format
+msgid "make_builtin: can't use gawk built-in `%s' as function name"
msgstr ""
-"tuhoisa: extension: kirjasto â€%sâ€: ei määrittele "
-"â€plugin_is_GPL_compatible†(%s)\n"
+"make_builtin: gawk-ohjelman sisäisen muuttujanimen â€%s†käyttö funktionimenä "
+"epäonnistui"
-#: ext.c:103
+#: ext.c:249 ext.c:304
#, c-format
-msgid "fatal: extension: library `%s': cannot call function `%s' (%s)\n"
-msgstr "tuhoisa: extension: kirjasto â€%sâ€: ei voi kutsua funktiota â€%s†(%s)\n"
+msgid "make_builtin: negative argument count for function `%s'"
+msgstr "make_builtin: negatiivinen argumenttilukumäärä funktiolle â€%sâ€"
-#: ext.c:137
+#: ext.c:276
msgid "extension: missing function name"
msgstr "extension: puuttuva funktionimi"
-#: ext.c:142
+#: ext.c:279 ext.c:283
#, c-format
msgid "extension: illegal character `%c' in function name `%s'"
msgstr "extension: virheellinen merkki â€%c†funktionimessä â€%sâ€"
-#: ext.c:151
+#: ext.c:291
#, c-format
msgid "extension: can't redefine function `%s'"
-msgstr "extension: ei voi määritellä uudelleen funktiota â€%sâ€"
+msgstr "extension: funktion â€%s†uudelleenmäärittely epäonnistui"
-#: ext.c:155
+#: ext.c:295
#, c-format
msgid "extension: function `%s' already defined"
msgstr "extension: funktio â€%s†on jo määritelty"
-#: ext.c:160
+#: ext.c:299
#, c-format
msgid "extension: function name `%s' previously defined"
msgstr "extension: funktionimi â€%s†on määritelty jo aiemmin"
-#: ext.c:162
+#: ext.c:301
#, c-format
msgid "extension: can't use gawk built-in `%s' as function name"
msgstr ""
-"extension: ei voi käyttää gawk-ohjelman sisäistä muuttujanimeä â€%s†"
-"funktionimenä"
-
-#: ext.c:166
-#, c-format
-msgid "make_builtin: negative argument count for function `%s'"
-msgstr "make_builtin: negatiivinen argumenttilukumäärä funktiolle â€%sâ€"
+"extension: gawk-ohjelman sisäisen muuttujanimen käyttö â€%s†funktionimenä "
+"epäonnistui"
-#: ext.c:269
+#: ext.c:375
#, c-format
msgid "function `%s' defined to take no more than %d argument(s)"
msgstr "funktio â€%s†on määritelty ottamaan enemmän kuin %d argumenttia"
-#: ext.c:272
+#: ext.c:378
#, c-format
msgid "function `%s': missing argument #%d"
msgstr "function â€%sâ€: puuttuva argumentti #%d"
-#: ext.c:289
+#: ext.c:395
#, c-format
msgid "function `%s': argument #%d: attempt to use scalar as an array"
msgstr "funktio â€%sâ€: argumentti #%d: yritettiin käyttää skalaaria taulukkona"
-#: ext.c:293
+#: ext.c:399
#, c-format
msgid "function `%s': argument #%d: attempt to use array as a scalar"
msgstr "funktio â€%sâ€: argumentti #%d: yritettiin käyttää taulukkoa skalaarina"
-#: ext.c:306
-msgid "Operation Not Supported"
-msgstr "Toimintoa ei tueta"
+#: ext.c:413
+msgid "dynamic loading of library not supported"
+msgstr "kirjaston dynaamista latausta ei tueta"
+
+#: extension/filefuncs.c:159
+msgid "chdir: called with incorrect number of arguments, expecting 1"
+msgstr "chdir: kutsuttu argumenttien väärällä lukumäärällä, odotettiin 1"
+
+#: extension/filefuncs.c:439
+#, c-format
+msgid "stat: unable to read symbolic link `%s'"
+msgstr "stat: symbolisen linkin â€%s†lukeminen epäonnistui"
+
+#: extension/filefuncs.c:472
+msgid "stat: called with wrong number of arguments"
+msgstr "stat: kutsuttu argumenttien väärällä lukumäärällä"
+
+#: extension/filefuncs.c:479
+msgid "stat: bad parameters"
+msgstr "stat: väärät parametrit"
+
+#: extension/filefuncs.c:533
+#, c-format
+msgid "fts init: could not create variable %s"
+msgstr "fts init: muuttujan %s luominen epäonnistui"
+
+#: extension/filefuncs.c:554
+msgid "fts is not supported on this system"
+msgstr "fts ei ole tuettu tässä järjestelmässä"
+
+#: extension/filefuncs.c:573
+msgid "fill_stat_element: could not create array"
+msgstr "fill_stat_element: taulukon luominen epäonnistui"
+
+#: extension/filefuncs.c:582
+msgid "fill_stat_element: could not set element"
+msgstr "fill_stat_element: elementin asettaminen epäonnistui"
+
+#: extension/filefuncs.c:597
+msgid "fill_path_element: could not set element"
+msgstr "fill_path_element: elementin asettaminen epäonnistui"
+
+#: extension/filefuncs.c:613
+msgid "fill_error_element: could not set element"
+msgstr "fill_error_element: elementin asettaminen epäonnistui"
+
+#: extension/filefuncs.c:660 extension/filefuncs.c:707
+msgid "fts-process: could not create array"
+msgstr "fts-process: taulukon luominen epäonnistui"
+
+#: extension/filefuncs.c:670 extension/filefuncs.c:717
+#: extension/filefuncs.c:735
+msgid "fts-process: could not set element"
+msgstr "fts-process: elementin asettaminen epäonnistui"
+
+#: extension/filefuncs.c:784
+msgid "fts: called with incorrect number of arguments, expecting 3"
+msgstr "fts: kutsuttu argumenttien väärällä lukumäärällä, odotettiin 3"
+
+#: extension/filefuncs.c:787
+msgid "fts: bad first parameter"
+msgstr "fts: väärä ensimmäinen parametri"
+
+#: extension/filefuncs.c:793
+msgid "fts: bad second parameter"
+msgstr "fts: väärä toinen parametri"
+
+#: extension/filefuncs.c:799
+msgid "fts: bad third parameter"
+msgstr "fts: väärä kolmas parametri"
+
+#: extension/filefuncs.c:806
+msgid "fts: could not flatten array\n"
+msgstr "fts: taulukon litistäminen epäonnistui\n"
+
+#: extension/filefuncs.c:824
+msgid "fts: ignoring sneaky FTS_NOSTAT flag. nyah, nyah, nyah."
+msgstr "fts: ohitetaan petollinen FTS_NOSTAT-lippu. nyyh, nyyh, nyyh."
+
+#: extension/filefuncs.c:841
+msgid "fts: clear_array() failed\n"
+msgstr "fts: clear_array() epäonnistui\n"
+
+#: extension/fnmatch.c:112
+msgid "fnmatch: called with less than three arguments"
+msgstr "fnmatch: kutsuttu vähemmällä kuin kolmella argumentilla"
+
+#: extension/fnmatch.c:115
+msgid "fnmatch: called with more than three arguments"
+msgstr "fnmatch: kutsuttu useammalla kuin kolmella argumentilla"
+
+#: extension/fnmatch.c:118
+msgid "fnmatch: could not get first argument"
+msgstr "fnmatch: ensimmäistä argumenttia ei saatu"
+
+#: extension/fnmatch.c:123
+msgid "fnmatch: could not get second argument"
+msgstr "fnmatch: toista argumenttia ei saatu"
+
+#: extension/fnmatch.c:128
+msgid "fnmatch: could not get third argument"
+msgstr "fnmatch: kolmatta argumenttia ei saatu"
+
+#: extension/fnmatch.c:141
+msgid "fnmatch is not implemented on this system\n"
+msgstr "fnmatch ei ole toteutettu tässä järjestelmässä\n"
+
+#: extension/fnmatch.c:173
+msgid "fnmatch init: could not add FNM_NOMATCH variable"
+msgstr "fnmatch init: muuttujan FNM_NOMATCH lisääminen epäonnistui"
+
+#: extension/fnmatch.c:183
+#, c-format
+msgid "fnmatch init: could not set array element %s"
+msgstr "fnmatch init: taulukkoelementin %s asettaminen epäonnistui"
+
+#: extension/fnmatch.c:193
+msgid "fnmatch init: could not install FNM array"
+msgstr "fnmatch init: FNM-taulukon lisääminen epäonnistui"
+
+#: extension/fork.c:81
+msgid "fork: called with too many arguments"
+msgstr "fork: kutsuttu liian monella argumentilla"
+
+#: extension/fork.c:94
+msgid "fork: PROCINFO is not an array!"
+msgstr "fork: PROCINFO ei ole taulukko!"
+
+#: extension/fork.c:118
+msgid "waitpid: called with too many arguments"
+msgstr "waitpid: kutsuttu liian monella argumentilla"
+
+#: extension/fork.c:126
+msgid "wait: called with no arguments"
+msgstr "wait: kutsuttu ilman argumentteja"
+
+#: extension/fork.c:143
+msgid "wait: called with too many arguments"
+msgstr "wait: kutsuttu liian monella argumentilla"
+
+#: extension/inplace.c:130
+msgid "inplace_begin: in-place editing already active"
+msgstr "inplace_begin: kohdallaanmuokkaus on jo aktivoitu"
+
+#: extension/inplace.c:133 extension/inplace.c:207
+#, c-format
+msgid "inplace_begin: expects 2 arguments but called with %d"
+msgstr ""
+"inplace_begin: odotetaan 2 argumenttia, mutta kutsussa oli %d argumenttia"
+
+#: extension/inplace.c:136
+msgid "inplace_begin: cannot retrieve 1st argument as a string filename"
+msgstr ""
+"inplace_begin: ensimmäisen argumentin noutaminen merkkijonotiedostonimenä "
+"epäonnistui"
+
+#: extension/inplace.c:144
+#, c-format
+msgid "inplace_begin: disabling in-place editing for invalid FILENAME `%s'"
+msgstr ""
+"inplace_begin: ottaen pois käytöstä virheellisen TIEDOSTONIMI â€%s†"
+"muokkauksen"
+
+#: extension/inplace.c:151
+#, c-format
+msgid "inplace_begin: Cannot stat `%s' (%s)"
+msgstr "inplace_begin: stat â€%s†(%s) epäonnistui"
+
+#: extension/inplace.c:158
+#, c-format
+msgid "inplace_begin: `%s' is not a regular file"
+msgstr "inplace_begin: â€%s†ei ole tavallinen tiedosto"
+
+#: extension/inplace.c:169
+#, c-format
+msgid "inplace_begin: mkstemp(`%s') failed (%s)"
+msgstr "inplace_begin: mkstemp(â€%sâ€) epäonnistui (%s)"
+
+#: extension/inplace.c:178
+#, c-format
+msgid "inplace_begin: chmod failed (%s)"
+msgstr "inplace_begin: chmod epäonnistui (%s)"
+
+#: extension/inplace.c:185
+#, c-format
+msgid "inplace_begin: dup(stdout) failed (%s)"
+msgstr "inplace_begin: dup(stdout) epäonnistui (%s)"
+
+#: extension/inplace.c:188
+#, c-format
+msgid "inplace_begin: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_begin: dup2(%d, stdout) epäonnistui (%s)"
+
+#: extension/inplace.c:191
+#, c-format
+msgid "inplace_begin: close(%d) failed (%s)"
+msgstr "inplace_begin: close(%d) epäonnistui (%s)"
+
+#: extension/inplace.c:210
+msgid "inplace_end: cannot retrieve 1st argument as a string filename"
+msgstr ""
+"inplace_end: ensimmäisen argumentin noutaminen merkkijonotiedostonimenä "
+"epäonnistui"
+
+#: extension/inplace.c:217
+msgid "inplace_end: in-place editing not active"
+msgstr "inplace_end: kohdallaanmuokkaus ei ole aktiivinen"
+
+#: extension/inplace.c:223
+#, c-format
+msgid "inplace_end: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_end: dup2(%d, stdout) epäonnistui (%s)"
+
+#: extension/inplace.c:226
+#, c-format
+msgid "inplace_end: close(%d) failed (%s)"
+msgstr "inplace_end: close(%d) epäonnistui (%s)"
+
+#: extension/inplace.c:230
+#, c-format
+msgid "inplace_end: fsetpos(stdout) failed (%s)"
+msgstr "inplace_end: fsetpos(stdout) epäonnistui (%s)"
+
+#: extension/inplace.c:243
+#, c-format
+msgid "inplace_end: link(`%s', `%s') failed (%s)"
+msgstr "inplace_end: link(â€%sâ€, â€%sâ€) epäonnistui (%s)."
+
+#: extension/inplace.c:253
+#, c-format
+msgid "inplace_end: rename(`%s', `%s') failed (%s)"
+msgstr "inplace_end: rename(â€%sâ€, â€%sâ€) epäonnistui (%s)"
+
+#: extension/ordchr.c:69
+msgid "ord: called with too many arguments"
+msgstr "ord: kutsuttu liian monella argumentilla"
+
+#: extension/ordchr.c:75
+msgid "ord: called with no arguments"
+msgstr "ord: kutsuttu ilman argumentteja"
+
+#: extension/ordchr.c:77
+msgid "ord: called with inappropriate argument(s)"
+msgstr "ord: kutsuttu sopimattomalla argumentilla"
+
+#: extension/ordchr.c:99
+msgid "chr: called with too many arguments"
+msgstr "chr: kutsuttu liian monella argumentilla"
+
+#: extension/ordchr.c:109
+msgid "chr: called with no arguments"
+msgstr "chr: kutsuttu ilman argumentteja"
+
+#: extension/ordchr.c:111
+msgid "chr: called with inappropriate argument(s)"
+msgstr "chr: kutsuttu sopimattomalla argumentilla"
+
+#: extension/readdir.c:281
+#, c-format
+msgid "dir_take_control_of: opendir/fdopendir failed: %s"
+msgstr "dir_take_control_of: opendir/fdopendir epäonnistui: %s"
+
+#: extension/readfile.c:113
+msgid "readfile: called with too many arguments"
+msgstr "readfile: kutsuttu liian monella argumentilla"
+
+#: extension/readfile.c:137
+msgid "readfile: called with no arguments"
+msgstr "readfile: kutsuttu ilman argumentteja"
+
+#: extension/rwarray.c:124
+msgid "writea: called with too many arguments"
+msgstr "writea: kutsuttu liian monella argumentilla"
+
+#: extension/rwarray.c:131
+#, c-format
+msgid "do_writea: argument 0 is not a string\n"
+msgstr "do_writea: argumentti 0 ei ole merkkijono\n"
+
+#: extension/rwarray.c:137
+#, c-format
+msgid "do_writea: argument 1 is not an array\n"
+msgstr "do_writea: argumentti 1 ei ole taulukko\n"
+
+#: extension/rwarray.c:184
+#, c-format
+msgid "write_array: could not flatten array\n"
+msgstr "write_array: taulukon litistäminen epäonnistui\n"
+
+#: extension/rwarray.c:198
+#, c-format
+msgid "write_array: could not release flattened array\n"
+msgstr "write_array: litistettyä taulukon vapauttaminen epäonnistui\n"
+
+#: extension/rwarray.c:280
+msgid "reada: called with too many arguments"
+msgstr "reada: kutsuttu liian monilla argumenteilla"
+
+#: extension/rwarray.c:287
+#, c-format
+msgid "do_reada: argument 0 is not a string\n"
+msgstr "do_reada: argumentti 0 ei ole merkkijono\n"
+
+#: extension/rwarray.c:293
+#, c-format
+msgid "do_reada: argument 1 is not an array\n"
+msgstr "do_reada: argumentti 1 ei ole taulukko\n"
+
+#: extension/rwarray.c:337
+#, c-format
+msgid "do_reada: clear_array failed\n"
+msgstr "do_reada: clear_array epäonnistui\n"
+
+#: extension/rwarray.c:374
+#, c-format
+msgid "read_array: set_array_element failed\n"
+msgstr "read_array: set_array_element epäonnistui\n"
+
+#: extension/time.c:113
+msgid "gettimeofday: ignoring arguments"
+msgstr "gettimeofday: ohitetaan argumentit"
+
+#: extension/time.c:144
+msgid "gettimeofday: not supported on this platform"
+msgstr "gettimeofday: ei ole tuettu tällä alustalla"
+
+#: extension/time.c:165
+msgid "sleep: called with too many arguments"
+msgstr "sleep: kutsuttu liian monella argumentilla"
-#: field.c:328
+#: extension/time.c:168
+msgid "sleep: missing required numeric argument"
+msgstr "sleep: puuttuu vaadittu numeerinen argumentti"
+
+#: extension/time.c:174
+msgid "sleep: argument is negative"
+msgstr "sleep: argumentti on negatiivinen"
+
+#: extension/time.c:208
+msgid "sleep: not supported on this platform"
+msgstr "sleep: ei ole tuettu tällä alustalla"
+
+#: field.c:345
msgid "NF set to negative value"
msgstr "NF asetettu negatiiviseen arvoon"
-#: field.c:951 field.c:958 field.c:962
+#: field.c:971 field.c:978 field.c:982
msgid "split: fourth argument is a gawk extension"
msgstr "split: neljäs argumentti on gawk-laajennus"
-#: field.c:955
+#: field.c:975
msgid "split: fourth argument is not an array"
msgstr "split: neljäs argumentti ei ole taulukko"
-#: field.c:969
+#: field.c:989
msgid "split: second argument is not an array"
msgstr "split: toinen argumentti ei ole taulukko"
-#: field.c:973
+#: field.c:993
msgid "split: cannot use the same array for second and fourth args"
msgstr ""
-"split: ei voida käyttää samaa taulukkoa toiselle ja neljännelle argumentille"
+"split: saman taulukon käyttö toiselle ja neljännelle argumentille epäonnistui"
-#: field.c:978
+#: field.c:998
msgid "split: cannot use a subarray of second arg for fourth arg"
msgstr ""
-"split: ei voida käyttää toisen argumentin alitaulukkoa neljännelle "
-"argumentille"
+"split: toisen argumentin käyttö alitaulukkoa neljännelle argumentille "
+"epäonnistui"
-#: field.c:981
+#: field.c:1001
msgid "split: cannot use a subarray of fourth arg for second arg"
msgstr ""
-"split: ei voida käyttää neljännen argumentin alitaulukkoa toiselle "
-"argumentille"
+"split: neljännen argumentin käyttö alitaulukkoa toiselle argumentille "
+"epäonnistui"
-#: field.c:1010
+#: field.c:1032
msgid "split: null string for third arg is a gawk extension"
msgstr "split: null-merkkijono kolmantena argumenttina on gawk-laajennus"
-#: field.c:1050
+#: field.c:1072
msgid "patsplit: fourth argument is not an array"
msgstr "patsplit: neljäs argumentti ei ole taulukko"
-#: field.c:1055
+#: field.c:1077
msgid "patsplit: second argument is not an array"
msgstr "patsplit: toinen argumentti ei ole taulukko"
-#: field.c:1061
+#: field.c:1083
msgid "patsplit: third argument must be non-null"
msgstr "patsplit: kolmas argumentti ei ole taulukko"
-#: field.c:1065
+#: field.c:1087
msgid "patsplit: cannot use the same array for second and fourth args"
msgstr ""
-"patsplit: ei voida käyttää samaa taulukkoa toiselle ja neljännelle "
-"argumentille"
+"patsplit: saman taulukon käyttö toiselle ja neljännelle argumentille "
+"epäonnistui"
-#: field.c:1070
+#: field.c:1092
msgid "patsplit: cannot use a subarray of second arg for fourth arg"
msgstr ""
-"patsplit: ei voida käyttää toisen argumentin alitaulukkkoa neljännelle "
-"argumentille"
+"patsplit: toisen argumentin käyttö alitaulukkkoa neljännelle argumentille "
+"epäonnistui"
-#: field.c:1073
+#: field.c:1095
msgid "patsplit: cannot use a subarray of fourth arg for second arg"
msgstr ""
-"patsplit: ei voida käyttää neljännen argumentin alitaulukkoa toiselle "
-"argumentille"
+"patsplit: neljännen argumentin käyttö alitaulukkoa toiselle argumentille "
+"epäonnistui"
-#: field.c:1110
+#: field.c:1133
msgid "`FIELDWIDTHS' is a gawk extension"
msgstr "â€FIELDWIDTHS†on gawk-laajennus"
-#: field.c:1173
+#: field.c:1197
#, c-format
msgid "invalid FIELDWIDTHS value, near `%s'"
msgstr "virheellinen FIELDWIDTHS-arvo, lähellä â€%sâ€"
-#: field.c:1246
+#: field.c:1270
msgid "null string for `FS' is a gawk extension"
msgstr "null-merkkijono â€FSâ€-kenttäerotinmuuttujalle on gawk-laajennus"
-#: field.c:1250
+#: field.c:1274
msgid "old awk does not support regexps as value of `FS'"
msgstr "vanha awk ei tue regexp-arvoja â€FSâ€-kenttäerotinmuuttujana"
-#: field.c:1369
+#: field.c:1393
msgid "`FPAT' is a gawk extension"
msgstr "â€FPAT†on gawk-laajennus"
-#: getopt.c:574 getopt.c:590
+#: gawkapi.c:146
+msgid "awk_value_to_node: received null retval"
+msgstr "awk_value_to_node: vastaanotti null retval-paluuarvon"
+
+#: gawkapi.c:384
+msgid "node_to_awk_value: received null node"
+msgstr "node_to_awk_value: vastaaotti null-solmun"
+
+#: gawkapi.c:387
+msgid "node_to_awk_value: received null val"
+msgstr "node_to_awk_value: vastaanotti null-arvon"
+
+#: gawkapi.c:807
+msgid "remove_element: received null array"
+msgstr "remove_element: vastaanotettu null-taulukko"
+
+#: gawkapi.c:810
+msgid "remove_element: received null subscript"
+msgstr "remove_element: vastaanotti null-alaindeksin"
+
+#: gawkapi.c:947
#, c-format
-msgid "%s: option '%s' is ambiguous\n"
-msgstr "%s: valitsin ’%s’ ei ole yksiselitteinen\n"
+msgid "api_flatten_array: could not convert index %d\n"
+msgstr "api_flatten_array: indeksin %d muuntaminen epäonnistui\n"
-#: getopt.c:623 getopt.c:627
+#: gawkapi.c:952
+#, c-format
+msgid "api_flatten_array: could not convert value %d\n"
+msgstr "api_flatten_array: arvon %d muuntaminen epäonnistui\n"
+
+#: getopt.c:604 getopt.c:633
+#, c-format
+msgid "%s: option '%s' is ambiguous; possibilities:"
+msgstr "%s: valitsin ’%s’ ei ole yksiselitteinen; mahdollisuudet:"
+
+#: getopt.c:679 getopt.c:683
#, c-format
msgid "%s: option '--%s' doesn't allow an argument\n"
msgstr "%s: valitsin ’--%s’ ei salli argumenttia\n"
-#: getopt.c:636 getopt.c:641
+#: getopt.c:692 getopt.c:697
#, c-format
msgid "%s: option '%c%s' doesn't allow an argument\n"
msgstr "%s: valitsin ’%c%s’ ei salli argumenttia\n"
-#: getopt.c:684 getopt.c:703
+#: getopt.c:740 getopt.c:759
#, c-format
msgid "%s: option '--%s' requires an argument\n"
msgstr "%s: valitsin ’--%s’ vaatii argumentin\n"
-#: getopt.c:741 getopt.c:744
+#: getopt.c:797 getopt.c:800
#, c-format
msgid "%s: unrecognized option '--%s'\n"
msgstr "%s: tunnistamaton valitsin ’--%s’\n"
-#: getopt.c:752 getopt.c:755
+#: getopt.c:808 getopt.c:811
#, c-format
msgid "%s: unrecognized option '%c%s'\n"
msgstr "%s: tunnistamaton valitsin ’%c%s’\n"
-#: getopt.c:804 getopt.c:807
+#: getopt.c:860 getopt.c:863
#, c-format
msgid "%s: invalid option -- '%c'\n"
msgstr "%s: virheellinen valitsin -- ’%c’\n"
-#: getopt.c:857 getopt.c:874 getopt.c:1082 getopt.c:1100
+#: getopt.c:916 getopt.c:933 getopt.c:1143 getopt.c:1161
#, c-format
msgid "%s: option requires an argument -- '%c'\n"
msgstr "%s: valitsin vaatii argumentin -- ’%c’\n"
-#: getopt.c:930 getopt.c:946
+#: getopt.c:989 getopt.c:1005
#, c-format
msgid "%s: option '-W %s' is ambiguous\n"
msgstr "%s: valitsin ’-W %s’ ei ole yksiselitteinen\n"
-#: getopt.c:970 getopt.c:988
+#: getopt.c:1029 getopt.c:1047
#, c-format
msgid "%s: option '-W %s' doesn't allow an argument\n"
msgstr "%s: valitsin ’-W %s’ ei salli argumenttia\n"
-#: getopt.c:1009 getopt.c:1027
+#: getopt.c:1068 getopt.c:1086
#, c-format
msgid "%s: option '-W %s' requires an argument\n"
msgstr "%s: valitsin ’-W %s’ vaatii argumentin\n"
-#: io.c:280
+#: io.c:392
#, c-format
msgid "command line argument `%s' is a directory: skipped"
msgstr "komentoriviargumentti â€%s†on hakemisto: ohitettiin"
-#: io.c:283 io.c:385
+#: io.c:395 io.c:513
#, c-format
msgid "cannot open file `%s' for reading (%s)"
-msgstr "ei voi avata tiedostoa â€%s†lukemista varten (%s)"
+msgstr "tiedoston â€%s†avaaminen lukemista varten (%s) epäonnistui"
-#: io.c:501
+#: io.c:640
#, c-format
msgid "close of fd %d (`%s') failed (%s)"
msgstr "tiedostomäärittelijän %d (â€%sâ€) sulkeminen epäonnistui (%s)"
-#: io.c:578
+#: io.c:716
msgid "redirection not allowed in sandbox mode"
msgstr "edelleenohjaus ei ole sallittua hiekkalaatikkotilassa"
-#: io.c:612
+#: io.c:750
#, c-format
msgid "expression in `%s' redirection only has numeric value"
msgstr "lausekkeella â€%sâ€-uudellenohjauksessa on vain numeerinen arvo"
-#: io.c:618
+#: io.c:756
#, c-format
msgid "expression for `%s' redirection has null string value"
msgstr "lausekkeella â€%sâ€-uudelleenohjauksessa on null-merkkijonoarvo"
-#: io.c:624
+#: io.c:761
#, c-format
msgid "filename `%s' for `%s' redirection may be result of logical expression"
msgstr ""
"tiedostonimi â€%s†â€%sâ€-uudelleenohjaukselle saattaa olla loogisen lausekkeen "
"tulos"
-#: io.c:667
+#: io.c:809
#, c-format
msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
msgstr "turha merkkien â€>†ja â€>>†sekoittaminen tiedostolle â€%.*sâ€"
-#: io.c:720
+#: io.c:863
#, c-format
msgid "can't open pipe `%s' for output (%s)"
-msgstr "ei voi avata putkea â€%s†tulosteelle (%s)"
+msgstr "putken â€%s†avaaminen tulosteelle (%s) epäonnistui"
-#: io.c:730
+#: io.c:873
#, c-format
msgid "can't open pipe `%s' for input (%s)"
-msgstr "ei voi avata putkea â€%s†syötteelle (%s)"
+msgstr "putken â€%s†avaaminen syötteelle (%s) epäonnistui"
-#: io.c:753
+#: io.c:904
#, c-format
msgid "can't open two way pipe `%s' for input/output (%s)"
-msgstr "ei voi avata kaksisuuntaista putkea â€%s†syötteelle/tulosteelle (%s)"
+msgstr ""
+"kaksisuuntaisen putken â€%s†avaaminen syötteelle/tulosteelle (%s) epäonnistui"
-#: io.c:835
+#: io.c:986
#, c-format
msgid "can't redirect from `%s' (%s)"
-msgstr "ei voi uudelleenohjata putkesta â€%s†(%s)"
+msgstr "uudelleenohjaus putkesta â€%s†(%s) epäonnistui"
-#: io.c:838
+#: io.c:989
#, c-format
msgid "can't redirect to `%s' (%s)"
-msgstr "ei voi uudelleenohjata putkeen â€%s†(%s)"
+msgstr "uudelleenohjaus putkeen â€%s†(%s) epäonnistui"
-#: io.c:889
+#: io.c:1040
msgid ""
"reached system limit for open files: starting to multiplex file descriptors"
msgstr ""
"saavutettiin avoimien tiedostojen järjestelmäraja: aloitetaan "
"tiedostomäärittelijöiden lomittaminen"
-#: io.c:905
+#: io.c:1056
#, c-format
msgid "close of `%s' failed (%s)."
msgstr "uudelleenohjauksen â€%s†sulkeminen epäonnistui (%s)."
-#: io.c:913
+#: io.c:1064
msgid "too many pipes or input files open"
msgstr "avoinna liian monta putkea tai syötetiedostoa"
-#: io.c:935
+#: io.c:1086
msgid "close: second argument must be `to' or `from'"
msgstr "close: toisen argumentin on oltava â€to†tai â€fromâ€"
-#: io.c:952
+#: io.c:1103
#, c-format
msgid "close: `%.*s' is not an open file, pipe or co-process"
msgstr "close: â€%.*s†ei ole avoin tiedosto, putki tai apuprosessi"
-#: io.c:957
+#: io.c:1108
msgid "close of redirection that was never opened"
msgstr "suljettiin uudelleenohjaus, jota ei avattu koskaan"
-#: io.c:1054
+#: io.c:1205
#, c-format
msgid "close: redirection `%s' not opened with `|&', second argument ignored"
msgstr ""
"close: uudelleenohjaus â€%s†ei ole avattu operaattoreilla â€|&â€, toinen "
"argumentti ohitettu"
-#: io.c:1070
+#: io.c:1222
#, c-format
msgid "failure status (%d) on pipe close of `%s' (%s)"
msgstr "virhetila (%d) putken â€%s†sulkemisessa (%s)"
-#: io.c:1073
+#: io.c:1225
#, c-format
msgid "failure status (%d) on file close of `%s' (%s)"
msgstr "virhetila (%d) tiedoston â€%s†sulkemisessa (%s)"
-#: io.c:1093
+#: io.c:1245
#, c-format
msgid "no explicit close of socket `%s' provided"
msgstr "pistokkeen â€%s†eksplisiittistä sulkemista ei tarjota"
-#: io.c:1096
+#: io.c:1248
#, c-format
msgid "no explicit close of co-process `%s' provided"
msgstr "apuprosessin â€%s†eksplisiittistä sulkemista ei tarjota"
-#: io.c:1099
+#: io.c:1251
#, c-format
msgid "no explicit close of pipe `%s' provided"
msgstr "putken â€%s†eksplisiittistä sulkemista ei tarjota"
-#: io.c:1102
+#: io.c:1254
#, c-format
msgid "no explicit close of file `%s' provided"
msgstr "tiedoston â€%s†eksplisiittistä sulkemista ei tarjota"
-#: io.c:1130 io.c:1185 main.c:793 main.c:830
+#: io.c:1284 io.c:1342 main.c:864 main.c:906
#, c-format
msgid "error writing standard output (%s)"
msgstr "virhe kirjoitettaessa vakiotulosteeseen (%s)"
-#: io.c:1134 io.c:1190
+#: io.c:1289 io.c:1348 main.c:866
#, c-format
msgid "error writing standard error (%s)"
msgstr "virhe kirjoitettaessa vakiovirheeseen (%s)"
-#: io.c:1142
+#: io.c:1297
#, c-format
msgid "pipe flush of `%s' failed (%s)."
msgstr "uudelleenohjauksen â€%s†putken tyhjennys epäonnistui (%s)."
-#: io.c:1145
+#: io.c:1300
#, c-format
msgid "co-process flush of pipe to `%s' failed (%s)."
msgstr "putken apuprosessityhjennys uudelleenohjaukseen â€%s†epäonnistui (%s)."
-#: io.c:1148
+#: io.c:1303
#, c-format
msgid "file flush of `%s' failed (%s)."
msgstr "uudelleenohjauksen â€%s†tiedostontyhjennys epäonnistui (%s)."
-#: io.c:1263
+#: io.c:1420
#, c-format
msgid "local port %s invalid in `/inet'"
msgstr "paikallinen portti %s virheellinen pistokkeessa â€/inetâ€"
-#: io.c:1280
+#: io.c:1438
#, c-format
msgid "remote host and port information (%s, %s) invalid"
msgstr "etäkone- ja porttitiedot (%s, %s) ovat virheellisiä"
-#: io.c:1432
+#: io.c:1590
#, c-format
msgid "no (known) protocol supplied in special filename `%s'"
msgstr "ei (tunnettua) yhteyskäytäntöä tarjottu erikoistiedostonimessä â€%sâ€"
-#: io.c:1446
+#: io.c:1604
#, c-format
msgid "special file name `%s' is incomplete"
msgstr "erikoistiedostonimi â€%s†on vaillinainen"
-#: io.c:1463
+#: io.c:1621
msgid "must supply a remote hostname to `/inet'"
msgstr "on tarjottava etäkoneen nimi pistokkeeseen â€/inetâ€"
-#: io.c:1481
+#: io.c:1639
msgid "must supply a remote port to `/inet'"
msgstr "on tarjottava etäportti pistokkeeseen â€/inetâ€"
-#: io.c:1527
+#: io.c:1685
msgid "TCP/IP communications are not supported"
msgstr "TCP/IP-viestintää ei tueta"
-#: io.c:1694
+#: io.c:1867
#, c-format
msgid "could not open `%s', mode `%s'"
-msgstr "ei voitu avata laitetta â€%sâ€, tila â€%sâ€"
+msgstr "laitteen â€%s†avaus epäonnistui, tila â€%sâ€"
-#: io.c:1748
+#: io.c:1917
#, c-format
msgid "close of master pty failed (%s)"
msgstr "â€master ptyâ€-sulkeminen epäonnistui (%s)"
-#: io.c:1750 io.c:1918 io.c:2075
+#: io.c:1919 io.c:2105 io.c:2305
#, c-format
msgid "close of stdout in child failed (%s)"
msgstr "vakiotulosteen sulkeminen lapsiprosessissa epäonnistui (%s)"
-#: io.c:1753
+#: io.c:1922
#, c-format
msgid "moving slave pty to stdout in child failed (dup: %s)"
msgstr ""
"â€slave ptyâ€:n siirtäminen vakiotulosteeseen lapsiprosessissa epäonnistui "
"(dup: %s)"
-#: io.c:1755 io.c:1923
+#: io.c:1924 io.c:2110
#, c-format
msgid "close of stdin in child failed (%s)"
msgstr "vakiosyötteen sulkeminen lapsiprosessissa epäonnistui (%s)"
-#: io.c:1758
+#: io.c:1927
#, c-format
msgid "moving slave pty to stdin in child failed (dup: %s)"
msgstr ""
"â€slave ptyâ€:n siirtäminen vakiosyötteeseen lapsiprosessissa epäonnistui "
"(dup: %s)"
-#: io.c:1760 io.c:1781
+#: io.c:1929 io.c:1951
#, c-format
msgid "close of slave pty failed (%s)"
msgstr "â€slave ptyâ€:n sulkeminen epäonnistui (%s)"
-#: io.c:1859 io.c:1921 io.c:2053 io.c:2078
+#: io.c:2040 io.c:2108 io.c:2276 io.c:2308
#, c-format
msgid "moving pipe to stdout in child failed (dup: %s)"
msgstr ""
"putken siirtäminen vakiotulosteeseen lapsiprosessissa epäonnistui (dup: %s)"
-#: io.c:1866 io.c:1926
+#: io.c:2047 io.c:2113
#, c-format
msgid "moving pipe to stdin in child failed (dup: %s)"
msgstr ""
"putken siirtäminen vakiosyötteeseen lapsiprosessissa epäonnistui (dup: %s)"
-#: io.c:1886 io.c:2068
+#: io.c:2073 io.c:2298
msgid "restoring stdout in parent process failed\n"
msgstr "vakiotulosteen palauttaminen äitiprosessissa epäonnistui\n"
-#: io.c:1894
+#: io.c:2081
msgid "restoring stdin in parent process failed\n"
msgstr "vakiosyötön palauttaminen äitiprosessissa epäonnistui\n"
-#: io.c:1929 io.c:2080 io.c:2094
+#: io.c:2116 io.c:2310 io.c:2324
#, c-format
msgid "close of pipe failed (%s)"
msgstr "putken sulkeminen epäonnistui (%s)"
-#: io.c:1974
+#: io.c:2174
msgid "`|&' not supported"
msgstr "â€|&†ei tueta"
-#: io.c:2040
+#: io.c:2261
#, c-format
msgid "cannot open pipe `%s' (%s)"
-msgstr "ei voi avata putkea â€%s†(%s)"
+msgstr "putken â€%s†(%s) avaaminen epäonnistui"
-#: io.c:2088
+#: io.c:2318
#, c-format
msgid "cannot create child process for `%s' (fork: %s)"
-msgstr "ei voida luoda lapsiprosessia komennolle â€%s†(fork: %s)"
+msgstr "lapsiprosessin luominen komennolle â€%s†(fork: %s) epäonnistui"
+
+#: io.c:2790
+msgid "register_input_parser: received NULL pointer"
+msgstr "register_input_parser: vastaanotettiin NULL-osoitin"
+
+#: io.c:2818
+#, c-format
+msgid "input parser `%s' conflicts with previously installed input parser `%s'"
+msgstr ""
+"syötejäsennin â€%s†on ristiriidassa aiemmin asennetun syötejäsentimen â€%s†"
+"kanssa"
-#: io.c:2521
+#: io.c:2825
+#, c-format
+msgid "input parser `%s' failed to open `%s'"
+msgstr "syötejäsentäjä â€%s†epäonnistui kohteen â€%s†avaamisessa"
+
+#: io.c:2845
+msgid "register_output_wrapper: received NULL pointer"
+msgstr "register_output_wrapper: vastaanotti NULL-osoittimen"
+
+#: io.c:2873
+#, c-format
+msgid ""
+"output wrapper `%s' conflicts with previously installed output wrapper `%s'"
+msgstr ""
+"tulostekäärin â€%s†on ristiriidassa aiemmin asennetun tulostekäärimen â€%s†"
+"kanssa"
+
+#: io.c:2880
+#, c-format
+msgid "output wrapper `%s' failed to open `%s'"
+msgstr "tulostekäärin â€%s†epäonnistui avaamaan â€%sâ€"
+
+#: io.c:2901
+msgid "register_output_processor: received NULL pointer"
+msgstr "register_output_processor: vastaanotti NULL-osoittimen"
+
+#: io.c:2930
+#, c-format
+msgid ""
+"two-way processor `%s' conflicts with previously installed two-way processor "
+"`%s'"
+msgstr ""
+"kaksisuuntainen prosessori â€%s†on ristiriidassa aiemmin asennetun "
+"kaksisuuntaisen prosessorin â€%s†kanssa"
+
+#: io.c:2939
+#, c-format
+msgid "two way processor `%s' failed to open `%s'"
+msgstr "kaksisuuntainen prosessori â€%s†epäonnistui avaamaan â€%sâ€"
+
+#: io.c:3064
#, c-format
msgid "data file `%s' is empty"
msgstr "data-tiedosto â€%s†on tyhjä"
-#: io.c:2562 io.c:2570
+#: io.c:3106 io.c:3114
msgid "could not allocate more input memory"
-msgstr "ei voitu varata lisää syötemuistia"
+msgstr "lisäsyötemuistin varaus epäonnistui"
-#: io.c:3128
+#: io.c:3682
msgid "multicharacter value of `RS' is a gawk extension"
msgstr "â€RSâ€-monimerkkiarvo on gawk-laajennus"
-#: io.c:3233
+#: io.c:3771
msgid "IPv6 communication is not supported"
msgstr "IPv6-viestintää ei tueta"
-#: main.c:364
-msgid "`-m[fr]' option irrelevant in gawk"
-msgstr "â€-m[fr]â€-valitsin asiaanliittymätön gawk:ssa"
-
-#: main.c:366
-msgid "-m option usage: `-m[fr] nnn'"
-msgstr "-m valitsinkäyttö: â€-m[fr] nnnâ€"
-
-#: main.c:389
+#: main.c:405
msgid "empty argument to `-e/--source' ignored"
msgstr "tyhjä argumentti valitsimelle â€-e/--source†ohitetaan"
-#: main.c:460
+#: main.c:495
#, c-format
msgid "%s: option `-W %s' unrecognized, ignored\n"
msgstr "%s: valitsin â€-W %s†on tunnistamaton, ohitetaan\n"
-#: main.c:513
+#: main.c:541
#, c-format
msgid "%s: option requires an argument -- %c\n"
msgstr "%s: valitsin vaatii argumentin -- %c\n"
-#: main.c:534
+#: main.c:562
msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
msgstr ""
"ympäristömuuttuja â€POSIXLY_CORRECT†asetettu: käännetään päälle valitsin â€--"
"posixâ€"
-#: main.c:540
+#: main.c:568
msgid "`--posix' overrides `--traditional'"
msgstr "valitsin â€--posix†korvaa valitsimen â€--traditionalâ€"
-#: main.c:551
+#: main.c:579
msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
msgstr ""
"valitsin â€--posix†tai â€--traditional†korvaa valitsimen â€--non-decimal-dataâ€"
-#: main.c:555
+#: main.c:583
#, c-format
msgid "running %s setuid root may be a security problem"
msgstr "suorittaminen â€%s setuid rootâ€-käyttäjänä saattaa olla turvapulma"
-#: main.c:560
-msgid "`--posix' overrides `--binary'"
-msgstr "valitsin â€--posix†korvaa valitsimen â€--binaryâ€"
+#: main.c:588
+msgid "`--posix' overrides `--characters-as-bytes'"
+msgstr "valitsin â€--posix†korvaa valitsimen â€--characters-as-bytesâ€"
-#: main.c:611
+#: main.c:647
#, c-format
msgid "can't set binary mode on stdin (%s)"
-msgstr "ei voi asettaa binaaritilaa vakiosyötteessä (%s)"
+msgstr "binaaritilan asettaminen vakiosyötteessä (%s) epäonnistui"
-#: main.c:614
+#: main.c:650
#, c-format
msgid "can't set binary mode on stdout (%s)"
-msgstr "ei voi asettaa binaaritilaa vakiotulosteessa (%s)"
+msgstr "binaaritilan asettaminen vakiotulosteessa (%s) epäonnistui"
-#: main.c:616
+#: main.c:652
#, c-format
msgid "can't set binary mode on stderr (%s)"
-msgstr "ei voi asettaa binaaritilaa vakiovirheessä (%s)"
+msgstr "binaaritilaa asettaminen vakiovirheessä (%s) epäonnistui"
-#: main.c:655
+#: main.c:710
msgid "no program text at all!"
msgstr "ei ohjelmatekstiä ollenkaan!"
-#: main.c:733
+#: main.c:799
#, c-format
msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
msgstr ""
"Käyttö: %s [POSIX- tai GNU-tyyliset valitsimet] -f ohjelmatiedosto [--] "
"tiedosto ...\n"
-#: main.c:735
+#: main.c:801
#, c-format
msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
msgstr ""
"Käyttö: %s [POSIX- tai GNU-tyyliset valitsimet] [--] %cohjelma%c "
"tiedosto ...\n"
-#: main.c:740
+#: main.c:806
msgid "POSIX options:\t\tGNU long options: (standard)\n"
msgstr "POSIX-valitsimet:\t\tGNU-pitkät valitsimet: (vakio)\n"
-#: main.c:741
+#: main.c:807
msgid "\t-f progfile\t\t--file=progfile\n"
msgstr "\t-f ohjelmatiedosto\t\t--file=ohjelmatiedosto\n"
-#: main.c:742
+#: main.c:808
msgid "\t-F fs\t\t\t--field-separator=fs\n"
msgstr "\t-F fs\t\t\t--field-separator=fs\n"
-#: main.c:743
+#: main.c:809
msgid "\t-v var=val\t\t--assign=var=val\n"
msgstr "\t-v var=arvo\t\t--assign=muuttuja=arvo\n"
-#: main.c:744
+#: main.c:810
msgid "Short options:\t\tGNU long options: (extensions)\n"
msgstr "Lyhyet valitsimet:\t\tGNU-pitkät valitsimet: (laajennukset)\n"
-#: main.c:745
+#: main.c:811
msgid "\t-b\t\t\t--characters-as-bytes\n"
msgstr "\t-b\t\t\t--characters-as-bytes\n"
-#: main.c:746
+#: main.c:812
msgid "\t-c\t\t\t--traditional\n"
msgstr "\t-c\t\t\t--traditional\n"
-#: main.c:747
+#: main.c:813
msgid "\t-C\t\t\t--copyright\n"
msgstr "\t-C\t\t\t--copyright\n"
-#: main.c:748
+#: main.c:814
msgid "\t-d[file]\t\t--dump-variables[=file]\n"
msgstr "\t-d[tiedosto]\t\t--dump-variables[=tiedosto]\n"
-#: main.c:749
+#: main.c:815
+msgid "\t-D[file]\t\t--debug[=file]\n"
+msgstr "\t-D[tiedosto]\t\t--debug[=tiedosto]\n"
+
+#: main.c:816
msgid "\t-e 'program-text'\t--source='program-text'\n"
msgstr "\t-e 'program-text'\t--source='program-text'\n"
-#: main.c:750
+#: main.c:817
msgid "\t-E file\t\t\t--exec=file\n"
msgstr "\t-E file\t\t\t--exec=tiedosto\n"
-#: main.c:751
+#: main.c:818
msgid "\t-g\t\t\t--gen-pot\n"
msgstr "\t-g\t\t\t--gen-po\n"
-#: main.c:752
+#: main.c:819
msgid "\t-h\t\t\t--help\n"
msgstr "\t-h\t\t\t--help\n"
-#: main.c:753
+#: main.c:820
+msgid "\t-i includefile\t\t--include=includefile\n"
+msgstr "\t-i include-tiedosto\t\t--include=include-tiedosto\n"
+
+#: main.c:821
+msgid "\t-l library\t\t--load=library\n"
+msgstr "\t-l kirjasto\t\t--load=kirjasto\n"
+
+#: main.c:822
msgid "\t-L [fatal]\t\t--lint[=fatal]\n"
msgstr "\t-L [fatal]\t\t--lint[=fatal]\n"
-#: main.c:754
+#: main.c:823
msgid "\t-n\t\t\t--non-decimal-data\n"
msgstr "\t-n\t\t\t--non-decimal-data\n"
-#: main.c:755
+#: main.c:824
+msgid "\t-M\t\t\t--bignum\n"
+msgstr "\t-M\t\t\t--bignum\n"
+
+#: main.c:825
msgid "\t-N\t\t\t--use-lc-numeric\n"
msgstr "\t-N\t\t\t--use-lc-numeric\n"
-#: main.c:756
+#: main.c:826
+msgid "\t-o[file]\t\t--pretty-print[=file]\n"
+msgstr "\t-o[tiedosto]\t\t--pretty-print[=tiedosto]\n"
+
+#: main.c:827
msgid "\t-O\t\t\t--optimize\n"
msgstr "\t-O\t\t\t--optimize\n"
-#: main.c:757
+#: main.c:828
msgid "\t-p[file]\t\t--profile[=file]\n"
msgstr "\t-p[tiedosto]\t\t--profile[=tiedosto]\n"
-#: main.c:758
+#: main.c:829
msgid "\t-P\t\t\t--posix\n"
msgstr "\t-P\t\t\t--posix\n"
-#: main.c:759
+#: main.c:830
msgid "\t-r\t\t\t--re-interval\n"
msgstr "\t-r\t\t\t--re-interval\n"
-#: main.c:761
-msgid "\t-R file\t\t\t--command=file\n"
-msgstr "\t-R tiedosto\t\t\t--exec=tiedosto\n"
-
-#: main.c:762
+#: main.c:831
msgid "\t-S\t\t\t--sandbox\n"
msgstr "\t-S\t\t\t--sandbox\n"
-#: main.c:763
+#: main.c:832
msgid "\t-t\t\t\t--lint-old\n"
msgstr "\t-t\t\t\t--lint-old\n"
-#: main.c:764
+#: main.c:833
msgid "\t-V\t\t\t--version\n"
msgstr "\t-V\t\t\t--version\n"
-#: main.c:766
+#: main.c:835
msgid "\t-W nostalgia\t\t--nostalgia\n"
msgstr "\t-W nostalgia\t\t--nostalgia\n"
-#: main.c:769
+#: main.c:838
msgid "\t-Y\t\t--parsedebug\n"
msgstr "\t-Y\t\t--parsedebug\n"
@@ -1821,7 +3146,7 @@ msgstr "\t-Y\t\t--parsedebug\n"
#. for this application. Please add _another line_ with the
#. address for translation bugs.
#. no-wrap
-#: main.c:778
+#: main.c:847
msgid ""
"\n"
"To report bugs, see node `Bugs' in `gawk.info', which is\n"
@@ -1834,7 +3159,7 @@ msgstr ""
"joka on kappale â€Reporting Problems and Bugs†painetussa versiossa.\n"
"\n"
-#: main.c:782
+#: main.c:851
msgid ""
"gawk is a pattern scanning and processing language.\n"
"By default it reads standard input and writes standard output.\n"
@@ -1844,7 +3169,7 @@ msgstr ""
"Oletuksena se lukee vakiosyötettä ja kirjoittaa vakiotulosteeseen.\n"
"\n"
-#: main.c:786
+#: main.c:855
msgid ""
"Examples:\n"
"\tgawk '{ sum += $1 }; END { print sum }' file\n"
@@ -1854,7 +3179,7 @@ msgstr ""
"\tgawk '{ sum += $1 }; END { print sum }' tiedosto\n"
"\tgawk -F: '{ print $1 }' /etc/passwd\n"
-#: main.c:806
+#: main.c:880
#, c-format
msgid ""
"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
@@ -1873,7 +3198,7 @@ msgstr ""
"ehtojen mukaisesti.\n"
"\n"
-#: main.c:814
+#: main.c:888
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"
@@ -1887,7 +3212,7 @@ msgstr ""
"GNU General Public License-ehdoista.\n"
"\n"
-#: main.c:820
+#: main.c:894
msgid ""
"You should have received a copy of the GNU General Public License\n"
"along with this program. If not, see http://www.gnu.org/licenses/.\n"
@@ -1895,16 +3220,16 @@ msgstr ""
"Sinun pitäisi vastaanottaa kopion GNU General Public Licence-lisenssistä\n"
"tämän ohjelman mukana. Jos näin ei ole, katso http://www.gnu.org/licenses/.\n"
-#: main.c:855
+#: main.c:931
msgid "-Ft does not set FS to tab in POSIX awk"
msgstr "-Ft ei aseta FS välilehteen POSIX awk:ssa"
-#: main.c:1089
+#: main.c:1208
#, c-format
msgid "unknown value for field spec: %d\n"
msgstr "tuntematon arvo kenttämääritteelle: %d\n"
-#: main.c:1170
+#: main.c:1306
#, c-format
msgid ""
"%s: `%s' argument to `-v' not in `var=value' form\n"
@@ -1913,84 +3238,127 @@ msgstr ""
"%s: â€%s†argumentti valitsimelle â€-v†ei ole â€var=arvoâ€-muodossa\n"
"\n"
-#: main.c:1196
+#: main.c:1332
#, c-format
msgid "`%s' is not a legal variable name"
msgstr "â€%s†ei ole laillinen muuttujanimi"
-#: main.c:1199
+#: main.c:1335
#, c-format
msgid "`%s' is not a variable name, looking for file `%s=%s'"
msgstr "â€%s†ei ole muuttujanimi, etsitään tiedostoa â€%s=%sâ€"
-#: main.c:1203
+#: main.c:1339
#, c-format
msgid "cannot use gawk builtin `%s' as variable name"
-msgstr "ei voi käyttää gawk-ohjelman sisäistä â€%sâ€-määrittelyä muuttujanimenä"
+msgstr ""
+"gawk-ohjelman sisäisen â€%sâ€-määrittelyn käyttö muuttujanimenä epäonnistui"
-#: main.c:1208
+#: main.c:1344
#, c-format
msgid "cannot use function `%s' as variable name"
-msgstr "funktionimeä â€%s†ei voi käyttää muuttujanimenä"
+msgstr "funktionimen â€%s†käyttö muuttujanimenä epäonnistui"
-#: main.c:1261
+#: main.c:1397
msgid "floating point exception"
msgstr "liukulukupoikkeus"
-#: main.c:1268
+#: main.c:1404
msgid "fatal error: internal error"
msgstr "tuhoisa virhe: sisäinen virhe"
-#: main.c:1283
+#: main.c:1419
msgid "fatal error: internal error: segfault"
msgstr "tuhoisa virhe: sisäinen virhe: segmenttivirhe"
-#: main.c:1295
+#: main.c:1431
msgid "fatal error: internal error: stack overflow"
msgstr "tuhoisa virhe: sisäinen virhe: pinoylivuoto"
-#: main.c:1345
+#: main.c:1490
#, c-format
msgid "no pre-opened fd %d"
msgstr "ei avattu uudelleen tiedostomäärittelijää %d"
-#: main.c:1352
+#: main.c:1497
#, c-format
msgid "could not pre-open /dev/null for fd %d"
-msgstr "ei voitu avata uudelleen laitetta /dev/null tiedostomäärittelijälle %d"
+msgstr ""
+"laitteen /dev/null avaaminen uudelleen tiedostomäärittelijälle %d epäonnistui"
+
+#: mpfr.c:550
+#, c-format
+msgid "PREC value `%.*s' is invalid"
+msgstr "PREC-arvo â€%.*s†on virheellinen"
+
+#: mpfr.c:608
+#, c-format
+msgid "RNDMODE value `%.*s' is invalid"
+msgstr "RNDMODE-arvo â€%.*s†on virheellinen"
+
+#: mpfr.c:698
+#, c-format
+msgid "%s: received non-numeric argument"
+msgstr "%s: vastaanotettu argumentti ei ole numeerinen"
+
+#: mpfr.c:800
+msgid "compl(%Rg): negative value will give strange results"
+msgstr "compl(%Rg): negatiivinen arvo antaa outoja tuloksia"
+
+#: mpfr.c:804
+msgid "comp(%Rg): fractional value will be truncated"
+msgstr "compl(%Rg): jaosarvo typistetään"
+
+#: mpfr.c:816
+#, c-format
+msgid "cmpl(%Zd): negative values will give strange results"
+msgstr "compl(%Zd): negatiiviset arvot antavat outoja tuloksia"
+
+#: mpfr.c:835
+#, c-format
+msgid "%s: received non-numeric argument #%d"
+msgstr "%s: vastaanotettu argumentti #%d ei ole numeerinen"
+
+#: mpfr.c:845
+msgid "%s: argument #%d has invalid value %Rg, using 0"
+msgstr "%s: argumentilla #%d on virheellinen arvo %Rg, käytetään 0"
+
+#: mpfr.c:857
+msgid "%s: argument #%d negative value %Rg will give strange results"
+msgstr "%s: argumentin #%d negatiivinen arvo %Rg antaa outoja tuloksia"
+
+#: mpfr.c:863
+msgid "%s: argument #%d fractional value %Rg will be truncated"
+msgstr "%s: argumentin #%d jaosarvo %Rg typistetään"
-#: main.c:1375 main.c:1384
+#: mpfr.c:878
#, c-format
-msgid "could not find groups: %s"
-msgstr "ei voitu löytää ryhmiä: %s"
+msgid "%s: argument #%d negative value %Zd will give strange results"
+msgstr "%s: argumentin #%d negatiivinen arvo %Zd antaa outoja tuloksia"
-#: msg.c:63
+#: msg.c:68
#, c-format
msgid "cmd. line:"
msgstr "komentorivi:"
-#: msg.c:107
-msgid "error: "
-msgstr "virhe:"
-
-#: node.c:406
+#: node.c:421
msgid "backslash at end of string"
msgstr "kenoviiva merkkijonon lopussa"
-#: node.c:517
+#: node.c:500
#, c-format
msgid "old awk does not support the `\\%c' escape sequence"
msgstr "vanha awk ei tue â€\\%câ€-koodinvaihtosekvenssiä"
-#: node.c:568
+#: node.c:551
msgid "POSIX does not allow `\\x' escapes"
msgstr "POSIX ei salli â€\\xâ€-koodinvaihtoja"
-#: node.c:574
+#: node.c:557
msgid "no hex digits in `\\x' escape sequence"
msgstr "ei heksadesimaalilukuja â€\\xâ€-koodinvaihtosekvenssissä"
-#: node.c:596
+#: node.c:579
#, c-format
msgid ""
"hex escape \\x%.*s of %d characters probably not interpreted the way you "
@@ -1999,12 +3367,12 @@ msgstr ""
"heksadesimaalikoodinvaihtomerkkejä \\x%.*s / %d ei ole luultavasti tulkittu "
"sillä tavalla kuin odotat"
-#: node.c:611
+#: node.c:594
#, c-format
msgid "escape sequence `\\%c' treated as plain `%c'"
msgstr "koodinvaihtosekvenssi â€\\%c†käsitelty kuin pelkkä â€%câ€"
-#: node.c:750
+#: node.c:739
msgid ""
"Invalid multibyte data detected. There may be a mismatch between your data "
"and your locale."
@@ -2012,26 +3380,27 @@ msgstr ""
"Virheellinen monitavutieto havaittu. Paikallisasetuksesi ja tietojesi "
"välillä saattaa olla täsmäämättömyys."
-#: posix/gawkmisc.c:176
+#: posix/gawkmisc.c:177
#, c-format
msgid "%s %s `%s': could not get fd flags: (fcntl F_GETFD: %s)"
-msgstr "%s %s â€%sâ€: ei voitu hakea fd-lippuja: (fcntl F_GETFD: %s)"
+msgstr "%s %s â€%sâ€: fd-lippujen hakeminen epäonnistui: (fcntl F_GETFD: %s)"
-#: posix/gawkmisc.c:188
+#: posix/gawkmisc.c:189
#, c-format
msgid "%s %s `%s': could not set close-on-exec: (fcntl F_SETFD: %s)"
-msgstr "%s %s â€%sâ€: ei voitu asettaa close-on-exec: (fcntl F_SETFD: %s)"
+msgstr ""
+"%s %s â€%sâ€: close-on-exec -asettaminen epäonnistui: (fcntl F_SETFD: %s)"
-#: profile.c:83
+#: profile.c:71
#, c-format
msgid "could not open `%s' for writing: %s"
-msgstr "ei voitu avata tiedostoa â€%s†kirjoittamista varten: %s"
+msgstr "tiedoston â€%s†avaaminen kirjoittamista varten epäonnistui: %s"
-#: profile.c:85
+#: profile.c:73
msgid "sending profile to standard error"
msgstr "lähetetään profiili vakiovirheeseen"
-#: profile.c:203
+#: profile.c:193
#, c-format
msgid ""
"\t# %s block(s)\n"
@@ -2040,7 +3409,7 @@ msgstr ""
"\t# %s-lohko(t)\n"
"\n"
-#: profile.c:208
+#: profile.c:198
#, c-format
msgid ""
"\t# Rule(s)\n"
@@ -2049,17 +3418,30 @@ msgstr ""
"\t# Säännöt\n"
"\n"
-#: profile.c:279
+#: profile.c:272
#, c-format
msgid "internal error: %s with null vname"
msgstr "sisäinen virhe: %s null vname-arvolla"
-#: profile.c:952
+#: profile.c:537
+msgid "internal error: builtin with null fname"
+msgstr "sisäinen virhe: builtin null-funktionimellä"
+
+#: profile.c:949
+#, c-format
+msgid ""
+"\t# Loaded extensions (-l and/or @load)\n"
+"\n"
+msgstr ""
+"\t# Ladatut laajennukset (-l ja/tai @load)\n"
+"\n"
+
+#: profile.c:972
#, c-format
msgid "\t# gawk profile, created %s\n"
msgstr "\t# gawk-profiili, luotu %s\n"
-#: profile.c:1331
+#: profile.c:1475
#, c-format
msgid ""
"\n"
@@ -2068,94 +3450,196 @@ msgstr ""
"\n"
"\t# Funktiot, luetteloitu aakkosjärjestyksessä\n"
-#: profile.c:1370
+#: profile.c:1513
#, c-format
msgid "redir2str: unknown redirection type %d"
msgstr "redir2str: tuntematon edelleenohjaustyyppi %d"
-#: re.c:572
-#, fuzzy, c-format
-msgid "range of the form `[%c-%c]' is locale dependent"
-msgstr "muodon â€[%c-%c]†lukualue on paikallisasetuksesta riippuvainen"
-
-#: re.c:599
+#: re.c:607
#, c-format
msgid "regexp component `%.*s' should probably be `[%.*s]'"
msgstr ""
"säännöllisen lausekkeen komponentin â€%.*s†pitäisi luultavasti olla â€[%.*s]â€"
-#: regcomp.c:132
+#: regcomp.c:131
msgid "Success"
msgstr "Onnistui"
-#: regcomp.c:135
+#: regcomp.c:134
msgid "No match"
msgstr "Ei täsmäystä"
-#: regcomp.c:138
+#: regcomp.c:137
msgid "Invalid regular expression"
msgstr "Virheellinen säännöllinen lauseke"
-#: regcomp.c:141
+#: regcomp.c:140
msgid "Invalid collation character"
msgstr "Virheellinen vertailumerkki"
-#: regcomp.c:144
+#: regcomp.c:143
msgid "Invalid character class name"
msgstr "Virheellinen merkkiluokkanimi"
-#: regcomp.c:147
+#: regcomp.c:146
msgid "Trailing backslash"
msgstr "Jäljessä oleva kenoviiva"
-#: regcomp.c:150
+#: regcomp.c:149
msgid "Invalid back reference"
msgstr "Virheellinen paluuviite"
-#: regcomp.c:153
+#: regcomp.c:152
msgid "Unmatched [ or [^"
msgstr "Pariton [ tai [^"
-#: regcomp.c:156
+#: regcomp.c:155
msgid "Unmatched ( or \\("
msgstr "Pariton ( tai \\("
-#: regcomp.c:159
+#: regcomp.c:158
msgid "Unmatched \\{"
msgstr "Pariton \\{"
-#: regcomp.c:162
-msgid "Invalid content of \\{\\}"
-msgstr "Virheellinen \\{\\}-sisältö"
-
-#: regcomp.c:165
+#: regcomp.c:164
msgid "Invalid range end"
msgstr "Virheellinen lukualueen loppu"
-#: regcomp.c:168
+#: regcomp.c:167
msgid "Memory exhausted"
msgstr "Muisti loppui"
-#: regcomp.c:171
+#: regcomp.c:170
msgid "Invalid preceding regular expression"
msgstr "Virheellinen edeltävä säännöllinen lauseke"
-#: regcomp.c:174
+#: regcomp.c:173
msgid "Premature end of regular expression"
msgstr "Ennenaikainen säännöllisen lausekkeen loppu"
-#: regcomp.c:177
-msgid "Regular expression too big"
-msgstr "Säännöllinen lauseke on liian iso"
-
-#: regcomp.c:180
+#: regcomp.c:179
msgid "Unmatched ) or \\)"
msgstr "Pariton ) tai \\)"
-#: regcomp.c:701
+#: regcomp.c:704
msgid "No previous regular expression"
msgstr "Ei edellistä säännöllistä lauseketta"
+#: symbol.c:741
+msgid "can not pop main context"
+msgstr "pääsisällön pop-toiminto epäonnistui"
+
+#~ msgid "range of the form `[%c-%c]' is locale dependent"
+#~ msgstr "muodon â€[%c-%c]†lukualue on paikallisasetuksesta riippuvainen"
+
+#~ msgid "attempt to use function `%s' as an array"
+#~ msgstr "yritettiin käyttää funktiota â€%s†taulukkona"
+
+#~ msgid "reference to uninitialized element `%s[\"%.*s\"]'"
+#~ msgstr "viite alustamattomaan elementtiin â€%s[\"%.*s\"]â€"
+
+#~ msgid "subscript of array `%s' is null string"
+#~ msgstr "taulukon alaindeksi â€%s†on null-merkkijono"
+
+#~ msgid "%s: empty (null)\n"
+#~ msgstr "%s: tyhjä (null)\n"
+
+#~ msgid "%s: empty (zero)\n"
+#~ msgstr "%s: tyhjä (nolla)\n"
+
+#~ msgid "%s: table_size = %d, array_size = %d\n"
+#~ msgstr "%s: table_size = %d, array_size = %d\n"
+
+#~ msgid "%s: array_ref to %s\n"
+#~ msgstr "%s: array_ref-viite taulukkoon %s\n"
+
+#~ msgid "`nextfile' is a gawk extension"
+#~ msgstr "â€nextfile†on gawk-laajennus"
+
+#~ msgid "`delete array' is a gawk extension"
+#~ msgstr "â€delete array†on gawk-laajennus"
+
+#~ msgid "use of non-array as array"
+#~ msgstr "ei-taulukon käyttö taulukkona"
+
+#~ msgid "`%s' is a Bell Labs extension"
+#~ msgstr "â€%s†on Bell Labs -laajennus"
+
+#~ msgid "and: received non-numeric first argument"
+#~ msgstr "and: ensimmäinen vastaanotettu argumentti ei ole numeerinen"
+
+#~ msgid "and: received non-numeric second argument"
+#~ msgstr "and: toinen vastaanotettu argumentti ei ole numeerinen"
+
+#~ msgid "or: received non-numeric first argument"
+#~ msgstr "or: ensimmäinen vastaanotettu argumentti ei ole numeerinen"
+
+#~ msgid "or: received non-numeric second argument"
+#~ msgstr "or: toinen vastaanotettu argumentti ei ole numeerinen"
+
+#~ msgid "or(%lf, %lf): negative values will give strange results"
+#~ msgstr "or(%lf, %lf): negatiiviset arvot antavat outoja tuloksia"
+
+#~ msgid "or(%lf, %lf): fractional values will be truncated"
+#~ msgstr "or(%lf, %lf): jaosarvot typistetään"
+
+#~ msgid "xor: received non-numeric first argument"
+#~ msgstr "xor: ensimmäinen vastaanotettu argumentti ei ole numeerinen"
+
+#~ msgid "xor: received non-numeric second argument"
+#~ msgstr "xor: toinen vastaanotettu argumentti ei ole numeerinen"
+
+#~ msgid "xor(%lf, %lf): fractional values will be truncated"
+#~ msgstr "xor(%lf, %lf): jaosarvot typistetään"
+
+#~ msgid "can't use function name `%s' as variable or array"
+#~ msgstr "funktionimeä â€%s†käyttö muuttujana tai taulukkona epäonnistui"
+
+#~ msgid "assignment used in conditional context"
+#~ msgstr "sijoitusta käytetty ehdollisessa kontekstissa"
+
+#~ msgid "statement has no effect"
+#~ msgstr "käskyllä ei ole vaikutusta"
+
+#~ msgid ""
+#~ "for loop: array `%s' changed size from %ld to %ld during loop execution"
+#~ msgstr ""
+#~ "for-silmukka: taulukon â€%s†koko muuttui arvosta %ld arvoon %ld silmukan "
+#~ "suorituksen aikana"
+
+#~ msgid "function called indirectly through `%s' does not exist"
+#~ msgstr "kohteen â€%s†kautta epäsuorasti kutsuttu funktio ei ole olemassa"
+
+#~ msgid "function `%s' not defined"
+#~ msgstr "funktio â€%s†ei ole määritelty"
+
+#~ msgid "non-redirected `getline' invalid inside `%s' rule"
+#~ msgstr "edelleenohjaamaton â€getline†virheellinen â€%sâ€-säännön sisällä"
+
+#~ msgid "`nextfile' cannot be called from a `%s' rule"
+#~ msgstr "â€nextfile†ei voida kutsua â€%sâ€-säännöstä"
+
+#~ msgid "`next' cannot be called from a `%s' rule"
+#~ msgstr "â€next†ei voida kutsua â€%sâ€-säännöstä"
+
+#~ msgid "Sorry, don't know how to interpret `%s'"
+#~ msgstr "Ei osata tulkita kohdetta â€%sâ€"
+
+#~ msgid "Operation Not Supported"
+#~ msgstr "Toimintoa ei tueta"
+
+#~ msgid "`-m[fr]' option irrelevant in gawk"
+#~ msgstr "â€-m[fr]â€-valitsin asiaanliittymätön gawk:ssa"
+
+#~ msgid "-m option usage: `-m[fr] nnn'"
+#~ msgstr "-m valitsinkäyttö: â€-m[fr] nnnâ€"
+
+#~ msgid "\t-R file\t\t\t--command=file\n"
+#~ msgstr "\t-R tiedosto\t\t\t--exec=tiedosto\n"
+
+#~ msgid "could not find groups: %s"
+#~ msgstr "ryhmien löytäminen epäonnistui: %s"
+
#~ msgid "assignment is not allowed to result of builtin function"
#~ msgstr "sijoitusta ei sallita sisäänrakennetun funktion tulokselle"
@@ -2219,7 +3703,7 @@ msgstr "Ei edellistä säännöllistä lauseketta"
#~ msgstr "/inet/raw-palvelin ei ole vielä valitettavasti valmis"
#~ msgid "file `%s' is a directory"
-#~ msgstr "tiedosto `%s' on hakemisto"
+#~ msgstr "tiedosto â€%s†on hakemisto"
#~ msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
#~ msgstr "käytä â€PROCINFO[\"%s\"]†eikä â€%sâ€"
@@ -2240,7 +3724,7 @@ msgstr "Ei edellistä säännöllistä lauseketta"
#~ msgstr "\t-W usage\t\t--usage\n"
#~ msgid "can't convert string to float"
-#~ msgstr "ei voi muuntaa merkkijonoa liukuluvuksi"
+#~ msgstr "merkkijonon muuntaminen liukuluvuksi epäonnistui"
#~ msgid "# treated internally as `delete'"
#~ msgstr "# käsitelty sisäisesti kuin â€deleteâ€"
@@ -2263,10 +3747,11 @@ msgstr "Ei edellistä säännöllistä lauseketta"
#~ msgid "can't open two way socket `%s' for input/output (%s)"
#~ msgstr ""
-#~ "ei voi avata kaksisuuntaista pistoketta â€%s†syötteelle/tulosteelle (%s)"
+#~ "kaksisuuntaisen vastakkeen â€%s†avaaminen syötteelle/tulosteelle (%s) "
+#~ "epäonnistui"
#~ msgid "attempt to use scalar `%s' as array"
#~ msgstr "yritettiin käyttää skalaaria â€%s†taulukkona"
-#~ msgid "attempt to use array `%s' in scalar context"
-#~ msgstr "yritettiin käyttää taulukkoa â€%s†skalaarikontekstissa"
+#~ msgid "cannot pop main context"
+#~ msgstr "pääsisällön pop-toiminto epäonnistui"
diff --git a/po/fix-merge.awk b/po/fix-merge.awk
new file mode 100755
index 00000000..ec9e253b
--- /dev/null
+++ b/po/fix-merge.awk
@@ -0,0 +1,6 @@
+#! /usr/bin/gawk -f
+
+/^<<<<<<< HEAD/ { next }
+/^=======/, /^>>>>>>> / { next }
+
+{ print }
diff --git a/po/fr.gmo b/po/fr.gmo
index 000b9a8a..c962ab71 100644
--- a/po/fr.gmo
+++ b/po/fr.gmo
Binary files differ
diff --git a/po/fr.po b/po/fr.po
index a958491d..2a951b29 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -3,14 +3,14 @@
# Ce fichier est distribué sous la même licence que le paquet gawk.
# Copyright © 2004 Free Software Foundation, Inc.
# Michel Robitaille <robitail@IRO.UMontreal.CA>, 1996-2005.
-# Jean-Philippe Guérard <jean-philippe.guerard@corbeaunoir.org>, 2010, 2011.
+# Jean-Philippe Guérard <jean-philippe.guerard@corbeaunoir.org>, 2010-2011.
#
msgid ""
msgstr ""
-"Project-Id-Version: gawk 4.0.0\n"
+"Project-Id-Version: gawk 4.1.0b\n"
"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
-"POT-Creation-Date: 2011-10-24 05:57+0200\n"
-"PO-Revision-Date: 2011-07-16 16:50+0200\n"
+"POT-Creation-Date: 2014-04-08 19:23+0300\n"
+"PO-Revision-Date: 2014-01-16 00:31+0100\n"
"Last-Translator: Jean-Philippe Guérard <jean-philippe.guerard@corbeaunoir."
"org>\n"
"Language-Team: French <traduc@traduc.org>\n"
@@ -20,512 +20,492 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-#: array.c:140
+#: array.c:256
#, c-format
msgid "from %s"
msgstr "de %s"
-#: array.c:248
+#: array.c:357
msgid "attempt to use a scalar value as array"
msgstr "tentative d'utiliser un scalaire comme tableau"
-#: array.c:251
-#, c-format
-msgid "attempt to use function `%s' as an array"
-msgstr "tentative d'utiliser la fonction « %s » comme tableau"
-
-#: array.c:254
+#: array.c:359
#, c-format
msgid "attempt to use scalar parameter `%s' as an array"
msgstr "tentative d'utiliser le paramètre scalaire « %s » comme tableau"
-#: array.c:257
+#: array.c:362
#, c-format
msgid "attempt to use scalar `%s' as an array"
msgstr "tentative d'utiliser le scalaire « %s » comme tableau"
-#: array.c:302 array.c:707 builtin.c:84 builtin.c:1384 builtin.c:1426
-#: builtin.c:1439 builtin.c:1856 builtin.c:1868 eval.c:1135 eval.c:1139
-#: eval.c:1495 eval.c:1812
+#: array.c:409 array.c:576 builtin.c:85 builtin.c:1615 builtin.c:1661
+#: builtin.c:1674 builtin.c:2102 builtin.c:2116 eval.c:1122 eval.c:1126
+#: eval.c:1531
#, c-format
msgid "attempt to use array `%s' in a scalar context"
msgstr "tentative d'utilisation du tableau « %s » dans un contexte scalaire"
-#: array.c:513
-#, c-format
-msgid "reference to uninitialized element `%s[\"%.*s\"]'"
-msgstr "référence à un élément non initialisé « %s[\"%.*s\"] »"
-
-#: array.c:519
-#, c-format
-msgid "subscript of array `%s' is null string"
-msgstr "l'indice du tableau « %s » est une chaîne vide"
-
-#: array.c:723
+#: array.c:583
#, c-format
msgid "delete: index `%s' not in array `%s'"
msgstr "delete : l'indice « %s » est absent du tableau « %s »"
-#: array.c:734 eval.c:1865
+#: array.c:597
#, c-format
msgid "attempt to use scalar `%s[\"%.*s\"]' as an array"
msgstr "tentative d'utiliser le scalaire « %s[\"%.*s\"] » comme tableau"
-#: array.c:910
-#, c-format
-msgid "%s: empty (null)\n"
-msgstr "%s : vide (non défini)\n"
-
-#: array.c:915
-#, c-format
-msgid "%s: empty (zero)\n"
-msgstr "%s : vide (vide)\n"
-
-#: array.c:919
-#, c-format
-msgid "%s: table_size = %d, array_size = %d\n"
-msgstr "%s : table_size = %d, array_size = %d\n"
-
-#: array.c:954
-#, c-format
-msgid "%s: is parameter\n"
-msgstr "%s : est un paramètre\n"
-
-#: array.c:958
-#, c-format
-msgid "%s: array_ref to %s\n"
-msgstr "%s : array_ref à %s\n"
+#: array.c:776
+msgid "adump: first argument not an array"
+msgstr "adump : le 1er argument n'est pas un tableau"
-#: array.c:963
-msgid "adump: argument not an array"
-msgstr "adump : l'argument n'est pas un tableau"
-
-#: array.c:1086
+#: array.c:815
msgid "asort: second argument not an array"
-msgstr "asort : le 2nd argument n'est pas un tableau"
+msgstr "asort : le 2e argument n'est pas un tableau"
-#: array.c:1087
+#: array.c:816
msgid "asorti: second argument not an array"
-msgstr "asorti : le 2nd argument n'est pas un tableau"
+msgstr "asorti : le 2e argument n'est pas un tableau"
-#: array.c:1094
+#: array.c:823
msgid "asort: first argument not an array"
msgstr "asort : le 1er argument n'est pas un tableau"
-#: array.c:1095
+#: array.c:824
msgid "asorti: first argument not an array"
msgstr "asorti : le 1er argument n'est pas un tableau"
-#: array.c:1102
+#: array.c:831
msgid "asort: cannot use a subarray of first arg for second arg"
-msgstr "asort : le 2nd argument ne doit pas être un sous-tableau du 1er"
+msgstr "asort : le 2e argument ne doit pas être un sous-tableau du 1er"
-#: array.c:1103
+#: array.c:832
msgid "asorti: cannot use a subarray of first arg for second arg"
-msgstr "asorti : le 2nd argument ne doit pas être un sous-tableau du 1er"
+msgstr "asorti : le 2e argument ne doit pas être un sous-tableau du 1er"
-#: array.c:1108
+#: array.c:837
msgid "asort: cannot use a subarray of second arg for first arg"
-msgstr "asort : le 1er argument ne doit pas être un sous-tableau du 2nd"
+msgstr "asort : le 1er argument ne doit pas être un sous-tableau du 2e"
-#: array.c:1109
+#: array.c:838
msgid "asorti: cannot use a subarray of second arg for first arg"
-msgstr "asorti : le 1er argument ne doit pas être un sous-tableau du 2nd"
+msgstr "asorti : le 1er argument ne doit pas être un sous-tableau du 2e"
-#: array.c:1659
+#: array.c:1314
#, c-format
msgid "`%s' is invalid as a function name"
msgstr "« %s » n'est pas un nom de fonction valide"
-#: array.c:1663
+#: array.c:1318
#, c-format
msgid "sort comparison function `%s' is not defined"
msgstr "la fonction de comparaison « %s » du tri n'est pas définie"
-#: awkgram.y:249
+#: awkgram.y:233
#, c-format
msgid "%s blocks must have an action part"
msgstr "les blocs %s doivent avoir une partie action"
-#: awkgram.y:252
+#: awkgram.y:236
msgid "each rule must have a pattern or an action part"
msgstr "chaque règle doit avoir au moins une partie motif ou action"
-#: awkgram.y:323 awkgram.y:334
+#: awkgram.y:325 awkgram.y:336
msgid "old awk does not support multiple `BEGIN' or `END' rules"
msgstr "l'ancien awk ne permet pas les « BEGIN » ou « END » multiples"
-#: awkgram.y:371
+#: awkgram.y:373
#, 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:432
+#: awkgram.y:419
msgid "regexp constant `//' looks like a C++ comment, but is not"
msgstr "l'expression rationnelle constante « // » n'est pas un commentaire C++"
-#: awkgram.y:436
+#: awkgram.y:423
#, c-format
msgid "regexp constant `/%s/' looks like a C comment, but is not"
msgstr "l'expression rationnelle constante « /%s/ » n'est pas un commentaire C"
-#: awkgram.y:528
+#: awkgram.y:515
#, c-format
msgid "duplicate case values in switch body: %s"
msgstr "le corps du switch comporte des cas répétés : %s"
-#: awkgram.y:549
+#: awkgram.y:536
msgid "duplicate `default' detected in switch body"
msgstr "plusieurs « default » ont été détectés dans le corps du switch"
-#: awkgram.y:809
+#: awkgram.y:796 awkgram.y:3723
msgid "`break' is not allowed outside a loop or switch"
msgstr "« break » est interdit en dehors d'une boucle ou d'un switch"
-#: awkgram.y:818
+#: awkgram.y:805 awkgram.y:3715
msgid "`continue' is not allowed outside a loop"
msgstr "« continue » est interdit en dehors d'une boucle ou d'un switch"
-#: awkgram.y:828
+#: awkgram.y:815
#, c-format
msgid "`next' used in %s action"
msgstr "« next » est utilisé dans l'action %s"
-#: awkgram.y:836
-msgid "`nextfile' is a gawk extension"
-msgstr "« nextfile » est une extension gawk"
-
-#: awkgram.y:841
+#: awkgram.y:824
#, c-format
msgid "`nextfile' used in %s action"
msgstr "« nextfile » est utilisé dans l'action %s"
-#: awkgram.y:865
+#: awkgram.y:848
msgid "`return' used outside function context"
msgstr "« return » est utilisé hors du contexte d'une fonction"
-#: awkgram.y:925
+#: awkgram.y:922
msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
msgstr ""
"dans BEGIN ou END, un « print » seul devrait sans doute être un « print "
"\"\" »"
-#: awkgram.y:995 awkgram.y:999 awkgram.y:1023
-msgid "`delete array' is a gawk extension"
-msgstr "« delete array » est une extension gawk"
+#: awkgram.y:988 awkgram.y:1037
+msgid "`delete' is not allowed with SYMTAB"
+msgstr "« delete » est interdit sur SYMTAB"
+
+#: awkgram.y:990 awkgram.y:1039
+msgid "`delete' is not allowed with FUNCTAB"
+msgstr "« delete » est interdit sur FUNCTAB"
-#: awkgram.y:1019
+#: awkgram.y:1024 awkgram.y:1028
msgid "`delete(array)' is a non-portable tawk extension"
msgstr "« delete(array) » est une extension non portable de tawk"
-#: awkgram.y:1135
+#: awkgram.y:1149
msgid "multistage two-way pipelines don't work"
msgstr "impossible d'utiliser des tubes bidirectionnels en série"
-#: awkgram.y:1238
+#: awkgram.y:1264
msgid "regular expression on right of assignment"
msgstr "expression rationnelle à droite d'une affectation"
-#: awkgram.y:1249
+#: awkgram.y:1275
msgid "regular expression on left of `~' or `!~' operator"
msgstr "expression rationnelle à gauche d'un opérateur « ~ » ou « !~ »"
-#: awkgram.y:1265 awkgram.y:1419
+#: awkgram.y:1291 awkgram.y:1442
msgid "old awk does not support the keyword `in' except after `for'"
msgstr "l'ancien awk n'autorise le mot-clef « in » qu'après « for »"
-#: awkgram.y:1275
+#: awkgram.y:1301
msgid "regular expression on right of comparison"
msgstr "expression rationnelle à droite d'une comparaison"
-#: awkgram.y:1394
+#: awkgram.y:1417
#, c-format
msgid "`getline var' invalid inside `%s' rule"
msgstr "« getline var » n'est pas valable dans une règle « %s »"
-#: awkgram.y:1397 eval.c:2504
+#: awkgram.y:1420
#, c-format
msgid "`getline' invalid inside `%s' rule"
msgstr "« getline » n'est pas valable dans une règle « %s »"
-#: awkgram.y:1402
+#: awkgram.y:1425
msgid "non-redirected `getline' undefined inside END action"
msgstr "dans une action END, un « getline » non redirigé n'est pas défini"
-#: awkgram.y:1421
+#: awkgram.y:1444
msgid "old awk does not support multidimensional arrays"
msgstr "l'ancien awk ne dispose pas des tableaux multidimensionnels"
-#: awkgram.y:1517
+#: awkgram.y:1541
msgid "call of `length' without parentheses is not portable"
msgstr "l'appel de « length » sans parenthèses n'est pas portable"
-#: awkgram.y:1580
+#: awkgram.y:1607
msgid "indirect function calls are a gawk extension"
msgstr "les appels indirects de fonctions sont une extension gawk"
-#: awkgram.y:1593
+#: awkgram.y:1620
#, c-format
msgid "can not use special variable `%s' for indirect function call"
msgstr ""
"impossible d'utiliser la variable spéciale « %s » pour un appel indirect de "
"fonction"
-#: awkgram.y:1671
+#: awkgram.y:1698
msgid "invalid subscript expression"
-msgstr "expression indice non valide"
+msgstr "expression indice incorrecte"
-#: awkgram.y:1711
-msgid "use of non-array as array"
-msgstr "utilisation d'un non tableau comme tableau"
-
-#: awkgram.y:1975 awkgram.y:1995 msg.c:98
+#: awkgram.y:2048 awkgram.y:2068 gawkapi.c:206 gawkapi.c:224 msg.c:126
msgid "warning: "
msgstr "avertissement : "
-#: awkgram.y:1993 msg.c:130
+#: awkgram.y:2066 gawkapi.c:192 gawkapi.c:221 msg.c:158
msgid "fatal: "
msgstr "fatal : "
-#: awkgram.y:2043
+#: awkgram.y:2116
msgid "unexpected newline or end of string"
msgstr "fin de chaîne ou passage à la ligne inattendu"
-#: awkgram.y:2300 awkgram.y:2358 awkgram.y:2542
+#: awkgram.y:2383 awkgram.y:2459 awkgram.y:2682 debug.c:523 debug.c:539
+#: debug.c:2812 debug.c:5055
#, c-format
msgid "can't open source file `%s' for reading (%s)"
msgstr "impossible d'ouvrir le fichier source « %s » en lecture (%s)"
-#: awkgram.y:2301 awkgram.y:2359 builtin.c:122
+#: awkgram.y:2384 awkgram.y:2509
+#, c-format
+msgid "can't open shared library `%s' for reading (%s)"
+msgstr "impossible d'ouvrir la bibliothèque partagée « %s » en lecture (%s)"
+
+#: awkgram.y:2386 awkgram.y:2460 awkgram.y:2510 builtin.c:135 debug.c:5206
msgid "reason unknown"
msgstr "raison inconnue"
-#: awkgram.y:2317
+#: awkgram.y:2395 awkgram.y:2419
+#, c-format
+msgid "can't include `%s' and use it as a program file"
+msgstr "impossible d'inclure « %s » et de l'utiliser comme extension"
+
+#: awkgram.y:2408
#, c-format
msgid "already included source file `%s'"
msgstr "le fichier source « %s » a déjà été intégré"
-#: awkgram.y:2343
+#: awkgram.y:2409
+#, c-format
+msgid "already loaded shared library `%s'"
+msgstr "la bibliothèque partagée « %s » est déjà chargée"
+
+#: awkgram.y:2444
msgid "@include is a gawk extension"
msgstr "@include est une extension gawk"
-#: awkgram.y:2349
+#: awkgram.y:2450
msgid "empty filename after @include"
msgstr "Le nom de fichier après @include est vide"
#: awkgram.y:2494
+msgid "@load is a gawk extension"
+msgstr "@load est une extension gawk"
+
+#: awkgram.y:2500
+msgid "empty filename after @load"
+msgstr "Le nom de fichier après @load est vide"
+
+#: awkgram.y:2634
msgid "empty program text on command line"
msgstr "le programme indiqué en ligne de commande est vide"
-#: awkgram.y:2609
+#: awkgram.y:2749
#, c-format
msgid "can't read sourcefile `%s' (%s)"
msgstr "impossible de lire le fichier source « %s » (%s)"
-#: awkgram.y:2620
+#: awkgram.y:2760
#, c-format
msgid "source file `%s' is empty"
msgstr "le fichier source « %s » est vide"
-#: awkgram.y:2805
+#: awkgram.y:2937
msgid "source file does not end in newline"
msgstr "le fichier source ne se termine pas par un passage à la ligne"
-#: awkgram.y:2882
+#: awkgram.y:3042
msgid "unterminated regexp ends with `\\' at end of file"
msgstr ""
"expression rationnelle non refermée terminée par un « \\ » en fin de fichier"
-#: awkgram.y:2906
+#: awkgram.y:3066
#, c-format
msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
msgstr ""
"%s : %d : le modificateur d'expressions rationnelles « /.../%c » de tawk ne "
"marche pas dans gawk"
-#: awkgram.y:2910
+#: awkgram.y:3070
#, c-format
msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
msgstr ""
"le modificateur d'expressions rationnelles « /.../%c » de tawk ne marche pas "
"dans gawk"
-#: awkgram.y:2917
+#: awkgram.y:3077
msgid "unterminated regexp"
msgstr "expression rationnelle non refermée"
-#: awkgram.y:2921
+#: awkgram.y:3081
msgid "unterminated regexp at end of file"
msgstr "expression rationnelle non refermée en fin de fichier"
-#: awkgram.y:2980
+#: awkgram.y:3140
msgid "use of `\\ #...' line continuation is not portable"
msgstr ""
"l'utilisation de « \\ #... » pour prolonger une ligne n'est pas portable"
-#: awkgram.y:2996
+#: awkgram.y:3156
msgid "backslash not last character on line"
msgstr "la barre oblique inverse n'est pas le dernier caractère de la ligne"
-#: awkgram.y:3057
+#: awkgram.y:3217
msgid "POSIX does not allow operator `**='"
msgstr "POSIX n'autorise pas l'opérateur « **= »"
-#: awkgram.y:3059
+#: awkgram.y:3219
msgid "old awk does not support operator `**='"
msgstr "l'ancien awk ne dispose pas de l'opérateur « **= »"
-#: awkgram.y:3068
+#: awkgram.y:3228
msgid "POSIX does not allow operator `**'"
msgstr "POSIX n'autorise pas l'opérateur « ** »"
-#: awkgram.y:3070
+#: awkgram.y:3230
msgid "old awk does not support operator `**'"
msgstr "l'ancien awk ne dispose pas de l'opérateur « ** »"
-#: awkgram.y:3105
+#: awkgram.y:3265
msgid "operator `^=' is not supported in old awk"
msgstr "l'ancien awk ne dispose pas de l'opérateur « ^= »"
-#: awkgram.y:3113
+#: awkgram.y:3273
msgid "operator `^' is not supported in old awk"
msgstr "l'ancien awk ne dispose pas de l'opérateur « ^ »"
-#: awkgram.y:3206 awkgram.y:3222
+#: awkgram.y:3366 awkgram.y:3382 command.y:1178
msgid "unterminated string"
msgstr "chaîne non refermée"
-#: awkgram.y:3418
+#: awkgram.y:3603
#, c-format
msgid "invalid char '%c' in expression"
-msgstr "caractère non valide « %c » dans l'expression"
+msgstr "caractère incorrect « %c » dans l'expression"
-#: awkgram.y:3465
+#: awkgram.y:3650
#, c-format
msgid "`%s' is a gawk extension"
msgstr "« %s » est une extension gawk"
-#: awkgram.y:3470
-#, c-format
-msgid "`%s' is a Bell Labs extension"
-msgstr "« %s » est une extension Bell Labs"
-
-#: awkgram.y:3475
+#: awkgram.y:3655
#, c-format
msgid "POSIX does not allow `%s'"
msgstr "POSIX n'autorise pas « %s »"
-#: awkgram.y:3483
+#: awkgram.y:3663
#, c-format
msgid "`%s' is not supported in old awk"
msgstr "l'ancien awk ne dispose pas de « %s »"
-#: awkgram.y:3550
+#: awkgram.y:3753
msgid "`goto' considered harmful!\n"
msgstr "« goto est jugé dangereux ! » (Edsger W. Dijkstra)\n"
-#: awkgram.y:3601
+#: awkgram.y:3787
#, c-format
msgid "%d is invalid as number of arguments for %s"
msgstr "%d n'est pas un nombre d'arguments valide de %s"
-#: awkgram.y:3636
+#: awkgram.y:3822
#, c-format
msgid "%s: string literal as last arg of substitute has no effect"
msgstr ""
"%s : une chaîne littérale en dernier argument d'une substitution est sans "
"effet"
-#: awkgram.y:3641
+#: awkgram.y:3827
#, c-format
msgid "%s third parameter is not a changeable object"
msgstr "le 3e paramètre de %s n'est pas un objet modifiable"
-#: awkgram.y:3714 awkgram.y:3717
+#: awkgram.y:3910 awkgram.y:3913
msgid "match: third argument is a gawk extension"
msgstr "match : le 3e argument est une extension gawk"
-#: awkgram.y:3771 awkgram.y:3774
+#: awkgram.y:3967 awkgram.y:3970
msgid "close: second argument is a gawk extension"
msgstr "close : le 2e argument est une extension gawk"
-#: awkgram.y:3786
+#: awkgram.y:3982
msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
msgstr ""
"utilisation incorrecte de dcgettext(_\"...\") : enlevez le souligné de tête"
-#: awkgram.y:3801
+#: awkgram.y:3997
msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
msgstr ""
"utilisation incorrecte de dcngettext(_\"...\") : enlevez le souligné de tête"
-#: awkgram.y:3893
-#, c-format
-msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+#: awkgram.y:4016
+msgid "index: regexp constant as second argument is not allowed"
msgstr ""
-"fonction « %s » : paramètre #%d, « %s » est un doublon du paramètre #%d"
+"index : le second argument ne peut être une expression rationnelle constante"
-#: awkgram.y:3935
+#: awkgram.y:4069
#, c-format
msgid "function `%s': parameter `%s' shadows global variable"
msgstr "fonction « %s » : le paramètre « %s » masque la variable globale"
-#: awkgram.y:4093
+#: awkgram.y:4126 debug.c:4041 debug.c:4084 debug.c:5204
#, c-format
msgid "could not open `%s' for writing (%s)"
msgstr "impossible d'ouvrir « %s » en écriture (%s)"
-#: awkgram.y:4094
+#: awkgram.y:4127
msgid "sending variable list to standard error"
msgstr "envoi de la liste des variables vers la sortie d'erreur standard"
-#: awkgram.y:4100
+#: awkgram.y:4135
#, c-format
msgid "%s: close failed (%s)"
msgstr "%s : échec de la fermeture (%s)"
-#: awkgram.y:4152
+#: awkgram.y:4160
msgid "shadow_funcs() called twice!"
msgstr "shadows_funcs() a été appelé deux fois !"
-#: awkgram.y:4158
+#: awkgram.y:4168
msgid "there were shadowed variables."
msgstr "il y avait des variables masquées."
-#: awkgram.y:4188
+#: awkgram.y:4239
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "nom de fonction « %s » déjà défini"
+
+#: awkgram.y:4285
#, c-format
msgid "function `%s': can't use function name as parameter name"
msgstr ""
"fonction « %s » : impossible d'utiliser un nom de fonction comme paramètre"
-#: awkgram.y:4192
+#: awkgram.y:4288
#, c-format
msgid "function `%s': can't use special variable `%s' as a function parameter"
msgstr ""
"fonction « %s » : impossible d'utiliser la variable spéciale « %s » comme "
"paramètre d'une fonction"
-#: awkgram.y:4208
+#: awkgram.y:4296
#, c-format
-msgid "function name `%s' previously defined"
-msgstr "nom de fonction « %s » déjà défini"
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr ""
+"fonction « %s » : paramètre #%d, « %s » est un doublon du paramètre #%d"
-#: awkgram.y:4376 awkgram.y:4382
+#: awkgram.y:4383 awkgram.y:4389
#, c-format
msgid "function `%s' called but never defined"
msgstr "fonction « %s » appelée sans être définie"
-#: awkgram.y:4385
+#: awkgram.y:4393
#, c-format
msgid "function `%s' defined but never called directly"
msgstr "fonction « %s » définie mais jamais appelée directement"
-#: awkgram.y:4417
+#: awkgram.y:4425
#, c-format
msgid "regexp constant for parameter #%d yields boolean value"
msgstr "le paramètre #%d, une expr. rationnelle constante, fournit un booléen"
-#: awkgram.y:4526
+#: awkgram.y:4484
#, c-format
msgid ""
"function `%s' called with space between name and `(',\n"
@@ -534,232 +514,249 @@ msgstr ""
"fonction « %s » appelée avec un espace entre son nom\n"
"et « ( », ou utilisée comme variable ou tableau"
-#: awkgram.y:4773 eval.c:2056
+#: awkgram.y:4720
msgid "division by zero attempted"
msgstr "tentative de division par zéro"
-#: awkgram.y:4782 eval.c:2072
+#: awkgram.y:4729
#, c-format
msgid "division by zero attempted in `%%'"
msgstr "tentative de division par zéro dans « %% »"
-#: builtin.c:120
+# gawk 'BEGIN { $1++ = 1 }'
+#: awkgram.y:5049
+msgid ""
+"cannot assign a value to the result of a field post-increment expression"
+msgstr ""
+"impossible d'assigner une valeur au résultat de la post-incrémentation d'un "
+"champ"
+
+#: awkgram.y:5052
+#, c-format
+msgid "invalid target of assignment (opcode %s)"
+msgstr "cible de l'assignement incorrecte (opcode %s)"
+
+#: builtin.c:133
#, c-format
msgid "%s to \"%s\" failed (%s)"
msgstr "échec de %s vers « %s » (%s)"
-#: builtin.c:121
+#: builtin.c:134
msgid "standard output"
msgstr "sortie standard"
-#: builtin.c:135
+#: builtin.c:148
msgid "exp: received non-numeric argument"
msgstr "exp : l'argument n'est pas numérique"
-#: builtin.c:141
+#: builtin.c:154
#, c-format
msgid "exp: argument %g is out of range"
msgstr "exp : l'argument %g est hors limite"
-#: builtin.c:200
+#: builtin.c:229
#, c-format
msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
msgstr ""
"fflush : vidage impossible : le tube « %s » est ouvert en lecture et non en "
"écriture"
-#: builtin.c:203
+#: builtin.c:232
#, c-format
msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
msgstr ""
"fflush : vidage impossible : fichier « %s » ouvert en lecture, pas en "
"écriture"
-#: builtin.c:215
+#: builtin.c:244
#, c-format
msgid "fflush: `%s' is not an open file, pipe or co-process"
msgstr ""
"fflush : « %s » n'est ni un fichier ouvert, ni un tube, ni un co-processus"
-#: builtin.c:333
+#: builtin.c:362
msgid "index: received non-string first argument"
msgstr "index : le premier argument n'est pas une chaîne"
-#: builtin.c:335
+#: builtin.c:364
msgid "index: received non-string second argument"
msgstr "index : le second argument n'est pas une chaîne"
-#: builtin.c:457
+#: builtin.c:488 mpfr.c:757
msgid "int: received non-numeric argument"
msgstr "int : l'argument n'est pas numérique"
-#: builtin.c:493
+#: builtin.c:525
msgid "length: received array argument"
msgstr "length : l'argument reçu est un tableau"
-#: builtin.c:496
+#: builtin.c:528
msgid "`length(array)' is a gawk extension"
msgstr "« length(tableau) » est une extension gawk"
-#: builtin.c:504
+#: builtin.c:544
msgid "length: received non-string argument"
msgstr "length : l'argument n'est pas une chaîne"
-#: builtin.c:535
+#: builtin.c:575
msgid "log: received non-numeric argument"
msgstr "log : l'argument n'est pas numérique"
-#: builtin.c:538
+#: builtin.c:578
#, c-format
msgid "log: received negative argument %g"
msgstr "log : l'argument est négatif %g"
-#: builtin.c:694 builtin.c:699
+#: builtin.c:776 builtin.c:781
msgid "fatal: must use `count$' on all formats or none"
msgstr ""
"fatal : « numéro$ » doit être utilisé pour toutes les formats ou pour aucun"
-#: builtin.c:761
+#: builtin.c:851
#, c-format
msgid "field width is ignored for `%%' specifier"
msgstr "taille du champ de la spécification « %% » ignorée"
-#: builtin.c:763
+#: builtin.c:853
#, c-format
msgid "precision is ignored for `%%' specifier"
msgstr "précision de la spécification « %% » ignorée"
-#: builtin.c:765
+#: builtin.c:855
#, c-format
msgid "field width and precision are ignored for `%%' specifier"
msgstr "taille du champ et précision de la spécification « %% » ignorées"
-#: builtin.c:816
+#: builtin.c:906
msgid "fatal: `$' is not permitted in awk formats"
msgstr "fatal : « $ » n'est pas autorisé dans les formats awk"
-#: builtin.c:825
+#: builtin.c:915
msgid "fatal: arg count with `$' must be > 0"
msgstr "fatal : le numéro d'argument de « $ » doit être > 0"
-#: builtin.c:829
+#: builtin.c:919
#, c-format
msgid "fatal: arg count %ld greater than total number of supplied arguments"
msgstr ""
"fatal : le numéro d'argument %ld est > au nombre total d'arguments fournis"
-#: builtin.c:833
+#: builtin.c:923
msgid "fatal: `$' not permitted after period in format"
msgstr "fatal : dans un format, « $ » ne doit pas suivre un point"
-#: builtin.c:849
+#: builtin.c:939
msgid "fatal: no `$' supplied for positional field width or precision"
msgstr ""
"fatal : aucun « $ » fourni pour la taille ou la précision du champ positionné"
-#: builtin.c:920
+#: builtin.c:1009
msgid "`l' is meaningless in awk formats; ignored"
msgstr "« l » n'a aucun sens dans un format awk ; ignoré"
-#: builtin.c:924
+#: builtin.c:1013
msgid "fatal: `l' is not permitted in POSIX awk formats"
msgstr "fatal : « l » est interdit dans un format awk POSIX"
-#: builtin.c:937
+#: builtin.c:1026
msgid "`L' is meaningless in awk formats; ignored"
msgstr "« L » n'a aucun sens dans un format awk ; ignoré"
-#: builtin.c:941
+#: builtin.c:1030
msgid "fatal: `L' is not permitted in POSIX awk formats"
msgstr "fatal : « L » est interdit dans un format awk POSIX"
-#: builtin.c:954
+#: builtin.c:1043
msgid "`h' is meaningless in awk formats; ignored"
msgstr "« h » n'a aucun sens dans un format awk ; ignoré"
-#: builtin.c:958
+#: builtin.c:1047
msgid "fatal: `h' is not permitted in POSIX awk formats"
msgstr "fatal : « h » est interdit dans un format awk POSIX"
-#: builtin.c:1271
+#: builtin.c:1463
#, c-format
msgid "[s]printf: value %g is out of range for `%%%c' format"
msgstr "[s]printf : valeur %g hors limite pour le format « %%%c »"
-#: builtin.c:1331
+#: builtin.c:1561
#, c-format
msgid "ignoring unknown format specifier character `%c': no argument converted"
msgstr "caractère de format inconnu « %c » ignoré : aucun argument converti"
-#: builtin.c:1336
+#: builtin.c:1566
msgid "fatal: not enough arguments to satisfy format string"
msgstr "fatal : pas assez d'arguments pour satisfaire la chaîne de formatage"
-#: builtin.c:1338
+#: builtin.c:1568
msgid "^ ran out for this one"
msgstr "^ à court pour celui-ci"
-#: builtin.c:1345
+#: builtin.c:1575
msgid "[s]printf: format specifier does not have control letter"
msgstr "[s]printf : spécification de format sans lettre de contrôle"
-#: builtin.c:1348
+#: builtin.c:1578
msgid "too many arguments supplied for format string"
msgstr "trop d'arguments pour la chaîne de formatage"
-#: builtin.c:1422 builtin.c:1433
+#: builtin.c:1634
+msgid "sprintf: no arguments"
+msgstr "sprintf : aucun argument"
+
+#: builtin.c:1657 builtin.c:1668
msgid "printf: no arguments"
msgstr "printf : aucun argument"
-#: builtin.c:1474
+#: builtin.c:1711
msgid "sqrt: received non-numeric argument"
msgstr "sqrt : l'argument n'est pas numérique"
-#: builtin.c:1478
+#: builtin.c:1715
#, c-format
msgid "sqrt: called with negative argument %g"
msgstr "sqrt : appelé avec un argument négatif %g"
-#: builtin.c:1502
+#: builtin.c:1746
#, c-format
msgid "substr: length %g is not >= 1"
msgstr "substr : la longueur %g n'est pas >= 1"
-#: builtin.c:1504
+#: builtin.c:1748
#, c-format
msgid "substr: length %g is not >= 0"
msgstr "substr : la longueur %g n'est pas >= 0"
-#: builtin.c:1511
+#: builtin.c:1755
#, c-format
msgid "substr: non-integer length %g will be truncated"
msgstr "substr : la longueur %g n'est pas entière, elle sera tronquée"
-#: builtin.c:1516
+#: builtin.c:1760
#, c-format
msgid "substr: length %g too big for string indexing, truncating to %g"
msgstr "substr : la longueur %g est trop grande, tronquée à %g"
-#: builtin.c:1528
+#: builtin.c:1772
#, c-format
msgid "substr: start index %g is invalid, using 1"
msgstr "substr : l'index de début %g n'est pas valide, utilisation de 1"
-#: builtin.c:1533
+#: builtin.c:1777
#, c-format
msgid "substr: non-integer start index %g will be truncated"
msgstr "substr : l'index de début %g n'est pas un entier, il sera tronqué"
-#: builtin.c:1558
+#: builtin.c:1802
msgid "substr: source string is zero length"
msgstr "substr : la chaîne source est de longueur nulle"
-#: builtin.c:1574
+#: builtin.c:1818
#, c-format
msgid "substr: start index %g is past end of string"
msgstr "substr : l'index de début %g est au-delà de la fin de la chaîne"
-#: builtin.c:1582
+#: builtin.c:1826
#, c-format
msgid ""
"substr: length %g at start index %g exceeds length of first argument (%lu)"
@@ -767,237 +764,1125 @@ msgstr ""
"substr : la longueur %g à partir de %g dépasse la fin du 1er argument (%lu)"
# Exemple : gawk --lint 'BEGIN { PROCINFO["strftime"]=123 ; print strftime() }'
-#: builtin.c:1655
+#: builtin.c:1900
msgid "strftime: format value in PROCINFO[\"strftime\"] has numeric type"
msgstr ""
"strftime : la valeur de formatage PROCINFO[\"strftime\"] est de type "
"numérique"
-#: builtin.c:1678
+#: builtin.c:1923
msgid "strftime: received non-numeric second argument"
msgstr "strftime : le second argument n'est pas numérique"
-#: builtin.c:1681
+#: builtin.c:1927
msgid "strftime: second argument less than 0 or too big for time_t"
-msgstr ""
+msgstr "strftime: second argument négatif ou trop grand pour time_t"
-#: builtin.c:1687
+#: builtin.c:1934
msgid "strftime: received non-string first argument"
msgstr "strftim : le premier argument n'est pas une chaîne"
-#: builtin.c:1693
+#: builtin.c:1941
msgid "strftime: received empty format string"
msgstr "strftime : la chaîne de formatage est vide"
-#: builtin.c:1759
+#: builtin.c:2007
msgid "mktime: received non-string argument"
msgstr "mktime : l'argument n'est pas une chaîne"
-#: builtin.c:1776
+#: builtin.c:2024
msgid "mktime: at least one of the values is out of the default range"
msgstr ""
"mktime : au moins l'une des valeurs est en dehors de la plage par défaut"
-#: builtin.c:1811
+#: builtin.c:2059
msgid "'system' function not allowed in sandbox mode"
msgstr "La fonction « system » est interdite en isolement (mode sandbox)"
-#: builtin.c:1816
+#: builtin.c:2064
msgid "system: received non-string argument"
msgstr "system : l'argument n'est pas une chaîne"
-#: builtin.c:1871 eval.c:1159 eval.c:1790 eval.c:1803
-#, c-format
-msgid "reference to uninitialized variable `%s'"
-msgstr "référence à une variable non initialisée « %s »"
-
-#: builtin.c:1938
+#: builtin.c:2184
#, c-format
msgid "reference to uninitialized field `$%d'"
msgstr "référence à un champ non initialisé « $%d »"
-#: builtin.c:2025
+#: builtin.c:2271
msgid "tolower: received non-string argument"
msgstr "tolower : l'argument n'est pas une chaîne"
-#: builtin.c:2059
+#: builtin.c:2305
msgid "toupper: received non-string argument"
msgstr "toupper : l'argument n'est pas une chaîne"
-#: builtin.c:2095
+#: builtin.c:2341 mpfr.c:672
msgid "atan2: received non-numeric first argument"
msgstr "atan2 : le premier argument n'est pas numérique"
-#: builtin.c:2097
+#: builtin.c:2343 mpfr.c:674
msgid "atan2: received non-numeric second argument"
msgstr "atan2 : le second argument n'est pas numérique"
-#: builtin.c:2116
+#: builtin.c:2362
msgid "sin: received non-numeric argument"
msgstr "sin : l'argument n'est pas numérique"
-#: builtin.c:2132
+#: builtin.c:2378
msgid "cos: received non-numeric argument"
msgstr "cos : l'argument n'est pas numérique"
-#: builtin.c:2185
+#: builtin.c:2431 mpfr.c:1156
msgid "srand: received non-numeric argument"
msgstr "srand : l'argument n'est pas numérique"
-#: builtin.c:2216
+#: builtin.c:2462
msgid "match: third argument is not an array"
msgstr "match : le 3e argument n'est pas un tableau"
-#: builtin.c:2480
+#: builtin.c:2734
msgid "gensub: third argument of 0 treated as 1"
msgstr "gensub : le 3e argument vaut 0, il sera traité comme un 1"
-#: builtin.c:2773
+#: builtin.c:3030
msgid "lshift: received non-numeric first argument"
msgstr "lshift : le premier argument n'est pas numérique"
-#: builtin.c:2775
+#: builtin.c:3032
msgid "lshift: received non-numeric second argument"
msgstr "lshift : le second argument reçu n'est pas numérique"
-#: builtin.c:2781
+#: builtin.c:3038
#, c-format
-msgid "lshift(%lf, %lf): negative values will give strange results"
+msgid "lshift(%f, %f): negative values will give strange results"
msgstr ""
-"lshift(%lf, %lf) : les valeurs négatives donneront des résultats inattendus"
+"lshift(%f, %f) : les valeurs négatives donnent des résultats inattendus"
-#: builtin.c:2783
+#: builtin.c:3040
#, c-format
-msgid "lshift(%lf, %lf): fractional values will be truncated"
-msgstr "lshift(%lf, %lf) : les valeurs non entières seront tronquées"
+msgid "lshift(%f, %f): fractional values will be truncated"
+msgstr "lshift(%f, %f) : les valeurs non entières seront tronquées"
-#: builtin.c:2785
+#: builtin.c:3042
#, c-format
-msgid "lshift(%lf, %lf): too large shift value will give strange results"
-msgstr ""
-"lshift(%lf, %lf) : un décalage trop grand donnera des résultats inattendus"
+msgid "lshift(%f, %f): too large shift value will give strange results"
+msgstr "lshift(%f, %f) : un décalage trop grand donne des résultats inattendus"
-#: builtin.c:2810
+#: builtin.c:3067
msgid "rshift: received non-numeric first argument"
msgstr "rshift : le premier argument n'est pas numérique"
-#: builtin.c:2812
+#: builtin.c:3069
msgid "rshift: received non-numeric second argument"
msgstr "rshift : le second argument reçu n'est pas numérique"
-#: builtin.c:2818
+#: builtin.c:3075
#, c-format
-msgid "rshift(%lf, %lf): negative values will give strange results"
+msgid "rshift(%f, %f): negative values will give strange results"
msgstr ""
-"rshift(%lf, %lf) : les valeurs négatives donneront des résultats inattendus"
+"rshift(%f, %f) : les valeurs négatives donneront des résultats inattendus"
-#: builtin.c:2820
+#: builtin.c:3077
#, c-format
-msgid "rshift(%lf, %lf): fractional values will be truncated"
-msgstr "rshift(%lf, %lf) : les valeurs non entières seront tronquées"
+msgid "rshift(%f, %f): fractional values will be truncated"
+msgstr "rshift(%f, %f) : les valeurs non entières seront tronquées"
-#: builtin.c:2822
+#: builtin.c:3079
#, c-format
-msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgid "rshift(%f, %f): too large shift value will give strange results"
msgstr ""
-"rshift(%lf, %lf) : un décalage trop grand donnera des résultats inattendus"
+"rshift(%f, %f) : un décalage trop grand donnera des résultats inattendus"
-#: builtin.c:2847
-msgid "and: received non-numeric first argument"
-msgstr "and : le premier argument n'est pas numérique"
+#: builtin.c:3104 mpfr.c:968
+msgid "and: called with less than two arguments"
+msgstr "and : appelé avec moins de 2 arguments"
-#: builtin.c:2849
-msgid "and: received non-numeric second argument"
-msgstr "and : le second argument reçu n'est pas numérique"
+#: builtin.c:3109
+#, c-format
+msgid "and: argument %d is non-numeric"
+msgstr "and : l'argument %d n'est pas numérique"
-#: builtin.c:2855
+#: builtin.c:3113
#, c-format
-msgid "and(%lf, %lf): negative values will give strange results"
+msgid "and: argument %d negative value %g will give strange results"
msgstr ""
-"and(%lf, %lf) : les valeurs négatives donneront des résultats inattendus"
+"and : l'argument %d est négatif (%g) ce qui aura des résultats inattendus"
-#: builtin.c:2857
+#: builtin.c:3136 mpfr.c:1000
+msgid "or: called with less than two arguments"
+msgstr "or : appelé avec moins de 2 arguments"
+
+#: builtin.c:3141
#, c-format
-msgid "and(%lf, %lf): fractional values will be truncated"
-msgstr "and(%lf, %lf): les valeurs non entières seront tronquées"
+msgid "or: argument %d is non-numeric"
+msgstr "or : l'argument %d n'est pas numérique"
-#: builtin.c:2882
-msgid "or: received non-numeric first argument"
-msgstr "or : le premier argument n'est pas numérique"
+#: builtin.c:3145
+#, c-format
+msgid "or: argument %d negative value %g will give strange results"
+msgstr ""
+"or : l'argument %d est négatif (%g) ce qui aura des résultats inattendus"
-#: builtin.c:2884
-msgid "or: received non-numeric second argument"
-msgstr "or : le second argument reçu n'est pas numérique"
+#: builtin.c:3167 mpfr.c:1031
+msgid "xor: called with less than two arguments"
+msgstr "xor : appelé avec moins de 2 arguments"
+
+#: builtin.c:3173
+#, c-format
+msgid "xor: argument %d is non-numeric"
+msgstr "xor : l'argument %d n'est pas numérique"
-#: builtin.c:2890
+#: builtin.c:3177
#, c-format
-msgid "or(%lf, %lf): negative values will give strange results"
+msgid "xor: argument %d negative value %g will give strange results"
msgstr ""
-"or(%lf, %lf) : les valeurs négatives donneront des résultats inattendus"
+"xor : l'argument %d est négatif (%g) ce qui aura des résultats inattendus"
+
+#: builtin.c:3202 mpfr.c:787
+msgid "compl: received non-numeric argument"
+msgstr "compl : l'argument n'est pas numérique"
+
+#: builtin.c:3208
+#, c-format
+msgid "compl(%f): negative value will give strange results"
+msgstr "compl(%f) : les valeurs négatives donneront des résultats inattendus"
-#: builtin.c:2892
+#: builtin.c:3210
#, c-format
-msgid "or(%lf, %lf): fractional values will be truncated"
-msgstr "or(%lf, %lf) : les valeurs non entières seront tronquées"
+msgid "compl(%f): fractional value will be truncated"
+msgstr "compl(%f) : les valeurs non entières seront tronquées"
-#: builtin.c:2920
-msgid "xor: received non-numeric first argument"
-msgstr "xor : le premier argument n'est pas numérique"
+#: builtin.c:3379
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext : « %s » n'est pas dans un catégorie valide de la locale"
+
+#: command.y:225
+#, c-format
+msgid "Type (g)awk statement(s). End with the command \"end\"\n"
+msgstr "Entrez des instructions (g)awk. Terminez avec « end »\n"
-#: builtin.c:2922
-msgid "xor: received non-numeric second argument"
-msgstr "xor : le second argument reçu n'est pas numérique"
+#: command.y:289
+#, c-format
+msgid "invalid frame number: %d"
+msgstr "numéro de trame incorrect : %d"
+
+#: command.y:295
+#, c-format
+msgid "info: invalid option - \"%s\""
+msgstr "info : option incorrecte - « %s »"
+
+#: command.y:321
+#, c-format
+msgid "source \"%s\": already sourced."
+msgstr "import source « %s » : déjà intégré."
-#: builtin.c:2928
+#: command.y:326
#, c-format
-msgid "xor(%lf, %lf): negative values will give strange results"
+msgid "save \"%s\": command not permitted."
+msgstr "sauve « %s » : commande interdite."
+
+#: command.y:339
+msgid "Can't use command `commands' for breakpoint/watchpoint commands"
msgstr ""
-"xor(%lf, %lf) : les valeurs négatives donneront des résultats inattendus"
+"Impossible d'utiliser « commands » pour des points d'arrêt ou de surveillance"
+
+#: command.y:341
+msgid "no breakpoint/watchpoint has been set yet"
+msgstr "Aucun point d'arrêt ou de surveillance défini"
+
+#: command.y:343
+msgid "invalid breakpoint/watchpoint number"
+msgstr "numéro de point d'arrêt ou de surveillance incorrect"
-#: builtin.c:2930
+#: command.y:348
#, c-format
-msgid "xor(%lf, %lf): fractional values will be truncated"
-msgstr "xor(%lf, %lf) : les valeurs non entières seront tronquées"
+msgid "Type commands for when %s %d is hit, one per line.\n"
+msgstr ""
+"Entrez les commandes exécutées lors de l'appui de %s %d, une par ligne.\n"
-#: builtin.c:2954 builtin.c:2960
-msgid "compl: received non-numeric argument"
-msgstr "compl : l'argument n'est pas numérique"
+#: command.y:350
+#, c-format
+msgid "End with the command \"end\"\n"
+msgstr "Terminez par la commande « end »\n"
+
+#: command.y:357
+msgid "`end' valid only in command `commands' or `eval'"
+msgstr "« end » n'est valable que dans « commands » ou « eval »"
+
+#: command.y:367
+msgid "`silent' valid only in command `commands'"
+msgstr "« silent » n'est valable que dans « commands »"
+
+#: command.y:373
+#, c-format
+msgid "trace: invalid option - \"%s\""
+msgstr "trace : option incorrecte - « %s »"
+
+#: command.y:387
+msgid "condition: invalid breakpoint/watchpoint number"
+msgstr "condition : numéro de point d'arrêt ou de surveillance incorrect"
+
+#: command.y:449
+msgid "argument not a string"
+msgstr "l'argument n'est pas une chaîne"
-#: builtin.c:2962
+#: command.y:459 command.y:464
#, c-format
-msgid "compl(%lf): negative value will give strange results"
-msgstr "compl(%lf) : les valeurs négatives donneront des résultats inattendus"
+msgid "option: invalid parameter - \"%s\""
+msgstr "option : paramètre incorrect - « %s »"
-#: builtin.c:2964
+#: command.y:474
#, c-format
-msgid "compl(%lf): fractional value will be truncated"
-msgstr "compl(%lf) : les valeurs non entières seront tronquées"
+msgid "no such function - \"%s\""
+msgstr "fonction inconnue - « %s »"
-#: builtin.c:3133
+#: command.y:531
#, c-format
-msgid "dcgettext: `%s' is not a valid locale category"
-msgstr "dcgettext : « %s » n'est pas dans un catégorie valide de la locale"
+msgid "enable: invalid option - \"%s\""
+msgstr "enable : option incorrecte - « %s »"
+
+#: command.y:597
+#, c-format
+msgid "invalid range specification: %d - %d"
+msgstr "plage non valable : %d - %d"
+
+#: command.y:659
+msgid "non-numeric value for field number"
+msgstr "numéro de champ non numérique"
+
+#: command.y:680 command.y:687
+msgid "non-numeric value found, numeric expected"
+msgstr "valeur non numérique trouvée, nombre attendu"
+
+#: command.y:712 command.y:718
+msgid "non-zero integer value"
+msgstr "valeur entière non nulle"
+
+#: command.y:817
+msgid ""
+"backtrace [N] - print trace of all or N innermost (outermost if N < 0) "
+"frames."
+msgstr ""
+"backtrace [N] - affiche la trace de tout ou des N dernières trames (du début "
+"si N < 0)."
+
+#: command.y:819
+msgid ""
+"break [[filename:]N|function] - set breakpoint at the specified location."
+msgstr ""
+"break [[fichier:]N|fonction] - définit un point d'arrêt à l'endroit indiqué."
+
+#: command.y:821
+msgid "clear [[filename:]N|function] - delete breakpoints previously set."
+msgstr "clear [[fichier:]N|fonction] - détruit un point d'arrêt existant."
+
+#: command.y:823
+msgid ""
+"commands [num] - starts a list of commands to be executed at a "
+"breakpoint(watchpoint) hit."
+msgstr ""
+"commands [no] - débute une liste de commande à lancer aux points d'arrêt ou "
+"de surveillance."
+
+#: command.y:825
+msgid "condition num [expr] - set or clear breakpoint or watchpoint condition."
+msgstr ""
+"condition no [expr] - défini ou détruit une condition d'arrêt ou de "
+"surveillance."
+
+#: command.y:827
+msgid "continue [COUNT] - continue program being debugged."
+msgstr "continue [NB] - continue le programme en cours."
+
+#: command.y:829
+msgid "delete [breakpoints] [range] - delete specified breakpoints."
+msgstr "delete [points d'arrêt] [plage] - détruit les points d'arrêt indiqués."
+
+#: command.y:831
+msgid "disable [breakpoints] [range] - disable specified breakpoints."
+msgstr ""
+"disable [points d'arrêt] [plage] - désactive les points d'arrêt indiqués."
+
+#: command.y:833
+msgid "display [var] - print value of variable each time the program stops."
+msgstr "display [var] - affiche la valeur de la variable à chaque arrêt."
+
+#: command.y:835
+msgid "down [N] - move N frames down the stack."
+msgstr "down [N] - descend de N trames dans la pile."
+
+#: command.y:837
+msgid "dump [filename] - dump instructions to file or stdout."
+msgstr ""
+"dump [fichier] - vide les instructions vers la sortie standard ou un fichier."
+
+#: command.y:839
+msgid "enable [once|del] [breakpoints] [range] - enable specified breakpoints."
+msgstr ""
+"enable [once|del] [points d'arrêt] [plage] - active les points d'arrêt."
+
+#: command.y:841
+msgid "end - end a list of commands or awk statements."
+msgstr "end - termine une liste de commandes ou d'instructions awk."
+
+#: command.y:843
+msgid "eval stmt|[p1, p2, ...] - evaluate awk statement(s)."
+msgstr "eval instructions|[p1, p2, ...] - évalue des instructions awk."
+
+#: command.y:845
+msgid "finish - execute until selected stack frame returns."
+msgstr "finish - exécute jusqu'au retour de la trame sélectionnée de la pile."
+
+#: command.y:847
+msgid "frame [N] - select and print stack frame number N."
+msgstr "frame [N] - sélectionne et affiche la trame N de la pile."
+
+#: command.y:849
+msgid "help [command] - print list of commands or explanation of command."
+msgstr ""
+"help [commande] - affiche la liste des commandes ou explique la commande."
+
+#: command.y:851
+msgid "ignore N COUNT - set ignore-count of breakpoint number N to COUNT."
+msgstr "ignore N NB - ignore les NB prochaines occurrences du point d'arrêt N."
+
+#: command.y:853
+msgid ""
+"info topic - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch."
+msgstr ""
+"info sujet - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch."
+
+#: command.y:855
+msgid "list [-|+|[filename:]lineno|function|range] - list specified line(s)."
+msgstr ""
+"list [-|+|[fichier:]no_ligne|fonction|plage] - affiche les lignes indiquées."
+
+#: command.y:857
+msgid "next [COUNT] - step program, proceeding through subroutine calls."
+msgstr "next [NB] - avance ligne par ligne, sans détailler les sous-routines."
+
+#: command.y:859
+msgid ""
+"nexti [COUNT] - step one instruction, but proceed through subroutine calls."
+msgstr ""
+"nexti [NB] - avance d'une instruction, sans détailler les sous-routines."
+
+#: command.y:861
+msgid "option [name[=value]] - set or display debugger option(s)."
+msgstr "option [nom[=valeur]] - affiche ou définit les options du débogueur."
+
+#: command.y:863
+msgid "print var [var] - print value of a variable or array."
+msgstr "print var [var] - affiche la valeur d'une variable ou d'un tableau."
+
+#: command.y:865
+msgid "printf format, [arg], ... - formatted output."
+msgstr "printf format, [arg], ... - sortie formatée."
+
+#: command.y:867
+msgid "quit - exit debugger."
+msgstr "quit - sort du débogueur."
+
+#: command.y:869
+msgid "return [value] - make selected stack frame return to its caller."
+msgstr "return [valeur] - fait revenir à son appelant la trame sélecionnée."
+
+#: command.y:871
+msgid "run - start or restart executing program."
+msgstr "run - démarre et redémarre l'exécution du programme."
+
+#: command.y:874
+msgid "save filename - save commands from the session to file."
+msgstr ""
+"save fichier - enregistre les commandes de la sessions dans un fichier."
+
+#: command.y:877
+msgid "set var = value - assign value to a scalar variable."
+msgstr "set var = valeur - assigne une valeur à une variable scalaire."
+
+#: command.y:879
+msgid ""
+"silent - suspends usual message when stopped at a breakpoint/watchpoint."
+msgstr ""
+"silent - suspend les messages habituels lors des points d'arrêt et de "
+"surveillance."
+
+#: command.y:881
+msgid "source file - execute commands from file."
+msgstr "source fichier - exécute les commandes du fichier."
+
+#: command.y:883
+msgid "step [COUNT] - step program until it reaches a different source line."
+msgstr "step [NB] - avance jusqu'à une ligne différente du code source."
+
+#: command.y:885
+msgid "stepi [COUNT] - step one instruction exactly."
+msgstr "stepi [NB] - avance d'une instruction exactement."
+
+#: command.y:887
+msgid "tbreak [[filename:]N|function] - set a temporary breakpoint."
+msgstr "tbreak [[fichier:]N|fonction] - définit un point d'arrêt temporaire."
+
+#: command.y:889
+msgid "trace on|off - print instruction before executing."
+msgstr "trace on|off - affiche les instructions avant de les exécuter."
+
+#: command.y:891
+msgid "undisplay [N] - remove variable(s) from automatic display list."
+msgstr ""
+"undisplay [N] - retire la ou les variables de la liste d'affichage "
+"automatique."
+
+#: command.y:893
+msgid ""
+"until [[filename:]N|function] - execute until program reaches a different "
+"line or line N within current frame."
+msgstr ""
+"until [[fichier:]N|fonction] - exécution jusqu'à dépasser la ligne courant "
+"ou la ligne N, dans la trame actuelle."
+
+#: command.y:895
+msgid "unwatch [N] - remove variable(s) from watch list."
+msgstr "unwatch [N] - enlève la ou les variables de la liste de surveillance."
+
+#: command.y:897
+msgid "up [N] - move N frames up the stack."
+msgstr "up [N] - remonte de N trames dans la pile."
+
+#: command.y:899
+msgid "watch var - set a watchpoint for a variable."
+msgstr "watch var - définit un point de surveillance pour une variable."
+
+#: command.y:1011 debug.c:401 msg.c:135
+#, c-format
+msgid "error: "
+msgstr "erreur : "
+
+#: command.y:1051
+#, c-format
+msgid "can't read command (%s)\n"
+msgstr "impossible de lire la commande (%s)\n"
+
+#: command.y:1065
+#, c-format
+msgid "can't read command (%s)"
+msgstr "impossible de lire la commande (%s)"
+
+#: command.y:1116
+msgid "invalid character in command"
+msgstr "la commande contient un caractère incorrect"
+
+#: command.y:1152
+#, c-format
+msgid "unknown command - \"%.*s\", try help"
+msgstr "commande inconnue - « %.*s », essayez « help »"
+
+#: command.y:1222
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: command.y:1284
+msgid "invalid character"
+msgstr "Caractère incorrect"
+
+#: command.y:1455
+#, c-format
+msgid "undefined command: %s\n"
+msgstr "commande inconnue : %s\n"
+
+#: debug.c:252
+msgid "set or show the number of lines to keep in history file."
+msgstr "affiche ou définit le nombre de lignes du fichier d'historique."
+
+#: debug.c:254
+msgid "set or show the list command window size."
+msgstr "affiche ou définit la taille de fenêtre pour la commande list."
+
+#: debug.c:256
+msgid "set or show gawk output file."
+msgstr "affiche ou définit le fichier de sortie de gawk."
+
+#: debug.c:258
+msgid "set or show debugger prompt."
+msgstr "affiche ou définit l'invite du débogueur."
+
+#: debug.c:260
+msgid "(un)set or show saving of command history (value=on|off)."
+msgstr ""
+"affiche ou (dés)active l'enregistrement de l'historique (valeur=on|off)."
+
+#: debug.c:262
+msgid "(un)set or show saving of options (value=on|off)."
+msgstr "affiche ou (dés)active l'enregistrement des options (valeur=on|off)."
+
+#: debug.c:264
+msgid "(un)set or show instruction tracing (value=on|off)."
+msgstr "affiche ou (dés)active le traçage des instructions (valeur=on|off)."
+
+#: debug.c:345
+msgid "program not running."
+msgstr "le programme n'est pas en cours."
+
+#: debug.c:448 debug.c:606
+#, c-format
+msgid "can't read source file `%s' (%s)"
+msgstr "impossible de lire le fichier source « %s » (%s)"
+
+#: debug.c:453
+#, c-format
+msgid "source file `%s' is empty.\n"
+msgstr "le fichier source « %s » est vide.\n"
+
+#: debug.c:480
+msgid "no current source file."
+msgstr "pas de fichier source courant."
+
+#: debug.c:505
+#, c-format
+msgid "cannot find source file named `%s' (%s)"
+msgstr "impossible de trouver le fichier source nommé « %s » (%s)"
+
+#: debug.c:529
+#, c-format
+msgid "WARNING: source file `%s' modified since program compilation.\n"
+msgstr ""
+"ATTENTION : fichier source « %s » modifié après compilation du programme.\n"
+
+#: debug.c:551
+#, c-format
+msgid "line number %d out of range; `%s' has %d lines"
+msgstr "numéro de ligne %d hors limite ; « %s » a %d lignes"
+
+#: debug.c:611
+#, c-format
+msgid "unexpected eof while reading file `%s', line %d"
+msgstr "fin de fichier inattendue lors de la lecture de « %s », ligne %d"
+
+#: debug.c:620
+#, c-format
+msgid "source file `%s' modified since start of program execution"
+msgstr "fichier source « %s » modifié depuis le début d'exécution du programme"
+
+# c-format
+#: debug.c:732
+#, c-format
+msgid "Current source file: %s\n"
+msgstr "Fichier source courant : %s\n"
+
+#: debug.c:733
+#, c-format
+msgid "Number of lines: %d\n"
+msgstr "Nombre de lignes : %d\n"
+
+#: debug.c:740
+#, c-format
+msgid "Source file (lines): %s (%d)\n"
+msgstr "Fichier source (lignes) : %s (%d)\n"
+
+#: debug.c:754
+msgid ""
+"Number Disp Enabled Location\n"
+"\n"
+msgstr ""
+"Numéro Post Activé Position\n"
+"\n"
+
+#: debug.c:765
+#, c-format
+msgid "\tno of hits = %ld\n"
+msgstr "\tnb occurrences = %ld\n"
+
+#: debug.c:767
+#, c-format
+msgid "\tignore next %ld hit(s)\n"
+msgstr "\tignore %ld prochaines occurrences\n"
+
+#: debug.c:769 debug.c:909
+#, c-format
+msgid "\tstop condition: %s\n"
+msgstr "\tcondition d'arrêt : %s\n"
+
+#: debug.c:771 debug.c:911
+msgid "\tcommands:\n"
+msgstr "\tcommandes :\n"
+
+#: debug.c:793
+#, c-format
+msgid "Current frame: "
+msgstr "Trame courante : "
+
+#: debug.c:796
+#, c-format
+msgid "Called by frame: "
+msgstr "Appelée par la trame : "
+
+#: debug.c:800
+#, c-format
+msgid "Caller of frame: "
+msgstr "Appelant de la trame : "
+
+#: debug.c:818
+#, c-format
+msgid "None in main().\n"
+msgstr "Aucune dans main().\n"
+
+#: debug.c:848
+msgid "No arguments.\n"
+msgstr "Aucun argument.\n"
+
+#: debug.c:849
+msgid "No locals.\n"
+msgstr "Aucune variable locale.\n"
+
+#: debug.c:857
+msgid ""
+"All defined variables:\n"
+"\n"
+msgstr ""
+"Liste des variables définies :\n"
+"\n"
+
+#: debug.c:867
+msgid ""
+"All defined functions:\n"
+"\n"
+msgstr ""
+"Liste des fonctions définies :\n"
+"\n"
+
+#: debug.c:886
+msgid ""
+"Auto-display variables:\n"
+"\n"
+msgstr ""
+"Variables affichées automatiquement :\n"
+"\n"
+
+#: debug.c:889
+msgid ""
+"Watch variables:\n"
+"\n"
+msgstr ""
+"Variables inspectées :\n"
+"\n"
+
+#: debug.c:1029
+#, c-format
+msgid "no symbol `%s' in current context\n"
+msgstr "pas de symbole « %s » dans le contexte actuel\n"
+
+#: debug.c:1041 debug.c:1427
+#, c-format
+msgid "`%s' is not an array\n"
+msgstr "« %s » n'est pas un tableau\n"
+
+#: debug.c:1055
+#, c-format
+msgid "$%ld = uninitialized field\n"
+msgstr "$%ld = champ non initialisé\n"
+
+#: debug.c:1076
+#, c-format
+msgid "array `%s' is empty\n"
+msgstr "le tableau « %s » est vide\n"
+
+#: debug.c:1119 debug.c:1171
+#, c-format
+msgid "[\"%s\"] not in array `%s'\n"
+msgstr "[\"%s\"] n'est pas dans le tableau « %s »\n"
+
+#: debug.c:1175
+#, c-format
+msgid "`%s[\"%s\"]' is not an array\n"
+msgstr "« %s[\"%s\"] » n'est pas un tableau\n"
+
+#: debug.c:1236 debug.c:4964
+#, c-format
+msgid "`%s' is not a scalar variable"
+msgstr "« %s » n'est pas une variable scalaire"
+
+#: debug.c:1258 debug.c:4994
+#, c-format
+msgid "attempt to use array `%s[\"%s\"]' in a scalar context"
+msgstr "tentative d'utilisation du tableau « %s[\"%s\"] » en contexte scalaire"
+
+#: debug.c:1280 debug.c:5005
+#, c-format
+msgid "attempt to use scalar `%s[\"%s\"]' as array"
+msgstr "tentative d'utiliser le scalaire « %s[\"%s\"] » comme tableau"
+
+#: debug.c:1423
+#, c-format
+msgid "`%s' is a function"
+msgstr "« %s » est une fonction"
+
+#: debug.c:1465
+#, c-format
+msgid "watchpoint %d is unconditional\n"
+msgstr "le point de surveillance %d est inconditionnel\n"
+
+#: debug.c:1499
+#, c-format
+msgid "No display item numbered %ld"
+msgstr "Aucune entrée d'affichage numéro %ld"
+
+#: debug.c:1502
+#, c-format
+msgid "No watch item numbered %ld"
+msgstr "Aucune entrée de surveillance numéro %ld"
+
+#: debug.c:1528
+#, c-format
+msgid "%d: [\"%s\"] not in array `%s'\n"
+msgstr "%d: [\"%s\"] n'est pas dans le tableau « %s »\n"
+
+#: debug.c:1767
+msgid "attempt to use scalar value as array"
+msgstr "tentative d'utiliser un scalaire comme tableau"
+
+#: debug.c:1856
+#, c-format
+msgid "Watchpoint %d deleted because parameter is out of scope.\n"
+msgstr ""
+"Point de surveillance %d détruit, car son paramètre est hors contexte.\n"
+
+#: debug.c:1867
+#, c-format
+msgid "Display %d deleted because parameter is out of scope.\n"
+msgstr "Affichage %d détruit, car son paramètre est hors contexte\n"
+
+#: debug.c:1900
+#, c-format
+msgid " in file `%s', line %d\n"
+msgstr "dans le fichier « %s », ligne %d\n"
+
+#: debug.c:1921
+#, c-format
+msgid " at `%s':%d"
+msgstr " à « %s »:%d"
+
+#: debug.c:1937 debug.c:2000
+#, c-format
+msgid "#%ld\tin "
+msgstr "#%ld\tdans "
+
+#: debug.c:1974
+#, c-format
+msgid "More stack frames follow ...\n"
+msgstr "D'autres trames de la pile suivent...\n"
+
+#: debug.c:2017
+msgid "invalid frame number"
+msgstr "Numéro de trame incorrect"
+
+#: debug.c:2200
+#, c-format
+msgid "Note: breakpoint %d (enabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+"Note : point d'arrêt %d (activé, ignore %ld occurrences) déjà défini à %s:%d"
+
+#: debug.c:2207
+#, c-format
+msgid "Note: breakpoint %d (enabled), also set at %s:%d"
+msgstr "Note : point d'arrêt %d (activé) déjà défini à %s:%d"
+
+#: debug.c:2214
+#, c-format
+msgid "Note: breakpoint %d (disabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+"Note : point d'arrêt %d (désactivé, ignore %ld occurrences) déjà défini à %s:"
+"%d"
+
+#: debug.c:2221
+#, c-format
+msgid "Note: breakpoint %d (disabled), also set at %s:%d"
+msgstr "Note : point d'arrêt %d (désactivé) déjà défini à %s:%d"
+
+#: debug.c:2238
+#, c-format
+msgid "Breakpoint %d set at file `%s', line %d\n"
+msgstr "Point d'arrêt %d défini dans le fichier « %s » ligne %d\n"
+
+#: debug.c:2340
+#, c-format
+msgid "Can't set breakpoint in file `%s'\n"
+msgstr "Impossible de définir un point d'arrêt dans le fichier « %s »\n"
+
+#: debug.c:2369 debug.c:2492 debug.c:3350
+#, c-format
+msgid "line number %d in file `%s' out of range"
+msgstr "numéro de ligne %d dans le fichier « %s » hors limite"
+
+#: debug.c:2373
+#, c-format
+msgid "Can't find rule!!!\n"
+msgstr "Règle introuvable !!!\n"
+
+#: debug.c:2375
+#, c-format
+msgid "Can't set breakpoint at `%s':%d\n"
+msgstr "Impossible de définir un point d'arrêt à « %s »:%d\n"
-#: eval.c:412
+#: debug.c:2387
+#, c-format
+msgid "Can't set breakpoint in function `%s'\n"
+msgstr "Impossible de définir un point d'arrêt dans la fonction « %s »\n"
+
+#: debug.c:2403
+#, c-format
+msgid "breakpoint %d set at file `%s', line %d is unconditional\n"
+msgstr ""
+"le point d'arrêt %d défini sur le fichier « %s », ligne %d est "
+"inconditionnel\n"
+
+#: debug.c:2508 debug.c:2530
+#, c-format
+msgid "Deleted breakpoint %d"
+msgstr "Point d'arrêt %d supprimé"
+
+#: debug.c:2514
+#, c-format
+msgid "No breakpoint(s) at entry to function `%s'\n"
+msgstr "Aucun point d'arrêt à l'appel de la fonction « %s »\n"
+
+#: debug.c:2541
+#, c-format
+msgid "No breakpoint at file `%s', line #%d\n"
+msgstr "Pas de point d'arrêt sur le fichier « %s », ligne #%d\n"
+
+#: debug.c:2596 debug.c:2637 debug.c:2657 debug.c:2700
+msgid "invalid breakpoint number"
+msgstr "Numéro de point d'arrêt incorrect"
+
+#: debug.c:2612
+msgid "Delete all breakpoints? (y or n) "
+msgstr "Supprimer tous les points d'arrêt (o ou n) "
+
+#: debug.c:2613 debug.c:2923 debug.c:2976
+msgid "y"
+msgstr "o"
+
+#: debug.c:2662
+#, c-format
+msgid "Will ignore next %ld crossing(s) of breakpoint %d.\n"
+msgstr "Ignorera les prochaines %ld occurrences du point d'arrêt %d.\n"
+
+#: debug.c:2666
+#, c-format
+msgid "Will stop next time breakpoint %d is reached.\n"
+msgstr "S'arrêtera à la prochaine occurrence du point d'arrêt %d.\n"
+
+#: debug.c:2783
+#, c-format
+msgid "Can only debug programs provided with the `-f' option.\n"
+msgstr ""
+"Seuls les programmes fournis via l'option « -f » peuvent être débogués.\n"
+
+#: debug.c:2908
+#, c-format
+msgid "Failed to restart debugger"
+msgstr "Échec de redémarrage du débogueur"
+
+#: debug.c:2922
+msgid "Program already running. Restart from beginning (y/n)? "
+msgstr "Programme en cours. Reprendre depuis le début (o/n) ? "
+
+#: debug.c:2926
+#, c-format
+msgid "Program not restarted\n"
+msgstr "Programme non redémarré\n"
+
+#: debug.c:2936
+#, c-format
+msgid "error: cannot restart, operation not allowed\n"
+msgstr "erreur : impossible de redémarrer, opération interdite\n"
+
+#: debug.c:2942
+#, c-format
+msgid "error (%s): cannot restart, ignoring rest of the commands\n"
+msgstr "erreur (%s) : impossible de redémarrer, suite des commandes ignorées\n"
+
+#: debug.c:2950
+#, c-format
+msgid "Starting program: \n"
+msgstr "Démarrage du programme :\n"
+
+#: debug.c:2959
+#, c-format
+msgid "Program exited %s with exit value: %d\n"
+msgstr "Le programme s'est terminé %s avec le code de retour : %d\n"
+
+#: debug.c:2975
+msgid "The program is running. Exit anyway (y/n)? "
+msgstr "Le programme est en cours. Sortir quand même (o/n) ?"
+
+#: debug.c:3010
+#, c-format
+msgid "Not stopped at any breakpoint; argument ignored.\n"
+msgstr "Auncun arrêt à un point d'arrêt : argument ignoré.\n"
+
+#: debug.c:3015
+#, c-format
+msgid "invalid breakpoint number %d."
+msgstr "point d'arrêt %d incorrect."
+
+#: debug.c:3020
+#, c-format
+msgid "Will ignore next %ld crossings of breakpoint %d.\n"
+msgstr "Les %ld prochaines occurrences du point d'arrêt %d seront ignorées.\n"
+
+#: debug.c:3207
+#, c-format
+msgid "'finish' not meaningful in the outermost frame main()\n"
+msgstr "« finish » n'a pas de sens dans la trame initiale main()\n"
+
+#: debug.c:3212
+#, c-format
+msgid "Run till return from "
+msgstr "S'exécute jusqu'au retour de "
+
+#: debug.c:3255
+#, c-format
+msgid "'return' not meaningful in the outermost frame main()\n"
+msgstr "« return » n'a pas de sens dans la trame initiale main()\n"
+
+#: debug.c:3369
+#, c-format
+msgid "Can't find specified location in function `%s'\n"
+msgstr "Impossible de trouver la position indiquée dans la fonction « %s »\n"
+
+#: debug.c:3377
+#, c-format
+msgid "invalid source line %d in file `%s'"
+msgstr "ligne source %d incorrecte dans le fichier « %s »"
+
+#: debug.c:3392
+#, c-format
+msgid "Can't find specified location %d in file `%s'\n"
+msgstr "Position %d introuvable dans le fichier « %s »\n"
+
+#: debug.c:3424
+#, c-format
+msgid "element not in array\n"
+msgstr "élément absent du tableau\n"
+
+#: debug.c:3424
+#, c-format
+msgid "untyped variable\n"
+msgstr "variable sans type\n"
+
+#: debug.c:3466
+#, c-format
+msgid "Stopping in %s ...\n"
+msgstr "Arrêt dans %s...\n"
+
+#: debug.c:3543
+#, c-format
+msgid "'finish' not meaningful with non-local jump '%s'\n"
+msgstr "« finish » n'a pas de sens avec un saut non local « %s »\n"
+
+#: debug.c:3550
+#, c-format
+msgid "'until' not meaningful with non-local jump '%s'\n"
+msgstr "« until » n'a pas de sens avec un saut non local « %s »\n"
+
+#: debug.c:4185
+msgid "\t------[Enter] to continue or q [Enter] to quit------"
+msgstr "\t---« [Entrée] » continuer ; « q [Entrée] » quitter---"
+
+#: debug.c:4186
+msgid "q"
+msgstr "q"
+
+#: debug.c:5001
+#, c-format
+msgid "[\"%s\"] not in array `%s'"
+msgstr "[\"%s\"] est absent du tableau « %s »"
+
+#: debug.c:5207
+#, c-format
+msgid "sending output to stdout\n"
+msgstr "envoi de la sortie vers stdout\n"
+
+#: debug.c:5247
+msgid "invalid number"
+msgstr "nombre incorrect"
+
+#: debug.c:5381
+#, c-format
+msgid "`%s' not allowed in current context; statement ignored"
+msgstr "« %s » interdit dans ce contexte ; instruction ignorée"
+
+#: debug.c:5389
+msgid "`return' not allowed in current context; statement ignored"
+msgstr "« return » interdit dans ce contexte ; instruction ignorée"
+
+#: debug.c:5590
+#, c-format
+msgid "No symbol `%s' in current context"
+msgstr "Pas de symbole « %s » dans le contexte actuel"
+
+#: dfa.c:1118 dfa.c:1121 dfa.c:1142 dfa.c:1150 dfa.c:1162 dfa.c:1197
+#: dfa.c:1206 dfa.c:1209 dfa.c:1214 dfa.c:1228 dfa.c:1275
+msgid "unbalanced ["
+msgstr "[ non apparié"
+
+#: dfa.c:1174
+msgid "invalid character class"
+msgstr "classe de caractères incorrecte"
+
+#: dfa.c:1316
+msgid "character class syntax is [[:space:]], not [:space:]"
+msgstr "la syntaxe des classes de caractères est [[:space:]], et non [:space:]"
+
+#: dfa.c:1366
+msgid "unfinished \\ escape"
+msgstr "échappement \\ non terminé"
+
+#: dfa.c:1513 regcomp.c:161
+msgid "Invalid content of \\{\\}"
+msgstr "Contenu de \\{\\} incorrect"
+
+#: dfa.c:1516 regcomp.c:176
+msgid "Regular expression too big"
+msgstr "Expression rationnelle trop grande"
+
+#: dfa.c:1936
+msgid "unbalanced ("
+msgstr "( non apparié"
+
+#: dfa.c:2062
+msgid "no syntax specified"
+msgstr "aucune syntaxe indiquée"
+
+#: dfa.c:2070
+msgid "unbalanced )"
+msgstr ") non apparié"
+
+#: eval.c:394
#, c-format
msgid "unknown nodetype %d"
msgstr "type de nœud %d inconnu"
-#: eval.c:423 eval.c:437
+#: eval.c:405 eval.c:419
#, c-format
msgid "unknown opcode %d"
msgstr "code opération %d inconnu"
-#: eval.c:434
+#: eval.c:416
#, c-format
msgid "opcode %s not an operator or keyword"
msgstr "le code opération %s n'est pas un opérateur ou un mot-clef"
-#: eval.c:488
+#: eval.c:472
msgid "buffer overflow in genflags2str"
msgstr "débordement de tampon dans genflag2str"
-#: eval.c:698
+#: eval.c:675
#, c-format
msgid ""
"\n"
@@ -1008,828 +1893,1261 @@ msgstr ""
"\t# Pile des appels de fonctions :\n"
"\n"
-#: eval.c:725
+#: eval.c:704
msgid "`IGNORECASE' is a gawk extension"
msgstr "« IGNORECASE » est une extension gawk"
-#: eval.c:754
+#: eval.c:736
msgid "`BINMODE' is a gawk extension"
msgstr "« BINMODE » est une extension gawk"
-#: eval.c:812
+#: eval.c:794
#, c-format
msgid "BINMODE value `%s' is invalid, treated as 3"
msgstr "la valeur « %s » de BINMODE n'est pas valide, 3 utilisé à la place"
-#: eval.c:902
+#: eval.c:885
#, c-format
msgid "bad `%sFMT' specification `%s'"
msgstr "spécification de « %sFMT » erronée « %s »"
-#: eval.c:980
+#: eval.c:969
msgid "turning off `--lint' due to assignment to `LINT'"
msgstr "désactivation de « --lint » en raison d'une affectation à « LINT »"
-#: eval.c:1127 eval.c:1777
-#, c-format
-msgid "can't use function name `%s' as variable or array"
-msgstr "impossible d'utiliser la fonction « %s » comme variable ou tableau"
-
-#: eval.c:1158 eval.c:1789 eval.c:1802
+#: eval.c:1147
#, c-format
msgid "reference to uninitialized argument `%s'"
msgstr "référence à un argument non initialisé « %s »"
-#: eval.c:1177
+#: eval.c:1148
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "référence à une variable non initialisée « %s »"
+
+#: eval.c:1166
msgid "attempt to field reference from non-numeric value"
msgstr "tentative de référence à un champ via une valeur non numérique"
-#: eval.c:1179
+#: eval.c:1168
msgid "attempt to field reference from null string"
msgstr "tentative de référence à un champ via une chaîne nulle"
-#: eval.c:1185
+#: eval.c:1176
#, c-format
msgid "attempt to access field %ld"
msgstr "tentative d'accès au champ %ld"
-#: eval.c:1194
+#: eval.c:1185
#, c-format
msgid "reference to uninitialized field `$%ld'"
msgstr "référence à un champ non initialisé « $%ld »"
-#: eval.c:1256
+#: eval.c:1272
#, c-format
msgid "function `%s' called with more arguments than declared"
msgstr "la fonction « %s » a été appelée avec trop d'arguments"
-#: eval.c:1437
+#: eval.c:1473
#, c-format
msgid "unwind_stack: unexpected type `%s'"
msgstr "unwind_stack: type « %s » inattendu"
-#: eval.c:1532
+#: eval.c:1569
msgid "division by zero attempted in `/='"
msgstr "tentative de division par zéro dans « /= »"
-#: eval.c:1539
+#: eval.c:1576
#, c-format
msgid "division by zero attempted in `%%='"
msgstr "tentative de division par zéro dans « %%= »"
-#: eval.c:1876 eval.c:2122
-#, c-format
-msgid "attempt to use array `%s[\"%.*s\"]' in a scalar context"
-msgstr ""
-"tentative d'utilisation du tableau « %s[\"%.*s\"] » dans un contexte scalaire"
+#: ext.c:89 ext.c:171
+msgid "extensions are not allowed in sandbox mode"
+msgstr "les extensions sont interdites en isolement (mode sandbox)"
-#: eval.c:1907
-msgid "assignment used in conditional context"
-msgstr "affectation utilisée dans un contexte conditionnel"
+#: ext.c:92
+msgid "-l / @load are gawk extensions"
+msgstr "-l / @load est une extension gawk"
-#: eval.c:1911
-msgid "statement has no effect"
-msgstr "la déclaration est sans effet"
+#: ext.c:95
+msgid "load_ext: received NULL lib_name"
+msgstr "load_ext : lib_name reçu NULL"
-#: eval.c:2343
+#: ext.c:98
#, c-format
-msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
-msgstr "boucle for : la taille du tableau « %s » est passée de %ld à %ld"
+msgid "load_ext: cannot open library `%s' (%s)\n"
+msgstr "load_ext : impossible d'ouvrir la bibliothèque « %s » (%s)\n"
-#: eval.c:2458
+#: ext.c:104
#, c-format
-msgid "function called indirectly through `%s' does not exist"
-msgstr "la fonction indirectement appelée via « %s » n'existe pas"
+msgid ""
+"load_ext: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"
+msgstr ""
+"load_ext : bibliothèque « %s » : ne définit pas "
+"« plugin_is_GPL_compatible » (%s)\n"
-#: eval.c:2470
+#: ext.c:110
#, c-format
-msgid "function `%s' not defined"
-msgstr "fonction « %s » non définie"
+msgid "load_ext: library `%s': cannot call function `%s' (%s)\n"
+msgstr ""
+"load_ext : bibliothèque « %s » : impossible d'appeler la fonction "
+"« %s » (%s)\n"
-#: eval.c:2511
+#: ext.c:114
#, c-format
-msgid "non-redirected `getline' invalid inside `%s' rule"
-msgstr "un « getline » non redirigé n'est pas valable dans une règle « %s »"
+msgid "load_ext: library `%s' initialization routine `%s' failed\n"
+msgstr ""
+"load_ext : bibliothèque « %s » : échec de la routine d'initialisation « %s "
+"»\n"
-#: eval.c:2600
-#, c-format
-msgid "error reading input file `%s': %s"
-msgstr "erreur lors de la lecture du fichier en entrée « %s » : %s"
+#: ext.c:174
+msgid "`extension' is a gawk extension"
+msgstr "« extension » est une extension gawk"
-#: eval.c:2614
+#: ext.c:177
+msgid "extension: received NULL lib_name"
+msgstr "extension : lib_name reçu NULL"
+
+#: ext.c:180
#, c-format
-msgid "`nextfile' cannot be called from a `%s' rule"
-msgstr "« nextfile » ne peut pas être appelé depuis une règle « %s »"
+msgid "extension: cannot open library `%s' (%s)"
+msgstr "extension : impossible d'ouvrir la bibliothèque « %s » (%s)"
-#: eval.c:2694
+#: ext.c:186
#, c-format
-msgid "`next' cannot be called from a `%s' rule"
-msgstr "« next » ne peut pas être appelé depuis une règle « %s »"
+msgid ""
+"extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)"
+msgstr ""
+"extension : bibliothèque « %s » : ne définit pas "
+"« plugin_is_GPL_compatible » (%s)"
-#: eval.c:2760
+#: ext.c:190
#, c-format
-msgid "Sorry, don't know how to interpret `%s'"
-msgstr "Désolé, je ne sais pas comment interpréter « %s »"
+msgid "extension: library `%s': cannot call function `%s' (%s)"
+msgstr ""
+"extension : bibliothèque « %s » : impossible d'appeler la fonction "
+"« %s » (%s)"
-#: ext.c:64
-msgid "extensions are not allowed in sandbox mode"
-msgstr "les extensions sont interdites en isolement (mode sandbox)"
+#: ext.c:221
+msgid "make_builtin: missing function name"
+msgstr "make_builtin : nom de fonction manquant"
-#: ext.c:70 ext.c:75
-msgid "`extension' is a gawk extension"
-msgstr "« extension » est une extension gawk"
+#: ext.c:236
+#, c-format
+msgid "make_builtin: can't redefine function `%s'"
+msgstr "make_builtin : impossible de redéfinir la fonction « %s »"
-#: ext.c:85
+#: ext.c:240
#, c-format
-msgid "fatal: extension: cannot open `%s' (%s)\n"
-msgstr "fatal : extension : impossible d'ouvrir « %s » (%s)\n"
+msgid "make_builtin: function `%s' already defined"
+msgstr "make_builtin : fonction « %s » déjà définie"
-#: ext.c:94
+#: ext.c:244
#, c-format
-msgid ""
-"fatal: extension: library `%s': does not define "
-"`plugin_is_GPL_compatible' (%s)\n"
-msgstr ""
-"fatal : extension : la bibliothèque « %s »ne définit pas "
-"« plugin_is_GPL_compatible » (%s)\n"
+msgid "make_builtin: function name `%s' previously defined"
+msgstr "make_builtin : nom de la fonction « %s » déjà défini"
-#: ext.c:103
+#: ext.c:246
#, c-format
-msgid "fatal: extension: library `%s': cannot call function `%s' (%s)\n"
+msgid "make_builtin: can't use gawk built-in `%s' as function name"
msgstr ""
-"fatal : extension : bibliothèque « %s » : impossible d'appeler la fonction "
-"« %s » (%s)\n"
+"make_builtin : impossible d'utiliser la fonction gawk « %s » comme nom de "
+"fonction"
+
+#: ext.c:249 ext.c:304
+#, c-format
+msgid "make_builtin: negative argument count for function `%s'"
+msgstr "make_builtin : la fonction « %s » a un nombre négatif d'arguments"
-#: ext.c:137
+#: ext.c:276
msgid "extension: missing function name"
msgstr "extension : nom de fonction manquant"
-#: ext.c:142
+#: ext.c:279 ext.c:283
#, 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:151
+#: ext.c:291
#, c-format
msgid "extension: can't redefine function `%s'"
msgstr "extension : impossible de redéfinir la fonction « %s »"
-#: ext.c:155
+#: ext.c:295
#, c-format
msgid "extension: function `%s' already defined"
msgstr "extension : fonction « %s » est déjà définie"
-#: ext.c:160
+#: ext.c:299
#, c-format
msgid "extension: function name `%s' previously defined"
msgstr "extension : nom de la fonction « %s » déjà défini"
-#: ext.c:162
+#: ext.c:301
#, c-format
msgid "extension: can't use gawk built-in `%s' as function name"
msgstr ""
"extension : impossible d'utiliser la fonction interne gawk « %s » comme nom "
"de fonction"
-#: ext.c:166
-#, c-format
-msgid "make_builtin: negative argument count for function `%s'"
-msgstr "make_builtin : la fonction « %s » a un nombre négatif d'arguments"
-
-#: ext.c:269
+#: ext.c:375
#, c-format
msgid "function `%s' defined to take no more than %d argument(s)"
msgstr "fonction « %s » définie comme ayant au maximum« %d » argument(s)"
-#: ext.c:272
+#: ext.c:378
#, c-format
msgid "function `%s': missing argument #%d"
msgstr "fonction « %s » : argument #%d manquant"
-#: ext.c:289
+#: ext.c:395
#, c-format
msgid "function `%s': argument #%d: attempt to use scalar as an array"
msgstr ""
"fonction « %s » : argument #%d : tentative d'utilisation d'un scalaire comme "
"tableau"
-#: ext.c:293
+#: ext.c:399
#, 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 "
"scalaire"
-#: ext.c:306
-msgid "Operation Not Supported"
-msgstr "Opération non disponible"
+#: ext.c:413
+msgid "dynamic loading of library not supported"
+msgstr "chargement dynamique des bibliothèques impossible"
+
+#: extension/filefuncs.c:159
+msgid "chdir: called with incorrect number of arguments, expecting 1"
+msgstr "chdir : appelé avec un nombre d'arguments incorrects, attendu : 1"
+
+#: extension/filefuncs.c:439
+#, c-format
+msgid "stat: unable to read symbolic link `%s'"
+msgstr "stat : impossible de lire le lien symbolique « %s »"
+
+#: extension/filefuncs.c:472
+msgid "stat: called with wrong number of arguments"
+msgstr "stat : appelé avec un nombre d'arguments incorrect"
+
+#: extension/filefuncs.c:479
+msgid "stat: bad parameters"
+msgstr "stat : paramètres incorrects"
+
+#: extension/filefuncs.c:533
+#, c-format
+msgid "fts init: could not create variable %s"
+msgstr "fts init : impossible de créer la variable %s"
+
+#: extension/filefuncs.c:554
+msgid "fts is not supported on this system"
+msgstr "fts n'est pas compatible avec ce système"
+
+#: extension/filefuncs.c:573
+msgid "fill_stat_element: could not create array"
+msgstr "fill_stat_element : impossible de créer le tableau"
+
+#: extension/filefuncs.c:582
+msgid "fill_stat_element: could not set element"
+msgstr "fill_stat_element : impossible de définir l'élément"
-#: field.c:328
+#: extension/filefuncs.c:597
+msgid "fill_path_element: could not set element"
+msgstr "fill_path_element : impossible de définir l'élément"
+
+#: extension/filefuncs.c:613
+msgid "fill_error_element: could not set element"
+msgstr "fill_error_element : impossible de définir l'élément"
+
+#: extension/filefuncs.c:660 extension/filefuncs.c:707
+msgid "fts-process: could not create array"
+msgstr "fts-process : impossible de créer le tableau"
+
+#: extension/filefuncs.c:670 extension/filefuncs.c:717
+#: extension/filefuncs.c:735
+msgid "fts-process: could not set element"
+msgstr "fts-process : impossible de définir l'élément"
+
+#: extension/filefuncs.c:784
+msgid "fts: called with incorrect number of arguments, expecting 3"
+msgstr "fts : appelé avec un nombre d'arguments incorrects, attendu : 3"
+
+#: extension/filefuncs.c:787
+msgid "fts: bad first parameter"
+msgstr "fts : premier paramètre incorrect"
+
+#: extension/filefuncs.c:793
+msgid "fts: bad second parameter"
+msgstr "fts : deuxième paramètre incorrect"
+
+#: extension/filefuncs.c:799
+msgid "fts: bad third parameter"
+msgstr "fts : troisième paramètre incorrect"
+
+#: extension/filefuncs.c:806
+msgid "fts: could not flatten array\n"
+msgstr "fts : impossible d'aplatir le tableau\n"
+
+#: extension/filefuncs.c:824
+msgid "fts: ignoring sneaky FTS_NOSTAT flag. nyah, nyah, nyah."
+msgstr "fts : on ignore le drapeau sournois FTS_NOSTAT..."
+
+#: extension/filefuncs.c:841
+msgid "fts: clear_array() failed\n"
+msgstr "fts : échec de clear_array()\n"
+
+#: extension/fnmatch.c:112
+msgid "fnmatch: called with less than three arguments"
+msgstr "fnmatch : appelé avec moins de 3 arguments"
+
+#: extension/fnmatch.c:115
+msgid "fnmatch: called with more than three arguments"
+msgstr "fnmatch : appelé avec plus de 3 arguments"
+
+#: extension/fnmatch.c:118
+msgid "fnmatch: could not get first argument"
+msgstr "fnmatch : impossible d'obtenir le 1er argument"
+
+#: extension/fnmatch.c:123
+msgid "fnmatch: could not get second argument"
+msgstr "fnmatch : impossible d'obtenir le 2e argument"
+
+#: extension/fnmatch.c:128
+msgid "fnmatch: could not get third argument"
+msgstr "fnmatch : impossible d'obtenir le 3e argument"
+
+#: extension/fnmatch.c:141
+msgid "fnmatch is not implemented on this system\n"
+msgstr "fnmatch n'est pas disponible sur ce système\n"
+
+#: extension/fnmatch.c:173
+msgid "fnmatch init: could not add FNM_NOMATCH variable"
+msgstr "fnmatch init : impossible d'ajouter la variable FNM_NOMATCH"
+
+#: extension/fnmatch.c:183
+#, c-format
+msgid "fnmatch init: could not set array element %s"
+msgstr "fnmatch init : impossible de définir l'élément de tableau %s"
+
+#: extension/fnmatch.c:193
+msgid "fnmatch init: could not install FNM array"
+msgstr "fnmatch init : impossible d'installer le tableau FNM"
+
+#: extension/fork.c:81
+msgid "fork: called with too many arguments"
+msgstr "fork : appelé avec trop d'arguments"
+
+#: extension/fork.c:94
+msgid "fork: PROCINFO is not an array!"
+msgstr "fork : PROCINFO n'est pas un tableau !"
+
+#: extension/fork.c:118
+msgid "waitpid: called with too many arguments"
+msgstr "waitpid : appelé avec trop d'arguments"
+
+#: extension/fork.c:126
+msgid "wait: called with no arguments"
+msgstr "wait : appelé sans argument"
+
+#: extension/fork.c:143
+msgid "wait: called with too many arguments"
+msgstr "wait : appelé avec trop d'arguments"
+
+#: extension/inplace.c:130
+msgid "inplace_begin: in-place editing already active"
+msgstr "inplace_begin : modification sur place déjà active"
+
+#: extension/inplace.c:133 extension/inplace.c:207
+#, c-format
+msgid "inplace_begin: expects 2 arguments but called with %d"
+msgstr "inplace_begin : 2 arguments attendu, appelé avec %d"
+
+#: extension/inplace.c:136
+msgid "inplace_begin: cannot retrieve 1st argument as a string filename"
+msgstr ""
+"inplace_begin : impossible de récupérer le 1er argument comme nom de fichier"
+
+#: extension/inplace.c:144
+#, c-format
+msgid "inplace_begin: disabling in-place editing for invalid FILENAME `%s'"
+msgstr ""
+"inplace_begin : modification sur place annulée pour le fichier incorrect "
+"« %s »"
+
+#: extension/inplace.c:151
+#, c-format
+msgid "inplace_begin: Cannot stat `%s' (%s)"
+msgstr "inplace_begin : stat impossible sur « %s » (%s)"
+
+#: extension/inplace.c:158
+#, c-format
+msgid "inplace_begin: `%s' is not a regular file"
+msgstr "inplace_begin : « %s » n'est pas un fichier ordinaire"
+
+#: extension/inplace.c:169
+#, c-format
+msgid "inplace_begin: mkstemp(`%s') failed (%s)"
+msgstr "inplace_begin : échec de mkstemp('%s') (%s)"
+
+#: extension/inplace.c:178
+#, c-format
+msgid "inplace_begin: chmod failed (%s)"
+msgstr "inplace_begin : échec de la chmod (%s)"
+
+#: extension/inplace.c:185
+#, c-format
+msgid "inplace_begin: dup(stdout) failed (%s)"
+msgstr "inplace_begin : échec de dup(stdout) (%s)"
+
+#: extension/inplace.c:188
+#, c-format
+msgid "inplace_begin: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_begin : échec de dup2(%d, stdout) (%s)"
+
+#: extension/inplace.c:191
+#, c-format
+msgid "inplace_begin: close(%d) failed (%s)"
+msgstr "inplace_begin : échec de close(%d) (%s)"
+
+#: extension/inplace.c:210
+msgid "inplace_end: cannot retrieve 1st argument as a string filename"
+msgstr ""
+"inplace_end : impossible de récupérer le 1er argument comme nom de fichier"
+
+#: extension/inplace.c:217
+msgid "inplace_end: in-place editing not active"
+msgstr "inplace_end : modification sur place non active"
+
+#: extension/inplace.c:223
+#, c-format
+msgid "inplace_end: dup2(%d, stdout) failed (%s)"
+msgstr "ipnlace_end : échec de dup2(%d, stdout) (%s)"
+
+#: extension/inplace.c:226
+#, c-format
+msgid "inplace_end: close(%d) failed (%s)"
+msgstr "inplace_end : échec de close(%d) (%s)"
+
+#: extension/inplace.c:230
+#, c-format
+msgid "inplace_end: fsetpos(stdout) failed (%s)"
+msgstr "inplace_end : échec de fsetpos(stdout) (%s)"
+
+#: extension/inplace.c:243
+#, c-format
+msgid "inplace_end: link(`%s', `%s') failed (%s)"
+msgstr "inplace_end : échec de link('%s', '%s') (%s)"
+
+#: extension/inplace.c:253
+#, c-format
+msgid "inplace_end: rename(`%s', `%s') failed (%s)"
+msgstr "inplace_end : échec de rename('%s', '%s') (%s)"
+
+#: extension/ordchr.c:69
+msgid "ord: called with too many arguments"
+msgstr "ord : appelé avec trop d'arguments"
+
+#: extension/ordchr.c:75
+msgid "ord: called with no arguments"
+msgstr "ord : appelé sans argument"
+
+#: extension/ordchr.c:77
+msgid "ord: called with inappropriate argument(s)"
+msgstr "ord : appelé avec des arguments incorrects"
+
+#: extension/ordchr.c:99
+msgid "chr: called with too many arguments"
+msgstr "chr : appelé avec trop d'arguments"
+
+#: extension/ordchr.c:109
+msgid "chr: called with no arguments"
+msgstr "chr : appelé sans argument"
+
+#: extension/ordchr.c:111
+msgid "chr: called with inappropriate argument(s)"
+msgstr "chr : appelé avec des arguments incorrects"
+
+#: extension/readdir.c:281
+#, c-format
+msgid "dir_take_control_of: opendir/fdopendir failed: %s"
+msgstr "dir_take_control_of : échec de opendir/fdopendir : %s"
+
+#: extension/readfile.c:113
+msgid "readfile: called with too many arguments"
+msgstr "readfile : appelé avec trop d'arguments"
+
+#: extension/readfile.c:137
+msgid "readfile: called with no arguments"
+msgstr "readfile : appelé sans argument"
+
+#: extension/rwarray.c:124
+msgid "writea: called with too many arguments"
+msgstr "writea : appelé avec trop d'arguments"
+
+#: extension/rwarray.c:131
+#, c-format
+msgid "do_writea: argument 0 is not a string\n"
+msgstr "do_writea : l'argument 0 n'est pas une chaîne\n"
+
+#: extension/rwarray.c:137
+#, c-format
+msgid "do_writea: argument 1 is not an array\n"
+msgstr "do_writea : l'argument 1 n'est pas un tableau\n"
+
+#: extension/rwarray.c:184
+#, c-format
+msgid "write_array: could not flatten array\n"
+msgstr "write_array : impossible d'aplatir le tableau\n"
+
+#: extension/rwarray.c:198
+#, c-format
+msgid "write_array: could not release flattened array\n"
+msgstr "write_array : impossible de libérer le tableau aplati\n"
+
+#: extension/rwarray.c:280
+msgid "reada: called with too many arguments"
+msgstr "reada : appelé avec trop d'arguments"
+
+#: extension/rwarray.c:287
+#, c-format
+msgid "do_reada: argument 0 is not a string\n"
+msgstr "do_reada : l'argument 0 n'est pas une chaîne\n"
+
+#: extension/rwarray.c:293
+#, c-format
+msgid "do_reada: argument 1 is not an array\n"
+msgstr "do_reada : l'argument 1 n'est pas un tableau\n"
+
+#: extension/rwarray.c:337
+#, c-format
+msgid "do_reada: clear_array failed\n"
+msgstr "do_reada : échec de clear_array\n"
+
+#: extension/rwarray.c:374
+#, c-format
+msgid "read_array: set_array_element failed\n"
+msgstr "read_array : échec de set_array_element\n"
+
+#: extension/time.c:113
+msgid "gettimeofday: ignoring arguments"
+msgstr "gettimeofday : arguments ignorés"
+
+#: extension/time.c:144
+msgid "gettimeofday: not supported on this platform"
+msgstr "gettimeofday : n'est pas disponible sur cette plateforme"
+
+#: extension/time.c:165
+msgid "sleep: called with too many arguments"
+msgstr "sleep : appelé avec trop d'arguments"
+
+#: extension/time.c:168
+msgid "sleep: missing required numeric argument"
+msgstr "sleep : l'argument numérique requis est absent"
+
+#: extension/time.c:174
+msgid "sleep: argument is negative"
+msgstr "sleep : l'argument est négatif"
+
+#: extension/time.c:208
+msgid "sleep: not supported on this platform"
+msgstr "sleep : n'est pas disponible sur cette plateforme"
+
+#: field.c:345
msgid "NF set to negative value"
msgstr "une valeur négative a été assignée à NF"
-#: field.c:951 field.c:958 field.c:962
+#: field.c:971 field.c:978 field.c:982
msgid "split: fourth argument is a gawk extension"
msgstr "split : le 4e argument est une extension gawk"
-#: field.c:955
+#: field.c:975
msgid "split: fourth argument is not an array"
msgstr "split : le 4e argument n'est pas un tableau"
-#: field.c:969
+#: field.c:989
msgid "split: second argument is not an array"
msgstr "split : le 2e argument n'est pas un tableau"
-#: field.c:973
+#: field.c:993
msgid "split: cannot use the same array for second and fourth args"
msgstr "split : impossible d'utiliser le même tableau comme 2e et 4e argument"
-#: field.c:978
+#: field.c:998
msgid "split: cannot use a subarray of second arg for fourth arg"
msgstr ""
"split : impossible d'utiliser un sous-tableau du 2e argument en 4e argument"
-#: field.c:981
+#: field.c:1001
msgid "split: cannot use a subarray of fourth arg for second arg"
msgstr ""
"split : impossible d'utiliser un sous-tableau du 4e argument en 2e argument"
-#: field.c:1010
+#: field.c:1032
msgid "split: null string for third arg is a gawk extension"
msgstr "split : utiliser une chaîne vide en 3e argument est une extension gawk"
-#: field.c:1050
+#: field.c:1072
msgid "patsplit: fourth argument is not an array"
msgstr "patsplit : le 4e argument n'est pas un tableau"
-#: field.c:1055
+#: field.c:1077
msgid "patsplit: second argument is not an array"
msgstr "patsplit : le 2e argument n'est pas un tableau"
-#: field.c:1061
+#: field.c:1083
msgid "patsplit: third argument must be non-null"
msgstr "patsplit : le 3e argument n'est pas un tableau"
-#: field.c:1065
+#: field.c:1087
msgid "patsplit: cannot use the same array for second and fourth args"
msgstr ""
"patsplit : impossible d'utiliser le même tableau comme 2e et 4e argument"
-#: field.c:1070
+#: field.c:1092
msgid "patsplit: cannot use a subarray of second arg for fourth arg"
msgstr ""
"patsplit : impossible d'utiliser un sous-tableau du 2e argument en 4e "
"argument"
-#: field.c:1073
+#: field.c:1095
msgid "patsplit: cannot use a subarray of fourth arg for second arg"
msgstr ""
"patsplit : impossible d'utiliser un sous-tableau du 4e argument en 2e "
"argument"
-#: field.c:1110
+#: field.c:1133
msgid "`FIELDWIDTHS' is a gawk extension"
msgstr "« FIELDWIDTHS » est une extension gawk"
-#: field.c:1173
+#: field.c:1197
#, c-format
msgid "invalid FIELDWIDTHS value, near `%s'"
-msgstr "valeur de FIELDWIDTHS non valide, près de « %s »"
+msgstr "valeur de FIELDWIDTHS incorrecte, près de « %s »"
-#: field.c:1246
+#: field.c:1270
msgid "null string for `FS' is a gawk extension"
msgstr "utiliser une chaîne vide pour « FS » est une extension gawk"
-#: field.c:1250
+#: field.c:1274
msgid "old awk does not support regexps as value of `FS'"
msgstr ""
"l'ancien awk n'accepte pas les expr. rationnelles comme valeur de « FS »"
-#: field.c:1369
+#: field.c:1393
msgid "`FPAT' is a gawk extension"
msgstr "« FPAT » est une extension gawk"
-#: getopt.c:574 getopt.c:590
+#: gawkapi.c:146
+msgid "awk_value_to_node: received null retval"
+msgstr "awk_value_to_node : retval nul reçu"
+
+#: gawkapi.c:384
+msgid "node_to_awk_value: received null node"
+msgstr "node_to_awk_value : node nul reçu"
+
+#: gawkapi.c:387
+msgid "node_to_awk_value: received null val"
+msgstr "node_to_awk_value : val nul reçu"
+
+#: gawkapi.c:807
+msgid "remove_element: received null array"
+msgstr "remove_element : tableau nul reçu"
+
+#: gawkapi.c:810
+msgid "remove_element: received null subscript"
+msgstr "remove_element : indice nul reçu"
+
+#: gawkapi.c:947
+#, c-format
+msgid "api_flatten_array: could not convert index %d\n"
+msgstr "api_flatten_array : impossible de convertir l'indice %d\n"
+
+#: gawkapi.c:952
+#, c-format
+msgid "api_flatten_array: could not convert value %d\n"
+msgstr "api_flatten_array : impossible de convertir la valeur %d\n"
+
+#: getopt.c:604 getopt.c:633
#, c-format
-msgid "%s: option '%s' is ambiguous\n"
-msgstr "%s : l'option « %s » est ambiguë\n"
+msgid "%s: option '%s' is ambiguous; possibilities:"
+msgstr "%s : l'option « %s » est ambiguë ; possibilités :"
-#: getopt.c:623 getopt.c:627
+#: getopt.c:679 getopt.c:683
#, c-format
msgid "%s: option '--%s' doesn't allow an argument\n"
msgstr "%s : l'option « --%s » n'accepte pas d'argument\n"
-#: getopt.c:636 getopt.c:641
+#: getopt.c:692 getopt.c:697
#, c-format
msgid "%s: option '%c%s' doesn't allow an argument\n"
msgstr "%s : l'option « %c%s » n'accepte pas d'argument\n"
-#: getopt.c:684 getopt.c:703
+#: getopt.c:740 getopt.c:759
#, c-format
msgid "%s: option '--%s' requires an argument\n"
msgstr "%s : l'option « --%s » nécessite un argument\n"
-#: getopt.c:741 getopt.c:744
+#: getopt.c:797 getopt.c:800
#, c-format
msgid "%s: unrecognized option '--%s'\n"
msgstr "%s : option non reconnue « --%s »\n"
-#: getopt.c:752 getopt.c:755
+#: getopt.c:808 getopt.c:811
#, c-format
msgid "%s: unrecognized option '%c%s'\n"
msgstr "%s : option non reconnue « %c%s »\n"
-#: getopt.c:804 getopt.c:807
+#: getopt.c:860 getopt.c:863
#, c-format
msgid "%s: invalid option -- '%c'\n"
-msgstr "%s : option non valide -- « %c »\n"
+msgstr "%s : option incorrecte - « %c »\n"
-#: getopt.c:857 getopt.c:874 getopt.c:1082 getopt.c:1100
+#: getopt.c:916 getopt.c:933 getopt.c:1143 getopt.c:1161
#, c-format
msgid "%s: option requires an argument -- '%c'\n"
-msgstr "%s : l'option requiert un argument -- « %c »\n"
+msgstr "%s : l'option requiert un argument - « %c »\n"
-#: getopt.c:930 getopt.c:946
+#: getopt.c:989 getopt.c:1005
#, c-format
msgid "%s: option '-W %s' is ambiguous\n"
msgstr "%s : l'option « -W %s » est ambiguë\n"
-#: getopt.c:970 getopt.c:988
+#: getopt.c:1029 getopt.c:1047
#, c-format
msgid "%s: option '-W %s' doesn't allow an argument\n"
msgstr "%s : l'option « -W %s » n'accepte pas d'argument\n"
-#: getopt.c:1009 getopt.c:1027
+#: getopt.c:1068 getopt.c:1086
#, c-format
msgid "%s: option '-W %s' requires an argument\n"
msgstr "%s : l'option « -W %s » nécessite un argument\n"
-#: io.c:280
+#: io.c:392
#, c-format
msgid "command line argument `%s' is a directory: skipped"
msgstr "L'argument « %s » de la ligne de commande est un répertoire : ignoré"
-#: io.c:283 io.c:385
+#: io.c:395 io.c:513
#, c-format
msgid "cannot open file `%s' for reading (%s)"
msgstr "impossible d'ouvrir le fichier « %s » en lecture (%s)"
-#: io.c:501
+#: io.c:640
#, c-format
msgid "close of fd %d (`%s') failed (%s)"
msgstr "échec de la fermeture du fd %d (« %s ») : %s"
-#: io.c:578
+#: io.c:716
msgid "redirection not allowed in sandbox mode"
msgstr "les redirections sont interdites en isolement (mode sandbox)"
-#: io.c:612
+#: io.c:750
#, c-format
msgid "expression in `%s' redirection only has numeric value"
msgstr "l'expression dans la redirection « %s » n'a qu'une valeur numérique"
-#: io.c:618
+#: io.c:756
#, c-format
msgid "expression for `%s' redirection has null string value"
msgstr "l'expression dans la redirection « %s » donne une chaîne nulle"
-#: io.c:624
+#: io.c:761
#, c-format
msgid "filename `%s' for `%s' redirection may be result of logical expression"
msgstr ""
"le fichier « %s » de la redirection « %s » pourrait être le résultat d'une "
"expression booléenne"
-#: io.c:667
+#: io.c:809
#, c-format
msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
msgstr "mélange non nécessaire de « > » et « >> » pour le fichier « %.*s »"
-#: io.c:720
+#: io.c:863
#, c-format
msgid "can't open pipe `%s' for output (%s)"
msgstr "impossible d'ouvrir le tube « %s » en sortie (%s)"
-#: io.c:730
+#: io.c:873
#, c-format
msgid "can't open pipe `%s' for input (%s)"
msgstr "impossible d'ouvrir le tube « %s » en entrée (%s)"
-#: io.c:753
+#: io.c:904
#, c-format
msgid "can't open two way pipe `%s' for input/output (%s)"
msgstr ""
"impossible d'ouvrir un tube bidirectionnel « %s » en entrées-sorties (%s)"
-#: io.c:835
+#: io.c:986
#, c-format
msgid "can't redirect from `%s' (%s)"
msgstr "impossible de rediriger depuis « %s » (%s)"
-#: io.c:838
+#: io.c:989
#, c-format
msgid "can't redirect to `%s' (%s)"
msgstr "impossible de rediriger vers « %s » (%s)"
-#: io.c:889
+#: io.c:1040
msgid ""
"reached system limit for open files: starting to multiplex file descriptors"
msgstr ""
"limite système du nombre de fichiers ouverts atteinte : début du "
"multiplexage des descripteurs de fichiers"
-#: io.c:905
+#: io.c:1056
#, c-format
msgid "close of `%s' failed (%s)."
-msgstr "échec de la fermeture de « %s » (%s)"
+msgstr "échec de la fermeture de « %s » (%s)."
-#: io.c:913
+#: io.c:1064
msgid "too many pipes or input files open"
msgstr "trop de fichiers d'entrées ou de tubes ouverts"
-#: io.c:935
+#: io.c:1086
msgid "close: second argument must be `to' or `from'"
msgstr "close : le second argument doit être « to » ou « from »"
-#: io.c:952
+#: io.c:1103
#, c-format
msgid "close: `%.*s' is not an open file, pipe or co-process"
msgstr ""
"close : « %.*s » n'est ni un fichier ouvert, ni un tube ou un co-processus"
-#: io.c:957
+#: io.c:1108
msgid "close of redirection that was never opened"
msgstr "fermeture d'une redirection qui n'a jamais été ouverte"
-#: io.c:1054
+#: io.c:1205
#, c-format
msgid "close: redirection `%s' not opened with `|&', second argument ignored"
msgstr ""
"close : la redirection « %s » n'a pas été ouverte avec « |& », second "
"argument ignoré"
-#: io.c:1070
+#: io.c:1222
#, c-format
msgid "failure status (%d) on pipe close of `%s' (%s)"
msgstr "résultat d'échec (%d) sur la fermeture du tube « %s » (%s)"
-#: io.c:1073
+#: io.c:1225
#, c-format
msgid "failure status (%d) on file close of `%s' (%s)"
msgstr "résultat d'échec (%d) sur la fermeture du fichier « %s » (%s)"
-#: io.c:1093
+#: io.c:1245
#, c-format
msgid "no explicit close of socket `%s' provided"
msgstr "aucune fermeture explicite du connecteur « %s » fournie"
-#: io.c:1096
+#: io.c:1248
#, c-format
msgid "no explicit close of co-process `%s' provided"
msgstr "aucune fermeture explicite du co-processus « %s » fournie"
-#: io.c:1099
+#: io.c:1251
#, c-format
msgid "no explicit close of pipe `%s' provided"
msgstr "aucune fermeture explicite du tube « %s » fournie"
-#: io.c:1102
+#: io.c:1254
#, c-format
msgid "no explicit close of file `%s' provided"
msgstr "aucune fermeture explicite du fichier « %s » fournie"
-#: io.c:1130 io.c:1185 main.c:793 main.c:830
+#: io.c:1284 io.c:1342 main.c:864 main.c:906
#, c-format
msgid "error writing standard output (%s)"
msgstr "erreur lors de l'écriture vers la sortie standard (%s)"
-#: io.c:1134 io.c:1190
+#: io.c:1289 io.c:1348 main.c:866
#, c-format
msgid "error writing standard error (%s)"
msgstr "erreur lors de l'écriture vers l'erreur standard (%s)"
-#: io.c:1142
+#: io.c:1297
#, c-format
msgid "pipe flush of `%s' failed (%s)."
msgstr "échec du vidage du tube « %s » (%s)."
-#: io.c:1145
+#: io.c:1300
#, c-format
msgid "co-process flush of pipe to `%s' failed (%s)."
msgstr "échec du vidage du tube vers « %s » par le co-processus (%s)."
-#: io.c:1148
+#: io.c:1303
#, c-format
msgid "file flush of `%s' failed (%s)."
-msgstr "échec du vidage vers le fichier « %s » (%s)"
+msgstr "échec du vidage vers le fichier « %s » (%s)."
-#: io.c:1263
+#: io.c:1420
#, c-format
msgid "local port %s invalid in `/inet'"
msgstr "le port local %s n'est pas valide dans « /inet »"
-#: io.c:1280
+#: io.c:1438
#, c-format
msgid "remote host and port information (%s, %s) invalid"
msgstr ""
"les informations sur l'hôte et le port distants (%s, %s) ne sont pas valides"
-#: io.c:1432
+#: io.c:1590
#, c-format
msgid "no (known) protocol supplied in special filename `%s'"
msgstr ""
"aucun protocole (connu) n'a été fourni dans le nom de fichier spécial « %s »"
-#: io.c:1446
+#: io.c:1604
#, c-format
msgid "special file name `%s' is incomplete"
msgstr "nom de fichier spécial « %s » incomplet"
-#: io.c:1463
+#: io.c:1621
msgid "must supply a remote hostname to `/inet'"
msgstr "un nom d'hôte distant doit être fourni à « /inet »"
-#: io.c:1481
+#: io.c:1639
msgid "must supply a remote port to `/inet'"
msgstr "un port distant doit être fourni à « /inet »"
-#: io.c:1527
+#: io.c:1685
msgid "TCP/IP communications are not supported"
msgstr "les communications TCP/IP ne sont pas disponibles"
-#: io.c:1694
+#: io.c:1867
#, c-format
msgid "could not open `%s', mode `%s'"
msgstr "impossible d'ouvrir « %s », mode « %s »"
-#: io.c:1748
+#: io.c:1917
#, c-format
msgid "close of master pty failed (%s)"
msgstr "échec de la fermeture du pty maître (%s)"
-#: io.c:1750 io.c:1918 io.c:2075
+#: io.c:1919 io.c:2105 io.c:2305
#, c-format
msgid "close of stdout in child failed (%s)"
msgstr "échec de la fermeture de stdout du processus fils (%s)"
-#: io.c:1753
+#: io.c:1922
#, c-format
msgid "moving slave pty to stdout in child failed (dup: %s)"
msgstr ""
"échec du déplacement du pty esclave vers le stdout du processus fils (dup : "
"%s)"
-#: io.c:1755 io.c:1923
+#: io.c:1924 io.c:2110
#, c-format
msgid "close of stdin in child failed (%s)"
msgstr "échec de fermeture du stdin du processus fils (%s)"
-#: io.c:1758
+#: io.c:1927
#, c-format
msgid "moving slave pty to stdin in child failed (dup: %s)"
msgstr ""
"échec du déplacement du pty esclave vers le stdin du processus fils (dup : "
"%s)"
-#: io.c:1760 io.c:1781
+#: io.c:1929 io.c:1951
#, c-format
msgid "close of slave pty failed (%s)"
msgstr "échec de la fermeture du pty esclave (%s)"
-#: io.c:1859 io.c:1921 io.c:2053 io.c:2078
+#: io.c:2040 io.c:2108 io.c:2276 io.c:2308
#, c-format
msgid "moving pipe to stdout in child failed (dup: %s)"
msgstr "échec du déplacement du tube vers stdout du processus fils (dup : %s)"
-#: io.c:1866 io.c:1926
+#: io.c:2047 io.c:2113
#, c-format
msgid "moving pipe to stdin in child failed (dup: %s)"
msgstr "échec de déplacement du tube vers stdin du processus fils (dup : %s)"
-#: io.c:1886 io.c:2068
+#: io.c:2073 io.c:2298
msgid "restoring stdout in parent process failed\n"
msgstr "échec de la restauration du stdout dans le processus parent\n"
-#: io.c:1894
+#: io.c:2081
msgid "restoring stdin in parent process failed\n"
msgstr "échec de la restauration du stdin dans le processus parent\n"
-#: io.c:1929 io.c:2080 io.c:2094
+#: io.c:2116 io.c:2310 io.c:2324
#, c-format
msgid "close of pipe failed (%s)"
msgstr "échec de la fermeture du tube (%s)"
-#: io.c:1974
+#: io.c:2174
msgid "`|&' not supported"
msgstr "« |& » non disponible"
-#: io.c:2040
+#: io.c:2261
#, c-format
msgid "cannot open pipe `%s' (%s)"
msgstr "impossible d'ouvrir le tube « %s » (%s)"
-#: io.c:2088
+#: io.c:2318
#, c-format
msgid "cannot create child process for `%s' (fork: %s)"
msgstr "impossible de créer le processus fils pour « %s » (fork : %s)"
-#: io.c:2521
+#: io.c:2790
+msgid "register_input_parser: received NULL pointer"
+msgstr "register_input_parser : pointeur NULL reçu"
+
+#: io.c:2818
+#, c-format
+msgid "input parser `%s' conflicts with previously installed input parser `%s'"
+msgstr ""
+"l'analyseur d'entrée « %s » est en conflit avec l'analyseur « %s » déjà "
+"installé"
+
+#: io.c:2825
+#, c-format
+msgid "input parser `%s' failed to open `%s'"
+msgstr "l'analyseur d'entrée « %s » n'a pu ouvrir « %s »"
+
+#: io.c:2845
+msgid "register_output_wrapper: received NULL pointer"
+msgstr "register_output_wrapper : pointeur NULL reçu"
+
+#: io.c:2873
+#, c-format
+msgid ""
+"output wrapper `%s' conflicts with previously installed output wrapper `%s'"
+msgstr ""
+"le filtre de sortie « %s » est en conflit avec le filtre « %s » déjà installé"
+
+#: io.c:2880
+#, c-format
+msgid "output wrapper `%s' failed to open `%s'"
+msgstr "le filtre de sortie « %s » n'a pu ouvrir « %s »"
+
+#: io.c:2901
+msgid "register_output_processor: received NULL pointer"
+msgstr "register_output_processor : pointeur NULL reçu"
+
+#: io.c:2930
+#, c-format
+msgid ""
+"two-way processor `%s' conflicts with previously installed two-way processor "
+"`%s'"
+msgstr ""
+"le gestionnaire bidirectionnel « %s » est en conflit avec le gestionnaire "
+"« %s » déjà installé"
+
+#: io.c:2939
+#, c-format
+msgid "two way processor `%s' failed to open `%s'"
+msgstr "le gestionnaire bidirectionnel « %s » n'a pu ouvrir « %s »"
+
+#: io.c:3064
#, c-format
msgid "data file `%s' is empty"
msgstr "le fichier de données « %s » est vide"
-#: io.c:2562 io.c:2570
+#: io.c:3106 io.c:3114
msgid "could not allocate more input memory"
msgstr "impossible d'allouer plus de mémoire d'entrée"
-#: io.c:3128
+#: io.c:3682
msgid "multicharacter value of `RS' is a gawk extension"
msgstr ""
"l'utilisation d'un « RS » de plusieurs caractères est une extension gawk"
-#: io.c:3233
+#: io.c:3771
msgid "IPv6 communication is not supported"
msgstr "les communications IPv6 ne sont pas disponibles"
-#: main.c:364
-msgid "`-m[fr]' option irrelevant in gawk"
-msgstr "l'option « -m[fr] » n'est pas pertinente en gawk"
-
-#: main.c:366
-msgid "-m option usage: `-m[fr] nnn'"
-msgstr "utilisation de l'option « -m » : « -m[fr] nnn »"
-
-#: main.c:389
+#: main.c:405
msgid "empty argument to `-e/--source' ignored"
msgstr "argument vide de l'option « -e / --source » ignoré"
-#: main.c:460
+#: main.c:495
#, c-format
msgid "%s: option `-W %s' unrecognized, ignored\n"
msgstr "%s : option « -W %s » non reconnue, ignorée\n"
-#: main.c:513
+#: main.c:541
#, c-format
msgid "%s: option requires an argument -- %c\n"
-msgstr "%s : l'option requiert un argument -- %c\n"
+msgstr "%s : l'option requiert un argument - %c\n"
-#: main.c:534
+#: main.c:562
msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
msgstr ""
"variable d'environnement « POSIXLY__CORRECT » définie : activation de « --"
"posix »"
-#: main.c:540
+#: main.c:568
msgid "`--posix' overrides `--traditional'"
msgstr "« --posix » prend le pas sur « --traditional »"
-#: main.c:551
+#: main.c:579
msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
msgstr ""
"« --posix » et « --traditional » prennent le pas sur « --non-decimal-data »"
-#: main.c:555
+#: main.c:583
#, c-format
msgid "running %s setuid root may be a security problem"
msgstr ""
"l'exécution de %s en mode setuid root peut être un problème de sécurité"
-#: main.c:560
-msgid "`--posix' overrides `--binary'"
-msgstr "« --posix » prend le pas sur « --binary »"
+#: main.c:588
+msgid "`--posix' overrides `--characters-as-bytes'"
+msgstr "« --posix » prend le pas sur « --characters-as-bytes »"
-#: main.c:611
+#: main.c:647
#, c-format
msgid "can't set binary mode on stdin (%s)"
msgstr "impossible d'activer le mode binaire sur stdin (%s)"
-#: main.c:614
+#: main.c:650
#, c-format
msgid "can't set binary mode on stdout (%s)"
msgstr "impossible d'activer le mode binaire sur stdout (%s)"
-#: main.c:616
+#: main.c:652
#, c-format
msgid "can't set binary mode on stderr (%s)"
msgstr "impossible d'activer le mode binaire sur stderr (%s)"
-#: main.c:655
+#: main.c:710
msgid "no program text at all!"
msgstr "aucun programme !"
-#: main.c:733
+#: main.c:799
#, c-format
msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
msgstr ""
"Utilisation : %s [options GNU ou POSIX] -f fichier_prog [--] fichier ...\n"
-#: main.c:735
+#: main.c:801
#, c-format
msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
msgstr ""
"Utilisation : %s [options GNU ou POSIX] [--] %cprogramme%c fichier ...\n"
-#: main.c:740
+#: main.c:806
msgid "POSIX options:\t\tGNU long options: (standard)\n"
msgstr "Options POSIX :\t\tOptions longues GNU : (standard)\n"
-#: main.c:741
+#: main.c:807
msgid "\t-f progfile\t\t--file=progfile\n"
msgstr "\t-f fichier_prog\t\t--file=fichier_prog\n"
-#: main.c:742
+#: main.c:808
msgid "\t-F fs\t\t\t--field-separator=fs\n"
msgstr "\t-F fs\t\t\t--field-separator=fs\n"
-#: main.c:743
+#: main.c:809
msgid "\t-v var=val\t\t--assign=var=val\n"
msgstr "\t-v var=valeur\t\t--assign=var=valeur\n"
-#: main.c:744
+#: main.c:810
msgid "Short options:\t\tGNU long options: (extensions)\n"
msgstr "Options POSIX :\t\tOptions longues GNU : (extensions)\n"
-#: main.c:745
+#: main.c:811
msgid "\t-b\t\t\t--characters-as-bytes\n"
msgstr "\t-b\t\t\t--characters-as-bytes\n"
-#: main.c:746
+#: main.c:812
msgid "\t-c\t\t\t--traditional\n"
msgstr "\t-c\t\t\t--traditional\n"
-#: main.c:747
+#: main.c:813
msgid "\t-C\t\t\t--copyright\n"
msgstr "\t-C\t\t\t--copyright\n"
-#: main.c:748
+#: main.c:814
msgid "\t-d[file]\t\t--dump-variables[=file]\n"
msgstr "\t-d[fichier]\t\t--dump-variables[=fichier]\n"
-#: main.c:749
+#: main.c:815
+msgid "\t-D[file]\t\t--debug[=file]\n"
+msgstr "\t-D[fichier]\t\t--debug[=fichier]\n"
+
+#: main.c:816
msgid "\t-e 'program-text'\t--source='program-text'\n"
msgstr "\t-e 'programme'\t\t--source='programme'\n"
-#: main.c:750
+#: main.c:817
msgid "\t-E file\t\t\t--exec=file\n"
msgstr "\t-E fichier\t\t--exec=fichier\n"
-#: main.c:751
+#: main.c:818
msgid "\t-g\t\t\t--gen-pot\n"
msgstr "\t-g\t\t\t--gen-pot\n"
-#: main.c:752
+#: main.c:819
msgid "\t-h\t\t\t--help\n"
msgstr "\t-h\t\t\t--help\n"
-#: main.c:753
+#: main.c:820
+msgid "\t-i includefile\t\t--include=includefile\n"
+msgstr "\t-i fichier\t\t--include=fichier\n"
+
+#: main.c:821
+msgid "\t-l library\t\t--load=library\n"
+msgstr "\t-l bibliothèque\t\t--load=bibliothèque\n"
+
+#: main.c:822
msgid "\t-L [fatal]\t\t--lint[=fatal]\n"
msgstr "\t-L [fatal]\t\t--lint[=fatal]\n"
-#: main.c:754
+#: main.c:823
msgid "\t-n\t\t\t--non-decimal-data\n"
msgstr "\t-n\t\t\t--non-decimal-data\n"
-#: main.c:755
+#: main.c:824
+msgid "\t-M\t\t\t--bignum\n"
+msgstr "\t-M\t\t\t--bignum\n"
+
+#: main.c:825
msgid "\t-N\t\t\t--use-lc-numeric\n"
msgstr "\t-N\t\t\t--use-lc-numeric\n"
-#: main.c:756
+#: main.c:826
+msgid "\t-o[file]\t\t--pretty-print[=file]\n"
+msgstr "\t-o[fichier]\t\t--pretty-print[=fichier]\n"
+
+#: main.c:827
msgid "\t-O\t\t\t--optimize\n"
msgstr "\t-O\t\t\t--optimize\n"
-#: main.c:757
+#: main.c:828
msgid "\t-p[file]\t\t--profile[=file]\n"
msgstr "\t-p[fichier]\t\t--profile[=fichier]\n"
-#: main.c:758
+#: main.c:829
msgid "\t-P\t\t\t--posix\n"
msgstr "\t-P\t\t\t--posix\n"
-#: main.c:759
+#: main.c:830
msgid "\t-r\t\t\t--re-interval\n"
msgstr "\t-r\t\t\t--re-interval\n"
-#: main.c:761
-msgid "\t-R file\t\t\t--command=file\n"
-msgstr "\t-R fichier\t\t\t--command=fichier\n"
-
-#: main.c:762
+#: main.c:831
msgid "\t-S\t\t\t--sandbox\n"
msgstr "\t-S\t\t\t--sandbox\n"
-#: main.c:763
+#: main.c:832
msgid "\t-t\t\t\t--lint-old\n"
msgstr "\t-t\t\t\t--lint-old\n"
-#: main.c:764
+#: main.c:833
msgid "\t-V\t\t\t--version\n"
msgstr "\t-V\t\t\t--version\n"
-#: main.c:766
+#: main.c:835
msgid "\t-W nostalgia\t\t--nostalgia\n"
msgstr "\t-W nostalgia\t\t--nostalgia\n"
-#: main.c:769
+#: main.c:838
msgid "\t-Y\t\t--parsedebug\n"
msgstr "\t-Y\t\t--parsedebug\n"
@@ -1838,7 +3156,7 @@ msgstr "\t-Y\t\t--parsedebug\n"
#. for this application. Please add _another line_ with the
#. address for translation bugs.
#. no-wrap
-#: main.c:778
+#: main.c:847
msgid ""
"\n"
"To report bugs, see node `Bugs' in `gawk.info', which is\n"
@@ -1853,7 +3171,7 @@ msgstr ""
"<traduc CHEZ traduc POINT org>.\n"
"\n"
-#: main.c:782
+#: main.c:851
msgid ""
"gawk is a pattern scanning and processing language.\n"
"By default it reads standard input and writes standard output.\n"
@@ -1863,7 +3181,7 @@ msgstr ""
"Par défaut, il lit l'entrée standard et écrit sur la sortie standard.\n"
"\n"
-#: main.c:786
+#: main.c:855
msgid ""
"Examples:\n"
"\tgawk '{ sum += $1 }; END { print sum }' file\n"
@@ -1873,7 +3191,7 @@ msgstr ""
"\tgawk '{ somme += $1 }; END { print somme }' fichier\n"
"\tgawk -F: '{ print $1 }' /etc/passwd\n"
-#: main.c:806
+#: main.c:880
#, c-format
msgid ""
"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
@@ -1893,7 +3211,7 @@ msgstr ""
"version ultérieure de votre choix.\n"
"\n"
-#: main.c:814
+#: main.c:888
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"
@@ -1908,7 +3226,7 @@ msgstr ""
"General Public License).\n"
"\n"
-#: main.c:820
+#: main.c:894
msgid ""
"You should have received a copy of the GNU General Public License\n"
"along with this program. If not, see http://www.gnu.org/licenses/.\n"
@@ -1917,16 +3235,16 @@ msgstr ""
"(GNU General Public License) avec ce programme. Sinon, consultez\n"
"http://www.gnu.org/licenses/.\n"
-#: main.c:855
+#: main.c:931
msgid "-Ft does not set FS to tab in POSIX awk"
msgstr "-Ft ne définit pas le FS comme étant une tabulation en awk POSIX"
-#: main.c:1089
+#: main.c:1208
#, c-format
msgid "unknown value for field spec: %d\n"
msgstr "valeur inconnue pour la définition de champ : %d\n"
-#: main.c:1170
+#: main.c:1306
#, c-format
msgid ""
"%s: `%s' argument to `-v' not in `var=value' form\n"
@@ -1935,84 +3253,127 @@ msgstr ""
"%s : « %s » l'argument de « -v » ne respecte pas la forme « var=valeur »\n"
"\n"
-#: main.c:1196
+#: main.c:1332
#, c-format
msgid "`%s' is not a legal variable name"
msgstr "« %s » n'est pas un nom de variable valide"
-#: main.c:1199
+#: main.c:1335
#, 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:1203
+#: main.c:1339
#, c-format
msgid "cannot use gawk builtin `%s' as variable name"
msgstr "impossible d'utiliser le mot clef gawk « %s » comme variable"
-#: main.c:1208
+#: main.c:1344
#, c-format
msgid "cannot use function `%s' as variable name"
msgstr "impossible d'utiliser la fonction « %s » comme variable"
-#: main.c:1261
+#: main.c:1397
msgid "floating point exception"
msgstr "exception du traitement en virgule flottante"
-#: main.c:1268
+#: main.c:1404
msgid "fatal error: internal error"
msgstr "fatal : erreur interne"
-#: main.c:1283
+#: main.c:1419
msgid "fatal error: internal error: segfault"
msgstr "fatal : erreur interne : erreur de segmentation"
-#: main.c:1295
+#: main.c:1431
msgid "fatal error: internal error: stack overflow"
msgstr "fatal : erreur interne : débordement de la pile"
-#: main.c:1345
+#: main.c:1490
#, c-format
msgid "no pre-opened fd %d"
msgstr "aucun descripteur fd %d pré-ouvert"
-#: main.c:1352
+#: main.c:1497
#, c-format
msgid "could not pre-open /dev/null for fd %d"
-msgstr "impossible de pré-ouvrir /dev/null pour le descripteud fd %d"
+msgstr "impossible de pré-ouvrir /dev/null pour le descripteur fd %d"
+
+#: mpfr.c:550
+#, c-format
+msgid "PREC value `%.*s' is invalid"
+msgstr "la valeur « %.*s » de PREC est incorrecte"
+
+#: mpfr.c:608
+#, c-format
+msgid "RNDMODE value `%.*s' is invalid"
+msgstr "la valeur « %.*s » de RNDMODE est incorrecte"
+
+#: mpfr.c:698
+#, c-format
+msgid "%s: received non-numeric argument"
+msgstr "%s : argument reçu non numérique"
-#: main.c:1375 main.c:1384
+#: mpfr.c:800
+msgid "compl(%Rg): negative value will give strange results"
+msgstr "compl(%Rg) : les valeurs négatives donneront des résultats inattendus"
+
+#: mpfr.c:804
+msgid "comp(%Rg): fractional value will be truncated"
+msgstr "compl(%Rg) : les valeurs non entières seront tronquées"
+
+#: mpfr.c:816
#, c-format
-msgid "could not find groups: %s"
-msgstr "impossible de trouver les groupes : %s"
+msgid "cmpl(%Zd): negative values will give strange results"
+msgstr "compl(%Zd) : les valeurs négatives donneront des résultats inattendus"
+
+#: mpfr.c:835
+#, c-format
+msgid "%s: received non-numeric argument #%d"
+msgstr "%s : argument reçu non numérique #%d"
+
+#: mpfr.c:845
+msgid "%s: argument #%d has invalid value %Rg, using 0"
+msgstr "%s : l'argument #%d a une valeur incorrecte %Rg, utilisation de 0"
-#: msg.c:63
+#: mpfr.c:857
+msgid "%s: argument #%d negative value %Rg will give strange results"
+msgstr ""
+"%s : argument #%d : la valeur négative %Rg donnera des résultats inattendus"
+
+#: mpfr.c:863
+msgid "%s: argument #%d fractional value %Rg will be truncated"
+msgstr "%s : argument #%d : la valeur non entière %Rg sera tronquée"
+
+#: mpfr.c:878
+#, c-format
+msgid "%s: argument #%d negative value %Zd will give strange results"
+msgstr ""
+"%s : argument #%d : la valeur négative %Zd donnera des résultats inattendus"
+
+#: msg.c:68
#, c-format
msgid "cmd. line:"
msgstr "ligne de commande:"
-#: msg.c:107
-msgid "error: "
-msgstr "erreur : "
-
-#: node.c:406
+#: node.c:421
msgid "backslash at end of string"
msgstr "barre oblique inverse à la fin de la chaîne"
-#: node.c:517
+#: node.c:500
#, c-format
msgid "old awk does not support the `\\%c' escape sequence"
msgstr "l'ancien awk ne dispose pas de la séquence d'échappement « \\%c »"
-#: node.c:568
+#: node.c:551
msgid "POSIX does not allow `\\x' escapes"
msgstr "POSIX n'autorise pas les séquences d'échappement « \\x »"
-#: node.c:574
+#: node.c:557
msgid "no hex digits in `\\x' escape sequence"
msgstr "aucun chiffre hexadécimal dans la séquence d'échappement « \\x » "
-#: node.c:596
+#: node.c:579
#, c-format
msgid ""
"hex escape \\x%.*s of %d characters probably not interpreted the way you "
@@ -2021,12 +3382,12 @@ msgstr ""
"la séquence d'échappement hexa. \\x%.*s de %d caractères ne sera "
"probablement pas interprétée comme vous l'imaginez"
-#: node.c:611
+#: node.c:594
#, c-format
msgid "escape sequence `\\%c' treated as plain `%c'"
msgstr "séquence d'échappement « \\%c » traitée comme un simple « %c »"
-#: node.c:750
+#: node.c:739
msgid ""
"Invalid multibyte data detected. There may be a mismatch between your data "
"and your locale."
@@ -2034,28 +3395,28 @@ msgstr ""
"Données multioctets non valables détectées. Possible incohérence entre "
"données et paramètres régionaux (locale)."
-#: posix/gawkmisc.c:176
+#: posix/gawkmisc.c:177
#, c-format
msgid "%s %s `%s': could not get fd flags: (fcntl F_GETFD: %s)"
msgstr ""
"%s %s « %s » : impossible d'obtenir les drapeaux du fd : (fcntl F_GETFD: %s)"
-#: posix/gawkmisc.c:188
+#: posix/gawkmisc.c:189
#, c-format
msgid "%s %s `%s': could not set close-on-exec: (fcntl F_SETFD: %s)"
msgstr ""
"%s %s « %s »: impossible de positionner close-on-exec: (fcntl F_SETFD: %s)"
-#: profile.c:83
+#: profile.c:71
#, c-format
msgid "could not open `%s' for writing: %s"
msgstr "impossible d'ouvrir « %s » en écriture : %s"
-#: profile.c:85
+#: profile.c:73
msgid "sending profile to standard error"
msgstr "envoi du profil vers la sortie d'erreur standard"
-#: profile.c:203
+#: profile.c:193
#, c-format
msgid ""
"\t# %s block(s)\n"
@@ -2064,7 +3425,7 @@ msgstr ""
"\t# Bloc(s) %s\n"
"\n"
-#: profile.c:208
+#: profile.c:198
#, c-format
msgid ""
"\t# Rule(s)\n"
@@ -2073,17 +3434,30 @@ msgstr ""
"\t# Règle(s)\n"
"\n"
-#: profile.c:279
+#: profile.c:272
#, c-format
msgid "internal error: %s with null vname"
msgstr "erreur interne : %s avec un vname nul"
-#: profile.c:952
+#: profile.c:537
+msgid "internal error: builtin with null fname"
+msgstr "erreur interne : fonction interne avec un fname nul"
+
+#: profile.c:949
+#, c-format
+msgid ""
+"\t# Loaded extensions (-l and/or @load)\n"
+"\n"
+msgstr ""
+"\t# Extensions chargées (-l ou @load)\n"
+"\n"
+
+#: profile.c:972
#, c-format
msgid "\t# gawk profile, created %s\n"
msgstr "\t# profile gawk, créé %s\n"
-#: profile.c:1331
+#: profile.c:1475
#, c-format
msgid ""
"\n"
@@ -2092,96 +3466,85 @@ msgstr ""
"\n"
"\t# Fonctions, par ordre alphabétique\n"
-#: profile.c:1370
+#: profile.c:1513
#, c-format
msgid "redir2str: unknown redirection type %d"
msgstr "redir2str : type de redirection %d inconnu"
-#: re.c:572
-#, fuzzy, c-format
-msgid "range of the form `[%c-%c]' is locale dependent"
-msgstr ""
-"les plages de type « [%c-%c] » sont dépendantes des paramètres régionaux "
-"(locale)"
-
-#: re.c:599
+#: re.c:607
#, c-format
msgid "regexp component `%.*s' should probably be `[%.*s]'"
msgstr ""
"le composant d'expression rationnelle « %.*s » devrait probablement être "
"« [%.*s] »"
-#: regcomp.c:132
+#: regcomp.c:131
msgid "Success"
msgstr "Succès"
-#: regcomp.c:135
+#: regcomp.c:134
msgid "No match"
-msgstr "Aucune concordance"
+msgstr "Aucune correspondance"
-#: regcomp.c:138
+#: regcomp.c:137
msgid "Invalid regular expression"
-msgstr "Expression rationnelle non valide"
+msgstr "Expression rationnelle incorrecte"
-#: regcomp.c:141
+#: regcomp.c:140
msgid "Invalid collation character"
-msgstr "Caractère d'interclassement non valide"
+msgstr "Caractère d'interclassement incorrect"
-#: regcomp.c:144
+#: regcomp.c:143
msgid "Invalid character class name"
-msgstr "Nom de classe de caractères non valide"
+msgstr "Nom de classe de caractères incorrect"
-#: regcomp.c:147
+#: regcomp.c:146
msgid "Trailing backslash"
msgstr "Barre oblique inverse finale"
-#: regcomp.c:150
+#: regcomp.c:149
msgid "Invalid back reference"
-msgstr "Référence arrière non valide"
+msgstr "Référence arrière incorrecte"
-#: regcomp.c:153
+#: regcomp.c:152
msgid "Unmatched [ or [^"
msgstr "[ ou [^ sans correspondance"
-#: regcomp.c:156
+#: regcomp.c:155
msgid "Unmatched ( or \\("
msgstr "( ou \\( sans correspondance"
-#: regcomp.c:159
+#: regcomp.c:158
msgid "Unmatched \\{"
msgstr "\\{ sans correspondance"
-#: regcomp.c:162
-msgid "Invalid content of \\{\\}"
-msgstr "Contenu de \\{\\} non valide"
-
-#: regcomp.c:165
+#: regcomp.c:164
msgid "Invalid range end"
-msgstr "Borne finale non valide"
+msgstr "Borne finale non valable"
-#: regcomp.c:168
+#: regcomp.c:167
msgid "Memory exhausted"
msgstr "Mémoire épuisée"
-#: regcomp.c:171
+#: regcomp.c:170
msgid "Invalid preceding regular expression"
-msgstr "Expression rationnelle précédente non valide"
+msgstr "Expression rationnelle précédente incorrecte"
-#: regcomp.c:174
+#: regcomp.c:173
msgid "Premature end of regular expression"
msgstr "Fin prématurée de l'expression rationnelle"
-#: regcomp.c:177
-msgid "Regular expression too big"
-msgstr "Expression rationnelle trop grande"
-
-#: regcomp.c:180
+#: regcomp.c:179
msgid "Unmatched ) or \\)"
msgstr ") ou \\) sans correspondance"
-#: regcomp.c:701
+#: regcomp.c:704
msgid "No previous regular expression"
msgstr "Aucune expression rationnelle précédente"
-#~ msgid "assignment is not allowed to result of builtin function"
-#~ msgstr "impossible d'affecter au résultat d'une fonction interne"
+#: symbol.c:741
+msgid "can not pop main context"
+msgstr "impossible de rétablir (pop) le contexte principal (main)"
+
+#~ msgid "range of the form `[%c-%c]' is locale dependent"
+#~ msgstr "les plages « [%c-%c] » sont dépendantes des paramètres régionaux"
diff --git a/po/ga.gmo b/po/ga.gmo
deleted file mode 100644
index 21141c51..00000000
--- a/po/ga.gmo
+++ /dev/null
Binary files differ
diff --git a/po/gawk.pot b/po/gawk.pot
index 290ff817..bb47fa9e 100644
--- a/po/gawk.pot
+++ b/po/gawk.pot
@@ -6,9 +6,9 @@
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: gawk 4.0.0c\n"
+"Project-Id-Version: gawk 4.1.1\n"
"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
-"POT-Creation-Date: 2011-10-24 05:57+0200\n"
+"POT-Creation-Date: 2014-04-08 19:23+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"
@@ -17,944 +17,1782 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-#: array.c:140
+#: array.c:256
#, c-format
msgid "from %s"
msgstr ""
-#: array.c:248
+#: array.c:357
msgid "attempt to use a scalar value as array"
msgstr ""
-#: array.c:251
-#, c-format
-msgid "attempt to use function `%s' as an array"
-msgstr ""
-
-#: array.c:254
+#: array.c:359
#, c-format
msgid "attempt to use scalar parameter `%s' as an array"
msgstr ""
-#: array.c:257
+#: array.c:362
#, c-format
msgid "attempt to use scalar `%s' as an array"
msgstr ""
-#: array.c:302 array.c:707 builtin.c:84 builtin.c:1384 builtin.c:1426
-#: builtin.c:1439 builtin.c:1856 builtin.c:1868 eval.c:1135 eval.c:1139
-#: eval.c:1495 eval.c:1812
+#: array.c:409 array.c:576 builtin.c:85 builtin.c:1615 builtin.c:1661
+#: builtin.c:1674 builtin.c:2102 builtin.c:2116 eval.c:1122 eval.c:1126
+#: eval.c:1531
#, c-format
msgid "attempt to use array `%s' in a scalar context"
msgstr ""
-#: array.c:513
-#, c-format
-msgid "reference to uninitialized element `%s[\"%.*s\"]'"
-msgstr ""
-
-#: array.c:519
-#, c-format
-msgid "subscript of array `%s' is null string"
-msgstr ""
-
-#: array.c:723
+#: array.c:583
#, c-format
msgid "delete: index `%s' not in array `%s'"
msgstr ""
-#: array.c:734 eval.c:1865
+#: array.c:597
#, c-format
msgid "attempt to use scalar `%s[\"%.*s\"]' as an array"
msgstr ""
-#: array.c:910
-#, c-format
-msgid "%s: empty (null)\n"
-msgstr ""
-
-#: array.c:915
-#, c-format
-msgid "%s: empty (zero)\n"
-msgstr ""
-
-#: array.c:919
-#, c-format
-msgid "%s: table_size = %d, array_size = %d\n"
-msgstr ""
-
-#: array.c:954
-#, c-format
-msgid "%s: is parameter\n"
-msgstr ""
-
-#: array.c:958
-#, c-format
-msgid "%s: array_ref to %s\n"
-msgstr ""
-
-#: array.c:963
-msgid "adump: argument not an array"
+#: array.c:776
+msgid "adump: first argument not an array"
msgstr ""
-#: array.c:1086
+#: array.c:815
msgid "asort: second argument not an array"
msgstr ""
-#: array.c:1087
+#: array.c:816
msgid "asorti: second argument not an array"
msgstr ""
-#: array.c:1094
+#: array.c:823
msgid "asort: first argument not an array"
msgstr ""
-#: array.c:1095
+#: array.c:824
msgid "asorti: first argument not an array"
msgstr ""
-#: array.c:1102
+#: array.c:831
msgid "asort: cannot use a subarray of first arg for second arg"
msgstr ""
-#: array.c:1103
+#: array.c:832
msgid "asorti: cannot use a subarray of first arg for second arg"
msgstr ""
-#: array.c:1108
+#: array.c:837
msgid "asort: cannot use a subarray of second arg for first arg"
msgstr ""
-#: array.c:1109
+#: array.c:838
msgid "asorti: cannot use a subarray of second arg for first arg"
msgstr ""
-#: array.c:1659
+#: array.c:1314
#, c-format
msgid "`%s' is invalid as a function name"
msgstr ""
-#: array.c:1663
+#: array.c:1318
#, c-format
msgid "sort comparison function `%s' is not defined"
msgstr ""
-#: awkgram.y:249
+#: awkgram.y:233
#, c-format
msgid "%s blocks must have an action part"
msgstr ""
-#: awkgram.y:252
+#: awkgram.y:236
msgid "each rule must have a pattern or an action part"
msgstr ""
-#: awkgram.y:323 awkgram.y:334
+#: awkgram.y:325 awkgram.y:336
msgid "old awk does not support multiple `BEGIN' or `END' rules"
msgstr ""
-#: awkgram.y:371
+#: awkgram.y:373
#, c-format
msgid "`%s' is a built-in function, it cannot be redefined"
msgstr ""
-#: awkgram.y:432
+#: awkgram.y:419
msgid "regexp constant `//' looks like a C++ comment, but is not"
msgstr ""
-#: awkgram.y:436
+#: awkgram.y:423
#, c-format
msgid "regexp constant `/%s/' looks like a C comment, but is not"
msgstr ""
-#: awkgram.y:528
+#: awkgram.y:515
#, c-format
msgid "duplicate case values in switch body: %s"
msgstr ""
-#: awkgram.y:549
+#: awkgram.y:536
msgid "duplicate `default' detected in switch body"
msgstr ""
-#: awkgram.y:809
+#: awkgram.y:796 awkgram.y:3723
msgid "`break' is not allowed outside a loop or switch"
msgstr ""
-#: awkgram.y:818
+#: awkgram.y:805 awkgram.y:3715
msgid "`continue' is not allowed outside a loop"
msgstr ""
-#: awkgram.y:828
+#: awkgram.y:815
#, c-format
msgid "`next' used in %s action"
msgstr ""
-#: awkgram.y:836
-msgid "`nextfile' is a gawk extension"
-msgstr ""
-
-#: awkgram.y:841
+#: awkgram.y:824
#, c-format
msgid "`nextfile' used in %s action"
msgstr ""
-#: awkgram.y:865
+#: awkgram.y:848
msgid "`return' used outside function context"
msgstr ""
-#: awkgram.y:925
+#: awkgram.y:922
msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
msgstr ""
-#: awkgram.y:995 awkgram.y:999 awkgram.y:1023
-msgid "`delete array' is a gawk extension"
+#: awkgram.y:988 awkgram.y:1037
+msgid "`delete' is not allowed with SYMTAB"
+msgstr ""
+
+#: awkgram.y:990 awkgram.y:1039
+msgid "`delete' is not allowed with FUNCTAB"
msgstr ""
-#: awkgram.y:1019
+#: awkgram.y:1024 awkgram.y:1028
msgid "`delete(array)' is a non-portable tawk extension"
msgstr ""
-#: awkgram.y:1135
+#: awkgram.y:1149
msgid "multistage two-way pipelines don't work"
msgstr ""
-#: awkgram.y:1238
+#: awkgram.y:1264
msgid "regular expression on right of assignment"
msgstr ""
-#: awkgram.y:1249
+#: awkgram.y:1275
msgid "regular expression on left of `~' or `!~' operator"
msgstr ""
-#: awkgram.y:1265 awkgram.y:1419
+#: awkgram.y:1291 awkgram.y:1442
msgid "old awk does not support the keyword `in' except after `for'"
msgstr ""
-#: awkgram.y:1275
+#: awkgram.y:1301
msgid "regular expression on right of comparison"
msgstr ""
-#: awkgram.y:1394
+#: awkgram.y:1417
#, c-format
msgid "`getline var' invalid inside `%s' rule"
msgstr ""
-#: awkgram.y:1397 eval.c:2504
+#: awkgram.y:1420
#, c-format
msgid "`getline' invalid inside `%s' rule"
msgstr ""
-#: awkgram.y:1402
+#: awkgram.y:1425
msgid "non-redirected `getline' undefined inside END action"
msgstr ""
-#: awkgram.y:1421
+#: awkgram.y:1444
msgid "old awk does not support multidimensional arrays"
msgstr ""
-#: awkgram.y:1517
+#: awkgram.y:1541
msgid "call of `length' without parentheses is not portable"
msgstr ""
-#: awkgram.y:1580
+#: awkgram.y:1607
msgid "indirect function calls are a gawk extension"
msgstr ""
-#: awkgram.y:1593
+#: awkgram.y:1620
#, c-format
msgid "can not use special variable `%s' for indirect function call"
msgstr ""
-#: awkgram.y:1671
+#: awkgram.y:1698
msgid "invalid subscript expression"
msgstr ""
-#: awkgram.y:1711
-msgid "use of non-array as array"
-msgstr ""
-
-#: awkgram.y:1975 awkgram.y:1995 msg.c:98
+#: awkgram.y:2048 awkgram.y:2068 gawkapi.c:206 gawkapi.c:224 msg.c:126
msgid "warning: "
msgstr ""
-#: awkgram.y:1993 msg.c:130
+#: awkgram.y:2066 gawkapi.c:192 gawkapi.c:221 msg.c:158
msgid "fatal: "
msgstr ""
-#: awkgram.y:2043
+#: awkgram.y:2116
msgid "unexpected newline or end of string"
msgstr ""
-#: awkgram.y:2300 awkgram.y:2358 awkgram.y:2542
+#: awkgram.y:2383 awkgram.y:2459 awkgram.y:2682 debug.c:523 debug.c:539
+#: debug.c:2812 debug.c:5055
#, c-format
msgid "can't open source file `%s' for reading (%s)"
msgstr ""
-#: awkgram.y:2301 awkgram.y:2359 builtin.c:122
+#: awkgram.y:2384 awkgram.y:2509
+#, c-format
+msgid "can't open shared library `%s' for reading (%s)"
+msgstr ""
+
+#: awkgram.y:2386 awkgram.y:2460 awkgram.y:2510 builtin.c:135 debug.c:5206
msgid "reason unknown"
msgstr ""
-#: awkgram.y:2317
+#: awkgram.y:2395 awkgram.y:2419
+#, c-format
+msgid "can't include `%s' and use it as a program file"
+msgstr ""
+
+#: awkgram.y:2408
#, c-format
msgid "already included source file `%s'"
msgstr ""
-#: awkgram.y:2343
+#: awkgram.y:2409
+#, c-format
+msgid "already loaded shared library `%s'"
+msgstr ""
+
+#: awkgram.y:2444
msgid "@include is a gawk extension"
msgstr ""
-#: awkgram.y:2349
+#: awkgram.y:2450
msgid "empty filename after @include"
msgstr ""
#: awkgram.y:2494
+msgid "@load is a gawk extension"
+msgstr ""
+
+#: awkgram.y:2500
+msgid "empty filename after @load"
+msgstr ""
+
+#: awkgram.y:2634
msgid "empty program text on command line"
msgstr ""
-#: awkgram.y:2609
+#: awkgram.y:2749
#, c-format
msgid "can't read sourcefile `%s' (%s)"
msgstr ""
-#: awkgram.y:2620
+#: awkgram.y:2760
#, c-format
msgid "source file `%s' is empty"
msgstr ""
-#: awkgram.y:2805
+#: awkgram.y:2937
msgid "source file does not end in newline"
msgstr ""
-#: awkgram.y:2882
+#: awkgram.y:3042
msgid "unterminated regexp ends with `\\' at end of file"
msgstr ""
-#: awkgram.y:2906
+#: awkgram.y:3066
#, c-format
msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
msgstr ""
-#: awkgram.y:2910
+#: awkgram.y:3070
#, c-format
msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
msgstr ""
-#: awkgram.y:2917
+#: awkgram.y:3077
msgid "unterminated regexp"
msgstr ""
-#: awkgram.y:2921
+#: awkgram.y:3081
msgid "unterminated regexp at end of file"
msgstr ""
-#: awkgram.y:2980
+#: awkgram.y:3140
msgid "use of `\\ #...' line continuation is not portable"
msgstr ""
-#: awkgram.y:2996
+#: awkgram.y:3156
msgid "backslash not last character on line"
msgstr ""
-#: awkgram.y:3057
+#: awkgram.y:3217
msgid "POSIX does not allow operator `**='"
msgstr ""
-#: awkgram.y:3059
+#: awkgram.y:3219
msgid "old awk does not support operator `**='"
msgstr ""
-#: awkgram.y:3068
+#: awkgram.y:3228
msgid "POSIX does not allow operator `**'"
msgstr ""
-#: awkgram.y:3070
+#: awkgram.y:3230
msgid "old awk does not support operator `**'"
msgstr ""
-#: awkgram.y:3105
+#: awkgram.y:3265
msgid "operator `^=' is not supported in old awk"
msgstr ""
-#: awkgram.y:3113
+#: awkgram.y:3273
msgid "operator `^' is not supported in old awk"
msgstr ""
-#: awkgram.y:3206 awkgram.y:3222
+#: awkgram.y:3366 awkgram.y:3382 command.y:1178
msgid "unterminated string"
msgstr ""
-#: awkgram.y:3418
+#: awkgram.y:3603
#, c-format
msgid "invalid char '%c' in expression"
msgstr ""
-#: awkgram.y:3465
+#: awkgram.y:3650
#, c-format
msgid "`%s' is a gawk extension"
msgstr ""
-#: awkgram.y:3470
-#, c-format
-msgid "`%s' is a Bell Labs extension"
-msgstr ""
-
-#: awkgram.y:3475
+#: awkgram.y:3655
#, c-format
msgid "POSIX does not allow `%s'"
msgstr ""
-#: awkgram.y:3483
+#: awkgram.y:3663
#, c-format
msgid "`%s' is not supported in old awk"
msgstr ""
-#: awkgram.y:3550
+#: awkgram.y:3753
msgid "`goto' considered harmful!\n"
msgstr ""
-#: awkgram.y:3601
+#: awkgram.y:3787
#, c-format
msgid "%d is invalid as number of arguments for %s"
msgstr ""
-#: awkgram.y:3636
+#: awkgram.y:3822
#, c-format
msgid "%s: string literal as last arg of substitute has no effect"
msgstr ""
-#: awkgram.y:3641
+#: awkgram.y:3827
#, c-format
msgid "%s third parameter is not a changeable object"
msgstr ""
-#: awkgram.y:3714 awkgram.y:3717
+#: awkgram.y:3910 awkgram.y:3913
msgid "match: third argument is a gawk extension"
msgstr ""
-#: awkgram.y:3771 awkgram.y:3774
+#: awkgram.y:3967 awkgram.y:3970
msgid "close: second argument is a gawk extension"
msgstr ""
-#: awkgram.y:3786
+#: awkgram.y:3982
msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
msgstr ""
-#: awkgram.y:3801
+#: awkgram.y:3997
msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
msgstr ""
-#: awkgram.y:3893
-#, c-format
-msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+#: awkgram.y:4016
+msgid "index: regexp constant as second argument is not allowed"
msgstr ""
-#: awkgram.y:3935
+#: awkgram.y:4069
#, c-format
msgid "function `%s': parameter `%s' shadows global variable"
msgstr ""
-#: awkgram.y:4093
+#: awkgram.y:4126 debug.c:4041 debug.c:4084 debug.c:5204
#, c-format
msgid "could not open `%s' for writing (%s)"
msgstr ""
-#: awkgram.y:4094
+#: awkgram.y:4127
msgid "sending variable list to standard error"
msgstr ""
-#: awkgram.y:4100
+#: awkgram.y:4135
#, c-format
msgid "%s: close failed (%s)"
msgstr ""
-#: awkgram.y:4152
+#: awkgram.y:4160
msgid "shadow_funcs() called twice!"
msgstr ""
-#: awkgram.y:4158
+#: awkgram.y:4168
msgid "there were shadowed variables."
msgstr ""
-#: awkgram.y:4188
+#: awkgram.y:4239
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr ""
+
+#: awkgram.y:4285
#, c-format
msgid "function `%s': can't use function name as parameter name"
msgstr ""
-#: awkgram.y:4192
+#: awkgram.y:4288
#, c-format
msgid "function `%s': can't use special variable `%s' as a function parameter"
msgstr ""
-#: awkgram.y:4208
+#: awkgram.y:4296
#, c-format
-msgid "function name `%s' previously defined"
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
msgstr ""
-#: awkgram.y:4376 awkgram.y:4382
+#: awkgram.y:4383 awkgram.y:4389
#, c-format
msgid "function `%s' called but never defined"
msgstr ""
-#: awkgram.y:4385
+#: awkgram.y:4393
#, c-format
msgid "function `%s' defined but never called directly"
msgstr ""
-#: awkgram.y:4417
+#: awkgram.y:4425
#, c-format
msgid "regexp constant for parameter #%d yields boolean value"
msgstr ""
-#: awkgram.y:4526
+#: awkgram.y:4484
#, c-format
msgid ""
"function `%s' called with space between name and `(',\n"
"or used as a variable or an array"
msgstr ""
-#: awkgram.y:4773 eval.c:2056
+#: awkgram.y:4720
msgid "division by zero attempted"
msgstr ""
-#: awkgram.y:4782 eval.c:2072
+#: awkgram.y:4729
#, c-format
msgid "division by zero attempted in `%%'"
msgstr ""
-#: builtin.c:120
+#: awkgram.y:5049
+msgid ""
+"cannot assign a value to the result of a field post-increment expression"
+msgstr ""
+
+#: awkgram.y:5052
+#, c-format
+msgid "invalid target of assignment (opcode %s)"
+msgstr ""
+
+#: builtin.c:133
#, c-format
msgid "%s to \"%s\" failed (%s)"
msgstr ""
-#: builtin.c:121
+#: builtin.c:134
msgid "standard output"
msgstr ""
-#: builtin.c:135
+#: builtin.c:148
msgid "exp: received non-numeric argument"
msgstr ""
-#: builtin.c:141
+#: builtin.c:154
#, c-format
msgid "exp: argument %g is out of range"
msgstr ""
-#: builtin.c:200
+#: builtin.c:229
#, c-format
msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
msgstr ""
-#: builtin.c:203
+#: builtin.c:232
#, c-format
msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
msgstr ""
-#: builtin.c:215
+#: builtin.c:244
#, c-format
msgid "fflush: `%s' is not an open file, pipe or co-process"
msgstr ""
-#: builtin.c:333
+#: builtin.c:362
msgid "index: received non-string first argument"
msgstr ""
-#: builtin.c:335
+#: builtin.c:364
msgid "index: received non-string second argument"
msgstr ""
-#: builtin.c:457
+#: builtin.c:488 mpfr.c:757
msgid "int: received non-numeric argument"
msgstr ""
-#: builtin.c:493
+#: builtin.c:525
msgid "length: received array argument"
msgstr ""
-#: builtin.c:496
+#: builtin.c:528
msgid "`length(array)' is a gawk extension"
msgstr ""
-#: builtin.c:504
+#: builtin.c:544
msgid "length: received non-string argument"
msgstr ""
-#: builtin.c:535
+#: builtin.c:575
msgid "log: received non-numeric argument"
msgstr ""
-#: builtin.c:538
+#: builtin.c:578
#, c-format
msgid "log: received negative argument %g"
msgstr ""
-#: builtin.c:694 builtin.c:699
+#: builtin.c:776 builtin.c:781
msgid "fatal: must use `count$' on all formats or none"
msgstr ""
-#: builtin.c:761
+#: builtin.c:851
#, c-format
msgid "field width is ignored for `%%' specifier"
msgstr ""
-#: builtin.c:763
+#: builtin.c:853
#, c-format
msgid "precision is ignored for `%%' specifier"
msgstr ""
-#: builtin.c:765
+#: builtin.c:855
#, c-format
msgid "field width and precision are ignored for `%%' specifier"
msgstr ""
-#: builtin.c:816
+#: builtin.c:906
msgid "fatal: `$' is not permitted in awk formats"
msgstr ""
-#: builtin.c:825
+#: builtin.c:915
msgid "fatal: arg count with `$' must be > 0"
msgstr ""
-#: builtin.c:829
+#: builtin.c:919
#, c-format
msgid "fatal: arg count %ld greater than total number of supplied arguments"
msgstr ""
-#: builtin.c:833
+#: builtin.c:923
msgid "fatal: `$' not permitted after period in format"
msgstr ""
-#: builtin.c:849
+#: builtin.c:939
msgid "fatal: no `$' supplied for positional field width or precision"
msgstr ""
-#: builtin.c:920
+#: builtin.c:1009
msgid "`l' is meaningless in awk formats; ignored"
msgstr ""
-#: builtin.c:924
+#: builtin.c:1013
msgid "fatal: `l' is not permitted in POSIX awk formats"
msgstr ""
-#: builtin.c:937
+#: builtin.c:1026
msgid "`L' is meaningless in awk formats; ignored"
msgstr ""
-#: builtin.c:941
+#: builtin.c:1030
msgid "fatal: `L' is not permitted in POSIX awk formats"
msgstr ""
-#: builtin.c:954
+#: builtin.c:1043
msgid "`h' is meaningless in awk formats; ignored"
msgstr ""
-#: builtin.c:958
+#: builtin.c:1047
msgid "fatal: `h' is not permitted in POSIX awk formats"
msgstr ""
-#: builtin.c:1271
+#: builtin.c:1463
#, c-format
msgid "[s]printf: value %g is out of range for `%%%c' format"
msgstr ""
-#: builtin.c:1331
+#: builtin.c:1561
#, c-format
msgid "ignoring unknown format specifier character `%c': no argument converted"
msgstr ""
-#: builtin.c:1336
+#: builtin.c:1566
msgid "fatal: not enough arguments to satisfy format string"
msgstr ""
-#: builtin.c:1338
+#: builtin.c:1568
msgid "^ ran out for this one"
msgstr ""
-#: builtin.c:1345
+#: builtin.c:1575
msgid "[s]printf: format specifier does not have control letter"
msgstr ""
-#: builtin.c:1348
+#: builtin.c:1578
msgid "too many arguments supplied for format string"
msgstr ""
-#: builtin.c:1422 builtin.c:1433
+#: builtin.c:1634
+msgid "sprintf: no arguments"
+msgstr ""
+
+#: builtin.c:1657 builtin.c:1668
msgid "printf: no arguments"
msgstr ""
-#: builtin.c:1474
+#: builtin.c:1711
msgid "sqrt: received non-numeric argument"
msgstr ""
-#: builtin.c:1478
+#: builtin.c:1715
#, c-format
msgid "sqrt: called with negative argument %g"
msgstr ""
-#: builtin.c:1502
+#: builtin.c:1746
#, c-format
msgid "substr: length %g is not >= 1"
msgstr ""
-#: builtin.c:1504
+#: builtin.c:1748
#, c-format
msgid "substr: length %g is not >= 0"
msgstr ""
-#: builtin.c:1511
+#: builtin.c:1755
#, c-format
msgid "substr: non-integer length %g will be truncated"
msgstr ""
-#: builtin.c:1516
+#: builtin.c:1760
#, c-format
msgid "substr: length %g too big for string indexing, truncating to %g"
msgstr ""
-#: builtin.c:1528
+#: builtin.c:1772
#, c-format
msgid "substr: start index %g is invalid, using 1"
msgstr ""
-#: builtin.c:1533
+#: builtin.c:1777
#, c-format
msgid "substr: non-integer start index %g will be truncated"
msgstr ""
-#: builtin.c:1558
+#: builtin.c:1802
msgid "substr: source string is zero length"
msgstr ""
-#: builtin.c:1574
+#: builtin.c:1818
#, c-format
msgid "substr: start index %g is past end of string"
msgstr ""
-#: builtin.c:1582
+#: builtin.c:1826
#, c-format
msgid ""
"substr: length %g at start index %g exceeds length of first argument (%lu)"
msgstr ""
-#: builtin.c:1655
+#: builtin.c:1900
msgid "strftime: format value in PROCINFO[\"strftime\"] has numeric type"
msgstr ""
-#: builtin.c:1678
+#: builtin.c:1923
msgid "strftime: received non-numeric second argument"
msgstr ""
-#: builtin.c:1681
+#: builtin.c:1927
msgid "strftime: second argument less than 0 or too big for time_t"
msgstr ""
-#: builtin.c:1687
+#: builtin.c:1934
msgid "strftime: received non-string first argument"
msgstr ""
-#: builtin.c:1693
+#: builtin.c:1941
msgid "strftime: received empty format string"
msgstr ""
-#: builtin.c:1759
+#: builtin.c:2007
msgid "mktime: received non-string argument"
msgstr ""
-#: builtin.c:1776
+#: builtin.c:2024
msgid "mktime: at least one of the values is out of the default range"
msgstr ""
-#: builtin.c:1811
+#: builtin.c:2059
msgid "'system' function not allowed in sandbox mode"
msgstr ""
-#: builtin.c:1816
+#: builtin.c:2064
msgid "system: received non-string argument"
msgstr ""
-#: builtin.c:1871 eval.c:1159 eval.c:1790 eval.c:1803
-#, c-format
-msgid "reference to uninitialized variable `%s'"
-msgstr ""
-
-#: builtin.c:1938
+#: builtin.c:2184
#, c-format
msgid "reference to uninitialized field `$%d'"
msgstr ""
-#: builtin.c:2025
+#: builtin.c:2271
msgid "tolower: received non-string argument"
msgstr ""
-#: builtin.c:2059
+#: builtin.c:2305
msgid "toupper: received non-string argument"
msgstr ""
-#: builtin.c:2095
+#: builtin.c:2341 mpfr.c:672
msgid "atan2: received non-numeric first argument"
msgstr ""
-#: builtin.c:2097
+#: builtin.c:2343 mpfr.c:674
msgid "atan2: received non-numeric second argument"
msgstr ""
-#: builtin.c:2116
+#: builtin.c:2362
msgid "sin: received non-numeric argument"
msgstr ""
-#: builtin.c:2132
+#: builtin.c:2378
msgid "cos: received non-numeric argument"
msgstr ""
-#: builtin.c:2185
+#: builtin.c:2431 mpfr.c:1156
msgid "srand: received non-numeric argument"
msgstr ""
-#: builtin.c:2216
+#: builtin.c:2462
msgid "match: third argument is not an array"
msgstr ""
-#: builtin.c:2480
+#: builtin.c:2734
msgid "gensub: third argument of 0 treated as 1"
msgstr ""
-#: builtin.c:2773
+#: builtin.c:3030
msgid "lshift: received non-numeric first argument"
msgstr ""
-#: builtin.c:2775
+#: builtin.c:3032
msgid "lshift: received non-numeric second argument"
msgstr ""
-#: builtin.c:2781
+#: builtin.c:3038
#, c-format
-msgid "lshift(%lf, %lf): negative values will give strange results"
+msgid "lshift(%f, %f): negative values will give strange results"
msgstr ""
-#: builtin.c:2783
+#: builtin.c:3040
#, c-format
-msgid "lshift(%lf, %lf): fractional values will be truncated"
+msgid "lshift(%f, %f): fractional values will be truncated"
msgstr ""
-#: builtin.c:2785
+#: builtin.c:3042
#, c-format
-msgid "lshift(%lf, %lf): too large shift value will give strange results"
+msgid "lshift(%f, %f): too large shift value will give strange results"
msgstr ""
-#: builtin.c:2810
+#: builtin.c:3067
msgid "rshift: received non-numeric first argument"
msgstr ""
-#: builtin.c:2812
+#: builtin.c:3069
msgid "rshift: received non-numeric second argument"
msgstr ""
-#: builtin.c:2818
+#: builtin.c:3075
#, c-format
-msgid "rshift(%lf, %lf): negative values will give strange results"
+msgid "rshift(%f, %f): negative values will give strange results"
msgstr ""
-#: builtin.c:2820
+#: builtin.c:3077
#, c-format
-msgid "rshift(%lf, %lf): fractional values will be truncated"
+msgid "rshift(%f, %f): fractional values will be truncated"
msgstr ""
-#: builtin.c:2822
+#: builtin.c:3079
#, c-format
-msgid "rshift(%lf, %lf): too large shift value will give strange results"
+msgid "rshift(%f, %f): too large shift value will give strange results"
msgstr ""
-#: builtin.c:2847
-msgid "and: received non-numeric first argument"
+#: builtin.c:3104 mpfr.c:968
+msgid "and: called with less than two arguments"
msgstr ""
-#: builtin.c:2849
-msgid "and: received non-numeric second argument"
+#: builtin.c:3109
+#, c-format
+msgid "and: argument %d is non-numeric"
msgstr ""
-#: builtin.c:2855
+#: builtin.c:3113
#, c-format
-msgid "and(%lf, %lf): negative values will give strange results"
+msgid "and: argument %d negative value %g will give strange results"
msgstr ""
-#: builtin.c:2857
+#: builtin.c:3136 mpfr.c:1000
+msgid "or: called with less than two arguments"
+msgstr ""
+
+#: builtin.c:3141
#, c-format
-msgid "and(%lf, %lf): fractional values will be truncated"
+msgid "or: argument %d is non-numeric"
msgstr ""
-#: builtin.c:2882
-msgid "or: received non-numeric first argument"
+#: builtin.c:3145
+#, c-format
+msgid "or: argument %d negative value %g will give strange results"
msgstr ""
-#: builtin.c:2884
-msgid "or: received non-numeric second argument"
+#: builtin.c:3167 mpfr.c:1031
+msgid "xor: called with less than two arguments"
msgstr ""
-#: builtin.c:2890
+#: builtin.c:3173
#, c-format
-msgid "or(%lf, %lf): negative values will give strange results"
+msgid "xor: argument %d is non-numeric"
msgstr ""
-#: builtin.c:2892
+#: builtin.c:3177
#, c-format
-msgid "or(%lf, %lf): fractional values will be truncated"
+msgid "xor: argument %d negative value %g will give strange results"
msgstr ""
-#: builtin.c:2920
-msgid "xor: received non-numeric first argument"
+#: builtin.c:3202 mpfr.c:787
+msgid "compl: received non-numeric argument"
msgstr ""
-#: builtin.c:2922
-msgid "xor: received non-numeric second argument"
+#: builtin.c:3208
+#, c-format
+msgid "compl(%f): negative value will give strange results"
msgstr ""
-#: builtin.c:2928
+#: builtin.c:3210
#, c-format
-msgid "xor(%lf, %lf): negative values will give strange results"
+msgid "compl(%f): fractional value will be truncated"
msgstr ""
-#: builtin.c:2930
+#: builtin.c:3379
#, c-format
-msgid "xor(%lf, %lf): fractional values will be truncated"
+msgid "dcgettext: `%s' is not a valid locale category"
msgstr ""
-#: builtin.c:2954 builtin.c:2960
-msgid "compl: received non-numeric argument"
+#: command.y:225
+#, c-format
+msgid "Type (g)awk statement(s). End with the command \"end\"\n"
msgstr ""
-#: builtin.c:2962
+#: command.y:289
#, c-format
-msgid "compl(%lf): negative value will give strange results"
+msgid "invalid frame number: %d"
msgstr ""
-#: builtin.c:2964
+#: command.y:295
#, c-format
-msgid "compl(%lf): fractional value will be truncated"
+msgid "info: invalid option - \"%s\""
msgstr ""
-#: builtin.c:3133
+#: command.y:321
#, c-format
-msgid "dcgettext: `%s' is not a valid locale category"
+msgid "source \"%s\": already sourced."
+msgstr ""
+
+#: command.y:326
+#, c-format
+msgid "save \"%s\": command not permitted."
+msgstr ""
+
+#: command.y:339
+msgid "Can't use command `commands' for breakpoint/watchpoint commands"
+msgstr ""
+
+#: command.y:341
+msgid "no breakpoint/watchpoint has been set yet"
+msgstr ""
+
+#: command.y:343
+msgid "invalid breakpoint/watchpoint number"
+msgstr ""
+
+#: command.y:348
+#, c-format
+msgid "Type commands for when %s %d is hit, one per line.\n"
+msgstr ""
+
+#: command.y:350
+#, c-format
+msgid "End with the command \"end\"\n"
+msgstr ""
+
+#: command.y:357
+msgid "`end' valid only in command `commands' or `eval'"
+msgstr ""
+
+#: command.y:367
+msgid "`silent' valid only in command `commands'"
+msgstr ""
+
+#: command.y:373
+#, c-format
+msgid "trace: invalid option - \"%s\""
+msgstr ""
+
+#: command.y:387
+msgid "condition: invalid breakpoint/watchpoint number"
+msgstr ""
+
+#: command.y:449
+msgid "argument not a string"
+msgstr ""
+
+#: command.y:459 command.y:464
+#, c-format
+msgid "option: invalid parameter - \"%s\""
+msgstr ""
+
+#: command.y:474
+#, c-format
+msgid "no such function - \"%s\""
+msgstr ""
+
+#: command.y:531
+#, c-format
+msgid "enable: invalid option - \"%s\""
+msgstr ""
+
+#: command.y:597
+#, c-format
+msgid "invalid range specification: %d - %d"
+msgstr ""
+
+#: command.y:659
+msgid "non-numeric value for field number"
+msgstr ""
+
+#: command.y:680 command.y:687
+msgid "non-numeric value found, numeric expected"
+msgstr ""
+
+#: command.y:712 command.y:718
+msgid "non-zero integer value"
+msgstr ""
+
+#: command.y:817
+msgid ""
+"backtrace [N] - print trace of all or N innermost (outermost if N < 0) "
+"frames."
+msgstr ""
+
+#: command.y:819
+msgid ""
+"break [[filename:]N|function] - set breakpoint at the specified location."
+msgstr ""
+
+#: command.y:821
+msgid "clear [[filename:]N|function] - delete breakpoints previously set."
+msgstr ""
+
+#: command.y:823
+msgid ""
+"commands [num] - starts a list of commands to be executed at a "
+"breakpoint(watchpoint) hit."
+msgstr ""
+
+#: command.y:825
+msgid "condition num [expr] - set or clear breakpoint or watchpoint condition."
+msgstr ""
+
+#: command.y:827
+msgid "continue [COUNT] - continue program being debugged."
+msgstr ""
+
+#: command.y:829
+msgid "delete [breakpoints] [range] - delete specified breakpoints."
+msgstr ""
+
+#: command.y:831
+msgid "disable [breakpoints] [range] - disable specified breakpoints."
+msgstr ""
+
+#: command.y:833
+msgid "display [var] - print value of variable each time the program stops."
+msgstr ""
+
+#: command.y:835
+msgid "down [N] - move N frames down the stack."
+msgstr ""
+
+#: command.y:837
+msgid "dump [filename] - dump instructions to file or stdout."
+msgstr ""
+
+#: command.y:839
+msgid "enable [once|del] [breakpoints] [range] - enable specified breakpoints."
+msgstr ""
+
+#: command.y:841
+msgid "end - end a list of commands or awk statements."
+msgstr ""
+
+#: command.y:843
+msgid "eval stmt|[p1, p2, ...] - evaluate awk statement(s)."
+msgstr ""
+
+#: command.y:845
+msgid "finish - execute until selected stack frame returns."
+msgstr ""
+
+#: command.y:847
+msgid "frame [N] - select and print stack frame number N."
+msgstr ""
+
+#: command.y:849
+msgid "help [command] - print list of commands or explanation of command."
+msgstr ""
+
+#: command.y:851
+msgid "ignore N COUNT - set ignore-count of breakpoint number N to COUNT."
+msgstr ""
+
+#: command.y:853
+msgid ""
+"info topic - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch."
+msgstr ""
+
+#: command.y:855
+msgid "list [-|+|[filename:]lineno|function|range] - list specified line(s)."
+msgstr ""
+
+#: command.y:857
+msgid "next [COUNT] - step program, proceeding through subroutine calls."
+msgstr ""
+
+#: command.y:859
+msgid ""
+"nexti [COUNT] - step one instruction, but proceed through subroutine calls."
+msgstr ""
+
+#: command.y:861
+msgid "option [name[=value]] - set or display debugger option(s)."
+msgstr ""
+
+#: command.y:863
+msgid "print var [var] - print value of a variable or array."
+msgstr ""
+
+#: command.y:865
+msgid "printf format, [arg], ... - formatted output."
+msgstr ""
+
+#: command.y:867
+msgid "quit - exit debugger."
+msgstr ""
+
+#: command.y:869
+msgid "return [value] - make selected stack frame return to its caller."
+msgstr ""
+
+#: command.y:871
+msgid "run - start or restart executing program."
+msgstr ""
+
+#: command.y:874
+msgid "save filename - save commands from the session to file."
+msgstr ""
+
+#: command.y:877
+msgid "set var = value - assign value to a scalar variable."
+msgstr ""
+
+#: command.y:879
+msgid ""
+"silent - suspends usual message when stopped at a breakpoint/watchpoint."
+msgstr ""
+
+#: command.y:881
+msgid "source file - execute commands from file."
+msgstr ""
+
+#: command.y:883
+msgid "step [COUNT] - step program until it reaches a different source line."
+msgstr ""
+
+#: command.y:885
+msgid "stepi [COUNT] - step one instruction exactly."
+msgstr ""
+
+#: command.y:887
+msgid "tbreak [[filename:]N|function] - set a temporary breakpoint."
+msgstr ""
+
+#: command.y:889
+msgid "trace on|off - print instruction before executing."
+msgstr ""
+
+#: command.y:891
+msgid "undisplay [N] - remove variable(s) from automatic display list."
+msgstr ""
+
+#: command.y:893
+msgid ""
+"until [[filename:]N|function] - execute until program reaches a different "
+"line or line N within current frame."
+msgstr ""
+
+#: command.y:895
+msgid "unwatch [N] - remove variable(s) from watch list."
+msgstr ""
+
+#: command.y:897
+msgid "up [N] - move N frames up the stack."
+msgstr ""
+
+#: command.y:899
+msgid "watch var - set a watchpoint for a variable."
+msgstr ""
+
+#: command.y:1011 debug.c:401 msg.c:135
+#, c-format
+msgid "error: "
msgstr ""
-#: eval.c:412
+#: command.y:1051
+#, c-format
+msgid "can't read command (%s)\n"
+msgstr ""
+
+#: command.y:1065
+#, c-format
+msgid "can't read command (%s)"
+msgstr ""
+
+#: command.y:1116
+msgid "invalid character in command"
+msgstr ""
+
+#: command.y:1152
+#, c-format
+msgid "unknown command - \"%.*s\", try help"
+msgstr ""
+
+#: command.y:1222
+#, c-format
+msgid "%s"
+msgstr ""
+
+#: command.y:1284
+msgid "invalid character"
+msgstr ""
+
+#: command.y:1455
+#, c-format
+msgid "undefined command: %s\n"
+msgstr ""
+
+#: debug.c:252
+msgid "set or show the number of lines to keep in history file."
+msgstr ""
+
+#: debug.c:254
+msgid "set or show the list command window size."
+msgstr ""
+
+#: debug.c:256
+msgid "set or show gawk output file."
+msgstr ""
+
+#: debug.c:258
+msgid "set or show debugger prompt."
+msgstr ""
+
+#: debug.c:260
+msgid "(un)set or show saving of command history (value=on|off)."
+msgstr ""
+
+#: debug.c:262
+msgid "(un)set or show saving of options (value=on|off)."
+msgstr ""
+
+#: debug.c:264
+msgid "(un)set or show instruction tracing (value=on|off)."
+msgstr ""
+
+#: debug.c:345
+msgid "program not running."
+msgstr ""
+
+#: debug.c:448 debug.c:606
+#, c-format
+msgid "can't read source file `%s' (%s)"
+msgstr ""
+
+#: debug.c:453
+#, c-format
+msgid "source file `%s' is empty.\n"
+msgstr ""
+
+#: debug.c:480
+msgid "no current source file."
+msgstr ""
+
+#: debug.c:505
+#, c-format
+msgid "cannot find source file named `%s' (%s)"
+msgstr ""
+
+#: debug.c:529
+#, c-format
+msgid "WARNING: source file `%s' modified since program compilation.\n"
+msgstr ""
+
+#: debug.c:551
+#, c-format
+msgid "line number %d out of range; `%s' has %d lines"
+msgstr ""
+
+#: debug.c:611
+#, c-format
+msgid "unexpected eof while reading file `%s', line %d"
+msgstr ""
+
+#: debug.c:620
+#, c-format
+msgid "source file `%s' modified since start of program execution"
+msgstr ""
+
+#: debug.c:732
+#, c-format
+msgid "Current source file: %s\n"
+msgstr ""
+
+#: debug.c:733
+#, c-format
+msgid "Number of lines: %d\n"
+msgstr ""
+
+#: debug.c:740
+#, c-format
+msgid "Source file (lines): %s (%d)\n"
+msgstr ""
+
+#: debug.c:754
+msgid ""
+"Number Disp Enabled Location\n"
+"\n"
+msgstr ""
+
+#: debug.c:765
+#, c-format
+msgid "\tno of hits = %ld\n"
+msgstr ""
+
+#: debug.c:767
+#, c-format
+msgid "\tignore next %ld hit(s)\n"
+msgstr ""
+
+#: debug.c:769 debug.c:909
+#, c-format
+msgid "\tstop condition: %s\n"
+msgstr ""
+
+#: debug.c:771 debug.c:911
+msgid "\tcommands:\n"
+msgstr ""
+
+#: debug.c:793
+#, c-format
+msgid "Current frame: "
+msgstr ""
+
+#: debug.c:796
+#, c-format
+msgid "Called by frame: "
+msgstr ""
+
+#: debug.c:800
+#, c-format
+msgid "Caller of frame: "
+msgstr ""
+
+#: debug.c:818
+#, c-format
+msgid "None in main().\n"
+msgstr ""
+
+#: debug.c:848
+msgid "No arguments.\n"
+msgstr ""
+
+#: debug.c:849
+msgid "No locals.\n"
+msgstr ""
+
+#: debug.c:857
+msgid ""
+"All defined variables:\n"
+"\n"
+msgstr ""
+
+#: debug.c:867
+msgid ""
+"All defined functions:\n"
+"\n"
+msgstr ""
+
+#: debug.c:886
+msgid ""
+"Auto-display variables:\n"
+"\n"
+msgstr ""
+
+#: debug.c:889
+msgid ""
+"Watch variables:\n"
+"\n"
+msgstr ""
+
+#: debug.c:1029
+#, c-format
+msgid "no symbol `%s' in current context\n"
+msgstr ""
+
+#: debug.c:1041 debug.c:1427
+#, c-format
+msgid "`%s' is not an array\n"
+msgstr ""
+
+#: debug.c:1055
+#, c-format
+msgid "$%ld = uninitialized field\n"
+msgstr ""
+
+#: debug.c:1076
+#, c-format
+msgid "array `%s' is empty\n"
+msgstr ""
+
+#: debug.c:1119 debug.c:1171
+#, c-format
+msgid "[\"%s\"] not in array `%s'\n"
+msgstr ""
+
+#: debug.c:1175
+#, c-format
+msgid "`%s[\"%s\"]' is not an array\n"
+msgstr ""
+
+#: debug.c:1236 debug.c:4964
+#, c-format
+msgid "`%s' is not a scalar variable"
+msgstr ""
+
+#: debug.c:1258 debug.c:4994
+#, c-format
+msgid "attempt to use array `%s[\"%s\"]' in a scalar context"
+msgstr ""
+
+#: debug.c:1280 debug.c:5005
+#, c-format
+msgid "attempt to use scalar `%s[\"%s\"]' as array"
+msgstr ""
+
+#: debug.c:1423
+#, c-format
+msgid "`%s' is a function"
+msgstr ""
+
+#: debug.c:1465
+#, c-format
+msgid "watchpoint %d is unconditional\n"
+msgstr ""
+
+#: debug.c:1499
+#, c-format
+msgid "No display item numbered %ld"
+msgstr ""
+
+#: debug.c:1502
+#, c-format
+msgid "No watch item numbered %ld"
+msgstr ""
+
+#: debug.c:1528
+#, c-format
+msgid "%d: [\"%s\"] not in array `%s'\n"
+msgstr ""
+
+#: debug.c:1767
+msgid "attempt to use scalar value as array"
+msgstr ""
+
+#: debug.c:1856
+#, c-format
+msgid "Watchpoint %d deleted because parameter is out of scope.\n"
+msgstr ""
+
+#: debug.c:1867
+#, c-format
+msgid "Display %d deleted because parameter is out of scope.\n"
+msgstr ""
+
+#: debug.c:1900
+#, c-format
+msgid " in file `%s', line %d\n"
+msgstr ""
+
+#: debug.c:1921
+#, c-format
+msgid " at `%s':%d"
+msgstr ""
+
+#: debug.c:1937 debug.c:2000
+#, c-format
+msgid "#%ld\tin "
+msgstr ""
+
+#: debug.c:1974
+#, c-format
+msgid "More stack frames follow ...\n"
+msgstr ""
+
+#: debug.c:2017
+msgid "invalid frame number"
+msgstr ""
+
+#: debug.c:2200
+#, c-format
+msgid "Note: breakpoint %d (enabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2207
+#, c-format
+msgid "Note: breakpoint %d (enabled), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2214
+#, c-format
+msgid "Note: breakpoint %d (disabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2221
+#, c-format
+msgid "Note: breakpoint %d (disabled), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2238
+#, c-format
+msgid "Breakpoint %d set at file `%s', line %d\n"
+msgstr ""
+
+#: debug.c:2340
+#, c-format
+msgid "Can't set breakpoint in file `%s'\n"
+msgstr ""
+
+#: debug.c:2369 debug.c:2492 debug.c:3350
+#, c-format
+msgid "line number %d in file `%s' out of range"
+msgstr ""
+
+#: debug.c:2373
+#, c-format
+msgid "Can't find rule!!!\n"
+msgstr ""
+
+#: debug.c:2375
+#, c-format
+msgid "Can't set breakpoint at `%s':%d\n"
+msgstr ""
+
+#: debug.c:2387
+#, c-format
+msgid "Can't set breakpoint in function `%s'\n"
+msgstr ""
+
+#: debug.c:2403
+#, c-format
+msgid "breakpoint %d set at file `%s', line %d is unconditional\n"
+msgstr ""
+
+#: debug.c:2508 debug.c:2530
+#, c-format
+msgid "Deleted breakpoint %d"
+msgstr ""
+
+#: debug.c:2514
+#, c-format
+msgid "No breakpoint(s) at entry to function `%s'\n"
+msgstr ""
+
+#: debug.c:2541
+#, c-format
+msgid "No breakpoint at file `%s', line #%d\n"
+msgstr ""
+
+#: debug.c:2596 debug.c:2637 debug.c:2657 debug.c:2700
+msgid "invalid breakpoint number"
+msgstr ""
+
+#: debug.c:2612
+msgid "Delete all breakpoints? (y or n) "
+msgstr ""
+
+#: debug.c:2613 debug.c:2923 debug.c:2976
+msgid "y"
+msgstr ""
+
+#: debug.c:2662
+#, c-format
+msgid "Will ignore next %ld crossing(s) of breakpoint %d.\n"
+msgstr ""
+
+#: debug.c:2666
+#, c-format
+msgid "Will stop next time breakpoint %d is reached.\n"
+msgstr ""
+
+#: debug.c:2783
+#, c-format
+msgid "Can only debug programs provided with the `-f' option.\n"
+msgstr ""
+
+#: debug.c:2908
+#, c-format
+msgid "Failed to restart debugger"
+msgstr ""
+
+#: debug.c:2922
+msgid "Program already running. Restart from beginning (y/n)? "
+msgstr ""
+
+#: debug.c:2926
+#, c-format
+msgid "Program not restarted\n"
+msgstr ""
+
+#: debug.c:2936
+#, c-format
+msgid "error: cannot restart, operation not allowed\n"
+msgstr ""
+
+#: debug.c:2942
+#, c-format
+msgid "error (%s): cannot restart, ignoring rest of the commands\n"
+msgstr ""
+
+#: debug.c:2950
+#, c-format
+msgid "Starting program: \n"
+msgstr ""
+
+#: debug.c:2959
+#, c-format
+msgid "Program exited %s with exit value: %d\n"
+msgstr ""
+
+#: debug.c:2975
+msgid "The program is running. Exit anyway (y/n)? "
+msgstr ""
+
+#: debug.c:3010
+#, c-format
+msgid "Not stopped at any breakpoint; argument ignored.\n"
+msgstr ""
+
+#: debug.c:3015
+#, c-format
+msgid "invalid breakpoint number %d."
+msgstr ""
+
+#: debug.c:3020
+#, c-format
+msgid "Will ignore next %ld crossings of breakpoint %d.\n"
+msgstr ""
+
+#: debug.c:3207
+#, c-format
+msgid "'finish' not meaningful in the outermost frame main()\n"
+msgstr ""
+
+#: debug.c:3212
+#, c-format
+msgid "Run till return from "
+msgstr ""
+
+#: debug.c:3255
+#, c-format
+msgid "'return' not meaningful in the outermost frame main()\n"
+msgstr ""
+
+#: debug.c:3369
+#, c-format
+msgid "Can't find specified location in function `%s'\n"
+msgstr ""
+
+#: debug.c:3377
+#, c-format
+msgid "invalid source line %d in file `%s'"
+msgstr ""
+
+#: debug.c:3392
+#, c-format
+msgid "Can't find specified location %d in file `%s'\n"
+msgstr ""
+
+#: debug.c:3424
+#, c-format
+msgid "element not in array\n"
+msgstr ""
+
+#: debug.c:3424
+#, c-format
+msgid "untyped variable\n"
+msgstr ""
+
+#: debug.c:3466
+#, c-format
+msgid "Stopping in %s ...\n"
+msgstr ""
+
+#: debug.c:3543
+#, c-format
+msgid "'finish' not meaningful with non-local jump '%s'\n"
+msgstr ""
+
+#: debug.c:3550
+#, c-format
+msgid "'until' not meaningful with non-local jump '%s'\n"
+msgstr ""
+
+#: debug.c:4185
+msgid "\t------[Enter] to continue or q [Enter] to quit------"
+msgstr ""
+
+#: debug.c:4186
+msgid "q"
+msgstr ""
+
+#: debug.c:5001
+#, c-format
+msgid "[\"%s\"] not in array `%s'"
+msgstr ""
+
+#: debug.c:5207
+#, c-format
+msgid "sending output to stdout\n"
+msgstr ""
+
+#: debug.c:5247
+msgid "invalid number"
+msgstr ""
+
+#: debug.c:5381
+#, c-format
+msgid "`%s' not allowed in current context; statement ignored"
+msgstr ""
+
+#: debug.c:5389
+msgid "`return' not allowed in current context; statement ignored"
+msgstr ""
+
+#: debug.c:5590
+#, c-format
+msgid "No symbol `%s' in current context"
+msgstr ""
+
+#: dfa.c:1118 dfa.c:1121 dfa.c:1142 dfa.c:1150 dfa.c:1162 dfa.c:1197
+#: dfa.c:1206 dfa.c:1209 dfa.c:1214 dfa.c:1228 dfa.c:1275
+msgid "unbalanced ["
+msgstr ""
+
+#: dfa.c:1174
+msgid "invalid character class"
+msgstr ""
+
+#: dfa.c:1316
+msgid "character class syntax is [[:space:]], not [:space:]"
+msgstr ""
+
+#: dfa.c:1366
+msgid "unfinished \\ escape"
+msgstr ""
+
+#: dfa.c:1513 regcomp.c:161
+msgid "Invalid content of \\{\\}"
+msgstr ""
+
+#: dfa.c:1516 regcomp.c:176
+msgid "Regular expression too big"
+msgstr ""
+
+#: dfa.c:1936
+msgid "unbalanced ("
+msgstr ""
+
+#: dfa.c:2062
+msgid "no syntax specified"
+msgstr ""
+
+#: dfa.c:2070
+msgid "unbalanced )"
+msgstr ""
+
+#: eval.c:394
#, c-format
msgid "unknown nodetype %d"
msgstr ""
-#: eval.c:423 eval.c:437
+#: eval.c:405 eval.c:419
#, c-format
msgid "unknown opcode %d"
msgstr ""
-#: eval.c:434
+#: eval.c:416
#, c-format
msgid "opcode %s not an operator or keyword"
msgstr ""
-#: eval.c:488
+#: eval.c:472
msgid "buffer overflow in genflags2str"
msgstr ""
-#: eval.c:698
+#: eval.c:675
#, c-format
msgid ""
"\n"
@@ -962,788 +1800,1205 @@ msgid ""
"\n"
msgstr ""
-#: eval.c:725
+#: eval.c:704
msgid "`IGNORECASE' is a gawk extension"
msgstr ""
-#: eval.c:754
+#: eval.c:736
msgid "`BINMODE' is a gawk extension"
msgstr ""
-#: eval.c:812
+#: eval.c:794
#, c-format
msgid "BINMODE value `%s' is invalid, treated as 3"
msgstr ""
-#: eval.c:902
+#: eval.c:885
#, c-format
msgid "bad `%sFMT' specification `%s'"
msgstr ""
-#: eval.c:980
+#: eval.c:969
msgid "turning off `--lint' due to assignment to `LINT'"
msgstr ""
-#: eval.c:1127 eval.c:1777
+#: eval.c:1147
#, c-format
-msgid "can't use function name `%s' as variable or array"
+msgid "reference to uninitialized argument `%s'"
msgstr ""
-#: eval.c:1158 eval.c:1789 eval.c:1802
+#: eval.c:1148
#, c-format
-msgid "reference to uninitialized argument `%s'"
+msgid "reference to uninitialized variable `%s'"
msgstr ""
-#: eval.c:1177
+#: eval.c:1166
msgid "attempt to field reference from non-numeric value"
msgstr ""
-#: eval.c:1179
+#: eval.c:1168
msgid "attempt to field reference from null string"
msgstr ""
-#: eval.c:1185
+#: eval.c:1176
#, c-format
msgid "attempt to access field %ld"
msgstr ""
-#: eval.c:1194
+#: eval.c:1185
#, c-format
msgid "reference to uninitialized field `$%ld'"
msgstr ""
-#: eval.c:1256
+#: eval.c:1272
#, c-format
msgid "function `%s' called with more arguments than declared"
msgstr ""
-#: eval.c:1437
+#: eval.c:1473
#, c-format
msgid "unwind_stack: unexpected type `%s'"
msgstr ""
-#: eval.c:1532
+#: eval.c:1569
msgid "division by zero attempted in `/='"
msgstr ""
-#: eval.c:1539
+#: eval.c:1576
#, c-format
msgid "division by zero attempted in `%%='"
msgstr ""
-#: eval.c:1876 eval.c:2122
-#, c-format
-msgid "attempt to use array `%s[\"%.*s\"]' in a scalar context"
+#: ext.c:89 ext.c:171
+msgid "extensions are not allowed in sandbox mode"
msgstr ""
-#: eval.c:1907
-msgid "assignment used in conditional context"
+#: ext.c:92
+msgid "-l / @load are gawk extensions"
msgstr ""
-#: eval.c:1911
-msgid "statement has no effect"
+#: ext.c:95
+msgid "load_ext: received NULL lib_name"
msgstr ""
-#: eval.c:2343
+#: ext.c:98
#, c-format
-msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+msgid "load_ext: cannot open library `%s' (%s)\n"
msgstr ""
-#: eval.c:2458
+#: ext.c:104
#, c-format
-msgid "function called indirectly through `%s' does not exist"
+msgid ""
+"load_ext: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"
msgstr ""
-#: eval.c:2470
+#: ext.c:110
#, c-format
-msgid "function `%s' not defined"
+msgid "load_ext: library `%s': cannot call function `%s' (%s)\n"
msgstr ""
-#: eval.c:2511
+#: ext.c:114
#, c-format
-msgid "non-redirected `getline' invalid inside `%s' rule"
+msgid "load_ext: library `%s' initialization routine `%s' failed\n"
msgstr ""
-#: eval.c:2600
-#, c-format
-msgid "error reading input file `%s': %s"
+#: ext.c:174
+msgid "`extension' is a gawk extension"
+msgstr ""
+
+#: ext.c:177
+msgid "extension: received NULL lib_name"
msgstr ""
-#: eval.c:2614
+#: ext.c:180
#, c-format
-msgid "`nextfile' cannot be called from a `%s' rule"
+msgid "extension: cannot open library `%s' (%s)"
msgstr ""
-#: eval.c:2694
+#: ext.c:186
#, c-format
-msgid "`next' cannot be called from a `%s' rule"
+msgid ""
+"extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)"
msgstr ""
-#: eval.c:2760
+#: ext.c:190
#, c-format
-msgid "Sorry, don't know how to interpret `%s'"
+msgid "extension: library `%s': cannot call function `%s' (%s)"
msgstr ""
-#: ext.c:64
-msgid "extensions are not allowed in sandbox mode"
+#: ext.c:221
+msgid "make_builtin: missing function name"
msgstr ""
-#: ext.c:70 ext.c:75
-msgid "`extension' is a gawk extension"
+#: ext.c:236
+#, c-format
+msgid "make_builtin: can't redefine function `%s'"
msgstr ""
-#: ext.c:85
+#: ext.c:240
#, c-format
-msgid "fatal: extension: cannot open `%s' (%s)\n"
+msgid "make_builtin: function `%s' already defined"
msgstr ""
-#: ext.c:94
+#: ext.c:244
#, c-format
-msgid ""
-"fatal: extension: library `%s': does not define "
-"`plugin_is_GPL_compatible' (%s)\n"
+msgid "make_builtin: function name `%s' previously defined"
msgstr ""
-#: ext.c:103
+#: ext.c:246
#, c-format
-msgid "fatal: extension: library `%s': cannot call function `%s' (%s)\n"
+msgid "make_builtin: can't use gawk built-in `%s' as function name"
msgstr ""
-#: ext.c:137
+#: ext.c:249 ext.c:304
+#, c-format
+msgid "make_builtin: negative argument count for function `%s'"
+msgstr ""
+
+#: ext.c:276
msgid "extension: missing function name"
msgstr ""
-#: ext.c:142
+#: ext.c:279 ext.c:283
#, c-format
msgid "extension: illegal character `%c' in function name `%s'"
msgstr ""
-#: ext.c:151
+#: ext.c:291
#, c-format
msgid "extension: can't redefine function `%s'"
msgstr ""
-#: ext.c:155
+#: ext.c:295
#, c-format
msgid "extension: function `%s' already defined"
msgstr ""
-#: ext.c:160
+#: ext.c:299
#, c-format
msgid "extension: function name `%s' previously defined"
msgstr ""
-#: ext.c:162
+#: ext.c:301
#, c-format
msgid "extension: can't use gawk built-in `%s' as function name"
msgstr ""
-#: ext.c:166
-#, c-format
-msgid "make_builtin: negative argument count for function `%s'"
-msgstr ""
-
-#: ext.c:269
+#: ext.c:375
#, c-format
msgid "function `%s' defined to take no more than %d argument(s)"
msgstr ""
-#: ext.c:272
+#: ext.c:378
#, c-format
msgid "function `%s': missing argument #%d"
msgstr ""
-#: ext.c:289
+#: ext.c:395
#, c-format
msgid "function `%s': argument #%d: attempt to use scalar as an array"
msgstr ""
-#: ext.c:293
+#: ext.c:399
#, c-format
msgid "function `%s': argument #%d: attempt to use array as a scalar"
msgstr ""
-#: ext.c:306
-msgid "Operation Not Supported"
+#: ext.c:413
+msgid "dynamic loading of library not supported"
+msgstr ""
+
+#: extension/filefuncs.c:159
+msgid "chdir: called with incorrect number of arguments, expecting 1"
+msgstr ""
+
+#: extension/filefuncs.c:439
+#, c-format
+msgid "stat: unable to read symbolic link `%s'"
+msgstr ""
+
+#: extension/filefuncs.c:472
+msgid "stat: called with wrong number of arguments"
+msgstr ""
+
+#: extension/filefuncs.c:479
+msgid "stat: bad parameters"
+msgstr ""
+
+#: extension/filefuncs.c:533
+#, c-format
+msgid "fts init: could not create variable %s"
+msgstr ""
+
+#: extension/filefuncs.c:554
+msgid "fts is not supported on this system"
+msgstr ""
+
+#: extension/filefuncs.c:573
+msgid "fill_stat_element: could not create array"
+msgstr ""
+
+#: extension/filefuncs.c:582
+msgid "fill_stat_element: could not set element"
+msgstr ""
+
+#: extension/filefuncs.c:597
+msgid "fill_path_element: could not set element"
+msgstr ""
+
+#: extension/filefuncs.c:613
+msgid "fill_error_element: could not set element"
+msgstr ""
+
+#: extension/filefuncs.c:660 extension/filefuncs.c:707
+msgid "fts-process: could not create array"
+msgstr ""
+
+#: extension/filefuncs.c:670 extension/filefuncs.c:717
+#: extension/filefuncs.c:735
+msgid "fts-process: could not set element"
+msgstr ""
+
+#: extension/filefuncs.c:784
+msgid "fts: called with incorrect number of arguments, expecting 3"
+msgstr ""
+
+#: extension/filefuncs.c:787
+msgid "fts: bad first parameter"
+msgstr ""
+
+#: extension/filefuncs.c:793
+msgid "fts: bad second parameter"
+msgstr ""
+
+#: extension/filefuncs.c:799
+msgid "fts: bad third parameter"
+msgstr ""
+
+#: extension/filefuncs.c:806
+msgid "fts: could not flatten array\n"
+msgstr ""
+
+#: extension/filefuncs.c:824
+msgid "fts: ignoring sneaky FTS_NOSTAT flag. nyah, nyah, nyah."
+msgstr ""
+
+#: extension/filefuncs.c:841
+msgid "fts: clear_array() failed\n"
+msgstr ""
+
+#: extension/fnmatch.c:112
+msgid "fnmatch: called with less than three arguments"
+msgstr ""
+
+#: extension/fnmatch.c:115
+msgid "fnmatch: called with more than three arguments"
+msgstr ""
+
+#: extension/fnmatch.c:118
+msgid "fnmatch: could not get first argument"
+msgstr ""
+
+#: extension/fnmatch.c:123
+msgid "fnmatch: could not get second argument"
+msgstr ""
+
+#: extension/fnmatch.c:128
+msgid "fnmatch: could not get third argument"
+msgstr ""
+
+#: extension/fnmatch.c:141
+msgid "fnmatch is not implemented on this system\n"
+msgstr ""
+
+#: extension/fnmatch.c:173
+msgid "fnmatch init: could not add FNM_NOMATCH variable"
+msgstr ""
+
+#: extension/fnmatch.c:183
+#, c-format
+msgid "fnmatch init: could not set array element %s"
+msgstr ""
+
+#: extension/fnmatch.c:193
+msgid "fnmatch init: could not install FNM array"
+msgstr ""
+
+#: extension/fork.c:81
+msgid "fork: called with too many arguments"
+msgstr ""
+
+#: extension/fork.c:94
+msgid "fork: PROCINFO is not an array!"
+msgstr ""
+
+#: extension/fork.c:118
+msgid "waitpid: called with too many arguments"
+msgstr ""
+
+#: extension/fork.c:126
+msgid "wait: called with no arguments"
+msgstr ""
+
+#: extension/fork.c:143
+msgid "wait: called with too many arguments"
+msgstr ""
+
+#: extension/inplace.c:130
+msgid "inplace_begin: in-place editing already active"
+msgstr ""
+
+#: extension/inplace.c:133 extension/inplace.c:207
+#, c-format
+msgid "inplace_begin: expects 2 arguments but called with %d"
+msgstr ""
+
+#: extension/inplace.c:136
+msgid "inplace_begin: cannot retrieve 1st argument as a string filename"
+msgstr ""
+
+#: extension/inplace.c:144
+#, c-format
+msgid "inplace_begin: disabling in-place editing for invalid FILENAME `%s'"
+msgstr ""
+
+#: extension/inplace.c:151
+#, c-format
+msgid "inplace_begin: Cannot stat `%s' (%s)"
+msgstr ""
+
+#: extension/inplace.c:158
+#, c-format
+msgid "inplace_begin: `%s' is not a regular file"
+msgstr ""
+
+#: extension/inplace.c:169
+#, c-format
+msgid "inplace_begin: mkstemp(`%s') failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:178
+#, c-format
+msgid "inplace_begin: chmod failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:185
+#, c-format
+msgid "inplace_begin: dup(stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:188
+#, c-format
+msgid "inplace_begin: dup2(%d, stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:191
+#, c-format
+msgid "inplace_begin: close(%d) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:210
+msgid "inplace_end: cannot retrieve 1st argument as a string filename"
+msgstr ""
+
+#: extension/inplace.c:217
+msgid "inplace_end: in-place editing not active"
+msgstr ""
+
+#: extension/inplace.c:223
+#, c-format
+msgid "inplace_end: dup2(%d, stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:226
+#, c-format
+msgid "inplace_end: close(%d) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:230
+#, c-format
+msgid "inplace_end: fsetpos(stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:243
+#, c-format
+msgid "inplace_end: link(`%s', `%s') failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:253
+#, c-format
+msgid "inplace_end: rename(`%s', `%s') failed (%s)"
+msgstr ""
+
+#: extension/ordchr.c:69
+msgid "ord: called with too many arguments"
+msgstr ""
+
+#: extension/ordchr.c:75
+msgid "ord: called with no arguments"
+msgstr ""
+
+#: extension/ordchr.c:77
+msgid "ord: called with inappropriate argument(s)"
+msgstr ""
+
+#: extension/ordchr.c:99
+msgid "chr: called with too many arguments"
msgstr ""
-#: field.c:328
+#: extension/ordchr.c:109
+msgid "chr: called with no arguments"
+msgstr ""
+
+#: extension/ordchr.c:111
+msgid "chr: called with inappropriate argument(s)"
+msgstr ""
+
+#: extension/readdir.c:281
+#, c-format
+msgid "dir_take_control_of: opendir/fdopendir failed: %s"
+msgstr ""
+
+#: extension/readfile.c:113
+msgid "readfile: called with too many arguments"
+msgstr ""
+
+#: extension/readfile.c:137
+msgid "readfile: called with no arguments"
+msgstr ""
+
+#: extension/rwarray.c:124
+msgid "writea: called with too many arguments"
+msgstr ""
+
+#: extension/rwarray.c:131
+#, c-format
+msgid "do_writea: argument 0 is not a string\n"
+msgstr ""
+
+#: extension/rwarray.c:137
+#, c-format
+msgid "do_writea: argument 1 is not an array\n"
+msgstr ""
+
+#: extension/rwarray.c:184
+#, c-format
+msgid "write_array: could not flatten array\n"
+msgstr ""
+
+#: extension/rwarray.c:198
+#, c-format
+msgid "write_array: could not release flattened array\n"
+msgstr ""
+
+#: extension/rwarray.c:280
+msgid "reada: called with too many arguments"
+msgstr ""
+
+#: extension/rwarray.c:287
+#, c-format
+msgid "do_reada: argument 0 is not a string\n"
+msgstr ""
+
+#: extension/rwarray.c:293
+#, c-format
+msgid "do_reada: argument 1 is not an array\n"
+msgstr ""
+
+#: extension/rwarray.c:337
+#, c-format
+msgid "do_reada: clear_array failed\n"
+msgstr ""
+
+#: extension/rwarray.c:374
+#, c-format
+msgid "read_array: set_array_element failed\n"
+msgstr ""
+
+#: extension/time.c:113
+msgid "gettimeofday: ignoring arguments"
+msgstr ""
+
+#: extension/time.c:144
+msgid "gettimeofday: not supported on this platform"
+msgstr ""
+
+#: extension/time.c:165
+msgid "sleep: called with too many arguments"
+msgstr ""
+
+#: extension/time.c:168
+msgid "sleep: missing required numeric argument"
+msgstr ""
+
+#: extension/time.c:174
+msgid "sleep: argument is negative"
+msgstr ""
+
+#: extension/time.c:208
+msgid "sleep: not supported on this platform"
+msgstr ""
+
+#: field.c:345
msgid "NF set to negative value"
msgstr ""
-#: field.c:951 field.c:958 field.c:962
+#: field.c:971 field.c:978 field.c:982
msgid "split: fourth argument is a gawk extension"
msgstr ""
-#: field.c:955
+#: field.c:975
msgid "split: fourth argument is not an array"
msgstr ""
-#: field.c:969
+#: field.c:989
msgid "split: second argument is not an array"
msgstr ""
-#: field.c:973
+#: field.c:993
msgid "split: cannot use the same array for second and fourth args"
msgstr ""
-#: field.c:978
+#: field.c:998
msgid "split: cannot use a subarray of second arg for fourth arg"
msgstr ""
-#: field.c:981
+#: field.c:1001
msgid "split: cannot use a subarray of fourth arg for second arg"
msgstr ""
-#: field.c:1010
+#: field.c:1032
msgid "split: null string for third arg is a gawk extension"
msgstr ""
-#: field.c:1050
+#: field.c:1072
msgid "patsplit: fourth argument is not an array"
msgstr ""
-#: field.c:1055
+#: field.c:1077
msgid "patsplit: second argument is not an array"
msgstr ""
-#: field.c:1061
+#: field.c:1083
msgid "patsplit: third argument must be non-null"
msgstr ""
-#: field.c:1065
+#: field.c:1087
msgid "patsplit: cannot use the same array for second and fourth args"
msgstr ""
-#: field.c:1070
+#: field.c:1092
msgid "patsplit: cannot use a subarray of second arg for fourth arg"
msgstr ""
-#: field.c:1073
+#: field.c:1095
msgid "patsplit: cannot use a subarray of fourth arg for second arg"
msgstr ""
-#: field.c:1110
+#: field.c:1133
msgid "`FIELDWIDTHS' is a gawk extension"
msgstr ""
-#: field.c:1173
+#: field.c:1197
#, c-format
msgid "invalid FIELDWIDTHS value, near `%s'"
msgstr ""
-#: field.c:1246
+#: field.c:1270
msgid "null string for `FS' is a gawk extension"
msgstr ""
-#: field.c:1250
+#: field.c:1274
msgid "old awk does not support regexps as value of `FS'"
msgstr ""
-#: field.c:1369
+#: field.c:1393
msgid "`FPAT' is a gawk extension"
msgstr ""
-#: getopt.c:574 getopt.c:590
+#: gawkapi.c:146
+msgid "awk_value_to_node: received null retval"
+msgstr ""
+
+#: gawkapi.c:384
+msgid "node_to_awk_value: received null node"
+msgstr ""
+
+#: gawkapi.c:387
+msgid "node_to_awk_value: received null val"
+msgstr ""
+
+#: gawkapi.c:807
+msgid "remove_element: received null array"
+msgstr ""
+
+#: gawkapi.c:810
+msgid "remove_element: received null subscript"
+msgstr ""
+
+#: gawkapi.c:947
#, c-format
-msgid "%s: option '%s' is ambiguous\n"
+msgid "api_flatten_array: could not convert index %d\n"
msgstr ""
-#: getopt.c:623 getopt.c:627
+#: gawkapi.c:952
+#, c-format
+msgid "api_flatten_array: could not convert value %d\n"
+msgstr ""
+
+#: getopt.c:604 getopt.c:633
+#, c-format
+msgid "%s: option '%s' is ambiguous; possibilities:"
+msgstr ""
+
+#: getopt.c:679 getopt.c:683
#, c-format
msgid "%s: option '--%s' doesn't allow an argument\n"
msgstr ""
-#: getopt.c:636 getopt.c:641
+#: getopt.c:692 getopt.c:697
#, c-format
msgid "%s: option '%c%s' doesn't allow an argument\n"
msgstr ""
-#: getopt.c:684 getopt.c:703
+#: getopt.c:740 getopt.c:759
#, c-format
msgid "%s: option '--%s' requires an argument\n"
msgstr ""
-#: getopt.c:741 getopt.c:744
+#: getopt.c:797 getopt.c:800
#, c-format
msgid "%s: unrecognized option '--%s'\n"
msgstr ""
-#: getopt.c:752 getopt.c:755
+#: getopt.c:808 getopt.c:811
#, c-format
msgid "%s: unrecognized option '%c%s'\n"
msgstr ""
-#: getopt.c:804 getopt.c:807
+#: getopt.c:860 getopt.c:863
#, c-format
msgid "%s: invalid option -- '%c'\n"
msgstr ""
-#: getopt.c:857 getopt.c:874 getopt.c:1082 getopt.c:1100
+#: getopt.c:916 getopt.c:933 getopt.c:1143 getopt.c:1161
#, c-format
msgid "%s: option requires an argument -- '%c'\n"
msgstr ""
-#: getopt.c:930 getopt.c:946
+#: getopt.c:989 getopt.c:1005
#, c-format
msgid "%s: option '-W %s' is ambiguous\n"
msgstr ""
-#: getopt.c:970 getopt.c:988
+#: getopt.c:1029 getopt.c:1047
#, c-format
msgid "%s: option '-W %s' doesn't allow an argument\n"
msgstr ""
-#: getopt.c:1009 getopt.c:1027
+#: getopt.c:1068 getopt.c:1086
#, c-format
msgid "%s: option '-W %s' requires an argument\n"
msgstr ""
-#: io.c:280
+#: io.c:392
#, c-format
msgid "command line argument `%s' is a directory: skipped"
msgstr ""
-#: io.c:283 io.c:385
+#: io.c:395 io.c:513
#, c-format
msgid "cannot open file `%s' for reading (%s)"
msgstr ""
-#: io.c:501
+#: io.c:640
#, c-format
msgid "close of fd %d (`%s') failed (%s)"
msgstr ""
-#: io.c:578
+#: io.c:716
msgid "redirection not allowed in sandbox mode"
msgstr ""
-#: io.c:612
+#: io.c:750
#, c-format
msgid "expression in `%s' redirection only has numeric value"
msgstr ""
-#: io.c:618
+#: io.c:756
#, c-format
msgid "expression for `%s' redirection has null string value"
msgstr ""
-#: io.c:624
+#: io.c:761
#, c-format
msgid "filename `%s' for `%s' redirection may be result of logical expression"
msgstr ""
-#: io.c:667
+#: io.c:809
#, c-format
msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
msgstr ""
-#: io.c:720
+#: io.c:863
#, c-format
msgid "can't open pipe `%s' for output (%s)"
msgstr ""
-#: io.c:730
+#: io.c:873
#, c-format
msgid "can't open pipe `%s' for input (%s)"
msgstr ""
-#: io.c:753
+#: io.c:904
#, c-format
msgid "can't open two way pipe `%s' for input/output (%s)"
msgstr ""
-#: io.c:835
+#: io.c:986
#, c-format
msgid "can't redirect from `%s' (%s)"
msgstr ""
-#: io.c:838
+#: io.c:989
#, c-format
msgid "can't redirect to `%s' (%s)"
msgstr ""
-#: io.c:889
+#: io.c:1040
msgid ""
"reached system limit for open files: starting to multiplex file descriptors"
msgstr ""
-#: io.c:905
+#: io.c:1056
#, c-format
msgid "close of `%s' failed (%s)."
msgstr ""
-#: io.c:913
+#: io.c:1064
msgid "too many pipes or input files open"
msgstr ""
-#: io.c:935
+#: io.c:1086
msgid "close: second argument must be `to' or `from'"
msgstr ""
-#: io.c:952
+#: io.c:1103
#, c-format
msgid "close: `%.*s' is not an open file, pipe or co-process"
msgstr ""
-#: io.c:957
+#: io.c:1108
msgid "close of redirection that was never opened"
msgstr ""
-#: io.c:1054
+#: io.c:1205
#, c-format
msgid "close: redirection `%s' not opened with `|&', second argument ignored"
msgstr ""
-#: io.c:1070
+#: io.c:1222
#, c-format
msgid "failure status (%d) on pipe close of `%s' (%s)"
msgstr ""
-#: io.c:1073
+#: io.c:1225
#, c-format
msgid "failure status (%d) on file close of `%s' (%s)"
msgstr ""
-#: io.c:1093
+#: io.c:1245
#, c-format
msgid "no explicit close of socket `%s' provided"
msgstr ""
-#: io.c:1096
+#: io.c:1248
#, c-format
msgid "no explicit close of co-process `%s' provided"
msgstr ""
-#: io.c:1099
+#: io.c:1251
#, c-format
msgid "no explicit close of pipe `%s' provided"
msgstr ""
-#: io.c:1102
+#: io.c:1254
#, c-format
msgid "no explicit close of file `%s' provided"
msgstr ""
-#: io.c:1130 io.c:1185 main.c:793 main.c:830
+#: io.c:1284 io.c:1342 main.c:864 main.c:906
#, c-format
msgid "error writing standard output (%s)"
msgstr ""
-#: io.c:1134 io.c:1190
+#: io.c:1289 io.c:1348 main.c:866
#, c-format
msgid "error writing standard error (%s)"
msgstr ""
-#: io.c:1142
+#: io.c:1297
#, c-format
msgid "pipe flush of `%s' failed (%s)."
msgstr ""
-#: io.c:1145
+#: io.c:1300
#, c-format
msgid "co-process flush of pipe to `%s' failed (%s)."
msgstr ""
-#: io.c:1148
+#: io.c:1303
#, c-format
msgid "file flush of `%s' failed (%s)."
msgstr ""
-#: io.c:1263
+#: io.c:1420
#, c-format
msgid "local port %s invalid in `/inet'"
msgstr ""
-#: io.c:1280
+#: io.c:1438
#, c-format
msgid "remote host and port information (%s, %s) invalid"
msgstr ""
-#: io.c:1432
+#: io.c:1590
#, c-format
msgid "no (known) protocol supplied in special filename `%s'"
msgstr ""
-#: io.c:1446
+#: io.c:1604
#, c-format
msgid "special file name `%s' is incomplete"
msgstr ""
-#: io.c:1463
+#: io.c:1621
msgid "must supply a remote hostname to `/inet'"
msgstr ""
-#: io.c:1481
+#: io.c:1639
msgid "must supply a remote port to `/inet'"
msgstr ""
-#: io.c:1527
+#: io.c:1685
msgid "TCP/IP communications are not supported"
msgstr ""
-#: io.c:1694
+#: io.c:1867
#, c-format
msgid "could not open `%s', mode `%s'"
msgstr ""
-#: io.c:1748
+#: io.c:1917
#, c-format
msgid "close of master pty failed (%s)"
msgstr ""
-#: io.c:1750 io.c:1918 io.c:2075
+#: io.c:1919 io.c:2105 io.c:2305
#, c-format
msgid "close of stdout in child failed (%s)"
msgstr ""
-#: io.c:1753
+#: io.c:1922
#, c-format
msgid "moving slave pty to stdout in child failed (dup: %s)"
msgstr ""
-#: io.c:1755 io.c:1923
+#: io.c:1924 io.c:2110
#, c-format
msgid "close of stdin in child failed (%s)"
msgstr ""
-#: io.c:1758
+#: io.c:1927
#, c-format
msgid "moving slave pty to stdin in child failed (dup: %s)"
msgstr ""
-#: io.c:1760 io.c:1781
+#: io.c:1929 io.c:1951
#, c-format
msgid "close of slave pty failed (%s)"
msgstr ""
-#: io.c:1859 io.c:1921 io.c:2053 io.c:2078
+#: io.c:2040 io.c:2108 io.c:2276 io.c:2308
#, c-format
msgid "moving pipe to stdout in child failed (dup: %s)"
msgstr ""
-#: io.c:1866 io.c:1926
+#: io.c:2047 io.c:2113
#, c-format
msgid "moving pipe to stdin in child failed (dup: %s)"
msgstr ""
-#: io.c:1886 io.c:2068
+#: io.c:2073 io.c:2298
msgid "restoring stdout in parent process failed\n"
msgstr ""
-#: io.c:1894
+#: io.c:2081
msgid "restoring stdin in parent process failed\n"
msgstr ""
-#: io.c:1929 io.c:2080 io.c:2094
+#: io.c:2116 io.c:2310 io.c:2324
#, c-format
msgid "close of pipe failed (%s)"
msgstr ""
-#: io.c:1974
+#: io.c:2174
msgid "`|&' not supported"
msgstr ""
-#: io.c:2040
+#: io.c:2261
#, c-format
msgid "cannot open pipe `%s' (%s)"
msgstr ""
-#: io.c:2088
+#: io.c:2318
#, c-format
msgid "cannot create child process for `%s' (fork: %s)"
msgstr ""
-#: io.c:2521
+#: io.c:2790
+msgid "register_input_parser: received NULL pointer"
+msgstr ""
+
+#: io.c:2818
#, c-format
-msgid "data file `%s' is empty"
+msgid "input parser `%s' conflicts with previously installed input parser `%s'"
msgstr ""
-#: io.c:2562 io.c:2570
-msgid "could not allocate more input memory"
+#: io.c:2825
+#, c-format
+msgid "input parser `%s' failed to open `%s'"
msgstr ""
-#: io.c:3128
-msgid "multicharacter value of `RS' is a gawk extension"
+#: io.c:2845
+msgid "register_output_wrapper: received NULL pointer"
msgstr ""
-#: io.c:3233
-msgid "IPv6 communication is not supported"
+#: io.c:2873
+#, c-format
+msgid ""
+"output wrapper `%s' conflicts with previously installed output wrapper `%s'"
msgstr ""
-#: main.c:364
-msgid "`-m[fr]' option irrelevant in gawk"
+#: io.c:2880
+#, c-format
+msgid "output wrapper `%s' failed to open `%s'"
msgstr ""
-#: main.c:366
-msgid "-m option usage: `-m[fr] nnn'"
+#: io.c:2901
+msgid "register_output_processor: received NULL pointer"
msgstr ""
-#: main.c:389
+#: io.c:2930
+#, c-format
+msgid ""
+"two-way processor `%s' conflicts with previously installed two-way processor "
+"`%s'"
+msgstr ""
+
+#: io.c:2939
+#, c-format
+msgid "two way processor `%s' failed to open `%s'"
+msgstr ""
+
+#: io.c:3064
+#, c-format
+msgid "data file `%s' is empty"
+msgstr ""
+
+#: io.c:3106 io.c:3114
+msgid "could not allocate more input memory"
+msgstr ""
+
+#: io.c:3682
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr ""
+
+#: io.c:3771
+msgid "IPv6 communication is not supported"
+msgstr ""
+
+#: main.c:405
msgid "empty argument to `-e/--source' ignored"
msgstr ""
-#: main.c:460
+#: main.c:495
#, c-format
msgid "%s: option `-W %s' unrecognized, ignored\n"
msgstr ""
-#: main.c:513
+#: main.c:541
#, c-format
msgid "%s: option requires an argument -- %c\n"
msgstr ""
-#: main.c:534
+#: main.c:562
msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
msgstr ""
-#: main.c:540
+#: main.c:568
msgid "`--posix' overrides `--traditional'"
msgstr ""
-#: main.c:551
+#: main.c:579
msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
msgstr ""
-#: main.c:555
+#: main.c:583
#, c-format
msgid "running %s setuid root may be a security problem"
msgstr ""
-#: main.c:560
-msgid "`--posix' overrides `--binary'"
+#: main.c:588
+msgid "`--posix' overrides `--characters-as-bytes'"
msgstr ""
-#: main.c:611
+#: main.c:647
#, c-format
msgid "can't set binary mode on stdin (%s)"
msgstr ""
-#: main.c:614
+#: main.c:650
#, c-format
msgid "can't set binary mode on stdout (%s)"
msgstr ""
-#: main.c:616
+#: main.c:652
#, c-format
msgid "can't set binary mode on stderr (%s)"
msgstr ""
-#: main.c:655
+#: main.c:710
msgid "no program text at all!"
msgstr ""
-#: main.c:733
+#: main.c:799
#, c-format
msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
msgstr ""
-#: main.c:735
+#: main.c:801
#, c-format
msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
msgstr ""
-#: main.c:740
+#: main.c:806
msgid "POSIX options:\t\tGNU long options: (standard)\n"
msgstr ""
-#: main.c:741
+#: main.c:807
msgid "\t-f progfile\t\t--file=progfile\n"
msgstr ""
-#: main.c:742
+#: main.c:808
msgid "\t-F fs\t\t\t--field-separator=fs\n"
msgstr ""
-#: main.c:743
+#: main.c:809
msgid "\t-v var=val\t\t--assign=var=val\n"
msgstr ""
-#: main.c:744
+#: main.c:810
msgid "Short options:\t\tGNU long options: (extensions)\n"
msgstr ""
-#: main.c:745
+#: main.c:811
msgid "\t-b\t\t\t--characters-as-bytes\n"
msgstr ""
-#: main.c:746
+#: main.c:812
msgid "\t-c\t\t\t--traditional\n"
msgstr ""
-#: main.c:747
+#: main.c:813
msgid "\t-C\t\t\t--copyright\n"
msgstr ""
-#: main.c:748
+#: main.c:814
msgid "\t-d[file]\t\t--dump-variables[=file]\n"
msgstr ""
-#: main.c:749
+#: main.c:815
+msgid "\t-D[file]\t\t--debug[=file]\n"
+msgstr ""
+
+#: main.c:816
msgid "\t-e 'program-text'\t--source='program-text'\n"
msgstr ""
-#: main.c:750
+#: main.c:817
msgid "\t-E file\t\t\t--exec=file\n"
msgstr ""
-#: main.c:751
+#: main.c:818
msgid "\t-g\t\t\t--gen-pot\n"
msgstr ""
-#: main.c:752
+#: main.c:819
msgid "\t-h\t\t\t--help\n"
msgstr ""
-#: main.c:753
+#: main.c:820
+msgid "\t-i includefile\t\t--include=includefile\n"
+msgstr ""
+
+#: main.c:821
+msgid "\t-l library\t\t--load=library\n"
+msgstr ""
+
+#: main.c:822
msgid "\t-L [fatal]\t\t--lint[=fatal]\n"
msgstr ""
-#: main.c:754
+#: main.c:823
msgid "\t-n\t\t\t--non-decimal-data\n"
msgstr ""
-#: main.c:755
+#: main.c:824
+msgid "\t-M\t\t\t--bignum\n"
+msgstr ""
+
+#: main.c:825
msgid "\t-N\t\t\t--use-lc-numeric\n"
msgstr ""
-#: main.c:756
+#: main.c:826
+msgid "\t-o[file]\t\t--pretty-print[=file]\n"
+msgstr ""
+
+#: main.c:827
msgid "\t-O\t\t\t--optimize\n"
msgstr ""
-#: main.c:757
+#: main.c:828
msgid "\t-p[file]\t\t--profile[=file]\n"
msgstr ""
-#: main.c:758
+#: main.c:829
msgid "\t-P\t\t\t--posix\n"
msgstr ""
-#: main.c:759
+#: main.c:830
msgid "\t-r\t\t\t--re-interval\n"
msgstr ""
-#: main.c:761
-msgid "\t-R file\t\t\t--command=file\n"
-msgstr ""
-
-#: main.c:762
+#: main.c:831
msgid "\t-S\t\t\t--sandbox\n"
msgstr ""
-#: main.c:763
+#: main.c:832
msgid "\t-t\t\t\t--lint-old\n"
msgstr ""
-#: main.c:764
+#: main.c:833
msgid "\t-V\t\t\t--version\n"
msgstr ""
-#: main.c:766
+#: main.c:835
msgid "\t-W nostalgia\t\t--nostalgia\n"
msgstr ""
-#: main.c:769
+#: main.c:838
msgid "\t-Y\t\t--parsedebug\n"
msgstr ""
@@ -1752,7 +3007,7 @@ msgstr ""
#. for this application. Please add _another line_ with the
#. address for translation bugs.
#. no-wrap
-#: main.c:778
+#: main.c:847
msgid ""
"\n"
"To report bugs, see node `Bugs' in `gawk.info', which is\n"
@@ -1760,21 +3015,21 @@ msgid ""
"\n"
msgstr ""
-#: main.c:782
+#: main.c:851
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:786
+#: main.c:855
msgid ""
"Examples:\n"
"\tgawk '{ sum += $1 }; END { print sum }' file\n"
"\tgawk -F: '{ print $1 }' /etc/passwd\n"
msgstr ""
-#: main.c:806
+#: main.c:880
#, c-format
msgid ""
"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
@@ -1786,7 +3041,7 @@ msgid ""
"\n"
msgstr ""
-#: main.c:814
+#: main.c:888
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"
@@ -1795,256 +3050,299 @@ msgid ""
"\n"
msgstr ""
-#: main.c:820
+#: main.c:894
msgid ""
"You should have received a copy of the GNU General Public License\n"
"along with this program. If not, see http://www.gnu.org/licenses/.\n"
msgstr ""
-#: main.c:855
+#: main.c:931
msgid "-Ft does not set FS to tab in POSIX awk"
msgstr ""
-#: main.c:1089
+#: main.c:1208
#, c-format
msgid "unknown value for field spec: %d\n"
msgstr ""
-#: main.c:1170
+#: main.c:1306
#, c-format
msgid ""
"%s: `%s' argument to `-v' not in `var=value' form\n"
"\n"
msgstr ""
-#: main.c:1196
+#: main.c:1332
#, c-format
msgid "`%s' is not a legal variable name"
msgstr ""
-#: main.c:1199
+#: main.c:1335
#, c-format
msgid "`%s' is not a variable name, looking for file `%s=%s'"
msgstr ""
-#: main.c:1203
+#: main.c:1339
#, c-format
msgid "cannot use gawk builtin `%s' as variable name"
msgstr ""
-#: main.c:1208
+#: main.c:1344
#, c-format
msgid "cannot use function `%s' as variable name"
msgstr ""
-#: main.c:1261
+#: main.c:1397
msgid "floating point exception"
msgstr ""
-#: main.c:1268
+#: main.c:1404
msgid "fatal error: internal error"
msgstr ""
-#: main.c:1283
+#: main.c:1419
msgid "fatal error: internal error: segfault"
msgstr ""
-#: main.c:1295
+#: main.c:1431
msgid "fatal error: internal error: stack overflow"
msgstr ""
-#: main.c:1345
+#: main.c:1490
#, c-format
msgid "no pre-opened fd %d"
msgstr ""
-#: main.c:1352
+#: main.c:1497
#, c-format
msgid "could not pre-open /dev/null for fd %d"
msgstr ""
-#: main.c:1375 main.c:1384
+#: mpfr.c:550
#, c-format
-msgid "could not find groups: %s"
+msgid "PREC value `%.*s' is invalid"
msgstr ""
-#: msg.c:63
+#: mpfr.c:608
#, c-format
-msgid "cmd. line:"
+msgid "RNDMODE value `%.*s' is invalid"
msgstr ""
-#: msg.c:107
-msgid "error: "
+#: mpfr.c:698
+#, c-format
+msgid "%s: received non-numeric argument"
+msgstr ""
+
+#: mpfr.c:800
+msgid "compl(%Rg): negative value will give strange results"
+msgstr ""
+
+#: mpfr.c:804
+msgid "comp(%Rg): fractional value will be truncated"
+msgstr ""
+
+#: mpfr.c:816
+#, c-format
+msgid "cmpl(%Zd): negative values will give strange results"
+msgstr ""
+
+#: mpfr.c:835
+#, c-format
+msgid "%s: received non-numeric argument #%d"
+msgstr ""
+
+#: mpfr.c:845
+msgid "%s: argument #%d has invalid value %Rg, using 0"
+msgstr ""
+
+#: mpfr.c:857
+msgid "%s: argument #%d negative value %Rg will give strange results"
msgstr ""
-#: node.c:406
+#: mpfr.c:863
+msgid "%s: argument #%d fractional value %Rg will be truncated"
+msgstr ""
+
+#: mpfr.c:878
+#, c-format
+msgid "%s: argument #%d negative value %Zd will give strange results"
+msgstr ""
+
+#: msg.c:68
+#, c-format
+msgid "cmd. line:"
+msgstr ""
+
+#: node.c:421
msgid "backslash at end of string"
msgstr ""
-#: node.c:517
+#: node.c:500
#, c-format
msgid "old awk does not support the `\\%c' escape sequence"
msgstr ""
-#: node.c:568
+#: node.c:551
msgid "POSIX does not allow `\\x' escapes"
msgstr ""
-#: node.c:574
+#: node.c:557
msgid "no hex digits in `\\x' escape sequence"
msgstr ""
-#: node.c:596
+#: node.c:579
#, c-format
msgid ""
"hex escape \\x%.*s of %d characters probably not interpreted the way you "
"expect"
msgstr ""
-#: node.c:611
+#: node.c:594
#, c-format
msgid "escape sequence `\\%c' treated as plain `%c'"
msgstr ""
-#: node.c:750
+#: node.c:739
msgid ""
"Invalid multibyte data detected. There may be a mismatch between your data "
"and your locale."
msgstr ""
-#: posix/gawkmisc.c:176
+#: posix/gawkmisc.c:177
#, c-format
msgid "%s %s `%s': could not get fd flags: (fcntl F_GETFD: %s)"
msgstr ""
-#: posix/gawkmisc.c:188
+#: posix/gawkmisc.c:189
#, c-format
msgid "%s %s `%s': could not set close-on-exec: (fcntl F_SETFD: %s)"
msgstr ""
-#: profile.c:83
+#: profile.c:71
#, c-format
msgid "could not open `%s' for writing: %s"
msgstr ""
-#: profile.c:85
+#: profile.c:73
msgid "sending profile to standard error"
msgstr ""
-#: profile.c:203
+#: profile.c:193
#, c-format
msgid ""
"\t# %s block(s)\n"
"\n"
msgstr ""
-#: profile.c:208
+#: profile.c:198
#, c-format
msgid ""
"\t# Rule(s)\n"
"\n"
msgstr ""
-#: profile.c:279
+#: profile.c:272
#, c-format
msgid "internal error: %s with null vname"
msgstr ""
-#: profile.c:952
+#: profile.c:537
+msgid "internal error: builtin with null fname"
+msgstr ""
+
+#: profile.c:949
+#, c-format
+msgid ""
+"\t# Loaded extensions (-l and/or @load)\n"
+"\n"
+msgstr ""
+
+#: profile.c:972
#, c-format
msgid "\t# gawk profile, created %s\n"
msgstr ""
-#: profile.c:1331
+#: profile.c:1475
#, c-format
msgid ""
"\n"
"\t# Functions, listed alphabetically\n"
msgstr ""
-#: profile.c:1370
+#: profile.c:1513
#, c-format
msgid "redir2str: unknown redirection type %d"
msgstr ""
-#: re.c:572
-#, c-format
-msgid "range of the form `[%c-%c]' is locale dependent"
-msgstr ""
-
-#: re.c:599
+#: re.c:607
#, c-format
msgid "regexp component `%.*s' should probably be `[%.*s]'"
msgstr ""
-#: regcomp.c:132
+#: regcomp.c:131
msgid "Success"
msgstr ""
-#: regcomp.c:135
+#: regcomp.c:134
msgid "No match"
msgstr ""
-#: regcomp.c:138
+#: regcomp.c:137
msgid "Invalid regular expression"
msgstr ""
-#: regcomp.c:141
+#: regcomp.c:140
msgid "Invalid collation character"
msgstr ""
-#: regcomp.c:144
+#: regcomp.c:143
msgid "Invalid character class name"
msgstr ""
-#: regcomp.c:147
+#: regcomp.c:146
msgid "Trailing backslash"
msgstr ""
-#: regcomp.c:150
+#: regcomp.c:149
msgid "Invalid back reference"
msgstr ""
-#: regcomp.c:153
+#: regcomp.c:152
msgid "Unmatched [ or [^"
msgstr ""
-#: regcomp.c:156
+#: regcomp.c:155
msgid "Unmatched ( or \\("
msgstr ""
-#: regcomp.c:159
+#: regcomp.c:158
msgid "Unmatched \\{"
msgstr ""
-#: regcomp.c:162
-msgid "Invalid content of \\{\\}"
-msgstr ""
-
-#: regcomp.c:165
+#: regcomp.c:164
msgid "Invalid range end"
msgstr ""
-#: regcomp.c:168
+#: regcomp.c:167
msgid "Memory exhausted"
msgstr ""
-#: regcomp.c:171
+#: regcomp.c:170
msgid "Invalid preceding regular expression"
msgstr ""
-#: regcomp.c:174
+#: regcomp.c:173
msgid "Premature end of regular expression"
msgstr ""
-#: regcomp.c:177
-msgid "Regular expression too big"
-msgstr ""
-
-#: regcomp.c:180
+#: regcomp.c:179
msgid "Unmatched ) or \\)"
msgstr ""
-#: regcomp.c:701
+#: regcomp.c:704
msgid "No previous regular expression"
msgstr ""
+
+#: symbol.c:741
+msgid "can not pop main context"
+msgstr ""
diff --git a/po/he.gmo b/po/he.gmo
deleted file mode 100644
index b9cb6d3c..00000000
--- a/po/he.gmo
+++ /dev/null
Binary files differ
diff --git a/po/id.gmo b/po/id.gmo
deleted file mode 100644
index 272d5f8c..00000000
--- a/po/id.gmo
+++ /dev/null
Binary files differ
diff --git a/po/id.po b/po/id.po
index 5fa3b23a..d1b97f73 100644
--- a/po/id.po
+++ b/po/id.po
@@ -1,14 +1,14 @@
# Pesan bahasa indonesia untuk gawk.
# Copyright (C) 2008 Free Software Foundation, Inc.
# This file is distributed under the same license as the gawk package.
-# Arif E. Nugroho <arif_endro@yahoo.com>, 2008, 2009.
+# Arif E. Nugroho <arif_endro@yahoo.com>, 2008, 2009, 2010, 2011, 2012, 2013, 2014.
#
msgid ""
msgstr ""
-"Project-Id-Version: gawk 3.1.6e\n"
+"Project-Id-Version: gawk 4.1.0b\n"
"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
-"POT-Creation-Date: 2011-03-18 12:00+0200\n"
-"PO-Revision-Date: 2009-07-11 14:00+0700\n"
+"POT-Creation-Date: 2014-01-14 22:23+0200\n"
+"PO-Revision-Date: 2014-08-03 07:30+0700\n"
"Last-Translator: Arif E. Nugroho <arif_endro@yahoo.com>\n"
"Language-Team: Indonesian <translation-team-id@lists.sourceforge.net>\n"
"Language: id\n"
@@ -16,494 +16,473 @@ msgstr ""
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
-#: array.c:103
+#: array.c:256
#, c-format
msgid "from %s"
msgstr "dari %s"
-#: array.c:267
-#, fuzzy
+#: array.c:357
msgid "attempt to use a scalar value as array"
-msgstr "mencoba untuk menggunakan skalar `%s' sebagai sebuah array"
-
-#: array.c:270
-#, c-format
-msgid "attempt to use function `%s' as an array"
-msgstr "mencoba untuk menggunakan fungsi `%s' sebagai sebuah array"
+msgstr "mencoba untuk menggunakan skalar sebagai sebuah array"
-#: array.c:273
+#: array.c:359
#, c-format
msgid "attempt to use scalar parameter `%s' as an array"
msgstr "mencoba untuk menggunakan parameter `%s' sebagai sebuah array"
-#: array.c:276 eval.c:2013
-#, fuzzy, c-format
+#: array.c:362
+#, c-format
msgid "attempt to use scalar `%s' as an array"
msgstr "mencoba untuk menggunakan skalar `%s' sebagai sebuah array"
-#: array.c:321 array.c:648 builtin.c:75 builtin.c:555 builtin.c:597
-#: builtin.c:610 builtin.c:1016 builtin.c:1028 eval.c:1381 eval.c:1385
-#: eval.c:1710 eval.c:1958 eval.c:2026 eval.c:2274
+#: array.c:409 array.c:576 builtin.c:85 builtin.c:1599 builtin.c:1645
+#: builtin.c:1658 builtin.c:2086 builtin.c:2100 eval.c:1122 eval.c:1126
+#: eval.c:1531
#, c-format
msgid "attempt to use array `%s' in a scalar context"
msgstr "mencoba menggunakan array `%s' dalam sebuah konteks skalar"
-#: array.c:570
-#, fuzzy, c-format
-msgid "reference to uninitialized element `%s[\"%.*s\"]'"
-msgstr "referensi ke elemen tidak terinisialisasi `%s[\"%s\"]'"
-
-#: array.c:576
-#, c-format
-msgid "subscript of array `%s' is null string"
-msgstr "subscript dari array `%s' adalah string null"
-
-#: array.c:684
+#: array.c:583
#, c-format
msgid "delete: index `%s' not in array `%s'"
msgstr "delete: indeks `%s' tidak dalam array `%s'"
-#: array.c:708
-#, fuzzy, c-format
+#: array.c:597
+#, c-format
msgid "attempt to use scalar `%s[\"%.*s\"]' as an array"
-msgstr "mencoba untuk menggunakan skalar `%s' sebagai sebuah array"
+msgstr "mencoba untuk menggunakan skalar `%s[\"%.*s\"]' sebagai sebuah array"
-#: array.c:871
-#, c-format
-msgid "%s: empty (null)\n"
-msgstr "%s: kosong (null)\n"
+#: array.c:776
+msgid "adump: first argument not an array"
+msgstr "adump: argumen ketiga bukan sebuah array"
-#: array.c:876
-#, c-format
-msgid "%s: empty (zero)\n"
-msgstr "%s: kosong (nol)\n"
+#: array.c:815
+msgid "asort: second argument not an array"
+msgstr "asort: argumen kedua bukan sebuah array"
-#: array.c:880
-#, c-format
-msgid "%s: table_size = %d, array_size = %d\n"
-msgstr "%s: table_size = %d, array_size = %d\n"
+#: array.c:816
+msgid "asorti: second argument not an array"
+msgstr "asorti: argumen kedua bukan sebuah array"
-#: array.c:915
-#, c-format
-msgid "%s: is parameter\n"
-msgstr "%s: adalah parameter\n"
+#: array.c:823
+msgid "asort: first argument not an array"
+msgstr "asort: argumen ketiga bukan sebuah array"
-#: array.c:919
-#, c-format
-msgid "%s: array_ref to %s\n"
-msgstr "%s: array_ref ke %s\n"
+#: array.c:824
+msgid "asorti: first argument not an array"
+msgstr "asorti: argumen ketiga bukan sebuah array"
-#: array.c:924
-#, fuzzy
-msgid "adump: argument not an array"
-msgstr "match: argumen ketiga bukan sebuah array"
+#: array.c:831
+msgid "asort: cannot use a subarray of first arg for second arg"
+msgstr "asort: cannot use a subarray of first arg for second arg"
-#: array.c:1142
-#, fuzzy
-msgid "attempt to use array in a scalar context"
-msgstr "mencoba menggunakan array `%s' dalam sebuah konteks skalar"
+#: array.c:832
+msgid "asorti: cannot use a subarray of first arg for second arg"
+msgstr "asorti: cannot use a subarray of first arg for second arg"
-#: array.c:1239
-#, fuzzy
-msgid "asort: second argument not an array"
-msgstr "split: argumen kedua bukan sebuah array"
+#: array.c:837
+msgid "asort: cannot use a subarray of second arg for first arg"
+msgstr "asort: cannot use a subarray of second arg for first arg"
-#: array.c:1240
-#, fuzzy
-msgid "asorti: second argument not an array"
-msgstr "split: argumen kedua bukan sebuah array"
+#: array.c:838
+msgid "asorti: cannot use a subarray of second arg for first arg"
+msgstr "asorti: cannot use a subarray of second arg for first arg"
-#: array.c:1247
-#, fuzzy
-msgid "asort: first argument not an array"
-msgstr "match: argumen ketiga bukan sebuah array"
+#: array.c:1314
+#, c-format
+msgid "`%s' is invalid as a function name"
+msgstr "`%s' digunakan dalam aksi"
-#: array.c:1248
-#, fuzzy
-msgid "asorti: first argument not an array"
-msgstr "match: argumen ketiga bukan sebuah array"
+#: array.c:1318
+#, c-format
+msgid "sort comparison function `%s' is not defined"
+msgstr "fungsi `%s' tidak didefinisikan"
-#: awkgram.y:249
+#: awkgram.y:233
#, c-format
msgid "%s blocks must have an action part"
msgstr "%s blok harus memiliki sebuah bagian aksi"
-#: awkgram.y:252
+#: awkgram.y:236
msgid "each rule must have a pattern or an action part"
msgstr "setiap aturan harus memiliki sebuah pola atau sebuah bagian aksi"
-#: awkgram.y:323 awkgram.y:334
+#: awkgram.y:325 awkgram.y:336
msgid "old awk does not support multiple `BEGIN' or `END' rules"
msgstr "awk lama tidak mendukung multiple aturan `BEGIN' atau `END'"
-#: awkgram.y:371
+#: awkgram.y:373
#, c-format
msgid "`%s' is a built-in function, it cannot be redefined"
msgstr "`%s' adalah sebuah fungsi bawaan, ini tidak dapat di redefinisi"
-#: awkgram.y:432
+#: awkgram.y:419
msgid "regexp constant `//' looks like a C++ comment, but is not"
msgstr "konstanta regexp `//' tampak seperti sebuah komentar C++, tetapi bukan"
-#: awkgram.y:436
+#: awkgram.y:423
#, c-format
msgid "regexp constant `/%s/' looks like a C comment, but is not"
msgstr "konstanta regexp `/%s/' tampak seperti sebuah komentar C, tetapi bukan"
-#: awkgram.y:528
+#: awkgram.y:515
#, c-format
msgid "duplicate case values in switch body: %s"
msgstr "duplikasi nilai case dalam tubuh switch: %s"
-#: awkgram.y:549
-#, fuzzy
+#: awkgram.y:536
msgid "duplicate `default' detected in switch body"
msgstr "Duplikasi `default' terdeteksi dalam tubuh switch"
-#: awkgram.y:811
-#, fuzzy
+#: awkgram.y:796 awkgram.y:3699
msgid "`break' is not allowed outside a loop or switch"
msgstr "`break' diluar sebuah loop tidak diijinkan"
-#: awkgram.y:820
-#, fuzzy
+#: awkgram.y:805 awkgram.y:3691
msgid "`continue' is not allowed outside a loop"
msgstr "`continue' diluar sebuah loop tidak diijinkan"
-#: awkgram.y:829
-#, fuzzy, c-format
+#: awkgram.y:815
+#, c-format
msgid "`next' used in %s action"
-msgstr "`%s' digunakan dalam aksi %s"
-
-#: awkgram.y:837
-msgid "`nextfile' is a gawk extension"
-msgstr "`nextfile' adalah sebuah ekstensi gawk"
+msgstr "`next' digunakan dalam aksi %s"
-#: awkgram.y:840
-#, fuzzy, c-format
+#: awkgram.y:824
+#, c-format
msgid "`nextfile' used in %s action"
-msgstr "`%s' digunakan dalam aksi %s"
+msgstr "`nextfile' digunakan dalam aksi %s"
-#: awkgram.y:863
+#: awkgram.y:848
msgid "`return' used outside function context"
msgstr "`return' digunakan diluar konteks fungsi"
-#: awkgram.y:923
+#: awkgram.y:922
msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
-msgstr ""
-"plain `print' dalam aturan BEGIN atau AKHIR seharusnya berupa `print \"\"'"
+msgstr "plain `print' dalam aturan BEGIN atau AKHIR seharusnya berupa `print \"\"'"
+
+#: awkgram.y:988 awkgram.y:1037
+msgid "`delete' is not allowed with SYMTAB"
+msgstr "`delete' is not allowed with SYMTAB"
-#: awkgram.y:993 awkgram.y:997 awkgram.y:1021
-msgid "`delete array' is a gawk extension"
-msgstr "`delete array' adalah sebuah ekstensi gawk"
+#: awkgram.y:990 awkgram.y:1039
+msgid "`delete' is not allowed with FUNCTAB"
+msgstr "`delete' is not allowed with FUNCTAB"
-#: awkgram.y:1017
+#: awkgram.y:1024 awkgram.y:1028
msgid "`delete(array)' is a non-portable tawk extension"
msgstr "`delete(array)' adalah sebuah ekstensi tidak portabel tawk"
-#: awkgram.y:1133
+#: awkgram.y:1149
msgid "multistage two-way pipelines don't work"
msgstr "multi tahap dua jalur pipe lines tidak bekerja"
-#: awkgram.y:1236
+#: awkgram.y:1264
msgid "regular expression on right of assignment"
msgstr "ekspresi regular di penempatan kanan"
-#: awkgram.y:1247
+#: awkgram.y:1275
msgid "regular expression on left of `~' or `!~' operator"
msgstr "ekspresi regular di kiri dari operator `~' atau `!~'"
-#: awkgram.y:1263 awkgram.y:1417
+#: awkgram.y:1291 awkgram.y:1442
msgid "old awk does not support the keyword `in' except after `for'"
msgstr "awk lama tidak mendukung kata kunci `in' kecuali setelah `for'"
-#: awkgram.y:1273
+#: awkgram.y:1301
msgid "regular expression on right of comparison"
msgstr "ekspresi regular di kanan dari perbandingan"
-#: awkgram.y:1392
+#: awkgram.y:1417
#, c-format
msgid "`getline var' invalid inside `%s' rule"
-msgstr ""
+msgstr "`getline var' invalid inside `%s' rule"
-#: awkgram.y:1395 eval.c:2649
+#: awkgram.y:1420
#, c-format
msgid "`getline' invalid inside `%s' rule"
-msgstr ""
+msgstr "`getline' invalid inside `%s' rule"
-#: awkgram.y:1400
+#: awkgram.y:1425
msgid "non-redirected `getline' undefined inside END action"
msgstr "tidak terdireksi `getline' tidak terdefinisi didalam aksi END"
-#: awkgram.y:1419
+#: awkgram.y:1444
msgid "old awk does not support multidimensional arrays"
msgstr "awk lama tidak mendukung array multi dimensi"
-#: awkgram.y:1515
+#: awkgram.y:1541
msgid "call of `length' without parentheses is not portable"
msgstr "panggilan dari `length' tanpa tanda kurung tidak portabel"
-#: awkgram.y:1578
-#, fuzzy
+#: awkgram.y:1607
msgid "indirect function calls are a gawk extension"
-msgstr "`nextfile' adalah sebuah ekstensi gawk"
+msgstr "indirect adalah sebuah ekstensi gawk"
-#: awkgram.y:1591
-#, fuzzy, c-format
+#: awkgram.y:1620
+#, c-format
msgid "can not use special variable `%s' for indirect function call"
-msgstr ""
-"fungsi `%s': tidak dapat menggunakan variabel `%s' sebagai fungsi parameter"
+msgstr "tidak dapat menggunakan variabel `%s' sebagai fungsi parameter"
-#: awkgram.y:1669
+#: awkgram.y:1698
msgid "invalid subscript expression"
msgstr "ekspresi subscript tidak valid"
-#: awkgram.y:1709
-msgid "use of non-array as array"
-msgstr "penggunaan dari bukan array sebagai array"
-
-#: awkgram.y:1973 awkgram.y:1993 msg.c:98
+#: awkgram.y:2024 awkgram.y:2044 gawkapi.c:206 gawkapi.c:224 msg.c:126
msgid "warning: "
msgstr "peringatan: "
-#: awkgram.y:1991 msg.c:130
+#: awkgram.y:2042 gawkapi.c:192 gawkapi.c:221 msg.c:158
msgid "fatal: "
msgstr "fatal: "
-#: awkgram.y:2041
+#: awkgram.y:2092
msgid "unexpected newline or end of string"
msgstr "tidak terduga baris baru atau akhir dari string"
-#: awkgram.y:2297 awkgram.y:2355 awkgram.y:2539
+#: awkgram.y:2359 awkgram.y:2435 awkgram.y:2658 debug.c:523 debug.c:539
+#: debug.c:2812 debug.c:5055
#, c-format
msgid "can't open source file `%s' for reading (%s)"
msgstr "tidak dapat membuka berkas sumber `%s' untuk pembacaan (%s)"
-#: awkgram.y:2298 awkgram.y:2356 builtin.c:119
+#: awkgram.y:2360 awkgram.y:2485
+#, c-format
+msgid "can't open shared library `%s' for reading (%s)"
+msgstr "tidak dapat membuka berkas sumber `%s' untuk pembacaan (%s)"
+
+#: awkgram.y:2362 awkgram.y:2436 awkgram.y:2486 builtin.c:135 debug.c:5206
msgid "reason unknown"
msgstr "alasan tidak diketahui"
-#: awkgram.y:2314
-#, fuzzy, c-format
+#: awkgram.y:2371 awkgram.y:2395
+#, c-format
+msgid "can't include `%s' and use it as a program file"
+msgstr "can't include `%s' and use it as a program file"
+
+#: awkgram.y:2384
+#, c-format
msgid "already included source file `%s'"
-msgstr "tidak dapat membaca berkas sumber `%s' (%s)"
+msgstr "tidak dapat membaca berkas sumber `%s'"
+
+#: awkgram.y:2385
+#, c-format
+msgid "already loaded shared library `%s'"
+msgstr "already loaded shared library `%s'"
-#: awkgram.y:2340
-#, fuzzy
+#: awkgram.y:2420
msgid "@include is a gawk extension"
-msgstr "`nextfile' adalah sebuah ekstensi gawk"
+msgstr "@include adalah sebuah ekstensi gawk"
-#: awkgram.y:2346
+#: awkgram.y:2426
msgid "empty filename after @include"
-msgstr ""
+msgstr "empty filename after @include"
+
+#: awkgram.y:2470
+msgid "@load is a gawk extension"
+msgstr "@load adalah sebuah ekstensi gawk"
-#: awkgram.y:2491
+#: awkgram.y:2476
+msgid "empty filename after @load"
+msgstr "empty filename after @load"
+
+#: awkgram.y:2610
msgid "empty program text on command line"
msgstr "aplikasi teks kosong di baris perintah"
-#: awkgram.y:2606
+#: awkgram.y:2725
#, c-format
msgid "can't read sourcefile `%s' (%s)"
msgstr "tidak dapat membaca berkas sumber `%s' (%s)"
-#: awkgram.y:2617
+#: awkgram.y:2736
#, c-format
msgid "source file `%s' is empty"
msgstr "berkas sumber `%s' kosong"
-#: awkgram.y:2802
+#: awkgram.y:2913
msgid "source file does not end in newline"
msgstr "berkas sumber tidak berakhir dalam baris baru"
-#: awkgram.y:2879
+#: awkgram.y:3018
msgid "unterminated regexp ends with `\\' at end of file"
msgstr "tidak terakhiri regexp akhir denga `\\' diakhir dari berkas"
-#: awkgram.y:2903
+#: awkgram.y:3042
#, c-format
msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
msgstr "%s: %d: tawk regex pemodifikasi `/.../%c' tidak bekerja dalam gawk"
-#: awkgram.y:2907
+#: awkgram.y:3046
#, c-format
msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
msgstr "tawk regex pemodifikasi `/.../%c' tidak bekerja dalam gawk"
-#: awkgram.y:2914
+#: awkgram.y:3053
msgid "unterminated regexp"
msgstr "tidak terselesaikan regexp"
-#: awkgram.y:2918
+#: awkgram.y:3057
msgid "unterminated regexp at end of file"
msgstr "tidak terselesaikan di akhir dari berkas"
-#: awkgram.y:2977
+#: awkgram.y:3116
msgid "use of `\\ #...' line continuation is not portable"
msgstr "penggunaan dari `\\ #...' kelanjutan baris tidak portabel"
-#: awkgram.y:2993
+#: awkgram.y:3132
msgid "backslash not last character on line"
msgstr "backslash bukan karakter terakhir di baris"
-#: awkgram.y:3054
+#: awkgram.y:3193
msgid "POSIX does not allow operator `**='"
msgstr "POSIX tidak mengijinkan operator `**='"
-#: awkgram.y:3056
+#: awkgram.y:3195
msgid "old awk does not support operator `**='"
msgstr "awk lama tidak mendukung operator `**='"
-#: awkgram.y:3065
+#: awkgram.y:3204
msgid "POSIX does not allow operator `**'"
msgstr "POSIX tidak mengijinkan operator `**'"
-#: awkgram.y:3067
+#: awkgram.y:3206
msgid "old awk does not support operator `**'"
msgstr "awk lama tidak mendukung operator `**'"
-#: awkgram.y:3102
+#: awkgram.y:3241
msgid "operator `^=' is not supported in old awk"
msgstr "operator `^=' tidak didukung dalam awk lama"
-#: awkgram.y:3110
+#: awkgram.y:3249
msgid "operator `^' is not supported in old awk"
msgstr "operator `^' tidak didukung dalam awk lama"
-#: awkgram.y:3203 awkgram.y:3219
+#: awkgram.y:3342 awkgram.y:3358 command.y:1178
msgid "unterminated string"
msgstr "string tidak terselesaikan"
-#: awkgram.y:3415
+#: awkgram.y:3579
#, c-format
msgid "invalid char '%c' in expression"
msgstr "karakter '%c' tidak valid dalam ekspresi"
-#: awkgram.y:3462
+#: awkgram.y:3626
#, c-format
msgid "`%s' is a gawk extension"
msgstr "`%s' adalah sebuah ekstensi gawk"
-#: awkgram.y:3467
-#, c-format
-msgid "`%s' is a Bell Labs extension"
-msgstr "`%s' adalah sebuah ekstensi Bell Labs"
-
-#: awkgram.y:3472
+#: awkgram.y:3631
#, c-format
msgid "POSIX does not allow `%s'"
msgstr "POSIX tidak mengijinkan `%s'"
-#: awkgram.y:3480
+#: awkgram.y:3639
#, c-format
msgid "`%s' is not supported in old awk"
msgstr "`%s' tidak didukung dalam awk lama"
-#: awkgram.y:3550
+#: awkgram.y:3729
msgid "`goto' considered harmful!\n"
msgstr "`goto' dipertimbangkan berbahaya!\n"
-#: awkgram.y:3602
+#: awkgram.y:3763
#, c-format
msgid "%d is invalid as number of arguments for %s"
msgstr "%d tidak valid sebagai jumlah dari argumen untuk %s"
-#: awkgram.y:3637 awkgram.y:3640
-msgid "match: third argument is a gawk extension"
-msgstr "cocok: argumen ketiga adalah sebuah ekstensi gawk"
-
-#: awkgram.y:3668
+#: awkgram.y:3798
#, c-format
msgid "%s: string literal as last arg of substitute has no effect"
-msgstr ""
-"%s: literal string sebagai argumen terakhir dari pergantian tidak memiliki "
-"efek"
+msgstr "%s: literal string sebagai argumen terakhir dari pergantian tidak memiliki efek"
-#: awkgram.y:3673
+#: awkgram.y:3803
#, c-format
msgid "%s third parameter is not a changeable object"
msgstr "%s parameter ketika bukan sebuah objek yang dapat diubah"
-#: awkgram.y:3759 awkgram.y:3762
+#: awkgram.y:3886 awkgram.y:3889
+msgid "match: third argument is a gawk extension"
+msgstr "cocok: argumen ketiga adalah sebuah ekstensi gawk"
+
+#: awkgram.y:3943 awkgram.y:3946
msgid "close: second argument is a gawk extension"
msgstr "tutup: argumen kedua adalah sebuah ekstensi gawk"
-#: awkgram.y:3774
+#: awkgram.y:3958
msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
-msgstr ""
-"penggunaan dari dcgettext(_\"...\") adalah tidak benar: hapus garis bawah "
-"yang mengawali"
+msgstr "penggunaan dari dcgettext(_\"...\") adalah tidak benar: hapus garis bawah yang mengawali"
-#: awkgram.y:3789
+#: awkgram.y:3973
msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
-msgstr ""
-"penggunaan dari dcngettext(_\"...\") adalah tidak benar: hapus garis bawah "
-"yang mengawali"
+msgstr "penggunaan dari dcngettext(_\"...\") adalah tidak benar: hapus garis bawah yang mengawali"
-#: awkgram.y:3881
-#, c-format
-msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
-msgstr "fungsi `%s': parameter #%d, `%s', duplikasi paramter #%d"
+#: awkgram.y:3992
+msgid "index: regexp constant as second argument is not allowed"
+msgstr "index: diterima argumen kedua bukan string"
-#: awkgram.y:3923
+#: awkgram.y:4045
#, c-format
msgid "function `%s': parameter `%s' shadows global variable"
msgstr "fungsi `%s': parameter `%s' bayangan variabel global"
-#: awkgram.y:4081
+#: awkgram.y:4102 debug.c:4041 debug.c:4084 debug.c:5204
#, c-format
msgid "could not open `%s' for writing (%s)"
msgstr "tidak dapat membuka `%s' untuk menulis (%s)"
-#: awkgram.y:4082 profile.c:85
-msgid "sending profile to standard error"
+#: awkgram.y:4103
+msgid "sending variable list to standard error"
msgstr "mengirim profile ke standar error"
-#: awkgram.y:4088
+#: awkgram.y:4111
#, c-format
msgid "%s: close failed (%s)"
msgstr "%s: tutup gagal (%s)"
-#: awkgram.y:4140
+#: awkgram.y:4136
msgid "shadow_funcs() called twice!"
msgstr "shadow_funcs() dipanggil dua kali!"
-#: awkgram.y:4146
+#: awkgram.y:4144
msgid "there were shadowed variables."
msgstr "disana tidak ada variabel bayangan."
-#: awkgram.y:4176
+#: awkgram.y:4215
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "nama fungsi `%s' sebelumnya telah didefinisikan"
+
+#: awkgram.y:4261
#, c-format
msgid "function `%s': can't use function name as parameter name"
-msgstr ""
-"fungsi `%s': tidak dapat menggunakan nama fungsi sebagai nama parameter"
+msgstr "fungsi `%s': tidak dapat menggunakan nama fungsi sebagai nama parameter"
-#: awkgram.y:4180
+#: awkgram.y:4264
#, c-format
msgid "function `%s': can't use special variable `%s' as a function parameter"
-msgstr ""
-"fungsi `%s': tidak dapat menggunakan variabel `%s' sebagai fungsi parameter"
+msgstr "fungsi `%s': tidak dapat menggunakan variabel `%s' sebagai fungsi parameter"
-#: awkgram.y:4196
+#: awkgram.y:4272
#, c-format
-msgid "function name `%s' previously defined"
-msgstr "nama fungsi `%s' sebelumnya telah didefinisikan"
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "fungsi `%s': parameter #%d, `%s', duplikasi paramter #%d"
-#: awkgram.y:4364 awkgram.y:4370
+#: awkgram.y:4359 awkgram.y:4365
#, c-format
msgid "function `%s' called but never defined"
msgstr "fungsi `%s' dipanggil tetapi tidak pernah didefinisikan"
-#: awkgram.y:4373
-#, fuzzy, c-format
+#: awkgram.y:4369
+#, c-format
msgid "function `%s' defined but never called directly"
msgstr "fungsi `%s' didefinisikan tetapi tidak pernah dipanggil"
-#: awkgram.y:4405
+#: awkgram.y:4401
#, c-format
msgid "regexp constant for parameter #%d yields boolean value"
msgstr "konstanta regexp untuk parameter #%d menghasilkan nilai boolean"
-#: awkgram.y:4514
+#: awkgram.y:4460
#, c-format
msgid ""
"function `%s' called with space between name and `(',\n"
@@ -512,363 +491,1306 @@ msgstr ""
"fungsi `%s' dipanggil dengan spasi diantara nama dan `(',\n"
"atau gunakan sebagai sebuah variabel atau sebuah array"
-#: awkgram.y:4761 eval.c:2206
+#: awkgram.y:4696
msgid "division by zero attempted"
msgstr "pembagian dengan nol telah dicoba"
-#: awkgram.y:4770 eval.c:2222
+#: awkgram.y:4705
#, c-format
msgid "division by zero attempted in `%%'"
msgstr "pembagian dengan nol dicoba dalam `%%'"
-#: builtin.c:117
+#: awkgram.y:5025
+msgid "cannot assign a value to the result of a field post-increment expression"
+msgstr "cannot assign a value to the result of a field post-increment expression"
+
+#: awkgram.y:5028
+#, c-format
+msgid "invalid target of assignment (opcode %s)"
+msgstr "tidak valid sebagai jumlah dari argumen untuk %s"
+
+#: builtin.c:133
#, c-format
msgid "%s to \"%s\" failed (%s)"
msgstr "%s ke \"%s\" gagal (%s)"
-#: builtin.c:118
+#: builtin.c:134
msgid "standard output"
msgstr "standar keluaran"
-#: builtin.c:132
+#: builtin.c:148
msgid "exp: received non-numeric argument"
msgstr "exp: diterima argumen bukan-numerik"
-#: builtin.c:138
+#: builtin.c:154
#, c-format
msgid "exp: argument %g is out of range"
msgstr "exp: argumen %g diluar dari jangkauan"
-#: builtin.c:197
+#: builtin.c:229
#, c-format
msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
-msgstr ""
-"fflush: tidak dapat flush: pipe `%s' dibuka untuk dibaca, bukan ditulis"
+msgstr "fflush: tidak dapat flush: pipe `%s' dibuka untuk dibaca, bukan ditulis"
-#: builtin.c:200
+#: builtin.c:232
#, c-format
msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
-msgstr ""
-"fflush: tidak dapat flush: berkas `%s' dibuka untuk dibaca, bukan ditulis"
+msgstr "fflush: tidak dapat flush: berkas `%s' dibuka untuk dibaca, bukan ditulis"
-#: builtin.c:212
+#: builtin.c:244
#, c-format
msgid "fflush: `%s' is not an open file, pipe or co-process"
msgstr "fflush: `%s' bukan sebuah berkas terbuka, pipe atau co-proses"
-#: builtin.c:330
+#: builtin.c:362
msgid "index: received non-string first argument"
msgstr "indeks: diterima argumen pertama bukan string"
-#: builtin.c:332
+#: builtin.c:364
msgid "index: received non-string second argument"
msgstr "indeks: diterima argumen kedua bukan string"
-#: builtin.c:454
+#: builtin.c:488 mpfr.c:757
msgid "int: received non-numeric argument"
msgstr "int: diterima argumen bukan numerik"
-#: builtin.c:490
-#, fuzzy
+#: builtin.c:525
msgid "length: received array argument"
msgstr "length: diterima argumen bukan-string"
-#: builtin.c:493
-#, fuzzy
+#: builtin.c:528
msgid "`length(array)' is a gawk extension"
msgstr "`length(array)' adalah sebuah ekstensi gawk"
-#: builtin.c:501
+#: builtin.c:544
msgid "length: received non-string argument"
msgstr "length: diterima argumen bukan-string"
-#: builtin.c:532
+#: builtin.c:575
msgid "log: received non-numeric argument"
msgstr "log: diterima argumen bukan numerik"
-#: builtin.c:535
+#: builtin.c:578
#, c-format
msgid "log: received negative argument %g"
msgstr "log: diterima argumen negatif %g"
-#: builtin.c:593 builtin.c:604
+#: builtin.c:776 builtin.c:781
+msgid "fatal: must use `count$' on all formats or none"
+msgstr "harus menggunakan `count$' di semua format atau tidak sama sekali"
+
+#: builtin.c:851
+#, c-format
+msgid "field width is ignored for `%%' specifier"
+msgstr "lebar daerah diabaikan untuk penspesifikasi `%%'"
+
+#: builtin.c:853
+#, c-format
+msgid "precision is ignored for `%%' specifier"
+msgstr "ketepatan diabaikan untuk penspesifikasi `%%'"
+
+#: builtin.c:855
+#, c-format
+msgid "field width and precision are ignored for `%%' specifier"
+msgstr "lebar daerah dan presisi diabaikan untuk penspesifikasi `%%'"
+
+#: builtin.c:906
+msgid "fatal: `$' is not permitted in awk formats"
+msgstr "`$' tidak diijinkan dalam format awk"
+
+#: builtin.c:915
+msgid "fatal: arg count with `$' must be > 0"
+msgstr "arg count dengan `$' harus > 0"
+
+#: builtin.c:919
+#, c-format
+msgid "fatal: arg count %ld greater than total number of supplied arguments"
+msgstr "arg count %ld lebih besar dari jumlah total dari argumen yang diberikan"
+
+#: builtin.c:923
+msgid "fatal: `$' not permitted after period in format"
+msgstr "`$' tidak diijinkan setelah periode dalam format"
+
+#: builtin.c:939
+msgid "fatal: no `$' supplied for positional field width or precision"
+msgstr "tidak ada `$' yang diberikan untuk posisional field width atau presisi"
+
+#: builtin.c:1011
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr "`l' tidak berarti dalam format awk; diabaikan"
+
+#: builtin.c:1015
+msgid "fatal: `l' is not permitted in POSIX awk formats"
+msgstr "`l' tidak diijinkan dalam format POSIX awk"
+
+#: builtin.c:1028
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr "`L' tidak berarti dalam format awk; diabaikan"
+
+#: builtin.c:1032
+msgid "fatal: `L' is not permitted in POSIX awk formats"
+msgstr "`L' tidak diijinkan dalam format awk POSIX"
+
+#: builtin.c:1045
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr "`h' tidak berarti dalam format awk; diabaikan"
+
+#: builtin.c:1049
+msgid "fatal: `h' is not permitted in POSIX awk formats"
+msgstr "`h' tidak diijinkan dalam format awk POSIX"
+
+#: builtin.c:1447
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr "[s]printf: nilai %g diluar dari jangkauan untuk format `%%%c'"
+
+#: builtin.c:1545
+#, c-format
+msgid "ignoring unknown format specifier character `%c': no argument converted"
+msgstr "mengabaikan format tidak dikenal karakter penspesifikasi `%c': tidak ada argumen yang diubah"
+
+#: builtin.c:1550
+msgid "fatal: not enough arguments to satisfy format string"
+msgstr "tidak cukup argumen untuk memuaskan format string"
+
+#: builtin.c:1552
+msgid "^ ran out for this one"
+msgstr "^ kehabisan untuk yang ini"
+
+#: builtin.c:1559
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "[s]printf: penspesifikasi format tidak memiliki pengontrol huruf"
+
+#: builtin.c:1562
+msgid "too many arguments supplied for format string"
+msgstr "terlalu banyak argumen diberikan untuk format string"
+
+#: builtin.c:1618
+msgid "sprintf: no arguments"
+msgstr "sprintf: tidak ada argumen"
+
+#: builtin.c:1641 builtin.c:1652
msgid "printf: no arguments"
msgstr "printf: tidak ada argumen"
-#: builtin.c:645
+#: builtin.c:1695
msgid "sqrt: received non-numeric argument"
msgstr "sqrt: diterima argumen bukan numerik"
-#: builtin.c:649
+#: builtin.c:1699
#, c-format
msgid "sqrt: called with negative argument %g"
msgstr "sqrt: dipanggil dengan argumen %g negatif"
-#: builtin.c:673
+#: builtin.c:1730
#, c-format
msgid "substr: length %g is not >= 1"
msgstr "substr: panjang %g tidak >= 1"
-#: builtin.c:675
+#: builtin.c:1732
#, c-format
msgid "substr: length %g is not >= 0"
msgstr "substr: panjang %g tidak >= 0"
-#: builtin.c:682
+#: builtin.c:1739
#, c-format
msgid "substr: non-integer length %g will be truncated"
msgstr "substr: panjang bukan integer %g akan dipotong"
-#: builtin.c:687
+#: builtin.c:1744
#, c-format
msgid "substr: length %g too big for string indexing, truncating to %g"
-msgstr ""
-"substr: panjang %g terlalu besar untuk pengindeksan string, dipotong ke %g"
+msgstr "substr: panjang %g terlalu besar untuk pengindeksan string, dipotong ke %g"
-#: builtin.c:699
+#: builtin.c:1756
#, c-format
msgid "substr: start index %g is invalid, using 1"
msgstr "substr: awal indeks %g tidak valid, menggunakan 1"
-#: builtin.c:704
+#: builtin.c:1761
#, c-format
msgid "substr: non-integer start index %g will be truncated"
msgstr "substr: awal indeks %g bukan integer akan dipotong"
-#: builtin.c:729
+#: builtin.c:1786
msgid "substr: source string is zero length"
msgstr "substr: sumber string memiliki panjang nol"
-#: builtin.c:745
+#: builtin.c:1802
#, c-format
msgid "substr: start index %g is past end of string"
msgstr "substr: awal indeks %g melewati akhir dari string"
-#: builtin.c:753
+#: builtin.c:1810
#, c-format
-msgid ""
-"substr: length %g at start index %g exceeds length of first argument (%lu)"
-msgstr ""
-"substr: panjang %g di awal indeks %g melewati panjang dari argumen pertama "
-"(%lu)"
+msgid "substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr "substr: panjang %g di awal indeks %g melewati panjang dari argumen pertama (%lu)"
-#: builtin.c:826
+#: builtin.c:1884
msgid "strftime: format value in PROCINFO[\"strftime\"] has numeric type"
-msgstr ""
+msgstr "strftime: format value in PROCINFO[\"strftime\"] has numeric type"
-#: builtin.c:840
+#: builtin.c:1907
msgid "strftime: received non-numeric second argument"
msgstr "strftime: diterima argumen kedua bukan numerik"
-#: builtin.c:847
+#: builtin.c:1911
+msgid "strftime: second argument less than 0 or too big for time_t"
+msgstr "strftime: second argument less than 0 or too big for time_t"
+
+#: builtin.c:1918
msgid "strftime: received non-string first argument"
msgstr "strftime: diterima argumen pertama bukan string"
-#: builtin.c:853
+#: builtin.c:1925
msgid "strftime: received empty format string"
msgstr "strftime: diterima format string kosong"
-#: builtin.c:919
+#: builtin.c:1991
msgid "mktime: received non-string argument"
msgstr "mktime: diterima argumen bukan string"
-#: builtin.c:936
+#: builtin.c:2008
msgid "mktime: at least one of the values is out of the default range"
-msgstr ""
+msgstr "mktime: at least one of the values is out of the default range"
-#: builtin.c:971
+#: builtin.c:2043
msgid "'system' function not allowed in sandbox mode"
-msgstr ""
+msgstr "'system' function not allowed in sandbox mode"
-#: builtin.c:976
+#: builtin.c:2048
msgid "system: received non-string argument"
msgstr "system: diterima argumen bukan string"
-#: builtin.c:1031 eval.c:1411 eval.c:1936 eval.c:1949
-#, c-format
-msgid "reference to uninitialized variable `%s'"
-msgstr "referensi ke variabel `%s' tidak terinisialisasi"
-
-#: builtin.c:1098
+#: builtin.c:2168
#, c-format
msgid "reference to uninitialized field `$%d'"
msgstr "referensi ke field tidak terinisialisasi `$%d'"
-#: builtin.c:1185
+#: builtin.c:2255
msgid "tolower: received non-string argument"
msgstr "tolower: diterima argumen bukan string"
-#: builtin.c:1219
+#: builtin.c:2289
msgid "toupper: received non-string argument"
msgstr "toupper: diterima argumen bukan string"
-#: builtin.c:1255
+#: builtin.c:2325 mpfr.c:672
msgid "atan2: received non-numeric first argument"
msgstr "atan2: diterima argumen pertama bukan numerik"
-#: builtin.c:1257
+#: builtin.c:2327 mpfr.c:674
msgid "atan2: received non-numeric second argument"
msgstr "atan2: diterima argumen kedua bukan numerik"
-#: builtin.c:1276
+#: builtin.c:2346
msgid "sin: received non-numeric argument"
msgstr "sin: diterima argumen bukan numerik"
-#: builtin.c:1292
+#: builtin.c:2362
msgid "cos: received non-numeric argument"
msgstr "cos: diterima argumen bukan numerik"
-#: builtin.c:1345
+#: builtin.c:2415 mpfr.c:1156
msgid "srand: received non-numeric argument"
msgstr "srand: diterima argumen bukan numerik"
-#: builtin.c:1376
+#: builtin.c:2446
msgid "match: third argument is not an array"
msgstr "match: argumen ketiga bukan sebuah array"
-#: builtin.c:1883
+#: builtin.c:2718
msgid "gensub: third argument of 0 treated as 1"
msgstr "gensub: argumen ketiga dari 0 diperlakukan sebagai 1"
-#: builtin.c:1923
+#: builtin.c:3014
msgid "lshift: received non-numeric first argument"
msgstr "lshift: diterima argumen pertama bukan numerik"
-#: builtin.c:1925
+#: builtin.c:3016
msgid "lshift: received non-numeric second argument"
msgstr "lshift: diterima argumen kedua bukan numerik"
-#: builtin.c:1931
+#: builtin.c:3022
#, c-format
-msgid "lshift(%lf, %lf): negative values will give strange results"
-msgstr "lshift(%lf, %lf): nilai negatif akan memberikan hasil aneh"
+msgid "lshift(%f, %f): negative values will give strange results"
+msgstr "lshift(%f, %f): nilai negatif akan memberikan hasil aneh"
-#: builtin.c:1933
+#: builtin.c:3024
#, c-format
-msgid "lshift(%lf, %lf): fractional values will be truncated"
-msgstr "lshift(%lf, %lf): nilai pecahan akan dipotong"
+msgid "lshift(%f, %f): fractional values will be truncated"
+msgstr "lshift(%f, %f): nilai pecahan akan dipotong"
-#: builtin.c:1935
+#: builtin.c:3026
#, c-format
-msgid "lshift(%lf, %lf): too large shift value will give strange results"
-msgstr "lshift(%lf, %lf): nilai shift terlalu besar akan memberikan hasil aneh"
+msgid "lshift(%f, %f): too large shift value will give strange results"
+msgstr "lshift(%f, %f): nilai shift terlalu besar akan memberikan hasil aneh"
-#: builtin.c:1960
+#: builtin.c:3051
msgid "rshift: received non-numeric first argument"
msgstr "rshift: diterima argumen pertama bukan numerik"
-#: builtin.c:1962
+#: builtin.c:3053
msgid "rshift: received non-numeric second argument"
msgstr "rshift: diterima argumen kedua bukan-numerik"
-#: builtin.c:1968
+#: builtin.c:3059
#, c-format
-msgid "rshift(%lf, %lf): negative values will give strange results"
-msgstr "rshift(%lf. %lf): nilai negatif akan memberikan hasil aneh"
+msgid "rshift(%f, %f): negative values will give strange results"
+msgstr "rshift(%f. %f): nilai negatif akan memberikan hasil aneh"
-#: builtin.c:1970
+#: builtin.c:3061
#, c-format
-msgid "rshift(%lf, %lf): fractional values will be truncated"
-msgstr "rshift(%lf, %lf): nilai pecahan akan dipotong"
+msgid "rshift(%f, %f): fractional values will be truncated"
+msgstr "rshift(%f, %f): nilai pecahan akan dipotong"
-#: builtin.c:1972
+#: builtin.c:3063
#, c-format
-msgid "rshift(%lf, %lf): too large shift value will give strange results"
-msgstr "rshift(%lf, %lf): nilai shift terlalu besar akan memberikan hasil aneh"
-
-#: builtin.c:1997
-msgid "and: received non-numeric first argument"
-msgstr "and: diterima argumen pertama tidak numerik"
+msgid "rshift(%f, %f): too large shift value will give strange results"
+msgstr "rshift(%f, %f): nilai shift terlalu besar akan memberikan hasil aneh"
-#: builtin.c:1999
-msgid "and: received non-numeric second argument"
-msgstr "and: diterima argumen kedua bukan numerik"
+#: builtin.c:3088 mpfr.c:968
+msgid "and: called with less than two arguments"
+msgstr "and: dipanggil dengan argumen negatif"
-#: builtin.c:2005
+#: builtin.c:3093
#, c-format
-msgid "and(%lf, %lf): negative values will give strange results"
-msgstr "and(%lf, %lf): nilai negatif akan memberikan hasil aneh"
+msgid "and: argument %d is non-numeric"
+msgstr "and: argumen %d diluar dari jangkauan"
-#: builtin.c:2007
+#: builtin.c:3097
#, c-format
-msgid "and(%lf, %lf): fractional values will be truncated"
-msgstr "and(%lf, %lf): nilai pecahan akan dipotong"
+msgid "and: argument %d negative value %g will give strange results"
+msgstr "and: nilai %d negatif akan memberikan %g hasil aneh"
-#: builtin.c:2032
-msgid "or: received non-numeric first argument"
-msgstr "or: diterima argumen pertama bukan numerik"
+#: builtin.c:3120 mpfr.c:1000
+msgid "or: called with less than two arguments"
+msgstr "or: dipanggil dengan argumen negatif"
-#: builtin.c:2034
-msgid "or: received non-numeric second argument"
-msgstr "or: diterima argumen kedua bukan numerik"
-
-#: builtin.c:2040
+#: builtin.c:3125
#, c-format
-msgid "or(%lf, %lf): negative values will give strange results"
-msgstr "or(%lf, %lf): nilai negatif akan memberikan hasil aneh"
+msgid "or: argument %d is non-numeric"
+msgstr "or: argumen %d diluar dari jangkauan"
-#: builtin.c:2042
+#: builtin.c:3129
#, c-format
-msgid "or(%lf, %lf): fractional values will be truncated"
-msgstr "or(%lf, %lf): nilai pecahan akan dipotong"
-
-#: builtin.c:2070
-msgid "xor: received non-numeric first argument"
-msgstr "xor: diterima argumen pertama bukan numerik"
+msgid "or: argument %d negative value %g will give strange results"
+msgstr "or: nilai %d negatif akan memberikan %g hasil aneh"
-#: builtin.c:2072
-msgid "xor: received non-numeric second argument"
-msgstr "xor: diterima argumen kedua bukan numerik"
+#: builtin.c:3151 mpfr.c:1031
+msgid "xor: called with less than two arguments"
+msgstr "xor: dipanggil dengan argumen negatif"
-#: builtin.c:2078
+#: builtin.c:3157
#, c-format
-msgid "xor(%lf, %lf): negative values will give strange results"
-msgstr "xor(%lf, %lf): nilai negatif akan memberikan hasil aneh"
+msgid "xor: argument %d is non-numeric"
+msgstr "xor: argumen %d diluar dari jangkauan"
-#: builtin.c:2080
+#: builtin.c:3161
#, c-format
-msgid "xor(%lf, %lf): fractional values will be truncated"
-msgstr "xor(%lf, %lf): nilai pecahan akan dipotong"
+msgid "xor: argument %d negative value %g will give strange results"
+msgstr "xor: nilai %d negatif akan memberikan %g hasil aneh"
-#: builtin.c:2104 builtin.c:2110
+#: builtin.c:3186 mpfr.c:787
msgid "compl: received non-numeric argument"
msgstr "compl: diterima argumen bukan numerik"
-#: builtin.c:2112
+#: builtin.c:3192
#, c-format
-msgid "compl(%lf): negative value will give strange results"
-msgstr "compl(%lf): nilai negatif akan memberikan hasil aneh"
+msgid "compl(%f): negative value will give strange results"
+msgstr "compl(%f): nilai negatif akan memberikan hasil aneh"
-#: builtin.c:2114
+#: builtin.c:3194
#, c-format
-msgid "compl(%lf): fractional value will be truncated"
-msgstr "compl(%lf): nilai pecahan akan dipotong"
+msgid "compl(%f): fractional value will be truncated"
+msgstr "compl(%f): nilai pecahan akan dipotong"
-#: builtin.c:2283
+#: builtin.c:3363
#, c-format
msgid "dcgettext: `%s' is not a valid locale category"
msgstr "dcgettext: `%s' bukan sebuah kategori lokal yang valid"
-#: eval.c:410
+#: command.y:225
+#, c-format
+msgid "Type (g)awk statement(s). End with the command \"end\"\n"
+msgstr "Type (g)awk statement(s). End with the command \"end\"\n"
+
+#: command.y:289
+#, c-format
+msgid "invalid frame number: %d"
+msgstr "Akhir jangkauan tidak valid: %d"
+
+#: command.y:295
+#, c-format
+msgid "info: invalid option - \"%s\""
+msgstr "info: pilihan tidak valid - \"%s\""
+
+#: command.y:321
+#, c-format
+msgid "source \"%s\": already sourced."
+msgstr "source \"%s\": already sourced."
+
+#: command.y:326
+#, c-format
+msgid "save \"%s\": command not permitted."
+msgstr "save \"%s\": command not permitted."
+
+#: command.y:339
+msgid "Can't use command `commands' for breakpoint/watchpoint commands"
+msgstr "Can't use command `commands' for breakpoint/watchpoint commands"
+
+#: command.y:341
+msgid "no breakpoint/watchpoint has been set yet"
+msgstr "no breakpoint/watchpoint has been set yet"
+
+#: command.y:343
+msgid "invalid breakpoint/watchpoint number"
+msgstr "invalid breakpoint/watchpoint number"
+
+#: command.y:348
+#, c-format
+msgid "Type commands for when %s %d is hit, one per line.\n"
+msgstr "Type commands for when %s %d is hit, one per line.\n"
+
+#: command.y:350
+#, c-format
+msgid "End with the command \"end\"\n"
+msgstr "End with the command \"end\"\n"
+
+#: command.y:357
+msgid "`end' valid only in command `commands' or `eval'"
+msgstr "`end' valid only in command `commands' or `eval'"
+
+#: command.y:367
+msgid "`silent' valid only in command `commands'"
+msgstr "`silent' valid only in command `commands'"
+
+#: command.y:373
+#, c-format
+msgid "trace: invalid option - \"%s\""
+msgstr "trace: pilihan tidak valid - \"%s\""
+
+#: command.y:387
+msgid "condition: invalid breakpoint/watchpoint number"
+msgstr "condition: invalid breakpoint/watchpoint number"
+
+#: command.y:449
+msgid "argument not a string"
+msgstr "tidak cukup argumen untuk memuaskan format string"
+
+#: command.y:459 command.y:464
+#, c-format
+msgid "option: invalid parameter - \"%s\""
+msgstr "option: invalid parameter - \"%s\""
+
+#: command.y:474
+#, c-format
+msgid "no such function - \"%s\""
+msgstr "no such function - \"%s\""
+
+#: command.y:531
+#, c-format
+msgid "enable: invalid option - \"%s\""
+msgstr "enable: pilihan tidak valid - \"%s\""
+
+#: command.y:597
+#, c-format
+msgid "invalid range specification: %d - %d"
+msgstr "Akhir jangkauan tidak valid: %d - %d"
+
+#: command.y:659
+msgid "non-numeric value for field number"
+msgstr "non-numeric value for field number"
+
+#: command.y:680 command.y:687
+msgid "non-numeric value found, numeric expected"
+msgstr "non-numeric value found, numeric expected"
+
+#: command.y:712 command.y:718
+msgid "non-zero integer value"
+msgstr "non-zero integer value"
+
+#: command.y:817
+msgid "backtrace [N] - print trace of all or N innermost (outermost if N < 0) frames."
+msgstr "backtrace [N] - print trace of all or N innermost (outermost if N < 0) frames."
+
+#: command.y:819
+msgid "break [[filename:]N|function] - set breakpoint at the specified location."
+msgstr "break [[filename:]N|function] - set breakpoint at the specified location."
+
+#: command.y:821
+msgid "clear [[filename:]N|function] - delete breakpoints previously set."
+msgstr "clear [[filename:]N|function] - delete breakpoints previously set."
+
+#: command.y:823
+msgid "commands [num] - starts a list of commands to be executed at a breakpoint(watchpoint) hit."
+msgstr "commands [num] - starts a list of commands to be executed at a breakpoint(watchpoint) hit."
+
+#: command.y:825
+msgid "condition num [expr] - set or clear breakpoint or watchpoint condition."
+msgstr "condition num [expr] - set or clear breakpoint or watchpoint condition."
+
+#: command.y:827
+msgid "continue [COUNT] - continue program being debugged."
+msgstr "continue [COUNT] - continue program being debugged."
+
+#: command.y:829
+msgid "delete [breakpoints] [range] - delete specified breakpoints."
+msgstr "delete [breakpoints] [range] - delete specified breakpoints."
+
+#: command.y:831
+msgid "disable [breakpoints] [range] - disable specified breakpoints."
+msgstr "disable [breakpoints] [range] - disable specified breakpoints."
+
+#: command.y:833
+msgid "display [var] - print value of variable each time the program stops."
+msgstr "display [var] - print value of variable each time the program stops."
+
+#: command.y:835
+msgid "down [N] - move N frames down the stack."
+msgstr "down [N] - move N frames down the stack."
+
+#: command.y:837
+msgid "dump [filename] - dump instructions to file or stdout."
+msgstr "dump [filename] - dump instructions to file or stdout."
+
+#: command.y:839
+msgid "enable [once|del] [breakpoints] [range] - enable specified breakpoints."
+msgstr "enable [once|del] [breakpoints] [range] - enable specified breakpoints."
+
+#: command.y:841
+msgid "end - end a list of commands or awk statements."
+msgstr "end - end a list of commands or awk statements."
+
+#: command.y:843
+msgid "eval stmt|[p1, p2, ...] - evaluate awk statement(s)."
+msgstr "eval stmt|[p1, p2, ...] - evaluate awk statement(s)."
+
+#: command.y:845
+msgid "finish - execute until selected stack frame returns."
+msgstr "finish - execute until selected stack frame returns."
+
+#: command.y:847
+msgid "frame [N] - select and print stack frame number N."
+msgstr "frame [N] - select and print stack frame number N."
+
+#: command.y:849
+msgid "help [command] - print list of commands or explanation of command."
+msgstr "help [command] - print list of commands or explanation of command."
+
+#: command.y:851
+msgid "ignore N COUNT - set ignore-count of breakpoint number N to COUNT."
+msgstr "ignore N COUNT - set ignore-count of breakpoint number N to COUNT."
+
+#: command.y:853
+msgid "info topic - source|sources|variables|functions|break|frame|args|locals|display|watch."
+msgstr "info topic - source|sources|variables|functions|break|frame|args|locals|display|watch."
+
+#: command.y:855
+msgid "list [-|+|[filename:]lineno|function|range] - list specified line(s)."
+msgstr "list [-|+|[filename:]lineno|function|range] - list specified line(s)."
+
+#: command.y:857
+msgid "next [COUNT] - step program, proceeding through subroutine calls."
+msgstr "next [COUNT] - step program, proceeding through subroutine calls."
+
+#: command.y:859
+msgid "nexti [COUNT] - step one instruction, but proceed through subroutine calls."
+msgstr "nexti [COUNT] - stepp one instruction, but proceed through subroutine calls."
+
+#: command.y:861
+msgid "option [name[=value]] - set or display debugger option(s)."
+msgstr "option [name[=value]] - set or display debugger option(s)."
+
+#: command.y:863
+msgid "print var [var] - print value of a variable or array."
+msgstr "print var [var] - print value of a variable or array."
+
+#: command.y:865
+msgid "printf format, [arg], ... - formatted output."
+msgstr "printf format, [arg], ... - formatted output."
+
+#: command.y:867
+msgid "quit - exit debugger."
+msgstr "quit - exit debugger."
+
+#: command.y:869
+msgid "return [value] - make selected stack frame return to its caller."
+msgstr "return [value] - make selected stack frame return to its caller."
+
+#: command.y:871
+msgid "run - start or restart executing program."
+msgstr "run - start or restart executing program."
+
+#: command.y:874
+msgid "save filename - save commands from the session to file."
+msgstr "save filename - save commands from the session to file."
+
+#: command.y:877
+msgid "set var = value - assign value to a scalar variable."
+msgstr "set var = value - assign value to a scalar variable."
+
+#: command.y:879
+msgid "silent - suspends usual message when stopped at a breakpoint/watchpoint."
+msgstr "silent - suspends usual message when stopped at a breakpoint/watchpoint."
+
+#: command.y:881
+msgid "source file - execute commands from file."
+msgstr "source file - execute commads from file."
+
+#: command.y:883
+msgid "step [COUNT] - step program until it reaches a different source line."
+msgstr "step [COUNT] - step program until it reaches a different source line."
+
+#: command.y:885
+msgid "stepi [COUNT] - step one instruction exactly."
+msgstr "stepi [COUNT] - step one instruction exactly."
+
+#: command.y:887
+msgid "tbreak [[filename:]N|function] - set a temporary breakpoint."
+msgstr "tbreak [[filename:]N|function] - set a temporary breakpoint."
+
+#: command.y:889
+msgid "trace on|off - print instruction before executing."
+msgstr "trace on|off - print instruction before executing."
+
+#: command.y:891
+msgid "undisplay [N] - remove variable(s) from automatic display list."
+msgstr "undisplay [N] - remove variable(s) from automatic display list."
+
+#: command.y:893
+msgid "until [[filename:]N|function] - execute until program reaches a different line or line N within current frame."
+msgstr "until [[filename:]N|function] - execute until program reaches a different line or line N within current frame."
+
+#: command.y:895
+msgid "unwatch [N] - remove variable(s) from watch list."
+msgstr "unwatch [N] - remove variable(s) from watch list."
+
+#: command.y:897
+msgid "up [N] - move N frames up the stack."
+msgstr "up [N] - move N frames up the stack."
+
+#: command.y:899
+msgid "watch var - set a watchpoint for a variable."
+msgstr "watch var - set a watchpoint for a variable."
+
+#: command.y:1011 debug.c:401 msg.c:135
+#, c-format
+msgid "error: "
+msgstr "error: "
+
+#: command.y:1051
+#, c-format
+msgid "can't read command (%s)\n"
+msgstr "tidak dapat redirek dari (%s)\n"
+
+#: command.y:1065
+#, c-format
+msgid "can't read command (%s)"
+msgstr "tidak dapat redirek dari (%s)"
+
+#: command.y:1116
+msgid "invalid character in command"
+msgstr "nama kelas karakter tidak valid"
+
+#: command.y:1152
+#, c-format
+msgid "unknown command - \"%.*s\", try help"
+msgstr "unknown command - \"%.*s\", try help"
+
+#: command.y:1222
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: command.y:1284
+msgid "invalid character"
+msgstr "Karakter kolasi tidak valid"
+
+#: command.y:1455
+#, c-format
+msgid "undefined command: %s\n"
+msgstr "undefined command: %s\n"
+
+#: debug.c:252
+msgid "set or show the number of lines to keep in history file."
+msgstr "set or show the number of lines to keep in history file."
+
+#: debug.c:254
+msgid "set or show the list command window size."
+msgstr "set or show the list command window size."
+
+#: debug.c:256
+msgid "set or show gawk output file."
+msgstr "set or show gawk output file."
+
+#: debug.c:258
+msgid "set or show debugger prompt."
+msgstr "set or show debugger prompt."
+
+#: debug.c:260
+msgid "(un)set or show saving of command history (value=on|off)."
+msgstr "(un)set or show saving of command history (value=on|off)."
+
+#: debug.c:262
+msgid "(un)set or show saving of options (value=on|off)."
+msgstr "(un)set or show saving of options (value=on|off)."
+
+#: debug.c:264
+msgid "(un)set or show instruction tracing (value=on|off)."
+msgstr "(un)set or show instruction tracing (value=on|off)."
+
+#: debug.c:345
+msgid "program not running."
+msgstr "program not running."
+
+#: debug.c:448 debug.c:606
+#, c-format
+msgid "can't read source file `%s' (%s)"
+msgstr "tidak dapat membaca berkas sumber `%s' (%s)"
+
+#: debug.c:453
+#, c-format
+msgid "source file `%s' is empty.\n"
+msgstr "berkas sumber `%s' kosong.\n"
+
+#: debug.c:480
+msgid "no current source file."
+msgstr "no current source file."
+
+#: debug.c:505
+#, c-format
+msgid "cannot find source file named `%s' (%s)"
+msgstr "tidak dapat membaca berkas sumber `%s' (%s)"
+
+#: debug.c:529
+#, c-format
+msgid "WARNING: source file `%s' modified since program compilation.\n"
+msgstr "WARNING: source file `%s' modified since program compilation.\n"
+
+#: debug.c:551
+#, c-format
+msgid "line number %d out of range; `%s' has %d lines"
+msgstr "line number %d out of range; `%s' has %d lines"
+
+#: debug.c:611
+#, c-format
+msgid "unexpected eof while reading file `%s', line %d"
+msgstr "tidak terduga baris baru atau akhir dari string `%s', %d"
+
+#: debug.c:620
+#, c-format
+msgid "source file `%s' modified since start of program execution"
+msgstr "source file `%s' modified since start of program execution"
+
+#: debug.c:732
+#, c-format
+msgid "Current source file: %s\n"
+msgstr "Current source file: %s\n"
+
+#: debug.c:733
+#, c-format
+msgid "Number of lines: %d\n"
+msgstr "Number of lines: %d\n"
+
+#: debug.c:740
+#, c-format
+msgid "Source file (lines): %s (%d)\n"
+msgstr "Source file (lines): %s (%d)\n"
+
+#: debug.c:754
+msgid ""
+"Number Disp Enabled Location\n"
+"\n"
+msgstr ""
+"Number Disp Enabled Location\n"
+"\n"
+
+#: debug.c:765
+#, c-format
+msgid "\tno of hits = %ld\n"
+msgstr "\tno of hits = %ld\n"
+
+#: debug.c:767
+#, c-format
+msgid "\tignore next %ld hit(s)\n"
+msgstr "\tignore next %ld hit(s)\n"
+
+#: debug.c:769 debug.c:909
+#, c-format
+msgid "\tstop condition: %s\n"
+msgstr "\tstop condition: %s\n"
+
+#: debug.c:771 debug.c:911
+msgid "\tcommands:\n"
+msgstr "\tcommands:\n"
+
+#: debug.c:793
+#, c-format
+msgid "Current frame: "
+msgstr "Current frame: "
+
+#: debug.c:796
+#, c-format
+msgid "Called by frame: "
+msgstr "Called by frame: "
+
+#: debug.c:800
+#, c-format
+msgid "Caller of frame: "
+msgstr "Caller of frame: "
+
+#: debug.c:818
+#, c-format
+msgid "None in main().\n"
+msgstr "None in main().\n"
+
+#: debug.c:848
+msgid "No arguments.\n"
+msgstr "tidak ada argumen\n"
+
+#: debug.c:849
+msgid "No locals.\n"
+msgstr "No locals.\n"
+
+#: debug.c:857
+msgid ""
+"All defined variables:\n"
+"\n"
+msgstr ""
+"All defined variables:\n"
+"\n"
+
+#: debug.c:867
+msgid ""
+"All defined functions:\n"
+"\n"
+msgstr ""
+"All defined functions:\n"
+"\n"
+
+#: debug.c:886
+msgid ""
+"Auto-display variables:\n"
+"\n"
+msgstr ""
+"Auto-display variables:\n"
+"\n"
+
+#: debug.c:889
+msgid ""
+"Watch variables:\n"
+"\n"
+msgstr ""
+"Watch variables:\n"
+"\n"
+
+#: debug.c:1029
+#, c-format
+msgid "no symbol `%s' in current context\n"
+msgstr "no symbol `%s' in current context\n"
+
+#: debug.c:1041 debug.c:1427
+#, c-format
+msgid "`%s' is not an array\n"
+msgstr "`%s' bukan sebuah nama variabel legal\n"
+
+#: debug.c:1055
+#, c-format
+msgid "$%ld = uninitialized field\n"
+msgstr "referensi ke field tidak terinisialisasi $%ld\n"
+
+#: debug.c:1076
+#, c-format
+msgid "array `%s' is empty\n"
+msgstr "berkas data `%s' kosong\n"
+
+#: debug.c:1119 debug.c:1171
+#, c-format
+msgid "[\"%s\"] not in array `%s'\n"
+msgstr "indeks [\"%s\"] tidak dalam array `%s'\n"
+
+#: debug.c:1175
+#, c-format
+msgid "`%s[\"%s\"]' is not an array\n"
+msgstr "`%s[\"%s\"]' is no an array\n"
+
+#: debug.c:1236 debug.c:4964
+#, c-format
+msgid "`%s' is not a scalar variable"
+msgstr "`%s' bukan sebuah nama variabel legal"
+
+#: debug.c:1258 debug.c:4994
+#, c-format
+msgid "attempt to use array `%s[\"%s\"]' in a scalar context"
+msgstr "mencoba menggunakan array `%s[\"%s\"]' dalam sebuah konteks skalar"
+
+#: debug.c:1280 debug.c:5005
+#, c-format
+msgid "attempt to use scalar `%s[\"%s\"]' as array"
+msgstr "mencoba untuk menggunakan skalar `%s[\"%s\"]' sebagai sebuah array"
+
+#: debug.c:1423
+#, c-format
+msgid "`%s' is a function"
+msgstr "`%s' digunakan dalam aksi"
+
+#: debug.c:1465
+#, c-format
+msgid "watchpoint %d is unconditional\n"
+msgstr "watchpoint %d is unconditional\n"
+
+#: debug.c:1499
+#, c-format
+msgid "No display item numbered %ld"
+msgstr "No display item numbered %ld"
+
+#: debug.c:1502
+#, c-format
+msgid "No watch item numbered %ld"
+msgstr "No watch item numbered %ld"
+
+#: debug.c:1528
+#, c-format
+msgid "%d: [\"%s\"] not in array `%s'\n"
+msgstr "%d: indeks [\"%s\"] tidak dalam array `%s'\n"
+
+#: debug.c:1767
+msgid "attempt to use scalar value as array"
+msgstr "mencoba untuk menggunakan skalar sebagai sebuah array"
+
+#: debug.c:1856
+#, c-format
+msgid "Watchpoint %d deleted because parameter is out of scope.\n"
+msgstr "Watchpoint %d deleted because parameter is out of scope.\n"
+
+#: debug.c:1867
+#, c-format
+msgid "Display %d deleted because parameter is out of scope.\n"
+msgstr "Display %d deleted because parameter is out of scope.\n"
+
+#: debug.c:1900
+#, c-format
+msgid " in file `%s', line %d\n"
+msgstr " in file `%s', line %d\n"
+
+#: debug.c:1921
+#, c-format
+msgid " at `%s':%d"
+msgstr " at `%s':%d"
+
+#: debug.c:1937 debug.c:2000
+#, c-format
+msgid "#%ld\tin "
+msgstr "#%ld\tin"
+
+#: debug.c:1974
+#, c-format
+msgid "More stack frames follow ...\n"
+msgstr "More stack frames follow ...\n"
+
+#: debug.c:2017
+msgid "invalid frame number"
+msgstr "Akhir jangkauan tidak valid"
+
+#: debug.c:2200
+#, c-format
+msgid "Note: breakpoint %d (enabled, ignore next %ld hits), also set at %s:%d"
+msgstr "Note: breakpoint %d (enabled, ignore next %ld hits), alse set at %s:%d"
+
+#: debug.c:2207
+#, c-format
+msgid "Note: breakpoint %d (enabled), also set at %s:%d"
+msgstr "Note: breakpoint %d (enabled), also set at %s:%d"
+
+#: debug.c:2214
+#, c-format
+msgid "Note: breakpoint %d (disabled, ignore next %ld hits), also set at %s:%d"
+msgstr "Note: breakpoint %d (disabled, ignore next %ld hits), also set at %s:%d"
+
+#: debug.c:2221
+#, c-format
+msgid "Note: breakpoint %d (disabled), also set at %s:%d"
+msgstr "Note: breakpoint %d (disabled), also set at %s:%d"
+
+#: debug.c:2238
+#, c-format
+msgid "Breakpoint %d set at file `%s', line %d\n"
+msgstr "Breakpoint %d set at file `%s', line %d\n"
+
+#: debug.c:2340
+#, c-format
+msgid "Can't set breakpoint in file `%s'\n"
+msgstr "Can't set breakpoint in file `%s'\n"
+
+#: debug.c:2369 debug.c:2492 debug.c:3350
+#, c-format
+msgid "line number %d in file `%s' out of range"
+msgstr "argumen %d diluar dari jangkauan `%s'"
+
+#: debug.c:2373
+#, c-format
+msgid "Can't find rule!!!\n"
+msgstr "Can't find rule!!!\n"
+
+#: debug.c:2375
+#, c-format
+msgid "Can't set breakpoint at `%s':%d\n"
+msgstr "Can't set breakpoint at `%s':%d\n"
+
+#: debug.c:2387
+#, c-format
+msgid "Can't set breakpoint in function `%s'\n"
+msgstr "Can't set breakpoint in function `%s'\n"
+
+#: debug.c:2403
+#, c-format
+msgid "breakpoint %d set at file `%s', line %d is unconditional\n"
+msgstr "breakpoint %d set at file `%s', line %d is unconditional\n"
+
+#: debug.c:2508 debug.c:2530
+#, c-format
+msgid "Deleted breakpoint %d"
+msgstr "Deleted breakpoint %d"
+
+#: debug.c:2514
+#, c-format
+msgid "No breakpoint(s) at entry to function `%s'\n"
+msgstr "No breakpoint(s) at entry to function `%s'\n"
+
+#: debug.c:2541
+#, c-format
+msgid "No breakpoint at file `%s', line #%d\n"
+msgstr "error membaca berkas masukan `%s': %d\n"
+
+#: debug.c:2596 debug.c:2637 debug.c:2657 debug.c:2700
+msgid "invalid breakpoint number"
+msgstr "invalid breakpoint number"
+
+#: debug.c:2612
+msgid "Delete all breakpoints? (y or n) "
+msgstr "Delete all breakpoints? (y or n) "
+
+#: debug.c:2613 debug.c:2923 debug.c:2976
+msgid "y"
+msgstr "y"
+
+#: debug.c:2662
+#, c-format
+msgid "Will ignore next %ld crossing(s) of breakpoint %d.\n"
+msgstr "Will ignore next %ld crossing(s) of breakpoint %d.\n"
+
+#: debug.c:2666
+#, c-format
+msgid "Will stop next time breakpoint %d is reached.\n"
+msgstr "Will stop next time breakpoint %d is reached.\n"
+
+#: debug.c:2783
+#, c-format
+msgid "Can only debug programs provided with the `-f' option.\n"
+msgstr "Can only debug programs provided with the `-f' option.\n"
+
+#: debug.c:2908
+#, c-format
+msgid "Failed to restart debugger"
+msgstr "Failed to restart debugger"
+
+#: debug.c:2922
+msgid "Program already running. Restart from beginning (y/n)? "
+msgstr "Program already running. Restart from beginning (y/n)? "
+
+#: debug.c:2926
+#, c-format
+msgid "Program not restarted\n"
+msgstr "Program not restarted\n"
+
+#: debug.c:2936
+#, c-format
+msgid "error: cannot restart, operation not allowed\n"
+msgstr "error: cannot restart, operation not allowed\n"
+
+#: debug.c:2942
+#, c-format
+msgid "error (%s): cannot restart, ignoring rest of the commands\n"
+msgstr "error (%s): cannot restart, ignoring rest of the commands\n"
+
+#: debug.c:2950
+#, c-format
+msgid "Starting program: \n"
+msgstr "Starting program: \n"
+
+#: debug.c:2959
+#, c-format
+msgid "Program exited %s with exit value: %d\n"
+msgstr "Program exited %s with exit value: %d\n"
+
+#: debug.c:2975
+msgid "The program is running. Exit anyway (y/n)? "
+msgstr "The program is running. Exit anyway (y/n)? "
+
+#: debug.c:3010
+#, c-format
+msgid "Not stopped at any breakpoint; argument ignored.\n"
+msgstr "Not stopped at any breakpoint; argument ignored.\n"
+
+#: debug.c:3015
+#, c-format
+msgid "invalid breakpoint number %d."
+msgstr "invalid breakpoint number %d."
+
+#: debug.c:3020
+#, c-format
+msgid "Will ignore next %ld crossings of breakpoint %d.\n"
+msgstr "Will ignore next %ld crossings of breakpoint %d.\n"
+
+#: debug.c:3207
+#, c-format
+msgid "'finish' not meaningful in the outermost frame main()\n"
+msgstr "'finish' not meaningful in the outermost frame main()\n"
+
+#: debug.c:3212
+#, c-format
+msgid "Run till return from "
+msgstr "Run till return from"
+
+#: debug.c:3255
+#, c-format
+msgid "'return' not meaningful in the outermost frame main()\n"
+msgstr "'return' not meaningful in the outermost frame main()\n"
+
+#: debug.c:3369
+#, c-format
+msgid "Can't find specified location in function `%s'\n"
+msgstr "Can't find specified location in function `%s'\n"
+
+#: debug.c:3377
+#, c-format
+msgid "invalid source line %d in file `%s'"
+msgstr "invalid source line %d in file `%s'"
+
+#: debug.c:3392
+#, c-format
+msgid "Can't find specified location %d in file `%s'\n"
+msgstr "Can't find specified location %d in file `%s'\n"
+
+#: debug.c:3424
+#, c-format
+msgid "element not in array\n"
+msgstr "tidak dalam array\n"
+
+#: debug.c:3424
+#, c-format
+msgid "untyped variable\n"
+msgstr "untyped variable\n"
+
+#: debug.c:3466
+#, c-format
+msgid "Stopping in %s ...\n"
+msgstr "Stopping in %s ...\n"
+
+#: debug.c:3543
+#, c-format
+msgid "'finish' not meaningful with non-local jump '%s'\n"
+msgstr "'finish' not meaningful with non-local jump '%s'\n"
+
+#: debug.c:3550
+#, c-format
+msgid "'until' not meaningful with non-local jump '%s'\n"
+msgstr "'until' not meaningful with non-local jump '%s'\n"
+
+#: debug.c:4185
+msgid "\t------[Enter] to continue or q [Enter] to quit------"
+msgstr "\t------[Enter] to continue or q [Enter] to quit------"
+
+#: debug.c:4186
+msgid "q"
+msgstr "q"
+
+#: debug.c:5001
+#, c-format
+msgid "[\"%s\"] not in array `%s'"
+msgstr "[\"%s\"] tidak dalam array `%s'"
+
+#: debug.c:5207
+#, c-format
+msgid "sending output to stdout\n"
+msgstr "sending output to stdout\n"
+
+#: debug.c:5247
+msgid "invalid number"
+msgstr "invalid number"
+
+#: debug.c:5381
+#, c-format
+msgid "`%s' not allowed in current context; statement ignored"
+msgstr "`%s' not allowed in current context; statement ignored"
+
+#: debug.c:5389
+msgid "`return' not allowed in current context; statement ignored"
+msgstr "`return' not allowed in current context; statement ignored"
+
+#: debug.c:5590
+#, c-format
+msgid "No symbol `%s' in current context"
+msgstr "No symbol `%s' in current context"
+
+#: dfa.c:998 dfa.c:1001 dfa.c:1021 dfa.c:1031 dfa.c:1043 dfa.c:1094 dfa.c:1103
+#: dfa.c:1106 dfa.c:1111 dfa.c:1124 dfa.c:1191
+msgid "unbalanced ["
+msgstr "unbalanced ["
+
+#: dfa.c:1052
+msgid "invalid character class"
+msgstr "nama kelas karakter tidak valid"
+
+#: dfa.c:1228
+msgid "character class syntax is [[:space:]], not [:space:]"
+msgstr "character class syntax is [[:space:]], not [:space:]"
+
+#: dfa.c:1280
+msgid "unfinished \\ escape"
+msgstr "unfinished \\ escape"
+
+#: dfa.c:1427 regcomp.c:161
+msgid "Invalid content of \\{\\}"
+msgstr "Isi dari \\{\\} tidak valid"
+
+#: dfa.c:1430 regcomp.c:176
+msgid "Regular expression too big"
+msgstr "Ekspresi regular terlalu besar"
+
+#: dfa.c:1847
+msgid "unbalanced ("
+msgstr "unbalanced ("
+
+#: dfa.c:1973
+msgid "no syntax specified"
+msgstr "no syntax specified"
+
+#: dfa.c:1981
+msgid "unbalanced )"
+msgstr "unbalanced )"
+
+#: eval.c:394
#, c-format
msgid "unknown nodetype %d"
msgstr "tipe titik %d tidak diketahui"
-#: eval.c:421 eval.c:435
-#, fuzzy, c-format
+#: eval.c:405 eval.c:419
+#, c-format
msgid "unknown opcode %d"
msgstr "tipe titik %d tidak diketahui"
-#: eval.c:432
+#: eval.c:416
#, c-format
msgid "opcode %s not an operator or keyword"
-msgstr ""
+msgstr "opcode %s not an operator or keyword"
-#: eval.c:485
+#: eval.c:472
msgid "buffer overflow in genflags2str"
msgstr "buffer overflow dalam genflags2str"
-#: eval.c:696
+#: eval.c:675
#, c-format
msgid ""
"\n"
@@ -879,835 +1801,1208 @@ msgstr ""
"\t# Fungsi Call Stack:\n"
"\n"
-#: eval.c:723
+#: eval.c:704
msgid "`IGNORECASE' is a gawk extension"
msgstr "`IGNORECASE' adalah ekstensi gawk"
-#: eval.c:752
+#: eval.c:736
msgid "`BINMODE' is a gawk extension"
msgstr "`BINMODE' adalah ekstensi gawk"
-#: eval.c:810
+#: eval.c:794
#, c-format
msgid "BINMODE value `%s' is invalid, treated as 3"
msgstr "BINMODE nilai `%s' tidak valid, diperlakukan sebagai 3"
-#: eval.c:900
+#: eval.c:885
#, c-format
msgid "bad `%sFMT' specification `%s'"
msgstr "buruk `%sFMT' spesifikasi `%s'"
-#: eval.c:978
+#: eval.c:969
msgid "turning off `--lint' due to assignment to `LINT'"
-msgstr "menonaktifkan `--lint' karena assignmen ke `LINT'"
-
-#: eval.c:1247
-#, fuzzy
-msgid "sorted array traversal is a gawk extension"
-msgstr "`delete array' adalah sebuah ekstensi gawk"
-
-#: eval.c:1291
-msgid "`PROCINFO[\"sorted_in\"]' value is not recognized"
-msgstr ""
+msgstr "menonaktifkan `--lint' karena penempatan ke `LINT'"
-#: eval.c:1373 eval.c:1923
-#, c-format
-msgid "can't use function name `%s' as variable or array"
-msgstr ""
-"tidak dapat menggunakan nama fungsi `%s' sebagai sebuah variabel atau array"
-
-#: eval.c:1401
-msgid "assignment is not allowed to result of builtin function"
-msgstr "assignmen tidak diijinkan untuk menghasilkan fungsi bawaan"
-
-#: eval.c:1410 eval.c:1935 eval.c:1948
+#: eval.c:1147
#, c-format
msgid "reference to uninitialized argument `%s'"
msgstr "referensi ke argumen `%s' tidak terinisialisasi"
-#: eval.c:1429
+#: eval.c:1148
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "referensi ke variabel `%s' tidak terinisialisasi"
+
+#: eval.c:1166
msgid "attempt to field reference from non-numeric value"
msgstr "mencoba untuk mereferensi field dari nilai bukan numerik"
-#: eval.c:1431
-#, fuzzy
+#: eval.c:1168
msgid "attempt to field reference from null string"
msgstr "mencoba untuk mereferensi dari null string"
-#: eval.c:1437
-#, fuzzy, c-format
+#: eval.c:1176
+#, c-format
msgid "attempt to access field %ld"
-msgstr "mencoba untuk mengakses field %d"
+msgstr "mencoba untuk mengakses field %ld"
-#: eval.c:1446
-#, fuzzy, c-format
+#: eval.c:1185
+#, c-format
msgid "reference to uninitialized field `$%ld'"
-msgstr "referensi ke field tidak terinisialisasi `$%d'"
+msgstr "referensi ke field tidak terinisialisasi `$%ld'"
-#: eval.c:1508
+#: eval.c:1272
#, c-format
msgid "function `%s' called with more arguments than declared"
msgstr "fungsi `%s' dipanggil argumen lebih dari yang dideklarasikan"
-#: eval.c:1663
+#: eval.c:1473
#, c-format
msgid "unwind_stack: unexpected type `%s'"
-msgstr ""
+msgstr "unwind_stack: unexpected type `%s'"
-#: eval.c:1747
+#: eval.c:1569
msgid "division by zero attempted in `/='"
msgstr "pembagian dengan nol dicoba dalam `/='"
-#: eval.c:1754
+#: eval.c:1576
#, c-format
msgid "division by zero attempted in `%%='"
msgstr "pembagian dengan nol dicoba dalam `%%='"
-#: eval.c:2057
-msgid "assignment used in conditional context"
-msgstr "assignment digunakan dalam konteks kondisional"
+#: ext.c:89 ext.c:171
+msgid "extensions are not allowed in sandbox mode"
+msgstr "extensions are not allowed in sandbox mode"
+
+#: ext.c:92
+msgid "-l / @load are gawk extensions"
+msgstr "adalah sebuah ekstensi gawk"
-#: eval.c:2061
-msgid "statement has no effect"
-msgstr "pernyataan tidak memiliki efek"
+#: ext.c:95
+msgid "load_ext: received NULL lib_name"
+msgstr "load_ext: received NULL lib_name"
-#: eval.c:2473
+#: ext.c:98
#, c-format
-msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
-msgstr ""
-"for loop: array `%s' berubah ukuran dari %ld ke %ld selama eksekusi loop"
+msgid "load_ext: cannot open library `%s' (%s)\n"
+msgstr "load_ext: tidak dapat membuka `%s' (%s)\n"
-#: eval.c:2583
+#: ext.c:104
#, c-format
-msgid "function called indirectly through `%s' does not exist"
-msgstr ""
+msgid "load_ext: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"
+msgstr "load_ext: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"
-#: eval.c:2595
+#: ext.c:110
#, c-format
-msgid "function `%s' not defined"
-msgstr "fungsi `%s' tidak didefinisikan"
+msgid "load_ext: library `%s': cannot call function `%s' (%s)\n"
+msgstr "load_ext: perpustakaan `%s': tidak dapat memanggil fungsi `%s' (%s)\n"
-#: eval.c:2656
-#, fuzzy, c-format
-msgid "non-redirected `getline' invalid inside `%s' rule"
-msgstr "tidak terdireksi `getline' tidak terdefinisi didalam aksi END"
+#: ext.c:114
+#, c-format
+msgid "load_ext: library `%s' initialization routine `%s' failed\n"
+msgstr "load_ext: library `%s' initialization routine `%s' failed\n"
-#: eval.c:2717
-#, fuzzy, c-format
-msgid "`nextfile' cannot be called from a `%s' rule"
-msgstr "`nextfile' tidak dapat dipanggil dari sebuah aturan END"
+#: ext.c:174
+msgid "`extension' is a gawk extension"
+msgstr "`extension' adalah sebuah ekstensi gawk"
-#: eval.c:2767
-#, fuzzy, c-format
-msgid "`next' cannot be called from a `%s' rule"
-msgstr "`next' tidak dapat dipanggil dari sebuah aturan END"
+#: ext.c:177
+msgid "extension: received NULL lib_name"
+msgstr "extension: received NULL lib_name"
-#: eval.c:2834
+#: ext.c:180
#, c-format
-msgid "Sorry, don't know how to interpret `%s'"
-msgstr ""
+msgid "extension: cannot open library `%s' (%s)"
+msgstr "extension: tidak dapat membuka `%s' (%s)"
-#: ext.c:64
-msgid "extensions are not allowed in sandbox mode"
-msgstr ""
+#: ext.c:186
+#, c-format
+msgid "extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)"
+msgstr "extension: perpustakaan `%s': tidak dapat memanggil fungsi (%s)"
-#: ext.c:70 ext.c:75
-msgid "`extension' is a gawk extension"
-msgstr "`extension' adalah sebuah ekstensi gawk"
+#: ext.c:190
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)"
+msgstr "extension: perpustakaan `%s': tidak dapat memanggil fungsi `%s' (%s)"
-#: ext.c:85
-#, fuzzy, c-format
-msgid "fatal: extension: cannot open `%s' (%s)\n"
-msgstr "extension: tidak dapat membuka `%s' (%s)\n"
+#: ext.c:221
+msgid "make_builtin: missing function name"
+msgstr "make_builtin: hilang nama fungsi"
-#: ext.c:94
-#, fuzzy, c-format
-msgid ""
-"fatal: extension: library `%s': does not define "
-"`plugin_is_GPL_compatible' (%s)\n"
-msgstr "extension: perpustakaan `%s': tidak dapat memanggil fungsi `%s' (%s)\n"
+#: ext.c:236
+#, c-format
+msgid "make_builtin: can't redefine function `%s'"
+msgstr "make_builtin: tidak dapat meredefinisi fungsi `%s'"
-#: ext.c:103
-#, fuzzy, c-format
-msgid "fatal: extension: library `%s': cannot call function `%s' (%s)\n"
-msgstr "extension: perpustakaan `%s': tidak dapat memanggil fungsi `%s' (%s)\n"
+#: ext.c:240
+#, c-format
+msgid "make_builtin: function `%s' already defined"
+msgstr "make_builtin: fungsi `%s' telah didefinisikan"
+
+#: ext.c:244
+#, c-format
+msgid "make_builtin: function name `%s' previously defined"
+msgstr "make_builtin: nama fungsi `%s' telah didefinisikan sebelumnya"
-#: ext.c:137
+#: ext.c:246
+#, c-format
+msgid "make_builtin: can't use gawk built-in `%s' as function name"
+msgstr "make_builtin: tidak dapat menggunakan gawk bawaan `%s' sebagai nama fungsi"
+
+#: ext.c:249 ext.c:304
+#, c-format
+msgid "make_builtin: negative argument count for function `%s'"
+msgstr "make_builtin: negative argument count for function `%s'"
+
+#: ext.c:276
msgid "extension: missing function name"
msgstr "extension: hilang nama fungsi"
-#: ext.c:142
+#: ext.c:279 ext.c:283
#, c-format
msgid "extension: illegal character `%c' in function name `%s'"
msgstr "extension: karakter `%c' tidak legal dalam nama fungsi `%s'"
-#: ext.c:151
+#: ext.c:291
#, c-format
msgid "extension: can't redefine function `%s'"
msgstr "extension: tidak dapat meredefinisi fungsi `%s'"
-#: ext.c:155
+#: ext.c:295
#, c-format
msgid "extension: function `%s' already defined"
msgstr "extension: fungsi `%s' telah didefinisikan"
-#: ext.c:160
+#: ext.c:299
#, c-format
msgid "extension: function name `%s' previously defined"
msgstr "extension: nama fungsi `%s' telah didefinisikan sebelumnya"
-#: ext.c:162
+#: ext.c:301
#, c-format
msgid "extension: can't use gawk built-in `%s' as function name"
-msgstr ""
-"extension: tidak dapat menggunakan gawk bawaan `%s' sebagai nama fungsi"
+msgstr "extension: tidak dapat menggunakan gawk bawaan `%s' sebagai nama fungsi"
-#: ext.c:166
+#: ext.c:375
#, c-format
-msgid "make_builtin: negative argument count for function `%s'"
-msgstr ""
-
-#: ext.c:269
-#, fuzzy, c-format
msgid "function `%s' defined to take no more than %d argument(s)"
msgstr "fungsi `%s' didefinisikan untuk mengambil lebih dari %d argumen"
-#: ext.c:272
+#: ext.c:378
#, c-format
msgid "function `%s': missing argument #%d"
msgstr "fungsi `%s': hilang argumen #%d"
-#: ext.c:282
+#: ext.c:395
#, c-format
msgid "function `%s': argument #%d: attempt to use scalar as an array"
-msgstr ""
-"fungsi `%s': argumen #%d: mencoba menggunaka skalar sebagai sebuah array"
+msgstr "fungsi `%s': argumen #%d: mencoba menggunaka skalar sebagai sebuah array"
-#: ext.c:286
+#: ext.c:399
#, c-format
msgid "function `%s': argument #%d: attempt to use array as a scalar"
-msgstr ""
-"fungsi `%s': argumen #%d: mencoba untuk menggunakan array sebagai sebuah "
-"skalar"
+msgstr "fungsi `%s': argumen #%d: mencoba untuk menggunakan array sebagai sebuah skalar"
-#: ext.c:299
-msgid "Operation Not Supported"
-msgstr "Operasi Tidak Didukung"
+#: ext.c:413
+msgid "dynamic loading of library not supported"
+msgstr "dynamic loading of library not supported"
+
+#: extension/filefuncs.c:159
+msgid "chdir: called with incorrect number of arguments, expecting 1"
+msgstr "chdir: dipanggil dengan argumen %g negatif"
+
+#: extension/filefuncs.c:439
+#, c-format
+msgid "stat: unable to read symbolic link `%s'"
+msgstr "stat: unable to read symbolic link `%s'"
+
+#: extension/filefuncs.c:472
+msgid "stat: called with wrong number of arguments"
+msgstr "stat: dipanggil dengan argumen negatif"
+
+#: extension/filefuncs.c:479
+msgid "stat: bad parameters"
+msgstr "stat: adalah parameter"
+
+#: extension/filefuncs.c:533
+#, c-format
+msgid "fts init: could not create variable %s"
+msgstr "fts init: could not create variable %s"
+
+#: extension/filefuncs.c:554
+msgid "fts is not supported on this system"
+msgstr "tidak didukung dalam awk lama"
+
+#: extension/filefuncs.c:573
+msgid "fill_stat_element: could not create array"
+msgstr "fill_stat_element: could not create array"
+
+#: extension/filefuncs.c:582
+msgid "fill_stat_element: could not set element"
+msgstr "fill_stat_element: could not set element"
+
+#: extension/filefuncs.c:597
+msgid "fill_path_element: could not set element"
+msgstr "fill_path_element: could not set element"
+
+#: extension/filefuncs.c:613
+msgid "fill_error_element: could not set element"
+msgstr "fill_error_element: could not set element"
+
+#: extension/filefuncs.c:660 extension/filefuncs.c:707
+msgid "fts-process: could not create array"
+msgstr "fts-process: could not create array"
+
+#: extension/filefuncs.c:670 extension/filefuncs.c:717
+#: extension/filefuncs.c:735
+msgid "fts-process: could not set element"
+msgstr "fts-process: could not set element"
+
+#: extension/filefuncs.c:784
+msgid "fts: called with incorrect number of arguments, expecting 3"
+msgstr "fts: dipanggil dengan argumen negatif"
+
+#: extension/filefuncs.c:787
+msgid "fts: bad first parameter"
+msgstr "fts: adalah parameter"
+
+#: extension/filefuncs.c:793
+msgid "fts: bad second parameter"
+msgstr "fts: adalah parameter"
+
+#: extension/filefuncs.c:799
+msgid "fts: bad third parameter"
+msgstr "fts: adalah parameter"
+
+#: extension/filefuncs.c:806
+msgid "fts: could not flatten array\n"
+msgstr "fts: could not flatten array\n"
-#: field.c:328
+#: extension/filefuncs.c:824
+msgid "fts: ignoring sneaky FTS_NOSTAT flag. nyah, nyah, nyah."
+msgstr "fts: ignoring sneaky FTS_NOSTAT flag. nyah, nyah, nyah."
+
+#: extension/filefuncs.c:841
+msgid "fts: clear_array() failed\n"
+msgstr "fts: clear_array() failed\n"
+
+#: extension/fnmatch.c:112
+msgid "fnmatch: called with less than three arguments"
+msgstr "fnmatch: dipanggil dengan argumen negatif"
+
+#: extension/fnmatch.c:115
+msgid "fnmatch: called with more than three arguments"
+msgstr "fnmatch: dipanggil dengan argumen negatif"
+
+#: extension/fnmatch.c:118
+msgid "fnmatch: could not get first argument"
+msgstr "fnmatch: diterima argumen pertama bukan string"
+
+#: extension/fnmatch.c:123
+msgid "fnmatch: could not get second argument"
+msgstr "fnmatch: diterima argumen kedua bukan string"
+
+#: extension/fnmatch.c:128
+msgid "fnmatch: could not get third argument"
+msgstr "fnmatch: could not get third argument"
+
+#: extension/fnmatch.c:141
+msgid "fnmatch is not implemented on this system\n"
+msgstr "fnmatch is not implemented on this system\n"
+
+#: extension/fnmatch.c:173
+msgid "fnmatch init: could not add FNM_NOMATCH variable"
+msgstr "fnmatch init: could not add FNM_NOMATCH variable"
+
+#: extension/fnmatch.c:183
+#, c-format
+msgid "fnmatch init: could not set array element %s"
+msgstr "fnmatch init: could not set array element %s"
+
+#: extension/fnmatch.c:193
+msgid "fnmatch init: could not install FNM array"
+msgstr "fnmatch init: could not install FNM array"
+
+#: extension/fork.c:81
+msgid "fork: called with too many arguments"
+msgstr "fork: dipanggil dengan argumen negatif"
+
+#: extension/fork.c:94
+msgid "fork: PROCINFO is not an array!"
+msgstr "fork: PROCINFO is not an array!"
+
+#: extension/fork.c:118
+msgid "waitpid: called with too many arguments"
+msgstr "waitpid: dipanggil dengan argumen negatif"
+
+#: extension/fork.c:126
+msgid "wait: called with no arguments"
+msgstr "wait: dipanggil dengan argumen negatif"
+
+#: extension/fork.c:143
+msgid "wait: called with too many arguments"
+msgstr "wait: dipanggil dengan argumen negatif"
+
+#: extension/inplace.c:130
+msgid "inplace_begin: in-place editing already active"
+msgstr "inplace_begin: in-place editing already active"
+
+#: extension/inplace.c:133 extension/inplace.c:207
+#, c-format
+msgid "inplace_begin: expects 2 arguments but called with %d"
+msgstr "inplace_begin: expects 2 arguments but called with %d"
+
+#: extension/inplace.c:136
+msgid "inplace_begin: cannot retrieve 1st argument as a string filename"
+msgstr "inplace_begin: cannot retrieve 1st argument as a string filename"
+
+#: extension/inplace.c:144
+#, c-format
+msgid "inplace_begin: disabling in-place editing for invalid FILENAME `%s'"
+msgstr "inplace_begin: disabling in-place editing for invalid FILENAME `%s'"
+
+#: extension/inplace.c:151
+#, c-format
+msgid "inplace_begin: Cannot stat `%s' (%s)"
+msgstr "inplace_begin: tidak dapat membuka `%s' (%s)"
+
+#: extension/inplace.c:158
+#, c-format
+msgid "inplace_begin: `%s' is not a regular file"
+msgstr "inplace_begin: `%s' is not a regular file"
+
+#: extension/inplace.c:169
+#, c-format
+msgid "inplace_begin: mkstemp(`%s') failed (%s)"
+msgstr "inplace_begin: mkstemp(`%s') failed (%s)"
+
+#: extension/inplace.c:178
+#, c-format
+msgid "inplace_begin: chmod failed (%s)"
+msgstr "inplace_begin: tutup gagal (%s)"
+
+#: extension/inplace.c:185
+#, c-format
+msgid "inplace_begin: dup(stdout) failed (%s)"
+msgstr "inplace_begin: dup(stdout) failed (%s)"
+
+#: extension/inplace.c:188
+#, c-format
+msgid "inplace_begin: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_begin: dup2(%d, stdout) failed (%s)"
+
+#: extension/inplace.c:191
+#, c-format
+msgid "inplace_begin: close(%d) failed (%s)"
+msgstr "inplace_begin: tutup(%d) gagal (%s)"
+
+#: extension/inplace.c:210
+msgid "inplace_end: cannot retrieve 1st argument as a string filename"
+msgstr "inplace_end: cannot retrieve 1st argument as a string filename"
+
+#: extension/inplace.c:217
+msgid "inplace_end: in-place editing not active"
+msgstr "inplace_end: in-place editing not active"
+
+#: extension/inplace.c:223
+#, c-format
+msgid "inplace_end: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_end: dup2(%d, stdout) failed (%s)"
+
+#: extension/inplace.c:226
+#, c-format
+msgid "inplace_end: close(%d) failed (%s)"
+msgstr "inplace_end: tutup(%d) gagal (%s)"
+
+#: extension/inplace.c:230
+#, c-format
+msgid "inplace_end: fsetpos(stdout) failed (%s)"
+msgstr "inplace_end: fsetpos(stdout) failed (%s)"
+
+#: extension/inplace.c:243
+#, c-format
+msgid "inplace_end: link(`%s', `%s') failed (%s)"
+msgstr "inplace_end: pipe flush dari (`%s',`%s') gagal (%s)."
+
+#: extension/inplace.c:253
+#, c-format
+msgid "inplace_end: rename(`%s', `%s') failed (%s)"
+msgstr "inplace_end: penutupan dari fd (`%s',`%s') gagal (%s)"
+
+#: extension/ordchr.c:69
+msgid "ord: called with too many arguments"
+msgstr "ord: dipanggil dengan argumen negatif"
+
+#: extension/ordchr.c:75
+msgid "ord: called with no arguments"
+msgstr "ord: dipanggil dengan argumen negatif"
+
+#: extension/ordchr.c:77
+msgid "ord: called with inappropriate argument(s)"
+msgstr "ord: dipanggil dengan argumen negatif"
+
+#: extension/ordchr.c:99
+msgid "chr: called with too many arguments"
+msgstr "chr: dipanggil dengan argumen negatif"
+
+#: extension/ordchr.c:109
+msgid "chr: called with no arguments"
+msgstr "chr: dipanggil dengan argumen negatif"
+
+#: extension/ordchr.c:111
+msgid "chr: called with inappropriate argument(s)"
+msgstr "chr: dipanggil dengan argumen negatif"
+
+#: extension/readdir.c:277
+#, c-format
+msgid "dir_take_control_of: opendir/fdopendir failed: %s"
+msgstr "dir_take_control_of: opendir/fdopendir failed: %s"
+
+#: extension/readfile.c:84
+msgid "readfile: called with too many arguments"
+msgstr "readfile: dipanggil dengan argumen negatif"
+
+#: extension/readfile.c:118
+msgid "readfile: called with no arguments"
+msgstr "readfile: dipanggil dengan argumen negatif"
+
+#: extension/rwarray.c:124
+msgid "writea: called with too many arguments"
+msgstr "writea: dipanggil dengan argumen negatif"
+
+#: extension/rwarray.c:131
+#, c-format
+msgid "do_writea: argument 0 is not a string\n"
+msgstr "do_write: argumen diluar dari jangkauan\n"
+
+#: extension/rwarray.c:137
+#, c-format
+msgid "do_writea: argument 1 is not an array\n"
+msgstr "do_writea: argumen kedua bukan sebuah array\n"
+
+#: extension/rwarray.c:184
+#, c-format
+msgid "write_array: could not flatten array\n"
+msgstr "write_array: could not flatten array\n"
+
+#: extension/rwarray.c:198
+#, c-format
+msgid "write_array: could not release flattened array\n"
+msgstr "write_array: could not release flattened array\n"
+
+#: extension/rwarray.c:280
+msgid "reada: called with too many arguments"
+msgstr "reada: dipanggil dengan argumen negatif"
+
+#: extension/rwarray.c:287
+#, c-format
+msgid "do_reada: argument 0 is not a string\n"
+msgstr "do_reada: argumen diluar dari jangkauan\n"
+
+#: extension/rwarray.c:293
+#, c-format
+msgid "do_reada: argument 1 is not an array\n"
+msgstr "do_reada: argumen ketiga bukan sebuah array\n"
+
+#: extension/rwarray.c:337
+#, c-format
+msgid "do_reada: clear_array failed\n"
+msgstr "do_reada: clear_array failed\n"
+
+#: extension/rwarray.c:374
+#, c-format
+msgid "read_array: set_array_element failed\n"
+msgstr "read_array: set_array_element failed\n"
+
+#: extension/time.c:106
+msgid "gettimeofday: ignoring arguments"
+msgstr "gettimeofday: diterima argumen bukan string"
+
+#: extension/time.c:137
+msgid "gettimeofday: not supported on this platform"
+msgstr "gettimeofday: not supported on this platform"
+
+#: extension/time.c:158
+msgid "sleep: called with too many arguments"
+msgstr "sleep: dipanggil dengan argumen negatif"
+
+#: extension/time.c:161
+msgid "sleep: missing required numeric argument"
+msgstr "sleep: diterima argumen bukan-numerik"
+
+#: extension/time.c:167
+msgid "sleep: argument is negative"
+msgstr "sleep: argumen diluar dari jangkauan"
+
+#: extension/time.c:201
+msgid "sleep: not supported on this platform"
+msgstr "sleep: not supported on this platform"
+
+#: field.c:345
msgid "NF set to negative value"
msgstr "NF set ke nilai negatif"
-#: field.c:939 field.c:946 field.c:950
-#, fuzzy
+#: field.c:971 field.c:978 field.c:982
msgid "split: fourth argument is a gawk extension"
-msgstr "cocok: argumen ketiga adalah sebuah ekstensi gawk"
+msgstr "split: argumen ketiga adalah sebuah ekstensi gawk"
-#: field.c:943
-#, fuzzy
+#: field.c:975
msgid "split: fourth argument is not an array"
msgstr "split: argumen kedua bukan sebuah array"
-#: field.c:957
+#: field.c:989
msgid "split: second argument is not an array"
msgstr "split: argumen kedua bukan sebuah array"
-#: field.c:962
-msgid "split: can not use the same array for second and fourth args"
-msgstr ""
+#: field.c:993
+msgid "split: cannot use the same array for second and fourth args"
+msgstr "split: cannot use the same array for second and fourth args"
-#: field.c:990
+#: field.c:998
+msgid "split: cannot use a subarray of second arg for fourth arg"
+msgstr "split: cannot use a subarray of second arg for fourth arg"
+
+#: field.c:1001
+msgid "split: cannot use a subarray of fourth arg for second arg"
+msgstr "split: cannot use a subarray of fourth arg for secod arg"
+
+#: field.c:1032
msgid "split: null string for third arg is a gawk extension"
msgstr "split: null string untuk arg ketika adalah sebuah ekstensi gawk"
-#: field.c:1031
-#, fuzzy
+#: field.c:1072
msgid "patsplit: fourth argument is not an array"
-msgstr "split: argumen kedua bukan sebuah array"
+msgstr "patsplit: argumen kedua bukan sebuah array"
-#: field.c:1036
-#, fuzzy
+#: field.c:1077
msgid "patsplit: second argument is not an array"
-msgstr "split: argumen kedua bukan sebuah array"
+msgstr "patsplit: argumen kedua bukan sebuah array"
-#: field.c:1054
-#, fuzzy
+#: field.c:1083
msgid "patsplit: third argument must be non-null"
-msgstr "match: argumen ketiga bukan sebuah array"
+msgstr "patsplit: argumen ketiga bukan sebuah array"
-#: field.c:1059
-msgid "patsplit: can not use the same array for second and fourth args"
-msgstr ""
+#: field.c:1087
+msgid "patsplit: cannot use the same array for second and fourth args"
+msgstr "patsplit: cannot use the same array for second and fourth args"
-#: field.c:1089
+#: field.c:1092
+msgid "patsplit: cannot use a subarray of second arg for fourth arg"
+msgstr "patsplit: cannot use a subarray of second arg for fourth arg"
+
+#: field.c:1095
+msgid "patsplit: cannot use a subarray of fourth arg for second arg"
+msgstr "patsplit: cannot use a subarray of fourth arg for second arg"
+
+#: field.c:1133
msgid "`FIELDWIDTHS' is a gawk extension"
msgstr "`FIELDWIDTHS' adalah sebuah ekstensi gawk"
-#: field.c:1152
+#: field.c:1197
#, c-format
msgid "invalid FIELDWIDTHS value, near `%s'"
msgstr "nilai FIELDWIDTHS tidak valid, didekat `%s'"
-#: field.c:1225
+#: field.c:1270
msgid "null string for `FS' is a gawk extension"
msgstr "null string untuk `FS' adalah sebuah ekstensi gawk"
-#: field.c:1229
+#: field.c:1274
msgid "old awk does not support regexps as value of `FS'"
msgstr "awk lama tidak mendukung regexps sebagai nilai dari `FS'"
-#: field.c:1348
-#, fuzzy
+#: field.c:1393
msgid "`FPAT' is a gawk extension"
-msgstr "`%s' adalah sebuah ekstensi gawk"
+msgstr "`FPAT' adalah sebuah ekstensi gawk"
+
+#: gawkapi.c:146
+msgid "awk_value_to_node: received null retval"
+msgstr "awk_value_to_node: received null retval"
+
+#: gawkapi.c:384
+msgid "node_to_awk_value: received null node"
+msgstr "node_to_awk_value: received null node"
+
+#: gawkapi.c:387
+msgid "node_to_awk_value: received null val"
+msgstr "node_to_awk_value: received null val"
+
+#: gawkapi.c:808
+msgid "remove_element: received null array"
+msgstr "remove_element: received null array"
+
+#: gawkapi.c:811
+msgid "remove_element: received null subscript"
+msgstr "remove_element: received null subscript"
+
+#: gawkapi.c:948
+#, c-format
+msgid "api_flatten_array: could not convert index %d\n"
+msgstr "api_flatten_array: could not convert index %d\n"
+
+#: gawkapi.c:953
+#, c-format
+msgid "api_flatten_array: could not convert value %d\n"
+msgstr "api_flatten_array: could not convert value %d\n"
-#: getopt.c:574 getopt.c:590
+#: getopt.c:604 getopt.c:633
#, c-format
-msgid "%s: option '%s' is ambiguous\n"
-msgstr "%s: pilihan '%s' adalah ambigu\n"
+msgid "%s: option '%s' is ambiguous; possibilities:"
+msgstr "%s: pilihan '%s' adalah ambigu"
-#: getopt.c:623 getopt.c:627
+#: getopt.c:679 getopt.c:683
#, c-format
msgid "%s: option '--%s' doesn't allow an argument\n"
msgstr "%s: pilihan '--%s' tidak mengijinkan sebuah argumen\n"
-#: getopt.c:636 getopt.c:641
+#: getopt.c:692 getopt.c:697
#, c-format
msgid "%s: option '%c%s' doesn't allow an argument\n"
msgstr "%s: pilihan '%c%s' tidak mengijinkan sebuah argumen\n"
-#: getopt.c:684 getopt.c:703
-#, fuzzy, c-format
+#: getopt.c:740 getopt.c:759
+#, c-format
msgid "%s: option '--%s' requires an argument\n"
-msgstr "%s: pilihan '%s' membutuhkan sebuah argumen\n"
+msgstr "%s: pilihan '--%s' membutuhkan sebuah argumen\n"
-#: getopt.c:741 getopt.c:744
+#: getopt.c:797 getopt.c:800
#, c-format
msgid "%s: unrecognized option '--%s'\n"
msgstr "%s: pilihan tidak dikenal '--%s'\n"
-#: getopt.c:752 getopt.c:755
+#: getopt.c:808 getopt.c:811
#, c-format
msgid "%s: unrecognized option '%c%s'\n"
msgstr "%s: pilihan tidak dikenal '%c%s'\n"
-#: getopt.c:804 getopt.c:807
+#: getopt.c:860 getopt.c:863
#, c-format
msgid "%s: invalid option -- '%c'\n"
msgstr "%s: pilihan tidak valid -- '%c'\n"
-#: getopt.c:857 getopt.c:874 getopt.c:1082 getopt.c:1100
+#: getopt.c:916 getopt.c:933 getopt.c:1143 getopt.c:1161
#, c-format
msgid "%s: option requires an argument -- '%c'\n"
msgstr "%s: pilihan membutuhkan sebuah argumen -- '%c'\n"
-#: getopt.c:930 getopt.c:946
+#: getopt.c:989 getopt.c:1005
#, c-format
msgid "%s: option '-W %s' is ambiguous\n"
msgstr "%s: pilihan '-W %s' adalah ambigu\n"
-#: getopt.c:970 getopt.c:988
+#: getopt.c:1029 getopt.c:1047
#, c-format
msgid "%s: option '-W %s' doesn't allow an argument\n"
msgstr "%s: pilihan '-W %s' tidak mengijinkan sebuah argumen\n"
-#: getopt.c:1009 getopt.c:1027
-#, fuzzy, c-format
+#: getopt.c:1068 getopt.c:1086
+#, c-format
msgid "%s: option '-W %s' requires an argument\n"
-msgstr "%s: pilihan '%s' membutuhkan sebuah argumen\n"
+msgstr "%s: pilihan '-w %s' membutuhkan sebuah argumen\n"
-#: io.c:282
+#: io.c:392
#, c-format
msgid "command line argument `%s' is a directory: skipped"
-msgstr ""
+msgstr "command line argument `%s' is a directory: skipped"
-#: io.c:285 io.c:382
+#: io.c:395 io.c:513
#, c-format
msgid "cannot open file `%s' for reading (%s)"
msgstr "tidak dapat membuka berkas `%s' untuk membaca (%s)"
-#: io.c:429
-#, c-format
-msgid "error reading input file `%s': %s"
-msgstr "error membaca berkas masukan `%s': %s"
-
-#: io.c:498
+#: io.c:640
#, c-format
msgid "close of fd %d (`%s') failed (%s)"
msgstr "penutupan dari fd %d (`%s') gagal (%s)"
-#: io.c:575
+#: io.c:716
msgid "redirection not allowed in sandbox mode"
-msgstr ""
+msgstr "redirection not allowed in sandbox mode"
-#: io.c:609
+#: io.c:750
#, c-format
msgid "expression in `%s' redirection only has numeric value"
msgstr "ekspresi dalam `%s' redireksi hanya memiliki nilai numerik"
-#: io.c:615
+#: io.c:756
#, c-format
msgid "expression for `%s' redirection has null string value"
msgstr "ekspresi untuk `%s' redireksi hanya memiliki nilai string null"
-#: io.c:621
+#: io.c:761
#, c-format
msgid "filename `%s' for `%s' redirection may be result of logical expression"
-msgstr ""
-"nama berkas `%s' untuk `%s' redireksi hanya menghasilkan ekspresi logikal"
+msgstr "nama berkas `%s' untuk `%s' redireksi hanya menghasilkan ekspresi logikal"
-#: io.c:664
+#: io.c:809
#, c-format
msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
msgstr "pencampuran tidak perlu dari `>' dan `>>' untuk berkas `%.*s'"
-#: io.c:717
+#: io.c:863
#, c-format
msgid "can't open pipe `%s' for output (%s)"
msgstr "tidak dapat membuka pipe `%s' untuk keluaran (%s)"
-#: io.c:727
+#: io.c:873
#, c-format
msgid "can't open pipe `%s' for input (%s)"
msgstr "tidak dapat membuka pipe `%s' untuk masukan (%s)"
-#: io.c:749
+#: io.c:904
#, c-format
msgid "can't open two way pipe `%s' for input/output (%s)"
msgstr "tidak dapat membuka pipe dua arah `%s' untuk input/output (%s)"
-#: io.c:831
+#: io.c:986
#, c-format
msgid "can't redirect from `%s' (%s)"
msgstr "tidak dapat redirek dari `%s' (%s)"
-#: io.c:834
+#: io.c:989
#, c-format
msgid "can't redirect to `%s' (%s)"
msgstr "tidak dapat redirek ke `%s' (%s)"
-#: io.c:883
-msgid ""
-"reached system limit for open files: starting to multiplex file descriptors"
-msgstr ""
-"batas sistem tercapi untuk berkas terbuka: mulai untuk multiplex berkas "
-"deskripsi"
+#: io.c:1040
+msgid "reached system limit for open files: starting to multiplex file descriptors"
+msgstr "batas sistem tercapi untuk berkas terbuka: mulai untuk multiplex berkas deskripsi"
-#: io.c:899
+#: io.c:1056
#, c-format
msgid "close of `%s' failed (%s)."
msgstr "penutupan dari `%s' gagal (%s)."
-#: io.c:907
+#: io.c:1064
msgid "too many pipes or input files open"
msgstr "terlalu banyak pipes atau berkas masukan terbuka"
-#: io.c:929
+#: io.c:1086
msgid "close: second argument must be `to' or `from'"
msgstr "close: argumen kedua harus berupa `to' atau `from'"
-#: io.c:946
+#: io.c:1103
#, c-format
msgid "close: `%.*s' is not an open file, pipe or co-process"
msgstr "close: `%.*s' bukan sebuah berkas terbuka, pipe atau co-proses"
-#: io.c:951
+#: io.c:1108
msgid "close of redirection that was never opened"
msgstr "penutupan dari redireksi yang tidak pernah terbuka"
-#: io.c:1048
+#: io.c:1205
#, c-format
msgid "close: redirection `%s' not opened with `|&', second argument ignored"
-msgstr ""
-"close: redireksi `%s' tidak dibuka dengan `|&', argumen kedua diabaikan"
+msgstr "close: redireksi `%s' tidak dibuka dengan `|&', argumen kedua diabaikan"
-#: io.c:1064
+#: io.c:1222
#, c-format
msgid "failure status (%d) on pipe close of `%s' (%s)"
msgstr "status gagal (%d) di tutup pipe dari `%s' (%s)"
-#: io.c:1067
+#: io.c:1225
#, c-format
msgid "failure status (%d) on file close of `%s' (%s)"
msgstr "status gagal (%d) di tutup berkas dari `%s' (%s)"
-#: io.c:1087
+#: io.c:1245
#, c-format
msgid "no explicit close of socket `%s' provided"
msgstr "tidak ada eksplisit tutup dari socket `%s' yang disediakan"
-#: io.c:1090
+#: io.c:1248
#, c-format
msgid "no explicit close of co-process `%s' provided"
msgstr "tidak ada eksplisit tutup dari co-proses `%s' yang disediakan"
-#: io.c:1093
+#: io.c:1251
#, c-format
msgid "no explicit close of pipe `%s' provided"
msgstr "tidak ada eksplisit tutup dari pipe `%s' disediakan"
-#: io.c:1096
+#: io.c:1254
#, c-format
msgid "no explicit close of file `%s' provided"
msgstr "tidak ada eksplisit close dari berkas `%s' disediakan"
-#: io.c:1124 io.c:1179 main.c:809 main.c:851
+#: io.c:1284 io.c:1342 main.c:864 main.c:906
#, c-format
msgid "error writing standard output (%s)"
msgstr "error menulis standar keluaran (%s)"
-#: io.c:1128 io.c:1184
+#: io.c:1289 io.c:1348 main.c:866
#, c-format
msgid "error writing standard error (%s)"
msgstr "error menulis standar error (%s)"
-#: io.c:1136
+#: io.c:1297
#, c-format
msgid "pipe flush of `%s' failed (%s)."
msgstr "pipe flush dari `%s' gagal (%s)."
-#: io.c:1139
+#: io.c:1300
#, c-format
msgid "co-process flush of pipe to `%s' failed (%s)."
msgstr "co-proses flush dari pipe ke `%s' gagal (%s)."
-#: io.c:1142
+#: io.c:1303
#, c-format
msgid "file flush of `%s' failed (%s)."
msgstr "file flush dari `%s' gagal (%s)."
-#: io.c:1257
+#: io.c:1420
#, c-format
msgid "local port %s invalid in `/inet'"
msgstr "lokal port %s tidak valid dalam `/inet'"
-#: io.c:1274
+#: io.c:1438
#, c-format
msgid "remote host and port information (%s, %s) invalid"
msgstr "remote host dan informasi port (%s, %s) tidak valid"
-#: io.c:1426
+#: io.c:1590
#, c-format
msgid "no (known) protocol supplied in special filename `%s'"
-msgstr ""
-"tidak (diketahui) protokol yang diberikan dalam nama berkas spesial `%s'"
+msgstr "tidak (diketahui) protokol yang diberikan dalam nama berkas spesial `%s'"
-#: io.c:1440
+#: io.c:1604
#, c-format
msgid "special file name `%s' is incomplete"
msgstr "nama berkas spesial `%s' tidak lengkap"
-#: io.c:1457
+#: io.c:1621
msgid "must supply a remote hostname to `/inet'"
msgstr "harus memberikan sebuah remote hostname ke `/inet'"
-#: io.c:1475
+#: io.c:1639
msgid "must supply a remote port to `/inet'"
msgstr "harus memberikan sebuah remote port ke `/inet'"
-#: io.c:1521
+#: io.c:1685
msgid "TCP/IP communications are not supported"
msgstr "komunikasi TCP/IP tidak didukung"
-#: io.c:1688
+#: io.c:1867
#, c-format
msgid "could not open `%s', mode `%s'"
msgstr "tidak dapat membuka `%s', mode `%s'"
-#: io.c:1739
+#: io.c:1917
#, c-format
msgid "close of master pty failed (%s)"
msgstr "penutupan dari master pty gagal (%s)"
-#: io.c:1741 io.c:1909 io.c:2066
+#: io.c:1919 io.c:2105 io.c:2305
#, c-format
msgid "close of stdout in child failed (%s)"
msgstr "penutupan dari stdout dalam child gagal (%s)"
-#: io.c:1744
+#: io.c:1922
#, c-format
msgid "moving slave pty to stdout in child failed (dup: %s)"
msgstr "memindahkan slave pty ke stdout dalam child gagal (dup: %s)"
-#: io.c:1746 io.c:1914
+#: io.c:1924 io.c:2110
#, c-format
msgid "close of stdin in child failed (%s)"
msgstr "penutupan dari stdin dalam anak gagal (%s)"
-#: io.c:1749
+#: io.c:1927
#, c-format
msgid "moving slave pty to stdin in child failed (dup: %s)"
msgstr "memindahkan slave pty ke stdin dalam anak gagal (dup: %s)"
-#: io.c:1751 io.c:1772
+#: io.c:1929 io.c:1951
#, c-format
msgid "close of slave pty failed (%s)"
msgstr "penutupan dari pty budak gagal (%s)"
-#: io.c:1850 io.c:1912 io.c:2044 io.c:2069
+#: io.c:2040 io.c:2108 io.c:2276 io.c:2308
#, c-format
msgid "moving pipe to stdout in child failed (dup: %s)"
msgstr "memindahkan pipe ke stdout dalam anak gaal (dup: %s)"
-#: io.c:1857 io.c:1917
+#: io.c:2047 io.c:2113
#, c-format
msgid "moving pipe to stdin in child failed (dup: %s)"
msgstr "memindahkan pipe ke stdin dalam anak gagal (dup: %s)"
-#: io.c:1877 io.c:2059
+#: io.c:2073 io.c:2298
msgid "restoring stdout in parent process failed\n"
msgstr "mengembalikan stdout dalam proses orang tua gagal\n"
-#: io.c:1885
+#: io.c:2081
msgid "restoring stdin in parent process failed\n"
msgstr "mengembalikan stdin dalam proses orang tua gagal\n"
-#: io.c:1920 io.c:2071 io.c:2085
+#: io.c:2116 io.c:2310 io.c:2324
#, c-format
msgid "close of pipe failed (%s)"
msgstr "penutupan dari pipe gagal (%s)"
-#: io.c:1965
+#: io.c:2174
msgid "`|&' not supported"
msgstr "`|&' tidak didukung"
-#: io.c:2031
+#: io.c:2261
#, c-format
msgid "cannot open pipe `%s' (%s)"
msgstr "tidak dapat membuka pipe `%s' (%s)"
-#: io.c:2079
+#: io.c:2318
#, c-format
msgid "cannot create child process for `%s' (fork: %s)"
msgstr "tidak dapat membuat proses anak untuk `%s' (fork: %s)"
-#: io.c:2569
+#: io.c:2790
+msgid "register_input_parser: received NULL pointer"
+msgstr "register_input_parser: received NULL pointer"
+
+#: io.c:2818
+#, c-format
+msgid "input parser `%s' conflicts with previously installed input parser `%s'"
+msgstr "input parser `%s' conflicts with previously installed input parser `%s'"
+
+#: io.c:2825
+#, c-format
+msgid "input parser `%s' failed to open `%s'"
+msgstr "input parser `%s' failed to open `%s'"
+
+#: io.c:2845
+msgid "register_output_wrapper: received NULL pointer"
+msgstr "register_output_wrapper: received NULL pointer"
+
+#: io.c:2873
+#, c-format
+msgid "output wrapper `%s' conflicts with previously installed output wrapper `%s'"
+msgstr "output wrapper `%s' conflicts with previously installed output wrapper `%s'"
+
+#: io.c:2880
+#, c-format
+msgid "output wrapper `%s' failed to open `%s'"
+msgstr "output wrapper `%s' failed to open `%s'"
+
+#: io.c:2901
+msgid "register_output_processor: received NULL pointer"
+msgstr "register_output_processor: received NULL pointer"
+
+#: io.c:2930
+#, c-format
+msgid "two-way processor `%s' conflicts with previously installed two-way processor `%s'"
+msgstr "two-way processor `%s' conflicts with previously installed two-way processor `%s'"
+
+#: io.c:2939
+#, c-format
+msgid "two way processor `%s' failed to open `%s'"
+msgstr "two way processor `%s' failed to open `%s'"
+
+#: io.c:3064
#, c-format
msgid "data file `%s' is empty"
msgstr "berkas data `%s' kosong"
-#: io.c:2610 io.c:2618
+#: io.c:3106 io.c:3114
msgid "could not allocate more input memory"
msgstr "tidak dapat mengalokasikan lebih dari masukan memori"
-#: io.c:3171
+#: io.c:3682
msgid "multicharacter value of `RS' is a gawk extension"
msgstr "nilai multi karakter dari `RS' adalah sebuah ekstensi gawk"
-#: io.c:3276
-#, fuzzy
+#: io.c:3771
msgid "IPv6 communication is not supported"
-msgstr "komunikasi TCP/IP tidak didukung"
-
-#: main.c:307
-msgid "out of memory"
-msgstr "kehabisan memori"
+msgstr "IPv6 komunikasi TCP/IP tidak didukung"
-#: main.c:384
-msgid "`-m[fr]' option irrelevant in gawk"
-msgstr "pilihan `-m[fr]' tidak relevan dalam gawk"
-
-#: main.c:386
-msgid "-m option usage: `-m[fr] nnn'"
-msgstr "penggunaan pilihan -m: `-m[fr] nnn'"
-
-#: main.c:409
-#, fuzzy
+#: main.c:405
msgid "empty argument to `-e/--source' ignored"
-msgstr "argumen kosong ke `--source' diabaikan"
+msgstr "argumen kosong ke `-e/--source' diabaikan"
-#: main.c:475
+#: main.c:495
#, c-format
msgid "%s: option `-W %s' unrecognized, ignored\n"
msgstr "%s: pilihan `-W %s' tidak dikenal, diabaikan\n"
-#: main.c:528
+#: main.c:541
#, c-format
msgid "%s: option requires an argument -- %c\n"
msgstr "%s: pilihan membutuhkan sebuah argumen -- %c\n"
-#: main.c:549
+#: main.c:562
msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
msgstr "variabel lingkungan `POSIXLY_CORRECT' set: mengaktifkan `--posix'"
-#: main.c:555
+#: main.c:568
msgid "`--posix' overrides `--traditional'"
msgstr "`--posix' overrides `--traditional'"
-#: main.c:566
+#: main.c:579
msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
msgstr "`--posix'/`--traditional' overrides `--non-decimal-data'"
-#: main.c:570
+#: main.c:583
#, c-format
msgid "running %s setuid root may be a security problem"
msgstr "menjalankan %s setuid root mungkin sebuah masalah keamanan"
-#: main.c:575
-#, fuzzy
-msgid "`--posix' overrides `--binary'"
-msgstr "`--posix' overrides `--traditional'"
+#: main.c:588
+msgid "`--posix' overrides `--characters-as-bytes'"
+msgstr "`--posix' overrides `--characters-as-bytes'"
-#: main.c:626
+#: main.c:647
#, c-format
msgid "can't set binary mode on stdin (%s)"
msgstr "tidak dapat menset mode binari di stdin (%s)"
-#: main.c:629
+#: main.c:650
#, c-format
msgid "can't set binary mode on stdout (%s)"
msgstr "tidak dapat menset mode binari di stdout (%s)"
-#: main.c:631
+#: main.c:652
#, c-format
msgid "can't set binary mode on stderr (%s)"
msgstr "tidak dapat menset mode binari di stderr (%s)"
-#: main.c:670
+#: main.c:710
msgid "no program text at all!"
msgstr "tidak ada teks aplikasi apapun!"
-#: main.c:749
+#: main.c:799
#, c-format
msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
-msgstr ""
-"Penggunaan: %s [pilihan POSIX atau gaya GNU] -f progfile [--] berkas ...\n"
+msgstr "Penggunaan: %s [pilihan POSIX atau gaya GNU] -f progfile [--] berkas ...\n"
-#: main.c:751
+#: main.c:801
#, c-format
msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
-msgstr ""
-"Penggunaan: %s[ pilihan POSIX atau gaya GNU] [--] %cprogram%c berkas ...\n"
+msgstr "Penggunaan: %s[ pilihan POSIX atau gaya GNU] [--] %cprogram%c berkas ...\n"
-#: main.c:756
-#, fuzzy
+#: main.c:806
msgid "POSIX options:\t\tGNU long options: (standard)\n"
msgstr "pilihan POSIX:\t\tpilihan panjang GNU:\n"
-#: main.c:757
+#: main.c:807
msgid "\t-f progfile\t\t--file=progfile\n"
msgstr "\t-f progfile\t\t--file=progfile\n"
-#: main.c:758
+#: main.c:808
msgid "\t-F fs\t\t\t--field-separator=fs\n"
msgstr "\t-F fs\t\t\t--field-separator=fs\n"
-#: main.c:759
+#: main.c:809
msgid "\t-v var=val\t\t--assign=var=val\n"
msgstr "\t-v var=val\t\t--assign=var=val\n"
-#: main.c:760
-#, fuzzy
+#: main.c:810
msgid "Short options:\t\tGNU long options: (extensions)\n"
msgstr "pilihan POSIX:\t\tpilihan panjang GNU:\n"
-#: main.c:761
+#: main.c:811
msgid "\t-b\t\t\t--characters-as-bytes\n"
-msgstr ""
+msgstr "\t-b\t\t\t--characters-as-bytes\n"
-#: main.c:762
-#, fuzzy
+#: main.c:812
msgid "\t-c\t\t\t--traditional\n"
-msgstr "\t-W tradisional\t\t--traditional\n"
+msgstr "\t-c\t\t\t--traditional\n"
-#: main.c:763
-#, fuzzy
+#: main.c:813
msgid "\t-C\t\t\t--copyright\n"
-msgstr "\t-W hak cipta\t\t--copyright\n"
+msgstr "\t-C hak cipta\t\t--copyright\n"
-#: main.c:764
-#, fuzzy
-msgid "\t-d [file]\t\t--dump-variables[=file]\n"
-msgstr "\t-W tampilkan variabel[=berkas]\t--dump-variables[=berkas]\n"
+#: main.c:814
+msgid "\t-d[file]\t\t--dump-variables[=file]\n"
+msgstr "\t-d tampilkan variabel[=berkas]\t\t--dump-variables[=berkas]\n"
-#: main.c:765
-#, fuzzy
+#: main.c:815
+msgid "\t-D[file]\t\t--debug[=file]\n"
+msgstr "\t-D profile[=file]\t\t--profile[=file]\n"
+
+#: main.c:816
msgid "\t-e 'program-text'\t--source='program-text'\n"
-msgstr "\t-W sumber=teks-program\t--source=teks-program\n"
+msgstr "\t-e sumber=teks-program\t\t--source=teks-program\n"
-#: main.c:766
-#, fuzzy
+#: main.c:817
msgid "\t-E file\t\t\t--exec=file\n"
-msgstr "\t-W exec=berkas\t\t--exec=berkas\n"
+msgstr "\t-E exec=berkas\t\t\t--exec=berkas\n"
-#: main.c:767
-#, fuzzy
+#: main.c:818
msgid "\t-g\t\t\t--gen-pot\n"
-msgstr "\t-W gen-po\t\t--gen-po\n"
+msgstr "\t-g gen-po\t\t\t--gen-po\n"
-#: main.c:768
-#, fuzzy
+#: main.c:819
msgid "\t-h\t\t\t--help\n"
-msgstr "\t-W bantuan\t\t\t--help\n"
+msgstr "\t-h bantuan\t\t\t--help\n"
+
+#: main.c:820
+msgid "\t-i includefile\t\t--include=includefile\n"
+msgstr "\t-i includefile\t\t--include=includefile\n"
+
+#: main.c:821
+msgid "\t-l library\t\t--load=library\n"
+msgstr "\t-I library\t\t--load=library\n"
-#: main.c:769
-#, fuzzy
+#: main.c:822
msgid "\t-L [fatal]\t\t--lint[=fatal]\n"
-msgstr "\t-W lint[=fatal]\t\t--lint[=fatal]\n"
+msgstr "\t-L lint[=fatal]\t\t--lint[=fatal]\n"
-#: main.c:770
-#, fuzzy
+#: main.c:823
msgid "\t-n\t\t\t--non-decimal-data\n"
-msgstr "\t-W non-decimal-data\t--non-decimal-data\n"
+msgstr "\t-n non-decimal-data\t\t\t--non-decimal-data\n"
+
+#: main.c:824
+msgid "\t-M\t\t\t--bignum\n"
+msgstr "\t-M\t\t\t--optimize\n"
-#: main.c:771
-#, fuzzy
+#: main.c:825
msgid "\t-N\t\t\t--use-lc-numeric\n"
-msgstr "\t-W use-lc-numeric\t--use-lc-numeric\n"
+msgstr "\t-N use-lc-numeric\t\t\t--use-lc-numeric\n"
-#: main.c:772
+#: main.c:826
+msgid "\t-o[file]\t\t--pretty-print[=file]\n"
+msgstr "\t-W profile[=file]\t\t--profile[=file]\n"
+
+#: main.c:827
msgid "\t-O\t\t\t--optimize\n"
msgstr "\t-0\t\t\t--optimize\n"
-#: main.c:773
-#, fuzzy
-msgid "\t-p [file]\t\t--profile[=file]\n"
-msgstr "\t-W profile[=file]\t--profile[=file]\n"
+#: main.c:828
+msgid "\t-p[file]\t\t--profile[=file]\n"
+msgstr "\t-p profile[=file]\t\t--profile[=file]\n"
-#: main.c:774
-#, fuzzy
+#: main.c:829
msgid "\t-P\t\t\t--posix\n"
-msgstr "\t-W posix\t\t--posix\n"
+msgstr "\t-P posix\t\t\t--posix\n"
-#: main.c:775
-#, fuzzy
+#: main.c:830
msgid "\t-r\t\t\t--re-interval\n"
-msgstr "\t-W re-interval\t\t--re-interval\n"
+msgstr "\t-r re-interval\t\t\t--re-interval\n"
-#: main.c:777
-#, fuzzy
-msgid "\t-R file\t\t\t--command=file\n"
-msgstr "\t-W exec=berkas\t\t--exec=berkas\n"
-
-#: main.c:778
+#: main.c:831
msgid "\t-S\t\t\t--sandbox\n"
-msgstr ""
+msgstr "\t-S\t\t\t--sandbox\n"
-#: main.c:779
-#, fuzzy
+#: main.c:832
msgid "\t-t\t\t\t--lint-old\n"
-msgstr "\t-W lint-old\t\t--lint-old\n"
+msgstr "\t-t lint-old\t\t\t--lint-old\n"
-#: main.c:780
-#, fuzzy
+#: main.c:833
msgid "\t-V\t\t\t--version\n"
-msgstr "\t-W versi\t\t--version\n"
+msgstr "\t-V versi\t\t\t--version\n"
-#: main.c:782
+#: main.c:835
msgid "\t-W nostalgia\t\t--nostalgia\n"
msgstr "\t-W nostalgia\t\t--nostalgia\n"
-#: main.c:785
-#, fuzzy
+#: main.c:838
msgid "\t-Y\t\t--parsedebug\n"
-msgstr "\t-W parsedebug\t\t--parsedebug\n"
+msgstr "\t-Y parsedebug\t\t--parsedebug\n"
#. TRANSLATORS: --help output 5 (end)
#. TRANSLATORS: the placeholder indicates the bug-reporting address
#. for this application. Please add _another line_ with the
#. address for translation bugs.
#. no-wrap
-#: main.c:794
+#: main.c:847
msgid ""
"\n"
"To report bugs, see node `Bugs' in `gawk.info', which is\n"
@@ -1719,7 +3014,7 @@ msgstr ""
"daerah `Reporting Problems and Bugs' dalam versi tercetak.\n"
"\n"
-#: main.c:798
+#: main.c:851
msgid ""
"gawk is a pattern scanning and processing language.\n"
"By default it reads standard input and writes standard output.\n"
@@ -1729,7 +3024,7 @@ msgstr ""
"Secara baku ini membaca standar masukan dan menulis standa keluaran.\n"
"\n"
-#: main.c:802
+#: main.c:855
msgid ""
"Examples:\n"
"\tgawk '{ sum += $1 }; END { print sum }' file\n"
@@ -1739,7 +3034,7 @@ msgstr ""
"\tgawk '{ sum += $1 }; END { print sum }' berkas\n"
"\tgawk -F: '{ print $1 }' /etc/passwd\n"
-#: main.c:822
+#: main.c:880
#, c-format
msgid ""
"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
@@ -1752,15 +3047,13 @@ msgid ""
msgstr ""
"Hak Cipta (C) 1989, 1991-%d Free Software Foundationn.\n"
"\n"
-"Aplikasi ini adalah aplikasi bebas; anda dapat meredistribusikannya dan/atau "
-"memodifikasinya\n"
-"dibawah ketentuan dari GNU General Public License seperti dipublikasikan "
-"oleh\n"
+"Aplikasi ini adalah aplikasi bebas; anda dapat meredistribusikannya dan/atau memodifikasinya\n"
+"dibawah ketentuan dari GNU General Public License seperti dipublikasikan oleh\n"
"Free Software Foundation; baik versi 3 dari Lisensi, atau\n"
"(di pilihan anda) untuk versi selanjutnya.\n"
"\n"
-#: main.c:830
+#: main.c:888
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"
@@ -1769,31 +3062,29 @@ msgid ""
"\n"
msgstr ""
"Aplikasi ini didistribusikan dengan harapan ini akan berguna,\n"
-"tetapi TANPA GARANSI APAPUN; bahkan tanpa garansi yang diimplisikasikan "
-"dari\n"
+"tetapi TANPA GARANSI APAPUN; bahkan tanpa garansi yang diimplisikasikan dari\n"
"PERDAGANGAN atau KESESUAIAN UNTUK SEBUAH TUJUAN TERTENTU. Lihat\n"
"GNU General Public License untuk lebih lengkapnya.\n"
"\n"
-#: main.c:841
+#: main.c:894
msgid ""
"You should have received a copy of the GNU General Public License\n"
"along with this program. If not, see http://www.gnu.org/licenses/.\n"
msgstr ""
"Anda seharusnya menerima salinan dari GNU General Public License\n"
-"bersama dengan aplikasi ini. Jika tidak, lihat http://www.gnu.org/"
-"licenses/.\n"
+"bersama dengan aplikasi ini. Jika tidak, lihat http://www.gnu.org/licenses/.\n"
-#: main.c:876
+#: main.c:931
msgid "-Ft does not set FS to tab in POSIX awk"
msgstr "-Ft tidak menset FS ke tab dalam POSIX awk"
-#: main.c:1110
+#: main.c:1208
#, c-format
msgid "unknown value for field spec: %d\n"
-msgstr ""
+msgstr "unknown value for field spec: %d\n"
-#: main.c:1170
+#: main.c:1306
#, c-format
msgid ""
"%s: `%s' argument to `-v' not in `var=value' form\n"
@@ -1802,119 +3093,168 @@ msgstr ""
"%s: `%s' argumen ke `-v' tidak dalam bentuk `var=value'\n"
"\n"
-#: main.c:1190
+#: main.c:1332
#, c-format
msgid "`%s' is not a legal variable name"
msgstr "`%s' bukan sebuah nama variabel legal"
-#: main.c:1193
+#: main.c:1335
#, c-format
msgid "`%s' is not a variable name, looking for file `%s=%s'"
msgstr "`%s' bukan sebuah nama variabel, pencarian untuk berkas `%s=%s'"
-#: main.c:1246
+#: main.c:1339
+#, c-format
+msgid "cannot use gawk builtin `%s' as variable name"
+msgstr "tidak dapat menggunakan gawk bawaan `%s' sebagai nama fungsi"
+
+#: main.c:1344
+#, c-format
+msgid "cannot use function `%s' as variable name"
+msgstr "tidak dapat menggunakan nama fungsi `%s' sebagai sebuah variabel atau array"
+
+#: main.c:1397
msgid "floating point exception"
msgstr "eksepsi titik pecahan"
-#: main.c:1253
+#: main.c:1404
msgid "fatal error: internal error"
msgstr "fatal error: internal error"
-#: main.c:1268
+#: main.c:1419
msgid "fatal error: internal error: segfault"
msgstr "fatal error: internal error: segfault"
-#: main.c:1280
+#: main.c:1431
msgid "fatal error: internal error: stack overflow"
msgstr "fatal error: internal error: stack overflow"
-#: main.c:1330
+#: main.c:1490
#, c-format
msgid "no pre-opened fd %d"
msgstr "tidak ada pre-opened fd %d"
-#: main.c:1337
+#: main.c:1497
#, c-format
msgid "could not pre-open /dev/null for fd %d"
msgstr "tidak dapat pre-open /dev/null untuk fd %d"
-#: main.c:1360 main.c:1369
+#: mpfr.c:550
#, c-format
-msgid "could not find groups: %s"
-msgstr "tidak dapat menemukan grup: %s"
+msgid "PREC value `%.*s' is invalid"
+msgstr "PREC nilai `%.*s' tidak valid, diperlakukan sebagai 3"
-#: msg.c:63
+#: mpfr.c:608
+#, c-format
+msgid "RNDMODE value `%.*s' is invalid"
+msgstr "RNDMODE nilai `%.*s' tidak valid, diperlakukan sebagai 3"
+
+#: mpfr.c:698
+#, c-format
+msgid "%s: received non-numeric argument"
+msgstr "%s: diterima argumen bukan numerik"
+
+#: mpfr.c:800
+msgid "compl(%Rg): negative value will give strange results"
+msgstr "compl(%Rg): nilai negatif akan memberikan hasil aneh"
+
+#: mpfr.c:804
+msgid "comp(%Rg): fractional value will be truncated"
+msgstr "compl(%Rg): nilai pecahan akan dipotong"
+
+#: mpfr.c:816
+#, c-format
+msgid "cmpl(%Zd): negative values will give strange results"
+msgstr "compl(%Zd): nilai negatif akan memberikan hasil aneh"
+
+#: mpfr.c:835
+#, c-format
+msgid "%s: received non-numeric argument #%d"
+msgstr "%s: diterima argumen bukan numerik #%d"
+
+#: mpfr.c:845
+msgid "%s: argument #%d has invalid value %Rg, using 0"
+msgstr "%s: argument #%d has invalid value %Rg, using 0"
+
+#: mpfr.c:857
+msgid "%s: argument #%d negative value %Rg will give strange results"
+msgstr "%s: #%d nilai negatif %Rg akan memberikan hasil aneh"
+
+#: mpfr.c:863
+msgid "%s: argument #%d fractional value %Rg will be truncated"
+msgstr "%s: #%d nilai pecahan %Rg akan dipotong"
+
+#: mpfr.c:878
+#, c-format
+msgid "%s: argument #%d negative value %Zd will give strange results"
+msgstr "%s: #%d nilai negatif %Zd akan memberikan hasil aneh"
+
+#: msg.c:68
#, c-format
msgid "cmd. line:"
msgstr "cmd. baris:"
-#: msg.c:107
-msgid "error: "
-msgstr "error: "
-
-#: node.c:401
+#: node.c:421
msgid "backslash at end of string"
msgstr "backslash di akhir dari string"
-#: node.c:502
+#: node.c:500
#, c-format
msgid "old awk does not support the `\\%c' escape sequence"
msgstr "awk lama tidak mendukung escape sequence `\\%c'"
-#: node.c:553
+#: node.c:551
msgid "POSIX does not allow `\\x' escapes"
msgstr "POSIX tidak mengijinkan escapes `\\x'"
-#: node.c:559
+#: node.c:557
msgid "no hex digits in `\\x' escape sequence"
msgstr "tidak ada digit heksa dalam escape sequence `\\x'"
-#: node.c:581
+#: node.c:579
#, c-format
-msgid ""
-"hex escape \\x%.*s of %d characters probably not interpreted the way you "
-"expect"
-msgstr ""
-"hex escape \\x%.*s dari karakter %d mungkin tidak dapat diinterpretrasikan "
-"seperti yang anda kira"
+msgid "hex escape \\x%.*s of %d characters probably not interpreted the way you expect"
+msgstr "hex escape \\x%.*s dari karakter %d mungkin tidak dapat diinterpretrasikan seperti yang anda kira"
-#: node.c:596
+#: node.c:594
#, c-format
msgid "escape sequence `\\%c' treated as plain `%c'"
msgstr "escape sequence `\\%c' diperlakukan sebagai plain `%c'"
-#: node.c:735
-msgid ""
-"Invalid multibyte data detected. There may be a mismatch between your data "
-"and your locale."
-msgstr ""
+#: node.c:739
+msgid "Invalid multibyte data detected. There may be a mismatch between your data and your locale."
+msgstr "Invalid multibyte data detected. There may be a mismatch between your data and your locale."
-#: posix/gawkmisc.c:175
-#, fuzzy, c-format
+#: posix/gawkmisc.c:177
+#, c-format
msgid "%s %s `%s': could not get fd flags: (fcntl F_GETFD: %s)"
msgstr "%s %s `%s': tidak dapat menset close-on-exec: (fcntl: %s)"
-#: posix/gawkmisc.c:187
-#, fuzzy, c-format
+#: posix/gawkmisc.c:189
+#, c-format
msgid "%s %s `%s': could not set close-on-exec: (fcntl F_SETFD: %s)"
msgstr "%s %s `%s': tidak dapat menset close-on-exec: (fcntl: %s)"
-#: profile.c:83
+#: profile.c:71
#, c-format
msgid "could not open `%s' for writing: %s"
msgstr "tidak dapat membuka `%s' untuk penulisan: %s"
-#: profile.c:203
-#, fuzzy, c-format
+#: profile.c:73
+msgid "sending profile to standard error"
+msgstr "mengirim profile ke standar error"
+
+#: profile.c:193
+#, c-format
msgid ""
"\t# %s block(s)\n"
"\n"
msgstr ""
-"\t# END blok\n"
+"\t# %s END blok\n"
"\n"
-#: profile.c:208
-#, fuzzy, c-format
+#: profile.c:198
+#, c-format
msgid ""
"\t# Rule(s)\n"
"\n"
@@ -1922,17 +3262,30 @@ msgstr ""
"\t# Aturan\n"
"\n"
-#: profile.c:279
+#: profile.c:272
#, c-format
msgid "internal error: %s with null vname"
msgstr "internal error: %s dengan null vname"
-#: profile.c:938
+#: profile.c:537
+msgid "internal error: builtin with null fname"
+msgstr "internal error: dengan null vname"
+
+#: profile.c:949
+#, c-format
+msgid ""
+"\t# Loaded extensions (-l and/or @load)\n"
+"\n"
+msgstr ""
+"\t# Loaded extensions (-l and/or @load)\n"
+"\n"
+
+#: profile.c:972
#, c-format
msgid "\t# gawk profile, created %s\n"
msgstr "\t# gawk profile, dibuat %s\n"
-#: profile.c:1317
+#: profile.c:1475
#, c-format
msgid ""
"\n"
@@ -1941,271 +3294,256 @@ msgstr ""
"\n"
"\t# Fungsi, terdaftar secara alphabet\n"
-#: profile.c:1356
+#: profile.c:1513
#, c-format
msgid "redir2str: unknown redirection type %d"
-msgstr ""
+msgstr "redir2str: unknown redirection type %d"
-#: re.c:589
-#, c-format
-msgid "range of the form `[%c-%c]' is locale dependant"
-msgstr ""
-
-#: re.c:611
+#: re.c:607
#, c-format
msgid "regexp component `%.*s' should probably be `[%.*s]'"
-msgstr ""
+msgstr "regexp component `%.*s' should probably be `[%.*s]'"
-#: regcomp.c:132
+#: regcomp.c:131
msgid "Success"
msgstr "Sukses"
-#: regcomp.c:135
+#: regcomp.c:134
msgid "No match"
msgstr "Tidak cocok"
-#: regcomp.c:138
+#: regcomp.c:137
msgid "Invalid regular expression"
msgstr "Ekspresi regular tidak valid"
-#: regcomp.c:141
+#: regcomp.c:140
msgid "Invalid collation character"
msgstr "Karakter kolasi tidak valid"
-#: regcomp.c:144
+#: regcomp.c:143
msgid "Invalid character class name"
msgstr "nama kelas karakter tidak valid"
-#: regcomp.c:147
+#: regcomp.c:146
msgid "Trailing backslash"
msgstr "Akhiran backslash"
-#: regcomp.c:150
+#: regcomp.c:149
msgid "Invalid back reference"
msgstr "Referensi balik tidak valid"
-#: regcomp.c:153
+#: regcomp.c:152
msgid "Unmatched [ or [^"
msgstr "Tidak cocok [ atau [^"
-#: regcomp.c:156
+#: regcomp.c:155
msgid "Unmatched ( or \\("
msgstr "Tidak cocok ( atau \\("
-#: regcomp.c:159
+#: regcomp.c:158
msgid "Unmatched \\{"
msgstr "Tidak cocok \\{"
-#: regcomp.c:162
-msgid "Invalid content of \\{\\}"
-msgstr "Isi dari \\{\\} tidak valid"
-
-#: regcomp.c:165
+#: regcomp.c:164
msgid "Invalid range end"
msgstr "Akhir jangkauan tidak valid"
-#: regcomp.c:168
+#: regcomp.c:167
msgid "Memory exhausted"
msgstr "Kehabisan memori"
-#: regcomp.c:171
+#: regcomp.c:170
msgid "Invalid preceding regular expression"
msgstr "Ekspresi regular yang mengawali tidak valid"
-#: regcomp.c:174
+#: regcomp.c:173
msgid "Premature end of regular expression"
msgstr "Akhir dari ekspresi regular prematur"
-#: regcomp.c:177
-msgid "Regular expression too big"
-msgstr "Ekspresi regular terlalu besar"
-
-#: regcomp.c:180
+#: regcomp.c:179
msgid "Unmatched ) or \\)"
msgstr "Tidak cocok ) atau \\)"
-#: regcomp.c:701
+#: regcomp.c:704
msgid "No previous regular expression"
msgstr "Tidak ada ekspresi regular sebelumnya"
-#~ msgid "statement may have no effect"
-#~ msgstr "pernyataan mungkin tidak memiliki pengaruh"
+#: symbol.c:741
+msgid "can not pop main context"
+msgstr "can not pop main context"
-#~ msgid "attempt to use scalar `%s' as array"
-#~ msgstr "mencoba untuk menggunakan skalar `%s' sebagai sebuah array"
+#~ msgid "attempt to use function `%s' as an array"
+#~ msgstr "mencoba untuk menggunakan fungsi `%s' sebagai sebuah array"
-#, fuzzy
-#~ msgid "attempt to use array `%s' in scalar context"
-#~ msgstr "mencoba menggunakan array `%s' dalam sebuah konteks skalar"
+#~ msgid "reference to uninitialized element `%s[\"%s\"]'"
+#~ msgstr "referensi ke elemen tidak terinisialisasi `%s[\"%s\"]'"
-#~ msgid "`continue' outside a loop is not allowed"
-#~ msgstr "`continue' diluar sebuah loop tidak diijinkan"
+#~ msgid "subscript of array `%s' is null string"
+#~ msgstr "subscript dari array `%s' adalah string null"
-#, fuzzy
-#~ msgid "`break' outside a loop is not allowed"
-#~ msgstr "`break' diluar sebuah loop tidak diijinkan"
+#~ msgid "%s: empty (null)\n"
+#~ msgstr "%s: kosong (null)\n"
-#~ msgid "/inet/raw client not ready yet, sorry"
-#~ msgstr "/inet/raw client belum siap, maaf"
+#~ msgid "%s: empty (zero)\n"
+#~ msgstr "%s: kosong (nol)\n"
-#~ msgid "only root may use `/inet/raw'."
-#~ msgstr "hanya root yang boleh menggunakan `/inet/raw'."
+#~ msgid "%s: table_size = %d, array_size = %d\n"
+#~ msgstr "%s: table_size = %d, array_size = %d\n"
-#~ msgid "/inet/raw server not ready yet, sorry"
-#~ msgstr "/inet/raw server belum siap, maaf"
+#~ msgid "%s: array_ref to %s\n"
+#~ msgstr "%s: array_ref ke %s\n"
-#~ msgid "\t-m[fr] val\n"
-#~ msgstr "\t-m[fr] val\n"
+#~ msgid "statement may have no effect"
+#~ msgstr "pernyataan mungkin tidak memiliki pengaruh"
+
+#~ msgid "`delete array' is a gawk extension"
+#~ msgstr "`delete array' adalah sebuah ekstensi gawk"
#~ msgid "call of `length' without parentheses is deprecated by POSIX"
-#~ msgstr ""
-#~ "panggilan dari `length' tanpa tanda kurung sudah ditinggalkan oleh POSIX"
+#~ msgstr "panggilan dari `length' tanpa tanda kurung sudah ditinggalkan oleh POSIX"
-#, fuzzy
-#~ msgid "reference to uninitialized field `$%s'"
-#~ msgstr "referensi ke field tidak terinisialisasi `$%d'"
+#~ msgid "use of non-array as array"
+#~ msgstr "penggunaan dari bukan array sebagai array"
-#~ msgid "can't convert string to float"
-#~ msgstr "tidak dapat mengubah string ke float"
+#~ msgid "`%s' is a Bell Labs extension"
+#~ msgstr "`%s' adalah sebuah ekstensi Bell Labs"
-#~ msgid "`continue' outside a loop is not portable"
-#~ msgstr "`continue' diluar sebuah loop tidak portabel"
+#~ msgid "length: untyped argument will be forced to scalar"
+#~ msgstr "length: argument tidak terketik akan dipaksa ke skalar"
-#~ msgid "`break' outside a loop is not portable"
-#~ msgstr "`break' diluar sebuah loop adalah tidak portabel"
+#~ msgid "and: received non-numeric first argument"
+#~ msgstr "and: diterima argumen pertama tidak numerik"
-#~ msgid "`nextfile' cannot be called from a BEGIN rule"
-#~ msgstr "`nextfile' tidak dapat dipanggil dari sebuah aturan BEGIN"
+#~ msgid "and: received non-numeric second argument"
+#~ msgstr "and: diterima argumen kedua bukan numerik"
-#~ msgid "`next' cannot be called from a BEGIN rule"
-#~ msgstr "`next' tidak dapat dipanggil dari sebuah aturan BEGIN"
+#~ msgid "or: received non-numeric first argument"
+#~ msgstr "or: diterima argumen pertama bukan numerik"
-#~ msgid "file `%s' is a directory"
-#~ msgstr "berkas `%s' adalah sebuah direktori"
+#~ msgid "or: received non-numeric second argument"
+#~ msgstr "or: diterima argumen kedua bukan numerik"
-#~ msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
-#~ msgstr "lebih baik gunakan `PROCINFO[\"%s\"]' daripada `%s'"
+#~ msgid "or(%lf, %lf): negative values will give strange results"
+#~ msgstr "or(%lf, %lf): nilai negatif akan memberikan hasil aneh"
-#~ msgid "use `PROCINFO[...]' instead of `/dev/user'"
-#~ msgstr "lebih baik gunakan `PROCINFO[...]' daripada `/dev/user'"
+#~ msgid "or(%lf, %lf): fractional values will be truncated"
+#~ msgstr "or(%lf, %lf): nilai pecahan akan dipotong"
-#~ msgid "\t-W compat\t\t--compat\n"
-#~ msgstr "\t-W compabilitas\t\t--compat\n"
+#~ msgid "xor: received non-numeric first argument"
+#~ msgstr "xor: diterima argumen pertama bukan numerik"
-#~ msgid "\t-W copyleft\t\t--copyleft\n"
-#~ msgstr "\t-W copyleft\t\t--copyleft\n"
+#~ msgid "xor: received non-numeric second argument"
+#~ msgstr "xor: diterima argumen kedua bukan numerik"
-#~ msgid "\t-W usage\t\t--usage\n"
-#~ msgstr "\t-W penggunaan\t\t--usage\n"
+#~ msgid "xor(%lf, %lf): fractional values will be truncated"
+#~ msgstr "xor(%lf, %lf): nilai pecahan akan dipotong"
-#~ msgid ""
-#~ "\t# BEGIN block(s)\n"
-#~ "\n"
-#~ msgstr ""
-#~ "\t # BEGIN blok\n"
-#~ "\n"
+#~ msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+#~ msgstr "for loop: array `%s' berubah ukuran dari %ld ke %ld selama eksekusi loop"
-#~ msgid "must use `count$' on all formats or none"
-#~ msgstr "harus menggunakan `count$' di semua format atau tidak sama sekali"
+#~ msgid "`break' outside a loop is not portable"
+#~ msgstr "`break' diluar sebuah loop adalah tidak portabel"
-#~ msgid "field width is ignored for `%%%%' specifier"
-#~ msgstr "lebar daerah diabaikan untuk penspesifikasi `%%%%'"
+#~ msgid "`continue' outside a loop is not portable"
+#~ msgstr "`continue' diluar sebuah loop tidak portabel"
-#~ msgid "precision is ignored for `%%%%' specifier"
-#~ msgstr "ketepatan diabaikan untuk penspesifikasi `%%%%'"
+#~ msgid "`next' cannot be called from a BEGIN rule"
+#~ msgstr "`next' tidak dapat dipanggil dari sebuah aturan BEGIN"
-#~ msgid "field width and precision are ignored for `%%%%' specifier"
-#~ msgstr "lebar daerah dan presisi diabaikan untuk penspesifikasi `%%%%'"
+#~ msgid "`next' cannot be called from an END rule"
+#~ msgstr "`next' tidak dapat dipanggil dari sebuah aturan END"
-#~ msgid "`$' is not permitted in awk formats"
-#~ msgstr "`$' tidak diijinkan dalam format awk"
+#~ msgid "`nextfile' cannot be called from a BEGIN rule"
+#~ msgstr "`nextfile' tidak dapat dipanggil dari sebuah aturan BEGIN"
-#~ msgid "arg count with `$' must be > 0"
-#~ msgstr "arg count dengan `$' harus > 0"
+#~ msgid "`nextfile' cannot be called from an END rule"
+#~ msgstr "`nextfile' tidak dapat dipanggil dari sebuah aturan END"
-#~ msgid "arg count %ld greater than total number of supplied arguments"
-#~ msgstr ""
-#~ "arg count %ld lebih besar dari jumlah total dari argumen yang diberikan"
+#~ msgid "statement has no effect"
+#~ msgstr "pernyataan tidak memiliki efek"
-#~ msgid "`$' not permitted after period in format"
-#~ msgstr "`$' tidak diijinkan setelah periode dalam format"
+#~ msgid "concatenation: side effects in one expression have changed the length of another!"
+#~ msgstr "concatenation: efek samping dalam satu ekspresi telah mengubah panjang dari yang lain!"
-#~ msgid "no `$' supplied for positional field width or precision"
-#~ msgstr ""
-#~ "tidak ada `$' yang diberikan untuk posisional field width atau presisi"
+#~ msgid "assignment used in conditional context"
+#~ msgstr "penempatan digunakan dalam konteks kondisional"
-#~ msgid "`l' is meaningless in awk formats; ignored"
-#~ msgstr "`l' tidak berarti dalam format awk; diabaikan"
+#~ msgid "illegal type (%s) in tree_eval"
+#~ msgstr "tipe (%s) tidak legal dalam tree_eval"
-#~ msgid "`l' is not permitted in POSIX awk formats"
-#~ msgstr "`l' tidak diijinkan dalam format POSIX awk"
+#~ msgid "\t# -- main --\n"
+#~ msgstr "\t# -- main --\n"
-#~ msgid "`L' is meaningless in awk formats; ignored"
-#~ msgstr "`L' tidak berarti dalam format awk; diabaikan"
+#~ msgid "assignment is not allowed to result of builtin function"
+#~ msgstr "penempatan tidak diijinkan untuk menghasilkan fungsi bawaan"
-#~ msgid "`L' is not permitted in POSIX awk formats"
-#~ msgstr "`L' tidak diijinkan dalam format awk POSIX"
+#~ msgid "Operation Not Supported"
+#~ msgstr "Operasi Tidak Didukung"
-#~ msgid "`h' is meaningless in awk formats; ignored"
-#~ msgstr "`h' tidak berarti dalam format awk; diabaikan"
+#~ msgid "invalid tree type %s in redirect()"
+#~ msgstr "tipe tree %s tidak valid dalam redirect()"
-#~ msgid "`h' is not permitted in POSIX awk formats"
-#~ msgstr "`h' tidak diijinkan dalam format awk POSIX"
+#~ msgid "can't open two way socket `%s' for input/output (%s)"
+#~ msgstr "tidak dapat membuka socket dua arah `%s' untuk input/output (%s)"
-#~ msgid "[s]printf: value %g is out of range for `%%%c' format"
-#~ msgstr "[s]printf: nilai %g diluar dari jangkauan untuk format `%%%c'"
+#~ msgid "/inet/raw client not ready yet, sorry"
+#~ msgstr "/inet/raw client belum siap, maaf"
-#~ msgid ""
-#~ "ignoring unknown format specifier character `%c': no argument converted"
-#~ msgstr ""
-#~ "mengabaikan format tidak dikenal karakter penspesifikasi `%c': tidak ada "
-#~ "argumen yang diubah"
+#~ msgid "only root may use `/inet/raw'."
+#~ msgstr "hanya root yang boleh menggunakan `/inet/raw'."
-#~ msgid "not enough arguments to satisfy format string"
-#~ msgstr "tidak cukup argumen untuk memuaskan format string"
+#~ msgid "/inet/raw server not ready yet, sorry"
+#~ msgstr "/inet/raw server belum siap, maaf"
-#~ msgid "^ ran out for this one"
-#~ msgstr "^ kehabisan untuk yang ini"
+#~ msgid "file `%s' is a directory"
+#~ msgstr "berkas `%s' adalah sebuah direktori"
-#~ msgid "[s]printf: format specifier does not have control letter"
-#~ msgstr "[s]printf: penspesifikasi format tidak memiliki pengontrol huruf"
+#~ msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
+#~ msgstr "lebih baik gunakan `PROCINFO[\"%s\"]' daripada `%s'"
-#~ msgid "too many arguments supplied for format string"
-#~ msgstr "terlalu banyak argumen diberikan untuk format string"
+#~ msgid "use `PROCINFO[...]' instead of `/dev/user'"
+#~ msgstr "lebih baik gunakan `PROCINFO[...]' daripada `/dev/user'"
-#, fuzzy
-#~ msgid "attempt to use array parameter `%s' in a scalar context"
-#~ msgstr "mencoba menggunakan array `%s' dalam sebuah konteks skalar"
+#~ msgid "out of memory"
+#~ msgstr "kehabisan memori"
-#~ msgid "can't open two way socket `%s' for input/output (%s)"
-#~ msgstr "tidak dapat membuka socket dua arah `%s' untuk input/output (%s)"
+#~ msgid "`-m[fr]' option irrelevant in gawk"
+#~ msgstr "pilihan `-m[fr]' tidak relevan dalam gawk"
-#~ msgid "length: untyped argument will be forced to scalar"
-#~ msgstr "length: argument tidak terketik akan dipaksa ke skalar"
+#~ msgid "-m option usage: `-m[fr] nnn'"
+#~ msgstr "penggunaan pilihan -m: `-m[fr] nnn'"
-#~ msgid ""
-#~ "concatenation: side effects in one expression have changed the length of "
-#~ "another!"
-#~ msgstr ""
-#~ "concatenation: efek samping dalam satu ekspresi telah mengubah panjang "
-#~ "dari yang lain!"
+#~ msgid "\t-m[fr] val\n"
+#~ msgstr "\t-m[fr] val\n"
-#~ msgid "illegal type (%s) in tree_eval"
-#~ msgstr "tipe (%s) tidak legal dalam tree_eval"
+#~ msgid "\t-W compat\t\t--compat\n"
+#~ msgstr "\t-W compabilitas\t\t--compat\n"
-#~ msgid "\t# -- main --\n"
-#~ msgstr "\t# -- main --\n"
+#~ msgid "\t-W copyleft\t\t--copyleft\n"
+#~ msgstr "\t-W copyleft\t\t--copyleft\n"
-#~ msgid "invalid tree type %s in redirect()"
-#~ msgstr "tipe tree %s tidak valid dalam redirect()"
+#~ msgid "\t-W usage\t\t--usage\n"
+#~ msgstr "\t-W penggunaan\t\t--usage\n"
+
+#~ msgid "could not find groups: %s"
+#~ msgstr "tidak dapat menemukan grup: %s"
+
+#~ msgid "can't convert string to float"
+#~ msgstr "tidak dapat mengubah string ke float"
-#, fuzzy
#~ msgid "# treated internally as `delete'"
-#~ msgstr "# diperlakukan secara internal sebagai 'delete'"
+#~ msgstr "# diperlakukan secara internal sebagai `delete'"
#~ msgid "# this is a dynamically loaded extension function"
#~ msgstr "# ini adalah sebuah fungsi yang secara dinamis diload ekstensi"
+#~ msgid ""
+#~ "\t# BEGIN block(s)\n"
+#~ "\n"
+#~ msgstr ""
+#~ "\t # BEGIN blok\n"
+#~ "\n"
+
#~ msgid "unexpected type %s in prec_level"
#~ msgstr "tipe %s tidak terduga dalam prec_level"
diff --git a/po/it.gmo b/po/it.gmo
index ac3fa30d..73f46395 100644
--- a/po/it.gmo
+++ b/po/it.gmo
Binary files differ
diff --git a/po/it.po b/po/it.po
index a2005288..12305a74 100644
--- a/po/it.po
+++ b/po/it.po
@@ -1,13 +1,13 @@
# Italian messages for GNU Awk
-# Copyright (C) 2002-2011 Free Software Foundation, Inc.
+# Copyright (C) 2002-2014 Free Software Foundation, Inc.
# Antonio Colombo <azc100@gmail.com>.
#
msgid ""
msgstr ""
-"Project-Id-Version: gawk 3.1.81\n"
-"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
-"POT-Creation-Date: 2011-10-24 05:57+0200\n"
-"PO-Revision-Date: 2011-03-19 16:52+0100\n"
+"Project-Id-Version: GNU Awk 4.0.73, API: 0.0\n"
+"Report-Msgid-Bugs-To: bug-gawk@gnu.org\n"
+"POT-Creation-Date: 2014-12-14 21:30+0100\n"
+"PO-Revision-Date: 2014-12-14 22:10+0100\n"
"Last-Translator: Antonio Colombo <azc100@gmail.com>\n"
"Language-Team: Italian <it@li.org>\n"
"Language: it\n"
@@ -15,513 +15,492 @@ msgstr ""
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8-bit\n"
-#: array.c:140
+#: array.c:256
#, c-format
msgid "from %s"
msgstr "da %s"
-#: array.c:248
+#: array.c:357
msgid "attempt to use a scalar value as array"
msgstr "tentativo di usare valore scalare come vettore"
-#: array.c:251
-#, c-format
-msgid "attempt to use function `%s' as an array"
-msgstr "tentativo di usare funzione '%s' come vettore"
-
-#: array.c:254
+#: array.c:359
#, c-format
msgid "attempt to use scalar parameter `%s' as an array"
msgstr "tentativo di usare il parametro scalare `%s' come un vettore"
-#: array.c:257
+#: array.c:362
#, c-format
msgid "attempt to use scalar `%s' as an array"
msgstr "tentativo di usare scalare '%s' come vettore"
-#: array.c:302 array.c:707 builtin.c:84 builtin.c:1384 builtin.c:1426
-#: builtin.c:1439 builtin.c:1856 builtin.c:1868 eval.c:1135 eval.c:1139
-#: eval.c:1495 eval.c:1812
+#: array.c:409 array.c:576 builtin.c:85 builtin.c:1600 builtin.c:1646
+#: builtin.c:1659 builtin.c:2086 builtin.c:2100 eval.c:1150 eval.c:1154
+#: eval.c:1559
#, c-format
msgid "attempt to use array `%s' in a scalar context"
msgstr "tentativo di usare vettore `%s' in un contesto scalare"
-#: array.c:513
-#, c-format
-msgid "reference to uninitialized element `%s[\"%.*s\"]'"
-msgstr "riferimento a elemento non inizializzato `%s[\"%.*s\"]'"
-
-#: array.c:519
-#, c-format
-msgid "subscript of array `%s' is null string"
-msgstr "l'indice del vettore '%s' è una stringa nulla"
-
-#: array.c:723
+#: array.c:583
#, c-format
msgid "delete: index `%s' not in array `%s'"
msgstr "delete: indice `%s' non presente nel vettore `%s'"
-#: array.c:734 eval.c:1865
+#: array.c:597
#, c-format
msgid "attempt to use scalar `%s[\"%.*s\"]' as an array"
msgstr "tentativo di usare scalare`%s[\"%.*s\"]' come vettore"
-#: array.c:910
-#, c-format
-msgid "%s: empty (null)\n"
-msgstr "%s: vuoto (nullo)\n"
-
-#: array.c:915
-#, c-format
-msgid "%s: empty (zero)\n"
-msgstr "%s: vuoto (zero)\n"
-
-#: array.c:919
-#, c-format
-msgid "%s: table_size = %d, array_size = %d\n"
-msgstr "%s: dimensione_tabella = %d, dimensione_vettore = %d\n"
-
-#: array.c:954
-#, c-format
-msgid "%s: is parameter\n"
-msgstr "%s: è parametro\n"
-
-#: array.c:958
-#, c-format
-msgid "%s: array_ref to %s\n"
-msgstr "%s: riferimento_vettoriale a %s\n"
-
-#: array.c:963
-msgid "adump: argument not an array"
-msgstr "adump: l'argomento non è un vettore"
+#: array.c:776
+msgid "adump: first argument not an array"
+msgstr "adump: primo argomento non-vettoriale"
-#: array.c:1086
+#: array.c:815
msgid "asort: second argument not an array"
-msgstr "asort: il secondo argomento non è un vettore"
+msgstr "asort: secondo argomento non-vettoriale"
-#: array.c:1087
+#: array.c:816
msgid "asorti: second argument not an array"
-msgstr "asorti: il secondo argomento non è un vettore"
+msgstr "asorti: secondo argomento non-vettoriale"
-#: array.c:1094
+#: array.c:823
msgid "asort: first argument not an array"
-msgstr "asort: il primo argomento non è un vettore"
+msgstr "asort: primo argomento non-vettoriale"
-#: array.c:1095
+#: array.c:824
msgid "asorti: first argument not an array"
-msgstr "asorti: il primo argomento non è un vettore"
+msgstr "asorti: primo argomento non-vettoriale"
-#: array.c:1102
-#, fuzzy
+#: array.c:831
msgid "asort: cannot use a subarray of first arg for second arg"
msgstr ""
-"patsplit: non si può usare lo stesso vettore come secondo e quarto argomento"
+"asort: non consentito un secondo argomento che sia un sottovettore del primo "
+"argomento"
-#: array.c:1103
-#, fuzzy
+#: array.c:832
msgid "asorti: cannot use a subarray of first arg for second arg"
msgstr ""
-"patsplit: non si può usare lo stesso vettore come secondo e quarto argomento"
+"asorti: non consentito un secondo argomento che sia un sottovettore del "
+"primo argomento"
-#: array.c:1108
-#, fuzzy
+#: array.c:837
msgid "asort: cannot use a subarray of second arg for first arg"
msgstr ""
-"split: non si può usare lo stesso vettore come secondo e quarto argomento"
+"asort: non consentito un primo argomento che sia un sottovettore del secondo "
+"argomento"
-#: array.c:1109
-#, fuzzy
+#: array.c:838
msgid "asorti: cannot use a subarray of second arg for first arg"
msgstr ""
-"split: non si può usare lo stesso vettore come secondo e quarto argomento"
+"asorti: non consentito un primo argomento che sia un sottovettore del "
+"secondo argomento"
-#: array.c:1659
-#, fuzzy, c-format
+#: array.c:1313
+#, c-format
msgid "`%s' is invalid as a function name"
-msgstr "estensione: manca nome di funzione"
+msgstr "`%s' non è un nome funzione valido"
-#: array.c:1663
-#, fuzzy, c-format
+#: array.c:1317
+#, c-format
msgid "sort comparison function `%s' is not defined"
-msgstr "funzione `%s' non definita"
+msgstr "funzione di confronto del sort `%s' non definita"
-#: awkgram.y:249
+#: awkgram.y:241
#, c-format
msgid "%s blocks must have an action part"
-msgstr "blocchi %s richiedono una 'azione'"
+msgstr "blocchi %s richiedono una `azione'"
-#: awkgram.y:252
+#: awkgram.y:244
msgid "each rule must have a pattern or an action part"
-msgstr "ogni regola deve avere una parte 'espressione' o una parte 'azione'"
+msgstr "ogni regola deve avere una parte `espressione' o una parte `azione'"
-#: awkgram.y:323 awkgram.y:334
+#: awkgram.y:354 awkgram.y:368
msgid "old awk does not support multiple `BEGIN' or `END' rules"
msgstr "il vecchio awk non supporta più di una regola `BEGIN' o `END'"
-#: awkgram.y:371
+#: awkgram.y:412
#, c-format
msgid "`%s' is a built-in function, it cannot be redefined"
msgstr "`%s' è una funzione interna, non si può ridefinire"
-#: awkgram.y:432
+#: awkgram.y:474
msgid "regexp constant `//' looks like a C++ comment, but is not"
msgstr "espressione regolare costante `//' sembra un commento C++, ma non lo è"
-#: awkgram.y:436
+#: awkgram.y:478
#, 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:528
+#: awkgram.y:590
#, c-format
msgid "duplicate case values in switch body: %s"
-msgstr "valori di 'case' doppi all'interno di uno 'switch': %s"
+msgstr "valori di `case' doppi all'interno di uno `switch': %s"
-#: awkgram.y:549
+#: awkgram.y:611
msgid "duplicate `default' detected in switch body"
-msgstr "valori di default doppi all'interno di uno 'switch'"
+msgstr "valori di default doppi all'interno di uno `switch'"
-#: awkgram.y:809
+#: awkgram.y:871 awkgram.y:3948
msgid "`break' is not allowed outside a loop or switch"
-msgstr "`break' non permesso fuori da un ciclo o da uno 'switch'"
+msgstr "`break' non consentito fuori da un ciclo o da uno `switch'"
-#: awkgram.y:818
+#: awkgram.y:880 awkgram.y:3940
msgid "`continue' is not allowed outside a loop"
-msgstr "`continue' non permesso fuori da un un ciclo"
+msgstr "`continue' non consentito fuori da un un ciclo"
-#: awkgram.y:828
+#: awkgram.y:890
#, c-format
msgid "`next' used in %s action"
-msgstr "`next' usato in 'azione' %s"
-
-#: awkgram.y:836
-msgid "`nextfile' is a gawk extension"
-msgstr "`nextfile' è un'estensione gawk"
+msgstr "`next' usato in `azione' %s"
-#: awkgram.y:841
+#: awkgram.y:899
#, c-format
msgid "`nextfile' used in %s action"
-msgstr "`nextfile' usato in 'azione' %s"
+msgstr "`nextfile' usato in `azione' %s"
-#: awkgram.y:865
+#: awkgram.y:923
msgid "`return' used outside function context"
msgstr "`return' usato fuori da una funzione"
-#: awkgram.y:925
+#: awkgram.y:997
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:995 awkgram.y:999 awkgram.y:1023
-msgid "`delete array' is a gawk extension"
-msgstr "`delete array' è un'estensione gawk"
+#: awkgram.y:1063 awkgram.y:1112
+msgid "`delete' is not allowed with SYMTAB"
+msgstr "`delete' non consentito in SYMTAB"
+
+#: awkgram.y:1065 awkgram.y:1114
+msgid "`delete' is not allowed with FUNCTAB"
+msgstr "`delete' non consentito in FUNCTAB"
-#: awkgram.y:1019
+#: awkgram.y:1099 awkgram.y:1103
msgid "`delete(array)' is a non-portable tawk extension"
msgstr "`delete(array)' è un'estensione tawk non-portabile"
-#: awkgram.y:1135
+#: awkgram.y:1224
msgid "multistage two-way pipelines don't work"
-msgstr "'pipeline' multistadio bidirezionali non funzionano"
+msgstr "`pipeline' multistadio bidirezionali non funzionano"
-#: awkgram.y:1238
+#: awkgram.y:1339
msgid "regular expression on right of assignment"
msgstr "espressione regolare usata per assegnare un valore"
-#: awkgram.y:1249
+#: awkgram.y:1350
msgid "regular expression on left of `~' or `!~' operator"
msgstr "espressione regolare prima di operatore `~' o `!~'"
-#: awkgram.y:1265 awkgram.y:1419
+#: awkgram.y:1366 awkgram.y:1508
msgid "old awk does not support the keyword `in' except after `for'"
msgstr "il vecchio awk non supporta la parola-chiave `in' se non dopo `for'"
-#: awkgram.y:1275
+#: awkgram.y:1376
msgid "regular expression on right of comparison"
msgstr "espressione regolare a destra in un confronto"
-#: awkgram.y:1394
-#, c-format
-msgid "`getline var' invalid inside `%s' rule"
-msgstr "`getline var' invalida all'interno della regola `%s'"
-
-#: awkgram.y:1397 eval.c:2504
+#: awkgram.y:1488
#, c-format
-msgid "`getline' invalid inside `%s' rule"
-msgstr "`getline' invalida all'interno della regola `%s'"
+msgid "non-redirected `getline' invalid inside `%s' rule"
+msgstr "`getline' non ridiretta invalida all'interno della regola `%s'"
-#: awkgram.y:1402
+#: awkgram.y:1491
msgid "non-redirected `getline' undefined inside END action"
-msgstr "`getline' non re-diretta indefinita dentro 'azione' END"
+msgstr "`getline' non ri-diretta indefinita dentro `azione' END"
-#: awkgram.y:1421
+#: awkgram.y:1510
msgid "old awk does not support multidimensional arrays"
msgstr "il vecchio awk non supporta vettori multidimensionali"
-#: awkgram.y:1517
+#: awkgram.y:1607
msgid "call of `length' without parentheses is not portable"
msgstr "chiamata a `length' senza parentesi non portabile"
-#: awkgram.y:1580
+#: awkgram.y:1673
msgid "indirect function calls are a gawk extension"
msgstr "chiamate a funzione indirette sono un'estensione gawk"
-#: awkgram.y:1593
+#: awkgram.y:1686
#, c-format
msgid "can not use special variable `%s' for indirect function call"
msgstr ""
-"non posso usare la variabile speciale `%s' come parametro indiretto di "
-"funzione "
+"non riesco a usare la variabile speciale `%s' come parametro indiretto di "
+"funzione"
-#: awkgram.y:1671
+#: awkgram.y:1764
msgid "invalid subscript expression"
msgstr "espressione indice invalida"
-#: awkgram.y:1711
-msgid "use of non-array as array"
-msgstr "uso di non-vettore come vettore"
-
-#: awkgram.y:1975 awkgram.y:1995 msg.c:98
+#: awkgram.y:2111 awkgram.y:2131 gawkapi.c:206 gawkapi.c:224 msg.c:126
msgid "warning: "
msgstr "attenzione: "
-#: awkgram.y:1993 msg.c:130
+#: awkgram.y:2129 gawkapi.c:192 gawkapi.c:221 msg.c:158
msgid "fatal: "
msgstr "fatale: "
-#: awkgram.y:2043
+#: awkgram.y:2179
msgid "unexpected newline or end of string"
-msgstr "carattere 'a capo' o fine stringa inaspettati"
+msgstr "carattere 'a capo' o fine stringa non previsti"
-#: awkgram.y:2300 awkgram.y:2358 awkgram.y:2542
+#: awkgram.y:2470 awkgram.y:2546 awkgram.y:2769 debug.c:523 debug.c:539
+#: debug.c:2812 debug.c:5056
#, 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:2301 awkgram.y:2359 builtin.c:122
+#: awkgram.y:2471 awkgram.y:2596
+#, c-format
+msgid "can't open shared library `%s' for reading (%s)"
+msgstr "non riesco ad aprire shared library `%s' in lettura (%s)"
+
+#: awkgram.y:2473 awkgram.y:2547 awkgram.y:2597 builtin.c:135 debug.c:5207
msgid "reason unknown"
msgstr "ragione indeterminata"
-#: awkgram.y:2317
+#: awkgram.y:2482 awkgram.y:2506
+#, c-format
+msgid "can't include `%s' and use it as a program file"
+msgstr "non riesco a includere `%s' per usarlo come file di programma"
+
+#: awkgram.y:2495
#, c-format
msgid "already included source file `%s'"
msgstr "file sorgente `%s' già incluso"
-#: awkgram.y:2343
+#: awkgram.y:2496
+#, c-format
+msgid "already loaded shared library `%s'"
+msgstr "shared library `%s' già inclusa"
+
+#: awkgram.y:2531
msgid "@include is a gawk extension"
msgstr "@include è un'estensione gawk"
-#: awkgram.y:2349
+#: awkgram.y:2537
msgid "empty filename after @include"
msgstr "nome-file mancante dopo @include"
-#: awkgram.y:2494
+#: awkgram.y:2581
+msgid "@load is a gawk extension"
+msgstr "@load è un'estensione gawk"
+
+#: awkgram.y:2587
+msgid "empty filename after @load"
+msgstr "nome-file mancante dopo @include"
+
+#: awkgram.y:2721
msgid "empty program text on command line"
-msgstr "programma nullo sulla linea comandi"
+msgstr "programma nullo sulla riga comandi"
-#: awkgram.y:2609
+#: awkgram.y:2836
#, c-format
msgid "can't read sourcefile `%s' (%s)"
msgstr "non riesco a leggere file sorgente `%s' (%s)"
-#: awkgram.y:2620
+#: awkgram.y:2847
#, c-format
msgid "source file `%s' is empty"
msgstr "file sorgente `%s' vuoto"
-#: awkgram.y:2805
+#: awkgram.y:2906
+#, c-format
+msgid "PEBKAC error: invalid character '\\%03o' in source code"
+msgstr "errore PEBKAC: carattere invalido '\\%03o' nel codice sorgente"
+
+#: awkgram.y:3142
msgid "source file does not end in newline"
msgstr "file sorgente non termina con carattere 'a capo'"
-#: awkgram.y:2882
+#: awkgram.y:3247
msgid "unterminated regexp ends with `\\' at end of file"
msgstr "espressione regolare non completata termina con `\\' a fine file"
-#: awkgram.y:2906
+#: awkgram.y:3271
#, 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:2910
+#: awkgram.y:3275
#, 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:2917
+#: awkgram.y:3282
msgid "unterminated regexp"
msgstr "espressione regolare non completata"
-#: awkgram.y:2921
+#: awkgram.y:3286
msgid "unterminated regexp at end of file"
msgstr "espressione regolare non completata a fine file"
-#: awkgram.y:2980
+#: awkgram.y:3357
msgid "use of `\\ #...' line continuation is not portable"
-msgstr "uso di `\\ #...' continuazione linea non portabile"
+msgstr "uso di `\\ #...' continuazione riga non portabile"
-#: awkgram.y:2996
+#: awkgram.y:3377
msgid "backslash not last character on line"
-msgstr "'\\' non è l'ultimo carattere della linea"
+msgstr "'\\' non è l'ultimo carattere della riga"
-#: awkgram.y:3057
+#: awkgram.y:3438
msgid "POSIX does not allow operator `**='"
msgstr "POSIX non permette l'operatore `**='"
-#: awkgram.y:3059
+#: awkgram.y:3440
msgid "old awk does not support operator `**='"
msgstr "il vecchio awk non supporta l'operatore `**='"
-#: awkgram.y:3068
+#: awkgram.y:3449
msgid "POSIX does not allow operator `**'"
msgstr "POSIX non permette l'operatore `**'"
-#: awkgram.y:3070
+#: awkgram.y:3451
msgid "old awk does not support operator `**'"
msgstr "il vecchio awk non supporta l'operatore `**'"
-#: awkgram.y:3105
+#: awkgram.y:3486
msgid "operator `^=' is not supported in old awk"
msgstr "l'operatore `^=' non è supportato nel vecchio awk"
-#: awkgram.y:3113
+#: awkgram.y:3494
msgid "operator `^' is not supported in old awk"
msgstr "l'operatore `^' non è supportato nel vecchio awk"
-#: awkgram.y:3206 awkgram.y:3222
+#: awkgram.y:3591 awkgram.y:3607 command.y:1180
msgid "unterminated string"
msgstr "stringa non terminata"
-#: awkgram.y:3418
+#: awkgram.y:3828
#, c-format
msgid "invalid char '%c' in expression"
msgstr "carattere '%c' non valido in un'espressione"
-#: awkgram.y:3465
+#: awkgram.y:3875
#, c-format
msgid "`%s' is a gawk extension"
msgstr "`%s' è un'estensione gawk"
-#: awkgram.y:3470
-#, c-format
-msgid "`%s' is a Bell Labs extension"
-msgstr "`%s' è un'estensione Bell Labs"
-
-#: awkgram.y:3475
+#: awkgram.y:3880
#, c-format
msgid "POSIX does not allow `%s'"
msgstr "POSIX non permette `%s'"
-#: awkgram.y:3483
+#: awkgram.y:3888
#, c-format
msgid "`%s' is not supported in old awk"
msgstr "`%s' non è supportato nel vecchio awk"
-#: awkgram.y:3550
+#: awkgram.y:3978
msgid "`goto' considered harmful!\n"
msgstr "`goto' considerato pericoloso!\n"
-#: awkgram.y:3601
+#: awkgram.y:4012
#, c-format
msgid "%d is invalid as number of arguments for %s"
msgstr "%d non valido come numero di argomenti per %s"
-#: awkgram.y:3636
+#: awkgram.y:4047
#, 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"
+msgstr "%s: una stringa come ultimo argomento di `substitute' non ha effetto"
-#: awkgram.y:3641
+#: awkgram.y:4052
#, c-format
msgid "%s third parameter is not a changeable object"
msgstr "il terzo parametro di '%s' non è un oggetto modificabile"
-#: awkgram.y:3714 awkgram.y:3717
+#: awkgram.y:4144 awkgram.y:4147
msgid "match: third argument is a gawk extension"
msgstr "match: il terzo argomento è un'estensione gawk"
-#: awkgram.y:3771 awkgram.y:3774
+#: awkgram.y:4201 awkgram.y:4204
msgid "close: second argument is a gawk extension"
msgstr "close: il secondo argomento è un'estensione gawk"
-#: awkgram.y:3786
+#: awkgram.y:4216
msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
msgstr ""
"uso scorretto di dcgettext(_\"...\"): togliere il carattere '_' iniziale"
-#: awkgram.y:3801
+#: awkgram.y:4231
msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
msgstr ""
"uso scorretto di dcngettext(_\"...\"): togliere il carattere '_' iniziale"
-#: awkgram.y:3893
-#, c-format
-msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
-msgstr "funzione `%s': parametro #%d, `%s', duplica parametro #%d"
+#: awkgram.y:4250
+msgid "index: regexp constant as second argument is not allowed"
+msgstr "index: espressione regolare come secondo argomento non consentita"
-#: awkgram.y:3935
+#: awkgram.y:4303
#, c-format
msgid "function `%s': parameter `%s' shadows global variable"
msgstr "funzione `%s': parametro `%s' nasconde variabile globale"
-#: awkgram.y:4093
+#: awkgram.y:4360 debug.c:4042 debug.c:4085 debug.c:5205
#, c-format
msgid "could not open `%s' for writing (%s)"
msgstr "non riesco ad aprire `%s' in scrittura (%s)"
-#: awkgram.y:4094
-#, fuzzy
+#: awkgram.y:4361
msgid "sending variable list to standard error"
-msgstr "mando profilo a 'standard error'"
+msgstr "mando lista variabili a 'standard error'"
-#: awkgram.y:4100
+#: awkgram.y:4369
#, c-format
msgid "%s: close failed (%s)"
-msgstr "%s: 'close' fallita (%s)"
+msgstr "%s: `close' non riuscita (%s)"
-#: awkgram.y:4152
+#: awkgram.y:4394
msgid "shadow_funcs() called twice!"
msgstr "shadow_funcs() chiamata due volte!"
-#: awkgram.y:4158
+#: awkgram.y:4402
msgid "there were shadowed variables."
msgstr "c'erano variabili nascoste."
-#: awkgram.y:4188
+#: awkgram.y:4481
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "funzione di nome `%s' definita in precedenza"
+
+#: awkgram.y:4527
#, 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"
+msgstr ""
+"funzione `%s': non è possibile usare nome della funzione come nome parametro"
-#: awkgram.y:4192
+#: awkgram.y:4530
#, c-format
msgid "function `%s': can't use special variable `%s' as a function parameter"
msgstr ""
-"funzione `%s': non posso usare la variabile speciale `%s' come parametro di "
-"funzione"
+"funzione `%s': non è possibile usare la variabile speciale `%s' come "
+"parametro di funzione"
-#: awkgram.y:4208
+#: awkgram.y:4538
#, c-format
-msgid "function name `%s' previously defined"
-msgstr "funzione di nome `%s' definita in precedenza"
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "funzione `%s': parametro #%d, `%s', duplica parametro #%d"
-#: awkgram.y:4376 awkgram.y:4382
+#: awkgram.y:4625 awkgram.y:4631
#, c-format
msgid "function `%s' called but never defined"
msgstr "funzione `%s' chiamata ma mai definita"
-#: awkgram.y:4385
+#: awkgram.y:4635
#, c-format
msgid "function `%s' defined but never called directly"
msgstr "funzione `%s' definita ma mai chiamata direttamente"
-#: awkgram.y:4417
+#: awkgram.y:4667
#, 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:4526
+#: awkgram.y:4726
#, c-format
msgid ""
"function `%s' called with space between name and `(',\n"
@@ -530,227 +509,255 @@ msgstr ""
"funzione `%s' chiamata con spazio tra il nome e `(',\n"
"o usata come variabile o vettore"
-#: awkgram.y:4773 eval.c:2056
+#: awkgram.y:4962
msgid "division by zero attempted"
msgstr "tentativo di dividere per zero"
-#: awkgram.y:4782 eval.c:2072
+#: awkgram.y:4971
#, c-format
msgid "division by zero attempted in `%%'"
msgstr "tentativo di dividere per zero in `%%'"
-#: builtin.c:120
+#: awkgram.y:5294
+msgid ""
+"cannot assign a value to the result of a field post-increment expression"
+msgstr ""
+"impossibile assegnare un valore al risultato di un'espressione di post-"
+"incremento di un campo"
+
+#: awkgram.y:5297
+#, c-format
+msgid "invalid target of assignment (opcode %s)"
+msgstr "destinazione di assegnazione non valida (codice operativo %s)"
+
+#: builtin.c:133
#, c-format
msgid "%s to \"%s\" failed (%s)"
-msgstr "%s a \"%s\" fallita (%s)"
+msgstr "%s a \"%s\" non riuscita (%s)"
-#: builtin.c:121
+#: builtin.c:134
msgid "standard output"
msgstr "standard output"
-#: builtin.c:135
+#: builtin.c:148
msgid "exp: received non-numeric argument"
-msgstr "exp: argomento non numerico"
+msgstr "exp: l'argomento ricevuto non è numerico"
-#: builtin.c:141
+#: builtin.c:154
#, c-format
msgid "exp: argument %g is out of range"
-msgstr "exp: argomento %g non accettabile"
+msgstr "exp: argomento %g fuori intervallo"
-#: builtin.c:200
+#: builtin.c:229
#, 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"
+"fflush: non riesco a scaricare: `pipe' `%s' aperta in lettura, non in "
+"scrittura"
-#: builtin.c:203
+#: builtin.c:232
#, 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"
+"fflush: non riesco a scaricare: file `%s' aperto in lettura, non in scrittura"
-#: builtin.c:215
+#: builtin.c:244
#, 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"
+msgstr "fflush: `%s' non è un file aperto, una `pipe' o un co-processo"
-#: builtin.c:333
+#: builtin.c:351
msgid "index: received non-string first argument"
-msgstr "index: il primo argomento non è una stringa"
+msgstr "index: il primo argomento ricevuto non è una stringa"
-#: builtin.c:335
+#: builtin.c:353
msgid "index: received non-string second argument"
-msgstr "index: il secondo argomento non è una stringa"
+msgstr "index: il secondo argomento ricevuto non è una stringa"
-#: builtin.c:457
+#: builtin.c:466 mpfr.c:777
msgid "int: received non-numeric argument"
-msgstr "int: argomento non numerico"
+msgstr "int: l'argomento ricevuto non è numerico"
-#: builtin.c:493
+#: builtin.c:503
msgid "length: received array argument"
-msgstr "length: l'argomento fornito è un vettore"
+msgstr "length: l'argomento ricevuto è un vettore"
-#: builtin.c:496
+#: builtin.c:506
msgid "`length(array)' is a gawk extension"
msgstr "`length(array)' è un'estensione gawk"
-#: builtin.c:504
+#: builtin.c:522
msgid "length: received non-string argument"
-msgstr "length: l'argomento non è una stringa"
+msgstr "length: l'argomento ricevuto non è una stringa"
-#: builtin.c:535
+#: builtin.c:551
msgid "log: received non-numeric argument"
-msgstr "log: argomento non numerico"
+msgstr "log: l'argomento ricevuto non è numerico"
-#: builtin.c:538
+#: builtin.c:554
#, c-format
msgid "log: received negative argument %g"
-msgstr "log: argomento negativo %g"
+msgstr "log: argomento ricevuto negativo %g"
-#: builtin.c:694 builtin.c:699
+#: builtin.c:752 builtin.c:757
msgid "fatal: must use `count$' on all formats or none"
-msgstr ""
+msgstr "fatale: `count$' va usato per tutti i formati o per nessuno"
-#: builtin.c:761
+#: builtin.c:827
#, c-format
msgid "field width is ignored for `%%' specifier"
-msgstr ""
+msgstr "larghezza campo ignorata per la specifica `%%'"
-#: builtin.c:763
+#: builtin.c:829
#, c-format
msgid "precision is ignored for `%%' specifier"
-msgstr ""
+msgstr "precisione ignorata per la specifica `%%'"
-#: builtin.c:765
+#: builtin.c:831
#, c-format
msgid "field width and precision are ignored for `%%' specifier"
-msgstr ""
+msgstr "larghezza campo e precisone ignorate per la specifica `%%'"
-#: builtin.c:816
-#, fuzzy
+#: builtin.c:882
msgid "fatal: `$' is not permitted in awk formats"
-msgstr "l'operatore `^' non è supportato nel vecchio awk"
+msgstr "fatale: operatore `$' non consentito nei formati awk"
-#: builtin.c:825
+#: builtin.c:891
msgid "fatal: arg count with `$' must be > 0"
-msgstr ""
+msgstr "fatale: numero argomenti con `$' dev'essere > 0"
-#: builtin.c:829
+#: builtin.c:895
#, c-format
msgid "fatal: arg count %ld greater than total number of supplied arguments"
-msgstr ""
+msgstr "fatale: numero argomenti %ld > del numero totale argomenti specificati"
-#: builtin.c:833
+#: builtin.c:899
msgid "fatal: `$' not permitted after period in format"
-msgstr ""
+msgstr "fatale: `$' non consentito dopo il punto in un formato"
-#: builtin.c:849
+#: builtin.c:915
msgid "fatal: no `$' supplied for positional field width or precision"
-msgstr ""
+msgstr "fatale: manca `$' per i campi posizionali larghezza o precisione"
-#: builtin.c:920
+#: builtin.c:985
msgid "`l' is meaningless in awk formats; ignored"
-msgstr ""
+msgstr "`l' non ha senso nei formati awk; ignorato"
-#: builtin.c:924
+#: builtin.c:989
msgid "fatal: `l' is not permitted in POSIX awk formats"
-msgstr ""
+msgstr "fatale: `l' non consentito nei formati POSIX awk"
-#: builtin.c:937
+#: builtin.c:1002
msgid "`L' is meaningless in awk formats; ignored"
-msgstr ""
+msgstr "`L' non ha senso nei formati awk; ignorato"
-#: builtin.c:941
+#: builtin.c:1006
msgid "fatal: `L' is not permitted in POSIX awk formats"
-msgstr ""
+msgstr "fatale: `L' non consentito nei formati POSIX awk"
-#: builtin.c:954
+#: builtin.c:1019
msgid "`h' is meaningless in awk formats; ignored"
-msgstr ""
+msgstr "`h' non ha senso nei formati awk; ignorato"
-#: builtin.c:958
+#: builtin.c:1023
msgid "fatal: `h' is not permitted in POSIX awk formats"
-msgstr ""
+msgstr "fatale: `h' non consentito nei formati POSIX awk"
+
+#: builtin.c:1049
+#, c-format
+msgid "[s]printf: value %g is too big for %%c format"
+msgstr "[s]printf: valore %g troppo elevato per il formato %%c"
+
+#: builtin.c:1062
+#, c-format
+msgid "[s]printf: value %g is not a valid wide character"
+msgstr "[s]printf: valore %g non è un carattere multibyte valido "
-#: builtin.c:1271
+#: builtin.c:1448
#, c-format
msgid "[s]printf: value %g is out of range for `%%%c' format"
-msgstr ""
+msgstr "[s]printf: valore %g fuori intervallo per il formato `%%%c'"
-#: builtin.c:1331
+#: builtin.c:1546
#, c-format
msgid "ignoring unknown format specifier character `%c': no argument converted"
-msgstr ""
+msgstr "carattere di formato ignoto `%c' ignorato: nessun argomento convertito"
-#: builtin.c:1336
+#: builtin.c:1551
msgid "fatal: not enough arguments to satisfy format string"
msgstr ""
+"fatale: argomenti in numero minore di quelli richiesti dalla stringa di "
+"formato"
-#: builtin.c:1338
+#: builtin.c:1553
msgid "^ ran out for this one"
-msgstr ""
+msgstr "^ esauriti a questo punto"
-#: builtin.c:1345
+#: builtin.c:1560
msgid "[s]printf: format specifier does not have control letter"
-msgstr ""
+msgstr "[s]printf: specifica di formato senza un carattere di controllo"
-#: builtin.c:1348
+#: builtin.c:1563
msgid "too many arguments supplied for format string"
-msgstr ""
+msgstr "troppi argomenti specificati per questa stringa di formato"
+
+#: builtin.c:1619
+msgid "sprintf: no arguments"
+msgstr "sprintf: nessun argomento"
-#: builtin.c:1422 builtin.c:1433
+#: builtin.c:1642 builtin.c:1653
msgid "printf: no arguments"
-msgstr "printf: manca argomento"
+msgstr "printf: nessun argomento"
-#: builtin.c:1474
+#: builtin.c:1696
msgid "sqrt: received non-numeric argument"
-msgstr "sqrt: argomento non numerico"
+msgstr "sqrt: l'argomento ricevuto non è numerico"
-#: builtin.c:1478
+#: builtin.c:1700
#, c-format
msgid "sqrt: called with negative argument %g"
msgstr "sqrt: chiamata con argomento negativo %g"
-#: builtin.c:1502
+#: builtin.c:1731
#, c-format
msgid "substr: length %g is not >= 1"
msgstr "substr: lunghezza %g non >= 1"
-#: builtin.c:1504
+#: builtin.c:1733
#, c-format
msgid "substr: length %g is not >= 0"
msgstr "substr: lunghezza %g non >= 0"
-#: builtin.c:1511
+#: builtin.c:1747
#, c-format
msgid "substr: non-integer length %g will be truncated"
msgstr "substr: lunghezza non intera %g: sarà troncata"
-#: builtin.c:1516
+#: builtin.c:1752
#, 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:1528
+#: builtin.c:1764
#, c-format
msgid "substr: start index %g is invalid, using 1"
msgstr "substr: indice di partenza %g non valido, uso 1"
-#: builtin.c:1533
+#: builtin.c:1769
#, c-format
msgid "substr: non-integer start index %g will be truncated"
msgstr "substr: indice di partenza non intero %g: sarà troncato"
-#: builtin.c:1558
+#: builtin.c:1792
msgid "substr: source string is zero length"
msgstr "substr: stringa di partenza lunga zero"
-#: builtin.c:1574
+#: builtin.c:1806
#, 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:1582
+#: builtin.c:1814
#, c-format
msgid ""
"substr: length %g at start index %g exceeds length of first argument (%lu)"
@@ -758,228 +765,1149 @@ msgstr ""
"substr: lunghezza %g all'indice di partenza %g supera la lunghezza del primo "
"argomento (%lu)"
-#: builtin.c:1655
+#: builtin.c:1884
msgid "strftime: format value in PROCINFO[\"strftime\"] has numeric type"
msgstr ""
-"strftime: il valore del 'format' in PROCINFO[\"strftime\"] è di tipo numerico"
+"strftime: il valore del formato in PROCINFO[\"strftime\"] è di tipo numerico"
-#: builtin.c:1678
+#: builtin.c:1907
msgid "strftime: received non-numeric second argument"
-msgstr "strftime: il secondo argomento non è numerico"
+msgstr "strftime: il secondo argomento ricevuto non è numerico"
-#: builtin.c:1681
+#: builtin.c:1911
msgid "strftime: second argument less than 0 or too big for time_t"
-msgstr ""
+msgstr "strftime: il secondo argomento è < 0 o troppo elevato per time_t"
-#: builtin.c:1687
+#: builtin.c:1918
msgid "strftime: received non-string first argument"
-msgstr "strftime: il primo argomento non è una stringa"
+msgstr "strftime: il primo argomento ricevuto non è una stringa"
-#: builtin.c:1693
+#: builtin.c:1925
msgid "strftime: received empty format string"
-msgstr "strftime: 'format' è una stringa nulla"
+msgstr "strftime: il formato ricevuto è una stringa nulla"
-#: builtin.c:1759
+#: builtin.c:1991
msgid "mktime: received non-string argument"
-msgstr "mktime: l'argomento non è una stringa"
+msgstr "mktime: l'argomento ricevuto non è una stringa"
-#: builtin.c:1776
+#: builtin.c:2008
msgid "mktime: at least one of the values is out of the default range"
msgstr "mktime: almeno un valore è fuori dall'intervallo di default"
-#: builtin.c:1811
+#: builtin.c:2043
msgid "'system' function not allowed in sandbox mode"
-msgstr "la funzione 'system' non è permessa in modo 'sandbox'"
+msgstr "funzione 'system' non consentita in modo `sandbox'"
-#: builtin.c:1816
+#: builtin.c:2048
msgid "system: received non-string argument"
-msgstr "system: l'argomento non è una stringa"
+msgstr "system: l'argomento ricevuto non è una stringa"
-#: builtin.c:1871 eval.c:1159 eval.c:1790 eval.c:1803
-#, c-format
-msgid "reference to uninitialized variable `%s'"
-msgstr "riferimento a variabile non inizializzata `%s'"
-
-#: builtin.c:1938
+#: builtin.c:2168
#, c-format
msgid "reference to uninitialized field `$%d'"
msgstr "riferimento a variabile non inizializzata `$%d'"
-#: builtin.c:2025
+#: builtin.c:2253
msgid "tolower: received non-string argument"
-msgstr "tolower: l'argomento non è una stringa"
+msgstr "tolower: l'argomento ricevuto non è una stringa"
-#: builtin.c:2059
+#: builtin.c:2284
msgid "toupper: received non-string argument"
-msgstr "toupper: l'argomento non è una stringa"
+msgstr "toupper: l'argomento ricevuto non è una stringa"
-#: builtin.c:2095
+#: builtin.c:2317 mpfr.c:679
msgid "atan2: received non-numeric first argument"
-msgstr "atan2: il primo argomento non è numerico"
+msgstr "atan2: il primo argomento ricevuto non è numerico"
-#: builtin.c:2097
+#: builtin.c:2319 mpfr.c:681
msgid "atan2: received non-numeric second argument"
-msgstr "atan2: il secondo argomento non è numerico"
+msgstr "atan2: il secondo argomento ricevuto non è numerico"
-#: builtin.c:2116
+#: builtin.c:2338
msgid "sin: received non-numeric argument"
-msgstr "sin: l'argomento non è numerico"
+msgstr "sin: l'argomento ricevuto non è numerico"
-#: builtin.c:2132
+#: builtin.c:2354
msgid "cos: received non-numeric argument"
-msgstr "cos: l'argomento non è numerico"
+msgstr "cos: l'argomento ricevuto non è numerico"
-#: builtin.c:2185
+#: builtin.c:2468 mpfr.c:1176
msgid "srand: received non-numeric argument"
-msgstr "srand: l'argomento non è numerico"
+msgstr "srand: l'argomento ricevuto non è numerico"
-#: builtin.c:2216
+#: builtin.c:2499
msgid "match: third argument is not an array"
-msgstr "match: il terzo argomento non è un vettore"
+msgstr "match: terzo argomento non-vettoriale"
-#: builtin.c:2480
-msgid "gensub: third argument of 0 treated as 1"
-msgstr "gensub: il terzo argomento è 0, trattato come 1"
+#: builtin.c:2760
+#, c-format
+msgid "gensub: third argument `%.*s' treated as 1"
+msgstr "gensub: il terzo argomento `%.*s' trattato come 1"
-#: builtin.c:2773
+#: builtin.c:2775
+#, c-format
+msgid "gensub: third argument %g treated as 1"
+msgstr "gensub: il terzo argomento %g trattato come 1"
+
+#: builtin.c:3075
msgid "lshift: received non-numeric first argument"
-msgstr "lshift: il primo argomento non è numerico"
+msgstr "lshift: il primo argomento ricevuto non è numerico"
-#: builtin.c:2775
+#: builtin.c:3077
msgid "lshift: received non-numeric second argument"
-msgstr "lshift: il secondo argomento non è numerico"
+msgstr "lshift: il secondo argomento ricevuto non è numerico"
-#: builtin.c:2781
+#: builtin.c:3083
#, c-format
-msgid "lshift(%lf, %lf): negative values will give strange results"
-msgstr "lshift(%lf, %lf): valori negativi daranno risultati strani"
+msgid "lshift(%f, %f): negative values will give strange results"
+msgstr "lshift(%f, %f): valori negativi daranno risultati strani"
-#: builtin.c:2783
+#: builtin.c:3085
#, c-format
-msgid "lshift(%lf, %lf): fractional values will be truncated"
-msgstr "lshift(%lf, %lf): valori con decimali verranno troncati"
+msgid "lshift(%f, %f): fractional values will be truncated"
+msgstr "lshift(%f, %f): valori decimali saranno troncati"
-#: builtin.c:2785
+#: builtin.c:3087
#, c-format
-msgid "lshift(%lf, %lf): too large shift value will give strange results"
-msgstr "lshift(%lf, %lf): valori troppo alti daranno risultati strani"
+msgid "lshift(%f, %f): too large shift value will give strange results"
+msgstr "lshift(%f, %f): valori troppo alti daranno risultati strani"
-#: builtin.c:2810
+#: builtin.c:3112
msgid "rshift: received non-numeric first argument"
-msgstr "rshift: il primo argomento non è numerico"
+msgstr "rshift: il primo argomento ricevuto non è numerico"
-#: builtin.c:2812
+#: builtin.c:3114
msgid "rshift: received non-numeric second argument"
-msgstr "rshift: il secondo argomento non è numerico"
+msgstr "rshift: il secondo argomento ricevuto non è numerico"
-#: builtin.c:2818
+#: builtin.c:3120
#, c-format
-msgid "rshift(%lf, %lf): negative values will give strange results"
-msgstr "rshift(%lf, %lf): valori negativi daranno risultati strani"
+msgid "rshift(%f, %f): negative values will give strange results"
+msgstr "rshift(%f, %f): valori negativi daranno risultati strani"
-#: builtin.c:2820
+#: builtin.c:3122
#, c-format
-msgid "rshift(%lf, %lf): fractional values will be truncated"
-msgstr "rshift(%lf, %lf): valori con decimali verranno troncati"
+msgid "rshift(%f, %f): fractional values will be truncated"
+msgstr "rshift(%f, %f): valori decimali saranno troncati"
-#: builtin.c:2822
+#: builtin.c:3124
#, c-format
-msgid "rshift(%lf, %lf): too large shift value will give strange results"
-msgstr "rshift(%lf, %lf): valori troppo alti daranno risultati strani"
+msgid "rshift(%f, %f): too large shift value will give strange results"
+msgstr "rshift(%f, %f): valori troppo alti daranno risultati strani"
-#: builtin.c:2847
-msgid "and: received non-numeric first argument"
-msgstr "and: il primo argomento non è numerico"
+#: builtin.c:3149 mpfr.c:988
+msgid "and: called with less than two arguments"
+msgstr "and: chiamata con meno di due argomenti"
-#: builtin.c:2849
-msgid "and: received non-numeric second argument"
-msgstr "and: il secondo argomento non è numerico"
+#: builtin.c:3154
+#, c-format
+msgid "and: argument %d is non-numeric"
+msgstr "and: l'argomento %d non è numerico"
-#: builtin.c:2855
+#: builtin.c:3158
#, c-format
-msgid "and(%lf, %lf): negative values will give strange results"
-msgstr "and(%lf, %lf): valori negativi daranno risultati strani"
+msgid "and: argument %d negative value %g will give strange results"
+msgstr "and: argomento %d, valore negativo %g darà risultati strani"
-#: builtin.c:2857
+#: builtin.c:3181 mpfr.c:1020
+msgid "or: called with less than two arguments"
+msgstr "or: chiamata con meno di due argomenti"
+
+#: builtin.c:3186
#, c-format
-msgid "and(%lf, %lf): fractional values will be truncated"
-msgstr "and(%lf, %lf): valori con decimali verranno troncati"
+msgid "or: argument %d is non-numeric"
+msgstr "or: l'argomento %d non è numerico"
-#: builtin.c:2882
-msgid "or: received non-numeric first argument"
-msgstr "or: il primo argomento non è numerico"
+#: builtin.c:3190
+#, c-format
+msgid "or: argument %d negative value %g will give strange results"
+msgstr "or: argomento %d, valore negativo %g darà risultati strani"
-#: builtin.c:2884
-msgid "or: received non-numeric second argument"
-msgstr "or: il secondo argomento non è numerico"
+#: builtin.c:3212 mpfr.c:1051
+msgid "xor: called with less than two arguments"
+msgstr "xor: chiamata con meno di due argomenti"
-#: builtin.c:2890
+#: builtin.c:3218
#, c-format
-msgid "or(%lf, %lf): negative values will give strange results"
-msgstr "or(%lf, %lf): valori negativi daranno risultati strani"
+msgid "xor: argument %d is non-numeric"
+msgstr "xor: l'argomento %d non è numerico"
-#: builtin.c:2892
+#: builtin.c:3222
#, c-format
-msgid "or(%lf, %lf): fractional values will be truncated"
-msgstr "or(%lf, %lf): valori con decimali verranno troncati"
+msgid "xor: argument %d negative value %g will give strange results"
+msgstr "xor: argomento %d, valore negativo %g darà risultati strani"
-#: builtin.c:2920
-msgid "xor: received non-numeric first argument"
-msgstr "xor: il primo argomento non è numerico"
+#: builtin.c:3247 mpfr.c:807
+msgid "compl: received non-numeric argument"
+msgstr "compl: l'argomento ricevuto non è numerico"
-#: builtin.c:2922
-msgid "xor: received non-numeric second argument"
-msgstr "xor: il secondo argomento non è numerico"
+#: builtin.c:3253
+#, c-format
+msgid "compl(%f): negative value will give strange results"
+msgstr "compl(%f): valore negativo, darà risultati strani"
-#: builtin.c:2928
+#: builtin.c:3255
#, c-format
-msgid "xor(%lf, %lf): negative values will give strange results"
-msgstr "xor(%lf, %lf): valori negativi daranno risultati strani"
+msgid "compl(%f): fractional value will be truncated"
+msgstr "compl(%f): valori decimali saranno troncati"
-#: builtin.c:2930
+#: builtin.c:3424
#, c-format
-msgid "xor(%lf, %lf): fractional values will be truncated"
-msgstr "xor(%lf, %lf): valori con decimali verranno troncati"
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: `%s' non è una categoria `locale' valida"
-#: builtin.c:2954 builtin.c:2960
-msgid "compl: received non-numeric argument"
-msgstr "compl: l'argomento non è numerico"
+#: builtin.c:3611 mpfr.c:1209
+msgid "div: third argument is not an array"
+msgstr "div: terzo argomento non-vettoriale"
+
+#: builtin.c:3619 mpfr.c:1217
+msgid "div: received non-numeric first argument"
+msgstr "div: il primo argomento ricevuto non è numerico"
+
+#: builtin.c:3621 mpfr.c:1219
+msgid "div: received non-numeric second argument"
+msgstr "div: il secondo argomento ricevuto non è numerico"
-#: builtin.c:2962
+#: builtin.c:3630 mpfr.c:1253
+msgid "div: division by zero attempted"
+msgstr "div: tentativo di dividere per zero"
+
+#: command.y:225
#, c-format
-msgid "compl(%lf): negative value will give strange results"
-msgstr "compl(%lf): valore negativo darà risultati strani"
+msgid "Type (g)awk statement(s). End with the command \"end\"\n"
+msgstr "Immetti istruzioni (g)awk. Termina col comando \"end\"\n"
-#: builtin.c:2964
+#: command.y:289
#, c-format
-msgid "compl(%lf): fractional value will be truncated"
-msgstr "compl(%lf): valore con decimali verrà troncato"
+msgid "invalid frame number: %d"
+msgstr "numero elemento non valido: %d"
-#: builtin.c:3133
+#: command.y:295
#, c-format
-msgid "dcgettext: `%s' is not a valid locale category"
-msgstr "dcgettext: `%s' non è una categoria 'locale' valida"
+msgid "info: invalid option - \"%s\""
+msgstr "info: opzione non valida - \"%s\""
+
+#: command.y:321
+#, c-format
+msgid "source \"%s\": already sourced."
+msgstr "sorgente \"%s\": già immesso."
+
+#: command.y:326
+#, c-format
+msgid "save \"%s\": command not permitted."
+msgstr "save \"%s\": comando non consentito."
+
+#: command.y:339
+msgid "Can't use command `commands' for breakpoint/watchpoint commands"
+msgstr ""
+"Non è possibile usare il comando `commands' con comandi di breakpoint/"
+"watchpoint"
+
+#: command.y:341
+msgid "no breakpoint/watchpoint has been set yet"
+msgstr "non è stato ancora impostato alcun breakpoint/watchpoint"
+
+#: command.y:343
+msgid "invalid breakpoint/watchpoint number"
+msgstr "numero di breakpoint/watchpoint non valido"
+
+#: command.y:348
+#, c-format
+msgid "Type commands for when %s %d is hit, one per line.\n"
+msgstr "Immetti comandi per quando si incontra %s %d, uno per riga.\n"
+
+#: command.y:350
+#, c-format
+msgid "End with the command \"end\"\n"
+msgstr "Termina col comando \"end\"\n"
+
+#: command.y:357
+msgid "`end' valid only in command `commands' or `eval'"
+msgstr "`end' valido solo nei comandi `commands' o `eval'"
+
+#: command.y:367
+msgid "`silent' valid only in command `commands'"
+msgstr "`silent' valido solo nel comando `commands'"
-#: eval.c:412
+#: command.y:373
+#, c-format
+msgid "trace: invalid option - \"%s\""
+msgstr "trace: opzione non valida - \"%s\""
+
+#: command.y:387
+msgid "condition: invalid breakpoint/watchpoint number"
+msgstr "condition: numero di breakpoint/watchpoint non valido"
+
+#: command.y:449
+msgid "argument not a string"
+msgstr "l'argomento non è una stringa"
+
+#: command.y:459 command.y:464
+#, c-format
+msgid "option: invalid parameter - \"%s\""
+msgstr "option: paramtro non valido - \"%s\""
+
+#: command.y:474
+#, c-format
+msgid "no such function - \"%s\""
+msgstr "funzione non esistente - \"%s\""
+
+#: command.y:531
+#, c-format
+msgid "enable: invalid option - \"%s\""
+msgstr "enable: opzione non valida - \"%s\""
+
+#: command.y:597
+#, c-format
+msgid "invalid range specification: %d - %d"
+msgstr "intervallo specificato non valido: %d - %d"
+
+#: command.y:659
+msgid "non-numeric value for field number"
+msgstr "valore non-numerico per campo numerico"
+
+#: command.y:680 command.y:687
+msgid "non-numeric value found, numeric expected"
+msgstr "trovato valore non-numerico, invece che numerico"
+
+#: command.y:712 command.y:718
+msgid "non-zero integer value"
+msgstr "valore intero diverso da zero"
+
+#: command.y:817
+msgid ""
+"backtrace [N] - print trace of all or N innermost (outermost if N < 0) "
+"frames."
+msgstr ""
+"backtrace [N] - stampe trace di tutti gli elementi o degli N più interni "
+"(più esterni se N <0)"
+
+#: command.y:819
+msgid ""
+"break [[filename:]N|function] - set breakpoint at the specified location."
+msgstr ""
+"break [[nome-file:]N|funzione] - metti breakpoint nel punto specificato."
+
+#: command.y:821
+msgid "clear [[filename:]N|function] - delete breakpoints previously set."
+msgstr "clear [[nome-file:]N|funzione] - togli breakpoint impostati prima."
+
+#: command.y:823
+msgid ""
+"commands [num] - starts a list of commands to be executed at a "
+"breakpoint(watchpoint) hit."
+msgstr ""
+"commands [num] - inizia una lista di comandi da eseguire se si raggiunge un "
+"breakpoint (watchpoint)."
+
+#: command.y:825
+msgid "condition num [expr] - set or clear breakpoint or watchpoint condition."
+msgstr ""
+"condition num [espr.] - imposta o togli condizione di breakpoint o "
+"watchpoint."
+
+#: command.y:827
+msgid "continue [COUNT] - continue program being debugged."
+msgstr "continue [COUNT] - continua il programma che stai testando."
+
+#: command.y:829
+msgid "delete [breakpoints] [range] - delete specified breakpoints."
+msgstr "delete [breakpoints] [range] - togli breakpoint specificati."
+
+#: command.y:831
+msgid "disable [breakpoints] [range] - disable specified breakpoints."
+msgstr "disbale [breakpoints] [range] - disabilita breakpoint specificati."
+
+#: command.y:833
+msgid "display [var] - print value of variable each time the program stops."
+msgstr "display [var] - stampa valore variabile a ogni arresto di programma."
+
+#: command.y:835
+msgid "down [N] - move N frames down the stack."
+msgstr "down [N] - discendi N elementi nello stack."
+
+#: command.y:837
+msgid "dump [filename] - dump instructions to file or stdout."
+msgstr "dump [nome-file] - elenca istruzioni su file o stdout."
+
+#: command.y:839
+msgid "enable [once|del] [breakpoints] [range] - enable specified breakpoints."
+msgstr ""
+"enable [once|del] [breakpoints] [range] - abilita breakpoint specificati."
+
+#: command.y:841
+msgid "end - end a list of commands or awk statements."
+msgstr "end - termina una lista di comandi o istruzioni awk."
+
+#: command.y:843
+msgid "eval stmt|[p1, p2, ...] - evaluate awk statement(s)."
+msgstr "eval stmt|[p1, p2, ...] - calcola valore di istruzione/i awk."
+
+#: command.y:845
+msgid "finish - execute until selected stack frame returns."
+msgstr "finish - esegui fino al ritorno dell'elemento di stack selezionato."
+
+#: command.y:847
+msgid "frame [N] - select and print stack frame number N."
+msgstr "frame [N] - seleziona e stampa elemento di stack numero N."
+
+#: command.y:849
+msgid "help [command] - print list of commands or explanation of command."
+msgstr "help [command] - stampa lista comandi o spiegazione di un comando."
+
+#: command.y:851
+msgid "ignore N COUNT - set ignore-count of breakpoint number N to COUNT."
+msgstr ""
+"ignore N CONTATORE - imposta a CONTATORE il numero delle volte in cui "
+"ignorare il breakpoint numero N."
+
+#: command.y:853
+msgid ""
+"info topic - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch."
+msgstr ""
+"info argomento - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch."
+
+#: command.y:855
+msgid "list [-|+|[filename:]lineno|function|range] - list specified line(s)."
+msgstr ""
+"list [-|+|[nome-file:]num_riga|funzione|intervallo] - elenca riga/he "
+"richiesta/e."
+
+#: command.y:857
+msgid "next [COUNT] - step program, proceeding through subroutine calls."
+msgstr ""
+"next [COUNT] - esegui la/e prossima/e istruzione/i, incluse chiamate a "
+"subroutine."
+
+#: command.y:859
+msgid ""
+"nexti [COUNT] - step one instruction, but proceed through subroutine calls."
+msgstr ""
+"nexti [COUNT] - esegui la prossima istruzione, anche se è una chiamate a "
+"subroutine."
+
+#: command.y:861
+msgid "option [name[=value]] - set or display debugger option(s)."
+msgstr "option [name[=value]] - imposta o mostra opzione/i debugger."
+
+#: command.y:863
+msgid "print var [var] - print value of a variable or array."
+msgstr "print var [var] - stampa valore di variabile/i o vettore/i."
+
+#: command.y:865
+msgid "printf format, [arg], ... - formatted output."
+msgstr "printf format, [arg], ... - output secondo formato."
+
+#: command.y:867
+msgid "quit - exit debugger."
+msgstr "quit - esci dal debugger."
+
+#: command.y:869
+msgid "return [value] - make selected stack frame return to its caller."
+msgstr ""
+"return [value] - fa tornare al suo chiamante l'elemento di stack selezionato."
+
+#: command.y:871
+msgid "run - start or restart executing program."
+msgstr "run - inizia o ricomincia esecuzione programma."
+
+#: command.y:874
+msgid "save filename - save commands from the session to file."
+msgstr "save nome-file - salva i comandi dalla sessione al file."
+
+#: command.y:877
+msgid "set var = value - assign value to a scalar variable."
+msgstr "set var = value - assegna valore a una variabile scalare."
+
+#: command.y:879
+msgid ""
+"silent - suspends usual message when stopped at a breakpoint/watchpoint."
+msgstr ""
+"silent - sospendi messaggio che segnala stop a un breakpoint/watchpoint."
+
+#: command.y:881
+msgid "source file - execute commands from file."
+msgstr "source file - esegui comandi contenuti nel file."
+
+#: command.y:883
+msgid "step [COUNT] - step program until it reaches a different source line."
+msgstr ""
+"step [CONTATORE] - esegui il programma finché non arriva a un'istruzione con "
+"numero di riga differente."
+
+#: command.y:885
+msgid "stepi [COUNT] - step one instruction exactly."
+msgstr "stepi [COUNT] - esegui esattamente un'istruzione."
+
+#: command.y:887
+msgid "tbreak [[filename:]N|function] - set a temporary breakpoint."
+msgstr "tbreak [[nome-file:]N|funzione] - imposta un breakpoint temporaneo."
+
+#: command.y:889
+msgid "trace on|off - print instruction before executing."
+msgstr "trace on|off - stampa istruzione prima di eseguirla."
+
+#: command.y:891
+msgid "undisplay [N] - remove variable(s) from automatic display list."
+msgstr ""
+"undisplay [N] - togli variabile/i dalla lista visualizzazioni automatiche."
+
+#: command.y:893
+msgid ""
+"until [[filename:]N|function] - execute until program reaches a different "
+"line or line N within current frame."
+msgstr ""
+"until [[nome-file:]N|funzione] - esegui finché il programma arriva una riga "
+"differente, o alla riga N nell'elemento di stack corrente."
+
+#: command.y:895
+msgid "unwatch [N] - remove variable(s) from watch list."
+msgstr "unwatch [N] - togli variabile/i dalla watchlist."
+
+#: command.y:897
+msgid "up [N] - move N frames up the stack."
+msgstr "up [N] - spostati di N elementi dello stack verso l'alto."
+
+#: command.y:899
+msgid "watch var - set a watchpoint for a variable."
+msgstr "watch var - imposta un watchpoint per una variabile."
+
+#: command.y:901
+msgid ""
+"where [N] - (same as backtrace) print trace of all or N innermost (outermost "
+"if N < 0) frames."
+msgstr ""
+"dove [N] - (equivalente a backtrace) stampa tracia di tutti gli elementi o "
+"degli N più interni (più esterni se N <0)"
+
+#: command.y:1013 debug.c:401 msg.c:135
+#, c-format
+msgid "error: "
+msgstr "errore: "
+
+#: command.y:1053
+#, c-format
+msgid "can't read command (%s)\n"
+msgstr "non riesco a leggere comando (%s)\n"
+
+#: command.y:1067
+#, c-format
+msgid "can't read command (%s)"
+msgstr "non riesco a leggere comando (%s)"
+
+#: command.y:1118
+msgid "invalid character in command"
+msgstr "carattere non valido nel comando"
+
+#: command.y:1154
+#, c-format
+msgid "unknown command - \"%.*s\", try help"
+msgstr "comando sconosciuto - \"%.*s\", vedere help"
+
+#: command.y:1224
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: command.y:1286
+msgid "invalid character"
+msgstr "carattere non valido"
+
+#: command.y:1457
+#, c-format
+msgid "undefined command: %s\n"
+msgstr "comando non definito: %s\n"
+
+#: debug.c:252
+msgid "set or show the number of lines to keep in history file."
+msgstr ""
+"imposta o mostra il numero di righe da tenere nel file che contiene la "
+"storia comandi."
+
+#: debug.c:254
+msgid "set or show the list command window size."
+msgstr "imposta o mostra dimensioni finestra lista comandi"
+
+#: debug.c:256
+msgid "set or show gawk output file."
+msgstr "imposta o mostra file di outpu gawk"
+
+#: debug.c:258
+msgid "set or show debugger prompt."
+msgstr "imposta o mostra prompt di debug"
+
+#: debug.c:260
+msgid "(un)set or show saving of command history (value=on|off)."
+msgstr "(dis)imposta o mostra salvataggio storia comandi (valore=on|off)."
+
+#: debug.c:262
+msgid "(un)set or show saving of options (value=on|off)."
+msgstr "(dis)imposta o mostra salvataggio opzioni (valore=on|off)."
+
+#: debug.c:264
+msgid "(un)set or show instruction tracing (value=on|off)."
+msgstr "(dis)imposta o mostra tracciamento istruzioni (valore=on|off)."
+
+#: debug.c:345
+msgid "program not running."
+msgstr "programma non in esecuzione."
+
+#: debug.c:448 debug.c:606
+#, c-format
+msgid "can't read source file `%s' (%s)"
+msgstr "non riesco a leggere file sorgente `%s' (%s)"
+
+#: debug.c:453
+#, c-format
+msgid "source file `%s' is empty.\n"
+msgstr "file sorgente `%s' vuoto.\n"
+
+#: debug.c:480
+msgid "no current source file."
+msgstr "file sorgente non disponibile."
+
+#: debug.c:505
+#, c-format
+msgid "cannot find source file named `%s' (%s)"
+msgstr "non riesco a leggere file di nome `%s' (%s)"
+
+#: debug.c:529
+#, c-format
+msgid "WARNING: source file `%s' modified since program compilation.\n"
+msgstr ""
+"ATTENZIONE: file sorgente `%s' modificato dopo la compilazione del "
+"programma.\n"
+
+#: debug.c:551
+#, c-format
+msgid "line number %d out of range; `%s' has %d lines"
+msgstr "numero riga %d non ammesso; `%s' ha %d righe"
+
+#: debug.c:611
+#, c-format
+msgid "unexpected eof while reading file `%s', line %d"
+msgstr "fine-file inattesa durante lettura file `%s', riga %d"
+
+#: debug.c:620
+#, c-format
+msgid "source file `%s' modified since start of program execution"
+msgstr "file sorgente `%s' modificato dopo l'inizio esecuzione del programma."
+
+#: debug.c:732
+#, c-format
+msgid "Current source file: %s\n"
+msgstr "File sorgente corrente: %s\n"
+
+#: debug.c:733
+#, c-format
+msgid "Number of lines: %d\n"
+msgstr "Numero di righe: %d\n"
+
+#: debug.c:740
+#, c-format
+msgid "Source file (lines): %s (%d)\n"
+msgstr "File sorgente (righe): %s (%d)\n"
+
+#: debug.c:754
+msgid ""
+"Number Disp Enabled Location\n"
+"\n"
+msgstr ""
+"Numero Disp Abilit. Posizione\n"
+"\n"
+
+#: debug.c:765
+#, c-format
+msgid "\tno of hits = %ld\n"
+msgstr "\tn. di occorrenze = %ld\n"
+
+#: debug.c:767
+#, c-format
+msgid "\tignore next %ld hit(s)\n"
+msgstr "\tignora prossime %ld occorrenze\n"
+
+#: debug.c:769 debug.c:909
+#, c-format
+msgid "\tstop condition: %s\n"
+msgstr "\tcondizione per stop: %s\n"
+
+#: debug.c:771 debug.c:911
+msgid "\tcommands:\n"
+msgstr "\tcomandi:\n"
+
+#: debug.c:793
+#, c-format
+msgid "Current frame: "
+msgstr "Elemento corrente: "
+
+#: debug.c:796
+#, c-format
+msgid "Called by frame: "
+msgstr "Chiamato da elemento: "
+
+#: debug.c:800
+#, c-format
+msgid "Caller of frame: "
+msgstr "Chiamante di elemento: "
+
+#: debug.c:818
+#, c-format
+msgid "None in main().\n"
+msgstr "Assente in main().\n"
+
+#: debug.c:848
+msgid "No arguments.\n"
+msgstr "Nessun argomento.\n"
+
+#: debug.c:849
+msgid "No locals.\n"
+msgstr "Nessun `locale'.\n"
+
+#: debug.c:857
+msgid ""
+"All defined variables:\n"
+"\n"
+msgstr ""
+"Tutte le variabili definite:\n"
+"\n"
+
+#: debug.c:867
+msgid ""
+"All defined functions:\n"
+"\n"
+msgstr ""
+"Tutte le funzioni definite:\n"
+"\n"
+
+#: debug.c:886
+msgid ""
+"Auto-display variables:\n"
+"\n"
+msgstr ""
+"Auto-visualizzazione variabili:\n"
+"\n"
+
+#: debug.c:889
+msgid ""
+"Watch variables:\n"
+"\n"
+msgstr ""
+"Variabili Watch [da tenere sott'occhio]:\n"
+"\n"
+
+#: debug.c:1029
+#, c-format
+msgid "no symbol `%s' in current context\n"
+msgstr "nessun simbolo `%s' nel contesto corrente\n"
+
+#: debug.c:1041 debug.c:1427
+#, c-format
+msgid "`%s' is not an array\n"
+msgstr "`%s' non è un vettore\n"
+
+#: debug.c:1055
+#, c-format
+msgid "$%ld = uninitialized field\n"
+msgstr "%ld = variabile non inizializzata\n"
+
+#: debug.c:1076
+#, c-format
+msgid "array `%s' is empty\n"
+msgstr "vettore `%s' vuoto\n"
+
+#: debug.c:1119 debug.c:1171
+#, c-format
+msgid "[\"%s\"] not in array `%s'\n"
+msgstr "[\"%s\"] non presente nel vettore `%s\n"
+
+#: debug.c:1175
+#, c-format
+msgid "`%s[\"%s\"]' is not an array\n"
+msgstr "`%s[\"%s\"]' non è un vettore\n"
+
+#: debug.c:1236 debug.c:4965
+#, c-format
+msgid "`%s' is not a scalar variable"
+msgstr "`%s' non è una variabile scalare"
+
+#: debug.c:1258 debug.c:4995
+#, c-format
+msgid "attempt to use array `%s[\"%s\"]' in a scalar context"
+msgstr "tentativo di usare vettore `%s[\"%s\"]' in un contesto scalare"
+
+#: debug.c:1280 debug.c:5006
+#, c-format
+msgid "attempt to use scalar `%s[\"%s\"]' as array"
+msgstr "tentativo di usare scalare `%s[\"%s\"]' come vettore"
+
+#: debug.c:1423
+#, c-format
+msgid "`%s' is a function"
+msgstr "`%s' è una funzione"
+
+#: debug.c:1465
+#, c-format
+msgid "watchpoint %d is unconditional\n"
+msgstr "watchpoint %d non soggetto a condizioni\n"
+
+#: debug.c:1499
+#, c-format
+msgid "No display item numbered %ld"
+msgstr "Nessun elemento numerato da visualizzare %ld"
+
+#: debug.c:1502
+#, c-format
+msgid "No watch item numbered %ld"
+msgstr "Nessun elemento numerato watch [da sorvegliare] da visualizzare %ld"
+
+#: debug.c:1528
+#, c-format
+msgid "%d: [\"%s\"] not in array `%s'\n"
+msgstr "%d: [\"%s\"] non presente nel vettore `%s'\n"
+
+#: debug.c:1767
+msgid "attempt to use scalar value as array"
+msgstr "tentativo di usare valore scalare come vettore"
+
+#: debug.c:1856
+#, c-format
+msgid "Watchpoint %d deleted because parameter is out of scope.\n"
+msgstr "Watchpoint %d cancellato perché il parametro è fuori intervallo.\n"
+
+#: debug.c:1867
+#, c-format
+msgid "Display %d deleted because parameter is out of scope.\n"
+msgstr ""
+"Visualizzazione %d cancellata perché il parametro è fuori intervallo.\n"
+
+#: debug.c:1900
+#, c-format
+msgid " in file `%s', line %d\n"
+msgstr " nel file `%s', riga %d\n"
+
+#: debug.c:1921
+#, c-format
+msgid " at `%s':%d"
+msgstr " a `%s':%d"
+
+#: debug.c:1937 debug.c:2000
+#, c-format
+msgid "#%ld\tin "
+msgstr "#%ld\tin "
+
+#: debug.c:1974
+#, c-format
+msgid "More stack frames follow ...\n"
+msgstr "Ulteriori elementi stack seguono...\n"
+
+#: debug.c:2017
+msgid "invalid frame number"
+msgstr "numero elemento non valido"
+
+#: debug.c:2200
+#, c-format
+msgid "Note: breakpoint %d (enabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+"Nota: breakpoint %d (abilitato, ignora prossimi %ld passaggi), anche "
+"impostato a %s:%d"
+
+#: debug.c:2207
+#, c-format
+msgid "Note: breakpoint %d (enabled), also set at %s:%d"
+msgstr "Nota: breakpoint %d (abilitato), anche impostato a %s:%d"
+
+#: debug.c:2214
+#, c-format
+msgid "Note: breakpoint %d (disabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+"Nota: breakpoint %d (disabilitato, ignora prossimi %ld passaggi), anche "
+"impostato a %s:%d"
+
+#: debug.c:2221
+#, c-format
+msgid "Note: breakpoint %d (disabled), also set at %s:%d"
+msgstr "Nota: breakpoint %d (disabilitato), anche impostato a %s:%d"
+
+#: debug.c:2238
+#, c-format
+msgid "Breakpoint %d set at file `%s', line %d\n"
+msgstr "Breakpoint %d impostato al file `%s', riga %d\n"
+
+#: debug.c:2340
+#, c-format
+msgid "Can't set breakpoint in file `%s'\n"
+msgstr "Non riesco a impostare breakpoint nel file `%s'\n"
+
+#: debug.c:2369 debug.c:2492 debug.c:3350
+#, c-format
+msgid "line number %d in file `%s' out of range"
+msgstr "numero riga %d nel file `%s' fuori intervallo"
+
+#: debug.c:2373
+#, c-format
+msgid "Can't find rule!!!\n"
+msgstr "Non riesco a trovare la regola!!!\n"
+
+#: debug.c:2375
+#, c-format
+msgid "Can't set breakpoint at `%s':%d\n"
+msgstr "Non riesco a impostare breakpoint a `%s':%d\n"
+
+#: debug.c:2387
+#, c-format
+msgid "Can't set breakpoint in function `%s'\n"
+msgstr "Non riesco a impostare breakpoint nella funzione `%s'\n"
+
+#: debug.c:2403
+#, c-format
+msgid "breakpoint %d set at file `%s', line %d is unconditional\n"
+msgstr "breakpoint %d impostato al file `%s', riga %d è senza condizioni\n"
+
+#: debug.c:2508 debug.c:2530
+#, c-format
+msgid "Deleted breakpoint %d"
+msgstr "Cancellato breakpoint %d"
+
+#: debug.c:2514
+#, c-format
+msgid "No breakpoint(s) at entry to function `%s'\n"
+msgstr "No breakpoint all'entrata nella funzione `%s'\n"
+
+#: debug.c:2541
+#, c-format
+msgid "No breakpoint at file `%s', line #%d\n"
+msgstr "No breakpoint al file `%s', riga #%d\n"
+
+#: debug.c:2596 debug.c:2637 debug.c:2657 debug.c:2700
+msgid "invalid breakpoint number"
+msgstr "numero breakpoint non valido"
+
+#: debug.c:2612
+msgid "Delete all breakpoints? (y or n) "
+msgstr "Cancello tutti i breakpoint? (y oppure n) "
+
+#: debug.c:2613 debug.c:2923 debug.c:2976
+msgid "y"
+msgstr "y"
+
+#: debug.c:2662
+#, c-format
+msgid "Will ignore next %ld crossing(s) of breakpoint %d.\n"
+msgstr "Prossimi %ld passaggi dal breakpoint %d ignorati.\n"
+
+#: debug.c:2666
+#, c-format
+msgid "Will stop next time breakpoint %d is reached.\n"
+msgstr "Farò uno stop al prossimo passaggio dal breakpoint %d.\n"
+
+#: debug.c:2783
+#, c-format
+msgid "Can only debug programs provided with the `-f' option.\n"
+msgstr "Debug possibile solo per programmi con opzione `-f' specificata.\n"
+
+#: debug.c:2908
+#, c-format
+msgid "Failed to restart debugger"
+msgstr "Non sono riuscito a far ripartire il debugger"
+
+#: debug.c:2922
+msgid "Program already running. Restart from beginning (y/n)? "
+msgstr "Programma già in esecuzione. Lo faccio ripartire dall'inizio (y/n)? "
+
+#: debug.c:2926
+#, c-format
+msgid "Program not restarted\n"
+msgstr "Programma non fatto ripartire\n"
+
+#: debug.c:2936
+#, c-format
+msgid "error: cannot restart, operation not allowed\n"
+msgstr "errore: non riesco a far ripartire, operazione non consentita\n"
+
+#: debug.c:2942
+#, c-format
+msgid "error (%s): cannot restart, ignoring rest of the commands\n"
+msgstr "errore (%s): non riesco a far ripartire, ignoro i comandi rimanenti\n"
+
+#: debug.c:2950
+#, c-format
+msgid "Starting program: \n"
+msgstr "Partenza del programma: \n"
+
+#: debug.c:2959
+#, c-format
+msgid "Program exited %s with exit value: %d\n"
+msgstr "Programma %s eseguit, valore in uscita: %d\n"
+
+#: debug.c:2975
+msgid "The program is running. Exit anyway (y/n)? "
+msgstr "Il programma è in esecuzione. Esco comunque (y/n)? "
+
+#: debug.c:3010
+#, c-format
+msgid "Not stopped at any breakpoint; argument ignored.\n"
+msgstr "Non interrotto ad alcun breakpoint: argomento ignorato.\n"
+
+#: debug.c:3015
+#, c-format
+msgid "invalid breakpoint number %d."
+msgstr "numero di breakpoint non valido %d."
+
+#: debug.c:3020
+#, c-format
+msgid "Will ignore next %ld crossings of breakpoint %d.\n"
+msgstr "Prossimi %ld passaggi dal breakpoint %d ignorati.\n"
+
+#: debug.c:3207
+#, c-format
+msgid "'finish' not meaningful in the outermost frame main()\n"
+msgstr "'finish' non significativo nell'elemento iniziale main()\n"
+
+#: debug.c:3212
+#, c-format
+msgid "Run till return from "
+msgstr "Esegui fino al ritorno da "
+
+#: debug.c:3255
+#, c-format
+msgid "'return' not meaningful in the outermost frame main()\n"
+msgstr "'return' non significativo nell'elemento iniziale main()\n"
+
+#: debug.c:3369
+#, c-format
+msgid "Can't find specified location in function `%s'\n"
+msgstr "Non trovo la posizione specificata nella funzione `%s'\n"
+
+#: debug.c:3377
+#, c-format
+msgid "invalid source line %d in file `%s'"
+msgstr "riga sorgente invalida %d nel file `%s'"
+
+#: debug.c:3392
+#, c-format
+msgid "Can't find specified location %d in file `%s'\n"
+msgstr "Non trovo posizione specificata %d nel file `%s'\n"
+
+#: debug.c:3424
+#, c-format
+msgid "element not in array\n"
+msgstr "elemento non presente nel vettore\n"
+
+#: debug.c:3424
+#, c-format
+msgid "untyped variable\n"
+msgstr "variabile di tipo sconosciuto\n"
+
+#: debug.c:3466
+#, c-format
+msgid "Stopping in %s ...\n"
+msgstr "Mi fermo in %s ...\n"
+
+#: debug.c:3543
+#, c-format
+msgid "'finish' not meaningful with non-local jump '%s'\n"
+msgstr "'finish' not significativo per salti non-locali '%s'\n"
+
+#: debug.c:3550
+#, c-format
+msgid "'until' not meaningful with non-local jump '%s'\n"
+msgstr "'until' not significativo per salti non-locali '%s'\n"
+
+#: debug.c:4186
+msgid "\t------[Enter] to continue or q [Enter] to quit------"
+msgstr "\t------[Invio] per continuare o q [Invio] per uscire------"
+
+#: debug.c:4187
+msgid "q"
+msgstr "q"
+
+#: debug.c:5002
+#, c-format
+msgid "[\"%s\"] not in array `%s'"
+msgstr "[\"%s\"] non presente nel vettore `%s'"
+
+#: debug.c:5208
+#, c-format
+msgid "sending output to stdout\n"
+msgstr "output inviato a stdout\n"
+
+#: debug.c:5248
+msgid "invalid number"
+msgstr "numero non valido"
+
+#: debug.c:5382
+#, c-format
+msgid "`%s' not allowed in current context; statement ignored"
+msgstr "`%s' non consentito nel contesto corrente; istruzione ignorata"
+
+#: debug.c:5390
+msgid "`return' not allowed in current context; statement ignored"
+msgstr "`return' non consentito nel contesto corrente; istruzione ignorata"
+
+#: debug.c:5605
+#, c-format
+msgid "No symbol `%s' in current context"
+msgstr "Simbolo `%s' non esiste nel contesto corrente"
+
+#: dfa.c:1051 dfa.c:1054 dfa.c:1073 dfa.c:1083 dfa.c:1095 dfa.c:1131
+#: dfa.c:1140 dfa.c:1143 dfa.c:1148 dfa.c:1162 dfa.c:1210
+msgid "unbalanced ["
+msgstr "[ non chiusa"
+
+#: dfa.c:1107
+msgid "invalid character class"
+msgstr "character class non valida"
+
+#: dfa.c:1253
+msgid "character class syntax is [[:space:]], not [:space:]"
+msgstr "sintassi character class è [[:spazio:]], non [:spazio:]"
+
+#: dfa.c:1315
+msgid "unfinished \\ escape"
+msgstr "sequenza escape \\ non completa"
+
+#: dfa.c:1462
+msgid "invalid content of \\{\\}"
+msgstr "contenuto di \\{\\} non valido"
+
+#: dfa.c:1465
+msgid "regular expression too big"
+msgstr "espressione regolare troppo complessa"
+
+#: dfa.c:1900
+msgid "unbalanced ("
+msgstr "( non chiusa"
+
+#: dfa.c:2026
+msgid "no syntax specified"
+msgstr "nessuna sintassi specificata"
+
+#: dfa.c:2034
+msgid "unbalanced )"
+msgstr ") non aperta"
+
+#: eval.c:397
#, c-format
msgid "unknown nodetype %d"
msgstr "tipo nodo sconosciuto %d"
-#: eval.c:423 eval.c:437
+#: eval.c:408 eval.c:422
#, c-format
msgid "unknown opcode %d"
msgstr "codice operativo sconosciuto %d"
-#: eval.c:434
+#: eval.c:419
#, c-format
msgid "opcode %s not an operator or keyword"
msgstr "codice operativo %s non è un operatore o una parola chiave"
-#: eval.c:488
+#: eval.c:475
msgid "buffer overflow in genflags2str"
msgstr "superamento limiti buffer in 'genflags2str'"
-#: eval.c:698
+#: eval.c:677
#, c-format
msgid ""
"\n"
@@ -987,819 +1915,1211 @@ msgid ""
"\n"
msgstr ""
"\n"
-"\t# 'Stack' (Pila) Chiamate Funzione:\n"
+"\t# `Stack' (Pila) Chiamate Funzione:\n"
"\n"
-#: eval.c:725
+#: eval.c:706
msgid "`IGNORECASE' is a gawk extension"
msgstr "`IGNORECASE' è un'estensione gawk"
-#: eval.c:754
+#: eval.c:738
msgid "`BINMODE' is a gawk extension"
msgstr "`BINMODE' è un'estensione gawk"
-#: eval.c:812
+#: eval.c:796
#, c-format
msgid "BINMODE value `%s' is invalid, treated as 3"
msgstr "valore di BINMODE `%s' non valido, considerato come 3"
-#: eval.c:902
+#: eval.c:913
#, c-format
msgid "bad `%sFMT' specification `%s'"
msgstr "specificazione invalida `%sFMT' `%s'"
-#: eval.c:980
+#: eval.c:997
msgid "turning off `--lint' due to assignment to `LINT'"
msgstr "disabilito `--lint' a causa di assegnamento a `LINT'"
-#: eval.c:1127 eval.c:1777
-#, 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:1158 eval.c:1789 eval.c:1802
+#: eval.c:1175
#, c-format
msgid "reference to uninitialized argument `%s'"
msgstr "riferimento ad argomento non inizializzato `%s'"
-#: eval.c:1177
+#: eval.c:1176
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "riferimento a variabile non inizializzata `%s'"
+
+#: eval.c:1194
msgid "attempt to field reference from non-numeric value"
-msgstr "tentativo di riferimento a un campo da valore non numerico"
+msgstr "tentativo di riferimento a un campo da valore non-numerico"
-#: eval.c:1179
+#: eval.c:1196
msgid "attempt to field reference from null string"
msgstr "tentativo di riferimento a un campo da una stringa nulla"
-#: eval.c:1185
+#: eval.c:1204
#, c-format
msgid "attempt to access field %ld"
msgstr "tentativo di accedere al campo %ld"
-#: eval.c:1194
+#: eval.c:1213
#, c-format
msgid "reference to uninitialized field `$%ld'"
msgstr "riferimento a campo non inizializzato `$%ld'"
-#: eval.c:1256
+#: eval.c:1300
#, c-format
msgid "function `%s' called with more arguments than declared"
msgstr "funzione `%s' chiamata con più argomenti di quelli previsti"
-#: eval.c:1437
+#: eval.c:1501
#, c-format
msgid "unwind_stack: unexpected type `%s'"
msgstr "unwind_stack: tipo non previsto `%s'"
-#: eval.c:1532
+#: eval.c:1597
msgid "division by zero attempted in `/='"
msgstr "divisione per zero tentata in `/='"
-#: eval.c:1539
+#: eval.c:1604
#, c-format
msgid "division by zero attempted in `%%='"
msgstr "divisione per zero tentata in `%%='"
-#: eval.c:1876 eval.c:2122
-#, fuzzy, c-format
-msgid "attempt to use array `%s[\"%.*s\"]' in a scalar context"
-msgstr "tentativo di usare vettore `%s' in un contesto scalare"
+#: ext.c:65 ext.c:147
+msgid "extensions are not allowed in sandbox mode"
+msgstr "le estensioni non sono consentite in modo `sandbox'"
-#: eval.c:1907
-msgid "assignment used in conditional context"
-msgstr "assegnamento usato nel contesto di un test condizionale"
+#: ext.c:68
+msgid "-l / @load are gawk extensions"
+msgstr "-l / @load sono estensioni gawk"
-#: eval.c:1911
-msgid "statement has no effect"
-msgstr "istruzione che non fa nulla"
+#: ext.c:71
+msgid "load_ext: received NULL lib_name"
+msgstr "load_ext: il nome libreria ricevuto è NULL"
-#: eval.c:2343
+#: ext.c:74
#, 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"
+msgid "load_ext: cannot open library `%s' (%s)\n"
+msgstr "load_ext: non riesco ad aprire libreria `%s' (%s)\n"
-#: eval.c:2458
+#: ext.c:80
#, c-format
-msgid "function called indirectly through `%s' does not exist"
-msgstr "la funzione chiamata indirettamente tramite `%s' non esiste"
+msgid ""
+"load_ext: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"
+msgstr ""
+"load_ext: libreria `%s': non definisce `plugin_is_GPL_compatible' (%s)\n"
-#: eval.c:2470
+#: ext.c:86
#, c-format
-msgid "function `%s' not defined"
-msgstr "funzione `%s' non definita"
+msgid "load_ext: library `%s': cannot call function `%s' (%s)\n"
+msgstr "load_ext: libreria `%s': non riesco a chiamare funzione `%s' (%s)\n"
-#: eval.c:2511
+#: ext.c:90
#, c-format
-msgid "non-redirected `getline' invalid inside `%s' rule"
-msgstr "`getline' non-diretta indefinita dentro regola '%s'"
+msgid "load_ext: library `%s' initialization routine `%s' failed\n"
+msgstr ""
+"load_ext: libreria `%s' routine di inizializzazione `%s' non riuscita\n"
-#: eval.c:2600
-#, c-format
-msgid "error reading input file `%s': %s"
-msgstr "errore leggendo file di input `%s': %s"
+#: ext.c:150
+msgid "`extension' is a gawk extension"
+msgstr "`extension' è un'estensione gawk"
-#: eval.c:2614
+#: ext.c:153
+msgid "extension: received NULL lib_name"
+msgstr "extension: il nome libreria ricevuto è NULL"
+
+#: ext.c:156
#, c-format
-msgid "`nextfile' cannot be called from a `%s' rule"
-msgstr "`nextfile' non può essere chiamato da una regola `%s'"
+msgid "extension: cannot open library `%s' (%s)"
+msgstr "extension: non riesco ad aprire libreria `%s' (%s)"
-#: eval.c:2694
+#: ext.c:162
#, c-format
-msgid "`next' cannot be called from a `%s' rule"
-msgstr "`next' non può essere chiamato da una regola `%s'"
+msgid ""
+"extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)"
+msgstr ""
+"extension: libreria `%s': non definisce `plugin_is_GPL_compatible' (%s)"
-#: eval.c:2760
+#: ext.c:166
#, c-format
-msgid "Sorry, don't know how to interpret `%s'"
-msgstr "Spiacente, non so come interpretare `%s'"
+msgid "extension: library `%s': cannot call function `%s' (%s)"
+msgstr "extension: libreria `%s': non riesco a chiamare funzione `%s' (%s)"
-#: ext.c:64
-msgid "extensions are not allowed in sandbox mode"
-msgstr "le estensioni non sono permesse in modo 'sandbox'"
+#: ext.c:197
+msgid "make_builtin: missing function name"
+msgstr "make_builtin: manca nome di funzione"
-#: ext.c:70 ext.c:75
-msgid "`extension' is a gawk extension"
-msgstr "`extension' è un'estensione gawk"
+#: ext.c:212
+#, c-format
+msgid "make_builtin: can't redefine function `%s'"
+msgstr "make_builtin: non riesco a ridefinire funzione `%s'"
-#: ext.c:85
+#: ext.c:216
#, c-format
-msgid "fatal: extension: cannot open `%s' (%s)\n"
-msgstr "fatale: estensione: non riesco ad aprire `%s' (%s)\n"
+msgid "make_builtin: function `%s' already defined"
+msgstr "make_builtin: funzione `%s' già definita"
-#: ext.c:94
+#: ext.c:220
#, c-format
-msgid ""
-"fatal: extension: library `%s': does not define "
-"`plugin_is_GPL_compatible' (%s)\n"
-msgstr ""
-"fatale: estensione: libreria `%s': non definisce "
-"`plugin_is_GPL_compatible' (%s)\n"
+msgid "make_builtin: function name `%s' previously defined"
+msgstr "make_builtin: funzione di nome `%s' definita in precedenza"
-#: ext.c:103
+#: ext.c:222
#, c-format
-msgid "fatal: extension: library `%s': cannot call function `%s' (%s)\n"
+msgid "make_builtin: can't use gawk built-in `%s' as function name"
msgstr ""
-"fatale: estensione: libreria `%s': non riesco a chiamare funzione `%s' (%s)\n"
+"make_builtin: nome funzione interna gawk `%s' non ammesso come nome funzione"
+
+#: ext.c:225 ext.c:280
+#, c-format
+msgid "make_builtin: negative argument count for function `%s'"
+msgstr "make_builtin: contatore argomenti negativo per la funzione `%s'"
-#: ext.c:137
+#: ext.c:252
msgid "extension: missing function name"
-msgstr "estensione: manca nome di funzione"
+msgstr "extension: manca nome di funzione"
-#: ext.c:142
+#: ext.c:255 ext.c:259
#, c-format
msgid "extension: illegal character `%c' in function name `%s'"
-msgstr "estensione: carattere non ammesso `%c' nel nome di funzione `%s'"
+msgstr "extension: carattere non ammesso `%c' nel nome di funzione `%s'"
-#: ext.c:151
+#: ext.c:267
#, c-format
msgid "extension: can't redefine function `%s'"
-msgstr "estensione: non riesco a ridefinire funzione `%s'"
+msgstr "extension: non riesco a ridefinire funzione `%s'"
-#: ext.c:155
+#: ext.c:271
#, c-format
msgid "extension: function `%s' already defined"
-msgstr "estensione: funzione `%s' già definita"
+msgstr "extension: funzione `%s' già definita"
-#: ext.c:160
+#: ext.c:275
#, c-format
msgid "extension: function name `%s' previously defined"
-msgstr "estensione: funzione di nome `%s' definita in precedenza"
+msgstr "extension: funzione di nome `%s' definita in precedenza"
-#: ext.c:162
+#: ext.c:277
#, 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"
+"extension: nome funzione interna gawk `%s' non ammesso come nome funzione"
-#: ext.c:166
-#, c-format
-msgid "make_builtin: negative argument count for function `%s'"
-msgstr "make_builtin: contatore argomenti negativo per la funzione `%s'"
-
-#: ext.c:269
+#: ext.c:351
#, c-format
msgid "function `%s' defined to take no more than %d argument(s)"
msgstr "funzione `%s' definita per avere al massimo %d argomenti(o)"
-#: ext.c:272
+#: ext.c:354
#, c-format
msgid "function `%s': missing argument #%d"
msgstr "funzione `%s': manca argomento #%d"
-#: ext.c:289
+#: ext.c:371
#, 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:293
+#: ext.c:375
#, 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:306
-msgid "Operation Not Supported"
-msgstr "Operazione Non Supportata"
+#: ext.c:389
+msgid "dynamic loading of library not supported"
+msgstr "caricamento dinamico di libreria non supportato"
+
+#: extension/filefuncs.c:159
+msgid "chdir: called with incorrect number of arguments, expecting 1"
+msgstr "chdir: chiamata con numero di argomenti errato, 1 previsto"
+
+#: extension/filefuncs.c:439
+#, c-format
+msgid "stat: unable to read symbolic link `%s'"
+msgstr "stat: non riesco a leggere il link simbolico `%s'"
+
+#: extension/filefuncs.c:472
+msgid "stat: called with wrong number of arguments"
+msgstr "stat: chiamata con numero di argomenti errato"
+
+#: extension/filefuncs.c:479
+msgid "stat: bad parameters"
+msgstr "stat: parametri errati"
+
+#: extension/filefuncs.c:533
+#, c-format
+msgid "fts init: could not create variable %s"
+msgstr "ftp init: non riesco a creare variabile %s"
+
+#: extension/filefuncs.c:554
+msgid "fts is not supported on this system"
+msgstr "fts non disponibile su questo sistema"
+
+#: extension/filefuncs.c:573
+msgid "fill_stat_element: could not create array"
+msgstr "fill_stat_element: non riesco a creare vettore"
+
+#: extension/filefuncs.c:582
+msgid "fill_stat_element: could not set element"
+msgstr "fill_stat_element: non riesco a impostare elemento"
+
+#: extension/filefuncs.c:597
+msgid "fill_path_element: could not set element"
+msgstr "fill_path_element: non riesco a impostare elemento"
+
+#: extension/filefuncs.c:613
+msgid "fill_error_element: could not set element"
+msgstr "fill_error_element: non riesco a impostare elemento"
+
+#: extension/filefuncs.c:660 extension/filefuncs.c:707
+msgid "fts-process: could not create array"
+msgstr "fts-process: non riesco a creare vettore"
+
+#: extension/filefuncs.c:670 extension/filefuncs.c:717
+#: extension/filefuncs.c:735
+msgid "fts-process: could not set element"
+msgstr "fts-process: non riesco a impostare elemento"
+
+#: extension/filefuncs.c:784
+msgid "fts: called with incorrect number of arguments, expecting 3"
+msgstr "fts: chiamata con numero di argomenti errato, 3 previsti"
+
+#: extension/filefuncs.c:787
+msgid "fts: bad first parameter"
+msgstr "fts: primo parametro errato"
+
+#: extension/filefuncs.c:793
+msgid "fts: bad second parameter"
+msgstr "fts: secondo parametro errato"
+
+#: extension/filefuncs.c:799
+msgid "fts: bad third parameter"
+msgstr "fts: terzo parametro errato"
+
+#: extension/filefuncs.c:806
+msgid "fts: could not flatten array\n"
+msgstr "fts: non sono riuscito a appiattire un vettore\n"
+
+#: extension/filefuncs.c:824
+msgid "fts: ignoring sneaky FTS_NOSTAT flag. nyah, nyah, nyah."
+msgstr "fts: ignoro flag infido FTS_NOSTAT. nooo, nooo, nooo."
+
+#: extension/filefuncs.c:841
+msgid "fts: clear_array() failed\n"
+msgstr "fts: clear_array() non riuscita\n"
+
+#: extension/fnmatch.c:112
+msgid "fnmatch: called with less than three arguments"
+msgstr "fnmatch: chiamata con meno di tre argomenti"
+
+#: extension/fnmatch.c:115
+msgid "fnmatch: called with more than three arguments"
+msgstr "fnmatch: chiamata con più di tre argomenti"
+
+#: extension/fnmatch.c:118
+msgid "fnmatch: could not get first argument"
+msgstr "fnmatch: primo argomento non disponibile"
+
+#: extension/fnmatch.c:123
+msgid "fnmatch: could not get second argument"
+msgstr "fnmatch: secondo argomento non disponibile"
+
+#: extension/fnmatch.c:128
+msgid "fnmatch: could not get third argument"
+msgstr "fnmatch: terzo argomento non disponibile"
+
+#: extension/fnmatch.c:141
+msgid "fnmatch is not implemented on this system\n"
+msgstr "fnmatch non disponibile su questo sistema\n"
+
+#: extension/fnmatch.c:173
+msgid "fnmatch init: could not add FNM_NOMATCH variable"
+msgstr "fnmatch init: non riesco ad aggiungere variabile FNM_NOMATCH"
+
+#: extension/fnmatch.c:183
+#, c-format
+msgid "fnmatch init: could not set array element %s"
+msgstr "fnmatch init: non riesco a impostare elemento vettoriale %s"
+
+#: extension/fnmatch.c:193
+msgid "fnmatch init: could not install FNM array"
+msgstr "fnmatch init: non riesco a installare vettore FNM"
+
+#: extension/fork.c:81
+msgid "fork: called with too many arguments"
+msgstr "fork: chiamata con troppi argomenti"
+
+#: extension/fork.c:94
+msgid "fork: PROCINFO is not an array!"
+msgstr "fork: PROCINFO non è un vettore!"
+
+#: extension/fork.c:118
+msgid "waitpid: called with too many arguments"
+msgstr "waitpid: chiamata con troppi argomenti"
+
+#: extension/fork.c:126
+msgid "wait: called with no arguments"
+msgstr "wait: chiamata senza argomenti"
+
+#: extension/fork.c:143
+msgid "wait: called with too many arguments"
+msgstr "wait: chiamata con troppi argomenti"
+
+#: extension/inplace.c:130
+msgid "inplace_begin: in-place editing already active"
+msgstr "inplace_begin: modifica in-place già attiva"
+
+#: extension/inplace.c:133 extension/inplace.c:210
+#, c-format
+msgid "inplace_begin: expects 2 arguments but called with %d"
+msgstr "inplace_begin: 2 argumenti richiesti, ma chiamata con %d"
+
+#: extension/inplace.c:136
+msgid "inplace_begin: cannot retrieve 1st argument as a string filename"
+msgstr ""
+"inplace_begin: non riesco a trovare il 1° argomento come stringa nome-file"
+
+#: extension/inplace.c:144
+#, c-format
+msgid "inplace_begin: disabling in-place editing for invalid FILENAME `%s'"
+msgstr ""
+"inplace_begin: modifica in-place disabilitato, FILENAME non valido `%s'"
+
+#: extension/inplace.c:151
+#, c-format
+msgid "inplace_begin: Cannot stat `%s' (%s)"
+msgstr "inplace_begin: Non riesco a trovare `%s' (%s)"
+
+#: extension/inplace.c:158
+#, c-format
+msgid "inplace_begin: `%s' is not a regular file"
+msgstr "inplace_begin: `%s' non è un file regolare"
+
+#: extension/inplace.c:169
+#, c-format
+msgid "inplace_begin: mkstemp(`%s') failed (%s)"
+msgstr "inplace_begin: mkstemp(`%s') non riuscita (%s)"
+
+#: extension/inplace.c:181
+#, c-format
+msgid "inplace_begin: chmod failed (%s)"
+msgstr "inplace_begin: chmod non riuscita (%s)"
+
+#: extension/inplace.c:188
+#, c-format
+msgid "inplace_begin: dup(stdout) failed (%s)"
+msgstr "inplace_begin: dup(stdout) non riuscita (%s)"
+
+#: extension/inplace.c:191
+#, c-format
+msgid "inplace_begin: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_begin: dup2(%d, stdout) non riuscita (%s)"
+
+#: extension/inplace.c:194
+#, c-format
+msgid "inplace_begin: close(%d) failed (%s)"
+msgstr "inplace_begin: close(%d) non riuscita (%s)"
+
+#: extension/inplace.c:213
+msgid "inplace_end: cannot retrieve 1st argument as a string filename"
+msgstr ""
+"inplace_end: non riesco a trovare il 1° argomento come stringa nome-file"
+
+#: extension/inplace.c:220
+msgid "inplace_end: in-place editing not active"
+msgstr "inplace_end: modifica in-place non attiva"
+
+#: extension/inplace.c:226
+#, c-format
+msgid "inplace_end: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_end: dup2(%d, stdout) non riuscita (%s)"
+
+#: extension/inplace.c:229
+#, c-format
+msgid "inplace_end: close(%d) failed (%s)"
+msgstr "inplace_end: close(%d) non riuscita (%s)"
+
+#: extension/inplace.c:233
+#, c-format
+msgid "inplace_end: fsetpos(stdout) failed (%s)"
+msgstr "inplace_end: fsetpos(stdout) non riuscita (%s)"
+
+#: extension/inplace.c:246
+#, c-format
+msgid "inplace_end: link(`%s', `%s') failed (%s)"
+msgstr "inplace_end: link(`%s', `%s') non riuscita (%s)"
+
+#: extension/inplace.c:256
+#, c-format
+msgid "inplace_end: rename(`%s', `%s') failed (%s)"
+msgstr "inplace_end: rename(`%s', `%s') non riuscito (%s)"
+
+#: extension/ordchr.c:69
+msgid "ord: called with too many arguments"
+msgstr "ord: chiamata con troppi argomenti"
+
+#: extension/ordchr.c:75
+msgid "ord: called with no arguments"
+msgstr "ord: chiamata senza argomenti"
+
+#: extension/ordchr.c:77
+msgid "ord: called with inappropriate argument(s)"
+msgstr "ord: chiamata con argomento/i non corretto/i"
+
+#: extension/ordchr.c:99
+msgid "chr: called with too many arguments"
+msgstr "chr: chiamata con troppi argomenti"
+
+#: extension/ordchr.c:109
+msgid "chr: called with no arguments"
+msgstr "chr: chiamata senza argomenti"
+
+#: extension/ordchr.c:111
+msgid "chr: called with inappropriate argument(s)"
+msgstr "chr: chiamata con argomento/i non corretto/i"
+
+#: extension/readdir.c:281
+#, c-format
+msgid "dir_take_control_of: opendir/fdopendir failed: %s"
+msgstr "dir_take_control_of: opendir/fdopendir non riuscita: %s"
+
+#: extension/readfile.c:113
+msgid "readfile: called with too many arguments"
+msgstr "readfile: chiamata con troppi argomenti"
+
+#: extension/readfile.c:137
+msgid "readfile: called with no arguments"
+msgstr "readfile: chiamata senza argomenti"
+
+#: extension/rwarray.c:124
+msgid "writea: called with too many arguments"
+msgstr "writea: chiamata con troppi argomenti"
+
+#: extension/rwarray.c:131
+#, c-format
+msgid "do_writea: argument 0 is not a string\n"
+msgstr "do_writea: argomento 0 non è una stringa\n"
+
+#: extension/rwarray.c:137
+#, c-format
+msgid "do_writea: argument 1 is not an array\n"
+msgstr "do_writea: argomento 1 non-vettoriale\n"
+
+#: extension/rwarray.c:184
+#, c-format
+msgid "write_array: could not flatten array\n"
+msgstr "write_array: non sono riuscito a appiattire un vettore\n"
+
+#: extension/rwarray.c:198
+#, c-format
+msgid "write_array: could not release flattened array\n"
+msgstr "write_array: non sono riuscito a rilasciare un vettore appiattito\n"
-#: field.c:328
+#: extension/rwarray.c:280
+msgid "reada: called with too many arguments"
+msgstr "reada: chiamata con troppi argomenti"
+
+#: extension/rwarray.c:287
+#, c-format
+msgid "do_reada: argument 0 is not a string\n"
+msgstr "do_reada: argomento 0 non è una stringa\n"
+
+#: extension/rwarray.c:293
+#, c-format
+msgid "do_reada: argument 1 is not an array\n"
+msgstr "do_reada: argomento 1 non-vettoriale\n"
+
+#: extension/rwarray.c:337
+#, c-format
+msgid "do_reada: clear_array failed\n"
+msgstr "do_reada: clear_array non riuscita\n"
+
+#: extension/rwarray.c:374
+#, c-format
+msgid "read_array: set_array_element failed\n"
+msgstr "read_array: set_array_element non riuscita\n"
+
+#: extension/time.c:113
+msgid "gettimeofday: ignoring arguments"
+msgstr "gettimeofday: ignoro argomenti"
+
+#: extension/time.c:144
+msgid "gettimeofday: not supported on this platform"
+msgstr "gettimeofday: non supportato in questa architettura"
+
+#: extension/time.c:165
+msgid "sleep: called with too many arguments"
+msgstr "sleep: chiamata con troppi argomenti"
+
+#: extension/time.c:168
+msgid "sleep: missing required numeric argument"
+msgstr "sleep: manca necessario argomento numerico"
+
+#: extension/time.c:174
+msgid "sleep: argument is negative"
+msgstr "sleep: l'argomento è negativo"
+
+#: extension/time.c:208
+msgid "sleep: not supported on this platform"
+msgstr "sleep: non supportato in questa architettura"
+
+#: field.c:346
msgid "NF set to negative value"
msgstr "NF impostato a un valore negativo"
-#: field.c:951 field.c:958 field.c:962
+#: field.c:958 field.c:965 field.c:969
msgid "split: fourth argument is a gawk extension"
msgstr "split: il quarto argomento è un'estensione gawk"
-#: field.c:955
+#: field.c:962
msgid "split: fourth argument is not an array"
-msgstr "split: il quarto argomento non è un vettore"
+msgstr "split: quarto argomento non-vettoriale"
-#: field.c:969
+#: field.c:976
msgid "split: second argument is not an array"
-msgstr "split: il secondo argomento non è un vettore"
+msgstr "split: secondo argomento non-vettoriale"
-#: field.c:973
-#, fuzzy
+#: field.c:980
msgid "split: cannot use the same array for second and fourth args"
msgstr ""
-"split: non si può usare lo stesso vettore come secondo e quarto argomento"
+"split: non si può usare un unico vettore come secondo e quarto argomento"
-#: field.c:978
-#, fuzzy
+#: field.c:985
msgid "split: cannot use a subarray of second arg for fourth arg"
msgstr ""
-"split: non si può usare lo stesso vettore come secondo e quarto argomento"
+"split: non consentito un quarto argomento che sia un sottovettore del "
+"secondo argomento"
-#: field.c:981
-#, fuzzy
+#: field.c:988
msgid "split: cannot use a subarray of fourth arg for second arg"
msgstr ""
-"split: non si può usare lo stesso vettore come secondo e quarto argomento"
+"split: non consentito un secondo argomento che sia un sottovettore del "
+"quarto argomento"
-#: field.c:1010
+#: field.c:1019
msgid "split: null string for third arg is a gawk extension"
msgstr "split: la stringa nulla come terzo arg. è un'estensione gawk"
-#: field.c:1050
+#: field.c:1059
msgid "patsplit: fourth argument is not an array"
-msgstr "patsplit: il secondo argomento non è un vettore"
+msgstr "patsplit: secondo argomento non-vettoriale"
-#: field.c:1055
+#: field.c:1064
msgid "patsplit: second argument is not an array"
-msgstr "patsplit: il secondo argomento non è un vettore"
+msgstr "patsplit: secondo argomento non-vettoriale"
-#: field.c:1061
+#: field.c:1070
msgid "patsplit: third argument must be non-null"
msgstr "patsplit: il terzo argomento non può essere nullo"
-#: field.c:1065
-#, fuzzy
+#: field.c:1074
msgid "patsplit: cannot use the same array for second and fourth args"
msgstr ""
-"patsplit: non si può usare lo stesso vettore come secondo e quarto argomento"
+"patsplit: non si può usare un unico vettore come secondo e quarto argomento"
-#: field.c:1070
-#, fuzzy
+#: field.c:1079
msgid "patsplit: cannot use a subarray of second arg for fourth arg"
msgstr ""
-"patsplit: non si può usare lo stesso vettore come secondo e quarto argomento"
+"patsplit: non consentito un quarto argomento che sia un sottovettore del "
+"secondo argomento"
-#: field.c:1073
-#, fuzzy
+#: field.c:1082
msgid "patsplit: cannot use a subarray of fourth arg for second arg"
msgstr ""
-"patsplit: non si può usare lo stesso vettore come secondo e quarto argomento"
+"patsplit: non consentito un secondo argomento che sia un sottovettore del "
+"quarto argomento"
-#: field.c:1110
+#: field.c:1120
msgid "`FIELDWIDTHS' is a gawk extension"
msgstr "`FIELDWIDTHS' è un'estensione gawk"
-#: field.c:1173
+#: field.c:1184
#, c-format
msgid "invalid FIELDWIDTHS value, near `%s'"
msgstr "valore di FIELDWIDTHS non valido, vicino a `%s'"
-#: field.c:1246
+#: field.c:1257
msgid "null string for `FS' is a gawk extension"
msgstr "la stringa nulla usata come `FS' è un'estensione gawk"
-#: field.c:1250
+#: field.c:1261
msgid "old awk does not support regexps as value of `FS'"
msgstr "il vecchio awk non supporta espressioni come valori di `FS'"
-#: field.c:1369
+#: field.c:1380
msgid "`FPAT' is a gawk extension"
msgstr "`FPAT' è un'estensione gawk"
-#: getopt.c:574 getopt.c:590
+#: gawkapi.c:146
+msgid "awk_value_to_node: received null retval"
+msgstr "awk_value_to_node: ricevuto retval nullo"
+
+#: gawkapi.c:384
+msgid "node_to_awk_value: received null node"
+msgstr "node_to_awk_value: ricevuto nodo nullo"
+
+#: gawkapi.c:387
+msgid "node_to_awk_value: received null val"
+msgstr "node_to_awk_value: ricevuto valore nullo"
+
+#: gawkapi.c:810
+msgid "remove_element: received null array"
+msgstr "remove_element: ricevuto vettore nullo"
+
+#: gawkapi.c:813
+msgid "remove_element: received null subscript"
+msgstr "remove_element: ricevuto indice nullo"
+
+#: gawkapi.c:950
#, c-format
-msgid "%s: option '%s' is ambiguous\n"
-msgstr "%s: opzione '%s' ambigua\n"
+msgid "api_flatten_array: could not convert index %d\n"
+msgstr "api_flatten_array: non sono riuscito a convertire l'indice %d\n"
-#: getopt.c:623 getopt.c:627
+#: gawkapi.c:955
+#, c-format
+msgid "api_flatten_array: could not convert value %d\n"
+msgstr "api_flatten_array: non sono riuscito a convertire il valore %d\n"
+
+#: getopt.c:604 getopt.c:633
+#, c-format
+msgid "%s: option '%s' is ambiguous; possibilities:"
+msgstr "%s: opzione '%s' ambigua; possibilità:"
+
+#: getopt.c:679 getopt.c:683
#, c-format
msgid "%s: option '--%s' doesn't allow an argument\n"
msgstr "%s: l'opzione '--%s' non ammette un argomento\n"
-#: getopt.c:636 getopt.c:641
+#: getopt.c:692 getopt.c:697
#, c-format
msgid "%s: option '%c%s' doesn't allow an argument\n"
msgstr "%s: l'opzione '%c%s' non ammette un argomento\n"
-#: getopt.c:684 getopt.c:703
+#: getopt.c:740 getopt.c:759
#, c-format
msgid "%s: option '--%s' requires an argument\n"
msgstr "%s: l'opzione '--%s' richiede un argomento\n"
-#: getopt.c:741 getopt.c:744
+#: getopt.c:797 getopt.c:800
#, c-format
msgid "%s: unrecognized option '--%s'\n"
msgstr "%s: opzione sconosciuta '--%s'\n"
-#: getopt.c:752 getopt.c:755
+#: getopt.c:808 getopt.c:811
#, c-format
msgid "%s: unrecognized option '%c%s'\n"
msgstr "%s: opzione sconosciuta '%c%s'\n"
-#: getopt.c:804 getopt.c:807
+#: getopt.c:860 getopt.c:863
#, c-format
msgid "%s: invalid option -- '%c'\n"
msgstr "%s: opzione non valida -- '%c'\n"
-#: getopt.c:857 getopt.c:874 getopt.c:1082 getopt.c:1100
+#: getopt.c:916 getopt.c:933 getopt.c:1143 getopt.c:1161
#, c-format
msgid "%s: option requires an argument -- '%c'\n"
msgstr "%s: l'opzione richiede un argomento -- '%c'\n"
-#: getopt.c:930 getopt.c:946
+#: getopt.c:989 getopt.c:1005
#, c-format
msgid "%s: option '-W %s' is ambiguous\n"
msgstr "%s: l'opzione '-W %s' è ambigua\n"
-#: getopt.c:970 getopt.c:988
+#: getopt.c:1029 getopt.c:1047
#, c-format
msgid "%s: option '-W %s' doesn't allow an argument\n"
msgstr "%s: l'opzione '-W %s' non ammette un argomento\n"
-#: getopt.c:1009 getopt.c:1027
+#: getopt.c:1068 getopt.c:1086
#, c-format
msgid "%s: option '-W %s' requires an argument\n"
msgstr "%s: l'opzione '-W %s' richiede un argomento\n"
-#: io.c:280
+#: io.c:423
#, c-format
msgid "command line argument `%s' is a directory: skipped"
-msgstr "l'argomento in linea comando `%s' è una directory: saltato"
+msgstr "l'argomento in riga comando `%s' è una directory: ignorata"
-#: io.c:283 io.c:385
+#: io.c:426 io.c:544
#, c-format
msgid "cannot open file `%s' for reading (%s)"
msgstr "non riesco ad aprire file `%s' in lettura (%s)"
-#: io.c:501
+#: io.c:671
#, c-format
msgid "close of fd %d (`%s') failed (%s)"
-msgstr "chiusura di fd %d (`%s') fallita (%s)"
+msgstr "chiusura di fd %d (`%s') non riuscita (%s)"
-#: io.c:578
+#: io.c:749
msgid "redirection not allowed in sandbox mode"
-msgstr "re-direzione non permessa in modo 'sandbox'"
+msgstr "ri-direzione non consentita in modo `sandbox'"
-#: io.c:612
+#: io.c:783
#, c-format
msgid "expression in `%s' redirection only has numeric value"
-msgstr "espressione nella re-direzione `%s' ha solo un valore numerico"
+msgstr "espressione nella ri-direzione `%s' ha solo un valore numerico"
-#: io.c:618
+#: io.c:789
#, c-format
msgid "expression for `%s' redirection has null string value"
-msgstr "espressione nella re-direzione `%s' ha per valore la stringa nulla"
+msgstr "espressione nella ri-direzione `%s' ha per valore la stringa nulla"
-#: io.c:624
+#: io.c:794
#, 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 "
+"nome-file `%s' per la ri-direzione `%s' può essere il risultato di una "
"espressione logica"
-#: io.c:667
+#: io.c:842
#, c-format
msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
msgstr "mistura non necessaria di `>' e `>>' per il file `%.*s'"
-#: io.c:720
+#: io.c:896
#, c-format
msgid "can't open pipe `%s' for output (%s)"
-msgstr "non posso aprire 'pipe' `%s' in scrittura (%s)"
+msgstr "non riesco ad aprire `pipe' `%s' in scrittura (%s)"
-#: io.c:730
+#: io.c:906
#, c-format
msgid "can't open pipe `%s' for input (%s)"
-msgstr "non posso aprire 'pipe' `%s' in lettura (%s)"
+msgstr "non riesco ad aprire `pipe' `%s' in lettura (%s)"
-#: io.c:753
+#: io.c:937
#, 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)"
+msgstr ""
+"non riesco ad aprire `pipe' bidirezionale `%s' in lettura/scrittura (%s)"
-#: io.c:835
+#: io.c:1019
#, c-format
msgid "can't redirect from `%s' (%s)"
-msgstr "non posso re-dirigere da `%s' (%s)"
+msgstr "non riesco a ri-dirigere da `%s' (%s)"
-#: io.c:838
+#: io.c:1022
#, c-format
msgid "can't redirect to `%s' (%s)"
-msgstr "non posso re-dirigere a `%s' (%s)"
+msgstr "non riesco a ri-dirigere a `%s' (%s)"
-#: io.c:889
+#: io.c:1073
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:905
+#: io.c:1089
#, c-format
msgid "close of `%s' failed (%s)."
-msgstr "chiusura di `%s' fallita (%s)."
+msgstr "chiusura di `%s' non riuscita (%s)."
-#: io.c:913
+#: io.c:1097
msgid "too many pipes or input files open"
-msgstr "troppe 'pipe' o file di input aperti"
+msgstr "troppe `pipe' o file di input aperti"
-#: io.c:935
+#: io.c:1119
msgid "close: second argument must be `to' or `from'"
msgstr "close: il secondo argomento deve essere `a' o `da'"
-#: io.c:952
+#: io.c:1136
#, 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"
+msgstr "close: `%.*s' non è un file aperto, una `pipe' o un co-processo"
-#: io.c:957
+#: io.c:1141
msgid "close of redirection that was never opened"
-msgstr "chiusura di una re-direzione mai aperta"
+msgstr "chiusura di una ri-direzione mai aperta"
-#: io.c:1054
+#: io.c:1238
#, c-format
msgid "close: redirection `%s' not opened with `|&', second argument ignored"
-msgstr "close: re-direzione `%s' non aperta con `|&', ignoro secondo argomento"
+msgstr "close: ri-direzione `%s' non aperta con `|&', ignoro secondo argomento"
-#: io.c:1070
+#: io.c:1255
#, c-format
msgid "failure status (%d) on pipe close of `%s' (%s)"
-msgstr "errore ritornato (%d) dalla chiusura della 'pipe' `%s' (%s)"
+msgstr "errore ritornato (%d) dalla chiusura della `pipe' `%s' (%s)"
-#: io.c:1073
+#: io.c:1258
#, c-format
msgid "failure status (%d) on file close of `%s' (%s)"
msgstr "errore ritornato (%d) dalla chiusura del file `%s' (%s)"
-#: io.c:1093
+#: io.c:1278
#, c-format
msgid "no explicit close of socket `%s' provided"
-msgstr "nessuna chiusura esplicita richiesta per 'socket' `%s'"
+msgstr "nessuna chiusura esplicita richiesta per `socket' `%s'"
-#: io.c:1096
+#: io.c:1281
#, c-format
msgid "no explicit close of co-process `%s' provided"
msgstr "nessuna chiusura esplicita richiesta per co-processo `%s'"
-#: io.c:1099
+#: io.c:1284
#, c-format
msgid "no explicit close of pipe `%s' provided"
-msgstr "nessuna chiusura esplicita richiesta per 'pipe' `%s'"
+msgstr "nessuna chiusura esplicita richiesta per `pipe' `%s'"
-#: io.c:1102
+#: io.c:1287
#, c-format
msgid "no explicit close of file `%s' provided"
msgstr "nessuna chiusura esplicita richiesta per file `%s'"
-#: io.c:1130 io.c:1185 main.c:793 main.c:830
+#: io.c:1317 io.c:1375 main.c:615 main.c:657
#, c-format
msgid "error writing standard output (%s)"
msgstr "errore scrivendo 'standard output' (%s)"
-#: io.c:1134 io.c:1190
+#: io.c:1322 io.c:1381 main.c:617
#, c-format
msgid "error writing standard error (%s)"
msgstr "errore scrivendo 'standard error' (%s)"
-#: io.c:1142
+#: io.c:1330
#, c-format
msgid "pipe flush of `%s' failed (%s)."
-msgstr "scaricamento di 'pipe' `%s' fallita (%s)."
+msgstr "scaricamento di `pipe' `%s' non riuscito (%s)."
-#: io.c:1145
+#: io.c:1333
#, c-format
msgid "co-process flush of pipe to `%s' failed (%s)."
-msgstr "scaricamento da co-processo di 'pipe' a `%s' fallita (%s)."
+msgstr "scaricamento da co-processo di `pipe' a `%s' non riuscito (%s)."
-#: io.c:1148
+#: io.c:1336
#, c-format
msgid "file flush of `%s' failed (%s)."
-msgstr "scaricamento di file `%s' fallita (%s)."
+msgstr "scaricamento di file `%s' non riuscito (%s)."
-#: io.c:1263
+#: io.c:1453
#, c-format
msgid "local port %s invalid in `/inet'"
msgstr "porta locale %s invalida in `/inet'"
-#: io.c:1280
+#: io.c:1471
#, c-format
msgid "remote host and port information (%s, %s) invalid"
msgstr "host remoto e informazione di porta (%s, %s) invalidi"
-#: io.c:1432
-#, c-format
-msgid "no (known) protocol supplied in special filename `%s'"
-msgstr "nessuno protocollo (noto) specificato nel filename speciale `%s'"
-
-#: io.c:1446
-#, c-format
-msgid "special file name `%s' is incomplete"
-msgstr "nome-file speciale `%s' incompleto"
-
-#: io.c:1463
-msgid "must supply a remote hostname to `/inet'"
-msgstr "va fornito nome di 'host' remoto a `/inet'"
-
-#: io.c:1481
-msgid "must supply a remote port to `/inet'"
-msgstr "va fornita porta remota a `/inet'"
-
-#: io.c:1527
+#: io.c:1673
msgid "TCP/IP communications are not supported"
msgstr "comunicazioni TCP/IP non supportate"
-#: io.c:1694
+#: io.c:1854
#, c-format
msgid "could not open `%s', mode `%s'"
msgstr "non riesco ad aprire `%s', modo `%s'"
-#: io.c:1748
+#: io.c:1904
#, c-format
msgid "close of master pty failed (%s)"
-msgstr "fallita chiusura di 'pty' principale (%s)"
+msgstr "close di `pty' principale non riuscita (%s)"
-#: io.c:1750 io.c:1918 io.c:2075
+#: io.c:1906 io.c:2092 io.c:2293
#, c-format
msgid "close of stdout in child failed (%s)"
-msgstr "fallita chiusura di 'stdout' nel processo-figlio (%s)"
+msgstr "close di `stdout' nel processo-figlio non riuscita (%s)"
-#: io.c:1753
+#: io.c:1909
#, 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)"
+"trasferimento di `pty' secondaria a `stdout' nel processo-figlio non "
+"riuscita (dup: %s)"
-#: io.c:1755 io.c:1923
+#: io.c:1911 io.c:2097
#, c-format
msgid "close of stdin in child failed (%s)"
-msgstr "fallita chiusura di 'stdin' nel processo-figlio (%s)"
+msgstr "close di `stdin' nel processo-figlio non riuscita (%s)"
-#: io.c:1758
+#: io.c:1914
#, c-format
msgid "moving slave pty to stdin in child failed (dup: %s)"
msgstr ""
-"fallito trasferimento di 'pty' secondaria a 'stdin' nel processo-figlio "
+"trasferimento di 'pty' secondaria a 'stdin' nel processo-figlio non riuscito "
"(dup: %s)"
-#: io.c:1760 io.c:1781
+#: io.c:1916 io.c:1938
#, c-format
msgid "close of slave pty failed (%s)"
-msgstr "fallita chiusura di 'pty' secondaria (%s)"
+msgstr "close di 'pty' secondaria non riuscita (%s)"
-#: io.c:1859 io.c:1921 io.c:2053 io.c:2078
+#: io.c:2027 io.c:2095 io.c:2264 io.c:2296
#, c-format
msgid "moving pipe to stdout in child failed (dup: %s)"
-msgstr "fallito passaggio di 'pipe' a 'stdout' nel processo-figlio (dup: %s)"
+msgstr ""
+"passaggio di `pipe' a `stdout' nel processo-figlio non riuscito (dup: %s)"
-#: io.c:1866 io.c:1926
+#: io.c:2034 io.c:2100
#, c-format
msgid "moving pipe to stdin in child failed (dup: %s)"
-msgstr "fallito passaggio di pipe a 'stdin' nel processo-figlio (dup: %s)"
+msgstr ""
+"passaggio di pipe a `stdin' nel processo-figlio non riuscito (dup: %s)"
-#: io.c:1886 io.c:2068
+#: io.c:2060 io.c:2286
msgid "restoring stdout in parent process failed\n"
-msgstr "fallito ripristino di 'stdout' nel processo-padre\n"
+msgstr "ripristino di `stdout' nel processo-padre non riuscito\n"
-#: io.c:1894
+#: io.c:2068
msgid "restoring stdin in parent process failed\n"
-msgstr "fallito ripristino di 'stdin' nel processo-padre\n"
+msgstr "ripristino di `stdin' nel processo-padre non riuscito\n"
-#: io.c:1929 io.c:2080 io.c:2094
+#: io.c:2103 io.c:2298 io.c:2313
#, c-format
msgid "close of pipe failed (%s)"
-msgstr "fallita chiusura di 'pipe' (%s)"
+msgstr "close di 'pipe' non riuscita (%s)"
-#: io.c:1974
+#: io.c:2162
msgid "`|&' not supported"
msgstr "`|&' non supportato"
-#: io.c:2040
+#: io.c:2249
#, c-format
msgid "cannot open pipe `%s' (%s)"
-msgstr "non riesco ad aprire 'pipe' `%s' (%s)"
+msgstr "non riesco ad aprire `pipe' `%s' (%s)"
-#: io.c:2088
+#: io.c:2307
#, c-format
msgid "cannot create child process for `%s' (fork: %s)"
msgstr "non riesco a creare processo-figlio per `%s' (fork: %s)"
-#: io.c:2521
+#: io.c:2734
+msgid "register_input_parser: received NULL pointer"
+msgstr "register_input_parser: ricevuto puntatore NULL"
+
+#: io.c:2762
+#, c-format
+msgid "input parser `%s' conflicts with previously installed input parser `%s'"
+msgstr ""
+"input parser `%s' in conflitto con l'input parser `%s' installato in "
+"precedenza"
+
+#: io.c:2769
+#, c-format
+msgid "input parser `%s' failed to open `%s'"
+msgstr "l'input parser `%s' non è riuscito ad aprire `%s'"
+
+#: io.c:2789
+msgid "register_output_wrapper: received NULL pointer"
+msgstr "register_output_wrapper: ricevuto puntatore NULL"
+
+#: io.c:2817
+#, c-format
+msgid ""
+"output wrapper `%s' conflicts with previously installed output wrapper `%s'"
+msgstr ""
+"output wrapper `%s' in conflitto con l'output wrapper `%s' installato in "
+"precedenza"
+
+#: io.c:2824
+#, c-format
+msgid "output wrapper `%s' failed to open `%s'"
+msgstr "l'output wrapper `%s' non è riuscito ad aprire `%s'"
+
+#: io.c:2845
+msgid "register_output_processor: received NULL pointer"
+msgstr "register_output_processor: ricevuto puntatore NULL"
+
+#: io.c:2874
+#, c-format
+msgid ""
+"two-way processor `%s' conflicts with previously installed two-way processor "
+"`%s'"
+msgstr ""
+"processore doppio `%s' in conflitto con il processore doppio installato in "
+"precedenza `%s'"
+
+#: io.c:2883
+#, c-format
+msgid "two way processor `%s' failed to open `%s'"
+msgstr "il processore doppio `%s' non è riuscito ad aprire `%s'"
+
+#: io.c:3008
#, c-format
msgid "data file `%s' is empty"
msgstr "file dati `%s' vuoto"
-#: io.c:2562 io.c:2570
+#: io.c:3050 io.c:3058
msgid "could not allocate more input memory"
msgstr "non riesco ad allocare ulteriore memoria per l'input"
-#: io.c:3128
+#: io.c:3636
msgid "multicharacter value of `RS' is a gawk extension"
msgstr "valore multicarattere per `RS' è un'estensione gawk"
-#: io.c:3233
+#: io.c:3783
msgid "IPv6 communication is not supported"
msgstr "comunicazioni IPv6 non supportate"
-#: main.c:364
-msgid "`-m[fr]' option irrelevant in gawk"
-msgstr "`-m[fr]' opzione irrilevante per gawk"
-
-#: main.c:366
-msgid "-m option usage: `-m[fr] nnn'"
-msgstr "-m uso opzione: `-m[fr] nnn'"
-
-#: main.c:389
-msgid "empty argument to `-e/--source' ignored"
-msgstr "argomento di `-e/--source' nullo, ignorato"
-
-#: main.c:460
-#, c-format
-msgid "%s: option `-W %s' unrecognized, ignored\n"
-msgstr "%s: opzione `-W %s' non riconosciuta, ignorata\n"
-
-#: main.c:513
-#, c-format
-msgid "%s: option requires an argument -- %c\n"
-msgstr "%s: l'opzione richiede un argomento -- %c\n"
-
-#: main.c:534
+#: main.c:309
msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
msgstr "variable d'ambiente `POSIXLY_CORRECT' impostata: attivo `--posix'"
-#: main.c:540
+#: main.c:315
msgid "`--posix' overrides `--traditional'"
msgstr "`--posix' annulla `--traditional'"
-#: main.c:551
+#: main.c:326
msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
msgstr "`--posix'/`--traditional' annulla `--non-decimal-data'"
-#: main.c:555
+#: main.c:330
#, 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"
+msgstr "eseguire %s con `setuid' root può essere un rischio per la sicurezza"
-#: main.c:560
-msgid "`--posix' overrides `--binary'"
-msgstr "`--posix' annulla `--binary"
+#: main.c:334
+msgid "`--posix' overrides `--characters-as-bytes'"
+msgstr "`--posix' annulla `--characters-as-bytes'"
-#: main.c:611
+#: main.c:392
#, c-format
msgid "can't set binary mode on stdin (%s)"
-msgstr "non posso impostare modalità binaria su 'stdin'(%s)"
+msgstr "non è possibile impostare modalità binaria su `stdin'(%s)"
-#: main.c:614
+#: main.c:395
#, c-format
msgid "can't set binary mode on stdout (%s)"
-msgstr "non posso impostare modalità binaria su 'stdout'(%s)"
+msgstr "non è possibile impostare modalità binaria su `stdout'(%s)"
-#: main.c:616
+#: main.c:397
#, c-format
msgid "can't set binary mode on stderr (%s)"
-msgstr "non posso impostare modalità binaria su 'stderr'(%s)"
+msgstr "non è possibile impostare modalità binaria su `stderr'(%s)"
-#: main.c:655
+#: main.c:457
msgid "no program text at all!"
msgstr "manca del tutto il testo del programma!"
-#: main.c:733
+#: main.c:550
#, c-format
msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
msgstr "Uso: %s [opzioni in stile POSIX o GNU] -f file-prog. [--] file ...\n"
-#: main.c:735
+#: main.c:552
#, 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:740
+#: main.c:557
msgid "POSIX options:\t\tGNU long options: (standard)\n"
msgstr "Opzioni POSIX:\t\topzioni lunghe GNU: (standard)\n"
-#: main.c:741
+#: main.c:558
msgid "\t-f progfile\t\t--file=progfile\n"
msgstr "\t-f fileprog\t\t--file=file-prog.\n"
-#: main.c:742
+#: main.c:559
msgid "\t-F fs\t\t\t--field-separator=fs\n"
msgstr "\t-F fs\t\t\t--field-separator=fs\n"
-#: main.c:743
+#: main.c:560
msgid "\t-v var=val\t\t--assign=var=val\n"
msgstr "\t-v var=valore\t\t--assign=var=valore\n"
-#: main.c:744
+#: main.c:561
msgid "Short options:\t\tGNU long options: (extensions)\n"
msgstr "Opzioni brevi:\t\topzioni lunghe GNU: (estensioni)\n"
-#: main.c:745
+#: main.c:562
msgid "\t-b\t\t\t--characters-as-bytes\n"
msgstr "\t-b\t\t\t--characters-as-bytes\n"
-#: main.c:746
+#: main.c:563
msgid "\t-c\t\t\t--traditional\n"
msgstr "\t-c\t\t\t--traditional\n"
-#: main.c:747
+#: main.c:564
msgid "\t-C\t\t\t--copyright\n"
msgstr "\t-C\t\t\t--copyright\n"
-#: main.c:748
-#, fuzzy
+#: main.c:565
msgid "\t-d[file]\t\t--dump-variables[=file]\n"
-msgstr "\t-d [file]\t\t--dump-variables[=file]\n"
+msgstr "\t-d[file]\t\t--dump-variables[=file]\n"
+
+#: main.c:566
+msgid "\t-D[file]\t\t--debug[=file]\n"
+msgstr "\t-D[file]\t\t--debug[=file]\n"
-#: main.c:749
+#: main.c:567
msgid "\t-e 'program-text'\t--source='program-text'\n"
msgstr "\t-e 'testo-del-programma'\t--source='testo-del-programma'\n"
-#: main.c:750
+#: main.c:568
msgid "\t-E file\t\t\t--exec=file\n"
msgstr "\t-E file\t\t\t--exec=file\n"
-#: main.c:751
+#: main.c:569
msgid "\t-g\t\t\t--gen-pot\n"
msgstr "\t-g\t\t\t--gen-pot\n"
-#: main.c:752
+#: main.c:570
msgid "\t-h\t\t\t--help\n"
msgstr "\t-h\t\t\t--help\n"
-#: main.c:753
-msgid "\t-L [fatal]\t\t--lint[=fatal]\n"
-msgstr "\t-L [fatal]\t\t--lint[=fatal]\n"
+#: main.c:571
+msgid "\t-i includefile\t\t--include=includefile\n"
+msgstr "\t-i include_file\t\t--include=include_file\n"
-#: main.c:754
-msgid "\t-n\t\t\t--non-decimal-data\n"
-msgstr "\t-n\t\t\t--non-decimal-data\n"
+#: main.c:572
+msgid "\t-l library\t\t--load=library\n"
+msgstr "\t-l libreria\t\t--load=libreria\n"
-#: main.c:755
+#: main.c:573
+msgid "\t-L[fatal|invalid]\t--lint[=fatal|invalid]\n"
+msgstr "\t-L[fatal|invalid]\t--lint[=fatal|invalid]\n"
+
+#: main.c:574
+msgid "\t-M\t\t\t--bignum\n"
+msgstr "\t-M\t\t\t--bignum\n"
+
+#: main.c:575
msgid "\t-N\t\t\t--use-lc-numeric\n"
msgstr "\t-N\t\t\t--use-lc-numeric\n"
-#: main.c:756
+#: main.c:576
+msgid "\t-n\t\t\t--non-decimal-data\n"
+msgstr "\t-n\t\t\t--non-decimal-data\n"
+
+#: main.c:577
+msgid "\t-o[file]\t\t--pretty-print[=file]\n"
+msgstr "\t-o[file]\t\t--pretty-print[=file]\n"
+
+#: main.c:578
msgid "\t-O\t\t\t--optimize\n"
msgstr "\t-O\t\t\t--optimize\n"
-#: main.c:757
-#, fuzzy
+#: main.c:579
msgid "\t-p[file]\t\t--profile[=file]\n"
-msgstr "\t-p [file]\t\t--profile[=file]\n"
+msgstr "\t-p[file]\t\t--profile[=file]\n"
-#: main.c:758
+#: main.c:580
msgid "\t-P\t\t\t--posix\n"
msgstr "\t-P\t\t\t--posix\n"
-#: main.c:759
+#: main.c:581
msgid "\t-r\t\t\t--re-interval\n"
msgstr "\t-r\t\t\t--re-interval\n"
-#: main.c:761
-msgid "\t-R file\t\t\t--command=file\n"
-msgstr "\t-R file\t\t\t--command=file\n"
-
-#: main.c:762
+#: main.c:582
msgid "\t-S\t\t\t--sandbox\n"
msgstr "\t-S\t\t\t--sandbox\n"
-#: main.c:763
+#: main.c:583
msgid "\t-t\t\t\t--lint-old\n"
msgstr "\t-t\t\t\t--lint-old\n"
-#: main.c:764
+#: main.c:584
msgid "\t-V\t\t\t--version\n"
msgstr "\t-V\t\t\t--version\n"
-#: main.c:766
+#: main.c:586
msgid "\t-W nostalgia\t\t--nostalgia\n"
msgstr "\t-W nostalgia\t\t--nostalgia\n"
-#: main.c:769
+#: main.c:589
msgid "\t-Y\t\t--parsedebug\n"
msgstr "\t-Y\t\t--parsedebug\n"
@@ -1808,7 +3128,7 @@ msgstr "\t-Y\t\t--parsedebug\n"
#. for this application. Please add _another line_ with the
#. address for translation bugs.
#. no-wrap
-#: main.c:778
+#: main.c:598
msgid ""
"\n"
"To report bugs, see node `Bugs' in `gawk.info', which is\n"
@@ -1818,9 +3138,10 @@ msgstr ""
"\n"
"Per segnalare problemi, vedi nodo `Bugs' in `gawk.info', oppure la\n"
"sezione `Reporting Problems and Bugs' nella versione a stampa.\n"
+"Problemi di traduzione, segnalare ad: azc100@gmail.com.\n"
"\n"
-#: main.c:782
+#: main.c:602
msgid ""
"gawk is a pattern scanning and processing language.\n"
"By default it reads standard input and writes standard output.\n"
@@ -1830,7 +3151,7 @@ msgstr ""
"Senza parametri, legge da 'standard input' e scrive su 'standard output'.\n"
"\n"
-#: main.c:786
+#: main.c:606
msgid ""
"Examples:\n"
"\tgawk '{ sum += $1 }; END { print sum }' file\n"
@@ -1840,7 +3161,7 @@ msgstr ""
"\tgawk '{ sum += $1 }; END { print sum }' file\n"
"\tgawk -F: '{ print $1 }' /etc/passwd\n"
-#: main.c:806
+#: main.c:631
#, c-format
msgid ""
"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
@@ -1859,7 +3180,7 @@ msgstr ""
"Licenza, o (a tua scelta) a una qualsiasi versione successiva.\n"
"\n"
-#: main.c:814
+#: main.c:639
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"
@@ -1873,7 +3194,7 @@ msgstr ""
"Vedi la 'GNU General Public License' per ulteriori dettagli.\n"
"\n"
-#: main.c:820
+#: main.c:645
msgid ""
"You should have received a copy of the GNU General Public License\n"
"along with this program. If not, see http://www.gnu.org/licenses/.\n"
@@ -1882,16 +3203,16 @@ msgstr ""
"assieme a questo programma; se non è così, vedi http://www.gnu.org/"
"licenses/.\n"
-#: main.c:855
+#: main.c:682
msgid "-Ft does not set FS to tab in POSIX awk"
-msgstr "-Ft non imposta FS a 'tab' nell'awk POSIX"
+msgstr "-Ft non imposta FS a `tab' nell'awk POSIX"
-#: main.c:1089
+#: main.c:973
#, c-format
msgid "unknown value for field spec: %d\n"
msgstr "valore non noto per specifica campo: %d\n"
-#: main.c:1170
+#: main.c:1071
#, c-format
msgid ""
"%s: `%s' argument to `-v' not in `var=value' form\n"
@@ -1900,85 +3221,143 @@ msgstr ""
"%s: `%s' argomento di `-v' non in forma `var=valore'\n"
"\n"
-#: main.c:1196
+#: main.c:1097
#, c-format
msgid "`%s' is not a legal variable name"
msgstr "`%s' non è un nome di variabile ammesso"
-#: main.c:1199
+#: main.c:1100
#, 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:1203
-#, fuzzy, c-format
+#: main.c:1104
+#, c-format
msgid "cannot use gawk builtin `%s' as variable name"
-msgstr ""
-"estensione: nome funzione interna gawk `%s' non ammesso come nome funzione"
+msgstr "nome funzione interna gawk `%s' non ammesso come nome variabile"
-#: main.c:1208
-#, fuzzy, c-format
+#: main.c:1109
+#, c-format
msgid "cannot use function `%s' as variable name"
-msgstr "non posso usare nome di funzione `%s' come variabile o vettore"
+msgstr "non è possibile usare nome di funzione `%s' come nome di variabile"
-#: main.c:1261
+#: main.c:1162
msgid "floating point exception"
msgstr "eccezione floating point"
-#: main.c:1268
+#: main.c:1169
msgid "fatal error: internal error"
msgstr "errore fatale: errore interno"
-#: main.c:1283
+#: main.c:1184
msgid "fatal error: internal error: segfault"
msgstr "errore fatale: errore interno: segfault"
-#: main.c:1295
+#: main.c:1196
msgid "fatal error: internal error: stack overflow"
msgstr "errore fatale: errore interno: stack overflow"
-#: main.c:1345
+#: main.c:1255
#, c-format
msgid "no pre-opened fd %d"
-msgstr "manca 'fd' pre-aperta %d"
+msgstr "manca `fd' pre-aperta %d"
-#: main.c:1352
+#: main.c:1262
#, c-format
msgid "could not pre-open /dev/null for fd %d"
-msgstr "non riesco a pre-aprire /dev/null per 'fd' %d"
+msgstr "non riesco a pre-aprire /dev/null per `fd' %d"
+
+#: main.c:1476
+msgid "empty argument to `-e/--source' ignored"
+msgstr "argomento di `-e/--source' nullo, ignorato"
+
+#: main.c:1547
+msgid "-M ignored: MPFR/GMP support not compiled in"
+msgstr "-M ignorato: supporto per MPFR/GMP non generato"
-#: main.c:1375 main.c:1384
+#: main.c:1568
#, c-format
-msgid "could not find groups: %s"
-msgstr "non riesco a trovare gruppi: %s"
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr "%s: opzione `-W %s' non riconosciuta, ignorata\n"
-#: msg.c:63
+#: main.c:1621
#, c-format
-msgid "cmd. line:"
-msgstr "linea com.:"
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s: l'opzione richiede un argomento -- %c\n"
-#: msg.c:107
-msgid "error: "
-msgstr "errore: "
+#: mpfr.c:557
+#, c-format
+msgid "PREC value `%.*s' is invalid"
+msgstr "valore PREC `%.*s' non valido"
+
+#: mpfr.c:615
+#, c-format
+msgid "RNDMODE value `%.*s' is invalid"
+msgstr "valore di RNDMODE `%.*s' non valido"
+
+#: mpfr.c:711
+#, c-format
+msgid "%s: received non-numeric argument"
+msgstr "%s: l'argomento ricevuto non è numerico"
-#: node.c:406
+#: mpfr.c:820
+msgid "compl(%Rg): negative value will give strange results"
+msgstr "compl(%Rg): valore negativo, darà risultati strani"
+
+#: mpfr.c:824
+msgid "comp(%Rg): fractional value will be truncated"
+msgstr "comp(%Rg): valore decimale sarà troncato"
+
+#: mpfr.c:836
+#, c-format
+msgid "cmpl(%Zd): negative values will give strange results"
+msgstr "cmpl(%Zd): valori negativi, daranno risultati strani"
+
+#: mpfr.c:855
+#, c-format
+msgid "%s: received non-numeric argument #%d"
+msgstr "%s: l'argomento ricevuto non è numerico #%d"
+
+#: mpfr.c:865
+msgid "%s: argument #%d has invalid value %Rg, using 0"
+msgstr "%s: argomento #%d con valore non valido %Rg, uso 0"
+
+#: mpfr.c:877
+msgid "%s: argument #%d negative value %Rg will give strange results"
+msgstr "%s: argomento #%d con valore negativo %Rg, darà risultati strani"
+
+#: mpfr.c:883
+msgid "%s: argument #%d fractional value %Rg will be truncated"
+msgstr "%s: argomento #%d, valore decimale sarà troncato"
+
+#: mpfr.c:898
+#, c-format
+msgid "%s: argument #%d negative value %Zd will give strange results"
+msgstr "%s: argomento #%d con valore negativo %Zd, darà risultati strani"
+
+#: msg.c:68
+#, c-format
+msgid "cmd. line:"
+msgstr "riga com.:"
+
+#: node.c:409
msgid "backslash at end of string"
msgstr "'\\' a fine stringa"
-#: node.c:517
+#: node.c:488
#, c-format
msgid "old awk does not support the `\\%c' escape sequence"
msgstr "il vecchio awk non supporta la sequenza di escape '\\%c'"
-#: node.c:568
+#: node.c:539
msgid "POSIX does not allow `\\x' escapes"
msgstr "POSIX non permette escape `\\x'"
-#: node.c:574
+#: node.c:545
msgid "no hex digits in `\\x' escape sequence"
msgstr "niente cifre esadecimali nella sequenza di escape `\\x'"
-#: node.c:596
+#: node.c:566
#, c-format
msgid ""
"hex escape \\x%.*s of %d characters probably not interpreted the way you "
@@ -1987,12 +3366,12 @@ msgstr ""
"sequenza di escape esadec.\\x%.*s di %d caratteri probabilmente non "
"interpretata nel modo previsto"
-#: node.c:611
+#: node.c:581
#, c-format
msgid "escape sequence `\\%c' treated as plain `%c'"
msgstr "sequenza di escape `\\%c' considerata come semplice `%c'"
-#: node.c:750
+#: node.c:725
msgid ""
"Invalid multibyte data detected. There may be a mismatch between your data "
"and your locale."
@@ -2000,36 +3379,36 @@ msgstr ""
"Trovati dati multi-byte invalidi. Può esserci una differenza tra i dati e la "
"codifica locale."
-#: posix/gawkmisc.c:176
+#: posix/gawkmisc.c:177
#, c-format
msgid "%s %s `%s': could not get fd flags: (fcntl F_GETFD: %s)"
-msgstr "%s %s `%s': non riesco a ottenere flag 'fd': (fcntl F_GETFD: %s)"
+msgstr "%s %s `%s': non riesco a ottenere flag `fd': (fcntl F_GETFD: %s)"
-#: posix/gawkmisc.c:188
+#: posix/gawkmisc.c:189
#, c-format
msgid "%s %s `%s': could not set close-on-exec: (fcntl F_SETFD: %s)"
msgstr ""
"%s %s `%s': non riesco a impostare 'close-on-exec': (fcntl F_SETFD: %s)"
-#: profile.c:83
+#: profile.c:73
#, c-format
msgid "could not open `%s' for writing: %s"
msgstr "non riesco ad aprire `%s' in scrittura: %s"
-#: profile.c:85
+#: profile.c:75
msgid "sending profile to standard error"
msgstr "mando profilo a 'standard error'"
-#: profile.c:203
+#: profile.c:220
#, c-format
msgid ""
-"\t# %s block(s)\n"
+"\t# %s rule(s)\n"
"\n"
msgstr ""
-"\t# blocco(hi) %s\n"
+"\t# %s regola(e)\n"
"\n"
-#: profile.c:208
+#: profile.c:227
#, c-format
msgid ""
"\t# Rule(s)\n"
@@ -2038,124 +3417,121 @@ msgstr ""
"\t# Regola(e)\n"
"\n"
-#: profile.c:279
+#: profile.c:308
#, c-format
msgid "internal error: %s with null vname"
-msgstr "errore interno: %s con 'vname' nullo"
+msgstr "errore interno: %s con `vname' nullo"
-#: profile.c:952
+#: profile.c:574
+msgid "internal error: builtin with null fname"
+msgstr "errore interno: funzione interna con `fname' nullo"
+
+#: profile.c:1016
+#, c-format
+msgid ""
+"\t# Loaded extensions (-l and/or @load)\n"
+"\n"
+msgstr ""
+"\t# Estensioni caricate (-l e/o @load)\n"
+"\n"
+
+#: profile.c:1065
#, c-format
msgid "\t# gawk profile, created %s\n"
msgstr "\t# profilo gawk, creato %s\n"
-#: profile.c:1331
+#: profile.c:1607
#, c-format
msgid ""
"\n"
"\t# Functions, listed alphabetically\n"
msgstr ""
"\n"
-"\t# Funzioni, listate in ordine alfabetico\n"
+"\t# Funzioni, in ordine alfabetico\n"
-#: profile.c:1370
+#: profile.c:1658
#, c-format
msgid "redir2str: unknown redirection type %d"
-msgstr "redir2str: tipo di re-direzione non noto %d"
+msgstr "redir2str: tipo di ri-direzione non noto %d"
-#: re.c:572
-#, fuzzy, c-format
-msgid "range of the form `[%c-%c]' is locale dependent"
-msgstr "intervallo nella forma `[%c-%c]' dipende da 'locale'"
-
-#: re.c:599
+#: re.c:607
#, c-format
msgid "regexp component `%.*s' should probably be `[%.*s]'"
msgstr ""
"componente di espressione `%.*s' dovrebbe probabilmente essere `[%.*s]'"
-#: regcomp.c:132
+#: regcomp.c:131
msgid "Success"
msgstr "Successo"
-#: regcomp.c:135
+#: regcomp.c:134
msgid "No match"
msgstr "Nessuna corrispondenza"
-#: regcomp.c:138
+#: regcomp.c:137
msgid "Invalid regular expression"
msgstr "Espressione regolare invalida"
-#: regcomp.c:141
+#: regcomp.c:140
msgid "Invalid collation character"
msgstr "Carattere di ordinamento non valido"
-#: regcomp.c:144
+#: regcomp.c:143
msgid "Invalid character class name"
msgstr "Nome di 'classe di caratteri' non valido"
-#: regcomp.c:147
+#: regcomp.c:146
msgid "Trailing backslash"
msgstr "'\\' finale"
-#: regcomp.c:150
+#: regcomp.c:149
msgid "Invalid back reference"
msgstr "Riferimento indietro non valido"
-#: regcomp.c:153
-msgid "Unmatched [ or [^"
-msgstr "[ o [^ non chiusa"
+#: regcomp.c:152
+msgid "Unmatched [, [^, [:, [., or [="
+msgstr "[, [^, [:, [. o [= non chiusa"
-#: regcomp.c:156
+#: regcomp.c:155
msgid "Unmatched ( or \\("
msgstr "( o \\( non chiusa"
-#: regcomp.c:159
+#: regcomp.c:158
msgid "Unmatched \\{"
msgstr "\\{ non chiusa"
-#: regcomp.c:162
+#: regcomp.c:161
msgid "Invalid content of \\{\\}"
msgstr "Contenuto di \\{\\} non valido"
-#: regcomp.c:165
+#: regcomp.c:164
msgid "Invalid range end"
msgstr "Fine di intervallo non valido"
-#: regcomp.c:168
+#: regcomp.c:167
msgid "Memory exhausted"
msgstr "Memoria esaurita"
-#: regcomp.c:171
+#: regcomp.c:170
msgid "Invalid preceding regular expression"
msgstr "Espressione regolare precedente invalida"
-#: regcomp.c:174
+#: regcomp.c:173
msgid "Premature end of regular expression"
msgstr "Fine di espressione regolare inaspettata"
-#: regcomp.c:177
+#: regcomp.c:176
msgid "Regular expression too big"
msgstr "Espressione regolare troppo complessa"
-#: regcomp.c:180
+#: regcomp.c:179
msgid "Unmatched ) or \\)"
msgstr ") o \\) non aperta"
-#: regcomp.c:701
+#: regcomp.c:704
msgid "No previous regular expression"
msgstr "Nessuna espressione regolare precedente"
-#~ msgid "assignment is not allowed to result of builtin function"
-#~ msgstr "assegnamento non permesso al risultato di una funzione interna"
-
-#~ msgid "attempt to use array in a scalar context"
-#~ msgstr "tentativo di usare vettore in un contesto scalare"
-
-#~ msgid "sorted array traversal is a gawk extension"
-#~ msgstr "`sorted array traversal' è un'estensione gawk"
-
-#~ msgid "`PROCINFO[\"sorted_in\"]' value is not recognized"
-#~ msgstr "`PROCINFO[\"sorted_in\"]' valore non riconosciuto"
-
-#~ msgid "out of memory"
-#~ msgstr "memoria esaurita"
+#: symbol.c:749
+msgid "can not pop main context"
+msgstr "non posso salire più in alto nello stack"
diff --git a/po/ja.gmo b/po/ja.gmo
index f00953e0..64b16819 100644
--- a/po/ja.gmo
+++ b/po/ja.gmo
Binary files differ
diff --git a/po/ja.po b/po/ja.po
index c78d3215..19321711 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -1,15 +1,15 @@
# Japanese messages for gawk.
-# Copyright (C) 2003, 2011 Free Software Foundation, Inc.
+# Copyright (C) 2003, 2014 Free Software Foundation, Inc.
# This file is distributed under the same license as the gawk package.
# Makoto Hosoya <mhosoya@ozemail.com.au>, 2003.
-# Yasuaki Taniguchi <yasuakit@gmail.com>, 2011.
+# Yasuaki Taniguchi <yasuakit@gmail.com>, 2011, 2014.
#
msgid ""
msgstr ""
-"Project-Id-Version: gawk 4.0.0\n"
+"Project-Id-Version: gawk 4.1.0b\n"
"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
-"POT-Creation-Date: 2011-10-24 05:57+0200\n"
-"PO-Revision-Date: 2011-07-17 08:28+0900\n"
+"POT-Creation-Date: 2014-04-08 19:23+0300\n"
+"PO-Revision-Date: 2014-11-07 12:26+0000\n"
"Last-Translator: Yasuaki Taniguchi <yasuakit@gmail.com>\n"
"Language-Team: Japanese <translation-team-ja@lists.sourceforge.net>\n"
"Language: ja\n"
@@ -18,499 +18,479 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-#: array.c:140
+#: array.c:256
#, c-format
msgid "from %s"
msgstr "%s ã‹ã‚‰"
-#: array.c:248
+#: array.c:357
msgid "attempt to use a scalar value as array"
msgstr "スカラー値をé…列ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹è©¦ã¿ã§ã™"
-#: array.c:251
-#, c-format
-msgid "attempt to use function `%s' as an array"
-msgstr "関数 `%s' ã‚’é…列ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹è©¦ã¿ã§ã™"
-
-#: array.c:254
+#: array.c:359
#, c-format
msgid "attempt to use scalar parameter `%s' as an array"
msgstr "スカラー仮引数 `%s' ã‚’é…列ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹è©¦ã¿ã§ã™"
-#: array.c:257
+#: array.c:362
#, c-format
msgid "attempt to use scalar `%s' as an array"
msgstr "スカラー `%s' ã‚’é…列ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹è©¦ã¿ã§ã™"
-#: array.c:302 array.c:707 builtin.c:84 builtin.c:1384 builtin.c:1426
-#: builtin.c:1439 builtin.c:1856 builtin.c:1868 eval.c:1135 eval.c:1139
-#: eval.c:1495 eval.c:1812
+#: array.c:409 array.c:576 builtin.c:85 builtin.c:1615 builtin.c:1661
+#: builtin.c:1674 builtin.c:2102 builtin.c:2116 eval.c:1122 eval.c:1126
+#: eval.c:1531
#, c-format
msgid "attempt to use array `%s' in a scalar context"
msgstr "スカラーコンテキストã§é…列 `%s' を使用ã™ã‚‹è©¦ã¿ã§ã™"
-#: array.c:513
-#, c-format
-msgid "reference to uninitialized element `%s[\"%.*s\"]'"
-msgstr "åˆæœŸåŒ–ã•ã‚Œã¦ã„ãªã„è¦ç´  `%s[\"%.*s\"]' ã¸ã®å‚ç…§ã§ã™"
-
-#: array.c:519
-#, c-format
-msgid "subscript of array `%s' is null string"
-msgstr "é…列 `%s' ã®æ·»å­—㌠NULL 文字列ã§ã™"
-
-#: array.c:723
+#: array.c:583
#, c-format
msgid "delete: index `%s' not in array `%s'"
msgstr "delete: é…列 `%2$s' 内ã«ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ `%1$s' ãŒã‚ã‚Šã¾ã›ã‚“"
-#: array.c:734 eval.c:1865
+#: array.c:597
#, c-format
msgid "attempt to use scalar `%s[\"%.*s\"]' as an array"
msgstr "スカラー `%s[\"%.*s\"]' ã‚’é…列ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹è©¦ã¿ã§ã™"
-#: array.c:910
-#, c-format
-msgid "%s: empty (null)\n"
-msgstr "%s: 空 (null)\n"
-
-#: array.c:915
-#, c-format
-msgid "%s: empty (zero)\n"
-msgstr "%s: 空 (zero)\n"
-
-#: array.c:919
-#, c-format
-msgid "%s: table_size = %d, array_size = %d\n"
-msgstr "%s: テーブルサイズ (table_size) = %d, é…列サイズ (array_size) = %d\n"
-
-#: array.c:954
-#, c-format
-msgid "%s: is parameter\n"
-msgstr "%s: 仮引数ã§ã™\n"
-
-#: array.c:958
-#, c-format
-msgid "%s: array_ref to %s\n"
-msgstr "%s: %s ã¸ã®é…列å‚ç…§ (array_ref) ã§ã™\n"
-
-#: array.c:963
-msgid "adump: argument not an array"
-msgstr "adump: 引数ãŒé…列ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
+#: array.c:776
+msgid "adump: first argument not an array"
+msgstr "adump: 第一引数ãŒé…列ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: array.c:1086
+#: array.c:815
msgid "asort: second argument not an array"
msgstr "asort: 第二引数ãŒé…列ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: array.c:1087
+#: array.c:816
msgid "asorti: second argument not an array"
msgstr "asorti: 第二引数ãŒé…列ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: array.c:1094
+#: array.c:823
msgid "asort: first argument not an array"
msgstr "asort: 第一引数ãŒé…列ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: array.c:1095
+#: array.c:824
msgid "asorti: first argument not an array"
msgstr "asorti: 第一引数ãŒé…列ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: array.c:1102
+#: array.c:831
msgid "asort: cannot use a subarray of first arg for second arg"
msgstr "asort: 第一引数ã®éƒ¨åˆ†é…列を第二引数用ã«ä½¿ç”¨ã™ã‚‹ã“ã¨ã¯å‡ºæ¥ã¾ã›ã‚“"
-#: array.c:1103
+#: array.c:832
msgid "asorti: cannot use a subarray of first arg for second arg"
msgstr "asorti: 第一引数ã®éƒ¨åˆ†é…列を第二引数用ã«ä½¿ç”¨ã™ã‚‹ã“ã¨ã¯å‡ºæ¥ã¾ã›ã‚“"
-#: array.c:1108
+#: array.c:837
msgid "asort: cannot use a subarray of second arg for first arg"
msgstr "asort: 第二引数ã®éƒ¨åˆ†é…列を第一引数用ã«ä½¿ç”¨ã™ã‚‹ã“ã¨ã¯å‡ºæ¥ã¾ã›ã‚“"
-#: array.c:1109
+#: array.c:838
msgid "asorti: cannot use a subarray of second arg for first arg"
msgstr "asorti: 第二引数ã®éƒ¨åˆ†é…列を第一引数用ã«ä½¿ç”¨ã™ã‚‹ã“ã¨ã¯å‡ºæ¥ã¾ã›ã‚“"
-#: array.c:1659
+#: array.c:1314
#, c-format
msgid "`%s' is invalid as a function name"
msgstr "`%s' ã¯é–¢æ•°åã¨ã—ã¦ã¯ç„¡åŠ¹ã§ã™"
-#: array.c:1663
+#: array.c:1318
#, c-format
msgid "sort comparison function `%s' is not defined"
msgstr "ソート比較関数 `%s' ãŒå®šç¾©ã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: awkgram.y:249
+#: awkgram.y:233
#, c-format
msgid "%s blocks must have an action part"
msgstr "%s ブロックã«ã¯ã‚¢ã‚¯ã‚·ãƒ§ãƒ³éƒ¨ãŒå¿…é ˆã§ã™"
-#: awkgram.y:252
+#: awkgram.y:236
msgid "each rule must have a pattern or an action part"
msgstr "å„ルールã«ã¯ãƒ‘ターンã¾ãŸã¯ã‚¢ã‚¯ã‚·ãƒ§ãƒ³éƒ¨ãŒå¿…é ˆã§ã™ã€‚"
-#: awkgram.y:323 awkgram.y:334
+#: awkgram.y:325 awkgram.y:336
msgid "old awk does not support multiple `BEGIN' or `END' rules"
msgstr "å¤ã„ awk ã¯è¤‡æ•°ã® `BEGIN' ã¾ãŸã¯ `END' ルールをサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
-#: awkgram.y:371
+#: awkgram.y:373
#, c-format
msgid "`%s' is a built-in function, it cannot be redefined"
msgstr "`%s' ã¯çµ„è¾¼ã¿é–¢æ•°ã§ã™ã€‚å†å®šç¾©ã§ãã¾ã›ã‚“"
-#: awkgram.y:432
+#: awkgram.y:419
msgid "regexp constant `//' looks like a C++ comment, but is not"
msgstr "æ­£è¦è¡¨ç¾å®šæ•° `//' 㯠C++コメントã«ä¼¼ã¦ã„ã¾ã™ãŒã€é•ã„ã¾ã™ã€‚"
-#: awkgram.y:436
+#: awkgram.y:423
#, c-format
msgid "regexp constant `/%s/' looks like a C comment, but is not"
msgstr "æ­£è¦è¡¨ç¾å®šæ•° `/%s/' 㯠C コメントã«ä¼¼ã¦ã„ã¾ã™ãŒã€ç•°ãªã‚Šã¾ã™"
-#: awkgram.y:528
+#: awkgram.y:515
#, c-format
msgid "duplicate case values in switch body: %s"
msgstr "switch æ–‡ã®ä¸­ã§é‡è¤‡ã—㟠case 値ãŒä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™: %s"
-#: awkgram.y:549
+#: awkgram.y:536
msgid "duplicate `default' detected in switch body"
msgstr "switch æ–‡ã®ä¸­ã§é‡è¤‡ã—㟠`default' ãŒæ¤œå‡ºã•ã‚Œã¾ã—ãŸ"
-#: awkgram.y:809
+#: awkgram.y:796 awkgram.y:3723
msgid "`break' is not allowed outside a loop or switch"
msgstr "`break' ã¯ãƒ«ãƒ¼ãƒ—ã¾ãŸã¯ switch ã®å¤–ã§ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: awkgram.y:818
+#: awkgram.y:805 awkgram.y:3715
msgid "`continue' is not allowed outside a loop"
msgstr "`continue' ã¯ãƒ«ãƒ¼ãƒ—ã®å¤–ã§ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: awkgram.y:828
+#: awkgram.y:815
#, c-format
msgid "`next' used in %s action"
msgstr "%s アクション内㧠`next' ãŒä½¿ç”¨ã•ã‚Œã¾ã—ãŸ"
-#: awkgram.y:836
-msgid "`nextfile' is a gawk extension"
-msgstr "`nextfile' 㯠gawk æ‹¡å¼µã§ã™"
-
-#: awkgram.y:841
+#: awkgram.y:824
#, c-format
msgid "`nextfile' used in %s action"
msgstr "`nextfile' ㌠%s アクション内ã§ä½¿ç”¨ã•ã‚Œã¾ã—ãŸ"
-#: awkgram.y:865
+#: awkgram.y:848
msgid "`return' used outside function context"
msgstr "`return' ãŒé–¢æ•°å®šç¾©æ–‡ã®å¤–ã§ä½¿ã‚ã‚Œã¾ã—ãŸ"
-#: awkgram.y:925
+#: awkgram.y:922
msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
msgstr ""
"BEGIN ã¾ãŸã¯ END ルール内ã®å¼•æ•°ã®ç„¡ã„ `print' 㯠`print \"\"' ã ã¨æ€ã‚ã‚Œã¾ã™"
-#: awkgram.y:995 awkgram.y:999 awkgram.y:1023
-msgid "`delete array' is a gawk extension"
-msgstr "`delete array' 㯠gawk æ‹¡å¼µã§ã™"
+#: awkgram.y:988 awkgram.y:1037
+msgid "`delete' is not allowed with SYMTAB"
+msgstr ""
+
+#: awkgram.y:990 awkgram.y:1039
+msgid "`delete' is not allowed with FUNCTAB"
+msgstr ""
-#: awkgram.y:1019
+#: awkgram.y:1024 awkgram.y:1028
msgid "`delete(array)' is a non-portable tawk extension"
msgstr "`delete(array)' ã¯ç§»æ¤æ€§ã®ç„¡ã„ tawk æ‹¡å¼µã§ã™"
-#: awkgram.y:1135
+#: awkgram.y:1149
msgid "multistage two-way pipelines don't work"
msgstr "多段階ã§åŒæ–¹å‘パイプを利用ã—ãŸå¼ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“"
-#: awkgram.y:1238
+#: awkgram.y:1264
msgid "regular expression on right of assignment"
msgstr "æ­£è¦è¡¨ç¾ãŒä»£å…¥å¼ã®å³è¾ºã«ä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™"
-#: awkgram.y:1249
+#: awkgram.y:1275
msgid "regular expression on left of `~' or `!~' operator"
msgstr "`~' ã‚„ `!~' 演算å­ã®å·¦è¾ºã«æ­£è¦è¡¨ç¾ãŒä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™"
-#: awkgram.y:1265 awkgram.y:1419
+#: awkgram.y:1291 awkgram.y:1442
msgid "old awk does not support the keyword `in' except after `for'"
msgstr "å¤ã„ awk ã§ã¯ `in' 予約語㯠`for' ã®å¾Œã‚’除ãサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
-#: awkgram.y:1275
+#: awkgram.y:1301
msgid "regular expression on right of comparison"
msgstr "比較å¼ã®å³è¾ºã«æ­£è¦è¡¨ç¾ãŒä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™ã€‚"
-#: awkgram.y:1394
+#: awkgram.y:1417
#, c-format
msgid "`getline var' invalid inside `%s' rule"
msgstr "`%s' ルールã®å†…部ã§ã¯ `getline var' ã¯ç„¡åŠ¹ã§ã™"
-#: awkgram.y:1397 eval.c:2504
+#: awkgram.y:1420
#, c-format
msgid "`getline' invalid inside `%s' rule"
msgstr "`%s' ルールã®å†…部ã§ã¯ `getline' ã¯ç„¡åŠ¹ã§ã™"
-#: awkgram.y:1402
+#: awkgram.y:1425
msgid "non-redirected `getline' undefined inside END action"
msgstr "リダイレクトã•ã‚Œã¦ã„ãªã„ `getline' 㯠END アクションã§ã¯æœªå®šç¾©ã§ã™ã€‚"
-#: awkgram.y:1421
+#: awkgram.y:1444
msgid "old awk does not support multidimensional arrays"
msgstr "å¤ã„ awk ã¯å¤šæ¬¡å…ƒé…列をサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
-#: awkgram.y:1517
+#: awkgram.y:1541
msgid "call of `length' without parentheses is not portable"
msgstr "å°æ‹¬å¼§ãŒç„¡ã„ `length' ã¯ç§»æ¤æ€§ãŒã‚ã‚Šã¾ã›ã‚“"
-#: awkgram.y:1580
+#: awkgram.y:1607
msgid "indirect function calls are a gawk extension"
msgstr "間接関数呼ã³å‡ºã—㯠gawk æ‹¡å¼µã§ã™"
-#: awkgram.y:1593
+#: awkgram.y:1620
#, c-format
msgid "can not use special variable `%s' for indirect function call"
msgstr "特別ãªå¤‰æ•° `%s' ã¯é–“接関数呼ã³å‡ºã—用ã«ã¯ä½¿ç”¨å‡ºæ¥ã¾ã›ã‚“"
-#: awkgram.y:1671
+#: awkgram.y:1698
msgid "invalid subscript expression"
msgstr "添字ã®å¼ãŒç„¡åŠ¹ã§ã™"
-#: awkgram.y:1711
-msgid "use of non-array as array"
-msgstr "é…列ã§ãªã„ã‚‚ã®ã‚’é…列ã¨ã—ã¦ä½¿ç”¨ã—ã¦ã„ã¾ã™"
-
-#: awkgram.y:1975 awkgram.y:1995 msg.c:98
+#: awkgram.y:2048 awkgram.y:2068 gawkapi.c:206 gawkapi.c:224 msg.c:126
msgid "warning: "
msgstr "警告: "
-#: awkgram.y:1993 msg.c:130
+#: awkgram.y:2066 gawkapi.c:192 gawkapi.c:221 msg.c:158
msgid "fatal: "
msgstr "致命的: "
-#: awkgram.y:2043
+#: awkgram.y:2116
msgid "unexpected newline or end of string"
msgstr "予期ã—ãªã„改行ã¾ãŸã¯æ–‡å­—列終端ã§ã™"
-#: awkgram.y:2300 awkgram.y:2358 awkgram.y:2542
+#: awkgram.y:2383 awkgram.y:2459 awkgram.y:2682 debug.c:523 debug.c:539
+#: debug.c:2812 debug.c:5055
#, c-format
msgid "can't open source file `%s' for reading (%s)"
msgstr "ソースファイル `%s' を読ã¿è¾¼ã¿ç”¨ã«é–‹ã‘ã¾ã›ã‚“ (%s)"
-#: awkgram.y:2301 awkgram.y:2359 builtin.c:122
+#: awkgram.y:2384 awkgram.y:2509
+#, c-format
+msgid "can't open shared library `%s' for reading (%s)"
+msgstr "共有ライブラリ `%s' を読ã¿è¾¼ã¿ç”¨ã«é–‹ã‘ã¾ã›ã‚“ (%s)"
+
+#: awkgram.y:2386 awkgram.y:2460 awkgram.y:2510 builtin.c:135 debug.c:5206
msgid "reason unknown"
msgstr "原因ä¸æ˜Ž"
-#: awkgram.y:2317
+#: awkgram.y:2395 awkgram.y:2419
+#, c-format
+msgid "can't include `%s' and use it as a program file"
+msgstr ""
+
+#: awkgram.y:2408
#, c-format
msgid "already included source file `%s'"
msgstr "ソースファイル `%s' ã¯æ—¢ã«èª­ã¿è¾¼ã¾ã‚Œã¦ã„ã¾ã™"
-#: awkgram.y:2343
+#: awkgram.y:2409
+#, c-format
+msgid "already loaded shared library `%s'"
+msgstr "共有ライブラリ `%s' ã¯æ—¢ã«èª­ã¿è¾¼ã¾ã‚Œã¦ã„ã¾ã™"
+
+#: awkgram.y:2444
msgid "@include is a gawk extension"
msgstr "@include 㯠gawk æ‹¡å¼µã§ã™"
-#: awkgram.y:2349
+#: awkgram.y:2450
msgid "empty filename after @include"
msgstr "@include ã®å¾Œã«ç©ºã®ãƒ•ã‚¡ã‚¤ãƒ«åãŒã‚ã‚Šã¾ã™"
#: awkgram.y:2494
+msgid "@load is a gawk extension"
+msgstr "@load 㯠gawk æ‹¡å¼µã§ã™"
+
+#: awkgram.y:2500
+msgid "empty filename after @load"
+msgstr "@load ã®å¾Œã«ç©ºã®ãƒ•ã‚¡ã‚¤ãƒ«åãŒã‚ã‚Šã¾ã™"
+
+#: awkgram.y:2634
msgid "empty program text on command line"
msgstr "コマンド行ã®ãƒ—ログラム表記ãŒç©ºã§ã™"
-#: awkgram.y:2609
+#: awkgram.y:2749
#, c-format
msgid "can't read sourcefile `%s' (%s)"
msgstr "ソースファイル `%s' を読ã¿è¾¼ã‚ã¾ã›ã‚“ (%s)"
-#: awkgram.y:2620
+#: awkgram.y:2760
#, c-format
msgid "source file `%s' is empty"
msgstr "ソースファイル `%s' ã¯ç©ºã§ã™"
-#: awkgram.y:2805
+#: awkgram.y:2937
msgid "source file does not end in newline"
msgstr "ソースファイルãŒæ”¹è¡Œã§çµ‚ã£ã¦ã„ã¾ã›ã‚“"
-#: awkgram.y:2882
+#: awkgram.y:3042
msgid "unterminated regexp ends with `\\' at end of file"
msgstr "終端ã•ã‚Œã¦ã„ãªã„æ­£è¦è¡¨ç¾ãŒãƒ•ã‚¡ã‚¤ãƒ«æœ€å¾Œã® `\\' ã§çµ‚ã£ã¦ã„ã¾ã™ã€‚"
-#: awkgram.y:2906
+#: awkgram.y:3066
#, c-format
msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
msgstr "%s: %d: tawk ã®æ­£è¦è¡¨ç¾ä¿®é£¾å­ `/.../%c' 㯠gawk ã§ä½¿ç”¨ã§ãã¾ã›ã‚“"
-#: awkgram.y:2910
+#: awkgram.y:3070
#, c-format
msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
msgstr "tawk ã®æ­£è¦è¡¨ç¾ä¿®é£¾å­ `/.../%c' 㯠gawk ã§ä½¿ç”¨ã§ãã¾ã›ã‚“"
-#: awkgram.y:2917
+#: awkgram.y:3077
msgid "unterminated regexp"
msgstr "æ­£è¦è¡¨ç¾ãŒçµ‚端ã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: awkgram.y:2921
+#: awkgram.y:3081
msgid "unterminated regexp at end of file"
msgstr "ファイルã®ä¸­ã§æ­£è¦è¡¨ç¾ãŒçµ‚端ã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: awkgram.y:2980
+#: awkgram.y:3140
msgid "use of `\\ #...' line continuation is not portable"
msgstr "`\\ #...' å½¢å¼ã®è¡Œç¶™ç¶šã¯ç§»æ¤æ€§ãŒã‚ã‚Šã¾ã›ã‚“"
-#: awkgram.y:2996
+#: awkgram.y:3156
msgid "backslash not last character on line"
msgstr "ãƒãƒƒã‚¯ã‚¹ãƒ©ãƒƒã‚·ãƒ¥ãŒè¡Œæœ€å¾Œã®æ–‡å­—ã«ãªã£ã¦ã„ã¾ã›ã‚“。"
-#: awkgram.y:3057
+#: awkgram.y:3217
msgid "POSIX does not allow operator `**='"
msgstr "POSIX ã§ã¯æ¼”ç®—å­ `**=' ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: awkgram.y:3059
+#: awkgram.y:3219
msgid "old awk does not support operator `**='"
msgstr "å¤ã„ awk ã¯æ¼”ç®—å­ `**=' をサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
-#: awkgram.y:3068
+#: awkgram.y:3228
msgid "POSIX does not allow operator `**'"
msgstr "POSIX ã§ã¯æ¼”ç®—å­ `**' ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: awkgram.y:3070
+#: awkgram.y:3230
msgid "old awk does not support operator `**'"
msgstr "å¤ã„ awk ã¯æ¼”ç®—å­ `**' をサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
-#: awkgram.y:3105
+#: awkgram.y:3265
msgid "operator `^=' is not supported in old awk"
msgstr "å¤ã„ awk ã¯æ¼”ç®—å­ `^=' をサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
-#: awkgram.y:3113
+#: awkgram.y:3273
msgid "operator `^' is not supported in old awk"
msgstr "å¤ã„ awk ã¯æ¼”ç®—å­ `^' をサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
-#: awkgram.y:3206 awkgram.y:3222
+#: awkgram.y:3366 awkgram.y:3382 command.y:1178
msgid "unterminated string"
msgstr "文字列ãŒçµ‚端ã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: awkgram.y:3418
+#: awkgram.y:3603
#, c-format
msgid "invalid char '%c' in expression"
msgstr "å¼å†…ã«ç„¡åŠ¹ãªæ–‡å­— '%c' ãŒã‚ã‚Šã¾ã™"
-#: awkgram.y:3465
+#: awkgram.y:3650
#, c-format
msgid "`%s' is a gawk extension"
msgstr "`%s' 㯠gawk æ‹¡å¼µã§ã™"
-#: awkgram.y:3470
-#, c-format
-msgid "`%s' is a Bell Labs extension"
-msgstr "`%s' ã¯ãƒ™ãƒ«ç ”究所ã«ã‚ˆã‚‹æ‹¡å¼µã§ã™"
-
-#: awkgram.y:3475
+#: awkgram.y:3655
#, c-format
msgid "POSIX does not allow `%s'"
msgstr "POSIX ã§ã¯ `%s' ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: awkgram.y:3483
+#: awkgram.y:3663
#, c-format
msgid "`%s' is not supported in old awk"
msgstr "å¤ã„ awk 㯠`%s' をサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
-#: awkgram.y:3550
+#: awkgram.y:3753
msgid "`goto' considered harmful!\n"
msgstr "`goto' ã¯æœ‰å®³ã ã¨è¦‹ãªã•ã‚Œã¦ã„ã¾ã™!\n"
-#: awkgram.y:3601
+#: awkgram.y:3787
#, c-format
msgid "%d is invalid as number of arguments for %s"
msgstr "%d 㯠%s 用ã®å¼•æ•°ã®æ•°ã¨ã—ã¦ã¯ç„¡åŠ¹ã§ã™"
-#: awkgram.y:3636
+#: awkgram.y:3822
#, c-format
msgid "%s: string literal as last arg of substitute has no effect"
msgstr "%s: 文字列リテラルを置ãæ›ãˆæœ€å¾Œã®å¼•æ•°ã«ä½¿ç”¨ã™ã‚‹ã¨åŠ¹æžœãŒã‚ã‚Šã¾ã›ã‚“"
-#: awkgram.y:3641
+#: awkgram.y:3827
#, c-format
msgid "%s third parameter is not a changeable object"
msgstr "%s 第三仮引数ã¯å¯å¤‰ã‚ªãƒ–ジェクトã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: awkgram.y:3714 awkgram.y:3717
+#: awkgram.y:3910 awkgram.y:3913
msgid "match: third argument is a gawk extension"
msgstr "match: 第三引数㯠gawk æ‹¡å¼µã§ã™"
-#: awkgram.y:3771 awkgram.y:3774
+#: awkgram.y:3967 awkgram.y:3970
msgid "close: second argument is a gawk extension"
msgstr "close: 第二引数㯠gawk æ‹¡å¼µã§ã™"
-#: awkgram.y:3786
+#: awkgram.y:3982
msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
msgstr ""
"dcgettext(_\"...\")ã®ä½¿ç”¨æ³•ãŒé–“é•ã£ã¦ã„ã¾ã™: 先頭ã®ã‚¢ãƒ³ãƒ€ãƒ¼ã‚¹ã‚³ã‚¢(_)を削除ã—"
"ã¦ãã ã•ã„"
-#: awkgram.y:3801
+#: awkgram.y:3997
msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
msgstr ""
"dcngettext(_\"...\")ã®ä½¿ç”¨æ³•ãŒé–“é•ã£ã¦ã„ã¾ã™: 先頭ã®ã‚¢ãƒ³ãƒ€ãƒ¼ã‚¹ã‚³ã‚¢(_)を削除ã—"
"ã¦ãã ã•ã„"
-#: awkgram.y:3893
-#, c-format
-msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
-msgstr "関数 `%s': 仮引数 #%d, `%s' ãŒä»®å¼•æ•° #%d ã¨é‡è¤‡ã—ã¦ã„ã¾ã™"
+#: awkgram.y:4016
+#, fuzzy
+msgid "index: regexp constant as second argument is not allowed"
+msgstr "index: 文字列ã§ã¯ç„¡ã„第二引数をå—ã‘å–ã‚Šã¾ã—ãŸ"
-#: awkgram.y:3935
+#: awkgram.y:4069
#, c-format
msgid "function `%s': parameter `%s' shadows global variable"
msgstr "関数 `%s': 仮引数 `%s' ãŒå¤§åŸŸå¤‰æ•°ã‚’覆ã„éš ã—ã¦ã„ã¾ã™"
-#: awkgram.y:4093
+#: awkgram.y:4126 debug.c:4041 debug.c:4084 debug.c:5204
#, c-format
msgid "could not open `%s' for writing (%s)"
msgstr "`%s' を書込ã¿ç”¨ã«é–‹ã‘ã¾ã›ã‚“ã§ã—㟠(%s)"
-#: awkgram.y:4094
+#: awkgram.y:4127
msgid "sending variable list to standard error"
msgstr "変数リストを標準エラーã«é€ã£ã¦ã„ã¾ã™"
-#: awkgram.y:4100
+#: awkgram.y:4135
#, c-format
msgid "%s: close failed (%s)"
msgstr "%s: é–‰ã˜ã‚‹ã®ã«å¤±æ•—ã—ã¾ã—㟠(%s)"
-#: awkgram.y:4152
+#: awkgram.y:4160
msgid "shadow_funcs() called twice!"
msgstr "shadow_funcs() を二回呼ã³å‡ºã—ã¦ã„ã¾ã™!"
-#: awkgram.y:4158
+#: awkgram.y:4168
msgid "there were shadowed variables."
msgstr "覆ã„éš ã•ã‚ŒãŸå¤‰æ•°ãŒã‚ã‚Šã¾ã—ãŸ"
-#: awkgram.y:4188
+#: awkgram.y:4239
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "関数å `%s' ã¯å‰ã«å®šç¾©ã•ã‚Œã¦ã„ã¾ã™"
+
+#: awkgram.y:4285
#, c-format
msgid "function `%s': can't use function name as parameter name"
msgstr "関数 `%s': 関数åを仮引数åã¨ã—ã¦ä½¿ç”¨å‡ºæ¥ã¾ã›ã‚“"
-#: awkgram.y:4192
+#: awkgram.y:4288
#, c-format
msgid "function `%s': can't use special variable `%s' as a function parameter"
msgstr "関数 `%s': 特別ãªå¤‰æ•° `%s' ã¯é–¢æ•°ã®ä»®å¼•æ•°ã¨ã—ã¦ä½¿ç”¨å‡ºæ¥ã¾ã›ã‚“"
-#: awkgram.y:4208
+#: awkgram.y:4296
#, c-format
-msgid "function name `%s' previously defined"
-msgstr "関数å `%s' ã¯å‰ã«å®šç¾©ã•ã‚Œã¦ã„ã¾ã™"
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "関数 `%s': 仮引数 #%d, `%s' ãŒä»®å¼•æ•° #%d ã¨é‡è¤‡ã—ã¦ã„ã¾ã™"
-#: awkgram.y:4376 awkgram.y:4382
+#: awkgram.y:4383 awkgram.y:4389
#, c-format
msgid "function `%s' called but never defined"
msgstr "未定義ã®é–¢æ•° `%s' を呼ã³å‡ºã—ã¾ã—ãŸ"
-#: awkgram.y:4385
+#: awkgram.y:4393
#, c-format
msgid "function `%s' defined but never called directly"
msgstr "関数 `%s' ã¯å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ãŒã€ä¸€åº¦ã‚‚直接呼ã³å‡ºã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: awkgram.y:4417
+#: awkgram.y:4425
#, c-format
msgid "regexp constant for parameter #%d yields boolean value"
msgstr "仮引数 #%d 用ã®æ­£è¦è¡¨ç¾å®šæ•°ã¯çœŸå½å€¤ã‚’出力ã—ã¾ã™"
-#: awkgram.y:4526
+#: awkgram.y:4484
#, c-format
msgid ""
"function `%s' called with space between name and `(',\n"
@@ -519,230 +499,244 @@ msgstr ""
"関数å㨠`(' ã®é–“ã«ã‚¹ãƒšãƒ¼ã‚¹ã‚’入れã¦é–¢æ•° `%s' を呼ã³å‡ºã—ã¦ã„ã¾ã™ã€‚\n"
"ã¾ãŸã¯ã€å¤‰æ•°ã‹é…列ã¨ã—ã¦ä½¿ã‚ã‚Œã¦ã„ã¾ã™ã€‚"
-#: awkgram.y:4773 eval.c:2056
+#: awkgram.y:4720
msgid "division by zero attempted"
msgstr "ゼロã«ã‚ˆã‚‹é™¤ç®—ãŒè©¦ã¿ã‚‰ã‚Œã¾ã—ãŸ"
-#: awkgram.y:4782 eval.c:2072
+#: awkgram.y:4729
#, c-format
msgid "division by zero attempted in `%%'"
msgstr "`%%' 内ã§ã‚¼ãƒ­ã«ã‚ˆã‚‹é™¤ç®—ãŒè©¦ã¿ã‚‰ã‚Œã¾ã—ãŸ"
-#: builtin.c:120
+#: awkgram.y:5049
+msgid ""
+"cannot assign a value to the result of a field post-increment expression"
+msgstr ""
+
+#: awkgram.y:5052
+#, fuzzy, c-format
+msgid "invalid target of assignment (opcode %s)"
+msgstr "%d 㯠%s 用ã®å¼•æ•°ã®æ•°ã¨ã—ã¦ã¯ç„¡åŠ¹ã§ã™"
+
+#: builtin.c:133
#, c-format
msgid "%s to \"%s\" failed (%s)"
msgstr "%s ã‹ã‚‰ \"%s\" ã¸å‡ºåŠ›ã§ãã¾ã›ã‚“ (%s)。"
-#: builtin.c:121
+#: builtin.c:134
msgid "standard output"
msgstr "標準出力"
-#: builtin.c:135
+#: builtin.c:148
msgid "exp: received non-numeric argument"
msgstr "exp: 引数ãŒæ•°å€¤ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: builtin.c:141
+#: builtin.c:154
#, c-format
msgid "exp: argument %g is out of range"
msgstr "exp: 引数 %g ãŒç¯„囲外ã§ã™"
-#: builtin.c:200
+#: builtin.c:229
#, c-format
msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
msgstr ""
"fflush: flush ã§ãã¾ã›ã‚“: パイプ `%s' ã¯èª­ã¿è¾¼ã¿ç”¨ã«é–‹ã‹ã‚Œã¦ã„ã¾ã™ã€‚書ãè¾¼ã¿"
"用ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: builtin.c:203
+#: builtin.c:232
#, c-format
msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
msgstr ""
"fflush: flush ã§ãã¾ã›ã‚“: ファイル `%s' ã¯èª­ã¿è¾¼ã¿ç”¨ã«é–‹ã‹ã‚Œã¦ã„ã¾ã™ã€‚書ãè¾¼"
"ã¿ç”¨ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: builtin.c:215
+#: builtin.c:244
#, c-format
msgid "fflush: `%s' is not an open file, pipe or co-process"
msgstr "fflush: `%s' ãŒé–‹ã‹ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã€ãƒ‘イプã€ãƒ—ロセス共有ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: builtin.c:333
+#: builtin.c:362
msgid "index: received non-string first argument"
msgstr "index: 文字列ã§ã¯ç„¡ã„第一引数をå—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:335
+#: builtin.c:364
msgid "index: received non-string second argument"
msgstr "index: 文字列ã§ã¯ç„¡ã„第二引数をå—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:457
+#: builtin.c:488 mpfr.c:757
msgid "int: received non-numeric argument"
msgstr "int: 数値ã§ã¯ç„¡ã„引数をå—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:493
+#: builtin.c:525
msgid "length: received array argument"
msgstr "length: é…列引数をå—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:496
+#: builtin.c:528
msgid "`length(array)' is a gawk extension"
msgstr "`length(array)' 㯠gawk æ‹¡å¼µã§ã™"
-#: builtin.c:504
+#: builtin.c:544
msgid "length: received non-string argument"
msgstr "length: 文字列ã§ã¯ç„¡ã„引数をå—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:535
+#: builtin.c:575
msgid "log: received non-numeric argument"
msgstr "log: 数値ã§ã¯ç„¡ã„引数をå—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:538
+#: builtin.c:578
#, c-format
msgid "log: received negative argument %g"
msgstr "log: è² ã®å¼•æ•° %g ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:694 builtin.c:699
+#: builtin.c:776 builtin.c:781
msgid "fatal: must use `count$' on all formats or none"
msgstr ""
"致命的: `count$’ ã¯å…¨ã¦ã®æ›¸å¼ä½¿ç”¨ã™ã‚‹ã€ã¾ãŸã¯å…¨ã¦ã«ä½¿ç”¨ã—ãªã„ã®ã„ãšã‚Œã‹ã§ãªã‘"
"ã‚Œã°ã„ã‘ã¾ã›ã‚“"
-#: builtin.c:761
+#: builtin.c:851
#, c-format
msgid "field width is ignored for `%%' specifier"
msgstr "`%%' 指定用ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰å¹…ã¯ç„¡è¦–ã•ã‚Œã¾ã™"
-#: builtin.c:763
+#: builtin.c:853
#, c-format
msgid "precision is ignored for `%%' specifier"
msgstr "`%%' 指定用ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰å¹…ã¯ç„¡è¦–ã•ã‚Œã¾ã™"
-#: builtin.c:765
+#: builtin.c:855
#, c-format
msgid "field width and precision are ignored for `%%' specifier"
msgstr "`%%' 指定用ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰å¹…ãŠã‚ˆã³ç²¾åº¦ã¯ç„¡è¦–ã•ã‚Œã¾ã™"
-#: builtin.c:816
+#: builtin.c:906
msgid "fatal: `$' is not permitted in awk formats"
msgstr "致命的: `$' 㯠awk å½¢å¼å†…ã§ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: builtin.c:825
+#: builtin.c:915
msgid "fatal: arg count with `$' must be > 0"
msgstr "致命的: `$' ã§æŒ‡å®šã™ã‚‹å¼•æ•°ã®ç•ªå·ã¯æ­£ã§ãªã‘ã‚Œã°ã„ã‘ã¾ã›ã‚“"
-#: builtin.c:829
+#: builtin.c:919
#, c-format
msgid "fatal: arg count %ld greater than total number of supplied arguments"
msgstr "致命的: 引数ã®ç•ªå· %ld ã¯å¼•æ•°ã¨ã—ã¦ä¸Žãˆã‚‰ã‚ŒãŸæ•°ã‚ˆã‚Šå¤§ãã„ã§ã™"
-#: builtin.c:833
+#: builtin.c:923
msgid "fatal: `$' not permitted after period in format"
msgstr "致命的: `$' ã¯æ›¸å¼æŒ‡å®šå†…ã®ãƒ”リオド `.' ã®å¾Œã«ä½¿ç”¨ã§ãã¾ã›ã‚“"
-#: builtin.c:849
+#: builtin.c:939
msgid "fatal: no `$' supplied for positional field width or precision"
msgstr "致命的: フィールド幅ã€ã¾ãŸã¯ç²¾åº¦ã®æŒ‡å®šå­ã« `$' ãŒä¸Žãˆã‚‰ã‚Œã¦ã„ã¾ã›ã‚“"
-#: builtin.c:920
+#: builtin.c:1009
msgid "`l' is meaningless in awk formats; ignored"
msgstr "awk ã®æ›¸å¼æŒ‡å®šã§ã¯ `l' ã¯ç„¡æ„味ã§ã™ã€‚無視ã—ã¾ã™"
-#: builtin.c:924
+#: builtin.c:1013
msgid "fatal: `l' is not permitted in POSIX awk formats"
msgstr "致命的: POSIX awk 書å¼å†…ã§ã¯ `l' ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: builtin.c:937
+#: builtin.c:1026
msgid "`L' is meaningless in awk formats; ignored"
msgstr "awk ã®æ›¸å¼æŒ‡å®šã§ã¯ `L' ã¯ç„¡æ„味ã§ã™ã€‚無視ã—ã¾ã™ã€‚"
-#: builtin.c:941
+#: builtin.c:1030
msgid "fatal: `L' is not permitted in POSIX awk formats"
msgstr "致命的: POSIX awk 書å¼å†…ã§ã¯ `L' ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: builtin.c:954
+#: builtin.c:1043
msgid "`h' is meaningless in awk formats; ignored"
msgstr "awk ã®æ›¸å¼æŒ‡å®šã§ã¯ `h' ã¯ç„¡æ„味ã§ã™ã€‚無視ã—ã¾ã™ã€‚"
-#: builtin.c:958
+#: builtin.c:1047
msgid "fatal: `h' is not permitted in POSIX awk formats"
msgstr "致命的: POSIX awk 書å¼å†…ã§ã¯ `h' ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: builtin.c:1271
+#: builtin.c:1463
#, c-format
msgid "[s]printf: value %g is out of range for `%%%c' format"
msgstr "[s]printf: 値 %g ã¯æ›¸å¼ `%%%c' ã®ç¯„囲外ã§ã™"
-#: builtin.c:1331
+#: builtin.c:1561
#, c-format
msgid "ignoring unknown format specifier character `%c': no argument converted"
msgstr "ä¸æ˜Žãªæ›¸å¼æŒ‡å®šæ–‡å­— `%c' を無視ã—ã¦ã„ã¾ã™: 変æ›ã•ã‚Œã‚‹å¼•æ•°ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: builtin.c:1336
+#: builtin.c:1566
msgid "fatal: not enough arguments to satisfy format string"
msgstr "致命的: 書å¼æ–‡å­—列を満ãŸã™å分ãªæ•°ã®å¼•æ•°ãŒã‚ã‚Šã¾ã›ã‚“"
-#: builtin.c:1338
+#: builtin.c:1568
msgid "^ ran out for this one"
msgstr "^ ã“ã“ã‹ã‚‰è¶³ã‚Šã¾ã›ã‚“"
-#: builtin.c:1345
+#: builtin.c:1575
msgid "[s]printf: format specifier does not have control letter"
msgstr "[s]printf: 書å¼æŒ‡å®šå­ã«åˆ¶å¾¡æ–‡å­—ãŒã‚ã‚Šã¾ã›ã‚“"
-#: builtin.c:1348
+#: builtin.c:1578
msgid "too many arguments supplied for format string"
msgstr "書å¼æ–‡å­—列ã«ä¸Žãˆã‚‰ã‚Œã¦ã„る引数ãŒå¤šã™ãŽã¾ã™"
-#: builtin.c:1422 builtin.c:1433
+#: builtin.c:1634
+msgid "sprintf: no arguments"
+msgstr "sprintf: 引数ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: builtin.c:1657 builtin.c:1668
msgid "printf: no arguments"
msgstr "printf: 引数ãŒã‚ã‚Šã¾ã›ã‚“"
-#: builtin.c:1474
+#: builtin.c:1711
msgid "sqrt: received non-numeric argument"
msgstr "sqrt: 数値ã§ã¯ç„¡ã„引数をå—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:1478
+#: builtin.c:1715
#, c-format
msgid "sqrt: called with negative argument %g"
msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
-#: builtin.c:1502
+#: builtin.c:1746
#, c-format
msgid "substr: length %g is not >= 1"
msgstr "substr: é•·ã• %g ㌠1 以上ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: builtin.c:1504
+#: builtin.c:1748
#, c-format
msgid "substr: length %g is not >= 0"
msgstr "substr: é•·ã• %g ㌠0 以上ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: builtin.c:1511
+#: builtin.c:1755
#, c-format
msgid "substr: non-integer length %g will be truncated"
msgstr "substr: 文字数 %g ã®å°æ•°ç‚¹ä»¥ä¸‹ã¯åˆ‡ã‚Šæ¨ã¦ã¾ã™ã€‚"
-#: builtin.c:1516
+#: builtin.c:1760
#, c-format
msgid "substr: length %g too big for string indexing, truncating to %g"
msgstr "substr: 文字数 %g ã¯æœ€å¤§å€¤ã‚’超ãˆã¦ã„ã¾ã™ã€‚%g を使ã„ã¾ã™ã€‚"
-#: builtin.c:1528
+#: builtin.c:1772
#, c-format
msgid "substr: start index %g is invalid, using 1"
msgstr "substr: 開始インデックス %g ãŒç„¡åŠ¹ã§ã™ã€‚1を使用ã—ã¾ã™"
-#: builtin.c:1533
+#: builtin.c:1777
#, c-format
msgid "substr: non-integer start index %g will be truncated"
msgstr "substr: 開始インデックス %g ãŒéžæ•´æ•°ã®ãŸã‚ã€å€¤ã¯åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã™"
-#: builtin.c:1558
+#: builtin.c:1802
msgid "substr: source string is zero length"
msgstr "substr: 文字列ã®é•·ã•ãŒã‚¼ãƒ­ã§ã™ã€‚"
-#: builtin.c:1574
+#: builtin.c:1818
#, c-format
msgid "substr: start index %g is past end of string"
msgstr "substr: 開始インデックス %g ãŒæ–‡å­—列終端ã®å¾Œã«ã‚ã‚Šã¾ã™"
-#: builtin.c:1582
+#: builtin.c:1826
#, c-format
msgid ""
"substr: length %g at start index %g exceeds length of first argument (%lu)"
@@ -750,227 +744,1078 @@ msgstr ""
"substr: 開始インデックス %2$g ã‹ã‚‰ã®é•·ã• %1$g ã¯ç¬¬ä¸€å¼•æ•°ã®é•·ã•ã‚’超ãˆã¦ã„ã¾ã™ "
"(%3$lu)"
-#: builtin.c:1655
+#: builtin.c:1900
msgid "strftime: format value in PROCINFO[\"strftime\"] has numeric type"
msgstr "strftime: PROCINFO[\"strftime\"] ã®æ›¸å¼ã®å€¤ã¯æ•°å€¤åž‹ã§ã™"
-#: builtin.c:1678
+#: builtin.c:1923
msgid "strftime: received non-numeric second argument"
msgstr "strftime: éžæ•°å€¤ã®ç¬¬äºŒå¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:1681
+#: builtin.c:1927
msgid "strftime: second argument less than 0 or too big for time_t"
msgstr ""
-#: builtin.c:1687
+#: builtin.c:1934
msgid "strftime: received non-string first argument"
msgstr "strftime: éžæ–‡å­—列ã®ç¬¬ä¸€å¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:1693
+#: builtin.c:1941
msgid "strftime: received empty format string"
msgstr "strftime: 空ã®æ›¸å¼æ–‡å­—列をå—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:1759
+#: builtin.c:2007
msgid "mktime: received non-string argument"
msgstr "mktime: éžæ–‡å­—列引数をå—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:1776
+#: builtin.c:2024
msgid "mktime: at least one of the values is out of the default range"
msgstr "mktime: 一ã¤ä»¥ä¸Šã®å€¤ãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ç¯„囲を超ãˆã¦ã„ã¾ã™"
-#: builtin.c:1811
+#: builtin.c:2059
msgid "'system' function not allowed in sandbox mode"
msgstr "サンドボックスモードã§ã¯ 'system' 関数ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: builtin.c:1816
+#: builtin.c:2064
msgid "system: received non-string argument"
msgstr "system: 文字列ã§ã¯ç„¡ã„引数をå—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:1871 eval.c:1159 eval.c:1790 eval.c:1803
-#, c-format
-msgid "reference to uninitialized variable `%s'"
-msgstr "åˆæœŸåŒ–ã•ã‚Œã¦ã„ãªã„変数 `%s' ã¸ã®å‚ç…§ã§ã™"
-
-#: builtin.c:1938
+#: builtin.c:2184
#, c-format
msgid "reference to uninitialized field `$%d'"
msgstr "åˆæœŸåŒ–ã•ã‚Œã¦ã„ãªã„フィールド `$%d' ã¸ã®å‚ç…§ã§ã™"
-#: builtin.c:2025
+#: builtin.c:2271
msgid "tolower: received non-string argument"
msgstr "tolower: éžæ–‡å­—列引数をå—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:2059
+#: builtin.c:2305
msgid "toupper: received non-string argument"
msgstr "toupper: éžæ–‡å­—列引数をå—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:2095
+#: builtin.c:2341 mpfr.c:672
msgid "atan2: received non-numeric first argument"
msgstr "atan2: éžæ•°å€¤ã®ç¬¬ä¸€å¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:2097
+#: builtin.c:2343 mpfr.c:674
msgid "atan2: received non-numeric second argument"
msgstr "atan2: éžæ•°å€¤ã®ç¬¬äºŒå¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:2116
+#: builtin.c:2362
msgid "sin: received non-numeric argument"
msgstr "sin: éžæ•°å€¤ã®å¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:2132
+#: builtin.c:2378
msgid "cos: received non-numeric argument"
msgstr "cos: éžæ•°å€¤ã®å¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:2185
+#: builtin.c:2431 mpfr.c:1156
msgid "srand: received non-numeric argument"
msgstr "srand: éžæ•°å€¤ã®å¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:2216
+#: builtin.c:2462
msgid "match: third argument is not an array"
msgstr "match: 第三引数ãŒé…列ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: builtin.c:2480
+#: builtin.c:2734
msgid "gensub: third argument of 0 treated as 1"
msgstr "gensub: 第三引数㌠0 ã§ã™ã€‚1 を代ã‚ã‚Šã«ä½¿ç”¨ã—ã¾ã™"
-#: builtin.c:2773
+#: builtin.c:3030
msgid "lshift: received non-numeric first argument"
msgstr "lshift: éžæ•°å€¤ã®ç¬¬ä¸€å¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:2775
+#: builtin.c:3032
msgid "lshift: received non-numeric second argument"
msgstr "lshift: éžæ•°å€¤ã®ç¬¬äºŒå¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:2781
+#: builtin.c:3038
#, c-format
-msgid "lshift(%lf, %lf): negative values will give strange results"
-msgstr "lshift(%lf, %lf): è² ã®æ•°å€¤ã‚’使用ã™ã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
+msgid "lshift(%f, %f): negative values will give strange results"
+msgstr "lshift(%f, %f): è² ã®æ•°å€¤ã‚’使用ã™ã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
-#: builtin.c:2783
+#: builtin.c:3040
#, c-format
-msgid "lshift(%lf, %lf): fractional values will be truncated"
-msgstr "lshift(%lf, %lf): å°æ•°ç‚¹ä»¥ä¸‹ã¯åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã™"
+msgid "lshift(%f, %f): fractional values will be truncated"
+msgstr "lshift(%f, %f): å°æ•°ç‚¹ä»¥ä¸‹ã¯åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã™"
-#: builtin.c:2785
+#: builtin.c:3042
#, c-format
-msgid "lshift(%lf, %lf): too large shift value will give strange results"
-msgstr "lshift(%lf, %lf): シフト値ãŒå¤§ãéŽãŽã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
+msgid "lshift(%f, %f): too large shift value will give strange results"
+msgstr "lshift(%f, %f): シフト値ãŒå¤§ãéŽãŽã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
-#: builtin.c:2810
+#: builtin.c:3067
msgid "rshift: received non-numeric first argument"
msgstr "rshift: éžæ•°å€¤ã®ç¬¬ä¸€å¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:2812
+#: builtin.c:3069
msgid "rshift: received non-numeric second argument"
msgstr "rshift: éžæ•°å€¤ã®ç¬¬äºŒå¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:2818
+#: builtin.c:3075
#, c-format
-msgid "rshift(%lf, %lf): negative values will give strange results"
-msgstr "rshift(%lf, %lf): è² ã®æ•°å€¤ã‚’使用ã™ã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
+msgid "rshift(%f, %f): negative values will give strange results"
+msgstr "rshift(%f, %f): è² ã®æ•°å€¤ã‚’使用ã™ã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
-#: builtin.c:2820
+#: builtin.c:3077
#, c-format
-msgid "rshift(%lf, %lf): fractional values will be truncated"
-msgstr "rshift(%lf, %lf): å°æ•°ç‚¹ä»¥ä¸‹ã¯åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã™"
+msgid "rshift(%f, %f): fractional values will be truncated"
+msgstr "rshift(%f, %f): å°æ•°ç‚¹ä»¥ä¸‹ã¯åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã™"
-#: builtin.c:2822
+#: builtin.c:3079
#, c-format
-msgid "rshift(%lf, %lf): too large shift value will give strange results"
-msgstr "rshift(%lf, %lf): シフト値ãŒå¤§ãéŽãŽã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
-
-#: builtin.c:2847
-msgid "and: received non-numeric first argument"
-msgstr "and: éžæ•°å€¤ã®ç¬¬ä¸€å¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
+msgid "rshift(%f, %f): too large shift value will give strange results"
+msgstr "rshift(%f, %f): シフト値ãŒå¤§ãéŽãŽã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
-#: builtin.c:2849
-msgid "and: received non-numeric second argument"
-msgstr "and: éžæ•°å€¤ã®ç¬¬äºŒå¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
+#: builtin.c:3104 mpfr.c:968
+msgid "and: called with less than two arguments"
+msgstr "and: 2個未満ã®å¼•æ•°ã§å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
-#: builtin.c:2855
+#: builtin.c:3109
#, c-format
-msgid "and(%lf, %lf): negative values will give strange results"
+msgid "and: argument %d is non-numeric"
+msgstr "and: 引数 %d ãŒéžæ•°å€¤ã§ã™"
+
+#: builtin.c:3113
+#, fuzzy, c-format
+msgid "and: argument %d negative value %g will give strange results"
msgstr "and(%lf, %lf): è² ã®æ•°å€¤ã‚’使用ã™ã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
-#: builtin.c:2857
+#: builtin.c:3136 mpfr.c:1000
+msgid "or: called with less than two arguments"
+msgstr "or: 2個未満ã®å¼•æ•°ã§å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: builtin.c:3141
#, c-format
-msgid "and(%lf, %lf): fractional values will be truncated"
-msgstr "and(%lf, %lf): å°æ•°ç‚¹ä»¥ä¸‹ã¯åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã™"
+msgid "or: argument %d is non-numeric"
+msgstr "or: 引数 %d ãŒéžæ•°å€¤ã§ã™"
-#: builtin.c:2882
-msgid "or: received non-numeric first argument"
-msgstr "or: éžæ•°å€¤ã®ç¬¬ä¸€å¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
+#: builtin.c:3145
+#, fuzzy, c-format
+msgid "or: argument %d negative value %g will give strange results"
+msgstr "compl(%lf): è² ã®æ•°å€¤ã‚’使用ã™ã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
-#: builtin.c:2884
-msgid "or: received non-numeric second argument"
-msgstr "or: éžæ•°å€¤ã®ç¬¬äºŒå¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
+#: builtin.c:3167 mpfr.c:1031
+#, fuzzy
+msgid "xor: called with less than two arguments"
+msgstr "xor: 2個未満ã®å¼•æ•°ã§å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
-#: builtin.c:2890
+#: builtin.c:3173
#, c-format
-msgid "or(%lf, %lf): negative values will give strange results"
-msgstr "or(%lf, %lf): è² ã®æ•°å€¤ã‚’使用ã™ã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
+msgid "xor: argument %d is non-numeric"
+msgstr "xor: 引数 %d ãŒéžæ•°å€¤ã§ã™"
+
+#: builtin.c:3177
+#, fuzzy, c-format
+msgid "xor: argument %d negative value %g will give strange results"
+msgstr "xor(%lf, %lf): è² ã®æ•°å€¤ã‚’使用ã™ã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
+
+#: builtin.c:3202 mpfr.c:787
+msgid "compl: received non-numeric argument"
+msgstr "compl: éžæ•°å€¤ã®å¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
-#: builtin.c:2892
+#: builtin.c:3208
#, c-format
-msgid "or(%lf, %lf): fractional values will be truncated"
-msgstr "or(%lf, %lf): å°æ•°ç‚¹ä»¥ä¸‹ã¯åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã™"
+msgid "compl(%f): negative value will give strange results"
+msgstr "compl(%f): è² ã®æ•°å€¤ã‚’使用ã™ã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
-#: builtin.c:2920
-msgid "xor: received non-numeric first argument"
-msgstr "xor: éžæ•°å€¤ã®ç¬¬ä¸€å¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
+#: builtin.c:3210
+#, c-format
+msgid "compl(%f): fractional value will be truncated"
+msgstr "compl(%f): å°æ•°ç‚¹ä»¥ä¸‹ã¯åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã™"
-#: builtin.c:2922
-msgid "xor: received non-numeric second argument"
-msgstr "xor: éžæ•°å€¤ã®ç¬¬äºŒå¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
+#: builtin.c:3379
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr "dcgettext: `%s' ã¯ç„¡åŠ¹ãªãƒ­ã‚±ãƒ¼ãƒ«åŒºåˆ†ã§ã™"
-#: builtin.c:2928
+#: command.y:225
#, c-format
-msgid "xor(%lf, %lf): negative values will give strange results"
-msgstr "xor(%lf, %lf): è² ã®æ•°å€¤ã‚’使用ã™ã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
+msgid "Type (g)awk statement(s). End with the command \"end\"\n"
+msgstr ""
-#: builtin.c:2930
+#: command.y:289
#, c-format
-msgid "xor(%lf, %lf): fractional values will be truncated"
-msgstr "xor(%lf, %lf): å°æ•°ç‚¹ä»¥ä¸‹ã¯åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã™"
+msgid "invalid frame number: %d"
+msgstr "無効ãªãƒ•ãƒ¬ãƒ¼ãƒ ç•ªå·ã§ã™: %d"
-#: builtin.c:2954 builtin.c:2960
-msgid "compl: received non-numeric argument"
-msgstr "compl: éžæ•°å€¤ã®å¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
+#: command.y:295
+#, fuzzy, c-format
+msgid "info: invalid option - \"%s\""
+msgstr "info: 無効ãªã‚ªãƒ—ション - \"%s\""
-#: builtin.c:2962
+#: command.y:321
#, c-format
-msgid "compl(%lf): negative value will give strange results"
-msgstr "compl(%lf): è² ã®æ•°å€¤ã‚’使用ã™ã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
+msgid "source \"%s\": already sourced."
+msgstr "source \"%s\": æ—¢ã«èª­ã¿è¾¼ã¾ã‚Œã¦(source)ã„ã¾ã™ã€‚"
-#: builtin.c:2964
+#: command.y:326
#, c-format
-msgid "compl(%lf): fractional value will be truncated"
-msgstr "compl(%lf): å°æ•°ç‚¹ä»¥ä¸‹ã¯åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã™"
+msgid "save \"%s\": command not permitted."
+msgstr "save \"%s\": コマンドã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“。"
+
+#: command.y:339
+msgid "Can't use command `commands' for breakpoint/watchpoint commands"
+msgstr ""
+
+#: command.y:341
+msgid "no breakpoint/watchpoint has been set yet"
+msgstr "ã¾ã ä¸€ã¤ã‚‚ブレークãƒã‚¤ãƒ³ãƒˆ/ウオッãƒãƒã‚¤ãƒ³ãƒˆã¯è¨­å®šã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: builtin.c:3133
+#: command.y:343
+msgid "invalid breakpoint/watchpoint number"
+msgstr "無効ãªãƒ–レークãƒã‚¤ãƒ³ãƒˆ/ウオッãƒãƒã‚¤ãƒ³ãƒˆç•ªå·ã§ã™"
+
+#: command.y:348
#, c-format
-msgid "dcgettext: `%s' is not a valid locale category"
-msgstr "dcgettext: `%s' ã¯ç„¡åŠ¹ãªãƒ­ã‚±ãƒ¼ãƒ«åŒºåˆ†ã§ã™"
+msgid "Type commands for when %s %d is hit, one per line.\n"
+msgstr ""
+
+#: command.y:350
+#, c-format
+msgid "End with the command \"end\"\n"
+msgstr ""
+
+#: command.y:357
+msgid "`end' valid only in command `commands' or `eval'"
+msgstr ""
+
+#: command.y:367
+msgid "`silent' valid only in command `commands'"
+msgstr ""
+
+#: command.y:373
+#, c-format
+msgid "trace: invalid option - \"%s\""
+msgstr "trace: 無効ãªã‚ªãƒ—ション - \"%s\""
+
+#: command.y:387
+msgid "condition: invalid breakpoint/watchpoint number"
+msgstr ""
+
+#: command.y:449
+msgid "argument not a string"
+msgstr "引数ãŒæ–‡å­—列ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
+
+#: command.y:459 command.y:464
+#, c-format
+msgid "option: invalid parameter - \"%s\""
+msgstr "option: 無効ãªãƒ‘ラメーター - \"%s\""
+
+#: command.y:474
+#, c-format
+msgid "no such function - \"%s\""
+msgstr "ãã®ã‚ˆã†ãªé–¢æ•°ã¯ã‚ã‚Šã¾ã›ã‚“ - \"%s\""
+
+#: command.y:531
+#, c-format
+msgid "enable: invalid option - \"%s\""
+msgstr "enable: 無効ãªã‚ªãƒ—ション - \"%s\""
+
+#: command.y:597
+#, c-format
+msgid "invalid range specification: %d - %d"
+msgstr "無効ãªç¯„囲指定: %d - %d"
+
+#: command.y:659
+msgid "non-numeric value for field number"
+msgstr "フィールド番å·ã«å¯¾ã—ã¦éžæ•°å€¤ãŒæŒ‡å®šã•ã‚Œã¦ã„ã¾ã™"
+
+#: command.y:680 command.y:687
+msgid "non-numeric value found, numeric expected"
+msgstr "éžæ•°å€¤ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚数値ãŒäºˆæœŸã•ã‚Œã¾ã™ã€‚"
+
+#: command.y:712 command.y:718
+msgid "non-zero integer value"
+msgstr "éžã‚¼ãƒ­æ•´æ•°"
+
+#: command.y:817
+msgid ""
+"backtrace [N] - print trace of all or N innermost (outermost if N < 0) "
+"frames."
+msgstr ""
+
+#: command.y:819
+msgid ""
+"break [[filename:]N|function] - set breakpoint at the specified location."
+msgstr ""
+
+#: command.y:821
+msgid "clear [[filename:]N|function] - delete breakpoints previously set."
+msgstr ""
+
+#: command.y:823
+msgid ""
+"commands [num] - starts a list of commands to be executed at a "
+"breakpoint(watchpoint) hit."
+msgstr ""
+
+#: command.y:825
+msgid "condition num [expr] - set or clear breakpoint or watchpoint condition."
+msgstr ""
+
+#: command.y:827
+msgid "continue [COUNT] - continue program being debugged."
+msgstr ""
+
+#: command.y:829
+msgid "delete [breakpoints] [range] - delete specified breakpoints."
+msgstr ""
+
+#: command.y:831
+msgid "disable [breakpoints] [range] - disable specified breakpoints."
+msgstr ""
+
+#: command.y:833
+msgid "display [var] - print value of variable each time the program stops."
+msgstr ""
+
+#: command.y:835
+msgid "down [N] - move N frames down the stack."
+msgstr ""
+
+#: command.y:837
+msgid "dump [filename] - dump instructions to file or stdout."
+msgstr ""
+
+#: command.y:839
+msgid "enable [once|del] [breakpoints] [range] - enable specified breakpoints."
+msgstr ""
+
+#: command.y:841
+msgid "end - end a list of commands or awk statements."
+msgstr ""
+
+#: command.y:843
+msgid "eval stmt|[p1, p2, ...] - evaluate awk statement(s)."
+msgstr ""
+
+#: command.y:845
+msgid "finish - execute until selected stack frame returns."
+msgstr ""
+
+#: command.y:847
+msgid "frame [N] - select and print stack frame number N."
+msgstr ""
+
+#: command.y:849
+msgid "help [command] - print list of commands or explanation of command."
+msgstr ""
+
+#: command.y:851
+msgid "ignore N COUNT - set ignore-count of breakpoint number N to COUNT."
+msgstr ""
+
+#: command.y:853
+msgid ""
+"info topic - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch."
+msgstr ""
+
+#: command.y:855
+msgid "list [-|+|[filename:]lineno|function|range] - list specified line(s)."
+msgstr ""
+
+#: command.y:857
+msgid "next [COUNT] - step program, proceeding through subroutine calls."
+msgstr ""
+
+#: command.y:859
+msgid ""
+"nexti [COUNT] - step one instruction, but proceed through subroutine calls."
+msgstr ""
+
+#: command.y:861
+msgid "option [name[=value]] - set or display debugger option(s)."
+msgstr ""
+
+#: command.y:863
+msgid "print var [var] - print value of a variable or array."
+msgstr ""
+
+#: command.y:865
+msgid "printf format, [arg], ... - formatted output."
+msgstr ""
+
+#: command.y:867
+msgid "quit - exit debugger."
+msgstr ""
+
+#: command.y:869
+msgid "return [value] - make selected stack frame return to its caller."
+msgstr ""
+
+#: command.y:871
+msgid "run - start or restart executing program."
+msgstr ""
+
+#: command.y:874
+msgid "save filename - save commands from the session to file."
+msgstr ""
+
+#: command.y:877
+msgid "set var = value - assign value to a scalar variable."
+msgstr ""
+
+#: command.y:879
+msgid ""
+"silent - suspends usual message when stopped at a breakpoint/watchpoint."
+msgstr ""
+
+#: command.y:881
+msgid "source file - execute commands from file."
+msgstr ""
+
+#: command.y:883
+msgid "step [COUNT] - step program until it reaches a different source line."
+msgstr ""
+
+#: command.y:885
+msgid "stepi [COUNT] - step one instruction exactly."
+msgstr ""
+
+#: command.y:887
+msgid "tbreak [[filename:]N|function] - set a temporary breakpoint."
+msgstr ""
+
+#: command.y:889
+msgid "trace on|off - print instruction before executing."
+msgstr ""
+
+#: command.y:891
+msgid "undisplay [N] - remove variable(s) from automatic display list."
+msgstr ""
+
+#: command.y:893
+msgid ""
+"until [[filename:]N|function] - execute until program reaches a different "
+"line or line N within current frame."
+msgstr ""
+
+#: command.y:895
+msgid "unwatch [N] - remove variable(s) from watch list."
+msgstr ""
+
+#: command.y:897
+msgid "up [N] - move N frames up the stack."
+msgstr ""
+
+#: command.y:899
+msgid "watch var - set a watchpoint for a variable."
+msgstr ""
+
+#: command.y:1011 debug.c:401 msg.c:135
+#, c-format
+msgid "error: "
+msgstr "エラー: "
+
+#: command.y:1051
+#, fuzzy, c-format
+msgid "can't read command (%s)\n"
+msgstr "`%s' ã‹ã‚‰ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã§ãã¾ã›ã‚“ (%s)"
+
+#: command.y:1065
+#, fuzzy, c-format
+msgid "can't read command (%s)"
+msgstr "`%s' ã‹ã‚‰ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã§ãã¾ã›ã‚“ (%s)"
+
+#: command.y:1116
+#, fuzzy
+msgid "invalid character in command"
+msgstr "無効ãªæ–‡å­—クラスåã§ã™"
+
+#: command.y:1152
+#, c-format
+msgid "unknown command - \"%.*s\", try help"
+msgstr ""
+
+#: command.y:1222
+#, c-format
+msgid "%s"
+msgstr ""
+
+#: command.y:1284
+msgid "invalid character"
+msgstr "無効ãªæ–‡å­—ã§ã™"
+
+#: command.y:1455
+#, c-format
+msgid "undefined command: %s\n"
+msgstr ""
+
+#: debug.c:252
+msgid "set or show the number of lines to keep in history file."
+msgstr ""
+
+#: debug.c:254
+msgid "set or show the list command window size."
+msgstr ""
+
+#: debug.c:256
+msgid "set or show gawk output file."
+msgstr ""
+
+#: debug.c:258
+msgid "set or show debugger prompt."
+msgstr ""
+
+#: debug.c:260
+msgid "(un)set or show saving of command history (value=on|off)."
+msgstr ""
+
+#: debug.c:262
+msgid "(un)set or show saving of options (value=on|off)."
+msgstr ""
+
+#: debug.c:264
+msgid "(un)set or show instruction tracing (value=on|off)."
+msgstr ""
+
+#: debug.c:345
+msgid "program not running."
+msgstr ""
+
+#: debug.c:448 debug.c:606
+#, fuzzy, c-format
+msgid "can't read source file `%s' (%s)"
+msgstr "ソースファイル `%s' を読ã¿è¾¼ã‚ã¾ã›ã‚“ (%s)"
+
+#: debug.c:453
+#, fuzzy, c-format
+msgid "source file `%s' is empty.\n"
+msgstr "ソースファイル `%s' ã¯ç©ºã§ã™"
+
+#: debug.c:480
+msgid "no current source file."
+msgstr ""
+
+#: debug.c:505
+#, fuzzy, c-format
+msgid "cannot find source file named `%s' (%s)"
+msgstr "ソースファイル `%s' を読ã¿è¾¼ã‚ã¾ã›ã‚“ (%s)"
+
+#: debug.c:529
+#, c-format
+msgid "WARNING: source file `%s' modified since program compilation.\n"
+msgstr ""
+
+#: debug.c:551
+#, c-format
+msgid "line number %d out of range; `%s' has %d lines"
+msgstr ""
+
+#: debug.c:611
+#, fuzzy, c-format
+msgid "unexpected eof while reading file `%s', line %d"
+msgstr "予期ã—ãªã„改行ã¾ãŸã¯æ–‡å­—列終端ã§ã™"
+
+#: debug.c:620
+#, c-format
+msgid "source file `%s' modified since start of program execution"
+msgstr ""
+
+#: debug.c:732
+#, fuzzy, c-format
+msgid "Current source file: %s\n"
+msgstr "ソースファイル `%s' ã¯æ—¢ã«èª­ã¿è¾¼ã¾ã‚Œã¦ã„ã¾ã™"
+
+#: debug.c:733
+#, c-format
+msgid "Number of lines: %d\n"
+msgstr ""
+
+#: debug.c:740
+#, c-format
+msgid "Source file (lines): %s (%d)\n"
+msgstr ""
+
+#: debug.c:754
+msgid ""
+"Number Disp Enabled Location\n"
+"\n"
+msgstr ""
+
+#: debug.c:765
+#, c-format
+msgid "\tno of hits = %ld\n"
+msgstr ""
+
+#: debug.c:767
+#, c-format
+msgid "\tignore next %ld hit(s)\n"
+msgstr ""
+
+#: debug.c:769 debug.c:909
+#, c-format
+msgid "\tstop condition: %s\n"
+msgstr ""
+
+#: debug.c:771 debug.c:911
+msgid "\tcommands:\n"
+msgstr ""
+
+#: debug.c:793
+#, c-format
+msgid "Current frame: "
+msgstr ""
+
+#: debug.c:796
+#, c-format
+msgid "Called by frame: "
+msgstr ""
+
+#: debug.c:800
+#, c-format
+msgid "Caller of frame: "
+msgstr ""
+
+#: debug.c:818
+#, c-format
+msgid "None in main().\n"
+msgstr ""
+
+#: debug.c:848
+#, fuzzy
+msgid "No arguments.\n"
+msgstr "printf: 引数ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: debug.c:849
+msgid "No locals.\n"
+msgstr ""
+
+#: debug.c:857
+msgid ""
+"All defined variables:\n"
+"\n"
+msgstr ""
+
+#: debug.c:867
+msgid ""
+"All defined functions:\n"
+"\n"
+msgstr ""
+
+#: debug.c:886
+msgid ""
+"Auto-display variables:\n"
+"\n"
+msgstr ""
+
+#: debug.c:889
+msgid ""
+"Watch variables:\n"
+"\n"
+msgstr ""
+
+#: debug.c:1029
+#, c-format
+msgid "no symbol `%s' in current context\n"
+msgstr ""
+
+#: debug.c:1041 debug.c:1427
+#, fuzzy, c-format
+msgid "`%s' is not an array\n"
+msgstr "`%s' ã¯ä¸æ­£ãªå¤‰æ•°åã§ã™"
+
+#: debug.c:1055
+#, fuzzy, c-format
+msgid "$%ld = uninitialized field\n"
+msgstr "åˆæœŸåŒ–ã•ã‚Œã¦ã„ãªã„フィールド `$%d' ã¸ã®å‚ç…§ã§ã™"
+
+#: debug.c:1076
+#, fuzzy, c-format
+msgid "array `%s' is empty\n"
+msgstr "データファイル `%s' ã¯ç©ºã§ã™ã€‚"
+
+#: debug.c:1119 debug.c:1171
+#, fuzzy, c-format
+msgid "[\"%s\"] not in array `%s'\n"
+msgstr "delete: é…列 `%2$s' 内ã«ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ `%1$s' ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: debug.c:1175
+#, c-format
+msgid "`%s[\"%s\"]' is not an array\n"
+msgstr ""
+
+#: debug.c:1236 debug.c:4964
+#, fuzzy, c-format
+msgid "`%s' is not a scalar variable"
+msgstr "`%s' ã¯ä¸æ­£ãªå¤‰æ•°åã§ã™"
+
+#: debug.c:1258 debug.c:4994
+#, fuzzy, c-format
+msgid "attempt to use array `%s[\"%s\"]' in a scalar context"
+msgstr "スカラーコンテキスト内ã§é…列 `%s[\"%.*s\"]' ã®ä½¿ç”¨ã®è©¦ã¿ã§ã™"
+
+#: debug.c:1280 debug.c:5005
+#, fuzzy, c-format
+msgid "attempt to use scalar `%s[\"%s\"]' as array"
+msgstr "スカラー `%s[\"%.*s\"]' ã‚’é…列ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹è©¦ã¿ã§ã™"
+
+#: debug.c:1423
+#, fuzzy, c-format
+msgid "`%s' is a function"
+msgstr "`%s' ã¯é–¢æ•°åã¨ã—ã¦ã¯ç„¡åŠ¹ã§ã™"
+
+#: debug.c:1465
+#, c-format
+msgid "watchpoint %d is unconditional\n"
+msgstr ""
+
+#: debug.c:1499
+#, c-format
+msgid "No display item numbered %ld"
+msgstr ""
+
+#: debug.c:1502
+#, c-format
+msgid "No watch item numbered %ld"
+msgstr ""
+
+#: debug.c:1528
+#, fuzzy, c-format
+msgid "%d: [\"%s\"] not in array `%s'\n"
+msgstr "delete: é…列 `%2$s' 内ã«ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ `%1$s' ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: debug.c:1767
+#, fuzzy
+msgid "attempt to use scalar value as array"
+msgstr "スカラー値をé…列ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹è©¦ã¿ã§ã™"
+
+#: debug.c:1856
+#, c-format
+msgid "Watchpoint %d deleted because parameter is out of scope.\n"
+msgstr ""
+
+#: debug.c:1867
+#, c-format
+msgid "Display %d deleted because parameter is out of scope.\n"
+msgstr ""
+
+#: debug.c:1900
+#, c-format
+msgid " in file `%s', line %d\n"
+msgstr ""
+
+#: debug.c:1921
+#, c-format
+msgid " at `%s':%d"
+msgstr ""
+
+#: debug.c:1937 debug.c:2000
+#, c-format
+msgid "#%ld\tin "
+msgstr ""
+
+#: debug.c:1974
+#, c-format
+msgid "More stack frames follow ...\n"
+msgstr ""
+
+#: debug.c:2017
+#, fuzzy
+msgid "invalid frame number"
+msgstr "無効ãªç¯„囲終了ã§ã™"
+
+#: debug.c:2200
+#, c-format
+msgid "Note: breakpoint %d (enabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2207
+#, c-format
+msgid "Note: breakpoint %d (enabled), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2214
+#, c-format
+msgid "Note: breakpoint %d (disabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2221
+#, c-format
+msgid "Note: breakpoint %d (disabled), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2238
+#, c-format
+msgid "Breakpoint %d set at file `%s', line %d\n"
+msgstr ""
+
+#: debug.c:2340
+#, c-format
+msgid "Can't set breakpoint in file `%s'\n"
+msgstr ""
+
+#: debug.c:2369 debug.c:2492 debug.c:3350
+#, fuzzy, c-format
+msgid "line number %d in file `%s' out of range"
+msgstr "exp: 引数 %g ãŒç¯„囲外ã§ã™"
+
+#: debug.c:2373
+#, c-format
+msgid "Can't find rule!!!\n"
+msgstr ""
+
+#: debug.c:2375
+#, c-format
+msgid "Can't set breakpoint at `%s':%d\n"
+msgstr ""
+
+#: debug.c:2387
+#, c-format
+msgid "Can't set breakpoint in function `%s'\n"
+msgstr ""
+
+#: debug.c:2403
+#, c-format
+msgid "breakpoint %d set at file `%s', line %d is unconditional\n"
+msgstr ""
+
+#: debug.c:2508 debug.c:2530
+#, c-format
+msgid "Deleted breakpoint %d"
+msgstr ""
+
+#: debug.c:2514
+#, c-format
+msgid "No breakpoint(s) at entry to function `%s'\n"
+msgstr ""
+
+#: debug.c:2541
+#, fuzzy, c-format
+msgid "No breakpoint at file `%s', line #%d\n"
+msgstr "入力ファイル `%s' を読ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s"
+
+#: debug.c:2596 debug.c:2637 debug.c:2657 debug.c:2700
+msgid "invalid breakpoint number"
+msgstr ""
+
+#: debug.c:2612
+msgid "Delete all breakpoints? (y or n) "
+msgstr ""
+
+#: debug.c:2613 debug.c:2923 debug.c:2976
+msgid "y"
+msgstr ""
+
+#: debug.c:2662
+#, c-format
+msgid "Will ignore next %ld crossing(s) of breakpoint %d.\n"
+msgstr ""
+
+#: debug.c:2666
+#, c-format
+msgid "Will stop next time breakpoint %d is reached.\n"
+msgstr ""
+
+#: debug.c:2783
+#, c-format
+msgid "Can only debug programs provided with the `-f' option.\n"
+msgstr ""
+
+#: debug.c:2908
+#, c-format
+msgid "Failed to restart debugger"
+msgstr ""
+
+#: debug.c:2922
+msgid "Program already running. Restart from beginning (y/n)? "
+msgstr ""
+
+#: debug.c:2926
+#, c-format
+msgid "Program not restarted\n"
+msgstr ""
+
+#: debug.c:2936
+#, c-format
+msgid "error: cannot restart, operation not allowed\n"
+msgstr ""
+
+#: debug.c:2942
+#, c-format
+msgid "error (%s): cannot restart, ignoring rest of the commands\n"
+msgstr ""
+
+#: debug.c:2950
+#, c-format
+msgid "Starting program: \n"
+msgstr ""
+
+#: debug.c:2959
+#, c-format
+msgid "Program exited %s with exit value: %d\n"
+msgstr ""
+
+#: debug.c:2975
+msgid "The program is running. Exit anyway (y/n)? "
+msgstr ""
+
+#: debug.c:3010
+#, c-format
+msgid "Not stopped at any breakpoint; argument ignored.\n"
+msgstr ""
+
+#: debug.c:3015
+#, c-format
+msgid "invalid breakpoint number %d."
+msgstr ""
+
+#: debug.c:3020
+#, c-format
+msgid "Will ignore next %ld crossings of breakpoint %d.\n"
+msgstr ""
+
+#: debug.c:3207
+#, c-format
+msgid "'finish' not meaningful in the outermost frame main()\n"
+msgstr ""
+
+#: debug.c:3212
+#, c-format
+msgid "Run till return from "
+msgstr ""
+
+#: debug.c:3255
+#, c-format
+msgid "'return' not meaningful in the outermost frame main()\n"
+msgstr ""
+
+#: debug.c:3369
+#, c-format
+msgid "Can't find specified location in function `%s'\n"
+msgstr ""
+
+#: debug.c:3377
+#, fuzzy, c-format
+msgid "invalid source line %d in file `%s'"
+msgstr "ソースファイル `%s' ã¯æ—¢ã«èª­ã¿è¾¼ã¾ã‚Œã¦ã„ã¾ã™"
+
+#: debug.c:3392
+#, c-format
+msgid "Can't find specified location %d in file `%s'\n"
+msgstr ""
+
+#: debug.c:3424
+#, fuzzy, c-format
+msgid "element not in array\n"
+msgstr "adump: 引数ãŒé…列ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
+
+#: debug.c:3424
+#, c-format
+msgid "untyped variable\n"
+msgstr ""
+
+#: debug.c:3466
+#, c-format
+msgid "Stopping in %s ...\n"
+msgstr ""
+
+#: debug.c:3543
+#, c-format
+msgid "'finish' not meaningful with non-local jump '%s'\n"
+msgstr ""
+
+#: debug.c:3550
+#, c-format
+msgid "'until' not meaningful with non-local jump '%s'\n"
+msgstr ""
+
+#: debug.c:4185
+msgid "\t------[Enter] to continue or q [Enter] to quit------"
+msgstr ""
+
+#: debug.c:4186
+msgid "q"
+msgstr ""
+
+#: debug.c:5001
+#, fuzzy, c-format
+msgid "[\"%s\"] not in array `%s'"
+msgstr "delete: é…列 `%2$s' 内ã«ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ `%1$s' ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: debug.c:5207
+#, c-format
+msgid "sending output to stdout\n"
+msgstr ""
-#: eval.c:412
+#: debug.c:5247
+msgid "invalid number"
+msgstr ""
+
+#: debug.c:5381
+#, c-format
+msgid "`%s' not allowed in current context; statement ignored"
+msgstr ""
+
+#: debug.c:5389
+msgid "`return' not allowed in current context; statement ignored"
+msgstr ""
+
+#: debug.c:5590
+#, c-format
+msgid "No symbol `%s' in current context"
+msgstr ""
+
+#: dfa.c:1118 dfa.c:1121 dfa.c:1142 dfa.c:1150 dfa.c:1162 dfa.c:1197
+#: dfa.c:1206 dfa.c:1209 dfa.c:1214 dfa.c:1228 dfa.c:1275
+msgid "unbalanced ["
+msgstr ""
+
+#: dfa.c:1174
+#, fuzzy
+msgid "invalid character class"
+msgstr "無効ãªæ–‡å­—クラスåã§ã™"
+
+#: dfa.c:1316
+msgid "character class syntax is [[:space:]], not [:space:]"
+msgstr ""
+
+#: dfa.c:1366
+msgid "unfinished \\ escape"
+msgstr ""
+
+#: dfa.c:1513 regcomp.c:161
+msgid "Invalid content of \\{\\}"
+msgstr "\\{\\} ã®ä¸­èº«ãŒç„¡åŠ¹ã§ã™"
+
+#: dfa.c:1516 regcomp.c:176
+msgid "Regular expression too big"
+msgstr "æ­£è¦è¡¨ç¾ãŒå¤§ãã™ãŽã¾ã™"
+
+#: dfa.c:1936
+msgid "unbalanced ("
+msgstr ""
+
+#: dfa.c:2062
+msgid "no syntax specified"
+msgstr ""
+
+#: dfa.c:2070
+msgid "unbalanced )"
+msgstr ""
+
+#: eval.c:394
#, c-format
msgid "unknown nodetype %d"
msgstr "ä¸æ˜ŽãªãƒŽãƒ¼ãƒ‰åž‹ %d ã§ã™"
-#: eval.c:423 eval.c:437
+#: eval.c:405 eval.c:419
#, c-format
msgid "unknown opcode %d"
msgstr "ä¸æ˜Žãªã‚ªãƒšã‚³ãƒ¼ãƒ‰ %d ã§ã™"
-#: eval.c:434
+#: eval.c:416
#, c-format
msgid "opcode %s not an operator or keyword"
msgstr "オペコード %s ã¯æ¼”ç®—å­ã¾ãŸã¯äºˆç´„語ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: eval.c:488
+#: eval.c:472
msgid "buffer overflow in genflags2str"
msgstr "genflags2str 内ã§ãƒãƒƒãƒ•ã‚¡ã‚ªãƒ¼ãƒãƒ¼ãƒ•ãƒ­ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
-#: eval.c:698
+#: eval.c:675
#, c-format
msgid ""
"\n"
@@ -981,807 +1826,1264 @@ msgstr ""
"\t# 呼出関数スタック:\n"
"\n"
-#: eval.c:725
+#: eval.c:704
msgid "`IGNORECASE' is a gawk extension"
msgstr "`IGNORECASE' 㯠gawk æ‹¡å¼µã§ã™"
-#: eval.c:754
+#: eval.c:736
msgid "`BINMODE' is a gawk extension"
msgstr "`BINMODE' 㯠gawk æ‹¡å¼µã§ã™"
-#: eval.c:812
+#: eval.c:794
#, c-format
msgid "BINMODE value `%s' is invalid, treated as 3"
msgstr "BINMODE 値 `%s' ã¯ç„¡åŠ¹ã§ã™ã€‚代ã‚ã‚Šã« 3 を使用ã—ã¾ã™"
-#: eval.c:902
+#: eval.c:885
#, c-format
msgid "bad `%sFMT' specification `%s'"
msgstr "誤ã£ãŸ `%sFMT' 指定 `%s' ã§ã™"
-#: eval.c:980
+#: eval.c:969
msgid "turning off `--lint' due to assignment to `LINT'"
msgstr "`LINT' ã¸ã®ä»£å…¥ã«å¾“ã„ `--lint' を無効ã«ã—ã¾ã™"
-#: eval.c:1127 eval.c:1777
-#, c-format
-msgid "can't use function name `%s' as variable or array"
-msgstr "関数å `%s' ã¯å¤‰æ•°ã¾ãŸã¯é…列ã¨ã—ã¦ä½¿ç”¨å‡ºæ¥ã¾ã›ã‚“"
-
-#: eval.c:1158 eval.c:1789 eval.c:1802
+#: eval.c:1147
#, c-format
msgid "reference to uninitialized argument `%s'"
msgstr "åˆæœŸåŒ–ã•ã‚Œã¦ã„ãªã„引数 `%s' ã¸ã®å‚ç…§ã§ã™"
-#: eval.c:1177
+#: eval.c:1148
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "åˆæœŸåŒ–ã•ã‚Œã¦ã„ãªã„変数 `%s' ã¸ã®å‚ç…§ã§ã™"
+
+#: eval.c:1166
msgid "attempt to field reference from non-numeric value"
msgstr "éžæ•°å€¤ã‚’使用ã—ãŸãƒ•ã‚¤ãƒ¼ãƒ«ãƒ‰å‚ç…§ã®è©¦ã¿ã§ã™"
-#: eval.c:1179
+#: eval.c:1168
msgid "attempt to field reference from null string"
msgstr "NULL 文字列を使用ã—ã¦ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã®å‚照を試ã¿ã¦ã„ã¾ã™"
-#: eval.c:1185
+#: eval.c:1176
#, c-format
msgid "attempt to access field %ld"
msgstr "フィールド %ld ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã®è©¦ã¿ã§ã™"
-#: eval.c:1194
+#: eval.c:1185
#, c-format
msgid "reference to uninitialized field `$%ld'"
msgstr "åˆæœŸåŒ–ã•ã‚Œã¦ã„ãªã„フィールド `$%ld' ã¸ã®å‚ç…§ã§ã™"
-#: eval.c:1256
+#: eval.c:1272
#, c-format
msgid "function `%s' called with more arguments than declared"
msgstr "宣言ã•ã‚Œã¦ã„る数より多ã„引数を使ã£ã¦é–¢æ•° `%s' を呼ã³å‡ºã—ã¾ã—ãŸ"
-#: eval.c:1437
+#: eval.c:1473
#, c-format
msgid "unwind_stack: unexpected type `%s'"
msgstr "unwind_stack: 予期ã—ãªã„åž‹ `%s' ã§ã™"
-#: eval.c:1532
+#: eval.c:1569
msgid "division by zero attempted in `/='"
msgstr "`/=' 内ã§ã‚¼ãƒ­ã«ã‚ˆã‚‹é™¤ç®—ãŒè¡Œã‚ã‚Œã¾ã—ãŸ"
-#: eval.c:1539
+#: eval.c:1576
#, c-format
msgid "division by zero attempted in `%%='"
msgstr "`%%=' 内ã§ã‚¼ãƒ­ã«ã‚ˆã‚‹é™¤ç®—ãŒè¡Œã‚ã‚Œã¾ã—ãŸ"
-#: eval.c:1876 eval.c:2122
-#, c-format
-msgid "attempt to use array `%s[\"%.*s\"]' in a scalar context"
-msgstr "スカラーコンテキスト内ã§é…列 `%s[\"%.*s\"]' ã®ä½¿ç”¨ã®è©¦ã¿ã§ã™"
-
-#: eval.c:1907
-msgid "assignment used in conditional context"
-msgstr "æ¡ä»¶ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆå†…ã§ä»£å…¥ãŒä½¿ç”¨ã•ã‚Œã¾ã—ãŸ"
+#: ext.c:89 ext.c:171
+msgid "extensions are not allowed in sandbox mode"
+msgstr "サンドボックスモード内ã§ã¯æ‹¡å¼µã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: eval.c:1911
-msgid "statement has no effect"
-msgstr "æ–‡ã«åŠ¹æžœãŒã‚ã‚Šã¾ã›ã‚“"
+#: ext.c:92
+#, fuzzy
+msgid "-l / @load are gawk extensions"
+msgstr "@include 㯠gawk æ‹¡å¼µã§ã™"
-#: eval.c:2343
-#, c-format
-msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
+#: ext.c:95
+msgid "load_ext: received NULL lib_name"
msgstr ""
-"for ループ: ループ実行中ã«é…列 `%s' ã®ã‚µã‚¤ã‚ºãŒ %ld ã‹ã‚‰ %ld ã¸å¤‰æ›´ã•ã‚Œã¾ã—ãŸ"
-#: eval.c:2458
-#, c-format
-msgid "function called indirectly through `%s' does not exist"
-msgstr "`%s' を通ã—ã¦é–“接的ã«å‘¼ã³å‡ºã•ã‚ŒãŸé–¢æ•°ãŒå­˜åœ¨ã—ã¾ã›ã‚“"
-
-#: eval.c:2470
-#, c-format
-msgid "function `%s' not defined"
-msgstr "関数 `%s' ã¯å®šç¾©ã•ã‚Œã¦ã„ã¾ã›ã‚“"
-
-#: eval.c:2511
-#, c-format
-msgid "non-redirected `getline' invalid inside `%s' rule"
-msgstr "`%s' ルールã®å†…å´ã§ã¯ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã•ã‚Œã¦ã„ãªã„ `getline' ã¯ç„¡åŠ¹ã§ã™"
-
-#: eval.c:2600
-#, c-format
-msgid "error reading input file `%s': %s"
-msgstr "入力ファイル `%s' を読ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s"
+#: ext.c:98
+#, fuzzy, c-format
+msgid "load_ext: cannot open library `%s' (%s)\n"
+msgstr "致命的: extension: `%s' ã‚’é–‹ãã“ã¨ãŒå‡ºæ¥ã¾ã›ã‚“ (%s)\n"
-#: eval.c:2614
-#, c-format
-msgid "`nextfile' cannot be called from a `%s' rule"
-msgstr "`nextfile' 㯠`%s' ルールã‹ã‚‰å‘¼ã³å‡ºã™ã“ã¨ãŒå‡ºæ¥ã¾ã›ã‚“"
+#: ext.c:104
+#, fuzzy, c-format
+msgid ""
+"load_ext: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"
+msgstr ""
+"致命的: extension: ライブラリ `%s': `plugin_is_GPL_compatible' ãŒå®šç¾©ã•ã‚Œã¦ã„"
+"ã¾ã›ã‚“ (%s)\n"
-#: eval.c:2694
-#, c-format
-msgid "`next' cannot be called from a `%s' rule"
-msgstr "`next' 㯠`%s' ã‹ã‚‰å‘¼ã³å‡ºã™ã“ã¨ãŒå‡ºæ¥ã¾ã›ã‚“"
+#: ext.c:110
+#, fuzzy, c-format
+msgid "load_ext: library `%s': cannot call function `%s' (%s)\n"
+msgstr ""
+"致命的: extension: ライブラリ `%s': 関数 `%s' を呼ã³å‡ºã™ã“ã¨ãŒå‡ºæ¥ã¾ã›ã‚“ "
+"(%s)\n"
-#: eval.c:2760
+#: ext.c:114
#, c-format
-msgid "Sorry, don't know how to interpret `%s'"
-msgstr "申ã—訳ã‚ã‚Šã¾ã›ã‚“㌠`%s' ã‚’ã©ã®ã‚ˆã†ã«è§£é‡ˆã™ã‚‹ã‹åˆ†ã‹ã‚Šã¾ã›ã‚“"
-
-#: ext.c:64
-msgid "extensions are not allowed in sandbox mode"
-msgstr "サンドボックスモード内ã§ã¯æ‹¡å¼µã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+msgid "load_ext: library `%s' initialization routine `%s' failed\n"
+msgstr ""
-#: ext.c:70 ext.c:75
+#: ext.c:174
msgid "`extension' is a gawk extension"
msgstr "`extension' 㯠gawk æ‹¡å¼µã§ã™"
-#: ext.c:85
-#, c-format
-msgid "fatal: extension: cannot open `%s' (%s)\n"
+#: ext.c:177
+msgid "extension: received NULL lib_name"
+msgstr ""
+
+#: ext.c:180
+#, fuzzy, c-format
+msgid "extension: cannot open library `%s' (%s)"
msgstr "致命的: extension: `%s' ã‚’é–‹ãã“ã¨ãŒå‡ºæ¥ã¾ã›ã‚“ (%s)\n"
-#: ext.c:94
-#, c-format
+#: ext.c:186
+#, fuzzy, c-format
msgid ""
-"fatal: extension: library `%s': does not define "
-"`plugin_is_GPL_compatible' (%s)\n"
+"extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)"
msgstr ""
"致命的: extension: ライブラリ `%s': `plugin_is_GPL_compatible' ãŒå®šç¾©ã•ã‚Œã¦ã„"
"ã¾ã›ã‚“ (%s)\n"
-#: ext.c:103
-#, c-format
-msgid "fatal: extension: library `%s': cannot call function `%s' (%s)\n"
+#: ext.c:190
+#, fuzzy, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)"
msgstr ""
"致命的: extension: ライブラリ `%s': 関数 `%s' を呼ã³å‡ºã™ã“ã¨ãŒå‡ºæ¥ã¾ã›ã‚“ "
"(%s)\n"
-#: ext.c:137
+#: ext.c:221
+#, fuzzy
+msgid "make_builtin: missing function name"
+msgstr "extension: 関数åãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: ext.c:236
+#, fuzzy, c-format
+msgid "make_builtin: can't redefine function `%s'"
+msgstr "extension: 関数 `%s' ã‚’å†å®šç¾©ã§ãã¾ã›ã‚“"
+
+#: ext.c:240
+#, fuzzy, c-format
+msgid "make_builtin: function `%s' already defined"
+msgstr "extension: 関数 `%s' ã¯æ—¢ã«å®šç¾©ã•ã‚Œã¦ã„ã¾ã™"
+
+#: ext.c:244
+#, fuzzy, c-format
+msgid "make_builtin: function name `%s' previously defined"
+msgstr "extension: 関数å `%s' ã¯å‰ã«å®šç¾©ã•ã‚Œã¦ã„ã¾ã™"
+
+#: ext.c:246
+#, fuzzy, c-format
+msgid "make_builtin: can't use gawk built-in `%s' as function name"
+msgstr "extension: gawk ã«çµ„ã¿è¾¼ã¾ã‚Œã¦ã„ã‚‹ `%s' ã¯é–¢æ•°åã¨ã—ã¦ä½¿ç”¨å‡ºæ¥ã¾ã›ã‚“"
+
+#: ext.c:249 ext.c:304
+#, c-format
+msgid "make_builtin: negative argument count for function `%s'"
+msgstr "make_builtin: 関数 `%s' ã®å¼•æ•°ã®æ•°ãŒè² ã§ã™"
+
+#: ext.c:276
msgid "extension: missing function name"
msgstr "extension: 関数åãŒã‚ã‚Šã¾ã›ã‚“"
-#: ext.c:142
+#: ext.c:279 ext.c:283
#, c-format
msgid "extension: illegal character `%c' in function name `%s'"
msgstr "extension: 関数å `%2$s' ã®ä¸­ã§ä¸æ­£ãªæ–‡å­— `%1$c' ãŒä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™"
-#: ext.c:151
+#: ext.c:291
#, c-format
msgid "extension: can't redefine function `%s'"
msgstr "extension: 関数 `%s' ã‚’å†å®šç¾©ã§ãã¾ã›ã‚“"
-#: ext.c:155
+#: ext.c:295
#, c-format
msgid "extension: function `%s' already defined"
msgstr "extension: 関数 `%s' ã¯æ—¢ã«å®šç¾©ã•ã‚Œã¦ã„ã¾ã™"
-#: ext.c:160
+#: ext.c:299
#, c-format
msgid "extension: function name `%s' previously defined"
msgstr "extension: 関数å `%s' ã¯å‰ã«å®šç¾©ã•ã‚Œã¦ã„ã¾ã™"
-#: ext.c:162
+#: ext.c:301
#, c-format
msgid "extension: can't use gawk built-in `%s' as function name"
msgstr "extension: gawk ã«çµ„ã¿è¾¼ã¾ã‚Œã¦ã„ã‚‹ `%s' ã¯é–¢æ•°åã¨ã—ã¦ä½¿ç”¨å‡ºæ¥ã¾ã›ã‚“"
-#: ext.c:166
-#, c-format
-msgid "make_builtin: negative argument count for function `%s'"
-msgstr "make_builtin: 関数 `%s' ã®å¼•æ•°ã®æ•°ãŒè² ã§ã™"
-
-#: ext.c:269
+#: ext.c:375
#, c-format
msgid "function `%s' defined to take no more than %d argument(s)"
msgstr "関数 `%s' ã«ä½¿ãˆã‚‹å¼•æ•°ã®æ•°ã¯ `%d' 以下ã¨å®šç¾©ã•ã‚Œã¦ã„ã¾ã™"
-#: ext.c:272
+#: ext.c:378
#, c-format
msgid "function `%s': missing argument #%d"
msgstr "関数 `%s': 引数 #%d ãŒã‚ã‚Šã¾ã›ã‚“"
-#: ext.c:289
+#: ext.c:395
#, c-format
msgid "function `%s': argument #%d: attempt to use scalar as an array"
msgstr "関数 `%s': 引数 #%d: スカラーをé…列ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹è©¦ã¿ã§ã™"
-#: ext.c:293
+#: ext.c:399
#, c-format
msgid "function `%s': argument #%d: attempt to use array as a scalar"
msgstr "関数 `%s': 引数 #%d: é…列をスカラーã¨ã—ã¦ä½¿ç”¨ã™ã‚‹è©¦ã¿ã§ã™"
-#: ext.c:306
-msgid "Operation Not Supported"
-msgstr "ã“ã®æ“作ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“"
+#: ext.c:413
+msgid "dynamic loading of library not supported"
+msgstr ""
+
+#: extension/filefuncs.c:159
+#, fuzzy
+msgid "chdir: called with incorrect number of arguments, expecting 1"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/filefuncs.c:439
+#, c-format
+msgid "stat: unable to read symbolic link `%s'"
+msgstr ""
+
+#: extension/filefuncs.c:472
+#, fuzzy
+msgid "stat: called with wrong number of arguments"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/filefuncs.c:479
+#, fuzzy
+msgid "stat: bad parameters"
+msgstr "%s: 仮引数ã§ã™\n"
+
+#: extension/filefuncs.c:533
+#, c-format
+msgid "fts init: could not create variable %s"
+msgstr ""
+
+#: extension/filefuncs.c:554
+#, fuzzy
+msgid "fts is not supported on this system"
+msgstr "å¤ã„ awk 㯠`%s' をサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
+
+#: extension/filefuncs.c:573
+msgid "fill_stat_element: could not create array"
+msgstr ""
+
+#: extension/filefuncs.c:582
+msgid "fill_stat_element: could not set element"
+msgstr ""
+
+#: extension/filefuncs.c:597
+msgid "fill_path_element: could not set element"
+msgstr ""
+
+#: extension/filefuncs.c:613
+msgid "fill_error_element: could not set element"
+msgstr ""
+
+#: extension/filefuncs.c:660 extension/filefuncs.c:707
+msgid "fts-process: could not create array"
+msgstr ""
+
+#: extension/filefuncs.c:670 extension/filefuncs.c:717
+#: extension/filefuncs.c:735
+msgid "fts-process: could not set element"
+msgstr ""
+
+#: extension/filefuncs.c:784
+#, fuzzy
+msgid "fts: called with incorrect number of arguments, expecting 3"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/filefuncs.c:787
+#, fuzzy
+msgid "fts: bad first parameter"
+msgstr "%s: 仮引数ã§ã™\n"
+
+#: extension/filefuncs.c:793
+#, fuzzy
+msgid "fts: bad second parameter"
+msgstr "%s: 仮引数ã§ã™\n"
+
+#: extension/filefuncs.c:799
+#, fuzzy
+msgid "fts: bad third parameter"
+msgstr "%s: 仮引数ã§ã™\n"
+
+#: extension/filefuncs.c:806
+msgid "fts: could not flatten array\n"
+msgstr ""
+
+#: extension/filefuncs.c:824
+msgid "fts: ignoring sneaky FTS_NOSTAT flag. nyah, nyah, nyah."
+msgstr ""
+
+#: extension/filefuncs.c:841
+msgid "fts: clear_array() failed\n"
+msgstr ""
+
+#: extension/fnmatch.c:112
+#, fuzzy
+msgid "fnmatch: called with less than three arguments"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/fnmatch.c:115
+#, fuzzy
+msgid "fnmatch: called with more than three arguments"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/fnmatch.c:118
+#, fuzzy
+msgid "fnmatch: could not get first argument"
+msgstr "strftime: éžæ–‡å­—列ã®ç¬¬ä¸€å¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
+
+#: extension/fnmatch.c:123
+#, fuzzy
+msgid "fnmatch: could not get second argument"
+msgstr "index: 文字列ã§ã¯ç„¡ã„第二引数をå—ã‘å–ã‚Šã¾ã—ãŸ"
+
+#: extension/fnmatch.c:128
+msgid "fnmatch: could not get third argument"
+msgstr ""
+
+#: extension/fnmatch.c:141
+msgid "fnmatch is not implemented on this system\n"
+msgstr ""
+
+#: extension/fnmatch.c:173
+msgid "fnmatch init: could not add FNM_NOMATCH variable"
+msgstr ""
+
+#: extension/fnmatch.c:183
+#, c-format
+msgid "fnmatch init: could not set array element %s"
+msgstr ""
+
+#: extension/fnmatch.c:193
+msgid "fnmatch init: could not install FNM array"
+msgstr ""
+
+#: extension/fork.c:81
+#, fuzzy
+msgid "fork: called with too many arguments"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/fork.c:94
+msgid "fork: PROCINFO is not an array!"
+msgstr ""
+
+#: extension/fork.c:118
+#, fuzzy
+msgid "waitpid: called with too many arguments"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/fork.c:126
+#, fuzzy
+msgid "wait: called with no arguments"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/fork.c:143
+#, fuzzy
+msgid "wait: called with too many arguments"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/inplace.c:130
+msgid "inplace_begin: in-place editing already active"
+msgstr ""
+
+#: extension/inplace.c:133 extension/inplace.c:207
+#, c-format
+msgid "inplace_begin: expects 2 arguments but called with %d"
+msgstr ""
+
+#: extension/inplace.c:136
+msgid "inplace_begin: cannot retrieve 1st argument as a string filename"
+msgstr ""
+
+#: extension/inplace.c:144
+#, c-format
+msgid "inplace_begin: disabling in-place editing for invalid FILENAME `%s'"
+msgstr ""
+
+#: extension/inplace.c:151
+#, fuzzy, c-format
+msgid "inplace_begin: Cannot stat `%s' (%s)"
+msgstr "致命的: extension: `%s' ã‚’é–‹ãã“ã¨ãŒå‡ºæ¥ã¾ã›ã‚“ (%s)\n"
+
+#: extension/inplace.c:158
+#, c-format
+msgid "inplace_begin: `%s' is not a regular file"
+msgstr ""
+
+#: extension/inplace.c:169
+#, c-format
+msgid "inplace_begin: mkstemp(`%s') failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:178
+#, fuzzy, c-format
+msgid "inplace_begin: chmod failed (%s)"
+msgstr "%s: é–‰ã˜ã‚‹ã®ã«å¤±æ•—ã—ã¾ã—㟠(%s)"
-#: field.c:328
+#: extension/inplace.c:185
+#, c-format
+msgid "inplace_begin: dup(stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:188
+#, c-format
+msgid "inplace_begin: dup2(%d, stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:191
+#, fuzzy, c-format
+msgid "inplace_begin: close(%d) failed (%s)"
+msgstr "%s: é–‰ã˜ã‚‹ã®ã«å¤±æ•—ã—ã¾ã—㟠(%s)"
+
+#: extension/inplace.c:210
+msgid "inplace_end: cannot retrieve 1st argument as a string filename"
+msgstr ""
+
+#: extension/inplace.c:217
+msgid "inplace_end: in-place editing not active"
+msgstr ""
+
+#: extension/inplace.c:223
+#, c-format
+msgid "inplace_end: dup2(%d, stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:226
+#, fuzzy, c-format
+msgid "inplace_end: close(%d) failed (%s)"
+msgstr "%s: é–‰ã˜ã‚‹ã®ã«å¤±æ•—ã—ã¾ã—㟠(%s)"
+
+#: extension/inplace.c:230
+#, c-format
+msgid "inplace_end: fsetpos(stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:243
+#, fuzzy, c-format
+msgid "inplace_end: link(`%s', `%s') failed (%s)"
+msgstr "パイプ `%s' をフラッシュã§ãã¾ã›ã‚“ (%s)。"
+
+#: extension/inplace.c:253
+#, fuzzy, c-format
+msgid "inplace_end: rename(`%s', `%s') failed (%s)"
+msgstr "fd %d (`%s') ã‚’é–‰ã˜ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ (%s)"
+
+#: extension/ordchr.c:69
+#, fuzzy
+msgid "ord: called with too many arguments"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/ordchr.c:75
+#, fuzzy
+msgid "ord: called with no arguments"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/ordchr.c:77
+#, fuzzy
+msgid "ord: called with inappropriate argument(s)"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/ordchr.c:99
+#, fuzzy
+msgid "chr: called with too many arguments"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/ordchr.c:109
+#, fuzzy
+msgid "chr: called with no arguments"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/ordchr.c:111
+#, fuzzy
+msgid "chr: called with inappropriate argument(s)"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/readdir.c:281
+#, c-format
+msgid "dir_take_control_of: opendir/fdopendir failed: %s"
+msgstr ""
+
+#: extension/readfile.c:113
+#, fuzzy
+msgid "readfile: called with too many arguments"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/readfile.c:137
+#, fuzzy
+msgid "readfile: called with no arguments"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/rwarray.c:124
+#, fuzzy
+msgid "writea: called with too many arguments"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/rwarray.c:131
+#, fuzzy, c-format
+msgid "do_writea: argument 0 is not a string\n"
+msgstr "exp: 引数 %g ãŒç¯„囲外ã§ã™"
+
+#: extension/rwarray.c:137
+#, fuzzy, c-format
+msgid "do_writea: argument 1 is not an array\n"
+msgstr "split: 第四引数ãŒé…列ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
+
+#: extension/rwarray.c:184
+#, c-format
+msgid "write_array: could not flatten array\n"
+msgstr ""
+
+#: extension/rwarray.c:198
+#, c-format
+msgid "write_array: could not release flattened array\n"
+msgstr ""
+
+#: extension/rwarray.c:280
+#, fuzzy
+msgid "reada: called with too many arguments"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/rwarray.c:287
+#, fuzzy, c-format
+msgid "do_reada: argument 0 is not a string\n"
+msgstr "exp: 引数 %g ãŒç¯„囲外ã§ã™"
+
+#: extension/rwarray.c:293
+#, fuzzy, c-format
+msgid "do_reada: argument 1 is not an array\n"
+msgstr "adump: 引数ãŒé…列ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
+
+#: extension/rwarray.c:337
+#, c-format
+msgid "do_reada: clear_array failed\n"
+msgstr ""
+
+#: extension/rwarray.c:374
+#, c-format
+msgid "read_array: set_array_element failed\n"
+msgstr ""
+
+#: extension/time.c:113
+#, fuzzy
+msgid "gettimeofday: ignoring arguments"
+msgstr "mktime: éžæ–‡å­—列引数をå—ã‘å–ã‚Šã¾ã—ãŸ"
+
+#: extension/time.c:144
+msgid "gettimeofday: not supported on this platform"
+msgstr ""
+
+#: extension/time.c:165
+#, fuzzy
+msgid "sleep: called with too many arguments"
+msgstr "sqrt: è² ã®å€¤ %g を引数ã«ä½¿ç”¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: extension/time.c:168
+#, fuzzy
+msgid "sleep: missing required numeric argument"
+msgstr "exp: 引数ãŒæ•°å€¤ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
+
+#: extension/time.c:174
+#, fuzzy
+msgid "sleep: argument is negative"
+msgstr "exp: 引数 %g ãŒç¯„囲外ã§ã™"
+
+#: extension/time.c:208
+msgid "sleep: not supported on this platform"
+msgstr ""
+
+#: field.c:345
msgid "NF set to negative value"
msgstr "NF ãŒè² ã®å€¤ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã™"
-#: field.c:951 field.c:958 field.c:962
+#: field.c:971 field.c:978 field.c:982
msgid "split: fourth argument is a gawk extension"
msgstr "split: 第四引数㯠gawk æ‹¡å¼µã§ã™"
-#: field.c:955
+#: field.c:975
msgid "split: fourth argument is not an array"
msgstr "split: 第四引数ãŒé…列ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: field.c:969
+#: field.c:989
msgid "split: second argument is not an array"
msgstr "split: 第二引数ãŒé…列ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: field.c:973
+#: field.c:993
msgid "split: cannot use the same array for second and fourth args"
msgstr "split: 第二引数ã¨ç¬¬å››å¼•æ•°ã«åŒã˜é…列を使用ã™ã‚‹ã“ã¨ã¯å‡ºæ¥ã¾ã›ã‚“"
-#: field.c:978
+#: field.c:998
msgid "split: cannot use a subarray of second arg for fourth arg"
msgstr "split: 第四引数ã«ç¬¬äºŒå¼•æ•°ã®éƒ¨åˆ†é…列を使用ã™ã‚‹ã“ã¨ã¯å‡ºæ¥ã¾ã›ã‚“"
-#: field.c:981
+#: field.c:1001
msgid "split: cannot use a subarray of fourth arg for second arg"
msgstr "split: 第二引数ã«ç¬¬å››å¼•æ•°ã®éƒ¨åˆ†é…列を使用ã™ã‚‹ã“ã¨ã¯å‡ºæ¥ã¾ã›ã‚“"
-#: field.c:1010
+#: field.c:1032
msgid "split: null string for third arg is a gawk extension"
msgstr "split: 第三引数㫠NULL 文字列を使用ã™ã‚‹ã“ã¨ã¯ gawk æ‹¡å¼µã§ã™"
-#: field.c:1050
+#: field.c:1072
msgid "patsplit: fourth argument is not an array"
msgstr "patsplit: 第四引数ãŒé…列ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: field.c:1055
+#: field.c:1077
msgid "patsplit: second argument is not an array"
msgstr "patsplit: 第二引数ãŒé…列ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: field.c:1061
+#: field.c:1083
msgid "patsplit: third argument must be non-null"
msgstr "patsplit: 第三引数ã¯éž NULL ã§ãªã‘ã‚Œã°ã„ã‘ã¾ã›ã‚“"
-#: field.c:1065
+#: field.c:1087
msgid "patsplit: cannot use the same array for second and fourth args"
msgstr "patsplit: 第二引数ã¨ç¬¬å››å¼•æ•°ã«åŒã˜é…列を使用ã™ã‚‹ã“ã¨ã¯å‡ºæ¥ã¾ã›ã‚“"
-#: field.c:1070
+#: field.c:1092
msgid "patsplit: cannot use a subarray of second arg for fourth arg"
msgstr "patsplit: 第四引数ã«ç¬¬äºŒå¼•æ•°ã®éƒ¨åˆ†é…列を使用ã™ã‚‹ã“ã¨ã¯å‡ºæ¥ã¾ã›ã‚“"
-#: field.c:1073
+#: field.c:1095
msgid "patsplit: cannot use a subarray of fourth arg for second arg"
msgstr "patsplit: 第二引数ã«ç¬¬å››å¼•æ•°ã®éƒ¨åˆ†é…列を使用ã™ã‚‹ã“ã¨ã¯å‡ºæ¥ã¾ã›ã‚“"
-#: field.c:1110
+#: field.c:1133
msgid "`FIELDWIDTHS' is a gawk extension"
msgstr "`FIELDWIDTHS' 㯠gawk æ‹¡å¼µã§ã™"
-#: field.c:1173
+#: field.c:1197
#, c-format
msgid "invalid FIELDWIDTHS value, near `%s'"
msgstr "`%s' 付近㮠FIELDWIDTHS 値ãŒç„¡åŠ¹ã§ã™"
-#: field.c:1246
+#: field.c:1270
msgid "null string for `FS' is a gawk extension"
msgstr "`FS' ã« NULL 文字列を使用ã™ã‚‹ã®ã¯ gawk æ‹¡å¼µã§ã™"
-#: field.c:1250
+#: field.c:1274
msgid "old awk does not support regexps as value of `FS'"
msgstr "å¤ã„ awk 㯠`FS' ã®å€¤ã¨ã—ã¦æ­£è¦è¡¨ç¾ã‚’サãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
-#: field.c:1369
+#: field.c:1393
msgid "`FPAT' is a gawk extension"
msgstr "`FPAT' 㯠gawk æ‹¡å¼µã§ã™"
-#: getopt.c:574 getopt.c:590
+#: gawkapi.c:146
+msgid "awk_value_to_node: received null retval"
+msgstr ""
+
+#: gawkapi.c:384
+msgid "node_to_awk_value: received null node"
+msgstr ""
+
+#: gawkapi.c:387
+msgid "node_to_awk_value: received null val"
+msgstr ""
+
+#: gawkapi.c:807
+#, fuzzy
+msgid "remove_element: received null array"
+msgstr "length: é…列引数をå—ã‘å–ã‚Šã¾ã—ãŸ"
+
+#: gawkapi.c:810
+msgid "remove_element: received null subscript"
+msgstr ""
+
+#: gawkapi.c:947
#, c-format
-msgid "%s: option '%s' is ambiguous\n"
+msgid "api_flatten_array: could not convert index %d\n"
+msgstr ""
+
+#: gawkapi.c:952
+#, c-format
+msgid "api_flatten_array: could not convert value %d\n"
+msgstr ""
+
+#: getopt.c:604 getopt.c:633
+#, fuzzy, c-format
+msgid "%s: option '%s' is ambiguous; possibilities:"
msgstr "%s: オプション '%s' ã¯æ›–昧ã§ã™\n"
-#: getopt.c:623 getopt.c:627
+#: getopt.c:679 getopt.c:683
#, c-format
msgid "%s: option '--%s' doesn't allow an argument\n"
msgstr "%s: オプション '--%s' ã¯å¼•æ•°ã‚’å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“\n"
-#: getopt.c:636 getopt.c:641
+#: getopt.c:692 getopt.c:697
#, c-format
msgid "%s: option '%c%s' doesn't allow an argument\n"
msgstr "%s: オプション '%c%s' ã¯å¼•æ•°ã‚’å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“\n"
-#: getopt.c:684 getopt.c:703
+#: getopt.c:740 getopt.c:759
#, c-format
msgid "%s: option '--%s' requires an argument\n"
msgstr "%s: オプション '--%s' ã«ã¯å¼•æ•°ãŒå¿…è¦ã§ã™\n"
-#: getopt.c:741 getopt.c:744
+#: getopt.c:797 getopt.c:800
#, c-format
msgid "%s: unrecognized option '--%s'\n"
msgstr "%s: オプション '--%s' ã‚’èªè­˜ã§ãã¾ã›ã‚“\n"
-#: getopt.c:752 getopt.c:755
+#: getopt.c:808 getopt.c:811
#, c-format
msgid "%s: unrecognized option '%c%s'\n"
msgstr "%s: オプション '%c%s' ã‚’èªè­˜ã§ãã¾ã›ã‚“\n"
-#: getopt.c:804 getopt.c:807
+#: getopt.c:860 getopt.c:863
#, c-format
msgid "%s: invalid option -- '%c'\n"
msgstr "%s: 無効ãªã‚ªãƒ—ション -- '%c'\n"
-#: getopt.c:857 getopt.c:874 getopt.c:1082 getopt.c:1100
+#: getopt.c:916 getopt.c:933 getopt.c:1143 getopt.c:1161
#, c-format
msgid "%s: option requires an argument -- '%c'\n"
msgstr "%s: オプションã«ã¯å¼•æ•°ãŒå¿…è¦ã§ã™ -- '%c'\n"
-#: getopt.c:930 getopt.c:946
+#: getopt.c:989 getopt.c:1005
#, c-format
msgid "%s: option '-W %s' is ambiguous\n"
msgstr "%s: オプション '-W %s' ã¯æ›–昧ã§ã™\n"
-#: getopt.c:970 getopt.c:988
+#: getopt.c:1029 getopt.c:1047
#, c-format
msgid "%s: option '-W %s' doesn't allow an argument\n"
msgstr "%s: オプション '-W %s' ã¯å¼•æ•°ã‚’å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“\n"
-#: getopt.c:1009 getopt.c:1027
+#: getopt.c:1068 getopt.c:1086
#, c-format
msgid "%s: option '-W %s' requires an argument\n"
msgstr "%s: オプション '-W %s' ã«ã¯å¼•æ•°ãŒå¿…è¦ã§ã™\n"
-#: io.c:280
+#: io.c:392
#, c-format
msgid "command line argument `%s' is a directory: skipped"
msgstr "コマンドライン引数 `%s' ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã™: スキップã•ã‚Œã¾ã—ãŸ"
-#: io.c:283 io.c:385
+#: io.c:395 io.c:513
#, c-format
msgid "cannot open file `%s' for reading (%s)"
msgstr "ファイル `%s' を読ã¿è¾¼ã¿ç”¨ã«é–‹ã‘ã¾ã›ã‚“ (%s)"
-#: io.c:501
+#: io.c:640
#, c-format
msgid "close of fd %d (`%s') failed (%s)"
msgstr "fd %d (`%s') ã‚’é–‰ã˜ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ (%s)"
-#: io.c:578
+#: io.c:716
msgid "redirection not allowed in sandbox mode"
msgstr "サンドボックスモード内ã§ã¯ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: io.c:612
+#: io.c:750
#, c-format
msgid "expression in `%s' redirection only has numeric value"
msgstr "`%s' リダイレクトã®å‘½ä»¤å¼ã«æ•°å€¤ã—ã‹è¨˜è¿°ã•ã‚Œã¦ã„ã¾ã›ã‚“。"
-#: io.c:618
+#: io.c:756
#, c-format
msgid "expression for `%s' redirection has null string value"
msgstr "`%s' リダイレクトã®å‘½ä»¤å¼ãŒç©ºåˆ—ã§ã™ã€‚"
-#: io.c:624
+#: io.c:761
#, c-format
msgid "filename `%s' for `%s' redirection may be result of logical expression"
msgstr ""
"`%2$s' リダイレクトã«è«–ç†æ¼”ç®—ã®çµæžœã¨æ€ã‚れるファイルå `%1$s' ãŒä½¿ã‚ã‚Œã¦ã„ã¾"
"ã™ã€‚"
-#: io.c:667
+#: io.c:809
#, c-format
msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
msgstr "ファイル `%.*s' ã§å¿…è¦ä»¥ä¸Šã« `>' 㨠`>>' を組åˆã›ã¦ã„ã¾ã™ã€‚"
-#: io.c:720
+#: io.c:863
#, c-format
msgid "can't open pipe `%s' for output (%s)"
msgstr "出力用ã«ãƒ‘イプ `%s' ã‚’é–‹ã‘ã¾ã›ã‚“ (%s)"
-#: io.c:730
+#: io.c:873
#, c-format
msgid "can't open pipe `%s' for input (%s)"
msgstr "入力用ã«ãƒ‘イプ `%s' ã‚’é–‹ã‘ã¾ã›ã‚“ (%s)"
-#: io.c:753
+#: io.c:904
#, c-format
msgid "can't open two way pipe `%s' for input/output (%s)"
msgstr "入出力用ã®åŒæ–¹å‘パイプ `%s' ãŒé–‹ã‘ã¾ã›ã‚“ (%s)"
-#: io.c:835
+#: io.c:986
#, c-format
msgid "can't redirect from `%s' (%s)"
msgstr "`%s' ã‹ã‚‰ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã§ãã¾ã›ã‚“ (%s)"
-#: io.c:838
+#: io.c:989
#, c-format
msgid "can't redirect to `%s' (%s)"
msgstr "`%s' ã«ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã§ãã¾ã›ã‚“ (%s)"
-#: io.c:889
+#: io.c:1040
msgid ""
"reached system limit for open files: starting to multiplex file descriptors"
msgstr ""
"é–‹ã„ã¦ã„るファイルã®æ•°ãŒã‚·ã‚¹ãƒ†ãƒ åˆ¶é™ã«é”ã—ã¾ã—ãŸã€‚ファイル記述å­ã‚’多é‡åŒ–ã—ã¾"
"ã™ã€‚"
-#: io.c:905
+#: io.c:1056
#, c-format
msgid "close of `%s' failed (%s)."
msgstr "`%s' ã‚’é–‰ã˜ã‚‹ã®ã«å¤±æ•—ã—ã¾ã—㟠(%s)"
-#: io.c:913
+#: io.c:1064
msgid "too many pipes or input files open"
msgstr "é–‹ã„ã¦ã„るパイプã¾ãŸã¯å…¥åŠ›ãƒ•ã‚¡ã‚¤ãƒ«ã®æ•°ãŒå¤šéŽãŽã¾ã™ã€‚"
-#: io.c:935
+#: io.c:1086
msgid "close: second argument must be `to' or `from'"
msgstr "close: 第二引数㯠`to' ã¾ãŸã¯ `from' ã§ãªã‘ã‚Œã°ã„ã‘ã¾ã›ã‚“"
-#: io.c:952
+#: io.c:1103
#, c-format
msgid "close: `%.*s' is not an open file, pipe or co-process"
msgstr "close: `%.*s' ã¯é–‹ã„ã¦ã„るファイルã€ãƒ‘イプã€ãƒ—ロセス共有ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-#: io.c:957
+#: io.c:1108
msgid "close of redirection that was never opened"
msgstr "é–‹ã„ã¦ãªã„リダイレクトを閉ã˜ã‚ˆã†ã¨ã—ã¦ã„ã¾ã™"
-#: io.c:1054
+#: io.c:1205
#, c-format
msgid "close: redirection `%s' not opened with `|&', second argument ignored"
msgstr ""
"close: リダイレクト `%s' 㯠`|&' を使用ã—ã¦é–‹ã‹ã‚Œã¦ã„ã¾ã›ã‚“。第二引数ã¯ç„¡è¦–ã•"
"ã‚Œã¾ã—ãŸ"
-#: io.c:1070
+#: io.c:1222
#, c-format
msgid "failure status (%d) on pipe close of `%s' (%s)"
msgstr "パイプ `%2$s' ã‚’é–‰ã˜ãŸã¨ãã®çŠ¶æ…‹ã‚³ãƒ¼ãƒ‰ãŒå¤±æ•— (%1$d) ã§ã—㟠(%3$s)。"
-#: io.c:1073
+#: io.c:1225
#, c-format
msgid "failure status (%d) on file close of `%s' (%s)"
msgstr "ファイル `%2$s' ã‚’é–‰ã˜ãŸã¨ãã®çŠ¶æ…‹ã‚³ãƒ¼ãƒ‰ãŒå¤±æ•— (%1$d) ã§ã—㟠(%3$s)。"
-#: io.c:1093
+#: io.c:1245
#, c-format
msgid "no explicit close of socket `%s' provided"
msgstr "ソケット `%s' を明示ã—ã¦é–‰ã˜ã¦ã„ã¾ã›ã‚“。"
-#: io.c:1096
+#: io.c:1248
#, c-format
msgid "no explicit close of co-process `%s' provided"
msgstr "並行プロセス `%s' を明示ã—ã¦é–‰ã˜ã¦ã„ã¾ã›ã‚“。"
-#: io.c:1099
+#: io.c:1251
#, c-format
msgid "no explicit close of pipe `%s' provided"
msgstr "パイプ `%s' を明示ã—ã¦é–‰ã˜ã¦ã„ã¾ã›ã‚“。"
-#: io.c:1102
+#: io.c:1254
#, c-format
msgid "no explicit close of file `%s' provided"
msgstr "ファイル `%s' を明示ã—ã¦é–‰ã˜ã¦ã„ã¾ã›ã‚“。"
-#: io.c:1130 io.c:1185 main.c:793 main.c:830
+#: io.c:1284 io.c:1342 main.c:864 main.c:906
#, c-format
msgid "error writing standard output (%s)"
msgstr "標準出力ã¸ã®æ›¸è¾¼ã¿ã‚¨ãƒ©ãƒ¼ (%s)"
-#: io.c:1134 io.c:1190
+#: io.c:1289 io.c:1348 main.c:866
#, c-format
msgid "error writing standard error (%s)"
msgstr "標準エラーã¸ã®æ›¸è¾¼ã¿ã‚¨ãƒ©ãƒ¼ (%s)"
-#: io.c:1142
+#: io.c:1297
#, c-format
msgid "pipe flush of `%s' failed (%s)."
msgstr "パイプ `%s' をフラッシュã§ãã¾ã›ã‚“ (%s)。"
-#: io.c:1145
+#: io.c:1300
#, c-format
msgid "co-process flush of pipe to `%s' failed (%s)."
msgstr "`%s' ã¸æŽ¥ç¶šã™ã‚‹ãƒ‘イプを並行プロセスã‹ã‚‰ãƒ•ãƒ©ãƒƒã‚·ãƒ¥ã§ãã¾ã›ã‚“ (%s)。"
-#: io.c:1148
+#: io.c:1303
#, c-format
msgid "file flush of `%s' failed (%s)."
msgstr "ファイル `%s' をフラッシュã§ãã¾ã›ã‚“ (%s)。"
-#: io.c:1263
+#: io.c:1420
#, c-format
msgid "local port %s invalid in `/inet'"
msgstr "`/inet' 内ã®ãƒ­ãƒ¼ã‚«ãƒ«ãƒãƒ¼ãƒˆ %s ãŒç„¡åŠ¹ã§ã™"
-#: io.c:1280
+#: io.c:1438
#, c-format
msgid "remote host and port information (%s, %s) invalid"
msgstr "リモートã®ãƒ›ã‚¹ãƒˆãŠã‚ˆã³ãƒãƒ¼ãƒˆæƒ…å ± (%s, %s) ãŒç„¡åŠ¹ã§ã™"
-#: io.c:1432
+#: io.c:1590
#, c-format
msgid "no (known) protocol supplied in special filename `%s'"
msgstr ""
"スペシャルファイルå `%s' ã«ï¼ˆèªè­˜ã§ãる)プロトコルãŒæŒ‡å®šã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: io.c:1446
+#: io.c:1604
#, c-format
msgid "special file name `%s' is incomplete"
msgstr "スペシャルファイルå `%s' ã¯ä¸å®Œå…¨ã§ã™"
-#: io.c:1463
+#: io.c:1621
msgid "must supply a remote hostname to `/inet'"
msgstr "`/inet' ã«ã¯ãƒªãƒ¢ãƒ¼ãƒˆãƒ›ã‚¹ãƒˆåを与ãˆãªã‘ã‚Œã°ã„ã‘ã¾ã›ã‚“"
-#: io.c:1481
+#: io.c:1639
msgid "must supply a remote port to `/inet'"
msgstr "`/inet' ã«ã¯ãƒªãƒ¢ãƒ¼ãƒˆãƒãƒ¼ãƒˆç•ªå·ã‚’与ãˆãªã‘ã‚Œã°ã„ã‘ã¾ã›ã‚“"
-#: io.c:1527
+#: io.c:1685
msgid "TCP/IP communications are not supported"
msgstr "TCP/IP 通信ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: io.c:1694
+#: io.c:1867
#, c-format
msgid "could not open `%s', mode `%s'"
msgstr "`%s' をモード `%s' ã§é–‹ã‘ã¾ã›ã‚“"
-#: io.c:1748
+#: io.c:1917
#, c-format
msgid "close of master pty failed (%s)"
msgstr "マスター pty ã‚’é–‰ã˜ã‚‹ã®ã«å¤±æ•—ã—ã¾ã—㟠(%s)"
-#: io.c:1750 io.c:1918 io.c:2075
+#: io.c:1919 io.c:2105 io.c:2305
#, c-format
msgid "close of stdout in child failed (%s)"
msgstr "å­ãƒ—ロセスãŒæ¨™æº–出力を閉ã˜ã‚‹ã®ã«å¤±æ•—ã—ã¾ã—㟠(%s)"
-#: io.c:1753
+#: io.c:1922
#, c-format
msgid "moving slave pty to stdout in child failed (dup: %s)"
msgstr "å­ãƒ—ロセスãŒã‚¹ãƒ¬ãƒ¼ãƒ– pty を標準出力ã«ç§»å‹•ã§ãã¾ã›ã‚“ (dup: %s)。"
-#: io.c:1755 io.c:1923
+#: io.c:1924 io.c:2110
#, c-format
msgid "close of stdin in child failed (%s)"
msgstr "å­ãƒ—ロセスãŒæ¨™æº–入力を閉ã˜ã‚‰ã‚Œã¾ã›ã‚“ (%s)。"
-#: io.c:1758
+#: io.c:1927
#, c-format
msgid "moving slave pty to stdin in child failed (dup: %s)"
msgstr "å­ãƒ—ロセスãŒã‚¹ãƒ¬ãƒ¼ãƒ– pty を標準入力ã«ç§»å‹•ã§ãã¾ã›ã‚“ (dup: %s)。"
-#: io.c:1760 io.c:1781
+#: io.c:1929 io.c:1951
#, c-format
msgid "close of slave pty failed (%s)"
msgstr "スレーブ pty ã‚’é–‰ã˜ã‚‹ã®ã«å¤±æ•—ã—ã¾ã—㟠(%s)"
-#: io.c:1859 io.c:1921 io.c:2053 io.c:2078
+#: io.c:2040 io.c:2108 io.c:2276 io.c:2308
#, c-format
msgid "moving pipe to stdout in child failed (dup: %s)"
msgstr "å­ãƒ—ロセスãŒãƒ‘イプを標準出力ã«ç§»å‹•ã§ãã¾ã›ã‚“ (dup: %s)。"
-#: io.c:1866 io.c:1926
+#: io.c:2047 io.c:2113
#, c-format
msgid "moving pipe to stdin in child failed (dup: %s)"
msgstr "å­ãƒ—ロセスãŒãƒ‘イプを標準入力ã«ç§»å‹•ã§ãã¾ã›ã‚“ (dup: %s)。"
-#: io.c:1886 io.c:2068
+#: io.c:2073 io.c:2298
msgid "restoring stdout in parent process failed\n"
msgstr "親プロセスãŒæ¨™æº–出力を復旧ã§ãã¾ã›ã‚“。\n"
-#: io.c:1894
+#: io.c:2081
msgid "restoring stdin in parent process failed\n"
msgstr "親プロセスãŒæ¨™æº–入力を復旧ã§ãã¾ã›ã‚“。\n"
-#: io.c:1929 io.c:2080 io.c:2094
+#: io.c:2116 io.c:2310 io.c:2324
#, c-format
msgid "close of pipe failed (%s)"
msgstr "パイプを閉ã˜ã‚‰ã‚Œã¾ã›ã‚“ (%s)。"
-#: io.c:1974
+#: io.c:2174
msgid "`|&' not supported"
msgstr "`|&' ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。"
-#: io.c:2040
+#: io.c:2261
#, c-format
msgid "cannot open pipe `%s' (%s)"
msgstr "パイプ `%s' ãŒé–‹ã‘ã¾ã›ã‚“ (%s)。"
-#: io.c:2088
+#: io.c:2318
#, c-format
msgid "cannot create child process for `%s' (fork: %s)"
msgstr "`%s' 用ã®å­ãƒ—ロセスを実行ã§ãã¾ã›ã‚“ (fork: %s)。"
-#: io.c:2521
+#: io.c:2790
+msgid "register_input_parser: received NULL pointer"
+msgstr ""
+
+#: io.c:2818
+#, c-format
+msgid "input parser `%s' conflicts with previously installed input parser `%s'"
+msgstr ""
+
+#: io.c:2825
+#, c-format
+msgid "input parser `%s' failed to open `%s'"
+msgstr ""
+
+#: io.c:2845
+msgid "register_output_wrapper: received NULL pointer"
+msgstr ""
+
+#: io.c:2873
+#, c-format
+msgid ""
+"output wrapper `%s' conflicts with previously installed output wrapper `%s'"
+msgstr ""
+
+#: io.c:2880
+#, c-format
+msgid "output wrapper `%s' failed to open `%s'"
+msgstr ""
+
+#: io.c:2901
+msgid "register_output_processor: received NULL pointer"
+msgstr ""
+
+#: io.c:2930
+#, c-format
+msgid ""
+"two-way processor `%s' conflicts with previously installed two-way processor "
+"`%s'"
+msgstr ""
+
+#: io.c:2939
+#, c-format
+msgid "two way processor `%s' failed to open `%s'"
+msgstr ""
+
+#: io.c:3064
#, c-format
msgid "data file `%s' is empty"
msgstr "データファイル `%s' ã¯ç©ºã§ã™ã€‚"
-#: io.c:2562 io.c:2570
+#: io.c:3106 io.c:3114
msgid "could not allocate more input memory"
msgstr "入力用メモリーをã“れ以上確ä¿ã§ãã¾ã›ã‚“。"
-#: io.c:3128
+#: io.c:3682
msgid "multicharacter value of `RS' is a gawk extension"
msgstr "複数ã®æ–‡å­—ã‚’ `RS' ã«ä½¿ç”¨ã™ã‚‹ã®ã¯ gawk 特有ã®æ‹¡å¼µã§ã™ã€‚"
-#: io.c:3233
+#: io.c:3771
msgid "IPv6 communication is not supported"
msgstr "IPv6 通信ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: main.c:364
-msgid "`-m[fr]' option irrelevant in gawk"
-msgstr "gawk ã§ã¯ã‚ªãƒ—ション `-m[fr]' ã«åŠ¹æžœã¯ã‚ã‚Šã¾ã›ã‚“。"
-
-#: main.c:366
-msgid "-m option usage: `-m[fr] nnn'"
-msgstr "-m オプションã®ä½¿ç”¨æ³•: `-m[fr] 数値'"
-
-#: main.c:389
+#: main.c:405
msgid "empty argument to `-e/--source' ignored"
msgstr "`-e/--source' ã¸ã®ç©ºã®å¼•æ•°ã¯ç„¡è¦–ã•ã‚Œã¾ã—ãŸ"
-#: main.c:460
+#: main.c:495
#, c-format
msgid "%s: option `-W %s' unrecognized, ignored\n"
msgstr "%s: オプション `-W %s' ã¯èªè­˜ã§ãã¾ã›ã‚“。無視ã•ã‚Œã¾ã—ãŸ\n"
-#: main.c:513
+#: main.c:541
#, c-format
msgid "%s: option requires an argument -- %c\n"
msgstr "%s: 引数ãŒå¿…è¦ãªã‚ªãƒ—ション -- %c\n"
-#: main.c:534
+#: main.c:562
msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
msgstr ""
"環境変数 `POSIXLY_CORRECT' ãŒæŒ‡å®šã•ã‚Œã¦ã„ã¾ã™ã€‚オプション `--posix' を有効ã«"
"ã—ã¾ã™"
-#: main.c:540
+#: main.c:568
msgid "`--posix' overrides `--traditional'"
msgstr "オプション `--posix' 㯠`--traditional' を無効ã«ã—ã¾ã™ã€‚"
-#: main.c:551
+#: main.c:579
msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
msgstr ""
"オプション `--posix'/`--traditional' 㯠`--non-decimal-data' を無効ã«ã—ã¾ã™ã€‚"
-#: main.c:555
+#: main.c:583
#, c-format
msgid "running %s setuid root may be a security problem"
msgstr ""
"setuid root 㧠%s を実行ã™ã‚‹ã¨ã€ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ä¸Šã®å•é¡ŒãŒç™ºç”Ÿã™ã‚‹å ´åˆãŒã‚ã‚Šã¾"
"ã™ã€‚"
-#: main.c:560
-msgid "`--posix' overrides `--binary'"
+#: main.c:588
+#, fuzzy
+msgid "`--posix' overrides `--characters-as-bytes'"
msgstr "`--posix' 㯠`--binary' を上書ãã—ã¾ã™"
-#: main.c:611
+#: main.c:647
#, c-format
msgid "can't set binary mode on stdin (%s)"
msgstr "標準入力をãƒã‚¤ãƒŠãƒªãƒ¢ãƒ¼ãƒ‰ã«è¨­å®šã§ãã¾ã›ã‚“ (%s)"
-#: main.c:614
+#: main.c:650
#, c-format
msgid "can't set binary mode on stdout (%s)"
msgstr "標準出力をãƒã‚¤ãƒŠãƒªãƒ¢ãƒ¼ãƒ‰ã«è¨­å®šã§ãã¾ã›ã‚“ (%s)"
-#: main.c:616
+#: main.c:652
#, c-format
msgid "can't set binary mode on stderr (%s)"
msgstr "標準エラーをãƒã‚¤ãƒŠãƒªãƒ¢ãƒ¼ãƒ‰ã«è¨­å®šã§ãã¾ã›ã‚“ (%s)"
-#: main.c:655
+#: main.c:710
msgid "no program text at all!"
msgstr "プログラム文ãŒå…¨ãã‚ã‚Šã¾ã›ã‚“!"
-#: main.c:733
+#: main.c:799
#, c-format
msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
msgstr ""
"使用法: %s [POSIX ã¾ãŸã¯ GNU å½¢å¼ã®ã‚ªãƒ—ション] -f progfile [--] file ...\n"
-#: main.c:735
+#: main.c:801
#, c-format
msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
msgstr ""
"使用法: %s [POSIX ã¾ãŸã¯ GNU å½¢å¼ã®ã‚ªãƒ—ション] [--] %cprogram%c file ...\n"
-#: main.c:740
+#: main.c:806
msgid "POSIX options:\t\tGNU long options: (standard)\n"
msgstr "POSIX オプション:\t\tGNU é•·ã„å½¢å¼ã®ã‚ªãƒ—ション: (標準)\n"
-#: main.c:741
+#: main.c:807
msgid "\t-f progfile\t\t--file=progfile\n"
msgstr "\t-f progfile\t\t--file=progfile\n"
-#: main.c:742
+#: main.c:808
msgid "\t-F fs\t\t\t--field-separator=fs\n"
msgstr "\t-F fs\t\t\t--field-separator=fs\n"
-#: main.c:743
+#: main.c:809
msgid "\t-v var=val\t\t--assign=var=val\n"
msgstr "\t-v var=val\t\t--assign=var=val\n"
-#: main.c:744
+#: main.c:810
msgid "Short options:\t\tGNU long options: (extensions)\n"
msgstr "短ã„オプション:\t\tGNU é•·ã„å½¢å¼ã®ã‚ªãƒ—ション: (æ‹¡å¼µ)\n"
-#: main.c:745
+#: main.c:811
msgid "\t-b\t\t\t--characters-as-bytes\n"
msgstr "\t-b\t\t\t--characters-as-bytes\n"
-#: main.c:746
+#: main.c:812
msgid "\t-c\t\t\t--traditional\n"
msgstr "\t-c\t\t\t--traditional\n"
-#: main.c:747
+#: main.c:813
msgid "\t-C\t\t\t--copyright\n"
msgstr "\t-C\t\t\t--copyright\n"
-#: main.c:748
+#: main.c:814
msgid "\t-d[file]\t\t--dump-variables[=file]\n"
msgstr "\t-d[file]\t\t--dump-variables[=file]\n"
-#: main.c:749
+#: main.c:815
+#, fuzzy
+msgid "\t-D[file]\t\t--debug[=file]\n"
+msgstr "\t-p[file]\t\t--profile[=file]\n"
+
+#: main.c:816
msgid "\t-e 'program-text'\t--source='program-text'\n"
msgstr "\t-e 'program-text'\t--source='program-text'\n"
-#: main.c:750
+#: main.c:817
msgid "\t-E file\t\t\t--exec=file\n"
msgstr "\t-E file\t\t\t--exec=file\n"
-#: main.c:751
+#: main.c:818
msgid "\t-g\t\t\t--gen-pot\n"
msgstr "\t-g\t\t\t--gen-pot\n"
-#: main.c:752
+#: main.c:819
msgid "\t-h\t\t\t--help\n"
msgstr "\t-h\t\t\t--help\n"
-#: main.c:753
+#: main.c:820
+msgid "\t-i includefile\t\t--include=includefile\n"
+msgstr ""
+
+#: main.c:821
+msgid "\t-l library\t\t--load=library\n"
+msgstr ""
+
+#: main.c:822
msgid "\t-L [fatal]\t\t--lint[=fatal]\n"
msgstr "\t-L [fatal]\t\t--lint[=fatal]\n"
-#: main.c:754
+#: main.c:823
msgid "\t-n\t\t\t--non-decimal-data\n"
msgstr "\t-n\t\t\t--non-decimal-data\n"
-#: main.c:755
+#: main.c:824
+#, fuzzy
+msgid "\t-M\t\t\t--bignum\n"
+msgstr "\t-g\t\t\t--gen-pot\n"
+
+#: main.c:825
msgid "\t-N\t\t\t--use-lc-numeric\n"
msgstr "\t-N\t\t\t--use-lc-numeric\n"
-#: main.c:756
+#: main.c:826
+#, fuzzy
+msgid "\t-o[file]\t\t--pretty-print[=file]\n"
+msgstr "\t-p[file]\t\t--profile[=file]\n"
+
+#: main.c:827
msgid "\t-O\t\t\t--optimize\n"
msgstr "\t-O\t\t\t--optimize\n"
-#: main.c:757
+#: main.c:828
msgid "\t-p[file]\t\t--profile[=file]\n"
msgstr "\t-p[file]\t\t--profile[=file]\n"
-#: main.c:758
+#: main.c:829
msgid "\t-P\t\t\t--posix\n"
msgstr "\t-P\t\t\t--posix\n"
-#: main.c:759
+#: main.c:830
msgid "\t-r\t\t\t--re-interval\n"
msgstr "\t-r\t\t\t--re-interval\n"
-#: main.c:761
-msgid "\t-R file\t\t\t--command=file\n"
-msgstr "\t-R file\t\t\t--command=file\n"
-
-#: main.c:762
+#: main.c:831
msgid "\t-S\t\t\t--sandbox\n"
msgstr "\t-S\t\t\t--sandbox\n"
-#: main.c:763
+#: main.c:832
msgid "\t-t\t\t\t--lint-old\n"
msgstr "\t-t\t\t\t--lint-old\n"
-#: main.c:764
+#: main.c:833
msgid "\t-V\t\t\t--version\n"
msgstr "\t-V\t\t\t--version\n"
-#: main.c:766
+#: main.c:835
msgid "\t-W nostalgia\t\t--nostalgia\n"
msgstr "\t-W nostalgia\t\t--nostalgia\n"
-#: main.c:769
+#: main.c:838
msgid "\t-Y\t\t--parsedebug\n"
msgstr "\t-Y\t\t--parsedebug\n"
@@ -1790,7 +3092,7 @@ msgstr "\t-Y\t\t--parsedebug\n"
#. for this application. Please add _another line_ with the
#. address for translation bugs.
#. no-wrap
-#: main.c:778
+#: main.c:847
msgid ""
"\n"
"To report bugs, see node `Bugs' in `gawk.info', which is\n"
@@ -1805,7 +3107,7 @@ msgstr ""
"翻訳ã«é–¢ã™ã‚‹ãƒã‚°ã¯<translation-team-ja@lists.sourceforge.net>ã«å ±å‘Šã—ã¦ãã ã•"
"ã„。\n"
-#: main.c:782
+#: main.c:851
msgid ""
"gawk is a pattern scanning and processing language.\n"
"By default it reads standard input and writes standard output.\n"
@@ -1815,7 +3117,7 @@ msgstr ""
"デフォルト設定ã§ã¯ã€æ¨™æº–入力を読ã¿è¾¼ã¿ã€æ¨™æº–出力ã«æ›¸ã出ã—ã¾ã™ã€‚\n"
"\n"
-#: main.c:786
+#: main.c:855
msgid ""
"Examples:\n"
"\tgawk '{ sum += $1 }; END { print sum }' file\n"
@@ -1825,7 +3127,7 @@ msgstr ""
"\tgawk '{ sum += $1 }; END { print sum }' file\n"
"\tgawk -F: '{ print $1 }' /etc/passwd\n"
-#: main.c:806
+#: main.c:880
#, c-format
msgid ""
"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
@@ -1844,7 +3146,7 @@ msgstr ""
"(at your option) any later version.\n"
"\n"
-#: main.c:814
+#: main.c:888
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"
@@ -1858,7 +3160,7 @@ msgstr ""
"GNU General Public License for more details.\n"
"\n"
-#: main.c:820
+#: main.c:894
msgid ""
"You should have received a copy of the GNU General Public License\n"
"along with this program. If not, see http://www.gnu.org/licenses/.\n"
@@ -1866,16 +3168,16 @@ msgstr ""
"You should have received a copy of the GNU General Public License\n"
"along with this program. If not, see http://www.gnu.org/licenses/.\n"
-#: main.c:855
+#: main.c:931
msgid "-Ft does not set FS to tab in POSIX awk"
msgstr "POSIX awk ã§ã¯ -Ft 㯠FS をタブã«è¨­å®šã—ã¾ã›ã‚“"
-#: main.c:1089
+#: main.c:1208
#, c-format
msgid "unknown value for field spec: %d\n"
msgstr "フィールド指定ã«ä¸æ˜Žãªå€¤ãŒã‚ã‚Šã¾ã™: %d\n"
-#: main.c:1170
+#: main.c:1306
#, c-format
msgid ""
"%s: `%s' argument to `-v' not in `var=value' form\n"
@@ -1884,84 +3186,129 @@ msgstr ""
"%s: オプション `-v' ã®å¼•æ•° `%s' ㌠`変数=代入値' ã®å½¢å¼ã«ãªã£ã¦ã„ã¾ã›ã‚“。\n"
"\n"
-#: main.c:1196
+#: main.c:1332
#, c-format
msgid "`%s' is not a legal variable name"
msgstr "`%s' ã¯ä¸æ­£ãªå¤‰æ•°åã§ã™"
-#: main.c:1199
+#: main.c:1335
#, c-format
msgid "`%s' is not a variable name, looking for file `%s=%s'"
msgstr "`%s' ã¯å¤‰æ•°åã§ã¯ã‚ã‚Šã¾ã›ã‚“。`%s=%s' ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’探ã—ã¾ã™ã€‚"
-#: main.c:1203
+#: main.c:1339
#, c-format
msgid "cannot use gawk builtin `%s' as variable name"
msgstr "gawk ã«çµ„ã¿è¾¼ã¿ã® `%s' ã¯å¤‰æ•°åã¨ã—ã¦ä½¿ç”¨å‡ºæ¥ã¾ã›ã‚“"
-#: main.c:1208
+#: main.c:1344
#, c-format
msgid "cannot use function `%s' as variable name"
msgstr "関数 `%s' ã¯å¤‰æ•°åã¨ã—ã¦ä½¿ç”¨å‡ºæ¥ã¾ã›ã‚“"
-#: main.c:1261
+#: main.c:1397
msgid "floating point exception"
msgstr "浮動å°æ•°ç‚¹ä¾‹å¤–"
-#: main.c:1268
+#: main.c:1404
msgid "fatal error: internal error"
msgstr "致命的エラー: 内部エラー"
-#: main.c:1283
+#: main.c:1419
msgid "fatal error: internal error: segfault"
msgstr "致命的エラー: 内部エラー: セグメンテーションé•å"
-#: main.c:1295
+#: main.c:1431
msgid "fatal error: internal error: stack overflow"
msgstr "致命的エラー: 内部エラー: スタックオーãƒãƒ¼ãƒ•ãƒ­ãƒ¼"
-#: main.c:1345
+#: main.c:1490
#, c-format
msgid "no pre-opened fd %d"
msgstr "fd %d ãŒäº‹å‰ã«é–‹ã„ã¦ã„ã¾ã›ã‚“。"
-#: main.c:1352
+#: main.c:1497
#, c-format
msgid "could not pre-open /dev/null for fd %d"
msgstr "事å‰ã« fd %d 用㫠/dev/null ã‚’é–‹ã‘ã¾ã›ã‚“。"
-#: main.c:1375 main.c:1384
-#, c-format
-msgid "could not find groups: %s"
-msgstr "グループãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: %s"
+#: mpfr.c:550
+#, fuzzy, c-format
+msgid "PREC value `%.*s' is invalid"
+msgstr "BINMODE 値 `%s' ã¯ç„¡åŠ¹ã§ã™ã€‚代ã‚ã‚Šã« 3 を使用ã—ã¾ã™"
+
+#: mpfr.c:608
+#, fuzzy, c-format
+msgid "RNDMODE value `%.*s' is invalid"
+msgstr "BINMODE 値 `%s' ã¯ç„¡åŠ¹ã§ã™ã€‚代ã‚ã‚Šã« 3 を使用ã—ã¾ã™"
+
+#: mpfr.c:698
+#, fuzzy, c-format
+msgid "%s: received non-numeric argument"
+msgstr "cos: éžæ•°å€¤ã®å¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
+
+#: mpfr.c:800
+#, fuzzy
+msgid "compl(%Rg): negative value will give strange results"
+msgstr "compl(%lf): è² ã®æ•°å€¤ã‚’使用ã™ã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
+
+#: mpfr.c:804
+#, fuzzy
+msgid "comp(%Rg): fractional value will be truncated"
+msgstr "compl(%lf): å°æ•°ç‚¹ä»¥ä¸‹ã¯åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã™"
+
+#: mpfr.c:816
+#, fuzzy, c-format
+msgid "cmpl(%Zd): negative values will give strange results"
+msgstr "compl(%lf): è² ã®æ•°å€¤ã‚’使用ã™ã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
+
+#: mpfr.c:835
+#, fuzzy, c-format
+msgid "%s: received non-numeric argument #%d"
+msgstr "cos: éžæ•°å€¤ã®å¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
+
+#: mpfr.c:845
+msgid "%s: argument #%d has invalid value %Rg, using 0"
+msgstr ""
+
+#: mpfr.c:857
+#, fuzzy
+msgid "%s: argument #%d negative value %Rg will give strange results"
+msgstr "and(%lf, %lf): è² ã®æ•°å€¤ã‚’使用ã™ã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
+
+#: mpfr.c:863
+#, fuzzy
+msgid "%s: argument #%d fractional value %Rg will be truncated"
+msgstr "and(%lf, %lf): å°æ•°ç‚¹ä»¥ä¸‹ã¯åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã™"
-#: msg.c:63
+#: mpfr.c:878
+#, fuzzy, c-format
+msgid "%s: argument #%d negative value %Zd will give strange results"
+msgstr "and(%lf, %lf): è² ã®æ•°å€¤ã‚’使用ã™ã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
+
+#: msg.c:68
#, c-format
msgid "cmd. line:"
msgstr "コマンドライン:"
-#: msg.c:107
-msgid "error: "
-msgstr "エラー: "
-
-#: node.c:406
+#: node.c:421
msgid "backslash at end of string"
msgstr "文字列ã®çµ‚ã‚Šã«ãƒãƒƒã‚¯ã‚¹ãƒ©ãƒƒã‚·ãƒ¥ãŒä½¿ã‚ã‚Œã¦ã„ã¾ã™ã€‚"
-#: node.c:517
+#: node.c:500
#, c-format
msgid "old awk does not support the `\\%c' escape sequence"
msgstr "å¤ã„ awk 㯠`\\%c' エスケープシーケンスをサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
-#: node.c:568
+#: node.c:551
msgid "POSIX does not allow `\\x' escapes"
msgstr "POSIX ã§ã¯ `\\x' エスケープã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
-#: node.c:574
+#: node.c:557
msgid "no hex digits in `\\x' escape sequence"
msgstr "`\\x' エスケープシーケンスã«å六進数ãŒã‚ã‚Šã¾ã›ã‚“"
-#: node.c:596
+#: node.c:579
#, c-format
msgid ""
"hex escape \\x%.*s of %d characters probably not interpreted the way you "
@@ -1970,12 +3317,12 @@ msgstr ""
"å六進エスケープ \\x%.*s (%d 文字) ã¯ãŠãらã予期ã—ãŸã‚ˆã†ã«ã¯è§£é‡ˆã•ã‚Œãªã„ã§"
"ã—ょã†"
-#: node.c:611
+#: node.c:594
#, c-format
msgid "escape sequence `\\%c' treated as plain `%c'"
msgstr "エスケープシーケンス `\\%c' 㯠`%c' ã¨åŒç­‰ã«æ‰±ã‚ã‚Œã¾ã™"
-#: node.c:750
+#: node.c:739
msgid ""
"Invalid multibyte data detected. There may be a mismatch between your data "
"and your locale."
@@ -1983,26 +3330,26 @@ msgstr ""
"無効ãªãƒžãƒ«ãƒãƒã‚¤ãƒˆãƒ‡ãƒ¼ã‚¿ãŒæ¤œå‡ºã•ã‚Œã¾ã—ãŸã€‚データã¨ãƒ­ã‚±ãƒ¼ãƒ«ãŒä¸€è‡´ã—ã¦ã„ãªã„よ"
"ã†ã§ã™ã€‚"
-#: posix/gawkmisc.c:176
+#: posix/gawkmisc.c:177
#, c-format
msgid "%s %s `%s': could not get fd flags: (fcntl F_GETFD: %s)"
msgstr "%s %s `%s': fd フラグをå–å¾—ã§ãã¾ã›ã‚“: (fcntl F_GETFD: %s)"
-#: posix/gawkmisc.c:188
+#: posix/gawkmisc.c:189
#, c-format
msgid "%s %s `%s': could not set close-on-exec: (fcntl F_SETFD: %s)"
msgstr "%s %s `%s': close-on-exec を設定ã§ãã¾ã›ã‚“: (fcntl F_SETFD: %s)"
-#: profile.c:83
+#: profile.c:71
#, c-format
msgid "could not open `%s' for writing: %s"
msgstr "`%s' を書込ã¿ç”¨ã«é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸ: %s"
-#: profile.c:85
+#: profile.c:73
msgid "sending profile to standard error"
msgstr "プロファイルを標準エラーã«é€ã£ã¦ã„ã¾ã™"
-#: profile.c:203
+#: profile.c:193
#, c-format
msgid ""
"\t# %s block(s)\n"
@@ -2011,7 +3358,7 @@ msgstr ""
"\t# %s ブロック\n"
"\n"
-#: profile.c:208
+#: profile.c:198
#, c-format
msgid ""
"\t# Rule(s)\n"
@@ -2020,17 +3367,29 @@ msgstr ""
"\t# ルール\n"
"\n"
-#: profile.c:279
+#: profile.c:272
#, c-format
msgid "internal error: %s with null vname"
msgstr "内部エラー: %s ã® vname ãŒç„¡åŠ¹ã§ã™ã€‚"
-#: profile.c:952
+#: profile.c:537
+#, fuzzy
+msgid "internal error: builtin with null fname"
+msgstr "内部エラー: %s ã® vname ãŒç„¡åŠ¹ã§ã™ã€‚"
+
+#: profile.c:949
+#, c-format
+msgid ""
+"\t# Loaded extensions (-l and/or @load)\n"
+"\n"
+msgstr ""
+
+#: profile.c:972
#, c-format
msgid "\t# gawk profile, created %s\n"
msgstr "\t# gawk プロファイルã€ä½œæˆæ—¥æ™‚ %s\n"
-#: profile.c:1331
+#: profile.c:1475
#, c-format
msgid ""
"\n"
@@ -2039,92 +3398,195 @@ msgstr ""
"\n"
"\t# 関数一覧(アルファベット順)\n"
-#: profile.c:1370
+#: profile.c:1513
#, c-format
msgid "redir2str: unknown redirection type %d"
msgstr "redir2str: ä¸æ˜Žãªãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆåž‹ %d ã§ã™"
-#: re.c:572
-#, fuzzy, c-format
-msgid "range of the form `[%c-%c]' is locale dependent"
-msgstr "`[%c-%c]' å½¢å¼ã®ç¯„囲ã¯ãƒ­ã‚±ãƒ¼ãƒ«ä¾å­˜ã§ã™"
-
-#: re.c:599
+#: re.c:607
#, c-format
msgid "regexp component `%.*s' should probably be `[%.*s]'"
msgstr "æ­£è¦è¡¨ç¾ã®è¦ç´  `%.*s' ã¯ãŠãらã `[%.*s]' ã§ã‚ã‚‹ã¹ãã§ã™"
-#: regcomp.c:132
+#: regcomp.c:131
msgid "Success"
msgstr "æˆåŠŸã§ã™"
-#: regcomp.c:135
+#: regcomp.c:134
msgid "No match"
msgstr "一致ã—ã¾ã›ã‚“"
-#: regcomp.c:138
+#: regcomp.c:137
msgid "Invalid regular expression"
msgstr "無効ãªæ­£è¦è¡¨ç¾ã§ã™"
-#: regcomp.c:141
+#: regcomp.c:140
msgid "Invalid collation character"
msgstr "無効ãªç…§åˆæ–‡å­—ã§ã™"
-#: regcomp.c:144
+#: regcomp.c:143
msgid "Invalid character class name"
msgstr "無効ãªæ–‡å­—クラスåã§ã™"
-#: regcomp.c:147
+#: regcomp.c:146
msgid "Trailing backslash"
msgstr "終端ã®ãƒãƒƒã‚¯ã‚¹ãƒ©ãƒƒã‚·ãƒ¥"
-#: regcomp.c:150
+#: regcomp.c:149
msgid "Invalid back reference"
msgstr "無効ãªå‰æ–¹å‚ç…§ã§ã™"
-#: regcomp.c:153
+#: regcomp.c:152
msgid "Unmatched [ or [^"
msgstr "[ ã¾ãŸã¯ [^ ãŒä¸ä¸€è‡´ã§ã™"
-#: regcomp.c:156
+#: regcomp.c:155
msgid "Unmatched ( or \\("
msgstr "( ã¾ãŸã¯ \\( ãŒä¸ä¸€è‡´ã§ã™"
-#: regcomp.c:159
+#: regcomp.c:158
msgid "Unmatched \\{"
msgstr "\\{ ãŒä¸ä¸€è‡´ã§ã™"
-#: regcomp.c:162
-msgid "Invalid content of \\{\\}"
-msgstr "\\{\\} ã®ä¸­èº«ãŒç„¡åŠ¹ã§ã™"
-
-#: regcomp.c:165
+#: regcomp.c:164
msgid "Invalid range end"
msgstr "無効ãªç¯„囲終了ã§ã™"
-#: regcomp.c:168
+#: regcomp.c:167
msgid "Memory exhausted"
msgstr "メモリを使ã„æžœãŸã—ã¾ã—ãŸ"
-#: regcomp.c:171
+#: regcomp.c:170
msgid "Invalid preceding regular expression"
msgstr "無効ãªå‰æ–¹æ­£è¦è¡¨ç¾ã§ã™"
-#: regcomp.c:174
+#: regcomp.c:173
msgid "Premature end of regular expression"
msgstr "æ­£è¦è¡¨ç¾ãŒé€”中ã§çµ‚了ã—ã¾ã—ãŸ"
-#: regcomp.c:177
-msgid "Regular expression too big"
-msgstr "æ­£è¦è¡¨ç¾ãŒå¤§ãã™ãŽã¾ã™"
-
-#: regcomp.c:180
+#: regcomp.c:179
msgid "Unmatched ) or \\)"
msgstr ") ã¾ãŸã¯ \\) ãŒä¸ä¸€è‡´ã§ã™"
-#: regcomp.c:701
+#: regcomp.c:704
msgid "No previous regular expression"
msgstr "以å‰ã«æ­£è¦è¡¨ç¾ãŒã‚ã‚Šã¾ã›ã‚“"
+#: symbol.c:741
+msgid "can not pop main context"
+msgstr ""
+
+#~ msgid "attempt to use function `%s' as an array"
+#~ msgstr "関数 `%s' ã‚’é…列ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹è©¦ã¿ã§ã™"
+
+#~ msgid "reference to uninitialized element `%s[\"%.*s\"]'"
+#~ msgstr "åˆæœŸåŒ–ã•ã‚Œã¦ã„ãªã„è¦ç´  `%s[\"%.*s\"]' ã¸ã®å‚ç…§ã§ã™"
+
+#~ msgid "subscript of array `%s' is null string"
+#~ msgstr "é…列 `%s' ã®æ·»å­—㌠NULL 文字列ã§ã™"
+
+#~ msgid "%s: empty (null)\n"
+#~ msgstr "%s: 空 (null)\n"
+
+#~ msgid "%s: empty (zero)\n"
+#~ msgstr "%s: 空 (zero)\n"
+
+#~ msgid "%s: table_size = %d, array_size = %d\n"
+#~ msgstr ""
+#~ "%s: テーブルサイズ (table_size) = %d, é…列サイズ (array_size) = %d\n"
+
+#~ msgid "%s: array_ref to %s\n"
+#~ msgstr "%s: %s ã¸ã®é…列å‚ç…§ (array_ref) ã§ã™\n"
+
+#~ msgid "`nextfile' is a gawk extension"
+#~ msgstr "`nextfile' 㯠gawk æ‹¡å¼µã§ã™"
+
+#~ msgid "`delete array' is a gawk extension"
+#~ msgstr "`delete array' 㯠gawk æ‹¡å¼µã§ã™"
+
+#~ msgid "use of non-array as array"
+#~ msgstr "é…列ã§ãªã„ã‚‚ã®ã‚’é…列ã¨ã—ã¦ä½¿ç”¨ã—ã¦ã„ã¾ã™"
+
+#~ msgid "`%s' is a Bell Labs extension"
+#~ msgstr "`%s' ã¯ãƒ™ãƒ«ç ”究所ã«ã‚ˆã‚‹æ‹¡å¼µã§ã™"
+
+#~ msgid "and: received non-numeric first argument"
+#~ msgstr "and: éžæ•°å€¤ã®ç¬¬ä¸€å¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
+
+#~ msgid "and: received non-numeric second argument"
+#~ msgstr "and: éžæ•°å€¤ã®ç¬¬äºŒå¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
+
+#~ msgid "or: received non-numeric first argument"
+#~ msgstr "or: éžæ•°å€¤ã®ç¬¬ä¸€å¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
+
+#~ msgid "or: received non-numeric second argument"
+#~ msgstr "or: éžæ•°å€¤ã®ç¬¬äºŒå¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
+
+#~ msgid "or(%lf, %lf): negative values will give strange results"
+#~ msgstr "or(%lf, %lf): è² ã®æ•°å€¤ã‚’使用ã™ã‚‹ã¨ç•°å¸¸ãªçµæžœã«ãªã‚Šã¾ã™"
+
+#~ msgid "or(%lf, %lf): fractional values will be truncated"
+#~ msgstr "or(%lf, %lf): å°æ•°ç‚¹ä»¥ä¸‹ã¯åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã™"
+
+#~ msgid "xor: received non-numeric first argument"
+#~ msgstr "xor: éžæ•°å€¤ã®ç¬¬ä¸€å¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
+
+#~ msgid "xor: received non-numeric second argument"
+#~ msgstr "xor: éžæ•°å€¤ã®ç¬¬äºŒå¼•æ•°ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ"
+
+#~ msgid "xor(%lf, %lf): fractional values will be truncated"
+#~ msgstr "xor(%lf, %lf): å°æ•°ç‚¹ä»¥ä¸‹ã¯åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã™"
+
+#~ msgid "can't use function name `%s' as variable or array"
+#~ msgstr "関数å `%s' ã¯å¤‰æ•°ã¾ãŸã¯é…列ã¨ã—ã¦ä½¿ç”¨å‡ºæ¥ã¾ã›ã‚“"
+
#~ msgid "assignment is not allowed to result of builtin function"
#~ msgstr "組込関数ã®æˆ»ã‚Šå€¤ã¸ã®ä»£å…¥ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#~ msgid "assignment used in conditional context"
+#~ msgstr "æ¡ä»¶ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆå†…ã§ä»£å…¥ãŒä½¿ç”¨ã•ã‚Œã¾ã—ãŸ"
+
+#~ msgid "statement has no effect"
+#~ msgstr "æ–‡ã«åŠ¹æžœãŒã‚ã‚Šã¾ã›ã‚“"
+
+#~ msgid ""
+#~ "for loop: array `%s' changed size from %ld to %ld during loop execution"
+#~ msgstr ""
+#~ "for ループ: ループ実行中ã«é…列 `%s' ã®ã‚µã‚¤ã‚ºãŒ %ld ã‹ã‚‰ %ld ã¸å¤‰æ›´ã•ã‚Œã¾ã—"
+#~ "ãŸ"
+
+#~ msgid "function called indirectly through `%s' does not exist"
+#~ msgstr "`%s' を通ã—ã¦é–“接的ã«å‘¼ã³å‡ºã•ã‚ŒãŸé–¢æ•°ãŒå­˜åœ¨ã—ã¾ã›ã‚“"
+
+#~ msgid "function `%s' not defined"
+#~ msgstr "関数 `%s' ã¯å®šç¾©ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#~ msgid "non-redirected `getline' invalid inside `%s' rule"
+#~ msgstr "`%s' ルールã®å†…å´ã§ã¯ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã•ã‚Œã¦ã„ãªã„ `getline' ã¯ç„¡åŠ¹ã§ã™"
+
+#~ msgid "`nextfile' cannot be called from a `%s' rule"
+#~ msgstr "`nextfile' 㯠`%s' ルールã‹ã‚‰å‘¼ã³å‡ºã™ã“ã¨ãŒå‡ºæ¥ã¾ã›ã‚“"
+
+#~ msgid "`next' cannot be called from a `%s' rule"
+#~ msgstr "`next' 㯠`%s' ã‹ã‚‰å‘¼ã³å‡ºã™ã“ã¨ãŒå‡ºæ¥ã¾ã›ã‚“"
+
+#~ msgid "Sorry, don't know how to interpret `%s'"
+#~ msgstr "申ã—訳ã‚ã‚Šã¾ã›ã‚“㌠`%s' ã‚’ã©ã®ã‚ˆã†ã«è§£é‡ˆã™ã‚‹ã‹åˆ†ã‹ã‚Šã¾ã›ã‚“"
+
+#~ msgid "Operation Not Supported"
+#~ msgstr "ã“ã®æ“作ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#~ msgid "`-m[fr]' option irrelevant in gawk"
+#~ msgstr "gawk ã§ã¯ã‚ªãƒ—ション `-m[fr]' ã«åŠ¹æžœã¯ã‚ã‚Šã¾ã›ã‚“。"
+
+#~ msgid "-m option usage: `-m[fr] nnn'"
+#~ msgstr "-m オプションã®ä½¿ç”¨æ³•: `-m[fr] 数値'"
+
+#~ msgid "\t-R file\t\t\t--command=file\n"
+#~ msgstr "\t-R file\t\t\t--command=file\n"
+
+#~ msgid "could not find groups: %s"
+#~ msgstr "グループãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: %s"
+
+#~ msgid "range of the form `[%c-%c]' is locale dependant"
+#~ msgstr "`[%c-%c]' å½¢å¼ã®ç¯„囲ã¯ãƒ­ã‚±ãƒ¼ãƒ«ä¾å­˜ã§ã™"
diff --git a/po/ms.gmo b/po/ms.gmo
new file mode 100644
index 00000000..6123c873
--- /dev/null
+++ b/po/ms.gmo
Binary files differ
diff --git a/po/ms.po b/po/ms.po
new file mode 100644
index 00000000..09ec6472
--- /dev/null
+++ b/po/ms.po
@@ -0,0 +1,3350 @@
+# gawk Bahasa Melayu (Malay).
+# Copyright (C) 2013 Free Software Foundation, Inc.
+# This file is distributed under the same license as the gawk package.
+# Sharuzzaman Ahmat Raslan <sharuzzaman@gmail.com>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gawk 4.0.75\n"
+"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
+"POT-Creation-Date: 2014-04-08 19:23+0300\n"
+"PO-Revision-Date: 2013-04-19 10:45+0800\n"
+"Last-Translator: Sharuzzaman Ahmat Raslan <sharuzzaman@gmail.com>\n"
+"Language-Team: Malay <translation-team-ms@lists.sourceforge.net>\n"
+"Language: ms\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.5.5\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Poedit-SourceCharset: UTF-8\n"
+
+#: array.c:256
+#, c-format
+msgid "from %s"
+msgstr "dari %s"
+
+#: array.c:357
+msgid "attempt to use a scalar value as array"
+msgstr "cubaan untuk menggunakan nilai skalar sebagai tatasusunan"
+
+#: array.c:359
+#, c-format
+msgid "attempt to use scalar parameter `%s' as an array"
+msgstr "cubaan untuk menggunakan parameter skalar `%s' sebagai tatasusunan"
+
+#: array.c:362
+#, c-format
+msgid "attempt to use scalar `%s' as an array"
+msgstr "cubaan untuk menggunakan skalar `%s' sebagai tatasusunan"
+
+#: array.c:409 array.c:576 builtin.c:85 builtin.c:1615 builtin.c:1661
+#: builtin.c:1674 builtin.c:2102 builtin.c:2116 eval.c:1122 eval.c:1126
+#: eval.c:1531
+#, c-format
+msgid "attempt to use array `%s' in a scalar context"
+msgstr "cubaan untuk menggunakan tatasusunan `%s' dalam konteks skalar"
+
+#: array.c:583
+#, c-format
+msgid "delete: index `%s' not in array `%s'"
+msgstr "padam: indeks `%s' tiada dalam tatasusunan `%s'"
+
+#: array.c:597
+#, c-format
+msgid "attempt to use scalar `%s[\"%.*s\"]' as an array"
+msgstr ""
+
+#: array.c:776
+msgid "adump: first argument not an array"
+msgstr ""
+
+#: array.c:815
+msgid "asort: second argument not an array"
+msgstr ""
+
+#: array.c:816
+msgid "asorti: second argument not an array"
+msgstr ""
+
+#: array.c:823
+msgid "asort: first argument not an array"
+msgstr ""
+
+#: array.c:824
+msgid "asorti: first argument not an array"
+msgstr ""
+
+#: array.c:831
+msgid "asort: cannot use a subarray of first arg for second arg"
+msgstr ""
+
+#: array.c:832
+msgid "asorti: cannot use a subarray of first arg for second arg"
+msgstr ""
+
+#: array.c:837
+msgid "asort: cannot use a subarray of second arg for first arg"
+msgstr ""
+
+#: array.c:838
+msgid "asorti: cannot use a subarray of second arg for first arg"
+msgstr ""
+
+#: array.c:1314
+#, c-format
+msgid "`%s' is invalid as a function name"
+msgstr ""
+
+#: array.c:1318
+#, c-format
+msgid "sort comparison function `%s' is not defined"
+msgstr ""
+
+#: awkgram.y:233
+#, c-format
+msgid "%s blocks must have an action part"
+msgstr ""
+
+#: awkgram.y:236
+msgid "each rule must have a pattern or an action part"
+msgstr ""
+
+#: awkgram.y:325 awkgram.y:336
+msgid "old awk does not support multiple `BEGIN' or `END' rules"
+msgstr ""
+
+#: awkgram.y:373
+#, c-format
+msgid "`%s' is a built-in function, it cannot be redefined"
+msgstr ""
+
+#: awkgram.y:419
+msgid "regexp constant `//' looks like a C++ comment, but is not"
+msgstr ""
+
+#: awkgram.y:423
+#, c-format
+msgid "regexp constant `/%s/' looks like a C comment, but is not"
+msgstr ""
+
+#: awkgram.y:515
+#, c-format
+msgid "duplicate case values in switch body: %s"
+msgstr ""
+
+#: awkgram.y:536
+msgid "duplicate `default' detected in switch body"
+msgstr ""
+
+#: awkgram.y:796 awkgram.y:3723
+msgid "`break' is not allowed outside a loop or switch"
+msgstr ""
+
+#: awkgram.y:805 awkgram.y:3715
+msgid "`continue' is not allowed outside a loop"
+msgstr ""
+
+#: awkgram.y:815
+#, c-format
+msgid "`next' used in %s action"
+msgstr ""
+
+#: awkgram.y:824
+#, c-format
+msgid "`nextfile' used in %s action"
+msgstr ""
+
+#: awkgram.y:848
+msgid "`return' used outside function context"
+msgstr ""
+
+#: awkgram.y:922
+msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
+msgstr ""
+
+#: awkgram.y:988 awkgram.y:1037
+msgid "`delete' is not allowed with SYMTAB"
+msgstr ""
+
+#: awkgram.y:990 awkgram.y:1039
+msgid "`delete' is not allowed with FUNCTAB"
+msgstr ""
+
+#: awkgram.y:1024 awkgram.y:1028
+msgid "`delete(array)' is a non-portable tawk extension"
+msgstr ""
+
+#: awkgram.y:1149
+msgid "multistage two-way pipelines don't work"
+msgstr ""
+
+#: awkgram.y:1264
+msgid "regular expression on right of assignment"
+msgstr ""
+
+#: awkgram.y:1275
+msgid "regular expression on left of `~' or `!~' operator"
+msgstr ""
+
+#: awkgram.y:1291 awkgram.y:1442
+msgid "old awk does not support the keyword `in' except after `for'"
+msgstr ""
+
+#: awkgram.y:1301
+msgid "regular expression on right of comparison"
+msgstr ""
+
+#: awkgram.y:1417
+#, c-format
+msgid "`getline var' invalid inside `%s' rule"
+msgstr ""
+
+#: awkgram.y:1420
+#, c-format
+msgid "`getline' invalid inside `%s' rule"
+msgstr ""
+
+#: awkgram.y:1425
+msgid "non-redirected `getline' undefined inside END action"
+msgstr ""
+
+#: awkgram.y:1444
+msgid "old awk does not support multidimensional arrays"
+msgstr ""
+
+#: awkgram.y:1541
+msgid "call of `length' without parentheses is not portable"
+msgstr ""
+
+#: awkgram.y:1607
+msgid "indirect function calls are a gawk extension"
+msgstr ""
+
+#: awkgram.y:1620
+#, c-format
+msgid "can not use special variable `%s' for indirect function call"
+msgstr ""
+
+#: awkgram.y:1698
+msgid "invalid subscript expression"
+msgstr ""
+
+#: awkgram.y:2048 awkgram.y:2068 gawkapi.c:206 gawkapi.c:224 msg.c:126
+msgid "warning: "
+msgstr ""
+
+#: awkgram.y:2066 gawkapi.c:192 gawkapi.c:221 msg.c:158
+msgid "fatal: "
+msgstr ""
+
+#: awkgram.y:2116
+msgid "unexpected newline or end of string"
+msgstr ""
+
+#: awkgram.y:2383 awkgram.y:2459 awkgram.y:2682 debug.c:523 debug.c:539
+#: debug.c:2812 debug.c:5055
+#, c-format
+msgid "can't open source file `%s' for reading (%s)"
+msgstr ""
+
+#: awkgram.y:2384 awkgram.y:2509
+#, c-format
+msgid "can't open shared library `%s' for reading (%s)"
+msgstr ""
+
+#: awkgram.y:2386 awkgram.y:2460 awkgram.y:2510 builtin.c:135 debug.c:5206
+msgid "reason unknown"
+msgstr ""
+
+#: awkgram.y:2395 awkgram.y:2419
+#, c-format
+msgid "can't include `%s' and use it as a program file"
+msgstr ""
+
+#: awkgram.y:2408
+#, c-format
+msgid "already included source file `%s'"
+msgstr ""
+
+#: awkgram.y:2409
+#, c-format
+msgid "already loaded shared library `%s'"
+msgstr ""
+
+#: awkgram.y:2444
+msgid "@include is a gawk extension"
+msgstr ""
+
+#: awkgram.y:2450
+msgid "empty filename after @include"
+msgstr ""
+
+#: awkgram.y:2494
+msgid "@load is a gawk extension"
+msgstr ""
+
+#: awkgram.y:2500
+msgid "empty filename after @load"
+msgstr ""
+
+#: awkgram.y:2634
+msgid "empty program text on command line"
+msgstr ""
+
+#: awkgram.y:2749
+#, c-format
+msgid "can't read sourcefile `%s' (%s)"
+msgstr ""
+
+#: awkgram.y:2760
+#, c-format
+msgid "source file `%s' is empty"
+msgstr ""
+
+#: awkgram.y:2937
+msgid "source file does not end in newline"
+msgstr ""
+
+#: awkgram.y:3042
+msgid "unterminated regexp ends with `\\' at end of file"
+msgstr ""
+
+#: awkgram.y:3066
+#, c-format
+msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:3070
+#, c-format
+msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
+msgstr ""
+
+#: awkgram.y:3077
+msgid "unterminated regexp"
+msgstr ""
+
+#: awkgram.y:3081
+msgid "unterminated regexp at end of file"
+msgstr ""
+
+#: awkgram.y:3140
+msgid "use of `\\ #...' line continuation is not portable"
+msgstr ""
+
+#: awkgram.y:3156
+msgid "backslash not last character on line"
+msgstr ""
+
+#: awkgram.y:3217
+msgid "POSIX does not allow operator `**='"
+msgstr ""
+
+#: awkgram.y:3219
+msgid "old awk does not support operator `**='"
+msgstr ""
+
+#: awkgram.y:3228
+msgid "POSIX does not allow operator `**'"
+msgstr ""
+
+#: awkgram.y:3230
+msgid "old awk does not support operator `**'"
+msgstr ""
+
+#: awkgram.y:3265
+msgid "operator `^=' is not supported in old awk"
+msgstr ""
+
+#: awkgram.y:3273
+msgid "operator `^' is not supported in old awk"
+msgstr ""
+
+#: awkgram.y:3366 awkgram.y:3382 command.y:1178
+msgid "unterminated string"
+msgstr ""
+
+#: awkgram.y:3603
+#, c-format
+msgid "invalid char '%c' in expression"
+msgstr ""
+
+#: awkgram.y:3650
+#, c-format
+msgid "`%s' is a gawk extension"
+msgstr ""
+
+#: awkgram.y:3655
+#, c-format
+msgid "POSIX does not allow `%s'"
+msgstr ""
+
+#: awkgram.y:3663
+#, c-format
+msgid "`%s' is not supported in old awk"
+msgstr ""
+
+#: awkgram.y:3753
+msgid "`goto' considered harmful!\n"
+msgstr ""
+
+#: awkgram.y:3787
+#, c-format
+msgid "%d is invalid as number of arguments for %s"
+msgstr ""
+
+#: awkgram.y:3822
+#, c-format
+msgid "%s: string literal as last arg of substitute has no effect"
+msgstr ""
+
+#: awkgram.y:3827
+#, c-format
+msgid "%s third parameter is not a changeable object"
+msgstr ""
+
+#: awkgram.y:3910 awkgram.y:3913
+msgid "match: third argument is a gawk extension"
+msgstr ""
+
+#: awkgram.y:3967 awkgram.y:3970
+msgid "close: second argument is a gawk extension"
+msgstr ""
+
+#: awkgram.y:3982
+msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+
+#: awkgram.y:3997
+msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
+msgstr ""
+
+#: awkgram.y:4016
+msgid "index: regexp constant as second argument is not allowed"
+msgstr ""
+
+#: awkgram.y:4069
+#, c-format
+msgid "function `%s': parameter `%s' shadows global variable"
+msgstr ""
+
+#: awkgram.y:4126 debug.c:4041 debug.c:4084 debug.c:5204
+#, c-format
+msgid "could not open `%s' for writing (%s)"
+msgstr ""
+
+#: awkgram.y:4127
+msgid "sending variable list to standard error"
+msgstr ""
+
+#: awkgram.y:4135
+#, c-format
+msgid "%s: close failed (%s)"
+msgstr ""
+
+#: awkgram.y:4160
+msgid "shadow_funcs() called twice!"
+msgstr ""
+
+#: awkgram.y:4168
+msgid "there were shadowed variables."
+msgstr ""
+
+#: awkgram.y:4239
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr ""
+
+#: awkgram.y:4285
+#, c-format
+msgid "function `%s': can't use function name as parameter name"
+msgstr ""
+
+#: awkgram.y:4288
+#, c-format
+msgid "function `%s': can't use special variable `%s' as a function parameter"
+msgstr ""
+
+#: awkgram.y:4296
+#, c-format
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr ""
+
+#: awkgram.y:4383 awkgram.y:4389
+#, c-format
+msgid "function `%s' called but never defined"
+msgstr ""
+
+#: awkgram.y:4393
+#, c-format
+msgid "function `%s' defined but never called directly"
+msgstr ""
+
+#: awkgram.y:4425
+#, c-format
+msgid "regexp constant for parameter #%d yields boolean value"
+msgstr ""
+
+#: awkgram.y:4484
+#, c-format
+msgid ""
+"function `%s' called with space between name and `(',\n"
+"or used as a variable or an array"
+msgstr ""
+
+#: awkgram.y:4720
+msgid "division by zero attempted"
+msgstr ""
+
+#: awkgram.y:4729
+#, c-format
+msgid "division by zero attempted in `%%'"
+msgstr ""
+
+#: awkgram.y:5049
+msgid ""
+"cannot assign a value to the result of a field post-increment expression"
+msgstr ""
+
+#: awkgram.y:5052
+#, c-format
+msgid "invalid target of assignment (opcode %s)"
+msgstr ""
+
+#: builtin.c:133
+#, c-format
+msgid "%s to \"%s\" failed (%s)"
+msgstr ""
+
+#: builtin.c:134
+msgid "standard output"
+msgstr ""
+
+#: builtin.c:148
+msgid "exp: received non-numeric argument"
+msgstr ""
+
+#: builtin.c:154
+#, c-format
+msgid "exp: argument %g is out of range"
+msgstr ""
+
+#: builtin.c:229
+#, c-format
+msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
+msgstr ""
+
+#: builtin.c:232
+#, c-format
+msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
+msgstr ""
+
+#: builtin.c:244
+#, c-format
+msgid "fflush: `%s' is not an open file, pipe or co-process"
+msgstr ""
+
+#: builtin.c:362
+msgid "index: received non-string first argument"
+msgstr ""
+
+#: builtin.c:364
+msgid "index: received non-string second argument"
+msgstr ""
+
+#: builtin.c:488 mpfr.c:757
+msgid "int: received non-numeric argument"
+msgstr ""
+
+#: builtin.c:525
+msgid "length: received array argument"
+msgstr ""
+
+#: builtin.c:528
+msgid "`length(array)' is a gawk extension"
+msgstr ""
+
+#: builtin.c:544
+msgid "length: received non-string argument"
+msgstr ""
+
+#: builtin.c:575
+msgid "log: received non-numeric argument"
+msgstr ""
+
+#: builtin.c:578
+#, c-format
+msgid "log: received negative argument %g"
+msgstr ""
+
+#: builtin.c:776 builtin.c:781
+msgid "fatal: must use `count$' on all formats or none"
+msgstr ""
+
+#: builtin.c:851
+#, c-format
+msgid "field width is ignored for `%%' specifier"
+msgstr ""
+
+#: builtin.c:853
+#, c-format
+msgid "precision is ignored for `%%' specifier"
+msgstr ""
+
+#: builtin.c:855
+#, c-format
+msgid "field width and precision are ignored for `%%' specifier"
+msgstr ""
+
+#: builtin.c:906
+msgid "fatal: `$' is not permitted in awk formats"
+msgstr ""
+
+#: builtin.c:915
+msgid "fatal: arg count with `$' must be > 0"
+msgstr ""
+
+#: builtin.c:919
+#, c-format
+msgid "fatal: arg count %ld greater than total number of supplied arguments"
+msgstr ""
+
+#: builtin.c:923
+msgid "fatal: `$' not permitted after period in format"
+msgstr ""
+
+#: builtin.c:939
+msgid "fatal: no `$' supplied for positional field width or precision"
+msgstr ""
+
+#: builtin.c:1009
+msgid "`l' is meaningless in awk formats; ignored"
+msgstr ""
+
+#: builtin.c:1013
+msgid "fatal: `l' is not permitted in POSIX awk formats"
+msgstr ""
+
+#: builtin.c:1026
+msgid "`L' is meaningless in awk formats; ignored"
+msgstr ""
+
+#: builtin.c:1030
+msgid "fatal: `L' is not permitted in POSIX awk formats"
+msgstr ""
+
+#: builtin.c:1043
+msgid "`h' is meaningless in awk formats; ignored"
+msgstr ""
+
+#: builtin.c:1047
+msgid "fatal: `h' is not permitted in POSIX awk formats"
+msgstr ""
+
+#: builtin.c:1463
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr ""
+
+#: builtin.c:1561
+#, c-format
+msgid "ignoring unknown format specifier character `%c': no argument converted"
+msgstr ""
+
+#: builtin.c:1566
+msgid "fatal: not enough arguments to satisfy format string"
+msgstr ""
+
+#: builtin.c:1568
+msgid "^ ran out for this one"
+msgstr ""
+
+#: builtin.c:1575
+msgid "[s]printf: format specifier does not have control letter"
+msgstr ""
+
+#: builtin.c:1578
+msgid "too many arguments supplied for format string"
+msgstr ""
+
+#: builtin.c:1634
+msgid "sprintf: no arguments"
+msgstr ""
+
+#: builtin.c:1657 builtin.c:1668
+msgid "printf: no arguments"
+msgstr ""
+
+#: builtin.c:1711
+msgid "sqrt: received non-numeric argument"
+msgstr ""
+
+#: builtin.c:1715
+#, c-format
+msgid "sqrt: called with negative argument %g"
+msgstr ""
+
+#: builtin.c:1746
+#, c-format
+msgid "substr: length %g is not >= 1"
+msgstr ""
+
+#: builtin.c:1748
+#, c-format
+msgid "substr: length %g is not >= 0"
+msgstr ""
+
+#: builtin.c:1755
+#, c-format
+msgid "substr: non-integer length %g will be truncated"
+msgstr ""
+
+#: builtin.c:1760
+#, c-format
+msgid "substr: length %g too big for string indexing, truncating to %g"
+msgstr ""
+
+#: builtin.c:1772
+#, c-format
+msgid "substr: start index %g is invalid, using 1"
+msgstr ""
+
+#: builtin.c:1777
+#, c-format
+msgid "substr: non-integer start index %g will be truncated"
+msgstr ""
+
+#: builtin.c:1802
+msgid "substr: source string is zero length"
+msgstr ""
+
+#: builtin.c:1818
+#, c-format
+msgid "substr: start index %g is past end of string"
+msgstr ""
+
+#: builtin.c:1826
+#, c-format
+msgid ""
+"substr: length %g at start index %g exceeds length of first argument (%lu)"
+msgstr ""
+
+#: builtin.c:1900
+msgid "strftime: format value in PROCINFO[\"strftime\"] has numeric type"
+msgstr ""
+
+#: builtin.c:1923
+msgid "strftime: received non-numeric second argument"
+msgstr ""
+
+#: builtin.c:1927
+msgid "strftime: second argument less than 0 or too big for time_t"
+msgstr ""
+
+#: builtin.c:1934
+msgid "strftime: received non-string first argument"
+msgstr ""
+
+#: builtin.c:1941
+msgid "strftime: received empty format string"
+msgstr ""
+
+#: builtin.c:2007
+msgid "mktime: received non-string argument"
+msgstr ""
+
+#: builtin.c:2024
+msgid "mktime: at least one of the values is out of the default range"
+msgstr ""
+
+#: builtin.c:2059
+msgid "'system' function not allowed in sandbox mode"
+msgstr ""
+
+#: builtin.c:2064
+msgid "system: received non-string argument"
+msgstr ""
+
+#: builtin.c:2184
+#, c-format
+msgid "reference to uninitialized field `$%d'"
+msgstr ""
+
+#: builtin.c:2271
+msgid "tolower: received non-string argument"
+msgstr ""
+
+#: builtin.c:2305
+msgid "toupper: received non-string argument"
+msgstr ""
+
+#: builtin.c:2341 mpfr.c:672
+msgid "atan2: received non-numeric first argument"
+msgstr ""
+
+#: builtin.c:2343 mpfr.c:674
+msgid "atan2: received non-numeric second argument"
+msgstr ""
+
+#: builtin.c:2362
+msgid "sin: received non-numeric argument"
+msgstr ""
+
+#: builtin.c:2378
+msgid "cos: received non-numeric argument"
+msgstr ""
+
+#: builtin.c:2431 mpfr.c:1156
+msgid "srand: received non-numeric argument"
+msgstr ""
+
+#: builtin.c:2462
+msgid "match: third argument is not an array"
+msgstr ""
+
+#: builtin.c:2734
+msgid "gensub: third argument of 0 treated as 1"
+msgstr ""
+
+#: builtin.c:3030
+msgid "lshift: received non-numeric first argument"
+msgstr ""
+
+#: builtin.c:3032
+msgid "lshift: received non-numeric second argument"
+msgstr ""
+
+#: builtin.c:3038
+#, c-format
+msgid "lshift(%f, %f): negative values will give strange results"
+msgstr ""
+
+#: builtin.c:3040
+#, c-format
+msgid "lshift(%f, %f): fractional values will be truncated"
+msgstr ""
+
+#: builtin.c:3042
+#, c-format
+msgid "lshift(%f, %f): too large shift value will give strange results"
+msgstr ""
+
+#: builtin.c:3067
+msgid "rshift: received non-numeric first argument"
+msgstr ""
+
+#: builtin.c:3069
+msgid "rshift: received non-numeric second argument"
+msgstr ""
+
+#: builtin.c:3075
+#, c-format
+msgid "rshift(%f, %f): negative values will give strange results"
+msgstr ""
+
+#: builtin.c:3077
+#, c-format
+msgid "rshift(%f, %f): fractional values will be truncated"
+msgstr ""
+
+#: builtin.c:3079
+#, c-format
+msgid "rshift(%f, %f): too large shift value will give strange results"
+msgstr ""
+
+#: builtin.c:3104 mpfr.c:968
+msgid "and: called with less than two arguments"
+msgstr ""
+
+#: builtin.c:3109
+#, c-format
+msgid "and: argument %d is non-numeric"
+msgstr ""
+
+#: builtin.c:3113
+#, c-format
+msgid "and: argument %d negative value %g will give strange results"
+msgstr ""
+
+#: builtin.c:3136 mpfr.c:1000
+msgid "or: called with less than two arguments"
+msgstr ""
+
+#: builtin.c:3141
+#, c-format
+msgid "or: argument %d is non-numeric"
+msgstr ""
+
+#: builtin.c:3145
+#, c-format
+msgid "or: argument %d negative value %g will give strange results"
+msgstr ""
+
+#: builtin.c:3167 mpfr.c:1031
+msgid "xor: called with less than two arguments"
+msgstr ""
+
+#: builtin.c:3173
+#, c-format
+msgid "xor: argument %d is non-numeric"
+msgstr ""
+
+#: builtin.c:3177
+#, c-format
+msgid "xor: argument %d negative value %g will give strange results"
+msgstr ""
+
+#: builtin.c:3202 mpfr.c:787
+msgid "compl: received non-numeric argument"
+msgstr ""
+
+#: builtin.c:3208
+#, c-format
+msgid "compl(%f): negative value will give strange results"
+msgstr ""
+
+#: builtin.c:3210
+#, c-format
+msgid "compl(%f): fractional value will be truncated"
+msgstr ""
+
+#: builtin.c:3379
+#, c-format
+msgid "dcgettext: `%s' is not a valid locale category"
+msgstr ""
+
+#: command.y:225
+#, c-format
+msgid "Type (g)awk statement(s). End with the command \"end\"\n"
+msgstr ""
+
+#: command.y:289
+#, c-format
+msgid "invalid frame number: %d"
+msgstr ""
+
+#: command.y:295
+#, c-format
+msgid "info: invalid option - \"%s\""
+msgstr ""
+
+#: command.y:321
+#, c-format
+msgid "source \"%s\": already sourced."
+msgstr ""
+
+#: command.y:326
+#, c-format
+msgid "save \"%s\": command not permitted."
+msgstr ""
+
+#: command.y:339
+msgid "Can't use command `commands' for breakpoint/watchpoint commands"
+msgstr ""
+
+#: command.y:341
+msgid "no breakpoint/watchpoint has been set yet"
+msgstr ""
+
+#: command.y:343
+msgid "invalid breakpoint/watchpoint number"
+msgstr ""
+
+#: command.y:348
+#, c-format
+msgid "Type commands for when %s %d is hit, one per line.\n"
+msgstr ""
+
+#: command.y:350
+#, c-format
+msgid "End with the command \"end\"\n"
+msgstr ""
+
+#: command.y:357
+msgid "`end' valid only in command `commands' or `eval'"
+msgstr ""
+
+#: command.y:367
+msgid "`silent' valid only in command `commands'"
+msgstr ""
+
+#: command.y:373
+#, c-format
+msgid "trace: invalid option - \"%s\""
+msgstr ""
+
+#: command.y:387
+msgid "condition: invalid breakpoint/watchpoint number"
+msgstr ""
+
+#: command.y:449
+msgid "argument not a string"
+msgstr ""
+
+#: command.y:459 command.y:464
+#, c-format
+msgid "option: invalid parameter - \"%s\""
+msgstr ""
+
+#: command.y:474
+#, c-format
+msgid "no such function - \"%s\""
+msgstr ""
+
+#: command.y:531
+#, c-format
+msgid "enable: invalid option - \"%s\""
+msgstr ""
+
+#: command.y:597
+#, c-format
+msgid "invalid range specification: %d - %d"
+msgstr ""
+
+#: command.y:659
+msgid "non-numeric value for field number"
+msgstr ""
+
+#: command.y:680 command.y:687
+msgid "non-numeric value found, numeric expected"
+msgstr ""
+
+#: command.y:712 command.y:718
+msgid "non-zero integer value"
+msgstr ""
+
+#: command.y:817
+msgid ""
+"backtrace [N] - print trace of all or N innermost (outermost if N < 0) "
+"frames."
+msgstr ""
+
+#: command.y:819
+msgid ""
+"break [[filename:]N|function] - set breakpoint at the specified location."
+msgstr ""
+
+#: command.y:821
+msgid "clear [[filename:]N|function] - delete breakpoints previously set."
+msgstr ""
+
+#: command.y:823
+msgid ""
+"commands [num] - starts a list of commands to be executed at a "
+"breakpoint(watchpoint) hit."
+msgstr ""
+
+#: command.y:825
+msgid "condition num [expr] - set or clear breakpoint or watchpoint condition."
+msgstr ""
+
+#: command.y:827
+msgid "continue [COUNT] - continue program being debugged."
+msgstr ""
+
+#: command.y:829
+msgid "delete [breakpoints] [range] - delete specified breakpoints."
+msgstr ""
+
+#: command.y:831
+msgid "disable [breakpoints] [range] - disable specified breakpoints."
+msgstr ""
+
+#: command.y:833
+msgid "display [var] - print value of variable each time the program stops."
+msgstr ""
+
+#: command.y:835
+msgid "down [N] - move N frames down the stack."
+msgstr ""
+
+#: command.y:837
+msgid "dump [filename] - dump instructions to file or stdout."
+msgstr ""
+
+#: command.y:839
+msgid "enable [once|del] [breakpoints] [range] - enable specified breakpoints."
+msgstr ""
+
+#: command.y:841
+msgid "end - end a list of commands or awk statements."
+msgstr ""
+
+#: command.y:843
+msgid "eval stmt|[p1, p2, ...] - evaluate awk statement(s)."
+msgstr ""
+
+#: command.y:845
+msgid "finish - execute until selected stack frame returns."
+msgstr ""
+
+#: command.y:847
+msgid "frame [N] - select and print stack frame number N."
+msgstr ""
+
+#: command.y:849
+msgid "help [command] - print list of commands or explanation of command."
+msgstr ""
+
+#: command.y:851
+msgid "ignore N COUNT - set ignore-count of breakpoint number N to COUNT."
+msgstr ""
+
+#: command.y:853
+msgid ""
+"info topic - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch."
+msgstr ""
+
+#: command.y:855
+msgid "list [-|+|[filename:]lineno|function|range] - list specified line(s)."
+msgstr ""
+
+#: command.y:857
+msgid "next [COUNT] - step program, proceeding through subroutine calls."
+msgstr ""
+
+#: command.y:859
+msgid ""
+"nexti [COUNT] - step one instruction, but proceed through subroutine calls."
+msgstr ""
+
+#: command.y:861
+msgid "option [name[=value]] - set or display debugger option(s)."
+msgstr ""
+
+#: command.y:863
+msgid "print var [var] - print value of a variable or array."
+msgstr ""
+
+#: command.y:865
+msgid "printf format, [arg], ... - formatted output."
+msgstr ""
+
+#: command.y:867
+msgid "quit - exit debugger."
+msgstr ""
+
+#: command.y:869
+msgid "return [value] - make selected stack frame return to its caller."
+msgstr ""
+
+#: command.y:871
+msgid "run - start or restart executing program."
+msgstr ""
+
+#: command.y:874
+msgid "save filename - save commands from the session to file."
+msgstr ""
+
+#: command.y:877
+msgid "set var = value - assign value to a scalar variable."
+msgstr ""
+
+#: command.y:879
+msgid ""
+"silent - suspends usual message when stopped at a breakpoint/watchpoint."
+msgstr ""
+
+#: command.y:881
+msgid "source file - execute commands from file."
+msgstr ""
+
+#: command.y:883
+msgid "step [COUNT] - step program until it reaches a different source line."
+msgstr ""
+
+#: command.y:885
+msgid "stepi [COUNT] - step one instruction exactly."
+msgstr ""
+
+#: command.y:887
+msgid "tbreak [[filename:]N|function] - set a temporary breakpoint."
+msgstr ""
+
+#: command.y:889
+msgid "trace on|off - print instruction before executing."
+msgstr ""
+
+#: command.y:891
+msgid "undisplay [N] - remove variable(s) from automatic display list."
+msgstr ""
+
+#: command.y:893
+msgid ""
+"until [[filename:]N|function] - execute until program reaches a different "
+"line or line N within current frame."
+msgstr ""
+
+#: command.y:895
+msgid "unwatch [N] - remove variable(s) from watch list."
+msgstr ""
+
+#: command.y:897
+msgid "up [N] - move N frames up the stack."
+msgstr ""
+
+#: command.y:899
+msgid "watch var - set a watchpoint for a variable."
+msgstr ""
+
+#: command.y:1011 debug.c:401 msg.c:135
+#, c-format
+msgid "error: "
+msgstr ""
+
+#: command.y:1051
+#, c-format
+msgid "can't read command (%s)\n"
+msgstr ""
+
+#: command.y:1065
+#, c-format
+msgid "can't read command (%s)"
+msgstr ""
+
+#: command.y:1116
+msgid "invalid character in command"
+msgstr ""
+
+#: command.y:1152
+#, c-format
+msgid "unknown command - \"%.*s\", try help"
+msgstr ""
+
+#: command.y:1222
+#, c-format
+msgid "%s"
+msgstr ""
+
+#: command.y:1284
+msgid "invalid character"
+msgstr ""
+
+#: command.y:1455
+#, c-format
+msgid "undefined command: %s\n"
+msgstr ""
+
+#: debug.c:252
+msgid "set or show the number of lines to keep in history file."
+msgstr ""
+
+#: debug.c:254
+msgid "set or show the list command window size."
+msgstr ""
+
+#: debug.c:256
+msgid "set or show gawk output file."
+msgstr ""
+
+#: debug.c:258
+msgid "set or show debugger prompt."
+msgstr ""
+
+#: debug.c:260
+msgid "(un)set or show saving of command history (value=on|off)."
+msgstr ""
+
+#: debug.c:262
+msgid "(un)set or show saving of options (value=on|off)."
+msgstr ""
+
+#: debug.c:264
+msgid "(un)set or show instruction tracing (value=on|off)."
+msgstr ""
+
+#: debug.c:345
+msgid "program not running."
+msgstr ""
+
+#: debug.c:448 debug.c:606
+#, c-format
+msgid "can't read source file `%s' (%s)"
+msgstr ""
+
+#: debug.c:453
+#, c-format
+msgid "source file `%s' is empty.\n"
+msgstr ""
+
+#: debug.c:480
+msgid "no current source file."
+msgstr ""
+
+#: debug.c:505
+#, c-format
+msgid "cannot find source file named `%s' (%s)"
+msgstr ""
+
+#: debug.c:529
+#, c-format
+msgid "WARNING: source file `%s' modified since program compilation.\n"
+msgstr ""
+
+#: debug.c:551
+#, c-format
+msgid "line number %d out of range; `%s' has %d lines"
+msgstr ""
+
+#: debug.c:611
+#, c-format
+msgid "unexpected eof while reading file `%s', line %d"
+msgstr ""
+
+#: debug.c:620
+#, c-format
+msgid "source file `%s' modified since start of program execution"
+msgstr ""
+
+#: debug.c:732
+#, c-format
+msgid "Current source file: %s\n"
+msgstr ""
+
+#: debug.c:733
+#, c-format
+msgid "Number of lines: %d\n"
+msgstr ""
+
+#: debug.c:740
+#, c-format
+msgid "Source file (lines): %s (%d)\n"
+msgstr ""
+
+#: debug.c:754
+msgid ""
+"Number Disp Enabled Location\n"
+"\n"
+msgstr ""
+
+#: debug.c:765
+#, c-format
+msgid "\tno of hits = %ld\n"
+msgstr ""
+
+#: debug.c:767
+#, c-format
+msgid "\tignore next %ld hit(s)\n"
+msgstr ""
+
+#: debug.c:769 debug.c:909
+#, c-format
+msgid "\tstop condition: %s\n"
+msgstr ""
+
+#: debug.c:771 debug.c:911
+msgid "\tcommands:\n"
+msgstr ""
+
+#: debug.c:793
+#, c-format
+msgid "Current frame: "
+msgstr ""
+
+#: debug.c:796
+#, c-format
+msgid "Called by frame: "
+msgstr ""
+
+#: debug.c:800
+#, c-format
+msgid "Caller of frame: "
+msgstr ""
+
+#: debug.c:818
+#, c-format
+msgid "None in main().\n"
+msgstr ""
+
+#: debug.c:848
+msgid "No arguments.\n"
+msgstr ""
+
+#: debug.c:849
+msgid "No locals.\n"
+msgstr ""
+
+#: debug.c:857
+msgid ""
+"All defined variables:\n"
+"\n"
+msgstr ""
+
+#: debug.c:867
+msgid ""
+"All defined functions:\n"
+"\n"
+msgstr ""
+
+#: debug.c:886
+msgid ""
+"Auto-display variables:\n"
+"\n"
+msgstr ""
+
+#: debug.c:889
+msgid ""
+"Watch variables:\n"
+"\n"
+msgstr ""
+
+#: debug.c:1029
+#, c-format
+msgid "no symbol `%s' in current context\n"
+msgstr ""
+
+#: debug.c:1041 debug.c:1427
+#, c-format
+msgid "`%s' is not an array\n"
+msgstr ""
+
+#: debug.c:1055
+#, c-format
+msgid "$%ld = uninitialized field\n"
+msgstr ""
+
+#: debug.c:1076
+#, c-format
+msgid "array `%s' is empty\n"
+msgstr ""
+
+#: debug.c:1119 debug.c:1171
+#, c-format
+msgid "[\"%s\"] not in array `%s'\n"
+msgstr ""
+
+#: debug.c:1175
+#, c-format
+msgid "`%s[\"%s\"]' is not an array\n"
+msgstr ""
+
+#: debug.c:1236 debug.c:4964
+#, c-format
+msgid "`%s' is not a scalar variable"
+msgstr ""
+
+#: debug.c:1258 debug.c:4994
+#, c-format
+msgid "attempt to use array `%s[\"%s\"]' in a scalar context"
+msgstr ""
+
+#: debug.c:1280 debug.c:5005
+#, c-format
+msgid "attempt to use scalar `%s[\"%s\"]' as array"
+msgstr ""
+
+#: debug.c:1423
+#, c-format
+msgid "`%s' is a function"
+msgstr ""
+
+#: debug.c:1465
+#, c-format
+msgid "watchpoint %d is unconditional\n"
+msgstr ""
+
+#: debug.c:1499
+#, c-format
+msgid "No display item numbered %ld"
+msgstr ""
+
+#: debug.c:1502
+#, c-format
+msgid "No watch item numbered %ld"
+msgstr ""
+
+#: debug.c:1528
+#, c-format
+msgid "%d: [\"%s\"] not in array `%s'\n"
+msgstr ""
+
+#: debug.c:1767
+msgid "attempt to use scalar value as array"
+msgstr ""
+
+#: debug.c:1856
+#, c-format
+msgid "Watchpoint %d deleted because parameter is out of scope.\n"
+msgstr ""
+
+#: debug.c:1867
+#, c-format
+msgid "Display %d deleted because parameter is out of scope.\n"
+msgstr ""
+
+#: debug.c:1900
+#, c-format
+msgid " in file `%s', line %d\n"
+msgstr ""
+
+#: debug.c:1921
+#, c-format
+msgid " at `%s':%d"
+msgstr ""
+
+#: debug.c:1937 debug.c:2000
+#, c-format
+msgid "#%ld\tin "
+msgstr ""
+
+#: debug.c:1974
+#, c-format
+msgid "More stack frames follow ...\n"
+msgstr ""
+
+#: debug.c:2017
+msgid "invalid frame number"
+msgstr ""
+
+#: debug.c:2200
+#, c-format
+msgid "Note: breakpoint %d (enabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2207
+#, c-format
+msgid "Note: breakpoint %d (enabled), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2214
+#, c-format
+msgid "Note: breakpoint %d (disabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2221
+#, c-format
+msgid "Note: breakpoint %d (disabled), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2238
+#, c-format
+msgid "Breakpoint %d set at file `%s', line %d\n"
+msgstr ""
+
+#: debug.c:2340
+#, c-format
+msgid "Can't set breakpoint in file `%s'\n"
+msgstr ""
+
+#: debug.c:2369 debug.c:2492 debug.c:3350
+#, c-format
+msgid "line number %d in file `%s' out of range"
+msgstr ""
+
+#: debug.c:2373
+#, c-format
+msgid "Can't find rule!!!\n"
+msgstr ""
+
+#: debug.c:2375
+#, c-format
+msgid "Can't set breakpoint at `%s':%d\n"
+msgstr ""
+
+#: debug.c:2387
+#, c-format
+msgid "Can't set breakpoint in function `%s'\n"
+msgstr ""
+
+#: debug.c:2403
+#, c-format
+msgid "breakpoint %d set at file `%s', line %d is unconditional\n"
+msgstr ""
+
+#: debug.c:2508 debug.c:2530
+#, c-format
+msgid "Deleted breakpoint %d"
+msgstr ""
+
+#: debug.c:2514
+#, c-format
+msgid "No breakpoint(s) at entry to function `%s'\n"
+msgstr ""
+
+#: debug.c:2541
+#, c-format
+msgid "No breakpoint at file `%s', line #%d\n"
+msgstr ""
+
+#: debug.c:2596 debug.c:2637 debug.c:2657 debug.c:2700
+msgid "invalid breakpoint number"
+msgstr ""
+
+#: debug.c:2612
+msgid "Delete all breakpoints? (y or n) "
+msgstr ""
+
+#: debug.c:2613 debug.c:2923 debug.c:2976
+msgid "y"
+msgstr ""
+
+#: debug.c:2662
+#, c-format
+msgid "Will ignore next %ld crossing(s) of breakpoint %d.\n"
+msgstr ""
+
+#: debug.c:2666
+#, c-format
+msgid "Will stop next time breakpoint %d is reached.\n"
+msgstr ""
+
+#: debug.c:2783
+#, c-format
+msgid "Can only debug programs provided with the `-f' option.\n"
+msgstr ""
+
+#: debug.c:2908
+#, c-format
+msgid "Failed to restart debugger"
+msgstr ""
+
+#: debug.c:2922
+msgid "Program already running. Restart from beginning (y/n)? "
+msgstr ""
+
+#: debug.c:2926
+#, c-format
+msgid "Program not restarted\n"
+msgstr ""
+
+#: debug.c:2936
+#, c-format
+msgid "error: cannot restart, operation not allowed\n"
+msgstr ""
+
+#: debug.c:2942
+#, c-format
+msgid "error (%s): cannot restart, ignoring rest of the commands\n"
+msgstr ""
+
+#: debug.c:2950
+#, c-format
+msgid "Starting program: \n"
+msgstr ""
+
+#: debug.c:2959
+#, c-format
+msgid "Program exited %s with exit value: %d\n"
+msgstr ""
+
+#: debug.c:2975
+msgid "The program is running. Exit anyway (y/n)? "
+msgstr ""
+
+#: debug.c:3010
+#, c-format
+msgid "Not stopped at any breakpoint; argument ignored.\n"
+msgstr ""
+
+#: debug.c:3015
+#, c-format
+msgid "invalid breakpoint number %d."
+msgstr ""
+
+#: debug.c:3020
+#, c-format
+msgid "Will ignore next %ld crossings of breakpoint %d.\n"
+msgstr ""
+
+#: debug.c:3207
+#, c-format
+msgid "'finish' not meaningful in the outermost frame main()\n"
+msgstr ""
+
+#: debug.c:3212
+#, c-format
+msgid "Run till return from "
+msgstr ""
+
+#: debug.c:3255
+#, c-format
+msgid "'return' not meaningful in the outermost frame main()\n"
+msgstr ""
+
+#: debug.c:3369
+#, c-format
+msgid "Can't find specified location in function `%s'\n"
+msgstr ""
+
+#: debug.c:3377
+#, c-format
+msgid "invalid source line %d in file `%s'"
+msgstr ""
+
+#: debug.c:3392
+#, c-format
+msgid "Can't find specified location %d in file `%s'\n"
+msgstr ""
+
+#: debug.c:3424
+#, c-format
+msgid "element not in array\n"
+msgstr ""
+
+#: debug.c:3424
+#, c-format
+msgid "untyped variable\n"
+msgstr ""
+
+#: debug.c:3466
+#, c-format
+msgid "Stopping in %s ...\n"
+msgstr ""
+
+#: debug.c:3543
+#, c-format
+msgid "'finish' not meaningful with non-local jump '%s'\n"
+msgstr ""
+
+#: debug.c:3550
+#, c-format
+msgid "'until' not meaningful with non-local jump '%s'\n"
+msgstr ""
+
+#: debug.c:4185
+msgid "\t------[Enter] to continue or q [Enter] to quit------"
+msgstr ""
+
+#: debug.c:4186
+msgid "q"
+msgstr ""
+
+#: debug.c:5001
+#, c-format
+msgid "[\"%s\"] not in array `%s'"
+msgstr ""
+
+#: debug.c:5207
+#, c-format
+msgid "sending output to stdout\n"
+msgstr ""
+
+#: debug.c:5247
+msgid "invalid number"
+msgstr ""
+
+#: debug.c:5381
+#, c-format
+msgid "`%s' not allowed in current context; statement ignored"
+msgstr ""
+
+#: debug.c:5389
+msgid "`return' not allowed in current context; statement ignored"
+msgstr ""
+
+#: debug.c:5590
+#, c-format
+msgid "No symbol `%s' in current context"
+msgstr ""
+
+#: dfa.c:1118 dfa.c:1121 dfa.c:1142 dfa.c:1150 dfa.c:1162 dfa.c:1197
+#: dfa.c:1206 dfa.c:1209 dfa.c:1214 dfa.c:1228 dfa.c:1275
+msgid "unbalanced ["
+msgstr ""
+
+#: dfa.c:1174
+msgid "invalid character class"
+msgstr ""
+
+#: dfa.c:1316
+msgid "character class syntax is [[:space:]], not [:space:]"
+msgstr ""
+
+#: dfa.c:1366
+msgid "unfinished \\ escape"
+msgstr ""
+
+#: dfa.c:1513 regcomp.c:161
+msgid "Invalid content of \\{\\}"
+msgstr ""
+
+#: dfa.c:1516 regcomp.c:176
+msgid "Regular expression too big"
+msgstr ""
+
+#: dfa.c:1936
+msgid "unbalanced ("
+msgstr ""
+
+#: dfa.c:2062
+msgid "no syntax specified"
+msgstr ""
+
+#: dfa.c:2070
+msgid "unbalanced )"
+msgstr ""
+
+#: eval.c:394
+#, c-format
+msgid "unknown nodetype %d"
+msgstr ""
+
+#: eval.c:405 eval.c:419
+#, c-format
+msgid "unknown opcode %d"
+msgstr ""
+
+#: eval.c:416
+#, c-format
+msgid "opcode %s not an operator or keyword"
+msgstr ""
+
+#: eval.c:472
+msgid "buffer overflow in genflags2str"
+msgstr ""
+
+#: eval.c:675
+#, c-format
+msgid ""
+"\n"
+"\t# Function Call Stack:\n"
+"\n"
+msgstr ""
+
+#: eval.c:704
+msgid "`IGNORECASE' is a gawk extension"
+msgstr ""
+
+#: eval.c:736
+msgid "`BINMODE' is a gawk extension"
+msgstr ""
+
+#: eval.c:794
+#, c-format
+msgid "BINMODE value `%s' is invalid, treated as 3"
+msgstr ""
+
+#: eval.c:885
+#, c-format
+msgid "bad `%sFMT' specification `%s'"
+msgstr ""
+
+#: eval.c:969
+msgid "turning off `--lint' due to assignment to `LINT'"
+msgstr ""
+
+#: eval.c:1147
+#, c-format
+msgid "reference to uninitialized argument `%s'"
+msgstr ""
+
+#: eval.c:1148
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr ""
+
+#: eval.c:1166
+msgid "attempt to field reference from non-numeric value"
+msgstr ""
+
+#: eval.c:1168
+msgid "attempt to field reference from null string"
+msgstr ""
+
+#: eval.c:1176
+#, c-format
+msgid "attempt to access field %ld"
+msgstr ""
+
+#: eval.c:1185
+#, c-format
+msgid "reference to uninitialized field `$%ld'"
+msgstr ""
+
+#: eval.c:1272
+#, c-format
+msgid "function `%s' called with more arguments than declared"
+msgstr ""
+
+#: eval.c:1473
+#, c-format
+msgid "unwind_stack: unexpected type `%s'"
+msgstr ""
+
+#: eval.c:1569
+msgid "division by zero attempted in `/='"
+msgstr ""
+
+#: eval.c:1576
+#, c-format
+msgid "division by zero attempted in `%%='"
+msgstr ""
+
+#: ext.c:89 ext.c:171
+msgid "extensions are not allowed in sandbox mode"
+msgstr ""
+
+#: ext.c:92
+msgid "-l / @load are gawk extensions"
+msgstr ""
+
+#: ext.c:95
+msgid "load_ext: received NULL lib_name"
+msgstr ""
+
+#: ext.c:98
+#, c-format
+msgid "load_ext: cannot open library `%s' (%s)\n"
+msgstr ""
+
+#: ext.c:104
+#, c-format
+msgid ""
+"load_ext: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"
+msgstr ""
+
+#: ext.c:110
+#, c-format
+msgid "load_ext: library `%s': cannot call function `%s' (%s)\n"
+msgstr ""
+
+#: ext.c:114
+#, c-format
+msgid "load_ext: library `%s' initialization routine `%s' failed\n"
+msgstr ""
+
+#: ext.c:174
+msgid "`extension' is a gawk extension"
+msgstr ""
+
+#: ext.c:177
+msgid "extension: received NULL lib_name"
+msgstr ""
+
+#: ext.c:180
+#, c-format
+msgid "extension: cannot open library `%s' (%s)"
+msgstr ""
+
+#: ext.c:186
+#, c-format
+msgid ""
+"extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)"
+msgstr ""
+
+#: ext.c:190
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)"
+msgstr ""
+
+#: ext.c:221
+msgid "make_builtin: missing function name"
+msgstr ""
+
+#: ext.c:236
+#, c-format
+msgid "make_builtin: can't redefine function `%s'"
+msgstr ""
+
+#: ext.c:240
+#, c-format
+msgid "make_builtin: function `%s' already defined"
+msgstr ""
+
+#: ext.c:244
+#, c-format
+msgid "make_builtin: function name `%s' previously defined"
+msgstr ""
+
+#: ext.c:246
+#, c-format
+msgid "make_builtin: can't use gawk built-in `%s' as function name"
+msgstr ""
+
+#: ext.c:249 ext.c:304
+#, c-format
+msgid "make_builtin: negative argument count for function `%s'"
+msgstr ""
+
+#: ext.c:276
+msgid "extension: missing function name"
+msgstr ""
+
+#: ext.c:279 ext.c:283
+#, c-format
+msgid "extension: illegal character `%c' in function name `%s'"
+msgstr ""
+
+#: ext.c:291
+#, c-format
+msgid "extension: can't redefine function `%s'"
+msgstr ""
+
+#: ext.c:295
+#, c-format
+msgid "extension: function `%s' already defined"
+msgstr ""
+
+#: ext.c:299
+#, c-format
+msgid "extension: function name `%s' previously defined"
+msgstr ""
+
+#: ext.c:301
+#, c-format
+msgid "extension: can't use gawk built-in `%s' as function name"
+msgstr ""
+
+#: ext.c:375
+#, c-format
+msgid "function `%s' defined to take no more than %d argument(s)"
+msgstr ""
+
+#: ext.c:378
+#, c-format
+msgid "function `%s': missing argument #%d"
+msgstr ""
+
+#: ext.c:395
+#, c-format
+msgid "function `%s': argument #%d: attempt to use scalar as an array"
+msgstr ""
+
+#: ext.c:399
+#, c-format
+msgid "function `%s': argument #%d: attempt to use array as a scalar"
+msgstr ""
+
+#: ext.c:413
+msgid "dynamic loading of library not supported"
+msgstr ""
+
+#: extension/filefuncs.c:159
+msgid "chdir: called with incorrect number of arguments, expecting 1"
+msgstr ""
+
+#: extension/filefuncs.c:439
+#, c-format
+msgid "stat: unable to read symbolic link `%s'"
+msgstr ""
+
+#: extension/filefuncs.c:472
+msgid "stat: called with wrong number of arguments"
+msgstr ""
+
+#: extension/filefuncs.c:479
+msgid "stat: bad parameters"
+msgstr ""
+
+#: extension/filefuncs.c:533
+#, c-format
+msgid "fts init: could not create variable %s"
+msgstr ""
+
+#: extension/filefuncs.c:554
+msgid "fts is not supported on this system"
+msgstr ""
+
+#: extension/filefuncs.c:573
+msgid "fill_stat_element: could not create array"
+msgstr ""
+
+#: extension/filefuncs.c:582
+msgid "fill_stat_element: could not set element"
+msgstr ""
+
+#: extension/filefuncs.c:597
+msgid "fill_path_element: could not set element"
+msgstr ""
+
+#: extension/filefuncs.c:613
+msgid "fill_error_element: could not set element"
+msgstr ""
+
+#: extension/filefuncs.c:660 extension/filefuncs.c:707
+msgid "fts-process: could not create array"
+msgstr ""
+
+#: extension/filefuncs.c:670 extension/filefuncs.c:717
+#: extension/filefuncs.c:735
+msgid "fts-process: could not set element"
+msgstr ""
+
+#: extension/filefuncs.c:784
+msgid "fts: called with incorrect number of arguments, expecting 3"
+msgstr ""
+
+#: extension/filefuncs.c:787
+msgid "fts: bad first parameter"
+msgstr ""
+
+#: extension/filefuncs.c:793
+msgid "fts: bad second parameter"
+msgstr ""
+
+#: extension/filefuncs.c:799
+msgid "fts: bad third parameter"
+msgstr ""
+
+#: extension/filefuncs.c:806
+msgid "fts: could not flatten array\n"
+msgstr ""
+
+#: extension/filefuncs.c:824
+msgid "fts: ignoring sneaky FTS_NOSTAT flag. nyah, nyah, nyah."
+msgstr ""
+
+#: extension/filefuncs.c:841
+msgid "fts: clear_array() failed\n"
+msgstr ""
+
+#: extension/fnmatch.c:112
+msgid "fnmatch: called with less than three arguments"
+msgstr ""
+
+#: extension/fnmatch.c:115
+msgid "fnmatch: called with more than three arguments"
+msgstr ""
+
+#: extension/fnmatch.c:118
+msgid "fnmatch: could not get first argument"
+msgstr ""
+
+#: extension/fnmatch.c:123
+msgid "fnmatch: could not get second argument"
+msgstr ""
+
+#: extension/fnmatch.c:128
+msgid "fnmatch: could not get third argument"
+msgstr ""
+
+#: extension/fnmatch.c:141
+msgid "fnmatch is not implemented on this system\n"
+msgstr ""
+
+#: extension/fnmatch.c:173
+msgid "fnmatch init: could not add FNM_NOMATCH variable"
+msgstr ""
+
+#: extension/fnmatch.c:183
+#, c-format
+msgid "fnmatch init: could not set array element %s"
+msgstr ""
+
+#: extension/fnmatch.c:193
+msgid "fnmatch init: could not install FNM array"
+msgstr ""
+
+#: extension/fork.c:81
+msgid "fork: called with too many arguments"
+msgstr ""
+
+#: extension/fork.c:94
+msgid "fork: PROCINFO is not an array!"
+msgstr ""
+
+#: extension/fork.c:118
+msgid "waitpid: called with too many arguments"
+msgstr ""
+
+#: extension/fork.c:126
+msgid "wait: called with no arguments"
+msgstr ""
+
+#: extension/fork.c:143
+msgid "wait: called with too many arguments"
+msgstr ""
+
+#: extension/inplace.c:130
+msgid "inplace_begin: in-place editing already active"
+msgstr ""
+
+#: extension/inplace.c:133 extension/inplace.c:207
+#, c-format
+msgid "inplace_begin: expects 2 arguments but called with %d"
+msgstr ""
+
+#: extension/inplace.c:136
+msgid "inplace_begin: cannot retrieve 1st argument as a string filename"
+msgstr ""
+
+#: extension/inplace.c:144
+#, c-format
+msgid "inplace_begin: disabling in-place editing for invalid FILENAME `%s'"
+msgstr ""
+
+#: extension/inplace.c:151
+#, c-format
+msgid "inplace_begin: Cannot stat `%s' (%s)"
+msgstr ""
+
+#: extension/inplace.c:158
+#, c-format
+msgid "inplace_begin: `%s' is not a regular file"
+msgstr ""
+
+#: extension/inplace.c:169
+#, c-format
+msgid "inplace_begin: mkstemp(`%s') failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:178
+#, c-format
+msgid "inplace_begin: chmod failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:185
+#, c-format
+msgid "inplace_begin: dup(stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:188
+#, c-format
+msgid "inplace_begin: dup2(%d, stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:191
+#, c-format
+msgid "inplace_begin: close(%d) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:210
+msgid "inplace_end: cannot retrieve 1st argument as a string filename"
+msgstr ""
+
+#: extension/inplace.c:217
+msgid "inplace_end: in-place editing not active"
+msgstr ""
+
+#: extension/inplace.c:223
+#, c-format
+msgid "inplace_end: dup2(%d, stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:226
+#, c-format
+msgid "inplace_end: close(%d) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:230
+#, c-format
+msgid "inplace_end: fsetpos(stdout) failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:243
+#, c-format
+msgid "inplace_end: link(`%s', `%s') failed (%s)"
+msgstr ""
+
+#: extension/inplace.c:253
+#, c-format
+msgid "inplace_end: rename(`%s', `%s') failed (%s)"
+msgstr ""
+
+#: extension/ordchr.c:69
+msgid "ord: called with too many arguments"
+msgstr ""
+
+#: extension/ordchr.c:75
+msgid "ord: called with no arguments"
+msgstr ""
+
+#: extension/ordchr.c:77
+msgid "ord: called with inappropriate argument(s)"
+msgstr ""
+
+#: extension/ordchr.c:99
+msgid "chr: called with too many arguments"
+msgstr ""
+
+#: extension/ordchr.c:109
+msgid "chr: called with no arguments"
+msgstr ""
+
+#: extension/ordchr.c:111
+msgid "chr: called with inappropriate argument(s)"
+msgstr ""
+
+#: extension/readdir.c:281
+#, c-format
+msgid "dir_take_control_of: opendir/fdopendir failed: %s"
+msgstr ""
+
+#: extension/readfile.c:113
+msgid "readfile: called with too many arguments"
+msgstr ""
+
+#: extension/readfile.c:137
+msgid "readfile: called with no arguments"
+msgstr ""
+
+#: extension/rwarray.c:124
+msgid "writea: called with too many arguments"
+msgstr ""
+
+#: extension/rwarray.c:131
+#, c-format
+msgid "do_writea: argument 0 is not a string\n"
+msgstr ""
+
+#: extension/rwarray.c:137
+#, c-format
+msgid "do_writea: argument 1 is not an array\n"
+msgstr ""
+
+#: extension/rwarray.c:184
+#, c-format
+msgid "write_array: could not flatten array\n"
+msgstr ""
+
+#: extension/rwarray.c:198
+#, c-format
+msgid "write_array: could not release flattened array\n"
+msgstr ""
+
+#: extension/rwarray.c:280
+msgid "reada: called with too many arguments"
+msgstr ""
+
+#: extension/rwarray.c:287
+#, c-format
+msgid "do_reada: argument 0 is not a string\n"
+msgstr ""
+
+#: extension/rwarray.c:293
+#, c-format
+msgid "do_reada: argument 1 is not an array\n"
+msgstr ""
+
+#: extension/rwarray.c:337
+#, c-format
+msgid "do_reada: clear_array failed\n"
+msgstr ""
+
+#: extension/rwarray.c:374
+#, c-format
+msgid "read_array: set_array_element failed\n"
+msgstr ""
+
+#: extension/time.c:113
+msgid "gettimeofday: ignoring arguments"
+msgstr ""
+
+#: extension/time.c:144
+msgid "gettimeofday: not supported on this platform"
+msgstr ""
+
+#: extension/time.c:165
+msgid "sleep: called with too many arguments"
+msgstr ""
+
+#: extension/time.c:168
+msgid "sleep: missing required numeric argument"
+msgstr ""
+
+#: extension/time.c:174
+msgid "sleep: argument is negative"
+msgstr ""
+
+#: extension/time.c:208
+msgid "sleep: not supported on this platform"
+msgstr ""
+
+#: field.c:345
+msgid "NF set to negative value"
+msgstr ""
+
+#: field.c:971 field.c:978 field.c:982
+msgid "split: fourth argument is a gawk extension"
+msgstr ""
+
+#: field.c:975
+msgid "split: fourth argument is not an array"
+msgstr ""
+
+#: field.c:989
+msgid "split: second argument is not an array"
+msgstr ""
+
+#: field.c:993
+msgid "split: cannot use the same array for second and fourth args"
+msgstr ""
+
+#: field.c:998
+msgid "split: cannot use a subarray of second arg for fourth arg"
+msgstr ""
+
+#: field.c:1001
+msgid "split: cannot use a subarray of fourth arg for second arg"
+msgstr ""
+
+#: field.c:1032
+msgid "split: null string for third arg is a gawk extension"
+msgstr ""
+
+#: field.c:1072
+msgid "patsplit: fourth argument is not an array"
+msgstr ""
+
+#: field.c:1077
+msgid "patsplit: second argument is not an array"
+msgstr ""
+
+#: field.c:1083
+msgid "patsplit: third argument must be non-null"
+msgstr ""
+
+#: field.c:1087
+msgid "patsplit: cannot use the same array for second and fourth args"
+msgstr ""
+
+#: field.c:1092
+msgid "patsplit: cannot use a subarray of second arg for fourth arg"
+msgstr ""
+
+#: field.c:1095
+msgid "patsplit: cannot use a subarray of fourth arg for second arg"
+msgstr ""
+
+#: field.c:1133
+msgid "`FIELDWIDTHS' is a gawk extension"
+msgstr ""
+
+#: field.c:1197
+#, c-format
+msgid "invalid FIELDWIDTHS value, near `%s'"
+msgstr ""
+
+#: field.c:1270
+msgid "null string for `FS' is a gawk extension"
+msgstr ""
+
+#: field.c:1274
+msgid "old awk does not support regexps as value of `FS'"
+msgstr ""
+
+#: field.c:1393
+msgid "`FPAT' is a gawk extension"
+msgstr ""
+
+#: gawkapi.c:146
+msgid "awk_value_to_node: received null retval"
+msgstr ""
+
+#: gawkapi.c:384
+msgid "node_to_awk_value: received null node"
+msgstr ""
+
+#: gawkapi.c:387
+msgid "node_to_awk_value: received null val"
+msgstr ""
+
+#: gawkapi.c:807
+msgid "remove_element: received null array"
+msgstr ""
+
+#: gawkapi.c:810
+msgid "remove_element: received null subscript"
+msgstr ""
+
+#: gawkapi.c:947
+#, c-format
+msgid "api_flatten_array: could not convert index %d\n"
+msgstr ""
+
+#: gawkapi.c:952
+#, c-format
+msgid "api_flatten_array: could not convert value %d\n"
+msgstr ""
+
+#: getopt.c:604 getopt.c:633
+#, c-format
+msgid "%s: option '%s' is ambiguous; possibilities:"
+msgstr ""
+
+#: getopt.c:679 getopt.c:683
+#, c-format
+msgid "%s: option '--%s' doesn't allow an argument\n"
+msgstr ""
+
+#: getopt.c:692 getopt.c:697
+#, c-format
+msgid "%s: option '%c%s' doesn't allow an argument\n"
+msgstr ""
+
+#: getopt.c:740 getopt.c:759
+#, c-format
+msgid "%s: option '--%s' requires an argument\n"
+msgstr ""
+
+#: getopt.c:797 getopt.c:800
+#, c-format
+msgid "%s: unrecognized option '--%s'\n"
+msgstr ""
+
+#: getopt.c:808 getopt.c:811
+#, c-format
+msgid "%s: unrecognized option '%c%s'\n"
+msgstr ""
+
+#: getopt.c:860 getopt.c:863
+#, c-format
+msgid "%s: invalid option -- '%c'\n"
+msgstr ""
+
+#: getopt.c:916 getopt.c:933 getopt.c:1143 getopt.c:1161
+#, c-format
+msgid "%s: option requires an argument -- '%c'\n"
+msgstr ""
+
+#: getopt.c:989 getopt.c:1005
+#, c-format
+msgid "%s: option '-W %s' is ambiguous\n"
+msgstr ""
+
+#: getopt.c:1029 getopt.c:1047
+#, c-format
+msgid "%s: option '-W %s' doesn't allow an argument\n"
+msgstr ""
+
+#: getopt.c:1068 getopt.c:1086
+#, c-format
+msgid "%s: option '-W %s' requires an argument\n"
+msgstr ""
+
+#: io.c:392
+#, c-format
+msgid "command line argument `%s' is a directory: skipped"
+msgstr ""
+
+#: io.c:395 io.c:513
+#, c-format
+msgid "cannot open file `%s' for reading (%s)"
+msgstr ""
+
+#: io.c:640
+#, c-format
+msgid "close of fd %d (`%s') failed (%s)"
+msgstr ""
+
+#: io.c:716
+msgid "redirection not allowed in sandbox mode"
+msgstr ""
+
+#: io.c:750
+#, c-format
+msgid "expression in `%s' redirection only has numeric value"
+msgstr ""
+
+#: io.c:756
+#, c-format
+msgid "expression for `%s' redirection has null string value"
+msgstr ""
+
+#: io.c:761
+#, c-format
+msgid "filename `%s' for `%s' redirection may be result of logical expression"
+msgstr ""
+
+#: io.c:809
+#, c-format
+msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
+msgstr ""
+
+#: io.c:863
+#, c-format
+msgid "can't open pipe `%s' for output (%s)"
+msgstr ""
+
+#: io.c:873
+#, c-format
+msgid "can't open pipe `%s' for input (%s)"
+msgstr ""
+
+#: io.c:904
+#, c-format
+msgid "can't open two way pipe `%s' for input/output (%s)"
+msgstr ""
+
+#: io.c:986
+#, c-format
+msgid "can't redirect from `%s' (%s)"
+msgstr ""
+
+#: io.c:989
+#, c-format
+msgid "can't redirect to `%s' (%s)"
+msgstr ""
+
+#: io.c:1040
+msgid ""
+"reached system limit for open files: starting to multiplex file descriptors"
+msgstr ""
+
+#: io.c:1056
+#, c-format
+msgid "close of `%s' failed (%s)."
+msgstr ""
+
+#: io.c:1064
+msgid "too many pipes or input files open"
+msgstr ""
+
+#: io.c:1086
+msgid "close: second argument must be `to' or `from'"
+msgstr ""
+
+#: io.c:1103
+#, c-format
+msgid "close: `%.*s' is not an open file, pipe or co-process"
+msgstr ""
+
+#: io.c:1108
+msgid "close of redirection that was never opened"
+msgstr ""
+
+#: io.c:1205
+#, c-format
+msgid "close: redirection `%s' not opened with `|&', second argument ignored"
+msgstr ""
+
+#: io.c:1222
+#, c-format
+msgid "failure status (%d) on pipe close of `%s' (%s)"
+msgstr ""
+
+#: io.c:1225
+#, c-format
+msgid "failure status (%d) on file close of `%s' (%s)"
+msgstr ""
+
+#: io.c:1245
+#, c-format
+msgid "no explicit close of socket `%s' provided"
+msgstr ""
+
+#: io.c:1248
+#, c-format
+msgid "no explicit close of co-process `%s' provided"
+msgstr ""
+
+#: io.c:1251
+#, c-format
+msgid "no explicit close of pipe `%s' provided"
+msgstr ""
+
+#: io.c:1254
+#, c-format
+msgid "no explicit close of file `%s' provided"
+msgstr ""
+
+#: io.c:1284 io.c:1342 main.c:864 main.c:906
+#, c-format
+msgid "error writing standard output (%s)"
+msgstr ""
+
+#: io.c:1289 io.c:1348 main.c:866
+#, c-format
+msgid "error writing standard error (%s)"
+msgstr ""
+
+#: io.c:1297
+#, c-format
+msgid "pipe flush of `%s' failed (%s)."
+msgstr ""
+
+#: io.c:1300
+#, c-format
+msgid "co-process flush of pipe to `%s' failed (%s)."
+msgstr ""
+
+#: io.c:1303
+#, c-format
+msgid "file flush of `%s' failed (%s)."
+msgstr ""
+
+#: io.c:1420
+#, c-format
+msgid "local port %s invalid in `/inet'"
+msgstr ""
+
+#: io.c:1438
+#, c-format
+msgid "remote host and port information (%s, %s) invalid"
+msgstr ""
+
+#: io.c:1590
+#, c-format
+msgid "no (known) protocol supplied in special filename `%s'"
+msgstr ""
+
+#: io.c:1604
+#, c-format
+msgid "special file name `%s' is incomplete"
+msgstr ""
+
+#: io.c:1621
+msgid "must supply a remote hostname to `/inet'"
+msgstr ""
+
+#: io.c:1639
+msgid "must supply a remote port to `/inet'"
+msgstr ""
+
+#: io.c:1685
+msgid "TCP/IP communications are not supported"
+msgstr ""
+
+#: io.c:1867
+#, c-format
+msgid "could not open `%s', mode `%s'"
+msgstr ""
+
+#: io.c:1917
+#, c-format
+msgid "close of master pty failed (%s)"
+msgstr ""
+
+#: io.c:1919 io.c:2105 io.c:2305
+#, c-format
+msgid "close of stdout in child failed (%s)"
+msgstr ""
+
+#: io.c:1922
+#, c-format
+msgid "moving slave pty to stdout in child failed (dup: %s)"
+msgstr ""
+
+#: io.c:1924 io.c:2110
+#, c-format
+msgid "close of stdin in child failed (%s)"
+msgstr ""
+
+#: io.c:1927
+#, c-format
+msgid "moving slave pty to stdin in child failed (dup: %s)"
+msgstr ""
+
+#: io.c:1929 io.c:1951
+#, c-format
+msgid "close of slave pty failed (%s)"
+msgstr ""
+
+#: io.c:2040 io.c:2108 io.c:2276 io.c:2308
+#, c-format
+msgid "moving pipe to stdout in child failed (dup: %s)"
+msgstr ""
+
+#: io.c:2047 io.c:2113
+#, c-format
+msgid "moving pipe to stdin in child failed (dup: %s)"
+msgstr ""
+
+#: io.c:2073 io.c:2298
+msgid "restoring stdout in parent process failed\n"
+msgstr ""
+
+#: io.c:2081
+msgid "restoring stdin in parent process failed\n"
+msgstr ""
+
+#: io.c:2116 io.c:2310 io.c:2324
+#, c-format
+msgid "close of pipe failed (%s)"
+msgstr ""
+
+#: io.c:2174
+msgid "`|&' not supported"
+msgstr ""
+
+#: io.c:2261
+#, c-format
+msgid "cannot open pipe `%s' (%s)"
+msgstr ""
+
+#: io.c:2318
+#, c-format
+msgid "cannot create child process for `%s' (fork: %s)"
+msgstr ""
+
+#: io.c:2790
+msgid "register_input_parser: received NULL pointer"
+msgstr ""
+
+#: io.c:2818
+#, c-format
+msgid "input parser `%s' conflicts with previously installed input parser `%s'"
+msgstr ""
+
+#: io.c:2825
+#, c-format
+msgid "input parser `%s' failed to open `%s'"
+msgstr ""
+
+#: io.c:2845
+msgid "register_output_wrapper: received NULL pointer"
+msgstr ""
+
+#: io.c:2873
+#, c-format
+msgid ""
+"output wrapper `%s' conflicts with previously installed output wrapper `%s'"
+msgstr ""
+
+#: io.c:2880
+#, c-format
+msgid "output wrapper `%s' failed to open `%s'"
+msgstr ""
+
+#: io.c:2901
+msgid "register_output_processor: received NULL pointer"
+msgstr ""
+
+#: io.c:2930
+#, c-format
+msgid ""
+"two-way processor `%s' conflicts with previously installed two-way processor "
+"`%s'"
+msgstr ""
+
+#: io.c:2939
+#, c-format
+msgid "two way processor `%s' failed to open `%s'"
+msgstr ""
+
+#: io.c:3064
+#, c-format
+msgid "data file `%s' is empty"
+msgstr ""
+
+#: io.c:3106 io.c:3114
+msgid "could not allocate more input memory"
+msgstr ""
+
+#: io.c:3682
+msgid "multicharacter value of `RS' is a gawk extension"
+msgstr ""
+
+#: io.c:3771
+msgid "IPv6 communication is not supported"
+msgstr ""
+
+#: main.c:405
+msgid "empty argument to `-e/--source' ignored"
+msgstr ""
+
+#: main.c:495
+#, c-format
+msgid "%s: option `-W %s' unrecognized, ignored\n"
+msgstr ""
+
+#: main.c:541
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr ""
+
+#: main.c:562
+msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
+msgstr ""
+
+#: main.c:568
+msgid "`--posix' overrides `--traditional'"
+msgstr ""
+
+#: main.c:579
+msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
+msgstr ""
+
+#: main.c:583
+#, c-format
+msgid "running %s setuid root may be a security problem"
+msgstr ""
+
+#: main.c:588
+msgid "`--posix' overrides `--characters-as-bytes'"
+msgstr ""
+
+#: main.c:647
+#, c-format
+msgid "can't set binary mode on stdin (%s)"
+msgstr ""
+
+#: main.c:650
+#, c-format
+msgid "can't set binary mode on stdout (%s)"
+msgstr ""
+
+#: main.c:652
+#, c-format
+msgid "can't set binary mode on stderr (%s)"
+msgstr ""
+
+#: main.c:710
+msgid "no program text at all!"
+msgstr ""
+
+#: main.c:799
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
+msgstr ""
+
+#: main.c:801
+#, c-format
+msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
+msgstr ""
+
+#: main.c:806
+msgid "POSIX options:\t\tGNU long options: (standard)\n"
+msgstr ""
+
+#: main.c:807
+msgid "\t-f progfile\t\t--file=progfile\n"
+msgstr ""
+
+#: main.c:808
+msgid "\t-F fs\t\t\t--field-separator=fs\n"
+msgstr ""
+
+#: main.c:809
+msgid "\t-v var=val\t\t--assign=var=val\n"
+msgstr ""
+
+#: main.c:810
+msgid "Short options:\t\tGNU long options: (extensions)\n"
+msgstr ""
+
+#: main.c:811
+msgid "\t-b\t\t\t--characters-as-bytes\n"
+msgstr ""
+
+#: main.c:812
+msgid "\t-c\t\t\t--traditional\n"
+msgstr ""
+
+#: main.c:813
+msgid "\t-C\t\t\t--copyright\n"
+msgstr ""
+
+#: main.c:814
+msgid "\t-d[file]\t\t--dump-variables[=file]\n"
+msgstr ""
+
+#: main.c:815
+msgid "\t-D[file]\t\t--debug[=file]\n"
+msgstr ""
+
+#: main.c:816
+msgid "\t-e 'program-text'\t--source='program-text'\n"
+msgstr ""
+
+#: main.c:817
+msgid "\t-E file\t\t\t--exec=file\n"
+msgstr ""
+
+#: main.c:818
+msgid "\t-g\t\t\t--gen-pot\n"
+msgstr ""
+
+#: main.c:819
+msgid "\t-h\t\t\t--help\n"
+msgstr ""
+
+#: main.c:820
+msgid "\t-i includefile\t\t--include=includefile\n"
+msgstr ""
+
+#: main.c:821
+msgid "\t-l library\t\t--load=library\n"
+msgstr ""
+
+#: main.c:822
+msgid "\t-L [fatal]\t\t--lint[=fatal]\n"
+msgstr ""
+
+#: main.c:823
+msgid "\t-n\t\t\t--non-decimal-data\n"
+msgstr ""
+
+#: main.c:824
+msgid "\t-M\t\t\t--bignum\n"
+msgstr ""
+
+#: main.c:825
+msgid "\t-N\t\t\t--use-lc-numeric\n"
+msgstr ""
+
+#: main.c:826
+msgid "\t-o[file]\t\t--pretty-print[=file]\n"
+msgstr ""
+
+#: main.c:827
+msgid "\t-O\t\t\t--optimize\n"
+msgstr ""
+
+#: main.c:828
+msgid "\t-p[file]\t\t--profile[=file]\n"
+msgstr ""
+
+#: main.c:829
+msgid "\t-P\t\t\t--posix\n"
+msgstr ""
+
+#: main.c:830
+msgid "\t-r\t\t\t--re-interval\n"
+msgstr ""
+
+#: main.c:831
+msgid "\t-S\t\t\t--sandbox\n"
+msgstr ""
+
+#: main.c:832
+msgid "\t-t\t\t\t--lint-old\n"
+msgstr ""
+
+#: main.c:833
+msgid "\t-V\t\t\t--version\n"
+msgstr ""
+
+#: main.c:835
+msgid "\t-W nostalgia\t\t--nostalgia\n"
+msgstr ""
+
+#: main.c:838
+msgid "\t-Y\t\t--parsedebug\n"
+msgstr ""
+
+#. TRANSLATORS: --help output 5 (end)
+#. TRANSLATORS: the placeholder indicates the bug-reporting address
+#. for this application. Please add _another line_ with the
+#. address for translation bugs.
+#. no-wrap
+#: main.c:847
+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:851
+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:855
+msgid ""
+"Examples:\n"
+"\tgawk '{ sum += $1 }; END { print sum }' file\n"
+"\tgawk -F: '{ print $1 }' /etc/passwd\n"
+msgstr ""
+
+#: main.c:880
+#, 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 3 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+msgstr ""
+
+#: main.c:888
+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:894
+msgid ""
+"You should have received a copy of the GNU General Public License\n"
+"along with this program. If not, see http://www.gnu.org/licenses/.\n"
+msgstr ""
+
+#: main.c:931
+msgid "-Ft does not set FS to tab in POSIX awk"
+msgstr ""
+
+#: main.c:1208
+#, c-format
+msgid "unknown value for field spec: %d\n"
+msgstr ""
+
+#: main.c:1306
+#, c-format
+msgid ""
+"%s: `%s' argument to `-v' not in `var=value' form\n"
+"\n"
+msgstr ""
+
+#: main.c:1332
+#, c-format
+msgid "`%s' is not a legal variable name"
+msgstr ""
+
+#: main.c:1335
+#, c-format
+msgid "`%s' is not a variable name, looking for file `%s=%s'"
+msgstr ""
+
+#: main.c:1339
+#, c-format
+msgid "cannot use gawk builtin `%s' as variable name"
+msgstr ""
+
+#: main.c:1344
+#, c-format
+msgid "cannot use function `%s' as variable name"
+msgstr ""
+
+#: main.c:1397
+msgid "floating point exception"
+msgstr ""
+
+#: main.c:1404
+msgid "fatal error: internal error"
+msgstr ""
+
+#: main.c:1419
+msgid "fatal error: internal error: segfault"
+msgstr ""
+
+#: main.c:1431
+msgid "fatal error: internal error: stack overflow"
+msgstr ""
+
+#: main.c:1490
+#, c-format
+msgid "no pre-opened fd %d"
+msgstr ""
+
+#: main.c:1497
+#, c-format
+msgid "could not pre-open /dev/null for fd %d"
+msgstr ""
+
+#: mpfr.c:550
+#, c-format
+msgid "PREC value `%.*s' is invalid"
+msgstr ""
+
+#: mpfr.c:608
+#, c-format
+msgid "RNDMODE value `%.*s' is invalid"
+msgstr ""
+
+#: mpfr.c:698
+#, c-format
+msgid "%s: received non-numeric argument"
+msgstr ""
+
+#: mpfr.c:800
+msgid "compl(%Rg): negative value will give strange results"
+msgstr ""
+
+#: mpfr.c:804
+msgid "comp(%Rg): fractional value will be truncated"
+msgstr ""
+
+#: mpfr.c:816
+#, c-format
+msgid "cmpl(%Zd): negative values will give strange results"
+msgstr ""
+
+#: mpfr.c:835
+#, c-format
+msgid "%s: received non-numeric argument #%d"
+msgstr ""
+
+#: mpfr.c:845
+msgid "%s: argument #%d has invalid value %Rg, using 0"
+msgstr ""
+
+#: mpfr.c:857
+msgid "%s: argument #%d negative value %Rg will give strange results"
+msgstr ""
+
+#: mpfr.c:863
+msgid "%s: argument #%d fractional value %Rg will be truncated"
+msgstr ""
+
+#: mpfr.c:878
+#, c-format
+msgid "%s: argument #%d negative value %Zd will give strange results"
+msgstr ""
+
+#: msg.c:68
+#, c-format
+msgid "cmd. line:"
+msgstr ""
+
+#: node.c:421
+msgid "backslash at end of string"
+msgstr ""
+
+#: node.c:500
+#, c-format
+msgid "old awk does not support the `\\%c' escape sequence"
+msgstr ""
+
+#: node.c:551
+msgid "POSIX does not allow `\\x' escapes"
+msgstr ""
+
+#: node.c:557
+msgid "no hex digits in `\\x' escape sequence"
+msgstr ""
+
+#: node.c:579
+#, c-format
+msgid ""
+"hex escape \\x%.*s of %d characters probably not interpreted the way you "
+"expect"
+msgstr ""
+
+#: node.c:594
+#, c-format
+msgid "escape sequence `\\%c' treated as plain `%c'"
+msgstr ""
+
+#: node.c:739
+msgid ""
+"Invalid multibyte data detected. There may be a mismatch between your data "
+"and your locale."
+msgstr ""
+
+#: posix/gawkmisc.c:177
+#, c-format
+msgid "%s %s `%s': could not get fd flags: (fcntl F_GETFD: %s)"
+msgstr ""
+
+#: posix/gawkmisc.c:189
+#, c-format
+msgid "%s %s `%s': could not set close-on-exec: (fcntl F_SETFD: %s)"
+msgstr ""
+
+#: profile.c:71
+#, c-format
+msgid "could not open `%s' for writing: %s"
+msgstr ""
+
+#: profile.c:73
+msgid "sending profile to standard error"
+msgstr ""
+
+#: profile.c:193
+#, c-format
+msgid ""
+"\t# %s block(s)\n"
+"\n"
+msgstr ""
+
+#: profile.c:198
+#, c-format
+msgid ""
+"\t# Rule(s)\n"
+"\n"
+msgstr ""
+
+#: profile.c:272
+#, c-format
+msgid "internal error: %s with null vname"
+msgstr ""
+
+#: profile.c:537
+msgid "internal error: builtin with null fname"
+msgstr ""
+
+#: profile.c:949
+#, c-format
+msgid ""
+"\t# Loaded extensions (-l and/or @load)\n"
+"\n"
+msgstr ""
+
+#: profile.c:972
+#, c-format
+msgid "\t# gawk profile, created %s\n"
+msgstr ""
+
+#: profile.c:1475
+#, c-format
+msgid ""
+"\n"
+"\t# Functions, listed alphabetically\n"
+msgstr ""
+
+#: profile.c:1513
+#, c-format
+msgid "redir2str: unknown redirection type %d"
+msgstr ""
+
+#: re.c:607
+#, c-format
+msgid "regexp component `%.*s' should probably be `[%.*s]'"
+msgstr ""
+
+#: regcomp.c:131
+msgid "Success"
+msgstr ""
+
+#: regcomp.c:134
+msgid "No match"
+msgstr ""
+
+#: regcomp.c:137
+msgid "Invalid regular expression"
+msgstr ""
+
+#: regcomp.c:140
+msgid "Invalid collation character"
+msgstr ""
+
+#: regcomp.c:143
+msgid "Invalid character class name"
+msgstr ""
+
+#: regcomp.c:146
+msgid "Trailing backslash"
+msgstr ""
+
+#: regcomp.c:149
+msgid "Invalid back reference"
+msgstr ""
+
+#: regcomp.c:152
+msgid "Unmatched [ or [^"
+msgstr ""
+
+#: regcomp.c:155
+msgid "Unmatched ( or \\("
+msgstr ""
+
+#: regcomp.c:158
+msgid "Unmatched \\{"
+msgstr ""
+
+#: regcomp.c:164
+msgid "Invalid range end"
+msgstr ""
+
+#: regcomp.c:167
+msgid "Memory exhausted"
+msgstr ""
+
+#: regcomp.c:170
+msgid "Invalid preceding regular expression"
+msgstr ""
+
+#: regcomp.c:173
+msgid "Premature end of regular expression"
+msgstr ""
+
+#: regcomp.c:179
+msgid "Unmatched ) or \\)"
+msgstr ""
+
+#: regcomp.c:704
+msgid "No previous regular expression"
+msgstr ""
+
+#: symbol.c:741
+msgid "can not pop main context"
+msgstr ""
diff --git a/po/nl.gmo b/po/nl.gmo
index 0fd9c46d..76c57134 100644
--- a/po/nl.gmo
+++ b/po/nl.gmo
Binary files differ
diff --git a/po/nl.po b/po/nl.po
index 641a6bee..dc037a99 100644
--- a/po/nl.po
+++ b/po/nl.po
@@ -1,17 +1,17 @@
# Dutch translations for GNU gawk.
-# Copyright (C) 2011 Free Software Foundation, Inc.
+# Copyright (C) 2014 Free Software Foundation, Inc.
# This file is distributed under the same license as the gawk package.
#
-# And so it goes.
+# “Flierefluiten!!â€
#
-# Benno Schulenberg <benno@vertaalt.nl>, 2005, 2007, 2010, 2011.
# Erwin Poeze <erwin.poeze@gmail.com>, 2009.
+# Benno Schulenberg <benno@vertaalt.nl>, 2005, 2007, 2010, 2011, 2012, 2013, 2014.
msgid ""
msgstr ""
-"Project-Id-Version: gawk 4.0.0\n"
+"Project-Id-Version: gawk 4.1.0b\n"
"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
-"POT-Creation-Date: 2011-10-24 05:57+0200\n"
-"PO-Revision-Date: 2011-07-17 21:44+0200\n"
+"POT-Creation-Date: 2014-04-08 19:23+0300\n"
+"PO-Revision-Date: 2014-02-04 11:18+0100\n"
"Last-Translator: Benno Schulenberg <benno@vertaalt.nl>\n"
"Language-Team: Dutch <vertaling@vrijschrift.org>\n"
"Language: nl\n"
@@ -21,505 +21,486 @@ msgstr ""
"X-Generator: Lokalize 1.0\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: array.c:140
+#: array.c:256
#, c-format
msgid "from %s"
msgstr "van %s"
-#: array.c:248
+#: array.c:357
msgid "attempt to use a scalar value as array"
msgstr "scalaire waarde wordt gebruikt als array"
-#: array.c:251
-#, c-format
-msgid "attempt to use function `%s' as an array"
-msgstr "functie '%s' wordt gebruikt als array"
-
-#: array.c:254
+#: array.c:359
#, c-format
msgid "attempt to use scalar parameter `%s' as an array"
msgstr "scalaire parameter '%s' wordt gebruikt als array"
-#: array.c:257
+#: array.c:362
#, c-format
msgid "attempt to use scalar `%s' as an array"
msgstr "scalair '%s' wordt gebruikt als array"
-#: array.c:302 array.c:707 builtin.c:84 builtin.c:1384 builtin.c:1426
-#: builtin.c:1439 builtin.c:1856 builtin.c:1868 eval.c:1135 eval.c:1139
-#: eval.c:1495 eval.c:1812
+#: array.c:409 array.c:576 builtin.c:85 builtin.c:1615 builtin.c:1661
+#: builtin.c:1674 builtin.c:2102 builtin.c:2116 eval.c:1122 eval.c:1126
+#: eval.c:1531
#, c-format
msgid "attempt to use array `%s' in a scalar context"
msgstr "array '%s' wordt gebruikt in een scalaire context"
-#: array.c:513
-#, c-format
-msgid "reference to uninitialized element `%s[\"%.*s\"]'"
-msgstr "verwijzing naar ongeïnitialiseerd element '%s[\"%.*s\"]'"
-
-#: array.c:519
-#, c-format
-msgid "subscript of array `%s' is null string"
-msgstr "index van array '%s' is lege string"
-
-#: array.c:723
+#: array.c:583
#, c-format
msgid "delete: index `%s' not in array `%s'"
msgstr "delete: index '%s' niet in array '%s'"
-#: array.c:734 eval.c:1865
+#: array.c:597
#, c-format
msgid "attempt to use scalar `%s[\"%.*s\"]' as an array"
msgstr "scalair '%s[\"%.*s\"]' wordt gebruikt als array"
-#: array.c:910
-#, c-format
-msgid "%s: empty (null)\n"
-msgstr "%s: leeg (nil)\n"
-
-#: array.c:915
-#, c-format
-msgid "%s: empty (zero)\n"
-msgstr "%s: leeg (nul)\n"
-
-#: array.c:919
-#, c-format
-msgid "%s: table_size = %d, array_size = %d\n"
-msgstr "%s: tabelgrootte = %d, arraygrootte = %d\n"
+#: array.c:776
+msgid "adump: first argument not an array"
+msgstr "adump: eerste argument is geen array"
-#: array.c:954
-#, c-format
-msgid "%s: is parameter\n"
-msgstr "%s: is een parameter\n"
-
-#: array.c:958
-#, c-format
-msgid "%s: array_ref to %s\n"
-msgstr "%s: array-verwijzing naar %s\n"
-
-#: array.c:963
-msgid "adump: argument not an array"
-msgstr "adump: argument is geen array"
-
-#: array.c:1086
+#: array.c:815
msgid "asort: second argument not an array"
msgstr "asort: tweede argument is geen array"
-#: array.c:1087
+#: array.c:816
msgid "asorti: second argument not an array"
msgstr "asorti: tweede argument is geen array"
-#: array.c:1094
+#: array.c:823
msgid "asort: first argument not an array"
msgstr "asort: eerste argument is geen array"
-#: array.c:1095
+#: array.c:824
msgid "asorti: first argument not an array"
msgstr "asorti: eerste argument is geen array"
-#: array.c:1102
+#: array.c:831
msgid "asort: cannot use a subarray of first arg for second arg"
msgstr ""
"asort: een subarray van het eerste argument kan niet als tweede argument "
"gebruikt worden"
-#: array.c:1103
+#: array.c:832
msgid "asorti: cannot use a subarray of first arg for second arg"
msgstr ""
"asorti: een subarray van het eerste argument kan niet als tweede argument "
"gebruikt worden"
-#: array.c:1108
+#: array.c:837
msgid "asort: cannot use a subarray of second arg for first arg"
msgstr ""
"asort: een subarray van het tweede argument kan niet als eerste argument "
"gebruikt worden"
-#: array.c:1109
+#: array.c:838
msgid "asorti: cannot use a subarray of second arg for first arg"
msgstr ""
"asorti: een subarray van het tweede argument kan niet als eerste argument "
"gebruikt worden"
-#: array.c:1659
+#: array.c:1314
#, c-format
msgid "`%s' is invalid as a function name"
msgstr "'%s' is ongeldig als functienaam"
-#: array.c:1663
+#: array.c:1318
#, c-format
msgid "sort comparison function `%s' is not defined"
msgstr "sorteervergelijkingsfunctie '%s' is niet gedefinieerd"
-#: awkgram.y:249
+#: awkgram.y:233
#, c-format
msgid "%s blocks must have an action part"
msgstr "%s-blokken horen een actiedeel te hebben"
-#: awkgram.y:252
+#: awkgram.y:236
msgid "each rule must have a pattern or an action part"
msgstr "elke regel hoort een patroon of een actiedeel te hebben"
-#: awkgram.y:323 awkgram.y:334
+#: awkgram.y:325 awkgram.y:336
msgid "old awk does not support multiple `BEGIN' or `END' rules"
msgstr "oude 'awk' staat meerdere 'BEGIN'- en 'END'-regels niet toe"
-#: awkgram.y:371
+#: awkgram.y:373
#, 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:432
+#: awkgram.y:419
msgid "regexp constant `//' looks like a C++ comment, but is not"
msgstr "regexp-constante '//' lijkt op C-commentaar, maar is het niet"
-#: awkgram.y:436
+#: awkgram.y:423
#, c-format
msgid "regexp constant `/%s/' looks like a C comment, but is not"
msgstr "regexp-constante '/%s/' lijkt op C-commentaar, maar is het niet"
-#: awkgram.y:528
+#: awkgram.y:515
#, c-format
msgid "duplicate case values in switch body: %s"
msgstr "dubbele 'case'-waarde in 'switch'-opdracht: %s"
-#: awkgram.y:549
+#: awkgram.y:536
msgid "duplicate `default' detected in switch body"
msgstr "dubbele 'default' in 'switch'-opdracht"
-#: awkgram.y:809
+#: awkgram.y:796 awkgram.y:3723
msgid "`break' is not allowed outside a loop or switch"
msgstr "'break' buiten een lus of 'switch'-opdracht is niet toegestaan"
-#: awkgram.y:818
+#: awkgram.y:805 awkgram.y:3715
msgid "`continue' is not allowed outside a loop"
msgstr "'continue' buiten een lus is niet toegestaan"
-#: awkgram.y:828
+#: awkgram.y:815
#, c-format
msgid "`next' used in %s action"
msgstr "'next' wordt gebruikt in %s-actie"
-#: awkgram.y:836
-msgid "`nextfile' is a gawk extension"
-msgstr "'nextfile' is een gawk-uitbreiding"
-
-#: awkgram.y:841
+#: awkgram.y:824
#, c-format
msgid "`nextfile' used in %s action"
msgstr "'nextfile' wordt gebruikt in %s-actie"
-#: awkgram.y:865
+#: awkgram.y:848
msgid "`return' used outside function context"
msgstr "'return' wordt gebruikt buiten functiecontext"
-#: awkgram.y:925
+#: awkgram.y:922
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:995 awkgram.y:999 awkgram.y:1023
-msgid "`delete array' is a gawk extension"
-msgstr "'delete array' is een gawk-uitbreiding"
+#: awkgram.y:988 awkgram.y:1037
+msgid "`delete' is not allowed with SYMTAB"
+msgstr "'delete' is niet toegestaan met SYMTAB"
+
+#: awkgram.y:990 awkgram.y:1039
+msgid "`delete' is not allowed with FUNCTAB"
+msgstr "'delete' is niet toegestaan met FUNCTAB"
-#: awkgram.y:1019
+#: awkgram.y:1024 awkgram.y:1028
msgid "`delete(array)' is a non-portable tawk extension"
msgstr "'delete(array)' is een niet-overdraagbare 'tawk'-uitbreiding"
-#: awkgram.y:1135
+#: awkgram.y:1149
msgid "multistage two-way pipelines don't work"
msgstr "meerfase-tweerichtings-pijplijnen werken niet"
-#: awkgram.y:1238
+#: awkgram.y:1264
msgid "regular expression on right of assignment"
msgstr "reguliere expressie rechts van toewijzing"
-#: awkgram.y:1249
+#: awkgram.y:1275
msgid "regular expression on left of `~' or `!~' operator"
msgstr "reguliere expressie links van operator '~' of '!~'"
-#: awkgram.y:1265 awkgram.y:1419
+#: awkgram.y:1291 awkgram.y:1442
msgid "old awk does not support the keyword `in' except after `for'"
msgstr "oude 'awk' kent het sleutelwoord 'in' niet, behalve na 'for'"
-#: awkgram.y:1275
+#: awkgram.y:1301
msgid "regular expression on right of comparison"
msgstr "reguliere expressie rechts van vergelijking"
-#: awkgram.y:1394
+#: awkgram.y:1417
#, c-format
msgid "`getline var' invalid inside `%s' rule"
msgstr "'getline var' is ongeldig binnen een '%s'-regel"
-#: awkgram.y:1397 eval.c:2504
+#: awkgram.y:1420
#, c-format
msgid "`getline' invalid inside `%s' rule"
msgstr "'getline' is ongeldig binnen een '%s'-regel"
-#: awkgram.y:1402
+#: awkgram.y:1425
msgid "non-redirected `getline' undefined inside END action"
msgstr "niet-omgeleide 'getline' is ongedefinieerd binnen een END-actie"
-#: awkgram.y:1421
+#: awkgram.y:1444
msgid "old awk does not support multidimensional arrays"
msgstr "oude 'awk' kent geen meerdimensionale arrays"
-#: awkgram.y:1517
+#: awkgram.y:1541
msgid "call of `length' without parentheses is not portable"
msgstr "aanroep van 'length' zonder haakjes is niet overdraagbaar"
-#: awkgram.y:1580
+#: awkgram.y:1607
msgid "indirect function calls are a gawk extension"
msgstr "indirecte functieaanroepen zijn een gawk-uitbreiding"
-#: awkgram.y:1593
+#: awkgram.y:1620
#, c-format
msgid "can not use special variable `%s' for indirect function call"
msgstr ""
"kan speciale variabele '%s' niet voor indirecte functieaanroep gebruiken"
-#: awkgram.y:1671
+#: awkgram.y:1698
msgid "invalid subscript expression"
msgstr "ongeldige index-expressie"
-#: awkgram.y:1711
-msgid "use of non-array as array"
-msgstr "non-array wordt gebruikt als array"
-
-#: awkgram.y:1975 awkgram.y:1995 msg.c:98
+#: awkgram.y:2048 awkgram.y:2068 gawkapi.c:206 gawkapi.c:224 msg.c:126
msgid "warning: "
msgstr "waarschuwing: "
-#: awkgram.y:1993 msg.c:130
+#: awkgram.y:2066 gawkapi.c:192 gawkapi.c:221 msg.c:158
msgid "fatal: "
msgstr "fataal: "
-#: awkgram.y:2043
+#: awkgram.y:2116
msgid "unexpected newline or end of string"
msgstr "onverwacht regeleinde of einde van string"
-#: awkgram.y:2300 awkgram.y:2358 awkgram.y:2542
+#: awkgram.y:2383 awkgram.y:2459 awkgram.y:2682 debug.c:523 debug.c:539
+#: debug.c:2812 debug.c:5055
#, c-format
msgid "can't open source file `%s' for reading (%s)"
msgstr "kan bronbestand '%s' niet openen om te lezen (%s)"
-#: awkgram.y:2301 awkgram.y:2359 builtin.c:122
+#: awkgram.y:2384 awkgram.y:2509
+#, c-format
+msgid "can't open shared library `%s' for reading (%s)"
+msgstr "kan gedeelde bibliotheek '%s' niet openen om te lezen (%s)"
+
+#: awkgram.y:2386 awkgram.y:2460 awkgram.y:2510 builtin.c:135 debug.c:5206
msgid "reason unknown"
msgstr "reden onbekend"
-#: awkgram.y:2317
+#: awkgram.y:2395 awkgram.y:2419
+#, c-format
+msgid "can't include `%s' and use it as a program file"
+msgstr "kan '%s' niet invoegen en als programmabestand gebruiken"
+
+#: awkgram.y:2408
#, c-format
msgid "already included source file `%s'"
msgstr "bronbestand '%s' is reeds ingesloten"
-#: awkgram.y:2343
+#: awkgram.y:2409
+#, c-format
+msgid "already loaded shared library `%s'"
+msgstr "gedeelde bibliotheek '%s' is reeds geladen"
+
+#: awkgram.y:2444
msgid "@include is a gawk extension"
msgstr "'@include' is een gawk-uitbreiding"
-#: awkgram.y:2349
+#: awkgram.y:2450
msgid "empty filename after @include"
msgstr "lege bestandsnaam na '@include'"
#: awkgram.y:2494
+msgid "@load is a gawk extension"
+msgstr "'@load' is een gawk-uitbreiding"
+
+#: awkgram.y:2500
+msgid "empty filename after @load"
+msgstr "lege bestandsnaam na '@load'"
+
+#: awkgram.y:2634
msgid "empty program text on command line"
-msgstr "lege programmatekst op commandoregel"
+msgstr "lege programmatekst op opdrachtregel"
-#: awkgram.y:2609
+#: awkgram.y:2749
#, c-format
msgid "can't read sourcefile `%s' (%s)"
msgstr "kan bronbestand '%s' niet lezen (%s)"
-#: awkgram.y:2620
+#: awkgram.y:2760
#, c-format
msgid "source file `%s' is empty"
msgstr "bronbestand '%s' is leeg"
-#: awkgram.y:2805
+#: awkgram.y:2937
msgid "source file does not end in newline"
msgstr "bronbestand eindigt niet met een regeleindeteken (LF)"
-#: awkgram.y:2882
+#: awkgram.y:3042
msgid "unterminated regexp ends with `\\' at end of file"
msgstr "onafgesloten reguliere expressie eindigt met '\\' aan bestandseinde"
-#: awkgram.y:2906
+#: awkgram.y:3066
#, c-format
msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
msgstr "%s: %d: regexp-optie '/.../%c' van 'tawk' werkt niet in gawk"
-#: awkgram.y:2910
+#: awkgram.y:3070
#, c-format
msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
msgstr "regexp-optie '/.../%c' van 'tawk' werkt niet in gawk"
-#: awkgram.y:2917
+#: awkgram.y:3077
msgid "unterminated regexp"
msgstr "onafgesloten reguliere expressie"
-#: awkgram.y:2921
+#: awkgram.y:3081
msgid "unterminated regexp at end of file"
msgstr "onafgesloten reguliere expressie aan bestandseinde"
-#: awkgram.y:2980
+#: awkgram.y:3140
msgid "use of `\\ #...' line continuation is not portable"
msgstr "gebruik van regelvoortzetting '\\ #...' is niet overdraagbaar"
-#: awkgram.y:2996
+#: awkgram.y:3156
msgid "backslash not last character on line"
msgstr "backslash is niet het laatste teken op de regel"
-#: awkgram.y:3057
+#: awkgram.y:3217
msgid "POSIX does not allow operator `**='"
msgstr "POSIX staat operator '**=' niet toe"
-#: awkgram.y:3059
+#: awkgram.y:3219
msgid "old awk does not support operator `**='"
msgstr "oude 'awk' kent de operator '**=' niet"
-#: awkgram.y:3068
+#: awkgram.y:3228
msgid "POSIX does not allow operator `**'"
msgstr "POSIX staat operator '**' niet toe"
-#: awkgram.y:3070
+#: awkgram.y:3230
msgid "old awk does not support operator `**'"
msgstr "oude 'awk' kent de operator '**' niet"
-#: awkgram.y:3105
+#: awkgram.y:3265
msgid "operator `^=' is not supported in old awk"
msgstr "oude 'awk' kent de operator '^=' niet"
-#: awkgram.y:3113
+#: awkgram.y:3273
msgid "operator `^' is not supported in old awk"
msgstr "oude 'awk' kent de operator '^' niet"
-#: awkgram.y:3206 awkgram.y:3222
+#: awkgram.y:3366 awkgram.y:3382 command.y:1178
msgid "unterminated string"
msgstr "onafgesloten string"
-#: awkgram.y:3418
+#: awkgram.y:3603
#, c-format
msgid "invalid char '%c' in expression"
msgstr "ongeldig teken '%c' in expressie"
-#: awkgram.y:3465
+#: awkgram.y:3650
#, c-format
msgid "`%s' is a gawk extension"
msgstr "'%s' is een gawk-uitbreiding"
-#: awkgram.y:3470
-#, c-format
-msgid "`%s' is a Bell Labs extension"
-msgstr "'%s' is een uitbreiding door Bell Labs"
-
-#: awkgram.y:3475
+#: awkgram.y:3655
#, c-format
msgid "POSIX does not allow `%s'"
msgstr "POSIX staat '%s' niet toe"
-#: awkgram.y:3483
+#: awkgram.y:3663
#, c-format
msgid "`%s' is not supported in old awk"
msgstr "oude 'awk' kent '%s' niet"
-#: awkgram.y:3550
+#: awkgram.y:3753
msgid "`goto' considered harmful!\n"
msgstr "'goto' wordt als schadelijk beschouwd!\n"
-#: awkgram.y:3601
+#: awkgram.y:3787
#, c-format
msgid "%d is invalid as number of arguments for %s"
msgstr "%d is een ongeldig aantal argumenten voor %s"
-#: awkgram.y:3636
+#: awkgram.y:3822
#, 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:3641
+#: awkgram.y:3827
#, c-format
msgid "%s third parameter is not a changeable object"
msgstr "%s: derde parameter is geen veranderbaar object"
-#: awkgram.y:3714 awkgram.y:3717
+#: awkgram.y:3910 awkgram.y:3913
msgid "match: third argument is a gawk extension"
msgstr "match: derde argument is een gawk-uitbreiding"
-#: awkgram.y:3771 awkgram.y:3774
+#: awkgram.y:3967 awkgram.y:3970
msgid "close: second argument is a gawk extension"
msgstr "close: tweede argument is een gawk-uitbreiding"
-#: awkgram.y:3786
+#: awkgram.y:3982
msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
msgstr "dcgettext(_\"...\") is onjuist: verwijder het liggende streepje"
-#: awkgram.y:3801
+#: awkgram.y:3997
msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
msgstr "dcngettext(_\"...\") is onjuist: verwijder het liggende streepje"
-#: awkgram.y:3893
-#, c-format
-msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
-msgstr "functie '%s': parameter #%d, '%s', dupliceert parameter #%d"
+#: awkgram.y:4016
+msgid "index: regexp constant as second argument is not allowed"
+msgstr ""
+"index: een reguliere-expressie-constante als tweede argument is niet "
+"toegestaan"
-#: awkgram.y:3935
+#: awkgram.y:4069
#, c-format
msgid "function `%s': parameter `%s' shadows global variable"
msgstr "functie '%s': parameter '%s' schaduwt een globale variabele"
-#: awkgram.y:4093
+#: awkgram.y:4126 debug.c:4041 debug.c:4084 debug.c:5204
#, c-format
msgid "could not open `%s' for writing (%s)"
msgstr "kan '%s' niet openen om te schrijven (%s)"
-#: awkgram.y:4094
+#: awkgram.y:4127
msgid "sending variable list to standard error"
msgstr "variabelenlijst gaat naar standaardfoutuitvoer"
-#: awkgram.y:4100
+#: awkgram.y:4135
#, c-format
msgid "%s: close failed (%s)"
msgstr "%s: sluiten is mislukt (%s)"
-#: awkgram.y:4152
+#: awkgram.y:4160
msgid "shadow_funcs() called twice!"
msgstr "shadow_funcs() twee keer aangeroepen!"
-#: awkgram.y:4158
+#: awkgram.y:4168
msgid "there were shadowed variables."
msgstr "er waren geschaduwde variabelen."
-#: awkgram.y:4188
+#: awkgram.y:4239
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "functienaam '%s' is al eerder gedefinieerd"
+
+#: awkgram.y:4285
#, c-format
msgid "function `%s': can't use function name as parameter name"
msgstr "functie '%s': kan functienaam niet als parameternaam gebruiken"
-#: awkgram.y:4192
+#: awkgram.y:4288
#, c-format
msgid "function `%s': can't use special variable `%s' as a function parameter"
msgstr ""
"functie '%s': kan speciale variabele '%s' niet als functieparameter gebruiken"
-#: awkgram.y:4208
+#: awkgram.y:4296
#, c-format
-msgid "function name `%s' previously defined"
-msgstr "functienaam '%s' is al eerder gedefinieerd"
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "functie '%s': parameter #%d, '%s', dupliceert parameter #%d"
-#: awkgram.y:4376 awkgram.y:4382
+#: awkgram.y:4383 awkgram.y:4389
#, c-format
msgid "function `%s' called but never defined"
msgstr "functie '%s' wordt aangeroepen maar is nergens gedefinieerd"
-#: awkgram.y:4385
+#: awkgram.y:4393
#, c-format
msgid "function `%s' defined but never called directly"
msgstr "functie '%s' is gedefinieerd maar wordt nergens direct aangeroepen"
-#: awkgram.y:4417
+#: awkgram.y:4425
#, c-format
msgid "regexp constant for parameter #%d yields boolean value"
msgstr "regexp-constante als parameter #%d levert booleanwaarde op"
-#: awkgram.y:4526
+#: awkgram.y:4484
#, c-format
msgid ""
"function `%s' called with space between name and `(',\n"
@@ -528,230 +509,246 @@ msgstr ""
"functie '%s' wordt aangeroepen met een spatie tussen naam en '(',\n"
"of wordt gebruikt als variabele of array"
-#: awkgram.y:4773 eval.c:2056
+#: awkgram.y:4720
msgid "division by zero attempted"
msgstr "deling door nul"
-#: awkgram.y:4782 eval.c:2072
+#: awkgram.y:4729
#, c-format
msgid "division by zero attempted in `%%'"
msgstr "deling door nul in '%%'"
-#: builtin.c:120
+#: awkgram.y:5049
+msgid ""
+"cannot assign a value to the result of a field post-increment expression"
+msgstr ""
+"kan geen waarde toewijzen aan het resultaat van een post-increment-expressie "
+"van een veld"
+
+#: awkgram.y:5052
+#, c-format
+msgid "invalid target of assignment (opcode %s)"
+msgstr "ongeldig doel van toewijzing (opcode %s)"
+
+#: builtin.c:133
#, c-format
msgid "%s to \"%s\" failed (%s)"
msgstr "%s naar \"%s\" is mislukt (%s)"
-#: builtin.c:121
+#: builtin.c:134
msgid "standard output"
msgstr "standaarduitvoer"
-#: builtin.c:135
+#: builtin.c:148
msgid "exp: received non-numeric argument"
msgstr "exp: argument is geen getal"
-#: builtin.c:141
+#: builtin.c:154
#, c-format
msgid "exp: argument %g is out of range"
msgstr "exp: argument %g ligt buiten toegestane bereik"
-#: builtin.c:200
+#: builtin.c:229
#, c-format
msgid "fflush: cannot flush: pipe `%s' opened for reading, not writing"
msgstr ""
"fflush: kan pijp niet leegmaken: '%s' is geopend om te lezen, niet om te "
"schrijven"
-#: builtin.c:203
+#: builtin.c:232
#, 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:215
+#: builtin.c:244
#, c-format
msgid "fflush: `%s' is not an open file, pipe or co-process"
msgstr "fflush: '%s' is geen open bestand, pijp, of co-proces"
-#: builtin.c:333
+#: builtin.c:362
msgid "index: received non-string first argument"
msgstr "index: eerste argument is geen string"
-#: builtin.c:335
+#: builtin.c:364
msgid "index: received non-string second argument"
msgstr "index: tweede argument is geen string"
-#: builtin.c:457
+#: builtin.c:488 mpfr.c:757
msgid "int: received non-numeric argument"
msgstr "int: argument is geen getal"
-#: builtin.c:493
+#: builtin.c:525
msgid "length: received array argument"
msgstr "length: argument is een array"
-#: builtin.c:496
+#: builtin.c:528
msgid "`length(array)' is a gawk extension"
msgstr "'length(array)' is een gawk-uitbreiding"
-#: builtin.c:504
+#: builtin.c:544
msgid "length: received non-string argument"
msgstr "length: argument is geen string"
-#: builtin.c:535
+#: builtin.c:575
msgid "log: received non-numeric argument"
msgstr "log: argument is geen getal"
-#: builtin.c:538
+#: builtin.c:578
#, c-format
msgid "log: received negative argument %g"
msgstr "log: argument %g is negatief"
-#: builtin.c:694 builtin.c:699
+#: builtin.c:776 builtin.c:781
msgid "fatal: must use `count$' on all formats or none"
msgstr "fataal: 'count$' hoort in alle opmaken gebruikt te worden, of in geen"
-#: builtin.c:761
+#: builtin.c:851
#, c-format
msgid "field width is ignored for `%%' specifier"
msgstr "veldbreedte wordt genegeerd voor opmaakaanduiding '%%'"
-#: builtin.c:763
+#: builtin.c:853
#, c-format
msgid "precision is ignored for `%%' specifier"
msgstr "veldprecisie wordt genegeerd voor opmaakaanduiding '%%'"
-#: builtin.c:765
+#: builtin.c:855
#, c-format
msgid "field width and precision are ignored for `%%' specifier"
msgstr "veldbreedte en -precisie worden genegeerd voor opmaakaanduiding '%%'"
-#: builtin.c:816
+#: builtin.c:906
msgid "fatal: `$' is not permitted in awk formats"
msgstr "fataal: '$' is niet toegestaan in awk-opmaak"
-#: builtin.c:825
+#: builtin.c:915
msgid "fatal: arg count with `$' must be > 0"
msgstr "fataal: het aantal argumenten met '$' moet > 0 zijn"
-#: builtin.c:829
+#: builtin.c:919
#, c-format
msgid "fatal: arg count %ld greater than total number of supplied arguments"
msgstr "fataal: argumentental %ld is groter dan het gegeven aantal argumenten"
-#: builtin.c:833
+#: builtin.c:923
msgid "fatal: `$' not permitted after period in format"
msgstr "fataal: '$' is niet toegestaan na een punt in de opmaak"
-#: builtin.c:849
+#: builtin.c:939
msgid "fatal: no `$' supplied for positional field width or precision"
msgstr "fataal: geen '$' opgegeven bij positionele veldbreedte of -precisie"
-#: builtin.c:920
+#: builtin.c:1009
msgid "`l' is meaningless in awk formats; ignored"
msgstr "'l' is betekenisloos in awk-opmaak; genegeerd"
-#: builtin.c:924
+#: builtin.c:1013
msgid "fatal: `l' is not permitted in POSIX awk formats"
msgstr "fataal: 'l' is niet toegestaan in POSIX awk-opmaak"
-#: builtin.c:937
+#: builtin.c:1026
msgid "`L' is meaningless in awk formats; ignored"
msgstr "'L' is betekenisloos in awk-opmaak; genegeerd"
-#: builtin.c:941
+#: builtin.c:1030
msgid "fatal: `L' is not permitted in POSIX awk formats"
msgstr "fataal: 'L' is niet toegestaan in POSIX awk-opmaak"
-#: builtin.c:954
+#: builtin.c:1043
msgid "`h' is meaningless in awk formats; ignored"
msgstr "'h' is betekenisloos in awk-opmaak; genegeerd"
-#: builtin.c:958
+#: builtin.c:1047
msgid "fatal: `h' is not permitted in POSIX awk formats"
msgstr "fataal: 'h' is niet toegestaan in POSIX awk-opmaak"
-#: builtin.c:1271
+#: builtin.c:1463
#, 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:1331
+#: builtin.c:1561
#, c-format
msgid "ignoring unknown format specifier character `%c': no argument converted"
msgstr ""
"onbekend opmaakteken '%c' wordt genegeerd: geen argument is geconverteerd"
-#: builtin.c:1336
+#: builtin.c:1566
msgid "fatal: not enough arguments to satisfy format string"
msgstr "fataal: niet genoeg argumenten voor opmaakstring"
-#: builtin.c:1338
+#: builtin.c:1568
msgid "^ ran out for this one"
msgstr "niet genoeg ^ voor deze"
-#: builtin.c:1345
+#: builtin.c:1575
msgid "[s]printf: format specifier does not have control letter"
msgstr "[s]printf: opmaakaanduiding mist een stuurletter"
-#: builtin.c:1348
+#: builtin.c:1578
msgid "too many arguments supplied for format string"
msgstr "te veel argumenten voor opmaakstring"
-#: builtin.c:1422 builtin.c:1433
+#: builtin.c:1634
+msgid "sprintf: no arguments"
+msgstr "sprintf: geen argumenten"
+
+#: builtin.c:1657 builtin.c:1668
msgid "printf: no arguments"
msgstr "printf: geen argumenten"
-#: builtin.c:1474
+#: builtin.c:1711
msgid "sqrt: received non-numeric argument"
msgstr "sqrt: argument is geen getal"
-#: builtin.c:1478
+#: builtin.c:1715
#, c-format
msgid "sqrt: called with negative argument %g"
msgstr "sqrt: argument %g is negatief"
-#: builtin.c:1502
+#: builtin.c:1746
#, c-format
msgid "substr: length %g is not >= 1"
msgstr "substr: lengte %g is niet >= 1"
-#: builtin.c:1504
+#: builtin.c:1748
#, c-format
msgid "substr: length %g is not >= 0"
msgstr "substr: lengte %g is niet >= 0"
-#: builtin.c:1511
+#: builtin.c:1755
#, c-format
msgid "substr: non-integer length %g will be truncated"
msgstr "substr: lengte %g is geen integer; wordt afgekapt"
-#: builtin.c:1516
+#: builtin.c:1760
#, 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:1528
+#: builtin.c:1772
#, c-format
msgid "substr: start index %g is invalid, using 1"
msgstr "substr: startindex %g is ongeldig; 1 wordt gebruikt"
-#: builtin.c:1533
+#: builtin.c:1777
#, c-format
msgid "substr: non-integer start index %g will be truncated"
msgstr "substr: startindex %g is geen integer; wordt afgekapt"
-#: builtin.c:1558
+#: builtin.c:1802
msgid "substr: source string is zero length"
msgstr "substr: bronstring heeft lengte nul"
-#: builtin.c:1574
+#: builtin.c:1818
#, 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:1582
+#: builtin.c:1826
#, c-format
msgid ""
"substr: length %g at start index %g exceeds length of first argument (%lu)"
@@ -759,227 +756,1123 @@ msgstr ""
"substr: lengte %g bij startindex %g is groter dan de lengte van het eerste "
"argument (%lu)"
-#: builtin.c:1655
+#: builtin.c:1900
msgid "strftime: format value in PROCINFO[\"strftime\"] has numeric type"
msgstr "strftime: opmaakwaarde in PROCINFO[\"strftime\"] is numeriek"
-#: builtin.c:1678
+#: builtin.c:1923
msgid "strftime: received non-numeric second argument"
msgstr "strftime: tweede argument is geen getal"
-#: builtin.c:1681
+#: builtin.c:1927
msgid "strftime: second argument less than 0 or too big for time_t"
-msgstr ""
+msgstr "strftime: tweede argument is kleiner dan nul of te groot voor 'time_t'"
-#: builtin.c:1687
+#: builtin.c:1934
msgid "strftime: received non-string first argument"
msgstr "strftime: eerste argument is geen string"
-#: builtin.c:1693
+#: builtin.c:1941
msgid "strftime: received empty format string"
msgstr "strftime: opmaakstring is leeg"
-#: builtin.c:1759
+#: builtin.c:2007
msgid "mktime: received non-string argument"
msgstr "mktime: argument is geen string"
-#: builtin.c:1776
+#: builtin.c:2024
msgid "mktime: at least one of the values is out of the default range"
msgstr "mktime: minstens één van waarden valt buiten het standaardbereik"
-#: builtin.c:1811
+#: builtin.c:2059
msgid "'system' function not allowed in sandbox mode"
msgstr "'system'-functie is niet toegestaan in sandbox-modus"
-#: builtin.c:1816
+#: builtin.c:2064
msgid "system: received non-string argument"
msgstr "system: argument is geen string"
-#: builtin.c:1871 eval.c:1159 eval.c:1790 eval.c:1803
-#, c-format
-msgid "reference to uninitialized variable `%s'"
-msgstr "verwijzing naar ongeïnitialiseerde variabele '%s'"
-
-#: builtin.c:1938
+#: builtin.c:2184
#, c-format
msgid "reference to uninitialized field `$%d'"
msgstr "verwijzing naar ongeïnitialiseerd veld '$%d'"
-#: builtin.c:2025
+#: builtin.c:2271
msgid "tolower: received non-string argument"
msgstr "tolower: argument is geen string"
-#: builtin.c:2059
+#: builtin.c:2305
msgid "toupper: received non-string argument"
msgstr "toupper: argument is geen string"
-#: builtin.c:2095
+#: builtin.c:2341 mpfr.c:672
msgid "atan2: received non-numeric first argument"
msgstr "atan2: eerste argument is geen getal"
-#: builtin.c:2097
+#: builtin.c:2343 mpfr.c:674
msgid "atan2: received non-numeric second argument"
msgstr "atan2: tweede argument is geen getal"
-#: builtin.c:2116
+#: builtin.c:2362
msgid "sin: received non-numeric argument"
msgstr "sin: argument is geen getal"
-#: builtin.c:2132
+#: builtin.c:2378
msgid "cos: received non-numeric argument"
msgstr "cos: argument is geen getal"
-#: builtin.c:2185
+#: builtin.c:2431 mpfr.c:1156
msgid "srand: received non-numeric argument"
msgstr "srand: argument is geen getal"
-#: builtin.c:2216
+#: builtin.c:2462
msgid "match: third argument is not an array"
msgstr "match: derde argument is geen array"
-#: builtin.c:2480
+#: builtin.c:2734
msgid "gensub: third argument of 0 treated as 1"
msgstr "gensub: derde argument is 0; wordt beschouwd als 1"
-#: builtin.c:2773
+#: builtin.c:3030
msgid "lshift: received non-numeric first argument"
msgstr "lshift: eerste argument is geen getal"
-#: builtin.c:2775
+#: builtin.c:3032
msgid "lshift: received non-numeric second argument"
msgstr "lshift: tweede argument is geen getal"
-#: builtin.c:2781
+#: builtin.c:3038
#, c-format
-msgid "lshift(%lf, %lf): negative values will give strange results"
-msgstr "lshift(%lf, %lf): negatieve waarden geven rare resultaten"
+msgid "lshift(%f, %f): negative values will give strange results"
+msgstr "lshift(%f, %f): negatieve waarden geven rare resultaten"
-#: builtin.c:2783
+#: builtin.c:3040
#, c-format
-msgid "lshift(%lf, %lf): fractional values will be truncated"
-msgstr "lshift(%lf, %lf): cijfers na de komma worden afgekapt"
+msgid "lshift(%f, %f): fractional values will be truncated"
+msgstr "lshift(%f, %f): cijfers na de komma worden afgekapt"
-#: builtin.c:2785
+#: builtin.c:3042
#, c-format
-msgid "lshift(%lf, %lf): too large shift value will give strange results"
-msgstr "lshift(%lf, %lf): te grote opschuifwaarden geven rare resultaten"
+msgid "lshift(%f, %f): too large shift value will give strange results"
+msgstr "lshift(%f, %f): te grote opschuifwaarden geven rare resultaten"
-#: builtin.c:2810
+#: builtin.c:3067
msgid "rshift: received non-numeric first argument"
msgstr "rshift: eerste argument is geen getal"
-#: builtin.c:2812
+#: builtin.c:3069
msgid "rshift: received non-numeric second argument"
msgstr "rshift: tweede argument is geen getal"
-#: builtin.c:2818
+#: builtin.c:3075
#, c-format
-msgid "rshift(%lf, %lf): negative values will give strange results"
-msgstr "rshift(%lf, %lf): negatieve waarden geven rare resultaten"
+msgid "rshift(%f, %f): negative values will give strange results"
+msgstr "rshift(%f, %f): negatieve waarden geven rare resultaten"
-#: builtin.c:2820
+#: builtin.c:3077
#, c-format
-msgid "rshift(%lf, %lf): fractional values will be truncated"
-msgstr "rshift(%lf, %lf): cijfers na de komma worden afgekapt"
+msgid "rshift(%f, %f): fractional values will be truncated"
+msgstr "rshift(%f, %f): cijfers na de komma worden afgekapt"
-#: builtin.c:2822
+#: builtin.c:3079
#, c-format
-msgid "rshift(%lf, %lf): too large shift value will give strange results"
-msgstr "rshift(%lf, %lf): te grote opschuifwaarden geven rare resultaten"
+msgid "rshift(%f, %f): too large shift value will give strange results"
+msgstr "rshift(%f, %f): te grote opschuifwaarden geven rare resultaten"
-#: builtin.c:2847
-msgid "and: received non-numeric first argument"
-msgstr "and: eerste argument is geen getal"
+#: builtin.c:3104 mpfr.c:968
+msgid "and: called with less than two arguments"
+msgstr "and: aangeroepen met minder dan twee argumenten"
-#: builtin.c:2849
-msgid "and: received non-numeric second argument"
-msgstr "and: tweede argument is geen getal"
-
-#: builtin.c:2855
+#: builtin.c:3109
#, c-format
-msgid "and(%lf, %lf): negative values will give strange results"
-msgstr "and(%lf, %lf): negatieve waarden geven rare resultaten"
+msgid "and: argument %d is non-numeric"
+msgstr "and: argument %d is niet-numeriek"
-#: builtin.c:2857
+#: builtin.c:3113
#, c-format
-msgid "and(%lf, %lf): fractional values will be truncated"
-msgstr "and(%lf, %lf): cijfers na de komma worden afgekapt"
-
-#: builtin.c:2882
-msgid "or: received non-numeric first argument"
-msgstr "or: eerste argument is geen getal"
+msgid "and: argument %d negative value %g will give strange results"
+msgstr "and: negatieve waarde %2$g van argument %1$d geeft rare resultaten"
-#: builtin.c:2884
-msgid "or: received non-numeric second argument"
-msgstr "or: tweede argument is geen getal"
+#: builtin.c:3136 mpfr.c:1000
+msgid "or: called with less than two arguments"
+msgstr "or: aangeroepen met minder dan twee argumenten"
-#: builtin.c:2890
+#: builtin.c:3141
#, c-format
-msgid "or(%lf, %lf): negative values will give strange results"
-msgstr "or(%lf, %lf): negatieve waarden geven rare resultaten"
+msgid "or: argument %d is non-numeric"
+msgstr "or: argument %d is niet-numeriek"
-#: builtin.c:2892
+#: builtin.c:3145
#, c-format
-msgid "or(%lf, %lf): fractional values will be truncated"
-msgstr "or(%lf, %lf): cijfers na de komma worden afgekapt"
-
-#: builtin.c:2920
-msgid "xor: received non-numeric first argument"
-msgstr "xor: eerste argument is geen getal"
+msgid "or: argument %d negative value %g will give strange results"
+msgstr "or: negatieve waarde %2$g van argument %1$d geeft rare resultaten"
-#: builtin.c:2922
-msgid "xor: received non-numeric second argument"
-msgstr "xor: tweede argument is geen getal"
+#: builtin.c:3167 mpfr.c:1031
+msgid "xor: called with less than two arguments"
+msgstr "xor: aangeroepen met minder dan twee argumenten"
-#: builtin.c:2928
+#: builtin.c:3173
#, c-format
-msgid "xor(%lf, %lf): negative values will give strange results"
-msgstr "xor(%lf, %lf): negatieve waarden geven rare resultaten"
+msgid "xor: argument %d is non-numeric"
+msgstr "xor: argument %d is niet-numeriek"
-#: builtin.c:2930
+#: builtin.c:3177
#, c-format
-msgid "xor(%lf, %lf): fractional values will be truncated"
-msgstr "xor(%lf, %lf): cijfers na de komma worden afgekapt"
+msgid "xor: argument %d negative value %g will give strange results"
+msgstr "xor: negatieve waarde %2$g van argument %1$d geeft rare resultaten"
-#: builtin.c:2954 builtin.c:2960
+#: builtin.c:3202 mpfr.c:787
msgid "compl: received non-numeric argument"
msgstr "compl: argument is geen getal"
-#: builtin.c:2962
+#: builtin.c:3208
#, c-format
-msgid "compl(%lf): negative value will give strange results"
-msgstr "compl(%lf): negatieve waarden geven rare resultaten"
+msgid "compl(%f): negative value will give strange results"
+msgstr "compl(%f): negatieve waarden geven rare resultaten"
-#: builtin.c:2964
+#: builtin.c:3210
#, c-format
-msgid "compl(%lf): fractional value will be truncated"
-msgstr "compl(%lf): cijfers na de komma worden afgekapt"
+msgid "compl(%f): fractional value will be truncated"
+msgstr "compl(%f): cijfers na de komma worden afgekapt"
-#: builtin.c:3133
+#: builtin.c:3379
#, c-format
msgid "dcgettext: `%s' is not a valid locale category"
msgstr "dcgettext: '%s' is geen geldige taalregio-deelcategorie"
-#: eval.c:412
+#: command.y:225
+#, c-format
+msgid "Type (g)awk statement(s). End with the command \"end\"\n"
+msgstr "Typ (g)awk statement(s). Eindig met het commando \"end\".\n"
+
+#: command.y:289
+#, c-format
+msgid "invalid frame number: %d"
+msgstr "ongeldig framenummer: %d"
+
+#: command.y:295
+#, c-format
+msgid "info: invalid option - \"%s\""
+msgstr "info: ongeldige optie -- \"%s\""
+
+#: command.y:321
+#, c-format
+msgid "source \"%s\": already sourced."
+msgstr "source \"%s\": is reeds ingelezen."
+
+#: command.y:326
+#, c-format
+msgid "save \"%s\": command not permitted."
+msgstr "save \"%s\": commando niet toegestaan."
+
+#: command.y:339
+msgid "Can't use command `commands' for breakpoint/watchpoint commands"
+msgstr ""
+"Kan commando 'commands' niet voor breekpunt-/kijkpunt-commando's gebruiken"
+
+#: command.y:341
+msgid "no breakpoint/watchpoint has been set yet"
+msgstr "er is nog geen breekpunt/kijkpunt gezet"
+
+#: command.y:343
+msgid "invalid breakpoint/watchpoint number"
+msgstr "ongeldig nummer van breekpunt/kijkpunt"
+
+#: command.y:348
+#, c-format
+msgid "Type commands for when %s %d is hit, one per line.\n"
+msgstr "Typ de commando's voor wanneer %s %d getroffen wordt, één per regel.\n"
+
+#: command.y:350
+#, c-format
+msgid "End with the command \"end\"\n"
+msgstr "Eindig met het commando 'end'.\n"
+
+#: command.y:357
+msgid "`end' valid only in command `commands' or `eval'"
+msgstr "'end' is alleen geldig bij de commando's 'commands' en 'eval'"
+
+#: command.y:367
+msgid "`silent' valid only in command `commands'"
+msgstr "'silent' is alleen geldig bij het commando 'commands'"
+
+#: command.y:373
+#, c-format
+msgid "trace: invalid option - \"%s\""
+msgstr "trace: ongeldige optie -- \"%s\""
+
+#: command.y:387
+msgid "condition: invalid breakpoint/watchpoint number"
+msgstr "condition: ongeldig nummer van breekpunt/kijkpunt"
+
+#: command.y:449
+msgid "argument not a string"
+msgstr "argument is geen string"
+
+#: command.y:459 command.y:464
+#, c-format
+msgid "option: invalid parameter - \"%s\""
+msgstr "option: ongeldige parameter -- \"%s\""
+
+#: command.y:474
+#, c-format
+msgid "no such function - \"%s\""
+msgstr "functie \"%s\" bestaat niet"
+
+#: command.y:531
+#, c-format
+msgid "enable: invalid option - \"%s\""
+msgstr "enable: ongeldige optie -- \"%s\""
+
+#: command.y:597
+#, c-format
+msgid "invalid range specification: %d - %d"
+msgstr "ongeldig bereik: %d - %d"
+
+#: command.y:659
+msgid "non-numeric value for field number"
+msgstr "niet-numerieke waarde voor veldnummer"
+
+#: command.y:680 command.y:687
+msgid "non-numeric value found, numeric expected"
+msgstr "niet-numerieke waarde gevonden, numerieke wordt verwacht"
+
+#: command.y:712 command.y:718
+msgid "non-zero integer value"
+msgstr "niet-nul geheel getal"
+
+#: command.y:817
+msgid ""
+"backtrace [N] - print trace of all or N innermost (outermost if N < 0) "
+"frames."
+msgstr ""
+"backtrace [N] - een trace weergeven van alle of N binnenste frames (of "
+"buitenste als N < 0)"
+
+#: command.y:819
+msgid ""
+"break [[filename:]N|function] - set breakpoint at the specified location."
+msgstr ""
+"break [[BESTANDSNAAM:]REGELNUMMER|FUNCTIE] - breekpunt zetten op gegeven "
+"positie"
+
+#: command.y:821
+msgid "clear [[filename:]N|function] - delete breakpoints previously set."
+msgstr ""
+"clear [[BESTANDSNAAM:]REGELNUMMER|FUNCTIE] - eerder gezet breekpunt "
+"verwijderen"
+
+#: command.y:823
+msgid ""
+"commands [num] - starts a list of commands to be executed at a "
+"breakpoint(watchpoint) hit."
+msgstr ""
+"commands [NUMMER] - een lijst van commando's beginnen die uitgevoerd moeten "
+"worden wanneer een breekpunt/kijkpunt getroffen wordt"
+
+#: command.y:825
+msgid "condition num [expr] - set or clear breakpoint or watchpoint condition."
+msgstr ""
+"condition NUMMER [EXPRESSIE] - de conditie van een breekpunt/kijkpunt zetten "
+"of wissen"
+
+#: command.y:827
+msgid "continue [COUNT] - continue program being debugged."
+msgstr "continue [AANTAL] - doorgaan met het programma in de debugger"
+
+#: command.y:829
+msgid "delete [breakpoints] [range] - delete specified breakpoints."
+msgstr "delete [BREEKPUNTEN] [BEREIK] - de gegeven breekpunten verwijderen"
+
+#: command.y:831
+msgid "disable [breakpoints] [range] - disable specified breakpoints."
+msgstr "disable [BREEKPUNTEN] [BEREIK] - de gegeven breekpunten uitschakelen"
+
+#: command.y:833
+msgid "display [var] - print value of variable each time the program stops."
+msgstr ""
+"display [VAR] - waarde van variabele weergeven elke keer dat het programma "
+"stopt"
+
+#: command.y:835
+msgid "down [N] - move N frames down the stack."
+msgstr "down [AANTAL] - dit aantal frames naar beneden in de stack gaan"
+
+#: command.y:837
+msgid "dump [filename] - dump instructions to file or stdout."
+msgstr ""
+"dump [BESTANDSNAAM] - instructies dumpen op standaarduitvoer (of naar "
+"bestand)"
+
+#: command.y:839
+msgid "enable [once|del] [breakpoints] [range] - enable specified breakpoints."
+msgstr ""
+"enable [once|del] [BREEKPUNTEN] [BEREIK] - de gegeven breekpunten inschakelen"
+
+#: command.y:841
+msgid "end - end a list of commands or awk statements."
+msgstr "end - een lijst van commando's of awk-statements beëindigen"
+
+#: command.y:843
+msgid "eval stmt|[p1, p2, ...] - evaluate awk statement(s)."
+msgstr "eval STATEMENT|[p1, p2, ...] - awk-statement(s) evalueren"
+
+#: command.y:845
+msgid "finish - execute until selected stack frame returns."
+msgstr "finish - uitvoeren totdat het geselecteerde stack-frame terugkeert"
+
+#: command.y:847
+msgid "frame [N] - select and print stack frame number N."
+msgstr "frame [NUMMER] - stack-frame met dit nummer selecteren en weergeven"
+
+#: command.y:849
+msgid "help [command] - print list of commands or explanation of command."
+msgstr ""
+"help [COMMANDO] - lijst van beschikbare commando's (of uitleg van commando) "
+"tonen"
+
+#: command.y:851
+msgid "ignore N COUNT - set ignore-count of breakpoint number N to COUNT."
+msgstr ""
+"ignore NUMMER AANTAL - het aantal keren dat dit breekpuntnummer genegeerd "
+"moet worden"
+
+#: command.y:853
+msgid ""
+"info topic - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch."
+msgstr ""
+"info THEMA - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch"
+
+#: command.y:855
+msgid "list [-|+|[filename:]lineno|function|range] - list specified line(s)."
+msgstr ""
+"list [-|+|[BESTANDSNAAM:]REGELNUMMER|FUNCTIE|BEREIK] - aangegeven regels "
+"tonen"
+
+#: command.y:857
+msgid "next [COUNT] - step program, proceeding through subroutine calls."
+msgstr ""
+"next [AANTAL] - programma uitvoeren tot de volgende bronregel bereikt is"
+
+#: command.y:859
+msgid ""
+"nexti [COUNT] - step one instruction, but proceed through subroutine calls."
+msgstr ""
+"nexti [AANTAL] - één instructie (of dit aantal) uitvoeren, waarbij een "
+"functie-aanroep als één telt"
+
+#: command.y:861
+msgid "option [name[=value]] - set or display debugger option(s)."
+msgstr "option [NAAM[=WAARDE]] - opties van debugger tonen of instellen"
+
+#: command.y:863
+msgid "print var [var] - print value of a variable or array."
+msgstr "print VAR [VAR] - waarde van variabele of array weergeven"
+
+#: command.y:865
+msgid "printf format, [arg], ... - formatted output."
+msgstr "printf OPMAAK [, ARGUMENT...] - opgemaakte uitvoer"
+
+#: command.y:867
+msgid "quit - exit debugger."
+msgstr "quit - de debugger verlaten"
+
+#: command.y:869
+msgid "return [value] - make selected stack frame return to its caller."
+msgstr "return [WAARDE] - gekozen stack-frame terug laten keren naar aanroeper"
+
+#: command.y:871
+msgid "run - start or restart executing program."
+msgstr "run - programma starten of herstarten"
+
+#: command.y:874
+msgid "save filename - save commands from the session to file."
+msgstr "save BESTANDSNAAM - commando's van de sessie opslaan in bestand"
+
+#: command.y:877
+msgid "set var = value - assign value to a scalar variable."
+msgstr "set VAR = WAARDE - een waarde aan een scalaire variabele toekennen"
+
+#: command.y:879
+msgid ""
+"silent - suspends usual message when stopped at a breakpoint/watchpoint."
+msgstr ""
+"silent - de gewone meldingen bij het stoppen bij een breekpunt/kijkpunt "
+"onderdrukken"
+
+#: command.y:881
+msgid "source file - execute commands from file."
+msgstr "source BESTANDSNAAM - commando's uit dit bestand uitvoeren"
+
+#: command.y:883
+msgid "step [COUNT] - step program until it reaches a different source line."
+msgstr ""
+"step [AANTAL] - programma uitvoeren tot een andere bronregel bereikt is"
+
+#: command.y:885
+msgid "stepi [COUNT] - step one instruction exactly."
+msgstr "stepi [AANTAL] - precies één (of dit aantal) instructies uitvoeren"
+
+#: command.y:887
+msgid "tbreak [[filename:]N|function] - set a temporary breakpoint."
+msgstr ""
+"tbreak [[BESTANDSNAAM:]REGELNUMMER|FUNCTIE] - een tijdelijk breekpunt zetten"
+
+#: command.y:889
+msgid "trace on|off - print instruction before executing."
+msgstr "trace on|off - instructie weergeven alvorens deze uit te voeren"
+
+#: command.y:891
+msgid "undisplay [N] - remove variable(s) from automatic display list."
+msgstr ""
+"undisplay [AANTAL] - variabele(n) van automatische weergavelijst verwijderen"
+
+#: command.y:893
+msgid ""
+"until [[filename:]N|function] - execute until program reaches a different "
+"line or line N within current frame."
+msgstr ""
+"until [[BESTANDSNAAM:]N|FUNCTIE] - programma uitvoeren totdat deze een "
+"andere regel bereikt of regel N binnen het huidige frame"
+
+#: command.y:895
+msgid "unwatch [N] - remove variable(s) from watch list."
+msgstr "unwatch [AANTAL] - variabele(n) van de kijklijst verwijderen"
+
+#: command.y:897
+msgid "up [N] - move N frames up the stack."
+msgstr "up [AANTAL] - dit aantal frames naar boven in de stack gaan"
+
+#: command.y:899
+msgid "watch var - set a watchpoint for a variable."
+msgstr "watch VAR - een kijkpunt voor een variabele zetten"
+
+#: command.y:1011 debug.c:401 msg.c:135
+#, c-format
+msgid "error: "
+msgstr "fout: "
+
+#: command.y:1051
+#, c-format
+msgid "can't read command (%s)\n"
+msgstr "kan commando niet lezen (%s)\n"
+
+#: command.y:1065
+#, c-format
+msgid "can't read command (%s)"
+msgstr "kan commando niet lezen (%s)"
+
+#: command.y:1116
+msgid "invalid character in command"
+msgstr "ongeldig teken in commando"
+
+#: command.y:1152
+#, c-format
+msgid "unknown command - \"%.*s\", try help"
+msgstr "onbekend commando - \"%.*s\", probeer help"
+
+#: command.y:1222
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: command.y:1284
+msgid "invalid character"
+msgstr "ongeldig teken"
+
+#: command.y:1455
+#, c-format
+msgid "undefined command: %s\n"
+msgstr "ongedefinieerd commando: %s\n"
+
+#: debug.c:252
+msgid "set or show the number of lines to keep in history file."
+msgstr "zetten of tonen van maximum aantal regels in geschiedenisbestand"
+
+#: debug.c:254
+msgid "set or show the list command window size."
+msgstr "zetten of tonen van venstergrootte van list-commando"
+
+#: debug.c:256
+msgid "set or show gawk output file."
+msgstr "zetten of tonen van gawk-uitvoerbestand"
+
+#: debug.c:258
+msgid "set or show debugger prompt."
+msgstr "zetten of tonen van debugger-prompt"
+
+#: debug.c:260
+msgid "(un)set or show saving of command history (value=on|off)."
+msgstr "zetten of tonen van opslaan van commandogeschiedenis (waarde=on|off)"
+
+#: debug.c:262
+msgid "(un)set or show saving of options (value=on|off)."
+msgstr "zetten of tonen van opslaan van opties (waarde=on|off)"
+
+#: debug.c:264
+msgid "(un)set or show instruction tracing (value=on|off)."
+msgstr "zetten of tonen van instructie-tracing (waarde=on|off)"
+
+#: debug.c:345
+msgid "program not running."
+msgstr "programma draait niet."
+
+#: debug.c:448 debug.c:606
+#, c-format
+msgid "can't read source file `%s' (%s)"
+msgstr "kan bronbestand '%s' niet lezen (%s)"
+
+#: debug.c:453
+#, c-format
+msgid "source file `%s' is empty.\n"
+msgstr "bronbestand '%s' is leeg\n"
+
+#: debug.c:480
+msgid "no current source file."
+msgstr "geen huidig bronbestand"
+
+#: debug.c:505
+#, c-format
+msgid "cannot find source file named `%s' (%s)"
+msgstr "kan geen bronbestand met naam '%s' vinden (%s)"
+
+#: debug.c:529
+#, c-format
+msgid "WARNING: source file `%s' modified since program compilation.\n"
+msgstr ""
+"Waarschuwing: bronbestand '%s' is gewijzigd sinds programmacompilatie.\n"
+
+#: debug.c:551
+#, c-format
+msgid "line number %d out of range; `%s' has %d lines"
+msgstr "regelnummer %d valt buiten bereik; '%s' heeft %d regels"
+
+#: debug.c:611
+#, c-format
+msgid "unexpected eof while reading file `%s', line %d"
+msgstr "onverwacht einde-van-bestand tijdens lezen van bestand '%s', regel %d"
+
+#: debug.c:620
+#, c-format
+msgid "source file `%s' modified since start of program execution"
+msgstr "bronbestand '%s' is gewijzigd sinds start van programma-uitvoering"
+
+#: debug.c:732
+#, c-format
+msgid "Current source file: %s\n"
+msgstr "Huidig bronbestand: %s\n"
+
+#: debug.c:733
+#, c-format
+msgid "Number of lines: %d\n"
+msgstr "Aantal regels: %d\n"
+
+#: debug.c:740
+#, c-format
+msgid "Source file (lines): %s (%d)\n"
+msgstr "Bronbestand (regels): %s (%d)\n"
+
+#: debug.c:754
+msgid ""
+"Number Disp Enabled Location\n"
+"\n"
+msgstr ""
+"Nummer Toon Actief Locatie\n"
+"\n"
+
+#: debug.c:765
+#, c-format
+msgid "\tno of hits = %ld\n"
+msgstr "\taantal treffers = %ld\n"
+
+#: debug.c:767
+#, c-format
+msgid "\tignore next %ld hit(s)\n"
+msgstr "\tvolgende %ld treffer(s) negeren\n"
+
+#: debug.c:769 debug.c:909
+#, c-format
+msgid "\tstop condition: %s\n"
+msgstr "\tstopconditie: %s\n"
+
+#: debug.c:771 debug.c:911
+msgid "\tcommands:\n"
+msgstr "\tcommando's:\n"
+
+#: debug.c:793
+#, c-format
+msgid "Current frame: "
+msgstr "Huidig frame: "
+
+#: debug.c:796
+#, c-format
+msgid "Called by frame: "
+msgstr "Aangeroepen door frame: "
+
+#: debug.c:800
+#, c-format
+msgid "Caller of frame: "
+msgstr "Aanroeper van frame: "
+
+#: debug.c:818
+#, c-format
+msgid "None in main().\n"
+msgstr "Geen in main().\n"
+
+#: debug.c:848
+msgid "No arguments.\n"
+msgstr "Geen argumenten.\n"
+
+#: debug.c:849
+msgid "No locals.\n"
+msgstr "Geen lokalen.\n"
+
+#: debug.c:857
+msgid ""
+"All defined variables:\n"
+"\n"
+msgstr ""
+"Alle gedefinieerde variabelen:\n"
+"\n"
+
+#: debug.c:867
+msgid ""
+"All defined functions:\n"
+"\n"
+msgstr ""
+"Alle gedefinieerde functies:\n"
+"\n"
+
+#: debug.c:886
+msgid ""
+"Auto-display variables:\n"
+"\n"
+msgstr ""
+"Automatisch weer te geven variabelen:\n"
+"\n"
+
+#: debug.c:889
+msgid ""
+"Watch variables:\n"
+"\n"
+msgstr ""
+"Kijkvariabelen:\n"
+"\n"
+
+#: debug.c:1029
+#, c-format
+msgid "no symbol `%s' in current context\n"
+msgstr "geen symbool '%s' in huidige context\n"
+
+#: debug.c:1041 debug.c:1427
+#, c-format
+msgid "`%s' is not an array\n"
+msgstr "'%s' is geen array\n"
+
+#: debug.c:1055
+#, c-format
+msgid "$%ld = uninitialized field\n"
+msgstr "$%ld = ongeïnitialiseerd veld\n"
+
+#: debug.c:1076
+#, c-format
+msgid "array `%s' is empty\n"
+msgstr "array '%s' is leeg\n"
+
+#: debug.c:1119 debug.c:1171
+#, c-format
+msgid "[\"%s\"] not in array `%s'\n"
+msgstr "[\"%s\"] niet in array '%s'\n"
+
+#: debug.c:1175
+#, c-format
+msgid "`%s[\"%s\"]' is not an array\n"
+msgstr "'%s[\"%s\"]' is geen array\n"
+
+#: debug.c:1236 debug.c:4964
+#, c-format
+msgid "`%s' is not a scalar variable"
+msgstr "'%s' is geen scalaire variabele"
+
+#: debug.c:1258 debug.c:4994
+#, c-format
+msgid "attempt to use array `%s[\"%s\"]' in a scalar context"
+msgstr "array '%s[\"%s\"]' wordt gebruikt in een scalaire context"
+
+#: debug.c:1280 debug.c:5005
+#, c-format
+msgid "attempt to use scalar `%s[\"%s\"]' as array"
+msgstr "scalair '%s[\"%s\"]' wordt gebruikt als array"
+
+#: debug.c:1423
+#, c-format
+msgid "`%s' is a function"
+msgstr "'%s' is een functie"
+
+#: debug.c:1465
+#, c-format
+msgid "watchpoint %d is unconditional\n"
+msgstr "kijkpunt %d is zonder conditie\n"
+
+#: debug.c:1499
+#, c-format
+msgid "No display item numbered %ld"
+msgstr "Er is geen weergave-item met nummer %ld"
+
+#: debug.c:1502
+#, c-format
+msgid "No watch item numbered %ld"
+msgstr "Er is geen kijk-item met nummer %ld"
+
+#: debug.c:1528
+#, c-format
+msgid "%d: [\"%s\"] not in array `%s'\n"
+msgstr "%d: [\"%s\"] niet in array '%s'\n"
+
+#: debug.c:1767
+msgid "attempt to use scalar value as array"
+msgstr "scalaire waarde wordt gebruikt als array"
+
+#: debug.c:1856
+#, c-format
+msgid "Watchpoint %d deleted because parameter is out of scope.\n"
+msgstr "Kijkpunt %d is verwijderd omdat parameter buiten bereik is.\n"
+
+#: debug.c:1867
+#, c-format
+msgid "Display %d deleted because parameter is out of scope.\n"
+msgstr "Weergave %d is verwijderd omdat parameter buiten bereik is.\n"
+
+#: debug.c:1900
+#, c-format
+msgid " in file `%s', line %d\n"
+msgstr " in bestand '%s', regel %d\n"
+
+#: debug.c:1921
+#, c-format
+msgid " at `%s':%d"
+msgstr " op '%s':%d"
+
+#: debug.c:1937 debug.c:2000
+#, c-format
+msgid "#%ld\tin "
+msgstr "#%ld\tin "
+
+#: debug.c:1974
+#, c-format
+msgid "More stack frames follow ...\n"
+msgstr "Er volgen meer stack-frames...\n"
+
+#: debug.c:2017
+msgid "invalid frame number"
+msgstr "ongeldig framenummer"
+
+#: debug.c:2200
+#, c-format
+msgid "Note: breakpoint %d (enabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+"Opmerking: breekpunt %d (ingeschakeld, volgende %ld passages genegeerd), ook "
+"gezet op %s:%d"
+
+#: debug.c:2207
+#, c-format
+msgid "Note: breakpoint %d (enabled), also set at %s:%d"
+msgstr "Opmerking: breekpunt %d (ingeschakeld), ook gezet op %s:%d"
+
+#: debug.c:2214
+#, c-format
+msgid "Note: breakpoint %d (disabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+"Opmerking: breekpunt %d (uitgeschakeld, volgende %ld passages genegeerd), "
+"ook gezet op %s:%d"
+
+#: debug.c:2221
+#, c-format
+msgid "Note: breakpoint %d (disabled), also set at %s:%d"
+msgstr "Opmerking: breekpunt %d (uitgeschakeld), ook gezet op %s:%d"
+
+#: debug.c:2238
+#, c-format
+msgid "Breakpoint %d set at file `%s', line %d\n"
+msgstr "Breekpunt %d is gezet in bestand '%s', op regel %d\n"
+
+#: debug.c:2340
+#, c-format
+msgid "Can't set breakpoint in file `%s'\n"
+msgstr "Kan geen breekpunt zetten in bestand '%s'\n"
+
+#: debug.c:2369 debug.c:2492 debug.c:3350
+#, c-format
+msgid "line number %d in file `%s' out of range"
+msgstr "regelnummer %d in bestand '%s' valt buiten bereik"
+
+#: debug.c:2373
+#, c-format
+msgid "Can't find rule!!!\n"
+msgstr "Kan regel niet vinden!!!\n"
+
+#: debug.c:2375
+#, c-format
+msgid "Can't set breakpoint at `%s':%d\n"
+msgstr "Kan geen breekpunt zetten op '%s':%d\n"
+
+#: debug.c:2387
+#, c-format
+msgid "Can't set breakpoint in function `%s'\n"
+msgstr "Kan geen breekpunt zetten in functie '%s'\n"
+
+#: debug.c:2403
+#, c-format
+msgid "breakpoint %d set at file `%s', line %d is unconditional\n"
+msgstr "breekpunt %d (gezet in bestand '%s', op regel %d) is onconditioneel\n"
+
+#: debug.c:2508 debug.c:2530
+#, c-format
+msgid "Deleted breakpoint %d"
+msgstr "Breekpunt %d is verwijderd"
+
+#: debug.c:2514
+#, c-format
+msgid "No breakpoint(s) at entry to function `%s'\n"
+msgstr "Geen breekpunt(en) bij binnengaan van functie '%s'\n"
+
+#: debug.c:2541
+#, c-format
+msgid "No breakpoint at file `%s', line #%d\n"
+msgstr "Geen breekpunt in bestand '%s', op regel #%d\n"
+
+#: debug.c:2596 debug.c:2637 debug.c:2657 debug.c:2700
+msgid "invalid breakpoint number"
+msgstr "ongeldig breekpuntnummer"
+
+#: debug.c:2612
+msgid "Delete all breakpoints? (y or n) "
+msgstr "Alle breekpunten verwijderen? (j of n) "
+
+#: debug.c:2613 debug.c:2923 debug.c:2976
+msgid "y"
+msgstr "j"
+
+#: debug.c:2662
+#, c-format
+msgid "Will ignore next %ld crossing(s) of breakpoint %d.\n"
+msgstr "Zal de volgende %ld passage(s) van breekpunt %d negeren.\n"
+
+#: debug.c:2666
+#, c-format
+msgid "Will stop next time breakpoint %d is reached.\n"
+msgstr "Zal de volgende keer dat breekpunt %d wordt bereikt stoppen.\n"
+
+#: debug.c:2783
+#, c-format
+msgid "Can only debug programs provided with the `-f' option.\n"
+msgstr "Kan alleen programma's debuggen die met optie '-f' gegeven zijn.\n"
+
+#: debug.c:2908
+#, c-format
+msgid "Failed to restart debugger"
+msgstr "Herstarten van debugger is mislukt"
+
+#: debug.c:2922
+msgid "Program already running. Restart from beginning (y/n)? "
+msgstr "Programma draait al. Herstarten vanaf begin (j/n)? "
+
+#: debug.c:2926
+#, c-format
+msgid "Program not restarted\n"
+msgstr "Programma is niet herstart\n"
+
+#: debug.c:2936
+#, c-format
+msgid "error: cannot restart, operation not allowed\n"
+msgstr "fout: kan niet herstarten; operatie is niet toegestaan\n"
+
+#: debug.c:2942
+#, c-format
+msgid "error (%s): cannot restart, ignoring rest of the commands\n"
+msgstr ""
+"fout(%s): kan niet herstarten; de resterende commando's worden genegeerd\n"
+
+#: debug.c:2950
+#, c-format
+msgid "Starting program: \n"
+msgstr "Starten van programma: \n"
+
+#: debug.c:2959
+#, c-format
+msgid "Program exited %s with exit value: %d\n"
+msgstr "Programma verliet %s met afsluitwaarde %d\n"
+
+#: debug.c:2975
+msgid "The program is running. Exit anyway (y/n)? "
+msgstr "Het programma draait. Toch afsluiten (j/n)? "
+
+#: debug.c:3010
+#, c-format
+msgid "Not stopped at any breakpoint; argument ignored.\n"
+msgstr "Niet gestopt op een breekpunt; argument is genegeerd.\n"
+
+#: debug.c:3015
+#, c-format
+msgid "invalid breakpoint number %d."
+msgstr "ongeldig breekpuntnummer %d."
+
+#: debug.c:3020
+#, c-format
+msgid "Will ignore next %ld crossings of breakpoint %d.\n"
+msgstr "Zal de volgende %ld passages van breekpunt %d negeren.\n"
+
+#: debug.c:3207
+#, c-format
+msgid "'finish' not meaningful in the outermost frame main()\n"
+msgstr "'finish' is niet zinvol in het buitenste frame van main()\n"
+
+#: debug.c:3212
+#, c-format
+msgid "Run till return from "
+msgstr "Draaien tot terugkeer uit "
+
+#: debug.c:3255
+#, c-format
+msgid "'return' not meaningful in the outermost frame main()\n"
+msgstr "'return' is niet zinvol in het buitenste frame van main()\n"
+
+#: debug.c:3369
+#, c-format
+msgid "Can't find specified location in function `%s'\n"
+msgstr "Kan gegeven locatie in functie '%s' niet vinden\n"
+
+#: debug.c:3377
+#, c-format
+msgid "invalid source line %d in file `%s'"
+msgstr "ongeldige bronregel %d in bestand '%s'"
+
+#: debug.c:3392
+#, c-format
+msgid "Can't find specified location %d in file `%s'\n"
+msgstr "Kan gegeven locatie %d in bestand '%s' niet vinden\n"
+
+#: debug.c:3424
+#, c-format
+msgid "element not in array\n"
+msgstr "element niet in array\n"
+
+#: debug.c:3424
+#, c-format
+msgid "untyped variable\n"
+msgstr "ongetypeerde variabele\n"
+
+#: debug.c:3466
+#, c-format
+msgid "Stopping in %s ...\n"
+msgstr "Stoppend in %s...\n"
+
+#: debug.c:3543
+#, c-format
+msgid "'finish' not meaningful with non-local jump '%s'\n"
+msgstr "'finish' is niet zinvol met een niet-lokale sprong '%s'\n"
+
+#: debug.c:3550
+#, c-format
+msgid "'until' not meaningful with non-local jump '%s'\n"
+msgstr "'until' is niet zinvol met een niet-lokale sprong '%s'\n"
+
+#: debug.c:4185
+msgid "\t------[Enter] to continue or q [Enter] to quit------"
+msgstr ""
+"\t------[Enter] om verder te gaan, of [q] [Enter] om af te sluiten------"
+
+#: debug.c:4186
+msgid "q"
+msgstr "q"
+
+#: debug.c:5001
+#, c-format
+msgid "[\"%s\"] not in array `%s'"
+msgstr "[\"%s\"] niet in array '%s'"
+
+#: debug.c:5207
+#, c-format
+msgid "sending output to stdout\n"
+msgstr "uitvoer wordt naar standaarduitvoer gestuurd\n"
+
+#: debug.c:5247
+msgid "invalid number"
+msgstr "ongeldig nummer"
+
+#: debug.c:5381
+#, c-format
+msgid "`%s' not allowed in current context; statement ignored"
+msgstr "'%s' is niet toegestaan in huidige context; statement is genegeerd"
+
+#: debug.c:5389
+msgid "`return' not allowed in current context; statement ignored"
+msgstr "'return' is niet toegestaan in huidige context; statement is genegeerd"
+
+#: debug.c:5590
+#, c-format
+msgid "No symbol `%s' in current context"
+msgstr "Geen symbool '%s' in huidige context"
+
+#: dfa.c:1118 dfa.c:1121 dfa.c:1142 dfa.c:1150 dfa.c:1162 dfa.c:1197
+#: dfa.c:1206 dfa.c:1209 dfa.c:1214 dfa.c:1228 dfa.c:1275
+msgid "unbalanced ["
+msgstr "ongepaarde ["
+
+#: dfa.c:1174
+msgid "invalid character class"
+msgstr "ongeldige tekenklasse"
+
+#: dfa.c:1316
+msgid "character class syntax is [[:space:]], not [:space:]"
+msgstr "syntax van tekenklasse is [[:space:]], niet [:space:]"
+
+#: dfa.c:1366
+msgid "unfinished \\ escape"
+msgstr "onafgemaakte \\-stuurcode"
+
+#: dfa.c:1513 regcomp.c:161
+msgid "Invalid content of \\{\\}"
+msgstr "Ongeldige inhoud van \\{\\}"
+
+#: dfa.c:1516 regcomp.c:176
+msgid "Regular expression too big"
+msgstr "Reguliere expressie is te groot"
+
+#: dfa.c:1936
+msgid "unbalanced ("
+msgstr "ongepaarde ("
+
+#: dfa.c:2062
+msgid "no syntax specified"
+msgstr "geen syntax opgegeven"
+
+#: dfa.c:2070
+msgid "unbalanced )"
+msgstr "ongepaarde )"
+
+#: eval.c:394
#, c-format
msgid "unknown nodetype %d"
msgstr "onbekend knooptype %d"
-#: eval.c:423 eval.c:437
+#: eval.c:405 eval.c:419
#, c-format
msgid "unknown opcode %d"
msgstr "onbekende opcode %d"
-#: eval.c:434
+#: eval.c:416
#, c-format
msgid "opcode %s not an operator or keyword"
msgstr "opcode %s is geen operator noch sleutelwoord"
-#: eval.c:488
+#: eval.c:472
msgid "buffer overflow in genflags2str"
msgstr "bufferoverloop in genflags2str()"
-#: eval.c:698
+#: eval.c:675
#, c-format
msgid ""
"\n"
@@ -990,822 +1883,1244 @@ msgstr ""
"\t# Functieaanroepen-stack:\n"
"\n"
-#: eval.c:725
+#: eval.c:704
msgid "`IGNORECASE' is a gawk extension"
msgstr "'IGNORECASE' is een gawk-uitbreiding"
-#: eval.c:754
+#: eval.c:736
msgid "`BINMODE' is a gawk extension"
msgstr "'BINMODE' is een gawk-uitbreiding"
-#: eval.c:812
+#: eval.c:794
#, c-format
msgid "BINMODE value `%s' is invalid, treated as 3"
msgstr "BINMODE-waarde '%s' is ongeldig, wordt behandeld als 3"
-#: eval.c:902
+#: eval.c:885
#, c-format
msgid "bad `%sFMT' specification `%s'"
msgstr "onjuiste opgave van '%sFMT': '%s'"
-#: eval.c:980
+#: eval.c:969
msgid "turning off `--lint' due to assignment to `LINT'"
msgstr "'--lint' wordt uitgeschakeld wegens toewijzing aan 'LINT'"
-#: eval.c:1127 eval.c:1777
-#, 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:1158 eval.c:1789 eval.c:1802
+#: eval.c:1147
#, c-format
msgid "reference to uninitialized argument `%s'"
msgstr "verwijzing naar ongeïnitialiseerd argument '%s'"
-#: eval.c:1177
+#: eval.c:1148
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "verwijzing naar ongeïnitialiseerde variabele '%s'"
+
+#: eval.c:1166
msgid "attempt to field reference from non-numeric value"
msgstr "veldverwijzingspoging via een waarde die geen getal is"
-#: eval.c:1179
+#: eval.c:1168
msgid "attempt to field reference from null string"
msgstr "veldverwijzingspoging via een lege string"
-#: eval.c:1185
+#: eval.c:1176
#, c-format
msgid "attempt to access field %ld"
msgstr "toegangspoging tot veld %ld"
-#: eval.c:1194
+#: eval.c:1185
#, c-format
msgid "reference to uninitialized field `$%ld'"
msgstr "verwijzing naar ongeïnitialiseerd veld '$%ld'"
-#: eval.c:1256
+#: eval.c:1272
#, c-format
msgid "function `%s' called with more arguments than declared"
msgstr "functie '%s' aangeroepen met meer argumenten dan gedeclareerd"
-#: eval.c:1437
+#: eval.c:1473
#, c-format
msgid "unwind_stack: unexpected type `%s'"
msgstr "unwind_stack(): onverwacht type '%s'"
-#: eval.c:1532
+#: eval.c:1569
msgid "division by zero attempted in `/='"
msgstr "deling door nul in '/='"
-#: eval.c:1539
+#: eval.c:1576
#, c-format
msgid "division by zero attempted in `%%='"
msgstr "deling door nul in '%%='"
-#: eval.c:1876 eval.c:2122
-#, c-format
-msgid "attempt to use array `%s[\"%.*s\"]' in a scalar context"
-msgstr "array '%s[\"%.*s\"]' wordt gebruikt in een scalaire context"
+#: ext.c:89 ext.c:171
+msgid "extensions are not allowed in sandbox mode"
+msgstr "uitbreidingen zijn niet toegestaan in sandbox-modus"
-#: eval.c:1907
-msgid "assignment used in conditional context"
-msgstr "toewijzing wordt gebruikt in een conditionele context"
+#: ext.c:92
+msgid "-l / @load are gawk extensions"
+msgstr "-l / '@load' zijn gawk-uitbreidingen"
-#: eval.c:1911
-msgid "statement has no effect"
-msgstr "opdracht heeft geen effect"
+#: ext.c:95
+msgid "load_ext: received NULL lib_name"
+msgstr "load_ext: lege bibliotheeknaam ontvangen"
-#: eval.c:2343
+#: ext.c:98
#, 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"
+msgid "load_ext: cannot open library `%s' (%s)\n"
+msgstr "load_ext: kan bibliotheek '%s' niet openen (%s)\n"
-#: eval.c:2458
+#: ext.c:104
#, c-format
-msgid "function called indirectly through `%s' does not exist"
-msgstr "indirect (via '%s') aangeroepen functie bestaat niet"
+msgid ""
+"load_ext: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"
+msgstr ""
+"load_ext: bibliotheek '%s' definieert 'plugin_is_GPL_compatible' niet (%s)\n"
-#: eval.c:2470
+#: ext.c:110
#, c-format
-msgid "function `%s' not defined"
-msgstr "functie '%s' is niet gedefinieerd"
+msgid "load_ext: library `%s': cannot call function `%s' (%s)\n"
+msgstr "load_ext: bibliotheek '%s' kan functie '%s' niet aanroepen (%s)\n"
-#: eval.c:2511
+#: ext.c:114
#, c-format
-msgid "non-redirected `getline' invalid inside `%s' rule"
-msgstr "niet-omgeleide 'getline' is ongeldig binnen een '%s'-regel"
+msgid "load_ext: library `%s' initialization routine `%s' failed\n"
+msgstr "load_ext: bibliotheek '%s': initialisatiefunctie '%s' is mislukt\n"
-#: eval.c:2600
-#, c-format
-msgid "error reading input file `%s': %s"
-msgstr "fout tijdens lezen van invoerbestand '%s': %s"
+#: ext.c:174
+msgid "`extension' is a gawk extension"
+msgstr "'extension' is een gawk-uitbreiding"
+
+#: ext.c:177
+msgid "extension: received NULL lib_name"
+msgstr "uitbreiding: lege bibliotheeknaam ontvangen"
-#: eval.c:2614
+#: ext.c:180
#, c-format
-msgid "`nextfile' cannot be called from a `%s' rule"
-msgstr "'nextfile' kan niet aangeroepen worden in een '%s'-regel"
+msgid "extension: cannot open library `%s' (%s)"
+msgstr "extension: kan bibliotheek '%s' niet openen (%s)"
-#: eval.c:2694
+#: ext.c:186
#, c-format
-msgid "`next' cannot be called from a `%s' rule"
-msgstr "'next' kan niet aangeroepen worden in een '%s'-regel"
+msgid ""
+"extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)"
+msgstr ""
+"extension: bibliotheek '%s' definieert 'plugin_is_GPL_compatible' niet (%s)"
-#: eval.c:2760
+#: ext.c:190
#, c-format
-msgid "Sorry, don't know how to interpret `%s'"
-msgstr "Kan '%s' niet interpreteren"
+msgid "extension: library `%s': cannot call function `%s' (%s)"
+msgstr "extension: bibliotheek '%s' kan functie '%s' niet aanroepen (%s)"
-#: ext.c:64
-msgid "extensions are not allowed in sandbox mode"
-msgstr "uitbreidingen zijn niet toegestaan in sandbox-modus"
+#: ext.c:221
+msgid "make_builtin: missing function name"
+msgstr "make_builtin: ontbrekende functienaam"
-#: ext.c:70 ext.c:75
-msgid "`extension' is a gawk extension"
-msgstr "'extension' is een gawk-uitbreiding"
+#: ext.c:236
+#, c-format
+msgid "make_builtin: can't redefine function `%s'"
+msgstr "make_builtin: kan functie '%s' niet herdefiniëren"
-#: ext.c:85
+#: ext.c:240
#, c-format
-msgid "fatal: extension: cannot open `%s' (%s)\n"
-msgstr "fatale fout: extension: kan '%s' niet openen (%s)\n"
+msgid "make_builtin: function `%s' already defined"
+msgstr "make_builtin: functie '%s' is al gedefinieerd"
-#: ext.c:94
+#: ext.c:244
#, c-format
-msgid ""
-"fatal: extension: library `%s': does not define "
-"`plugin_is_GPL_compatible' (%s)\n"
-msgstr ""
-"fatale fout: extension: bibliotheek '%s': definieert "
-"'plugin_is_GPL_compatible' niet (%s)\n"
+msgid "make_builtin: function name `%s' previously defined"
+msgstr "make_builtin: functienaam '%s' is al eerder gedefinieerd"
-#: ext.c:103
+#: ext.c:246
#, c-format
-msgid "fatal: extension: library `%s': cannot call function `%s' (%s)\n"
+msgid "make_builtin: can't use gawk built-in `%s' as function name"
msgstr ""
-"fatale fout: extension: bibliotheek '%s': kan functie '%s' niet aanroepen "
-"(%s)\n"
+"make_builtin: kan in gawk ingebouwde '%s' niet als functienaam gebruiken"
-#: ext.c:137
+#: ext.c:249 ext.c:304
+#, c-format
+msgid "make_builtin: negative argument count for function `%s'"
+msgstr "make_builtin: negatief aantal argumenten voor functie '%s'"
+
+#: ext.c:276
msgid "extension: missing function name"
msgstr "extension: ontbrekende functienaam"
-#: ext.c:142
+#: ext.c:279 ext.c:283
#, c-format
msgid "extension: illegal character `%c' in function name `%s'"
msgstr "extension: ongeldig teken '%c' in functienaam '%s'"
-#: ext.c:151
+#: ext.c:291
#, c-format
msgid "extension: can't redefine function `%s'"
msgstr "extension: kan functie '%s' niet herdefiniëren"
-#: ext.c:155
+#: ext.c:295
#, c-format
msgid "extension: function `%s' already defined"
msgstr "extension: functie '%s' is al gedefinieerd"
-#: ext.c:160
+#: ext.c:299
#, c-format
msgid "extension: function name `%s' previously defined"
msgstr "extension: functienaam '%s' is al eerder gedefinieerd"
-#: ext.c:162
+#: ext.c:301
#, 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:166
-#, c-format
-msgid "make_builtin: negative argument count for function `%s'"
-msgstr "make_builtin: negatief aantal argumenten voor functie '%s'"
-
-#: ext.c:269
+#: ext.c:375
#, 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:272
+#: ext.c:378
#, c-format
msgid "function `%s': missing argument #%d"
msgstr "functie '%s': ontbrekend argument #%d"
-#: ext.c:289
+#: ext.c:395
#, 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:293
+#: ext.c:399
#, 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:306
-msgid "Operation Not Supported"
-msgstr "Actie wordt niet ondersteund"
+#: ext.c:413
+msgid "dynamic loading of library not supported"
+msgstr "het dynamisch laden van de bibliotheek wordt niet ondersteund"
+
+#: extension/filefuncs.c:159
+msgid "chdir: called with incorrect number of arguments, expecting 1"
+msgstr ""
+"chdir: aangeroepen met onjuist aantal argumenten; één wordt er verwacht"
+
+#: extension/filefuncs.c:439
+#, c-format
+msgid "stat: unable to read symbolic link `%s'"
+msgstr "stat: kan symbolische koppeling '%s' niet lezen"
+
+#: extension/filefuncs.c:472
+msgid "stat: called with wrong number of arguments"
+msgstr "stat: aangeroepen met onjuist aantal argumenten"
+
+#: extension/filefuncs.c:479
+msgid "stat: bad parameters"
+msgstr "stat: onjuiste parameters"
+
+#: extension/filefuncs.c:533
+#, c-format
+msgid "fts init: could not create variable %s"
+msgstr "fts-initialisatie: kan variabele %s niet aanmaken"
+
+#: extension/filefuncs.c:554
+msgid "fts is not supported on this system"
+msgstr "'fts' wordt op dit systeem niet ondersteund"
+
+#: extension/filefuncs.c:573
+msgid "fill_stat_element: could not create array"
+msgstr "fill_stat_element: kan array niet aanmaken"
+
+#: extension/filefuncs.c:582
+msgid "fill_stat_element: could not set element"
+msgstr "fill_stat_element: kan element niet instellen"
+
+#: extension/filefuncs.c:597
+msgid "fill_path_element: could not set element"
+msgstr "fill_path_element: kan element niet instellen"
+
+#: extension/filefuncs.c:613
+msgid "fill_error_element: could not set element"
+msgstr "fill_error_element: kan element niet instellen"
+
+#: extension/filefuncs.c:660 extension/filefuncs.c:707
+msgid "fts-process: could not create array"
+msgstr "fts-verwerking: kan array niet aanmaken"
+
+#: extension/filefuncs.c:670 extension/filefuncs.c:717
+#: extension/filefuncs.c:735
+msgid "fts-process: could not set element"
+msgstr "fts-verwerking: kan element niet instellen"
+
+#: extension/filefuncs.c:784
+msgid "fts: called with incorrect number of arguments, expecting 3"
+msgstr ""
+"fts: aangeroepen met onjuist aantal argumenten; drie worden er verwacht"
+
+#: extension/filefuncs.c:787
+msgid "fts: bad first parameter"
+msgstr "fts: onjuiste eerste parameter"
+
+#: extension/filefuncs.c:793
+msgid "fts: bad second parameter"
+msgstr "fts: onjuiste tweede parameter"
+
+#: extension/filefuncs.c:799
+msgid "fts: bad third parameter"
+msgstr "fts: onjuiste derde parameter"
+
+#: extension/filefuncs.c:806
+msgid "fts: could not flatten array\n"
+msgstr "fts: kan array niet pletten\n"
+
+#: extension/filefuncs.c:824
+msgid "fts: ignoring sneaky FTS_NOSTAT flag. nyah, nyah, nyah."
+msgstr "fts: listige FTS_NOSTAT-vlag wordt genegeerd -- lekker puh :)"
+
+#: extension/filefuncs.c:841
+msgid "fts: clear_array() failed\n"
+msgstr "fts: clear_array() is mislukt\n"
+
+#: extension/fnmatch.c:112
+msgid "fnmatch: called with less than three arguments"
+msgstr "fnmatch: aangeroepen met minder dan drie argumenten"
+
+#: extension/fnmatch.c:115
+msgid "fnmatch: called with more than three arguments"
+msgstr "fnmatch: aangeroepen met meer dan drie argumenten"
+
+#: extension/fnmatch.c:118
+msgid "fnmatch: could not get first argument"
+msgstr "fnmatch: kan eerste argument niet verkrijgen"
+
+#: extension/fnmatch.c:123
+msgid "fnmatch: could not get second argument"
+msgstr "fnmatch: kan tweede argument niet verkrijgen"
+
+#: extension/fnmatch.c:128
+msgid "fnmatch: could not get third argument"
+msgstr "fnmatch: kan derde argument niet verkrijgen"
+
+#: extension/fnmatch.c:141
+msgid "fnmatch is not implemented on this system\n"
+msgstr "'fnmatch' is niet geïmplementeerd op dit systeem\n"
+
+#: extension/fnmatch.c:173
+msgid "fnmatch init: could not add FNM_NOMATCH variable"
+msgstr "fnmatch()-initialisatie: kan de variabele FNM_NOMATCH niet toevoegen"
+
+#: extension/fnmatch.c:183
+#, c-format
+msgid "fnmatch init: could not set array element %s"
+msgstr "fnmatch()-initialisatie: kan array-element %s niet instellen"
+
+#: extension/fnmatch.c:193
+msgid "fnmatch init: could not install FNM array"
+msgstr "fnmatch()-initialisatie: kan array FNM niet installeren"
+
+#: extension/fork.c:81
+msgid "fork: called with too many arguments"
+msgstr "fork: aangeroepen met te veel argumenten"
+
+#: extension/fork.c:94
+msgid "fork: PROCINFO is not an array!"
+msgstr "fork: PROCINFO is geen array!"
+
+#: extension/fork.c:118
+msgid "waitpid: called with too many arguments"
+msgstr "waitpid: aangeroepen met te veel argumenten"
+
+#: extension/fork.c:126
+msgid "wait: called with no arguments"
+msgstr "wait: aangeroepen zonder argumenten"
+
+#: extension/fork.c:143
+msgid "wait: called with too many arguments"
+msgstr "wait: aangeroepen met te veel argumenten"
+
+#: extension/inplace.c:130
+msgid "inplace_begin: in-place editing already active"
+msgstr "inplace_begin(): in-situ-bewerken is al actief"
+
+#: extension/inplace.c:133 extension/inplace.c:207
+#, c-format
+msgid "inplace_begin: expects 2 arguments but called with %d"
+msgstr "inplace_begin(): verwachtte twee argumenten maar is aangeroepen met %d"
+
+#: extension/inplace.c:136
+msgid "inplace_begin: cannot retrieve 1st argument as a string filename"
+msgstr ""
+"inplace_begin(): kan eerste argument niet als bestandsnaamstring oppakken"
+
+#: extension/inplace.c:144
+#, c-format
+msgid "inplace_begin: disabling in-place editing for invalid FILENAME `%s'"
+msgstr ""
+"inplace_begin(): in-situ-bewerken wordt uitgeschakeld voor ongeldige "
+"bestandsnaam '%s'"
+
+#: extension/inplace.c:151
+#, c-format
+msgid "inplace_begin: Cannot stat `%s' (%s)"
+msgstr "inplace_begin(): Kan status van '%s' niet bepalen (%s)"
+
+#: extension/inplace.c:158
+#, c-format
+msgid "inplace_begin: `%s' is not a regular file"
+msgstr "inplace_begin(): '%s' is geen normaal bestand"
+
+#: extension/inplace.c:169
+#, c-format
+msgid "inplace_begin: mkstemp(`%s') failed (%s)"
+msgstr "inplace_begin(): mkstemp('%s') is mislukt (%s)"
+
+#: extension/inplace.c:178
+#, c-format
+msgid "inplace_begin: chmod failed (%s)"
+msgstr "inplace_begin(): chmod is mislukt (%s)"
+
+#: extension/inplace.c:185
+#, c-format
+msgid "inplace_begin: dup(stdout) failed (%s)"
+msgstr "inplace_begin(): dup(stdout) is mislukt (%s)"
+
+#: extension/inplace.c:188
+#, c-format
+msgid "inplace_begin: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_begin(): dup2(%d, stdout) is mislukt (%s)"
+
+#: extension/inplace.c:191
+#, c-format
+msgid "inplace_begin: close(%d) failed (%s)"
+msgstr "inplace_begin(): close(%d) is mislukt (%s)"
+
+#: extension/inplace.c:210
+msgid "inplace_end: cannot retrieve 1st argument as a string filename"
+msgstr ""
+"inplace_end(): kan eerste argument niet als bestandsnaamstring oppakken"
+
+#: extension/inplace.c:217
+msgid "inplace_end: in-place editing not active"
+msgstr "inplace_end(): in-situ-bewerken is niet actief"
+
+#: extension/inplace.c:223
+#, c-format
+msgid "inplace_end: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_end(): dup2(%d, stdout) is mislukt (%s)"
+
+#: extension/inplace.c:226
+#, c-format
+msgid "inplace_end: close(%d) failed (%s)"
+msgstr "inplace_end(): close(%d) is mislukt (%s)"
+
+#: extension/inplace.c:230
+#, c-format
+msgid "inplace_end: fsetpos(stdout) failed (%s)"
+msgstr "inplace_end(): fsetpos(stdout) is mislukt (%s)"
+
+#: extension/inplace.c:243
+#, c-format
+msgid "inplace_end: link(`%s', `%s') failed (%s)"
+msgstr "inplace_end(): link('%s', '%s') is mislukt (%s)"
+
+#: extension/inplace.c:253
+#, c-format
+msgid "inplace_end: rename(`%s', `%s') failed (%s)"
+msgstr "inplace_end(): rename('%s', '%s') is mislukt (%s)"
+
+#: extension/ordchr.c:69
+msgid "ord: called with too many arguments"
+msgstr "ord: aangeroepen met te veel argumenten"
+
+#: extension/ordchr.c:75
+msgid "ord: called with no arguments"
+msgstr "ord: aangeroepen zonder argumenten"
+
+#: extension/ordchr.c:77
+msgid "ord: called with inappropriate argument(s)"
+msgstr "ord: aangeroepen met onjuiste argumenten"
+
+#: extension/ordchr.c:99
+msgid "chr: called with too many arguments"
+msgstr "chr: aangeroepen met te veel argumenten"
+
+#: extension/ordchr.c:109
+msgid "chr: called with no arguments"
+msgstr "chr: aangeroepen zonder argumenten"
+
+#: extension/ordchr.c:111
+msgid "chr: called with inappropriate argument(s)"
+msgstr "chr: aangeroepen met onjuiste argumenten"
+
+#: extension/readdir.c:281
+#, c-format
+msgid "dir_take_control_of: opendir/fdopendir failed: %s"
+msgstr "dir_take_control_of(): opendir()/fdopendir() is mislukt: %s"
+
+#: extension/readfile.c:113
+msgid "readfile: called with too many arguments"
+msgstr "readfile: aangeroepen met te veel argumenten"
+
+#: extension/readfile.c:137
+msgid "readfile: called with no arguments"
+msgstr "readfile: aangeroepen zonder argumenten"
+
+#: extension/rwarray.c:124
+msgid "writea: called with too many arguments"
+msgstr "writea: aangeroepen met te veel argumenten"
+
+#: extension/rwarray.c:131
+#, c-format
+msgid "do_writea: argument 0 is not a string\n"
+msgstr "do_writea: argument 0 is geen string\n"
+
+#: extension/rwarray.c:137
+#, c-format
+msgid "do_writea: argument 1 is not an array\n"
+msgstr "do_writea: argument 1 is geen array\n"
+
+#: extension/rwarray.c:184
+#, c-format
+msgid "write_array: could not flatten array\n"
+msgstr "write_array: kan array niet pletten\n"
+
+#: extension/rwarray.c:198
+#, c-format
+msgid "write_array: could not release flattened array\n"
+msgstr "write_array: kan geplet array niet vrijgeven\n"
+
+#: extension/rwarray.c:280
+msgid "reada: called with too many arguments"
+msgstr "reada: aangeroepen met te veel argumenten"
+
+#: extension/rwarray.c:287
+#, c-format
+msgid "do_reada: argument 0 is not a string\n"
+msgstr "do_reada: argument 0 is geen string\n"
+
+#: extension/rwarray.c:293
+#, c-format
+msgid "do_reada: argument 1 is not an array\n"
+msgstr "do_reada: argument 1 is geen array\n"
+
+#: extension/rwarray.c:337
+#, c-format
+msgid "do_reada: clear_array failed\n"
+msgstr "do_reada: clear_array() is mislukt\n"
+
+#: extension/rwarray.c:374
+#, c-format
+msgid "read_array: set_array_element failed\n"
+msgstr "read_array: set_array_element() is mislukt\n"
+
+#: extension/time.c:113
+msgid "gettimeofday: ignoring arguments"
+msgstr "gettimeofday: argumenten worden genegeerd"
+
+#: extension/time.c:144
+msgid "gettimeofday: not supported on this platform"
+msgstr "gettimeofday: wordt op dit platform niet ondersteund"
+
+#: extension/time.c:165
+msgid "sleep: called with too many arguments"
+msgstr "sleep: aangeroepen met te veel argumenten"
+
+#: extension/time.c:168
+msgid "sleep: missing required numeric argument"
+msgstr "sleep: vereist numeriek argument ontbreekt"
+
+#: extension/time.c:174
+msgid "sleep: argument is negative"
+msgstr "sleep: argument is negatief"
-#: field.c:328
+#: extension/time.c:208
+msgid "sleep: not supported on this platform"
+msgstr "sleep: wordt op dit platform niet ondersteund"
+
+#: field.c:345
msgid "NF set to negative value"
msgstr "NF is op een negatieve waarde gezet"
-#: field.c:951 field.c:958 field.c:962
+#: field.c:971 field.c:978 field.c:982
msgid "split: fourth argument is a gawk extension"
msgstr "split: vierde argument is een gawk-uitbreiding"
-#: field.c:955
+#: field.c:975
msgid "split: fourth argument is not an array"
msgstr "split: vierde argument is geen array"
-#: field.c:969
+#: field.c:989
msgid "split: second argument is not an array"
msgstr "split: tweede argument is geen array"
-#: field.c:973
+#: field.c:993
msgid "split: cannot use the same array for second and fourth args"
msgstr ""
"split: hetzelfde array kan niet zowel als tweede als als vierde argument "
"gebruikt worden"
-#: field.c:978
+#: field.c:998
msgid "split: cannot use a subarray of second arg for fourth arg"
msgstr ""
"split: een subarray van het tweede argument kan niet als vierde argument "
"gebruikt worden"
-#: field.c:981
+#: field.c:1001
msgid "split: cannot use a subarray of fourth arg for second arg"
msgstr ""
"split: een subarray van het vierde argument kan niet als tweede argument "
"gebruikt worden"
-#: field.c:1010
+#: field.c:1032
msgid "split: null string for third arg is a gawk extension"
msgstr "split: lege string als derde argument is een gawk-uitbreiding"
-#: field.c:1050
+#: field.c:1072
msgid "patsplit: fourth argument is not an array"
msgstr "patsplit: vierde argument is geen array"
-#: field.c:1055
+#: field.c:1077
msgid "patsplit: second argument is not an array"
msgstr "patsplit: tweede argument is geen array"
-#: field.c:1061
+#: field.c:1083
msgid "patsplit: third argument must be non-null"
msgstr "patsplit: derde argument moet niet-nil zijn"
-#: field.c:1065
+#: field.c:1087
msgid "patsplit: cannot use the same array for second and fourth args"
msgstr ""
"patsplit: hetzelfde array kan niet zowel als tweede als als vierde argument "
"gebruikt worden"
-#: field.c:1070
+#: field.c:1092
msgid "patsplit: cannot use a subarray of second arg for fourth arg"
msgstr ""
"patsplit: een subarray van het tweede argument kan niet als vierde argument "
"gebruikt worden"
-#: field.c:1073
+#: field.c:1095
msgid "patsplit: cannot use a subarray of fourth arg for second arg"
msgstr ""
"patsplit: een subarray van het vierde argument kan niet als tweede argument "
"gebruikt worden"
-#: field.c:1110
+#: field.c:1133
msgid "`FIELDWIDTHS' is a gawk extension"
msgstr "'FIELDWIDTHS' is een gawk-uitbreiding"
-#: field.c:1173
+#: field.c:1197
#, c-format
msgid "invalid FIELDWIDTHS value, near `%s'"
msgstr "ongeldige waarde voor FIELDWIDTHS, nabij '%s'"
-#: field.c:1246
+#: field.c:1270
msgid "null string for `FS' is a gawk extension"
msgstr "een lege string als 'FS' is een gawk-uitbreiding"
-#: field.c:1250
+#: field.c:1274
msgid "old awk does not support regexps as value of `FS'"
msgstr "oude 'awk' staat geen reguliere expressies toe als waarde van 'FS'"
-#: field.c:1369
+#: field.c:1393
msgid "`FPAT' is a gawk extension"
msgstr "'FPAT' is een gawk-uitbreiding"
-#: getopt.c:574 getopt.c:590
+#: gawkapi.c:146
+msgid "awk_value_to_node: received null retval"
+msgstr "awk_value_to_node(): lege returnwaarde ontvangen"
+
+#: gawkapi.c:384
+msgid "node_to_awk_value: received null node"
+msgstr "node_to_awk_value(): lege knoop ontvangen"
+
+#: gawkapi.c:387
+msgid "node_to_awk_value: received null val"
+msgstr "node_to_awk_value(): lege waarde ontvangen"
+
+#: gawkapi.c:807
+msgid "remove_element: received null array"
+msgstr "remove_element(): leeg array ontvangen"
+
+#: gawkapi.c:810
+msgid "remove_element: received null subscript"
+msgstr "remove_element(): lege index ontvangen"
+
+#: gawkapi.c:947
#, c-format
-msgid "%s: option '%s' is ambiguous\n"
-msgstr "%s: optie '%s' is niet eenduidig\n"
+msgid "api_flatten_array: could not convert index %d\n"
+msgstr "api_flatten_array(): kan index %d niet converteren\n"
-#: getopt.c:623 getopt.c:627
+#: gawkapi.c:952
+#, c-format
+msgid "api_flatten_array: could not convert value %d\n"
+msgstr "api_flatten_array(): kan waarde %d niet converteren\n"
+
+#: getopt.c:604 getopt.c:633
+#, c-format
+msgid "%s: option '%s' is ambiguous; possibilities:"
+msgstr "%s: optie '%s' is niet eenduidig; mogelijkheden zijn:"
+
+#: getopt.c:679 getopt.c:683
#, 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
+#: getopt.c:692 getopt.c:697
#, 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:684 getopt.c:703
+#: getopt.c:740 getopt.c:759
#, c-format
msgid "%s: option '--%s' requires an argument\n"
msgstr "%s: optie '--%s' vereist een argument\n"
-#: getopt.c:741 getopt.c:744
+#: getopt.c:797 getopt.c:800
#, c-format
msgid "%s: unrecognized option '--%s'\n"
msgstr "%s: onbekende optie '--%s'\n"
-#: getopt.c:752 getopt.c:755
+#: getopt.c:808 getopt.c:811
#, c-format
msgid "%s: unrecognized option '%c%s'\n"
msgstr "%s: onbekende optie '%c%s'\n"
-#: getopt.c:804 getopt.c:807
+#: getopt.c:860 getopt.c:863
#, c-format
msgid "%s: invalid option -- '%c'\n"
msgstr "%s: ongeldige optie -- '%c'\n"
-#: getopt.c:857 getopt.c:874 getopt.c:1082 getopt.c:1100
+#: getopt.c:916 getopt.c:933 getopt.c:1143 getopt.c:1161
#, c-format
msgid "%s: option requires an argument -- '%c'\n"
msgstr "%s: optie vereist een argument -- '%c'\n"
-#: getopt.c:930 getopt.c:946
+#: getopt.c:989 getopt.c:1005
#, c-format
msgid "%s: option '-W %s' is ambiguous\n"
msgstr "%s: optie '-W %s' is niet eenduidig\n"
-#: getopt.c:970 getopt.c:988
+#: getopt.c:1029 getopt.c:1047
#, c-format
msgid "%s: option '-W %s' doesn't allow an argument\n"
msgstr "%s: optie '-W %s' staat geen argument toe\n"
-#: getopt.c:1009 getopt.c:1027
+#: getopt.c:1068 getopt.c:1086
#, c-format
msgid "%s: option '-W %s' requires an argument\n"
msgstr "%s: optie '-W %s' vereist een argument\n"
-#: io.c:280
+#: io.c:392
#, c-format
msgid "command line argument `%s' is a directory: skipped"
msgstr "opdrachtregelargument '%s' is een map -- overgeslagen"
-#: io.c:283 io.c:385
+#: io.c:395 io.c:513
#, c-format
msgid "cannot open file `%s' for reading (%s)"
msgstr "kan bestand '%s' niet openen om te lezen (%s)"
-#: io.c:501
+#: io.c:640
#, c-format
msgid "close of fd %d (`%s') failed (%s)"
msgstr "sluiten van bestandsdescriptor %d ('%s') is mislukt (%s)"
-#: io.c:578
+#: io.c:716
msgid "redirection not allowed in sandbox mode"
msgstr "omleiding is niet toegestaan in sandbox-modus"
-#: io.c:612
+#: io.c:750
#, c-format
msgid "expression in `%s' redirection only has numeric value"
msgstr "expressie in omleiding '%s' heeft alleen een getal als waarde"
-#: io.c:618
+#: io.c:756
#, c-format
msgid "expression for `%s' redirection has null string value"
msgstr "expressie voor omleiding '%s' heeft een lege string als waarde"
-#: io.c:624
+#: io.c:761
#, 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:667
+#: io.c:809
#, c-format
msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
msgstr "onnodige mix van '>' en '>>' voor bestand '%.*s'"
-#: io.c:720
+#: io.c:863
#, c-format
msgid "can't open pipe `%s' for output (%s)"
msgstr "kan pijp '%s' niet openen voor uitvoer (%s)"
-#: io.c:730
+#: io.c:873
#, c-format
msgid "can't open pipe `%s' for input (%s)"
msgstr "kan pijp '%s' niet openen voor invoer (%s)"
-#: io.c:753
+#: io.c:904
#, c-format
msgid "can't open two way pipe `%s' for input/output (%s)"
msgstr "kan tweerichtings-pijp '%s' niet openen voor in- en uitvoer (%s)"
-#: io.c:835
+#: io.c:986
#, c-format
msgid "can't redirect from `%s' (%s)"
msgstr "kan niet omleiden van '%s' (%s)"
-#: io.c:838
+#: io.c:989
#, c-format
msgid "can't redirect to `%s' (%s)"
msgstr "kan niet omleiden naar '%s' (%s)"
-#: io.c:889
+#: io.c:1040
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:905
+#: io.c:1056
#, c-format
msgid "close of `%s' failed (%s)."
msgstr "sluiten van '%s' is mislukt (%s)"
-#: io.c:913
+#: io.c:1064
msgid "too many pipes or input files open"
msgstr "te veel pijpen of invoerbestanden geopend"
-#: io.c:935
+#: io.c:1086
msgid "close: second argument must be `to' or `from'"
msgstr "close: tweede argument moet 'to' of 'from' zijn"
-#: io.c:952
+#: io.c:1103
#, c-format
msgid "close: `%.*s' is not an open file, pipe or co-process"
msgstr "close: '%.*s' is geen open bestand, pijp, of co-proces"
-#: io.c:957
+#: io.c:1108
msgid "close of redirection that was never opened"
msgstr "sluiten van een nooit-geopende omleiding"
-#: io.c:1054
+#: io.c:1205
#, c-format
msgid "close: redirection `%s' not opened with `|&', second argument ignored"
msgstr ""
"close: omleiding '%s' is niet geopend met '|&'; tweede argument wordt "
"genegeerd"
-#: io.c:1070
+#: io.c:1222
#, c-format
msgid "failure status (%d) on pipe close of `%s' (%s)"
msgstr "afsluitwaarde %d bij mislukte sluiting van pijp '%s' (%s)"
-#: io.c:1073
+#: io.c:1225
#, c-format
msgid "failure status (%d) on file close of `%s' (%s)"
msgstr "afsluitwaarde %d bij mislukte sluiting van bestand '%s' (%s)"
-#: io.c:1093
+#: io.c:1245
#, c-format
msgid "no explicit close of socket `%s' provided"
msgstr "geen expliciete sluiting van socket '%s' aangegeven"
-#: io.c:1096
+#: io.c:1248
#, c-format
msgid "no explicit close of co-process `%s' provided"
msgstr "geen expliciete sluiting van co-proces '%s' aangegeven"
-#: io.c:1099
+#: io.c:1251
#, c-format
msgid "no explicit close of pipe `%s' provided"
msgstr "geen expliciete sluiting van pijp '%s' aangegeven"
-#: io.c:1102
+#: io.c:1254
#, c-format
msgid "no explicit close of file `%s' provided"
msgstr "geen expliciete sluiting van bestand '%s' aangegeven"
-#: io.c:1130 io.c:1185 main.c:793 main.c:830
+#: io.c:1284 io.c:1342 main.c:864 main.c:906
#, c-format
msgid "error writing standard output (%s)"
msgstr "fout tijdens schrijven van standaarduitvoer (%s)"
-#: io.c:1134 io.c:1190
+#: io.c:1289 io.c:1348 main.c:866
#, c-format
msgid "error writing standard error (%s)"
msgstr "fout tijdens schrijven van standaardfoutuitvoer (%s)"
-#: io.c:1142
+#: io.c:1297
#, c-format
msgid "pipe flush of `%s' failed (%s)."
msgstr "leegmaken van pijp '%s' is mislukt (%s)"
-#: io.c:1145
+#: io.c:1300
#, c-format
msgid "co-process flush of pipe to `%s' failed (%s)."
msgstr "leegmaken door co-proces van pijp naar '%s' is mislukt (%s)"
-#: io.c:1148
+#: io.c:1303
#, c-format
msgid "file flush of `%s' failed (%s)."
msgstr "leegmaken van bestand '%s' is mislukt (%s)"
-#: io.c:1263
+#: io.c:1420
#, c-format
msgid "local port %s invalid in `/inet'"
msgstr "lokale poort %s is ongeldig in '/inet'"
-#: io.c:1280
+#: io.c:1438
#, c-format
msgid "remote host and port information (%s, %s) invalid"
msgstr "host- en poortinformatie (%s, %s) zijn ongeldig"
-#: io.c:1432
+#: io.c:1590
#, c-format
msgid "no (known) protocol supplied in special filename `%s'"
msgstr "geen (bekend) protocol aangegeven in speciale bestandsnaam '%s'"
-#: io.c:1446
+#: io.c:1604
#, c-format
msgid "special file name `%s' is incomplete"
msgstr "speciale bestandsnaam '%s' is onvolledig"
-#: io.c:1463
+#: io.c:1621
msgid "must supply a remote hostname to `/inet'"
msgstr "'/inet' heeft een gindse hostnaam nodig"
-#: io.c:1481
+#: io.c:1639
msgid "must supply a remote port to `/inet'"
msgstr "'/inet' heeft een gindse poort nodig"
-#: io.c:1527
+#: io.c:1685
msgid "TCP/IP communications are not supported"
msgstr "TCP/IP-communicatie wordt niet ondersteund"
-#: io.c:1694
+#: io.c:1867
#, c-format
msgid "could not open `%s', mode `%s'"
msgstr "kan '%s' niet openen -- modus '%s'"
-#: io.c:1748
+#: io.c:1917
#, c-format
msgid "close of master pty failed (%s)"
msgstr "kan meester-pty van dochterproces niet sluiten (%s)"
-#: io.c:1750 io.c:1918 io.c:2075
+#: io.c:1919 io.c:2105 io.c:2305
#, c-format
msgid "close of stdout in child failed (%s)"
msgstr "kan standaarduitvoer van dochterproces niet sluiten (%s)"
-#: io.c:1753
+#: io.c:1922
#, c-format
msgid "moving slave pty to stdout in child failed (dup: %s)"
msgstr ""
"kan slaaf-pty niet overzetten naar standaarduitvoer van dochterproces (dup: "
"%s)"
-#: io.c:1755 io.c:1923
+#: io.c:1924 io.c:2110
#, c-format
msgid "close of stdin in child failed (%s)"
msgstr "kan standaardinvoer van dochterproces niet sluiten (%s)"
-#: io.c:1758
+#: io.c:1927
#, c-format
msgid "moving slave pty to stdin in child failed (dup: %s)"
msgstr ""
"kan slaaf-pty niet overzetten naar standaardinvoer van dochterproces (dup: "
"%s)"
-#: io.c:1760 io.c:1781
+#: io.c:1929 io.c:1951
#, c-format
msgid "close of slave pty failed (%s)"
msgstr "kan slaaf-pty niet sluiten (%s)"
-#: io.c:1859 io.c:1921 io.c:2053 io.c:2078
+#: io.c:2040 io.c:2108 io.c:2276 io.c:2308
#, c-format
msgid "moving pipe to stdout in child failed (dup: %s)"
msgstr ""
"kan pijp niet overzetten naar standaarduitvoer van dochterproces (dup: %s)"
-#: io.c:1866 io.c:1926
+#: io.c:2047 io.c:2113
#, c-format
msgid "moving pipe to stdin in child failed (dup: %s)"
msgstr ""
"kan pijp niet overzetten naar standaardinvoer van dochterproces (dup: %s)"
-#: io.c:1886 io.c:2068
+#: io.c:2073 io.c:2298
msgid "restoring stdout in parent process failed\n"
msgstr "kan standaarduitvoer van ouderproces niet herstellen\n"
-#: io.c:1894
+#: io.c:2081
msgid "restoring stdin in parent process failed\n"
msgstr "kan standaardinvoer van ouderproces niet herstellen\n"
-#: io.c:1929 io.c:2080 io.c:2094
+#: io.c:2116 io.c:2310 io.c:2324
#, c-format
msgid "close of pipe failed (%s)"
msgstr "kan pijp niet sluiten (%s)"
-#: io.c:1974
+#: io.c:2174
msgid "`|&' not supported"
msgstr "'|&' wordt niet ondersteund"
-#: io.c:2040
+#: io.c:2261
#, c-format
msgid "cannot open pipe `%s' (%s)"
msgstr "kan pijp '%s' niet openen (%s)"
-#: io.c:2088
+#: io.c:2318
#, c-format
msgid "cannot create child process for `%s' (fork: %s)"
msgstr "kan voor '%s' geen dochterproces starten (fork: %s)"
-#: io.c:2521
+#: io.c:2790
+msgid "register_input_parser: received NULL pointer"
+msgstr "register_input_parser(): NULL-pointer gekregen"
+
+#: io.c:2818
+#, c-format
+msgid "input parser `%s' conflicts with previously installed input parser `%s'"
+msgstr "invoer-parser '%s' botst met eerder geïnstalleerde invoer-parser '%s'"
+
+#: io.c:2825
+#, c-format
+msgid "input parser `%s' failed to open `%s'"
+msgstr "invoer-parser '%s' kan '%s' niet openen"
+
+#: io.c:2845
+msgid "register_output_wrapper: received NULL pointer"
+msgstr "register_output_wrapper(): NULL-pointer gekregen"
+
+#: io.c:2873
+#, c-format
+msgid ""
+"output wrapper `%s' conflicts with previously installed output wrapper `%s'"
+msgstr ""
+"uitvoer-wrapper '%s' botst met eerder geïnstalleerde uitvoer-wrapper '%s'"
+
+#: io.c:2880
+#, c-format
+msgid "output wrapper `%s' failed to open `%s'"
+msgstr "uitvoer-wrapper '%s' kan '%s' niet openen"
+
+#: io.c:2901
+msgid "register_output_processor: received NULL pointer"
+msgstr "register_output_processor(): NULL-pointer gekregen"
+
+#: io.c:2930
+#, c-format
+msgid ""
+"two-way processor `%s' conflicts with previously installed two-way processor "
+"`%s'"
+msgstr ""
+"tweeweg-processor '%s' botst met eerder geïnstalleerde tweeweg-processor '%s'"
+
+#: io.c:2939
+#, c-format
+msgid "two way processor `%s' failed to open `%s'"
+msgstr "tweeweg-processor '%s' kan '%s' niet openen"
+
+#: io.c:3064
#, c-format
msgid "data file `%s' is empty"
msgstr "databestand '%s' is leeg"
-#: io.c:2562 io.c:2570
+#: io.c:3106 io.c:3114
msgid "could not allocate more input memory"
msgstr "kan geen extra invoergeheugen meer toewijzen"
-#: io.c:3128
+#: io.c:3682
msgid "multicharacter value of `RS' is a gawk extension"
msgstr "een 'RS' van meerdere tekens is een gawk-uitbreiding"
-#: io.c:3233
+#: io.c:3771
msgid "IPv6 communication is not supported"
msgstr "IPv6-communicatie wordt niet ondersteund"
-#: main.c:364
-msgid "`-m[fr]' option irrelevant in gawk"
-msgstr "optie '-m[fr]' is irrelevant in gawk"
-
-#: main.c:366
-msgid "-m option usage: `-m[fr] nnn'"
-msgstr "gebruikswijze van optie -m: '-m[fr] nnn'"
-
-#: main.c:389
+#: main.c:405
msgid "empty argument to `-e/--source' ignored"
msgstr "argument van '-e/--source' is leeg; genegeerd"
-#: main.c:460
+#: main.c:495
#, c-format
msgid "%s: option `-W %s' unrecognized, ignored\n"
msgstr "%s: optie '-W %s' is onbekend; genegeerd\n"
-#: main.c:513
+#: main.c:541
#, c-format
msgid "%s: option requires an argument -- %c\n"
msgstr "%s: optie vereist een argument -- %c\n"
-#: main.c:534
+#: main.c:562
msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
msgstr "omgevingsvariabele 'POSIXLY_CORRECT' is gezet: '--posix' ingeschakeld"
-#: main.c:540
+#: main.c:568
msgid "`--posix' overrides `--traditional'"
msgstr "'--posix' overstijgt '--traditional'"
-#: main.c:551
+#: main.c:579
msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
msgstr "'--posix'/'--traditional' overstijgen '--non-decimal-data'"
-#: main.c:555
+#: main.c:583
#, 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:560
-msgid "`--posix' overrides `--binary'"
-msgstr "'--posix' overstijgt '--binary'"
+#: main.c:588
+msgid "`--posix' overrides `--characters-as-bytes'"
+msgstr "'--posix' overstijgt '--characters-as-bytes'"
-#: main.c:611
+#: main.c:647
#, c-format
msgid "can't set binary mode on stdin (%s)"
msgstr "kan standaardinvoer niet in binaire modus zetten (%s)"
-#: main.c:614
+#: main.c:650
#, c-format
msgid "can't set binary mode on stdout (%s)"
msgstr "kan standaarduitvoer niet in binaire modus zetten (%s)"
-#: main.c:616
+#: main.c:652
#, c-format
msgid "can't set binary mode on stderr (%s)"
msgstr "kan standaardfoutuitvoer niet in binaire modus zetten (%s)"
-#: main.c:655
+#: main.c:710
msgid "no program text at all!"
msgstr "helemaal geen programmatekst!"
-#: main.c:733
+#: main.c:799
#, c-format
msgid "Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"
msgstr "Gebruik: %s [opties] -f programmabestand [--] bestand...\n"
-#: main.c:735
+#: main.c:801
#, c-format
msgid "Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"
msgstr ""
" of: %s [opties] [--] %cprogrammatekst%c bestand...\n"
"\n"
-#: main.c:740
+#: main.c:806
msgid "POSIX options:\t\tGNU long options: (standard)\n"
msgstr "\tPOSIX-opties:\t\tEquivalente GNU-opties: (standaard)\n"
-#: main.c:741
+#: main.c:807
msgid "\t-f progfile\t\t--file=progfile\n"
msgstr "\t-f programmabestand\t--file=programmabestand\n"
-#: main.c:742
+#: main.c:808
msgid "\t-F fs\t\t\t--field-separator=fs\n"
msgstr "\t-F veldscheidingsteken\t--field-separator=veldscheidingsteken\n"
-#: main.c:743
+#: main.c:809
msgid "\t-v var=val\t\t--assign=var=val\n"
msgstr ""
"\t-v var=waarde\t\t--assign=var=waarde\n"
"\n"
-#: main.c:744
+#: main.c:810
msgid "Short options:\t\tGNU long options: (extensions)\n"
msgstr "\tKorte opties:\t\tEquivalente GNU-opties: (uitbreidingen)\n"
-#: main.c:745
+#: main.c:811
msgid "\t-b\t\t\t--characters-as-bytes\n"
msgstr "\t-b\t\t\t--characters-as-bytes\n"
-#: main.c:746
+#: main.c:812
msgid "\t-c\t\t\t--traditional\n"
msgstr "\t-c\t\t\t--traditional\n"
-#: main.c:747
+#: main.c:813
msgid "\t-C\t\t\t--copyright\n"
msgstr "\t-C\t\t\t--copyright\n"
-#: main.c:748
+#: main.c:814
msgid "\t-d[file]\t\t--dump-variables[=file]\n"
msgstr "\t-d[bestand]\t\t--dump-variables[=bestand]\n"
-#: main.c:749
+#: main.c:815
+msgid "\t-D[file]\t\t--debug[=file]\n"
+msgstr "\t-D[bestand]\t\t--debug[=bestand]\n"
+
+#: main.c:816
msgid "\t-e 'program-text'\t--source='program-text'\n"
msgstr "\t-e 'programmatekst'\t--source='programmatekst'\n"
-#: main.c:750
+#: main.c:817
msgid "\t-E file\t\t\t--exec=file\n"
msgstr "\t-E bestand\t\t--exec=bestand\n"
-#: main.c:751
+#: main.c:818
msgid "\t-g\t\t\t--gen-pot\n"
msgstr "\t-g\t\t\t--gen-pot\n"
-#: main.c:752
+#: main.c:819
msgid "\t-h\t\t\t--help\n"
msgstr "\t-h\t\t\t--help\n"
-#: main.c:753
+#: main.c:820
+msgid "\t-i includefile\t\t--include=includefile\n"
+msgstr "\t-i include-bestand\t\t--include=include-bestand\n"
+
+#: main.c:821
+msgid "\t-l library\t\t--load=library\n"
+msgstr "\t-l bibliotheek\t\t--load=bibliotheek\n"
+
+#: main.c:822
msgid "\t-L [fatal]\t\t--lint[=fatal]\n"
msgstr "\t-L [fataal]\t\t--lint[=fataal]\n"
-#: main.c:754
+#: main.c:823
msgid "\t-n\t\t\t--non-decimal-data\n"
msgstr "\t-n\t\t\t--non-decimal-data\n"
-#: main.c:755
+#: main.c:824
+msgid "\t-M\t\t\t--bignum\n"
+msgstr "\t-M\t\t\t--bignum\n"
+
+#: main.c:825
msgid "\t-N\t\t\t--use-lc-numeric\n"
msgstr "\t-N\t\t\t--use-lc-numeric\n"
-#: main.c:756
+#: main.c:826
+msgid "\t-o[file]\t\t--pretty-print[=file]\n"
+msgstr "\t-o[bestand]\t\t--pretty-print[=bestand]\n"
+
+#: main.c:827
msgid "\t-O\t\t\t--optimize\n"
msgstr "\t-O\t\t\t--optimize\n"
-#: main.c:757
+#: main.c:828
msgid "\t-p[file]\t\t--profile[=file]\n"
msgstr "\t-p[bestand]\t\t--profile[=bestand]\n"
-#: main.c:758
+#: main.c:829
msgid "\t-P\t\t\t--posix\n"
msgstr "\t-P\t\t\t--posix\n"
-#: main.c:759
+#: main.c:830
msgid "\t-r\t\t\t--re-interval\n"
msgstr "\t-r\t\t\t--re-interval\n"
-#: main.c:761
-msgid "\t-R file\t\t\t--command=file\n"
-msgstr "\t-R bestand\t\t\t--command=bestand\n"
-
-#: main.c:762
+#: main.c:831
msgid "\t-S\t\t\t--sandbox\n"
msgstr "\t-S\t\t\t--sandbox\n"
-#: main.c:763
+#: main.c:832
msgid "\t-t\t\t\t--lint-old\n"
msgstr "\t-t\t\t\t--lint-old\n"
-#: main.c:764
+#: main.c:833
msgid "\t-V\t\t\t--version\n"
msgstr "\t-V\t\t\t--version\n"
-#: main.c:766
+#: main.c:835
msgid "\t-W nostalgia\t\t--nostalgia\n"
msgstr "\t-W nostalgia\t\t\t--nostalgia\n"
-#: main.c:769
+#: main.c:838
msgid "\t-Y\t\t--parsedebug\n"
msgstr "\t-Y\t\t\t--parsedebug\n"
@@ -1814,7 +3129,7 @@ msgstr "\t-Y\t\t\t--parsedebug\n"
#. for this application. Please add _another line_ with the
#. address for translation bugs.
#. no-wrap
-#: main.c:778
+#: main.c:847
msgid ""
"\n"
"To report bugs, see node `Bugs' in `gawk.info', which is\n"
@@ -1827,7 +3142,7 @@ msgstr ""
"Meld fouten in de vertaling aan <vertaling@vrijschrift.org>.\n"
"\n"
-#: main.c:782
+#: main.c:851
msgid ""
"gawk is a pattern scanning and processing language.\n"
"By default it reads standard input and writes standard output.\n"
@@ -1837,7 +3152,7 @@ msgstr ""
"Standaard leest het van standaardinvoer en schrijft naar standaarduitvoer.\n"
"\n"
-#: main.c:786
+#: main.c:855
msgid ""
"Examples:\n"
"\tgawk '{ sum += $1 }; END { print sum }' file\n"
@@ -1847,7 +3162,7 @@ msgstr ""
"\tgawk '{ som += $1 }; END { print som }' bestand\n"
"\tgawk -F: '{ print $1 }' /etc/passwd\n"
-#: main.c:806
+#: main.c:880
#, c-format
msgid ""
"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
@@ -1865,7 +3180,7 @@ msgstr ""
"uitgegeven door de Free Software Foundation, naar keuze ofwel onder\n"
"versie 3 of onder een nieuwere versie van die licentie.\n"
-#: main.c:814
+#: main.c:888
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"
@@ -1879,7 +3194,7 @@ msgstr ""
"Zie de GNU General Public License voor meer details.\n"
"\n"
-#: main.c:820
+#: main.c:894
msgid ""
"You should have received a copy of the GNU General Public License\n"
"along with this program. If not, see http://www.gnu.org/licenses/.\n"
@@ -1888,16 +3203,16 @@ msgstr ""
"ontvangen te hebben; is dit niet het geval, dan kunt u deze licentie\n"
"ook vinden op http://www.gnu.org/licenses/.\n"
-#: main.c:855
+#: main.c:931
msgid "-Ft does not set FS to tab in POSIX awk"
msgstr "-Ft maakt van FS geen tab in POSIX-awk"
-#: main.c:1089
+#: main.c:1208
#, c-format
msgid "unknown value for field spec: %d\n"
msgstr "onbekende waarde voor veldspecificatie: %d\n"
-#: main.c:1170
+#: main.c:1306
#, c-format
msgid ""
"%s: `%s' argument to `-v' not in `var=value' form\n"
@@ -1906,84 +3221,126 @@ msgstr ""
"%s: argument '%s' van '-v' is niet van de vorm 'var=waarde'\n"
"\n"
-#: main.c:1196
+#: main.c:1332
#, c-format
msgid "`%s' is not a legal variable name"
msgstr "'%s' is geen geldige variabelenaam"
-#: main.c:1199
+#: main.c:1335
#, 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:1203
+#: main.c:1339
#, c-format
msgid "cannot use gawk builtin `%s' as variable name"
msgstr "kan in gawk ingebouwde '%s' niet als variabelenaam gebruiken"
-#: main.c:1208
+#: main.c:1344
#, c-format
msgid "cannot use function `%s' as variable name"
msgstr "kan functie '%s' niet als variabelenaam gebruiken"
-#: main.c:1261
+#: main.c:1397
msgid "floating point exception"
msgstr "drijvendekomma-berekeningsfout"
-#: main.c:1268
+#: main.c:1404
msgid "fatal error: internal error"
msgstr "fatale fout: **interne fout**"
-#: main.c:1283
+#: main.c:1419
msgid "fatal error: internal error: segfault"
msgstr "fatale fout: **interne fout**: segmentatiefout"
-#: main.c:1295
+#: main.c:1431
msgid "fatal error: internal error: stack overflow"
msgstr "fatale fout: **interne fout**: stack is vol"
-#: main.c:1345
+#: main.c:1490
#, c-format
msgid "no pre-opened fd %d"
msgstr "geen reeds-geopende bestandsdescriptor %d"
-#: main.c:1352
+#: main.c:1497
#, c-format
msgid "could not pre-open /dev/null for fd %d"
msgstr "kan /dev/null niet openen voor bestandsdescriptor %d"
-#: main.c:1375 main.c:1384
+#: mpfr.c:550
+#, c-format
+msgid "PREC value `%.*s' is invalid"
+msgstr "PREC-waarde '%.*s' is ongeldig"
+
+#: mpfr.c:608
+#, c-format
+msgid "RNDMODE value `%.*s' is invalid"
+msgstr "RNDMODE-waarde '%.*s' is ongeldig"
+
+#: mpfr.c:698
+#, c-format
+msgid "%s: received non-numeric argument"
+msgstr "%s: niet-numeriek argument ontvangen"
+
+#: mpfr.c:800
+msgid "compl(%Rg): negative value will give strange results"
+msgstr "compl(%Rg): negatieve waarden geven rare resultaten"
+
+#: mpfr.c:804
+msgid "comp(%Rg): fractional value will be truncated"
+msgstr "compl(%Rg): cijfers na de komma worden afgekapt"
+
+#: mpfr.c:816
+#, c-format
+msgid "cmpl(%Zd): negative values will give strange results"
+msgstr "compl(%Zd): negatieve waarden geven rare resultaten"
+
+#: mpfr.c:835
+#, c-format
+msgid "%s: received non-numeric argument #%d"
+msgstr "%s: niet-numeriek argument #%d ontvangen"
+
+#: mpfr.c:845
+msgid "%s: argument #%d has invalid value %Rg, using 0"
+msgstr "%s: argument #%d heeft ongeldige waarde %Rg; 0 wordt gebruikt"
+
+#: mpfr.c:857
+msgid "%s: argument #%d negative value %Rg will give strange results"
+msgstr "%s: negatieve waarde %2$Rg van argument #%1$d geeft rare resultaten"
+
+#: mpfr.c:863
+msgid "%s: argument #%d fractional value %Rg will be truncated"
+msgstr ""
+"%s: cijfers na de komma van waarde %2$Rg van argument #%1$d worden afgekapt"
+
+#: mpfr.c:878
#, c-format
-msgid "could not find groups: %s"
-msgstr "kan groepen niet vinden: %s"
+msgid "%s: argument #%d negative value %Zd will give strange results"
+msgstr "%1$s: negatieve waarde %3$Zd van argument #%2$d geeft rare resultaten"
-#: msg.c:63
+#: msg.c:68
#, c-format
msgid "cmd. line:"
msgstr "commandoregel:"
-#: msg.c:107
-msgid "error: "
-msgstr "fout: "
-
-#: node.c:406
+#: node.c:421
msgid "backslash at end of string"
msgstr "backslash aan het einde van de string"
-#: node.c:517
+#: node.c:500
#, c-format
msgid "old awk does not support the `\\%c' escape sequence"
msgstr "oude 'awk' kent de stuurcodereeks '\\%c' niet"
-#: node.c:568
+#: node.c:551
msgid "POSIX does not allow `\\x' escapes"
msgstr "POSIX staat stuurcode '\\x' niet toe"
-#: node.c:574
+#: node.c:557
msgid "no hex digits in `\\x' escape sequence"
msgstr "geen hex cijfers in stuurcodereeks '\\x'"
-#: node.c:596
+#: node.c:579
#, c-format
msgid ""
"hex escape \\x%.*s of %d characters probably not interpreted the way you "
@@ -1992,12 +3349,12 @@ msgstr ""
"hexadecimale stuurcode \\x%.*s van %d tekens wordt waarschijnlijk niet "
"afgehandeld zoals u verwacht"
-#: node.c:611
+#: node.c:594
#, c-format
msgid "escape sequence `\\%c' treated as plain `%c'"
msgstr "stuurcodereeks '\\%c' behandeld als normale '%c'"
-#: node.c:750
+#: node.c:739
msgid ""
"Invalid multibyte data detected. There may be a mismatch between your data "
"and your locale."
@@ -2005,28 +3362,28 @@ msgstr ""
"Ongeldige multibyte-gegevens gevonden.\n"
"Uw gegevens passen vermoedelijk niet bij uw taalregio."
-#: posix/gawkmisc.c:176
+#: posix/gawkmisc.c:177
#, c-format
msgid "%s %s `%s': could not get fd flags: (fcntl F_GETFD: %s)"
msgstr ""
"%s %s '%s': kan bestandsdescriptorvlaggen niet verkrijgen: (fcntl F_GETFD: "
"%s)"
-#: posix/gawkmisc.c:188
+#: posix/gawkmisc.c:189
#, c-format
msgid "%s %s `%s': could not set close-on-exec: (fcntl F_SETFD: %s)"
msgstr "%s %s '%s': kan 'close-on-exec' niet activeren: (fcntl F_SETFD: %s)"
-#: profile.c:83
+#: profile.c:71
#, c-format
msgid "could not open `%s' for writing: %s"
msgstr "kan '%s' niet openen om te schrijven: %s"
-#: profile.c:85
+#: profile.c:73
msgid "sending profile to standard error"
msgstr "profiel gaat naar standaardfoutuitvoer"
-#: profile.c:203
+#: profile.c:193
#, c-format
msgid ""
"\t# %s block(s)\n"
@@ -2035,7 +3392,7 @@ msgstr ""
"\t# %s-blok(ken)\n"
"\n"
-#: profile.c:208
+#: profile.c:198
#, c-format
msgid ""
"\t# Rule(s)\n"
@@ -2044,17 +3401,30 @@ msgstr ""
"\t# Regel(s)\n"
"\n"
-#: profile.c:279
+#: profile.c:272
#, c-format
msgid "internal error: %s with null vname"
-msgstr "**interne fout**: %s heeft een lege 'vname'"
+msgstr "**interne fout**: %s met lege 'vname'"
-#: profile.c:952
+#: profile.c:537
+msgid "internal error: builtin with null fname"
+msgstr "**interne fout**: ingebouwde functie met lege 'fname'"
+
+#: profile.c:949
+#, c-format
+msgid ""
+"\t# Loaded extensions (-l and/or @load)\n"
+"\n"
+msgstr ""
+"\t# Geladen uitbreidingen ('-l' en/of '@load')\n"
+"\n"
+
+#: profile.c:972
#, c-format
msgid "\t# gawk profile, created %s\n"
msgstr "\t# gawk-profiel, gemaakt op %s\n"
-#: profile.c:1331
+#: profile.c:1475
#, c-format
msgid ""
"\n"
@@ -2063,96 +3433,198 @@ msgstr ""
"\n"
"\t# Functies, alfabetisch geordend\n"
-#: profile.c:1370
+#: profile.c:1513
#, c-format
msgid "redir2str: unknown redirection type %d"
msgstr "redir2str(): onbekend omleidingstype %d"
-#: re.c:572
-#, fuzzy, c-format
-msgid "range of the form `[%c-%c]' is locale dependent"
-msgstr ""
-"de betekenis van een bereik van de vorm '[%c-%c]' is afhankelijk van de "
-"taalregio"
-
-#: re.c:599
+#: re.c:607
#, c-format
msgid "regexp component `%.*s' should probably be `[%.*s]'"
msgstr ""
"component '%.*s' van reguliere expressie moet vermoedelijk '[%.*s]' zijn"
-#: regcomp.c:132
+#: regcomp.c:131
msgid "Success"
msgstr "Gelukt"
-#: regcomp.c:135
+#: regcomp.c:134
msgid "No match"
msgstr "Geen overeenkomsten"
-#: regcomp.c:138
+#: regcomp.c:137
msgid "Invalid regular expression"
msgstr "Ongeldige reguliere expressie"
-#: regcomp.c:141
+#: regcomp.c:140
msgid "Invalid collation character"
msgstr "Ongeldig samengesteld teken"
-#: regcomp.c:144
+#: regcomp.c:143
msgid "Invalid character class name"
msgstr "Ongeldige tekenklassenaam"
-#: regcomp.c:147
+#: regcomp.c:146
msgid "Trailing backslash"
msgstr "Backslash aan het eind"
-#: regcomp.c:150
+#: regcomp.c:149
msgid "Invalid back reference"
msgstr "Ongeldige terugverwijzing"
-#: regcomp.c:153
+#: regcomp.c:152
msgid "Unmatched [ or [^"
msgstr "Ongepaarde [ of [^"
-#: regcomp.c:156
+#: regcomp.c:155
msgid "Unmatched ( or \\("
msgstr "Ongepaarde ( of \\("
-#: regcomp.c:159
+#: regcomp.c:158
msgid "Unmatched \\{"
msgstr "Ongepaarde \\{"
-#: regcomp.c:162
-msgid "Invalid content of \\{\\}"
-msgstr "Ongeldige inhoud van \\{\\}"
-
-#: regcomp.c:165
+#: regcomp.c:164
msgid "Invalid range end"
msgstr "Ongeldig bereikeinde"
-#: regcomp.c:168
+#: regcomp.c:167
msgid "Memory exhausted"
msgstr "Onvoldoende geheugen beschikbaar"
-#: regcomp.c:171
+#: regcomp.c:170
msgid "Invalid preceding regular expression"
msgstr "Ongeldige voorafgaande reguliere expressie"
-#: regcomp.c:174
+#: regcomp.c:173
msgid "Premature end of regular expression"
msgstr "Voortijdig einde van reguliere expressie"
-#: regcomp.c:177
-msgid "Regular expression too big"
-msgstr "Reguliere expressie is te groot"
-
-#: regcomp.c:180
+#: regcomp.c:179
msgid "Unmatched ) or \\)"
msgstr "Ongepaarde ) of \\)"
-#: regcomp.c:701
+#: regcomp.c:704
msgid "No previous regular expression"
msgstr "Geen eerdere reguliere expressie"
+#: symbol.c:741
+msgid "can not pop main context"
+msgstr "kan hoofdcontext niet poppen"
+
+#~ msgid "range of the form `[%c-%c]' is locale dependent"
+#~ msgstr ""
+#~ "de betekenis van een bereik van de vorm '[%c-%c]' is afhankelijk van de "
+#~ "taalregio"
+
+#~ msgid "attempt to use function `%s' as an array"
+#~ msgstr "functie '%s' wordt gebruikt als array"
+
+#~ msgid "reference to uninitialized element `%s[\"%.*s\"]'"
+#~ msgstr "verwijzing naar ongeïnitialiseerd element '%s[\"%.*s\"]'"
+
+#~ msgid "subscript of array `%s' is null string"
+#~ msgstr "index van array '%s' is lege string"
+
+#~ msgid "%s: empty (null)\n"
+#~ msgstr "%s: leeg (nil)\n"
+
+#~ msgid "%s: empty (zero)\n"
+#~ msgstr "%s: leeg (nul)\n"
+
+#~ msgid "%s: table_size = %d, array_size = %d\n"
+#~ msgstr "%s: tabelgrootte = %d, arraygrootte = %d\n"
+
+#~ msgid "%s: array_ref to %s\n"
+#~ msgstr "%s: array-verwijzing naar %s\n"
+
+#~ msgid "`nextfile' is a gawk extension"
+#~ msgstr "'nextfile' is een gawk-uitbreiding"
+
+#~ msgid "`delete array' is a gawk extension"
+#~ msgstr "'delete array' is een gawk-uitbreiding"
+
+#~ msgid "use of non-array as array"
+#~ msgstr "non-array wordt gebruikt als array"
+
+#~ msgid "`%s' is a Bell Labs extension"
+#~ msgstr "'%s' is een uitbreiding door Bell Labs"
+
+#~ msgid "and: received non-numeric first argument"
+#~ msgstr "and: eerste argument is geen getal"
+
+#~ msgid "and: received non-numeric second argument"
+#~ msgstr "and: tweede argument is geen getal"
+
+#~ msgid "or: received non-numeric first argument"
+#~ msgstr "or: eerste argument is geen getal"
+
+#~ msgid "or: received non-numeric second argument"
+#~ msgstr "or: tweede argument is geen getal"
+
+#~ msgid "or(%lf, %lf): negative values will give strange results"
+#~ msgstr "or(%lf, %lf): negatieve waarden geven rare resultaten"
+
+#~ msgid "or(%lf, %lf): fractional values will be truncated"
+#~ msgstr "or(%lf, %lf): cijfers na de komma worden afgekapt"
+
+#~ msgid "xor: received non-numeric first argument"
+#~ msgstr "xor: eerste argument is geen getal"
+
+#~ msgid "xor: received non-numeric second argument"
+#~ msgstr "xor: tweede argument is geen getal"
+
+#~ msgid "xor(%lf, %lf): fractional values will be truncated"
+#~ msgstr "xor(%lf, %lf): cijfers na de komma worden afgekapt"
+
+#~ msgid "can't use function name `%s' as variable or array"
+#~ msgstr "kan functienaam '%s' niet als variabele of array gebruiken"
+
+#~ msgid "assignment used in conditional context"
+#~ msgstr "toewijzing wordt gebruikt in een conditionele context"
+
+#~ msgid "statement has no effect"
+#~ msgstr "opdracht heeft geen effect"
+
+#~ 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"
+
+#~ msgid "function called indirectly through `%s' does not exist"
+#~ msgstr "indirect (via '%s') aangeroepen functie bestaat niet"
+
+#~ msgid "function `%s' not defined"
+#~ msgstr "functie '%s' is niet gedefinieerd"
+
+#~ msgid "non-redirected `getline' invalid inside `%s' rule"
+#~ msgstr "niet-omgeleide 'getline' is ongeldig binnen een '%s'-regel"
+
+#~ msgid "`nextfile' cannot be called from a `%s' rule"
+#~ msgstr "'nextfile' kan niet aangeroepen worden in een '%s'-regel"
+
+#~ msgid "`next' cannot be called from a `%s' rule"
+#~ msgstr "'next' kan niet aangeroepen worden in een '%s'-regel"
+
+#~ msgid "Sorry, don't know how to interpret `%s'"
+#~ msgstr "Kan '%s' niet interpreteren"
+
+#~ msgid "Operation Not Supported"
+#~ msgstr "Actie wordt niet ondersteund"
+
+#~ msgid "`-m[fr]' option irrelevant in gawk"
+#~ msgstr "optie '-m[fr]' is irrelevant in gawk"
+
+#~ msgid "-m option usage: `-m[fr] nnn'"
+#~ msgstr "gebruikswijze van optie -m: '-m[fr] nnn'"
+
+#~ msgid "\t-R file\t\t\t--command=file\n"
+#~ msgstr "\t-R bestand\t\t\t--command=bestand\n"
+
+#~ msgid "could not find groups: %s"
+#~ msgstr "kan groepen niet vinden: %s"
+
#~ msgid "assignment is not allowed to result of builtin function"
#~ msgstr ""
#~ "toewijzing aan het resultaat van een ingebouwde functie is niet toegestaan"
@@ -2169,9 +3641,6 @@ msgstr "Geen eerdere reguliere expressie"
#~ msgid "attempt to use scalar `%s' as array"
#~ msgstr "scalair '%s' wordt gebruikt als array"
-#~ msgid "attempt to use array `%s' in scalar context"
-#~ msgstr "array '%s' wordt gebruikt in een scalaire context"
-
#~ msgid "call of `length' without parentheses is deprecated by POSIX"
#~ msgstr "aanroep van 'length' zonder haakjes wordt door POSIX afgeraden"
@@ -2233,15 +3702,6 @@ msgstr "Geen eerdere reguliere expressie"
#~ msgid "\t-m[fr] val\n"
#~ msgstr "\t-m[fr] waarde\n"
-#~ msgid "\t-W compat\t\t--compat\n"
-#~ msgstr "\t-W compat\t\t\t--compat\n"
-
-#~ msgid "\t-W copyleft\t\t--copyleft\n"
-#~ msgstr "\t-W copyleft\t\t\t--copyleft\n"
-
-#~ msgid "\t-W usage\t\t--usage\n"
-#~ msgstr "\t-W usage\t\t\t--usage\n"
-
#~ msgid "can't convert string to float"
#~ msgstr "kan string niet converteren naar drijvende-komma-getal"
diff --git a/po/pl.gmo b/po/pl.gmo
index c90a7959..b2c8e5fa 100644
--- a/po/pl.gmo
+++ b/po/pl.gmo
Binary files differ
diff --git a/po/pl.po b/po/pl.po
index 33f5543f..95ddbec2 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -1,16 +1,16 @@
# Polish translations for GNU AWK package.
-# Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+# Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
# This file is distributed under the same license as the gawk package.
#
-# Wojciech Polak <polak@gnu.org>, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011.
+# Wojciech Polak <polak@gnu.org>, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014.
# additional help by Sergey Poznyakoff <gray@gnu.org>, 2003.
#
msgid ""
msgstr ""
-"Project-Id-Version: gawk 3.1.81\n"
+"Project-Id-Version: gawk 4.1.0b\n"
"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
-"POT-Creation-Date: 2011-10-24 05:57+0200\n"
-"PO-Revision-Date: 2011-05-14 11:41-0400\n"
+"POT-Creation-Date: 2014-04-08 19:23+0300\n"
+"PO-Revision-Date: 2014-03-22 17:49+0100\n"
"Last-Translator: Wojciech Polak <polak@gnu.org>\n"
"Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n"
"Language: pl\n"
@@ -20,515 +20,493 @@ msgstr ""
"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:140
+#: array.c:256
#, c-format
msgid "from %s"
msgstr "od %s"
-#: array.c:248
+#: array.c:357
msgid "attempt to use a scalar value as array"
msgstr "próba użycia wartości skalarnej jako tablicy"
-#: array.c:251
-#, c-format
-msgid "attempt to use function `%s' as an array"
-msgstr "próba użycia funkcji `%s' jako tablicy"
-
-#: array.c:254
+#: array.c:359
#, c-format
msgid "attempt to use scalar parameter `%s' as an array"
msgstr "próba użycia parametru `%s' skalaru jako tablicy"
-#: array.c:257
+#: array.c:362
#, c-format
msgid "attempt to use scalar `%s' as an array"
msgstr "próba użycia skalaru `%s' jako tablicy"
-#: array.c:302 array.c:707 builtin.c:84 builtin.c:1384 builtin.c:1426
-#: builtin.c:1439 builtin.c:1856 builtin.c:1868 eval.c:1135 eval.c:1139
-#: eval.c:1495 eval.c:1812
+#: array.c:409 array.c:576 builtin.c:85 builtin.c:1615 builtin.c:1661
+#: builtin.c:1674 builtin.c:2102 builtin.c:2116 eval.c:1122 eval.c:1126
+#: eval.c:1531
#, c-format
msgid "attempt to use array `%s' in a scalar context"
msgstr "próba użycia tablicy `%s' w kontekście skalaru"
-#: array.c:513
-#, c-format
-msgid "reference to uninitialized element `%s[\"%.*s\"]'"
-msgstr "odwołanie do niezainicjowanego elementu `%s[\"%.*s\"]'"
-
-#: array.c:519
-#, c-format
-msgid "subscript of array `%s' is null string"
-msgstr "indeks tablicy `%s' jest zerowym łańcuchem"
-
-#: array.c:723
+#: array.c:583
#, c-format
msgid "delete: index `%s' not in array `%s'"
msgstr "delete: indeks `%s' nie jest w tablicy `%s'"
-#: array.c:734 eval.c:1865
+#: array.c:597
#, c-format
msgid "attempt to use scalar `%s[\"%.*s\"]' as an array"
msgstr "próba użycia skalaru `%s[\"%.*s\"]' jako tablicy"
-#: array.c:910
-#, c-format
-msgid "%s: empty (null)\n"
-msgstr "%s: pusty (null)\n"
-
-#: array.c:915
-#, c-format
-msgid "%s: empty (zero)\n"
-msgstr "%s: pusty (zero)\n"
-
-#: array.c:919
-#, c-format
-msgid "%s: table_size = %d, array_size = %d\n"
-msgstr "%s: table_size = %d, array_size = %d\n"
-
-#: array.c:954
-#, c-format
-msgid "%s: is parameter\n"
-msgstr "%s: jest parametrem\n"
-
-#: array.c:958
-#, c-format
-msgid "%s: array_ref to %s\n"
-msgstr "%s: array_ref do %s\n"
+#: array.c:776
+msgid "adump: first argument not an array"
+msgstr "adump: pierwszy argument nie jest tablicÄ…"
-#: array.c:963
-msgid "adump: argument not an array"
-msgstr "adump: argument nie jest tablicÄ…"
-
-#: array.c:1086
+#: array.c:815
msgid "asort: second argument not an array"
msgstr "asort: drugi argument nie jest tablicÄ…"
-#: array.c:1087
+#: array.c:816
msgid "asorti: second argument not an array"
msgstr "asorti: drugi argument nie jest tablicÄ…"
-#: array.c:1094
+#: array.c:823
msgid "asort: first argument not an array"
msgstr "asort: pierwszy argument nie jest tablicÄ…"
-#: array.c:1095
+#: array.c:824
msgid "asorti: first argument not an array"
msgstr "asorti: pierwszy argument nie jest tablicÄ…"
-#: array.c:1102
+#: array.c:831
msgid "asort: cannot use a subarray of first arg for second arg"
msgstr ""
"asort: nie można użyć podtablicy pierwszego argumentu dla drugiego argumentu"
-#: array.c:1103
+#: array.c:832
msgid "asorti: cannot use a subarray of first arg for second arg"
msgstr ""
"asorti: nie można użyć podtablicy pierwszego argumentu dla drugiego argumentu"
-#: array.c:1108
+#: array.c:837
msgid "asort: cannot use a subarray of second arg for first arg"
msgstr ""
"asort: nie można użyć podtablicy drugiego argumentu dla pierwszego argumentu"
-#: array.c:1109
+#: array.c:838
msgid "asorti: cannot use a subarray of second arg for first arg"
msgstr ""
"asorti: nie można użyć podtablicy drugiego argumentu dla pierwszego argumentu"
-#: array.c:1659
+#: array.c:1314
#, c-format
msgid "`%s' is invalid as a function name"
msgstr "nieprawidłowa nazwa funkcji `%s'"
-#: array.c:1663
+#: array.c:1318
#, c-format
msgid "sort comparison function `%s' is not defined"
msgstr "funkcja porównująca w sortowaniu `%s' nie została zdefiniowna"
-#: awkgram.y:249
+#: awkgram.y:233
#, c-format
msgid "%s blocks must have an action part"
msgstr "%s bloków musi posiadać część dotyczącą akcji"
-#: awkgram.y:252
+#: awkgram.y:236
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:323 awkgram.y:334
+#: awkgram.y:325 awkgram.y:336
msgid "old awk does not support multiple `BEGIN' or `END' rules"
msgstr "stary awk nie wspiera wielokrotnych reguł `BEGIN' lub `END'"
-#: awkgram.y:371
+#: awkgram.y:373
#, 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:432
+#: awkgram.y:419
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:436
+#: awkgram.y:423
#, 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:528
+#: awkgram.y:515
#, c-format
msgid "duplicate case values in switch body: %s"
msgstr "powielone wartości case w ciele switch: %s"
-#: awkgram.y:549
+#: awkgram.y:536
msgid "duplicate `default' detected in switch body"
msgstr "wykryto powielony `default' w ciele switch"
-#: awkgram.y:809
+#: awkgram.y:796 awkgram.y:3723
msgid "`break' is not allowed outside a loop or switch"
msgstr "instrukcja `break' poza pętlą lub switch'em jest niedozwolona"
-#: awkgram.y:818
+#: awkgram.y:805 awkgram.y:3715
msgid "`continue' is not allowed outside a loop"
msgstr "instrukcja `continue' poza pętlą jest niedozwolona"
-#: awkgram.y:828
+#: awkgram.y:815
#, c-format
msgid "`next' used in %s action"
msgstr "`next' użyty w akcji %s"
-#: awkgram.y:836
-msgid "`nextfile' is a gawk extension"
-msgstr "`nextfile' jest rozszerzeniem gawk"
-
-#: awkgram.y:841
+#: awkgram.y:824
#, c-format
msgid "`nextfile' used in %s action"
msgstr "`nextfile' użyty w akcji %s"
-#: awkgram.y:865
+#: awkgram.y:848
msgid "`return' used outside function context"
msgstr "`return' użyty poza kontekstem funkcji"
-#: awkgram.y:925
+#: awkgram.y:922
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:995 awkgram.y:999 awkgram.y:1023
-msgid "`delete array' is a gawk extension"
-msgstr "`delete tablica' jest rozszerzeniem gawk"
+#: awkgram.y:988 awkgram.y:1037
+msgid "`delete' is not allowed with SYMTAB"
+msgstr "`delete' nie jest dozwolony z SYMTAB"
+
+#: awkgram.y:990 awkgram.y:1039
+msgid "`delete' is not allowed with FUNCTAB"
+msgstr "`delete' nie jest dozwolony z FUNCTAB"
-#: awkgram.y:1019
+#: awkgram.y:1024 awkgram.y:1028
msgid "`delete(array)' is a non-portable tawk extension"
msgstr "`delete(tablica)' jest nieprzenośnym rozszerzeniem tawk"
-#: awkgram.y:1135
+#: awkgram.y:1149
msgid "multistage two-way pipelines don't work"
msgstr "wieloetapowe dwukierunkowe linie potokowe nie działają"
-#: awkgram.y:1238
+#: awkgram.y:1264
msgid "regular expression on right of assignment"
msgstr "wyrażanie regularne po prawej stronie przypisania"
-#: awkgram.y:1249
+#: awkgram.y:1275
msgid "regular expression on left of `~' or `!~' operator"
msgstr "wyrażenie regularne po lewej stronie operatora `~' lub `!~'"
-#: awkgram.y:1265 awkgram.y:1419
+#: awkgram.y:1291 awkgram.y:1442
msgid "old awk does not support the keyword `in' except after `for'"
msgstr ""
"stary awk nie wspiera słowa kluczowego `in', z wyjątkiem po słowie `for'"
-#: awkgram.y:1275
+#: awkgram.y:1301
msgid "regular expression on right of comparison"
msgstr "wyrażenie regularne po prawej stronie porównania"
-#: awkgram.y:1394
+#: awkgram.y:1417
#, c-format
msgid "`getline var' invalid inside `%s' rule"
msgstr "nieprawidłowy `getline var' wewnątrz reguły `%s'"
-#: awkgram.y:1397 eval.c:2504
+#: awkgram.y:1420
#, c-format
msgid "`getline' invalid inside `%s' rule"
msgstr "nieprawidłowy `getline' wewnątrz reguły `%s'"
-#: awkgram.y:1402
+#: awkgram.y:1425
msgid "non-redirected `getline' undefined inside END action"
msgstr ""
"komenda `getline' bez przekierowania nie jest zdefiniowana wewnÄ…trz akcji END"
-#: awkgram.y:1421
+#: awkgram.y:1444
msgid "old awk does not support multidimensional arrays"
msgstr "stary awk nie wspiera wielowymiarowych tablic"
-#: awkgram.y:1517
+#: awkgram.y:1541
msgid "call of `length' without parentheses is not portable"
msgstr "wywołanie `length' bez nawiasów jest nieprzenośne"
-#: awkgram.y:1580
+#: awkgram.y:1607
msgid "indirect function calls are a gawk extension"
msgstr "pośrednie wywołania funkcji są rozszerzeniem gawk"
-#: awkgram.y:1593
+#: awkgram.y:1620
#, c-format
msgid "can not use special variable `%s' for indirect function call"
msgstr ""
"nie można użyć specjalnej zmiennej `%s' do pośredniego wywołania funkcji"
-#: awkgram.y:1671
+#: awkgram.y:1698
msgid "invalid subscript expression"
msgstr "nieprawidłowe wyrażenie indeksowe"
-#: awkgram.y:1711
-msgid "use of non-array as array"
-msgstr "użycie nie-tablicy jako tablicy"
-
-#: awkgram.y:1975 awkgram.y:1995 msg.c:98
+#: awkgram.y:2048 awkgram.y:2068 gawkapi.c:206 gawkapi.c:224 msg.c:126
msgid "warning: "
msgstr "ostrzeżenie: "
-#: awkgram.y:1993 msg.c:130
+#: awkgram.y:2066 gawkapi.c:192 gawkapi.c:221 msg.c:158
msgid "fatal: "
msgstr "fatalny błąd: "
-#: awkgram.y:2043
+#: awkgram.y:2116
msgid "unexpected newline or end of string"
msgstr "niespodziewany znak nowego wiersza lub końca łańcucha"
-#: awkgram.y:2300 awkgram.y:2358 awkgram.y:2542
+#: awkgram.y:2383 awkgram.y:2459 awkgram.y:2682 debug.c:523 debug.c:539
+#: debug.c:2812 debug.c:5055
#, 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:2301 awkgram.y:2359 builtin.c:122
+#: awkgram.y:2384 awkgram.y:2509
+#, c-format
+msgid "can't open shared library `%s' for reading (%s)"
+msgstr "nie można otworzyć współdzielonej biblioteki `%s' do czytania (%s)"
+
+#: awkgram.y:2386 awkgram.y:2460 awkgram.y:2510 builtin.c:135 debug.c:5206
msgid "reason unknown"
msgstr "nieznany powód"
-#: awkgram.y:2317
+#: awkgram.y:2395 awkgram.y:2419
+#, c-format
+msgid "can't include `%s' and use it as a program file"
+msgstr "nie można dołączyć `%s' i używać go jako pliku programu"
+
+#: awkgram.y:2408
#, c-format
msgid "already included source file `%s'"
msgstr "plik źródłowy `%s' jest już załączony"
-#: awkgram.y:2343
+#: awkgram.y:2409
+#, c-format
+msgid "already loaded shared library `%s'"
+msgstr "biblioteka współdzielona jest już załadowana `%s'"
+
+#: awkgram.y:2444
msgid "@include is a gawk extension"
msgstr "@include jest rozszerzeniem gawk"
-#: awkgram.y:2349
+#: awkgram.y:2450
msgid "empty filename after @include"
msgstr "pusta nazwa pliku po @include"
#: awkgram.y:2494
+msgid "@load is a gawk extension"
+msgstr "@load jest rozszerzeniem gawk"
+
+#: awkgram.y:2500
+msgid "empty filename after @load"
+msgstr "pusta nazwa pliku po @load"
+
+#: awkgram.y:2634
msgid "empty program text on command line"
msgstr "pusty tekst programu w linii poleceń"
-#: awkgram.y:2609
+#: awkgram.y:2749
#, c-format
msgid "can't read sourcefile `%s' (%s)"
msgstr "nie można otworzyć pliku źródłowego `%s' (%s)"
-#: awkgram.y:2620
+#: awkgram.y:2760
#, c-format
msgid "source file `%s' is empty"
msgstr "plik źródłowy `%s' jest pusty"
-#: awkgram.y:2805
+#: awkgram.y:2937
msgid "source file does not end in newline"
msgstr "plik źródłowy nie posiada na końcu znaku nowego wiersza"
-#: awkgram.y:2882
+#: awkgram.y:3042
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:2906
+#: awkgram.y:3066
#, 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:2910
+#: awkgram.y:3070
#, 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:2917
+#: awkgram.y:3077
msgid "unterminated regexp"
msgstr "niezakończone wyrażenie regularne"
-#: awkgram.y:2921
+#: awkgram.y:3081
msgid "unterminated regexp at end of file"
msgstr "niezakończone wyrażenie regularne na końcu pliku"
-#: awkgram.y:2980
+#: awkgram.y:3140
msgid "use of `\\ #...' line continuation is not portable"
msgstr "użycie `\\ #...' kontynuacji linii nie jest przenośne"
-#: awkgram.y:2996
+#: awkgram.y:3156
msgid "backslash not last character on line"
msgstr "backslash nie jest ostatnim znakiem w wierszu"
-#: awkgram.y:3057
+#: awkgram.y:3217
msgid "POSIX does not allow operator `**='"
msgstr "POSIX nie zezwala na operator `**='"
-#: awkgram.y:3059
+#: awkgram.y:3219
msgid "old awk does not support operator `**='"
msgstr "stary awk nie wspiera operatora `**='"
-#: awkgram.y:3068
+#: awkgram.y:3228
msgid "POSIX does not allow operator `**'"
msgstr "POSIX nie zezwala na operator `**'"
-#: awkgram.y:3070
+#: awkgram.y:3230
msgid "old awk does not support operator `**'"
msgstr "stary awk nie wspiera operatora `**'"
-#: awkgram.y:3105
+#: awkgram.y:3265
msgid "operator `^=' is not supported in old awk"
msgstr "operator `^=' nie jest wspierany w starym awk"
-#: awkgram.y:3113
+#: awkgram.y:3273
msgid "operator `^' is not supported in old awk"
msgstr "operator `^' nie jest wspierany w starym awk"
-#: awkgram.y:3206 awkgram.y:3222
+#: awkgram.y:3366 awkgram.y:3382 command.y:1178
msgid "unterminated string"
msgstr "niezakończony łańcuch"
-#: awkgram.y:3418
+#: awkgram.y:3603
#, c-format
msgid "invalid char '%c' in expression"
msgstr "nieprawidłowy znak '%c' w wyrażeniu"
-#: awkgram.y:3465
+#: awkgram.y:3650
#, c-format
msgid "`%s' is a gawk extension"
msgstr "`%s' jest rozszerzeniem gawk"
-#: awkgram.y:3470
-#, c-format
-msgid "`%s' is a Bell Labs extension"
-msgstr "`%s' jest rozszerzeniem Bell Labs"
-
-#: awkgram.y:3475
+#: awkgram.y:3655
#, c-format
msgid "POSIX does not allow `%s'"
msgstr "POSIX nie zezwala na `%s'"
-#: awkgram.y:3483
+#: awkgram.y:3663
#, c-format
msgid "`%s' is not supported in old awk"
msgstr "`%s' nie jest wspierany w starym awk"
-#: awkgram.y:3550
+#: awkgram.y:3753
msgid "`goto' considered harmful!\n"
msgstr "`goto' uważane za szkodliwe!\n"
-#: awkgram.y:3601
+#: awkgram.y:3787
#, 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:3636
+#: awkgram.y:3822
#, 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:3641
+#: awkgram.y:3827
#, c-format
msgid "%s third parameter is not a changeable object"
msgstr "%s trzeci parametr nie jest zmiennym obiektem"
-#: awkgram.y:3714 awkgram.y:3717
+#: awkgram.y:3910 awkgram.y:3913
msgid "match: third argument is a gawk extension"
msgstr "match: trzeci argument jest rozszerzeniem gawk"
-#: awkgram.y:3771 awkgram.y:3774
+#: awkgram.y:3967 awkgram.y:3970
msgid "close: second argument is a gawk extension"
msgstr "close: drugi argument jest rozszerzeniem gawk"
-#: awkgram.y:3786
+#: awkgram.y:3982
msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
msgstr "nieprawidłowe użycie dcgettext(_\"...\"): usuń znak podkreślenia"
-#: awkgram.y:3801
+#: awkgram.y:3997
msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
msgstr "nieprawidłowe użycie dcngettext(_\"...\"): usuń znak podkreślenia"
-#: awkgram.y:3893
-#, c-format
-msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
-msgstr "funkcja `%s': parametr #%d, `%s', powiela parametr #%d"
+#: awkgram.y:4016
+msgid "index: regexp constant as second argument is not allowed"
+msgstr "index: stały regexp jako drugi argument nie jest dozwolony"
-#: awkgram.y:3935
+#: awkgram.y:4069
#, c-format
msgid "function `%s': parameter `%s' shadows global variable"
msgstr "funkcja `%s': parametr `%s' zasłania globalną zmienną"
-#: awkgram.y:4093
+#: awkgram.y:4126 debug.c:4041 debug.c:4084 debug.c:5204
#, c-format
msgid "could not open `%s' for writing (%s)"
msgstr "nie można otworzyć `%s' do zapisu (%s)"
-#: awkgram.y:4094
-#, fuzzy
+#: awkgram.y:4127
msgid "sending variable list to standard error"
-msgstr "wysyłanie profilu na standardowe wyjście diagnostyczne"
+msgstr "wysyłanie listy zmiennych na standardowe wyjście diagnostyczne"
-#: awkgram.y:4100
+#: awkgram.y:4135
#, c-format
msgid "%s: close failed (%s)"
msgstr "%s: zamknięcie nie powiodło się (%s)"
-#: awkgram.y:4152
+#: awkgram.y:4160
msgid "shadow_funcs() called twice!"
msgstr "shadow_funcs() wywołana podwójnie!"
-#: awkgram.y:4158
+#: awkgram.y:4168
msgid "there were shadowed variables."
msgstr "wystąpiły przykryte zmienne."
-#: awkgram.y:4188
+#: awkgram.y:4239
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "nazwa funkcji `%s' została zdefiniowana poprzednio"
+
+#: awkgram.y:4285
#, 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:4192
+#: awkgram.y:4288
#, c-format
msgid "function `%s': can't use special variable `%s' as a function parameter"
msgstr ""
"funkcja `%s': nie można użyć specjalnej zmiennej `%s' jako parametru funkcji"
-#: awkgram.y:4208
+#: awkgram.y:4296
#, c-format
-msgid "function name `%s' previously defined"
-msgstr "nazwa funkcji `%s' została zdefiniowana poprzednio"
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "funkcja `%s': parametr #%d, `%s', powiela parametr #%d"
-#: awkgram.y:4376 awkgram.y:4382
+#: awkgram.y:4383 awkgram.y:4389
#, c-format
msgid "function `%s' called but never defined"
msgstr "funkcja `%s' została wywołana, ale nigdy nie została zdefiniowana"
-#: awkgram.y:4385
+#: awkgram.y:4393
#, c-format
msgid "function `%s' defined but never called directly"
msgstr ""
"funkcja `%s' została zdefiniowana, ale nigdy nie została wywołana "
"bezpośrednio"
-#: awkgram.y:4417
+#: awkgram.y:4425
#, 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:4526
+#: awkgram.y:4484
#, c-format
msgid ""
"function `%s' called with space between name and `(',\n"
@@ -538,233 +516,247 @@ msgstr ""
"`(',\n"
"lub użyta jako zmienna lub jako tablica"
-#: awkgram.y:4773 eval.c:2056
+#: awkgram.y:4720
msgid "division by zero attempted"
msgstr "próba dzielenia przez zero"
-#: awkgram.y:4782 eval.c:2072
+#: awkgram.y:4729
#, c-format
msgid "division by zero attempted in `%%'"
msgstr "próba dzielenia przez zero w `%%'"
-#: builtin.c:120
+#: awkgram.y:5049
+msgid ""
+"cannot assign a value to the result of a field post-increment expression"
+msgstr "nie można przypisać wartości do wyniku tego wyrażenia"
+
+#: awkgram.y:5052
+#, c-format
+msgid "invalid target of assignment (opcode %s)"
+msgstr "nieprawidłowy cel przypisania (opcode %s)"
+
+#: builtin.c:133
#, c-format
msgid "%s to \"%s\" failed (%s)"
msgstr "%s do \"%s\" nie powiódł się (%s)"
-#: builtin.c:121
+#: builtin.c:134
msgid "standard output"
msgstr "standardowe wyjście"
-#: builtin.c:135
+#: builtin.c:148
msgid "exp: received non-numeric argument"
msgstr "exp: otrzymano argument nie będący liczbą"
-#: builtin.c:141
+#: builtin.c:154
#, c-format
msgid "exp: argument %g is out of range"
msgstr "exp: argument %g jest poza zasięgiem"
-#: builtin.c:200
+#: builtin.c:229
#, 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:203
+#: builtin.c:232
#, 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:215
+#: builtin.c:244
#, 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:333
+#: builtin.c:362
msgid "index: received non-string first argument"
msgstr "index: otrzymano pierwszy argument, który nie jest łańcuchem"
-#: builtin.c:335
+#: builtin.c:364
msgid "index: received non-string second argument"
msgstr "index: otrzymano drugi argument, który nie jest łańcuchem"
-#: builtin.c:457
+#: builtin.c:488 mpfr.c:757
msgid "int: received non-numeric argument"
msgstr "int: otrzymano argument, który nie jest liczbą"
-#: builtin.c:493
+#: builtin.c:525
msgid "length: received array argument"
msgstr "length: otrzymano argument, który jest tablicą"
-#: builtin.c:496
+#: builtin.c:528
msgid "`length(array)' is a gawk extension"
msgstr "`length(tablica)' jest rozszerzeniem gawk"
-#: builtin.c:504
+#: builtin.c:544
msgid "length: received non-string argument"
msgstr "length: otrzymano argument, który nie jest łańcuchem"
-#: builtin.c:535
+#: builtin.c:575
msgid "log: received non-numeric argument"
msgstr "log: otrzymano argument, który nie jest liczbą"
-#: builtin.c:538
+#: builtin.c:578
#, c-format
msgid "log: received negative argument %g"
msgstr "log: otrzymano ujemny argument %g"
-#: builtin.c:694 builtin.c:699
+#: builtin.c:776 builtin.c:781
msgid "fatal: must use `count$' on all formats or none"
msgstr "fatal: należy użyć `count$' we wszystkich formatach lub nic"
-#: builtin.c:761
+#: builtin.c:851
#, c-format
msgid "field width is ignored for `%%' specifier"
msgstr "szerokość pola jest ignorowana dla specyfikatora `%%'"
-#: builtin.c:763
+#: builtin.c:853
#, c-format
msgid "precision is ignored for `%%' specifier"
msgstr "precyzja jest ignorowana dla specyfikatora `%%'"
-#: builtin.c:765
+#: builtin.c:855
#, c-format
msgid "field width and precision are ignored for `%%' specifier"
msgstr "szerokość pola i precyzja są ignorowane dla specyfikatora `%%'"
-#: builtin.c:816
+#: builtin.c:906
msgid "fatal: `$' is not permitted in awk formats"
msgstr "fatal: `$' jest niedozwolony w formatach awk"
-#: builtin.c:825
+#: builtin.c:915
msgid "fatal: arg count with `$' must be > 0"
msgstr "fatal: argument count z `$' musi być > 0"
-#: builtin.c:829
+#: builtin.c:919
#, c-format
msgid "fatal: arg count %ld greater than total number of supplied arguments"
msgstr ""
"fatal: argument count %ld większy niż całkowita suma argumentów dostarczonych"
-#: builtin.c:833
+#: builtin.c:923
msgid "fatal: `$' not permitted after period in format"
msgstr "fatal: `$' jest niedozwolony po kropce w formacie"
-#: builtin.c:849
+#: builtin.c:939
msgid "fatal: no `$' supplied for positional field width or precision"
msgstr "fatal: brak `$' dla pozycyjnej szerokości pola lub precyzji"
-#: builtin.c:920
+#: builtin.c:1009
msgid "`l' is meaningless in awk formats; ignored"
msgstr "`l' jest bezsensowny w formatach awk; zignorowany"
-#: builtin.c:924
+#: builtin.c:1013
msgid "fatal: `l' is not permitted in POSIX awk formats"
msgstr "fatal: `l' jest niedozwolony w formatach POSIX awk"
-#: builtin.c:937
+#: builtin.c:1026
msgid "`L' is meaningless in awk formats; ignored"
msgstr "`L' jest bezsensowny w formatach awk; zignorowany"
-#: builtin.c:941
+#: builtin.c:1030
msgid "fatal: `L' is not permitted in POSIX awk formats"
msgstr "fatal: `L' jest niedozwolony w formatach POSIX awk"
-#: builtin.c:954
+#: builtin.c:1043
msgid "`h' is meaningless in awk formats; ignored"
msgstr "`h' jest bezsensowny w formatach awk; zignorowany"
-#: builtin.c:958
+#: builtin.c:1047
msgid "fatal: `h' is not permitted in POSIX awk formats"
msgstr "fatal: `h' jest niedozwolony w formatach POSIX awk"
-#: builtin.c:1271
+#: builtin.c:1463
#, 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:1331
+#: builtin.c:1561
#, c-format
msgid "ignoring unknown format specifier character `%c': no argument converted"
msgstr ""
"pominięcie nieznanego formatu specyfikatora znaku `%c': nie skonwertowano "
"argumentu"
-#: builtin.c:1336
+#: builtin.c:1566
msgid "fatal: not enough arguments to satisfy format string"
msgstr ""
"fatal: brak wystarczającej liczby argumentów, aby zaspokoić łańcuch "
"formatujÄ…cy"
-#: builtin.c:1338
+#: builtin.c:1568
msgid "^ ran out for this one"
msgstr "zabrakło ^"
-#: builtin.c:1345
+#: builtin.c:1575
msgid "[s]printf: format specifier does not have control letter"
msgstr "[s]printf: specyfikator formatu nie posiada kontrolnej litery"
-#: builtin.c:1348
+#: builtin.c:1578
msgid "too many arguments supplied for format string"
msgstr "zbyt dużo podanych argumentów w łańcuchu formatującym"
-#: builtin.c:1422 builtin.c:1433
+#: builtin.c:1634
+msgid "sprintf: no arguments"
+msgstr "sprintf: brak argumentów"
+
+#: builtin.c:1657 builtin.c:1668
msgid "printf: no arguments"
msgstr "printf: brak argumentów"
-#: builtin.c:1474
+#: builtin.c:1711
msgid "sqrt: received non-numeric argument"
msgstr "sqrt: otrzymano argument, który nie jest liczbą"
-#: builtin.c:1478
+#: builtin.c:1715
#, c-format
msgid "sqrt: called with negative argument %g"
msgstr "sqrt: wywołana z ujemnym argumentem %g"
-#: builtin.c:1502
+#: builtin.c:1746
#, c-format
msgid "substr: length %g is not >= 1"
msgstr "substr: długość %g nie jest >= 1"
-#: builtin.c:1504
+#: builtin.c:1748
#, c-format
msgid "substr: length %g is not >= 0"
msgstr "substr: długość %g nie jest >= 0"
-#: builtin.c:1511
+#: builtin.c:1755
#, 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:1516
+#: builtin.c:1760
#, 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:1528
+#: builtin.c:1772
#, 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:1533
+#: builtin.c:1777
#, 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:1558
+#: builtin.c:1802
msgid "substr: source string is zero length"
msgstr "substr: łańcuch źródłowy ma zerową długość"
-#: builtin.c:1574
+#: builtin.c:1818
#, 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:1582
+#: builtin.c:1826
#, c-format
msgid ""
"substr: length %g at start index %g exceeds length of first argument (%lu)"
@@ -772,230 +764,1082 @@ msgstr ""
"substr: długość %g zaczynając od %g przekracza długość pierwszego argumentu "
"(%lu)"
-#: builtin.c:1655
+#: builtin.c:1900
msgid "strftime: format value in PROCINFO[\"strftime\"] has numeric type"
msgstr ""
"strftime: wartość formatu w PROCINFO[\"strftime\"] posiada typ numeryczny"
-#: builtin.c:1678
+#: builtin.c:1923
msgid "strftime: received non-numeric second argument"
msgstr "strftime: otrzymano drugi argument, który nie jest liczbą"
-#: builtin.c:1681
+#: builtin.c:1927
msgid "strftime: second argument less than 0 or too big for time_t"
-msgstr ""
+msgstr "strftime: drugi argument mniejszy od 0 lub zbyt duży dla time_t"
-#: builtin.c:1687
+#: builtin.c:1934
msgid "strftime: received non-string first argument"
msgstr "strftime: otrzymano pierwszy argument, który nie jest łańcuchem"
-#: builtin.c:1693
+#: builtin.c:1941
msgid "strftime: received empty format string"
msgstr "strftime: otrzymano pusty łańcuch formatujący"
-#: builtin.c:1759
+#: builtin.c:2007
msgid "mktime: received non-string argument"
msgstr "mktime: otrzymano argument, który nie jest łańcuchem"
-#: builtin.c:1776
+#: builtin.c:2024
msgid "mktime: at least one of the values is out of the default range"
msgstr "mktime: przynajmniej jedna z wartości jest poza domyślnym zakresem"
-#: builtin.c:1811
+#: builtin.c:2059
msgid "'system' function not allowed in sandbox mode"
msgstr "funkcja 'system' nie jest dozwolona w trybie piaskownicy"
-#: builtin.c:1816
+#: builtin.c:2064
msgid "system: received non-string argument"
msgstr "system: otrzymano argument, który nie jest łańcuchem"
-#: builtin.c:1871 eval.c:1159 eval.c:1790 eval.c:1803
-#, c-format
-msgid "reference to uninitialized variable `%s'"
-msgstr "odwołanie do niezainicjowanej zmiennej `%s'"
-
-#: builtin.c:1938
+#: builtin.c:2184
#, c-format
msgid "reference to uninitialized field `$%d'"
msgstr "odwołanie do niezainicjowanego pola `$%d'"
-#: builtin.c:2025
+#: builtin.c:2271
msgid "tolower: received non-string argument"
msgstr "tolower: otrzymano argument, który nie jest łańcuchem"
-#: builtin.c:2059
+#: builtin.c:2305
msgid "toupper: received non-string argument"
msgstr "toupper: otrzymano argument, który nie jest łańcuchem"
-#: builtin.c:2095
+#: builtin.c:2341 mpfr.c:672
msgid "atan2: received non-numeric first argument"
msgstr "atan2: otrzymano pierwszy argument, który nie jest liczbą"
-#: builtin.c:2097
+#: builtin.c:2343 mpfr.c:674
msgid "atan2: received non-numeric second argument"
msgstr "atan2: otrzymano drugi argument, który nie jest liczbą"
-#: builtin.c:2116
+#: builtin.c:2362
msgid "sin: received non-numeric argument"
msgstr "sin: otrzymano argument, który nie jest liczbą"
-#: builtin.c:2132
+#: builtin.c:2378
msgid "cos: received non-numeric argument"
msgstr "cos: otrzymano argument, który nie jest liczbą"
-#: builtin.c:2185
+#: builtin.c:2431 mpfr.c:1156
msgid "srand: received non-numeric argument"
msgstr "srand: otrzymano argument, który nie jest liczbą"
-#: builtin.c:2216
+#: builtin.c:2462
msgid "match: third argument is not an array"
msgstr "match: otrzymano trzeci argument, który nie jest tablicą"
-#: builtin.c:2480
+#: builtin.c:2734
msgid "gensub: third argument of 0 treated as 1"
msgstr "gensub: trzeci argument 0 potraktowany jako 1"
-#: builtin.c:2773
+#: builtin.c:3030
msgid "lshift: received non-numeric first argument"
msgstr "lshift: otrzymano pierwszy argument, który nie jest liczbą"
-#: builtin.c:2775
+#: builtin.c:3032
msgid "lshift: received non-numeric second argument"
msgstr "lshift: otrzymano drugi argument, który nie jest liczbą"
-#: builtin.c:2781
+#: builtin.c:3038
#, c-format
-msgid "lshift(%lf, %lf): negative values will give strange results"
-msgstr "lshift(%lf, %lf): ujemne wartości spowodują dziwne wyniki"
+msgid "lshift(%f, %f): negative values will give strange results"
+msgstr "lshift(%f, %f): ujemne wartości spowodują dziwne wyniki"
-#: builtin.c:2783
+#: builtin.c:3040
#, c-format
-msgid "lshift(%lf, %lf): fractional values will be truncated"
-msgstr "lshift(%lf, %lf): ułamkowe wartości zostaną obcięte"
+msgid "lshift(%f, %f): fractional values will be truncated"
+msgstr "lshift(%f, %f): ułamkowe wartości zostaną obcięte"
-#: builtin.c:2785
+#: builtin.c:3042
#, 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"
+msgid "lshift(%f, %f): too large shift value will give strange results"
+msgstr "lshift(%f, %f): zbyt duża wartość przesunięcia spowoduje dziwne wyniki"
-#: builtin.c:2810
+#: builtin.c:3067
msgid "rshift: received non-numeric first argument"
msgstr "rshift: otrzymano pierwszy argument, który nie jest liczbą"
-#: builtin.c:2812
+#: builtin.c:3069
msgid "rshift: received non-numeric second argument"
msgstr "rshift: otrzymano drugi argument, który nie jest liczbą"
-#: builtin.c:2818
+#: builtin.c:3075
#, c-format
-msgid "rshift(%lf, %lf): negative values will give strange results"
-msgstr "rshift(%lf, %lf): ujemne wartości spowodują dziwne wyniki"
+msgid "rshift(%f, %f): negative values will give strange results"
+msgstr "rshift(%f, %f): ujemne wartości spowodują dziwne wyniki"
-#: builtin.c:2820
+#: builtin.c:3077
#, c-format
-msgid "rshift(%lf, %lf): fractional values will be truncated"
-msgstr "rshift(%lf, %lf): ułamkowe wartości zostaną obcięte"
+msgid "rshift(%f, %f): fractional values will be truncated"
+msgstr "rshift(%f, %f): ułamkowe wartości zostaną obcięte"
-#: builtin.c:2822
+#: builtin.c:3079
#, 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"
+msgid "rshift(%f, %f): too large shift value will give strange results"
+msgstr "rshift(%f, %f): zbyt duża wartość przesunięcia spowoduje dziwne wyniki"
-#: builtin.c:2847
-msgid "and: received non-numeric first argument"
-msgstr "and: otrzymano pierwszy argument, który nie jest liczbą"
+#: builtin.c:3104 mpfr.c:968
+msgid "and: called with less than two arguments"
+msgstr "and: wywołano z mniej niż dwoma argumentami"
-#: builtin.c:2849
-msgid "and: received non-numeric second argument"
-msgstr "and: otrzymano drugi argument, który nie jest liczbą"
-
-#: builtin.c:2855
+#: builtin.c:3109
#, c-format
-msgid "and(%lf, %lf): negative values will give strange results"
-msgstr "and(%lf, %lf): ujemne wartości spowodują dziwne wyniki"
+msgid "and: argument %d is non-numeric"
+msgstr "and: argument %d nie jest liczbÄ…"
-#: builtin.c:2857
+#: builtin.c:3113
#, c-format
-msgid "and(%lf, %lf): fractional values will be truncated"
-msgstr "and(%lf, %lf): ułamkowe wartości zostaną obcięte"
-
-#: builtin.c:2882
-msgid "or: received non-numeric first argument"
-msgstr "or: otrzymano pierwszy argument, który nie jest liczbą"
+msgid "and: argument %d negative value %g will give strange results"
+msgstr "and: argument %d ujemna wartość %g spowoduje dziwne wyniki"
-#: builtin.c:2884
-msgid "or: received non-numeric second argument"
-msgstr "or: otrzymano drugi argument, który nie jest liczbą"
+#: builtin.c:3136 mpfr.c:1000
+msgid "or: called with less than two arguments"
+msgstr "or: wywołano z mniej niż dwoma argumentami"
-#: builtin.c:2890
+#: builtin.c:3141
#, c-format
-msgid "or(%lf, %lf): negative values will give strange results"
-msgstr "or(%lf, %lf): ujemne wartości spowodują dziwne wyniki"
+msgid "or: argument %d is non-numeric"
+msgstr "or: argument %d nie jest liczbÄ…"
-#: builtin.c:2892
+#: builtin.c:3145
#, c-format
-msgid "or(%lf, %lf): fractional values will be truncated"
-msgstr "or(%lf, %lf): ułamkowe wartości zostaną obcięte"
-
-#: builtin.c:2920
-msgid "xor: received non-numeric first argument"
-msgstr "xor: otrzymano pierwszy argument, który nie jest liczbą"
+msgid "or: argument %d negative value %g will give strange results"
+msgstr "or: argument %d ujemna wartość %g spowoduje dziwne wyniki"
-#: builtin.c:2922
-msgid "xor: received non-numeric second argument"
-msgstr "xor: otrzymano drugi argument, który nie jest liczbą"
+#: builtin.c:3167 mpfr.c:1031
+msgid "xor: called with less than two arguments"
+msgstr "xor: wywołano z mniej niż dwoma argumentami"
-#: builtin.c:2928
+#: builtin.c:3173
#, c-format
-msgid "xor(%lf, %lf): negative values will give strange results"
-msgstr "xor(%lf, %lf): ujemne wartości spowodują dziwne wyniki"
+msgid "xor: argument %d is non-numeric"
+msgstr "xor: argument %d nie jest liczbÄ…"
-#: builtin.c:2930
+#: builtin.c:3177
#, c-format
-msgid "xor(%lf, %lf): fractional values will be truncated"
-msgstr "xor(%lf, %lf): ułamkowe wartości zostaną obcięte"
+msgid "xor: argument %d negative value %g will give strange results"
+msgstr "xor: argument %d ujemna wartość %g spowoduje dziwne wyniki"
-#: builtin.c:2954 builtin.c:2960
+#: builtin.c:3202 mpfr.c:787
msgid "compl: received non-numeric argument"
msgstr "compl: otrzymano argument, który nie jest liczbą"
-#: builtin.c:2962
+#: builtin.c:3208
#, c-format
-msgid "compl(%lf): negative value will give strange results"
-msgstr "compl(%lf): ujemne wartości spowodują dziwne wyniki"
+msgid "compl(%f): negative value will give strange results"
+msgstr "compl(%f): ujemne wartości spowodują dziwne wyniki"
-#: builtin.c:2964
+#: builtin.c:3210
#, c-format
-msgid "compl(%lf): fractional value will be truncated"
-msgstr "compl(%lf): ułamkowe wartości zostaną obcięte"
+msgid "compl(%f): fractional value will be truncated"
+msgstr "compl(%f): ułamkowe wartości zostaną obcięte"
-#: builtin.c:3133
+#: builtin.c:3379
#, c-format
msgid "dcgettext: `%s' is not a valid locale category"
msgstr "dcgettext: `%s' nie jest prawidłową kategorią lokalizacji"
-#: eval.c:412
+#: command.y:225
+#, c-format
+msgid "Type (g)awk statement(s). End with the command \"end\"\n"
+msgstr "Podaj komendy (g)awk. Zakończ poleceniem \"end\"\n"
+
+#: command.y:289
+#, c-format
+msgid "invalid frame number: %d"
+msgstr "nieprawidłowy numer ramki: %d"
+
+#: command.y:295
+#, c-format
+msgid "info: invalid option - \"%s\""
+msgstr "info: nieprawidłowa opcja - \"%s\""
+
+#: command.y:321
+#, c-format
+msgid "source \"%s\": already sourced."
+msgstr "source \"%s\": stanowi już źródło."
+
+#: command.y:326
+#, c-format
+msgid "save \"%s\": command not permitted."
+msgstr "save \"%s\": niedozwolona komenda."
+
+#: command.y:339
+msgid "Can't use command `commands' for breakpoint/watchpoint commands"
+msgstr "Nie można użyć polecenia `commands' dla komend breakpoint/watchpoint."
+
+#: command.y:341
+msgid "no breakpoint/watchpoint has been set yet"
+msgstr "nie ustawiono jeszcze breakpoint/watchpoint"
+
+#: command.y:343
+msgid "invalid breakpoint/watchpoint number"
+msgstr "nieprawidłowy numer breakpoint/watchpoint"
+
+#: command.y:348
+#, c-format
+msgid "Type commands for when %s %d is hit, one per line.\n"
+msgstr ""
+
+#: command.y:350
+#, c-format
+msgid "End with the command \"end\"\n"
+msgstr "Zakończ komendą \"end\"\n"
+
+#: command.y:357
+msgid "`end' valid only in command `commands' or `eval'"
+msgstr "`end' dozwolony jedynie dla komendy `commands' lub `eval'"
+
+#: command.y:367
+msgid "`silent' valid only in command `commands'"
+msgstr "polecenie `silent' dozwolone jedynie w komendzie `commands'"
+
+#: command.y:373
+#, c-format
+msgid "trace: invalid option - \"%s\""
+msgstr "trace: nieprawidłowa opcja - \"%s\""
+
+#: command.y:387
+msgid "condition: invalid breakpoint/watchpoint number"
+msgstr "condition: nieprawidłowy numer breakpoint/watchpoint"
+
+#: command.y:449
+msgid "argument not a string"
+msgstr "argument nie jest łańcuchem tekstowym"
+
+#: command.y:459 command.y:464
+#, c-format
+msgid "option: invalid parameter - \"%s\""
+msgstr "option: nieprawidłowy parametr - \"%s\""
+
+#: command.y:474
+#, c-format
+msgid "no such function - \"%s\""
+msgstr "brak takiej funkcji - \"%s\""
+
+#: command.y:531
+#, c-format
+msgid "enable: invalid option - \"%s\""
+msgstr "enable: nieprawidłowa opcja - \"%s\""
+
+#: command.y:597
+#, c-format
+msgid "invalid range specification: %d - %d"
+msgstr "nieprawidłowy zakres specyfikacji: %d - %d"
+
+#: command.y:659
+msgid "non-numeric value for field number"
+msgstr "nienumeryczna wartość dla numeru pola"
+
+#: command.y:680 command.y:687
+msgid "non-numeric value found, numeric expected"
+msgstr "znaleziono nienumeryczną wartość, spodziewano się numerycznej"
+
+#: command.y:712 command.y:718
+msgid "non-zero integer value"
+msgstr "niezerowa wartość"
+
+#: command.y:817
+msgid ""
+"backtrace [N] - print trace of all or N innermost (outermost if N < 0) "
+"frames."
+msgstr ""
+
+#: command.y:819
+msgid ""
+"break [[filename:]N|function] - set breakpoint at the specified location."
+msgstr ""
+
+#: command.y:821
+msgid "clear [[filename:]N|function] - delete breakpoints previously set."
+msgstr ""
+
+#: command.y:823
+msgid ""
+"commands [num] - starts a list of commands to be executed at a "
+"breakpoint(watchpoint) hit."
+msgstr ""
+
+#: command.y:825
+msgid "condition num [expr] - set or clear breakpoint or watchpoint condition."
+msgstr ""
+
+#: command.y:827
+msgid "continue [COUNT] - continue program being debugged."
+msgstr ""
+
+#: command.y:829
+msgid "delete [breakpoints] [range] - delete specified breakpoints."
+msgstr ""
+
+#: command.y:831
+msgid "disable [breakpoints] [range] - disable specified breakpoints."
+msgstr ""
+
+#: command.y:833
+msgid "display [var] - print value of variable each time the program stops."
+msgstr ""
+
+#: command.y:835
+msgid "down [N] - move N frames down the stack."
+msgstr ""
+
+#: command.y:837
+msgid "dump [filename] - dump instructions to file or stdout."
+msgstr ""
+
+#: command.y:839
+msgid "enable [once|del] [breakpoints] [range] - enable specified breakpoints."
+msgstr ""
+
+#: command.y:841
+msgid "end - end a list of commands or awk statements."
+msgstr ""
+
+#: command.y:843
+msgid "eval stmt|[p1, p2, ...] - evaluate awk statement(s)."
+msgstr ""
+
+#: command.y:845
+msgid "finish - execute until selected stack frame returns."
+msgstr ""
+
+#: command.y:847
+msgid "frame [N] - select and print stack frame number N."
+msgstr ""
+
+#: command.y:849
+msgid "help [command] - print list of commands or explanation of command."
+msgstr ""
+
+#: command.y:851
+msgid "ignore N COUNT - set ignore-count of breakpoint number N to COUNT."
+msgstr ""
+
+#: command.y:853
+msgid ""
+"info topic - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch."
+msgstr ""
+
+#: command.y:855
+msgid "list [-|+|[filename:]lineno|function|range] - list specified line(s)."
+msgstr ""
+
+#: command.y:857
+msgid "next [COUNT] - step program, proceeding through subroutine calls."
+msgstr ""
+
+#: command.y:859
+msgid ""
+"nexti [COUNT] - step one instruction, but proceed through subroutine calls."
+msgstr ""
+
+#: command.y:861
+msgid "option [name[=value]] - set or display debugger option(s)."
+msgstr ""
+
+#: command.y:863
+msgid "print var [var] - print value of a variable or array."
+msgstr ""
+
+#: command.y:865
+msgid "printf format, [arg], ... - formatted output."
+msgstr ""
+
+#: command.y:867
+msgid "quit - exit debugger."
+msgstr ""
+
+#: command.y:869
+msgid "return [value] - make selected stack frame return to its caller."
+msgstr ""
+
+#: command.y:871
+msgid "run - start or restart executing program."
+msgstr ""
+
+#: command.y:874
+msgid "save filename - save commands from the session to file."
+msgstr ""
+
+#: command.y:877
+msgid "set var = value - assign value to a scalar variable."
+msgstr ""
+
+#: command.y:879
+msgid ""
+"silent - suspends usual message when stopped at a breakpoint/watchpoint."
+msgstr ""
+
+#: command.y:881
+msgid "source file - execute commands from file."
+msgstr ""
+
+#: command.y:883
+msgid "step [COUNT] - step program until it reaches a different source line."
+msgstr ""
+
+#: command.y:885
+msgid "stepi [COUNT] - step one instruction exactly."
+msgstr ""
+
+#: command.y:887
+msgid "tbreak [[filename:]N|function] - set a temporary breakpoint."
+msgstr ""
+
+#: command.y:889
+msgid "trace on|off - print instruction before executing."
+msgstr ""
+
+#: command.y:891
+msgid "undisplay [N] - remove variable(s) from automatic display list."
+msgstr ""
+
+#: command.y:893
+msgid ""
+"until [[filename:]N|function] - execute until program reaches a different "
+"line or line N within current frame."
+msgstr ""
+
+#: command.y:895
+msgid "unwatch [N] - remove variable(s) from watch list."
+msgstr ""
+
+#: command.y:897
+msgid "up [N] - move N frames up the stack."
+msgstr ""
+
+#: command.y:899
+msgid "watch var - set a watchpoint for a variable."
+msgstr ""
+
+#: command.y:1011 debug.c:401 msg.c:135
+#, c-format
+msgid "error: "
+msgstr "błąd: "
+
+#: command.y:1051
+#, c-format
+msgid "can't read command (%s)\n"
+msgstr "nie można odczytać komendy (%s)\n"
+
+#: command.y:1065
+#, c-format
+msgid "can't read command (%s)"
+msgstr "nie można odczytać komendy (%s)"
+
+#: command.y:1116
+msgid "invalid character in command"
+msgstr "nieprawidłowy znak w komendzie"
+
+#: command.y:1152
+#, c-format
+msgid "unknown command - \"%.*s\", try help"
+msgstr "nieznana komenda - \"%.*s\", spróbuj pomoc"
+
+#: command.y:1222
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: command.y:1284
+msgid "invalid character"
+msgstr "nieprawidłowy znak"
+
+#: command.y:1455
+#, c-format
+msgid "undefined command: %s\n"
+msgstr "niezdefiniowana komenda: %s\n"
+
+#: debug.c:252
+msgid "set or show the number of lines to keep in history file."
+msgstr ""
+
+#: debug.c:254
+msgid "set or show the list command window size."
+msgstr ""
+
+#: debug.c:256
+msgid "set or show gawk output file."
+msgstr ""
+
+#: debug.c:258
+msgid "set or show debugger prompt."
+msgstr ""
+
+#: debug.c:260
+msgid "(un)set or show saving of command history (value=on|off)."
+msgstr ""
+
+#: debug.c:262
+msgid "(un)set or show saving of options (value=on|off)."
+msgstr ""
+
+#: debug.c:264
+msgid "(un)set or show instruction tracing (value=on|off)."
+msgstr ""
+
+#: debug.c:345
+msgid "program not running."
+msgstr ""
+
+#: debug.c:448 debug.c:606
+#, c-format
+msgid "can't read source file `%s' (%s)"
+msgstr "nie można odczytać pliku źródłowego `%s' (%s)"
+
+#: debug.c:453
+#, c-format
+msgid "source file `%s' is empty.\n"
+msgstr "plik źródłowy `%s' jest pusty.\n"
+
+#: debug.c:480
+msgid "no current source file."
+msgstr "brak aktualnego pliku źródłowego."
+
+#: debug.c:505
+#, c-format
+msgid "cannot find source file named `%s' (%s)"
+msgstr "nie można znaleźć pliku źródłowego `%s' (%s)"
+
+#: debug.c:529
+#, c-format
+msgid "WARNING: source file `%s' modified since program compilation.\n"
+msgstr "UWAGA: plik źródłowy `%s' uległ zmianie od kompilacji programu.\n"
+
+#: debug.c:551
+#, c-format
+msgid "line number %d out of range; `%s' has %d lines"
+msgstr ""
+
+#: debug.c:611
+#, c-format
+msgid "unexpected eof while reading file `%s', line %d"
+msgstr "niespodziewany koniec pliku podczas czytania `%s', linia %d"
+
+#: debug.c:620
+#, c-format
+msgid "source file `%s' modified since start of program execution"
+msgstr "plik źródłowy `%s' uległ zmianie od rozpoczęcia działania programu"
+
+#: debug.c:732
+#, c-format
+msgid "Current source file: %s\n"
+msgstr "Aktualny plik źródłowy: %s\n"
+
+#: debug.c:733
+#, c-format
+msgid "Number of lines: %d\n"
+msgstr "Ilość linii: %d\n"
+
+#: debug.c:740
+#, c-format
+msgid "Source file (lines): %s (%d)\n"
+msgstr "Plik źródłowy (linie): %s (%d)\n"
+
+#: debug.c:754
+msgid ""
+"Number Disp Enabled Location\n"
+"\n"
+msgstr ""
+"Numer Disp Enabled Lokacja\n"
+"\n"
+
+#: debug.c:765
+#, c-format
+msgid "\tno of hits = %ld\n"
+msgstr ""
+
+#: debug.c:767
+#, c-format
+msgid "\tignore next %ld hit(s)\n"
+msgstr ""
+
+#: debug.c:769 debug.c:909
+#, c-format
+msgid "\tstop condition: %s\n"
+msgstr "\tkoniec warunku: %s\n"
+
+#: debug.c:771 debug.c:911
+msgid "\tcommands:\n"
+msgstr "\tkomendy:\n"
+
+#: debug.c:793
+#, c-format
+msgid "Current frame: "
+msgstr "Aktualna ramka: "
+
+#: debug.c:796
+#, c-format
+msgid "Called by frame: "
+msgstr ""
+
+#: debug.c:800
+#, c-format
+msgid "Caller of frame: "
+msgstr ""
+
+#: debug.c:818
+#, c-format
+msgid "None in main().\n"
+msgstr ""
+
+#: debug.c:848
+msgid "No arguments.\n"
+msgstr "Brak argumentów.\n"
+
+#: debug.c:849
+msgid "No locals.\n"
+msgstr ""
+
+#: debug.c:857
+msgid ""
+"All defined variables:\n"
+"\n"
+msgstr ""
+"Wszystkie zdefiniowane zmienne:\n"
+"\n"
+
+#: debug.c:867
+msgid ""
+"All defined functions:\n"
+"\n"
+msgstr ""
+"Wszystkie zdefiniowane funkcje:\n"
+"\n"
+
+#: debug.c:886
+msgid ""
+"Auto-display variables:\n"
+"\n"
+msgstr ""
+
+#: debug.c:889
+msgid ""
+"Watch variables:\n"
+"\n"
+msgstr ""
+"Obserwowane zmienne:\n"
+"\n"
+
+#: debug.c:1029
+#, c-format
+msgid "no symbol `%s' in current context\n"
+msgstr "brak symbolu `%s' w bieżącym kontekście\n"
+
+#: debug.c:1041 debug.c:1427
+#, c-format
+msgid "`%s' is not an array\n"
+msgstr "`%s' nie jest tablicÄ…\n"
+
+#: debug.c:1055
+#, c-format
+msgid "$%ld = uninitialized field\n"
+msgstr "$%ld = niezainicjowane pole\n"
+
+#: debug.c:1076
+#, c-format
+msgid "array `%s' is empty\n"
+msgstr "tablica `%s' jest pusta\n"
+
+#: debug.c:1119 debug.c:1171
+#, c-format
+msgid "[\"%s\"] not in array `%s'\n"
+msgstr "[\"%s\"] nie ma w tablicy `%s'\n"
+
+#: debug.c:1175
+#, c-format
+msgid "`%s[\"%s\"]' is not an array\n"
+msgstr "`%s[\"%s\"]' nie jest tablicÄ…\n"
+
+#: debug.c:1236 debug.c:4964
+#, c-format
+msgid "`%s' is not a scalar variable"
+msgstr "`%s' nie jest zmiennÄ… skalarnÄ…"
+
+#: debug.c:1258 debug.c:4994
+#, c-format
+msgid "attempt to use array `%s[\"%s\"]' in a scalar context"
+msgstr "próba użycia tablicy `%s[\"%s\"]' w kontekście skalaru"
+
+#: debug.c:1280 debug.c:5005
+#, c-format
+msgid "attempt to use scalar `%s[\"%s\"]' as array"
+msgstr "próba użycia skalaru `%s[\"%s\"]' jako tablicy"
+
+#: debug.c:1423
+#, c-format
+msgid "`%s' is a function"
+msgstr "`%s' jest funkcjÄ…"
+
+#: debug.c:1465
+#, c-format
+msgid "watchpoint %d is unconditional\n"
+msgstr ""
+
+#: debug.c:1499
+#, c-format
+msgid "No display item numbered %ld"
+msgstr ""
+
+#: debug.c:1502
+#, c-format
+msgid "No watch item numbered %ld"
+msgstr ""
+
+#: debug.c:1528
+#, c-format
+msgid "%d: [\"%s\"] not in array `%s'\n"
+msgstr "%d: [\"%s\"] nie ma w tablicy `%s'\n"
+
+#: debug.c:1767
+msgid "attempt to use scalar value as array"
+msgstr "próba użycia wartości skalarnej jako tablicy"
+
+#: debug.c:1856
+#, c-format
+msgid "Watchpoint %d deleted because parameter is out of scope.\n"
+msgstr ""
+
+#: debug.c:1867
+#, c-format
+msgid "Display %d deleted because parameter is out of scope.\n"
+msgstr ""
+
+#: debug.c:1900
+#, c-format
+msgid " in file `%s', line %d\n"
+msgstr " w pliku `%s', linia %d\n"
+
+#: debug.c:1921
+#, c-format
+msgid " at `%s':%d"
+msgstr " w `%s':%d"
+
+#: debug.c:1937 debug.c:2000
+#, c-format
+msgid "#%ld\tin "
+msgstr "#%ld\tw "
+
+#: debug.c:1974
+#, c-format
+msgid "More stack frames follow ...\n"
+msgstr ""
+
+#: debug.c:2017
+msgid "invalid frame number"
+msgstr "nieprawidłowy numer ramki"
+
+#: debug.c:2200
+#, c-format
+msgid "Note: breakpoint %d (enabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2207
+#, c-format
+msgid "Note: breakpoint %d (enabled), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2214
+#, c-format
+msgid "Note: breakpoint %d (disabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2221
+#, c-format
+msgid "Note: breakpoint %d (disabled), also set at %s:%d"
+msgstr ""
+
+#: debug.c:2238
+#, c-format
+msgid "Breakpoint %d set at file `%s', line %d\n"
+msgstr "Breakpoint %d ustawiony w pliku `%s', linia %d\n"
+
+#: debug.c:2340
+#, c-format
+msgid "Can't set breakpoint in file `%s'\n"
+msgstr ""
+
+#: debug.c:2369 debug.c:2492 debug.c:3350
+#, c-format
+msgid "line number %d in file `%s' out of range"
+msgstr "numer linii %d w pliku `%s' jest poza zasięgiem"
+
+#: debug.c:2373
+#, c-format
+msgid "Can't find rule!!!\n"
+msgstr "Nie można znaleźć reguły!!!\n"
+
+#: debug.c:2375
+#, c-format
+msgid "Can't set breakpoint at `%s':%d\n"
+msgstr ""
+
+#: debug.c:2387
+#, c-format
+msgid "Can't set breakpoint in function `%s'\n"
+msgstr ""
+
+#: debug.c:2403
+#, c-format
+msgid "breakpoint %d set at file `%s', line %d is unconditional\n"
+msgstr ""
+
+#: debug.c:2508 debug.c:2530
+#, c-format
+msgid "Deleted breakpoint %d"
+msgstr "Skasowany breakpoint %d"
+
+#: debug.c:2514
+#, c-format
+msgid "No breakpoint(s) at entry to function `%s'\n"
+msgstr ""
+
+#: debug.c:2541
+#, c-format
+msgid "No breakpoint at file `%s', line #%d\n"
+msgstr "Brak breakpointa w pliku `%s', linii #%d\n"
+
+#: debug.c:2596 debug.c:2637 debug.c:2657 debug.c:2700
+msgid "invalid breakpoint number"
+msgstr ""
+
+#: debug.c:2612
+msgid "Delete all breakpoints? (y or n) "
+msgstr "Czy skasować wszystkie breakpointy? (y lub n) "
+
+#: debug.c:2613 debug.c:2923 debug.c:2976
+msgid "y"
+msgstr "t"
+
+#: debug.c:2662
+#, c-format
+msgid "Will ignore next %ld crossing(s) of breakpoint %d.\n"
+msgstr ""
+
+#: debug.c:2666
+#, c-format
+msgid "Will stop next time breakpoint %d is reached.\n"
+msgstr ""
+
+#: debug.c:2783
+#, c-format
+msgid "Can only debug programs provided with the `-f' option.\n"
+msgstr ""
+
+#: debug.c:2908
+#, c-format
+msgid "Failed to restart debugger"
+msgstr ""
+
+#: debug.c:2922
+msgid "Program already running. Restart from beginning (y/n)? "
+msgstr ""
+
+#: debug.c:2926
+#, c-format
+msgid "Program not restarted\n"
+msgstr ""
+
+#: debug.c:2936
+#, c-format
+msgid "error: cannot restart, operation not allowed\n"
+msgstr ""
+
+#: debug.c:2942
+#, c-format
+msgid "error (%s): cannot restart, ignoring rest of the commands\n"
+msgstr ""
+
+#: debug.c:2950
+#, c-format
+msgid "Starting program: \n"
+msgstr "Uruchamianie programu: \n"
+
+#: debug.c:2959
+#, c-format
+msgid "Program exited %s with exit value: %d\n"
+msgstr ""
+
+#: debug.c:2975
+msgid "The program is running. Exit anyway (y/n)? "
+msgstr ""
+
+#: debug.c:3010
+#, c-format
+msgid "Not stopped at any breakpoint; argument ignored.\n"
+msgstr ""
+
+#: debug.c:3015
+#, c-format
+msgid "invalid breakpoint number %d."
+msgstr ""
+
+#: debug.c:3020
+#, c-format
+msgid "Will ignore next %ld crossings of breakpoint %d.\n"
+msgstr ""
+
+#: debug.c:3207
+#, c-format
+msgid "'finish' not meaningful in the outermost frame main()\n"
+msgstr ""
+
+#: debug.c:3212
+#, c-format
+msgid "Run till return from "
+msgstr ""
+
+#: debug.c:3255
+#, c-format
+msgid "'return' not meaningful in the outermost frame main()\n"
+msgstr ""
+
+#: debug.c:3369
+#, c-format
+msgid "Can't find specified location in function `%s'\n"
+msgstr ""
+
+#: debug.c:3377
+#, c-format
+msgid "invalid source line %d in file `%s'"
+msgstr "nieprawidłowa linia źródłowa %d w pliku `%s'"
+
+#: debug.c:3392
+#, c-format
+msgid "Can't find specified location %d in file `%s'\n"
+msgstr ""
+
+#: debug.c:3424
+#, c-format
+msgid "element not in array\n"
+msgstr "brak elementu w tablicy\n"
+
+#: debug.c:3424
+#, c-format
+msgid "untyped variable\n"
+msgstr "zmienna bez typu\n"
+
+#: debug.c:3466
+#, c-format
+msgid "Stopping in %s ...\n"
+msgstr ""
+
+#: debug.c:3543
+#, c-format
+msgid "'finish' not meaningful with non-local jump '%s'\n"
+msgstr ""
+
+#: debug.c:3550
+#, c-format
+msgid "'until' not meaningful with non-local jump '%s'\n"
+msgstr ""
+
+#: debug.c:4185
+msgid "\t------[Enter] to continue or q [Enter] to quit------"
+msgstr ""
+
+#: debug.c:4186
+msgid "q"
+msgstr "q"
+
+#: debug.c:5001
+#, c-format
+msgid "[\"%s\"] not in array `%s'"
+msgstr "[\"%s\"] nie ma w tablicy `%s'"
+
+#: debug.c:5207
+#, c-format
+msgid "sending output to stdout\n"
+msgstr "wysyłanie wyjścia na stdout\n"
+
+#: debug.c:5247
+msgid "invalid number"
+msgstr "nieprawidłowa liczba"
+
+#: debug.c:5381
+#, c-format
+msgid "`%s' not allowed in current context; statement ignored"
+msgstr "polecenie `%s' nie może być wywołane w tym kontekście; zignorowano"
+
+#: debug.c:5389
+msgid "`return' not allowed in current context; statement ignored"
+msgstr ""
+"instrukcja `return' nie może być wywołana w tym kontekście; zignorowano"
+
+#: debug.c:5590
+#, c-format
+msgid "No symbol `%s' in current context"
+msgstr "Brak symbolu `%s' w bieżącym kontekście"
+
+#: dfa.c:1118 dfa.c:1121 dfa.c:1142 dfa.c:1150 dfa.c:1162 dfa.c:1197
+#: dfa.c:1206 dfa.c:1209 dfa.c:1214 dfa.c:1228 dfa.c:1275
+msgid "unbalanced ["
+msgstr "[ nie do pary"
+
+#: dfa.c:1174
+msgid "invalid character class"
+msgstr "nieprawidłowa klasa znaku"
+
+#: dfa.c:1316
+msgid "character class syntax is [[:space:]], not [:space:]"
+msgstr "składnia klasy znaku to [[:space:]], a nie [:space:]"
+
+#: dfa.c:1366
+msgid "unfinished \\ escape"
+msgstr "niedokończona sekwencja ucieczki \\"
+
+#: dfa.c:1513 regcomp.c:161
+msgid "Invalid content of \\{\\}"
+msgstr "Nieprawidłowa zawartość \\{\\}"
+
+#: dfa.c:1516 regcomp.c:176
+msgid "Regular expression too big"
+msgstr "Wyrażenie regularne jest zbyt duże"
+
+#: dfa.c:1936
+msgid "unbalanced ("
+msgstr "( nie do pary"
+
+#: dfa.c:2062
+msgid "no syntax specified"
+msgstr "nie podano składni"
+
+#: dfa.c:2070
+msgid "unbalanced )"
+msgstr ") nie do pary"
+
+#: eval.c:394
#, c-format
msgid "unknown nodetype %d"
msgstr "nieznany typ węzła %d"
-#: eval.c:423 eval.c:437
+#: eval.c:405 eval.c:419
#, c-format
msgid "unknown opcode %d"
msgstr "nieznany opcode %d"
-#: eval.c:434
+#: eval.c:416
#, c-format
msgid "opcode %s not an operator or keyword"
msgstr "opcode %s nie jest operatorem ani słowem kluczowym"
-#: eval.c:488
+#: eval.c:472
msgid "buffer overflow in genflags2str"
msgstr "przepełnienie bufora w genflags2str"
-#: eval.c:698
+#: eval.c:675
#, c-format
msgid ""
"\n"
@@ -1006,830 +1850,1248 @@ msgstr ""
"\t# Stos Wywoławczy Funkcji:\n"
"\n"
-#: eval.c:725
+#: eval.c:704
msgid "`IGNORECASE' is a gawk extension"
msgstr "`IGNORECASE' jest rozszerzeniem gawk"
-#: eval.c:754
+#: eval.c:736
msgid "`BINMODE' is a gawk extension"
msgstr "`BINMODE' jest rozszerzeniem gawk"
-#: eval.c:812
+#: eval.c:794
#, c-format
msgid "BINMODE value `%s' is invalid, treated as 3"
msgstr "wartość BINMODE `%s' jest nieprawidłowa, przyjęto ją jako 3"
-#: eval.c:902
+#: eval.c:885
#, c-format
msgid "bad `%sFMT' specification `%s'"
msgstr "zła specyfikacja `%sFMT' `%s'"
-#: eval.c:980
+#: eval.c:969
msgid "turning off `--lint' due to assignment to `LINT'"
msgstr "wyłączenie `--lint' z powodu przypisania do `LINT'"
-#: eval.c:1127 eval.c:1777
-#, 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:1158 eval.c:1789 eval.c:1802
+#: eval.c:1147
#, c-format
msgid "reference to uninitialized argument `%s'"
msgstr "odwołanie do niezainicjowanego argumentu `%s'"
-#: eval.c:1177
+#: eval.c:1148
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "odwołanie do niezainicjowanej zmiennej `%s'"
+
+#: eval.c:1166
msgid "attempt to field reference from non-numeric value"
msgstr "próba odwołania do pola poprzez nienumeryczną wartość"
-#: eval.c:1179
+#: eval.c:1168
msgid "attempt to field reference from null string"
msgstr "próba odwołania z zerowego łańcucha"
-#: eval.c:1185
+#: eval.c:1176
#, c-format
msgid "attempt to access field %ld"
msgstr "próba dostępu do pola %ld"
-#: eval.c:1194
+#: eval.c:1185
#, c-format
msgid "reference to uninitialized field `$%ld'"
msgstr "odwołanie do niezainicjowanego pola `$%ld'"
-#: eval.c:1256
+#: eval.c:1272
#, 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:1437
+#: eval.c:1473
#, c-format
msgid "unwind_stack: unexpected type `%s'"
msgstr "unwind_stack: niespodziewany typ `%s'"
-#: eval.c:1532
+#: eval.c:1569
msgid "division by zero attempted in `/='"
msgstr "próba dzielenia przez zero w `/='"
-#: eval.c:1539
+#: eval.c:1576
#, c-format
msgid "division by zero attempted in `%%='"
msgstr "próba dzielenia przez zero w `%%='"
-#: eval.c:1876 eval.c:2122
-#, c-format
-msgid "attempt to use array `%s[\"%.*s\"]' in a scalar context"
-msgstr "próba użycia tablicy `%s[\"%.*s\"]' w kontekście skalaru"
+#: ext.c:89 ext.c:171
+msgid "extensions are not allowed in sandbox mode"
+msgstr "rozszerzenia nie sÄ… dozwolone w trybie piaskownicy"
-#: eval.c:1907
-msgid "assignment used in conditional context"
-msgstr "przypisanie użyte w kontekście warunkowym"
+#: ext.c:92
+msgid "-l / @load are gawk extensions"
+msgstr "-l / @load sÄ… rozszerzeniami gawk"
-#: eval.c:1911
-msgid "statement has no effect"
-msgstr "instrukcja nie ma żadnego efektu"
+#: ext.c:95
+msgid "load_ext: received NULL lib_name"
+msgstr "load_ext: otrzymano NULL lib_name"
-#: eval.c:2343
+#: ext.c:98
#, 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"
+msgid "load_ext: cannot open library `%s' (%s)\n"
+msgstr "load_ext: nie można otworzyć biblioteki `%s' (%s)\n"
-#: eval.c:2458
+#: ext.c:104
#, c-format
-msgid "function called indirectly through `%s' does not exist"
-msgstr "pośrednio wywołana funkcja poprzez `%s' nie istnieje"
+msgid ""
+"load_ext: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"
+msgstr ""
+"load_ext: biblioteka `%s': nie definiuje `plugin_is_GPL_compatible' (%s)\n"
-#: eval.c:2470
+#: ext.c:110
#, c-format
-msgid "function `%s' not defined"
-msgstr "funkcja `%s' nie została zdefiniowana"
+msgid "load_ext: library `%s': cannot call function `%s' (%s)\n"
+msgstr "load_ext: biblioteka `%s': nie można wywołać funkcji `%s' (%s)\n"
-#: eval.c:2511
+#: ext.c:114
#, c-format
-msgid "non-redirected `getline' invalid inside `%s' rule"
+msgid "load_ext: library `%s' initialization routine `%s' failed\n"
msgstr ""
-"komenda `getline' bez przekierowania jest nieprawidłowa wewnątrz reguły `%s'"
+"load_ext: funkcja inicjalizująca `%s' biblioteki `%s' nie powiodła się\n"
-#: eval.c:2600
-#, c-format
-msgid "error reading input file `%s': %s"
-msgstr "błąd podczas czytania z pliku `%s': %s"
+#: ext.c:174
+msgid "`extension' is a gawk extension"
+msgstr "`extension' jest rozszerzeniem gawk"
-#: eval.c:2614
+#: ext.c:177
+msgid "extension: received NULL lib_name"
+msgstr "extension: otrzymano NULL lib_name"
+
+#: ext.c:180
#, c-format
-msgid "`nextfile' cannot be called from a `%s' rule"
-msgstr "instrukcja `nextfile' nie może być wywołana z wnętrza reguły `%s'"
+msgid "extension: cannot open library `%s' (%s)"
+msgstr "extension: nie można otworzyć biblioteki `%s' (%s)"
-#: eval.c:2694
+#: ext.c:186
#, c-format
-msgid "`next' cannot be called from a `%s' rule"
-msgstr "instrukcja `next' nie może być wywołana z wnętrza reguły `%s'"
+msgid ""
+"extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)"
+msgstr ""
+"extension: biblioteka `%s': nie definiuje `plugin_is_GPL_compatible' (%s)"
-#: eval.c:2760
+#: ext.c:190
#, c-format
-msgid "Sorry, don't know how to interpret `%s'"
-msgstr "Niestety nie wiem jak zinterpretować `%s'"
+msgid "extension: library `%s': cannot call function `%s' (%s)"
+msgstr "extension: biblioteka `%s': nie można wywołać funkcji `%s' (%s)"
-#: ext.c:64
-msgid "extensions are not allowed in sandbox mode"
-msgstr "rozszerzenia nie sÄ… dozwolone w trybie piaskownicy"
+#: ext.c:221
+msgid "make_builtin: missing function name"
+msgstr "make_builtin: brakujÄ…ca nazwa funkcji"
-#: ext.c:70 ext.c:75
-msgid "`extension' is a gawk extension"
-msgstr "`extension' jest rozszerzeniem gawk"
+#: ext.c:236
+#, c-format
+msgid "make_builtin: can't redefine function `%s'"
+msgstr "make_builtin: nie można zredefiniować funkcji `%s'"
-#: ext.c:85
+#: ext.c:240
#, c-format
-msgid "fatal: extension: cannot open `%s' (%s)\n"
-msgstr "fatal: rozszerzenie: nie można otworzyć `%s' (%s)\n"
+msgid "make_builtin: function `%s' already defined"
+msgstr "make_builtin: funkcja `%s' została już zdefiniowana"
-#: ext.c:94
+#: ext.c:244
#, c-format
-msgid ""
-"fatal: extension: library `%s': does not define "
-"`plugin_is_GPL_compatible' (%s)\n"
-msgstr ""
-"fatal: rozszerzenie: biblioteka `%s': nie definiuje "
-"`plugin_is_GPL_compatible' (%s)\n"
+msgid "make_builtin: function name `%s' previously defined"
+msgstr "make_builtin: nazwa funkcji `%s' została zdefiniowana wcześniej"
-#: ext.c:103
+#: ext.c:246
#, c-format
-msgid "fatal: extension: library `%s': cannot call function `%s' (%s)\n"
-msgstr ""
-"fatal: rozszerzenie: biblioteka `%s': nie można wywołać funkcji `%s' (%s)\n"
+msgid "make_builtin: can't use gawk built-in `%s' as function name"
+msgstr "make_builtin: nie można użyć wbudowanej w gawk `%s' jako nazwy funkcji"
+
+#: ext.c:249 ext.c:304
+#, c-format
+msgid "make_builtin: negative argument count for function `%s'"
+msgstr "make_builtin: ujemny licznik argumentów dla funkcji `%s'"
-#: ext.c:137
+#: ext.c:276
msgid "extension: missing function name"
-msgstr "rozszerzenie: brakujÄ…ca nazwa funkcji"
+msgstr "extension: brakujÄ…ca nazwa funkcji"
-#: ext.c:142
+#: ext.c:279 ext.c:283
#, c-format
msgid "extension: illegal character `%c' in function name `%s'"
-msgstr "rozszerzenie: nieprawidłowy znak `%c' w nazwie funkcji `%s'"
+msgstr "extension: nieprawidłowy znak `%c' w nazwie funkcji `%s'"
-#: ext.c:151
+#: ext.c:291
#, c-format
msgid "extension: can't redefine function `%s'"
-msgstr "rozszerzenie: nie można zredefiniować funkcji `%s'"
+msgstr "extension: nie można zredefiniować funkcji `%s'"
-#: ext.c:155
+#: ext.c:295
#, c-format
msgid "extension: function `%s' already defined"
-msgstr "rozserzenie: funkcja `%s' została już zdefiniowana"
+msgstr "extension: funkcja `%s' została już zdefiniowana"
-#: ext.c:160
+#: ext.c:299
#, c-format
msgid "extension: function name `%s' previously defined"
-msgstr "rozserzenie: nazwa funkcji `%s' została zdefiniowana wcześniej"
+msgstr "extension: nazwa funkcji `%s' została zdefiniowana wcześniej"
-#: ext.c:162
+#: ext.c:301
#, 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"
+msgstr "extension: nie można użyć wbudowanej w gawk `%s' jako nazwy funkcji"
-#: ext.c:166
-#, c-format
-msgid "make_builtin: negative argument count for function `%s'"
-msgstr "make_builtin: ujemny licznik argumentów dla funkcji `%s'"
-
-#: ext.c:269
+#: ext.c:375
#, 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:272
+#: ext.c:378
#, c-format
msgid "function `%s': missing argument #%d"
msgstr "funkcja `%s': brakuje #%d argumentu"
-#: ext.c:289
+#: ext.c:395
#, 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:293
+#: ext.c:399
#, 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:306
-msgid "Operation Not Supported"
-msgstr "Operacja nie jest wspierana"
+#: ext.c:413
+msgid "dynamic loading of library not supported"
+msgstr "dynamiczne Å‚adowanie biblioteki nie jest wspierane"
+
+#: extension/filefuncs.c:159
+msgid "chdir: called with incorrect number of arguments, expecting 1"
+msgstr "chdir: wywołano z nieprawidłową ilością argumentów, spodziewano się 1"
+
+#: extension/filefuncs.c:439
+#, c-format
+msgid "stat: unable to read symbolic link `%s'"
+msgstr "stat: nie można odczytać dowiązania symbolicznego `%s'"
+
+#: extension/filefuncs.c:472
+msgid "stat: called with wrong number of arguments"
+msgstr "stat: wywołano z nieprawidłową ilością argumentów"
+
+#: extension/filefuncs.c:479
+msgid "stat: bad parameters"
+msgstr "stat: złe parametry"
+
+#: extension/filefuncs.c:533
+#, c-format
+msgid "fts init: could not create variable %s"
+msgstr "fts init: nie można utworzyć zmiennej %s"
+
+#: extension/filefuncs.c:554
+msgid "fts is not supported on this system"
+msgstr "funkcja fts nie jest wspierana w tym systemie"
+
+#: extension/filefuncs.c:573
+msgid "fill_stat_element: could not create array"
+msgstr "fill_stat_element: nie można utworzyć tablicy"
+
+#: extension/filefuncs.c:582
+msgid "fill_stat_element: could not set element"
+msgstr "fill_stat_element: nie można ustawić elementu"
+
+#: extension/filefuncs.c:597
+msgid "fill_path_element: could not set element"
+msgstr "fill_path_element: nie można ustawić elementu"
+
+#: extension/filefuncs.c:613
+msgid "fill_error_element: could not set element"
+msgstr "fill_error_element: nie można ustawić elementu"
+
+#: extension/filefuncs.c:660 extension/filefuncs.c:707
+msgid "fts-process: could not create array"
+msgstr "fts-process: nie można utworzyć tablicy"
+
+#: extension/filefuncs.c:670 extension/filefuncs.c:717
+#: extension/filefuncs.c:735
+msgid "fts-process: could not set element"
+msgstr "fts-process: nie można ustawić elementu"
+
+#: extension/filefuncs.c:784
+msgid "fts: called with incorrect number of arguments, expecting 3"
+msgstr "fts: wywołano z nieprawidłową ilością argumentów, powinny być 3"
+
+#: extension/filefuncs.c:787
+msgid "fts: bad first parameter"
+msgstr "fts: nieprawidłowy pierwszy parametr"
+
+#: extension/filefuncs.c:793
+msgid "fts: bad second parameter"
+msgstr "fts: nieprawidłowy drugi parametr"
+
+#: extension/filefuncs.c:799
+msgid "fts: bad third parameter"
+msgstr "fts: nieprawidłowy trzeci parametr"
+
+#: extension/filefuncs.c:806
+msgid "fts: could not flatten array\n"
+msgstr "fts: nie można spłaszczyć tablicy\n"
+
+#: extension/filefuncs.c:824
+msgid "fts: ignoring sneaky FTS_NOSTAT flag. nyah, nyah, nyah."
+msgstr "fts: zignorowano flagÄ™ FTS_NOSTAT. nyah, nyah, nyah."
+
+#: extension/filefuncs.c:841
+msgid "fts: clear_array() failed\n"
+msgstr "fts: clear_array() nie powiodła się\n"
+
+#: extension/fnmatch.c:112
+msgid "fnmatch: called with less than three arguments"
+msgstr "fnmatch: wywołano z mniej niż trzema argumentami"
+
+#: extension/fnmatch.c:115
+msgid "fnmatch: called with more than three arguments"
+msgstr "fnmatch: wywołano z więcej niż trzema argumentami"
+
+#: extension/fnmatch.c:118
+msgid "fnmatch: could not get first argument"
+msgstr "fnmatch: nie można pobrać pierwszego argumentu"
+
+#: extension/fnmatch.c:123
+msgid "fnmatch: could not get second argument"
+msgstr "fnmatch: nie można pobrać drugiego argumentu"
+
+#: extension/fnmatch.c:128
+msgid "fnmatch: could not get third argument"
+msgstr "fnmatch: nie można pobrać trzeciego argumentu"
+
+#: extension/fnmatch.c:141
+msgid "fnmatch is not implemented on this system\n"
+msgstr "funkcja fnmatch nie została zaimplementowana w tym systemie\n"
+
+#: extension/fnmatch.c:173
+msgid "fnmatch init: could not add FNM_NOMATCH variable"
+msgstr "fnmatch init: nie można było dodać zmiennej FNM_NOMATCH"
+
+#: extension/fnmatch.c:183
+#, c-format
+msgid "fnmatch init: could not set array element %s"
+msgstr "fnmatch init: nie można było ustawić elementu tablicy %s"
+
+#: extension/fnmatch.c:193
+msgid "fnmatch init: could not install FNM array"
+msgstr "fnmatch init: nie można było zainstalować tablicy FNM"
+
+#: extension/fork.c:81
+msgid "fork: called with too many arguments"
+msgstr "fork: wywołana ze zbyt dużą ilością argumentów"
+
+#: extension/fork.c:94
+msgid "fork: PROCINFO is not an array!"
+msgstr "fork: PROCINFO nie jest tablicÄ…!"
+
+#: extension/fork.c:118
+msgid "waitpid: called with too many arguments"
+msgstr "waitpid: wywołana ze zbyt dużą ilością argumentów"
+
+#: extension/fork.c:126
+msgid "wait: called with no arguments"
+msgstr "wait: wywołano bez argumentów"
+
+#: extension/fork.c:143
+msgid "wait: called with too many arguments"
+msgstr "wait: wywołana ze zbyt dużą ilością argumentów"
+
+#: extension/inplace.c:130
+msgid "inplace_begin: in-place editing already active"
+msgstr "inplace_begin: edycja w miejscu jest już aktywna"
+
+#: extension/inplace.c:133 extension/inplace.c:207
+#, c-format
+msgid "inplace_begin: expects 2 arguments but called with %d"
+msgstr "inplace_begin: spodziewano się 2 argumentów, a otrzymano %d"
+
+#: extension/inplace.c:136
+msgid "inplace_begin: cannot retrieve 1st argument as a string filename"
+msgstr "inplace_begin: nie można pobrać pierwszego argumentu jako nazwy pliku"
+
+#: extension/inplace.c:144
+#, c-format
+msgid "inplace_begin: disabling in-place editing for invalid FILENAME `%s'"
+msgstr ""
+"inplace_begin: wyłączenie edycji w miejscu dla nieprawidłowej nazwy pliku `"
+"%s'"
+
+#: extension/inplace.c:151
+#, c-format
+msgid "inplace_begin: Cannot stat `%s' (%s)"
+msgstr "inplace_begin: nie można sprawdzić `%s' (%s)"
+
+#: extension/inplace.c:158
+#, c-format
+msgid "inplace_begin: `%s' is not a regular file"
+msgstr "inplace_begin: `%s' nie jest zwykłym plikiem"
+
+#: extension/inplace.c:169
+#, c-format
+msgid "inplace_begin: mkstemp(`%s') failed (%s)"
+msgstr "inplace_begin: wywołanie mkstemp(`%s') nie powiodło się (%s)"
+
+#: extension/inplace.c:178
+#, c-format
+msgid "inplace_begin: chmod failed (%s)"
+msgstr "inplace_begin: funkcja chmod nie powiodła się (%s)"
+
+#: extension/inplace.c:185
+#, c-format
+msgid "inplace_begin: dup(stdout) failed (%s)"
+msgstr "inplace_begin: wywołanie dup(stdout) nie powiodło się (%s)"
+
+#: extension/inplace.c:188
+#, c-format
+msgid "inplace_begin: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_begin: wywołanie dup2(%d, stdout) nie powiodło się (%s)"
+
+#: extension/inplace.c:191
+#, c-format
+msgid "inplace_begin: close(%d) failed (%s)"
+msgstr "inplace_begin: wywołanie close(%d) nie powiodło się (%s)"
+
+#: extension/inplace.c:210
+msgid "inplace_end: cannot retrieve 1st argument as a string filename"
+msgstr "inplace_end: nie można pobrać pierwszego argumentu jako nazwy pliku"
+
+#: extension/inplace.c:217
+msgid "inplace_end: in-place editing not active"
+msgstr "inplace_end: edycja w miejscu nie jest aktywna"
+
+#: extension/inplace.c:223
+#, c-format
+msgid "inplace_end: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_end: wywołanie dup2(%d, stdout) nie powiodło się (%s)"
+
+#: extension/inplace.c:226
+#, c-format
+msgid "inplace_end: close(%d) failed (%s)"
+msgstr "inplace_end: wywołanie close(%d) nie powiodło się (%s)"
+
+#: extension/inplace.c:230
+#, c-format
+msgid "inplace_end: fsetpos(stdout) failed (%s)"
+msgstr "inplace_end: wywołanie fsetpos(stdout) nie powiodło się (%s)"
+
+#: extension/inplace.c:243
+#, c-format
+msgid "inplace_end: link(`%s', `%s') failed (%s)"
+msgstr "inplace_end: wywołanie link(`%s', `%s') nie powiodło się (%s)"
+
+#: extension/inplace.c:253
+#, c-format
+msgid "inplace_end: rename(`%s', `%s') failed (%s)"
+msgstr "inplace_end: wywołanie rename(`%s', `%s') nie powiodło się (%s)"
+
+#: extension/ordchr.c:69
+msgid "ord: called with too many arguments"
+msgstr "ord: wywołana ze zbyt dużą ilością argumentów"
+
+#: extension/ordchr.c:75
+msgid "ord: called with no arguments"
+msgstr "ord: wywołano bez argumentów"
-#: field.c:328
+#: extension/ordchr.c:77
+msgid "ord: called with inappropriate argument(s)"
+msgstr "ord: wywołano z nieprawidłowymi argumentami"
+
+#: extension/ordchr.c:99
+msgid "chr: called with too many arguments"
+msgstr "chr: wywołana ze zbyt dużą ilością argumentów"
+
+#: extension/ordchr.c:109
+msgid "chr: called with no arguments"
+msgstr "chr: wywołano bez argumentów"
+
+#: extension/ordchr.c:111
+msgid "chr: called with inappropriate argument(s)"
+msgstr "chr: wywołano z nieprawidłowymi argumentami"
+
+#: extension/readdir.c:281
+#, c-format
+msgid "dir_take_control_of: opendir/fdopendir failed: %s"
+msgstr "dir_take_control_of: wywołanie opendir/fdopendir nie powiodło się: %s"
+
+#: extension/readfile.c:113
+msgid "readfile: called with too many arguments"
+msgstr "readfile: wywołana ze zbyt dużą ilością argumentów"
+
+#: extension/readfile.c:137
+msgid "readfile: called with no arguments"
+msgstr "readfile: wywołano bez argumentów"
+
+#: extension/rwarray.c:124
+msgid "writea: called with too many arguments"
+msgstr "writea: wywołana ze zbyt dużą ilością argumentów"
+
+#: extension/rwarray.c:131
+#, c-format
+msgid "do_writea: argument 0 is not a string\n"
+msgstr "do_writea: argument 0 nie jest tekstem\n"
+
+#: extension/rwarray.c:137
+#, c-format
+msgid "do_writea: argument 1 is not an array\n"
+msgstr "do_writea: argument 1 nie jest tablicÄ…\n"
+
+#: extension/rwarray.c:184
+#, c-format
+msgid "write_array: could not flatten array\n"
+msgstr "write_array: nie można spłaszczyć tablicy\n"
+
+#: extension/rwarray.c:198
+#, c-format
+msgid "write_array: could not release flattened array\n"
+msgstr "write_array: nie można było zwolnić spłaszczonej tablicy\n"
+
+#: extension/rwarray.c:280
+msgid "reada: called with too many arguments"
+msgstr "reada: wywołana ze zbyt dużą ilością argumentów"
+
+#: extension/rwarray.c:287
+#, c-format
+msgid "do_reada: argument 0 is not a string\n"
+msgstr "do_reada: argument 0 nie jest tekstem\n"
+
+#: extension/rwarray.c:293
+#, c-format
+msgid "do_reada: argument 1 is not an array\n"
+msgstr "do_reada: argument 1 nie jest tablicÄ…\n"
+
+#: extension/rwarray.c:337
+#, c-format
+msgid "do_reada: clear_array failed\n"
+msgstr "do_reada: clear_array nie powiodła się\n"
+
+#: extension/rwarray.c:374
+#, c-format
+msgid "read_array: set_array_element failed\n"
+msgstr "read_array: set_array_element nie powiodła się\n"
+
+#: extension/time.c:113
+msgid "gettimeofday: ignoring arguments"
+msgstr "gettimeofday: zignorowano argumenty"
+
+#: extension/time.c:144
+msgid "gettimeofday: not supported on this platform"
+msgstr "gettimeofday: funkcja nie jest wspierana na tej platformie"
+
+#: extension/time.c:165
+msgid "sleep: called with too many arguments"
+msgstr "sleep: wywołana ze zbyt dużą ilością argumentów"
+
+#: extension/time.c:168
+msgid "sleep: missing required numeric argument"
+msgstr "sleep: brakuje wymaganego argumentu numerycznego"
+
+#: extension/time.c:174
+msgid "sleep: argument is negative"
+msgstr "sleep: argument jest ujemny"
+
+#: extension/time.c:208
+msgid "sleep: not supported on this platform"
+msgstr "sleep: funkcja nie jest wspierana na tej platformie"
+
+#: field.c:345
msgid "NF set to negative value"
msgstr "NF ustawiony na wartość ujemną"
-#: field.c:951 field.c:958 field.c:962
+#: field.c:971 field.c:978 field.c:982
msgid "split: fourth argument is a gawk extension"
msgstr "split: czwarty argument jest rozszerzeniem gawk"
-#: field.c:955
+#: field.c:975
msgid "split: fourth argument is not an array"
msgstr "split: czwarty argument nie jest tablicÄ…"
-#: field.c:969
+#: field.c:989
msgid "split: second argument is not an array"
msgstr "split: drugi argument nie jest tablicÄ…"
-#: field.c:973
+#: field.c:993
msgid "split: cannot use the same array for second and fourth args"
msgstr ""
"split: nie można użyć tej samej tablicy dla drugiego i czwartego argumentu"
-#: field.c:978
+#: field.c:998
msgid "split: cannot use a subarray of second arg for fourth arg"
msgstr ""
"split: nie można użyć podtablicy drugiego argumentu dla czwartego argumentu"
-#: field.c:981
+#: field.c:1001
msgid "split: cannot use a subarray of fourth arg for second arg"
msgstr ""
"split: nie można użyć podtablicy czwartego argumentu dla drugiego argumentu"
-#: field.c:1010
+#: field.c:1032
msgid "split: null string for third arg is a gawk extension"
msgstr "split: zerowy łańcuch dla trzeciego argumentu jest rozszerzeniem gawk"
-#: field.c:1050
+#: field.c:1072
msgid "patsplit: fourth argument is not an array"
msgstr "patsplit: czwarty argument nie jest tablicÄ…"
-#: field.c:1055
+#: field.c:1077
msgid "patsplit: second argument is not an array"
msgstr "patsplit: drugi argument nie jest tablicÄ…"
-#: field.c:1061
+#: field.c:1083
msgid "patsplit: third argument must be non-null"
msgstr "patsplit: trzeci argument nie może być pusty"
-#: field.c:1065
+#: field.c:1087
msgid "patsplit: cannot use the same array for second and fourth args"
msgstr ""
"patsplit: nie można użyć tej samej tablicy dla drugiego i czwartego argumentu"
-#: field.c:1070
+#: field.c:1092
msgid "patsplit: cannot use a subarray of second arg for fourth arg"
msgstr ""
"patsplit: nie można użyć podtablicy drugiego argumentu dla czwartego "
"argumentu"
-#: field.c:1073
+#: field.c:1095
msgid "patsplit: cannot use a subarray of fourth arg for second arg"
msgstr ""
"patsplit: nie można użyć podtablicy czwartego argumentu dla drugiego "
"argumentu"
-#: field.c:1110
+#: field.c:1133
msgid "`FIELDWIDTHS' is a gawk extension"
msgstr "`FIELDWIDTHS' jest rozszerzeniem gawk"
-#: field.c:1173
+#: field.c:1197
#, c-format
msgid "invalid FIELDWIDTHS value, near `%s'"
msgstr "nieprawidłowa wartość FIELDWIDTHS, w pobliżu `%s'"
-#: field.c:1246
+#: field.c:1270
msgid "null string for `FS' is a gawk extension"
msgstr "zerowy łańcuch dla `FS' jest rozszerzeniem gawk"
-#: field.c:1250
+#: field.c:1274
msgid "old awk does not support regexps as value of `FS'"
msgstr "stary awk nie wspiera wyrażeń regularnych jako wartości `FS'"
-#: field.c:1369
+#: field.c:1393
msgid "`FPAT' is a gawk extension"
msgstr "`FPAT' jest rozszerzeniem gawk"
-#: getopt.c:574 getopt.c:590
+#: gawkapi.c:146
+msgid "awk_value_to_node: received null retval"
+msgstr "awk_value_to_node: otrzymano null retval"
+
+#: gawkapi.c:384
+msgid "node_to_awk_value: received null node"
+msgstr "node_to_awk_value: otrzymano null node"
+
+#: gawkapi.c:387
+msgid "node_to_awk_value: received null val"
+msgstr "node_to_awk_value: otrzymano null val"
+
+#: gawkapi.c:807
+msgid "remove_element: received null array"
+msgstr "remove_element: otrzymano tablicÄ™ null"
+
+#: gawkapi.c:810
+msgid "remove_element: received null subscript"
+msgstr "remove_element: otrzymano null subscript"
+
+#: gawkapi.c:947
+#, c-format
+msgid "api_flatten_array: could not convert index %d\n"
+msgstr "api_flatten_array: nie można było skonwertować indeksu %d\n"
+
+#: gawkapi.c:952
+#, c-format
+msgid "api_flatten_array: could not convert value %d\n"
+msgstr "api_flatten_array: nie można było skonwertować wartości %d\n"
+
+#: getopt.c:604 getopt.c:633
#, c-format
-msgid "%s: option '%s' is ambiguous\n"
-msgstr "%s: opcja '%s' jest niejednoznaczna\n"
+msgid "%s: option '%s' is ambiguous; possibilities:"
+msgstr "%s: opcja '%s' jest niejednoznaczna; możliwości:"
-#: getopt.c:623 getopt.c:627
+#: getopt.c:679 getopt.c:683
#, 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
+#: getopt.c:692 getopt.c:697
#, 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:684 getopt.c:703
+#: getopt.c:740 getopt.c:759
#, c-format
msgid "%s: option '--%s' requires an argument\n"
msgstr "%s: opcja '--%s' wymaga argumentu\n"
-#: getopt.c:741 getopt.c:744
+#: getopt.c:797 getopt.c:800
#, c-format
msgid "%s: unrecognized option '--%s'\n"
msgstr "%s: nieznana opcja '--%s'\n"
-#: getopt.c:752 getopt.c:755
+#: getopt.c:808 getopt.c:811
#, c-format
msgid "%s: unrecognized option '%c%s'\n"
msgstr "%s: nieznana opcja '%c%s'\n"
-#: getopt.c:804 getopt.c:807
+#: getopt.c:860 getopt.c:863
#, c-format
msgid "%s: invalid option -- '%c'\n"
msgstr "%s: błędna opcja -- '%c'\n"
-#: getopt.c:857 getopt.c:874 getopt.c:1082 getopt.c:1100
+#: getopt.c:916 getopt.c:933 getopt.c:1143 getopt.c:1161
#, c-format
msgid "%s: option requires an argument -- '%c'\n"
msgstr "%s: opcja wymaga argumentu -- '%c'\n"
-#: getopt.c:930 getopt.c:946
+#: getopt.c:989 getopt.c:1005
#, c-format
msgid "%s: option '-W %s' is ambiguous\n"
msgstr "%s: opcja '-W %s' jest niejednoznaczna\n"
-#: getopt.c:970 getopt.c:988
+#: getopt.c:1029 getopt.c:1047
#, 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"
-#: getopt.c:1009 getopt.c:1027
+#: getopt.c:1068 getopt.c:1086
#, c-format
msgid "%s: option '-W %s' requires an argument\n"
msgstr "%s: opcja '-W %s' wymaga argumentu\n"
-#: io.c:280
+#: io.c:392
#, c-format
msgid "command line argument `%s' is a directory: skipped"
msgstr "argument linii poleceń `%s' jest katalogiem: pominięto"
-#: io.c:283 io.c:385
+#: io.c:395 io.c:513
#, c-format
msgid "cannot open file `%s' for reading (%s)"
msgstr "nie można otworzyć pliku `%s' do czytania (%s)"
-#: io.c:501
+#: io.c:640
#, c-format
msgid "close of fd %d (`%s') failed (%s)"
msgstr "zamknięcie fd %d (`%s') nie powiodło się (%s)"
-#: io.c:578
+#: io.c:716
msgid "redirection not allowed in sandbox mode"
msgstr "przekierowanie nie jest dozwolone w trybie piaskownicy"
-#: io.c:612
+#: io.c:750
#, c-format
msgid "expression in `%s' redirection only has numeric value"
msgstr "wyrażenie w przekierowaniu `%s' ma tylko wartość numeryczną"
-#: io.c:618
+#: io.c:756
#, c-format
msgid "expression for `%s' redirection has null string value"
msgstr "wyrażenie dla przekierowania `%s' ma zerową wartość łańcucha"
-#: io.c:624
+#: io.c:761
#, 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:667
+#: io.c:809
#, c-format
msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
msgstr "niepotrzebne mieszanie `>' i `>>' dla pliku `%.*s'"
-#: io.c:720
+#: io.c:863
#, c-format
msgid "can't open pipe `%s' for output (%s)"
msgstr "nie można otworzyć potoku `%s' jako wyjścia (%s)"
-#: io.c:730
+#: io.c:873
#, c-format
msgid "can't open pipe `%s' for input (%s)"
msgstr "nie można otworzyć potoku `%s' jako wejścia (%s)"
-#: io.c:753
+#: io.c:904
#, 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:835
+#: io.c:986
#, c-format
msgid "can't redirect from `%s' (%s)"
msgstr "nie można przekierować z `%s' (%s)"
-#: io.c:838
+#: io.c:989
#, c-format
msgid "can't redirect to `%s' (%s)"
msgstr "nie można przekierować do `%s' (%s)"
-#: io.c:889
+#: io.c:1040
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:905
+#: io.c:1056
#, c-format
msgid "close of `%s' failed (%s)."
msgstr "zamknięcie `%s' nie powiodło się (%s)."
-#: io.c:913
+#: io.c:1064
msgid "too many pipes or input files open"
msgstr "zbyt dużo otwartych potoków lub plików wejściowych"
-#: io.c:935
+#: io.c:1086
msgid "close: second argument must be `to' or `from'"
msgstr "close: drugim argumentem musi być `to' lub `from'"
-#: io.c:952
+#: io.c:1103
#, 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:957
+#: io.c:1108
msgid "close of redirection that was never opened"
msgstr "zamknięcie przekierowania, które nigdy nie zostało otwarte"
-#: io.c:1054
+#: io.c:1205
#, 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:1070
+#: io.c:1222
#, c-format
msgid "failure status (%d) on pipe close of `%s' (%s)"
msgstr "status awarii (%d) podczas zamykania potoku `%s' (%s)"
-#: io.c:1073
+#: io.c:1225
#, c-format
msgid "failure status (%d) on file close of `%s' (%s)"
msgstr "status awarii (%d) podczas zamykania pliku `%s' (%s)"
-#: io.c:1093
+#: io.c:1245
#, c-format
msgid "no explicit close of socket `%s' provided"
msgstr "brak jawnego zamknięcia gniazdka `%s'"
-#: io.c:1096
+#: io.c:1248
#, c-format
msgid "no explicit close of co-process `%s' provided"
msgstr "brak jawnego zamknięcia procesu pomocniczego `%s'"
-#: io.c:1099
+#: io.c:1251
#, c-format
msgid "no explicit close of pipe `%s' provided"
msgstr "brak jawnego zamknięcia potoku `%s'"
-#: io.c:1102
+#: io.c:1254
#, c-format
msgid "no explicit close of file `%s' provided"
msgstr "brak jawnego zamknięcia pliku `%s'"
-#: io.c:1130 io.c:1185 main.c:793 main.c:830
+#: io.c:1284 io.c:1342 main.c:864 main.c:906
#, c-format
msgid "error writing standard output (%s)"
msgstr "błąd podczas zapisu na standardowe wyjście (%s)"
-#: io.c:1134 io.c:1190
+#: io.c:1289 io.c:1348 main.c:866
#, c-format
msgid "error writing standard error (%s)"
msgstr "błąd podczas zapisu na standardowe wyjście diagnostyczne (%s)"
-#: io.c:1142
+#: io.c:1297
#, c-format
msgid "pipe flush of `%s' failed (%s)."
msgstr "opróżnienie potoku `%s' nie powiodło się (%s)."
-#: io.c:1145
+#: io.c:1300
#, 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:1148
+#: io.c:1303
#, c-format
msgid "file flush of `%s' failed (%s)."
msgstr "opróżnienie pliku `%s' nie powiodło się (%s)."
-#: io.c:1263
+#: io.c:1420
#, c-format
msgid "local port %s invalid in `/inet'"
msgstr "nieprawidłowy lokalny port %s w `/inet'"
-#: io.c:1280
+#: io.c:1438
#, c-format
msgid "remote host and port information (%s, %s) invalid"
msgstr "informacje o zdalnym hoście i porcie są nieprawidłowe (%s, %s)"
-#: io.c:1432
+#: io.c:1590
#, c-format
msgid "no (known) protocol supplied in special filename `%s'"
msgstr "nie dostarczono (znanego) protokołu w specjalnym pliku `%s'"
-#: io.c:1446
+#: io.c:1604
#, c-format
msgid "special file name `%s' is incomplete"
msgstr "specjalna nazwa pliku `%s' jest niekompletna"
-#: io.c:1463
+#: io.c:1621
msgid "must supply a remote hostname to `/inet'"
msgstr "należy dostarczyć nazwę zdalnego hosta do `/inet'"
-#: io.c:1481
+#: io.c:1639
msgid "must supply a remote port to `/inet'"
msgstr "należy dostarczyć numer zdalnego portu do `/inet'"
-#: io.c:1527
+#: io.c:1685
msgid "TCP/IP communications are not supported"
msgstr "Komunikacja TCP/IP nie jest wspierana"
-#: io.c:1694
+#: io.c:1867
#, c-format
msgid "could not open `%s', mode `%s'"
msgstr "nie można otworzyć `%s', tryb `%s'"
-#: io.c:1748
+#: io.c:1917
#, c-format
msgid "close of master pty failed (%s)"
msgstr "zamknięcie nadrzędnego pty nie powiodło się (%s)"
-#: io.c:1750 io.c:1918 io.c:2075
+#: io.c:1919 io.c:2105 io.c:2305
#, 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:1753
+#: io.c:1922
#, 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:1755 io.c:1923
+#: io.c:1924 io.c:2110
#, 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:1758
+#: io.c:1927
#, 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:1760 io.c:1781
+#: io.c:1929 io.c:1951
#, c-format
msgid "close of slave pty failed (%s)"
msgstr "zamknięcie podległego pty nie powiodło się (%s)"
-#: io.c:1859 io.c:1921 io.c:2053 io.c:2078
+#: io.c:2040 io.c:2108 io.c:2276 io.c:2308
#, 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:1866 io.c:1926
+#: io.c:2047 io.c:2113
#, 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:1886 io.c:2068
+#: io.c:2073 io.c:2298
msgid "restoring stdout in parent process failed\n"
msgstr ""
"odzyskanie standardowego wyjścia w procesie potomnym nie powiodło się\n"
-#: io.c:1894
+#: io.c:2081
msgid "restoring stdin in parent process failed\n"
msgstr ""
"odzyskanie standardowego wejścia w procesie potomnym nie powiodło się\n"
-#: io.c:1929 io.c:2080 io.c:2094
+#: io.c:2116 io.c:2310 io.c:2324
#, c-format
msgid "close of pipe failed (%s)"
msgstr "zamknięcie potoku nie powiodło się (%s)"
-#: io.c:1974
+#: io.c:2174
msgid "`|&' not supported"
msgstr "`|&' nie jest wspierany"
-#: io.c:2040
+#: io.c:2261
#, c-format
msgid "cannot open pipe `%s' (%s)"
msgstr "nie można otworzyć potoku `%s' (%s)"
-#: io.c:2088
+#: io.c:2318
#, c-format
msgid "cannot create child process for `%s' (fork: %s)"
msgstr "nie można utworzyć procesu potomnego dla `%s' (fork: %s)"
-#: io.c:2521
+#: io.c:2790
+msgid "register_input_parser: received NULL pointer"
+msgstr "register_input_parser: otrzymano wskaźnik NULL"
+
+#: io.c:2818
+#, c-format
+msgid "input parser `%s' conflicts with previously installed input parser `%s'"
+msgstr ""
+"parser wejścia `%s' konfliktuje z poprzednio zainstalowanym parserem `%s'"
+
+#: io.c:2825
+#, c-format
+msgid "input parser `%s' failed to open `%s'"
+msgstr "parser wejścia `%s': nie powiodło się otwarcie `%s'"
+
+#: io.c:2845
+msgid "register_output_wrapper: received NULL pointer"
+msgstr "register_output_wrapper: otrzymano wskaźnik NULL"
+
+#: io.c:2873
+#, c-format
+msgid ""
+"output wrapper `%s' conflicts with previously installed output wrapper `%s'"
+msgstr ""
+"otoczka wyjścia `%s' konfliktuje z poprzednio zainstalowaną otoczką `%s'"
+
+#: io.c:2880
+#, c-format
+msgid "output wrapper `%s' failed to open `%s'"
+msgstr "otoczka wyjścia `%s': nie powiodło się otwarcie `%s'"
+
+#: io.c:2901
+msgid "register_output_processor: received NULL pointer"
+msgstr "register_output_processor: otrzymano wskaźnik NULL"
+
+#: io.c:2930
+#, c-format
+msgid ""
+"two-way processor `%s' conflicts with previously installed two-way processor "
+"`%s'"
+msgstr ""
+"dwukierunkowy procesor `%s' konfliktuje z poprzednio zainstalowanym "
+"procesorem `%s'"
+
+#: io.c:2939
+#, c-format
+msgid "two way processor `%s' failed to open `%s'"
+msgstr "dwukierunkowy procesor `%s' zawiódł w otwarciu `%s'"
+
+#: io.c:3064
#, c-format
msgid "data file `%s' is empty"
msgstr "plik danych `%s' jest pusty"
-#: io.c:2562 io.c:2570
+#: io.c:3106 io.c:3114
msgid "could not allocate more input memory"
msgstr "nie można zarezerwować więcej pamięci wejściowej"
-#: io.c:3128
+#: io.c:3682
msgid "multicharacter value of `RS' is a gawk extension"
msgstr "wieloznakowa wartość `RS' jest rozszerzeniem gawk"
-#: io.c:3233
+#: io.c:3771
msgid "IPv6 communication is not supported"
msgstr "Komunikacja IPv6 nie jest wspierana"
-#: main.c:364
-msgid "`-m[fr]' option irrelevant in gawk"
-msgstr "nieistotna opcja `-m[fr]' w gawk"
-
-#: main.c:366
-msgid "-m option usage: `-m[fr] nnn'"
-msgstr "użycie opcji -m: `-m[fr] nnn'"
-
-#: main.c:389
+#: main.c:405
msgid "empty argument to `-e/--source' ignored"
msgstr "pusty argument dla opcji `-e/--source' został zignorowany"
-#: main.c:460
+#: main.c:495
#, c-format
msgid "%s: option `-W %s' unrecognized, ignored\n"
msgstr "%s: opcja `-W %s' nierozpoznana i zignorowana\n"
-#: main.c:513
+#: main.c:541
#, c-format
msgid "%s: option requires an argument -- %c\n"
msgstr "%s: opcja musi mieć argument -- %c\n"
-#: main.c:534
+#: main.c:562
msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
msgstr ""
"zmienna środowiskowa `POSIXLY_CORRECT' ustawiona: `--posix' został włączony"
-#: main.c:540
+#: main.c:568
msgid "`--posix' overrides `--traditional'"
msgstr "opcja `--posix' zostanie użyta nad `--traditional'"
-#: main.c:551
+#: main.c:579
msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
msgstr "`--posix'/`--traditional' użyte nad opcją `--non-decimal-data'"
-#: main.c:555
+#: main.c:583
#, 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:560
-msgid "`--posix' overrides `--binary'"
-msgstr "opcja `--posix' zostanie użyta nad `--binary'"
+#: main.c:588
+msgid "`--posix' overrides `--characters-as-bytes'"
+msgstr "opcja `--posix' zostanie użyta nad `--characters-as-bytes'"
-#: main.c:611
+#: main.c:647
#, 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:614
+#: main.c:650
#, 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:616
+#: main.c:652
#, 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:655
+#: main.c:710
msgid "no program text at all!"
msgstr "brak tekstu programu!"
-#: main.c:733
+#: main.c:799
#, 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:735
+#: main.c:801
#, 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:740
+#: main.c:806
msgid "POSIX options:\t\tGNU long options: (standard)\n"
msgstr "Opcje POSIX:\t\tDÅ‚ugie opcje GNU (standard):\n"
-#: main.c:741
+#: main.c:807
msgid "\t-f progfile\t\t--file=progfile\n"
msgstr "\t-f program\t\t--file=program\n"
-#: main.c:742
+#: main.c:808
msgid "\t-F fs\t\t\t--field-separator=fs\n"
msgstr "\t-F fs\t\t\t--field-separator=fs\n"
-#: main.c:743
+#: main.c:809
msgid "\t-v var=val\t\t--assign=var=val\n"
msgstr "\t-v zmienna=wartość\t--assign=zmienna=wartość\n"
-#: main.c:744
+#: main.c:810
msgid "Short options:\t\tGNU long options: (extensions)\n"
msgstr "Krótkie opcje:\t\tDługie opcje GNU: (rozszerzenia)\n"
-#: main.c:745
+#: main.c:811
msgid "\t-b\t\t\t--characters-as-bytes\n"
msgstr "\t-b\t\t\t--characters-as-bytes\n"
-#: main.c:746
+#: main.c:812
msgid "\t-c\t\t\t--traditional\n"
msgstr "\t-c\t\t\t--traditional\n"
-#: main.c:747
+#: main.c:813
msgid "\t-C\t\t\t--copyright\n"
msgstr "\t-C\t\t\t--copyright\n"
-#: main.c:748
-#, fuzzy
+#: main.c:814
msgid "\t-d[file]\t\t--dump-variables[=file]\n"
-msgstr "\t-d [plik]\t\t--dump-variables[=plik]\n"
+msgstr "\t-d[plik]\t\t--dump-variables[=plik]\n"
+
+#: main.c:815
+msgid "\t-D[file]\t\t--debug[=file]\n"
+msgstr "\t-D[plik]\t\t--debug[=plik]\n"
-#: main.c:749
+#: main.c:816
msgid "\t-e 'program-text'\t--source='program-text'\n"
msgstr "\t-e 'tekst-programu'\t--source='tekst-programu'\n"
-#: main.c:750
+#: main.c:817
msgid "\t-E file\t\t\t--exec=file\n"
msgstr "\t-E plik\t\t\t--exec=plik\n"
-#: main.c:751
+#: main.c:818
msgid "\t-g\t\t\t--gen-pot\n"
msgstr "\t-g\t\t\t--gen-pot\n"
-#: main.c:752
+#: main.c:819
msgid "\t-h\t\t\t--help\n"
msgstr "\t-h\t\t\t--help\n"
-#: main.c:753
+#: main.c:820
+msgid "\t-i includefile\t\t--include=includefile\n"
+msgstr "\t-i plikinclude\t\t--include=plikinclude\n"
+
+#: main.c:821
+msgid "\t-l library\t\t--load=library\n"
+msgstr "\t-l biblioteka\t\t--load=biblioteka\n"
+
+#: main.c:822
msgid "\t-L [fatal]\t\t--lint[=fatal]\n"
msgstr "\t-L [fatal]\t\t--lint[=fatal]\n"
-#: main.c:754
+#: main.c:823
msgid "\t-n\t\t\t--non-decimal-data\n"
msgstr "\t-n\t\t\t--non-decimal-data\n"
-#: main.c:755
+#: main.c:824
+msgid "\t-M\t\t\t--bignum\n"
+msgstr "\t-M\t\t\t--bignum\n"
+
+#: main.c:825
msgid "\t-N\t\t\t--use-lc-numeric\n"
msgstr "\t-N\t\t\t--use-lc-numeric\n"
-#: main.c:756
+#: main.c:826
+msgid "\t-o[file]\t\t--pretty-print[=file]\n"
+msgstr "\t-o[plik]\t\t--pretty-print[=plik]\n"
+
+#: main.c:827
msgid "\t-O\t\t\t--optimize\n"
msgstr "\t-O\t\t\t--optimize\n"
-#: main.c:757
-#, fuzzy
+#: main.c:828
msgid "\t-p[file]\t\t--profile[=file]\n"
-msgstr "\t-p [plik]\t\t--profile[=plik]\n"
+msgstr "\t-p[plik]\t\t--profile[=plik]\n"
-#: main.c:758
+#: main.c:829
msgid "\t-P\t\t\t--posix\n"
msgstr "\t-P\t\t\t--posix\n"
-#: main.c:759
+#: main.c:830
msgid "\t-r\t\t\t--re-interval\n"
msgstr "\t-r\t\t\t--re-interval\n"
-#: main.c:761
-msgid "\t-R file\t\t\t--command=file\n"
-msgstr "\t-R plik\t\t\t--command=plik\n"
-
-#: main.c:762
+#: main.c:831
msgid "\t-S\t\t\t--sandbox\n"
msgstr "\t-S\t\t\t--sandbox\n"
-#: main.c:763
+#: main.c:832
msgid "\t-t\t\t\t--lint-old\n"
msgstr "\t-t\t\t\t--lint-old\n"
-#: main.c:764
+#: main.c:833
msgid "\t-V\t\t\t--version\n"
msgstr "\t-V\t\t\t--version\n"
-#: main.c:766
+#: main.c:835
msgid "\t-W nostalgia\t\t--nostalgia\n"
msgstr "\t-W nostalgia\t\t--nostalgia\n"
-#: main.c:769
+#: main.c:838
msgid "\t-Y\t\t--parsedebug\n"
msgstr "\t-Y\t\t--parsedebug\n"
@@ -1838,7 +3100,7 @@ msgstr "\t-Y\t\t--parsedebug\n"
#. for this application. Please add _another line_ with the
#. address for translation bugs.
#. no-wrap
-#: main.c:778
+#: main.c:847
msgid ""
"\n"
"To report bugs, see node `Bugs' in `gawk.info', which is\n"
@@ -1851,7 +3113,7 @@ msgstr ""
"dokumentacji.\n"
"\n"
-#: main.c:782
+#: main.c:851
msgid ""
"gawk is a pattern scanning and processing language.\n"
"By default it reads standard input and writes standard output.\n"
@@ -1861,7 +3123,7 @@ msgstr ""
"Program domyślnie czyta standardowe wejście i zapisuje standardowe wyjście.\n"
"\n"
-#: main.c:786
+#: main.c:855
msgid ""
"Examples:\n"
"\tgawk '{ sum += $1 }; END { print sum }' file\n"
@@ -1871,7 +3133,7 @@ msgstr ""
"\tgawk '{ suma += $1 }; END { print suma }' plik\n"
"\tgawk -F: '{ print $1 }' /etc/passwd\n"
-#: main.c:806
+#: main.c:880
#, c-format
msgid ""
"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
@@ -1890,7 +3152,7 @@ msgstr ""
"tej Licencji lub którejś z późniejszych wersji.\n"
"\n"
-#: main.c:814
+#: main.c:888
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"
@@ -1905,7 +3167,7 @@ msgstr ""
"PowszechnÄ… LicencjÄ™ PublicznÄ… GNU.\n"
"\n"
-#: main.c:820
+#: main.c:894
msgid ""
"You should have received a copy of the GNU General Public License\n"
"along with this program. If not, see http://www.gnu.org/licenses/.\n"
@@ -1914,16 +3176,16 @@ msgstr ""
"Powszechnej Licencji Publicznej GNU (GNU General Public License);\n"
"jeśli zaś nie - odwiedź stronę http://www.gnu.org/licenses/.\n"
-#: main.c:855
+#: main.c:931
msgid "-Ft does not set FS to tab in POSIX awk"
msgstr "-Ft nie ustawia FS na znak tabulatora w POSIX awk"
-#: main.c:1089
+#: main.c:1208
#, c-format
msgid "unknown value for field spec: %d\n"
msgstr "nieznana wartość dla specyfikacji pola: %d\n"
-#: main.c:1170
+#: main.c:1306
#, c-format
msgid ""
"%s: `%s' argument to `-v' not in `var=value' form\n"
@@ -1932,84 +3194,125 @@ msgstr ""
"%s: argument `%s' dla `-v' nie jest zgodny ze składnią `zmienna=wartość'\n"
"\n"
-#: main.c:1196
+#: main.c:1332
#, c-format
msgid "`%s' is not a legal variable name"
msgstr "`%s' nie jest dozwolonÄ… nazwÄ… zmiennej"
-#: main.c:1199
+#: main.c:1335
#, 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:1203
-#, fuzzy, c-format
+#: main.c:1339
+#, c-format
msgid "cannot use gawk builtin `%s' as variable name"
-msgstr "rozszerzenie: nie można użyć wbudowanej w gawk `%s' jako nazwy funkcji"
+msgstr "nie można użyć wbudowanej w gawk `%s' jako nazwy zmiennej"
-#: main.c:1208
-#, fuzzy, c-format
+#: main.c:1344
+#, c-format
msgid "cannot use function `%s' as variable name"
-msgstr "nie można użyć nazwy funkcji `%s' jako zmiennej lub tablicy"
+msgstr "nie można użyć funkcji `%s' jako nazwy zmiennej"
-#: main.c:1261
+#: main.c:1397
msgid "floating point exception"
msgstr "wyjÄ…tek zmiennopozycyjny"
-#: main.c:1268
+#: main.c:1404
msgid "fatal error: internal error"
msgstr "fatalny błąd: wewnętrzny błąd"
-#: main.c:1283
+#: main.c:1419
msgid "fatal error: internal error: segfault"
msgstr "fatalny błąd: wewnętrzny błąd: błąd segmentacji"
-#: main.c:1295
+#: main.c:1431
msgid "fatal error: internal error: stack overflow"
msgstr "fatalny błąd: wewnętrzny błąd: przepełnienie stosu"
-#: main.c:1345
+#: main.c:1490
#, c-format
msgid "no pre-opened fd %d"
msgstr "brak już otwartego fd %d"
-#: main.c:1352
+#: main.c:1497
#, 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:1375 main.c:1384
+#: mpfr.c:550
+#, c-format
+msgid "PREC value `%.*s' is invalid"
+msgstr "wartość PREC `%.*s' jest nieprawidłowa"
+
+#: mpfr.c:608
+#, c-format
+msgid "RNDMODE value `%.*s' is invalid"
+msgstr "wartość RNDMODE `%.*s' jest nieprawidłowa"
+
+#: mpfr.c:698
+#, c-format
+msgid "%s: received non-numeric argument"
+msgstr "%s: otrzymano argument, który nie jest liczbą"
+
+#: mpfr.c:800
+msgid "compl(%Rg): negative value will give strange results"
+msgstr "compl(%Rg): ujemne wartości spowodują dziwne wyniki"
+
+#: mpfr.c:804
+msgid "comp(%Rg): fractional value will be truncated"
+msgstr "compl(%Rg): ułamkowe wartości zostaną obcięte"
+
+#: mpfr.c:816
+#, c-format
+msgid "cmpl(%Zd): negative values will give strange results"
+msgstr "cmpl(%Zd): ujemne wartości spowodują dziwne wyniki"
+
+#: mpfr.c:835
+#, c-format
+msgid "%s: received non-numeric argument #%d"
+msgstr "%s: otrzymano argument #%d, który nie jest liczbą"
+
+#: mpfr.c:845
+msgid "%s: argument #%d has invalid value %Rg, using 0"
+msgstr "%s: argument #%d ma nieprawidłową wartość %Rg, użyto 0"
+
+#: mpfr.c:857
+msgid "%s: argument #%d negative value %Rg will give strange results"
+msgstr "%s: argument #%d ujemna wartość %Rg spowoduje dziwne wyniki"
+
+#: mpfr.c:863
+msgid "%s: argument #%d fractional value %Rg will be truncated"
+msgstr "%s: argument #%d ułamkowa wartość %Rg zostanie obcięta"
+
+#: mpfr.c:878
#, c-format
-msgid "could not find groups: %s"
-msgstr "nie można znaleźć grup: %s"
+msgid "%s: argument #%d negative value %Zd will give strange results"
+msgstr "%s: argument #%d ujemna wartość %Zd spowoduje dziwne wyniki"
-#: msg.c:63
+#: msg.c:68
#, c-format
msgid "cmd. line:"
msgstr "linia poleceń:"
-#: msg.c:107
-msgid "error: "
-msgstr "błąd: "
-
-#: node.c:406
+#: node.c:421
msgid "backslash at end of string"
msgstr "backslash na końcu łańcucha"
-#: node.c:517
+#: node.c:500
#, c-format
msgid "old awk does not support the `\\%c' escape sequence"
msgstr "stary awk nie wspiera sekwencji ucieczki `\\%c'"
-#: node.c:568
+#: node.c:551
msgid "POSIX does not allow `\\x' escapes"
msgstr "POSIX nie zezwala na sekwencjÄ™ ucieczki `\\x'"
-#: node.c:574
+#: node.c:557
msgid "no hex digits in `\\x' escape sequence"
msgstr "brak liczb szesnastkowych w sekwencji ucieczki `\\x'"
-#: node.c:596
+#: node.c:579
#, c-format
msgid ""
"hex escape \\x%.*s of %d characters probably not interpreted the way you "
@@ -2018,12 +3321,12 @@ msgstr ""
"szesnastkowa sekwencja ucieczki \\x%.*s %d znaków prawdopodobnie nie została "
"zinterpretowana jak tego oczekujesz"
-#: node.c:611
+#: node.c:594
#, c-format
msgid "escape sequence `\\%c' treated as plain `%c'"
msgstr "sekwencja ucieczki `\\%c' potraktowana jako zwykłe `%c'"
-#: node.c:750
+#: node.c:739
msgid ""
"Invalid multibyte data detected. There may be a mismatch between your data "
"and your locale."
@@ -2031,26 +3334,26 @@ msgstr ""
"Wykryto nieprawidłowe dane. Możliwe jest niedopasowanie pomiędzy Twoimi "
"danymi a ustawieniami regionalnymi."
-#: posix/gawkmisc.c:176
+#: posix/gawkmisc.c:177
#, c-format
msgid "%s %s `%s': could not get fd flags: (fcntl F_GETFD: %s)"
msgstr "%s %s `%s': nie można uzyskać flag fd: (fcntl F_GETFD: %s)"
-#: posix/gawkmisc.c:188
+#: posix/gawkmisc.c:189
#, c-format
msgid "%s %s `%s': could not set close-on-exec: (fcntl F_SETFD: %s)"
msgstr "%s %s `%s': nie można ustawić close-on-exec: (fcntl F_SETFD: %s)"
-#: profile.c:83
+#: profile.c:71
#, c-format
msgid "could not open `%s' for writing: %s"
msgstr "nie można otworzyć `%s' do zapisu: %s"
-#: profile.c:85
+#: profile.c:73
msgid "sending profile to standard error"
msgstr "wysyłanie profilu na standardowe wyjście diagnostyczne"
-#: profile.c:203
+#: profile.c:193
#, c-format
msgid ""
"\t# %s block(s)\n"
@@ -2059,7 +3362,7 @@ msgstr ""
"\t# %s blok(i)\n"
"\n"
-#: profile.c:208
+#: profile.c:198
#, c-format
msgid ""
"\t# Rule(s)\n"
@@ -2068,17 +3371,30 @@ msgstr ""
"\t# Reguła(i)\n"
"\n"
-#: profile.c:279
+#: profile.c:272
#, c-format
msgid "internal error: %s with null vname"
msgstr "wewnętrzny błąd: %s z zerowym vname"
-#: profile.c:952
+#: profile.c:537
+msgid "internal error: builtin with null fname"
+msgstr "wewnętrzny błąd: builtin z fname null"
+
+#: profile.c:949
+#, c-format
+msgid ""
+"\t# Loaded extensions (-l and/or @load)\n"
+"\n"
+msgstr ""
+"\t# Załadowane rozszerzenia (-l i/lub @load)\n"
+"\n"
+
+#: profile.c:972
#, c-format
msgid "\t# gawk profile, created %s\n"
msgstr "\t# profil programu gawk, utworzony %s\n"
-#: profile.c:1331
+#: profile.c:1475
#, c-format
msgid ""
"\n"
@@ -2087,93 +3403,200 @@ msgstr ""
"\n"
"\t# Funkcje, spis alfabetyczny\n"
-#: profile.c:1370
+#: profile.c:1513
#, c-format
msgid "redir2str: unknown redirection type %d"
msgstr "redir2str: nieznany typ przekierowania %d"
-#: re.c:572
-#, fuzzy, c-format
-msgid "range of the form `[%c-%c]' is locale dependent"
-msgstr "zasięg formy `[%c-%c]' jest zależny od lokalizacji"
-
-#: re.c:599
+#: re.c:607
#, c-format
msgid "regexp component `%.*s' should probably be `[%.*s]'"
msgstr "komponent regexp `%.*s' powinien być prawdopodobnie `[%.*s]'"
-#: regcomp.c:132
+#: regcomp.c:131
msgid "Success"
msgstr "Sukces"
-#: regcomp.c:135
+#: regcomp.c:134
msgid "No match"
msgstr "Brak dopasowania"
-#: regcomp.c:138
+#: regcomp.c:137
msgid "Invalid regular expression"
msgstr "Nieprawidłowe wyrażenie regularne"
-#: regcomp.c:141
+#: regcomp.c:140
msgid "Invalid collation character"
msgstr "Nieprawidłowy znak porównania"
-#: regcomp.c:144
+#: regcomp.c:143
msgid "Invalid character class name"
msgstr "Nieprawidłowa nazwa klasy znaku"
-#: regcomp.c:147
+#: regcomp.c:146
msgid "Trailing backslash"
msgstr "Końcowy znak backslash"
-#: regcomp.c:150
+#: regcomp.c:149
msgid "Invalid back reference"
msgstr "Nieprawidłowe odwołanie wsteczne"
-#: regcomp.c:153
+#: regcomp.c:152
msgid "Unmatched [ or [^"
msgstr "Niedopasowany znak [ lub [^"
-#: regcomp.c:156
+#: regcomp.c:155
msgid "Unmatched ( or \\("
msgstr "Niedopasowany znak ( lub \\("
-#: regcomp.c:159
+#: regcomp.c:158
msgid "Unmatched \\{"
msgstr "Niedopasowany znak \\{"
-#: regcomp.c:162
-msgid "Invalid content of \\{\\}"
-msgstr "Nieprawidłowa zawartość \\{\\}"
-
-#: regcomp.c:165
+#: regcomp.c:164
msgid "Invalid range end"
msgstr "Nieprawidłowy koniec zakresu"
-#: regcomp.c:168
+#: regcomp.c:167
msgid "Memory exhausted"
msgstr "Pamięć wyczerpana"
-#: regcomp.c:171
+#: regcomp.c:170
msgid "Invalid preceding regular expression"
msgstr "Nieprawidłowe poprzedzające wyrażenie regularne"
-#: regcomp.c:174
+#: regcomp.c:173
msgid "Premature end of regular expression"
msgstr "Przedwczesny koniec wyrażenia regularnego"
-#: regcomp.c:177
-msgid "Regular expression too big"
-msgstr "Wyrażenie regularne jest zbyt duże"
-
-#: regcomp.c:180
+#: regcomp.c:179
msgid "Unmatched ) or \\)"
msgstr "Niedopasowany znak ) lub \\)"
-#: regcomp.c:701
+#: regcomp.c:704
msgid "No previous regular expression"
msgstr "Brak poprzedniego wyrażenia regularnego"
+#: symbol.c:741
+msgid "can not pop main context"
+msgstr "nie można zdjąć głównego kontekstu"
+
+#~ msgid "range of the form `[%c-%c]' is locale dependent"
+#~ msgstr "zasięg formy `[%c-%c]' jest zależny od lokalizacji"
+
+#~ msgid "attempt to use function `%s' as an array"
+#~ msgstr "próba użycia funkcji `%s' jako tablicy"
+
+#~ msgid "reference to uninitialized element `%s[\"%.*s\"]'"
+#~ msgstr "odwołanie do niezainicjowanego elementu `%s[\"%.*s\"]'"
+
+#~ msgid "subscript of array `%s' is null string"
+#~ msgstr "indeks tablicy `%s' jest zerowym łańcuchem"
+
+#~ msgid "%s: empty (null)\n"
+#~ msgstr "%s: pusty (null)\n"
+
+#~ msgid "%s: empty (zero)\n"
+#~ msgstr "%s: pusty (zero)\n"
+
+#~ msgid "%s: table_size = %d, array_size = %d\n"
+#~ msgstr "%s: table_size = %d, array_size = %d\n"
+
+#~ msgid "%s: array_ref to %s\n"
+#~ msgstr "%s: array_ref do %s\n"
+
+#~ msgid "`nextfile' is a gawk extension"
+#~ msgstr "`nextfile' jest rozszerzeniem gawk"
+
+#~ msgid "`delete array' is a gawk extension"
+#~ msgstr "`delete tablica' jest rozszerzeniem gawk"
+
+#~ msgid "use of non-array as array"
+#~ msgstr "użycie nie-tablicy jako tablicy"
+
+#~ msgid "`%s' is a Bell Labs extension"
+#~ msgstr "`%s' jest rozszerzeniem Bell Labs"
+
+#~ msgid "and: received non-numeric first argument"
+#~ msgstr "and: otrzymano pierwszy argument, który nie jest liczbą"
+
+#~ msgid "and: received non-numeric second argument"
+#~ msgstr "and: otrzymano drugi argument, który nie jest liczbą"
+
+#~ msgid "or: received non-numeric first argument"
+#~ msgstr "or: otrzymano pierwszy argument, który nie jest liczbą"
+
+#~ msgid "or: received non-numeric second argument"
+#~ msgstr "or: otrzymano drugi argument, który nie jest liczbą"
+
+#~ msgid "or(%lf, %lf): negative values will give strange results"
+#~ msgstr "or(%lf, %lf): ujemne wartości spowodują dziwne wyniki"
+
+#~ msgid "or(%lf, %lf): fractional values will be truncated"
+#~ msgstr "or(%lf, %lf): ułamkowe wartości zostaną obcięte"
+
+#~ msgid "xor: received non-numeric first argument"
+#~ msgstr "xor: otrzymano pierwszy argument, który nie jest liczbą"
+
+#~ msgid "xor: received non-numeric second argument"
+#~ msgstr "xor: otrzymano drugi argument, który nie jest liczbą"
+
+#~ msgid "xor(%lf, %lf): fractional values will be truncated"
+#~ msgstr "xor(%lf, %lf): ułamkowe wartości zostaną obcięte"
+
+#~ msgid "can't use function name `%s' as variable or array"
+#~ msgstr "nie można użyć nazwy funkcji `%s' jako zmiennej lub tablicy"
+
+#~ msgid "assignment used in conditional context"
+#~ msgstr "przypisanie użyte w kontekście warunkowym"
+
+#~ msgid "statement has no effect"
+#~ msgstr "instrukcja nie ma żadnego efektu"
+
+#~ 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"
+
+#~ msgid "function called indirectly through `%s' does not exist"
+#~ msgstr "pośrednio wywołana funkcja poprzez `%s' nie istnieje"
+
+#~ msgid "function `%s' not defined"
+#~ msgstr "funkcja `%s' nie została zdefiniowana"
+
+#~ msgid "non-redirected `getline' invalid inside `%s' rule"
+#~ msgstr ""
+#~ "komenda `getline' bez przekierowania jest nieprawidłowa wewnątrz reguły `"
+#~ "%s'"
+
+#~ msgid "error reading input file `%s': %s"
+#~ msgstr "błąd podczas czytania z pliku `%s': %s"
+
+#~ msgid "`nextfile' cannot be called from a `%s' rule"
+#~ msgstr "instrukcja `nextfile' nie może być wywołana z wnętrza reguły `%s'"
+
+#~ msgid "`next' cannot be called from a `%s' rule"
+#~ msgstr "instrukcja `next' nie może być wywołana z wnętrza reguły `%s'"
+
+#~ msgid "Sorry, don't know how to interpret `%s'"
+#~ msgstr "Niestety nie wiem jak zinterpretować `%s'"
+
+#~ msgid "Operation Not Supported"
+#~ msgstr "Operacja nie jest wspierana"
+
+#~ msgid "`-m[fr]' option irrelevant in gawk"
+#~ msgstr "nieistotna opcja `-m[fr]' w gawk"
+
+#~ msgid "-m option usage: `-m[fr] nnn'"
+#~ msgstr "użycie opcji -m: `-m[fr] nnn'"
+
+#~ msgid "\t-R file\t\t\t--command=file\n"
+#~ msgstr "\t-R plik\t\t\t--command=plik\n"
+
+#~ msgid "could not find groups: %s"
+#~ msgstr "nie można znaleźć grup: %s"
+
#~ msgid "assignment is not allowed to result of builtin function"
#~ msgstr "przypisanie do wyniku wbudowanej funkcji nie jest dozwolone"
@@ -2189,9 +3612,6 @@ msgstr "Brak poprzedniego wyrażenia regularnego"
#~ msgid "attempt to use scalar `%s' as array"
#~ msgstr "próba użycia skalaru `%s' jako tablicy"
-#~ msgid "attempt to use array `%s' in scalar context"
-#~ msgstr "próba użycia tablicy `%s' w kontekście skalaru"
-
#~ msgid "call of `length' without parentheses is deprecated by POSIX"
#~ msgstr ""
#~ "wywołanie `length' bez podania nawiasów jest niezalecane przez POSIX"
@@ -2338,26 +3758,8 @@ msgstr "Brak poprzedniego wyrażenia regularnego"
#~ 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 "internal error: file `%s', line %d\n"
-#~ msgstr "wewnętrzny błąd: plik `%s', linia %d\n"
diff --git a/po/pt_BR.gmo b/po/pt_BR.gmo
deleted file mode 100644
index 4cbc6792..00000000
--- a/po/pt_BR.gmo
+++ /dev/null
Binary files differ
diff --git a/po/ro.gmo b/po/ro.gmo
deleted file mode 100644
index e3534b89..00000000
--- a/po/ro.gmo
+++ /dev/null
Binary files differ
diff --git a/po/rw.gmo b/po/rw.gmo
deleted file mode 100644
index a08f9183..00000000
--- a/po/rw.gmo
+++ /dev/null
Binary files differ
diff --git a/po/sv.gmo b/po/sv.gmo
index 0878d1e0..acc069b3 100644
--- a/po/sv.gmo
+++ b/po/sv.gmo
Binary files differ
diff --git a/po/sv.po b/po/sv.po
index 5a9f0161..50eb2736 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -1,991 +1,1867 @@
# Swedish translation of gawk
-# Copyright © 2003, 2011 Free Software Foundation, Inc.
+# Copyright © 2003, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
# This file is distributed under the same license as the gawk package.
-# Martin Sjögren <md9ms@mdstud.chalmers.se>, 2001-2002.
+#
+# Martin Sjögren <md9ms@mdstud.chalmers.se>, 2001-2002.
# Christer Andersson <klamm@comhem.se>, 2007.
-# Göran Uddeborg <goeran@uddeborg.se>, 2011.
+# Göran Uddeborg <goeran@uddeborg.se>, 2011, 2012, 2013, 2014.
#
-# $Id: gawk.po,v 1.5 2011-07-16 15:21:02+02 göran Exp $
+# $Revision: 1.15 $
msgid ""
msgstr ""
-"Project-Id-Version: gawk 4.0.0\n"
+"Project-Id-Version: gawk 4.1.0b\n"
"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
-"POT-Creation-Date: 2011-10-24 05:57+0200\n"
-"PO-Revision-Date: 2011-07-16 15:20+0200\n"
-"Last-Translator: Göran Uddeborg <goeran@uddeborg.se>\n"
+"POT-Creation-Date: 2014-04-08 19:23+0300\n"
+"PO-Revision-Date: 2014-09-22 09:12+0200\n"
+"Last-Translator: Göran Uddeborg <goeran@uddeborg.se>\n"
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
"Language: sv\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: array.c:140
+#: array.c:256
#, c-format
msgid "from %s"
-msgstr "från %s"
+msgstr "från %s"
-#: array.c:248
+#: array.c:357
msgid "attempt to use a scalar value as array"
-msgstr "försök att använda ett skalärt värde som vektor"
-
-#: array.c:251
-#, c-format
-msgid "attempt to use function `%s' as an array"
-msgstr "försök att använda funktionen \"%s\" som vektor"
+msgstr "försök att använda ett skalärt värde som vektor"
-#: array.c:254
+#: array.c:359
#, 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"
+msgstr "försök att använda skalärparametern â€%s†som en vektor"
-#: array.c:257
+#: array.c:362
#, c-format
msgid "attempt to use scalar `%s' as an array"
-msgstr "försök att använda skalären \"%s\" som en vektor"
+msgstr "försök att använda skalären â€%s†som en vektor"
-#: array.c:302 array.c:707 builtin.c:84 builtin.c:1384 builtin.c:1426
-#: builtin.c:1439 builtin.c:1856 builtin.c:1868 eval.c:1135 eval.c:1139
-#: eval.c:1495 eval.c:1812
+#: array.c:409 array.c:576 builtin.c:85 builtin.c:1615 builtin.c:1661
+#: builtin.c:1674 builtin.c:2102 builtin.c:2116 eval.c:1122 eval.c:1126
+#: eval.c:1531
#, c-format
msgid "attempt to use array `%s' in a scalar context"
-msgstr "försök att använda vektorn \"%s\" i skalärsammanhang"
-
-#: array.c:513
-#, c-format
-msgid "reference to uninitialized element `%s[\"%.*s\"]'"
-msgstr "referens till oinitierat element \"%s[\"%.*s\"]\""
+msgstr "försök att använda vektorn â€%s†i skalärsammanhang"
-#: array.c:519
-#, c-format
-msgid "subscript of array `%s' is null string"
-msgstr "index i vektorn \"%s\" är en tom sträng"
-
-#: array.c:723
+#: array.c:583
#, c-format
msgid "delete: index `%s' not in array `%s'"
-msgstr "delete: index \"%s\" finns inte i vektorn \"%s\""
+msgstr "delete: index â€%s†finns inte i vektorn â€%sâ€"
-#: array.c:734 eval.c:1865
+#: array.c:597
#, c-format
msgid "attempt to use scalar `%s[\"%.*s\"]' as an array"
-msgstr "försök att använda skalären \"%s[\"%.*s\"]\" som en vektor"
+msgstr "försök att använda skalären â€%s[\"%.*s\"]†som en vektor"
-#: array.c:910
-#, c-format
-msgid "%s: empty (null)\n"
-msgstr "%s: tom (null)\n"
-
-#: array.c:915
-#, c-format
-msgid "%s: empty (zero)\n"
-msgstr "%s: tom (noll)\n"
+#: array.c:776
+msgid "adump: first argument not an array"
+msgstr "adump: första argumentet är inte en vektor"
-#: array.c:919
-#, c-format
-msgid "%s: table_size = %d, array_size = %d\n"
-msgstr "%s: tabellstorlek = %d, vektorstorlek = %d\n"
-
-#: array.c:954
-#, c-format
-msgid "%s: is parameter\n"
-msgstr "%s: är en parameter\n"
-
-#: array.c:958
-#, c-format
-msgid "%s: array_ref to %s\n"
-msgstr "%s: vektorreferens till %s\n"
-
-#: array.c:963
-msgid "adump: argument not an array"
-msgstr "adump: argumentet är inte en vektor"
-
-#: array.c:1086
+#: array.c:815
msgid "asort: second argument not an array"
-msgstr "asort: andra argumentet är inte en vektor"
+msgstr "asort: andra argumentet är inte en vektor"
-#: array.c:1087
+#: array.c:816
msgid "asorti: second argument not an array"
-msgstr "asorti: andra argumentet är inte en vektor"
+msgstr "asorti: andra argumentet är inte en vektor"
-#: array.c:1094
+#: array.c:823
msgid "asort: first argument not an array"
-msgstr "asort: första argumentet är inte en vektor"
+msgstr "asort: första argumentet är inte en vektor"
-#: array.c:1095
+#: array.c:824
msgid "asorti: first argument not an array"
-msgstr "asorti: första argumentet är inte en vektor"
+msgstr "asorti: första argumentet är inte en vektor"
-#: array.c:1102
+#: array.c:831
msgid "asort: cannot use a subarray of first arg for second arg"
msgstr ""
-"asort: det går inte att använda en delvektor av första argumentet som andra "
+"asort: det går inte att använda en delvektor av första argumentet som andra "
"argument"
-#: array.c:1103
+#: array.c:832
msgid "asorti: cannot use a subarray of first arg for second arg"
msgstr ""
-"asorti: det går inte att använda en delvektor av första argumentet som andra "
+"asorti: det går inte att använda en delvektor av första argumentet som andra "
"argument"
-#: array.c:1108
+#: array.c:837
msgid "asort: cannot use a subarray of second arg for first arg"
msgstr ""
-"asort: det går inte att använda en delvektor av andra argumentet som första "
+"asort: det går inte att använda en delvektor av andra argumentet som första "
"argument"
-#: array.c:1109
+#: array.c:838
msgid "asorti: cannot use a subarray of second arg for first arg"
msgstr ""
-"asorti: det går inte att använda en delvektor av andra argumentet som första "
+"asorti: det går inte att använda en delvektor av andra argumentet som första "
"argument"
-#: array.c:1659
+#: array.c:1314
#, c-format
msgid "`%s' is invalid as a function name"
-msgstr "\"%s\" är ogiltigt som ett funktionsnamn"
+msgstr "â€%s†är ogiltigt som ett funktionsnamn"
-#: array.c:1663
+#: array.c:1318
#, c-format
msgid "sort comparison function `%s' is not defined"
-msgstr "jämförelsefunktionen \"%s\" för sortering är inte definierad"
+msgstr "jämförelsefunktionen â€%s†för sortering är inte definierad"
-#: awkgram.y:249
+#: awkgram.y:233
#, c-format
msgid "%s blocks must have an action part"
-msgstr "%s-block måste ha en åtgärdsdel"
+msgstr "%s-block måste ha en åtgärdsdel"
-#: awkgram.y:252
+#: awkgram.y:236
msgid "each rule must have a pattern or an action part"
-msgstr "varje regel måste ha ett mönster eller en åtgärdsdel"
+msgstr "varje regel måste ha ett mönster eller en åtgärdsdel"
-#: awkgram.y:323 awkgram.y:334
+#: awkgram.y:325 awkgram.y:336
msgid "old awk does not support multiple `BEGIN' or `END' rules"
-msgstr "gamla awk stöder inte flera \"BEGIN\"- eller \"END\"-regler"
+msgstr "gamla awk stöder inte flera â€BEGINâ€- eller â€ENDâ€-regler"
-#: awkgram.y:371
+#: awkgram.y:373
#, c-format
msgid "`%s' is a built-in function, it cannot be redefined"
-msgstr "\"%s\" är en inbyggd funktion, den kan inte definieras om"
+msgstr "â€%s“ är en inbyggd funktion, den kan inte definieras om"
-#: awkgram.y:432
+#: awkgram.y:419
msgid "regexp constant `//' looks like a C++ comment, but is not"
-msgstr "regexp-konstanten \"//\" ser ut som en C++-kommentar men är inte det"
+msgstr "regexp-konstanten \"//\" ser ut som en C++-kommentar men är inte det"
-#: awkgram.y:436
+#: awkgram.y:423
#, 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"
+msgstr "regexp-konstanten \"/%s/\" ser ut som en C-kommentar men är inte det"
-#: awkgram.y:528
+#: awkgram.y:515
#, c-format
msgid "duplicate case values in switch body: %s"
-msgstr "upprepade case-värden i switch-sats: %s"
+msgstr "upprepade case-värden i switch-sats: %s"
-#: awkgram.y:549
+#: awkgram.y:536
msgid "duplicate `default' detected in switch body"
-msgstr "flera \"default\" upptäcktes i switch-sats"
+msgstr "flera \"default\" upptäcktes i switch-sats"
-#: awkgram.y:809
+#: awkgram.y:796 awkgram.y:3723
msgid "`break' is not allowed outside a loop or switch"
-msgstr "\"break\" är inte tillåtet utanför en slinga eller switch"
+msgstr "\"break\" är inte tillåtet utanför en slinga eller switch"
-#: awkgram.y:818
+#: awkgram.y:805 awkgram.y:3715
msgid "`continue' is not allowed outside a loop"
-msgstr "\"continue\" är inte tillåtet utanför en slinga"
+msgstr "\"continue\" är inte tillåtet utanför en slinga"
-#: awkgram.y:828
+#: awkgram.y:815
#, c-format
msgid "`next' used in %s action"
-msgstr "\"next\" använt i %s-åtgärd"
+msgstr "\"next\" använt i %s-åtgärd"
-#: awkgram.y:836
-msgid "`nextfile' is a gawk extension"
-msgstr "\"nextfile\" är en gawk-utökning"
-
-#: awkgram.y:841
+#: awkgram.y:824
#, c-format
msgid "`nextfile' used in %s action"
-msgstr "\"nextfile\" använt i %s-åtgärd"
+msgstr "\"nextfile\" använt i %s-åtgärd"
-#: awkgram.y:865
+#: awkgram.y:848
msgid "`return' used outside function context"
-msgstr "\"return\" använd utanför funktion"
+msgstr "\"return\" använd utanför funktion"
-#: awkgram.y:925
+#: awkgram.y:922
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 \"\"'"
+"ensamt \"print\" i BEGIN eller END-regel bör troligen vara 'print \"\"'"
+
+#: awkgram.y:988 awkgram.y:1037
+msgid "`delete' is not allowed with SYMTAB"
+msgstr "â€delete†är inte tillÃ¥tet med SYMTAB"
-#: awkgram.y:995 awkgram.y:999 awkgram.y:1023
-msgid "`delete array' is a gawk extension"
-msgstr "\"delete array\" är en gawk-utökning"
+#: awkgram.y:990 awkgram.y:1039
+msgid "`delete' is not allowed with FUNCTAB"
+msgstr "â€delete†är inte tillÃ¥tet med FUNCTAB"
-#: awkgram.y:1019
+#: awkgram.y:1024 awkgram.y:1028
msgid "`delete(array)' is a non-portable tawk extension"
-msgstr "\"delete(array)\" är en icke portabel tawk-utökning"
+msgstr "\"delete(array)\" är en icke portabel tawk-utökning"
-#: awkgram.y:1135
+#: awkgram.y:1149
msgid "multistage two-way pipelines don't work"
-msgstr "flerstegs dubbelriktade rör fungerar inte"
+msgstr "flerstegs dubbelriktade rör fungerar inte"
-#: awkgram.y:1238
+#: awkgram.y:1264
msgid "regular expression on right of assignment"
-msgstr "reguljärt uttryck i högerledet av en tilldelning"
+msgstr "reguljärt uttryck i högerledet av en tilldelning"
-#: awkgram.y:1249
+#: awkgram.y:1275
msgid "regular expression on left of `~' or `!~' operator"
-msgstr "reguljärt uttryck på vänster sida om en \"~\"- eller \"!~\"-operator"
+msgstr "reguljärt uttryck på vänster sida om en \"~\"- eller \"!~\"-operator"
-#: awkgram.y:1265 awkgram.y:1419
+#: awkgram.y:1291 awkgram.y:1442
msgid "old awk does not support the keyword `in' except after `for'"
-msgstr "gamla awk stöder inte operatorn \"**\""
+msgstr "gamla awk stöder inte operatorn \"**\""
-#: awkgram.y:1275
+#: awkgram.y:1301
msgid "regular expression on right of comparison"
-msgstr "reguljärt uttryck i högerledet av en jämförelse"
+msgstr "reguljärt uttryck i högerledet av en jämförelse"
-#: awkgram.y:1394
+#: awkgram.y:1417
#, c-format
msgid "`getline var' invalid inside `%s' rule"
-msgstr "\"getline var\" är ogiltigt inuti \"%s\"-regel"
+msgstr "\"getline var\" är ogiltigt inuti \"%s\"-regel"
-#: awkgram.y:1397 eval.c:2504
+#: awkgram.y:1420
#, c-format
msgid "`getline' invalid inside `%s' rule"
-msgstr "\"getline är ogiltigt inuti \"%s\"-regel"
+msgstr "\"getline är ogiltigt inuti \"%s\"-regel"
-#: awkgram.y:1402
+#: awkgram.y:1425
msgid "non-redirected `getline' undefined inside END action"
-msgstr "icke omdirigerad \"getline\" odefinierad inuti END-åtgärd"
+msgstr "icke omdirigerad \"getline\" odefinierad inuti END-åtgärd"
-#: awkgram.y:1421
+#: awkgram.y:1444
msgid "old awk does not support multidimensional arrays"
-msgstr "gamla awk stöder inte flerdimensionella vektorer"
+msgstr "gamla awk stöder inte flerdimensionella vektorer"
-#: awkgram.y:1517
+#: awkgram.y:1541
msgid "call of `length' without parentheses is not portable"
-msgstr "anrop av \"length\" utan parenteser är inte portabelt"
+msgstr "anrop av \"length\" utan parenteser är inte portabelt"
-#: awkgram.y:1580
+#: awkgram.y:1607
msgid "indirect function calls are a gawk extension"
-msgstr "indirekta funktionsanrop är en gawk-utökning"
+msgstr "indirekta funktionsanrop är en gawk-utökning"
-#: awkgram.y:1593
+#: awkgram.y:1620
#, c-format
msgid "can not use special variable `%s' for indirect function call"
msgstr ""
-"det går inte att använda specialvariabeln \"%s\" för indirekta fuktionsanrop"
+"det går inte att använda specialvariabeln \"%s\" för indirekta fuktionsanrop"
-#: awkgram.y:1671
+#: awkgram.y:1698
msgid "invalid subscript expression"
msgstr "ogiltig indexuttryck"
-#: awkgram.y:1711
-msgid "use of non-array as array"
-msgstr "icke-vektor används som vektor"
-
-#: awkgram.y:1975 awkgram.y:1995 msg.c:98
+#: awkgram.y:2048 awkgram.y:2068 gawkapi.c:206 gawkapi.c:224 msg.c:126
msgid "warning: "
msgstr "varning: "
-#: awkgram.y:1993 msg.c:130
+#: awkgram.y:2066 gawkapi.c:192 gawkapi.c:221 msg.c:158
msgid "fatal: "
-msgstr "ödesdigert: "
+msgstr "ödesdigert: "
-#: awkgram.y:2043
+#: awkgram.y:2116
msgid "unexpected newline or end of string"
-msgstr "oväntat nyradstecken eller slut på strängen"
+msgstr "oväntat nyradstecken eller slut på strängen"
-#: awkgram.y:2300 awkgram.y:2358 awkgram.y:2542
+#: awkgram.y:2383 awkgram.y:2459 awkgram.y:2682 debug.c:523 debug.c:539
+#: debug.c:2812 debug.c:5055
#, c-format
msgid "can't open source file `%s' for reading (%s)"
-msgstr "kan inte öppna källfilen \"%s\" för läsning (%s)"
+msgstr "kan inte öppna källfilen \"%s\" för läsning (%s)"
+
+#: awkgram.y:2384 awkgram.y:2509
+#, c-format
+msgid "can't open shared library `%s' for reading (%s)"
+msgstr "kan inte öppna det delade biblioteket â€%s†för läsning (%s)"
-#: awkgram.y:2301 awkgram.y:2359 builtin.c:122
+#: awkgram.y:2386 awkgram.y:2460 awkgram.y:2510 builtin.c:135 debug.c:5206
msgid "reason unknown"
-msgstr "okänd anledning"
+msgstr "okänd anledning"
-#: awkgram.y:2317
+#: awkgram.y:2395 awkgram.y:2419
+#, c-format
+msgid "can't include `%s' and use it as a program file"
+msgstr "kan inte inkludera â€%s†och använda den som en programfil"
+
+#: awkgram.y:2408
#, c-format
msgid "already included source file `%s'"
-msgstr "inkluderade redan källfilen \"%s\""
+msgstr "inkluderade redan källfilen \"%s\""
-#: awkgram.y:2343
+#: awkgram.y:2409
+#, c-format
+msgid "already loaded shared library `%s'"
+msgstr "inkluderade redan det delade biblioteket â€%sâ€"
+
+#: awkgram.y:2444
msgid "@include is a gawk extension"
-msgstr "@include är en gawk-utökning"
+msgstr "@include är en gawk-utökning"
-#: awkgram.y:2349
+#: awkgram.y:2450
msgid "empty filename after @include"
msgstr "tomt filnamn efter @include"
#: awkgram.y:2494
+msgid "@load is a gawk extension"
+msgstr "@load är en gawk-utökning"
+
+#: awkgram.y:2500
+msgid "empty filename after @load"
+msgstr "tomt filnamn efter @load"
+
+#: awkgram.y:2634
msgid "empty program text on command line"
-msgstr "tom programtext på kommandoraden"
+msgstr "tom programtext på kommandoraden"
-#: awkgram.y:2609
+#: awkgram.y:2749
#, c-format
msgid "can't read sourcefile `%s' (%s)"
-msgstr "kan inte läsa källfilen \"%s\" (%s)"
+msgstr "kan inte läsa källfilen \"%s\" (%s)"
-#: awkgram.y:2620
+#: awkgram.y:2760
#, c-format
msgid "source file `%s' is empty"
-msgstr "källfilen \"%s\" är tom"
+msgstr "källfilen \"%s\" är tom"
-#: awkgram.y:2805
+#: awkgram.y:2937
msgid "source file does not end in newline"
-msgstr "källfilen slutar inte med en ny rad"
+msgstr "källfilen slutar inte med en ny rad"
-#: awkgram.y:2882
+#: awkgram.y:3042
msgid "unterminated regexp ends with `\\' at end of file"
-msgstr "oavslutat reguljärt uttryck slutar med \"\\\" i slutet av filen"
+msgstr "oavslutat reguljärt uttryck slutar med \"\\\" i slutet av filen"
-#: awkgram.y:2906
+#: awkgram.y:3066
#, c-format
msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
msgstr ""
-"%s: %d: tawk-modifierare för reguljära uttryck \"/.../%c\" fungerar inte i "
+"%s: %d: tawk-modifierare för reguljära uttryck \"/.../%c\" fungerar inte i "
"gawk"
-#: awkgram.y:2910
+#: awkgram.y:3070
#, c-format
msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
msgstr ""
-"tawk-modifierare för reguljära uttryck \"/.../%c\" fungerar inte i gawk"
+"tawk-modifierare för reguljära uttryck \"/.../%c\" fungerar inte i gawk"
-#: awkgram.y:2917
+#: awkgram.y:3077
msgid "unterminated regexp"
-msgstr "oavslutat reguljärt uttryck"
+msgstr "oavslutat reguljärt uttryck"
-#: awkgram.y:2921
+#: awkgram.y:3081
msgid "unterminated regexp at end of file"
-msgstr "oavslutat reguljärt uttryck i slutet av filen"
+msgstr "oavslutat reguljärt uttryck i slutet av filen"
-#: awkgram.y:2980
+#: awkgram.y:3140
msgid "use of `\\ #...' line continuation is not portable"
-msgstr "Användning av \"\\ #...\" för radfortsättning är inte portabelt"
+msgstr "Användning av \"\\ #...\" för radfortsättning är inte portabelt"
-#: awkgram.y:2996
+#: awkgram.y:3156
msgid "backslash not last character on line"
-msgstr "sista tecknet på raden är inte ett omvänt snedstreck"
+msgstr "sista tecknet på raden är inte ett omvänt snedstreck"
-#: awkgram.y:3057
+#: awkgram.y:3217
msgid "POSIX does not allow operator `**='"
-msgstr "POSIX tillåter inte operatorn \"**=\""
+msgstr "POSIX tillåter inte operatorn \"**=\""
-#: awkgram.y:3059
+#: awkgram.y:3219
msgid "old awk does not support operator `**='"
-msgstr "gamla awk stöder inte operatorn \"**=\""
+msgstr "gamla awk stöder inte operatorn \"**=\""
-#: awkgram.y:3068
+#: awkgram.y:3228
msgid "POSIX does not allow operator `**'"
-msgstr "POSIX tillåter inte operatorn \"**\""
+msgstr "POSIX tillåter inte operatorn \"**\""
-#: awkgram.y:3070
+#: awkgram.y:3230
msgid "old awk does not support operator `**'"
-msgstr "gamla awk stöder inte operatorn \"**\""
+msgstr "gamla awk stöder inte operatorn \"**\""
-#: awkgram.y:3105
+#: awkgram.y:3265
msgid "operator `^=' is not supported in old awk"
-msgstr "operatorn \"^=\" stöds inte i gamla awk"
+msgstr "operatorn \"^=\" stöds inte i gamla awk"
-#: awkgram.y:3113
+#: awkgram.y:3273
msgid "operator `^' is not supported in old awk"
-msgstr "operatorn \"^\" stöds inte i gamla awk"
+msgstr "operatorn \"^\" stöds inte i gamla awk"
-#: awkgram.y:3206 awkgram.y:3222
+#: awkgram.y:3366 awkgram.y:3382 command.y:1178
msgid "unterminated string"
-msgstr "oavslutad sträng"
+msgstr "oavslutad sträng"
-#: awkgram.y:3418
+#: awkgram.y:3603
#, c-format
msgid "invalid char '%c' in expression"
msgstr "ogiltigt tecken \"%c\" i uttryck"
-#: awkgram.y:3465
+#: awkgram.y:3650
#, c-format
msgid "`%s' is a gawk extension"
-msgstr "\"%s\" är en gawk-utökning"
-
-#: awkgram.y:3470
-#, c-format
-msgid "`%s' is a Bell Labs extension"
-msgstr "\"%s\" är en Bell Labs-utökning"
+msgstr "\"%s\" är en gawk-utökning"
-#: awkgram.y:3475
+#: awkgram.y:3655
#, c-format
msgid "POSIX does not allow `%s'"
-msgstr "POSIX tillåter inte \"%s\""
+msgstr "POSIX tillåter inte \"%s\""
-#: awkgram.y:3483
+#: awkgram.y:3663
#, c-format
msgid "`%s' is not supported in old awk"
-msgstr "\"%s\" stöds inte i gamla awk"
+msgstr "\"%s\" stöds inte i gamla awk"
-#: awkgram.y:3550
+#: awkgram.y:3753
msgid "`goto' considered harmful!\n"
msgstr "\"goto\" anses skadlig!\n"
-#: awkgram.y:3601
+#: awkgram.y:3787
#, c-format
msgid "%d is invalid as number of arguments for %s"
-msgstr "%d är ett ogiltigt antal argument för %s"
+msgstr "%d är ett ogiltigt antal argument för %s"
-#: awkgram.y:3636
+#: awkgram.y:3822
#, 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"
+"%s: bokstavlig sträng som sista argument till ersättning har ingen effekt"
-#: awkgram.y:3641
+#: awkgram.y:3827
#, c-format
msgid "%s third parameter is not a changeable object"
-msgstr "%s: tredje argumentet är inte ett ändringsbart objekt"
+msgstr "%s: tredje argumentet är inte ett ändringsbart objekt"
-#: awkgram.y:3714 awkgram.y:3717
+#: awkgram.y:3910 awkgram.y:3913
msgid "match: third argument is a gawk extension"
-msgstr "match: tredje argumentet är en gawk-utökning"
+msgstr "match: tredje argumentet är en gawk-utökning"
-#: awkgram.y:3771 awkgram.y:3774
+#: awkgram.y:3967 awkgram.y:3970
msgid "close: second argument is a gawk extension"
-msgstr "close: andra argumentet är en gawk-utökning"
+msgstr "close: andra argumentet är en gawk-utökning"
-#: awkgram.y:3786
+#: awkgram.y:3982
msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
msgstr ""
-"användandet av dcgettext(_\"...\") är felaktigt: ta bort det inledande "
+"användandet av dcgettext(_\"...\") är felaktigt: ta bort det inledande "
"understrykningstecknet"
-#: awkgram.y:3801
+#: awkgram.y:3997
msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
msgstr ""
-"användandet av dcngettext(_\"...\") är felaktigt: ta bort det inledande "
+"användandet av dcngettext(_\"...\") är felaktigt: ta bort det inledande "
"understrykningstecknet"
-#: awkgram.y:3893
-#, c-format
-msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
-msgstr "funktionen \"%s\": parameter %d, \"%s\", är samma som parameter %d"
+#: awkgram.y:4016
+msgid "index: regexp constant as second argument is not allowed"
+msgstr "index: reguljäruttryck som andra argumentet är inte tillåtet"
-#: awkgram.y:3935
+#: awkgram.y:4069
#, c-format
msgid "function `%s': parameter `%s' shadows global variable"
-msgstr "funktionen \"%s\": parametern \"%s\" överskuggar en global variabel"
+msgstr "funktionen \"%s\": parametern \"%s\" överskuggar en global variabel"
-#: awkgram.y:4093
+#: awkgram.y:4126 debug.c:4041 debug.c:4084 debug.c:5204
#, c-format
msgid "could not open `%s' for writing (%s)"
-msgstr "kunde inte öppna \"%s\" för skrivning (%s)"
+msgstr "kunde inte öppna \"%s\" för skrivning (%s)"
-#: awkgram.y:4094
+#: awkgram.y:4127
msgid "sending variable list to standard error"
msgstr "skickar variabellista till standard fel"
-#: awkgram.y:4100
+#: awkgram.y:4135
#, c-format
msgid "%s: close failed (%s)"
-msgstr "%s: misslyckades att stänga (%s)"
+msgstr "%s: misslyckades att stänga (%s)"
-#: awkgram.y:4152
+#: awkgram.y:4160
msgid "shadow_funcs() called twice!"
-msgstr "shadow_funcs() anropad två gånger!"
+msgstr "shadow_funcs() anropad två gånger!"
-#: awkgram.y:4158
+#: awkgram.y:4168
msgid "there were shadowed variables."
-msgstr "det fanns överskuggade variabler."
+msgstr "det fanns överskuggade variabler."
-#: awkgram.y:4188
+#: awkgram.y:4239
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "funktionsnamnet \"%s\" är definierat sedan tidigare"
+
+#: awkgram.y:4285
#, c-format
msgid "function `%s': can't use function name as parameter name"
-msgstr "funktionen \"%s\": kan inte använda funktionsnamn som parameternamn"
+msgstr "funktionen \"%s\": kan inte använda funktionsnamn som parameternamn"
-#: awkgram.y:4192
+#: awkgram.y:4288
#, c-format
msgid "function `%s': can't use special variable `%s' as a function parameter"
msgstr ""
-"funktionen \"%s\": det går inte att använda specialvariabeln \"%s\" som en "
+"funktionen \"%s\": det går inte att använda specialvariabeln \"%s\" som en "
"funktionsparameter"
-#: awkgram.y:4208
+#: awkgram.y:4296
#, c-format
-msgid "function name `%s' previously defined"
-msgstr "funktionsnamnet \"%s\" är definierat sedan tidigare"
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "funktionen \"%s\": parameter %d, \"%s\", är samma som parameter %d"
-#: awkgram.y:4376 awkgram.y:4382
+#: awkgram.y:4383 awkgram.y:4389
#, c-format
msgid "function `%s' called but never defined"
msgstr "funktionen \"%s\" anropad men aldrig definierad"
-#: awkgram.y:4385
+#: awkgram.y:4393
#, c-format
msgid "function `%s' defined but never called directly"
msgstr "funktionen \"%s\" definierad men aldrig anropad direkt"
-#: awkgram.y:4417
+#: awkgram.y:4425
#, 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"
+msgstr "konstant reguljärt uttryck för parameter %d ger ett booleskt värde"
-#: awkgram.y:4526
+#: awkgram.y:4484
#, 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"
-"eller använd som variabel eller vektor"
+"eller använd som variabel eller vektor"
-#: awkgram.y:4773 eval.c:2056
+#: awkgram.y:4720
msgid "division by zero attempted"
-msgstr "försökte dividera med noll"
+msgstr "försökte dividera med noll"
-#: awkgram.y:4782 eval.c:2072
+#: awkgram.y:4729
#, c-format
msgid "division by zero attempted in `%%'"
-msgstr "försökte dividera med noll i \"%%\""
+msgstr "försökte dividera med noll i \"%%\""
+
+#: awkgram.y:5049
+msgid ""
+"cannot assign a value to the result of a field post-increment expression"
+msgstr ""
+"kan inte tilldela ett värde till uttryck som är en efterinkrementering av "
+"ett fält"
+
+#: awkgram.y:5052
+#, c-format
+msgid "invalid target of assignment (opcode %s)"
+msgstr "ogiltigt mål för tilldelning (op-kod %s)"
-#: builtin.c:120
+#: builtin.c:133
#, c-format
msgid "%s to \"%s\" failed (%s)"
msgstr "%s till \"%s\" misslyckades (%s)"
-#: builtin.c:121
+#: builtin.c:134
msgid "standard output"
msgstr "standard ut"
-#: builtin.c:135
+#: builtin.c:148
msgid "exp: received non-numeric argument"
msgstr "exp: fick ett ickenumeriskt argument"
-#: builtin.c:141
+#: builtin.c:154
#, c-format
msgid "exp: argument %g is out of range"
-msgstr "exp: argumentet %g är inte inom tillåten gräns"
+msgstr "exp: argumentet %g är inte inom tillåten gräns"
-#: builtin.c:200
+#: builtin.c:229
#, 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"
+"fflush: kan inte spola: röret \"%s\" öppnat för läsning, inte skrivning"
-#: builtin.c:203
+#: builtin.c:232
#, 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"
+"fflush: kan inte spola: filen \"%s\" öppnad för läsning, inte skrivning"
-#: builtin.c:215
+#: builtin.c:244
#, 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"
+msgstr "fflush: \"%s\" är inte en öppen fil, rör eller koprocess"
-#: builtin.c:333
+#: builtin.c:362
msgid "index: received non-string first argument"
-msgstr "index: första argumentet är inte en sträng"
+msgstr "index: första argumentet är inte en sträng"
-#: builtin.c:335
+#: builtin.c:364
msgid "index: received non-string second argument"
-msgstr "index: andra argumentet är inte en sträng"
+msgstr "index: andra argumentet är inte en sträng"
-#: builtin.c:457
+#: builtin.c:488 mpfr.c:757
msgid "int: received non-numeric argument"
msgstr "int: fick ett ickenumeriskt argument"
-#: builtin.c:493
+#: builtin.c:525
msgid "length: received array argument"
msgstr "length: fick ett vektorargument"
-#: builtin.c:496
+#: builtin.c:528
msgid "`length(array)' is a gawk extension"
-msgstr "\"length(array)\" är en gawk-utökning"
+msgstr "\"length(array)\" är en gawk-utökning"
-#: builtin.c:504
+#: builtin.c:544
msgid "length: received non-string argument"
-msgstr "length: fick ett argument som inte är en sträng"
+msgstr "length: fick ett argument som inte är en sträng"
-#: builtin.c:535
+#: builtin.c:575
msgid "log: received non-numeric argument"
msgstr "log: fick ett ickenumeriskt argument"
-#: builtin.c:538
+#: builtin.c:578
#, c-format
msgid "log: received negative argument %g"
msgstr "log: fick ett negativt argumentet %g"
-#: builtin.c:694 builtin.c:699
+#: builtin.c:776 builtin.c:781
msgid "fatal: must use `count$' on all formats or none"
-msgstr "ödesdigert: måste använda \"count$\" på alla eller inga format"
+msgstr "ödesdigert: måste använda \"count$\" på alla eller inga format"
-#: builtin.c:761
+#: builtin.c:851
#, c-format
msgid "field width is ignored for `%%' specifier"
-msgstr "fältbredd ignoreras för \"%%\"-specificerare"
+msgstr "fältbredd ignoreras för \"%%\"-specificerare"
-#: builtin.c:763
+#: builtin.c:853
#, c-format
msgid "precision is ignored for `%%' specifier"
-msgstr "precision ignoreras för \"%%\"-specificerare"
+msgstr "precision ignoreras för \"%%\"-specificerare"
-#: builtin.c:765
+#: builtin.c:855
#, c-format
msgid "field width and precision are ignored for `%%' specifier"
-msgstr "fältbredd och precision ignoreras för \"%%\"-specificerare"
+msgstr "fältbredd och precision ignoreras för \"%%\"-specificerare"
-#: builtin.c:816
+#: builtin.c:906
msgid "fatal: `$' is not permitted in awk formats"
-msgstr "ödesdigert: \"$\" tillåts inte i awk-format"
+msgstr "ödesdigert: \"$\" tillåts inte i awk-format"
-#: builtin.c:825
+#: builtin.c:915
msgid "fatal: arg count with `$' must be > 0"
-msgstr "ödesdigert: argumentantalet med \"$\" måste vara > 0"
+msgstr "ödesdigert: argumentantalet med \"$\" måste vara > 0"
-#: builtin.c:829
+#: builtin.c:919
#, c-format
msgid "fatal: arg count %ld greater than total number of supplied arguments"
-msgstr "ödesdigert: argumentantalet %ld är större än antalet givna argument"
+msgstr "ödesdigert: argumentantalet %ld är större än antalet givna argument"
-#: builtin.c:833
+#: builtin.c:923
msgid "fatal: `$' not permitted after period in format"
-msgstr "ödesdigert: \"$\" tillåts inte efter en punkt i formatet"
+msgstr "ödesdigert: \"$\" tillåts inte efter en punkt i formatet"
-#: builtin.c:849
+#: builtin.c:939
msgid "fatal: no `$' supplied for positional field width or precision"
msgstr ""
-"ödesdigert: inget \"$\" bifogat för positionsangiven fältbredd eller "
+"ödesdigert: inget \"$\" bifogat för positionsangiven fältbredd eller "
"precision"
-#: builtin.c:920
+#: builtin.c:1009
msgid "`l' is meaningless in awk formats; ignored"
-msgstr "\"l\" är meningslös i awk-format, ignorerad"
+msgstr "\"l\" är meningslös i awk-format, ignorerad"
-#: builtin.c:924
+#: builtin.c:1013
msgid "fatal: `l' is not permitted in POSIX awk formats"
-msgstr "ödesdigert: \"l\" tillåts inte i POSIX awk-format"
+msgstr "ödesdigert: \"l\" tillåts inte i POSIX awk-format"
-#: builtin.c:937
+#: builtin.c:1026
msgid "`L' is meaningless in awk formats; ignored"
-msgstr "\"L\" är meningslös i awk-format, ignorerad"
+msgstr "\"L\" är meningslös i awk-format, ignorerad"
-#: builtin.c:941
+#: builtin.c:1030
msgid "fatal: `L' is not permitted in POSIX awk formats"
-msgstr "ödesdigert: \"L\" tillåts inte i POSIX awk-format"
+msgstr "ödesdigert: \"L\" tillåts inte i POSIX awk-format"
-#: builtin.c:954
+#: builtin.c:1043
msgid "`h' is meaningless in awk formats; ignored"
-msgstr "\"h\" är meningslös i awk-format, ignorerad"
+msgstr "\"h\" är meningslös i awk-format, ignorerad"
-#: builtin.c:958
+#: builtin.c:1047
msgid "fatal: `h' is not permitted in POSIX awk formats"
-msgstr "ödesdigert: \"h\" tillåts inte i POSIX awk-format"
+msgstr "ödesdigert: \"h\" tillåts inte i POSIX awk-format"
-#: builtin.c:1271
+#: builtin.c:1463
#, c-format
msgid "[s]printf: value %g is out of range for `%%%c' format"
-msgstr "[s]printf: värdet %g är utanför \"%%%c\"-formatets giltiga intervall"
+msgstr "[s]printf: värdet %g är utanför \"%%%c\"-formatets giltiga intervall"
-#: builtin.c:1331
+#: builtin.c:1561
#, c-format
msgid "ignoring unknown format specifier character `%c': no argument converted"
msgstr ""
-"ignorerar okänt formatspecifikationstecken \"%c\": inget argument konverterat"
+"ignorerar okänt formatspecifikationstecken \"%c\": inget argument konverterat"
-#: builtin.c:1336
+#: builtin.c:1566
msgid "fatal: not enough arguments to satisfy format string"
-msgstr "ödesdigert: för få argument för formatsträngen"
+msgstr "ödesdigert: för få argument för formatsträngen"
-#: builtin.c:1338
+#: builtin.c:1568
msgid "^ ran out for this one"
-msgstr "^ tog slut här"
+msgstr "^ tog slut här"
-#: builtin.c:1345
+#: builtin.c:1575
msgid "[s]printf: format specifier does not have control letter"
-msgstr "[s]printf: formatspecifieraren har ingen kommandobokstav"
+msgstr "[s]printf: formatspecificeraren har ingen kommandobokstav"
-#: builtin.c:1348
+#: builtin.c:1578
msgid "too many arguments supplied for format string"
-msgstr "för många argument för formatsträngen"
+msgstr "för många argument för formatsträngen"
-#: builtin.c:1422 builtin.c:1433
+#: builtin.c:1634
+msgid "sprintf: no arguments"
+msgstr "sprintf: inga argument"
+
+#: builtin.c:1657 builtin.c:1668
msgid "printf: no arguments"
msgstr "printf: inga argument"
-#: builtin.c:1474
+#: builtin.c:1711
msgid "sqrt: received non-numeric argument"
msgstr "sqrt: fick ickenumeriskt argument"
-#: builtin.c:1478
+#: builtin.c:1715
#, c-format
msgid "sqrt: called with negative argument %g"
msgstr "sqrt: anropad med negativt argument %g"
-#: builtin.c:1502
+#: builtin.c:1746
#, c-format
msgid "substr: length %g is not >= 1"
-msgstr "substr: längden %g är inte >= 1"
+msgstr "substr: längden %g är inte >= 1"
-#: builtin.c:1504
+#: builtin.c:1748
#, c-format
msgid "substr: length %g is not >= 0"
-msgstr "substr: längden %g är inte >= 0"
+msgstr "substr: längden %g är inte >= 0"
-#: builtin.c:1511
+#: builtin.c:1755
#, c-format
msgid "substr: non-integer length %g will be truncated"
-msgstr "substr: längden %g som inte är ett heltal kommer trunkeras"
+msgstr "substr: längden %g som inte är ett heltal kommer huggas av"
-#: builtin.c:1516
+#: builtin.c:1760
#, 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"
+msgstr "substr: längden %g är för stor för strängindexering, huggas av till %g"
-#: builtin.c:1528
+#: builtin.c:1772
#, c-format
msgid "substr: start index %g is invalid, using 1"
-msgstr "substr: startindex %g är ogiltigt, använder 1"
+msgstr "substr: startindex %g är ogiltigt, använder 1"
-#: builtin.c:1533
+#: builtin.c:1777
#, c-format
msgid "substr: non-integer start index %g will be truncated"
-msgstr "substr: startindex %g som inte är ett heltal kommer trunkeras"
+msgstr "substr: startindex %g som inte är ett heltal kommer huggas av"
-#: builtin.c:1558
+#: builtin.c:1802
msgid "substr: source string is zero length"
-msgstr "substr: källsträngen är tom"
+msgstr "substr: källsträngen är tom"
-#: builtin.c:1574
+#: builtin.c:1818
#, c-format
msgid "substr: start index %g is past end of string"
-msgstr "substr: startindex %g är bortom strängens slut"
+msgstr "substr: startindex %g är bortom strängens slut"
-#: builtin.c:1582
+#: builtin.c:1826
#, 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)"
+"substr: längden %g vid startindex %g överskrider det första argumentets "
+"längd (%lu)"
-#: builtin.c:1655
+#: builtin.c:1900
msgid "strftime: format value in PROCINFO[\"strftime\"] has numeric type"
-msgstr "strftime: formatvärde i PROCINFO[\"strftime\"] har numerisk typ"
+msgstr "strftime: formatvärde i PROCINFO[\"strftime\"] har numerisk typ"
-#: builtin.c:1678
+#: builtin.c:1923
msgid "strftime: received non-numeric second argument"
msgstr "strftime: fick ett ickenumeriskt andra argument"
-#: builtin.c:1681
+#: builtin.c:1927
msgid "strftime: second argument less than 0 or too big for time_t"
-msgstr ""
+msgstr "strftime: andra argumentet mindre än 0 eller för stort för time_t"
-#: builtin.c:1687
+#: builtin.c:1934
msgid "strftime: received non-string first argument"
-msgstr "strftime: fick ett första argument som inte är en sträng"
+msgstr "strftime: fick ett första argument som inte är en sträng"
-#: builtin.c:1693
+#: builtin.c:1941
msgid "strftime: received empty format string"
-msgstr "strftime: fick en tom formatsträng"
+msgstr "strftime: fick en tom formatsträng"
-#: builtin.c:1759
+#: builtin.c:2007
msgid "mktime: received non-string argument"
-msgstr "mktime: fick ett argument som inte är en sträng"
+msgstr "mktime: fick ett argument som inte är en sträng"
-#: builtin.c:1776
+#: builtin.c:2024
msgid "mktime: at least one of the values is out of the default range"
-msgstr "mktime: åtminstone ett av värdena är utanför standardintervallet"
+msgstr "mktime: åtminstone ett av värdena är utanför standardintervallet"
-#: builtin.c:1811
+#: builtin.c:2059
msgid "'system' function not allowed in sandbox mode"
-msgstr "funktionen \"system\" är inte tillåten i sandlådeläge"
+msgstr "funktionen \"system\" är inte tillåten i sandlådeläge"
-#: builtin.c:1816
+#: builtin.c:2064
msgid "system: received non-string argument"
-msgstr "system: fick ett argument som inte är en sträng"
-
-#: builtin.c:1871 eval.c:1159 eval.c:1790 eval.c:1803
-#, c-format
-msgid "reference to uninitialized variable `%s'"
-msgstr "referens till icke initierad variabel \"%s\""
+msgstr "system: fick ett argument som inte är en sträng"
-#: builtin.c:1938
+#: builtin.c:2184
#, c-format
msgid "reference to uninitialized field `$%d'"
-msgstr "referens till icke initierat fält \"$%d\""
+msgstr "referens till icke initierat fält \"$%d\""
-#: builtin.c:2025
+#: builtin.c:2271
msgid "tolower: received non-string argument"
-msgstr "tolower: fick ett argument som inte är en sträng"
+msgstr "tolower: fick ett argument som inte är en sträng"
-#: builtin.c:2059
+#: builtin.c:2305
msgid "toupper: received non-string argument"
-msgstr "toupper: fick ett argument som inte är en sträng"
+msgstr "toupper: fick ett argument som inte är en sträng"
-#: builtin.c:2095
+#: builtin.c:2341 mpfr.c:672
msgid "atan2: received non-numeric first argument"
-msgstr "atan2: fick ett ickenumeriskt första argument"
+msgstr "atan2: fick ett ickenumeriskt första argument"
-#: builtin.c:2097
+#: builtin.c:2343 mpfr.c:674
msgid "atan2: received non-numeric second argument"
msgstr "atan2: fick ett ickenumeriskt andra argument"
-#: builtin.c:2116
+#: builtin.c:2362
msgid "sin: received non-numeric argument"
msgstr "sin: fick ett ickenumeriskt argument"
-#: builtin.c:2132
+#: builtin.c:2378
msgid "cos: received non-numeric argument"
msgstr "cos: fick ett ickenumeriskt argument"
-#: builtin.c:2185
+#: builtin.c:2431 mpfr.c:1156
msgid "srand: received non-numeric argument"
msgstr "srand: fick ett ickenumeriskt argument"
-#: builtin.c:2216
+#: builtin.c:2462
msgid "match: third argument is not an array"
-msgstr "match: tredje argumentet är inte en vektor"
+msgstr "match: tredje argumentet är inte en vektor"
-#: builtin.c:2480
+#: builtin.c:2734
msgid "gensub: third argument of 0 treated as 1"
msgstr "gensub: nollan i tredje argumentet behandlad som en etta"
-#: builtin.c:2773
+#: builtin.c:3030
msgid "lshift: received non-numeric first argument"
-msgstr "lshift: fick ett ickenumeriskt första argument"
+msgstr "lshift: fick ett ickenumeriskt första argument"
-#: builtin.c:2775
+#: builtin.c:3032
msgid "lshift: received non-numeric second argument"
msgstr "lshift: fick ett ickenumeriskt andra argument"
-#: builtin.c:2781
+#: builtin.c:3038
#, c-format
-msgid "lshift(%lf, %lf): negative values will give strange results"
-msgstr "lshift(%lf, %lf): negativa värden kommer ge konstiga resultat"
+msgid "lshift(%f, %f): negative values will give strange results"
+msgstr "lshift(%f, %f): negativa värden kommer ge konstiga resultat"
-#: builtin.c:2783
+#: builtin.c:3040
#, c-format
-msgid "lshift(%lf, %lf): fractional values will be truncated"
-msgstr "lshift(%lf, %lf): flyttalsvärden kommer trunkeras"
+msgid "lshift(%f, %f): fractional values will be truncated"
+msgstr "lshift(%f, %f): flyttalsvärden kommer huggas av"
-#: builtin.c:2785
+#: builtin.c:3042
#, 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"
+msgid "lshift(%f, %f): too large shift value will give strange results"
+msgstr "lshift(%f, %f): för stort skiftvärde kommer ge konstiga resultat"
-#: builtin.c:2810
+#: builtin.c:3067
msgid "rshift: received non-numeric first argument"
-msgstr "rshift: fick ett ickenumeriskt första argument"
+msgstr "rshift: fick ett ickenumeriskt första argument"
-#: builtin.c:2812
+#: builtin.c:3069
msgid "rshift: received non-numeric second argument"
msgstr "rshift: fick ett ickenumeriskt andra argument"
-#: builtin.c:2818
+#: builtin.c:3075
#, c-format
-msgid "rshift(%lf, %lf): negative values will give strange results"
-msgstr "rshift(%lf, %lf): negativa värden kommer ge konstiga resultat"
+msgid "rshift(%f, %f): negative values will give strange results"
+msgstr "rshift(%f, %f): negativa värden kommer ge konstiga resultat"
-#: builtin.c:2820
+#: builtin.c:3077
#, c-format
-msgid "rshift(%lf, %lf): fractional values will be truncated"
-msgstr "rshift(%lf, %lf): flyttalsvärden kommer trunkeras"
+msgid "rshift(%f, %f): fractional values will be truncated"
+msgstr "rshift(%f, %f): flyttalsvärden kommer huggas av"
-#: builtin.c:2822
+#: builtin.c:3079
#, 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:2847
-msgid "and: received non-numeric first argument"
-msgstr "and: fick ett ickenumeriskt första argument"
+msgid "rshift(%f, %f): too large shift value will give strange results"
+msgstr "rshift(%f, %f): för stor skiftvärde kommer ge konstiga resultat"
-#: builtin.c:2849
-msgid "and: received non-numeric second argument"
-msgstr "and: fick ett ickenumeriskt andra argument"
+#: builtin.c:3104 mpfr.c:968
+msgid "and: called with less than two arguments"
+msgstr "and: anropad med mindre än två argument"
-#: builtin.c:2855
+#: builtin.c:3109
#, c-format
-msgid "and(%lf, %lf): negative values will give strange results"
-msgstr "and(%lf, %lf): negativa värden kommer ge konstiga resultat"
+msgid "and: argument %d is non-numeric"
+msgstr "and: argument %d är inte numeriskt"
-#: builtin.c:2857
+#: builtin.c:3113
#, c-format
-msgid "and(%lf, %lf): fractional values will be truncated"
-msgstr "and(%lf, %lf): flyttalsvärden kommer trunkeras"
+msgid "and: argument %d negative value %g will give strange results"
+msgstr "and: argument %d med negativt värde %g kommer ge konstiga resultat"
-#: builtin.c:2882
-msgid "or: received non-numeric first argument"
-msgstr "or: fick ett ickenumeriskt första argument"
+#: builtin.c:3136 mpfr.c:1000
+msgid "or: called with less than two arguments"
+msgstr "or: anropad med färre än två argument"
-#: builtin.c:2884
-msgid "or: received non-numeric second argument"
-msgstr "or: fick ett ickenumeriskt andra argument"
-
-#: builtin.c:2890
+#: builtin.c:3141
#, c-format
-msgid "or(%lf, %lf): negative values will give strange results"
-msgstr "or(%lf, %lf): negativa värden kommer ge konstiga resultat"
+msgid "or: argument %d is non-numeric"
+msgstr "or: argument %d är inte numeriskt"
-#: builtin.c:2892
+#: builtin.c:3145
#, c-format
-msgid "or(%lf, %lf): fractional values will be truncated"
-msgstr "or(%lf, %lf): flyttalsvärden kommer trunkeras"
-
-#: builtin.c:2920
-msgid "xor: received non-numeric first argument"
-msgstr "xor: fick ett ickenumeriskt första argument"
+msgid "or: argument %d negative value %g will give strange results"
+msgstr "or: argument %d med negativt värde %g kommer ge konstiga resultat"
-#: builtin.c:2922
-msgid "xor: received non-numeric second argument"
-msgstr "xor: fick ett ickenumeriskt andra argument"
+#: builtin.c:3167 mpfr.c:1031
+msgid "xor: called with less than two arguments"
+msgstr "xor: anropad med färre än två argument"
-#: builtin.c:2928
+#: builtin.c:3173
#, c-format
-msgid "xor(%lf, %lf): negative values will give strange results"
-msgstr "xor(%lf, %lf): negativa värden kommer ge konstiga resultat"
+msgid "xor: argument %d is non-numeric"
+msgstr "xor: argument %d är inte numeriskt"
-#: builtin.c:2930
+#: builtin.c:3177
#, c-format
-msgid "xor(%lf, %lf): fractional values will be truncated"
-msgstr "xor(%lf, %lf): flyttalsvärden kommer trunkeras"
+msgid "xor: argument %d negative value %g will give strange results"
+msgstr "xor: argument %d med negativt värde %g kommer ge konstiga resultat"
-#: builtin.c:2954 builtin.c:2960
+#: builtin.c:3202 mpfr.c:787
msgid "compl: received non-numeric argument"
msgstr "compl: fick ett ickenumeriskt argument"
-#: builtin.c:2962
+#: builtin.c:3208
#, c-format
-msgid "compl(%lf): negative value will give strange results"
-msgstr "compl(%lf): negativa värden kommer ge konstiga resultat"
+msgid "compl(%f): negative value will give strange results"
+msgstr "compl(%f): negativt värde kommer ge konstiga resultat"
-#: builtin.c:2964
+#: builtin.c:3210
#, c-format
-msgid "compl(%lf): fractional value will be truncated"
-msgstr "compl(%lf): flyttalsvärden kommer trunkeras"
+msgid "compl(%f): fractional value will be truncated"
+msgstr "compl(%f): flyttalsvärde kommer huggas av"
-#: builtin.c:3133
+#: builtin.c:3379
#, c-format
msgid "dcgettext: `%s' is not a valid locale category"
-msgstr "dcgettext: \"%s\" är inte en giltig lokalkategori"
+msgstr "dcgettext: \"%s\" är inte en giltig lokalkategori"
+
+#: command.y:225
+#, c-format
+msgid "Type (g)awk statement(s). End with the command \"end\"\n"
+msgstr "Skriv (g)awk-satser. Avsluta med kommandot â€endâ€\n"
+
+#: command.y:289
+#, c-format
+msgid "invalid frame number: %d"
+msgstr "ogiltigt ramnummer: %d"
+
+#: command.y:295
+#, c-format
+msgid "info: invalid option - \"%s\""
+msgstr "info: ogiltig flagga - â€%sâ€"
+
+#: command.y:321
+#, c-format
+msgid "source \"%s\": already sourced."
+msgstr "source \"%s\": redan inläst."
+
+#: command.y:326
+#, c-format
+msgid "save \"%s\": command not permitted."
+msgstr "save \"%s\": kommandot inte tillåtet."
+
+#: command.y:339
+msgid "Can't use command `commands' for breakpoint/watchpoint commands"
+msgstr ""
+"Det gÃ¥r inte att använda kommandot â€commands†i brytpunkts-/"
+"observationspunktskommandon"
+
+#: command.y:341
+msgid "no breakpoint/watchpoint has been set yet"
+msgstr "ingen brytpunkt/observationspunkt har satts ännu"
+
+#: command.y:343
+msgid "invalid breakpoint/watchpoint number"
+msgstr "ogiltigt brytpunkts-/observationspunktsnummer"
+
+#: command.y:348
+#, c-format
+msgid "Type commands for when %s %d is hit, one per line.\n"
+msgstr "Skriv kommandon att användas när %s %d träffas, ett per rad.\n"
+
+#: command.y:350
+#, c-format
+msgid "End with the command \"end\"\n"
+msgstr "Avsluta med kommandot â€endâ€\n"
+
+#: command.y:357
+msgid "`end' valid only in command `commands' or `eval'"
+msgstr "â€end†är giltigt endast i kommandona â€commands†och â€evalâ€"
+
+#: command.y:367
+msgid "`silent' valid only in command `commands'"
+msgstr "â€silent†är giltigt endast i kommandot â€commandsâ€"
+
+#: command.y:373
+#, c-format
+msgid "trace: invalid option - \"%s\""
+msgstr "trace: ogiltig flagga - â€%sâ€"
+
+#: command.y:387
+msgid "condition: invalid breakpoint/watchpoint number"
+msgstr "condition: ogiltigt brytpunkts-/observationspunktsnummer"
+
+#: command.y:449
+msgid "argument not a string"
+msgstr "argumentet är inte en sträng"
+
+#: command.y:459 command.y:464
+#, c-format
+msgid "option: invalid parameter - \"%s\""
+msgstr "option: ogiltig parameter - \"%s\""
+
+#: command.y:474
+#, c-format
+msgid "no such function - \"%s\""
+msgstr "ingen sådan funktion - \"%s\""
+
+#: command.y:531
+#, c-format
+msgid "enable: invalid option - \"%s\""
+msgstr "enable: ogiltig flagga - â€%sâ€"
+
+#: command.y:597
+#, c-format
+msgid "invalid range specification: %d - %d"
+msgstr "ogiltigt intervallspecifikation: %d - %d"
+
+#: command.y:659
+msgid "non-numeric value for field number"
+msgstr "icke numeriskt värde som fältnummer"
+
+#: command.y:680 command.y:687
+msgid "non-numeric value found, numeric expected"
+msgstr "ickenumeriskt värde fanns, numeriskt förväntades"
+
+#: command.y:712 command.y:718
+msgid "non-zero integer value"
+msgstr "heltalsvärde som inte är noll"
+
+#: command.y:817
+msgid ""
+"backtrace [N] - print trace of all or N innermost (outermost if N < 0) "
+"frames."
+msgstr ""
+"backtrace [N] - skriv ett spår över alla eller N innersta (yttersta om N < "
+"0) ramar."
+
+#: command.y:819
+msgid ""
+"break [[filename:]N|function] - set breakpoint at the specified location."
+msgstr "break [[filename:]N|function] - sätt brytpunkt på den angivna platsen."
+
+#: command.y:821
+msgid "clear [[filename:]N|function] - delete breakpoints previously set."
+msgstr "clear [[filnamn:]N|funktion] - radera tidigare satta brytpunkter."
+
+#: command.y:823
+msgid ""
+"commands [num] - starts a list of commands to be executed at a "
+"breakpoint(watchpoint) hit."
+msgstr ""
+"commands [num] - startar en lista av kommandon att köra när en "
+"brytpunkt(observationspunkt) träffas."
+
+#: command.y:825
+msgid "condition num [expr] - set or clear breakpoint or watchpoint condition."
+msgstr ""
+"condition num [uttr] - sätt eller töm en brytpunkts eller observationspunkts "
+"villkor."
+
+#: command.y:827
+msgid "continue [COUNT] - continue program being debugged."
+msgstr "continue [ANTAL] - fortsätt programmet som felsöks."
+
+#: command.y:829
+msgid "delete [breakpoints] [range] - delete specified breakpoints."
+msgstr "delete [brytpunkter] [intervall] - radera angivna brytpunkter."
+
+#: command.y:831
+msgid "disable [breakpoints] [range] - disable specified breakpoints."
+msgstr "disable [brytpunkter] [intervall] - avaktivera angivna brytpunkter."
+
+#: command.y:833
+msgid "display [var] - print value of variable each time the program stops."
+msgstr ""
+"display [var] - skriv ut värdet på variabeln varje gång programmet stoppar."
+
+#: command.y:835
+msgid "down [N] - move N frames down the stack."
+msgstr "down [N] - flytta N ramar ner i stacken."
+
+#: command.y:837
+msgid "dump [filename] - dump instructions to file or stdout."
+msgstr "dump [filnamn] - skriv instruktioner till filen eller standard ut."
+
+#: command.y:839
+msgid "enable [once|del] [breakpoints] [range] - enable specified breakpoints."
+msgstr ""
+"enable [once|del] [brytpunkter] [intervall] - aktivera angivna brytpunkter."
+
+#: command.y:841
+msgid "end - end a list of commands or awk statements."
+msgstr "end - avsluta en lista av kommandon eller awk-satser."
+
+#: command.y:843
+msgid "eval stmt|[p1, p2, ...] - evaluate awk statement(s)."
+msgstr "eval sats|[p1, p2, ...] - utför awk-sats(er)."
+
+#: command.y:845
+msgid "finish - execute until selected stack frame returns."
+msgstr "finish - kör tills den valda stackramen returnerar."
+
+#: command.y:847
+msgid "frame [N] - select and print stack frame number N."
+msgstr "frame [N] - välj och skriv ut stackram nummer N."
+
+#: command.y:849
+msgid "help [command] - print list of commands or explanation of command."
+msgstr ""
+"help [kommando] - skriv listan av kommandon eller en förklaring av kommando."
+
+#: command.y:851
+msgid "ignore N COUNT - set ignore-count of breakpoint number N to COUNT."
+msgstr ""
+"ignore N ANTAL - sätt ignoreringsantal på brytpunkt nummer N till ANTAL."
+
+#: command.y:853
+msgid ""
+"info topic - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch."
+msgstr ""
+"info topic - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch."
+
+#: command.y:855
+msgid "list [-|+|[filename:]lineno|function|range] - list specified line(s)."
+msgstr "list [-|+|[filnamn:]radnr|funktion|intervall] - lista angivna rad(er)."
+
+#: command.y:857
+msgid "next [COUNT] - step program, proceeding through subroutine calls."
+msgstr "next [ANTAL] - stega programmet, passera genom subrutinanrop."
+
+#: command.y:859
+msgid ""
+"nexti [COUNT] - step one instruction, but proceed through subroutine calls."
+msgstr "nexti [ANTAL] - stega en instruktion, men passera genom subrutinanrop."
+
+#: command.y:861
+msgid "option [name[=value]] - set or display debugger option(s)."
+msgstr "option [namn[=värde]] - sätt eller visa felsökningsalternativ."
+
+#: command.y:863
+msgid "print var [var] - print value of a variable or array."
+msgstr "print var [var] - skriv värdet på en variabel eller vektor."
+
+#: command.y:865
+msgid "printf format, [arg], ... - formatted output."
+msgstr "printf format, [arg], … - formaterad utskrift."
+
+#: command.y:867
+msgid "quit - exit debugger."
+msgstr "quit - avsluta felsökaren."
+
+#: command.y:869
+msgid "return [value] - make selected stack frame return to its caller."
+msgstr "return [värde] - låt den valda stackramen returnera till sin anropare."
+
+#: command.y:871
+msgid "run - start or restart executing program."
+msgstr "run - starta eller starta om körningen av programmet."
+
+#: command.y:874
+msgid "save filename - save commands from the session to file."
+msgstr "save filnamn - spara kommandon från sessionen i en fil."
+
+#: command.y:877
+msgid "set var = value - assign value to a scalar variable."
+msgstr "set var = värde - tilldela värde till en skalär variabel."
+
+#: command.y:879
+msgid ""
+"silent - suspends usual message when stopped at a breakpoint/watchpoint."
+msgstr ""
+"silent - undertrycker normala meddelanden vid stopp på en brytpunkt/"
+"observationspunkt. "
+
+#: command.y:881
+msgid "source file - execute commands from file."
+msgstr "source fil - kör kommandon från fil."
+
+#: command.y:883
+msgid "step [COUNT] - step program until it reaches a different source line."
+msgstr "step [ANTAL] - stega programmet tills det når en annan källkodsrad."
+
+#: command.y:885
+msgid "stepi [COUNT] - step one instruction exactly."
+msgstr "stepi [ANTAL] - stega exakt en instruktion."
+
+#: command.y:887
+msgid "tbreak [[filename:]N|function] - set a temporary breakpoint."
+msgstr "tbreak [[filenamn:]N|funktion] - sätt en tillfällig brytpunkt."
+
+#: command.y:889
+msgid "trace on|off - print instruction before executing."
+msgstr "trace on|off - skriv ut instruktioner före de körs."
+
+#: command.y:891
+msgid "undisplay [N] - remove variable(s) from automatic display list."
+msgstr "undisplay [N] - ta bort variabler från listan över automatiskt visade."
+
+#: command.y:893
+msgid ""
+"until [[filename:]N|function] - execute until program reaches a different "
+"line or line N within current frame."
+msgstr ""
+"until [[filenamn:]N|funktion] - kör tills programmet når en annan rad eller "
+"rad N inom aktuell ram."
+
+#: command.y:895
+msgid "unwatch [N] - remove variable(s) from watch list."
+msgstr "unwatch [N] - ta bort variabler från observationslistan."
+
+#: command.y:897
+msgid "up [N] - move N frames up the stack."
+msgstr "up [N] - flytta N ramar uppåt i stacken."
+
+#: command.y:899
+msgid "watch var - set a watchpoint for a variable."
+msgstr "watch var - sätt en observationspunkt för en variabel."
+
+#: command.y:1011 debug.c:401 msg.c:135
+#, c-format
+msgid "error: "
+msgstr "fel: "
+
+#: command.y:1051
+#, c-format
+msgid "can't read command (%s)\n"
+msgstr "kan inte läsa kommando (%s)\n"
+
+#: command.y:1065
+#, c-format
+msgid "can't read command (%s)"
+msgstr "kan inte läsa kommandot (%s)"
+
+#: command.y:1116
+msgid "invalid character in command"
+msgstr "ogiltigt tecken i kommandot"
+
+#: command.y:1152
+#, c-format
+msgid "unknown command - \"%.*s\", try help"
+msgstr "okänt kommando - \"%.*s\", försök med help"
+
+#: command.y:1222
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: command.y:1284
+msgid "invalid character"
+msgstr "ogiltigt tecken"
+
+#: command.y:1455
+#, c-format
+msgid "undefined command: %s\n"
+msgstr "odefinierat kommando: %s\n"
+
+#: debug.c:252
+msgid "set or show the number of lines to keep in history file."
+msgstr "sätt eller visa antalet rader att behålla i historikfilen."
+
+#: debug.c:254
+msgid "set or show the list command window size."
+msgstr "sätt eller visa fönsterstorleken för listkommandot."
+
+#: debug.c:256
+msgid "set or show gawk output file."
+msgstr "sätt eller visa gawks utmatningsfil."
+
+#: debug.c:258
+msgid "set or show debugger prompt."
+msgstr "sätt eller visa felsökningsprompten."
+
+#: debug.c:260
+msgid "(un)set or show saving of command history (value=on|off)."
+msgstr "slå av/på eller visa sparandet av kommandohistorik (värde=on|off)."
+
+#: debug.c:262
+msgid "(un)set or show saving of options (value=on|off)."
+msgstr "slå av/på eller visa sparandet av flaggor (värde=on|off)."
+
+#: debug.c:264
+msgid "(un)set or show instruction tracing (value=on|off)."
+msgstr "slå av/på eller visa instruktionsspårande (värde=on|off)."
+
+#: debug.c:345
+msgid "program not running."
+msgstr "programmet kör inte."
+
+#: debug.c:448 debug.c:606
+#, c-format
+msgid "can't read source file `%s' (%s)"
+msgstr "kan inte läsa källfilen â€%s†(%s)"
+
+#: debug.c:453
+#, c-format
+msgid "source file `%s' is empty.\n"
+msgstr "källfilen â€%s†är tom.\n"
+
+#: debug.c:480
+msgid "no current source file."
+msgstr "ingen aktuell källkodsfil."
+
+#: debug.c:505
+#, c-format
+msgid "cannot find source file named `%s' (%s)"
+msgstr "kan inte hitta nÃ¥gon källfil med namnet â€%s†(%s)"
+
+#: debug.c:529
+#, c-format
+msgid "WARNING: source file `%s' modified since program compilation.\n"
+msgstr "VARNING: källfilen â€%s†ändrad sedan programmet kompilerades.\n"
+
+#: debug.c:551
+#, c-format
+msgid "line number %d out of range; `%s' has %d lines"
+msgstr "radnummer %d utanför intervallet; â€%s†har %d rader"
+
+#: debug.c:611
+#, c-format
+msgid "unexpected eof while reading file `%s', line %d"
+msgstr "oväntat filslut när filen â€%s†lästes, rad %d"
+
+#: debug.c:620
+#, c-format
+msgid "source file `%s' modified since start of program execution"
+msgstr "källfilen â€%s†ändrad sedan början av programkörningen"
+
+#: debug.c:732
+#, c-format
+msgid "Current source file: %s\n"
+msgstr "Aktuell källfil: %s\n"
+
+#: debug.c:733
+#, c-format
+msgid "Number of lines: %d\n"
+msgstr "Antalet rader: %d\n"
+
+#: debug.c:740
+#, c-format
+msgid "Source file (lines): %s (%d)\n"
+msgstr "Källfilen (rader): %s (%d)\n"
+
+#: debug.c:754
+msgid ""
+"Number Disp Enabled Location\n"
+"\n"
+msgstr ""
+"Nummer Visa Aktiv Plats\n"
+"\n"
+
+#: debug.c:765
+#, c-format
+msgid "\tno of hits = %ld\n"
+msgstr "\tantal träffar = %ld\n"
+
+#: debug.c:767
+#, c-format
+msgid "\tignore next %ld hit(s)\n"
+msgstr "\tignorera nästa %ld träffar\n"
+
+#: debug.c:769 debug.c:909
+#, c-format
+msgid "\tstop condition: %s\n"
+msgstr "\tstoppvillkor: %s\n"
+
+#: debug.c:771 debug.c:911
+msgid "\tcommands:\n"
+msgstr "\tkommandon:\n"
+
+#: debug.c:793
+#, c-format
+msgid "Current frame: "
+msgstr "Aktuell ram: "
+
+#: debug.c:796
+#, c-format
+msgid "Called by frame: "
+msgstr "Anropad av ramen: "
+
+#: debug.c:800
+#, c-format
+msgid "Caller of frame: "
+msgstr "Anropare av ramen: "
+
+#: debug.c:818
+#, c-format
+msgid "None in main().\n"
+msgstr "Ingen i main().\n"
+
+#: debug.c:848
+msgid "No arguments.\n"
+msgstr "Inga argument.\n"
+
+#: debug.c:849
+msgid "No locals.\n"
+msgstr "Inga lokala.\n"
+
+#: debug.c:857
+msgid ""
+"All defined variables:\n"
+"\n"
+msgstr ""
+"Alla definierade variabler:\n"
+"\n"
+
+#: debug.c:867
+msgid ""
+"All defined functions:\n"
+"\n"
+msgstr ""
+"Alla definierade funktioner:\n"
+"\n"
+
+#: debug.c:886
+msgid ""
+"Auto-display variables:\n"
+"\n"
+msgstr ""
+"Automatvisade variabler:\n"
+"\n"
+
+#: debug.c:889
+msgid ""
+"Watch variables:\n"
+"\n"
+msgstr ""
+"Observerade variabler:\n"
+"\n"
+
+#: debug.c:1029
+#, c-format
+msgid "no symbol `%s' in current context\n"
+msgstr "ingen symbol â€%s†i aktuellt sammanhang\n"
+
+#: debug.c:1041 debug.c:1427
+#, c-format
+msgid "`%s' is not an array\n"
+msgstr "â€%s†är inte en vektor\n"
+
+#: debug.c:1055
+#, c-format
+msgid "$%ld = uninitialized field\n"
+msgstr "$%ld = oinitierat fält\n"
+
+#: debug.c:1076
+#, c-format
+msgid "array `%s' is empty\n"
+msgstr "vektorn â€%s†är tom\n"
+
+#: debug.c:1119 debug.c:1171
+#, c-format
+msgid "[\"%s\"] not in array `%s'\n"
+msgstr "[\"%s\"] finns inte i vektorn â€%sâ€\n"
+
+#: debug.c:1175
+#, c-format
+msgid "`%s[\"%s\"]' is not an array\n"
+msgstr "â€%s[\"%s\"]†är inte en vektor\n"
+
+#: debug.c:1236 debug.c:4964
+#, c-format
+msgid "`%s' is not a scalar variable"
+msgstr "â€%s†är inte en skalär variabel"
+
+#: debug.c:1258 debug.c:4994
+#, c-format
+msgid "attempt to use array `%s[\"%s\"]' in a scalar context"
+msgstr "försök att använda vektorn â€%s[\"%s\"]†i skalärt sammanhang"
+
+#: debug.c:1280 debug.c:5005
+#, c-format
+msgid "attempt to use scalar `%s[\"%s\"]' as array"
+msgstr "försök att använda skalären â€%s[\"%s\"]†som en vektor"
+
+#: debug.c:1423
+#, c-format
+msgid "`%s' is a function"
+msgstr "â€%s†är en funktion"
+
+#: debug.c:1465
+#, c-format
+msgid "watchpoint %d is unconditional\n"
+msgstr "observationspunkt %d är ovillkorlig\n"
+
+#: debug.c:1499
+#, c-format
+msgid "No display item numbered %ld"
+msgstr "Ingen visningspost med numret %ld"
+
+#: debug.c:1502
+#, c-format
+msgid "No watch item numbered %ld"
+msgstr "Ingen observationspost med numret %ld"
+
+#: debug.c:1528
+#, c-format
+msgid "%d: [\"%s\"] not in array `%s'\n"
+msgstr "%d: [\"%s\"] finns inte i vektorn â€%sâ€\n"
+
+#: debug.c:1767
+msgid "attempt to use scalar value as array"
+msgstr "försök att använda ett skalärt värde som vektor"
+
+#: debug.c:1856
+#, c-format
+msgid "Watchpoint %d deleted because parameter is out of scope.\n"
+msgstr ""
+"Observationspunkt %d raderad för att parametern är utanför sin räckvidd.\n"
+
+#: debug.c:1867
+#, c-format
+msgid "Display %d deleted because parameter is out of scope.\n"
+msgstr "Visning %d raderad för att parametern är utanför sin räckvidd.\n"
+
+#: debug.c:1900
+#, c-format
+msgid " in file `%s', line %d\n"
+msgstr " i filen â€%sâ€, rad %d\n"
+
+#: debug.c:1921
+#, c-format
+msgid " at `%s':%d"
+msgstr " vid â€%sâ€:%d"
+
+#: debug.c:1937 debug.c:2000
+#, c-format
+msgid "#%ld\tin "
+msgstr "#%ld\ti "
+
+#: debug.c:1974
+#, c-format
+msgid "More stack frames follow ...\n"
+msgstr "Fler stackramar följer …\n"
+
+#: debug.c:2017
+msgid "invalid frame number"
+msgstr "Ogiltigt ramnummer"
+
+#: debug.c:2200
+#, c-format
+msgid "Note: breakpoint %d (enabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+"Observera: brytpunkt %d (aktiverad, ignorera följande %ld träffar), är också "
+"satt vid %s:%d"
+
+#: debug.c:2207
+#, c-format
+msgid "Note: breakpoint %d (enabled), also set at %s:%d"
+msgstr "Observera: brytpunkt %d (aktiverad), är också satt vid %s:%d"
+
+#: debug.c:2214
+#, c-format
+msgid "Note: breakpoint %d (disabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+"Observera: brytpunkt %d (avaktiverad, intorera följande %ld träffar), är "
+"också satt vid %s:%d"
+
+#: debug.c:2221
+#, c-format
+msgid "Note: breakpoint %d (disabled), also set at %s:%d"
+msgstr "Observera: brytpunkt %d (avaktiverad), är också satt vid %s:%d"
+
+#: debug.c:2238
+#, c-format
+msgid "Breakpoint %d set at file `%s', line %d\n"
+msgstr "Brytpunkt %d satt vid filen â€%sâ€, rad %d\n"
+
+#: debug.c:2340
+#, c-format
+msgid "Can't set breakpoint in file `%s'\n"
+msgstr "Kan inte sätta en brytpunkt i filen â€%sâ€\n"
+
+#: debug.c:2369 debug.c:2492 debug.c:3350
+#, c-format
+msgid "line number %d in file `%s' out of range"
+msgstr "radnummer %d i filen â€%s†är utanför tillÃ¥tet intervall"
+
+#: debug.c:2373
+#, c-format
+msgid "Can't find rule!!!\n"
+msgstr "Kan inte hitta regeln!!!\n"
-#: eval.c:412
+#: debug.c:2375
+#, c-format
+msgid "Can't set breakpoint at `%s':%d\n"
+msgstr "Kan inte sätta en brytpunkt vid â€%sâ€:%d\n"
+
+#: debug.c:2387
+#, c-format
+msgid "Can't set breakpoint in function `%s'\n"
+msgstr "Kan inte sätta en brytpunkt i funktionen â€%sâ€\n"
+
+#: debug.c:2403
+#, c-format
+msgid "breakpoint %d set at file `%s', line %d is unconditional\n"
+msgstr "brytpunkt %d satt i filen â€%sâ€, rad %d är ovillkorlig\n"
+
+#: debug.c:2508 debug.c:2530
+#, c-format
+msgid "Deleted breakpoint %d"
+msgstr "Raderade brytpunkt %d"
+
+#: debug.c:2514
+#, c-format
+msgid "No breakpoint(s) at entry to function `%s'\n"
+msgstr "Inga brytpunkter vid ingÃ¥ngen till funktionen â€%sâ€\n"
+
+#: debug.c:2541
+#, c-format
+msgid "No breakpoint at file `%s', line #%d\n"
+msgstr "Ingen brytpunkt i filen â€%sâ€, rad nr. %d\n"
+
+#: debug.c:2596 debug.c:2637 debug.c:2657 debug.c:2700
+msgid "invalid breakpoint number"
+msgstr "ogiltigt brytpunktsnummer"
+
+#: debug.c:2612
+msgid "Delete all breakpoints? (y or n) "
+msgstr "Radera alla brytpunkter? (j eller n)"
+
+#: debug.c:2613 debug.c:2923 debug.c:2976
+msgid "y"
+msgstr "j"
+
+#: debug.c:2662
+#, c-format
+msgid "Will ignore next %ld crossing(s) of breakpoint %d.\n"
+msgstr "Kommer ignorera följande %ld passager av brytpunkt %d.\n"
+
+#: debug.c:2666
+#, c-format
+msgid "Will stop next time breakpoint %d is reached.\n"
+msgstr "Kommer stanna nästa gång brytpunkt %d nås.\n"
+
+#: debug.c:2783
+#, c-format
+msgid "Can only debug programs provided with the `-f' option.\n"
+msgstr "Kan bara felsöka program som getts flaggan â€-fâ€.\n"
+
+#: debug.c:2908
+#, c-format
+msgid "Failed to restart debugger"
+msgstr "Misslyckades att starta om felsökaren"
+
+#: debug.c:2922
+msgid "Program already running. Restart from beginning (y/n)? "
+msgstr "Programmet kör redan. Starta om från början (j/n)? "
+
+#: debug.c:2926
+#, c-format
+msgid "Program not restarted\n"
+msgstr "Programmet inte omstartat\n"
+
+#: debug.c:2936
+#, c-format
+msgid "error: cannot restart, operation not allowed\n"
+msgstr "fel: kan inte starta om, åtgärden är inte tillåten\n"
+
+#: debug.c:2942
+#, c-format
+msgid "error (%s): cannot restart, ignoring rest of the commands\n"
+msgstr "fel (%s): kan inte starta om, ignorerar resten av kommandona\n"
+
+#: debug.c:2950
+#, c-format
+msgid "Starting program: \n"
+msgstr "Startar programmet: \n"
+
+#: debug.c:2959
+#, c-format
+msgid "Program exited %s with exit value: %d\n"
+msgstr "Programmet avslutade %s med slutvärde: %d\n"
+
+#: debug.c:2975
+msgid "The program is running. Exit anyway (y/n)? "
+msgstr "Programmet kör. Avsluta ändå (j/n)? "
+
+#: debug.c:3010
+#, c-format
+msgid "Not stopped at any breakpoint; argument ignored.\n"
+msgstr "Inte stoppad vid någon brytpunkt, argumentet ignoreras.\n"
+
+#: debug.c:3015
+#, c-format
+msgid "invalid breakpoint number %d."
+msgstr "ogiltigt brytpunktsnummer %d."
+
+#: debug.c:3020
+#, c-format
+msgid "Will ignore next %ld crossings of breakpoint %d.\n"
+msgstr "Kommer ignorera de nästa %ld passagerna av brytpunkt %d.\n"
+
+#: debug.c:3207
+#, c-format
+msgid "'finish' not meaningful in the outermost frame main()\n"
+msgstr "â€finish†är inte meningsfullt i den yttersta ramen main()\n"
+
+#: debug.c:3212
+#, c-format
+msgid "Run till return from "
+msgstr "Kör till retur från "
+
+#: debug.c:3255
+#, c-format
+msgid "'return' not meaningful in the outermost frame main()\n"
+msgstr "â€return†är inte meningsfullt i den yttersta ramen main()\n"
+
+#: debug.c:3369
+#, c-format
+msgid "Can't find specified location in function `%s'\n"
+msgstr "Kan inte hitta angiven plats i funktionen â€%sâ€\n"
+
+#: debug.c:3377
+#, c-format
+msgid "invalid source line %d in file `%s'"
+msgstr "ogiltig källrad %d i filen â€%sâ€"
+
+#: debug.c:3392
+#, c-format
+msgid "Can't find specified location %d in file `%s'\n"
+msgstr "Kan inte hitta angiven plats %d i filen â€%sâ€\n"
+
+#: debug.c:3424
+#, c-format
+msgid "element not in array\n"
+msgstr "elementet finns inte i vektorn\n"
+
+#: debug.c:3424
+#, c-format
+msgid "untyped variable\n"
+msgstr "otypad variabel\n"
+
+#: debug.c:3466
+#, c-format
+msgid "Stopping in %s ...\n"
+msgstr "Stannar i %s …\n"
+
+#: debug.c:3543
+#, c-format
+msgid "'finish' not meaningful with non-local jump '%s'\n"
+msgstr "â€finish†är inte meningsfullt med icke lokalt hopp â€%sâ€\n"
+
+#: debug.c:3550
+#, c-format
+msgid "'until' not meaningful with non-local jump '%s'\n"
+msgstr "â€until†är inte meningsfullt med icke lokalt hopp â€%sâ€\n"
+
+#: debug.c:4185
+msgid "\t------[Enter] to continue or q [Enter] to quit------"
+msgstr ""
+"\t------[Retur] för att fortsätta eller a [Retur] för att avsluta------"
+
+#: debug.c:4186
+msgid "q"
+msgstr "a"
+
+#: debug.c:5001
+#, c-format
+msgid "[\"%s\"] not in array `%s'"
+msgstr "[\"%s\"] finns inte i vektorn â€%sâ€"
+
+#: debug.c:5207
+#, c-format
+msgid "sending output to stdout\n"
+msgstr "skickar utdata till standard ut\n"
+
+#: debug.c:5247
+msgid "invalid number"
+msgstr "ogiltigt tal"
+
+#: debug.c:5381
+#, c-format
+msgid "`%s' not allowed in current context; statement ignored"
+msgstr "â€%s†är inte tillÃ¥tet i det aktuella sammanhanget; satsen ignoreras"
+
+#: debug.c:5389
+msgid "`return' not allowed in current context; statement ignored"
+msgstr ""
+"â€return†är inte tillÃ¥tet i det aktuella sammanhanget; satsen ignoreras"
+
+#: debug.c:5590
+#, c-format
+msgid "No symbol `%s' in current context"
+msgstr "Ingen symbol â€%s†i aktuell omgivning"
+
+#: dfa.c:1118 dfa.c:1121 dfa.c:1142 dfa.c:1150 dfa.c:1162 dfa.c:1197
+#: dfa.c:1206 dfa.c:1209 dfa.c:1214 dfa.c:1228 dfa.c:1275
+msgid "unbalanced ["
+msgstr "obalanserad ["
+
+#: dfa.c:1174
+msgid "invalid character class"
+msgstr "ogiltig teckenklass"
+
+#: dfa.c:1316
+msgid "character class syntax is [[:space:]], not [:space:]"
+msgstr "syntaxen för teckenklass är [[:space:]], inte [:space:]"
+
+#: dfa.c:1366
+msgid "unfinished \\ escape"
+msgstr "oavslutad \\-följd"
+
+#: dfa.c:1513 regcomp.c:161
+msgid "Invalid content of \\{\\}"
+msgstr "Ogiltigt innehåll i \\{\\}"
+
+#: dfa.c:1516 regcomp.c:176
+msgid "Regular expression too big"
+msgstr "Reguljärt uttryck för stort"
+
+#: dfa.c:1936
+msgid "unbalanced ("
+msgstr "obalanserad ("
+
+#: dfa.c:2062
+msgid "no syntax specified"
+msgstr "ingen syntax angiven"
+
+#: dfa.c:2070
+msgid "unbalanced )"
+msgstr "obalanserad )"
+
+#: eval.c:394
#, c-format
msgid "unknown nodetype %d"
-msgstr "okänd nodtyp %d"
+msgstr "okänd nodtyp %d"
-#: eval.c:423 eval.c:437
+#: eval.c:405 eval.c:419
#, c-format
msgid "unknown opcode %d"
-msgstr "okänd op-kod %d"
+msgstr "okänd op-kod %d"
-#: eval.c:434
+#: eval.c:416
#, c-format
msgid "opcode %s not an operator or keyword"
-msgstr "op-kod %s är inte en operator eller ett nyckelord"
+msgstr "op-kod %s är inte en operator eller ett nyckelord"
-#: eval.c:488
+#: eval.c:472
msgid "buffer overflow in genflags2str"
-msgstr "buffertöverflöd i genflags2str"
+msgstr "buffertöverflöd i genflags2str"
-#: eval.c:698
+#: eval.c:675
#, c-format
msgid ""
"\n"
@@ -996,812 +1872,1234 @@ msgstr ""
"\t# Funktionsanropsstack:\n"
"\n"
-#: eval.c:725
+#: eval.c:704
msgid "`IGNORECASE' is a gawk extension"
-msgstr "\"IGNORECASE\" är en gawk-utökning"
+msgstr "\"IGNORECASE\" är en gawk-utökning"
-#: eval.c:754
+#: eval.c:736
msgid "`BINMODE' is a gawk extension"
-msgstr "\"BINMODE\" är en gawk-utökning"
+msgstr "\"BINMODE\" är en gawk-utökning"
-#: eval.c:812
+#: eval.c:794
#, c-format
msgid "BINMODE value `%s' is invalid, treated as 3"
-msgstr "BINMODE-värde \"%s\" är ogiltigt, behandlas som 3"
+msgstr "BINMODE-värde \"%s\" är ogiltigt, behandlas som 3"
-#: eval.c:902
+#: eval.c:885
#, c-format
msgid "bad `%sFMT' specification `%s'"
msgstr "felaktig \"%sFMT\"-specifikation \"%s\""
-#: eval.c:980
+#: eval.c:969
msgid "turning off `--lint' due to assignment to `LINT'"
-msgstr "slår av \"--lint\" på grund av en tilldelning till \"LINT\""
-
-#: eval.c:1127 eval.c:1777
-#, c-format
-msgid "can't use function name `%s' as variable or array"
-msgstr "kan inte använda funktionsnamnet \"%s\" som variabel eller vektor"
+msgstr "slår av \"--lint\" på grund av en tilldelning till \"LINT\""
-#: eval.c:1158 eval.c:1789 eval.c:1802
+#: eval.c:1147
#, c-format
msgid "reference to uninitialized argument `%s'"
msgstr "referens till icke initierat argument \"%s\""
-#: eval.c:1177
+#: eval.c:1148
+#, c-format
+msgid "reference to uninitialized variable `%s'"
+msgstr "referens till icke initierad variabel \"%s\""
+
+#: eval.c:1166
msgid "attempt to field reference from non-numeric value"
-msgstr "försök att fältreferera från ickenumeriskt värde"
+msgstr "försök att fältreferera från ickenumeriskt värde"
-#: eval.c:1179
+#: eval.c:1168
msgid "attempt to field reference from null string"
-msgstr "försök till fältreferens från en tom sträng"
+msgstr "försök till fältreferens från en tom sträng"
-#: eval.c:1185
+#: eval.c:1176
#, c-format
msgid "attempt to access field %ld"
-msgstr "försök att komma åt fält nummer %ld"
+msgstr "försök att komma åt fält nummer %ld"
-#: eval.c:1194
+#: eval.c:1185
#, c-format
msgid "reference to uninitialized field `$%ld'"
-msgstr "referens till icke initierat fält \"$%ld\""
+msgstr "referens till icke initierat fält \"$%ld\""
-#: eval.c:1256
+#: eval.c:1272
#, c-format
msgid "function `%s' called with more arguments than declared"
-msgstr "funktionen \"%s\" anropad med fler argument än vad som deklarerats"
+msgstr "funktionen \"%s\" anropad med fler argument än vad som deklarerats"
-#: eval.c:1437
+#: eval.c:1473
#, c-format
msgid "unwind_stack: unexpected type `%s'"
-msgstr "unwind_stack: oväntad typ \"%s\""
+msgstr "unwind_stack: oväntad typ \"%s\""
-#: eval.c:1532
+#: eval.c:1569
msgid "division by zero attempted in `/='"
-msgstr "försökte dividera med noll i \"/=\""
+msgstr "försökte dividera med noll i \"/=\""
-#: eval.c:1539
+#: eval.c:1576
#, c-format
msgid "division by zero attempted in `%%='"
-msgstr "försökte dividera med noll i \"%%=\""
+msgstr "försökte dividera med noll i \"%%=\""
-#: eval.c:1876 eval.c:2122
-#, c-format
-msgid "attempt to use array `%s[\"%.*s\"]' in a scalar context"
-msgstr "försök att använda vektorn \"%s[\"%.*s\"]\" i skalärsammanhang"
+#: ext.c:89 ext.c:171
+msgid "extensions are not allowed in sandbox mode"
+msgstr "utökningar är inte tillåtna i sandlådeläge"
-#: eval.c:1907
-msgid "assignment used in conditional context"
-msgstr "tilldelning använt i jämförelsesammanhang"
+#: ext.c:92
+msgid "-l / @load are gawk extensions"
+msgstr "-l / @load är gawk-utökningar"
-#: eval.c:1911
-msgid "statement has no effect"
-msgstr "kommandot har ingen effekt"
+#: ext.c:95
+msgid "load_ext: received NULL lib_name"
+msgstr "load_ext: mottog NULL-lib_name"
-#: eval.c:2343
+#: ext.c:98
#, 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"
+msgid "load_ext: cannot open library `%s' (%s)\n"
+msgstr "load_ext: kan inte öppna biblioteket â€%s†(%s)\n"
-#: eval.c:2458
+#: ext.c:104
#, c-format
-msgid "function called indirectly through `%s' does not exist"
-msgstr "funktionen anropad indirekt genom \"%s\" finns inte"
+msgid ""
+"load_ext: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"
+msgstr ""
+"load_ext: biblioteket â€%sâ€: definierar inte â€plugin_is_GPL_compatible†(%s)\n"
-#: eval.c:2470
+#: ext.c:110
#, c-format
-msgid "function `%s' not defined"
-msgstr "funktionen \"%s\" är inte definierad"
+msgid "load_ext: library `%s': cannot call function `%s' (%s)\n"
+msgstr "load_ext: biblioteket â€%sâ€: kan inte anropa funktionen â€%s†(%s)\n"
-#: eval.c:2511
+#: ext.c:114
#, c-format
-msgid "non-redirected `getline' invalid inside `%s' rule"
-msgstr "icke omdirigerad \"getline\" odefinierad inuti \"%s\"-regel"
+msgid "load_ext: library `%s' initialization routine `%s' failed\n"
+msgstr ""
+"load_ext: initieringsrutinen â€%2$s†i biblioteket â€%1$s†misslyckades\n"
-#: eval.c:2600
-#, c-format
-msgid "error reading input file `%s': %s"
-msgstr "fel vid läsning av indatafilen \"%s\": %s"
+#: ext.c:174
+msgid "`extension' is a gawk extension"
+msgstr "\"extension\" är en gawk-utökning"
+
+#: ext.c:177
+msgid "extension: received NULL lib_name"
+msgstr "utökning: mottog NULL-lib_name"
-#: eval.c:2614
+#: ext.c:180
#, c-format
-msgid "`nextfile' cannot be called from a `%s' rule"
-msgstr "\"nextfile\" kan inte anropas från en \"%s\"-regel"
+msgid "extension: cannot open library `%s' (%s)"
+msgstr "extension: kan inte öppna biblioteket â€%s†(%s)"
-#: eval.c:2694
+#: ext.c:186
#, c-format
-msgid "`next' cannot be called from a `%s' rule"
-msgstr "\"next\" kan inte anropas från en \"%s\"-regel"
+msgid ""
+"extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)"
+msgstr ""
+"extension: biblioteket â€%sâ€: definierar inte â€plugin_is_GPL_compatible†(%s)"
-#: eval.c:2760
+#: ext.c:190
#, c-format
-msgid "Sorry, don't know how to interpret `%s'"
-msgstr "Tyvärr, vet inte hur \"%s\" skall tolkas"
+msgid "extension: library `%s': cannot call function `%s' (%s)"
+msgstr "extension: biblioteket â€%sâ€: kan inte anropa funktionen â€%s†(%s)"
-#: ext.c:64
-msgid "extensions are not allowed in sandbox mode"
-msgstr "utökningar är inte tillåtna i sandlådeläge"
+#: ext.c:221
+msgid "make_builtin: missing function name"
+msgstr "make_builtin: funktionsnamn saknas"
-#: ext.c:70 ext.c:75
-msgid "`extension' is a gawk extension"
-msgstr "\"extension\" är en gawk-utökning"
+#: ext.c:236
+#, c-format
+msgid "make_builtin: can't redefine function `%s'"
+msgstr "make_builtin: det gÃ¥r inte att definiera om funktionen â€%sâ€"
-#: ext.c:85
+#: ext.c:240
#, c-format
-msgid "fatal: extension: cannot open `%s' (%s)\n"
-msgstr "ödesdigert: extension: kan inte öppna \"%s\" (%s)\n"
+msgid "make_builtin: function `%s' already defined"
+msgstr "make_builtin: funktionen â€%s†är redan definierad"
-#: ext.c:94
+#: ext.c:244
#, c-format
-msgid ""
-"fatal: extension: library `%s': does not define "
-"`plugin_is_GPL_compatible' (%s)\n"
-msgstr ""
-"ödesdigert: extension: biblioteket \"%s\": definierar inte "
-"\"plugin_is_GPL_compatible\" (%s)\n"
+msgid "make_builtin: function name `%s' previously defined"
+msgstr "make_builtin: funktionsnamnet â€%s†är definierat sedan tidigare"
-#: ext.c:103
+#: ext.c:246
#, c-format
-msgid "fatal: extension: library `%s': cannot call function `%s' (%s)\n"
+msgid "make_builtin: can't use gawk built-in `%s' as function name"
msgstr ""
-"ödesdigert: extension: bibliotek \"%s\": kan inte anropa funktionen \"%s"
-"\" (%s)\n"
+"make_builtin: kan inte använda gawks inbyggda â€%s†som ett funktionsnamn"
-#: ext.c:137
+#: ext.c:249 ext.c:304
+#, c-format
+msgid "make_builtin: negative argument count for function `%s'"
+msgstr "make_builtin: negativt argumentantal för funktionen \"%s\""
+
+#: ext.c:276
msgid "extension: missing function name"
msgstr "extension: saknar funktionsnamn"
-#: ext.c:142
+#: ext.c:279 ext.c:283
#, c-format
msgid "extension: illegal character `%c' in function name `%s'"
msgstr "extension: ogiltigt tecken \"%c\" i funktionsnamnet \"%s\""
-#: ext.c:151
+#: ext.c:291
#, c-format
msgid "extension: can't redefine function `%s'"
-msgstr "extension: det går inte att definiera om funktionen \"%s\""
+msgstr "extension: det går inte att definiera om funktionen \"%s\""
-#: ext.c:155
+#: ext.c:295
#, c-format
msgid "extension: function `%s' already defined"
-msgstr "extension: funktionen \"%s\" är redan definierad"
+msgstr "extension: funktionen \"%s\" är redan definierad"
-#: ext.c:160
+#: ext.c:299
#, c-format
msgid "extension: function name `%s' previously defined"
-msgstr "extension: funktionsnamnet \"%s\" är definierat sedan tidigare"
+msgstr "extension: funktionsnamnet \"%s\" är definierat sedan tidigare"
-#: ext.c:162
+#: ext.c:301
#, c-format
msgid "extension: can't use gawk built-in `%s' as function name"
msgstr ""
-"extension: kan inte använda gawks inbyggda \"%s\" som ett funktionsnamn"
-
-#: ext.c:166
-#, c-format
-msgid "make_builtin: negative argument count for function `%s'"
-msgstr "make_builtin: negativt argumentantal för funktionen \"%s\""
+"extension: kan inte använda gawks inbyggda \"%s\" som ett funktionsnamn"
-#: ext.c:269
+#: ext.c:375
#, c-format
msgid "function `%s' defined to take no more than %d argument(s)"
-msgstr "funktionen \"%s\" definierades för att ta maximalt %d argument"
+msgstr "funktionen \"%s\" definierades för att ta maximalt %d argument"
-#: ext.c:272
+#: ext.c:378
#, c-format
msgid "function `%s': missing argument #%d"
msgstr "funktionen \"%s\": argument %d saknas"
-#: ext.c:289
+#: ext.c:395
#, c-format
msgid "function `%s': argument #%d: attempt to use scalar as an array"
-msgstr "funktionen \"%s\": argument %d: försök att använda skalär som vektor"
+msgstr "funktionen \"%s\": argument %d: försök att använda skalär som vektor"
-#: ext.c:293
+#: ext.c:399
#, c-format
msgid "function `%s': argument #%d: attempt to use array as a scalar"
-msgstr "funktionen \"%s\": argument %d: försök att använda vektor som skalär"
+msgstr "funktionen \"%s\": argument %d: försök att använda vektor som skalär"
+
+#: ext.c:413
+msgid "dynamic loading of library not supported"
+msgstr "dynamisk laddning av bibliotek stödjs inte"
+
+#: extension/filefuncs.c:159
+msgid "chdir: called with incorrect number of arguments, expecting 1"
+msgstr "chdir: anropad med felaktigt antal argument, förväntade 1"
+
+#: extension/filefuncs.c:439
+#, c-format
+msgid "stat: unable to read symbolic link `%s'"
+msgstr "stat: kan inte läsa den symboliska länken â€%sâ€"
+
+#: extension/filefuncs.c:472
+msgid "stat: called with wrong number of arguments"
+msgstr "stat: anropad med fel antal argument"
+
+#: extension/filefuncs.c:479
+msgid "stat: bad parameters"
+msgstr "stat: felaktiga parametrar"
+
+#: extension/filefuncs.c:533
+#, c-format
+msgid "fts init: could not create variable %s"
+msgstr "fts init: kunde inte skapa variabeln %s"
+
+#: extension/filefuncs.c:554
+msgid "fts is not supported on this system"
+msgstr "fts stödjs inte på detta system"
+
+#: extension/filefuncs.c:573
+msgid "fill_stat_element: could not create array"
+msgstr "fill_stat_element: kunde inte skapa en vektor"
+
+#: extension/filefuncs.c:582
+msgid "fill_stat_element: could not set element"
+msgstr "fill_stat_element: kunde inte sätta ett element"
+
+#: extension/filefuncs.c:597
+msgid "fill_path_element: could not set element"
+msgstr "fill_path_element: kunde inte sätta ett element"
+
+#: extension/filefuncs.c:613
+msgid "fill_error_element: could not set element"
+msgstr "fill_error_element: kunde inte sätta ett element"
+
+#: extension/filefuncs.c:660 extension/filefuncs.c:707
+msgid "fts-process: could not create array"
+msgstr "fts-process: kunde inte skapa en vektor"
+
+#: extension/filefuncs.c:670 extension/filefuncs.c:717
+#: extension/filefuncs.c:735
+msgid "fts-process: could not set element"
+msgstr "fts-process: kunde inte sätta ett element"
+
+#: extension/filefuncs.c:784
+msgid "fts: called with incorrect number of arguments, expecting 3"
+msgstr "fts: anropad med felaktigt antal argument, förväntade 3"
+
+#: extension/filefuncs.c:787
+msgid "fts: bad first parameter"
+msgstr "fts: felaktig första parameter"
+
+#: extension/filefuncs.c:793
+msgid "fts: bad second parameter"
+msgstr "fts: felaktig andra parameter"
+
+#: extension/filefuncs.c:799
+msgid "fts: bad third parameter"
+msgstr "fts: felaktig tredje parameter"
+
+#: extension/filefuncs.c:806
+msgid "fts: could not flatten array\n"
+msgstr "fts: kunde inte platta till en vektor\n"
+
+#: extension/filefuncs.c:824
+msgid "fts: ignoring sneaky FTS_NOSTAT flag. nyah, nyah, nyah."
+msgstr "fts: ignorerar lömsk FTS_NOSTAT-flagga, nä, nä, nä."
+
+#: extension/filefuncs.c:841
+msgid "fts: clear_array() failed\n"
+msgstr "fts: clear_array() misslyckades\n"
+
+#: extension/fnmatch.c:112
+msgid "fnmatch: called with less than three arguments"
+msgstr "fnmatch: anropad färre an tre argument"
+
+#: extension/fnmatch.c:115
+msgid "fnmatch: called with more than three arguments"
+msgstr "fnmatch: anropad med mer än tre argument"
+
+#: extension/fnmatch.c:118
+msgid "fnmatch: could not get first argument"
+msgstr "fnmatch: kunde inte hämta första argumentet"
+
+#: extension/fnmatch.c:123
+msgid "fnmatch: could not get second argument"
+msgstr "fnmatch: kunde inte hämta andra argumentet"
+
+#: extension/fnmatch.c:128
+msgid "fnmatch: could not get third argument"
+msgstr "fnmatch: kunde inte hämta ett tredje argument"
+
+#: extension/fnmatch.c:141
+msgid "fnmatch is not implemented on this system\n"
+msgstr "fnmatch är inte implementerat på detta system\n"
+
+#: extension/fnmatch.c:173
+msgid "fnmatch init: could not add FNM_NOMATCH variable"
+msgstr "fnmatch init: kunde inte lägga till en FNM_NOMATCH-variabel"
+
+#: extension/fnmatch.c:183
+#, c-format
+msgid "fnmatch init: could not set array element %s"
+msgstr "fnmatch init: kunde inte sätta vektorelement %s"
-#: ext.c:306
-msgid "Operation Not Supported"
-msgstr "Operationen stöds inte"
+#: extension/fnmatch.c:193
+msgid "fnmatch init: could not install FNM array"
+msgstr "fnmatch init: kunde inte installera en FNM-vektor"
-#: field.c:328
+#: extension/fork.c:81
+msgid "fork: called with too many arguments"
+msgstr "fork: anropad med för många argument"
+
+#: extension/fork.c:94
+msgid "fork: PROCINFO is not an array!"
+msgstr "fork: PROCINFO är inte en vektor!"
+
+#: extension/fork.c:118
+msgid "waitpid: called with too many arguments"
+msgstr "waitpid: anropad med för många argument"
+
+#: extension/fork.c:126
+msgid "wait: called with no arguments"
+msgstr "wait: anropad utan argument"
+
+#: extension/fork.c:143
+msgid "wait: called with too many arguments"
+msgstr "wait: anropad med för många argument"
+
+#: extension/inplace.c:130
+msgid "inplace_begin: in-place editing already active"
+msgstr "inplace_begin: redigering på plats är redan aktivt"
+
+#: extension/inplace.c:133 extension/inplace.c:207
+#, c-format
+msgid "inplace_begin: expects 2 arguments but called with %d"
+msgstr "inplace_begin: förväntar sig 2 argument men anropad med %d"
+
+#: extension/inplace.c:136
+msgid "inplace_begin: cannot retrieve 1st argument as a string filename"
+msgstr "inplace_begin: kan inte hämta 1:a argumentet som en filnamnssträng"
+
+#: extension/inplace.c:144
+#, c-format
+msgid "inplace_begin: disabling in-place editing for invalid FILENAME `%s'"
+msgstr ""
+"inplace_begin: avaktiverar redigering pÃ¥ plats för ogiltigt FILNAMN â€%sâ€"
+
+#: extension/inplace.c:151
+#, c-format
+msgid "inplace_begin: Cannot stat `%s' (%s)"
+msgstr "inplace_begin: kan inte ta status pÃ¥ â€%s†(%s)"
+
+#: extension/inplace.c:158
+#, c-format
+msgid "inplace_begin: `%s' is not a regular file"
+msgstr "inplace_begin: â€%s†är inte en vanlig fil"
+
+#: extension/inplace.c:169
+#, c-format
+msgid "inplace_begin: mkstemp(`%s') failed (%s)"
+msgstr "inplace_begin: mkstemp(â€%sâ€) misslyckades (%s)"
+
+#: extension/inplace.c:178
+#, c-format
+msgid "inplace_begin: chmod failed (%s)"
+msgstr "inplace_begin: chmod misslyckades (%s)"
+
+#: extension/inplace.c:185
+#, c-format
+msgid "inplace_begin: dup(stdout) failed (%s)"
+msgstr "inplace_begin: dup(standard ut) misslyckades (%s)"
+
+#: extension/inplace.c:188
+#, c-format
+msgid "inplace_begin: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_begin: dup2(%d, standard ut) misslyckades (%s)"
+
+#: extension/inplace.c:191
+#, c-format
+msgid "inplace_begin: close(%d) failed (%s)"
+msgstr "inplace_begin: close(%d) misslyckades (%s)"
+
+#: extension/inplace.c:210
+msgid "inplace_end: cannot retrieve 1st argument as a string filename"
+msgstr "inplace_end: kan inte hämta 1:a argumentet som en filnamnssträng"
+
+#: extension/inplace.c:217
+msgid "inplace_end: in-place editing not active"
+msgstr "inplace_end: redigering på plats är inte aktivt"
+
+#: extension/inplace.c:223
+#, c-format
+msgid "inplace_end: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_end: dup2(%d, standard ut) misslyckades (%s)"
+
+#: extension/inplace.c:226
+#, c-format
+msgid "inplace_end: close(%d) failed (%s)"
+msgstr "inplace_end: close(%d) misslyckades (%s)"
+
+#: extension/inplace.c:230
+#, c-format
+msgid "inplace_end: fsetpos(stdout) failed (%s)"
+msgstr "inplace_end: fsetpos(standard ut) misslyckades (%s)"
+
+#: extension/inplace.c:243
+#, c-format
+msgid "inplace_end: link(`%s', `%s') failed (%s)"
+msgstr "inplace_end: link(â€%sâ€, â€%sâ€) misslyckades (%s)"
+
+#: extension/inplace.c:253
+#, c-format
+msgid "inplace_end: rename(`%s', `%s') failed (%s)"
+msgstr "inplace_end: rename(â€%sâ€, â€%sâ€) misslyckades (%s)"
+
+#: extension/ordchr.c:69
+msgid "ord: called with too many arguments"
+msgstr "ord: anropad med för många argument"
+
+#: extension/ordchr.c:75
+msgid "ord: called with no arguments"
+msgstr "ord: anropad utan argument"
+
+#: extension/ordchr.c:77
+msgid "ord: called with inappropriate argument(s)"
+msgstr "ord: anropad med felaktiga argument"
+
+#: extension/ordchr.c:99
+msgid "chr: called with too many arguments"
+msgstr "chr: anropad med för många argument"
+
+#: extension/ordchr.c:109
+msgid "chr: called with no arguments"
+msgstr "chr: anropad utan argument"
+
+#: extension/ordchr.c:111
+msgid "chr: called with inappropriate argument(s)"
+msgstr "chr: anropad med felaktiga argument"
+
+#: extension/readdir.c:281
+#, c-format
+msgid "dir_take_control_of: opendir/fdopendir failed: %s"
+msgstr "dir_take_control_of: opendir/fdopendir misslyckades: %s"
+
+#: extension/readfile.c:113
+msgid "readfile: called with too many arguments"
+msgstr "readfile: anropad med för många argument"
+
+#: extension/readfile.c:137
+msgid "readfile: called with no arguments"
+msgstr "readfile: anropad utan argument"
+
+#: extension/rwarray.c:124
+msgid "writea: called with too many arguments"
+msgstr "writea: anropad med för många argument"
+
+#: extension/rwarray.c:131
+#, c-format
+msgid "do_writea: argument 0 is not a string\n"
+msgstr "do_writea: argument 0 är inte en sträng\n"
+
+#: extension/rwarray.c:137
+#, c-format
+msgid "do_writea: argument 1 is not an array\n"
+msgstr "do_writea: argument 1 är inte en vektor\n"
+
+#: extension/rwarray.c:184
+#, c-format
+msgid "write_array: could not flatten array\n"
+msgstr "write_array: kunde inte platta till vektor\n"
+
+#: extension/rwarray.c:198
+#, c-format
+msgid "write_array: could not release flattened array\n"
+msgstr "write_array: kunde inte släppa en tillplattad vektor\n"
+
+#: extension/rwarray.c:280
+msgid "reada: called with too many arguments"
+msgstr "reada: anropad med för många argument"
+
+#: extension/rwarray.c:287
+#, c-format
+msgid "do_reada: argument 0 is not a string\n"
+msgstr "do_reada: argument 0 är inte en sträng\n"
+
+#: extension/rwarray.c:293
+#, c-format
+msgid "do_reada: argument 1 is not an array\n"
+msgstr "do_reada: argument 1 är inte en vektor\n"
+
+#: extension/rwarray.c:337
+#, c-format
+msgid "do_reada: clear_array failed\n"
+msgstr "do_reada: clear_array misslyckades\n"
+
+#: extension/rwarray.c:374
+#, c-format
+msgid "read_array: set_array_element failed\n"
+msgstr "read_array: set_array_element misslyckades\n"
+
+#: extension/time.c:113
+msgid "gettimeofday: ignoring arguments"
+msgstr "gettimeofday: ignorerar argumenten"
+
+#: extension/time.c:144
+msgid "gettimeofday: not supported on this platform"
+msgstr "gettimeofday: stödjs inte på denna plattform"
+
+#: extension/time.c:165
+msgid "sleep: called with too many arguments"
+msgstr "sleep: anropad med för många argument"
+
+#: extension/time.c:168
+msgid "sleep: missing required numeric argument"
+msgstr "sleep: nödvändigt numeriskt argument saknas"
+
+#: extension/time.c:174
+msgid "sleep: argument is negative"
+msgstr "sleep: argumentet är negativt"
+
+#: extension/time.c:208
+msgid "sleep: not supported on this platform"
+msgstr "sleep: stödjs inte på denna plattform"
+
+#: field.c:345
msgid "NF set to negative value"
-msgstr "NF satt till ett negativt värde"
+msgstr "NF satt till ett negativt värde"
-#: field.c:951 field.c:958 field.c:962
+#: field.c:971 field.c:978 field.c:982
msgid "split: fourth argument is a gawk extension"
-msgstr "split: fjärde argumentet är en gawk-utökning"
+msgstr "split: fjärde argumentet är en gawk-utökning"
-#: field.c:955
+#: field.c:975
msgid "split: fourth argument is not an array"
-msgstr "split: fjärde argumentet är inte en vektor"
+msgstr "split: fjärde argumentet är inte en vektor"
-#: field.c:969
+#: field.c:989
msgid "split: second argument is not an array"
-msgstr "split: andra argumentet är inte en vektor"
+msgstr "split: andra argumentet är inte en vektor"
-#: field.c:973
+#: field.c:993
msgid "split: cannot use the same array for second and fourth args"
msgstr ""
-"split: det går inte att använda samma vektor som andra och fjärde argument"
+"split: det går inte att använda samma vektor som andra och fjärde argument"
-#: field.c:978
+#: field.c:998
msgid "split: cannot use a subarray of second arg for fourth arg"
msgstr ""
-"split: det går inte att använda en delvektor av andra argumentet som fjärde "
+"split: det går inte att använda en delvektor av andra argumentet som fjärde "
"argument"
-#: field.c:981
+#: field.c:1001
msgid "split: cannot use a subarray of fourth arg for second arg"
msgstr ""
-"split: det går inte att använda en delvektor av fjärde argumentet som andra "
+"split: det går inte att använda en delvektor av fjärde argumentet som andra "
"argument"
-#: field.c:1010
+#: field.c:1032
msgid "split: null string for third arg is a gawk extension"
-msgstr "split: tom sträng som tredje argument är en gawk-utökning"
+msgstr "split: tom sträng som tredje argument är en gawk-utökning"
-#: field.c:1050
+#: field.c:1072
msgid "patsplit: fourth argument is not an array"
-msgstr "patsplit: fjärde argumentet är inte en vektor"
+msgstr "patsplit: fjärde argumentet är inte en vektor"
-#: field.c:1055
+#: field.c:1077
msgid "patsplit: second argument is not an array"
-msgstr "patsplit: andra argumentet är inte en vektor"
+msgstr "patsplit: andra argumentet är inte en vektor"
-#: field.c:1061
+#: field.c:1083
msgid "patsplit: third argument must be non-null"
-msgstr "patsplit: tredje argumentet får inte vara tomt"
+msgstr "patsplit: tredje argumentet får inte vara tomt"
-#: field.c:1065
+#: field.c:1087
msgid "patsplit: cannot use the same array for second and fourth args"
msgstr ""
-"patsplit: det går inte att använda samma vektor som andra och fjärde argument"
+"patsplit: det går inte att använda samma vektor som andra och fjärde argument"
-#: field.c:1070
+#: field.c:1092
msgid "patsplit: cannot use a subarray of second arg for fourth arg"
msgstr ""
-"patsplit: det går inte att använda en delvektor av andra argumentet som "
-"fjärde argument"
+"patsplit: det går inte att använda en delvektor av andra argumentet som "
+"fjärde argument"
-#: field.c:1073
+#: field.c:1095
msgid "patsplit: cannot use a subarray of fourth arg for second arg"
msgstr ""
-"patsplit: det går inte att använda en delvektor av fjärde argumentet som "
+"patsplit: det går inte att använda en delvektor av fjärde argumentet som "
"andra argument"
-#: field.c:1110
+#: field.c:1133
msgid "`FIELDWIDTHS' is a gawk extension"
-msgstr "\"FIELDWIDTHS\" är en gawk-utökning"
+msgstr "\"FIELDWIDTHS\" är en gawk-utökning"
-#: field.c:1173
+#: field.c:1197
#, c-format
msgid "invalid FIELDWIDTHS value, near `%s'"
-msgstr "ogiltigt FIELDWITHS-värde i närheten av \"%s\""
+msgstr "ogiltigt FIELDWITHS-värde i närheten av \"%s\""
-#: field.c:1246
+#: field.c:1270
msgid "null string for `FS' is a gawk extension"
-msgstr "tom sträng som \"FS\" är en gawk-utökning"
+msgstr "tom sträng som \"FS\" är en gawk-utökning"
-#: field.c:1250
+#: field.c:1274
msgid "old awk does not support regexps as value of `FS'"
-msgstr "gamla awk stöder inte reguljära uttryck som värden på \"FS\""
+msgstr "gamla awk stöder inte reguljära uttryck som värden på \"FS\""
-#: field.c:1369
+#: field.c:1393
msgid "`FPAT' is a gawk extension"
-msgstr "\"FPAT\" är en gawk-utökning"
+msgstr "\"FPAT\" är en gawk-utökning"
+
+#: gawkapi.c:146
+msgid "awk_value_to_node: received null retval"
+msgstr "awk_value_to_node: mottog null-returvärde"
+
+#: gawkapi.c:384
+msgid "node_to_awk_value: received null node"
+msgstr "node_to_awk_value: mottog null-nod"
+
+#: gawkapi.c:387
+msgid "node_to_awk_value: received null val"
+msgstr "node_to_awk_value: mottog null-värde"
-#: getopt.c:574 getopt.c:590
+#: gawkapi.c:807
+msgid "remove_element: received null array"
+msgstr "remove_element: fick en null-vektor"
+
+#: gawkapi.c:810
+msgid "remove_element: received null subscript"
+msgstr "remove_element: mottog null-index"
+
+#: gawkapi.c:947
+#, c-format
+msgid "api_flatten_array: could not convert index %d\n"
+msgstr "api_flatten_array: kunde inte konvertera index %d\n"
+
+#: gawkapi.c:952
+#, c-format
+msgid "api_flatten_array: could not convert value %d\n"
+msgstr "api_flatten_array: kunde inte konvertera värdet %d\n"
+
+#: getopt.c:604 getopt.c:633
#, c-format
-msgid "%s: option '%s' is ambiguous\n"
-msgstr "%s: flaggan \"%s\" är tvetydig\n"
+msgid "%s: option '%s' is ambiguous; possibilities:"
+msgstr "%s: flaggan â€%s†är tvetydig; möjligheter:"
-#: getopt.c:623 getopt.c:627
+#: getopt.c:679 getopt.c:683
#, c-format
msgid "%s: option '--%s' doesn't allow an argument\n"
-msgstr "%s: flaggan \"--%s\" tillåter inte något argument\n"
+msgstr "%s: flaggan \"--%s\" tillåter inte något argument\n"
-#: getopt.c:636 getopt.c:641
+#: getopt.c:692 getopt.c:697
#, c-format
msgid "%s: option '%c%s' doesn't allow an argument\n"
-msgstr "%s: flaggan \"%c%s\" tillåter inte något argument\n"
+msgstr "%s: flaggan \"%c%s\" tillåter inte något argument\n"
-#: getopt.c:684 getopt.c:703
+#: getopt.c:740 getopt.c:759
#, c-format
msgid "%s: option '--%s' requires an argument\n"
-msgstr "%s: flaggan \"%s\" kräver ett argument\n"
+msgstr "%s: flaggan \"%s\" kräver ett argument\n"
-#: getopt.c:741 getopt.c:744
+#: getopt.c:797 getopt.c:800
#, c-format
msgid "%s: unrecognized option '--%s'\n"
-msgstr "%s: okänd flagga \"--%s\"\n"
+msgstr "%s: okänd flagga \"--%s\"\n"
-#: getopt.c:752 getopt.c:755
+#: getopt.c:808 getopt.c:811
#, c-format
msgid "%s: unrecognized option '%c%s'\n"
-msgstr "%s: okänd flagga \"%c%s\"\n"
+msgstr "%s: okänd flagga \"%c%s\"\n"
-#: getopt.c:804 getopt.c:807
+#: getopt.c:860 getopt.c:863
#, c-format
msgid "%s: invalid option -- '%c'\n"
msgstr "%s: ogiltig flagga -- \"%c\"\n"
-#: getopt.c:857 getopt.c:874 getopt.c:1082 getopt.c:1100
+#: getopt.c:916 getopt.c:933 getopt.c:1143 getopt.c:1161
#, c-format
msgid "%s: option requires an argument -- '%c'\n"
-msgstr "%s: flaggan kräver ett argument -- \"%c\"\n"
+msgstr "%s: flaggan kräver ett argument -- \"%c\"\n"
-#: getopt.c:930 getopt.c:946
+#: getopt.c:989 getopt.c:1005
#, c-format
msgid "%s: option '-W %s' is ambiguous\n"
-msgstr "%s: flaggan \"-W %s\" är tvetydig\n"
+msgstr "%s: flaggan \"-W %s\" är tvetydig\n"
-#: getopt.c:970 getopt.c:988
+#: getopt.c:1029 getopt.c:1047
#, 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"
+msgstr "%s: flaggan \"-W %s\" tillåter inte något argument\n"
-#: getopt.c:1009 getopt.c:1027
+#: getopt.c:1068 getopt.c:1086
#, c-format
msgid "%s: option '-W %s' requires an argument\n"
-msgstr "%s: flaggan \"-W %s\" kräver ett argument\n"
+msgstr "%s: flaggan \"-W %s\" kräver ett argument\n"
-#: io.c:280
+#: io.c:392
#, c-format
msgid "command line argument `%s' is a directory: skipped"
-msgstr "kommandoradsargumentet \"%s\" är en katalog: hoppas över"
+msgstr "kommandoradsargumentet \"%s\" är en katalog: hoppas över"
-#: io.c:283 io.c:385
+#: io.c:395 io.c:513
#, c-format
msgid "cannot open file `%s' for reading (%s)"
-msgstr "kan inte öppna filen \"%s\" för läsning (%s)"
+msgstr "kan inte öppna filen \"%s\" för läsning (%s)"
-#: io.c:501
+#: io.c:640
#, c-format
msgid "close of fd %d (`%s') failed (%s)"
-msgstr "stängning av fd %d (\"%s\") misslyckades (%s)"
+msgstr "stängning av fd %d (\"%s\") misslyckades (%s)"
-#: io.c:578
+#: io.c:716
msgid "redirection not allowed in sandbox mode"
-msgstr "omdirigering är inte tillåten i sandlådeläge"
+msgstr "omdirigering är inte tillåten i sandlådeläge"
-#: io.c:612
+#: io.c:750
#, c-format
msgid "expression in `%s' redirection only has numeric value"
-msgstr "uttrycket i \"%s\"-omdirigering har bara numeriskt värde"
+msgstr "uttrycket i \"%s\"-omdirigering har bara numeriskt värde"
-#: io.c:618
+#: io.c:756
#, 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"
+msgstr "uttrycket för \"%s\"-omdirigering har en tom sträng som värde"
-#: io.c:624
+#: io.c:761
#, 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 "
+"filnamnet \"%s\" för \"%s\"-omdirigering kan vara resultatet av ett logiskt "
"uttryck"
-#: io.c:667
+#: io.c:809
#, c-format
msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
-msgstr "onödig blandning av \">\" och \">>\" för filen \"%.*s\""
+msgstr "onödig blandning av \">\" och \">>\" för filen \"%.*s\""
-#: io.c:720
+#: io.c:863
#, c-format
msgid "can't open pipe `%s' for output (%s)"
-msgstr "kan inte öppna röret \"%s\" för utmatning (%s)"
+msgstr "kan inte öppna röret \"%s\" för utmatning (%s)"
-#: io.c:730
+#: io.c:873
#, c-format
msgid "can't open pipe `%s' for input (%s)"
-msgstr "kan inte öppna röret \"%s\" för inmatning (%s)"
+msgstr "kan inte öppna röret \"%s\" för inmatning (%s)"
-#: io.c:753
+#: io.c:904
#, 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)"
+msgstr "kan inte öppna tvåvägsröret \"%s\" för in-/utmatning (%s)"
-#: io.c:835
+#: io.c:986
#, c-format
msgid "can't redirect from `%s' (%s)"
-msgstr "kan inte dirigera om från \"%s\" (%s)"
+msgstr "kan inte dirigera om från \"%s\" (%s)"
-#: io.c:838
+#: io.c:989
#, c-format
msgid "can't redirect to `%s' (%s)"
msgstr "kan inte dirigera om till \"%s\" (%s)"
-#: io.c:889
+#: io.c:1040
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"
+"nådde systembegränsningen för öppna filer: börjar multiplexa fildeskriptorer"
-#: io.c:905
+#: io.c:1056
#, c-format
msgid "close of `%s' failed (%s)."
-msgstr "stängning av \"%s\" misslyckades (%s)"
+msgstr "stängning av \"%s\" misslyckades (%s)"
-#: io.c:913
+#: io.c:1064
msgid "too many pipes or input files open"
-msgstr "för många rör eller indatafiler öppna"
+msgstr "för många rör eller indatafiler öppna"
-#: io.c:935
+#: io.c:1086
msgid "close: second argument must be `to' or `from'"
-msgstr "close: andra argumentet måste vara \"to\" eller \"from\""
+msgstr "close: andra argumentet måste vara \"to\" eller \"from\""
-#: io.c:952
+#: io.c:1103
#, 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"
+msgstr "close: \"%.*s\" är inte en öppen fil, rör eller koprocess"
-#: io.c:957
+#: io.c:1108
msgid "close of redirection that was never opened"
-msgstr "stängning av omdirigering som aldrig öppnades"
+msgstr "stängning av omdirigering som aldrig öppnades"
-#: io.c:1054
+#: io.c:1205
#, c-format
msgid "close: redirection `%s' not opened with `|&', second argument ignored"
msgstr ""
-"close: omdirigeringen \"%s\" öppnades inte med \"|&\", andra argumentet "
+"close: omdirigeringen \"%s\" öppnades inte med \"|&\", andra argumentet "
"ignorerat"
-#: io.c:1070
+#: io.c:1222
#, c-format
msgid "failure status (%d) on pipe close of `%s' (%s)"
-msgstr "felstatus (%d) från rörstängning av \"%s\" (%s)"
+msgstr "felstatus (%d) från rörstängning av \"%s\" (%s)"
-#: io.c:1073
+#: io.c:1225
#, c-format
msgid "failure status (%d) on file close of `%s' (%s)"
-msgstr "felstatus (%d) från filstängning av \"%s\" (%s)"
+msgstr "felstatus (%d) från filstängning av \"%s\" (%s)"
-#: io.c:1093
+#: io.c:1245
#, c-format
msgid "no explicit close of socket `%s' provided"
-msgstr "ingen explicit stängning av uttaget \"%s\" tillhandahållen"
+msgstr "ingen explicit stängning av uttaget \"%s\" tillhandahållen"
-#: io.c:1096
+#: io.c:1248
#, c-format
msgid "no explicit close of co-process `%s' provided"
-msgstr "ingen explicit stängning av koprocessen \"%s\" tillhandahållen"
+msgstr "ingen explicit stängning av koprocessen \"%s\" tillhandahållen"
-#: io.c:1099
+#: io.c:1251
#, c-format
msgid "no explicit close of pipe `%s' provided"
-msgstr "ingen explicit stängning av röret \"%s\" tillhandahållen"
+msgstr "ingen explicit stängning av röret \"%s\" tillhandahållen"
-#: io.c:1102
+#: io.c:1254
#, c-format
msgid "no explicit close of file `%s' provided"
-msgstr "ingen explicit stängning av filen \"%s\" tillhandahållen"
+msgstr "ingen explicit stängning av filen \"%s\" tillhandahållen"
-#: io.c:1130 io.c:1185 main.c:793 main.c:830
+#: io.c:1284 io.c:1342 main.c:864 main.c:906
#, c-format
msgid "error writing standard output (%s)"
msgstr "fel vid skrivning till standard ut (%s)"
-#: io.c:1134 io.c:1190
+#: io.c:1289 io.c:1348 main.c:866
#, c-format
msgid "error writing standard error (%s)"
msgstr "fel vid skrivning till standard fel (%s)"
-#: io.c:1142
+#: io.c:1297
#, c-format
msgid "pipe flush of `%s' failed (%s)."
-msgstr "rörspolning av \"%s\" misslyckades (%s)"
+msgstr "rörspolning av \"%s\" misslyckades (%s)"
-#: io.c:1145
+#: io.c:1300
#, c-format
msgid "co-process flush of pipe to `%s' failed (%s)."
-msgstr "koprocesspolning av röret till \"%s\" misslyckades (%s)"
+msgstr "koprocesspolning av röret till \"%s\" misslyckades (%s)"
-#: io.c:1148
+#: io.c:1303
#, c-format
msgid "file flush of `%s' failed (%s)."
msgstr "filspolning av \"%s\" misslyckades (%s)"
-#: io.c:1263
+#: io.c:1420
#, c-format
msgid "local port %s invalid in `/inet'"
msgstr "lokal port %s ogiltig i \"/inet\""
-#: io.c:1280
+#: io.c:1438
#, c-format
msgid "remote host and port information (%s, %s) invalid"
-msgstr "ogiltig information (%s, %s) för fjärrvärd och fjärrport"
+msgstr "ogiltig information (%s, %s) för fjärrvärd och fjärrport"
-#: io.c:1432
+#: io.c:1590
#, c-format
msgid "no (known) protocol supplied in special filename `%s'"
msgstr ""
-"inget (känt) protokoll tillhandahållet i det speciella filnamnet \"%s\""
+"inget (känt) protokoll tillhandahållet i det speciella filnamnet \"%s\""
-#: io.c:1446
+#: io.c:1604
#, c-format
msgid "special file name `%s' is incomplete"
-msgstr "speciellt filnamn \"%s\" är ofullständigt"
+msgstr "speciellt filnamn \"%s\" är ofullständigt"
-#: io.c:1463
+#: io.c:1621
msgid "must supply a remote hostname to `/inet'"
-msgstr "måste tillhandahålla ett fjärrdatornamn till \"/inet\""
+msgstr "måste tillhandahålla ett fjärrdatornamn till \"/inet\""
-#: io.c:1481
+#: io.c:1639
msgid "must supply a remote port to `/inet'"
-msgstr "måste tillhandahålla en fjärrport till \"/inet\""
+msgstr "måste tillhandahålla en fjärrport till \"/inet\""
-#: io.c:1527
+#: io.c:1685
msgid "TCP/IP communications are not supported"
-msgstr "TCP/IP-kommunikation stöds inte"
+msgstr "TCP/IP-kommunikation stöds inte"
-#: io.c:1694
+#: io.c:1867
#, c-format
msgid "could not open `%s', mode `%s'"
-msgstr "kunde inte öppna \"%s\", läge \"%s\""
+msgstr "kunde inte öppna \"%s\", läge \"%s\""
-#: io.c:1748
+#: io.c:1917
#, c-format
msgid "close of master pty failed (%s)"
-msgstr "stängning av huvudpty misslyckades (%s)"
+msgstr "stängning av huvudpty misslyckades (%s)"
-#: io.c:1750 io.c:1918 io.c:2075
+#: io.c:1919 io.c:2105 io.c:2305
#, c-format
msgid "close of stdout in child failed (%s)"
-msgstr "stängning av standard ut i barnet misslyckades (%s)"
+msgstr "stängning av standard ut i barnet misslyckades (%s)"
-#: io.c:1753
+#: io.c:1922
#, 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:1755 io.c:1923
+#: io.c:1924 io.c:2110
#, c-format
msgid "close of stdin in child failed (%s)"
-msgstr "stängning av standard in i barnet misslyckades (%s)"
+msgstr "stängning av standard in i barnet misslyckades (%s)"
-#: io.c:1758
+#: io.c:1927
#, 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:1760 io.c:1781
+#: io.c:1929 io.c:1951
#, c-format
msgid "close of slave pty failed (%s)"
-msgstr "stängning av slavpty misslyckades (%s)"
+msgstr "stängning av slavpty misslyckades (%s)"
-#: io.c:1859 io.c:1921 io.c:2053 io.c:2078
+#: io.c:2040 io.c:2108 io.c:2276 io.c:2308
#, 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)"
+msgstr "flyttande av rör till standard ut i barnet misslyckades (dup: %s)"
-#: io.c:1866 io.c:1926
+#: io.c:2047 io.c:2113
#, 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)"
+msgstr "flyttande av rör till standard in i barnet misslyckades (dup: %s)"
-#: io.c:1886 io.c:2068
+#: io.c:2073 io.c:2298
msgid "restoring stdout in parent process failed\n"
-msgstr "återställande av standard ut i förälderprocessen misslyckades\n"
+msgstr "återställande av standard ut i föräldraprocessen misslyckades\n"
-#: io.c:1894
+#: io.c:2081
msgid "restoring stdin in parent process failed\n"
-msgstr "återställande av standard in i förälderprocessen misslyckades\n"
+msgstr "återställande av standard in i föräldraprocessen misslyckades\n"
-#: io.c:1929 io.c:2080 io.c:2094
+#: io.c:2116 io.c:2310 io.c:2324
#, c-format
msgid "close of pipe failed (%s)"
-msgstr "stängning av röret misslyckades (%s)"
+msgstr "stängning av röret misslyckades (%s)"
-#: io.c:1974
+#: io.c:2174
msgid "`|&' not supported"
-msgstr "\"|&\" stöds inte"
+msgstr "\"|&\" stöds inte"
-#: io.c:2040
+#: io.c:2261
#, c-format
msgid "cannot open pipe `%s' (%s)"
-msgstr "kan inte öppna röret \"%s\" (%s)"
+msgstr "kan inte öppna röret \"%s\" (%s)"
-#: io.c:2088
+#: io.c:2318
#, c-format
msgid "cannot create child process for `%s' (fork: %s)"
-msgstr "kan inte skapa barnprocess för \"%s\" (fork: %s)"
+msgstr "kan inte skapa barnprocess för \"%s\" (fork: %s)"
+
+#: io.c:2790
+msgid "register_input_parser: received NULL pointer"
+msgstr "register_input_parser: mottog NULL-pekare"
+
+#: io.c:2818
+#, c-format
+msgid "input parser `%s' conflicts with previously installed input parser `%s'"
+msgstr ""
+"inmatningstolken â€%s†stÃ¥r i konflikt med tidigare installerad "
+"inmatningstolk â€%sâ€"
-#: io.c:2521
+#: io.c:2825
+#, c-format
+msgid "input parser `%s' failed to open `%s'"
+msgstr "inmatningstolken â€%s†misslyckades att öppna â€%sâ€"
+
+#: io.c:2845
+msgid "register_output_wrapper: received NULL pointer"
+msgstr "register_output_wrapper: mottog NULL-pekare"
+
+#: io.c:2873
+#, c-format
+msgid ""
+"output wrapper `%s' conflicts with previously installed output wrapper `%s'"
+msgstr ""
+"utmatningsomslag â€%s†stÃ¥r i konflikt med tidigare installerat "
+"utmatningsomslag â€%sâ€"
+
+#: io.c:2880
+#, c-format
+msgid "output wrapper `%s' failed to open `%s'"
+msgstr "utmatningsomslag â€%s†misslyckades att öppna â€%sâ€"
+
+#: io.c:2901
+msgid "register_output_processor: received NULL pointer"
+msgstr "register_output_processor: mottog NULL-pekare"
+
+#: io.c:2930
+#, c-format
+msgid ""
+"two-way processor `%s' conflicts with previously installed two-way processor "
+"`%s'"
+msgstr ""
+"tvÃ¥vägsprocessorn â€%s†stÃ¥r i konflikt med tidigare installerad "
+"tvÃ¥vägsprocessor â€%sâ€"
+
+#: io.c:2939
+#, c-format
+msgid "two way processor `%s' failed to open `%s'"
+msgstr "tvÃ¥vägsprocessorn â€%s†misslyckades att öppna â€%sâ€"
+
+#: io.c:3064
#, c-format
msgid "data file `%s' is empty"
-msgstr "datafilen \"%s\" är tom"
+msgstr "datafilen \"%s\" är tom"
-#: io.c:2562 io.c:2570
+#: io.c:3106 io.c:3114
msgid "could not allocate more input memory"
msgstr "kunde inte allokera mer indataminne"
-#: io.c:3128
+#: io.c:3682
msgid "multicharacter value of `RS' is a gawk extension"
-msgstr "flerteckensvärdet av \"RS\" är en gawk-utökning"
+msgstr "flerteckensvärdet av \"RS\" är en gawk-utökning"
-#: io.c:3233
+#: io.c:3771
msgid "IPv6 communication is not supported"
-msgstr "IPv6-kommunikation stöds inte"
-
-#: main.c:364
-msgid "`-m[fr]' option irrelevant in gawk"
-msgstr "\"-m[fr]\"-flaggan är irrelevant i gawk"
-
-#: main.c:366
-msgid "-m option usage: `-m[fr] nnn'"
-msgstr "-m-flaggans användning: \"-m[fr] nnn\""
+msgstr "IPv6-kommunikation stöds inte"
-#: main.c:389
+#: main.c:405
msgid "empty argument to `-e/--source' ignored"
msgstr "tomt argument till \"-e/--source\" ignorerat"
-#: main.c:460
+#: main.c:495
#, c-format
msgid "%s: option `-W %s' unrecognized, ignored\n"
-msgstr "%s: flaggan \"-W %s\" okänd, ignorerad\n"
+msgstr "%s: flaggan \"-W %s\" okänd, ignorerad\n"
-#: main.c:513
+#: main.c:541
#, c-format
msgid "%s: option requires an argument -- %c\n"
-msgstr "%s: flaggan kräver ett argument -- %c\n"
+msgstr "%s: flaggan kräver ett argument -- %c\n"
-#: main.c:534
+#: main.c:562
msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
-msgstr "miljövariabeln \"POSIXLY_CORRECT\" satt: slår på \"--posix\""
+msgstr "miljövariabeln \"POSIXLY_CORRECT\" satt: slår på \"--posix\""
-#: main.c:540
+#: main.c:568
msgid "`--posix' overrides `--traditional'"
-msgstr "\"--posix\" åsidosätter \"--traditional\""
+msgstr "\"--posix\" åsidosätter \"--traditional\""
-#: main.c:551
+#: main.c:579
msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
-msgstr "\"--posix\"/\"--traditional\" åsidosätter \"--non-decimal-data\""
+msgstr "\"--posix\"/\"--traditional\" åsidosätter \"--non-decimal-data\""
-#: main.c:555
+#: main.c:583
#, c-format
msgid "running %s setuid root may be a security problem"
-msgstr "att köra %s setuid root kan vara ett säkerhetsproblem"
+msgstr "att köra %s setuid root kan vara ett säkerhetsproblem"
-#: main.c:560
-msgid "`--posix' overrides `--binary'"
-msgstr "\"--posix\" åsidosätter \"--binary\""
+#: main.c:588
+msgid "`--posix' overrides `--characters-as-bytes'"
+msgstr "â€--posix†åsidosätter â€--character-as-bytesâ€"
-#: main.c:611
+#: main.c:647
#, c-format
msgid "can't set binary mode on stdin (%s)"
-msgstr "kan inte sätta binärläge på standard in (%s)"
+msgstr "kan inte sätta binärläge på standard in (%s)"
-#: main.c:614
+#: main.c:650
#, c-format
msgid "can't set binary mode on stdout (%s)"
-msgstr "kan inte sätta binärläge på standard ut (%s)"
+msgstr "kan inte sätta binärläge på standard ut (%s)"
-#: main.c:616
+#: main.c:652
#, c-format
msgid "can't set binary mode on stderr (%s)"
-msgstr "kan inte sätta binärläge på standard fel (%s)"
+msgstr "kan inte sätta binärläge på standard fel (%s)"
-#: main.c:655
+#: main.c:710
msgid "no program text at all!"
msgstr "ingen programtext alls!"
-#: main.c:733
+#: main.c:799
#, 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"
+"Användning: %s [POSIX- eller GNU-stilsflaggor] -f progfil [--] fil ...\n"
-#: main.c:735
+#: main.c:801
#, 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"
+msgstr "Användning: %s [POSIX- eller GNU-stilsflaggor] %cprogram%c fil ...\n"
-#: main.c:740
+#: main.c:806
msgid "POSIX options:\t\tGNU long options: (standard)\n"
-msgstr "POSIX-flaggor:\t\tGNU långa flaggor: (standard)\n"
+msgstr "POSIX-flaggor:\t\tGNU långa flaggor: (standard)\n"
-#: main.c:741
+#: main.c:807
msgid "\t-f progfile\t\t--file=progfile\n"
msgstr "\t-f progfil\t\t--file=progfil\n"
-#: main.c:742
+#: main.c:808
msgid "\t-F fs\t\t\t--field-separator=fs\n"
msgstr "\t-F fs\t\t\t--field-separator=fs\n"
-#: main.c:743
+#: main.c:809
msgid "\t-v var=val\t\t--assign=var=val\n"
-msgstr "\t-v var=värde\t\t--assign=var=värde\n"
+msgstr "\t-v var=värde\t\t--assign=var=värde\n"
-#: main.c:744
+#: main.c:810
msgid "Short options:\t\tGNU long options: (extensions)\n"
-msgstr "Korta flaggor:\t\tGNU långa flaggor: (utökningar)\n"
+msgstr "Korta flaggor:\t\tGNU långa flaggor: (utökningar)\n"
-#: main.c:745
+#: main.c:811
msgid "\t-b\t\t\t--characters-as-bytes\n"
msgstr "\t-b\t\t\t--characters-as-bytes\n"
-#: main.c:746
+#: main.c:812
msgid "\t-c\t\t\t--traditional\n"
msgstr "\t-c\t\t\t--traditional\n"
-#: main.c:747
+#: main.c:813
msgid "\t-C\t\t\t--copyright\n"
msgstr "\t-C\t\t\t--copyright\n"
-#: main.c:748
+#: main.c:814
msgid "\t-d[file]\t\t--dump-variables[=file]\n"
msgstr "\t-d[fil]\t\t\t--dump-variables[=fil]\n"
-#: main.c:749
+#: main.c:815
+msgid "\t-D[file]\t\t--debug[=file]\n"
+msgstr "\t-D[fil]\t\t\t--debug[=fil]\n"
+
+#: main.c:816
msgid "\t-e 'program-text'\t--source='program-text'\n"
msgstr "\t-e 'programtext'\t--source='programtext'\n"
-#: main.c:750
+#: main.c:817
msgid "\t-E file\t\t\t--exec=file\n"
msgstr "\t-E fil\t\t\t--exec=fil\n"
-#: main.c:751
+#: main.c:818
msgid "\t-g\t\t\t--gen-pot\n"
msgstr "\t-g\t\t\t--gen-pot\n"
-#: main.c:752
+#: main.c:819
msgid "\t-h\t\t\t--help\n"
msgstr "\t-h\t\t\t--help\n"
-#: main.c:753
+#: main.c:820
+msgid "\t-i includefile\t\t--include=includefile\n"
+msgstr "\t-i inkluderingsfil\t--include=inkluderingsfil\n"
+
+#: main.c:821
+msgid "\t-l library\t\t--load=library\n"
+msgstr "\t-l bibliotek\t\t--load=bibliotek\n"
+
+#: main.c:822
msgid "\t-L [fatal]\t\t--lint[=fatal]\n"
msgstr "\t-L [fatal]\t\t--lint[=fatal]\n"
-#: main.c:754
+#: main.c:823
msgid "\t-n\t\t\t--non-decimal-data\n"
msgstr "\t-n\t\t\t--non-decimal-data\n"
-#: main.c:755
+#: main.c:824
+msgid "\t-M\t\t\t--bignum\n"
+msgstr "\t-M\t\t\t--bignum\n"
+
+#: main.c:825
msgid "\t-N\t\t\t--use-lc-numeric\n"
msgstr "\t-N\t\t\t--use-lc-numeric\n"
-#: main.c:756
+#: main.c:826
+msgid "\t-o[file]\t\t--pretty-print[=file]\n"
+msgstr "\t-o[fil]\t\t\t--pretty-print[=fil]\n"
+
+#: main.c:827
msgid "\t-O\t\t\t--optimize\n"
msgstr "\t-O\t\t\t--optimize\n"
-#: main.c:757
+#: main.c:828
msgid "\t-p[file]\t\t--profile[=file]\n"
msgstr "\t-p[fil]\t\t\t--profile[=fil]\n"
-#: main.c:758
+#: main.c:829
msgid "\t-P\t\t\t--posix\n"
msgstr "\t-P\t\t\t--posix\n"
-#: main.c:759
+#: main.c:830
msgid "\t-r\t\t\t--re-interval\n"
msgstr "\t-r\t\t\t--re-interval\n"
-#: main.c:761
-msgid "\t-R file\t\t\t--command=file\n"
-msgstr "\t-R file\t\t\t--command=file\n"
-
-#: main.c:762
+#: main.c:831
msgid "\t-S\t\t\t--sandbox\n"
msgstr "\t-S\t\t\t--sandbox\n"
-#: main.c:763
+#: main.c:832
msgid "\t-t\t\t\t--lint-old\n"
msgstr "\t-t\t\t\t--lint-old\n"
-#: main.c:764
+#: main.c:833
msgid "\t-V\t\t\t--version\n"
msgstr "\t-V\t\t\t--version\n"
-#: main.c:766
+#: main.c:835
msgid "\t-W nostalgia\t\t--nostalgia\n"
msgstr "\t-W nostalgia\t\t--nostalgia\n"
-#: main.c:769
+#: main.c:838
msgid "\t-Y\t\t--parsedebug\n"
msgstr "\t-Y\t\t--parsedebug\n"
@@ -1810,7 +3108,7 @@ msgstr "\t-Y\t\t--parsedebug\n"
#. for this application. Please add _another line_ with the
#. address for translation bugs.
#. no-wrap
-#: main.c:778
+#: main.c:847
msgid ""
"\n"
"To report bugs, see node `Bugs' in `gawk.info', which is\n"
@@ -1818,23 +3116,23 @@ msgid ""
"\n"
msgstr ""
"\n"
-"För att rapportera fel, se noden \"Bugs\" i \"gawk.info\",\n"
-"vilket är avsnittet \"Reporting Problems and Bugs\" i den utskrivna\n"
+"För att rapportera fel, se noden \"Bugs\" i \"gawk.info\",\n"
+"vilket är avsnittet \"Reporting Problems and Bugs\" i den utskrivna\n"
"versionen.\n"
-"Rapportera synpunkter på översättningen till <tp-sv@listor.tp-sv.se>.\n"
+"Rapportera synpunkter på översättningen till <tp-sv@listor.tp-sv.se>.\n"
"\n"
-#: main.c:782
+#: main.c:851
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"
+"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:786
+#: main.c:855
msgid ""
"Examples:\n"
"\tgawk '{ sum += $1 }; END { print sum }' file\n"
@@ -1844,7 +3142,7 @@ msgstr ""
"\tgawk '{ sum += $1 }; END { print sum }' fil\n"
"\tgawk -F: '{ print $1 }' /etc/passwd\n"
-#: main.c:806
+#: main.c:880
#, c-format
msgid ""
"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
@@ -1855,15 +3153,15 @@ msgid ""
"(at your option) any later version.\n"
"\n"
msgstr ""
-"Copyright © 1989, 1991-%d Free Software Foundation.\n"
+"Copyright © 1989, 1991-%d Free Software Foundation.\n"
"\n"
-"Detta program är fri programvara. Du kan distribuera det och/eller\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 3 eller (om du så vill)\n"
-"någon senare version.\n"
+"av Free Software Foundation, antingen version 3 eller (om du så vill)\n"
+"någon senare version.\n"
"\n"
-#: main.c:814
+#: main.c:888
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"
@@ -1871,155 +3169,196 @@ msgid ""
"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"
+"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:820
+#: main.c:894
msgid ""
"You should have received a copy of the GNU General Public License\n"
"along with this program. If not, see http://www.gnu.org/licenses/.\n"
msgstr ""
-"Du bör ha fått en kopia av GNU General Public License tillsammans\n"
-"med detta program. Om inte, se http//www.gnu.org/liceences/.\n"
+"Du bör ha fått en kopia av GNU General Public License tillsammans\n"
+"med detta program. Om inte, se http://www.gnu.org/licenses/.\n"
-#: main.c:855
+#: main.c:931
msgid "-Ft does not set FS to tab in POSIX awk"
-msgstr "-Ft sätter inte FS till tab i POSIX-awk"
+msgstr "-Ft sätter inte FS till tab i POSIX-awk"
-#: main.c:1089
+#: main.c:1208
#, c-format
msgid "unknown value for field spec: %d\n"
-msgstr "okänt värde till fältspecifikation: %d\n"
+msgstr "okänt värde till fältspecifikation: %d\n"
-#: main.c:1170
+#: main.c:1306
#, 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"
+msgstr "%s: Argumentet \"%s\" till \"-v\" är inte på formatet \"var=värde\"\n"
-#: main.c:1196
+#: main.c:1332
#, c-format
msgid "`%s' is not a legal variable name"
-msgstr "\"%s\" är inte ett giltigt variabelnamn"
+msgstr "\"%s\" är inte ett giltigt variabelnamn"
-#: main.c:1199
+#: main.c:1335
#, 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\""
+msgstr "\"%s\" är inte ett variabelnamn, letar efter filen \"%s=%s\""
-#: main.c:1203
+#: main.c:1339
#, c-format
msgid "cannot use gawk builtin `%s' as variable name"
-msgstr "kan inte använda gawks inbyggda \"%s\" som ett funktionsnamn"
+msgstr "kan inte använda gawks inbyggda \"%s\" som ett funktionsnamn"
-#: main.c:1208
+#: main.c:1344
#, c-format
msgid "cannot use function `%s' as variable name"
-msgstr "kan inte använda funktionen \"%s\" som variabelnamn"
+msgstr "kan inte använda funktionen \"%s\" som variabelnamn"
-#: main.c:1261
+#: main.c:1397
msgid "floating point exception"
msgstr "flyttalsundantag"
-#: main.c:1268
+#: main.c:1404
msgid "fatal error: internal error"
-msgstr "ödesdigert fel: internt fel"
+msgstr "ödesdigert fel: internt fel"
-#: main.c:1283
+#: main.c:1419
msgid "fatal error: internal error: segfault"
-msgstr "ödesdigert fel: internt fel: segmenteringsfel"
+msgstr "ödesdigert fel: internt fel: segmenteringsfel"
-#: main.c:1295
+#: main.c:1431
msgid "fatal error: internal error: stack overflow"
-msgstr "ödesdigert fel: internt fel: stackspill"
+msgstr "ödesdigert fel: internt fel: stackspill"
-#: main.c:1345
+#: main.c:1490
#, c-format
msgid "no pre-opened fd %d"
-msgstr "ingen föröppnad fd %d"
+msgstr "ingen föröppnad fd %d"
-#: main.c:1352
+#: main.c:1497
#, c-format
msgid "could not pre-open /dev/null for fd %d"
-msgstr "kunde inte föröppna /dev/null för fd %d"
+msgstr "kunde inte föröppna /dev/null för fd %d"
-#: main.c:1375 main.c:1384
+#: mpfr.c:550
#, c-format
-msgid "could not find groups: %s"
-msgstr "kunde inte hitta grupper: %s"
+msgid "PREC value `%.*s' is invalid"
+msgstr "PREC-värdet â€%.*s†är ogiltigt"
-#: msg.c:63
+#: mpfr.c:608
+#, c-format
+msgid "RNDMODE value `%.*s' is invalid"
+msgstr "RNDMODE-värdet â€%.*s†är ogiltigt"
+
+#: mpfr.c:698
+#, c-format
+msgid "%s: received non-numeric argument"
+msgstr "%s: fick ett ickenumeriskt argument"
+
+#: mpfr.c:800
+msgid "compl(%Rg): negative value will give strange results"
+msgstr "compl(%Rg): negativt värde kommer ge konstiga resultat"
+
+#: mpfr.c:804
+msgid "comp(%Rg): fractional value will be truncated"
+msgstr "compl(%Rg): flyttalsvärden kommer huggas av"
+
+#: mpfr.c:816
+#, c-format
+msgid "cmpl(%Zd): negative values will give strange results"
+msgstr "cmpl(%Zd): negativt värde kommer ge konstiga resultat"
+
+#: mpfr.c:835
+#, c-format
+msgid "%s: received non-numeric argument #%d"
+msgstr "%s: fick ett ickenumeriskt argument nr. %d"
+
+#: mpfr.c:845
+msgid "%s: argument #%d has invalid value %Rg, using 0"
+msgstr "%s: argument nr. %d har ogiltigt värde %Rg, använder 0"
+
+#: mpfr.c:857
+msgid "%s: argument #%d negative value %Rg will give strange results"
+msgstr "%s: argument nr. %d negativa värde %Rg kommer ge konstiga resultat"
+
+#: mpfr.c:863
+msgid "%s: argument #%d fractional value %Rg will be truncated"
+msgstr "%s: argument nr. %d flyttalsvärde %Rg kommer huggas av"
+
+#: mpfr.c:878
+#, c-format
+msgid "%s: argument #%d negative value %Zd will give strange results"
+msgstr "%s: argument nr. %d negativa värde %Zd kommer ge konstiga resultat"
+
+#: msg.c:68
#, c-format
msgid "cmd. line:"
msgstr "kommandorad:"
-#: msg.c:107
-msgid "error: "
-msgstr "fel: "
-
-#: node.c:406
+#: node.c:421
msgid "backslash at end of string"
-msgstr "omvänt snedstreck i slutet av strängen"
+msgstr "omvänt snedstreck i slutet av strängen"
-#: node.c:517
+#: node.c:500
#, c-format
msgid "old awk does not support the `\\%c' escape sequence"
-msgstr "gamla awk stöder inte kontrollsekvensen \"\\%c\""
+msgstr "gamla awk stöder inte kontrollsekvensen \"\\%c\""
-#: node.c:568
+#: node.c:551
msgid "POSIX does not allow `\\x' escapes"
-msgstr "POSIX tillåter inte \"\\x\"-kontrollsekvenser"
+msgstr "POSIX tillåter inte \"\\x\"-kontrollsekvenser"
-#: node.c:574
+#: node.c:557
msgid "no hex digits in `\\x' escape sequence"
msgstr "inga hexadecimala siffror i \"\\x\"-kontrollsekvenser"
-#: node.c:596
+#: node.c:579
#, c-format
msgid ""
"hex escape \\x%.*s of %d characters probably not interpreted the way you "
"expect"
msgstr ""
-"hexkod \\x%.*s med %d tecken tolkas förmodligen inte på det sätt du "
-"förväntar dig"
+"hexkod \\x%.*s med %d tecken tolkas förmodligen inte på det sätt du "
+"förväntar dig"
-#: node.c:611
+#: node.c:594
#, c-format
msgid "escape sequence `\\%c' treated as plain `%c'"
msgstr "kontrollsekvensen \"\\%c\" behandlad som bara \"%c\""
-#: node.c:750
+#: node.c:739
msgid ""
"Invalid multibyte data detected. There may be a mismatch between your data "
"and your locale."
msgstr ""
-"Ogiltig multibytedata upptäckt. Dina data och din lokal stämmer kanske inte "
-"överens."
+"Ogiltig multibytedata upptäckt. Dina data och din lokal stämmer kanske inte "
+"överens."
-#: posix/gawkmisc.c:176
+#: posix/gawkmisc.c:177
#, c-format
msgid "%s %s `%s': could not get fd flags: (fcntl F_GETFD: %s)"
-msgstr "%s %s \"%s\": kunde inte hämta fb-flaggor: (fcntl F_GETFD: %s)"
+msgstr "%s %s \"%s\": kunde inte hämta fb-flaggor: (fcntl F_GETFD: %s)"
-#: posix/gawkmisc.c:188
+#: posix/gawkmisc.c:189
#, c-format
msgid "%s %s `%s': could not set close-on-exec: (fcntl F_SETFD: %s)"
-msgstr "%s %s \"%s\": kunde inte sätta stäng-vid-exec (fcntl F_SETFD: %s)"
+msgstr "%s %s \"%s\": kunde inte sätta stäng-vid-exec (fcntl F_SETFD: %s)"
-#: profile.c:83
+#: profile.c:71
#, c-format
msgid "could not open `%s' for writing: %s"
-msgstr "kunde inte öppna \"%s\" för skrivning: %s"
+msgstr "kunde inte öppna \"%s\" för skrivning: %s"
-#: profile.c:85
+#: profile.c:73
msgid "sending profile to standard error"
msgstr "skickar profilen till standard fel"
-#: profile.c:203
+#: profile.c:193
#, c-format
msgid ""
"\t# %s block(s)\n"
@@ -2028,7 +3367,7 @@ msgstr ""
"\t# %s-block\n"
"\n"
-#: profile.c:208
+#: profile.c:198
#, c-format
msgid ""
"\t# Rule(s)\n"
@@ -2037,17 +3376,30 @@ msgstr ""
"\t# Regel/regler\n"
"\n"
-#: profile.c:279
+#: profile.c:272
#, c-format
msgid "internal error: %s with null vname"
msgstr "internt fel: %s med null vname"
-#: profile.c:952
+#: profile.c:537
+msgid "internal error: builtin with null fname"
+msgstr "internt fel: inbyggd med tomt fname"
+
+#: profile.c:949
+#, c-format
+msgid ""
+"\t# Loaded extensions (-l and/or @load)\n"
+"\n"
+msgstr ""
+"\t# Laddade utvidgningar (-l och/eller @load)\n"
+"\n"
+
+#: profile.c:972
#, c-format
msgid "\t# gawk profile, created %s\n"
msgstr "\t# gawkprofil, skapad %s\n"
-#: profile.c:1331
+#: profile.c:1475
#, c-format
msgid ""
"\n"
@@ -2056,94 +3408,81 @@ msgstr ""
"\n"
"\t# Funktioner, listade alfabetiskt\n"
-#: profile.c:1370
+#: profile.c:1513
#, c-format
msgid "redir2str: unknown redirection type %d"
-msgstr "redir2str: okänd omdirigeringstyp %d"
-
-#: re.c:572
-#, fuzzy, c-format
-msgid "range of the form `[%c-%c]' is locale dependent"
-msgstr "intervall på formen \"[%c-%c]\" är lokalberoende"
+msgstr "redir2str: okänd omdirigeringstyp %d"
-#: re.c:599
+#: re.c:607
#, c-format
msgid "regexp component `%.*s' should probably be `[%.*s]'"
msgstr ""
-"komponenten \"%.*s\" i reguljäruttryck skall förmodligen vara \"[%.*s]\""
+"komponenten \"%.*s\" i reguljäruttryck skall förmodligen vara \"[%.*s]\""
-#: regcomp.c:132
+#: regcomp.c:131
msgid "Success"
msgstr "Lyckades"
-#: regcomp.c:135
+#: regcomp.c:134
msgid "No match"
msgstr "Misslyckades"
-#: regcomp.c:138
+#: regcomp.c:137
msgid "Invalid regular expression"
-msgstr "Ogiltigt reguljärt uttryck"
+msgstr "Ogiltigt reguljärt uttryck"
-#: regcomp.c:141
+#: regcomp.c:140
msgid "Invalid collation character"
msgstr "Ogiltigt kollationeringstecken"
-#: regcomp.c:144
+#: regcomp.c:143
msgid "Invalid character class name"
msgstr "Ogiltigt teckenklassnamn"
-#: regcomp.c:147
+#: regcomp.c:146
msgid "Trailing backslash"
-msgstr "Eftersläpande omvänt snedstreck"
+msgstr "Eftersläpande omvänt snedstreck"
-#: regcomp.c:150
+#: regcomp.c:149
msgid "Invalid back reference"
-msgstr "Ogiltig bakåtrerefens"
+msgstr "Ogiltig bakåtrerefens"
-#: regcomp.c:153
+#: regcomp.c:152
msgid "Unmatched [ or [^"
msgstr "Obalanserad [ eller [^"
-#: regcomp.c:156
+#: regcomp.c:155
msgid "Unmatched ( or \\("
msgstr "Obalanserad ( eller \\("
-#: regcomp.c:159
+#: regcomp.c:158
msgid "Unmatched \\{"
msgstr "Obalanserad \\{"
-#: regcomp.c:162
-msgid "Invalid content of \\{\\}"
-msgstr "Ogiltigt innehåll i \\{\\}"
-
-#: regcomp.c:165
+#: regcomp.c:164
msgid "Invalid range end"
-msgstr "Ogiltigt omfångsslut"
+msgstr "Ogiltigt omfångsslut"
-#: regcomp.c:168
+#: regcomp.c:167
msgid "Memory exhausted"
msgstr "Minnet slut"
-#: regcomp.c:171
+#: regcomp.c:170
msgid "Invalid preceding regular expression"
-msgstr "Ogiltigt föregående reguljärt uttryck"
+msgstr "Ogiltigt föregående reguljärt uttryck"
-#: regcomp.c:174
+#: regcomp.c:173
msgid "Premature end of regular expression"
-msgstr "För tidigt slut på reguljärt uttryck"
-
-#: regcomp.c:177
-msgid "Regular expression too big"
-msgstr "Reguljärt uttryck för stort"
+msgstr "För tidigt slut på reguljärt uttryck"
-#: regcomp.c:180
+#: regcomp.c:179
msgid "Unmatched ) or \\)"
msgstr "Obalanserad ) eller \\)"
-#: regcomp.c:701
+#: regcomp.c:704
msgid "No previous regular expression"
-msgstr "Inget föregående reguljärt uttryck"
+msgstr "Inget föregående reguljärt uttryck"
-#~ msgid "assignment is not allowed to result of builtin function"
-#~ msgstr ""
-#~ "det är inte tillåtet att tilldela resultatet från en inbyggd funktion"
+#: symbol.c:741
+msgid "can not pop main context"
+msgstr "kan inte poppa huvudsammanhang"
diff --git a/po/tr.gmo b/po/tr.gmo
deleted file mode 100644
index 146da41d..00000000
--- a/po/tr.gmo
+++ /dev/null
Binary files differ
diff --git a/po/vi.gmo b/po/vi.gmo
index e3a5e619..10c710dc 100644
--- a/po/vi.gmo
+++ b/po/vi.gmo
Binary files differ
diff --git a/po/vi.po b/po/vi.po
index 8b0cedb6..faa458a1 100644
--- a/po/vi.po
+++ b/po/vi.po
@@ -1,885 +1,1888 @@
# Vietnamese translation for Gawk.
-# Copyright © 2007 Free Software Foundation, Inc.
-# Clytie Siddall <clytie@riverland.net.au>, 2005-2007.
+# Bản dịch Tiếng Việt dành cho Gawk.
+# Copyright © 2014 Free Software Foundation, Inc.
+# This file is distributed under the same license as the gawk package.
+# Clytie Siddall <clytie@riverland.net.au>, 2005-2010.
+# Trần Ngá»c Quân <vnwildman@gmail.com>, 2012-2014.
#
msgid ""
msgstr ""
-"Project-Id-Version: gawk 3.1.6\n"
+"Project-Id-Version: gawk-4.1.0b\n"
"Report-Msgid-Bugs-To: arnold@skeeve.com\n"
-"POT-Creation-Date: 2011-03-18 12:00+0200\n"
-"PO-Revision-Date: 2007-11-30 22:29+1030\n"
-"Last-Translator: Clytie Siddall <clytie@riverland.net.au>\n"
-"Language-Team: Vietnamese <vi-VN@googlegroups.com>\n"
+"POT-Creation-Date: 2014-04-08 19:23+0300\n"
+"PO-Revision-Date: 2014-01-16 14:52+0700\n"
+"Last-Translator: Trần Ngá»c Quân <vnwildman@gmail.com>\n"
+"Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n"
"Language: vi\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: LocFactoryEditor 1.7b1\n"
+"X-Generator: Poedit 1.5.5\n"
+"X-Poedit-SourceCharset: UTF-8\n"
-#: array.c:103
+#: array.c:256
#, c-format
msgid "from %s"
msgstr "từ %s"
-#: array.c:267
-#, fuzzy
+#: array.c:357
msgid "attempt to use a scalar value as array"
-msgstr "cố dùng Ä‘iá»u cô hÆ°á»›ng « %s » là mảng"
+msgstr "cố dùng giá trị vô hướng như là một mảng"
-#: array.c:270
-#, c-format
-msgid "attempt to use function `%s' as an array"
-msgstr "cố gắng dùng chức năng « %s » như mảng"
-
-#: array.c:273
+#: array.c:359
#, c-format
msgid "attempt to use scalar parameter `%s' as an array"
-msgstr "cố gắng dùng tham số vô hướng « %s » như là mảng"
+msgstr "cố dùng tham số vô hướng “%s†như là mảng"
-#: array.c:276 eval.c:2013
-#, fuzzy, c-format
+#: array.c:362
+#, c-format
msgid "attempt to use scalar `%s' as an array"
-msgstr "cố dùng Ä‘iá»u cô hÆ°á»›ng « %s » là mảng"
+msgstr "cố dùng “%s†vô hướng như là mảng"
-#: array.c:321 array.c:648 builtin.c:75 builtin.c:555 builtin.c:597
-#: builtin.c:610 builtin.c:1016 builtin.c:1028 eval.c:1381 eval.c:1385
-#: eval.c:1710 eval.c:1958 eval.c:2026 eval.c:2274
+#: array.c:409 array.c:576 builtin.c:85 builtin.c:1615 builtin.c:1661
+#: builtin.c:1674 builtin.c:2102 builtin.c:2116 eval.c:1122 eval.c:1126
+#: eval.c:1531
#, c-format
msgid "attempt to use array `%s' in a scalar context"
-msgstr "cố gắng dùng mảng « %s » trong một ngữ cảnh vô hướng"
-
-#: array.c:570
-#, fuzzy, c-format
-msgid "reference to uninitialized element `%s[\"%.*s\"]'"
-msgstr "tham chiếu đến phần tử chưa sở khởi « %s[\"%s\"] »"
+msgstr "cố gắng dùng mảng “%s†trong một ngữ cảnh vô hướng"
-#: array.c:576
-#, 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:684
+#: array.c:583
#, c-format
msgid "delete: index `%s' not in array `%s'"
-msgstr "delete: (xóa bá») số mÅ© « %s » không phải nằm trong mảng « %s »"
+msgstr "delete: (xoá) chỉ số “%s†không nằm trong mảng “%sâ€"
-#: array.c:708
-#, fuzzy, c-format
+#: array.c:597
+#, c-format
msgid "attempt to use scalar `%s[\"%.*s\"]' as an array"
-msgstr "cố dùng Ä‘iá»u cô hÆ°á»›ng « %s » là mảng"
+msgstr "cố dùng “%s[\"%.*s\"]†vô hướng như là mảng"
-#: array.c:871
-#, c-format
-msgid "%s: empty (null)\n"
-msgstr "%s: rỗng (vô giá trị)\n"
+#: array.c:776
+msgid "adump: first argument not an array"
+msgstr "adump: đối số thứ nhất không phải là một mảng"
-#: array.c:876
-#, c-format
-msgid "%s: empty (zero)\n"
-msgstr "%s: rỗng (số không)\n"
+#: array.c:815
+msgid "asort: second argument not an array"
+msgstr "asort: đối số thứ hai không phải là một mảng"
-#: array.c:880
-#, c-format
-msgid "%s: table_size = %d, array_size = %d\n"
-msgstr "%s: cỡ_bảng = %d, cỡ_mảng = %d\n"
+#: array.c:816
+msgid "asorti: second argument not an array"
+msgstr "asorti: đối số thứ hai không phải là một mảng"
-#: array.c:915
-#, c-format
-msgid "%s: is parameter\n"
-msgstr "%s: là tham số\n"
+#: array.c:823
+msgid "asort: first argument not an array"
+msgstr "asort: đối số thứ nhất không phải là một mảng"
-#: array.c:919
-#, c-format
-msgid "%s: array_ref to %s\n"
-msgstr "%s: « array_ref » (mảng tham chiếu) đến « %s »\n"
+#: array.c:824
+msgid "asorti: first argument not an array"
+msgstr "asorti: đối số thứ nhất không phải là một mảng"
-#: array.c:924
-#, fuzzy
-msgid "adump: argument not an array"
-msgstr "match: (khớp) đối số thứ ba không phải là mảng"
+#: array.c:831
+msgid "asort: cannot use a subarray of first arg for second arg"
+msgstr ""
+"asort (một chương trình xắp xếp thứ tự): không thể sử dụng mảng con của tham "
+"số thứ nhất cho tham số thứ hai"
-#: array.c:1142
-#, fuzzy
-msgid "attempt to use array in a scalar context"
-msgstr "cố gắng dùng mảng « %s » trong một ngữ cảnh vô hướng"
+#: array.c:832
+msgid "asorti: cannot use a subarray of first arg for second arg"
+msgstr ""
+"asorti (một chương trình xắp xếp thứ tự): không thể sử dụng mảng con của "
+"tham số thứ nhất cho tham số thứ hai"
-#: array.c:1239
-#, fuzzy
-msgid "asort: second argument not an array"
-msgstr "split: (chia tách) đối số thứ hai không phải là mảng"
+#: array.c:837
+msgid "asort: cannot use a subarray of second arg for first arg"
+msgstr ""
+"asort (một chương trình xắp xếp thứ tự): không thể sử dụng mảng con của tham "
+"số thứ hai cho tham số thứ nhất"
-#: array.c:1240
-#, fuzzy
-msgid "asorti: second argument not an array"
-msgstr "split: (chia tách) đối số thứ hai không phải là mảng"
+#: array.c:838
+msgid "asorti: cannot use a subarray of second arg for first arg"
+msgstr ""
+"asorti (một chương trình xắp xếp thứ tự): không thể sử dụng mảng con của "
+"tham số thứ hai cho tham số thứ nhất"
-#: array.c:1247
-#, fuzzy
-msgid "asort: first argument not an array"
-msgstr "match: (khớp) đối số thứ ba không phải là mảng"
+#: array.c:1314
+#, c-format
+msgid "`%s' is invalid as a function name"
+msgstr "“%s†không phải là tên hàm hợp lệ"
-#: array.c:1248
-#, fuzzy
-msgid "asorti: first argument not an array"
-msgstr "match: (khớp) đối số thứ ba không phải là mảng"
+#: array.c:1318
+#, c-format
+msgid "sort comparison function `%s' is not defined"
+msgstr "chÆ°a định nghÄ©a hàm so sánh xắp xếp “%sâ€"
-#: awkgram.y:249
+#: awkgram.y:233
#, c-format
msgid "%s blocks must have an action part"
msgstr "Má»i khối %s phải có má»™t phần kiểu hành Ä‘á»™ng"
-#: awkgram.y:252
+#: awkgram.y:236
msgid "each rule must have a pattern or an action part"
msgstr "Má»i quy tắc phải có má»™t mẫu hay phần kiểu hành Ä‘á»™ng"
-#: awkgram.y:323 awkgram.y:334
+#: awkgram.y:325 awkgram.y:336
msgid "old awk does not support multiple `BEGIN' or `END' rules"
msgstr ""
-"awk cÅ© không há»— trợ nhiá»u quy tắc kiểu « BEGIN » (bắt đầu) hay « END » (kết "
-"thúc)"
+"awk cÅ© không há»— trợ nhiá»u quy tắc kiểu “BEGIN†(bắt đầu) hay “END†(kết thúc)"
-#: awkgram.y:371
+#: awkgram.y:373
#, c-format
msgid "`%s' is a built-in function, it cannot be redefined"
-msgstr "« %s » là một hàm có sẵn nên nó không thể được định nghĩa lái."
+msgstr "“%s†là một hàm có sẵn nên nó không thể được định nghĩa lại."
-#: awkgram.y:432
+#: awkgram.y:419
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"
+"hằng biểu thức chính quy “//†trông giống như một chú thích C++, nhưng mà "
+"không phải"
-#: awkgram.y:436
+#: awkgram.y:423
#, 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"
+"hằng biểu thức chính quy “/%s/†trông giống như một chú thích C, nhưng mà "
+"không phải"
-#: awkgram.y:528
+#: awkgram.y:515
#, c-format
msgid "duplicate case values in switch body: %s"
msgstr "gặp giá trị case trùng trong thân chuyển đổi (switch body): %s"
-#: awkgram.y:549
-#, fuzzy
+#: awkgram.y:536
msgid "duplicate `default' detected in switch body"
msgstr ""
-"Phát hiện « default » (mặc định) trong thân chuyển đổi (switch body): %s"
+"đã phát hiện trùng “default†trong thân cấu trúc Ä‘iá»u khiển chá»n lá»±a (switch)"
-#: awkgram.y:811
-#, fuzzy
+#: awkgram.y:796 awkgram.y:3723
msgid "`break' is not allowed outside a loop or switch"
-msgstr "không cho phép « break » (ngắt) nằm ở ngoại vòng lặp"
+msgstr ""
+"không cho phép “break†(ngắt) nằm ở ngoại vòng lặp hay cấu trúc chá»n lá»±a"
-#: awkgram.y:820
-#, fuzzy
+#: awkgram.y:805 awkgram.y:3715
msgid "`continue' is not allowed outside a loop"
-msgstr "không cho phép « continue » (tiếp tục) nằm ở ngoại vòng lặp"
+msgstr "không cho phép “continue†(tiếp tục) ở ngoài một vòng lặp"
-#: awkgram.y:829
-#, fuzzy, c-format
+#: awkgram.y:815
+#, c-format
msgid "`next' used in %s action"
-msgstr "« %s » được dùng trong hành động %s"
-
-#: awkgram.y:837
-msgid "`nextfile' is a gawk extension"
-msgstr "« nextfile » (tập tin kế tiếp) là một phần mở rộng gawk"
+msgstr "“next†(kế tiếp) được dùng trong hành động %s"
-#: awkgram.y:840
-#, fuzzy, c-format
+#: awkgram.y:824
+#, c-format
msgid "`nextfile' used in %s action"
-msgstr "« %s » được dùng trong hành động %s"
+msgstr "“nextfile†(tập tin kế tiếp) được dùng trong hành động %s"
-#: awkgram.y:863
+#: awkgram.y:848
msgid "`return' used outside function context"
-msgstr "« return » (trở vá») được dùng ở ngoại ngữ cảnh hàm"
+msgstr "“return†(trở vá») được dùng ở ngoại ngữ cảnh hàm"
-#: awkgram.y:923
+#: awkgram.y:922
msgid "plain `print' in BEGIN or END rule should probably be `print \"\"'"
msgstr ""
-"« print » (in) chuẩn trong quy tắc « BEGIN » (bắt đầu) hay « END » (kết "
-"thúc) rất có thể nên là « print\"\" »"
+"“print†(in) thÆ°á»ng trong quy tắc “BEGIN†(bắt đầu) hay “END†(kết thúc) gần "
+"nhÆ° chắc chắn nên là “printâ€â€â€"
+
+#: awkgram.y:988 awkgram.y:1037
+msgid "`delete' is not allowed with SYMTAB"
+msgstr "“delete†không được phép với SYMTAB"
-#: awkgram.y:993 awkgram.y:997 awkgram.y:1021
-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:990 awkgram.y:1039
+msgid "`delete' is not allowed with FUNCTAB"
+msgstr "“delete†không được phép với FUNCTAB"
-#: awkgram.y:1017
+#: awkgram.y:1024 awkgram.y:1028
msgid "`delete(array)' is a non-portable tawk extension"
-msgstr ""
-"« delete array » (xóa bỠmảng) là phần mở rộng gawk không thể mang theo"
+msgstr "“delete array†(xoá mảng) là phần mở rộng gawk không khả chuyển"
-#: awkgram.y:1133
+#: awkgram.y:1149
msgid "multistage two-way pipelines don't work"
msgstr "Ä‘Æ°á»ng ống dẫn hai chiếu Ä‘a giai Ä‘oạn không phải hoạt Ä‘á»™ng được"
-#: awkgram.y:1236
+#: awkgram.y:1264
msgid "regular expression on right of assignment"
-msgstr "biểu thức chính quy nằm bên phải Ä‘iá»u gán"
+msgstr "biểu thức chính quy nằm bên phải phép gán"
-#: awkgram.y:1247
+#: awkgram.y:1275
msgid "regular expression on left of `~' or `!~' operator"
-msgstr "biểu thức chính quy nằm bên trái toán tử « ~ » hay « !~ »"
+msgstr "biểu thức chính quy nằm bên trái toán tá»­ “~†hay “!~â€"
-#: awkgram.y:1263 awkgram.y:1417
+#: awkgram.y:1291 awkgram.y:1442
msgid "old awk does not support the keyword `in' except after `for'"
-msgstr "awk cũ không hỗ trợ từ khoá « in », trừ khi nằm sau « for »"
+msgstr "awk cÅ© không há»— trợ từ khoá “inâ€, trừ khi nằm sau “forâ€"
-#: awkgram.y:1273
+#: awkgram.y:1301
msgid "regular expression on right of comparison"
msgstr "biểu thức chính quy nằm bên phải sự so sánh"
-#: awkgram.y:1392
+#: awkgram.y:1417
#, c-format
msgid "`getline var' invalid inside `%s' rule"
-msgstr ""
+msgstr "“getline var†không hợp lệ bên trong quy tắc “%sâ€"
-#: awkgram.y:1395 eval.c:2649
+#: awkgram.y:1420
#, c-format
msgid "`getline' invalid inside `%s' rule"
-msgstr ""
+msgstr "“getline†không hợp lệ trong quy tắc “%sâ€"
-#: awkgram.y:1400
+#: awkgram.y:1425
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 lại và chưa được xác định."
+"trong hành động “END†(kết thúc) có “getline†(lấy dòng) không được chuyển "
+"hướng lại và chưa được định nghĩa."
-#: awkgram.y:1419
+#: awkgram.y:1444
msgid "old awk does not support multidimensional arrays"
msgstr "awk cÅ© không há»— trợ mảng Ä‘a chiá»u"
-#: awkgram.y:1515
+#: awkgram.y:1541
msgid "call of `length' without parentheses is not portable"
-msgstr "không thể mang lá»i gá»i « length » (Ä‘á»™ dài) không có dấu ngoặc"
+msgstr ""
+"lá»i gá»i “length†(Ä‘á»™ dài) mà không có dấu ngoặc Ä‘Æ¡n là không tÆ°Æ¡ng thích "
+"trên các hệ thống khác"
-#: awkgram.y:1578
-#, fuzzy
+#: awkgram.y:1607
msgid "indirect function calls are a gawk extension"
-msgstr "« nextfile » (tập tin kế tiếp) là một phần mở rộng gawk"
+msgstr "cuá»™c gá»i hàm gián tiếp là má»™t phần mở rá»™ng gawk"
-#: awkgram.y:1591
-#, fuzzy, c-format
+#: awkgram.y:1620
+#, c-format
msgid "can not use special variable `%s' for indirect function call"
-msgstr "chức năng « %s »: không thể dùng tên chức năng như là tên tham số"
+msgstr "không thể dùng biến đặc biệt “%s†cho cú gá»i hàm gián tiếp"
-#: awkgram.y:1669
+#: awkgram.y:1698
msgid "invalid subscript expression"
msgstr "biểu thức in thấp không hợp lệ"
-#: awkgram.y:1709
-msgid "use of non-array as array"
-msgstr "việc dùng Ä‘iá»u khác mảng nhÆ° là mảng"
-
-#: awkgram.y:1973 awkgram.y:1993 msg.c:98
+#: awkgram.y:2048 awkgram.y:2068 gawkapi.c:206 gawkapi.c:224 msg.c:126
msgid "warning: "
-msgstr "cảnh báo : "
+msgstr "cảnh báo: "
-#: awkgram.y:1991 msg.c:130
+#: awkgram.y:2066 gawkapi.c:192 gawkapi.c:221 msg.c:158
msgid "fatal: "
-msgstr "nghiêm trá»ng: "
+msgstr "lá»—i nghiêm trá»ng: "
-#: awkgram.y:2041
+#: awkgram.y:2116
msgid "unexpected newline or end of string"
-msgstr "gặp dòng mới bất ngỠhay kết thúc của chuỗi"
+msgstr "gặp dòng má»›i hay kết thúc chuá»—i bất ngá»"
-#: awkgram.y:2297 awkgram.y:2355 awkgram.y:2539
+#: awkgram.y:2383 awkgram.y:2459 awkgram.y:2682 debug.c:523 debug.c:539
+#: debug.c:2812 debug.c:5055
#, c-format
msgid "can't open source file `%s' for reading (%s)"
-msgstr "không thể mở tập tin nguồn « %s » để Ä‘á»c (%s)"
+msgstr "không thể mở tập tin nguồn “%s†để Ä‘á»c (%s)"
+
+#: awkgram.y:2384 awkgram.y:2509
+#, c-format
+msgid "can't open shared library `%s' for reading (%s)"
+msgstr "không thể mở tập thÆ° viện chia sẻ “%s†để Ä‘á»c (%s)"
-#: awkgram.y:2298 awkgram.y:2356 builtin.c:119
+#: awkgram.y:2386 awkgram.y:2460 awkgram.y:2510 builtin.c:135 debug.c:5206
msgid "reason unknown"
-msgstr "không biết sao"
+msgstr "không rõ lý do"
+
+#: awkgram.y:2395 awkgram.y:2419
+#, c-format
+msgid "can't include `%s' and use it as a program file"
+msgstr "không thể bao gồm “%s†và dùng nó như là tập tin chương trình"
-#: awkgram.y:2314
-#, fuzzy, c-format
+#: awkgram.y:2408
+#, c-format
msgid "already included source file `%s'"
-msgstr "không thể Ä‘á»c tập tin nguồn « %s » (%s)"
+msgstr "đã sẵn bao gồm tập tin nguồn “%sâ€"
+
+#: awkgram.y:2409
+#, c-format
+msgid "already loaded shared library `%s'"
+msgstr "thư viện dùng chung “%s†đã được sẵn được tải rồi"
-#: awkgram.y:2340
-#, fuzzy
+#: awkgram.y:2444
msgid "@include is a gawk extension"
-msgstr "« nextfile » (tập tin kế tiếp) là một phần mở rộng gawk"
+msgstr "@include là phần mở rộng của gawk"
-#: awkgram.y:2346
+#: awkgram.y:2450
msgid "empty filename after @include"
-msgstr ""
+msgstr "tập tin trống sau @include"
+
+#: awkgram.y:2494
+msgid "@load is a gawk extension"
+msgstr "@load là một phần mở rộng gawk"
-#: awkgram.y:2491
+#: awkgram.y:2500
+msgid "empty filename after @load"
+msgstr "tên tập tin trống sau @load"
+
+#: awkgram.y:2634
msgid "empty program text on command line"
msgstr "gặp đoạn chữ chương trình rỗng nằm trên dòng lệnh"
-#: awkgram.y:2606
+#: awkgram.y:2749
#, c-format
msgid "can't read sourcefile `%s' (%s)"
-msgstr "không thể Ä‘á»c tập tin nguồn « %s » (%s)"
+msgstr "không thể Ä‘á»c tập tin nguồn “%s†(%s)"
-#: awkgram.y:2617
+#: awkgram.y:2760
#, c-format
msgid "source file `%s' is empty"
-msgstr "tập tin nguồn « %s » là rỗng"
+msgstr "tập tin nguồn “%s†là rỗng"
-#: awkgram.y:2802
+#: awkgram.y:2937
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"
+msgstr "tập tin nguồn không kết thúc với một dòng mới"
-#: awkgram.y:2879
+#: awkgram.y:3042
msgid "unterminated regexp ends with `\\' at end of file"
msgstr ""
-"biểu thức chính quy chưa được chấm dứt kết thúc với « \\ » tại kết thúc của "
+"biểu thức chính quy chưa được chấm dứt kết thúc với “\\†tại kết thúc của "
"tập tin"
-#: awkgram.y:2903
+#: awkgram.y:3066
#, c-format
msgid "%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"
msgstr ""
-"%s: %d: bộ sửa đổi biểu thức chính quy tawk « /.../%c » không hoạt động được "
+"%s: %d: bộ sửa đổi biểu thức chính quy tawk “/.../%c†không hoạt động được "
"trong gawk"
-#: awkgram.y:2907
+#: awkgram.y:3070
#, c-format
msgid "tawk regex modifier `/.../%c' doesn't work in gawk"
msgstr ""
-"bộ sửa đổi biểu thức chính quy tawk « /.../%c » không hoạt động được trong "
-"gawk"
+"bộ sửa đổi biểu thức chính quy tawk “/.../%c†không hoạt động được trong gawk"
-#: awkgram.y:2914
+#: awkgram.y:3077
msgid "unterminated regexp"
msgstr "biểu thức chính quy chưa được chấm dứt"
-#: awkgram.y:2918
+#: awkgram.y:3081
msgid "unterminated regexp at end of file"
msgstr "biểu thức chính quy chưa được chấm dứt nằm tại kết thúc của tập tin"
-#: awkgram.y:2977
+#: awkgram.y:3140
msgid "use of `\\ #...' line continuation is not portable"
-msgstr "không thể mang khả năng dùng « \\#... » để tiếp tục dòng"
+msgstr "không thể mang khả năng dùng “\\#...†để tiếp tục dòng"
-#: awkgram.y:2993
+#: awkgram.y:3156
msgid "backslash not last character on line"
-msgstr "xuyệc ngược không phải là ký tự cuối cùng nằm trên dòng"
+msgstr "dấu gạch ngược không phải là ký tự cuối cùng nằm trên dòng"
-#: awkgram.y:3054
+#: awkgram.y:3217
msgid "POSIX does not allow operator `**='"
-msgstr "POSIX không cho phép toán tử « **= »"
+msgstr "POSIX không cho phép toán tá»­ “**=â€"
-#: awkgram.y:3056
+#: awkgram.y:3219
msgid "old awk does not support operator `**='"
-msgstr "awk cũ không hỗ trợ toán tử « **= »"
+msgstr "awk cÅ© không há»— trợ toán tá»­ “**=â€"
-#: awkgram.y:3065
+#: awkgram.y:3228
msgid "POSIX does not allow operator `**'"
-msgstr "POSIX không cho phép toán tử « ** »"
+msgstr "POSIX không cho phép toán tá»­ “**â€"
-#: awkgram.y:3067
+#: awkgram.y:3230
msgid "old awk does not support operator `**'"
-msgstr "awk cũ không hỗ trợ toán tử « ** »"
+msgstr "awk cÅ© không há»— trợ toán tá»­ “**â€"
-#: awkgram.y:3102
+#: awkgram.y:3265
msgid "operator `^=' is not supported in old awk"
-msgstr "awk cũ không hỗ trợ toán tử « ^= »"
+msgstr "awk cÅ© không há»— trợ toán tá»­ “^=â€"
-#: awkgram.y:3110
+#: awkgram.y:3273
msgid "operator `^' is not supported in old awk"
-msgstr "awk cũ không hỗ trợ toán tử « ^ »"
+msgstr "awk cÅ© không há»— trợ toán tá»­ “^â€"
-#: awkgram.y:3203 awkgram.y:3219
+#: awkgram.y:3366 awkgram.y:3382 command.y:1178
msgid "unterminated string"
msgstr "chuỗi không được chấm dứt"
-#: awkgram.y:3415
+#: awkgram.y:3603
#, c-format
msgid "invalid char '%c' in expression"
-msgstr "biểu thức một ký tự không hợp lệ « %c » nằm trong biểu thức"
+msgstr "có ký tự không hợp lệ “%c†nằm trong biểu thức"
-#: awkgram.y:3462
+#: awkgram.y:3650
#, c-format
msgid "`%s' is a gawk extension"
-msgstr "« %s » là một phần mở rộng gawk"
+msgstr "“%s†là một phần mở rộng gawk"
-#: awkgram.y:3467
-#, c-format
-msgid "`%s' is a Bell Labs extension"
-msgstr "« %s » là một phần mở rộng của Bell Labs (Phòng thí nghiệm Bell)"
-
-#: awkgram.y:3472
+#: awkgram.y:3655
#, c-format
msgid "POSIX does not allow `%s'"
-msgstr "POSIX không cho phép « %s »"
+msgstr "POSIX không cho phép “%sâ€"
-#: awkgram.y:3480
+#: awkgram.y:3663
#, c-format
msgid "`%s' is not supported in old awk"
-msgstr "awk cũ không hỗ trợ « %s »"
+msgstr "awk kiểu cÅ© không há»— trợ “%sâ€"
-#: awkgram.y:3550
+#: awkgram.y:3753
msgid "`goto' considered harmful!\n"
-msgstr "« goto » được xem là gây tai hại\n"
+msgstr "“goto†được xem là có hại!\n"
-#: awkgram.y:3602
+#: awkgram.y:3787
#, c-format
msgid "%d is invalid as number of arguments for %s"
-msgstr "« %d » không hợp lệ như là số đối số cho « %s »"
+msgstr "“%d†không hợp lệ khi là số đối số cho “%sâ€"
-#: awkgram.y:3637 awkgram.y:3640
-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:3668
+#: awkgram.y:3822
#, 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 sự thay thế, hằng mã nguồn chuỗi không có tác "
"dụng"
-#: awkgram.y:3673
+#: awkgram.y:3827
#, 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:3759 awkgram.y:3762
+#: awkgram.y:3910 awkgram.y:3913
+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:3967 awkgram.y:3970
msgid "close: second argument is a gawk extension"
msgstr "close: (đóng) đối số thứ hai là phần mở rộng gawk"
-#: awkgram.y:3774
+#: awkgram.y:3982
msgid "use of dcgettext(_\"...\") is incorrect: remove leading underscore"
-msgstr "dùng « dcgettext(_\"...\") » không đúng: hãy gỡ bỠgạch dưới nằm trước"
+msgstr "dùng “dcgettext(_\"...\")†không đúng: hãy gỡ bỠgạch dưới nằm trước"
-#: awkgram.y:3789
+#: awkgram.y:3997
msgid "use of dcngettext(_\"...\") is incorrect: remove leading underscore"
-msgstr "dùng « dcgettext(_\"...\") » không đúng: hãy gỡ bỠgạch dưới nằm trước"
+msgstr "dùng “dcgettext(_\"...\")†không đúng: hãy gỡ bỠgạch dưới nằm trước"
-#: awkgram.y:3881
-#, 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:4016
+msgid "index: regexp constant as second argument is not allowed"
+msgstr ""
+"index: (chỉ mục) không cho phép hằng biểu thức chính quy làm đối số thứ hai"
-#: awkgram.y:3923
+#: awkgram.y:4069
#, 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"
+msgstr "hàm “%sâ€: tham số “%s†che biến toàn cục"
-#: awkgram.y:4081
+#: awkgram.y:4126 debug.c:4041 debug.c:4084 debug.c:5204
#, c-format
msgid "could not open `%s' for writing (%s)"
-msgstr "không mở được «%s» để ghi (%s)"
+msgstr "không mở được “%s†để ghi (%s)"
-#: awkgram.y:4082 profile.c:85
-msgid "sending profile to standard error"
-msgstr "đang gởi hồ sơ cho thiết bị lỗi chuẩn"
+#: awkgram.y:4127
+msgid "sending variable list to standard error"
+msgstr "đang gởi danh sách biến tới thiết bị lỗi chuẩn"
-#: awkgram.y:4088
+#: awkgram.y:4135
#, c-format
msgid "%s: close failed (%s)"
-msgstr "%s: lỗi đóng (%s)"
+msgstr "%s: gặp lỗi khi đóng (%s)"
-#: awkgram.y:4140
+#: awkgram.y:4160
msgid "shadow_funcs() called twice!"
-msgstr "shadow_funcs() (hàm bóng) được gá»i hai lần !"
+msgstr "shadow_funcs() (hàm bóng) được gá»i hai lần!"
-#: awkgram.y:4146
+#: awkgram.y:4168
msgid "there were shadowed variables."
msgstr "có biến bị bóng."
-#: awkgram.y:4176
+#: awkgram.y:4239
+#, c-format
+msgid "function name `%s' previously defined"
+msgstr "tên hàm “%s†trước đây đã được định nghĩa rồi"
+
+#: awkgram.y:4285
#, c-format
msgid "function `%s': can't use function name as parameter name"
-msgstr "chức năng « %s »: không thể dùng tên chức năng như là tên tham số"
+msgstr "hàm “%sâ€: không thể dùng tên hàm nhÆ° là tên tham số"
-#: awkgram.y:4180
-#, fuzzy, c-format
+#: awkgram.y:4288
+#, c-format
msgid "function `%s': can't use special variable `%s' as a function parameter"
-msgstr "chức năng « %s »: không thể dùng tên chức năng như là tên tham số"
+msgstr "hàm “%sâ€: không thể dùng biến đặc biệt “%s†nhÆ° là tham số hàm"
-#: awkgram.y:4196
+#: awkgram.y:4296
#, c-format
-msgid "function name `%s' previously defined"
-msgstr "tên chức năng « %s » được xác định trước"
+msgid "function `%s': parameter #%d, `%s', duplicates parameter #%d"
+msgstr "hàm “%sâ€: tham số “#%dâ€, “%sâ€, nhân đôi tham số “#%dâ€"
-#: awkgram.y:4364 awkgram.y:4370
+#: awkgram.y:4383 awkgram.y:4389
#, c-format
msgid "function `%s' called but never defined"
-msgstr "chức năng « %s » được gá»i nhÆ°ng mà chÆ°a xác định"
+msgstr "hàm “%s†được gá»i nhÆ°ng mà chÆ°a định nghÄ©a"
-#: awkgram.y:4373
-#, fuzzy, c-format
+#: awkgram.y:4393
+#, c-format
msgid "function `%s' defined but never called directly"
-msgstr "chức năng « %s » được xác định nhÆ°ng mà chÆ°a được gá»i"
+msgstr "hàm “%s†được định nghÄ©a nhÆ°ng mà chÆ°a được gá»i trá»±c tiếp bao giá»"
-#: awkgram.y:4405
+#: awkgram.y:4425
#, 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ý (bun)"
+msgstr "hằng biểu thức chính quy cho tham số “#%d†làm giá trị luận lý (bun)"
-#: awkgram.y:4514
+#: awkgram.y:4484
#, 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 vá»›i dấu cách nằm giữa tên và « ( »\n"
+"hàm “%s†được gá»i vá»›i dấu cách nằm giữa tên và “(â€\n"
"hoặc được dùng như là biến hay mảng"
-#: awkgram.y:4761 eval.c:2206
+#: awkgram.y:4720
msgid "division by zero attempted"
-msgstr "cố gắng chia cho số không"
+msgstr "gặp phép chia cho số không"
-#: awkgram.y:4770 eval.c:2222
+#: awkgram.y:4729
#, c-format
msgid "division by zero attempted in `%%'"
-msgstr "cố gắng chia cho số không trong « %% »"
+msgstr "gặp phép chia cho số không trong “%%â€"
-#: builtin.c:117
+#: awkgram.y:5049
+msgid ""
+"cannot assign a value to the result of a field post-increment expression"
+msgstr "không thể gán giá trị cho kết quả của biểu thức trÆ°á»ng tăng-trÆ°á»›c"
+
+#: awkgram.y:5052
+#, c-format
+msgid "invalid target of assignment (opcode %s)"
+msgstr "gán Ä‘ich không hợp lệ (mã thi hành “%sâ€)"
+
+#: builtin.c:133
#, c-format
msgid "%s to \"%s\" failed (%s)"
-msgstr "%s tới « %s » bị lỗi (%s)"
+msgstr "%s tới “%s†gặp lỗi (%s)"
-#: builtin.c:118
+#: builtin.c:134
msgid "standard output"
-msgstr "thiết bị xuất chuẩn"
+msgstr "đầu ra tiêu chuẩn"
-#: builtin.c:132
+#: builtin.c:148
msgid "exp: received non-numeric argument"
msgstr "exp: đã nhận đối số không phải thuộc số"
-#: builtin.c:138
+#: builtin.c:154
#, c-format
msgid "exp: argument %g is out of range"
-msgstr "exp: đối số « %g » ở ngoại phạm vị"
+msgstr "exp: đối số “%g†nằm ngoài phạm vi"
-#: builtin.c:197
+#: builtin.c:229
#, 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"
+"fflush: không thể flush (đẩy dữ liệu lên Ä‘Ä©a): ống dẫn “%s†được mở để Ä‘á»c, "
+"không phải để ghi"
-#: builtin.c:200
+#: builtin.c:232
#, 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"
+"fflush: không thể flush (đẩy dữ liệu vào Ä‘Ä©a): tập tin “%s†được mở để Ä‘á»c, "
+"không phải để ghi"
-#: builtin.c:212
+#: builtin.c:244
#, c-format
msgid "fflush: `%s' is not an open file, pipe or co-process"
msgstr ""
-"fflush: « %s » không phải là tập tin đã mở, ống dẫn hay đồng tiến trình"
+"fflush: “%s†không phải là tập tin, ống dẫn hay đồng tiến trình được mở"
-#: builtin.c:330
+#: builtin.c:362
msgid "index: received non-string first argument"
-msgstr "index: (chỉ mục) đã nhận đối số thứ nhất không phải là chuỗi"
+msgstr "index: (chỉ số) đã nhận đối số thứ nhất không phải là chuỗi"
-#: builtin.c:332
+#: builtin.c:364
msgid "index: received non-string second argument"
-msgstr "index: (chỉ mục) đã nhận đối số thứ hai không phải là chuỗi"
+msgstr "index: (chỉ số) đã nhận đối số thứ hai không phải là chuỗi"
-#: builtin.c:454
+#: builtin.c:488 mpfr.c:757
msgid "int: received non-numeric argument"
msgstr "int: (số nguyên?) đã nhận đối số không phải thuộc số"
-#: builtin.c:490
-#, fuzzy
+#: builtin.c:525
msgid "length: received array argument"
-msgstr "length: (độ dài) đã nhận đối số không phải chuỗi"
+msgstr "length: (chiá»u dài) đã nhận mảng đối số"
-#: builtin.c:493
-#, fuzzy
+#: builtin.c:528
msgid "`length(array)' is a gawk extension"
-msgstr "« length(array) » (độ dài mảng) là một phần mở rộng gawk"
+msgstr "“length(array)†(độ dài mảng) là một phần mở rộng gawk"
-#: builtin.c:501
+#: builtin.c:544
msgid "length: received non-string argument"
-msgstr "length: (độ dài) đã nhận đối số không phải chuỗi"
+msgstr "length: (chiá»u dài) đã nhận đối số không phải chuá»—i"
-#: builtin.c:532
+#: builtin.c:575
msgid "log: received non-numeric argument"
-msgstr "log: (bản ghi) đã nhận đối số không phải thuộc số"
+msgstr "log: (nhật ký) đã nhận đối số không phải thuộc số"
-#: builtin.c:535
+#: builtin.c:578
#, c-format
msgid "log: received negative argument %g"
-msgstr "log: (bản ghi) đã nhận đối số âm «%g»"
+msgstr "log: (nhật ký) đã nhận đối số âm “%gâ€"
+
+#: builtin.c:776 builtin.c:781
+msgid "fatal: must use `count$' on all formats or none"
+msgstr "lá»—i nghiêm trá»ng: phải dùng “count$†vá»›i má»i dạng thức hay không gì cả"
+
+#: builtin.c:851
+#, c-format
+msgid "field width is ignored for `%%' specifier"
+msgstr "chiá»u rá»™ng trÆ°á»ng bị bá» qua đối vá»›i bá»™ chỉ định “%%â€"
+
+#: builtin.c:853
+#, c-format
+msgid "precision is ignored for `%%' specifier"
+msgstr "Ä‘á»™ chính xác bị bá» qua đối vá»›i bá»™ chỉ định “%%â€"
+
+#: builtin.c:855
+#, c-format
+msgid "field width and precision are ignored for `%%' specifier"
+msgstr "chiá»u rá»™ng trÆ°á»ng và Ä‘á»™ chính xác bị bá» qua đối vá»›i bá»™ chỉ định “%%â€"
+
+#: builtin.c:906
+msgid "fatal: `$' is not permitted in awk formats"
+msgstr "lá»—i nghiêm trá»ng: không cho phép “$†trong định dạng awk"
+
+#: builtin.c:915
+msgid "fatal: arg count with `$' must be > 0"
+msgstr "lá»—i nghiêm trá»ng: số lượng đối số vá»›i “$†phải >0"
+
+#: builtin.c:919
+#, c-format
+msgid "fatal: arg count %ld greater than total number of supplied arguments"
+msgstr ""
+"lá»—i nghiêm trá»ng: số lượng đối số %ld lá»›n hÆ¡n tổng số đối số được cung cấp"
+
+#: builtin.c:923
+msgid "fatal: `$' not permitted after period in format"
+msgstr "lá»—i nghiêm trá»ng: không cho phép “$†nằm sau dấu chấm trong định dạng"
+
+#: builtin.c:939
+msgid "fatal: no `$' supplied for positional field width or precision"
+msgstr ""
+"lá»—i nghiêm trá»ng: chÆ°a cung cấp “$†cho Ä‘á»™ rá»™ng trÆ°á»ng thuá»™c vị trí hay cho "
+"độ chính xác"
+
+#: builtin.c:1009
+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:1013
+msgid "fatal: `l' is not permitted in POSIX awk formats"
+msgstr "lá»—i nghiêm trá»ng: không cho phép chữ “l†nằm trong định dạng awk POSIX"
+
+#: builtin.c:1026
+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:1030
+msgid "fatal: `L' is not permitted in POSIX awk formats"
+msgstr "lá»—i nghiêm trá»ng: không cho phép chữ “L†nằm trong định dạng awk POSIX"
-#: builtin.c:593 builtin.c:604
+#: builtin.c:1043
+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:1047
+msgid "fatal: `h' is not permitted in POSIX awk formats"
+msgstr "lá»—i nghiêm trá»ng: không cho phép chữ “h†nằm trong định dạng awk POSIX"
+
+#: builtin.c:1463
+#, c-format
+msgid "[s]printf: value %g is out of range for `%%%c' format"
+msgstr "[s]printf: giá trị %g ở ngoại phạm vi cho dạng thức “%%%câ€"
+
+#: builtin.c:1561
+#, c-format
+msgid "ignoring unknown format specifier character `%c': no argument converted"
+msgstr ""
+"Ä‘ang bá» qua ký tá»± ghi rõ định dạng không rõ “%câ€: không có đối số được "
+"chuyển đổi"
+
+#: builtin.c:1566
+msgid "fatal: not enough arguments to satisfy format string"
+msgstr "lá»—i nghiêm trá»ng: chÆ°a có đủ đối số để đáp ứng chuá»—i định dạng"
+
+#: builtin.c:1568
+msgid "^ ran out for this one"
+msgstr "bị hết “^†cho cái này"
+
+#: builtin.c:1575
+msgid "[s]printf: format specifier does not have control letter"
+msgstr "[s]printf: chỉ định định dạng không có ký hiệu Ä‘iá»u khiển"
+
+#: builtin.c:1578
+msgid "too many arguments supplied for format string"
+msgstr "quá nhiá»u đối số được cung cấp cho chuá»—i định dạng"
+
+#: builtin.c:1634
+msgid "sprintf: no arguments"
+msgstr "sprintf: không có đối số"
+
+#: builtin.c:1657 builtin.c:1668
msgid "printf: no arguments"
msgstr "printf: không có đối số"
-#: builtin.c:645
+#: builtin.c:1711
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:649
+#: builtin.c:1715
#, c-format
msgid "sqrt: called with negative argument %g"
-msgstr "sqrt: (căn bậc hai) đã gá»i vá»›i đối số âm «%g»"
+msgstr "sqrt: (căn bậc hai) đã gá»i vá»›i đối số âm “%gâ€"
-#: builtin.c:673
+#: builtin.c:1746
#, c-format
msgid "substr: length %g is not >= 1"
-msgstr "substr: (chuỗi phụ) độ dài %g không phải ≥1"
+msgstr "substr: (chuỗi con) độ dài %g không phải ≥1"
-#: builtin.c:675
+#: builtin.c:1748
#, c-format
msgid "substr: length %g is not >= 0"
-msgstr "substr: (chuỗi phụ) độ dài %g không phải ≥0"
+msgstr "substr: (chuỗi con) độ dài %g không phải ≥0"
-#: builtin.c:682
+#: builtin.c:1755
#, c-format
msgid "substr: non-integer length %g will be truncated"
-msgstr "substr: (chuỗi phụ) sẽ cắt xén độ dài không phải số nguyên « %g »"
+msgstr "substr: (chuá»—i con) sẽ cắt xén Ä‘á»™ dài không phải số nguyên “%gâ€"
-#: builtin.c:687
+#: builtin.c:1760
#, c-format
msgid "substr: length %g too big for string indexing, truncating to %g"
-msgstr "substr: độ dài %g quá lớn để chỉ mục chuỗi nên xén ngắn thành %g"
+msgstr ""
+"substr: (chuỗi con) độ dài %g là quá lớn cho chỉ số chuỗi, nên xén ngắn "
+"thành %g"
-#: builtin.c:699
+#: builtin.c:1772
#, c-format
msgid "substr: start index %g is invalid, using 1"
-msgstr "substr: (chuỗi phụ) số chỉ mục đầu « %g » không hợp lệ nên dùng 1"
+msgstr "substr: (chuỗi con) chỉ số đầu “%g†không hợp lệ nên dùng 1"
-#: builtin.c:704
+#: builtin.c:1777
#, c-format
msgid "substr: non-integer start index %g will be truncated"
msgstr ""
-"substr: (chuỗi phụ) số chỉ mục đầu không phải số nguyên « %g » sẽ bị cắt ngắn"
+"substr: (chuỗi con) chỉ số đầu không phải số nguyên “%g†sẽ bị cắt ngắn"
-#: builtin.c:729
+#: builtin.c:1802
msgid "substr: source string is zero length"
msgstr "substr: (chuỗi con) chuỗi nguồn có độ dài số không"
-#: builtin.c:745
+#: builtin.c:1818
#, c-format
msgid "substr: start index %g is past end of string"
-msgstr "substr: (chuỗi phụ) số chỉ mục đầu %g nằm sau kết thúc của chuỗi"
+msgstr "substr: (chuỗi con) chỉ số đầu %g nằm sau kết thúc của chuỗi"
-#: builtin.c:753
+#: builtin.c:1826
#, c-format
msgid ""
"substr: length %g at start index %g exceeds length of first argument (%lu)"
msgstr ""
-"substr: (chuỗi phụ) độ dài %g tại số chỉ mục đầu %g vượt quá độ dài của đối "
-"số đầu (%lu)"
+"substr: (chuỗi con) độ dài %g chỉ số đầu %g vượt quá độ dài của đối số đầu "
+"(%lu)"
-#: builtin.c:826
+#: builtin.c:1900
msgid "strftime: format value in PROCINFO[\"strftime\"] has numeric type"
msgstr ""
+"strftime: giá trị định dạng trong PROCINFO[â€strftimeâ€] phải thuá»™c kiểu số"
-#: builtin.c:840
+#: builtin.c:1923
msgid "strftime: received non-numeric second argument"
msgstr "strftime: đã nhận đối số thứ hai khác thuộc số"
-#: builtin.c:847
+#: builtin.c:1927
+msgid "strftime: second argument less than 0 or too big for time_t"
+msgstr "strftime: tham số thứ hai nhỠhơn 0 hay quá lớn dành cho time_t"
+
+#: builtin.c:1934
msgid "strftime: received non-string first argument"
msgstr "strftime: đã nhận đối số thứ nhất khác chuỗi"
-#: builtin.c:853
+#: builtin.c:1941
msgid "strftime: received empty format string"
msgstr "strftime: đã nhận chuỗi định dạng rỗng"
-#: builtin.c:919
+#: builtin.c:2007
msgid "mktime: received non-string argument"
msgstr "mktime: đã nhận đối số khác chuỗi"
-#: builtin.c:936
+#: builtin.c:2024
msgid "mktime: at least one of the values is out of the default range"
-msgstr ""
+msgstr "mktime: ít nhất một của những giá trị nằm ở ngoại phạm vi mặc định"
-#: builtin.c:971
+#: builtin.c:2059
msgid "'system' function not allowed in sandbox mode"
-msgstr ""
+msgstr "hàm “system†không cho phép ở chế độ khuôn đúc"
-#: builtin.c:976
+#: builtin.c:2064
msgid "system: received non-string argument"
msgstr "system: (hệ thống) đã nhận đối số khác chuỗi"
-#: builtin.c:1031 eval.c:1411 eval.c:1936 eval.c:1949
-#, c-format
-msgid "reference to uninitialized variable `%s'"
-msgstr "gặp tham chiếu đến biến chưa được sở khởi « %s »"
-
-#: builtin.c:1098
+#: builtin.c:2184
#, c-format
msgid "reference to uninitialized field `$%d'"
-msgstr "gặp tham chiếu đến trÆ°á»ng chÆ°a được sở khởi « $%d »"
+msgstr "gặp tham chiếu đến trÆ°á»ng chÆ°a được khởi tạo “$%dâ€"
-#: builtin.c:1185
+#: builtin.c:2271
msgid "tolower: received non-string argument"
msgstr "tolower: (đến thấp hơn) đã nhận đối số khác chuỗi"
-#: builtin.c:1219
+#: builtin.c:2305
msgid "toupper: received non-string argument"
msgstr "toupper: (đến cao hơn) đã nhận đối số khác chuỗi"
-#: builtin.c:1255
+#: builtin.c:2341 mpfr.c:672
msgid "atan2: received non-numeric first argument"
msgstr "atan2: đã nhận đối số thứ nhất khác thuộc số"
-#: builtin.c:1257
+#: builtin.c:2343 mpfr.c:674
msgid "atan2: received non-numeric second argument"
msgstr "atan2: đã nhận đối số thứ hai khác thuộc số"
-#: builtin.c:1276
+#: builtin.c:2362
msgid "sin: received non-numeric argument"
msgstr "sin: đã nhận đối số không phải thuộc số"
-#: builtin.c:1292
+#: builtin.c:2378
msgid "cos: received non-numeric argument"
msgstr "cos: đã nhận đối số không phải thuộc số"
-#: builtin.c:1345
+#: builtin.c:2431 mpfr.c:1156
msgid "srand: received non-numeric argument"
msgstr "srand: đã nhận đối số không phải thuộc số"
-#: builtin.c:1376
+#: builtin.c:2462
msgid "match: third argument is not an array"
msgstr "match: (khớp) đối số thứ ba không phải là mảng"
-#: builtin.c:1883
+#: builtin.c:2734
msgid "gensub: third argument of 0 treated as 1"
-msgstr "gensub: đối số thứ ba 0 được xử lý như 1"
+msgstr "gensub: đối số thứ ba của 0 được xử lý như 1"
-#: builtin.c:1923
+#: builtin.c:3030
msgid "lshift: received non-numeric first argument"
msgstr "lshift: đã nhận đối số đầu không phải thuộc số"
-#: builtin.c:1925
+#: builtin.c:3032
msgid "lshift: received non-numeric second argument"
msgstr "lshift: (dịch bên trái) đã nhận đối số thứ hai khác thuộc số"
-#: builtin.c:1931
+#: builtin.c:3038
#, c-format
-msgid "lshift(%lf, %lf): negative values will give strange results"
-msgstr "lshift(%lf, %lf): giá trị âm sẽ gây ra kết quả lạ"
+msgid "lshift(%f, %f): negative values will give strange results"
+msgstr "lshift(%f, %f): giá trị âm sẽ gây ra kết quả không như mong muốn"
-#: builtin.c:1933
+#: builtin.c:3040
#, c-format
-msgid "lshift(%lf, %lf): fractional values will be truncated"
-msgstr "lshift(%lf, %lf): giá trị thuộc phân số sẽ bị xén ngắn"
+msgid "lshift(%f, %f): fractional values will be truncated"
+msgstr "lshift(%f, %f): giá trị thuộc phân số sẽ bị cắt ngắn"
-#: builtin.c:1935
+#: builtin.c:3042
#, 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 sẽ gây ra kết quả lạ"
+msgid "lshift(%f, %f): too large shift value will give strange results"
+msgstr ""
+"lshift(%f, %f): giá trị dịch quá lớn sẽ gây ra kết quả không như mong muốn"
-#: builtin.c:1960
+#: builtin.c:3067
msgid "rshift: received non-numeric first argument"
msgstr "rshift: đã nhận đối số thứ nhất khác thuộc số"
-#: builtin.c:1962
+#: builtin.c:3069
msgid "rshift: received non-numeric second argument"
-msgstr "rshift: (dịch bên phải) đã nhận đối số thứ hai khác thuộc số"
+msgstr "rshift: (dịch phải) đã nhận đối số thứ hai khác thuộc số"
-#: builtin.c:1968
+#: builtin.c:3075
#, c-format
-msgid "rshift(%lf, %lf): negative values will give strange results"
-msgstr "rshift(%lf, %lf): giá trị âm sẽ gây ra kết quả lạ"
+msgid "rshift(%f, %f): negative values will give strange results"
+msgstr "rshift(%f, %f): giá trị âm sẽ gây ra kết quả không như mong muốn"
-#: builtin.c:1970
+#: builtin.c:3077
#, c-format
-msgid "rshift(%lf, %lf): fractional values will be truncated"
-msgstr "rshift(%lf, %lf): giá trị thuộc phân số sẽ bị xén ngắn"
+msgid "rshift(%f, %f): fractional values will be truncated"
+msgstr "rshift(%f, %f): giá trị thuộc kiểu phân số sẽ bị xén ngắn"
-#: builtin.c:1972
+#: builtin.c:3079
#, 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 sẽ gây ra kết quả lạ"
+msgid "rshift(%f, %f): too large shift value will give strange results"
+msgstr ""
+"rshift(%f, %f): giá trị dịch quá lớn sẽ gây ra kết quả không như mong muốn"
-#: builtin.c:1997
-msgid "and: received non-numeric first argument"
-msgstr "and: (và) đã nhận đối số đầu không phải thuộc số"
+#: builtin.c:3104 mpfr.c:968
+msgid "and: called with less than two arguments"
+msgstr "and: được gá»i vá»›i ít hÆ¡n hai đối số"
-#: builtin.c:1999
-msgid "and: received non-numeric second argument"
-msgstr "and: (và) đã nhận đối số thứ hai khác thuộc số"
+#: builtin.c:3109
+#, c-format
+msgid "and: argument %d is non-numeric"
+msgstr "and: đối số %d không phải thuộc số"
-#: builtin.c:2005
+#: builtin.c:3113
#, c-format
-msgid "and(%lf, %lf): negative values will give strange results"
-msgstr "and(%lf, %lf): (và) giá trị âm sẽ gây ra kết quả lạ"
+msgid "and: argument %d negative value %g will give strange results"
+msgstr ""
+"and: (và) đối số %d giá trị âm %g sẽ đưa lại kết quả không như mong muốn"
-#: builtin.c:2007
+#: builtin.c:3136 mpfr.c:1000
+msgid "or: called with less than two arguments"
+msgstr "or: (hoặc) được gá»i vá»›i ít hÆ¡n hai đối số"
+
+#: builtin.c:3141
#, c-format
-msgid "and(%lf, %lf): fractional values will be truncated"
-msgstr "and(%lf, %lf): (và) giá trị thuộc phân số sẽ bị xén ngắn"
+msgid "or: argument %d is non-numeric"
+msgstr "or: (hoặc) đối số %d không thuộc kiểu số"
-#: builtin.c:2032
-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:3145
+#, c-format
+msgid "or: argument %d negative value %g will give strange results"
+msgstr ""
+"or: (hoặc) đối số %d giá trị âm %g sẽ đưa lại kết quả không như mong muốn"
-#: builtin.c:2034
-msgid "or: received non-numeric second argument"
-msgstr "or: (hoặc) đã nhận đối số thứ hai khác thuộc số"
+#: builtin.c:3167 mpfr.c:1031
+msgid "xor: called with less than two arguments"
+msgstr "xor: được gá»i vá»›i ít hÆ¡n hai đối số"
-#: builtin.c:2040
+#: builtin.c:3173
#, c-format
-msgid "or(%lf, %lf): negative values will give strange results"
-msgstr "or(%lf, %lf): (hoặc) giá trị âm sẽ gây ra kết quả lạ"
+msgid "xor: argument %d is non-numeric"
+msgstr "xor: đối số %d không thuộc kiểu số"
-#: builtin.c:2042
+#: builtin.c:3177
#, c-format
-msgid "or(%lf, %lf): fractional values will be truncated"
-msgstr "or(%lf, %lf): (hoặc) giá trị thuộc phân số sẽ bị xén ngắn"
+msgid "xor: argument %d negative value %g will give strange results"
+msgstr "xor: đối số %d giá trị âm %g sẽ đưa lại kết quả không như mong muốn"
-#: builtin.c:2070
-msgid "xor: received non-numeric first argument"
-msgstr "xor: (không hoặc) đã nhận đối số thứ nhất khác thuộc số"
+#: builtin.c:3202 mpfr.c:787
+msgid "compl: received non-numeric argument"
+msgstr "compl: (biên dịch) đã nhận được đối số không-phải-số"
-#: builtin.c:2072
-msgid "xor: received non-numeric second argument"
-msgstr "xor: đã nhận đối số thứ hai khác thuộc số"
+#: builtin.c:3208
+#, c-format
+msgid "compl(%f): negative value will give strange results"
+msgstr "compl(%f): giá trị âm sẽ gây ra kết quả không như mong đợi"
-#: builtin.c:2078
+#: builtin.c:3210
#, c-format
-msgid "xor(%lf, %lf): negative values will give strange results"
-msgstr "xor(%lf, %lf): (không hoặc) giá trị âm sẽ gây ra kết quả lạ"
+msgid "compl(%f): fractional value will be truncated"
+msgstr "compl(%f): giá trị thuộc phân số sẽ bị cắt ngắn"
-#: builtin.c:2080
+#: builtin.c:3379
#, 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ố sẽ bị xén ngắn"
+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ệ"
-#: builtin.c:2104 builtin.c:2110
-msgid "compl: received non-numeric argument"
-msgstr "compl: (biên dịch) đã nhận đối số khác thuộc số"
+#: command.y:225
+#, c-format
+msgid "Type (g)awk statement(s). End with the command \"end\"\n"
+msgstr "Gõ các câu lệnh (g)awk. Kết thúc bằng lệnh “endâ€\n"
-#: builtin.c:2112
+#: command.y:289
#, c-format
-msgid "compl(%lf): negative value will give strange results"
-msgstr "compl(%lf): (biên dịch) giá trị âm sẽ gây ra kết quả lạ"
+msgid "invalid frame number: %d"
+msgstr "số khung không hợp lệ: %d"
-#: builtin.c:2114
+#: command.y:295
#, c-format
-msgid "compl(%lf): fractional value will be truncated"
-msgstr "compl(%lf): (biên dịch) giá trị thuộc phân số se bị xén ngắn"
+msgid "info: invalid option - \"%s\""
+msgstr "info: tùy chá»n không hợp lệ - “%sâ€"
-#: builtin.c:2283
+#: command.y:321
#, 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ệ"
+msgid "source \"%s\": already sourced."
+msgstr "nguồn “%sâ€: đã sẵn có trong nguồn rồi."
+
+#: command.y:326
+#, c-format
+msgid "save \"%s\": command not permitted."
+msgstr "ghi “%sâ€: lệnh không đủ thẩm quyá»n."
+
+#: command.y:339
+msgid "Can't use command `commands' for breakpoint/watchpoint commands"
+msgstr "Không thể dùng lệnh “commands†cho lệnh breakpoint/watchpoint"
+
+#: command.y:341
+msgid "no breakpoint/watchpoint has been set yet"
+msgstr "chưa có điểm ngắt hay điểm theo dõi nào được đặt cả"
+
+#: command.y:343
+msgid "invalid breakpoint/watchpoint number"
+msgstr "số điểm ngắt hay điểm theo dõi không hợp lệ"
+
+#: command.y:348
+#, c-format
+msgid "Type commands for when %s %d is hit, one per line.\n"
+msgstr "Gõ lệnh cho %s khi %d được gợi ý, mỗi lệnh một dòng.\n"
+
+#: command.y:350
+#, c-format
+msgid "End with the command \"end\"\n"
+msgstr "Kết thúc vá»›i lệnh “endâ€\n"
+
+#: command.y:357
+msgid "`end' valid only in command `commands' or `eval'"
+msgstr "“end†chỉ hợp lệ trong “commands†hay “evalâ€"
+
+#: command.y:367
+msgid "`silent' valid only in command `commands'"
+msgstr "“silent†chỉ hợp lệ vá»›i lệnh “commandsâ€"
+
+#: command.y:373
+#, c-format
+msgid "trace: invalid option - \"%s\""
+msgstr "trace: tùy chá»n không hợp lệ - “%sâ€"
+
+#: command.y:387
+msgid "condition: invalid breakpoint/watchpoint number"
+msgstr "condition: Ä‘iá»u kiện: số hiệu Ä‘iểm ngắt hay Ä‘iểm theo dõi không hợp lệ"
+
+#: command.y:449
+msgid "argument not a string"
+msgstr "tham số không phải là một chuỗi"
+
+#: command.y:459 command.y:464
+#, c-format
+msgid "option: invalid parameter - \"%s\""
+msgstr "option: tùy chá»n không hợp lệ - “%sâ€"
+
+#: command.y:474
+#, c-format
+msgid "no such function - \"%s\""
+msgstr "không có hàm nào nhÆ° thế cả - “%sâ€"
+
+#: command.y:531
+#, c-format
+msgid "enable: invalid option - \"%s\""
+msgstr "enable: tùy chá»n không hợp lệ - “%sâ€"
+
+#: command.y:597
+#, c-format
+msgid "invalid range specification: %d - %d"
+msgstr "đặc tả vùng không hợp lệ: %d - %d"
+
+#: command.y:659
+msgid "non-numeric value for field number"
+msgstr "giá trị cho trÆ°á»ng số mà không thuá»™c kiểu số"
+
+#: command.y:680 command.y:687
+msgid "non-numeric value found, numeric expected"
+msgstr "cần giá trị kiểu số nhưng lại nhận được giá trị không thuộc kiểu này"
+
+#: command.y:712 command.y:718
+msgid "non-zero integer value"
+msgstr "giá trị số nguyên khác không"
+
+#: command.y:817
+msgid ""
+"backtrace [N] - print trace of all or N innermost (outermost if N < 0) "
+"frames."
+msgstr ""
+"backtrace [N] - in vết của tất cả hay N khung trong cùng nhất (ngoài cùng "
+"nhất nếu N < 0)."
+
+#: command.y:819
+msgid ""
+"break [[filename:]N|function] - set breakpoint at the specified location."
+msgstr "break [[tên_tập_tin:]N|hàm] - đặt điểm ngắt tại vị trí đã cho."
+
+#: command.y:821
+msgid "clear [[filename:]N|function] - delete breakpoints previously set."
+msgstr ""
+"clear [[tên_tập_tin:]N|function] - xóa các điểm ngắt được đặt trước đây."
+
+#: command.y:823
+msgid ""
+"commands [num] - starts a list of commands to be executed at a "
+"breakpoint(watchpoint) hit."
+msgstr ""
+"commands [số] - chạy một danh sách các câu lệnh được thực thi tại điểm ngắt "
+"(hay điểm theo dõi) tìm được."
+
+#: command.y:825
+msgid "condition num [expr] - set or clear breakpoint or watchpoint condition."
+msgstr ""
+"condition num [expr] - đặt hay xóa Ä‘iểm ngắt hay Ä‘iá»u kiện Ä‘iểm theo dõi."
+
+#: command.y:827
+msgid "continue [COUNT] - continue program being debugged."
+msgstr "continue [Sá»_LƯỢNG] - tiếp tục chÆ°Æ¡ng trình Ä‘ang được gỡ lá»—i."
+
+#: command.y:829
+msgid "delete [breakpoints] [range] - delete specified breakpoints."
+msgstr "delete [điểm_ngắt] [vùng] - xóa các điểm ngắt đã chỉ ra."
+
+#: command.y:831
+msgid "disable [breakpoints] [range] - disable specified breakpoints."
+msgstr "disable [điểm_ngắt] [vùng] - tắt các điểm ngắt đã chỉ định."
+
+#: command.y:833
+msgid "display [var] - print value of variable each time the program stops."
+msgstr "display [var] - in giá trị của biến mỗi lần chương trình dừng."
+
+#: command.y:835
+msgid "down [N] - move N frames down the stack."
+msgstr "down [N] - chuyển xuống N khung stack."
+
+#: command.y:837
+msgid "dump [filename] - dump instructions to file or stdout."
+msgstr ""
+"dump [tên_tập_tin] - dump các chỉ lệnh ra tập tin hay đầu ra tiêu chuẩn."
+
+#: command.y:839
+msgid "enable [once|del] [breakpoints] [range] - enable specified breakpoints."
+msgstr "enable [once|del] [điểm_ngắt] [range] - bật các điểm ngắt đã chỉ ra."
+
+#: command.y:841
+msgid "end - end a list of commands or awk statements."
+msgstr "end - kết thúc một danh sách các câu lệnh hay biểu thức awk"
+
+#: command.y:843
+msgid "eval stmt|[p1, p2, ...] - evaluate awk statement(s)."
+msgstr "eval stmt|[p1, p2, ...] - định giá các câu lệnh awk."
+
+#: command.y:845
+msgid "finish - execute until selected stack frame returns."
+msgstr "finish - thá»±c thi cho đến khi khung stack đã chá»n trả vá»."
+
+#: command.y:847
+msgid "frame [N] - select and print stack frame number N."
+msgstr "frame [N] - chá»n và in khung stack số hiệu N."
+
+#: command.y:849
+msgid "help [command] - print list of commands or explanation of command."
+msgstr "help [lệnh] - hiển thị danh sách các lệnh hay giải thích câu lệnh."
+
+#: command.y:851
+msgid "ignore N COUNT - set ignore-count of breakpoint number N to COUNT."
+msgstr "ignore N Sá»-LƯỢNG - đặt số lượng Ä‘iểm ngắt bị bá» qua."
+
+#: command.y:853
+msgid ""
+"info topic - source|sources|variables|functions|break|frame|args|locals|"
+"display|watch."
+msgstr ""
+"info chủ_đỠ- nguồn|nguồn|biến|hàm|break|frame|args|locals|display|watch."
+
+#: command.y:855
+msgid "list [-|+|[filename:]lineno|function|range] - list specified line(s)."
+msgstr "list [-|+|[tập_tin:]số_dòng|hàm|vùng] - liệt kê các dòng đã chỉ định."
+
+#: command.y:857
+msgid "next [COUNT] - step program, proceeding through subroutine calls."
+msgstr ""
+"next [Sá»_LƯỢNG] - nhảy má»™t chỉ lệnh, nhÆ°ng được xá»­ lý thông qua gá»i thủ "
+"tục con."
+
+#: command.y:859
+msgid ""
+"nexti [COUNT] - step one instruction, but proceed through subroutine calls."
+msgstr ""
+"nexti [Sá»_LƯỢNG] - nhảy từng chỉ lệnh, nhÆ°ng được xá»­ lý thông qua gá»i thủ "
+"tục con."
+
+#: command.y:861
+msgid "option [name[=value]] - set or display debugger option(s)."
+msgstr "option [tên[=giá trị]] - đặt hay hiển thị tùy chá»n gỡ lá»—i."
+
+#: command.y:863
+msgid "print var [var] - print value of a variable or array."
+msgstr "print var [var] - in giá trị của biến hay mảng."
+
+#: command.y:865
+msgid "printf format, [arg], ... - formatted output."
+msgstr "printf format, [arg], ... - kết xuất có định dạng."
+
+#: command.y:867
+msgid "quit - exit debugger."
+msgstr "quit - thoát khá»i chÆ°Æ¡ng trình gỡ lá»—i."
+
+#: command.y:869
+msgid "return [value] - make selected stack frame return to its caller."
+msgstr ""
+"return [giá-trị] - làm cho khung stack đã chá»n trả vá» giá trị này cho bá»™ gá»i "
+"nó."
+
+#: command.y:871
+msgid "run - start or restart executing program."
+msgstr "run - khởi chạy hay khởi động lại chương trình."
+
+#: command.y:874
+msgid "save filename - save commands from the session to file."
+msgstr "save tên_tập_tin - ghi các câu lệnh từ phiên làm việc vào tập tin."
+
+#: command.y:877
+msgid "set var = value - assign value to a scalar variable."
+msgstr "set biến = giá_trị - gán giá trị cho một biến vô hướng."
+
+#: command.y:879
+msgid ""
+"silent - suspends usual message when stopped at a breakpoint/watchpoint."
+msgstr ""
+"silent - chặn các lá»i nhắn thông thÆ°á»ng khi dừng tại Ä‘iểm ngăt hay Ä‘iểm theo "
+"dõi."
+
+#: command.y:881
+msgid "source file - execute commands from file."
+msgstr "source file - thực hiện các câu lệnh từ tập tin."
+
+#: command.y:883
+msgid "step [COUNT] - step program until it reaches a different source line."
+msgstr ""
+"step [Sá»_LƯỢNG] - chạy từng bÆ°á»›c chÆ°Æ¡ng trình cho đến khi nó gặp má»™t dòng "
+"nguồn khác."
+
+#: command.y:885
+msgid "stepi [COUNT] - step one instruction exactly."
+msgstr "stepi [Sá»_LƯỢNG] - chạy từng lệnh má»™t."
+
+#: command.y:887
+msgid "tbreak [[filename:]N|function] - set a temporary breakpoint."
+msgstr "tbreak [[tên_tập_tin:]N|hàm] - đặt Ä‘iểm ngắt tạm thá»i."
+
+#: command.y:889
+msgid "trace on|off - print instruction before executing."
+msgstr "trace on|off - hiển thị chỉ lệnh trước khi thực hiện."
+
+#: command.y:891
+msgid "undisplay [N] - remove variable(s) from automatic display list."
+msgstr "undisplay [N] - gỡ bỠcác biến từ danh sách hiển thị tự động."
+
+#: command.y:893
+msgid ""
+"until [[filename:]N|function] - execute until program reaches a different "
+"line or line N within current frame."
+msgstr ""
+"until [[tên_tập_tin:]N|hàm] - thực hiện cho đến khi chương trình đạt đến "
+"dòng khác hay dòng N trong khung hiện tại."
+
+#: command.y:895
+msgid "unwatch [N] - remove variable(s) from watch list."
+msgstr "unwatch [N] - gỡ bỠcác biến từ danh sách theo dõi."
+
+#: command.y:897
+msgid "up [N] - move N frames up the stack."
+msgstr "up [N] - chuyển xuống N khung stack."
+
+#: command.y:899
+msgid "watch var - set a watchpoint for a variable."
+msgstr "watch var - đặt điểm theo dõi cho một biến."
+
+#: command.y:1011 debug.c:401 msg.c:135
+#, c-format
+msgid "error: "
+msgstr "lá»—i: "
+
+#: command.y:1051
+#, c-format
+msgid "can't read command (%s)\n"
+msgstr "không thể Ä‘á»c lệnh (%s)\n"
+
+#: command.y:1065
+#, c-format
+msgid "can't read command (%s)"
+msgstr "không thể Ä‘á»c lệnh (%s)"
+
+#: command.y:1116
+msgid "invalid character in command"
+msgstr "ký tự trong câu lệnh không hợp lệ"
+
+#: command.y:1152
+#, c-format
+msgid "unknown command - \"%.*s\", try help"
+msgstr "không hiểu lệnh - “%.*sâ€, hãy gõ lệnh trợ giúp “helpâ€"
+
+#: command.y:1222
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: command.y:1284
+msgid "invalid character"
+msgstr "ký tự không hợp lệ"
+
+#: command.y:1455
+#, c-format
+msgid "undefined command: %s\n"
+msgstr "lệnh chưa định nghĩa: %s\n"
+
+#: debug.c:252
+msgid "set or show the number of lines to keep in history file."
+msgstr "đặt hay hiển thị số dòng được lưu giữ trong tập tin lịch sử."
+
+#: debug.c:254
+msgid "set or show the list command window size."
+msgstr "đặt hay hiển thị kích thước cửa sổ danh sách lệnh."
+
+#: debug.c:256
+msgid "set or show gawk output file."
+msgstr "đặt hay hiển thị tập tin kết xuất gawk."
+
+#: debug.c:258
+msgid "set or show debugger prompt."
+msgstr "đặt hay hiển thị dấu nhắc gỡ lỗi."
+
+#: debug.c:260
+msgid "(un)set or show saving of command history (value=on|off)."
+msgstr "(bá») đặt hay ghi lại lịch sá»­ lệnh (giá trị=on|off)."
+
+#: debug.c:262
+msgid "(un)set or show saving of options (value=on|off)."
+msgstr "đặt/bỠđặt hay hiển thị các tùy chá»n được ghi lại (giá_trị=on|off)."
+
+#: debug.c:264
+msgid "(un)set or show instruction tracing (value=on|off)."
+msgstr "(bá») đặt hay hiển thị việc theo vết chỉ lệnh (giá trị=on|off)."
+
+#: debug.c:345
+msgid "program not running."
+msgstr "chương trình không chạy."
+
+#: debug.c:448 debug.c:606
+#, c-format
+msgid "can't read source file `%s' (%s)"
+msgstr "không thể Ä‘á»c tập tin nguồn “%s†(%s)"
+
+#: debug.c:453
+#, c-format
+msgid "source file `%s' is empty.\n"
+msgstr "tập tin nguồn “%s†bị trống rỗng.\n"
+
+#: debug.c:480
+msgid "no current source file."
+msgstr "không có tập tin nguồn hiện tại."
+
+#: debug.c:505
+#, c-format
+msgid "cannot find source file named `%s' (%s)"
+msgstr "không thể tìm thấy tập tin nguồn có tên “%s†(%s)"
+
+#: debug.c:529
+#, c-format
+msgid "WARNING: source file `%s' modified since program compilation.\n"
+msgstr "CẢNH BÃO: tập tin nguồn “%s†bị sá»­a đổi kể từ lúc nó được dịch.\n"
+
+#: debug.c:551
+#, c-format
+msgid "line number %d out of range; `%s' has %d lines"
+msgstr "số dòng %d nằm ngoài phạm vi; “%s†có %d dòng"
+
+#: debug.c:611
+#, c-format
+msgid "unexpected eof while reading file `%s', line %d"
+msgstr "gặp kết thúc tập tin bất ngá» khi Ä‘ang Ä‘á»c tập tin “%sâ€, dòng %d"
+
+#: debug.c:620
+#, c-format
+msgid "source file `%s' modified since start of program execution"
+msgstr "tập tin nguồn “%s†đã bị sửa đổi kể từ lúc chưong trình được khởi chạy"
+
+#: debug.c:732
+#, c-format
+msgid "Current source file: %s\n"
+msgstr "Tập tin nguồn hiện tại: %s\n"
+
+#: debug.c:733
+#, c-format
+msgid "Number of lines: %d\n"
+msgstr "Số dòng: %d\n"
+
+#: debug.c:740
+#, c-format
+msgid "Source file (lines): %s (%d)\n"
+msgstr "Tập tin nguồn (dòng): %s (%d)\n"
+
+#: debug.c:754
+msgid ""
+"Number Disp Enabled Location\n"
+"\n"
+msgstr ""
+"Số Hthị Bật Vị trí\n"
+"\n"
+
+#: debug.c:765
+#, c-format
+msgid "\tno of hits = %ld\n"
+msgstr "\tkhông gợi ý = %ld\n"
+
+#: debug.c:767
+#, c-format
+msgid "\tignore next %ld hit(s)\n"
+msgstr "\tbỠqua %ld gợi ý tiếp\n"
+
+#: debug.c:769 debug.c:909
+#, c-format
+msgid "\tstop condition: %s\n"
+msgstr "\tdừng Ä‘iá»u kiện: %s\n"
+
+#: debug.c:771 debug.c:911
+msgid "\tcommands:\n"
+msgstr "\tlệnh:\n"
+
+#: debug.c:793
+#, c-format
+msgid "Current frame: "
+msgstr "Khung hiện tại:"
+
+#: debug.c:796
+#, c-format
+msgid "Called by frame: "
+msgstr "Äược gá»i bởi khung:"
+
+#: debug.c:800
+#, c-format
+msgid "Caller of frame: "
+msgstr "Bá»™ gá»i của khung:"
+
+#: debug.c:818
+#, c-format
+msgid "None in main().\n"
+msgstr "Không có gì trong main().\n"
+
+#: debug.c:848
+msgid "No arguments.\n"
+msgstr "Không có đối số nào.\n"
+
+#: debug.c:849
+msgid "No locals.\n"
+msgstr "Không có nội bộ.\n"
+
+#: debug.c:857
+msgid ""
+"All defined variables:\n"
+"\n"
+msgstr ""
+"Tất cả các biến đã định nghĩa:\n"
+"\n"
-#: eval.c:410
+#: debug.c:867
+msgid ""
+"All defined functions:\n"
+"\n"
+msgstr ""
+"Tất cả các hàm đã định nghĩa:\n"
+"\n"
+
+#: debug.c:886
+msgid ""
+"Auto-display variables:\n"
+"\n"
+msgstr ""
+"Các biến hiển thị tự động:\n"
+"\n"
+
+#: debug.c:889
+msgid ""
+"Watch variables:\n"
+"\n"
+msgstr ""
+"Các biến theo dõi:\n"
+"\n"
+
+#: debug.c:1029
+#, c-format
+msgid "no symbol `%s' in current context\n"
+msgstr "không có ký hiệu “%s†trong ngữ cảnh hiện tại\n"
+
+#: debug.c:1041 debug.c:1427
+#, c-format
+msgid "`%s' is not an array\n"
+msgstr "“%s†không phải là một mảng\n"
+
+#: debug.c:1055
+#, c-format
+msgid "$%ld = uninitialized field\n"
+msgstr "$%ld = trÆ°á»ng chÆ°a được khởi tạo\n"
+
+#: debug.c:1076
+#, c-format
+msgid "array `%s' is empty\n"
+msgstr "mảng “%s†trống rỗng\n"
+
+#: debug.c:1119 debug.c:1171
+#, c-format
+msgid "[\"%s\"] not in array `%s'\n"
+msgstr "[â€%sâ€] không nằm trong mảng “%sâ€\n"
+
+#: debug.c:1175
+#, c-format
+msgid "`%s[\"%s\"]' is not an array\n"
+msgstr "“%s[â€%sâ€]†không phải là má»™t mảng\n"
+
+#: debug.c:1236 debug.c:4964
+#, c-format
+msgid "`%s' is not a scalar variable"
+msgstr "“%s†không phải là biến scalar"
+
+#: debug.c:1258 debug.c:4994
+#, c-format
+msgid "attempt to use array `%s[\"%s\"]' in a scalar context"
+msgstr "cố dùng mảng “%s[â€%sâ€]†trong má»™t ngữ cảnh vô hÆ°á»›ng"
+
+#: debug.c:1280 debug.c:5005
+#, c-format
+msgid "attempt to use scalar `%s[\"%s\"]' as array"
+msgstr "cố dùng kiểu vô hÆ°á»›ng “%s[â€%sâ€]†nhÆ° là mảng"
+
+#: debug.c:1423
+#, c-format
+msgid "`%s' is a function"
+msgstr "“%s†là một hàm"
+
+#: debug.c:1465
+#, c-format
+msgid "watchpoint %d is unconditional\n"
+msgstr "Ä‘iểm kiểm tra %d là vô Ä‘iá»u kiện\n"
+
+#: debug.c:1499
+#, c-format
+msgid "No display item numbered %ld"
+msgstr "Không có mục tin hiển thị nào đánh số %ld"
+
+#: debug.c:1502
+#, c-format
+msgid "No watch item numbered %ld"
+msgstr "Không có mục tin theo dõi nào đánh số %ld"
+
+#: debug.c:1528
+#, c-format
+msgid "%d: [\"%s\"] not in array `%s'\n"
+msgstr "%d: [â€%sâ€] không trong mảng “%sâ€\n"
+
+#: debug.c:1767
+msgid "attempt to use scalar value as array"
+msgstr "cố dùng biến vô hướng như là một mảng"
+
+#: debug.c:1856
+#, c-format
+msgid "Watchpoint %d deleted because parameter is out of scope.\n"
+msgstr "Äiểm theo dõi %d bị xóa bởi vì đối số nằm ngoài phạm vi\n"
+
+#: debug.c:1867
+#, c-format
+msgid "Display %d deleted because parameter is out of scope.\n"
+msgstr "Trình bày %d bị xóa bởi vì đối số nằm ngoài phạm vi\n"
+
+#: debug.c:1900
+#, c-format
+msgid " in file `%s', line %d\n"
+msgstr " tại tập tin “%sâ€, dòng %d\n"
+
+#: debug.c:1921
+#, c-format
+msgid " at `%s':%d"
+msgstr " tại “%sâ€:%d"
+
+#: debug.c:1937 debug.c:2000
+#, c-format
+msgid "#%ld\tin "
+msgstr "#%ld\ttrong "
+
+#: debug.c:1974
+#, c-format
+msgid "More stack frames follow ...\n"
+msgstr "Nhiá»u khung ngăn xếp theo sau...\n"
+
+#: debug.c:2017
+msgid "invalid frame number"
+msgstr "số khung không hợp lệ"
+
+#: debug.c:2200
+#, c-format
+msgid "Note: breakpoint %d (enabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+"Chú ý: Ä‘iểm ngắt %d (được bật, bá» qua %ld gợi ý tiếp), đồng thá»i được đặt "
+"tại %s:%d"
+
+#: debug.c:2207
+#, c-format
+msgid "Note: breakpoint %d (enabled), also set at %s:%d"
+msgstr "Chú ý: Ä‘iểm ngắt %d (được bật), đồng thá»i được đặt tại %s:%d"
+
+#: debug.c:2214
+#, c-format
+msgid "Note: breakpoint %d (disabled, ignore next %ld hits), also set at %s:%d"
+msgstr ""
+"Chú ý: Ä‘iểm ngắt %d (bị tắt, bá» qua %ld gợi ý tiếp), đồng thá»i được đặt tại "
+"%s:%d"
+
+#: debug.c:2221
+#, c-format
+msgid "Note: breakpoint %d (disabled), also set at %s:%d"
+msgstr "Chú ý: Ä‘iểm ngắt %d (bị tắt), đồng thá»i được đặt tại %s:%d"
+
+#: debug.c:2238
+#, c-format
+msgid "Breakpoint %d set at file `%s', line %d\n"
+msgstr "Äiểm ngắt %d đặt tại tập tin “%sâ€, dòng %d\n"
+
+#: debug.c:2340
+#, c-format
+msgid "Can't set breakpoint in file `%s'\n"
+msgstr "Không thể đặt Ä‘iểm ngắt trong tập tin “%sâ€\n"
+
+#: debug.c:2369 debug.c:2492 debug.c:3350
+#, c-format
+msgid "line number %d in file `%s' out of range"
+msgstr "số dòng %d trong tập tin “%s†nằm ngoài phạm vi"
+
+#: debug.c:2373
+#, c-format
+msgid "Can't find rule!!!\n"
+msgstr "Không tìm thấy quy tắc!!!\n"
+
+#: debug.c:2375
+#, c-format
+msgid "Can't set breakpoint at `%s':%d\n"
+msgstr "Không thể đặt Ä‘iểm ngắt tại “%sâ€:%d\n"
+
+#: debug.c:2387
+#, c-format
+msgid "Can't set breakpoint in function `%s'\n"
+msgstr "Không thể đặt Ä‘iểm ngắt trong hàm “%sâ€\n"
+
+#: debug.c:2403
+#, c-format
+msgid "breakpoint %d set at file `%s', line %d is unconditional\n"
+msgstr "Ä‘iểm ngắt %d đặt tại tập tin “%sâ€, dòng %d là vô Ä‘iá»u kiện\n"
+
+#: debug.c:2508 debug.c:2530
+#, c-format
+msgid "Deleted breakpoint %d"
+msgstr "Xóa điểm dừng %d"
+
+#: debug.c:2514
+#, c-format
+msgid "No breakpoint(s) at entry to function `%s'\n"
+msgstr "Không có Ä‘iểm ngắt tại Ä‘iểm vào của hàm “%sâ€\n"
+
+#: debug.c:2541
+#, c-format
+msgid "No breakpoint at file `%s', line #%d\n"
+msgstr "Không có Ä‘iểm ngắt tại tập tin “%sâ€, dòng #%d\n"
+
+#: debug.c:2596 debug.c:2637 debug.c:2657 debug.c:2700
+msgid "invalid breakpoint number"
+msgstr "số điểm ngắt không hợp lệ"
+
+#: debug.c:2612
+msgid "Delete all breakpoints? (y or n) "
+msgstr "Xóa tất cả các điểm ngắt? (c hay k) "
+
+#: debug.c:2613 debug.c:2923 debug.c:2976
+msgid "y"
+msgstr "c"
+
+#: debug.c:2662
+#, c-format
+msgid "Will ignore next %ld crossing(s) of breakpoint %d.\n"
+msgstr "Sẽ bỠqua %ld điểm giao chéo của điểm ngắt %d.\n"
+
+#: debug.c:2666
+#, c-format
+msgid "Will stop next time breakpoint %d is reached.\n"
+msgstr "Sẽ dừng lần gặp điểm ngắt %d tiếp theo.\n"
+
+#: debug.c:2783
+#, c-format
+msgid "Can only debug programs provided with the `-f' option.\n"
+msgstr ""
+"Chỉ có thể gỡ lá»—i các chÆ°Æ¡ng trình được cung cấp cùng vá»›i tùy chá»n “-fâ€.\n"
+
+#: debug.c:2908
+#, c-format
+msgid "Failed to restart debugger"
+msgstr "Gặp lỗi khi khởi động lại bộ gỡ lỗi"
+
+#: debug.c:2922
+msgid "Program already running. Restart from beginning (y/n)? "
+msgstr "Chương trình đang chạy. Khởi động từ đầu (c/không)?"
+
+#: debug.c:2926
+#, c-format
+msgid "Program not restarted\n"
+msgstr "Chương trình không khởi động lại\n"
+
+#: debug.c:2936
+#, c-format
+msgid "error: cannot restart, operation not allowed\n"
+msgstr "lỗi: không thể khởi động lại, thao tác không được cho phép\n"
+
+#: debug.c:2942
+#, c-format
+msgid "error (%s): cannot restart, ignoring rest of the commands\n"
+msgstr "lỗi (%s): không thể khởi động lại, bỠqua các lệnh còn lại\n"
+
+#: debug.c:2950
+#, c-format
+msgid "Starting program: \n"
+msgstr "Äang khởi Ä‘á»™ng chÆ°Æ¡ng trình:\n"
+
+#: debug.c:2959
+#, c-format
+msgid "Program exited %s with exit value: %d\n"
+msgstr "Chương trình %s được thoát ra với mã thoát là: %d\n"
+
+#: debug.c:2975
+msgid "The program is running. Exit anyway (y/n)? "
+msgstr "Chương trình này đang chạy. Vẫn thoát (c/không)?"
+
+#: debug.c:3010
+#, c-format
+msgid "Not stopped at any breakpoint; argument ignored.\n"
+msgstr "Không dừng tại bất ký điểm ngắt nào; đối số bị bỠqua.\n"
+
+#: debug.c:3015
+#, c-format
+msgid "invalid breakpoint number %d."
+msgstr "số điểm ngắt không hợp lệ %d."
+
+#: debug.c:3020
+#, c-format
+msgid "Will ignore next %ld crossings of breakpoint %d.\n"
+msgstr "Sẽ bỠqua %ld điểm ngắt xuyên chéo %d kế tiếp.\n"
+
+#: debug.c:3207
+#, c-format
+msgid "'finish' not meaningful in the outermost frame main()\n"
+msgstr "“finish†không có nghĩa trong khung ngoài cùng nhất main()\n"
+
+#: debug.c:3212
+#, c-format
+msgid "Run till return from "
+msgstr "Chạy cho đến khi có trả vỠtừ đó"
+
+#: debug.c:3255
+#, c-format
+msgid "'return' not meaningful in the outermost frame main()\n"
+msgstr "“return†không có nghĩa trong khung ngoài cùng nhất main()\n"
+
+#: debug.c:3369
+#, c-format
+msgid "Can't find specified location in function `%s'\n"
+msgstr "Không tìm thấy vị trí đã cho trong hàm “%sâ€\n"
+
+#: debug.c:3377
+#, c-format
+msgid "invalid source line %d in file `%s'"
+msgstr "dòng nguồn không hợp lệ %d trong tập tin “%sâ€"
+
+#: debug.c:3392
+#, c-format
+msgid "Can't find specified location %d in file `%s'\n"
+msgstr "Không thể tìm thấy vị trí %d được chỉ ra trong tập tin “%sâ€\n"
+
+#: debug.c:3424
+#, c-format
+msgid "element not in array\n"
+msgstr "phần tử không trong mảng\n"
+
+#: debug.c:3424
+#, c-format
+msgid "untyped variable\n"
+msgstr "biến chưa định kiểu\n"
+
+#: debug.c:3466
+#, c-format
+msgid "Stopping in %s ...\n"
+msgstr "Dừng trong %s ...\n"
+
+#: debug.c:3543
+#, c-format
+msgid "'finish' not meaningful with non-local jump '%s'\n"
+msgstr "“finish†không có nghÄ©a vá»›i lệnh nhảy non-local “%sâ€\n"
+
+#: debug.c:3550
+#, c-format
+msgid "'until' not meaningful with non-local jump '%s'\n"
+msgstr "“until†không có nghÄ©a vá»›i cú nhảy non-local “%sâ€\n"
+
+#: debug.c:4185
+msgid "\t------[Enter] to continue or q [Enter] to quit------"
+msgstr "\t-Nhấn [Enter] để tiếp tục hay “q†[Enter] để thoát------"
+
+#: debug.c:4186
+msgid "q"
+msgstr "t"
+
+#: debug.c:5001
+#, c-format
+msgid "[\"%s\"] not in array `%s'"
+msgstr "[\"%s\"] không trong mảng “%sâ€"
+
+#: debug.c:5207
+#, c-format
+msgid "sending output to stdout\n"
+msgstr "gửi kết xuất ra stdout\n"
+
+#: debug.c:5247
+msgid "invalid number"
+msgstr "số không hợp lệ"
+
+#: debug.c:5381
+#, c-format
+msgid "`%s' not allowed in current context; statement ignored"
+msgstr "“%s†không được phép trong ngữ cảnh hiện hành; câu lệnh bị bỠqua"
+
+#: debug.c:5389
+msgid "`return' not allowed in current context; statement ignored"
+msgstr "“return†không được phép trong ngữ cảnh hiện hành; câu lệnh bị bỠqua"
+
+#: debug.c:5590
+#, c-format
+msgid "No symbol `%s' in current context"
+msgstr "Không có ký hiệu “%s†trong ngữ cảnh hiện thá»i"
+
+#: dfa.c:1118 dfa.c:1121 dfa.c:1142 dfa.c:1150 dfa.c:1162 dfa.c:1197
+#: dfa.c:1206 dfa.c:1209 dfa.c:1214 dfa.c:1228 dfa.c:1275
+msgid "unbalanced ["
+msgstr "thiếu dấu ngoặc vuông mở ["
+
+#: dfa.c:1174
+msgid "invalid character class"
+msgstr "sai lớp ký tự"
+
+#: dfa.c:1316
+msgid "character class syntax is [[:space:]], not [:space:]"
+msgstr "cú pháp lớp ký tự là [[:dấu_cách:]], không phải [:dấu_cách:]"
+
+#: dfa.c:1366
+msgid "unfinished \\ escape"
+msgstr "chưa kết thúc dãy thoát \\"
+
+#: dfa.c:1513 regcomp.c:161
+msgid "Invalid content of \\{\\}"
+msgstr "Nội dung của “\\{\\}†không hợp lệ"
+
+#: dfa.c:1516 regcomp.c:176
+msgid "Regular expression too big"
+msgstr "Biểu thức chính quy quá lớn"
+
+#: dfa.c:1936
+msgid "unbalanced ("
+msgstr "thiếu dấu ("
+
+#: dfa.c:2062
+msgid "no syntax specified"
+msgstr "chưa chỉ rõ cú pháp"
+
+#: dfa.c:2070
+msgid "unbalanced )"
+msgstr "thiếu dấu )"
+
+#: eval.c:394
#, c-format
msgid "unknown nodetype %d"
msgstr "không biết kiểu nút %d"
-#: eval.c:421 eval.c:435
-#, fuzzy, c-format
+#: eval.c:405 eval.c:419
+#, c-format
msgid "unknown opcode %d"
-msgstr "không biết kiểu nút %d"
+msgstr "gặp opcode (mã thao tác) không rõ %d"
-#: eval.c:432
+#: eval.c:416
#, c-format
msgid "opcode %s not an operator or keyword"
-msgstr ""
+msgstr "mã lệnh %s không phải là một toán tử hoặc từ khoá"
-#: eval.c:485
+#: eval.c:472
msgid "buffer overflow in genflags2str"
-msgstr "tràn bộ đệm trong « genflags2str » (tạo ra cỠđến chuỗi)"
+msgstr "tràn bộ đệm trong “genflags2str†(tạo ra cỠđến chuỗi)"
-#: eval.c:696
+#: eval.c:675
#, c-format
msgid ""
"\n"
@@ -887,899 +1890,1268 @@ msgid ""
"\n"
msgstr ""
"\n"
-"\t# Äống gá»i chức năng:\n"
+"\t# Ngăn xếp gá»i hàm:\n"
"\n"
-#: eval.c:723
+#: eval.c:704
msgid "`IGNORECASE' is a gawk extension"
-msgstr "« IGNORECASE » (bá» qua chữ hoa/thÆ°á»ng) là phần mở rá»™ng gawk"
+msgstr "“IGNORECASE†(bá» qua chữ HOA/thÆ°á»ng) là phần mở rá»™ng gawk"
-#: eval.c:752
+#: eval.c:736
msgid "`BINMODE' is a gawk extension"
-msgstr "« BINMODE » (chế độ nhị phân) là phần mở rộng gawk"
+msgstr "“BINMODE†(chế độ nhị phân) là phần mở rộng gawk"
-#: eval.c:810
+#: eval.c:794
#, c-format
msgid "BINMODE value `%s' is invalid, treated as 3"
-msgstr ""
+msgstr "Giá trị BINMODE (chế độ nhị phân) “%s†không hợp lệ nên đã coi là 3"
-#: eval.c:900
+#: eval.c:885
#, c-format
msgid "bad `%sFMT' specification `%s'"
-msgstr "đặc tả « %sFMT » sai « %s »"
+msgstr "đặc tả “%sFMT†sai “%sâ€"
-#: eval.c:978
+#: eval.c:969
msgid "turning off `--lint' due to assignment to `LINT'"
-msgstr "đang tắt « --lint » do việc gán cho « LINT »"
-
-#: eval.c:1247
-#, fuzzy
-msgid "sorted array traversal is a gawk extension"
-msgstr "« delete array » (xóa bỠmảng) là một phần mở rộng gawk"
-
-#: eval.c:1291
-msgid "`PROCINFO[\"sorted_in\"]' value is not recognized"
-msgstr ""
+msgstr "Ä‘ang tắt “--lint†do việc gán cho “LINTâ€"
-#: eval.c:1373 eval.c:1923
+#: eval.c:1147
#, 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 » như là biến hay mảng"
-
-#: eval.c:1401
-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)"
+msgid "reference to uninitialized argument `%s'"
+msgstr "gặp tham chiếu đến đối số chÆ°a được khởi tạo “%sâ€"
-#: eval.c:1410 eval.c:1935 eval.c:1948
+#: eval.c:1148
#, c-format
-msgid "reference to uninitialized argument `%s'"
-msgstr "gặp tham chiếu đến đối số chưa được sở khởi « %s »"
+msgid "reference to uninitialized variable `%s'"
+msgstr "gặp tham chiếu đến biến chÆ°a được khởi tạo “%sâ€"
-#: eval.c:1429
+#: eval.c:1166
msgid "attempt to field reference from non-numeric value"
msgstr "cố gắng tham chiếu trÆ°á»ng từ giá trị khác thuá»™c số"
-#: eval.c:1431
-#, fuzzy
+#: eval.c:1168
msgid "attempt to field reference from null string"
-msgstr "cố tham chiếu từ chuỗi vô giá trị"
+msgstr "cố gắng tham chiếu trÆ°á»ng từ chuá»—i trống rá»—ng"
-#: eval.c:1437
-#, fuzzy, c-format
+#: eval.c:1176
+#, c-format
msgid "attempt to access field %ld"
-msgstr "cố gắng truy cập trÆ°á»ng %d"
+msgstr "cố gắng để truy cập trÆ°á»ng %ld"
-#: eval.c:1446
-#, fuzzy, c-format
+#: eval.c:1185
+#, c-format
msgid "reference to uninitialized field `$%ld'"
-msgstr "gặp tham chiếu đến trÆ°á»ng chÆ°a được sở khởi « $%d »"
+msgstr "tham chiếu đến trÆ°á»ng chÆ°a được khởi tạo “$%ldâ€"
-#: eval.c:1508
+#: eval.c:1272
#, c-format
msgid "function `%s' called with more arguments than declared"
-msgstr "chức năng « %s » được gá»i vá»›i số đối số hÆ¡n số được tuyên bố"
+msgstr "hàm “%s†được gá»i vá»›i nhiá»u số đối số hÆ¡n số được khai báo"
-#: eval.c:1663
+#: eval.c:1473
#, c-format
msgid "unwind_stack: unexpected type `%s'"
-msgstr ""
+msgstr "unwind_stack: không cần kiểu “%sâ€"
-#: eval.c:1747
+#: eval.c:1569
msgid "division by zero attempted in `/='"
-msgstr "cố gắng chia cho số không trong « /= »"
+msgstr "gặp phép chia cho số không trong “/=â€"
-#: eval.c:1754
+#: eval.c:1576
#, c-format
msgid "division by zero attempted in `%%='"
-msgstr "cố gắng chia cho số không trong « %%= »"
+msgstr "gặp phép chia cho số không trong “%%=â€"
+
+#: ext.c:89 ext.c:171
+msgid "extensions are not allowed in sandbox mode"
+msgstr "phần mở rộng không cho phép ở chế độ khuôn đúc"
-#: eval.c:2057
-msgid "assignment used in conditional context"
-msgstr "Ä‘iá»u gán được dùng trong ngữ cảnh Ä‘iá»u kiện"
+#: ext.c:92
+msgid "-l / @load are gawk extensions"
+msgstr "-l / @load là một phần mở rộng gawk"
-#: eval.c:2061
-msgid "statement has no effect"
-msgstr "câu không có tác dụng"
+#: ext.c:95
+msgid "load_ext: received NULL lib_name"
+msgstr "load_ext: nhận được NULL lib_name"
-#: eval.c:2473
+#: ext.c:98
#, c-format
-msgid "for loop: array `%s' changed size from %ld to %ld during loop execution"
-msgstr ""
-"cho 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"
+msgid "load_ext: cannot open library `%s' (%s)\n"
+msgstr "load_ext: không thể mở thư viện “%s†(%s)\n"
-#: eval.c:2583
+#: ext.c:104
#, c-format
-msgid "function called indirectly through `%s' does not exist"
+msgid ""
+"load_ext: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"
msgstr ""
+"load_ext: thÆ° viện “%sâ€: chÆ°a định nghÄ©a “plugin_is_GPL_compatible†(%s)\n"
-#: eval.c:2595
+#: ext.c:110
#, c-format
-msgid "function `%s' not defined"
-msgstr "chưa xác định chức năng « %s »"
+msgid "load_ext: library `%s': cannot call function `%s' (%s)\n"
+msgstr "load_ext: thÆ° viện “%sâ€: không thể gá»i hàm “%s†(%s)\n"
-#: eval.c:2656
-#, fuzzy, c-format
-msgid "non-redirected `getline' invalid inside `%s' rule"
-msgstr ""
-"trong hành động « END » (kết thúc) có « getline » (lấy dòng) không được "
-"chuyển hướng lại và chưa được xác định."
+#: ext.c:114
+#, c-format
+msgid "load_ext: library `%s' initialization routine `%s' failed\n"
+msgstr "load_ext: thư viện “%s†thủ tục khởi tạo “%s†gặp lỗi\n"
-#: eval.c:2717
-#, fuzzy, c-format
-msgid "`nextfile' cannot be called from a `%s' rule"
-msgstr ""
-"không thể gá»i « nextfile » (tập tin kế tiếp) từ quy tắc « END » kết thúc)"
+#: ext.c:174
+msgid "`extension' is a gawk extension"
+msgstr "“extension†là một phần mở rộng gawk"
-#: eval.c:2767
-#, fuzzy, c-format
-msgid "`next' cannot be called from a `%s' rule"
-msgstr "không thể gá»i « next » (kế tiếp) từ quy tắc « END » kết thúc)"
+#: ext.c:177
+msgid "extension: received NULL lib_name"
+msgstr "extension: nhận được NULL lib_name"
-#: eval.c:2834
+#: ext.c:180
#, c-format
-msgid "Sorry, don't know how to interpret `%s'"
-msgstr ""
+msgid "extension: cannot open library `%s' (%s)"
+msgstr "phần mở rộng: không thể mở thư viện “%s†(%s)"
-#: ext.c:64
-msgid "extensions are not allowed in sandbox mode"
+#: ext.c:186
+#, c-format
+msgid ""
+"extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)"
msgstr ""
+"phần mở rá»™ng: thÆ° viện “%sâ€: chÆ°a định nghÄ©a “plugin_is_GPL_compatible†(%s)"
-#: ext.c:70 ext.c:75
-msgid "`extension' is a gawk extension"
-msgstr "« extension » là một phần mở rộng gawk"
+#: ext.c:190
+#, c-format
+msgid "extension: library `%s': cannot call function `%s' (%s)"
+msgstr "phần mở rá»™ng: thÆ° viện “%sâ€: không thể gá»i hàm “%s†(%s)"
-#: ext.c:85
-#, fuzzy, c-format
-msgid "fatal: extension: cannot open `%s' (%s)\n"
-msgstr "extension: (phần mở rộng) không thể mở « %s » (%s)\n"
+#: ext.c:221
+msgid "make_builtin: missing function name"
+msgstr "make_builtin: thiếu tên hàm"
-#: ext.c:94
-#, fuzzy, c-format
-msgid ""
-"fatal: extension: library `%s': does not define "
-"`plugin_is_GPL_compatible' (%s)\n"
-msgstr ""
-"extension: (phần mở rá»™ng) thÆ° viện « %s »: không thể gá»i chức năng « %s "
-"» (%s)\n"
+#: ext.c:236
+#, c-format
+msgid "make_builtin: can't redefine function `%s'"
+msgstr "make_builtin: không thể định nghÄ©a lại hàm “%sâ€"
+
+#: ext.c:240
+#, c-format
+msgid "make_builtin: function `%s' already defined"
+msgstr "make_builtin: hàm “%s†đã được định nghĩa rồi"
-#: ext.c:103
-#, fuzzy, c-format
-msgid "fatal: extension: library `%s': cannot call function `%s' (%s)\n"
+#: ext.c:244
+#, c-format
+msgid "make_builtin: function name `%s' previously defined"
+msgstr "make_builtin: hàm “%s†đã được định nghĩa trước đây rồi"
+
+#: ext.c:246
+#, c-format
+msgid "make_builtin: can't use gawk built-in `%s' as function name"
msgstr ""
-"extension: (phần mở rá»™ng) thÆ° viện « %s »: không thể gá»i chức năng « %s "
-"» (%s)\n"
+"make_builtin: không thể sử dụng “%s†như là một hàm được xây dựng sẵn trong "
+"gawk"
+
+#: ext.c:249 ext.c:304
+#, c-format
+msgid "make_builtin: negative argument count for function `%s'"
+msgstr "make_builtin: đối số dành cho số đếm bị âm cho hàm “%sâ€"
-#: ext.c:137
+#: ext.c:276
msgid "extension: missing function name"
-msgstr "extension: (phần mở rộng) tên chức năng còn thiếu"
+msgstr "extension: (phần mở rộng) tên hàm còn thiếu"
-#: ext.c:142
+#: ext.c:279 ext.c:283
#, c-format
msgid "extension: illegal character `%c' in function name `%s'"
-msgstr ""
-"extension: (phần mở rộng) gặp ký tự cấm « %c » nằm trong tên chức năng « %s »"
+msgstr "extension: (phần mở rá»™ng) gặp ký tá»± cấm “%c†nằm trong tên hàm “%sâ€"
-#: ext.c:151
+#: ext.c:291
#, c-format
msgid "extension: can't redefine function `%s'"
-msgstr "extension: (phần mở rộng) không thể xác định lại chức năng « %s »"
+msgstr "extension: (phần mở rá»™ng) không thể định nghÄ©a lại hàm “%sâ€"
-#: ext.c:155
+#: ext.c:295
#, c-format
msgid "extension: function `%s' already defined"
-msgstr "extension: (phần mở rộng) chức năng « %s » đã được xác định"
+msgstr "extension: (phần mở rộng) hàm “%s†đã được định nghĩa"
-#: ext.c:160
+#: ext.c:299
#, c-format
msgid "extension: function name `%s' previously defined"
-msgstr "tên chức năng « %s » đã được xác định trước"
+msgstr "tên hàm “%s†đã được định nghĩa trước đó"
-#: ext.c:162
+#: ext.c:301
#, 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 Ä‘iá»u có sẵn của gawk « %s » nhÆ° là "
-"tên chức năng"
+"extension: (phần mở rá»™ng) không thể dùng Ä‘iá»u có sẵn của gawk “%s†nhÆ° là "
+"tên hàm"
-#: ext.c:166
+#: ext.c:375
#, c-format
-msgid "make_builtin: negative argument count for function `%s'"
-msgstr ""
-
-#: ext.c:269
-#, fuzzy, c-format
msgid "function `%s' defined to take no more than %d argument(s)"
-msgstr "chức năng « %s » được xác định để chấp nhấn %d đối số tối đa"
+msgstr "hàm “%s†được định nghĩa để chấp nhấn %d đối số tối đa"
-#: ext.c:272
+#: ext.c:378
#, c-format
msgid "function `%s': missing argument #%d"
-msgstr "chức năng « %s » còn thiếu đối số thứ %d"
+msgstr "hàm “%sâ€: thiếu đối số #%d"
-#: ext.c:282
+#: ext.c:395
#, c-format
msgid "function `%s': argument #%d: attempt to use scalar as an array"
-msgstr ""
-"chức năng « %s »: đối số thứ %d: cố gắng dùng Ä‘iá»u vô hÆ°á»›ng nhÆ° là mảng"
+msgstr "hàm “%sâ€: đối số thứ %d: cố gắng dùng kiểu vô hÆ°á»›ng nhÆ° là mảng"
-#: ext.c:286
+#: ext.c:399
#, c-format
msgid "function `%s': argument #%d: attempt to use array as a scalar"
-msgstr ""
-"chức năng « %s »: đối số thứ %d: cố gắng dùng mảng nhÆ° là Ä‘iá»u vô hÆ°á»›ng"
+msgstr "hàm “%sâ€: đối số thứ %d: cố gắng dùng mảng nhÆ° là kiểu vô hÆ°á»›ng"
-#: ext.c:299
-msgid "Operation Not Supported"
-msgstr "Thao tác không được hỗ trợ"
+#: ext.c:413
+msgid "dynamic loading of library not supported"
+msgstr "tải động của thư viện không được hỗ trợ"
+
+#: extension/filefuncs.c:159
+msgid "chdir: called with incorrect number of arguments, expecting 1"
+msgstr "chdir: được gá»i vá»›i số lượng đối số không đúng, cần 1"
+
+#: extension/filefuncs.c:439
+#, c-format
+msgid "stat: unable to read symbolic link `%s'"
+msgstr "stat: không thể Ä‘á»c liên kết má»m “%sâ€"
+
+#: extension/filefuncs.c:472
+msgid "stat: called with wrong number of arguments"
+msgstr "stat: được gá»i vá»›i số lượng đối số không đúng"
+
+#: extension/filefuncs.c:479
+msgid "stat: bad parameters"
+msgstr "stat: các đối số sai"
+
+#: extension/filefuncs.c:533
+#, c-format
+msgid "fts init: could not create variable %s"
+msgstr "khởi tạo fts: không thể tạo biến %s"
+
+#: extension/filefuncs.c:554
+msgid "fts is not supported on this system"
+msgstr "fts không được hỗ trợ trên hệ thống này"
+
+#: extension/filefuncs.c:573
+msgid "fill_stat_element: could not create array"
+msgstr "fill_stat_element: không thể tạo mảng"
+
+#: extension/filefuncs.c:582
+msgid "fill_stat_element: could not set element"
+msgstr "fill_stat_element: không thể đặt phần tử"
+
+#: extension/filefuncs.c:597
+msgid "fill_path_element: could not set element"
+msgstr "fill_path_element: không thể đặt phần tử"
+
+#: extension/filefuncs.c:613
+msgid "fill_error_element: could not set element"
+msgstr "fill_error_element: không thể đặt phần tử"
+
+#: extension/filefuncs.c:660 extension/filefuncs.c:707
+msgid "fts-process: could not create array"
+msgstr "fts-process: không thể tạo mảng"
+
+#: extension/filefuncs.c:670 extension/filefuncs.c:717
+#: extension/filefuncs.c:735
+msgid "fts-process: could not set element"
+msgstr "fts-process: không thể đặt phần tử"
+
+#: extension/filefuncs.c:784
+msgid "fts: called with incorrect number of arguments, expecting 3"
+msgstr "fts: được gá»i vá»›i số lượng đối số không đúng, cần 3"
+
+#: extension/filefuncs.c:787
+msgid "fts: bad first parameter"
+msgstr "fts: đối số đầu tiên sai"
+
+#: extension/filefuncs.c:793
+msgid "fts: bad second parameter"
+msgstr "fts: đối số thứ hai sai"
+
+#: extension/filefuncs.c:799
+msgid "fts: bad third parameter"
+msgstr "fts: đối số thứ ba sai"
+
+#: extension/filefuncs.c:806
+msgid "fts: could not flatten array\n"
+msgstr "fts: không thể làm phẳng mảng\n"
+
+#: extension/filefuncs.c:824
+msgid "fts: ignoring sneaky FTS_NOSTAT flag. nyah, nyah, nyah."
+msgstr "fts: bỠqua cỠFTS_NOSTAT vụng trộm. nyah, nyah, nyah."
+
+#: extension/filefuncs.c:841
+msgid "fts: clear_array() failed\n"
+msgstr "fts: clear_array() gặp lỗi\n"
+
+#: extension/fnmatch.c:112
+msgid "fnmatch: called with less than three arguments"
+msgstr "fnmatch: được gá»i vá»›i ít hÆ¡n ba đối số"
+
+#: extension/fnmatch.c:115
+msgid "fnmatch: called with more than three arguments"
+msgstr "fnmatch: được gá»i vá»›i nhiá»u hÆ¡n ba đối số"
+
+#: extension/fnmatch.c:118
+msgid "fnmatch: could not get first argument"
+msgstr "fnmatch: không lấy được đối số đầu tiên"
+
+#: extension/fnmatch.c:123
+msgid "fnmatch: could not get second argument"
+msgstr "fnmatch: không lấy được đối số thứ hai"
+
+#: extension/fnmatch.c:128
+msgid "fnmatch: could not get third argument"
+msgstr "fnmatch: không thể lấy tham số thứ ba"
+
+#: extension/fnmatch.c:141
+msgid "fnmatch is not implemented on this system\n"
+msgstr "fnmatch không được hỗ trợ trên hệ thống này\n"
+
+#: extension/fnmatch.c:173
+msgid "fnmatch init: could not add FNM_NOMATCH variable"
+msgstr "khởi tạo fnmatch: không thể thêm biến FNM_NOMATCH"
+
+#: extension/fnmatch.c:183
+#, c-format
+msgid "fnmatch init: could not set array element %s"
+msgstr "fnmatch init: không thể đặt phần tử mảng %s"
+
+#: extension/fnmatch.c:193
+msgid "fnmatch init: could not install FNM array"
+msgstr "khởi tạo fnmatch: không thể cài đặt mảng FNM"
+
+#: extension/fork.c:81
+msgid "fork: called with too many arguments"
+msgstr "fork: được gá»i vá»›i quá nhiá»u đối số"
+
+#: extension/fork.c:94
+msgid "fork: PROCINFO is not an array!"
+msgstr "fork: PROCINFO không phải là mảng!"
+
+#: extension/fork.c:118
+msgid "waitpid: called with too many arguments"
+msgstr "waitpid: được gá»i vá»›i quá nhiá»u đối số"
+
+#: extension/fork.c:126
+msgid "wait: called with no arguments"
+msgstr "wait: được gá»i mà không truyá»n đối số"
+
+#: extension/fork.c:143
+msgid "wait: called with too many arguments"
+msgstr "wait: được gá»i vá»›i quá nhiá»u đối số"
+
+#: extension/inplace.c:130
+msgid "inplace_begin: in-place editing already active"
+msgstr "inplace_begin: sửa in-place đã sẵn được kích hoạt rồi"
+
+#: extension/inplace.c:133 extension/inplace.c:207
+#, c-format
+msgid "inplace_begin: expects 2 arguments but called with %d"
+msgstr "inplace_begin: cần 2 đối số nhÆ° lại được gá»i vá»›i %d"
+
+#: extension/inplace.c:136
+msgid "inplace_begin: cannot retrieve 1st argument as a string filename"
+msgstr "inplace_begin: không thể lấy đối số thứ nhất như là tên tập tin"
+
+#: extension/inplace.c:144
+#, c-format
+msgid "inplace_begin: disabling in-place editing for invalid FILENAME `%s'"
+msgstr "inplace_begin: tắt sá»­a chữa in-place cho TÊN_TẬP_TIN không hợp lệ “%sâ€"
+
+#: extension/inplace.c:151
+#, c-format
+msgid "inplace_begin: Cannot stat `%s' (%s)"
+msgstr "inplace_begin: Không thể lấy thông tin thống kê của “%s†(%s)"
+
+#: extension/inplace.c:158
+#, c-format
+msgid "inplace_begin: `%s' is not a regular file"
+msgstr "inplace_begin: “%s†không phải là tập tin thÆ°á»ng"
+
+#: extension/inplace.c:169
+#, c-format
+msgid "inplace_begin: mkstemp(`%s') failed (%s)"
+msgstr "inplace_begin: mkstemp(“%sâ€) gặp lá»—i (%s)"
+
+#: extension/inplace.c:178
+#, c-format
+msgid "inplace_begin: chmod failed (%s)"
+msgstr "inplace_begin: chmod gặp lỗi (%s)"
+
+#: extension/inplace.c:185
+#, c-format
+msgid "inplace_begin: dup(stdout) failed (%s)"
+msgstr "inplace_begin: dup(stdout) gặp lỗi (%s)"
+
+#: extension/inplace.c:188
+#, c-format
+msgid "inplace_begin: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_begin: dup2(%d, stdout) gặp lỗi (%s)"
+
+#: extension/inplace.c:191
+#, c-format
+msgid "inplace_begin: close(%d) failed (%s)"
+msgstr "inplace_begin: close(%d) gặp lỗi (%s)"
+
+#: extension/inplace.c:210
+msgid "inplace_end: cannot retrieve 1st argument as a string filename"
+msgstr "inplace_end: không thể lấy lại đối số thứ nhất như là một tên tập tin"
+
+#: extension/inplace.c:217
+msgid "inplace_end: in-place editing not active"
+msgstr "inplace_end: việc sửa in-place không được kích hoạt"
+
+#: extension/inplace.c:223
+#, c-format
+msgid "inplace_end: dup2(%d, stdout) failed (%s)"
+msgstr "inplace_end: dup2(%d, stdout) gặp lỗi (%s)"
+
+#: extension/inplace.c:226
+#, c-format
+msgid "inplace_end: close(%d) failed (%s)"
+msgstr "inplace_end: close(%d) gặp lỗi (%s)"
+
+#: extension/inplace.c:230
+#, c-format
+msgid "inplace_end: fsetpos(stdout) failed (%s)"
+msgstr "inplace_end: fsetpos(stdout) gặp lỗi (%s)"
+
+#: extension/inplace.c:243
+#, c-format
+msgid "inplace_end: link(`%s', `%s') failed (%s)"
+msgstr "inplace_end: link(“%sâ€, “%sâ€) gặp lá»—i (%s)"
+
+#: extension/inplace.c:253
+#, c-format
+msgid "inplace_end: rename(`%s', `%s') failed (%s)"
+msgstr "inplace_end: rename(“%sâ€, “%sâ€) gặp lá»—i (%s)"
+
+#: extension/ordchr.c:69
+msgid "ord: called with too many arguments"
+msgstr "ord: được gá»i vá»›i quá nhiá»u đối số"
+
+#: extension/ordchr.c:75
+msgid "ord: called with no arguments"
+msgstr "ord: được gá»i mà không có đối số"
+
+#: extension/ordchr.c:77
+msgid "ord: called with inappropriate argument(s)"
+msgstr "ord: được gá»i vá»›i đối số không thích hợp"
+
+#: extension/ordchr.c:99
+msgid "chr: called with too many arguments"
+msgstr "chr: được gá»i vá»›i quá nhiá»u đối số"
+
+#: extension/ordchr.c:109
+msgid "chr: called with no arguments"
+msgstr "chr: được gá»i mà không có đối số"
+
+#: extension/ordchr.c:111
+msgid "chr: called with inappropriate argument(s)"
+msgstr "chr: được gá»i vá»›i đối số không thích hợp"
+
+#: extension/readdir.c:281
+#, c-format
+msgid "dir_take_control_of: opendir/fdopendir failed: %s"
+msgstr "dir_take_control_of: opendir/fdopendir gặp lỗi: %s"
+
+#: extension/readfile.c:113
+msgid "readfile: called with too many arguments"
+msgstr "readfile: được gá»i vá»›i quá nhiá»u đối số"
+
+#: extension/readfile.c:137
+msgid "readfile: called with no arguments"
+msgstr "readfile: được gá»i mà không có đối số"
+
+#: extension/rwarray.c:124
+msgid "writea: called with too many arguments"
+msgstr "writea: được gá»i vá»›i quá nhiá»u đối số"
+
+#: extension/rwarray.c:131
+#, c-format
+msgid "do_writea: argument 0 is not a string\n"
+msgstr "do_writea: đối số 0 không phải là một chuỗi\n"
+
+#: extension/rwarray.c:137
+#, c-format
+msgid "do_writea: argument 1 is not an array\n"
+msgstr "do_writea: đối số 1 không phải là một mảng\n"
-#: field.c:328
+#: extension/rwarray.c:184
+#, c-format
+msgid "write_array: could not flatten array\n"
+msgstr "write_array: không thể làm phẳng mảng\n"
+
+#: extension/rwarray.c:198
+#, c-format
+msgid "write_array: could not release flattened array\n"
+msgstr "write_array: không thể giải phóng mảng được làm phẳng\n"
+
+#: extension/rwarray.c:280
+msgid "reada: called with too many arguments"
+msgstr "reada: được gá»i vá»›i quá nhiá»u đối số"
+
+#: extension/rwarray.c:287
+#, c-format
+msgid "do_reada: argument 0 is not a string\n"
+msgstr "do_reada: đối số 0 không phải là một chuỗi\n"
+
+#: extension/rwarray.c:293
+#, c-format
+msgid "do_reada: argument 1 is not an array\n"
+msgstr "do_reada: đối số 1 không phải là một mảng\n"
+
+#: extension/rwarray.c:337
+#, c-format
+msgid "do_reada: clear_array failed\n"
+msgstr "do_reada: clear_array gặp lỗi\n"
+
+#: extension/rwarray.c:374
+#, c-format
+msgid "read_array: set_array_element failed\n"
+msgstr "read_array: set_array_element gặp lỗi\n"
+
+#: extension/time.c:113
+msgid "gettimeofday: ignoring arguments"
+msgstr "gettimeofday: đang lỠđi các đối số"
+
+#: extension/time.c:144
+msgid "gettimeofday: not supported on this platform"
+msgstr "gettimeofday: không được há»— trợ trên ná»n tảng này"
+
+#: extension/time.c:165
+msgid "sleep: called with too many arguments"
+msgstr "sleep: được gá»i vá»›i quá nhiá»u đối số"
+
+#: extension/time.c:168
+msgid "sleep: missing required numeric argument"
+msgstr "sleep: thiếu đối số dạng số cần thiết"
+
+#: extension/time.c:174
+msgid "sleep: argument is negative"
+msgstr "sleep: đối số âm"
+
+#: extension/time.c:208
+msgid "sleep: not supported on this platform"
+msgstr "sleep: không được há»— trợ trên ná»n tảng này"
+
+#: field.c:345
msgid "NF set to negative value"
-msgstr "« NF » được đặt thành giá trị âm"
+msgstr "“NF†được đặt thành giá trị âm"
-#: field.c:939 field.c:946 field.c:950
-#, fuzzy
+#: field.c:971 field.c:978 field.c:982
msgid "split: fourth argument is a gawk extension"
-msgstr "match: (khớp) đối số thứ ba là phần mở rộng gawk"
+msgstr "split (chia tách): đối số thứ tư là phần mở rộng gawk"
-#: field.c:943
-#, fuzzy
+#: field.c:975
msgid "split: fourth argument is not an array"
-msgstr "split: (chia tách) đối số thứ hai không phải là mảng"
+msgstr "split (chia tách): đối số thứ tư không phải là mảng"
-#: field.c:957
+#: field.c:989
msgid "split: second argument is not an array"
msgstr "split: (chia tách) đối số thứ hai không phải là mảng"
-#: field.c:962
-msgid "split: can not use the same array for second and fourth args"
+#: field.c:993
+msgid "split: cannot use the same array for second and fourth args"
+msgstr ""
+"split (chia tách): không thể sử dụng cùng một mảng có cả đối số thứ hai và "
+"thứ tư"
+
+#: field.c:998
+msgid "split: cannot use a subarray of second arg for fourth arg"
+msgstr ""
+"split (phân tách): không thể sử dụng mảng con của tham số thứ hai cho tham "
+"số thứ tư"
+
+#: field.c:1001
+msgid "split: cannot use a subarray of fourth arg for second arg"
msgstr ""
+"split (phân tách): không thể sử dụng mảng con của tham số thứ tư cho tham số "
+"thứ hai"
-#: field.c:990
+#: field.c:1032
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à phần mở rộng gawk"
-#: field.c:1031
-#, fuzzy
+#: field.c:1072
msgid "patsplit: fourth argument is not an array"
-msgstr "split: (chia tách) đối số thứ hai không phải là mảng"
+msgstr "patsplit: đối số thứ tư không phải là mảng"
-#: field.c:1036
-#, fuzzy
+#: field.c:1077
msgid "patsplit: second argument is not an array"
-msgstr "split: (chia tách) đối số thứ hai không phải là mảng"
+msgstr "patsplit: đối số thứ hai không phải là mảng"
-#: field.c:1054
-#, fuzzy
+#: field.c:1083
msgid "patsplit: third argument must be non-null"
-msgstr "match: (khớp) đối số thứ ba không phải là mảng"
+msgstr "patsplit: đối số thứ ba không phải không rỗng"
+
+#: field.c:1087
+msgid "patsplit: cannot use the same array for second and fourth args"
+msgstr ""
+"patsplit (chương trình chia tách): không thể sử dụng cùng một mảng cho cả "
+"hai đối số thứ hai và thứ tư"
+
+#: field.c:1092
+msgid "patsplit: cannot use a subarray of second arg for fourth arg"
+msgstr ""
+"patsplit (chương trình phân tách): không thể sử dụng mảng con của tham số "
+"thứ hai cho tham số thứ tư"
-#: field.c:1059
-msgid "patsplit: can not use the same array for second and fourth args"
+#: field.c:1095
+msgid "patsplit: cannot use a subarray of fourth arg for second arg"
msgstr ""
+"patsplit (chương trình phân tách): không thể sử dụng mảng con của tham số "
+"thứ tư cho tham số thứ hai"
-#: field.c:1089
+#: field.c:1133
msgid "`FIELDWIDTHS' is a gawk extension"
-msgstr "« FIELDWIDTHS » (Ä‘á»™ rá»™ng trÆ°á»ng) là phần mở rá»™ng gawk"
+msgstr "“FIELDWIDTHS†(Ä‘á»™ rá»™ng trÆ°á»ng) là phần mở rá»™ng gawk"
-#: field.c:1152
+#: field.c:1197
#, c-format
msgid "invalid FIELDWIDTHS value, near `%s'"
-msgstr "giá trị FIELDWIDTHS (Ä‘á»™ rá»™ng trÆ°á»ng) không hợp lệ, gần « %s »"
+msgstr "giá trị FIELDWIDTHS (Ä‘á»™ rá»™ng trÆ°á»ng) không hợp lệ, gần “%sâ€"
-#: field.c:1225
+#: field.c:1270
msgid "null string for `FS' is a gawk extension"
-msgstr "chuỗi vô giá trị cho « FS » là phần mở rộng gawk"
+msgstr "chuỗi vô giá trị cho “FS†là phần mở rộng gawk"
-#: field.c:1229
+#: field.c:1274
msgid "old awk does not support regexps as value of `FS'"
-msgstr "awk cũ không hỗ trợ biểu thức chính quy làm giá trị của « FS »"
+msgstr "awk cÅ© không há»— trợ biểu thức chính quy làm giá trị của “FSâ€"
-#: field.c:1348
-#, fuzzy
+#: field.c:1393
msgid "`FPAT' is a gawk extension"
-msgstr "« %s » là một phần mở rộng gawk"
+msgstr "“FPAT†là phần mở rộng của gawk"
+
+#: gawkapi.c:146
+msgid "awk_value_to_node: received null retval"
+msgstr "awk_value_to_node: retval nhận được là null"
+
+#: gawkapi.c:384
+msgid "node_to_awk_value: received null node"
+msgstr "node_to_awk_value: nút nhận được là null"
+
+#: gawkapi.c:387
+msgid "node_to_awk_value: received null val"
+msgstr "node_to_awk_value: biến nhận được là null"
+
+#: gawkapi.c:807
+msgid "remove_element: received null array"
+msgstr "remove_element: mảng nhận được là null"
+
+#: gawkapi.c:810
+msgid "remove_element: received null subscript"
+msgstr "remove_element: nhận được là null"
-#: getopt.c:574 getopt.c:590
-#, fuzzy, c-format
-msgid "%s: option '%s' is ambiguous\n"
-msgstr "%s: tùy chá»n « %s » là mÆ¡ hồ\n"
+#: gawkapi.c:947
+#, c-format
+msgid "api_flatten_array: could not convert index %d\n"
+msgstr "api_flatten_array: không thể chuyển đổi chỉ số %d\n"
+
+#: gawkapi.c:952
+#, c-format
+msgid "api_flatten_array: could not convert value %d\n"
+msgstr "api_flatten_array: không thể chuyển đổi giá trị %d\n"
-#: getopt.c:623 getopt.c:627
-#, fuzzy, c-format
+#: getopt.c:604 getopt.c:633
+#, c-format
+msgid "%s: option '%s' is ambiguous; possibilities:"
+msgstr "%s: tùy chá»n “%s†chÆ°a rõ ràng; khả năng là:"
+
+#: getopt.c:679 getopt.c:683
+#, 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"
+msgstr "%s: tùy chá»n “--%s†không cho phép đối số\n"
-#: getopt.c:636 getopt.c:641
-#, fuzzy, c-format
+#: getopt.c:692 getopt.c:697
+#, 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"
+msgstr "%s: tùy chá»n “%c%s†không cho phép đối số\n"
-#: getopt.c:684 getopt.c:703
-#, fuzzy, c-format
+#: getopt.c:740 getopt.c:759
+#, c-format
msgid "%s: option '--%s' requires an argument\n"
-msgstr "%s: tùy chá»n «%s» cần đến đối số\n"
+msgstr "%s: tùy chá»n “--%s†yêu cầu má»™t đối số\n"
-#: getopt.c:741 getopt.c:744
-#, fuzzy, c-format
+#: getopt.c:797 getopt.c:800
+#, c-format
msgid "%s: unrecognized option '--%s'\n"
-msgstr "%s: không nhận diện tùy chá»n « --%s »\n"
+msgstr "%s: không nhận ra tùy chá»n “--%sâ€\n"
-#: getopt.c:752 getopt.c:755
-#, fuzzy, c-format
+#: getopt.c:808 getopt.c:811
+#, c-format
msgid "%s: unrecognized option '%c%s'\n"
-msgstr "%s: không nhận diện tùy chá»n « %c%s »\n"
+msgstr "%s: không nhận ra tùy chá»n “%c%sâ€\n"
-#: getopt.c:804 getopt.c:807
-#, fuzzy, c-format
+#: getopt.c:860 getopt.c:863
+#, c-format
msgid "%s: invalid option -- '%c'\n"
-msgstr "%s: tùy chá»n không hợp lệ « -- %c »\n"
+msgstr "%s: tùy chá»n không hợp lệ -- “%câ€\n"
-#: getopt.c:857 getopt.c:874 getopt.c:1082 getopt.c:1100
-#, fuzzy, c-format
+#: getopt.c:916 getopt.c:933 getopt.c:1143 getopt.c:1161
+#, c-format
msgid "%s: option requires an argument -- '%c'\n"
-msgstr "%s: tùy chá»n cần đến đối số « -- %c »\n"
+msgstr "%s: tùy chá»n yêu cầu má»™t đối số -- “%câ€\n"
-#: getopt.c:930 getopt.c:946
-#, fuzzy, c-format
+#: getopt.c:989 getopt.c:1005
+#, c-format
msgid "%s: option '-W %s' is ambiguous\n"
-msgstr "%s: tùy chá»n « -W %s » là mÆ¡ hồ\n"
+msgstr "%s: tùy chá»n “-W %s†vẫn mÆ¡ hồ\n"
-#: getopt.c:970 getopt.c:988
-#, fuzzy, c-format
+#: getopt.c:1029 getopt.c:1047
+#, 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"
+msgstr "%s: tùy chá»n “-W %s†không cho phép đối số\n"
-#: getopt.c:1009 getopt.c:1027
-#, fuzzy, c-format
+#: getopt.c:1068 getopt.c:1086
+#, c-format
msgid "%s: option '-W %s' requires an argument\n"
-msgstr "%s: tùy chá»n «%s» cần đến đối số\n"
+msgstr "%s: tùy chá»n “-W %s†yêu cầu má»™t đối số\n"
-#: io.c:282
+#: io.c:392
#, c-format
msgid "command line argument `%s' is a directory: skipped"
-msgstr ""
+msgstr "tham số dòng lệnh “%s†là một thư mục: đã bị bỠqua"
-#: io.c:285 io.c:382
+#: io.c:395 io.c:513
#, c-format
msgid "cannot open file `%s' for reading (%s)"
-msgstr "không mở được tập tin «%s» để ghi (%s)"
+msgstr "không mở được tập tin “%s†để Ä‘á»c (%s)"
-#: io.c:429
-#, c-format
-msgid "error reading input file `%s': %s"
-msgstr "gặp lá»—i khi Ä‘á»c tập tin nhập « %s »: %s"
-
-#: io.c:498
+#: io.c:640
#, c-format
msgid "close of fd %d (`%s') failed (%s)"
-msgstr "lỗi đóng « fd %d » (« %s ») (%s)"
+msgstr "lá»—i đóng fd %d (“%sâ€) (%s)"
-#: io.c:575
+#: io.c:716
msgid "redirection not allowed in sandbox mode"
-msgstr ""
+msgstr "chuyển hướng không cho phép ở chế độ khuôn đúc"
-#: io.c:609
+#: io.c:750
#, 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ố"
+msgstr "biểu thức trong Ä‘iá»u chuyển hÆ°á»›ng “%s†chỉ có giá trị thuá»™c số"
-#: io.c:615
+#: io.c:756
#, 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ị"
+msgstr "biểu thức cho Ä‘iá»u chuyển hÆ°á»›ng “%s†có giá trị chuá»—i vô giá trị"
-#: io.c:621
+#: io.c:761
#, 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 "
+"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:664
+#: io.c:809
#, c-format
msgid "unnecessary mixing of `>' and `>>' for file `%.*s'"
-msgstr "không cần hợp « > » và « >> » cho tập tin « %.*s »"
+msgstr "không cần hợp “>†và “>>†cho tập tin “%.*sâ€"
-#: io.c:717
+#: io.c:863
#, c-format
msgid "can't open pipe `%s' for output (%s)"
-msgstr "không thể mở ống dẫn « %s » để xuất (%s)"
+msgstr "không thể mở ống dẫn “%s†để xuất (%s)"
-#: io.c:727
+#: io.c:873
#, c-format
msgid "can't open pipe `%s' for input (%s)"
-msgstr "không thể mở ống dẫn « %s » để nhập (%s)"
+msgstr "không thể mở ống dẫn “%s†để nhập (%s)"
-#: io.c:749
+#: io.c:904
#, c-format
msgid "can't open two way pipe `%s' for input/output (%s)"
-msgstr "không thể mở ống dẫn hai chiá»u « %s » để nhập/xuất (%s)"
+msgstr "không thể mở ống dẫn hai chiá»u “%s†để nhập/xuất (%s)"
-#: io.c:831
+#: io.c:986
#, c-format
msgid "can't redirect from `%s' (%s)"
-msgstr "không thể chuyển hướng từ « %s » (%s)"
+msgstr "không thể chuyển hướng từ “%s†(%s)"
-#: io.c:834
+#: io.c:989
#, c-format
msgid "can't redirect to `%s' (%s)"
-msgstr "không thể chuyển hướng đến «%s» (%s)"
+msgstr "không thể chuyển hướng đến “%s†(%s)"
-#: io.c:883
+#: io.c:1040
msgid ""
"reached system limit for open files: starting to multiplex file descriptors"
msgstr ""
"đã tá»›i giá»›i hạn hệ thống vá» tập tin được mở nên bắt đầu phối hợp nhiá»u dòng "
"Ä‘iá»u mô tả tập tin"
-#: io.c:899
+#: io.c:1056
#, c-format
msgid "close of `%s' failed (%s)."
-msgstr "lỗi đóng « %s » (%s)"
+msgstr "lỗi đóng “%s†(%s)"
-#: io.c:907
+#: io.c:1064
msgid "too many pipes or input files open"
msgstr "quá nhiá»u ống dẫn hay tập tin nhập được mở"
-#: io.c:929
+#: io.c:1086
msgid "close: second argument must be `to' or `from'"
-msgstr "close: (đóng) đối số thứ hai phải là « to » (đến) hay « from » (từ)"
+msgstr "close: (đóng) đối số thứ hai phải là “to†(đến) hay “from†(từ)"
-#: io.c:946
+#: io.c:1103
#, c-format
msgid "close: `%.*s' is not an open file, pipe or co-process"
msgstr ""
-"close: (đóng) « %.*s » không phải là tập tin được mở, ống dẫn hay tiến trình "
-"vá»›i nhau"
+"close: (đóng) “%.*s†không phải là tập tin, ống dẫn hay đồng tiến trình đã "
+"được mở"
-#: io.c:951
+#: io.c:1108
msgid "close of redirection that was never opened"
-msgstr "việc đóng Ä‘iá»u chuyển hÆ°á»›ng chÆ°a mở"
+msgstr "đóng một chuyển hướng mà nó chưa từng được mở"
-#: io.c:1048
+#: io.c:1205
#, c-format
msgid "close: redirection `%s' not opened with `|&', second argument ignored"
msgstr ""
-"close: (đóng) Ä‘iá»u chuyển hÆ°á»›ng « %s » không được mở bởi « |& » nên đối số "
-"thứ hai bị bỠqua"
+"close: chuyển hướng “%s†không được mở bởi “|&†nên đối số thứ hai bị bỠqua"
-#: io.c:1064
+#: io.c:1222
#, 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)"
+msgstr "trạng thái thất bại (%d) khi đóng ống dẫn “%s†(%s)"
-#: io.c:1067
+#: io.c:1225
#, 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)"
+msgstr "trạng thái thất bại (%d) khi đóng tập tin “%s†(%s)"
-#: io.c:1087
+#: io.c:1245
#, c-format
msgid "no explicit close of socket `%s' provided"
-msgstr "không có việc đóng dứt khoát ổ cắm « %s » được cung cấp"
+msgstr "không cung cấp lệnh đóng ổ cắm “%s†rõ ràng"
-#: io.c:1090
+#: io.c:1248
#, c-format
msgid "no explicit close of co-process `%s' provided"
-msgstr "không có việc đóng dứt khoát đồng tiến trình « %s » được cung cấp"
+msgstr "không cung cấp lệnh đóng đồng tiến trình “%s†rõ ràng"
-#: io.c:1093
+#: io.c:1251
#, c-format
msgid "no explicit close of pipe `%s' provided"
-msgstr "không có việc đóng dứt khoát ống dẫn « %s » được cung cấp"
+msgstr "không cung cấp lệnh đóng Ä‘Æ°á»ng ống dẫn lệnh “%s†rõ ràng"
-#: io.c:1096
+#: io.c:1254
#, c-format
msgid "no explicit close of file `%s' provided"
-msgstr "không có việc đóng dứt khoát tập tin « %s » được cung cấp"
+msgstr "không cung cấp lệnh đóng tập tin “%s†rõ ràng"
-#: io.c:1124 io.c:1179 main.c:809 main.c:851
+#: io.c:1284 io.c:1342 main.c:864 main.c:906
#, c-format
msgid "error writing standard output (%s)"
-msgstr "gặp lỗi khi ghi thiết bị xụất chuẩn (%s)"
+msgstr "gặp lỗi khi ghi đầu ra tiêu chuẩn (%s)"
-#: io.c:1128 io.c:1184
+#: io.c:1289 io.c:1348 main.c:866
#, 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:1136
+#: io.c:1297
#, c-format
msgid "pipe flush of `%s' failed (%s)."
-msgstr "lỗi xóa sạch ống dẫn « %s » (%s)"
+msgstr "lỗi xoá sạch ống dẫn “%s†(%s)"
-#: io.c:1139
+#: io.c:1300
#, c-format
msgid "co-process flush of pipe to `%s' failed (%s)."
-msgstr "lỗi xóa sạch ống dẫn đồng tiến trình đến « %s » (%s)"
+msgstr "lỗi xoá sạch ống dẫn đồng tiến trình đến “%s†(%s)"
-#: io.c:1142
+#: io.c:1303
#, c-format
msgid "file flush of `%s' failed (%s)."
-msgstr "lỗi xóa sạch tập tin « %s » (%s)"
+msgstr "lỗi xoá sạch tập tin “%s†(%s)"
-#: io.c:1257
+#: io.c:1420
#, c-format
msgid "local port %s invalid in `/inet'"
-msgstr "cổng cục bộ %s không hợp lệ trong « /inet »"
+msgstr "cổng cục bá»™ %s không hợp lệ trong “/inetâ€"
-#: io.c:1274
+#: io.c:1438
#, c-format
msgid "remote host and port information (%s, %s) invalid"
msgstr "thông tin vỠmáy/cổng ở xa (%s, %s) không phải hợp lệ"
-#: io.c:1426
+#: io.c:1590
#, 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"
+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:1440
+#: io.c:1604
#, c-format
msgid "special file name `%s' is incomplete"
-msgstr "tên tập tin đặc biệt « %s » chưa xong"
+msgstr "tên tập tin đặc biệt “%s†chưa xong"
-#: io.c:1457
+#: io.c:1621
msgid "must supply a remote hostname to `/inet'"
-msgstr "phải cung cấp một tên máy từ xa cho </inet>"
+msgstr "phải cung cấp một tên máy chủ cho </inet>"
-#: io.c:1475
+#: io.c:1639
msgid "must supply a remote port to `/inet'"
-msgstr "phải cung cấp một cổng từ xa cho </inet>"
+msgstr "phải cung cấp một cổng máy chủ cho </inet>"
-#: io.c:1521
+#: io.c:1685
msgid "TCP/IP communications are not supported"
msgstr "truyá»n thông TCP/IP không được há»— trợ"
-#: io.c:1688
+#: io.c:1867
#, c-format
msgid "could not open `%s', mode `%s'"
-msgstr "không mở được «%s», chế độ «%s»"
+msgstr "không mở được “%sâ€, chế Ä‘á»™ “%sâ€"
-#: io.c:1739
+#: io.c:1917
#, c-format
msgid "close of master pty failed (%s)"
-msgstr "lỗi đóng pty (tài sản?) chính (%s)"
+msgstr "gặp lỗi khi đóng thiết bị cuối giả (%s)"
-#: io.c:1741 io.c:1909 io.c:2066
+#: io.c:1919 io.c:2105 io.c:2305
#, c-format
msgid "close of stdout in child failed (%s)"
-msgstr "lỗi đóng thiết bị xuất chuẩn trong tiến trình con (%s)"
+msgstr "lỗi đóng đầu ra tiêu chuẩn trong tiến trình con (%s)"
-#: io.c:1744
+#: io.c:1922
#, c-format
msgid "moving slave pty to stdout in child failed (dup: %s)"
msgstr ""
-"lá»—i di chuyển pty (tài sản?) phụ tá»›i thiết bị xuất chuẩn trong Ä‘iá»u con "
-"(nhân đôi: %s)"
+"gặp lỗi khi di chuyển pty (thiết bị cuối giả) phụ thuộc đến thiết bị đầu ra "
+"tiêu chuẩn trong con (trùng: %s)"
-#: io.c:1746 io.c:1914
+#: io.c:1924 io.c:2110
#, c-format
msgid "close of stdin in child failed (%s)"
msgstr "lỗi đóng thiết bị nhập chuẩn trong tiến trình con (%s)"
-#: io.c:1749
+#: io.c:1927
#, c-format
msgid "moving slave pty to stdin in child failed (dup: %s)"
msgstr ""
-"lá»—i di chuyển pty (tài sản?) phụ tá»›i thiết bị nhập chuẩn trong Ä‘iá»u con "
-"(nhân đôi: %s)"
+"lá»—i di chuyển pty (thiết bị cuối giả) phụ tá»›i thiết bị nhập chuẩn trong Ä‘iá»u "
+"con (nhân đôi: %s)"
-#: io.c:1751 io.c:1772
+#: io.c:1929 io.c:1951
#, c-format
msgid "close of slave pty failed (%s)"
-msgstr "lỗi đóng pty (tài sản?) phụ (%s)"
+msgstr "đóng pty (thiết bị cuối giả) phụ thuộc gặp lỗi (%s)"
-#: io.c:1850 io.c:1912 io.c:2044 io.c:2069
+#: io.c:2040 io.c:2108 io.c:2276 io.c:2308
#, c-format
msgid "moving pipe to stdout in child failed (dup: %s)"
msgstr ""
-"lỗi di chuyển ống dẫn đến thiết bị xuất chuẩn trong tiến trình con (dup: %s) "
-"(nhân đôi)"
+"lỗi di chuyển ống dẫn đến thiết bị xuất chuẩn trong tiến trình con (trùng: "
+"%s)"
-#: io.c:1857 io.c:1917
+#: io.c:2047 io.c:2113
#, c-format
msgid "moving pipe to stdin in child failed (dup: %s)"
msgstr ""
-"lỗi di chuyển ống dẫn đến thiết bị nhập chuẩn trong tiến trình con (dup: %s) "
-"(nhân đôi)"
+"lỗi di chuyển ống dẫn đến thiết bị nhập chuẩn trong tiến trình con (trùng: "
+"%s)"
-#: io.c:1877 io.c:2059
+#: io.c:2073 io.c:2298
msgid "restoring stdout in parent process failed\n"
-msgstr "lỗi phục hồi thiết bị xuất chuẩn trong tiến trình mẹ\n"
+msgstr "phục hồi đầu ra tiêu chuẩn trong tiến trình mẹ gặp lỗi\n"
-#: io.c:1885
+#: io.c:2081
msgid "restoring stdin in parent process failed\n"
-msgstr "lỗi phục hồi thiết bị nhập chuẩn trong tiến trình mẹ\n"
+msgstr "phục hồi đầu vào tiêu chuẩn trong tiến trình mẹ gặp lỗi\n"
-#: io.c:1920 io.c:2071 io.c:2085
+#: io.c:2116 io.c:2310 io.c:2324
#, c-format
msgid "close of pipe failed (%s)"
-msgstr "lỗi đóng ống dẫn (%s)"
+msgstr "đóng ống dẫn gặp lỗi (%s)"
-#: io.c:1965
+#: io.c:2174
msgid "`|&' not supported"
-msgstr "« |& » không được hỗ trợ"
+msgstr "“|&†không được hỗ trợ"
-#: io.c:2031
+#: io.c:2261
#, c-format
msgid "cannot open pipe `%s' (%s)"
-msgstr "không thể mở ống dẫn « %s » (%s)"
+msgstr "không thể mở ống dẫn “%s†(%s)"
-#: io.c:2079
+#: io.c:2318
#, c-format
msgid "cannot create child process for `%s' (fork: %s)"
-msgstr "không thể tạo tiến trình con cho « %s » (fork: %s)"
+msgstr "không thể tạo tiến trình con cho “%s†(fork: %s)"
-#: io.c:2569
+#: io.c:2790
+msgid "register_input_parser: received NULL pointer"
+msgstr "register_input_parser: nhận được con trỠNULL"
+
+#: io.c:2818
+#, c-format
+msgid "input parser `%s' conflicts with previously installed input parser `%s'"
+msgstr ""
+"bộ phân tích đầu vào “%s†xung đột với bộ phân tích đầu vào được cài đặt "
+"trÆ°á»›c đó “%sâ€"
+
+#: io.c:2825
+#, c-format
+msgid "input parser `%s' failed to open `%s'"
+msgstr "bá»™ phân tích đầu vào “%s†gặp lá»—i khi mở “%sâ€"
+
+#: io.c:2845
+msgid "register_output_wrapper: received NULL pointer"
+msgstr "register_output_wrapper: nhận được con trỠNULL"
+
+#: io.c:2873
+#, c-format
+msgid ""
+"output wrapper `%s' conflicts with previously installed output wrapper `%s'"
+msgstr ""
+"bá»™ bao kết xuất “%s†xung Ä‘á»™t vá»›i bá»™ bao kết xuất được cài đặt trÆ°á»›c đó “%sâ€"
+
+#: io.c:2880
+#, c-format
+msgid "output wrapper `%s' failed to open `%s'"
+msgstr "bá»™ bao kết xuất “%s†gặp lá»—i khi mở “%sâ€"
+
+#: io.c:2901
+msgid "register_output_processor: received NULL pointer"
+msgstr "register_output_processor: nhận được con trỠNULL"
+
+#: io.c:2930
+#, c-format
+msgid ""
+"two-way processor `%s' conflicts with previously installed two-way processor "
+"`%s'"
+msgstr ""
+"bộ xử lý hai hướng “%s†xung đột với bộ xử lý hai hướng đã được cài đặt "
+"trÆ°á»›c đó “%sâ€"
+
+#: io.c:2939
+#, c-format
+msgid "two way processor `%s' failed to open `%s'"
+msgstr "bá»™ xá»­ lý hai hÆ°á»›ng “%s†gặp lá»—i khi mở “%sâ€"
+
+#: io.c:3064
#, c-format
msgid "data file `%s' is empty"
-msgstr "tập tin dữ liệu « %s » là rỗng"
+msgstr "tập tin dữ liệu “%s†là rỗng"
-#: io.c:2610 io.c:2618
+#: io.c:3106 io.c:3114
msgid "could not allocate more input memory"
msgstr "không thể cấp phát bộ nhớ nhập thêm nữa"
-#: io.c:3171
+#: io.c:3682
msgid "multicharacter value of `RS' is a gawk extension"
-msgstr "giá trị đa ký tự của « RS » là phần mở rộng gawk"
+msgstr "giá trị đa ký tự của “RS†là phần mở rộng gawk"
-#: io.c:3276
-#, fuzzy
+#: io.c:3771
msgid "IPv6 communication is not supported"
-msgstr "truyá»n thông TCP/IP không được há»— trợ"
+msgstr "Truyá»n thông trên IPv6 không được há»— trợ"
-#: main.c:307
-msgid "out of memory"
-msgstr ""
-
-#: main.c:384
-msgid "`-m[fr]' option irrelevant in gawk"
-msgstr "tùy chá»n « -m[fr] » không thích Ä‘ang trong gawk"
-
-#: main.c:386
-msgid "-m option usage: `-m[fr] nnn'"
-msgstr "cách sá»­ dụng tùy chá»n «-m»: « -m[fr] nnn »"
-
-#: main.c:409
-#, fuzzy
+#: main.c:405
msgid "empty argument to `-e/--source' ignored"
-msgstr "đối số rỗng tới « --source » (nguồn) bị bỠqua"
+msgstr "đối số rá»—ng cho tuỳ chá»n “-e/--source†bị bá» qua"
-#: main.c:475
+#: main.c:495
#, 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"
+msgstr "%s: tùy chá»n “-W %s†không được nhận diện nên bị bá» qua\n"
-#: main.c:528
+#: main.c:541
#, c-format
msgid "%s: option requires an argument -- %c\n"
-msgstr "%s: tùy chá»n cần đến đối số « -- %c »\n"
+msgstr "%s: tùy chá»n cần đến đối số “-- %câ€\n"
-#: main.c:549
+#: main.c:562
msgid "environment variable `POSIXLY_CORRECT' set: turning on `--posix'"
msgstr ""
-"biến môi trÆ°á»ng « POSIXLY_CORRECT » (đúng kiểu POSIX) đã được đặt; Ä‘ang bật "
-"tùy chá»n « --posix »"
+"biến môi trÆ°á»ng “POSIXLY_CORRECT†(đúng kiểu POSIX) đã được đặt; Ä‘ang bật "
+"tùy chá»n “--posixâ€"
-#: main.c:555
+#: main.c:568
msgid "`--posix' overrides `--traditional'"
-msgstr "tùy chá»n « --posix » có quyá»n cao hÆ¡n « --traditional » (truyá»n thống)"
+msgstr "tùy chá»n “--posix†có quyá»n cao hÆ¡n “--traditional†(truyá»n thống)"
-#: main.c:566
+#: main.c:579
msgid "`--posix'/`--traditional' overrides `--non-decimal-data'"
msgstr ""
-"« --posix »/« --traditional » (truyá»n thống) có quyá»n cao hÆ¡n « --non-"
-"decimal-data » (dữ liệu khác thập phân)"
+"“--posixâ€/“--traditional†(cổ Ä‘iển) có quyá»n cao hÆ¡n “--non-decimal-"
+"data†(dữ liệu khác thập phân)"
-#: main.c:570
+#: main.c:583
#, c-format
msgid "running %s setuid root may be a security problem"
-msgstr "việc chạy %s với tư cách « setuid root » có thể rủi rỠbảo mật"
+msgstr "việc chạy %s với tư cách “setuid root†có thể rủi rỠbảo mật"
-#: main.c:575
-#, fuzzy
-msgid "`--posix' overrides `--binary'"
-msgstr "tùy chá»n « --posix » có quyá»n cao hÆ¡n « --traditional » (truyá»n thống)"
+#: main.c:588
+msgid "`--posix' overrides `--characters-as-bytes'"
+msgstr "“--posix†đè lên “--characters-as-bytesâ€"
-#: main.c:626
+#: main.c:647
#, c-format
msgid "can't set binary mode on stdin (%s)"
-msgstr "không thể đặt chế độ nhị phân trên thiết bị nhập chuẩn (%s)"
+msgstr "không thể đặt chế độ nhị phân trên đầu vào tiêu chuẩn (%s)"
-#: main.c:629
+#: main.c:650
#, c-format
msgid "can't set binary mode on stdout (%s)"
-msgstr "không thể đặt chế độ nhị phân trên thiết bị xuất chuẩn (%s)"
+msgstr "không thể đặt chế độ nhị phân trên đầu ra tiêu chuẩn (%s)"
-#: main.c:631
+#: main.c:652
#, c-format
msgid "can't set binary mode on stderr (%s)"
-msgstr "không thể đặt chế độ nhị phân trên thiết bị lỗi chuẩn (%s)"
+msgstr "không thể đặt chế độ nhị phân trên đầu ra lỗi tiêu chuẩn (%s)"
-#: main.c:670
+#: main.c:710
msgid "no program text at all!"
-msgstr "không có đoạn chữ chương trình nào cả !"
+msgstr "không có đoạn chữ chương trình nào cả!"
-#: main.c:749
+#: main.c:799
#, 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 [--] "
+"Cách 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:751
+#: main.c:801
#, 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 "
+"Cách dùng: %s [tùy chá»n kiểu POSIX hay GNU] [--] %cchÆ°Æ¡ng_trình%c "
"tập_tin ...\n"
-#: main.c:756
-#, fuzzy
+#: main.c:806
msgid "POSIX options:\t\tGNU long options: (standard)\n"
-msgstr "tùy chá»n POSIX:\t\ttùy chá»n dài GNU:\n"
+msgstr "Tùy chá»n POSIX:\t\t\tTùy chá»n dài GNU: (tiêu chuẩn)\n"
-#: main.c:757
+#: main.c:807
msgid "\t-f progfile\t\t--file=progfile\n"
-msgstr "\t-f tập_tin_chương_trình\t\t--file=tập_tin_chương_trình\n"
+msgstr "\t-f tập_tin_chương_trình\t--file=tập_tin_chương_trình\n"
-#: main.c:758
+#: main.c:808
msgid "\t-F fs\t\t\t--field-separator=fs\n"
-msgstr "\t-F fs\t\t\t--field-separator=Ä‘iá»u phân cách trÆ°á»ng\n"
+msgstr "\t-F fs\t\t\t--field-separator=ký_hiệu_phân_cách_trÆ°á»ng\n"
-#: main.c:759
+#: main.c:809
msgid "\t-v var=val\t\t--assign=var=val\n"
msgstr ""
-"\t-v var=giá trị\t\t--assign=biến=giá_trị\n"
-"(assign: gán, var: biến)\n"
+"\t-v var=giá_trị\t\t--assign=biến=giá_trị\n"
+"(assign: gán)\n"
-#: main.c:760
-#, fuzzy
+#: main.c:810
msgid "Short options:\t\tGNU long options: (extensions)\n"
-msgstr "tùy chá»n POSIX:\t\ttùy chá»n dài GNU:\n"
+msgstr "Tuỳ chá»n ngắn:\t\t\tTuỳ chá»n GNU dạng dài: (mở rá»™ng)\n"
-#: main.c:761
+#: main.c:811
msgid "\t-b\t\t\t--characters-as-bytes\n"
-msgstr ""
+msgstr "\t-b\t\t\t--characters-as-bytes\n"
-#: main.c:762
-#, fuzzy
+#: main.c:812
msgid "\t-c\t\t\t--traditional\n"
-msgstr ""
-"\t-W traditional\t\t--traditional\n"
-"(truyá»n thống)\n"
+msgstr "\t-c\t\t\t--traditional\n"
-#: main.c:763
-#, fuzzy
+#: main.c:813
msgid "\t-C\t\t\t--copyright\n"
-msgstr ""
-"\t-W copyright\t\t--copyright\n"
-"(tác quyá»n)\n"
+msgstr "\t-C\t\t\t--copyright\n"
-#: main.c:764
-#, fuzzy
-msgid "\t-d [file]\t\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:814
+msgid "\t-d[file]\t\t--dump-variables[=file]\n"
+msgstr "\t-d[tập_tin]\t\t--dump-variables[=tập_tin]\n"
+
+#: main.c:815
+msgid "\t-D[file]\t\t--debug[=file]\n"
+msgstr "\t-D[tập_tin]\t\t--debug[=tập_tin]\n"
-#: main.c:765
-#, fuzzy
+#: main.c:816
msgid "\t-e 'program-text'\t--source='program-text'\n"
-msgstr ""
-"\t-W source=program-text\t--source=program-text\n"
-"(source: nguồn\n"
-"program-text: đoạn chữ của chương trình)\n"
+msgstr "\t-e “program-textâ€\t--source=“program-textâ€\n"
-#: main.c:766
-#, fuzzy
+#: main.c:817
msgid "\t-E file\t\t\t--exec=file\n"
-msgstr "\t-W exec=tập_tin\t\t--exec=tập_tin\n"
+msgstr "\t-E file\t\t\t--exec=tập_tin\n"
-#: main.c:767
-#, fuzzy
+#: main.c:818
msgid "\t-g\t\t\t--gen-pot\n"
-msgstr ""
-"\t-W gen-po\t\t--gen-po\n"
-"(gen là viết tắt cho generate: tạo ra)\n"
+msgstr "\t-g\t\t\t--gen-pot\n"
-#: main.c:768
-#, fuzzy
+#: main.c:819
msgid "\t-h\t\t\t--help\n"
-msgstr ""
-"\t-W help\t\t\t--help\n"
-"(trợ giúp)\n"
+msgstr "\t-h\t\t\t--help\n"
-#: main.c:769
-#, fuzzy
+#: main.c:820
+msgid "\t-i includefile\t\t--include=includefile\n"
+msgstr "\t-i includefile\t\t--include=tập-tin-bao-gồm\n"
+
+#: main.c:821
+msgid "\t-l library\t\t--load=library\n"
+msgstr "\t-l library\t\t--load=thư-viện\n"
+
+#: main.c:822
msgid "\t-L [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"
+msgstr "\t-L [fatal]\t\t--lint[=fatal]\n"
-#: main.c:770
-#, fuzzy
+#: main.c:823
msgid "\t-n\t\t\t--non-decimal-data\n"
-msgstr ""
-"\t-W non-decimal-data\t--non-decimal-data\n"
-"(dữ liệu khác thập phân)\n"
+msgstr "\t-n\t\t\t--non-decimal-data\n"
+
+#: main.c:824
+msgid "\t-M\t\t\t--bignum\n"
+msgstr "\t-M\t\t\t--bignum\n"
-#: main.c:771
-#, fuzzy
+#: main.c:825
msgid "\t-N\t\t\t--use-lc-numeric\n"
-msgstr "\t-W use-lc-numeric\t--use-lc-numeric\n"
+msgstr "\t-N\t\t\t--use-lc-numeric\n"
-#: main.c:772
+#: main.c:826
+msgid "\t-o[file]\t\t--pretty-print[=file]\n"
+msgstr "\t-o[tập_tin]\t\t--pretty-print[=tập_tin]\n"
+
+#: main.c:827
msgid "\t-O\t\t\t--optimize\n"
-msgstr ""
+msgstr "\t-O\t\t\t--optimize (tạm dịch: tối_ưu_hoá)\n"
-#: main.c:773
-#, fuzzy
-msgid "\t-p [file]\t\t--profile[=file]\n"
-msgstr ""
-"\t-W profile[=tập_tin]\t--profile[=tập_tin]\n"
-"(profile: hồ sơ)\n"
+#: main.c:828
+msgid "\t-p[file]\t\t--profile[=file]\n"
+msgstr "\t-p[tập_tin]\t\t--profile[=tập_tin]\n"
-#: main.c:774
-#, fuzzy
+#: main.c:829
msgid "\t-P\t\t\t--posix\n"
-msgstr "\t-W posix\t\t--posix\n"
+msgstr "\t-P\t\t\t--posix\n"
-#: main.c:775
-#, fuzzy
+#: main.c:830
msgid "\t-r\t\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:777
-#, fuzzy
-msgid "\t-R file\t\t\t--command=file\n"
-msgstr "\t-W exec=tập_tin\t\t--exec=tập_tin\n"
+msgstr "\t-r\t\t\t--re-interval\n"
-#: main.c:778
+#: main.c:831
msgid "\t-S\t\t\t--sandbox\n"
-msgstr ""
+msgstr "\t-S\t\t\t--sandbox\n"
-#: main.c:779
-#, fuzzy
+#: main.c:832
msgid "\t-t\t\t\t--lint-old\n"
-msgstr ""
-"\t-W lint-old\t\t--lint-old\n"
-"(old: cũ)\n"
+msgstr "\t-t\t\t\t--lint-old\n"
-#: main.c:780
-#, fuzzy
+#: main.c:833
msgid "\t-V\t\t\t--version\n"
-msgstr ""
-"\t-W version\t\t--version\n"
-"(phiên bản)\n"
+msgstr "\t-V\t\t\t--version\n"
-#: main.c:782
+#: main.c:835
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:785
-#, fuzzy
+#: main.c:838
msgid "\t-Y\t\t--parsedebug\n"
-msgstr ""
-"\t-W parsedebug\t\t--parsedebug\n"
-"(parse: phân tách\n"
-"debug: gỡ lỗi)\n"
+msgstr "\t-Y\t\t--parsedebug\n"
#. TRANSLATORS: --help output 5 (end)
#. TRANSLATORS: the placeholder indicates the bug-reporting address
#. for this application. Please add _another line_ with the
#. address for translation bugs.
#. no-wrap
-#: main.c:794
+#: main.c:847
msgid ""
"\n"
"To report bugs, see node `Bugs' in `gawk.info', which is\n"
@@ -1787,33 +3159,34 @@ msgid ""
"\n"
msgstr ""
"\n"
-"Äể thông báo lá»—i, xem nút « Bugs » (lá»—i) trong tập tin\n"
-"thông tin « gawk.info » mà nằm trong phần\n"
-"« Reporting Problems and Bugs » (thông báo vấn đỠvà lỗi)\n"
+"Äể thông báo lá»—i, xem nút “Bugs†(lá»—i) trong tập tin\n"
+"thông tin “gawk.infoâ€, cái mà nằm trong phần\n"
+"“Reporting Problems and Bugs†(thông báo trục trặc và lỗi)\n"
"trong bản in.\n"
+"Thông báo lỗi dịch cho: <http://translationproject.org/team/vi.html>.\n"
"\n"
-#: main.c:798
+#: main.c:851
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à ngôn ngữ quét và xử lý mẫu.\n"
-"Mặc định là nó Ä‘á»c thiết bị nhập chuẩn và ghi ra thiết bị xuất chuẩn.\n"
+"Mặc định, nó Ä‘á»c từ đầu vào tiêu chuẩn và ghi ra đầu ra tiêu chuẩn.\n"
"\n"
-#: main.c:802
+#: main.c:855
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"
+"Ví dụ:\n"
+"\tgawk \"{ sum += $1 }; END { print sum }\" file\n"
+"\tgawk -F: \"{ print $1 }\" /etc/passwd\n"
-#: main.c:822
+#: main.c:880
#, c-format
msgid ""
"Copyright (C) 1989, 1991-%d Free Software Foundation.\n"
@@ -1826,13 +3199,13 @@ msgid ""
msgstr ""
"Tác quyá»n © năm 1989, 1991-%d của 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át hành lại nó và/hoặc sá»­a "
-"đổi nó vá»›i Ä‘iá»u kiện của Giấy Phép Công Cá»™ng GNU nhÆ° được xuất bản bởi Tổ "
-"Chức Phần Má»m Tá»± Do; hoặc phiên bản 3 của Giấy Phép này, hoặc (tùy chá»n) bất "
-"kỳ phiên bản sau nào.\n"
+"ChÆ°Æ¡ng trình này là phần má»m tá»± do; bạn có thể phát hành lại nó\n"
+"và/hoặc sá»­a đổi nó vá»›i các Ä‘iá»u Ä‘iá»u khoản của Giấy Phép Công Cá»™ng GNU\n"
+"được xuất bản bởi Tổ Chức Phần Má»m Tá»± Do; hoặc là phiên bản 3\n"
+"của Giấy Phép này, hoặc là (tùy chá»n) bất kỳ phiên bản má»›i hÆ¡n.\n"
"\n"
-#: main.c:830
+#: main.c:888
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"
@@ -1841,155 +3214,209 @@ msgid ""
"\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 Bản Quyá»n Công Chung GNU (GPL) để tìm chi tiết.\n"
+"nhÆ°ng mà KHÔNG BẢO ÄẢM GÃŒ CẢ, không ngay cả khi nó ÄƯỢC BÃN\n"
+"hoặc PHÙ HỢP VỚI CÃC MỤC ÄÃCH ÄẶC THÙ.\n"
+"Hãy xem Giấy phép Công Chung GNU (GPL) để biết chi tiết.\n"
"\n"
-#: main.c:841
+#: main.c:894
msgid ""
"You should have received a copy of the GNU General Public License\n"
"along with this program. If not, see http://www.gnu.org/licenses/.\n"
msgstr ""
-"Bện nên đã nhận một bản sao của Giấy Phép Công Cộng GNU\n"
-"cùng với chương trình này. Không thì xem địa chỉ « http://www.gnu.org/"
-"licenses/ ».\n"
+"Bạn nên nhận một bản sao của Giấy Phép Công Cộng GNU cùng với chương\n"
+"trình này. Nếu chưa có, bạn xem tại <http://www.gnu.org/licenses/>.\n"
-#: main.c:876
+#: main.c:931
msgid "-Ft does not set FS to tab in POSIX awk"
-msgstr "-Ft không đặt FS (hệ thống tập tin?) là tab trong awk POSIX"
+msgstr "-Ft không đặt FS (hệ thống tập tin?) vào tab trong awk POSIX"
-#: main.c:1110
+#: main.c:1208
#, c-format
msgid "unknown value for field spec: %d\n"
-msgstr ""
+msgstr "không hiểu giá trị dành cho đặc tả trÆ°á»ng: %d\n"
-#: main.c:1170
+#: main.c:1306
#, c-format
msgid ""
"%s: `%s' argument to `-v' not in `var=value' form\n"
"\n"
msgstr ""
-"%s: đối số « %s » đối với « -v » không phải có dạng « biến=giá_trị »\n"
+"%s: đối số “%s†cho “-v†không có dạng “biến=giá_trịâ€\n"
"\n"
-#: main.c:1190
+#: main.c:1332
#, c-format
msgid "`%s' is not a legal variable name"
-msgstr "« %s » không phải là tên biến hợp lệ"
+msgstr "“%s†không phải là tên biến hợp lệ"
-#: main.c:1193
+#: main.c:1335
#, c-format
msgid "`%s' is not a variable name, looking for file `%s=%s'"
-msgstr "« %s » không phải là tên biến; đang tìm tập tin « %s=%s »"
+msgstr "“%s†không phải là tên biến; Ä‘ang tìm tập tin “%s=%sâ€"
+
+#: main.c:1339
+#, c-format
+msgid "cannot use gawk builtin `%s' as variable name"
+msgstr "không thể dùng builtin (dựng sẵn) của gawk “%s†như là tên biến"
+
+#: main.c:1344
+#, c-format
+msgid "cannot use function `%s' as variable name"
+msgstr "không thể dùng hàm “%s†như là tên biến"
-#: main.c:1246
+#: main.c:1397
msgid "floating point exception"
-msgstr "ngoại lệ điểm phù động"
+msgstr "ngoại lệ số thực dấu chấm động"
-#: main.c:1253
+#: main.c:1404
msgid "fatal error: internal error"
msgstr "lá»—i nghiêm trá»ng: lá»—i ná»™i bá»™"
-#: main.c:1268
-#, fuzzy
+#: main.c:1419
msgid "fatal error: internal error: segfault"
-msgstr "lá»—i nghiêm trá»ng: lá»—i ná»™i bá»™"
+msgstr "lá»—i nghiêm trá»ng: lá»—i ná»™i bá»™: lá»—i phân Ä‘oạn"
-#: main.c:1280
-#, fuzzy
+#: main.c:1431
msgid "fatal error: internal error: stack overflow"
-msgstr "lá»—i nghiêm trá»ng: lá»—i ná»™i bá»™"
+msgstr "lá»—i nghiêm trá»ng: lá»—i ná»™i bá»™: tràn ngăn xếp"
-#: main.c:1330
+#: main.c:1490
#, c-format
msgid "no pre-opened fd %d"
-msgstr "không có fd (chỉ thị tập tin?) %d đã mở trước"
+msgstr "không có fd (bộ mô tả tập tin) %d đã mở trước"
-#: main.c:1337
+#: main.c:1497
#, c-format
msgid "could not pre-open /dev/null for fd %d"
-msgstr "không thể mở </dev/null> trước cho fd (chỉ thị tập tin?) %d"
+msgstr "không thể mở trước “/dev/null†cho fd %d"
+
+#: mpfr.c:550
+#, c-format
+msgid "PREC value `%.*s' is invalid"
+msgstr "giá trị PREC “%.*s†là không hợp lệ"
-#: main.c:1360 main.c:1369
+#: mpfr.c:608
#, c-format
-msgid "could not find groups: %s"
-msgstr "không tìm thấy nhóm: %s"
+msgid "RNDMODE value `%.*s' is invalid"
+msgstr "giá trị RNDMODE “%.*s†là không hợp lệ"
-#: msg.c:63
+#: mpfr.c:698
+#, c-format
+msgid "%s: received non-numeric argument"
+msgstr "%s: đã nhận đối số không phải thuộc số"
+
+#: mpfr.c:800
+msgid "compl(%Rg): negative value will give strange results"
+msgstr "compl(%Rg): giá trị âm sẽ gây ra kết quả không như mong muốn"
+
+#: mpfr.c:804
+msgid "comp(%Rg): fractional value will be truncated"
+msgstr "compl(%Rg): giá trị thuộc phân số sẽ bị cắt ngắn"
+
+#: mpfr.c:816
+#, c-format
+msgid "cmpl(%Zd): negative values will give strange results"
+msgstr "cmpl(%Zd): giá trị âm sẽ gây ra kết quả không như mong muốn"
+
+#: mpfr.c:835
+#, c-format
+msgid "%s: received non-numeric argument #%d"
+msgstr "%s: đã nhận đối số không phải thuộc số #%d"
+
+#: mpfr.c:845
+msgid "%s: argument #%d has invalid value %Rg, using 0"
+msgstr "%s: đối số #%d có giá trị không hợp lệ %Rg, dùng 0"
+
+#: mpfr.c:857
+msgid "%s: argument #%d negative value %Rg will give strange results"
+msgstr "%s: đối số #%d giá trị âm %Rg sẽ gây ra kết quả không như mong muốn"
+
+#: mpfr.c:863
+msgid "%s: argument #%d fractional value %Rg will be truncated"
+msgstr "%s: đối số #%d giá trị phần phân số %Rg sẽ bị cắt cụt"
+
+#: mpfr.c:878
+#, c-format
+msgid "%s: argument #%d negative value %Zd will give strange results"
+msgstr "%s: đối số #%d có giá trị âm %Zd sẽ đưa ra kết quả không như mong muốn"
+
+#: msg.c:68
#, c-format
msgid "cmd. line:"
msgstr "dòng lệnh:"
-#: msg.c:107
-msgid "error: "
-msgstr "lá»—i: "
-
-#: node.c:401
+#: node.c:421
msgid "backslash at end of string"
-msgstr "gặp xuyệc ngoặc tại kết thúc của chuỗi"
+msgstr "gặp dấu gạch ngược tại kết thúc của chuỗi"
-#: node.c:502
+#: node.c:500
#, c-format
msgid "old awk does not support the `\\%c' escape sequence"
-msgstr "awk cũ không hỗ trợ dãy thoát « \\%c »"
+msgstr "awk cÅ© không há»— trợ thoát chuá»—i “\\%câ€"
-#: node.c:553
+#: node.c:551
msgid "POSIX does not allow `\\x' escapes"
-msgstr "POSIX không cho phép Ä‘iá»u thoát « \\x »"
+msgstr "POSIX không cho phép thoát chuá»—i “\\xâ€"
-#: node.c:559
+#: node.c:557
msgid "no hex digits in `\\x' escape sequence"
-msgstr "không có số thập lúc nằm trong dây thoát « \\x »"
+msgstr "không có số thập lúc nằm trong thoát chuá»—i “\\xâ€"
-#: node.c:581
+#: node.c:579
#, c-format
msgid ""
"hex escape \\x%.*s of %d characters probably not interpreted the way you "
"expect"
msgstr ""
+"thoát chuá»—i thập lục \\x%.*s chứa %d ký tá»± mà rất có thể không phải được Ä‘á»c "
+"bằng cách dự định"
-#: node.c:596
+#: node.c:594
#, c-format
msgid "escape sequence `\\%c' treated as plain `%c'"
-msgstr "dây thoát « \\%c » được xử lý như là « %c » chuẩn"
+msgstr "thoát chuỗi “\\%c†được xử lý như là “%c†chuẩn"
-#: node.c:735
+#: node.c:739
msgid ""
"Invalid multibyte data detected. There may be a mismatch between your data "
"and your locale."
msgstr ""
+"Dữ liệu dạng đa byte (multibyte) không hợp lệ được tìm thấy. Tại đó có lẽ "
+"không khớp giữa dữ liệu của bạn và nơi xảy ra."
-#: posix/gawkmisc.c:175
-#, fuzzy, c-format
+#: posix/gawkmisc.c:177
+#, c-format
msgid "%s %s `%s': could not get fd flags: (fcntl F_GETFD: %s)"
-msgstr ""
-"%s %s « %s »: không thể đặt « close-on-exec » (đóng một khi thực hiện) "
-"(fcntl: %s)"
+msgstr "%s %s “%sâ€: không thể lấy cá» mô tả (fd): (fcntl F_GETFD: %s)"
-#: posix/gawkmisc.c:187
-#, fuzzy, c-format
+#: posix/gawkmisc.c:189
+#, c-format
msgid "%s %s `%s': could not set close-on-exec: (fcntl F_SETFD: %s)"
msgstr ""
-"%s %s « %s »: không thể đặt « close-on-exec » (đóng một khi thực hiện) "
-"(fcntl: %s)"
+"%s %s “%sâ€: không thể đặt “close-on-exec†(đóng má»™t khi thá»±c hiện): (fcntl "
+"F_SETFD: %s)"
-#: profile.c:83
+#: profile.c:71
#, c-format
msgid "could not open `%s' for writing: %s"
-msgstr "không thể mở « %s » để ghi: %s"
+msgstr "không thể mở “%s†để ghi: %s"
+
+#: profile.c:73
+msgid "sending profile to standard error"
+msgstr "đang gởi hồ sơ cho thiết bị lỗi chuẩn"
-#: profile.c:203
-#, fuzzy, c-format
+#: profile.c:193
+#, c-format
msgid ""
"\t# %s block(s)\n"
"\n"
msgstr ""
-"\t# khối END (kết thúc)\n"
+"\t# %s khối\n"
"\n"
-#: profile.c:208
-#, fuzzy, c-format
+#: profile.c:198
+#, c-format
msgid ""
"\t# Rule(s)\n"
"\n"
@@ -1997,289 +3424,198 @@ msgstr ""
"\t# Quy tắc\n"
"\n"
-#: profile.c:279
+#: profile.c:272
#, 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:938
+#: profile.c:537
+msgid "internal error: builtin with null fname"
+msgstr "lỗi nội bộ: phần dựng sẵn với fname là null"
+
+#: profile.c:949
+#, c-format
+msgid ""
+"\t# Loaded extensions (-l and/or @load)\n"
+"\n"
+msgstr ""
+"\t# Các phần mở rộng được tải (-l và/hoặc @load)\n"
+"\n"
+
+#: profile.c:972
#, c-format
msgid "\t# gawk profile, created %s\n"
msgstr "\t# hồ sơ gawk, được tạo %s\n"
-#: profile.c:1317
+#: profile.c:1475
#, c-format
msgid ""
"\n"
"\t# Functions, listed alphabetically\n"
msgstr ""
"\n"
-"\t# Danh sách các chức năng theo thứ tự abc\n"
+"\t# Danh sách các hàm theo thứ tự abc\n"
-#: profile.c:1356
+#: profile.c:1513
#, c-format
msgid "redir2str: unknown redirection type %d"
-msgstr ""
+msgstr "redir2str: không hiểu kiểu chuyển hướng %d"
-#: re.c:589
-#, c-format
-msgid "range of the form `[%c-%c]' is locale dependant"
-msgstr ""
-
-#: re.c:611
+#: re.c:607
#, c-format
msgid "regexp component `%.*s' should probably be `[%.*s]'"
msgstr ""
+"thành phần của biểu thức chính qui (regexp) “%.*s†gần như chắc chắn nên là "
+"“[%.*s]â€"
-#: regcomp.c:132
+#: regcomp.c:131
msgid "Success"
msgstr "Thành công"
-#: regcomp.c:135
+#: regcomp.c:134
msgid "No match"
msgstr "Không khớp"
-#: regcomp.c:138
+#: regcomp.c:137
msgid "Invalid regular expression"
msgstr "Biểu thức chính quy không hợp lệ"
-#: regcomp.c:141
+#: regcomp.c:140
msgid "Invalid collation character"
msgstr "Ký tự đối chiếu không hợp lệ"
-#: regcomp.c:144
+#: regcomp.c:143
msgid "Invalid character class name"
msgstr "Tên hạng ký tự không hợp lệ"
-#: regcomp.c:147
+#: regcomp.c:146
msgid "Trailing backslash"
-msgstr "Gặp xuyệc ngược nằm theo"
+msgstr "Gặp dấu gạch ngược thừa"
-#: regcomp.c:150
+#: regcomp.c:149
msgid "Invalid back reference"
-msgstr "Tham chiếu trở lại không hợp lệ"
+msgstr "Tham chiếu ngược không hợp lệ"
-#: regcomp.c:153
+#: regcomp.c:152
msgid "Unmatched [ or [^"
-msgstr "Chưa khớp « [ » hay « [^ »"
+msgstr "ChÆ°a khá»›p “[†hay “[^â€"
-#: regcomp.c:156
+#: regcomp.c:155
msgid "Unmatched ( or \\("
-msgstr "Chưa khớp « ( » hay « \\( »"
+msgstr "ChÆ°a khá»›p “(†hay “\\(â€"
-#: regcomp.c:159
+#: regcomp.c:158
msgid "Unmatched \\{"
-msgstr "Chưa khớp « \\{ »"
+msgstr "ChÆ°a khá»›p “\\{â€"
-#: regcomp.c:162
-msgid "Invalid content of \\{\\}"
-msgstr "Nội dụng « \\{\\} » không hợp lệ"
-
-#: regcomp.c:165
+#: regcomp.c:164
msgid "Invalid range end"
-msgstr "Kết thúc phạm vị không hợp lệ"
+msgstr "Kết thúc phạm vi không hợp lệ"
-#: regcomp.c:168
+#: regcomp.c:167
msgid "Memory exhausted"
-msgstr "Hết bộ nhớ rồi"
+msgstr "Hết bộ nhớ"
-#: regcomp.c:171
+#: regcomp.c:170
msgid "Invalid preceding regular expression"
msgstr "Biểu thức chính quy nằm trước không hợp lệ"
-#: regcomp.c:174
+#: regcomp.c:173
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:177
-msgid "Regular expression too big"
-msgstr "Biểu thức chính quy quá lớn"
-
-#: regcomp.c:180
+#: regcomp.c:179
msgid "Unmatched ) or \\)"
-msgstr "Chưa khớp « ) » hay « \\) »"
+msgstr "ChÆ°a khá»›p “)†hoặc “\\)â€"
-#: regcomp.c:701
+#: regcomp.c:704
msgid "No previous regular expression"
msgstr "Không có biểu thức chính quy nằm trước"
-#~ msgid "statement may have no effect"
-#~ msgstr "câu có lẽ sẽ không có tác dụng"
-
-#~ msgid "attempt to use scalar `%s' as array"
-#~ msgstr "cố dùng Ä‘iá»u cô hÆ°á»›ng « %s » là mảng"
-
-#, fuzzy
-#~ msgid "attempt to use array `%s' in scalar context"
-#~ msgstr "cố gắng dùng mảng « %s » trong một ngữ cảnh vô hướng"
-
-#~ msgid "`continue' outside a loop is not allowed"
-#~ msgstr "không cho phép « continue » (tiếp tục) nằm ở ngoại vòng lặp"
-
-#, fuzzy
-#~ msgid "`break' outside a loop is not allowed"
-#~ msgstr "không cho phép « break » (ngắt) nằm ở ngoại vòng lặp"
-
-#~ msgid "/inet/raw client not ready yet, sorry"
-#~ msgstr "tiếc là ứng dụng khách <inet/raw> chưa sẵn sàng"
-
-#~ msgid "only root may use `/inet/raw'."
-#~ msgstr "chỉ ngÆ°á»i chủ (root) có thể dùng </inet/raw> thôi"
-
-#~ 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"
-
-#~ msgid "\t-m[fr] val\n"
-#~ msgstr "\t-m[fr] giá_trị\n"
-
-#~ 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ó dấu ngoặc"
-
-#, fuzzy
-#~ msgid "reference to uninitialized field `$%s'"
-#~ msgstr "gặp tham chiếu đến trÆ°á»ng chÆ°a được sở khởi « $%d »"
+#: symbol.c:741
+msgid "can not pop main context"
+msgstr "không thể pop (lấy ra) ngữ cảnh chính"
-#~ msgid "can't convert string to float"
-#~ msgstr "không thể chuyển đổi chuá»—i sang Ä‘iá»u lÆ¡ lá»­ng"
+#~ msgid "range of the form `[%c-%c]' is locale dependent"
+#~ msgstr "vùng của dạng thức “[%c-%c]†phụ thuộc vào vị trí"
-#~ msgid "`continue' outside a loop is not portable"
-#~ msgstr ""
-#~ "không thể mang khả năng « continue » (tiếp tục) nằm ở ngoại vòng lặp"
-
-#~ msgid "`break' outside a loop is not portable"
-#~ msgstr "không thể mang khả năng « break » (ngắt) nằm ở ngoại vòng lặp"
-
-#~ msgid "`nextfile' cannot be called from a BEGIN rule"
-#~ msgstr ""
-#~ "không thể gá»i « nextfile » (tập tin kế tiếp) từ quy tắc « BEGIN » (bắt "
-#~ "đầu)"
-
-#~ msgid "`next' cannot be called from a BEGIN rule"
-#~ msgstr "không thể gá»i « next » (kế tiếp) từ quy tắc « BEGIN » (bắt đầu)"
-
-#~ msgid "file `%s' is a directory"
-#~ msgstr "tập tin « %s » là thư mục"
-
-#~ msgid "use `PROCINFO[\"%s\"]' instead of `%s'"
-#~ msgstr ""
-#~ "hãy dùng « PROCINFO[\"%s\"] » (thông tin tiến trình) thay cho « %s »"
-
-#~ msgid "use `PROCINFO[...]' instead of `/dev/user'"
-#~ msgstr ""
-#~ "hãy dùng « PROCINFO[...] » (thông tin tiến trình) thay cho </dev/user>"
-
-#~ 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"
+#~ msgid "attempt to use function `%s' as an array"
+#~ msgstr "cố gắng dùng hàm “%s†như mảng"
-#~ msgid "\t-W copyleft\t\t--copyleft\n"
-#~ msgstr ""
-#~ "\t-W copyleft\t\t--copyleft\n"
-#~ "(tắc quyá»n ngược)\n"
+#~ msgid "reference to uninitialized element `%s[\"%.*s\"]'"
+#~ msgstr "tham chiếu đến phần tá»­ chÆ°a khởi tạo “%s[â€%.*sâ€]â€"
-#~ msgid "\t-W usage\t\t--usage\n"
-#~ msgstr ""
-#~ "\t-W usage\t\t--usage\n"
-#~ "(cách sử dụng)\n"
+#~ msgid "subscript of array `%s' is null string"
+#~ msgstr "chữ in dưới mảng “%s†là chuỗi rỗng"
-#~ msgid ""
-#~ "\t# BEGIN block(s)\n"
-#~ "\n"
-#~ msgstr ""
-#~ "\t# khối BEGIN (bắt đầu)\n"
-#~ "\n"
+#~ msgid "%s: empty (null)\n"
+#~ msgstr "%s: rỗng (vô giá trị)\n"
-#~ msgid "must use `count$' on all formats or none"
-#~ msgstr "phải dùng « count$ » vá»›i má»i dạng thức hay không dùng cả"
+#~ msgid "%s: empty (zero)\n"
+#~ msgstr "%s: rỗng (số không)\n"
-#~ msgid "`$' is not permitted in awk formats"
-#~ msgstr "không cho phép « $ » trong định dạng awk"
+#~ msgid "%s: table_size = %d, array_size = %d\n"
+#~ msgstr "%s: cỡ_bảng = %d, cỡ_mảng = %d\n"
-#~ msgid "arg count with `$' must be > 0"
-#~ msgstr "số đếm đối số với « $ » phải là >0"
+#~ msgid "%s: array_ref to %s\n"
+#~ msgstr "%s: “array_ref†(mảng tham chiếu) đến “%sâ€\n"
-#~ 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"
+#~ msgid "`nextfile' is a gawk extension"
+#~ msgstr "“nextfile†(tập tin kế tiếp) là một phần mở rộng gawk"
-#~ msgid "`$' not permitted after period in format"
-#~ msgstr "không cho phép « $ » nằm sau dấu chấm trong định dạng"
+#~ msgid "`delete array' is a gawk extension"
+#~ msgstr "“delete array†(xoá mảng) là một phần mở rộng gawk"
-#~ msgid "no `$' supplied for positional field width or precision"
-#~ msgstr ""
-#~ "chÆ°a cung cấp « $ » cho Ä‘á»™ rá»™ng trÆ°á»ng thuá»™c vị trí hay cho Ä‘á»™ chính xác"
+#~ msgid "use of non-array as array"
+#~ msgstr "việc dùng cái khác mảng như là mảng"
-#~ 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"
+#~ msgid "`%s' is a Bell Labs extension"
+#~ msgstr "“%s†là một phần mở rộng của Bell Labs (Phòng thí nghiệm Bell)"
-#~ msgid "`l' is not permitted in POSIX awk formats"
-#~ msgstr "không cho phép chữ « l » nằm trong định dạng awk POSIX"
+#~ msgid "and: received non-numeric first argument"
+#~ msgstr "and: (và) đã nhận đối số đầu không phải thuộc số"
-#~ 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"
+#~ msgid "and: received non-numeric second argument"
+#~ msgstr "and: (và) đã nhận đối số thứ hai khác thuộc số"
-#~ msgid "`L' is not permitted in POSIX awk formats"
-#~ msgstr "không cho phép chữ « L » nằm trong định dạng awk POSIX"
+#~ msgid "or: received non-numeric first argument"
+#~ msgstr "or: (hoặc) đã nhận đối số đầu không phải thuộc số"
-#~ 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"
+#~ msgid "or: received non-numeric second argument"
+#~ msgstr "or: (hoặc) đã nhận đối số thứ hai khác thuộc số"
-#~ msgid "`h' is not permitted in POSIX awk formats"
-#~ msgstr "không cho phép chữ « h » nằm trong định dạng awk POSIX"
+#~ msgid "or(%lf, %lf): negative values will give strange results"
+#~ msgstr "or(%lf, %lf): (hoặc) giá trị âm sẽ gây ra kết quả lạ"
-#~ msgid "[s]printf: value %g is out of range for `%%%c' format"
-#~ msgstr "[s]printf: giá trị %g ở ngoại phạm vị cho dạng thức « %%%c »"
+#~ msgid "or(%lf, %lf): fractional values will be truncated"
+#~ msgstr "or(%lf, %lf): (hoặc) giá trị thuộc phân số sẽ bị xén ngắn"
-#~ msgid "not enough arguments to satisfy format string"
-#~ msgstr "chưa có đủ đối số để đáp ứng chuỗi định dạng"
+#~ msgid "xor: received non-numeric first argument"
+#~ msgstr "xor: (không hoặc) đã nhận đối số thứ nhất khác thuộc số"
-#~ msgid "^ ran out for this one"
-#~ msgstr "hết « ^ » cho Ä‘iá»u này"
+#~ msgid "xor: received non-numeric second argument"
+#~ msgstr "xor: đã nhận đối số thứ hai khác thuộc số"
-#~ 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"
+#~ msgid "xor(%lf, %lf): fractional values will be truncated"
+#~ msgstr "xor(%lf, %lf): (không hoặc) giá trị thuộc phân số sẽ bị xén ngắn"
-#~ msgid "too many arguments supplied for format string"
-#~ msgstr "quá nhiá»u đối số được cung cấp cho chuá»—i định dạng"
+#~ msgid "can't use function name `%s' as variable or array"
+#~ msgstr "không thể dùng tên hàm “%s†như là biến hay mảng"
-#, fuzzy
-#~ msgid "attempt to use array parameter `%s' in a scalar context"
-#~ msgstr "cố gắng dùng mảng « %s » trong một ngữ cảnh vô hướng"
+#~ msgid "assignment used in conditional context"
+#~ msgstr "Ä‘iá»u gán được dùng trong ngữ cảnh Ä‘iá»u kiện"
-#~ msgid "can't open two way socket `%s' for input/output (%s)"
-#~ msgstr "không thể mở ổ cắm hai chiá»u « %s » để nhập/xuất (%s)"
+#~ msgid "statement has no effect"
+#~ msgstr "câu không có tác dụng"
#~ 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 !"
-
-#~ msgid "illegal type (%s) in tree_eval"
-#~ msgstr "không cho phép kiểu (%s) trong « tree_eval » (ước lượng cây)"
-
-#~ msgid "\t# -- main --\n"
+#~ "for loop: array `%s' changed size from %ld to %ld during loop execution"
#~ msgstr ""
-#~ "\t# -- main --\n"
-#~ "(chính)\n"
-
-#~ msgid "invalid tree type %s in redirect()"
-#~ msgstr "kiểu cây không hợp lệ « %s » trong « redirect() »"
-
-#, fuzzy
-#~ msgid "# treated internally as `delete'"
-#~ msgstr "# được xá»­ lý ná»™i bá»™ là « delete » (xoá bá»)"
-
-#~ msgid "# this is a dynamically loaded extension function"
-#~ msgstr "# đây là một chức năng mở rộng được tải động"
-
-#~ msgid "unexpected type %s in prec_level"
-#~ msgstr "gặp kiểu bất ngỠ« %s » trong « prec_level » (cấp nằm trước?)"
+#~ "cho 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"
-#, fuzzy
-#~ msgid "Unknown node type %s in pp_var"
-#~ msgstr "không biết kiểu nút %d"
+#~ msgid "function called indirectly through `%s' does not exist"
+#~ msgstr "hàm được gá»i gián tiếp thông qua “%s†không tồn tại"
-#~ msgid "%s: illegal option -- %c\n"
-#~ msgstr "%s: không cho phép tùy chá»n « -- %c »\n"
+#~ msgid "function `%s' not defined"
+#~ msgstr "chÆ°a định nghÄ©a hàm “%sâ€"
diff --git a/po/zh_CN.gmo b/po/zh_CN.gmo
deleted file mode 100644
index 7ed096c3..00000000
--- a/po/zh_CN.gmo
+++ /dev/null
Binary files differ
diff --git a/posix/ChangeLog b/posix/ChangeLog
index 8aaeb418..b93b891f 100644
--- a/posix/ChangeLog
+++ b/posix/ChangeLog
@@ -1,3 +1,59 @@
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.1: Release tar ball made.
+
+2013-06-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.c (init_sockets): Remove ifdefs.
+
+2013-06-01 Eli Zaretskii <eliz@gnu.org>
+
+ * gawkmisc.c (init_sockets): New dummy function.
+
+2013-05-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.c (optimal_bufsize): Change check from HAVE_ST_BLKSIZE
+ to HAVE_STRUCT_STAT_ST_BLKSIZE.
+
+2013-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.0: Release tar ball made.
+
+2012-12-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.2: Release tar ball made.
+
+2012-10-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.c (os_isreadable): Change name of input parameter to
+ awk_inputbuf_t.
+
+2012-08-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.pc (os_isreadable): Take IOBUF_PUBLIC instead of fd and
+ use passed in info.
+
+2012-07-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.c (os_isreadable): Add isdir pointer parameter to be
+ set to true if fd is for a directory.
+
+2012-07-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.c (os_isreadable): New function.
+
+2012-05-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.c: Use `bool', `true', and `false' everywhere.
+
+2012-03-20 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkmisc.c (deflibpath): New global variable.
+
+2012-03-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.1: Release tar ball made.
+
2011-06-23 Arnold D. Robbins <arnold@skeeve.com>
* ChangeLog.0: Rotated ChangeLog into this file.
diff --git a/posix/gawkmisc.c b/posix/gawkmisc.c
index acc3c9d5..d422bd0f 100644
--- a/posix/gawkmisc.c
+++ b/posix/gawkmisc.c
@@ -26,6 +26,7 @@
char quote = '\'';
char *defpath = DEFPATH;
+char *deflibpath = DEFLIBPATH;
char envsep = ':';
#ifndef INVALID_HANDLE
@@ -92,8 +93,8 @@ optimal_bufsize(int fd, struct stat *stb)
{
char *val;
static size_t env_val = 0;
- static short first = TRUE;
- static short exact = FALSE;
+ static bool first = true;
+ static bool exact = false;
/* force all members to zero in case OS doesn't use all of them. */
memset(stb, '\0', sizeof(struct stat));
@@ -103,11 +104,11 @@ optimal_bufsize(int fd, struct stat *stb)
fatal("can't stat fd %d (%s)", fd, strerror(errno));
if (first) {
- first = FALSE;
+ first = false;
if ((val = getenv("AWKBUFSIZE")) != NULL) {
if (strcmp(val, "exact") == 0)
- exact = TRUE;
+ exact = true;
else if (isdigit((unsigned char) *val)) {
for (; *val && isdigit((unsigned char) *val); val++)
env_val = (env_val * 10) + *val - '0';
@@ -126,7 +127,7 @@ optimal_bufsize(int fd, struct stat *stb)
* guess. We use stdio's BUFSIZ, since that is what it was
* meant for in the first place.
*/
-#ifdef HAVE_ST_BLKSIZE
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
#define DEFBLKSIZE (stb->st_blksize > 0 ? stb->st_blksize : BUFSIZ)
#else
#define DEFBLKSIZE BUFSIZ
@@ -203,6 +204,34 @@ os_isdir(int fd)
return (fstat(fd, &sbuf) == 0 && S_ISDIR(sbuf.st_mode));
}
+/* os_isreadable --- fd can be read from */
+
+int
+os_isreadable(const awk_input_buf_t *iobuf, bool *isdir)
+{
+ *isdir = false;
+
+ if (iobuf->fd == INVALID_HANDLE)
+ return false;
+
+ switch (iobuf->sbuf.st_mode & S_IFMT) {
+ case S_IFREG:
+ case S_IFCHR: /* ttys, /dev/null, .. */
+#ifdef S_IFSOCK
+ case S_IFSOCK:
+#endif
+#ifdef S_IFIFO
+ case S_IFIFO:
+#endif
+ return true;
+ case S_IFDIR:
+ *isdir = true;
+ /* fall through */
+ default:
+ return false;
+ }
+}
+
/* os_is_setuid --- true if running setuid root */
int
@@ -256,6 +285,11 @@ files_are_same(char *path, SRCFILE *src)
&& st.st_ino == src->sbuf.st_ino);
}
+void
+init_sockets(void)
+{
+}
+
#ifdef __CYGWIN__
void
cygwin_premain0(int argc, char **argv, struct per_process *myself)
diff --git a/profile.c b/profile.c
index 5c581e8e..233bca0f 100644
--- a/profile.c
+++ b/profile.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1999-2011 the Free Software Foundation, Inc.
+ * Copyright (C) 1999-2013 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -25,28 +25,31 @@
#include "awk.h"
-static void pprint(INSTRUCTION *startp, INSTRUCTION *endp, int in_for_header);
+static void pprint(INSTRUCTION *startp, INSTRUCTION *endp, bool in_for_header);
+static void end_line(INSTRUCTION *ip);
static void pp_parenthesize(NODE *n);
static void parenthesize(int type, NODE *left, NODE *right);
static char *pp_list(int nargs, const char *paren, const char *delim);
-static char *pp_concat(const char *s1, const char *s2, const char *s3);
-static int is_binary(int type);
+static char *pp_group3(const char *s1, const char *s2, const char *s3);
+static char *pp_concat(int nargs);
+static bool is_binary(int type);
+static bool is_scalar(int type);
static int prec_level(int type);
static void pp_push(int type, char *s, int flag);
static NODE *pp_pop(void);
-static void pp_free(NODE *n);
+static void pprint(INSTRUCTION *startp, INSTRUCTION *endp, bool in_for_header);
+static void print_comment(INSTRUCTION *pc, long in);
const char *redir2str(int redirtype);
-#define pp_str hname
-#define pp_len hlength
+#define pp_str vname
+#define pp_len sub.nodep.reserved
+#define pp_next rnode
#define DONT_FREE 1
#define CAN_FREE 2
-#ifdef PROFILING
static RETSIGTYPE dump_and_exit(int signum) ATTRIBUTE_NORETURN;
static RETSIGTYPE just_dump(int signum);
-#endif
/* pretty printing related functions and variables */
@@ -59,20 +62,7 @@ static long indent_level = 0;
#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 |= DO_PROFILING;
- set_prof_file(def_file);
- }
-#endif
-}
-
-/* set_prof_file --- set the output file for profiling */
+/* set_prof_file --- set the output file for profiling or pretty-printing */
void
set_prof_file(const char *file)
@@ -87,12 +77,11 @@ set_prof_file(const char *file)
}
}
-/* init_profiling_signals --- set up signal handling for pgawk */
+/* init_profiling_signals --- set up signal handling for gawk --profile */
void
init_profiling_signals()
{
-#ifdef PROFILING
#ifdef __DJGPP__
signal(SIGINT, dump_and_exit);
signal(SIGQUIT, just_dump);
@@ -104,7 +93,6 @@ init_profiling_signals()
signal(SIGUSR1, just_dump);
#endif
#endif /* !__DJGPP__ */
-#endif /* PROFILING */
}
/* indent --- print out enough tabs */
@@ -114,10 +102,12 @@ indent(long count)
{
int i;
- if (count == 0)
- fprintf(prof_fp, "\t");
- else
- fprintf(prof_fp, "%6ld ", count);
+ if (do_profile) {
+ if (count == 0)
+ fprintf(prof_fp, "\t");
+ else
+ fprintf(prof_fp, "%6ld ", count);
+ }
assert(indent_level >= 0);
for (i = 0; i < indent_level; i++)
@@ -142,6 +132,8 @@ indent_out(void)
assert(indent_level >= 0);
}
+/* pp_push --- push a pretty printed string onto the stack */
+
static void
pp_push(int type, char *s, int flag)
{
@@ -151,19 +143,23 @@ pp_push(int type, char *s, int flag)
n->pp_len = strlen(s);
n->flags = flag;
n->type = type;
- n->hnext = pp_stack;
+ n->pp_next = pp_stack;
pp_stack = n;
}
+/* pp_pop --- pop a pretty printed string off the stack */
+
static NODE *
pp_pop()
{
NODE *n;
n = pp_stack;
- pp_stack = n->hnext;
+ pp_stack = n->pp_next;
return n;
}
+/* pp_free --- release a pretty printed node */
+
static void
pp_free(NODE *n)
{
@@ -172,18 +168,17 @@ pp_free(NODE *n)
freenode(n);
}
-/*
- * pprint --- pretty print a program segment
- */
+/* pprint --- pretty print a program segment */
static void
-pprint(INSTRUCTION *startp, INSTRUCTION *endp, int in_for_header)
+pprint(INSTRUCTION *startp, INSTRUCTION *endp, bool in_for_header)
{
INSTRUCTION *pc;
NODE *t1;
char *str;
NODE *t2;
- INSTRUCTION *ip;
+ INSTRUCTION *ip1;
+ INSTRUCTION *ip2;
NODE *m;
char *tmp;
int rule;
@@ -193,42 +188,74 @@ pprint(INSTRUCTION *startp, INSTRUCTION *endp, int in_for_header)
if (pc->source_line > 0)
sourceline = pc->source_line;
+ /* skip leading EOL comment as it has already been printed */
+ if (pc->opcode == Op_comment
+ && pc->memory->comment_type == EOL_COMMENT)
+ continue;
switch (pc->opcode) {
case Op_rule:
+ /*
+ * Rules are three instructions long.
+ * See append_rule in awkgram.y.
+ * The first has the Rule Op Code, nexti etc.
+ * The second, (pc + 1) has firsti and lasti:
+ * the first/last ACTION instructions for this rule.
+ * The third has first_line and last_line:
+ * the first and last source line numbers.
+ */
source = pc->source_file;
rule = pc->in_rule;
if (rule != Rule) {
- if (! rule_count[rule]++)
- fprintf(prof_fp, _("\t# %s block(s)\n\n"), ruletab[rule]);
- fprintf(prof_fp, "\t%s {\n", ruletab[rule]);
- ip = (pc + 1)->firsti;
+ /* Allow for pre-non-rule-block comment */
+ if (pc->nexti != (pc +1)->firsti
+ && pc->nexti->opcode == Op_comment
+ && pc->nexti->memory->comment_type == FULL_COMMENT)
+ print_comment(pc->nexti, -1);
+ ip1 = (pc + 1)->firsti;
+ ip2 = (pc + 1)->lasti;
+
+ if (do_profile) {
+ if (! rule_count[rule]++)
+ fprintf(prof_fp, _("\t# %s rule(s)\n\n"), ruletab[rule]);
+ indent(0);
+ }
+ fprintf(prof_fp, "%s {", ruletab[rule]);
+ end_line(pc);
} else {
- if (! rule_count[rule]++)
+ if (do_profile && ! rule_count[rule]++)
fprintf(prof_fp, _("\t# Rule(s)\n\n"));
- ip = pc->nexti;
- indent(ip->exec_count);
- if (ip != (pc + 1)->firsti) { /* non-empty pattern */
- pprint(ip->nexti, (pc + 1)->firsti, FALSE);
- t1 = pp_pop();
- fprintf(prof_fp, "%s {", t1->pp_str);
- pp_free(t1);
- ip = (pc + 1)->firsti;
-#ifdef PROFILING
- if (ip->exec_count > 0)
- fprintf(prof_fp, " # %ld", ip->exec_count);
-#endif
- fprintf(prof_fp, "\n");
+ ip1 = pc->nexti;
+ if (ip1 != (pc + 1)->firsti) { /* non-empty pattern */
+ pprint(ip1->nexti, (pc + 1)->firsti, false);
+ /* Allow for case where the "pattern" is just a comment */
+ if (ip1->nexti->nexti->nexti != (pc +1)->firsti
+ || ip1->nexti->opcode != Op_comment) {
+ t1 = pp_pop();
+ fprintf(prof_fp, "%s {", t1->pp_str);
+ pp_free(t1);
+ } else
+ fprintf(prof_fp, "{");
+ ip1 = (pc + 1)->firsti;
+ ip2 = (pc + 1)->lasti;
+
+ if (do_profile && ip1->exec_count > 0)
+ fprintf(prof_fp, " # %ld", ip1->exec_count);
+
+ end_line(ip1);
} else {
fprintf(prof_fp, "{\n");
- ip = (pc + 1)->firsti;
+ ip1 = (pc + 1)->firsti;
+ ip2 = (pc + 1)->lasti;
}
- ip = ip->nexti;
+ ip1 = ip1->nexti;
}
indent_in();
- pprint(ip, (pc + 1)->lasti, FALSE);
+ pprint(ip1, ip2, false);
indent_out();
- fprintf(prof_fp, "\t}\n\n");
+ if (do_profile)
+ indent(0);
+ fprintf(prof_fp, "}\n\n");
pc = (pc + 1)->lasti;
break;
@@ -244,12 +271,12 @@ pprint(INSTRUCTION *startp, INSTRUCTION *endp, int in_for_header)
if (m == Nnull_string) /* optional return or exit value; don't print 0 or "" */
pp_push(pc->opcode, m->stptr, DONT_FREE);
else if ((m->flags & NUMBER) != 0)
- pp_push(pc->opcode, pp_number(m->numbr), CAN_FREE);
+ pp_push(pc->opcode, pp_number(m), CAN_FREE);
else {
str = pp_string(m->stptr, m->stlen, '"');
if ((m->flags & INTLSTR) != 0) {
char *tmp = str;
- str = pp_concat("_", tmp, "");
+ str = pp_group3("_", tmp, "");
efree(tmp);
}
pp_push(pc->opcode, str, CAN_FREE);
@@ -306,14 +333,14 @@ pprint(INSTRUCTION *startp, INSTRUCTION *endp, int in_for_header)
case Op_assign_concat:
t2 = pp_pop(); /* l.h.s. */
t1 = pp_pop();
- tmp = pp_concat(t2->pp_str, op2str(Op_concat), t1->pp_str);
+ tmp = pp_group3(t2->pp_str, op2str(Op_concat), t1->pp_str);
fprintf(prof_fp, "%s%s%s", t2->pp_str, op2str(Op_assign), tmp);
efree(tmp);
cleanup:
pp_free(t2);
pp_free(t1);
if (! in_for_header)
- fprintf(prof_fp, "\n");
+ end_line(pc);
break;
default:
@@ -326,7 +353,7 @@ cleanup:
case Op_subscript:
tmp = pp_list(pc->sub_count, op2str(pc->opcode), ", ");
t1 = pp_pop();
- str = pp_concat(t1->pp_str, tmp, "");
+ str = pp_group3(t1->pp_str, tmp, "");
efree(tmp);
pp_free(t1);
pp_push(pc->opcode, str, CAN_FREE);
@@ -338,7 +365,7 @@ cleanup:
t2 = pp_pop();
t1 = pp_pop();
parenthesize(pc->opcode, t1, t2);
- str = pp_concat(t1->pp_str, op2str(pc->opcode), t2->pp_str);
+ str = pp_group3(t1->pp_str, op2str(pc->opcode), t2->pp_str);
pp_free(t1);
pp_free(t2);
pp_push(pc->opcode, str, CAN_FREE);
@@ -357,10 +384,10 @@ cleanup:
&& is_binary(t1->type)) /* (a - b) * 1 */
pp_parenthesize(t1);
if ((m->flags & NUMBER) != 0)
- tmp = pp_number(m->numbr);
+ tmp = pp_number(m);
else
tmp = pp_string(m->stptr, m->stlen, '"');
- str = pp_concat(t1->pp_str, op2str(pc->opcode), tmp);
+ str = pp_group3(t1->pp_str, op2str(pc->opcode), tmp);
efree(tmp);
pp_free(t1);
pp_push(pc->opcode, str, CAN_FREE);
@@ -381,7 +408,7 @@ cleanup:
t2 = pp_pop();
t1 = pp_pop();
parenthesize(pc->opcode, t1, t2);
- str = pp_concat(t1->pp_str, op2str(pc->opcode), t2->pp_str);
+ str = pp_group3(t1->pp_str, op2str(pc->opcode), t2->pp_str);
pp_free(t1);
pp_free(t2);
pp_push(pc->opcode, str, CAN_FREE);
@@ -393,9 +420,9 @@ cleanup:
case Op_postdecrement:
t1 = pp_pop();
if (pc->opcode == Op_preincrement || pc->opcode == Op_predecrement)
- str = pp_concat(op2str(pc->opcode), t1->pp_str, "");
+ str = pp_group3(op2str(pc->opcode), t1->pp_str, "");
else
- str = pp_concat(t1->pp_str, op2str(pc->opcode), "");
+ str = pp_group3(t1->pp_str, op2str(pc->opcode), "");
pp_free(t1);
pp_push(pc->opcode, str, CAN_FREE);
break;
@@ -405,11 +432,12 @@ cleanup:
case Op_unary_minus:
case Op_not:
t1 = pp_pop();
- if (is_binary(t1->type))
+ if (is_binary(t1->type)
+ || (((OPCODE) t1->type) == pc->opcode && pc->opcode == Op_unary_minus))
pp_parenthesize(t1);
/* optypes table (eval.c) includes space after ! */
- str = pp_concat(op2str(pc->opcode), t1->pp_str, "");
+ str = pp_group3(op2str(pc->opcode), t1->pp_str, "");
pp_free(t1);
pp_push(pc->opcode, str, CAN_FREE);
break;
@@ -423,7 +451,7 @@ cleanup:
case Op_assign_exp:
t2 = pp_pop(); /* l.h.s. */
t1 = pp_pop();
- str = pp_concat(t2->pp_str, op2str(pc->opcode), t1->pp_str);
+ str = pp_group3(t2->pp_str, op2str(pc->opcode), t1->pp_str);
pp_free(t2);
pp_free(t1);
pp_push(pc->opcode, str, CAN_FREE);
@@ -438,12 +466,11 @@ cleanup:
pp_free(t2);
pp_free(t1);
if (! in_for_header)
- fprintf(prof_fp, "\n");
+ end_line(pc);
break;
case Op_concat:
- str = pp_list(pc->expr_count, NULL,
- (pc->concat_flag & CSUBSEP) ? ", " : op2str(Op_concat));
+ str = pp_concat(pc->expr_count);
pp_push(Op_concat, str, CAN_FREE);
break;
@@ -454,13 +481,13 @@ cleanup:
array = t1->pp_str;
if (pc->expr_count > 0) {
char *sub;
- sub = pp_list(pc->expr_count, NULL, ", ");
+ sub = pp_list(pc->expr_count, NULL, pc->expr_count > 1 ? "][" : ", ");
fprintf(prof_fp, "%s %s[%s]", op2str(Op_K_delete), array, sub);
efree(sub);
} else
fprintf(prof_fp, "%s %s", op2str(Op_K_delete), array);
if (! in_for_header)
- fprintf(prof_fp, "\n");
+ end_line(pc);
pp_free(t1);
}
break;
@@ -477,12 +504,15 @@ cleanup:
array = t1->pp_str;
if (pc->expr_count > 1) {
sub = pp_list(pc->expr_count, "()", ", ");
- str = pp_concat(sub, op2str(Op_in_array), array);
+ str = pp_group3(sub, op2str(Op_in_array), array);
efree(sub);
} else {
t2 = pp_pop();
+ if (prec_level(t2->type) < prec_level(Op_in_array)) {
+ pp_parenthesize(t2);
+ }
sub = t2->pp_str;
- str = pp_concat(sub, op2str(Op_in_array), array);
+ str = pp_group3(sub, op2str(Op_in_array), array);
pp_free(t2);
}
pp_free(t1);
@@ -493,6 +523,7 @@ cleanup:
case Op_var_update:
case Op_var_assign:
case Op_field_assign:
+ case Op_subscript_assign:
case Op_arrayfor_init:
case Op_arrayfor_incr:
case Op_arrayfor_final:
@@ -513,12 +544,12 @@ cleanup:
case Op_sub_builtin:
{
const char *fname = "sub";
- if (pc->sub_flags & GSUB)
+ if ((pc->sub_flags & GSUB) != 0)
fname = "gsub";
- else if (pc->sub_flags & GENSUB)
+ else if ((pc->sub_flags & GENSUB) != 0)
fname = "gensub";
tmp = pp_list(pc->expr_count, "()", ", ");
- str = pp_concat(fname, tmp, "");
+ str = pp_group3(fname, tmp, "");
efree(tmp);
pp_push(Op_sub_builtin, str, CAN_FREE);
}
@@ -535,10 +566,10 @@ cleanup:
if (fname != NULL) {
if (pc->expr_count > 0) {
tmp = pp_list(pc->expr_count, "()", ", ");
- str = pp_concat(fname, tmp, "");
+ str = pp_group3(fname, tmp, "");
efree(tmp);
} else
- str = pp_concat(fname, "()", "");
+ str = pp_group3(fname, "()", "");
pp_push(Op_builtin, str, CAN_FREE);
} else
fatal(_("internal error: builtin with null fname"));
@@ -549,7 +580,7 @@ cleanup:
case Op_K_printf:
case Op_K_print_rec:
if (pc->opcode == Op_K_print_rec)
- tmp = pp_concat(" ", op2str(Op_field_spec), "0");
+ tmp = pp_group3(" ", op2str(Op_field_spec), "0");
else if (pc->redir_type != 0)
tmp = pp_list(pc->expr_count, "()", ", ");
else {
@@ -568,7 +599,7 @@ cleanup:
fprintf(prof_fp, "%s%s", op2str(pc->opcode), tmp);
efree(tmp);
if (! in_for_header)
- fprintf(prof_fp, "\n");
+ end_line(pc);
break;
case Op_push_re:
@@ -599,12 +630,12 @@ cleanup:
if (is_binary(t2->type))
pp_parenthesize(t2);
txt = t2->pp_str;
- str = pp_concat(txt, op2str(pc->opcode), restr);
+ str = pp_group3(txt, op2str(pc->opcode), restr);
pp_free(t2);
} else {
NODE *re = m->re_exp;
restr = pp_string(re->stptr, re->stlen, '/');
- str = pp_concat(txt, op2str(pc->opcode), restr);
+ str = pp_group3(txt, op2str(pc->opcode), restr);
efree(restr);
}
pp_free(t1);
@@ -616,10 +647,10 @@ cleanup:
case Op_K_getline_redir:
if (pc->into_var) {
t1 = pp_pop();
- tmp = pp_concat(op2str(Op_K_getline), " ", t1->pp_str);
+ tmp = pp_group3(op2str(Op_K_getline), " ", t1->pp_str);
pp_free(t1);
} else
- tmp = pp_concat(op2str(Op_K_getline), "", "");
+ tmp = pp_group3(op2str(Op_K_getline), "", "");
if (pc->redir_type != 0) {
int before = (pc->redir_type == redirect_pipein
@@ -629,9 +660,9 @@ cleanup:
if (is_binary(t2->type))
pp_parenthesize(t2);
if (before)
- str = pp_concat(t2->pp_str, redir2str(pc->redir_type), tmp);
+ str = pp_group3(t2->pp_str, redir2str(pc->redir_type), tmp);
else
- str = pp_concat(tmp, redir2str(pc->redir_type), t2->pp_str);
+ str = pp_group3(tmp, redir2str(pc->redir_type), t2->pp_str);
efree(tmp);
pp_free(t2);
} else
@@ -653,10 +684,10 @@ cleanup:
pcount = (pc + 1)->expr_count;
if (pcount > 0) {
tmp = pp_list(pcount, "()", ", ");
- str = pp_concat(pre, fname, tmp);
+ str = pp_group3(pre, fname, tmp);
efree(tmp);
} else
- str = pp_concat(pre, fname, "()");
+ str = pp_group3(pre, fname, "()");
if (pc->opcode == Op_indirect_func_call) {
t1 = pp_pop(); /* indirect var */
pp_free(t1);
@@ -686,33 +717,33 @@ cleanup:
t1 = pp_pop();
fprintf(prof_fp, "%s", t1->pp_str);
if (! in_for_header)
- fprintf(prof_fp, "\n");
+ end_line(pc);
pp_free(t1);
break;
case Op_line_range:
- ip = pc + 1;
- pprint(pc->nexti, ip->condpair_left, FALSE);
- pprint(ip->condpair_left->nexti, ip->condpair_right, FALSE);
+ ip1 = pc + 1;
+ pprint(pc->nexti, ip1->condpair_left, false);
+ pprint(ip1->condpair_left->nexti, ip1->condpair_right, false);
t2 = pp_pop();
t1 = pp_pop();
- str = pp_concat(t1->pp_str, ", ", t2->pp_str);
+ str = pp_group3(t1->pp_str, ", ", t2->pp_str);
pp_free(t1);
pp_free(t2);
pp_push(Op_line_range, str, CAN_FREE);
- pc = ip->condpair_right;
+ pc = ip1->condpair_right;
break;
case Op_K_while:
- ip = pc + 1;
- indent(ip->while_body->exec_count);
+ ip1 = pc + 1;
+ indent(ip1->while_body->exec_count);
fprintf(prof_fp, "%s (", op2str(pc->opcode));
- pprint(pc->nexti, ip->while_body, FALSE);
+ pprint(pc->nexti, ip1->while_body, false);
t1 = pp_pop();
fprintf(prof_fp, "%s) {\n", t1->pp_str);
pp_free(t1);
indent_in();
- pprint(ip->while_body->nexti, pc->target_break, FALSE);
+ pprint(ip1->while_body->nexti, pc->target_break, false);
indent_out();
indent(SPACEOVER);
fprintf(prof_fp, "}\n");
@@ -720,13 +751,13 @@ cleanup:
break;
case Op_K_do:
- ip = pc + 1;
+ ip1 = pc + 1;
indent(pc->nexti->exec_count);
fprintf(prof_fp, "%s {\n", op2str(pc->opcode));
indent_in();
- pprint(pc->nexti->nexti, ip->doloop_cond, FALSE);
+ pprint(pc->nexti->nexti, ip1->doloop_cond, false);
indent_out();
- pprint(ip->doloop_cond, pc->target_break, FALSE);
+ pprint(ip1->doloop_cond, pc->target_break, false);
indent(SPACEOVER);
t1 = pp_pop();
fprintf(prof_fp, "} %s (%s)\n", op2str(Op_K_while), t1->pp_str);
@@ -735,26 +766,34 @@ cleanup:
break;
case Op_K_for:
- ip = pc + 1;
- indent(ip->forloop_body->exec_count);
+ ip1 = pc + 1;
+ indent(ip1->forloop_body->exec_count);
fprintf(prof_fp, "%s (", op2str(pc->opcode));
- pprint(pc->nexti, ip->forloop_cond, TRUE);
- fprintf(prof_fp, "; ");
- if (ip->forloop_cond->opcode == Op_no_op &&
- ip->forloop_cond->nexti == ip->forloop_body)
+ /* If empty for looop header, print it a little more nicely. */
+ if ( pc->nexti->opcode == Op_no_op
+ && ip1->forloop_cond == pc->nexti
+ && pc->target_continue->opcode == Op_jmp) {
+ fprintf(prof_fp, ";;");
+ } else {
+ pprint(pc->nexti, ip1->forloop_cond, true);
fprintf(prof_fp, "; ");
- else {
- pprint(ip->forloop_cond, ip->forloop_body, TRUE);
- t1 = pp_pop();
- fprintf(prof_fp, "%s; ", t1->pp_str);
- pp_free(t1);
- }
- pprint(pc->target_continue, pc->target_break, TRUE);
+ if (ip1->forloop_cond->opcode == Op_no_op &&
+ ip1->forloop_cond->nexti == ip1->forloop_body)
+ fprintf(prof_fp, "; ");
+ else {
+ pprint(ip1->forloop_cond, ip1->forloop_body, true);
+ t1 = pp_pop();
+ fprintf(prof_fp, "%s; ", t1->pp_str);
+ pp_free(t1);
+ }
+
+ pprint(pc->target_continue, pc->target_break, true);
+ }
fprintf(prof_fp, ") {\n");
indent_in();
- pprint(ip->forloop_body->nexti, pc->target_continue, FALSE);
+ pprint(ip1->forloop_body->nexti, pc->target_continue, false);
indent_out();
indent(SPACEOVER);
fprintf(prof_fp, "}\n");
@@ -766,20 +805,20 @@ cleanup:
char *array;
const char *item;
- ip = pc + 1;
+ ip1 = pc + 1;
t1 = pp_pop();
array = t1->pp_str;
- m = ip->forloop_cond->array_var;
+ m = ip1->forloop_cond->array_var;
if (m->type == Node_param_list)
item = func_params[m->param_cnt].param;
else
item = m->vname;
- indent(ip->forloop_body->exec_count);
+ indent(ip1->forloop_body->exec_count);
fprintf(prof_fp, "%s (%s%s%s) {\n", op2str(Op_K_arrayfor),
item, op2str(Op_in_array), array);
indent_in();
pp_free(t1);
- pprint(ip->forloop_body->nexti, pc->target_break, FALSE);
+ pprint(ip1->forloop_body->nexti, pc->target_break, false);
indent_out();
indent(SPACEOVER);
fprintf(prof_fp, "}\n");
@@ -788,13 +827,13 @@ cleanup:
break;
case Op_K_switch:
- ip = pc + 1;
+ ip1 = pc + 1;
fprintf(prof_fp, "%s (", op2str(pc->opcode));
- pprint(pc->nexti, ip->switch_start, FALSE);
+ pprint(pc->nexti, ip1->switch_start, false);
t1 = pp_pop();
fprintf(prof_fp, "%s) {\n", t1->pp_str);
pp_free(t1);
- pprint(ip->switch_start, ip->switch_end, FALSE);
+ pprint(ip1->switch_start, ip1->switch_end, false);
indent(SPACEOVER);
fprintf(prof_fp, "}\n");
pc = pc->target_break;
@@ -810,23 +849,23 @@ cleanup:
} else
fprintf(prof_fp, "%s:\n", op2str(pc->opcode));
indent_in();
- pprint(pc->stmt_start->nexti, pc->stmt_end->nexti, FALSE);
+ pprint(pc->stmt_start->nexti, pc->stmt_end->nexti, false);
indent_out();
break;
case Op_K_if:
fprintf(prof_fp, "%s (", op2str(pc->opcode));
- pprint(pc->nexti, pc->branch_if, FALSE);
+ pprint(pc->nexti, pc->branch_if, false);
t1 = pp_pop();
fprintf(prof_fp, "%s) {", t1->pp_str);
pp_free(t1);
- ip = pc->branch_if;
- if (ip->exec_count > 0)
- fprintf(prof_fp, " # %ld", ip->exec_count);
- fprintf(prof_fp, "\n");
+ ip1 = pc->branch_if;
+ if (ip1->exec_count > 0)
+ fprintf(prof_fp, " # %ld", ip1->exec_count);
+ end_line(pc);
indent_in();
- pprint(ip->nexti, pc->branch_else, FALSE);
+ pprint(ip1->nexti, pc->branch_else, false);
indent_out();
pc = pc->branch_else;
if (pc->nexti->opcode == Op_no_op) {
@@ -838,7 +877,7 @@ cleanup:
case Op_K_else:
fprintf(prof_fp, "} %s {\n", op2str(pc->opcode));
indent_in();
- pprint(pc->nexti, pc->branch_end, FALSE);
+ pprint(pc->nexti, pc->branch_end, false);
indent_out();
indent(SPACEOVER);
fprintf(prof_fp, "}\n");
@@ -850,14 +889,14 @@ cleanup:
NODE *f, *t, *cond;
size_t len;
- pprint(pc->nexti, pc->branch_if, FALSE);
- ip = pc->branch_if;
- pprint(ip->nexti, pc->branch_else, FALSE);
- ip = pc->branch_else->nexti;
+ pprint(pc->nexti, pc->branch_if, false);
+ ip1 = pc->branch_if;
+ pprint(ip1->nexti, pc->branch_else, false);
+ ip1 = pc->branch_else->nexti;
- pc = ip->nexti;
+ pc = ip1->nexti;
assert(pc->opcode == Op_cond_exp);
- pprint(pc->nexti, pc->branch_end, FALSE);
+ pprint(pc->nexti, pc->branch_end, false);
f = pp_pop();
t = pp_pop();
@@ -880,6 +919,13 @@ cleanup:
indent(pc->exec_count);
break;
+ case Op_comment:
+ print_comment(pc, 0);
+ break;
+
+ case Op_list:
+ break;
+
default:
cant_happen();
}
@@ -889,6 +935,21 @@ cleanup:
}
}
+/* end_line --- end pretty print line with new line or on-line comment */
+
+void
+end_line(INSTRUCTION *ip)
+{
+ if (ip->nexti->opcode == Op_comment
+ && ip->nexti->memory->comment_type == EOL_COMMENT) {
+ fprintf(prof_fp, "\t");
+ print_comment(ip->nexti, -1);
+ ip = ip->nexti->nexti;
+ }
+ else
+ fprintf(prof_fp, "\n");
+}
+
/* pp_string_fp --- printy print a string to the fp */
/*
@@ -898,7 +959,7 @@ cleanup:
void
pp_string_fp(Func_print print_func, FILE *fp, const char *in_str,
- size_t len, int delim, int breaklines)
+ size_t len, int delim, bool breaklines)
{
char *s = pp_string(in_str, len, delim);
int count;
@@ -908,16 +969,16 @@ pp_string_fp(Func_print print_func, FILE *fp, const char *in_str,
slen = strlen(str);
for (count = 0; slen > 0; slen--, str++) {
+ print_func(fp, "%c", *str);
if (++count >= BREAKPOINT && breaklines) {
print_func(fp, "%c\n%c", delim, delim);
count = 0;
- } else
- print_func(fp, "%c", *str);
+ }
}
efree(s);
}
-#ifdef PROFILING
+
/* just_dump --- dump the profile and function stack and keep going */
static RETSIGTYPE
@@ -938,10 +999,54 @@ static RETSIGTYPE
dump_and_exit(int signum)
{
just_dump(signum);
- exit(EXIT_FAILURE);
+ final_exit(EXIT_FAILURE);
}
-#endif
+/* print_lib_list --- print a list of all libraries loaded */
+
+static void
+print_lib_list(FILE *prof_fp)
+{
+ SRCFILE *s;
+ static bool printed_header = false;
+
+ for (s = srcfiles->next; s != srcfiles; s = s->next) {
+ if (s->stype == SRC_EXTLIB) {
+ if (! printed_header) {
+ printed_header = true;
+ fprintf(prof_fp, _("\t# Loaded extensions (-l and/or @load)\n\n"));
+ }
+ fprintf(prof_fp, "\t@load \"%s\"\n", s->src);
+ }
+ }
+ if (printed_header) /* we found some */
+ fprintf(prof_fp, "\n");
+}
+
+/* print_comment --- print comment text with proper indentation */
+
+static void
+print_comment(INSTRUCTION* pc, long in)
+{
+ char *text;
+ size_t count;
+ bool after_newline = false;
+
+ count = pc->memory->stlen;
+ text = pc->memory->stptr;
+
+ if (in >= 0)
+ indent(in); /* is this correct? Where should comments go? */
+ for (; count > 0; count--, text++) {
+ if (after_newline) {
+ indent(in);
+ after_newline = false;
+ }
+ putc(*text, prof_fp);
+ if (*text == '\n')
+ after_newline = true;
+ }
+}
/* dump_prog --- dump the program */
@@ -957,8 +1062,10 @@ dump_prog(INSTRUCTION *code)
(void) time(& now);
/* \n on purpose, with \n in ctime() output */
- fprintf(prof_fp, _("\t# gawk profile, created %s\n"), ctime(& now));
- pprint(code, NULL, FALSE);
+ if (do_profile)
+ fprintf(prof_fp, _("\t# gawk profile, created %s\n"), ctime(& now));
+ print_lib_list(prof_fp);
+ pprint(code, NULL, false);
}
/* prec_level --- return the precedence of an operator, for paren tests */
@@ -979,25 +1086,25 @@ prec_level(int type)
case Op_func_call:
case Op_K_delete_loop:
case Op_builtin:
- return 15;
+ return 16;
case Op_field_spec:
case Op_field_spec_lhs:
- return 14;
-
- case Op_exp:
- case Op_exp_i:
- return 13;
+ return 15;
case Op_preincrement:
case Op_predecrement:
case Op_postincrement:
case Op_postdecrement:
- return 12;
+ return 14;
+
+ case Op_exp:
+ case Op_exp_i:
+ return 13;
case Op_unary_minus:
case Op_not:
- return 11;
+ return 12;
case Op_times:
case Op_times_i:
@@ -1005,23 +1112,26 @@ prec_level(int type)
case Op_quotient_i:
case Op_mod:
case Op_mod_i:
- return 10;
+ return 11;
case Op_plus:
case Op_plus_i:
case Op_minus:
case Op_minus_i:
- return 9;
+ return 10;
case Op_concat:
case Op_assign_concat:
- return 8;
+ return 9;
case Op_equal:
case Op_notequal:
case Op_greater:
+ case Op_less:
case Op_leq:
case Op_geq:
+ return 8;
+
case Op_match:
case Op_nomatch:
return 7;
@@ -1030,9 +1140,6 @@ prec_level(int type)
case Op_K_getline_redir:
return 6;
- case Op_less:
- return 5;
-
case Op_in_array:
return 5;
@@ -1059,7 +1166,40 @@ prec_level(int type)
}
}
-static int
+/* is_scalar --- return true if scalar, false otherwise */
+
+static bool
+is_scalar(int type)
+{
+ switch (type) {
+ case Op_push_lhs:
+ case Op_push_param:
+ case Op_push_array:
+ case Op_push:
+ case Op_push_i:
+ case Op_push_re:
+ case Op_subscript:
+ case Op_subscript_lhs:
+ case Op_func_call:
+ case Op_builtin:
+ case Op_field_spec:
+ case Op_field_spec_lhs:
+ case Op_preincrement:
+ case Op_predecrement:
+ case Op_postincrement:
+ case Op_postdecrement:
+ case Op_unary_minus:
+ case Op_not:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/* is_binary --- return true if type represents a binary operator */
+
+static bool
is_binary(int type)
{
switch (type) {
@@ -1098,14 +1238,14 @@ is_binary(int type)
case Op_in_array:
case Op_K_getline_redir: /* sometimes */
case Op_K_getline:
- return TRUE;
+ return true;
default:
- return FALSE;
+ return false;
}
}
-/* parenthesize --- parenthesize an expression in stack */
+/* pp_parenthesize --- parenthesize an expression in stack */
static void
pp_parenthesize(NODE *sp)
@@ -1125,6 +1265,28 @@ pp_parenthesize(NODE *sp)
sp->flags |= CAN_FREE;
}
+/* div_on_left_mul_on_right --- have / or % on left and * on right */
+
+static bool
+div_on_left_mul_on_right(int o1, int o2)
+{
+ OPCODE op1 = (OPCODE) o1;
+ OPCODE op2 = (OPCODE) o2;
+
+ switch (op1) {
+ case Op_quotient:
+ case Op_quotient_i:
+ case Op_mod:
+ case Op_mod_i:
+ return (op2 == Op_times || op2 == Op_times_i);
+
+ default:
+ return false;
+ }
+}
+
+/* parenthesize --- parenthesize two nodes relative to parent node type */
+
static void
parenthesize(int type, NODE *left, NODE *right)
{
@@ -1132,15 +1294,12 @@ parenthesize(int type, NODE *left, NODE *right)
int lprec = prec_level(left->type);
int prec = prec_level(type);
- if (prec > lprec) {
- if (is_binary(left->type)) /* (a - b) * c */
- pp_parenthesize(left);
- if (prec >= rprec && is_binary(right->type)) /* (a - b) * (c - d) */
- pp_parenthesize(right);
- } else {
- if (prec >= rprec && is_binary(right->type)) /* a - b - (c - d) */
- pp_parenthesize(right);
- }
+ if (lprec < prec
+ || (lprec == prec && div_on_left_mul_on_right(left->type, type)))
+ pp_parenthesize(left);
+ if (rprec < prec
+ || (rprec == prec && div_on_left_mul_on_right(type, right->type)))
+ pp_parenthesize(right);
}
/* pp_string --- pretty format a string or regex constant */
@@ -1177,7 +1336,7 @@ pp_string(const char *in_str, size_t len, int delim)
obufout = obuf + olen; \
ofre += osiz; \
osiz *= 2; \
-} ofre -= (l)
+ } ofre -= (l)
osiz = len + 3 + 2; /* initial size; 3 for delim + terminating null */
emalloc(obuf, char *, osiz, "pp_string");
@@ -1190,6 +1349,13 @@ pp_string(const char *in_str, size_t len, int delim)
if (delim != '/' && *str == delim) {
*obufout++ = '\\';
*obufout++ = delim;
+ } else if (*str == '\0') {
+ chksize(4);
+
+ *obufout++ = '\\';
+ *obufout++ = '0';
+ *obufout++ = '0';
+ *obufout++ = '0';
} else if ((cp = strchr(escapes, *str)) != NULL) {
i = cp - escapes;
*obufout++ = '\\';
@@ -1209,7 +1375,7 @@ pp_string(const char *in_str, size_t len, int delim)
obufout += len;
}
}
- chksize(1);
+ chksize(2);
*obufout++ = delim;
*obufout = '\0';
return obuf;
@@ -1219,13 +1385,20 @@ pp_string(const char *in_str, size_t len, int delim)
/* pp_number --- pretty format a number */
char *
-pp_number(AWKNUM d)
+pp_number(NODE *n)
{
#define PP_PRECISION 6
char *str;
emalloc(str, char *, PP_PRECISION + 10, "pp_number");
- sprintf(str, "%0.*g", PP_PRECISION, d);
+#ifdef HAVE_MPFR
+ if (is_mpg_float(n))
+ mpfr_sprintf(str, "%0.*R*g", PP_PRECISION, ROUND_MODE, n->mpg_numbr);
+ else if (is_mpg_integer(n))
+ mpfr_sprintf(str, "%Zd", n->mpg_i);
+ else
+#endif
+ sprintf(str, "%0.*g", PP_PRECISION, n->numbr);
return str;
#undef PP_PRECISION
}
@@ -1236,10 +1409,12 @@ char *
pp_node(NODE *n)
{
if ((n->flags & NUMBER) != 0)
- return pp_number(n->numbr);
+ return pp_number(n);
return pp_string(n->stptr, n->stlen, '"');
}
+/* pp_list --- pretty print a list, with surrounding characters and separator */
+
static NODE **pp_args = NULL;
static int npp_args;
@@ -1295,8 +1470,101 @@ pp_list(int nargs, const char *paren, const char *delim)
return str;
}
+/* is_unary_minus --- return true if string starts with unary minus */
+
+static bool
+is_unary_minus(const char *str)
+{
+ return str[0] == '-' && str[1] != '-';
+}
+
+/* pp_concat --- handle concatenation and correct parenthesizing of expressions */
+
static char *
-pp_concat(const char *s1, const char *s2, const char *s3)
+pp_concat(int nargs)
+{
+ NODE *r;
+ char *str, *s;
+ size_t len;
+ static const size_t delimlen = 1; /* " " */
+ int i;
+ int pl_l, pl_r;
+
+ if (pp_args == NULL) {
+ npp_args = nargs;
+ emalloc(pp_args, NODE **, (nargs + 2) * sizeof(NODE *), "pp_concat");
+ } else if (nargs > npp_args) {
+ npp_args = nargs;
+ erealloc(pp_args, NODE **, (nargs + 2) * sizeof(NODE *), "pp_concat");
+ }
+
+ /*
+ * items are on the stack in reverse order that they
+ * will be printed to pop them off backwards.
+ */
+
+ len = -delimlen;
+ for (i = nargs; i >= 1; i--) {
+ r = pp_args[i] = pp_pop();
+ len += r->pp_len + delimlen + 2;
+ }
+
+ emalloc(str, char *, len + 1, "pp_concat");
+ s = str;
+
+ /* now copy in */
+ for (i = 1; i < nargs; i++) {
+ r = pp_args[i];
+
+ pl_l = prec_level(pp_args[i]->type);
+ pl_r = prec_level(pp_args[i+1]->type);
+
+ if (i >= 2 && is_unary_minus(r->pp_str)) {
+ *s++ = '(';
+ memcpy(s, r->pp_str, r->pp_len);
+ s += r->pp_len;
+ *s++ = ')';
+ } else if (is_scalar(pp_args[i]->type) && is_scalar(pp_args[i+1]->type)) {
+ memcpy(s, r->pp_str, r->pp_len);
+ s += r->pp_len;
+ } else if (pl_l <= pl_r || is_scalar(pp_args[i+1]->type)) {
+ *s++ = '(';
+ memcpy(s, r->pp_str, r->pp_len);
+ s += r->pp_len;
+ *s++ = ')';
+ } else {
+ memcpy(s, r->pp_str, r->pp_len);
+ s += r->pp_len;
+ }
+ pp_free(r);
+
+ if (i < nargs) {
+ *s++ = ' ';
+ }
+ }
+
+ pl_l = prec_level(pp_args[nargs-1]->type);
+ pl_r = prec_level(pp_args[nargs]->type);
+ r = pp_args[nargs];
+ if (is_unary_minus(r->pp_str) || ((pl_l >= pl_r && ! is_scalar(pp_args[nargs]->type)))) {
+ *s++ = '(';
+ memcpy(s, r->pp_str, r->pp_len);
+ s += r->pp_len;
+ *s++ = ')';
+ } else {
+ memcpy(s, r->pp_str, r->pp_len);
+ s += r->pp_len;
+ }
+ pp_free(r);
+
+ *s = '\0';
+ return str;
+}
+
+/* pp_group3 --- string together up to 3 strings */
+
+static char *
+pp_group3(const char *s1, const char *s2, const char *s3)
{
size_t len1, len2, len3, l;
char *str, *s;
@@ -1305,7 +1573,7 @@ pp_concat(const char *s1, const char *s2, const char *s3)
len2 = strlen(s2);
len3 = strlen(s3);
l = len1 + len2 + len3 + 2;
- emalloc(str, char *, l, "pp_concat");
+ emalloc(str, char *, l, "pp_group3");
s = str;
if (len1 > 0) {
memcpy(s, s1, len1);
@@ -1329,17 +1597,27 @@ int
pp_func(INSTRUCTION *pc, void *data ATTRIBUTE_UNUSED)
{
int j;
- static int first = TRUE;
+ static bool first = true;
NODE *func;
int pcount;
+ INSTRUCTION *fp;
if (first) {
- first = FALSE;
- fprintf(prof_fp, _("\n\t# Functions, listed alphabetically\n"));
+ first = false;
+ if (do_profile)
+ fprintf(prof_fp, _("\n\t# Functions, listed alphabetically\n"));
}
+ fp = pc->nexti->nexti;
func = pc->func_body;
fprintf(prof_fp, "\n");
+
+ /* print any function comment */
+ if (fp->opcode == Op_comment && fp->source_line == 0) {
+ print_comment(fp, -1); /* -1 ==> don't indent */
+ fp = fp->nexti;
+ }
+
indent(pc->nexti->exec_count);
fprintf(prof_fp, "%s %s(", op2str(Op_K_function), func->vname);
pcount = func->param_cnt;
@@ -1349,11 +1627,16 @@ pp_func(INSTRUCTION *pc, void *data ATTRIBUTE_UNUSED)
if (j < pcount - 1)
fprintf(prof_fp, ", ");
}
- fprintf(prof_fp, ")\n\t{\n");
+ fprintf(prof_fp, ")\n");
+ if (do_profile)
+ indent(0);
+ fprintf(prof_fp, "{\n");
indent_in();
- pprint(pc->nexti->nexti, NULL, FALSE); /* function body */
+ pprint(fp, NULL, false); /* function body */
indent_out();
- fprintf(prof_fp, "\t}\n");
+ if (do_profile)
+ indent(0);
+ fprintf(prof_fp, "}\n");
return 0;
}
@@ -1368,13 +1651,11 @@ redir2str(int redirtype)
" >> ", /* redirect_append */
" | ", /* redirect_pipe */
" | ", /* redirect_pipein */
- " < " /* redirect_input */
- " |& " /* redirect_twoway */
+ " < ", /* redirect_input */
+ " |& ", /* redirect_twoway */
};
if (redirtype < 0 || redirtype > redirect_twoway)
fatal(_("redir2str: unknown redirection type %d"), redirtype);
return redirtab[redirtype];
}
-
-
diff --git a/protos.h b/protos.h
index 0afe4bbc..7bef8b84 100644
--- a/protos.h
+++ b/protos.h
@@ -26,9 +26,9 @@
#ifndef STDC_HEADERS
#define aptr_t void * /* arbitrary pointer type */
-extern aptr_t malloc(MALLOC_ARG_T);
-extern aptr_t realloc(aptr_t, MALLOC_ARG_T);
-extern aptr_t calloc(MALLOC_ARG_T, MALLOC_ARG_T);
+extern aptr_t malloc(size_t);
+extern aptr_t realloc(aptr_t, size_t);
+extern aptr_t calloc(size_t, size_t);
extern void free(aptr_t);
extern char *getenv(const char *);
diff --git a/random.h b/random.h
index 626cbcdb..d4c6ef16 100644
--- a/random.h
+++ b/random.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1996, 2001, 2004, 2005 the Free Software Foundation, Inc.
+ * Copyright (C) 1996, 2001, 2004, 2005, 2013 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -40,11 +40,4 @@ typedef long gawk_int32_t;
#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));
+extern long random (void);
diff --git a/re.c b/re.c
index cec95dac..edb5bc48 100644
--- a/re.c
+++ b/re.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1991-2011 the Free Software Foundation, Inc.
+ * Copyright (C) 1991-2013 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -27,12 +27,14 @@
static reg_syntax_t syn;
static void check_bracket_exp(char *s, size_t len);
+const char *regexflags2str(int flags);
/* make_regexp --- generate compiled regular expressions */
Regexp *
-make_regexp(const char *s, size_t len, int ignorecase, int dfa, int canfatal)
+make_regexp(const char *s, size_t len, bool ignorecase, bool dfa, bool canfatal)
{
+ static char metas[] = ".*+(){}[]|?^$\\";
Regexp *rp;
const char *rerr;
const char *src = s;
@@ -41,26 +43,23 @@ make_regexp(const char *s, size_t len, int ignorecase, int dfa, int canfatal)
const char *end = s + len;
char *dest;
int c, c2;
- static short first = TRUE;
- static short no_dfa = FALSE;
- int has_anchor = FALSE;
- int may_have_range = 0;
+ static bool first = true;
+ static bool no_dfa = false;
+ bool has_anchor = false;
reg_syntax_t dfa_syn;
+ int i;
/*
* 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;
-#if MBS_SUPPORT
mbstate_t mbs;
- if (gawk_mb_cur_max > 1)
- memset(&mbs, 0, sizeof(mbstate_t)); /* Initialize. */
-#endif
+ memset(&mbs, 0, sizeof(mbstate_t)); /* Initialize. */
if (first) {
- first = FALSE;
+ first = false;
/* for debugging and testing */
no_dfa = (getenv("GAWK_NO_DFA") != NULL);
}
@@ -85,20 +84,18 @@ make_regexp(const char *s, size_t len, int ignorecase, int dfa, int canfatal)
dest = buf;
while (src < end) {
-#if 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. */
+ if ( is_multibyte == 1
+ || is_multibyte == (size_t) -1
+ || is_multibyte == (size_t) -2
+ || is_multibyte == 0) {
+ /* We treat it as a single-byte character. */
is_multibyte = 0;
}
}
-#endif
/* We skip multibyte character, since it must not be a special
character. */
@@ -160,9 +157,7 @@ make_regexp(const char *s, size_t len, int ignorecase, int dfa, int canfatal)
} else {
c = *src;
if (c == '^' || c == '$')
- has_anchor = TRUE;
- if (c == '[' || c == '-' || c == ']')
- may_have_range++;
+ has_anchor = true;
*dest++ = *src++; /* not '\\' */
}
@@ -225,14 +220,29 @@ make_regexp(const char *s, size_t len, int ignorecase, int dfa, int canfatal)
}
/* gack. this must be done *after* re_compile_pattern */
- rp->pat.newline_anchor = FALSE; /* don't get \n in middle of string */
+ rp->pat.newline_anchor = false; /* don't get \n in middle of string */
if (dfa && ! no_dfa) {
- rp->dfa = TRUE;
+ rp->dfa = true;
rp->dfareg = dfaalloc();
- dfacomp(buf, len, rp->dfareg, TRUE);
+ dfacomp(buf, len, rp->dfareg, true);
} else
- rp->dfa = FALSE;
+ rp->dfa = false;
rp->has_anchor = has_anchor;
+
+ /* Additional flags that help with RS as regexp. */
+ for (i = 0; i < len; i++) {
+ if (strchr(metas, buf[i]) != NULL) {
+ rp->has_meta = true;
+ break;
+ }
+ }
+
+ for (i = len - 1; i >= 0; i--) {
+ if (strchr("*+|?", buf[i]) != NULL) {
+ rp->maybe_long = true;
+ break;
+ }
+ }
return rp;
}
@@ -244,7 +254,7 @@ research(Regexp *rp, char *str, int start,
size_t len, int flags)
{
const char *ret = str;
- int try_backref;
+ int try_backref = false;
int need_start;
int no_bol;
int res;
@@ -268,19 +278,24 @@ research(Regexp *rp, char *str, int start,
*/
if (rp->dfa && ! no_bol && ! need_start) {
char save;
- int count = 0;
+ size_t count = 0;
+ struct dfa *superset = dfasuperset(rp->dfareg);
/*
* 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);
+ if (superset)
+ ret = dfaexec(superset, str+start, str+start+len,
+ true, NULL, NULL);
+ if (ret)
+ 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) {
+ 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.
@@ -322,6 +337,7 @@ void
dfaerror(const char *s)
{
fatal("%s", s);
+ exit(EXIT_FATAL); /* for DJGPP */
}
/* re_update --- recompile a dynamic regexp */
@@ -366,7 +382,7 @@ re_update(NODE *t)
}
/* compile it */
t->re_reg = make_regexp(t->re_text->stptr, t->re_text->stlen,
- IGNORECASE, t->re_cnt, TRUE);
+ IGNORECASE, t->re_cnt, true);
/* clear case flag */
t->re_flags &= ~CASE;
@@ -380,6 +396,13 @@ re_update(NODE *t)
void
resetup()
{
+ /*
+ * Syntax bits: _that_ is yet another mind trip. Recreational drugs
+ * are helpful for recovering from the experience.
+ *
+ * Aharon Robbins <arnold@skeeve.com>
+ * Sun, 21 Oct 2007 23:55:33 +0200
+ */
if (do_posix)
syn = RE_SYNTAX_POSIX_AWK; /* strict POSIX re's */
else if (do_traditional)
@@ -393,10 +416,10 @@ resetup()
* variable remains for use with --traditional.
*/
if (do_intervals)
- syn |= RE_INTERVALS | RE_INVALID_INTERVAL_ORD;
+ syn |= RE_INTERVALS | RE_INVALID_INTERVAL_ORD | RE_NO_BK_BRACES;
(void) re_set_syntax(syn);
- dfasyntax(syn, FALSE, '\n');
+ dfasyntax(syn, false, '\n');
}
/* avoid_dfa --- return true if we should not use the DFA matcher */
@@ -407,31 +430,26 @@ avoid_dfa(NODE *re, char *str, size_t len)
char *end;
if (! re->re_reg->has_anchor)
- return FALSE;
+ return false;
for (end = str + len; str < end; str++)
if (*str == '\n')
- return TRUE;
+ return true;
- return FALSE;
+ return false;
}
-/* reisstring --- return TRUE if the RE match is a simple string match */
+/* 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 */
- }
- }
+ /* simple checking for meta characters in re */
+ if (re->has_meta)
+ return false; /* give up early, can't be string match */
/* make accessable to gdb */
matched = &buf[RESTART(re, buf)];
@@ -441,20 +459,6 @@ reisstring(const char *text, size_t len, Regexp *re, const char *buf)
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 *
@@ -517,28 +521,28 @@ check_bracket_exp(char *s, size_t length)
static struct reclass {
const char *name;
size_t len;
- short warned;
+ bool warned;
} classes[] = {
/*
* Ordered by what we hope is frequency,
* since it's linear searched.
*/
- { "[:alpha:]", 9, FALSE },
- { "[:digit:]", 9, FALSE },
- { "[:alnum:]", 9, FALSE },
- { "[:upper:]", 9, FALSE },
- { "[:lower:]", 9, FALSE },
- { "[:space:]", 9, FALSE },
- { "[:xdigit:]", 10, FALSE },
- { "[:punct:]", 9, FALSE },
- { "[:print:]", 9, FALSE },
- { "[:graph:]", 9, FALSE },
- { "[:cntrl:]", 9, FALSE },
- { "[:blank:]", 9, FALSE },
+ { "[:alpha:]", 9, false },
+ { "[:digit:]", 9, false },
+ { "[:alnum:]", 9, false },
+ { "[:upper:]", 9, false },
+ { "[:lower:]", 9, false },
+ { "[:space:]", 9, false },
+ { "[:xdigit:]", 10, false },
+ { "[:punct:]", 9, false },
+ { "[:print:]", 9, false },
+ { "[:graph:]", 9, false },
+ { "[:cntrl:]", 9, false },
+ { "[:blank:]", 9, false },
{ NULL, 0 }
};
int i;
- int found = FALSE;
+ bool found = false;
char save;
char *sp, *sp2, *end;
int len;
@@ -558,20 +562,24 @@ again:
goto done;
for (count++, sp++; *sp != '\0'; sp++) {
- static short range_warned = FALSE;
-
if (*sp == '[')
count++;
- else if (*sp == ']')
- count--;
- if (*sp == '-' && do_lint && ! range_warned && count == 1
- && sp[-1] != '[' && sp[1] != ']'
- && ! isdigit((unsigned char) sp[-1]) && ! isdigit((unsigned char) sp[1])
- && ! (sp[-2] == '[' && sp[-1] == '^')) {
- range_warned = TRUE;
- warning(_("range of the form `[%c-%c]' is locale dependent"),
- sp[-1], sp[1]);
+ /*
+ * ] as first char after open [ is skipped
+ * \] is skipped
+ * [^]] is skipped
+ */
+ if (*sp == ']' && sp > sp2) {
+ if (sp[-1] != '['
+ && sp[-1] != '\\')
+ ;
+ else if ((sp - sp2) >= 2
+ && sp[-1] == '^' && sp[-2] == '[')
+ ;
+ else
+ count--;
}
+
if (count == 0) {
sp++; /* skip past ']' */
break;
@@ -590,7 +598,7 @@ again:
len = classes[i].len;
if ( len == (sp - sp2)
&& memcmp(sp2, classes[i].name, len) == 0) {
- found = TRUE;
+ found = true;
break;
}
}
@@ -598,13 +606,50 @@ again:
if (found && ! classes[i].warned) {
warning(_("regexp component `%.*s' should probably be `[%.*s]'"),
len, sp2, len, sp2);
- classes[i].warned = TRUE;
+ classes[i].warned = true;
}
if (sp < end) {
- found = FALSE;
+ found = false;
goto again;
}
done:
s[length] = save;
}
+
+/* regexflags2str --- make regex flags printable */
+
+const char *
+regexflags2str(int flags)
+{
+ static const struct flagtab regextab[] = {
+ { 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" },
+ { 0, NULL }
+ };
+
+ return genflags2str(flags, regextab);
+}
diff --git a/regcomp.c b/regcomp.c
index a181d63f..70468c82 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -1,5 +1,5 @@
/* Extended regular expression matching and search library.
- Copyright (C) 2002-2007,2009,2010,2011 Free Software Foundation, Inc.
+ Copyright (C) 2002-2013 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
@@ -14,9 +14,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,
size_t length, reg_syntax_t syntax);
@@ -150,7 +149,7 @@ const char __re_error_msgid[] attribute_hidden =
gettext_noop ("Invalid back reference") /* REG_ESUBREG */
"\0"
#define REG_EBRACK_IDX (REG_ESUBREG_IDX + sizeof "Invalid back reference")
- gettext_noop ("Unmatched [ or [^") /* REG_EBRACK */
+ gettext_noop ("Unmatched [, [^, [:, [., or [=") /* REG_EBRACK */
"\0"
#define REG_EPAREN_IDX (REG_EBRACK_IDX + sizeof "Unmatched [ or [^")
gettext_noop ("Unmatched ( or \\(") /* REG_EPAREN */
@@ -323,7 +322,7 @@ static void
re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
char *fastmap)
{
- volatile re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
+ 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)
@@ -574,8 +573,12 @@ regerror (errcode, preg, errbuf, errbuf_size)
{
if (BE (msg_size > errbuf_size, 0))
{
+#if defined HAVE_MEMPCPY || defined _LIBC
+ *((char *) __mempcpy (errbuf, msg, errbuf_size - 1)) = '\0';
+#else
memcpy (errbuf, msg, errbuf_size - 1);
errbuf[errbuf_size - 1] = 0;
+#endif
}
else
memcpy (errbuf, msg, msg_size);
@@ -896,20 +899,9 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
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. */
@@ -974,6 +966,39 @@ init_word_char (re_dfa_t *dfa)
{
int i, j, ch;
dfa->word_ops_used = 1;
+#ifndef GAWK
+ if (BE (dfa->map_notascii == 0, 1))
+ {
+ if (sizeof (dfa->word_char[0]) == 8)
+ {
+ /* The extra temporaries here avoid "implicitly truncated"
+ warnings in the case when this is dead code, i.e. 32-bit. */
+ const uint64_t wc0 = UINT64_C (0x03ff000000000000);
+ const uint64_t wc1 = UINT64_C (0x07fffffe87fffffe);
+ dfa->word_char[0] = wc0;
+ dfa->word_char[1] = wc1;
+ i = 2;
+ }
+ else if (sizeof (dfa->word_char[0]) == 4)
+ {
+ dfa->word_char[0] = UINT32_C (0x00000000);
+ dfa->word_char[1] = UINT32_C (0x03ff0000);
+ dfa->word_char[2] = UINT32_C (0x87fffffe);
+ dfa->word_char[3] = UINT32_C (0x07fffffe);
+ i = 4;
+ }
+ else
+ abort ();
+ ch = 128;
+
+ if (BE (dfa->is_utf8, 1))
+ {
+ memset (&dfa->word_char[i], '\0', (SBC_MAX - ch) / 8);
+ return;
+ }
+ }
+#endif
+
for (i = 0, ch = 0; i < BITSET_WORDS; ++i)
for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
if (isalnum (ch) || ch == '_')
@@ -2167,7 +2192,11 @@ parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,
{
branch = parse_branch (regexp, preg, token, syntax, nest, err);
if (BE (*err != REG_NOERROR && branch == NULL, 0))
- return NULL;
+ {
+ if (tree != NULL)
+ postorder (tree, free_tree, NULL);
+ return NULL;
+ }
}
else
branch = NULL;
@@ -2428,14 +2457,21 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
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;
+ bin_tree_t *dup_tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
+ if (BE (*err != REG_NOERROR && dup_tree == NULL, 0))
+ {
+ if (tree != NULL)
+ postorder (tree, free_tree, NULL);
+ return NULL;
+ }
+ tree = dup_tree;
/* In BRE consecutive duplications are not allowed. */
if ((syntax & RE_CONTEXT_INVALID_DUP)
&& (token->type == OP_DUP_ASTERISK
|| token->type == OP_OPEN_DUP_NUM))
{
+ if (tree != NULL)
+ postorder (tree, free_tree, NULL);
*err = REG_BADRPT;
return NULL;
}
@@ -2499,13 +2535,7 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa,
{
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)
{
@@ -2590,6 +2620,8 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa,
/* Duplicate ELEM before it is marked optional. */
elem = duplicate_tree (elem, dfa);
+ if (BE (elem == NULL, 0))
+ goto parse_dup_op_espace;
old_tree = tree;
}
else
@@ -2651,7 +2683,6 @@ build_range_exp (reg_syntax_t syntax, bitset_t sbcset,
# endif /* not RE_ENABLE_I18N */
{
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,
@@ -2723,7 +2754,14 @@ build_range_exp (reg_syntax_t syntax, bitset_t sbcset,
new_nranges);
if (BE (new_array_start == NULL || new_array_end == NULL, 0))
- return REG_ESPACE;
+ {
+ /* if one is not NULL, free it to avoid leaks */
+ if (new_array_start != NULL)
+ re_free(new_array_start);
+ if (new_array_end != NULL)
+ re_free(new_array_end);
+ return REG_ESPACE;
+ }
mbcset->range_starts = new_array_start;
mbcset->range_ends = new_array_end;
@@ -2806,40 +2844,29 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
/* 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. */
+ Return the index of the symbol in the SYMB_TABLE,
+ or -1 if not found. */
auto inline int32_t
__attribute ((always_inline))
- seek_collating_symbol_entry (name, name_len)
- const unsigned char *name;
- size_t name_len;
+ seek_collating_symbol_entry (const unsigned char *name, size_t name_len)
{
- int32_t hash = elem_hash ((const char *) name, name_len);
- int32_t elem = hash % table_size;
- if (symb_table[2 * elem] != 0)
- {
- int32_t second = hash % (table_size - 2) + 1;
-
- do
- {
- /* 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;
- }
+ int32_t elem;
- /* Next entry. */
- elem += second;
- }
- while (symb_table[2 * elem] != 0);
- }
- return elem;
+ for (elem = 0; elem < table_size; elem++)
+ if (symb_table[2 * elem] != 0)
+ {
+ int32_t idx = symb_table[2 * elem + 1];
+ /* Skip the name of collating element name. */
+ idx += 1 + extra[idx];
+ if (/* Compare the length of the name. */
+ name_len == extra[idx]
+ /* Compare the name. */
+ && memcmp (name, &extra[idx + 1], name_len) == 0)
+ /* Yep, this is the entry. */
+ return elem;
+ }
+ return -1;
}
/* Local function for parse_bracket_exp used in _LIBC environment.
@@ -2848,8 +2875,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
auto inline unsigned int
__attribute ((always_inline))
- lookup_collation_sequence_value (br_elem)
- bracket_elem_t *br_elem;
+ lookup_collation_sequence_value (bracket_elem_t *br_elem)
{
if (br_elem->type == SB_CHAR)
{
@@ -2877,7 +2903,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
int32_t elem, idx;
elem = seek_collating_symbol_entry (br_elem->opr.name,
sym_name_len);
- if (symb_table[2 * elem] != 0)
+ if (elem != -1)
{
/* We found the entry. */
idx = symb_table[2 * elem + 1];
@@ -2895,7 +2921,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
/* Return the collation sequence value. */
return *(unsigned int *) (extra + idx);
}
- else if (symb_table[2 * elem] == 0 && sym_name_len == 1)
+ else if (sym_name_len == 1)
{
/* No valid character. Match it as a single byte
character. */
@@ -2917,11 +2943,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
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;
- bitset_t sbcset;
- bracket_elem_t *start_elem, *end_elem;
+ build_range_exp (bitset_t sbcset, re_charset_t *mbcset, int *range_alloc,
+ bracket_elem_t *start_elem, bracket_elem_t *end_elem)
{
unsigned int ch;
uint32_t start_collseq;
@@ -3000,25 +3023,22 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
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;
- bitset_t sbcset;
- const unsigned char *name;
+ build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset,
+ int *coll_sym_alloc, 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)
+ if (elem != -1)
{
/* 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)
+ else if (name_len == 1)
{
/* No valid character, treat it as a normal
character. */
@@ -3470,8 +3490,8 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name)
_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))
+ idx1 = findidx (&cp, -1);
+ if (BE (idx1 == 0 || *cp != '\0', 0))
/* This isn't a valid character. */
return REG_ECOLLATE;
@@ -3482,7 +3502,7 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name)
{
char_buf[0] = ch;
cp = char_buf;
- idx2 = findidx (&cp);
+ idx2 = findidx (&cp, 1);
/*
idx2 = table[ch];
*/
@@ -3650,6 +3670,13 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
if (BE (sbcset == NULL, 0))
#endif /* not RE_ENABLE_I18N */
{
+ /* if one is not NULL, free it to avoid leaks */
+ if (sbcset != NULL)
+ free(sbcset);
+#ifdef RE_ENABLE_I18N
+ if (mbcset != NULL)
+ free(mbcset);
+#endif
*err = REG_ESPACE;
return NULL;
}
@@ -3692,6 +3719,7 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
#endif
/* Build a tree for simple bracket. */
+ memset(& br_token, 0, sizeof(br_token)); /* silence "not initialized" errors froms static checkers */
br_token.type = SIMPLE_BRACKET;
br_token.opr.sbcset = sbcset;
tree = create_token_tree (dfa, NULL, NULL, &br_token);
@@ -3782,6 +3810,7 @@ create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right,
re_token_type_t type)
{
re_token_t t;
+ memset(& t, 0, sizeof(t)); /* silence "not initialized" errors froms static checkers */
t.type = type;
return create_token_tree (dfa, left, right, &t);
}
diff --git a/regex.c b/regex.c
index 09b51944..f56e8692 100644
--- a/regex.c
+++ b/regex.c
@@ -1,5 +1,5 @@
/* Extended regular expression matching and search library.
- Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002-2014 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
@@ -14,9 +14,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -57,6 +56,11 @@
#undefs RE_DUP_MAX and sets it to the right value. */
#include <limits.h>
+/* This header defines the MIN and MAX macros. */
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif /* HAVE_SYS_PARAM_H */
+
#ifdef GAWK
#undef alloca
#define alloca alloca_is_bad_you_should_never_use_it
@@ -65,10 +69,8 @@
#include "regex_internal.h"
#include "regex_internal.c"
-#ifdef GAWK
-#define bool int
-#define true (1)
-#define false (0)
+#ifndef HAVE_STDBOOL_H
+#include "missing_d/gawkbool.h"
#endif
#include "regcomp.c"
#include "regexec.c"
diff --git a/regex.h b/regex.h
index 6bc503b2..3d26a606 100644
--- a/regex.h
+++ b/regex.h
@@ -1,7 +1,6 @@
/* Definitions for data structures and routines for the regular
expression library.
- Copyright (C) 1985,1989-93,1995-98,2000,2001,2002,2003,2005,2006,2008,2011
- Free Software Foundation, Inc.
+ Copyright (C) 1985, 1989-2014 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
@@ -15,9 +14,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _REGEX_H
#define _REGEX_H 1
@@ -349,9 +347,9 @@ typedef enum
/* 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. */
+ and `translate' can be set. After the pattern has been compiled,
+ the fields `re_nsub', `not_bol' and `not_eol' are available. All
+ other fields are private to the regex routines. */
#ifndef RE_TRANSLATE_TYPE
# define __RE_TRANSLATE_TYPE unsigned char *
@@ -472,19 +470,24 @@ typedef struct
#ifdef __USE_GNU
/* 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 (reg_syntax_t __syntax);
+extern reg_syntax_t re_set_syntax (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 (const char *__pattern, size_t __length,
- struct re_pattern_buffer *__buffer);
+ BUFFER. Return NULL if successful, and an error string if not.
+
+ To free the allocated storage, you must call `regfree' on BUFFER.
+ Note that the translate table must either have been initialised by
+ `regcomp', with a malloc'ed value, or set to NULL before calling
+ `regfree'. */
+extern const char *re_compile_pattern (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 (struct re_pattern_buffer *__buffer);
+extern int re_compile_fastmap (struct re_pattern_buffer *buffer);
/* Search in the string STRING (with length LENGTH) for the pattern
@@ -492,30 +495,30 @@ extern int re_compile_fastmap (struct re_pattern_buffer *__buffer);
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 (struct re_pattern_buffer *__buffer, const char *__cstring,
- int __length, int __start, int __range,
- struct re_registers *__regs);
+extern int re_search (struct re_pattern_buffer *buffer, const char *c_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 (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);
+extern int re_search_2 (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 (struct re_pattern_buffer *__buffer, const char *__cstring,
- int __length, int __start, struct re_registers *__regs);
+extern int re_match (struct re_pattern_buffer *buffer, const char *c_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 (struct re_pattern_buffer *__buffer,
- const char *__string1, int __length1,
- const char *__string2, int __length2, int __start,
- struct re_registers *__regs, int __stop);
+extern int re_match_2 (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
@@ -530,13 +533,13 @@ extern int re_match_2 (struct re_pattern_buffer *__buffer,
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 (struct re_pattern_buffer *__buffer,
- struct re_registers *__regs,
- unsigned int __num_regs,
- regoff_t *__starts, regoff_t *__ends);
+extern void re_set_registers (struct re_pattern_buffer *buffer,
+ struct re_registers *regs,
+ unsigned int num_regs,
+ regoff_t *starts, regoff_t *ends);
#endif /* Use GNU */
-#if defined _REGEX_RE_COMP || (defined _LIBC && defined __USE_BSD)
+#if defined _REGEX_RE_COMP || (defined _LIBC && defined __USE_MISC)
# ifndef _CRAY
/* 4.2 bsd compatibility. */
extern char *re_comp (const char *);
@@ -566,19 +569,19 @@ extern int re_exec (const char *);
#endif
/* POSIX compatibility. */
-extern int regcomp (regex_t *__restrict __preg,
- const char *__restrict __pattern,
- int __cflags);
+extern int regcomp (regex_t *__restrict preg,
+ const char *__restrict pattern,
+ int cflags);
-extern int regexec (const regex_t *__restrict __preg,
- const char *__restrict __cstring, size_t __nmatch,
- regmatch_t __pmatch[__restrict_arr],
- int __eflags);
+extern int regexec (const regex_t *__restrict preg,
+ const char *__restrict c_string, size_t nmatch,
+ regmatch_t pmatch[__restrict_arr],
+ int eflags);
-extern size_t regerror (int __errcode, const regex_t *__restrict __preg,
- char *__restrict __errbuf, size_t __errbuf_size);
+extern size_t regerror (int errcode, const regex_t *__restrict preg,
+ char *__restrict errbuf, size_t errbuf_size);
-extern void regfree (regex_t *__preg);
+extern void regfree (regex_t *preg);
#ifdef __cplusplus
diff --git a/regex_internal.c b/regex_internal.c
index 0c4f8f80..9e427081 100644
--- a/regex_internal.c
+++ b/regex_internal.c
@@ -1,5 +1,5 @@
/* Extended regular expression matching and search library.
- Copyright (C) 2002-2006, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2002-2014 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
@@ -14,9 +14,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
static void re_string_construct_common (const char *str, int len,
re_string_t *pstr,
@@ -246,13 +245,8 @@ build_wcs_buffer (re_string_t *pstr)
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))
+ if (BE (mbclen == (size_t) -1 || mbclen == 0
+ || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len), 0))
{
/* We treat these cases as a singlebyte character. */
mbclen = 1;
@@ -261,6 +255,12 @@ build_wcs_buffer (re_string_t *pstr)
wc = pstr->trans[wc];
pstr->cur_state = prev_st;
}
+ else if (BE (mbclen == (size_t) -2, 0))
+ {
+ /* The buffer doesn't have enough space, finish to build. */
+ pstr->cur_state = prev_st;
+ break;
+ }
/* Write wide character and padding. */
pstr->wcs[byte_idx++] = wc;
@@ -320,12 +320,11 @@ build_wcs_upper_buffer (re_string_t *pstr)
+ byte_idx), remain_len, &pstr->cur_state);
if (BE (mbclen + 2 > 2, 1))
{
- wchar_t wcu = wc;
- if (iswlower (wc))
+ wchar_t wcu = towupper (wc);
+ if (wcu != wc)
{
size_t mbcdlen;
- wcu = towupper (wc);
mbcdlen = wcrtomb (buf, wcu, &prev_st);
if (BE (mbclen == mbcdlen, 1))
memcpy (pstr->mbs + byte_idx, buf, mbclen);
@@ -343,9 +342,11 @@ build_wcs_upper_buffer (re_string_t *pstr)
for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
pstr->wcs[byte_idx++] = WEOF;
}
- else if (mbclen == (size_t) -1 || mbclen == 0)
+ else if (mbclen == (size_t) -1 || mbclen == 0
+ || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len))
{
- /* It is an invalid character or '\0'. Just use the byte. */
+ /* It is an invalid character, an incomplete character
+ at the end of the string, 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. */
@@ -388,12 +389,11 @@ build_wcs_upper_buffer (re_string_t *pstr)
mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
if (BE (mbclen + 2 > 2, 1))
{
- wchar_t wcu = wc;
- if (iswlower (wc))
+ wchar_t wcu = towupper (wc);
+ if (wcu != wc)
{
size_t mbcdlen;
- wcu = towupper (wc);
mbcdlen = wcrtomb ((char *) buf, wcu, &prev_st);
if (BE (mbclen == mbcdlen, 1))
memcpy (pstr->mbs + byte_idx, buf, mbclen);
@@ -458,7 +458,8 @@ build_wcs_upper_buffer (re_string_t *pstr)
for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
pstr->wcs[byte_idx++] = WEOF;
}
- else if (mbclen == (size_t) -1 || mbclen == 0)
+ else if (mbclen == (size_t) -1 || mbclen == 0
+ || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len))
{
/* It is an invalid character or '\0'. Just use the byte. */
int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx];
@@ -505,7 +506,7 @@ re_string_skip_chars (re_string_t *pstr, int new_raw_idx, wint_t *last_wc)
rawbuf_idx < new_raw_idx;)
{
wchar_t wc2;
- int remain_len = pstr->len - rawbuf_idx;
+ int remain_len = pstr->raw_len - rawbuf_idx;
prev_st = pstr->cur_state;
mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx,
remain_len, &pstr->cur_state);
@@ -685,7 +686,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
pstr->valid_len - offset);
pstr->valid_len -= offset;
pstr->valid_raw_len -= offset;
-#if DEBUG
+#if defined DEBUG && DEBUG
assert (pstr->valid_len > 0);
#endif
}
@@ -741,16 +742,18 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
unsigned char buf[6];
size_t mbclen;
+ const unsigned char *pp = p;
if (BE (pstr->trans != NULL, 0))
{
int i = mlen < 6 ? mlen : 6;
while (--i >= 0)
buf[i] = pstr->trans[p[i]];
+ pp = buf;
}
/* XXX Don't use mbrtowc, we know which conversion
to use (UTF-8 -> UCS4). */
memset (&cur_state, 0, sizeof (cur_state));
- mbclen = __mbrtowc (&wc2, (const char *) p, mlen,
+ mbclen = __mbrtowc (&wc2, (const char *) pp, mlen,
&cur_state);
if (raw + offset - p <= mbclen
&& mbclen < (size_t) -2)
@@ -940,7 +943,7 @@ re_string_context_at (const re_string_t *input, int idx, int eflags)
int wc_idx = idx;
while(input->wcs[wc_idx] == WEOF)
{
-#ifdef DEBUG
+#if defined DEBUG && DEBUG
/* It must not happen. */
assert (wc_idx >= 0);
#endif
@@ -1446,7 +1449,18 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
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;
+ {
+ /* if any are not NULL, free them, avoid leaks */
+ if (new_nexts != NULL)
+ re_free(new_nexts);
+ if (new_indices != NULL)
+ re_free(new_indices);
+ if (new_edests != NULL)
+ re_free(new_edests);
+ if (new_eclosures != NULL)
+ re_free(new_eclosures);
+ return -1;
+ }
dfa->nexts = new_nexts;
dfa->org_indices = new_indices;
dfa->edests = new_edests;
diff --git a/regex_internal.h b/regex_internal.h
index b5dc7b46..3fc2fc58 100644
--- a/regex_internal.h
+++ b/regex_internal.h
@@ -1,5 +1,5 @@
/* Extended regular expression matching and search library.
- Copyright (C) 2002-2005, 2007, 2008, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2002-2014 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
@@ -14,9 +14,8 @@
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., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _REGEX_INTERNAL_H
#define _REGEX_INTERNAL_H 1
@@ -91,7 +90,7 @@ is_blank (int c)
# ifdef _LIBC
# undef gettext
# define gettext(msgid) \
- INTUSE(__dcgettext) (_libc_intl_domainname, msgid, LC_MESSAGES)
+ __dcgettext (_libc_intl_domainname, msgid, LC_MESSAGES)
# endif
#else
# define gettext(msgid) (msgid)
@@ -108,9 +107,7 @@ is_blank (int c)
# define SIZE_MAX ((size_t) -1)
#endif
-#include "mbsupport.h" /* gawk */
-
-#if MBS_SUPPORT || _LIBC
+#if ! defined(__DJGPP__) && (defined(GAWK) || _LIBC)
# define RE_ENABLE_I18N
#endif
@@ -156,6 +153,7 @@ is_blank (int c)
# define __attribute(arg) __attribute__ (arg)
#else
# define __attribute(arg)
+# define __attribute__(arg) /* GAWK: They left this out. Duh. */
#endif
#ifdef GAWK
@@ -418,7 +416,7 @@ typedef struct re_dfa_t re_dfa_t;
#ifndef _LIBC
# ifdef __i386__
-# define internal_function __attribute ((regparm (3), stdcall))
+# define internal_function __attribute__ ((regparm (3), stdcall))
# else
# define internal_function
# endif
@@ -437,7 +435,7 @@ static void build_upper_buffer (re_string_t *pstr) internal_function;
static void re_string_translate_buffer (re_string_t *pstr) internal_function;
static unsigned int re_string_context_at (const re_string_t *input, int idx,
int eflags)
- internal_function __attribute ((pure));
+ internal_function __attribute__ ((pure));
#endif
#define re_string_peek_byte(pstr, offset) \
((pstr)->mbs[(pstr)->cur_idx + offset])
@@ -727,7 +725,7 @@ typedef struct
/* Inline functions for bitset operation. */
-static inline void
+static void __attribute__ ((unused))
bitset_not (bitset_t set)
{
int bitset_i;
@@ -735,7 +733,7 @@ bitset_not (bitset_t set)
set[bitset_i] = ~set[bitset_i];
}
-static inline void
+static void __attribute__ ((unused))
bitset_merge (bitset_t dest, const bitset_t src)
{
int bitset_i;
@@ -743,7 +741,7 @@ bitset_merge (bitset_t dest, const bitset_t src)
dest[bitset_i] |= src[bitset_i];
}
-static inline void
+static void __attribute__ ((unused))
bitset_mask (bitset_t dest, const bitset_t src)
{
int bitset_i;
@@ -753,8 +751,8 @@ bitset_mask (bitset_t dest, const bitset_t src)
#ifdef RE_ENABLE_I18N
/* Inline functions for re_string. */
-static inline int
-internal_function __attribute ((pure))
+static int
+internal_function __attribute__ ((pure, unused))
re_string_char_size_at (const re_string_t *pstr, int idx)
{
int byte_idx;
@@ -766,8 +764,8 @@ re_string_char_size_at (const re_string_t *pstr, int idx)
return byte_idx;
}
-static inline wint_t
-internal_function __attribute ((pure))
+static wint_t
+internal_function __attribute__ ((pure, unused))
re_string_wchar_at (const re_string_t *pstr, int idx)
{
if (pstr->mb_cur_max == 1)
@@ -777,13 +775,12 @@ re_string_wchar_at (const re_string_t *pstr, int idx)
# ifndef NOT_IN_libc
static int
-internal_function __attribute ((pure))
+internal_function __attribute__ ((pure, unused))
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);
@@ -795,7 +792,7 @@ re_string_elem_size_at (const re_string_t *pstr, int idx)
indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
_NL_COLLATE_INDIRECTMB);
p = pstr->mbs + idx;
- tmp = findidx (&p);
+ findidx (&p, pstr->len - idx);
return p - pstr->mbs - idx;
}
else
diff --git a/regexec.c b/regexec.c
index 97fcba00..77795f69 100644
--- a/regexec.c
+++ b/regexec.c
@@ -1,5 +1,5 @@
/* Extended regular expression matching and search library.
- Copyright (C) 2002-2005, 2007, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2002-2013 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
@@ -14,9 +14,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
int n) internal_function;
@@ -198,8 +197,17 @@ static int group_nodes_into_DFAstates (const re_dfa_t *dfa,
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)
+static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len)
internal_function;
+
+#ifdef GAWK
+#undef MIN /* safety */
+static int
+MIN(size_t a, size_t b)
+{
+ return (a < b ? a : b);
+}
+#endif
/* Entry point for POSIX code. */
@@ -367,7 +375,7 @@ re_search_2_stub (bufp, string1, length1, string2, length2, start, range, regs,
const char *str;
int rval;
int len = length1 + length2;
- int free_str = 0;
+ char *s = NULL;
if (BE (length1 < 0 || length2 < 0 || stop < 0 || len < length1, 0))
return -2;
@@ -376,7 +384,7 @@ re_search_2_stub (bufp, string1, length1, string2, length2, start, range, regs,
if (length2 > 0)
if (length1 > 0)
{
- char *s = re_malloc (char, len);
+ s = re_malloc (char, len);
if (BE (s == NULL, 0))
return -2;
@@ -387,7 +395,6 @@ re_search_2_stub (bufp, string1, length1, string2, length2, start, range, regs,
memcpy (s + length1, string2, length2);
#endif
str = s;
- free_str = 1;
}
else
str = string2;
@@ -395,8 +402,7 @@ re_search_2_stub (bufp, string1, length1, string2, length2, start, range, regs,
str = string1;
rval = re_search_stub (bufp, str, len, start, range, stop, regs, ret_len);
- if (free_str)
- re_free ((char *) str);
+ re_free (s);
return rval;
}
@@ -658,7 +664,7 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
nmatch -= extra_nmatch;
/* Check if the DFA haven't been compiled. */
- if (BE (preg->used == 0 || dfa->init_state == NULL
+ if (BE (preg->used == 0 || dfa == NULL || dfa->init_state == NULL
|| dfa->init_state_word == NULL || dfa->init_state_nl == NULL
|| dfa->init_state_begbuf == NULL, 0))
return REG_NOMATCH;
@@ -1156,11 +1162,12 @@ check_matching (re_match_context_t *mctx, int fl_longest_match,
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)
+ if ((BE (next_char_idx >= mctx->input.bufs_len, 0)
+ && mctx->input.bufs_len < mctx->input.len)
|| (BE (next_char_idx >= mctx->input.valid_len, 0)
&& mctx->input.valid_len < mctx->input.len))
{
- err = extend_buffers (mctx);
+ err = extend_buffers (mctx, next_char_idx + 1);
if (BE (err != REG_NOERROR, 0))
{
assert (err == REG_ESPACE);
@@ -1734,12 +1741,13 @@ clean_state_log_if_needed (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
+ if ((next_state_log_idx >= mctx->input.bufs_len
+ && mctx->input.bufs_len < mctx->input.len)
|| (next_state_log_idx >= mctx->input.valid_len
&& mctx->input.valid_len < mctx->input.len))
{
reg_errcode_t err;
- err = extend_buffers (mctx);
+ err = extend_buffers (mctx, next_state_log_idx + 1);
if (BE (err != REG_NOERROR, 0))
return err;
}
@@ -2793,7 +2801,7 @@ get_subexp (re_match_context_t *mctx, int bkref_node, int bkref_str_idx)
if (bkref_str_off >= mctx->input.len)
break;
- err = extend_buffers (mctx);
+ err = extend_buffers (mctx, bkref_str_off + 1);
if (BE (err != REG_NOERROR, 0))
return err;
@@ -3932,7 +3940,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
indirect = (const int32_t *)
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
- int32_t idx = findidx (&cp);
+ int32_t idx = findidx (&cp, elem_len);
if (idx > 0)
for (i = 0; i < cset->nequiv_classes; ++i)
{
@@ -3963,18 +3971,10 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
# 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)
+ if (cset->range_starts[i] <= wc
+ && wc <= cset->range_ends[i])
{
match_len = char_len;
goto check_node_accept_bytes_match;
@@ -4111,7 +4111,7 @@ check_node_accept (const re_match_context_t *mctx, const re_token_t *node,
static reg_errcode_t
internal_function __attribute_warn_unused_result__
-extend_buffers (re_match_context_t *mctx)
+extend_buffers (re_match_context_t *mctx, int min_len)
{
reg_errcode_t ret;
re_string_t *pstr = &mctx->input;
@@ -4120,8 +4120,10 @@ extend_buffers (re_match_context_t *mctx)
if (BE (INT_MAX / 2 / sizeof (re_dfastate_t *) <= pstr->bufs_len, 0))
return REG_ESPACE;
- /* Double the lengthes of the buffers. */
- ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
+ /* Double the lengthes of the buffers, but allocate at least MIN_LEN. */
+ ret = re_string_realloc_buffers (pstr,
+ MAX (min_len,
+ MIN (pstr->len, pstr->bufs_len * 2)));
if (BE (ret != REG_NOERROR, 0))
return ret;
diff --git a/replace.c b/replace.c
index d2dcbbcc..6d345f52 100644
--- a/replace.c
+++ b/replace.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1989, 1991-2011 the Free Software Foundation, Inc.
+ * Copyright (C) 1989, 1991-2013 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -27,8 +27,7 @@
* 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"
+#include "awk.h" /* includes config.h for us */
#ifndef HAVE_SYSTEM
@@ -51,7 +50,7 @@
#include "missing_d/memmove.c"
#endif /* HAVE_MEMMOVE */
-#ifndef HAVE_STRNCASECMP
+#if !defined(HAVE_STRNCASECMP) || !defined(HAVE_STRCASECMP)
#include "missing_d/strncasecmp.c"
#endif /* HAVE_STRCASE */
@@ -111,3 +110,7 @@
#ifndef HAVE_STRCOLL
#include "missing_d/strcoll.c"
#endif
+
+#if defined(__DJGPP__)
+#include "missing_d/wcmisc.c"
+#endif
diff --git a/str_array.c b/str_array.c
index 8fb6ba8a..33c9ddcc 100644
--- a/str_array.c
+++ b/str_array.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-2011 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-2013 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -55,14 +55,10 @@ static NODE **str_list(NODE *symbol, NODE *subs);
static NODE **str_copy(NODE *symbol, NODE *newsymb);
static NODE **str_dump(NODE *symbol, NODE *ndump);
-#ifdef ARRAYDEBUG
-static NODE **str_option(NODE *opt, NODE *val);
-#endif
-
-
-array_ptr str_array_func[] = {
+afunc_t str_array_func[] = {
str_array_init,
- (array_ptr) 0,
+ (afunc_t) 0,
+ null_length,
str_lookup,
str_exists,
str_clear,
@@ -70,9 +66,26 @@ array_ptr str_array_func[] = {
str_list,
str_copy,
str_dump,
-#ifdef ARRAYDEBUG
- str_option
-#endif
+ (afunc_t) 0,
+};
+
+static NODE **env_remove(NODE *symbol, NODE *subs);
+static NODE **env_store(NODE *symbol, NODE *subs);
+static NODE **env_clear(NODE *symbol, NODE *subs);
+
+/* special case for ENVIRON */
+afunc_t env_array_func[] = {
+ str_array_init,
+ (afunc_t) 0,
+ null_length,
+ str_lookup,
+ str_exists,
+ env_clear,
+ env_remove,
+ str_list,
+ str_copy,
+ str_dump,
+ env_store,
};
static inline NODE **str_find(NODE *symbol, NODE *s1, size_t code1, unsigned long hash1);
@@ -85,18 +98,23 @@ static unsigned long awk_hash(const char *s, size_t len, unsigned long hsize, si
unsigned long (*hash)(const char *s, size_t len, unsigned long hsize, size_t *code) = awk_hash;
-/* str_array_init --- check relevant environment variables */
+/* str_array_init --- array initialization routine */
static NODE **
str_array_init(NODE *symbol ATTRIBUTE_UNUSED, NODE *subs ATTRIBUTE_UNUSED)
{
- long newval;
- const char *val;
+ if (symbol == NULL) { /* first time */
+ long newval;
+ const char *val;
+
+ /* check relevant environment variables */
+ if ((newval = getenv_long("STR_CHAIN_MAX")) > 0)
+ STR_CHAIN_MAX = newval;
+ if ((val = getenv("AWK_HASH")) != NULL && strcmp(val, "gst") == 0)
+ hash = gst_hash_string;
+ } else
+ null_array(symbol);
- if ((newval = getenv_long("STR_CHAIN_MAX")) > 0)
- STR_CHAIN_MAX = newval;
- if ((val = getenv("AWK_HASH")) != NULL && strcmp(val, "gst") == 0)
- hash = gst_hash_string;
return (NODE **) ! NULL;
}
@@ -158,7 +176,7 @@ str_lookup(NODE *symbol, NODE *subs)
* never be used.
*/
- if (subs->flags & NUMCUR) {
+ if ((subs->flags & (MPFN|MPZN|NUMCUR)) == NUMCUR) {
tmp->numbr = subs->numbr;
tmp->flags |= NUMCUR;
}
@@ -187,16 +205,15 @@ str_lookup(NODE *symbol, NODE *subs)
static NODE **
str_exists(NODE *symbol, NODE *subs)
{
- NODE **lhs;
unsigned long hash1;
size_t code1;
- assert(symbol->table_size > 0);
+ if (symbol->table_size == 0)
+ return NULL;
subs = force_string(subs);
hash1 = hash(subs->stptr, subs->stlen, (unsigned long) symbol->array_size, & code1);
- lhs = str_find(symbol, subs, code1, hash1);
- return lhs;
+ return str_find(symbol, subs, code1, hash1);
}
/* str_clear --- flush all the values in symbol[] */
@@ -226,8 +243,7 @@ str_clear(NODE *symbol, NODE *subs ATTRIBUTE_UNUSED)
if (symbol->buckets != NULL)
efree(symbol->buckets);
- init_array(symbol); /* re-initialize symbol */
- symbol->flags &= ~ARRAYMAXED;
+ symbol->ainit(symbol, NULL); /* re-initialize symbol */
return NULL;
}
@@ -242,7 +258,8 @@ str_remove(NODE *symbol, NODE *subs)
NODE *s2;
size_t s1_len;
- assert(symbol->table_size > 0);
+ if (symbol->table_size == 0)
+ return NULL;
s2 = force_string(subs);
hash1 = hash(s2->stptr, s2->stlen, (unsigned long) symbol->array_size, NULL);
@@ -272,8 +289,7 @@ str_remove(NODE *symbol, NODE *subs)
if (--symbol->table_size == 0) {
if (symbol->buckets != NULL)
efree(symbol->buckets);
- init_array(symbol); /* re-initialize symbol */
- symbol->flags &= ~ARRAYMAXED;
+ symbol->ainit(symbol, NULL); /* re-initialize symbol */
}
return (NODE **) ! NULL; /* return success */
@@ -335,6 +351,7 @@ str_copy(NODE *symbol, NODE *newsymb)
newchain->ahcode = chain->ahcode;
*pnew = newchain;
+ newchain->ahnext = NULL;
pnew = & newchain->ahnext;
}
}
@@ -357,15 +374,18 @@ str_list(NODE *symbol, NODE *t)
BUCKET *b;
unsigned long num_elems, list_size, i, k = 0;
int elem_size = 1;
+ assoc_kind_t assoc_kind;
- assert(symbol->table_size > 0);
+ if (symbol->table_size == 0)
+ return NULL;
- if ((t->flags & (AINDEX|AVALUE)) == (AINDEX|AVALUE))
+ assoc_kind = (assoc_kind_t) t->flags;
+ if ((assoc_kind & (AINDEX|AVALUE)) == (AINDEX|AVALUE))
elem_size = 2;
/* allocate space for array */
num_elems = symbol->table_size;
- if ((t->flags & (AINDEX|AVALUE|ADELETE)) == (AINDEX|ADELETE))
+ if ((assoc_kind & (AINDEX|AVALUE|ADELETE)) == (AINDEX|ADELETE))
num_elems = 1;
list_size = elem_size * num_elems;
@@ -377,17 +397,17 @@ str_list(NODE *symbol, NODE *t)
for (b = symbol->buckets[i]; b != NULL; b = b->ahnext) {
/* index */
subs = b->ahname;
- if (t->flags & AINUM)
+ if ((assoc_kind & AINUM) != 0)
(void) force_number(subs);
list[k++] = dupnode(subs);
/* value */
- if (t->flags & AVALUE) {
+ if ((assoc_kind & AVALUE) != 0) {
val = b->ahvalue;
if (val->type == Node_val) {
- if ((t->flags & AVNUM) != 0)
+ if ((assoc_kind & AVNUM) != 0)
(void) force_number(val);
- else if ((t->flags & AVSTR) != 0)
+ else if ((assoc_kind & AVSTR) != 0)
val = force_string(val);
}
list[k++] = val;
@@ -443,7 +463,7 @@ str_dump(NODE *symbol, NODE *ndump)
fprintf(output_fp, "flags: %s\n", flags2str(symbol->flags));
}
indent(indent_level);
- fprintf(output_fp, "STR_CHAIN_MAX: %lu\n", STR_CHAIN_MAX);
+ fprintf(output_fp, "STR_CHAIN_MAX: %lu\n", (unsigned long) STR_CHAIN_MAX);
indent(indent_level);
fprintf(output_fp, "array_size: %lu\n", (unsigned long) symbol->array_size);
indent(indent_level);
@@ -670,27 +690,6 @@ grow_table(NODE *symbol)
}
-#ifdef ARRAYDEBUG
-
-static NODE **
-str_option(NODE *opt, NODE *val)
-{
- int newval;
- NODE *tmp;
- NODE **ret = (NODE **) ! NULL;
-
- tmp = force_string(opt);
- (void) force_number(val);
- if (STREQ(tmp->stptr, "STR_CHAIN_MAX")) {
- newval = (int) val->numbr;
- if (newval > 0)
- STR_CHAIN_MAX = newval;
- } else
- ret = NULL;
- return ret;
-}
-#endif
-
/*
From bonzini@gnu.org Mon Oct 28 16:05:26 2002
@@ -757,3 +756,63 @@ scramble(unsigned long x)
return x;
}
+
+/* env_remove --- for ENVIRON, remove value from real environment */
+
+static NODE **
+env_remove(NODE *symbol, NODE *subs)
+{
+ NODE **val = str_remove(symbol, subs);
+
+ if (val != NULL)
+ (void) unsetenv(subs->stptr);
+
+ return val;
+}
+
+/* env_clear --- clear out the environment when ENVIRON is deleted */
+
+static NODE **
+env_clear(NODE *symbol, NODE *subs)
+{
+ extern char **environ;
+ NODE **val = str_clear(symbol, subs);
+
+ environ = NULL; /* ZAP! */
+
+ /* str_clear zaps the vtable, reset it */
+ symbol->array_funcs = env_array_func;
+
+ return val;
+}
+
+/* env_store --- post assign function for ENVIRON, put new value into env */
+
+static NODE **
+env_store(NODE *symbol, NODE *subs)
+{
+ NODE **val = str_exists(symbol, subs);
+ const char *newval;
+
+ assert(val != NULL);
+
+ newval = (*val)->stptr;
+ if (newval == NULL)
+ newval = "";
+
+ (void) setenv(subs->stptr, newval, 1);
+
+ return val;
+}
+
+/* init_env_array --- set up the pointers for ENVIRON. A bit hacky. */
+
+void
+init_env_array(NODE *env_node)
+{
+ /* If POSIX simply don't reset the vtable and things work as before */
+ if (do_posix)
+ return;
+
+ env_node->array_funcs = env_array_func;
+}
diff --git a/symbol.c b/symbol.c
index 57ca7be0..23e04c03 100644
--- a/symbol.c
+++ b/symbol.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-2011 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-2013 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -30,19 +30,43 @@ extern INSTRUCTION *rule_list;
#define HASHSIZE 1021
-static NODE *variables[HASHSIZE];
static int func_count; /* total number of functions */
static int var_count; /* total number of global variables and functions */
static NODE *symbol_list;
static void (*install_func)(NODE *) = NULL;
-static NODE *make_symbol(char *name, NODETYPE type);
-static NODE *install(char *name, NODE *hp, NODETYPE type);
+static NODE *make_symbol(const char *name, NODETYPE type);
+static NODE *install(const char *name, NODE *parm, NODETYPE type);
static void free_bcpool(INSTRUCTION *pl);
static AWK_CONTEXT *curr_ctxt = NULL;
static int ctxt_level;
+static NODE *global_table, *param_table;
+NODE *symbol_table, *func_table;
+
+/* Use a flag to avoid a strcmp() call inside install() */
+static bool installing_specials = false;
+
+/* init_symbol_table --- make sure the symbol tables are initialized */
+
+void
+init_symbol_table()
+{
+ getnode(global_table);
+ memset(global_table, '\0', sizeof(NODE));
+ null_array(global_table);
+
+ getnode(param_table);
+ memset(param_table, '\0', sizeof(NODE));
+ null_array(param_table);
+
+ installing_specials = true;
+ func_table = install_symbol(estrdup("FUNCTAB", 7), Node_var_array);
+
+ symbol_table = install_symbol(estrdup("SYMTAB", 6), Node_var_array);
+ installing_specials = false;
+}
/*
* install_symbol:
@@ -51,30 +75,49 @@ static int ctxt_level;
*/
NODE *
-install_symbol(char *name, NODETYPE type)
+install_symbol(const char *name, NODETYPE type)
{
return install(name, NULL, type);
}
-/* lookup --- find the most recent global or param node for name
+/*
+ * lookup --- find the most recent global or param node for name
* installed by install_symbol
*/
NODE *
lookup(const char *name)
{
- NODE *hp;
- size_t len;
- int hash1;
-
- len = strlen(name);
- hash1 = hash(name, len, (unsigned long) HASHSIZE, NULL);
- for (hp = variables[hash1]; hp != NULL; hp = hp->hnext) {
- if (hp->hlength == len && strncmp(hp->hname, name, len) == 0)
- return hp->hvalue;
+ NODE *n;
+ NODE *tmp;
+ NODE *tables[5]; /* manual init below, for z/OS */
+ int i;
+
+ /* ``It's turtles, all the way down.'' */
+ tables[0] = param_table; /* parameters shadow everything */
+ tables[1] = global_table; /* SYMTAB and FUNCTAB found first, can't be redefined */
+ tables[2] = func_table; /* then functions */
+ tables[3] = symbol_table; /* then globals */
+ tables[4] = NULL;
+
+ tmp = make_string(name, strlen(name));
+
+ n = NULL;
+ for (i = 0; tables[i] != NULL; i++) {
+ if (tables[i]->table_size == 0)
+ continue;
+
+ if ((do_posix || do_traditional) && tables[i] == global_table)
+ continue;
+
+ n = in_array(tables[i], tmp);
+ if (n != NULL)
+ break;
}
- return NULL;
+
+ unref(tmp);
+ return n; /* NULL or new place */
}
/* make_params --- allocate function parameters for the symbol table */
@@ -82,7 +125,7 @@ lookup(const char *name)
NODE *
make_params(char **pnames, int pcount)
{
- NODE *hp, *parms;
+ NODE *p, *parms;
int i;
if (pcount <= 0 || pnames == NULL)
@@ -91,12 +134,10 @@ make_params(char **pnames, int pcount)
emalloc(parms, NODE *, pcount * sizeof(NODE), "make_params");
memset(parms, '\0', pcount * sizeof(NODE));
- for (i = 0, hp = parms; i < pcount; i++, hp++) {
- hp->type = Node_param_list;
- hp->hname = pnames[i]; /* shadows pname and vname */
- hp->hlength = strlen(pnames[i]);
- hp->param_cnt = i;
- hp->hvalue = hp; /* points to itself */
+ for (i = 0, p = parms; i < pcount; i++, p++) {
+ p->type = Node_param_list;
+ p->param = pnames[i]; /* shadows pname and vname */
+ p->param_cnt = i;
}
return parms;
@@ -112,13 +153,15 @@ install_params(NODE *func)
if (func == NULL)
return;
+
assert(func->type == Node_func);
- if ((pcount = func->param_cnt) <= 0
- || (parms = func->fparms) == NULL
- )
+
+ if ( (pcount = func->param_cnt) <= 0
+ || (parms = func->fparms) == NULL)
return;
+
for (i = 0; i < pcount; i++)
- (void) install(NULL, parms + i, Node_param_list);
+ (void) install(parms[i].param, parms + i, Node_param_list);
}
@@ -129,34 +172,35 @@ install_params(NODE *func)
void
remove_params(NODE *func)
{
- NODE *parms, *p, *prev, *n;
- int i, pcount, hash1;
+ NODE *parms, *p;
+ int i, pcount;
if (func == NULL)
return;
+
assert(func->type == Node_func);
- if ((pcount = func->param_cnt) <= 0
- || (parms = func->fparms) == NULL
- )
+
+ if ( (pcount = func->param_cnt) <= 0
+ || (parms = func->fparms) == NULL)
return;
for (i = pcount - 1; i >= 0; i--) {
+ NODE *tmp;
+ NODE *tmp2;
+
p = parms + i;
- hash1 = p->hcode;
- if (hash1 < 0 || hash1 >= HASHSIZE)
- continue;
- for (prev = NULL, n = variables[hash1]; n != NULL;
- prev = n, n = n->hnext) {
- if (n == p)
- break;
- }
- if (n == NULL)
- continue;
- if (prev == NULL)
- variables[hash1] = n->hnext; /* param at the head of the chain */
+ assert(p->type == Node_param_list);
+ tmp = make_string(p->vname, strlen(p->vname));
+ tmp2 = in_array(param_table, tmp);
+ if (tmp2 != NULL && tmp2->dup_ent != NULL)
+ tmp2->dup_ent = tmp2->dup_ent->dup_ent;
else
- prev->hnext = n->hnext; /* param not at the head */
+ (void) assoc_remove(param_table, tmp);
+
+ unref(tmp);
}
+
+ assoc_clear(param_table); /* shazzam! */
}
@@ -165,39 +209,23 @@ remove_params(NODE *func)
NODE *
remove_symbol(NODE *r)
{
- NODE *prev, *hp;
- int hash1;
-
- hash1 = hash(r->vname, strlen(r->vname), (unsigned long) HASHSIZE, NULL);
- for (prev = NULL, hp = variables[hash1]; hp != NULL;
- prev = hp, hp = hp->hnext) {
- if (hp->hvalue == r)
- break;
- }
+ NODE *n = in_array(symbol_table, r);
- if (hp == NULL)
- return NULL;
- assert(hp->hcode == hash1);
-
- if (prev == NULL)
- variables[hash1] = hp->hnext; /* symbol at the head of chain */
- else
- prev->hnext = hp->hnext; /* symbol not at the head */
-
- if (r->type == Node_param_list)
- return r; /* r == hp */
- if (r->type == Node_func)
- func_count--;
- if (r->type != Node_ext_func)
- var_count--;
- freenode(hp);
- return r;
+ if (n == NULL)
+ return n;
+
+ n = dupnode(n);
+
+ (void) assoc_remove(symbol_table, r);
+
+ return n;
}
-/* destroy_symbol --- remove a symbol from symbol table
-* and free all associated memory.
-*/
+/*
+ * destroy_symbol --- remove a symbol from symbol table
+ * and free all associated memory.
+ */
void
destroy_symbol(NODE *r)
@@ -236,7 +264,7 @@ destroy_symbol(NODE *r)
default:
/* Node_param_list -- YYABORT */
- return;
+ break; /* use break so that storage is freed */
}
efree(r->vname);
@@ -247,48 +275,71 @@ destroy_symbol(NODE *r)
/* make_symbol --- allocates a global symbol for the symbol table. */
static NODE *
-make_symbol(char *name, NODETYPE type)
+make_symbol(const char *name, NODETYPE type)
{
- NODE *hp, *r;
+ NODE *r;
- getnode(hp);
- hp->type = Node_hashnode;
- hp->hlength = strlen(name);
- hp->hname = name;
getnode(r);
memset(r, '\0', sizeof(NODE));
- hp->hvalue = r;
if (type == Node_var_array)
- init_array(r);
+ null_array(r);
else if (type == Node_var)
r->var_value = dupnode(Nnull_string);
- r->vname = name;
+ r->vname = (char *) name;
r->type = type;
- return hp;
+
+ return r;
}
/* install --- install a global name or function parameter in the symbol table */
static NODE *
-install(char *name, NODE *hp, NODETYPE type)
+install(const char *name, NODE *parm, NODETYPE type)
{
- int hash1;
NODE *r;
+ NODE **aptr;
+ NODE *table;
+ NODE *n_name;
+ NODE *prev;
+
+ n_name = make_string(name, strlen(name));
+ table = symbol_table;
+
+ if (type == Node_param_list) {
+ table = param_table;
+ } else if ( type == Node_func
+ || type == Node_ext_func
+ || type == Node_builtin_func) {
+ table = func_table;
+ } else if (installing_specials) {
+ table = global_table;
+ }
- if (hp == NULL) {
+ if (parm != NULL)
+ r = parm;
+ else {
/* global symbol */
- hp = make_symbol(name, type);
+ r = make_symbol(name, type);
if (type == Node_func)
func_count++;
- if (type != Node_ext_func)
+ if (type != Node_ext_func && type != Node_builtin_func && table != global_table)
var_count++; /* total, includes Node_func */
}
- r = hp->hvalue;
- hash1 = hash(hp->hname, hp->hlength, (unsigned long) HASHSIZE, NULL);
- hp->hcode = hash1;
- hp->hnext = variables[hash1];
- variables[hash1] = hp;
+ if (type == Node_param_list) {
+ prev = in_array(table, n_name);
+ if (prev == NULL)
+ goto simple;
+ r->dup_ent = prev->dup_ent;
+ prev->dup_ent = r;
+ } else {
+simple:
+ /* the simple case */
+ aptr = assoc_lookup(table, n_name);
+ unref(*aptr);
+ *aptr = r;
+ }
+ unref(n_name);
if (install_func)
(*install_func)(r);
@@ -296,7 +347,6 @@ install(char *name, NODE *hp, NODETYPE type)
return r;
}
-
/* comp_symbol --- compare two (variable or function) names */
static int
@@ -319,34 +369,55 @@ typedef enum { FUNCTION = 1, VARIABLE } SYMBOL_TYPE;
/* get_symbols --- return a list of optionally sorted symbols */
static NODE **
-get_symbols(SYMBOL_TYPE what, int sort)
+get_symbols(SYMBOL_TYPE what, bool sort)
{
int i;
NODE **table;
- NODE *hp, *r;
- long j, count = 0;
+ NODE **list;
+ NODE *r;
+ long count = 0;
+ long max;
+ NODE *the_table;
+
+ /*
+ * assoc_list() returns an array with two elements per awk array
+ * element. Elements i and i+1 in the C array represent the key
+ * and value of element j in the awk array. Thus the loops use += 2
+ * to go through the awk array.
+ */
+
+ if (what == FUNCTION) {
+ the_table = func_table;
+ max = the_table->table_size * 2;
+
+ list = assoc_list(the_table, "@unsorted", ASORTI);
+ emalloc(table, NODE **, (func_count + 1) * sizeof(NODE *), "get_symbols");
+
+ for (i = count = 0; i < max; i += 2) {
+ r = list[i+1];
+ if (r->type == Node_ext_func || r->type == Node_builtin_func)
+ continue;
+ assert(r->type == Node_func);
+ table[count++] = r;
+ }
+ } else { /* what == VARIABLE */
+ update_global_values();
- if (what == FUNCTION)
- count = func_count;
- else /* if (what == VARIABLE) */
- count = var_count;
+ the_table = symbol_table;
+ max = the_table->table_size * 2;
- emalloc(table, NODE **, (count + 1) * sizeof(NODE *), "symbol_list");
- if (what == VARIABLE)
- update_global_values();
+ list = assoc_list(the_table, "@unsorted", ASORTI);
+ emalloc(table, NODE **, (var_count + 1) * sizeof(NODE *), "get_symbols");
- for (i = j = 0; i < HASHSIZE; i++)
- for (hp = variables[i]; hp != NULL; hp = hp->hnext) {
- if (hp->type != Node_hashnode)
- continue;
- r = hp->hvalue;
- if (r->type == Node_ext_func)
+ for (i = count = 0; i < max; i += 2) {
+ r = list[i+1];
+ if (r->type == Node_val) /* non-variable in SYMTAB */
continue;
- if (what == FUNCTION && r->type == Node_func)
- table[j++] = r;
- else if (what == VARIABLE)
- table[j++] = r;
+ table[count++] = r;
}
+ }
+
+ efree(list);
if (sort && count > 1)
qsort(table, count, sizeof(NODE *), comp_symbol); /* Shazzam! */
@@ -360,13 +431,13 @@ get_symbols(SYMBOL_TYPE what, int sort)
NODE **
variable_list()
{
- return get_symbols(VARIABLE, TRUE);
+ return get_symbols(VARIABLE, true);
}
/* function_list --- list of functions */
NODE **
-function_list(int sort)
+function_list(bool sort)
{
return get_symbols(FUNCTION, sort);
}
@@ -386,7 +457,7 @@ print_vars(NODE **table, int (*print_func)(FILE *, const char *, ...), FILE *fp)
continue;
print_func(fp, "%s: ", r->vname);
if (r->type == Node_var_array)
- print_func(fp, "array, %ld elements\n", r->table_size);
+ print_func(fp, "array, %ld elements\n", assoc_length(r));
else if (r->type == Node_var_new)
print_func(fp, "untyped variable\n");
else if (r->type == Node_var)
@@ -418,25 +489,9 @@ foreach_func(NODE **table, int (*pfunc)(INSTRUCTION *, void *), void *data)
void
release_all_vars()
{
- int i;
- NODE *hp, *r, *next;
-
- for (i = 0; i < HASHSIZE; i++)
- for (hp = variables[i]; hp != NULL; hp = next) {
- next = hp->hnext;
- if (hp->type != Node_hashnode)
- continue;
- r = hp->hvalue;
- if (r->type == Node_func || r->type == Node_ext_func)
- continue;
- if (r->type == Node_var_array)
- assoc_clear(r);
- else if (r->type == Node_var)
- unref(r->var_value);
- efree(r->vname);
- freenode(r);
- freenode(hp);
- }
+ assoc_clear(symbol_table);
+ assoc_clear(func_table);
+ assoc_clear(global_table);
}
@@ -447,34 +502,129 @@ release_all_vars()
void
append_symbol(NODE *r)
{
- NODE *hp;
+ NODE *p;
- getnode(hp);
- hp->lnode = r;
- hp->rnode = symbol_list->rnode;
- symbol_list->rnode = hp;
+ getnode(p);
+ p->lnode = r;
+ p->rnode = symbol_list->rnode;
+ symbol_list->rnode = p;
}
-/* release_symbol --- free symbol list and optionally remove symbol from symbol table */
+/* release_symbols --- free symbol list and optionally remove symbol from symbol table */
void
release_symbols(NODE *symlist, int keep_globals)
{
- NODE *hp, *next;
+ NODE *p, *next;
- for (hp = symlist->rnode; hp != NULL; hp = next) {
+ for (p = symlist->rnode; p != NULL; p = next) {
if (! keep_globals) {
- /* destroys globals, function, and params
+ /*
+ * destroys globals, function, and params
* if still in symbol table
*/
- destroy_symbol(hp->lnode);
+ destroy_symbol(p->lnode);
}
- next = hp->rnode;
- freenode(hp);
+ next = p->rnode;
+ freenode(p);
}
symlist->rnode = NULL;
}
+/* load_symbols --- fill in symbols' information */
+
+void
+load_symbols()
+{
+ NODE *r;
+ NODE *tmp;
+ NODE *sym_array;
+ NODE **aptr;
+ long i, j, max;
+ NODE *user, *extension, *untyped, *scalar, *array, *built_in;
+ NODE **list;
+ NODE *tables[4];
+
+ if (PROCINFO_node == NULL)
+ return;
+
+ tables[0] = func_table;
+ tables[1] = symbol_table;
+ tables[2] = global_table;
+ tables[3] = NULL;
+
+ tmp = make_string("identifiers", 11);
+ aptr = assoc_lookup(PROCINFO_node, tmp);
+
+ getnode(sym_array);
+ memset(sym_array, '\0', sizeof(NODE)); /* PPC Mac OS X wants this */
+ null_array(sym_array);
+
+ unref(*aptr);
+ *aptr = sym_array;
+
+ sym_array->parent_array = PROCINFO_node;
+ sym_array->vname = estrdup("identifiers", 11);
+
+ user = make_string("user", 4);
+ extension = make_string("extension", 9);
+ scalar = make_string("scalar", 6);
+ untyped = make_string("untyped", 7);
+ array = make_string("array", 5);
+ built_in = make_string("builtin", 7);
+
+ for (i = 0; tables[i] != NULL; i++) {
+ list = assoc_list(tables[i], "@unsorted", ASORTI);
+ max = tables[i]->table_size * 2;
+ if (max == 0)
+ continue;
+ for (j = 0; j < max; j += 2) {
+ r = list[j+1];
+ if ( r->type == Node_ext_func
+ || r->type == Node_func
+ || r->type == Node_builtin_func
+ || r->type == Node_var
+ || r->type == Node_var_array
+ || r->type == Node_var_new) {
+ tmp = make_string(r->vname, strlen(r->vname));
+ aptr = assoc_lookup(sym_array, tmp);
+ unref(tmp);
+ unref(*aptr);
+ switch (r->type) {
+ case Node_ext_func:
+ *aptr = dupnode(extension);
+ break;
+ case Node_func:
+ *aptr = dupnode(user);
+ break;
+ case Node_builtin_func:
+ *aptr = dupnode(built_in);
+ break;
+ case Node_var:
+ *aptr = dupnode(scalar);
+ break;
+ case Node_var_array:
+ *aptr = dupnode(array);
+ break;
+ case Node_var_new:
+ *aptr = dupnode(untyped);
+ break;
+ default:
+ cant_happen();
+ break;
+ }
+ }
+ }
+ efree(list);
+ }
+
+ unref(user);
+ unref(extension);
+ unref(scalar);
+ unref(untyped);
+ unref(array);
+}
+
#define pool_size d.dl
#define freei x.xi
static INSTRUCTION *pool_list;
@@ -616,7 +766,7 @@ in_main_context()
/* free_context --- free context structure and related data. */
void
-free_context(AWK_CONTEXT *ctxt, int keep_globals)
+free_context(AWK_CONTEXT *ctxt, bool keep_globals)
{
SRCFILE *s, *sn;
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 00000000..fee5eeca
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,90 @@
+#
+# test/CMakeLists.txt --- CMake input file for gawk
+#
+# Copyright (C) 2013
+# 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 3 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 CMake to produce Makefile
+
+if(WIN32)
+ set(SHELL_PREFIX "C:\\MinGW\\msys\\1.0\\bin\\sh")
+endif()
+
+# Find the names of the groups of tests in Makefile.am.
+file(READ ${CMAKE_CURRENT_SOURCE_DIR}/Makefile.am ALL_GROUPS)
+string(REGEX MATCHALL "[A-Z_]*_TESTS " ALL_GROUPS "${ALL_GROUPS}")
+string(REGEX REPLACE "_TESTS " ";" ALL_GROUPS "${ALL_GROUPS}")
+# For each group of test cases, search through Makefile.am and find the test cases.
+foreach(testgroup ${ALL_GROUPS} )
+ file(READ ${CMAKE_CURRENT_SOURCE_DIR}/Makefile.am ONE_GROUP)
+ string(REGEX MATCH "${testgroup}_TESTS = [a-z0-9_ \\\n\t]*" ONE_GROUP "${ONE_GROUP}")
+ string(REGEX REPLACE "${testgroup}_TESTS = " "" ONE_GROUP "${ONE_GROUP}")
+ string(REGEX REPLACE "[\\\n\t]" "" ONE_GROUP "${ONE_GROUP}")
+ string(REGEX REPLACE " " ";" ONE_GROUP "${ONE_GROUP}")
+ # Use each name of a test case to start a script that executes the test case.
+ foreach(testcase ${ONE_GROUP} )
+ add_test("${testgroup}.${testcase}" ${SHELL_PREFIX} ${CMAKE_SOURCE_DIR}/cmake/basictest ${CMAKE_BINARY_DIR}/gawk${CMAKE_EXECUTABLE_SUFFIX} ${testcase})
+ endforeach(testcase)
+endforeach(testgroup)
+
+# Create an empty configuration file for customizing test execution.
+set(CTestCustom ${CMAKE_BINARY_DIR}/CTestCustom.cmake)
+file(WRITE ${CTestCustom} "# DO NOT EDIT, THIS FILE WILL BE OVERWRITTEN\n" )
+# Test case SHLIB.filefuncs needs a file named gawkapi.o in source directory.
+file(APPEND ${CTestCustom} "file(COPY ${CMAKE_SOURCE_DIR}/README DESTINATION ${CMAKE_SOURCE_DIR}/gawkapi.o)\n")
+# Exclude test cases from execution that make no sense on a certain platform.
+file(APPEND ${CTestCustom} "set(CTEST_CUSTOM_TESTS_IGNORE\n")
+if(WIN32)
+ file(APPEND ${CTestCustom} " BASIC.exitval2\n")
+ file(APPEND ${CTestCustom} " BASIC.hsprint\n")
+ file(APPEND ${CTestCustom} " BASIC.rstest4\n")
+ file(APPEND ${CTestCustom} " BASIC.rstest5\n")
+ file(APPEND ${CTestCustom} " UNIX.getlnhd\n")
+ file(APPEND ${CTestCustom} " UNIX.pid\n")
+ file(APPEND ${CTestCustom} " GAWK_EXT.beginfile1\n")
+ file(APPEND ${CTestCustom} " GAWK_EXT.beginfile2\n")
+ file(APPEND ${CTestCustom} " GAWK_EXT.clos1way\n")
+ file(APPEND ${CTestCustom} " GAWK_EXT.devfd\n")
+ file(APPEND ${CTestCustom} " GAWK_EXT.devfd1\n")
+ file(APPEND ${CTestCustom} " GAWK_EXT.devfd2\n")
+ file(APPEND ${CTestCustom} " GAWK_EXT.getlndir\n")
+ file(APPEND ${CTestCustom} " GAWK_EXT.posix\n")
+ file(APPEND ${CTestCustom} " GAWK_EXT.pty1\n")
+ file(APPEND ${CTestCustom} " INET.inetdayu\n")
+ file(APPEND ${CTestCustom} " INET.inetdayt\n")
+ file(APPEND ${CTestCustom} " INET.inetechu\n")
+ file(APPEND ${CTestCustom} " INET.inetecht\n")
+ file(APPEND ${CTestCustom} " MACHINE.double2\n")
+ file(APPEND ${CTestCustom} " LOCALE_CHARSET.fmttest\n")
+ file(APPEND ${CTestCustom} " LOCALE_CHARSET.lc_num1\n")
+ file(APPEND ${CTestCustom} " LOCALE_CHARSET.mbfw1\n")
+ file(APPEND ${CTestCustom} " SHLIB.filefuncs\n")
+ file(APPEND ${CTestCustom} " SHLIB.fnmatch\n")
+ file(APPEND ${CTestCustom} " SHLIB.fork\n")
+ file(APPEND ${CTestCustom} " SHLIB.fork2\n")
+ file(APPEND ${CTestCustom} " SHLIB.fts\n")
+ file(APPEND ${CTestCustom} " SHLIB.functab4\n")
+ file(APPEND ${CTestCustom} " SHLIB.readdir\n")
+ file(APPEND ${CTestCustom} " SHLIB.revtwoway\n")
+ file(APPEND ${CTestCustom} " SHLIB.rwarray\n")
+endif()
+file(APPEND ${CTestCustom} ")\n")
+
diff --git a/test/ChangeLog b/test/ChangeLog
index 05a74f87..19105027 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,961 @@
+2015-01-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (profile8): Actually add the test and the files.
+ Thanks to Hermann Peifer for the report.
+
+2015-01-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (profile8): New test.
+ * profile8.awk, profile8.ok: New files.
+
+2015-01-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (dumpvars): Grep out ENVIRON and PROCINFO since
+ those can be different depending on who runs the test.
+ * dumpvars.ok, id.ok: Updated after code changes.
+
+2015-01-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (regexpbrack): New test.
+ * regexpbrack.awk, regexpbrack.in, regexpbrack.ok: New files.
+
+ Unrelated:
+
+ * Makefile.am (printfbad4): New test.
+ * printfbad4.awk, printfbad4.ok: New files.
+
+ Unrelated:
+
+ * testext.ok: Adjust for code changes.
+
+2014-12-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (badbuild): New test.
+ * badbuild.awk, badbuild.in, badbuild.ok: New files.
+
+2014-12-24 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (check): If tests don't pass, run 'make diffout'
+ and exit 1. Should help distros to notice when they have built
+ gawk incorrectly. (Can you say "Fedora", boys and girls?)
+
+2014-12-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile5.ok: Updated after code changes.
+
+2014-11-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Gentests: Fix gensub call after adding warning.
+
+2014-11-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gensub2.ok: Update after code changes.
+
+2014-11-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (sortglos): New test.
+ * sortglos.awk, sortglos.in, sortglos.ok: New files.
+ Thanks to Antonio Columbo.
+
+2014-11-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * mbprintf4.awk: Add record and line number for debugging.
+ * mpprint4.ok: Adjust.
+
+2014-11-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (profile7): New test.
+ (profile6): Add missing @ in front of gawk run.
+ * profile7.awk, profile7.ok: New files.
+
+2014-11-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (profile6): Actually run profiling. Should make test
+ output consistent with what's in master.
+ * profile6.ok: Updated.
+
+2014-10-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (profile6): New test.
+ * profile6.awk, profile6.ok: New files.
+
+2014-10-17 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (profile1, testext): Use explicit ./foo.awk to avoid
+ assumptions about AWKPATH in the environment.
+
+2014-10-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (charset-msg-start): Add a list of needed locales.
+ Suggested by Shaun Jackman <sjackman@gmail.com>.
+
+2014-10-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile2.ok, profile3.ok, profile4.ok, profile5.ok:
+ Adjusted after minor code change. Again.
+
+2014-10-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (genpot): New test.
+ * genpot.awk, genpot.ok: New files.
+
+2014-09-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.ok: Adjusted after minor code change.
+
+2014-09-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile2.ok, profile3.ok, profile4.ok, profile5.ok:
+ Adjusted after minor code change.
+
+2014-09-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.awk: Change to build directory instead of "..".
+ * Makefile.am (filefuncs): Pass in $(abs_top_builddir).
+
+2014-09-13 Stephen Davies <sdavies@sdc.com.au>
+
+ * Makefile.am (profile4, profile5): Changes processing to not delete
+ the first two lines. This is no longer needed.
+ * profile4.ok, profile5.ok: Changed to suit new rules and comments.
+
+2014-09-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile2.ok, profile4.ok, profile5.ok: Update for new code.
+
+2014-09-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ * functab4.awk: Changed to use stat instead of chdir since
+ /tmp isn't /tmp on all systems (e.g. Mac OS X). Thanks to
+ Hermann Peifer for the report.
+
+ Sort of related:
+
+ * indirectcall2.awk, indirectcall2.ok: New files.
+ * id.ok: Updated.
+
+2014-09-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile2.ok: Update after code improvement in profiler.
+ * functab4.ok: Update after making indirect calls of
+ extension functions work. :-)
+
+2014-08-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * badargs.ok: Adjust after revising text for -L option.
+
+2014-08-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * ofs1.ok: Updated to match corrected behavior in gawk.
+
+2014-08-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (mpfrsqrt): New test.
+ * mpfrsqrt.awk, mpfrsqrt.ok: New files.
+ Test from Katie Wasserman <katie@wass.net>.
+
+2014-07-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * printhuge.awk: Add a newline to output.
+ * printhuge.ok: Adjust.
+
+2014-07-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * badargs.ok: Adjust after correctly alphabetizing options.
+
+2014-07-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (printhuge): New test.
+ * printhuge.awk, printhuge.ok: New files.
+ Test from mail.green.fox@gmail.com.
+
+2014-06-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (profile1, profile4, profile5): Adjust for change to
+ --pretty-print option.
+
+2014-06-19 Michael Forney <forney@google.com>
+
+ * Makefile.am (poundbang): Fix relative path of AWKPROG.
+
+2014-06-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (dbugeval): Add leading @ to recipe. Ooops.
+
+2014-05-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (regnul1, regnul2): New tests.
+ * regnul1.awk, regnul1.ok, regnul1.awk, regnul2.ok: New files.
+
+2014-05-22 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * lintwarn.ok: Updated.
+
+2014-05-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (EXTRA_DIST): Forgot dbugeval.ok. Ooops.
+
+2014-05-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (dbugeval): New test.
+ * dbugeval.in, dbugeval.ok: New files.
+
+2014-05-10 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (rsglstdin): New test.
+ * rsglstdin.ok: New file.
+
+2014-05-09 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (rebuf): Force buffer size to 4096 via AWKBUFSIZE
+ environment variable.
+ (rsgetline): New test.
+ * rsgetline.awk, rsgetline.in, rsgetline.ok: New files.
+
+2014-04-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (charset-msg-start): Add a warning message that tests
+ may fail without adequate locale support, per request from
+ Nelson H.F. Beebe.
+
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.1: Release tar ball made.
+
+2014-04-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am: Prettify list of tests a little bit.
+
+2014-04-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (EXTRA_DIST): Add readfile2.ok. Oops.
+
+2014-03-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (readfile2): New test.
+ * readfile2.awk, readfile2.ok: New files.
+
+2014-02-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regrange.ok: Update after code improvements.
+
+2014-02-03 Stepan Kasal <kasal@ucw.cz>
+
+ * strftime.awk: the default format uses %e, not %d (Introduced on
+ 2014-01-16; the previous code mangled the output of command "date"
+ to match %d.) Remove the "mucking" for cygwin, it's obsolete and
+ incompatible with %e.
+
+2014-01-28 Eli Zaretskii <eliz@gnu.org>
+
+ * strftime.awk: If DATECMD variable is non-empty, use it instead
+ of the literal "date" as the 'date'-like command.
+
+2014-01-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (mpfrnegzero): New test.
+ * mpfrnegzero.awk, mpfrnegzero.ok: New files.
+
+2014-01-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (readdir): Run ls commands outside the awk script.
+ * readdir0.awk: Read ls results from files. Helps with MinGW.
+ Thanks to Eli Zaretskii for the problem report.
+
+2014-01-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am: Quote instances of $(top_srcdir) also.
+
+2014-01-16 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (strftime): Remove comment about the race condition, since
+ this should be fixed. And gawk now calls date inside the script.
+ * strftime.awk: Based on an idea from Pat Rankin, fix the race
+ condition by looping repeatedly over strftime/date/strftime until
+ the before and after strftime results match. That should fix
+ the race condition where the seconds field might increment between
+ invocations.
+
+2014-01-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (split_after_fpat): New test.
+ * split_after_fpat.awk, split_after_fpat.ok,
+ split_after_fpat.in: New files.
+
+2013-12-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (ignrcas2): Change to use en_US.UTF-8; it
+ seems that plain en_US doesn't exist anymore. Thanks to
+ Richard Palo.
+
+2013-12-29 John E. Malmberg <wb8tyw@qsl.net>
+
+ * fts.awk: Adjust for VMS.
+ * rwarray.awk: Adjust for VMS.
+
+2013-12-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am: Remove instances of "" that were incorrect.
+ Thanks to Scott Deifik for the report.
+
+2013-12-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (fts): Add a check for Cygwin on NFS and print
+ a message, similar to that of IRIX. Per Corinna Vinschen.
+
+2013-11-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (pipeio3): Removed test and reference to files.
+ It was too ful of race conditions to work reliably everywhere.
+ * pipeio3.awk, pipeio3.ok, pipeio3.ok2: Removed.
+
+2013-11-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * readdir0.awk: Take argument which is directory to read.
+ * Makefile.am (readdir): Pass $(top_srcdir) to readdir0.awk.
+
+2013-11-27 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * readdir0.awk: Restore fix so that we do not fail on filesysystems
+ such as XFS where the dirent does not contain the file type.
+
+2013-11-27 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (ordchr2): Use --load instead of -l to make sure the
+ long option works properly. Note that the readfile test still uses
+ the short version.
+ (include2): Use --include instead of -i to make sure that the long
+ option works properly. Note that many other tests use the -i short
+ version.
+
+2013-11-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * readdir0.awk: Use `ls -lan' to get numeric user and group ID
+ numbers. This keeps the number of fields correct and consistent, even
+ on systems (like, oh, say, Windows with Cygwin) where group names
+ can contain spaces.
+
+2013-11-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ Solaris fixes.
+
+ * readdir0.awk: Run ls -afi and ls -la separately since POSIX
+ says that -f turns off -l. Thanks to Dagobert Michelsen
+ <dam@opencsw.org> for the report.
+ * Makefile.am (diffout): Don't use POSIX or bash-isms so that
+ it will work on Solaris. Sigh.
+
+2013-11-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (backsmalls2): New test.
+ (pipeio3): Check results against pipeio3.ok2 if
+ the first check fails.
+ * backsmalls2.awk, backsmalls2.ok: New files.
+ * pipeio3.ok2: New file. This is the results on PPC Mac OS X.
+
+2013-10-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (pipeio3): Enhance test, again, to be more resilient
+ to variations in error messages produced by different Bourne shells
+ when a command is not found. This time for Cygwin.
+
+ Unrelated:
+
+ (charasbytes): Translit any tabs to spaces. Should help on
+ some System V systems such as Solaris. We hope.
+
+ Unrelated:
+
+ (pass-fail): Exit non-zero if tests fail. Useful for buildbots.
+
+2013-10-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (pipeio3): Enhance test to be more resilient to
+ variations in error messages produced by different Bourne shells
+ when a command is not found. Initially for Mac OS X.
+
+2013-10-17 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (pipeio3): New test.
+ * pipeio3.awk, pipeio3.ok: New files.
+
+2013-10-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (backbigs1, backsmalls1): New tests.
+ * backbigs1.awk, backbigs1.in, backbigs1.ok: New files.
+ * backsmalls1.awk, backsmalls1.in, backsmalls1.ok: New files.
+
+2013-10-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (badassign1): New test.
+ * badassign1.awk, badassign1.ok: New files.
+
+2013-09-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makfile.am (randtest): New test.
+ * randtest.sh, randtest.ok: New files.
+ * rand.ok: Updated to reflect new results based on code change.
+
+2013-09-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am: Fix quoting for generation of Maketests file so
+ that it will happen correctly.
+
+ Unrelated:
+
+ * Makefile.am (nfloop): New test.
+ * nfloop.awk, nfloop.ok: New files.
+
+2013-08-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am: Quote $(srcdir) everywhere so that tests can run
+ in locations with spaces in their names (think Windows or Mac OS X).
+ * Gentests: Ditto for when creating Maketests file.
+
+2013-07-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile2.ok, profile5.ok: Update.
+
+2013-07-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (mbprintf4): New test.
+ * mbprintf4.awk, mbprintf4.in, mbprintf4.ok: New files.
+ Test cases from Nethox <nethox@gmail.com>.
+
+2013-06-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (dfamb1): New test.
+ * dfamb1.awk, dfamb1.in, dfamb1.ok: New files.
+ Test case from Steven Daniels <stevendaniels88@gmail.com>.
+
+2013-06-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (clos1way): Move to here since Maketests gets
+ regenerated whenever Makefile.am is touched.
+
+2013-06-22 Eli Zaretskii <eliz@gnu.org>
+
+ * Maketests (clos1way): Set LC_ALL=C, since clos1way.awk no longer
+ does.
+
+2013-06-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (exit2): New test.
+ * exit2.awk, exit2.ok: New files.
+
+2013-06-01 Eli Zaretskii <eliz@gnu.org>
+
+ * clos1way.awk: Don't use features of Posix shells, to allow this
+ test to work on Windows.
+
+ * beginfile2.sh: Leave one blank between the left quote and the
+ following slash. Use non-absolute name for a non-existent file.
+ This is to avoid breakage on Windows due to MSYS transformation of
+ Posix style /foo/bar absolute file names.
+
+ * beginfile2.ok: Adapt to changes in beginfile2.sh.
+
+2013-05-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (profile4, profile5): New tests.
+ * profile4.awk, profile4.in, profile5.awk, profile5.in: New files.
+
+2013-05-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (mpfr-tests, shlib-tests): Propogate Eli's changes
+ and comment of 2013-05-14 to here, so that they get passed into
+ Makefile.in whenever Makefile.am is modified.
+
+2013-05-14 Eli Zaretskii <eliz@gnu.org>
+
+ * Makefile.in (mpfr-tests, shlib-tests): Add a blank character
+ between ' and /FOO/ in Gawk command lines, for the benefit of
+ testing under MSYS Bash.
+
+ * filefuncs.awk (BEGIN): Call 'stat' on gawkapi.o, not on gawk,
+ which does not exist on systems that produce gawk.exe.
+
+2013-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.0: Release tar ball made.
+
+2013-05-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * symtab9.awk: Don't remove test file in END rule, breaks on Windows.
+ * Makefile.am (symtab9): Add explicit rule and remove test file file.
+
+2013-04-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (LOCALES): New variable split out from AWK.
+ (AWK): Adjust.
+ (next): Add LOCALES to the test so that it will pass everywhere.
+ Thanks to Juergen Kahrs for the report.
+
+2013-04-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am: Prettify the lists of tests.
+ (GENTESTS_UNUSED): Bring the list up to date.
+
+2013-03-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (readdir): Add a check for GNU/Linux and NFS directory
+ and issue a warning if so.
+ (fts): Ditto for IRIX - can't check for NFS so just print the message.
+ (fnmatch.awk, fnmatch.ok): Improve portability.
+
+2013-03-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (readdir): Add -a to ls options. -f does not
+ automatically mean -a on all systems.
+ * jarebug.sh: Send error output of locale to /dev/null in case
+ it doesn't exist.
+
+2013-03-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (colonwarn): New test.
+ * colonwarn.awk, colonwarn.in, colonwarn.ok: New files.
+
+2013-02-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * parseme.ok: Update after change in grammar. Now with new and
+ improved error message!
+
+2013-01-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am: Move functab4 into shlib tests, since it uses
+ @load. Thanks to Anders Wallin for the report.
+ (shlib-tests): Check --version output for "API" and run tests
+ if there.
+
+2013-01-31 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am: To decide whether to run MPFR tests, use the output
+ of gawk --version instead of the automake TEST_MPFR conditional (which
+ has now been removed from configure.ac).
+
+2013-01-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (EXTRA_DIST): Add all the mpfr test files. Duh.
+ (reginttrad): Use $(srcdir)/$@.awk. Double Duh.
+
+2013-01-27 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am: Add mpfr tests if MPFR is available.
+
+2013-01-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (reginttrad): New test.
+ * reginttrad.awk, reginttrad.ok: New files.
+
+2013-01-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ Fix tests to work with make diffout:
+
+ * rtlenmb.ok: New file.
+ * Makefile.am (clobber, mmap8k, rtlenmb): Tests adjusted.
+ (EXTRA_DIST): Add rtlenmb.ok.
+
+2013-01-15 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Gentests: Remove a debugging printf.
+
+2013-01-15 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (readdir): Try to protect against failure on filesystems
+ lacking type information by invoking readdir.awk before readdir0.awk
+ and passing the results of readdir to readdir0 for inspection.
+ * readdir0.awk: Analyze the results of the readdir extension.
+ If all file types are set to "u", we infer that this filesystem lacks
+ type information.
+
+2013-01-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (rand): Let Gentests create the test.
+ (fmtspcl): Add $(AWKFLAGS).
+ * Gentests: For MPFR tests, add $(AWKFLAGS) on the command line.
+ * mpfr-rand.ok: Updated.
+
+2013-01-14 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (symtab8): Use grep to remove FILENAME from the output
+ so the test will succeed when building outside the source tree.
+ * symtab8.ok: Remove FILENAME.
+
+2013-01-10 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * inplace.1.in, inplace.2.in, inplace.in, inplace1.1.ok, inplace1.2.ok,
+ inplace1.ok, inplace2.1.bak.ok, inplace2.1.ok, inplace2.2.bak.ok,
+ inplace2.2.ok, inplace2.ok, inplace3.1.bak.ok, inplace3.1.ok,
+ inplace3.2.bak.ok, inplace3.2.ok, inplace3.ok: New files.
+ * Makefile.am (EXTRA_DIST): Add new files.
+ (SHLIB_TESTS): Add inplace1, inplace2, and inplace3.
+ (inplace1, inplace2, inplace3): New tests.
+
+2012-12-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * assignconst.awk, assignconst.ok: Removed.
+ * Makefile.am (EXTRA_DIST): Removed assignconst.awk, assignconst.ok.
+ (SHLIB_TESTS): Removed assignconst.
+ (assignconst): Removed test.
+
+2012-12-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.2: Release tar ball made.
+
+2012-12-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (paramuninitglobal): New test.
+ * paramuninitglobal.awk, paramuninitglobal.ok: New files.
+ Thanks to John Haque.
+
+2012-12-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * symtab9.awk, symtab9.ok: New files.
+ * Makefile.am (EXTRA_DIST): Add new files.
+ (symtab9): New test.
+ * symtab1.ok, testext.ok: Updated.
+
+2012-12-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * symtab7.awk, symtab7.in, symtab7.ok, symtab8.awk, symtab8.in,
+ symtab8.ok: New files.
+ * Makefile.am (EXTRA_DIST): Add new files.
+ (symtab7, symtab8): New tests.
+ Thanks to Assaf Gordon <gordon@cshl.edu>.
+
+2012-11-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (readdir): Add a 'this could fail message'.
+ * readdir.awk: Revise to match simplified behavior of the extension.
+
+2012-11-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (GAWK_EXTRA_TESTS): Move to sorted order of tests.
+
+2012-11-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * symtab6.ok: Remove PROCINFO.
+ * Makefile.am (symtab6): Adjust recipe.
+
+2012-11-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * symtab4.awk, symtab4.in, symtab4.ok, symtab5.awk, symtab5.in,
+ symtab5.ok, symtab6.awk: New files.
+ * Makefile.am (EXTRA_DIST): Add new files.
+ (symtab4, symtab5, symtab6): New tests.
+ Thanks to Assaf Gordon <gordon@cshl.edu>.
+
+2012-10-28 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * messages.awk, fts.awk: Adjusted so make diffout will work.
+ * Makefile.am (messages): Adjust to use standard failure test for
+ make diffout.
+
+2012-10-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * symtab1.awk: Adjust to not print ENVIRON and PROCINFO which won't
+ be the same as on the author's machine.
+ * lintwarn.ok: Adjust.
+
+2012-10-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (EXTRA_DIST): Add jarebug.sh.
+
+2012-10-11 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (readdir): Use $(top_srcdir) instead of `.'. Helps
+ when running the valgrind tests.
+
+2012-10-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.ok: Updated.
+
+2012-10-04 Akim Demaille <akim@lrde.epita.fr>
+
+ Fix VPATH builds.
+
+ * Makefile.am (shlib-tests): config.h is in builddir.
+ (beginfile2): So is gawk itself.
+
+ * Makefile.am (functab1, functab2, functab3, functab4, id, symtab1,
+ symtab2, symtab3): New tests.
+ * functab1.awk, functab1.ok, functab2.awk, functab2.ok, functab3.awk,
+ functab3.ok, functab4.awk, functab4.ok, id.awk, id.ok, symtab1.awk,
+ symtab1.ok, symtab2.awk, symtab2.ok, symtab3.awk, symtab3.ok:
+ New files.
+
+2012-09-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * lintwarn.ok: Updated.
+
+2012-09-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.ok: Updated. Twice.
+
+2012-09-11 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (shlib-tests): Check if DYNAMIC is enabled and
+ only if so run the tests. A bit hacky. Needed at least for
+ z/OS.
+
+2012-09-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * readdir.awk: Change argument to readdir_do_ftype().
+
+2012-08-28 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (EXTRA_DIST): Add jarebug.sh.
+ (readdir): Use standard output filenames readdir.ok and _readdir
+ instead of readdir.out1 and readdir.out2. The standard names are
+ required for the pass-fail and diffout rules to work correctly.
+ (clean): Remove readdir.ok
+
+2012-08-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (charasbytes): Revise test to canonicalize
+ whitespace. (For Mac OS X 10.5, at least.)
+ * charasbytes.ok: Updated.
+
+2012-08-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (revout, revtwoway): New tests.
+ * revout.awk, revout.ok, revtwoway.awk, revtwoway.ok: New files.
+
+2012-08-11 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (EXTRA_DIST): Add inchello.awk and incdupe[4-7].ok.
+ (GAWK_EXT_TESTS): Add incdupe[4-7].
+ (incdupe[4-7]): New tests to ensure that mixing -f with include
+ causes a fatal error.
+ * incdupe[4-7].ok, inchello.awk: New files.
+
+2012-08-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (fts): New test.
+ * fts.awk: New file.
+
+2012-07-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (assignconst): Use AWKPATH to get results that will
+ be consistent no matter where the test is run.
+ * assignconst.ok: Updated.
+
+2012-07-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (readdir): New test.
+ * readdir0.awk, readdir.awk: New files.
+
+2012-07-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * fnmatch.awk, fnmatch.ok: Portability updates.
+
+2012-07-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.ok: Update contents.
+
+2012-07-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (fnmatch): New test.
+ * fnmatch.awk, fnmatch.ok: New files.
+
+ * Makefile.am (assignconst): New test.
+ * assignconst.awk, assignconst.ok: New files.
+
+2012-06-28 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * time.awk: Avoid possibly throwing a spurious error by protecting
+ a race condition that depends on the order of expression evaluation.
+
+2012-06-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (rwarray): New test.
+ * rwarray.awk, rwarray.in, rwarray.ok: New files.
+
+2012-06-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.ok: Update contents.
+
+2012-06-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.ok: Update contents.
+
+2012-06-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.ok: Update contents.
+
+2012-06-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (testext): New test.
+ (EXTRA_DIST): Add new file testext.ok.
+ (SHLIB_TESTS): Add testext.
+ (clean): Add testext.awk to the list.
+ * testext.ok: New file.
+
+2012-06-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (clean): Add fork.tmp.* to the list.
+
+2012-06-10 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (EXTRA_DIST): Add new files time.awk and time.ok.
+ (SHLIB_TESTS): Add time.
+ * time.awk, time.ok: New files.
+
+2012-05-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (clean): Add readfile.ok to list of files to removed.
+
+2012-05-26 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (readfile): Revert previous patch, and add comment
+ explaining that we need to create readfile.ok on failure so that
+ "make diffout" will work properly.
+ (ordchr.awk, ordchr.ok): Add more tests to catch type conversion
+ problems.
+
+2012-05-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (readfile): Don't copy the Makefile over readfile.ok
+ if there's a problem.
+
+2012-05-24 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (fmtspcl, include2, incdupe, incdup2, incdupe3): Fix
+ paths to work properly when built in another directory.
+
+2012-05-19 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (EXTRA_DIST): Add new files hello.awk, inclib.awk,
+ include.awk, include.ok, include2.ok, incdupe.ok, incdupe2.ok and
+ incdupe3.ok.
+ (GAWK_EXT_TESTS): Add include, include2, incdupe, incdupe2 and incdupe3.
+ (include2, incdupe, incdupe2, incdupe3): New tests.
+ * badargs.ok: Fix usage message to include new -i option.
+ * hello.awk, incdupe.ok, incdupe2.ok, incdupe3.ok, inclib.awk,
+ include.awk, include.ok, include2.ok: New files.
+
+2012-08-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (regexprange): New test.
+ * regexprange.awk, regexprange.ok: New files.
+
+2012-08-05 Arnold D. Robbins <arnold@skeeve.com>
+
+ New test from Nelson Beebe.
+
+ * Makefile.am (ofs1): New test.
+ * ofs1.awk, ofs1.in, ofs1.ok: New files.
+
+2012-07-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (getline5): New test.
+ * getline5.awk, getline5.ok: New files.
+
+2012-06-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (charasbytes): New test.
+ * charasbytes.awk, charasbytes.in, charasbytes.ok: New files.
+
+2012-05-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * jarebug.sh: New file. Handles Mac OS X also.
+ * Makefile.am (jarebug): Use jarebug.sh to run the test.
+
+2012-05-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (jarebug): Remove leading `-' from $(CMP) line.
+
+2012-05-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (jarebug): Move to charset tests. Adjust to check
+ for existence of needed Japanese locale before running the test.
+
+2012-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (jarebug): New test.
+ * jarebug.awk, jarebug.in, jarebug.ok: New files.
+
+2012-04-08 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (VALGRIND): Set to empty to protect against random
+ values in the environment.
+
+2012-04-08 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (EXTRA_DIST): Add missing files fork.ok, fork2.ok
+ and ordchr2.ok.
+
+2012-04-08 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (AWK, PGAWK): Include new $(VALGRIND) variable in
+ command line (now passed in by top-level Makefile).
+
+2012-04-07 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (ordchr2, readfile): Fix so "make diffout" will work
+ properly.
+ * orchr2.ok: New file.
+
+2012-04-07 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (check): Add new shlib-tests target.
+ (SHLIB_TESTS): Add tests ordchr, ordchr2, fork, fork2, readfile and
+ filefuncs.
+ * ordchr.awk, ordchr.ok, fork.awk, fork.ok, fork2.awk, fork2.ok,
+ filefuncs.awk, filefuncs.ok: New files.
+
+2012-04-01 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (valgrind-scan): Update to match modern valgrind output.
+
+2012-04-01 John Haque <j.eh@mchsi.com>
+
+ * Makefile.am (mpfr-test): Add target for manual testing of MPFR
+ and GMP numbers.
+ * mpfrbigint.awk, mpfrexprange.awk, mpfrieee.awk, mpfrnr.awk,
+ mpfrrnd.awk, mpfrsort.awk: New tests.
+ (MPFR_TESTS): Add the new tests.
+ * mpfrnr.in, mpfrbigint.ok, mpfrexprange.ok, mpfrieee.ok, mpfrnr.ok,
+ mpfrrnd.ok, mpfrsort.ok: New files.
+ (AWK): Add AWKFLAGS; useful for testing with 'gawk -M' invocation.
+
+2012-02-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * fmtspcl-mpfr.ok, fnarydel-mpfr.ok, fnparydl-mpfr.ok,
+ rand-mpfr.ok: New files.
+ * Makefile.am (EXTRA_DIST): Add them.
+ (CHECK_MPFR): New list of files that have MPFR variant .ok file.
+ * Gentests: Deal with MPFR files by modifying the generated
+ comparison command.
+
+2011-12-26 John Haque <j.eh@mchsi.com>
+
+ * badargs.ok: Adjust for new and changed command line options.
+
+2012-03-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.1: Release tar ball made.
+
+2012-03-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (printfbad3): New test.
+ * printfbad3.awk, printfbad3.ok: New files.
+
+2012-02-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (beginfile2, next): Set LC_ALL=C so that error
+ messages will be in English for comparison with .ok files.
+ Thanks to Jeroen Schot <schot@a-eskwadraat.nl>.
+
+2011-12-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (rri1): New test.
+ * rri1.awk, rri1.in, rri1.ok: New files.
+
+2011-12-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am: Rationalize the $(CMP) lines wherever possible.
+
2011-10-24 Arnold D. Robbins <arnold@skeeve.com>
* beginfile2.sh: Use `...` instead of $(...) for broken systems
diff --git a/test/Gentests b/test/Gentests
index fc779f00..5a7aaa09 100755
--- a/test/Gentests
+++ b/test/Gentests
@@ -45,6 +45,15 @@ BEGIN {
next
}
+/^CHECK_MPFR *=/,/[^\\]$/ {
+ gsub(/(^CHECK_MPFR *=|\\$)/,"")
+ for (i = 1; i <= NF; i++)
+ {
+ mpfr[$i]
+ }
+ next
+}
+
/^[[:alpha:]_][[:alnum:]_]*:/ {
# remember all targets from Makefile.am
sub(/:.*/,"")
@@ -87,13 +96,22 @@ function generate(x, s)
delete lint_old[x]
}
if (x".in" in files) {
- s = s " < $(srcdir)/$@.in"
+ 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"
+ printf "\t@echo $@\n"
+
+ if (x in mpfr) {
+ delete mpfr[x]
+ printf "\t@AWKPATH=\"$(srcdir)\" $(AWK) $(AWKFLAGS) -f $@.awk %s >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@\n", s
+ printf "\t@-if test -z \"$$AWKFLAGS\" ; then $(CMP) \"$(srcdir)\"/$@.ok _$@ && rm -f _$@ ; else \\\n"
+ printf "\t$(CMP) \"$(srcdir)\"/$@-mpfr.ok _$@ && rm -f _$@ ; \\\n"
+ printf "\tfi\n\n"
+ } else {
+ 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 {
@@ -105,7 +123,7 @@ END {
printf "WARNING: --lint-old target `%s' is missing.\n", x > "/dev/stderr"
for (x in files)
if (!(x in unused) && \
- !(gensub(/\.(awk|in)$/,"","",x) in targets))
+ !(gensub(/\.(awk|in)$/,"",1,x) in targets))
printf "WARNING: unused file `%s'.\n", x > "/dev/stderr"
}
diff --git a/test/Makefile.am b/test/Makefile.am
index 450fc35d..8f501b56 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,7 +1,7 @@
#
# test/Makefile.am --- automake input file for gawk
#
-# Copyright (C) 1988-2011 the Free Software Foundation, Inc.
+# Copyright (C) 1988-2015 the Free Software Foundation, Inc.
#
# This file is part of GAWK, the GNU implementation of the
# AWK Programming Language.
@@ -47,8 +47,6 @@ EXTRA_DIST = \
anchgsub.awk \
anchgsub.in \
anchgsub.ok \
- arraysort.awk \
- arraysort.ok \
argarray.awk \
argarray.in \
argarray.ok \
@@ -62,6 +60,8 @@ EXTRA_DIST = \
arrayprm3.ok \
arrayref.awk \
arrayref.ok \
+ arraysort.awk \
+ arraysort.ok \
arrymem1.awk \
arrymem1.ok \
arryref2.awk \
@@ -112,13 +112,29 @@ EXTRA_DIST = \
backw.awk \
backw.in \
backw.ok \
+ backbigs1.awk \
+ backbigs1.in \
+ backbigs1.ok \
+ backsmalls1.awk \
+ backsmalls1.in \
+ backsmalls1.ok \
+ backsmalls2.awk \
+ backsmalls2.ok \
badargs.ok \
+ badassign1.awk \
+ badassign1.ok \
+ badbuild.awk \
+ badbuild.in \
+ badbuild.ok \
beginfile1.awk \
beginfile1.ok \
beginfile2.in \
beginfile2.ok \
beginfile2.sh \
binmode1.ok \
+ charasbytes.awk \
+ charasbytes.in \
+ charasbytes.ok \
childin.awk \
childin.in \
childin.ok \
@@ -131,6 +147,9 @@ EXTRA_DIST = \
clsflnam.awk \
clsflnam.in \
clsflnam.ok \
+ colonwarn.awk \
+ colonwarn.in \
+ colonwarn.ok \
compare.awk \
compare.in \
compare.ok \
@@ -151,14 +170,16 @@ EXTRA_DIST = \
datanonl.awk \
datanonl.in \
datanonl.ok \
+ dbugeval.in \
+ dbugeval.ok \
defref.awk \
defref.ok \
delargv.awk \
delargv.ok \
- delarprm.awk \
- delarprm.ok \
delarpm2.awk \
delarpm2.ok \
+ delarprm.awk \
+ delarprm.ok \
delfunc.awk \
delfunc.ok \
delsub.awk \
@@ -171,6 +192,9 @@ EXTRA_DIST = \
devfd1.awk \
devfd1.ok \
devfd2.ok \
+ dfamb1.awk \
+ dfamb1.in \
+ dfamb1.ok \
dfastress.awk \
dfastress.ok \
double1.awk \
@@ -186,6 +210,8 @@ EXTRA_DIST = \
eofsplit.ok \
exit.ok \
exit.sh \
+ exit2.awk \
+ exit2.ok \
exitval1.awk \
exitval1.ok \
exitval2.awk \
@@ -194,19 +220,22 @@ EXTRA_DIST = \
fcall_exit.awk \
fcall_exit.ok \
fcall_exit2.awk \
- fcall_exit2.ok \
fcall_exit2.in \
+ fcall_exit2.ok \
fflush.ok \
fflush.sh \
fieldwdth.awk \
fieldwdth.in \
fieldwdth.ok \
+ filefuncs.awk \
+ filefuncs.ok \
fldchg.awk \
fldchg.in \
fldchg.ok \
fldchgnf.awk \
fldchgnf.in \
fldchgnf.ok \
+ fmtspcl-mpfr.ok \
fmtspcl.awk \
fmtspcl.tok \
fmttest.awk \
@@ -219,6 +248,7 @@ EXTRA_DIST = \
fnarray2.awk \
fnarray2.in \
fnarray2.ok \
+ fnarydel-mpfr.ok \
fnarydel.awk \
fnarydel.ok \
fnaryscl.awk \
@@ -226,10 +256,23 @@ EXTRA_DIST = \
fnasgnm.awk \
fnasgnm.in \
fnasgnm.ok \
+ fnmatch.awk \
+ fnmatch.ok \
fnmisc.awk \
fnmisc.ok \
+ fnparydl-mpfr.ok \
fnparydl.awk \
fnparydl.ok \
+ fordel.awk \
+ fordel.ok \
+ fork.awk \
+ fork.ok \
+ fork2.awk \
+ fork2.ok \
+ forref.awk \
+ forref.ok \
+ forsimp.awk \
+ forsimp.ok \
fpat1.awk \
fpat1.in \
fpat1.ok \
@@ -241,12 +284,6 @@ EXTRA_DIST = \
fpatnull.awk \
fpatnull.in \
fpatnull.ok \
- fordel.awk \
- fordel.ok \
- forref.awk \
- forref.ok \
- forsimp.awk \
- forsimp.ok \
fsbs.awk \
fsbs.in \
fsbs.ok \
@@ -262,6 +299,15 @@ EXTRA_DIST = \
fstabplus.awk \
fstabplus.in \
fstabplus.ok \
+ fts.awk \
+ functab1.awk \
+ functab1.ok \
+ functab2.awk \
+ functab2.ok \
+ functab3.awk \
+ functab3.ok \
+ functab4.awk \
+ functab4.ok \
funlen.awk \
funlen.in \
funlen.ok \
@@ -281,6 +327,8 @@ EXTRA_DIST = \
fwtest3.awk \
fwtest3.in \
fwtest3.ok \
+ genpot.awk \
+ genpot.ok \
gensub.awk \
gensub.in \
gensub.ok \
@@ -296,6 +344,8 @@ EXTRA_DIST = \
getline4.awk \
getline4.in \
getline4.ok \
+ getline5.awk \
+ getline5.ok \
getlnbuf.awk \
getlnbuf.in \
getlnbuf.ok \
@@ -338,6 +388,7 @@ EXTRA_DIST = \
gsubtst8.in \
gsubtst8.ok \
gtlnbufv.awk \
+ hello.awk \
hex.awk \
hex.ok \
hsprint.awk \
@@ -347,22 +398,54 @@ EXTRA_DIST = \
icasers.awk \
icasers.in \
icasers.ok \
+ id.awk \
+ id.ok \
igncdym.awk \
igncdym.in \
igncdym.ok \
igncfs.awk \
igncfs.in \
igncfs.ok \
+ ignrcas2.awk \
+ ignrcas2.ok \
ignrcase.awk \
ignrcase.in \
ignrcase.ok \
- ignrcas2.awk \
- ignrcas2.ok \
+ incdupe.ok \
+ incdupe2.ok \
+ incdupe3.ok \
+ incdupe4.ok \
+ incdupe5.ok \
+ incdupe6.ok \
+ incdupe7.ok \
+ inchello.awk \
+ inclib.awk \
+ include.awk \
+ include.ok \
+ include2.ok \
indirectcall.awk \
indirectcall.in \
indirectcall.ok \
+ indirectcall2.awk \
+ indirectcall2.ok \
inftest.awk \
inftest.ok \
+ inplace.in \
+ inplace.1.in \
+ inplace.2.in \
+ inplace1.ok \
+ inplace1.1.ok \
+ inplace1.2.ok \
+ inplace2.ok \
+ inplace2.1.ok \
+ inplace2.1.bak.ok \
+ inplace2.2.ok \
+ inplace2.2.bak.ok \
+ inplace3.ok \
+ inplace3.1.ok \
+ inplace3.1.bak.ok \
+ inplace3.2.ok \
+ inplace3.2.bak.ok \
inputred.awk \
inputred.ok \
intest.awk \
@@ -373,6 +456,10 @@ EXTRA_DIST = \
intprec.ok \
iobug1.awk \
iobug1.ok \
+ jarebug.awk \
+ jarebug.in \
+ jarebug.ok \
+ jarebug.sh \
lc_num1.awk \
lc_num1.ok \
leaddig.awk \
@@ -398,8 +485,8 @@ EXTRA_DIST = \
longsub.in \
longsub.ok \
longwrds.awk \
- longwrds.ok \
longwrds.in \
+ longwrds.ok \
manglprm.awk \
manglprm.in \
manglprm.ok \
@@ -425,6 +512,9 @@ EXTRA_DIST = \
mbprintf3.awk \
mbprintf3.in \
mbprintf3.ok \
+ mbprintf4.awk \
+ mbprintf4.in \
+ mbprintf4.ok \
mbstr1.awk \
mbstr1.ok \
membug1.awk \
@@ -435,6 +525,25 @@ EXTRA_DIST = \
minusstr.ok \
mixed1.ok \
mmap8k.in \
+ mpfrbigint.awk \
+ mpfrbigint.ok \
+ mpfrexprange.awk \
+ mpfrexprange.ok \
+ mpfrieee.awk \
+ mpfrieee.ok \
+ mpfrnegzero.awk \
+ mpfrnegzero.ok \
+ mpfrnr.awk \
+ mpfrnr.in \
+ mpfrnr.ok \
+ mpfrrem.awk \
+ mpfrrem.ok \
+ mpfrrnd.awk \
+ mpfrrnd.ok \
+ mpfrsort.awk \
+ mpfrsort.ok \
+ mpfrsqrt.awk \
+ mpfrsqrt.ok \
mtchi18n.awk \
mtchi18n.in \
mtchi18n.ok \
@@ -456,6 +565,8 @@ EXTRA_DIST = \
nfldstr.awk \
nfldstr.in \
nfldstr.ok \
+ nfloop.awk \
+ nfloop.ok \
nfneg.awk \
nfneg.ok \
nfset.awk \
@@ -515,6 +626,9 @@ EXTRA_DIST = \
ofmts.awk \
ofmts.in \
ofmts.ok \
+ ofs1.awk \
+ ofs1.in \
+ ofs1.ok \
onlynl.awk \
onlynl.in \
onlynl.ok \
@@ -522,6 +636,9 @@ EXTRA_DIST = \
opasnidx.ok \
opasnslf.awk \
opasnslf.ok \
+ ordchr.awk \
+ ordchr.ok \
+ ordchr2.ok \
out1.ok \
out2.ok \
out3.ok \
@@ -531,6 +648,8 @@ EXTRA_DIST = \
paramres.ok \
paramtyp.awk \
paramtyp.ok \
+ paramuninitglobal.awk \
+ paramuninitglobal.ok \
parse1.awk \
parse1.in \
parse1.ok \
@@ -560,9 +679,6 @@ EXTRA_DIST = \
prdupval.awk \
prdupval.in \
prdupval.ok \
- profile2.ok \
- profile3.awk \
- profile3.ok \
prec.awk \
prec.ok \
printf0.awk \
@@ -574,7 +690,13 @@ EXTRA_DIST = \
printfbad2.awk \
printfbad2.in \
printfbad2.ok \
+ printfbad3.awk \
+ printfbad3.ok \
+ printfbad4.awk \
+ printfbad4.ok \
printfloat.awk \
+ printhuge.awk \
+ printhuge.ok \
printlang.awk \
prmarscl.awk \
prmarscl.ok \
@@ -582,35 +704,66 @@ EXTRA_DIST = \
prmreuse.ok \
procinfs.awk \
procinfs.ok \
+ profile2.ok \
+ profile3.awk \
+ profile3.ok \
+ profile4.awk \
+ profile4.ok \
+ profile5.awk \
+ profile5.ok \
+ profile6.awk \
+ profile6.ok \
+ profile7.awk \
+ profile7.ok \
+ profile8.awk \
+ profile8.ok \
prt1eval.awk \
prt1eval.ok \
prtoeval.awk \
prtoeval.ok \
pty1.awk \
pty1.ok \
+ rand-mpfr.ok \
rand.awk \
rand.ok \
+ randtest.sh \
+ randtest.ok \
range1.awk \
range1.in \
range1.ok \
+ readdir.awk \
+ readdir0.awk \
+ readfile2.awk \
+ readfile2.ok \
rebt8b1.awk \
rebt8b1.ok \
rebt8b2.awk \
rebt8b2.ok \
+ rebuf.awk \
+ rebuf.in \
+ rebuf.ok \
redfilnm.awk \
redfilnm.in \
redfilnm.ok \
regeq.awk \
regeq.in \
regeq.ok \
+ regexpbrack.awk \
+ regexpbrack.in \
+ regexpbrack.ok \
+ regexprange.awk \
+ regexprange.ok \
+ reginttrad.awk \
+ reginttrad.ok \
+ regnul1.awk \
+ regnul1.ok \
+ regnul2.awk \
+ regnul2.ok \
regrange.awk \
regrange.ok \
regtest.sh \
regx8bit.awk \
regx8bit.ok \
- rebuf.awk \
- rebuf.in \
- rebuf.ok \
reindops.awk \
reindops.in \
reindops.ok \
@@ -626,9 +779,20 @@ EXTRA_DIST = \
resplit.awk \
resplit.in \
resplit.ok \
+ revout.awk \
+ revout.ok \
+ revtwoway.awk \
+ revtwoway.ok \
+ rri1.awk \
+ rri1.in \
+ rri1.ok \
rs.awk \
rs.in \
rs.ok \
+ rsgetline.awk \
+ rsgetline.in \
+ rsgetline.ok \
+ rsglstdin.ok \
rsnul1nl.awk \
rsnul1nl.in \
rsnul1nl.ok \
@@ -658,8 +822,12 @@ EXTRA_DIST = \
rswhite.ok \
rtlen.ok \
rtlen.sh \
+ rtlenmb.ok \
rtlen01.ok \
rtlen01.sh \
+ rwarray.awk \
+ rwarray.in \
+ rwarray.ok \
scalar.awk \
scalar.ok \
sclforin.awk \
@@ -675,9 +843,15 @@ EXTRA_DIST = \
sortfor.awk \
sortfor.in \
sortfor.ok \
+ sortglos.awk \
+ sortglos.in \
+ sortglos.ok \
sortu.awk \
sortu.ok \
space.ok \
+ split_after_fpat.awk \
+ split_after_fpat.in \
+ split_after_fpat.ok \
splitarg4.awk \
splitarg4.in \
splitarg4.ok \
@@ -698,16 +872,16 @@ EXTRA_DIST = \
sprintfc.ok \
strcat1.awk \
strcat1.ok \
+ strftime.awk \
+ strftlng.awk \
+ strftlng.ok \
+ strnum1.awk \
+ strnum1.ok \
strtod.awk \
strtod.in \
strtod.ok \
- strnum1.awk \
- strnum1.ok \
strtonum.awk \
strtonum.ok \
- strftime.awk \
- strftlng.awk \
- strftlng.ok \
subamp.awk \
subamp.in \
subamp.ok \
@@ -724,10 +898,35 @@ EXTRA_DIST = \
swaplns.ok \
switch2.awk \
switch2.ok \
+ symtab1.awk \
+ symtab1.ok \
+ symtab2.awk \
+ symtab2.ok \
+ symtab3.awk \
+ symtab3.ok \
+ symtab4.awk \
+ symtab4.in \
+ symtab4.ok \
+ symtab5.awk \
+ symtab5.in \
+ symtab5.ok \
+ symtab6.awk \
+ symtab6.ok \
+ symtab7.awk \
+ symtab7.in \
+ symtab7.ok \
+ symtab8.awk \
+ symtab8.in \
+ symtab8.ok \
+ symtab9.awk \
+ symtab9.ok \
synerr1.awk \
synerr1.ok \
synerr2.awk \
synerr2.ok \
+ testext.ok \
+ time.awk \
+ time.ok \
tradanch.awk \
tradanch.in \
tradanch.ok \
@@ -775,62 +974,75 @@ EXTRA_DIST = \
zeroflag.awk \
zeroflag.ok
+
TESTS_WE_ARE_NOT_DOING_YET_FIXME_ONE_DAY = longdbl
# Get rid of core files when cleaning and generated .ok file
CLEANFILES = core core.* fmtspcl.ok
-# try to keep these sorted
+# try to keep these sorted. each letter starts a new line
BASIC_TESTS = \
addcomma anchgsub argarray arrayparm arrayprm2 arrayprm3 \
arrayref arrymem1 arryref2 arryref3 arryref4 arryref5 arynasty \
arynocls aryprm1 aryprm2 aryprm3 aryprm4 aryprm5 aryprm6 aryprm7 \
- aryprm8 arysubnm asgext awkpath back89 backgsub childin clobber \
- closebad clsflnam compare compare2 concat1 concat2 concat3 \
- concat4 convfmt datanonl defref delargv delarpm2 delarprm delfunc \
- dfastress dynlj eofsplit exitval1 exitval2 fcall_exit fcall_exit2 \
- fldchg fldchgnf fnamedat fnarray fnarray2 fnaryscl fnasgnm fnmisc \
- fordel forref forsimp fsbs fsrs fsspcoln fstabplus funsemnl funsmnam \
- funstack getline getline2 getline3 getline4 \
- getlnbuf getnr2tb getnr2tm \
+ aryprm8 arysubnm asgext awkpath \
+ back89 backgsub badassign1 badbuild \
+ childin clobber closebad clsflnam compare compare2 concat1 concat2 \
+ concat3 concat4 convfmt \
+ datanonl defref delargv delarpm2 delarprm delfunc dfamb1 dfastress dynlj \
+ eofsplit exit2 exitval1 exitval2 \
+ fcall_exit fcall_exit2 fldchg fldchgnf fnamedat fnarray fnarray2 \
+ fnaryscl fnasgnm fnmisc fordel forref forsimp fsbs fsrs fsspcoln \
+ fstabplus funsemnl funsmnam funstack \
+ getline getline2 getline3 getline4 getline5 getlnbuf getnr2tb getnr2tm \
gsubasgn gsubtest gsubtst2 gsubtst3 gsubtst4 gsubtst5 gsubtst6 \
gsubtst7 gsubtst8 \
- hex hsprint inputred intest intprec iobug1 leaddig leadnl litoct \
- longsub longwrds manglprm math membug1 messages minusstr mmap8k \
- mtchi18n nasty nasty2 negexp negrange nested nfldstr nfneg \
- nfset nlfldsep nlinstr nlstrina noeffect nofile nofmtch noloop1 \
- noloop2 nonl noparms nors nulrsend numindex numsubstr octsub ofmt \
- ofmta ofmtbig ofmtfidl ofmts onlynl opasnidx opasnslf paramdup \
- paramres paramtyp parse1 parsefld parseme pcntplus posix2008sub \
- prdupval prec printf0 printf1 prmarscl prmreuse prt1eval prtoeval \
- rand range1 rebt8b1 redfilnm regeq regrange reindops reparse resplit \
- rs rsnul1nl rsnulbig rsnulbig2 rstest1 rstest2 rstest3 rstest4 \
- rstest5 rswhite scalar sclforin sclifin sortempty splitargv \
- splitarr splitdef splitvar splitwht strcat1 strnum1 strtod subamp \
- subi18n subsepnm subslash substr swaplns synerr1 synerr2 tradanch \
- tweakfld uninit2 uninit3 uninit4 uninit5 uninitialized unterm \
- uparrfs wideidx wideidx2 widesub widesub2 widesub3 widesub4 \
- wjposer1 zero2 zeroe0 zeroflag
+ hex hsprint \
+ inputred intest intprec iobug1 \
+ leaddig leadnl litoct longsub longwrds \
+ manglprm math membug1 messages minusstr mmap8k mtchi18n \
+ nasty nasty2 negexp negrange nested nfldstr nfloop nfneg nfset nlfldsep \
+ nlinstr nlstrina noeffect nofile nofmtch noloop1 noloop2 nonl \
+ noparms nors nulrsend numindex numsubstr \
+ octsub ofmt ofmta ofmtbig ofmtfidl ofmts ofs1 onlynl opasnidx opasnslf \
+ paramdup paramres paramtyp paramuninitglobal parse1 parsefld parseme \
+ pcntplus posix2008sub prdupval prec printf0 printf1 prmarscl prmreuse \
+ prt1eval prtoeval \
+ rand randtest range1 rebt8b1 redfilnm regeq regexpbrack regexprange regrange reindops \
+ reparse resplit rri1 rs rsnul1nl rsnulbig rsnulbig2 rstest1 rstest2 \
+ rstest3 rstest4 rstest5 rswhite \
+ scalar sclforin sclifin sortempty sortglos splitargv splitarr splitdef \
+ splitvar splitwht strcat1 strnum1 strtod subamp subi18n \
+ subsepnm subslash substr swaplns synerr1 synerr2 tradanch tweakfld \
+ uninit2 uninit3 uninit4 uninit5 uninitialized unterm uparrfs \
+ wideidx wideidx2 widesub widesub2 widesub3 widesub4 wjposer1 \
+ zero2 zeroe0 zeroflag
UNIX_TESTS = \
- fflush getlnhd localenl pid pipeio1 pipeio2 poundbang rtlen rtlen01 \
- space strftlng
+ fflush getlnhd localenl pid pipeio1 pipeio2 poundbang \
+ rtlen rtlen01 space strftlng
GAWK_EXT_TESTS = \
aadelete1 aadelete2 aarray1 aasort aasorti argtest arraysort \
- backw badargs beginfile1 beginfile2 \
- binmode1 clos1way delsub devfd devfd1 \
- devfd2 dumpvars exit fieldwdth fpat1 fpat2 fpat3 \
- fpatnull fsfwfs funlen \
- fwtest fwtest2 fwtest3 \
- gensub gensub2 getlndir gnuops2 gnuops3 gnureops \
- icasefs icasers igncdym igncfs ignrcas2 ignrcase indirectcall lint \
- lintold lintwarn manyfiles match1 match2 match3 mbstr1 nastyparm \
- next nondec nondec2 patsplit posix printfbad1 printfbad2 procinfs \
- profile1 profile2 profile3 pty1 \
- rebuf regx8bit reint reint2 rsstart1 \
- rsstart2 rsstart3 rstest6 shadow sortfor sortu splitarg4 strftime \
- strtonum switch2
+ backw badargs beginfile1 beginfile2 binmode1 charasbytes \
+ colonwarn clos1way dbugeval delsub devfd devfd1 devfd2 dumpvars exit \
+ fieldwdth fpat1 fpat2 fpat3 fpatnull fsfwfs funlen \
+ functab1 functab2 functab3 fwtest fwtest2 fwtest3 \
+ genpot gensub gensub2 getlndir gnuops2 gnuops3 gnureops \
+ icasefs icasers id igncdym igncfs ignrcas2 ignrcase \
+ incdupe incdupe2 incdupe3 incdupe4 incdupe5 incdupe6 incdupe7 \
+ include include2 indirectcall indirectcall2 \
+ lint lintold lintwarn \
+ manyfiles match1 match2 match3 mbstr1 \
+ nastyparm next nondec nondec2 \
+ patsplit posix printfbad1 printfbad2 printfbad3 printfbad4 printhuge procinfs \
+ profile1 profile2 profile3 profile4 profile5 profile6 profile7 \
+ profile8 pty1 \
+ rebuf regnul1 regnul2 regx8bit reginttrad reint reint2 rsgetline rsglstdin rsstart1 \
+ rsstart2 rsstart3 rstest6 shadow sortfor sortu split_after_fpat \
+ splitarg4 strftime \
+ strtonum switch2 symtab1 symtab2 symtab3 symtab4 symtab5 symtab6 \
+ symtab7 symtab8 symtab9
EXTRA_TESTS = inftest regtest
@@ -838,9 +1050,17 @@ INET_TESTS = inetdayu inetdayt inetechu inetecht
MACHINE_TESTS = double1 double2 fmtspcl intformat
+MPFR_TESTS = mpfrnr mpfrnegzero mpfrrem mpfrrnd mpfrieee mpfrexprange \
+ mpfrsort mpfrsqrt mpfrbigint
+
LOCALE_CHARSET_TESTS = \
- asort asorti fmttest fnarydel fnparydl lc_num1 mbfw1 \
- mbprintf1 mbprintf2 mbprintf3 rebt8b2 rtlenmb sort1 sprintfc
+ asort asorti backbigs1 backsmalls1 backsmalls2 \
+ fmttest fnarydel fnparydl jarebug lc_num1 mbfw1 \
+ mbprintf1 mbprintf2 mbprintf3 mbprintf4 rebt8b2 rtlenmb sort1 sprintfc
+
+SHLIB_TESTS = \
+ fnmatch filefuncs fork fork2 fts functab4 inplace1 inplace2 inplace3 \
+ ordchr ordchr2 readdir readfile readfile2 revout revtwoway rwarray testext time
# List of the tests which should be run with --lint option:
NEED_LINT = \
@@ -854,20 +1074,32 @@ NEED_LINT_OLD = lintold
FAIL_CODE1 = \
fnarray2 fnmisc gsubasgn mixed1 noparms paramdup synerr1 synerr2 unterm
+# List of files which have .ok versions for MPFR
+CHECK_MPFR = \
+ rand fnarydel fnparydl
+
# List of the files that appear in manual tests or are for reserve testing:
-GENTESTS_UNUSED = Makefile.in gtlnbufv.awk printfloat.awk
+GENTESTS_UNUSED = Makefile.in dtdgport.awk gtlnbufv.awk hello.awk \
+ inchello.awk inclib.awk inplace.1.in inplace.2.in inplace.in \
+ longdbl.awk longdbl.in printfloat.awk readdir0.awk xref.awk
CMP = cmp
AWKPROG = ../gawk$(EXEEXT)
-PGAWKPROG = ../pgawk$(EXEEXT)
+
+# Default for VALGRIND is empty unless overridden by a command-line argument.
+# This protects against cruft in the environment.
+VALGRIND =
# 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)
-PGAWK = LC_ALL=$${GAWKLOCALE:-C} LANG=$${GAWKLOCALE:-C} $(PGAWKPROG)
+
+#
+# And we set AWKLIBPATH to find the extension libraries we built.
+LOCALES = LC_ALL=$${GAWKLOCALE:-C} LANG=$${GAWKLOCALE:-C}
+AWK = $(LOCALES) AWKLIBPATH=../extension/.libs $(VALGRIND) $(AWKPROG)
# Message stuff is to make it a little easier to follow.
# Make the pass-fail last and dependent on others to avoid
@@ -878,8 +1110,10 @@ check: msg \
unix-msg-start unix-tests unix-msg-end \
extend-msg-start gawk-extensions extend-msg-end \
machine-msg-start machine-tests machine-msg-end \
- charset-msg-start charset-tests charset-msg-end
- @$(MAKE) pass-fail
+ charset-msg-start charset-tests charset-msg-end \
+ shlib-msg-start shlib-tests shlib-msg-end \
+ mpfr-msg-start mpfr-tests mpfr-msg-end
+ @$(MAKE) pass-fail || { $(MAKE) diffout; exit 1; }
basic: $(BASIC_TESTS)
@@ -895,6 +1129,24 @@ inet: inetmesg $(INET_TESTS)
machine-tests: $(MACHINE_TESTS)
+# The blank between ' and /MPFR/ is for running tests on Windows under
+# MSYS, which thinks /MPFR is a Unix-style file name and converts it
+# to Windows format, butchering it in the process. Likewise for /API/
+# in the next shlib-tests.
+mpfr-tests:
+ @if $(AWK) --version | $(AWK) ' /MPFR/ { exit 1 }' ; then \
+ echo MPFR tests not supported on this system ; \
+ else $(MAKE) $(MPFR_TESTS) ; \
+ fi
+
+shlib-tests:
+ @if $(AWK) --version | $(AWK) ' /API/ { exit 1 }' ; then \
+ echo shlib tests not supported on this system ; \
+ else $(MAKE) shlib-real-tests ; \
+ fi
+
+shlib-real-tests: $(SHLIB_TESTS)
+
msg::
@echo ''
@echo 'Any output from "cmp" is bad news, although some differences'
@@ -903,7 +1155,7 @@ msg::
@echo 'precision may lead to slightly different output in a few cases.'
printlang::
- @$(AWK) -f $(srcdir)/printlang.awk
+ @$(AWK) -f "$(srcdir)"/printlang.awk
basic-msg-start:
@echo "======== Starting basic tests ========"
@@ -931,16 +1183,34 @@ machine-msg-end:
charset-msg-start:
@echo "======== Starting tests that can vary based on character set or locale support ========"
+ @echo "************************************************"
+ @echo "** Some or all of these tests may fail if you **"
+ @echo "** have inadequate or missing locale support **"
+ @echo "** At least en_US.UTF-8, ru_RU.UTF-8 and **"
+ @echo "** ja_JP.UTF-8 are needed. **"
+ @echo "************************************************"
charset-msg-end:
@echo "======== Done with tests that can vary based on character set or locale support ========"
+shlib-msg-start:
+ @echo "======== Starting shared library tests ========"
+
+shlib-msg-end:
+ @echo "======== Done with shared library tests ========"
+
+mpfr-msg-start:
+ @echo "======== Starting MPFR tests ========"
+
+mpfr-msg-end:
+ @echo "======== Done with MPFR tests ========"
+
lc_num1:
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
# This test is a PITA because increasingly, /tmp is getting
@@ -950,186 +1220,197 @@ lc_num1:
# so this can still fail
poundbang::
@echo $@
- @sed "s;/tmp/gawk;`pwd`/$(AWKPROG);" < $(srcdir)/poundbang.awk > ./_pbd.awk
+ @sed "s;/tmp/gawk;`pwd`/$(AWKPROG);" < "$(srcdir)"/poundbang.awk > ./_pbd.awk
@chmod +x ./_pbd.awk
- @if ./_pbd.awk $(srcdir)/poundbang.awk > _`basename $@` ; \
+ @if ./_pbd.awk "$(srcdir)"/poundbang.awk > _`basename $@` ; \
then : ; \
else \
- sed "s;/tmp/gawk;../$(AWKPROG);" < $(srcdir)/poundbang.awk > ./_pbd.awk ; \
+ 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 $@`; \
+ LC_ALL=$${GAWKLOCALE:-C} LANG=$${GAWKLOCALE:-C} ./_pbd.awk "$(srcdir)"/poundbang.awk > _`basename $@`; \
fi
- @-$(CMP) $(srcdir)/poundbang.awk _`basename $@` && rm -f _`basename $@` _pbd.awk
+ @-$(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
+ @$(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 \
+ @case "$(srcdir)" in \
.) : ;; \
- *) cp $(srcdir)/argarray.in . ;; \
+ *) cp "$(srcdir)"/argarray.in . ;; \
esac
- @TEST=test echo just a test | $(AWK) -f $(srcdir)/argarray.awk ./argarray.in - >_$@
- @case $(srcdir) in \
+ @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 _$@
+ @-$(CMP) "$(srcdir)"/$@.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=$(AWKPROG) $(srcdir)/regtest.sh
+ AWK=$(AWKPROG) "$(srcdir)"/regtest.sh
manyfiles::
@echo manyfiles
@rm -rf junk
@mkdir junk
@$(AWK) 'BEGIN { for (i = 1; i <= 1030; i++) print i, i}' >_$@
- @$(AWK) -f $(srcdir)/manyfiles.awk _$@ _$@
+ @$(AWK) -f "$(srcdir)"/manyfiles.awk _$@ _$@
@wc -l junk/* | $(AWK) '$$1 != 2' | wc -l | sed "s/ *//g" > _$@
- @rm -rf junk ; $(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @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 _$@
+ @$(AWK) -f "$(srcdir)"/compare.awk 0 1 "$(srcdir)"/compare.in >_$@
+ @-$(CMP) "$(srcdir)"/$@.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 _$@
+ @$(AWK) -f "$(srcdir)"/inftest.awk | sed "s/inf/Inf/g" >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
getline2::
@echo $@
- @$(AWK) -f $(srcdir)/getline2.awk $(srcdir)/getline2.awk $(srcdir)/getline2.awk >_$@
- @-$(CMP) $(srcdir)/getline2.ok _$@ && rm -f _$@
+ @$(AWK) -f "$(srcdir)"/getline2.awk "$(srcdir)"/getline2.awk "$(srcdir)"/getline2.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
awkpath::
@echo $@
@AWKPATH="$(srcdir)$(PATH_SEPARATOR)$(srcdir)/lib" $(AWK) -f awkpath.awk >_$@
- @-$(CMP) $(srcdir)/awkpath.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
argtest::
@echo $@
- @$(AWK) -f $(srcdir)/argtest.awk -x -y abc >_$@
- @-$(CMP) $(srcdir)/argtest.ok _$@ && rm -f _$@
+ @$(AWK) -f "$(srcdir)"/argtest.awk -x -y abc >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
badargs::
@echo $@
@-$(AWK) -f 2>&1 | grep -v patchlevel >_$@
- @-$(CMP) $(srcdir)/badargs.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
nonl::
@echo $@
- @-AWKPATH=$(srcdir) $(AWK) --lint -f nonl.awk /dev/null >_$@ 2>&1
- @-$(CMP) $(srcdir)/nonl.ok _$@ && rm -f _$@
+ @-AWKPATH="$(srcdir)" $(AWK) --lint -f nonl.awk /dev/null >_$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.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
+ $(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 _$@
+ @echo ab | $(AWK) --traditional -f "$(srcdir)"/litoct.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
devfd::
@echo $@
- @$(AWK) 1 /dev/fd/4 /dev/fd/5 4<$(srcdir)/devfd.in4 5<$(srcdir)/devfd.in5 >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(AWK) 1 /dev/fd/4 /dev/fd/5 4<"$(srcdir)"/devfd.in4 5<"$(srcdir)"/devfd.in5 >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fflush::
@echo $@
- @$(srcdir)/fflush.sh >_$@
- @-$(CMP) $(srcdir)/fflush.ok _$@ && rm -f _$@
+ @"$(srcdir)"/fflush.sh >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
tweakfld::
@echo $@
- @$(AWK) -f $(srcdir)/tweakfld.awk $(srcdir)/tweakfld.in >_$@
+ @$(AWK) -f "$(srcdir)"/tweakfld.awk "$(srcdir)"/tweakfld.in >_$@
@rm -f errors.cleanup
- @-$(CMP) $(srcdir)/tweakfld.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mmap8k::
@echo $@
- @$(AWK) '{ print }' $(srcdir)/mmap8k.in >_$@
- @-$(CMP) $(srcdir)/mmap8k.in _$@ && rm -f _$@
+ @$(AWK) '{ print }' "$(srcdir)"/mmap8k.in >_$@
+ @-$(CMP) "$(srcdir)"/mmap8k.in _$@ && rm -f _$@ || cp "$(srcdir)"/$@.in $@.ok
tradanch::
@echo $@
- @$(AWK) --traditional -f $(srcdir)/tradanch.awk $(srcdir)/tradanch.in >_$@
- @-$(CMP) $(srcdir)/tradanch.ok _$@ && rm -f _$@
+ @$(AWK) --traditional -f "$(srcdir)"/tradanch.awk "$(srcdir)"/tradanch.in >_$@
+ @-$(CMP) "$(srcdir)"/$@.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 $@`
+ @AWKPATH="$(srcdir)" AWK=$(AWKPROG) $(SHELL) "$(srcdir)"/pid.sh $$$$ > _`basename $@` ; :
+ @-$(CMP) "$(srcdir)"/pid.ok _`basename $@` && rm -f _`basename $@`
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 >_$@ ; \
+ @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 _$@
+ @-$(CMP) "$(srcdir)"/$@.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 _$@
+ @echo A B C D E | tr -d '\12\15' | $(AWK) '{ print $$NF }' - "$(srcdir)"/nors.in > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fmtspcl.ok: fmtspcl.tok Makefile
- @$(AWK) -v "sd=$(srcdir)" 'BEGIN {pnan = sprintf("%g",sqrt(-1)); nnan = sprintf("%g",-sqrt(-1)); pinf = sprintf("%g",-log(0)); ninf = sprintf("%g",log(0))} {sub(/positive_nan/,pnan); sub(/negative_nan/,nnan); sub(/positive_infinity/,pinf); sub(/negative_infinity/,ninf); sub(/fmtspcl/,(sd"/fmtspcl")); print}' < $(srcdir)/fmtspcl.tok > $@ 2>/dev/null
+ @$(AWK) -v "sd=$(srcdir)" 'BEGIN {pnan = sprintf("%g",sqrt(-1)); nnan = sprintf("%g",-sqrt(-1)); pinf = sprintf("%g",-log(0)); ninf = sprintf("%g",log(0))} {sub(/positive_nan/,pnan); sub(/negative_nan/,nnan); sub(/positive_infinity/,pinf); sub(/negative_infinity/,ninf); sub(/fmtspcl/,(sd"/fmtspcl")); print}' < "$(srcdir)"/fmtspcl.tok > $@ 2>/dev/null
fmtspcl: fmtspcl.ok
- @echo fmtspcl
- @$(AWK) -f $(srcdir)/fmtspcl.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $@.ok _$@ && rm -f _$@
+ @echo $@
+ @$(AWK) $(AWKFLAGS) -f "$(srcdir)"/fmtspcl.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-if test -z "$$AWKFLAGS" ; then $(CMP) $@.ok _$@ && rm -f _$@ ; else \
+ $(CMP) "$(srcdir)"/$@-mpfr.ok _$@ && rm -f _$@ ; \
+ fi
+
+rebuf::
+ @echo $@
+ @AWKBUFSIZE=4096 AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+rsglstdin::
+ @echo $@
+ @cat "$(srcdir)"/rsgetline.in | AWKPATH="$(srcdir)" $(AWK) -f rsgetline.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
reint::
@echo $@
- @$(AWK) --re-interval -f $(srcdir)/reint.awk $(srcdir)/reint.in >_$@
- @-$(CMP) $(srcdir)/reint.ok _$@ && rm -f _$@
+ @$(AWK) --re-interval -f "$(srcdir)"/reint.awk "$(srcdir)"/reint.in >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
pipeio1::
@echo $@
- @$(AWK) -f $(srcdir)/pipeio1.awk >_$@
+ @$(AWK) -f "$(srcdir)"/pipeio1.awk >_$@
@rm -f test1 test2
- @-$(CMP) $(srcdir)/pipeio1.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
pipeio2::
@echo $@
- @$(AWK) -v SRCDIR=$(srcdir) -f $(srcdir)/pipeio2.awk >_$@
- @-$(CMP) $(srcdir)/pipeio2.ok _$@ && rm -f _$@
+ @$(AWK) -v SRCDIR="$(srcdir)" -f "$(srcdir)"/pipeio2.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
clobber::
@echo $@
- @$(AWK) -f $(srcdir)/clobber.awk >_$@
- @-$(CMP) $(srcdir)/clobber.ok seq && $(CMP) $(srcdir)/clobber.ok _$@ && rm -f _$@
+ @$(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 _$@
+ @-AWKPATH="$(srcdir)" $(AWK) -v INPUT="$(srcdir)"/arynocls.in -f arynocls.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.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$@
+ @-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
@@ -1156,28 +1437,28 @@ inetdayt::
redfilnm::
@echo $@
- @$(AWK) -f $(srcdir)/redfilnm.awk srcdir=$(srcdir) $(srcdir)/redfilnm.in >_$@
- @-$(CMP) $(srcdir)/redfilnm.ok _$@ && rm -f _$@
+ @$(AWK) -f "$(srcdir)"/redfilnm.awk srcdir="$(srcdir)" "$(srcdir)"/redfilnm.in >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
leaddig::
@echo $@
- @$(AWK) -v x=2E -f $(srcdir)/leaddig.awk >_$@
- @-$(CMP) $(srcdir)/leaddig.ok _$@ && rm -f _$@
+ @$(AWK) -v x=2E -f "$(srcdir)"/leaddig.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
gsubtst3::
@echo $@
- @$(AWK) --re-interval -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(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 _$@
+ @$(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 _$@
+ @$(AWK) --posix -f "$(srcdir)"/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
rsnulbig::
@echo $@
@@ -1185,7 +1466,7 @@ rsnulbig::
@$(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 _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
rsnulbig2::
@echo $@
@@ -1193,274 +1474,584 @@ rsnulbig2::
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 _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
wideidx::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
wideidx2::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
widesub::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
widesub2::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
widesub3::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
widesub4::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(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 _$@
+ @GAWKLOCALE=en_US.UTF-8 ; 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 _$@
+ $(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 _$@
+ @$(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 _$@
+ @$(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 _$@
+ @$(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 _$@
+ @$(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 _$@
+ @head "$(srcdir)"/rsstart1.in | $(AWK) -f "$(srcdir)"/rsstart2.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
rtlen::
@echo $@
- @$(srcdir)/$@.sh >_$@ || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @"$(srcdir)"/$@.sh >_$@ || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
rtlen01::
@echo $@
- @$(srcdir)/$@.sh >_$@ || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @"$(srcdir)"/$@.sh >_$@ || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
rtlenmb::
@echo $@
@GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
- $(srcdir)/rtlen.sh >_$@ || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/rtlen.ok _$@ && rm -f _$@
+ "$(srcdir)"/rtlen.sh >_$@ || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
nondec2::
@echo $@
- @$(AWK) --non-decimal-data -v a=0x1 -f $(srcdir)/$@.awk >_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(AWK) --non-decimal-data -v a=0x1 -f "$(srcdir)"/$@.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
nofile::
@echo $@
@$(AWK) '{}' no/such/file >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
binmode1::
@echo $@
@$(AWK) -v BINMODE=3 'BEGIN { print BINMODE }' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
subi18n::
@echo $@
- @GAWKLOCALE=en_US.UTF-8 ; $(AWK) -f $(srcdir)/$@.awk > _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @GAWKLOCALE=en_US.UTF-8 ; $(AWK) -f "$(srcdir)"/$@.awk > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
concat4::
@echo $@
- @GAWKLOCALE=en_US.UTF-8 ; $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in > _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @GAWKLOCALE=en_US.UTF-8 ; $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
devfd1::
@echo $@
- @$(AWK) -f $(srcdir)/$@.awk 4< $(srcdir)/devfd.in1 5< $(srcdir)/devfd.in2 >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(AWK) -f "$(srcdir)"/$@.awk 4< "$(srcdir)"/devfd.in1 5< "$(srcdir)"/devfd.in2 >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
# The program text is the '1' which will print each record. How compact can you get?
devfd2::
@echo $@
- @$(AWK) 1 /dev/fd/4 /dev/fd/5 4< $(srcdir)/devfd.in1 5< $(srcdir)/devfd.in2 >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(AWK) 1 /dev/fd/4 /dev/fd/5 4< "$(srcdir)"/devfd.in1 5< "$(srcdir)"/devfd.in2 >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mixed1::
@echo $@
@$(AWK) -f /dev/null --source 'BEGIN {return junk}' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mtchi18n::
@echo $@
@GAWKLOCALE=ru_RU.UTF-8 ; export GAWKLOCALE ; \
- $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
reint2::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) --re-interval -f $@.awk $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) --re-interval -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
localenl::
@echo $@
- @$(srcdir)/$@.sh >_$@ 2>/dev/null
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @"$(srcdir)"/$@.sh >_$@ 2>/dev/null
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbprintf1::
@echo $@
@GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
- $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbprintf2::
@echo $@
@GAWKLOCALE=ja_JP.UTF-8 ; export GAWKLOCALE ; \
- $(AWK) -f $(srcdir)/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ $(AWK) -f "$(srcdir)"/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbprintf3::
@echo $@
@GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
- $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mbprintf4::
+ @echo $@
+ @GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
+ $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbfw1::
@echo $@
@GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
- $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
gsubtst6::
@echo $@
- @GAWKLOCALE=C ; $(AWK) -f $(srcdir)/$@.awk > _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @GAWKLOCALE=C ; $(AWK) -f "$(srcdir)"/$@.awk > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbstr1::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
printfbad2: printfbad2.ok
@echo $@
- @$(AWK) --lint -f $(srcdir)/$@.awk $(srcdir)/$@.in 2>&1 | sed 's;\$(srcdir)/;;g' >_$@ || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(AWK) --lint -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in 2>&1 | sed 's;$(srcdir)/;;g' >_$@ || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
beginfile1::
@echo $@
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk $(srcdir)/$@.awk . ./no/such/file Makefile >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.awk . ./no/such/file Makefile >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
beginfile2:
@echo $@
- @-( cd $(srcdir) && AWK="$(abs_builddir)/$(AWKPROG)" $(srcdir)/$@.sh $(srcdir)/$@.in ) > _$@ 2>&1
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-( cd "$(srcdir)" && LC_ALL=C AWK="$(abs_builddir)/$(AWKPROG)" $(abs_srcdir)/$@.sh $(abs_srcdir)/$@.in ) > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
dumpvars::
@echo $@
- @AWKPATH=$(srcdir) $(AWK) --dump-variables 1 < $(srcdir)/$@.in >/dev/null 2>&1 || echo EXIT CODE: $$? >>_$@
- @mv awkvars.out _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @AWKPATH="$(srcdir)" $(AWK) --dump-variables 1 < "$(srcdir)"/$@.in >/dev/null 2>&1 || echo EXIT CODE: $$? >>_$@
+ @grep -v ENVIRON < awkvars.out | grep -v PROCINFO > _$@; rm awkvars.out
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
profile1:
@echo $@
- @$(AWK) --profile=ap-$@.out -f $(srcdir)/xref.awk $(srcdir)/dtdgport.awk > _$@.out1
- @$(AWK) -f ap-$@.out $(srcdir)/dtdgport.awk > _$@.out2 ; rm ap-$@.out
- @cmp _$@.out1 _$@.out2 && rm _$@.out[12] || echo EXIT CODE: $$? >>_$@
+ @$(AWK) -f "$(srcdir)"/xref.awk "$(srcdir)"/dtdgport.awk > _$@.out1
+ @$(AWK) --pretty-print=ap-$@.out -f "$(srcdir)"/xref.awk
+ @$(AWK) -f ./ap-$@.out "$(srcdir)"/dtdgport.awk > _$@.out2 ; rm ap-$@.out
+ @$(CMP) _$@.out1 _$@.out2 && rm _$@.out[12] || { echo EXIT CODE: $$? >>_$@ ; \
+ cp "$(srcdir)"/dtdgport.awk $@.ok ; }
+
profile2:
@echo $@
- @$(PGAWK) --profile=ap-$@.out -v sortcmd=sort -f $(srcdir)/xref.awk $(srcdir)/dtdgport.awk > /dev/null
+ @$(AWK) --profile=ap-$@.out -v sortcmd=sort -f "$(srcdir)"/xref.awk "$(srcdir)"/dtdgport.awk > /dev/null
@sed 1,2d < ap-$@.out > _$@; rm ap-$@.out
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
profile3:
@echo $@
- @$(PGAWK) --profile=ap-$@.out -f $(srcdir)/$@.awk > /dev/null
+ @$(AWK) --profile=ap-$@.out -f "$(srcdir)"/$@.awk > /dev/null
@sed 1,2d < ap-$@.out > _$@; rm ap-$@.out
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+profile4:
+ @echo $@
+ @$(AWK) --pretty-print=_$@ -f "$(srcdir)"/$@.awk > /dev/null
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+profile5:
+ @echo $@
+ @$(AWK) --pretty-print=_$@ -f "$(srcdir)"/$@.awk > /dev/null
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+profile6:
+ @echo $@
+ @$(AWK) --profile=ap-$@.out -f "$(srcdir)"/$@.awk > /dev/null
+ @sed 1,2d < ap-$@.out > _$@; rm ap-$@.out
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+profile7:
+ @echo $@
+ @$(AWK) --profile=ap-$@.out -f "$(srcdir)"/$@.awk > /dev/null
+ @sed 1,2d < ap-$@.out > _$@; rm ap-$@.out
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+profile8:
+ @echo $@
+ @$(AWK) --pretty-print=_$@ -f "$(srcdir)"/$@.awk > /dev/null
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
posix2008sub:
@echo $@
- @$(AWK) --posix -f $(srcdir)/$@.awk > _$@ 2>&1
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(AWK) --posix -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
next:
@echo $@
- @-AWK="$(AWKPROG)" $(srcdir)/$@.sh > _$@ 2>&1
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-$(LOCALES) AWK="$(AWKPROG)" "$(srcdir)"/$@.sh > _$@ 2>&1
+ @-LC_ALL=C $(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
exit:
@echo $@
- @-AWK="$(AWKPROG)" $(srcdir)/$@.sh > _$@ 2>&1
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-AWK="$(AWKPROG)" "$(srcdir)"/$@.sh > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+rri1::
+ @echo $@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrieee:
+ @echo $@
+ @$(AWK) -M -vPREC=double -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrexprange:
+ @echo $@
+ @$(AWK) -M -vPREC=53 -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrrnd:
+ @echo $@
+ @$(AWK) -M -vPREC=53 -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrnegzero:
+ @echo $@
+ @$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrnr:
+ @echo $@
+ @$(AWK) -M -vPREC=113 -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrsort:
+ @echo $@
+ @$(AWK) -M -vPREC=53 -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrbigint:
+ @echo $@
+ @$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrsqrt:
+ @echo $@
+ @$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrrem:
+ @echo $@
+ @$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+jarebug::
+ @echo $@
+ @"$(srcdir)"/$@.sh "$(AWKPROG)" "$(srcdir)"/$@.awk "$(srcdir)"/$@.in "_$@"
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+ordchr2::
+ @echo $@
+ @$(AWK) --load ordchr 'BEGIN {print chr(ord("z"))}' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+# N.B. If the test fails, create readfile.ok so that "make diffout" will work
+readfile::
+ @echo $@
+ @$(AWK) -l readfile 'BEGIN {printf "%s", readfile("Makefile")}' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) Makefile _$@ && rm -f _$@ || cp -p Makefile $@.ok
+
+readfile2::
+ @echo $@
+ @$(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.awk "$(srcdir)"/readdir.awk > _$@ || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+include2::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --include inclib 'BEGIN {print sandwich("a", "b", "c")}' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -i inclib -i inclib.awk 'BEGIN {print sandwich("a", "b", "c")}' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe2::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -f inclib -f inclib.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe3::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -f hello -f hello.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe4::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -f hello -i hello.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe5::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -i hello -f hello.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe6::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -i inchello -f hello.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe7::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -f hello -i inchello >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+inplace1::
+ @echo $@
+ @cp "$(srcdir)"/inplace.1.in _$@.1
+ @cp "$(srcdir)"/inplace.2.in _$@.2
+ @AWKPATH="$(srcdir)"/../awklib/eg/lib $(AWK) -i inplace 'BEGIN {print "before"} {gsub(/foo/, "bar"); print} END {print "after"}' _$@.1 - _$@.2 < "$(srcdir)"/inplace.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.1.ok _$@.1 && rm -f _$@.1
+ @-$(CMP) "$(srcdir)"/$@.2.ok _$@.2 && rm -f _$@.2
+
+inplace2::
+ @echo $@
+ @cp "$(srcdir)"/inplace.1.in _$@.1
+ @cp "$(srcdir)"/inplace.2.in _$@.2
+ @AWKPATH="$(srcdir)"/../awklib/eg/lib $(AWK) -i inplace -v INPLACE_SUFFIX=.bak 'BEGIN {print "before"} {gsub(/foo/, "bar"); print} END {print "after"}' _$@.1 - _$@.2 < "$(srcdir)"/inplace.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.1.ok _$@.1 && rm -f _$@.1
+ @-$(CMP) "$(srcdir)"/$@.1.bak.ok _$@.1.bak && rm -f _$@.1.bak
+ @-$(CMP) "$(srcdir)"/$@.2.ok _$@.2 && rm -f _$@.2
+ @-$(CMP) "$(srcdir)"/$@.2.bak.ok _$@.2.bak && rm -f _$@.2.bak
+
+inplace3::
+ @echo $@
+ @cp "$(srcdir)"/inplace.1.in _$@.1
+ @cp "$(srcdir)"/inplace.2.in _$@.2
+ @AWKPATH="$(srcdir)"/../awklib/eg/lib $(AWK) -i inplace -v INPLACE_SUFFIX=.bak 'BEGIN {print "before"} {gsub(/foo/, "bar"); print} END {print "after"}' _$@.1 - _$@.2 < "$(srcdir)"/inplace.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @AWKPATH="$(srcdir)"/../awklib/eg/lib $(AWK) -i inplace -v INPLACE_SUFFIX=.bak 'BEGIN {print "Before"} {gsub(/bar/, "foo"); print} END {print "After"}' _$@.1 - _$@.2 < "$(srcdir)"/inplace.in >>_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.1.ok _$@.1 && rm -f _$@.1
+ @-$(CMP) "$(srcdir)"/$@.1.bak.ok _$@.1.bak && rm -f _$@.1.bak
+ @-$(CMP) "$(srcdir)"/$@.2.ok _$@.2 && rm -f _$@.2
+ @-$(CMP) "$(srcdir)"/$@.2.bak.ok _$@.2.bak && rm -f _$@.2.bak
+
+testext::
+ @echo $@
+ @$(AWK) '/^(@load|BEGIN)/,/^}/' "$(top_srcdir)"/extension/testext.c > testext.awk
+ @$(AWK) -f ./testext.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ testext.awk
+
+readdir:
+ @if [ "`uname`" = Linux ] && [ "`stat -f . 2>/dev/null | awk 'NR == 2 { print $$NF }'`" = nfs ]; then \
+ echo This test may fail on GNU/Linux systems when run on an NFS filesystem.; \
+ echo If it does, try rerunning on an ext'[234]' filesystem. ; \
+ fi
+ @echo $@
+ @$(AWK) -f "$(srcdir)"/readdir.awk "$(top_srcdir)" > _$@
+ @ls -afi "$(top_srcdir)" > _dirlist
+ @ls -lna "$(top_srcdir)" | sed 1d > _longlist
+ @$(AWK) -f "$(srcdir)"/readdir0.awk -v extout=_$@ \
+ -v dirlist=_dirlist -v longlist=_longlist > $@.ok
+ @-$(CMP) $@.ok _$@ && rm -f $@.ok _$@ _dirlist _longlist
+
+fts:
+ @case `uname` in \
+ IRIX) \
+ echo This test may fail on IRIX systems when run on an NFS filesystem.; \
+ echo If it does, try rerunning on an xfs filesystem. ;; \
+ CYGWIN*) \
+ echo This test may fail on CYGWIN systems when run on an NFS filesystem.; \
+ echo If it does, try rerunning on an ntfs filesystem. ;; \
+ esac
+ @echo $@
+ @$(AWK) -f "$(srcdir)"/fts.awk
+ @-$(CMP) $@.ok _$@ && rm -f $@.ok _$@
+
+charasbytes:
+ @echo $@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -b -f $@.awk "$(srcdir)"/$@.in | \
+ od -c -t x1 | tr ' ' ' ' | sed -e 's/ */ /g' -e 's/ *$$//' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab6:
+ @echo $@
+ @$(AWK) -d__$@ -f "$(srcdir)"/$@.awk
+ @grep -v '^ENVIRON' __$@ | grep -v '^PROCINFO' > _$@ ; rm __$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab8:
+ @echo $@
+ @$(AWK) -d__$@ -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@
+ @grep -v '^ENVIRON' __$@ | grep -v '^PROCINFO' | grep -v '^FILENAME' >> _$@ ; rm __$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab9:
+ @echo $@
+ @$(AWK) -f "$(srcdir)"/$@.awk >_$@
+ @rm -f testit.txt
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+reginttrad:
+ @echo $@
+ @$(AWK) --traditional -r -f "$(srcdir)"/$@.awk > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+colonwarn:
+ @echo $@
+ @for i in 1 2 3 ; \
+ do $(AWK) -f "$(srcdir)"/$@.awk $$i < "$(srcdir)"/$@.in ; \
+ done > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+clos1way:
+ @echo $@
+ @AWKPATH="$(srcdir)" LC_ALL=C $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+dfamb1:
+ @echo $@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+
+randtest::
+ @echo $@
+ @GAWK="$(AWKPROG)" "$(srcdir)"/randtest.sh >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+backbigs1:
+ @echo $@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+backsmalls1:
+ @echo $@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+backsmalls2:
+ @echo $@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+dbugeval::
+ @echo $@
+ @$(AWK) --debug -f /dev/null < "$(srcdir)"/$@.in > _$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+printhuge::
+ @echo $@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+filefuncs:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk -v builddir="$(abs_top_builddir)" >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+genpot:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --gen-pot >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
# Targets generated for other tests:
include Maketests
$(srcdir)/Maketests: $(srcdir)/Makefile.am $(srcdir)/Gentests
files=`cd "$(srcdir)" && echo *.awk *.in`; \
- $(AWK) -f $(srcdir)/Gentests "$(srcdir)/Makefile.am" $$files > $(srcdir)/Maketests
+ $(AWK) -f "$(srcdir)"/Gentests "$(srcdir)"/Makefile.am $$files > "$(srcdir)"/Maketests
clean:
- rm -fr _* core core.* fmtspcl.ok junk out1 out2 out3 strftime.ok test1 test2 seq *~
+ rm -fr _* core core.* fmtspcl.ok junk strftime.ok test1 test2 \
+ seq *~ readfile.ok fork.tmp.* testext.awk fts.ok readdir.ok \
+ mmap8k.ok profile1.ok
# 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 ; \
+ else echo $$COUNT TESTS FAILED ; exit 1; \
fi
# This target for my convenience to look at all the results
+# Don't use POSIX or bash-isms so that it'll work on !@#$%^&*() Solaris.
diffout:
for i in _* ; \
do \
if [ "$$i" != "_*" ]; then \
echo ============== $$i ============= ; \
- if [ -r $${i#_}.ok ]; then \
- diff -c $${i#_}.ok $$i ; \
+ base=`echo $$i | sed 's/^_//'` ; \
+ if [ -r $${base}.ok ]; then \
+ diff -c $${base}.ok $$i ; \
else \
- diff -c $(srcdir)/$${i#_}.ok $$i ; \
+ diff -c "$(srcdir)"/$${base}.ok $$i ; \
fi ; \
fi ; \
done | more
@@ -1472,8 +2063,8 @@ valgrind-scan:
function show() {if (cmd) {printf "%s: %s\n",FILENAME,cmd; cmd = ""}; \
printf "\t%s\n",$$0}; \
{$$1 = ""}; \
- /Prog and args are:/ {incmd = 1; cmd = ""; next}; \
- incmd {if (NF == 1) incmd = 0; else {cmd = (cmd $$0); next}}; \
+ $$2 == "Command:" {incmd = 1; $$2 = ""; cmd = $$0; next}; \
+ incmd {if (/Parent PID:/) incmd = 0; else {cmd = (cmd $$0); next}}; \
/ERROR SUMMARY:/ && !/: 0 errors from 0 contexts/ {show()}; \
/definitely lost:/ && !/: 0 bytes in 0 blocks/ {show()}; \
/possibly lost:/ && !/: 0 bytes in 0 blocks/ {show()}; \
diff --git a/test/Makefile.in b/test/Makefile.in
index 91173ea5..d4097f3d 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
+# Copyright (C) 1994-2013 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.
@@ -18,7 +17,7 @@
#
# test/Makefile.am --- automake input file for gawk
#
-# Copyright (C) 1988-2011 the Free Software Foundation, Inc.
+# Copyright (C) 1988-2015 the Free Software Foundation, Inc.
#
# This file is part of GAWK, the GNU implementation of the
# AWK Programming Language.
@@ -38,6 +37,51 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -56,21 +100,21 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
- $(srcdir)/Maketests ChangeLog
+DIST_COMMON = $(srcdir)/Maketests $(srcdir)/Makefile.in \
+ $(srcdir)/Makefile.am $(top_srcdir)/mkinstalldirs ChangeLog \
+ README
subdir = test
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/arch.m4 \
$(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/gettext.m4 \
$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
- $(top_srcdir)/m4/intmax_t.m4 $(top_srcdir)/m4/inttypes_h.m4 \
$(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/lcmessage.m4 \
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libsigsegv.m4 \
- $(top_srcdir)/m4/longlong.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/longlong.m4 $(top_srcdir)/m4/mpfr.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/noreturn.m4 \
$(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
$(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/socket.m4 \
- $(top_srcdir)/m4/stdint_h.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)
@@ -78,21 +122,34 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
SOURCES =
DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
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)
+AWK = $(LOCALES) AWKLIBPATH=../extension/.libs $(VALGRIND) $(AWKPROG)
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -106,6 +163,7 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
+GAWKLIBEXT = @GAWKLIBEXT@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
@@ -121,6 +179,7 @@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
LDFLAGS = @LDFLAGS@
LIBICONV = @LIBICONV@
LIBINTL = @LIBINTL@
+LIBMPFR = @LIBMPFR@
LIBOBJS = @LIBOBJS@
LIBREADLINE = @LIBREADLINE@
LIBS = @LIBS@
@@ -146,6 +205,7 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
POSUB = @POSUB@
+SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SOCKET_LIBS = @SOCKET_LIBS@
@@ -162,6 +222,7 @@ abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
+acl_shlibext = @acl_shlibext@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -196,12 +257,14 @@ mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
+pkgextensiondir = @pkgextensiondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
@@ -231,8 +294,6 @@ EXTRA_DIST = \
anchgsub.awk \
anchgsub.in \
anchgsub.ok \
- arraysort.awk \
- arraysort.ok \
argarray.awk \
argarray.in \
argarray.ok \
@@ -246,6 +307,8 @@ EXTRA_DIST = \
arrayprm3.ok \
arrayref.awk \
arrayref.ok \
+ arraysort.awk \
+ arraysort.ok \
arrymem1.awk \
arrymem1.ok \
arryref2.awk \
@@ -296,13 +359,29 @@ EXTRA_DIST = \
backw.awk \
backw.in \
backw.ok \
+ backbigs1.awk \
+ backbigs1.in \
+ backbigs1.ok \
+ backsmalls1.awk \
+ backsmalls1.in \
+ backsmalls1.ok \
+ backsmalls2.awk \
+ backsmalls2.ok \
badargs.ok \
+ badassign1.awk \
+ badassign1.ok \
+ badbuild.awk \
+ badbuild.in \
+ badbuild.ok \
beginfile1.awk \
beginfile1.ok \
beginfile2.in \
beginfile2.ok \
beginfile2.sh \
binmode1.ok \
+ charasbytes.awk \
+ charasbytes.in \
+ charasbytes.ok \
childin.awk \
childin.in \
childin.ok \
@@ -315,6 +394,9 @@ EXTRA_DIST = \
clsflnam.awk \
clsflnam.in \
clsflnam.ok \
+ colonwarn.awk \
+ colonwarn.in \
+ colonwarn.ok \
compare.awk \
compare.in \
compare.ok \
@@ -335,14 +417,16 @@ EXTRA_DIST = \
datanonl.awk \
datanonl.in \
datanonl.ok \
+ dbugeval.in \
+ dbugeval.ok \
defref.awk \
defref.ok \
delargv.awk \
delargv.ok \
- delarprm.awk \
- delarprm.ok \
delarpm2.awk \
delarpm2.ok \
+ delarprm.awk \
+ delarprm.ok \
delfunc.awk \
delfunc.ok \
delsub.awk \
@@ -355,6 +439,9 @@ EXTRA_DIST = \
devfd1.awk \
devfd1.ok \
devfd2.ok \
+ dfamb1.awk \
+ dfamb1.in \
+ dfamb1.ok \
dfastress.awk \
dfastress.ok \
double1.awk \
@@ -370,6 +457,8 @@ EXTRA_DIST = \
eofsplit.ok \
exit.ok \
exit.sh \
+ exit2.awk \
+ exit2.ok \
exitval1.awk \
exitval1.ok \
exitval2.awk \
@@ -378,19 +467,22 @@ EXTRA_DIST = \
fcall_exit.awk \
fcall_exit.ok \
fcall_exit2.awk \
- fcall_exit2.ok \
fcall_exit2.in \
+ fcall_exit2.ok \
fflush.ok \
fflush.sh \
fieldwdth.awk \
fieldwdth.in \
fieldwdth.ok \
+ filefuncs.awk \
+ filefuncs.ok \
fldchg.awk \
fldchg.in \
fldchg.ok \
fldchgnf.awk \
fldchgnf.in \
fldchgnf.ok \
+ fmtspcl-mpfr.ok \
fmtspcl.awk \
fmtspcl.tok \
fmttest.awk \
@@ -403,6 +495,7 @@ EXTRA_DIST = \
fnarray2.awk \
fnarray2.in \
fnarray2.ok \
+ fnarydel-mpfr.ok \
fnarydel.awk \
fnarydel.ok \
fnaryscl.awk \
@@ -410,10 +503,23 @@ EXTRA_DIST = \
fnasgnm.awk \
fnasgnm.in \
fnasgnm.ok \
+ fnmatch.awk \
+ fnmatch.ok \
fnmisc.awk \
fnmisc.ok \
+ fnparydl-mpfr.ok \
fnparydl.awk \
fnparydl.ok \
+ fordel.awk \
+ fordel.ok \
+ fork.awk \
+ fork.ok \
+ fork2.awk \
+ fork2.ok \
+ forref.awk \
+ forref.ok \
+ forsimp.awk \
+ forsimp.ok \
fpat1.awk \
fpat1.in \
fpat1.ok \
@@ -425,12 +531,6 @@ EXTRA_DIST = \
fpatnull.awk \
fpatnull.in \
fpatnull.ok \
- fordel.awk \
- fordel.ok \
- forref.awk \
- forref.ok \
- forsimp.awk \
- forsimp.ok \
fsbs.awk \
fsbs.in \
fsbs.ok \
@@ -446,6 +546,15 @@ EXTRA_DIST = \
fstabplus.awk \
fstabplus.in \
fstabplus.ok \
+ fts.awk \
+ functab1.awk \
+ functab1.ok \
+ functab2.awk \
+ functab2.ok \
+ functab3.awk \
+ functab3.ok \
+ functab4.awk \
+ functab4.ok \
funlen.awk \
funlen.in \
funlen.ok \
@@ -465,6 +574,8 @@ EXTRA_DIST = \
fwtest3.awk \
fwtest3.in \
fwtest3.ok \
+ genpot.awk \
+ genpot.ok \
gensub.awk \
gensub.in \
gensub.ok \
@@ -480,6 +591,8 @@ EXTRA_DIST = \
getline4.awk \
getline4.in \
getline4.ok \
+ getline5.awk \
+ getline5.ok \
getlnbuf.awk \
getlnbuf.in \
getlnbuf.ok \
@@ -522,6 +635,7 @@ EXTRA_DIST = \
gsubtst8.in \
gsubtst8.ok \
gtlnbufv.awk \
+ hello.awk \
hex.awk \
hex.ok \
hsprint.awk \
@@ -531,22 +645,54 @@ EXTRA_DIST = \
icasers.awk \
icasers.in \
icasers.ok \
+ id.awk \
+ id.ok \
igncdym.awk \
igncdym.in \
igncdym.ok \
igncfs.awk \
igncfs.in \
igncfs.ok \
+ ignrcas2.awk \
+ ignrcas2.ok \
ignrcase.awk \
ignrcase.in \
ignrcase.ok \
- ignrcas2.awk \
- ignrcas2.ok \
+ incdupe.ok \
+ incdupe2.ok \
+ incdupe3.ok \
+ incdupe4.ok \
+ incdupe5.ok \
+ incdupe6.ok \
+ incdupe7.ok \
+ inchello.awk \
+ inclib.awk \
+ include.awk \
+ include.ok \
+ include2.ok \
indirectcall.awk \
indirectcall.in \
indirectcall.ok \
+ indirectcall2.awk \
+ indirectcall2.ok \
inftest.awk \
inftest.ok \
+ inplace.in \
+ inplace.1.in \
+ inplace.2.in \
+ inplace1.ok \
+ inplace1.1.ok \
+ inplace1.2.ok \
+ inplace2.ok \
+ inplace2.1.ok \
+ inplace2.1.bak.ok \
+ inplace2.2.ok \
+ inplace2.2.bak.ok \
+ inplace3.ok \
+ inplace3.1.ok \
+ inplace3.1.bak.ok \
+ inplace3.2.ok \
+ inplace3.2.bak.ok \
inputred.awk \
inputred.ok \
intest.awk \
@@ -557,6 +703,10 @@ EXTRA_DIST = \
intprec.ok \
iobug1.awk \
iobug1.ok \
+ jarebug.awk \
+ jarebug.in \
+ jarebug.ok \
+ jarebug.sh \
lc_num1.awk \
lc_num1.ok \
leaddig.awk \
@@ -582,8 +732,8 @@ EXTRA_DIST = \
longsub.in \
longsub.ok \
longwrds.awk \
- longwrds.ok \
longwrds.in \
+ longwrds.ok \
manglprm.awk \
manglprm.in \
manglprm.ok \
@@ -609,6 +759,9 @@ EXTRA_DIST = \
mbprintf3.awk \
mbprintf3.in \
mbprintf3.ok \
+ mbprintf4.awk \
+ mbprintf4.in \
+ mbprintf4.ok \
mbstr1.awk \
mbstr1.ok \
membug1.awk \
@@ -619,6 +772,25 @@ EXTRA_DIST = \
minusstr.ok \
mixed1.ok \
mmap8k.in \
+ mpfrbigint.awk \
+ mpfrbigint.ok \
+ mpfrexprange.awk \
+ mpfrexprange.ok \
+ mpfrieee.awk \
+ mpfrieee.ok \
+ mpfrnegzero.awk \
+ mpfrnegzero.ok \
+ mpfrnr.awk \
+ mpfrnr.in \
+ mpfrnr.ok \
+ mpfrrem.awk \
+ mpfrrem.ok \
+ mpfrrnd.awk \
+ mpfrrnd.ok \
+ mpfrsort.awk \
+ mpfrsort.ok \
+ mpfrsqrt.awk \
+ mpfrsqrt.ok \
mtchi18n.awk \
mtchi18n.in \
mtchi18n.ok \
@@ -640,6 +812,8 @@ EXTRA_DIST = \
nfldstr.awk \
nfldstr.in \
nfldstr.ok \
+ nfloop.awk \
+ nfloop.ok \
nfneg.awk \
nfneg.ok \
nfset.awk \
@@ -699,6 +873,9 @@ EXTRA_DIST = \
ofmts.awk \
ofmts.in \
ofmts.ok \
+ ofs1.awk \
+ ofs1.in \
+ ofs1.ok \
onlynl.awk \
onlynl.in \
onlynl.ok \
@@ -706,6 +883,9 @@ EXTRA_DIST = \
opasnidx.ok \
opasnslf.awk \
opasnslf.ok \
+ ordchr.awk \
+ ordchr.ok \
+ ordchr2.ok \
out1.ok \
out2.ok \
out3.ok \
@@ -715,6 +895,8 @@ EXTRA_DIST = \
paramres.ok \
paramtyp.awk \
paramtyp.ok \
+ paramuninitglobal.awk \
+ paramuninitglobal.ok \
parse1.awk \
parse1.in \
parse1.ok \
@@ -744,9 +926,6 @@ EXTRA_DIST = \
prdupval.awk \
prdupval.in \
prdupval.ok \
- profile2.ok \
- profile3.awk \
- profile3.ok \
prec.awk \
prec.ok \
printf0.awk \
@@ -758,7 +937,13 @@ EXTRA_DIST = \
printfbad2.awk \
printfbad2.in \
printfbad2.ok \
+ printfbad3.awk \
+ printfbad3.ok \
+ printfbad4.awk \
+ printfbad4.ok \
printfloat.awk \
+ printhuge.awk \
+ printhuge.ok \
printlang.awk \
prmarscl.awk \
prmarscl.ok \
@@ -766,35 +951,66 @@ EXTRA_DIST = \
prmreuse.ok \
procinfs.awk \
procinfs.ok \
+ profile2.ok \
+ profile3.awk \
+ profile3.ok \
+ profile4.awk \
+ profile4.ok \
+ profile5.awk \
+ profile5.ok \
+ profile6.awk \
+ profile6.ok \
+ profile7.awk \
+ profile7.ok \
+ profile8.awk \
+ profile8.ok \
prt1eval.awk \
prt1eval.ok \
prtoeval.awk \
prtoeval.ok \
pty1.awk \
pty1.ok \
+ rand-mpfr.ok \
rand.awk \
rand.ok \
+ randtest.sh \
+ randtest.ok \
range1.awk \
range1.in \
range1.ok \
+ readdir.awk \
+ readdir0.awk \
+ readfile2.awk \
+ readfile2.ok \
rebt8b1.awk \
rebt8b1.ok \
rebt8b2.awk \
rebt8b2.ok \
+ rebuf.awk \
+ rebuf.in \
+ rebuf.ok \
redfilnm.awk \
redfilnm.in \
redfilnm.ok \
regeq.awk \
regeq.in \
regeq.ok \
+ regexpbrack.awk \
+ regexpbrack.in \
+ regexpbrack.ok \
+ regexprange.awk \
+ regexprange.ok \
+ reginttrad.awk \
+ reginttrad.ok \
+ regnul1.awk \
+ regnul1.ok \
+ regnul2.awk \
+ regnul2.ok \
regrange.awk \
regrange.ok \
regtest.sh \
regx8bit.awk \
regx8bit.ok \
- rebuf.awk \
- rebuf.in \
- rebuf.ok \
reindops.awk \
reindops.in \
reindops.ok \
@@ -810,9 +1026,20 @@ EXTRA_DIST = \
resplit.awk \
resplit.in \
resplit.ok \
+ revout.awk \
+ revout.ok \
+ revtwoway.awk \
+ revtwoway.ok \
+ rri1.awk \
+ rri1.in \
+ rri1.ok \
rs.awk \
rs.in \
rs.ok \
+ rsgetline.awk \
+ rsgetline.in \
+ rsgetline.ok \
+ rsglstdin.ok \
rsnul1nl.awk \
rsnul1nl.in \
rsnul1nl.ok \
@@ -842,8 +1069,12 @@ EXTRA_DIST = \
rswhite.ok \
rtlen.ok \
rtlen.sh \
+ rtlenmb.ok \
rtlen01.ok \
rtlen01.sh \
+ rwarray.awk \
+ rwarray.in \
+ rwarray.ok \
scalar.awk \
scalar.ok \
sclforin.awk \
@@ -859,9 +1090,15 @@ EXTRA_DIST = \
sortfor.awk \
sortfor.in \
sortfor.ok \
+ sortglos.awk \
+ sortglos.in \
+ sortglos.ok \
sortu.awk \
sortu.ok \
space.ok \
+ split_after_fpat.awk \
+ split_after_fpat.in \
+ split_after_fpat.ok \
splitarg4.awk \
splitarg4.in \
splitarg4.ok \
@@ -882,16 +1119,16 @@ EXTRA_DIST = \
sprintfc.ok \
strcat1.awk \
strcat1.ok \
+ strftime.awk \
+ strftlng.awk \
+ strftlng.ok \
+ strnum1.awk \
+ strnum1.ok \
strtod.awk \
strtod.in \
strtod.ok \
- strnum1.awk \
- strnum1.ok \
strtonum.awk \
strtonum.ok \
- strftime.awk \
- strftlng.awk \
- strftlng.ok \
subamp.awk \
subamp.in \
subamp.ok \
@@ -908,10 +1145,35 @@ EXTRA_DIST = \
swaplns.ok \
switch2.awk \
switch2.ok \
+ symtab1.awk \
+ symtab1.ok \
+ symtab2.awk \
+ symtab2.ok \
+ symtab3.awk \
+ symtab3.ok \
+ symtab4.awk \
+ symtab4.in \
+ symtab4.ok \
+ symtab5.awk \
+ symtab5.in \
+ symtab5.ok \
+ symtab6.awk \
+ symtab6.ok \
+ symtab7.awk \
+ symtab7.in \
+ symtab7.ok \
+ symtab8.awk \
+ symtab8.in \
+ symtab8.ok \
+ symtab9.awk \
+ symtab9.ok \
synerr1.awk \
synerr1.ok \
synerr2.awk \
synerr2.ok \
+ testext.ok \
+ time.awk \
+ time.ok \
tradanch.awk \
tradanch.in \
tradanch.ok \
@@ -964,64 +1226,84 @@ TESTS_WE_ARE_NOT_DOING_YET_FIXME_ONE_DAY = longdbl
# Get rid of core files when cleaning and generated .ok file
CLEANFILES = core core.* fmtspcl.ok
-# try to keep these sorted
+# try to keep these sorted. each letter starts a new line
BASIC_TESTS = \
addcomma anchgsub argarray arrayparm arrayprm2 arrayprm3 \
arrayref arrymem1 arryref2 arryref3 arryref4 arryref5 arynasty \
arynocls aryprm1 aryprm2 aryprm3 aryprm4 aryprm5 aryprm6 aryprm7 \
- aryprm8 arysubnm asgext awkpath back89 backgsub childin clobber \
- closebad clsflnam compare compare2 concat1 concat2 concat3 \
- concat4 convfmt datanonl defref delargv delarpm2 delarprm delfunc \
- dfastress dynlj eofsplit exitval1 exitval2 fcall_exit fcall_exit2 \
- fldchg fldchgnf fnamedat fnarray fnarray2 fnaryscl fnasgnm fnmisc \
- fordel forref forsimp fsbs fsrs fsspcoln fstabplus funsemnl funsmnam \
- funstack getline getline2 getline3 getline4 \
- getlnbuf getnr2tb getnr2tm \
+ aryprm8 arysubnm asgext awkpath \
+ back89 backgsub badassign1 badbuild \
+ childin clobber closebad clsflnam compare compare2 concat1 concat2 \
+ concat3 concat4 convfmt \
+ datanonl defref delargv delarpm2 delarprm delfunc dfamb1 dfastress dynlj \
+ eofsplit exit2 exitval1 exitval2 \
+ fcall_exit fcall_exit2 fldchg fldchgnf fnamedat fnarray fnarray2 \
+ fnaryscl fnasgnm fnmisc fordel forref forsimp fsbs fsrs fsspcoln \
+ fstabplus funsemnl funsmnam funstack \
+ getline getline2 getline3 getline4 getline5 getlnbuf getnr2tb getnr2tm \
gsubasgn gsubtest gsubtst2 gsubtst3 gsubtst4 gsubtst5 gsubtst6 \
gsubtst7 gsubtst8 \
- hex hsprint inputred intest intprec iobug1 leaddig leadnl litoct \
- longsub longwrds manglprm math membug1 messages minusstr mmap8k \
- mtchi18n nasty nasty2 negexp negrange nested nfldstr nfneg \
- nfset nlfldsep nlinstr nlstrina noeffect nofile nofmtch noloop1 \
- noloop2 nonl noparms nors nulrsend numindex numsubstr octsub ofmt \
- ofmta ofmtbig ofmtfidl ofmts onlynl opasnidx opasnslf paramdup \
- paramres paramtyp parse1 parsefld parseme pcntplus posix2008sub \
- prdupval prec printf0 printf1 prmarscl prmreuse prt1eval prtoeval \
- rand range1 rebt8b1 redfilnm regeq regrange reindops reparse resplit \
- rs rsnul1nl rsnulbig rsnulbig2 rstest1 rstest2 rstest3 rstest4 \
- rstest5 rswhite scalar sclforin sclifin sortempty splitargv \
- splitarr splitdef splitvar splitwht strcat1 strnum1 strtod subamp \
- subi18n subsepnm subslash substr swaplns synerr1 synerr2 tradanch \
- tweakfld uninit2 uninit3 uninit4 uninit5 uninitialized unterm \
- uparrfs wideidx wideidx2 widesub widesub2 widesub3 widesub4 \
- wjposer1 zero2 zeroe0 zeroflag
+ hex hsprint \
+ inputred intest intprec iobug1 \
+ leaddig leadnl litoct longsub longwrds \
+ manglprm math membug1 messages minusstr mmap8k mtchi18n \
+ nasty nasty2 negexp negrange nested nfldstr nfloop nfneg nfset nlfldsep \
+ nlinstr nlstrina noeffect nofile nofmtch noloop1 noloop2 nonl \
+ noparms nors nulrsend numindex numsubstr \
+ octsub ofmt ofmta ofmtbig ofmtfidl ofmts ofs1 onlynl opasnidx opasnslf \
+ paramdup paramres paramtyp paramuninitglobal parse1 parsefld parseme \
+ pcntplus posix2008sub prdupval prec printf0 printf1 prmarscl prmreuse \
+ prt1eval prtoeval \
+ rand randtest range1 rebt8b1 redfilnm regeq regexpbrack regexprange regrange reindops \
+ reparse resplit rri1 rs rsnul1nl rsnulbig rsnulbig2 rstest1 rstest2 \
+ rstest3 rstest4 rstest5 rswhite \
+ scalar sclforin sclifin sortempty sortglos splitargv splitarr splitdef \
+ splitvar splitwht strcat1 strnum1 strtod subamp subi18n \
+ subsepnm subslash substr swaplns synerr1 synerr2 tradanch tweakfld \
+ uninit2 uninit3 uninit4 uninit5 uninitialized unterm uparrfs \
+ wideidx wideidx2 widesub widesub2 widesub3 widesub4 wjposer1 \
+ zero2 zeroe0 zeroflag
UNIX_TESTS = \
- fflush getlnhd localenl pid pipeio1 pipeio2 poundbang rtlen rtlen01 \
- space strftlng
+ fflush getlnhd localenl pid pipeio1 pipeio2 poundbang \
+ rtlen rtlen01 space strftlng
GAWK_EXT_TESTS = \
aadelete1 aadelete2 aarray1 aasort aasorti argtest arraysort \
- backw badargs beginfile1 beginfile2 \
- binmode1 clos1way delsub devfd devfd1 \
- devfd2 dumpvars exit fieldwdth fpat1 fpat2 fpat3 \
- fpatnull fsfwfs funlen \
- fwtest fwtest2 fwtest3 \
- gensub gensub2 getlndir gnuops2 gnuops3 gnureops \
- icasefs icasers igncdym igncfs ignrcas2 ignrcase indirectcall lint \
- lintold lintwarn manyfiles match1 match2 match3 mbstr1 nastyparm \
- next nondec nondec2 patsplit posix printfbad1 printfbad2 procinfs \
- profile1 profile2 profile3 pty1 \
- rebuf regx8bit reint reint2 rsstart1 \
- rsstart2 rsstart3 rstest6 shadow sortfor sortu splitarg4 strftime \
- strtonum switch2
+ backw badargs beginfile1 beginfile2 binmode1 charasbytes \
+ colonwarn clos1way dbugeval delsub devfd devfd1 devfd2 dumpvars exit \
+ fieldwdth fpat1 fpat2 fpat3 fpatnull fsfwfs funlen \
+ functab1 functab2 functab3 fwtest fwtest2 fwtest3 \
+ genpot gensub gensub2 getlndir gnuops2 gnuops3 gnureops \
+ icasefs icasers id igncdym igncfs ignrcas2 ignrcase \
+ incdupe incdupe2 incdupe3 incdupe4 incdupe5 incdupe6 incdupe7 \
+ include include2 indirectcall indirectcall2 \
+ lint lintold lintwarn \
+ manyfiles match1 match2 match3 mbstr1 \
+ nastyparm next nondec nondec2 \
+ patsplit posix printfbad1 printfbad2 printfbad3 printfbad4 printhuge procinfs \
+ profile1 profile2 profile3 profile4 profile5 profile6 profile7 \
+ profile8 pty1 \
+ rebuf regnul1 regnul2 regx8bit reginttrad reint reint2 rsgetline rsglstdin rsstart1 \
+ rsstart2 rsstart3 rstest6 shadow sortfor sortu split_after_fpat \
+ splitarg4 strftime \
+ strtonum switch2 symtab1 symtab2 symtab3 symtab4 symtab5 symtab6 \
+ symtab7 symtab8 symtab9
EXTRA_TESTS = inftest regtest
INET_TESTS = inetdayu inetdayt inetechu inetecht
MACHINE_TESTS = double1 double2 fmtspcl intformat
+MPFR_TESTS = mpfrnr mpfrnegzero mpfrrem mpfrrnd mpfrieee mpfrexprange \
+ mpfrsort mpfrsqrt mpfrbigint
+
LOCALE_CHARSET_TESTS = \
- asort asorti fmttest fnarydel fnparydl lc_num1 mbfw1 \
- mbprintf1 mbprintf2 mbprintf3 rebt8b2 rtlenmb sort1 sprintfc
+ asort asorti backbigs1 backsmalls1 backsmalls2 \
+ fmttest fnarydel fnparydl jarebug lc_num1 mbfw1 \
+ mbprintf1 mbprintf2 mbprintf3 mbprintf4 rebt8b2 rtlenmb sort1 sprintfc
+
+SHLIB_TESTS = \
+ fnmatch filefuncs fork fork2 fts functab4 inplace1 inplace2 inplace3 \
+ ordchr ordchr2 readdir readfile readfile2 revout revtwoway rwarray testext time
# List of the tests which should be run with --lint option:
@@ -1038,12 +1320,32 @@ FAIL_CODE1 = \
fnarray2 fnmisc gsubasgn mixed1 noparms paramdup synerr1 synerr2 unterm
+# List of files which have .ok versions for MPFR
+CHECK_MPFR = \
+ rand fnarydel fnparydl
+
+
# List of the files that appear in manual tests or are for reserve testing:
-GENTESTS_UNUSED = Makefile.in gtlnbufv.awk printfloat.awk
+GENTESTS_UNUSED = Makefile.in dtdgport.awk gtlnbufv.awk hello.awk \
+ inchello.awk inclib.awk inplace.1.in inplace.2.in inplace.in \
+ longdbl.awk longdbl.in printfloat.awk readdir0.awk xref.awk
+
CMP = cmp
AWKPROG = ../gawk$(EXEEXT)
-PGAWKPROG = ../pgawk$(EXEEXT)
-PGAWK = LC_ALL=$${GAWKLOCALE:-C} LANG=$${GAWKLOCALE:-C} $(PGAWKPROG)
+
+# Default for VALGRIND is empty unless overridden by a command-line argument.
+# This protects against cruft in the environment.
+VALGRIND =
+
+# 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.
+
+#
+# And we set AWKLIBPATH to find the extension libraries we built.
+LOCALES = LC_ALL=$${GAWKLOCALE:-C} LANG=$${GAWKLOCALE:-C}
all: all-am
.SUFFIXES:
@@ -1077,11 +1379,11 @@ $(top_srcdir)/configure: $(am__configure_deps)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
-tags: TAGS
-TAGS:
+tags TAGS:
+
+ctags CTAGS:
-ctags: CTAGS
-CTAGS:
+cscope cscopelist:
distdir: $(DISTFILES)
@@ -1128,10 +1430,15 @@ install-am: all-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
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
mostlyclean-generic:
clean-generic:
@@ -1210,15 +1517,16 @@ uninstall-am:
.MAKE: install-am install-strip
-.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-dvi \
- install-dvi-am install-exec install-exec-am install-html \
- install-html-am install-info install-info-am install-man \
- install-pdf install-pdf-am install-ps install-ps-am \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am
+.PHONY: all all-am check check-am clean clean-generic cscopelist-am \
+ ctags-am distclean distclean-generic distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+ pdf-am ps ps-am tags-am uninstall uninstall-am
# Message stuff is to make it a little easier to follow.
@@ -1230,8 +1538,10 @@ check: msg \
unix-msg-start unix-tests unix-msg-end \
extend-msg-start gawk-extensions extend-msg-end \
machine-msg-start machine-tests machine-msg-end \
- charset-msg-start charset-tests charset-msg-end
- @$(MAKE) pass-fail
+ charset-msg-start charset-tests charset-msg-end \
+ shlib-msg-start shlib-tests shlib-msg-end \
+ mpfr-msg-start mpfr-tests mpfr-msg-end
+ @$(MAKE) pass-fail || { $(MAKE) diffout; exit 1; }
basic: $(BASIC_TESTS)
@@ -1247,6 +1557,24 @@ inet: inetmesg $(INET_TESTS)
machine-tests: $(MACHINE_TESTS)
+# The blank between ' and /MPFR/ is for running tests on Windows under
+# MSYS, which thinks /MPFR is a Unix-style file name and converts it
+# to Windows format, butchering it in the process. Likewise for /API/
+# in the next shlib-tests.
+mpfr-tests:
+ @if $(AWK) --version | $(AWK) ' /MPFR/ { exit 1 }' ; then \
+ echo MPFR tests not supported on this system ; \
+ else $(MAKE) $(MPFR_TESTS) ; \
+ fi
+
+shlib-tests:
+ @if $(AWK) --version | $(AWK) ' /API/ { exit 1 }' ; then \
+ echo shlib tests not supported on this system ; \
+ else $(MAKE) shlib-real-tests ; \
+ fi
+
+shlib-real-tests: $(SHLIB_TESTS)
+
msg::
@echo ''
@echo 'Any output from "cmp" is bad news, although some differences'
@@ -1255,7 +1583,7 @@ msg::
@echo 'precision may lead to slightly different output in a few cases.'
printlang::
- @$(AWK) -f $(srcdir)/printlang.awk
+ @$(AWK) -f "$(srcdir)"/printlang.awk
basic-msg-start:
@echo "======== Starting basic tests ========"
@@ -1283,15 +1611,33 @@ machine-msg-end:
charset-msg-start:
@echo "======== Starting tests that can vary based on character set or locale support ========"
+ @echo "************************************************"
+ @echo "** Some or all of these tests may fail if you **"
+ @echo "** have inadequate or missing locale support **"
+ @echo "** At least en_US.UTF-8, ru_RU.UTF-8 and **"
+ @echo "** ja_JP.UTF-8 are needed. **"
+ @echo "************************************************"
charset-msg-end:
@echo "======== Done with tests that can vary based on character set or locale support ========"
+shlib-msg-start:
+ @echo "======== Starting shared library tests ========"
+
+shlib-msg-end:
+ @echo "======== Done with shared library tests ========"
+
+mpfr-msg-start:
+ @echo "======== Starting MPFR tests ========"
+
+mpfr-msg-end:
+ @echo "======== Done with MPFR tests ========"
+
lc_num1:
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
# This test is a PITA because increasingly, /tmp is getting
# mounted noexec. So, we'll test it locally. Sigh.
@@ -1300,186 +1646,197 @@ lc_num1:
# so this can still fail
poundbang::
@echo $@
- @sed "s;/tmp/gawk;`pwd`/$(AWKPROG);" < $(srcdir)/poundbang.awk > ./_pbd.awk
+ @sed "s;/tmp/gawk;`pwd`/$(AWKPROG);" < "$(srcdir)"/poundbang.awk > ./_pbd.awk
@chmod +x ./_pbd.awk
- @if ./_pbd.awk $(srcdir)/poundbang.awk > _`basename $@` ; \
+ @if ./_pbd.awk "$(srcdir)"/poundbang.awk > _`basename $@` ; \
then : ; \
else \
- sed "s;/tmp/gawk;../$(AWKPROG);" < $(srcdir)/poundbang.awk > ./_pbd.awk ; \
+ 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 $@`; \
+ LC_ALL=$${GAWKLOCALE:-C} LANG=$${GAWKLOCALE:-C} ./_pbd.awk "$(srcdir)"/poundbang.awk > _`basename $@`; \
fi
- @-$(CMP) $(srcdir)/poundbang.awk _`basename $@` && rm -f _`basename $@` _pbd.awk
+ @-$(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
+ @$(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 \
+ @case "$(srcdir)" in \
.) : ;; \
- *) cp $(srcdir)/argarray.in . ;; \
+ *) cp "$(srcdir)"/argarray.in . ;; \
esac
- @TEST=test echo just a test | $(AWK) -f $(srcdir)/argarray.awk ./argarray.in - >_$@
- @case $(srcdir) in \
+ @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 _$@
+ @-$(CMP) "$(srcdir)"/$@.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=$(AWKPROG) $(srcdir)/regtest.sh
+ AWK=$(AWKPROG) "$(srcdir)"/regtest.sh
manyfiles::
@echo manyfiles
@rm -rf junk
@mkdir junk
@$(AWK) 'BEGIN { for (i = 1; i <= 1030; i++) print i, i}' >_$@
- @$(AWK) -f $(srcdir)/manyfiles.awk _$@ _$@
+ @$(AWK) -f "$(srcdir)"/manyfiles.awk _$@ _$@
@wc -l junk/* | $(AWK) '$$1 != 2' | wc -l | sed "s/ *//g" > _$@
- @rm -rf junk ; $(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @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 _$@
+ @$(AWK) -f "$(srcdir)"/compare.awk 0 1 "$(srcdir)"/compare.in >_$@
+ @-$(CMP) "$(srcdir)"/$@.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 _$@
+ @$(AWK) -f "$(srcdir)"/inftest.awk | sed "s/inf/Inf/g" >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
getline2::
@echo $@
- @$(AWK) -f $(srcdir)/getline2.awk $(srcdir)/getline2.awk $(srcdir)/getline2.awk >_$@
- @-$(CMP) $(srcdir)/getline2.ok _$@ && rm -f _$@
+ @$(AWK) -f "$(srcdir)"/getline2.awk "$(srcdir)"/getline2.awk "$(srcdir)"/getline2.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
awkpath::
@echo $@
@AWKPATH="$(srcdir)$(PATH_SEPARATOR)$(srcdir)/lib" $(AWK) -f awkpath.awk >_$@
- @-$(CMP) $(srcdir)/awkpath.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
argtest::
@echo $@
- @$(AWK) -f $(srcdir)/argtest.awk -x -y abc >_$@
- @-$(CMP) $(srcdir)/argtest.ok _$@ && rm -f _$@
+ @$(AWK) -f "$(srcdir)"/argtest.awk -x -y abc >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
badargs::
@echo $@
@-$(AWK) -f 2>&1 | grep -v patchlevel >_$@
- @-$(CMP) $(srcdir)/badargs.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
nonl::
@echo $@
- @-AWKPATH=$(srcdir) $(AWK) --lint -f nonl.awk /dev/null >_$@ 2>&1
- @-$(CMP) $(srcdir)/nonl.ok _$@ && rm -f _$@
+ @-AWKPATH="$(srcdir)" $(AWK) --lint -f nonl.awk /dev/null >_$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.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
+ $(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 _$@
+ @echo ab | $(AWK) --traditional -f "$(srcdir)"/litoct.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
devfd::
@echo $@
- @$(AWK) 1 /dev/fd/4 /dev/fd/5 4<$(srcdir)/devfd.in4 5<$(srcdir)/devfd.in5 >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(AWK) 1 /dev/fd/4 /dev/fd/5 4<"$(srcdir)"/devfd.in4 5<"$(srcdir)"/devfd.in5 >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fflush::
@echo $@
- @$(srcdir)/fflush.sh >_$@
- @-$(CMP) $(srcdir)/fflush.ok _$@ && rm -f _$@
+ @"$(srcdir)"/fflush.sh >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
tweakfld::
@echo $@
- @$(AWK) -f $(srcdir)/tweakfld.awk $(srcdir)/tweakfld.in >_$@
+ @$(AWK) -f "$(srcdir)"/tweakfld.awk "$(srcdir)"/tweakfld.in >_$@
@rm -f errors.cleanup
- @-$(CMP) $(srcdir)/tweakfld.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mmap8k::
@echo $@
- @$(AWK) '{ print }' $(srcdir)/mmap8k.in >_$@
- @-$(CMP) $(srcdir)/mmap8k.in _$@ && rm -f _$@
+ @$(AWK) '{ print }' "$(srcdir)"/mmap8k.in >_$@
+ @-$(CMP) "$(srcdir)"/mmap8k.in _$@ && rm -f _$@ || cp "$(srcdir)"/$@.in $@.ok
tradanch::
@echo $@
- @$(AWK) --traditional -f $(srcdir)/tradanch.awk $(srcdir)/tradanch.in >_$@
- @-$(CMP) $(srcdir)/tradanch.ok _$@ && rm -f _$@
+ @$(AWK) --traditional -f "$(srcdir)"/tradanch.awk "$(srcdir)"/tradanch.in >_$@
+ @-$(CMP) "$(srcdir)"/$@.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 $@`
+ @AWKPATH="$(srcdir)" AWK=$(AWKPROG) $(SHELL) "$(srcdir)"/pid.sh $$$$ > _`basename $@` ; :
+ @-$(CMP) "$(srcdir)"/pid.ok _`basename $@` && rm -f _`basename $@`
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 >_$@ ; \
+ @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 _$@
+ @-$(CMP) "$(srcdir)"/$@.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 _$@
+ @echo A B C D E | tr -d '\12\15' | $(AWK) '{ print $$NF }' - "$(srcdir)"/nors.in > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fmtspcl.ok: fmtspcl.tok Makefile
- @$(AWK) -v "sd=$(srcdir)" 'BEGIN {pnan = sprintf("%g",sqrt(-1)); nnan = sprintf("%g",-sqrt(-1)); pinf = sprintf("%g",-log(0)); ninf = sprintf("%g",log(0))} {sub(/positive_nan/,pnan); sub(/negative_nan/,nnan); sub(/positive_infinity/,pinf); sub(/negative_infinity/,ninf); sub(/fmtspcl/,(sd"/fmtspcl")); print}' < $(srcdir)/fmtspcl.tok > $@ 2>/dev/null
+ @$(AWK) -v "sd=$(srcdir)" 'BEGIN {pnan = sprintf("%g",sqrt(-1)); nnan = sprintf("%g",-sqrt(-1)); pinf = sprintf("%g",-log(0)); ninf = sprintf("%g",log(0))} {sub(/positive_nan/,pnan); sub(/negative_nan/,nnan); sub(/positive_infinity/,pinf); sub(/negative_infinity/,ninf); sub(/fmtspcl/,(sd"/fmtspcl")); print}' < "$(srcdir)"/fmtspcl.tok > $@ 2>/dev/null
fmtspcl: fmtspcl.ok
- @echo fmtspcl
- @$(AWK) -f $(srcdir)/fmtspcl.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $@.ok _$@ && rm -f _$@
+ @echo $@
+ @$(AWK) $(AWKFLAGS) -f "$(srcdir)"/fmtspcl.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-if test -z "$$AWKFLAGS" ; then $(CMP) $@.ok _$@ && rm -f _$@ ; else \
+ $(CMP) "$(srcdir)"/$@-mpfr.ok _$@ && rm -f _$@ ; \
+ fi
+
+rebuf::
+ @echo $@
+ @AWKBUFSIZE=4096 AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+rsglstdin::
+ @echo $@
+ @cat "$(srcdir)"/rsgetline.in | AWKPATH="$(srcdir)" $(AWK) -f rsgetline.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
reint::
@echo $@
- @$(AWK) --re-interval -f $(srcdir)/reint.awk $(srcdir)/reint.in >_$@
- @-$(CMP) $(srcdir)/reint.ok _$@ && rm -f _$@
+ @$(AWK) --re-interval -f "$(srcdir)"/reint.awk "$(srcdir)"/reint.in >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
pipeio1::
@echo $@
- @$(AWK) -f $(srcdir)/pipeio1.awk >_$@
+ @$(AWK) -f "$(srcdir)"/pipeio1.awk >_$@
@rm -f test1 test2
- @-$(CMP) $(srcdir)/pipeio1.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
pipeio2::
@echo $@
- @$(AWK) -v SRCDIR=$(srcdir) -f $(srcdir)/pipeio2.awk >_$@
- @-$(CMP) $(srcdir)/pipeio2.ok _$@ && rm -f _$@
+ @$(AWK) -v SRCDIR="$(srcdir)" -f "$(srcdir)"/pipeio2.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
clobber::
@echo $@
- @$(AWK) -f $(srcdir)/clobber.awk >_$@
- @-$(CMP) $(srcdir)/clobber.ok seq && $(CMP) $(srcdir)/clobber.ok _$@ && rm -f _$@
+ @$(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 _$@
+ @-AWKPATH="$(srcdir)" $(AWK) -v INPUT="$(srcdir)"/arynocls.in -f arynocls.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.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$@
+ @-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
@@ -1506,28 +1863,28 @@ inetdayt::
redfilnm::
@echo $@
- @$(AWK) -f $(srcdir)/redfilnm.awk srcdir=$(srcdir) $(srcdir)/redfilnm.in >_$@
- @-$(CMP) $(srcdir)/redfilnm.ok _$@ && rm -f _$@
+ @$(AWK) -f "$(srcdir)"/redfilnm.awk srcdir="$(srcdir)" "$(srcdir)"/redfilnm.in >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
leaddig::
@echo $@
- @$(AWK) -v x=2E -f $(srcdir)/leaddig.awk >_$@
- @-$(CMP) $(srcdir)/leaddig.ok _$@ && rm -f _$@
+ @$(AWK) -v x=2E -f "$(srcdir)"/leaddig.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
gsubtst3::
@echo $@
- @$(AWK) --re-interval -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(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 _$@
+ @$(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 _$@
+ @$(AWK) --posix -f "$(srcdir)"/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
rsnulbig::
@echo $@
@@ -1535,7 +1892,7 @@ rsnulbig::
@$(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 _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
rsnulbig2::
@echo $@
@@ -1543,1436 +1900,1920 @@ rsnulbig2::
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 _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
wideidx::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
wideidx2::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
widesub::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
widesub2::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
widesub3::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
widesub4::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(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 _$@
+ @GAWKLOCALE=en_US.UTF-8 ; 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 _$@
+ $(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 _$@
+ @$(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 _$@
+ @$(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 _$@
+ @$(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 _$@
+ @$(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 _$@
+ @head "$(srcdir)"/rsstart1.in | $(AWK) -f "$(srcdir)"/rsstart2.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
rtlen::
@echo $@
- @$(srcdir)/$@.sh >_$@ || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @"$(srcdir)"/$@.sh >_$@ || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
rtlen01::
@echo $@
- @$(srcdir)/$@.sh >_$@ || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @"$(srcdir)"/$@.sh >_$@ || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
rtlenmb::
@echo $@
@GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
- $(srcdir)/rtlen.sh >_$@ || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/rtlen.ok _$@ && rm -f _$@
+ "$(srcdir)"/rtlen.sh >_$@ || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
nondec2::
@echo $@
- @$(AWK) --non-decimal-data -v a=0x1 -f $(srcdir)/$@.awk >_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(AWK) --non-decimal-data -v a=0x1 -f "$(srcdir)"/$@.awk >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
nofile::
@echo $@
@$(AWK) '{}' no/such/file >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
binmode1::
@echo $@
@$(AWK) -v BINMODE=3 'BEGIN { print BINMODE }' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
subi18n::
@echo $@
- @GAWKLOCALE=en_US.UTF-8 ; $(AWK) -f $(srcdir)/$@.awk > _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @GAWKLOCALE=en_US.UTF-8 ; $(AWK) -f "$(srcdir)"/$@.awk > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
concat4::
@echo $@
- @GAWKLOCALE=en_US.UTF-8 ; $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in > _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @GAWKLOCALE=en_US.UTF-8 ; $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
devfd1::
@echo $@
- @$(AWK) -f $(srcdir)/$@.awk 4< $(srcdir)/devfd.in1 5< $(srcdir)/devfd.in2 >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(AWK) -f "$(srcdir)"/$@.awk 4< "$(srcdir)"/devfd.in1 5< "$(srcdir)"/devfd.in2 >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
# The program text is the '1' which will print each record. How compact can you get?
devfd2::
@echo $@
- @$(AWK) 1 /dev/fd/4 /dev/fd/5 4< $(srcdir)/devfd.in1 5< $(srcdir)/devfd.in2 >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(AWK) 1 /dev/fd/4 /dev/fd/5 4< "$(srcdir)"/devfd.in1 5< "$(srcdir)"/devfd.in2 >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mixed1::
@echo $@
@$(AWK) -f /dev/null --source 'BEGIN {return junk}' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mtchi18n::
@echo $@
@GAWKLOCALE=ru_RU.UTF-8 ; export GAWKLOCALE ; \
- $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
reint2::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) --re-interval -f $@.awk $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) --re-interval -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
localenl::
@echo $@
- @$(srcdir)/$@.sh >_$@ 2>/dev/null
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @"$(srcdir)"/$@.sh >_$@ 2>/dev/null
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbprintf1::
@echo $@
@GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
- $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbprintf2::
@echo $@
@GAWKLOCALE=ja_JP.UTF-8 ; export GAWKLOCALE ; \
- $(AWK) -f $(srcdir)/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ $(AWK) -f "$(srcdir)"/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbprintf3::
@echo $@
@GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
- $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mbprintf4::
+ @echo $@
+ @GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
+ $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbfw1::
@echo $@
@GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
- $(AWK) -f $(srcdir)/$@.awk $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
gsubtst6::
@echo $@
- @GAWKLOCALE=C ; $(AWK) -f $(srcdir)/$@.awk > _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @GAWKLOCALE=C ; $(AWK) -f "$(srcdir)"/$@.awk > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbstr1::
@echo $@
@[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
- AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
printfbad2: printfbad2.ok
@echo $@
- @$(AWK) --lint -f $(srcdir)/$@.awk $(srcdir)/$@.in 2>&1 | sed 's;\$(srcdir)/;;g' >_$@ || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(AWK) --lint -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in 2>&1 | sed 's;$(srcdir)/;;g' >_$@ || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
beginfile1::
@echo $@
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk $(srcdir)/$@.awk . ./no/such/file Makefile >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.awk . ./no/such/file Makefile >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
beginfile2:
@echo $@
- @-( cd $(srcdir) && AWK="$(abs_builddir)/$(AWKPROG)" $(srcdir)/$@.sh $(srcdir)/$@.in ) > _$@ 2>&1
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-( cd "$(srcdir)" && LC_ALL=C AWK="$(abs_builddir)/$(AWKPROG)" $(abs_srcdir)/$@.sh $(abs_srcdir)/$@.in ) > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
dumpvars::
@echo $@
- @AWKPATH=$(srcdir) $(AWK) --dump-variables 1 < $(srcdir)/$@.in >/dev/null 2>&1 || echo EXIT CODE: $$? >>_$@
- @mv awkvars.out _$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @AWKPATH="$(srcdir)" $(AWK) --dump-variables 1 < "$(srcdir)"/$@.in >/dev/null 2>&1 || echo EXIT CODE: $$? >>_$@
+ @grep -v ENVIRON < awkvars.out | grep -v PROCINFO > _$@; rm awkvars.out
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
profile1:
@echo $@
- @$(AWK) --profile=ap-$@.out -f $(srcdir)/xref.awk $(srcdir)/dtdgport.awk > _$@.out1
- @$(AWK) -f ap-$@.out $(srcdir)/dtdgport.awk > _$@.out2 ; rm ap-$@.out
- @cmp _$@.out1 _$@.out2 && rm _$@.out[12] || echo EXIT CODE: $$? >>_$@
+ @$(AWK) -f "$(srcdir)"/xref.awk "$(srcdir)"/dtdgport.awk > _$@.out1
+ @$(AWK) --pretty-print=ap-$@.out -f "$(srcdir)"/xref.awk
+ @$(AWK) -f ./ap-$@.out "$(srcdir)"/dtdgport.awk > _$@.out2 ; rm ap-$@.out
+ @$(CMP) _$@.out1 _$@.out2 && rm _$@.out[12] || { echo EXIT CODE: $$? >>_$@ ; \
+ cp "$(srcdir)"/dtdgport.awk $@.ok ; }
profile2:
@echo $@
- @$(PGAWK) --profile=ap-$@.out -v sortcmd=sort -f $(srcdir)/xref.awk $(srcdir)/dtdgport.awk > /dev/null
+ @$(AWK) --profile=ap-$@.out -v sortcmd=sort -f "$(srcdir)"/xref.awk "$(srcdir)"/dtdgport.awk > /dev/null
@sed 1,2d < ap-$@.out > _$@; rm ap-$@.out
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
profile3:
@echo $@
- @$(PGAWK) --profile=ap-$@.out -f $(srcdir)/$@.awk > /dev/null
+ @$(AWK) --profile=ap-$@.out -f "$(srcdir)"/$@.awk > /dev/null
@sed 1,2d < ap-$@.out > _$@; rm ap-$@.out
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+profile4:
+ @echo $@
+ @$(AWK) --pretty-print=_$@ -f "$(srcdir)"/$@.awk > /dev/null
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+profile5:
+ @echo $@
+ @$(AWK) --pretty-print=_$@ -f "$(srcdir)"/$@.awk > /dev/null
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+profile6:
+ @echo $@
+ @$(AWK) --profile=ap-$@.out -f "$(srcdir)"/$@.awk > /dev/null
+ @sed 1,2d < ap-$@.out > _$@; rm ap-$@.out
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+profile7:
+ @echo $@
+ @$(AWK) --profile=ap-$@.out -f "$(srcdir)"/$@.awk > /dev/null
+ @sed 1,2d < ap-$@.out > _$@; rm ap-$@.out
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+profile8:
+ @echo $@
+ @$(AWK) --pretty-print=_$@ -f "$(srcdir)"/$@.awk > /dev/null
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
posix2008sub:
@echo $@
- @$(AWK) --posix -f $(srcdir)/$@.awk > _$@ 2>&1
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @$(AWK) --posix -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
next:
@echo $@
- @-AWK="$(AWKPROG)" $(srcdir)/$@.sh > _$@ 2>&1
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-$(LOCALES) AWK="$(AWKPROG)" "$(srcdir)"/$@.sh > _$@ 2>&1
+ @-LC_ALL=C $(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
exit:
@echo $@
- @-AWK="$(AWKPROG)" $(srcdir)/$@.sh > _$@ 2>&1
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @-AWK="$(AWKPROG)" "$(srcdir)"/$@.sh > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+rri1::
+ @echo $@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrieee:
+ @echo $@
+ @$(AWK) -M -vPREC=double -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrexprange:
+ @echo $@
+ @$(AWK) -M -vPREC=53 -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrrnd:
+ @echo $@
+ @$(AWK) -M -vPREC=53 -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrnegzero:
+ @echo $@
+ @$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrnr:
+ @echo $@
+ @$(AWK) -M -vPREC=113 -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrsort:
+ @echo $@
+ @$(AWK) -M -vPREC=53 -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrbigint:
+ @echo $@
+ @$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrsqrt:
+ @echo $@
+ @$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+mpfrrem:
+ @echo $@
+ @$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+jarebug::
+ @echo $@
+ @"$(srcdir)"/$@.sh "$(AWKPROG)" "$(srcdir)"/$@.awk "$(srcdir)"/$@.in "_$@"
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+ordchr2::
+ @echo $@
+ @$(AWK) --load ordchr 'BEGIN {print chr(ord("z"))}' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+# N.B. If the test fails, create readfile.ok so that "make diffout" will work
+readfile::
+ @echo $@
+ @$(AWK) -l readfile 'BEGIN {printf "%s", readfile("Makefile")}' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) Makefile _$@ && rm -f _$@ || cp -p Makefile $@.ok
+
+readfile2::
+ @echo $@
+ @$(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.awk "$(srcdir)"/readdir.awk > _$@ || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+include2::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --include inclib 'BEGIN {print sandwich("a", "b", "c")}' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -i inclib -i inclib.awk 'BEGIN {print sandwich("a", "b", "c")}' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe2::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -f inclib -f inclib.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe3::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -f hello -f hello.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe4::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -f hello -i hello.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe5::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -i hello -f hello.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe6::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -i inchello -f hello.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+incdupe7::
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) --lint -f hello -i inchello >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+inplace1::
+ @echo $@
+ @cp "$(srcdir)"/inplace.1.in _$@.1
+ @cp "$(srcdir)"/inplace.2.in _$@.2
+ @AWKPATH="$(srcdir)"/../awklib/eg/lib $(AWK) -i inplace 'BEGIN {print "before"} {gsub(/foo/, "bar"); print} END {print "after"}' _$@.1 - _$@.2 < "$(srcdir)"/inplace.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.1.ok _$@.1 && rm -f _$@.1
+ @-$(CMP) "$(srcdir)"/$@.2.ok _$@.2 && rm -f _$@.2
+
+inplace2::
+ @echo $@
+ @cp "$(srcdir)"/inplace.1.in _$@.1
+ @cp "$(srcdir)"/inplace.2.in _$@.2
+ @AWKPATH="$(srcdir)"/../awklib/eg/lib $(AWK) -i inplace -v INPLACE_SUFFIX=.bak 'BEGIN {print "before"} {gsub(/foo/, "bar"); print} END {print "after"}' _$@.1 - _$@.2 < "$(srcdir)"/inplace.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.1.ok _$@.1 && rm -f _$@.1
+ @-$(CMP) "$(srcdir)"/$@.1.bak.ok _$@.1.bak && rm -f _$@.1.bak
+ @-$(CMP) "$(srcdir)"/$@.2.ok _$@.2 && rm -f _$@.2
+ @-$(CMP) "$(srcdir)"/$@.2.bak.ok _$@.2.bak && rm -f _$@.2.bak
+
+inplace3::
+ @echo $@
+ @cp "$(srcdir)"/inplace.1.in _$@.1
+ @cp "$(srcdir)"/inplace.2.in _$@.2
+ @AWKPATH="$(srcdir)"/../awklib/eg/lib $(AWK) -i inplace -v INPLACE_SUFFIX=.bak 'BEGIN {print "before"} {gsub(/foo/, "bar"); print} END {print "after"}' _$@.1 - _$@.2 < "$(srcdir)"/inplace.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @AWKPATH="$(srcdir)"/../awklib/eg/lib $(AWK) -i inplace -v INPLACE_SUFFIX=.bak 'BEGIN {print "Before"} {gsub(/bar/, "foo"); print} END {print "After"}' _$@.1 - _$@.2 < "$(srcdir)"/inplace.in >>_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+ @-$(CMP) "$(srcdir)"/$@.1.ok _$@.1 && rm -f _$@.1
+ @-$(CMP) "$(srcdir)"/$@.1.bak.ok _$@.1.bak && rm -f _$@.1.bak
+ @-$(CMP) "$(srcdir)"/$@.2.ok _$@.2 && rm -f _$@.2
+ @-$(CMP) "$(srcdir)"/$@.2.bak.ok _$@.2.bak && rm -f _$@.2.bak
+
+testext::
+ @echo $@
+ @$(AWK) '/^(@load|BEGIN)/,/^}/' "$(top_srcdir)"/extension/testext.c > testext.awk
+ @$(AWK) -f ./testext.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ testext.awk
+
+readdir:
+ @if [ "`uname`" = Linux ] && [ "`stat -f . 2>/dev/null | awk 'NR == 2 { print $$NF }'`" = nfs ]; then \
+ echo This test may fail on GNU/Linux systems when run on an NFS filesystem.; \
+ echo If it does, try rerunning on an ext'[234]' filesystem. ; \
+ fi
+ @echo $@
+ @$(AWK) -f "$(srcdir)"/readdir.awk "$(top_srcdir)" > _$@
+ @ls -afi "$(top_srcdir)" > _dirlist
+ @ls -lna "$(top_srcdir)" | sed 1d > _longlist
+ @$(AWK) -f "$(srcdir)"/readdir0.awk -v extout=_$@ \
+ -v dirlist=_dirlist -v longlist=_longlist > $@.ok
+ @-$(CMP) $@.ok _$@ && rm -f $@.ok _$@ _dirlist _longlist
+
+fts:
+ @case `uname` in \
+ IRIX) \
+ echo This test may fail on IRIX systems when run on an NFS filesystem.; \
+ echo If it does, try rerunning on an xfs filesystem. ;; \
+ CYGWIN*) \
+ echo This test may fail on CYGWIN systems when run on an NFS filesystem.; \
+ echo If it does, try rerunning on an ntfs filesystem. ;; \
+ esac
+ @echo $@
+ @$(AWK) -f "$(srcdir)"/fts.awk
+ @-$(CMP) $@.ok _$@ && rm -f $@.ok _$@
+
+charasbytes:
+ @echo $@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -b -f $@.awk "$(srcdir)"/$@.in | \
+ od -c -t x1 | tr ' ' ' ' | sed -e 's/ */ /g' -e 's/ *$$//' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab6:
+ @echo $@
+ @$(AWK) -d__$@ -f "$(srcdir)"/$@.awk
+ @grep -v '^ENVIRON' __$@ | grep -v '^PROCINFO' > _$@ ; rm __$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab8:
+ @echo $@
+ @$(AWK) -d__$@ -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@
+ @grep -v '^ENVIRON' __$@ | grep -v '^PROCINFO' | grep -v '^FILENAME' >> _$@ ; rm __$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab9:
+ @echo $@
+ @$(AWK) -f "$(srcdir)"/$@.awk >_$@
+ @rm -f testit.txt
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+reginttrad:
+ @echo $@
+ @$(AWK) --traditional -r -f "$(srcdir)"/$@.awk > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+colonwarn:
+ @echo $@
+ @for i in 1 2 3 ; \
+ do $(AWK) -f "$(srcdir)"/$@.awk $$i < "$(srcdir)"/$@.in ; \
+ done > _$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+clos1way:
+ @echo $@
+ @AWKPATH="$(srcdir)" LC_ALL=C $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+dfamb1:
+ @echo $@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+randtest::
+ @echo $@
+ @GAWK="$(AWKPROG)" "$(srcdir)"/randtest.sh >_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+backbigs1:
+ @echo $@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+backsmalls1:
+ @echo $@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+backsmalls2:
+ @echo $@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+dbugeval::
+ @echo $@
+ @$(AWK) --debug -f /dev/null < "$(srcdir)"/$@.in > _$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+printhuge::
+ @echo $@
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+filefuncs:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk -v builddir="$(abs_top_builddir)" >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+genpot:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --gen-pot >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+badassign1:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+badbuild:
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
closebad:
- @echo closebad
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
delargv:
- @echo delargv
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
dfastress:
- @echo dfastress
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+exit2:
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fcall_exit:
- @echo fcall_exit
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fcall_exit2:
- @echo fcall_exit2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fnarray2:
- @echo fnarray2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
forref:
- @echo forref
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
getline4:
- @echo getline4
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+getline5:
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
gsubtst7:
- @echo gsubtst7
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
gsubtst8:
- @echo gsubtst8
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
negrange:
- @echo negrange
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+nfloop:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
ofmta:
- @echo ofmta
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+ofs1:
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
paramres:
- @echo paramres
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+paramuninitglobal:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
parse1:
- @echo parse1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
parsefld:
- @echo parsefld
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) $(AWKFLAGS) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-if test -z "$$AWKFLAGS" ; then $(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ ; else \
+ $(CMP) "$(srcdir)"/$@-mpfr.ok _$@ && rm -f _$@ ; \
+ fi
range1:
- @echo range1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+regexpbrack:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+regexprange:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
regrange:
- @echo regrange
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+sortglos:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
strnum1:
- @echo strnum1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
synerr2:
- @echo synerr2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
uninit5:
- @echo uninit5
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
uparrfs:
- @echo uparrfs
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
zero2:
- @echo zero2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
aadelete1:
- @echo aadelete1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
aadelete2:
- @echo aadelete2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
aarray1:
- @echo aarray1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
aasort:
- @echo aasort
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
aasorti:
- @echo aasorti
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
arraysort:
- @echo arraysort
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
delsub:
- @echo delsub
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fpat1:
- @echo fpat1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fpat2:
- @echo fpat2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fpat3:
- @echo fpat3
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fpatnull:
- @echo fpatnull
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
funlen:
- @echo funlen
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+functab1:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+functab2:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+functab3:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fwtest:
- @echo fwtest
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fwtest2:
- @echo fwtest2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fwtest3:
- @echo fwtest3
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
getlndir:
- @echo getlndir
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+id:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+include:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
indirectcall:
- @echo indirectcall
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+indirectcall2:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
lintold:
- @echo lintold
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint-old < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint-old < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
lintwarn:
- @echo lintwarn
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
match3:
- @echo match3
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
nastyparm:
- @echo nastyparm
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
patsplit:
- @echo patsplit
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+printfbad3:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+printfbad4:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
pty1:
- @echo pty1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+regnul1:
+ @echo $@
+ @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 _$@
+regnul2:
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+rsgetline:
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
sortfor:
- @echo sortfor
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
sortu:
- @echo sortu
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+split_after_fpat:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
splitarg4:
- @echo splitarg4
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
switch2:
- @echo switch2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab1:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab2:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab3:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab4:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab5:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab7:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
double1:
- @echo double1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
double2:
- @echo double2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
intformat:
- @echo intformat
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) $(AWKFLAGS) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-if test -z "$$AWKFLAGS" ; then $(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ ; else \
+ $(CMP) "$(srcdir)"/$@-mpfr.ok _$@ && rm -f _$@ ; \
+ fi
fnparydl:
- @echo fnparydl
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) $(AWKFLAGS) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-if test -z "$$AWKFLAGS" ; then $(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ ; else \
+ $(CMP) "$(srcdir)"/$@-mpfr.ok _$@ && rm -f _$@ ; \
+ fi
rebt8b2:
- @echo rebt8b2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+fnmatch:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+fork:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+fork2:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+functab4:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+ordchr:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+revout:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+revtwoway:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+rwarray:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+time:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
# end of file Maketests
@@ -2980,29 +3821,33 @@ sprintfc:
$(srcdir)/Maketests: $(srcdir)/Makefile.am $(srcdir)/Gentests
files=`cd "$(srcdir)" && echo *.awk *.in`; \
- $(AWK) -f $(srcdir)/Gentests "$(srcdir)/Makefile.am" $$files > $(srcdir)/Maketests
+ $(AWK) -f "$(srcdir)"/Gentests "$(srcdir)"/Makefile.am $$files > "$(srcdir)"/Maketests
clean:
- rm -fr _* core core.* fmtspcl.ok junk out1 out2 out3 strftime.ok test1 test2 seq *~
+ rm -fr _* core core.* fmtspcl.ok junk strftime.ok test1 test2 \
+ seq *~ readfile.ok fork.tmp.* testext.awk fts.ok readdir.ok \
+ mmap8k.ok profile1.ok
# 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 ; \
+ else echo $$COUNT TESTS FAILED ; exit 1; \
fi
# This target for my convenience to look at all the results
+# Don't use POSIX or bash-isms so that it'll work on !@#$%^&*() Solaris.
diffout:
for i in _* ; \
do \
if [ "$$i" != "_*" ]; then \
echo ============== $$i ============= ; \
- if [ -r $${i#_}.ok ]; then \
- diff -c $${i#_}.ok $$i ; \
+ base=`echo $$i | sed 's/^_//'` ; \
+ if [ -r $${base}.ok ]; then \
+ diff -c $${base}.ok $$i ; \
else \
- diff -c $(srcdir)/$${i#_}.ok $$i ; \
+ diff -c "$(srcdir)"/$${base}.ok $$i ; \
fi ; \
fi ; \
done | more
@@ -3014,8 +3859,8 @@ valgrind-scan:
function show() {if (cmd) {printf "%s: %s\n",FILENAME,cmd; cmd = ""}; \
printf "\t%s\n",$$0}; \
{$$1 = ""}; \
- /Prog and args are:/ {incmd = 1; cmd = ""; next}; \
- incmd {if (NF == 1) incmd = 0; else {cmd = (cmd $$0); next}}; \
+ $$2 == "Command:" {incmd = 1; $$2 = ""; cmd = $$0; next}; \
+ incmd {if (/Parent PID:/) incmd = 0; else {cmd = (cmd $$0); next}}; \
/ERROR SUMMARY:/ && !/: 0 errors from 0 contexts/ {show()}; \
/definitely lost:/ && !/: 0 bytes in 0 blocks/ {show()}; \
/possibly lost:/ && !/: 0 bytes in 0 blocks/ {show()}; \
diff --git a/test/Maketests b/test/Maketests
index 5c1a6b38..5c4c40f9 100644
--- a/test/Maketests
+++ b/test/Maketests
@@ -1,1193 +1,1374 @@
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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+badassign1:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+badbuild:
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
closebad:
- @echo closebad
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
delargv:
- @echo delargv
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
dfastress:
- @echo dfastress
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+exit2:
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fcall_exit:
- @echo fcall_exit
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fcall_exit2:
- @echo fcall_exit2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fnarray2:
- @echo fnarray2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
forref:
- @echo forref
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
getline4:
- @echo getline4
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+getline5:
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
gsubtst7:
- @echo gsubtst7
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
gsubtst8:
- @echo gsubtst8
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
negrange:
- @echo negrange
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+nfloop:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
ofmta:
- @echo ofmta
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+ofs1:
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
paramres:
- @echo paramres
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+paramuninitglobal:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
parse1:
- @echo parse1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
parsefld:
- @echo parsefld
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) $(AWKFLAGS) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-if test -z "$$AWKFLAGS" ; then $(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ ; else \
+ $(CMP) "$(srcdir)"/$@-mpfr.ok _$@ && rm -f _$@ ; \
+ fi
range1:
- @echo range1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+regexpbrack:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+regexprange:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
regrange:
- @echo regrange
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+sortglos:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
strnum1:
- @echo strnum1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
synerr2:
- @echo synerr2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
uninit5:
- @echo uninit5
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
uparrfs:
- @echo uparrfs
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
zero2:
- @echo zero2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
aadelete1:
- @echo aadelete1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
aadelete2:
- @echo aadelete2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
aarray1:
- @echo aarray1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
aasort:
- @echo aasort
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
aasorti:
- @echo aasorti
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
arraysort:
- @echo arraysort
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
delsub:
- @echo delsub
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fpat1:
- @echo fpat1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fpat2:
- @echo fpat2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fpat3:
- @echo fpat3
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fpatnull:
- @echo fpatnull
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
funlen:
- @echo funlen
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+functab1:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+functab2:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+functab3:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fwtest:
- @echo fwtest
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fwtest2:
- @echo fwtest2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
fwtest3:
- @echo fwtest3
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
getlndir:
- @echo getlndir
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+id:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+include:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
indirectcall:
- @echo indirectcall
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+indirectcall2:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
lintold:
- @echo lintold
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint-old < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint-old < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
lintwarn:
- @echo lintwarn
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
match3:
- @echo match3
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
nastyparm:
- @echo nastyparm
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
patsplit:
- @echo patsplit
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+printfbad3:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+printfbad4:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
pty1:
- @echo pty1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+regnul1:
+ @echo $@
+ @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 _$@
+regnul2:
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+rsgetline:
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
sortfor:
- @echo sortfor
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
sortu:
- @echo sortu
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+split_after_fpat:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
splitarg4:
- @echo splitarg4
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
switch2:
- @echo switch2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab1:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab2:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab3:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab4:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab5:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+symtab7:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
double1:
- @echo double1
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
double2:
- @echo double2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
intformat:
- @echo intformat
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) $(AWKFLAGS) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-if test -z "$$AWKFLAGS" ; then $(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ ; else \
+ $(CMP) "$(srcdir)"/$@-mpfr.ok _$@ && rm -f _$@ ; \
+ fi
fnparydl:
- @echo fnparydl
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) $(AWKFLAGS) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-if test -z "$$AWKFLAGS" ; then $(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ ; else \
+ $(CMP) "$(srcdir)"/$@-mpfr.ok _$@ && rm -f _$@ ; \
+ fi
rebt8b2:
- @echo rebt8b2
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 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 _$@
+ @echo $@
+ @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 _$@
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+fnmatch:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+fork:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+fork2:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+functab4:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+ordchr:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+revout:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+revtwoway:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+rwarray:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+time:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
# end of file Maketests
diff --git a/test/backbigs1.awk b/test/backbigs1.awk
new file mode 100644
index 00000000..fb4d811f
--- /dev/null
+++ b/test/backbigs1.awk
@@ -0,0 +1 @@
+/\S/
diff --git a/test/backbigs1.in b/test/backbigs1.in
new file mode 100644
index 00000000..16b415f4
--- /dev/null
+++ b/test/backbigs1.in
@@ -0,0 +1 @@
+‚
diff --git a/test/backbigs1.ok b/test/backbigs1.ok
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/backbigs1.ok
diff --git a/test/backsmalls1.awk b/test/backsmalls1.awk
new file mode 100644
index 00000000..f3e0aba4
--- /dev/null
+++ b/test/backsmalls1.awk
@@ -0,0 +1 @@
+/^\s$/
diff --git a/test/backsmalls1.in b/test/backsmalls1.in
new file mode 100644
index 00000000..491807cd
--- /dev/null
+++ b/test/backsmalls1.in
@@ -0,0 +1,36 @@
+# U+00A0 NO-BREAK SPACE: c2 a0
+# 
+# U+2007 FIGURE SPACE: e2 80 87
+# 
+# U+200B ZERO WIDTH SPACE: e2 80 8b
+#​
+# U+202F NARROW NO-BREAK SPACE: e2 80 af
+# 
+U+0020 SPACE: 20
+
+U+1680 OGHAM SPACE MARK: e1 9a 80
+ 
+U+2000 EN QUAD: e2 80 80
+ 
+U+2001 EM QUAD: e2 80 81
+â€
+U+2002 EN SPACE: e2 80 82
+ 
+U+2003 EM SPACE: e2 80 83
+ 
+U+2004 THREE-PER-EM SPACE: e2 80 84
+ 
+U+2005 FOUR-PER-EM SPACE: e2 80 85
+ 
+U+2006 SIX-PER-EM SPACE: e2 80 86
+ 
+U+2008 PUNCTUATION SPACE: e2 80 88
+ 
+U+2009 THIN SPACE: e2 80 89
+ 
+U+200A HAIR SPACE: e2 80 8a
+ 
+U+205F MEDIUM MATHEMATICAL SPACE: e2 81 9f
+âŸ
+U+3000 IDEOGRAPHIC SPACE: e3 80 80
+ 
diff --git a/test/backsmalls1.ok b/test/backsmalls1.ok
new file mode 100644
index 00000000..1f678123
--- /dev/null
+++ b/test/backsmalls1.ok
@@ -0,0 +1,14 @@
+
+ 
+ 
+â€
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+âŸ
+ 
diff --git a/test/backsmalls2.awk b/test/backsmalls2.awk
new file mode 100644
index 00000000..02326f58
--- /dev/null
+++ b/test/backsmalls2.awk
@@ -0,0 +1,10 @@
+BEGIN {
+ pat["^\\s*$"] = pat["^\\s+$"] = pat["^\\s?$"] = pat["^\\s{1}$"] = 1
+ for (i in pat) {
+ if (" " !~ i) {
+ printf("pattern \"%s\" failed!\n", i) > "/dev/stderr"
+ exit 1
+ }
+ }
+ exit 0
+}
diff --git a/test/backsmalls2.ok b/test/backsmalls2.ok
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/backsmalls2.ok
diff --git a/test/badargs.ok b/test/badargs.ok
index 66e67b03..1664ec1c 100644
--- a/test/badargs.ok
+++ b/test/badargs.ok
@@ -10,13 +10,18 @@ Short options: GNU long options: (extensions)
-c --traditional
-C --copyright
-d[file] --dump-variables[=file]
+ -D[file] --debug[=file]
-e 'program-text' --source='program-text'
-E file --exec=file
-g --gen-pot
-h --help
- -L [fatal] --lint[=fatal]
- -n --non-decimal-data
+ -i includefile --include=includefile
+ -l library --load=library
+ -L[fatal|invalid] --lint[=fatal|invalid]
+ -M --bignum
-N --use-lc-numeric
+ -n --non-decimal-data
+ -o[file] --pretty-print[=file]
-O --optimize
-p[file] --profile[=file]
-P --posix
diff --git a/test/badassign1.awk b/test/badassign1.awk
new file mode 100644
index 00000000..5614f4a4
--- /dev/null
+++ b/test/badassign1.awk
@@ -0,0 +1 @@
+BEGIN { $i++ = 3 ; print i }
diff --git a/test/badassign1.ok b/test/badassign1.ok
new file mode 100644
index 00000000..c5ade3b3
--- /dev/null
+++ b/test/badassign1.ok
@@ -0,0 +1,3 @@
+gawk: badassign1.awk:1: BEGIN { $i++ = 3 ; print i }
+gawk: badassign1.awk:1: ^ cannot assign a value to the result of a field post-increment expression
+EXIT CODE: 1
diff --git a/test/badbuild.awk b/test/badbuild.awk
new file mode 100644
index 00000000..12a6caeb
--- /dev/null
+++ b/test/badbuild.awk
@@ -0,0 +1,6 @@
+$1 == $2 == $3 {
+ print "Gawk was built incorrectly."
+ print "Use bison, not byacc or something else!"
+ print "(Really, why aren't you using the awkgram.c in the distribution?)"
+ exit 42
+}
diff --git a/test/badbuild.in b/test/badbuild.in
new file mode 100644
index 00000000..560711d4
--- /dev/null
+++ b/test/badbuild.in
@@ -0,0 +1 @@
+a a 1
diff --git a/test/badbuild.ok b/test/badbuild.ok
new file mode 100644
index 00000000..6d60f5a9
--- /dev/null
+++ b/test/badbuild.ok
@@ -0,0 +1,3 @@
+gawk: badbuild.awk:1: $1 == $2 == $3 {
+gawk: badbuild.awk:1: ^ syntax error
+EXIT CODE: 1
diff --git a/test/beginfile2.ok b/test/beginfile2.ok
index 2d872eae..fed71bb2 100644
--- a/test/beginfile2.ok
+++ b/test/beginfile2.ok
@@ -5,12 +5,12 @@ In BEGINFILE: beginfile2.in
--Test 1b--
In BEGIN
In BEGINFILE: beginfile2.in
-In BEGINFILE: /file/does/not/exist
-gawk: cmd. line:3: fatal: cannot open file `/file/does/not/exist' for reading (No such file or directory)
+In BEGINFILE: file/does/not/exist
+gawk: cmd. line:3: fatal: cannot open file `file/does/not/exist' for reading (No such file or directory)
--Test 2--
In BEGINFILE: beginfile2.in
In ENDFILE: beginfile2.in
-In BEGINFILE: /file/does/not/exist
+In BEGINFILE: file/does/not/exist
--Test 3--
In BEGINFILE: beginfile2.in
In ENDFILE: beginfile2.in
@@ -47,12 +47,12 @@ In ENDFILE: beginfile2.sh
beginfile2.in
1 2
--Test 9a--
-Skipping: 1:/file/does/not/exist
+Skipping: 1:file/does/not/exist
In BEGINFILE: 2:beginfile2.in
In Rule: beginfile2.in
In ENDFILE: beginfile2.in
--Test 9b--
-Skipping: 1:/file/does/not/exist
+Skipping: 1:file/does/not/exist
Skipping: 2:beginfile2.in
In ENDFILE: beginfile2.in
--Test 10--
diff --git a/test/beginfile2.sh b/test/beginfile2.sh
index 69161200..dffaa88b 100755
--- a/test/beginfile2.sh
+++ b/test/beginfile2.sh
@@ -13,70 +13,70 @@ then
fi
echo "--Test 1a--"
-prog=`$AWK '/#TEST1#/, /#TEST2#/' $AWKPROG`
+prog=`$AWK ' /#TEST1#/, /#TEST2#/' $AWKPROG`
$AWK "$prog" $AWKPROG
echo "--Test 1b--"
-$AWK "$prog" $AWKPROG /file/does/not/exist
+$AWK "$prog" $AWKPROG file/does/not/exist
echo "--Test 2--"
-prog=`$AWK '/#TEST2#/, /#TEST3#/' $AWKPROG`
-$AWK "$prog" $AWKPROG /file/does/not/exist
+prog=`$AWK ' /#TEST2#/, /#TEST3#/' $AWKPROG`
+$AWK "$prog" $AWKPROG file/does/not/exist
echo "--Test 3--"
-prog=`$AWK '/#TEST3#/, /#TEST4#/' $AWKPROG`
+prog=`$AWK ' /#TEST3#/, /#TEST4#/' $AWKPROG`
$AWK -vsrc=$SCRIPT "$prog" $AWKPROG
echo "--Test 4--"
-prog=`$AWK '/#TEST4#/, /#TEST5#/' $AWKPROG`
+prog=`$AWK ' /#TEST4#/, /#TEST5#/' $AWKPROG`
$AWK -vsrc=$SCRIPT "$prog" $AWKPROG
echo "--Test 5--"
-prog=`$AWK '/#TEST5#/, /#TEST6#/' $AWKPROG`
+prog=`$AWK ' /#TEST5#/, /#TEST6#/' $AWKPROG`
$AWK "$prog" $AWKPROG
echo "--Test 6--"
-prog=`$AWK '/#TEST6#/, /#TEST7#/' $AWKPROG`
+prog=`$AWK ' /#TEST6#/, /#TEST7#/' $AWKPROG`
$AWK "$prog" $AWKPROG
echo "--Test 7--"
-prog=`$AWK '/#TEST7#/, /#TEST8#/' $AWKPROG`
+prog=`$AWK ' /#TEST7#/, /#TEST8#/' $AWKPROG`
$AWK "$prog" $AWKPROG $SCRIPT
echo "--Test 8--"
-prog=`$AWK '/#TEST8#/, /#TEST9#/' $AWKPROG`
+prog=`$AWK ' /#TEST8#/, /#TEST9#/' $AWKPROG`
$AWK "$prog" $AWKPROG
echo "--Test 9a--"
-prog=`$AWK '/#TEST9#/, /#TEST10#/' $AWKPROG`
-$AWK "$prog" /file/does/not/exist $AWKPROG
+prog=`$AWK ' /#TEST9#/, /#TEST10#/' $AWKPROG`
+$AWK "$prog" file/does/not/exist $AWKPROG
echo "--Test 9b--"
-$AWK -vskip=1 "$prog" /file/does/not/exist $AWKPROG
+$AWK -vskip=1 "$prog" file/does/not/exist $AWKPROG
echo "--Test 10--"
-prog=`$AWK '/#TEST10#/, /#TEST11#/' $AWKPROG`
+prog=`$AWK ' /#TEST10#/, /#TEST11#/' $AWKPROG`
$AWK "$prog" $AWKPROG $SCRIPT
echo "--Test 11--"
-prog=`$AWK '/#TEST11#/, /#TEST12#/' $AWKPROG`
+prog=`$AWK ' /#TEST11#/, /#TEST12#/' $AWKPROG`
$AWK "$prog" $AWKPROG $SCRIPT
echo "--Test 12--"
-prog=`$AWK '/#TEST12#/, /#TEST13#/' $AWKPROG`
+prog=`$AWK ' /#TEST12#/, /#TEST13#/' $AWKPROG`
$AWK "$prog" $AWKPROG $SCRIPT
echo "--Test 13--"
-prog=`$AWK '/#TEST13#/, /#TEST14#/' $AWKPROG`
+prog=`$AWK ' /#TEST13#/, /#TEST14#/' $AWKPROG`
$AWK "$prog" $AWKPROG $SCRIPT
echo "--Test 14--"
-prog=`$AWK '/#TEST14#/, /#TEST15#/' $AWKPROG`
+prog=`$AWK ' /#TEST14#/, /#TEST15#/' $AWKPROG`
$AWK "$prog" $AWKPROG $SCRIPT
echo "--Test 15--"
-prog=`$AWK '/#TEST15#/, /#TEST16#/' $AWKPROG`
+prog=`$AWK ' /#TEST15#/, /#TEST16#/' $AWKPROG`
$AWK "$prog" $AWKPROG $SCRIPT
echo "--Test 16--"
-prog=`$AWK '/#TEST16#/, /#TEST17#/' $AWKPROG`
+prog=`$AWK ' /#TEST16#/, /#TEST17#/' $AWKPROG`
$AWK "$prog" $AWKPROG $SCRIPT
diff --git a/test/charasbytes.awk b/test/charasbytes.awk
new file mode 100755
index 00000000..feb195c8
--- /dev/null
+++ b/test/charasbytes.awk
@@ -0,0 +1 @@
+{ print gensub(/\xE2\x80./, "ZZZ", "g", $0) }
diff --git a/test/charasbytes.in b/test/charasbytes.in
new file mode 100644
index 00000000..4a8d4a1e
--- /dev/null
+++ b/test/charasbytes.in
@@ -0,0 +1 @@
+–
diff --git a/test/charasbytes.ok b/test/charasbytes.ok
new file mode 100644
index 00000000..f60f2ab4
--- /dev/null
+++ b/test/charasbytes.ok
@@ -0,0 +1,3 @@
+0000000 Z Z Z \n
+ 5a 5a 5a 0a
+0000004
diff --git a/test/clos1way.awk b/test/clos1way.awk
index 5bc40684..c9dab09a 100644
--- a/test/clos1way.awk
+++ b/test/clos1way.awk
@@ -1,5 +1,5 @@
BEGIN {
- command = "LC_ALL=C sort"
+ command = "sort"
n = split("abcdefghijklmnopqrstuvwxyz", a, "")
for (i = n; i > 0; i--) {
diff --git a/test/colonwarn.awk b/test/colonwarn.awk
new file mode 100644
index 00000000..0b0650e0
--- /dev/null
+++ b/test/colonwarn.awk
@@ -0,0 +1,4 @@
+BEGIN { pattern = ARGV[1] + 0; delete ARGV }
+pattern == 1 { sub(/[][:space:]]/,""); print }
+pattern == 2 { sub(/[\][:space:]]/,""); print }
+pattern == 3 { sub(/[^][:space:]]/,""); print }
diff --git a/test/colonwarn.in b/test/colonwarn.in
new file mode 100644
index 00000000..d34368d7
--- /dev/null
+++ b/test/colonwarn.in
@@ -0,0 +1 @@
+a]b
diff --git a/test/colonwarn.ok b/test/colonwarn.ok
new file mode 100644
index 00000000..d084ee3d
--- /dev/null
+++ b/test/colonwarn.ok
@@ -0,0 +1,3 @@
+ab
+ab
+]b
diff --git a/test/dbugeval.in b/test/dbugeval.in
new file mode 100644
index 00000000..6a3c2459
--- /dev/null
+++ b/test/dbugeval.in
@@ -0,0 +1,2 @@
+eval ""
+eval ""
diff --git a/test/dbugeval.ok b/test/dbugeval.ok
new file mode 100644
index 00000000..284f2abb
--- /dev/null
+++ b/test/dbugeval.ok
@@ -0,0 +1 @@
+EXIT CODE: 2
diff --git a/test/dfamb1.awk b/test/dfamb1.awk
new file mode 100644
index 00000000..7647adf5
--- /dev/null
+++ b/test/dfamb1.awk
@@ -0,0 +1,4 @@
+# The first of these used to core dump gawk. As of 7/2013 it's fixed.
+# This file is to make sure that remains true.
+{match($0, /(([^ \?.]*\?pos=ad |([^ \?.]*\?pos=(jj|va) )地\?pos=dev ){0,2})/ , arr)} { if(arr[0]) print arr[1], arr[4], $6}
+{match($0, /(([^ \?.]*\?pos=ad |([^ \?.]*\?pos=(jj|va) )[地]\?pos=dev ){0,2})/ , arr)} { if(arr[0]) print arr[1], arr[4], $6}
diff --git a/test/dfamb1.in b/test/dfamb1.in
new file mode 100644
index 00000000..8347590f
--- /dev/null
+++ b/test/dfamb1.in
@@ -0,0 +1 @@
+很?pos=ad 宽广?pos=va , 更?pos=ad 是?pos=vc1
diff --git a/test/dfamb1.ok b/test/dfamb1.ok
new file mode 100644
index 00000000..ad443a23
--- /dev/null
+++ b/test/dfamb1.ok
@@ -0,0 +1,2 @@
+很?pos=ad
+很?pos=ad
diff --git a/test/dumpvars.ok b/test/dumpvars.ok
index 01d5fb78..73d3d306 100644
--- a/test/dumpvars.ok
+++ b/test/dumpvars.ok
@@ -16,7 +16,9 @@ NR: 3
OFMT: "%.6g"
OFS: " "
ORS: "\n"
+PREC: 53
RLENGTH: 0
+ROUNDMODE: "N"
RS: "\n"
RSTART: 0
RT: "\n"
diff --git a/test/exit2.awk b/test/exit2.awk
new file mode 100644
index 00000000..ffbb0430
--- /dev/null
+++ b/test/exit2.awk
@@ -0,0 +1,2 @@
+function _fn0() { exit }
+BEGIN { ARRAY[_fn0()] }
diff --git a/test/exit2.ok b/test/exit2.ok
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/exit2.ok
diff --git a/test/filefuncs.awk b/test/filefuncs.awk
new file mode 100644
index 00000000..7aa5ae6a
--- /dev/null
+++ b/test/filefuncs.awk
@@ -0,0 +1,25 @@
+@load "filefuncs"
+
+BEGIN {
+ if (chdir(builddir) < 0) {
+ printf "Error: chdir failed with ERRNO %s\n", ERRNO
+ exit 1
+ }
+
+ if (stat(ARGV[0] "api.o", st) < 0) {
+ printf "Error: stat(%s) failed with ERRNO %s\n", ARGV[0] "api.o", ERRNO
+ exit 1
+ }
+
+ nf = split("name dev ino mode nlink uid gid size blocks atime mtime ctime pmode type", f)
+
+ for (i = 1; i <= nf; i++) {
+ if (!(f[i] in st)) {
+ printf "stat value for %s is missing\n",f[i]
+ rc = 1
+ }
+ else
+ delete st[f[i]]
+ }
+ exit rc+0
+}
diff --git a/test/filefuncs.ok b/test/filefuncs.ok
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/filefuncs.ok
diff --git a/test/fmtspcl-mpfr.ok b/test/fmtspcl-mpfr.ok
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/fmtspcl-mpfr.ok
diff --git a/test/fnarydel-mpfr.ok b/test/fnarydel-mpfr.ok
new file mode 100644
index 00000000..7f3e4531
--- /dev/null
+++ b/test/fnarydel-mpfr.ok
@@ -0,0 +1,27 @@
+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
diff --git a/test/fnmatch.awk b/test/fnmatch.awk
new file mode 100644
index 00000000..b3717549
--- /dev/null
+++ b/test/fnmatch.awk
@@ -0,0 +1,13 @@
+@load "fnmatch"
+
+BEGIN {
+ # can't print the values; they vary from system to system
+ for (i in FNM)
+ printf("\"%s\" is an element in FNM\n", i)
+ # can't even print this
+ # print "FNM_NOMATCH =", FNM_NOMATCH
+
+ printf("fnmatch(\"*.a\", \"foo.a\", 0) = %d\n", fnmatch("*.a", "foo.a", 0) )
+ if (fnmatch("*.a", "foo.c", 0) == FNM_NOMATCH)
+ printf("fnmatch(\"*.a\", \"foo.c\", 0) == FNM_NOMATCH\n")
+}
diff --git a/test/fnmatch.ok b/test/fnmatch.ok
new file mode 100644
index 00000000..15bb1916
--- /dev/null
+++ b/test/fnmatch.ok
@@ -0,0 +1,8 @@
+"LEADING_DIR" is an element in FNM
+"CASEFOLD" is an element in FNM
+"NOESCAPE" is an element in FNM
+"PERIOD" is an element in FNM
+"PATHNAME" is an element in FNM
+"FILE_NAME" is an element in FNM
+fnmatch("*.a", "foo.a", 0) = 0
+fnmatch("*.a", "foo.c", 0) == FNM_NOMATCH
diff --git a/test/fnparydl-mpfr.ok b/test/fnparydl-mpfr.ok
new file mode 100644
index 00000000..26a5c390
--- /dev/null
+++ b/test/fnparydl-mpfr.ok
@@ -0,0 +1,10 @@
+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[]
diff --git a/test/fork.awk b/test/fork.awk
new file mode 100644
index 00000000..0b29f9ff
--- /dev/null
+++ b/test/fork.awk
@@ -0,0 +1,33 @@
+@load "fork"
+
+BEGIN {
+ fn = ("fork.tmp." PROCINFO["pid"])
+ switch (pid = fork()) {
+ case -1:
+ printf "Error: fork failed with ERRNO %s\n", ERRNO
+ exit 1
+ case 0:
+ # child
+ printf "pid %s ppid %s\n", PROCINFO["pid"], PROCINFO["ppid"] > fn
+ exit 0
+ default:
+ # parent
+ erc = 1
+ if ((rc = wait()) < 0)
+ printf "Error: wait failed with ERRNO %s\n", ERRNO
+ else if (rc != pid)
+ printf "Error: wait returned %s instead of child pid %s\n", rc, pid
+ else if ((getline x < fn) != 1)
+ printf "Error: getline failed on temp file %s\n", fn
+ else {
+ expected = ("pid " pid " ppid " PROCINFO["pid"])
+ if (x != expected)
+ printf "Error: child data (%s) != expected (%s)\n", x, expected
+ else if ((rc = system("rm " fn)) != 0)
+ printf "Error removing temp file %s with ERRNO %s\n", fn, ERRNO
+ else
+ erc = 0
+ }
+ exit erc
+ }
+}
diff --git a/test/fork.ok b/test/fork.ok
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/fork.ok
diff --git a/test/fork2.awk b/test/fork2.awk
new file mode 100644
index 00000000..bd364286
--- /dev/null
+++ b/test/fork2.awk
@@ -0,0 +1,35 @@
+@load "fork"
+
+BEGIN {
+ # avoid instantiating PROCINFO prior to the fork
+ switch (pid = fork()) {
+ case -1:
+ printf "Error: fork failed with ERRNO %s\n", ERRNO
+ exit 1
+ case 0:
+ # child
+ fn = ("fork.tmp." PROCINFO["pid"])
+ printf "pid %s ppid %s\n", PROCINFO["pid"], PROCINFO["ppid"] > fn
+ exit 0
+ default:
+ # parent
+ erc = 1
+ fn = ("fork.tmp." pid)
+ if ((rc = wait()) < 0)
+ printf "Error: wait failed with ERRNO %s\n", ERRNO
+ else if (rc != pid)
+ printf "Error: wait returned %s instead of child pid %s\n", rc, pid
+ else if ((getline x < fn) != 1)
+ printf "Error: getline failed on temp file %s\n", fn
+ else {
+ expected = ("pid " pid " ppid " PROCINFO["pid"])
+ if (x != expected)
+ printf "Error: child data (%s) != expected (%s)\n", x, expected
+ else if ((rc = system("rm " fn)) != 0)
+ printf "Error removing temp file %s with ERRNO %s\n", fn, ERRNO
+ else
+ erc = 0
+ }
+ exit erc
+ }
+}
diff --git a/test/fork2.ok b/test/fork2.ok
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/fork2.ok
diff --git a/test/fts.awk b/test/fts.awk
new file mode 100644
index 00000000..70af560f
--- /dev/null
+++ b/test/fts.awk
@@ -0,0 +1,146 @@
+@load "filefuncs"
+
+BEGIN {
+ Level = 0
+
+ os = ""
+ if (ENVIRON["AWKLIBPATH"] == "sys$disk:[-]") {
+ os = "VMS"
+ system("create/dir/prot=o:rwed [.d1]")
+ system("create/dir/prot=o:rwed [.d2]")
+ system("copy fts.awk [.d1]f1")
+ system("copy fts.awk [.d1]f2")
+ system("copy fts.awk [.d2]f1")
+ system("copy fts.awk [.d2]f2")
+ } else {
+ system("rm -fr d1 d2")
+ system("mkdir d1 d2 ; touch d1/f1 d1/f2 d2/f1 d2/f2")
+ }
+ pathlist[1] = "d1"
+ pathlist[2] = "d2"
+ flags = FTS_PHYSICAL
+ fts(pathlist, flags, data)
+
+ output = "fts.ok"
+ traverse(data)
+ close(output)
+
+ ftswalk(pathlist, data2)
+ output = "_fts"
+ traverse(data2)
+ close(output)
+
+ if (os == "VMS") {
+ system("delete [.d1]*.*;*")
+ system("delete [.d2]*.*;*")
+ system("delete d1.dir;*")
+ system("delete d2.dir;*")
+ } else {
+ system("rm -fr d1 d2")
+ }
+}
+
+function indent( i)
+{
+ for (i = 1; i <= Level; i++)
+ printf("\t") > output
+}
+
+function sort_traverse(data, sorted, i)
+{
+ asorti(data, sorted)
+ for (i = 1; i in sorted; i++) {
+ indent()
+ printf("%s --> %s\n", sorted[i], data[sorted[i]]) > output
+ }
+}
+
+function traverse(data, i)
+{
+ for (i in data) {
+ if (isarray(data[i])) {
+ indent()
+ printf("%s:\n", i) > output
+
+ Level++
+ if (("mtime" in data[i]) && ! isarray(data[i][mtime])) {
+ sort_traverse(data[i])
+ } else {
+ traverse(data[i])
+ }
+ Level--
+ } else {
+ indent()
+ printf("%s --> %s\n", i, data[i]) > output
+ }
+ }
+}
+
+
+function ftswalk(pathlist, data, i, toppath)
+{
+ delete data
+ for (i = 1; i in pathlist; i++) {
+ toppath = pathlist[i]
+ data[toppath]["junk"]++ # create array
+ delete data[toppath]["junk"]
+ process(pathlist[i], data)
+ }
+}
+
+# enter process with pathname, array for that path already created but
+# empty
+
+function process(pathname, data_array,
+ stat_data, i, direntry, command, shortname) # locals
+{
+ stat(pathname, stat_data)
+ if (stat_data["type"] == "file") {
+ shortname = strrstr(pathname, "/")
+ data_array["path"] = pathname
+ for (i in stat_data) {
+ if (i == "name")
+ data_array["stat"][i] = shortname
+ else
+ data_array["stat"][i] = stat_data[i]
+ }
+
+ return
+ }
+
+ # stuff for a directory
+
+ data_array[pathname]["."]["path"] = pathname
+ for (i in stat_data)
+ data_array[pathname]["."]["stat"][i] = stat_data[i]
+
+ os = ""
+ if (ENVIRON["AWKLIBPATH"] == "sys$disk:[-]") {
+ os = "VMS"
+ # Command in next section not valid on VMS.
+ return
+ }
+
+ command = ("ls -f " pathname)
+ while ((command | getline direntry) > 0) {
+ if (direntry == "." || direntry == "..")
+ continue
+ data_array[pathname][direntry]["junk"]++
+ delete data_array[pathname][direntry]["junk"]
+ process(pathname "/" direntry,
+ data_array[pathname][direntry])
+ }
+ close(command)
+}
+
+function strrstr(string, delim, ind)
+{
+ if ((ind = index(string, delim)) == 0)
+ return string
+
+ do {
+ string = substr(string, ind + 1)
+ } while ((ind = index(string, delim)) > 0)
+
+ return string
+}
diff --git a/test/functab1.awk b/test/functab1.awk
new file mode 100644
index 00000000..05692684
--- /dev/null
+++ b/test/functab1.awk
@@ -0,0 +1,3 @@
+BEGIN {
+ delete FUNCTAB
+}
diff --git a/test/functab1.ok b/test/functab1.ok
new file mode 100644
index 00000000..2a60a4cb
--- /dev/null
+++ b/test/functab1.ok
@@ -0,0 +1,2 @@
+gawk: functab1.awk:3: fatal: `delete' is not allowed with FUNCTAB
+EXIT CODE: 2
diff --git a/test/functab2.awk b/test/functab2.awk
new file mode 100644
index 00000000..9a07dfc3
--- /dev/null
+++ b/test/functab2.awk
@@ -0,0 +1,8 @@
+function foo()
+{
+ print "foo!"
+}
+
+BEGIN {
+ FUNCTAB["a"] = "something"
+}
diff --git a/test/functab2.ok b/test/functab2.ok
new file mode 100644
index 00000000..32b07ad3
--- /dev/null
+++ b/test/functab2.ok
@@ -0,0 +1,2 @@
+gawk: functab2.awk:7: fatal: cannot assign to elements of FUNCTAB
+EXIT CODE: 2
diff --git a/test/functab3.awk b/test/functab3.awk
new file mode 100644
index 00000000..98fa49b1
--- /dev/null
+++ b/test/functab3.awk
@@ -0,0 +1,10 @@
+function foo()
+{
+ print "foo!"
+}
+
+BEGIN {
+ x = FUNCTAB["foo"]
+ print "x =", x
+ @x()
+}
diff --git a/test/functab3.ok b/test/functab3.ok
new file mode 100644
index 00000000..66f53d72
--- /dev/null
+++ b/test/functab3.ok
@@ -0,0 +1,2 @@
+x = foo
+foo!
diff --git a/test/functab4.awk b/test/functab4.awk
new file mode 100644
index 00000000..196fcc6d
--- /dev/null
+++ b/test/functab4.awk
@@ -0,0 +1,30 @@
+@load "filefuncs"
+
+function foo()
+{
+ print "foo!"
+}
+
+BEGIN {
+ f = FUNCTAB["foo"]
+ @f()
+
+ ret1 = stat(".", data1)
+ print "ret1 =", ret1
+
+ f = "stat"
+ ret2 = @f(".", data2)
+ print "ret2 =", ret2
+
+ problem = 0
+ for (i in data1) {
+ if (! isarray(data1[i])) {
+# print i, data1[i]
+ if (! (i in data2) || data1[i] != data2[i]) {
+ printf("mismatch element \"%s\"\n", i)
+ problems++
+ }
+ }
+ }
+ print(problems ? (problems+0) "encountered" : "no problems encountered")
+}
diff --git a/test/functab4.ok b/test/functab4.ok
new file mode 100644
index 00000000..2b76cd88
--- /dev/null
+++ b/test/functab4.ok
@@ -0,0 +1,4 @@
+foo!
+ret1 = 0
+ret2 = 0
+no problems encountered
diff --git a/test/genpot.awk b/test/genpot.awk
new file mode 100644
index 00000000..990b0b5c
--- /dev/null
+++ b/test/genpot.awk
@@ -0,0 +1 @@
+{print _"This string is so long that gawk --gen-pot will break it and lose a letter at the break."}
diff --git a/test/genpot.ok b/test/genpot.ok
new file mode 100644
index 00000000..35c0cc99
--- /dev/null
+++ b/test/genpot.ok
@@ -0,0 +1,5 @@
+#: genpot.awk:1
+msgid "This string is so long that gawk --gen-pot will break it and lose a l"
+"etter at the break."
+msgstr ""
+
diff --git a/test/gensub2.ok b/test/gensub2.ok
index 89824140..318f940c 100644
--- a/test/gensub2.ok
+++ b/test/gensub2.ok
@@ -1,3 +1,4 @@
xy
xy
+gawk: gensub2.awk:4: warning: gensub: third argument `a' treated as 1
yx
diff --git a/test/getline5.awk b/test/getline5.awk
new file mode 100644
index 00000000..4757bcfe
--- /dev/null
+++ b/test/getline5.awk
@@ -0,0 +1,35 @@
+# Message-ID: <4F7832BD.9030709@gmx.com>
+# Date: Sun, 01 Apr 2012 11:49:33 +0100
+# From: Duncan Moore <duncan.moore@gmx.com>
+# To: "bug-gawk@gnu.org" <bug-gawk@gnu.org>
+# Subject: [bug-gawk] getline difference from gawk versions >=4.0.0
+#
+# Hi
+#
+# b.awk:
+#
+# BEGIN {
+# system("echo 1 > f")
+# while ((getline a[++c] < "f") > 0) {}
+# print c
+# }
+#
+# gawk -f b.awk
+#
+# Prior to gawk 4.0.0 this outputs:
+#
+# 1
+#
+# For 4.0.0 and 4.0.1 it outputs:
+#
+# 2
+#
+# Regards
+# Duncan Moore
+
+BEGIN {
+ system("echo 1 > f")
+ while ((getline a[++c] < "f") > 0) {}
+ print c
+ system("rm -f f")
+}
diff --git a/test/getline5.ok b/test/getline5.ok
new file mode 100644
index 00000000..0cfbf088
--- /dev/null
+++ b/test/getline5.ok
@@ -0,0 +1 @@
+2
diff --git a/test/hello.awk b/test/hello.awk
new file mode 100644
index 00000000..9e6d569d
--- /dev/null
+++ b/test/hello.awk
@@ -0,0 +1,3 @@
+BEGIN {
+ print "Hello"
+}
diff --git a/test/id.awk b/test/id.awk
new file mode 100644
index 00000000..2a35e42c
--- /dev/null
+++ b/test/id.awk
@@ -0,0 +1,11 @@
+function function1()
+{
+ print "function1"
+}
+
+BEGIN {
+ an_array[1] = 1
+
+ for (i in PROCINFO["identifiers"])
+ printf("%s -> %s\n", i, PROCINFO["identifiers"][i])
+}
diff --git a/test/id.ok b/test/id.ok
new file mode 100644
index 00000000..fb77f457
--- /dev/null
+++ b/test/id.ok
@@ -0,0 +1,74 @@
+OFS -> scalar
+rand -> builtin
+ARGC -> scalar
+dcgettext -> builtin
+gsub -> builtin
+PREC -> scalar
+match -> builtin
+ARGIND -> scalar
+int -> builtin
+ERRNO -> scalar
+ARGV -> array
+log -> builtin
+sprintf -> builtin
+ROUNDMODE -> scalar
+strftime -> builtin
+systime -> builtin
+and -> builtin
+srand -> builtin
+FNR -> scalar
+asort -> builtin
+atan2 -> builtin
+cos -> builtin
+TEXTDOMAIN -> scalar
+ORS -> scalar
+split -> builtin
+div -> builtin
+RSTART -> scalar
+compl -> builtin
+bindtextdomain -> builtin
+exp -> builtin
+or -> builtin
+fflush -> builtin
+gensub -> builtin
+LINT -> scalar
+dcngettext -> builtin
+index -> builtin
+IGNORECASE -> scalar
+system -> builtin
+CONVFMT -> scalar
+sqrt -> builtin
+rshift -> builtin
+tolower -> builtin
+FS -> scalar
+BINMODE -> scalar
+sin -> builtin
+asorti -> builtin
+FIELDWIDTHS -> scalar
+function1 -> user
+FILENAME -> scalar
+close -> builtin
+mktime -> builtin
+FUNCTAB -> array
+NF -> scalar
+isarray -> builtin
+an_array -> untyped
+patsplit -> builtin
+NR -> scalar
+SUBSEP -> scalar
+extension -> builtin
+i -> untyped
+sub -> builtin
+OFMT -> scalar
+RLENGTH -> scalar
+substr -> builtin
+FPAT -> scalar
+RS -> scalar
+xor -> builtin
+RT -> scalar
+PROCINFO -> array
+lshift -> builtin
+SYMTAB -> array
+strtonum -> builtin
+toupper -> builtin
+ENVIRON -> array
diff --git a/test/incdupe.ok b/test/incdupe.ok
new file mode 100644
index 00000000..63c85e41
--- /dev/null
+++ b/test/incdupe.ok
@@ -0,0 +1,3 @@
+gawk: warning: already included source file `inclib.awk'
+Include library loaded.
+abc
diff --git a/test/incdupe2.ok b/test/incdupe2.ok
new file mode 100644
index 00000000..11787238
--- /dev/null
+++ b/test/incdupe2.ok
@@ -0,0 +1,2 @@
+gawk: inclib.awk:5: error: function name `sandwich' previously defined
+EXIT CODE: 1
diff --git a/test/incdupe3.ok b/test/incdupe3.ok
new file mode 100644
index 00000000..af17d2f8
--- /dev/null
+++ b/test/incdupe3.ok
@@ -0,0 +1,2 @@
+Hello
+Hello
diff --git a/test/incdupe4.ok b/test/incdupe4.ok
new file mode 100644
index 00000000..a6fc26e2
--- /dev/null
+++ b/test/incdupe4.ok
@@ -0,0 +1,2 @@
+gawk: fatal: can't include `hello.awk' and use it as a program file
+EXIT CODE: 2
diff --git a/test/incdupe5.ok b/test/incdupe5.ok
new file mode 100644
index 00000000..a6fc26e2
--- /dev/null
+++ b/test/incdupe5.ok
@@ -0,0 +1,2 @@
+gawk: fatal: can't include `hello.awk' and use it as a program file
+EXIT CODE: 2
diff --git a/test/incdupe6.ok b/test/incdupe6.ok
new file mode 100644
index 00000000..42a4f9fd
--- /dev/null
+++ b/test/incdupe6.ok
@@ -0,0 +1,3 @@
+gawk: inchello:1: warning: `include' is a gawk extension
+gawk: inchello:2: fatal: can't include `hello' and use it as a program file
+EXIT CODE: 2
diff --git a/test/incdupe7.ok b/test/incdupe7.ok
new file mode 100644
index 00000000..42a4f9fd
--- /dev/null
+++ b/test/incdupe7.ok
@@ -0,0 +1,3 @@
+gawk: inchello:1: warning: `include' is a gawk extension
+gawk: inchello:2: fatal: can't include `hello' and use it as a program file
+EXIT CODE: 2
diff --git a/test/inchello.awk b/test/inchello.awk
new file mode 100644
index 00000000..148d4bef
--- /dev/null
+++ b/test/inchello.awk
@@ -0,0 +1 @@
+@include "hello"
diff --git a/test/inclib.awk b/test/inclib.awk
new file mode 100644
index 00000000..51785283
--- /dev/null
+++ b/test/inclib.awk
@@ -0,0 +1,7 @@
+BEGIN {
+ print "Include library loaded."
+}
+
+function sandwich(pfx,x,sfx) {
+ return (pfx x sfx)
+}
diff --git a/test/include.awk b/test/include.awk
new file mode 100644
index 00000000..8fc7837d
--- /dev/null
+++ b/test/include.awk
@@ -0,0 +1,5 @@
+@include "inclib.awk"
+
+BEGIN {
+ print sandwich("a", "b", "c")
+}
diff --git a/test/include.ok b/test/include.ok
new file mode 100644
index 00000000..a720efca
--- /dev/null
+++ b/test/include.ok
@@ -0,0 +1,2 @@
+Include library loaded.
+abc
diff --git a/test/include2.ok b/test/include2.ok
new file mode 100644
index 00000000..a720efca
--- /dev/null
+++ b/test/include2.ok
@@ -0,0 +1,2 @@
+Include library loaded.
+abc
diff --git a/test/indirectcall2.awk b/test/indirectcall2.awk
new file mode 100644
index 00000000..8f3c9483
--- /dev/null
+++ b/test/indirectcall2.awk
@@ -0,0 +1,11 @@
+BEGIN {
+ Quarter_pi = 3.1415927 / 4
+ print sin(Quarter_pi)
+
+ f = "sin"
+ print @f(Quarter_pi)
+
+ print substr("abcdefgh", 2, 3)
+ f = "substr"
+ print @f("abcdefgh", 2, 3)
+}
diff --git a/test/indirectcall2.ok b/test/indirectcall2.ok
new file mode 100644
index 00000000..05bee4b1
--- /dev/null
+++ b/test/indirectcall2.ok
@@ -0,0 +1,4 @@
+0.707107
+0.707107
+bcd
+bcd
diff --git a/test/inplace.1.in b/test/inplace.1.in
new file mode 100644
index 00000000..d87f79a1
--- /dev/null
+++ b/test/inplace.1.in
@@ -0,0 +1,2 @@
+is foo replaced?
+and again foo here?
diff --git a/test/inplace.2.in b/test/inplace.2.in
new file mode 100644
index 00000000..4644a915
--- /dev/null
+++ b/test/inplace.2.in
@@ -0,0 +1,2 @@
+another input file containing foo and foo and more foo
+but nothing to replace here
diff --git a/test/inplace.in b/test/inplace.in
new file mode 100644
index 00000000..bf2cf989
--- /dev/null
+++ b/test/inplace.in
@@ -0,0 +1,3 @@
+stdin start
+is foo replaced?
+stdin end
diff --git a/test/inplace1.1.ok b/test/inplace1.1.ok
new file mode 100644
index 00000000..8faa542e
--- /dev/null
+++ b/test/inplace1.1.ok
@@ -0,0 +1,2 @@
+is bar replaced?
+and again bar here?
diff --git a/test/inplace1.2.ok b/test/inplace1.2.ok
new file mode 100644
index 00000000..64427be3
--- /dev/null
+++ b/test/inplace1.2.ok
@@ -0,0 +1,2 @@
+another input file containing bar and bar and more bar
+but nothing to replace here
diff --git a/test/inplace1.ok b/test/inplace1.ok
new file mode 100644
index 00000000..ffcb768d
--- /dev/null
+++ b/test/inplace1.ok
@@ -0,0 +1,6 @@
+before
+gawk: inplace:9: warning: inplace_begin: disabling in-place editing for invalid FILENAME `-'
+stdin start
+is bar replaced?
+stdin end
+after
diff --git a/test/inplace2.1.bak.ok b/test/inplace2.1.bak.ok
new file mode 100644
index 00000000..d87f79a1
--- /dev/null
+++ b/test/inplace2.1.bak.ok
@@ -0,0 +1,2 @@
+is foo replaced?
+and again foo here?
diff --git a/test/inplace2.1.ok b/test/inplace2.1.ok
new file mode 100644
index 00000000..8faa542e
--- /dev/null
+++ b/test/inplace2.1.ok
@@ -0,0 +1,2 @@
+is bar replaced?
+and again bar here?
diff --git a/test/inplace2.2.bak.ok b/test/inplace2.2.bak.ok
new file mode 100644
index 00000000..4644a915
--- /dev/null
+++ b/test/inplace2.2.bak.ok
@@ -0,0 +1,2 @@
+another input file containing foo and foo and more foo
+but nothing to replace here
diff --git a/test/inplace2.2.ok b/test/inplace2.2.ok
new file mode 100644
index 00000000..64427be3
--- /dev/null
+++ b/test/inplace2.2.ok
@@ -0,0 +1,2 @@
+another input file containing bar and bar and more bar
+but nothing to replace here
diff --git a/test/inplace2.ok b/test/inplace2.ok
new file mode 100644
index 00000000..ffcb768d
--- /dev/null
+++ b/test/inplace2.ok
@@ -0,0 +1,6 @@
+before
+gawk: inplace:9: warning: inplace_begin: disabling in-place editing for invalid FILENAME `-'
+stdin start
+is bar replaced?
+stdin end
+after
diff --git a/test/inplace3.1.bak.ok b/test/inplace3.1.bak.ok
new file mode 100644
index 00000000..8faa542e
--- /dev/null
+++ b/test/inplace3.1.bak.ok
@@ -0,0 +1,2 @@
+is bar replaced?
+and again bar here?
diff --git a/test/inplace3.1.ok b/test/inplace3.1.ok
new file mode 100644
index 00000000..d87f79a1
--- /dev/null
+++ b/test/inplace3.1.ok
@@ -0,0 +1,2 @@
+is foo replaced?
+and again foo here?
diff --git a/test/inplace3.2.bak.ok b/test/inplace3.2.bak.ok
new file mode 100644
index 00000000..64427be3
--- /dev/null
+++ b/test/inplace3.2.bak.ok
@@ -0,0 +1,2 @@
+another input file containing bar and bar and more bar
+but nothing to replace here
diff --git a/test/inplace3.2.ok b/test/inplace3.2.ok
new file mode 100644
index 00000000..4644a915
--- /dev/null
+++ b/test/inplace3.2.ok
@@ -0,0 +1,2 @@
+another input file containing foo and foo and more foo
+but nothing to replace here
diff --git a/test/inplace3.ok b/test/inplace3.ok
new file mode 100644
index 00000000..7cd960bc
--- /dev/null
+++ b/test/inplace3.ok
@@ -0,0 +1,12 @@
+before
+gawk: inplace:9: warning: inplace_begin: disabling in-place editing for invalid FILENAME `-'
+stdin start
+is bar replaced?
+stdin end
+after
+Before
+gawk: inplace:9: warning: inplace_begin: disabling in-place editing for invalid FILENAME `-'
+stdin start
+is foo replaced?
+stdin end
+After
diff --git a/test/jarebug.awk b/test/jarebug.awk
new file mode 100644
index 00000000..906d1846
--- /dev/null
+++ b/test/jarebug.awk
@@ -0,0 +1 @@
+/.*/ { gsub ("·½", "ERROR"); print; }
diff --git a/test/jarebug.in b/test/jarebug.in
new file mode 100644
index 00000000..6ce66826
--- /dev/null
+++ b/test/jarebug.in
@@ -0,0 +1,4 @@
+aa·ïa¿·½è
+aaa·ïa¿·½è
+aaaa·ïa¿·½è
+aaaaa·ïa¿·½è
diff --git a/test/jarebug.ok b/test/jarebug.ok
new file mode 100644
index 00000000..6ce66826
--- /dev/null
+++ b/test/jarebug.ok
@@ -0,0 +1,4 @@
+aa·ïa¿·½è
+aaa·ïa¿·½è
+aaaa·ïa¿·½è
+aaaaa·ïa¿·½è
diff --git a/test/jarebug.sh b/test/jarebug.sh
new file mode 100755
index 00000000..6dc728a6
--- /dev/null
+++ b/test/jarebug.sh
@@ -0,0 +1,21 @@
+#! /bin/sh
+
+awk=$1
+prog=$2
+infile=$3
+out=$4
+
+# GLIBC gives us ja_JP.EUC-JP but Mac OS X uses ja_JP.eucJP
+
+cp $infile $out # set up default
+
+for locale in ja_JP.EUC-JP ja_JP.eucJP
+do
+ if locale -a 2>/dev/null | grep $locale > /dev/null
+ then
+ LANG=$locale
+ LC_ALL=$locale
+ export LANG LC_ALL
+ $awk -f $prog $infile >$out 2>&1 || echo EXIT CODE: $? >> $out
+ fi
+done
diff --git a/test/lintwarn.ok b/test/lintwarn.ok
index 169b0020..bc5226e6 100644
--- a/test/lintwarn.ok
+++ b/test/lintwarn.ok
@@ -1,11 +1,9 @@
gawk: lintwarn.awk:2: warning: `BEGINFILE' is a gawk extension
-gawk: lintwarn.awk:3: error: `getline var' invalid inside `BEGINFILE' rule
-gawk: lintwarn.awk:4: error: `getline' invalid inside `BEGINFILE' rule
+gawk: lintwarn.awk:3: error: non-redirected `getline' invalid inside `BEGINFILE' rule
+gawk: lintwarn.awk:4: error: non-redirected `getline' invalid inside `BEGINFILE' rule
gawk: lintwarn.awk:8: warning: statement may have no effect
gawk: lintwarn.awk:9: warning: plain `print' in BEGIN or END rule should probably be `print ""'
-gawk: lintwarn.awk:10: warning: `nextfile' is a gawk extension
gawk: lintwarn.awk:10: error: `nextfile' used in BEGIN action
-gawk: lintwarn.awk:11: warning: `delete array' is a gawk extension
gawk: lintwarn.awk:12: warning: `delete(array)' is a non-portable tawk extension
gawk: lintwarn.awk:13: warning: regular expression on right of assignment
gawk: lintwarn.awk:14: warning: regular expression on right of comparison
@@ -18,6 +16,7 @@ gawk: lintwarn.awk:18: warning: `case' is a gawk extension
gawk: lintwarn.awk:19: warning: `default' is a gawk extension
gawk: lintwarn.awk:19: error: duplicate `default' detected in switch body
gawk: lintwarn.awk:18: error: duplicate case values in switch body: 1
+gawk: lintwarn.awk:24: error: `continue' is not allowed outside a loop
gawk: lintwarn.awk:23: error: `break' is not allowed outside a loop or switch
gawk: lintwarn.awk:24: error: `continue' is not allowed outside a loop
gawk: lintwarn.awk:25: error: `next' used in BEGIN action
diff --git a/test/mbprintf4.awk b/test/mbprintf4.awk
new file mode 100644
index 00000000..1e436bca
--- /dev/null
+++ b/test/mbprintf4.awk
@@ -0,0 +1,35 @@
+# printf with multi-byte text encoding, %c and %s, width and precision, and left-alignment.
+{
+ count = 1
+
+ print NR, count++, "printf %c " $0
+ printf "%d:%d: |%c|\n", NR, count++, $0
+ printf "%d:%d: |%1c|\n", NR, count++, $0
+ printf "%d:%d: |%3c|\n", NR, count++, $0
+ # precision is ignored by %c.
+ printf "%d:%d: |%3.1c|\n", NR, count++, $0
+ printf "%d:%d: |%3.5c|\n", NR, count++, $0
+ print NR, count++, "printf %-c " $0
+ printf "%d:%d: |%-c|\n", NR, count++, $0
+ printf "%d:%d: |%-1c|\n", NR, count++, $0
+ printf "%d:%d: |%-3c|\n", NR, count++, $0
+ # precision is ignored by %c.
+ printf "%d:%d: |%-3.1c|\n", NR, count++, $0
+ printf "%d:%d: |%-3.5c|\n", NR, count++, $0
+ printf ORS
+
+ print NR, count++, "printf %s " $0
+ printf "%d:%d: |%s|\n", NR, count++, $0
+ printf "%d:%d: |%1s|\n", NR, count++, $0
+ printf "%d:%d: |%3s|\n", NR, count++, $0
+ printf "%d:%d: |%3.1s|\n", NR, count++, $0
+ printf "%d:%d: |%3.5s|\n", NR, count++, $0
+
+ print NR, count++, "printf %-s " $0
+ printf "%d:%d: |%-s|\n", NR, count++, $0
+ printf "%d:%d: |%-1s|\n", NR, count++, $0
+ printf "%d:%d: |%-3s|\n", NR, count++, $0
+ printf "%d:%d: |%-3.1s|\n", NR, count++, $0
+ printf "%d:%d: |%-3.5s|\n", NR, count++, $0
+ printf ORS ORS
+}
diff --git a/test/mbprintf4.in b/test/mbprintf4.in
new file mode 100644
index 00000000..c93d40de
--- /dev/null
+++ b/test/mbprintf4.in
@@ -0,0 +1,3 @@
+ú
+último
+áé
diff --git a/test/mbprintf4.ok b/test/mbprintf4.ok
new file mode 100644
index 00000000..e32fe408
--- /dev/null
+++ b/test/mbprintf4.ok
@@ -0,0 +1,81 @@
+1 1 printf %c ú
+1:2: |ú|
+1:3: |ú|
+1:4: | ú|
+1:5: | ú|
+1:6: | ú|
+1 7 printf %-c ú
+1:8: |ú|
+1:9: |ú|
+1:10: |ú |
+1:11: |ú |
+1:12: |ú |
+
+1 13 printf %s ú
+1:14: |ú|
+1:15: |ú|
+1:16: | ú|
+1:17: | ú|
+1:18: | ú|
+1 19 printf %-s ú
+1:20: |ú|
+1:21: |ú|
+1:22: |ú |
+1:23: |ú |
+1:24: |ú |
+
+
+2 1 printf %c último
+2:2: |ú|
+2:3: |ú|
+2:4: | ú|
+2:5: | ú|
+2:6: | ú|
+2 7 printf %-c último
+2:8: |ú|
+2:9: |ú|
+2:10: |ú |
+2:11: |ú |
+2:12: |ú |
+
+2 13 printf %s último
+2:14: |último|
+2:15: |último|
+2:16: |último|
+2:17: | ú|
+2:18: |últim|
+2 19 printf %-s último
+2:20: |último|
+2:21: |último|
+2:22: |último|
+2:23: |ú |
+2:24: |últim|
+
+
+3 1 printf %c áé
+3:2: |á|
+3:3: |á|
+3:4: | á|
+3:5: | á|
+3:6: | á|
+3 7 printf %-c áé
+3:8: |á|
+3:9: |á|
+3:10: |á |
+3:11: |á |
+3:12: |á |
+
+3 13 printf %s áé
+3:14: |áé|
+3:15: |áé|
+3:16: | áé|
+3:17: | á|
+3:18: | áé|
+3 19 printf %-s áé
+3:20: |áé|
+3:21: |áé|
+3:22: |áé |
+3:23: |á |
+3:24: |áé |
+
+
diff --git a/test/messages.awk b/test/messages.awk
index 555f6e38..50f7d91f 100644
--- a/test/messages.awk
+++ b/test/messages.awk
@@ -2,7 +2,7 @@
# 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 "Goes to a file out1" > "_out1"
print "Normal print statement"
print "This printed on stdout" > "/dev/stdout"
print "You blew it!" > "/dev/stderr"
diff --git a/test/mpfrbigint.awk b/test/mpfrbigint.awk
new file mode 100644
index 00000000..bfdd871a
--- /dev/null
+++ b/test/mpfrbigint.awk
@@ -0,0 +1,11 @@
+BEGIN {
+ x = 5^4^3^2
+ print "# of digits =", length(x)
+ print substr(x, 1, 20), "...", substr(x, length(x) - 19, 20)
+
+ PREC = 1 + 3.321928095 * length(x); # 1 + digits * log2(10)
+ print "floating-point computation with precision =", PREC
+ y = 5.0^4.0^3.0^2.0
+ print "# of digits =", length(y)
+ print substr(y, 1, 20), "...", substr(y, length(y) - 19, 20)
+}
diff --git a/test/mpfrbigint.ok b/test/mpfrbigint.ok
new file mode 100644
index 00000000..670d4e07
--- /dev/null
+++ b/test/mpfrbigint.ok
@@ -0,0 +1,5 @@
+# of digits = 183231
+62060698786608744707 ... 92256259918212890625
+floating-point computation with precision = 608681
+# of digits = 183231
+62060698786608744707 ... 92256259918212890625
diff --git a/test/mpfrexprange.awk b/test/mpfrexprange.awk
new file mode 100644
index 00000000..68e95a39
--- /dev/null
+++ b/test/mpfrexprange.awk
@@ -0,0 +1,7 @@
+# test change of allowed exponent range
+BEGIN {
+ x=1.0e-10000
+ print x+0
+ PREC="double"
+ print x+0
+}
diff --git a/test/mpfrexprange.ok b/test/mpfrexprange.ok
new file mode 100644
index 00000000..4700ee22
--- /dev/null
+++ b/test/mpfrexprange.ok
@@ -0,0 +1,2 @@
+1e-10000
+0
diff --git a/test/mpfrieee.awk b/test/mpfrieee.awk
new file mode 100644
index 00000000..dc6e120d
--- /dev/null
+++ b/test/mpfrieee.awk
@@ -0,0 +1,13 @@
+# Test IEEE-754 binary double format
+BEGIN {
+ x = 1.0e-320
+ i = 0
+ while (x > 0) {
+ printf("%.15e\n", x)
+ x /= 2
+
+ # terminate early when the test is going to fail.
+ if (++i > 50)
+ break
+ }
+}
diff --git a/test/mpfrieee.ok b/test/mpfrieee.ok
new file mode 100644
index 00000000..e88f5c79
--- /dev/null
+++ b/test/mpfrieee.ok
@@ -0,0 +1,12 @@
+9.999888671826830e-321
+4.999944335913415e-321
+2.499972167956708e-321
+1.249986083978354e-321
+6.225227137599706e-322
+3.112613568799853e-322
+1.581010066691989e-322
+7.905050333459945e-323
+3.952525166729972e-323
+1.976262583364986e-323
+9.881312916824931e-324
+4.940656458412465e-324
diff --git a/test/mpfrnegzero.awk b/test/mpfrnegzero.awk
new file mode 100644
index 00000000..cc6bf65b
--- /dev/null
+++ b/test/mpfrnegzero.awk
@@ -0,0 +1,15 @@
+BEGIN {
+ printf("-0 -> %f, -0.0 -> %f\n", -0, -0.0)
+
+ printf("atan2(+0, -0) = %f\n", atan2(+0, -0))
+ printf("atan2(+0.0, -0.0) = %f\n", atan2(+0.0, -0.0))
+
+ printf("atan2(-0, -0) = %f\n", atan2(-0, -0))
+ printf("atan2(-0.0, -0.0) = %f\n", atan2(-0.0, -0.0))
+
+ printf("atan2(+0, +0) = %f\n", atan2(+0, +0))
+ printf("atan2(+0.0, +0.0) = %f\n", atan2(+0.0, +0.0))
+
+ printf("atan2(-0, +0) = %f\n", atan2(-0, +0))
+ printf("atan2(-0.0, +0.0) = %f\n", atan2(-0.0, +0.0))
+}
diff --git a/test/mpfrnegzero.ok b/test/mpfrnegzero.ok
new file mode 100644
index 00000000..7af16292
--- /dev/null
+++ b/test/mpfrnegzero.ok
@@ -0,0 +1,9 @@
+-0 -> -0.000000, -0.0 -> -0.000000
+atan2(+0, -0) = 3.141593
+atan2(+0.0, -0.0) = 3.141593
+atan2(-0, -0) = -3.141593
+atan2(-0.0, -0.0) = -3.141593
+atan2(+0, +0) = 0.000000
+atan2(+0.0, +0.0) = 0.000000
+atan2(-0, +0) = -0.000000
+atan2(-0.0, +0.0) = -0.000000
diff --git a/test/mpfrnr.awk b/test/mpfrnr.awk
new file mode 100644
index 00000000..1a3b753a
--- /dev/null
+++ b/test/mpfrnr.awk
@@ -0,0 +1,10 @@
+# Test NR and FNR for file(s) with records > LONG_MAX
+BEGIN {
+ NR = 0x7FFFFFFF
+}
+BEGINFILE {
+ FNR = 0x7fffffffffffffff
+}
+END {
+ print NR, NR-0x7FFFFFFF, FNR, FNR-0x7fffffffffffffff
+}
diff --git a/test/mpfrnr.in b/test/mpfrnr.in
new file mode 100644
index 00000000..6ad36e52
--- /dev/null
+++ b/test/mpfrnr.in
@@ -0,0 +1,3 @@
+Line 1
+Line 2
+Line 3
diff --git a/test/mpfrnr.ok b/test/mpfrnr.ok
new file mode 100644
index 00000000..e472f8bf
--- /dev/null
+++ b/test/mpfrnr.ok
@@ -0,0 +1 @@
+2147483650 3 9223372036854775810 3
diff --git a/test/mpfrrem.awk b/test/mpfrrem.awk
new file mode 100644
index 00000000..fd8bc4d5
--- /dev/null
+++ b/test/mpfrrem.awk
@@ -0,0 +1,6 @@
+BEGIN {
+ print "15 % 7 =", 15 % 7
+ print "15 % -7 =", 15 % -7
+ print "-15 % 7 =", -15 % 7
+ print "-15 % -7 =", -15 % -7
+}
diff --git a/test/mpfrrem.ok b/test/mpfrrem.ok
new file mode 100644
index 00000000..91010457
--- /dev/null
+++ b/test/mpfrrem.ok
@@ -0,0 +1,4 @@
+15 % 7 = 1
+15 % -7 = 1
+-15 % 7 = -1
+-15 % -7 = -1
diff --git a/test/mpfrrnd.awk b/test/mpfrrnd.awk
new file mode 100644
index 00000000..508ac26b
--- /dev/null
+++ b/test/mpfrrnd.awk
@@ -0,0 +1,15 @@
+BEGIN {
+ N = 22/7
+ printf(" %.15f\n", N)
+
+ printf("* %.10f\n", N) # default
+ ROUNDMODE="N"; printf("N %.10f\n", N)
+ ROUNDMODE="U"; printf("U %.10f\n", N)
+ ROUNDMODE="D"; printf("D %.10f\n", N)
+ ROUNDMODE="Z"; printf("Z %.10f\n", N)
+ N = -N
+ ROUNDMODE="N"; printf("N %.10f\n", N)
+ ROUNDMODE="U"; printf("U %.10f\n", N)
+ ROUNDMODE="D"; printf("D %.10f\n", N)
+ ROUNDMODE="Z"; printf("Z %.10f\n", N)
+}
diff --git a/test/mpfrrnd.ok b/test/mpfrrnd.ok
new file mode 100644
index 00000000..fceb937b
--- /dev/null
+++ b/test/mpfrrnd.ok
@@ -0,0 +1,10 @@
+ 3.142857142857143
+* 3.1428571429
+N 3.1428571429
+U 3.1428571429
+D 3.1428571428
+Z 3.1428571428
+N -3.1428571429
+U -3.1428571428
+D -3.1428571429
+Z -3.1428571428
diff --git a/test/mpfrsort.awk b/test/mpfrsort.awk
new file mode 100644
index 00000000..6f7fa65c
--- /dev/null
+++ b/test/mpfrsort.awk
@@ -0,0 +1,8 @@
+BEGIN {
+# s = "1.0 +nan 0.0 -1 +inf -0.0 1 nan 1.0 -nan -inf 2.0"
+ s = "1.0 +nan 0.0 -1 +inf -0.0 1 1.0 -nan -inf 2.0"
+ split(s, a)
+ PROCINFO["sorted_in"] = "@val_num_asc"
+ for (i in a)
+ print a[i]
+}
diff --git a/test/mpfrsort.ok b/test/mpfrsort.ok
new file mode 100644
index 00000000..77a51ecf
--- /dev/null
+++ b/test/mpfrsort.ok
@@ -0,0 +1,11 @@
+-inf
+-1
+-0.0
+0.0
+1
+1.0
+1.0
+2.0
++inf
++nan
+-nan
diff --git a/test/mpfrsqrt.awk b/test/mpfrsqrt.awk
new file mode 100644
index 00000000..23a15c92
--- /dev/null
+++ b/test/mpfrsqrt.awk
@@ -0,0 +1,82 @@
+# Date: Sat, 02 Aug 2014 12:27:00 -0400
+# To: bug-gawk@gnu.org
+# From: Katherine Wasserman <katie@wass.net>
+# Message-ID: <E1XDc9F-0007BX-O1@eggs.gnu.org>
+# Subject: [bug-gawk] GAWK 4.1 SQRT() bug
+#
+# In version 4.1.60 of GAWK the sqrt() function does not work correctly on bignums.
+# Here's a demo of the problem along with, a function that does work correctly.
+#
+# Running this program (sqrt-bug.awk):
+# --------------------------------------------------------------------
+BEGIN {
+a=11111111111111111111111111111111111111111111111111111111111
+print sqrt(a^2)
+#print sq_root(a^2)
+
+# ADR: Added for gawk-4.1-stable which doesn't have built-in div() function
+if (PROCINFO["version"] < "4.1.60")
+ print sq_root2(a^2)
+else
+ print sq_root(a^2)
+}
+
+
+function sq_root(x, temp,r,z)
+{ temp=substr(x,1,length(x)/2) + 0 # a good first guess
+ z=0
+ while (abs(z-temp)>1)
+ { z=temp
+ div(x,temp,r)
+ temp=r["quotient"] + temp
+ div(temp,2,r)
+ temp=r["quotient"]
+ }
+ return temp
+}
+
+function sq_root2(x, temp,r,z)
+{ temp=substr(x,1,length(x)/2) + 0 # a good first guess
+ z=0
+ while (abs(z-temp)>1)
+ { z=temp
+ awk_div(x,temp,r)
+ temp=r["quotient"] + temp
+ awk_div(temp,2,r)
+ temp=r["quotient"]
+ }
+ return temp
+}
+
+function abs(x)
+{ return (x<0 ? -x : x)
+}
+#
+# --------------------------------------------------------------------
+# gawk -M -f sqrt-bug.awk
+#
+# results in:
+# 11111111111111111261130863809439559987542611609749437808640
+# 11111111111111111111111111111111111111111111111111111111111
+#
+# Thanks,
+# Katie
+#
+
+# div --- do integer division
+
+function awk_div(numerator, denominator, result, i, save_PREC)
+{
+ save_PREC = PREC
+ PREC = 400 # good enough for this test
+
+ split("", result)
+
+ numerator = int(numerator)
+ denominator = int(denominator)
+ result["quotient"] = int(numerator / denominator)
+ result["remainder"] = int(numerator % denominator)
+
+ PREC = save_PREC
+ return 0.0
+}
diff --git a/test/mpfrsqrt.ok b/test/mpfrsqrt.ok
new file mode 100644
index 00000000..16217c78
--- /dev/null
+++ b/test/mpfrsqrt.ok
@@ -0,0 +1,2 @@
+11111111111111111111111111111111111111111111111111111111111
+11111111111111111111111111111111111111111111111111111111111
diff --git a/test/nfloop.awk b/test/nfloop.awk
new file mode 100644
index 00000000..c37700ac
--- /dev/null
+++ b/test/nfloop.awk
@@ -0,0 +1,8 @@
+BEGIN {
+ $0 = "aaa"
+ NF = 10
+ for (j = 2; j <= NF; ++j) {
+ $j = "_"
+ }
+ print
+}
diff --git a/test/nfloop.ok b/test/nfloop.ok
new file mode 100644
index 00000000..cc683eae
--- /dev/null
+++ b/test/nfloop.ok
@@ -0,0 +1 @@
+aaa _ _ _ _ _ _ _ _ _
diff --git a/test/ofs1.awk b/test/ofs1.awk
new file mode 100755
index 00000000..83b3c2a5
--- /dev/null
+++ b/test/ofs1.awk
@@ -0,0 +1,23 @@
+# Translate this shell script into gawk:
+#
+#! /bin/sh -
+#
+# awktest()
+# {
+# echo a:b:c | $AWK -F":" '{$2="x"; OFS=FS; print}'
+# echo a:b:c | $AWK -F":" '{$2="x"; print; OFS=FS; print}'
+# echo a:b:c | $AWK -F":" '{$2="x"; print $1; OFS=FS; print}'
+# echo a:b:c | $AWK -F":" '{$2="x"; print; $2=$2; OFS=FS; print}'
+# }
+#
+# AWK=./gawk
+# awktest > foo.gawk
+
+BEGIN { FS = ":" }
+
+# Have to reset OFS at end since not running separate invocations
+
+FNR == 1 { $2 = "x"; OFS = FS; print ; OFS = " "}
+FNR == 2 { $2 = "x"; print; OFS = FS; print ; OFS = " "}
+FNR == 3 { $2 = "x"; print $1; OFS = FS; print ; OFS = " "}
+FNR == 4 { $2 = "x"; print; $2 = $2; OFS = FS; print }
diff --git a/test/ofs1.in b/test/ofs1.in
new file mode 100644
index 00000000..0582b9b1
--- /dev/null
+++ b/test/ofs1.in
@@ -0,0 +1,4 @@
+a:b:c
+a:b:c
+a:b:c
+a:b:c
diff --git a/test/ofs1.ok b/test/ofs1.ok
new file mode 100644
index 00000000..d01fa161
--- /dev/null
+++ b/test/ofs1.ok
@@ -0,0 +1,7 @@
+a x c
+a x c
+a x c
+a
+a x c
+a x c
+a x c
diff --git a/test/ordchr.awk b/test/ordchr.awk
new file mode 100644
index 00000000..0295105e
--- /dev/null
+++ b/test/ordchr.awk
@@ -0,0 +1,10 @@
+@load "ordchr"
+
+BEGIN {
+ print chr(ord("A"))
+ print chr(ord("0"))
+ print ord(chr(65))
+ # test if type conversion between strings and numbers is working properly
+ print chr(ord(0))
+ print ord(chr("65"))
+}
diff --git a/test/ordchr.ok b/test/ordchr.ok
new file mode 100644
index 00000000..86d901e9
--- /dev/null
+++ b/test/ordchr.ok
@@ -0,0 +1,5 @@
+A
+0
+65
+0
+65
diff --git a/test/ordchr2.ok b/test/ordchr2.ok
new file mode 100644
index 00000000..b6802534
--- /dev/null
+++ b/test/ordchr2.ok
@@ -0,0 +1 @@
+z
diff --git a/test/paramuninitglobal.awk b/test/paramuninitglobal.awk
new file mode 100644
index 00000000..0d7989d9
--- /dev/null
+++ b/test/paramuninitglobal.awk
@@ -0,0 +1,15 @@
+function f(x)
+{
+ a = 10
+ x = 90
+ print x
+ print a
+ a++
+ x++
+ print x
+}
+
+BEGIN {
+ f(a)
+ print a
+}
diff --git a/test/paramuninitglobal.ok b/test/paramuninitglobal.ok
new file mode 100644
index 00000000..ce1879d7
--- /dev/null
+++ b/test/paramuninitglobal.ok
@@ -0,0 +1,4 @@
+90
+10
+91
+11
diff --git a/test/parseme.ok b/test/parseme.ok
index b13fcaca..83c0d056 100644
--- a/test/parseme.ok
+++ b/test/parseme.ok
@@ -1,5 +1,5 @@
gawk: parseme.awk:1: BEGIN { toupper(substr*line,1,12)) }
gawk: parseme.awk:1: ^ syntax error
gawk: parseme.awk:1: BEGIN { toupper(substr*line,1,12)) }
-gawk: parseme.awk:1: ^ 2 is invalid as number of arguments for toupper
+gawk: parseme.awk:1: ^ 3 is invalid as number of arguments for toupper
EXIT CODE: 1
diff --git a/test/printfbad3.awk b/test/printfbad3.awk
new file mode 100644
index 00000000..1cabdd76
--- /dev/null
+++ b/test/printfbad3.awk
@@ -0,0 +1,22 @@
+# Date: Wed, 14 Mar 2012 08:10:48 -0500
+# From: John Haque <j.eh@mchsi.com>
+# To: arnold@skeeve.com
+# Subject: gawk printf format bug
+#
+# Hi.
+#
+# I think this is a bug:
+#
+# $ gawk 'BEGIN { printf("%.0x%#x%#x\n", 0, 167, 167)}'
+# 570xa7
+#
+# It should print 0xa70xa7.
+#
+# The solution is to initialize base to 0 in the beginning
+# of the while loop along with other stuff (format_tree).
+#
+# Thanks.
+#
+# John
+
+BEGIN { printf(">>%.0x<< >>%#x<< >>%#x<<\n", 0, 167, 167) }
diff --git a/test/printfbad3.ok b/test/printfbad3.ok
new file mode 100644
index 00000000..a87b0192
--- /dev/null
+++ b/test/printfbad3.ok
@@ -0,0 +1 @@
+>><< >>0xa7<< >>0xa7<<
diff --git a/test/printfbad4.awk b/test/printfbad4.awk
new file mode 100644
index 00000000..dd9220ae
--- /dev/null
+++ b/test/printfbad4.awk
@@ -0,0 +1,5 @@
+BEGIN {
+ for (i = 1; i <= 10; i++) {
+ printf "%03$*d %2$d \n", 4, 5, i
+ }
+}
diff --git a/test/printfbad4.ok b/test/printfbad4.ok
new file mode 100644
index 00000000..71eed3d6
--- /dev/null
+++ b/test/printfbad4.ok
@@ -0,0 +1,2 @@
+gawk: printfbad4.awk:3: fatal: fatal: must use `count$' on all formats or none
+EXIT CODE: 2
diff --git a/test/printhuge.awk b/test/printhuge.awk
new file mode 100644
index 00000000..1de27ecc
--- /dev/null
+++ b/test/printhuge.awk
@@ -0,0 +1,3 @@
+BEGIN {
+ printf("%c\n", sprintf("%c", (0xffffff00+255)))
+}
diff --git a/test/printhuge.ok b/test/printhuge.ok
new file mode 100644
index 00000000..29e181eb
--- /dev/null
+++ b/test/printhuge.ok
@@ -0,0 +1 @@
+ÿ
diff --git a/test/profile2.ok b/test/profile2.ok
index fe76a2c9..938d6858 100644
--- a/test/profile2.ok
+++ b/test/profile2.ok
@@ -1,4 +1,4 @@
- # BEGIN block(s)
+ # BEGIN rule(s)
BEGIN {
1 if (sortcmd == "") {
@@ -7,7 +7,7 @@
1 asplit("BEGIN:END:atan2:break:close:continue:cos:delete:" "do:else:exit:exp:for:getline:gsub:if:in:index:int:" "length:log:match:next:print:printf:rand:return:sin:" "split:sprintf:sqrt:srand:sub:substr:system:while", keywords, ":")
1 split("00:00:00:00:00:00:00:00:00:00:" "20:10:10:12:12:11:07:00:00:00:" "08:08:08:08:08:33:08:00:00:00:" "08:44:08:36:08:08:08:00:00:00:" "08:44:45:42:42:41:08", machine, ":")
1 state = 1
- 571 for (; ; ) {
+ 571 for (;;) {
571 symb = lex()
571 nextstate = substr(machine[state symb], 1, 1)
571 act = substr(machine[state symb], 2, 1)
@@ -109,7 +109,7 @@
571 function lex()
{
- 1702 for (; ; ) {
+ 1702 for (;;) {
1702 if (tok == "(eof)") {
return 7
}
diff --git a/test/profile3.ok b/test/profile3.ok
index 50172c48..bbf06541 100644
--- a/test/profile3.ok
+++ b/test/profile3.ok
@@ -1,4 +1,4 @@
- # BEGIN block(s)
+ # BEGIN rule(s)
BEGIN {
1 the_func = "p"
diff --git a/test/profile4.awk b/test/profile4.awk
new file mode 100644
index 00000000..11a3dbd4
--- /dev/null
+++ b/test/profile4.awk
@@ -0,0 +1,8 @@
+BEGIN {
+ a = ("foo" (c = "bar"))
+ a = (b - c) "foo"
+ a = "foo" (b - c)
+ q = (d = "x") (e = "y")
+ a = ((c = tolower("FOO")) in JUNK)
+ x = (y == 0 && z == 2 && q == 45)
+}
diff --git a/test/profile4.ok b/test/profile4.ok
new file mode 100644
index 00000000..9d2b9430
--- /dev/null
+++ b/test/profile4.ok
@@ -0,0 +1,9 @@
+BEGIN {
+ a = "foo" (c = "bar")
+ a = (b - c) "foo"
+ a = "foo" (b - c)
+ q = (d = "x") (e = "y")
+ a = (c = tolower("FOO")) in JUNK
+ x = y == 0 && z == 2 && q == 45
+}
+
diff --git a/test/profile5.awk b/test/profile5.awk
new file mode 100644
index 00000000..4e962b4b
--- /dev/null
+++ b/test/profile5.awk
@@ -0,0 +1,5179 @@
+
+
+
+
+
+
+BEGIN{ _addlib("_BASE") } ##########################################################
+
+func _BASE(c,t,P, A) {
+ switch ( c ) {
+ case "_lib_CMDLN":
+ if ( match(t,/^((--([Vv])ersion)|(-([Vv])))[ \t]*/,A) ) { t=substr(t,RLENGTH+1); _cmdln_version=A[3] A[5] }
+ else if ( match(t,/^((-?\?)|(--help))[ \t]*/) ) { t=substr(t,RLENGTH+1); _cmdln_help=1 }
+ else if ( match(t,/^--[ \t]*/) ) return _endpass(substr(t,RLENGTH+1))
+ return t
+ #___________________________________________________________
+
+ case "_lib_APPLY":
+ if ( _cmdln_help ) { match(_fbaccr(_LIBAPI,"_lib_HELP"),/^([^\x00]*)\x00([^\x01]*)\x01(.*)/,A)
+ _out(A[2] A[1] A[3]); return _endpass(_basexit_fl=1) }
+ if ( _cmdln_version ) { _out( _ln(_PRODUCT_NAME " v" _PRODUCT_VERSION) _ln(_PRODUCT_COPYRIGHT) _ln() (_cmdln_version=="v" ? "" : _lib_NAMEVER())); return _endpass(_basexit_fl=1) }
+ return
+ #___________________________________________________________
+
+ case "_lib_HELP":
+ return "\x00" _ln(_PRODUCT_NAME " v" _PRODUCT_VERSION) _ln(_PRODUCT_COPYRIGHT) _ln() _ln(" Usage:") _ln() _ln(" " _PRODUCT_FILENAME " [/key1 /key2...] [-- cmdline]") _ln() _ln(" keys:") _ln() "\x01" _ln(" -v -V --version - output product version and (if /V) all modules") _ln(" ? -? --help - output this help page") _ln(" -- - command line string edge")
+ #___________________________________________________________
+
+ case "_lib_NAMEVER":
+ return _ln("_BASE 3.0")
+ #___________________________________________________________
+
+ case "_lib_BEGIN":
+ return
+ #___________________________________________________________
+
+ case "_lib_END":
+ return } }
+#_____________________________________________________________________________
+func _addlib(f) { ###########################################################
+ _addf(_LIBAPI,f) }
+#_______________________________________________________________________
+func _lib_CMDLN(t) {
+ return _pass(_LIBAPI["F"],"_lib_CMDLN",t) }
+#_________________________________________________________________
+func _lib_APPLY() {
+ return _ffaccr(_LIBAPI,"_lib_APPLY") }
+#_________________________________________________________________
+func _lib_HELP() {
+ return _fbaccr(_LIBAPI,"_lib_HELP") }
+#_________________________________________________________________
+func _lib_NAMEVER() {
+ return _fbaccr(_LIBAPI,"_lib_NAMEVER") }
+#_________________________________________________________________
+func _lib_BEGIN(A) {
+ return _ffaccr(_LIBAPI,"_lib_BEGIN","",A) }
+#_________________________________________________________________
+func _lib_END(A) {
+ return _ffaccr(_LIBAPI,"_lib_END","",A) }
+#___________________________________________________________________________________
+BEGIN { ############################################################################
+
+ BINMODE="rw"
+ SUBSEP="\x00"
+ _NULARR[""]; delete _NULARR[""]
+ _INITBASE() }
+#_____________________________________________________________________________
+END { ########################################################################
+
+ _EXIT() }
+
+
+BEGIN { _addlib("_sYS") } ################################################################
+#_____________________________________________________________________________
+func _sYS(c,t,P, a,A) { #####################################################
+ switch ( c ) {
+ #___________________________________________________________
+ case "_lib_CMDLN": return t
+ #_____________________________________________________
+ case "_lib_APPLY": return
+ #_____________________________________________________
+ case "_lib_HELP": return
+ #_____________________________________________________
+ case "_lib_NAMEVER": return
+ #_____________________________________________________
+ case "_lib_BEGIN": return
+ #_____________________________________________________
+ case "_lib_END": return } }
+
+BEGIN { _addlib("_rEG") } ################################################################
+#_____________________________________________________________________________
+func _rEG(c,t,P, a,A) { #####################################################
+ switch ( c ) {
+ #___________________________________________________________
+ case "_lib_CMDLN": return t
+ #_____________________________________________________
+ case "_lib_APPLY": return
+ #_____________________________________________________
+ case "_lib_HELP": return
+ #_____________________________________________________
+ case "_lib_NAMEVER": return _ln("_reg 0.001")
+ #_____________________________________________________
+ case "_lib_BEGIN": return
+ #_____________________________________________________
+ case "_lib_END": return } }
+
+
+
+
+
+BEGIN { _addlib("_INSTRUC") } ######################################################
+
+func _INSTRUC(c,t,P) {
+ switch ( c ) {
+ case "_lib_CMDLN":
+ return t
+ #___________________________________________________________
+
+ case "_lib_APPLY":
+ return
+ #___________________________________________________________
+
+ case "_lib_HELP":
+ return
+ #___________________________________________________________
+
+ case "_lib_NAMEVER":
+ return _ln("_INSTRUC 1.0")
+ #___________________________________________________________
+
+ case "_lib_BEGIN":
+ return
+ #___________________________________________________________
+
+ case "_lib_END":
+ return } }
+#___________________________________________________________________________________
+BEGIN{ #############################################################################
+
+ _delay_perfmsdelay =11500 }
+
+
+
+
+
+
+BEGIN { _addlib("_ARR") } ##########################################################
+
+func _ARR(c,t,P) {
+ switch ( c ) {
+ case "_lib_CMDLN":
+ return t
+ #___________________________________________________________
+
+ case "_lib_APPLY":
+ return
+ #___________________________________________________________
+
+ case "_lib_HELP":
+ return
+ #___________________________________________________________
+
+ case "_lib_NAMEVER":
+ return _ln("_ARR 1.0")
+ #___________________________________________________________
+
+ case "_lib_BEGIN":
+ return
+ #___________________________________________________________
+
+ case "_lib_END":
+ return } }
+#___________________________________________________________________________________
+BEGIN{ } ###########################################################################
+
+
+
+
+
+
+BEGIN { _addlib("_EXTFN") } ########################################################
+
+func _EXTFN(c,t,P) {
+ switch ( c ) {
+ case "_lib_CMDLN":
+ return t
+ #___________________________________________________________
+
+ case "_lib_APPLY":
+ return
+ #___________________________________________________________
+
+ case "_lib_HELP":
+ return
+ #___________________________________________________________
+
+ case "_lib_NAMEVER":
+ return _ln("_EXTFN 1.0")
+ #___________________________________________________________
+
+ case "_lib_BEGIN":
+ return
+ #___________________________________________________________
+
+ case "_lib_END":
+ return } }
+#___________________________________________________________________________________
+BEGIN{ #############################################################################
+
+ delete _XCHR; delete _ASC; delete _CHR; t=""
+ for ( i=0; i<256; i++ ) { _ASC[a=_CHR[i]=sprintf("%c",i)]=i; _QASC[a]=sprintf("%.3o",i)
+ _XCHR[_CHR[i]]=sprintf("%c", (i<128 ? i+128 : i-128)) }
+#_____________________________________________________________________________
+
+ for ( i=0; i<256; i++ ) {
+ _QSTRQ[_CHR[i]]="\\" sprintf("%.3o",i) }
+#_______________________________________________________________________
+
+ for ( i=0; i<32; i++ ) {
+ _QSTR[_CHR[i]]=_QSTRQ[_CHR[i]] }
+ for ( ; i<128; i++ ) {
+ _QSTR[_CHR[i]]=_CHR[i] }
+ for ( ; i<256; i++ ) {
+ _QSTR[_CHR[i]]=_QSTRQ[_CHR[i]] }
+ _QSTR["\\"]="\\\\" #; _QSTR["\""]="\\\""
+#_____________________________________________________________________________
+
+ _CHR["CR"] ="\015"
+ _CHR["EOL"] ="\015\012"
+ _CHR["EOF"] ="\032"
+
+ _QSTR[_CHR["EOL"]] ="\\015\\012"
+#_______________________________________________________________________
+
+ _CHR["MONTH"][_CHR["MONTH"]["Jan"]="01"]="Jan"
+ _CHR["MONTH"][_CHR["MONTH"]["Feb"]="02"]="Feb"
+ _CHR["MONTH"][_CHR["MONTH"]["Mar"]="03"]="Mar"
+ _CHR["MONTH"][_CHR["MONTH"]["Apr"]="04"]="Apr"
+ _CHR["MONTH"][_CHR["MONTH"]["May"]="05"]="May"
+ _CHR["MONTH"][_CHR["MONTH"]["Jun"]="06"]="Jun"
+ _CHR["MONTH"][_CHR["MONTH"]["Jul"]="07"]="Jul"
+ _CHR["MONTH"][_CHR["MONTH"]["Aug"]="08"]="Aug"
+ _CHR["MONTH"][_CHR["MONTH"]["Sep"]="09"]="Sep"
+ _CHR["MONTH"][_CHR["MONTH"]["Oct"]="10"]="Oct"
+ _CHR["MONTH"][_CHR["MONTH"]["Nov"]="11"]="Nov"
+ _CHR["MONTH"][_CHR["MONTH"]["Dec"]="12"]="Dec"
+#_____________________________________________________________________________
+
+ _TAB_STEP_DEFAULT =8
+#_____________________________________________________________________________
+
+ for ( i=0; i<32; i++ ) _REXPSTR[_CHR[i]]=_QSTRQ[_CHR[i]]
+ for ( ; i<256; i++ ) _REXPSTR[_CHR[i]]=_CHR[i]
+ _gensubfn("\\^$.()|{,}[-]?+*",".","_rexpstr_i0") }
+#_____________________________________________________________________________
+func _rexpstr_i0(t,A,p0) {
+ return _REXPSTR[t]="\\" t }
+
+
+
+
+
+
+BEGIN { _addlib("_SYSIO") } #########################################################
+
+func _SYSIO(c,t,P) {
+ switch ( c ) {
+ case "_lib_CMDLN":
+ return t
+ #___________________________________________________________
+
+ case "_lib_APPLY":
+ return
+ #___________________________________________________________
+
+ case "_lib_HELP":
+ return
+ #___________________________________________________________
+
+ case "_lib_NAMEVER":
+ return _ln("_SYSIO 1.0")
+ #___________________________________________________________
+
+ case "_lib_BEGIN":
+ return
+ #___________________________________________________________
+
+ case "_lib_END":
+ return } }
+#___________________________________________________________________________________
+BEGIN{ #############################################################################
+
+ _SYS_STDCON ="CON"
+ _CON_WIDTH=match(_cmd("MODE "_SYS_STDCON" 2>NUL"),/Columns:[ \t]*([0-9]+)/,A) ? strtonum(A[1]) : 80 }
+
+
+
+
+
+
+BEGIN { _addlib("_FILEIO") } #######################################################
+
+func _FILEIO(c,t,P, A) {
+ switch ( c ) {
+ case "_lib_CMDLN":
+ if ( match(t,/^[ \t]*-[Tt]([\+-])[ \t]*/,A) ) { t=substr(t,RLENGTH+1)
+ if ( A[1]=="+" ) _fileio_notdeltmpflag=1
+ else _fileio_notdeltmpflag="" }
+ return t
+ #___________________________________________________________
+
+ case "_lib_APPLY":
+ if ( _fileio_notdeltmpflag ) {
+ _info("Temporary objects deletion DISABLED (inherited)")
+ }
+ return
+ #___________________________________________________________
+
+ case "_lib_HELP":
+ return _ln(" -[Tt][+-] - inherited: +enable\\-disable temporary files\\dirs deletion") _ln()
+ #___________________________________________________________
+
+ case "_lib_NAMEVER":
+ return _ln("_FILEIO 2.1")
+ #___________________________________________________________
+
+ case "_lib_BEGIN":
+ P["ENVIRON"]["CD"] =ENVIRON["CD"]
+ P["_FILEIO_RD"] =_FILEIO_RD
+ P["_FILEIO_R"] =_FILEIO_R
+ P["_FILEIO_D"] =_FILEIO_D
+ if ( !("_FILEIO_TMPRD" in P) ) {
+ P["_FILEIO_TMPRD"] =_getmpdir(_filen(P["SOURCE"]) "." ++_egawk_subcntr _CHR["SUBDIR"]) }
+ return
+ #___________________________________________________________
+
+ case "_lib_END":
+ return } }
+#___________________________________________________________________________________
+BEGIN{ #############################################################################
+
+ if ( _SYS_STDOUT=="" ) _SYS_STDOUT="/dev/stdout"
+ if ( _SYS_STDERR=="" ) _SYS_STDERR="/dev/stderr"
+ _CHR["SUBDIR"]="\\"
+ if ( _gawk_scriptlevel<1 ) {
+ match(b=_cmd("echo %CD% 2>NUL"),/[^\x00-\x1F]*/)
+ ENVIRON["CD"]=_FILEIO_RD=_filerd(substr(b,RSTART,RLENGTH) _CHR["SUBDIR"]); _FILEIO_R=_filer(_FILEIO_RD); _FILEIO_D=_filed(_FILEIO_RD)
+ _setmpath(_filerd(_FILEIO_RD "_tmp" _CHR["SUBDIR"])) } }
+
+
+
+
+
+
+BEGIN { _addlib("_tOBJ") } #########################################################
+
+func _tOBJ(c,t,P) {
+ switch ( c ) {
+ #___________________________________________________________
+ case "_lib_CMDLN":
+ return t
+ #___________________________________________________________
+ case "_lib_APPLY":
+ return
+ #___________________________________________________________
+ case "_lib_HELP":
+ return
+ #___________________________________________________________
+ case "_lib_NAMEVER":
+ return _ln("_tOBJ 3.0")
+ #___________________________________________________________
+ case "_lib_BEGIN":
+ return
+ #___________________________________________________________
+ case "_lib_END":
+ return
+ #___________________________________________________________
+ case "_lib_CLEANUP":
+ return _tOBJ_CLEANUP() } }
+#_______________________________________________________________________
+func _tOBJ_CLEANUP( p) { ##############################################
+ for ( p in UIDSDEL ) {
+ delete _ptr[p]
+ delete _tPREV[p]; delete _tPARENT[p]; delete _tNEXT[p]
+ delete _tFCHLD[p]; delete _tQCHLD[p]; delete _tLCHLD[p]
+ delete _TMP0[p]; delete _TMP1[p]
+ delete _tLINK[p]; delete _tCLASS[p] } }
+#___________________________________________________________________________________
+BEGIN{ #############################################################################
+ _tInBy ="\x8A._tInBy"
+ _tgenuid_init()
+ _UIDS[""]; delete _UIDS[""]; _UIDSDEL[""]; delete _UIDSDEL[""]
+ _tPREV[""]; _tPARENT[""]; _tNEXT[""]; _tFCHLD[""]; _tQCHLD[""]; _tLCHLD[""]
+ _tLINK[""]; _tCLASS[""]
+ _tSTR[""]; _tDLINK[""]
+ _[""]; delete _[""]; _ptr[""]; delete _ptr[""]
+ _TMP0[""]; delete _TMP0[""]; _TMP1[""]; delete _TMP1[""] }
+
+
+
+
+
+BEGIN{ _addlib("_ERRLOG") } ########################################################
+
+func _ERRLOG(c,t,P, a,b,A) {
+ switch ( c ) {
+ case "_lib_CMDLN":
+ if ( match(t,/^[ \t]*-L:([TtVvIiWwEeFf]*)[ \t]*/,A) ) { t=substr(t,RLENGTH+1); _errlog_errflkey=_errlog_errflkey A[1] }
+ return t
+ #_______________________________________________________________________
+
+ case "_lib_APPLY":
+ if ( _errlog_errflkey ) {
+ split(_errlog_errflkey,A,"")
+ for ( a=1; a in A; a++ ) {
+ if ( A[a]==toupper(A[a]) ) b=1; else b=""
+ switch ( toupper(A[a]) ) {
+ case "T":
+ _ERRLOG_TF=b; break
+ case "V":
+ _ERRLOG_VF=b; break
+ case "I":
+ _ERRLOG_IF=b; break
+ case "W":
+ _ERRLOG_WF=b; break
+ case "E":
+ _ERRLOG_EF=b; break
+ case "F":
+ _ERRLOG_FF=b; break } }
+ if ( _ERRLOG_IF ) {
+ _info("Log-message types inherited acc/deny: " "TRACE " (_ERRLOG_TF ? "ON" : "OFF") "/" "VERBOSE " (_ERRLOG_VF ? "ON" : "OFF") "/" "INFO " (_ERRLOG_IF ? "ON" : "OFF") "/" "WARNING " (_ERRLOG_WF ? "ON" : "OFF") "/" "ERROR " (_ERRLOG_EF ? "ON" : "OFF") "/" "FATAL " (_ERRLOG_FF ? "ON" : "OFF") ) } }
+ return
+ #_______________________________________________________________________
+
+ case "_lib_HELP":
+ return _ln(" -L:TtVvIiWwEeFf - enable(upcase: TVIWEF) or disable(lowcase: tviwef) allowable type of") _ln(" log messages. Trace/Verbose/Informational/Warning/Error/Fatal.") _ln()
+ #_______________________________________________________________________
+
+ case "_lib_NAMEVER":
+ return _ln("_ERRLOG 1.0")
+ #_______________________________________________________________________
+
+ case "_lib_BEGIN":
+ P["_ERRLOG_TF"] =_ERRLOG_TF
+ P["_ERRLOG_VF"] =_ERRLOG_VF
+ P["_ERRLOG_IF"] =_ERRLOG_IF
+ P["_ERRLOG_WF"] =_ERRLOG_WF
+ P["_ERRLOG_EF"] =_ERRLOG_EF
+ P["_ERRLOG_FF"] =_ERRLOG_FF
+ P["_errlog_file"] ="/dev/stderr"
+ return } }
+#___________________________________________________________________________________
+BEGIN{ #############################################################################
+
+ if ( _gawk_scriptlevel<1 ) {
+ _ERRLOG_TF =1
+ _ERRLOG_VF =1
+ _ERRLOG_IF =1
+ _ERRLOG_WF =1
+ _ERRLOG_EF =1
+ _ERRLOG_FF =1
+ _wrfile(_errlog_file=_getmpfile("OUTPUT.LOG"),"") } }
+
+
+
+
+
+
+BEGIN { _addlib("_SHORTCUT") } #####################################################
+
+func _SHORTCUT(c,t,P) {
+ switch ( c ) {
+ case "_lib_CMDLN":
+ return t
+ #___________________________________________________________
+
+ case "_lib_APPLY":
+ return
+ #___________________________________________________________
+
+ case "_lib_HELP":
+ return
+ #___________________________________________________________
+
+ case "_lib_NAMEVER":
+ return _ln("_shortcut 1.0")
+ #___________________________________________________________
+
+ case "_lib_BEGIN":
+ return
+ #___________________________________________________________
+
+ case "_lib_END":
+ return } }
+#___________________________________________________________________________________
+BEGIN { _shortcut_init() } #########################################################
+
+
+
+BEGIN { _addlib("_eXTFN") } ########################################################
+
+func _eXTFN(c,t,P) {
+ switch ( c ) {
+ case "_lib_CMDLN":
+ return t
+ #___________________________________________________________
+
+ case "_lib_APPLY":
+ return
+ #___________________________________________________________
+
+ case "_lib_HELP":
+ return
+ #___________________________________________________________
+
+ case "_lib_NAMEVER":
+ return _ln("_extfn 1.0")
+ #___________________________________________________________
+
+ case "_lib_BEGIN":
+ return
+ #___________________________________________________________
+
+ case "_lib_END":
+ return } }
+#___________________________________________________________________________________
+BEGIN { _extfn_init() } ############################################################
+
+
+BEGIN { _addlib("_sHARE") } ##############################################################
+#_____________________________________________________________________________
+func _sHARE(c,t,P, a,A) { ###################################################
+ switch ( c ) {
+ #___________________________________________________________
+ case "_lib_CMDLN": return t
+ #_____________________________________________________
+ case "_lib_APPLY": return
+ #_____________________________________________________
+ case "_lib_HELP": return
+ #_____________________________________________________
+ case "_lib_NAMEVER": return _ln("_share 1.000")
+ #_____________________________________________________
+ case "_lib_BEGIN": return
+ #_____________________________________________________
+ case "_lib_END": return } }
+
+BEGIN { _addlib("_FILEVER") } ############################################################
+#_____________________________________________________________________________
+func _FILEVER(c,t,P, a,A) { #################################################
+ switch ( c ) {
+ #___________________________________________________________
+ case "_lib_CMDLN": return t
+ #_____________________________________________________
+ case "_lib_APPLY": return
+ #_____________________________________________________
+ case "_lib_HELP": return
+ #_____________________________________________________
+ case "_lib_NAMEVER": return
+ #_____________________________________________________
+ case "_lib_BEGIN": return
+ #_____________________________________________________
+ case "_lib_END": return } }
+
+
+BEGIN { _addlib("_DS") ###############################################################################
+
+ _PRODUCT_NAME ="Deployment Solution Control"
+ _PRODUCT_VERSION ="1.0"
+ _PRODUCT_COPYRIGHT ="Copyright (C) 2013 by CosumoGEN"
+ _PRODUCT_FILENAME ="_main.ewk"
+}#____________________________________________________________________________
+func _DS(c,t,P, a,A) { ######################################################
+ switch ( c ) {
+ #___________________________________________________________
+ case "_lib_CMDLN": return t
+ #_____________________________________________________
+ case "_lib_APPLY": return
+ #_____________________________________________________
+ case "_lib_HELP": return _ln() _ln( " Usage: " _PRODUCT_NAME " [/key1 /key2...] sourcefile [cmdline]") _ln()
+ #_____________________________________________________
+ case "_lib_NAMEVER": return
+ #_____________________________________________________
+ case "_lib_BEGIN": return
+ #_____________________________________________________
+ case "_lib_END": return } }
+
+func _INIT(f) { } #############################################################################
+
+
+
+func _pmap(m,s1,s2,s3,s4,s5,s6,s7,s8) {
+ if ( match(m,/^([^\(]+)\(([^\)]*)\)$/,_QMAP) ) { _qparamf1=_QMAP[1]; _QMAP[0]="r" (_qparamc1=split(_QMAP[2],_QMAP,""))
+ _qparamf0="_p" _QMAP[_qparamc1--]
+ return @_qparamf0(s1,s2,s3,s4,s5,s6,s7,s8) } }
+
+func _p1(s1,s2,s3,s4,s5,s6,s7,s8,p1,p2,p3,p4,p5,p6,p7,p8) {
+ _qparamf0="_p" _QMAP[_qparamc1--]
+ return @_qparamf0(s1,s2,s3,s4,s5,s6,s7,s8,s1,p1,p2,p3,p4,p5,p6,p7) }
+
+func _p2(s1,s2,s3,s4,s5,s6,s7,s8,p1,p2,p3,p4,p5,p6,p7,p8) {
+ _qparamf0="_p" _QMAP[_qparamc1--]
+ return @_qparamf0(s1,s2,s3,s4,s5,s6,s7,s8,s2,p1,p2,p3,p4,p5,p6,p7) }
+
+func _p3(s1,s2,s3,s4,s5,s6,s7,s8,p1,p2,p3,p4,p5,p6,p7,p8) {
+ _qparamf0="_p" _QMAP[_qparamc1--]
+ return @_qparamf0(s1,s2,s3,s4,s5,s6,s7,s8,s3,p1,p2,p3,p4,p5,p6,p7) }
+
+func _p4(s1,s2,s3,s4,s5,s6,s7,s8,p1,p2,p3,p4,p5,p6,p7,p8) {
+ _qparamf0="_p" _QMAP[_qparamc1--]
+ return @_qparamf0(s1,s2,s3,s4,s5,s6,s7,s8,s4,p1,p2,p3,p4,p5,p6,p7) }
+
+func _p5(s1,s2,s3,s4,s5,s6,s7,s8,p1,p2,p3,p4,p5,p6,p7,p8) {
+ _qparamf0="_p" _QMAP[_qparamc1--]
+ return @_qparamf0(s1,s2,s3,s4,s5,s6,s7,s8,s5,p1,p2,p3,p4,p5,p6,p7) }
+
+func _p6(s1,s2,s3,s4,s5,s6,s7,s8,p1,p2,p3,p4,p5,p6,p7,p8) {
+ _qparamf0="_p" _QMAP[_qparamc1--]
+ return @_qparamf0(s1,s2,s3,s4,s5,s6,s7,s8,s6,p1,p2,p3,p4,p5,p6,p7) }
+
+func _p7(s1,s2,s3,s4,s5,s6,s7,s8,p1,p2,p3,p4,p5,p6,p7,p8) {
+ _qparamf0="_p" _QMAP[_qparamc1--]
+ return @_qparamf0(s1,s2,s3,s4,s5,s6,s7,s8,s7,p1,p2,p3,p4,p5,p6,p7) }
+
+func _p8(s1,s2,s3,s4,s5,s6,s7,s8,p1,p2,p3,p4,p5,p6,p7,p8) {
+ _qparamf0="_p" _QMAP[_qparamc1--]
+ return @_qparamf0(s1,s2,s3,s4,s5,s6,s7,s8,s8,p1,p2,p3,p4,p5,p6,p7) }
+
+func _pr8(s1,s2,s3,s4,s5,s6,s7,s8,p1,p2,p3,p4,p5,p6,p7,p8) {
+
+ return @_qparamf1(p1,p2,p3,p4,p5,p6,p7,p8) }
+
+func _pr7(s1,s2,s3,s4,s5,s6,s7,s8,p1,p2,p3,p4,p5,p6,p7,p8) {
+
+ return @_qparamf1(p1,p2,p3,p4,p5,p6,p7) }
+
+func _pr6(s1,s2,s3,s4,s5,s6,s7,s8,p1,p2,p3,p4,p5,p6,p7,p8) {
+
+ return @_qparamf1(p1,p2,p3,p4,p5,p6) }
+
+func _pr5(s1,s2,s3,s4,s5,s6,s7,s8,p1,p2,p3,p4,p5,p6,p7,p8) {
+
+ return @_qparamf1(p1,p2,p3,p4,p5) }
+
+func _pr4(s1,s2,s3,s4,s5,s6,s7,s8,p1,p2,p3,p4,p5,p6,p7,p8) {
+
+ return @_qparamf1(p1,p2,p3,p4) }
+
+func _pr3(s1,s2,s3,s4,s5,s6,s7,s8,p1,p2,p3,p4,p5,p6,p7,p8) {
+
+ return @_qparamf1(p1,p2,p3) }
+
+func _pr2(s1,s2,s3,s4,s5,s6,s7,s8,p1,p2,p3,p4,p5,p6,p7,p8) {
+
+ return @_qparamf1(p1,p2) }
+
+func _pr1(s1,s2,s3,s4,s5,s6,s7,s8,p1,p2,p3,p4,p5,p6,p7,p8) {
+
+ return @_qparamf1(p1) }
+
+func _pr0(s1,s2,s3,s4,s5,s6,s7,s8,p1,p2,p3,p4,p5,p6,p7,p8) {
+
+ return @_qparamf1() }
+
+
+
+
+
+
+
+
+
+
+
+func hujf(a,b,c) { _conl("hujf(" a "," b "," c ")") }
+
+
+
+
+func _qparam(qm,p0,p1,p2,p3,p4,p5,p6,p7) {
+
+ if ( qm==qm+0 && qm>0 ) _qparamim=substr(" ",1,qm)
+ else if ( qm!="" ) _qparamim=qm
+ else _qparamim=" "
+ _qparamask=""; return _qparam_i0(p0,p1,p2,p3,p4,p5,p6,p7) }
+
+func _qparam_i0(p0,p1,p2,p3,p4,p5,p6,p7) { _qparama0=substr(_qparamim,1,1); _qparamim=substr(_qparamim,2)
+ switch ( _qparama0 ) { case "": gsub(/ +$/,"",_qparamask); return length(_qparamask)
+ default: if ( isarray(p0) ) _qparama0="A"
+ else if ( p0=="" && p0==0 ) _qparama0=" "
+ else if ( _isptr(p0) ) _qparama0="P"
+ else _qparama0="S"
+ case ".": _qparamask=_qparamask _qparama0
+ return _qparam_i0(p1,p2,p3,p4,p5,p6,p7) } }
+func tts(p,uidel,psfx,cnt,chr,p5,p6,p7, im) {
+ im=" "
+ im=".. .."
+ _conl("ret: " _qparam(im,p,uidel,psfx,cnt,chr,p5,p6,p7) "'")
+ _conl("mask: `" _qparamask "'") }
+
+func _uidcyc(p, i) {
+ _dumpuidgen(p)
+ for ( i=1; i<(64*8*6-1); i++ ) _conl(i ":" _var(_getuid(p)))
+ _dumpuidgen(p) }
+
+
+
+func _dumpuidgen(p, pd,pc,ps) {
+ _conline("#" (++cntdm) ": " p "'"); _conl()
+ if ( p in _tuidel ) { _conl("DEL: " _var(pd=_tuidel[p]))
+ _conl(_dumparr(_tUIDEL[pd]) _ln()) }
+ _conl("PFX: " _tUIDPFX[p] "'"); _conl("SFX: " _tUIDSFX[p] "'")
+
+ _conl("COUNT: " (p in _tuidcnt ? (pc=_tuidcnt[p]) "'" : _th0("-",pc=-2)))
+ _con("CHARS: "); if ( p in _tuidchr ) { _conl((ps=_tuidchr[p]) "'")
+ _conl("HCHR: " (pc==-2 ? "-" : _tUIDCNTH[pc] "'")); _conl(_dumparr(_tUIDCHRH[ps]) _ln())
+ _conl("LCHR: " (pc==-2 ? "-" : _tUIDCNTL[pc] "'")); _conl(_dumparr(_tUIDCHRL[ps]) _ln()) }
+ else _conl("-") }
+
+
+
+# prefix -
+# prichr - aware character `{', `^',`]'
+# sechr - aware character `.' as the first char of sechr, and character `}'
+# suffix - aware character `]'
+# cntptr - aware character `]'
+
+func _tr(n,cs, H) {
+ #_tuidinitcs[p]=cs
+ #2 uidel, 5 pfx, 7 hichr,11(10) lochr,14 suffix
+ _rconline(n ": " cs); _rconl()
+ if ( match(cs,/^((([^\xB4:\[\|\]]*\xB4.)*[^\xB4:\[\|\]]*):)?((([^\xB4\[\|\]]*\xB4.)*[^\xB4\[\|\]]*)\[)?(([^\xB4\|\]]*\xB4.)*[^\xB4\|\]]*)?(\|(\.)?(([^\xB4\]]*\xB4.)*[^\xB4\]]*))?(\](.*))?$/,H) ) {
+ _rconl("delptr: " _une(H[2]) "'")
+ _rconl("pfxstr: " _une(H[5]) "'")
+ _rconl("hichr: " _une(H[7]) "'")
+ _rconl("lochr: " _une(H[10] ? H[7] "' and " H[11] "'" : H[11] "'"))
+ _rconl("sfxstr: " _une(H[14]) "'") }
+ else _rconl("NOT MATCH!")
+ _rconl() }
+
+func _une(t) { return gensub(/\xB4(.)/,"\\1","G",t) }
+func _rconl(t) { _rprt=_rprt _ln(t) }
+func _rconline(t) { _rprt=_rprt _ln((t=" " t " ") _getchrln("_",_CON_WIDTH-length(t)-1)) }
+
+
+
+
+
+
+
+
+
+
+
+
+func _splitpath_test() {
+ _conl(); _conl("########################################################################################"); _conl()
+ _fpp(" ")
+ _fpp(" fi le . ex t ")
+ _fpp(" di r0 / / ")
+ _fpp(" di r0 / / fi le . ex t ")
+ _fpp(" / ")
+ _fpp(" / fi le . ex t ")
+ _fpp(" / di r0 / / ")
+ _fpp(" / di r0 / / fi le . ex t ")
+ _conl(); _conl("########################################################################################"); _conl()
+ _fpp(" c : ")
+ _fpp(" c : fi le . ex t ")
+ _fpp(" c : di r0 / / ")
+ _fpp(" c : di r0 / / fi le . ex t ")
+ _fpp(" c : / / ")
+ _fpp(" c : / / fi le . ex t ")
+ _fpp(" c : / / di r0 / / ")
+ _fpp(" c : / / di r0 / / fi le . ex t ")
+ _conl(); _conl("########################################################################################"); _conl()
+ _fpp(" / / ")
+ _fpp(" / / ho st . hs t ")
+ _fpp(" / / ho st / / ")
+ _fpp(" / / ho st / / fi le . ex t ")
+ _fpp(" / / ho st / / di r0 / / ")
+ _fpp(" / / ho st / / di r0 / / fi le . ex t ")
+ _conl(); _conl("########################################################################################"); _conl()
+ _fpp(" / / ho st / / c : ")
+ _fpp(" / / ho st / / c : fi le . ex t ")
+ _fpp(" / / ho st / / c : di r0 / / ")
+ _fpp(" / / ho st / / c : di r0 / / fi le . ex t ")
+ _fpp(" / / ho st / / c : / / ")
+ _fpp(" / / ho st / / c : / / fi le . ex t ")
+ _fpp(" / / ho st / / c : / / di r0 / / ")
+ _fpp(" / / ho st / / c : / / di r0 / / fi le . ex t ")
+ _conl(); _conl("########################################################################################"); _conl()
+ _fpp(" http : / / / ")
+ _fpp(" http : / / / si te . ex t ")
+ _fpp(" http : / / / si te / / ")
+ _fpp(" http : / / / si te / / fi le . ex t ")
+ _fpp(" http : / / / si te / / di r0 / / ")
+ _fpp(" http : / / / si te / / di r0 / / fi le . ex t ")
+ _conl(); _conl("########################################################################################"); _conl()
+ _fpp(" ftp : / / / : po rt ")
+ _fpp(" ftp : / / / si te . ex t : po rt ")
+ _fpp(" ftp : / / / si te : po rt / / ")
+ _fpp(" ftp : / / / si te : po rt / / fi le . ex t ")
+ _fpp(" ftp : / / / si te : po rt / / di r0 / / ")
+ _fpp(" ftp : / / / si te : po rt / / di r0 / / fi le . ex t ")
+ _conl(); _conl("## //. ######################################################################################"); _conl()
+ _fpp(" / / . ")
+ _fpp(" / / . / / ")
+ _fpp(" / / . / / com 56 ")
+ _fpp(" / / . / / com 56 / / ")
+ _fpp(" / / . / / c : ")
+ _fpp(" / / . / / c : / / ")
+ _fpp(" / / . / / c : com 56 ")
+ _fpp(" / / . / / c : com 56 / / ")
+ _fpp(" / / . / / c : / / com 56 ")
+ _fpp(" / / . / / c : / / com 56 / / ")
+ _conl(); _conl("## //? ######################################################################################"); _conl()
+ _fpp(" / / ? ")
+ _fpp(" / / ? / / ")
+ _fpp(" / / ? / / com 56 ")
+ _fpp(" / / ? / / com 56 / / ")
+ _fpp(" / / ? / / c : ")
+ _fpp(" / / ? / / c : / / ")
+ _fpp(" / / ? / / c : com 56 ")
+ _fpp(" / / ? / / c : com 56 / / ")
+ _fpp(" / / ? / / c : / / com 56 ")
+ _fpp(" / / ? / / c : / / com 56 / / ")
+ _conl(); _conl("########################################################################################"); _conl()
+ _fpp(" / / / ")
+ _fpp(" / / / . hs t ")
+ _fpp(" / / / / fi le . ex t ")
+ _fpp(" / / / / di r0 / / ")
+ _fpp(" / / / / di r0 / / di r1 / fi le . ex t ")
+ _fpp(" / / / / c : ")
+ _fpp(" / / / / c : fi le . ex t ")
+ _fpp(" / / / / c : di r0 / / ")
+ _fpp(" / / / / c : di r0 / / fi le . ex t ")
+ _fpp(" / / / / c : / / ")
+ _fpp(" / / / / c : / / fi le . ex t ")
+ _fpp(" / / / / c : / / di r0 / / ")
+ _fpp(" / / / / c : / / di r0 / / fi le . ex t ")
+ _conl(); _conl("########################################################################################"); _conl()
+
+
+ return }
+# this is somnitelno: that / / . / / com 56 / / - is the DEV...; what is DEV ??? this already PROBLEM
+#_____________________________________________________________________________
+func _patharr0(D,q, i,h,A,B) { ##############################################
+ delete D; if ( 0<q=split(gensub(/\\/,"/","G",gensub(/ *([:$\\\/]) */,"\\1","G",gensub(/(^[ \t]+)|([ \t]+$)/,"","G",q))),A,/\/+/,B) ) {
+ if ( 2>h=length(B[1]) ) { D["type"]="FILE"; A[1]=_patharr0_i0(A[1],D,"drive"); return _patharr0_i1(D,A,1,q) }
+ i=gensub(/ *([\.\?]) */,"\\1","G",A[2]); IGNORECASE=1; match(A[1],/^((https?)|(ftp)):$/); IGNORECASE=0
+ if ( RLENGTH>0 ) { D["type"]=toupper(substr(A[1],1,RLENGTH-1)); _patharr0_i0(i,D,"site","port") }
+ else if ( A[1]=="" ) { D["type"]="UNC"; if ( h>2 ) { D["host"]; A[2]=_patharr0_i0(A[2],D,"drive","","FILE"); return _patharr0_i1(D,A,2,q) }
+ if ( i=="" ) return 1
+ D["host"]=i; A[3]=_patharr0_i0(A[3],D,"drive","","FILE") }
+ else { D["type"]="FILE"; A[1]=_patharr0_i0(A[1],D,"drive"); return _patharr0_i1(D,A,1,q) } return _patharr0_i1(D,A,3,q) } }
+ #_____________________________________________________
+ func _patharr0_i0(t,D,l,r,d, i) { if ( i=index(t,":") ) { if ( d ) D["type"]=d
+ if ( i>1 ) D[l]=substr(t,1,i-1)
+ if ( (t=substr(t,i+1)) && r ) D[r]=t; return t }
+ else if ( t && r ) D[l]=t; return t }
+ #_____________________________________________________
+ func _patharr0_i1(D,A,i,q, t,c) { if ( D["type"]=="UNC" ) { if ( t=A[i++] ) D[0]=(D["share"]=D[++c]=t) "/"; else return 1 }
+ while ( i<q ) D[0]=D[0] (D[++c]=A[i++]) "/"
+ if ( i==q ) { if ( match(t=A[i],/\.[^\.]*$/) ) { if ( RSTART>1 ) D["name"]=substr(t,1,RSTART-1); D["ext"]=substr(t,RSTART,RLENGTH) }
+ else if ( t!="" ) D["name"]=t } return 1 }
+
+
+func _fpp(q, D,S) {
+ _conl(); _conline(q); _conl();
+ q=_patharr0(S,q)
+ #_arregpath(D,S)
+ #_conl(_dumparr(D))
+ _conl( _dumparr(S)); _conl()
+
+ return q }
+
+
+func _rpp(q, D,S) {
+ _conl(); _conline(q); _conl();
+
+ _regpath0(D,q)
+ #_conl(_dumparr(D))
+
+ _conl(_ln("DEST:") _dumparr(D)); _conl()
+ return q }
+
+func _split_regpath() {
+ _rpp(" / / / / ")
+ _rpp(" / / / / huj ")
+ _rpp(" / / / / huj / ")
+ _rpp(" / / / / huj / pizda.TSR ")
+ _rpp(" / / / / hklm ")
+ _rpp(" / / / / hklm / ")
+ _rpp(" / / / / hklm / huj ")
+ _rpp(" / / / / hklm / huj / ")
+ _rpp(" / / / / hklm / huj / pizda.TSR ")
+ _conl(); _conl("########################################################################################"); _conl()
+ _rpp(" / / / / hklm / software / altiris / fi le . ex t ")
+ _rpp(" / / . / / hkcr / software / altiris / fi le . ex t ")
+ _rpp(" / / ? / / hKcU / software / altiris / fi le . ex t ")
+ _rpp(" / / lOcAlHoSt / / hKu / software / altiris / fi le . ex t ")
+ _rpp(" / / ho st / / hKcc / software / altiris / fi le . ex t ")
+ _rpp(" / / ho st / / hKPd / software / altiris / fi le . ex t ")
+ _conl(); _conl("########################################################################################"); _conl()
+
+
+
+ }
+# test with the different path types
+# _conl(_ln("SRC:") _dumparr(S)); _conl();
+
+func _ini(p,cs, dptr,pfx,sfx,hstr,lstr) {
+ return _inituid(p,cs, dptr,pfx,sfx,hstr,lstr,A) }
+
+#_______________________________________________________________________
+func _inituid(p,cs, dptr,pfx,sfx,hstr,lstr,A) { ################### 1 #
+ if ( cs==0 && cs=="" ) { cs=p; p=_getuid() }
+
+ _conl(); _conl(); _conl(cs)
+
+ if ( match(cs,/^(([^:]*):)?(([^'\xB4]*\xB4.)*[^'\xB4]*)[']/,A) ) { pfx=A[3]; dptr=A[2] }
+ if ( match(cs=substr(cs,1+RLENGTH),/'(([^'\xB4]*\xB4.)*[^'\xB4]*)$/,A) ) { sfx=A[1]; cs=substr(cs,1,RSTART-1) }
+ if ( match(cs,/^(([`\^])(.*))/,A) ) { if ( A[2]=="`" ) { hstr=A[3] "~"; lstr="" } else { lstr=A[3] "+"; hstr="" } }
+ else if ( match(cs,/^(([^'\xB4\|]*\xB4.)*[^'\xB4\|]*)(\|(.*))?/,A) ) { hstr=A[1]; lstr=A[4] }
+ else { ERRNO="_inituid(): bad parameters"; return }
+
+ _conl(dptr ":" pfx "'" hstr "|" lstr "'" sfx)
+
+ return _cfguid(p,dptr,pfx,sfx,hstr,lstr) }
+
+# dptr - morg ptr; in case if object deleted then _CLASSPTR[ptr] will be deleted(object is death), but
+# _tUIDEL[_CLASSPTR[ptr]] will be created that object can be resurrected from morg
+# dptr can be any string containing any characters except `:'. It's not verified
+# pfx,sfx - uid prefix str, and uid suffix str; this strings specifies string that can be inserted before/after
+# uid generated by uid generator:
+#
+# class uid: pfx uidgen sfx
+#
+# Both can be any string(including ""), and can contains any character with B4-escaping feature.
+# Note: that this strings cannot contains "'" character: it's should be escaped by B4-escaper.
+# hstr,lstr - this values configure uid-generator itself. ther is a 3 combinations regarding its:
+#
+# hstr lstr function
+#
+# `ptr * - specify pointer to external uid-generator
+# All uids and chars will be generated by external uid-generator
+# * ^ptr - class will have it's own uid generator using external character set
+# str str - class will have it's own uid generator with it's own character set
+# character set inmplemented in hstr(high-charset) and in lstr(low-charset) in 2 ways:
+# 1) "AB" "AB01" - this mean that high-charset contain chars: `A' and `B'
+# low-charset contains chars: `A', `B', `0', `1'
+#
+# 2) "Az,By" "Ax,Bw,0v,1u" - this mean that high-charset contain chars: `Az' and `By'
+# low-charset contains chars: `Ax', `Bw', `0v', `1u'
+# Note: both: hstr and lstr cannot contain char `,' directly, but it's can uses
+# B4-escaper to escape any char including `,'
+
+
+
+# !!!! in case of using `,' in hstr/lstr - the escaped `,' will leads to interpretate hstr and lstr as divided by `,'
+# if parameters error then i should be more specific about what error in parameters detected
+# document _inituid(): parameters; document cs: uid initialization string format
+# test with escape char
+# adv hstr and lstr splitting?
+# chk if hstr len==0 ?
+# return _tclass & report error?
+# _tapi thru function
+
+# additional syntax checking ???
+# implement syntax and uid srv in docs
+# add _dumpuid() ????
+# make performance measurement
+# protection against badchar list
+# additional feature to specify _getuid() to not resurrect uid; and informative that uid was ressurected or not
+# build _defclass fn
+
+# _tuidinitcs ????
+# _tuidchrh[p]
+# _tuidchrl[p]
+# _tuidchr[p]
+# _tuidcnt[p]
+# _tUIDPFX[p]
+# _tUIDSFX[p]
+# _tUIDEL
+# _tUIDCNTH
+# _tUIDCNTL
+# _tUIDCHRL
+# _tUIDCHRH
+
+# create default class basic `new' and `del' functions
+
+
+
+func _tstini() {
+ _ini("uidel:pfx'hstr|lstr'sfx")
+ _ini("uidel:pfx'hstr|lstr'")
+ _ini("uidel:'hstr|lstr'sfx")
+ _ini("uidel:'hstr|lstr'")
+ _ini("uidel:pfx'hstr'sfx")
+ _ini("uidel:pfx'hstr'")
+ _ini("uidel:'hstr'sfx")
+ _ini("uidel:'hstr'")
+ _conl(); _conl("########################################################################################"); _conl()
+ _ini("pfx'hstr|lstr'sfx")
+ _ini("pfx'hstr|lstr'")
+ _ini("'hstr|lstr'sfx")
+ _ini("'hstr|lstr'")
+ _ini("pfx'hstr'sfx")
+ _ini("pfx'hstr'")
+ _ini("'hstr'sfx")
+ _ini("'hstr'")
+ _conl(); _conl("########################################################################################"); _conl()
+ _ini("uidel:pfx'`cntptr'sfx")
+ _ini("uidel:pfx'`cntptr'")
+ _ini("uidel:'`cntptr'sfx")
+ _ini("uidel:'`cntptr'")
+ _conl(); _conl("########################################################################################"); _conl()
+ _ini("pfx'`cntptr'sfx")
+ _ini("pfx'`cntptr'")
+ _ini("'`cntptr'sfx")
+ _ini("'`cntptr'")
+ _conl(); _conl("########################################################################################"); _conl()
+ _ini("uidel:pfx'^chrptr'sfx")
+ _ini("uidel:pfx'^chrptr'")
+ _ini("uidel:'^chrptr'sfx")
+ _ini("uidel:'^chrptr'")
+ _conl(); _conl("########################################################################################"); _conl()
+ _ini("pfx'^chrptr'sfx")
+ _ini("pfx'^chrptr'")
+ _ini("'^chrptr'sfx")
+ _ini("'^chrptr'")
+ _conl(); _conl("########################################################################################"); _conl()
+
+
+ }
+
+func _rtn(v,A) {
+ _conl(); _conline(_val(v) " : " _val(A)); _conl()
+
+ _rtn2(v,A)
+
+ _conl() }
+
+func _rtn2(v,A, r,t) {
+
+ r=isarray(A) ? _typa(v,A) : _typ(v)
+
+ if ( "`">_t0 && _t0 ) _conl("ggggg")
+
+ t=(r ? "TRUE" : "FALSE") " / " (r>0 ? r ">0" : r "!>0") " / " (r+0>0 ? r "+0>0" : r "+0!>0") " / " (r+0!=r ? r "+0!=" r : r "+0==" r) " / " (r && "`">r ? "'`'>" r " && " r : "!('`'>" r " && " r")")
+
+ _conl("`" r "' : " t)
+
+ return r }
+
+
+
+
+func _typ(p) {
+ return _t0=isarray(p) ? "#" : p==0 ? p=="" ? 0 : p in _CLASSPTR ? "`" : p ? 3 : 4 : p in _CLASSPTR ? "`" : p+0==p ? 5 : p ? 3 : 2 }
+
+func _typa(p,A) {
+
+ return _t0=isarray(p) ? "#" : p==0 ? p=="" ? 0 : p in A ? "`" : p ? 3 : 4 : p in A ? "`" : p+0==p ? 5 : p ? 3 : 2 }
+
+# # - p is array
+# ` - p is ptr detected in array _CLASSPTR(for _typ); or p is ptr detected in array A(for _typa)
+# 0 - p is undefined
+
+# 2 - p is string==""
+# 3 - p is string!=""
+# 4 - p is number 0
+# 5 - p is any number except 0(positive and negative)
+
+# str: _typ(p)+0 !_typ(p)+0
+# str/ptr _typ(p)>0 _typ(p)<1
+# str/arr "`">_typ(p0) && _t0
+# str/ptr/arr _typ(p) !_typ(p)
+# ptr _typ(p)=="`" _typ(p)<"`" ?
+# ptr/arr _typ(p)+0!=_t0
+# arr _typ(p)=="#" _typ(p)>"#" ?
+
+func zorr(A,i, r) {
+ if ( i in A ) _conl("`" i "' in A"); else _conl("`" i "' not in A")
+ r=A[i]=="" && A[i]==0
+ _conl("A[" i "] status is " r)
+ return
+
+ a=a+-a
+ _conl("``````````````" a "''''''''''''''''") }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+func test_splitstr(A) {
+
+ AA0[-1]="huj"; AA0["A"]="pizda"; AA0[1]="zhopa"
+ delete AB0[AB0[""]=""]
+ AC0[-1]="HUJ"; AC0["A"]="PIZDA"; AC0[1]="ZHOPA"
+
+ _SPLITSTRB0["1"]
+
+
+ wonl=""
+ _tstv(0,A,0,"_tstv")
+ _conl(wonl)
+ _wrfile("wonl.out",wonl)
+ }
+
+
+
+func _tstv(p,A,r,f) {
+
+ if ( f=="" ) f="tst_splitstr"
+
+ @f(_NOP,A,p)
+ @f(AA0,A,p)
+ @f(AB0,A,p)
+ @f(AC0,A,p)
+ @f("",A,p)
+ @f("a",A,p)
+ @f("´a",A,p)
+ @f("´",A,p)
+ @f("a´´´,ba´´´,",A,p)
+ @f("´,",A,p)
+
+ @f(",",A,p)
+ @f("´a,",A,p)
+ @f("ab,",A,p)
+ @f("ab,´",A,p)
+ @f("´a´,,ba",A,p)
+ @f(",a,,b´,c,,´a,,´,,,",A,p)
+
+ }
+
+func _wonl(t) {
+ wonl=wonl _ln(t) }
+
+func _wonline(t) {
+ wonl=wonl _ln(substr(" _ " t " _____________________________________________________________________________________________________________________________________",1,126)) }
+
+func tst_splitstr(t,A,R, r) {
+ delete A; A["not cleared"]
+ _wonl()
+ _wonline("_splitstr(" (isarray(t) ? "ARR" (length(t)>0 ? "#" (t[1]!="zhopa" ? "U" : "l") : "") : _val0(t)) ",A" (isarray(R) ? ", ARR" (length(R)>0 ? "#" (R[1]!="zhopa" ? "U" : "l") : "") : ", " _val0(R)) "):")
+
+ _wonl( _val0(r=_splitstr(t,A,R)))
+ _wonl("arrary A:"); _wonl(_dumparr(A))
+ return r }
+
+
+ #_____________________________________________________________________________
+ func _val(v,t) { if ( isarray(v) ) return _dumparr(v) _ln(t)
+ if ( v==0 && v=="" ) return _ln("- (ERRNO=" ERRNO ")") _ln(t)
+ return _ln(v "'") _ln(t) }
+
+ #_____________________________________________________________________________
+ func _val0(v) { if ( isarray(v) ) return _dumparr(v)
+ if ( v==0 && v=="" ) return "-"
+ return "\"" v "\"" }
+
+# add to _dumparr: checking that if element is undefined
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#_______________________________________________________________________
+func _cfguid(p,optr,pfx,sfx,hstrcnt,lstrchr) { #################### 0 #
+ delete _UIDOBL[p]
+ if ( _isptr(optr) ) { if ( optr==p ) { delete _UIDOBLV[p]; delete _UIDOBLV[_UIDOBLV[_UIDOBL[p]=p][""]=p][""] }
+ else if ( optr in _UIDOBL ) _UIDOBL[p]=_UIDOBL[optr] }
+ _UIDPFX[p]=_istr(pfx) ? pfx : ""; _UIDSFX[p]=_istr(sfx) ? sfx : ""
+ if ( _isptr(hstrcnt) ) { if ( hstrcnt!=p ) { _UIDCHR[p]=_UIDCHR[_UIDCNT[p]=_UIDCNT[hstrcnt]]; return p } hstrcnt=_NOP }
+ _UIDCNTL[_UIDCNT[p]=p]=_cfguidchr(p,hstrcnt,lstrchr); return p }
+ #_____________________________________________________
+ func _cfguidchr(p,h,l, H,L) {
+ if ( _isptr(l) ) { if ( l!=p ) return _UIDCHR[p]=_UIDCHR[l]; _UIDCHR[p]=p; l=_NOP }
+ _UIDCHR[p]=p
+ _splitstr(H,h,_UIDCHRH[_classys]); _splitstr(L,l,H)
+ delete _UIDCHRH[_UIDCHRH[p][""]=p][""]; delete _UIDCHRL[_UIDCHRL[p][""]=p][""]
+ _cfguidh(p,H,L); return _cfguidl(p,L,L) }
+ #_______________________________________________
+ func _cfguidh(p,H,L, hi,h,li) { for ( hi=1; hi in H; hi++ ) { h=H[hi]
+ for ( li=1; li in L; li++ ) _UIDCHRH[p][h L[li]] } }
+ func _cfguidl(p,H,L, hi,h,hl,li) { for ( hi=1; hi in H; hi++ ) { h=H[hi]
+ for ( li=1; li in L; li++ ) hl=_UIDCHRL[p][hl]=h L[li] }
+ return hl }
+
+# problem configuring uid by array charset: i can' understand what format of the array: possibly - remove array support
+# after removal of array format detection: there is unfinished conflicts: it is possible to totally remove array uid-gen initialization
+
+ #_____________________________________________________
+ BEGIN { _inituidefault() }
+ func _inituidefault( h,l,H,L) {
+ _classys =""
+
+ delete _UIDOBLV[_UIDOBLV[_UIDOBL[_classys]=_classys][""]=_classys][""]
+ _UIDPFX[_classys]; _UIDSFX[_classys]
+ _UIDCNT[_classys]=_UIDCHR[_classys]=_CLASSPTR[_classys]=_classys
+
+ h ="AB"
+ l =h "01"
+
+ _splitstr(H,h); _splitstr(L,l);
+ delete _UIDCHRH[_UIDCHRH[_classys][""]=_classys][""]; delete _UIDCHRL[_UIDCHRL[_classys][""]=_classys][""]
+ _UIDCNTH[_classys]; _cfguidh(_classys,H,L); _UIDCNTL[_classys]=_cfguidl(_classys,L,L)
+
+ _CLASSFN[_classys]["del"] ="_tobjDEL"
+ _CLASSFN[_classys]["new"] ="_tobjNEW"
+ _drawuid(_classys)
+ _initspecialuid() }
+ #_________________________________________
+ func _initspecialuid() {
+ _NOINDEX =_getuid()
+ _LEN =_getuid()
+ _PTR =_getuid()
+ _NAME =_getuid()
+ _TYPE =_getuid()
+ _FORMAT =_getuid()
+
+ }
+#_______________________________________________________________________
+func _getuid(p) { ################################################# 1 #
+ if ( p in _UIDOBL ) { for ( _tptr in _UIDOBLV[_getuida0=_UIDOBL[p]] ) { delete _UIDOBLV[_getuida0][_tptr]; _CLASSPTR[_tptr]=p; return _tptr } }
+ _CLASSPTR[_tptr=_UIDPFX[p] _getuid_i0(_UIDCNT[p],_UIDCHRL[_tptr=_UIDCHR[p]],_UIDCHRH[_tptr]) _UIDSFX[p]]=p
+ return _tptr }
+ #_____________________________________________________
+ func _getuid_i0(p,UL,UH) { if ( ""==_tptr=UL[_UIDCNTL[p]] ) { for ( _tptr in UH ) { delete UH[_tptr]; return (_UIDCNTH[p]=_tptr) (_UIDCNTL[p]=UL[""]) }
+ _fatal("out of UID") }
+ return _UIDCNTH[p] (_UIDCNTL[p]=_tptr) }
+#_______________________________________________________________________
+func _deluid(p) { ################################################# 1 #
+ if ( p in _CLASSPTR ) { _deluida0=_CLASSPTR[p]
+ if ( _deluida0 in _UIDOBL ) _UIDOBLV[_UIDOBL[_deluida0]][p] }
+ delete _CLASSPTR[p]; return _deluida0 }
+
+func test_uid( p,i) {
+ #test_cfg()
+ #return
+
+ _fclass=_cfguid(p=_getuid(_classys),p,"pfx","sfx","abc")
+ #_fclass=_cfguid(p=_getuid(_classys),_NOP,_NOP,_NOP,"",_classys)
+ _conl("_fclass uid: " _getuid(_fclass)); _drawuid(_fclass)
+ _conl("_classys uid: " _getuid(_classys))_drawuid(_classys)
+ for ( i=1; i<81; i++ ) _conl(i ": " _getuid(_fclass))
+ _drawuid(_fclass)
+ }
+
+
+func test_cfg( p,z,AA0,a) {
+ AA0[1]
+
+ _fclass=_cfguid(p=_getuid(_classys),_NOP,_NOP,_NOP,_NOP,_classys); _conl(); _conline(); _conl(); _drawuid(p)
+ _fclass=_cfguid(p=_getuid(_classys),AA0,AA0,AA0,AA0,_classys); _conl(); _conline(); _conl(); _drawuid(p)
+ a=_getuid(z=_fclass=_cfguid(p=_getuid(_classys),p,"<",">","ab","cd")); _conl("### " a "########"); _conline(); _conl(); _drawuid(p)
+ a=_getuid(_fclass=_cfguid(p=_getuid(_classys),z,0,0,_NOP,z)); _conl("### " a "########"); _conline(); _conl(); _drawuid(p)
+ a=_getuid(_fclass=_cfguid(p=_getuid(_classys),z,"^","$",z,_classys)); _conl("### " a "########"); _conline(); _conl(); _drawuid(p)
+ _fclass=_cfguid(p=_getuid(_classys),"oblptr","pfx","sfx","abcd"); _conl(); _conline(); _conl(); _drawuid(p)
+
+
+ _conl("```````````````````" z "'''''''''" ( _isptr(z) ? " ptr" : " not ptr"))
+ _drawuid(z)
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+func _drawuid(p, cn,ch,o) {
+ _conl("uid: " p)
+ _conl("\toblptr: " (p in _UIDOBL ? _UIDOBL[p] "'" : "-"))
+ if ( p in _UIDOBL ) { if ( !_isptr(o=_UIDOBL[p]) ) _conl(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> oblptr not pointer")
+ if ( !isarray(_UIDOBLV[o]) ) _conl(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> no OBLV array at ptr") }
+
+ _conl("\tprefix: " (p in _UIDPFX ? _UIDPFX[p] "'" : "-"))
+ _conl("\tsuffix: " (p in _UIDSFX ? _UIDSFX[p] "'" : "-"))
+ _conl("\tcounters: " (cn=p in _UIDCNT ? _UIDCNT[p] "'" : "-"))
+ if ( cn!="-" ) { _conl("\t\tcntrL: " _UIDCNTL[_UIDCNT[p]] "'")
+ _conl("\t\tcntrH: " _UIDCNTH[_UIDCNT[p]] "'") }
+ _conl("\tcharset: " (ch=p in _UIDCHR ? _UIDCHR[p] "'" : "-"))
+ if ( ch!="-" ) { _conl("chrH: "); _conl(_dumparr(_UIDCHRH[_UIDCHR[p]])); _conl()
+ _conl("chrL: "); _conl(_dumparr(_UIDCHRL[_UIDCHR[p]])); _conl() }
+
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#_______________________________________________________________________
+func _splitstr(A,t,r) { ########################################### 1 #
+ if ( _istr(t) ) { if ( _splitstr_i0(A,t)>0 ) return _splitstrp0
+ if ( _istr(r) ) return _splitstr_i0(A,r) }
+ else { if ( it=="A" ) if ( length(t)>0 ) { _movarr(A,t); return 0-length(A) }; _istr(r) }
+ if ( it=="A" ) if ( length(r)>0 ) { _movarr(A,r); return 0-length(A) } }
+ #_____________________________________________________
+ func _splitstr_i0(A,t, C) {
+ if ( 2>_splitstrq0=patsplit(t,_SPLITSTRA0,/([^,\xB4]*\xB4.)*[^,\xB4]*/) ) _splitstrq0=split(gensub(/\xB4(.)/,"\\1","G",t),_SPLITSTRA0,"")
+ delete A; _splitstri0=_splitstrp0=0
+ while ( _splitstri0++<_splitstrq0 ) {
+ if ( (t=gensub(/\xB4(.)/,"\\1","G",_SPLITSTRA0[_splitstri0])) in C || t=="" ) continue
+ C[A[++_splitstrp0]=t] }
+ return _splitstrp0 }
+
+# there is problem with string's format: i can;t easilly merge 2 charsets: comma-divided and every-char-divided strings
+
+#_______________________________________________________________________
+func _isptr(p) { ################################################## 1 #
+ if ( isarray(p) ) { is=_NOP; it="A"; return 0 }
+ is=p; if ( p==0 && p=="" ) { it="-"; return 0 }
+ if ( p in _CLASSPTR ) return it="P"
+ it="S"; return 0 }
+#_______________________________________________________________________
+func _istr(p) { ################################################### 1 #
+ if ( isarray(p) ) { is=_NOP; it="A"; return 0 }
+ is=p; if ( p==0 && p=="" ) { it="-"; return 0 }
+ return it=p=="" ? "s" : "S" }
+
+#______________________________________________________________________________________________
+func _START( t,i,A) { #########################################################################
+ _torexp_init()
+ test_uid()
+ return
+ _conl(patsplit("a,b,c",A,/[^,]/,B))
+ test_splitstr(); return
+
+
+ A[""]; _CLASSPTR["ptr"]; ALTARR["ptra"]
+ _conl(_dumparr(SYMTAB))
+ BB[1]=_NOP
+ zorr(1,2,3,4,5,6)
+ zorr(BB,1)
+
+
+ _rtn()
+ _rtn("")
+ _rtn(0); _rtn("0")
+ _rtn(1); _rtn("1")
+ _rtn(-1); _rtn("-1")
+ _rtn("huj")
+ _rtn("ptr")
+ _rtn("ptra",ALTARR)
+ _rtn(ALTARR)
+ _rtn(ALTARR,ALTARR)
+
+
+ return
+ _tstini()
+
+ return
+
+ _splitpath_test()
+# _split_regpath()
+ return
+
+ hh="CPU"
+ _conl("go1!")
+ _conl(_var(_sharepath(hh,"gdfsgdsgsd sdgsdighjui teretiewrotrewut 345345345 rtjtireutireu huj")))
+ _conl("go2!")
+ _conl(_var(_sharelist(AAA,hh),_dumparr(AAA)))
+ _conline()
+ A[1]="h"
+ A[3]="j"
+ t="pizda"
+ if ( match(t,/^pi(Z)da/,A) ) _conl("match")
+ else _conl("not match")
+ _conl(_dumparr(A))
+ return
+
+
+
+
+
+
+
+ _pathSMA="C:\\Program Files\\Altiris\\Altiris Agent\\"
+
+
+ DSPlugInPath =_pathSMA "Agents\\Deployment\\Agent\\"
+ DSAutoPath =_pathSMA
+
+ if ( !_sysinfo(_SYS,_hostname) ) _fatal("_sysinfo: unknown error")
+ _REG[""]; delete _REG[""]
+ _servoutput=_CHR["EOL"] _cmd("sc query state= all")
+
+ _dsbasepath="\\\\CPU\\CPU\\DEV\\PROJECT\\_DS\\"
+ _rdreg(_REG,"HKEY_LOCAL_MACHINE\\SOFTWARE\\Altiris")
+ _wrfile("rego.txt",_dumparr(_REG)); _conl("fF")
+ #_______________________________________________________________________
+
+ c=_getreg_i1(DDD,"HKEY_LOCAL_MACHINE\\SOFTWARE\\Altiris\\Altiris Agent\\Plugin Objects\\„~.*”Install path",_REG)
+#_________________________________________________________________________________________
+ pp=_n("NAME","NS")
+ #pp=_n()
+ #___________________________________________________________________________________
+ p=_defsolution(pp,"DS Plug-in","HKEY_LOCAL_MACHINE\\SOFTWARE\\Altiris\\Altiris Agent\\Plugin Objects\\Agents\\")
+ ClientConfiguration =_defdll(p,"Client Configuration","ClientConfiguration")
+ ClientImagingPrep =_defdll(p,"Client Inaging Preparation","ClientImagingPrep")
+ ClientImaging =_defdll(p,"Client Imaging","ClientImaging")
+ ClientPCT =_defdll(p,"Client PCT","ClientPCT")
+ ClientRebootTo =_defdll(p,"Client Reboot To","ClientRebootTo")
+ DeploymentAgent =_defdll(p,"Deployment Agent","Deployment Agent")
+ DeploymentSolutionBaseAgent =_defdll(p,"Deployment Solution Base Agent","Deployment Solution Base Agent")
+
+ ClientBCDEdit =_defile(p,"Client BCD Edit","ClientBCDEdit.dll")
+ ClientCopyFile =_defile(p,"Client Copy File","ClientCopyFile.dll")
+ ClientPreImage =_defile(p,"Client Pre Image","ClientPreImage.dll")
+ ClientRebootTo =_defile(p,"Client Reboot To","ClientRebootTo.dll")
+ _defile(p,"ConfigService.exe","ConfigService.exe","")
+ _defile(p,"config.dll","config.dll","")
+
+ _defsrv(p,"DS Plug-in Service","Altiris Deployment Solution - System Configuration")
+ _defreg(p,"Deployment Agent Path","HKEY_LOCAL_MACHINE\\SOFTWARE\\Altiris\\Deployment\\AgentInstallPath.STR")
+ _defile(p,"Altiris_DeploymentSolutionAgent_7_1_x86.msi", _SYS["OSArchitecture"]=="64-bit" ? "C:\\Program Files\\Altiris\\Altiris Agent\\Agents\\SoftwareManagement\\Software Delivery\\{9D76E4CA-377A-472D-A82E-EDAD77E7E4ED}\\cache\\Altiris_DeploymentSolutionAgent_7_1_x64.msi" : "C:\\Program Files\\Altiris\\Altiris Agent\\Agents\\SoftwareManagement\\Software Delivery\\{4B747D25-612F-48FC-B6B5-9916D1BB755C}\\cache\\Altiris_DeploymentSolutionAgent_7_1_x86.msi","")
+ _defdir(p,"Deployment Folder",a=gensub(/[^\\]*$/,"",1,_rdsafe(_REG,"HKEY_LOCAL_MACHINE\\SOFTWARE\\Altiris\\Deployment\\AgentInstallPath.STR","C:\\Program Files\\Altiris\\Altiris Agent\\Agents\\Deployment\\Agent\\")))
+
+ #___________________________________________________________________________________
+ p=_defsolution(pp,"DS Auto","HKEY_LOCAL_MACHINE\\SOFTWARE\\Altiris\\Altiris Agent\\Plugin Objects\\Agents\\")
+ _defdir(p,"C:\\Boot\\Altiris\\iso\\boot\\fonts\\","C:\\Boot\\Altiris\\iso\\boot\\fonts\\")
+ _defdir(p,"C:\\Boot\\Altiris\\iso\\sources\\","C:\\Boot\\Altiris\\iso\\sources\\")
+
+ _defile(p,"C:\\Boot\\Altiris\\iso\\autoinst.exe","C:\\Boot\\Altiris\\iso\\autoinst.exe","")
+ _defile(p,"C:\\Boot\\Altiris\\iso\\autoinst.ini","C:\\Boot\\Altiris\\iso\\autoinst.ini","")
+ _defile(p,"C:\\Boot\\Altiris\\iso\\autoutil.exe","C:\\Boot\\Altiris\\iso\\autoutil.exe","")
+ _defile(p,"C:\\Boot\\Altiris\\iso\\autoutil.ini","C:\\Boot\\Altiris\\iso\\autoutil.ini","")
+ _defile(p,"C:\\Boot\\Altiris\\iso\\bcdedit.exe","C:\\Boot\\Altiris\\iso\\bcdedit.exe","")
+ _defile(p,"C:\\Boot\\Altiris\\iso\\bootmgr","C:\\Boot\\Altiris\\iso\\bootmgr","")
+ _defile(p,"C:\\Boot\\Altiris\\iso\\bootsect.exe","C:\\Boot\\Altiris\\iso\\bootsect.exe","")
+
+ _defreg(p,"Deployment Automation reg.File","HKEY_LOCAL_MACHINE\\SOFTWARE\\Altiris\\AutoUtil\\File.XSZ","autoutil.exe")
+ _defreg(p,"Deployment Automation reg.Path","HKEY_LOCAL_MACHINE\\SOFTWARE\\Altiris\\AutoUtil\\Path.XSZ","%systemdrive%\\boot\\altiris\\iso")
+#_________________________________________________________________________________________
+
+ _check(pp)
+#_________________________________________________________________________________________
+
+ _conl(_report(pp)); _wrfile("report.txt",_report(pp))
+}#______________________________________________________________________________________________
+func _END() { #################################################################################
+
+}#______________________________________________________________________________________________
+func _EXIT() { ################################################################################
+
+}#____________________________________________________________________________________________________
+func _check(p) { ####################################################################################
+ _dll_check(p)
+ _file_check(p)
+ _serv_check(p)
+ _reg_check(p) }
+#_________________________________________________________________________________________
+func _report(p) { #######################################################################
+ _report_t0=_reportparnt=""; _report_i0(p); _tframe("_report_i0",p)
+ return _report_t0 }
+
+ func _report_i0(p,p0,p1,p2) { if ( p in _tPARENT ) {
+ if ( _reportparnt!=_reportparnt=_tPARENT[p] ) {
+ _report_t0=_report_t0 _ln() _ln((z="_ " _[_tPARENT[p]]["NAME"] " ") _getchrln("_",_CON_WIDTH-length(z)-2)) _ln(_getchrln("#",_CON_WIDTH-2)) _ln() } }
+ if ( "ERROR" in _[p] ) { _report_t0=_report_t0 _reporterr(p,_[p]["ERROR"])}
+ if ( "REPORT" in _[p] ) { _report_t0=_report_t0 _ln(_[p]["REPORT"]) } }
+#___________________________________________________________________________________
+func _creport(p,t,f, z) {
+ _[p]["REPORT"]=_[p]["REPORT"] _ln(t (f=="" ? "" : ": " f)) }
+#___________________________________________________________________________________
+func _reporterr(p,t3, pp,t,t2) {
+ t=""; pp=p
+ do { "NAME" in _[pp] ? t=_[pp]["NAME"] ": " t : "" } while ( pp=_rPARENT(pp) )
+ if ( match(t3,/\x00/) ) return substr(t3,1,RSTART-1) t substr(t3,RSTART+1)
+ return t t3 }
+#___________________________________________________________________________________
+func _dllerr(p,t,f) { if ( t!~/\x00/ ) t="ERROR: \x00" t
+ _errfl=1; _[p]["ERROR"]=_[p]["ERROR"] _ln(t (f=="" ? "" : ": " f)) }
+
+
+#_______________________________________________________________________________________________
+func _defsolution(pp,n,rn, p) { ###############################################################
+ _[p=_wLCHLD(pp,_n("TYPE","solution"))]["NAME"]=n
+ _[p]["REGPATH"]=rn
+ _[p]["ERRHOST"]=pp
+ return p }
+#_________________________________________________________________________________________
+func _defreg(pp,n,f,v, p) { #############################################################
+ _[p=_wLCHLD(pp,_n("TYPE","defreg"))]["NAME"]=n
+ _[p]["REGPATH"]=f; if ( !(v==0 && v=="") ) _[p]["VALUE"]=v }
+ #_______________________________________________________________________
+ func _reg_check(p) { _tframe("_reg_check_i0",p,p) }
+ #_______________________________________________
+ func _reg_check_i0(p,pp,p1,p2) {
+ if ( _[p]["TYPE"]=="defreg" ) {
+ if ( _[p]["REGPATH"] in _REG ) {
+ if ( "VALUE" in _[p] ) { if ( _[p]["VALUE"]==_REG[_[p]["REGPATH"]] ) _creport(p,substr("OK: REGENTRY MATCH(==" _[p]["VALUE"] "): " _[p]["REGPATH"],1,126))
+ else _dllerr(p,substr("REGENTRY NOT MATCH(!=" _[p]["VALUE"] "): " _[p]["REGPATH"],1,126)) }
+ else if ( _VAR[_[p]["REGPATH"]]==_REG[_[p]["REGPATH"]] ) _creport(p,substr("OK: REGPATH MATCH(==" _VAR[_[p]["REGPATH"]] "): " _[p]["REGPATH"],1,126))
+ else _dllerr(p,substr("REGPATH NOT MATCH(!=" _VAR[_[p]["REGPATH"]] "): " _[p]["REGPATH"],1,126)) }
+ else { _dllerr(p,substr("REGPATH NOT FOUND: " _[p]["REGPATH"],1,126)) } } }
+#_________________________________________________________________________________________
+func _defdir(pp,n,f,v, p) { #############################################################
+ _[p=_wLCHLD(pp,_n("TYPE","defdir"))]["NAME"]=n
+ _[p]["DIR"]=f
+ return p }
+#_________________________________________________________________________________________
+func _defile(pp,n,f,v, p) { #############################################################
+ _[p=_wLCHLD(pp,_n("TYPE","defile"))]["NAME"]=n
+ _[p]["FILE"]=f; if ( !(v==0 && v=="") ) _[p]["RQVERSION"]=v
+ return p }
+ #_______________________________________________________________________
+ func _file_check(p) { if ( 1 || "AGENT" in _[p] ) { _tframe("_file_check_i0",p,p) } }
+ #_______________________________________________
+ func _file_check_i0(p,pp,p1,p2, f,v) {
+ if ( _[p]["TYPE"]=="defile" ) {
+ f=_[p]["FILE"]
+ f=(match(f,/^.:/) ? "" : _[_[pp]["AGENT"]][".Install Path"] "\\") _[p]["FILE"]; if ( "RQVERSION" in _[p] ) v=_[p]["RQVERSION"]; else v=_[pp][".Product Version"]
+ ERRNO=""; if ( _th1(_[p]["DATA"]=_rdfile(f),ERRNO) ) { delete _[p]["DATA"]; return _dllerr(p,"read file: " ERRNO,f) }
+ if ( v!="" && v!=(_[p]["VERSION"]=_getfilever(f)) ) return _dllerr(p," file version mismatch: ==`" _[p]["VERSION"] "'; !=`" v "'",f)
+ _creport(p,substr("OK: FILE DETECTED" (v=="" ? "" : "(" v ")") ": " f,1,122)) }
+ else if ( _[p]["TYPE"]=="defdir" ) { if ( _filexist(f=_[p]["DIR"]) ) _creport(p,substr("OK: DIR DETECTED: " f,1,112))
+ else _dllerr(p,"directory " f " is not detected") } }
+#_________________________________________________________________________________________
+func _defsrv(pp,n,f,v, p) { #############################################################
+ _[p=_wLCHLD(pp,_n("TYPE","defsrv"))]["NAME"]=n
+ _[p]["SERVNAME"]=f
+ return p }
+ #_______________________________________________________________________
+ func _serv_check(p) { _tframe("_serv_check_i0",p,p) }
+ #_______________________________________________
+ func _serv_check_i0(p,p0,p1,p2,p3, i,q,c) {
+ if ( _[p]["TYPE"]=="defsrv" ) {
+ i=IGNORECASE; IGNORECASE=1
+ if ( match(_servoutput,roi="\\012DISPLAY_NAME: " _torexp(_[p]["SERVNAME"])) ) { _creport(p,"OK: SERVICE DETECTED: " substr(_[p]["SERVNAME"],1,112)) }
+ else { _dllerr(p,"service " _[p]["SERVNAME"] " not detected") } }
+ IGNORECASE=i }
+#_________________________________________________________________________________________
+func _defdll(pp,n,rn, p) { ##############################################################
+ _[p=_wLCHLD(pp,_n("TYPE","defdll"))]["NAME"]=n
+ _[p]["REGPATH"]=_[pp]["REGPATH"] rn
+ _[p]["ERRHOST"]=pp
+ return p }
+ #_______________________________________________________________________
+ func _dll_check(pp) { _dllchktv=""; _missfl=1
+ _tframe("_dll_check_i0",pp,_REG,pp) #also check that all dll have same version; also check that all dlls have success and then report that DS plug-in version n - installed
+ if ( 1 || "AGENT" in _[pp] ) {
+ if ( _dllchktv!=_[pp][".Product Version"] ) _dllerr(_[pp]["AGENT"],"agent version (" _[pp][".Product Version"] ") do not match all lib versions: " _dllchktv "'") }
+ else { if ( !_missfl ) _creport(pp,"agent not detected in registry")
+ else { _dllerr(pp,"agent not detected in registry but some registry entries exist:")
+ _tframe("_dll_check_i1",pp,pp) } } }
+ #_______________________________________________
+ func _dll_check_i1(p,pp,p1,p2,p3, i) {
+ if ( _[p]["TYPE"]=="defdll" ) {
+ for ( i in _[p] ) { if ( i~/^\./ ) _dllerr(pp," " _[p]["REGPATH"] "\\" substr(i,2)) } } }
+ #_______________________________________________
+ func _dll_check_i0(p,R,pp,p2, i,i2,r,f,v,rs,d,tv,tf) {
+ if ( _[p]["TYPE"]=="defdll" ) {
+ r=toupper(_[p]["REGPATH"]); rs=0; tf=0; tv=""
+ for ( i in R ) {
+ if ( toupper(substr(i,1,length(r)))==r ) { if ( (_chka0=substr(i,1+length(r),1))=="" || _chka0=="\\" ) {
+ rs=1; _missfl=1; _[p]["." substr(gensub(/\....$/,"",1,i),i2=2+length(r),length(i)-i2+1)]=R[i]
+ if ( chka0!="" ) rs=1 } } } #{ rs=_missfl=1; _[p]["." gensub(/^([^\\]+\\)+(.*)\..../,"\\2","G",i)]=R[i] } }
+ if ( rs ) { if ( (i=".Install Path") in _[p] && (i=".Product Version") in _[p] ) { _[p]["STATUS"]="PRESENT"
+ f=_[p][".Install Path"]; v=_[p][".Product Version"]
+ if ( !(".Module" in _[p]) ) { _[pp][".Product Version"]=v; _VAR["HKEY_LOCAL_MACHINE\\SOFTWARE\\Altiris\\Deployment\\AgentInstallPath.STR"]=f; _[pp]["AGENT"]=p; _creport("OK: DLL DETECTED(" v "): " substr(_[p]["NAME"],1,112)) }
+ else { if ( _dllchktv=="" ) _dllchktv=v
+ else if ( v!=_dllchktv ) return _dllerr(p,"different versions detected: " _dllchktv "!=" v "'")
+ ERRNO=""; if ( _th1(_[p]["DATA"]=_rdfile(f),ERRNO) ) { delete _[p]["DATA"]; return _dllerr(p,"read lib: " ERRNO,f) }
+ if ( v!=(_[p]["VERSION"]=_getfilever(f)) ) return _dllerr(p,"library file version mismatch: ==`" _[p]["VERSION"] "'; !=`" v "'",f)
+ _creport(p,"OK: LIBRARY DETECTED(" v "): " substr(f,1,100)) } }
+ else { tf=1; _dllerr(p,"registry corrupt: `" i "' not present") } }
+ else _[p]["STATUS"]="MISSED" } }
+#_____________________________________________________________________________________________________
+######################################################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+func _rdsafe(A,i,d) { if ( i in A ) return A[i]; return d }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #_____________________________________________________________________________
+ func _var(v,t) { if ( isarray(v) ) return _dumparr(v) _ln(t)
+ if ( v==0 && v=="" ) return _ln("- (ERRNO=" ERRNO ")") _ln(t)
+ return _ln(v "'") _ln(t) }
+ #_____________________________________________________________________________
+ func _dumpval(v,n) {
+ _dumpstr=_dumpstr (v=_ln((n==0 && n=="" ? "RET" : n) ": " (v==0 && v=="" ? "-" : v "'")))
+ return v }
+
+
+func _torexp(r) { return _subseqon(_TOREXPB0,gensub(/(^[ \t]+)|(([ \t]*(\\)+)+[ \t]*)|([ \t]+$)/,"\\4","G",_subseqoff(r,_TOREXPB0)),_TOREXPFN) }
+
+
+ #_______________________________________________
+ func _torexp_init() { _TOREXPFN[""] ="_strtorexp"
+ _TOREXPFN["~"] ="_torexp_rexp"
+ _TOREXPFN["="] ="_strtorexp"
+ _TOREXPFN[">"] ="_torexp_cmdstr"
+ _TOREXPFN["#"] ="_torexp_fmask"
+ _TOREXPFN["\""] ="_torexp_dqstr"
+ _TOREXPFN["'"] ="_torexp_sqstr"
+ }
+
+func _subseqoff(r,B) { patsplit(r,B,/\x84[^\x94]*\x94/); return gensub(/\x84[^\x94]*\x94/,"\x84","G",r) }
+
+func _subseqon(B,r,F, f,s,e,q,i,A) {
+ q=split(r,A,/\x84/); r=""; f=F[""]
+ for ( i=1; i<q; i++ ) { s=substr(e=B[i],2,1)
+ #_conl("curr r==`" r "': A[" i "]=`" A[i] "'")
+ #s=s in F ? _th0(F[s],_conl("handler `" F[s] "' for `" s "' ost=`" substr(e,3,length(e)-3) "'")) : _th0(F[""],_conl("default handler for `" s "'"))
+ s=s in F ? F[s] : F[""]
+ #_conl("`" f "'")
+ r=r @f(A[i]) @s(substr(e,3,length(e)-3)) }
+ return r @f(A[i]) }
+ #_______________________________________________
+ func _torexp_rexp(t) { return t }
+ #_______________________________________________
+ func _strtorexp(t) { gsub(/[\\\.\?\*\+\-\(\)\{\}\[\]\^\$\/\|]/,"\\\\&",t)
+ t=split(t,_TOREXP_STRA,/[\x00-\x1F]/,_TOREXP_STRB); _torexp_strt0=""
+ for ( _torexp_stri0=1; _torexp_stri0<t; _torexp_stri0++ ) _torexp_strt0=_torexp_strt0 _TOREXP_STRA[_torexp_stri0] "\\" _QASC[_TOREXP_STRB[_torexp_stri0]]
+ return _torexp_strt0 _TOREXP_STRA[_torexp_stri0] }
+
+ func _torexp_cmdstr(t) { return _strtorexp(gensub(/\^(.)/,"\\1","G",t)) }
+
+ func _torexp_fmask(t) { return gensub(/\\\*/,".*","G",gensub(/\\\?/,".?","G",_strtorexp(t))) }
+
+
+func _getfilever(f) { #############################################################
+ split(_cmd(_fileverpath " \"" f "\""),_GETFILEVERA0,/[ \t]+/)
+ if ( _GETFILEVERA0[5] ) return _GETFILEVERA0[5] }
+ #_____________________________________________________
+ BEGIN { _initfilever() }
+ func _initfilever() { _fileverpath ="\\\\CPU\\eGAWK\\LIB\\_filever\\_filever.exe" }
+
+#_________________________________________________________________________________________
+##########################################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+func _sharelist(D,h, q,c,l,A,B) { #################################################
+ delete D; c=_sharextool " \\\\" (h=="" ? h=ENVIRON["COMPUTERNAME"] : h) " 2>&1"
+ if ( match(c=_cmd(c),/\x0AShare[^\x0A]*Remark/) ) {
+ gsub(/(^[^-]*\x0D?\x0A-+\x0D?\x0A[ \t]*)|(\x0D?\x0AThe command completed successfully.*$)/,"",c)
+ l=RLENGTH-7; split(c,A,/([ \t]*\x0D?\x0A)+[ \t]*/)
+ for ( c in A ) if ( match(A[c],/((([^ \t:]+[ \t]+)*[^ \t:]+)[ \t]+)([A-Za-z])[ \t]*:/,B) && ++q ) D[B[2]]=A[c]~/\.\.\.$/ ? _sharepath(h,B[2]) : gensub(/[ \t\\\/]*$/,"\\\\",1,substr(A[c],1+B[1,"length"],l-B[1,"length"]))
+ return q }
+ return _rmtsharerr(h,c) }
+#_____________________________________________________________________________
+func _sharepath(h,s, A) { ###################################################
+ s=_sharextool " \\\\" (h=="" ? h=ENVIRON["COMPUTERNAME"] : h) "\\\"" s "\" 2>&1"
+ if ( match(s=_cmd(s),/\x0APath[ \t]+([^\x0D\x0A]+)/,_SHAREPATHA0) ) return gensub(/[ \t\\\/]*$/,"\\\\",1,_SHAREPATHA0[1])
+ return _rmtsharerr(h,s) }
+ #___________________________________________________________
+ func _rmtsharerr(h,t) { gsub(/[\x0D\x0A]+/,"",t)
+ if ( t~/^The command failed: 53/) ERRNO="host not found: \\\\" h
+ else ERRNO=t ": \\\\" h }
+ #_____________________________________________________
+ BEGIN { _initshare() }
+ func _initshare() { _sharextool ="\\\\CPU\\eGAWK\\LIB\\_share\\_share.exe" }
+#_________________________________________________________________________________________
+##########################################################################################
+
+
+
+
+
+
+
+
+func _extfn_init() { ##############################################################
+
+ _formatstrs_init(); _formatstrd_init(); _formatrexp_init()
+
+ _unformatstr_init()
+
+ _mac_init()
+
+}#__________________________________________________________________________________
+####################################################################################
+
+
+
+
+#___________________________________________________________________________________
+func _formatstrs(t) { _formatstrq0=split(t,_FORMATSTRA,/['\x00-\x1F\x80-\xFF]/,_FORMATSTRB); _formatstrs0=""
+ for ( t=1; t<_formatstrq0; t++ ) _formatstrs0=_formatstrs0 _FORMATSTRA[t] _FORMATSTRSESC[_FORMATSTRB[t]]
+ return _formatstrs0 _FORMATSTRA[t] }
+ #___________________________________________________________
+ func _formatstrs_init() { _defescarr(_FORMATSTRSESC,"[\\x00-\\x1F\\x80-\\xFF]",_QASC)
+ _defescarr(_FORMATSTRSESC,"[\\\\']","\\")
+ _FORMATSTRSESC["\t"]="\\t" }
+#_____________________________________________________________________________
+func _formatstrd(t) { _formatstrq0=split(t,_FORMATSTRA,/["\x00-\x1F\x80-\xFF]/,_FORMATSTRB); _formatstrs0=""
+ for ( t=1; t<_formatstrq0; t++ ) _formatstrs0=_formatstrs0 _FORMATSTRA[t] _FORMATSTRDESC[_FORMATSTRB[t]]
+ return _formatstrs0 _FORMATSTRA[t] }
+ #___________________________________________________________
+ func _formatstrd_init() { _defescarr(_FORMATSTRDESC,"[\\x00-\\x1F\\x80-\\xFF]",_QASC)
+ _defescarr(_FORMATSTRDESC,"[\\\\\"]","\\")
+ _FORMATSTRDESC["\t"]="\\t" }
+#_____________________________________________________________________________
+func _formatrexp(t) { _formatstrq0=split(t,_FORMATSTRA,/[\/\x00-\x1F\x80-\xFF]/,_FORMATSTRB); _formatstrs0=""
+ for ( t=1; t<_formatstrq0; t++ ) _formatstrs0=_formatstrs0 _FORMATSTRA[t] _FORMATREXPESC[_FORMATSTRB[t]]
+ return _formatstrs0 _FORMATSTRA[t] }
+ #___________________________________________________________
+ func _formatrexp_init() { _defescarr(_FORMATREXPESC,"[\\x00-\\x1F\\x80-\\xFF]",_QASC)
+ _defescarr(_FORMATREXPESC,"\\/","\\")
+ _FORMATREXPESC["\t"]="\\t" }
+#___________________________________________________________
+func _defescarr(D,r,S, i,c,t) { if ( isarray(S) ) { for ( i=0; i<256; i++ ) { if ( (c=_CHR[i])~r ) { D[c]="\\" S[c]; t=t c }
+ else if ( D[c]=="" ) D[c]=c } }
+ else { for ( i=0; i<256; i++ ) { if ( (c=_CHR[i])~r ) { D[c]=S c; if ( S!="" ) t=t c }
+ else if ( D[c]=="" ) D[c]=c } } return t }
+
+
+#___________________________________________________________________________________
+func _unformatstr(t) { _formatstrq0=split(t,_FORMATSTRA,/(\\[0-9]{1,3})|(\\x[[:xdigit:]]+)|(\\.)/,_FORMATSTRB); _formatstrs0=""
+ for ( t=1; t<_formatstrq0; t++ ) _formatstrs0=_formatstrs0 _FORMATSTRA[t] (_FORMATSTRB[t] in _QESCHR ? _QESCHR[_FORMATSTRB[t]] : _QESCHR[toupper(substr(_FORMATSTRB[t],length(_FORMATSTRB[t])-1))])
+ return _formatstrs0 _FORMATSTRA[t] }
+ #___________________________________________________________
+ func _unformatstr_init( i) { for ( i=0; i<256; i++ ) _QESCHR["\\" _CHR[i]] =_CHR[i]
+ for ( i=0; i<256; i++ ) { _QESCHR[sprintf("%.2X",i)] =_CHR[i]
+ _QESCHR["\\" sprintf("%.3o",i)] =_CHR[i]
+ if ( i<8 ) _QESCHR["\\" sprintf("%.1o",i)] =_CHR[i]
+ if ( i<64 ) _QESCHR["\\" sprintf("%.2o",i)] =_CHR[i]
+ if ( i<16 ) _QESCHR["\\x" sprintf("%.1X",i)]=_QESCHR["\\x" sprintf("%.1x",i)] =_CHR[i] }
+ i="a" 7 "b" 8 "f" 12 "n" 10 "r" 13 "t" 9 "v" 11
+ patsplit(i,_FORMATSTRA,/[^0-9]/,_FORMATSTRB)
+ for ( i in _FORMATSTRA ) _QESCHR["\\" _FORMATSTRA[i]]=_CHR[_FORMATSTRB[i]+0] }
+
+
+
+#___________________________________________________________________________________
+func _unformatrexp(t) { _formatstrq0=split(t,_FORMATSTRA,/(\\[0-9]{1,3})|(\\x[[:xdigit:]]+)|(\\.)/,_FORMATSTRB); _formatstrs0=""
+ for ( t=1; t<_formatstrq0; t++ ) _formatstrs0=_formatstrs0 _FORMATSTRA[t] (_FORMATSTRB[t] in _QESCHR ? _QESCREXP[_FORMATSTRB[t]] : _QESCREXP[toupper(substr(_FORMATSTRB[t],length(_FORMATSTRB[t])-1))])
+ return _formatstrs0 _FORMATSTRA[t] }
+ #___________________________________________________________
+ func _unformatrexp_init( i,a) { _formatstrs0="\\^$.[]|()*+?{}-sSwW<>yB`'"; delete _FORMATSTRB
+ for ( i=0; i<256; i++ ) _QESCREXP["\\" _CHR[i]] =index(_formatstrs0,_CHR[i]) ? "\\" _CHR[i] : _CHR[i]
+ for ( i=0; i<256; i++ ) { a=index(_formatstrs0,_CHR[i]) ? "\\" : ""
+ _QESCREXP[sprintf("%.2X",i)] =a _CHR[i]
+ _QESCREXP["\\" sprintf("%.3o",i)] =a _CHR[i]
+ if ( i<8 ) _QESCREXP["\\" sprintf("%.1o",i)] =a _CHR[i]
+ if ( i<64 ) _QESCREXP["\\" sprintf("%.2o",i)] =a _CHR[i]
+ if ( i<16 ) _QESCREXP["\\x" sprintf("%.1X",i)]=_QESCREXP["\\x" sprintf("%.1x",i)]=a _CHR[i] }
+ patsplit("a" 7 "b" 8 "f" 12 "n" 10 "r" 13 "t" 9 "v" 11,_FORMATSTRA,/[^0-9]/,_FORMATSTRB)
+ for ( i in _FORMATSTRA ) _QESCREXP["\\" _FORMATSTRA[i]]=_CHR[_FORMATSTRB[i]+0] }
+#
+# /rexpstr/ -> datastr
+# (\x00\t\+)* -> 28 00 09 5B 2B 29
+#
+# unesc all non-rexp characters: replace unesc of rexp-characters but do not remove it: \* -> \*, \x2A -> \*, \052 -> \*, \\ -> \#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+func _mpudefaulthnd(F,D,C,p1,p2,p3) { _mpuretsub(D,_mpucc0) }
+
+
+
+
+
+func _mpupfxsubret(F,D,C,p1,p2,p3) { return 1 }
+
+func _mpusfxsubret(F,D,C,p1,p2,p3) { return -1 }
+
+func _mpuretsub(D,t) { _mpuacc=D[_mpuptr++]; _accmpu(D,t); return 1 }
+
+
+ func _mac_init() { _MACPFX["\x84"] ="_macpfx84"
+ _MACPFX[""] ="_mpupfxsubret"
+
+
+ _MACPFX84SFX["\x84"] ="_macpfx84"
+ _MACPFX84SFX["\x94"] ="_macsfx94"
+ _MACPFX84SFX[""] ="_mpusfxsubret"
+
+
+ _VLDMAXSTRING =1000000
+
+ }
+
+
+func _macpfx84(F,D,C,p1,p2,p3) { return _mpusub(_MACPFX84SFX,D,C,D[_mpuptr++],p1,p2,p3) }
+
+
+
+
+
+func _macsfx94(F,D,C,p1,p2,p3) { return _mpuretsub(D,_handle8494(_mpuacc)) }
+
+func _handle8494(t) { return gensub(/(.)/,".\\1","G",t) }
+
+
+func _mpu(t,F,p1,p2,p3, D,C) {
+ if ( patsplit(t,C,/[\x84\x93\x94]/,D)>0 ) { _conline("CODE"); _conl(); _conl(_dumparr(C))
+ _conline("DATA"); _conl(); _conl(_dumparr(D))
+
+ _mpuptr=0; _mpucc0=""; _mpusub(F,D,C,D[_mpuptr++],p1,p2,p3)
+ return _mpuacc }
+ return t }
+
+func _mpusub(F,D,C,d,p1,p2,p3, q) {
+ q=D[_ARRLEN]
+ if ( _VLDMAXSTRING<length(d) ) { D[--D[_ARRLEN]]=d; _mpuacc="" }
+ else _mpuacc=d
+ d=_mpucc0
+ _conl("_mpusub enter: in `" _mpuacc "' / _mpuptr=" _mpuptr "'")
+ do { if ( (_mpucc0=C[_mpuptr]) in F ) { if ( isarray(F[_mpucc0]) ) _mpufn0=F[_mpucc0]
+ _conl("FN: `" _mpucc0 "' > CALL: `" (_mpufn0) "' : _mpuacc=" _mpuacc "'") }
+ else _mpufn0="_mpudefaulthnd" } while ( !_accmpu(D,_mpuacc,@_mpufn0(F,D,C,p1,p2,p3)) )
+ if ( _mpufn0==-1 ) { _conl("WARNING: unclosed expression: `" d _mpuacc"'")
+ _mpuacc=d _mpuacc }
+ _retarrm(D,q,"",_mpufn0==-1 ? _th0(d,_mpusubwrng("WARNING: unclosed expression",d _mpuacc)) : "")
+ # collect: _mpuacc=_retarr(D) _mpuacc
+ _conl("mpusub exit: _mpuacc: `" _mpuacc "'") }
+
+
+
+
+
+
+func _accmpu(A,a,n) { if ( n ) return _mpufn0=n
+ if ( _mpuacc ) { if ( _VLDMAXSTRING<length(_mpuacc)+length(a) ) {
+ if ( a ) { if ( _VLDMAXSTRING<length(_mpuacc) ) { A[--A[_ARRLEN]]=a; A[--A[_ARRLEN]]=_mpuacc }
+ else A[--A[_ARRLEN]]=a _mpuacc }
+ else A[--A[_ARRLEN]]=_mpuacc
+ _mpuacc="" }
+ else _mpuacc=a _mpuacc }
+ else _mpuacc=a }
+
+
+
+
+func _acc(A,a,t) { if ( t ) { if ( _VLDMAXSTRING<length(t)+length(a) ) {
+ if ( a ) { if ( _VLDMAXSTRING<length(t) ) { A[--A[_ARRPTR]]=a; A[--A[_ARRPTR]]=t }
+ else A[--A[_ARRPTR]]=a t }
+ else A[++A[_ARRLEN]]=t
+ return "" }
+ return a t }
+ return a }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+func _shortcut(D,S) { #############################################################
+ if ( isarray(D) ) { if ( isarray(S) ) { _addarrmask(D,S,_SHORTCUTWSTRUC) } # array,array2* - copy from array2 to array shorcut-specific elements
+ else if ( S==0 && S=="" ) { _addarrmask(D,_SHORTCUTDEFAULT,_SHORTCUTWSTRUC) } # array* - define shortcut-specific elements in array by default values
+ else if ( _isnotfileptr(S) ) { _addarrmask(D,_[S],_SHORTCUTWSTRUC) } # array,ptr* - copy from array _[ptr] to array shorcut-specific elements
+ else if ( _rd_shortcut(D,S) ) return } # array,filepath* - define in array shortcut-specific elements by reading its from shortcut file filepath(load shortcut)
+ else if ( D==0 && D=="" ) return _NOP # -* - no action(return -)
+ else if ( _isnotfileptr(D) ) { if ( isarray(S) ) { _addarrmask(_[D],S,_SHORTCUTWSTRUC) } # ptr,array* - copy from array to array _[ptr] shorcut-specific elements
+ else if ( S==0 && S=="" ) { _addarrmask(_[D],_SHORTCUTDEFAULT,_SHORTCUTWSTRUC) } # ptr* - define shortcut-specifc elements in array _[ptr] by default values
+ else if ( _isnotfileptr(S) ) { _addarrmask(_[D],_[S],_SHORTCUTWSTRUC) } # ptr,ptr2* - copy from array _[ptr2] to array _[ptr] shorcut-specific elements
+ else if ( _rd_shortcut(_[D],S) ) return } # ptr,filepath* - define in array _[ptr] shortcut-specific elements by reading its from shortcut file filepath(load shortcut)
+ else { if ( isarray(S) && _wr_shortcut(D,S) ) return # filepath,array* - [over]write shorcut file filepath; shortcut parameters will be defined by shortcut-specific elements in array(save shortcut)
+ else if ( S==0 && S=="" && _wr_shortcut(D,_SHORTCUTDEFAULT) ) return # filepath* - [over]write shorcut file filepath; shortcut parameters will be defined by default values
+ else if ( _isnotfileptr(S) && _wr_shortcut(D,_[S]) ) return # filepath,ptr* - [over]write shorcut file filepath; shortcut parameters will be defined by shortcut-specific elements in array _[ptr](save shortcut)
+ else if ( _rd_shortcut(_SHRTCUTA1,S) || _wr_shortcut(D,_SHRTCUTA1) ) return } # filepath,filepath2* - [over]write shorcut file filepath; shortcut parameters will be defined from shortcut file filepath2(copy shortcut)
+ return 1 }
+ #___________________________________________________________
+ func _wr_shortcut(f,S) { if ( (_shrtcutf0=_filepath(f)) ) {
+ ERRNO=""; _shrtcuta0=_shortcut_fpath " /A:C /F:\"" _shrtcutf0 "\" 2>&1"
+ for ( f in _SHORTCUTWSTRUC ) if ( f in S ) _shrtcuta0=_shrtcuta0 " " _SHORTCUTWSTRUC[f] "\"" gensub(/(\\?)$/,"\\1\\1",1,S[f]) "\""
+ if ( _shortcut_nerr(_cmd(_shrtcuta0),_shrtcutf0) ) return }
+ return ERRNO ? ERRNO="write shortcut: " ERRNO : _NOP }
+ #___________________________________________________________
+ func _rd_shortcut(D,f) { if ( (_shrtcutf0=_filepath(f)) && _shortcut_nerr(_shrtcuta0=_cmd(_shortcut_fpath " /A:Q /F:\"" _shrtcutf0 "\" 2>&1"),_shrtcutf0) ) {
+ ERRNO=""; split(_shrtcuta0,_SHRTCUTA0,/\x0D?\x0A/)
+ for ( _shrtcuta0 in _SHRTCUTA0 ) for ( f in _SHORTCUTRSTRUC ) if ( match(_SHRTCUTA0[_shrtcuta0],"^" f) ) D[_SHORTCUTRSTRUC[f]]=substr(_SHRTCUTA0[_shrtcuta0],1+RLENGTH) }
+ return ERRNO ? ERRNO="read shortcut: " ERRNO : _NOP }
+ #_____________________________________________________
+ func _shortcut_nerr(t,s, A) { if ( match(t,/\x0ASystem error (-?[0-9]+)[^\x0D\x0A]*[\x0D\x0A]+([^\x0D\x0A]+)/,A) ) {
+ ERRNO=(A[1] in _SHORTCUTERR ? _SHORTCUTERR[A[1]] : A[2] in _SHORTCUTERR ? _SHORTCUTERR[A[2]] : tolower(gensub(/^(The )?(((.*)\.$)|(.*[^\.]$))/,"\\4\\5","G",A[2])) "(" A[1] ")") (s ? ": `" s "'" : "") }
+ else return 1 }
+ #________________________________________________
+ func _shortcut_init( A,B,q) {
+ _SHORTCUTERR[2] ="file not found"
+ _SHORTCUTERR[3] ="no such filepath"
+ _SHORTCUTERR["The system cannot find the file specified."] ="no such filepath"
+ _SHORTCUTERR[5] ="file is folder"
+ _SHORTCUTERR["Access is denied."] ="file is folder"
+ _SHORTCUTERR[123] ="filepath syntax error"
+ _SHORTCUTERR["The filename, directory name, or volume label syntax is incorrect."] ="filepath syntax error"
+ q= "target /T: TargetPath= target? ; _target TargetPathExpanded= ; parameters /P: Arguments= paraneters? ; _parameters ArgumentsExpanded= ; startdir /W: WorkingDirectory= startdir? ; _startdir WorkingDirectoryExpanded= ; runstyle /R: RunStyle= 1 ; icon,index /I: IconLocation= icon,index? ; xicon,index IconLocationExpanded= ; shortcut key /H: HotKey= 0 ; description /D: Description= _env4: default shortcut "
+ split(q,_SHRTCUTA0,/[ \t]*;[ \t]*/)
+ for ( q in _SHRTCUTA0 ) if ( match(_SHRTCUTA0[q],/^([^\t]+)\t+([^\t]+)(\t+([^\t]+)(\t+([^\t]+))?)?/,B) ) {
+ if ( B[3]=="" ) _SHORTCUTRSTRUC[B[2]]=B[1]
+ else if ( B[5]=="" ) { _SHORTCUTWSTRUC[_SHORTCUTRSTRUC[B[4]]=B[1]]=B[2]; delete _SHORTCUTDEFAULT[B[1]] }
+ else { _SHORTCUTWSTRUC[_SHORTCUTRSTRUC[B[4]]=B[1]]=B[2]; _SHORTCUTDEFAULT[B[1]]=B[6] } }
+ else _fatal("_shortcut.init: _shortcut_struc: syntax error: `" _SHRTCUTA0[q] "'")
+ _SHRTCUTA1[""]; delete _SHRTCUTA1[""]
+ _shortcut_fpath="\\\\localhost\\eGAWK\\LIB\\_shortcut\\_shortcut.exe" }
+#_______________________________________________________________________
+########################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+END{ ###############################################################################
+
+ if ( _gawk_scriptlevel<1 ) {
+ close(_errlog_file)
+ p=_Zimport(_rdfile(_errlog_file),_N())
+ if ( (t=_get_errout(p))!="" ) _expout(t,"/dev/stderr") } }
+#___________________________________________________________________________________
+####################################################################################
+
+#_____________________________________________________________________________
+func _expout(t,d, a,b) { ####################################################
+ a=BINMODE; b=ORS; BINMODE="rw"; ORS=""
+ print t > (d ? d : (d=_errlog_file)); fflush(d)
+ BINMODE=a; ORS=b }
+#_______________________________________________________________________
+func _fatal(t,d, A) { #################################################
+ if ( _ERRLOG_FF ) {
+ A["TYPE"]="FATAL"; A["TEXT"]=t
+ _log(A,d) }
+ if ( !d ) exit }
+#_______________________________________________________________________
+func _error(t,d, A) { #################################################
+ if ( _ERRLOG_EF ) {
+ A["TYPE"]="ERROR"; A["TEXT"]=t
+ _log(A,d) } }
+#_______________________________________________________________________
+func _warning(t,d, A) { ###############################################
+ if ( _ERRLOG_WF ) {
+ A["TYPE"]="WARNING"; A["TEXT"]=t
+ _log(A,d) } }
+#_______________________________________________________________________
+func _info(t,d, A) { ##################################################
+ if ( _ERRLOG_IF ) {
+ A["TYPE"]="INFO"; A["TEXT"]=t
+ _log(A,d) } }
+#_______________________________________________________________________
+func _verb(t,d, A) { ##################################################
+ if ( _ERRLOG_VF ) {
+ A["TYPE"]="VERB"; A["TEXT"]=t
+ _log(A,d) } }
+#_______________________________________________________________________
+func _trace(t,d, A) { #################################################
+ if ( _ERRLOG_TF ) {
+ A["TYPE"]="TRACE"; A["TEXT"]=t
+ _log(A,d) } }
+#_________________________________________________________________
+func _log(A,p, a,B) { ###########################################
+ if ( isarray(A) ) {
+ A["TIME"]=_getime(); A["DATE"]=_getdate()
+ if ( p ) {
+ _tLOG[p=_wLCHLD(p,_N())][""]; delete _tLOG[p][""]
+ _movarr(_tLOG[p],A)
+ return p }
+ _expout("_ERRLOG: " _Zexparr(A) "\x0A") }
+ else {
+ B["TEXT"]=A; B["TYPE"]=""
+ return _log(B,p) } }
+#_______________________________________________________________________
+func _yexport(p) { #####################################################
+ return _tframe("_yexport_i0",p) }
+#_______________________________________________________________________
+func _yexport_i0(p,p0,p1,p2) {
+ if ( p in _tLOG ) return "_ERRLOG: " _Zexparr(_tLOG[p]) "\x0A"
+ if ( p in _tSTR ) {
+ p=_tSTR[p]; gsub(/\x1B/,"\x1B\x3B",p); gsub(/\x0A/,"\x1B\x3A",p)
+ return p "\x0A" } }
+#_____________________________________________________________________________
+func _Zimport(t,p,A, c,i,n,B) { ##############################################
+ if ( p ) {
+ c=split(t,B,/\x0A/)
+ for ( i=1; i<=c; i++ ) {
+ if ( (t=B[i])=="" ) continue
+ gsub(/\x1B\x3A/,"\x0A",t)
+ if ( match(t,/^_ERRLOG: /) ) {
+ _tLOG[n=_wLCHLD(p,_N())][""]; delete _tLOG[n][""]
+ _Zimparr(_tLOG[n],substr(t,10)) }
+ else if ( (t=_pass(_IMPORT,t,p,A))!="" ) {
+ gsub(/\x1B\x3B/,"\x1B",t); _wLCHLD(p,_N(_tSTR,t)) } }
+ return p }
+ else _expout(t) }
+#_____________________________________________________________________________
+func _export_data(t,i, A) { #################################################
+ A["DATA"]=t; A["ID"]=i
+ _expout("_DATA: " _Zexparr(A) "\x0A") }
+#_________________________________________________________________
+BEGIN { _inspass(_IMPORT,"_import_data") }
+
+func _import_data(t,p,p2, a) {
+ if ( match(t,/^_DATA: /) ) {
+ _tDATA[a=_wLCHLD(p,_N())][""]; delete _tDATA[a][""]
+ _Zimparr(_tDATA[a],substr(t,8))
+ _conl("DATA: `" _tDATA[a]["ID"] "':`" _tDATA[a]["DATA"] "'")
+ return "" }
+ return t }
+
+#_____________________________________________________________________________
+func _get_errout(p) { #######################################################
+ return _tframe("_get_errout_i0",p) }
+#_______________________________________________________________________
+func _get_errout_i0(p, t,n,a) {
+ return p in _tLOG ? (_get_errout_i1(p) _get_errout_i3(p)) : "" }
+#_________________________________________________________________
+func _get_errout_i1(p, t,n,a) {
+ if ( p in _tLOG ) {
+ n=""
+ if ( _tLOG[p]["TYPE"] ) {
+ n=_tLOG[p]["TYPE"] ": " _get_errout_i2(p)
+ if ( match(_tLOG[p]["TEXT"],/\x1F/) ) {
+ t=n; gsub(/[^\t]/," ",t)
+ return _ln(n substr(_tLOG[p]["TEXT"],1,RSTART-1)) _ln(t substr(_tLOG[p]["TEXT"],RSTART+1)) } }
+ return _ln(n _tLOG[p]["TEXT"]) } }
+#_______________________________________________________________________
+func _get_errout_i2(p) {
+ return "FILE" in _tLOG[p] ? (_tLOG[p]["FILE"] ("LINE" in _tLOG[p] ? ("(" _tLOG[p]["LINE"] ")") : "") ": ") : "" }
+#_______________________________________________________________________
+func _get_errout_i3(p, t,ts,cl,cp,cr,a,b) {
+ if ( "LSTR" in _tLOG[p] ) {
+ t=_tLOG[p]["FULLSTR"]; ts=_tLOG[p]["TS"]; cp="^"
+ if ( "CSTR" in _tLOG[p] ) {
+ cr=_tLOG[p]["CSTR"]
+ cl=_tLOG[p]["CLSTR"]
+ if ( "CPSTR" in _tLOG[p] ) cp=_tLOG[p]["CPSTR"] }
+ cr=substr(cr,length(cl)+length(cp)+1)
+ return _ln(_tabtospc(t,ts)) _ln(_getchrln(" ",a=length(_tabtospc(_tLOG[p]["LSTR"],ts))) _getchrln("-",b=length(_tabtospc(cl,ts,a))) _getchrln("^",b=length(_tabtospc(cp,ts,a=a+b))) _getchrln("-",length(_tabtospc(cr,ts,a+b)))) } }
+#_____________________________________________________________________________
+func _get_logout(p) { #######################################################
+ return _tframe("_get_logout_i0",p) }
+#_______________________________________________________________________
+func _get_logout_i0(p, t,n,a) {
+ if ( p in _tLOG ) {
+ n= ("DATE" in _tLOG[p] ? (_tLOG[p]["DATE"] " ") : "") ("TIME" in _tLOG[p] ? (_tLOG[p]["TIME"] " ") : "")
+ if ( _tLOG[p]["TYPE"] ) {
+ n=n _tLOG[p]["TYPE"] ": " ("FILE" in _tLOG[p] ? ( _tLOG[p]["FILE"] ("LINE" in _tLOG[p] ? ("(" _tLOG[p]["LINE"] ")") : "") ": ") : "")
+ if ( match(_tLOG[p]["TEXT"],/\x1F/) ) {
+ t=n; gsub(/[^\t]/," ",t)
+ return _ln(n substr(_tLOG[p]["TEXT"],1,RSTART-1)) _ln(t substr(_tLOG[p]["TEXT"],RSTART+1)) } }
+ return _ln(n _tLOG[p]["TEXT"]) } }
+#___________________________________________________________________________________
+
+
+####################################################################################
+
+
+#_____________________________________________________________________________
+func _N(F,v, p) { ###########################################################
+ for ( p in _UIDS ) { delete _UIDS[p]; return _nN_i0(p,F,v) }
+ return _nN_i0(_tgenuid(),F,v) }
+#_______________________________________________________________________
+func _n(F,v, p) { #####################################################
+ for ( p in _UIDSDEL ) { delete _UIDSDEL[p]
+ delete _ptr[p]
+ delete _tPREV[p]; delete _tPARENT[p]; delete _tNEXT[p]
+ delete _tFCHLD[p]; delete _tQCHLD[p]; delete _tLCHLD[p]
+ delete _TMP0[p]; delete _TMP1[p]
+ delete _tLINK[p]; delete _tCLASS[p]
+ return _nN_i0(p,F,v) }
+ for ( p in _UIDS ) { delete _UIDS[p]; return _nN_i0(p,F,v) }
+ return _nN_i0(_tgenuid(),F,v) }
+#_____________________________________________________
+func _nN_i0(p,F,v) {
+ _[p][""]; delete _[p][""]; _ptr[p][""]; delete _ptr[p][""]
+ _TMP0[p][_ARRLEN]=_TMP1[p][_ARRLEN]=0
+ if ( isarray(F) ) { delete F[p]
+ if ( isarray(v) ) { F[p][""]; delete F[p][""]; _copyarr(F[p],v) }
+ else if ( !(v==0 && v=="") ) F[p]=v }
+ else { if ( !(F==0 && F=="") ) { if ( isarray(v) ) { _[p][F][""]; delete _[p][F][""]; _copyarr(_[p][F],v) }
+ else if ( v==0 && v=="" ) _mpu(F,p)
+ else _[p][F]=v } }
+ return p }
+#_____________________________________________________
+# F v action
+#-----------------------------------------------------
+# - * no additional action
+# A B delete A[p] and define A[p] as array; copy array B to array A[p]
+# A - delete A[p]
+# A "*" delete A[p]; A[p]="*"
+# "*" B define _[p]["*"] as array; copy array B to array _[p]["*"]
+# "*" - run _mpu program "*" for `p
+# "*0" "*1" _[p]["*0"]="*1"
+#___________________________________________________________
+func _tgenuid( c) { for ( _uidcntr in _UIDARR1 ) { delete _UIDARR1[_uidcntr]; for ( c in _UIDARR0 ) _UIDS[_uidcntr c]; delete _UIDS[_uidcntr c]; return _uidcntr c }
+ return _fatal("_tUID: Out of UID range") }
+#_____________________________________________________
+func _tgenuid_init( a,b,A) {
+ _ptrlength =4
+ a= "\x92\x93\x94\x95\x96\x97\x98\x99\x9A" "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7" "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF" "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF" "\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF"
+ split(a,A,""); for (a in A) for (b in A) _UIDARR0[A[a] A[b]] _UIDARR1[A[a] A[b]]; _uidcntr=A[a] A[b] }
+
+#_____________________________________________________________________________
+func _tdel(p, i) { ##########################################################
+ if ( p in _ ) {
+ _texclude(p)
+ for ( i in _ptr[p] ) { if ( isarray(_ptr[p][i]) ) _tdel_i1(_ptr[p][i])
+ else if ( (i=_ptr[p][i]) ) _tdel(i) }
+ if ( p in _tFCHLD ) { i=_tFCHLD[p]; do { i=(i in _tNEXT ? _tNEXT[i] : "") _tdel_i0(i) } while ( i ) }
+ delete _[p]; _UIDSDEL[p] } }
+#_____________________________________________________
+func _tdel_i0(p, i) {
+ for ( i in _ptr[p] ) { if ( isarray(_ptr[p][i]) ) _tdel_i1(_ptr[p][i])
+ else if ( (i=_ptr[p][i]) ) _tdel(i) }
+ if ( p in _tFCHLD ) { i=_tFCHLD[p]; do { i=(i in _tNEXT ? _tNEXT[i] : "") _tdel_i0(i) } while ( i ) }
+ delete _[p]; _UIDSDEL[p] }
+#_____________________________________________________
+func _tdel_i1(A, i) {
+ for ( i in A ) { if ( isarray(A[i]) ) _tdel_i1(A[i])
+ else if ( (i=A[i]) ) _tdel(i) } }
+#_____________________________________________________________________________
+func _texclude(p, v,pp) { ################################################### # TEST!!!
+ if ( p in _ ) {
+ if ( p in _tPARENT ) {
+ pp=_tPARENT[p]; delete _tPARENT[p]
+ if ( p in _tPREV ) {
+ if ( p in _tNEXT ) { _tPREV[_tNEXT[v]=_tNEXT[p]]=v=_tPREV[p]; delete _tNEXT[p] }
+ else delete _tNEXT[_tLCHLD[pp]=_tPREV[p]]
+ delete _tPREV[p] }
+ else {
+ if ( p in _tNEXT ) { delete _tPREV[_tFCHLD[pp]=_tNEXT[p]]; delete _tNEXT[p] }
+ else { delete _tFCHLD[pp]; delete _tLCHLD[pp]; delete _tQCHLD[pp]; return p } }
+ --_tQCHLD[pp] }
+ else {
+ if ( p in _tPREV ) {
+ if ( p in _tNEXT ) { _tPREV[_tNEXT[v]=_tNEXT[p]]=v=_tPREV[p]; delete _tNEXT[p] }
+ else delete _tNEXT[_tPREV[p]]
+ delete _tPREV[p] }
+ else if ( p in _tNEXT ) { delete _tPREV[_tNEXT[p]]; delete _tNEXT[p] } }
+ return p } }
+#_______________________________________________________________________
+func _rFBRO(p) { ######################################################
+ if ( p ) {
+ if ( p in _tPARENT ) {
+ return _tFCHLD[_tPARENT[p]] }
+ while ( p in _tPREV ) {
+ p=_tPREV[p] }
+ return p }
+ return p }
+#_________________________________________________________________
+func _wFBRO(p,v ,a) { ###########################################
+ if ( p ) {
+ if ( v ) {
+ for ( a=p; a in _tPARENT; ) {
+ if ( (a=_tPARENT[a])==v ) {
+ return v } } ######################## v is parentesis of p
+ if ( p in _tPARENT ) {
+ p=_tPARENT[p]
+ if ( v in _tNEXT ) {
+ if ( v in _tPREV ) {
+ _tPREV[_tNEXT[a]=_tNEXT[v]]=a=_tPREV[v]; delete _tPREV[v]
+ if ( v in _tPARENT ) {
+ if ( p==(a=_tPARENT[v]) ) {
+ return _tFCHLD[p]=_tPREV[_tNEXT[v]=_tFCHLD[p]]=v }
+ --_tQCHLD[a] } }
+ else {
+ if ( v in _tPARENT ) {
+ if ( p==(a=_tPARENT[v]) ) { return v }
+ delete _tPREV[_tFCHLD[a]=_tNEXT[v]]; --_tQCHLD[a] }
+ else {
+ delete _tPREV[_tNEXT[v]] } }
+ ++_tQCHLD[p]; return _tFCHLD[p]=_tPREV[_tNEXT[v]=_tFCHLD[_tPARENT[v]=p]]=v }
+ else {
+ if ( v in _tPREV ) {
+ if ( v in _tPARENT ) {
+ delete _tNEXT[_tLCHLD[a=_tPARENT[v]]=_tPREV[v]]
+ if ( p==a ) {
+ delete _tPREV[v]
+ return _tFCHLD[p]=_tPREV[_tNEXT[v]=_tFCHLD[p]]=v }
+ --_tQCHLD[a] }
+ else {
+ delete _tNEXT[_tPREV[v]] }
+ delete _tPREV[v] }
+ else {
+ if ( v in _tPARENT ) {
+ if ( p==(a=_tPARENT[v]) ) { return v }
+ delete _tFCHLD[a]; delete _tLCHLD[a]; delete _tQCHLD[a] } }
+ ++_tQCHLD[p]; return _tFCHLD[p]=_tPREV[_tNEXT[v]=_tFCHLD[_tPARENT[v]=p]]=v } }
+ else {
+ while ( p in _tPREV ) {
+ p=_tPREV[p] }
+ if ( v in _tPREV ) {
+ if ( v in _tPARENT ) {
+ --_tQCHLD[a=_tPARENT[v]]; delete _tPARENT[v]
+ if ( v in _tNEXT ) {
+ _tNEXT[_tPREV[a]=_tPREV[v]]=a=_tNEXT[v] }
+ else {
+ delete _tNEXT[_tLCHLD[a]=_tPREV[v]] } }
+ else {
+ if ( v in _tNEXT ) {
+ _tNEXT[_tPREV[a]=_tPREV[v]]=a=_tNEXT[v] }
+ else {
+ delete _tNEXT[_tPREV[v]] } }
+ delete _tPREV[v] }
+ else {
+ if ( p==v ) { return v }
+ if ( v in _tPARENT ) {
+ if ( v in _tNEXT ) {
+ delete _tPREV[_tFCHLD[a=_tPARENT[v]]=_tNEXT[v]]; --_tQCHLD[a] }
+ else {
+ delete _tLCHLD[a=_tPARENT[v]]; delete _tFCHLD[a]; delete _tQCHLD[a] }
+ delete _tPARENT[v] }
+ else {
+ if ( v in _tNEXT ) {
+ delete _tPREV[_tNEXT[v]] } } }
+ return _tPREV[_tNEXT[v]=p]=v } }
+ else {
+ if ( v==0 ) {
+ return v } ######################## p=ptr, v=0
+ return v } } ######################## p=ptr, v=""
+ else {
+ if ( p==0 ) return v ######################## p=0
+ if ( v ) return _texclude(v) ######################## p="", v=ptr - exclude v
+ return v } } ######################## p=""
+#_______________________________________________________________________
+func _rPREV(p) { ######################################################
+ if ( (p) && (p in _tPREV) ) {
+ return _tPREV[p] }
+ return "" }
+#_________________________________________________________________
+func _wPREV(p,v, a,b) { #########################################
+ if ( p ) {
+ if ( v ) {
+ if ( p==v ) { return v } ######################## p=v=ptr
+ for ( a=p; a in _tPARENT; ) {
+ if ( (a=_tPARENT[a])==v ) {
+ return v } } ######################## v is parentesis of p
+ if ( v in _tNEXT ) {
+ if ( p==(a=_tNEXT[v]) ) { return v }
+ if ( v in _tPREV ) {
+ _tNEXT[_tPREV[a]=_tPREV[v]]=a
+ if ( v in _tPARENT ) {
+ --_tQCHLD[_tPARENT[v]] } }
+ else {
+ delete _tPREV[a]
+ if ( v in _tPARENT ) {
+ _tFCHLD[b=_tPARENT[v]]=a
+ --_tQCHLD[b] } } }
+ else {
+ if ( v in _tPREV ) {
+ if ( v in _tPARENT ) {
+ delete _tNEXT[_tLCHLD[a=_tPARENT[v]]=_tPREV[v]]
+ --_tQCHLD[a] }
+ else {
+ delete _tNEXT[_tPREV[v]] } }
+ else {
+ if ( v in _tPARENT ) {
+ delete _tLCHLD[a=_tPARENT[v]]; delete _tFCHLD[a]; delete _tQCHLD[a] } } }
+ if ( p in _tPREV ) {
+ _tNEXT[_tPREV[v]=_tPREV[p]]=v
+ if ( p in _tPARENT ) {
+ ++_tQCHLD[_tPARENT[v]=_tPARENT[p]] }
+ else {
+ delete _tPARENT[v] } }
+ else {
+ delete _tPREV[v]
+ if ( p in _tPARENT ) {
+ ++_tQCHLD[_tPARENT[_tFCHLD[a]=v]=a=_tPARENT[p]] }
+ else {
+ delete _tPARENT[v] } }
+ return _tPREV[_tNEXT[v]=p]=v }
+ else {
+ if ( v==0 ) {
+ return v } ######################## p=ptr, v=0
+ return v } } ######################## p=ptr, v=""
+ else {
+ if ( p==0 ) return v ######################## p=0
+ if ( v ) return _texclude(v) ######################## p="", v=ptr - exclude v
+ return v } } ######################## p=""
+#_______________________________________________________________________
+func _rPARENT(p) { ####################################################
+ if ( (p) && (p in _tPARENT) ) {
+ return _tPARENT[p] }
+ return "" }
+#_________________________________________________________________
+func _wPARENT(p,v) { ############################################
+ return v }
+#_______________________________________________________________________
+func _rFCHLD(p) { #####################################################
+ if ( (p) && (p in _tFCHLD) ) {
+ return _tFCHLD[p] }
+ return "" }
+#_________________________________________________________________
+func _wFCHLD(p,v, a) { ##########################################
+ if ( p ) {
+ if ( v ) {
+ if ( p==v ) { return v } ######################## p=v=ptr
+ for ( a=p; a in _tPARENT; ) {
+ if ( (a=_tPARENT[a])==v ) {
+ return v } } ######################## v is parentesis of p
+ if ( v in _tNEXT ) {
+ if ( v in _tPREV ) {
+ _tPREV[_tNEXT[a]=_tNEXT[v]]=a=_tPREV[v]; delete _tPREV[v]
+ if ( v in _tPARENT ) {
+ if ( p==(a=_tPARENT[v]) ) {
+ return _tFCHLD[p]=_tPREV[_tNEXT[v]=_tFCHLD[p]]=v }
+ --_tQCHLD[a] } }
+ else {
+ if ( v in _tPARENT ) {
+ if ( p==(a=_tPARENT[v]) ) { return v }
+ delete _tPREV[_tFCHLD[a]=_tNEXT[v]]; --_tQCHLD[a] }
+ else {
+ delete _tPREV[_tNEXT[v]] } }
+ if ( p in _tFCHLD ) {
+ ++_tQCHLD[p]; return _tFCHLD[p]=_tPREV[_tNEXT[v]=_tFCHLD[_tPARENT[v]=p]]=v }
+ delete _tNEXT[v] }
+ else {
+ if ( v in _tPREV ) {
+ if ( v in _tPARENT ) {
+ delete _tNEXT[_tLCHLD[a=_tPARENT[v]]=_tPREV[v]]
+ if ( p==a ) {
+ delete _tPREV[v]
+ return _tFCHLD[p]=_tPREV[_tNEXT[v]=_tFCHLD[p]]=v }
+ --_tQCHLD[a] }
+ else {
+ delete _tNEXT[_tPREV[v]] }
+ delete _tPREV[v] }
+ else {
+ if ( v in _tPARENT ) {
+ if ( p==(a=_tPARENT[v]) ) { return v }
+ delete _tFCHLD[a]; delete _tLCHLD[a]; delete _tQCHLD[a] } }
+ if ( p in _tFCHLD ) {
+ ++_tQCHLD[p]; return _tFCHLD[p]=_tPREV[_tNEXT[v]=_tFCHLD[_tPARENT[v]=p]]=v } }
+ _tQCHLD[p]=1; return _tFCHLD[_tPARENT[v]=p]=_tLCHLD[p]=v }
+ else {
+ if ( v==0 ) {
+ if ( p in _tFCHLD ) { ######################## p=ptr, v=0 > delete all chld
+ v=_tFCHLD[p]
+ delete _tFCHLD[p]; delete _tLCHLD[p]; delete _tQCHLD[p]
+ do{
+ delete _tPARENT[v] } while ( (v in _tNEXT) && (v=_tNEXT[v]) ) } }
+ return v } } ######################## p=ptr, v="" > ignore action
+ else {
+ if ( p==0 ) return v ######################## p=0
+ return v } } ######################## p=""
+#_______________________________________________________________________
+func _rLCHLD(p) { #####################################################
+ if ( (p) && (p in _tLCHLD) ) {
+ return _tLCHLD[p] }
+ return "" }
+#_________________________________________________________________
+func _wLCHLD(p,v, a) { ##########################################
+ if ( p ) {
+ if ( v ) {
+ if ( p==v ) { return v } ######################## p=v=ptr
+ for ( a=p; a in _tPARENT; ) {
+ if ( (a=_tPARENT[a])==v ) {
+ return v } } ######################## v is parentesis of p
+ if ( v in _tPREV ) {
+ if ( v in _tNEXT ) {
+ _tNEXT[_tPREV[a]=_tPREV[v]]=a=_tNEXT[v]; delete _tNEXT[v]
+ if ( v in _tPARENT ) {
+ if ( p==(a=_tPARENT[v]) ) {
+ return _tLCHLD[p]=_tNEXT[_tPREV[v]=_tLCHLD[p]]=v }
+ --_tQCHLD[a] } }
+ else {
+ if ( v in _tPARENT ) {
+ if ( p==(a=_tPARENT[v]) ) { return v }
+ delete _tNEXT[_tLCHLD[a]=_tPREV[v]]; --_tQCHLD[a] }
+ else {
+ delete _tNEXT[_tPREV[v]] } }
+ if ( p in _tLCHLD ) {
+ ++_tQCHLD[p]; return _tLCHLD[p]=_tNEXT[_tPREV[v]=_tLCHLD[_tPARENT[v]=p]]=v }
+ delete _tPREV[v] }
+ else {
+ if ( v in _tNEXT ) {
+ if ( v in _tPARENT ) {
+ delete _tPREV[_tFCHLD[a=_tPARENT[v]]=_tNEXT[v]]
+ if ( p==a ) {
+ delete _tNEXT[v]
+ return _tLCHLD[p]=_tNEXT[_tPREV[v]=_tLCHLD[p]]=v }
+ --_tQCHLD[a] }
+ else {
+ delete _tPREV[_tNEXT[v]] }
+ delete _tNEXT[v] }
+ else {
+ if ( v in _tPARENT ) {
+ if ( p==(a=_tPARENT[v]) ) { return v }
+ delete _tLCHLD[a]; delete _tFCHLD[a]; delete _tQCHLD[a] } }
+ if ( p in _tLCHLD ) {
+ ++_tQCHLD[p]; return _tLCHLD[p]=_tNEXT[_tPREV[v]=_tLCHLD[_tPARENT[v]=p]]=v } }
+ _tQCHLD[p]=1; return _tLCHLD[_tPARENT[v]=p]=_tFCHLD[p]=v }
+ else {
+ if ( v==0 ) {
+ if ( p in _tFCHLD ) { ######################## p=ptr, v=0 > delete all chld
+ v=_tFCHLD[p]
+ delete _tFCHLD[p]; delete _tLCHLD[p]; delete _tQCHLD[p]
+ do{
+ delete _tPARENT[v] } while ( (v in _tNEXT) && (v=_tNEXT[v]) ) } }
+ return v } } ######################## p=ptr, v="" > ignore action
+ else {
+ if ( p==0 ) return v ######################## p=0
+ return v } } ######################## p=""
+#_______________________________________________________________________
+func _rQCHLD(p) { #####################################################
+ if ( (p) && (p in _tQCHLD) ) {
+ return _tQCHLD[p] }
+ return "" }
+#_________________________________________________________________
+func _wQCHLD(p,v) { #############################################
+ if ( p ) {
+ if ( v ) { } ######################## p=ptr, v=ptr
+ else {
+ if ( v==0 ) {
+ if ( p in _tFCHLD ) { ######################## p=ptr, v=0 > delete all chld
+ v=_tFCHLD[p]
+ delete _tFCHLD[p]; delete _tLCHLD[p]; delete _tQCHLD[p]
+ do{
+ delete _tPARENT[v] } while ( (v in _tNEXT) && (v=_tNEXT[v]) ) } }
+ return v } } ######################## p=ptr, v="" > ignore action
+ else {
+ if ( p==0 ) {
+ return v } ######################## p=0
+ return v } } ######################## p=""
+#_______________________________________________________________________
+func _rNEXT(p) { ######################################################
+ if ( (p) && (p in _tNEXT) ) {
+ return _tNEXT[p] }
+ return "" }
+#_________________________________________________________________
+func _wNEXT(p,v, a,b) { #########################################
+ if ( p ) {
+ if ( v ) {
+ if ( p==v ) { return v } ######################## p=v=ptr
+ for ( a=p; a in _tPARENT; ) {
+ if ( (a=_tPARENT[a])==v ) {
+ return v } } ######################## v is parentesis of p
+ if ( v in _tPREV ) {
+ if ( p==(a=_tPREV[v]) ) { return v }
+ if ( v in _tNEXT ) {
+ _tPREV[_tNEXT[a]=_tNEXT[v]]=a
+ if ( v in _tPARENT ) {
+ --_tQCHLD[_tPARENT[v]] } }
+ else {
+ delete _tNEXT[a]
+ if ( v in _tPARENT ) {
+ _tLCHLD[b=_tPARENT[v]]=a
+ --_tQCHLD[b] } } }
+ else {
+ if ( v in _tNEXT ) {
+ if ( v in _tPARENT ) {
+ delete _tPREV[_tFCHLD[a=_tPARENT[v]]=_tNEXT[v]]
+ --_tQCHLD[a] }
+ else {
+ delete _tPREV[_tNEXT[v]] } }
+ else {
+ if ( v in _tPARENT ) {
+ delete _tFCHLD[a=_tPARENT[v]]; delete _tLCHLD[a]; delete _tQCHLD[a] } } }
+ if ( p in _tNEXT ) {
+ _tPREV[_tNEXT[v]=_tNEXT[p]]=v
+ if ( p in _tPARENT ) {
+ ++_tQCHLD[_tPARENT[v]=_tPARENT[p]] }
+ else {
+ delete _tPARENT[v] } }
+ else {
+ delete _tNEXT[v]
+ if ( p in _tPARENT ) {
+ ++_tQCHLD[_tPARENT[_tLCHLD[a]=v]=a=_tPARENT[p]] }
+ else {
+ delete _tPARENT[v] } }
+ return _tNEXT[_tPREV[v]=p]=v }
+ else {
+ if ( v==0 ) {
+ return v } ######################## p=ptr, v=0
+ return v } } ######################## p=ptr, v=""
+ else {
+ if ( p==0 ) return v ######################## p=0
+ if ( v ) return _texclude(v) ######################## p="", v=ptr - exclude v
+ return v } } ######################## p="", !v
+#_______________________________________________________________________
+func _rLBRO(p) { ######################################################
+ if ( p ) {
+ if ( p in _tPARENT ) {
+ return _tLCHLD[_tPARENT[p]] }
+ while ( p in _tNEXT ) {
+ p=_tNEXT[p] }
+ return p }
+ return p }
+#_________________________________________________________________
+func _wLBRO(p,v ,a) { ###########################################
+ if ( p ) {
+ if ( v ) {
+ for ( a=p; a in _tPARENT; ) {
+ if ( (a=_tPARENT[a])==v ) {
+ return v } } ######################## v is parentesis of p
+ if ( p in _tPARENT ) {
+ p=_tPARENT[p]
+ if ( v in _tPREV ) {
+ if ( v in _tNEXT ) {
+ _tNEXT[_tPREV[a]=_tPREV[v]]=a=_tNEXT[v]; delete _tNEXT[v]
+ if ( v in _tPARENT ) {
+ if ( p==(a=_tPARENT[v]) ) {
+ return _tLCHLD[p]=_tNEXT[_tPREV[v]=_tLCHLD[p]]=v }
+ --_tQCHLD[a] } }
+ else {
+ if ( v in _tPARENT ) {
+ if ( p==(a=_tPARENT[v]) ) { return v }
+ delete _tNEXT[_tLCHLD[a]=_tPREV[v]]; --_tQCHLD[a] }
+ else {
+ delete _tNEXT[_tPREV[v]] } }
+ ++_tQCHLD[p]; return _tLCHLD[p]=_tNEXT[_tPREV[v]=_tLCHLD[_tPARENT[v]=p]]=v }
+ else {
+ if ( v in _tNEXT ) {
+ if ( v in _tPARENT ) {
+ delete _tPREV[_tFCHLD[a=_tPARENT[v]]=_tNEXT[v]]
+ if ( p==a ) {
+ delete _tNEXT[v]
+ return _tLCHLD[p]=_tNEXT[_tPREV[v]=_tLCHLD[p]]=v }
+ --_tQCHLD[a] }
+ else {
+ delete _tPREV[_tNEXT[v]] }
+ delete _tNEXT[v] }
+ else {
+ if ( v in _tPARENT ) {
+ if ( p==(a=_tPARENT[v]) ) { return v }
+ delete _tLCHLD[a]; delete _tFCHLD[a]; delete _tQCHLD[a] } }
+ ++_tQCHLD[p]; return _tLCHLD[p]=_tNEXT[_tPREV[v]=_tLCHLD[_tPARENT[v]=p]]=v } }
+ else {
+ while ( p in _tNEXT ) {
+ p=_tNEXT[p] }
+ if ( v in _tNEXT ) {
+ if ( v in _tPARENT ) {
+ --_tQCHLD[a=_tPARENT[v]]; delete _tPARENT[v]
+ if ( v in _tPREV ) {
+ _tPREV[_tNEXT[a]=_tNEXT[v]]=a=_tPREV[v] }
+ else {
+ delete _tPREV[_tFCHLD[a]=_tNEXT[v]] } }
+ else {
+ if ( v in _tPREV ) {
+ _tPREV[_tNEXT[a]=_tNEXT[v]]=a=_tPREV[v] }
+ else {
+ delete _tPREV[_tNEXT[v]] } }
+ delete _tNEXT[v] }
+ else {
+ if ( p==v ) { return v }
+ if ( v in _tPARENT ) {
+ if ( v in _tPREV ) {
+ delete _tNEXT[_tLCHLD[a=_tPARENT[v]]=_tPREV[v]]; --_tQCHLD[a] }
+ else {
+ delete _tFCHLD[a=_tPARENT[v]]; delete _tLCHLD[a]; delete _tQCHLD[a] }
+ delete _tPARENT[v] }
+ else {
+ if ( v in _tPREV ) {
+ delete _tNEXT[_tPREV[v]] } } }
+ return _tNEXT[_tPREV[v]=p]=v } }
+ else {
+ if ( v==0 ) {
+ return v } ######################## p=ptr, v=0
+ return v } } ######################## p=ptr, v=""
+ else {
+ if ( p==0 ) return v ######################## p=0
+ if ( v ) return _texclude(v) ######################## p="", v=ptr - exclude v
+ return v } } ######################## p=""
+#_______________________________________________________________________
+func _rQBRO(p, c,p1) { ################################################
+ if ( p ) {
+ if ( p in _tPARENT ) {
+ return _tQCHLD[_tPARENT[p]] }
+ c=1; p1=p
+ while ( p1 in _tPREV ) {
+ c++; p1=_tPREV[p1] }
+ while ( p in _tNEXT ) {
+ c++; p=_tNEXT[p] }
+ return c }
+ return p }
+#_________________________________________________________________
+func _wQBRO(p,v) { ##############################################
+ return v }
+#_______________________________________________________________________
+func _rLINK(p) { ######################################################
+ return p in _tLINK ? _tLINK[p] : "" }
+#_________________________________________________________________
+func _wLINK(p,v) { ##############################################
+ return _tLINK[p]=v }
+#_____________________________________________________________________________
+func _tpush(p,aA, a) { ######################################################
+ if ( isarray(aA) ) {
+ delete _tSTACK[p][a=++_tSTACK[p][0]]; _tSTACK[p][a][""]; delete _tSTACK[p][a][""]
+ _movarr(_tSTACK[p][a],aA); return }
+ delete _tSTACK[p][a=++_tSTACK[p][0]]; return _tSTACK[p][a]=aA }
+#_________________________________________________________________
+func _tpop(p,aA, a) { ###########################################
+ if ( (a=_tSTACK[p][0])>0 ) {
+ _tSTACK[p][0]--
+ if ( isarray(_tSTACK[p][a]) ) {
+ delete aA; _movarr(aA,_tSTACK[p][a]); return }
+ return _tSTACK[p][a] }
+ _fatal("^" p ": Out of tSTACK") }
+#_________________________________________________________________
+func _tsetsp(p,v) { #############################################
+ return _tSTACK[p][0]=v }
+#_________________________________________________________________
+func _tgetsp(p) { ###############################################
+ return _tSTACK[p][0] }
+#_______________________________________________________________________
+########################################################################
+
+
+func _W(p,A,v) {
+ if ( isarray(v) ) {
+ if ( p ) {
+ delete A[p]; A[p][""]; delete A[p][""]
+ _movarr(A[p],v) }
+ return p }
+ if ( p ) {
+ delete A[p]; return A[p]=v }
+ return v }
+
+
+
+# _tDLINK progressive development: concrete _tDLINK function\processing algo; all frame's families support
+#_____________________________________________________________________________
+func _tframe(fF,p,p0,p1,p2) { ###############################################
+ delete _t_ENDF[++_t_ENDF[0]]
+ p=_isptr(p) ? isarray(fF) ? _tframe_i1(fF,p,p0,p1,p2) : _tframe_i0(fF,p,p0,p1,p2) : ""
+ --_t_ENDF[0]
+ return p }
+#___________________________________________________________
+func _tframe_i0(f,p,p0,p1,p2, a) {
+ while ( p in _tLINK ) p=_tLINK[p]
+ return p in _tFCHLD ? _tmframe_i0(f,_tFCHLD[p],p0,p1,p2) : (p in _tDLINK ? @f(_tDLINK[p],p0,p1,p2) : @f(p,p0,p1,p2)) }
+#___________________________________________________________
+func _tframe_i1(F,p,p0,p1,p2, a) {
+ while ( p in _tLINK ) p=_tLINK[p]
+ return p in _tFCHLD ? ("." in F ? _th1(a=F["."],@a(p,p0,p1,p2)) : "") _tmframe_i1(F,_tFCHLD[p],p0,p1,p2) : (">" in F ? _th1(a=F[">"],p in _tDLINK ? @a(_tDLINK[p],p0,p1,p2) : @a(p,p0,p1,p2)) : "") }
+#_________________________________________________________________
+func _tmframe(f,p,p0,p1,p2) { ###################################
+ delete _t_ENDF[++_t_ENDF[0]]
+ f=p ? _tmframe_i0(f,p,p0,p1,p2) : ""
+ --_t_ENDF[0]
+ return f }
+#___________________________________________________________
+func _tmframe_i0(f,p,p0,p1,p2, t) {
+ while ( (p) && (!(_t_ENDF[0] in _t_ENDF)) ) {
+ t=t _tframe_i0(f,p,p0,p1,p2, p=p in _tNEXT ? _tNEXT[p] : "") }
+ return t }
+#___________________________________________________________
+func _tmframe_i1(F,p,p0,p1,p2, t) {
+ while ( (p) && (!(_t_ENDF[0] in _t_ENDF)) ) {
+ t=t _tframe_i1(F,p,p0,p1,p2, p=p in _tNEXT ? _tNEXT[p] : "") }
+ return t }
+#_________________________________________________________________
+func _trunframe(f,p,p0,p1,p2) { #################################
+ return _tframe(f ? f : "_trunframe_i0",p,p0,p1,p2) }
+#_________________________________________________________________
+func _trunframe_i0(p,p0,p1,p2, f) {
+ if ( p in _tFN ) {
+ f=_tFN[p]
+ return @f(p,p0,p1,p2) } }
+#_____________________________________________________________________________
+func _tbframe(f,p,p0,p1) { ##################################################
+ delete _t_ENDF[++_t_ENDF[0]]
+ f=p ? _tbframe_i0(f,p,p0,p1) : ""
+ --_t_ENDF[0]
+ return f }
+#___________________________________________________________
+func _tbframe_i0(f,p,p0,p1, a) {
+ while ( p in _tLINK ) p=_tLINK[p]
+ return p in _tLCHLD ? _tmbframe(f,_tLCHLD[p],p0,p1) : @f(p,p0,p1) }
+#_________________________________________________________________
+func _tmbframe(f,p,p0,p1, t) { ##################################
+ while ( (p) && (!(_t_ENDF[0] in _t_ENDF)) ) {
+ t=t _tbframe_i0(f,p,p0,p1, p=p in _tPREV ? _tPREV[p] : "") }
+ return t }
+#_________________________________________________________________
+func _tbrunframe(f,p,p0,p1) { ###################################
+ return _tbframe(f ? f : "_trunframe_i0",p,p0,p1) }
+#_______________________________________________________________________
+func _tframex(f,p,p0,p1) { ############################################
+ delete _t_ENDF[++_t_ENDF[0]]
+ f=p ? _tframex_i0(f,p,p0,p1) : ""
+ --_t_ENDF[0]
+ return f }
+#___________________________________________________________
+func _tframex_i0(f,p,p0,p1) {
+ while ( p in _tLINK ) p=_tLINK[p]
+ return p in _tFCHLD ? _tmframex(f,_tFCHLD[p],p0,p1) : @f(p,p0,p1) }
+#_________________________________________________________________
+func _tmframex(f,p,p0,p1, t) { ##################################
+ while ( (p) && (!(_t_ENDF[0] in _t_ENDF)) ) {
+ t=t _tframex_i0(f,p,p0,p1); p=p in _tNEXT ? _tNEXT[p] : "" }
+ return t }
+#_________________________________________________________________
+func _trunframex(f,p,p0,p1) { ###################################
+ return _tframex(f ? f : "_trunframe_i0",p,p0,p1) }
+#_______________________________________________________________________
+func _tbframex(f,p,p0,p1) { ###########################################
+ delete _t_ENDF[++_t_ENDF[0]]
+ f=p ? _tbframex_i0(f,p,p0,p1) : ""
+ --_t_ENDF[0]
+ return f }
+#___________________________________________________________
+func _tbframex_i0(f,p,p0,p1) {
+ while ( p in _tLINK ) p=_tLINK[p]
+ return p in _tLCHLD ? _tmbframex(f,_tLCHLD[p],p0,p1) : @f(p,p0,p1) }
+#_________________________________________________________________
+func _tmbframex(f,p,p0,p1, t) { #################################
+ while ( (p) && (!(_t_ENDF[0] in _t_ENDF)) ) {
+ t=t _tbframex_i0(f,p,p0,p1); p=p in _tPREV ? _tPREV[p] : "" }
+ return t }
+#_________________________________________________________________
+func _tbrunframex(f,p,p0,p1) { ##################################
+ return _tbframex(f ? f : "_trunframe_i0",p,p0,p1) }
+#_____________________________________________________________________________
+func _tpass(f,p,p0,p1) { ####################################################
+ delete _t_ENDF[++_t_ENDF[0]]
+ f=p ? _tpass_i0(f,p,p0,p1) : ""
+ --_t_ENDF[0]
+ return f }
+#___________________________________________________________
+func _tpass_i0(f,p,p0,p1, a) {
+ while ( p in _tLINK ) p=_tLINK[p]
+ return p in _tFCHLD ? _tmpass(f,_tFCHLD[p],p0,p1) : @f(p,p0,p1) }
+#_________________________________________________________________
+func _tmpass(f,p,p0,p1) { #######################################
+ while ( (p) && (!(_t_ENDF[0] in _t_ENDF)) ) {
+ p0=_tbpass_i0(f,p,p0,p1, p=p in _tNEXT ? _tNEXT[p] : "") }
+ return p0 }
+#_________________________________________________________________
+func _trunpass(f,p,p0,p1) { #####################################
+ return _tpass(f ? f : "_trunframe_i0",p,p0,p1) }
+#_____________________________________________________________________________
+func _tpassx(f,p,p0,p1) { ###################################################
+ delete _t_ENDF[++_t_ENDF[0]]
+ f=p ? _tpassx_i0(f,p,p0,p1) : ""
+ --_t_ENDF[0]
+ return f }
+#___________________________________________________________
+func _tpassx_i0(f,p,p0,p1) {
+ while ( p in _tLINK ) p=_tLINK[p]
+ return p in _tFCHLD ? _tmpassx(f,_tFCHLD[p],p0,p1) : @f(p,p0,p1) }
+#_________________________________________________________________
+func _tmpassx(f,p,p0,p1) { ######################################
+ while ( (p) && (!(_t_ENDF[0] in _t_ENDF)) ) {
+ p0=_tbpassx_i0(f,p,p0,p1); p=p in _tNEXT ? _tNEXT[p] : "" }
+ return p0 }
+#_________________________________________________________________
+func _trunpassx(f,p,p0,p1) { ####################################
+ return _tpassx(f ? f : "_trunframe_i0",p,p0,p1) }
+#_____________________________________________________________________________
+func _tbpass(f,p,p0,p1) { ###################################################
+ delete _t_ENDF[++_t_ENDF[0]]
+ f=p ? _tbpass_i0(f,p,p0,p1) : ""
+ --_t_ENDF[0]
+ return f }
+#___________________________________________________________
+func _tbpass_i0(f,p,p0,p1, a) {
+ while ( p in _tLINK ) p=_tLINK[p]
+ return p in _tLCHLD ? _tmbpass(f,_tLCHLD[p],p0,p1) : @f(p,p0,p1) }
+#_________________________________________________________________
+func _tmbpass(f,p,p0,p1) { ######################################
+ while ( (p) && (!(_t_ENDF[0] in _t_ENDF)) ) {
+ p0=_tbpass_i0(f,p,p0,p1, p=p in _tPREV ? _tPREV[p] : "") }
+ return p0 }
+#_________________________________________________________________
+func _tbrunpass(f,p,p0,p1) { ####################################
+ return _tbpass(f ? f : "_trunframe_i0",p,p0,p1) }
+#_____________________________________________________________________________
+func _tbpassx(f,p,p0,p1) { ##################################################
+ delete _t_ENDF[++_t_ENDF[0]]
+ f=p ? _tbpassx_i0(f,p,p0,p1) : ""
+ --_t_ENDF[0]
+ return f }
+#___________________________________________________________
+func _tbpassx_i0(f,p,p0,p1) {
+ while ( p in _tLINK ) p=_tLINK[p]
+ return p in _tLCHLD ? _tmbpassx(f,_tLCHLD[p],p0,p1) : @f(p,p0,p1) }
+#_________________________________________________________________
+func _tmbpassx(f,p,p0,p1) { #####################################
+ while ( (p) && (!(_t_ENDF[0] in _t_ENDF)) ) {
+ p0=_tbpassx_i0(f,p,p0,p1); p=p in _tPREV ? _tPREV[p] : "" }
+ return p0 }
+#_________________________________________________________________
+func _tbrunpassx(f,p,p0,p1) { ###################################
+ return _tbpassx(f ? f : "_trunframe_i0",p,p0,p1) }
+#_______________________________________________________________________
+func _tend(a,b) { #####################################################
+ if ( b=="" ) return _t_ENDF[_t_ENDF[0]]=a
+ else return _t_ENDF[_t_ENDF[0]+a]=b }
+#_________________________________________________________________
+func _tifend(l) { ###############################################
+ return (_t_ENDF[0]+l) in _t_ENDF ? (_t_ENDF[_t_ENDF[0]+l] ? _t_ENDF[_t_ENDF[0]+l] : 1) : "" }
+
+
+#_____________________________________________________________________________
+func _tdelete(p, v) { ####################################################### # REMAKE EXCLUDE
+ if ( p ) _wLCHLD(_tDELPTR,p)
+ return v }
+
+
+#_____________________________________________________________________________
+func _tbrochld(p, f,pp) { ################################################### # TEST!!!
+ if ( p ) {
+ if ( p in _tFCHLD ) {
+ f=_tFCHLD[p]; delete _tFCHLD[p]; delete _tLCHLD[p]
+ if ( p in _tPARENT ) {
+ pp=_tPARENT[p]; delete _tPARENT[p]
+ if ( p in _tPREV ) {
+ _tNEXT[_tPREV[f]=_tPREV[p]]=f; delete _tPREV[p] }
+ else {
+ _tFCHLD[pp]=f }
+ for ( ; f in _tNEXT; f=_tNEXT[f] ) _tPARENT[f]=pp
+ _tPARENT[f]=pp
+ if ( p in _tNEXT ) {
+ _tPREV[_tNEXT[f]=_tNEXT[p]]=f; delete _tNEXT[p] }
+ else {
+ _tLCHLD[pp]=f }
+ _tQCHLD[pp]=_tQCHLD[pp]+_tQCHLD[p]-1
+ delete _tQCHLD[p]
+ return f }
+ else {
+ delete _tQCHLD[p]
+ if ( p in _tPREV ) {
+ _tNEXT[_tPREV[f]=_tPREV[p]]=f; delete _tPREV[p] }
+ for ( ; f in _tNEXT; f=_tNEXT[f] ) delete _tPARENT[f]
+ delete _tPARENT[f]
+ if ( p in _tNEXT ) {
+ _tPREV[_tNEXT[f]=_tNEXT[p]]=f; delete _tNEXT[p] }
+ return f } }
+ else {
+ if ( p in _tPARENT ) {
+ pp=_tPARENT[p]; delete _tPARENT[p]
+ if ( p in _tPREV ) {
+ if ( p in _tNEXT ) {
+ _tNEXT[_tPREV[f]=_tPREV[p]]=f=_tNEXT[p]; delete _tNEXT[p] }
+ else {
+ delete _tNEXT[_tLCHLD[pp]=_tPREV[p]] }
+ delete _tPREV[p]; _tQCHLD[pp]-- }
+ else {
+ if ( p in _tNEXT ) {
+ delete _tPREV[_tFCHLD[pp]=_tNEXT[p]]; delete _tNEXT[p]; _tQCHLD[pp]-- }
+ else {
+ delete _tFCHLD[pp]; delete _tLCHLD[pp]; delete _tQCHLD[pp] } } }
+ else {
+ if ( p in _tPREV ) {
+ if ( p in _tNEXT ) {
+ _tNEXT[_tPREV[f]=_tPREV[p]]=f=_tNEXT[p]; delete _tNEXT[p] }
+ else {
+ delete _tNEXT[_tPREV[p]] }
+ delete _tPREV[p] }
+ else {
+ if ( p in _tNEXT ) {
+ delete _tPREV[_tNEXT[p]]; delete _tNEXT[p] } } } } }
+ return p }
+
+# test _tbrochld fn; develope tOBJ r\w func specification for brochld func
+
+#_________________________________________________________________
+func _tinit_i0(D,S, i) {
+ for ( i in S ) {
+ if ( isarray(S[i]) ) {
+ if ( !isarray(D[i][""]) ) {
+ delete D[i]; D[i][""]; delete D[i][""] }
+ _N_i0(D[i],S[i]) }
+ else {
+ if ( isarray(D[i]) ) delete D[i]
+ D[i]=S[i] } } }
+#_______________________________________________________________________
+func W(p,p0,p1) { #####################################################
+ if ( isarray(p0) ) {
+ delete p0[p]
+ if ( isarray(p1) ) {
+ for ( i in p1 ) {
+ if ( isarray(p1[i]) ) {
+ p0[p][i][""]; delete p0[p][i][""]; _N_i0(p0[p][i],p1[i]) }
+ else p0[p][i]=p1[i] }
+ return p }
+ return p0[p]=p1 }
+ delete _[p][p0]
+ if ( isarray(p1) ) {
+ for ( i in p1 ) {
+ if ( isarray(p1[i]) ) {
+ _[p][p0][i][""]; delete _[p][p0][i][""]; _N_i0(_[p][p0][i],p1[i]) }
+ else _[p][p0][i]=p1[i] }
+ return p }
+ return _[p][p0]=p1 }
+
+
+
+
+#___________________________________________________________________________________
+# EMMULATED FUNCTIONAL FIELDS ######################################################
+
+#_____________________________________________________________________________
+func _rSQFIRST(g,p,A) { #####################################################
+ if ( isarray(A) ) return _rSQFIRSTA(g,p,A)
+ _SQTOPTR[g]=p; _SQSTACK[g][0]=0
+ return _rsqgetptr(g,p) }
+#_________________________________________________________________
+func _rSQFIRSTA(g,p,A) { ########################################
+ _SQTOPTR[g]=p; _SQSTACK[g][0]=0
+ if ( (p=_rsqgetptr(g,p)) in A ) return p
+ return _rSQNEXTA(g,p,A) }
+#_______________________________________________________________________
+func _rSQNEXT(g,p,A) { ################################################
+ if ( isarray(A) ) return _rSQNEXTA(g,p,A)
+ return _rsqnext_i0(g,p) }
+#___________________________________________________________
+func _rsqnext_i0(g,p) {
+ if ( p==_SQTOPTR[g] ) {
+ if ( _SQSTACK[g][0]>0 ) {
+ _SQTOPTR[g]=_SQSTACK[g][_SQSTACK[g][0]--]
+ return _rsqnext_i0(g,_SQSTACK[g][_SQSTACK[g][0]--]) }
+ return }
+ if ( p in _tNEXT ) return _rsqgetptr(g,_tNEXT[p])
+ return _rsqnext_i0(g,_tPARENT[p]) }
+#_________________________________________________________________
+func _rSQNEXTA(g,p,A) { #########################################
+ if ( p==_SQTOPTR[g] ) {
+ if ( _SQSTACK[g][0]>0 ) {
+ _SQTOPTR[g]=_SQSTACK[g][_SQSTACK[g][0]--]
+ return _rSQNEXTA(g,_SQSTACK[g][_SQSTACK[g][0]--],A) }
+ return }
+ while ( p in _tNEXT ) {
+ if ( (p=_rsqgetptr(g,_tNEXT[p])) in A ) return p }
+ return p in _tPARENT ? _rSQNEXTA(g,_tPARENT[p],A) : "" }
+#_________________________________________________________________
+func _rsqgetptr(g,p,A) {
+ if ( p in _tLINK ) {
+ _SQSTACK[g][++_SQSTACK[g][0]]=p
+ _SQSTACK[g][++_SQSTACK[g][0]]=_SQTOPTR[g]
+ while ( (p=_tLINK[p]) in _tLINK ) { _con(".") }
+ _SQTOPTR[g]=p }
+ if ( p in _tFCHLD ) return _rsqgetptr(g,_tFCHLD[p])
+ return p }
+#___________________________________________________________________________________
+####################################################################################
+
+
+#___________________________________________________________________________________
+# OTHER tFUNCTIONs #################################################################
+
+#_____________________________________________________________________________
+func _dumpobj(p,f,t, s) { ###################################################
+ s=_dumpobj_i0(p,f,t=t "." p "{")
+ if ( (p=_rFCHLD(p)) ) return s=s _dumpobjm(p,f,s ? _getchrln(" ",length(t)-1) : t " ")
+ return s }
+#___________________________________________________________
+func _dumpobj_i0(p,f,t) {
+ if ( f=="" ) return _dumpobj_i2(p,t)
+ if ( f==0 ) return _dumpobj_i1(p,t " ")
+ return _dumpobj_i1(p,t " ") _dumpobj_i2(p,_getchrln(" ",length(t))) }
+#___________________________________________________________
+func _dumpobj_i1(p,t) {
+ return _ln(t substr(((p in _tPREV) ? "\xAB" _tPREV[p] : "") " ",1,7) " " substr(((p in _tPARENT) ? "\x88" _tPARENT[p] : "") " ",1,7) " " substr( ((p in _tFCHLD) ? _tFCHLD[p] : "") "\x85" ((p in _tQCHLD) ? " (" _tQCHLD[p] ") " : "\x85") "\x85" ((p in _tLCHLD) ? _tLCHLD[p] : "") " ",1,22) substr(((p in _tNEXT) ? "\xBB" _tNEXT[p] : "") " ",1,8) ) }
+#___________________________________________________________
+func _dumpobj_i2(p,t) {
+ return _dumpobj_i3(_[p],t " ") _dumpobj_i3(_ptr[p],_getchrln(" ",length(t)) "`","`") }
+#___________________________________________________________
+func _dumpobj_i3(A,t,p,e, s,i,t2) {
+ if ( isarray(A) ) {
+ for ( i in A ) {
+ t2=_getchrln(" ",length(t))
+ for ( i in A ) { if ( isarray(A[i]) ) s=s _dumpobj_i3(A[i],t "[" _dumpobj_i4(i) "]",p,_ln())
+ else s=s _ln(t "[" _dumpobj_i4(i) "]=" p _dumpobj_i4(A[i]) "'")
+ t=t2 }
+ return s }
+ return e=="" ? "" : t e }
+ if ( A==0 && A=="" ) return
+ return _ln(t "=" _dumpobj_i4(p A) "'") }
+#___________________________________________________________
+func _dumpobj_i4(t) {
+ if ( length(t)>64 ) return substr(t,1,28) " ... " substr(t,length(t)-28)
+ return t }
+#_________________________________________________________________
+func _dumpobjm(p,f,t, s,t2) { ###################################
+ t2=_getchrln(" ",length(t))
+ do { s=s _dumpobj(p,f,t); t=t2 } while ( (p=_rNEXT(p)) )
+ return s }
+#_________________________________________________________________
+func _dumpobj_nc(p,f,t) { #######################################
+ return _dumpobj_i0(p,f,t "." p "{ ") }
+#_________________________________________________________________
+func _dumpobjm_nc(p,f,t, s,t2) { ################################
+ t2=_getchrln(" ",length(t))
+ do { s=s _dumpobj_nc(p,f,t); t=t2 } while ( (p=_rNEXT(p)) )
+ return s }
+#___________________________________________________________________________________
+####################################################################################
+
+
+
+
+
+
+
+func _tapi(p,f,p0,p1,p2,p3, c) {
+ c=p
+ do { if ( f in _[c]["API"] ) { f=_[c]["API"][f]; return @f(p,p0,p1,p2,p3) }
+ c=_[c]["CLASS"] } while ( "CLASS" in _[c] ) }
+
+# if ( F in _TCLASS ) { _[p]["CLASS"]=_TCLASS[F]; _tapi(p); return p }
+# # ??? _mpu(F,p) ???
+# return p }
+# _[p][F]=v; return p }
+
+#_______________________________________________________________________
+func _tgetitem(p,n, a,b) { ############################################
+ if ( p ) {
+ if ( isarray(_PTR[p]["ITEM"]) && (n in _PTR[p]["ITEM"]) ) a=_PTR[p]["ITEM"][n]
+ else a=_PTR[p]["ITEM"][n]=_N()
+ if ( !(b=_rFCHLD(a)) ) { b=_wLCHLD(a,_N()); _PTR[b]["HOST"]=p; _[b]["ITEMNAME"]=n }
+ return b } }
+#_________________________________________________________________
+func _tdelitem(p) { #############################################
+ if ( p ) {
+ if ( "HOST" in _PTR[p] && "ITEMNAME" in _[p] ) {
+ return _wLCHLD(_PTR[_PTR[p]["HOST"]]["ITEM"][_[p]["ITEMNAME"]],p) }
+ _tdelete(p); return p } }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#_____________________________________________________________________________
+func _tframe0(f,p,p0,p1,p2,p3, A) { #########################################
+ if ( _isptr(p) ) { if ( isarray(f) ) return _tframe0_i0(f,p)
+ _tframex_p0(A,f,0); return _th0(_tframe0_i0(A,p),--_TEND[_ARRLEN]) } }
+#_______________________________________________
+func _tframe0_i0(A,p, f) { if ( p in _tLINK ) {
+ _tframe_link=p
+ if ( "`" in A ) { f=A["`"]; while ( p in _tLINK ) @f(p=_tLINK[p]) }
+ else while ( p in _tLINK ) p=_tLINK[p] }
+ else _tframe_link=""
+ if ( p in _tFCHLD ) return _tframe0_i2(A,"^",p) _tframe0_i1(A,_tFCHLD[p])
+ return _tframe0_i2(A,".",p) }
+#_______________________________________________
+func _tframe0_i1(A,p) { if ( _TEND[_ARRLEN] in _TEND ) return
+ if ( p in _tNEXT ) return _tframe0_i0(A,p) _tframe0_i1(A,_tNEXT[p])
+ return _tframe0_i0(A,p) }
+#_______________________________________________
+func _tframe0_i2(A,m,p) { _tframe_dlink=p; while ( p in _tDLINK ) p=_tDLINK[p]
+ if ( m in A ) { if ( (m "~") in A ) { if ( !(_TYPEWORD in _[p]) || A[m "~"]!~_[p][_TYPEWORD] ) return }
+ m=A[m]; return @m(p) } }
+#_____________________________________________________
+func _tframex_p0(A,f,q, i,B,C) {
+ _tframe_qparam=q; delete _TEND[++_TEND[_ARRLEN]]
+
+ if ( match(f,/\~(.*)$/,B) ) { A["^~"]=A[".~"]=B[1]; f=substr(f,1,RSTART-1) }
+ A["."]=A["^"]=f; return
+ q=split(f,B,/;/); i=0
+ while ( i<q ) { _tframex_p1(A,C[i]); while ( ++i<=q ) _tframex_p1(A,C[i],B[i]) } }
+#_______________________________________________
+func _tframex_p1(A,v,i, r,B) {
+ gsub(/[ \t]+/,"",v)
+ while ( match(v,/^([^~]*)~\/(([^\/\\]*\\.)*[^\/\\]*)\//,B) ) { v=B[1] substr(v,RSTART+RLENGTH); r=B[2] }
+ if ( i=="" ) { if ( v!="" ) { A["."]=v; delete A["`"]; delete A["^"] }
+ if ( r!="" ) A[".~"]=A["`~"]=A["^~"]=r }
+ else { if ( match(v,/!/) ) delete A[i]
+ else { A[i]=v; if ( r!="" ) A[i "~"]=r } } }
+#_________________________________________________________________
+func _tframe1(f,p,p0,p1,p2,p3, A) { #############################
+ if ( _isptr(p) ) { if ( isarray(f) ) return _tframe1_i0(f,p,p0)
+ _tframex_p0(A,f,1); return _th0(_tframe1_i0(A,p,p0),--_TEND[_ARRLEN]) } }
+#_______________________________________________
+func _tframe1_i0(A,p,p0) { _tframe_link=p; while ( p in _tLINK ) p=_tLINK[p]
+ if ( p in _tFCHLD ) return _tframe1_i2(A,"^",p,p0) _tframe1_i1(A,_tFCHLD[p],p0)
+ return _tframe1_i2(A,".",p,p0) }
+#_______________________________________________
+func _tframe1_i1(A,p,p0) { if ( _TEND[_ARRLEN] in _TEND ) return
+ if ( p in _tNEXT ) return _tframe1_i0(A,p,p0) _tframe1_i1(A,_tNEXT[p],p0)
+ return _tframe1_i0(A,p,p0) }
+#_______________________________________________
+func _tframe1_i2(A,m,p,p0) { _tframe_dlink=p; while ( p in _tDLINK ) p=_tDLINK[p]
+ if ( m in A ) { if ( (m "~") in A ) { if ( !(_TYPEWORD in _[p]) || A[m "~"]!~_[p][_TYPEWORD] ) return }
+ m=A[m]; return @m(p,p0) } }
+#_________________________________________________________________
+func _tframe2(f,p,p0,p1,p2,p3, A) { #############################
+ if ( _isptr(p) ) { if ( isarray(f) ) return _tframe2_i0(f,p,p0,p1)
+ _tframex_p0(A,f,2); return _th0(_tframe2_i0(A,p,p0,p1),--_TEND[_ARRLEN]) } }
+#_______________________________________________
+func _tframe2_i0(A,p,p0,p1) { _tframe_link=p; while ( p in _tLINK ) p=_tLINK[p]
+ if ( p in _tFCHLD ) return _tframe2_i2(A,"^",p,p0,p1) _tframe2_i1(A,_tFCHLD[p],p0,p1)
+ return _tframe2_i2(A,".",p,p0,p1) }
+#_______________________________________________
+func _tframe2_i1(A,p,p0,p1) { if ( _TEND[_ARRLEN] in _TEND ) return
+ if ( p in _tNEXT ) return _tframe2_i0(A,p,p0,p1) _tframe2_i1(A,_tNEXT[p],p0,p1)
+ return _tframe2_i0(A,p,p0,p1) }
+#_______________________________________________
+func _tframe2_i2(A,m,p,p0,p1) { _tframe_dlink=p; while ( p in _tDLINK ) p=_tDLINK[p]
+ if ( m in A ) { if ( (m "~") in A ) { if ( !(_TYPEWORD in _[p]) || A[m "~"]!~_[p][_TYPEWORD] ) return }
+ m=A[m]; return @m(p,p0,p1) } }
+#_________________________________________________________________
+func _tframe3(f,p,p0,p1,p2,p3, A) { #############################
+ if ( _isptr(p) ) { if ( isarray(f) ) return _tframe3_i0(f,p,p0,p1,p2)
+ _tframex_p0(A,f,3); return _th0(_tframe3_i0(A,p,p0,p1,p2),--_TEND[_ARRLEN]) } }
+#_______________________________________________
+func _tframe3_i0(A,p,p0,p1,p2) { _tframe_link=p; while ( p in _tLINK ) p=_tLINK[p]
+ if ( p in _tFCHLD ) return _tframe3_i2(A,"^",p,p0,p1,p2) _tframe3_i1(A,_tFCHLD[p],p0,p1,p2)
+ return _tframe3_i2(A,".",p,p0,p1,p2) }
+#_______________________________________________
+func _tframe3_i1(A,p,p0,p1,p2) { if ( _TEND[_ARRLEN] in _TEND ) return
+ if ( p in _tNEXT ) return _tframe3_i0(A,p,p0,p1,p2) _tframe3_i1(A,_tNEXT[p],p0,p1,p2)
+ return _tframe3_i0(A,p,p0,p1,p2) }
+#_______________________________________________
+func _tframe3_i2(A,m,p,p0,p1,p2) { _tframe_dlink=p; while ( p in _tDLINK ) p=_tDLINK[p]
+ if ( m in A ) { if ( (m "~") in A ) { if ( !(_TYPEWORD in _[p]) || A[m "~"]!~_[p][_TYPEWORD] ) return }
+ m=A[m]; return @m(p,p0,p1,p2) } }
+#_________________________________________________________________
+func _tframe4(f,p,p0,p1,p2,p3, A) { #############################
+ if ( _isptr(p) ) { if ( isarray(f) ) return _tframe4_i0(f,p,p0,p1,p2,p3)
+ _tframex_p0(A,f,4); return _th0(_tframe4_i0(A,p,p0,p1,p2,p3),--_TEND[_ARRLEN]) } }
+#_______________________________________________
+func _tframe4_i0(A,p,p0,p1,p2,p3) { _tframe_link=p; while ( p in _tLINK ) p=_tLINK[p]
+ if ( p in _tFCHLD ) return _tframe4_i2(A,"^",p,p0,p1,p2,p3) _tframe4_i1(A,_tFCHLD[p],p0,p1,p2,p3)
+ return _tframe4_i2(A,".",p,p0,p1,p2,p3) }
+#_______________________________________________
+func _tframe4_i1(A,p,p0,p1,p2,p3) { if ( _TEND[_ARRLEN] in _TEND ) return
+ if ( p in _tNEXT ) return _tframe4_i0(A,p,p0,p1,p2,p3) _tframe4_i1(A,_tNEXT[p],p0,p1,p2,p3)
+ return _tframe4_i0(A,p,p0,p1,p2,p3) }
+#_______________________________________________
+func _tframe4_i2(A,m,p,p0,p1,p2,p3) { _tframe_dlink=p; while ( p in _tDLINK ) p=_tDLINK[p]
+ if ( m in A ) { if ( (m "~") in A ) { if ( !(_TYPEWORD in _[p]) || A[m "~"]!~_[p][_TYPEWORD] ) return }
+ m=A[m]; return @m(p,p0,p1,p2,p3) } }
+#_____________________________________________________
+# _tframe0(hndstr,ptr)
+#
+#
+# IN:
+# MOD:
+# OUT:
+# RETURN:
+#
+# handler string:
+# Handler-string divides to words. Word splitter is char ";"
+#
+# Note that handler-string processed left to right. This mean that next word(more rightly) will overwrite fields implemented before(leftmost).
+# Note that if word-string contains more than one rexp-field then only last rexp-field(most rightly) will be applied.
+#_______________________________________________
+# TO DESIGN:
+#
+# 0-4: complete design of tlink handler call
+# 1-4: add new tlink handler call
+# 1-4: add new run fn (changed rexp to different for each type: see _tframe0)
+#
+# hndstr:
+# may be add rexp for each type of handler and also total rexp for all ??? ADDED (test)
+# may be add separator char ";" ??? ADDED (test)
+#_______________________________________________________________________
+func _tzend(a,b) { #####################################################
+ if ( b==0 && b=="" ) return _TEND[_TEND[_ARRLEN]]=a
+ else return _TEND[_TEND[_ARRLEN]+a]=b }
+#_______________________________________________
+BEGIN { _TEND[_ARRLEN]=0
+ _TYPEWORD ="_TYPE" }
+#_______________________________________________________________________
+########################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#_______________________________________________________________________
+# _N(arr\str\mpuptr,val) \ _n(arr\str\mpuptr,val)
+# This functions create new object and return ptr.
+# _n() - creates object from list of deleted objects or if it's empty create new one, while _N() always create new one
+# It is strongly recommended to use _N() for the objects that have some data outside of standart object arrays. Or - make routines
+# that will clear outsided object data in case if object deleting.
+#
+# IN: arr\str\mpu,val - (both missed) just create obj and return ptr
+# arr,val - create object and write arr[ptr]=val
+# str,val - create object and write _[ptr][str]=val
+# mpuptr - NOT ALLOWED (val missed) create object and run MPU-code specified by mpuptr with created object ptr as primary parameter
+# MOD: -
+# OUT: -
+# RETURN: ptr - pointer to newly created object
+#_________________________________________________________________
+# _tdel(ptr)
+# This function exclude object from it's current structure and delete it. ptr can be later used by function: _n() for creating new object
+# Also same story will occured with all chields and subchields of object specified by ptr.
+# ??? What happened with linked py _ptr[ptr] objects ???
+#
+# IN: ptr - pointer to object that will deleted
+# MOD: -
+# OUT: -
+# RETURN: undefined
+#_________________________________________________________________
+# _isptr(ptr)
+# This function checks: is ptr is the object pointer that is currently exist?
+# Unescaped remained data will be in data of src_dst_ptr.
+#
+# IN: ptr - string that will be tested
+# MOD: -
+# OUT: -
+# RETURN: undefined - if ptr is not pointer to exist object
+# ptr - if ptr is the pointer to exist object
+#_________________________________________________________________
+
+
+
+#_________________________________________________________________
+#
+# TO DESIGN:
+#
+# create basic objectapi interface support
+# modify everywhere checking ptr not by `if ( ptr )...', but by `if ( ptr in _ )...'
+# _TMP0, _TMP1 name change to something like _DATA name ???
+# think about redesigning routines for not depending if ptr is exist in tsysarrs: reason: performance\light code
+
+
+
+
+
+
+
+
+
+
+
+func _tlist(L,p,f) {
+ _tlisti1=_tlisti0=L[_ARRLEN]+0
+ if ( f==0 && f=="" ) _tlist_i0(L,p)
+ else { _tlistf0=f in _TAPI ? _TAPI[f] : f; _tlist_i1(L,p) }
+ return _tlisti0-_tlisti1 }
+
+func _tlist_i0(L,p, q,i) { if ( isarray(p) ) { q=p[_ARRLEN]; i=0; while ( i++<q ) _tlist_i0(L,p[i]); return }
+ if ( p in _ ) { while ( p in _tLINK ) p=_tLINK[p]
+ L[++_tlisti0]=p
+ if ( p in _tFCHLD ) for ( p=_tFCHLD[p]; p; p=p in _tNEXT ? _tNEXT[p] : "" ) _tlist_i0(L,p) } }
+
+func _tlist_i1(L,p) { if ( isarray(p) ) { q=p[_ARRLEN]; i=0; while ( i++<q ) _tlist_i1(L,p[i]); return }
+ if ( p in _ ) { while ( p in _tLINK ) p=_tLINK[p]
+ if ( _tlistf0 in _[p] ) L[++_tlisti0]=p
+ if ( p in _tFCHLD ) for ( p=_tFCHLD[p]; p; p=p in _tNEXT ? _tNEXT[p] : "" ) _tlist_i1(L,p) } }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+##########################################################################################
+# PUBLIC:
+#_____________________________________________________________________________
+# _rFBRO(ptr) - Return ptr of first-bro. [TESTED]
+# If !ptr then returns "".
+#_____________________________________________________________________________
+# _rLBRO(ptr) - Return ptr of last-bro. [TESTED]
+# If !ptr then returns "".
+#_____________________________________________________________________________
+# _rQBRO(ptr) - Returns brothers total quantity. [TESTED]
+# If !ptr then returns "".
+END{ ###############################################################################
+
+ if ( _gawk_scriptlevel<1 ) {
+ if ( !_fileio_notdeltmpflag ) {
+ _FILEIO_TMPATHS[_FILEIO_TMPRD]
+ _Foreach(_FILEIO_TMPATHS,"_uninit_del") } } }
+#_____________________________________________________________________________
+func _uninit_del(A,i,p0) {
+ _del(i) }
+#___________________________________________________________________________________
+####################################################################################
+
+#___________________________________________________________________________________
+func _out(t, a,b) { ###############################################################
+ a=BINMODE; b=ORS; BINMODE="rw"; ORS=""
+ print t > _SYS_STDOUT; fflush(_SYS_STDOUT)
+ BINMODE=a; ORS=b
+ return t }
+#_________________________________________________________________
+func _outnl(t) { ################################################
+ return _out(t (t~/\x0A$/ ? "" : _CHR["EOL"])) }
+#_______________________________________________________________________
+func _err(t, a,b) { ###################################################
+ a=BINMODE; b=ORS; BINMODE="rw"; ORS=""
+ print t > _SYS_STDERR; fflush(_SYS_STDERR)
+ BINMODE=a; ORS=b
+ return t }
+#_________________________________________________________________
+func _errnl(t) { ################################################
+ return _err(t (t~/\x0A$/ ? "" : _CHR["EOL"])) }
+#_____________________________________________________________________________
+func _getfilepath(t, f,al,b,A) { ############################################
+ ERRNO=""
+ if ( match(t,/^[ \t]*(("([^"]*)"[ \t]*)|([`']([^']*)'[ \t]*)|(([^ \t]+)[ \t]*))/,A) ) {
+ al=RLENGTH; f=A[3] A[5] A[7]; _conl("_getfilepath(" f ") (" al ")")
+ if ( (b=_filepath(f)) ) { if ( length(f)<=FLENGTH ) { FLENGTH=al; return b }
+ ERRNO="Filepath `" f "' error" } }
+ FLENGTH=0 }
+#_______________________________________________________________________
+func _filepath(f,dd) { ################################################
+ if ( (f=_filerdnehnd(f))=="" ) return ""
+ return filegetrootdir(f,dd) (f in _FILENAM ? _FILENAM[f] : "") (f in _FILEXT ? _FILEXT[f] : "") }
+#_________________________________________________________________
+func _filerdne(f,dd) { ##########################################
+ if ( (f=_filerdnehnd(f))=="" ) return ""
+ if ( (f in _FILENAM) ) return filegetrootdir(f,dd) _FILENAM[f] (f in _FILEXT ? _FILEXT[f] : "")
+ if ( f in _FILEXT ) return filegetrootdir(f,dd) _FILEXT[f]
+ return "" }
+#_________________________________________________________________
+func _filerdn(f,dd) { ###########################################
+ if ( (f=_filerdnehnd(f))=="" ) return ""
+ return f in _FILENAM ? (filegetrootdir(f,dd) _FILENAM[f]) : "" }
+#_________________________________________________________________
+func _filerd(f,dd) { ############################################
+ if ( (f=_filerdnehnd(f))=="" ) return ""
+ return filegetrootdir(f,dd) }
+#_________________________________________________________________
+func _filer(f,dd) { #############################################
+ if ( (f=_filerdnehnd(f))=="" ) return ""
+ if ( f in _FILEROOT ) return _FILEROOT[f]
+ if ( ((dd=dd ? dd : _FILEIO_RD),f) in _FILEROOT ) return _FILEROOT[dd,f]
+ return _FILEROOT[dd,f]=fileri(dd) }
+#_________________________________________________________________
+func _filed(f,dd, d) { ##########################################
+ if ( (f=_filerdnehnd(f))=="" ) return ""
+ if ( f in _FILEDIRFL ) return _FILEDIR[f]
+ if ( f in _FILEROOT ) {
+ if ( (d=filegetdrvdir(_FILEROOT[f])) ) _FILEDIRFL[f]
+ return _FILEDIR[f]=d _FILEDIR[f] }
+ if ( ((dd=dd ? dd : _FILEIO_RD),f) in _FILEDIR ) return _FILEDIR[dd,f]
+ if ( (d=filedi(dd) _FILEDIR[f])~/^\\/ ) return _FILEDIR[dd,f]=d
+ return d }
+#___________________________________________________________
+func filegetrootdir(f,dd, d) {
+ if ( f in _FILEDIRFL ) {
+ if ( f in _FILEROOT ) return _FILEROOT[f] _FILEDIR[f]
+ if ( ((dd=dd ? dd : _FILEIO_RD),f) in _FILEROOT ) return _FILEROOT[dd,f] _FILEDIR[f]
+ return (_FILEROOT[dd,f]=fileri(dd)) _FILEDIR[f] }
+ if ( f in _FILEROOT ) {
+ if ( (d=filegetdrvdir(_FILEROOT[f])) ) {
+ _FILEDIRFL[f]; return _FILEROOT[f] (_FILEDIR[f]=d _FILEDIR[f]) }
+ else return _FILEROOT[f] _FILEDIR[f] }
+ if ( ((dd=dd ? dd : _FILEIO_RD),f) in _FILEROOT ) {
+ if ( (dd,f) in _FILEDIR ) return _FILEROOT[dd,f] _FILEDIR[dd,f]
+ if ( (d=filedi(dd) _FILEDIR[f])~/^\\/ ) return _FILEROOT[dd,f] (_FILEDIR[dd,f]=d)
+ return _FILEROOT[dd,f] d }
+ if ( (dd,f) in _FILEDIR ) return (_FILEROOT[dd,f]=fileri(dd)) _FILEDIR[dd,f]
+ if ( (d=filedi(dd) _FILEDIR[f])~/^\\/ ) return (_FILEROOT[dd,f]=fileri(dd)) (_FILEDIR[dd,f]=d)
+ return (_FILEROOT[dd,f]=fileri(dd)) d }
+#___________________________________________________________
+func _filerdnehnd(st, c,r,d,n,A) {
+ if ( st ) {
+ if ( (c=toupper(st)) in _FILECACHE ) {
+ FLENGTH=length(st); return _FILECACHE[c] }
+ if ( match(st,/^[ \t]*\\[ \t]*\\/) ) {
+ if ( match(substr(st,(FLENGTH=RLENGTH)+1),/^[ \t]*([0-9A-Za-z\-]+)[ \t]*(\\[ \t]*([A-Za-z])[ \t]*\$[ \t]*)?(\\[ \t]*([0-9A-Za-z_\!\+\-\[\]\(\)\{\}\~\.]+( +[0-9A-Za-z_\!\+\-\[\]\(\)\{\}\~\.]+)*[ \t]*\\)+[ \t]*)?(([0-9A-Za-z_\!\+\.\~\-\[\]\{\}\(\)]+( +[0-9A-Za-z_\!\+\.\~\-\[\]\{\}\(\)]+)*)[ \t]*)?/,A) ) {
+ FLENGTH=FLENGTH+RLENGTH
+ d=(A[3] ? ("\\" A[3] "$") : "") A[4]; gsub(/[ \t]*\\[ \t]*/,"\\",d)
+ if ( (st=toupper((r="\\\\" A[1]) d (n=A[8]))) in _FILECACHE ) return _FILECACHE[substr(c,1,FLENGTH)]=_FILECACHE[st]
+ _FILEDIR[c=_FILECACHE[substr(c,1,FLENGTH)]=_FILECACHE[st]=++_file_rootcntr]=d; _FILEDIRFL[c]
+ _FILEROOT[c]=r }
+ else {
+ FLENGTH=0; _filepath_err="UNC"; return "" } }
+ else {
+ match(st,/^(([ \t]*\.[ \t]*\\[ \t]*)|(([ \t]*([A-Za-z])[ \t]*(\:)[ \t]*)?([ \t]*(\\)[ \t]*)?))([ \t]*(([ \t]*[0-9A-Za-z_\!\+\-\[\]\(\)\{\}\~\.]+( +[0-9A-Za-z_\!\+\-\[\]\(\)\{\}\~\.]+)*[ \t]*\\)+)[ \t]*)?([ \t]*([0-9A-Za-z_\!\+\.\~\-\[\]\{\}\(\)]+( +[0-9A-Za-z_\!\+\.\~\-\[\]\{\}\(\)]+)*)[ \t]*)?/,A)
+ if ( !(FLENGTH=RLENGTH) ) return ""
+ d=A[8] A[10]; gsub(/[ \t]*\\[ \t]*/,"\\",d)
+ if ( (st=toupper((r=A[5] A[6]) d (n=A[14]))) in _FILECACHE ) return _FILECACHE[substr(c,1,FLENGTH)]=_FILECACHE[st]
+ _FILEDIR[c=_FILECACHE[substr(c,1,FLENGTH)]=_FILECACHE[st]=++_file_rootcntr]=d
+ if ( A[8] ) _FILEDIRFL[c]
+ if ( r ) _FILEROOT[c]=r }
+ if ( n ) {
+ if ( match(n,/\.[^\.]*$/) ) {
+ _FILEXT[c]=substr(n,RSTART); _FILENAM[c]=substr(n,1,RSTART-1) }
+ else _FILENAM[c]=n }
+ return c }
+ return "" }
+#___________________________________________________________
+func filedi(f, d) {
+ if ( (f=filerdnehndi(f))=="" ) return _FILEIO_D
+ if ( f in _FILEDIRFL ) return _FILEDIR[f]
+ if ( f in _FILEROOT ) {
+ if ( (d=filegetdrvdir(_FILEROOT[f])) ) _FILEDIRFL[f]
+ return _FILEDIR[f]=d _FILEDIR[f] }
+ if ( (_FILEIO_RD,f) in _FILEDIR ) return _FILEDIR[_FILEIO_RD,f]
+ return _FILEDIR[_FILEIO_RD,f]=_FILEIO_D _FILEDIR[f] }
+#_____________________________________________________
+func fileri(f) {
+ if ( (f=filerdnehndi(f))=="" ) return _FILEIO_R
+ if ( f in _FILEROOT ) return _FILEROOT[f]
+ if ( (_FILEIO_RD,f) in _FILEROOT ) return _FILEROOT[_FILEIO_RD,f]
+ return _FILEROOT[_FILEIO_RD,f]=_FILEIO_R }
+#___________________________________________________________
+func filerdnehndi(st, a,c,r,d,n,A) {
+ if ( st ) {
+ if ( (c=toupper(st)) in _FILECACHE ) return _FILECACHE[c]
+ if ( match(st,/^[ \t]*\\[ \t]*\\/) ) {
+ if ( match(substr(st,a=RLENGTH+1),/^[ \t]*([0-9A-Za-z\-]+)[ \t]*(\\[ \t]*([A-Za-z])[ \t]*\$[ \t]*)?(\\[ \t]*([0-9A-Za-z_\!\+\-\[\]\(\)\{\}\~\.]+( +[0-9A-Za-z_\!\+\-\[\]\(\)\{\}\~\.]+)*[ \t]*\\)*[ \t]*)?(([0-9A-Za-z_\!\+\.\~\-\[\]\{\}\(\)]+( +[0-9A-Za-z_\!\+\.\~\-\[\]\{\}\(\)]+)*)[ \t]*)?/,A) ) {
+ a=a+RLENGTH
+ d=(A[3] ? ("\\" A[3] "$") : "") "\\" A[5]; gsub(/[ \t]*\\[ \t]*/,"\\",d)
+ if ( (st=toupper((r="\\\\" A[1]) d (n=A[8]))) in _FILECACHE ) return _FILECACHE[substr(c,1,a)]=_FILECACHE[st]
+ _FILEDIR[c=_FILECACHE[substr(c,1,a)]=_FILECACHE[st]=++_file_rootcntr]=d; _FILEDIRFL[c]
+ _FILEROOT[c]=r }
+ else {
+ _filepath_err="UNC"; return "" } }
+ else {
+ match(st,/^(([ \t]*\.[ \t]*\\[ \t]*)|(([ \t]*([A-Za-z])[ \t]*(\:)[ \t]*)?([ \t]*(\\)[ \t]*)?))([ \t]*(([ \t]*[0-9A-Za-z_\!\+\-\[\]\(\)\{\}\~\.]+( +[0-9A-Za-z_\!\+\-\[\]\(\)\{\}\~\.]+)*[ \t]*\\)+)[ \t]*)?([ \t]*([0-9A-Za-z_\!\+\.\~\-\[\]\{\}\(\)]+( +[0-9A-Za-z_\!\+\.\~\-\[\]\{\}\(\)]+)*)[ \t]*)?/,A)
+ if ( !RLENGTH ) return ""
+ d=A[8] A[10]; gsub(/[ \t]*\\[ \t]*/,"\\",d)
+ if ( (st=toupper((r=A[5] A[6]) d (n=A[14]))) in _FILECACHE ) return _FILECACHE[substr(c,1,RLENGTH)]=_FILECACHE[st]
+ _FILEDIR[c=_FILECACHE[substr(c,1,RLENGTH)]=_FILECACHE[st]=++_file_rootcntr]=d
+ if ( A[8] ) _FILEDIRFL[c]
+ if ( r ) _FILEROOT[c]=r }
+ if ( n ) {
+ if ( match(n,/\.[^\.]*$/) ) {
+ _FILEXT[c]=substr(n,RSTART); _FILENAM[c]=substr(n,1,RSTART-1) }
+ else _FILENAM[c]=n }
+ return c }
+ return "" }
+#___________________________________________________________
+func filegetdrvdir(t, r) {
+ if ( t in _FILEDRV ) return _FILEDRV[t]
+ if ( match(r=_cmd("cd " t " 2>NUL"),/[^\x00-\x1F]+/) ) {
+ r=gensub(/[ \t]*([\\\$\:])[ \t]*/,"\\1","G",substr(r,RSTART,RLENGTH)); gsub(/(^[ \t]*)|([ \t]*$)/,"",r)
+ if ( match (r,/\:(.*)/) ) {
+ return _FILEDRV[tolower(t)]=_FILEDRV[toupper(t)]=substr(r,RSTART+1) (r~/\\$/ ? "" : "\\") } }
+ return "" }
+#_________________________________________________________________
+func _filene(f) { ###############################################
+ if ( (f=_filerdnehnd(f))=="" ) return ""
+ return (f in _FILENAM ? _FILENAM[f] : "") (f in _FILEXT ? _FILEXT[f] : "") }
+#_________________________________________________________________
+func _filen(f) { ################################################
+ if ( (f=_filerdnehnd(f))=="" ) return ""
+ return f in _FILENAM ? _FILENAM[f] : "" }
+#_________________________________________________________________
+func _file(f) { #################################################
+ if ( (f=_filerdnehnd(f))=="" ) return ""
+ return f in _FILEXT ? _FILEXT[f] : "" }
+
+
+
+#_______________________________________________________________________
+func _rdfile(f, i,A) { ################################################
+ if ( ((f=_filerdne(f))=="") || (_filene(f)=="") ) { ERRNO="Filename error"; return }
+ _fio_cmda=RS; RS=".{1,}"; _fio_cmdb=BINMODE; BINMODE="rw"; ERRNO=RT=_NUL
+ getline RS < f; BINMODE=_fio_cmdb; RS=_fio_cmda
+ if ( ERRNO=="" ) close(f)
+ if ( ERRNO=="" ) return RT
+ return RT=_NOP }
+#_________________________________________________________________
+func _wrfile(f,d, a,b) { #########################################
+ if ( ((f=_wfilerdnehnd(f))=="") || (_filene(f)=="") ) {
+ ERRNO="Filename error"; return }
+ a=BINMODE; BINMODE="rw"; b=ORS; ORS=""; ERRNO=""
+ print d > f
+ if ( ERRNO ) return ""
+ close(f)
+ BINMODE=a; ORS=b
+ if ( ERRNO ) return ""
+ return f }
+#___________________________________________________________
+func _wrfile1(f,d, a,b) { ##################################
+ if ( ((f=_wfilerdnehnd(f))=="") || (_filene(f)=="") ) {
+ ERRNO="Filename error"; return }
+ a=BINMODE; BINMODE="rw"; b=ORS; ORS=""; ERRNO=""
+ print d > f
+ if ( ERRNO ) return ""
+ close(f)
+ BINMODE=a; ORS=b
+ if ( ERRNO ) return ""
+ return d }
+#___________________________________________________________
+func _addfile(f,d, a,b) { ##################################
+ if ( ((f=_wfilerdnehnd(f))=="") || (_filene(f)=="") ) {
+ ERRNO="Filename error"; return }
+ a=BINMODE; BINMODE="rw"; b=ORS; ORS=""; ERRNO=""
+ print d >> f
+ if ( ERRNO ) return ""
+ close(f)
+ BINMODE=a; ORS=b
+ if ( ERRNO ) return ""
+ return d }
+#___________________________________________________________
+func _wfilerdnehnd(f, t) {
+ if ( (f=_filerdne(f))=="" ) return ""
+ if ( !((t=_filerd(f)) in _WFILEROOTDIR) ) {
+ _cmd("md \"" t "\" 2>NUL"); _WFILEROOTDIR[t] }
+ return f }
+#_______________________________________________________________________
+func _dir(A,rd, i,r,f,ds,pf,B,C) { ####################################
+ delete A
+ gsub(/(^[ \t]*)|([ \t]*$)/,"",rd); if ( rd=="" ) return ""
+ i=split(_cmd("dir \"" rd "\" 2>NUL"),B,/\x0D?\x0A/)-3
+ pf=(match(B[4],/Directory of ([^\x00-\x1F]+)/,C) ? (C[1] (C[1]~/\\$/ ? "" :"\\")) : "")
+ for ( r=0; i>5; i-- ) {
+ if ( match(B[i],/^([^ \t]*)[ \t]+([^ \t]*)[ \t]+((<DIR>)|([0-9\,]+))[ \t]+([^\x00-\x1F]+)$/,C) ) {
+ if ( C[6]!~/^\.\.?$/ ) {
+ if ( C[4] ) ds="D "
+ else {
+ ds=C[5] " "; gsub(/\,/,"",ds) }
+ if ( (f=_filepath(pf C[6] (C[4] ? "\\" : "")))!="" ) {
+ A[f]=ds C[1] " " C[2]; r++ } } } }
+ return r }
+#_________________________________________________________________
+func _dirtree(A,f, B) { #########################################
+ gsub(/(^[ \t]*)|([ \t]*$)/,"",f)
+ delete A; A[""]; delete A[""]
+ _dirtree_i0(B,8,split(_cmd("dir \"" f "\" /-C /S 2>NUL"),B,/\x0D?\x0A/),A,f=_filerd(f))
+ return f }
+#___________________________________________________________
+func _dirtree_i0(B,i,c,A,f, lf,a,C) {
+ delete A[f]; A[f][0]; delete A[f][0]
+ lf=length(f)
+ for ( ; i<=c; ) {
+ if ( match(B[i],/^[ \t]*Directory of (.+)/,C) ) {
+ if ( substr(a=_filerd(C[1] "\\"),1,lf)==f ) {
+ i=_dirtree_i0(B,i+4,c,A[f],a) }
+ else return i }
+ else if ( match(B[i++],/^([^ \t\-]+)\-([^ \t\-]+)\-([^ \t]+)[ \t]+([^ \t]+)[ \t]+([0-9]+)[ \t]+(.+)$/,C) ) {
+ A[f][f C[6]]=C[5] " " C[1] "/" _CHR["MONTH"][C[2]] "/" C[3] " " C[4] } }
+ return i }
+#_______________________________________________________________________
+func _filexist(f, a) { ################################################
+ if ( f=="" ) return ""
+ if ( (a=_filepath(f))=="" ) {
+ ERRNO="Filepath error `" f "'"; return "" }
+ _cmd("if exist \"" a "\" exit 1 2>NUL")
+ if ( _exitcode==1 ) return a
+ ERRNO="File not found `" f "'"
+ return _NOP }
+#_________________________________________________________________
+func _filenotexist(f, a) { ######################################
+ if ( f=="" ) return ""
+ if ( (a=_filepath(f))=="" ) {
+ ERRNO="Filepath error `" f "'"; return "" }
+ _cmd("if exist \"" a "\" exit 1 2>NUL")
+ if ( _exitcode==1 ) return ERRNO=_NOP
+ return a }
+#_______________________________________________________________________
+func _newdir(f) { #####################################################
+ if ( (f=_filerd(f))=="" ) return
+ if ( !(f in _WFILEROOTDIR) ) {
+ _cmd("md " f " 2>NUL"); _WFILEROOTDIR[f] }
+ return f }
+#_________________________________________________________________
+func _newclrdir(f) { ############################################
+ if ( (f=_filerd(f))=="" ) return
+ _cmd("rd " f " /S /Q 2>NUL"); _cmd("md " f " 2>NUL")
+ _WFILEROOTDIR[f]
+ return f }
+#_______________________________________________________________________
+func _del(f, c,a,A) { #################################################
+ if ( match(f,/\\[ \t]*$/) ) {
+ if ( (c=toupper(_filerd(f))) && (length(f)==FLENGTH) ) {
+ _cmd("rd " c " /S /Q 2>NUL")
+ _deletepfx(_WFILEROOTDIR,c); _deletepfx(_FILEIO_RDTMP,c); _deletepfx(_FILEIO_RDNETMP,c) }
+ else {
+ _conl("HUJ TEBE!")
+ return "" } }
+ else {
+ a=_dir(A,f); _cmd("del " f " /Q 2>NUL")
+ for ( c in A ) {
+ if ( c~/\\$/ ) {
+ _cmd("rd " c " /S /Q 2>NUL")
+ _deletepfx(_WFILEROOTDIR,c); _deletepfx(_FILEIO_RDTMP,c) }
+ _deletepfx(_FILEIO_RDNETMP,c) } }
+ return a }
+#_______________________________________________________________________
+func _setmpath(p, a) { ################################################
+ ERRNO=""
+ if ( (p) && (a=_filerd(p)) ) {
+ if ( _FILEIO_TMPRD ) _FILEIO_TMPATHS[_FILEIO_TMPRD]
+ #if ( _filexist(a) ) _del(a)
+ #_cmd("rd " a " /S /Q 2>NUL"); _cmd("del " a " /Q 2>NUL")
+ return _FILEIO_TMPRD=a }
+ else return _warning("`" p "': cannot set temporary folder" (ERRNO ? (": " ERRNO) : "")) }
+#_________________________________________________________________
+func _getmpfile(f,dd) { #########################################
+ if ( (!dd) || (!(dd=_filerd(dd))) ) dd=_FILEIO_TMPRD
+ if ( (f=_filerdne(_filene(f) ? f : (f "_" ++_FILEIO_TMPCNTR),dd)) ) _FILEIO_RDNETMP[toupper(f)]
+ return f }
+#_________________________________________________________________
+func _getmpdir(f,dd) { ##########################################
+ if ( (!dd) || (!(dd=_filerd(dd))) ) dd=_FILEIO_TMPRD
+ if ( (f=f ? _filerd(f,dd) : _filerd("_" ++_FILEIO_TMPCNTR "\\",dd)) ) _FILEIO_RDTMP[toupper(f)]
+ return f }
+#_________________________________________________________________
+func _untmp(f, a) { #############################################
+ if ( (f=filepath(f)) ) {
+ if ( match(f,/\\$/) ) {
+ _deletepfx(_FILEIO_RDTMP,a=toupper(f)); _deletepfx(_FILEIO_RDNETMP,a) }
+ else {
+ delete _FILEIO_RDNETMP[toupper(f)] }
+ return f }
+ return "" }
+#___________________________________________________________________________________
+####################################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#___________________________________________________________________________________
+# fn _dirtree(array,pathmask)
+#
+# Return in `array' file tree from pathmask:
+# array["file.filerdne"]="size date time"
+# array["subdir.filerd"]["file.filerdne"]="size date time"
+# array["subdir.filerd"]["file.filerd"][...]
+#
+# The array will be cleared before any action. Function return pathmask w/o ltabspc and rtabspc.
+#___________________________________________________________________________________
+
+
+
+
+
+# OK: change internal function's names to: w\o "_"
+# OK: FLENGTH: should cover r-spcs
+# OK: optimize REXP
+# OK: add new symbols to dir/file names ( ! and + )
+# OK: create _getfilepath()
+# OK: del - conflict with WROOTDIR (do not update it)
+# OK: dir/del - support for filemask ( * and ? )
+# OK: how to define code injections: header\ender; and HANDLERS
+# OK: units in header\ender? conline division...
+# OK: _FILEPATH problem: it will not been defined at the moment when subscript0 starts - at the start TMPRD="_tmp"
+# OK: del: if del("dir\\") - then all ok except it NOT deleted "dir\\" - _del function removed(renamed to __del)
+# OK: tmpdirs: it delete only autotmp dir and only from script0
+# OK: MICROTEST: global testing of filepath (UNC! CORRECT RESULTS! )
+# question about cache: did new just now generated absolute filepath cached in FILECACHE? its seems like NO
+# check _untmp: CONFLICT: if file or dir from autotmp dir will be untmp then it anyway will be deleted; but file or dir from other point never be deleted anyway - so what is the point of untmp?????
+#ERRLOG: _setmpath: warning!!!!!
+
+#___________________________________________________________________________________
+####################################################################################
+# PUBLIC:
+#___________________________________________________________________________________
+#
+# fn _rdfile(_filepath)
+#
+# Read and return data from file specified in _filepath.
+# If _filepath=="" then no action occured and return "".
+# Function read and return data from file. No any changes in data occured.
+# Function use _filerdne function internally. If some syntax error
+# found in _filepath then function return "".
+# If some error occured while reading data from file then fuction return ""
+# and error-text is in ERRNO(and no close-file action will be occured!).
+# If reading data completed successfully then function try to close
+# file and if while closing file some error occured then function
+# returns "" and error-text is in ERRNO.
+# Otherwise function returns readed data.
+#_____________________________________________________________________________
+#
+# fn _wrfile(_filepath,_data)
+#
+# Write data into file specified in _filepath.
+# If _filepath=="" then no action occured and return "".
+# Function write _data to file. No any changes in data occured.
+# Function use _filerdne function internally. If some syntax error
+# found in _filepath then function return "".
+# If some error occured while writing data to file then fuction return ""
+# and error-text is in ERRNO(and no close-file action will be occured!).
+# If writing data completed successfully then function try to close
+# file and if while closing file some error occured then function
+# returns "" and error-text is in ERRNO.
+# Otherwise function returns _filepath(re-processed).
+#___________________________________________________________________________________
+#
+# fn _filepath(_filepath)
+#
+# Return re-processed root-dir-name-ext of _filepath.
+# If _filepath=="" then no action occured and return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+#_____________________________________________________________________________
+#
+# fn _filerdne(_filepath)
+#
+# Return re-processed root-dir-filename of _filepath.
+# If _filepath=="" then no action occured and return "".
+# Function return result only if in _filepath present file-name(name
+# and/or extension) - otherwise its return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+#_____________________________________________________________________________
+#
+# fn _filerdn(_filepath)
+#
+# Return re-processed root-dir-name of _filepath.
+# If _filepath=="" then no action occured and return "".
+# Function return result only if in _filepath present name field -
+# - otherwise its return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+#_____________________________________________________________________________
+#
+# fn _filerd(_filepath)
+#
+# Return re-processed root-dir of _filepath.
+# If _filepath=="" then no action occured and return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+#_____________________________________________________________________________
+#
+# fn _filer(_filepath)
+#
+# Return re-processed root of _filepath.
+# If _filepath=="" then no action occured and return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+#_____________________________________________________________________________
+#
+# fn _filed(_filepath)
+#
+# Return re-processed dir of _filepath.
+# If _filepath=="" then no action occured and return "".
+# There is only one case when dir string can be =="" - when in
+# _filepath specified unmounted drive(MS-format) and from-
+# current-location address used(like Z:file.ext). In this
+# case no rootdir-cache-record will be created.
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+#_____________________________________________________________________________
+# fn _filene(_filepath)
+#
+# Return re-processed name-ext of _filepath.
+# If _filepath=="" then no action occured and return "".
+# Function return result only if in _filepath present file-name(name
+# and/or extension) - otherwise its return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+#_____________________________________________________________________________
+#
+# fn _filen(_filepath)
+#
+# Return re-processed name of _filepath.
+# If _filepath=="" then no action occured and return "".
+# Function return result only if in _filepath present name field -
+# - otherwise its return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+#_____________________________________________________________________________
+#
+# fn _file(_filepath)
+#
+# Return re-processed ext of _filepath.
+# If _filepath=="" then no action occured and return "".
+# Function return result only if in _filepath present ext field -
+# - otherwise its return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+#___________________________________________________________________________________
+#
+# fn _dir(_ARR,_filepathmask)
+#
+# Get file-/folder-list of root-folder of _filepathmask.
+# If _filepathmask=="" then no action occured and return "".
+# _filepathmask can contain symbols like `*' and `?' as like
+# its used in `dir'-shell command.
+# Function gets file-/folder-list of specified root-dir-_filepathmask
+# and return this list in array _ARR - where each element:
+#
+# index - is the _filepath of file-or-folder name-ext
+# value - contains 3 fields separated by " ":
+# 1. =="D" if this is folder
+# ==/[0-9]+/ if this is file - size of file in bytes
+# 2. ==date-of-creation of file or folder
+# 3. ==time-of-creation of file or folder
+#
+# Function returns quantity of items in ARR.
+#___________________________________________________________________________________
+#
+# fn _filexist(_filepath)
+#
+# Test if file or path or drive specified in _filepath is exist.
+# If _filepath=="" then no action occured and return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+# Function returns _filepath if _filepath is exist. Otherwise
+# function return 0.
+#_____________________________________________________________________________
+#
+# fn _filenotexist(_filepath)
+#
+# Test if file or path or drive specified in _filepath is not exist.
+# If _filepath=="" then no action occured and return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+# Function returns 1 if _filepath is not exist. Otherwise function
+# return 0.
+#_____________________________________________________________________________
+#
+# fn _newdir(_filepath)
+#
+# Create path specified in root-dir-_filepath.
+# If _filepath=="" then no action occured and return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+# Function returns root-dir of _filepath.
+#_______________________________________________________________________
+#
+# fn _newdir(_filepath)
+#
+# Create path specified in root-dir-_filepath. If this folder
+# already exist then it will be completely cleared.
+# If _filepath=="" then no action occured and return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+# Function returns root-dir of _filepath.
+#___________________________________________________________________________________
+#
+# fn _getmpfile(_filepath,_currfilepath)
+#
+# Return ....
+#
+#_____________________________________________________________________________
+#
+# fn _getmpdir(_filepath,_currfilepath)
+#
+# Return ...
+#
+#_____________________________________________________________________________
+#
+# Temporary files folder.
+#
+# Temporary files folder location is defined by _FILEIO_TMPRD.
+# If it wasn't been initialized before program run or not been initialized
+# by ENVIRON["TMPDIR"] then it will defined as the:
+# `current rootdir(stored in _FILEIO_RD)\programname.TMP'
+# In this case if its already exist then it will completely cleared when _FILEIO
+# library initialization processed.
+# And at the program uninitialization processed it will completely
+# cleared if _FILEIO_TMPCLRFLAG is true.
+#___________________________________________________________________________________
+#
+# var _FILEIO_RD (ENVIRON["CD"])
+#
+# This var can be set before running program. It can contain path which
+# will be used as default current dir while program run.
+# If this var is set before program runs - then it will be refreshed by the
+# _filerd it will be used as default current dir while program run.
+# If this var is not set before program runs - then ENVIRON["CD"] can also
+# set up default current dir while program run. If it set before program
+# begin then it will be refreshed by the _filerd - and also writed into
+# _FILEIO_RD.
+# If both _FILEIO_RD and ENVIRON["CD"] are not set before program begins
+# then real current root\dir will be writed into both _FILEIO_RD and
+# ENVIRON["CD"] and it will be used as default current dir while program run.
+#
+#___________________________________________________________________________________
+#
+# var _FILEIO_TMPRD (ENVIRON["TMPRD"])
+#
+# This var can be set before running program. It can contain path which
+# will be used as default temporary files root-folder while program run.
+# If this var is set before program runs - then it will be refreshed by the
+# _filerd - and also writed into ENVIRON["TMPRD"].
+# If this var is not set before program runs - then ENVIRON["TMPRD"] can also
+# set up default temporary files root-folder while program run. If it set
+# before program begin then it will be refreshed by the _filerd - and
+# also writed into _FILEIO_TMPRD.
+# If both _FILEIO_TMPRD and ENVIRON["TMPRD"] are not set before program begins
+# then new folder into path specified by the _FILEIO_RD(after its handling)
+# will be writed into both _FILEIO_TMPRD and ENVIRON["TMPRD"] and it
+# will be used as default temporary files root-folder while program run.
+#___________________________________________________________________________________
+#
+# var _FILEPATH
+#
+# This var contain filepath of working script. It should be setting up externally.
+#
+# var _gawk_scriptlevel
+#___________________________________________________________________________________
+####################################################################################
+END{ ###############################################################################
+ if ( _constatstrln>0 ) _constat() }
+
+#_____________________________________________________________________________
+func _cmd(c, i,A) { #######################################################
+ _fio_cmda=RS; RS=".{1,}"; _fio_cmdb=BINMODE; BINMODE="rw"; ERRNO=RT=_NUL
+ c | getline RS; BINMODE=_fio_cmdb; RS=_fio_cmda
+ if ( ERRNO || 0>_exitcode=close(c) ) return RT=_NOP
+ return RT }
+
+
+#_____________________________________________________________________________
+func _con(t,ts, a,b,c,d,i,r,A,B) { ##########################################
+ d=RLENGTH
+ if ( (c=split(r=t,A,/\x0D?\x0A/,B))>0 ) {
+ a=BINMODE; b=ORS; BINMODE="rw"; ORS=""
+ if ( c>1 ) {
+ if ( (i=length(t=_tabtospc(A[1],ts,_conlastrln)))<_constatstrln ) {
+ t=t _getchrln(" ",_constatstrln-i) }
+ print (t B[1]) > _SYS_STDCON
+ for ( i=2; i<c; i++ ) {
+ print (_tabtospc(A[i],ts) B[i]) > _SYS_STDCON }
+ print (_conlastr=_tabtospc(A[c],ts)) > _SYS_STDCON; fflush(_SYS_STDCON) }
+ else {
+ print (t=_tabtospc(t,ts,_conlastrln)) > _SYS_STDCON; fflush(_SYS_STDCON)
+ _conlastr=_conlastr t }
+ if ( (i=length(_conlastr))>=_CON_WIDTH ) {
+ _conlastr=substr(_conlastr,1+(int(i/_CON_WIDTH)*_CON_WIDTH)) }
+ _conlastrln=length(_conlastr)
+ if ( _constatstr ) {
+ print ((t=_constatgtstr(_constatstr,_CON_WIDTH-1-_conlastrln)) _CHR["CR"] _conlastr) > _SYS_STDCON; fflush(_SYS_STDCON)
+ _constatstrln=length(t) }
+ BINMODE=a; ORS=b; RLENGTH=d; return r }
+ RLENGTH=d }
+#_______________________________________________________________________
+func _conl(t,ts) { ####################################################
+ return _con(t (t~/\x0A$/ ? "" : _CHR["EOL"]),ts) }
+#_______________________________________________________________________
+func _conline(t,ts) { #################################################
+ return _con(_chrline(t,ts)) }
+#_______________________________________________________________________
+func _constat(t,ts, ln,a) { ###########################################
+ if ( _constatstrln>(ln=length(t=_constatgtstr(_constatstr=_tabtospc(t,ts),_CON_WIDTH-1-_conlastrln))) ) {
+ t=t _getchrln(" ",_constatstrln-ln) }
+ _constatstrln=ln
+ ln=ORS; a=BINMODE; BINMODE="rw"; ORS=""
+ print (t _CHR["CR"] _conlastr) > _SYS_STDCON; fflush(_SYS_STDCON)
+ ORS=ln; BINMODE=a; return _constatstr }
+#_________________________________________________________________
+func _constatgtstr(t,ln, a,b) {
+ if ( ln<1 ) {
+ return "" }
+ if ( (a=length(t))<=ln ) {
+ return t }
+ if ( ln<11 ) {
+ return substr(t,a-ln+1) }
+ if ( ln<19 ) {
+ return "..." substr(t,a-ln+4) }
+ return substr(t,1,b=int((ln-3)/2)) "..." substr(t,a-ln+b+4) }
+#_______________________________________________________________________
+func _constatpush(t,ts) { #############################################
+ _CONSTATPUSH[++_CONSTATPUSH[0]]=_constatstr
+ if ( t ) _constat(t,ts)
+ return _constatstr }
+#_______________________________________________________________________
+func _constatpop() { ##################################################
+ if ( _CONSTATPUSH[0]>0 ) {
+ return _constat(_CONSTATPUSH[_CONSTATPUSH[0]--]) }
+ return _constat("") }
+#_______________________________________________________________________
+func _conin(t, a,b) { #################################################
+ _constatpush(); _constat(); a=BINMODE; b=RS; BINMODE="rw"; RS="\n"
+ _con(t); getline t < "CON"; close("CON"); _conlastrln=0; _conlastr=""
+ gsub(/[\x0D\x0A]+/,"",t)
+ BINMODE=a; RS=b; _constatpop()
+ return t }
+#___________________________________________________________________________________
+####################################################################################
+
+
+
+func _conlq(t,ts) {
+ return _conl("`" t "'",ts) }
+
+
+
+
+
+
+
+
+####################################################################################
+# PUBLIC:
+#_____________________________________________________________________________
+# var _SYS_STDOUT - (by default = "/dev/stdout") standart output pipe filename
+# var _SYS_STDERR - (by default = "/dev/stderr") standart error output pipe filename
+# var _SYS_STDCON - (by default = "CON") standart console output device
+#_____________________________________________________________________________
+# var _CHR["CR"] - return cursor to the position 0 without newline(normally ="\x0D")
+# var _CHR["EOL"] - return cursor to the position 0 & newline (MS:="\x0D\x0A" / UX:="\x0D")
+# var _CON_WIDTH - console width(columns number)
+#_____________________________________________________________________________
+# fn _cmd(c) - execute shell command c and return output
+# fn _err - output string w\o any addition into _SYS_STDERR device
+# fn _errnl - output string with addition _CHR["EOL"] at the end of the string into _SYS_STDERR device
+# fn _out - output string w\o any addition into _SYS_STDOUT device
+# fn _outnl - output string with addition _CHR["EOL"] at the end of the string into _SYS_STDOUT device
+#_____________________________________________________________________________
+# fn _con(text[,tabspace])
+# fn _conl(text[,tabspace])
+# fn _conline(text[,tabspace])
+# fn _constat(status[,tabspace])
+# fn _constatpush([status[,tabspace]])
+# fn _constatpop()
+#_______________________________________________________________________
+# var _constatstr
+####################################################################################
+
+
+func _unstr(t) { return gensub(/\\(.)/,"\\1","G",t) }
+#_____________________________________________________________________________
+func _gensubfn(t,r,f,p0, A) { ###############################################
+ if ( match(t,r,A) ) return substr(t,1,RSTART-1) @f(_th0(substr(t,RSTART,RLENGTH),t=substr(t,RSTART+RLENGTH)),A,p0) _gensubfn(t,r,f,p0)
+ return t }
+#_____________________________________________________________________________
+func _rexpstr(r, i,c,A) { ###################################################
+ c=split(r,A,""); r=""
+ for ( i=1; i<=c; i++ ) r=r _REXPSTR[A[i]]
+ return r }
+#_____________________________________________________________________________
+func _hexnum(n,l) { #########################################################
+ if ( l+0<1 ) l=2
+ return sprintf("%." (l+0<1 ? 2 : l) "X",n) }
+#_____________________________________________________________________________
+func _ln(t) { ###############################################################
+ return t~/\x0A$/ ? t : (t _CHR["EOL"]) }
+#_______________________________________________________________________
+func _getchrln(s,w) { #################################################
+ if ( s=="" ) return
+ #if ( w!=w+0 || w<0 ) w=_CON_WIDTH
+ if ( length(s)<w ) { if ( s in _GETCHRLN ) { if ( length(_getchrlnt0=_GETCHRLN[s])>=w ) return substr(_getchrlnt0,1,w) }
+ else _getchrlnt0=s s
+ while ( length(_getchrlnt0)<w ) _getchrlnt0=_getchrlnt0 _getchrlnt0
+ _GETCHRLN[s]=_getchrlnt0; return substr(_getchrlnt0,1,w) }
+ else return substr(s,1,w) }
+#_______________________________________________________________________
+func _chrline(t,ts,w,s) { #############################################
+ return (t=" " _tabtospc(t,ts) (t ? t~/[ \t]$/ ? "" : " " : "")) _getchrln(s ? s : "_",(w ? w : _CON_WIDTH-1)-length(t)) _CHR["EOL"] }
+#_______________________________________________________________________
+func _tabtospc(t,ts,xc, a,c,n,A,B) { ##################################
+ if ( !ts ) {
+ ts=_TAB_STEP_DEFAULT }
+ c=split("." t,A,/\t+/,B); A[1]=substr(A[1],2); t=""
+ for ( n=1; n<=c; n++ ) {
+ t=t A[n] _getchrln(" ",(xc=length(B[n])*ts+int((a=xc+length(A[n]))/ts)*ts)-a) }
+ return t }
+#_________________________________________________________________
+func _lspctab(t,ts,l, l1,l2,A) { ################################
+ while ( match(t,/^(\t*)( *)((\t*)(.*))$/,A) ) {
+ if ( A[1,"length"]>=l ) return substr(t,l+1)
+ if ( A[2] ) {
+ if ( (l1=int(A[2,"length"]/ts))>=(l2=l-A[1,"length"]) ) return substr(A[2],l2*ts+1) A[3]
+ if ( !A[4] ) return A[5]
+ t=A[1] _getchrln("\t",l1) A[3] }
+ else return t } }
+#_______________________________________________________________________
+func _qstr(t, c,A,B) { ################################################
+ c=""; for ( t=split(t,A,/[\x00-\x1F\\"]/,B); t>=0; t-- ) {
+ c=_QSTR[B[t]] A[t+1] c }
+ return c }
+#_________________________________________________________________
+func _qstrq(t) { ################################################
+ gsub(/\\/,"\\\\",t); gsub(/"/,"\\\"",t); return t }
+#_______________________________________________________________________
+func _Zexparr(S,s, t,i) { ##############################################
+ t=""; if ( isarray(S) ) {
+ for ( i in S ) {
+ t=t (isarray(S[i]) ? (_Zexparr_i1(i) "\x10" _Zexparr_i0(S[i]) "\x11\x11\x10" ) : (_Zexparr_i2(_Zexparr_i3(i) "\x11" _Zexparr_i3(S[i])) "\x10" ) ) } }
+ if ( s!="" ) {
+ gsub(/\x1B/,"\x1B\x3B",s)
+ gsub(/\x10/,"\x1B\x30",s)
+ t=t "\x11\x11\x10" s }
+ gsub(/\x0A/,"\x1B\x3A",t); return t }
+#_________________________________________________________________
+func _Zexparr_i0(S, t,i) {
+ for ( i in S ) {
+ t=t (isarray(S[i]) ? (_Zexparr_i1(i) "\x10" _Zexparr_i0(S[i]) "\x11\x11\x10" ) : (_Zexparr_i2(_Zexparr_i3(i) "\x11" _Zexparr_i3(S[i])) "\x10" ) ) }
+ return t }
+#_________________________________________________________________
+func _Zexparr_i1(t) {
+ gsub(/\x1B/,"\x1B\x3B",t); gsub(/\x11/,"\x1B\x31",t); gsub(/\x10/,"\x1B\x30",t)
+ return t }
+#_________________________________________________________________
+func _Zexparr_i2(t) {
+ gsub(/\x10/,"\x1B\x30",t); return t }
+#_________________________________________________________________
+func _Zexparr_i3(t) {
+ gsub(/\x1B/,"\x1B\x3B",t); gsub(/\x11/,"\x1B\x31",t)
+ return t }
+#_______________________________________________________________________
+func _Zimparr(D,t, A,B) { ##############################################
+ if ( isarray(D) ) {
+ split(t,A,/\x10/,B)
+ t=_Zimparr_i0(A,B,_Zimparr_i1(D,A,B,1))
+ gsub(/\x1B\x30/,"\x10",t)
+ gsub(/\x1B\x3B/,"\x1B",t)
+ return t } }
+#_________________________________________________________________
+func _Zimparr_i0(A,B,i) {
+ return i in A ? (A[i] B[i] _Zimparr_i0(A,B,i+1)) : "" }
+#_________________________________________________________________
+func _Zimparr_i1(D,A,B,i, t,a,n) {
+ while ( i in B ) {
+ if ( (t=A[i++])=="\x11\x11" ) return i
+ gsub(/\x1B\x30/,"\x10",t)
+ if ( (a=index(t,"\x11"))>0 ) {
+ if ( isarray(D[n=_Zimparr_i2(substr(t,1,a-1))]) ) {
+ delete D[n] }
+ D[n]=_Zimparr_i2(substr(t,a+1)) }
+ else {
+ if ( !isarray(D[t=_Zimparr_i2(t)]) ) {
+ delete D[t]; D[t][""]; delete D[t][""] }
+ i=_Zimparr_i1(D[t],A,B,i) } } }
+#_________________________________________________________________
+func _Zimparr_i2(t) {
+ gsub(/\x1B\x31/,"\x11",t); gsub(/\x1B\x3B/,"\x1B",t)
+ return t }
+#___________________________________________________________________________________
+####################################################################################
+
+
+
+
+#_______________________________________________________________________
+# _CHR array
+#
+# _CHR[ASC-code decimal number]=="char"
+#
+# Contains 256 elements. The index is the decimal number from 0-255.
+# The value is the single character with ASC-code equivalent to index number:
+#
+# _CHR[97] =="a" - character with ASC-code 97 is `a'
+#
+# This array is useful if you want to get character using it's ASC-code
+#_________________________________________________________________
+# _ASC array
+#
+# _ASC[char]==number: ASC-code of char
+#
+# Contains 256 elements. The index is the any single character with ASC-code \x00-\xFF.
+# The value is the number equivalent of character's ASC-code:
+#
+# _ASC["A"] ==65 - ASC-code of character `A' is 65
+#
+# This array is useful if you want to get ASC-code of the character.
+#_________________________________________________________________
+# _QASC array
+#
+# _QASC[char]=="string: octal ASC-code of char in 3-digit octal format"
+#
+# Contains 256 elements. The index is the any single charcter with ASC-code \x00-\xFF.
+# The value is the octal number equivalent of character's ASC-code in fixed-length - 3-digit - string:
+#
+# _QASC["!"] =="041" - ASC-code of character `!' is 33(decimal) == 41(in octal)
+# _QASC["\x0D"] =="015"
+#
+# This array is useful when some type of string escape conversion is performed. It allows quickly get
+# replace string for the characters that can be specified only by character code in result string:
+#
+# "\x0D" -> "\\015"
+#_______________________________________________________________________
+
+
+
+
+
+
+
+####################################################################################
+# PUBLIC:
+#_____________________________________________________________________________
+# fn _getchrln(ptt,len)
+#_____________________________________________________________________________
+# fn _tabtospc(src,tabstep,xcoord)
+####################################################################################
+
+#_____________________________________________________________________________
+func _retarr(A,i,p,a, q) { ##################################################
+ if ( isarray(A) ) {
+ i=i=="" ? 0 : i+0; q=A[_ARRLEN]+0
+ if ( i<q ) return p A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] _retarr_i0(A,q,i,a)
+ } }
+
+func _retarr_i0(A,q,i,a) {
+ if ( i<q ) return A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] _retarr_i0(A,q,i,a)
+ while ( q<i ) delete A[++q]
+ return a }
+#_____________________________________________________
+# _retarr(ARRAY,start,prefixtr,postfixtr)
+# Return string collected from elements of ARRAY.
+# The data elements in ARRAY have numeric indexes. By default it starts from element with index 1, but it is possible to locate elements starting from
+# 0,-1,-.... The last data element in the ARRAY have the highest numeric index that is stored in ARRAY[_ARRLEN].
+# Optimized for very large data size.
+#
+# IN: ARRAY - source data array(is ARRAY is not array then return undefined)
+# start - (optional) start index in ARRAY; if missed or have non-numeric value then start array index will be 1.
+# prefixst - the string that will be inserted in the begin of generated return string
+# postfix - the string that will be added at the end of generated return string
+# MOD: -
+# OUT: -
+# RETURN: undefined - if ARRAY is not array; if ARRAY is empty; if start is higher than ARRAY last element index
+# string - collected string: prefixtr-arraydata-postfixtr
+#_________________________________________________________________
+func _nretarr(A,i,v, r,q) { #####################################
+ if ( (i=i=="" ? 1 : i+0)<=(q=A[_ARRLEN]) ) {
+ if ( i<=(r=q-16) ) {
+ _ARRSTR=A[i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i]
+ while ( i<r ) _ARRSTR=_ARRSTR A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i]
+ _ARRSTR=_ARRSTR A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] v _retarr_i0(A,q,i)
+ return }
+ _ARRSTR=A[i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] v _retarr_i0(A,q,i)
+ return }
+ _ARRSTR=v
+ return }
+#___________________________________________________________
+func _nretarrd(A,i,v, r,q) { ##############################
+ if ( (i=i=="" ? 1 : i+0)<=(q=A[_ARRLEN]) ) {
+ if ( i<=(r=q-16) ) {
+ _ARRSTR=A[i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i]
+ while ( i<r ) _ARRSTR=_ARRSTR A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i]
+ _ARRSTR=_ARRSTR A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] v _retarr_i0(A,q,i) }
+ else _ARRSTR=A[i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] v _retarr_i0(A,q,i) }
+ else _ARRSTR=v
+ delete A; A[""]; delete A[""] }
+#_______________________________________________
+BEGIN{ _ARRLEN ="\x1ALEN"
+ _ARRPTR ="\x1APTR"
+ _ARRSTR="" }
+#_______________________________________________________________________
+func _movarr(D,S) { ###################################################
+ delete D; D[""]; delete D[""]
+ _addarr(D,S) }
+#_________________________________________________________________
+func _addarr(D,S) { #############################################
+ if ( isarray(S) ) _addarr_i0(D,S) }
+#_____________________________________________________
+func _addarr_i0(D,S, i) {
+ for ( i in S ) {
+ if ( isarray(S[i]) ) {
+ delete D[i]; D[i][""]; delete D[i][""]; _addarr_i0(D[i],S[i]) }
+ else {
+ delete D[i]; D[i]=S[i] } } }
+#_______________________________________________________________________
+func _addarrmask(D,S,M) { #############################################
+ for ( _addarrmaski0 in M ) { if ( _addarrmaski0 in S ) { if ( isarray(S[_addarrmaski0]) ) { if ( !isarray(D[_addarrmaski0]) ) { delete D[_addarrmaski0]; D[_addarrmaski0][""]; delete D[_addarrmaski0][""] }
+ if ( isarray(M[_addarrmaski0]) ) { _addarrmask(D[_addarrmaski0],S[_addarrmaski0],M[_addarrmaski0]) }
+ else { _extarr_i0(D[_addarrmaski0],S[_addarrmaski0]) } }
+ else { if ( isarray(D[_addarrmaski0]) ) delete D[_addarrmaski0]
+ D[_addarrmaski0]=S[_addarrmaski0] } }
+ else delete D[_addarrmaski0] } }
+#_______________________________________________________________________
+func _add(S,sf,D,df) { ################################################
+ if ( sf in S ) {
+ if ( isarray(S[sf]) ) {
+ if ( df in D ) {
+ if ( isarray(D[df]) ) return _extarr(D[df],S[sf])
+ delete D[df] }
+ D[df][""]; delete D[df][""]
+ return _extarr(D[df],S[sf]) }
+ else {
+ if ( isarray(D[df]) ) delete D[df]
+ D[df]=D[df] S[sf] } } }
+#_______________________________________________________________________
+func _ins(S,sf,D,df) { ################################################
+ if ( sf in S ) {
+ if ( isarray(S[sf]) ) {
+ if ( df in D ) {
+ if ( isarray(D[df]) ) return _extarr(D[df],S[sf])
+ delete D[df] }
+ D[df][""]; delete D[df][""]
+ return _extarr(D[df],S[sf]) }
+ else {
+ if ( isarray(D[df]) ) delete D[df]
+ D[df]=S[sf] D[df] } } }
+#_______________________________________________________________________
+func _cmparr(A0,A1,R, a,i) { ##########################################
+ a=0; delete R
+ for ( i in A0 ) {
+ if ( !(i in A1) ) {
+ a++; R[i]=0 }
+ else if ( A0[i]!=A1[i] ) {
+ a++; R[i]=2 } }
+ for ( i in A1 ) {
+ if ( !(i in A0) ) {
+ a++; R[i]=1 } }
+ return a }
+#_______________________________________________________________________
+func _deletepfx(A,f, B,le,i) { ########################################
+ le=length(f)
+ for ( i in A ) {
+ if ( substr(toupper(i),1,le)==f ) {
+ B[i]=A[i]; delete A[i] } } }
+#___________________________________________________________________________________
+####################################################################################
+
+
+#_______________________________________________________________________
+func _addlist(A,v) { ##################################################
+ A[++A[0]]=v }
+
+
+
+
+
+
+
+
+
+
+
+#_________________________________________________________________
+func _retarrd(A,v, i) { #########################################
+ if ( 1 in A ) return A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] A[9] A[10] A[11] A[12] A[13] A[14] A[15] A[16] ((i=17) in A ? _retarrd_i0(A,i) v : v)
+ delete A; return v }
+#_____________________________________________________
+func _retarrd_i0(A,i) {
+ if ( i in A ) return A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] (i in A ? _retarrd_i0(A,i) : "")
+ delete A }
+
+
+
+
+#_________________________________________________________________
+func _lengthsort(i1, v1, i2, v2) { ##############################
+ return length(i1)<length(i2) ? -1 : length(i1)>length(i2) ? 1 : i1<i2 ? -1 : 1 }
+
+
+#_______________________________________________________________________
+func _dumparr(A,t,lv, a) { ############################################
+ b=PROCINFO["sorted_in"]; PROCINFO["sorted_in"]="_lengthsort"
+ if ( isarray(A) ) {
+ delete _DUMPARR; _dumparrc=_dumparrd=""
+ _dumparr_i1(A,lv=(lv=="" ? 16 : lv==0 || (lv+0)!=0 ? lv : lv=="-*" ? -3 : lv~/^\+?\*$/ ? 3 : 16)+0,lv<0 ? -1 : 1,0,_tabtospc(t))
+ PROCINFO["sorted_in"]=a
+ return _retarrd(_DUMPARR,_dumparrd, _dumparrd="") } }
+#___________________________________________________________
+func _dumparr_i1(A,lv,ls,ln,t, t2,i,a,f) {
+ t2=_getchrln(" ",length(t))
+ if ( ln==lv ) { if ( ls>0 ) for ( i in A ) ++a
+ else for ( i in A ) isarray(A[i]) ? ++a : ""
+ if ( length(_dumparrd=_dumparrd t (a>0 ? " ... (x" a ")" : "") _CHR["EOL"])>262144 ) { _DUMPARR[++_dumparrc]=_dumparrd; _dumparrd="" }
+ return }
+ if ( ls>=0 ) for ( i in A ) if ( !isarray(A[i]) ) if ( length(_dumparrd=_dumparrd (f ? t2 : t _nop(f=1)) "[" i "]=" A[i] "'" _CHR["EOL"])>262144 ) { _DUMPARR[++_dumparrc]=_dumparrd; _dumparrd="" }
+ for ( i in A ) if ( isarray(A[i]) ) _dumparr_i1(A[i],lv,ls,ln+ls,_th0(f ? t2 : t,f=1) "[" i "]")
+ if ( !f ) if ( length(_dumparrd=_dumparrd t _CHR["EOL"])>262144 ) { _DUMPARR[++_dumparrc]=_dumparrd; _dumparrd="" } }
+#_________________________________________________________________
+func _printarr(A,t,lv,r, a) { ####################################
+ a=PROCINFO["sorted_in"]; PROCINFO["sorted_in"]="_lengthsort"; _printarrexp=r ? r : ""
+ if ( isarray(A) ) {
+ delete _DUMPARR; _dumparrc=_dumparrd=""
+ _printarr_i1(A,lv=(lv=="" ? 16 : lv==0 || (lv+0)!=0 ? lv : lv=="-*" ? -3 : lv~/^\+?\*$/ ? 3 : 16)+0,lv<0 ? -1 : 1,0,_tabtospc(t))
+ PROCINFO["sorted_in"]=a
+ return _retarrd(_DUMPARR,_dumparrd, _dumparrd="") } }
+#___________________________________________________________
+func _printarr_i1(A,lv,ls,ln,t, t2,i,a,f) {
+ t2=_getchrln(" ",length(t))
+ if ( ln==lv ) { if ( ls>0 ) for ( i in A ) ++a
+ else for ( i in A ) isarray(A[i]) ? ++a : ""
+ if ( length(_dumparrd=_dumparrd t (a>0 ? " ... (x" a ")" : "") _CHR["EOL"])>262144 ) { _conl(_dumparrd); _dumparrd="" }
+ return }
+ if ( ls>=0 ) for ( i in A ) if ( !_printarrexp || i~_printarrexp ) if ( !isarray(A[i]) ) if ( length(_dumparrd=_dumparrd (f ? t2 : t _nop(f=1)) "[" i "]=" A[i] "'" _CHR["EOL"])>262144 ) { _conl(_dumparrd); _dumparrd="" }
+ for ( i in A ) if ( isarray(A[i]) ) if ( !_printarrexp || i~_printarrexp ) _printarr_i1(A[i],lv,ls,ln+ls,_th0(f ? t2 : t,f=1) "[" i "]")
+ if ( !f ) if ( length(_dumparrd=_dumparrd t _CHR["EOL"])>262144 ) { _conl(_dumparrd); _dumparrd="" } }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+####################################################################################
+
+#_____________________________________________________________________________
+func _th0(p,p1,p2,p3) { return p } ##########################################
+#_________________________________________________________________
+func _th1(p0,p,p2,p3) { return p } ##############################
+#_________________________________________________________________
+func _th2(p0,p1,r,p3) { return p } ##############################
+#_________________________________________________________________
+func _th3(p0,p1,p2,r) { return p } ##############################
+#_________________________________________________________________
+func _th10(p0,p1) { return p1 p0 } ##############################
+#_______________________________________________________________________
+func _nop(p0,p1,p2,p3) { } ############################################
+#_______________________________________________________________________
+func _bearray(A) { ####################################################
+ if ( isarray(A) || (A==0 && A=="") ) return 1 }
+#_______________________________________________________________________
+func _setarrsort(f, a) { ##############################################
+ a=PROCINFO["sorted_in"]
+ if ( !f ) delete PROCINFO["sorted_in"]
+ else PROCINFO["sorted_in"]=f
+ return a }
+#_________________________________________________________________
+func cmp_str_idx(i1, v1, i2, v2) { ##############################
+ return i1 < i2 ? -1 : 1 }
+#___________________________________________________________
+func ncmp_str_idx(i1, v1, i2, v2) { #######################
+ return i1 < i2 ? 1 : -1 }
+#_______________________________________________________________________
+func _exit(c) { #######################################################
+ exit c }
+#_______________________________________________________________________
+func _fn(f,p0,p1,p2) { ################################################
+ if ( f in FUNCTAB ) return @f(p0,p1,p2) }
+#_______________________________________________________________________
+func _defn(f,c,v) { ###################################################
+ FUNCTAB[c f]=v }
+#_______________________________________________________________________
+func _delay(t, a) { ###################################################
+ for ( a=1; a<=t; a++ ) {
+ _delayms() } }
+#_________________________________________________________________
+func _delayms( a) { #############################################
+ for ( a=1; a<=_delay_perfmsdelay; a++ ) { } }
+#_______________________________________________________________________
+func _getdate() { #####################################################
+ return strftime("%F") }
+#_________________________________________________________________
+func _getime() { ################################################
+ return strftime("%H:%M:%S") }
+#_________________________________________________________________
+func _getsecond() { #############################################
+ return systime() }
+#___________________________________________________________
+func _getsecondsync( a,c,b,c2) { ##########################
+ a=systime()
+ while ( a==systime() ) { ++c }
+ return a+1 }
+#_______________________________________________________________________
+func _getperf(o,t, a) { ###############################################
+ o=="" ? ++_getperf_opcurr : _getperf_opcurr=o
+ if ( (a=_getsecond())!=_getperf_last ) {
+ _getperf_opsec=(_getperf_opcurr-_getperf_opstart)/((_getperf_last=a)-_getperf_start)
+ return @_getperf_fn(o,t,a) }
+ return 1 }
+#_____________________________________________________
+BEGIN{
+ _getperf_fn="_nop" }
+#___________________________________________________________
+func _getperf_noenot(o,t,a) { return 1 }
+#___________________________________________________________
+func _getperf_noe(o,t,a) {
+ if ( _getperf_opsecp!=_getperf_opsec ) { _constat((_constatstr==_getperf_stat ? _getperf_statstr : (_getperf_statstr=_constatstr)) t " [TIME=" (a-_getperf_start) " sec(" (_getperf_opsecp=_getperf_opsec) " ops/sec)]"); _getperf_stat=_constatstr }
+ return 1 }
+#___________________________________________________________
+func _getperf_not(o,t,a) {
+ if ( a<_getperf_end ) return 1 }
+#___________________________________________________________
+func _getperf_(o,t,a) {
+ if ( a>=_getperf_end ) return 0
+ if ( _getperf_opsecp!=_getperf_opsec ) { _constat((_constatstr==_getperf_stat ? _getperf_statstr : (_getperf_statstr=_constatstr)) t " [TIME=" (a-_getperf_start) " sec(" (_getperf_opsecp=_getperf_opsec) " ops/sec)]"); _getperf_stat=_constatstr }
+ return 1 }
+#_________________________________________________________________
+func _igetperf(t,s,o) { ######################################### # t-test period in seconds(==0 ? no period; s(=true/false)-output/not output status; o-qnt of ops before test start
+ if ( t==0 && t=="" && s==0 && s=="" && o==0 && o=="" ) {
+ if ( _getperf_fn!~/not$/ && _constatstr==_getperf_stat ) _constat(_getperf_statstr)
+ _getperf_fn="_nop"
+ return "[TIME=" (_getperf_last-_getperf_start) " sec(" _getperf_opsec " ops/sec)]" }
+ _conl("initiate _getperf")
+ _getperf_opstart=_getperf_opcurr=o+0; _getperf_opsec=_getperf_opsecp=_getperf_stat=_getperf_statstr=""
+ _getperf_end=t+(_getperf_start=_getperf_last=_getsecondsync())
+ _getperf_fn=(t+0>0 ? "_getperf_" : "_getperf_noe") (s ? "" : "not")
+ return _getperf_start }
+
+#___________________________________________________________________________________
+####################################################################################
+
+
+#_______________________________________________________________________
+func _addf(A,f) { #####################################################
+ A["B"][""]=A["F"][A["B"][f]=A["B"][""]]=f }
+#_________________________________________________________________
+func _insf(A,f) { ###############################################
+ A["F"][""]=A["B"][A["F"][f]=A["F"][""]]=f }
+#_________________________________________________________________
+func _delf(A,f) { ###############################################
+ A["B"][A["F"][A["B"][f]]=A["F"][f]]=A["B"][f]
+ delete A["F"][f]; delete A["B"][f] }
+#_______________________________________________________________________
+func _pass(A,f,t,p2, i,a) { ###########################################
+ a=_endpass_v0; _endpass_v0=""; i=1
+ while ( t && i ) { i=""; while ( (i=A[i]) && (t==(t=@i(f,t,p2))) ) { } }
+ if ( i && _endpass_v0 ) { A["!"]=1; t=_endpass_v0 }
+ else delete A["!"]
+ _endpass_v0=a; return t }
+#_________________________________________________________________
+func _endpass(t) { _endpass_v0=t } ########################
+#_________________________________________________________________
+func _inspass(A,f) { A[f]=A[""]; A[""]=f } ##################
+#_______________________________________________________________________
+func _fframe(A,t,p) { #################################################
+ return _fframe_i0(A,t,p,A[""]) }
+#___________________________________________________________
+func _fframe_i0(A,t,p,f) {
+ return f ? (@f(t,p) _fframe_i0(A,t,p,A[f])) : "" }
+#_________________________________________________________________
+func _bframe(A,t,p) { ###########################################
+ return _bframe_i0(A,t,p,A[""]) }
+#___________________________________________________________
+func _bframe_i0(A,t,p,f) {
+ return f ? (_bframe_i0(A,t,p,A[f]) @f(t,p)) : "" }
+#_________________________________________________________________
+func _insframe(A,f) { ###########################################
+ A[f]=A[""]; A[""]=f }
+#_______________________________________________________________________
+########################################################################
+
+
+
+
+
+
+
+
+
+func _fthru(A,c,p, B) {
+ return _fthru_i0(A,c,p,B,A[""]) }
+#_________________________________________________________________
+func _fthru_i0(A,c,p,B,f) {
+ return f ? @f(c,_fthru_i0(A,c,p,B,A[f]),B) : "" }
+
+
+
+
+
+
+
+
+
+
+
+#_______________________________________________________________________
+########################################################################
+#EXPERIMENTAL
+
+func _rexpfn(R,t,p) {
+ _REXPFN[""]=""
+ while ( t ) {
+ t=_rxpfn(R,t,p) }
+ return _REXPFN[""] }
+
+func _rxpfn(R,t,p, i,f,A) {
+ for ( i in R ) {
+ if ( match(t,i,A) ) {
+ f=R[i]; if ( t!=(t=@f(A,substr(t,RLENGTH+1),p)) ) return t } }
+ return _rexpfnend(t) }
+
+func _rexpfnend(t) {
+ _REXPFN[""]=t }
+
+
+func _ffaccr(A,t,p,P) {
+ return _faccr_i0(A["F"],t,p,P) }
+
+func _fbaccr(A,t,p,P) {
+ return _faccr_i0(A["B"],t,p,P) }
+
+func _faccr_i0(A,t,p,P, f,r) {
+ f=r=""
+ if ( isarray(A) ) {
+ while ( (f=A[f]) ) r=r @f(t,p,P) }
+ return r }
+
+func _ffaccl(A,t,p,P) {
+ return _faccl_i0(A["F"],t,p,P) }
+
+func _fbaccl(A,t,p,P) {
+ return _faccl_i0(A["B"],t,p,P) }
+
+func _faccl_i0(A,t,p,P, f,r) {
+ f=r=""
+ if ( isarray(A) ) {
+ while ( (f=A[f]) ) r=@f(t,p,P) r }
+ return r }
+
+
+func _Foreach(A,f, p0, i) {
+ for ( i in A ) @f(A,i,p0) }
+#_______________________________________________________________________
+func _foreach(A,f,r,p0,p1,p2, i,p) { ####################################
+ if ( isarray(A) ) {
+ _TMP0[p=_n()]["."]=1
+ _foreach_i0(A,f,_TMP0[p],p0,p1,p2)
+ return _th0(_retarr(_TMP0[p]),_tdel(p)) }
+ if ( _isptr(A) ) {
+ _TMP0[p=_n()][_ARRLEN]=1
+ _tframe4("_foreach_i1" (r ? "~" r : ""),A,f,_TMP0[p],p0,p1)
+ return _th0(_retarr(_TMP0[p]),_tdel(p)) } }
+ #_____________________________________________________
+ func _foreach_i0(A,f,D,p0,p1,p2) {
+ for ( i in A ) {
+ if ( isarray(A[i]) ) _foreach_i0(A[i],f,D,p0,p1,p2)
+ else _gen(D,@f(A[i],p0,p1,p2)) } }
+ #_____________________________________________________
+ func _foreach_i1(p,f,D,p0,p1,p2) {
+
+ _gen(D,@f(p,p0,p1,p2)) }
+
+BEGIN{
+ _datablock_length =262144 }
+
+func _gen(D,t) {
+ if ( length(D[D[_ARRLEN]]=D[D["."]] t)>_datablock_length ) {
+ D[++D[_ARRLEN]]="" } }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+####################################################################################
+# PUBLIC:
+#_____________________________________________________________________________
+# fn _th0,_th1,_th2,_th3
+# USAGE:
+# _th0(p1,p2,p3,p4)
+#
+# Each of this functions can have up to 4 parameters.
+# _th0(p1,p2,p3,p4) return 1st parameter (p1)
+# _th1(p1,p2,p3,p4) return 2nd parameter (p2)
+# _th2(p1,p2,p3,p4) return 3rd parameter (p3)
+# _th3(p1,p2,p3,p4) return 4th parameter (p4)
+#_____________________________________________________________________________
+# fn _nop(p1,p2,p3,p4,p5,p6,p7,p8)
+# USAGE:
+# _nop()
+#
+# Does not do any action. No result returned. Up to 8 parameters.
+#_____________________________________________________________________________
+# fn _exit(c)
+# USAGE:
+# _exit(code)
+#
+# This function do the same as GAWK-operator `exit code'.
+#_____________________________________________________________________________
+# fn _getdate()
+# fn _getime()
+# fn _getsecond()
+# fn _getsecondsync()
+func _rdreg(D,p) { ################################################################
+ _rdregp0="reg query \"" p "\" /S /reg:64 2>NUL"; _rdregfld=_rdregkey=0
+ _rdregq0=split(gensub(/[\x0D?\x0A]{2,}/,_CHR["EOL"],"G",_cmd(_rdregp0)),_RDREGA0,/\x0D?\x0A/)
+ while ( _rdregq0>0 ) _rdreg_i0(D)
+ return _rdregfld+_rdregkey }
+ #___________________________________________________________
+ func _rdreg_i0(D, A) { while ( _rdregq0>0 ){
+ if ( match(_rdregp0=_RDREGA0[_rdregq0--],/ (.*) REG_((SZ)|(DWORD)|(QWORD)|(BINARY)|(EXPAND_SZ)|(MULTI_SZ)) (.*)$/,A) ) {
+ if ( !_rdreg_i0(D) ) { ++_rdregfld; D[_rdregp0 A[1] "." _RDREGTYPE[A[2]]]=A[9]; return } else break }
+ else if ( _rdregp0~/^HK/ ) { ++_rdregkey; return D[_rdregp0=_rdregp0 "\\"] } } return 1 }
+ #_____________________________________________________
+ BEGIN { _initrdreg() }
+ func _initrdreg() { _RDREGTYPE["SZ"] ="STR"
+ _RDREGTYPE["DWORD"] ="W32"
+ _RDREGTYPE["QWORD"] ="W64"
+ _RDREGTYPE["BINARY"] ="BIN"
+ _RDREGTYPE["EXPAND_SZ"] ="XSZ"
+ _RDREGTYPE["MULTI_SZ"] ="MSZ"
+ _RDrdregfld=_rdregkey=0 }
+
+# _rdregfld : gvar - number of readed registry fields by _rdreg()
+# _rdregkey : gvar - number of readed registry keys by _rdreg()
+#_____________________________________________________________________________
+func _regpath0(D,i, s,q,S) { ############################################ 0 #
+ if ( i=_patharr0(S,i) ) {
+ if ( "name" in S ) D["name"]=S["name"]; if ( "ext" in S ) D["ext"]=S["ext"]
+ s=(toupper(s=i in S ? S[i] : "") in _REGPATH0REGDIR ? D[++q]=_REGPATH0REGDIR[toupper(s)] : (D[++q]=_REGPATH0REGDIR[""]) "\\" (D[++q]=s)) "\\"
+ while ( ++i in S ) s=s (D[++q]=S[i]) "\\"
+ if ( s!="" ) D[0]=s; IGNORECASE=1
+ D["hostdir"]="\\\\" (D["host"]="host" in S && ((""==i=S["host"]) || "."==i || "?"==i || "localhost"==i) ? ENVIRON["COMPUTERNAME"] : i) "\\" s; IGNORECASE=0 } }
+ #_____________________________________________________
+ BEGIN { _initregpath0() }
+ func _initregpath0() { _REGPATH0REGDIR[""] ="HKEY_LOCAL_MACHINE"
+ _REGPATH0REGDIR["HKLM"] ="HKEY_LOCAL_MACHINE"
+ _REGPATH0REGDIR["HKEY_LOCAL_MACHINE"] ="HKEY_LOCAL_MACHINE"
+ _REGPATH0REGDIR["HKCR"] ="HKEY_CLASSES_ROOT"
+ _REGPATH0REGDIR["HKEY_CLASSES_ROOT"] ="HKEY_CLASSES_ROOT"
+ _REGPATH0REGDIR["HKCU"] ="HKEY_CURRENT_USER"
+ _REGPATH0REGDIR["HKEY_CURRENT_USER"] ="HKEY_CURRENT_USER"
+ _REGPATH0REGDIR["HKU"] ="HKEY_USERS"
+ _REGPATH0REGDIR["HKEY_USERS"] ="HKEY_USERS"
+ _REGPATH0REGDIR["HKCC"] ="HKEY_CURRENT_CONFIG"
+ _REGPATH0REGDIR["HKEY_CURRENT_CONFIG"] ="HKEY_CURRENT_CONFIG"
+ _REGPATH0REGDIR["HKPD"] ="HKEY_PERFORMANCE_DATA"
+ _REGPATH0REGDIR["HKEY_PERFORMANCE_DATA"] ="HKEY_PERFORMANCE_DATA" }
+#_________________________________________________________________________________________
+##########################################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+func _getreg_i1(D,r,R, a,i,il,ir,rc,B) {
+ a=IGNORECASE; IGNORECASE=1; r="^" _torexp(r); rc=0
+ zs=""
+ for ( i in R ) { if ( match(i,r,B) ) { il=B[_torexp_pfxcntr]; ir=gensub(/....$/,"",1,substr(i,1+B[_torexp_pfxcntr,"length"]))
+ if ( !gsub(/^\\/,"",ir) && match(il,/[^\\]+$/) ) ir=substr(il,RSTART) ir
+ D[ir]=R[i]; rc++ } }
+ IGNORECASE=a; if ( rc>0 ) return rc }
+#_________________________________________________________________________________________
+func _rrdreg(DD,p, k,t,v,c,i,q,tT,A,B,C,D) { ############################################# old; regedit
+ if ( !_registrytmpfile ) _registryinit()
+ _cmd("regedit /E \"" _registrytmpfile "\" \"" p "\" 2>&1")
+ q=patsplit(gensub(/[\x00\xFF\xFE]+/,"","G",_rdfile(_registrytmpfile)),A,/\x0D?\x0A\[[^\]]+\]\x0D?\x0A/,B)
+ for ( i=1; i<=q; i++ ) { p=gensub(/(^[ \t\x0D\x0A]*\[)|((\\)\\+)|(\][ \t\x0D\x0A]*$)/,"\\3","G",A[i]); DD[p "\\"]; delete C[split(B[i],C,/[\x0D\x0A]+/)]
+ for ( c=1; c in C; c++ ) { tt=tt C[c]; if ( gsub(/\\$/,"",tt) ) continue
+ if ( tt=="" ) continue
+ if ( match(_th0(tt,tt=""),/((^"(([^\\"]|\\.)*)")|(@))=(("(([^\\"]|\\.)*)")|(dword:([[:xdigit:]]{8}))|(hex(\(([27b])\))?:(.*)))$/,D) ) {
+ if ( D[7] ) { t="STR"; v=_unstr(D[8]) }
+ else if ( D[10] ) { t="W32"; v=D[11] }
+ else { v=D[15]
+ if ( D[13] ) { switch ( D[14] ) {
+ case "2": t="XSZ"; break
+ case "7": t="MSZ"; break
+ default: t="W64" } }
+ else t="BIN" }
+ DD[gensub(/(\\)\\+/,"\\1","G",p "\\" _unstr(D[3] (D[5] ? "(Default)" : "")) "." t)]=v }
+ else _fatal("regedit: unknown output format(" c "): `" C[c] "'") } } }
+ #_____________________________________________________
+ func _registryinit() { _registrytmpfile=_getmpfile() }
+#_____________________________________________________________________________
+# _rdreg(ARRAY,reg_path)
+# Import into ARRAY the content of the whole registree tree with the higher point specified by reg_path.
+# ARRAY will be filled by the strings with following format:
+#
+# HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\GnuWin32\CoreUtils\5.3.0\pck\InstallPath.STR=C:\Program Files (x86)\GnuWin32
+# where:
+# HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\GnuWin32\CoreUtils\5.3.0\pck <- REG KEY PATH
+# InstallPath <- DATA FIELD
+# STR <- TYPE
+# C:\Program Files (x86)\GnuWin32 <- VALUE
+# TYPE:
+# STR - REG_SZ (String Value)
+# W32 - REG_DWORD (DWORD (32-bit) Value)
+# W64 - REG_QWORD (QWORD (64-bit) Value)
+# BIN - REG_BINARY (Binary Value)
+# XSZ - REG_EXPAND_SZ (Expandable String Value)
+# MSZ - REG_MULTI_SZ (Multi-String Value)
+#_________________________________________________________________________________________
+
+
+
+
+# HKCR HKEY_CLASSES_ROOT
+# HKCU HKEY_CURRENT_USER
+# HKLM HKEY_LOCAL_MACHINE
+# HKU HKEY_USERS
+# HKCC HKEY_CURRENT_CONFIG
+# HKPD HKEY_PERFORMANCE_DATA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#___________________________________________________________________________________
+####################################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+func _sysinfo(D,h) { ##############################################################
+ h="wmic /NODE: \"" h "\" OS 2>NUL"
+ if ( split(_cmd(h),_SYSINFOA0,/[\x0D\x0A]+/)==3 ) {
+ _sysinfol0=length(h=_SYSINFOA0[2])+1; _sysinfoq0=_sysinfoq1=split(_SYSINFOA0[1],_SYSINFOA0,/ +/,_SYSINFOB0)
+ while ( --_sysinfoq0>0 ) D[_sysinfof0]=gensub(/^ +| +$/,"","G",substr(h,_sysinfol0=_sysinfol0-(_sysinfol1=length(_sysinfof0=_SYSINFOA0[_sysinfoq0])+length(_SYSINFOB0[_sysinfoq0])),_sysinfol1))
+ return _sysinfoq1-1 } }
+#_____________________________________________________________________________
+func zzer() { ################################################################
+ }
+ #_____________________________________________________
+ BEGIN { _initsys() }
+ func _initsys() { }
+#_________________________________________________________________________________________
+##########################################################################################
+
+
+
+
+
+
+
+#BootDevice BuildNumber BuildType Caption CodeSet CountryCode CreationClassName CSCreationClassName CSDVersion CSName CurrentTimeZone DataExecutionPrevention_32BitApplications DataExecutionPrevention_Available DataExecutionPrevention_Drivers DataExecutionPrevention_SupportPolicy Debug Description Distributed EncryptionLevel ForegroundApplicationBoost FreePhysicalMemory FreeSpaceInPagingFiles FreeVirtualMemory InstallDate LargeSystemCache LastBootUpTime LocalDateTime Locale Manufacturer MaxNumberOfProcesses MaxProcessMemorySize MUILanguages Name NumberOfLicensedUsers NumberOfProcesses NumberOfUsers OperatingSystemSKU Organization OSArchitecture OSLanguage OSProductSuite OSType OtherTypeDescription PAEEnabled PlusProductID PlusVersionNumber Primary ProductType RegisteredUser SerialNumber ServicePackMajorVersion ServicePackMinorVersion SizeStoredInPagingFiles Status SuiteMask SystemDevice SystemDirectory SystemDrive TotalSwapSpaceSize TotalVirtualMemorySize TotalVisibleMemorySize Version WindowsDirectory
+#\Device\HarddiskVolume1 7601 Multiprocessor Free Microsoft Windows Server 2008 R2 Enterprise 1252 1 Win32_OperatingSystem Win32_ComputerSystem Service Pack 1 CPU 180 TRUE TRUE TRUE 3 FALSE FALSE 256 0 6925316 33518716 41134632 20110502192745.000000+180 20130426120425.497469+180 20130510134606.932000+180 0409 Microsoft Corporation -1 8589934464 {"en-US"} Microsoft Windows Server 2008 R2 Enterprise |C:\Windows|\Device\Harddisk0\Partition2 0 116 2 10 64-bit 1033 274 18 TRUE 3 Windows User 55041-507-2389175-84833 1 0 33554432 OK 274 \Device\HarddiskVolume2 C:\Windows\system32 C: 50311020 16758448 6.1.7601 C:\Windows
+
+
+
+
+
+
+
+
+
+
+
+
+
+BEGIN { ############################################################################
+
+ a=ENVIRON["EGAWK_CMDLINE"]; gsub(/^[ \t]*/,"",a)
+ a=_lib_CMDLN(a)
+ if ( (a!="") && (!_LIBAPI["F"]["!"]) ) { _out(_lib_HELP()); _fatal("Bad comandline argument `" a "'") }
+ gsub(/^[ \t]*/,"",a); ENVIRON["EGAWK_CMDLINE"]=a
+ _lib_APPLY(); if ( _basexit_fl ) exit
+ _INIT()
+ _START()
+ _END() }
+#___________________________________________________________________________________
+func _INITBASE() { ################################################################
+
+ _egawk_utilpath =ENVIRON["EGAWK_PATH"] "BIN\\UTIL\\" }
+#___________________________________________________________________________________
+####################################################################################
+
+
+
+
+
+
+
+# make sure that stdout contain only expected characters
+# make sure that stderr contain only expected characters
+# redesign & reformat keys and its outputs
+# try different key combinations
+# add lib-specified to all libs
+
diff --git a/test/profile5.ok b/test/profile5.ok
new file mode 100644
index 00000000..5bf04dcf
--- /dev/null
+++ b/test/profile5.ok
@@ -0,0 +1,8354 @@
+BEGIN {
+ _addlib("_BASE")
+}
+
+#___________________________________________________________________________________
+BEGIN {
+ BINMODE = "rw"
+ SUBSEP = "\000"
+ _NULARR[""]
+ delete _NULARR[""]
+ _INITBASE()
+}
+
+BEGIN {
+ _addlib("_sYS")
+}
+
+BEGIN {
+ _addlib("_rEG")
+}
+
+BEGIN {
+ _addlib("_INSTRUC")
+}
+
+#___________________________________________________________________________________
+BEGIN {
+ _delay_perfmsdelay = 11500
+}
+
+BEGIN {
+ _addlib("_ARR")
+}
+
+#___________________________________________________________________________________
+BEGIN {
+}
+
+BEGIN { ###########################################################################
+ _addlib("_EXTFN")
+}
+
+#___________________________________________________________________________________
+BEGIN {
+ delete _XCHR
+ delete _ASC
+ delete _CHR
+ t = ""
+ for (i = 0; i < 256; i++) {
+ _ASC[a = _CHR[i] = sprintf("%c", i)] = i
+ _QASC[a] = sprintf("%.3o", i)
+ _XCHR[_CHR[i]] = sprintf("%c", (i < 128 ? i + 128 : i - 128))
+ }
+ #_____________________________________________________________________________
+
+ for (i = 0; i < 256; i++) {
+ _QSTRQ[_CHR[i]] = "\\" sprintf("%.3o", i)
+ }
+ #_______________________________________________________________________
+
+ for (i = 0; i < 32; i++) {
+ _QSTR[_CHR[i]] = _QSTRQ[_CHR[i]]
+ }
+ for (; i < 128; i++) {
+ _QSTR[_CHR[i]] = _CHR[i]
+ }
+ for (; i < 256; i++) {
+ _QSTR[_CHR[i]] = _QSTRQ[_CHR[i]]
+ }
+ _QSTR["\\"] = "\\\\"
+ #_____________________________________________________________________________
+
+ _CHR["CR"] = "\r"
+ _CHR["EOL"] = "\r\n"
+ _CHR["EOF"] = "\032"
+ _QSTR[_CHR["EOL"]] = "\\015\\012"
+ #_______________________________________________________________________
+
+ _CHR["MONTH"][_CHR["MONTH"]["Jan"] = "01"] = "Jan"
+ _CHR["MONTH"][_CHR["MONTH"]["Feb"] = "02"] = "Feb"
+ _CHR["MONTH"][_CHR["MONTH"]["Mar"] = "03"] = "Mar"
+ _CHR["MONTH"][_CHR["MONTH"]["Apr"] = "04"] = "Apr"
+ _CHR["MONTH"][_CHR["MONTH"]["May"] = "05"] = "May"
+ _CHR["MONTH"][_CHR["MONTH"]["Jun"] = "06"] = "Jun"
+ _CHR["MONTH"][_CHR["MONTH"]["Jul"] = "07"] = "Jul"
+ _CHR["MONTH"][_CHR["MONTH"]["Aug"] = "08"] = "Aug"
+ _CHR["MONTH"][_CHR["MONTH"]["Sep"] = "09"] = "Sep"
+ _CHR["MONTH"][_CHR["MONTH"]["Oct"] = "10"] = "Oct"
+ _CHR["MONTH"][_CHR["MONTH"]["Nov"] = "11"] = "Nov"
+ _CHR["MONTH"][_CHR["MONTH"]["Dec"] = "12"] = "Dec"
+ #_____________________________________________________________________________
+
+ _TAB_STEP_DEFAULT = 8
+ #_____________________________________________________________________________
+
+ for (i = 0; i < 32; i++) {
+ _REXPSTR[_CHR[i]] = _QSTRQ[_CHR[i]]
+ }
+ for (; i < 256; i++) {
+ _REXPSTR[_CHR[i]] = _CHR[i]
+ }
+ _gensubfn("\\^$.()|{,}[-]?+*", ".", "_rexpstr_i0")
+}
+
+BEGIN {
+ _addlib("_SYSIO")
+}
+
+#___________________________________________________________________________________
+BEGIN {
+ _SYS_STDCON = "CON"
+ _CON_WIDTH = (match(_cmd("MODE " _SYS_STDCON " 2>NUL"), /Columns:[ \t]*([0-9]+)/, A) ? strtonum(A[1]) : 80)
+}
+
+BEGIN {
+ _addlib("_FILEIO")
+}
+
+#___________________________________________________________________________________
+BEGIN {
+ if (_SYS_STDOUT == "") {
+ _SYS_STDOUT = "/dev/stdout"
+ }
+ if (_SYS_STDERR == "") {
+ _SYS_STDERR = "/dev/stderr"
+ }
+ _CHR["SUBDIR"] = "\\"
+ if (_gawk_scriptlevel < 1) {
+ match(b = _cmd("echo %CD% 2>NUL"), /[^\x00-\x1F]*/)
+ ENVIRON["CD"] = _FILEIO_RD = _filerd(substr(b, RSTART, RLENGTH) _CHR["SUBDIR"])
+ _FILEIO_R = _filer(_FILEIO_RD)
+ _FILEIO_D = _filed(_FILEIO_RD)
+ _setmpath(_filerd(_FILEIO_RD "_tmp" _CHR["SUBDIR"]))
+ }
+}
+
+BEGIN {
+ _addlib("_tOBJ")
+}
+
+#___________________________________________________________________________________
+BEGIN {
+ _tInBy = "\212._tInBy"
+ _tgenuid_init()
+ _UIDS[""]
+ delete _UIDS[""]
+ _UIDSDEL[""]
+ delete _UIDSDEL[""]
+ _tPREV[""]
+ _tPARENT[""]
+ _tNEXT[""]
+ _tFCHLD[""]
+ _tQCHLD[""]
+ _tLCHLD[""]
+ _tLINK[""]
+ _tCLASS[""]
+ _tSTR[""]
+ _tDLINK[""]
+ _[""]
+ delete _[""]
+ _ptr[""]
+ delete _ptr[""]
+ _TMP0[""]
+ delete _TMP0[""]
+ _TMP1[""]
+ delete _TMP1[""]
+}
+
+BEGIN {
+ _addlib("_ERRLOG")
+}
+
+#___________________________________________________________________________________
+BEGIN {
+ if (_gawk_scriptlevel < 1) {
+ _ERRLOG_TF = 1
+ _ERRLOG_VF = 1
+ _ERRLOG_IF = 1
+ _ERRLOG_WF = 1
+ _ERRLOG_EF = 1
+ _ERRLOG_FF = 1
+ _wrfile(_errlog_file = _getmpfile("OUTPUT.LOG"), "")
+ }
+}
+
+BEGIN {
+ _addlib("_SHORTCUT")
+}
+
+#___________________________________________________________________________________
+BEGIN {
+ _shortcut_init()
+}
+
+BEGIN { #########################################################
+ _addlib("_eXTFN")
+}
+
+#___________________________________________________________________________________
+BEGIN {
+ _extfn_init()
+}
+
+BEGIN { ############################################################
+ _addlib("_sHARE")
+}
+
+BEGIN {
+ _addlib("_FILEVER")
+}
+
+BEGIN {
+ _addlib("_DS") ###############################################################################
+ _PRODUCT_NAME = "Deployment Solution Control"
+ _PRODUCT_VERSION = "1.0"
+ _PRODUCT_COPYRIGHT = "Copyright (C) 2013 by CosumoGEN"
+ _PRODUCT_FILENAME = "_main.ewk"
+}
+
+# problem configuring uid by array charset: i can' understand what format of the array: possibly - remove array support
+# after removal of array format detection: there is unfinished conflicts: it is possible to totally remove array uid-gen initialization
+
+#_____________________________________________________
+BEGIN {
+ _inituidefault()
+}
+
+#_____________________________________________________
+BEGIN {
+ _initfilever()
+}
+
+#_____________________________________________________
+BEGIN {
+ _initshare()
+}
+
+#_________________________________________________________________
+BEGIN {
+ _inspass(_IMPORT, "_import_data")
+}
+
+#_______________________________________________
+BEGIN {
+ _TEND[_ARRLEN] = 0
+ _TYPEWORD = "_TYPE"
+}
+
+#_______________________________________________
+BEGIN {
+ _ARRLEN = "\032LEN"
+ _ARRPTR = "\032PTR"
+ _ARRSTR = ""
+}
+
+#_____________________________________________________
+BEGIN {
+ _getperf_fn = "_nop"
+}
+
+BEGIN {
+ _datablock_length = 262144
+}
+
+#_____________________________________________________
+BEGIN {
+ _initrdreg()
+}
+
+#_____________________________________________________
+BEGIN {
+ _initregpath0()
+}
+
+#_____________________________________________________
+BEGIN {
+ _initsys()
+}
+
+#_________________________________________________________________________________________
+##########################################################################################
+
+
+
+
+
+
+
+#BootDevice BuildNumber BuildType Caption CodeSet CountryCode CreationClassName CSCreationClassName CSDVersion CSName CurrentTimeZone DataExecutionPrevention_32BitApplications DataExecutionPrevention_Available DataExecutionPrevention_Drivers DataExecutionPrevention_SupportPolicy Debug Description Distributed EncryptionLevel ForegroundApplicationBoost FreePhysicalMemory FreeSpaceInPagingFiles FreeVirtualMemory InstallDate LargeSystemCache LastBootUpTime LocalDateTime Locale Manufacturer MaxNumberOfProcesses MaxProcessMemorySize MUILanguages Name NumberOfLicensedUsers NumberOfProcesses NumberOfUsers OperatingSystemSKU Organization OSArchitecture OSLanguage OSProductSuite OSType OtherTypeDescription PAEEnabled PlusProductID PlusVersionNumber Primary ProductType RegisteredUser SerialNumber ServicePackMajorVersion ServicePackMinorVersion SizeStoredInPagingFiles Status SuiteMask SystemDevice SystemDirectory SystemDrive TotalSwapSpaceSize TotalVirtualMemorySize TotalVisibleMemorySize Version WindowsDirectory
+#\Device\HarddiskVolume1 7601 Multiprocessor Free Microsoft Windows Server 2008 R2 Enterprise 1252 1 Win32_OperatingSystem Win32_ComputerSystem Service Pack 1 CPU 180 TRUE TRUE TRUE 3 FALSE FALSE 256 0 6925316 33518716 41134632 20110502192745.000000+180 20130426120425.497469+180 20130510134606.932000+180 0409 Microsoft Corporation -1 8589934464 {"en-US"} Microsoft Windows Server 2008 R2 Enterprise |C:\Windows|\Device\Harddisk0\Partition2 0 116 2 10 64-bit 1033 274 18 TRUE 3 Windows User 55041-507-2389175-84833 1 0 33554432 OK 274 \Device\HarddiskVolume2 C:\Windows\system32 C: 50311020 16758448 6.1.7601 C:\Windows
+
+
+
+
+
+
+
+
+
+
+
+
+
+BEGIN {
+ a = ENVIRON["EGAWK_CMDLINE"]
+ gsub(/^[ \t]*/, "", a)
+ a = _lib_CMDLN(a)
+ if (a != "" && ! _LIBAPI["F"]["!"]) {
+ _out(_lib_HELP())
+ _fatal("Bad comandline argument `" a "'")
+ }
+ gsub(/^[ \t]*/, "", a)
+ ENVIRON["EGAWK_CMDLINE"] = a
+ _lib_APPLY()
+ if (_basexit_fl) {
+ exit
+ }
+ _INIT()
+ _START()
+ _END()
+}
+
+#_____________________________________________________________________________
+END {
+ _EXIT()
+}
+
+#_______________________________________________________________________
+########################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+END {
+ if (_gawk_scriptlevel < 1) {
+ close(_errlog_file)
+ p = _Zimport(_rdfile(_errlog_file), _N())
+ if ((t = _get_errout(p)) != "") {
+ _expout(t, "/dev/stderr")
+ }
+ }
+}
+
+##########################################################################################
+# PUBLIC:
+#_____________________________________________________________________________
+# _rFBRO(ptr) - Return ptr of first-bro. [TESTED]
+# If !ptr then returns "".
+#_____________________________________________________________________________
+# _rLBRO(ptr) - Return ptr of last-bro. [TESTED]
+# If !ptr then returns "".
+#_____________________________________________________________________________
+# _rQBRO(ptr) - Returns brothers total quantity. [TESTED]
+# If !ptr then returns "".
+END {
+ if (_gawk_scriptlevel < 1) {
+ if (! _fileio_notdeltmpflag) {
+ _FILEIO_TMPATHS[_FILEIO_TMPRD]
+ _Foreach(_FILEIO_TMPATHS, "_uninit_del")
+ }
+ }
+}
+
+#___________________________________________________________________________________
+####################################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#___________________________________________________________________________________
+# fn _dirtree(array,pathmask)
+#
+# Return in `array' file tree from pathmask:
+# array["file.filerdne"]="size date time"
+# array["subdir.filerd"]["file.filerdne"]="size date time"
+# array["subdir.filerd"]["file.filerd"][...]
+#
+# The array will be cleared before any action. Function return pathmask w/o ltabspc and rtabspc.
+#___________________________________________________________________________________
+
+
+
+
+
+# OK: change internal function's names to: w\o "_"
+# OK: FLENGTH: should cover r-spcs
+# OK: optimize REXP
+# OK: add new symbols to dir/file names ( ! and + )
+# OK: create _getfilepath()
+# OK: del - conflict with WROOTDIR (do not update it)
+# OK: dir/del - support for filemask ( * and ? )
+# OK: how to define code injections: header\ender; and HANDLERS
+# OK: units in header\ender? conline division...
+# OK: _FILEPATH problem: it will not been defined at the moment when subscript0 starts - at the start TMPRD="_tmp"
+# OK: del: if del("dir\\") - then all ok except it NOT deleted "dir\\" - _del function removed(renamed to __del)
+# OK: tmpdirs: it delete only autotmp dir and only from script0
+# OK: MICROTEST: global testing of filepath (UNC! CORRECT RESULTS! )
+# question about cache: did new just now generated absolute filepath cached in FILECACHE? its seems like NO
+# check _untmp: CONFLICT: if file or dir from autotmp dir will be untmp then it anyway will be deleted; but file or dir from other point never be deleted anyway - so what is the point of untmp?????
+#ERRLOG: _setmpath: warning!!!!!
+
+#___________________________________________________________________________________
+####################################################################################
+# PUBLIC:
+#___________________________________________________________________________________
+#
+# fn _rdfile(_filepath)
+#
+# Read and return data from file specified in _filepath.
+# If _filepath=="" then no action occured and return "".
+# Function read and return data from file. No any changes in data occured.
+# Function use _filerdne function internally. If some syntax error
+# found in _filepath then function return "".
+# If some error occured while reading data from file then fuction return ""
+# and error-text is in ERRNO(and no close-file action will be occured!).
+# If reading data completed successfully then function try to close
+# file and if while closing file some error occured then function
+# returns "" and error-text is in ERRNO.
+# Otherwise function returns readed data.
+#_____________________________________________________________________________
+#
+# fn _wrfile(_filepath,_data)
+#
+# Write data into file specified in _filepath.
+# If _filepath=="" then no action occured and return "".
+# Function write _data to file. No any changes in data occured.
+# Function use _filerdne function internally. If some syntax error
+# found in _filepath then function return "".
+# If some error occured while writing data to file then fuction return ""
+# and error-text is in ERRNO(and no close-file action will be occured!).
+# If writing data completed successfully then function try to close
+# file and if while closing file some error occured then function
+# returns "" and error-text is in ERRNO.
+# Otherwise function returns _filepath(re-processed).
+#___________________________________________________________________________________
+#
+# fn _filepath(_filepath)
+#
+# Return re-processed root-dir-name-ext of _filepath.
+# If _filepath=="" then no action occured and return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+#_____________________________________________________________________________
+#
+# fn _filerdne(_filepath)
+#
+# Return re-processed root-dir-filename of _filepath.
+# If _filepath=="" then no action occured and return "".
+# Function return result only if in _filepath present file-name(name
+# and/or extension) - otherwise its return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+#_____________________________________________________________________________
+#
+# fn _filerdn(_filepath)
+#
+# Return re-processed root-dir-name of _filepath.
+# If _filepath=="" then no action occured and return "".
+# Function return result only if in _filepath present name field -
+# - otherwise its return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+#_____________________________________________________________________________
+#
+# fn _filerd(_filepath)
+#
+# Return re-processed root-dir of _filepath.
+# If _filepath=="" then no action occured and return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+#_____________________________________________________________________________
+#
+# fn _filer(_filepath)
+#
+# Return re-processed root of _filepath.
+# If _filepath=="" then no action occured and return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+#_____________________________________________________________________________
+#
+# fn _filed(_filepath)
+#
+# Return re-processed dir of _filepath.
+# If _filepath=="" then no action occured and return "".
+# There is only one case when dir string can be =="" - when in
+# _filepath specified unmounted drive(MS-format) and from-
+# current-location address used(like Z:file.ext). In this
+# case no rootdir-cache-record will be created.
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+#_____________________________________________________________________________
+# fn _filene(_filepath)
+#
+# Return re-processed name-ext of _filepath.
+# If _filepath=="" then no action occured and return "".
+# Function return result only if in _filepath present file-name(name
+# and/or extension) - otherwise its return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+#_____________________________________________________________________________
+#
+# fn _filen(_filepath)
+#
+# Return re-processed name of _filepath.
+# If _filepath=="" then no action occured and return "".
+# Function return result only if in _filepath present name field -
+# - otherwise its return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+#_____________________________________________________________________________
+#
+# fn _file(_filepath)
+#
+# Return re-processed ext of _filepath.
+# If _filepath=="" then no action occured and return "".
+# Function return result only if in _filepath present ext field -
+# - otherwise its return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+#___________________________________________________________________________________
+#
+# fn _dir(_ARR,_filepathmask)
+#
+# Get file-/folder-list of root-folder of _filepathmask.
+# If _filepathmask=="" then no action occured and return "".
+# _filepathmask can contain symbols like `*' and `?' as like
+# its used in `dir'-shell command.
+# Function gets file-/folder-list of specified root-dir-_filepathmask
+# and return this list in array _ARR - where each element:
+#
+# index - is the _filepath of file-or-folder name-ext
+# value - contains 3 fields separated by " ":
+# 1. =="D" if this is folder
+# ==/[0-9]+/ if this is file - size of file in bytes
+# 2. ==date-of-creation of file or folder
+# 3. ==time-of-creation of file or folder
+#
+# Function returns quantity of items in ARR.
+#___________________________________________________________________________________
+#
+# fn _filexist(_filepath)
+#
+# Test if file or path or drive specified in _filepath is exist.
+# If _filepath=="" then no action occured and return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+# Function returns _filepath if _filepath is exist. Otherwise
+# function return 0.
+#_____________________________________________________________________________
+#
+# fn _filenotexist(_filepath)
+#
+# Test if file or path or drive specified in _filepath is not exist.
+# If _filepath=="" then no action occured and return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+# Function returns 1 if _filepath is not exist. Otherwise function
+# return 0.
+#_____________________________________________________________________________
+#
+# fn _newdir(_filepath)
+#
+# Create path specified in root-dir-_filepath.
+# If _filepath=="" then no action occured and return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+# Function returns root-dir of _filepath.
+#_______________________________________________________________________
+#
+# fn _newdir(_filepath)
+#
+# Create path specified in root-dir-_filepath. If this folder
+# already exist then it will be completely cleared.
+# If _filepath=="" then no action occured and return "".
+# If some syntax error found in _filepath then function return ""
+# (and NO _filepath-cache-record will be created!).
+# Function returns root-dir of _filepath.
+#___________________________________________________________________________________
+#
+# fn _getmpfile(_filepath,_currfilepath)
+#
+# Return ....
+#
+#_____________________________________________________________________________
+#
+# fn _getmpdir(_filepath,_currfilepath)
+#
+# Return ...
+#
+#_____________________________________________________________________________
+#
+# Temporary files folder.
+#
+# Temporary files folder location is defined by _FILEIO_TMPRD.
+# If it wasn't been initialized before program run or not been initialized
+# by ENVIRON["TMPDIR"] then it will defined as the:
+# `current rootdir(stored in _FILEIO_RD)\programname.TMP'
+# In this case if its already exist then it will completely cleared when _FILEIO
+# library initialization processed.
+# And at the program uninitialization processed it will completely
+# cleared if _FILEIO_TMPCLRFLAG is true.
+#___________________________________________________________________________________
+#
+# var _FILEIO_RD (ENVIRON["CD"])
+#
+# This var can be set before running program. It can contain path which
+# will be used as default current dir while program run.
+# If this var is set before program runs - then it will be refreshed by the
+# _filerd it will be used as default current dir while program run.
+# If this var is not set before program runs - then ENVIRON["CD"] can also
+# set up default current dir while program run. If it set before program
+# begin then it will be refreshed by the _filerd - and also writed into
+# _FILEIO_RD.
+# If both _FILEIO_RD and ENVIRON["CD"] are not set before program begins
+# then real current root\dir will be writed into both _FILEIO_RD and
+# ENVIRON["CD"] and it will be used as default current dir while program run.
+#
+#___________________________________________________________________________________
+#
+# var _FILEIO_TMPRD (ENVIRON["TMPRD"])
+#
+# This var can be set before running program. It can contain path which
+# will be used as default temporary files root-folder while program run.
+# If this var is set before program runs - then it will be refreshed by the
+# _filerd - and also writed into ENVIRON["TMPRD"].
+# If this var is not set before program runs - then ENVIRON["TMPRD"] can also
+# set up default temporary files root-folder while program run. If it set
+# before program begin then it will be refreshed by the _filerd - and
+# also writed into _FILEIO_TMPRD.
+# If both _FILEIO_TMPRD and ENVIRON["TMPRD"] are not set before program begins
+# then new folder into path specified by the _FILEIO_RD(after its handling)
+# will be writed into both _FILEIO_TMPRD and ENVIRON["TMPRD"] and it
+# will be used as default temporary files root-folder while program run.
+#___________________________________________________________________________________
+#
+# var _FILEPATH
+#
+# This var contain filepath of working script. It should be setting up externally.
+#
+# var _gawk_scriptlevel
+#___________________________________________________________________________________
+####################################################################################
+END {
+ if (_constatstrln > 0) {
+ _constat()
+ }
+}
+
+#___________________________________________________________________________________
+####################################################################################
+
+
+
+
+
+
+
+# make sure that stdout contain only expected characters
+# make sure that stderr contain only expected characters
+# redesign & reformat keys and its outputs
+# try different key combinations
+# add lib-specified to all libs
+
+
+#_______________________________________________________________________
+function W(p, p0, p1)
+{
+ if (isarray(p0)) {
+ delete p0[p]
+ if (isarray(p1)) {
+ for (i in p1) {
+ if (isarray(p1[i])) {
+ p0[p][i][""]
+ delete p0[p][i][""]
+ _N_i0(p0[p][i], p1[i])
+ } else {
+ p0[p][i] = p1[i]
+ }
+ }
+ return p
+ }
+ return (p0[p] = p1)
+ }
+ delete _[p][p0]
+ if (isarray(p1)) {
+ for (i in p1) {
+ if (isarray(p1[i])) {
+ _[p][p0][i][""]
+ delete _[p][p0][i][""]
+ _N_i0(_[p][p0][i], p1[i])
+ } else {
+ _[p][p0][i] = p1[i]
+ }
+ }
+ return p
+ }
+ return (_[p][p0] = p1)
+}
+
+##########################################################
+function _ARR(c, t, P)
+{
+ switch (c) {
+ case "_lib_CMDLN":
+ return t
+ #___________________________________________________________
+
+ case "_lib_APPLY":
+ return
+ #___________________________________________________________
+
+ case "_lib_HELP":
+ return
+ #___________________________________________________________
+
+ case "_lib_NAMEVER":
+ return _ln("_ARR 1.0")
+ #___________________________________________________________
+
+ case "_lib_BEGIN":
+ return
+ #___________________________________________________________
+
+ case "_lib_END":
+ return
+ }
+}
+
+##########################################################
+function _BASE(c, t, P, A)
+{
+ switch (c) {
+ case "_lib_CMDLN":
+ if (match(t, /^((--([Vv])ersion)|(-([Vv])))[ \t]*/, A)) {
+ t = substr(t, RLENGTH + 1)
+ _cmdln_version = A[3] A[5]
+ } else {
+ if (match(t, /^((-?\?)|(--help))[ \t]*/)) {
+ t = substr(t, RLENGTH + 1)
+ _cmdln_help = 1
+ } else {
+ if (match(t, /^--[ \t]*/)) {
+ return _endpass(substr(t, RLENGTH + 1))
+ }
+ }
+ }
+ return t
+ #___________________________________________________________
+
+ case "_lib_APPLY":
+ if (_cmdln_help) {
+ match(_fbaccr(_LIBAPI, "_lib_HELP"), /^([^\x00]*)\x00([^\x01]*)\x01(.*)/, A)
+ _out(A[2] A[1] A[3])
+ return _endpass(_basexit_fl = 1)
+ }
+ if (_cmdln_version) {
+ _out(_ln(_PRODUCT_NAME " v" _PRODUCT_VERSION) _ln(_PRODUCT_COPYRIGHT) _ln() ((_cmdln_version == "v" ? "" : _lib_NAMEVER())))
+ return _endpass(_basexit_fl = 1)
+ }
+ return
+ #___________________________________________________________
+
+ case "_lib_HELP":
+ return ("\000" _ln(_PRODUCT_NAME " v" _PRODUCT_VERSION) _ln(_PRODUCT_COPYRIGHT) _ln() _ln(" Usage:") _ln() _ln(" " _PRODUCT_FILENAME " [/key1 /key2...] [-- cmdline]") _ln() _ln(" keys:") _ln() "\001" _ln(" -v -V --version - output product version and (if /V) all modules") _ln(" ? -? --help - output this help page") _ln(" -- - command line string edge"))
+ #___________________________________________________________
+
+ case "_lib_NAMEVER":
+ return _ln("_BASE 3.0")
+ #___________________________________________________________
+
+ case "_lib_BEGIN":
+ return
+ #___________________________________________________________
+
+ case "_lib_END":
+ return
+ }
+}
+
+#____________________________________________________________________________
+function _DS(c, t, P, a, A)
+{
+ switch (c) {
+ case "_lib_CMDLN":
+ #___________________________________________________________
+ return t
+ #_____________________________________________________
+ case "_lib_APPLY":
+ return
+ #_____________________________________________________
+ case "_lib_HELP":
+ return (_ln() _ln(" Usage: " _PRODUCT_NAME " [/key1 /key2...] sourcefile [cmdline]") _ln())
+ #_____________________________________________________
+ case "_lib_NAMEVER":
+ return
+ #_____________________________________________________
+ case "_lib_BEGIN":
+ return
+ #_____________________________________________________
+ case "_lib_END":
+ return
+ }
+}
+
+#______________________________________________________________________________________________
+function _END()
+{
+}
+
+########################################################
+function _ERRLOG(c, t, P, a, b, A)
+{
+ switch (c) {
+ case "_lib_CMDLN":
+ if (match(t, /^[ \t]*-L:([TtVvIiWwEeFf]*)[ \t]*/, A)) {
+ t = substr(t, RLENGTH + 1)
+ _errlog_errflkey = _errlog_errflkey A[1]
+ }
+ return t
+ #_______________________________________________________________________
+
+ case "_lib_APPLY":
+ if (_errlog_errflkey) {
+ split(_errlog_errflkey, A, "")
+ for (a = 1; a in A; a++) {
+ if (A[a] == toupper(A[a])) {
+ b = 1
+ } else {
+ b = ""
+ }
+ switch (toupper(A[a])) {
+ case "T":
+ _ERRLOG_TF = b
+ break
+ case "V":
+ _ERRLOG_VF = b
+ break
+ case "I":
+ _ERRLOG_IF = b
+ break
+ case "W":
+ _ERRLOG_WF = b
+ break
+ case "E":
+ _ERRLOG_EF = b
+ break
+ case "F":
+ _ERRLOG_FF = b
+ break
+ }
+ }
+ if (_ERRLOG_IF) {
+ _info("Log-message types inherited acc/deny: " "TRACE " ((_ERRLOG_TF ? "ON" : "OFF")) "/" "VERBOSE " ((_ERRLOG_VF ? "ON" : "OFF")) "/" "INFO " ((_ERRLOG_IF ? "ON" : "OFF")) "/" "WARNING " ((_ERRLOG_WF ? "ON" : "OFF")) "/" "ERROR " ((_ERRLOG_EF ? "ON" : "OFF")) "/" "FATAL " ((_ERRLOG_FF ? "ON" : "OFF")))
+ }
+ }
+ return
+ #_______________________________________________________________________
+
+ case "_lib_HELP":
+ return (_ln(" -L:TtVvIiWwEeFf - enable(upcase: TVIWEF) or disable(lowcase: tviwef) allowable type of") _ln(" log messages. Trace/Verbose/Informational/Warning/Error/Fatal.") _ln())
+ #_______________________________________________________________________
+
+ case "_lib_NAMEVER":
+ return _ln("_ERRLOG 1.0")
+ #_______________________________________________________________________
+
+ case "_lib_BEGIN":
+ P["_ERRLOG_TF"] = _ERRLOG_TF
+ P["_ERRLOG_VF"] = _ERRLOG_VF
+ P["_ERRLOG_IF"] = _ERRLOG_IF
+ P["_ERRLOG_WF"] = _ERRLOG_WF
+ P["_ERRLOG_EF"] = _ERRLOG_EF
+ P["_ERRLOG_FF"] = _ERRLOG_FF
+ P["_errlog_file"] = "/dev/stderr"
+ return
+ }
+}
+
+#______________________________________________________________________________________________
+function _EXIT()
+{
+}
+
+########################################################
+function _EXTFN(c, t, P)
+{
+ switch (c) {
+ case "_lib_CMDLN":
+ return t
+ #___________________________________________________________
+
+ case "_lib_APPLY":
+ return
+ #___________________________________________________________
+
+ case "_lib_HELP":
+ return
+ #___________________________________________________________
+
+ case "_lib_NAMEVER":
+ return _ln("_EXTFN 1.0")
+ #___________________________________________________________
+
+ case "_lib_BEGIN":
+ return
+ #___________________________________________________________
+
+ case "_lib_END":
+ return
+ }
+}
+
+#######################################################
+function _FILEIO(c, t, P, A)
+{
+ switch (c) {
+ case "_lib_CMDLN":
+ if (match(t, /^[ \t]*-[Tt]([\+-])[ \t]*/, A)) {
+ t = substr(t, RLENGTH + 1)
+ if (A[1] == "+") {
+ _fileio_notdeltmpflag = 1
+ } else {
+ _fileio_notdeltmpflag = ""
+ }
+ }
+ return t
+ #___________________________________________________________
+
+ case "_lib_APPLY":
+ if (_fileio_notdeltmpflag) {
+ _info("Temporary objects deletion DISABLED (inherited)")
+ }
+ return
+ #___________________________________________________________
+
+ case "_lib_HELP":
+ return (_ln(" -[Tt][+-] - inherited: +enable\\-disable temporary files\\dirs deletion") _ln())
+ #___________________________________________________________
+
+ case "_lib_NAMEVER":
+ return _ln("_FILEIO 2.1")
+ #___________________________________________________________
+
+ case "_lib_BEGIN":
+ P["ENVIRON"]["CD"] = ENVIRON["CD"]
+ P["_FILEIO_RD"] = _FILEIO_RD
+ P["_FILEIO_R"] = _FILEIO_R
+ P["_FILEIO_D"] = _FILEIO_D
+ if (! ("_FILEIO_TMPRD" in P)) {
+ P["_FILEIO_TMPRD"] = _getmpdir(_filen(P["SOURCE"]) "." ++_egawk_subcntr _CHR["SUBDIR"])
+ }
+ return
+ #___________________________________________________________
+
+ case "_lib_END":
+ return
+ }
+}
+
+#_____________________________________________________________________________
+function _FILEVER(c, t, P, a, A)
+{
+ switch (c) {
+ case "_lib_CMDLN":
+ #___________________________________________________________
+ return t
+ #_____________________________________________________
+ case "_lib_APPLY":
+ return
+ #_____________________________________________________
+ case "_lib_HELP":
+ return
+ #_____________________________________________________
+ case "_lib_NAMEVER":
+ return
+ #_____________________________________________________
+ case "_lib_BEGIN":
+ return
+ #_____________________________________________________
+ case "_lib_END":
+ return
+ }
+}
+
+function _Foreach(A, f, p0, i)
+{
+ for (i in A) {
+ @f(A, i, p0)
+ }
+}
+
+function _INIT(f)
+{
+}
+
+#___________________________________________________________________________________
+function _INITBASE()
+{
+ _egawk_utilpath = ENVIRON["EGAWK_PATH"] "BIN\\UTIL\\"
+}
+
+######################################################
+function _INSTRUC(c, t, P)
+{
+ switch (c) {
+ case "_lib_CMDLN":
+ return t
+ #___________________________________________________________
+
+ case "_lib_APPLY":
+ return
+ #___________________________________________________________
+
+ case "_lib_HELP":
+ return
+ #___________________________________________________________
+
+ case "_lib_NAMEVER":
+ return _ln("_INSTRUC 1.0")
+ #___________________________________________________________
+
+ case "_lib_BEGIN":
+ return
+ #___________________________________________________________
+
+ case "_lib_END":
+ return
+ }
+}
+
+#___________________________________________________________________________________
+
+
+####################################################################################
+
+
+#_____________________________________________________________________________
+function _N(F, v, p)
+{
+ for (p in _UIDS) {
+ delete _UIDS[p]
+ return _nN_i0(p, F, v)
+ }
+ return _nN_i0(_tgenuid(), F, v)
+}
+
+#####################################################
+function _SHORTCUT(c, t, P)
+{
+ switch (c) {
+ case "_lib_CMDLN":
+ return t
+ #___________________________________________________________
+
+ case "_lib_APPLY":
+ return
+ #___________________________________________________________
+
+ case "_lib_HELP":
+ return
+ #___________________________________________________________
+
+ case "_lib_NAMEVER":
+ return _ln("_shortcut 1.0")
+ #___________________________________________________________
+
+ case "_lib_BEGIN":
+ return
+ #___________________________________________________________
+
+ case "_lib_END":
+ return
+ }
+}
+
+#______________________________________________________________________________________________
+function _START(t, i, A)
+{
+ _torexp_init()
+ test_uid()
+ return
+ _conl(patsplit("a,b,c", A, /[^,]/, B))
+ test_splitstr()
+ return
+ A[""]
+ _CLASSPTR["ptr"]
+ ALTARR["ptra"]
+ _conl(_dumparr(SYMTAB))
+ BB[1] = _NOP
+ zorr(1, 2, 3, 4, 5, 6)
+ zorr(BB, 1)
+ _rtn()
+ _rtn("")
+ _rtn(0)
+ _rtn("0")
+ _rtn(1)
+ _rtn("1")
+ _rtn(-1)
+ _rtn("-1")
+ _rtn("huj")
+ _rtn("ptr")
+ _rtn("ptra", ALTARR)
+ _rtn(ALTARR)
+ _rtn(ALTARR, ALTARR)
+ return
+ _tstini()
+ return
+ _splitpath_test()
+ # _split_regpath()
+ return
+ hh = "CPU"
+ _conl("go1!")
+ _conl(_var(_sharepath(hh, "gdfsgdsgsd sdgsdighjui teretiewrotrewut 345345345 rtjtireutireu huj")))
+ _conl("go2!")
+ _conl(_var(_sharelist(AAA, hh), _dumparr(AAA)))
+ _conline()
+ A[1] = "h"
+ A[3] = "j"
+ t = "pizda"
+ if (match(t, /^pi(Z)da/, A)) {
+ _conl("match")
+ } else {
+ _conl("not match")
+ }
+ _conl(_dumparr(A))
+ return
+ _pathSMA = "C:\\Program Files\\Altiris\\Altiris Agent\\"
+ DSPlugInPath = _pathSMA "Agents\\Deployment\\Agent\\"
+ DSAutoPath = _pathSMA
+ if (! _sysinfo(_SYS, _hostname)) {
+ _fatal("_sysinfo: unknown error")
+ }
+ _REG[""]
+ delete _REG[""]
+ _servoutput = _CHR["EOL"] _cmd("sc query state= all")
+ _dsbasepath = "\\\\CPU\\CPU\\DEV\\PROJECT\\_DS\\"
+ _rdreg(_REG, "HKEY_LOCAL_MACHINE\\SOFTWARE\\Altiris")
+ _wrfile("rego.txt", _dumparr(_REG))
+ _conl("fF")
+ #_______________________________________________________________________
+
+ c = _getreg_i1(DDD, "HKEY_LOCAL_MACHINE\\SOFTWARE\\Altiris\\Altiris Agent\\Plugin Objects\\\204~.*\224Install path", _REG)
+ #_________________________________________________________________________________________
+ pp = _n("NAME", "NS")
+ #pp=_n()
+ #___________________________________________________________________________________
+ p = _defsolution(pp, "DS Plug-in", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Altiris\\Altiris Agent\\Plugin Objects\\Agents\\")
+ ClientConfiguration = _defdll(p, "Client Configuration", "ClientConfiguration")
+ ClientImagingPrep = _defdll(p, "Client Inaging Preparation", "ClientImagingPrep")
+ ClientImaging = _defdll(p, "Client Imaging", "ClientImaging")
+ ClientPCT = _defdll(p, "Client PCT", "ClientPCT")
+ ClientRebootTo = _defdll(p, "Client Reboot To", "ClientRebootTo")
+ DeploymentAgent = _defdll(p, "Deployment Agent", "Deployment Agent")
+ DeploymentSolutionBaseAgent = _defdll(p, "Deployment Solution Base Agent", "Deployment Solution Base Agent")
+ ClientBCDEdit = _defile(p, "Client BCD Edit", "ClientBCDEdit.dll")
+ ClientCopyFile = _defile(p, "Client Copy File", "ClientCopyFile.dll")
+ ClientPreImage = _defile(p, "Client Pre Image", "ClientPreImage.dll")
+ ClientRebootTo = _defile(p, "Client Reboot To", "ClientRebootTo.dll")
+ _defile(p, "ConfigService.exe", "ConfigService.exe", "")
+ _defile(p, "config.dll", "config.dll", "")
+ _defsrv(p, "DS Plug-in Service", "Altiris Deployment Solution - System Configuration")
+ _defreg(p, "Deployment Agent Path", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Altiris\\Deployment\\AgentInstallPath.STR")
+ _defile(p, "Altiris_DeploymentSolutionAgent_7_1_x86.msi", (_SYS["OSArchitecture"] == "64-bit" ? "C:\\Program Files\\Altiris\\Altiris Agent\\Agents\\SoftwareManagement\\Software Delivery\\{9D76E4CA-377A-472D-A82E-EDAD77E7E4ED}\\cache\\Altiris_DeploymentSolutionAgent_7_1_x64.msi" : "C:\\Program Files\\Altiris\\Altiris Agent\\Agents\\SoftwareManagement\\Software Delivery\\{4B747D25-612F-48FC-B6B5-9916D1BB755C}\\cache\\Altiris_DeploymentSolutionAgent_7_1_x86.msi"), "")
+ _defdir(p, "Deployment Folder", a = gensub(/[^\\]*$/, "", 1, _rdsafe(_REG, "HKEY_LOCAL_MACHINE\\SOFTWARE\\Altiris\\Deployment\\AgentInstallPath.STR", "C:\\Program Files\\Altiris\\Altiris Agent\\Agents\\Deployment\\Agent\\")))
+ #___________________________________________________________________________________
+ p = _defsolution(pp, "DS Auto", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Altiris\\Altiris Agent\\Plugin Objects\\Agents\\")
+ _defdir(p, "C:\\Boot\\Altiris\\iso\\boot\\fonts\\", "C:\\Boot\\Altiris\\iso\\boot\\fonts\\")
+ _defdir(p, "C:\\Boot\\Altiris\\iso\\sources\\", "C:\\Boot\\Altiris\\iso\\sources\\")
+ _defile(p, "C:\\Boot\\Altiris\\iso\\autoinst.exe", "C:\\Boot\\Altiris\\iso\\autoinst.exe", "")
+ _defile(p, "C:\\Boot\\Altiris\\iso\\autoinst.ini", "C:\\Boot\\Altiris\\iso\\autoinst.ini", "")
+ _defile(p, "C:\\Boot\\Altiris\\iso\\autoutil.exe", "C:\\Boot\\Altiris\\iso\\autoutil.exe", "")
+ _defile(p, "C:\\Boot\\Altiris\\iso\\autoutil.ini", "C:\\Boot\\Altiris\\iso\\autoutil.ini", "")
+ _defile(p, "C:\\Boot\\Altiris\\iso\\bcdedit.exe", "C:\\Boot\\Altiris\\iso\\bcdedit.exe", "")
+ _defile(p, "C:\\Boot\\Altiris\\iso\\bootmgr", "C:\\Boot\\Altiris\\iso\\bootmgr", "")
+ _defile(p, "C:\\Boot\\Altiris\\iso\\bootsect.exe", "C:\\Boot\\Altiris\\iso\\bootsect.exe", "")
+ _defreg(p, "Deployment Automation reg.File", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Altiris\\AutoUtil\\File.XSZ", "autoutil.exe")
+ _defreg(p, "Deployment Automation reg.Path", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Altiris\\AutoUtil\\Path.XSZ", "%systemdrive%\\boot\\altiris\\iso")
+ #_________________________________________________________________________________________
+
+ _check(pp)
+ #_________________________________________________________________________________________
+
+ _conl(_report(pp))
+ _wrfile("report.txt", _report(pp))
+}
+
+#########################################################
+function _SYSIO(c, t, P)
+{
+ switch (c) {
+ case "_lib_CMDLN":
+ return t
+ #___________________________________________________________
+
+ case "_lib_APPLY":
+ return
+ #___________________________________________________________
+
+ case "_lib_HELP":
+ return
+ #___________________________________________________________
+
+ case "_lib_NAMEVER":
+ return _ln("_SYSIO 1.0")
+ #___________________________________________________________
+
+ case "_lib_BEGIN":
+ return
+ #___________________________________________________________
+
+ case "_lib_END":
+ return
+ }
+}
+
+#_______________________________________________________________________
+########################################################################
+
+
+function _W(p, A, v)
+{
+ if (isarray(v)) {
+ if (p) {
+ delete A[p]
+ A[p][""]
+ delete A[p][""]
+ _movarr(A[p], v)
+ }
+ return p
+ }
+ if (p) {
+ delete A[p]
+ return (A[p] = v)
+ }
+ return v
+}
+
+#_______________________________________________________________________
+function _Zexparr(S, s, t, i)
+{
+ t = ""
+ if (isarray(S)) {
+ for (i in S) {
+ t = t ((isarray(S[i]) ? _Zexparr_i1(i) "\020" _Zexparr_i0(S[i]) "\021\021\020" : _Zexparr_i2(_Zexparr_i3(i) "\021" _Zexparr_i3(S[i])) "\020"))
+ }
+ }
+ if (s != "") {
+ gsub(/\x1B/, "\033;", s)
+ gsub(/\x10/, "\0330", s)
+ t = t "\021\021\020" s
+ }
+ gsub(/\x0A/, "\033:", t)
+ return t
+}
+
+#_________________________________________________________________
+function _Zexparr_i0(S, t, i)
+{
+ for (i in S) {
+ t = t ((isarray(S[i]) ? _Zexparr_i1(i) "\020" _Zexparr_i0(S[i]) "\021\021\020" : _Zexparr_i2(_Zexparr_i3(i) "\021" _Zexparr_i3(S[i])) "\020"))
+ }
+ return t
+}
+
+#_________________________________________________________________
+function _Zexparr_i1(t)
+{
+ gsub(/\x1B/, "\033;", t)
+ gsub(/\x11/, "\0331", t)
+ gsub(/\x10/, "\0330", t)
+ return t
+}
+
+#_________________________________________________________________
+function _Zexparr_i2(t)
+{
+ gsub(/\x10/, "\0330", t)
+ return t
+}
+
+#_________________________________________________________________
+function _Zexparr_i3(t)
+{
+ gsub(/\x1B/, "\033;", t)
+ gsub(/\x11/, "\0331", t)
+ return t
+}
+
+#_______________________________________________________________________
+function _Zimparr(D, t, A, B)
+{
+ if (isarray(D)) {
+ split(t, A, /\x10/, B)
+ t = _Zimparr_i0(A, B, _Zimparr_i1(D, A, B, 1))
+ gsub(/\x1B\x30/, "\020", t)
+ gsub(/\x1B\x3B/, "\033", t)
+ return t
+ }
+}
+
+#_________________________________________________________________
+function _Zimparr_i0(A, B, i)
+{
+ return ((i in A ? A[i] B[i] _Zimparr_i0(A, B, i + 1) : ""))
+}
+
+#_________________________________________________________________
+function _Zimparr_i1(D, A, B, i, t, a, n)
+{
+ while (i in B) {
+ if ((t = A[i++]) == "\021\021") {
+ return i
+ }
+ gsub(/\x1B\x30/, "\020", t)
+ if ((a = index(t, "\021")) > 0) {
+ if (isarray(D[n = _Zimparr_i2(substr(t, 1, a - 1))])) {
+ delete D[n]
+ }
+ D[n] = _Zimparr_i2(substr(t, a + 1))
+ } else {
+ if (! isarray(D[t = _Zimparr_i2(t)])) {
+ delete D[t]
+ D[t][""]
+ delete D[t][""]
+ }
+ i = _Zimparr_i1(D[t], A, B, i)
+ }
+ }
+}
+
+#_________________________________________________________________
+function _Zimparr_i2(t)
+{
+ gsub(/\x1B\x31/, "\021", t)
+ gsub(/\x1B\x3B/, "\033", t)
+ return t
+}
+
+#_____________________________________________________________________________
+function _Zimport(t, p, A, c, i, n, B)
+{
+ if (p) {
+ c = split(t, B, /\x0A/)
+ for (i = 1; i <= c; i++) {
+ if ((t = B[i]) == "") {
+ continue
+ }
+ gsub(/\x1B\x3A/, "\n", t)
+ if (match(t, /^_ERRLOG: /)) {
+ _tLOG[n = _wLCHLD(p, _N())][""]
+ delete _tLOG[n][""]
+ _Zimparr(_tLOG[n], substr(t, 10))
+ } else {
+ if ((t = _pass(_IMPORT, t, p, A)) != "") {
+ gsub(/\x1B\x3B/, "\033", t)
+ _wLCHLD(p, _N(_tSTR, t))
+ }
+ }
+ }
+ return p
+ } else {
+ _expout(t)
+ }
+}
+
+function _acc(A, a, t)
+{
+ if (t) {
+ if (_VLDMAXSTRING < length(t) + length(a)) {
+ if (a) {
+ if (_VLDMAXSTRING < length(t)) {
+ A[--A[_ARRPTR]] = a
+ A[--A[_ARRPTR]] = t
+ } else {
+ A[--A[_ARRPTR]] = a t
+ }
+ } else {
+ A[++A[_ARRLEN]] = t
+ }
+ return ""
+ }
+ return (a t)
+ }
+ return a
+}
+
+function _accmpu(A, a, n)
+{
+ if (n) {
+ return (_mpufn0 = n)
+ }
+ if (_mpuacc) {
+ if (_VLDMAXSTRING < length(_mpuacc) + length(a)) {
+ if (a) {
+ if (_VLDMAXSTRING < length(_mpuacc)) {
+ A[--A[_ARRLEN]] = a
+ A[--A[_ARRLEN]] = _mpuacc
+ } else {
+ A[--A[_ARRLEN]] = a _mpuacc
+ }
+ } else {
+ A[--A[_ARRLEN]] = _mpuacc
+ }
+ _mpuacc = ""
+ } else {
+ _mpuacc = a _mpuacc
+ }
+ } else {
+ _mpuacc = a
+ }
+}
+
+#_______________________________________________________________________
+function _add(S, sf, D, df)
+{
+ if (sf in S) {
+ if (isarray(S[sf])) {
+ if (df in D) {
+ if (isarray(D[df])) {
+ return _extarr(D[df], S[sf])
+ }
+ delete D[df]
+ }
+ D[df][""]
+ delete D[df][""]
+ return _extarr(D[df], S[sf])
+ } else {
+ if (isarray(D[df])) {
+ delete D[df]
+ }
+ D[df] = D[df] S[sf]
+ }
+ }
+}
+
+#_________________________________________________________________
+function _addarr(D, S)
+{
+ if (isarray(S)) {
+ _addarr_i0(D, S)
+ }
+}
+
+#_____________________________________________________
+function _addarr_i0(D, S, i)
+{
+ for (i in S) {
+ if (isarray(S[i])) {
+ delete D[i]
+ D[i][""]
+ delete D[i][""]
+ _addarr_i0(D[i], S[i])
+ } else {
+ delete D[i]
+ D[i] = S[i]
+ }
+ }
+}
+
+#_______________________________________________________________________
+function _addarrmask(D, S, M)
+{
+ for (_addarrmaski0 in M) {
+ if (_addarrmaski0 in S) {
+ if (isarray(S[_addarrmaski0])) {
+ if (! isarray(D[_addarrmaski0])) {
+ delete D[_addarrmaski0]
+ D[_addarrmaski0][""]
+ delete D[_addarrmaski0][""]
+ }
+ if (isarray(M[_addarrmaski0])) {
+ _addarrmask(D[_addarrmaski0], S[_addarrmaski0], M[_addarrmaski0])
+ } else {
+ _extarr_i0(D[_addarrmaski0], S[_addarrmaski0])
+ }
+ } else {
+ if (isarray(D[_addarrmaski0])) {
+ delete D[_addarrmaski0]
+ }
+ D[_addarrmaski0] = S[_addarrmaski0]
+ }
+ } else {
+ delete D[_addarrmaski0]
+ }
+ }
+}
+
+#___________________________________________________________________________________
+####################################################################################
+
+
+#_______________________________________________________________________
+function _addf(A, f)
+{
+ A["B"][""] = A["F"][A["B"][f] = A["B"][""]] = f
+}
+
+#___________________________________________________________
+function _addfile(f, d, a, b)
+{
+ if ((f = _wfilerdnehnd(f)) == "" || _filene(f) == "") {
+ ERRNO = "Filename error"
+ return
+ }
+ a = BINMODE
+ BINMODE = "rw"
+ b = ORS
+ ORS = ""
+ ERRNO = ""
+ print(d) >> f
+ if (ERRNO) {
+ return ""
+ }
+ close(f)
+ BINMODE = a
+ ORS = b
+ if (ERRNO) {
+ return ""
+ }
+ return d
+}
+
+#_____________________________________________________________________________
+function _addlib(f)
+{
+ _addf(_LIBAPI, f)
+}
+
+#___________________________________________________________________________________
+####################################################################################
+
+
+#_______________________________________________________________________
+function _addlist(A, v)
+{
+ A[++A[0]] = v
+}
+
+#_______________________________________________________________________
+function _bearray(A)
+{
+ if (isarray(A) || A == 0 && A == "") {
+ return 1
+ }
+}
+
+#_________________________________________________________________
+function _bframe(A, t, p)
+{
+ return _bframe_i0(A, t, p, A[""])
+}
+
+#___________________________________________________________
+function _bframe_i0(A, t, p, f)
+{
+ return ((f ? _bframe_i0(A, t, p, A[f]) (@f(t, p)) : ""))
+}
+
+# add to _dumparr: checking that if element is undefined
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#_______________________________________________________________________
+function _cfguid(p, optr, pfx, sfx, hstrcnt, lstrchr)
+{
+ delete _UIDOBL[p]
+ if (_isptr(optr)) {
+ if (optr == p) {
+ delete _UIDOBLV[p]
+ delete _UIDOBLV[_UIDOBLV[_UIDOBL[p] = p][""] = p][""]
+ } else {
+ if (optr in _UIDOBL) {
+ _UIDOBL[p] = _UIDOBL[optr]
+ }
+ }
+ }
+ _UIDPFX[p] = (_istr(pfx) ? pfx : "")
+ _UIDSFX[p] = (_istr(sfx) ? sfx : "")
+ if (_isptr(hstrcnt)) {
+ if (hstrcnt != p) {
+ _UIDCHR[p] = _UIDCHR[_UIDCNT[p] = _UIDCNT[hstrcnt]]
+ return p
+ }
+ hstrcnt = _NOP
+ }
+ _UIDCNTL[_UIDCNT[p] = p] = _cfguidchr(p, hstrcnt, lstrchr)
+ return p
+}
+
+#_____________________________________________________
+function _cfguidchr(p, h, l, H, L)
+{
+ if (_isptr(l)) {
+ if (l != p) {
+ return (_UIDCHR[p] = _UIDCHR[l])
+ }
+ _UIDCHR[p] = p
+ l = _NOP
+ }
+ _UIDCHR[p] = p
+ _splitstr(H, h, _UIDCHRH[_classys])
+ _splitstr(L, l, H)
+ delete _UIDCHRH[_UIDCHRH[p][""] = p][""]
+ delete _UIDCHRL[_UIDCHRL[p][""] = p][""]
+ _cfguidh(p, H, L)
+ return _cfguidl(p, L, L)
+}
+
+#_______________________________________________
+function _cfguidh(p, H, L, hi, h, li)
+{
+ for (hi = 1; hi in H; hi++) {
+ h = H[hi]
+ for (li = 1; li in L; li++) {
+ _UIDCHRH[p][h L[li]]
+ }
+ }
+}
+
+function _cfguidl(p, H, L, hi, h, hl, li)
+{
+ for (hi = 1; hi in H; hi++) {
+ h = H[hi]
+ for (li = 1; li in L; li++) {
+ hl = _UIDCHRL[p][hl] = h L[li]
+ }
+ }
+ return hl
+}
+
+#____________________________________________________________________________________________________
+function _check(p)
+{
+ _dll_check(p)
+ _file_check(p)
+ _serv_check(p)
+ _reg_check(p)
+}
+
+#_______________________________________________________________________
+function _chrline(t, ts, w, s)
+{
+ return ((t = " " _tabtospc(t, ts) ((t ? (t ~ /[ \t]$/ ? "" : " ") : ""))) _getchrln((s ? s : "_"), ((w ? w : _CON_WIDTH - 1)) - length(t)) _CHR["EOL"])
+}
+
+#_____________________________________________________________________________
+function _cmd(c, i, A)
+{
+ _fio_cmda = RS
+ RS = ".{1,}"
+ _fio_cmdb = BINMODE
+ BINMODE = "rw"
+ ERRNO = RT = _NUL
+ c | getline RS
+ BINMODE = _fio_cmdb
+ RS = _fio_cmda
+ if (ERRNO || 0 > (_exitcode = close(c))) {
+ return (RT = _NOP)
+ }
+ return RT
+}
+
+#_______________________________________________________________________
+function _cmparr(A0, A1, R, a, i)
+{
+ a = 0
+ delete R
+ for (i in A0) {
+ if (! (i in A1)) {
+ a++
+ R[i] = 0
+ } else {
+ if (A0[i] != A1[i]) {
+ a++
+ R[i] = 2
+ }
+ }
+ }
+ for (i in A1) {
+ if (! (i in A0)) {
+ a++
+ R[i] = 1
+ }
+ }
+ return a
+}
+
+#_____________________________________________________________________________
+function _con(t, ts, a, b, c, d, i, r, A, B)
+{
+ d = RLENGTH
+ if ((c = split(r = t, A, /\x0D?\x0A/, B)) > 0) {
+ a = BINMODE
+ b = ORS
+ BINMODE = "rw"
+ ORS = ""
+ if (c > 1) {
+ if ((i = length(t = _tabtospc(A[1], ts, _conlastrln))) < _constatstrln) {
+ t = t _getchrln(" ", _constatstrln - i)
+ }
+ print(t B[1]) > _SYS_STDCON
+ for (i = 2; i < c; i++) {
+ print(_tabtospc(A[i], ts) B[i]) > _SYS_STDCON
+ }
+ print(_conlastr = _tabtospc(A[c], ts)) > _SYS_STDCON
+ fflush(_SYS_STDCON)
+ } else {
+ print(t = _tabtospc(t, ts, _conlastrln)) > _SYS_STDCON
+ fflush(_SYS_STDCON)
+ _conlastr = _conlastr t
+ }
+ if ((i = length(_conlastr)) >= _CON_WIDTH) {
+ _conlastr = substr(_conlastr, 1 + int(i / _CON_WIDTH) * _CON_WIDTH)
+ }
+ _conlastrln = length(_conlastr)
+ if (_constatstr) {
+ print((t = _constatgtstr(_constatstr, _CON_WIDTH - 1 - _conlastrln)) _CHR["CR"] _conlastr) > _SYS_STDCON
+ fflush(_SYS_STDCON)
+ _constatstrln = length(t)
+ }
+ BINMODE = a
+ ORS = b
+ RLENGTH = d
+ return r
+ }
+ RLENGTH = d
+}
+
+#_______________________________________________________________________
+function _conin(t, a, b)
+{
+ _constatpush()
+ _constat()
+ a = BINMODE
+ b = RS
+ BINMODE = "rw"
+ RS = "\n"
+ _con(t)
+ getline t < "CON"
+ close("CON")
+ _conlastrln = 0
+ _conlastr = ""
+ gsub(/[\x0D\x0A]+/, "", t)
+ BINMODE = a
+ RS = b
+ _constatpop()
+ return t
+}
+
+#_______________________________________________________________________
+function _conl(t, ts)
+{
+ return _con(t ((t ~ /\x0A$/ ? "" : _CHR["EOL"])), ts)
+}
+
+#_______________________________________________________________________
+function _conline(t, ts)
+{
+ return _con(_chrline(t, ts))
+}
+
+#___________________________________________________________________________________
+####################################################################################
+
+
+
+function _conlq(t, ts)
+{
+ return _conl("`" t "'", ts)
+}
+
+#_______________________________________________________________________
+function _constat(t, ts, ln, a)
+{
+ if (_constatstrln > (ln = length(t = _constatgtstr(_constatstr = _tabtospc(t, ts), _CON_WIDTH - 1 - _conlastrln)))) {
+ t = t _getchrln(" ", _constatstrln - ln)
+ }
+ _constatstrln = ln
+ ln = ORS
+ a = BINMODE
+ BINMODE = "rw"
+ ORS = ""
+ print(t _CHR["CR"] _conlastr) > _SYS_STDCON
+ fflush(_SYS_STDCON)
+ ORS = ln
+ BINMODE = a
+ return _constatstr
+}
+
+#_________________________________________________________________
+function _constatgtstr(t, ln, a, b)
+{
+ if (ln < 1) {
+ return ""
+ }
+ if ((a = length(t)) <= ln) {
+ return t
+ }
+ if (ln < 11) {
+ return substr(t, a - ln + 1)
+ }
+ if (ln < 19) {
+ return ("..." substr(t, a - ln + 4))
+ }
+ return (substr(t, 1, b = int((ln - 3) / 2)) "..." substr(t, a - ln + b + 4))
+}
+
+#_______________________________________________________________________
+function _constatpop()
+{
+ if (_CONSTATPUSH[0] > 0) {
+ return _constat(_CONSTATPUSH[_CONSTATPUSH[0]--])
+ }
+ return _constat("")
+}
+
+#_______________________________________________________________________
+function _constatpush(t, ts)
+{
+ _CONSTATPUSH[++_CONSTATPUSH[0]] = _constatstr
+ if (t) {
+ _constat(t, ts)
+ }
+ return _constatstr
+}
+
+#___________________________________________________________________________________
+function _creport(p, t, f, z)
+{
+ _[p]["REPORT"] = _[p]["REPORT"] _ln(t ((f == "" ? "" : ": " f)))
+}
+
+#_________________________________________________________________________________________
+function _defdir(pp, n, f, v, p)
+{
+ _[p = _wLCHLD(pp, _n("TYPE", "defdir"))]["NAME"] = n
+ _[p]["DIR"] = f
+ return p
+}
+
+#_________________________________________________________________________________________
+function _defdll(pp, n, rn, p)
+{
+ _[p = _wLCHLD(pp, _n("TYPE", "defdll"))]["NAME"] = n
+ _[p]["REGPATH"] = _[pp]["REGPATH"] rn
+ _[p]["ERRHOST"] = pp
+ return p
+}
+
+#___________________________________________________________
+function _defescarr(D, r, S, i, c, t)
+{
+ if (isarray(S)) {
+ for (i = 0; i < 256; i++) {
+ if ((c = _CHR[i]) ~ r) {
+ D[c] = "\\" S[c]
+ t = t c
+ } else {
+ if (D[c] == "") {
+ D[c] = c
+ }
+ }
+ }
+ } else {
+ for (i = 0; i < 256; i++) {
+ if ((c = _CHR[i]) ~ r) {
+ D[c] = S c
+ if (S != "") {
+ t = t c
+ }
+ } else {
+ if (D[c] == "") {
+ D[c] = c
+ }
+ }
+ }
+ }
+ return t
+}
+
+#_________________________________________________________________________________________
+function _defile(pp, n, f, v, p)
+{
+ _[p = _wLCHLD(pp, _n("TYPE", "defile"))]["NAME"] = n
+ _[p]["FILE"] = f
+ if (! (v == 0 && v == "")) {
+ _[p]["RQVERSION"] = v
+ }
+ return p
+}
+
+#_______________________________________________________________________
+function _defn(f, c, v)
+{
+ FUNCTAB[c f] = v
+}
+
+#_________________________________________________________________________________________
+function _defreg(pp, n, f, v, p)
+{
+ _[p = _wLCHLD(pp, _n("TYPE", "defreg"))]["NAME"] = n
+ _[p]["REGPATH"] = f
+ if (! (v == 0 && v == "")) {
+ _[p]["VALUE"] = v
+ }
+}
+
+#_______________________________________________________________________________________________
+function _defsolution(pp, n, rn, p)
+{
+ _[p = _wLCHLD(pp, _n("TYPE", "solution"))]["NAME"] = n
+ _[p]["REGPATH"] = rn
+ _[p]["ERRHOST"] = pp
+ return p
+}
+
+#_________________________________________________________________________________________
+function _defsrv(pp, n, f, v, p)
+{
+ _[p = _wLCHLD(pp, _n("TYPE", "defsrv"))]["NAME"] = n
+ _[p]["SERVNAME"] = f
+ return p
+}
+
+#_______________________________________________________________________
+function _del(f, c, a, A)
+{
+ if (match(f, /\\[ \t]*$/)) {
+ if ((c = toupper(_filerd(f))) && length(f) == FLENGTH) {
+ _cmd("rd " c " /S /Q 2>NUL")
+ _deletepfx(_WFILEROOTDIR, c)
+ _deletepfx(_FILEIO_RDTMP, c)
+ _deletepfx(_FILEIO_RDNETMP, c)
+ } else {
+ _conl("HUJ TEBE!")
+ return ""
+ }
+ } else {
+ a = _dir(A, f)
+ _cmd("del " f " /Q 2>NUL")
+ for (c in A) {
+ if (c ~ /\\$/) {
+ _cmd("rd " c " /S /Q 2>NUL")
+ _deletepfx(_WFILEROOTDIR, c)
+ _deletepfx(_FILEIO_RDTMP, c)
+ }
+ _deletepfx(_FILEIO_RDNETMP, c)
+ }
+ }
+ return a
+}
+
+#_______________________________________________________________________
+function _delay(t, a)
+{
+ for (a = 1; a <= t; a++) {
+ _delayms()
+ }
+}
+
+#_________________________________________________________________
+function _delayms(a)
+{
+ for (a = 1; a <= _delay_perfmsdelay; a++) {
+ }
+}
+
+#_______________________________________________________________________
+function _deletepfx(A, f, B, le, i)
+{
+ le = length(f)
+ for (i in A) {
+ if (substr(toupper(i), 1, le) == f) {
+ B[i] = A[i]
+ delete A[i]
+ }
+ }
+}
+
+#_________________________________________________________________
+function _delf(A, f)
+{
+ A["B"][A["F"][A["B"][f]] = A["F"][f]] = A["B"][f]
+ delete A["F"][f]
+ delete A["B"][f]
+}
+
+#_______________________________________________________________________
+function _deluid(p)
+{
+ if (p in _CLASSPTR) {
+ _deluida0 = _CLASSPTR[p]
+ if (_deluida0 in _UIDOBL) {
+ _UIDOBLV[_UIDOBL[_deluida0]][p]
+ }
+ }
+ delete _CLASSPTR[p]
+ return _deluida0
+}
+
+#_______________________________________________________________________
+function _dir(A, rd, i, r, f, ds, pf, B, C)
+{
+ delete A
+ gsub(/(^[ \t]*)|([ \t]*$)/, "", rd)
+ if (rd == "") {
+ return ""
+ }
+ i = split(_cmd("dir \"" rd "\" 2>NUL"), B, /\x0D?\x0A/) - 3
+ pf = (match(B[4], /Directory of ([^\x00-\x1F]+)/, C) ? C[1] ((C[1] ~ /\\$/ ? "" : "\\")) : "")
+ for (r = 0; i > 5; i--) {
+ if (match(B[i], /^([^ \t]*)[ \t]+([^ \t]*)[ \t]+((<DIR>)|([0-9\,]+))[ \t]+([^\x00-\x1F]+)$/, C)) {
+ if (C[6] !~ /^\.\.?$/) {
+ if (C[4]) {
+ ds = "D "
+ } else {
+ ds = C[5] " "
+ gsub(/\,/, "", ds)
+ }
+ if ((f = _filepath(pf C[6] ((C[4] ? "\\" : "")))) != "") {
+ A[f] = ds C[1] " " C[2]
+ r++
+ }
+ }
+ }
+ }
+ return r
+}
+
+#_________________________________________________________________
+function _dirtree(A, f, B)
+{
+ gsub(/(^[ \t]*)|([ \t]*$)/, "", f)
+ delete A
+ A[""]
+ delete A[""]
+ _dirtree_i0(B, 8, split(_cmd("dir \"" f "\" /-C /S 2>NUL"), B, /\x0D?\x0A/), A, f = _filerd(f))
+ return f
+}
+
+#___________________________________________________________
+function _dirtree_i0(B, i, c, A, f, lf, a, C)
+{
+ delete A[f]
+ A[f][0]
+ delete A[f][0]
+ lf = length(f)
+ for (; i <= c; ) {
+ if (match(B[i], /^[ \t]*Directory of (.+)/, C)) {
+ if (substr(a = _filerd(C[1] "\\"), 1, lf) == f) {
+ i = _dirtree_i0(B, i + 4, c, A[f], a)
+ } else {
+ return i
+ }
+ } else {
+ if (match(B[i++], /^([^ \t\-]+)\-([^ \t\-]+)\-([^ \t]+)[ \t]+([^ \t]+)[ \t]+([0-9]+)[ \t]+(.+)$/, C)) {
+ A[f][f C[6]] = C[5] " " C[1] "/" _CHR["MONTH"][C[2]] "/" C[3] " " C[4]
+ }
+ }
+ }
+ return i
+}
+
+#_______________________________________________________________________
+function _dll_check(pp)
+{
+ _dllchktv = ""
+ _missfl = 1
+ _tframe("_dll_check_i0", pp, _REG, pp) #also check that all dll have same version; also check that all dlls have success and then report that DS plug-in version n - installed
+ if (1 || "AGENT" in _[pp]) {
+ if (_dllchktv != _[pp][".Product Version"]) {
+ _dllerr(_[pp]["AGENT"], "agent version (" _[pp][".Product Version"] ") do not match all lib versions: " _dllchktv "'")
+ }
+ } else {
+ if (! _missfl) {
+ _creport(pp, "agent not detected in registry")
+ } else {
+ _dllerr(pp, "agent not detected in registry but some registry entries exist:")
+ _tframe("_dll_check_i1", pp, pp)
+ }
+ }
+}
+
+#_______________________________________________
+function _dll_check_i0(p, R, pp, p2, i, i2, r, f, v, rs, d, tv, tf)
+{
+ if (_[p]["TYPE"] == "defdll") {
+ r = toupper(_[p]["REGPATH"])
+ rs = 0
+ tf = 0
+ tv = ""
+ for (i in R) {
+ if (toupper(substr(i, 1, length(r))) == r) {
+ if ((_chka0 = substr(i, 1 + length(r), 1)) == "" || _chka0 == "\\") {
+ rs = 1
+ _missfl = 1
+ _[p]["." substr(gensub(/\....$/, "", 1, i), i2 = 2 + length(r), length(i) - i2 + 1)] = R[i]
+ if (chka0 != "") {
+ rs = 1
+ }
+ }
+ }
+ }
+ if (rs) {
+ if ((i = ".Install Path") in _[p] && (i = ".Product Version") in _[p]) {
+ _[p]["STATUS"] = "PRESENT"
+ f = _[p][".Install Path"]
+ v = _[p][".Product Version"]
+ if (! (".Module" in _[p])) {
+ _[pp][".Product Version"] = v
+ _VAR["HKEY_LOCAL_MACHINE\\SOFTWARE\\Altiris\\Deployment\\AgentInstallPath.STR"] = f
+ _[pp]["AGENT"] = p
+ _creport("OK: DLL DETECTED(" v "): " substr(_[p]["NAME"], 1, 112))
+ } else {
+ if (_dllchktv == "") {
+ _dllchktv = v
+ } else {
+ if (v != _dllchktv) {
+ return _dllerr(p, "different versions detected: " _dllchktv "!=" v "'")
+ }
+ }
+ ERRNO = ""
+ if (_th1(_[p]["DATA"] = _rdfile(f), ERRNO)) {
+ delete _[p]["DATA"]
+ return _dllerr(p, "read lib: " ERRNO, f)
+ }
+ if (v != (_[p]["VERSION"] = _getfilever(f))) {
+ return _dllerr(p, "library file version mismatch: ==`" _[p]["VERSION"] "'; !=`" v "'", f)
+ }
+ _creport(p, "OK: LIBRARY DETECTED(" v "): " substr(f, 1, 100))
+ }
+ } else {
+ tf = 1
+ _dllerr(p, "registry corrupt: `" i "' not present")
+ }
+ } else {
+ _[p]["STATUS"] = "MISSED"
+ }
+ }
+}
+
+#_______________________________________________
+function _dll_check_i1(p, pp, p1, p2, p3, i)
+{
+ if (_[p]["TYPE"] == "defdll") {
+ for (i in _[p]) {
+ if (i ~ /^\./) {
+ _dllerr(pp, " " _[p]["REGPATH"] "\\" substr(i, 2))
+ }
+ }
+ }
+}
+
+#___________________________________________________________________________________
+function _dllerr(p, t, f)
+{
+ if (t !~ /\x00/) {
+ t = "ERROR: \000" t
+ }
+ _errfl = 1
+ _[p]["ERROR"] = _[p]["ERROR"] _ln(t ((f == "" ? "" : ": " f)))
+}
+
+function _drawuid(p, cn, ch, o)
+{
+ _conl("uid: " p)
+ _conl("\toblptr: " ((p in _UIDOBL ? _UIDOBL[p] "'" : "-")))
+ if (p in _UIDOBL) {
+ if (! _isptr(o = _UIDOBL[p])) {
+ _conl(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> oblptr not pointer")
+ }
+ if (! isarray(_UIDOBLV[o])) {
+ _conl(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> no OBLV array at ptr")
+ }
+ }
+ _conl("\tprefix: " ((p in _UIDPFX ? _UIDPFX[p] "'" : "-")))
+ _conl("\tsuffix: " ((p in _UIDSFX ? _UIDSFX[p] "'" : "-")))
+ _conl("\tcounters: " (cn = (p in _UIDCNT ? _UIDCNT[p] "'" : "-")))
+ if (cn != "-") {
+ _conl("\t\tcntrL: " _UIDCNTL[_UIDCNT[p]] "'")
+ _conl("\t\tcntrH: " _UIDCNTH[_UIDCNT[p]] "'")
+ }
+ _conl("\tcharset: " (ch = (p in _UIDCHR ? _UIDCHR[p] "'" : "-")))
+ if (ch != "-") {
+ _conl("chrH: ")
+ _conl(_dumparr(_UIDCHRH[_UIDCHR[p]]))
+ _conl()
+ _conl("chrL: ")
+ _conl(_dumparr(_UIDCHRL[_UIDCHR[p]]))
+ _conl()
+ }
+}
+
+#_______________________________________________________________________
+function _dumparr(A, t, lv, a)
+{
+ b = PROCINFO["sorted_in"]
+ PROCINFO["sorted_in"] = "_lengthsort"
+ if (isarray(A)) {
+ delete _DUMPARR
+ _dumparrc = _dumparrd = ""
+ _dumparr_i1(A, lv = ((lv == "" ? 16 : (lv == 0 || lv + 0 != 0 ? lv : (lv == "-*" ? -3 : (lv ~ /^\+?\*$/ ? 3 : 16))))) + 0, (lv < 0 ? -1 : 1), 0, _tabtospc(t))
+ PROCINFO["sorted_in"] = a
+ return _retarrd(_DUMPARR, _dumparrd, _dumparrd = "")
+ }
+}
+
+#___________________________________________________________
+function _dumparr_i1(A, lv, ls, ln, t, t2, i, a, f)
+{
+ t2 = _getchrln(" ", length(t))
+ if (ln == lv) {
+ if (ls > 0) {
+ for (i in A) {
+ ++a
+ }
+ } else {
+ for (i in A) {
+ (isarray(A[i]) ? ++a : "")
+ }
+ }
+ if (length(_dumparrd = _dumparrd t ((a > 0 ? " ... (x" a ")" : "")) _CHR["EOL"]) > 262144) {
+ _DUMPARR[++_dumparrc] = _dumparrd
+ _dumparrd = ""
+ }
+ return
+ }
+ if (ls >= 0) {
+ for (i in A) {
+ if (! isarray(A[i])) {
+ if (length(_dumparrd = _dumparrd ((f ? t2 : t _nop(f = 1))) "[" i "]=" A[i] "'" _CHR["EOL"]) > 262144) {
+ _DUMPARR[++_dumparrc] = _dumparrd
+ _dumparrd = ""
+ }
+ }
+ }
+ }
+ for (i in A) {
+ if (isarray(A[i])) {
+ _dumparr_i1(A[i], lv, ls, ln + ls, _th0((f ? t2 : t), f = 1) "[" i "]")
+ }
+ }
+ if (! f) {
+ if (length(_dumparrd = _dumparrd t _CHR["EOL"]) > 262144) {
+ _DUMPARR[++_dumparrc] = _dumparrd
+ _dumparrd = ""
+ }
+ }
+}
+
+#___________________________________________________________________________________
+####################################################################################
+
+
+#___________________________________________________________________________________
+# OTHER tFUNCTIONs #################################################################
+
+#_____________________________________________________________________________
+function _dumpobj(p, f, t, s)
+{
+ s = _dumpobj_i0(p, f, t = t "." p "{")
+ if (p = _rFCHLD(p)) {
+ return (s = s _dumpobjm(p, f, (s ? _getchrln(" ", length(t) - 1) : t " ")))
+ }
+ return s
+}
+
+#___________________________________________________________
+function _dumpobj_i0(p, f, t)
+{
+ if (f == "") {
+ return _dumpobj_i2(p, t)
+ }
+ if (f == 0) {
+ return _dumpobj_i1(p, t " ")
+ }
+ return (_dumpobj_i1(p, t " ") _dumpobj_i2(p, _getchrln(" ", length(t))))
+}
+
+#___________________________________________________________
+function _dumpobj_i1(p, t)
+{
+ return _ln(t substr(((p in _tPREV ? "\253" _tPREV[p] : "")) " ", 1, 7) " " substr(((p in _tPARENT ? "\210" _tPARENT[p] : "")) " ", 1, 7) " " substr(((p in _tFCHLD ? _tFCHLD[p] : "")) "\205" ((p in _tQCHLD ? " (" _tQCHLD[p] ") " : "\205")) "\205" ((p in _tLCHLD ? _tLCHLD[p] : "")) " ", 1, 22) substr(((p in _tNEXT ? "\273" _tNEXT[p] : "")) " ", 1, 8))
+}
+
+#___________________________________________________________
+function _dumpobj_i2(p, t)
+{
+ return (_dumpobj_i3(_[p], t " ") _dumpobj_i3(_ptr[p], _getchrln(" ", length(t)) "`", "`"))
+}
+
+#___________________________________________________________
+function _dumpobj_i3(A, t, p, e, s, i, t2)
+{
+ if (isarray(A)) {
+ for (i in A) {
+ t2 = _getchrln(" ", length(t))
+ for (i in A) {
+ if (isarray(A[i])) {
+ s = s _dumpobj_i3(A[i], t "[" _dumpobj_i4(i) "]", p, _ln())
+ } else {
+ s = s _ln(t "[" _dumpobj_i4(i) "]=" p _dumpobj_i4(A[i]) "'")
+ }
+ t = t2
+ }
+ return s
+ }
+ return ((e == "" ? "" : t e))
+ }
+ if (A == 0 && A == "") {
+ return
+ }
+ return _ln(t "=" _dumpobj_i4(p A) "'")
+}
+
+#___________________________________________________________
+function _dumpobj_i4(t)
+{
+ if (length(t) > 64) {
+ return (substr(t, 1, 28) " ... " substr(t, length(t) - 28))
+ }
+ return t
+}
+
+#_________________________________________________________________
+function _dumpobj_nc(p, f, t)
+{
+ return _dumpobj_i0(p, f, t "." p "{ ")
+}
+
+#_________________________________________________________________
+function _dumpobjm(p, f, t, s, t2)
+{
+ t2 = _getchrln(" ", length(t))
+ do {
+ s = s _dumpobj(p, f, t)
+ t = t2
+ } while (p = _rNEXT(p))
+ return s
+}
+
+#_________________________________________________________________
+function _dumpobjm_nc(p, f, t, s, t2)
+{
+ t2 = _getchrln(" ", length(t))
+ do {
+ s = s _dumpobj_nc(p, f, t)
+ t = t2
+ } while (p = _rNEXT(p))
+ return s
+}
+
+function _dumpuidgen(p, pd, pc, ps)
+{
+ _conline("#" ++cntdm ": " p "'")
+ _conl()
+ if (p in _tuidel) {
+ _conl("DEL: " _var(pd = _tuidel[p]))
+ _conl(_dumparr(_tUIDEL[pd]) _ln())
+ }
+ _conl("PFX: " _tUIDPFX[p] "'")
+ _conl("SFX: " _tUIDSFX[p] "'")
+ _conl("COUNT: " ((p in _tuidcnt ? (pc = _tuidcnt[p]) "'" : _th0("-", pc = -2))))
+ _con("CHARS: ")
+ if (p in _tuidchr) {
+ _conl((ps = _tuidchr[p]) "'")
+ _conl("HCHR: " ((pc == -2 ? "-" : _tUIDCNTH[pc] "'")))
+ _conl(_dumparr(_tUIDCHRH[ps]) _ln())
+ _conl("LCHR: " ((pc == -2 ? "-" : _tUIDCNTL[pc] "'")))
+ _conl(_dumparr(_tUIDCHRL[ps]) _ln())
+ } else {
+ _conl("-")
+ }
+}
+
+#_____________________________________________________________________________
+function _dumpval(v, n)
+{
+ _dumpstr = _dumpstr (v = _ln(((n == 0 && n == "" ? "RET" : n)) ": " ((v == 0 && v == "" ? "-" : v "'"))))
+ return v
+}
+
+########################################################
+function _eXTFN(c, t, P)
+{
+ switch (c) {
+ case "_lib_CMDLN":
+ return t
+ #___________________________________________________________
+
+ case "_lib_APPLY":
+ return
+ #___________________________________________________________
+
+ case "_lib_HELP":
+ return
+ #___________________________________________________________
+
+ case "_lib_NAMEVER":
+ return _ln("_extfn 1.0")
+ #___________________________________________________________
+
+ case "_lib_BEGIN":
+ return
+ #___________________________________________________________
+
+ case "_lib_END":
+ return
+ }
+}
+
+#_________________________________________________________________
+function _endpass(t)
+{
+ _endpass_v0 = t
+}
+
+#_______________________________________________________________________
+function _err(t, a, b)
+{
+ a = BINMODE
+ b = ORS
+ BINMODE = "rw"
+ ORS = ""
+ print(t) > _SYS_STDERR
+ fflush(_SYS_STDERR)
+ BINMODE = a
+ ORS = b
+ return t
+}
+
+#_________________________________________________________________
+function _errnl(t)
+{
+ return _err(t ((t ~ /\x0A$/ ? "" : _CHR["EOL"])))
+}
+
+#_______________________________________________________________________
+function _error(t, d, A)
+{
+ if (_ERRLOG_EF) {
+ A["TYPE"] = "ERROR"
+ A["TEXT"] = t
+ _log(A, d)
+ }
+}
+
+#_______________________________________________________________________
+function _exit(c)
+{
+ exit c
+}
+
+#_____________________________________________________________________________
+function _export_data(t, i, A)
+{
+ A["DATA"] = t
+ A["ID"] = i
+ _expout("_DATA: " _Zexparr(A) "\n")
+}
+
+#___________________________________________________________________________________
+####################################################################################
+
+#_____________________________________________________________________________
+function _expout(t, d, a, b)
+{
+ a = BINMODE
+ b = ORS
+ BINMODE = "rw"
+ ORS = ""
+ print(t) > ((d ? d : d = _errlog_file))
+ fflush(d)
+ BINMODE = a
+ ORS = b
+}
+
+#_________________________________________________________________________________________
+##########################################################################################
+
+
+
+
+
+
+
+
+function _extfn_init()
+{
+ _formatstrs_init()
+ _formatstrd_init()
+ _formatrexp_init()
+ _unformatstr_init()
+ _mac_init()
+}
+
+function _faccl_i0(A, t, p, P, f, r)
+{
+ f = r = ""
+ if (isarray(A)) {
+ while (f = A[f]) {
+ r = (@f(t, p, P)) r
+ }
+ }
+ return r
+}
+
+function _faccr_i0(A, t, p, P, f, r)
+{
+ f = r = ""
+ if (isarray(A)) {
+ while (f = A[f]) {
+ r = r @f(t, p, P)
+ }
+ }
+ return r
+}
+
+#_______________________________________________________________________
+function _fatal(t, d, A)
+{
+ if (_ERRLOG_FF) {
+ A["TYPE"] = "FATAL"
+ A["TEXT"] = t
+ _log(A, d)
+ }
+ if (! d) {
+ exit
+ }
+}
+
+function _fbaccl(A, t, p, P)
+{
+ return _faccl_i0(A["B"], t, p, P)
+}
+
+function _fbaccr(A, t, p, P)
+{
+ return _faccr_i0(A["B"], t, p, P)
+}
+
+function _ffaccl(A, t, p, P)
+{
+ return _faccl_i0(A["F"], t, p, P)
+}
+
+function _ffaccr(A, t, p, P)
+{
+ return _faccr_i0(A["F"], t, p, P)
+}
+
+#_______________________________________________________________________
+function _fframe(A, t, p)
+{
+ return _fframe_i0(A, t, p, A[""])
+}
+
+#___________________________________________________________
+function _fframe_i0(A, t, p, f)
+{
+ return ((f ? (@f(t, p)) _fframe_i0(A, t, p, A[f]) : ""))
+}
+
+#_________________________________________________________________
+function _file(f)
+{
+ if ((f = _filerdnehnd(f)) == "") {
+ return ""
+ }
+ return ((f in _FILEXT ? _FILEXT[f] : ""))
+}
+
+#_______________________________________________________________________
+function _file_check(p)
+{
+ if (1 || "AGENT" in _[p]) {
+ _tframe("_file_check_i0", p, p)
+ }
+}
+
+#_______________________________________________
+function _file_check_i0(p, pp, p1, p2, f, v)
+{
+ if (_[p]["TYPE"] == "defile") {
+ f = _[p]["FILE"]
+ f = ((match(f, /^.:/) ? "" : _[_[pp]["AGENT"]][".Install Path"] "\\")) _[p]["FILE"]
+ if ("RQVERSION" in _[p]) {
+ v = _[p]["RQVERSION"]
+ } else {
+ v = _[pp][".Product Version"]
+ }
+ ERRNO = ""
+ if (_th1(_[p]["DATA"] = _rdfile(f), ERRNO)) {
+ delete _[p]["DATA"]
+ return _dllerr(p, "read file: " ERRNO, f)
+ }
+ if (v != "" && v != (_[p]["VERSION"] = _getfilever(f))) {
+ return _dllerr(p, " file version mismatch: ==`" _[p]["VERSION"] "'; !=`" v "'", f)
+ }
+ _creport(p, substr("OK: FILE DETECTED" ((v == "" ? "" : "(" v ")")) ": " f, 1, 122))
+ } else {
+ if (_[p]["TYPE"] == "defdir") {
+ if (_filexist(f = _[p]["DIR"])) {
+ _creport(p, substr("OK: DIR DETECTED: " f, 1, 112))
+ } else {
+ _dllerr(p, "directory " f " is not detected")
+ }
+ }
+ }
+}
+
+#_________________________________________________________________
+function _filed(f, dd, d)
+{
+ if ((f = _filerdnehnd(f)) == "") {
+ return ""
+ }
+ if (f in _FILEDIRFL) {
+ return _FILEDIR[f]
+ }
+ if (f in _FILEROOT) {
+ if (d = filegetdrvdir(_FILEROOT[f])) {
+ _FILEDIRFL[f]
+ }
+ return (_FILEDIR[f] = d _FILEDIR[f])
+ }
+ if ((dd = (dd ? dd : _FILEIO_RD), f) in _FILEDIR) {
+ return _FILEDIR[dd, f]
+ }
+ if ((d = filedi(dd) _FILEDIR[f]) ~ /^\\/) {
+ return (_FILEDIR[dd, f] = d)
+ }
+ return d
+}
+
+#_________________________________________________________________
+function _filen(f)
+{
+ if ((f = _filerdnehnd(f)) == "") {
+ return ""
+ }
+ return ((f in _FILENAM ? _FILENAM[f] : ""))
+}
+
+#_________________________________________________________________
+function _filene(f)
+{
+ if ((f = _filerdnehnd(f)) == "") {
+ return ""
+ }
+ return (((f in _FILENAM ? _FILENAM[f] : "")) ((f in _FILEXT ? _FILEXT[f] : "")))
+}
+
+#_________________________________________________________________
+function _filenotexist(f, a)
+{
+ if (f == "") {
+ return ""
+ }
+ if ((a = _filepath(f)) == "") {
+ ERRNO = "Filepath error `" f "'"
+ return ""
+ }
+ _cmd("if exist \"" a "\" exit 1 2>NUL")
+ if (_exitcode == 1) {
+ return (ERRNO = _NOP)
+ }
+ return a
+}
+
+#_______________________________________________________________________
+function _filepath(f, dd)
+{
+ if ((f = _filerdnehnd(f)) == "") {
+ return ""
+ }
+ return (filegetrootdir(f, dd) ((f in _FILENAM ? _FILENAM[f] : "")) ((f in _FILEXT ? _FILEXT[f] : "")))
+}
+
+#_________________________________________________________________
+function _filer(f, dd)
+{
+ if ((f = _filerdnehnd(f)) == "") {
+ return ""
+ }
+ if (f in _FILEROOT) {
+ return _FILEROOT[f]
+ }
+ if ((dd = (dd ? dd : _FILEIO_RD), f) in _FILEROOT) {
+ return _FILEROOT[dd, f]
+ }
+ return (_FILEROOT[dd, f] = fileri(dd))
+}
+
+#_________________________________________________________________
+function _filerd(f, dd)
+{
+ if ((f = _filerdnehnd(f)) == "") {
+ return ""
+ }
+ return filegetrootdir(f, dd)
+}
+
+#_________________________________________________________________
+function _filerdn(f, dd)
+{
+ if ((f = _filerdnehnd(f)) == "") {
+ return ""
+ }
+ return ((f in _FILENAM ? filegetrootdir(f, dd) _FILENAM[f] : ""))
+}
+
+#_________________________________________________________________
+function _filerdne(f, dd)
+{
+ if ((f = _filerdnehnd(f)) == "") {
+ return ""
+ }
+ if (f in _FILENAM) {
+ return (filegetrootdir(f, dd) _FILENAM[f] ((f in _FILEXT ? _FILEXT[f] : "")))
+ }
+ if (f in _FILEXT) {
+ return (filegetrootdir(f, dd) _FILEXT[f])
+ }
+ return ""
+}
+
+#___________________________________________________________
+function _filerdnehnd(st, c, r, d, n, A)
+{
+ if (st) {
+ if ((c = toupper(st)) in _FILECACHE) {
+ FLENGTH = length(st)
+ return _FILECACHE[c]
+ }
+ if (match(st, /^[ \t]*\\[ \t]*\\/)) {
+ if (match(substr(st, (FLENGTH = RLENGTH) + 1), /^[ \t]*([0-9A-Za-z\-]+)[ \t]*(\\[ \t]*([A-Za-z])[ \t]*\$[ \t]*)?(\\[ \t]*([0-9A-Za-z_\!\+\-\[\]\(\)\{\}\~\.]+( +[0-9A-Za-z_\!\+\-\[\]\(\)\{\}\~\.]+)*[ \t]*\\)+[ \t]*)?(([0-9A-Za-z_\!\+\.\~\-\[\]\{\}\(\)]+( +[0-9A-Za-z_\!\+\.\~\-\[\]\{\}\(\)]+)*)[ \t]*)?/, A)) {
+ FLENGTH = FLENGTH + RLENGTH
+ d = ((A[3] ? "\\" A[3] "$" : "")) A[4]
+ gsub(/[ \t]*\\[ \t]*/, "\\", d)
+ if ((st = toupper((r = "\\\\" A[1]) d (n = A[8]))) in _FILECACHE) {
+ return (_FILECACHE[substr(c, 1, FLENGTH)] = _FILECACHE[st])
+ }
+ _FILEDIR[c = _FILECACHE[substr(c, 1, FLENGTH)] = _FILECACHE[st] = ++_file_rootcntr] = d
+ _FILEDIRFL[c]
+ _FILEROOT[c] = r
+ } else {
+ FLENGTH = 0
+ _filepath_err = "UNC"
+ return ""
+ }
+ } else {
+ match(st, /^(([ \t]*\.[ \t]*\\[ \t]*)|(([ \t]*([A-Za-z])[ \t]*(\:)[ \t]*)?([ \t]*(\\)[ \t]*)?))([ \t]*(([ \t]*[0-9A-Za-z_\!\+\-\[\]\(\)\{\}\~\.]+( +[0-9A-Za-z_\!\+\-\[\]\(\)\{\}\~\.]+)*[ \t]*\\)+)[ \t]*)?([ \t]*([0-9A-Za-z_\!\+\.\~\-\[\]\{\}\(\)]+( +[0-9A-Za-z_\!\+\.\~\-\[\]\{\}\(\)]+)*)[ \t]*)?/, A)
+ if (! (FLENGTH = RLENGTH)) {
+ return ""
+ }
+ d = A[8] A[10]
+ gsub(/[ \t]*\\[ \t]*/, "\\", d)
+ if ((st = toupper((r = A[5] A[6]) d (n = A[14]))) in _FILECACHE) {
+ return (_FILECACHE[substr(c, 1, FLENGTH)] = _FILECACHE[st])
+ }
+ _FILEDIR[c = _FILECACHE[substr(c, 1, FLENGTH)] = _FILECACHE[st] = ++_file_rootcntr] = d
+ if (A[8]) {
+ _FILEDIRFL[c]
+ }
+ if (r) {
+ _FILEROOT[c] = r
+ }
+ }
+ if (n) {
+ if (match(n, /\.[^\.]*$/)) {
+ _FILEXT[c] = substr(n, RSTART)
+ _FILENAM[c] = substr(n, 1, RSTART - 1)
+ } else {
+ _FILENAM[c] = n
+ }
+ }
+ return c
+ }
+ return ""
+}
+
+#_______________________________________________________________________
+function _filexist(f, a)
+{
+ if (f == "") {
+ return ""
+ }
+ if ((a = _filepath(f)) == "") {
+ ERRNO = "Filepath error `" f "'"
+ return ""
+ }
+ _cmd("if exist \"" a "\" exit 1 2>NUL")
+ if (_exitcode == 1) {
+ return a
+ }
+ ERRNO = "File not found `" f "'"
+ return _NOP
+}
+
+#_______________________________________________________________________
+function _fn(f, p0, p1, p2)
+{
+ if (f in FUNCTAB) {
+ return @f(p0, p1, p2)
+ }
+}
+
+#_______________________________________________________________________
+function _foreach(A, f, r, p0, p1, p2, i, p)
+{
+ if (isarray(A)) {
+ _TMP0[p = _n()]["."] = 1
+ _foreach_i0(A, f, _TMP0[p], p0, p1, p2)
+ return _th0(_retarr(_TMP0[p]), _tdel(p))
+ }
+ if (_isptr(A)) {
+ _TMP0[p = _n()][_ARRLEN] = 1
+ _tframe4("_foreach_i1" ((r ? "~" r : "")), A, f, _TMP0[p], p0, p1)
+ return _th0(_retarr(_TMP0[p]), _tdel(p))
+ }
+}
+
+#_____________________________________________________
+function _foreach_i0(A, f, D, p0, p1, p2)
+{
+ for (i in A) {
+ if (isarray(A[i])) {
+ _foreach_i0(A[i], f, D, p0, p1, p2)
+ } else {
+ _gen(D, @f(A[i], p0, p1, p2))
+ }
+ }
+}
+
+#_____________________________________________________
+function _foreach_i1(p, f, D, p0, p1, p2)
+{
+ _gen(D, @f(p, p0, p1, p2))
+}
+
+#_____________________________________________________________________________
+function _formatrexp(t)
+{
+ _formatstrq0 = split(t, _FORMATSTRA, /[\/\x00-\x1F\x80-\xFF]/, _FORMATSTRB)
+ _formatstrs0 = ""
+ for (t = 1; t < _formatstrq0; t++) {
+ _formatstrs0 = _formatstrs0 _FORMATSTRA[t] _FORMATREXPESC[_FORMATSTRB[t]]
+ }
+ return (_formatstrs0 _FORMATSTRA[t])
+}
+
+#___________________________________________________________
+function _formatrexp_init()
+{
+ _defescarr(_FORMATREXPESC, "[\\x00-\\x1F\\x80-\\xFF]", _QASC)
+ _defescarr(_FORMATREXPESC, "\\/", "\\")
+ _FORMATREXPESC["\t"] = "\\t"
+}
+
+#_____________________________________________________________________________
+function _formatstrd(t)
+{
+ _formatstrq0 = split(t, _FORMATSTRA, /["\x00-\x1F\x80-\xFF]/, _FORMATSTRB)
+ _formatstrs0 = ""
+ for (t = 1; t < _formatstrq0; t++) {
+ _formatstrs0 = _formatstrs0 _FORMATSTRA[t] _FORMATSTRDESC[_FORMATSTRB[t]]
+ }
+ return (_formatstrs0 _FORMATSTRA[t])
+}
+
+#___________________________________________________________
+function _formatstrd_init()
+{
+ _defescarr(_FORMATSTRDESC, "[\\x00-\\x1F\\x80-\\xFF]", _QASC)
+ _defescarr(_FORMATSTRDESC, "[\\\\\"]", "\\")
+ _FORMATSTRDESC["\t"] = "\\t"
+}
+
+####################################################################################
+
+
+
+
+#___________________________________________________________________________________
+function _formatstrs(t)
+{
+ _formatstrq0 = split(t, _FORMATSTRA, /['\x00-\x1F\x80-\xFF]/, _FORMATSTRB)
+ _formatstrs0 = ""
+ for (t = 1; t < _formatstrq0; t++) {
+ _formatstrs0 = _formatstrs0 _FORMATSTRA[t] _FORMATSTRSESC[_FORMATSTRB[t]]
+ }
+ return (_formatstrs0 _FORMATSTRA[t])
+}
+
+#___________________________________________________________
+function _formatstrs_init()
+{
+ _defescarr(_FORMATSTRSESC, "[\\x00-\\x1F\\x80-\\xFF]", _QASC)
+ _defescarr(_FORMATSTRSESC, "[\\\\']", "\\")
+ _FORMATSTRSESC["\t"] = "\\t"
+}
+
+function _fpp(q, D, S)
+{
+ _conl()
+ _conline(q)
+ _conl()
+ q = _patharr0(S, q)
+ #_arregpath(D,S)
+ #_conl(_dumparr(D))
+ _conl(_dumparr(S))
+ _conl()
+ return q
+}
+
+#_______________________________________________________________________
+########################################################################
+
+
+
+
+
+
+
+
+
+function _fthru(A, c, p, B)
+{
+ return _fthru_i0(A, c, p, B, A[""])
+}
+
+#_________________________________________________________________
+function _fthru_i0(A, c, p, B, f)
+{
+ return ((f ? @f(c, _fthru_i0(A, c, p, B, A[f]), B) : ""))
+}
+
+function _gen(D, t)
+{
+ if (length(D[D[_ARRLEN]] = D[D["."]] t) > _datablock_length) {
+ D[++D[_ARRLEN]] = ""
+ }
+}
+
+#_____________________________________________________________________________
+function _gensubfn(t, r, f, p0, A)
+{
+ if (match(t, r, A)) {
+ return (substr(t, 1, RSTART - 1) (@f(_th0(substr(t, RSTART, RLENGTH), t = substr(t, RSTART + RLENGTH)), A, p0)) _gensubfn(t, r, f, p0))
+ }
+ return t
+}
+
+#_____________________________________________________________________________
+function _get_errout(p)
+{
+ return _tframe("_get_errout_i0", p)
+}
+
+#_______________________________________________________________________
+function _get_errout_i0(p, t, n, a)
+{
+ return ((p in _tLOG ? _get_errout_i1(p) _get_errout_i3(p) : ""))
+}
+
+#_________________________________________________________________
+function _get_errout_i1(p, t, n, a)
+{
+ if (p in _tLOG) {
+ n = ""
+ if (_tLOG[p]["TYPE"]) {
+ n = _tLOG[p]["TYPE"] ": " _get_errout_i2(p)
+ if (match(_tLOG[p]["TEXT"], /\x1F/)) {
+ t = n
+ gsub(/[^\t]/, " ", t)
+ return (_ln(n substr(_tLOG[p]["TEXT"], 1, RSTART - 1)) _ln(t substr(_tLOG[p]["TEXT"], RSTART + 1)))
+ }
+ }
+ return _ln(n _tLOG[p]["TEXT"])
+ }
+}
+
+#_______________________________________________________________________
+function _get_errout_i2(p)
+{
+ return (("FILE" in _tLOG[p] ? _tLOG[p]["FILE"] (("LINE" in _tLOG[p] ? "(" _tLOG[p]["LINE"] ")" : "")) ": " : ""))
+}
+
+#_______________________________________________________________________
+function _get_errout_i3(p, t, ts, cl, cp, cr, a, b)
+{
+ if ("LSTR" in _tLOG[p]) {
+ t = _tLOG[p]["FULLSTR"]
+ ts = _tLOG[p]["TS"]
+ cp = "^"
+ if ("CSTR" in _tLOG[p]) {
+ cr = _tLOG[p]["CSTR"]
+ cl = _tLOG[p]["CLSTR"]
+ if ("CPSTR" in _tLOG[p]) {
+ cp = _tLOG[p]["CPSTR"]
+ }
+ }
+ cr = substr(cr, length(cl) + length(cp) + 1)
+ return (_ln(_tabtospc(t, ts)) _ln(_getchrln(" ", a = length(_tabtospc(_tLOG[p]["LSTR"], ts))) _getchrln("-", b = length(_tabtospc(cl, ts, a))) _getchrln("^", b = length(_tabtospc(cp, ts, a = a + b))) _getchrln("-", length(_tabtospc(cr, ts, a + b)))))
+ }
+}
+
+#_____________________________________________________________________________
+function _get_logout(p)
+{
+ return _tframe("_get_logout_i0", p)
+}
+
+#_______________________________________________________________________
+function _get_logout_i0(p, t, n, a)
+{
+ if (p in _tLOG) {
+ n = (("DATE" in _tLOG[p] ? _tLOG[p]["DATE"] " " : "")) (("TIME" in _tLOG[p] ? _tLOG[p]["TIME"] " " : ""))
+ if (_tLOG[p]["TYPE"]) {
+ n = n _tLOG[p]["TYPE"] ": " (("FILE" in _tLOG[p] ? _tLOG[p]["FILE"] (("LINE" in _tLOG[p] ? "(" _tLOG[p]["LINE"] ")" : "")) ": " : ""))
+ if (match(_tLOG[p]["TEXT"], /\x1F/)) {
+ t = n
+ gsub(/[^\t]/, " ", t)
+ return (_ln(n substr(_tLOG[p]["TEXT"], 1, RSTART - 1)) _ln(t substr(_tLOG[p]["TEXT"], RSTART + 1)))
+ }
+ }
+ return _ln(n _tLOG[p]["TEXT"])
+ }
+}
+
+#_______________________________________________________________________
+function _getchrln(s, w)
+{
+ if (s == "") {
+ return
+ }
+ #if ( w!=w+0 || w<0 ) w=_CON_WIDTH
+ if (length(s) < w) {
+ if (s in _GETCHRLN) {
+ if (length(_getchrlnt0 = _GETCHRLN[s]) >= w) {
+ return substr(_getchrlnt0, 1, w)
+ }
+ } else {
+ _getchrlnt0 = s s
+ }
+ while (length(_getchrlnt0) < w) {
+ _getchrlnt0 = _getchrlnt0 _getchrlnt0
+ }
+ _GETCHRLN[s] = _getchrlnt0
+ return substr(_getchrlnt0, 1, w)
+ } else {
+ return substr(s, 1, w)
+ }
+}
+
+#_______________________________________________________________________
+function _getdate()
+{
+ return strftime("%F")
+}
+
+#_____________________________________________________________________________
+function _getfilepath(t, f, al, b, A)
+{
+ ERRNO = ""
+ if (match(t, /^[ \t]*(("([^"]*)"[ \t]*)|([`']([^']*)'[ \t]*)|(([^ \t]+)[ \t]*))/, A)) {
+ al = RLENGTH
+ f = A[3] A[5] A[7]
+ _conl("_getfilepath(" f ") (" al ")")
+ if (b = _filepath(f)) {
+ if (length(f) <= FLENGTH) {
+ FLENGTH = al
+ return b
+ }
+ ERRNO = "Filepath `" f "' error"
+ }
+ }
+ FLENGTH = 0
+}
+
+function _getfilever(f)
+{
+ split(_cmd(_fileverpath " \"" f "\""), _GETFILEVERA0, /[ \t]+/)
+ if (_GETFILEVERA0[5]) {
+ return _GETFILEVERA0[5]
+ }
+}
+
+#_________________________________________________________________
+function _getime()
+{
+ return strftime("%H:%M:%S")
+}
+
+#_________________________________________________________________
+function _getmpdir(f, dd)
+{
+ if (! dd || ! (dd = _filerd(dd))) {
+ dd = _FILEIO_TMPRD
+ }
+ if (f = (f ? _filerd(f, dd) : _filerd("_" ++_FILEIO_TMPCNTR "\\", dd))) {
+ _FILEIO_RDTMP[toupper(f)]
+ }
+ return f
+}
+
+#_________________________________________________________________
+function _getmpfile(f, dd)
+{
+ if (! dd || ! (dd = _filerd(dd))) {
+ dd = _FILEIO_TMPRD
+ }
+ if (f = _filerdne((_filene(f) ? f : f "_" ++_FILEIO_TMPCNTR), dd)) {
+ _FILEIO_RDNETMP[toupper(f)]
+ }
+ return f
+}
+
+#_______________________________________________________________________
+function _getperf(o, t, a)
+{
+ (o == "" ? ++_getperf_opcurr : _getperf_opcurr = o)
+ if ((a = _getsecond()) != _getperf_last) {
+ _getperf_opsec = (_getperf_opcurr - _getperf_opstart) / ((_getperf_last = a) - _getperf_start)
+ return @_getperf_fn(o, t, a)
+ }
+ return 1
+}
+
+#___________________________________________________________
+function _getperf_(o, t, a)
+{
+ if (a >= _getperf_end) {
+ return 0
+ }
+ if (_getperf_opsecp != _getperf_opsec) {
+ _constat(((_constatstr == _getperf_stat ? _getperf_statstr : _getperf_statstr = _constatstr)) t " [TIME=" (a - _getperf_start) " sec(" (_getperf_opsecp = _getperf_opsec) " ops/sec)]")
+ _getperf_stat = _constatstr
+ }
+ return 1
+}
+
+#___________________________________________________________
+function _getperf_noe(o, t, a)
+{
+ if (_getperf_opsecp != _getperf_opsec) {
+ _constat(((_constatstr == _getperf_stat ? _getperf_statstr : _getperf_statstr = _constatstr)) t " [TIME=" (a - _getperf_start) " sec(" (_getperf_opsecp = _getperf_opsec) " ops/sec)]")
+ _getperf_stat = _constatstr
+ }
+ return 1
+}
+
+#___________________________________________________________
+function _getperf_noenot(o, t, a)
+{
+ return 1
+}
+
+#___________________________________________________________
+function _getperf_not(o, t, a)
+{
+ if (a < _getperf_end) {
+ return 1
+ }
+}
+
+#_________________________________________________________________________________________
+##########################################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+function _getreg_i1(D, r, R, a, i, il, ir, rc, B)
+{
+ a = IGNORECASE
+ IGNORECASE = 1
+ r = "^" _torexp(r)
+ rc = 0
+ zs = ""
+ for (i in R) {
+ if (match(i, r, B)) {
+ il = B[_torexp_pfxcntr]
+ ir = gensub(/....$/, "", 1, substr(i, 1 + B[_torexp_pfxcntr, "length"]))
+ if (! gsub(/^\\/, "", ir) && match(il, /[^\\]+$/)) {
+ ir = substr(il, RSTART) ir
+ }
+ D[ir] = R[i]
+ rc++
+ }
+ }
+ IGNORECASE = a
+ if (rc > 0) {
+ return rc
+ }
+}
+
+#_________________________________________________________________
+function _getsecond()
+{
+ return systime()
+}
+
+#___________________________________________________________
+function _getsecondsync(a, c, b, c2)
+{
+ a = systime()
+ while (a == systime()) {
+ ++c
+ }
+ return (a + 1)
+}
+
+#_______________________________________________________________________
+function _getuid(p)
+{
+ if (p in _UIDOBL) {
+ for (_tptr in _UIDOBLV[_getuida0 = _UIDOBL[p]]) {
+ delete _UIDOBLV[_getuida0][_tptr]
+ _CLASSPTR[_tptr] = p
+ return _tptr
+ }
+ }
+ _CLASSPTR[_tptr = _UIDPFX[p] _getuid_i0(_UIDCNT[p], _UIDCHRL[_tptr = _UIDCHR[p]], _UIDCHRH[_tptr]) _UIDSFX[p]] = p
+ return _tptr
+}
+
+#_____________________________________________________
+function _getuid_i0(p, UL, UH)
+{
+ if ("" == (_tptr = UL[_UIDCNTL[p]])) {
+ for (_tptr in UH) {
+ delete UH[_tptr]
+ return ((_UIDCNTH[p] = _tptr) (_UIDCNTL[p] = UL[""]))
+ }
+ _fatal("out of UID")
+ }
+ return (_UIDCNTH[p] (_UIDCNTL[p] = _tptr))
+}
+
+function _handle8494(t)
+{
+ return gensub(/(.)/, ".\\1", "G", t)
+}
+
+#_____________________________________________________________________________
+function _hexnum(n, l)
+{
+ if (l + 0 < 1) {
+ l = 2
+ }
+ return sprintf("%." ((l + 0 < 1 ? 2 : l)) "X", n)
+}
+
+#_________________________________________________________________
+function _igetperf(t, s, o)
+{
+ if (t == 0 && t == "" && s == 0 && s == "" && o == 0 && o == "") {
+ if (_getperf_fn !~ /not$/ && _constatstr == _getperf_stat) {
+ _constat(_getperf_statstr)
+ }
+ _getperf_fn = "_nop"
+ return ("[TIME=" (_getperf_last - _getperf_start) " sec(" _getperf_opsec " ops/sec)]")
+ }
+ _conl("initiate _getperf")
+ _getperf_opstart = _getperf_opcurr = o + 0
+ _getperf_opsec = _getperf_opsecp = _getperf_stat = _getperf_statstr = ""
+ _getperf_end = t + (_getperf_start = _getperf_last = _getsecondsync())
+ _getperf_fn = ((t + 0 > 0 ? "_getperf_" : "_getperf_noe")) ((s ? "" : "not"))
+ return _getperf_start
+}
+
+function _import_data(t, p, p2, a)
+{
+ if (match(t, /^_DATA: /)) {
+ _tDATA[a = _wLCHLD(p, _N())][""]
+ delete _tDATA[a][""]
+ _Zimparr(_tDATA[a], substr(t, 8))
+ _conl("DATA: `" _tDATA[a]["ID"] "':`" _tDATA[a]["DATA"] "'")
+ return ""
+ }
+ return t
+}
+
+#_______________________________________________________________________
+function _info(t, d, A)
+{
+ if (_ERRLOG_IF) {
+ A["TYPE"] = "INFO"
+ A["TEXT"] = t
+ _log(A, d)
+ }
+}
+
+# test with the different path types
+# _conl(_ln("SRC:") _dumparr(S)); _conl();
+
+function _ini(p, cs, dptr, pfx, sfx, hstr, lstr)
+{
+ return _inituid(p, cs, dptr, pfx, sfx, hstr, lstr, A)
+}
+
+function _initfilever()
+{
+ _fileverpath = "\\\\CPU\\eGAWK\\LIB\\_filever\\_filever.exe"
+}
+
+function _initrdreg()
+{
+ _RDREGTYPE["SZ"] = "STR"
+ _RDREGTYPE["DWORD"] = "W32"
+ _RDREGTYPE["QWORD"] = "W64"
+ _RDREGTYPE["BINARY"] = "BIN"
+ _RDREGTYPE["EXPAND_SZ"] = "XSZ"
+ _RDREGTYPE["MULTI_SZ"] = "MSZ"
+ _RDrdregfld = _rdregkey = 0
+}
+
+function _initregpath0()
+{
+ _REGPATH0REGDIR[""] = "HKEY_LOCAL_MACHINE"
+ _REGPATH0REGDIR["HKLM"] = "HKEY_LOCAL_MACHINE"
+ _REGPATH0REGDIR["HKEY_LOCAL_MACHINE"] = "HKEY_LOCAL_MACHINE"
+ _REGPATH0REGDIR["HKCR"] = "HKEY_CLASSES_ROOT"
+ _REGPATH0REGDIR["HKEY_CLASSES_ROOT"] = "HKEY_CLASSES_ROOT"
+ _REGPATH0REGDIR["HKCU"] = "HKEY_CURRENT_USER"
+ _REGPATH0REGDIR["HKEY_CURRENT_USER"] = "HKEY_CURRENT_USER"
+ _REGPATH0REGDIR["HKU"] = "HKEY_USERS"
+ _REGPATH0REGDIR["HKEY_USERS"] = "HKEY_USERS"
+ _REGPATH0REGDIR["HKCC"] = "HKEY_CURRENT_CONFIG"
+ _REGPATH0REGDIR["HKEY_CURRENT_CONFIG"] = "HKEY_CURRENT_CONFIG"
+ _REGPATH0REGDIR["HKPD"] = "HKEY_PERFORMANCE_DATA"
+ _REGPATH0REGDIR["HKEY_PERFORMANCE_DATA"] = "HKEY_PERFORMANCE_DATA"
+}
+
+function _initshare()
+{
+ _sharextool = "\\\\CPU\\eGAWK\\LIB\\_share\\_share.exe"
+}
+
+#_________________________________________
+function _initspecialuid()
+{
+ _NOINDEX = _getuid()
+ _LEN = _getuid()
+ _PTR = _getuid()
+ _NAME = _getuid()
+ _TYPE = _getuid()
+ _FORMAT = _getuid()
+}
+
+function _initsys()
+{
+}
+
+#_______________________________________________________________________
+function _inituid(p, cs, dptr, pfx, sfx, hstr, lstr, A)
+{
+ if (cs == 0 && cs == "") {
+ cs = p
+ p = _getuid()
+ }
+ _conl()
+ _conl()
+ _conl(cs)
+ if (match(cs, /^(([^:]*):)?(([^'\xB4]*\xB4.)*[^'\xB4]*)[']/, A)) {
+ pfx = A[3]
+ dptr = A[2]
+ }
+ if (match(cs = substr(cs, 1 + RLENGTH), /'(([^'\xB4]*\xB4.)*[^'\xB4]*)$/, A)) {
+ sfx = A[1]
+ cs = substr(cs, 1, RSTART - 1)
+ }
+ if (match(cs, /^(([`\^])(.*))/, A)) {
+ if (A[2] == "`") {
+ hstr = A[3] "~"
+ lstr = ""
+ } else {
+ lstr = A[3] "+"
+ hstr = ""
+ }
+ } else {
+ if (match(cs, /^(([^'\xB4\|]*\xB4.)*[^'\xB4\|]*)(\|(.*))?/, A)) {
+ hstr = A[1]
+ lstr = A[4]
+ } else {
+ ERRNO = "_inituid(): bad parameters"
+ return
+ }
+ }
+ _conl(dptr ":" pfx "'" hstr "|" lstr "'" sfx)
+ return _cfguid(p, dptr, pfx, sfx, hstr, lstr)
+}
+
+function _inituidefault(h, l, H, L)
+{
+ _classys = ""
+ delete _UIDOBLV[_UIDOBLV[_UIDOBL[_classys] = _classys][""] = _classys][""]
+ _UIDPFX[_classys]
+ _UIDSFX[_classys]
+ _UIDCNT[_classys] = _UIDCHR[_classys] = _CLASSPTR[_classys] = _classys
+ h = "AB"
+ l = h "01"
+ _splitstr(H, h)
+ _splitstr(L, l)
+ delete _UIDCHRH[_UIDCHRH[_classys][""] = _classys][""]
+ delete _UIDCHRL[_UIDCHRL[_classys][""] = _classys][""]
+ _UIDCNTH[_classys]
+ _cfguidh(_classys, H, L)
+ _UIDCNTL[_classys] = _cfguidl(_classys, L, L)
+ _CLASSFN[_classys]["del"] = "_tobjDEL"
+ _CLASSFN[_classys]["new"] = "_tobjNEW"
+ _drawuid(_classys)
+ _initspecialuid()
+}
+
+#_______________________________________________________________________
+function _ins(S, sf, D, df)
+{
+ if (sf in S) {
+ if (isarray(S[sf])) {
+ if (df in D) {
+ if (isarray(D[df])) {
+ return _extarr(D[df], S[sf])
+ }
+ delete D[df]
+ }
+ D[df][""]
+ delete D[df][""]
+ return _extarr(D[df], S[sf])
+ } else {
+ if (isarray(D[df])) {
+ delete D[df]
+ }
+ D[df] = S[sf] D[df]
+ }
+ }
+}
+
+#_________________________________________________________________
+function _insf(A, f)
+{
+ A["F"][""] = A["B"][A["F"][f] = A["F"][""]] = f
+}
+
+#_________________________________________________________________
+function _insframe(A, f)
+{
+ A[f] = A[""]
+ A[""] = f
+}
+
+#_________________________________________________________________
+function _inspass(A, f)
+{
+ A[f] = A[""]
+ A[""] = f
+}
+
+# there is problem with string's format: i can;t easilly merge 2 charsets: comma-divided and every-char-divided strings
+
+#_______________________________________________________________________
+function _isptr(p)
+{
+ if (isarray(p)) {
+ is = _NOP
+ it = "A"
+ return 0
+ }
+ is = p
+ if (p == 0 && p == "") {
+ it = "-"
+ return 0
+ }
+ if (p in _CLASSPTR) {
+ return (it = "P")
+ }
+ it = "S"
+ return 0
+}
+
+#_______________________________________________________________________
+function _istr(p)
+{
+ if (isarray(p)) {
+ is = _NOP
+ it = "A"
+ return 0
+ }
+ is = p
+ if (p == 0 && p == "") {
+ it = "-"
+ return 0
+ }
+ return (it = (p == "" ? "s" : "S"))
+}
+
+#_________________________________________________________________
+function _lengthsort(i1, v1, i2, v2)
+{
+ return ((length(i1) < length(i2) ? -1 : (length(i1) > length(i2) ? 1 : (i1 < i2 ? -1 : 1))))
+}
+
+#_________________________________________________________________
+function _lib_APPLY()
+{
+ return _ffaccr(_LIBAPI, "_lib_APPLY")
+}
+
+#_________________________________________________________________
+function _lib_BEGIN(A)
+{
+ return _ffaccr(_LIBAPI, "_lib_BEGIN", "", A)
+}
+
+#_______________________________________________________________________
+function _lib_CMDLN(t)
+{
+ return _pass(_LIBAPI["F"], "_lib_CMDLN", t)
+}
+
+#_________________________________________________________________
+function _lib_END(A)
+{
+ return _ffaccr(_LIBAPI, "_lib_END", "", A)
+}
+
+#_________________________________________________________________
+function _lib_HELP()
+{
+ return _fbaccr(_LIBAPI, "_lib_HELP")
+}
+
+#_________________________________________________________________
+function _lib_NAMEVER()
+{
+ return _fbaccr(_LIBAPI, "_lib_NAMEVER")
+}
+
+#_____________________________________________________________________________
+function _ln(t)
+{
+ return ((t ~ /\x0A$/ ? t : t _CHR["EOL"]))
+}
+
+#_________________________________________________________________
+function _log(A, p, a, B)
+{
+ if (isarray(A)) {
+ A["TIME"] = _getime()
+ A["DATE"] = _getdate()
+ if (p) {
+ _tLOG[p = _wLCHLD(p, _N())][""]
+ delete _tLOG[p][""]
+ _movarr(_tLOG[p], A)
+ return p
+ }
+ _expout("_ERRLOG: " _Zexparr(A) "\n")
+ } else {
+ B["TEXT"] = A
+ B["TYPE"] = ""
+ return _log(B, p)
+ }
+}
+
+#_________________________________________________________________
+function _lspctab(t, ts, l, l1, l2, A)
+{
+ while (match(t, /^(\t*)( *)((\t*)(.*))$/, A)) {
+ if (A[1, "length"] >= l) {
+ return substr(t, l + 1)
+ }
+ if (A[2]) {
+ if ((l1 = int(A[2, "length"] / ts)) >= (l2 = l - A[1, "length"])) {
+ return (substr(A[2], l2 * ts + 1) A[3])
+ }
+ if (! A[4]) {
+ return A[5]
+ }
+ t = A[1] _getchrln("\t", l1) A[3]
+ } else {
+ return t
+ }
+ }
+}
+
+function _mac_init()
+{
+ _MACPFX["\204"] = "_macpfx84"
+ _MACPFX[""] = "_mpupfxsubret"
+ _MACPFX84SFX["\204"] = "_macpfx84"
+ _MACPFX84SFX["\224"] = "_macsfx94"
+ _MACPFX84SFX[""] = "_mpusfxsubret"
+ _VLDMAXSTRING = 1e+06
+}
+
+function _macpfx84(F, D, C, p1, p2, p3)
+{
+ return _mpusub(_MACPFX84SFX, D, C, D[_mpuptr++], p1, p2, p3)
+}
+
+function _macsfx94(F, D, C, p1, p2, p3)
+{
+ return _mpuretsub(D, _handle8494(_mpuacc))
+}
+
+#_______________________________________________________________________
+function _movarr(D, S)
+{
+ delete D
+ D[""]
+ delete D[""]
+ _addarr(D, S)
+}
+
+function _mpu(t, F, p1, p2, p3, D, C)
+{
+ if (patsplit(t, C, /[\x84\x93\x94]/, D) > 0) {
+ _conline("CODE")
+ _conl()
+ _conl(_dumparr(C))
+ _conline("DATA")
+ _conl()
+ _conl(_dumparr(D))
+ _mpuptr = 0
+ _mpucc0 = ""
+ _mpusub(F, D, C, D[_mpuptr++], p1, p2, p3)
+ return _mpuacc
+ }
+ return t
+}
+
+#
+# /rexpstr/ -> datastr
+# (\x00\t\+)* -> 28 00 09 5B 2B 29
+#
+# unesc all non-rexp characters: replace unesc of rexp-characters but do not remove it: \* -> \*, \x2A -> \*, \052 -> \*, \\ -> \#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+function _mpudefaulthnd(F, D, C, p1, p2, p3)
+{
+ _mpuretsub(D, _mpucc0)
+}
+
+function _mpupfxsubret(F, D, C, p1, p2, p3)
+{
+ return 1
+}
+
+function _mpuretsub(D, t)
+{
+ _mpuacc = D[_mpuptr++]
+ _accmpu(D, t)
+ return 1
+}
+
+function _mpusfxsubret(F, D, C, p1, p2, p3)
+{
+ return -1
+}
+
+function _mpusub(F, D, C, d, p1, p2, p3, q)
+{
+ q = D[_ARRLEN]
+ if (_VLDMAXSTRING < length(d)) {
+ D[--D[_ARRLEN]] = d
+ _mpuacc = ""
+ } else {
+ _mpuacc = d
+ }
+ d = _mpucc0
+ _conl("_mpusub enter: in `" _mpuacc "' / _mpuptr=" _mpuptr "'")
+ do {
+ if ((_mpucc0 = C[_mpuptr]) in F) {
+ if (isarray(F[_mpucc0])) {
+ _mpufn0 = F[_mpucc0]
+ }
+ _conl("FN: `" _mpucc0 "' > CALL: `" _mpufn0 "' : _mpuacc=" _mpuacc "'")
+ } else {
+ _mpufn0 = "_mpudefaulthnd"
+ }
+ } while (! _accmpu(D, _mpuacc, @_mpufn0(F, D, C, p1, p2, p3)))
+ if (_mpufn0 == -1) {
+ _conl("WARNING: unclosed expression: `" d _mpuacc "'")
+ _mpuacc = d _mpuacc
+ }
+ _retarrm(D, q, "", (_mpufn0 == -1 ? _th0(d, _mpusubwrng("WARNING: unclosed expression", d _mpuacc)) : ""))
+ # collect: _mpuacc=_retarr(D) _mpuacc
+ _conl("mpusub exit: _mpuacc: `" _mpuacc "'")
+}
+
+#_______________________________________________________________________
+function _n(F, v, p)
+{
+ for (p in _UIDSDEL) {
+ delete _UIDSDEL[p]
+ delete _ptr[p]
+ delete _tPREV[p]
+ delete _tPARENT[p]
+ delete _tNEXT[p]
+ delete _tFCHLD[p]
+ delete _tQCHLD[p]
+ delete _tLCHLD[p]
+ delete _TMP0[p]
+ delete _TMP1[p]
+ delete _tLINK[p]
+ delete _tCLASS[p]
+ return _nN_i0(p, F, v)
+ }
+ for (p in _UIDS) {
+ delete _UIDS[p]
+ return _nN_i0(p, F, v)
+ }
+ return _nN_i0(_tgenuid(), F, v)
+}
+
+#_____________________________________________________
+function _nN_i0(p, F, v)
+{
+ _[p][""]
+ delete _[p][""]
+ _ptr[p][""]
+ delete _ptr[p][""]
+ _TMP0[p][_ARRLEN] = _TMP1[p][_ARRLEN] = 0
+ if (isarray(F)) {
+ delete F[p]
+ if (isarray(v)) {
+ F[p][""]
+ delete F[p][""]
+ _copyarr(F[p], v)
+ } else {
+ if (! (v == 0 && v == "")) {
+ F[p] = v
+ }
+ }
+ } else {
+ if (! (F == 0 && F == "")) {
+ if (isarray(v)) {
+ _[p][F][""]
+ delete _[p][F][""]
+ _copyarr(_[p][F], v)
+ } else {
+ if (v == 0 && v == "") {
+ _mpu(F, p)
+ } else {
+ _[p][F] = v
+ }
+ }
+ }
+ }
+ return p
+}
+
+#_________________________________________________________________
+function _newclrdir(f)
+{
+ if ((f = _filerd(f)) == "") {
+ return
+ }
+ _cmd("rd " f " /S /Q 2>NUL")
+ _cmd("md " f " 2>NUL")
+ _WFILEROOTDIR[f]
+ return f
+}
+
+#_______________________________________________________________________
+function _newdir(f)
+{
+ if ((f = _filerd(f)) == "") {
+ return
+ }
+ if (! (f in _WFILEROOTDIR)) {
+ _cmd("md " f " 2>NUL")
+ _WFILEROOTDIR[f]
+ }
+ return f
+}
+
+#_______________________________________________________________________
+function _nop(p0, p1, p2, p3)
+{
+}
+
+#_____________________________________________________
+# _retarr(ARRAY,start,prefixtr,postfixtr)
+# Return string collected from elements of ARRAY.
+# The data elements in ARRAY have numeric indexes. By default it starts from element with index 1, but it is possible to locate elements starting from
+# 0,-1,-.... The last data element in the ARRAY have the highest numeric index that is stored in ARRAY[_ARRLEN].
+# Optimized for very large data size.
+#
+# IN: ARRAY - source data array(is ARRAY is not array then return undefined)
+# start - (optional) start index in ARRAY; if missed or have non-numeric value then start array index will be 1.
+# prefixst - the string that will be inserted in the begin of generated return string
+# postfix - the string that will be added at the end of generated return string
+# MOD: -
+# OUT: -
+# RETURN: undefined - if ARRAY is not array; if ARRAY is empty; if start is higher than ARRAY last element index
+# string - collected string: prefixtr-arraydata-postfixtr
+#_________________________________________________________________
+function _nretarr(A, i, v, r, q)
+{
+ if ((i = (i == "" ? 1 : i + 0)) <= (q = A[_ARRLEN])) {
+ if (i <= (r = q - 16)) {
+ _ARRSTR = A[i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i]
+ while (i < r) {
+ _ARRSTR = _ARRSTR A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i]
+ }
+ _ARRSTR = _ARRSTR A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] v _retarr_i0(A, q, i)
+ return
+ }
+ _ARRSTR = A[i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] v _retarr_i0(A, q, i)
+ return
+ }
+ _ARRSTR = v
+ return
+}
+
+#___________________________________________________________
+function _nretarrd(A, i, v, r, q)
+{
+ if ((i = (i == "" ? 1 : i + 0)) <= (q = A[_ARRLEN])) {
+ if (i <= (r = q - 16)) {
+ _ARRSTR = A[i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i]
+ while (i < r) {
+ _ARRSTR = _ARRSTR A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i]
+ }
+ _ARRSTR = _ARRSTR A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] v _retarr_i0(A, q, i)
+ } else {
+ _ARRSTR = A[i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] v _retarr_i0(A, q, i)
+ }
+ } else {
+ _ARRSTR = v
+ }
+ delete A
+ A[""]
+ delete A[""]
+}
+
+#___________________________________________________________________________________
+####################################################################################
+
+#___________________________________________________________________________________
+function _out(t, a, b)
+{
+ a = BINMODE
+ b = ORS
+ BINMODE = "rw"
+ ORS = ""
+ print(t) > _SYS_STDOUT
+ fflush(_SYS_STDOUT)
+ BINMODE = a
+ ORS = b
+ return t
+}
+
+#_________________________________________________________________
+function _outnl(t)
+{
+ return _out(t ((t ~ /\x0A$/ ? "" : _CHR["EOL"])))
+}
+
+function _p1(s1, s2, s3, s4, s5, s6, s7, s8, p1, p2, p3, p4, p5, p6, p7, p8)
+{
+ _qparamf0 = "_p" _QMAP[_qparamc1--]
+ return @_qparamf0(s1, s2, s3, s4, s5, s6, s7, s8, s1, p1, p2, p3, p4, p5, p6, p7)
+}
+
+function _p2(s1, s2, s3, s4, s5, s6, s7, s8, p1, p2, p3, p4, p5, p6, p7, p8)
+{
+ _qparamf0 = "_p" _QMAP[_qparamc1--]
+ return @_qparamf0(s1, s2, s3, s4, s5, s6, s7, s8, s2, p1, p2, p3, p4, p5, p6, p7)
+}
+
+function _p3(s1, s2, s3, s4, s5, s6, s7, s8, p1, p2, p3, p4, p5, p6, p7, p8)
+{
+ _qparamf0 = "_p" _QMAP[_qparamc1--]
+ return @_qparamf0(s1, s2, s3, s4, s5, s6, s7, s8, s3, p1, p2, p3, p4, p5, p6, p7)
+}
+
+function _p4(s1, s2, s3, s4, s5, s6, s7, s8, p1, p2, p3, p4, p5, p6, p7, p8)
+{
+ _qparamf0 = "_p" _QMAP[_qparamc1--]
+ return @_qparamf0(s1, s2, s3, s4, s5, s6, s7, s8, s4, p1, p2, p3, p4, p5, p6, p7)
+}
+
+function _p5(s1, s2, s3, s4, s5, s6, s7, s8, p1, p2, p3, p4, p5, p6, p7, p8)
+{
+ _qparamf0 = "_p" _QMAP[_qparamc1--]
+ return @_qparamf0(s1, s2, s3, s4, s5, s6, s7, s8, s5, p1, p2, p3, p4, p5, p6, p7)
+}
+
+function _p6(s1, s2, s3, s4, s5, s6, s7, s8, p1, p2, p3, p4, p5, p6, p7, p8)
+{
+ _qparamf0 = "_p" _QMAP[_qparamc1--]
+ return @_qparamf0(s1, s2, s3, s4, s5, s6, s7, s8, s6, p1, p2, p3, p4, p5, p6, p7)
+}
+
+function _p7(s1, s2, s3, s4, s5, s6, s7, s8, p1, p2, p3, p4, p5, p6, p7, p8)
+{
+ _qparamf0 = "_p" _QMAP[_qparamc1--]
+ return @_qparamf0(s1, s2, s3, s4, s5, s6, s7, s8, s7, p1, p2, p3, p4, p5, p6, p7)
+}
+
+function _p8(s1, s2, s3, s4, s5, s6, s7, s8, p1, p2, p3, p4, p5, p6, p7, p8)
+{
+ _qparamf0 = "_p" _QMAP[_qparamc1--]
+ return @_qparamf0(s1, s2, s3, s4, s5, s6, s7, s8, s8, p1, p2, p3, p4, p5, p6, p7)
+}
+
+#_______________________________________________________________________
+function _pass(A, f, t, p2, i, a)
+{
+ a = _endpass_v0
+ _endpass_v0 = ""
+ i = 1
+ while (t && i) {
+ i = ""
+ while ((i = A[i]) && t == (t = @i(f, t, p2))) {
+ }
+ }
+ if (i && _endpass_v0) {
+ A["!"] = 1
+ t = _endpass_v0
+ } else {
+ delete A["!"]
+ }
+ _endpass_v0 = a
+ return t
+}
+
+# this is somnitelno: that / / . / / com 56 / / - is the DEV...; what is DEV ??? this already PROBLEM
+#_____________________________________________________________________________
+function _patharr0(D, q, i, h, A, B)
+{
+ delete D
+ if (0 < (q = split(gensub(/\\/, "/", "G", gensub(/ *([:$\\\/]) */, "\\1", "G", gensub(/(^[ \t]+)|([ \t]+$)/, "", "G", q))), A, /\/+/, B))) {
+ if (2 > (h = length(B[1]))) {
+ D["type"] = "FILE"
+ A[1] = _patharr0_i0(A[1], D, "drive")
+ return _patharr0_i1(D, A, 1, q)
+ }
+ i = gensub(/ *([\.\?]) */, "\\1", "G", A[2])
+ IGNORECASE = 1
+ match(A[1], /^((https?)|(ftp)):$/)
+ IGNORECASE = 0
+ if (RLENGTH > 0) {
+ D["type"] = toupper(substr(A[1], 1, RLENGTH - 1))
+ _patharr0_i0(i, D, "site", "port")
+ } else {
+ if (A[1] == "") {
+ D["type"] = "UNC"
+ if (h > 2) {
+ D["host"]
+ A[2] = _patharr0_i0(A[2], D, "drive", "", "FILE")
+ return _patharr0_i1(D, A, 2, q)
+ }
+ if (i == "") {
+ return 1
+ }
+ D["host"] = i
+ A[3] = _patharr0_i0(A[3], D, "drive", "", "FILE")
+ } else {
+ D["type"] = "FILE"
+ A[1] = _patharr0_i0(A[1], D, "drive")
+ return _patharr0_i1(D, A, 1, q)
+ }
+ }
+ return _patharr0_i1(D, A, 3, q)
+ }
+}
+
+#_____________________________________________________
+function _patharr0_i0(t, D, l, r, d, i)
+{
+ if (i = index(t, ":")) {
+ if (d) {
+ D["type"] = d
+ }
+ if (i > 1) {
+ D[l] = substr(t, 1, i - 1)
+ }
+ if ((t = substr(t, i + 1)) && r) {
+ D[r] = t
+ }
+ return t
+ } else {
+ if (t && r) {
+ D[l] = t
+ }
+ }
+ return t
+}
+
+#_____________________________________________________
+function _patharr0_i1(D, A, i, q, t, c)
+{
+ if (D["type"] == "UNC") {
+ if (t = A[i++]) {
+ D[0] = (D["share"] = D[++c] = t) "/"
+ } else {
+ return 1
+ }
+ }
+ while (i < q) {
+ D[0] = D[0] (D[++c] = A[i++]) "/"
+ }
+ if (i == q) {
+ if (match(t = A[i], /\.[^\.]*$/)) {
+ if (RSTART > 1) {
+ D["name"] = substr(t, 1, RSTART - 1)
+ }
+ D["ext"] = substr(t, RSTART, RLENGTH)
+ } else {
+ if (t != "") {
+ D["name"] = t
+ }
+ }
+ }
+ return 1
+}
+
+#############################################################################
+function _pmap(m, s1, s2, s3, s4, s5, s6, s7, s8)
+{
+ if (match(m, /^([^\(]+)\(([^\)]*)\)$/, _QMAP)) {
+ _qparamf1 = _QMAP[1]
+ _QMAP[0] = "r" (_qparamc1 = split(_QMAP[2], _QMAP, ""))
+ _qparamf0 = "_p" _QMAP[_qparamc1--]
+ return @_qparamf0(s1, s2, s3, s4, s5, s6, s7, s8)
+ }
+}
+
+function _pr0(s1, s2, s3, s4, s5, s6, s7, s8, p1, p2, p3, p4, p5, p6, p7, p8)
+{
+ return @_qparamf1()
+}
+
+function _pr1(s1, s2, s3, s4, s5, s6, s7, s8, p1, p2, p3, p4, p5, p6, p7, p8)
+{
+ return @_qparamf1(p1)
+}
+
+function _pr2(s1, s2, s3, s4, s5, s6, s7, s8, p1, p2, p3, p4, p5, p6, p7, p8)
+{
+ return @_qparamf1(p1, p2)
+}
+
+function _pr3(s1, s2, s3, s4, s5, s6, s7, s8, p1, p2, p3, p4, p5, p6, p7, p8)
+{
+ return @_qparamf1(p1, p2, p3)
+}
+
+function _pr4(s1, s2, s3, s4, s5, s6, s7, s8, p1, p2, p3, p4, p5, p6, p7, p8)
+{
+ return @_qparamf1(p1, p2, p3, p4)
+}
+
+function _pr5(s1, s2, s3, s4, s5, s6, s7, s8, p1, p2, p3, p4, p5, p6, p7, p8)
+{
+ return @_qparamf1(p1, p2, p3, p4, p5)
+}
+
+function _pr6(s1, s2, s3, s4, s5, s6, s7, s8, p1, p2, p3, p4, p5, p6, p7, p8)
+{
+ return @_qparamf1(p1, p2, p3, p4, p5, p6)
+}
+
+function _pr7(s1, s2, s3, s4, s5, s6, s7, s8, p1, p2, p3, p4, p5, p6, p7, p8)
+{
+ return @_qparamf1(p1, p2, p3, p4, p5, p6, p7)
+}
+
+function _pr8(s1, s2, s3, s4, s5, s6, s7, s8, p1, p2, p3, p4, p5, p6, p7, p8)
+{
+ return @_qparamf1(p1, p2, p3, p4, p5, p6, p7, p8)
+}
+
+#_________________________________________________________________
+function _printarr(A, t, lv, r, a)
+{
+ a = PROCINFO["sorted_in"]
+ PROCINFO["sorted_in"] = "_lengthsort"
+ _printarrexp = (r ? r : "")
+ if (isarray(A)) {
+ delete _DUMPARR
+ _dumparrc = _dumparrd = ""
+ _printarr_i1(A, lv = ((lv == "" ? 16 : (lv == 0 || lv + 0 != 0 ? lv : (lv == "-*" ? -3 : (lv ~ /^\+?\*$/ ? 3 : 16))))) + 0, (lv < 0 ? -1 : 1), 0, _tabtospc(t))
+ PROCINFO["sorted_in"] = a
+ return _retarrd(_DUMPARR, _dumparrd, _dumparrd = "")
+ }
+}
+
+#___________________________________________________________
+function _printarr_i1(A, lv, ls, ln, t, t2, i, a, f)
+{
+ t2 = _getchrln(" ", length(t))
+ if (ln == lv) {
+ if (ls > 0) {
+ for (i in A) {
+ ++a
+ }
+ } else {
+ for (i in A) {
+ (isarray(A[i]) ? ++a : "")
+ }
+ }
+ if (length(_dumparrd = _dumparrd t ((a > 0 ? " ... (x" a ")" : "")) _CHR["EOL"]) > 262144) {
+ _conl(_dumparrd)
+ _dumparrd = ""
+ }
+ return
+ }
+ if (ls >= 0) {
+ for (i in A) {
+ if (! _printarrexp || i ~ _printarrexp) {
+ if (! isarray(A[i])) {
+ if (length(_dumparrd = _dumparrd ((f ? t2 : t _nop(f = 1))) "[" i "]=" A[i] "'" _CHR["EOL"]) > 262144) {
+ _conl(_dumparrd)
+ _dumparrd = ""
+ }
+ }
+ }
+ }
+ }
+ for (i in A) {
+ if (isarray(A[i])) {
+ if (! _printarrexp || i ~ _printarrexp) {
+ _printarr_i1(A[i], lv, ls, ln + ls, _th0((f ? t2 : t), f = 1) "[" i "]")
+ }
+ }
+ }
+ if (! f) {
+ if (length(_dumparrd = _dumparrd t _CHR["EOL"]) > 262144) {
+ _conl(_dumparrd)
+ _dumparrd = ""
+ }
+ }
+}
+
+function _qparam(qm, p0, p1, p2, p3, p4, p5, p6, p7)
+{
+ if (qm == qm + 0 && qm > 0) {
+ _qparamim = substr(" ", 1, qm)
+ } else {
+ if (qm != "") {
+ _qparamim = qm
+ } else {
+ _qparamim = " "
+ }
+ }
+ _qparamask = ""
+ return _qparam_i0(p0, p1, p2, p3, p4, p5, p6, p7)
+}
+
+function _qparam_i0(p0, p1, p2, p3, p4, p5, p6, p7)
+{
+ _qparama0 = substr(_qparamim, 1, 1)
+ _qparamim = substr(_qparamim, 2)
+ switch (_qparama0) {
+ case "":
+ gsub(/ +$/, "", _qparamask)
+ return length(_qparamask)
+ default:
+ if (isarray(p0)) {
+ _qparama0 = "A"
+ } else {
+ if (p0 == "" && p0 == 0) {
+ _qparama0 = " "
+ } else {
+ if (_isptr(p0)) {
+ _qparama0 = "P"
+ } else {
+ _qparama0 = "S"
+ }
+ }
+ }
+ case ".":
+ _qparamask = _qparamask _qparama0
+ return _qparam_i0(p1, p2, p3, p4, p5, p6, p7)
+ }
+}
+
+#_______________________________________________________________________
+function _qstr(t, c, A, B)
+{
+ c = ""
+ for (t = split(t, A, /[\x00-\x1F\\"]/, B); t >= 0; t--) {
+ c = _QSTR[B[t]] A[t + 1] c
+ }
+ return c
+}
+
+#_________________________________________________________________
+function _qstrq(t)
+{
+ gsub(/\\/, "\\\\", t)
+ gsub(/"/, "\\\"", t)
+ return t
+}
+
+#_____________________________________________________________________________
+function _rEG(c, t, P, a, A)
+{
+ switch (c) {
+ case "_lib_CMDLN":
+ #___________________________________________________________
+ return t
+ #_____________________________________________________
+ case "_lib_APPLY":
+ return
+ #_____________________________________________________
+ case "_lib_HELP":
+ return
+ #_____________________________________________________
+ case "_lib_NAMEVER":
+ return _ln("_reg 0.001")
+ #_____________________________________________________
+ case "_lib_BEGIN":
+ return
+ #_____________________________________________________
+ case "_lib_END":
+ return
+ }
+}
+
+#_______________________________________________________________________
+function _rFBRO(p)
+{
+ if (p) {
+ if (p in _tPARENT) {
+ return _tFCHLD[_tPARENT[p]]
+ }
+ while (p in _tPREV) {
+ p = _tPREV[p]
+ }
+ return p
+ }
+ return p
+}
+
+#_______________________________________________________________________
+function _rFCHLD(p)
+{
+ if (p && p in _tFCHLD) {
+ return _tFCHLD[p]
+ }
+ return ""
+}
+
+#_______________________________________________________________________
+function _rLBRO(p)
+{
+ if (p) {
+ if (p in _tPARENT) {
+ return _tLCHLD[_tPARENT[p]]
+ }
+ while (p in _tNEXT) {
+ p = _tNEXT[p]
+ }
+ return p
+ }
+ return p
+}
+
+#_______________________________________________________________________
+function _rLCHLD(p)
+{
+ if (p && p in _tLCHLD) {
+ return _tLCHLD[p]
+ }
+ return ""
+}
+
+#_______________________________________________________________________
+function _rLINK(p)
+{
+ return ((p in _tLINK ? _tLINK[p] : ""))
+}
+
+#_______________________________________________________________________
+function _rNEXT(p)
+{
+ if (p && p in _tNEXT) {
+ return _tNEXT[p]
+ }
+ return ""
+}
+
+#_______________________________________________________________________
+function _rPARENT(p)
+{
+ if (p && p in _tPARENT) {
+ return _tPARENT[p]
+ }
+ return ""
+}
+
+#_______________________________________________________________________
+function _rPREV(p)
+{
+ if (p && p in _tPREV) {
+ return _tPREV[p]
+ }
+ return ""
+}
+
+#_______________________________________________________________________
+function _rQBRO(p, c, p1)
+{
+ if (p) {
+ if (p in _tPARENT) {
+ return _tQCHLD[_tPARENT[p]]
+ }
+ c = 1
+ p1 = p
+ while (p1 in _tPREV) {
+ c++
+ p1 = _tPREV[p1]
+ }
+ while (p in _tNEXT) {
+ c++
+ p = _tNEXT[p]
+ }
+ return c
+ }
+ return p
+}
+
+#_______________________________________________________________________
+function _rQCHLD(p)
+{
+ if (p && p in _tQCHLD) {
+ return _tQCHLD[p]
+ }
+ return ""
+}
+
+#___________________________________________________________________________________
+# EMMULATED FUNCTIONAL FIELDS ######################################################
+
+#_____________________________________________________________________________
+function _rSQFIRST(g, p, A)
+{
+ if (isarray(A)) {
+ return _rSQFIRSTA(g, p, A)
+ }
+ _SQTOPTR[g] = p
+ _SQSTACK[g][0] = 0
+ return _rsqgetptr(g, p)
+}
+
+#_________________________________________________________________
+function _rSQFIRSTA(g, p, A)
+{
+ _SQTOPTR[g] = p
+ _SQSTACK[g][0] = 0
+ if ((p = _rsqgetptr(g, p)) in A) {
+ return p
+ }
+ return _rSQNEXTA(g, p, A)
+}
+
+#_______________________________________________________________________
+function _rSQNEXT(g, p, A)
+{
+ if (isarray(A)) {
+ return _rSQNEXTA(g, p, A)
+ }
+ return _rsqnext_i0(g, p)
+}
+
+#_________________________________________________________________
+function _rSQNEXTA(g, p, A)
+{
+ if (p == _SQTOPTR[g]) {
+ if (_SQSTACK[g][0] > 0) {
+ _SQTOPTR[g] = _SQSTACK[g][_SQSTACK[g][0]--]
+ return _rSQNEXTA(g, _SQSTACK[g][_SQSTACK[g][0]--], A)
+ }
+ return
+ }
+ while (p in _tNEXT) {
+ if ((p = _rsqgetptr(g, _tNEXT[p])) in A) {
+ return p
+ }
+ }
+ return ((p in _tPARENT ? _rSQNEXTA(g, _tPARENT[p], A) : ""))
+}
+
+function _rconl(t)
+{
+ _rprt = _rprt _ln(t)
+}
+
+function _rconline(t)
+{
+ _rprt = _rprt _ln((t = " " t " ") _getchrln("_", _CON_WIDTH - length(t) - 1))
+}
+
+#___________________________________________________________
+function _rd_shortcut(D, f)
+{
+ if ((_shrtcutf0 = _filepath(f)) && _shortcut_nerr(_shrtcuta0 = _cmd(_shortcut_fpath " /A:Q /F:\"" _shrtcutf0 "\" 2>&1"), _shrtcutf0)) {
+ ERRNO = ""
+ split(_shrtcuta0, _SHRTCUTA0, /\x0D?\x0A/)
+ for (_shrtcuta0 in _SHRTCUTA0) {
+ for (f in _SHORTCUTRSTRUC) {
+ if (match(_SHRTCUTA0[_shrtcuta0], "^" f)) {
+ D[_SHORTCUTRSTRUC[f]] = substr(_SHRTCUTA0[_shrtcuta0], 1 + RLENGTH)
+ }
+ }
+ }
+ }
+ return ((ERRNO ? ERRNO = "read shortcut: " ERRNO : _NOP))
+}
+
+#_______________________________________________________________________
+function _rdfile(f, i, A)
+{
+ if ((f = _filerdne(f)) == "" || _filene(f) == "") {
+ ERRNO = "Filename error"
+ return
+ }
+ _fio_cmda = RS
+ RS = ".{1,}"
+ _fio_cmdb = BINMODE
+ BINMODE = "rw"
+ ERRNO = RT = _NUL
+ getline RS < f
+ BINMODE = _fio_cmdb
+ RS = _fio_cmda
+ if (ERRNO == "") {
+ close(f)
+ }
+ if (ERRNO == "") {
+ return RT
+ }
+ return (RT = _NOP)
+}
+
+####################################################################################
+# PUBLIC:
+#_____________________________________________________________________________
+# fn _th0,_th1,_th2,_th3
+# USAGE:
+# _th0(p1,p2,p3,p4)
+#
+# Each of this functions can have up to 4 parameters.
+# _th0(p1,p2,p3,p4) return 1st parameter (p1)
+# _th1(p1,p2,p3,p4) return 2nd parameter (p2)
+# _th2(p1,p2,p3,p4) return 3rd parameter (p3)
+# _th3(p1,p2,p3,p4) return 4th parameter (p4)
+#_____________________________________________________________________________
+# fn _nop(p1,p2,p3,p4,p5,p6,p7,p8)
+# USAGE:
+# _nop()
+#
+# Does not do any action. No result returned. Up to 8 parameters.
+#_____________________________________________________________________________
+# fn _exit(c)
+# USAGE:
+# _exit(code)
+#
+# This function do the same as GAWK-operator `exit code'.
+#_____________________________________________________________________________
+# fn _getdate()
+# fn _getime()
+# fn _getsecond()
+# fn _getsecondsync()
+function _rdreg(D, p)
+{
+ _rdregp0 = "reg query \"" p "\" /S /reg:64 2>NUL"
+ _rdregfld = _rdregkey = 0
+ _rdregq0 = split(gensub(/[\x0D?\x0A]{2,}/, _CHR["EOL"], "G", _cmd(_rdregp0)), _RDREGA0, /\x0D?\x0A/)
+ while (_rdregq0 > 0) {
+ _rdreg_i0(D)
+ }
+ return (_rdregfld + _rdregkey)
+}
+
+#___________________________________________________________
+function _rdreg_i0(D, A)
+{
+ while (_rdregq0 > 0) {
+ if (match(_rdregp0 = _RDREGA0[_rdregq0--], / (.*) REG_((SZ)|(DWORD)|(QWORD)|(BINARY)|(EXPAND_SZ)|(MULTI_SZ)) (.*)$/, A)) {
+ if (! _rdreg_i0(D)) {
+ ++_rdregfld
+ D[_rdregp0 A[1] "." _RDREGTYPE[A[2]]] = A[9]
+ return
+ } else {
+ break
+ }
+ } else {
+ if (_rdregp0 ~ /^HK/) {
+ ++_rdregkey
+ return D[_rdregp0 = _rdregp0 "\\"]
+ }
+ }
+ }
+ return 1
+}
+
+#_____________________________________________________________________________________________________
+######################################################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+function _rdsafe(A, i, d)
+{
+ if (i in A) {
+ return A[i]
+ }
+ return d
+}
+
+#_______________________________________________________________________
+function _reg_check(p)
+{
+ _tframe("_reg_check_i0", p, p)
+}
+
+#_______________________________________________
+function _reg_check_i0(p, pp, p1, p2)
+{
+ if (_[p]["TYPE"] == "defreg") {
+ if (_[p]["REGPATH"] in _REG) {
+ if ("VALUE" in _[p]) {
+ if (_[p]["VALUE"] == _REG[_[p]["REGPATH"]]) {
+ _creport(p, substr("OK: REGENTRY MATCH(==" _[p]["VALUE"] "): " _[p]["REGPATH"], 1, 126))
+ } else {
+ _dllerr(p, substr("REGENTRY NOT MATCH(!=" _[p]["VALUE"] "): " _[p]["REGPATH"], 1, 126))
+ }
+ } else {
+ if (_VAR[_[p]["REGPATH"]] == _REG[_[p]["REGPATH"]]) {
+ _creport(p, substr("OK: REGPATH MATCH(==" _VAR[_[p]["REGPATH"]] "): " _[p]["REGPATH"], 1, 126))
+ } else {
+ _dllerr(p, substr("REGPATH NOT MATCH(!=" _VAR[_[p]["REGPATH"]] "): " _[p]["REGPATH"], 1, 126))
+ }
+ }
+ } else {
+ _dllerr(p, substr("REGPATH NOT FOUND: " _[p]["REGPATH"], 1, 126))
+ }
+ }
+}
+
+#_____________________________________________________
+function _registryinit()
+{
+ _registrytmpfile = _getmpfile()
+}
+
+# _rdregfld : gvar - number of readed registry fields by _rdreg()
+# _rdregkey : gvar - number of readed registry keys by _rdreg()
+#_____________________________________________________________________________
+function _regpath0(D, i, s, q, S)
+{
+ if (i = _patharr0(S, i)) {
+ if ("name" in S) {
+ D["name"] = S["name"]
+ }
+ if ("ext" in S) {
+ D["ext"] = S["ext"]
+ }
+ s = ((toupper(s = (i in S ? S[i] : "")) in _REGPATH0REGDIR ? D[++q] = _REGPATH0REGDIR[toupper(s)] : (D[++q] = _REGPATH0REGDIR[""]) "\\" (D[++q] = s))) "\\"
+ while (++i in S) {
+ s = s (D[++q] = S[i]) "\\"
+ }
+ if (s != "") {
+ D[0] = s
+ }
+ IGNORECASE = 1
+ D["hostdir"] = "\\\\" (D["host"] = ("host" in S && ("" == (i = S["host"]) || "." == i || "?" == i || "localhost" == i) ? ENVIRON["COMPUTERNAME"] : i)) "\\" s
+ IGNORECASE = 0
+ }
+}
+
+#_________________________________________________________________________________________
+function _report(p)
+{
+ _report_t0 = _reportparnt = ""
+ _report_i0(p)
+ _tframe("_report_i0", p)
+ return _report_t0
+}
+
+function _report_i0(p, p0, p1, p2)
+{
+ if (p in _tPARENT) {
+ if (_reportparnt != (_reportparnt = _tPARENT[p])) {
+ _report_t0 = _report_t0 _ln() _ln((z = "_ " _[_tPARENT[p]]["NAME"] " ") _getchrln("_", _CON_WIDTH - length(z) - 2)) _ln(_getchrln("#", _CON_WIDTH - 2)) _ln()
+ }
+ }
+ if ("ERROR" in _[p]) {
+ _report_t0 = _report_t0 _reporterr(p, _[p]["ERROR"])
+ }
+ if ("REPORT" in _[p]) {
+ _report_t0 = _report_t0 _ln(_[p]["REPORT"])
+ }
+}
+
+#___________________________________________________________________________________
+function _reporterr(p, t3, pp, t, t2)
+{
+ t = ""
+ pp = p
+ do {
+ ("NAME" in _[pp] ? t = _[pp]["NAME"] ": " t : "")
+ } while (pp = _rPARENT(pp))
+ if (match(t3, /\x00/)) {
+ return (substr(t3, 1, RSTART - 1) t substr(t3, RSTART + 1))
+ }
+ return (t t3)
+}
+
+#___________________________________________________________________________________
+####################################################################################
+
+
+
+
+#_______________________________________________________________________
+# _CHR array
+#
+# _CHR[ASC-code decimal number]=="char"
+#
+# Contains 256 elements. The index is the decimal number from 0-255.
+# The value is the single character with ASC-code equivalent to index number:
+#
+# _CHR[97] =="a" - character with ASC-code 97 is `a'
+#
+# This array is useful if you want to get character using it's ASC-code
+#_________________________________________________________________
+# _ASC array
+#
+# _ASC[char]==number: ASC-code of char
+#
+# Contains 256 elements. The index is the any single character with ASC-code \x00-\xFF.
+# The value is the number equivalent of character's ASC-code:
+#
+# _ASC["A"] ==65 - ASC-code of character `A' is 65
+#
+# This array is useful if you want to get ASC-code of the character.
+#_________________________________________________________________
+# _QASC array
+#
+# _QASC[char]=="string: octal ASC-code of char in 3-digit octal format"
+#
+# Contains 256 elements. The index is the any single charcter with ASC-code \x00-\xFF.
+# The value is the octal number equivalent of character's ASC-code in fixed-length - 3-digit - string:
+#
+# _QASC["!"] =="041" - ASC-code of character `!' is 33(decimal) == 41(in octal)
+# _QASC["\x0D"] =="015"
+#
+# This array is useful when some type of string escape conversion is performed. It allows quickly get
+# replace string for the characters that can be specified only by character code in result string:
+#
+# "\x0D" -> "\\015"
+#_______________________________________________________________________
+
+
+
+
+
+
+
+####################################################################################
+# PUBLIC:
+#_____________________________________________________________________________
+# fn _getchrln(ptt,len)
+#_____________________________________________________________________________
+# fn _tabtospc(src,tabstep,xcoord)
+####################################################################################
+
+#_____________________________________________________________________________
+function _retarr(A, i, p, a, q)
+{
+ if (isarray(A)) {
+ i = (i == "" ? 0 : i + 0)
+ q = A[_ARRLEN] + 0
+ if (i < q) {
+ return (p A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] _retarr_i0(A, q, i, a))
+ }
+ }
+}
+
+function _retarr_i0(A, q, i, a)
+{
+ if (i < q) {
+ return (A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] A[++i] _retarr_i0(A, q, i, a))
+ }
+ while (q < i) {
+ delete A[++q]
+ }
+ return a
+}
+
+#_________________________________________________________________
+function _retarrd(A, v, i)
+{
+ if (1 in A) {
+ return (A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] A[9] A[10] A[11] A[12] A[13] A[14] A[15] A[16] (((i = 17) in A ? _retarrd_i0(A, i) v : v)))
+ }
+ delete A
+ return v
+}
+
+#_____________________________________________________
+function _retarrd_i0(A, i)
+{
+ if (i in A) {
+ return (A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] A[i++] ((i in A ? _retarrd_i0(A, i) : "")))
+ }
+ delete A
+}
+
+#_______________________________________________________________________
+########################################################################
+#EXPERIMENTAL
+
+function _rexpfn(R, t, p)
+{
+ _REXPFN[""] = ""
+ while (t) {
+ t = _rxpfn(R, t, p)
+ }
+ return _REXPFN[""]
+}
+
+function _rexpfnend(t)
+{
+ _REXPFN[""] = t
+}
+
+#_____________________________________________________________________________
+function _rexpstr(r, i, c, A)
+{
+ c = split(r, A, "")
+ r = ""
+ for (i = 1; i <= c; i++) {
+ r = r _REXPSTR[A[i]]
+ }
+ return r
+}
+
+#_____________________________________________________________________________
+function _rexpstr_i0(t, A, p0)
+{
+ return (_REXPSTR[t] = "\\" t)
+}
+
+#___________________________________________________________
+function _rmtsharerr(h, t)
+{
+ gsub(/[\x0D\x0A]+/, "", t)
+ if (t ~ /^The command failed: 53/) {
+ ERRNO = "host not found: \\\\" h
+ } else {
+ ERRNO = t ": \\\\" h
+ }
+}
+
+function _rpp(q, D, S)
+{
+ _conl()
+ _conline(q)
+ _conl()
+ _regpath0(D, q)
+ #_conl(_dumparr(D))
+
+ _conl(_ln("DEST:") _dumparr(D))
+ _conl()
+ return q
+}
+
+#_________________________________________________________________________________________
+function _rrdreg(DD, p, k, t, v, c, i, q, tT, A, B, C, D)
+{
+ if (! _registrytmpfile) {
+ _registryinit()
+ }
+ _cmd("regedit /E \"" _registrytmpfile "\" \"" p "\" 2>&1")
+ q = patsplit(gensub(/[\x00\xFF\xFE]+/, "", "G", _rdfile(_registrytmpfile)), A, /\x0D?\x0A\[[^\]]+\]\x0D?\x0A/, B)
+ for (i = 1; i <= q; i++) {
+ p = gensub(/(^[ \t\x0D\x0A]*\[)|((\\)\\+)|(\][ \t\x0D\x0A]*$)/, "\\3", "G", A[i])
+ DD[p "\\"]
+ delete C[split(B[i], C, /[\x0D\x0A]+/)]
+ for (c = 1; c in C; c++) {
+ tt = tt C[c]
+ if (gsub(/\\$/, "", tt)) {
+ continue
+ }
+ if (tt == "") {
+ continue
+ }
+ if (match(_th0(tt, tt = ""), /((^"(([^\\"]|\\.)*)")|(@))=(("(([^\\"]|\\.)*)")|(dword:([[:xdigit:]]{8}))|(hex(\(([27b])\))?:(.*)))$/, D)) {
+ if (D[7]) {
+ t = "STR"
+ v = _unstr(D[8])
+ } else {
+ if (D[10]) {
+ t = "W32"
+ v = D[11]
+ } else {
+ v = D[15]
+ if (D[13]) {
+ switch (D[14]) {
+ case "2":
+ t = "XSZ"
+ break
+ case "7":
+ t = "MSZ"
+ break
+ default:
+ t = "W64"
+ }
+ } else {
+ t = "BIN"
+ }
+ }
+ }
+ DD[gensub(/(\\)\\+/, "\\1", "G", p "\\" _unstr(D[3] ((D[5] ? "(Default)" : ""))) "." t)] = v
+ } else {
+ _fatal("regedit: unknown output format(" c "): `" C[c] "'")
+ }
+ }
+ }
+}
+
+#_________________________________________________________________
+function _rsqgetptr(g, p, A)
+{
+ if (p in _tLINK) {
+ _SQSTACK[g][++_SQSTACK[g][0]] = p
+ _SQSTACK[g][++_SQSTACK[g][0]] = _SQTOPTR[g]
+ while ((p = _tLINK[p]) in _tLINK) {
+ _con(".")
+ }
+ _SQTOPTR[g] = p
+ }
+ if (p in _tFCHLD) {
+ return _rsqgetptr(g, _tFCHLD[p])
+ }
+ return p
+}
+
+#___________________________________________________________
+function _rsqnext_i0(g, p)
+{
+ if (p == _SQTOPTR[g]) {
+ if (_SQSTACK[g][0] > 0) {
+ _SQTOPTR[g] = _SQSTACK[g][_SQSTACK[g][0]--]
+ return _rsqnext_i0(g, _SQSTACK[g][_SQSTACK[g][0]--])
+ }
+ return
+ }
+ if (p in _tNEXT) {
+ return _rsqgetptr(g, _tNEXT[p])
+ }
+ return _rsqnext_i0(g, _tPARENT[p])
+}
+
+function _rtn(v, A)
+{
+ _conl()
+ _conline(_val(v) " : " _val(A))
+ _conl()
+ _rtn2(v, A)
+ _conl()
+}
+
+function _rtn2(v, A, r, t)
+{
+ r = (isarray(A) ? _typa(v, A) : _typ(v))
+ if ("`" > _t0 && _t0) {
+ _conl("ggggg")
+ }
+ t = ((r ? "TRUE" : "FALSE")) " / " ((r > 0 ? r ">0" : r "!>0")) " / " ((r + 0 > 0 ? r "+0>0" : r "+0!>0")) " / " ((r + 0 != r ? r "+0!=" r : r "+0==" r)) " / " ((r && "`" > r ? "'`'>" r " && " r : "!('`'>" r " && " r ")"))
+ _conl("`" r "' : " t)
+ return r
+}
+
+function _rxpfn(R, t, p, i, f, A)
+{
+ for (i in R) {
+ if (match(t, i, A)) {
+ f = R[i]
+ if (t != (t = @f(A, substr(t, RLENGTH + 1), p))) {
+ return t
+ }
+ }
+ }
+ return _rexpfnend(t)
+}
+
+#_____________________________________________________________________________
+function _sHARE(c, t, P, a, A)
+{
+ switch (c) {
+ case "_lib_CMDLN":
+ #___________________________________________________________
+ return t
+ #_____________________________________________________
+ case "_lib_APPLY":
+ return
+ #_____________________________________________________
+ case "_lib_HELP":
+ return
+ #_____________________________________________________
+ case "_lib_NAMEVER":
+ return _ln("_share 1.000")
+ #_____________________________________________________
+ case "_lib_BEGIN":
+ return
+ #_____________________________________________________
+ case "_lib_END":
+ return
+ }
+}
+
+#_____________________________________________________________________________
+function _sYS(c, t, P, a, A)
+{
+ switch (c) {
+ case "_lib_CMDLN":
+ #___________________________________________________________
+ return t
+ #_____________________________________________________
+ case "_lib_APPLY":
+ return
+ #_____________________________________________________
+ case "_lib_HELP":
+ return
+ #_____________________________________________________
+ case "_lib_NAMEVER":
+ return
+ #_____________________________________________________
+ case "_lib_BEGIN":
+ return
+ #_____________________________________________________
+ case "_lib_END":
+ return
+ }
+}
+
+#_______________________________________________________________________
+function _serv_check(p)
+{
+ _tframe("_serv_check_i0", p, p)
+}
+
+#_______________________________________________
+function _serv_check_i0(p, p0, p1, p2, p3, i, q, c)
+{
+ if (_[p]["TYPE"] == "defsrv") {
+ i = IGNORECASE
+ IGNORECASE = 1
+ if (match(_servoutput, roi = "\\012DISPLAY_NAME: " _torexp(_[p]["SERVNAME"]))) {
+ _creport(p, "OK: SERVICE DETECTED: " substr(_[p]["SERVNAME"], 1, 112))
+ } else {
+ _dllerr(p, "service " _[p]["SERVNAME"] " not detected")
+ }
+ }
+ IGNORECASE = i
+}
+
+#_______________________________________________________________________
+function _setarrsort(f, a)
+{
+ a = PROCINFO["sorted_in"]
+ if (! f) {
+ delete PROCINFO["sorted_in"]
+ } else {
+ PROCINFO["sorted_in"] = f
+ }
+ return a
+}
+
+#_______________________________________________________________________
+function _setmpath(p, a)
+{
+ ERRNO = ""
+ if (p && (a = _filerd(p))) {
+ if (_FILEIO_TMPRD) {
+ _FILEIO_TMPATHS[_FILEIO_TMPRD]
+ }
+ #if ( _filexist(a) ) _del(a)
+ #_cmd("rd " a " /S /Q 2>NUL"); _cmd("del " a " /Q 2>NUL")
+ return (_FILEIO_TMPRD = a)
+ } else {
+ return _warning("`" p "': cannot set temporary folder" ((ERRNO ? ": " ERRNO : "")))
+ }
+}
+
+#_________________________________________________________________________________________
+##########################################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+function _sharelist(D, h, q, c, l, A, B)
+{
+ delete D
+ c = _sharextool " \\\\" ((h == "" ? h = ENVIRON["COMPUTERNAME"] : h)) " 2>&1"
+ if (match(c = _cmd(c), /\x0AShare[^\x0A]*Remark/)) {
+ gsub(/(^[^-]*\x0D?\x0A-+\x0D?\x0A[ \t]*)|(\x0D?\x0AThe command completed successfully.*$)/, "", c)
+ l = RLENGTH - 7
+ split(c, A, /([ \t]*\x0D?\x0A)+[ \t]*/)
+ for (c in A) {
+ if (match(A[c], /((([^ \t:]+[ \t]+)*[^ \t:]+)[ \t]+)([A-Za-z])[ \t]*:/, B) && ++q) {
+ D[B[2]] = (A[c] ~ /\.\.\.$/ ? _sharepath(h, B[2]) : gensub(/[ \t\\\/]*$/, "\\\\", 1, substr(A[c], 1 + B[1, "length"], l - B[1, "length"])))
+ }
+ }
+ return q
+ }
+ return _rmtsharerr(h, c)
+}
+
+#_____________________________________________________________________________
+function _sharepath(h, s, A)
+{
+ s = _sharextool " \\\\" ((h == "" ? h = ENVIRON["COMPUTERNAME"] : h)) "\\\"" s "\" 2>&1"
+ if (match(s = _cmd(s), /\x0APath[ \t]+([^\x0D\x0A]+)/, _SHAREPATHA0)) {
+ return gensub(/[ \t\\\/]*$/, "\\\\", 1, _SHAREPATHA0[1])
+ }
+ return _rmtsharerr(h, s)
+}
+
+function _shortcut(D, S)
+{
+ if (isarray(D)) {
+ if (isarray(S)) {
+ _addarrmask(D, S, _SHORTCUTWSTRUC)
+ } else {
+ if (S == 0 && S == "") {
+ _addarrmask(D, _SHORTCUTDEFAULT, _SHORTCUTWSTRUC)
+ } else {
+ if (_isnotfileptr(S)) {
+ _addarrmask(D, _[S], _SHORTCUTWSTRUC)
+ } else {
+ if (_rd_shortcut(D, S)) {
+ return
+ }
+ }
+ }
+ }
+ } else {
+ if (D == 0 && D == "") {
+ return _NOP
+ } else {
+ if (_isnotfileptr(D)) {
+ if (isarray(S)) {
+ _addarrmask(_[D], S, _SHORTCUTWSTRUC)
+ } else {
+ if (S == 0 && S == "") {
+ _addarrmask(_[D], _SHORTCUTDEFAULT, _SHORTCUTWSTRUC)
+ } else {
+ if (_isnotfileptr(S)) {
+ _addarrmask(_[D], _[S], _SHORTCUTWSTRUC)
+ } else {
+ if (_rd_shortcut(_[D], S)) {
+ return
+ }
+ }
+ }
+ }
+ } else {
+ if (isarray(S) && _wr_shortcut(D, S)) {
+ return
+ } else {
+ if (S == 0 && S == "" && _wr_shortcut(D, _SHORTCUTDEFAULT)) {
+ return
+ } else {
+ if (_isnotfileptr(S) && _wr_shortcut(D, _[S])) {
+ return
+ } else {
+ if (_rd_shortcut(_SHRTCUTA1, S) || _wr_shortcut(D, _SHRTCUTA1)) {
+ return
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return 1
+}
+
+#________________________________________________
+function _shortcut_init(A, B, q)
+{
+ _SHORTCUTERR[2] = "file not found"
+ _SHORTCUTERR[3] = "no such filepath"
+ _SHORTCUTERR["The system cannot find the file specified."] = "no such filepath"
+ _SHORTCUTERR[5] = "file is folder"
+ _SHORTCUTERR["Access is denied."] = "file is folder"
+ _SHORTCUTERR[123] = "filepath syntax error"
+ _SHORTCUTERR["The filename, directory name, or volume label syntax is incorrect."] = "filepath syntax error"
+ q = "target\t\t\t/T:\t\t\t\tTargetPath=\t\t\t\t\ttarget?\t\t\t;\t\t\t_target\t\t\t\t\t\t\tTargetPathExpanded=\t\t\t\t\t\t\t;\t\t\tparameters\t\t\t/P:\t\t\t\tArguments=\t\t\t\t\tparaneters?\t\t\t;\t\t\t_parameters\t\t\t\t\t\t\tArgumentsExpanded=\t\t\t\t\t\t\t;\t\t\tstartdir\t\t\t/W:\t\t\t\tWorkingDirectory=\t\t\t\tstartdir?\t\t\t;\t\t\t_startdir\t\t\t\t\t\t\tWorkingDirectoryExpanded=\t\t\t\t\t\t;\t\t\trunstyle\t\t\t/R:\t\t\t\tRunStyle=\t\t\t\t\t1\t\t\t\t;\t\t\ticon,index\t\t\t/I:\t\t\t\tIconLocation=\t\t\t\ticon,index?\t\t\t;\t\t\txicon,index\t\t\t\t\t\t\tIconLocationExpanded=\t\t\t\t\t\t\t;\t\t\tshortcut key\t\t/H:\t\t\t\tHotKey=\t\t\t\t\t0\t\t\t\t;\t\t\tdescription\t\t\t/D:\t\t\t\tDescription=\t\t\t\t_env4: default shortcut\t"
+ split(q, _SHRTCUTA0, /[ \t]*;[ \t]*/)
+ for (q in _SHRTCUTA0) {
+ if (match(_SHRTCUTA0[q], /^([^\t]+)\t+([^\t]+)(\t+([^\t]+)(\t+([^\t]+))?)?/, B)) {
+ if (B[3] == "") {
+ _SHORTCUTRSTRUC[B[2]] = B[1]
+ } else {
+ if (B[5] == "") {
+ _SHORTCUTWSTRUC[_SHORTCUTRSTRUC[B[4]] = B[1]] = B[2]
+ delete _SHORTCUTDEFAULT[B[1]]
+ } else {
+ _SHORTCUTWSTRUC[_SHORTCUTRSTRUC[B[4]] = B[1]] = B[2]
+ _SHORTCUTDEFAULT[B[1]] = B[6]
+ }
+ }
+ } else {
+ _fatal("_shortcut.init: _shortcut_struc: syntax error: `" _SHRTCUTA0[q] "'")
+ }
+ }
+ _SHRTCUTA1[""]
+ delete _SHRTCUTA1[""]
+ _shortcut_fpath = "\\\\localhost\\eGAWK\\LIB\\_shortcut\\_shortcut.exe"
+}
+
+#_____________________________________________________
+function _shortcut_nerr(t, s, A)
+{
+ if (match(t, /\x0ASystem error (-?[0-9]+)[^\x0D\x0A]*[\x0D\x0A]+([^\x0D\x0A]+)/, A)) {
+ ERRNO = ((A[1] in _SHORTCUTERR ? _SHORTCUTERR[A[1]] : (A[2] in _SHORTCUTERR ? _SHORTCUTERR[A[2]] : tolower(gensub(/^(The )?(((.*)\.$)|(.*[^\.]$))/, "\\4\\5", "G", A[2])) "(" A[1] ")"))) ((s ? ": `" s "'" : ""))
+ } else {
+ return 1
+ }
+}
+
+function _split_regpath()
+{
+ _rpp(" / / / / ")
+ _rpp(" / / / / huj ")
+ _rpp(" / / / / huj / ")
+ _rpp(" / / / / huj / pizda.TSR ")
+ _rpp(" / / / / hklm ")
+ _rpp(" / / / / hklm / ")
+ _rpp(" / / / / hklm / huj ")
+ _rpp(" / / / / hklm / huj / ")
+ _rpp(" / / / / hklm / huj / \tpizda.TSR ")
+ _conl()
+ _conl("########################################################################################")
+ _conl()
+ _rpp(" / / / / hklm / software / altiris / fi le . ex t ")
+ _rpp(" / / . / / hkcr / software / altiris / fi le . ex t ")
+ _rpp(" / / ? / / hKcU / software / altiris / fi le . ex t ")
+ _rpp(" / / lOcAlHoSt / / hKu / software / altiris / fi le . ex t ")
+ _rpp(" / / ho st / / hKcc / software / altiris / fi le . ex t ")
+ _rpp(" / / ho st / / hKPd / software / altiris / fi le . ex t ")
+ _conl()
+ _conl("########################################################################################")
+ _conl()
+}
+
+function _splitpath_test()
+{
+ _conl()
+ _conl("########################################################################################")
+ _conl()
+ _fpp(" ")
+ _fpp(" fi le . ex t ")
+ _fpp(" di r0 / / ")
+ _fpp(" di r0 / / fi le . ex t ")
+ _fpp(" / ")
+ _fpp(" / fi le . ex t ")
+ _fpp(" / di r0 / / ")
+ _fpp(" / di r0 / / fi le . ex t ")
+ _conl()
+ _conl("########################################################################################")
+ _conl()
+ _fpp(" c : ")
+ _fpp(" c : fi le . ex t ")
+ _fpp(" c : di r0 / / ")
+ _fpp(" c : di r0 / / fi le . ex t ")
+ _fpp(" c : / / ")
+ _fpp(" c : / / fi le . ex t ")
+ _fpp(" c : / / di r0 / / ")
+ _fpp(" c : / / di r0 / / fi le . ex t ")
+ _conl()
+ _conl("########################################################################################")
+ _conl()
+ _fpp(" / / ")
+ _fpp(" / / ho st . hs t ")
+ _fpp(" / / ho st / / ")
+ _fpp(" / / ho st / / fi le . ex t ")
+ _fpp(" / / ho st / / di r0 / / ")
+ _fpp(" / / ho st / / di r0 / / fi le . ex t ")
+ _conl()
+ _conl("########################################################################################")
+ _conl()
+ _fpp(" / / ho st / / c : ")
+ _fpp(" / / ho st / / c : fi le . ex t ")
+ _fpp(" / / ho st / / c : di r0 / / ")
+ _fpp(" / / ho st / / c : di r0 / / fi le . ex t ")
+ _fpp(" / / ho st / / c : / / ")
+ _fpp(" / / ho st / / c : / / fi le . ex t ")
+ _fpp(" / / ho st / / c : / / di r0 / / ")
+ _fpp(" / / ho st / / c : / / di r0 / / fi le . ex t ")
+ _conl()
+ _conl("########################################################################################")
+ _conl()
+ _fpp(" http : / / / ")
+ _fpp(" http : / / / si te . ex t ")
+ _fpp(" http : / / / si te / / ")
+ _fpp(" http : / / / si te / / fi le . ex t ")
+ _fpp(" http : / / / si te / / di r0 / / ")
+ _fpp(" http : / / / si te / / di r0 / / fi le . ex t ")
+ _conl()
+ _conl("########################################################################################")
+ _conl()
+ _fpp(" ftp : / / / : po rt ")
+ _fpp(" ftp : / / / si te . ex t : po rt ")
+ _fpp(" ftp : / / / si te : po rt / / ")
+ _fpp(" ftp : / / / si te : po rt / / fi le . ex t ")
+ _fpp(" ftp : / / / si te : po rt / / di r0 / / ")
+ _fpp(" ftp : / / / si te : po rt / / di r0 / / fi le . ex t ")
+ _conl()
+ _conl("## //. ######################################################################################")
+ _conl()
+ _fpp(" / / . ")
+ _fpp(" / / . / / ")
+ _fpp(" / / . / / com 56 ")
+ _fpp(" / / . / / com 56 / / ")
+ _fpp(" / / . / / c : ")
+ _fpp(" / / . / / c : / / ")
+ _fpp(" / / . / / c : com 56 ")
+ _fpp(" / / . / / c : com 56 / / ")
+ _fpp(" / / . / / c : / / com 56 ")
+ _fpp(" / / . / / c : / / com 56 / / ")
+ _conl()
+ _conl("## //? ######################################################################################")
+ _conl()
+ _fpp(" / / ? ")
+ _fpp(" / / ? / / ")
+ _fpp(" / / ? / / com 56 ")
+ _fpp(" / / ? / / com 56 / / ")
+ _fpp(" / / ? / / c : ")
+ _fpp(" / / ? / / c : / / ")
+ _fpp(" / / ? / / c : com 56 ")
+ _fpp(" / / ? / / c : com 56 / / ")
+ _fpp(" / / ? / / c : / / com 56 ")
+ _fpp(" / / ? / / c : / / com 56 / / ")
+ _conl()
+ _conl("########################################################################################")
+ _conl()
+ _fpp(" / / / ")
+ _fpp(" / / / . hs t ")
+ _fpp(" / / / / fi le . ex t ")
+ _fpp(" / / / / di r0 / / ")
+ _fpp(" / / / / di r0 / / di r1 / fi le . ex t ")
+ _fpp(" / / / / c : ")
+ _fpp(" / / / / c : fi le . ex t ")
+ _fpp(" / / / / c : di r0 / / ")
+ _fpp(" / / / / c : di r0 / / fi le . ex t ")
+ _fpp(" / / / / c : / / ")
+ _fpp(" / / / / c : / / fi le . ex t ")
+ _fpp(" / / / / c : / / di r0 / / ")
+ _fpp(" / / / / c : / / di r0 / / fi le . ex t ")
+ _conl()
+ _conl("########################################################################################")
+ _conl()
+ return
+}
+
+#_______________________________________________________________________
+function _splitstr(A, t, r)
+{
+ if (_istr(t)) {
+ if (_splitstr_i0(A, t) > 0) {
+ return _splitstrp0
+ }
+ if (_istr(r)) {
+ return _splitstr_i0(A, r)
+ }
+ } else {
+ if (it == "A") {
+ if (length(t) > 0) {
+ _movarr(A, t)
+ return (0 - length(A))
+ }
+ }
+ _istr(r)
+ }
+ if (it == "A") {
+ if (length(r) > 0) {
+ _movarr(A, r)
+ return (0 - length(A))
+ }
+ }
+}
+
+#_____________________________________________________
+function _splitstr_i0(A, t, C)
+{
+ if (2 > (_splitstrq0 = patsplit(t, _SPLITSTRA0, /([^,\xB4]*\xB4.)*[^,\xB4]*/))) {
+ _splitstrq0 = split(gensub(/\xB4(.)/, "\\1", "G", t), _SPLITSTRA0, "")
+ }
+ delete A
+ _splitstri0 = _splitstrp0 = 0
+ while (_splitstri0++ < _splitstrq0) {
+ if ((t = gensub(/\xB4(.)/, "\\1", "G", _SPLITSTRA0[_splitstri0])) in C || t == "") {
+ continue
+ }
+ C[A[++_splitstrp0] = t]
+ }
+ return _splitstrp0
+}
+
+#_______________________________________________
+function _strtorexp(t)
+{
+ gsub(/[\\\.\?\*\+\-\(\)\{\}\[\]\^\$\/\|]/, "\\\\&", t)
+ t = split(t, _TOREXP_STRA, /[\x00-\x1F]/, _TOREXP_STRB)
+ _torexp_strt0 = ""
+ for (_torexp_stri0 = 1; _torexp_stri0 < t; _torexp_stri0++) {
+ _torexp_strt0 = _torexp_strt0 _TOREXP_STRA[_torexp_stri0] "\\" _QASC[_TOREXP_STRB[_torexp_stri0]]
+ }
+ return (_torexp_strt0 _TOREXP_STRA[_torexp_stri0])
+}
+
+function _subseqoff(r, B)
+{
+ patsplit(r, B, /\x84[^\x94]*\x94/)
+ return gensub(/\x84[^\x94]*\x94/, "\204", "G", r)
+}
+
+function _subseqon(B, r, F, f, s, e, q, i, A)
+{
+ q = split(r, A, /\x84/)
+ r = ""
+ f = F[""]
+ for (i = 1; i < q; i++) {
+ s = substr(e = B[i], 2, 1)
+ #_conl("curr r==`" r "': A[" i "]=`" A[i] "'")
+ #s=s in F ? _th0(F[s],_conl("handler `" F[s] "' for `" s "' ost=`" substr(e,3,length(e)-3) "'")) : _th0(F[""],_conl("default handler for `" s "'"))
+ s = (s in F ? F[s] : F[""])
+ #_conl("`" f "'")
+ r = r (@f(A[i])) (@s(substr(e, 3, length(e) - 3)))
+ }
+ return (r (@f(A[i])))
+}
+
+#_____________________________________________________________________________
+# _rdreg(ARRAY,reg_path)
+# Import into ARRAY the content of the whole registree tree with the higher point specified by reg_path.
+# ARRAY will be filled by the strings with following format:
+#
+# HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\GnuWin32\CoreUtils\5.3.0\pck\InstallPath.STR=C:\Program Files (x86)\GnuWin32
+# where:
+# HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\GnuWin32\CoreUtils\5.3.0\pck <- REG KEY PATH
+# InstallPath <- DATA FIELD
+# STR <- TYPE
+# C:\Program Files (x86)\GnuWin32 <- VALUE
+# TYPE:
+# STR - REG_SZ (String Value)
+# W32 - REG_DWORD (DWORD (32-bit) Value)
+# W64 - REG_QWORD (QWORD (64-bit) Value)
+# BIN - REG_BINARY (Binary Value)
+# XSZ - REG_EXPAND_SZ (Expandable String Value)
+# MSZ - REG_MULTI_SZ (Multi-String Value)
+#_________________________________________________________________________________________
+
+
+
+
+# HKCR HKEY_CLASSES_ROOT
+# HKCU HKEY_CURRENT_USER
+# HKLM HKEY_LOCAL_MACHINE
+# HKU HKEY_USERS
+# HKCC HKEY_CURRENT_CONFIG
+# HKPD HKEY_PERFORMANCE_DATA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#___________________________________________________________________________________
+####################################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+function _sysinfo(D, h)
+{
+ h = "wmic /NODE: \"" h "\" OS 2>NUL"
+ if (split(_cmd(h), _SYSINFOA0, /[\x0D\x0A]+/) == 3) {
+ _sysinfol0 = length(h = _SYSINFOA0[2]) + 1
+ _sysinfoq0 = _sysinfoq1 = split(_SYSINFOA0[1], _SYSINFOA0, / +/, _SYSINFOB0)
+ while (--_sysinfoq0 > 0) {
+ D[_sysinfof0] = gensub(/^ +| +$/, "", "G", substr(h, _sysinfol0 = _sysinfol0 - (_sysinfol1 = length(_sysinfof0 = _SYSINFOA0[_sysinfoq0]) + length(_SYSINFOB0[_sysinfoq0])), _sysinfol1))
+ }
+ return (_sysinfoq1 - 1)
+ }
+}
+
+#########################################################
+function _tOBJ(c, t, P)
+{
+ switch (c) {
+ case "_lib_CMDLN":
+ #___________________________________________________________
+ return t
+ #___________________________________________________________
+ case "_lib_APPLY":
+ return
+ #___________________________________________________________
+ case "_lib_HELP":
+ return
+ #___________________________________________________________
+ case "_lib_NAMEVER":
+ return _ln("_tOBJ 3.0")
+ #___________________________________________________________
+ case "_lib_BEGIN":
+ return
+ #___________________________________________________________
+ case "_lib_END":
+ return
+ #___________________________________________________________
+ case "_lib_CLEANUP":
+ return _tOBJ_CLEANUP()
+ }
+}
+
+#_______________________________________________________________________
+function _tOBJ_CLEANUP(p)
+{
+ for (p in UIDSDEL) {
+ delete _ptr[p]
+ delete _tPREV[p]
+ delete _tPARENT[p]
+ delete _tNEXT[p]
+ delete _tFCHLD[p]
+ delete _tQCHLD[p]
+ delete _tLCHLD[p]
+ delete _TMP0[p]
+ delete _TMP1[p]
+ delete _tLINK[p]
+ delete _tCLASS[p]
+ }
+}
+
+#_______________________________________________________________________
+function _tabtospc(t, ts, xc, a, c, n, A, B)
+{
+ if (! ts) {
+ ts = _TAB_STEP_DEFAULT
+ }
+ c = split("." t, A, /\t+/, B)
+ A[1] = substr(A[1], 2)
+ t = ""
+ for (n = 1; n <= c; n++) {
+ t = t A[n] _getchrln(" ", (xc = length(B[n]) * ts + int((a = xc + length(A[n])) / ts) * ts) - a)
+ }
+ return t
+}
+
+#___________________________________________________________________________________
+####################################################################################
+
+
+
+
+
+
+
+function _tapi(p, f, p0, p1, p2, p3, c)
+{
+ c = p
+ do {
+ if (f in _[c]["API"]) {
+ f = _[c]["API"][f]
+ return @f(p, p0, p1, p2, p3)
+ }
+ c = _[c]["CLASS"]
+ } while ("CLASS" in _[c])
+}
+
+#_____________________________________________________________________________
+function _tbframe(f, p, p0, p1)
+{
+ delete _t_ENDF[++_t_ENDF[0]]
+ f = (p ? _tbframe_i0(f, p, p0, p1) : "")
+ --_t_ENDF[0]
+ return f
+}
+
+#___________________________________________________________
+function _tbframe_i0(f, p, p0, p1, a)
+{
+ while (p in _tLINK) {
+ p = _tLINK[p]
+ }
+ return ((p in _tLCHLD ? _tmbframe(f, _tLCHLD[p], p0, p1) : @f(p, p0, p1)))
+}
+
+#_______________________________________________________________________
+function _tbframex(f, p, p0, p1)
+{
+ delete _t_ENDF[++_t_ENDF[0]]
+ f = (p ? _tbframex_i0(f, p, p0, p1) : "")
+ --_t_ENDF[0]
+ return f
+}
+
+#___________________________________________________________
+function _tbframex_i0(f, p, p0, p1)
+{
+ while (p in _tLINK) {
+ p = _tLINK[p]
+ }
+ return ((p in _tLCHLD ? _tmbframex(f, _tLCHLD[p], p0, p1) : @f(p, p0, p1)))
+}
+
+#_____________________________________________________________________________
+function _tbpass(f, p, p0, p1)
+{
+ delete _t_ENDF[++_t_ENDF[0]]
+ f = (p ? _tbpass_i0(f, p, p0, p1) : "")
+ --_t_ENDF[0]
+ return f
+}
+
+#___________________________________________________________
+function _tbpass_i0(f, p, p0, p1, a)
+{
+ while (p in _tLINK) {
+ p = _tLINK[p]
+ }
+ return ((p in _tLCHLD ? _tmbpass(f, _tLCHLD[p], p0, p1) : @f(p, p0, p1)))
+}
+
+#_____________________________________________________________________________
+function _tbpassx(f, p, p0, p1)
+{
+ delete _t_ENDF[++_t_ENDF[0]]
+ f = (p ? _tbpassx_i0(f, p, p0, p1) : "")
+ --_t_ENDF[0]
+ return f
+}
+
+#___________________________________________________________
+function _tbpassx_i0(f, p, p0, p1)
+{
+ while (p in _tLINK) {
+ p = _tLINK[p]
+ }
+ return ((p in _tLCHLD ? _tmbpassx(f, _tLCHLD[p], p0, p1) : @f(p, p0, p1)))
+}
+
+#_____________________________________________________________________________
+function _tbrochld(p, f, pp)
+{
+ if (p) {
+ if (p in _tFCHLD) {
+ f = _tFCHLD[p]
+ delete _tFCHLD[p]
+ delete _tLCHLD[p]
+ if (p in _tPARENT) {
+ pp = _tPARENT[p]
+ delete _tPARENT[p]
+ if (p in _tPREV) {
+ _tNEXT[_tPREV[f] = _tPREV[p]] = f
+ delete _tPREV[p]
+ } else {
+ _tFCHLD[pp] = f
+ }
+ for (; f in _tNEXT; f = _tNEXT[f]) {
+ _tPARENT[f] = pp
+ }
+ _tPARENT[f] = pp
+ if (p in _tNEXT) {
+ _tPREV[_tNEXT[f] = _tNEXT[p]] = f
+ delete _tNEXT[p]
+ } else {
+ _tLCHLD[pp] = f
+ }
+ _tQCHLD[pp] = _tQCHLD[pp] + _tQCHLD[p] - 1
+ delete _tQCHLD[p]
+ return f
+ } else {
+ delete _tQCHLD[p]
+ if (p in _tPREV) {
+ _tNEXT[_tPREV[f] = _tPREV[p]] = f
+ delete _tPREV[p]
+ }
+ for (; f in _tNEXT; f = _tNEXT[f]) {
+ delete _tPARENT[f]
+ }
+ delete _tPARENT[f]
+ if (p in _tNEXT) {
+ _tPREV[_tNEXT[f] = _tNEXT[p]] = f
+ delete _tNEXT[p]
+ }
+ return f
+ }
+ } else {
+ if (p in _tPARENT) {
+ pp = _tPARENT[p]
+ delete _tPARENT[p]
+ if (p in _tPREV) {
+ if (p in _tNEXT) {
+ _tNEXT[_tPREV[f] = _tPREV[p]] = f = _tNEXT[p]
+ delete _tNEXT[p]
+ } else {
+ delete _tNEXT[_tLCHLD[pp] = _tPREV[p]]
+ }
+ delete _tPREV[p]
+ _tQCHLD[pp]--
+ } else {
+ if (p in _tNEXT) {
+ delete _tPREV[_tFCHLD[pp] = _tNEXT[p]]
+ delete _tNEXT[p]
+ _tQCHLD[pp]--
+ } else {
+ delete _tFCHLD[pp]
+ delete _tLCHLD[pp]
+ delete _tQCHLD[pp]
+ }
+ }
+ } else {
+ if (p in _tPREV) {
+ if (p in _tNEXT) {
+ _tNEXT[_tPREV[f] = _tPREV[p]] = f = _tNEXT[p]
+ delete _tNEXT[p]
+ } else {
+ delete _tNEXT[_tPREV[p]]
+ }
+ delete _tPREV[p]
+ } else {
+ if (p in _tNEXT) {
+ delete _tPREV[_tNEXT[p]]
+ delete _tNEXT[p]
+ }
+ }
+ }
+ }
+ }
+ return p
+}
+
+#_________________________________________________________________
+function _tbrunframe(f, p, p0, p1)
+{
+ return _tbframe((f ? f : "_trunframe_i0"), p, p0, p1)
+}
+
+#_________________________________________________________________
+function _tbrunframex(f, p, p0, p1)
+{
+ return _tbframex((f ? f : "_trunframe_i0"), p, p0, p1)
+}
+
+#_________________________________________________________________
+function _tbrunpass(f, p, p0, p1)
+{
+ return _tbpass((f ? f : "_trunframe_i0"), p, p0, p1)
+}
+
+#_________________________________________________________________
+function _tbrunpassx(f, p, p0, p1)
+{
+ return _tbpassx((f ? f : "_trunframe_i0"), p, p0, p1)
+}
+
+#_____________________________________________________________________________
+function _tdel(p, i)
+{
+ if (p in _) {
+ _texclude(p)
+ for (i in _ptr[p]) {
+ if (isarray(_ptr[p][i])) {
+ _tdel_i1(_ptr[p][i])
+ } else {
+ if (i = _ptr[p][i]) {
+ _tdel(i)
+ }
+ }
+ }
+ if (p in _tFCHLD) {
+ i = _tFCHLD[p]
+ do {
+ i = ((i in _tNEXT ? _tNEXT[i] : "")) _tdel_i0(i)
+ } while (i)
+ }
+ delete _[p]
+ _UIDSDEL[p]
+ }
+}
+
+#_____________________________________________________
+function _tdel_i0(p, i)
+{
+ for (i in _ptr[p]) {
+ if (isarray(_ptr[p][i])) {
+ _tdel_i1(_ptr[p][i])
+ } else {
+ if (i = _ptr[p][i]) {
+ _tdel(i)
+ }
+ }
+ }
+ if (p in _tFCHLD) {
+ i = _tFCHLD[p]
+ do {
+ i = ((i in _tNEXT ? _tNEXT[i] : "")) _tdel_i0(i)
+ } while (i)
+ }
+ delete _[p]
+ _UIDSDEL[p]
+}
+
+#_____________________________________________________
+function _tdel_i1(A, i)
+{
+ for (i in A) {
+ if (isarray(A[i])) {
+ _tdel_i1(A[i])
+ } else {
+ if (i = A[i]) {
+ _tdel(i)
+ }
+ }
+ }
+}
+
+#_____________________________________________________________________________
+function _tdelete(p, v)
+{
+ if (p) {
+ _wLCHLD(_tDELPTR, p)
+ }
+ return v
+}
+
+#_________________________________________________________________
+function _tdelitem(p)
+{
+ if (p) {
+ if ("HOST" in _PTR[p] && "ITEMNAME" in _[p]) {
+ return _wLCHLD(_PTR[_PTR[p]["HOST"]]["ITEM"][_[p]["ITEMNAME"]], p)
+ }
+ _tdelete(p)
+ return p
+ }
+}
+
+#_______________________________________________________________________
+function _tend(a, b)
+{
+ if (b == "") {
+ return (_t_ENDF[_t_ENDF[0]] = a)
+ } else {
+ return (_t_ENDF[_t_ENDF[0] + a] = b)
+ }
+}
+
+#_____________________________________________________________________________
+function _texclude(p, v, pp)
+{
+ if (p in _) {
+ if (p in _tPARENT) {
+ pp = _tPARENT[p]
+ delete _tPARENT[p]
+ if (p in _tPREV) {
+ if (p in _tNEXT) {
+ _tPREV[_tNEXT[v] = _tNEXT[p]] = v = _tPREV[p]
+ delete _tNEXT[p]
+ } else {
+ delete _tNEXT[_tLCHLD[pp] = _tPREV[p]]
+ }
+ delete _tPREV[p]
+ } else {
+ if (p in _tNEXT) {
+ delete _tPREV[_tFCHLD[pp] = _tNEXT[p]]
+ delete _tNEXT[p]
+ } else {
+ delete _tFCHLD[pp]
+ delete _tLCHLD[pp]
+ delete _tQCHLD[pp]
+ return p
+ }
+ }
+ --_tQCHLD[pp]
+ } else {
+ if (p in _tPREV) {
+ if (p in _tNEXT) {
+ _tPREV[_tNEXT[v] = _tNEXT[p]] = v = _tPREV[p]
+ delete _tNEXT[p]
+ } else {
+ delete _tNEXT[_tPREV[p]]
+ }
+ delete _tPREV[p]
+ } else {
+ if (p in _tNEXT) {
+ delete _tPREV[_tNEXT[p]]
+ delete _tNEXT[p]
+ }
+ }
+ }
+ return p
+ }
+}
+
+# _tDLINK progressive development: concrete _tDLINK function\processing algo; all frame's families support
+#_____________________________________________________________________________
+function _tframe(fF, p, p0, p1, p2)
+{
+ delete _t_ENDF[++_t_ENDF[0]]
+ p = (_isptr(p) ? (isarray(fF) ? _tframe_i1(fF, p, p0, p1, p2) : _tframe_i0(fF, p, p0, p1, p2)) : "")
+ --_t_ENDF[0]
+ return p
+}
+
+#_____________________________________________________________________________
+function _tframe0(f, p, p0, p1, p2, p3, A)
+{
+ if (_isptr(p)) {
+ if (isarray(f)) {
+ return _tframe0_i0(f, p)
+ }
+ _tframex_p0(A, f, 0)
+ return _th0(_tframe0_i0(A, p), --_TEND[_ARRLEN])
+ }
+}
+
+#_______________________________________________
+function _tframe0_i0(A, p, f)
+{
+ if (p in _tLINK) {
+ _tframe_link = p
+ if ("`" in A) {
+ f = A["`"]
+ while (p in _tLINK) {
+ @f(p = _tLINK[p])
+ }
+ } else {
+ while (p in _tLINK) {
+ p = _tLINK[p]
+ }
+ }
+ } else {
+ _tframe_link = ""
+ }
+ if (p in _tFCHLD) {
+ return (_tframe0_i2(A, "^", p) _tframe0_i1(A, _tFCHLD[p]))
+ }
+ return _tframe0_i2(A, ".", p)
+}
+
+#_______________________________________________
+function _tframe0_i1(A, p)
+{
+ if (_TEND[_ARRLEN] in _TEND) {
+ return
+ }
+ if (p in _tNEXT) {
+ return (_tframe0_i0(A, p) _tframe0_i1(A, _tNEXT[p]))
+ }
+ return _tframe0_i0(A, p)
+}
+
+#_______________________________________________
+function _tframe0_i2(A, m, p)
+{
+ _tframe_dlink = p
+ while (p in _tDLINK) {
+ p = _tDLINK[p]
+ }
+ if (m in A) {
+ if (m "~" in A) {
+ if (! (_TYPEWORD in _[p]) || A[m "~"] !~ _[p][_TYPEWORD]) {
+ return
+ }
+ }
+ m = A[m]
+ return @m(p)
+ }
+}
+
+#_________________________________________________________________
+function _tframe1(f, p, p0, p1, p2, p3, A)
+{
+ if (_isptr(p)) {
+ if (isarray(f)) {
+ return _tframe1_i0(f, p, p0)
+ }
+ _tframex_p0(A, f, 1)
+ return _th0(_tframe1_i0(A, p, p0), --_TEND[_ARRLEN])
+ }
+}
+
+#_______________________________________________
+function _tframe1_i0(A, p, p0)
+{
+ _tframe_link = p
+ while (p in _tLINK) {
+ p = _tLINK[p]
+ }
+ if (p in _tFCHLD) {
+ return (_tframe1_i2(A, "^", p, p0) _tframe1_i1(A, _tFCHLD[p], p0))
+ }
+ return _tframe1_i2(A, ".", p, p0)
+}
+
+#_______________________________________________
+function _tframe1_i1(A, p, p0)
+{
+ if (_TEND[_ARRLEN] in _TEND) {
+ return
+ }
+ if (p in _tNEXT) {
+ return (_tframe1_i0(A, p, p0) _tframe1_i1(A, _tNEXT[p], p0))
+ }
+ return _tframe1_i0(A, p, p0)
+}
+
+#_______________________________________________
+function _tframe1_i2(A, m, p, p0)
+{
+ _tframe_dlink = p
+ while (p in _tDLINK) {
+ p = _tDLINK[p]
+ }
+ if (m in A) {
+ if (m "~" in A) {
+ if (! (_TYPEWORD in _[p]) || A[m "~"] !~ _[p][_TYPEWORD]) {
+ return
+ }
+ }
+ m = A[m]
+ return @m(p, p0)
+ }
+}
+
+#_________________________________________________________________
+function _tframe2(f, p, p0, p1, p2, p3, A)
+{
+ if (_isptr(p)) {
+ if (isarray(f)) {
+ return _tframe2_i0(f, p, p0, p1)
+ }
+ _tframex_p0(A, f, 2)
+ return _th0(_tframe2_i0(A, p, p0, p1), --_TEND[_ARRLEN])
+ }
+}
+
+#_______________________________________________
+function _tframe2_i0(A, p, p0, p1)
+{
+ _tframe_link = p
+ while (p in _tLINK) {
+ p = _tLINK[p]
+ }
+ if (p in _tFCHLD) {
+ return (_tframe2_i2(A, "^", p, p0, p1) _tframe2_i1(A, _tFCHLD[p], p0, p1))
+ }
+ return _tframe2_i2(A, ".", p, p0, p1)
+}
+
+#_______________________________________________
+function _tframe2_i1(A, p, p0, p1)
+{
+ if (_TEND[_ARRLEN] in _TEND) {
+ return
+ }
+ if (p in _tNEXT) {
+ return (_tframe2_i0(A, p, p0, p1) _tframe2_i1(A, _tNEXT[p], p0, p1))
+ }
+ return _tframe2_i0(A, p, p0, p1)
+}
+
+#_______________________________________________
+function _tframe2_i2(A, m, p, p0, p1)
+{
+ _tframe_dlink = p
+ while (p in _tDLINK) {
+ p = _tDLINK[p]
+ }
+ if (m in A) {
+ if (m "~" in A) {
+ if (! (_TYPEWORD in _[p]) || A[m "~"] !~ _[p][_TYPEWORD]) {
+ return
+ }
+ }
+ m = A[m]
+ return @m(p, p0, p1)
+ }
+}
+
+#_________________________________________________________________
+function _tframe3(f, p, p0, p1, p2, p3, A)
+{
+ if (_isptr(p)) {
+ if (isarray(f)) {
+ return _tframe3_i0(f, p, p0, p1, p2)
+ }
+ _tframex_p0(A, f, 3)
+ return _th0(_tframe3_i0(A, p, p0, p1, p2), --_TEND[_ARRLEN])
+ }
+}
+
+#_______________________________________________
+function _tframe3_i0(A, p, p0, p1, p2)
+{
+ _tframe_link = p
+ while (p in _tLINK) {
+ p = _tLINK[p]
+ }
+ if (p in _tFCHLD) {
+ return (_tframe3_i2(A, "^", p, p0, p1, p2) _tframe3_i1(A, _tFCHLD[p], p0, p1, p2))
+ }
+ return _tframe3_i2(A, ".", p, p0, p1, p2)
+}
+
+#_______________________________________________
+function _tframe3_i1(A, p, p0, p1, p2)
+{
+ if (_TEND[_ARRLEN] in _TEND) {
+ return
+ }
+ if (p in _tNEXT) {
+ return (_tframe3_i0(A, p, p0, p1, p2) _tframe3_i1(A, _tNEXT[p], p0, p1, p2))
+ }
+ return _tframe3_i0(A, p, p0, p1, p2)
+}
+
+#_______________________________________________
+function _tframe3_i2(A, m, p, p0, p1, p2)
+{
+ _tframe_dlink = p
+ while (p in _tDLINK) {
+ p = _tDLINK[p]
+ }
+ if (m in A) {
+ if (m "~" in A) {
+ if (! (_TYPEWORD in _[p]) || A[m "~"] !~ _[p][_TYPEWORD]) {
+ return
+ }
+ }
+ m = A[m]
+ return @m(p, p0, p1, p2)
+ }
+}
+
+#_________________________________________________________________
+function _tframe4(f, p, p0, p1, p2, p3, A)
+{
+ if (_isptr(p)) {
+ if (isarray(f)) {
+ return _tframe4_i0(f, p, p0, p1, p2, p3)
+ }
+ _tframex_p0(A, f, 4)
+ return _th0(_tframe4_i0(A, p, p0, p1, p2, p3), --_TEND[_ARRLEN])
+ }
+}
+
+#_______________________________________________
+function _tframe4_i0(A, p, p0, p1, p2, p3)
+{
+ _tframe_link = p
+ while (p in _tLINK) {
+ p = _tLINK[p]
+ }
+ if (p in _tFCHLD) {
+ return (_tframe4_i2(A, "^", p, p0, p1, p2, p3) _tframe4_i1(A, _tFCHLD[p], p0, p1, p2, p3))
+ }
+ return _tframe4_i2(A, ".", p, p0, p1, p2, p3)
+}
+
+#_______________________________________________
+function _tframe4_i1(A, p, p0, p1, p2, p3)
+{
+ if (_TEND[_ARRLEN] in _TEND) {
+ return
+ }
+ if (p in _tNEXT) {
+ return (_tframe4_i0(A, p, p0, p1, p2, p3) _tframe4_i1(A, _tNEXT[p], p0, p1, p2, p3))
+ }
+ return _tframe4_i0(A, p, p0, p1, p2, p3)
+}
+
+#_______________________________________________
+function _tframe4_i2(A, m, p, p0, p1, p2, p3)
+{
+ _tframe_dlink = p
+ while (p in _tDLINK) {
+ p = _tDLINK[p]
+ }
+ if (m in A) {
+ if (m "~" in A) {
+ if (! (_TYPEWORD in _[p]) || A[m "~"] !~ _[p][_TYPEWORD]) {
+ return
+ }
+ }
+ m = A[m]
+ return @m(p, p0, p1, p2, p3)
+ }
+}
+
+#___________________________________________________________
+function _tframe_i0(f, p, p0, p1, p2, a)
+{
+ while (p in _tLINK) {
+ p = _tLINK[p]
+ }
+ return ((p in _tFCHLD ? _tmframe_i0(f, _tFCHLD[p], p0, p1, p2) : (p in _tDLINK ? @f(_tDLINK[p], p0, p1, p2) : @f(p, p0, p1, p2))))
+}
+
+#___________________________________________________________
+function _tframe_i1(F, p, p0, p1, p2, a)
+{
+ while (p in _tLINK) {
+ p = _tLINK[p]
+ }
+ return ((p in _tFCHLD ? (("." in F ? _th1(a = F["."], @a(p, p0, p1, p2)) : "")) _tmframe_i1(F, _tFCHLD[p], p0, p1, p2) : (">" in F ? _th1(a = F[">"], (p in _tDLINK ? @a(_tDLINK[p], p0, p1, p2) : @a(p, p0, p1, p2))) : "")))
+}
+
+#_______________________________________________________________________
+function _tframex(f, p, p0, p1)
+{
+ delete _t_ENDF[++_t_ENDF[0]]
+ f = (p ? _tframex_i0(f, p, p0, p1) : "")
+ --_t_ENDF[0]
+ return f
+}
+
+#___________________________________________________________
+function _tframex_i0(f, p, p0, p1)
+{
+ while (p in _tLINK) {
+ p = _tLINK[p]
+ }
+ return ((p in _tFCHLD ? _tmframex(f, _tFCHLD[p], p0, p1) : @f(p, p0, p1)))
+}
+
+#_____________________________________________________
+function _tframex_p0(A, f, q, i, B, C)
+{
+ _tframe_qparam = q
+ delete _TEND[++_TEND[_ARRLEN]]
+ if (match(f, /\~(.*)$/, B)) {
+ A["^~"] = A[".~"] = B[1]
+ f = substr(f, 1, RSTART - 1)
+ }
+ A["."] = A["^"] = f
+ return
+ q = split(f, B, /;/)
+ i = 0
+ while (i < q) {
+ _tframex_p1(A, C[i])
+ while (++i <= q) {
+ _tframex_p1(A, C[i], B[i])
+ }
+ }
+}
+
+#_______________________________________________
+function _tframex_p1(A, v, i, r, B)
+{
+ gsub(/[ \t]+/, "", v)
+ while (match(v, /^([^~]*)~\/(([^\/\\]*\\.)*[^\/\\]*)\//, B)) {
+ v = B[1] substr(v, RSTART + RLENGTH)
+ r = B[2]
+ }
+ if (i == "") {
+ if (v != "") {
+ A["."] = v
+ delete A["`"]
+ delete A["^"]
+ }
+ if (r != "") {
+ A[".~"] = A["`~"] = A["^~"] = r
+ }
+ } else {
+ if (match(v, /!/)) {
+ delete A[i]
+ } else {
+ A[i] = v
+ if (r != "") {
+ A[i "~"] = r
+ }
+ }
+ }
+}
+
+#_____________________________________________________
+# F v action
+#-----------------------------------------------------
+# - * no additional action
+# A B delete A[p] and define A[p] as array; copy array B to array A[p]
+# A - delete A[p]
+# A "*" delete A[p]; A[p]="*"
+# "*" B define _[p]["*"] as array; copy array B to array _[p]["*"]
+# "*" - run _mpu program "*" for `p
+# "*0" "*1" _[p]["*0"]="*1"
+#___________________________________________________________
+function _tgenuid(c)
+{
+ for (_uidcntr in _UIDARR1) {
+ delete _UIDARR1[_uidcntr]
+ for (c in _UIDARR0) {
+ _UIDS[_uidcntr c]
+ }
+ delete _UIDS[_uidcntr c]
+ return (_uidcntr c)
+ }
+ return _fatal("_tUID: Out of UID range")
+}
+
+#_____________________________________________________
+function _tgenuid_init(a, b, A)
+{
+ _ptrlength = 4
+ a = "\222\223\224\225\226\227\230\231\232" "\240\241\242\243\244\245\246\247" "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277" "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317" "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
+ split(a, A, "")
+ for (a in A) {
+ for (b in A) {
+ _UIDARR0[A[a] A[b]] _UIDARR1[A[a] A[b]]
+ }
+ }
+ _uidcntr = A[a] A[b]
+}
+
+# if ( F in _TCLASS ) { _[p]["CLASS"]=_TCLASS[F]; _tapi(p); return p }
+# # ??? _mpu(F,p) ???
+# return p }
+# _[p][F]=v; return p }
+
+#_______________________________________________________________________
+function _tgetitem(p, n, a, b)
+{
+ if (p) {
+ if (isarray(_PTR[p]["ITEM"]) && n in _PTR[p]["ITEM"]) {
+ a = _PTR[p]["ITEM"][n]
+ } else {
+ a = _PTR[p]["ITEM"][n] = _N()
+ }
+ if (! (b = _rFCHLD(a))) {
+ b = _wLCHLD(a, _N())
+ _PTR[b]["HOST"] = p
+ _[b]["ITEMNAME"] = n
+ }
+ return b
+ }
+}
+
+#_________________________________________________________________
+function _tgetsp(p)
+{
+ return _tSTACK[p][0]
+}
+
+####################################################################################
+
+#_____________________________________________________________________________
+function _th0(p, p1, p2, p3)
+{
+ return p
+}
+
+#_________________________________________________________________
+function _th1(p0, p, p2, p3)
+{
+ return p
+}
+
+#_________________________________________________________________
+function _th10(p0, p1)
+{
+ return (p1 p0)
+}
+
+#_________________________________________________________________
+function _th2(p0, p1, r, p3)
+{
+ return p
+}
+
+#_________________________________________________________________
+function _th3(p0, p1, p2, r)
+{
+ return p
+}
+
+#_________________________________________________________________
+function _tifend(l)
+{
+ return ((_t_ENDF[0] + l in _t_ENDF ? (_t_ENDF[_t_ENDF[0] + l] ? _t_ENDF[_t_ENDF[0] + l] : 1) : ""))
+}
+
+# test _tbrochld fn; develope tOBJ r\w func specification for brochld func
+
+#_________________________________________________________________
+function _tinit_i0(D, S, i)
+{
+ for (i in S) {
+ if (isarray(S[i])) {
+ if (! isarray(D[i][""])) {
+ delete D[i]
+ D[i][""]
+ delete D[i][""]
+ }
+ _N_i0(D[i], S[i])
+ } else {
+ if (isarray(D[i])) {
+ delete D[i]
+ }
+ D[i] = S[i]
+ }
+ }
+}
+
+#_______________________________________________________________________
+########################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#_______________________________________________________________________
+# _N(arr\str\mpuptr,val) \ _n(arr\str\mpuptr,val)
+# This functions create new object and return ptr.
+# _n() - creates object from list of deleted objects or if it's empty create new one, while _N() always create new one
+# It is strongly recommended to use _N() for the objects that have some data outside of standart object arrays. Or - make routines
+# that will clear outsided object data in case if object deleting.
+#
+# IN: arr\str\mpu,val - (both missed) just create obj and return ptr
+# arr,val - create object and write arr[ptr]=val
+# str,val - create object and write _[ptr][str]=val
+# mpuptr - NOT ALLOWED (val missed) create object and run MPU-code specified by mpuptr with created object ptr as primary parameter
+# MOD: -
+# OUT: -
+# RETURN: ptr - pointer to newly created object
+#_________________________________________________________________
+# _tdel(ptr)
+# This function exclude object from it's current structure and delete it. ptr can be later used by function: _n() for creating new object
+# Also same story will occured with all chields and subchields of object specified by ptr.
+# ??? What happened with linked py _ptr[ptr] objects ???
+#
+# IN: ptr - pointer to object that will deleted
+# MOD: -
+# OUT: -
+# RETURN: undefined
+#_________________________________________________________________
+# _isptr(ptr)
+# This function checks: is ptr is the object pointer that is currently exist?
+# Unescaped remained data will be in data of src_dst_ptr.
+#
+# IN: ptr - string that will be tested
+# MOD: -
+# OUT: -
+# RETURN: undefined - if ptr is not pointer to exist object
+# ptr - if ptr is the pointer to exist object
+#_________________________________________________________________
+
+
+
+#_________________________________________________________________
+#
+# TO DESIGN:
+#
+# create basic objectapi interface support
+# modify everywhere checking ptr not by `if ( ptr )...', but by `if ( ptr in _ )...'
+# _TMP0, _TMP1 name change to something like _DATA name ???
+# think about redesigning routines for not depending if ptr is exist in tsysarrs: reason: performance\light code
+
+
+
+
+
+
+
+
+
+
+
+function _tlist(L, p, f)
+{
+ _tlisti1 = _tlisti0 = L[_ARRLEN] + 0
+ if (f == 0 && f == "") {
+ _tlist_i0(L, p)
+ } else {
+ _tlistf0 = (f in _TAPI ? _TAPI[f] : f)
+ _tlist_i1(L, p)
+ }
+ return (_tlisti0 - _tlisti1)
+}
+
+function _tlist_i0(L, p, q, i)
+{
+ if (isarray(p)) {
+ q = p[_ARRLEN]
+ i = 0
+ while (i++ < q) {
+ _tlist_i0(L, p[i])
+ }
+ return
+ }
+ if (p in _) {
+ while (p in _tLINK) {
+ p = _tLINK[p]
+ }
+ L[++_tlisti0] = p
+ if (p in _tFCHLD) {
+ for (p = _tFCHLD[p]; p; p = (p in _tNEXT ? _tNEXT[p] : "")) {
+ _tlist_i0(L, p)
+ }
+ }
+ }
+}
+
+function _tlist_i1(L, p)
+{
+ if (isarray(p)) {
+ q = p[_ARRLEN]
+ i = 0
+ while (i++ < q) {
+ _tlist_i1(L, p[i])
+ }
+ return
+ }
+ if (p in _) {
+ while (p in _tLINK) {
+ p = _tLINK[p]
+ }
+ if (_tlistf0 in _[p]) {
+ L[++_tlisti0] = p
+ }
+ if (p in _tFCHLD) {
+ for (p = _tFCHLD[p]; p; p = (p in _tNEXT ? _tNEXT[p] : "")) {
+ _tlist_i1(L, p)
+ }
+ }
+ }
+}
+
+#_________________________________________________________________
+function _tmbframe(f, p, p0, p1, t)
+{
+ while (p && ! (_t_ENDF[0] in _t_ENDF)) {
+ t = t _tbframe_i0(f, p, p0, p1, p = (p in _tPREV ? _tPREV[p] : ""))
+ }
+ return t
+}
+
+#_________________________________________________________________
+function _tmbframex(f, p, p0, p1, t)
+{
+ while (p && ! (_t_ENDF[0] in _t_ENDF)) {
+ t = t _tbframex_i0(f, p, p0, p1)
+ p = (p in _tPREV ? _tPREV[p] : "")
+ }
+ return t
+}
+
+#_________________________________________________________________
+function _tmbpass(f, p, p0, p1)
+{
+ while (p && ! (_t_ENDF[0] in _t_ENDF)) {
+ p0 = _tbpass_i0(f, p, p0, p1, p = (p in _tPREV ? _tPREV[p] : ""))
+ }
+ return p0
+}
+
+#_________________________________________________________________
+function _tmbpassx(f, p, p0, p1)
+{
+ while (p && ! (_t_ENDF[0] in _t_ENDF)) {
+ p0 = _tbpassx_i0(f, p, p0, p1)
+ p = (p in _tPREV ? _tPREV[p] : "")
+ }
+ return p0
+}
+
+#_________________________________________________________________
+function _tmframe(f, p, p0, p1, p2)
+{
+ delete _t_ENDF[++_t_ENDF[0]]
+ f = (p ? _tmframe_i0(f, p, p0, p1, p2) : "")
+ --_t_ENDF[0]
+ return f
+}
+
+#___________________________________________________________
+function _tmframe_i0(f, p, p0, p1, p2, t)
+{
+ while (p && ! (_t_ENDF[0] in _t_ENDF)) {
+ t = t _tframe_i0(f, p, p0, p1, p2, p = (p in _tNEXT ? _tNEXT[p] : ""))
+ }
+ return t
+}
+
+#___________________________________________________________
+function _tmframe_i1(F, p, p0, p1, p2, t)
+{
+ while (p && ! (_t_ENDF[0] in _t_ENDF)) {
+ t = t _tframe_i1(F, p, p0, p1, p2, p = (p in _tNEXT ? _tNEXT[p] : ""))
+ }
+ return t
+}
+
+#_________________________________________________________________
+function _tmframex(f, p, p0, p1, t)
+{
+ while (p && ! (_t_ENDF[0] in _t_ENDF)) {
+ t = t _tframex_i0(f, p, p0, p1)
+ p = (p in _tNEXT ? _tNEXT[p] : "")
+ }
+ return t
+}
+
+#_________________________________________________________________
+function _tmpass(f, p, p0, p1)
+{
+ while (p && ! (_t_ENDF[0] in _t_ENDF)) {
+ p0 = _tbpass_i0(f, p, p0, p1, p = (p in _tNEXT ? _tNEXT[p] : ""))
+ }
+ return p0
+}
+
+#_________________________________________________________________
+function _tmpassx(f, p, p0, p1)
+{
+ while (p && ! (_t_ENDF[0] in _t_ENDF)) {
+ p0 = _tbpassx_i0(f, p, p0, p1)
+ p = (p in _tNEXT ? _tNEXT[p] : "")
+ }
+ return p0
+}
+
+function _torexp(r)
+{
+ return _subseqon(_TOREXPB0, gensub(/(^[ \t]+)|(([ \t]*(\\)+)+[ \t]*)|([ \t]+$)/, "\\4", "G", _subseqoff(r, _TOREXPB0)), _TOREXPFN)
+}
+
+function _torexp_cmdstr(t)
+{
+ return _strtorexp(gensub(/\^(.)/, "\\1", "G", t))
+}
+
+function _torexp_fmask(t)
+{
+ return gensub(/\\\*/, ".*", "G", gensub(/\\\?/, ".?", "G", _strtorexp(t)))
+}
+
+#_______________________________________________
+function _torexp_init()
+{
+ _TOREXPFN[""] = "_strtorexp"
+ _TOREXPFN["~"] = "_torexp_rexp"
+ _TOREXPFN["="] = "_strtorexp"
+ _TOREXPFN[">"] = "_torexp_cmdstr"
+ _TOREXPFN["#"] = "_torexp_fmask"
+ _TOREXPFN["\""] = "_torexp_dqstr"
+ _TOREXPFN["'"] = "_torexp_sqstr"
+}
+
+#_______________________________________________
+function _torexp_rexp(t)
+{
+ return t
+}
+
+#_____________________________________________________________________________
+function _tpass(f, p, p0, p1)
+{
+ delete _t_ENDF[++_t_ENDF[0]]
+ f = (p ? _tpass_i0(f, p, p0, p1) : "")
+ --_t_ENDF[0]
+ return f
+}
+
+#___________________________________________________________
+function _tpass_i0(f, p, p0, p1, a)
+{
+ while (p in _tLINK) {
+ p = _tLINK[p]
+ }
+ return ((p in _tFCHLD ? _tmpass(f, _tFCHLD[p], p0, p1) : @f(p, p0, p1)))
+}
+
+#_____________________________________________________________________________
+function _tpassx(f, p, p0, p1)
+{
+ delete _t_ENDF[++_t_ENDF[0]]
+ f = (p ? _tpassx_i0(f, p, p0, p1) : "")
+ --_t_ENDF[0]
+ return f
+}
+
+#___________________________________________________________
+function _tpassx_i0(f, p, p0, p1)
+{
+ while (p in _tLINK) {
+ p = _tLINK[p]
+ }
+ return ((p in _tFCHLD ? _tmpassx(f, _tFCHLD[p], p0, p1) : @f(p, p0, p1)))
+}
+
+#_________________________________________________________________
+function _tpop(p, aA, a)
+{
+ if ((a = _tSTACK[p][0]) > 0) {
+ _tSTACK[p][0]--
+ if (isarray(_tSTACK[p][a])) {
+ delete aA
+ _movarr(aA, _tSTACK[p][a])
+ return
+ }
+ return _tSTACK[p][a]
+ }
+ _fatal("^" p ": Out of tSTACK")
+}
+
+#_____________________________________________________________________________
+function _tpush(p, aA, a)
+{
+ if (isarray(aA)) {
+ delete _tSTACK[p][a = ++_tSTACK[p][0]]
+ _tSTACK[p][a][""]
+ delete _tSTACK[p][a][""]
+ _movarr(_tSTACK[p][a], aA)
+ return
+ }
+ delete _tSTACK[p][a = ++_tSTACK[p][0]]
+ return (_tSTACK[p][a] = aA)
+}
+
+# prefix -
+# prichr - aware character `{', `^',`]'
+# sechr - aware character `.' as the first char of sechr, and character `}'
+# suffix - aware character `]'
+# cntptr - aware character `]'
+
+function _tr(n, cs, H)
+{
+ #_tuidinitcs[p]=cs
+ #2 uidel, 5 pfx, 7 hichr,11(10) lochr,14 suffix
+ _rconline(n ": " cs)
+ _rconl()
+ if (match(cs, /^((([^\xB4:\[\|\]]*\xB4.)*[^\xB4:\[\|\]]*):)?((([^\xB4\[\|\]]*\xB4.)*[^\xB4\[\|\]]*)\[)?(([^\xB4\|\]]*\xB4.)*[^\xB4\|\]]*)?(\|(\.)?(([^\xB4\]]*\xB4.)*[^\xB4\]]*))?(\](.*))?$/, H)) {
+ _rconl("delptr: " _une(H[2]) "'")
+ _rconl("pfxstr: " _une(H[5]) "'")
+ _rconl("hichr: " _une(H[7]) "'")
+ _rconl("lochr: " _une((H[10] ? H[7] "' and " H[11] "'" : H[11] "'")))
+ _rconl("sfxstr: " _une(H[14]) "'")
+ } else {
+ _rconl("NOT MATCH!")
+ }
+ _rconl()
+}
+
+#_______________________________________________________________________
+function _trace(t, d, A)
+{
+ if (_ERRLOG_TF) {
+ A["TYPE"] = "TRACE"
+ A["TEXT"] = t
+ _log(A, d)
+ }
+}
+
+#_________________________________________________________________
+function _trunframe(f, p, p0, p1, p2)
+{
+ return _tframe((f ? f : "_trunframe_i0"), p, p0, p1, p2)
+}
+
+#_________________________________________________________________
+function _trunframe_i0(p, p0, p1, p2, f)
+{
+ if (p in _tFN) {
+ f = _tFN[p]
+ return @f(p, p0, p1, p2)
+ }
+}
+
+#_________________________________________________________________
+function _trunframex(f, p, p0, p1)
+{
+ return _tframex((f ? f : "_trunframe_i0"), p, p0, p1)
+}
+
+#_________________________________________________________________
+function _trunpass(f, p, p0, p1)
+{
+ return _tpass((f ? f : "_trunframe_i0"), p, p0, p1)
+}
+
+#_________________________________________________________________
+function _trunpassx(f, p, p0, p1)
+{
+ return _tpassx((f ? f : "_trunframe_i0"), p, p0, p1)
+}
+
+#_________________________________________________________________
+function _tsetsp(p, v)
+{
+ return (_tSTACK[p][0] = v)
+}
+
+# dptr - morg ptr; in case if object deleted then _CLASSPTR[ptr] will be deleted(object is death), but
+# _tUIDEL[_CLASSPTR[ptr]] will be created that object can be resurrected from morg
+# dptr can be any string containing any characters except `:'. It's not verified
+# pfx,sfx - uid prefix str, and uid suffix str; this strings specifies string that can be inserted before/after
+# uid generated by uid generator:
+#
+# class uid: pfx uidgen sfx
+#
+# Both can be any string(including ""), and can contains any character with B4-escaping feature.
+# Note: that this strings cannot contains "'" character: it's should be escaped by B4-escaper.
+# hstr,lstr - this values configure uid-generator itself. ther is a 3 combinations regarding its:
+#
+# hstr lstr function
+#
+# `ptr * - specify pointer to external uid-generator
+# All uids and chars will be generated by external uid-generator
+# * ^ptr - class will have it's own uid generator using external character set
+# str str - class will have it's own uid generator with it's own character set
+# character set inmplemented in hstr(high-charset) and in lstr(low-charset) in 2 ways:
+# 1) "AB" "AB01" - this mean that high-charset contain chars: `A' and `B'
+# low-charset contains chars: `A', `B', `0', `1'
+#
+# 2) "Az,By" "Ax,Bw,0v,1u" - this mean that high-charset contain chars: `Az' and `By'
+# low-charset contains chars: `Ax', `Bw', `0v', `1u'
+# Note: both: hstr and lstr cannot contain char `,' directly, but it's can uses
+# B4-escaper to escape any char including `,'
+
+
+
+# !!!! in case of using `,' in hstr/lstr - the escaped `,' will leads to interpretate hstr and lstr as divided by `,'
+# if parameters error then i should be more specific about what error in parameters detected
+# document _inituid(): parameters; document cs: uid initialization string format
+# test with escape char
+# adv hstr and lstr splitting?
+# chk if hstr len==0 ?
+# return _tclass & report error?
+# _tapi thru function
+
+# additional syntax checking ???
+# implement syntax and uid srv in docs
+# add _dumpuid() ????
+# make performance measurement
+# protection against badchar list
+# additional feature to specify _getuid() to not resurrect uid; and informative that uid was ressurected or not
+# build _defclass fn
+
+# _tuidinitcs ????
+# _tuidchrh[p]
+# _tuidchrl[p]
+# _tuidchr[p]
+# _tuidcnt[p]
+# _tUIDPFX[p]
+# _tUIDSFX[p]
+# _tUIDEL
+# _tUIDCNTH
+# _tUIDCNTL
+# _tUIDCHRL
+# _tUIDCHRH
+
+# create default class basic `new' and `del' functions
+
+
+
+function _tstini()
+{
+ _ini("uidel:pfx'hstr|lstr'sfx")
+ _ini("uidel:pfx'hstr|lstr'")
+ _ini("uidel:'hstr|lstr'sfx")
+ _ini("uidel:'hstr|lstr'")
+ _ini("uidel:pfx'hstr'sfx")
+ _ini("uidel:pfx'hstr'")
+ _ini("uidel:'hstr'sfx")
+ _ini("uidel:'hstr'")
+ _conl()
+ _conl("########################################################################################")
+ _conl()
+ _ini("pfx'hstr|lstr'sfx")
+ _ini("pfx'hstr|lstr'")
+ _ini("'hstr|lstr'sfx")
+ _ini("'hstr|lstr'")
+ _ini("pfx'hstr'sfx")
+ _ini("pfx'hstr'")
+ _ini("'hstr'sfx")
+ _ini("'hstr'")
+ _conl()
+ _conl("########################################################################################")
+ _conl()
+ _ini("uidel:pfx'`cntptr'sfx")
+ _ini("uidel:pfx'`cntptr'")
+ _ini("uidel:'`cntptr'sfx")
+ _ini("uidel:'`cntptr'")
+ _conl()
+ _conl("########################################################################################")
+ _conl()
+ _ini("pfx'`cntptr'sfx")
+ _ini("pfx'`cntptr'")
+ _ini("'`cntptr'sfx")
+ _ini("'`cntptr'")
+ _conl()
+ _conl("########################################################################################")
+ _conl()
+ _ini("uidel:pfx'^chrptr'sfx")
+ _ini("uidel:pfx'^chrptr'")
+ _ini("uidel:'^chrptr'sfx")
+ _ini("uidel:'^chrptr'")
+ _conl()
+ _conl("########################################################################################")
+ _conl()
+ _ini("pfx'^chrptr'sfx")
+ _ini("pfx'^chrptr'")
+ _ini("'^chrptr'sfx")
+ _ini("'^chrptr'")
+ _conl()
+ _conl("########################################################################################")
+ _conl()
+}
+
+function _tstv(p, A, r, f)
+{
+ if (f == "") {
+ f = "tst_splitstr"
+ }
+ @f(_NOP, A, p)
+ @f(AA0, A, p)
+ @f(AB0, A, p)
+ @f(AC0, A, p)
+ @f("", A, p)
+ @f("a", A, p)
+ @f("\264a", A, p)
+ @f("\264", A, p)
+ @f("a\264\264\264,ba\264\264\264,", A, p)
+ @f("\264,", A, p)
+ @f(",", A, p)
+ @f("\264a,", A, p)
+ @f("ab,", A, p)
+ @f("ab,\264", A, p)
+ @f("\264a\264,,ba", A, p)
+ @f(",a,,b\264,c,,\264a,,\264,,,", A, p)
+}
+
+function _typ(p)
+{
+ return (_t0 = (isarray(p) ? "#" : (p == 0 ? (p == "" ? 0 : (p in _CLASSPTR ? "`" : (p ? 3 : 4))) : (p in _CLASSPTR ? "`" : (p + 0 == p ? 5 : (p ? 3 : 2))))))
+}
+
+function _typa(p, A)
+{
+ return (_t0 = (isarray(p) ? "#" : (p == 0 ? (p == "" ? 0 : (p in A ? "`" : (p ? 3 : 4))) : (p in A ? "`" : (p + 0 == p ? 5 : (p ? 3 : 2))))))
+}
+
+#_____________________________________________________
+# _tframe0(hndstr,ptr)
+#
+#
+# IN:
+# MOD:
+# OUT:
+# RETURN:
+#
+# handler string:
+# Handler-string divides to words. Word splitter is char ";"
+#
+# Note that handler-string processed left to right. This mean that next word(more rightly) will overwrite fields implemented before(leftmost).
+# Note that if word-string contains more than one rexp-field then only last rexp-field(most rightly) will be applied.
+#_______________________________________________
+# TO DESIGN:
+#
+# 0-4: complete design of tlink handler call
+# 1-4: add new tlink handler call
+# 1-4: add new run fn (changed rexp to different for each type: see _tframe0)
+#
+# hndstr:
+# may be add rexp for each type of handler and also total rexp for all ??? ADDED (test)
+# may be add separator char ";" ??? ADDED (test)
+#_______________________________________________________________________
+function _tzend(a, b)
+{
+ if (b == 0 && b == "") {
+ return (_TEND[_TEND[_ARRLEN]] = a)
+ } else {
+ return (_TEND[_TEND[_ARRLEN] + a] = b)
+ }
+}
+
+function _uidcyc(p, i)
+{
+ _dumpuidgen(p)
+ for (i = 1; i < 64 * 8 * 6 - 1; i++) {
+ _conl(i ":" _var(_getuid(p)))
+ }
+ _dumpuidgen(p)
+}
+
+function _une(t)
+{
+ return gensub(/\xB4(.)/, "\\1", "G", t)
+}
+
+#___________________________________________________________________________________
+function _unformatrexp(t)
+{
+ _formatstrq0 = split(t, _FORMATSTRA, /(\\[0-9]{1,3})|(\\x[[:xdigit:]]+)|(\\.)/, _FORMATSTRB)
+ _formatstrs0 = ""
+ for (t = 1; t < _formatstrq0; t++) {
+ _formatstrs0 = _formatstrs0 _FORMATSTRA[t] ((_FORMATSTRB[t] in _QESCHR ? _QESCREXP[_FORMATSTRB[t]] : _QESCREXP[toupper(substr(_FORMATSTRB[t], length(_FORMATSTRB[t]) - 1))]))
+ }
+ return (_formatstrs0 _FORMATSTRA[t])
+}
+
+#___________________________________________________________
+function _unformatrexp_init(i, a)
+{
+ _formatstrs0 = "\\^$.[]|()*+?{}-sSwW<>yB`'"
+ delete _FORMATSTRB
+ for (i = 0; i < 256; i++) {
+ _QESCREXP["\\" _CHR[i]] = (index(_formatstrs0, _CHR[i]) ? "\\" _CHR[i] : _CHR[i])
+ }
+ for (i = 0; i < 256; i++) {
+ a = (index(_formatstrs0, _CHR[i]) ? "\\" : "")
+ _QESCREXP[sprintf("%.2X", i)] = a _CHR[i]
+ _QESCREXP["\\" sprintf("%.3o", i)] = a _CHR[i]
+ if (i < 8) {
+ _QESCREXP["\\" sprintf("%.1o", i)] = a _CHR[i]
+ }
+ if (i < 64) {
+ _QESCREXP["\\" sprintf("%.2o", i)] = a _CHR[i]
+ }
+ if (i < 16) {
+ _QESCREXP["\\x" sprintf("%.1X", i)] = _QESCREXP["\\x" sprintf("%.1x", i)] = a _CHR[i]
+ }
+ }
+ patsplit("a" 7 "b" 8 "f" 12 "n" 10 "r" 13 "t" 9 "v" 11, _FORMATSTRA, /[^0-9]/, _FORMATSTRB)
+ for (i in _FORMATSTRA) {
+ _QESCREXP["\\" _FORMATSTRA[i]] = _CHR[_FORMATSTRB[i] + 0]
+ }
+}
+
+#___________________________________________________________________________________
+function _unformatstr(t)
+{
+ _formatstrq0 = split(t, _FORMATSTRA, /(\\[0-9]{1,3})|(\\x[[:xdigit:]]+)|(\\.)/, _FORMATSTRB)
+ _formatstrs0 = ""
+ for (t = 1; t < _formatstrq0; t++) {
+ _formatstrs0 = _formatstrs0 _FORMATSTRA[t] ((_FORMATSTRB[t] in _QESCHR ? _QESCHR[_FORMATSTRB[t]] : _QESCHR[toupper(substr(_FORMATSTRB[t], length(_FORMATSTRB[t]) - 1))]))
+ }
+ return (_formatstrs0 _FORMATSTRA[t])
+}
+
+#___________________________________________________________
+function _unformatstr_init(i)
+{
+ for (i = 0; i < 256; i++) {
+ _QESCHR["\\" _CHR[i]] = _CHR[i]
+ }
+ for (i = 0; i < 256; i++) {
+ _QESCHR[sprintf("%.2X", i)] = _CHR[i]
+ _QESCHR["\\" sprintf("%.3o", i)] = _CHR[i]
+ if (i < 8) {
+ _QESCHR["\\" sprintf("%.1o", i)] = _CHR[i]
+ }
+ if (i < 64) {
+ _QESCHR["\\" sprintf("%.2o", i)] = _CHR[i]
+ }
+ if (i < 16) {
+ _QESCHR["\\x" sprintf("%.1X", i)] = _QESCHR["\\x" sprintf("%.1x", i)] = _CHR[i]
+ }
+ }
+ i = "a" 7 "b" 8 "f" 12 "n" 10 "r" 13 "t" 9 "v" 11
+ patsplit(i, _FORMATSTRA, /[^0-9]/, _FORMATSTRB)
+ for (i in _FORMATSTRA) {
+ _QESCHR["\\" _FORMATSTRA[i]] = _CHR[_FORMATSTRB[i] + 0]
+ }
+}
+
+#_____________________________________________________________________________
+function _uninit_del(A, i, p0)
+{
+ _del(i)
+}
+
+####################################################################################
+# PUBLIC:
+#_____________________________________________________________________________
+# var _SYS_STDOUT - (by default = "/dev/stdout") standart output pipe filename
+# var _SYS_STDERR - (by default = "/dev/stderr") standart error output pipe filename
+# var _SYS_STDCON - (by default = "CON") standart console output device
+#_____________________________________________________________________________
+# var _CHR["CR"] - return cursor to the position 0 without newline(normally ="\x0D")
+# var _CHR["EOL"] - return cursor to the position 0 & newline (MS:="\x0D\x0A" / UX:="\x0D")
+# var _CON_WIDTH - console width(columns number)
+#_____________________________________________________________________________
+# fn _cmd(c) - execute shell command c and return output
+# fn _err - output string w\o any addition into _SYS_STDERR device
+# fn _errnl - output string with addition _CHR["EOL"] at the end of the string into _SYS_STDERR device
+# fn _out - output string w\o any addition into _SYS_STDOUT device
+# fn _outnl - output string with addition _CHR["EOL"] at the end of the string into _SYS_STDOUT device
+#_____________________________________________________________________________
+# fn _con(text[,tabspace])
+# fn _conl(text[,tabspace])
+# fn _conline(text[,tabspace])
+# fn _constat(status[,tabspace])
+# fn _constatpush([status[,tabspace]])
+# fn _constatpop()
+#_______________________________________________________________________
+# var _constatstr
+####################################################################################
+
+
+function _unstr(t)
+{
+ return gensub(/\\(.)/, "\\1", "G", t)
+}
+
+#_________________________________________________________________
+function _untmp(f, a)
+{
+ if (f = filepath(f)) {
+ if (match(f, /\\$/)) {
+ _deletepfx(_FILEIO_RDTMP, a = toupper(f))
+ _deletepfx(_FILEIO_RDNETMP, a)
+ } else {
+ delete _FILEIO_RDNETMP[toupper(f)]
+ }
+ return f
+ }
+ return ""
+}
+
+#_____________________________________________________________________________
+function _val(v, t)
+{
+ if (isarray(v)) {
+ return (_dumparr(v) _ln(t))
+ }
+ if (v == 0 && v == "") {
+ return (_ln("- (ERRNO=" ERRNO ")") _ln(t))
+ }
+ return (_ln(v "'") _ln(t))
+}
+
+#_____________________________________________________________________________
+function _val0(v)
+{
+ if (isarray(v)) {
+ return _dumparr(v)
+ }
+ if (v == 0 && v == "") {
+ return "-"
+ }
+ return ("\"" v "\"")
+}
+
+#_____________________________________________________________________________
+function _var(v, t)
+{
+ if (isarray(v)) {
+ return (_dumparr(v) _ln(t))
+ }
+ if (v == 0 && v == "") {
+ return (_ln("- (ERRNO=" ERRNO ")") _ln(t))
+ }
+ return (_ln(v "'") _ln(t))
+}
+
+#_______________________________________________________________________
+function _verb(t, d, A)
+{
+ if (_ERRLOG_VF) {
+ A["TYPE"] = "VERB"
+ A["TEXT"] = t
+ _log(A, d)
+ }
+}
+
+#_________________________________________________________________
+function _wFBRO(p, v, a)
+{
+ if (p) {
+ if (v) {
+ for (a = p; a in _tPARENT; ) {
+ if ((a = _tPARENT[a]) == v) {
+ return v
+ }
+ }
+ if (p in _tPARENT) {
+ p = _tPARENT[p]
+ if (v in _tNEXT) {
+ if (v in _tPREV) {
+ _tPREV[_tNEXT[a] = _tNEXT[v]] = a = _tPREV[v]
+ delete _tPREV[v]
+ if (v in _tPARENT) {
+ if (p == (a = _tPARENT[v])) {
+ return (_tFCHLD[p] = _tPREV[_tNEXT[v] = _tFCHLD[p]] = v)
+ }
+ --_tQCHLD[a]
+ }
+ } else {
+ if (v in _tPARENT) {
+ if (p == (a = _tPARENT[v])) {
+ return v
+ }
+ delete _tPREV[_tFCHLD[a] = _tNEXT[v]]
+ --_tQCHLD[a]
+ } else {
+ delete _tPREV[_tNEXT[v]]
+ }
+ }
+ ++_tQCHLD[p]
+ return (_tFCHLD[p] = _tPREV[_tNEXT[v] = _tFCHLD[_tPARENT[v] = p]] = v)
+ } else {
+ if (v in _tPREV) {
+ if (v in _tPARENT) {
+ delete _tNEXT[_tLCHLD[a = _tPARENT[v]] = _tPREV[v]]
+ if (p == a) {
+ delete _tPREV[v]
+ return (_tFCHLD[p] = _tPREV[_tNEXT[v] = _tFCHLD[p]] = v)
+ }
+ --_tQCHLD[a]
+ } else {
+ delete _tNEXT[_tPREV[v]]
+ }
+ delete _tPREV[v]
+ } else {
+ if (v in _tPARENT) {
+ if (p == (a = _tPARENT[v])) {
+ return v
+ }
+ delete _tFCHLD[a]
+ delete _tLCHLD[a]
+ delete _tQCHLD[a]
+ }
+ }
+ ++_tQCHLD[p]
+ return (_tFCHLD[p] = _tPREV[_tNEXT[v] = _tFCHLD[_tPARENT[v] = p]] = v)
+ }
+ } else {
+ while (p in _tPREV) {
+ p = _tPREV[p]
+ }
+ if (v in _tPREV) {
+ if (v in _tPARENT) {
+ --_tQCHLD[a = _tPARENT[v]]
+ delete _tPARENT[v]
+ if (v in _tNEXT) {
+ _tNEXT[_tPREV[a] = _tPREV[v]] = a = _tNEXT[v]
+ } else {
+ delete _tNEXT[_tLCHLD[a] = _tPREV[v]]
+ }
+ } else {
+ if (v in _tNEXT) {
+ _tNEXT[_tPREV[a] = _tPREV[v]] = a = _tNEXT[v]
+ } else {
+ delete _tNEXT[_tPREV[v]]
+ }
+ }
+ delete _tPREV[v]
+ } else {
+ if (p == v) {
+ return v
+ }
+ if (v in _tPARENT) {
+ if (v in _tNEXT) {
+ delete _tPREV[_tFCHLD[a = _tPARENT[v]] = _tNEXT[v]]
+ --_tQCHLD[a]
+ } else {
+ delete _tLCHLD[a = _tPARENT[v]]
+ delete _tFCHLD[a]
+ delete _tQCHLD[a]
+ }
+ delete _tPARENT[v]
+ } else {
+ if (v in _tNEXT) {
+ delete _tPREV[_tNEXT[v]]
+ }
+ }
+ }
+ return (_tPREV[_tNEXT[v] = p] = v)
+ }
+ } else {
+ if (v == 0) {
+ return v
+ }
+ return v
+ }
+ } else {
+ if (p == 0) {
+ return v
+ }
+ if (v) {
+ return _texclude(v)
+ }
+ return v
+ }
+}
+
+#_________________________________________________________________
+function _wFCHLD(p, v, a)
+{
+ if (p) {
+ if (v) {
+ if (p == v) {
+ return v
+ }
+ for (a = p; a in _tPARENT; ) {
+ if ((a = _tPARENT[a]) == v) {
+ return v
+ }
+ }
+ if (v in _tNEXT) {
+ if (v in _tPREV) {
+ _tPREV[_tNEXT[a] = _tNEXT[v]] = a = _tPREV[v]
+ delete _tPREV[v]
+ if (v in _tPARENT) {
+ if (p == (a = _tPARENT[v])) {
+ return (_tFCHLD[p] = _tPREV[_tNEXT[v] = _tFCHLD[p]] = v)
+ }
+ --_tQCHLD[a]
+ }
+ } else {
+ if (v in _tPARENT) {
+ if (p == (a = _tPARENT[v])) {
+ return v
+ }
+ delete _tPREV[_tFCHLD[a] = _tNEXT[v]]
+ --_tQCHLD[a]
+ } else {
+ delete _tPREV[_tNEXT[v]]
+ }
+ }
+ if (p in _tFCHLD) {
+ ++_tQCHLD[p]
+ return (_tFCHLD[p] = _tPREV[_tNEXT[v] = _tFCHLD[_tPARENT[v] = p]] = v)
+ }
+ delete _tNEXT[v]
+ } else {
+ if (v in _tPREV) {
+ if (v in _tPARENT) {
+ delete _tNEXT[_tLCHLD[a = _tPARENT[v]] = _tPREV[v]]
+ if (p == a) {
+ delete _tPREV[v]
+ return (_tFCHLD[p] = _tPREV[_tNEXT[v] = _tFCHLD[p]] = v)
+ }
+ --_tQCHLD[a]
+ } else {
+ delete _tNEXT[_tPREV[v]]
+ }
+ delete _tPREV[v]
+ } else {
+ if (v in _tPARENT) {
+ if (p == (a = _tPARENT[v])) {
+ return v
+ }
+ delete _tFCHLD[a]
+ delete _tLCHLD[a]
+ delete _tQCHLD[a]
+ }
+ }
+ if (p in _tFCHLD) {
+ ++_tQCHLD[p]
+ return (_tFCHLD[p] = _tPREV[_tNEXT[v] = _tFCHLD[_tPARENT[v] = p]] = v)
+ }
+ }
+ _tQCHLD[p] = 1
+ return (_tFCHLD[_tPARENT[v] = p] = _tLCHLD[p] = v)
+ } else {
+ if (v == 0) {
+ if (p in _tFCHLD) {
+ v = _tFCHLD[p]
+ delete _tFCHLD[p]
+ delete _tLCHLD[p]
+ delete _tQCHLD[p]
+ do {
+ delete _tPARENT[v]
+ } while (v in _tNEXT && (v = _tNEXT[v]))
+ }
+ }
+ return v
+ }
+ } else {
+ if (p == 0) {
+ return v
+ }
+ return v
+ }
+}
+
+#_________________________________________________________________
+function _wLBRO(p, v, a)
+{
+ if (p) {
+ if (v) {
+ for (a = p; a in _tPARENT; ) {
+ if ((a = _tPARENT[a]) == v) {
+ return v
+ }
+ }
+ if (p in _tPARENT) {
+ p = _tPARENT[p]
+ if (v in _tPREV) {
+ if (v in _tNEXT) {
+ _tNEXT[_tPREV[a] = _tPREV[v]] = a = _tNEXT[v]
+ delete _tNEXT[v]
+ if (v in _tPARENT) {
+ if (p == (a = _tPARENT[v])) {
+ return (_tLCHLD[p] = _tNEXT[_tPREV[v] = _tLCHLD[p]] = v)
+ }
+ --_tQCHLD[a]
+ }
+ } else {
+ if (v in _tPARENT) {
+ if (p == (a = _tPARENT[v])) {
+ return v
+ }
+ delete _tNEXT[_tLCHLD[a] = _tPREV[v]]
+ --_tQCHLD[a]
+ } else {
+ delete _tNEXT[_tPREV[v]]
+ }
+ }
+ ++_tQCHLD[p]
+ return (_tLCHLD[p] = _tNEXT[_tPREV[v] = _tLCHLD[_tPARENT[v] = p]] = v)
+ } else {
+ if (v in _tNEXT) {
+ if (v in _tPARENT) {
+ delete _tPREV[_tFCHLD[a = _tPARENT[v]] = _tNEXT[v]]
+ if (p == a) {
+ delete _tNEXT[v]
+ return (_tLCHLD[p] = _tNEXT[_tPREV[v] = _tLCHLD[p]] = v)
+ }
+ --_tQCHLD[a]
+ } else {
+ delete _tPREV[_tNEXT[v]]
+ }
+ delete _tNEXT[v]
+ } else {
+ if (v in _tPARENT) {
+ if (p == (a = _tPARENT[v])) {
+ return v
+ }
+ delete _tLCHLD[a]
+ delete _tFCHLD[a]
+ delete _tQCHLD[a]
+ }
+ }
+ ++_tQCHLD[p]
+ return (_tLCHLD[p] = _tNEXT[_tPREV[v] = _tLCHLD[_tPARENT[v] = p]] = v)
+ }
+ } else {
+ while (p in _tNEXT) {
+ p = _tNEXT[p]
+ }
+ if (v in _tNEXT) {
+ if (v in _tPARENT) {
+ --_tQCHLD[a = _tPARENT[v]]
+ delete _tPARENT[v]
+ if (v in _tPREV) {
+ _tPREV[_tNEXT[a] = _tNEXT[v]] = a = _tPREV[v]
+ } else {
+ delete _tPREV[_tFCHLD[a] = _tNEXT[v]]
+ }
+ } else {
+ if (v in _tPREV) {
+ _tPREV[_tNEXT[a] = _tNEXT[v]] = a = _tPREV[v]
+ } else {
+ delete _tPREV[_tNEXT[v]]
+ }
+ }
+ delete _tNEXT[v]
+ } else {
+ if (p == v) {
+ return v
+ }
+ if (v in _tPARENT) {
+ if (v in _tPREV) {
+ delete _tNEXT[_tLCHLD[a = _tPARENT[v]] = _tPREV[v]]
+ --_tQCHLD[a]
+ } else {
+ delete _tFCHLD[a = _tPARENT[v]]
+ delete _tLCHLD[a]
+ delete _tQCHLD[a]
+ }
+ delete _tPARENT[v]
+ } else {
+ if (v in _tPREV) {
+ delete _tNEXT[_tPREV[v]]
+ }
+ }
+ }
+ return (_tNEXT[_tPREV[v] = p] = v)
+ }
+ } else {
+ if (v == 0) {
+ return v
+ }
+ return v
+ }
+ } else {
+ if (p == 0) {
+ return v
+ }
+ if (v) {
+ return _texclude(v)
+ }
+ return v
+ }
+}
+
+#_________________________________________________________________
+function _wLCHLD(p, v, a)
+{
+ if (p) {
+ if (v) {
+ if (p == v) {
+ return v
+ }
+ for (a = p; a in _tPARENT; ) {
+ if ((a = _tPARENT[a]) == v) {
+ return v
+ }
+ }
+ if (v in _tPREV) {
+ if (v in _tNEXT) {
+ _tNEXT[_tPREV[a] = _tPREV[v]] = a = _tNEXT[v]
+ delete _tNEXT[v]
+ if (v in _tPARENT) {
+ if (p == (a = _tPARENT[v])) {
+ return (_tLCHLD[p] = _tNEXT[_tPREV[v] = _tLCHLD[p]] = v)
+ }
+ --_tQCHLD[a]
+ }
+ } else {
+ if (v in _tPARENT) {
+ if (p == (a = _tPARENT[v])) {
+ return v
+ }
+ delete _tNEXT[_tLCHLD[a] = _tPREV[v]]
+ --_tQCHLD[a]
+ } else {
+ delete _tNEXT[_tPREV[v]]
+ }
+ }
+ if (p in _tLCHLD) {
+ ++_tQCHLD[p]
+ return (_tLCHLD[p] = _tNEXT[_tPREV[v] = _tLCHLD[_tPARENT[v] = p]] = v)
+ }
+ delete _tPREV[v]
+ } else {
+ if (v in _tNEXT) {
+ if (v in _tPARENT) {
+ delete _tPREV[_tFCHLD[a = _tPARENT[v]] = _tNEXT[v]]
+ if (p == a) {
+ delete _tNEXT[v]
+ return (_tLCHLD[p] = _tNEXT[_tPREV[v] = _tLCHLD[p]] = v)
+ }
+ --_tQCHLD[a]
+ } else {
+ delete _tPREV[_tNEXT[v]]
+ }
+ delete _tNEXT[v]
+ } else {
+ if (v in _tPARENT) {
+ if (p == (a = _tPARENT[v])) {
+ return v
+ }
+ delete _tLCHLD[a]
+ delete _tFCHLD[a]
+ delete _tQCHLD[a]
+ }
+ }
+ if (p in _tLCHLD) {
+ ++_tQCHLD[p]
+ return (_tLCHLD[p] = _tNEXT[_tPREV[v] = _tLCHLD[_tPARENT[v] = p]] = v)
+ }
+ }
+ _tQCHLD[p] = 1
+ return (_tLCHLD[_tPARENT[v] = p] = _tFCHLD[p] = v)
+ } else {
+ if (v == 0) {
+ if (p in _tFCHLD) {
+ v = _tFCHLD[p]
+ delete _tFCHLD[p]
+ delete _tLCHLD[p]
+ delete _tQCHLD[p]
+ do {
+ delete _tPARENT[v]
+ } while (v in _tNEXT && (v = _tNEXT[v]))
+ }
+ }
+ return v
+ }
+ } else {
+ if (p == 0) {
+ return v
+ }
+ return v
+ }
+}
+
+#_________________________________________________________________
+function _wLINK(p, v)
+{
+ return (_tLINK[p] = v)
+}
+
+#_________________________________________________________________
+function _wNEXT(p, v, a, b)
+{
+ if (p) {
+ if (v) {
+ if (p == v) {
+ return v
+ }
+ for (a = p; a in _tPARENT; ) {
+ if ((a = _tPARENT[a]) == v) {
+ return v
+ }
+ }
+ if (v in _tPREV) {
+ if (p == (a = _tPREV[v])) {
+ return v
+ }
+ if (v in _tNEXT) {
+ _tPREV[_tNEXT[a] = _tNEXT[v]] = a
+ if (v in _tPARENT) {
+ --_tQCHLD[_tPARENT[v]]
+ }
+ } else {
+ delete _tNEXT[a]
+ if (v in _tPARENT) {
+ _tLCHLD[b = _tPARENT[v]] = a
+ --_tQCHLD[b]
+ }
+ }
+ } else {
+ if (v in _tNEXT) {
+ if (v in _tPARENT) {
+ delete _tPREV[_tFCHLD[a = _tPARENT[v]] = _tNEXT[v]]
+ --_tQCHLD[a]
+ } else {
+ delete _tPREV[_tNEXT[v]]
+ }
+ } else {
+ if (v in _tPARENT) {
+ delete _tFCHLD[a = _tPARENT[v]]
+ delete _tLCHLD[a]
+ delete _tQCHLD[a]
+ }
+ }
+ }
+ if (p in _tNEXT) {
+ _tPREV[_tNEXT[v] = _tNEXT[p]] = v
+ if (p in _tPARENT) {
+ ++_tQCHLD[_tPARENT[v] = _tPARENT[p]]
+ } else {
+ delete _tPARENT[v]
+ }
+ } else {
+ delete _tNEXT[v]
+ if (p in _tPARENT) {
+ ++_tQCHLD[_tPARENT[_tLCHLD[a] = v] = a = _tPARENT[p]]
+ } else {
+ delete _tPARENT[v]
+ }
+ }
+ return (_tNEXT[_tPREV[v] = p] = v)
+ } else {
+ if (v == 0) {
+ return v
+ }
+ return v
+ }
+ } else {
+ if (p == 0) {
+ return v
+ }
+ if (v) {
+ return _texclude(v)
+ }
+ return v
+ }
+}
+
+#_________________________________________________________________
+function _wPARENT(p, v)
+{
+ return v
+}
+
+#_________________________________________________________________
+function _wPREV(p, v, a, b)
+{
+ if (p) {
+ if (v) {
+ if (p == v) {
+ return v
+ }
+ for (a = p; a in _tPARENT; ) {
+ if ((a = _tPARENT[a]) == v) {
+ return v
+ }
+ }
+ if (v in _tNEXT) {
+ if (p == (a = _tNEXT[v])) {
+ return v
+ }
+ if (v in _tPREV) {
+ _tNEXT[_tPREV[a] = _tPREV[v]] = a
+ if (v in _tPARENT) {
+ --_tQCHLD[_tPARENT[v]]
+ }
+ } else {
+ delete _tPREV[a]
+ if (v in _tPARENT) {
+ _tFCHLD[b = _tPARENT[v]] = a
+ --_tQCHLD[b]
+ }
+ }
+ } else {
+ if (v in _tPREV) {
+ if (v in _tPARENT) {
+ delete _tNEXT[_tLCHLD[a = _tPARENT[v]] = _tPREV[v]]
+ --_tQCHLD[a]
+ } else {
+ delete _tNEXT[_tPREV[v]]
+ }
+ } else {
+ if (v in _tPARENT) {
+ delete _tLCHLD[a = _tPARENT[v]]
+ delete _tFCHLD[a]
+ delete _tQCHLD[a]
+ }
+ }
+ }
+ if (p in _tPREV) {
+ _tNEXT[_tPREV[v] = _tPREV[p]] = v
+ if (p in _tPARENT) {
+ ++_tQCHLD[_tPARENT[v] = _tPARENT[p]]
+ } else {
+ delete _tPARENT[v]
+ }
+ } else {
+ delete _tPREV[v]
+ if (p in _tPARENT) {
+ ++_tQCHLD[_tPARENT[_tFCHLD[a] = v] = a = _tPARENT[p]]
+ } else {
+ delete _tPARENT[v]
+ }
+ }
+ return (_tPREV[_tNEXT[v] = p] = v)
+ } else {
+ if (v == 0) {
+ return v
+ }
+ return v
+ }
+ } else {
+ if (p == 0) {
+ return v
+ }
+ if (v) {
+ return _texclude(v)
+ }
+ return v
+ }
+}
+
+#_________________________________________________________________
+function _wQBRO(p, v)
+{
+ return v
+}
+
+#_________________________________________________________________
+function _wQCHLD(p, v)
+{
+ if (p) {
+ if (v) {
+ } else {
+ if (v == 0) {
+ if (p in _tFCHLD) {
+ v = _tFCHLD[p]
+ delete _tFCHLD[p]
+ delete _tLCHLD[p]
+ delete _tQCHLD[p]
+ do {
+ delete _tPARENT[v]
+ } while (v in _tNEXT && (v = _tNEXT[v]))
+ }
+ }
+ return v
+ }
+ } else {
+ if (p == 0) {
+ return v
+ }
+ return v
+ }
+}
+
+#_______________________________________________________________________
+function _warning(t, d, A)
+{
+ if (_ERRLOG_WF) {
+ A["TYPE"] = "WARNING"
+ A["TEXT"] = t
+ _log(A, d)
+ }
+}
+
+#___________________________________________________________
+function _wfilerdnehnd(f, t)
+{
+ if ((f = _filerdne(f)) == "") {
+ return ""
+ }
+ if (! ((t = _filerd(f)) in _WFILEROOTDIR)) {
+ _cmd("md \"" t "\" 2>NUL")
+ _WFILEROOTDIR[t]
+ }
+ return f
+}
+
+function _wonl(t)
+{
+ wonl = wonl _ln(t)
+}
+
+function _wonline(t)
+{
+ wonl = wonl _ln(substr(" _ " t " _____________________________________________________________________________________________________________________________________", 1, 126))
+}
+
+#___________________________________________________________
+function _wr_shortcut(f, S)
+{
+ if (_shrtcutf0 = _filepath(f)) {
+ ERRNO = ""
+ _shrtcuta0 = _shortcut_fpath " /A:C /F:\"" _shrtcutf0 "\" 2>&1"
+ for (f in _SHORTCUTWSTRUC) {
+ if (f in S) {
+ _shrtcuta0 = _shrtcuta0 " " _SHORTCUTWSTRUC[f] "\"" (gensub(/(\\?)$/, "\\1\\1", 1, S[f])) "\""
+ }
+ }
+ if (_shortcut_nerr(_cmd(_shrtcuta0), _shrtcutf0)) {
+ return
+ }
+ }
+ return ((ERRNO ? ERRNO = "write shortcut: " ERRNO : _NOP))
+}
+
+#_________________________________________________________________
+function _wrfile(f, d, a, b)
+{
+ if ((f = _wfilerdnehnd(f)) == "" || _filene(f) == "") {
+ ERRNO = "Filename error"
+ return
+ }
+ a = BINMODE
+ BINMODE = "rw"
+ b = ORS
+ ORS = ""
+ ERRNO = ""
+ print(d) > f
+ if (ERRNO) {
+ return ""
+ }
+ close(f)
+ BINMODE = a
+ ORS = b
+ if (ERRNO) {
+ return ""
+ }
+ return f
+}
+
+#___________________________________________________________
+function _wrfile1(f, d, a, b)
+{
+ if ((f = _wfilerdnehnd(f)) == "" || _filene(f) == "") {
+ ERRNO = "Filename error"
+ return
+ }
+ a = BINMODE
+ BINMODE = "rw"
+ b = ORS
+ ORS = ""
+ ERRNO = ""
+ print(d) > f
+ if (ERRNO) {
+ return ""
+ }
+ close(f)
+ BINMODE = a
+ ORS = b
+ if (ERRNO) {
+ return ""
+ }
+ return d
+}
+
+#_______________________________________________________________________
+function _yexport(p)
+{
+ return _tframe("_yexport_i0", p)
+}
+
+#_______________________________________________________________________
+function _yexport_i0(p, p0, p1, p2)
+{
+ if (p in _tLOG) {
+ return ("_ERRLOG: " _Zexparr(_tLOG[p]) "\n")
+ }
+ if (p in _tSTR) {
+ p = _tSTR[p]
+ gsub(/\x1B/, "\033;", p)
+ gsub(/\x0A/, "\033:", p)
+ return (p "\n")
+ }
+}
+
+#_________________________________________________________________
+function cmp_str_idx(i1, v1, i2, v2)
+{
+ return ((i1 < i2 ? -1 : 1))
+}
+
+#___________________________________________________________
+function filedi(f, d)
+{
+ if ((f = filerdnehndi(f)) == "") {
+ return _FILEIO_D
+ }
+ if (f in _FILEDIRFL) {
+ return _FILEDIR[f]
+ }
+ if (f in _FILEROOT) {
+ if (d = filegetdrvdir(_FILEROOT[f])) {
+ _FILEDIRFL[f]
+ }
+ return (_FILEDIR[f] = d _FILEDIR[f])
+ }
+ if ((_FILEIO_RD, f) in _FILEDIR) {
+ return _FILEDIR[_FILEIO_RD, f]
+ }
+ return (_FILEDIR[_FILEIO_RD, f] = _FILEIO_D _FILEDIR[f])
+}
+
+#___________________________________________________________
+function filegetdrvdir(t, r)
+{
+ if (t in _FILEDRV) {
+ return _FILEDRV[t]
+ }
+ if (match(r = _cmd("cd " t " 2>NUL"), /[^\x00-\x1F]+/)) {
+ r = gensub(/[ \t]*([\\\$\:])[ \t]*/, "\\1", "G", substr(r, RSTART, RLENGTH))
+ gsub(/(^[ \t]*)|([ \t]*$)/, "", r)
+ if (match(r, /\:(.*)/)) {
+ return (_FILEDRV[tolower(t)] = _FILEDRV[toupper(t)] = substr(r, RSTART + 1) ((r ~ /\\$/ ? "" : "\\")))
+ }
+ }
+ return ""
+}
+
+#___________________________________________________________
+function filegetrootdir(f, dd, d)
+{
+ if (f in _FILEDIRFL) {
+ if (f in _FILEROOT) {
+ return (_FILEROOT[f] _FILEDIR[f])
+ }
+ if ((dd = (dd ? dd : _FILEIO_RD), f) in _FILEROOT) {
+ return (_FILEROOT[dd, f] _FILEDIR[f])
+ }
+ return ((_FILEROOT[dd, f] = fileri(dd)) _FILEDIR[f])
+ }
+ if (f in _FILEROOT) {
+ if (d = filegetdrvdir(_FILEROOT[f])) {
+ _FILEDIRFL[f]
+ return (_FILEROOT[f] (_FILEDIR[f] = d _FILEDIR[f]))
+ } else {
+ return (_FILEROOT[f] _FILEDIR[f])
+ }
+ }
+ if ((dd = (dd ? dd : _FILEIO_RD), f) in _FILEROOT) {
+ if ((dd, f) in _FILEDIR) {
+ return (_FILEROOT[dd, f] _FILEDIR[dd, f])
+ }
+ if ((d = filedi(dd) _FILEDIR[f]) ~ /^\\/) {
+ return (_FILEROOT[dd, f] (_FILEDIR[dd, f] = d))
+ }
+ return (_FILEROOT[dd, f] d)
+ }
+ if ((dd, f) in _FILEDIR) {
+ return ((_FILEROOT[dd, f] = fileri(dd)) _FILEDIR[dd, f])
+ }
+ if ((d = filedi(dd) _FILEDIR[f]) ~ /^\\/) {
+ return ((_FILEROOT[dd, f] = fileri(dd)) (_FILEDIR[dd, f] = d))
+ }
+ return ((_FILEROOT[dd, f] = fileri(dd)) d)
+}
+
+#___________________________________________________________
+function filerdnehndi(st, a, c, r, d, n, A)
+{
+ if (st) {
+ if ((c = toupper(st)) in _FILECACHE) {
+ return _FILECACHE[c]
+ }
+ if (match(st, /^[ \t]*\\[ \t]*\\/)) {
+ if (match(substr(st, a = RLENGTH + 1), /^[ \t]*([0-9A-Za-z\-]+)[ \t]*(\\[ \t]*([A-Za-z])[ \t]*\$[ \t]*)?(\\[ \t]*([0-9A-Za-z_\!\+\-\[\]\(\)\{\}\~\.]+( +[0-9A-Za-z_\!\+\-\[\]\(\)\{\}\~\.]+)*[ \t]*\\)*[ \t]*)?(([0-9A-Za-z_\!\+\.\~\-\[\]\{\}\(\)]+( +[0-9A-Za-z_\!\+\.\~\-\[\]\{\}\(\)]+)*)[ \t]*)?/, A)) {
+ a = a + RLENGTH
+ d = ((A[3] ? "\\" A[3] "$" : "")) "\\" A[5]
+ gsub(/[ \t]*\\[ \t]*/, "\\", d)
+ if ((st = toupper((r = "\\\\" A[1]) d (n = A[8]))) in _FILECACHE) {
+ return (_FILECACHE[substr(c, 1, a)] = _FILECACHE[st])
+ }
+ _FILEDIR[c = _FILECACHE[substr(c, 1, a)] = _FILECACHE[st] = ++_file_rootcntr] = d
+ _FILEDIRFL[c]
+ _FILEROOT[c] = r
+ } else {
+ _filepath_err = "UNC"
+ return ""
+ }
+ } else {
+ match(st, /^(([ \t]*\.[ \t]*\\[ \t]*)|(([ \t]*([A-Za-z])[ \t]*(\:)[ \t]*)?([ \t]*(\\)[ \t]*)?))([ \t]*(([ \t]*[0-9A-Za-z_\!\+\-\[\]\(\)\{\}\~\.]+( +[0-9A-Za-z_\!\+\-\[\]\(\)\{\}\~\.]+)*[ \t]*\\)+)[ \t]*)?([ \t]*([0-9A-Za-z_\!\+\.\~\-\[\]\{\}\(\)]+( +[0-9A-Za-z_\!\+\.\~\-\[\]\{\}\(\)]+)*)[ \t]*)?/, A)
+ if (! RLENGTH) {
+ return ""
+ }
+ d = A[8] A[10]
+ gsub(/[ \t]*\\[ \t]*/, "\\", d)
+ if ((st = toupper((r = A[5] A[6]) d (n = A[14]))) in _FILECACHE) {
+ return (_FILECACHE[substr(c, 1, RLENGTH)] = _FILECACHE[st])
+ }
+ _FILEDIR[c = _FILECACHE[substr(c, 1, RLENGTH)] = _FILECACHE[st] = ++_file_rootcntr] = d
+ if (A[8]) {
+ _FILEDIRFL[c]
+ }
+ if (r) {
+ _FILEROOT[c] = r
+ }
+ }
+ if (n) {
+ if (match(n, /\.[^\.]*$/)) {
+ _FILEXT[c] = substr(n, RSTART)
+ _FILENAM[c] = substr(n, 1, RSTART - 1)
+ } else {
+ _FILENAM[c] = n
+ }
+ }
+ return c
+ }
+ return ""
+}
+
+#_____________________________________________________
+function fileri(f)
+{
+ if ((f = filerdnehndi(f)) == "") {
+ return _FILEIO_R
+ }
+ if (f in _FILEROOT) {
+ return _FILEROOT[f]
+ }
+ if ((_FILEIO_RD, f) in _FILEROOT) {
+ return _FILEROOT[_FILEIO_RD, f]
+ }
+ return (_FILEROOT[_FILEIO_RD, f] = _FILEIO_R)
+}
+
+function hujf(a, b, c)
+{
+ _conl("hujf(" a "," b "," c ")")
+}
+
+#___________________________________________________________
+function ncmp_str_idx(i1, v1, i2, v2)
+{
+ return ((i1 < i2 ? 1 : -1))
+}
+
+function test_cfg(p, z, AA0, a)
+{
+ AA0[1]
+ _fclass = _cfguid(p = _getuid(_classys), _NOP, _NOP, _NOP, _NOP, _classys)
+ _conl()
+ _conline()
+ _conl()
+ _drawuid(p)
+ _fclass = _cfguid(p = _getuid(_classys), AA0, AA0, AA0, AA0, _classys)
+ _conl()
+ _conline()
+ _conl()
+ _drawuid(p)
+ a = _getuid(z = _fclass = _cfguid(p = _getuid(_classys), p, "<", ">", "ab", "cd"))
+ _conl("### " a "########")
+ _conline()
+ _conl()
+ _drawuid(p)
+ a = _getuid(_fclass = _cfguid(p = _getuid(_classys), z, 0, 0, _NOP, z))
+ _conl("### " a "########")
+ _conline()
+ _conl()
+ _drawuid(p)
+ a = _getuid(_fclass = _cfguid(p = _getuid(_classys), z, "^", "$", z, _classys))
+ _conl("### " a "########")
+ _conline()
+ _conl()
+ _drawuid(p)
+ _fclass = _cfguid(p = _getuid(_classys), "oblptr", "pfx", "sfx", "abcd")
+ _conl()
+ _conline()
+ _conl()
+ _drawuid(p)
+ _conl("```````````````````" z "'''''''''" ((_isptr(z) ? " ptr" : " not ptr")))
+ _drawuid(z)
+}
+
+function test_splitstr(A)
+{
+ AA0[-1] = "huj"
+ AA0["A"] = "pizda"
+ AA0[1] = "zhopa"
+ delete AB0[AB0[""] = ""]
+ AC0[-1] = "HUJ"
+ AC0["A"] = "PIZDA"
+ AC0[1] = "ZHOPA"
+ _SPLITSTRB0["1"]
+ wonl = ""
+ _tstv(0, A, 0, "_tstv")
+ _conl(wonl)
+ _wrfile("wonl.out", wonl)
+}
+
+function test_uid(p, i)
+{
+ #test_cfg()
+ #return
+
+ _fclass = _cfguid(p = _getuid(_classys), p, "pfx", "sfx", "abc")
+ #_fclass=_cfguid(p=_getuid(_classys),_NOP,_NOP,_NOP,"",_classys)
+ _conl("_fclass uid: " _getuid(_fclass))
+ _drawuid(_fclass)
+ _conl("_classys uid: " _getuid(_classys)) _drawuid(_classys)
+ for (i = 1; i < 81; i++) {
+ _conl(i ": " _getuid(_fclass))
+ }
+ _drawuid(_fclass)
+}
+
+function tst_splitstr(t, A, R, r)
+{
+ delete A
+ A["not cleared"]
+ _wonl()
+ _wonline("_splitstr(" ((isarray(t) ? "ARR" ((length(t) > 0 ? "#" ((t[1] != "zhopa" ? "U" : "l")) : "")) : _val0(t))) ",A" ((isarray(R) ? ", ARR" ((length(R) > 0 ? "#" ((R[1] != "zhopa" ? "U" : "l")) : "")) : ", " _val0(R))) "):")
+ _wonl(_val0(r = _splitstr(t, A, R)))
+ _wonl("arrary A:")
+ _wonl(_dumparr(A))
+ return r
+}
+
+function tts(p, uidel, psfx, cnt, chr, p5, p6, p7, im)
+{
+ im = " "
+ im = ".. .."
+ _conl("ret: " _qparam(im, p, uidel, psfx, cnt, chr, p5, p6, p7) "'")
+ _conl("mask: `" _qparamask "'")
+}
+
+# # - p is array
+# ` - p is ptr detected in array _CLASSPTR(for _typ); or p is ptr detected in array A(for _typa)
+# 0 - p is undefined
+
+# 2 - p is string==""
+# 3 - p is string!=""
+# 4 - p is number 0
+# 5 - p is any number except 0(positive and negative)
+
+# str: _typ(p)+0 !_typ(p)+0
+# str/ptr _typ(p)>0 _typ(p)<1
+# str/arr "`">_typ(p0) && _t0
+# str/ptr/arr _typ(p) !_typ(p)
+# ptr _typ(p)=="`" _typ(p)<"`" ?
+# ptr/arr _typ(p)+0!=_t0
+# arr _typ(p)=="#" _typ(p)>"#" ?
+
+function zorr(A, i, r)
+{
+ if (i in A) {
+ _conl("`" i "' in A")
+ } else {
+ _conl("`" i "' not in A")
+ }
+ r = A[i] == "" && A[i] == 0
+ _conl("A[" i "] status is " r)
+ return
+ a = a + -a
+ _conl("``````````````" a "''''''''''''''''")
+}
+
+#_____________________________________________________________________________
+function zzer()
+{
+}
diff --git a/test/profile6.awk b/test/profile6.awk
new file mode 100644
index 00000000..754f8ae6
--- /dev/null
+++ b/test/profile6.awk
@@ -0,0 +1,7 @@
+BEGIN {
+ x = 3
+ print -(-x)
+ Q = "|"
+ print -3 Q (-4)
+ print -3 Q (-4) (-5)
+}
diff --git a/test/profile6.ok b/test/profile6.ok
new file mode 100644
index 00000000..0c9486c7
--- /dev/null
+++ b/test/profile6.ok
@@ -0,0 +1,10 @@
+ # BEGIN rule(s)
+
+ BEGIN {
+ 1 x = 3
+ 1 print -(-x)
+ 1 Q = "|"
+ 1 print -3 Q (-4)
+ 1 print -3 Q (-4) (-5)
+ }
+
diff --git a/test/profile7.awk b/test/profile7.awk
new file mode 100644
index 00000000..454694f9
--- /dev/null
+++ b/test/profile7.awk
@@ -0,0 +1,12 @@
+BEGIN {
+ print 1 / 10 * 10
+ print 1 / (10 * 10)
+ print 1 % 10 * 10
+ print 1 % (10 * 10)
+ print (10 * 5) / 2
+ print 10 * (5 / 2)
+ a = 5
+ b = 3
+ print a - 1 - b
+ print a + 1 - b
+}
diff --git a/test/profile7.ok b/test/profile7.ok
new file mode 100644
index 00000000..d65afa86
--- /dev/null
+++ b/test/profile7.ok
@@ -0,0 +1,15 @@
+ # BEGIN rule(s)
+
+ BEGIN {
+ 1 print 1 / 10 * 10
+ 1 print 1 / (10 * 10)
+ 1 print 1 % 10 * 10
+ 1 print 1 % (10 * 10)
+ 1 print 10 * 5 / 2
+ 1 print 10 * 5 / 2
+ 1 a = 5
+ 1 b = 3
+ 1 print a - 1 - b
+ 1 print a + 1 - b
+ }
+
diff --git a/test/profile8.awk b/test/profile8.awk
new file mode 100644
index 00000000..16252cea
--- /dev/null
+++ b/test/profile8.awk
@@ -0,0 +1,9 @@
+# Some
+# header
+# comments
+
+# Add up
+{ sum += $1 }
+
+# Print sum
+END { print sum }
diff --git a/test/profile8.ok b/test/profile8.ok
new file mode 100644
index 00000000..34f7a96b
--- /dev/null
+++ b/test/profile8.ok
@@ -0,0 +1,14 @@
+# Some
+# header
+# comments
+
+# Add up
+{
+ sum += $1
+}
+
+# Print sum
+END {
+ print sum
+}
+
diff --git a/test/rand-mpfr.ok b/test/rand-mpfr.ok
new file mode 100644
index 00000000..448f4032
--- /dev/null
+++ b/test/rand-mpfr.ok
@@ -0,0 +1 @@
+ 25 42 47 49 80 5 4 92 59 96 8 63 92 28 41 37 80 51 48
diff --git a/test/rand-mpfr1.ok b/test/rand-mpfr1.ok
new file mode 100644
index 00000000..448f4032
--- /dev/null
+++ b/test/rand-mpfr1.ok
@@ -0,0 +1 @@
+ 25 42 47 49 80 5 4 92 59 96 8 63 92 28 41 37 80 51 48
diff --git a/test/rand.ok b/test/rand.ok
index 60432b95..1df4ba39 100644
--- a/test/rand.ok
+++ b/test/rand.ok
@@ -1 +1 @@
- 62 67 88 6 35 77 3 68 30 96 90 26 35 8 88 93 49 53 37
+ 67 6 77 68 96 26 8 93 53 74 53 95 78 74 96 77 33 58 91
diff --git a/test/randtest.ok b/test/randtest.ok
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/randtest.ok
diff --git a/test/randtest.sh b/test/randtest.sh
new file mode 100755
index 00000000..b17fda73
--- /dev/null
+++ b/test/randtest.sh
@@ -0,0 +1,113 @@
+# THIS PURPOSELY DOES NOT HAVE A !# LINE !!!!
+#
+# Date: Mon, 9 Sep 2013 14:49:43 -0700
+# From: Bob Jewett <jewett@bill.scs.agilent.com>
+# Message-Id: <201309092149.r89Lnh94010909@bill.scs.agilent.com>
+# To: arnold@skeeve.com
+# Subject: Re: [bug-gawk] Bug in random() in builtin.c
+#
+# Hi Arnold,
+#
+# Attached below is a script that tests gawk for this particular
+# rand() problem. The pair-wise combinations show a strong
+# autocorrelation for a delay of 31 pairs of rand() samples.
+#
+# The script prints out the measured autocorrelation for a record
+# of NSAMPLES pairs. It also prints a fail message at the end if
+# it fails.
+#
+# If you want to see the autocorrelation values, there is a print
+# statement that if uncommented will save them to a file.
+#
+# Please let me know if the mailer screws up the transfer or
+# if you have any questions about the test.
+#
+# Best regards,
+# Bob
+#
+# -------------- test_pair_power_autocorrelation -----------------------
+#
+#!/bin/ksh
+
+#GAWK=/bin/gawk
+
+# ADR: Get GAWK from the environment.
+# Additional note: This wants ksh/bash for the use of $RANDOM below to
+# seed the generator. However, shells that don't provide it won't be
+# a problem since gawk will then seed the generator with the time of day,
+# as srand() will be called without an argument.
+
+# large NSAMPLES and NRUNS will bring any correlation out of the noise better
+NSAMPLES=1024; MAX_ALLOWED_SIGMA=5; NRUNS=50;
+
+$GAWK 'BEGIN{
+ srand('$RANDOM');
+ nsamples=('$NSAMPLES');
+ max_allowed_sigma=('$MAX_ALLOWED_SIGMA');
+ nruns=('$NRUNS');
+ for(tau=0;tau<nsamples/2;tau++) corr[tau]=0;
+
+ for(run=0;run<nruns;run++) {
+ sum=0;
+
+ # Fill an array with a sequence of samples that are a
+ # function of pairs of rand() values.
+
+ for(i=0;i<nsamples;i++) {
+ samp[i]=((rand()-0.5)*(rand()-0.5))^2;
+ sum=sum+samp[i];
+ }
+
+ # Subtract off the mean of the sequence:
+
+ mean=sum/nsamples;
+ for(i=0;i<nsamples;i++) samp[i]=samp[i]-mean;
+
+ # Calculate an autocorrelation function on the sequence.
+ # Because the values of rand() should be independent, there
+ # should be no peaks in the autocorrelation.
+
+ for(tau=0;tau<nsamples/2;tau++) {
+ sum=0;
+ for(i=0;i<nsamples/2;i++) sum=sum+samp[i]*samp[i+tau];
+ corr[tau]=corr[tau]+sum;
+ }
+
+ }
+ # Normalize the autocorrelation to the tau=0 value.
+
+ max_corr=corr[0];
+ for(tau=0;tau<nsamples/2;tau++) corr[tau]=corr[tau]/max_corr;
+
+ # OPTIONALLY Print out the autocorrelation values:
+
+ # for(tau=0;tau<nsamples/2;tau++) print tau, corr[tau] > "pairpower_corr.data";
+
+ # Calculate the sigma for the non-zero tau values:
+
+ power_sum=0;
+
+ for(tau=1;tau<nsamples/2;tau++) power_sum=power_sum+(corr[tau])^2;
+
+ sigma=sqrt(power_sum/(nsamples/2-1));
+
+ # See if any of the correlations exceed a reasonable number of sigma:
+
+ passed=1;
+ for(tau=1;tau<nsamples/2;tau++) {
+ if ( abs(corr[tau])/sigma > max_allowed_sigma ) {
+ print "Tau=", tau ", Autocorr=", corr[tau]/sigma, "sigma";
+ passed=0;
+ }
+ }
+ if(!passed) {
+ print "Test failed."
+ exit(1);
+ }
+ else exit (0);
+ }
+
+function abs(abs_input) { return(sqrt(abs_input^2)) ; }
+'
+
+exit 0
diff --git a/test/readdir.awk b/test/readdir.awk
new file mode 100644
index 00000000..d407bbce
--- /dev/null
+++ b/test/readdir.awk
@@ -0,0 +1,3 @@
+@load "readdir"
+
+{ print }
diff --git a/test/readdir0.awk b/test/readdir0.awk
new file mode 100644
index 00000000..2b7674a4
--- /dev/null
+++ b/test/readdir0.awk
@@ -0,0 +1,44 @@
+# NOTE: This program is not a generalized parser for the output of 'ls'.
+# It's job is to read the output of ls from the gawk source code directory,
+# where we know there are no symbolic links, nor are there files with
+# spaces in their file names, etc.
+BEGIN {
+ # analyze results from readdir extension
+ while ((getline x < extout) > 0) {
+ numrec++
+ if ((split(x, f, "/") == 3) && (f[3] == "u"))
+ num_unknown++
+ }
+ close(extout)
+ if ((numrec > 0) && (num_unknown == numrec)) {
+ print "Notice: this filesystem does not appear to support file type information" > "/dev/stderr"
+ ftype_unknown = 1
+ }
+}
+
+BEGIN {
+ for (i = 1; (getline < dirlist) > 0; i++) {
+ # inode number is $1, filename is read of record
+ inode = $1
+ $1 = ""
+ $0 = $0
+ sub(/^ */, "")
+ names[i] = $0
+ ino[names[i]] = inode
+ }
+ close(dirlist)
+
+ for (j = 1; (getline < longlist) > 0; j++) {
+ type_let = substr($0, 1, 1)
+ if (type_let == "-")
+ type_let = "f"
+ type[$NF] = type_let
+ }
+ close(longlist)
+
+ if (i != j)
+ printf("mismatch: %d from `ls -afi' and %d from `ls -lna'\n", i, j) > "/dev/stderr"
+
+ for (i = 1; i in names; i++)
+ printf("%s/%s/%s\n", ino[names[i]], names[i], (ftype_unknown ? "u" : type[names[i]]))
+}
diff --git a/test/readfile2.awk b/test/readfile2.awk
new file mode 100644
index 00000000..c21483fc
--- /dev/null
+++ b/test/readfile2.awk
@@ -0,0 +1,12 @@
+@load "readfile"
+BEGIN { PROCINFO["readfile"] = 1 }
+BEGINFILE { print "Start of", basename(FILENAME) }
+{ printf ("%d: <%s>\n", FNR, $0 ) }
+ENDFILE { print "End of", basename(FILENAME) }
+
+function basename(file, result)
+{
+ result = file
+ gsub(".*/", "", result)
+ return result
+}
diff --git a/test/readfile2.ok b/test/readfile2.ok
new file mode 100644
index 00000000..be1ded6c
--- /dev/null
+++ b/test/readfile2.ok
@@ -0,0 +1,21 @@
+Start of readfile2.awk
+1: <@load "readfile"
+BEGIN { PROCINFO["readfile"] = 1 }
+BEGINFILE { print "Start of", basename(FILENAME) }
+{ printf ("%d: <%s>\n", FNR, $0 ) }
+ENDFILE { print "End of", basename(FILENAME) }
+
+function basename(file, result)
+{
+ result = file
+ gsub(".*/", "", result)
+ return result
+}
+>
+End of readfile2.awk
+Start of readdir.awk
+1: <@load "readdir"
+
+{ print }
+>
+End of readdir.awk
diff --git a/test/regexpbrack.awk b/test/regexpbrack.awk
new file mode 100644
index 00000000..136cd194
--- /dev/null
+++ b/test/regexpbrack.awk
@@ -0,0 +1,2 @@
+/[]+()0-9.,$%/'"-]*$/
+/^[]+()0-9.,$%/'"-]*$/
diff --git a/test/regexpbrack.in b/test/regexpbrack.in
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/regexpbrack.in
diff --git a/test/regexpbrack.ok b/test/regexpbrack.ok
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/regexpbrack.ok
diff --git a/test/regexprange.awk b/test/regexprange.awk
new file mode 100644
index 00000000..861e5ee5
--- /dev/null
+++ b/test/regexprange.awk
@@ -0,0 +1,14 @@
+BEGIN {
+ range = "[a-dx-z]"
+
+ split("ABCDEFGHIJKLMNOPQRSTUVWXYZ", upper, "")
+ split("abcdefghijklmnopqrstuvwxyz", lower, "")
+
+ for (i = 1; i in upper; i++)
+ printf("%s ~ %s ---> %s\n",
+ upper[i], range, (upper[i] ~ range) ? "true" : "false")
+
+ for (i = 1; i in lower; i++)
+ printf("%s ~ %s ---> %s\n",
+ lower[i], range, (lower[i] ~ range) ? "true" : "false")
+}
diff --git a/test/regexprange.ok b/test/regexprange.ok
new file mode 100644
index 00000000..dbf5d35a
--- /dev/null
+++ b/test/regexprange.ok
@@ -0,0 +1,52 @@
+A ~ [a-dx-z] ---> false
+B ~ [a-dx-z] ---> false
+C ~ [a-dx-z] ---> false
+D ~ [a-dx-z] ---> false
+E ~ [a-dx-z] ---> false
+F ~ [a-dx-z] ---> false
+G ~ [a-dx-z] ---> false
+H ~ [a-dx-z] ---> false
+I ~ [a-dx-z] ---> false
+J ~ [a-dx-z] ---> false
+K ~ [a-dx-z] ---> false
+L ~ [a-dx-z] ---> false
+M ~ [a-dx-z] ---> false
+N ~ [a-dx-z] ---> false
+O ~ [a-dx-z] ---> false
+P ~ [a-dx-z] ---> false
+Q ~ [a-dx-z] ---> false
+R ~ [a-dx-z] ---> false
+S ~ [a-dx-z] ---> false
+T ~ [a-dx-z] ---> false
+U ~ [a-dx-z] ---> false
+V ~ [a-dx-z] ---> false
+W ~ [a-dx-z] ---> false
+X ~ [a-dx-z] ---> false
+Y ~ [a-dx-z] ---> false
+Z ~ [a-dx-z] ---> false
+a ~ [a-dx-z] ---> true
+b ~ [a-dx-z] ---> true
+c ~ [a-dx-z] ---> true
+d ~ [a-dx-z] ---> true
+e ~ [a-dx-z] ---> false
+f ~ [a-dx-z] ---> false
+g ~ [a-dx-z] ---> false
+h ~ [a-dx-z] ---> false
+i ~ [a-dx-z] ---> false
+j ~ [a-dx-z] ---> false
+k ~ [a-dx-z] ---> false
+l ~ [a-dx-z] ---> false
+m ~ [a-dx-z] ---> false
+n ~ [a-dx-z] ---> false
+o ~ [a-dx-z] ---> false
+p ~ [a-dx-z] ---> false
+q ~ [a-dx-z] ---> false
+r ~ [a-dx-z] ---> false
+s ~ [a-dx-z] ---> false
+t ~ [a-dx-z] ---> false
+u ~ [a-dx-z] ---> false
+v ~ [a-dx-z] ---> false
+w ~ [a-dx-z] ---> false
+x ~ [a-dx-z] ---> true
+y ~ [a-dx-z] ---> true
+z ~ [a-dx-z] ---> true
diff --git a/test/reginttrad.awk b/test/reginttrad.awk
new file mode 100644
index 00000000..9d115657
--- /dev/null
+++ b/test/reginttrad.awk
@@ -0,0 +1,6 @@
+BEGIN {
+ str1 = "aabbbc"
+ str2 = "aaabcc"
+ if (str1 ~ /b{2,}/) printf("\"%s\" matches /b{2,}/\n", str1)
+ if (str2 ~ /b{2,}/) printf("\"%s\" matches /b{2,}/\n", str2)
+}
diff --git a/test/reginttrad.ok b/test/reginttrad.ok
new file mode 100644
index 00000000..eaa278a6
--- /dev/null
+++ b/test/reginttrad.ok
@@ -0,0 +1 @@
+"aabbbc" matches /b{2,}/
diff --git a/test/regnul1.awk b/test/regnul1.awk
new file mode 100644
index 00000000..2a35d176
--- /dev/null
+++ b/test/regnul1.awk
@@ -0,0 +1,84 @@
+# From denis@gissoft.eu Thu May 29 09:07:56 IDT 2014
+# Article: 8400 of comp.lang.awk
+# X-Received: by 10.236.81.99 with SMTP id l63mr3912466yhe.3.1401224812642;
+# Tue, 27 May 2014 14:06:52 -0700 (PDT)
+# X-Received: by 10.140.37.148 with SMTP id r20mr578874qgr.0.1401224812310; Tue,
+# 27 May 2014 14:06:52 -0700 (PDT)
+# Path: eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!v102.xanadu-bbs.net!xanadu-bbs.net!news.glorb.com!hl10no6493021igb.0!news-out.google.com!gi6ni15574igc.0!nntp.google.com!hl10no6493018igb.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail
+# Newsgroups: comp.lang.awk
+# Date: Tue, 27 May 2014 14:06:52 -0700 (PDT)
+# Complaints-To: groups-abuse@google.com
+# Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=85.253.50.165;
+# posting-account=zNhVLgoAAACsg-WfVe_or2VV7loUhx8H
+# NNTP-Posting-Host: 85.253.50.165
+# User-Agent: G2/1.0
+# MIME-Version: 1.0
+# Message-ID: <3112e356-d2e1-45cd-ba55-2f939ee50105@googlegroups.com>
+# Subject: \0 character can't be implement inside regexp in some cases?
+# From: denis@gissoft.eu
+# Injection-Date: Tue, 27 May 2014 21:06:52 +0000
+# Content-Type: text/plain; charset=ISO-8859-1
+# Xref: news.eternal-september.org comp.lang.awk:8400
+#
+# Hello,
+#
+# while doing some experiments with the gawk(4.1.1) i was found problem in implementing character \x00 inside regexp for two cases:
+#
+# str~/\0/
+#
+# and
+#
+# switch ( str ) { case /\0/: ... }
+#
+# the following code try to match given string(=="\x00") with the regexp /^\0$/ using different ways provided by gawk:
+#
+func _chm(t) {
+ _ch("match()",match(t,/^\0$/))
+ _ch("split()",split(t,A,/^\0$/)>1)
+ _ch("patsplit()",patsplit(t,A,/^\0$/))
+ _ch("gsub()",gsub(/^\0$/,"&",t))
+ _ch("sub()",sub(/^\0$/,"&",t))
+ _ch("gensub()",!gensub(/^\0$/,"","G",t))
+ _ch("str~/rexp/",t~/^\0$/)
+ a=0; switch ( t ) { case /^\0$/: a=1 }; _ch("switch-case //",a) }
+
+func _ch(fn,bool) {
+ print substr(fn ": ",1,16) (bool ? "+" : "-") }
+
+BEGIN{ _chm("\000") }
+#
+# output:
+#
+# > gawk -f _null.gwk
+# match(): +
+# split(): +
+# patsplit(): +
+# gsub(): +
+# sub(): +
+# gensub(): +
+# str~/rexp/: -
+# switch-case //: -
+#
+# can someone explain me:
+#
+# why in case using match(), split(), patsplit(), gsub(), sub() and gensub() the given string "\x00" matches with the /^\0$/
+#
+# but in cases:
+#
+# "\x00"~/^\0$/
+#
+# and
+#
+# switch ( "\x00" ) { case /^\0$/: doesn't match? }
+#
+#
+# thank You
+#
+#
+# GNU Awk 4.1.1, API: 1.1 (GNU MPFR 3.1.0-p8, GNU MP 5.0.2)
+# Copyright (C) 1989, 1991-2014 Free Software Foundation.
+# downloaded from ezwinports
+#
+# windows 7x64; cmd
+#
+#
diff --git a/test/regnul1.ok b/test/regnul1.ok
new file mode 100644
index 00000000..2ba0e1da
--- /dev/null
+++ b/test/regnul1.ok
@@ -0,0 +1,8 @@
+match(): +
+split(): +
+patsplit(): +
+gsub(): +
+sub(): +
+gensub(): +
+str~/rexp/: +
+switch-case //: +
diff --git a/test/regnul2.awk b/test/regnul2.awk
new file mode 100644
index 00000000..3d93df41
--- /dev/null
+++ b/test/regnul2.awk
@@ -0,0 +1,112 @@
+# From denis@gissoft.eu Thu May 29 09:10:18 IDT 2014
+# Article: 8408 of comp.lang.awk
+# X-Received: by 10.182.128.166 with SMTP id np6mr93689obb.16.1401289466734;
+# Wed, 28 May 2014 08:04:26 -0700 (PDT)
+# X-Received: by 10.140.36.6 with SMTP id o6mr4939qgo.26.1401289466607; Wed, 28
+# May 2014 08:04:26 -0700 (PDT)
+# Path: eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!news.glorb.com!c1no19185457igq.0!news-out.google.com!qf4ni13600igc.0!nntp.google.com!c1no19185454igq.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail
+# Newsgroups: comp.lang.awk
+# Date: Wed, 28 May 2014 08:04:26 -0700 (PDT)
+# In-Reply-To: <lm4rra$4u9$1@dont-email.me>
+# Complaints-To: groups-abuse@google.com
+# Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=82.131.35.51; posting-account=zNhVLgoAAACsg-WfVe_or2VV7loUhx8H
+# NNTP-Posting-Host: 82.131.35.51
+# References: <3112e356-d2e1-45cd-ba55-2f939ee50105@googlegroups.com>
+# <lm34d7$tb4$1@news.m-online.net> <f666871f-a94c-4505-9677-8711d656433c@googlegroups.com>
+# <lm4rra$4u9$1@dont-email.me>
+# User-Agent: G2/1.0
+# MIME-Version: 1.0
+# Message-ID: <79828a24-d265-4e88-8de1-e61ecbaa6701@googlegroups.com>
+# Subject: Re: \0 character can't be implement inside regexp in some cases?
+# From: Denis Shirokov <denis@gissoft.eu>
+# Injection-Date: Wed, 28 May 2014 15:04:26 +0000
+# Content-Type: text/plain; charset=ISO-8859-1
+# Xref: news.eternal-september.org comp.lang.awk:8408
+#
+#
+# All of the other use-cases just cluttered up your posting.
+#
+# oh, really?
+#
+# 1. where in the Janis code the case with the `switch-case'?
+# 2. how do you know about that there is only two cases? may be you know it because my code contains the other test cases?
+# 3. fine. do you know what situation with the dynamic regexps? no?
+# 4. do you know what situation with RS,FS and /.../ in the middle-area? how you can say that there is only two cases if you absolutely do not know it?
+#
+# i'm asking: WHO will perform testing other cases? You? gawk-team? the God?
+# what is that point of view: that it will be enough to say:
+# Oh! my match(t,/^\0$/) is matching "\x00" but t~/^\0$/ is not. why oh why?
+#
+# where is the test cover? or you think that other peoples will doing its instead of You? instead of Me?
+#
+# and the second point: guys you are screaming about two levels of stack. really, you kidding? =)
+#
+# however, i'm attaching some additional information about dynrexp:
+#
+func _chmd(t,r) {
+ _ch("match()",match(t,r))
+ _ch("split()",split(t,A,r)>1)
+ _ch("patsplit()",patsplit(t,A,r))
+ _ch("gsub()",gsub(r,"&",t))
+ t2=t; _ch("sub()",sub(r,"&",t2))
+ _ch("gensub()",!gensub(r,"","G",t))
+ _ch("str~/rexp/",t~r)
+ # switch-case is not applicable with dynrxp
+ _conline() }
+
+func _ch(fn,bool) {
+ print substr(fn ": ",1,16) (bool ? "+" : "-") }
+
+func _conline() {
+ print "__________________________"; print }
+
+BEGIN{ _chmd("\x01","^\1$") #testing that all doings right; all match
+ _chmd("\x00","^\1$") #testing that all doings right; all not match
+ _chmd("\x00","^\0$") #tesing dynrexp
+}
+#
+# output:
+#
+# match(): +
+# split(): +
+# patsplit(): +
+# gsub(): +
+# sub(): +
+# gensub(): +
+# str~/rexp/: +
+# __________________________
+#
+# match(): -
+# split(): -
+# patsplit(): -
+# gsub(): -
+# sub(): -
+# gensub(): -
+# str~/rexp/: -
+# __________________________
+#
+# match(): +
+# split(): +
+# patsplit(): +
+# gsub(): +
+# sub(): +
+# gensub(): +
+# str~/rexp/: -
+#
+# it's looks like with the dynamic regexp the same story.
+#
+# i found another one moment that is possible near with the reason of this issue:
+#
+# i was testing what characters can be present in doublestring and regexp "directly" (just as the character) and what characters must be present as escape sequence (\qqq)
+#
+# so, i found the following:
+#
+# t="abc"
+# if ( match(t,/^abc[NUL]def/) ) ... - where [NUL] is the character \x00
+#
+# it's seems that in that case the regular expression is processed until [NUL]character and the other part is ignored because the example above gives TRUE
+#
+# friendship
+# Denis Shirokov
+#
+#
diff --git a/test/regnul2.ok b/test/regnul2.ok
new file mode 100644
index 00000000..6b3cecab
--- /dev/null
+++ b/test/regnul2.ok
@@ -0,0 +1,27 @@
+match(): +
+split(): +
+patsplit(): +
+gsub(): +
+sub(): +
+gensub(): +
+str~/rexp/: +
+__________________________
+
+match(): -
+split(): -
+patsplit(): -
+gsub(): -
+sub(): -
+gensub(): -
+str~/rexp/: -
+__________________________
+
+match(): +
+split(): +
+patsplit(): +
+gsub(): +
+sub(): +
+gensub(): +
+str~/rexp/: +
+__________________________
+
diff --git a/test/regrange.ok b/test/regrange.ok
index 1fa00c70..ae8c6499 100644
--- a/test/regrange.ok
+++ b/test/regrange.ok
@@ -3,4 +3,4 @@
"c" ~ /[[a-d]/ --> 1
"\" ~ /[\[-\]]/ --> 1
"[.c.]" ~ /[a-[.e.]]/ --> 1
-"[.d.]" ~ /[[.c.]-[.z.]]/ --> 0
+"[.d.]" ~ /[[.c.]-[.z.]]/ --> 1
diff --git a/test/revout.awk b/test/revout.awk
new file mode 100644
index 00000000..25f62fc7
--- /dev/null
+++ b/test/revout.awk
@@ -0,0 +1,6 @@
+@load "revoutput"
+
+BEGIN {
+ REVOUT = 1
+ print "hello, world" > "/dev/stdout"
+}
diff --git a/test/revout.ok b/test/revout.ok
new file mode 100644
index 00000000..8101cb93
--- /dev/null
+++ b/test/revout.ok
@@ -0,0 +1 @@
+dlrow ,olleh
diff --git a/test/revtwoway.awk b/test/revtwoway.awk
new file mode 100644
index 00000000..05bded5a
--- /dev/null
+++ b/test/revtwoway.awk
@@ -0,0 +1,11 @@
+@load "revtwoway"
+
+BEGIN {
+ cmd = "/magic/mirror"
+
+ print "hello, world" |& cmd
+ cmd |& getline line
+
+ printf("got back: <%s>, RT = <%s>\n", line, RT)
+ close(cmd)
+}
diff --git a/test/revtwoway.ok b/test/revtwoway.ok
new file mode 100644
index 00000000..b8a5ff31
--- /dev/null
+++ b/test/revtwoway.ok
@@ -0,0 +1,2 @@
+got back: <dlrow ,olleh>, RT = <
+>
diff --git a/test/rri1.awk b/test/rri1.awk
new file mode 100644
index 00000000..889dbdcb
--- /dev/null
+++ b/test/rri1.awk
@@ -0,0 +1 @@
+/[d-f]/
diff --git a/test/rri1.in b/test/rri1.in
new file mode 100644
index 00000000..28b6b408
--- /dev/null
+++ b/test/rri1.in
@@ -0,0 +1 @@
+no match: è
diff --git a/test/rri1.ok b/test/rri1.ok
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/rri1.ok
diff --git a/test/rsgetline.awk b/test/rsgetline.awk
new file mode 100644
index 00000000..fa327fcf
--- /dev/null
+++ b/test/rsgetline.awk
@@ -0,0 +1,23 @@
+# Date: Sun, 4 May 2014 18:09:01 +0200
+# From: Davide Brini <dave_br@gmx.com>
+# To: bug-gawk@gnu.org
+# Subject: Re: [bug-gawk] Computed regex and getline bug / issue
+#
+# I have been able to reduce the behavior to these simple test cases, which
+# (unless I'm missing something obvious) should behave identically but don't:
+#
+# $ printf '1,2,' | gawk 'BEGIN{RS="[,]+"}{print; a = getline; print "-"a"-"; print}'
+# 1
+# -0-
+# 1
+
+BEGIN {
+ RS = "[,]+"
+}
+
+{
+ printf "[%s] [%s]\n", $0, RT
+ a = getline
+ print "-"a"-"
+ printf "[%s] [%s]\n", $0, RT
+}
diff --git a/test/rsgetline.in b/test/rsgetline.in
new file mode 100644
index 00000000..f1782346
--- /dev/null
+++ b/test/rsgetline.in
@@ -0,0 +1 @@
+1,2, \ No newline at end of file
diff --git a/test/rsgetline.ok b/test/rsgetline.ok
new file mode 100644
index 00000000..1388369a
--- /dev/null
+++ b/test/rsgetline.ok
@@ -0,0 +1,3 @@
+[1] [,]
+-1-
+[2] [,]
diff --git a/test/rsglstdin.ok b/test/rsglstdin.ok
new file mode 100644
index 00000000..1388369a
--- /dev/null
+++ b/test/rsglstdin.ok
@@ -0,0 +1,3 @@
+[1] [,]
+-1-
+[2] [,]
diff --git a/test/rtlenmb.ok b/test/rtlenmb.ok
new file mode 100644
index 00000000..b8a484df
--- /dev/null
+++ b/test/rtlenmb.ok
@@ -0,0 +1,3 @@
+3
+5
+2
diff --git a/test/rwarray.awk b/test/rwarray.awk
new file mode 100644
index 00000000..0cb214ee
--- /dev/null
+++ b/test/rwarray.awk
@@ -0,0 +1,40 @@
+@load "rwarray"
+
+BEGIN {
+ while ((getline word) > 0)
+ dict[word] = word word
+
+ n = asorti(dict, dictindices)
+ for (i = 1; i <= n; i++)
+ printf("dict[%s] = %s\n", dictindices[i], dict[dictindices[i]]) > "orig.out"
+ close("orig.out");
+
+ ret = writea("orig.bin", dict)
+ printf "writea() returned %d, expecting 1\n", ret
+
+
+ ret = reada("orig.bin", dict)
+ printf "reada() returned %d, expecting 1\n", ret
+
+ n = asorti(dict, dictindices)
+ for (i = 1; i <= n; i++)
+ printf("dict[%s] = %s\n", dictindices[i], dict[dictindices[i]]) > "new.out"
+ close("new.out");
+
+ os = ""
+ if (ENVIRON["AWKLIBPATH"] == "sys$disk:[-]") {
+ os = "VMS"
+ # return status from system() on VMS can not be used here
+ }
+ if (os != "VMS") {
+ ret = system("cmp orig.out new.out")
+
+ if (ret == 0)
+ print "old and new are equal - GOOD"
+ else
+ print "old and new are not equal - BAD"
+
+ if (ret == 0 && !("KEEPIT" in ENVIRON))
+ system("rm -f orig.bin orig.out new.out")
+ }
+}
diff --git a/test/rwarray.in b/test/rwarray.in
new file mode 100644
index 00000000..aff88306
--- /dev/null
+++ b/test/rwarray.in
@@ -0,0 +1,780 @@
+a
+aardvark
+aardvark's
+aardvarks
+abaci
+aback
+abacus
+abacus's
+abacuses
+abaft
+abalone
+abalone's
+abalones
+abandon
+abandoned
+abandoning
+abandonment
+abandonment's
+abandons
+abase
+abased
+abasement
+abases
+abash
+abashed
+abashes
+abashing
+abasing
+abate
+abated
+b
+baa
+baaed
+baaing
+baas
+babble
+babbled
+babbler
+babbler's
+babblers
+babbles
+babbling
+babe
+babe's
+babel
+babels
+babes
+babied
+babier
+babies
+babiest
+baboon
+baboon's
+baboons
+babushka
+babushka's
+babushkas
+baby
+baby's
+babyhood
+c
+cab
+cab's
+cabal
+cabal's
+cabals
+cabana
+cabana's
+cabanas
+cabaret
+cabaret's
+cabarets
+cabbage
+cabbage's
+cabbages
+cabbed
+cabbie
+cabbies
+cabbing
+cabby
+cabby's
+cabin
+cabin's
+cabinet
+cabinet's
+cabinetmaker
+cabinetmaker's
+cabinetmakers
+cabinets
+cabins
+d
+d'arezzo
+d'estaing
+dab
+dabbed
+dabbing
+dabble
+dabbled
+dabbler
+dabbler's
+dabblers
+dabbles
+dabbling
+dabs
+dacha
+dacha's
+dachas
+dachshund
+dachshund's
+dachshunds
+dactyl
+dactyl's
+dactylic
+dactylics
+dactyls
+dad
+dad's
+daddies
+db
+db's
+e
+e'er
+each
+eager
+eager's
+eagerer
+eagerest
+eagerly
+eagerness
+eagerness's
+eagle
+eagle's
+eagles
+eaglet
+eaglet's
+eaglets
+ear
+ear's
+earache
+earache's
+earaches
+eardrum
+eardrum's
+eardrums
+earful
+earful's
+earfuls
+earl
+ebay
+ebay's
+f
+fa
+fa's
+fable
+fable's
+fabled
+fables
+fabric
+fabric's
+fabricate
+fabricated
+fabricates
+fabricating
+fabrication
+fabrication's
+fabrications
+fabrics
+fabulous
+fabulously
+facade
+facade's
+facades
+face
+face's
+faced
+faceless
+facelift
+facelifts
+faces
+facet
+g
+gab
+gabardine
+gabardine's
+gabardines
+gabbed
+gabbier
+gabbiest
+gabbing
+gabble
+gabbled
+gabbles
+gabbling
+gabby
+gaberdine
+gaberdine's
+gaberdines
+gable
+gable's
+gabled
+gables
+gabling
+gabs
+gad
+gadabout
+gadabout's
+gadabouts
+gadded
+gadding
+gadflies
+h
+h'm
+ha
+haberdasher
+haberdasher's
+haberdasheries
+haberdashers
+haberdashery
+haberdashery's
+habit
+habit's
+habitability
+habitability's
+habitable
+habitat
+habitat's
+habitation
+habitation's
+habitations
+habitats
+habits
+habitual
+habitually
+habituals
+habituate
+habituated
+habituates
+habituating
+habituation
+habituation's
+i
+iamb
+iamb's
+iambic
+iambics
+iambs
+ibex
+ibex's
+ibexes
+ibices
+ibis
+ibis's
+ibises
+ibuprofen
+ice
+ice's
+iceberg
+iceberg's
+icebergs
+icebound
+icebox
+icebox's
+iceboxes
+icebreaker
+icebreaker's
+icebreakers
+icecap
+icecap's
+icecaps
+iced
+j
+jab
+jabbed
+jabber
+jabbered
+jabberer
+jabberer's
+jabberers
+jabbering
+jabbers
+jabbing
+jabot
+jabot's
+jabots
+jabs
+jack
+jack's
+jackal
+jackal's
+jackals
+jackass
+jackass's
+jackasses
+jackboot
+jackboot's
+jackboots
+jackdaw
+jackdaw's
+jackdaws
+jacked
+k
+kabob
+kabob's
+kabobs
+kaboom
+kale
+kale's
+kaleidoscope
+kaleidoscope's
+kaleidoscopes
+kaleidoscopic
+kamikaze
+kamikaze's
+kamikazes
+kangaroo
+kangaroo's
+kangarooed
+kangarooing
+kangaroos
+kaolin
+kaolin's
+kapok
+kapok's
+kaput
+kaput's
+karakul
+karakul's
+khz
+khz's
+kw
+l
+la
+la's
+lab
+lab's
+label
+label's
+labeled
+labeling
+labelled
+labelling
+labels
+labia
+labia's
+labial
+labials
+labium
+labor
+labor's
+laboratories
+laboratory
+laboratory's
+labored
+laborer
+laborer's
+laborers
+laboring
+laborious
+laboriously
+labors
+m
+ma
+ma'am
+ma's
+macabre
+macadam
+macadam's
+macaroni
+macaroni's
+macaroon
+macaroon's
+macaroons
+macaw
+macaw's
+macaws
+mace
+mace's
+maced
+macerate
+macerated
+macerates
+macerating
+maceration
+maceration's
+maces
+machete
+machete's
+machetes
+machination
+machination's
+n
+nab
+nabbed
+nabbing
+nabob
+nabob's
+nabobs
+nabs
+nacho
+nachos
+nacre
+nacre's
+nadir
+nadir's
+nadirs
+nag
+nagged
+nagging
+nags
+naiad
+naiad's
+naiades
+naiads
+nail
+nail's
+nailbrush
+nailbrush's
+nailbrushes
+nailed
+nailing
+o
+o'clock
+o'er
+oaf
+oaf's
+oafish
+oafs
+oak
+oak's
+oaken
+oaks
+oakum
+oakum's
+oar
+oar's
+oared
+oaring
+oarlock
+oarlock's
+oarlocks
+oars
+oarsman
+oarsman's
+oarsmen
+oases
+oasis
+oasis's
+oat
+oat's
+oaten
+p
+pa
+pa's
+pace
+pace's
+paced
+pacemaker
+pacemaker's
+pacemakers
+paces
+pacesetter
+pacesetter's
+pacesetters
+pachyderm
+pachyderm's
+pachyderms
+pacific
+pacifically
+pacification
+pacification's
+pacified
+pacifier
+pacifier's
+pacifiers
+pacifies
+pacifism
+pacifism's
+pacifist
+ph
+ph's
+q
+qua
+quack
+quacked
+quackery
+quackery's
+quacking
+quacks
+quad
+quad's
+quadrangle
+quadrangle's
+quadrangles
+quadrangular
+quadrangular's
+quadrant
+quadrant's
+quadrants
+quadraphonic
+quadraphonics
+quadratic
+quadratic's
+quadrature
+quadrature's
+quadrennial
+quadriceps
+quadriceps's
+quadricepses
+quadrilateral
+quadrilaterals
+r
+rabbi
+rabbi's
+rabbies
+rabbinate
+rabbinate's
+rabbinical
+rabbis
+rabbit
+rabbit's
+rabbited
+rabbiting
+rabbits
+rabble
+rabble's
+rabbles
+rabid
+rabies
+raccoon
+raccoon's
+raccoons
+race
+race's
+racecourse
+racecourse's
+racecourses
+raced
+racehorse
+racehorse's
+racehorses
+s
+sabbatical
+sabbaticals
+saber
+saber's
+sabers
+sable
+sable's
+sabled
+sables
+sabling
+sabotage
+sabotage's
+sabotaged
+sabotages
+sabotaging
+saboteur
+saboteur's
+saboteurs
+sabre
+sabres
+sac
+sac's
+saccharin
+saccharin's
+saccharine
+sacerdotal
+sachem
+sachem's
+sachems
+t
+tab
+tab's
+tabbed
+tabbies
+tabbing
+tabby
+tabernacle
+tabernacle's
+tabernacles
+table
+table's
+tableau
+tableau's
+tableaus
+tableaux
+tablecloth
+tablecloth's
+tablecloths
+tabled
+tableland
+tableland's
+tablelands
+tables
+tablespoon
+tablespoon's
+tablespoonful
+tablespoonful's
+tablespoonfuls
+tablespoons
+u
+ubiquitous
+ubiquitously
+ubiquity
+udder
+udder's
+udders
+ugh
+uglied
+uglier
+uglies
+ugliest
+ugliness
+ugliness's
+ugly
+uglying
+uh
+ukulele
+ukulele's
+ukuleles
+ulcer
+ulcer's
+ulcerate
+ulcerated
+ulcerates
+ulcerating
+ulceration
+ulceration's
+ulcered
+ulcering
+v
+vacancies
+vacancy
+vacancy's
+vacant
+vacantly
+vacate
+vacated
+vacates
+vacating
+vacation
+vacation's
+vacationed
+vacationer
+vacationers
+vacationing
+vacations
+vaccinate
+vaccinated
+vaccinates
+vaccinating
+vaccination
+vaccination's
+vaccinations
+vaccine
+vaccine's
+vaccines
+vacillate
+vacillated
+vacillates
+w
+wackes
+wackier
+wackiest
+wackiness
+wackiness's
+wacko
+wackos
+wacky
+wad
+wad's
+wadded
+wadding
+wadding's
+waddle
+waddled
+waddles
+waddling
+wade
+waded
+wader
+wader's
+waders
+wades
+wadi
+wadi's
+wadies
+wading
+wadis
+wads
+x
+xenon
+xenon's
+xenophobia
+xenophobia's
+xenophobic
+xenophon's
+xerographic
+xerography
+xerography's
+xerox
+xerox's
+xeroxed
+xeroxes
+xeroxing
+xerxes
+xerxes's
+xhosa
+xhosa's
+xi'an
+xiaoping
+xiaoping's
+xingu
+xylem
+xylem's
+xylophone
+xylophone's
+xylophones
+xylophonist
+xylophonists
+y
+y'all
+ya
+yacht
+yacht's
+yachted
+yachting
+yachting's
+yachts
+yachtsman
+yachtsmen
+yahoo
+yahoo's
+yahoos
+yak
+yak's
+yakked
+yakking
+yaks
+yam
+yam's
+yammer
+yammered
+yammering
+yammers
+yams
+yank
+yanked
+yanking
+yanks
+z
+zanied
+zanier
+zanies
+zaniest
+zaniness
+zaniness's
+zany
+zanying
+zap
+zapped
+zapping
+zaps
+zeal
+zeal's
+zealot
+zealot's
+zealots
+zealous
+zealously
+zealousness
+zealousness's
+zebra
+zebra's
+zebras
+zebu
+zebu's
+zebus
+zed
+zed's
diff --git a/test/rwarray.ok b/test/rwarray.ok
new file mode 100644
index 00000000..8392135e
--- /dev/null
+++ b/test/rwarray.ok
@@ -0,0 +1,3 @@
+writea() returned 1, expecting 1
+reada() returned 1, expecting 1
+old and new are equal - GOOD
diff --git a/test/sortglos.awk b/test/sortglos.awk
new file mode 100755
index 00000000..e4f910d7
--- /dev/null
+++ b/test/sortglos.awk
@@ -0,0 +1,51 @@
+BEGIN {
+ pr="y";
+ npre=0;
+ po="n";
+ npos=0;
+ }
+
+pr=="y" { npre++; pre[npre]=$0; }
+$1=="@table" && $2=="@asis" { pr="n";nite++; next; }
+
+po=="y" { npos++; pos[npos]=$0; }
+$1=="@end" && $2=="table" {
+ po="y";
+ npos++;
+ pos[npos]=$0;
+ # last item...
+ vec[nite]=nlin;
+}
+
+ { nite++; }
+
+END {
+ for ( i=1; i<=npre; i++ ) { print pre[i]; }
+ if ( srt=="y" ) {
+ n=asorti(entr,ital);
+ ##print "n=",n;
+ for ( i=1; i<=n; i++ ) {
+ #printf("=========> %3.3d %s\n",i,ital[i]);
+ # ital[i] is the sorted key;
+ j=entr[ital[i]];
+ # j is the original item number
+ for ( k=1; k<=vec[j]; k++ ) {
+ print dat[j,k];
+ }
+ }
+ }
+ if ( srt=="n" ) {
+ for ( i=1; i<=nite; i++ ) {
+ printf("=========> %3.3d %2.2d %s\n",i,vec[i],titl[i]);
+ for ( j=1; j<=vec[i]; j++ ) {
+ print dat[i,j];
+ }
+ }
+ print "========================= END";
+ }
+ for ( i=1; i<=npos; i++ ) { print pos[i]; }
+ print "@c npre=" npre;
+ print "@c nite=" nite;
+ print "@c npos=" npos;
+}
+
diff --git a/test/sortglos.in b/test/sortglos.in
new file mode 100755
index 00000000..b24373de
--- /dev/null
+++ b/test/sortglos.in
@@ -0,0 +1,22 @@
+@node Glossario
+@unnumbered Glossario
+
+@table @asis
+@item Azione
+Una serie di istruzioni @command{awk} associate a una regola. Se
+l'espressione di ricerca della regola individua un record in input,
+@command{awk} esegue su quel record l'azione relativa. Le azioni sono
+sempre racchiuse fra parentesi graffe.
+(@xref{Panoramica sulle azioni}).
+
+@item Spazio bianco
+Una sequenza di spazi, TAB, o caratteri di "a capo" presenti in un record in
+input o in una stringa.
+@end table
+
+@end ifclear
+
+@c The GNU General Public License.
+
+@c aggiornato alla versione: settembre 2014
+@c ultimo aggiornamento: 14 novembre 2014
diff --git a/test/sortglos.ok b/test/sortglos.ok
new file mode 100644
index 00000000..69ddbe67
--- /dev/null
+++ b/test/sortglos.ok
@@ -0,0 +1,15 @@
+@node Glossario
+@unnumbered Glossario
+
+@table @asis
+@end table
+
+@end ifclear
+
+@c The GNU General Public License.
+
+@c aggiornato alla versione: settembre 2014
+@c ultimo aggiornamento: 14 novembre 2014
+@c npre=4
+@c nite=22
+@c npos=8
diff --git a/test/split_after_fpat.awk b/test/split_after_fpat.awk
new file mode 100644
index 00000000..7e7cfd99
--- /dev/null
+++ b/test/split_after_fpat.awk
@@ -0,0 +1,11 @@
+BEGIN { FPAT = "\"[^\"]*\"" }
+
+{ print $1 }
+
+END { f("hi there") }
+
+function f (p, a, n, i)
+{
+ n = split(p,a)
+ print n ; for (i=1; i<=n; i++) print a[i]
+}
diff --git a/test/split_after_fpat.in b/test/split_after_fpat.in
new file mode 100644
index 00000000..1aeefd59
--- /dev/null
+++ b/test/split_after_fpat.in
@@ -0,0 +1 @@
+a"stuff"b
diff --git a/test/split_after_fpat.ok b/test/split_after_fpat.ok
new file mode 100644
index 00000000..5c284490
--- /dev/null
+++ b/test/split_after_fpat.ok
@@ -0,0 +1,4 @@
+"stuff"
+2
+hi
+there
diff --git a/test/strftime.awk b/test/strftime.awk
index 775cd4e5..f1276c15 100644
--- a/test/strftime.awk
+++ b/test/strftime.awk
@@ -1,19 +1,35 @@
# 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
+BEGIN {
+ maxtries = 10
+ # On DOS/Windows, DATECMD is set by the Makefile to point to
+ # Unix-like 'date' command.
+ datecmd = DATECMD
+ if (datecmd == "")
+ datecmd = "date"
+ fmt = "%a %b %e %H:%M:%S %Z %Y"
-{
- $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
+ # loop until before equals after, thereby protecting
+ # against a race condition where the seconds field might have
+ # incremented between running date and strftime
+ i = 0
+ while (1) {
+ if (++i > maxtries) {
+ printf "Warning: this system is so slow that after %d attempts, we could never get two sequential invocations of strftime to give the same result!\n", maxtries > "/dev/stderr"
+ break
+ }
+ before = strftime(fmt)
+ datecmd | getline sd
+ after = strftime(fmt)
+ close(datecmd)
+ if (before == after) {
+ if (i > 1)
+ printf "Notice: it took %d loops to get the before and after strftime values to match\n", i > "/dev/stderr"
+ break
+ }
+ }
+ print sd > "strftime.ok"
+ print after > OUTPUT
}
diff --git a/test/symtab1.awk b/test/symtab1.awk
new file mode 100644
index 00000000..eeb01437
--- /dev/null
+++ b/test/symtab1.awk
@@ -0,0 +1,21 @@
+function dumparray(name, array, i)
+{
+ if (name == "ENVIRON" || name == "PROCINFO")
+ return
+
+ for (i in array)
+ if (isarray(array[i]))
+ dumparray(name "[" i "]", array[i])
+ else
+ printf("%s[%s] = %s\n", name, i, array[i])
+}
+
+BEGIN {
+ a[1] = 1
+ a[2][1] = 21
+ for (i in SYMTAB)
+ if (isarray(SYMTAB[i]))
+ dumparray(i, SYMTAB[i])
+ else
+ printf("SYMTAB[\"%s\"] = \"%s\"\n", i, SYMTAB[i])
+}
diff --git a/test/symtab1.ok b/test/symtab1.ok
new file mode 100644
index 00000000..04709e09
--- /dev/null
+++ b/test/symtab1.ok
@@ -0,0 +1,31 @@
+ARGV[0] = gawk
+SYMTAB["i"] = "i"
+SYMTAB["ROUNDMODE"] = "N"
+SYMTAB["ORS"] = "
+"
+SYMTAB["OFS"] = " "
+SYMTAB["LINT"] = "0"
+SYMTAB["FNR"] = "0"
+SYMTAB["ERRNO"] = ""
+SYMTAB["NR"] = "0"
+SYMTAB["IGNORECASE"] = "0"
+SYMTAB["TEXTDOMAIN"] = "messages"
+SYMTAB["NF"] = "0"
+SYMTAB["ARGIND"] = "0"
+a[1] = 1
+a[2][1] = 21
+SYMTAB["ARGC"] = "1"
+SYMTAB["FIELDWIDTHS"] = ""
+SYMTAB["CONVFMT"] = "%.6g"
+SYMTAB["SUBSEP"] = ""
+SYMTAB["PREC"] = "53"
+SYMTAB["RS"] = "
+"
+SYMTAB["FPAT"] = "[^[:space:]]+"
+SYMTAB["RT"] = ""
+SYMTAB["RLENGTH"] = "0"
+SYMTAB["OFMT"] = "%.6g"
+SYMTAB["FS"] = " "
+SYMTAB["RSTART"] = "0"
+SYMTAB["FILENAME"] = ""
+SYMTAB["BINMODE"] = "0"
diff --git a/test/symtab2.awk b/test/symtab2.awk
new file mode 100644
index 00000000..bb26f75d
--- /dev/null
+++ b/test/symtab2.awk
@@ -0,0 +1,6 @@
+BEGIN {
+ a = 5
+ printf "a = %d, SYMTAB[\"a\"] = %d\n", a, SYMTAB["a"]
+ SYMTAB["a"] = 4
+ printf "a = %d, SYMTAB[\"a\"] = %d\n", a, SYMTAB["a"]
+}
diff --git a/test/symtab2.ok b/test/symtab2.ok
new file mode 100644
index 00000000..23d2bf69
--- /dev/null
+++ b/test/symtab2.ok
@@ -0,0 +1,2 @@
+a = 5, SYMTAB["a"] = 5
+a = 4, SYMTAB["a"] = 4
diff --git a/test/symtab3.awk b/test/symtab3.awk
new file mode 100644
index 00000000..4c2026dc
--- /dev/null
+++ b/test/symtab3.awk
@@ -0,0 +1 @@
+BEGIN { a = 5 ; delete SYMTAB["a"] }
diff --git a/test/symtab3.ok b/test/symtab3.ok
new file mode 100644
index 00000000..5b283583
--- /dev/null
+++ b/test/symtab3.ok
@@ -0,0 +1,2 @@
+gawk: symtab3.awk:1: fatal: `delete' is not allowed with SYMTAB
+EXIT CODE: 2
diff --git a/test/symtab4.awk b/test/symtab4.awk
new file mode 100644
index 00000000..4eed7e99
--- /dev/null
+++ b/test/symtab4.awk
@@ -0,0 +1 @@
+{SYMTAB["POS"]=1 ; print $POS }
diff --git a/test/symtab4.in b/test/symtab4.in
new file mode 100644
index 00000000..d35e1920
--- /dev/null
+++ b/test/symtab4.in
@@ -0,0 +1,2 @@
+1 a
+2 b
diff --git a/test/symtab4.ok b/test/symtab4.ok
new file mode 100644
index 00000000..1191247b
--- /dev/null
+++ b/test/symtab4.ok
@@ -0,0 +1,2 @@
+1
+2
diff --git a/test/symtab5.awk b/test/symtab5.awk
new file mode 100644
index 00000000..e4fbc85f
--- /dev/null
+++ b/test/symtab5.awk
@@ -0,0 +1 @@
+BEGIN {SYMTAB["POS"]=1} {print $POS}
diff --git a/test/symtab5.in b/test/symtab5.in
new file mode 100644
index 00000000..d35e1920
--- /dev/null
+++ b/test/symtab5.in
@@ -0,0 +1,2 @@
+1 a
+2 b
diff --git a/test/symtab5.ok b/test/symtab5.ok
new file mode 100644
index 00000000..1191247b
--- /dev/null
+++ b/test/symtab5.ok
@@ -0,0 +1,2 @@
+1
+2
diff --git a/test/symtab6.awk b/test/symtab6.awk
new file mode 100644
index 00000000..d8f4cb1d
--- /dev/null
+++ b/test/symtab6.awk
@@ -0,0 +1 @@
+BEGIN {SYMTAB["POS"]=1}
diff --git a/test/symtab6.ok b/test/symtab6.ok
new file mode 100644
index 00000000..91f27e75
--- /dev/null
+++ b/test/symtab6.ok
@@ -0,0 +1,26 @@
+ARGC: 1
+ARGIND: 0
+ARGV: array, 1 elements
+BINMODE: 0
+CONVFMT: "%.6g"
+ERRNO: ""
+FIELDWIDTHS: ""
+FILENAME: ""
+FNR: 0
+FPAT: "[^[:space:]]+"
+FS: " "
+IGNORECASE: 0
+LINT: 0
+NF: 0
+NR: 0
+OFMT: "%.6g"
+OFS: " "
+ORS: "\n"
+PREC: 53
+RLENGTH: 0
+ROUNDMODE: "N"
+RS: "\n"
+RSTART: 0
+RT: ""
+SUBSEP: "\034"
+TEXTDOMAIN: "messages"
diff --git a/test/symtab7.awk b/test/symtab7.awk
new file mode 100644
index 00000000..eb051145
--- /dev/null
+++ b/test/symtab7.awk
@@ -0,0 +1,7 @@
+BEGIN {
+ getline
+ for (i = 1; i <= NF;++i)
+ SYMTAB[$i] = i
+}
+
+{ print $Age }
diff --git a/test/symtab7.in b/test/symtab7.in
new file mode 100644
index 00000000..d2b5645d
--- /dev/null
+++ b/test/symtab7.in
@@ -0,0 +1,3 @@
+Name Age
+John 30
+Jane 40
diff --git a/test/symtab7.ok b/test/symtab7.ok
new file mode 100644
index 00000000..28328831
--- /dev/null
+++ b/test/symtab7.ok
@@ -0,0 +1,2 @@
+30
+40
diff --git a/test/symtab8.awk b/test/symtab8.awk
new file mode 100644
index 00000000..2c808318
--- /dev/null
+++ b/test/symtab8.awk
@@ -0,0 +1,5 @@
+{
+ SYMTAB[$1] = 1
+}
+
+END { print $test }
diff --git a/test/symtab8.in b/test/symtab8.in
new file mode 100644
index 00000000..9daeafb9
--- /dev/null
+++ b/test/symtab8.in
@@ -0,0 +1 @@
+test
diff --git a/test/symtab8.ok b/test/symtab8.ok
new file mode 100644
index 00000000..724f374b
--- /dev/null
+++ b/test/symtab8.ok
@@ -0,0 +1,27 @@
+test
+ARGC: 2
+ARGIND: 1
+ARGV: array, 2 elements
+BINMODE: 0
+CONVFMT: "%.6g"
+ERRNO: ""
+FIELDWIDTHS: ""
+FNR: 1
+FPAT: "[^[:space:]]+"
+FS: " "
+IGNORECASE: 0
+LINT: 0
+NF: 1
+NR: 1
+OFMT: "%.6g"
+OFS: " "
+ORS: "\n"
+PREC: 53
+RLENGTH: 0
+ROUNDMODE: "N"
+RS: "\n"
+RSTART: 0
+RT: "\n"
+SUBSEP: "\034"
+TEXTDOMAIN: "messages"
+test: 1
diff --git a/test/symtab9.awk b/test/symtab9.awk
new file mode 100644
index 00000000..6b520147
--- /dev/null
+++ b/test/symtab9.awk
@@ -0,0 +1,19 @@
+BEGIN {
+ file = "testit.txt"
+ for (i = 1; i <= 3; i++)
+ print("line", i) > file
+ close(file)
+
+ ARGV[1] = file
+ ARGC = 2
+
+ for (i = 1; i <= 3; i++)
+ getline
+
+ printf "NR should be 3, is %d\n", SYMTAB["NR"]
+
+ # Can't do this here. Windows doesn't let you remove a file that
+ # is still open. Moving it to END won't help either, since the file
+ # (correctly) remain open until after the END finishes.
+ # system("rm testit.txt")
+}
diff --git a/test/symtab9.ok b/test/symtab9.ok
new file mode 100644
index 00000000..759a427d
--- /dev/null
+++ b/test/symtab9.ok
@@ -0,0 +1 @@
+NR should be 3, is 3
diff --git a/test/testext.ok b/test/testext.ok
new file mode 100644
index 00000000..a828ecb2
--- /dev/null
+++ b/test/testext.ok
@@ -0,0 +1,79 @@
+pets has 5 elements
+dump_array_and_delete: sym_lookup of pets passed
+dump_array_and_delete: incoming size is 5
+ pets["1"] = "blacky"
+ pets["2"] = "rusty"
+ pets["3"] = "sophie"
+dump_array_and_delete: marking element "3" for deletion
+ pets["4"] = "raincloud"
+ pets["5"] = "lucky"
+dump_array_and_delete(pets) returned 1
+dump_array_and_delete() did remove index "3"!
+
+try_modify_environ: sym_lookup of ENVIRON passed
+try_modify_environ: set_array_element of ENVIRON failed
+try_modify_environ: marking element "testext" for deletion
+try_del_environ() could not delete element - pass
+try_del_environ() could not add an element - pass
+var_test: sym_lookup of PROCINFO passed - got a value!
+var_test: sym_lookup of ARGC passed - got a value!
+var_test: sym_update of ARGC failed - correctly
+var_test: sym_update("testvar") succeeded
+var_test() returned 1, test_var = 42
+
+test_errno() returned 1, ERRNO = No child processes
+
+length of test_array is 10, should be 10
+test_array_size: incoming size is 10
+test_array_size() returned 1, length is now 0
+
+test_array_elem: a["3"] = "three"
+test_array_elem() returned 1, test_array2[3] = 42
+test_array_elem() did remove element "5"
+test_array_elem() added element "7" --> seven
+test_array2["subarray"]["hello"] = world
+test_array2["subarray"]["answer"] = 42
+
+test_array_param() returned 1
+isarray(a_new_array) = 1
+a_new_array["hello"] = world
+a_new_array["answer"] = 42
+test_array_param: argument is not undefined (1)
+test_array_param() returned 0
+isarray(a_scalar) = 0
+
+Initial value of LINT is 0
+print_do_lint: lint = 0
+print_do_lint() returned 1
+Changed value of LINT is 1
+print_do_lint: lint = 1
+print_do_lint() returned 1
+
+test_scalar(1) returned 1, the_scalar is 1
+test_scalar(3) returned 1, the_scalar is 3
+test_scalar(5) returned 1, the_scalar is 5
+test_scalar(7) returned 1, the_scalar is 7
+test_scalar(9) returned 1, the_scalar is 9
+test_scalar(11) returned 1, the_scalar is 11
+test_scalar(the) returned 1, the_scalar is the
+test_scalar(quick) returned 1, the_scalar is quick
+test_scalar(brown) returned 1, the_scalar is brown
+test_scalar(fox) returned 1, the_scalar is fox
+test_scalar(jumps) returned 1, the_scalar is jumps
+test_scalar(over) returned 1, the_scalar is over
+test_scalar(the) returned 1, the_scalar is the
+test_scalar(lazy) returned 1, the_scalar is lazy
+test_scalar(dog) returned 1, the_scalar is dog
+test_scalar_reserved: sym_lookup of ARGC passed - got a value!
+test_scalar_reserved: could not update new_value2 for ARGC - pass
+test_indirect_var: sym_lookup of NR passed
+test_indirect_var: value of NR is 3
+test_indirect_var() return 1
+answer_num = 42
+message_string = hello, world
+new_array["hello"] = "world"
+new_array["answer"] = "42"
+
+at_exit2 called (should be first): data = NULL, exit_status = 0
+at_exit1 called (should be second): (data is & data_for_1), data value = 0xdeadbeef, exit_status = 0
+at_exit0 called (should be third): data = NULL, exit_status = 0
diff --git a/test/time.awk b/test/time.awk
new file mode 100644
index 00000000..517377e2
--- /dev/null
+++ b/test/time.awk
@@ -0,0 +1,22 @@
+@load "time"
+
+# make sure gettimeofday() is consistent with systime(). We must call
+# gettimeofday() before systime() to make sure the subtraction gives 0
+# without risk of rolling over to the next second.
+function timecheck(st,res) {
+ res = gettimeofday()
+ st = systime()
+ printf "gettimeofday - systime = %d\n", res-st
+ return res
+}
+
+BEGIN {
+ delta = 1.3
+ t0 = timecheck()
+ printf "sleep(%s) = %s\n",delta,sleep(delta)
+ t1 = timecheck()
+ slept = t1-t0
+ if ((slept < 0.9*delta) || (slept > 1.3*delta))
+ printf "Warning: tried to sleep %.2f secs, but slept for %.2f secs\n",
+ delta,slept
+}
diff --git a/test/time.ok b/test/time.ok
new file mode 100644
index 00000000..46606bfe
--- /dev/null
+++ b/test/time.ok
@@ -0,0 +1,3 @@
+gettimeofday - systime = 0
+sleep(1.3) = 0
+gettimeofday - systime = 0
diff --git a/version.c b/version.c
index 4c1b6402..f5cf6ac0 100644
--- a/version.c
+++ b/version.c
@@ -1,3 +1,3 @@
#include "config.h"
-const char *version_string = "GNU Awk 4.0.70";
+const char *version_string = PACKAGE_STRING;
diff --git a/version.in b/version.in
deleted file mode 100644
index a489761a..00000000
--- a/version.in
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "config.h"
-
-const char *version_string = "@PACKAGE_STRING@";
diff --git a/vms/ChangeLog b/vms/ChangeLog
index 88a4bf88..c7dd4233 100644
--- a/vms/ChangeLog
+++ b/vms/ChangeLog
@@ -1,3 +1,302 @@
+2014-10-17 John E. Malmberg <wb8tyw@qsl.net>
+
+ * config_h.com: Use sys$disk: instead of prj_root: for
+ copying the configure file.
+ * gawk_alias_setup.com: Fix removal of out of date aliases.
+ * vmsbuild.com: Fix a typo for symbol CNAME and a case sensitive
+ test for "VAX" .eq. "vax" that failed. Also disable verify
+ while looking up the actual version.
+ * vmstest.com: Make sure that the test directory exists when
+ using a search list.
+
+2014-04-18 John E. Malmberg <wb8tyw@qsl.net>
+
+ * gawk_alias_setup.com: Fix problem with file links on Vax/VMS.
+
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.1: Release tar ball made.
+
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * descrip.mms, vmsbuild.com: Update patchlevel.
+
+2014-02-12 John E. Malmberg <wb8tyw@qsl.net>
+
+ * vmstest.com: (strftime) requires GNV Coreutils date command to run
+ (readdir) fix file cleanup to not generate warnings.
+
+2014-01-21 John E. Malmberg <wb8tyw@qsl.net>
+
+ * generate_config_vms_h_gawk.com: upate copyright and fix exit status.
+
+2014-01-17 John E. Malmberg <wb8tyw@qsl.net>
+
+ * vmstest.com (split_after_fpat): Added this test.
+
+2014-01-03 John E. Malmberg <wb8tyw@qsl.net>
+
+ * config_h.com, generate_config_vms_h_gawk.com,
+ vms_args.c, vms_cli.c, vms_fwrite.c, vms_gawk.c, vms_misc.c,
+ vms_popen.c: Update copyright to 2014.
+ * descrip.mms: Improve spotless cleanup.
+ * vmstest.com: Improve test cleanup.
+ * backup_gawk_src.com: New file. Create backup savesets for gawk source.
+ * build_gawk_pcsi_desc.com: New file. Create a pcsi$desc manifest
+ file for building a gawk package.
+ * build_gawk_pcsi_text.com: New file. Create a pcsi$text file for
+ building a gawk package.
+ * build_gawk_release_notes.com: New file. Create a VMS release notes
+ file based on the gawk README and COPYING files and the release note
+ start and build instruction files.
+ * compare_gawk_source.com: New file. Helper file to compare and
+ optionally update two gawk source directories. Used to copy
+ source from an NFS volume to a VMS native volume for backup.
+ * gawk_alias_setup.com: New file. Used at installation time to
+ create hard links for for some files instead of copies.
+ * gawk_build_steps.txt: New file. Document how to build a PCSI kit.
+ * gawk_release_note_start.txt: New file. Start of release notes.
+ * gawk_verb.com: New file. Converts the gawk.cld file into a
+ gawk_verb.cld file for setting up GAWK as a DCL command.
+ * gnv_gawk_startup.com: New file. Makes sure that the GNV$GNU logical
+ name need to easily find the gawk image is defined.
+ * make_pcsi_gawk_kit_name.com: New File. Create the PCSI kit name
+ based on the GAWK version.
+ * pcsi_gawk_file_list.txt: New File. Input file for creating the
+ pcsi$desc manifest file.
+ * pcsi_product_gawk.com: New file. File to create the PCSI kit.
+ * remove_old_gawk.com: New file. File to remove obsolete GNV gawk
+ files replaced by the new PCSI kit.
+ * stage_gawk_install.com: New file. Stages an install for the
+ pcsi kit building.
+
+2013-12-29 John E. Malmberg <wb8tyw@qsl.net>
+
+ * gawk_plugin.opt: New file. Needed to build plugins on IA64
+ and ALPHA.
+ * generate_config_vms_h_gawk.com: Document which version
+ of VMS the mkstemp issue was seen.
+ * vms_popen: (pclose): Tolerate invalid file pointer.
+ * vmstest.com: Add tests for extensions ported to VMS.
+
+2013-12-23 John E. Malmberg <wb8tyw@qsl.net>
+
+ * gawkmisc.vms: Fix program name calculation on VAX.
+ * vms_cli.c: Fix case of public symbol.
+ * vms.hlp: Fix typo, add cautions on rounding and timezones.
+ * vmstest.com: Dcl symbol tz causing conflict with test.
+
+2013-12-20 John E. Malmberg <wb8tyw@qsl.net>
+
+ * descrip.mms: Set CC exact symbol names, cleanup repository.
+ * generate_config_vms_h_gawk.com: Use correct VMS exit codes.
+ * vmsbuild.com: Set CC exact symbol names.
+ * vmstest.com: Extract correct Unix status for failed tests.
+ * vms.h, vms_args.c, vms_cli.c, vms_fwrite.c, vms_gawk.c,
+ vms_misc.c, vms_popen.c: Correct case of function names.
+ * vms.hlp: Updated with new information about exit codes.
+
+2013-12-10 John E. Malmberg <wb8tyw@qsl.net>
+
+ * gawkmisc.vms: Add lots of includes.
+ (sys_trnlnm): New function.
+ (gawk_name): Improved.
+ (os_arg_fixup): Fix up time zone.
+
+2013-12-08 John E. Malmberg <wb8tyw@qsl.net>
+
+ * descrip.mms: Add IEEE float for non-vax.
+ Add vms_crtl_init.c.
+ Remove code to generate version.c
+ * generate_config_vms_h_gawk.com (__attribute__): Removed
+ definition from here.
+ * version_c.com: removed no longer used.
+ * vmsbuild.com: Add IEEE float for non-vax.
+ Add vms_crtl_init.c
+ Remove code to generate version.c
+ Changes that should have been in the previous commit.
+ * vms_misc.c (vms_open): VMS CRTL for 8.3 Alpha is setting
+ errno to ENOENT instead of EISDIR for ".".
+
+2013-12-05 John E. Malmberg <wb8tyw@qsl.net>
+
+ * New config_h.com to generate config.h
+ * New gawk_ident.com generates ident line for link option file.
+ * Add version_c.com to create version.c from version.in.
+ * Remove fcntl.h covering up real fcntl.h. If an older version
+ of VMS needs this file, the build procedure should be updated
+ to generate it from a template.
+ * descrip.mms: Use command files to generate files based
+ on same input files as a Linux build.
+ * gawkmisc.vms (files_are_same): support _USE_STD_STAT for VMS 8.x.
+ * generate_config_vms_h_gawk.com: Generates a helper file
+ config_vms.h to cover issues config_h.com can not handle.
+ * vmsbuild.com: Use command files to generate files based
+ on the same input files as a Linux build.
+ * vms_misc.c (vms_open): VMS CRTL setting errno to ENOENT where
+ it should be set to EMFILE.
+
+2013-12-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * vms-conf.h (__attribute__): Removed definition from here; fixed
+ the issue in the main sources.
+
+2013-12-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ * vms-conf.h (ALLOW_SWITCH): Removed. No longer used.
+ (__attribute__): Define as empty.
+
+2013-08-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * vms-conf.h (RE_TOKEN_INIT_BUG): Remove define (change of
+ Feb 19 2005) since it's no longer needed.
+
+2013-06-03 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.c (init_sockets): New dummy function.
+
+2013-05-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * vms-conf.h: Remove obsolete HAVE_ST_BLKSIZE.
+
+2013-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.0: Release tar ball made.
+
+2012-05-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * vmsbuild.com (REL, PATCHLVL): Move to 4.1.0.
+ * descrip.mms (REL, PATCHLVL): Move to 4.1.0.
+ * vms-conf.h (VERSION, PACKAGE_VERSION, PACKAGE_STRING): Move to 4.1.0.
+
+2013-04-19 Anders Wallin <anders_s_wallin@yahoo.se>
+
+ * vmstest.com: Updated to match main test/Makefile.
+
+2012-12-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.2: Release tar ball made.
+
+2012-12-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * vmstest.com (paramuninitglobal): New test.
+
+2012-12-23 Arnold D. Robbins <arnold@skeeve.com>
+
+ * vmsbuild.com (REL, PATCHLVL): Move to 4.0.2.
+ * descrip.mms (REL, PATCHLVL): Move to 4.0.2.
+ * vms-conf.h (VERSION, PACKAGE_VERSION, PACKAGE_STRING): Move to 4.0.2.
+
+2012-12-18 John E. Malmberg <wb8tyw@qsl.net>
+
+ * descrip.mms: Make the build procedure run on a default directory
+ that is on a VMS logical name search list.
+ * vmstest.com: Make the tests run on a default directory that is on
+ a VMS logical name search list.
+
+2012-12-13 Anders Wallin <anders_s_wallin@yahoo.se>
+
+ * descrip.mms: Update to handle removal of pgawk and dgawk,
+ workaround for MMS bug
+
+2012-12-09 Anders Wallin <anders_s_wallin@yahoo.se>
+
+ * vmstest.com: Updated to match main test/Makefile.
+
+2012-12-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * vms_gawk.c (CmdName): Force to just "GAWK".
+
+2012-11-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * vmstest.com: Fix typo in applying previous patch.
+
+2012-11-22 Anders Wallin <anders_s_wallin@yahoo.se>
+
+ * vmstest.com: Updated to match main test/Makefile.
+
+2012-11-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * vmsbuild.com: Updated. Thanks to Anders Wallin.
+ * vms-conf.h: Ditto, ditto.
+
+2012-11-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.vms (os_isreadable): Change first argument type to
+ awk_input_buf_t.
+ * vms-conf.h (HAVE_STDINT_H): Define.
+ (SHLIBEXT, DEFLIBPATH): Add definitions.
+ * vms_fwrite.c (tty_fwrite): Check do_debug instead of no-longer-
+ extant which_gawk variable.
+ * vms_gawk.c (vms_gawk): Check do_debug and do_profiling instead
+ of which_gawk.
+
+ Thanks to Anders Wallin.
+
+2012-08-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.vms (os_isreadable): Take IOBUF_PUBLIC instead of fd and
+ use passed in info.
+
+2012-07-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.vms (os_isreadable): Add isdir pointer parameter to be
+ set to true if fd is for a directory.
+
+2012-07-26 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawkmisc.vms (os_isreadable): New function.
+
+2012-03-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * config.h: Add definition for _Noreturn.
+
+2012-03-20 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkmisc.vms (deflibpath): New global variable.
+
+2012-03-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.0.1: Release tar ball made.
+
+2012-03-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * vms-conf.h: Update copyright year.
+
+2012-03-21 Anders Wallin <anders_s_wallin@yahoo.se>
+
+ * vmstest.com: Make printfbad3 test work.
+
+2012-03-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * vmstest.com: Add printfbad3 test.
+
+2012-02-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * vmsbuild.com, descrip.mms, vms-conf.h: Update patch level.
+
+2011-12-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * vms_misc.c: [STREQ, STREQN]: Change use of macros to call
+ strcmp, strncmp, directly.
+
+2011-11-02 Pat Rankin <r.pat.rankin@gmail.com>
+
+ * vms-conf.h (HAVE_SETSID, HAVE_SYS_IOCTL): Add but leave undef'd.
+ (HAVE_ISWCTYPE, HAVE_ISWLOWER, HAVE_ISWUPPER, HAVE_MBRLEN,
+ HAVE_MBRTOWC, HAVE_TOWLOWER, HAVE_TOWUPPER, HAVE_WCHAR_H,
+ HAVE_WCRTOMB, HAVE_WCSCOLL, HAVE_WCTYPE, HAVE_WCTYPE_H,
+ HAVE_WCTYPE_T): Define as 1 since DEC C supports all these.
+
+ * descrip.mms (replace.obj): Add dependencies for missing_d/*.c.
+ * vmstest.com (unix_tests): Fix typo in spelling of rtlen01.
+
+2011-10-30 Pat Rankin <r.pat.rankin@gmail.com>
+
+ * vmstest.com (fpat3, fwtest3, getline5, gsubtst7, gsubtst8,
+ pty1, rtlen, rtlen01, rtlenmb): New tests.
+ (posix2008sub): Revised test.
+
2011-10-25 Anders Wallin <anders_s_wallin@yahoo.se>
* vmstest.com (posix2008sub): Added as specific test in order to
diff --git a/vms/backup_gawk_src.com b/vms/backup_gawk_src.com
new file mode 100644
index 00000000..d1e47fbe
--- /dev/null
+++ b/vms/backup_gawk_src.com
@@ -0,0 +1,113 @@
+$! File: Backup_gawk_src.com
+$!
+$! Procedure to create backup save sets for installing in a PCSI kit.
+$!
+$! To comply with most Open Source licenses, the source used for building
+$! a kit will be packaged with the distribution kit for the binary.
+$!
+$! Backup save sets are the only storage format that I can expect a
+$! VMS system to be able to extract ODS-5 filenames and directories.
+$!
+$! The make_pcsi_kit_name.com needs to be run before this procedure to
+$! properly name the files that will be created.
+$!
+$! This file is created from a template file for the purpose of making it
+$! easier to port Unix code, particularly open source code to VMS.
+$! Therefore permission is freely granted for any use.
+$!
+$! 13-Jun-2009 J. Malmberg
+$!
+$!===========================================================================
+$!
+$! Save default
+$ default_dir = f$environment("DEFAULT")
+$!
+$ arch_type = f$getsyi("ARCH_NAME")
+$ arch_code = f$extract(0, 1, arch_type)
+$!
+$ if arch_code .nes. "V"
+$ then
+$ set proc/parse=extended
+$ endif
+$!
+$ ss_abort = 44
+$ status = ss_abort
+$!
+$ kit_name = f$trnlnm("GNV_PCSI_KITNAME")
+$ if kit_name .eqs. ""
+$ then
+$ write sys$output "@MAKE_PCSI_GAWK_KIT_NAME.COM has not been run."
+$ goto all_exit
+$ endif
+$ producer = f$trnlnm("GNV_PCSI_PRODUCER")
+$ if producer .eqs. ""
+$ then
+$ write sys$output "@MAKE_PCSI_GAWK_KIT_NAME.COM has not been run."
+$ goto all_exit
+$ endif
+$ filename_base = f$trnlnm("GNV_PCSI_FILENAME_BASE")
+$ if filename_base .eqs. ""
+$ then
+$ write sys$output "@MAKE_PCSI_GAWK_KIT_NAME.COM has not been run."
+$ goto all_exit
+$ endif
+$!
+$ node_swvers = f$getsyi("NODE_SWVERS")
+$ node_swvers_type = f$extract(0, 1, node_swvers)
+$ node_swvers_vers = f$extract(1, f$length(node_swvers), node_swvers)
+$ swvers_maj = f$element(0, ".", node_swvers_vers)
+$ node_swvers_min_update = f$element(1, ".", node_swvers_vers)
+$ swvers_min = f$element(0, "-", node_swvers_min_update)
+$ swvers_update = f$element(1, "-", node_swvers_min_update)
+$!
+$ if swvers_update .eqs. "-" then swvers_update = ""
+$!
+$ vms_vers = f$fao("!2ZB!2ZB!AS", 'swvers_maj', 'swvers_min', swvers_update)
+$!
+$!
+$!
+$! If available make an interchange save set
+$!-------------------------------------------
+$ interchange = ""
+$ if arch_code .eqs. "V"
+$ then
+$ interchange = "/interchange"
+$ endif
+$ if (swvers_maj .ges. "8") .and. (swvers_min .ges. 4)
+$ then
+$ interchange = "/interchange/noconvert"
+$ endif
+$!
+$!
+$! Put things back on error.
+$ on warning then goto all_exit
+$!
+$ current_default = f$environment("DEFAULT")
+$ my_dir = f$parse(current_default,,,"DIRECTORY") - "[" - "<" - ">" - "]"
+$!
+$ src_root = "src_root:"
+$ if f$trnlnm("src_root1") .nes. "" then src_root = "src_root1:"
+$ backup'interchange' 'src_root'[gawk...]*.*;0 -
+ 'filename_base'_original_src.bck/sav
+$ status = $status
+$!
+$! There may be a VMS specific source kit
+$!-----------------------------------------
+$ vms_root = "vms_root:"
+$ if f$trnlnm("vms_root1") .nes. "" then vms_root = "vms_root1:"
+$ files_found = 0
+$ define/user sys$error nl:
+$ define/user sys$output nl:
+$ directory 'vms_root'[...]*.*;*/exc=*.dir
+$ if '$severity' .eq. 1 then files_found = 1
+$!
+$ if files_found .eq. 1
+$ then
+$ backup'interchange' 'vms_root'[gawk...]*.*;0 -
+ 'filename_base'_vms_src.bck/sav
+$ status = $status
+$ endif
+$!
+$all_exit:
+$ set def 'default_dir'
+$ exit
diff --git a/vms/build_gawk_pcsi_desc.com b/vms/build_gawk_pcsi_desc.com
new file mode 100644
index 00000000..63d149e6
--- /dev/null
+++ b/vms/build_gawk_pcsi_desc.com
@@ -0,0 +1,428 @@
+$! File: Build_GAWK_PCSI_DESC.COM
+$!
+$! Build the *.pcsi$text file in the following sections:
+$! Required software dependencies.
+$! install/upgrade/postinstall steps.
+$! 1. Duplicate filenames need an alias procedure.
+$! 2. ODS-5 filenames need an alias procedure.
+$! 3. Special alias links for executables (cp. -> gnv$cp.exe)
+$! if a lot, then an alias procedure is needed.
+$! 4. Rename the files to lowercase.
+$! Move Release Notes to destination
+$! Source kit option
+$! Create directory lines
+$! Add file lines for gawk.
+$! Add Link alias procedure file (used for gawk)
+$! Add [.SYS$STARTUP]gawk_startup file
+$! Add Release notes file.
+$!
+$! The file PCSI_GAWK_FILE_LIST.TXT is read in to get the files other
+$! than the release notes file and the source backup file.
+$!
+$! The PCSI system can really only handle ODS-2 format filenames and
+$! assumes that there is only one source directory. It also assumes that
+$! all destination files with the same name come from the same source file.
+$! Fortunately GAWK does not trip most of these issues, so those steps
+$! above are marked N/A.
+$!
+$! A rename action section is needed to make sure that the files are
+$! created in the GNV$GNU: in the correct case, and to create the alias
+$! link [usr.bin]gawk. for [usr.bin]gawk.exe.
+$!
+$! 02-Jan-2014 J. Malmberg - Gawk version
+$!
+$!===========================================================================
+$!
+$ kit_name = f$trnlnm("GNV_PCSI_KITNAME")
+$ if kit_name .eqs. ""
+$ then
+$ write sys$output "@[.vms]MAKE_PCSI_GAWK_KIT_NAME.COM has not been run."
+$ goto all_exit
+$ endif
+$ producer = f$trnlnm("GNV_PCSI_PRODUCER")
+$ if producer .eqs. ""
+$ then
+$ write sys$output "@[.vms]MAKE_PCSI_GAWK_KIT_NAME.COM has not been run."
+$ goto all_exit
+$ endif
+$ filename_base = f$trnlnm("GNV_PCSI_FILENAME_BASE")
+$ if filename_base .eqs. ""
+$ then
+$ write sys$output "@[.vms]MAKE_PCSI_GAWK_KIT_NAME.COM has not been run."
+$ goto all_exit
+$ endif
+$!
+$!
+$! Parse the kit name into components.
+$!---------------------------------------
+$ producer = f$element(0, "-", kit_name)
+$ base = f$element(1, "-", kit_name)
+$ product = f$element(2, "-", kit_name)
+$ mmversion = f$element(3, "-", kit_name)
+$ majorver = f$extract(0, 3, mmversion)
+$ minorver = f$extract(3, 2, mmversion)
+$ updatepatch = f$element(4, "-", kit_name)
+$ if updatepatch .eqs. "-" then updatepatch = ""
+$!
+$! kit type of "D" means a daily build
+$ kit_type = f$edit(f$extract(0, 1, majorver), "upcase")
+$!
+$!
+$ product_line = "product ''producer' ''base' ''product'"
+$ if updatepatch .eqs. ""
+$ then
+$ product_name = " ''majorver'.''minorver'"
+$ else
+$ product_name = " ''majorver'.''minorver'-''updatepatch'"
+$ endif
+$ product_line = product_line + " ''product_name' full;"
+$!write sys$output product_line
+$!
+$!
+$!
+$! Create the file as a VMS text file.
+$!----------------------------------------
+$ base_file = kit_name
+$ create 'base_file'.pcsi$desc
+$!
+$!
+$! Start building file.
+$!----------------------
+$ open/append pdsc 'base_file'.pcsi$desc
+$!
+$ write pdsc product_line
+$!
+$! Required product dependencies.
+$!----------------------------------
+$ vmsprd = "DEC"
+$ if base .eqs. "I64VMS" then vmsprd = "HP"
+$!
+$ write pdsc " software ''vmsprd' ''base' VMS ;"
+$ arch_type = f$getsyi("ARCH_NAME")
+$ node_swvers = f$getsyi("node_swvers")
+$ vernum = f$extract(1, f$length(node_swvers), node_swvers)
+$ majver = f$element(0, ".", vernum)
+$ minverdash = f$element(1, ".", vernum)
+$ minver = f$element(0, "-", minverdash)
+$ dashver = f$element(1, "-", minverdash)
+$ if dashver .eqs. "-" then dashver = ""
+$ vmstag = majver + minver + dashver
+$ code = f$extract(0, 1, arch_type)
+$ arch_code = f$extract(0, 1, arch_type)
+$ write pdsc -
+ " if (not <software ''vmsprd' ''base' VMS version minimum ''node_swvers'>) ;"
+$ write pdsc " error NEED_VMS''vmstag';"
+$ write pdsc " end if;"
+$!
+$!
+$!
+$! install/upgrade/postinstall steps.
+$!-----------------------------------
+$! 1. Duplicate filenames need an alias procedure.
+$! 2. ODS-5 filenames need an alias procedure.
+$! 3. Special alias links for executables (gawk. -> gnv$gawk.exe)
+$! if a lot, then an alias procedure is needed.
+$! 4. Rename the files to lowercase.
+$!
+$!
+$! Alias links needed.
+$!-------------------------
+$ add_alias_lines = ""
+$ rem_alias_lines = ""
+$ line_out = ""
+$!
+$! Read through the file list to set up aliases and rename commands.
+$!---------------------------------------------------------------------
+$ open/read flst [.vms]pcsi_gawk_file_list.txt
+$!
+$inst_alias_loop:
+$ read/end=inst_alias_loop_end flst line_in
+$ line_in = f$edit(line_in,"compress,trim,uncomment")
+$ if line_in .eqs. "" then goto inst_alias_loop
+$ pathname = f$element(0, " ", line_in)
+$ linkflag = f$element(1, " ", line_in)
+
+$ if linkflag .nes. "->" then goto inst_alias_write
+$!
+$ linktarget = f$element(2, " ", line_in)
+$ nlink = "pcsi$destination:" + pathname
+$ ntarg = "pcsi$destination:" + linktarget
+$ new_add_alias_line = -
+ """if f$search(""""''nlink'"""") .eqs. """""""" then" + -
+ " set file/enter=''nlink' ''ntarg'"""
+$ if add_alias_lines .nes. ""
+$ then
+$ add_alias_lines = add_alias_lines + "," + new_add_alias_line
+$ else
+$ add_alias_lines = new_add_alias_line
+$ endif
+$!
+$ new_rem_alias_line = -
+ """if f$search(""""''nlink'"""") .nes. """""""" then" + -
+ " set file/remove ''nlink';"""
+$ if rem_alias_lines .nes. ""
+$ then
+$ rem_alias_lines = rem_alias_lines + "," + new_rem_alias_line
+$ else
+$ rem_alias_lines = new_rem_alias_line
+$ endif
+$!
+$ goto inst_alias_loop
+$!
+$inst_alias_write:
+$!
+$! execute install / remove
+$ write pdsc " execute install ("
+$! add aliases
+$ i = 0
+$ex_ins_loop:
+$ line = f$element(i, ",", add_alias_lines)
+$ i = i + 1
+$ if line .eqs. "" then goto ex_ins_loop
+$ if line .eqs. "," then goto ex_ins_loop_end
+$ if line_out .nes. "" then write pdsc line_out,","
+$ line_out = line
+$ goto ex_ins_loop
+$ex_ins_loop_end:
+$ if line_out .eqs. "" then line_out = " ""continue"""
+$ write pdsc line_out
+$ line_out = ""
+$ write pdsc " )"
+$ write pdsc " remove ("
+$! remove aliases
+$ line_out = -
+ " ""@pcsi$destination:[gnv.vms_bin]gawk_alias_setup.com remove"""
+$ i = 0
+$ex_rem_loop:
+$ line = f$element(i, ",", rem_alias_lines)
+$ i = i + 1
+$ if line .eqs. "" then goto ex_rem_loop
+$ if line .eqs. "," then goto ex_rem_loop_end
+$ if line_out .nes. "" then write pdsc line_out,","
+$ line_out = line
+$ goto ex_rem_loop
+$ex_rem_loop_end:
+$ if line_out .eqs. "" then line_out = " ""continue"""
+$ write pdsc line_out
+$ line_out = ""
+$ write pdsc " ) ;"
+$!
+$! execute upgrade
+$ write pdsc " execute upgrade ("
+$ line_out = -
+ " ""@pcsi$destination:[gnv.vms_bin]gawk_alias_setup.com remove"""
+$ i = 0
+$ex_upg_loop:
+$ line = f$element(i, ",", rem_alias_lines)
+$ i = i + 1
+$ if line .eqs. "" then goto ex_upg_loop
+$ if line .eqs. "," then goto ex_upg_loop_end
+$ if line_out .nes. "" then write pdsc line_out,","
+$ line_out = line
+$ goto ex_upg_loop
+$ex_upg_loop_end:
+$ if line_out .eqs. "" then line_out = " ""continue"""
+$ write pdsc line_out
+$ line_out = ""
+$! remove aliases
+$ write pdsc " ) ;"
+$!
+$! execute postinstall
+$ write pdsc " execute postinstall ("
+$ if arch_code .nes. "V"
+$ then
+$ line_out = " ""set process/parse=extended"","
+$ write pdsc line_out
+$ endif
+$ line_out = " ""@pcsi$destination:[gnv.vms_bin]remove_old_gawk.com"","
+$ write pdsc line_out
+$ line_out = " ""@pcsi$destination:[gnv.vms_bin]gawk_alias_setup.com"""
+$ i = 0
+$ex_pins_loop:
+$ line = f$element(i, ",", add_alias_lines)
+$ i = i + 1
+$ if line .eqs. "" then goto ex_pins_loop
+$ if line .eqs. "," then goto ex_pins_loop_end
+$ if line_out .nes. "" then write pdsc line_out,","
+$ line_out = line
+$ goto ex_pins_loop
+$ex_pins_loop_end:
+$ if line_out .eqs. "" then line_out = " ""continue"""
+$! write pdsc line_out
+$! line_out = ""
+$! add aliases and follow with renames.
+$!
+$goto inst_dir
+$!
+$inst_dir_loop:
+$ read/end=inst_alias_loop_end flst line_in
+$ line_in = f$edit(line_in,"compress,trim,uncomment")
+$ if line_in .eqs. "" then goto inst_dir_loop
+$inst_dir:
+$ pathname = f$element(0, " ", line_in)
+$!
+$! Ignore the directory entries for now.
+$!-----------------------------------------
+$ filedir = f$parse(pathname,,,"DIRECTORY")
+$ if pathname .eqs. filedir then goto inst_dir_loop
+$!
+$! process .dir extensions for rename
+$! If this is not a directory then start processing files.
+$!-------------------------
+$ filetype = f$parse(pathname,,,"TYPE")
+$ filetype_u = f$edit(filetype, "upcase")
+$ filename = f$parse(pathname,,,"NAME")
+$ if filetype_u .nes. ".DIR" then goto inst_file
+$!
+$! process directory lines for rename.
+$!--------------------------------------
+$ if line_out .nes. ""
+$ then
+$ write pdsc line_out,","
+$ line_out = ""
+$ endif
+$ if arch_code .nes. "V"
+$ then
+$ if line_out .nes. "" then write pdsc line_out,","
+$ line_out = " ""rename pcsi$destination:''pathname' ''filename'.DIR"""
+$ else
+$ if line_out .nes. "" then write pdsc line_out
+$ line_out = ""
+$ endif
+$ goto inst_dir_loop
+$!
+$!
+$! process file lines for rename
+$!---------------------------------
+$inst_file_loop:
+$ read/end=inst_alias_loop_end flst line_in
+$ line_in = f$edit(line_in,"compress,trim,uncomment")
+$ if line_in .eqs. "" then goto inst_dir_loop
+$ pathname = f$element(0, " ", line_in)
+$!
+$! Filenames with $ in them are VMS special and do not need to be lowercased.
+$! --------------------------------------------------------------------------
+$ if f$locate("$", pathname) .lt. f$length(pathname) then goto inst_file_loop
+$!
+$ filetype = f$parse(pathname,,,"TYPE")
+$ filename = f$parse(pathname,,,"NAME") + filetype
+$inst_file:
+$ if arch_code .nes. "V"
+$ then
+$ if line_out .nes. "" then write pdsc line_out,","
+$ filetype = f$parse(pathname,,,"TYPE")
+$ filename = f$parse(pathname,,,"NAME") + filetype
+$ line_out = " ""rename pcsi$destination:''pathname' ''filename'"""
+$ else
+$ if line_out .nes. "" then write pdsc line_out
+$ line_out = ""
+$ endif
+$ goto inst_file_loop
+$!
+$inst_alias_loop_end:
+$!
+$write pdsc line_out
+$write pdsc " ) ;"
+$close flst
+$!
+$! Move Release Notes to destination
+$!-------------------------------------
+$write pdsc " information RELEASE_NOTES phase after ;"
+$!
+$! Source kit option
+$!---------------------
+$write pdsc " option SOURCE default 0;"
+$write pdsc " directory ""[gnv.common_src]"" PROTECTION PUBLIC ;"
+$write pdsc -
+ " file ""[gnv.common_src]''filename_base'_original_src.bck"""
+$write pdsc -
+ " source [common_src]''filename_base'_original_src.bck ;"
+$if f$search("sys$disk:''filename_base'_vms_src.bck") .nes. ""
+$then
+$ write pdsc " directory ""[gnv.vms_src]"" PROTECTION PUBLIC ;"
+$ write pdsc " file ""[gnv.vms_src]''filename_base'_vms_src.bck"""
+$ write pdsc " source [vms_src]''filename_base'_vms_src.bck ;"
+$endif
+$write pdsc " end option;"
+$!
+$!
+$! Read through the file list again.
+$!----------------------------------
+$open/read flst [.vms]pcsi_gawk_file_list.txt
+$!
+$!
+$! Create directory lines
+$!-------------------------
+$flst_dir_loop:
+$ read/end=flst_loop_end flst line_in
+$ line_in = f$edit(line_in,"compress,trim,uncomment")
+$ if line_in .eqs. "" then goto flst_dir_loop
+$!
+$ filename = f$element(0, " ", line_in)
+$ linkflag = f$element(1, " ", line_in)
+$ if linkflag .eqs. "->" then goto flst_dir_loop
+$!
+$! Ignore .dir extensions
+$!-------------------------
+$ filetype = f$edit(f$parse(filename,,,"TYPE"), "upcase")
+$ if filetype .eqs. ".DIR" then goto flst_dir_loop
+$!
+$ destname = filename
+$!
+$! It should be just a directory then.
+$!-------------------------------------
+$ filedir = f$edit(f$parse(filename,,,"DIRECTORY"), "lowercase")
+$! If this is not a directory then start processing files.
+$!---------------------------------------------------------
+$ if filename .nes. filedir then goto flst_file
+$!
+$ write pdsc " directory ""''destname'"" PROTECTION PUBLIC ;"
+$ goto flst_dir_loop
+$!
+$!
+$! Add file lines for gawk.
+$!---------------------------
+$flst_file_loop:
+$ read/end=flst_loop_end flst line_in
+$ line_in = f$edit(line_in,"compress,trim,uncomment")
+$ if line_in .eqs. "" then goto flst_file_loop
+$ filename = f$element(0, " ", line_in)
+$ destname = filename
+$flst_file:
+$ if arch_code .eqs. "V"
+$ then
+$! ! These files not available on VAX.
+$ src_dir = f$parse(destname,,,"DIRECTORY")
+$ if src_dir .eqs. "[GNV.USR.LIB.GAWK]" then goto flst_file_loop
+$ endif
+$ srcfile = filename - "gnv."
+$ write pdsc " file ""''destname'"" "
+$ write pdsc " source ""''srcfile'"" ;"
+$ goto flst_file_loop
+$!
+$flst_loop_end:
+$ close flst
+$!
+$! Add Link alias procedure file (N/A for gawk)
+$!-----------------------------------------------------
+$ write pdsc " file ""[vms_bin]gawk_alias_setup.com"""
+$ write pdsc " source [vms_bin]gawk_alias_setup.com ;"
+$!
+$! Add [.SYS$STARTUP]gawk_startup file
+$!---------------------------------------
+$ write pdsc " file ""[sys$startup]gnv$gawk_startup.com"""
+$ write pdsc " source [vms_bin]gnv$gawk_startup.com ;"
+$!
+$! Add Release notes file.
+$!------------------------------
+$ write pdsc -
+ " file ""[SYSHLP]''filename_base'.release_notes"" release notes ;"
+$!
+$! Close the product file
+$!------------------------
+$ write pdsc "end product;"
+$!
+$close pdsc
+$!
+$all_exit:
+$ exit
diff --git a/vms/build_gawk_pcsi_text.com b/vms/build_gawk_pcsi_text.com
new file mode 100644
index 00000000..a1053cf6
--- /dev/null
+++ b/vms/build_gawk_pcsi_text.com
@@ -0,0 +1,179 @@
+$! File: build_gawk_pcsi_text.com
+$!
+$! Build the *.pcsi$text file from the four components:
+$! 1. Generated =product header section
+$! 2. readme. file from the Gawk distribution, modified to fit
+$! a pcsi$text file format.
+$! 3. copying file from the Gawk distribution, modified to fit
+$! a pcsi$text file format.
+$! 4. Generated Producer section.
+$!
+$! Set the name of the release notes from the GNV_PCSI_FILENAME_BASE
+$!
+$!
+$! 02-Jan-2014 J. Malmberg - Gawk version
+$!
+$!===========================================================================
+$!
+$ kit_name = f$trnlnm("GNV_PCSI_KITNAME")
+$ if kit_name .eqs. ""
+$ then
+$ write sys$output "@MAKE_PCSI_GAWK_KIT_NAME.COM has not been run."
+$ goto all_exit
+$ endif
+$ producer = f$trnlnm("GNV_PCSI_PRODUCER")
+$ if producer .eqs. ""
+$ then
+$ write sys$output "@MAKE_PCSI_GAWK_KIT_NAME.COM has not been run."
+$ goto all_exit
+$ endif
+$ producer_full_name = f$trnlnm("GNV_PCSI_PRODUCER_FULL_NAME")
+$ if producer_full_name .eqs. ""
+$ then
+$ write sys$output "@MAKE_PCSI_GAWK_KIT_NAME.COM has not been run."
+$ goto all_exit
+$ endif
+$!
+$!
+$! Parse the kit name into components.
+$!---------------------------------------
+$ producer = f$element(0, "-", kit_name)
+$ base = f$element(1, "-", kit_name)
+$ product = f$element(2, "-", kit_name)
+$ mmversion = f$element(3, "-", kit_name)
+$ majorver = f$extract(0, 3, mmversion)
+$ minorver = f$extract(3, 2, mmversion)
+$ updatepatch = f$element(4, "-", kit_name)
+$ if updatepatch .eqs. "-" then updatepatch = ""
+$!
+$!
+$ product_line = "=product ''producer' ''base' ''product'"
+$ if updatepatch .eqs. ""
+$ then
+$ product_name = " ''majorver'.''minorver'"
+$ else
+$ product_name = " ''majorver'.''minorver'-''updatepatch'"
+$ endif
+$ product_line = product_line + " ''product_name' full"
+$!
+$!
+$! If this is VAX and the file is on NFS, the names may be mangled.
+$!-----------------------------------------------------------------
+$ readme_file = ""
+$ if f$search("readme.") .nes. ""
+$ then
+$ readme_file = "readme."
+$ else
+$ if f$search("$README.") .nes. ""
+$ then
+$ readme_file = "$README."
+$ else
+$ write sys$output "Can not find readme file."
+$ goto all_exit
+$ endif
+$ endif
+$ copying_file = ""
+$ if f$search("copying.") .nes. ""
+$ then
+$ copying_file = "copying."
+$ else
+$ if f$search("$COPYING.") .nes. ""
+$ then
+$ copying_file = "$COPYING."
+$ else
+$ write sys$output "Can not find copying file."
+$ goto all_exit
+$ endif
+$ endif
+$!
+$! Create the file as a VMS text file.
+$!----------------------------------------
+$ base_file = kit_name
+$ create 'base_file'.pcsi$text
+$!
+$!
+$! Start building file.
+$!----------------------
+$ open/append ptxt 'base_file'.pcsi$text
+$ write ptxt product_line
+$!
+$!
+$! First insert the Readme file.
+$!
+$ open/read rf 'readme_file'
+$!
+$ write ptxt "1 'PRODUCT"
+$ write ptxt "=prompt ''producter' ''product' for OpenVMS"
+$!
+$rf_loop:
+$ read/end=rf_loop_end rf line_in
+$ if line_in .nes. ""
+$ then
+$! PCSI files use the first character in for their purposes.
+$!--------------------------------------------------------------
+$ first_char = f$extract(0, 1, line_in)
+$ if first_char .nes. " " then line_in = " " + line_in
+$ endif
+$ write ptxt line_in
+$ goto rf_loop
+$rf_loop_end:
+$ close rf
+$!
+$!
+$! Now add in the copying file
+$!--------------------------------
+$ write ptxt ""
+$ write ptxt "1 'NOTICE"
+$ write ptxt ""
+$!
+$ open/read cf 'copying_file'
+$!
+$cf_loop:
+$ read/end=cf_loop_end cf line_in
+$ if line_in .nes. ""
+$ then
+$! PCSI files use the first character in for their purposes.
+$!--------------------------------------------------------------
+$ first_char = f$extract(0, 1, line_in)
+$ if first_char .nes. " " then line_in = " " + line_in
+$ endif
+$ write ptxt line_in
+$ goto cf_loop
+$cf_loop_end:
+$ close cf
+$!
+$! Now we need the rest of the boiler plate.
+$!--------------------------------------------
+$ write ptxt ""
+$ write ptxt "1 'PRODUCER"
+$ write ptxt "=prompt ''producer_full_name'"
+$ write ptxt -
+ "This software product is provided by ''producer_full_name' with no warranty."
+$!
+$ arch_type = f$getsyi("ARCH_NAME")
+$ node_swvers = f$getsyi("node_swvers")
+$ vernum = f$extract(1, f$length(node_swvers), node_swvers)
+$ majver = f$element(0, ".", vernum)
+$ minverdash = f$element(1, ".", vernum)
+$ minver = f$element(0, "-", minverdash)
+$ dashver = f$element(1, "-", minverdash)
+$ if dashver .eqs. "-" then dashver = ""
+$ vmstag = majver + minver + dashver
+$ code = f$extract(0, 1, arch_type)
+$!
+$ write ptxt "1 NEED_VMS''vmstag'"
+$ write ptxt -
+ "=prompt OpenVMS ''vernum' or later is not installed on your system."
+$ write ptxt "This product requires OpenVMS ''vernum' or later to function."
+$ write ptxt "1 SOURCE"
+$ write ptxt "=prompt Source modules for ''product'"
+$ write ptxt "The Source modules for ''product' will be installed."
+$ write ptxt "1 RELEASE_NOTES"
+$ write ptxt "=prompt Release notes are available in the [SYSHLP] directory."
+$!
+$ close ptxt
+$!
+$!
+$!
+$all_exit:
+$ exit
diff --git a/vms/build_gawk_release_notes.com b/vms/build_gawk_release_notes.com
new file mode 100644
index 00000000..c088ff8c
--- /dev/null
+++ b/vms/build_gawk_release_notes.com
@@ -0,0 +1,67 @@
+$! File: Build_gawk_release_notes.com
+$!
+$! Build the release note file from the three components:
+$! 1. The gawk_release_note_start.txt
+$! 2. readme. file from the Gawk distribution.
+$! 3. The gawk_build_steps.txt.
+$!
+$! Set the name of the release notes from the GNV_PCSI_FILENAME_BASE
+$! logical name.
+$!
+$!
+$! 31-Dec-2013 J. Malmberg
+$!
+$!===========================================================================
+$!
+$ base_file = f$trnlnm("GNV_PCSI_FILENAME_BASE")
+$ if base_file .eqs. ""
+$ then
+$ write sys$output "@MAKE_PCSI_GAWK_KIT_NAME.COM has not been run."
+$ goto all_exit
+$ endif
+$!
+$ gawk_vms_readme = f$search("sys$disk:[.readme_d]readme.vms")
+$ if gawk_vms_readme .eqs. ""
+$ then
+$ gawk_vms_readme = f$search("sys$disk:[.$README_$D]$README.VMS")
+$ endif
+$ if gawk_vms_readme .eqs. ""
+$ then
+$ write sys$output "Can not find gawk README.VMS file."
+$ goto all_exit
+$ endif
+$!
+$ gawk_readme = f$search("sys$disk:[]readme.")
+$ if gawk_readme .eqs. ""
+$ then
+$ gawk_readme = f$search("sys$disk:[]$README.")
+$ endif
+$ if gawk_readme .eqs. ""
+$ then
+$ write sys$output "Can not find gawk readme file."
+$ goto all_exit
+$ endif
+$!
+$ gawk_copying = f$search("sys$disk:[]copying.")
+$ if gawk_copying .eqs. ""
+$ then
+$ gawk_copying = f$search("sys$disk:[]$COPYING.")
+$ endif
+$ if gawk_copying .eqs. ""
+$ then
+$ write sys$output "Can not find gawk copying file."
+$ goto all_exit
+$ endif
+$!
+$ type/noheader sys$disk:[.vms]gawk_release_note_start.txt,-
+ 'gawk_readme',-
+ 'gawk_vms_readme',-
+ 'gawk_copying', -
+ sys$disk:[.vms]gawk_build_steps.txt -
+ /out='base_file'.release_notes
+$!
+$ purge 'base_file'.release_notes
+$ rename 'base_file.release_notes ;1
+$!
+$all_exit:
+$ exit
diff --git a/vms/compare_gawk_source.com b/vms/compare_gawk_source.com
new file mode 100644
index 00000000..260ec4eb
--- /dev/null
+++ b/vms/compare_gawk_source.com
@@ -0,0 +1,367 @@
+$! Compare_gawk_source.com
+$!
+$! This procedure compares the files in two directories and reports the
+$! differences.
+$!
+$! It needs to be customized to the local site directories.
+$!
+$! This is used by me for these purposes:
+$! 1. Compare the original source of a project with an existing
+$! VMS port.
+$! 2. Compare the checked out repository of a project with the
+$! the local working copy to make sure they are in sync.
+$! 3. Keep a copy directory up to date. The third is needed by
+$! me because VMS Backup can create a saveset of files from a
+$! NFS mounted volume.
+$!
+$! First the files in the original source directory which is assumed to be
+$! under source codde control are compared with the copy directory.
+$!
+$! Then the files are are only in the copy directory are listed.
+$!
+$! The result will five diagnostics about of files:
+$! 1. Files that are not generation 1.
+$! 2. Files missing in the copy directory.
+$! 3. Files in the copy directory not in the source directory.
+$! 4. Files different from the source directory.
+$! 5. Files that VMS DIFF can not process.
+$!
+$! This needs to be run on an ODS-5 volume.
+$!
+$! If UPDATE is given as a second parameter, files missing or different in the
+$! copy directory will be updated.
+$!
+$! By default:
+$! The source directory is source_root:[gawk.reference.gawk],
+$! the logical used on my system for the GNV Mecurial repository checkout.
+$! If source_root: is not defined, then src_root:[gawk] will be
+$! translated to something like DISK:[dir.gawk.reference.gawk]
+$! and then DISK:[dir.gawk.vms_source.gawk] will be used.
+$!
+$! The copy directory is vms_root:[gawk]
+$! The UPDATE parameter is ignored.
+$!
+$! This setting is used to make sure that the working vms directory
+$! and the VMS specific repository checkout directory have the same
+$! contents if they are different.
+$!
+$! If P1 is "SRCBCK" then this
+$! The source directory tree is: src_root:[gawk]
+$! The copy directory is src_root1:[gawk]
+$!
+$! src_root1:[gawk] is used by me to work around that VMS backup will
+$! not use NFS as a source directory so I need to make a copy.
+$!
+$! This is to make sure that the backup save set for the unmodified
+$! source is up to date.
+$!
+$! If your repository checkout is not on an NFS mounted volume, you do not
+$! need to use this option or have the logical name src_root1 defined.
+$!
+$! If P1 is "VMSBCK" then this changes the two directories:
+$! The source directory is vms_root:[gawk]
+$! The copy directory is vms_root1:[gawk]
+$!
+$! vms_root:
+$! src_root1:[gawk] is used by me to work around that VMS backup will
+$! not use NFS as a source directory so I need to make a copy.
+$!
+$! This is to make sure that the backup save set for the unmodified
+$! source is up to date.
+$!
+$! If your repository checkout is not on an NFS mounted volume, you do not
+$! need to use this option or have the logical name src_root1 defined.
+$!
+$! 02-Jan-2014 J. Malmberg
+$!==========================================================================
+$!
+$! Update missing/changed files.
+$update_file = 0
+$if (p2 .eqs. "UPDATE")
+$then
+$ update_file = 1
+$endif
+$!
+$myproc = f$environment("PROCEDURE")
+$myprocdir = f$parse(myproc,,,"DIRECTORY") - "[" - "]" - "<" - ">"
+$myprocdir = f$edit(myprocdir, "LOWERCASE")
+$mydefault = f$environment("DEFAULT")
+$mydir = f$parse(mydefault,,,"DIRECTORY")
+$mydir = f$edit(mydir, "LOWERCASE")
+$odelim = f$extract(0, 1, mydir)
+$mydir = mydir - "[" - "]" - "<" - ">"
+$mydev = f$parse(mydefault,,,"DEVICE")
+$!
+$ref = ""
+$if P1 .eqs. ""
+$then
+$ ref_base_dir = myprocdir - ".vms"
+$ wrk_base_dir = mydir
+$ update_file = 0
+$ resultd = f$parse("src_root:",,,,"NO_CONCEAL")
+$ resultd = f$edit(resultd, "LOWERCASE")
+$ resultd = resultd - "][" - "><" - ".;" - ".."
+$ resultd_len = f$length(resultd) - 1
+$ delim = f$extract(resultd_len, 1, resultd)
+$ ref_root_base = mydir + delim
+$ if f$locate(".reference.", resultd) .lt. resultd_len
+$ then
+$ resultd = resultd - ref_root_base - "reference." + "vms_source."
+$ else
+$ resultd = resultd - ref_root_base - "gnu." + "gnu_vms."
+$ endif
+$ ref = resultd + ref_base_dir
+$ wrk = "VMS_ROOT:" + odelim + wrk_base_dir
+$ resultd_len = f$length(resultd) - 1
+$ resultd = f$extract(0, resultd_len, resultd) + delim
+$ ref_root_dir = f$parse(resultd,,,"DIRECTORY")
+$ ref_root_dir = f$edit(ref_root_dir, "LOWERCASE")
+$ ref_root_dir = ref_root_dir - "[" - "]"
+$ ref_base_dir = ref_root_dir + "." + ref_base_dir
+$endif
+$!
+$if p1 .eqs. "SRCBCK"
+$then
+$ ref_base_dir = "gawk"
+$ wrk_base_dir = "gawk"
+$ ref = "src_root:[" + ref_base_dir
+$ wrk = "src_root1:[" + wrk_base_dir
+$ if update_file
+$ then
+$ if f$search("src_root1:[000000]gawk.dir") .eqs. ""
+$ then
+$ create/dir/prot=o:rwed src_root1:[gawk]
+$ endif
+$ endif
+$endif
+$!
+$!
+$if p1 .eqs. "VMSBCK"
+$then
+$ ref_base_dir = "gawk"
+$ wrk_base_dir = "gawk"
+$ ref = "vms_root:[" + ref_base_dir
+$ wrk = "vms_root1:[" + wrk_base_dir
+$ if update_file
+$ then
+$ if f$search("vms_root1:[000000]gawk.dir") .eqs. ""
+$ then
+$ create/dir/prot=o:rwed vms_root1:[gawk]
+$ endif
+$ endif
+$endif
+$!
+$!
+$if ref .eqs. ""
+$then
+$ write sys$output "Unknown compare type specified!"
+$ exit 44
+$endif
+$!
+$!
+$!
+$! Future - check the device types involved for the
+$! the syntax to check.
+$ODS2_SYNTAX = 0
+$NFS_MANGLE = 0
+$PWRK_MANGLE = 0
+$!
+$vax = f$getsyi("HW_MODEL") .lt. 1024
+$if vax
+$then
+$ ODS2_SYNTAX = 1
+$endif
+$!
+$report_missing = 1
+$!
+$if .not. ODS2_SYNTAX
+$then
+$ set proc/parse=extended
+$endif
+$!
+$loop:
+$ ref_spec = f$search("''ref'...]*.*;",1)
+$ if ref_spec .eqs. "" then goto loop_end
+$!
+$ ref_dev = f$parse(ref_spec,,,"DEVICE")
+$ ref_dir = f$parse(ref_spec,,,"DIRECTORY")
+$ ref_dir = f$edit(ref_dir, "LOWERCASE")
+$ ref_name = f$parse(ref_spec,,,"NAME")
+$ ref_type = f$parse(ref_spec,,,"TYPE")
+$!
+$!
+$ if f$locate(".CVS]", ref_dir) .lt. f$length(ref_dir) then goto loop
+$ if f$locate(".cvs]", ref_dir) .lt. f$length(ref_dir) then goto loop
+$ if f$locate(".$cvs]", ref_dir) .lt. f$length(ref_dir) then goto loop
+$ if f$locate(".^.git", ref_dir) .lt. f$length(ref_dir) then goto loop
+$ if f$locate(".$5ngit", ref_dir) .lt. f$length(ref_dir) then goto loop
+$!
+$ rel_path = ref_dir - "[" - ref_base_dir
+$! rel_path_len = f$length(rel_path) - 1
+$! delim = f$extract(rel_path_len, 1, rel_path)
+$! rel_path = rel_path - ".]" - ".>" - "]" - ">"
+$! rel_path = rel_path + delim
+$!
+$ if ODS2_SYNTAX
+$ then
+$ endif
+$!
+$ wrk_path = wrk + rel_path
+$!
+$ ref_name_type = ref_name + ref_type
+$!
+$ if ref_name_type .eqs. "CVS.DIR" then goto loop
+$ if ref_name_type .eqs. "cvs.dir" then goto loop
+$ if ref_name_type .eqs. "$CVS.DIR" then goto loop
+$ if ref_name_type .eqs. "^.git.DIR" then goto loop
+$ if ref_name_type .eqs. "$5ngit.DIR" then goto loop
+$ if ref_name_type .eqs. "$5NGIT.DIR" then goto loop
+$ if ODS2_SYNTAX
+$ then
+$!
+$ endif
+$!
+$ wrk_spec = wrk_path + ref_name_type
+$!
+$!
+$ wrk_chk = f$search(wrk_spec, 0)
+$ if wrk_chk .eqs. ""
+$ then
+$ if report_missing
+$ then
+$ write sys$output "''wrk_spec' is missing"
+$ endif
+$ if update_file
+$ then
+$ copy/log 'ref_spec' 'wrk_spec'
+$ endif
+$ goto loop
+$ endif
+$!
+$ wrk_name = f$parse(wrk_spec,,,"NAME")
+$ wrk_type = f$parse(wrk_spec,,,"TYPE")
+$ wrk_fname = wrk_name + wrk_type"
+$ ref_fname = ref_name + ref_type
+$!
+$ if ref_fname .nes. wrk_fname
+$ then
+$ write sys$output "''wrk_spc' wrong name, should be ""''ref_fname'"""
+$ endif
+$!
+$ ref_type = f$edit(ref_type, "UPCASE")
+$ if ref_type .eqs. ".DIR" then goto loop
+$!
+$ if ODS2_SYNTAX
+$ then
+$ ref_fname = f$edit(ref_fname, "LOWERCASE")
+$ endif
+$!
+$! These files have records to long to diff, and we don't change them anyway.
+$ ref_skip = 0
+$ if ref_type .eqs. ".GMO" then ref_skip = 1
+$ if ref_type .eqs. ".PDF" then ref_skip = 1
+$ if ref_type .eqs. ".PNG" then ref_skip = 1
+$ if ref_type .eqs. ".JPG" then ref_skip = 1
+$ if ref_fname .eqs. "inftest.ok" then ref_skip = 1
+$ if ref_fname .eqs. "longsub.in" then ref_skip = 1
+$ if ref_fname .eqs. "longsub.ok" then ref_skip = 1
+$ if ref_fname .eqs. "nasty2.ok" then ref_skip = 1
+$ if ref_fname .eqs. "profile5.awk" then ref_skip = 1
+$ if ref_fname .eqs. "profile5.ok" then ref_skip = 1
+$ if ref_fname .eqs. "po.m4" then ref_skip = 1
+$!
+$!
+$ if ref_skip .ne. 0
+$ then
+$ if report_missing
+$ then
+$ write sys$output "Skipping diff of ''ref_fname'"
+$ endif
+$ goto loop
+$ endif
+$!
+$!
+$ wrk_ver = f$parse(wrk_chk,,,"VERSION")
+$ if wrk_ver .nes. ";1"
+$ then
+$ write sys$output "Version for ''wrk_spec' is not 1"
+$ endif
+$ set noon
+$ diff/out=nl: 'wrk_spec' 'ref_spec'
+$ if $severity .nes. "1"
+$ then
+$ write sys$output "''wrk_spec' is different from ''ref_spec'"
+$ if update_file
+$ then
+$ delete 'wrk_spec';*
+$ copy/log 'ref_spec' 'wrk_spec'
+$ endif
+$ endif
+$ set on
+$
+$!
+$ goto loop
+$loop_end:
+$!
+$!
+$missing_loop:
+$! For missing loop, check the latest generation.
+$ ref_spec = f$search("''wrk'...]*.*;")
+$ if ref_spec .eqs. "" then goto missing_loop_end
+$!
+$ ref_dev = f$parse(ref_spec,,,"DEVICE")
+$ ref_dir = f$parse(ref_spec,,,"DIRECTORY")
+$ ref_dir = f$edit(ref_dir, "LOWERCASE")
+$ ref_name = f$parse(ref_spec,,,"NAME")
+$ ref_type = f$parse(ref_spec,,,"TYPE")
+$!
+$ rel_path = ref_dir - "[" - wrk_base_dir
+$!
+$!
+$ wrk_path = ref + rel_path
+$ wrk_spec = wrk_path + ref_name + ref_type
+$ wrk_name = f$parse(wrk_spec,,,"NAME")
+$ wrk_type = f$parse(wrk_spec,,,"TYPE")
+$!
+$ wrk_fname = wrk_name + wrk_type"
+$ ref_fname = ref_name + ref_type
+$!
+$ wrk_skip = 0
+$ ref_utype = f$edit(ref_type,"UPCASE")
+$ ref_ufname = f$edit(ref_fname,"UPCASE")
+$!
+$!
+$ if wrk_skip .eq. 0
+$ then
+$ wrk_chk = f$search(wrk_spec, 0)
+$ if wrk_chk .eqs. ""
+$ then
+$ if report_missing
+$ then
+$ write sys$output "''wrk_spec' is missing"
+$ endif
+$ goto missing_loop
+$ endif
+$ else
+$ goto missing_loop
+$ endif
+$!
+$ if ref_fname .nes. wrk_fname
+$ then
+$ write sys$output "''wrk_spc' wrong name, should be ""''ref_fname'"""
+$ endif
+$!
+$ if ref_utype .eqs. ".DIR" then goto missing_loop
+$!
+$ wrk_ver = f$parse(wrk_chk,,,"VERSION")
+$ if wrk_ver .nes. ";1"
+$ then
+$ write sys$output "Version for ''wrk_spec' is not 1"
+$ endif
+$!
+$ goto missing_loop
+$!
+$!
+$missing_loop_end:
+$!
+$exit
diff --git a/vms/config_h.com b/vms/config_h.com
new file mode 100644
index 00000000..0074a65a
--- /dev/null
+++ b/vms/config_h.com
@@ -0,0 +1,1661 @@
+$! File: config_h.com
+$!
+$! $Id: config_h.com,v 1.1.1.1 2012/12/02 19:25:21 wb8tyw Exp $
+$!
+$! This procedure attempts to figure out how to build a config.h file
+$! for the current project.
+$!
+$! The P1 parameter of "NOBUILTINS" inhibits the default #include <builtins.h>
+$! that is normally added. This include can cause side effects if
+$! special VMS compiler settings are used.
+$!
+$! The CONFIGURE shell script will be examined for hints and a few symbols
+$! but most of the tests will not produce valid results on OpenVMS. Some
+$! will produce false positives and some will produce false negatives.
+$!
+$! It is easier to just read the config.h_in file and make up tests based
+$! on what is in it!
+$!
+$! This file will create an empty config_vms.h file if one does not exist.
+$! The config_vms.h is intended for manual edits to handle things that
+$! this procedure can not.
+$!
+$! The config_vms.h will be invoked by the resulting config.h file.
+$!
+$! This procedure knows about the DEC C RTL on the system it is on.
+$! Future versions may be handle the GNV, the OpenVMS porting library,
+$! and others.
+$!
+$! This procedure may not guess the options correctly for all architectures,
+$! and is a work in progress.
+$!
+$! Copyright (C) 2014 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 3 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
+$!
+$! Per assignment agreement with FSF, similar procedures may be present
+$! in other packages under other licensing agreements and copyrights
+$!
+$! 15-Jan-2001 J. Malmberg Original
+$! 29-Apr-2001 J. Malmberg Also look for config.*in* in a [.include]
+$! subdirectory
+$! 30-Apr-2001 J. Malmberg Update for SAMBA checks
+$! 09-Apr-2005 J. Malmberg Update for RSYNC and large file.
+$! 29-Sep-2011 J. Malmberg Update for Bash 4.2
+$! 01-Mar-2012 J. Malmberg Warn about getcwd(0,0)
+$! 21-Dec-2012 J. Malmberg Update for gawk
+$!============================================================================
+$!
+$ss_normal = 1
+$ss_abort = 44
+$ss_control_y = 1556
+$status = ss_normal
+$on control_y then goto control_y
+$on warning then goto general_error
+$!
+$! Some information for writing timestamps to created files
+$!----------------------------------------------------------
+$my_proc = f$environment("PROCEDURE")
+$my_proc_file = f$parse(my_proc,,,"NAME") + f$parse(my_proc,,,"TYPE")
+$tab[0,8] = 9
+$datetime = f$element(0,".",f$cvtime(,"ABSOLUTE","DATETIME"))
+$username = f$edit(f$getjpi("","USERNAME"),"TRIM")
+$!
+$pid = f$getjpi("","PID")
+$tfile1 = "SYS$SCRATCH:config_h_temp1_''pid'.TEMP"
+$dchfile = "SYS$SCRATCH:config_h_decc_''pid'.TEMP"
+$configure_script = "SYS$SCRATCH:configure_script_''pid'.TEMP"
+$!
+$! Get the system type
+$!----------------------
+$arch_type = f$getsyi("arch_type")
+$!
+$! Does config_vms.h exist?
+$!-------------------------
+$update_config_vms = 0
+$file = f$search("sys$disk:[]config_vms.h")
+$if file .nes. ""
+$then
+$ write sys$output "Found existing custom file ''file'."
+$else
+$ update_config_vms = 1
+$ write sys$output "Creating new sys$disk:[]config_vms.h for you."
+$ gosub write_config_vms
+$endif
+$!
+$!
+$! On some platforms, DCL search has problems with searching a file
+$! on a NFS mounted volume. So copy it to sys$scratch:
+$!
+$if f$search(configure_script) .nes. "" then delete 'configure_script';*
+$copy sys$disk:configure 'configure_script'
+$!
+$!
+$! Write out the header
+$!----------------------
+$gosub write_config_h_header
+$!
+$!
+$!
+$! config.h.in could have at least five different names depending
+$! on how it was transferred to OpenVMS
+$!------------------------------------------------------------------
+$cfile = f$search("sys$disk:[]config.h.in")
+$if cfile .eqs. ""
+$then
+$ cfile = f$search("sys$disk:[]config.h_in")
+$ if cfile .eqs. ""
+$ then
+$ cfile = f$search("sys$disk:[]configh.in")
+$ if cfile .eqs. ""
+$ then
+$ cfile = f$search("sys$disk:[]config__2eh.in")
+$ if cfile .eqs. ""
+$ then
+$ cfile = f$search("sys$disk:[]config.h__2ein")
+$ endif
+$ endif
+$ endif
+$endif
+$if f$trnlnm("PRJ_INCLUDE") .nes. ""
+$then
+$ cfile = f$search("PRJ_INCLUDE:config.h.in")
+$ if cfile .eqs. ""
+$ then
+$ cfile = f$search("PRJ_INCLUDE:config.h_in")
+$ if cfile .eqs. ""
+$ then
+$ cfile = f$search("PRJ_INCLUDE:config__2eh.in")
+$ if cfile .eqs. ""
+$ then
+$ cfile = f$search("PRJ_INCLUDE:config__2eh.in")
+$ if cfile .eqs. ""
+$ then
+$ cfile = f$search("PRJ_INCLUDE:config.h__2ein")
+$ endif
+$ endif
+$ endif
+$ endif
+$endif
+$if cfile .eqs. ""
+$then
+$ write sys$output "Can not find sys$disk:config.h.in"
+$ line_out = "Looked for config.h.in, config.h_in, configh.in, "
+$ line_out = line_out + "config__2eh.in, "config.h__2ein"
+$ write/symbol sys$output line_out
+$ if f$trnlnm("PRJ_INCLUDE") .nes. ""
+$ then
+$ write sys$output "Also looked in PRJ_INCLUDE: for these files."
+$ endif
+$!
+$ write tf ""
+$ write tf -
+ " /* Could not find sys$disk:config.h.in */"
+$ write tf -
+ " /* Looked also for config.h_in, configh.in, config__2eh.in, */"
+$ write tf -
+ " /* config.h__2ein */"
+$ if f$trnlnm("PRJ_INCLUDE") .nes. ""
+$ then
+$ write tf -
+ " /* Also looked in PRJ_INCLUDE: for these files. */"
+$ endif
+$ write tf -
+ "/*--------------------------------------------------------------*/
+$ write tf ""
+$ goto write_tail
+$endif
+$!
+$!
+$! Locate the DECC libraries in use
+$!-----------------------------------
+$decc_rtldef = f$parse("decc$rtldef","sys$library:.tlb;0")
+$decc_shr = f$parse("decc$shr","sys$share:.exe;0")
+$!
+$! Dump the DECC header names into a file
+$!----------------------------------------
+$if f$search(dchfile) .nes. "" then delete 'dchfile';*
+$if f$search(tfile1) .nes. "" then delete 'tfile1';*
+$define/user sys$output 'tfile1'
+$library/list 'decc_rtldef'
+$open/read/error=rtldef_loop1_end tf1 'tfile1'
+$open/write/error=rtldef_loop1_end tf2 'dchfile'
+$rtldef_loop1:
+$ read/end=rtldef_loop1_end tf1 line_in
+$ line_in = f$edit(line_in,"TRIM,COMPRESS")
+$ key1 = f$element(0," ",line_in)
+$ key2 = f$element(1," ",line_in)
+$ if key1 .eqs. " " .or. key1 .eqs. "" then goto rtldef_loop1
+$ if key2 .nes. " " .and. key2 .nes. "" then goto rtldef_loop1
+$ write tf2 "|",key1,"|"
+$ goto rtldef_loop1
+$rtldef_loop1_end:
+$if f$trnlnm("tf1","lnm$process",,"SUPERVISOR") .nes. "" then close tf1
+$if f$trnlnm("tf2","lnm$process",,"SUPERVISOR") .nes. "" then close tf2
+$if f$search(tfile1) .nes. "" then delete 'tfile1';*
+$!
+$!
+$! Now calculate what should be in the file from reading
+$! config.h.in and CONFIGURE.
+$!---------------------------------------------------------------
+$open/read inf 'cfile'
+$do_comment = 0
+$if_block = 0
+$cfgh_in_loop1:
+$!set nover
+$ read/end=cfgh_in_loop1_end inf line_in
+$ xline = f$edit(line_in,"TRIM,COMPRESS")
+$!
+$! Blank line handling
+$!---------------------
+$ if xline .eqs. ""
+$ then
+$ write tf ""
+$ goto cfgh_in_loop1
+$ endif
+$ xlen = f$length(xline)
+$ key = f$extract(0,2,xline)
+$!
+$! deal with comments by copying exactly
+$!-----------------------------------------
+$ if (do_comment .eq. 1) .or. (key .eqs. "/*")
+$ then
+$ do_comment = 1
+$ write tf line_in
+$ key = f$extract(xlen - 2, 2, xline)
+$ if key .eqs. "*/" then do_comment = 0
+$ goto cfgh_in_loop1
+$ endif
+$!
+$! Some quick parsing
+$!----------------------
+$ keyif = f$extract(0,3,xline)
+$ key1 = f$element(0," ",xline)
+$ key2 = f$element(1," ",xline)
+$ key2a = f$element(0,"_",key2)
+$ key2b = f$element(1,"_",key2)
+$ key2_len = f$length(key2)
+$ key2_h = f$extract(key2_len - 2, 2, key2)
+$ key2_t = f$extract(key2_len - 5, 5, key2)
+$ if key2_t .eqs. "_TYPE" then key2_h = "_T"
+$ key64 = 0
+$ if f$locate("64", xline) .lt. xlen then key64 = 1
+$!
+$!write sys$output "xline = ''xline'"
+$!
+$! Comment out this section of the ifblock
+$!-----------------------------------------
+$ if if_block .ge. 3
+$ then
+$ write tf "/* ", xline, " */"
+$ if keyif .eqs. "#en" then if_block = 0
+$ goto cfgh_in_loop1
+$ endif
+$!
+$! Handle the end of an ifblock
+$!-------------------------------
+$ if keyif .eqs. "#en"
+$ then
+$ write tf xline
+$ if_block = 0
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key1 .eqs. "#ifndef"
+$ then
+$! Manual check for _ALL_SOURCE on AIX error
+$!-----------------------------------------------
+$ if key2 .eqs. "_ALL_SOURCE"
+$ then
+$ write tf "/* ", xline, " */"
+$!
+$! Ignore the rest of the block
+$!--------------------------------------
+$ if_block = 3
+$ goto cfgh_in_loop1
+$ endif
+$ endif
+$!
+$!
+$! Default action for an #if/#else/#endif
+$!------------------------------------------
+$ if keyif .eqs. "#if" .or. keyif .eqs. "#el"
+$ then
+$ if_block = 1
+$ write tf xline
+$ goto cfgh_in_loop1
+$ endif
+$!
+$!
+$! Process "normal?" stuff
+$!---------------------------
+$ if key1 .eqs. "#undef"
+$ then
+$ key2c = f$element(2, "_", key2)
+$ if (key2c .eqs. "_") .or. (key2c .eqs. "H") then key2c = ""
+$ key2d = f$element(3, "_", key2)
+$ if (key2d .eqs. "_") .or. (key2d .eqs. "H") then key2d = ""
+$ key2e = f$element(4, "_", key2)
+$ if (key2e .eqs. "_") .or. (key2e .eqs. "H") then key2e = ""
+$ if key2d .eqs. "T"
+$ then
+$ if key2e .eqs. "TYPE"
+$ then
+$ key2_h = "_T"
+$ key2d = ""
+$ endif
+$ endif
+$!
+$ double_under = 0
+$!
+$ if key2 .eqs. "bits16_t"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' short"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "u_bits16_t"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' unsigned short"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "bits32_t"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' int"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "u_bits32_t"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' unsigned int"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "intmax_t"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#ifdef __VAX"
+$ write tf "#define ''key2' long"
+$ write tf "#else"
+$ write tf "#define ''key2' long long"
+$ write tf "#endif"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "uintmax_t"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#ifdef __VAX"
+$ write tf "#define ''key2' unsigned long"
+$ write tf "#else"
+$ write tf "#define ''key2' unsigned long long"
+$ write tf "#endif"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "socklen_t"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' int"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "GETGROUPS_T"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' gid_t"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_DECL_SYS_SIGLIST"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 0"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_SYS_ERRLIST"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_STRUCT_DIRENT_D_INO"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$! ! The header files have this information, however
+$! ! The ioctl() call only works on sockets.
+$! if key2 .eqs. "FIONREAD_IN_SYS_IOCTL"
+$! then
+$! write tf "#ifndef ''key2'"
+$! write tf "#define ''key2' 1"
+$! write tf "#endif"
+$! goto cfgh_in_loop1
+$! endif
+$!
+$! ! The header files have this information, however
+$! ! The ioctl() call only works on sockets.
+$! if key2 .eqs. "GWINSZ_IN_SYS_IOCTL"
+$! then
+$! write tf "#ifndef ''key2'"
+$! write tf "#define ''key2' 1"
+$! write tf "#endif"
+$! goto cfgh_in_loop1
+$! endif
+$!
+$! ! The header files have this information, however
+$! ! The ioctl() call only works on sockets.
+$! if key2 .eqs. "STRUCT_WINSIZE_IN_SYS_IOCTL"
+$! then
+$! write tf "#ifndef ''key2'"
+$! write tf "#define ''key2' 0"
+$! write tf "#endif"
+$! goto cfgh_in_loop1
+$! endif
+$!
+$ if key2 .eqs. "HAVE_STRUCT_TM_TM_ZONE"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_TM_ZONE"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_TIMEVAL"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_TZNAME"
+$ then
+$ write tf "#if __CRTL_VER >= 70000000"
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "WEXITSTATUS_OFFSET"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 2"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_GETPW_DECLS"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_DECL_CONFSTR"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_DECL_PRINTF"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_DECL_SBRK"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_DECL_STRSIGNAL"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 0"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2a .eqs. "HAVE_DECL_STRTOLD"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 0"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_DECL_STRTOIMAX"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 0"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_DECL_STRTOL"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_DECL_STRTOLL"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_DECL_STRTOUL"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_DECL_STRTOULL"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_DECL_STRTOUMAX"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 0"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "GETPGRP_VOID"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "NAMED_PIPES_MISSING"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "OPENDIR_NOT_ROBUST"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "PGRP_PIPE"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "CAN_REDEFINE_GETENV"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_PRINTF_A_FORMAT"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "CTYPE_NON_ASCII"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_LANGINFO_CODESET"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_LC_MESSAGES"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$! This wants execve() to do this automagically to pass.
+$! if key2 .eqs. "HAVE_HASH_BANG_EXEC"
+$! then
+$! write tf "#ifndef ''key2'"
+$! write tf "#define ''key2' 1"
+$! write tf "#endif"
+$! goto cfgh_in_loop1
+$! endif
+$!
+$ if key2 .eqs. "ICONV_CONST"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2'"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "VOID_SIGHANDLER"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_POSIX_SIGNALS"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "UNUSABLE_RT_SIGNALS"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2a .eqs. "HAVE_DECL_FPURGE"
+$ then
+$ write tf "#ifndef ''key2a'"
+$ write tf "#define ''key2a' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_DECL_SETREGID"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_POSIX_SIGSETJMP"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "HAVE_LIBDL"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "STRCOLL_BROKEN"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2 .eqs. "DUP_BROKEN"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$! This is for a test that getcwd(0,0) works.
+$! It does not on VMS.
+$!--------------------------
+$ if key2 .eqs. "GETCWD_BROKEN"
+$ then
+$ write sys$output ""
+$ write sys$output -
+ "%CONFIG_H-I-NONPORT, ''key2' being tested for!"
+$ write sys$output -
+ "-CONFIG_H-I-GETCWD, GETCWD(0,0) does not work on VMS."
+$ write sys$output -
+ "-CONFIG_H-I-GETCWD2, Work around hack probably required."
+$ write sys$output -
+ "-CONFIG_H-I-REVIEW, Manual Code review required!"
+$ if update_config_vms
+$ then
+$ open/append tfcv sys$disk:[]config_vms.h
+$ write tfcv ""
+$ write tfcv -
+ "/* Check config.h for use of ''key2' settings */"
+$ write tfcv ""
+$ close tfcv
+$ endif
+$
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2a .eqs. "HAVE" .or. key2a .eqs. "STAT"
+$ then
+$!
+$! Process extra underscores
+$!------------------------------------
+$ if f$locate("HAVE___", key2) .lt. key2_len
+$ then
+$ key2b = "__" + key2d
+$ key2d = ""
+$ double_under = 1
+$ else
+$ if f$locate("HAVE__", key2) .lt. key2_len
+$ then
+$ key2b = "_" + key2c
+$ key2c = ""
+$ double_under = 1
+$ endif
+$ endif
+$!
+$ if key2_h .eqs. "_H"
+$ then
+$!
+$! Looking for a header file
+$!---------------------------------------
+$ headf = key2b
+$ if key2c .nes. "" then headf = headf + "_" + key2c
+$ if key2d .nes. "" then headf = headf + "_" + key2d
+$!
+$! (key2b .eqs. "READLINE")
+$!
+$! Some special parsing
+$!------------------------------------------
+$ if (key2b .eqs. "SYS") .or. (key2b .eqs. "ARPA") .or. -
+ (key2b .eqs. "NET") .or. (key2b .eqs. "NETINET")
+$ then
+$ if key2c .nes. ""
+$ then
+$ headf = key2c
+$ if key2d .nes. "" then headf = key2c + "_" + key2d
+$ endif
+$ endif
+$!
+$! And of course what's life with out some special cases
+$!--------------------------------------------------------------------
+$ if key2b .eqs. "FILE"
+$ then
+$ write sys$output ""
+$ write sys$output -
+ "%CONFIG_H-I-NONPORT, ''key2' being asked for!"
+$ write sys$output -
+ "-CONFIG_H-I-FILE_OLD, file.h will not be configured as is obsolete!"
+$ write sys$output -
+ "-CONFIG_H_I-FCNTL_NEW, "Expecting fcntl.h to be configured instead!"
+$ write sys$output -
+ "-CONFIG_H_I-FCNTL_CHK, "Unable to verify at this time!"
+$ write sys$output -
+ "-CONFIG_H-I-REVIEW, Manual Code review required!"
+$!
+$ if update_config_vms
+$ then
+$ open/append tfcv sys$disk:[]config_vms.h
+$ write tfcv ""
+$ write tfcv -
+ "/* Check config.h for use of fcntl.h instead of file.h */"
+$ write tfcv ""
+$ close tfcv
+$ endif
+$ endif
+$!
+$! Now look it up in the DEC C RTL
+$!---------------------------------------------
+$ define/user sys$output nl:
+$ define/user sys$error nl:
+$ search/output=nl: 'dchfile' |'headf'|/exact
+$ if '$severity' .eq. 1
+$ then
+$ if key64 then write tf "#ifndef __VAX"
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$if p2 .nes. "" then write sys$output "''dchfile' - #define ''key2' 1"
+$ write tf "#endif"
+$ if key64 then write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ else
+$!
+$! Looking for a routine or a symbol
+$!------------------------------------------------
+$ if key2c .eqs. "MACRO"
+$ then
+$ if (key2b .eqs. "FILE") .or. (key2b .eqs. "DATE") -
+ .or. (key2b .eqs. "LINE") .or. (key2b .eqs. "TIME")
+$ then
+$ write tf "#ifndef HAVE_''key2b'"
+$ write tf "#define HAVE_''key2b' 1"
+$ write tf "#endif"
+$ endif
+$ goto cfgh_in_loop1
+$ endif
+$!
+$! Special false tests
+$!-------------------------------------
+$ if double_under
+$ then
+$ if key2b .eqs. "_FCNTL" .or. key2b .eqs. "__FCNTL"
+$ then
+$ write tf "/* #undef HAVE_''key2b' */"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2b .eqs. "_STAT" .or. key2b .eqs. "__STAT"
+$ then
+$ write tf "/* #undef HAVE_''key2b' */"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if key2b .eqs. "_READ" .or. key2b .eqs. "__READ"
+$ then
+$ write tf "/* #undef HAVE_''key2b' */"
+$ goto cfgh_in_loop1
+$ endif
+$ endif
+$!
+$ keysym = key2b
+$ if key2c .nes. "" then keysym = keysym + "_" + key2c
+$ if key2d .nes. "" then keysym = keysym + "_" + key2d
+$ if key2e .nes. "" then keysym = keysym + "_" + key2e
+$!
+$!
+$! Stat structure members
+$!-------------------------------------
+$ if key2b .eqs. "STRUCT"
+$ then
+$ if key2c .eqs. "STAT" .and (key2d .nes. "")
+$ then
+$ key2b = key2b + "_" + key2c + "_" + key2d
+$ key2c = key2e
+$ key2d = ""
+$ key2e = ""
+$ endif
+$ endif
+$ if (key2b .eqs. "ST") .or. (key2b .eqs. "STRUCT_STAT_ST")
+$ then
+$ keysym = "ST" + "_" + key2c
+$ keysym = f$edit(keysym,"LOWERCASE")
+$ endif
+$ if key2a .eqs. "STAT"
+$ then
+$ if (f$locate("STATVFS", key2b) .eq. 0) .and. key2c .eqs. ""
+$ then
+$ keysym = f$edit(key2b, "LOWERCASE")
+$ endif
+$!$ if (key2b .eqs. "STATVFS" .or. key2b .eqs. "STATFS2" -
+$! .or. key2b .eqs. "STATFS3") .and. key2c .nes. ""
+$!
+$ if (key2b .eqs. "STATVFS") .and. key2c .nes. ""
+$ then
+$! Should really verify that the structure
+$! named by key2b actually exists first.
+$!------------------------------------------------------------
+$!
+$! Statvfs structure members
+$!-------------------------------------------------
+$ keysym = "f_" + f$edit(key2c,"LOWERCASE")
+$ endif
+$ endif
+$!
+$! UTMPX structure members
+$!--------------------------------------
+$ if key2b .eqs. "UT" .and. key2c .eqs. "UT"
+$ then
+$ keysym = "ut_" + f$edit(key2d,"LOWERCASE")
+$ endif
+$!
+$ if f$locate("MMAP",key2) .lt. key2_len
+$ then
+$ write sys$output ""
+$ write sys$output -
+ "%CONFIG_H-I-NONPORT, ''key2' being asked for!"
+$ write sys$output -
+ "-CONFIG_H-I-MMAP, MMAP operations only work on STREAM and BINARY files!"
+$ write sys$output -
+ "-CONFIG_H-I-REVIEW, Manual Code review required!"
+$ if update_config_vms
+$ then
+$ open/append tfcv sys$disk:[]config_vms.h
+$ write tfcv ""
+$ write tfcv -
+ "/* Check config.h for use of ''key2' settings */"
+$ write tfcv ""
+$ close tfcv
+$ endif
+$ endif
+$!
+$!
+$ if keysym .eqs. "CRYPT"
+$ then
+$ write sys$output ""
+$ write sys$output -
+ "%CONFIG_H-I-NONPORT, ''key2' being asked for!"
+$ write sys$output -
+ "-CONFIG_H-I-CRYPT, CRYPT operations on the VMS SYSUAF may not work!"
+$ write sys$output -
+ "-CONFIG_H-I-REVIEW, Manual Code review required!"
+$ if update_config_vms
+$ then
+$ open/append tfcv sys$disk:[]config_vms.h
+$ write tfcv ""
+$ write tfcv -
+ "/* Check config.h for use of ''keysym' */"
+$ write tfcv ""
+$ close tfcv
+$ endif
+$ endif
+$!
+$!
+$ if keysym .eqs. "EXECL"
+$ then
+$ write sys$output ""
+$ write sys$output -
+ "%CONFIG_H-I-NONPORT, ''key2' being asked for!"
+$ write sys$output -
+ "-CONFIG_H-I-EXCEL, EXECL configured, Will probably not work."
+$ write sys$output -
+ "-CONFIG_H-I-REVIEW, Manual Code review required!"
+$ if update_config_vms
+$ then
+$ open/append tfcv sys$disk:[]config_vms.h
+$ write tfcv ""
+$ write tfcv -
+ "/* Check config.h for use of ''keysym' */"
+$ write tfcv ""
+$ close tfcv
+$ endif
+$ endif
+$!
+$!
+$! Process if cpp supports ANSI-C stringizing '#' operator
+$!-----------------------------------------------------------------------
+$ if keysym .eqs. "STRINGIZE"
+$ then
+$ write tf "#ifndef HAVE_STRINGIZE"
+$ write tf "#define HAVE_STRINGSIZE 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if keysym .eqs. "VOLATILE"
+$ then
+$ write tf "#ifndef HAVE_VOLATILE"
+$ write tf "#define HAVE_VOLATILE 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if keysym .eqs. "ALLOCA"
+$ then
+$ write tf "#ifndef HAVE_ALLOCA"
+$ write tf "#define HAVE_ALLOCA 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if keysym .eqs. "ERRNO_DECL"
+$ then
+$ write tf "#ifndef HAVE_ERRNO_DECL"
+$ write tf "#define HAVE_ERRNO_DECL 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if keysym .eqs. "LONGLONG"
+$ then
+$ write tf "#ifndef __VAX"
+$ write tf "#pragma message disable longlongtype"
+$ write tf "#ifndef HAVE_LONGLONG"
+$ write tf "#define HAVE_LONGLONG 1"
+$ write tf "#endif"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$! May need to test compiler version
+$!-----------------------------------------------
+$ if (keysym .eqs. "LONG_LONG") .or. -
+ (keysym .eqs. "LONG_LONG_INT")
+$ then
+$ write tf "#ifndef __VAX"
+$ write tf "#pragma message disable longlongtype"
+$ write tf "#ifndef HAVE_''keysym'"
+$ write tf "#define HAVE_''keysym' 1"
+$ write tf "#endif"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$! May need to test compiler version
+$!-----------------------------------------------
+$ if keysym .eqs. "UNSIGNED_LONG_LONG"
+$ then
+$ write tf "#ifndef __VAX"
+$ write tf "#pragma message disable longlongtype"
+$ write tf "#ifndef HAVE_UNSIGNED_LONG_LONG"
+$ write tf "#define HAVE_UNSIGNED_LONG_LONG 1"
+$ write tf "#endif"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$! May need to test compiler version
+$!-----------------------------------------------
+$ if keysym .eqs. "UNSIGNED_LONG_LONG_INT"
+$ then
+$ write tf "#ifndef __VAX"
+$ write tf "#pragma message disable longlongtype"
+$ write tf "#ifndef HAVE_UNSIGNED_LONG_LONG_INT"
+$ write tf "#define HAVE_UNSIGNED_LONG_LONG_INT 1"
+$ write tf "#endif"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$! May need to test compiler version
+$!-----------------------------------------------
+$ if keysym .eqs. "LONG_DOUBLE"
+$ then
+$ write tf "#ifndef __VAX"
+$ write tf "#pragma message disable longlongtype"
+$ write tf "#ifndef HAVE_LONG_DOUBLE"
+$ write tf "#define HAVE_LONG_DOUBLE 1"
+$ write tf "#endif"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ if keysym .eqs. "FCNTL_LOCK"
+$ then
+$ write sys$output -
+ "%CONFIG_H-I-NONPORT, ''key2' being asked for!
+$ write sys$output -
+ "-CONFIG_H-I-REVIEW, Manual Code review required!"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$!
+$! These libraries are provided by the DEC C RTL
+$!-------------------------------------------------------------
+$ if keysym .eqs. "LIBINET" .or. keysym .eqs. "LIBSOCKET"
+$ then
+$ write tf "#ifndef HAVE_''keysym'"
+$ write tf "#define HAVE_''keysym' 1"
+$if p2 .nes. "" then write sys$output "''decc_shr' #define ''keysym' 1"
+$ write tf "#endif
+$ goto cfgh_in_loop1
+$ endif
+$!
+$!
+$ if keysym .eqs. "HERRNO" then keysym = "h_errno"
+$ if keysym .eqs. "UTIMBUF" then keysym = "utimbuf"
+$ if key2c .eqs. "STRUCT"
+$ then
+$ keysym = f$edit(key2d,"LOWERCASE")
+$ else
+$ if key2_h .eqs. "_T"
+$ then
+$ if key2_t .eqs. "_TYPE"
+$ then
+$ keysym = f$extract(0, key2_len - 5, key2) - "HAVE_"
+$ endif
+$ keysym = f$edit(keysym,"LOWERCASE")
+$ endif
+$ endif
+$!
+$! Check the DEC C RTL shared image first
+$!------------------------------------------------------
+$ if f$search(tfile1) .nes. "" then delete 'tfile1';*
+$ define/user sys$output nl:
+$ define/user sys$error nl:
+$ search/format=nonull/out='tfile1' 'decc_shr' 'keysym'
+$ if '$severity' .eq. 1
+$ then
+$!
+$! Not documented, but from observation
+$!------------------------------------------------------
+$ define/user sys$output nl:
+$ define/user sys$error nl:
+$ if arch_type .eq. 3
+$ then
+$ keyterm = "''keysym'<SOH>"
+$ else
+$ if arch_type .eq. 2
+$ then
+$ keyterm = "''keysym'<BS>"
+$ else
+$ keyterm = "''keysym'<STX>"
+$ endif
+$ endif
+$ search/out=nl: 'tfile1' -
+ "$''keyterm'","$g''keyterm'","$__utc_''keyterm'",-
+ "$__utctz_''keyterm'","$__bsd44_''keyterm'","$bsd_''keyterm'",-
+ "$''keysym'decc$","$G''keysym'decc$","$GX''keyterm'"
+$ severity = '$severity'
+$!
+$!
+$! Of course the 64 bit stuff is different
+$!---------------------------------------------------------
+$ if severity .ne. 1 .and. key64
+$ then
+$ define/user sys$output nl:
+$ define/user sys$error nl:
+$ search/out=nl: 'tfile1' "$_''keyterm'"
+$! search/out 'tfile1' "$_''keyterm'"
+$ severity = '$severity'
+$ endif
+$!
+$! UNIX compatability routines
+$!---------------------------------------------
+$ if severity .ne. 1
+$ then
+$ define/user sys$output nl:
+$ define/user sys$error nl:
+$ search/out=nl: 'tfile1' -
+ "$__unix_''keyterm'","$__vms_''keyterm'","$_posix_''keyterm'"
+$ severity = '$severity'
+$ endif
+$!
+$! VAX special handling routines
+$!---------------------------------------------
+$ if (severity .ne. 1) .and. (arch_type .eq. 1)
+$ then
+$ define/user sys$output nl:
+$ define/user sys$error nl:
+$ search/out=nl: 'tfile1' "DECC$''keysym'<SOH>"
+$ severity = '$severity'
+$ endif
+$!
+$! Show the result of the search
+$!------------------------------------------------
+$ if 'severity' .eq. 1
+$ then
+$ if key64 then write tf "#ifndef __VAX"
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$if p2 .nes. "" then write sys$output "''decc_shr' #define ''key2' 1"
+$ write tf "#endif"
+$ if key64 then write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$ endif
+$ if f$search(tfile1) .nes. "" then delete 'tfile1';*
+$!
+$! Check the DECC Header files next
+$!----------------------------------------------
+$ define/user sys$output nl:
+$ define/user sys$error nl:
+$ search/out=nl: 'decc_rtldef' -
+ "''keysym';", "''keysym'[", "struct ''keysym'"/exact
+$ severity = '$severity'
+$ if severity .eq. 1
+$ then
+$ if key64 then write tf "#ifndef __VAX"
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$if p2 .nes. "" then write sys$output "''decc_rtldef' #define ''key2' 1"
+$ write tf "#endif"
+$ if key64 then write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$ endif
+$ write tf "/* ", xline, " */"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$!
+$! Process SIZEOF directives found in SAMBA
+$!------------------------------------------------
+$ if key2a .eqs. "SIZEOF"
+$ then
+$ if key2b .eqs. "INO" .and. key2_h .eqs. "_T"
+$ then
+$ write tf "#ifndef SIZEOF_INO_T"
+$ write tf "#define SIZEOF_INO_T (6)"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$ if key2b .eqs. "INTMAX" .and. key2_h .eqs. "_T"
+$ then
+$ write tf "#ifndef SIZEOF_INTMAX_T"
+$ write tf "#ifdef __VAX"
+$ write tf "#define SIZEOF_INTMAX_T (4)"
+$ write tf "#else"
+$ write tf "#define SIZEOF_INTMAX_T (8)"
+$ write tf "#endif"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$ if key2b .eqs. "OFF" .and. key2_h .eqs. "_T"
+$ then
+$ write tf "#ifndef SIZEOF_OFF_T"
+$ write tf "#ifdef __VAX"
+$ write tf "#define SIZEOF_OFF_T (4)"
+$ write tf "#else"
+$ write tf "#define SIZEOF_OFF_T (8)"
+$ write tf "#endif"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$ if key2b .eqs. "CHAR" .and. key2_h .eqs. "_P"
+$ then
+$ write tf "#ifndef SIZEOF_CHAR_P"
+$ write tf "#define SIZEOF_CHAR_P (4)"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$ if (key2b .eqs. "INT")
+$ then
+$ write tf "#ifndef SIZEOF_''key2b'"
+$ write tf "#define SIZEOF_''key2b' (4)"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$ if key2b .eqs. "UNSIGNED"
+$ then
+$ if key2c .eqs. "INT" .or. key2c .eqs. "LONG"
+$ then
+$ write tf "#ifndef SIZEOF_''key2b'_''key2c'"
+$ write tf "#define SIZEOF_''key2b'_''key2c' (4)"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$ endif
+$ if key2b .eqs. "DOUBLE"
+$ then
+$ write tf "#ifndef SIZEOF_DOUBLE"
+$ write tf "#define SIZEOF_DOUBLE (8)"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$ if key2b .eqs. "LONG"
+$ then
+$ if key2c .eqs. ""
+$ then
+$ write tf "#ifndef SIZEOF_LONG"
+$ write tf "#define SIZEOF_LONG (4)"
+$ write tf "#endif"
+$ else
+$ write tf "#ifndef SIZEOF_LONG_LONG"
+$ write tf "#ifndef __VAX"
+$ write tf "#define SIZEOF_LONG_LONG (8)"
+$ write tf "#endif"
+$ write tf "#endif"
+$ endif
+$ goto cfgh_in_loop1
+$ endif
+$ if key2b .eqs. "SHORT"
+$ then
+$ write tf "#ifndef SIZEOF_SHORT"
+$ write tf "#define SIZEOF_SHORT (2)"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$ write tf "/* ", xline, " */"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$! Process NEED directives
+$!-------------------------------
+$ if key2a .eqs. "NEED"
+$ then
+$ if key2b .eqs. "STRINGS" .and. key2_h .eqs. "_H"
+$ then
+$ write tf "#ifndef NEED_STRINGS_H"
+$ write tf "#define NEED_STRINGS_H 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$ write tf "/* ", xline, " */"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$!
+$! Process STATFS directives
+$!-------------------------------
+$! if key2a .eqs. "STATFS"
+$! then
+$! write tf "/* ", xline, " */"
+$! goto cfgh_in_loop1
+$! endif
+$!
+$! Process inline directive
+$!------------------------------
+$ if key2 .eqs. "inline"
+$ then
+$ write tf "#ifndef inline"
+$ write tf "#define inline __inline"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$! Process restrict directive
+$!--------------------------------
+$ if key2 .eqs. "restrict"
+$ then
+$ write tf "#ifndef restrict"
+$ write tf "#define restrict __restrict"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$! Process RETSIGTYPE directive
+$!----------------------------------
+$ if key2 .eqs. "RETSIGTYPE"
+$ then
+$ write tf "#ifndef RETSIGTYPE"
+$ write tf "#define RETSIGTYPE void"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$! Process STDC_HEADERS (SAMBA!)
+$!---------------------------
+$ if key2 .eqs. "STDC_HEADERS"
+$ then
+$ write tf "#ifndef STDC_HEADERS"
+$ write tf "#define STDC_HEADERS 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$! Process PROTOTYPES directive
+$!-------------------------------------
+$ if key2 .eqs. "PROTOTYPES"
+$ then
+$ write tf "#ifndef PROTOTYPES"
+$ write tf "#define PROTOTYPES 1"
+$ write tf "#endif"
+$ goto cfgh_in_loop1
+$ endif
+$!
+$! Special for SEEKDIR_RETURNS_VOID
+$!---------------------------------------
+$ if key2 .eqs. "SEEKDIR_RETURNS_VOID"
+$ then
+$ write tf "#ifndef SEEKDIR_RETURNS_VOID"
+$ write tf "#define SEEKDIR_RETURNS_VOID 1"
+$ write tf "#endif"
+$ endif
+$!
+$! TIME_WITH_SYS_TIME note: On VMS time.h and sys/time.h are same module.
+$!
+$! TIME_T_IN_SYS_TYPES_H
+$!------------------------------
+$ if key2 .eqs. "TIME_T_IN_TYPES_H"
+$ then
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ''key2' 1"
+$ write tf "#endif"
+$ endif
+$!
+$! Unknown - See if CONFIGURE can give a clue for this
+$!----------------------------------------------------------
+$ pflag = 0
+$ set_flag = 0
+$! gproj_name = proj_name - "_VMS" - "-VMS"
+$ if f$search(tfile1) .nes. "" then delete 'tfile1';*
+$ define/user sys$output nl:
+$ define/user sys$error nl:
+$! if f$locate("FILE", key2) .lt. key2_len then pflag = 1
+$! if f$locate("DIR", key2) .eq. key2_len - 3 then pflag = 1
+$! if f$locate("PATH", key2) .eq. key2_len - 4 then pflag = 1
+$!
+$ search/out='tfile1' 'configure_script' "''key2'="/exact
+$ search_sev = '$severity'
+$ if 'search_sev' .eq. 1
+$ then
+$ open/read/err=unknown_cf_rd_error sf 'tfile1'
+$search_file_rd_loop:
+$ read/end=unknown_cf_rd_err sf line_in
+$ line_in = f$edit(line_in, "TRIM")
+$ skey1 = f$element(0,"=",line_in)
+$ if skey1 .eqs. key2
+$ then
+$ skey2 = f$element(1,"=",line_in)
+$ skey2a = f$extract(0,2,skey2)
+$!
+$! Keep these two cases separate to make it easier to add
+$! more future intelligence to this routine
+$!----------------------------------------------------------------------
+$ if skey2a .eqs. """`"
+$ then
+$! if pflag .eq. 1
+$! then
+$! write tf "#ifndef ''key2'"
+$! write tf "#define ",key2," """,gproj_name,"_",key2,""""
+$! write tf "#endif"
+$! else
+$! Ignore this for now
+$!------------------------------------------
+$ write tf "/* ", xline, " */"
+$! endif
+$ set_flag = 1
+$ goto found_in_configure
+$ endif
+$ if skey2a .eqs. """$"
+$ then
+$! if pflag .eq. 1
+$! then
+$! write tf "#ifndef ''key2'"
+$! write tf "#define ",key2," """,gproj_name,"_",key2,""""
+$! write tf "#endif"
+$! else
+$! Ignore this for now
+$!-------------------------------------------
+$ write tf "/* ", xline, " */"
+$! endif
+$ set_flag = 1
+$ goto found_in_configure
+$ endif
+$ if f$extract(0, 1, skey2) .eqs. "'"
+$ then
+$ skey2 = skey2 - "'" - "'"
+$ endif
+$ write tf "#ifndef ''key2'"
+$ write tf "#define ",key2," """,skey2,""""
+$ write tf "#endif"
+$ set_flag = 1
+$ else
+$ goto search_file_rd_loop
+$! if pflag .eq. 1
+$! then
+$! write tf "#ifndef ''key2'"
+$! write tf "#define ",key2," """,gproj_name,"_",key2,""""
+$! write tf "#endif"
+$! set_flag = 1
+$! endif
+$ endif
+$found_in_configure:
+$unknown_cf_rd_err:
+$ if f$trnlnm("sf","lnm$process",,"SUPERVISOR") .nes. ""
+$ then
+$ close sf
+$ endif
+$ if f$search(tfile1) .nes. "" then delete 'tfile1';*
+$ if set_flag .eq. 1 then goto cfgh_in_loop1
+$ endif
+$ endif
+$!
+$!
+$!
+$! If it falls through everything else, comment it out
+$!-----------------------------------------------------
+$ write tf "/* ", xline, " */"
+$ goto cfgh_in_loop1
+$cfgh_in_loop1_end:
+$close inf
+$!
+$!
+$! Write out the tail
+$!--------------------
+$write_tail:
+$gosub write_config_h_tail
+$!
+$! Exit and clean up
+$!--------------------
+$general_error:
+$status = '$status'
+$all_exit:
+$set noon
+$if f$trnlnm("sf","lnm$process",,"SUPERVISOR") .nes. "" then close sf
+$if f$trnlnm("tf","lnm$process",,"SUPERVISOR") .nes. "" then close tf
+$if f$trnlnm("inf","lnm$process",,"SUPERVISOR") .nes. "" then close inf
+$if f$trnlnm("tf1","lnm$process",,"SUPERVISOR") .nes. "" then close tf1
+$if f$trnlnm("tf2","lnm$process",,"SUPERVISOR") .nes. "" then close tf2
+$if f$trnlnm("tfcv","lnm$process",,"SUPERVISOR") .nes. "" then close tfcv
+$if f$type(tfile1) .eqs. "STRING"
+$then
+$ if f$search(tfile1) .nes. "" then delete 'tfile1';*
+$endif
+$if f$type(dchfile) .eqs. "STRING"
+$then
+$ if f$search(dchfile) .nes. "" then delete 'dchfile';*
+$endif
+$if f$type(configure_script) .eqs. "STRING"
+$then
+$ if f$search(configure_script) .nes. "" then delete 'configure_script';*
+$endif
+$exit 'status'
+$!
+$!
+$control_y:
+$ status = ss_control_y
+$ goto all_exit
+$!
+$!
+$!
+$! Gosub to write a new config_vms.h
+$!-----------------------------------
+$write_config_vms:
+$outfile = "sys$disk:[]config_vms.h"
+$create 'outfile'
+$open/append tf 'outfile'
+$write tf "/* File: config_vms.h"
+$write tf "**"
+$write tf "** This file contains the manual edits needed for porting"
+$!write tf "** the ''proj_name' package to OpenVMS.
+$write tf "**"
+$write tf "** Edit this file as needed. The procedure that automatically"
+$write tf "** generated this header stub will not overwrite or make any"
+$write tf "** changes to this file."
+$write tf "**"
+$write tf -
+ "** ", datetime, tab, username, tab, "Generated by ''my_proc_file'"
+$write tf "**"
+$write tf -
+ "**========================================================================*/"
+$write tf ""
+$close tf
+$return
+$!
+$! gosub to write out a documentation header for config.h
+$!----------------------------------------------------------------
+$write_config_h_header:
+$outfile = "sys$disk:[]config.h"
+$create 'outfile'
+$open/append tf 'outfile'
+$write tf "#ifndef CONFIG_H"
+$write tf "#define CONFIG_H"
+$write tf "/* File: config.h"
+$write tf "**"
+$write tf -
+ "** This file contains the options needed for porting "
+$write tf "** the project on a VMS system."
+$write tf "**"
+$write tf "** Try not to make any edits to this file, as it is"
+$write tf "** automagically generated."
+$write tf "**"
+$write tf "** Manual edits should be made to the config_vms.h file."
+$write tf "**"
+$write tf -
+ "** ", datetime, tab, username, tab, "Generated by ''my_proc_file'"
+$write tf "**"
+$write tf -
+ "**========================================================================*/"
+$write tf ""
+$write tf "#if (__CRTL_VER >= 70200000) && !defined (__VAX)"
+$write tf "#define _LARGEFILE 1"
+$write tf "#endif"
+$write tf ""
+$write tf "#ifndef __VAX"
+$write tf "#ifdef __CRTL_VER"
+$write tf "#if __CRTL_VER >= 80200000"
+$write tf "#define _USE_STD_STAT 1"
+$write tf "#endif"
+$write tf "#endif"
+$write tf "#endif"
+$write tf ""
+$!
+$if P1 .nes. "NOBUILTINS"
+$then
+$ write tf " /* Allow compiler builtins */"
+$ write tf "/*-------------------------*/"
+$ write tf "#ifdef __DECC_VER"
+$ write tf "#include <non_existant_dir:builtins.h>"
+$ write tf "#endif"
+$endif
+$!
+$write tf ""
+$return
+$!
+$! gosub to write out the tail for config.h and close it
+$!---------------------------------------------------------
+$write_config_h_tail:
+$write tf ""
+$write tf " /* Include the hand customized settings */"
+$write tf "/*--------------------------------------*/"
+$write tf "#include ""sys$disk:config_vms.h"""
+$write tf ""
+$write tf "#endif /* CONFIG_H */"
+$close tf
+$return
+$!
diff --git a/vms/descrip.mms b/vms/descrip.mms
index 967a312e..a0b7bd6a 100644
--- a/vms/descrip.mms
+++ b/vms/descrip.mms
@@ -12,14 +12,6 @@
# gawk.exe :
# This is the default target. DEC C has become the default compiler.
#
-# pgawk.exe :
-# An alternate version which generates some profiling feedback for
-# the awk programs it executes. Included with `make all'.
-#
-# dgawk.exe :
-# An alternate version which supports debugging.
-# Included with `make all'.
-#
# 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
@@ -48,12 +40,14 @@
# location of various source files, relative to the 'main' directory
VMSDIR = [.vms]
DOCDIR = [.doc]
+MISSNGD = [.missing_d]
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
+# Do not specify _POSIX_EXIT here, other tricks are used for this.
CDEFS = "GAWK","HAVE_CONFIG_H"
.ifdef GNUC
@@ -74,8 +68,15 @@ 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)
+.ifdef __VAX__
+CFLOAT =
+.else
+CFLOAT = /float=ieee/ieee_mode=denorm_results
+.endif
+CNAME = /NAME=(AS_IS,SHORT)
+CC = cc/DECC/Prefix=All/NESTED_INCLUDE=NONE$(CFLOAT)
+CFLAGS = /Incl=([],[.vms])/Obj=[]/Def=($(CDEFS))$(CNAME) $(CCFLAGS)
+CEFLAGS = /Incl=([],[.vms],[.missing_d],[.extension])$(CNAME) $(CCFLAGS)
LIBS = # DECC$SHR instead of VAXCRTL, no special link option needed
.endif !VAXC
.endif !GNUC
@@ -99,73 +100,45 @@ ECHO = write sys$output
NOOP = continue
# object files
-GAWKOBJ = eval.obj,profile.obj
-PGAWKOBJ = eval_p.obj,profile_p.obj
-DGAWKOBJ = eval_d.obj,profile.obj,command.obj,debug.obj
-AWKOBJ1 = array.obj,awkgram.obj,builtin.obj,dfa.obj,ext.obj,\
- field.obj,floatcomp.obj,gawkmisc.obj,getopt.obj,getopt1.obj,\
- io.obj
-AWKOBJ2 = main.obj,msg.obj,node.obj,random.obj,re.obj,\
- regex.obj,replace.obj,version.obj
+GAWKOBJ = eval.obj,profile.obj
+AWKOBJ1 = array.obj,awkgram.obj,builtin.obj,cint_array.obj,\
+ command.obj,debug.obj,dfa.obj,ext.obj,field.obj,\
+ floatcomp.obj,gawkapi.obj,gawkmisc.obj,getopt.obj,getopt1.obj
+
+AWKOBJ2 = int_array.obj,io.obj,main.obj,mpfr.obj,msg.obj,node.obj,\
+ random.obj,re.obj,regex.obj,replace.obj,\
+ str_array.obj,symbol.obj,version.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
+ vms_gawk.obj,vms_cli.obj,vms_crtl_init.obj
VMSCMD = gawk_cmd.obj # built from .cld file
VMSOBJS = $(VMSCODE),$(VMSCMD)
-# primary source files
-AWKSRC = array.c,builtin.c,dfa.c,eval.c,eval_p.c,ext.c,field.c,\
- floatcomp.c,gawkmisc.c,getopt.c,getopt1.c,io.c,main.c,\
- msg.c,node.c,profile.c,profile_p.c,random.c,re.c,regcomp.c,\
- regex.c,regex_internal.c,regexec.c,replace.c,version.c
-
-DBGSRC = eval_d.c,debug.c,command.y,cmd.h
-
-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=4.0
-PATCHLVL=0
+REL=4.1
+PATCHLVL=1
# generic target
-all : gawk,pgawk,dgawk
- $(NOOP)
+all : gawk
+ @ $(NOOP)
# dummy target to allow building "gawk" in addition to explicit "gawk.exe"
gawk : gawk.exe
- $(ECHO) " GAWK "
-pgawk : pgawk.exe
- $(ECHO) " PGAWK "
-dgawk : dgawk.exe
- $(ECHO) " DGAWK "
+ @ $(ECHO) "$< is upto date"
# rules to build gawk
gawk.exe : $(GAWKOBJ) $(AWKOBJS) $(VMSOBJS) gawk.opt
$(LINK) $(LINKFLAGS) gawk.opt/options
-# rules to build pgawk and dgawk
-pgawk.exe : $(PGAWKOBJ) $(AWKOBJS) $(VMSOBJS) pgawk.opt
- $(LINK) $(LINKFLAGS) pgawk.opt/options
-dgawk.exe : $(DGAWKOBJ) $(AWKOBJS) $(VMSOBJS) dgawk.opt
- $(LINK) $(LINKFLAGS) dgawk.opt/options
-
-gawk.opt : $(MAKEFILE) # create linker options file
- open/write opt gawk.opt ! ~ 'cat <<close >gawk.opt'
- write opt "! GAWK -- GNU awk"
+gawk.opt : $(MAKEFILE) config.h # create linker options file
+ @ open/write opt sys$disk:[]gawk.opt ! ~ 'cat <<close >gawk.opt'
+ @ write opt "! GAWK -- GNU awk"
@ write opt "$(GAWKOBJ)"
@ write opt "$(AWKOBJ1)"
@ write opt "$(AWKOBJ2)"
@@ -173,59 +146,64 @@ gawk.opt : $(MAKEFILE) # create linker options file
@ 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
-
-pgawk.opt : $(MAKEFILE) # create linker options file
- open/write opt pgawk.opt
- write opt "! PGAWK -- GNU awk w/ run-time profiling"
- @ write opt "$(PGAWKOBJ)"
- @ 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
-
-dgawk.opt : $(MAKEFILE) # create linker options file
- open/write opt dgawk.opt
- write opt "! DGAWK -- GNU awk w/ debugging"
- @ write opt "$(DGAWKOBJ)"
- @ 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
+ @ write opt "$(LIBS)"
+ @ close opt
+ $ @$(VMSDIR)gawk_ident.com
+
+$(VMSCODE) : awk.h config.h $(VMSDIR)redirect.h $(VMSDIR)vms.h
+$(AWKOBJS) : awk.h gettext.h mbsupport.h regex.h dfa.h config.h \
+ $(VMSDIR)redirect.h
+$(GAWKOBJ) : awk.h config.h $(VMSDIR)redirect.h
+
+#-----------------------------------------------------------------------------
+# Older versions of MMS have problems handling lower case file names typically
+# found on ODS-5 disks. Fix this by adding explicit dependencies.
+#_____________________________________________________________________________
+array.obj : array.c
+awkgram.obj : awkgram.c awk.h
+builtin.obj : builtin.c floatmagic.h random.h
+cint_array.obj : cint_array.c
+command.obj : command.c cmd.h
+debug.obj : debug.c cmd.h
+dfa.obj : dfa.c dfa.h
+ext.obj : ext.c
+eval.obj : eval.c
+field.obj : field.c
+floatcomp.obj : floatcomp.c
+gawkaoi.obj : gawkapi.c
+gawkmisc.obj : gawkmisc.c $(VMSDIR)gawkmisc.vms
+getopt.obj : getopt.c
+getopt1.obj : getopt1.c
+int_array.obj : int_array.c
+io.obj : io.c
+main.obj : main.c
+msg.obj : msg.c
+mpfr.obj : mpfr.c
+node.obj : node.c
+profile.obj : profile.c
+random.obj : random.c random.h
+re.obj : re.c
+regex.obj : regex.c regcomp.c regex_internal.c regexec.c regex.h \
+ regex_internal.h
+str_array.obj : str_array.c
+symbol.obj : symbol.c
+version.obj : version.c
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
-$(GAWKOBJ) : awk.h config.h $(VMSDIR)redirect.h
-$(PGAWKOBJ) : awk.h config.h $(VMSDIR)redirect.h
-$(DGAWKOBJ) : awk.h config.h $(VMSDIR)redirect.h
-random.obj : random.h
-builtin.obj : floatmagic.h 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
-command.obj,debug.obj : cmd.h
+vms_crtl_init.obj : $(VMSDIR)vms_crtl_init.c
+replace.obj : replace.c $(MISSNGD)system.c $(MISSNGD)memcmp.c \
+ $(MISSNGD)memcpy.c $(MISSNGD)memset.c $(MISSNGD)memmove.c \
+ $(MISSNGD)strncasecmp.c $(MISSNGD)strerror.c \
+ $(MISSNGD)strftime.c $(MISSNGD)strchr.c $(MISSNGD)strtod.c \
+ $(MISSNGD)strtoul.c $(MISSNGD)tzset.c $(MISSNGD)mktime.c \
+ $(MISSNGD)snprintf.c $(MISSNGD)getaddrinfo.c \
+ $(MISSNGD)usleep.c \
+ $(MISSNGD)setenv.c $(MISSNGD)strcoll.c $(MISSNGD)wcmisc.c
# bison or yacc required
awkgram.c : awkgram.y # foo.y :: yacc => y[_]tab.c, bison => foo_tab.c
@@ -236,7 +214,9 @@ awkgram.c : awkgram.y # foo.y :: yacc => y[_]tab.c, bison => foo_tab.c
$(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("awkgram_tab.c").nes."" then rename/new_vers awkgram_tab.c $@
+ @- if f$search("awkgram_tab.c").nes."" then \
+ rename/new_vers awkgram_tab.c $@
+
command.c : command.y
@- if f$search("ytab.c") .nes."" then delete ytab.c;*
@- if f$search("y_tab.c") .nes."" then delete y_tab.c;*
@@ -245,33 +225,148 @@ command.c : command.y
$(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("command_tab.c").nes."" then rename/new_vers command_tab.c $@
+ @- if f$search("command_tab.c").nes."" then \
+ rename/new_vers command_tab.c $@
+
+config_vms.h : $(VMSDIR)generate_config_vms_h_gawk.com
+ $ @$(VMSDIR)generate_config_vms_h_gawk.com
-config.h : $(VMSDIR)vms-conf.h
- copy $< $@
+config.h : configh.in config_vms.h $(VMSDIR)config_h.com
+ $ @$(VMSDIR)config_h.com
$(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
+install.help : $(VMSDIR)gawk.hlp
library/help $(HELPLIB) $< /log
+
+# Build dynamic extensions - Alpha/Itanium only.
+.ifdef __VAX__
+# VAX not complete yet.
+plug_opt = [.VMS.VAX]gawk_plugin_xfer.opt
+.else
+plug_opt = [.vms]gawk_plugin.opt
+.endif
+
+ext_gawkdirfd_h = [.extension]gawkdirfd.h config.h nonposix.h
+
+extensions : filefuncs.exe fnmatch.exe inplace.exe ordchr.exe readdir.exe \
+ revoutput.exe revtwoway.exe rwarray.exe testext.exe time.exe
+
+filefuncs.exe : filefuncs.obj stack.obj gawkfts.obj $(plug_opt)
+ link/share=$(MMS$TARGET) $(MMS$SOURCE), stack.obj, gawkfts.obj, \
+ $(plug_opt)/opt
+
+fnmatch.exe : fnmatch.obj $(plug_opt)
+ link/share=$(MMS$TARGET) $(MMS$SOURCE), $(plug_opt)/opt
+
+inplace.exe : inplace.obj $(plug_opt)
+ link/share=$(MMS$TARGET) $(MMS$SOURCE), $(plug_opt)/opt
+
+ordchr.exe : ordchr.obj $(plug_opt)
+ link/share=$(MMS$TARGET) $(MMS$SOURCE), $(plug_opt)/opt
+
+readdir.exe : readdir.obj $(plug_opt)
+ link/share=$(MMS$TARGET) $(MMS$SOURCE), $(plug_opt)/opt
+
+revoutput.exe : revoutput.obj $(plug_opt)
+ link/share=$(MMS$TARGET) $(MMS$SOURCE), $(plug_opt)/opt
+
+revtwoway.exe : revtwoway.obj $(plug_opt)
+ link/share=$(MMS$TARGET) $(MMS$SOURCE), $(plug_opt)/opt
+
+rwarray.exe : rwarray.obj $(plug_opt)
+ link/share=$(MMS$TARGET) $(MMS$SOURCE), $(plug_opt)/opt
+
+testext.exe : testext.obj $(plug_opt)
+ link/share=$(MMS$TARGET) $(MMS$SOURCE), $(plug_opt)/opt
+
+time.exe : time.obj $(plug_opt)
+ link/share=$(MMS$TARGET) $(MMS$SOURCE), $(plug_opt)/opt
+
+stack.obj : [.extension]stack.c config.h gawkapi.h \
+ [.extension]gawkfts.h, [.extension]stack.h
+ $(CC)$(CEFLAGS)/define=(HAVE_CONFIG_H)/object=$(MMS$TARGET) $(MMS$SOURCE)
+
+gawkfts.obj : [.extension]gawkfts.c config.h [.extension]gawkfts.h \
+ $(ext_gawkdirfd_h)
+ $(CC)$(CEFLAGS)/define=(HAVE_CONFIG_H, ZOS_USS, "fchdir(x)=(-1)") \
+ /object=$(MMS$TARGET) $(MMS$SOURCE)
+
+filefuncs.obj : [.extension]filefuncs.c config.h gawkapi.h \
+ [.extension]gawkfts.h
+ $(CC)$(CEFLAGS)/define=(HAVE_CONFIG_H)/object=$(MMS$TARGET) $(MMS$SOURCE)
+
+fnmatch.obj : [.extension]fnmatch.c config.h gawkapi.h \
+ [.missing_d]fnmatch.h [.missing_d]fnmatch.c
+ $(CC)$(CEFLAGS)/define=(HAVE_CONFIG_H)/object=$(MMS$TARGET) $(MMS$SOURCE)
+
+inplace.obj : [.extension]inplace.c config.h gawkapi.h
+ $(CC)$(CEFLAGS)/define=(HAVE_CONFIG_H)/object=$(MMS$TARGET) $(MMS$SOURCE)
+
+ordchr.obj : [.extension]ordchr.c config.h gawkapi.h
+ $(CC)$(CEFLAGS)/define=(HAVE_CONFIG_H)/object=$(MMS$TARGET) $(MMS$SOURCE)
+
+readdir.obj : [.extension]readdir.c config.h gawkapi.h \
+ $(ext_gawkdirfd_h)
+ $(CC)$(CEFLAGS)/define=(HAVE_CONFIG_H, HAVE_DIRENT_H) \
+ /object=$(MMS$TARGET) $(MMS$SOURCE)
+
+revoutput.obj : [.extension]revoutput.c config.h gawkapi.h
+ $(CC)$(CEFLAGS)/define=(HAVE_CONFIG_H)/object=$(MMS$TARGET) $(MMS$SOURCE)
+
+revtwoway.obj : [.extension]revtwoway.c config.h gawkapi.h
+ $(CC)$(CEFLAGS)/define=(HAVE_CONFIG_H, HAVE_GETDTABLESIZE) \
+ /object=$(MMS$TARGET) $(MMS$SOURCE)
+
+rwarray.obj : [.extension]rwarray.c config.h gawkapi.h
+ $(CC)$(CEFLAGS)/define=(HAVE_CONFIG_H)/object=$(MMS$TARGET) $(MMS$SOURCE)
+
+testext.obj : [.extension]testext.c config.h gawkapi.h
+ $(CC)$(CEFLAGS)/define=(HAVE_CONFIG_H)/object=$(MMS$TARGET) $(MMS$SOURCE)
+
+time.obj : [.extension]time.c config.h gawkapi.h
+ $(CC)$(CEFLAGS)/define=(HAVE_CONFIG_H)/object=$(MMS$TARGET) $(MMS$SOURCE)
+
+
# miscellaneous other targets
tidy :
- if f$search("*.*;-1").nes."" then purge
- if f$search("[.*]*.*;-1").nes."" then purge [.*]
clean :
- - delete *.obj;*,gawk.opt;*,pgawk.opt;*,dgawk.opt;*
+ - if f$search ("*.obj") .nes. "" then delete *.obj;*
+ - if f$search ("*.lis") .nes. "" then delete *.lis;*
+ - if f$search ("gawk.opt") .nes. "" then delete gawk.opt;*
spotless : clean tidy
- - if f$search("config.h").nes."" then rename config.h config.h-old/New
+ - if f$search("config.h").nes."" then delete config.h;*
+ - if f$search("config_vms.h").nes."" then delete config_vms.h;*
- if f$search("gawk.exe").nes."" then delete gawk.exe;*
- - if f$search("pgawk.exe").nes."" then delete pgawk.exe;*
- - if f$search("dgawk.exe").nes."" then delete dgawk.exe;*
+ - if f$search("*.dsf").nes."" then delete *.dsf;*
+ - if f$search("*.map").nes."" then delete *.map;*
+ - if f$search("*.pcsi$desc").nes."" then delete *.pcsi$desc;*
+ - if f$search("*.pcsi$text").nes."" then delete *.pcsi$text;*
+ - if f$search("gawk*_src.bck").nes."" then delete gawk*_src.bck;*
+ - if f$search("*.release_notes").nes."" then delete *.release_notes;*
+ - if f$search("filefuncs.exe").nes."" then delete filefuncs.exe;*
+ - if f$search("fnmatch.exe").nes."" then delete fnmatch.exe;*
+ - if f$search("inplace.exe").nes."" then delete inplace.exe;*
+ - if f$search("ordchr.exe").nes."" then delete ordchr.exe;*
+ - if f$search("readdir.exe").nes."" then delete readdir.exe;*
+ - if f$search("revoutput.exe").nes."" then delete revoutput.exe;*
+ - if f$search("revtwoway.exe").nes."" then delete revtwoway.exe;*
+ - if f$search("rwarray.exe").nes."" then delete rwarray.exe;*
+ - if f$search("testext.exe").nes."" then delete testext.exe;*
+ - if f$search("time.exe").nes."" then delete time.exe;*
+ - if f$search("gawk_verb.cld").nes."" then delete gawk_verb.cld;*
- if f$search("gawk.dvi").nes."" then delete gawk.dvi;*
- - if f$search("[.doc]texindex.exe").nes."" then delete [.doc]texindex.exe;*
+ - if f$search("[.doc]texindex.exe").nes."" then \
+ delete [.doc]texindex.exe;*
+ - if f$search("[.cxx_repository]*.*;").nes."" then \
+ delete [.cxx_repository]*.*;*
#
# Note: this only works if you kept a copy of [.support]texindex.c
@@ -293,7 +388,8 @@ gawk.dvi : [.doc]texindex.exe [.doc]gawk.texi
@ write sys$output " Third (final) pass"
TeX gawk.texi
-@ purge
- -@ delete gawk.lis;,.aux;,gawk.%%;,.cps;,.fns;,.kys;,.pgs;,.toc;,.tps;,.vrs;
+ -@ delete \
+ gawk.lis;,.aux;,gawk.%%;,.cps;,.fns;,.kys;,.pgs;,.toc;,.tps;,.vrs;
@ rename/new_vers gawk.dvi [-]*.*
@ set default [-]
diff --git a/vms/fcntl.h b/vms/fcntl.h
deleted file mode 100644
index d975db7a..00000000
--- a/vms/fcntl.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* "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
diff --git a/vms/gawk.hlp b/vms/gawk.hlp
index 4b82e7e9..a14ad72b 100644
--- a/vms/gawk.hlp
+++ b/vms/gawk.hlp
@@ -1183,6 +1183,10 @@
the default is systime(); if u is present and non-zero
then t is treated as a UTC value, otherwise it is
considered to be local time
+
+5 time_logical_names
+ Gawk needs the SYS$TIMEZONE_RULE or TZ logical names defined or it will
+ output the time in the GMT timezone.
5 time_formats
Formatting directives similar to the 'printf' & 'sprintf' functions
(each is introduced in the format string by preceding it with a
@@ -1557,9 +1561,28 @@
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.
+ VMS status value, so 0 indicates success. A failure is indicated
+ by 1 and VMS will set the ERROR status. A fatal error is indicated
+ by 2 and VMS will set the FATAL status. All other values will will have
+ the SUCCESS status. The exit value is encoded to comply with VMS
+ coding standards and will have the C_FACILITY_NO of 0x350000 with
+ the constant 0xA000 added to the number shifted over by 3 bits to
+ make room for the severity codes.
+
+ To extract the actual gawk exit code from the VMS status use:
+ unix_status = (vms_status .and. &x7f8) / 8
+
+ A C program that uses exec() to call gawk will get the original
+ UN*X-style exit value.
+
+ Older versions of Gawk treated Unix exit code 0 as 1, A failure as
+ 2, and a fatal error as 4, and passed all the other numbers through.
+ This violated the VMS exit status coding requirements.
+
+4 rounding
+ VAX/VMS floating point uses unbiased rounding. This is different than
+ what portable gawk programs expect.
+
3 changes
Changes between version 4.0.0 and earlier versions
@@ -1569,6 +1592,7 @@
General
dgawk.exe does interactive debugging of awk programs
pgawk.exe does comprehensive execution profiling of awk programs
+ pgawk.exe is not currently supplied for VMS.
-d[file] and -p[file] options added
-Wcompat and -Wusage options dropped; use -Wtraditional and -Whelp
BEGINFILE and ENDFILE built-in rule patterns
@@ -1594,6 +1618,10 @@
support for radix prefix '0' (octal) and '0x' (hexadecimal)
VMS-specific
+ The VMS exit codes now correctly encode the gawk exit status and
+ the VMS severity bits are set.
+ Large file support is enabled on the platforms that support it.
+ Extended filename support is enabled on the platforms that support it.
New command qualifiers: /EXTRA_COMMANDS, /PROFILE, /DUMP_VARIABLES,
/OPTIMIZE, /TRADITIONAL, /SANDBOX, /NON_DECIMAL_DATA
Revised qualifier: /LINT, takes optional argument list
diff --git a/vms/gawk_alias_setup.com b/vms/gawk_alias_setup.com
new file mode 100644
index 00000000..a7f13f4b
--- /dev/null
+++ b/vms/gawk_alias_setup.com
@@ -0,0 +1,139 @@
+$! File: gawk_alias_setup.com
+$!
+$! The PCSI procedure needs a helper script to set up and remove aliases.
+$!
+$! If p1 starts with "R" then remove instead of install.
+$!
+$!
+$! 02-Jan-2014 J. Malmberg - Gawk Version
+$!
+$!===========================================================================
+$!
+$ mode = "install"
+$ code = f$extract(0, 1, p1)
+$ if code .eqs. "R" .or. code .eqs. "r" then mode = "remove"
+$!
+$ arch_type = f$getsyi("ARCH_NAME")
+$ arch_code = f$extract(0, 1, arch_type)
+$!
+$ if arch_code .nes. "V"
+$ then
+$ set proc/parse=extended
+$ endif
+$!
+$!
+$ call do_alias "gawk" "[bin]"
+$ call do_alias "gawk" "[bin]" "awk"
+$ call do_alias "gawk" "[bin]" "gawk" "[usr.bin]"
+$ call do_alias "gawk" "[bin]" "awk" "[usr.bin]"
+$ call do_alias "gawk.1" "[usr.share.man.man1]" "awk.1"
+$!
+$ exit
+$!!
+$!
+$do_alias: subroutine
+$ if mode .eqs. "install"
+$ then
+$ call add_alias "''p1'" "''p2'" "''p3'" "''p4'"
+$ else
+$ call remove_alias "''p1'" "''p2'" "''p3'" "''p4'"
+$ endif
+$ exit
+$ENDSUBROUTINE ! do_alias
+$!
+$!
+$! P1 is the filename, p2 is the directory prefix,
+$! p3 is the alias name if different than p1
+$! p4 is the alias directory if different than p2
+$add_alias: subroutine
+$ if p3 .eqs. "" then p3 = p1
+$ if p4 .eqs. "" then p4 = p2
+$ ftype = f$element(1, ".", p1)
+$ if ftype .eqs. "."
+$ then
+$ file = "gnv$gnu:''p2'gnv$''p1'.EXE"
+$ alias = "gnv$gnu:''p4'''p3'."
+$ else
+$ file = "gnv$gnu:''p2'''p1'"
+$ alias = "gnv$gnu:''p4'''p3'"
+$ endif
+$ if f$search(file) .nes. ""
+$ then
+$ fid = ""
+$ mess = f$environment("message")
+$ if f$search(alias) .nes. ""
+$ then
+$ on warn then goto fix_link
+$ set message/nofac/nosev/noident/notext
+$ fid = f$file_attributes(alias, "FID")
+$ endif
+$ goto fix_link_end
+$fix_link:
+$ set file/remove 'alias';
+$fix_link_end:
+$ set message'mess'
+$ if f$search(alias) .eqs. ""
+$ then
+$ set file/enter='alias' 'file'
+$ endif
+$ alias1 = alias + "exe"
+$ if (ftype .eqs. ".")
+$ then
+$ fid = ""
+$ mess = f$environment("message")
+$ if f$search(alias1) .nes. ""
+$ then
+$ on warn then goto fix_link1
+$ set message/nofac/nosev/noident/notext
+$ fid = f$file_attributes(alias1, "FID")
+$ endif
+$ goto fix_link_end1
+$fix_link1:
+$ set file/remove 'alias1';
+$fix_link_end1:
+$ set message'mess'
+$ if (f$search(alias1) .eqs. "")
+$ then
+$ set file/enter='alias1' 'file'
+$ endif
+$ endif
+$ endif
+$ exit
+$ENDSUBROUTINE ! add_alias
+$!
+$remove_alias: subroutine
+$ if p3 .eqs. "" then p3 = p1
+$ if p4 .eqs. "" then p4 = p2
+$ ftype = f$element(1, ".", p1)
+$ if ftype .eqs. "."
+$ then
+$ file = "gnv$gnu:''p2'gnv$''p1'.EXE"
+$ alias = "gnv$gnu:''p4'''p3'."
+$ else
+$ file = "gnv$gnu:''p2'''p1'"
+$ alias = "gnv$gnu:''p4'''p3'"
+$ endif
+$ file_fid = "No_file_fid"
+$ if f$search(file) .nes. ""
+$ then
+$ fid = f$file_attributes(file, "FID")
+$ if f$search(alias) .nes. ""
+$ then
+$ afid = f$file_attributes(alias, "FID")
+$ if (afid .eqs. fid)
+$ then
+$ set file/remove 'alias';
+$ endif
+$ endif
+$ alias1 = alias + "exe"
+$ if (ftype .eqs. ".") .and. (f$search(alias1) .nes. "")
+$ then
+$ afid = f$file_attributes(alias1, "FID")
+$ if (afid .eqs. fid)
+$ then
+$ set file/remove 'alias1';
+$ endif
+$ endif
+$ endif
+$ exit
+$ENDSUBROUTINE ! remove_alias
diff --git a/vms/gawk_build_steps.txt b/vms/gawk_build_steps.txt
new file mode 100644
index 00000000..b3bb281b
--- /dev/null
+++ b/vms/gawk_build_steps.txt
@@ -0,0 +1,220 @@
+From File: gawk_build_steps.txt
+
+Building GAWK on OpenVMS for use with GNV requires a current HP C compiler
+and MMK.
+
+The HP C 7.x compilers were used for building on Alpha and Itanium.
+The Compaq C 6.4 compiler is being used on VAX.
+
+MMK was obtained from https://github.com/endlesssoftware/mmk
+
+Several special things were done in this port of Gawk to VMS to make it
+easier to keep it up to date with the Unix version.
+
+Note the GNV$ prefix is registered for the GNV project to prevent name
+collisions with other products and packages. This is a VMS convention.
+
+The files are stored with GNV_ instead of GNV$ most open source source
+code maintainers do not want to files with $ in their source repositories.
+
+The build procedure will copy the files to have the GNV$ names as needed.
+
+1. The original GNU Gawk source files are in their own directory tree which
+is never written to by the build process. This directory is kept up to date
+with the current official patches. See below about the how this is done
+with logical names.
+
+2. A file vms_eco_level.h is used to set the ECO of the package. The
+vms_eco_level.h needs to be set back to zero if the version or patch level
+of the GNU Unix source is changed. This file is currently only used
+by the kit building procedure.
+
+The source kits are provided in backup savesets inside of the PCSI install kit.
+
+Backup save sets are currently the only distribution medium that I can be
+sure is installed on a target VMS system that will correctly unpack files
+with extended character sets in them. You may need to adjust the ownership
+of the restored files for kits on Alpha/Itanium VMS versions 8.1 and earlier.
+
+On VAX, the filenames will be as seen on the VAX system, typically with non
+ODS-2 characters and case changes prefixed with $ characters.
+
+[gnv.common_src]gawk_*_original_src.bck is the original source of the
+gawk kit as provided by the GNV project.
+[gnv.vms_src]gawk-*_vms_src.bck, if present, has the changed files that
+are used for building that are not yet in the gawk source kits
+distributed by the GNU gawk project.
+
+These backup savesets should be restored to different directory trees on
+an ODS-5 volume(s) which are referenced by concealed rooted logical names,
+unless on VAX, where either an NFS or ODS-2 volume can be used.
+
+SRC_ROOT: is for the source files common to all platforms. This can be a
+ read only copy of the files from a change control repository.
+
+ In my build environment, the TRUNK_ROOT:[gawk] is the
+ same directory as src_root:[gawk]. TRUNK_ROOT:[gawk] is a
+ checkout of the gawk repository used for the build.
+
+VMS_ROOT: is for the files that were changed from the repository copy of
+ SRC_ROOT:
+
+ Note, you should create the VMS_ROOT: directory tree even if it is
+ initially empty. This is where you should put edits if you are
+ making changes.
+
+ In my build environment, the source_root:[gnu_vms.gawk] is a
+ directory with the checked out code and vms_root:[gawk] is
+ a copy with any local modifications.
+
+ The command procedure compare_gawk_source.com will report any
+ differences in the source_root:[gnu_vms.gawk] directory and the
+ vms_root:[gawk] directory. If the source_root: logical is not
+ defined, it will translate the logical name src_root to do the
+ effective of src_root:[gawk.-.-.gnu_vms.gawk] to find the
+ VMS specific code CVS checkout based on where the checkout for
+ the GNU source is expected to be.
+
+LCL_ROOT: is manually created to have the same base and sub-directories as
+ SRC_ROOT: and VMS_ROOT: This is for the architecture specific
+ binaries and other files created during the build.
+
+The logical name REF_ROOT: is optionally defined to be a logical name that
+is a search list for VMS_ROOT:,SRC_ROOT:
+
+The logical name PRJ_ROOT: is defined to be a logical name that is a search
+list for LCL_ROOT:,REF_ROOT:
+
+The VMS_ROOT and LCL_ROOT directory trees can be created with commands
+similar to:
+
+ $ create/dir lcl_root:[gawk]/prot=w:re
+ $ copy src_root:[gawk...]*.dir -
+ lcl_root:[gawk...]/prot=(o:rwed,w:re)
+ $ create/dir vms_root:[gawk]/prot=w:re
+ $ copy src_root:[gawk...]*.dir -
+ vms_root:[gawk...]/prot=(o:rwed,w:re)
+
+One of the ways with to protect the source from being modified is to have
+the directories under src_root: owned by a user or resource where the build
+username only has read access to it.
+
+Edit the file gawk_release_note_start.txt or other text files to reflect
+any changes.
+
+Edit the file PCSI_GAWK_FILE_LIST.TXT if there are new files added to the
+kit. These files should all be ODS-2 legal filenames and directories.
+
+Note that if src_root: or vms_root: are NFS mounted disks, the
+step of backing up the source files will probably hang or fail.
+
+You need to copy the source files to VMS mounted disks and create
+logical names SRC_ROOT1 and VMS_ROOT1 to work around this to to
+reference local disks. Make sure src_root1:[000000] and
+vms_root1:[000000] exist and can be written to.
+
+The command procedure compare_gawk_source can be used to check
+those directories and keep them up to date.
+
+ @[.vms]compare_gawk_source.com SRCBCK UPDATE
+
+ This compares the reference GNU source with the backup
+ staging directory for it and updates with any changes.
+
+ @[.vms]compare_gawk_source.com VMSBCK UPDATE
+
+ This compares the VMS specific source with the backup
+ staging directory for it and updates with any changes.
+
+ Leave off "UPDATE" to just check without doing any changes.
+
+ If you are not using NFS mounted disks and do not want to have a
+ separate directory for staging the sources for backup make sure
+ that src_root1: and vms_root1: do not exist.
+
+The kits will be built in the directory STAGE_ROOT:[KIT], which must be
+writable to the build procedure.
+
+Define the logical name GNV_PCSI_PRODUCER to indicate who is making the
+distribution.
+
+Define the logical name GNV_PCSI_PRODUCER_FULL_NAME to be your full name
+or full name of your company.
+
+These two GNV_PCSI_* logical names need to be manually defined to indicate
+the "branding" to differentiate the source of the kit.
+
+A limitation of the PCSI kitting procedure is that when selecting files, it
+tends to ignore the directory structure and assumes that all files with the
+same name are the same file, so every file placed in the kit must have a
+unique ODS-2 legal name. Then a procedure needs to be added to the kit to
+create an alias link on install and remove the link on remove.
+
+While newer versions of PCSI can support ODS-5 filenames, not all verions
+of PCSI on systems that have ODS-5 filenames do. So as a post install step,
+the PCSI kit built by these steps does a rename to the correct case.
+
+With these search lists set up and the logical names described, Gawk can
+be built and kitted by setting your default to PRJ_ROOT:[gawk]
+and then issuing the command:
+
+ $ @[.vms]pcsi_product_gawk.com
+
+First it will build the binaries by using MMK utility. The case of the
+parameter may be significant on ODS-5.
+
+ $ mmk/descrip=[.vms]descrip.mms gawk
+
+Then for Alpha and Itanium, it will build the dynamic extensions.
+
+ $ mmk/descrip=[.vms]descrip.mms extensions
+
+To clean up after a build to start over, run mmk with the target spotless.
+
+ $ mmk/descrip=[.vms]descrip.mms spotless
+
+The files are installed into a NEW_GNU directory for staging by running the
+procedure stage_gawk_install.com. This copies the binaries and creates
+alias links to them.
+
+ $ @[.vms]stage_gawk_install.com remove
+ $ @[.vms]stage_gawk_install.com
+
+On the VAX platform, the staged files are needed for building the PCSI
+kit, as the VAX source was staged on an NFS volume, which encodes the
+filenames that have any upper case or special symbols in them.
+
+To remove the staged files, the procedure is run again with the parameter
+"REMOVE". This makes sure that the alias links are removed.
+
+The names and contents of the PCSI files requires that the version of
+gawk be encoded in a special format. This is done by:
+
+ @[.vms]make_pcsi_gawk_kit_name.com
+
+The release notes are built from the release note start, readme files and
+this file:
+
+ @[.release]build_gawk_release_notes.com
+
+Then the backup the source kits.
+
+Building a PCSI kit for an architecture takes the following steps after
+making sure that you have a working build environment.
+
+On VAX, the product command always prompts to the terminal for a confirmation.
+
+If there is another kit for this same version of gawk, but for a different
+base platform or operating system version, the product command will prompt
+to the terminal to select which one to compress.
+
+ The following message is normal:
+ %PCSI-I-CANNOTVAL, cannot validate
+ EAGLE$DQA0:[stage_root.][kit]GNV-AXPVMS-GAWK-V--1.PCSI;1
+ -PCSI-I-NOTSIGNED, product kit is not signed and therefore has
+ no manifest file
+
+This will result in both compressed and uncompressed kits for the target
+platform.
+
+Good Luck.
diff --git a/vms/gawk_ident.com b/vms/gawk_ident.com
new file mode 100644
index 00000000..5b3966f9
--- /dev/null
+++ b/vms/gawk_ident.com
@@ -0,0 +1,21 @@
+$! gawk_ident.com - Append ident with version to gawk.
+$!
+$!
+$ open/read cfgh config.h
+$cfgh_loop:
+$ read/end=cfgh_loop_end cfgh line_in
+$ key1 = f$element(0, " ", line_in)
+$ if key1 .nes. "#define" then goto cfgh_loop
+$ key2 = f$element(1, " ", line_in)
+$ if key2 .nes. "VERSION" then goto cfgh_loop
+$ version_string = f$element(2, " ", line_in) - """" - """"
+$ ver_major = f$element(0, ".", version_string)
+$ ver_minor = f$element(1, ".", version_string)
+$ REL = ver_major + "." + ver_minor
+$ PATCHLVL = f$element(2, ".", version_string)
+$cfgh_loop_end:
+$ close cfgh
+$!
+$ open/append Fopt gawk.opt
+$ write Fopt "identification=""V''REL'.''PATCHLVL'"""
+$ close Fopt
diff --git a/vms/gawk_plugin.opt b/vms/gawk_plugin.opt
new file mode 100644
index 00000000..b0523d08
--- /dev/null
+++ b/vms/gawk_plugin.opt
@@ -0,0 +1,5 @@
+CASE_SENSITIVE=YES
+SYMBOL_VECTOR=(plugin_is_GPL_compatible=DATA)
+SYMBOL_VECTOR=(PLUGIN_IS_GPL_COMPATIBLE/plugin_is_GPL_compatible=DATA)
+SYMBOL_VECTOR=(dl_load=PROCEDURE)
+SYMBOL_VECTOR=(DL_LOAD/dl_load=PROCEDURE)
diff --git a/vms/gawk_release_note_start.txt b/vms/gawk_release_note_start.txt
new file mode 100644
index 00000000..44fceaf5
--- /dev/null
+++ b/vms/gawk_release_note_start.txt
@@ -0,0 +1,189 @@
+From file: gawk_release_note_start.com
+
+This is GNU gawk packaged for VMS.
+
+The original readme files for GAWK for standalone building on VMS are
+supplied here along with a procedure for building GAWK for the making
+a PCSI kit.
+
+Note: I am a hobbyist and am not providing any support or any commitment
+to supply bug fixes or future releases. This code is as-is with no
+warrantees.
+
+The testing of this port of Gawk involved running some self tests that
+were provided with the source.
+
+This version of gawk supports dynamically loaded extensions on Alpha and
+Itanium versions of VMS. The pre-built dynamically loaded extensions
+are in gnv$gnu:[usr.lib.gawk].
+
+The linker option file used to build a dynamically loaded extension is
+located in gnv$gnu:[usr.src.gawk.extension.vms], and the gawkapi.h file
+is in gnv$gnu:[usr.include].
+
+Special installation notes:
+
+* Please see https://sourceforge.net/p/gnv/wiki/InstallingGNVPackages/
+ for the latest information on installing GNV related PCSI kits.
+
+* We are updating and replacing GNV one kit at a time and transitioning
+ GNV to be a set of kits that the GNV package will install. During
+ this transition some extra issues will need to be handled during
+ installs and upgrades.
+
+* Due to the way that PCSI identifies packages, if you install a package
+ from one producer and then want to upgrade it from another producer,
+ you will probably need to uninstall the previous package first.
+
+ Some of these packages were previously created with different producer
+ prefixes. We are standardizing on VMSPORTS and GNV as the branding
+ prefixes. GNV will be for packages that are part of the GNV product
+ suite, and VMSPORTS will be for most other packages.
+
+ This uninstall can cause warning messages about dependencies. If you
+ are transitioning to an upwardly compatible package, you can ignore
+ those warnings.
+
+* This package should be installed to the same volume as GNV is installed.
+
+ If you uninstall or upgrade GNV or install a GNV from before the
+ transition is complete, you will need to reinstall all other packages
+ that install to the same GNV directory tree.
+
+ This is because at least some of the existing GNV installation procedures
+ have bugs in them were instead of just deleting the files that were
+ installed, they delete all files in the GNV directory tree.
+
+* Because this is a transition, this package is replacing files from the
+ old GNV packages. This is a necessary issue to allow incremental
+ improvement as we can not replace the GNV package until we get all
+ the component packages done.
+
+* The GNV 2.x through at least the 3.0.1 kits make an unusual change
+ to the disk directory structure where they are installed where
+ they use the [vms$common.gnv] as a mount point and mount the posix
+ root on it. This is a bug because it causes many problems and does
+ not offer any advantages. One of the problems is that it causes
+ problems with other PCSI installs and uninstalls to that directory.
+
+ This bug can be manually repaired such as has been done on
+ on encompasserve.org as documented in PORTING_TO_VMS notes conference.
+
+ At this time, we do not have a scripted repair to this bug, and it
+ may not be possible to fully script a repair because this bug can
+ cause the POSIX root and [vms$common.gnv] to have different contents
+ when they should be the same directory, and it will take a manual
+ inspection to select which files go where.
+
+* Because of the directory change bug, the gnv$startup.com in the GNV
+ kit must be run when the system boots up or the [vms$common.gnv]
+ directory will appear to be empty.
+
+ If a PCSI kit like this one is installed when the GNV startup has not
+ been run, it will create a new directory tree under [vms$common.gnv]
+ that will not be visible to the posix root. If you uninstall this
+ PCSI kit before running the gnv$startup.com procedure then you can
+ install it after running the gnv$startup.com procedure. If you have
+ run the gnv$startup.com procedure after the install, then you have
+ a mess, and you will need to use the GNV umnt to un-mount the
+ [vms$common.gnv] directory before the uninstall of this kit will
+ work.
+
+An analyze/disk/repair step on the installation disk should be done after
+installation to collect files left over from incomplete deletions into the
+SYSLOST directory. This step should be done on a "quiet" system per HP
+recomendations.
+
+Bugs can be logged at the tracker with https://sourceforge.net/projects/gnv/.
+There is no guarantee that bugs will be fixed for a hobbyist build.
+
+VMS specific port information:
+
+The logical name GNV$GNU is used to find the simulated posix root and defines
+the logical name SYS$POSIX_ROOT in the process table in user mode for child
+processes if needed. This is to comply with VMS logical name conventions.
+The logical name BIN is also set in the process table in user mode to be
+GNV$GNU:[BIN] if it is not already set.
+
+The following DECC$Feature settings are in in effect for Gawk by default:
+
+DECC$ACL_ACCESS_CHECK enabled.
+DECC$ALLOW_REMOVE_OPEN_FILES enabled.
+DECC$ARGV_PARSE_STYLE enabled.
+DECC$EFS_CASE_PRESERVE enabled.
+DECC$EFS_CHARSET enabled.
+DECC$EFS_FILE_TIMESTAMPS enabled.
+DECC$ENABLE_GETENV_CACHE enabled.
+DECC$EXEC_FILEATTR_INHERITANCE set to 2.
+DECC$FILE_PERMISSION_UNIX enabled.
+DECC$FILE_SHARING enabled.
+DECC$FILE_OWNER_UNIX enabled.
+DECC$FILENAME_REPORT_UNIX enabled.
+DECC$FILENAME_UNIX_NO_VERSION enabled.
+DECC$GLOB_UNIX_STYLE enabled.
+DECC$POSIX_SEEK_STREAM_FILE enabled.
+DECC$READDIR_DROPDOTNOTYPE enabled.
+DECC$RENAME_NO_INHERIT enabled.
+DECC$STDIO_CTX_EOL enabled.
+DECC$STRTOL_ERANGE enabled.
+DECC$UNIX_PATH_BEFORE_LOGNAME enabled.
+
+While more strict UNIX compatibility feature settings can be applied by users
+by setting feature logical names, these settings are all the Bash and most
+ported programs need.
+
+This port of Gawk uses the VMS CRTL to handle the Unix format pathnames
+and as such is dependent on them. It is a known issue that directories with
+a Unix name "file.dir/" and some symbolic links are not handled correctly.
+This is a combination of problems with RMS and CRTL. The RMS portion is
+fixed with the VMS84?_RMS-V0300 ECO kit. I am not aware of a CRTL kit that
+fixes the issues.
+
+This kit is designed to be used with the GNV Bash 4.2.45 or later kit.
+
+Fixes and enhancements:
+
+* No logical names required for proper Gawk operations other than GNV$GNU
+ for locating the simulated "/".
+
+* GNV$GNU is used to find the posix root and locally sets SYS$POSIX_ROOT
+ for child processes if needed. This is to comply with VMS logical
+ name conventions. The logical name BIN is also set locally to be
+ GNV$GNU:[BIN] if it is not already set.
+
+* config.h now generated at part of the build from a template.
+
+The supplied GNV$GAWK_STARTUP.COM procedure is provided in
+[VMS$COMMON.SYS$STARTUP] can be put in your VMS startup procedure to install
+selected images as known because they need privileges. It is recommended
+that the GNV$STARTUP.COM procedure be run first, followed by the
+GNV$BASH_STARTUP.COM procedure before the GNV$GAWK_STARTUP.COM is
+executed.
+
+The names of the gawk image have been prefixed with GNV$ to prevent
+possible naming conflicts with other programs that are on the system. The
+GNV$ prefix has been registered with HP for this purpose.
+
+OpenVMS specific building and kitting instructions are after the standard
+bash readme file below.
+
+The source kits contains files for building Gawk using MMK.
+MMK 4.0 was used for this build on Alpha and Itanium Itanium.
+
+Currently, the focus of the OpenVMS GNV porting team is to address bugs in
+the OpenVMS port of GNV components that pose immediate barriers to running
+configure and make scripts for Open Source Software packages targeting
+OpenVMS environments.
+
+The GNV development team is involved in an ongoing effort to identify and
+document the underlying technical causes for these current limitations and (if
+available) workarounds as well as developing code fixes to eliminate them. The
+VMS-Ports Source Forge project at https://sourceforge.net/p/vms-ports/tickets/
+currently documents OpenVMS CRTL bugs and limitations with respect to porting
+Open Source Software using OpenVMS. The VMS-Ports Source Forge Project also
+contains examples of ported packages provided by volunteer contributors as well
+as documentation with recommendations on how to setup, modify and use the
+OpenVMS GNV environment for the purpose of porting Open Source software
+packages to OpenVMS. Browse to https://sourceforge.net/p/vms-ports/wiki/Home/
+for more information.
+
diff --git a/vms/gawk_verb.com b/vms/gawk_verb.com
new file mode 100644
index 00000000..b74c49ed
--- /dev/null
+++ b/vms/gawk_verb.com
@@ -0,0 +1,26 @@
+$! gawk_verb.com - build the gawk_verb.cld from the gawk.cld.
+$!
+$! The CLD file needed to modify a DCL command table is different
+$! from the CLD file needed to build the product by specifying an image.
+$!
+$! So read in the [.vms]gawk.cld and generate a gawk_verb.cld.
+$!
+$! 23-Dec-2012 - J. Malmberg
+$!
+$outfile = "sys$disk:[]gawk_verb.cld"
+$infile = "[.vms]gawk.cld"
+$open/read cld 'infile'
+$create 'outfile'
+$open/append cldv 'outfile'
+$loop:
+$read cld/end=loop_end line_in
+$if f$locate("image gawk", line_in) .lt. f$length(line_in)
+$then
+$ write cldv " image gnv$gnu:[bin]gnv$gawk"
+$ goto loop
+$endif
+$write cldv line_in
+$goto loop
+$loop_end:
+$close cldv
+$close cld
diff --git a/vms/gawkmisc.vms b/vms/gawkmisc.vms
index 346a1e88..725cf669 100644
--- a/vms/gawkmisc.vms
+++ b/vms/gawkmisc.vms
@@ -3,7 +3,8 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-1996, 2003, 2011 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-1996, 2003, 2011, 2014
+ * the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Progamming Language.
@@ -23,29 +24,441 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#include <descrip.h>
+#include <dvidef.h>
+#include <efndef.h>
+#include <fscndef.h>
+#include <stsdef.h>
+#include <time.h>
+#include <lnmdef.h>
+
+
+#pragma member_alignment save
+#pragma nomember_alignment longword
+struct item_list_3 {
+ unsigned short len;
+ unsigned short code;
+ void * bufadr;
+ unsigned short * retlen;
+};
+
+struct filescan_itmlst_2 {
+ unsigned short length;
+ unsigned short itmcode;
+ char * component;
+};
+
+#pragma member_alignment
+
+int SYS$GETDVIW(
+ unsigned long efn,
+ unsigned short chan,
+ const struct dsc$descriptor_s * devnam,
+ const struct item_list_3 * itmlst,
+ void * iosb,
+ void (* astadr)(unsigned long),
+ unsigned long astprm,
+ void * nullarg);
+
+int SYS$FILESCAN(
+ const struct dsc$descriptor_s * srcstr,
+ struct filescan_itmlst_2 * valuelist,
+ unsigned long * fldflags,
+ struct dsc$descriptor_s *auxout,
+ unsigned short * retlen);
+
+int SYS$TRNLNM(
+ const unsigned long * attr,
+ const struct dsc$descriptor_s * table_dsc,
+ struct dsc$descriptor_s * name_dsc,
+ const unsigned char * acmode,
+ const struct item_list_3 * item_list);
+
char quote = '\'';
char *defpath = DEFPATH;
+char *deflibpath = DEFLIBPATH;
char envsep = ',';
+#define VMS_NAME_LEN 255
+static char vms_name[VMS_NAME_LEN+1];
+
+/* Take all the fun out of simply looking up a logical name */
+static int sys_trnlnm
+ (const char * logname,
+ char * value,
+ int value_len)
+{
+ const $DESCRIPTOR(table_dsc, "LNM$FILE_DEV");
+ const unsigned long attr = LNM$M_CASE_BLIND;
+ struct dsc$descriptor_s name_dsc;
+ int status;
+ unsigned short result;
+ struct item_list_3 itlst[2];
+
+ itlst[0].len = value_len;
+ itlst[0].code = LNM$_STRING;
+ itlst[0].bufadr = value;
+ itlst[0].retlen = &result;
+
+ itlst[1].len = 0;
+ itlst[1].code = 0;
+
+ name_dsc.dsc$w_length = strlen(logname);
+ name_dsc.dsc$a_pointer = (char *)logname;
+ name_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ name_dsc.dsc$b_class = DSC$K_CLASS_S;
+
+ status = SYS$TRNLNM(&attr, &table_dsc, &name_dsc, 0, itlst);
+
+ if ($VMS_STATUS_SUCCESS(status)) {
+
+ /* Null terminate and return the string */
+ value[result] = '\0';
+ }
+
+ return status;
+}
+
/* gawk_name --- pull out the "gawk" part from how the OS called us */
+/* You would not think that this should be a such a problem, but
+ * VMS extended file specifications are tricky to parse, and we have
+ * to tell the difference between a CRTL generated argv[0] and a
+ * passed exec() argv[0] and handle both cases.
+ */
+
char *
gawk_name(filespec)
const char *filespec;
{
- char *p, *q;
+ int status;
+ int result;
+ char * shell;
+ int lcname = 0;
+
+ /* If the path name starts with a /, then it is an absolute path
+ * that may have been generated by the CRTL instead of the command
+ * name. If it is the device name between the slashes, then this
+ * was likely from the run command and needs to be fixed up.
+ * If the DECC$POSIX_COMPLIANT_PATHNAMES is set to 2, then it is
+ * the DISK$VOLUME that will be present, and it will still need to
+ * be fixed.
+ */
- /* "device:[root.][directory.subdir]GAWK.EXE;n" -> "GAWK" */
- p = strrchr(filespec, ']'); /* directory punctuation */
- q = strrchr(filespec, '>'); /* alternate <international> punct */
+ result = 0;
+ if (filespec[0] == '/') {
+ char * nextslash;
+ int length;
+ struct item_list_3 itemlist[3];
+ unsigned short dvi_iosb[4];
+ char alldevnam[64];
+ unsigned short alldevnam_len;
+ struct dsc$descriptor_s devname_dsc;
+ char diskvolnam[256];
+ unsigned short diskvolnam_len;
+
+ /* Get some information about the disk */
+ /*--------------------------------------*/
+ itemlist[0].len = (sizeof alldevnam) - 1;
+ itemlist[0].code = DVI$_ALLDEVNAM;
+ itemlist[0].bufadr = alldevnam;
+ itemlist[0].retlen = &alldevnam_len;
+ itemlist[1].len = (sizeof diskvolnam) - 1 - 5;
+ itemlist[1].code = DVI$_VOLNAM;
+ itemlist[1].bufadr = &diskvolnam[5];
+ itemlist[1].retlen = &diskvolnam_len;
+ itemlist[2].len = 0;
+ itemlist[2].code = 0;
+
+ /* Add the prefix for the volume name. */
+ /* SYS$GETDVI will append the volume name to this */
+ strcpy(diskvolnam,"DISK$");
+
+ nextslash = strchr(&filespec[1], '/');
+ if (nextslash != NULL) {
+ length = nextslash - filespec - 1;
+
+ /* DECC requires a cast here */
+ devname_dsc.dsc$a_pointer = (char *)&filespec[1];
+ devname_dsc.dsc$w_length = length;
+ devname_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ devname_dsc.dsc$b_class = DSC$K_CLASS_S;
+
+ status = SYS$GETDVIW(
+ EFN$C_ENF,
+ 0,
+ &devname_dsc,
+ itemlist,
+ dvi_iosb,
+ NULL, 0, 0);
+ if (!$VMS_STATUS_SUCCESS(status)) {
+ /* If the sys$getdviw fails, then this path
+ * was passed by an exec() program and not
+ * from DCL, so do nothing.
+ * An example is "/tmp/program" where tmp:
+ * does not exist
+ */
+ result = 0;
+ } else if (!$VMS_STATUS_SUCCESS(dvi_iosb[0])) {
+ result = 0;
+ } else {
+ char * devnam;
+ int devnam_len;
+ char argv_dev[64];
+
+ /* Null terminate the returned alldevnam */
+ alldevnam[alldevnam_len] = 0;
+ devnam = alldevnam;
+ devnam_len = alldevnam_len;
+
+ /* Need to skip past any leading underscore */
+ if (devnam[0] == '_') {
+ devnam++;
+ devnam_len--;
+ }
+
+ /* And remove the trailing colon */
+ if (devnam[devnam_len - 1] == ':') {
+ devnam_len--;
+ devnam[devnam_len] = 0;
+ }
+
+ /* Null terminate the returned volnam */
+ diskvolnam_len += 5;
+ diskvolnam[diskvolnam_len] = 0;
+
+ /* Check first for normal CRTL behavior */
+ if (devnam_len == length) {
+ strncpy(vms_name, &filespec[1], length);
+ vms_name[length] = 0;
+ result = (strcasecmp(devnam, vms_name) == 0);
+ }
+
+ /* If we have not got a match check for
+ * POSIX Compliant behavior. To be more
+ * accurate, we could also check to see
+ * if that feature is active.
+ */
+ if ((result == 0) &&
+ (diskvolnam_len == length)) {
+ int cmp;
+ strncpy(vms_name, &filespec[1], length);
+ vms_name[length] = 0;
+ cmp = strcasecmp(diskvolnam, vms_name);
+ result = (cmp == 0);
+ }
+ }
+ }
+ } else {
+ /* The path did not start with a slash, so it could be VMS
+ * format. If it is vms format, it has a volume/device in
+ * it as it must be an absolute path
+ */
+ struct dsc$descriptor_s path_desc;
+ int status;
+ unsigned long field_flags;
+ struct filescan_itmlst_2 item_list[5];
+ char * volume;
+ char * name;
+ int name_len;
+ char * ext;
+
+ /* DECC requires a cast here */
+ path_desc.dsc$a_pointer = (char *)filespec;
+ path_desc.dsc$w_length = strlen(filespec);
+ path_desc.dsc$b_dtype = DSC$K_DTYPE_T;
+ path_desc.dsc$b_class = DSC$K_CLASS_S;
+
+ /* Don't actually need to initialize anything buf itmcode */
+ /* I just do not like uninitialized input values */
+
+ /* Sanity check, this must be the same length as input */
+ item_list[0].itmcode = FSCN$_FILESPEC;
+ item_list[0].length = 0;
+ item_list[0].component = NULL;
+
+ /* If the device is present, then it if a VMS spec */
+ item_list[1].itmcode = FSCN$_DEVICE;
+ item_list[1].length = 0;
+ item_list[1].component = NULL;
+
+ /* we need the program name and type */
+ item_list[2].itmcode = FSCN$_NAME;
+ item_list[2].length = 0;
+ item_list[2].component = NULL;
+
+ item_list[3].itmcode = FSCN$_TYPE;
+ item_list[3].length = 0;
+ item_list[3].component = NULL;
+
+ /* End the list */
+ item_list[4].itmcode = 0;
+ item_list[4].length = 0;
+ item_list[4].component = NULL;
+
+ status = SYS$FILESCAN(
+ (const struct dsc$descriptor_s *)&path_desc,
+ item_list, &field_flags, NULL, NULL);
+
+ if ($VMS_STATUS_SUCCESS(status) &&
+ (item_list[0].length == path_desc.dsc$w_length) &&
+ (item_list[1].length != 0)) {
+
+ char * dollar;
+ int keep_ext;
+ int i;
+
+ /* We need the filescan to be successful,
+ * same length as input, and a volume to be present.
+ *
+ * We will assume that we only get to this path on
+ * a version of VMS that does not support the EFS
+ * character set.
+ *
+ * There may be a xxx$ prefix on the image name.
+ * Linux programs do not handle that well, so
+ * strip the prefix.
+ */
+ name = item_list[2].component;
+ name_len = item_list[2].length;
+ dollar = strrchr(name, '$');
+ if (dollar != NULL) {
+ dollar++;
+ name_len = name_len - (dollar - name);
+ name = dollar;
+ }
+
+ strncpy(vms_name, name, name_len);
+ vms_name[name_len] = 0;
+ result = 1;
+
+ /* We only keep the extension if it is not ".exe" */
+ keep_ext = 0;
+ ext = item_list[3].component;
+
+ if (item_list[3].length != 1) {
+ if (item_list[3].length != 4) {
+ keep_ext = 1;
+ } else {
+ int x;
+ x = strncmp(ext, ".exe", 4);
+ if (x != 0) {
+ keep_ext = 1;
+ }
+ }
+ }
+
+ if (keep_ext == 1) {
+ strncpy(&vms_name[name_len],
+ ext, item_list[3].length);
+ }
+ }
+ }
+
+ if (result) {
+ char * lastslash;
+ char * dollar;
+ char * dotexe;
+ char * lastdot;
+ char * extension;
+
+ /* This means it is probably the name from a DCL command
+ * Find the last slash which separates the file from the
+ * path.
+ */
+ lastslash = strrchr(filespec, '/');
+
+ if (lastslash != NULL) {
+ int i;
+
+ lastslash++;
+
+ /* There may be a xxx$ prefix on the image name. */
+ /* Linux programs do not handle that well, so */
+ /* strip the prefix */
+ dollar = strrchr(lastslash, '$');
+
+ if (dollar != NULL) {
+ dollar++;
+ lastslash = dollar;
+ }
+
+ strcpy(vms_name, lastslash);
+
+ /* In UNIX mode + EFS character set, there should
+ * not be a version present, as it is not possible
+ * when parsing to tell if it is a version or part
+ * of the UNIX filename as UNIX programs use numeric
+ * extensions for many reasons.
+ */
+
+ lastdot = strrchr(vms_name, '.');
+ if (lastdot != NULL) {
+ int i;
+
+ i = 1;
+ while (isdigit(lastdot[i])) {
+ i++;
+ }
+ if (lastdot[i] == 0) {
+ *lastdot = 0;
+ }
+ }
+
+ /* Find the .exe on the name (case insenstive)
+ * and toss it
+ */
+ dotexe = strrchr(vms_name, '.');
+ if (dotexe != NULL) {
+ if ((dotexe[1] == 'e' || dotexe[1] == 'E') &&
+ (dotexe[2] == 'x' || dotexe[2] == 'X') &&
+ (dotexe[3] == 'e' || dotexe[3] == 'E') &&
+ (dotexe[4] == 0)) {
+
+ *dotexe = 0;
+ } else {
+ /* Also need to handle a null
+ * extension because of a CRTL bug.
+ */
+ if (dotexe[1] == 0) {
+ *dotexe = 0;
+ }
+ }
+ }
+ }
+ } else {
+ /* No changes needed */
+ strncpy(vms_name, filespec, VMS_NAME_LEN);
+ vms_name[VMS_NAME_LEN] = 0;
+ }
- 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;
+ /*
+ * The above fixes up the name, but for the DCL shell
+ * may leave it in upper case, which messes up the self tests.
+ * force it to lower case here.
+ */
+ shell = getenv("SHELL");
+ if (shell != NULL) {
+ if (strcmp(shell, "DCL") == 0) {
+ lcname = 1;
+ }
+ } else {
+ lcname = 1;
+ }
+ if (lcname == 1) {
+ int i = 0;
+ while (vms_name[i] != 0) {
+ vms_name[i] = tolower(vms_name[i]);
+ i++;
+ }
+ }
+ return vms_name;
}
/* os_arg_fixup --- fixup the command line */
@@ -55,7 +468,24 @@ os_arg_fixup(argcp, argvp)
int *argcp;
char ***argvp;
{
+ char *tz_rule;
+ int status;
+
(void) vms_arg_fixup(argcp, argvp);
+
+ /* Fix up the time zone */
+ /* For some reason it gets trashed */
+ tz_rule = malloc(1024);
+ status = sys_trnlnm("TZ", tz_rule, 1024);
+ if ($VMS_STATUS_SUCCESS(status)) {
+ setenv("TZ", tz_rule, 1);
+ } else {
+ status = sys_trnlnm("SYS$TIMEZONE_RULE", tz_rule, 1024);
+ if ($VMS_STATUS_SUCCESS(status)) {
+ setenv("TZ", tz_rule, 1);
+ }
+ }
+ free(tz_rule);
}
/* os_devopen --- open special per-OS devices */
@@ -143,6 +573,31 @@ int fd;
return (fstat(fd, &sbuf) == 0 && S_ISDIR(sbuf.st_mode));
}
+/* os_isreadable --- fd can be read from */
+
+int
+os_isreadable(const awk_input_buf_t *iobuf, bool *isdir)
+{
+ *isdir = false;
+
+ switch (iobuf->sbuf.st_mode & S_IFMT) {
+ case S_IFREG:
+ case S_IFCHR: /* ttys, /dev/null, .. */
+#ifdef S_IFSOCK
+ case S_IFSOCK:
+#endif
+#ifdef S_IFIFO
+ case S_IFIFO:
+#endif
+ return true;
+ case S_IFDIR:
+ *isdir = true;
+ /* fall through */
+ default:
+ return false;
+ }
+}
+
/* os_is_setuid --- true if running setuid root */
int
@@ -182,11 +637,17 @@ files_are_same(char *newfile, SRCFILE *oldfile)
f2 = &oldfile->sbuf;
/* compare device string */
+#ifdef _USE_STD_STAT
+ return (f1->st_dev == f2->st_dev
+ /* and 48-bit file id cookie */
+ && f1->st_ino == f2->st_ino);
+ #else
return (strcmp(f1->st_dev, f2->st_dev) == 0
/* and 48-bit file id cookie stored in 3 short ints */
&& f1->st_ino[0] == f2->st_ino[0]
&& f1->st_ino[1] == f2->st_ino[1]
&& f1->st_ino[2] == f2->st_ino[2]);
+#endif
}
int
@@ -194,3 +655,8 @@ os_isatty(int fd)
{
return (isatty(fd) > 0);
}
+
+void
+init_sockets(void)
+{
+}
diff --git a/vms/generate_config_vms_h_gawk.com b/vms/generate_config_vms_h_gawk.com
new file mode 100644
index 00000000..12d3d6cf
--- /dev/null
+++ b/vms/generate_config_vms_h_gawk.com
@@ -0,0 +1,298 @@
+$! File: GENERATE_CONFIG_H_VMS_GAWK.COM
+$!
+$! Gawk like most open source products uses a variant of a config.h file.
+$! Depending on the curl version, this could be config.h or curl_config.h.
+$!
+$! For GNV based builds, the configure script is run and that produces
+$! a [curl_]config.h file. Configure scripts on VMS generally do not
+$! know how to do everything, so there is also a [-.lib]config-vms.h file
+$! that has VMS specific code that compensates for bugs in some of the
+$! VMS shared images.
+$!
+$! This generates a []config.h file and also a config_vms.h file,
+$! which is used to supplement that file.
+$!
+$!
+$! Copyright (C) 2014 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 3 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
+$!
+$! Per assignment agreement with FSF, similar procedures may be present
+$! in other packages under other licensing agreements and copyrights
+$!
+$!
+$! 21-Jan-2014 J. Malmberg
+$!
+$!=========================================================================
+$!
+$! Allow arguments to be grouped together with comma or separated by spaces
+$! Do no know if we will need more than 8.
+$ args = "," + p1 + "," + p2 + "," + p3 + "," + p4 + ","
+$ args = args + p5 + "," + p6 + "," + p7 + "," + p8 + ","
+$!
+$! Provide lower case version to simplify parsing.
+$ args_lower = f$edit(args, "LOWERCASE")
+$!
+$ args_len = f$length(args)
+$!
+$ if (f$getsyi("HW_MODEL") .lt. 1024)
+$ then
+$ arch_name = "VAX"
+$ else
+$ arch_name = ""
+$ arch_name = arch_name + f$edit(f$getsyi("ARCH_NAME"), "UPCASE")
+$ if (arch_name .eqs. "") then arch_name = "UNK"
+$ endif
+$!
+$!
+$! Start the configuration file.
+$! Need to do a create and then an append to make the file have the
+$! typical file attributes of a VMS text file.
+$ create sys$disk:[]config_vms.h
+$ open/append cvh sys$disk:[]config_vms.h
+$!
+$! Write the defines to prevent multiple includes.
+$! These are probably not needed in this case,
+$! but are best practice to put on all header files.
+$ write cvh "#ifndef __CONFIG_VMS_H__"
+$ write cvh "#define __CONFIG_VMS_H__"
+$ write cvh ""
+$!
+$ write cvh "#if __CRTL_VER >= 70000000"
+$ write cvh "#define VMS_V7"
+$ write cvh "#else"
+$ write cvh "#define HAVE_TZNAME 1 /* (faked in vms/vms_misc.c) */
+$ write cvh "#define HAVE_TZSET 1 /* (faked in vms/vms_misc.c) */
+$ write cvh "#endif"
+$ write cvh "#if __CRTL_VER >= 70200000"
+$ write cvh "#define DYNAMIC 1"
+$ write cvh "#endif"
+$ write cvh ""
+$ write cvh "#define PRINTF_HAS_F_FORMAT 1"
+$ write cvh ""
+$ write cvh "/* The _Noreturn keyword of C11. */"
+$ write cvh "#ifndef _Noreturn"
+$ write cvh "# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \"
+$ write cvh " || 0x5110 <= __SUNPRO_C)"
+$ write cvh "# define _Noreturn __attribute__ ((__noreturn__))"
+$ write cvh "# elif defined _MSC_VER && 1200 <= _MSC_VER"
+$ write cvh "# define _Noreturn __declspec (noreturn)"
+$ write cvh "# else"
+$ write cvh "# define _Noreturn"
+$ write cvh "# endif"
+$ write cvh "#endif"
+$ write cvh ""
+$ write cvh "/*"
+$ write cvh " * VAXCRTL is pre-ANSI and does some variations of numeric"
+$ write cvh " * formatting differently than gawk expects."
+$ write cvh " */"
+$ write cvh "#if defined(VAX) && !defined(__DECC)"
+$ write cvh -
+ "/* '0' format modifier for %e,%f,%g gives wrong results in many cases */"
+$ write cvh "#define VAXCRTL"
+$ write cvh "/* %g format chooses %e format when should use %f */"
+$ write cvh "#define GFMT_WORKAROUND 1"
+$ write cvh "#endif"
+$ write cvh ""
+$ write cvh "/*"
+$ write cvh " * VAX C"
+$ write cvh " *"
+$ write cvh -
+ " * As of V3.2, VAX C is not yet ANSI-compliant. But it's close enough"
+$ write cvh -
+ " * for GAWK's purposes. Comment this out for VAX C V2.4 and earlier."
+$ write cvh -
+ " * YYDEBUG definition is needed for combination of VAX C V2.x and Bison."
+$ write cvh " */"
+$ write cvh "#if defined(VAXC) && !defined(__STDC__)"
+$ write cvh "#define __STDC__ 0"
+$ write cvh "#define NO_TOKEN_PASTING"
+$ write cvh "#define signed /*empty*/"
+$ write cvh "#define inline /*empty*/"
+$ write cvh "#ifndef __DECC /* DEC C does not support #pragma builtins */"
+$ write cvh "#define VAXC_BUILTINS"
+$ write cvh "#endif"
+$ write cvh "/* #define YYDEBUG 0 */"
+$ write cvh -
+ "#define NO_MBSUPPORT /* VAX C's preprocessor can't handle mbsupport.h */"
+$ write cvh "#endif"
+$ write cvh ""
+$ write cvh ""
+$ write cvh "#if __DECC_VER >= 60400000 && !defined(DEBUG)"
+$ write cvh "/* disable ""new feature in C99"" diagnostics (for regex code); "
+$ write cvh " NEWC99 ought to suffice but doesn't (at least in V6.4) */"
+$ write cvh "#pragma message disable (NEWC99,DESIGNATORUSE)"
+$ write cvh "#ifdef __VAX
+$ write cvh "#endif
+$ write cvh "#pragma message disable (LONGDOUBLENYI)"
+$ write cvh "#endif"
+$!
+$! This stuff seems needed for VMS 7.3 and earlier, but not VMS 8.2+
+$! Need some more data as to which versions these issues are fixed in.
+$ write cvh "#if __VMS_VER <= 80200000"
+$! mkstemp goes into an infinte loop in gawk in VAX/VMS 7.3
+$ write cvh "#ifdef HAVE_MKSTEMP"
+$ write cvh "#undef HAVE_MKSTEMP"
+$ write cvh "#endif"
+$ write cvh "#endif"
+$ write cvh ""
+$!
+$! VMS not legal for ANSI compiler to pre-define
+$ write cvh "#ifndef VMS"
+$ write cvh "#define VMS 1"
+$ write cvh "#endif"
+$ write cvh ""
+$!
+$! Need to temp hide stuff that gawk is replacing or redefining before
+$! including the header.
+$ write cvh "/* Need to hide some stuff */"
+$ write cvh "#define getopt hide_getopt"
+$ write cvh "#define optopt hide_optopt"
+$ write cvh "#define optind hide_optind"
+$ write cvh "#define optarg hide_optarg"
+$ write cvh "#define opterr hide_opterr"
+$ write cvh "#define getpgrp hide_getpgrp"
+$ write cvh "#define unsetenv hide_unsetenv"
+$ write cvh "#define read hide_read"
+$ write cvh "#define delete hide_delete"
+$ write cvh "#define getcwd hide_getcwd"
+$ write cvh "#define getgid hide_getgid"
+$ write cvh "#define getegid hide_getegid"
+$ write cvh "#define setgid hide_setgid"
+$ write cvh "#define exit hide_exit"
+$ write cvh "#define _exit hide__exit"
+$ write cvh "#include <unistd.h>"
+$ write cvh "#include <stdlib.h>"
+$ write cvh "#include <stdio.h>"
+$ write cvh "#include <time.h>"
+$ write cvh "#include <stsdef.h>"
+$ write cvh "#include <string.h>"
+$ write cvh "#undef getopt"
+$ write cvh "#undef optopt"
+$ write cvh "#undef optind"
+$ write cvh "#undef optarg"
+$ write cvh "#undef opterr"
+$ write cvh "#undef getpgrp"
+$ write cvh "#undef getcwd"
+$ write cvh "#undef unsetenv"
+$ write cvh "#undef read"
+$ write cvh "#undef delete"
+$ write cvh "#undef getgid"
+$ write cvh "#undef getegid"
+$ write cvh "#undef setgid"
+$ write cvh "#undef exit"
+$ write cvh "#undef _exit"
+$!
+$write cvh "#ifdef HAVE_STRNCASECMP"
+$write cvh "#undef HAVE_STRNCASECMP"
+$write cvh "#endif"
+$!
+$ write cvh "#define IN_CONFIG_H"
+$ write cvh "#include ""redirect.h"""
+$ write cvh "#undef IN_CONFIG_H"
+$ write cvh "#define getpgrp gawk_vms_getpgrp"
+$ write cvh "#ifdef HAVE_SETENV"
+$ write cvh "#undef HAVE_SETENV"
+$ write cvh "#endif"
+$ write cvh "#ifdef HAVE_UNSETENV"
+$ write cvh "#undef HAVE_UNSETENV"
+$ write cvh "#endif"
+$ write cvh "#ifdef HAVE_STRFTIME"
+$ write cvh "#undef HAVE_STRFTIME"
+$ write cvh "#define USE_INCLUDED_STRFTIME"
+$ write cvh "#endif /* HAVE_STRFTIME */"
+$ write cvh ""
+$ write cvh "#include <bitypes.h>"
+$ write cvh "#define INT32_MAX __INT32_MAX"
+$ write cvh "#define INT32_MIN __INT32_MIN"
+$ write cvh ""
+$ write cvh "/*"
+$ write cvh " * DEFPATH"
+$ write cvh " * VMS: ""/AWK_LIBRARY"" => ""AWK_LIBRARY:"""
+$ write cvh " * The default search path for the -f option of gawk. It is"
+$ write cvh " * used if the AWKPATH environment variable is undefined."
+$ write cvh " *"
+$ write cvh " * Note: OK even if no AWK_LIBRARY logical name has been defined."
+$ write cvh " */"
+$ write cvh ""
+$ write cvh "#define DEFPATH "".,/AWK_LIBRARY"""
+$ write cvh "#define DEFLIBPATH "".,/AWK_LIBRARY"""
+$ write cvh "#define ENVSEP ','"
+$ write cvh ""
+$ write cvh "/*"
+$ write cvh " * Extended source file access."
+$ write cvh " */"
+$ write cvh "#define DEFAULT_FILETYPE "".awk"""
+$ write cvh ""
+$ write cvh "/*"
+$ write cvh " * fork/Pipe handling."
+$ write cvh " */"
+$ write cvh "#define PIPES_SIMULATED 1"
+$ write cvh ""
+$ write cvh "/* Extension for shared libraries */"
+$ write cvh "#define SHLIBEXT ""exe"""
+$ write cvh ""
+$! GAWK does not want to use ALLOCA
+$ write cvh "#define NO_ALLOCA"
+$ write cvh "#define STACK_DIRECTION (-1)"
+$ write cvh ""
+$ write cvh "void decc$exit(int status);"
+$ write cvh "#define _exit(foo) vms_exit(foo)"
+$ write cvh "#define exit(foo) vms_exit(foo)"
+$ write cvh ""
+$ write cvh "/* Use POSIX exit codes here */"
+$ write cvh "#ifdef EXIT_FAILURE"
+$ write cvh "#undef EXIT_FAILURE"
+$ write cvh "#endif"
+$ write cvh "#define EXIT_FAILURE (1)"
+$ write cvh ""
+$ write cvh "#define EXIT_FATAL (2)"
+$ write cvh ""
+$ write cvh "#ifndef C_FACILITY_NO"
+$ write cvh "#define C_FACILITY_NO 0x350000"
+$ write cvh "#endif"
+$ write cvh ""
+$ write cvh "/* Build a Posix Exit with VMS severity */
+$ write cvh "static void vms_exit(int status) {"
+$ write cvh " int vms_status;"
+$ write cvh " /* Fake the __posix_exit with severity added */"
+$ write cvh " /* Undocumented correct way to do this. */"
+$ write cvh " vms_status = 0;"
+$ write cvh " if (status != 0) {"
+$ write cvh " vms_status = C_FACILITY_NO | 0xA000 | STS$M_INHIB_MSG;"
+$ write cvh " vms_status |= (status << 3);"
+$ write cvh " }"
+$ write cvh " if (status == EXIT_FAILURE) {"
+$ write cvh " vms_status |= STS$K_ERROR;"
+$ write cvh " } else if (status == EXIT_FATAL) {"
+$ write cvh " vms_status |= STS$K_SEVERE;"
+$ write cvh " } else {"
+$ write cvh " vms_status |= STS$K_SUCCESS;"
+$ write cvh " }"
+$ write cvh " decc$exit(vms_status);"
+$ write cvh "}"
+$!
+$! Close out the file
+$!
+$ write cvh ""
+$ write cvh "#endif /* __CONFIG_VMS_H__ */"
+$ close cvh
+$!
+$all_exit:
+$ exit
diff --git a/vms/gnv_gawk_startup.com b/vms/gnv_gawk_startup.com
new file mode 100644
index 00000000..e691965e
--- /dev/null
+++ b/vms/gnv_gawk_startup.com
@@ -0,0 +1,75 @@
+$! File: gnv$gawk_Startup.com / gnv_gawk_startup.com
+$!
+$! Procedure to setup the GAWK images for use by programs from the
+$! VMS SYSTARTUP*.COM procedure.
+$!
+$! 14-Mar-2011 J. Malmberg
+$! 04-May-2011 J. Malmberg Use GNV_PCSI_DESTINATION to find the
+$! value to assing GNV$GNU per suggestion
+$! by Martin Vorlander.
+$! 02-Jan-2014 J. Malmberg Gawk Version
+$!========================================================================
+$!
+$!
+$! GNV$GNU if needed.
+$ if f$trnlnm("GNV$GNU") .eqs. ""
+$ then
+$ x = f$trnlnm("GNU","LNM$SYSTEM_TABLE")
+$ if x .nes. ""
+$ then
+$ write sys$output -
+ "Notice: logical name GNU: was found in the system table instead of GNV$GNU:"
+$ write sys$output -
+ "This is a known bug in the GNV 2.1.3 and earlier kits."
+$ define/system/exec/trans=conc GNV$GNU 'x'
+$ else
+$!
+$! File name per VMS standards
+$! ---------------------------
+$ file1 = "sys$startup:gnv$destination_''f$getsyi("ARCH_NAME")'.com"
+$!
+$! File name in GNV 2.1.3
+$! ----------------------
+$ file2 = "sys$startup:gnv_destination_''f$getsyi("ARCH_NAME")'.com"
+$!
+$! File name before GNV 2.1.3
+$! ---------------------------
+$ file3 = "sys$startup:gnv_destination''f$getsyi("ARCH_NAME")'.com"
+$ arch_file = ""
+$ if f$search(file1) .nes. ""
+$ then
+$ arch_file = file1
+$ else
+$ if f$search(file2) .nes. ""
+$ then
+$ arch_file = file2
+$ else
+$ if f$search("file3") .nes. "" then arch_file = file3
+$ endif
+$ endif
+$ if (arch_file) .nes. "" then @'arch_file'
+$!
+$! Logical name per VMS standards
+$! -------------------------------
+$ destination = f$trnlnm("GNV$PCSI_DESTINATION")
+$!
+$! Logical name in GNV 2.1.3
+$! --------------------------
+$ if destination .eqs. ""
+$ then
+$ destination = f$trnlnm("GNV_PCSI_DESTINATION")
+$ endif
+$ if destination .eqs. ""
+$ then
+$ !Assume this procedure is on the same volume as the GNV install.
+$ my_proc = f$environment("PROCEDURE")
+$ my_dev = f$parse(my_proc,,,"DEVICE","NO_CONCEAL")
+$ destination = "''my_dev'[vms$common.gnv.]"
+$ endif
+$ define/system/exec/trans=conc gnv$gnu 'destination'
+$ endif
+$ endif
+$!
+$!
+$all_exit:
+$ exit
diff --git a/vms/make_pcsi_gawk_kit_name.com b/vms/make_pcsi_gawk_kit_name.com
new file mode 100644
index 00000000..daaa37a4
--- /dev/null
+++ b/vms/make_pcsi_gawk_kit_name.com
@@ -0,0 +1,189 @@
+$! File: MAKE_PCSI_GAWK_KIT_NAME.COM
+$!
+$! Calculates the PCSI kit name for use in building an installation kit.
+$! PCSI is HP's PolyCenter Software Installation Utility.
+$!
+$! The results are stored in as logical names so that other procedures
+$! can use them.
+$!
+$! 92-Jan-2014 J. Malmberg Gawk version
+$!========================================================================
+$!
+$! Save default
+$default_dir = f$environment("DEFAULT")
+$!
+$! Put things back on error.
+$on warning then goto all_exit
+$!
+$! The producer is the name or common abbreviation for the entity that is
+$! making the kit. It must be set as a logical name before running this
+$! procedure.
+$!
+$! HP documents the producer as the legal owner of the software, but for
+$! open source work, it should document who is creating the package for
+$! distribution.
+$!
+$producer = f$trnlnm("GNV_PCSI_PRODUCER")
+$if producer .eqs. ""
+$then
+$ write sys$output "The logical name GNV_PCSI_PRODUCER needs to be defined."
+$ write sys$output "This should be set to the common abbreviation or name of"
+$ write sys$output "the entity creating this kit. If you are an individual"
+$ write sys$output "then use your initials as long as they do not match"
+$ write sys$output "a different well known producer prefix."
+$ goto all_exit
+$endif
+$producer_full_name = f$trnlnm("GNV_PCSI_PRODUCER_FULL_NAME")
+$if producer_full_name .eqs. ""
+$then
+$ write sys$output "The logical name GNV_PCSI_PRODUCER_FULL_NAME needs to"
+$ write sys$output "be defined. This should be set to the full name of"
+$ write sys$output "the entity creating this kit. If you are an individual"
+$ write sys$output "then use your name."
+$ write sys$output "EX: DEFINE GNV_PCSI_PRODUCER_FULL_NAME ""First M. Last"""
+$ goto all_exit
+$endif
+$!
+$write sys$output "*****"
+$write sys$output "***** Producer = ''producer'"
+$write sys$output "*****"
+$!
+$!
+$! Base is one of 'VMS', 'AXPVMS', 'I64VMS', 'VAXVMS' and indicates what
+$! binaries are in the kit. A kit with just 'VMS' can be installed on all
+$! architectures.
+$!
+$base = "VMS"
+$arch_type = f$getsyi("ARCH_NAME")
+$code = f$extract(0, 1, arch_type)
+$if (code .eqs. "I") then base = "I64VMS"
+$if (code .eqs. "V") then base = "VAXVMS"
+$if (code .eqs. "A") then base = "AXPVMS"
+$!
+$!
+$product = "gawk"
+$!
+$!
+$! We need to get the version from config.h. It will have a lines like
+$! #define PACKAGE_VERSION "4.1.0a"
+$!
+$!
+$open/read/error=version_loop_end verf config.h
+$version_loop:
+$ read/end=version_loop_end verf line_in
+$ if line_in .eqs. "" then goto version_loop
+$ if f$locate("#define PACKAGE_VERSION", line_in) .ne. 0
+$ then
+$ goto version_loop
+$ endif
+$ tag = f$element(1, " ", line_in)
+$ value = f$element(2, " ", line_in) - """" - """"
+$ if tag .eqs. "PACKAGE_VERSION"
+$ then
+$ distversion = value
+$ goto version_loop_end
+$ endif
+$ goto version_loop
+$version_loop_end:
+$close verf
+$!
+$!
+$! Optional ECO file.
+$ECO_LEVEL = ""
+$vms_eco_file = "[.vms]vms_eco_level.h"
+$if f$search(vms_eco_file) .nes. ""
+$then
+$ open/read ef 'vms_eco_file'
+$ecolevel_loop:
+$ read/end=ecolevel_loop_end ef line_in
+$ prefix = f$element(0, " ", line_in)
+$ if prefix .nes. "#define" then goto ecolevel_loop
+$ key = f$element(1, " ", line_in)
+$ value = f$element(2, " ", line_in) - """" - """"
+$ if key .eqs. "VMS_ECO_LEVEL"
+$ then
+$ ECO_LEVEL = value
+$ if ECO_LEVEL .eq. 0
+$ then
+$ ECO_LEVEL = ""
+$ else
+$ ECO_LEVEL = "E" + ECO_LEVEL
+$ endif
+$ goto ecolevel_loop_end
+$ endif
+$ goto ecolevel_loop
+$ecolevel_loop_end:
+$ close ef
+$endif
+$!
+$raw_version = distversion
+$!
+$!
+$! This translates to V0114-08 or D0115-01
+$! We can not encode the snapshot date into the version due to the way that
+$! the Polycenter Software Installation Utility evaluates the name.
+$!
+$! version_type = 'V' for a production release, and 'D' for a build from a
+$! daily repository snapshot, and a code for a build from a pre-release branch
+$majorver = f$element(0, ".", raw_version)
+$minorver = f$element(1, ".", raw_version)
+$update = f$element(2,".", raw_version)
+$if update .eqs. "." then update = ""
+$vtype = "V"
+$if update .nes. ""
+$then
+$ update_len = f$length(update)
+$ code = f$extract(update_len - 1, 1, update)
+$ code = f$edit(code, "UPCASE")
+$ if (code .ges. "A") .and. (code .les. "Z")
+$ then
+$ update = f$extract(0, update_len - 1, update)
+$ vtype = code
+$ endif
+$endif
+$if update .eqs. "0" then update = ""
+$!
+$!
+$version_fao = "!2ZB!2ZB"
+$mmversion = f$fao(version_fao, 'majorver', 'minorver')
+$version = vtype + "''mmversion'"
+$if update .nes. "" .or. ECO_LEVEL .nes. ""
+$then
+$! The presence of an ECO implies an update
+$ if update .eqs. "" .and. ECO_LEVEL .nes. "" then update = "0"
+$ version = version + "-" + update + ECO_LEVEL
+$ fversion = version
+$else
+$ fversion = version
+$ version = version + "-"
+$endif
+$!
+$! Kit type 1 is complete kit, the only type that this procedure will make.
+$Kittype = 1
+$!
+$! Write out a logical name for the resulting base kit name.
+$name = "''producer'-''base'-''product'-''version'-''kittype'"
+$define GNV_PCSI_KITNAME "''name'"
+$fname = "''product'-''fversion'"
+$!
+$! No ECO or Patch level
+$fname_len = f$length(fname)
+$if f$extract(fname_len - 1, 1, fname) .eqs. "-"
+$then
+$ fname = f$extract(0, fname_len - 1, fname)
+$ fname_len = fname_len - 1
+$endif
+$if f$extract(fname_len - 1, 1, fname) .eqs. "-"
+$then
+$ fname = f$extract(0, fname_len - 1, fname)
+$ fname_len = fname_len - 1
+$endif
+$define GNV_PCSI_FILENAME_BASE 'fname'
+$write sys$output "*****"
+$write sys$output "***** GNV_PCSI_KITNAME = ''name'."
+$write sys$output "***** GNV_PCSI_FILENAME_BASE = ''fname'."
+$write sys$output "*****"
+$!
+$all_exit:
+$set def 'default_dir'
+$exit '$status'
diff --git a/vms/pcsi_gawk_file_list.txt b/vms/pcsi_gawk_file_list.txt
new file mode 100644
index 00000000..67d2d324
--- /dev/null
+++ b/vms/pcsi_gawk_file_list.txt
@@ -0,0 +1,120 @@
+! File: pcsi_gawk_file_list.txt
+!
+! File list for building a PCSI kit.
+! Very simple format so that the parsing logic can be simple.
+! links first, directory second, and files third.
+!
+! link -> file tells procedure to create/remove a link on install/uninstall
+! If more than one link, consider using an alias file.
+!
+! [xxx.yyy]foo.dir is a directory file for the rename phase.
+! [xxx.yyy.foo] is a directory file for the create phase.
+! Each subdirectory needs to be on its own pair of lines.
+!
+! [xxx.yyy]file.ext is a file for the rename and add phases.
+!
+! 14-Mar-2011 J. Malmberg
+! 08-Dec-2013 J. Malmberg This list is based on what was found on
+! some Linux systems and what can be currently
+! built on VMS.
+!
+!============================================================================
+![gnv.bin]awk. -> [gnv.bin]gnv$gawk.exe
+![gnv.bin]awk.exe -> [gnv.bin]gnv$gawk.exe
+![gnv.bin]gawk. -> [gnv.bin]gnv$gawk.exe
+![gnv.bin]gawk.exe -> [gnv.bin]gnv$gawk.exe
+![gnv.usr.bin]awk. -> [gnv.bin]gnv$gawk.exe
+![gnv.usr.bin]awk.exe -> [gnv.bin]gnv$gawk.exe
+![gnv.usr.bin]gawk. -> [gnv.bin]gnv$gawk.exe
+![gnv.usr.bin]gawk.exe -> [gnv.bin]gnv$gawk.exe
+![gnv.usr.share.man.man1]awk.1 -> [gnv.usr.share.man.man1]gawk.1
+[gnv]
+[000000]gnv.dir
+[gnv.bin]
+[gnv]bin.dir
+[gnv.vms_bin]
+[gnv]vms_bin.dir
+[gnv.vms_help]
+[gnv]vms_help.dir
+[gnv.lib]
+[gnv]lib.dir
+[gnv.usr]
+[gnv]usr.dir
+[gnv.usr.bin]
+[gnv.usr]bin.dir
+[gnv.usr.include]
+[gnv.usr]include.dir
+[gnv.usr.lib]
+[gnv.usr]lib.dir
+[gnv.usr.lib.gawk]
+[gnv.usr.lib]gawk.dir
+[gnv.usr.share]
+[gnv.usr]share.dir
+[gnv.usr.share.awk]
+[gnv.usr.share]awk.dir
+[gnv.usr.share.doc]
+[gnv.usr.share]doc.dir
+[gnv.usr.share.doc.gawk]
+[gnv.usr.share.doc]gawk.dir
+[gnv.usr.share.info]
+[gnv.usr.share]info.dir
+[gnv.usr.share.man]
+[gnv.usr.share]man.dir
+[gnv.usr.share.man.man1]
+[gnv.usr.share.man]man1.dir
+![gnv.usr.share.man.man7]
+![gnv.usr.share.man]man7.dir
+[gnv.usr]src.dir
+[gnv.usr.src]
+[gnv.usr.src]gawk.dir
+[gnv.usr.src.gawk]extension.dir
+[gnv.usr.src.gawk.extension]
+[gnv.usr.src.gawk.extension]vms.dir
+[gnv.usr.src.gawk.extension.vms]
+[gnv.bin]gnv$gawk.exe
+[gnv.bin]igawk.
+[gnv.vms_bin]remove_old_gawk.com
+[gnv.vms_bin]gawk_alias_setup.com
+[gnv.vms_bin]gawk_verb.cld
+[gnv.vms_help]gawk.hlp
+[gnv.usr.include]gawkapi.h
+[gnv.usr.lib.gawk]filefuncs.exe
+[gnv.usr.lib.gawk]fnmatch.exe
+[gnv.usr.lib.gawk]inplace.exe
+[gnv.usr.lib.gawk]ordchr.exe
+[gnv.usr.lib.gawk]readdir.exe
+[gnv.usr.lib.gawk]revoutput.exe
+[gnv.usr.lib.gawk]revtwoway.exe
+[gnv.usr.lib.gawk]rwarray.exe
+[gnv.usr.lib.gawk]time.exe
+[gnv.usr.share.awk]assert.awk
+[gnv.usr.share.awk]bits2str.awk
+[gnv.usr.share.awk]cliff_rand.awk
+[gnv.usr.share.awk]ctime.awk
+[gnv.usr.share.awk]ftrans.awk
+[gnv.usr.share.awk]getopt.awk
+[gnv.usr.share.awk]gettime.awk
+[gnv.usr.share.awk]join.awk
+[gnv.usr.share.awk]libintl.awk
+[gnv.usr.share.awk]noassign.awk
+[gnv.usr.share.awk]ord.awk
+[gnv.usr.share.awk]readable.awk
+[gnv.usr.share.awk]readfile.awk
+[gnv.usr.share.awk]rewind.awk
+[gnv.usr.share.awk]round.awk
+[gnv.usr.share.awk]strtonum.awk
+[gnv.usr.share.awk]walkarray.awk
+[gnv.usr.share.awk]zerofile.awk
+[gnv.usr.share.doc.gawk]COPYING.
+[gnv.usr.share.doc.gawk]NEWS.
+[gnv.usr.share.doc.gawk]POSIX.STD
+[gnv.usr.share.doc.gawk]README.
+[gnv.usr.share.doc.gawk]README.vms
+[gnv.usr.share.doc.gawk]README.multibyte
+[gnv.usr.share.doc.gawk]README.tests
+[gnv.usr.share.info]gawk.info
+[gnv.usr.share.info]gawkinet.info
+[gnv.usr.share.man.man1]gawk.1
+[gnv.usr.share.man.man1]igawk.1
+![gnv.usr.share.man.man7]
+[gnv.usr.src.gawk.extension.vms]gawk_plugin.opt
diff --git a/vms/pcsi_product_gawk.com b/vms/pcsi_product_gawk.com
new file mode 100644
index 00000000..b0d9febd
--- /dev/null
+++ b/vms/pcsi_product_gawk.com
@@ -0,0 +1,187 @@
+$! File: pcsi_product_gawk.com
+$!
+$! This command file packages up the product GAWK into a sequential
+$! format kit
+$!
+$! 13-Dec-2013 J.Malmberg
+$!
+$!=========================================================================
+$!
+$! Save default
+$ default_dir = f$environment("DEFAULT")
+$!
+$! Put things back on error.
+$ on warning then goto all_exit
+$!
+$ arch_type = f$getsyi("ARCH_NAME")
+$ arch_code = f$extract(0, 1, arch_type)
+$!
+$ can_build = 1
+$ producer = f$trnlnm("GNV_PCSI_PRODUCER")
+$ if producer .eqs. ""
+$ then
+$ write sys$output "GNV_PCSI_PRODUCER logical name has not been set."
+$ can_build = 0
+$ endif
+$ producer_full_name = f$trnlnm("GNV_PCSI_PRODUCER_FULL_NAME")
+$ if producer_full_name .eqs. ""
+$ then
+$ write sys$output -
+ "GNV_PCSI_PRODUCER_FULL_NAME logical name has not been set."
+$ can_build = 0
+$ endif
+$ stage_root_name = f$trnlnm("STAGE_ROOT")
+$ if stage_root_name .eqs. ""
+$ then
+$ write sys$output "STAGE_ROOT logical name has not been set."
+$ can_build = 0
+$ endif
+$!
+$ if (can_build .eq. 0)
+$ then
+$ write sys$output "Not able to build a kit."
+$ goto all_exit
+$ endif
+$!
+$!
+$! Build the gawk image(s)
+$!-------------------------
+$ if f$search("gawk.exe") .eqs. ""
+$ then
+$ mmk/descrip=[.vms]descrip.mms gawk
+$ endif
+$ if arch_code .nes. "V"
+$ then
+$ if f$search("filefuncs.exe") .eqs. ""
+$ then
+$ mmk/descrip=[.vms]descrip.mms extensions
+$ endif
+$ endif
+$!
+$! Build the gawk_verb.cld
+$!-------------------------
+$ if f$search("gawk_verb.cld") .eqs. ""
+$ then
+$ @[.vms]gawk_verb.com
+$ endif
+$!
+$! Stage the images for building the kit
+$!--------------------------------------
+$ @[.vms]stage_gawk_install.com remove
+$ @[.vms]stage_gawk_install.com
+$!
+$!
+$!
+$! Make sure that the kit name is up to date for this build
+$!----------------------------------------------------------
+$ @[.vms]make_pcsi_gawk_kit_name.com
+$!
+$! Make sure that the release note file name is up to date
+$!---------------------------------------------------------
+$ @[.vms]build_gawk_release_notes.com
+$!
+$!
+$! Make sure that the source has been backed up.
+$!----------------------------------------------
+$ @[.vms]backup_gawk_src.com
+$!
+$! Regenerate the PCSI description file.
+$!--------------------------------------
+$ @[.vms]build_gawk_pcsi_desc.com
+$!
+$! Regenerate the PCSI Text file.
+$!---------------------------------
+$ @[.vms]build_gawk_pcsi_text.com
+$!
+$!
+$! Parse the kit name into components.
+$!---------------------------------------
+$ kit_name = f$trnlnm("GNV_PCSI_KITNAME")
+$ if kit_name .eqs. ""
+$ then
+$ write sys$output "@[.vms]make_pcsi_gawk_kit_name.com has not been run."
+$ goto all_exit
+$ endif
+$ producer = f$element(0, "-", kit_name)
+$ base = f$element(1, "-", kit_name)
+$ product_name = f$element(2, "-", kit_name)
+$ mmversion = f$element(3, "-", kit_name)
+$ majorver = f$extract(0, 3, mmversion)
+$ minorver = f$extract(3, 2, mmversion)
+$ updatepatch = f$element(4, "-", kit_name)
+$ if updatepatch .eqs. "" then updatepatch = ""
+$!
+$ version_fao = "!AS.!AS"
+$ mmversion = f$fao(version_fao, "''majorver'", "''minorver'")
+$ if updatepatch .nes. ""
+$ then
+$ version = "''mmversion'" + "-" + updatepatch
+$ else
+$ version = "''mmversion'"
+$ endif
+$!
+$!
+$! Move to the base directories
+$ current_default = f$environment("DEFAULT")
+$ my_dir = f$parse(current_default,,,"DIRECTORY") - "[" - "<" - ">" - "]"
+$!
+$!
+$ source = "''default_dir'"
+$ src1 = "new_gnu:[bin],"
+$ src2 = "new_gnu:[usr.bin],"
+$ src3 = "new_gnu:[vms_bin],"
+$ src4 = "new_gnu:[vms_help],"
+$ src5 = "new_gnu:[vms_src],"
+$ src6 = "new_gnu:[common_src],"
+$ src7 = "sys$disk:[''my_dir'],sys$disk:[''my_dir'.vms],"
+$ src8 = "new_gnu:[usr.share.awk],"
+$ src9 = "new_gnu:[usr.share.man.man1],"
+$ src10 = "new_gnu:[usr.share.doc.gawk],"
+$ src11 = "new_gnu:[usr.share.info],"
+$ src12 = "sys$disk:[''m_dir'.pc.awklib]"
+$ gnu_src = src1 + src2 + src3 + src4 + src5 + src6 + src7 + src8 + src9
+$ gnu_src = gnu_src + src10 + src11 + src12
+$!
+$!
+$ base = ""
+$ arch_name = f$edit(f$getsyi("arch_name"),"UPCASE")
+$ if arch_name .eqs. "ALPHA" then base = "AXPVMS"
+$ if arch_name .eqs. "IA64" then base = "I64VMS"
+$ if arch_name .eqs. "VAX" then base = "VAXVMS"
+$!
+$ if base .eqs. "" then exit 44
+$!
+$ pcsi_option = "/option=noconfirm"
+$ if arch_code .eqs. "V"
+$ then
+$ pcsi_option = ""
+$ endif
+$!
+$!
+$product package 'product_name' -
+ /base='base' -
+ /producer='producer' -
+ /source='source' -
+ /destination=STAGE_ROOT:[KIT] -
+ /material=('gnu_src','source') -
+ /format=sequential 'pcsi_option'
+$!
+$!
+$! VAX can not do a compressed kit.
+$! ZIP -9 "-V" does a better job, so no reason to normally build a compressed
+$! kit.
+$!----------------------------------
+$if p1 .eqs. "COMPRESSED"
+$then
+$ if arch_code .nes. "V"
+$ then
+$ product copy /options=(novalidate, noconfirm) /format=compressed -
+ 'product_name' -
+ /source=stage_root:[kit]/dest=stage_root:[kit] -
+ /version='version'/base='base'
+$ endif
+$endif
+$!
+$all_exit:
+$ set def 'default_dir'
+$ exit
diff --git a/vms/remove_old_gawk.com b/vms/remove_old_gawk.com
new file mode 100644
index 00000000..ed68fc45
--- /dev/null
+++ b/vms/remove_old_gawk.com
@@ -0,0 +1,113 @@
+$! File: remove_old_gawk.com
+$!
+$! This is a procedure to remove the old gawk images that were installed
+$! by the GNV kits and replace them with links to the new image.
+$!
+$! 02-Jan-2014 J. Malmberg Gawk version
+$!
+$!==========================================================================
+$!
+$vax = f$getsyi("HW_MODEL") .lt. 1024
+$old_parse = ""
+$if .not. VAX
+$then
+$ old_parse = f$getjpi("", "parse_style_perm")
+$ set process/parse=extended
+$endif
+$!
+$old_cutils = "gawk,awk,"
+$!
+$!
+$ i = 0
+$cutils_loop:
+$ file = f$element(i, ",", old_cutils)
+$ if file .eqs. "" then goto cutils_loop_end
+$ if file .eqs. "," then goto cutils_loop_end
+$ call update_old_image 'file'
+$ i = i + 1
+$ goto cutils_loop
+$cutils_loop_end:
+$!
+$!
+$if .not. VAX
+$then
+$ file = "gnv$gnu:[usr.share.man.cat1]awk^.1.gz"
+$ if f$search(file) .nes. "" then delete 'file';*
+$ file = "gnv$gnu:[usr.share.man.cat1]gawk^.1.gz"
+$ if f$search(file) .nes. "" then delete 'file';*
+$ file = "gnv$gnu:[usr.share.man.cat1]iawk^.1.gz"
+$ if f$search(file) .nes. "" then delete 'file';*
+$endif
+$!
+$!
+$if .not. VAX
+$then
+$ set process/parse='old_parse'
+$endif
+$!
+$all_exit:
+$ exit
+$!
+$! Remove old image or update it if needed.
+$!-------------------------------------------
+$update_old_image: subroutine
+$!
+$ file = p1
+$! First get the FID of the new gawk image.
+$! Don't remove anything that matches it.
+$ new_gawk = f$search("GNV$GNU:[BIN]GNV$''file'.EXE")
+$!
+$ new_gawk_fid = "No_new_gawk_fid"
+$ if new_gawk .nes. ""
+$ then
+$ new_gawk_fid = f$file_attributes(new_gawk, "FID")
+$ endif
+$!
+$!
+$!
+$! Now get check the "''file'." and "''file'.exe"
+$! May be links or copies.
+$! Ok to delete and replace.
+$!
+$!
+$ old_gawk_fid = "No_old_gawk_fid"
+$ old_gawk = f$search("gnv$gnu:[bin]''file'.")
+$ old_gawk_exe_fid = "No_old_gawk_fid"
+$ old_gawk_exe = f$search("gnv$gnu:[bin]''file'.exe")
+$ if old_gawk_exe .nes. ""
+$ then
+$ old_gawk_exe_fid = f$file_attributes(old_gawk_exe, "FID")
+$ endif
+$!
+$ if old_gawk .nes. ""
+$ then
+$ fid = f$file_attributes(old_gawk, "FID")
+$ if fid .nes. new_gawk_fid
+$ then
+$ if fid .eqs. old_gawk_exe_fid
+$ then
+$ set file/remove 'old_gawk'
+$ else
+$ delete 'old_gawk'
+$ endif
+$ if new_gawk .nes. ""
+$ then
+$ set file/enter='old_gawk' 'new_gawk'
+$ endif
+$ endif
+$ endif
+$!
+$ if old_gawk_exe .nes. ""
+$ then
+$ if old_gawk_fid .nes. new_gawk_fid
+$ then
+$ delete 'old_gawk_exe'
+$ if new_gawk .nes. ""
+$ then
+$ set file/enter='old_gawk_exe' 'new_gawk'
+$ endif
+$ endif
+$ endif
+$!
+$ exit
+$ENDSUBROUTINE ! Update old image
diff --git a/vms/stage_gawk_install.com b/vms/stage_gawk_install.com
new file mode 100644
index 00000000..22daf7f5
--- /dev/null
+++ b/vms/stage_gawk_install.com
@@ -0,0 +1,300 @@
+$! File: stage_gawk_install.com
+$!
+$! Stages the build products to new_gnu:[...] for testing and for building
+$! a kit.
+$!
+$! If p1 starts with "R" then remove instead of install.
+$!
+$! The file PCSI_GAWK_FILE_LIST.TXT is read in to get the files other
+$! than the release notes file and the source backup file.
+$!
+$! The PCSI system can really only handle ODS-2 format filenames and
+$! assumes that there is only one source directory. It also assumes that
+$! all destination files with the same name come from the same source file.
+$!
+$!
+$! 29-Sep-2013 J. Malmberg
+$!
+$!===========================================================================
+$!
+$ arch_type = f$getsyi("ARCH_NAME")
+$ arch_code = f$extract(0, 1, arch_type)
+$!
+$ mode = "install"
+$ code = f$extract(0, 1, p1)
+$ if code .eqs. "R" .or. code .eqs. "r" then mode = "remove"
+$!
+$! First create the directories
+$!--------------------------------
+$ if mode .eqs. "install"
+$ then
+$ create/dir new_gnu:[bin]/prot=o:rwed
+$ create/dir new_gnu:[vms_bin]/prot=o:rwed
+$ create/dir new_gnu:[vms_help]/prot=o:rwed
+$ create/dir new_gnu:[lib]/prot=o:rwed
+$ create/dir new_gnu:[usr.bin]/prot=o:rwed
+$ create/dir new_gnu:[usr.include]/prot=o:rwed
+$ create/dir new_gnu:[usr.lib.gawk]/prot=o:rwed
+$ create/dir new_gnu:[usr.share.awk]/prot=o:rwed
+$ create/dir new_gnu:[usr.share.doc.gawk]/prot=o:rwed
+$ create/dir new_gnu:[usr.share.info]/prot=o:rwed
+$ create/dir new_gnu:[usr.src.gawk.extension.vms]/prot=o:rwed
+$ create/dir new_gnu:[usr.share.doc.man.man1]/prot=o:rwed
+$ endif
+$!
+$ if mode .eqs. "install"
+$ then
+$ copy [.vms]gnv_gawk_startup.com -
+ new_gnu:[vms_bin]gnv$gawk_startup.com
+$ else
+$ file = "new_gnu:[vms_bin]gnv$gawk_startup.com"
+$ if f$search(file) .nes. "" then delete 'file';*
+$ endif
+$!
+$!
+$! Read through the file list to set up aliases and rename commands.
+$!---------------------------------------------------------------------
+$ open/read flst [.vms]pcsi_gawk_file_list.txt
+$!
+$inst_alias_loop:
+$ ! Skip the aliases
+$ read/end=inst_file_loop_end flst line_in
+$ line_in = f$edit(line_in,"compress,trim,uncomment")
+$ if line_in .eqs. "" then goto inst_alias_loop
+$ pathname = f$element(0, " ", line_in)
+$ linkflag = f$element(1, " ", line_in)
+$ if linkflag .nes. "->" then goto inst_alias_done
+$ goto inst_alias_loop
+$!
+$inst_file_loop:
+$!
+$ read/end=inst_file_loop_end flst line_in
+$ line_in = f$edit(line_in,"compress,trim,uncomment")
+$ if line_in .eqs. "" then goto inst_file_loop
+$!
+$inst_alias_done:
+$!
+$!
+$! Skip the directories as we did them above.
+$! Just process the files.
+$ tdir = f$parse(line_in,,,"DIRECTORY")
+$ tdir_len = f$length(tdir)
+$ tname = f$parse(line_in,,,"NAME")
+$ lctname = f$edit(tname, "LOWERCASE")
+$ ttype = f$parse(line_in,,,"TYPE")
+$ if arch_code .eqs. "V"
+$ then
+$ tname = lctname
+$ ttype = f$edit(ttype, "LOWERCASE")
+$ tdir = f$edit(tdir, "LOWERCASE")
+$ endif
+$ if tname .eqs. "" then goto inst_file_loop
+$ if ttype .eqs. ".dir" then goto inst_file_loop
+$!
+$! if p1 starts with "R" then remove instead of install.
+$!
+$! If gnv$xxx.exe, then:
+$! Source is []gnv$gawk.exe
+$! Destination1 is new_gnu:[bin]gnv$gawk.exe
+$! Destination2 is new_gnu:[bin]xxx. (alias)
+$! Destination2 is new_gnu:[bin]xxx.exe (alias)
+$! We put all in new_gnu:[bin] instead of some in [usr.bin] because
+$! older GNV kits incorrectly put some images in [bin] and [bin]
+$! comes first in the search list.
+$ if f$locate("gnv$", tname) .eq. 0
+$ then
+$ myfile_len = f$length(tname)
+$ myfile = f$extract(4, myfile_len, tname)
+$ source = "[]''myfile'''ttype'"
+$ dest1 = "new_gnu:[bin]''tname'''ttype'"
+$ dest2 = "new_gnu:[bin]''myfile'."
+$ dest3 = "new_gnu:[bin]''myfile'.exe"
+$ if mode .eqs. "install"
+$ then
+$ if f$search(dest1) .eqs. "" then copy 'source' 'dest1'
+$ if f$search(dest2) .eqs. "" then set file/enter='dest2' 'dest1'
+$ if f$search(dest3) .eqs. "" then set file/enter='dest3' 'dest1'
+$ else
+$ if f$search(dest2) .nes. "" then set file/remove 'dest2';*
+$ if f$search(dest3) .nes. "" then set file/remove 'dest3';*
+$ if f$search(dest1) .nes. "" then delete 'dest1';*
+$ endif
+$ goto inst_file_loop
+$ endif
+$!
+$! If lib.gawk] then
+$! source is sys$disk:[]
+$! dest is new_gnu:[usr.lib.gawk]
+$ if f$locate("lib.gawk]", tdir) .lt. tdir_len
+$ then
+$! ! Not yet available on VAX/VMS
+$ if arch_code .eqs. "V" then goto inst_file_loop
+$!
+$ source = "[]''tname'''ttype'"
+$ dest = "new_gnu:[usr.lib.gawk]''tname'''ttype'"
+$ if mode .eqs. "install"
+$ then
+$ if f$search(dest) .eqs. "" then copy 'source' 'dest'
+$ else
+$ if f$search(dest) .nes. "" then delete 'dest';*
+$ endif
+$ goto inst_file_loop
+$ endif
+$!
+$! If .vms_bin] then
+$! source is sys$disk:[]
+$! dest is [vms_bin]
+$ if (f$locate("vms_bin]", tdir) .lt. tdir_len)
+$ then
+$ if (ttype .eqs. ".cld")
+$ then
+$ source = "sys$disk:[]''tname'''ttype'"
+$ else
+$ source = "sys$disk:[.vms]''tname'''ttype'"
+$ endif
+$ dest = "new_gnu:[vms_bin]''tname'''ttype'"
+$ if mode .eqs. "install"
+$ then
+$ if f$search(dest) .eqs. "" then copy 'source' 'dest'
+$ else
+$ if f$search(dest) .nes. "" then delete 'dest';*
+$ endif
+$ goto inst_file_loop
+$ endif
+$!
+$! If .vms_hlp] then
+$! source is sys$disk:[.vms]
+$! dest is [vms_help]
+$ if (f$locate("vms_help]", tdir) .lt. tdir_len) .and. (ttype .eqs. ".hlp")
+$ then
+$ source = "sys$disk:[.vms]''tname'''ttype'"
+$ dest = "new_gnu:[vms_help]''tname'''ttype'"
+$ if mode .eqs. "install"
+$ then
+$ if f$search(dest) .eqs. "" then copy 'source' 'dest'
+$ else
+$ if f$search(dest) .nes. "" then delete 'dest';*
+$ endif
+$ goto inst_file_loop
+$ endif
+$!
+$! If doc.gawk] then
+$! source is sys$disk:[] or [.readme_d]
+$! dest is [usr.share.doc.gawk]
+$ if f$locate(".doc.gawk]", tdir) .lt. tdir_len
+$ then
+$ if lctname .eqs. "readme" .and. ttype .nes. "."
+$ then
+$ source = "sys$disk:[.README_D]''tname'''ttype'"
+$ if f$search(source) .eqs. ""
+$ then
+$! ! This may be an NFS mangled name on VAX.
+$ stype = ttype - "."
+$ if stype .nes. "vms" then stype = "$" + stype
+$ source = "sys$disk:[.$README_$D]$README.''stype'"
+$ endif
+$ else
+$ source = "sys$disk:[]''tname'''ttype'"
+$ if f$search(source) .eqs. ""
+$ then
+$ source = "sys$disk:[]$''tname'''ttype'"
+$ endif
+$ endif
+$ dest = "new_gnu:[usr.share.doc.gawk]''tname'''ttype'"
+$ if mode .eqs. "install"
+$ then
+$ if f$search(dest) .eqs. "" then copy 'source' 'dest'
+$ else
+$ if f$search(dest) .nes. "" then delete 'dest';*
+$ endif
+$ goto inst_file_loop
+$ endif
+$!
+$! If .awk] then
+$! source is sys$disk:[.awklib.eg.lib]
+$! dest is new_gnu:[usr.share.awk]
+$ if f$locate(".awk]", tdir) .lt. tdir_len
+$ then
+$ source = "[.awklib.eg.lib]''tname'''ttype'"
+$ dest = "new_gnu:[usr.share.awk]''tname'''ttype'"
+$ if mode .eqs. "install"
+$ then
+$ if f$search(dest) .eqs. "" then copy 'source' 'dest'
+$ else
+$ if f$search(dest) .nes. "" then delete 'dest';*
+$ endif
+$ goto inst_file_loop
+$ endif
+$!
+$! If *.info then
+$! source is [.doc]gawk.info
+$! dest is [.usr.share.info]
+$ if ttype .eqs. ".info"
+$ then
+$ source = "[.doc]''tname'''ttype'"
+$ dest = "new_gnu:[usr.share.info]''tname'''ttype'"
+$ if mode .eqs. "install"
+$ then
+$ if f$search(dest) .eqs. "" then copy 'source' 'dest'
+$ else
+$ if f$search(dest) .nes. "" then delete 'dest';*
+$ endif
+$ goto inst_file_loop
+$ endif
+$!
+$! If *.h then
+$! source is []*.h
+$! dest is [.usr.include]
+$ if ttype .eqs. ".h"
+$ then
+$ source = "[]''tname'''ttype'"
+$ dest = "new_gnu:[usr.include]''tname'''ttype'"
+$ if mode .eqs. "install"
+$ then
+$ if f$search(dest) .eqs. "" then copy 'source' 'dest'
+$ else
+$ if f$search(dest) .nes. "" then delete 'dest';*
+$ endif
+$ goto inst_file_loop
+$ endif
+$!
+$! If *.opt then
+$! source is [.vms]gawk_plugin.opt
+$! dest is [.usr.src.gawk.extension.vms]
+$ if ttype .eqs. ".opt"
+$ then
+$ source = "[.vms]''tname'''ttype'"
+$ dest = "new_gnu:[usr.src.gawk.extension.vms]''tname'''ttype'"
+$ if mode .eqs. "install"
+$ then
+$ if f$search(dest) .eqs. "" then copy 'source' 'dest'
+$ else
+$ if f$search(dest) .nes. "" then delete 'dest';*
+$ endif
+$ goto inst_file_loop
+$ endif
+$!
+$! If xxx.1 then
+$! source is [.doc]xxx.1
+$! dest is [usr.share.man.man1]
+$ if ttype .eqs. ".1"
+$ then
+$ source = "[.doc]''tname'''ttype'"
+$ dest = "new_gnu:[usr.share.man.man1]''tname'''ttype'"
+$ if mode .eqs. "install"
+$ then
+$ if f$search(dest) .eqs. "" then copy 'source' 'dest'
+$ else
+$ if f$search(dest) .nes. "" then delete 'dest';*
+$ endif
+$ goto inst_file_loop
+$ endif
+$!
+$ goto inst_file_loop
+$!
+$inst_file_loop_end:
+$!
+$close flst
+$!
+$all_exit:
+$ exit
diff --git a/vms/vax/ChangeLog b/vms/vax/ChangeLog
new file mode 100644
index 00000000..7cf2c4fa
--- /dev/null
+++ b/vms/vax/ChangeLog
@@ -0,0 +1,11 @@
+2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 4.1.1: Release tar ball made.
+
+2013-12-29 John Malmberg <wb8tyw@qsl.net>
+
+ * ChangeLog: New directory.
+ * gawk_plugin_xfer.mar_exact, gawk_plugin_xfer.opt,
+ macro32_exactcase.com, macro32_exactcase.patch:
+ These are experimental files for future support of
+ dynamic extensions on VAX/VMS.
diff --git a/vms/vax/gawk_plugin_xfer.mar_exact b/vms/vax/gawk_plugin_xfer.mar_exact
new file mode 100644
index 00000000..e90babbd
--- /dev/null
+++ b/vms/vax/gawk_plugin_xfer.mar_exact
@@ -0,0 +1,13 @@
+ .PSECT GAWK_PLUGIN_XFERVECTORS -
+ PIC,USR,CON,REL,GBL,SHR,EXE,RD,NOWRT,QUAD
+
+; Exact case transfer vector and universal symbols
+;
+ .ALIGN QUAD
+ .EXTERNAL plugin_is_GPL_compatible
+
+ .TRANSFER dl_load
+ .MASK dl_load
+ JMP L^dl_load+2
+
+ .END
diff --git a/vms/vax/gawk_plugin_xfer.opt b/vms/vax/gawk_plugin_xfer.opt
new file mode 100644
index 00000000..75c134f7
--- /dev/null
+++ b/vms/vax/gawk_plugin_xfer.opt
@@ -0,0 +1,5 @@
+CASE_SENSITIVE=YES
+UNIVERSAL=plugin_is_GPL_compatible
+UNIVERSAL=dl_load
+!CLUSTER=GAWK_PLUGIN_XFER
+!COLLECT=GAWK_GLOBAL, GAWK_PLUGIN_XFERVECTORS
diff --git a/vms/vax/macro32_exactcase.com b/vms/vax/macro32_exactcase.com
new file mode 100644
index 00000000..79194e21
--- /dev/null
+++ b/vms/vax/macro32_exactcase.com
@@ -0,0 +1,16 @@
+$!
+$! Patch the Macro32 compiler and optional assemble
+$!-----------------------------------------------------
+$ patched_macro = "sys$disk:[]macro32_exactcase.exe"
+$ if f$search(patched_macro) .eqs. ""
+$ then
+$ copy sys$system:macro32.exe 'patched_macro'
+$ patch @[.vms]macro32_exactcase.patch
+$ endif
+$! Usage:
+$ xfer_file_source = p1
+$ if f$search(p1) .nes. ""
+$ then
+$ define/user macro32 'patched_macro'
+$ macro/lis 'p1'
+$ endif
diff --git a/vms/vax/macro32_exactcase.patch b/vms/vax/macro32_exactcase.patch
new file mode 100644
index 00000000..eda5cac7
--- /dev/null
+++ b/vms/vax/macro32_exactcase.patch
@@ -0,0 +1,11 @@
+macro32_exactcase.exe
+SE EC
+^X00000001
+RE /I
+^X00012B1D
+'BICB2 #^X00000020,R3'
+EXIT
+'BICB2 #^X00000000,R3'
+EXI
+U
+EXI
diff --git a/vms/vms-conf.h b/vms/vms-conf.h
deleted file mode 100644
index cbdc9508..00000000
--- a/vms/vms-conf.h
+++ /dev/null
@@ -1,661 +0,0 @@
-#ifndef CONFIG_H
-#define CONFIG_H
-/*
- * config.h -- configuration definitions for gawk.
- *
- * For VMS (assumes V4.6 or later; tested on V7.3-1, V8.3.
- */
-
-/*
- * Copyright (C) 1991-1992, 1995-1996, 1999, 2001-2003, 2005, 2009, 2010, 2011
- * 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 3 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
-
-#if 0 /* no longer used */
-/* Define to 1 if using alloca.c. */
-#define C_ALLOCA 1
-#else
-#define NO_ALLOCA /* vms/vms_fwrite.c needs this */
-/* 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)
-#endif /*0*/
-
-/* 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 the <arpa/inet.h> header file. */
-#undef HAVE_ARPA_INET_H
-
-/* Define to 1 if you have the `atexit' function. */
-#define HAVE_ATEXIT 1
-
-/* 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 have the declaration of `tzname', and to 0 if you don't.
- */
-#undef HAVE_DECL_TZNAME
-
-/* 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
-
-/* have getaddrinfo */
-#undef HAVE_GETADDRINFO
-
-/* 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. */
-#define HAVE_ISASCII 1
-
-/* 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 <libintl.h> header file. */
-#undef HAVE_LIBINTL_H
-
-/* Define if you have the libsigsegv library. */
-#undef HAVE_LIBSIGSEGV
-
-/* Define to 1 if you have the `m' library (-lm). */
-#undef HAVE_LIBM
-
-/* Define to 1 if you have a fully functional readline library. */
-#undef HAVE_LIBREADLINE
-
-/* 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 long' type. */
-#undef HAVE_LONG_LONG
-
-/* Define to 1 if the system has the type `long long int'. */
-#undef HAVE_LONG_LONG_INT
-
-/* 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 `memcpy_ulong' function. */
-#undef HAVE_MEMCPY_ULONG
-
-/* 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 `memset' function. */
-#define HAVE_MEMSET 1
-
-/* Define to 1 if you have the `memset_ulong' function. */
-#undef HAVE_MEMSET_ULONG
-
-/* Define to 1 if you have the `mkstemp' function. */
-#undef HAVE_MKSTEMP
-
-/* we have the mktime function */
-#define HAVE_MKTIME 1
-
-/* 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'll use the one in [.missing_d] */
-#undef HAVE_SETENV
-
-/* Define to 1 if you have the `setlocale' function. */
-#undef HAVE_SETLOCALE
-
-/* Define to 1 if you have the `snprintf' function. */
-#undef HAVE_SNPRINTF
-
-/* newer systems define this type here */
-#undef HAVE_SOCKADDR_STORAGE
-
-/* 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 `strchr' function. */
-#define HAVE_STRCHR 1
-
-/* Define to 1 if you have the `strcoll' function. */
-#define HAVE_STRCOLL 1
-
-/* 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 a member of `struct stat'. */
-#undef HAVE_STRUCT_STAT_ST_BLKSIZE
-
-/* Define to 1 if `tm_zone' is a 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 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 you have the `tmpfile' function. */
-#define HAVE_TMPFILE 1
-/* Force snprintf.c to use tmpfile() instead of mkstemp(). */
-#ifdef HAVE_MKSTEMP
-#undef HAVE_MKSTEMP
-#endif
-
-/* 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'. */
-#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 the system has the type `unsigned long long int'. */
-#undef HAVE_UNSIGNED_LONG_LONG_INT
-
-/* Define to 1 if you have the `usleep' function. */
-#define HAVE_USLEEP 1
-
-/* 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 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 fatal errors on directories */
-#undef NO_DIRECTORY_FATAL
-
-/* 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.8"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "gawk"
-
-/* Define to the home page for this package. */
-#undef PACKAGE_URL
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "4.0.0"
-
-/* Define to 1 if *printf supports %F format */
-#undef PRINTF_HAS_F_FORMAT
-
-/* 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 to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 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 "4.0.0"
-
-/* 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
-
-/* Enable GNU extensions on systems that have them. */
-#ifndef _GNU_SOURCE
-# undef _GNU_SOURCE
-#endif
-
-/* 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
-
-/* Enable extensions on Solaris. */
-#ifndef __EXTENSIONS__
-# undef __EXTENSIONS__
-#endif
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# undef _POSIX_PTHREAD_SEMANTICS
-#endif
-#ifndef _TANDEM_SOURCE
-# undef _TANDEM_SOURCE
-#endif
-
-/* 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 `int' if <sys/types.h> doesn't define. */
-#undef pid_t
-
-/* Define to the equivalent of the C99 'restrict' keyword, or to
- nothing if this is not supported. Do not define if restrict is
- supported directly. */
-#define restrict
-#if defined(__DECC) && (__DECC_VER >= 60400000)
-#undef restrict
-#endif
-
-/* Define to `unsigned' if <sys/types.h> doesn't 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. */
-#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 >= 70320000
-# define CRTL_VER_V732
-# define HAVE_SNPRINTF 1
-# endif
-# 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 */
-/* #undef HAVE_STDDEF_H */
-#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
-
-/* EXIT_SUCCESS and EXIT_FAILURE normally come from <stdlib.h> */
-#ifndef HAVE_STDLIB_H
-# define EXIT_SUCCESS 1 /* SYS$_NORMAL */
-# define EXIT_FAILURE 0x10000002 /* STS$M_INHIB_MSG|STS$K_ERROR */
-#endif
-/* EXIT_FATAL is specific to gawk, not part of Standard C */
-#define EXIT_FATAL 0x10000004 /* STS$M_INHIB_MSG|STS$K_SEVERE */
-
-#define IN_CONFIG_H
-#include "vms/redirect.h"
-#undef IN_CONFIG_H
-
-#endif /*"custom.h"*/
-
-#endif /*CONFIG_H*/
diff --git a/vms/vms.h b/vms/vms.h
index 0fb73d5b..3991d39b 100644
--- a/vms/vms.h
+++ b/vms/vms.h
@@ -54,26 +54,26 @@ typedef struct _itm { U_Short len, code; void *buffer; U_Short *retlen; } Itm;
#define Descrip(strdsc,strbuf) Dsc strdsc = {sizeof strbuf - 1, (char *)strbuf}
extern int shell$is_shell(void);
-extern U_Long lib$find_file(const Dsc *, Dsc *, void *, ...);
-extern U_Long lib$find_file_end(void *);
+extern U_Long LIB$FIND_FILE(const Dsc *, Dsc *, void *, ...);
+extern U_Long LIB$FIND_FILE_END(void *);
#ifndef NO_TTY_FWRITE
-extern U_Long lib$get_ef(long *);
-extern U_Long sys$assign(const Dsc *, short *, long, const Dsc *);
-extern U_Long sys$dassgn(short);
-extern U_Long sys$qio(U_Long, U_Long, U_Long, void *,
+extern U_Long LIB$GET_EF(long *);
+extern U_Long SYS$ASSIGN(const Dsc *, short *, long, const Dsc *);
+extern U_Long SYS$DASSGN(short);
+extern U_Long SYS$QIO(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(long, void *);
+extern U_Long SYS$SYNCH(long, void *);
#endif /*!NO_TTY_FWRITE*/
-extern U_Long lib$spawn(const Dsc *,const Dsc *,const Dsc *,
+extern U_Long LIB$SPAWN(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(const U_Long *,const Dsc *,const Dsc *,
+extern U_Long SYS$TRNLNM(const U_Long *,const Dsc *,const Dsc *,
const unsigned char *,Itm *);
-extern U_Long sys$crelnm(const U_Long *,const Dsc *,const Dsc *,
+extern U_Long SYS$CRELNM(const U_Long *,const Dsc *,const Dsc *,
const unsigned char *,const Itm *);
-extern U_Long sys$crelog(int,const Dsc *,const Dsc *,unsigned char);
-extern U_Long sys$dellnm(const Dsc *,const Dsc *,const unsigned char *);
+extern U_Long SYS$CRELOG(int,const Dsc *,const Dsc *,unsigned char);
+extern U_Long SYS$DELLNM(const Dsc *,const Dsc *,const unsigned char *);
extern void v_add_arg(int, const char *);
extern void vms_exit(int);
diff --git a/vms/vms_args.c b/vms/vms_args.c
index 0a296105..12165131 100644
--- a/vms/vms_args.c
+++ b/vms/vms_args.c
@@ -1,7 +1,7 @@
/* vms_args.c -- command line parsing, to emulate shell i/o redirection.
[ Escape sequence parsing now suppressed. ]
- Copyright (C) 1991-1996, 1997, 2011 the Free Software Foundation, Inc.
+ Copyright (C) 1991-1996, 1997, 2011, 2014 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
@@ -106,10 +106,26 @@ vms_arg_fixup( int *pargc, char ***pargv )
char **argv = *pargv;
int i, argc = *pargc;
int err_to_out_redirect = 0, out_to_err_redirect = 0;
+ char * shell;
+ int using_shell;
/* make sure AWK_LIBRARY has a value */
if (!getenv("AWK_LIBRARY"))
vms_define("AWK_LIBRARY", "SYS$LIBRARY:");
+
+ /* Check if running under a shell instead of DCL */
+ using_shell = 1;
+ shell = getenv("SHELL");
+ if (shell != NULL) {
+ if (strcmp(shell, "DCL") == 0) {
+ using_shell = 0;
+ }
+ } else {
+ using_shell = 0;
+ }
+ if (using_shell) {
+ return;
+ }
#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 */
@@ -325,12 +341,12 @@ vms_expand_wildcards( const char *prospective_filespec )
*/
len = -1; /* overload 'len' with flag value */
context = NULL; /* init */
- while (vmswork(lib$find_file(&spec, &result, &context))) {
+ 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);
+ (void)LIB$FIND_FILE_END(&context);
if (len >= 0) /* (still -1 => never entered loop) */
--v_argc; /* undo final post-increment */
return;
@@ -395,7 +411,7 @@ vms_define( const char *log_name, const char *trans_val )
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);
+ return SYS$CRELNM(&attr, &lnmtable, &log_dsc, &acmode, itemlist);
}
/* t_strstr -- strstr() substitute; search 'str' for 'sub' */
diff --git a/vms/vms_cli.c b/vms/vms_cli.c
index ac793c1a..08e2d142 100644
--- a/vms/vms_cli.c
+++ b/vms/vms_cli.c
@@ -1,6 +1,6 @@
/* vms_cli.c -- interface to CLI$xxx routines for fetching command line components
- Copyright (C) 1991-1993, 2003, 2011 the Free Software Foundation, Inc.
+ Copyright (C) 1991-1993, 2003, 2011, 2014 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
@@ -29,13 +29,13 @@
#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 */
+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 */
@@ -43,10 +43,10 @@ U_Long
Cli_Present( const char *item )
{
Dsc item_dsc;
- (void)lib$establish(lib$sig_to_ret);
+ (void)LIB$ESTABLISH(LIB$SIG_TO_RET);
item_dsc.len = strlen(item_dsc.adr = (char *)item);
- return cli$present(&item_dsc);
+ return CLI$PRESENT(&item_dsc);
}
/* Cli_Get_Value() - call CLI$GET_VALUE to retreive the value of a */
@@ -57,11 +57,11 @@ 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);
+ (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);
+ sts = CLI$GET_VALUE(&item_dsc, &res_dsc, &len);
result[len] = '\0';
return sts;
}
@@ -79,11 +79,11 @@ Cli_Parse_Command( const void *cmd_tables, const char *cmd_verb )
U_Long sts;
int ltmp;
char longbuf[8200];
- (void)lib$establish(lib$sig_to_ret);
+ (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 */
+ 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) */
@@ -92,7 +92,7 @@ Cli_Parse_Command( const void *cmd_tables, const char *cmd_verb )
/* 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);
+ (void)SYS$FILESCAN(&cmd.rdesc, fscn, (long *)0);
cmd.rdesc.len -= fscn[0].len; /* shrink size */
cmd.rdesc.adr += fscn[0].len; /* advance ptr */
}
@@ -102,7 +102,7 @@ Cli_Parse_Command( const void *cmd_tables, const char *cmd_verb )
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);
+ sts = CLI$DCL_PARSE(&cmd.rdesc, cmd_tables);
}
return sts;
diff --git a/vms/vms_crtl_init.c b/vms/vms_crtl_init.c
new file mode 100644
index 00000000..081ae2cc
--- /dev/null
+++ b/vms/vms_crtl_init.c
@@ -0,0 +1,470 @@
+/* File: VMS_CRTL_INIT.C
+
+ This file is common to a lot of projects.
+
+ $Id: vms_crtl_init.c,v 1.1.1.1 2012/12/02 19:25:22 wb8tyw Exp $
+
+ Module that provides a LIB$INITIALIZE routine for the GNV toolset that
+ will turn on some CRTL features that are not enabled by default.
+
+ The CRTL features can also be turned on via logical names, but that
+ impacts all programs and some aren't ready, willing, or able to handle
+ the settings that GNV needs.
+
+ The original module was found linked with GPL V2 modules, and thus must
+ be able to be distributed under the GPL V2 provisions.
+
+ As this module or similar is needed for virtually all programs built to run
+ under GNV or UNIX, it can be distributed with other licenses.
+
+ Edit History
+
+ 1-001 John Reagan Initial version using the old style interface
+ but with the new version commented out.
+
+ 1-002 John Reagan Switch to new API for setting features
+
+ 1-003 Steve Pitcher Add DECC$RENAME_NO_INHERIT.
+
+ 1-004 Steve Pitcher Quiet these, if the DECC feature doesn't exist.
+
+ 2-001 J. Malmberg New GNV requirements:
+ Three variations of object modules:
+ 1. For use with shells, sets the logical
+ name GNV$UNIX_SHELL.
+
+ 2. For utilities, if the logical name
+ GNV$UNIX_SHELL is set, it means that the
+ settings should assume that they are
+ running under a UNIX like shell.
+
+ 3. A third setting is for utilities that
+ always should behave as if they are
+ running under a UNIX shell.
+
+ If GNV$GNU is defined, then locally define
+ SYS$POSIX_ROOT to it. GNV$GNU can be set in
+ the SYSTEM table by the GNV setup.
+ SYS$POSIX_ROOT can not.
+
+ The logical name BIN also needs to be defined
+ here, otherwise the CRTL replaces it with
+ SYS$SYSTEM:
+
+ Never set the POSIX UID here, it will break
+ every reference to a GID/UID on systems that
+ do not have every VMS account mapped to a UID/GID
+ by TCPIP services.
+
+ Reformat text to fit 80 columns.
+
+ Remove all VAX C specific code.
+
+ Linker is probably using exact case, so public
+ symbols for LIB$* and SYS$* must be in upper case.
+
+ 2-002 J. Malmberg Support for VAX builds. OpenVMS/VAX does not have the
+ 17-Jun-2010 DECC$FEATURE routines. At this time I will not
+ be concerned if a feature setting exists on VAX,
+ as all we are doing is setting a logical name.
+
+ 2-003 J. Malmberg Add DECC$FILENAME_UNIX_NOVERSION as version numbers
+ will usually mess up ported programs.
+
+*/
+
+#include <stdio.h>
+#include <descrip.h>
+#include <lnmdef.h>
+#include <stsdef.h>
+#include <string.h>
+
+#pragma message disable pragma
+#pragma message disable dollarid
+#pragma message disable valuepres
+
+#pragma member_alignment save
+#pragma nomember_alignment longword
+#pragma message save
+#pragma message disable misalgndmem
+struct itmlst_3 {
+ unsigned short int buflen;
+ unsigned short int itmcode;
+ void *bufadr;
+ unsigned short int *retlen;
+};
+#pragma message restore
+#pragma member_alignment restore
+
+#ifdef __VAX
+#define ENABLE "ENABLE"
+#define DISABLE "DISABLE"
+#else
+
+#define ENABLE TRUE
+#define DISABLE 0
+int decc$feature_get_index (const char *name);
+int decc$feature_set_value (int index, int mode, int value);
+
+#endif
+
+int SYS$TRNLNM(
+ const unsigned long * attr,
+ const struct dsc$descriptor_s * table_dsc,
+ struct dsc$descriptor_s * name_dsc,
+ const unsigned char * acmode,
+ const struct itmlst_3 * item_list);
+int SYS$CRELNM(
+ const unsigned long * attr,
+ const struct dsc$descriptor_s * table_dsc,
+ const struct dsc$descriptor_s * name_dsc,
+ const unsigned char * acmode,
+ const struct itmlst_3 * item_list);
+int LIB$SIGNAL(int);
+
+/* Take all the fun out of simply looking up a logical name */
+static int sys_trnlnm
+ (const char * logname,
+ char * value,
+ int value_len)
+{
+ const $DESCRIPTOR(table_dsc, "LNM$FILE_DEV");
+ const unsigned long attr = LNM$M_CASE_BLIND;
+ struct dsc$descriptor_s name_dsc;
+ int status;
+ unsigned short result;
+ struct itmlst_3 itlst[2];
+
+ itlst[0].buflen = value_len;
+ itlst[0].itmcode = LNM$_STRING;
+ itlst[0].bufadr = value;
+ itlst[0].retlen = &result;
+
+ itlst[1].buflen = 0;
+ itlst[1].itmcode = 0;
+
+ name_dsc.dsc$w_length = strlen(logname);
+ name_dsc.dsc$a_pointer = (char *)logname;
+ name_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ name_dsc.dsc$b_class = DSC$K_CLASS_S;
+
+ status = SYS$TRNLNM(&attr, &table_dsc, &name_dsc, 0, itlst);
+
+ if ($VMS_STATUS_SUCCESS(status)) {
+
+ /* Null terminate and return the string */
+ /*--------------------------------------*/
+ value[result] = '\0';
+ }
+
+ return status;
+}
+
+/* How to simply create a logical name */
+static int sys_crelnm
+ (const char * logname,
+ const char * value)
+{
+ int ret_val;
+ const char * proc_table = "LNM$PROCESS_TABLE";
+ struct dsc$descriptor_s proc_table_dsc;
+ struct dsc$descriptor_s logname_dsc;
+ struct itmlst_3 item_list[2];
+
+ proc_table_dsc.dsc$a_pointer = (char *) proc_table;
+ proc_table_dsc.dsc$w_length = strlen(proc_table);
+ proc_table_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ proc_table_dsc.dsc$b_class = DSC$K_CLASS_S;
+
+ logname_dsc.dsc$a_pointer = (char *) logname;
+ logname_dsc.dsc$w_length = strlen(logname);
+ logname_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ logname_dsc.dsc$b_class = DSC$K_CLASS_S;
+
+ item_list[0].buflen = strlen(value);
+ item_list[0].itmcode = LNM$_STRING;
+ item_list[0].bufadr = (char *)value;
+ item_list[0].retlen = NULL;
+
+ item_list[1].buflen = 0;
+ item_list[1].itmcode = 0;
+
+ ret_val = SYS$CRELNM(NULL, &proc_table_dsc, &logname_dsc, NULL, item_list);
+
+ return ret_val;
+}
+
+
+ /* Start of DECC RTL Feature handling */
+
+/*
+** Sets default value for a feature
+*/
+#ifdef __VAX
+static void set_feature_default(const char *name, const char *value)
+{
+ sys_crelnm(name, value);
+}
+#else
+static void set_feature_default(const char *name, int value)
+{
+ int index;
+
+ index = decc$feature_get_index(name);
+
+ if (index > 0)
+ decc$feature_set_value (index, 0, value);
+}
+#endif
+
+static void set_coe ( void )
+{
+
+ char gnv_posix_root[4096];
+ char unix_shell_name[255];
+ int use_unix_settings = 0;
+ int status;
+ int gnv_posix_root_found = 0;
+
+ /* If this is compiled for use with a UNIX shell, then the logical
+ * name GNV$UNIX_SHELL will be set to that shell name.
+ *
+ * Else, if the GNV$UNIX_SHELL logical name is set, then this application
+ * is running under some UNIX like shell, so it should modify it's
+ * behavior to be UNIX like.
+ *
+ * If the above logical name is not set, then the application should
+ * expect that it is running under DCL, and should expect VMS filenames
+ * on input, and may need to output filenames in VMS format.
+ *
+ * This can be overriden at compile time with GNV_UNIX_TOOL being
+ * defined.
+ *
+ * So this means that there will be multiple object modules from this
+ * source module. One for each shell, one for programs that can function
+ * in both DCL and UNIX environments, and one for programs that require
+ * a UNIX environment.
+ */
+
+#ifdef GNV_UNIX_SHELL
+ use_unix_settings = 1;
+
+ status = sys_crelnm("GNV$UNIX_SHELL", GNV_UNIX_SHELL);
+ if (!$VMS_STATUS_SUCCESS(status)) {
+ /* We have a big problem */
+ LIB$SIGNAL(status);
+ }
+#else
+
+#ifdef GNV_UNIX_TOOL
+ use_unix_settings = 1;
+#else
+ status = sys_trnlnm("GNV$UNIX_SHELL",
+ unix_shell_name, sizeof
+ unix_shell_name -1);
+ if (!$VMS_STATUS_SUCCESS(status)) {
+ unix_shell_name[0] = 0;
+ use_unix_settings = 0;
+ }
+#endif /* GNV_UNIX_TOOL */
+
+#endif /* GNV_UNIX_SHELL */
+
+ /* New style interface that works only on very recent
+ (Apr 2001 and beyond) CRTLs */
+
+ /*
+ * Only setting defaults allows logical names to
+ * override these settings.
+ */
+
+ /* Always set */
+
+ /* ACCESS should check ACLs or it is lying. */
+ set_feature_default("DECC$ACL_ACCESS_CHECK" , ENABLE);
+
+ /* We always want the new parse style */
+ set_feature_default ("DECC$ARGV_PARSE_STYLE" , ENABLE);
+
+ /* Unless we are in POSIX compliant mode, we want the old POSIX root
+ * enabled.
+ */
+ set_feature_default("DECC$DISABLE_POSIX_ROOT", DISABLE);
+
+ /* EFS charset, means UTF-8 support */
+ /* VTF-7 support is controlled by a feature setting called UTF8 */
+ set_feature_default ("DECC$EFS_CHARSET" , ENABLE);
+ set_feature_default ("DECC$EFS_CASE_PRESERVE" , ENABLE);
+
+
+ /* Support timestamps when available */
+ set_feature_default ("DECC$EFS_FILE_TIMESTAMPS" , ENABLE);
+
+ /* Cache environment varibles - performance improvements */
+ set_feature_default ("DECC$ENABLE_GETENV_CACHE" , ENABLE);
+
+ /* Start out with new file attribute inheritance */
+#ifdef __VAX
+ set_feature_default ("DECC$EXEC_FILEATTR_INHERITANCE", "2");
+#else
+ set_feature_default ("DECC$EXEC_FILEATTR_INHERITANCE", 2);
+#endif
+
+ /* Don't display trailing dot after files without type */
+ set_feature_default ("DECC$READDIR_DROPDOTNOTYPE" , ENABLE);
+
+ /* For standard output channels buffer output until terminator */
+ /* Gets rid of output logs with single character lines in them. */
+ set_feature_default ("DECC$STDIO_CTX_EOL" , ENABLE);
+
+ /* Fix mv aa.bb aa */
+ set_feature_default ("DECC$RENAME_NO_INHERIT" , ENABLE);
+
+ if (use_unix_settings) {
+
+ /* POSIX requires that open files be able to be removed */
+ set_feature_default ("DECC$ALLOW_REMOVE_OPEN_FILES", ENABLE);
+
+ set_feature_default ("DECC$FILENAME_UNIX_ONLY" , ENABLE);
+ /* FILENAME_UNIX_ONLY Implicitly sets
+ decc$disable_to_vms_logname_translation */
+
+ set_feature_default ("DECC$FILE_PERMISSION_UNIX", ENABLE);
+
+ /* For now this only with UNIX mode, applications can override
+ * with out using a LIB$INITIALIZE setting.
+ * This should be an application specific setting only enabled
+ * if the application requires it.
+ * Left here for now for backwards compatibility
+ */
+ set_feature_default ("DECC$FILE_SHARING" , ENABLE);
+
+ set_feature_default ("DECC$FILE_OWNER_UNIX" , ENABLE);
+ set_feature_default ("DECC$POSIX_SEEK_STREAM_FILE", ENABLE);
+
+ } else {
+ set_feature_default("DECC$FILENAME_UNIX_REPORT", ENABLE);
+ }
+
+ /* When reporting UNIX filenames, glob the same way */
+ set_feature_default ("DECC$GLOB_UNIX_STYLE" , ENABLE);
+
+ /* The VMS version numbers on Unix filenames is incompatible with most */
+ /* ported packages. */
+ set_feature_default("DECC$FILENAME_UNIX_NO_VERSION", ENABLE);
+
+ /* The VMS version numbers on Unix filenames is incompatible with most */
+ /* ported packages. */
+ set_feature_default("DECC$UNIX_PATH_BEFORE_LOGNAME", ENABLE);
+
+ /* Set strtol to proper behavior */
+ set_feature_default("DECC$STRTOL_ERANGE", ENABLE);
+
+ /* Pipe feature settings are longer needed with virtual memory pipe
+ code. Programs that use pipe need to be converted to use the
+ virtual memory pipe code, which effectively removes the hangs and
+ left over temporary files.
+
+ Comment left here to prevent regressions, as the larger pipe size
+ actually hurts memory usage with the new algorithm.
+ */
+ /* do_not_set_default ("DECC$PIPE_BUFFER_SIZE" , 8192); */
+
+
+ /* Rather than remove this completely, a comment is left here to warn
+ * someone from putting this bug back in.
+ *
+ * POSIX style UIDs require that the system administrator have set the
+ * system up to use POSIX style UIDs and GIDs. And if they have done
+ * so, then they should set the DECC$POSIX_STYLE_UID as a system wide
+ * logical name.
+ *
+ * Setting them in a program will break all routines that expect GID/UID
+ * stuff to work on systems set up by default with out mappings.
+ *
+ * Most utilities do not reference GID/UID values, so it took a while for
+ * this bug to surface.
+ */
+ /* do_not_set_default ("DECC$POSIX_STYLE_UID" , TRUE); */
+
+
+
+ /* GNV depends on SYS$POSIX_ROOT to be properly set. Since SYS$POSIX_ROOT
+ * globally affects all C applications, SYS$POSIX_ROOT can not be set
+ * anywhere that can be seen by other applications.
+ *
+ * So GNV$GNU is used instead, and SYS$POSIX_ROOT will be set in
+ * in the process table in user mode to that value.
+ *
+ * Restriction: The system manager should not point GNV$GNU at
+ * SYS$POSIX_ROOT, or anything that resolves to SYS$POSIX_ROOT.
+ *
+ */
+
+ status = sys_trnlnm("GNV$GNU",
+ gnv_posix_root,
+ sizeof gnv_posix_root - 1);
+ if ($VMS_STATUS_SUCCESS(status)) {
+ status = sys_crelnm("SYS$POSIX_ROOT", "GNV$GNU:");
+ gnv_posix_root_found = 1;
+ }
+
+ /* GNV depends on BIN being set to GNV$GNU:[bin]. Since BIN
+ * is not prefixed, and it affects everything globally, it needs to
+ * be set here if it is not defined already.
+ * If it is set already, assume that it is correct, rather than
+ * trying to second guess the user.
+ * If GNV$GNU is not defined, then define bin to be SYS$POSIX_ROOT.
+ */
+
+ status = sys_trnlnm("BIN",
+ gnv_posix_root,
+ sizeof gnv_posix_root - 1);
+ if (!$VMS_STATUS_SUCCESS(status)) {
+ if (gnv_posix_root_found) {
+ status = sys_crelnm("BIN", "GNV$GNU:[BIN]");
+ } else {
+ status = sys_crelnm("BIN", "SYS$POSIX_ROOT:[BIN]");
+ }
+ }
+
+}
+
+#pragma nostandard
+#pragma extern_model save
+#ifdef __VAX
+#pragma extern_model strict_refdef "LIB$INITIALIZE" nowrt, long, nopic
+#else
+#pragma extern_model strict_refdef "LIB$INITIALIZE" nowrt, long
+# if __INITIAL_POINTER_SIZE
+# pragma __pointer_size __save
+# pragma __pointer_size 32
+# else
+# pragma __required_pointer_size __save
+# pragma __required_pointer_size 32
+# endif
+#endif
+/* Set our contribution to the LIB$INITIALIZE array */
+void (* const iniarray[])(void) = {set_coe, } ;
+#ifndef __VAX
+# if __INITIAL_POINTER_SIZE
+# pragma __pointer_size __restore
+# else
+# pragma __required_pointer_size __restore
+# endif
+#endif
+
+
+/*
+** Force a reference to LIB$INITIALIZE to ensure it
+** exists in the image.
+*/
+int LIB$INITIALIZE(void);
+#ifdef __DECC
+#pragma extern_model strict_refdef
+#endif
+ int lib_init_ref = (int) LIB$INITIALIZE;
+#ifdef __DECC
+#pragma extern_model restore
+#pragma standard
+#endif
diff --git a/vms/vms_fwrite.c b/vms/vms_fwrite.c
index 921ac2d4..f29ec832 100644
--- a/vms/vms_fwrite.c
+++ b/vms/vms_fwrite.c
@@ -1,6 +1,6 @@
/* vms_fwrite.c - augmentation for the fwrite() function.
- Copyright (C) 1991-1996, 2010, 2011 the Free Software Foundation, Inc.
+ Copyright (C) 1991-1996, 2010, 2011, 2014 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
@@ -77,15 +77,15 @@ tty_fwrite( const void *buf, size_t size, size_t number, 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 */
- && which_gawk != exe_debugging) {
+ && ! do_debug) {
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))) {
+ 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;
+ 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 */
@@ -119,19 +119,19 @@ tty_fwrite( const void *buf, size_t size, size_t number, FILE *file )
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);
+ 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,
+ 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);
+ sts = SYS$SYNCH(evfn, &iosb);
if (vmswork(sts)) sts = iosb.status, result += iosb.count;
}
if (vmsfail(sts)) errno = EVMSERR, vaxc$errno = sts;
@@ -202,7 +202,7 @@ tty_fclose( FILE *file )
short chan = file_num < _NFILE ? channel[file_num] : -1;
if (chan > 0)
- (void)sys$dassgn(chan); /* deassign the channel (ie, close) */
+ (void)SYS$DASSGN(chan); /* deassign the channel (ie, close) */
if (file_num < _NFILE)
channel[file_num] = 0; /* clear stale info */
}
diff --git a/vms/vms_gawk.c b/vms/vms_gawk.c
index 222d803d..4080e1db 100644
--- a/vms/vms_gawk.c
+++ b/vms/vms_gawk.c
@@ -1,6 +1,7 @@
/* vms_gawk.c -- parse GAWK command line using DCL syntax
- Copyright (C) 1991-1993, 1996, 2003, 2005, 2011 the Free Software Foundation, Inc.
+ Copyright (C) 1991-1993, 1996, 2003, 2005, 2011, 2014
+ 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
@@ -37,21 +38,21 @@
#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 */
+#ifndef __DECC
+extern void GAWK_CMD(); /* created with $ SET COMMAND/OBJECT */
+#define gawk_cmd ((const void *)GAWK_CMD) */
+#else /* Use ANSI definitions for DEC C */
#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;
+extern void *GAWK_CMD;
#pragma extern_model restore
-#define GAWK_CMD ((const void *)&gawk_cmd)
+#define gawk_cmd ((const void *)&GAWK_CMD)
#endif
extern void _exit(int);
static int vms_usage(int);
-static const char *CmdName; /* "GAWK", "DGAWK", or "PGAWK" */
+static const char *CmdName = "GAWK";
#define ARG_SIZ 250
union arg_w_prefix { /* structure used to simplify prepending of "-" */
@@ -80,10 +81,6 @@ vms_gawk()
int native_dcl = 1, /* assume true until we know otherwise */
short_circ; /* some options make P1, /commands, /input superfluous */
- CmdName = (which_gawk == exe_profiling) ? "PGAWK"
- : (which_gawk == exe_debugging) ? "DGAWK"
- : "GAWK";
-
/* check "GAWK_P1"--it's required; its presence will tip us off */
sts = Cli_Present("GAWK_P1");
if (CondVal(sts) == CondVal(CLI$_SYNTAX)) {
@@ -92,13 +89,13 @@ vms_gawk()
command, so we'll now attempt to generate a command from the
foreign command string and parse that.
*/
- sts = Cli_Parse_Command(GAWK_CMD, "GAWK"); /* (*not* CmdName) */
+ sts = Cli_Parse_Command(gawk_cmd, "GAWK"); /* (*not* CmdName) */
if (vmswork(sts))
sts = Cli_Present("GAWK_P1");
}
short_circ = Present("USAGE") || Present("VERSION") || Present("COPYRIGHT");
if (vmswork(sts)) /* command parsed successfully */
- v_add_arg(argc = 0, CmdName); /* save "GAWK|DGAWK|PGAWK" as argv[0] */
+ v_add_arg(argc = 0, CmdName); /* save "GAWK" as argv[0] */
else if (CondVal(sts) == CondVal(CLI$_INSFPRM))
/* vms_usage() will handle /usage, /version, and /copyright */
return short_circ ? vms_usage(0)
@@ -245,7 +242,7 @@ options: /FIELD_SEPARATOR=\"FS_value\" \n\
complaint = 0; /* clean exit */
} else if (Present("VERSION") || Present("COPYRIGHT")) {
/* construct a truncated Unix-style command line to control main() */
- v_add_arg(argc=0, CmdName); /* save "GAWK",&c as argv[0] */
+ v_add_arg(argc=0, CmdName); /* save "GAWK" as argv[0] */
#if 0
v_add_arg(++argc, Present("VERSION") ? "-V" : "-C");
#else
diff --git a/vms/vms_misc.c b/vms/vms_misc.c
index f3650ef4..82c2f8a8 100644
--- a/vms/vms_misc.c
+++ b/vms/vms_misc.c
@@ -1,6 +1,6 @@
/* vms_misc.c -- sustitute code for missing/different run-time library routines.
- Copyright (C) 1991-1993, 1996-1997, 2001, 2003, 2009, 2010, 2011
+ Copyright (C) 1991-1993, 1996-1997, 2001, 2003, 2009, 2010, 2011, 2014
the Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -98,7 +98,7 @@ vms_open( const char *name, int mode, ... )
{
int result;
- if (STREQN(name, "/dev/", 5)) {
+ if (strncmp(name, "/dev/", 5) == 0) {
/* (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: */
@@ -118,15 +118,24 @@ vms_open( const char *name, int mode, ... )
result = creat(name, 0, "rfm=stmlf", "rat=cr", "shr=nil", "mbc=32");
} else {
struct stat stb;
+ int stat_result;
const char *mbc, *shr = "shr=get", *ctx = "ctx=stm";
-
- if (stat((char *)name, &stb) < 0) { /* assume DECnet */
+
+ stat_result = stat((char *)name, &stb);
+ if ( stat_result < 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");
+ if ((stat_result >= 0) && (result < 0) && (errno == ENOENT)) {
+ /* ENOENT not possible because stat succeeded */
+ errno = EMFILE;
+ if (S_ISDIR(stb.st_mode)) {
+ errno = EISDIR; /* Bug seen in VMS 8.3 */
+ }
+ }
}
/* This is only approximate; the ACP -> RMS -> VAXCRTL interface
@@ -165,8 +174,8 @@ vms_devopen( const char *name, int mode )
#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();
+extern U_Long SYS$BINTIM(), SYS$GETTIM();
+extern U_Long LIB$SUBX(), LIB$EDIV();
/*
* Get current time in microsecond precision.
@@ -183,13 +192,13 @@ vms_gettimeofday(struct timeval *tv, void *timezone__not_used)
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 */
+ if (!epoch[0]) SYS$BINTIM(&epoch_dsc, epoch); /* 1 Jan 0:0:0 1970 */
/* get current time, as VMS quadword time */
- sys$gettim(now);
+ SYS$GETTIM(now);
/* convert the quadword time so that it's relative to Unix epoch */
- lib$subx(now, epoch, quad); /* quad = now - 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);
+ LIB$EDIV(&thunk, quad, &tv->tv_sec, &tv->tv_usec);
/* convert fraction of seconds into microseconds */
tv->tv_usec /= (VMS_UNITS_PER_SECOND / 1000000);
@@ -272,7 +281,7 @@ int fork( void ) {
#include <fab.h>
#include <nam.h>
-extern unsigned long sys$parse(), sys$search();
+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
@@ -307,7 +316,7 @@ VMS_fstat (fd, statbuf)
if (result == 0 /* GAWK addition; fixup /dev/null flags */
&& (statbuf->st_mode & S_IFREG)
- && STREQ(statbuf->st_dev, "_NLA0:"))
+ && strcmp(statbuf->st_dev, "_NLA0:") == 0)
{
statbuf->st_mode &= ~S_IFREG;
statbuf->st_mode |= S_IFCHR;
@@ -354,7 +363,7 @@ VMS_stat (name, statbuf)
if (result == 0 /* GAWK addition; fixup /dev/null flags */
&& (statbuf->st_mode & S_IFREG)
- && STREQ(statbuf->st_dev, "_NLA0:"))
+ && strcmp(statbuf->st_dev, "_NLA0:") == 0)
{
statbuf->st_mode &= ~S_IFREG;
statbuf->st_mode |= S_IFCHR;
diff --git a/vms/vms_popen.c b/vms/vms_popen.c
index 62f3f719..23482df1 100644
--- a/vms/vms_popen.c
+++ b/vms/vms_popen.c
@@ -1,6 +1,7 @@
/* [.vms]vms_popen.c -- substitute routines for missing pipe calls.
- Copyright (C) 1991-1993, 1996, 2010, 2011 the Free Software Foundation, Inc.
+ Copyright (C) 1991-1993, 1996, 2010, 2011, 2014
+ 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
@@ -133,8 +134,8 @@ pclose( FILE *current )
int rval, cur = fileno(current);
/* assert( cur >= 0 && cur < pipes_lim ); */
- if (pipes[cur].pmode == unopened)
- return -1; /* should never happen */
+ if ((cur < 0) || (pipes[cur].pmode == unopened))
+ return -1; /* should never happen, but does with two-way */
rval = fclose(current); /* close temp file; if reading, we're done */
if (pipes[cur].pmode == writing) {
@@ -172,7 +173,7 @@ vms_execute( const char *command, const char *input, const char *output )
out_p = 0;
push_logicals(); /* guard against user-mode definitions of sys$Xput */
- sts = lib$spawn(&cmd, in_p, out_p, (U_Long *)0,
+ sts = LIB$SPAWN(&cmd, in_p, out_p, (U_Long *)0,
(Dsc *)0, (U_Long *)0, &cmpltn_sts);
pop_logicals(); /* restore environment */
@@ -219,9 +220,9 @@ 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))
+#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))
@@ -333,7 +334,7 @@ restore_translation( const Dsc *logname, const Itm *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);
+ (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.
diff --git a/vms/vmsbuild.com b/vms/vmsbuild.com
index 0ad0d3d0..a46cc2ca 100644
--- a/vms/vmsbuild.com
+++ b/vms/vmsbuild.com
@@ -10,13 +10,24 @@ $! gawk 3.1.1 revised, Apr'02
$! gawk 3.1.6 revised, Mar'07
$! gawk-bytecode revd, Jan'10
$! gawk 4.0.0 revd, May'11
+$! gawk 4.1.0 revd, May'13
+$! gawk 4.1.1 revd, Apr'14
$!
-$ REL = "4.0" !release version number
-$ PATCHLVL = "0"
+$ REL = "4.1" !release version number
+$ PATCHLVL = "1"
$!
+$ if (f$getsyi("HW_MODEL") .lt. 1024)
+$ then
+$ arch_name = "VAX"
+$ else
+$ arch_name = f$edit(f$getsyi("ARCH_NAME"), "UPCASE")
+$ endif
$!
$ CCFLAGS = "/noList" ! "/noOpt/Debug"
+$! CCFLAGS = "/list/show=(expan,incl)
$ CDEFS = "GAWK,HAVE_CONFIG_H"
+$! Do not specify _POSIX_EXIT here, we are using other tricks for that.
+$!
$!
$ if p1.eqs."" then p1 = "DECC" !default compiler
$ if p1.eqs."GNUC"
@@ -37,8 +48,17 @@ $ 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)
+$ if arch_name .eqs. "VAX"
+$ then
+$ CFLOAT = ""
+$ else
+$ CFLOAT = "/float=ieee/ieee_mode=denorm_results"
+$ endif
$ CC = "cc/DECC/Prefix=All"
-$ CFLAGS = "/Incl=[]/Obj=[]/Def=(''CDEFS')''CCFLAGS'"
+$ CNAME = "/NAME=(AS_IS,SHORT)
+$ CINC = "/NESTED_INCLUDE=NONE"
+$ CFLAGS = "/Incl=([],[.vms])/Obj=[]/Def=(''CDEFS')''CINC'''CCFLAGS'"
+$ CFLAGS = CNAME + CFLOAT + CFLAGS
$ LIBS = "" ! DECC$SHR instead of VAXCRTL, no special link option needed
$ endif !VAXC
$ endif !GNUC
@@ -46,12 +66,15 @@ $!
$ 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)'
+$ if f$search("config.h") .nes. ""
+$ then
+$ if f$cvtime(f$file_attr("config.h", "RDT")) .ges. -
+ f$cvtime(f$file_attr("configh.in","RDT")) then goto config_ok
+$ endif
+$ v = f$verify(0)
+$ @[.vms]generate_config_vms_h_gawk.com
+$ @[.vms]config_h.com NOBUILTINS
+$!
$config_ok:
$ if f$search("awkgram.c").nes."" then goto awkgram_ok
$ write sys$output " You must process `awkgram.y' with ""yacc"" or ""bison"""
@@ -69,7 +92,7 @@ $ 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 `command.c'."
$ exit
$command_ok:
-$ v = f$verify(1)
+$ v1 = f$verify(1)
$ cc array.c
$ cc awkgram.c
$ cc builtin.c
@@ -90,19 +113,23 @@ $ cc regex.c
$ cc replace.c
$ cc version.c
$ cc eval.c
-$ cc eval_p.c
-$ cc eval_d.c
$ cc profile.c
-$ cc profile_p.c
$ cc command.c
$ cc debug.c
+$ cc int_array.c
+$ cc cint_array.c
+$ cc gawkapi.c
+$ cc mpfr.c
+$ cc str_array.c
+$ cc symbol.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
+$ cc [.vms]vms_crtl_init.c
+$ set command/Object=[]gawk_cmd.obj sys$disk:[.vms]gawk.cld
$! 'f$verify(v)'
$!
$ close/noLog Fopt
@@ -112,52 +139,21 @@ array.obj,awkgram.obj,builtin.obj,dfa.obj,ext.obj,field.obj,floatcomp.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
+command.obj,debug.obj,int_array.obj,cint_array.obj,gawkapi.obj,mpfr.obj
+str_array.obj,symbol.obj
[]vms_misc.obj,vms_popen.obj,vms_fwrite.obj,vms_args.obj
-[]vms_gawk.obj,vms_cli.obj,gawk_cmd.obj
+[]vms_gawk.obj,vms_cli.obj,gawk_cmd.obj,vms_crtl_init.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
$!
-$ create pgawk.opt
-! PGAWK -- GNU awk w/ run-time profiling
-array.obj,awkgram.obj,builtin.obj,dfa.obj,ext.obj,field.obj,floatcomp.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_p.obj,profile_p.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 pgawk.opt
-$ write Fopt libs
-$ write Fopt "identification=""V''REL'.''PATCHLVL'"""
-$ close Fopt
-$!
-$ create dgawk.opt
-! DGAWK -- GNU awk w/ debugging
-array.obj,awkgram.obj,builtin.obj,dfa.obj,ext.obj,field.obj,floatcomp.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_d.obj,profile.obj,command.obj,debug.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 dgawk.opt
+$ @[.vms]gawk_ident.com
+$ v1 = f$verify(1)
+$ open/append Fopt gawk.opt
$ write Fopt libs
-$ write Fopt "identification=""V''REL'.''PATCHLVL'"""
$ close Fopt
$!
-$ v = f$verify(1)
+$ v1 = f$verify(1)
$ link/exe=gawk.exe gawk.opt/options
-$ link/exe=pgawk.exe pgawk.opt/options
-$ link/exe=dgawk.exe dgawk.opt/options
$! 'f$verify(v)'
$ exit
diff --git a/vms/vmstest.com b/vms/vmstest.com
index d4d3d8a9..a2ab9bff 100644
--- a/vms/vmstest.com
+++ b/vms/vmstest.com
@@ -8,19 +8,30 @@ $
$! 3.1.7: changed to share code among many common tests, and
$! to put results for test foo into _foo.tmp instead of tmp.
$!
+$! 4.0.71: New tests:
+$! functab1,functab2,functab3,id,incdupe,incdupe2, incdupe3,include2
+$! symtab1,symtab2,symtab3,symtab4,symtab5,symtab6
+$!
+$! 4.0.75: New tests
+$! basic: rri1,getline5,incdupe4,incdupe5,incdupe6,incdupe7
+$! ext: colonwarn,reginttrad,symtab7,symtab8,symtab9
+$
$ echo = "write sys$output"
$ cmp = "diff/Output=_NL:/Maximum=1"
+$ delsym = "delete/symbol/local/nolog"
$ igncascmp = "''cmp'/Ignore=Case"
-$ sumslp = "edit/Sum"
+$ sumslp = "edit/Sum"
$ rm = "delete/noConfirm/noLog"
$ mv = "rename/New_Vers"
$ gawk = "$sys$disk:[-]gawk"
-$ pgawk = "$sys$disk:[-]pgawk"
$ AWKPATH_srcdir = "define/User AWKPATH sys$disk:[]"
+$ AWKLIBPATH_dir = "define/User AWKLIBPATH sys$disk:[-]"
$
+$! Make sure that the default directory exists on a search list.
+$ def_dir = f$environment("default")
+$ create/dir 'def_dir'
$ listdepth = 0
$ pipeok = 0
-$ pgawkok = -1
$ floatmode = -1 ! 0: D_float, 1: G_float, 2: IEEE T_float
$
$ list = p1+" "+p2+" "+p3+" "+p4+" "+p5+" "+p6+" "+p7+" "+p8
@@ -34,7 +45,7 @@ $all:
$bigtest: echo "bigtest..."
$ ! omits "printlang" and "extra"
$ list = "basic unix_tests gawk_ext vms_tests charset_tests" -
- + " machine_tests pgawk_tests"
+ + " machine_tests"
$ gosub list_of_tests
$ return
$
@@ -47,15 +58,17 @@ $ list = "msg addcomma anchgsub argarray arrayparm arrayref" -
+ " clobber closebad clsflnam compare compare2 concat1"
$ gosub list_of_tests
$ list = "concat2 concat3 concat4 convfmt datanonl defref" -
- + " delargv delarprm delarpm2 delfunc dynlj eofsplit exitval1" -
- + " dfastress" -
+ + " delargv delarprm delarpm2 delfunc dfastress dynlj" -
+ + " eofsplit exitval1" -
+ " exitval2 fcall_exit fcall_exit2 fldchg fldchgnf" -
+ " fnamedat fnarray fnarray2 fnaryscl fnasgnm fnmisc" -
+ " fordel forref forsimp fsbs fsspcoln fsrs fstabplus" -
- + " funsemnl funsmnam funstack getline getline2 getline3"
+ + " funsemnl funsmnam funstack getline getline2 getline3" -
+ + " getline4 getline5"
$ gosub list_of_tests
$ list = "getlnbuf getnr2tb getnr2tm gsubasgn gsubtest" -
- + " gsubtst2 gsubtst3 gsubtst4 gsubtst5 gsubtst6 hex" -
+ + " gsubtst2 gsubtst3 gsubtst4 gsubtst5 gsubtst6" -
+ + " gsubtst7 gsubtst8 hex" -
+ " hsprint inputred intest intprec iobug1" -
+ " leaddig leadnl litoct longsub longwrds"-
+ " manglprm math membug1 messages minusstr mmap8k" -
@@ -65,12 +78,13 @@ $ gosub list_of_tests
$ list = "nfset nlfldsep nlinstr nlstrina noeffect nofile" -
+ " nofmtch noloop1 noloop2 nonl noparms nors nulrsend" -
+ " numindex numsubstr octsub ofmt ofmtbig ofmtfidl" -
- + " ofmta ofmts onlynl opasnidx opasnslf paramdup" -
- + " paramres paramtyp parse1 parsefld parseme pcntplus" -
+ + " ofmta ofmts ofs1 onlynl opasnidx opasnslf paramdup" -
+ + " paramres paramtyp paramuninitglobal parse1 parsefld" -
+ + " parseme pcntplus" -
+ " posix2008sub prdupval prec printf0 printf1 prmarscl"
$ gosub list_of_tests
$ list = "prmreuse prt1eval prtoeval rand range1 rebt8b1" -
- + " redfilnm regeq regrange reindops reparse resplit rs rsnul1nl" -
+ + " redfilnm regeq regexprange regrange reindops reparse resplit rri1 rs rsnul1nl" -
+ " rsnulbig rsnulbig2 rstest1 rstest2 rstest3 rstest4" -
+ " rstest5 rswhite scalar sclforin sclifin sortempty" -
+ " splitargv splitarr splitdef splitvar splitwht" -
@@ -87,7 +101,7 @@ $
$unix:
$unix_tests: echo "unix_tests..."
$ list = "fflush getlnhd localenl pid pipeio1 pipeio2" -
- + " poundbang space strftlng"
+ + " poundbang rtlen rtlen01 space strftlng"
$ gosub list_of_tests
$ return
$
@@ -95,18 +109,23 @@ $gnu:
$gawk_ext: echo "gawk_ext... (gawk.extensions)"
$ list = "aadelete1 aadelete2 aarray1 aasort aasorti" -
+ " argtest arraysort backw badargs beginfile1 binmode1" -
- + " clos1way delsub devfd devfd1 devfd2 dumpvars exit" -
- + " fieldwdth fpat1 fpat2 fpatnull funlen fsfwfs fwtest fwtest2" -
+ + " colonwarn clos1way charasbytes delsub devfd devfd1 devfd2 dumpvars exit" -
+ + " fieldwdth fpat1 fpat2 fpat3 fpatnull funlen functab1" -
+ + " functab2 functab3 fsfwfs" -
+ + " fwtest fwtest2 fwtest3" -
+ " gensub gensub2 getlndir gnuops2 gnuops3 gnureops" -
- + " icasefs icasers igncdym igncfs ignrcase ignrcas2"
+ + " icasefs id icasers igncdym igncfs ignrcase ignrcas2" -
+ + " incdupe incdupe2 incdupe3 incdupe4 incdupe5 incdupe6 incdupe7"
$ gosub list_of_tests
-$ list = "indirectcall lint lintold lintwarn match1" -
+$ list = "include2 indirectcall lint lintold lintwarn match1" -
+ " match2 match3 manyfiles mbprintf3 mbstr1" -
+ " nastyparm next nondec" -
+ " nondec2 patsplit posix profile1 procinfs printfbad1" -
- + " printfbad2 regx8bit rebuf reint reint2 rsstart1" -
- + " rsstart2 rsstart3 rstest6 shadow sortfor sortu" -
- + " splitarg4 strtonum strftime switch2"
+ + " printfbad2 printfbad3 profile2 profile3 pty1" -
+ + " regx8bit rebuf reginttrad reint reint2 rsstart1 rsstart2 rsstart3 rstest6" -
+ + " shadow sortfor sortu split_after_fpat splitarg4" -
+ + " strtonum strftime switch2 symtab1 symtab2 symtab3" -
+ + " symtab4 symtab5 symtab6 symtab7 symtab8 symtab9"
$ gosub list_of_tests
$ return
$
@@ -121,7 +140,7 @@ $charset_tests: echo "charset_tests..."
$ ! without i18n kit, VMS only supports the C locale
$ ! and several of these fail
$ list = "asort asorti fmttest fnarydel fnparydl lc_num1 mbfw1" -
- + " mbprintf1 mbprintf2 rebt8b2 sort1 sprintfc"
+ + " mbprintf1 mbprintf2 rebt8b2 rtlenmb sort1 sprintfc"
$ gosub list_of_tests
$ return
$
@@ -132,16 +151,6 @@ $ list = "double1 double2 fmtspcl intformat"
$ gosub list_of_tests
$ return
$
-$ ! pgawk_tests is part of bigtest; profile_tests is a separate subset
-$profile_tests: echo "profile_tests..."
-$ list = "profile1"
-$ gosub list_of_tests
-$ ! fall through to pgawk_tests
-$pgawk_tests: echo "pgawk_tests..."
-$ list = "profile2 profile3"
-$ gosub list_of_tests
-$ return
-$
$extra: echo "extra..."
$ list = "regtest inftest inet"
$ gosub list_of_tests
@@ -155,6 +164,13 @@ $ type sys$input:
$ list = "inetechu inetecht inetdayu inetdayt"
$ gosub list_of_tests
$ return
+$!
+$extension: echo "extension...."
+$ list = "inplace1 filefuncs fnmatch fts functab4 ordchr" -
+ + " readdir revout revtwoway rwarray time"
+ gosub list_of_tests
+ return
+
$
$! list_of_tests: process 'list', a space-separated list of tests.
$! Some tests assign their own 'list' and call us recursively,
@@ -194,6 +210,7 @@ $fldchgnf:
$fmttest:
$fordel:
$fpat1:
+$fpat3:
$fpatnull:
$fsfwfs:
$fsrs:
@@ -201,14 +218,18 @@ $funlen:
$funstack:
$fwtest:
$fwtest2:
+$fwtest3:
$gensub:
$getline3:
+$getline4:
$getnr2tb:
$getnr2tm:
$gsubtest:
$gsubtst2:
$gsubtst4:
$gsubtst5:
+$gsubtst7:
+$gsubtst8:
$hex:
$icasers:
$igncfs:
@@ -229,6 +250,7 @@ $nulrsend:
$ofmt:
$ofmtfidl:
$ofmts:
+$ofs1:
$onlynl:
$parse1:
$parsefld:
@@ -249,6 +271,7 @@ $rstest6:
$rswhite:
$sortempty:
$sortfor:
+$split_after_fpat:
$splitarg4:
$splitargv:
$splitarr:
@@ -264,7 +287,7 @@ $zeroe0:
$! common with 'test'.in
$ echo "''test'"
$ gawk -f 'test'.awk 'test'.in >_'test'.tmp
-$ cmp 'test'.ok _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
$ if $status then rm _'test'.tmp;
$ return
$
@@ -285,8 +308,6 @@ $convfmt:
$delargv:
$delarprm:
$delsub:
-$!!double1:
-$!!double2:
$dynlj:
$fnarydel:
$fnparydl:
@@ -310,6 +331,7 @@ $nondec:
$octsub:
$ofmta:
$paramtyp:
+$paramuninitglobal:
$patsplit:
$pcntplus:
$printf1:
@@ -317,6 +339,7 @@ $procinfs:
$prt1eval:
$rebt8b1:
$rebt8b2:
+$regexprange:
$regrange:
$regx8bit:
$sort1:
@@ -332,10 +355,19 @@ $zeroflag:
$! common without 'test'.in
$ echo "''test'"
$ gawk -f 'test'.awk >_'test'.tmp
-$ cmp 'test'.ok _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
$ if $status then rm _'test'.tmp;
$ return
$
+$colonwarn: echo "''test'"
+$ gawk -f 'test'.awk 1 < 'test'.in > _'test'.tmp
+$ gawk -f 'test'.awk 2 < 'test'.in > _'test'_2.tmp
+$ gawk -f 'test'.awk 3 < 'test'.in > _'test'_3.tmp
+$ append _'test'_2.tmp,_'test'_3.tmp _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp;1
+$ if $status then rm _'test'*.tmp;*
+$ return
+$
$double1:
$double2:
$lc_num1:
@@ -343,6 +375,23 @@ $mbprintf1:
$ echo "''test' skipped"
$ return
$
+$getline5: echo "''test'"
+$ ! Use of echo and rm inside the awk script makes it necessary
+$ ! for some temporary redefinitions. The VMS gawk.exe also creates
+$ ! multiple output files. Only the first contains the data.
+$ old_echo = echo
+$ old_rm = rm
+$ echo = "pipe write sys$output"
+$ rm = "!"
+$ gawk -f 'test'.awk > _'test'.tmp
+$ echo = old_echo
+$ rm = old_rm
+$ delsym old_echo
+$ delsym old_rm
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp;1
+$ if $status then rm _'test'.tmp;*,f.;*
+$ return
+$
$msg:
$ ! first show gawk's version (without copyright notice)
$ gawk --version >_msg.tmp
@@ -363,18 +412,20 @@ $ gawk -f printlang.awk
$ return
$
$poundbang:
-$ echo "poundbang: not supported"
+$pty1:
+$ echo "''test': not supported"
$ return
$
-$messages: echo "messages"
+$
+$messages: echo "''test'"
$ 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.;
+$ gawk -f 'test'.awk > _out2 >& _out3
+$ cmp out1.ok sys$disk:[]_out1.
+$ if $status then rm _out1.;
+$ cmp out2.ok sys$disk:[]_out2.
+$ if $status then rm _out2.;
+$ cmp out3.ok sys$disk:[]_out3.
+$ if $status then rm _out3.;
$ set On
$ return
$
@@ -382,34 +433,34 @@ $argarray: echo "argarray"
$ define/User TEST "test" !this is useless...
$ gawk -f argarray.awk ./argarray.in - >_argarray.tmp
just a test
-$ cmp argarray.ok _argarray.tmp
+$ cmp argarray.ok sys$disk:[]_argarray.tmp
$ if $status then rm _argarray.tmp;
$ return
$
$fstabplus: echo "fstabplus"
$ gawk -f fstabplus.awk >_fstabplus.tmp
1 2
-$ cmp fstabplus.ok _fstabplus.tmp
+$ cmp fstabplus.ok sys$disk:[]_fstabplus.tmp
$ if $status then rm _fstabplus.tmp;
$ return
$
$longwrds: echo "longwrds"
$ gawk -v "SORT=sort sys$input: _longwrds.tmp" -f longwrds.awk longwrds.in >_NL:
-$ cmp longwrds.ok _longwrds.tmp
+$ cmp longwrds.ok sys$disk:[]_longwrds.tmp
$ if $status then rm _longwrds.tmp;
$ return
$
$fieldwdth: echo "fieldwdth"
$ gawk -v "FIELDWIDTHS=2 3 4" "{ print $2}" >_fieldwdth.tmp
123456789
-$ cmp fieldwdth.ok _fieldwdth.tmp
+$ cmp fieldwdth.ok sys$disk:[]_fieldwdth.tmp
$ if $status then rm _fieldwdth.tmp;
$ return
$
$ignrcase: echo "ignrcase"
$ gawk -v "IGNORECASE=1" "{ sub(/y/, """"); print}" >_ignrcase.tmp
xYz
-$ cmp ignrcase.ok _ignrcase.tmp
+$ cmp ignrcase.ok sys$disk:[]_ignrcase.tmp
$ if $status then rm _ignrcase.tmp;
$ return
$
@@ -427,7 +478,7 @@ $
$posix: echo "posix"
$ gawk -f posix.awk >_posix.tmp
1:2,3 4
-$ cmp posix.ok _posix.tmp
+$ cmp posix.ok sys$disk:[]_posix.tmp
$ if $status then rm _posix.tmp;
$ return
$
@@ -462,19 +513,19 @@ $ return
$
$compare: echo "compare"
$ gawk -f compare.awk 0 1 compare.in >_compare.tmp
-$ cmp compare.ok _compare.tmp
+$ cmp compare.ok sys$disk:[]_compare.tmp
$ if $status then rm _compare.tmp;
$ return
$
$rs: echo "rs"
$ gawk -v "RS=" "{ print $1, $2}" rs.in >_rs.tmp
-$ cmp rs.ok _rs.tmp
+$ cmp rs.ok sys$disk:[]_rs.tmp
$ if $status then rm _rs.tmp;
$ return
$
$fsbs: echo "fsbs"
$ gawk -v "FS=\" "{ print $1, $2 }" fsbs.in >_fsbs.tmp
-$ cmp fsbs.ok _fsbs.tmp
+$ cmp fsbs.ok sys$disk:[]_fsbs.tmp
$ if $status then rm _fsbs.tmp;
$ return
$
@@ -482,14 +533,14 @@ $inftest: echo "inftest"
$ !! echo "This test is very machine specific..."
$ set noOn
$ gawk -f inftest.awk >_inftest.tmp
-$ !! cmp inftest.ok _inftest.tmp !just care that gawk doesn't crash...
+$ !! cmp inftest.ok sys$disk:[]_inftest.tmp !just care that gawk doesn't crash...
$ if $status then rm _inftest.tmp;
$ set On
$ return
$
$getline2: echo "getline2"
$ gawk -f getline2.awk getline2.awk getline2.awk >_getline2.tmp
-$ cmp getline2.ok _getline2.tmp
+$ cmp getline2.ok sys$disk:[]_getline2.tmp
$ if $status then rm _getline2.tmp;
$ return
$
@@ -501,20 +552,20 @@ $ return
$
$negexp: echo "negexp"
$ gawk "BEGIN { a = -2; print 10^a }" >_negexp.tmp
-$ cmp negexp.ok _negexp.tmp
+$ cmp negexp.ok sys$disk:[]_negexp.tmp
$ if $status then rm _negexp.tmp;
$ return
$
$awkpath: echo "awkpath"
$ define/User AWK_LIBRARY [],[.lib]
$ gawk -f awkpath.awk >_awkpath.tmp
-$ cmp awkpath.ok _awkpath.tmp
+$ cmp awkpath.ok sys$disk:[]_awkpath.tmp
$ if $status then rm _awkpath.tmp;
$ return
$
$argtest: echo "argtest"
$ gawk -f argtest.awk -x -y abc >_argtest.tmp
-$ cmp argtest.ok _argtest.tmp
+$ cmp argtest.ok sys$disk:[]_argtest.tmp
$ if $status then rm _argtest.tmp;
$ return
$
@@ -523,7 +574,7 @@ $ on error then continue
$ gawk -f 2>&1 >_badargs.too
$! search/Match=Nor _badargs.too "patchlevel" /Output=_badargs.tmp
$ gawk "/patchlevel/{next}; {gsub(""\"""",""'""); print}" <_badargs.too >_badargs.tmp
-$ cmp badargs.ok _badargs.tmp
+$ cmp badargs.ok sys$disk:[]_badargs.tmp
$ if $status then rm _badargs.tmp;,_badargs.too;
$ return
$
@@ -532,7 +583,7 @@ $ ! 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: >_nonl.tmp 2>&1
-$ cmp nonl.ok _nonl.tmp
+$ cmp nonl.ok sys$disk:[]_nonl.tmp
$ if $status then rm _nonl.tmp;
$ return
$
@@ -540,22 +591,32 @@ $defref: echo "defref"
$ set noOn
$ AWKPATH_srcdir
$ gawk --lint -f defref.awk >_defref.tmp 2>&1
-$ if .not.$status then call exit_code 2 _defref.tmp
+$ if .not. $status then call exit_code '$status' _defref.tmp
$ set On
-$ cmp defref.ok _defref.tmp
+$ cmp defref.ok sys$disk:[]_defref.tmp
$ if $status then rm _defref.tmp;
$ return
$
$nofmtch: echo "nofmtch"
$ AWKPATH_srcdir
$ gawk --lint -f nofmtch.awk >_nofmtch.tmp 2>&1
-$ cmp nofmtch.ok _nofmtch.tmp
+$ cmp nofmtch.ok sys$disk:[]_nofmtch.tmp
$ if $status then rm _nofmtch.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
+$ ! This test needs SYS$TIMEZONE_NAME and SYS$TIMEZONE_RULE
+$ ! to be properly defined.
+$ ! This test now needs GNV Corutils to work
+$ date_bin = "gnv$gnu:[bin]gnv$date.exe"
+$ if f$search(date_bin) .eqs. ""
+$ then
+$ echo "''test' skipped"
+$ return
+$ endif
+$ date := $'date_bin'
$!! date | gawk -v "OUTPUT"=_strftime.tmp -f strftime.awk
$ now = f$time()
$ wkd = f$extract(0,3,f$cvtime(now,,"WEEKDAY"))
@@ -563,15 +624,16 @@ $ 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 = ""
+$! Can not use tz as it shows up in the C environment.
+$ timezone = f$trnlnm("SYS$TIMEZONE_NAME")
$ 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
+$ write ftmp wkd," ",mon," ",day," ",tim," ",timezone," ",yr
$ close ftmp
$ gawk -v "OUTPUT"=_strftime.tmp -f strftime.awk strftime.in
$ set noOn
-$ cmp strftime.ok _strftime.tmp
+$ cmp strftime.ok sys$disk:[]_strftime.tmp
$ if $status then rm _strftime.tmp;,strftime.ok;*,strftime.in;*
$ set On
$ return
@@ -579,54 +641,175 @@ $
$litoct: echo "litoct"
$ gawk --traditional -f litoct.awk >_litoct.tmp
ab
-$ cmp litoct.ok _litoct.tmp
+$ cmp litoct.ok sys$disk:[]_litoct.tmp
$ if $status then rm _litoct.tmp;
$ return
$
$resplit: echo "resplit"
$ gawk -- "{ FS = "":""; $0 = $0; print $2 }" >_resplit.tmp
a:b:c d:e:f
-$ cmp resplit.ok _resplit.tmp
+$ cmp resplit.ok sys$disk:[]_resplit.tmp
$ if $status then rm _resplit.tmp;
$ return
$
$intprec: echo "intprec"
$ gawk -f intprec.awk >_intprec.tmp 2>&1
-$ cmp intprec.ok _intprec.tmp
+$ cmp intprec.ok sys$disk:[]_intprec.tmp
$ if $status then rm _intprec.tmp;
$ return
$
-$childin: echo "childin 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"") }" >_childin.tmp
-$ gawk "BEGIN { ""type sys$input:"" | getline; print; close(""type sys$input:"") }" >_childin.tmp
-hi
-$ cmp childin.ok _childin.tmp
-$ if $status then rm _childin.tmp;
+$incdupe: echo "''test'"
+$ set noOn
+$ gawk --lint -i inclib -i inclib.awk "BEGIN {print sandwich(""a"", ""b"", ""c"")}" > _'test'.tmp 2>&1
+$ if .not. $status then call exit_code '$status' _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;*
+$ set On
+$ return
+$
+$incdupe2: echo "''test'"
+$ set noOn
+$ gawk --lint -f inclib -f inclib.awk >_'test'.tmp 2>&1
+$ if .not. $status then call exit_code '$status' _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;*
+$ set On
+$ return
+$
+$incdupe3: echo "''test'"
+$ gawk --lint -f hello -f hello.awk >_'test'.tmp 2>&1
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;*
+$ return
+$
+$incdupe4: echo "''test'"
+$ set NoOn
+$ gawk --lint -f hello -i hello.awk >_'test'.tmp 2>&1
+$ if .not. $status then call exit_code '$status' _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;*
+$ set On
+$ return
+$
+$incdupe5: echo "''test'"
+$ set NoOn
+$ gawk --lint -i hello -f hello.awk >_'test'.tmp 2>&1
+$ if .not. $status then call exit_code '$status' _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;*
+$ set On
+$ return
+$
+$incdupe6: echo "''test'"
+$ set NoOn
+$ gawk --lint -i inchello -f hello.awk >_'test'.tmp 2>&1
+$ if .not. $status then call exit_code '$status' _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;*
+$ set On
+$ return
+$
+$incdupe7: echo "''test'"
+$ set NoOn
+$ gawk --lint -f hello -i inchello >_'test'.tmp 2>&1
+$ if .not. $status then call exit_code '$status' _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;*
+$ set On
+$ return
+$
+$include2: echo "''test'"
+$ gawk -i inclib "BEGIN {print sandwich(""a"", ""b"", ""c"")}" >_'test'.tmp 2>&1
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;*
+$ return
+$
+$id:
+$symtab1:
+$symtab2:
+$symtab3: echo "''test'"
+$ set noOn
+$ gawk -f 'test'.awk >_'test'.tmp 2>&1
+$ if .not. $status then call exit_code '$status' _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;*
+$ set On
+$ return
+$
+$symtab4:
+$symtab5:
+$symtab7: echo "''test'"
+$ set noOn
+$ gawk -f 'test'.awk <'test'.in >_'test'.tmp 2>&1
+$ if .not. $status then call exit_code '$status' _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;*
+$ set On
+$ return
+$
+$symtab6: echo "''test'"
+$ set noOn
+$ gawk -d__'test'.tmp -f 'test'.awk
+$ pipe search __'test'.tmp "ENVIRON","PROCINFO" /match=nor > _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;*,__'test'.tmp;*
+$ set On
+$ return
+$
+$symtab8: echo "''test'"
+$ set noOn
+$ gawk -d__'test'.tmp -f 'test'.awk 'test'.in > _'test'.tmp
+$ pipe search __'test'.tmp "ENVIRON","PROCINFO","FILENAME" /match=nor > ___'test'.tmp
+$ convert/append ___'test'.tmp _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;*,__'test'.tmp;*,___'test'.tmp;*
+$ set On
+$ return
+$
+$!-----------------------------------------------------------------------------------
+$! This awk script performs some cleanup by doing "system (rm testit.txt)". This is
+$! good for Unix but a pain for VMS as we must specify version number when deleting
+$! a file. The workaround is to define "rm" as a VMS comment and deleting the file
+$! outside of the awk script.
+$! Additionally each awk "system" call results in a new version of the output file.
+$! so we need to compensate for that as well.
+$!-----------------------------------------------------------------------------------
+$symtab9: echo "''test'"
+$ old_rm = rm ! Remember old definition of rm
+$ rm = "!" ! Redefine rm to something harmless
+$ gawk -f 'test'.awk >_'test'.tmp
+$ rm = old_rm ! Restore old value
+$ delsym old_rm
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp;-0 ! -0 is the lowest version
+$ if $status then rm _'test'.tmp;*,testit.txt;*
+$ return
+$
+$childin: echo "''test'"
+$ cat = "type sys$input"
+$ gawk -f 'test'.awk < 'test'.in > _'test'.tmp
+$ delsym cat
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;
$ return
$
$noeffect: echo "noeffect"
$ AWKPATH_srcdir
$ gawk --lint -f noeffect.awk >_noeffect.tmp 2>&1
-$ cmp noeffect.ok _noeffect.tmp
+$ cmp noeffect.ok sys$disk:[]_noeffect.tmp
$ if $status then rm _noeffect.tmp;
$ return
$
$numsubstr: echo "numsubstr"
$ AWKPATH_srcdir
$ gawk -f numsubstr.awk numsubstr.in >_numsubstr.tmp
-$ cmp numsubstr.ok _numsubstr.tmp
+$ cmp numsubstr.ok sys$disk:[]_numsubstr.tmp
$ if $status then rm _numsubstr.tmp;
$ return
$
$prmreuse: echo "prmreuse"
$ if f$search("prmreuse.ok").eqs."" then create prmreuse.ok
$ gawk -f prmreuse.awk >_prmreuse.tmp
-$ cmp prmreuse.ok _prmreuse.tmp
+$ cmp prmreuse.ok sys$disk:[]_prmreuse.tmp
$ if $status then rm _prmreuse.tmp;
$ return
$
@@ -636,7 +819,7 @@ $ return
$!!fflush: echo "fflush"
$ ! hopelessly Unix-specific
$!! @fflush.sh >_fflush.tmp
-$ cmp fflush.ok _fflush.tmp
+$ cmp fflush.ok sys$disk:[]_fflush.tmp
$ if $status then rm _fflush.tmp;
$ return
$
@@ -645,62 +828,68 @@ $ echo "getlnhd skipped"
$ return
$!!getlnhd: echo "getlnhd"
$ gawk -f getlnhd.awk >_getlnhd.tmp
-$ cmp getlnhd.ok _getlnhd.tmp
+$ cmp getlnhd.ok sys$disk:[]_getlnhd.tmp
$ if $status then rm _getlnhd.tmp;
$ return
$
$tweakfld: echo "tweakfld"
$ gawk -f tweakfld.awk tweakfld.in >_tweakfld.tmp
$ if f$search("errors.cleanup").nes."" then rm errors.cleanup;*
-$ cmp tweakfld.ok _tweakfld.tmp
+$ cmp tweakfld.ok sys$disk:[]_tweakfld.tmp
$ if $status then rm _tweakfld.tmp;
$ return
$
$clsflnam: echo "clsflnam"
$ if f$search("clsflnam.ok").eqs."" then create clsflnam.ok
$ gawk -f clsflnam.awk clsflnam.in >_clsflnam.tmp 2>&1
-$ cmp clsflnam.ok _clsflnam.tmp
+$ cmp clsflnam.ok sys$disk:[]_clsflnam.tmp
$ if $status then rm _clsflnam.tmp;
$ return
$
$mmap8k: echo "mmap8k"
$ gawk "{ print }" mmap8k.in >_mmap8k.tmp
-$ cmp mmap8k.in _mmap8k.tmp
+$ cmp mmap8k.in sys$disk:[]_mmap8k.tmp
$ if $status then rm _mmap8k.tmp;
$ return
$
$eofsplit: echo "eofsplit"
$ if f$search("eofsplit.ok").eqs."" then create eofsplit.ok
$ gawk -f eofsplit.awk >_eofsplit.tmp
-$ cmp eofsplit.ok _eofsplit.tmp
+$ cmp eofsplit.ok sys$disk:[]_eofsplit.tmp
$ if $status then rm _eofsplit.tmp;
$ return
$
$back89: echo "back89"
$ gawk "/a\8b/" back89.in >_back89.tmp
-$ cmp back89.ok _back89.tmp
+$ cmp back89.ok sys$disk:[]_back89.tmp
$ if $status then rm _back89.tmp;
$ return
$
$tradanch: echo "tradanch"
$ if f$search("tradanch.ok").eqs."" then create tradanch.ok
$ gawk --traditional -f tradanch.awk tradanch.in >_tradanch.tmp
-$ cmp tradanch.ok _tradanch.tmp
+$ cmp tradanch.ok sys$disk:[]_tradanch.tmp
$ if $status then rm _tradanch.tmp;
$ return
$
+$reginttrad: echo "''test'"
+$ gawk --traditional -r -f 'test'.awk >_'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;
+$ return
+$
$pid: echo "pid"
$ pid = f$integer("%x" + f$getjpi("","PID"))
$ ppid = f$integer("%x" + f$getjpi("","OWNER"))
$ gawk -v "ok_pid=''pid'" -v "ok_ppid=''ppid'" -f pid.awk >_pid.tmp >& _NL:
-$ cmp pid.ok _pid.tmp
+$ cmp pid.ok sys$disk:[]_pid.tmp
$ if $status then rm _pid.tmp;
$ return
$
$strftlng: echo "strftlng"
$ define/User TZ "UTC" !useless
$ gawk -f strftlng.awk >_strftlng.tmp
-$ cmp strftlng.ok _strftlng.tmp
+$ cmp strftlng.ok sys$disk:[]_strftlng.tmp
$ if $status then rm _strftlng.tmp;
$ return
$
@@ -708,7 +897,7 @@ $nfldstr: echo "nfldstr"
$ if f$search("nfldstr.ok").eqs."" then create nfldstr.ok
$ gawk "$1 == 0 { print ""bug"" }" >_nfldstr.tmp
-$ cmp nfldstr.ok _nfldstr.tmp
+$ cmp nfldstr.ok sys$disk:[]_nfldstr.tmp
$ if $status then rm _nfldstr.tmp;
$ return
$
@@ -718,13 +907,13 @@ $!! @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 >_nors.tmp
A B C D E
-$ cmp nors.ok _nors.tmp
+$ cmp nors.ok sys$disk:[]_nors.tmp
$ if $status then rm _nors.tmp;
$ return
$
$reint: echo "reint"
$ gawk --re-interval -f reint.awk reint.in >_reint.tmp
-$ cmp reint.ok _reint.tmp
+$ cmp reint.ok sys$disk:[]_reint.tmp
$ if $status then rm _reint.tmp;
$ return
$
@@ -732,9 +921,9 @@ $noparms: echo "noparms"
$ set noOn
$ AWKPATH_srcdir
$ gawk -f noparms.awk >_noparms.tmp 2>&1
-$ if .not.$status then call exit_code 1 _noparms.tmp
+$ if .not. $status then call exit_code '$status' _noparms.tmp
$ set On
-$ cmp noparms.ok _noparms.tmp
+$ cmp noparms.ok sys$disk:[]_noparms.tmp
$ if $status then rm _noparms.tmp;
$ return
$
@@ -744,7 +933,7 @@ $ define/User test1 []test1.
$ define/User test2 []test2.
$ gawk -f pipeio1.awk >_pipeio1.tmp
$ rm test1.;,test2.;
-$ cmp pipeio1.ok _pipeio1.tmp
+$ cmp pipeio1.ok sys$disk:[]_pipeio1.tmp
$ if $status then rm _pipeio1.tmp;
$ return
$
@@ -755,15 +944,15 @@ $!!pipeio2: echo "pipeio2"
$ cat = "gawk -- {print}"
$ tr = "??" !unfortunately, no trivial substitution available...
$ gawk -v "SRCDIR=." -f pipeio2.awk >_pipeio2.tmp
-$ cmp pipeio2.ok _pipeio2.tmp
+$ cmp pipeio2.ok sys$disk:[]_pipeio2.tmp
$ if $status then rm _pipeio2.tmp;
$ return
$
$clobber: echo "clobber"
$ gawk -f clobber.awk >_clobber.tmp
-$ cmp clobber.ok seq.
+$ cmp clobber.ok sys$disk:[]seq.
$ if $status then rm seq.;*
-$ cmp clobber.ok _clobber.tmp
+$ cmp clobber.ok sys$disk:[]_clobber.tmp
$ if $status then rm _clobber.tmp;
$ return
$
@@ -772,8 +961,13 @@ $ set noOn
$ gawk -f nasty.awk >_nasty.tmp
$ call fixup_LRL nasty.ok
$ call fixup_LRL _nasty.tmp "purge"
-$ cmp nasty.ok _nasty.tmp
-$ if $status then rm _nasty.tmp;
+$ cmp nasty.ok sys$disk:[]_nasty.tmp
+$ if $status
+$ then
+$ rm _nasty.tmp;
+$ file = "lcl_root:[]nasty.ok"
+$ if f$search(file) .nes. "" then rm 'file';*
+$ endif
$ set On
$ return
$
@@ -782,8 +976,13 @@ $ set noOn
$ gawk -f nasty2.awk >_nasty2.tmp
$ call fixup_LRL nasty2.ok
$ call fixup_LRL _nasty2.tmp "purge"
-$ cmp nasty2.ok _nasty2.tmp
-$ if $status then rm _nasty2.tmp;
+$ cmp nasty2.ok sys$disk:[]_nasty2.tmp
+$ if $status
+$ then
+$ rm _nasty2.tmp;
+$ file = "lcl_root:[]nasty2.ok"
+$ if f$search(file) .nes. "" then rm 'file';*
+$ endif
$ set On
$ return
$
@@ -791,7 +990,9 @@ $aadelete1:
$aadelete2:
$arrayparm:
$fnaryscl:
-$match2:
+$functab1:
+$functab2:
+$functab3:
$nastyparm:
$opasnslf:
$opasnidx:
@@ -801,38 +1002,38 @@ $subslash:
$ echo "''test'"
$ set noOn
$ gawk -f 'test'.awk >_'test'.tmp 2>&1
-$ if .not.$status then call exit_code 2 _'test'.tmp
+$ if .not. $status then call exit_code '$status' _'test'.tmp
$ set On
-$ cmp 'test'.ok _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
$ if $status then rm _'test'.tmp;
$ return
$
$arynocls: echo "arynocls"
$ gawk -v "INPUT"=arynocls.in -f arynocls.awk >_arynocls.tmp
-$ cmp arynocls.ok _arynocls.tmp
+$ cmp arynocls.ok sys$disk:[]_arynocls.tmp
$ if $status then rm _arynocls.tmp;
$ return
$
$getlnbuf: echo "getlnbuf"
$ gawk -f getlnbuf.awk getlnbuf.in >_getlnbuf.tmp
$ gawk -f gtlnbufv.awk getlnbuf.in >_getlnbuf.too
-$ cmp getlnbuf.ok _getlnbuf.tmp
+$ cmp getlnbuf.ok sys$disk:[]_getlnbuf.tmp
$ if $status then rm _getlnbuf.tmp;
-$ cmp getlnbuf.ok _getlnbuf.too
+$ cmp getlnbuf.ok sys$disk:[]_getlnbuf.too
$ if $status then rm _getlnbuf.too;
$ return
$
$lint: echo "lint"
$ AWKPATH_srcdir
$ gawk -f lint.awk >_lint.tmp 2>&1
-$ cmp lint.ok _lint.tmp
+$ cmp lint.ok sys$disk:[]_lint.tmp
$ if $status then rm _lint.tmp;
$ return
$
$lintold: echo "lintold"
$ AWKPATH_srcdir
$ gawk -f lintold.awk --lint-old <lintold.in >_lintold.tmp 2>&1
-$ cmp lintold.ok _lintold.tmp
+$ cmp lintold.ok sys$disk:[]_lintold.tmp
$ if $status then rm _lintold.tmp;
$ return
$
@@ -840,7 +1041,7 @@ $ofmtbig: echo "ofmtbig"
$ set noOn
$ gawk -f ofmtbig.awk ofmtbig.in >_ofmtbig.tmp 2>&1
$ set On
-$ cmp ofmtbig.ok _ofmtbig.tmp
+$ cmp ofmtbig.ok sys$disk:[]_ofmtbig.tmp
$ if $status then rm _ofmtbig.tmp;
$ return
$
@@ -878,13 +1079,13 @@ $ return
$
$redfilnm: echo "redfilnm"
$ gawk -f redfilnm.awk srcdir="." redfilnm.in >_redfilnm.tmp
-$ cmp redfilnm.ok _redfilnm.tmp
+$ cmp redfilnm.ok sys$disk:[]_redfilnm.tmp
$ if $status then rm _redfilnm.tmp;
$ return
$
$leaddig: echo "leaddig"
$ gawk -v "x=2E" -f leaddig.awk >_leaddig.tmp
-$ cmp leaddig.ok _leaddig.tmp
+$ cmp leaddig.ok sys$disk:[]_leaddig.tmp
$ if $status then rm _leaddig.tmp;
$ return
$
@@ -893,7 +1094,7 @@ $ echo "clos1way: not supported"
$ return
$!!clos1way: echo "clos1way"
$ gawk -f clos1way.awk >_clos1way.tmp
-$ cmp clos1way.ok _clos1way.tmp
+$ cmp clos1way.ok sys$disk:[]_clos1way.tmp
$ if $status then rm _clos1way.tmp;
$ return
$
@@ -902,7 +1103,7 @@ $ set noOn
$ AWKPATH_srcdir
$ gawk --lint -f shadow.awk >_shadow.tmp 2>&1
$ set On
-$ cmp shadow.ok _shadow.tmp
+$ cmp shadow.ok sys$disk:[]_shadow.tmp
$ if $status then rm _shadow.tmp;
$ return
$
@@ -910,9 +1111,9 @@ $lintwarn: echo "lintwarn"
$ set noOn
$ AWKPATH_srcdir
$ gawk --lint -f lintwarn.awk >_lintwarn.tmp 2>&1
-$ if .not.$status then call exit_code 1 _lintwarn.tmp
+$ if .not. $status then call exit_code '$status' _lintwarn.tmp
$ set On
-$ cmp lintwarn.ok _lintwarn.tmp
+$ cmp lintwarn.ok sys$disk:[]_lintwarn.tmp
$ if $status then rm _lintwarn.tmp;
$ return
$
@@ -923,14 +1124,14 @@ $!! 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 _longsub.tmp "purge"
-$!! cmp longsub.ok _longsub.tmp
+$!! cmp longsub.ok sys$disk:[]_longsub.tmp
$ if $status then rm _longsub.tmp;
$ set On
$ return
$
$arrayprm3: echo "arrayprm3"
$ gawk -f arrayprm3.awk arrayprm3.in >_arrayprm3.tmp
-$ cmp arrayprm3.ok _arrayprm3.tmp
+$ cmp arrayprm3.ok sys$disk:[]_arrayprm3.tmp
$ if $status then rm _arrayprm3.tmp;
$ return
$
@@ -944,7 +1145,6 @@ $aryprm4:
$aryprm5:
$aryprm6:
$aryprm7:
-$delfunc:
$dfastress:
$nfneg:
$numindex:
@@ -954,20 +1154,21 @@ $sclifin:
$ echo "''test'"
$ set noOn
$ gawk -f 'test'.awk 'test'.in >_'test'.tmp 2>&1
-$ if .not.$status then call exit_code 2 _'test'.tmp
+$ if .not. $status then call exit_code '$status' _'test'.tmp
$ set On
-$ cmp 'test'.ok _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
$ if $status then rm _'test'.tmp;
$ return
$
-$fnamedat:
-$fnasgnm:
+$ !
+$ ! For tests requiring exit code 2
+$ !
$ echo "''test'"
$ set noOn
$ gawk -f 'test'.awk <'test'.in >_'test'.tmp 2>&1
-$ if .not.$status then call exit_code 2 _'test'.tmp
+$ if .not. $status then call exit_code '$status' _'test'.tmp
$ set On
-$ cmp 'test'.ok _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
$ if $status then rm _'test'.tmp;
$ return
$
@@ -975,21 +1176,24 @@ $exitval2: echo "exitval2 skipped"
$ return
$!!exitval2: echo "exitval2"
$ gawk -f exitval2.awk exitval2.in >_exitval2.tmp
-$ cmp exitval2.ok _exitval2.tmp
+$ cmp exitval2.ok sys$disk:[]_exitval2.tmp
$ if $status then rm _exitval2.tmp;
$ return
$
+$delfunc:
$fcall_exit2:
+$fnamedat:
$fnarray2:
+$fnasgnm:
$fnmisc:
$gsubasgn:
$unterm:
$ echo "''test'"
$ set noOn
$ gawk -f 'test'.awk 'test'.in >_'test'.tmp 2>&1
-$ if .not.$status then call exit_code 1 _'test'.tmp
+$ if .not. $status then call exit_code '$status' _'test'.tmp
$ set On
-$ cmp 'test'.ok _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
$ if $status then rm _'test'.tmp;
$ return
$
@@ -997,13 +1201,13 @@ $getline: echo "getline skipped"
$ return
$!!getline: echo "getline"
$ gawk -f getline.awk getline.in >_getline.tmp
-$ cmp getline.ok _getline.tmp
+$ cmp getline.ok sys$disk:[]_getline.tmp
$ if $status then rm _getline.tmp;
$ return
$
$gsubtst3: echo "gsubtst3"
$ gawk --re-interval -f gsubtst3.awk gsubtst3.in >_gsubtst3.tmp
-$ cmp gsubtst3.ok _gsubtst3.tmp
+$ cmp gsubtst3.ok sys$disk:[]_gsubtst3.tmp
$ if $status then rm _gsubtst3.tmp;
$ return
$
@@ -1015,7 +1219,7 @@ $ oldout = f$search("_iobug1.tmp;")
$ gawk -f iobug1.awk iobug1.in >_iobug1.tmp
$ badout = f$search("_iobug1.tmp;-1")
$ if badout.nes."" .and. badout.nes.oldout then rm 'badout'
-$ cmp iobug1.ok _iobug1.tmp
+$ cmp iobug1.ok sys$disk:[]_iobug1.tmp
$ if $status then rm _iobug1.tmp;
$ return
$
@@ -1023,7 +1227,7 @@ $rstest4: echo "rstest4 skipped"
$ return
$!!rstest4: echo "rstest4"
$ gawk -f rstest4.awk rstest4.in >_rstest4.tmp
-$ cmp rstest4.ok _rstest4.tmp
+$ cmp rstest4.ok sys$disk:[]_rstest4.tmp
$ if $status then rm _rstest4.tmp;
$ return
$
@@ -1031,13 +1235,14 @@ $rstest5: echo "rstest5 skipped"
$ return
$!!rstest5: echo "rstest5"
$ gawk -f rstest5.awk rstest5.in >_rstest5.tmp
-$ cmp rstest5.ok _rstest5.tmp
+$ cmp rstest5.ok sys$disk:[]_rstest5.tmp
$ if $status then rm _rstest5.tmp;
$ return
$
$fcall_exit:
$fnarray:
$funsmnam:
+$match2:
$paramdup:
$paramres:
$parseme:
@@ -1046,9 +1251,9 @@ $synerr2:
$ echo "''test'"
$ set noOn
$ gawk -f 'test'.awk >_'test'.tmp 2>&1
-$ if .not.$status then call exit_code 1 _'test'.tmp
+$ if .not. $status then call exit_code '$status' _'test'.tmp
$ set On
-$ cmp 'test'.ok _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
$ if $status then rm _'test'.tmp;
$ return
$
@@ -1059,34 +1264,30 @@ $uninit5:
$uninitialized:
$ echo "''test'"
$ gawk --lint -f 'test'.awk 'test'.in >_'test'.tmp 2>&1
-$ cmp 'test'.ok _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
$ if $status then rm _'test'.tmp;
$ return
$
$space: echo "space"
$ set noOn
$ gawk -f " " space.awk >_space.tmp 2>&1
-$ if .not.$status then call exit_code 2 _space.tmp
+$ if .not. $status then call exit_code '$status' _space.tmp
$ set On
$! we get a different error from what space.ok expects
$ gawk "{gsub(""file specification syntax error"", ""no such file or directory""); print}" -
_space.tmp >_space.too
$ rm _space.tmp;
$ mv _space.too _space.tmp
-$ igncascmp space.ok _space.tmp
+$ igncascmp space.ok sys$disk:[]_space.tmp
$ if $status then rm _space.tmp;
$ return
$
-$posix2008sub: echo "posix2008sub"
-$ gawk --posix -f posix2008sub.awk >_posix2008sub.tmp
-$ cmp posix2008sub.ok _posix2008sub.tmp
-$ if $status then  rm _posix2008sub.tmp;
-$ return
-$
-$printf0: echo "printf0"
-$ gawk --posix -f printf0.awk >_printf0.tmp
-$ cmp printf0.ok _printf0.tmp
-$ if $status then rm _printf0.tmp;
+$posix2008sub:
+$printf0:
+$ echo "''test'"
+$ gawk --posix -f 'test'.awk >_'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;
$ return
$
$rsnulbig: echo "rsnulbig"
@@ -1104,7 +1305,7 @@ $ pipe -
gawk -- "BEGIN {RS = """"; ORS = ""\n\n""}; {print}" | -
gawk -- "/^[^a]/; END {print NR}" >_rsnulbig.tmp
$ set On
-$ cmp rsnulbig.ok _rsnulbig.tmp
+$ cmp rsnulbig.ok sys$disk:[]_rsnulbig.tmp
$ if $status then rm _rsnulbig.tmp;
$ return
$
@@ -1123,7 +1324,7 @@ $ pipe -
gawk -- "BEGIN {RS=""""; ORS=""\n\n"" }; {print}" | -
gawk -- "/^[^a]/; END {print NR}" >_rsnulbig2.tmp
$ set On
-$ cmp rsnulbig2.ok _rsnulbig2.tmp
+$ cmp rsnulbig2.ok sys$disk:[]_rsnulbig2.tmp
$ if $status then rm _rsnulbig2.tmp;
$ return
$
@@ -1134,7 +1335,7 @@ $widesub3:
$ echo "''test'"
$ gosub define_gawklocale
$ gawk -f 'test'.awk 'test'.in >_'test'.tmp
-$ cmp 'test'.ok _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
$ if $status then rm _'test'.tmp;
$ return
$
@@ -1146,21 +1347,21 @@ $widesub4:
$ echo "''test'"
$ gosub define_gawklocale
$ gawk -f 'test'.awk >_'test'.tmp
-$ cmp 'test'.ok _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
$ if $status then rm _'test'.tmp;
$ return
$
$! This test is somewhat suspect for vms due to exit code manipulation
$exitval1: echo "exitval1"
$ gawk -f exitval1.awk >_exitval1.tmp 2>&1
-$ if $status then call exit_code 0 _exitval1.tmp
-$ cmp exitval1.ok _exitval1.tmp
+$ if $status then call exit_code '$status' _exitval1.tmp
+$ cmp exitval1.ok sys$disk:[]_exitval1.tmp
$ if $status then rm _exitval1.tmp;
$ return
$
$fsspcoln: echo "fsspcoln"
$ gawk -f fsspcoln.awk "FS=[ :]+" fsspcoln.in >_forspcoln.tmp
-$ cmp fsspcoln.ok _forspcoln.tmp
+$ cmp fsspcoln.ok sys$disk:[]_forspcoln.tmp
$ if $status then rm _forspcoln.tmp;
$ return
$
@@ -1169,13 +1370,13 @@ $ ! assume we're running in the test subdirectory; we don't want to
$ ! perform a messy conversion of [] into its file specification
$ gawk -v "SRCDIR=[-]test.dir" -f getlndir.awk >_getlndir.tmp
$! getlndir.ok expects "Is a directory", we see "is a directory"
-$ igncascmp getlndir.ok _getlndir.tmp
+$ igncascmp getlndir.ok sys$disk:[]_getlndir.tmp
$ if $status then rm _getlndir.tmp;
$ return
$
$rsstart2: echo "rsstart2"
$ gawk -f rsstart2.awk rsstart1.in >_rsstart2.tmp
-$ cmp rsstart2.ok _rsstart2.tmp
+$ cmp rsstart2.ok sys$disk:[]_rsstart2.tmp
$ if $status then rm _rsstart2.tmp;
$ return
$
@@ -1197,13 +1398,57 @@ $ pipe -
gawk -- "FNR <= 10" rsstart1.in | -
gawk -f rsstart2.awk >_rsstart3.tmp
$ set On
-$ cmp rsstart3.ok _rsstart3.tmp
+$ cmp rsstart3.ok sys$disk:[]_rsstart3.tmp
$ if $status then rm _rsstart3.tmp;
$ return
$
+$rtlen:
+$rtlen01:
+$rtlenmb:
+$ echo "''test'"
+$ if .not.pipeok
+$ then echo "Without the PIPE command, ''test' can't be run."
+$ On warning then return
+$ pipe echo "With PIPE, ''test' will finish quickly."
+$ On warning then $
+$ pipeok = 1
+$ endif
+$ f = "''test'.ok"
+$ if test.eqs."rtlen" .or. test.eqs."rtlenmb"
+$ then
+$ if test.eqs."rtlenmb" then GAWKLOCALE = "en_US.UTF-8"
+$ pipe -
+ gawk -- "BEGIN {printf ""0\n\n\n1\n\n\n\n\n2\n\n""; exit}" | -
+ gawk -- "BEGIN {RS=""""}; {print length(RT)}" >_'test'.tmp
+$ if test.eqs."rtlenmb" then delet_/Symbol/Local GAWKLOCALE
+$ if test.eqs."rtlenmb" then f = "rtlen.ok"
+$ else
+$ call/Output=_rtlen01.tmp do__rtlen01
+$ ! first test yields 1 instead of 0 due to forced newline
+$ gawk -- "FNR==1 {sub(""1"",""0"")}; {print}" _rtlen01.tmp >_rtlen01.too
+$ rm _rtlen01.tmp;
+$ mv _rtlen01.too _rtlen01.tmp
+$ endif
+$ cmp 'f' sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;
+$ return
+$
+$do__rtlen01: subroutine
+$ gawk = gawk !PIPE won't propagate local symbols from outer procedure
+$ pipe -
+ gawk -- "BEGIN {printf ""0""; exit}" | -
+ gawk -- "BEGIN {RS=""""}; {print length(RT)}"
+$ pipe -
+ gawk -- "BEGIN {printf ""0\n""; exit}" | -
+ gawk -- "BEGIN {RS=""""}; {print length(RT)}"
+$ pipe -
+ gawk -- "BEGIN {printf ""0\n\n""; exit}" | -
+ gawk -- "BEGIN {RS=""""}; {print length(RT)}"
+$ endsubroutine !do__rtlen01
+$
$nondec2: echo "nondec2"
$ gawk --non-decimal-data -v "a=0x1" -f nondec2.awk >_nondec2.tmp
-$ cmp nondec2.ok _nondec2.tmp
+$ cmp nondec2.ok sys$disk:[]_nondec2.tmp
$ if $status then rm _nondec2.tmp;
$ return
$
@@ -1213,42 +1458,43 @@ $! nofile.ok expects no/such/file, but using that name in the test would
$! yield "file specification syntax error" instead of "no such file..."
$ set noOn
$ gawk "{}" no-such-file >_nofile.tmp 2>&1
-$ if .not.$status then call exit_code 2 _nofile.tmp
+$ if .not. $status then call exit_code '$status' _nofile.tmp
$ set On
$! restore altered file name
$ gawk "{gsub(""no-such-file"", ""no/such/file""); print}" _nofile.tmp >_nofile.too
$ rm _nofile.tmp;
$ mv _nofile.too _nofile.tmp
$! nofile.ok expects "No such file ...", we see "no such file ..."
-$ igncascmp nofile.ok _nofile.tmp
+$ igncascmp nofile.ok sys$disk:[]_nofile.tmp
$ if $status then rm _nofile.tmp;
$ return
$
$binmode1: echo "binmode1"
$ gawk -v "BINMODE=3" "BEGIN { print BINMODE }" >_binmode1.tmp
-$ cmp binmode1.ok _binmode1.tmp
+$ cmp binmode1.ok sys$disk:[]_binmode1.tmp
$ if $status then rm _binmode1.tmp;
$ return
$
-$subi18n: echo "subi18n"
+$subi18n: echo "''test'"
$ define/User GAWKLOCALE "en_US.UTF-8"
-$ gawk -f subi18n.awk >_subi18n.tmp
-$ cmp subi18n.ok _subi18n.tmp
-$ if $status then rm _subi18n.tmp;
+$ gawk -f 'test'.awk > _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;
$ return
$
-$concat4: echo "concat4"
+$rri1:
+$concat4: echo "''test'"
$ define/User GAWKLOCALE "en_US.UTF-8"
-$ gawk -f concat4.awk concat4.in >_concat4.tmp
-$ cmp concat4.ok _concat4.tmp
-$ if $status then rm _concat4.tmp;
+$ gawk -f 'test'.awk 'test'.in > _'test'.tmp
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;
$ return
$
$devfd: echo "devfd: not supported"
$ return
$!!devfd: echo "devfd"
$ gawk 1 /dev/fd/4 /dev/fd/5 4< /devfd.in4 5< devfd.in5 >_devfd.tmp
-$ cmp devfd.ok _devfd.tmp
+$ cmp devfd.ok sys$disk:[]_devfd.tmp
$ if $status then rm _devfd.tmp;
$ return
$
@@ -1256,7 +1502,7 @@ $devfd1: echo "devfd1: not supported"
$ return
$!!devfd1: echo "devfd1"
$ gawk -f devfd1.awk 4< devfd.in1 5< devfd.in2 >_devfd1.tmp
-$ cmp devfd1.ok _devfd1.tmp
+$ cmp devfd1.ok sys$disk:[]_devfd1.tmp
$ if $status then rm _devfd1.tmp;
$ return
$
@@ -1265,30 +1511,42 @@ $ return
$!!devfd2: echo "devfd2"
$! The program text is the '1' which will print each record. How compact can you get?
$ gawk 1 /dev/fd/4 /dev/fd/5 4< /devfd.in1 5< devfd.in2 >_devfd2.tmp
-$ cmp devfd2.ok _devfd2.tmp
+$ cmp devfd2.ok sys$disk:[]_devfd2.tmp
$ if $status then rm _devfd2.tmp;
$ return
$
+$charasbytes:
+$! This test used "od" on Unix to verify the result. As this is not available
+$! we must try as best as possible using DUMP and SEARCH, instead of comparing
+$! to charasbytes.ok
+$!
+$ echo "''test'"
+$ gawk -b -f 'test'.awk 'test'.in >_'test'.tmp
+$ pipe dump/byte/block=count:1 _charasbytes.tmp | -
+ search sys$pipe /noout " 00 00 00 00 00 00 00 00 00 00 00 00 0A 5A 5A 5A"
+$ if $severity .eq. 1 then rm _'test'.tmp;*
+$ return
+$
$mixed1: echo "mixed1"
$ set noOn
$ gawk -f /dev/null --source "BEGIN {return junk}" >_mixed1.tmp 2>&1
-$ if .not.$status then call exit_code 1 _mixed1.tmp
+$ if .not. $status then call exit_code '$status' _mixed1.tmp
$ set On
-$ cmp mixed1.ok _mixed1.tmp
+$ cmp mixed1.ok sys$disk:[]_mixed1.tmp
$ if $status then rm _mixed1.tmp;
$ return
$
$mtchi18n: echo "mtchi18n"
$ define/User GAWKLOCALE "ru_RU.UTF-8"
$ gawk -f mtchi18n.awk mtchi18n.in >_mtchi18n.tmp
-$ cmp mtchi18n.ok _mtchi18n.tmp
+$ cmp mtchi18n.ok sys$disk:[]_mtchi18n.tmp
$ if $status then rm _mtchi18n.tmp;
$ return
$
$reint2: echo "reint2"
$ gosub define_gawklocale
$ gawk --re-interval -f reint2.awk reint2.in >_reint2.tmp
-$ cmp reint2.ok _reint2.tmp
+$ cmp reint2.ok sys$disk:[]_reint2.tmp
$ if $status then rm _reint2.tmp;
$ return
$
@@ -1296,7 +1554,7 @@ $localenl: echo "localenl skipped"
$ return
$!!localenl: echo "localenl"
$ @localenl.com /Output=_localenl.tmp ! sh ./localenl.sh >tmp.
-$ cmp localenl.ok _localenl.tmp
+$ cmp localenl.ok sys$disk:[]_localenl.tmp
$ if $status then rm _localenl.tmp;
$ return
$
@@ -1306,7 +1564,7 @@ $!!mbprintf1: echo "mbprintf1"
$! Makefile test exports this, but we don't want to impact user's environment
$ define/User GAWKLOCALE "en_US.UTF-8"
$ gawk -f mbprintf1.awk mbprintf1.in >_mbprintf1.tmp
-$ cmp mbprintf1.ok _mbprintf1.tmp
+$ cmp mbprintf1.ok sys$disk:[]_mbprintf1.tmp
$ if $status then rm _mbprintf1.tmp;
$ return
$
@@ -1314,7 +1572,7 @@ $mbprintf2: echo "mbprintf2"
$! Makefile test exports this, ...
$ define/User GAWKLOCALE "ja_JP.UTF-8"
$ gawk -f mbprintf2.awk >_mbprintf2.tmp
-$ cmp mbprintf2.ok _mbprintf2.tmp
+$ cmp mbprintf2.ok sys$disk:[]_mbprintf2.tmp
$ if $status then rm _mbprintf2.tmp;
$ return
$
@@ -1322,7 +1580,7 @@ $mbprintf3: echo "mbprintf3"
$! Makefile test exports this, ...
$ define/User GAWKLOCALE "en_US.UTF-8"
$ gawk -f mbprintf3.awk mbprintf3.in >_mbprintf2.tmp
-$ cmp mbprintf3.ok _mbprintf2.tmp
+$ cmp mbprintf3.ok sys$disk:[]_mbprintf2.tmp
$ if $status then rm _mbprintf2.tmp;
$ return
$
@@ -1332,14 +1590,14 @@ $!!mbfw1: echo "mbfw1"
$! Makefile test exports this, ...
$ define/User GAWKLOCALE "en_US.UTF-8"
$ gawk -f mbfw1.awk mbfw1.in >_mbfw1.tmp
-$ cmp mbfw1.ok _mbfw1.tmp
+$ cmp mbfw1.ok sys$disk:[]_mbfw1.tmp
$ if $status then rm _mbfw1.tmp;
$ return
$
$gsubtst6: echo "gsubtst6"
$ define/User GAWKLOCALE "C"
$ gawk -f gsubtst6.awk >_gsubtst6.tmp
-$ cmp gsubtst6.ok _gsubtst6.tmp
+$ cmp gsubtst6.ok sys$disk:[]_gsubtst6.tmp
$ if $status then rm _gsubtst6.tmp;
$ return
$
@@ -1347,16 +1605,18 @@ $mbstr1: echo "mbstr1"
$ gosub define_gawklocale
$ AWKPATH_srcdir
$ gawk -f mbstr1.awk >_mbstr1.tmp
-$ cmp mbstr1.ok _mbstr1.tmp
+$ cmp mbstr1.ok sys$disk:[]_mbstr1.tmp
$ if $status then rm _mbstr1.tmp;
$ return
$
-$printfbad2: echo "printfbad2"
+$printfbad2:
+$printfbad3:
+$ echo "''test'"
$ set noOn
-$ gawk --lint -f printfbad2.awk printfbad2.in >_printfbad2.tmp 2>&1
+$ gawk --lint -f 'test'.awk 'test'.in >_'test'.tmp 2>&1
$ set On
-$ cmp printfbad2.ok _printfbad2.tmp
-$ if $status then rm _printfbad2.tmp;
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;
$ return
$
$fmtspcl: echo "fmtspcl: not supported"
@@ -1368,7 +1628,7 @@ $ if floatmode.lt.2
$ then echo "fmtspcl: not supported"
$ else echo "fmtspcl"
$ gawk -f fmtspcl.awk >_fmtspcl.tmp 2>&1
-$ cmp fmtspcl.ok _fmtspcl.tmp
+$ cmp fmtspcl.ok sys$disk:[]_fmtspcl.tmp
$ if $status then rm _fmtspcl.tmp;
$ endif
$ return
@@ -1384,7 +1644,7 @@ $ hugeval = huge_'floatmode'
$ set noOn
$ gawk -v "HUGEVAL=''hugeval'" -f intformat.awk >_intformat.tmp 2>&1
$ set On
-$ cmp intformat.ok _intformat.tmp
+$ cmp intformat.ok sys$disk:[]_intformat.tmp
$ if $status then rm _intformat.tmp;
$ return
$
@@ -1404,73 +1664,56 @@ $ gawk -f - _beginfile1.tmp >_beginfile1.too
gsub("no-such-file","file"); gsub("Makefile.in","Makefile"); print }
$ rm _beginfile1.tmp;
$ mv _beginfile1.too _beginfile1.tmp
-$ igncascmp beginfile1.ok _beginfile1.tmp
+$ igncascmp beginfile1.ok sys$disk:[]_beginfile1.tmp
$ if $status then rm _beginfile1.tmp;
$ return
$
$dumpvars: echo "dumpvars"
$ gawk --dump-variables 1 <dumpvars.in >_NL: 2>&1
$ mv awkvars.out _dumpvars.tmp
-$ cmp dumpvars.ok _dumpvars.tmp
+$ cmp dumpvars.ok sys$disk:[]_dumpvars.tmp
$ if $status then rm _dumpvars.tmp;
$ return
$
-$profile1: echo "profile1"
-$ ! this profile test is run with gawk rather than pgawk
+$profile1: echo "''test'"
$ ! FIXME: for both gawk invocations which pipe output to SORT,
$ ! two output files get created; the top version has real output
$ ! but there's also an empty lower version.
-$ oldout = f$search("_profile1.tmp1")
-$ gawk --profile -v "sortcmd=SORT sys$intput: sys$output:" -
+$ oldout = f$search("_''test'.tmp1")
+$ gawk --pretty-print -v "sortcmd=SORT sys$intput: sys$output:" -
-f xref.awk dtdgport.awk > _'test'.tmp1
-$ badout = f$search("_profile1.tmp1;-1")
+$ badout = f$search("_''test'.tmp1;-1")
$ if badout.nes."" .and. badout.nes.oldout then rm 'badout'
-$ oldout = f$search("_profile1.tmp2")
+$ oldout = f$search("_''test'.tmp2")
$ gawk -v "sortcmd=SORT sys$intput: sys$output:" -
-f awkprof.out dtdgport.awk > _'test'.tmp2
-$ badout = f$search("_profile1.tmp2;-1")
+$ badout = f$search("_''test'.tmp2;-1")
$ if badout.nes."" .and. badout.nes.oldout then rm 'badout'
-$ cmp _profile1.tmp1 _profile1.tmp2
-$ if $status then rm _profile1.tmp%;,awkprof.out;
-$ return
-$
-$ ! pgawk tests; building pgawk is optional so have to check whether it's here
-$profile2:
-$profile3:
-$ if pgawkok.lt.0
-$ then f = f$parse(pgawk,".exe;")
-$ ! expect first parse to fail due to leading dollar sign
-$ if f.eqs."" then f = f$parse(f$extract(1,999,pgawk),".exe;")
-$ if f.nes."" then f = f$search(f)
-$ pgawkok = (f.nes."").and.1 ! set to 1 or 0
-$ if .not.pgawkok then -
- echo "Can't find pgawk.exe so can't run profiling tests."
-$ endif
-$ if pgawkok then goto do__'test'
-$ echo "''test' skipped"
+$ cmp _'test'.tmp1 sys$disk:[]_'test'.tmp2
+$ if $status then rm _'test'.tmp%;,awkprof.out;
$ return
$
-$do__profile2: echo "profile2"
-$ pgawk -v "sortcmd=SORT sys$input: sys$output:" -
+$profile2: echo "''test'"
+$ gawk --profile -v "sortcmd=SORT sys$input: sys$output:" -
-f xref.awk dtdgport.awk > _NL:
$ ! sed <awkprof.out 1,2d >_profile2.tmp
-$ sumslp awkprof.out /update=sys$input: /output=_profile2.tmp
+$ sumslp awkprof.out /update=sys$input: /output=_'test'.tmp
-1,2
/
$ rm awkprof.out;
-$ cmp profile2.ok _profile2.tmp
-$ if $status then rm _profile2.tmp;*
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;*
$ return
$
-$do__profile3: echo "profile3"
-$ pgawk -f profile3.awk > _NL:
+$profile3: echo "''test'"
+$ gawk --profile -f 'test'.awk > _NL:
$ ! sed <awkprof.out 1,2d >_profile3.tmp
-$ sumslp awkprof.out /update=sys$input: /output=_profile3.tmp
+$ sumslp awkprof.out /update=sys$input: /output=_'test'.tmp
-1,2
/
$ rm awkprof.out;
-$ cmp profile3.ok _profile3.tmp
-$ if $status then rm _profile3.tmp;*
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;*
$ return
$
$next: echo "next"
@@ -1482,7 +1725,7 @@ $ gawk "function f() {next}; {f()}; END{f()}" _NL: >>_next.tmp 2>&1
$ gawk "function f() {next}; BEGINFILE{f()}" _NL: >>_next.tmp 2>&1
$ gawk "function f() {next}; {f()}; ENDFILE{f()}" _NL: >>_next.tmp 2>&1
$ set On
-$ cmp next.ok _next.tmp
+$ cmp next.ok sys$disk:[]_next.tmp
$ if $status then rm _next.tmp;
$ return
$
@@ -1498,7 +1741,7 @@ $ endif
$ set noOn
$ call/Output=_exit.tmp do__exit
$ set On
-$ cmp exit.ok _exit.tmp
+$ cmp exit.ok sys$disk:[]_exit.tmp
$ if $status then rm _exit.tmp;
$ return
$
@@ -1548,8 +1791,8 @@ $ then create vms_cmd.ok
World!
$ endif
$ gawk /Commands="BEGIN { print ""World!"" }" _NL: /Output=_vms_cmd.tmp
-$ cmp vms_cmd.ok _vms_cmd.tmp
-$ if $status then rm _vms_cmd.tmp;
+$ cmp vms_cmd.ok sys$disk:[]_vms_cmd.tmp
+$ if $status then rm _vms_cmd.tmp;,vms_cmd.ok;*
$ return
$
$vms_io1: echo "vms_io1"
@@ -1561,8 +1804,8 @@ $ ! define/User dbg$input sys$command:
$ gawk -f - >_vms_io1.tmp
# prior to 3.0.4, gawk crashed doing any redirection after closing stdin
BEGIN { print "Hello" >"/dev/stdout" }
-$ cmp vms_io1.ok _vms_io1.tmp
-$ if $status then rm _vms_io1.tmp;
+$ cmp vms_io1.ok sys$disk:[]_vms_io1.tmp
+$ if $status then rm _vms_io1.tmp;,vms_io1.ok;*
$ return
$
$vms_io2: echo "vms_io2"
@@ -1587,10 +1830,93 @@ $ set noOn
$ ! define/User dbg$input sys$command:
$ gawk -- "BEGIN { print ""xyzzy"" >""_vms_io2.vfc"" }" >_vms_io2.tmp 2>&1
$ set On
-$ cmp _NL: _vms_io2.tmp
+$ cmp _NL: sys$disk:[]_vms_io2.tmp
$ if $status then rm _vms_io2.tmp;
-$ cmp vms_io2.ok _vms_io2.vfc
-$ if $status then rm _vms_io2.vfc;*
+$ cmp vms_io2.ok sys$disk:[]_vms_io2.vfc
+$ if $status then rm _vms_io2.vfc;*,vms_io2.ok;*
+$ return
+$!
+$!
+$inplace1:
+$ set process/parse=extended ! ODS-5 only
+$ echo "''test'"
+$ filefunc_file = "[-]gawkapi.o"
+$ open/write awkfile _'test'.awk
+$ write awkfile "@load ""inplace"""
+$! write awkfile "BEGIN {print ""before""}"
+$ write awkfile " {gsub(/foo/, ""bar""); print}"
+$! write awkfile "END {print ""after""}"
+$ close awkfile
+$ copy inplace^.1.in _'test'.1
+$ copy inplace^.2.in _'test'.2
+$ set noOn
+$ AWKLIBPATH_dir
+$ gawk -f _'test'.awk _'test'.1 <inplace.in >_'test'.1.tmp 2>&1
+$ if .not. $status then call exit_code '$status' _'test'.1.tmp
+$ AWKLIBPATH_dir
+$ gawk -f _'test'.awk _'test'.2 <inplace.in >_'test'.2.tmp 2>&1
+$ if .not. $status then call exit_code '$status' _'test'.2.tmp
+$ set On
+$ cmp 'test'.1.ok sys$disk:[]_'test'.1.tmp
+$ if $status then rm _'test'.1.tmp;,_'test'.1;
+$ cmp 'test'.2.ok sys$disk:[]_'test'.2.tmp
+$ if $status then rm _'test'.2.tmp;,_'test'.2;,_'test'.awk;
+$ return
+$!
+$filefuncs:
+$fnmatch:
+$functab4:
+$ordchr:
+$revout:
+$revtwoway:
+$time:
+$ echo "''test'"
+$ filefunc_file = "[-]gawkapi.o"
+$ open/write gapi 'filefunc_file'
+$ close gapi
+$ set noOn
+$ AWKLIBPATH_dir
+$ gawk -f 'test'.awk 'test'.in >_'test'.tmp 2>&1
+$ if .not. $status then call exit_code '$status' _'test'.tmp
+$ set On
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;
+$ if f$search(filefunc_file) .nes. "" then rm 'filefunc_file';*
+$ return
+$!
+$rwarray:
+$ echo "''test'"
+$ set noOn
+$ AWKLIBPATH_dir
+$ gawk -f 'test'.awk 'test'.in >_'test'.tmp 2>&1
+$ if .not. $status then call exit_code '$status' _'test'.tmp
+$ set On
+$ cmp orig.out new.out
+$ if $status
+$ then
+$ open/append tout _'test'.tmp
+$ write tout "old and new are equal - GOOD"
+$ close tout
+$ endif
+$ cmp 'test'.ok sys$disk:[]_'test'.tmp
+$ if $status then rm _'test'.tmp;,orig.bin;,orig.out;,new.out;
+$ return
+$!
+$readdir:
+$fts:
+$ echo "''test'"
+$ set noOn
+$ AWKLIBPATH_dir
+$ gawk -f 'test'.awk >_'test'.tmp 2>&1
+$ if .not. $status
+$ then
+$ call exit_code '$status' _'test'.tmp
+$ write sys$output _'test'.tmp
+$ else
+$ if f$search("_''test'.tmp") .nes. "" then rm _'test'.tmp;*
+$ if f$search("_''test'.") .nes. "" then rm _'test'.;*
+$ endif
+$ set On
$ return
$
$clean:
@@ -1660,10 +1986,12 @@ $ 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
+$! Unix code = vms_code & (255 * 2^3) >> 3
$exit_code: subroutine
+$ unix_status = (p1 .and. %x7f8) / 8
$ if f$trnlnm("FTMP").nes."" then close/noLog ftmp
$ open/Append ftmp 'p2'
-$ write ftmp "EXIT CODE: ",p1
+$ write ftmp "EXIT CODE: ",'unix_status'
$ close ftmp
$ endsubroutine !exit_code
$
diff --git a/xalloc.h b/xalloc.h
index 5810fc55..0d169cf9 100644
--- a/xalloc.h
+++ b/xalloc.h
@@ -136,6 +136,8 @@ xnmalloc (size_t n, size_t s)
#ifdef GAWK
#include <errno.h>
+extern void r_fatal(const char *msg, ...) ATTRIBUTE_NORETURN ;
+
/* Allocate an array of N objects, each with S bytes of memory,
dynamically, with error checking. S must be nonzero.
Clear the contents afterwards. */
@@ -165,10 +167,34 @@ xrealloc(void *p, size_t size)
void
xalloc_die (void)
{
- extern void r_fatal(const char *msg, ...) ATTRIBUTE_NORETURN ;
-
r_fatal(_("xalloc: malloc failed: %s"), strerror(errno));
}
+
+/* Clone an object P of size S, with error checking. There's no need
+ for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any
+ need for an arithmetic overflow check. */
+
+void *
+xmemdup (void const *p, size_t s)
+{
+ return memcpy (xmalloc (s), p, s);
+}
+
+/* xstrdup --- strdup and die if fails */
+char *xstrdup(const char *s)
+{
+ char *p;
+ int l;
+
+ if (s == NULL)
+ r_fatal(_("xstrdup: null parameter"));
+
+ l = strlen(s);
+ p = xmemdup(s, l + 1);
+ p[l] = '\0';
+
+ return p;
+}
#endif
/* Change the size of an allocated block of memory P to an array of N
@@ -250,7 +276,7 @@ x2nrealloc (void *p, size_t *pn, size_t s)
requests, when the invoking code specifies an old size of
zero. 64 bytes is the largest "small" request for the
GNU C library malloc. */
- enum { DEFAULT_MXFAST = 64 };
+ enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
n = DEFAULT_MXFAST / s;
n += !n;
@@ -264,7 +290,7 @@ x2nrealloc (void *p, size_t *pn, size_t s)
worth the trouble. */
if ((size_t) -1 / 3 * 2 / s <= n)
xalloc_die ();
- n += (n + 1) / 2;
+ n += n / 2 + 1;
}
*pn = n;
diff --git a/ylwrap b/ylwrap
index 102bd893..7befa46d 100644..100755
--- a/ylwrap
+++ b/ylwrap
@@ -1,10 +1,9 @@
#! /bin/sh
# ylwrap - wrapper for lex/yacc invocations.
-scriptversion=2005-05-14.22
+scriptversion=2012-07-14.08; # UTC
-# Copyright (C) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005
-# Free Software Foundation, Inc.
+# Copyright (C) 1996-2012 Free Software Foundation, Inc.
#
# Written by Tom Tromey <tromey@cygnus.com>.
#
@@ -19,9 +18,7 @@ scriptversion=2005-05-14.22
# 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.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -32,9 +29,40 @@ scriptversion=2005-05-14.22
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
+get_dirname ()
+{
+ case $1 in
+ */*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';;
+ # Otherwise, we want the empty string (not ".").
+ esac
+}
+
+# guard FILE
+# ----------
+# The CPP macro used to guard inclusion of FILE.
+guard()
+{
+ printf '%s\n' "$from" \
+ | sed \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'\
+ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'
+}
+
+# quote_for_sed [STRING]
+# ----------------------
+# Return STRING (or stdin) quoted to be used as a sed pattern.
+quote_for_sed ()
+{
+ case $# in
+ 0) cat;;
+ 1) printf '%s\n' "$1";;
+ esac \
+ | sed -e 's|[][\\.*]|\\&|g'
+}
+
case "$1" in
'')
- echo "$0: No files given. Try \`$0 --help' for more information." 1>&2
+ echo "$0: No files given. Try '$0 --help' for more information." 1>&2
exit 1
;;
--basedir)
@@ -69,6 +97,8 @@ esac
# The input.
input="$1"
shift
+# We'll later need for a correct munging of "#line" directives.
+input_sub_rx=`get_dirname "$input" | quote_for_sed`
case "$input" in
[\\/]* | ?:[\\/]*)
# Absolute path; do nothing.
@@ -78,15 +108,40 @@ case "$input" in
input="`pwd`/$input"
;;
esac
+input_rx=`get_dirname "$input" | quote_for_sed`
+
+# 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=false
+if test -f y_tab.c || test -f y_tab.h; then
+ y_tab_nodot=true
+fi
-pairlist=
+# The parser itself, the first file, is the destination of the .y.c
+# rule in the Makefile.
+parser=$1
+# A sed program to s/FROM/TO/g for all the FROM/TO so that, for
+# instance, we rename #include "y.tab.h" into #include "parse.h"
+# during the conversion from y.tab.c to parse.c.
+rename_sed=
while test "$#" -ne 0; do
if test "$1" = "--"; then
shift
break
fi
- pairlist="$pairlist $1"
+ from=$1
+ # Handle y_tab.c and y_tab.h output by DOS
+ if $y_tab_nodot; then
+ case $from in
+ "y.tab.c") from=y_tab.c;;
+ "y.tab.h") from=y_tab.h;;
+ esac
+ fi
shift
+ to=$1
+ shift
+ rename_sed="${rename_sed}s|"`quote_for_sed "$from"`"|$to|g;"
done
# The program to run.
@@ -101,110 +156,71 @@ 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
+do_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret'
+trap "ret=129; $do_exit" 1
+trap "ret=130; $do_exit" 2
+trap "ret=141; $do_exit" 13
+trap "ret=143; $do_exit" 15
mkdir $dirname || exit 1
cd $dirname
case $# in
- 0) $prog "$input" ;;
- *) $prog "$@" "$input" ;;
+ 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
+ for from in *
+ do
+ to=`printf '%s\n' "$from" | sed "$rename_sed"`
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";;
+ # otherwise prepend '../'.
+ case $to in
+ [\\/]* | ?:[\\/]*) target=$to;;
+ *) target="../$to";;
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`"
+ # Do not overwrite unchanged header files to avoid useless
+ # recompilations. Always update the parser itself: 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 $from != $parser; then
+ realtarget="$target"
+ target=tmp-`printf '%s\n' "$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"
+
+ # Munge "#line" or "#" directives. Don't let the resulting
+ # debug information point at an absolute srcdir. Use the real
+ # output file name, not yy.lex.c for instance. Adjust the
+ # include guards too.
+ FROM=`guard "$from"`
+ TARGET=`guard "$to"`
+ sed -e "/^#/!b" -e "s|$input_rx|$input_sub_rx|" -e "$rename_sed" \
+ -e "s|$FROM|$TARGET|" "$from" >"$target" || ret=$?
+
+ # Check whether files must be updated.
+ if test "$from" != "$parser"; then
+ if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then
+ echo "$to is unchanged"
+ rm -f "$target"
+ else
+ echo "updating $to"
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
+ # A missing file is only an error for the parser. This is a
+ # blatant hack to let us support using "yacc -d". If -d is not
+ # specified, don't fail when the header file is "missing".
+ if test "$from" = "$parser"; then
ret=1
fi
fi
- shift
- shift
- first=no
done
-else
- ret=$?
fi
# Remove the directory.
@@ -219,5 +235,6 @@ exit $ret
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
# End: